1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-17 10:26:15 +00:00

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
This commit is contained in:
Warner Losh 2000-03-11 20:22:09 +00:00
parent 5f2cd67530
commit 633f93bee5
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=57915
2 changed files with 34 additions and 24 deletions

View File

@ -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) {

View File

@ -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) {