aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/isicom.c112
1 files changed, 59 insertions, 53 deletions
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 55a47b33ff34..e9ebabaf8cb0 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -189,7 +189,7 @@ struct isi_board {
189 unsigned char irq; 189 unsigned char irq;
190 unsigned char port_count; 190 unsigned char port_count;
191 unsigned short status; 191 unsigned short status;
192 unsigned short port_status; /* each bit represents a single port */ 192 unsigned short port_status; /* each bit for each port */
193 unsigned short shift_count; 193 unsigned short shift_count;
194 struct isi_port * ports; 194 struct isi_port * ports;
195 signed char count; 195 signed char count;
@@ -242,7 +242,9 @@ static int lock_card(struct isi_board *card)
242 udelay(1000); /* 1ms */ 242 udelay(1000); /* 1ms */
243 } 243 }
244 } 244 }
245 printk(KERN_WARNING "ISICOM: Failed to lock Card (0x%lx)\n", card->base); 245 printk(KERN_WARNING "ISICOM: Failed to lock Card (0x%lx)\n",
246 card->base);
247
246 return 0; /* Failed to aquire the card! */ 248 return 0; /* Failed to aquire the card! */
247} 249}
248 250
@@ -466,33 +468,36 @@ static void isicom_tx(unsigned long _data)
466 residue = NO; 468 residue = NO;
467 wrd = 0; 469 wrd = 0;
468 while (1) { 470 while (1) {
469 cnt = min_t(int, txcount, (SERIAL_XMIT_SIZE - port->xmit_tail)); 471 cnt = min_t(int, txcount, (SERIAL_XMIT_SIZE
472 - port->xmit_tail));
470 if (residue == YES) { 473 if (residue == YES) {
471 residue = NO; 474 residue = NO;
472 if (cnt > 0) { 475 if (cnt > 0) {
473 wrd |= (port->xmit_buf[port->xmit_tail] << 8); 476 wrd |= (port->xmit_buf[port->xmit_tail]
474 port->xmit_tail = (port->xmit_tail + 1) & (SERIAL_XMIT_SIZE - 1); 477 << 8);
478 port->xmit_tail = (port->xmit_tail + 1)
479 & (SERIAL_XMIT_SIZE - 1);
475 port->xmit_cnt--; 480 port->xmit_cnt--;
476 txcount--; 481 txcount--;
477 cnt--; 482 cnt--;
478 outw(wrd, base); 483 outw(wrd, base);
479 } 484 } else {
480 else {
481 outw(wrd, base); 485 outw(wrd, base);
482 break; 486 break;
483 } 487 }
484 } 488 }
485 if (cnt <= 0) break; 489 if (cnt <= 0) break;
486 word_count = cnt >> 1; 490 word_count = cnt >> 1;
487 outsw(base, port->xmit_buf+port->xmit_tail, word_count); 491 outsw(base, port->xmit_buf+port->xmit_tail,word_count);
488 port->xmit_tail = (port->xmit_tail + (word_count << 1)) & 492 port->xmit_tail = (port->xmit_tail
489 (SERIAL_XMIT_SIZE - 1); 493 + (word_count << 1)) & (SERIAL_XMIT_SIZE - 1);
490 txcount -= (word_count << 1); 494 txcount -= (word_count << 1);
491 port->xmit_cnt -= (word_count << 1); 495 port->xmit_cnt -= (word_count << 1);
492 if (cnt & 0x0001) { 496 if (cnt & 0x0001) {
493 residue = YES; 497 residue = YES;
494 wrd = port->xmit_buf[port->xmit_tail]; 498 wrd = port->xmit_buf[port->xmit_tail];
495 port->xmit_tail = (port->xmit_tail + 1) & (SERIAL_XMIT_SIZE - 1); 499 port->xmit_tail = (port->xmit_tail + 1)
500 & (SERIAL_XMIT_SIZE - 1);
496 port->xmit_cnt--; 501 port->xmit_cnt--;
497 txcount--; 502 txcount--;
498 } 503 }
@@ -572,8 +577,8 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id, struct pt_regs *regs)
572 byte_count = header & 0xff; 577 byte_count = header & 0xff;
573 578
574 if (channel + 1 > card->port_count) { 579 if (channel + 1 > card->port_count) {
575 printk(KERN_WARNING "ISICOM: isicom_interrupt(0x%lx): %d(channel) > port_count.\n", 580 printk(KERN_WARNING "ISICOM: isicom_interrupt(0x%lx): "
576 base, channel+1); 581 "%d(channel) > port_count.\n", base, channel+1);
577 if (card->isa) 582 if (card->isa)
578 ClearInterrupt(base); 583 ClearInterrupt(base);
579 else 584 else
@@ -611,26 +616,22 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id, struct pt_regs *regs)
611 header = inw(base); 616 header = inw(base);
612 switch(header & 0xff) { 617 switch(header & 0xff) {
613 case 0: /* Change in EIA signals */ 618 case 0: /* Change in EIA signals */
614
615 if (port->flags & ASYNC_CHECK_CD) { 619 if (port->flags & ASYNC_CHECK_CD) {
616 if (port->status & ISI_DCD) { 620 if (port->status & ISI_DCD) {
617 if (!(header & ISI_DCD)) { 621 if (!(header & ISI_DCD)) {
618 /* Carrier has been lost */ 622 /* Carrier has been lost */
619 pr_dbg("interrupt: DCD->low.\n"); 623 pr_dbg("interrupt: DCD->low.\n"
624 );
620 port->status &= ~ISI_DCD; 625 port->status &= ~ISI_DCD;
621 schedule_work(&port->hangup_tq); 626 schedule_work(&port->hangup_tq);
622 } 627 }
628 } else if (header & ISI_DCD) {
629 /* Carrier has been detected */
630 pr_dbg("interrupt: DCD->high.\n");
631 port->status |= ISI_DCD;
632 wake_up_interruptible(&port->open_wait);
623 } 633 }
624 else { 634 } else {
625 if (header & ISI_DCD) {
626 /* Carrier has been detected */
627 pr_dbg("interrupt: DCD->high.\n");
628 port->status |= ISI_DCD;
629 wake_up_interruptible(&port->open_wait);
630 }
631 }
632 }
633 else {
634 if (header & ISI_DCD) 635 if (header & ISI_DCD)
635 port->status |= ISI_DCD; 636 port->status |= ISI_DCD;
636 else 637 else
@@ -642,19 +643,16 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id, struct pt_regs *regs)
642 if (header & ISI_CTS) { 643 if (header & ISI_CTS) {
643 port->tty->hw_stopped = 0; 644 port->tty->hw_stopped = 0;
644 /* start tx ing */ 645 /* start tx ing */
645 port->status |= (ISI_TXOK | ISI_CTS); 646 port->status |= (ISI_TXOK
647 | ISI_CTS);
646 schedule_work(&port->bh_tqueue); 648 schedule_work(&port->bh_tqueue);
647 } 649 }
650 } else if (!(header & ISI_CTS)) {
651 port->tty->hw_stopped = 1;
652 /* stop tx ing */
653 port->status &= ~(ISI_TXOK | ISI_CTS);
648 } 654 }
649 else { 655 } else {
650 if (!(header & ISI_CTS)) {
651 port->tty->hw_stopped = 1;
652 /* stop tx ing */
653 port->status &= ~(ISI_TXOK | ISI_CTS);
654 }
655 }
656 }
657 else {
658 if (header & ISI_CTS) 656 if (header & ISI_CTS)
659 port->status |= ISI_CTS; 657 port->status |= ISI_CTS;
660 else 658 else
@@ -673,7 +671,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id, struct pt_regs *regs)
673 671
674 break; 672 break;
675 673
676 case 1: /* Received Break !!! */ 674 case 1: /* Received Break !!! */
677 tty_insert_flip_char(tty, 0, TTY_BREAK); 675 tty_insert_flip_char(tty, 0, TTY_BREAK);
678 if (port->flags & ASYNC_SAK) 676 if (port->flags & ASYNC_SAK)
679 do_SAK(tty); 677 do_SAK(tty);
@@ -688,8 +686,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id, struct pt_regs *regs)
688 pr_dbg("Intr: Unknown code in status packet.\n"); 686 pr_dbg("Intr: Unknown code in status packet.\n");
689 break; 687 break;
690 } 688 }
691 } 689 } else { /* Data Packet */
692 else { /* Data Packet */
693 690
694 count = tty_prepare_flip_string(tty, &rp, byte_count & ~1); 691 count = tty_prepare_flip_string(tty, &rp, byte_count & ~1);
695 pr_dbg("Intr: Can rx %d of %d bytes.\n", count, byte_count); 692 pr_dbg("Intr: Can rx %d of %d bytes.\n", count, byte_count);
@@ -697,7 +694,8 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id, struct pt_regs *regs)
697 insw(base, rp, word_count); 694 insw(base, rp, word_count);
698 byte_count -= (word_count << 1); 695 byte_count -= (word_count << 1);
699 if (count & 0x0001) { 696 if (count & 0x0001) {
700 tty_insert_flip_char(tty, inw(base) & 0xff, TTY_NORMAL); 697 tty_insert_flip_char(tty, inw(base) & 0xff,
698 TTY_NORMAL);
701 byte_count -= 2; 699 byte_count -= 2;
702 } 700 }
703 if (byte_count > 0) { 701 if (byte_count > 0) {
@@ -714,6 +712,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id, struct pt_regs *regs)
714 ClearInterrupt(base); 712 ClearInterrupt(base);
715 else 713 else
716 outw(0x0000, base+0x04); /* enable interrupts */ 714 outw(0x0000, base+0x04); /* enable interrupts */
715
717 return IRQ_HANDLED; 716 return IRQ_HANDLED;
718} 717}
719 718
@@ -885,7 +884,8 @@ static int isicom_setup_port(struct isi_port *port)
885 return 0; 884 return 0;
886} 885}
887 886
888static int block_til_ready(struct tty_struct *tty, struct file *filp, struct isi_port *port) 887static int block_til_ready(struct tty_struct *tty, struct file *filp,
888 struct isi_port *port)
889{ 889{
890 struct isi_board *card = port->card; 890 struct isi_board *card = port->card;
891 int do_clocal = 0, retval; 891 int do_clocal = 0, retval;
@@ -905,7 +905,8 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, struct isi
905 905
906 /* if non-blocking mode is set ... */ 906 /* if non-blocking mode is set ... */
907 907
908 if ((filp->f_flags & O_NONBLOCK) || (tty->flags & (1 << TTY_IO_ERROR))) { 908 if ((filp->f_flags & O_NONBLOCK) ||
909 (tty->flags & (1 << TTY_IO_ERROR))) {
909 pr_dbg("block_til_ready: non-block mode.\n"); 910 pr_dbg("block_til_ready: non-block mode.\n");
910 port->flags |= ASYNC_NORMAL_ACTIVE; 911 port->flags |= ASYNC_NORMAL_ACTIVE;
911 return 0; 912 return 0;
@@ -1051,7 +1052,7 @@ static void isicom_shutdown_port(struct isi_port *port)
1051 card->count = 0; 1052 card->count = 0;
1052 } 1053 }
1053 1054
1054 /* last port was closed , shutdown that boad too */ 1055 /* last port was closed, shutdown that boad too */
1055 if (C_HUPCL(tty)) { 1056 if (C_HUPCL(tty)) {
1056 if (!card->count) 1057 if (!card->count)
1057 isicom_shutdown_board(card); 1058 isicom_shutdown_board(card);
@@ -1078,14 +1079,14 @@ static void isicom_close(struct tty_struct *tty, struct file *filp)
1078 } 1079 }
1079 1080
1080 if (tty->count == 1 && port->count != 1) { 1081 if (tty->count == 1 && port->count != 1) {
1081 printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port count" 1082 printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port "
1082 "tty->count = 1 port count = %d.\n", 1083 "count tty->count = 1 port count = %d.\n",
1083 card->base, port->count); 1084 card->base, port->count);
1084 port->count = 1; 1085 port->count = 1;
1085 } 1086 }
1086 if (--port->count < 0) { 1087 if (--port->count < 0) {
1087 printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port count for" 1088 printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port "
1088 "channel%d = %d", card->base, port->channel, 1089 "count for channel%d = %d", card->base, port->channel,
1089 port->count); 1090 port->count);
1090 port->count = 0; 1091 port->count = 0;
1091 } 1092 }
@@ -1121,7 +1122,8 @@ static void isicom_close(struct tty_struct *tty, struct file *filp)
1121 spin_unlock_irqrestore(&card->card_lock, flags); 1122 spin_unlock_irqrestore(&card->card_lock, flags);
1122 if (port->close_delay) { 1123 if (port->close_delay) {
1123 pr_dbg("scheduling until time out.\n"); 1124 pr_dbg("scheduling until time out.\n");
1124 msleep_interruptible(jiffies_to_msecs(port->close_delay)); 1125 msleep_interruptible(
1126 jiffies_to_msecs(port->close_delay));
1125 } 1127 }
1126 spin_lock_irqsave(&card->card_lock, flags); 1128 spin_lock_irqsave(&card->card_lock, flags);
1127 wake_up_interruptible(&port->open_wait); 1129 wake_up_interruptible(&port->open_wait);
@@ -1149,13 +1151,14 @@ static int isicom_write(struct tty_struct *tty, const unsigned char *buf,
1149 spin_lock_irqsave(&card->card_lock, flags); 1151 spin_lock_irqsave(&card->card_lock, flags);
1150 1152
1151 while(1) { 1153 while(1) {
1152 cnt = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, 1154 cnt = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt
1153 SERIAL_XMIT_SIZE - port->xmit_head)); 1155 - 1, SERIAL_XMIT_SIZE - port->xmit_head));
1154 if (cnt <= 0) 1156 if (cnt <= 0)
1155 break; 1157 break;
1156 1158
1157 memcpy(port->xmit_buf + port->xmit_head, buf, cnt); 1159 memcpy(port->xmit_buf + port->xmit_head, buf, cnt);
1158 port->xmit_head = (port->xmit_head + cnt) & (SERIAL_XMIT_SIZE - 1); 1160 port->xmit_head = (port->xmit_head + cnt) & (SERIAL_XMIT_SIZE
1161 - 1);
1159 port->xmit_cnt += cnt; 1162 port->xmit_cnt += cnt;
1160 buf += cnt; 1163 buf += cnt;
1161 count -= cnt; 1164 count -= cnt;
@@ -1200,7 +1203,8 @@ static void isicom_flush_chars(struct tty_struct *tty)
1200 if (isicom_paranoia_check(port, tty->name, "isicom_flush_chars")) 1203 if (isicom_paranoia_check(port, tty->name, "isicom_flush_chars"))
1201 return; 1204 return;
1202 1205
1203 if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || !port->xmit_buf) 1206 if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
1207 !port->xmit_buf)
1204 return; 1208 return;
1205 1209
1206 /* this tells the transmitter to consider this port for 1210 /* this tells the transmitter to consider this port for
@@ -1233,7 +1237,8 @@ static int isicom_chars_in_buffer(struct tty_struct *tty)
1233} 1237}
1234 1238
1235/* ioctl et all */ 1239/* ioctl et all */
1236static inline void isicom_send_break(struct isi_port *port, unsigned long length) 1240static inline void isicom_send_break(struct isi_port *port,
1241 unsigned long length)
1237{ 1242{
1238 struct isi_board *card = port->card; 1243 struct isi_board *card = port->card;
1239 unsigned long base = card->base; 1244 unsigned long base = card->base;
@@ -1368,7 +1373,8 @@ static int isicom_ioctl(struct tty_struct *tty, struct file *filp,
1368 return 0; 1373 return 0;
1369 1374
1370 case TIOCGSOFTCAR: 1375 case TIOCGSOFTCAR:
1371 return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *)argp); 1376 return put_user(C_CLOCAL(tty) ? 1 : 0,
1377 (unsigned long __user *)argp);
1372 1378
1373 case TIOCSSOFTCAR: 1379 case TIOCSSOFTCAR:
1374 if (get_user(arg, (unsigned long __user *) argp)) 1380 if (get_user(arg, (unsigned long __user *) argp))