summaryrefslogtreecommitdiff
path: root/sys/dev/usb/usb_subr.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/usb/usb_subr.c')
-rw-r--r--sys/dev/usb/usb_subr.c80
1 files changed, 59 insertions, 21 deletions
diff --git a/sys/dev/usb/usb_subr.c b/sys/dev/usb/usb_subr.c
index 4883a38aa17..66cb1fd6248 100644
--- a/sys/dev/usb/usb_subr.c
+++ b/sys/dev/usb/usb_subr.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: usb_subr.c,v 1.19 2002/05/02 20:08:04 nate Exp $ */
-/* $NetBSD: usb_subr.c,v 1.87 2001/08/15 00:04:59 augustss Exp $ */
+/* $OpenBSD: usb_subr.c,v 1.20 2002/05/07 18:08:04 nate Exp $ */
+/* $NetBSD: usb_subr.c,v 1.98 2002/02/20 20:30:13 christos Exp $ */
/* $FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma Exp $ */
/*
@@ -352,6 +352,9 @@ usbd_reset_port(usbd_device_handle dev, int port, usb_port_status_t *ps)
err));
return (err);
}
+ /* If the device disappeared, just give up. */
+ if (!(UGETW(ps->wPortStatus) & UPS_CURRENT_CONNECT_STATUS))
+ return (USBD_NORMAL_COMPLETION);
} while ((UGETW(ps->wPortChange) & UPS_C_PORT_RESET) == 0 && --n > 0);
if (n == 0)
return (USBD_TIMEOUT);
@@ -475,13 +478,36 @@ usbd_fill_iface_data(usbd_device_handle dev, int ifaceidx, int altidx)
break;
}
/* passed end, or bad desc */
- DPRINTF(("usbd_fill_iface_data: bad descriptor(s): %s\n",
- ed->bLength == 0 ? "0 length" :
- ed->bDescriptorType == UDESC_INTERFACE ? "iface desc":
- "out of data"));
+ printf("usbd_fill_iface_data: bad descriptor(s): %s\n",
+ ed->bLength == 0 ? "0 length" :
+ ed->bDescriptorType == UDESC_INTERFACE ? "iface desc":
+ "out of data");
goto bad;
found:
ifc->endpoints[endpt].edesc = ed;
+ if (dev->speed == USB_SPEED_HIGH) {
+ u_int mps;
+ /* Control and bulk endpoints have max packet
+ limits. */
+ switch (UE_GET_XFERTYPE(ed->bmAttributes)) {
+ case UE_CONTROL:
+ mps = USB_2_MAX_CTRL_PACKET;
+ goto check;
+ case UE_BULK:
+ mps = USB_2_MAX_BULK_PACKET;
+ check:
+ if (UGETW(ed->wMaxPacketSize) != mps) {
+ USETW(ed->wMaxPacketSize, mps);
+#ifdef DIAGNOSTIC
+ printf("usbd_fill_iface_data: bad max "
+ "packet size\n");
+#endif
+ }
+ break;
+ default:
+ break;
+ }
+ }
ifc->endpoints[endpt].refcnt = 0;
p += ed->bLength;
}
@@ -725,7 +751,6 @@ usbd_setup_pipe(usbd_device_handle dev, usbd_interface_handle iface,
p->repeat = 0;
p->interval = ival;
SIMPLEQ_INIT(&p->queue);
- usb_callout_init(p->abort_handle);
err = dev->bus->methods->open_pipe(p);
if (err) {
DPRINTFN(-1,("usbd_setup_pipe: endpoint=0x%x failed, error="
@@ -745,6 +770,7 @@ usbd_setup_pipe(usbd_device_handle dev, usbd_interface_handle iface,
void
usbd_kill_pipe(usbd_pipe_handle pipe)
{
+ usbd_abort_pipe(pipe);
pipe->methods->close(pipe);
pipe->endpoint->refcnt--;
free(pipe, M_USB);
@@ -927,16 +953,17 @@ usbd_probe_and_attach(device_ptr_t parent, usbd_device_handle dev,
*/
usbd_status
usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth,
- int lowspeed, int port, struct usbd_port *up)
+ int speed, int port, struct usbd_port *up)
{
usbd_device_handle dev;
+ struct usbd_device *hub;
usb_device_descriptor_t *dd;
usbd_status err;
int addr;
int i;
- DPRINTF(("usbd_new_device bus=%p port=%d depth=%d lowspeed=%d\n",
- bus, port, depth, lowspeed));
+ DPRINTF(("usbd_new_device bus=%p port=%d depth=%d speed=%d\n",
+ bus, port, depth, speed));
addr = usbd_getnewaddr(bus);
if (addr < 0) {
printf("%s: No free USB addresses, new device ignored.\n",
@@ -947,7 +974,7 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth,
dev = malloc(sizeof *dev, M_USB, M_NOWAIT);
if (dev == NULL)
return (USBD_NOMEM);
- memset(dev, 0, sizeof(*dev));
+ memset(dev, 0, sizeof *dev);
dev->bus = bus;
@@ -965,9 +992,15 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth,
dev->quirks = &usbd_no_quirk;
dev->address = USB_START_ADDR;
dev->ddesc.bMaxPacketSize = 0;
- dev->lowspeed = lowspeed != 0;
dev->depth = depth;
dev->powersrc = up;
+ dev->myhub = up->parent;
+ for (hub = up->parent;
+ hub != NULL && hub->speed != USB_SPEED_HIGH;
+ hub = hub->myhub)
+ ;
+ dev->myhighhub = hub;
+ dev->speed = speed;
dev->langid = USBD_NOLANG;
dev->cookie.cookie = ++usb_cookie_no;
@@ -996,11 +1029,22 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth,
return (err);
}
+ if (speed == USB_SPEED_HIGH) {
+ /* Max packet size must be 64 (sec 5.5.3). */
+ if (dd->bMaxPacketSize != USB_2_MAX_CTRL_PACKET) {
+#ifdef DIAGNOSTIC
+ printf("usbd_new_device: addr=%d bad max packet size\n",
+ addr);
+#endif
+ dd->bMaxPacketSize = USB_2_MAX_CTRL_PACKET;
+ }
+ }
+
DPRINTF(("usbd_new_device: adding unit addr=%d, rev=%02x, class=%d, "
- "subclass=%d, protocol=%d, maxpacket=%d, len=%d, ls=%d\n",
+ "subclass=%d, protocol=%d, maxpacket=%d, len=%d, speed=%d\n",
addr,UGETW(dd->bcdUSB), dd->bDeviceClass, dd->bDeviceSubClass,
dd->bDeviceProtocol, dd->bMaxPacketSize, dd->bLength,
- dev->lowspeed));
+ dev->speed));
if (dd->bDescriptorType != UDESC_DEVICE) {
/* Illegal device descriptor */
@@ -1203,7 +1247,7 @@ usbd_fill_deviceinfo(usbd_device_handle dev, struct usb_device_info *di,
di->udi_protocol = dev->ddesc.bDeviceProtocol;
di->udi_config = dev->config;
di->udi_power = dev->self_powered ? 0 : dev->power;
- di->udi_lowspeed = dev->lowspeed;
+ di->udi_speed = dev->speed;
if (dev->subdevs != NULL) {
for (i = 0; dev->subdevs[i] &&
@@ -1306,13 +1350,7 @@ usb_disconnect_port(struct usbd_port *up, device_ptr_t parent)
if (up->portno != 0)
printf(" port %d", up->portno);
printf(" (addr %d) disconnected\n", dev->address);
-#if defined(__NetBSD__) || defined(__OpenBSD__)
config_detach(dev->subdevs[i], DETACH_FORCE);
-#elif defined(__FreeBSD__)
- device_delete_child(device_get_parent(dev->subdevs[i]),
- dev->subdevs[i]);
-#endif
-
}
}