This source file includes following definitions.
- send_break
- send_intr
- receive_intr
- line_status_intr
- modem_status_intr
- UART_ISR_proc
- do_rs_write
- FourPort_ISR_proc
- rs_interrupt
- rs_timer
- init
- rs_write
- rs_close
- startup
- change_speed
- get_serial_info
- set_serial_info
- get_modem_info
- set_modem_info
- rs_ioctl
- rs_open
- rs_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #include <linux/errno.h>
21 #include <linux/signal.h>
22 #include <linux/sched.h>
23 #include <linux/timer.h>
24 #include <linux/tty.h>
25 #include <linux/serial.h>
26
27 #include <asm/system.h>
28 #include <asm/io.h>
29 #include <asm/segment.h>
30
31 #define WAKEUP_CHARS (3*TTY_BUF_SIZE/4)
32
33
34
35
36
37
38
39
40 static unsigned long rs_read_process = 0;
41 static unsigned long rs_write_timeout = 0;
42
43 static void UART_ISR_proc(async_ISR ISR, int line);
44 static void FourPort_ISR_proc(async_ISR ISR, int line);
45
46 struct struct_ISR COM1_ISR = { 4, 0x3f8, UART_ISR_proc, 0, };
47 struct struct_ISR COM2_ISR = { 3, 0x2f8, UART_ISR_proc, 0, };
48 struct struct_ISR COM3_ISR = { 4, 0x3e8, UART_ISR_proc, 0, };
49 struct struct_ISR COM4_ISR = { 3, 0x2e8, UART_ISR_proc, 0, };
50
51 struct struct_ISR FourPort1_ISR = { 2, 0x1bf, FourPort_ISR_proc, 0, };
52 struct struct_ISR FourPort2_ISR = { 5, 0x2bf, FourPort_ISR_proc, 0, };
53
54 struct struct_ISR Accent3_ISR = { 4, 0x330, UART_ISR_proc, 0, };
55 struct struct_ISR Accent4_ISR = { 4, 0x338, UART_ISR_proc, 0, };
56
57
58
59
60
61
62
63
64 #define BASE_BAUD ( 1843200 / 16 )
65
66 struct async_struct rs_table[] = {
67 { BASE_BAUD, 0x3F8, &COM1_ISR, 0, },
68 { BASE_BAUD, 0x2F8, &COM2_ISR, 0, },
69 { BASE_BAUD, 0x3E8, &COM3_ISR, 0, },
70 { BASE_BAUD, 0x2E8, &COM4_ISR, 0, },
71
72 { BASE_BAUD, 0x1A0, &FourPort1_ISR, ASYNC_FOURPORT },
73 { BASE_BAUD, 0x1A8, &FourPort1_ISR, ASYNC_FOURPORT },
74 { BASE_BAUD, 0x1B0, &FourPort1_ISR, ASYNC_FOURPORT },
75 { BASE_BAUD, 0x1B8, &FourPort1_ISR, ASYNC_FOURPORT | ASYNC_NOSCRATCH },
76
77 { BASE_BAUD, 0x2A0, &FourPort2_ISR, ASYNC_FOURPORT },
78 { BASE_BAUD, 0x2A8, &FourPort2_ISR, ASYNC_FOURPORT },
79 { BASE_BAUD, 0x2B0, &FourPort2_ISR, ASYNC_FOURPORT },
80 { BASE_BAUD, 0x2B8, &FourPort2_ISR, ASYNC_FOURPORT | ASYNC_NOSCRATCH },
81
82 { BASE_BAUD, 0x330, &Accent3_ISR, 0 },
83 { BASE_BAUD, 0x338, &Accent4_ISR, 0 },
84 };
85
86 #define NR_PORTS (sizeof(rs_table)/sizeof(struct async_struct))
87
88 static async_ISR IRQ_ISR[16];
89
90
91
92
93
94 static int baud_table[] = {
95 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
96 9600, 19200, 38400, 56000, 115200, 0 };
97
98 static void send_break( struct async_struct * info)
99 {
100 unsigned short port;
101
102 if (!(port = info->port))
103 return;
104 port += UART_LCR;
105 current->state = TASK_INTERRUPTIBLE;
106 current->timeout = jiffies + 25;
107 outb_p(inb_p(port) | UART_LCR_SBC, port);
108 schedule();
109 outb_p(inb_p(port) & ~UART_LCR_SBC, port);
110 }
111
112
113
114
115
116
117
118
119
120
121
122 static void send_intr(struct async_struct * info)
123 {
124 unsigned short port = info->port;
125 int line = info->line;
126 struct tty_queue * queue = &info->tty->write_q;
127 int c, count = 0;
128
129 if (info->tty->stopped)
130 return;
131
132 if (info->type == PORT_16550A)
133 count = 16;
134 else
135 count = 1;
136
137 rs_write_timeout &= ~(1 << line);
138
139 if (inb_p(UART_LSR + info->port) & UART_LSR_THRE) {
140 while (count-- && !info->tty->stopped) {
141 if (queue->tail == queue->head)
142 goto end_send;
143 c = queue->buf[queue->tail];
144 queue->tail++;
145 queue->tail &= TTY_BUF_SIZE-1;
146 outb(c, UART_TX + port);
147 }
148 }
149 info->timer = jiffies + info->timeout;
150 if (info->timer < timer_table[RS_TIMER].expires)
151 timer_table[RS_TIMER].expires = info->timer;
152 rs_write_timeout |= 1 << line;
153 timer_active |= 1 << RS_TIMER;
154 end_send:
155 if (LEFT(queue) > WAKEUP_CHARS)
156 wake_up(&queue->proc_list);
157 }
158
159 static void receive_intr(struct async_struct * info)
160 {
161 unsigned short port = info->port;
162 struct tty_queue * queue = &info->tty->read_q;
163 int head = queue->head;
164 int maxhead = (queue->tail-1) & (TTY_BUF_SIZE-1);
165 int count = 0;
166
167 rs_read_process &= ~(1 << info->line);
168 do {
169 count++;
170 queue->buf[head] = inb(UART_TX + port);
171 if (head != maxhead) {
172 head++;
173 head &= TTY_BUF_SIZE-1;
174 }
175 } while (inb(UART_LSR + port) & UART_LSR_DR);
176 queue->head = head;
177 rs_read_process |= 1 << info->line;
178 timer_table[RS_TIMER].expires = 0;
179 timer_active |= 1<<RS_TIMER;
180 }
181
182 static void line_status_intr(struct async_struct * info)
183 {
184 unsigned char status = inb(UART_LSR + info->port);
185
186
187 }
188
189 static void modem_status_intr(struct async_struct * info)
190 {
191 unsigned char status = inb(UART_MSR + info->port);
192
193 if (!(info->tty->termios->c_cflag & CLOCAL)) {
194 if (((status & (UART_MSR_DCD|UART_MSR_DDCD)) == UART_MSR_DDCD)
195 && info->tty->pgrp > 0)
196 kill_pg(info->tty->pgrp,SIGHUP,1);
197
198 if (info->tty->termios->c_cflag & CRTSCTS)
199 info->tty->stopped = !(status & UART_MSR_CTS);
200
201 if (!info->tty->stopped)
202 send_intr(info);
203 }
204 }
205
206 static void (*jmp_table[4])(struct async_struct *) = {
207 modem_status_intr,
208 send_intr,
209 receive_intr,
210 line_status_intr
211 };
212
213
214
215
216
217
218
219 static void UART_ISR_proc(async_ISR ISR, int line)
220 {
221 unsigned char ident;
222 struct async_struct * info = rs_table + line;
223
224 if (!info || !info->tty || !info->port)
225 return;
226 while (1) {
227 ident = inb(UART_IIR + info->port) & 7;
228 if (ident & 1)
229 return;
230 ident = ident >> 1;
231 jmp_table[ident](info);
232 }
233 }
234
235
236
237
238
239 static inline void do_rs_write(struct async_struct * info)
240 {
241 if (!info->tty || !info->port)
242 return;
243 if (EMPTY(&info->tty->write_q))
244 return;
245 cli();
246 send_intr(info);
247 sti();
248 }
249
250
251
252
253 static void FourPort_ISR_proc(async_ISR ISR, int line)
254 {
255 int i;
256 unsigned char ivec;
257
258 ivec = ~inb(ISR->port) & 0x0F;
259 for (i = line; ivec; i++) {
260 if (ivec & 1)
261 UART_ISR_proc(ISR, i);
262 ivec = ivec >> 1;
263 }
264 }
265
266
267
268
269 static void rs_interrupt(int irq)
270 {
271 async_ISR p = IRQ_ISR[irq];
272
273 while (p) {
274 (p->ISR_proc)(p, p->line);
275 p = p->next_ISR;
276 }
277 }
278
279
280
281
282
283
284 #define END_OF_TIME 0xffffffff
285 static void rs_timer(void)
286 {
287 unsigned long mask;
288 struct async_struct *info;
289 unsigned long next_timeout;
290
291 info = rs_table;
292 next_timeout = END_OF_TIME;
293 for (mask = 1 ; mask ; info++, mask <<= 1) {
294 if ((mask > rs_read_process) &&
295 (mask > rs_write_timeout))
296 break;
297 if (mask & rs_read_process) {
298 TTY_READ_FLUSH(info->tty);
299 rs_read_process &= ~mask;
300 }
301 if (mask & rs_write_timeout) {
302 if (info->timer > jiffies) {
303 rs_write_timeout &= ~mask;
304 do_rs_write(info);
305 }
306 if ((mask & rs_write_timeout) &&
307 (info->timer < next_timeout))
308 next_timeout = info->timer;
309 }
310 }
311 if (next_timeout != END_OF_TIME) {
312 timer_table[RS_TIMER].expires = next_timeout;
313 timer_active |= 1 << RS_TIMER;
314 }
315 }
316
317 static void init(struct async_struct * info)
318 {
319 unsigned char status1, status2, scratch, scratch2;
320 unsigned short port = info->port;
321
322
323
324
325 scratch = inb_p(UART_MCR + port);
326 outb_p(UART_MCR_LOOP | scratch, UART_MCR + port);
327 scratch2 = inb_p(UART_MSR + port);
328 outb_p(UART_MCR_LOOP | 0x0A, UART_MCR + port);
329 status1 = inb_p(UART_MSR + port) & 0xF0;
330 outb_p(scratch, UART_MCR + port);
331 outb_p(scratch2, UART_MSR + port);
332 if (status1 != 0x90) {
333 info->type = PORT_UNKNOWN;
334 return;
335 }
336
337 if (!(info->flags & ASYNC_NOSCRATCH)) {
338 scratch = inb(UART_SCR + port);
339 outb_p(0xa5, UART_SCR + port);
340 status1 = inb(UART_SCR + port);
341 outb_p(0x5a, UART_SCR + port);
342 status2 = inb(UART_SCR + port);
343 outb_p(scratch, UART_SCR + port);
344 } else {
345 status1 = 0xa5;
346 status2 = 0x5a;
347 }
348 if (status1 == 0xa5 && status2 == 0x5a) {
349 outb_p(UART_FCR_ENABLE_FIFO, UART_FCR + port);
350 scratch = inb(UART_IIR + port) >> 6;
351 info->xmit_fifo_size = 1;
352 switch (scratch) {
353 case 0:
354 info->type = PORT_16450;
355 break;
356 case 1:
357 info->type = PORT_UNKNOWN;
358 break;
359 case 2:
360 info->type = PORT_16550;
361 break;
362 case 3:
363 info->type = PORT_16550A;
364 info->xmit_fifo_size = 16;
365 break;
366 }
367 } else
368 info->type = PORT_8250;
369 change_speed(info->line);
370 outb_p(0x00, UART_IER + port);
371 outb_p(0x00, UART_MCR + port);
372 (void)inb(UART_RX + port);
373 }
374
375
376
377
378
379
380 void rs_write(struct tty_struct * tty)
381 {
382 do_rs_write(rs_table+DEV_TO_SL(tty->line));
383 }
384
385
386
387
388
389
390
391 static void rs_close(struct tty_struct *tty, struct file * filp)
392 {
393 struct async_struct * info;
394 async_ISR ISR;
395 int irq, line;
396
397 line = DEV_TO_SL(tty->line);
398 if ((line < 0) || (line >= NR_PORTS))
399 return;
400 wait_until_sent(tty);
401 info = rs_table + line;
402 if (!info->port)
403 return;
404 info->tty = 0;
405 outb_p(0x00, UART_IER + info->port);
406 outb_p(0x00, UART_MCR + info->port);
407 outb(UART_FCR_CLEAR_CMD, UART_FCR + info->port);
408 ISR = info->ISR;
409 irq = ISR->irq;
410 if (irq == 2)
411 irq = 9;
412 if (--ISR->refcnt == 0) {
413 if (ISR->next_ISR)
414 ISR->next_ISR->prev_ISR = ISR->prev_ISR;
415 if (ISR->prev_ISR)
416 ISR->prev_ISR->next_ISR = ISR->next_ISR;
417 else
418 IRQ_ISR[irq] = ISR->next_ISR;
419 if (!IRQ_ISR[irq])
420 free_irq(irq);
421 }
422 }
423
424 static void startup(struct async_struct * info)
425 {
426 unsigned short port = info->port;
427 unsigned short ICP;
428
429
430
431
432 if (info->type == PORT_16550A)
433 outb_p(UART_FCR_CLEAR_CMD, UART_FCR + port);
434
435
436
437
438 (void)inb_p(UART_LSR + port);
439 (void)inb_p(UART_RX + port);
440 (void)inb_p(UART_IIR + port);
441 (void)inb_p(UART_MSR + port);
442
443
444
445
446 outb_p(UART_LCR_WLEN8, UART_LCR + port);
447 if (info->flags & ASYNC_FOURPORT)
448 outb_p(UART_MCR_DTR | UART_MCR_RTS,
449 UART_MCR + port);
450 else
451 outb_p(UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2,
452 UART_MCR + port);
453
454
455
456
457 if (info->type == PORT_16550A) {
458 outb_p(UART_FCR_SETUP_CMD, UART_FCR + port);
459 info->xmit_fifo_size = 16;
460 } else {
461 info->xmit_fifo_size = 1;
462 }
463
464
465
466
467 outb_p(0x0f,UART_IER + port);
468 if (info->flags & ASYNC_FOURPORT) {
469
470 ICP = (port & 0xFE0) | 0x01F;
471 outb_p(0x80, ICP);
472 (void) inb(ICP);
473 }
474 }
475
476 void change_speed(unsigned int line)
477 {
478 struct async_struct * info;
479 unsigned short port;
480 int quot = 0;
481 unsigned cflag,cval;
482 int i;
483
484 if (line >= NR_PORTS)
485 return;
486 info = rs_table + line;
487 cflag = info->tty->termios->c_cflag;
488 if (!(port = info->port))
489 return;
490 i = cflag & CBAUD;
491 if (i == 15) {
492 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
493 i += 1;
494 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
495 i += 2;
496 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
497 quot = info->custom_divisor;
498 }
499 if (quot) {
500 info->timeout = ((info->xmit_fifo_size*HZ*15*quot) /
501 info->baud_base) + 2;
502 } else if (baud_table[i] == 134) {
503 quot = (2*info->baud_base / 269);
504 info->timeout = (info->xmit_fifo_size*HZ*30/269) + 2;
505 } else if (baud_table[i]) {
506 quot = info->baud_base / baud_table[i];
507 info->timeout = (info->xmit_fifo_size*HZ*15/baud_table[i]) + 2;
508 } else {
509 quot = 0;
510 info->timeout = 0;
511 }
512 if (!quot)
513 outb(0x00,UART_MCR + port);
514 else if (!inb(UART_MCR + port))
515 startup(info);
516
517 cval = cflag & (CSIZE | CSTOPB);
518 cval >>= 4;
519 if (cflag & PARENB)
520 cval |= 8;
521 if (!(cflag & PARODD))
522 cval |= 16;
523 cli();
524 outb_p(cval | UART_LCR_DLAB, UART_LCR + port);
525 outb_p(quot & 0xff, UART_DLL + port);
526 outb_p(quot >> 8, UART_DLM + port);
527 outb(cval, UART_LCR + port);
528 sti();
529 }
530
531 static int get_serial_info(struct async_struct * info,
532 struct serial_struct * retinfo)
533 {
534 struct serial_struct tmp;
535
536 if (!retinfo)
537 return -EFAULT;
538 tmp.type = info->type;
539 tmp.line = info->line;
540 tmp.port = info->port;
541 tmp.irq = info->ISR->irq;
542
543 memcpy_tofs(retinfo,&tmp,sizeof(*retinfo));
544 return 0;
545 }
546
547 static int set_serial_info(struct async_struct * info,
548 struct serial_struct * new_info)
549 {
550 struct serial_struct tmp;
551 async_ISR ISR;
552 unsigned int new_port;
553 unsigned int irq,new_irq;
554 int retval;
555 struct sigaction sa;
556
557 if (!suser())
558 return -EPERM;
559 if (!new_info)
560 return -EFAULT;
561 memcpy_fromfs(&tmp,new_info,sizeof(tmp));
562 new_port = tmp.port;
563 new_irq = tmp.irq;
564 if (new_irq > 15 || new_port > 0xffff)
565 return -EINVAL;
566 if (new_irq == 2)
567 new_irq = 9;
568 ISR = info->ISR;
569 irq = ISR->irq;
570 if (irq == 2)
571 irq = 9;
572 if (!new_irq)
573 new_irq = irq;
574 if (!new_port)
575 new_port = info->port;
576 if (irq != new_irq) {
577
578
579
580
581
582 if (!IRQ_ISR[new_irq]) {
583 sa.sa_handler = rs_interrupt;
584 sa.sa_flags = (SA_INTERRUPT);
585 sa.sa_mask = 0;
586 sa.sa_restorer = NULL;
587 retval = irqaction(new_irq,&sa);
588 if (retval)
589 return retval;
590 }
591
592
593
594
595
596 if (ISR->next_ISR)
597 ISR->next_ISR->prev_ISR = ISR->prev_ISR;
598 if (ISR->prev_ISR)
599 ISR->prev_ISR->next_ISR = ISR->next_ISR;
600 else
601 IRQ_ISR[irq] = ISR->next_ISR;
602 if (!IRQ_ISR[irq])
603 free_irq(irq);
604
605
606
607
608 ISR->prev_ISR = 0;
609 ISR->next_ISR = IRQ_ISR[new_irq];
610 if (ISR->next_ISR)
611 ISR->next_ISR->prev_ISR = ISR;
612 IRQ_ISR[new_irq] = ISR;
613 ISR->irq = new_irq;
614 }
615 cli();
616 if (new_port != info->port) {
617 outb_p(0x00, UART_IER + info->port);
618 outb(0x00, UART_MCR + info->port);
619 info->port = new_port;
620 init(info);
621 startup(info);
622 }
623 sti();
624 return 0;
625 }
626
627 static int get_modem_info(struct async_struct * info, unsigned int *value)
628 {
629 unsigned port;
630 unsigned char control, status;
631 unsigned int result;
632
633 port = info->port;
634 control = inb(UART_MCR + port);
635 status = inb(UART_MSR + port);
636 result = ((control & UART_MCR_RTS) ? TIOCM_RTS : 0)
637 | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0)
638 | ((status & UART_MSR_DCD) ? TIOCM_CAR : 0)
639 | ((status & UART_MSR_RI) ? TIOCM_RNG : 0)
640 | ((status & UART_MSR_DSR) ? TIOCM_DSR : 0)
641 | ((status & UART_MSR_CTS) ? TIOCM_CTS : 0);
642 put_fs_long(result,(unsigned long *) value);
643 return 0;
644 }
645
646 static int set_modem_info(struct async_struct * info, unsigned int cmd,
647 unsigned int *value)
648 {
649 unsigned port;
650 unsigned char control;
651 unsigned int arg = get_fs_long((unsigned long *) value);
652
653 port = info->port;
654 control = inb(UART_MCR + port);
655
656 switch (cmd) {
657 case TIOCMBIS:
658 if (arg & TIOCM_RTS)
659 control |= UART_MCR_RTS;
660 if (arg & TIOCM_DTR)
661 control |= UART_MCR_DTR;
662 break;
663 case TIOCMBIC:
664 if (arg & TIOCM_RTS)
665 control &= ~UART_MCR_RTS;
666 if (arg & TIOCM_DTR)
667 control &= ~UART_MCR_DTR;
668 break;
669 case TIOCMSET:
670 control = (control & ~0x03)
671 | ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0)
672 | ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0);
673 break;
674 default:
675 return -EINVAL;
676 }
677 outb(UART_MCR + port,control);
678 return 0;
679 }
680
681 static int rs_ioctl(struct tty_struct *tty, struct file * file,
682 unsigned int cmd, unsigned int arg)
683 {
684 int line;
685 struct async_struct * info;
686
687 line = DEV_TO_SL(tty->line);
688 if (line < 0 || line >= NR_PORTS)
689 return -ENODEV;
690 info = rs_table + line;
691
692 switch (cmd) {
693 case TCSBRK:
694 wait_until_sent(tty);
695 if (!arg)
696 send_break(info);
697 return 0;
698 case TIOCMGET:
699 verify_area((void *) arg,sizeof(unsigned int *));
700 return get_modem_info(info, (unsigned int *) arg);
701 case TIOCMBIS:
702 case TIOCMBIC:
703 case TIOCMSET:
704 return set_modem_info(info, cmd, (unsigned int *) arg);
705 case TIOCGSERIAL:
706 verify_area((void *) arg,sizeof(struct serial_struct));
707 return get_serial_info(info,
708 (struct serial_struct *) arg);
709 case TIOCSSERIAL:
710 return set_serial_info(info,
711 (struct serial_struct *) arg);
712
713 default:
714 return -EINVAL;
715 }
716 return 0;
717 }
718
719
720
721
722
723
724
725 int rs_open(struct tty_struct *tty, struct file * filp)
726 {
727 struct async_struct *info;
728 async_ISR ISR;
729 int irq, retval, line;
730 struct sigaction sa;
731
732 if (!tty)
733 return -ENODEV;
734 if (tty->count > 1)
735 return 0;
736 line = DEV_TO_SL(tty->line);
737 if ((line < 0) || (line >= NR_PORTS))
738 return -ENODEV;
739 info = rs_table + line;
740 if (!info->port)
741 return -ENODEV;
742 info->tty = tty;
743 tty->write = rs_write;
744 tty->close = rs_close;
745 tty->ioctl = rs_ioctl;
746 ISR = info->ISR;
747 irq = ISR->irq;
748 if (irq == 2)
749 irq = 9;
750 if (!IRQ_ISR[irq]) {
751 sa.sa_handler = rs_interrupt;
752 sa.sa_flags = (SA_INTERRUPT);
753 sa.sa_mask = 0;
754 sa.sa_restorer = NULL;
755 retval = irqaction(irq,&sa);
756 if (retval)
757 return retval;
758 }
759 if (!ISR->refcnt++) {
760
761
762
763
764 ISR->prev_ISR = 0;
765 ISR->next_ISR = IRQ_ISR[irq];
766 if (ISR->next_ISR)
767 ISR->next_ISR->prev_ISR = ISR;
768 IRQ_ISR[irq] = ISR;
769 }
770 startup(info);
771 return 0;
772 }
773
774 long rs_init(long kmem_start)
775 {
776 int i;
777 struct async_struct * info;
778
779 timer_table[RS_TIMER].fn = rs_timer;
780 timer_table[RS_TIMER].expires = 0;
781 for (i = 0; i < 16; i++) {
782 IRQ_ISR[i] = 0;
783 }
784 for (i = 0, info = rs_table; i < NR_PORTS; i++,info++) {
785 info->line = i;
786 info->tty = 0;
787 info->type = PORT_UNKNOWN;
788 info->timer = 0;
789 info->custom_divisor = 0;
790 if (!info->ISR->line) {
791 info->ISR->line = i;
792 info->ISR->refcnt = 0;
793 info->ISR->next_ISR = 0;
794 info->ISR->prev_ISR = 0;
795 }
796 init(info);
797 if (info->type == PORT_UNKNOWN)
798 continue;
799 printk("ttys%d%s at 0x%04x (irq = %d)", info->line,
800 (info->flags & ASYNC_FOURPORT) ? " FourPort" : "",
801 info->port, info->ISR->irq);
802 switch (info->type) {
803 case PORT_8250:
804 printk(" is a 8250\n");
805 break;
806 case PORT_16450:
807 printk(" is a 16450\n");
808 break;
809 case PORT_16550:
810 printk(" is a 16550\n");
811 break;
812 case PORT_16550A:
813 printk(" is a 16550A\n");
814 break;
815 default:
816 printk("\n");
817 break;
818 }
819 }
820 return kmem_start;
821 }
822