1) Add non-blocking I/O on read
2) Add checks to make sure we do not dereference the softc when not found because the device has been removed.
This commit is contained in:
parent
680514601e
commit
7b69218647
@ -397,6 +397,7 @@ ums_detach(device_t self)
|
||||
* the time the process gets a chance to notice. *_close and friends
|
||||
* should be fixed to handle this case.
|
||||
* Or we should do a delayed detach for this.
|
||||
* Does this delay now force tsleep to exit with an error?
|
||||
*/
|
||||
|
||||
#if 0
|
||||
@ -627,7 +628,7 @@ ums_close(dev_t dev, int flag, int fmt, struct proc *p)
|
||||
{
|
||||
USB_GET_SC(ums, UMSUNIT(dev), sc);
|
||||
|
||||
if (sc == NULL)
|
||||
if (!sc)
|
||||
return 0;
|
||||
|
||||
if (sc->sc_enabled)
|
||||
@ -646,14 +647,18 @@ ums_read(dev_t dev, struct uio *uio, int flag)
|
||||
int error;
|
||||
|
||||
s = splusb();
|
||||
if (!sc) {
|
||||
splx(s);
|
||||
return EIO;
|
||||
}
|
||||
|
||||
while (sc->qcount == 0 ) {
|
||||
/* NWH XXX non blocking I/O ??
|
||||
if (non blocking I/O ) {
|
||||
if (flag & IO_NDELAY) { /* non-blocking I/O */
|
||||
splx(s);
|
||||
return EWOULDBLOCK;
|
||||
} else {
|
||||
*/
|
||||
sc->state |= UMS_ASLEEP;
|
||||
}
|
||||
|
||||
sc->state |= UMS_ASLEEP; /* blocking I/O */
|
||||
error = tsleep(sc, PZERO | PCATCH, "umsrea", 0);
|
||||
if (error) {
|
||||
splx(s);
|
||||
@ -662,8 +667,23 @@ ums_read(dev_t dev, struct uio *uio, int flag)
|
||||
splx(s);
|
||||
return EINTR;
|
||||
}
|
||||
#if defined(__FreeBSD__)
|
||||
/* check whether the device is still there */
|
||||
|
||||
sc = devclass_get_softc(ums_devclass, UMSUNIT(dev));
|
||||
if (!sc) {
|
||||
splx(s);
|
||||
return EIO;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX we could optimise the use of splx/splusb somewhat. The writer
|
||||
* process only extends qcount and qtail. We could copy them and use the copies
|
||||
* to do the copying out of the queue.
|
||||
*/
|
||||
|
||||
while ((sc->qcount > 0) && (uio->uio_resid > 0)) {
|
||||
l = (sc->qcount < uio->uio_resid? sc->qcount:uio->uio_resid);
|
||||
if (l > sizeof(buf))
|
||||
@ -694,6 +714,9 @@ ums_poll(dev_t dev, int events, struct proc *p)
|
||||
int revents = 0;
|
||||
int s;
|
||||
|
||||
if (!sc)
|
||||
return 0;
|
||||
|
||||
s = splusb();
|
||||
if (events & (POLLIN | POLLRDNORM)) {
|
||||
if (sc->qcount) {
|
||||
@ -716,6 +739,9 @@ ums_ioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
|
||||
int s;
|
||||
mousemode_t mode;
|
||||
|
||||
if (!sc)
|
||||
return EIO;
|
||||
|
||||
switch(cmd) {
|
||||
case MOUSE_GETHWINFO:
|
||||
*(mousehw_t *)addr = sc->hw;
|
||||
|
Loading…
x
Reference in New Issue
Block a user