summaryrefslogtreecommitdiff
path: root/drivers/staging/dgnc/dgnc_driver.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/dgnc/dgnc_driver.c')
-rw-r--r--drivers/staging/dgnc/dgnc_driver.c372
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";
- }
-}