*/
static char stl_unwanted[SC26198_RXFIFOSIZE];
-/*
- * Keep track of what interrupts we have requested for us.
- * We don't need to request an interrupt twice if it is being
- * shared with another Stallion board.
- */
-static int stl_gotintrs[STL_MAXBRDS];
-static int stl_numintrs;
-
/*****************************************************************************/
static stlbrd_t *stl_brds[STL_MAXBRDS];
/*****************************************************************************/
-#ifdef MODULE
/*
* Define some string labels for arguments passed from the module
* load line. These allow for easy board definitions, and easy
* modification of the io, memory and irq resoucres.
*/
-
+static int stl_nargs = 0;
static char *board0[4];
static char *board1[4];
static char *board2[4];
MODULE_DESCRIPTION("Stallion Multiport Serial Driver");
MODULE_LICENSE("GPL");
-MODULE_PARM(board0, "1-4s");
+module_param_array(board0, charp, &stl_nargs, 0);
MODULE_PARM_DESC(board0, "Board 0 config -> name[,ioaddr[,ioaddr2][,irq]]");
-MODULE_PARM(board1, "1-4s");
+module_param_array(board1, charp, &stl_nargs, 0);
MODULE_PARM_DESC(board1, "Board 1 config -> name[,ioaddr[,ioaddr2][,irq]]");
-MODULE_PARM(board2, "1-4s");
+module_param_array(board2, charp, &stl_nargs, 0);
MODULE_PARM_DESC(board2, "Board 2 config -> name[,ioaddr[,ioaddr2][,irq]]");
-MODULE_PARM(board3, "1-4s");
+module_param_array(board3, charp, &stl_nargs, 0);
MODULE_PARM_DESC(board3, "Board 3 config -> name[,ioaddr[,ioaddr2][,irq]]");
-#endif
-
/*****************************************************************************/
/*
* Declare all those functions in this driver!
*/
-#ifdef MODULE
static void stl_argbrds(void);
static int stl_parsebrd(stlconf_t *confp, char **argp);
static unsigned long stl_atol(char *str);
-#endif
-int stl_init(void);
+static int stl_init(void);
static int stl_open(struct tty_struct *tty, struct file *filp);
static void stl_close(struct tty_struct *tty, struct file *filp);
static int stl_write(struct tty_struct *tty, const unsigned char *buf, int count);
static int stl_brdinit(stlbrd_t *brdp);
static int stl_initports(stlbrd_t *brdp, stlpanel_t *panelp);
-static int stl_mapirq(int irq, char *name);
static int stl_getserial(stlport_t *portp, struct serial_struct __user *sp);
static int stl_setserial(stlport_t *portp, struct serial_struct __user *sp);
static int stl_getbrdstats(combrd_t __user *bp);
static int stl_getportstruct(stlport_t __user *arg);
static int stl_getbrdstruct(stlbrd_t __user *arg);
static int stl_waitcarrier(stlport_t *portp, struct file *filp);
-static void stl_eiointr(stlbrd_t *brdp);
-static void stl_echatintr(stlbrd_t *brdp);
-static void stl_echmcaintr(stlbrd_t *brdp);
-static void stl_echpciintr(stlbrd_t *brdp);
-static void stl_echpci64intr(stlbrd_t *brdp);
+static int stl_eiointr(stlbrd_t *brdp);
+static int stl_echatintr(stlbrd_t *brdp);
+static int stl_echmcaintr(stlbrd_t *brdp);
+static int stl_echpciintr(stlbrd_t *brdp);
+static int stl_echpci64intr(stlbrd_t *brdp);
static void stl_offintr(void *private);
static void *stl_memalloc(int len);
static stlbrd_t *stl_allocbrd(void);
static struct class_simple *stallion_class;
-#ifdef MODULE
-
/*
* Loadable module initialization stuff.
*/
for (i = 0; (i < stl_nrbrds); i++) {
if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL)
continue;
+
+ free_irq(brdp->irq, brdp);
+
for (j = 0; (j < STL_MAXPANELS); j++) {
panelp = brdp->panels[j];
if (panelp == (stlpanel_t *) NULL)
stl_brds[i] = (stlbrd_t *) NULL;
}
- for (i = 0; (i < stl_numintrs); i++)
- free_irq(stl_gotintrs[i], NULL);
-
restore_flags(flags);
}
{
stlconf_t conf;
stlbrd_t *brdp;
- int nrargs, i;
+ int i;
#ifdef DEBUG
printk("stl_argbrds()\n");
#endif
- nrargs = sizeof(stl_brdsp) / sizeof(char **);
-
- for (i = stl_nrbrds; (i < nrargs); i++) {
+ for (i = stl_nrbrds; (i < stl_nargs); i++) {
memset(&conf, 0, sizeof(conf));
if (stl_parsebrd(&conf, stl_brdsp[i]) == 0)
continue;
return(1);
}
-#endif
-
/*****************************************************************************/
/*
static irqreturn_t stl_intr(int irq, void *dev_id, struct pt_regs *regs)
{
- stlbrd_t *brdp;
- int i;
- int handled = 0;
+ stlbrd_t *brdp = (stlbrd_t *) dev_id;
#ifdef DEBUG
- printk("stl_intr(irq=%d,regs=%x)\n", irq, (int) regs);
+ printk("stl_intr(brdp=%x,irq=%d,regs=%x)\n", (int) brdp, irq,
+ (int) regs);
#endif
- for (i = 0; (i < stl_nrbrds); i++) {
- if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL)
- continue;
- if (brdp->state == 0)
- continue;
- handled = 1;
- (* brdp->isr)(brdp);
- }
- return IRQ_RETVAL(handled);
+ return IRQ_RETVAL((* brdp->isr)(brdp));
}
/*****************************************************************************/
* Interrupt service routine for EasyIO board types.
*/
-static void stl_eiointr(stlbrd_t *brdp)
+static int stl_eiointr(stlbrd_t *brdp)
{
stlpanel_t *panelp;
unsigned int iobase;
+ int handled = 0;
panelp = brdp->panels[0];
iobase = panelp->iobase;
- while (inb(brdp->iostatus) & EIO_INTRPEND)
+ while (inb(brdp->iostatus) & EIO_INTRPEND) {
+ handled = 1;
(* panelp->isr)(panelp, iobase);
+ }
+ return handled;
}
/*****************************************************************************/
* Interrupt service routine for ECH-AT board types.
*/
-static void stl_echatintr(stlbrd_t *brdp)
+static int stl_echatintr(stlbrd_t *brdp)
{
stlpanel_t *panelp;
unsigned int ioaddr;
int bnknr;
+ int handled = 0;
outb((brdp->ioctrlval | ECH_BRDENABLE), brdp->ioctrl);
while (inb(brdp->iostatus) & ECH_INTRPEND) {
+ handled = 1;
for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) {
ioaddr = brdp->bnkstataddr[bnknr];
if (inb(ioaddr) & ECH_PNLINTRPEND) {
}
outb((brdp->ioctrlval | ECH_BRDDISABLE), brdp->ioctrl);
+
+ return handled;
}
/*****************************************************************************/
* Interrupt service routine for ECH-MCA board types.
*/
-static void stl_echmcaintr(stlbrd_t *brdp)
+static int stl_echmcaintr(stlbrd_t *brdp)
{
stlpanel_t *panelp;
unsigned int ioaddr;
int bnknr;
+ int handled = 0;
while (inb(brdp->iostatus) & ECH_INTRPEND) {
+ handled = 1;
for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) {
ioaddr = brdp->bnkstataddr[bnknr];
if (inb(ioaddr) & ECH_PNLINTRPEND) {
}
}
}
+ return handled;
}
/*****************************************************************************/
* Interrupt service routine for ECH-PCI board types.
*/
-static void stl_echpciintr(stlbrd_t *brdp)
+static int stl_echpciintr(stlbrd_t *brdp)
{
stlpanel_t *panelp;
unsigned int ioaddr;
int bnknr, recheck;
+ int handled = 0;
while (1) {
recheck = 0;
panelp = brdp->bnk2panel[bnknr];
(* panelp->isr)(panelp, (ioaddr & 0xfffc));
recheck++;
+ handled = 1;
}
}
if (! recheck)
break;
}
+ return handled;
}
/*****************************************************************************/
* Interrupt service routine for ECH-8/64-PCI board types.
*/
-static void stl_echpci64intr(stlbrd_t *brdp)
+static int stl_echpci64intr(stlbrd_t *brdp)
{
stlpanel_t *panelp;
unsigned int ioaddr;
int bnknr;
+ int handled = 0;
while (inb(brdp->ioctrl) & 0x1) {
+ handled = 1;
for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) {
ioaddr = brdp->bnkstataddr[bnknr];
if (inb(ioaddr) & ECH_PNLINTRPEND) {
}
}
}
+
+ return handled;
}
/*****************************************************************************/
/*****************************************************************************/
-/*
- * Map in interrupt vector to this driver. Check that we don't
- * already have this vector mapped, we might be sharing this
- * interrupt across multiple boards.
- */
-
-static int __init stl_mapirq(int irq, char *name)
-{
- int rc, i;
-
-#ifdef DEBUG
- printk("stl_mapirq(irq=%d,name=%s)\n", irq, name);
-#endif
-
- rc = 0;
- for (i = 0; (i < stl_numintrs); i++) {
- if (stl_gotintrs[i] == irq)
- break;
- }
- if (i >= stl_numintrs) {
- if (request_irq(irq, stl_intr, SA_SHIRQ, name, NULL) != 0) {
- printk("STALLION: failed to register interrupt "
- "routine for %s irq=%d\n", name, irq);
- rc = -ENODEV;
- } else {
- stl_gotintrs[stl_numintrs++] = irq;
- }
- }
- return(rc);
-}
-
-/*****************************************************************************/
-
/*
* Initialize all the ports on a panel.
*/
brdp->nrpanels = 1;
brdp->state |= BRD_FOUND;
brdp->hwid = status;
- rc = stl_mapirq(brdp->irq, name);
+ if (request_irq(brdp->irq, stl_intr, SA_SHIRQ, name, brdp) != 0) {
+ printk("STALLION: failed to register interrupt "
+ "routine for %s irq=%d\n", name, brdp->irq);
+ rc = -ENODEV;
+ } else {
+ rc = 0;
+ }
return(rc);
}
outb((brdp->ioctrlval | ECH_BRDDISABLE), brdp->ioctrl);
brdp->state |= BRD_FOUND;
- i = stl_mapirq(brdp->irq, name);
+ if (request_irq(brdp->irq, stl_intr, SA_SHIRQ, name, brdp) != 0) {
+ printk("STALLION: failed to register interrupt "
+ "routine for %s irq=%d\n", name, brdp->irq);
+ i = -ENODEV;
+ } else {
+ i = 0;
+ }
+
return(i);
}
*/
for (i = 0; (i < stl_nrbrds); i++) {
confp = &stl_brdconf[i];
-#ifdef MODULE
stl_parsebrd(confp, stl_brdsp[i]);
-#endif
if ((brdp = stl_allocbrd()) == (stlbrd_t *) NULL)
return(-ENOMEM);
brdp->brdnr = i;
* Find any dynamically supported boards. That is via module load
* line options or auto-detected on the PCI bus.
*/
-#ifdef MODULE
stl_argbrds();
-#endif
#ifdef CONFIG_PCI
stl_findpcibrds();
#endif
/*****************************************************************************/
-int __init stl_init(void)
+static int __init stl_init(void)
{
int i;
printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion);