aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/isicom.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/isicom.c')
-rw-r--r--drivers/char/isicom.c109
1 files changed, 56 insertions, 53 deletions
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 6812fda20953..57b115272aaa 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -126,8 +126,8 @@
126#include <linux/delay.h> 126#include <linux/delay.h>
127#include <linux/ioport.h> 127#include <linux/ioport.h>
128 128
129#include <asm/uaccess.h> 129#include <linux/uaccess.h>
130#include <asm/io.h> 130#include <linux/io.h>
131#include <asm/system.h> 131#include <asm/system.h>
132 132
133#include <linux/pci.h> 133#include <linux/pci.h>
@@ -189,7 +189,7 @@ struct isi_board {
189 unsigned short status; 189 unsigned short status;
190 unsigned short port_status; /* each bit for each port */ 190 unsigned short port_status; /* each bit for each port */
191 unsigned short shift_count; 191 unsigned short shift_count;
192 struct isi_port * ports; 192 struct isi_port *ports;
193 signed char count; 193 signed char count;
194 spinlock_t card_lock; /* Card wide lock 11/5/00 -sameer */ 194 spinlock_t card_lock; /* Card wide lock 11/5/00 -sameer */
195 unsigned long flags; 195 unsigned long flags;
@@ -205,11 +205,11 @@ struct isi_port {
205 u16 channel; 205 u16 channel;
206 u16 status; 206 u16 status;
207 u16 closing_wait; 207 u16 closing_wait;
208 struct isi_board * card; 208 struct isi_board *card;
209 struct tty_struct * tty; 209 struct tty_struct *tty;
210 wait_queue_head_t close_wait; 210 wait_queue_head_t close_wait;
211 wait_queue_head_t open_wait; 211 wait_queue_head_t open_wait;
212 unsigned char * xmit_buf; 212 unsigned char *xmit_buf;
213 int xmit_head; 213 int xmit_head;
214 int xmit_tail; 214 int xmit_tail;
215 int xmit_cnt; 215 int xmit_cnt;
@@ -405,7 +405,7 @@ static void isicom_tx(unsigned long _data)
405 405
406 /* find next active board */ 406 /* find next active board */
407 card = (prev_card + 1) & 0x0003; 407 card = (prev_card + 1) & 0x0003;
408 while(count-- > 0) { 408 while (count-- > 0) {
409 if (isi_card[card].status & BOARD_ACTIVE) 409 if (isi_card[card].status & BOARD_ACTIVE)
410 break; 410 break;
411 card = (card + 1) & 0x0003; 411 card = (card + 1) & 0x0003;
@@ -428,7 +428,7 @@ static void isicom_tx(unsigned long _data)
428 if (retries >= 100) 428 if (retries >= 100)
429 goto unlock; 429 goto unlock;
430 430
431 for (;count > 0;count--, port++) { 431 for (; count > 0; count--, port++) {
432 /* port not active or tx disabled to force flow control */ 432 /* port not active or tx disabled to force flow control */
433 if (!(port->flags & ASYNC_INITIALIZED) || 433 if (!(port->flags & ASYNC_INITIALIZED) ||
434 !(port->status & ISI_TXOK)) 434 !(port->status & ISI_TXOK))
@@ -471,9 +471,10 @@ static void isicom_tx(unsigned long _data)
471 break; 471 break;
472 } 472 }
473 } 473 }
474 if (cnt <= 0) break; 474 if (cnt <= 0)
475 break;
475 word_count = cnt >> 1; 476 word_count = cnt >> 1;
476 outsw(base, port->xmit_buf+port->xmit_tail,word_count); 477 outsw(base, port->xmit_buf+port->xmit_tail, word_count);
477 port->xmit_tail = (port->xmit_tail 478 port->xmit_tail = (port->xmit_tail
478 + (word_count << 1)) & (SERIAL_XMIT_SIZE - 1); 479 + (word_count << 1)) & (SERIAL_XMIT_SIZE - 1);
479 txcount -= (word_count << 1); 480 txcount -= (word_count << 1);
@@ -556,7 +557,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
556 tty = port->tty; 557 tty = port->tty;
557 if (tty == NULL) { 558 if (tty == NULL) {
558 word_count = byte_count >> 1; 559 word_count = byte_count >> 1;
559 while(byte_count > 1) { 560 while (byte_count > 1) {
560 inw(base); 561 inw(base);
561 byte_count -= 2; 562 byte_count -= 2;
562 } 563 }
@@ -569,7 +570,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
569 570
570 if (header & 0x8000) { /* Status Packet */ 571 if (header & 0x8000) { /* Status Packet */
571 header = inw(base); 572 header = inw(base);
572 switch(header & 0xff) { 573 switch (header & 0xff) {
573 case 0: /* Change in EIA signals */ 574 case 0: /* Change in EIA signals */
574 if (port->flags & ASYNC_CHECK_CD) { 575 if (port->flags & ASYNC_CHECK_CD) {
575 if (port->status & ISI_DCD) { 576 if (port->status & ISI_DCD) {
@@ -656,7 +657,8 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
656 if (byte_count > 0) { 657 if (byte_count > 0) {
657 pr_dbg("Intr(0x%lx:%d): Flip buffer overflow! dropping " 658 pr_dbg("Intr(0x%lx:%d): Flip buffer overflow! dropping "
658 "bytes...\n", base, channel + 1); 659 "bytes...\n", base, channel + 1);
659 while(byte_count > 0) { /* drain out unread xtra data */ 660 /* drain out unread xtra data */
661 while (byte_count > 0) {
660 inw(base); 662 inw(base);
661 byte_count -= 2; 663 byte_count -= 2;
662 } 664 }
@@ -679,8 +681,11 @@ static void isicom_config_port(struct isi_port *port)
679 shift_count = card->shift_count; 681 shift_count = card->shift_count;
680 unsigned char flow_ctrl; 682 unsigned char flow_ctrl;
681 683
682 if (!(tty = port->tty) || !tty->termios) 684 tty = port->tty;
685
686 if (tty == NULL)
683 return; 687 return;
688 /* FIXME: Switch to new tty baud API */
684 baud = C_BAUD(tty); 689 baud = C_BAUD(tty);
685 if (baud & CBAUDEX) { 690 if (baud & CBAUDEX) {
686 baud &= ~CBAUDEX; 691 baud &= ~CBAUDEX;
@@ -706,7 +711,7 @@ static void isicom_config_port(struct isi_port *port)
706 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) 711 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
707 baud++; /* 57.6 Kbps */ 712 baud++; /* 57.6 Kbps */
708 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) 713 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
709 baud +=2; /* 115 Kbps */ 714 baud += 2; /* 115 Kbps */
710 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) 715 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
711 baud += 3; /* 230 kbps*/ 716 baud += 3; /* 230 kbps*/
712 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) 717 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
@@ -716,15 +721,14 @@ static void isicom_config_port(struct isi_port *port)
716 /* hang up */ 721 /* hang up */
717 drop_dtr(port); 722 drop_dtr(port);
718 return; 723 return;
719 } 724 } else
720 else
721 raise_dtr(port); 725 raise_dtr(port);
722 726
723 if (WaitTillCardIsFree(base) == 0) { 727 if (WaitTillCardIsFree(base) == 0) {
724 outw(0x8000 | (channel << shift_count) |0x03, base); 728 outw(0x8000 | (channel << shift_count) | 0x03, base);
725 outw(linuxb_to_isib[baud] << 8 | 0x03, base); 729 outw(linuxb_to_isib[baud] << 8 | 0x03, base);
726 channel_setup = 0; 730 channel_setup = 0;
727 switch(C_CSIZE(tty)) { 731 switch (C_CSIZE(tty)) {
728 case CS5: 732 case CS5:
729 channel_setup |= ISICOM_CS5; 733 channel_setup |= ISICOM_CS5;
730 break; 734 break;
@@ -767,7 +771,7 @@ static void isicom_config_port(struct isi_port *port)
767 flow_ctrl |= ISICOM_INITIATE_XONXOFF; 771 flow_ctrl |= ISICOM_INITIATE_XONXOFF;
768 772
769 if (WaitTillCardIsFree(base) == 0) { 773 if (WaitTillCardIsFree(base) == 0) {
770 outw(0x8000 | (channel << shift_count) |0x04, base); 774 outw(0x8000 | (channel << shift_count) | 0x04, base);
771 outw(flow_ctrl << 8 | 0x05, base); 775 outw(flow_ctrl << 8 | 0x05, base);
772 outw((STOP_CHAR(tty)) << 8 | (START_CHAR(tty)), base); 776 outw((STOP_CHAR(tty)) << 8 | (START_CHAR(tty)), base);
773 InterruptTheCard(base); 777 InterruptTheCard(base);
@@ -805,20 +809,19 @@ static int isicom_setup_port(struct isi_port *port)
805 struct isi_board *card = port->card; 809 struct isi_board *card = port->card;
806 unsigned long flags; 810 unsigned long flags;
807 811
808 if (port->flags & ASYNC_INITIALIZED) { 812 if (port->flags & ASYNC_INITIALIZED)
809 return 0; 813 return 0;
810 }
811 if (!port->xmit_buf) { 814 if (!port->xmit_buf) {
812 unsigned long page; 815 /* Relies on BKL */
816 void *xmit_buf = (void *)get_zeroed_page(GFP_KERNEL);
813 817
814 if (!(page = get_zeroed_page(GFP_KERNEL))) 818 if (xmit_buf == NULL)
815 return -ENOMEM; 819 return -ENOMEM;
816
817 if (port->xmit_buf) { 820 if (port->xmit_buf) {
818 free_page(page); 821 free_page((unsigned long)xmit_buf);
819 return -ERESTARTSYS; 822 return -ERESTARTSYS;
820 } 823 }
821 port->xmit_buf = (unsigned char *) page; 824 port->xmit_buf = xmit_buf;
822 } 825 }
823 826
824 spin_lock_irqsave(&card->card_lock, flags); 827 spin_lock_irqsave(&card->card_lock, flags);
@@ -949,21 +952,18 @@ static int isicom_open(struct tty_struct *tty, struct file *filp)
949 port->count++; 952 port->count++;
950 tty->driver_data = port; 953 tty->driver_data = port;
951 port->tty = tty; 954 port->tty = tty;
952 if ((error = isicom_setup_port(port))!=0) 955 error = isicom_setup_port(port);
953 return error; 956 if (error == 0)
954 if ((error = block_til_ready(tty, filp, port))!=0) 957 error = block_til_ready(tty, filp, port);
955 return error; 958 return error;
956
957 return 0;
958} 959}
959 960
960/* close et all */ 961/* close et all */
961 962
962static inline void isicom_shutdown_board(struct isi_board *bp) 963static inline void isicom_shutdown_board(struct isi_board *bp)
963{ 964{
964 if (bp->status & BOARD_ACTIVE) { 965 if (bp->status & BOARD_ACTIVE)
965 bp->status &= ~BOARD_ACTIVE; 966 bp->status &= ~BOARD_ACTIVE;
966 }
967} 967}
968 968
969/* card->lock HAS to be held */ 969/* card->lock HAS to be held */
@@ -1119,7 +1119,7 @@ static int isicom_write(struct tty_struct *tty, const unsigned char *buf,
1119 1119
1120 spin_lock_irqsave(&card->card_lock, flags); 1120 spin_lock_irqsave(&card->card_lock, flags);
1121 1121
1122 while(1) { 1122 while (1) {
1123 cnt = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt 1123 cnt = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt
1124 - 1, SERIAL_XMIT_SIZE - port->xmit_head)); 1124 - 1, SERIAL_XMIT_SIZE - port->xmit_head));
1125 if (cnt <= 0) 1125 if (cnt <= 0)
@@ -1153,15 +1153,15 @@ static void isicom_put_char(struct tty_struct *tty, unsigned char ch)
1153 return; 1153 return;
1154 1154
1155 spin_lock_irqsave(&card->card_lock, flags); 1155 spin_lock_irqsave(&card->card_lock, flags);
1156 if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) { 1156 if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1)
1157 spin_unlock_irqrestore(&card->card_lock, flags); 1157 goto out;
1158 return;
1159 }
1160 1158
1161 port->xmit_buf[port->xmit_head++] = ch; 1159 port->xmit_buf[port->xmit_head++] = ch;
1162 port->xmit_head &= (SERIAL_XMIT_SIZE - 1); 1160 port->xmit_head &= (SERIAL_XMIT_SIZE - 1);
1163 port->xmit_cnt++; 1161 port->xmit_cnt++;
1164 spin_unlock_irqrestore(&card->card_lock, flags); 1162 spin_unlock_irqrestore(&card->card_lock, flags);
1163out:
1164 return;
1165} 1165}
1166 1166
1167/* flush_chars et all */ 1167/* flush_chars et all */
@@ -1286,10 +1286,9 @@ static int isicom_set_serial_info(struct isi_port *port,
1286 unlock_kernel(); 1286 unlock_kernel();
1287 return -EPERM; 1287 return -EPERM;
1288 } 1288 }
1289 port->flags = ((port->flags & ~ ASYNC_USR_MASK) | 1289 port->flags = ((port->flags & ~ASYNC_USR_MASK) |
1290 (newinfo.flags & ASYNC_USR_MASK)); 1290 (newinfo.flags & ASYNC_USR_MASK));
1291 } 1291 } else {
1292 else {
1293 port->close_delay = newinfo.close_delay; 1292 port->close_delay = newinfo.close_delay;
1294 port->closing_wait = newinfo.closing_wait; 1293 port->closing_wait = newinfo.closing_wait;
1295 port->flags = ((port->flags & ~ASYNC_FLAGS) | 1294 port->flags = ((port->flags & ~ASYNC_FLAGS) |
@@ -1336,7 +1335,7 @@ static int isicom_ioctl(struct tty_struct *tty, struct file *filp,
1336 if (isicom_paranoia_check(port, tty->name, "isicom_ioctl")) 1335 if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1337 return -ENODEV; 1336 return -ENODEV;
1338 1337
1339 switch(cmd) { 1338 switch (cmd) {
1340 case TCSBRK: 1339 case TCSBRK:
1341 retval = tty_check_change(tty); 1340 retval = tty_check_change(tty);
1342 if (retval) 1341 if (retval)
@@ -1585,7 +1584,7 @@ static int __devinit load_firmware(struct pci_dev *pdev,
1585 default: 1584 default:
1586 dev_err(&pdev->dev, "Unknown signature.\n"); 1585 dev_err(&pdev->dev, "Unknown signature.\n");
1587 goto end; 1586 goto end;
1588 } 1587 }
1589 1588
1590 retval = request_firmware(&fw, name, &pdev->dev); 1589 retval = request_firmware(&fw, name, &pdev->dev);
1591 if (retval) 1590 if (retval)
@@ -1613,7 +1612,8 @@ static int __devinit load_firmware(struct pci_dev *pdev,
1613 if (WaitTillCardIsFree(base)) 1612 if (WaitTillCardIsFree(base))
1614 goto errrelfw; 1613 goto errrelfw;
1615 1614
1616 if ((status = inw(base + 0x4)) != 0) { 1615 status = inw(base + 0x4);
1616 if (status != 0) {
1617 dev_warn(&pdev->dev, "Card%d rejected load header:\n" 1617 dev_warn(&pdev->dev, "Card%d rejected load header:\n"
1618 KERN_WARNING "Address:0x%x\n" 1618 KERN_WARNING "Address:0x%x\n"
1619 KERN_WARNING "Count:0x%x\n" 1619 KERN_WARNING "Count:0x%x\n"
@@ -1630,12 +1630,13 @@ static int __devinit load_firmware(struct pci_dev *pdev,
1630 if (WaitTillCardIsFree(base)) 1630 if (WaitTillCardIsFree(base))
1631 goto errrelfw; 1631 goto errrelfw;
1632 1632
1633 if ((status = inw(base + 0x4)) != 0) { 1633 status = inw(base + 0x4);
1634 if (status != 0) {
1634 dev_err(&pdev->dev, "Card%d got out of sync.Card " 1635 dev_err(&pdev->dev, "Card%d got out of sync.Card "
1635 "Status:0x%x\n", index + 1, status); 1636 "Status:0x%x\n", index + 1, status);
1636 goto errrelfw; 1637 goto errrelfw;
1637 } 1638 }
1638 } 1639 }
1639 1640
1640/* XXX: should we test it by reading it back and comparing with original like 1641/* XXX: should we test it by reading it back and comparing with original like
1641 * in load firmware package? */ 1642 * in load firmware package? */
@@ -1659,7 +1660,8 @@ static int __devinit load_firmware(struct pci_dev *pdev,
1659 if (WaitTillCardIsFree(base)) 1660 if (WaitTillCardIsFree(base))
1660 goto errrelfw; 1661 goto errrelfw;
1661 1662
1662 if ((status = inw(base + 0x4)) != 0) { 1663 status = inw(base + 0x4);
1664 if (status != 0) {
1663 dev_warn(&pdev->dev, "Card%d rejected verify header:\n" 1665 dev_warn(&pdev->dev, "Card%d rejected verify header:\n"
1664 KERN_WARNING "Address:0x%x\n" 1666 KERN_WARNING "Address:0x%x\n"
1665 KERN_WARNING "Count:0x%x\n" 1667 KERN_WARNING "Count:0x%x\n"
@@ -1692,7 +1694,8 @@ static int __devinit load_firmware(struct pci_dev *pdev,
1692 if (WaitTillCardIsFree(base)) 1694 if (WaitTillCardIsFree(base))
1693 goto errrelfw; 1695 goto errrelfw;
1694 1696
1695 if ((status = inw(base + 0x4)) != 0) { 1697 status = inw(base + 0x4);
1698 if (status != 0) {
1696 dev_err(&pdev->dev, "Card%d verify got out of sync. " 1699 dev_err(&pdev->dev, "Card%d verify got out of sync. "
1697 "Card Status:0x%x\n", index + 1, status); 1700 "Card Status:0x%x\n", index + 1, status);
1698 goto errrelfw; 1701 goto errrelfw;
@@ -1757,7 +1760,7 @@ static int __devinit isicom_probe(struct pci_dev *pdev,
1757 index + 1); 1760 index + 1);
1758 retval = -EBUSY; 1761 retval = -EBUSY;
1759 goto errdec; 1762 goto errdec;
1760 } 1763 }
1761 1764
1762 retval = request_irq(board->irq, isicom_interrupt, 1765 retval = request_irq(board->irq, isicom_interrupt,
1763 IRQF_SHARED | IRQF_DISABLED, ISICOM_NAME, board); 1766 IRQF_SHARED | IRQF_DISABLED, ISICOM_NAME, board);
@@ -1811,7 +1814,7 @@ static int __init isicom_init(void)
1811 int retval, idx, channel; 1814 int retval, idx, channel;
1812 struct isi_port *port; 1815 struct isi_port *port;
1813 1816
1814 for(idx = 0; idx < BOARD_COUNT; idx++) { 1817 for (idx = 0; idx < BOARD_COUNT; idx++) {
1815 port = &isi_ports[idx * 16]; 1818 port = &isi_ports[idx * 16];
1816 isi_card[idx].ports = port; 1819 isi_card[idx].ports = port;
1817 spin_lock_init(&isi_card[idx].card_lock); 1820 spin_lock_init(&isi_card[idx].card_lock);
@@ -1825,7 +1828,7 @@ static int __init isicom_init(void)
1825 init_waitqueue_head(&port->open_wait); 1828 init_waitqueue_head(&port->open_wait);
1826 init_waitqueue_head(&port->close_wait); 1829 init_waitqueue_head(&port->close_wait);
1827 /* . . . */ 1830 /* . . . */
1828 } 1831 }
1829 isi_card[idx].base = 0; 1832 isi_card[idx].base = 0;
1830 isi_card[idx].irq = 0; 1833 isi_card[idx].irq = 0;
1831 } 1834 }