summaryrefslogtreecommitdiffstats
path: root/sys/i386/isa
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/i386/isa
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/i386/isa')
-rw-r--r--sys/i386/isa/cy.c63
1 files changed, 32 insertions, 31 deletions
diff --git a/sys/i386/isa/cy.c b/sys/i386/isa/cy.c
index 063b9c5..203ed94 100644
--- a/sys/i386/isa/cy.c
+++ b/sys/i386/isa/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;
OpenPOWER on IntegriCloud