summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb/usbdi_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/usb/usbdi_util.c')
-rw-r--r--sys/dev/usb/usbdi_util.c111
1 files changed, 99 insertions, 12 deletions
diff --git a/sys/dev/usb/usbdi_util.c b/sys/dev/usb/usbdi_util.c
index 2d8160e..f94a35e0 100644
--- a/sys/dev/usb/usbdi_util.c
+++ b/sys/dev/usb/usbdi_util.c
@@ -1,12 +1,13 @@
-/* $NetBSD: usbdi_util.c,v 1.4 1998/08/02 22:30:53 augustss Exp $ */
+/* $NetBSD: usbdi_util.c,v 1.11 1999/01/03 01:00:56 augustss Exp $ */
/* FreeBSD $Id$ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
* All rights reserved.
*
- * Author: Lennart Augustsson <augustss@carlstedt.se>
- * Carlstedt Research & Technology
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Lennart Augustsson (augustss@carlstedt.se) at
+ * Carlstedt Research & Technology.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -37,16 +38,14 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <dev/usb/usb_port.h>
-
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
-#if defined(__NetBSD__)
-#include <sys/device.h>
-#endif
#include <sys/proc.h>
+#if defined(__FreeBSD__)
+#include <sys/bus.h>
+#endif
#include <sys/select.h>
#include <dev/usb/usb.h>
@@ -87,9 +86,19 @@ usbd_get_config_desc(dev, conf, d)
int conf;
usb_config_descriptor_t *d;
{
+ usbd_status r;
+
DPRINTFN(3,("usbd_get_config_desc: conf=%d\n", conf));
- return (usbd_get_desc(dev, UDESC_CONFIG,
- conf, USB_CONFIG_DESCRIPTOR_SIZE, d));
+ r = usbd_get_desc(dev, UDESC_CONFIG, conf,
+ USB_CONFIG_DESCRIPTOR_SIZE, d);
+ if (r != USBD_NORMAL_COMPLETION)
+ return (r);
+ if (d->bDescriptorType != UDESC_CONFIG) {
+ DPRINTFN(-1,("usbd_get_config_desc: conf %d, bad desc %d\n",
+ conf, d->bDescriptorType));
+ return (USBD_INVAL);
+ }
+ return (USBD_NORMAL_COMPLETION);
}
usbd_status
@@ -217,6 +226,8 @@ usbd_set_protocol(iface, report)
DPRINTFN(4, ("usbd_set_protocol: iface=%p, report=%d, endpt=%d\n",
iface, report, id->bInterfaceNumber));
+ if (!id)
+ return (USBD_IOERROR);
r = usbd_interface2device_handle(iface, &dev);
if (r != USBD_NORMAL_COMPLETION)
return (r);
@@ -244,6 +255,8 @@ usbd_set_report(iface, type, id, data, len)
usbd_status r;
DPRINTFN(4, ("usbd_set_report: len=%d\n", len));
+ if (!ifd)
+ return (USBD_IOERROR);
r = usbd_interface2device_handle(iface, &dev);
if (r != USBD_NORMAL_COMPLETION)
return (r);
@@ -271,6 +284,8 @@ usbd_set_report_async(iface, type, id, data, len)
usbd_status r;
DPRINTFN(4, ("usbd_set_report_async: len=%d\n", len));
+ if (!ifd)
+ return (USBD_IOERROR);
r = usbd_interface2device_handle(iface, &dev);
if (r != USBD_NORMAL_COMPLETION)
return (r);
@@ -298,6 +313,8 @@ usbd_get_report(iface, type, id, data, len)
usbd_status r;
DPRINTFN(4, ("usbd_set_report: len=%d\n", len));
+ if (!id)
+ return (USBD_IOERROR);
r = usbd_interface2device_handle(iface, &dev);
if (r != USBD_NORMAL_COMPLETION)
return (r);
@@ -323,6 +340,8 @@ usbd_set_idle(iface, duration, id)
usbd_status r;
DPRINTFN(4, ("usbd_set_idle: %d %d\n", duration, id));
+ if (!ifd)
+ return (USBD_IOERROR);
r = usbd_interface2device_handle(iface, &dev);
if (r != USBD_NORMAL_COMPLETION)
return (r);
@@ -365,6 +384,8 @@ usbd_get_hid_descriptor(ifc)
char *p, *end;
usbd_status r;
+ if (!idesc)
+ return (0);
r = usbd_interface2device_handle(ifc, &dev);
if (r != USBD_NORMAL_COMPLETION)
return (0);
@@ -414,11 +435,77 @@ usbd_alloc_report_desc(ifc, descp, sizep, mem)
if (!*descp)
return (USBD_NOMEM);
/* XXX should not use 0 Report ID */
- r = usbd_get_report_descriptor(dev, id->bInterfaceNumber, 0,
- *sizep, *descp);
+ r = usbd_get_report_descriptor(dev, id->bInterfaceNumber, 0,
+ *sizep, *descp);
if (r != USBD_NORMAL_COMPLETION) {
free(*descp, mem);
return (r);
}
return (USBD_NORMAL_COMPLETION);
}
+
+usbd_status
+usbd_get_config(dev, conf)
+ usbd_device_handle dev;
+ u_int8_t *conf;
+{
+ usb_device_request_t req;
+
+ req.bmRequestType = UT_READ_DEVICE;
+ req.bRequest = UR_GET_CONFIG;
+ USETW(req.wValue, 0);
+ USETW(req.wIndex, 0);
+ USETW(req.wLength, 1);
+ return (usbd_do_request(dev, &req, conf));
+}
+
+static void usbd_bulk_transfer_cb __P((usbd_request_handle reqh,
+ usbd_private_handle priv, usbd_status status));
+static void
+usbd_bulk_transfer_cb(reqh, priv, status)
+ usbd_request_handle reqh;
+ usbd_private_handle priv;
+ usbd_status status;
+{
+ wakeup(reqh);
+}
+
+usbd_status
+usbd_bulk_transfer(reqh, pipe, flags, buf, size, lbl)
+ usbd_request_handle reqh;
+ usbd_pipe_handle pipe;
+ u_int16_t flags;
+ void *buf;
+ u_int32_t *size;
+ char *lbl;
+{
+ usbd_private_handle priv;
+ void *buffer;
+ usbd_status r;
+ int s, error;
+
+ r = usbd_setup_request(reqh, pipe, 0, buf, *size,
+ flags, USBD_NO_TIMEOUT, usbd_bulk_transfer_cb);
+ if (r != USBD_NORMAL_COMPLETION)
+ return (r);
+ DPRINTFN(1, ("usbd_bulk_transfer: transfer %d bytes\n", *size));
+ s = splusb(); /* don't want callback until tsleep() */
+ r = usbd_transfer(reqh);
+ if (r != USBD_IN_PROGRESS) {
+ splx(s);
+ return (r);
+ }
+ error = tsleep((caddr_t)reqh, PZERO | PCATCH, lbl, 0);
+ splx(s);
+ if (error) {
+ usbd_abort_pipe(pipe);
+ return (USBD_INTERRUPTED);
+ }
+ usbd_get_request_status(reqh, &priv, &buffer, size, &r);
+ if (r != USBD_NORMAL_COMPLETION) {
+ DPRINTF(("ugenread: error=%d\n", r));
+ usbd_clear_endpoint_stall(pipe);
+ }
+ return (r);
+}
+
OpenPOWER on IntegriCloud