aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/rocket.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/rocket.c')
-rw-r--r--drivers/char/rocket.c93
1 files changed, 44 insertions, 49 deletions
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index 56cbba7b6ec0..d83419c3857e 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -84,6 +84,7 @@
84#include <linux/mutex.h> 84#include <linux/mutex.h>
85#include <linux/ioport.h> 85#include <linux/ioport.h>
86#include <linux/delay.h> 86#include <linux/delay.h>
87#include <linux/completion.h>
87#include <linux/wait.h> 88#include <linux/wait.h>
88#include <linux/pci.h> 89#include <linux/pci.h>
89#include <asm/uaccess.h> 90#include <asm/uaccess.h>
@@ -548,8 +549,8 @@ static void rp_handle_port(struct r_port *info)
548static void rp_do_poll(unsigned long dummy) 549static void rp_do_poll(unsigned long dummy)
549{ 550{
550 CONTROLLER_t *ctlp; 551 CONTROLLER_t *ctlp;
551 int ctrl, aiop, ch, line, i; 552 int ctrl, aiop, ch, line;
552 unsigned int xmitmask; 553 unsigned int xmitmask, i;
553 unsigned int CtlMask; 554 unsigned int CtlMask;
554 unsigned char AiopMask; 555 unsigned char AiopMask;
555 Word_t bit; 556 Word_t bit;
@@ -562,7 +563,7 @@ static void rp_do_poll(unsigned long dummy)
562 /* Get a ptr to the board's control struct */ 563 /* Get a ptr to the board's control struct */
563 ctlp = sCtlNumToCtlPtr(ctrl); 564 ctlp = sCtlNumToCtlPtr(ctrl);
564 565
565 /* Get the interupt status from the board */ 566 /* Get the interrupt status from the board */
566#ifdef CONFIG_PCI 567#ifdef CONFIG_PCI
567 if (ctlp->BusType == isPCI) 568 if (ctlp->BusType == isPCI)
568 CtlMask = sPCIGetControllerIntStatus(ctlp); 569 CtlMask = sPCIGetControllerIntStatus(ctlp);
@@ -650,7 +651,7 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev)
650 info->closing_wait = 3000; 651 info->closing_wait = 3000;
651 info->close_delay = 50; 652 info->close_delay = 50;
652 init_waitqueue_head(&info->open_wait); 653 init_waitqueue_head(&info->open_wait);
653 init_waitqueue_head(&info->close_wait); 654 init_completion(&info->close_wait);
654 info->flags &= ~ROCKET_MODE_MASK; 655 info->flags &= ~ROCKET_MODE_MASK;
655 switch (pc104[board][line]) { 656 switch (pc104[board][line]) {
656 case 422: 657 case 422:
@@ -699,8 +700,8 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev)
699 spin_lock_init(&info->slock); 700 spin_lock_init(&info->slock);
700 mutex_init(&info->write_mtx); 701 mutex_init(&info->write_mtx);
701 rp_table[line] = info; 702 rp_table[line] = info;
702 if (pci_dev) 703 tty_register_device(rocket_driver, line, pci_dev ? &pci_dev->dev :
703 tty_register_device(rocket_driver, line, &pci_dev->dev); 704 NULL);
704} 705}
705 706
706/* 707/*
@@ -878,7 +879,8 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
878 if (tty_hung_up_p(filp)) 879 if (tty_hung_up_p(filp))
879 return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS); 880 return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
880 if (info->flags & ROCKET_CLOSING) { 881 if (info->flags & ROCKET_CLOSING) {
881 interruptible_sleep_on(&info->close_wait); 882 if (wait_for_completion_interruptible(&info->close_wait))
883 return -ERESTARTSYS;
882 return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS); 884 return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
883 } 885 }
884 886
@@ -983,8 +985,10 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
983 return -ENOMEM; 985 return -ENOMEM;
984 986
985 if (info->flags & ROCKET_CLOSING) { 987 if (info->flags & ROCKET_CLOSING) {
986 interruptible_sleep_on(&info->close_wait); 988 retval = wait_for_completion_interruptible(&info->close_wait);
987 free_page(page); 989 free_page(page);
990 if (retval)
991 return retval;
988 return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS); 992 return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
989 } 993 }
990 994
@@ -1176,7 +1180,7 @@ static void rp_close(struct tty_struct *tty, struct file *filp)
1176 } 1180 }
1177 info->flags &= ~(ROCKET_INITIALIZED | ROCKET_CLOSING | ROCKET_NORMAL_ACTIVE); 1181 info->flags &= ~(ROCKET_INITIALIZED | ROCKET_CLOSING | ROCKET_NORMAL_ACTIVE);
1178 tty->closing = 0; 1182 tty->closing = 0;
1179 wake_up_interruptible(&info->close_wait); 1183 complete_all(&info->close_wait);
1180 atomic_dec(&rp_num_ports_open); 1184 atomic_dec(&rp_num_ports_open);
1181 1185
1182#ifdef ROCKET_DEBUG_OPEN 1186#ifdef ROCKET_DEBUG_OPEN
@@ -1869,8 +1873,6 @@ static __init int register_PCI(int i, struct pci_dev *dev)
1869 int fast_clock = 0; 1873 int fast_clock = 0;
1870 int altChanRingIndicator = 0; 1874 int altChanRingIndicator = 0;
1871 int ports_per_aiop = 8; 1875 int ports_per_aiop = 8;
1872 int ret;
1873 unsigned int class_rev;
1874 WordIO_t ConfigIO = 0; 1876 WordIO_t ConfigIO = 0;
1875 ByteIO_t UPCIRingInd = 0; 1877 ByteIO_t UPCIRingInd = 0;
1876 1878
@@ -1878,12 +1880,6 @@ static __init int register_PCI(int i, struct pci_dev *dev)
1878 return 0; 1880 return 0;
1879 1881
1880 rcktpt_io_addr[i] = pci_resource_start(dev, 0); 1882 rcktpt_io_addr[i] = pci_resource_start(dev, 0);
1881 ret = pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
1882
1883 if (ret) {
1884 printk(KERN_INFO " Error during register_PCI(), unable to read config dword \n");
1885 return 0;
1886 }
1887 1883
1888 rcktpt_type[i] = ROCKET_TYPE_NORMAL; 1884 rcktpt_type[i] = ROCKET_TYPE_NORMAL;
1889 rocketModel[i].loadrm2 = 0; 1885 rocketModel[i].loadrm2 = 0;
@@ -2037,8 +2033,9 @@ static __init int register_PCI(int i, struct pci_dev *dev)
2037 ports_per_aiop = 6; 2033 ports_per_aiop = 6;
2038 str = "6-port"; 2034 str = "6-port";
2039 2035
2040 /* If class_rev is 1, the rocketmodem flash must be loaded. If it is 2 it is a "socketed" version. */ 2036 /* If revision is 1, the rocketmodem flash must be loaded.
2041 if ((class_rev & 0xFF) == 1) { 2037 * If it is 2 it is a "socketed" version. */
2038 if (dev->revision == 1) {
2042 rcktpt_type[i] = ROCKET_TYPE_MODEMII; 2039 rcktpt_type[i] = ROCKET_TYPE_MODEMII;
2043 rocketModel[i].loadrm2 = 1; 2040 rocketModel[i].loadrm2 = 1;
2044 } else { 2041 } else {
@@ -2053,7 +2050,7 @@ static __init int register_PCI(int i, struct pci_dev *dev)
2053 max_num_aiops = 1; 2050 max_num_aiops = 1;
2054 ports_per_aiop = 4; 2051 ports_per_aiop = 4;
2055 str = "4-port"; 2052 str = "4-port";
2056 if ((class_rev & 0xFF) == 1) { 2053 if (dev->revision == 1) {
2057 rcktpt_type[i] = ROCKET_TYPE_MODEMII; 2054 rcktpt_type[i] = ROCKET_TYPE_MODEMII;
2058 rocketModel[i].loadrm2 = 1; 2055 rocketModel[i].loadrm2 = 1;
2059 } else { 2056 } else {
@@ -2362,26 +2359,14 @@ static const struct tty_operations rocket_ops = {
2362 */ 2359 */
2363static int __init rp_init(void) 2360static int __init rp_init(void)
2364{ 2361{
2365 int retval, pci_boards_found, isa_boards_found, i; 2362 int ret = -ENOMEM, pci_boards_found, isa_boards_found, i;
2366 2363
2367 printk(KERN_INFO "RocketPort device driver module, version %s, %s\n", 2364 printk(KERN_INFO "RocketPort device driver module, version %s, %s\n",
2368 ROCKET_VERSION, ROCKET_DATE); 2365 ROCKET_VERSION, ROCKET_DATE);
2369 2366
2370 rocket_driver = alloc_tty_driver(MAX_RP_PORTS); 2367 rocket_driver = alloc_tty_driver(MAX_RP_PORTS);
2371 if (!rocket_driver) 2368 if (!rocket_driver)
2372 return -ENOMEM; 2369 goto err;
2373
2374 /*
2375 * Initialize the array of pointers to our own internal state
2376 * structures.
2377 */
2378 memset(rp_table, 0, sizeof (rp_table));
2379 memset(xmit_flags, 0, sizeof (xmit_flags));
2380
2381 for (i = 0; i < MAX_RP_PORTS; i++)
2382 lineNumbers[i] = 0;
2383 nextLineNumber = 0;
2384 memset(rocketModel, 0, sizeof (rocketModel));
2385 2370
2386 /* 2371 /*
2387 * If board 1 is non-zero, there is at least one ISA configured. If controller is 2372 * If board 1 is non-zero, there is at least one ISA configured. If controller is
@@ -2396,8 +2381,11 @@ static int __init rp_init(void)
2396 2381
2397 /* If an ISA card is configured, reserve the 4 byte IO space for the Mudbac controller */ 2382 /* If an ISA card is configured, reserve the 4 byte IO space for the Mudbac controller */
2398 if (controller && (!request_region(controller, 4, "Comtrol RocketPort"))) { 2383 if (controller && (!request_region(controller, 4, "Comtrol RocketPort"))) {
2399 printk(KERN_INFO "Unable to reserve IO region for first configured ISA RocketPort controller 0x%lx. Driver exiting \n", controller); 2384 printk(KERN_ERR "Unable to reserve IO region for first "
2400 return -EBUSY; 2385 "configured ISA RocketPort controller 0x%lx. "
2386 "Driver exiting\n", controller);
2387 ret = -EBUSY;
2388 goto err_tty;
2401 } 2389 }
2402 2390
2403 /* Store ISA variable retrieved from command line or .conf file. */ 2391 /* Store ISA variable retrieved from command line or .conf file. */
@@ -2434,15 +2422,14 @@ static int __init rp_init(void)
2434 rocket_driver->init_termios.c_ispeed = 9600; 2422 rocket_driver->init_termios.c_ispeed = 9600;
2435 rocket_driver->init_termios.c_ospeed = 9600; 2423 rocket_driver->init_termios.c_ospeed = 9600;
2436#ifdef ROCKET_SOFT_FLOW 2424#ifdef ROCKET_SOFT_FLOW
2437 rocket_driver->flags |= TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; 2425 rocket_driver->flags |= TTY_DRIVER_REAL_RAW;
2438#endif 2426#endif
2439 tty_set_operations(rocket_driver, &rocket_ops); 2427 tty_set_operations(rocket_driver, &rocket_ops);
2440 2428
2441 retval = tty_register_driver(rocket_driver); 2429 ret = tty_register_driver(rocket_driver);
2442 if (retval < 0) { 2430 if (ret < 0) {
2443 printk(KERN_INFO "Couldn't install tty RocketPort driver (error %d)\n", -retval); 2431 printk(KERN_ERR "Couldn't install tty RocketPort driver\n");
2444 put_tty_driver(rocket_driver); 2432 goto err_tty;
2445 return -1;
2446 } 2433 }
2447 2434
2448#ifdef ROCKET_DEBUG_OPEN 2435#ifdef ROCKET_DEBUG_OPEN
@@ -2469,14 +2456,18 @@ static int __init rp_init(void)
2469 max_board = pci_boards_found + isa_boards_found; 2456 max_board = pci_boards_found + isa_boards_found;
2470 2457
2471 if (max_board == 0) { 2458 if (max_board == 0) {
2472 printk(KERN_INFO "No rocketport ports found; unloading driver.\n"); 2459 printk(KERN_ERR "No rocketport ports found; unloading driver\n");
2473 del_timer_sync(&rocket_timer); 2460 ret = -ENXIO;
2474 tty_unregister_driver(rocket_driver); 2461 goto err_ttyu;
2475 put_tty_driver(rocket_driver);
2476 return -ENXIO;
2477 } 2462 }
2478 2463
2479 return 0; 2464 return 0;
2465err_ttyu:
2466 tty_unregister_driver(rocket_driver);
2467err_tty:
2468 put_tty_driver(rocket_driver);
2469err:
2470 return ret;
2480} 2471}
2481 2472
2482 2473
@@ -2491,10 +2482,14 @@ static void rp_cleanup_module(void)
2491 if (retval) 2482 if (retval)
2492 printk(KERN_INFO "Error %d while trying to unregister " 2483 printk(KERN_INFO "Error %d while trying to unregister "
2493 "rocketport driver\n", -retval); 2484 "rocketport driver\n", -retval);
2494 put_tty_driver(rocket_driver);
2495 2485
2496 for (i = 0; i < MAX_RP_PORTS; i++) 2486 for (i = 0; i < MAX_RP_PORTS; i++)
2497 kfree(rp_table[i]); 2487 if (rp_table[i]) {
2488 tty_unregister_device(rocket_driver, i);
2489 kfree(rp_table[i]);
2490 }
2491
2492 put_tty_driver(rocket_driver);
2498 2493
2499 for (i = 0; i < NUM_BOARDS; i++) { 2494 for (i = 0; i < NUM_BOARDS; i++) {
2500 if (rcktpt_io_addr[i] <= 0 || is_PCI[i]) 2495 if (rcktpt_io_addr[i] <= 0 || is_PCI[i])