]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/char/isicom.c
drm: fix return value check
[linux-2.6-omap-h63xx.git] / drivers / char / isicom.c
index 51fa317e695ca790ccd45a2e26e0740bfe16fecd..5a747e685993314618e25729cf56b5f796679e0e 100644 (file)
@@ -172,12 +172,14 @@ static struct pci_driver isicom_driver = {
 static int prev_card = 3;      /*      start servicing isi_card[0]     */
 static struct tty_driver *isicom_normal;
 
-static struct timer_list tx;
+static DECLARE_COMPLETION(isi_timerdone);
 static char re_schedule = 1;
 
 static void isicom_tx(unsigned long _data);
 static void isicom_start(struct tty_struct *tty);
 
+static DEFINE_TIMER(tx, isicom_tx, 0, 0);
+
 /*   baud index mappings from linux defns to isi */
 
 static signed char linuxb_to_isib[] = {
@@ -195,6 +197,7 @@ struct      isi_board {
        signed char             count;
        spinlock_t              card_lock; /* Card wide lock 11/5/00 -sameer */
        unsigned long           flags;
+       unsigned int            index;
 };
 
 struct isi_port {
@@ -513,17 +516,11 @@ static void isicom_tx(unsigned long _data)
        /*      schedule another tx for hopefully in about 10ms */
 sched_again:
        if (!re_schedule) {
-               re_schedule = 2;
+               complete(&isi_timerdone);
                return;
        }
 
-       init_timer(&tx);
-       tx.expires = jiffies + HZ/100;
-       tx.data = 0;
-       tx.function = isicom_tx;
-       add_timer(&tx);
-
-       return;
+       mod_timer(&tx, jiffies + msecs_to_jiffies(10));
 }
 
 /*     Interrupt handlers      */
@@ -949,8 +946,8 @@ static int isicom_open(struct tty_struct *tty, struct file *filp)
 {
        struct isi_port *port;
        struct isi_board *card;
-       unsigned int line, board;
-       int error;
+       unsigned int board;
+       int error, line;
 
        line = tty->index;
        if (line < 0 || line > PORT_COUNT-1)
@@ -1708,6 +1705,11 @@ static int __devinit load_firmware(struct pci_dev *pdev,
                }
 
                data = kmalloc(word_count * 2, GFP_KERNEL);
+               if (data == NULL) {
+                       dev_err(&pdev->dev, "Card%d, firmware upload "
+                               "failed, not enough memory\n", index + 1);
+                       goto errrelfw;
+               }
                inw(base);
                insw(base, data, word_count);
                InterruptTheCard(base);
@@ -1781,13 +1783,15 @@ static int __devinit isicom_probe(struct pci_dev *pdev,
                        break;
                }
 
+       board->index = index;
        board->base = ioaddr;
        board->irq = pciirq;
        card++;
 
        pci_set_drvdata(pdev, board);
 
-       if (!request_region(board->base, 16, ISICOM_NAME)) {
+       retval = pci_request_region(pdev, 3, ISICOM_NAME);
+       if (retval) {
                dev_err(&pdev->dev, "I/O Region 0x%lx-0x%lx is busy. Card%d "
                        "will be disabled.\n", board->base, board->base + 15,
                        index + 1);
@@ -1811,12 +1815,16 @@ static int __devinit isicom_probe(struct pci_dev *pdev,
        if (retval < 0)
                goto errunri;
 
+       for (index = 0; index < board->port_count; index++)
+               tty_register_device(isicom_normal, board->index * 16 + index,
+                               &pdev->dev);
+
        return 0;
 
 errunri:
        free_irq(board->irq, board);
 errunrr:
-       release_region(board->base, 16);
+       pci_release_region(pdev, 3);
 err:
        board->base = 0;
        return retval;
@@ -1825,9 +1833,13 @@ err:
 static void __devexit isicom_remove(struct pci_dev *pdev)
 {
        struct isi_board *board = pci_get_drvdata(pdev);
+       unsigned int i;
+
+       for (i = 0; i < board->port_count; i++)
+               tty_unregister_device(isicom_normal, board->index * 16 + i);
 
        free_irq(board->irq, board);
-       release_region(board->base, 16);
+       pci_release_region(pdev, 3);
 }
 
 static int __init isicom_init(void)
@@ -1836,7 +1848,6 @@ static int __init isicom_init(void)
        struct isi_port *port;
 
        card = 0;
-       memset(isi_ports, 0, sizeof(isi_ports));
 
        for(idx = 0; idx < BOARD_COUNT; idx++) {
                port = &isi_ports[idx * 16];
@@ -1875,7 +1886,8 @@ static int __init isicom_init(void)
        isicom_normal->init_termios             = tty_std_termios;
        isicom_normal->init_termios.c_cflag     = B9600 | CS8 | CREAD | HUPCL |
                CLOCAL;
-       isicom_normal->flags                    = TTY_DRIVER_REAL_RAW;
+       isicom_normal->flags                    = TTY_DRIVER_REAL_RAW |
+               TTY_DRIVER_DYNAMIC_DEV;
        tty_set_operations(isicom_normal, &isicom_ops);
 
        retval = tty_register_driver(isicom_normal);
@@ -1890,12 +1902,7 @@ static int __init isicom_init(void)
                goto err_unrtty;
        }
 
-       init_timer(&tx);
-       tx.expires = jiffies + 1;
-       tx.data = 0;
-       tx.function = isicom_tx;
-       re_schedule = 1;
-       add_timer(&tx);
+       mod_timer(&tx, jiffies + 1);
 
        return 0;
 err_unrtty:
@@ -1908,12 +1915,9 @@ error:
 
 static void __exit isicom_exit(void)
 {
-       unsigned int index = 0;
-
        re_schedule = 0;
 
-       while (re_schedule != 2 && index++ < 100)
-               msleep(10);
+       wait_for_completion_timeout(&isi_timerdone, HZ);
 
        pci_unregister_driver(&isicom_driver);
        tty_unregister_driver(isicom_normal);