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:
parent
5f2cd67530
commit
633f93bee5
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=57915
@ -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) {
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user