diff options
Diffstat (limited to 'drivers/staging/dgnc/dgnc_driver.c')
-rw-r--r-- | drivers/staging/dgnc/dgnc_driver.c | 372 |
1 files changed, 100 insertions, 272 deletions
diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index 764613b2f4b4..21546659ff07 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -57,7 +57,7 @@ MODULE_SUPPORTED_DEVICE("dgnc"); */ PARM_INT(debug, 0x00, 0644, "Driver debugging level"); PARM_INT(rawreadok, 1, 0644, "Bypass flip buffers on input"); -PARM_INT(trcbuf_size, 0x100000, 0644, "Debugging trace buffer size."); +PARM_INT(trcbuf_size, 0x100000, 0644, "Debugging trace buffer size."); /************************************************************************** * @@ -70,26 +70,15 @@ static void dgnc_init_globals(void); static int dgnc_found_board(struct pci_dev *pdev, int id); static void dgnc_cleanup_board(struct dgnc_board *brd); static void dgnc_poll_handler(ulong dummy); -static int dgnc_init_pci(void); static int dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); -static void dgnc_remove_one(struct pci_dev *dev); -static int dgnc_probe1(struct pci_dev *pdev, int card_type); static void dgnc_do_remap(struct dgnc_board *brd); -/* Driver load/unload functions */ -int dgnc_init_module(void); -void dgnc_cleanup_module(void); - -module_init(dgnc_init_module); -module_exit(dgnc_cleanup_module); - - /* * File operations permitted on Control/Management major. */ static const struct file_operations dgnc_BoardFops = { .owner = THIS_MODULE, - .unlocked_ioctl = dgnc_mgmt_ioctl, + .unlocked_ioctl = dgnc_mgmt_ioctl, .open = dgnc_mgmt_open, .release = dgnc_mgmt_close }; @@ -101,23 +90,18 @@ static const struct file_operations dgnc_BoardFops = { uint dgnc_NumBoards; struct dgnc_board *dgnc_Board[MAXBOARDS]; DEFINE_SPINLOCK(dgnc_global_lock); -int dgnc_driver_state = DRIVER_INITIALIZED; -ulong dgnc_poll_counter; uint dgnc_Major; int dgnc_poll_tick = 20; /* Poll interval - 20 ms */ /* * Static vars. */ -static uint dgnc_Major_Control_Registered = FALSE; -static uint dgnc_driver_start = FALSE; - static struct class *dgnc_class; /* * Poller stuff */ -static DEFINE_SPINLOCK(dgnc_poll_lock); /* Poll scheduling lock */ +static DEFINE_SPINLOCK(dgnc_poll_lock); /* Poll scheduling lock */ static ulong dgnc_poll_time; /* Time of next poll */ static uint dgnc_poll_stop; /* Used to tell poller to stop */ static struct timer_list dgnc_poll_timer; @@ -128,25 +112,12 @@ static struct pci_device_id dgnc_pci_tbl[] = { { DIGI_VID, PCI_DEVICE_CLASSIC_4_422_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, { DIGI_VID, PCI_DEVICE_CLASSIC_8_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 }, { DIGI_VID, PCI_DEVICE_CLASSIC_8_422_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 }, - { DIGI_VID, PCI_DEVICE_NEO_4_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 }, - { DIGI_VID, PCI_DEVICE_NEO_8_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 }, - { DIGI_VID, PCI_DEVICE_NEO_2DB9_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6 }, - { DIGI_VID, PCI_DEVICE_NEO_2DB9PRI_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7 }, - { DIGI_VID, PCI_DEVICE_NEO_2RJ45_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, - { DIGI_VID, PCI_DEVICE_NEO_2RJ45PRI_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9 }, - { DIGI_VID, PCI_DEVICE_NEO_1_422_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 10 }, - { DIGI_VID, PCI_DEVICE_NEO_1_422_485_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11 }, - { DIGI_VID, PCI_DEVICE_NEO_2_422_485_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12 }, - { DIGI_VID, PCI_DEVICE_NEO_EXPRESS_8_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 13 }, - { DIGI_VID, PCI_DEVICE_NEO_EXPRESS_4_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 }, - { DIGI_VID, PCI_DEVICE_NEO_EXPRESS_4RJ45_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15 }, - { DIGI_VID, PCI_DEVICE_NEO_EXPRESS_8RJ45_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 }, {0,} /* 0 terminated list. */ }; MODULE_DEVICE_TABLE(pci, dgnc_pci_tbl); struct board_id { - uchar *name; + unsigned char *name; uint maxports; unsigned int is_pci_express; }; @@ -176,7 +147,6 @@ static struct pci_driver dgnc_driver = { .name = "dgnc", .probe = dgnc_init_one, .id_table = dgnc_pci_tbl, - .remove = dgnc_remove_one, }; @@ -186,12 +156,6 @@ char *dgnc_state_text[] = { "Board READY", }; -char *dgnc_driver_state_text[] = { - "Driver Initialized", - "Driver Ready." -}; - - /************************************************************************ * @@ -199,13 +163,47 @@ char *dgnc_driver_state_text[] = { * ************************************************************************/ +/* + * dgnc_cleanup_module() + * + * Module unload. This is where it all ends. + */ +static void dgnc_cleanup_module(void) +{ + int i; + unsigned long flags; + + spin_lock_irqsave(&dgnc_poll_lock, flags); + dgnc_poll_stop = 1; + spin_unlock_irqrestore(&dgnc_poll_lock, flags); + + /* Turn off poller right away. */ + del_timer_sync(&dgnc_poll_timer); + + dgnc_remove_driver_sysfiles(&dgnc_driver); + + device_destroy(dgnc_class, MKDEV(dgnc_Major, 0)); + class_destroy(dgnc_class); + unregister_chrdev(dgnc_Major, "dgnc"); + + for (i = 0; i < dgnc_NumBoards; ++i) { + dgnc_remove_ports_sysfiles(dgnc_Board[i]); + dgnc_tty_uninit(dgnc_Board[i]); + dgnc_cleanup_board(dgnc_Board[i]); + } + + dgnc_tty_post_uninit(); + + if (dgnc_NumBoards) + pci_unregister_driver(&dgnc_driver); +} /* * init_module() * * Module load. This is where it all starts. */ -int dgnc_init_module(void) +static int __init dgnc_init_module(void) { int rc = 0; @@ -222,7 +220,7 @@ int dgnc_init_module(void) /* * Find and configure all the cards */ - rc = dgnc_init_pci(); + rc = pci_register_driver(&dgnc_driver); /* * If something went wrong in the scan, bail out of driver. @@ -239,10 +237,11 @@ int dgnc_init_module(void) dgnc_create_driver_sysfiles(&dgnc_driver); } - DPR_INIT(("Finished init_module. Returning %d\n", rc)); return rc; } +module_init(dgnc_init_module); +module_exit(dgnc_cleanup_module); /* * Start of driver. @@ -252,77 +251,54 @@ static int dgnc_start(void) int rc = 0; unsigned long flags; - if (dgnc_driver_start == FALSE) { - - dgnc_driver_start = TRUE; - - /* make sure that the globals are init'd before we do anything else */ - dgnc_init_globals(); + /* make sure that the globals are init'd before we do anything else */ + dgnc_init_globals(); - dgnc_NumBoards = 0; + APR(("For the tools package or updated drivers please visit http://www.digi.com\n")); - APR(("For the tools package or updated drivers please visit http://www.digi.com\n")); - - /* - * Register our base character device into the kernel. - * This allows the download daemon to connect to the downld device - * before any of the boards are init'ed. - */ - if (!dgnc_Major_Control_Registered) { - /* - * Register management/dpa devices - */ - rc = register_chrdev(0, "dgnc", &dgnc_BoardFops); - if (rc <= 0) { - APR(("Can't register dgnc driver device (%d)\n", rc)); - rc = -ENXIO; - return rc; - } - dgnc_Major = rc; - - dgnc_class = class_create(THIS_MODULE, "dgnc_mgmt"); - device_create(dgnc_class, NULL, - MKDEV(dgnc_Major, 0), - NULL, "dgnc_mgmt"); - dgnc_Major_Control_Registered = TRUE; - } + /* + * Register our base character device into the kernel. + * This allows the download daemon to connect to the downld device + * before any of the boards are init'ed. + * + * Register management/dpa devices + */ + rc = register_chrdev(0, "dgnc", &dgnc_BoardFops); + if (rc <= 0) { + APR(("Can't register dgnc driver device (%d)\n", rc)); + return -ENXIO; + } + dgnc_Major = rc; - /* - * Init any global tty stuff. - */ - rc = dgnc_tty_preinit(); + dgnc_class = class_create(THIS_MODULE, "dgnc_mgmt"); + device_create(dgnc_class, NULL, + MKDEV(dgnc_Major, 0), + NULL, "dgnc_mgmt"); - if (rc < 0) { - APR(("tty preinit - not enough memory (%d)\n", rc)); - return rc; - } + /* + * Init any global tty stuff. + */ + rc = dgnc_tty_preinit(); - /* Start the poller */ - DGNC_LOCK(dgnc_poll_lock, flags); - init_timer(&dgnc_poll_timer); - dgnc_poll_timer.function = dgnc_poll_handler; - dgnc_poll_timer.data = 0; - dgnc_poll_time = jiffies + dgnc_jiffies_from_ms(dgnc_poll_tick); - dgnc_poll_timer.expires = dgnc_poll_time; - DGNC_UNLOCK(dgnc_poll_lock, flags); + if (rc < 0) { + APR(("tty preinit - not enough memory (%d)\n", rc)); + return rc; + } - add_timer(&dgnc_poll_timer); + /* Start the poller */ + spin_lock_irqsave(&dgnc_poll_lock, flags); + init_timer(&dgnc_poll_timer); + dgnc_poll_timer.function = dgnc_poll_handler; + dgnc_poll_timer.data = 0; + dgnc_poll_time = jiffies + dgnc_jiffies_from_ms(dgnc_poll_tick); + dgnc_poll_timer.expires = dgnc_poll_time; + spin_unlock_irqrestore(&dgnc_poll_lock, flags); - dgnc_driver_state = DRIVER_READY; - } + add_timer(&dgnc_poll_timer); return rc; } -/* - * Register pci driver, and return how many boards we have. - */ -static int dgnc_init_pci(void) -{ - return pci_register_driver(&dgnc_driver); -} - - /* returns count (>= 0), or negative on error */ static int dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -334,64 +310,13 @@ static int dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (rc < 0) { rc = -EIO; } else { - rc = dgnc_probe1(pdev, ent->driver_data); - if (rc == 0) { + rc = dgnc_found_board(pdev, ent->driver_data); + if (rc == 0) dgnc_NumBoards++; - DPR_INIT(("Incrementing numboards to %d\n", dgnc_NumBoards)); - } } return rc; } -static int dgnc_probe1(struct pci_dev *pdev, int card_type) -{ - return dgnc_found_board(pdev, card_type); -} - - -static void dgnc_remove_one(struct pci_dev *dev) -{ - /* Do Nothing */ -} - -/* - * dgnc_cleanup_module() - * - * Module unload. This is where it all ends. - */ -void dgnc_cleanup_module(void) -{ - int i; - ulong lock_flags; - - DGNC_LOCK(dgnc_poll_lock, lock_flags); - dgnc_poll_stop = 1; - DGNC_UNLOCK(dgnc_poll_lock, lock_flags); - - /* Turn off poller right away. */ - del_timer_sync(&dgnc_poll_timer); - - dgnc_remove_driver_sysfiles(&dgnc_driver); - - if (dgnc_Major_Control_Registered) { - device_destroy(dgnc_class, MKDEV(dgnc_Major, 0)); - class_destroy(dgnc_class); - unregister_chrdev(dgnc_Major, "dgnc"); - } - - for (i = 0; i < dgnc_NumBoards; ++i) { - dgnc_remove_ports_sysfiles(dgnc_Board[i]); - dgnc_tty_uninit(dgnc_Board[i]); - dgnc_cleanup_board(dgnc_Board[i]); - } - - dgnc_tty_post_uninit(); - - if (dgnc_NumBoards) - pci_unregister_driver(&dgnc_driver); -} - - /* * dgnc_cleanup_board() * @@ -431,12 +356,12 @@ static void dgnc_cleanup_board(struct dgnc_board *brd) if (brd->msgbuf_head) { unsigned long flags; - DGNC_LOCK(dgnc_global_lock, flags); + spin_lock_irqsave(&dgnc_global_lock, flags); brd->msgbuf = NULL; printk("%s", brd->msgbuf_head); kfree(brd->msgbuf_head); brd->msgbuf_head = NULL; - DGNC_UNLOCK(dgnc_global_lock, flags); + spin_unlock_irqrestore(&dgnc_global_lock, flags); } /* Free all allocated channels structs */ @@ -472,14 +397,16 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) unsigned long flags; /* get the board structure and prep it */ - brd = dgnc_Board[dgnc_NumBoards] = - kzalloc(sizeof(*brd), GFP_KERNEL); + dgnc_Board[dgnc_NumBoards] = kzalloc(sizeof(*brd), GFP_KERNEL); + brd = dgnc_Board[dgnc_NumBoards]; + if (!brd) return -ENOMEM; /* make a temporary message buffer for the boot messages */ - brd->msgbuf = brd->msgbuf_head = - kzalloc(sizeof(u8) * 8192, GFP_KERNEL); + brd->msgbuf_head = kzalloc(sizeof(u8) * 8192, GFP_KERNEL); + brd->msgbuf = brd->msgbuf_head; + if (!brd->msgbuf) { kfree(brd); return -ENOMEM; @@ -500,8 +427,8 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) brd->dpastatus = BD_NOFEP; init_waitqueue_head(&brd->state_wait); - DGNC_SPINLOCK_INIT(brd->bd_lock); - DGNC_SPINLOCK_INIT(brd->bd_intr_lock); + spin_lock_init(&brd->bd_lock); + spin_lock_init(&brd->bd_intr_lock); brd->state = BOARD_FOUND; @@ -526,8 +453,6 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) brd->dpatype = T_CLASSIC | T_PCIBUS; - DPR_INIT(("dgnc_found_board - Classic.\n")); - /* * For PCI ClassicBoards * PCI Local Address (i.e. "resource" number) space @@ -602,8 +527,6 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) else brd->dpatype = T_NEO | T_PCIBUS; - DPR_INIT(("dgnc_found_board - NEO.\n")); - /* get the PCI Base Address Registers */ brd->membase = pci_resource_start(pdev, 0); brd->membase_end = pci_resource_end(pdev, 0); @@ -677,13 +600,12 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) /* init our poll helper tasklet */ tasklet_init(&brd->helper_tasklet, brd->bd_ops->tasklet, (unsigned long) brd); - DPR_INIT(("dgnc_scan(%d) - printing out the msgbuf\n", i)); - DGNC_LOCK(dgnc_global_lock, flags); + spin_lock_irqsave(&dgnc_global_lock, flags); brd->msgbuf = NULL; printk("%s", brd->msgbuf_head); kfree(brd->msgbuf_head); brd->msgbuf_head = NULL; - DGNC_UNLOCK(dgnc_global_lock, flags); + spin_unlock_irqrestore(&dgnc_global_lock, flags); /* * allocate flip buffer for board. @@ -708,13 +630,9 @@ static int dgnc_finalize_board_init(struct dgnc_board *brd) { int rc = 0; - DPR_INIT(("dgnc_finalize_board_init() - start\n")); - if (!brd || brd->magic != DGNC_BOARD_MAGIC) return -ENODEV; - DPR_INIT(("dgnc_finalize_board_init() - start #2\n")); - if (brd->irq) { rc = request_irq(brd->irq, brd->bd_ops->intr, IRQF_SHARED, "DGNC", brd); @@ -725,9 +643,6 @@ static int dgnc_finalize_board_init(struct dgnc_board *brd) brd->state = BOARD_FAILED; brd->dpastatus = BD_NOFEP; rc = -ENODEV; - } else { - DPR_INIT(("Requested and received usage of IRQ %d\n", - brd->irq)); } } return rc; @@ -743,8 +658,6 @@ static void dgnc_do_remap(struct dgnc_board *brd) return; brd->re_map_membase = ioremap(brd->membase, 0x1000); - - DPR_INIT(("remapped mem: 0x%p\n", brd->re_map_membase)); } @@ -777,44 +690,32 @@ static void dgnc_do_remap(struct dgnc_board *brd) static void dgnc_poll_handler(ulong dummy) { struct dgnc_board *brd; - unsigned long lock_flags; + unsigned long flags; int i; unsigned long new_time; - dgnc_poll_counter++; - - /* - * Do not start the board state machine until - * driver tells us its up and running, and has - * everything it needs. - */ - if (dgnc_driver_state != DRIVER_READY) - goto schedule_poller; - /* Go thru each board, kicking off a tasklet for each if needed */ for (i = 0; i < dgnc_NumBoards; i++) { brd = dgnc_Board[i]; - DGNC_LOCK(brd->bd_lock, lock_flags); + spin_lock_irqsave(&brd->bd_lock, flags); /* If board is in a failed state, don't bother scheduling a tasklet */ if (brd->state == BOARD_FAILED) { - DGNC_UNLOCK(brd->bd_lock, lock_flags); + spin_unlock_irqrestore(&brd->bd_lock, flags); continue; } /* Schedule a poll helper task */ tasklet_schedule(&brd->helper_tasklet); - DGNC_UNLOCK(brd->bd_lock, lock_flags); + spin_unlock_irqrestore(&brd->bd_lock, flags); } -schedule_poller: - /* * Schedule ourself back at the nominal wakeup interval. */ - DGNC_LOCK(dgnc_poll_lock, lock_flags); + spin_lock_irqsave(&dgnc_poll_lock, flags); dgnc_poll_time += dgnc_jiffies_from_ms(dgnc_poll_tick); new_time = dgnc_poll_time - jiffies; @@ -826,7 +727,7 @@ schedule_poller: dgnc_poll_timer.function = dgnc_poll_handler; dgnc_poll_timer.data = 0; dgnc_poll_timer.expires = dgnc_poll_time; - DGNC_UNLOCK(dgnc_poll_lock, lock_flags); + spin_unlock_irqrestore(&dgnc_poll_lock, flags); if (!dgnc_poll_stop) add_timer(&dgnc_poll_timer); @@ -846,6 +747,7 @@ static void dgnc_init_globals(void) dgnc_rawreadok = rawreadok; dgnc_trcbuf_size = trcbuf_size; dgnc_debug = debug; + dgnc_NumBoards = 0; for (i = 0; i < MAXBOARDS; i++) dgnc_Board[i] = NULL; @@ -853,77 +755,3 @@ static void dgnc_init_globals(void) init_timer(&dgnc_poll_timer); } - -/************************************************************************ - * - * Utility functions - * - ************************************************************************/ - -/* - * dgnc_ms_sleep() - * - * Put the driver to sleep for x ms's - * - * Returns 0 if timed out, !0 (showing signal) if interrupted by a signal. - */ -int dgnc_ms_sleep(ulong ms) -{ - current->state = TASK_INTERRUPTIBLE; - schedule_timeout((ms * HZ) / 1000); - return signal_pending(current); -} - - - -/* - * dgnc_ioctl_name() : Returns a text version of each ioctl value. - */ -char *dgnc_ioctl_name(int cmd) -{ - switch (cmd) { - - case TCGETA: return "TCGETA"; - case TCGETS: return "TCGETS"; - case TCSETA: return "TCSETA"; - case TCSETS: return "TCSETS"; - case TCSETAW: return "TCSETAW"; - case TCSETSW: return "TCSETSW"; - case TCSETAF: return "TCSETAF"; - case TCSETSF: return "TCSETSF"; - case TCSBRK: return "TCSBRK"; - case TCXONC: return "TCXONC"; - case TCFLSH: return "TCFLSH"; - case TIOCGSID: return "TIOCGSID"; - - case TIOCGETD: return "TIOCGETD"; - case TIOCSETD: return "TIOCSETD"; - case TIOCGWINSZ: return "TIOCGWINSZ"; - case TIOCSWINSZ: return "TIOCSWINSZ"; - - case TIOCMGET: return "TIOCMGET"; - case TIOCMSET: return "TIOCMSET"; - case TIOCMBIS: return "TIOCMBIS"; - case TIOCMBIC: return "TIOCMBIC"; - - /* from digi.h */ - case DIGI_SETA: return "DIGI_SETA"; - case DIGI_SETAW: return "DIGI_SETAW"; - case DIGI_SETAF: return "DIGI_SETAF"; - case DIGI_SETFLOW: return "DIGI_SETFLOW"; - case DIGI_SETAFLOW: return "DIGI_SETAFLOW"; - case DIGI_GETFLOW: return "DIGI_GETFLOW"; - case DIGI_GETAFLOW: return "DIGI_GETAFLOW"; - case DIGI_GETA: return "DIGI_GETA"; - case DIGI_GEDELAY: return "DIGI_GEDELAY"; - case DIGI_SEDELAY: return "DIGI_SEDELAY"; - case DIGI_GETCUSTOMBAUD: return "DIGI_GETCUSTOMBAUD"; - case DIGI_SETCUSTOMBAUD: return "DIGI_SETCUSTOMBAUD"; - case TIOCMODG: return "TIOCMODG"; - case TIOCMODS: return "TIOCMODS"; - case TIOCSDTR: return "TIOCSDTR"; - case TIOCCDTR: return "TIOCCDTR"; - - default: return "unknown"; - } -} |