diff options
author | bde <bde@FreeBSD.org> | 2003-12-02 12:36:00 +0000 |
---|---|---|
committer | bde <bde@FreeBSD.org> | 2003-12-02 12:36:00 +0000 |
commit | 68eb4e63a382af4e61862b702bf07805e988f30c (patch) | |
tree | ce7ecba2fa1f8e3a071025c81902f0430df0e786 /sys/dev/cy/cy_isa.c | |
parent | 3a0af1aae72ca3322637a9d2f7f8b765835748c7 (diff) | |
download | FreeBSD-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/cy_isa.c')
-rw-r--r-- | sys/dev/cy/cy_isa.c | 63 |
1 files changed, 32 insertions, 31 deletions
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; |