summaryrefslogtreecommitdiffstats
path: root/sys/dev/cy
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>2003-12-02 12:36:00 +0000
committerbde <bde@FreeBSD.org>2003-12-02 12:36:00 +0000
commit68eb4e63a382af4e61862b702bf07805e988f30c (patch)
treece7ecba2fa1f8e3a071025c81902f0430df0e786 /sys/dev/cy
parent3a0af1aae72ca3322637a9d2f7f8b765835748c7 (diff)
downloadFreeBSD-src-68eb4e63a382af4e61862b702bf07805e988f30c.zip
FreeBSD-src-68eb4e63a382af4e61862b702bf07805e988f30c.tar.gz
Fixed breakage of the pci case of the cy driver by the new interrupt
code. Both the driver and the new code were wrong. Driver interrupt handlers are supposed to take "void *vsc" arg, but some including all COMPAT_ISA drivers and the pci part of the cy driver want an "int unit" arg. They got this using bogus casts of function pointers which should have kept working despite their bogusness. However, the new interrupt code doesn't honor requests to pass an arg of ((void *)0), so things are very broken if the arg is actually a representation of unit 0. The fix is to use a normal "void *vsc" arg for the pci case and a wrapper for the COMPAT_ISA case (of the cy driver). This cleans up new-busification of the pci case but takes the COMPAT_ISA case a little further from new-bus. The corresponding bug for the COMPAT_ISA case has already been fixed similarly using a wrapper in compat_isa.c and we need another wrapper just to undo that. Fixed some directly related style bugs (mainly by removing compatibility cruft). cy.c: Fixed an indirectly related old bug in cyattach_common(). A wrong status was returned in the unlikely event that malloc() failed. Approved by: re (scottl)
Diffstat (limited to 'sys/dev/cy')
-rw-r--r--sys/dev/cy/cy.c63
-rw-r--r--sys/dev/cy/cy_isa.c63
-rw-r--r--sys/dev/cy/cy_pci.c25
3 files changed, 72 insertions, 79 deletions
diff --git a/sys/dev/cy/cy.c b/sys/dev/cy/cy.c
index 063b9c5..203ed94 100644
--- a/sys/dev/cy/cy.c
+++ b/sys/dev/cy/cy.c
@@ -122,8 +122,7 @@ __FBSDID("$FreeBSD$");
#define siodriver cydriver
#define siodtrwakeup cydtrwakeup
#define sioinput cyinput
-#define siointr cyintr
-#define siointr1 cyintr1
+#define siointr1 cyintr
#define sioioctl cyioctl
#define sioopen cyopen
#define siopoll cypoll
@@ -333,10 +332,11 @@ struct com_s {
u_char obuf2[256];
};
-/* PCI driver entry point. */
-int cyattach_common(cy_addr cy_iobase, int cy_align);
-ointhand2_t siointr;
+/* PCI driver entry points. */
+void *cyattach_common(cy_addr cy_iobase, int cy_align);
+driver_intr_t siointr1;
+static ointhand2_t cyointr;
static int cy_units(cy_addr cy_iobase, int cy_align);
static int sioattach(struct isa_device *dev);
static void cd1400_channel_cmd(struct com_s *com, int cmd);
@@ -347,9 +347,6 @@ static void cd_setreg(struct com_s *com, int reg, int val);
static timeout_t siodtrwakeup;
static void comhardclose(struct com_s *com);
static void sioinput(struct com_s *com);
-#if 0
-static void siointr1(struct com_s *com);
-#endif
static int commctl(struct com_s *com, int bits, int how);
static int comparam(struct tty *tp, struct termios *t);
static void siopoll(void *arg);
@@ -510,11 +507,13 @@ static int
sioattach(isdp)
struct isa_device *isdp;
{
- int adapter;
+ int adapter;
+ struct com_s *com;
- adapter = cyattach_common((cy_addr) isdp->id_maddr, 0);
- if (adapter < 0)
+ com = cyattach_common((cy_addr) isdp->id_maddr, 0);
+ if (com == NULL)
return (0);
+ adapter = com->unit / CY_MAX_PORTS;
/*
* XXX
@@ -525,12 +524,12 @@ sioattach(isdp)
printf("cy%d: attached as cy%d\n", isdp->id_unit, adapter);
isdp->id_unit = adapter; /* XXX */
}
- isdp->id_ointr = siointr;
- /* isdp->id_ri_flags |= RI_FAST; XXX unimplemented - use newbus! */
+
+ isdp->id_ointr = cyointr;
return (1);
}
-int
+void *
cyattach_common(cy_iobase, cy_align)
cy_addr cy_iobase;
int cy_align;
@@ -548,11 +547,11 @@ cyattach_common(cy_iobase, cy_align)
printf(
"cy%d: can't attach adapter: insufficient cy devices configured\n",
adapter);
- return (-1);
+ return (NULL);
}
ncyu = cy_units(cy_iobase, cy_align);
if (ncyu == 0)
- return (-1);
+ return (NULL);
cy_nr_cd1400s[adapter] = ncyu;
cy_total_devices++;
@@ -615,7 +614,7 @@ cyattach_common(cy_iobase, cy_align)
}
if (siosetwater(com, com->it_in.c_ispeed) != 0) {
free(com, M_DEVBUF);
- return (0);
+ return (NULL);
}
termioschars(&com->it_in);
com->it_in.c_ispeed = com->it_in.c_ospeed = comdefaultrate;
@@ -656,7 +655,7 @@ cyattach_common(cy_iobase, cy_align)
/* ensure an edge for the next interrupt */
cy_outb(cy_iobase, CY_CLEAR_INTR, cy_align, 0);
- return (adapter);
+ return (com_addr(adapter * CY_MAX_PORTS));
}
static int
@@ -1111,22 +1110,32 @@ sioinput(com)
#endif
}
+static void
+cyointr(int unit)
+{
+ siointr1(com_addr(unit * CY_MAX_PORTS));
+}
+
void
-siointr(unit)
- int unit;
+siointr1(vcom)
+ void *vcom;
{
+ struct com_s *basecom;
int baseu;
int cy_align;
cy_addr cy_iobase;
int cyu;
cy_addr iobase;
u_char status;
+ int unit;
COM_LOCK(); /* XXX could this be placed down lower in the loop? */
- baseu = unit * CY_MAX_PORTS;
- cy_align = com_addr(baseu)->cy_align;
- cy_iobase = com_addr(baseu)->cy_iobase;
+ basecom = (struct com_s *)vcom;
+ baseu = basecom->unit;
+ cy_align = basecom->cy_align;
+ cy_iobase = basecom->cy_iobase;
+ unit = baseu / CY_MAX_PORTS;
/* check each CD1400 in turn */
for (cyu = 0; cyu < cy_nr_cd1400s[unit]; ++cyu) {
@@ -1592,14 +1601,6 @@ terminate_tx_service:
COM_UNLOCK();
}
-#if 0
-static void
-siointr1(com)
- struct com_s *com;
-{
-}
-#endif
-
static int
sioioctl(dev, cmd, data, flag, td)
dev_t dev;
diff --git a/sys/dev/cy/cy_isa.c b/sys/dev/cy/cy_isa.c
index 063b9c5..203ed94 100644
--- a/sys/dev/cy/cy_isa.c
+++ b/sys/dev/cy/cy_isa.c
@@ -122,8 +122,7 @@ __FBSDID("$FreeBSD$");
#define siodriver cydriver
#define siodtrwakeup cydtrwakeup
#define sioinput cyinput
-#define siointr cyintr
-#define siointr1 cyintr1
+#define siointr1 cyintr
#define sioioctl cyioctl
#define sioopen cyopen
#define siopoll cypoll
@@ -333,10 +332,11 @@ struct com_s {
u_char obuf2[256];
};
-/* PCI driver entry point. */
-int cyattach_common(cy_addr cy_iobase, int cy_align);
-ointhand2_t siointr;
+/* PCI driver entry points. */
+void *cyattach_common(cy_addr cy_iobase, int cy_align);
+driver_intr_t siointr1;
+static ointhand2_t cyointr;
static int cy_units(cy_addr cy_iobase, int cy_align);
static int sioattach(struct isa_device *dev);
static void cd1400_channel_cmd(struct com_s *com, int cmd);
@@ -347,9 +347,6 @@ static void cd_setreg(struct com_s *com, int reg, int val);
static timeout_t siodtrwakeup;
static void comhardclose(struct com_s *com);
static void sioinput(struct com_s *com);
-#if 0
-static void siointr1(struct com_s *com);
-#endif
static int commctl(struct com_s *com, int bits, int how);
static int comparam(struct tty *tp, struct termios *t);
static void siopoll(void *arg);
@@ -510,11 +507,13 @@ static int
sioattach(isdp)
struct isa_device *isdp;
{
- int adapter;
+ int adapter;
+ struct com_s *com;
- adapter = cyattach_common((cy_addr) isdp->id_maddr, 0);
- if (adapter < 0)
+ com = cyattach_common((cy_addr) isdp->id_maddr, 0);
+ if (com == NULL)
return (0);
+ adapter = com->unit / CY_MAX_PORTS;
/*
* XXX
@@ -525,12 +524,12 @@ sioattach(isdp)
printf("cy%d: attached as cy%d\n", isdp->id_unit, adapter);
isdp->id_unit = adapter; /* XXX */
}
- isdp->id_ointr = siointr;
- /* isdp->id_ri_flags |= RI_FAST; XXX unimplemented - use newbus! */
+
+ isdp->id_ointr = cyointr;
return (1);
}
-int
+void *
cyattach_common(cy_iobase, cy_align)
cy_addr cy_iobase;
int cy_align;
@@ -548,11 +547,11 @@ cyattach_common(cy_iobase, cy_align)
printf(
"cy%d: can't attach adapter: insufficient cy devices configured\n",
adapter);
- return (-1);
+ return (NULL);
}
ncyu = cy_units(cy_iobase, cy_align);
if (ncyu == 0)
- return (-1);
+ return (NULL);
cy_nr_cd1400s[adapter] = ncyu;
cy_total_devices++;
@@ -615,7 +614,7 @@ cyattach_common(cy_iobase, cy_align)
}
if (siosetwater(com, com->it_in.c_ispeed) != 0) {
free(com, M_DEVBUF);
- return (0);
+ return (NULL);
}
termioschars(&com->it_in);
com->it_in.c_ispeed = com->it_in.c_ospeed = comdefaultrate;
@@ -656,7 +655,7 @@ cyattach_common(cy_iobase, cy_align)
/* ensure an edge for the next interrupt */
cy_outb(cy_iobase, CY_CLEAR_INTR, cy_align, 0);
- return (adapter);
+ return (com_addr(adapter * CY_MAX_PORTS));
}
static int
@@ -1111,22 +1110,32 @@ sioinput(com)
#endif
}
+static void
+cyointr(int unit)
+{
+ siointr1(com_addr(unit * CY_MAX_PORTS));
+}
+
void
-siointr(unit)
- int unit;
+siointr1(vcom)
+ void *vcom;
{
+ struct com_s *basecom;
int baseu;
int cy_align;
cy_addr cy_iobase;
int cyu;
cy_addr iobase;
u_char status;
+ int unit;
COM_LOCK(); /* XXX could this be placed down lower in the loop? */
- baseu = unit * CY_MAX_PORTS;
- cy_align = com_addr(baseu)->cy_align;
- cy_iobase = com_addr(baseu)->cy_iobase;
+ basecom = (struct com_s *)vcom;
+ baseu = basecom->unit;
+ cy_align = basecom->cy_align;
+ cy_iobase = basecom->cy_iobase;
+ unit = baseu / CY_MAX_PORTS;
/* check each CD1400 in turn */
for (cyu = 0; cyu < cy_nr_cd1400s[unit]; ++cyu) {
@@ -1592,14 +1601,6 @@ terminate_tx_service:
COM_UNLOCK();
}
-#if 0
-static void
-siointr1(com)
- struct com_s *com;
-{
-}
-#endif
-
static int
sioioctl(dev, cmd, data, flag, td)
dev_t dev;
diff --git a/sys/dev/cy/cy_pci.c b/sys/dev/cy/cy_pci.c
index ef5cccd..faa660b 100644
--- a/sys/dev/cy/cy_pci.c
+++ b/sys/dev/cy/cy_pci.c
@@ -66,8 +66,8 @@ __FBSDID("$FreeBSD$");
#define PLX_9060 0x0c
#define PLX_9080 0x0d
-extern int cyattach_common(void *, int); /* Not exactly correct */
-extern void cyintr(int);
+void *cyattach_common(u_char volatile *iobase, int cy_align);
+driver_intr_t cyintr;
static int cy_pci_attach(device_t dev);
static int cy_pci_probe(device_t dev);
@@ -110,9 +110,9 @@ cy_pci_attach(dev)
device_t dev;
{
struct resource *ioport_res, *irq_res, *mem_res;
- void *irq_cookie, *vaddr;
+ void *irq_cookie, *vaddr, *vsc;
u_int32_t ioport;
- int adapter, irq_setup, ioport_rid, irq_rid, mem_rid;
+ int irq_setup, ioport_rid, irq_rid, mem_rid;
u_char plx_ver;
ioport_res = NULL;
@@ -137,21 +137,12 @@ cy_pci_attach(dev)
}
vaddr = rman_get_virtual(mem_res);
- adapter = cyattach_common(vaddr, 1);
- if (adapter < 0) {
+ vsc = cyattach_common(vaddr, 1);
+ if (vsc == NULL) {
device_printf(dev, "no ports found!\n");
goto fail;
}
- /*
- * Allocate our interrupt.
- * XXX Using the ISA interrupt handler directly is a bit of a violation
- * since it doesn't actually take the same argument. For PCI, the
- * argument is a void * token, but for ISA it is a unit. Since
- * there is no overlap in PCI/ISA unit numbers for this driver, and
- * since the ISA driver must handle the interrupt anyway, we use
- * the unit number as the token even for PCI.
- */
irq_rid = 0;
irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &irq_rid, 0ul, ~0ul, 0ul,
RF_SHAREABLE | RF_ACTIVE);
@@ -161,13 +152,13 @@ cy_pci_attach(dev)
}
#ifdef CY_PCI_FASTINTR
irq_setup = bus_setup_intr(dev, irq_res, INTR_TYPE_TTY | INTR_FAST,
- (driver_intr_t *)cyintr, (void *)adapter, &irq_cookie);
+ cyintr, vsc, &irq_cookie);
#else
irq_setup = ENXIO;
#endif
if (irq_setup != 0)
irq_setup = bus_setup_intr(dev, irq_res, INTR_TYPE_TTY,
- (driver_intr_t *)cyintr, (void *)adapter, &irq_cookie);
+ cyintr, vsc, &irq_cookie);
if (irq_setup != 0) {
device_printf(dev, "interrupt setup failed\n");
goto fail;
OpenPOWER on IntegriCloud