summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authorn_hibma <n_hibma@FreeBSD.org>2008-11-13 21:34:34 +0000
committern_hibma <n_hibma@FreeBSD.org>2008-11-13 21:34:34 +0000
commit5e5f99e12aa2af18f2a02c849339c37c965f53a5 (patch)
tree66955ea4201561ea436ef1799772498b3608a06d /sys/dev
parent1c998c296e7f4c398c2fc177d3648a7c1f6d46c1 (diff)
downloadFreeBSD-src-5e5f99e12aa2af18f2a02c849339c37c965f53a5.zip
FreeBSD-src-5e5f99e12aa2af18f2a02c849339c37c965f53a5.tar.gz
Add a reset device command to ugen.c.
This is needed to make some devices work that require a firmware upload and a USB reset afterwards.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/usb/ugen.c10
-rw-r--r--sys/dev/usb/usb.h1
-rw-r--r--sys/dev/usb/usb_subr.c8
-rw-r--r--sys/dev/usb/usbdi.c9
-rw-r--r--sys/dev/usb/usbdi.h1
5 files changed, 19 insertions, 10 deletions
diff --git a/sys/dev/usb/ugen.c b/sys/dev/usb/ugen.c
index 77ea2ef..4f03cfb 100644
--- a/sys/dev/usb/ugen.c
+++ b/sys/dev/usb/ugen.c
@@ -1059,8 +1059,8 @@ ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr,
sce->cur += count;
if(sce->cur >= sce->limit)
sce->cur = sce->ibuf + (sce->limit - sce->cur);
- DPRINTFN(5, ("ugen_isoc_rintr: throwing away %d bytes\n",
- count));
+ DPRINTF(("ugen_isoc_rintr: throwing away %d bytes\n",
+ count));
}
isize = UGETW(sce->edesc->wMaxPacketSize);
@@ -1427,7 +1427,6 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd,
struct iovec iov;
struct uio uio;
void *ptr = 0;
- usbd_status err;
int error = 0;
if (!(flag & FWRITE))
@@ -1485,6 +1484,11 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd,
usbd_fill_deviceinfo(sc->sc_udev,
(struct usb_device_info *)addr, 1);
break;
+ case USB_RESET_DEVICE:
+ err = usbd_reset_device(sc->sc_udev);
+ if (err)
+ return EIO;
+ break;
default:
return (EINVAL);
}
diff --git a/sys/dev/usb/usb.h b/sys/dev/usb/usb.h
index f4bc88c..7e64cac 100644
--- a/sys/dev/usb/usb.h
+++ b/sys/dev/usb/usb.h
@@ -699,6 +699,7 @@ struct usb_event {
#define USB_GET_DEVICEINFO _IOR ('U', 112, struct usb_device_info)
#define USB_SET_SHORT_XFER _IOW ('U', 113, int)
#define USB_SET_TIMEOUT _IOW ('U', 114, int)
+#define USB_RESET_DEVICE _IO ('U', 115)
/* Modem device */
#define USB_GET_CM_OVER_DATA _IOR ('U', 130, int)
diff --git a/sys/dev/usb/usb_subr.c b/sys/dev/usb/usb_subr.c
index 4d0b73b..324b435 100644
--- a/sys/dev/usb/usb_subr.c
+++ b/sys/dev/usb/usb_subr.c
@@ -322,16 +322,10 @@ usbd_delay_ms(usbd_device_handle dev, u_int ms)
usbd_status
usbd_reset_port(usbd_device_handle dev, int port, usb_port_status_t *ps)
{
- usb_device_request_t req;
usbd_status err;
int n;
- req.bmRequestType = UT_WRITE_CLASS_OTHER;
- req.bRequest = UR_SET_FEATURE;
- USETW(req.wValue, UHF_PORT_RESET);
- USETW(req.wIndex, port);
- USETW(req.wLength, 0);
- err = usbd_do_request(dev, &req, 0);
+ err = usbd_set_port_feature(dev, port, UHF_PORT_RESET);
DPRINTFN(1,("usbd_reset_port: port %d reset done, error=%s\n",
port, usbd_errstr(err)));
if (err)
diff --git a/sys/dev/usb/usbdi.c b/sys/dev/usb/usbdi.c
index 59bcf4b..8f0ce0f 100644
--- a/sys/dev/usb/usbdi.c
+++ b/sys/dev/usb/usbdi.c
@@ -1235,6 +1235,15 @@ usbd_set_polling(usbd_device_handle dev, int on)
dev->bus->methods->soft_intr(dev->bus);
}
+usbd_status
+usbd_reset_device(usbd_device_handle dev)
+{
+ usbd_device_handle parent = dev->myhub;
+ struct usbd_port *up = dev->powersrc;
+
+ return usbd_reset_port(parent, up->portno, &up->status);
+}
+
usb_endpoint_descriptor_t *
usbd_get_endpoint_descriptor(usbd_interface_handle iface, u_int8_t address)
diff --git a/sys/dev/usb/usbdi.h b/sys/dev/usb/usbdi.h
index cee2de0..d5bb035 100644
--- a/sys/dev/usb/usbdi.h
+++ b/sys/dev/usb/usbdi.h
@@ -160,6 +160,7 @@ usb_endpoint_descriptor_t *usbd_find_edesc(usb_config_descriptor_t *,
void usbd_dopoll(usbd_interface_handle);
void usbd_set_polling(usbd_device_handle, int);
+usbd_status usbd_reset_device(usbd_device_handle);
const char *usbd_errstr(usbd_status);
OpenPOWER on IntegriCloud