diff options
author | imp <imp@FreeBSD.org> | 2000-03-11 20:22:09 +0000 |
---|---|---|
committer | imp <imp@FreeBSD.org> | 2000-03-11 20:22:09 +0000 |
commit | 036c5aaf834d805ae8a26e2d784e7ffb1d9f4d61 (patch) | |
tree | f55b0b7d8e147d180690c00e06e0ccf9a1b020aa /sys/isa/sio.c | |
parent | cd961dcd2638c763977d132ff10e831c3b4481fd (diff) | |
download | FreeBSD-src-036c5aaf834d805ae8a26e2d784e7ffb1d9f4d61.zip FreeBSD-src-036c5aaf834d805ae8a26e2d784e7ffb1d9f4d61.tar.gz |
Fix crashes on card eject for pccard modems. We check for NULL when
we get the com address. If so, we go ahead and return. Bruce thinks
there's a bug in the pccard layer that it terminates devices with
extreme prejustice rather than letting them deside for themselves when
to terminate (and he's likely right). This fix doesn't change that,
but instead works around it by checking for NULL pointers at more
places than before.
The detach routine still calls functions at interrupt level that
aren't reentrant. In theory this could cause a problem, but none
showed up in practice. Future versions should correct this problem,
likely by making the detach process a thread/process at the pccard
level. NEWCARD will do this, and the current pccard layer should
likely be modified to that as well, should it live long enough.
A few style nits of the same form that were in my original patch sent
off to bde were also fixed as part of this process. Mostly use of
!ptr and return ENOPARENS.
This should prevent a crash on suspend with an active ppp link as
well, but that wasn't tested.
Reviewed by: bde
Approved by: jkh
Diffstat (limited to 'sys/isa/sio.c')
-rw-r--r-- | sys/isa/sio.c | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/sys/isa/sio.c b/sys/isa/sio.c index e2c8dda..95b8bfeb 100644 --- a/sys/isa/sio.c +++ b/sys/isa/sio.c @@ -442,7 +442,7 @@ sysctl_machdep_comdefaultrate SYSCTL_HANDLER_ARGS return (0); com = com_addr(comconsole); - if (!com) + if (com == NULL) return (ENXIO); /* @@ -510,11 +510,11 @@ sio_pccard_detach(dev) struct com_s *com; com = (struct com_s *) device_get_softc(dev); - if (!com) { + if (com == NULL) { device_printf(dev, "NULL com in siounload\n"); return (0); } - if (!com->iobase) { + if (com->iobase == 0) { device_printf(dev, "already unloaded!\n"); return (0); } @@ -526,17 +526,16 @@ sio_pccard_detach(dev) if (com->ioportres) bus_release_resource(dev, SYS_RES_IOPORT, 0, com->ioportres); if (com->tp && (com->tp->t_state & TS_ISOPEN)) { - device_printf(dev, "unload\n"); + device_printf(dev, "still open, forcing close\n"); com->tp->t_gen++; ttyclose(com->tp); ttwakeup(com->tp); ttwwakeup(com->tp); - device_printf(dev, "Was busy, so crash likely\n"); } else { if (com->ibuf != NULL) free(com->ibuf, M_DEVBUF); - device_printf(dev, "unload, gone\n"); } + device_printf(dev, "unloaded\n"); return (0); } #endif /* NCARD > 0 */ @@ -642,7 +641,7 @@ sioprobe(dev) port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, IO_COMSIZE, RF_ACTIVE); if (!port) - return ENXIO; + return (ENXIO); #if 0 /* @@ -989,7 +988,7 @@ sioattach(dev) port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, IO_COMSIZE, RF_ACTIVE); if (!port) - return ENXIO; + return (ENXIO); iobase = rman_get_start(port); unit = device_get_unit(dev); @@ -1425,6 +1424,8 @@ sioclose(dev, flag, mode, p) if (mynor & CONTROL_MASK) return (0); com = com_addr(MINOR_TO_UNIT(mynor)); + if (com == NULL) + return (ENODEV); tp = com->tp; s = spltty(); (*linesw[tp->t_line].l_close)(tp, flag); @@ -1512,7 +1513,7 @@ sioread(dev, uio, flag) if (mynor & CONTROL_MASK) return (ENODEV); com = com_addr(MINOR_TO_UNIT(mynor)); - if (com->gone) + if (com == NULL || com->gone) return (ENODEV); return ((*linesw[com->tp->t_line].l_read)(com->tp, uio, flag)); } @@ -1533,7 +1534,7 @@ siowrite(dev, uio, flag) unit = MINOR_TO_UNIT(mynor); com = com_addr(unit); - if (com->gone) + if (com == NULL || com->gone) return (ENODEV); /* * (XXX) We disallow virtual consoles if the physical console is @@ -1923,7 +1924,7 @@ sioioctl(dev, cmd, data, flag, p) mynor = minor(dev); com = com_addr(MINOR_TO_UNIT(mynor)); - if (com->gone) + if (com == NULL || com->gone) return (ENODEV); iobase = com->iobase; if (mynor & CONTROL_MASK) { @@ -2159,6 +2160,8 @@ comparam(tp, t) /* parameters are OK, convert them to the com struct and the device */ unit = DEV_TO_UNIT(tp->t_dev); com = com_addr(unit); + if (com == NULL) + return (ENODEV); iobase = com->iobase; s = spltty(); if (divisor == 0) @@ -2392,6 +2395,8 @@ comstart(tp) unit = DEV_TO_UNIT(tp->t_dev); com = com_addr(unit); + if (com == NULL) + return; s = spltty(); disable_intr(); if (tp->t_state & TS_TTSTOP) @@ -2474,7 +2479,7 @@ comstop(tp, rw) struct com_s *com; com = com_addr(DEV_TO_UNIT(tp->t_dev)); - if (com->gone) + if (com == NULL || com->gone) return; disable_intr(); if (rw & FWRITE) { |