diff options
Diffstat (limited to 'drivers/char/rocket.c')
-rw-r--r-- | drivers/char/rocket.c | 93 |
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) | |||
548 | static void rp_do_poll(unsigned long dummy) | 549 | static 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 | */ |
2363 | static int __init rp_init(void) | 2360 | static 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; |
2465 | err_ttyu: | ||
2466 | tty_unregister_driver(rocket_driver); | ||
2467 | err_tty: | ||
2468 | put_tty_driver(rocket_driver); | ||
2469 | err: | ||
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]) |