summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb/ugen.c
diff options
context:
space:
mode:
authorn_hibma <n_hibma@FreeBSD.org>1999-11-17 22:33:51 +0000
committern_hibma <n_hibma@FreeBSD.org>1999-11-17 22:33:51 +0000
commitaeb2d2626b24c89dbb68adb9caebd10bbe02dd43 (patch)
tree4ffabed555c86f3e004db50f4d745f46d25b77c9 /sys/dev/usb/ugen.c
parenta586d3a066b64caa068a9a83440201f39e4d6677 (diff)
downloadFreeBSD-src-aeb2d2626b24c89dbb68adb9caebd10bbe02dd43.zip
FreeBSD-src-aeb2d2626b24c89dbb68adb9caebd10bbe02dd43.tar.gz
Synchronisation with NetBSD as of 1999/11/16:
Cleaning up the code: - Declare many functions static - Change variable names to make them more self explanatory - Change usbd_request_handle -> usbd_xfer_handle - Syntactical changes - Remove some unused code - Other KNF changes Interrupt context handling - Change delay to usbd_delay_ms were possible (takes polling mode into account) - Change detection mechanism for interrupt context Add support for pre-allocation DMA-able memory by device driver Add preliminary support for isochronous to the UHCI driver (not for OHCI yet). usb.c, uhci.c, ohci.c - Initial attempt at detachable USB host controllers - Handle the use_polling flag with a lttle more care and only set it if we are cold booting. usb.c, uhci.c ohci.c, usbdi.c usbdi_util.c usb_subr.c - Make sure an aborted pipe is marked as not running. - Start queued request in the right order. - Insert some more DIAGNOSTIC sanity checks. - Remove (almost) unused definitions USBD_XFER_OUT and USBD_XFER_IN. usb.c, usb_subr.c - Add an event mechanism so that a userland process can watch devices come and go. ohci.c - Handle the case when a USB transfer is so long that it crosses two page (4K) boundaries. OHCI cannot do that with a single TD so we make a chain. ulpt.c - Use a bigger buffer when transferring data. - Pre-allocate the DMA buffer. This makes the driver slightly more efficient. - Comment out the GET_DEVICE_ID code, because for some unknown reason it causes printing to fail sometimes. usb.h - Add a macro to extract the isoc type. - Add a macro to check whether the routine has been entered after splusb and if not, complain. usbdi.c - Fix a glitch in dequeueing and aborting requests on interrupt pipes. - Add a flag in the request to determine if the data copying is done by the driver or the usbdi layer.
Diffstat (limited to 'sys/dev/usb/ugen.c')
-rw-r--r--sys/dev/usb/ugen.c338
1 files changed, 175 insertions, 163 deletions
diff --git a/sys/dev/usb/ugen.c b/sys/dev/usb/ugen.c
index 2d433d4..5c39160 100644
--- a/sys/dev/usb/ugen.c
+++ b/sys/dev/usb/ugen.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ugen.c,v 1.23 1999/09/09 12:26:44 augustss Exp $ */
+/* $NetBSD: ugen.c,v 1.27 1999/10/28 12:08:38 augustss Exp $ */
/* $FreeBSD$ */
/*
@@ -97,7 +97,7 @@ struct ugen_softc {
USBBASEDEVICE sc_dev; /* base device */
usbd_device_handle sc_udev;
- char sc_is_open[USB_MAX_ENDPOINTS][2];
+ char sc_is_open[USB_MAX_ENDPOINTS];
struct ugen_endpoint sc_endpoints[USB_MAX_ENDPOINTS][2];
#define OUT 0
#define IN 1
@@ -136,18 +136,18 @@ static struct cdevsw ugen_cdevsw = {
};
#endif
-void ugenintr __P((usbd_request_handle reqh, usbd_private_handle addr,
- usbd_status status));
+static void ugenintr __P((usbd_xfer_handle xfer, usbd_private_handle addr,
+ usbd_status status));
-int ugen_do_read __P((struct ugen_softc *, int, struct uio *, int));
-int ugen_do_write __P((struct ugen_softc *, int, struct uio *, int));
-int ugen_do_ioctl __P((struct ugen_softc *, int, u_long,
- caddr_t, int, struct proc *));
-int ugen_set_config __P((struct ugen_softc *sc, int configno));
-usb_config_descriptor_t *ugen_get_cdesc __P((struct ugen_softc *sc, int index,
- int *lenp));
-usbd_status ugen_set_interface __P((struct ugen_softc *, int, int));
-int ugen_get_alt_index __P((struct ugen_softc *sc, int ifaceidx));
+static int ugen_do_read __P((struct ugen_softc *, int, struct uio *, int));
+static int ugen_do_write __P((struct ugen_softc *, int, struct uio *, int));
+static int ugen_do_ioctl __P((struct ugen_softc *, int, u_long,
+ caddr_t, int, struct proc *));
+static int ugen_set_config __P((struct ugen_softc *sc, int configno));
+static usb_config_descriptor_t *ugen_get_cdesc __P((struct ugen_softc *sc,
+ int index, int *lenp));
+static usbd_status ugen_set_interface __P((struct ugen_softc *, int, int));
+static int ugen_get_alt_index __P((struct ugen_softc *sc, int ifaceidx));
#define UGENUNIT(n) ((minor(n) >> 4) & 0xf)
#define UGENENDPOINT(n) (minor(n) & 0xf)
@@ -169,7 +169,7 @@ USB_ATTACH(ugen)
{
USB_ATTACH_START(ugen, sc, uaa);
char devinfo[1024];
- usbd_status r;
+ usbd_status err;
int conf;
usbd_devinfo(uaa->device, 0, devinfo);
@@ -178,8 +178,8 @@ USB_ATTACH(ugen)
sc->sc_udev = uaa->device;
conf = 1; /* XXX should not hard code 1 */
- r = ugen_set_config(sc, conf);
- if (r != USBD_NORMAL_COMPLETION) {
+ err = ugen_set_config(sc, conf);
+ if (err) {
printf("%s: setting configuration %d failed\n",
USBDEVNAME(sc->sc_dev), conf);
sc->sc_dying = 1;
@@ -195,10 +195,11 @@ USB_ATTACH(ugen)
}
}
#endif
+
USB_ATTACH_SUCCESS_RETURN;
}
-int
+static int
ugen_set_config(sc, configno)
struct ugen_softc *sc;
int configno;
@@ -209,30 +210,30 @@ ugen_set_config(sc, configno)
struct ugen_endpoint *sce;
u_int8_t niface, nendpt;
int ifaceno, endptno, endpt;
- usbd_status r;
+ usbd_status err;
int dir;
DPRINTFN(1,("ugen_set_config: %s to configno %d, sc=%p\n",
USBDEVNAME(sc->sc_dev), configno, sc));
if (usbd_get_config_descriptor(dev)->bConfigurationValue != configno) {
/* Avoid setting the current value. */
- r = usbd_set_config_no(dev, configno, 0);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
+ err = usbd_set_config_no(dev, configno, 0);
+ if (err)
+ return (err);
}
- r = usbd_interface_count(dev, &niface);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
+ err = usbd_interface_count(dev, &niface);
+ if (err)
+ return (err);
memset(sc->sc_endpoints, 0, sizeof sc->sc_endpoints);
for (ifaceno = 0; ifaceno < niface; ifaceno++) {
DPRINTFN(1,("ugen_set_config: ifaceno %d\n", ifaceno));
- r = usbd_device2interface_handle(dev, ifaceno, &iface);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
- r = usbd_endpoint_count(iface, &nendpt);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
+ err = usbd_device2interface_handle(dev, ifaceno, &iface);
+ if (err)
+ return (err);
+ err = usbd_endpoint_count(iface, &nendpt);
+ if (err)
+ return (err);
for (endptno = 0; endptno < nendpt; endptno++) {
ed = usbd_interface2endpoint_descriptor(iface,endptno);
endpt = ed->bEndpointAddress;
@@ -257,29 +258,31 @@ ugenopen(dev, flag, mode, p)
int mode;
struct proc *p;
{
+ struct ugen_softc *sc;
int unit = UGENUNIT(dev);
int endpt = UGENENDPOINT(dev);
usb_endpoint_descriptor_t *edesc;
struct ugen_endpoint *sce;
int dir, isize;
- usbd_status r;
+ usbd_status err;
USB_GET_SC_OPEN(ugen, unit, sc);
+
DPRINTFN(5, ("ugenopen: flag=%d, mode=%d, unit=%d endpt=%d\n",
flag, mode, unit, endpt));
- if (!sc || sc->sc_dying)
+ if (sc == NULL || sc->sc_dying)
return (ENXIO);
+ if (sc->sc_is_open[endpt])
+ return (EBUSY);
+
if (endpt == USB_CONTROL_ENDPOINT) {
- sc->sc_is_open[USB_CONTROL_ENDPOINT][IN] = 1;
+ sc->sc_is_open[USB_CONTROL_ENDPOINT] = 1;
return (0);
}
/* Make sure there are pipes for all directions. */
for (dir = OUT; dir <= IN; dir++) {
- if (sc->sc_is_open[endpt][dir])
- return (EBUSY);
-
if (flag & (dir == OUT ? FWRITE : FREAD)) {
sce = &sc->sc_endpoints[endpt][dir];
if (sce == 0 || sce->edesc == 0)
@@ -298,8 +301,6 @@ ugenopen(dev, flag, mode, p)
DPRINTFN(5, ("ugenopen: sc=%p, endpt=%d, dir=%d, sce=%p\n",
sc, endpt, dir, sce));
edesc = sce->edesc;
- if (!edesc)
- return (ENXIO);
switch (edesc->bmAttributes & UE_XFERTYPE) {
case UE_INTERRUPT:
isize = UGETW(edesc->wMaxPacketSize);
@@ -308,40 +309,31 @@ ugenopen(dev, flag, mode, p)
sce->ibuf = malloc(isize, M_USBDEV, M_WAITOK);
DPRINTFN(5, ("ugenopen: intr endpt=%d,isize=%d\n",
endpt, isize));
-#if defined(__NetBSD__) || defined(__OpenBSD__)
- if (clalloc(&sce->q, UGEN_IBSIZE, 0) == -1)
- return (ENOMEM);
-#elif defined(__FreeBSD__)
- clist_alloc_cblocks(&sce->q, UGEN_IBSIZE, 0);
-#endif
- r = usbd_open_pipe_intr(sce->iface,
+ if (clalloc(&sce->q, UGEN_IBSIZE, 0) == -1)
+ return (ENOMEM);
+ err = usbd_open_pipe_intr(sce->iface,
edesc->bEndpointAddress,
USBD_SHORT_XFER_OK, &sce->pipeh, sce,
sce->ibuf, isize, ugenintr);
- if (r != USBD_NORMAL_COMPLETION) {
+ if (err) {
free(sce->ibuf, M_USBDEV);
-#if defined(__NetBSD__) || defined(__OpenBSD__)
clfree(&sce->q);
-#elif defined(__FreeBSD__)
- clist_free_cblocks(&sce->q);
-#endif
return (EIO);
}
DPRINTFN(5, ("ugenopen: interrupt open done\n"));
break;
case UE_BULK:
- r = usbd_open_pipe(sce->iface,
- edesc->bEndpointAddress, 0,
- &sce->pipeh);
- if (r != USBD_NORMAL_COMPLETION)
+ err = usbd_open_pipe(sce->iface,
+ edesc->bEndpointAddress, 0, &sce->pipeh);
+ if (err)
return (EIO);
break;
case UE_CONTROL:
case UE_ISOCHRONOUS:
return (EINVAL);
}
- sc->sc_is_open[endpt][dir] = 1;
}
+ sc->sc_is_open[endpt] = 1;
return (0);
}
@@ -352,16 +344,18 @@ ugenclose(dev, flag, mode, p)
int mode;
struct proc *p;
{
- USB_GET_SC(ugen, UGENUNIT(dev), sc);
int endpt = UGENENDPOINT(dev);
+ struct ugen_softc *sc;
struct ugen_endpoint *sce;
int dir;
+ USB_GET_SC(ugen, UGENUNIT(dev), sc);
+
DPRINTFN(5, ("ugenclose: flag=%d, mode=%d, unit=%d, endpt=%d\n",
flag, mode, UGENUNIT(dev), endpt));
#ifdef DIAGNOSTIC
- if (!sc->sc_is_open[endpt][IN] || !sc->sc_is_open[endpt][OUT] ) {
+ if (!sc->sc_is_open[endpt]) {
printf("ugenclose: not open\n");
return (EINVAL);
}
@@ -369,7 +363,7 @@ ugenclose(dev, flag, mode, p)
if (endpt == USB_CONTROL_ENDPOINT) {
DPRINTFN(5, ("ugenclose: close control\n"));
- sc->sc_is_open[USB_CONTROL_ENDPOINT][IN] = 0;
+ sc->sc_is_open[endpt] = 0;
return (0);
}
@@ -377,31 +371,28 @@ ugenclose(dev, flag, mode, p)
if (!(flag & (dir == OUT ? FWRITE : FREAD)))
continue;
sce = &sc->sc_endpoints[endpt][dir];
- if (!sce || !sce->pipeh)
+ if (sce == NULL || sce->pipeh == NULL)
continue;
DPRINTFN(5, ("ugenclose: endpt=%d dir=%d sce=%p\n",
endpt, dir, sce));
usbd_abort_pipe(sce->pipeh);
usbd_close_pipe(sce->pipeh);
- sce->pipeh = 0;
+ sce->pipeh = NULL;
- if (sce->ibuf) {
+ if (sce->ibuf != NULL) {
free(sce->ibuf, M_USBDEV);
- sce->ibuf = 0;
-#if defined(__NetBSD__) || defined(__OpenBSD__)
+ sce->ibuf = NULL;
clfree(&sce->q);
-#elif defined(__FreeBSD__)
- clist_free_cblocks(&sce->q);
-#endif
+
}
- sc->sc_is_open[endpt][dir] = 0;
}
+ sc->sc_is_open[endpt] = 0;
return (0);
}
-int
+static int
ugen_do_read(sc, endpt, uio, flag)
struct ugen_softc *sc;
int endpt;
@@ -411,8 +402,8 @@ ugen_do_read(sc, endpt, uio, flag)
struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][IN];
u_int32_t n, tn;
char buf[UGEN_BBSIZE];
- usbd_request_handle reqh;
- usbd_status r;
+ usbd_xfer_handle xfer;
+ usbd_status err;
int s;
int error = 0;
u_char buffer[UGEN_CHUNK];
@@ -420,15 +411,19 @@ ugen_do_read(sc, endpt, uio, flag)
#ifdef __NetBSD__
DPRINTFN(5, ("ugenread: %d:%d\n", sc->sc_dev.dv_unit, endpt));
#endif
+
if (sc->sc_dying)
return (EIO);
+ if (endpt == USB_CONTROL_ENDPOINT)
+ return (ENODEV);
+
#ifdef DIAGNOSTIC
- if (!sce->edesc) {
+ if (sce->edesc == NULL) {
printf("ugenread: no edesc\n");
return (EIO);
}
- if (!sce->pipeh) {
+ if (sce->pipeh == NULL) {
printf("ugenread: no pipe\n");
return (EIO);
}
@@ -473,21 +468,21 @@ ugen_do_read(sc, endpt, uio, flag)
}
break;
case UE_BULK:
- reqh = usbd_alloc_request(sc->sc_udev);
- if (reqh == 0)
+ xfer = usbd_alloc_request(sc->sc_udev);
+ if (xfer == 0)
return (ENOMEM);
while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) {
DPRINTFN(1, ("ugenread: start transfer %d bytes\n",n));
tn = n;
- r = usbd_bulk_transfer(
- reqh, sce->pipeh,
+ err = usbd_bulk_transfer(
+ xfer, sce->pipeh,
sce->state & UGEN_SHORT_OK ?
USBD_SHORT_XFER_OK : 0,
sce->timeout, buf, &tn, "ugenrb");
- if (r != USBD_NORMAL_COMPLETION) {
- if (r == USBD_INTERRUPTED)
+ if (err) {
+ if (err == USBD_INTERRUPTED)
error = EINTR;
- else if (r == USBD_TIMEOUT)
+ else if (err == USBD_TIMEOUT)
error = ETIMEDOUT;
else
error = EIO;
@@ -498,7 +493,7 @@ ugen_do_read(sc, endpt, uio, flag)
if (error || tn < n)
break;
}
- usbd_free_request(reqh);
+ usbd_free_request(xfer);
break;
default:
return (ENXIO);
@@ -512,10 +507,12 @@ ugenread(dev, uio, flag)
struct uio *uio;
int flag;
{
- USB_GET_SC(ugen, UGENUNIT(dev), sc);
int endpt = UGENENDPOINT(dev);
+ struct ugen_softc *sc;
int error;
+ USB_GET_SC(ugen, UGENUNIT(dev), sc);
+
sc->sc_refcnt++;
error = ugen_do_read(sc, endpt, uio, flag);
if (--sc->sc_refcnt < 0)
@@ -523,7 +520,7 @@ ugenread(dev, uio, flag)
return (error);
}
-int
+static int
ugen_do_write(sc, endpt, uio, flag)
struct ugen_softc *sc;
int endpt;
@@ -534,45 +531,49 @@ ugen_do_write(sc, endpt, uio, flag)
u_int32_t n;
int error = 0;
char buf[UGEN_BBSIZE];
- usbd_request_handle reqh;
- usbd_status r;
+ usbd_xfer_handle xfer;
+ usbd_status err;
+
+ DPRINTFN(5, ("%s: ugenwrite: %d\n", USBDEVNAME(sc->sc_dev), endpt));
if (sc->sc_dying)
return (EIO);
+ if (endpt == USB_CONTROL_ENDPOINT)
+ return (ENODEV);
+
#ifdef DIAGNOSTIC
- if (!sce->edesc) {
+ if (sce->edesc == NULL) {
printf("ugenwrite: no edesc\n");
return (EIO);
}
- if (!sce->pipeh) {
+ if (sce->pipeh == NULL) {
printf("ugenwrite: no pipe\n");
return (EIO);
}
#endif
- DPRINTF(("ugenwrite\n"));
switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
case UE_BULK:
- reqh = usbd_alloc_request(sc->sc_udev);
- if (reqh == 0)
+ xfer = usbd_alloc_request(sc->sc_udev);
+ if (xfer == 0)
return (EIO);
while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) {
error = uiomove(buf, n, uio);
if (error)
break;
DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n));
- r = usbd_bulk_transfer(reqh, sce->pipeh, 0,
- sce->timeout, buf, &n,"ugenwb");
- if (r != USBD_NORMAL_COMPLETION) {
- if (r == USBD_INTERRUPTED)
+ err = usbd_bulk_transfer(xfer, sce->pipeh, 0,
+ sce->timeout, buf, &n,"ugenwb");
+ if (err) {
+ if (err == USBD_INTERRUPTED)
error = EINTR;
else
error = EIO;
break;
}
}
- usbd_free_request(reqh);
+ usbd_free_request(xfer);
break;
default:
return (ENXIO);
@@ -586,10 +587,12 @@ ugenwrite(dev, uio, flag)
struct uio *uio;
int flag;
{
- USB_GET_SC(ugen, UGENUNIT(dev), sc);
int endpt = UGENENDPOINT(dev);
+ struct ugen_softc *sc;
int error;
+ USB_GET_SC(ugen, UGENUNIT(dev), sc);
+
sc->sc_refcnt++;
error = ugen_do_write(sc, endpt, uio, flag);
if (--sc->sc_refcnt < 0)
@@ -597,7 +600,6 @@ ugenwrite(dev, uio, flag)
return (error);
}
-
#if defined(__NetBSD__) || defined(__OpenBSD__)
int
ugen_activate(self, act)
@@ -669,9 +671,9 @@ USB_DETACH(ugen)
return (0);
}
-void
-ugenintr(reqh, addr, status)
- usbd_request_handle reqh;
+static void
+ugenintr(xfer, addr, status)
+ usbd_xfer_handle xfer;
usbd_private_handle addr;
usbd_status status;
{
@@ -689,11 +691,11 @@ ugenintr(reqh, addr, status)
return;
}
- usbd_get_request_status(reqh, 0, 0, &count, 0);
+ usbd_get_request_status(xfer, 0, 0, &count, 0);
ibuf = sce->ibuf;
- DPRINTFN(5, ("ugenintr: reqh=%p status=%d count=%d\n",
- reqh, status, count));
+ DPRINTFN(5, ("ugenintr: xfer=%p status=%d count=%d\n",
+ xfer, status, count));
DPRINTFN(5, (" data = %02x %02x %02x\n",
ibuf[0], ibuf[1], ibuf[2]));
@@ -707,32 +709,32 @@ ugenintr(reqh, addr, status)
selwakeup(&sce->rsel);
}
-usbd_status
+static usbd_status
ugen_set_interface(sc, ifaceidx, altno)
struct ugen_softc *sc;
int ifaceidx, altno;
{
usbd_interface_handle iface;
usb_endpoint_descriptor_t *ed;
- usbd_status r;
+ usbd_status err;
struct ugen_endpoint *sce;
u_int8_t niface, nendpt, endptno, endpt;
int dir;
DPRINTFN(15, ("ugen_set_interface %d %d\n", ifaceidx, altno));
- r = usbd_interface_count(sc->sc_udev, &niface);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
+ err = usbd_interface_count(sc->sc_udev, &niface);
+ if (err)
+ return (err);
if (ifaceidx < 0 || ifaceidx >= niface)
return (USBD_INVAL);
- r = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
- r = usbd_endpoint_count(iface, &nendpt);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
+ err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface);
+ if (err)
+ return (err);
+ err = usbd_endpoint_count(iface, &nendpt);
+ if (err)
+ return (err);
for (endptno = 0; endptno < nendpt; endptno++) {
ed = usbd_interface2endpoint_descriptor(iface,endptno);
endpt = ed->bEndpointAddress;
@@ -744,13 +746,13 @@ ugen_set_interface(sc, ifaceidx, altno)
}
/* change setting */
- r = usbd_set_interface(iface, altno);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
+ err = usbd_set_interface(iface, altno);
+ if (err)
+ return (err);
- r = usbd_endpoint_count(iface, &nendpt);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
+ err = usbd_endpoint_count(iface, &nendpt);
+ if (err)
+ return (err);
for (endptno = 0; endptno < nendpt; endptno++) {
ed = usbd_interface2endpoint_descriptor(iface,endptno);
endpt = ed->bEndpointAddress;
@@ -764,7 +766,7 @@ ugen_set_interface(sc, ifaceidx, altno)
}
/* Retrieve a complete descriptor for a certain device and index. */
-usb_config_descriptor_t *
+static usb_config_descriptor_t *
ugen_get_cdesc(sc, index, lenp)
struct ugen_softc *sc;
int index;
@@ -772,7 +774,7 @@ ugen_get_cdesc(sc, index, lenp)
{
usb_config_descriptor_t *cdesc, *tdesc, cdescr;
int len;
- usbd_status r;
+ usbd_status err;
if (index == USB_CURRENT_CONFIG_INDEX) {
tdesc = usbd_get_config_descriptor(sc->sc_udev);
@@ -783,16 +785,16 @@ ugen_get_cdesc(sc, index, lenp)
memcpy(cdesc, tdesc, len);
DPRINTFN(5,("ugen_get_cdesc: current, len=%d\n", len));
} else {
- r = usbd_get_config_desc(sc->sc_udev, index, &cdescr);
- if (r != USBD_NORMAL_COMPLETION)
+ err = usbd_get_config_desc(sc->sc_udev, index, &cdescr);
+ if (err)
return (0);
len = UGETW(cdescr.wTotalLength);
DPRINTFN(5,("ugen_get_cdesc: index=%d, len=%d\n", index, len));
if (lenp)
*lenp = len;
cdesc = malloc(len, M_TEMP, M_WAITOK);
- r = usbd_get_config_desc_full(sc->sc_udev, index, cdesc, len);
- if (r != USBD_NORMAL_COMPLETION) {
+ err = usbd_get_config_desc_full(sc->sc_udev, index, cdesc, len);
+ if (err) {
free(cdesc, M_TEMP);
return (0);
}
@@ -800,21 +802,21 @@ ugen_get_cdesc(sc, index, lenp)
return (cdesc);
}
-int
+static int
ugen_get_alt_index(sc, ifaceidx)
struct ugen_softc *sc;
int ifaceidx;
{
usbd_interface_handle iface;
- usbd_status r;
+ usbd_status err;
- r = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface);
- if (r != USBD_NORMAL_COMPLETION)
+ err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface);
+ if (err)
return (-1);
return (usbd_get_interface_altindex(iface));
}
-int
+static int
ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
struct ugen_softc *sc;
int endpt;
@@ -824,7 +826,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
struct proc *p;
{
struct ugen_endpoint *sce;
- usbd_status r;
+ usbd_status err;
usbd_interface_handle iface;
struct usb_config_desc *cd;
usb_config_descriptor_t *cdesc;
@@ -849,8 +851,10 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
if (endpt == USB_CONTROL_ENDPOINT)
return (EINVAL);
sce = &sc->sc_endpoints[endpt][IN];
+ if (sce == NULL)
+ return (EINVAL);
#ifdef DIAGNOSTIC
- if (!sce->pipeh) {
+ if (sce->pipeh == NULL) {
printf("ugenioctl: USB_SET_SHORT_XFER, no pipe\n");
return (EIO);
}
@@ -862,8 +866,10 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
return (0);
case USB_SET_TIMEOUT:
sce = &sc->sc_endpoints[endpt][IN];
+ if (sce == NULL)
+ return (EINVAL);
#ifdef DIAGNOSTIC
- if (!sce->pipeh) {
+ if (sce->pipeh == NULL) {
printf("ugenioctl: USB_SET_TIMEOUT, no pipe\n");
return (EIO);
}
@@ -884,26 +890,26 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
break;
#endif
case USB_GET_CONFIG:
- r = usbd_get_config(sc->sc_udev, &conf);
- if (r != USBD_NORMAL_COMPLETION)
+ err = usbd_get_config(sc->sc_udev, &conf);
+ if (err)
return (EIO);
*(int *)addr = conf;
break;
case USB_SET_CONFIG:
if (!(flag & FWRITE))
return (EPERM);
- r = ugen_set_config(sc, *(int *)addr);
- if (r != USBD_NORMAL_COMPLETION)
+ err = ugen_set_config(sc, *(int *)addr);
+ if (err)
return (EIO);
break;
case USB_GET_ALTINTERFACE:
ai = (struct usb_alt_interface *)addr;
- r = usbd_device2interface_handle(sc->sc_udev,
- ai->interface_index, &iface);
- if (r != USBD_NORMAL_COMPLETION)
+ err = usbd_device2interface_handle(sc->sc_udev,
+ ai->interface_index, &iface);
+ if (err)
return (EINVAL);
idesc = usbd_get_interface_descriptor(iface);
- if (!idesc)
+ if (idesc == NULL)
return (EIO);
ai->alt_no = idesc->bAlternateSetting;
break;
@@ -911,21 +917,21 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
if (!(flag & FWRITE))
return (EPERM);
ai = (struct usb_alt_interface *)addr;
- r = usbd_device2interface_handle(sc->sc_udev,
- ai->interface_index, &iface);
- if (r != USBD_NORMAL_COMPLETION)
+ err = usbd_device2interface_handle(sc->sc_udev,
+ ai->interface_index, &iface);
+ if (err)
return (EINVAL);
- r = ugen_set_interface(sc, ai->interface_index, ai->alt_no);
- if (r != USBD_NORMAL_COMPLETION)
+ err = ugen_set_interface(sc, ai->interface_index, ai->alt_no);
+ if (err)
return (EINVAL);
break;
case USB_GET_NO_ALT:
ai = (struct usb_alt_interface *)addr;
cdesc = ugen_get_cdesc(sc, ai->config_index, 0);
- if (!cdesc)
+ if (cdesc == NULL)
return (EINVAL);
idesc = usbd_find_idesc(cdesc, ai->interface_index, 0);
- if (!idesc) {
+ if (idesc == NULL) {
free(cdesc, M_TEMP);
return (EINVAL);
}
@@ -939,7 +945,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
case USB_GET_CONFIG_DESC:
cd = (struct usb_config_desc *)addr;
cdesc = ugen_get_cdesc(sc, cd->config_index, 0);
- if (!cdesc)
+ if (cdesc == NULL)
return (EINVAL);
cd->desc = *cdesc;
free(cdesc, M_TEMP);
@@ -947,7 +953,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
case USB_GET_INTERFACE_DESC:
id = (struct usb_interface_desc *)addr;
cdesc = ugen_get_cdesc(sc, id->config_index, 0);
- if (!cdesc)
+ if (cdesc == NULL)
return (EINVAL);
if (id->config_index == USB_CURRENT_CONFIG_INDEX &&
id->alt_index == USB_CURRENT_ALT_INDEX)
@@ -955,7 +961,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
else
alt = id->alt_index;
idesc = usbd_find_idesc(cdesc, id->interface_index, alt);
- if (!idesc) {
+ if (idesc == NULL) {
free(cdesc, M_TEMP);
return (EINVAL);
}
@@ -965,7 +971,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
case USB_GET_ENDPOINT_DESC:
ed = (struct usb_endpoint_desc *)addr;
cdesc = ugen_get_cdesc(sc, ed->config_index, 0);
- if (!cdesc)
+ if (cdesc == NULL)
return (EINVAL);
if (ed->config_index == USB_CURRENT_CONFIG_INDEX &&
ed->alt_index == USB_CURRENT_ALT_INDEX)
@@ -974,7 +980,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
alt = ed->alt_index;
edesc = usbd_find_edesc(cdesc, ed->interface_index,
alt, ed->endpoint_index);
- if (!edesc) {
+ if (edesc == NULL) {
free(cdesc, M_TEMP);
return (EINVAL);
}
@@ -1011,9 +1017,9 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
}
case USB_GET_STRING_DESC:
si = (struct usb_string_desc *)addr;
- r = usbd_get_string_desc(sc->sc_udev, si->string_index,
- si->language_id, &si->desc);
- if (r != USBD_NORMAL_COMPLETION)
+ err = usbd_get_string_desc(sc->sc_udev, si->string_index,
+ si->language_id, &si->desc);
+ if (err)
return (EINVAL);
break;
case USB_DO_REQUEST:
@@ -1023,7 +1029,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
struct iovec iov;
struct uio uio;
void *ptr = 0;
- usbd_status r;
+ usbd_status err;
int error = 0;
if (!(flag & FWRITE))
@@ -1058,9 +1064,9 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
goto ret;
}
}
- r = usbd_do_request_flags(sc->sc_udev, &ur->request,
- ptr, ur->flags, &ur->actlen);
- if (r != USBD_NORMAL_COMPLETION) {
+ err = usbd_do_request_flags(sc->sc_udev, &ur->request,
+ ptr, ur->flags, &ur->actlen);
+ if (err) {
error = EIO;
goto ret;
}
@@ -1078,7 +1084,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
}
case USB_GET_DEVICEINFO:
usbd_fill_deviceinfo(sc->sc_udev,
- (struct usb_device_info *)addr);
+ (struct usb_device_info *)addr);
break;
default:
return (EINVAL);
@@ -1094,10 +1100,12 @@ ugenioctl(dev, cmd, addr, flag, p)
int flag;
struct proc *p;
{
- USB_GET_SC(ugen, UGENUNIT(dev), sc);
int endpt = UGENENDPOINT(dev);
+ struct ugen_softc *sc;
int error;
+ USB_GET_SC(ugen, UGENUNIT(dev), sc);
+
sc->sc_refcnt++;
error = ugen_do_ioctl(sc, endpt, cmd, addr, flag, p);
if (--sc->sc_refcnt < 0)
@@ -1111,16 +1119,20 @@ ugenpoll(dev, events, p)
int events;
struct proc *p;
{
- USB_GET_SC(ugen, UGENUNIT(dev), sc);
+ struct ugen_softc *sc;
struct ugen_endpoint *sce;
int revents = 0;
int s;
+ USB_GET_SC(ugen, UGENUNIT(dev), sc);
+
if (sc->sc_dying)
return (EIO);
/* XXX always IN */
sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN];
+ if (sce == NULL)
+ return (EINVAL);
#ifdef DIAGNOSTIC
if (!sce->edesc) {
printf("ugenwrite: no edesc\n");
OpenPOWER on IntegriCloud