Lines Matching +full:needs +full:- +full:reset +full:- +full:on +full:- +full:resume

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2008-2023 Hans Petter Selasky
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
119 int usb_template = -1;
127 /*------------------------------------------------------------------------*
131 * operating in device mode either on (when on_not_off is 1), or off
133 *------------------------------------------------------------------------*/
147 max--;
149 if (bus == NULL || bus->devices == NULL ||
150 bus->devices[USB_ROOT_HUB_ADDR] == NULL) {
155 udev = bus->devices[USB_ROOT_HUB_ADDR];
157 if (udev->refcount == USB_DEV_REF_MAX) {
162 udev->refcount++;
201 if (--(udev->refcount) == 0)
202 cv_broadcast(&udev->ref_cv);
207 /*------------------------------------------------------------------------*
212 *------------------------------------------------------------------------*/
228 * Set the pull up resistors back on.
240 if (error != 0 || req->newptr == NULL || usb_template == val)
282 return (udev->manufacturer ? udev->manufacturer : "Unknown");
288 return (udev->product ? udev->product : "");
294 return (udev->serial ? udev->serial : "");
297 /*------------------------------------------------------------------------*
306 *------------------------------------------------------------------------*/
310 struct usb_endpoint *ep = udev->endpoints;
311 struct usb_endpoint *ep_end = udev->endpoints + udev->endpoints_max;
324 * based on the endpoint address:
327 if (ep->edesc == NULL) {
331 if ((ep->edesc->bEndpointAddress & EA_MASK) == ea_val) {
339 if ((udev->ctrl_ep.edesc != NULL) &&
340 ((udev->ctrl_ep.edesc->bEndpointAddress & EA_MASK) == ea_val)) {
341 ep = &udev->ctrl_ep;
350 /*------------------------------------------------------------------------*
353 * This function searches for an USB endpoint based on the information
359 *------------------------------------------------------------------------*/
364 struct usb_endpoint *ep = udev->endpoints;
365 struct usb_endpoint *ep_end = udev->endpoints + udev->endpoints_max;
366 uint8_t index = setup->ep_index;
374 udev, iface_index, setup->endpoint,
375 setup->type, setup->direction, setup->ep_index);
379 if (setup->usb_mode != USB_MODE_DUAL &&
380 udev->flags.usb_mode != setup->usb_mode) {
381 /* wrong mode - no endpoint */
387 if (setup->direction == UE_DIR_RX) {
389 ea_val = (udev->flags.usb_mode == USB_MODE_DEVICE) ?
391 } else if (setup->direction == UE_DIR_TX) {
393 ea_val = (udev->flags.usb_mode == USB_MODE_DEVICE) ?
395 } else if (setup->direction == UE_DIR_ANY) {
402 ea_val = (setup->direction & (UE_DIR_IN | UE_DIR_OUT));
407 if (setup->endpoint == UE_ADDR_ANY) {
412 ea_val |= (setup->endpoint & UE_ADDR);
417 if (setup->type == UE_BULK_INTR) {
421 } else if (setup->type == UE_TYPE_ANY) {
428 type_val = (setup->type & UE_XFERTYPE);
433 * based on the endpoint address. Note that we are searching
434 * the endpoints from the beginning of the "udev->endpoints" array.
437 if ((ep->edesc == NULL) ||
438 (ep->iface_index != iface_index)) {
443 if (((ep->edesc->bEndpointAddress & ea_mask) == ea_val) &&
444 ((ep->edesc->bmAttributes & type_mask) == type_val)) {
445 if (!index--) {
456 if ((udev->ctrl_ep.edesc != NULL) &&
457 ((udev->ctrl_ep.edesc->bEndpointAddress & ea_mask) == ea_val) &&
458 ((udev->ctrl_ep.edesc->bmAttributes & type_mask) == type_val) &&
460 ep = &udev->ctrl_ep;
469 /*------------------------------------------------------------------------*
474 * the unsigned 8-bit integer pointed to by "count".
479 *------------------------------------------------------------------------*/
483 if (udev->cdesc == NULL) {
487 *count = udev->ifaces_max;
491 /*------------------------------------------------------------------------*
497 *------------------------------------------------------------------------*/
507 methods = udev->bus->methods;
509 (methods->endpoint_init) (udev, edesc, ep);
512 ep->edesc = edesc;
513 ep->ecomp = ecomp;
514 ep->iface_index = iface_index;
518 TAILQ_INIT(&ep->endpoint_q[x].head);
519 ep->endpoint_q[x].command = &usbd_pipe_start;
523 if (ep->methods == NULL)
526 /* check for SUPER-speed streams mode endpoint */
527 if (udev->speed == USB_SPEED_SUPER && ecomp != NULL &&
528 (edesc->bmAttributes & UE_XFERTYPE) == UE_BULK &&
529 (UE_GET_BULK_STREAMS(ecomp->bmAttributes) != 0)) {
536 if (methods->clear_stall != NULL) {
537 USB_BUS_LOCK(udev->bus);
538 (methods->clear_stall) (udev, ep);
539 USB_BUS_UNLOCK(udev->bus);
543 /*-----------------------------------------------------------------------*
552 *------------------------------------------------------------------------*/
562 ep_end = udev->endpoints + udev->endpoints_max;
566 ep = udev->endpoints;
572 if (ep->edesc != NULL)
579 /*------------------------------------------------------------------------*
584 *------------------------------------------------------------------------*/
589 DPRINTF("Refcount = %d\n", (int)udev->refcount);
592 udev->refcount--;
595 if (udev->refcount == 0) {
597 udev->refcount = USB_DEV_REF_MAX;
600 cv_wait(&udev->ref_cv, &usb_ref_lock);
606 /*------------------------------------------------------------------------*
613 *------------------------------------------------------------------------*/
619 /* Prevent re-enumeration */
637 if (udev->linux_endpoint_start != NULL) {
639 udev->linux_endpoint_start = NULL;
646 if (udev->cdesc != NULL) {
647 if (udev->flags.usb_mode != USB_MODE_DEVICE)
648 usbd_free_config_desc(udev, udev->cdesc);
649 udev->cdesc = NULL;
652 udev->curr_config_no = USB_UNCONFIG_NO;
653 udev->curr_config_index = USB_UNCONFIG_INDEX;
659 /*------------------------------------------------------------------------*
669 *------------------------------------------------------------------------*/
683 /* Prevent re-enumeration */
691 * device. "usb_unconfigure()" will also reset
695 if (udev->state == USB_STATE_CONFIGURED)
700 if (udev->flags.usb_mode == USB_MODE_DEVICE) {
714 udev->cdesc = cdp;
718 if ((!udev->flags.uq_bus_powered) &&
719 (cdp->bmAttributes & UC_SELF_POWERED) &&
720 (udev->flags.usb_mode == USB_MODE_HOST)) {
722 if (cdp->bmAttributes & UC_BUS_POWERED) {
740 udev->address, cdp->bConfigurationValue, cdp->bmAttributes,
741 selfpowered, cdp->bMaxPower * 2);
744 power = cdp->bMaxPower * 2;
746 if (udev->parent_hub) {
747 max_power = udev->parent_hub->hub->portpower;
758 if (udev->flags.usb_mode == USB_MODE_HOST) {
759 udev->flags.self_powered = selfpowered;
761 udev->power = power;
762 udev->curr_config_no = cdp->bConfigurationValue;
763 udev->curr_config_index = index;
767 err = usbd_req_set_config(udev, NULL, cdp->bConfigurationValue);
797 /*------------------------------------------------------------------------*
813 *------------------------------------------------------------------------*/
844 sx_assert(&udev->enum_sx, SA_LOCKED);
846 /* check for in-use endpoints */
849 ep = udev->endpoints;
850 ep_max = udev->endpoints_max;
851 while (ep_max--) {
854 iface_index == ep->iface_index) {
855 if (ep->refcount_alloc != 0)
862 ep = udev->endpoints;
863 ep_max = udev->endpoints_max;
864 while (ep_max--) {
867 iface_index == ep->iface_index) {
869 * Check if hardware needs a callback
877 if (ep->edesc != NULL &&
878 udev->bus->methods->endpoint_uninit != NULL)
879 udev->bus->methods->endpoint_uninit(udev, ep);
881 /* reset endpoint */
884 ep->iface_index = USB_IFACE_INDEX_ANY;
898 while ((id = usb_idesc_foreach(udev->cdesc, &ips))) {
899 iface = udev->ifaces + ips.iface_index;
917 iface->num_altsetting = ips.iface_index_alt + 1;
930 iface->idesc = id;
932 iface->alt_index = alt_index;
935 iface->parent_iface_index =
940 DPRINTFN(5, "found idesc nendpt=%d\n", id->bNumEndpoints);
947 while ((ed = usb_edesc_foreach(udev->cdesc, ed))) {
954 ep = udev->endpoints + temp;
959 ecomp = usb_ed_comp_foreach(udev->cdesc, (void *)ed);
978 udev->ifaces_max = ips.iface_index;
980 udev->ifaces = NULL;
981 if (udev->ifaces_max != 0) {
982 udev->ifaces = malloc(sizeof(*iface) * udev->ifaces_max,
984 if (udev->ifaces == NULL) {
992 udev->endpoints = malloc(sizeof(*ep) * ep_max,
994 if (udev->endpoints == NULL) {
999 udev->endpoints = NULL;
1002 USB_BUS_LOCK(udev->bus);
1003 udev->endpoints_max = ep_max;
1004 /* reset any ongoing clear-stall */
1005 udev->ep_curr = NULL;
1006 USB_BUS_UNLOCK(udev->bus);
1014 USB_BUS_LOCK(udev->bus);
1015 udev->endpoints_max = 0;
1016 /* reset any ongoing clear-stall */
1017 udev->ep_curr = NULL;
1018 USB_BUS_UNLOCK(udev->bus);
1021 free(udev->ifaces, M_USB);
1022 udev->ifaces = NULL;
1025 free(udev->endpoints, M_USB);
1026 udev->endpoints = NULL;
1028 udev->ifaces_max = 0;
1034 /*------------------------------------------------------------------------*
1047 *------------------------------------------------------------------------*/
1056 /* Prevent re-enumeration */
1063 if (iface->alt_index == alt_index) {
1083 if (iface->alt_index != alt_index) {
1090 iface->idesc->bAlternateSetting);
1098 /*------------------------------------------------------------------------*
1107 *------------------------------------------------------------------------*/
1128 et = (ep->edesc->bmAttributes & UE_XFERTYPE);
1139 USB_BUS_LOCK(udev->bus);
1142 was_stalled = ep->is_stalled;
1147 USB_BUS_UNLOCK(udev->bus);
1152 ep->is_stalled = 1;
1158 xfer = ep->endpoint_q[x].curr;
1167 (udev->bus->methods->xfer_stall) (xfer);
1171 (udev->bus->methods->set_stall) (udev, ep, &do_stall);
1174 ep->toggle_next = 0; /* reset data toggle */
1175 ep->is_stalled = 0; /* clear stalled state */
1177 (udev->bus->methods->clear_stall) (udev, ep);
1181 usb_command_wrapper(&ep->endpoint_q[x],
1182 ep->endpoint_q[x].curr);
1185 USB_BUS_UNLOCK(udev->bus);
1189 /*------------------------------------------------------------------------*
1190 * usb_reset_iface_endpoints - used in USB device side mode
1191 *------------------------------------------------------------------------*/
1198 ep = udev->endpoints;
1199 ep_end = udev->endpoints + udev->endpoints_max;
1202 if ((ep->edesc == NULL) ||
1203 (ep->iface_index != iface_index)) {
1212 /*------------------------------------------------------------------------*
1219 *------------------------------------------------------------------------*/
1240 device_get_nameunit(udev->parent_dev),
1241 udev->port_no, udev->address);
1245 if (udev->flags.peer_suspended) {
1248 device_printf(dev, "Resume failed\n");
1253 if (device_delete_child(udev->parent_dev, dev)) {
1270 /*------------------------------------------------------------------------*
1277 *------------------------------------------------------------------------*/
1291 sx_assert(&udev->enum_sx, SA_LOCKED);
1295 * chance to detach the sub-devices in the correct order.
1297 * will detach all sub-devices from the bottom and upwards!
1315 usb_detach_device_sub(udev, &iface->subdev,
1316 &iface->pnpinfo, flag);
1320 /*------------------------------------------------------------------------*
1326 *------------------------------------------------------------------------*/
1335 iface = uaa->iface;
1336 if (iface->parent_iface_index != USB_IFACE_INDEX_ANY) {
1340 dev = iface->subdev;
1348 /* clear "iface->subdev" as early as possible */
1350 iface->subdev = NULL;
1352 if (device_delete_child(udev->parent_dev, dev)) {
1356 * never fail on detach!
1361 if (uaa->temp_dev == NULL) {
1363 uaa->temp_dev = device_add_child(udev->parent_dev, NULL, DEVICE_UNIT_ANY);
1364 if (uaa->temp_dev == NULL) {
1365 device_printf(udev->parent_dev,
1369 device_set_ivars(uaa->temp_dev, uaa);
1370 device_quiet(uaa->temp_dev);
1374 * the information it needs.
1376 iface->subdev = uaa->temp_dev;
1378 if (device_probe_and_attach(iface->subdev) == 0) {
1383 uaa->temp_dev = NULL;
1384 device_set_ivars(iface->subdev, NULL);
1386 if (udev->flags.peer_suspended) {
1387 err = DEVICE_SUSPEND(iface->subdev);
1389 device_printf(iface->subdev, "Suspend failed\n");
1394 iface->subdev = NULL;
1399 /*------------------------------------------------------------------------*
1402 * Using this function will lock the alternate interface setting on an
1408 *------------------------------------------------------------------------*/
1421 iface->parent_iface_index = parent_index;
1430 uaa->device = udev;
1431 uaa->usb_mode = udev->flags.usb_mode;
1432 uaa->port = udev->port_no;
1433 uaa->dev_state = UAA_DEV_READY;
1435 uaa->info.idVendor = UGETW(udev->ddesc.idVendor);
1436 uaa->info.idProduct = UGETW(udev->ddesc.idProduct);
1437 uaa->info.bcdDevice = UGETW(udev->ddesc.bcdDevice);
1438 uaa->info.bDeviceClass = udev->ddesc.bDeviceClass;
1439 uaa->info.bDeviceSubClass = udev->ddesc.bDeviceSubClass;
1440 uaa->info.bDeviceProtocol = udev->ddesc.bDeviceProtocol;
1441 uaa->info.bConfigIndex = udev->curr_config_index;
1442 uaa->info.bConfigNum = udev->curr_config_no;
1445 /*------------------------------------------------------------------------*
1454 *------------------------------------------------------------------------*/
1468 /* Prevent re-enumeration */
1471 if (udev->curr_config_index == USB_UNCONFIG_INDEX) {
1472 /* do nothing - no configuration has been set */
1520 if (iface->idesc == NULL) {
1527 iface->idesc->bInterfaceClass;
1529 iface->idesc->bInterfaceSubClass;
1531 iface->idesc->bInterfaceProtocol;
1534 iface->idesc->bInterfaceNumber;
1535 uaa.driver_info = 0; /* reset driver_info */
1553 if (device_delete_child(udev->parent_dev, uaa.temp_dev))
1563 /*------------------------------------------------------------------------*
1566 * This function is called when the suspend or resume methods should
1567 * be executed on an USB device.
1568 *------------------------------------------------------------------------*/
1587 do_suspend ? "Suspend" : "Resume");
1591 /*------------------------------------------------------------------------*
1594 * The following function will suspend or resume the USB device.
1599 *------------------------------------------------------------------------*/
1612 sx_assert(&udev->sr_sx, SA_LOCKED);
1614 USB_BUS_LOCK(udev->bus);
1616 if (udev->flags.peer_suspended == do_suspend) {
1617 USB_BUS_UNLOCK(udev->bus);
1621 udev->flags.peer_suspended = do_suspend;
1622 USB_BUS_UNLOCK(udev->bus);
1624 /* do the suspend or resume */
1632 usb_suspend_resume_sub(udev, iface->subdev, do_suspend);
1637 /*------------------------------------------------------------------------*
1641 *------------------------------------------------------------------------*/
1646 struct usb_device *udev = pm->udev;
1649 USB_BUS_UNLOCK(udev->bus);
1650 USB_MTX_LOCK(&udev->device_mtx);
1653 usbd_transfer_start(udev->ctrl_xfer[1]);
1656 USB_MTX_UNLOCK(&udev->device_mtx);
1657 USB_BUS_LOCK(udev->bus);
1660 /*------------------------------------------------------------------------*
1664 *------------------------------------------------------------------------*/
1675 * It appears that some string-less USB chips will crash and
1687 scratch_ptr = udev->scratch.data;
1689 if (udev->flags.no_strings) {
1691 } else if (udev->ddesc.iManufacturer ||
1692 udev->ddesc.iProduct ||
1693 udev->ddesc.iSerialNumber) {
1702 udev->flags.no_strings = 1;
1732 udev->langid = langid;
1739 /*------------------------------------------------------------------------*
1750 *------------------------------------------------------------------------*/
1779 (device_index != bus->devices_max) &&
1780 (bus->devices[device_index] != NULL);
1783 if (device_index == bus->devices_max) {
1784 device_printf(bus->bdev,
1790 device_printf(bus->bdev,
1800 /* initialise our SX-lock */
1801 sx_init_flags(&udev->enum_sx, "USB config SX lock", SX_DUPOK);
1802 sx_init_flags(&udev->sr_sx, "USB suspend and resume SX lock", SX_NOWITNESS);
1803 sx_init_flags(&udev->ctrl_sx, "USB control transfer SX lock", SX_DUPOK);
1805 cv_init(&udev->ctrlreq_cv, "WCTRL");
1806 cv_init(&udev->ref_cv, "UGONE");
1809 mtx_init(&udev->device_mtx, "USB device mutex", NULL, MTX_DEF);
1812 udev->cs_msg[0].hdr.pm_callback = &usbd_clear_stall_proc;
1813 udev->cs_msg[0].udev = udev;
1814 udev->cs_msg[1].hdr.pm_callback = &usbd_clear_stall_proc;
1815 udev->cs_msg[1].udev = udev;
1818 udev->parent_hub = parent_hub;
1819 udev->parent_dev = parent_dev;
1820 udev->port_index = port_index;
1821 udev->port_no = port_no;
1822 udev->depth = depth;
1823 udev->bus = bus;
1824 udev->address = USB_START_ADDR; /* default value */
1825 udev->plugtime = (usb_ticks_t)ticks;
1827 * We need to force the power mode to "on" because there are plenty
1829 * automatic suspend and resume!
1831 udev->power_mode = usbd_filter_power_mode(udev, USB_POWER_MODE_ON);
1832 udev->pwr_save.last_xfer_time = ticks;
1834 udev->refcount = 1;
1837 udev->ctrl_ep_desc.bLength = sizeof(udev->ctrl_ep_desc);
1838 udev->ctrl_ep_desc.bDescriptorType = UDESC_ENDPOINT;
1839 udev->ctrl_ep_desc.bEndpointAddress = USB_CONTROL_ENDPOINT;
1840 udev->ctrl_ep_desc.bmAttributes = UE_CONTROL;
1841 udev->ctrl_ep_desc.wMaxPacketSize[0] = USB_MAX_IPACKET;
1842 udev->ctrl_ep_desc.wMaxPacketSize[1] = 0;
1843 udev->ctrl_ep_desc.bInterval = 0;
1846 udev->ctrl_ep_comp_desc.bLength = sizeof(udev->ctrl_ep_comp_desc);
1847 udev->ctrl_ep_comp_desc.bDescriptorType = UDESC_ENDPOINT_SS_COMP;
1849 udev->ddesc.bMaxPacketSize = USB_MAX_IPACKET;
1851 udev->speed = speed;
1852 udev->flags.usb_mode = mode;
1857 hub = udev->parent_hub;
1860 if (hub->speed == USB_SPEED_HIGH) {
1861 udev->hs_hub_addr = hub->address;
1862 udev->parent_hs_hub = hub;
1863 udev->hs_port_no = adev->port_no;
1867 hub = hub->parent_hub;
1872 &udev->ctrl_ep_desc,
1873 &udev->ctrl_ep_comp_desc,
1874 &udev->ctrl_ep);
1877 udev->device_index = device_index;
1881 snprintf(udev->ugen_name, sizeof(udev->ugen_name),
1882 USB_GENERIC_NAME "%u.%u", device_get_unit(bus->bdev),
1884 SLIST_INIT(&udev->pd_list);
1887 udev->ctrl_dev = usb_make_dev(udev, NULL, 0, 0,
1891 if (udev->ctrl_dev != NULL)
1892 make_dev_alias(udev->ctrl_dev->cdev, "%s", udev->ugen_name);
1895 if (bus->methods->device_init != NULL) {
1896 err = (bus->methods->device_init) (udev);
1907 if (udev->flags.usb_mode == USB_MODE_HOST) {
1911 * This is the new USB device address from now on, if
1914 if (udev->address == USB_START_ADDR)
1915 udev->address = device_index;
1918 * We ignore any set-address errors, hence there are
1922 * to the subsequent get-descriptor at the new
1923 * address, then we know that the set-address command
1928 "(%s, ignored)\n", udev->address,
1933 udev->flags.self_powered = 0;
1936 udev->curr_config_no = USB_UNCONFIG_NO;
1937 udev->curr_config_index = USB_UNCONFIG_INDEX;
1942 DPRINTFN(0, "setting up USB template failed - "
1970 udev->flags.uq_bus_powered = 1;
1973 udev->flags.no_strings = 1;
1979 udev->power = USB_MIN_POWER;
1983 if (udev->flags.usb_mode == USB_MODE_DEVICE) {
2021 if (udev->ddesc.bNumConfigurations != 0) {
2024 /* XXX try to re-enumerate the device */
2031 config_index, usbd_errstr(err), udev->port_no,
2032 udev->address);
2041 if (!config_quirk && config_index + 1 < udev->ddesc.bNumConfigurations) {
2042 if ((udev->cdesc->bNumInterface < 2) &&
2043 usbd_get_no_descriptors(udev->cdesc, UDESC_ENDPOINT) == 0) {
2053 * auto-install disk there:
2056 DPRINTFN(0, "Found possible auto-install "
2087 udev->address, udev, udev->parent_hub);
2089 /* register our device - we are ready */
2091 parent_hub->hub->ports + port_index : NULL, udev, device_index);
2095 udev->ugen_symlink = usb_alloc_symlink(udev->ugen_name);
2098 printf("%s: <%s %s> at %s\n", udev->ugen_name,
2100 device_get_nameunit(udev->bus->bdev));
2129 pd->bus_index = device_get_unit(udev->bus->bdev);
2130 pd->dev_index = udev->device_index;
2131 pd->ep_addr = ep;
2132 pd->fifo_index = fi;
2133 pd->mode = rwmode;
2139 pd->bus_index, pd->dev_index, pd->ep_addr);
2150 if (make_dev_s(&args, &pd->cdev, "%s", devname) != 0) {
2162 pd->bus_index, pd->dev_index);
2168 destroy_dev(pd->cdev);
2182 bus = devclass_get_softc(usb_devclass_ptr, pd->bus_index);
2190 /* make sure we can re-use the device name */
2191 delist_dev(pd->cdev);
2194 SLIST_INSERT_HEAD(&bus->pd_cleanup_list, pd, pd_next);
2197 &bus->cleanup_msg[0], &bus->cleanup_msg[1]);
2211 KASSERT(SLIST_FIRST(&udev->pd_list) == NULL, ("stale cdev entries"));
2234 if ((desc->bDescriptorType == UDESC_ENDPOINT) &&
2235 (desc->bLength >= sizeof(*ed))) {
2239 ep = ed->bEndpointAddress;
2258 SLIST_INSERT_HEAD(&udev->pd_list, pd, pd_next);
2269 while ((pd = SLIST_FIRST(&udev->pd_list)) != NULL) {
2270 KASSERT(pd->cdev->si_drv1 == pd, ("privdata corrupt"));
2272 SLIST_REMOVE(&udev->pd_list, pd, usb_fs_privdata, pd_next);
2279 /*------------------------------------------------------------------------*
2286 *------------------------------------------------------------------------*/
2295 DPRINTFN(4, "udev=%p port=%d\n", udev, udev->port_no);
2297 bus = udev->bus;
2308 printf("%s: <%s %s> at %s (disconnected)\n", udev->ugen_name,
2310 device_get_nameunit(bus->bdev));
2314 if (udev->ugen_symlink) {
2315 usb_free_symlink(udev->ugen_symlink);
2316 udev->ugen_symlink = NULL;
2319 usb_destroy_dev(udev->ctrl_dev);
2322 if (udev->flags.usb_mode == USB_MODE_DEVICE) {
2324 usbd_transfer_unsetup(udev->ctrl_xfer, USB_CTRL_XFER_MAX);
2331 usb_bus_port_set_device(bus, udev->parent_hub ?
2332 udev->parent_hub->hub->ports + udev->port_index : NULL,
2336 usbd_transfer_unsetup(udev->ctrl_xfer, USB_CTRL_XFER_MAX);
2342 * Make sure that our clear-stall messages are not queued
2345 USB_BUS_LOCK(udev->bus);
2346 usb_proc_mwait(USB_BUS_CS_PROC(udev->bus),
2347 &udev->cs_msg[0], &udev->cs_msg[1]);
2348 USB_BUS_UNLOCK(udev->bus);
2353 sx_destroy(&udev->enum_sx);
2354 sx_destroy(&udev->sr_sx);
2355 sx_destroy(&udev->ctrl_sx);
2357 cv_destroy(&udev->ctrlreq_cv);
2358 cv_destroy(&udev->ref_cv);
2360 mtx_destroy(&udev->device_mtx);
2362 KASSERT(SLIST_FIRST(&udev->pd_list) == NULL, ("leaked cdev entries"));
2366 if (bus->methods->device_uninit != NULL)
2367 (bus->methods->device_uninit) (udev);
2370 free(udev->serial, M_USB);
2371 free(udev->manufacturer, M_USB);
2372 free(udev->product, M_USB);
2376 /*------------------------------------------------------------------------*
2385 *------------------------------------------------------------------------*/
2389 struct usb_interface *iface = udev->ifaces + iface_index;
2391 if (iface_index >= udev->ifaces_max)
2396 /*------------------------------------------------------------------------*
2410 *------------------------------------------------------------------------*/
2437 if (desc->bDescriptorType == UDESC_INTERFACE) {
2440 if (((desc->bDescriptorType & type_mask) == type) &&
2441 ((desc->bDescriptorSubtype & subtype_mask) == subtype)) {
2448 /*------------------------------------------------------------------------*
2455 *------------------------------------------------------------------------*/
2459 struct usb_device_descriptor *udd = &udev->ddesc;
2463 bcdUSB = UGETW(udd->bcdUSB);
2464 bcdDevice = UGETW(udd->bcdDevice);
2466 if (udd->bDeviceClass != 0xFF) {
2471 udd->bDeviceClass, udd->bDeviceSubClass,
2474 udev->address);
2482 udev->address);
2498 #define USB_KNOWNDEV_NOPROD 0x01 /* match on vendor only */
2507 struct usb_device_descriptor *udd = &udev->ddesc;
2520 temp_ptr = (char *)udev->scratch.data;
2521 temp_size = sizeof(udev->scratch.data);
2523 vendor_id = UGETW(udd->idVendor);
2524 product_id = UGETW(udd->idProduct);
2527 free(udev->serial, M_USB);
2528 free(udev->manufacturer, M_USB);
2529 free(udev->product, M_USB);
2532 udev->serial = NULL;
2533 udev->manufacturer = NULL;
2534 udev->product = NULL;
2538 udev->ddesc.iSerialNumber);
2539 udev->serial = strdup(temp_ptr, M_USB);
2543 udev->ddesc.iManufacturer);
2546 udev->manufacturer = strdup(temp_ptr, M_USB);
2550 udev->ddesc.iProduct);
2553 udev->product = strdup(temp_ptr, M_USB);
2556 if (udev->manufacturer == NULL || udev->product == NULL) {
2557 for (kdp = usb_knowndevs; kdp->vendorname != NULL; kdp++) {
2558 if (kdp->vendor == vendor_id &&
2559 (kdp->product == product_id ||
2560 (kdp->flags & USB_KNOWNDEV_NOPROD) != 0))
2563 if (kdp->vendorname != NULL) {
2565 if (udev->manufacturer == NULL) {
2566 udev->manufacturer = strdup(kdp->vendorname,
2569 if (udev->product == NULL &&
2570 (kdp->flags & USB_KNOWNDEV_NOPROD) == 0) {
2571 udev->product = strdup(kdp->productname,
2578 if (udev->manufacturer == NULL) {
2580 udev->manufacturer = strdup(temp_ptr, M_USB);
2582 if (udev->product == NULL) {
2584 udev->product = strdup(temp_ptr, M_USB);
2598 return (udev->flags.usb_mode);
2608 return (udev->speed);
2615 switch (udev->speed) {
2629 return (&udev->ddesc);
2637 return (udev->cdesc);
2640 /*------------------------------------------------------------------------*
2641 * usb_test_quirk - test a device for a given quirk
2646 *------------------------------------------------------------------------*/
2659 if (uaa->device->autoQuirk[x] == quirk)
2665 found = (usb_test_quirk_p) (&uaa->info, quirk);
2675 return (iface->idesc);
2681 return (iface->alt_index);
2687 return ((uint8_t)device_get_unit(udev->bus->bdev));
2693 return (udev->device_index);
2724 udev->ugen_name,
2725 udev->ugen_name,
2727 UGETW(udev->ddesc.idVendor),
2728 UGETW(udev->ddesc.idProduct),
2729 udev->ddesc.bDeviceClass,
2730 udev->ddesc.bDeviceSubClass,
2732 UGETW(udev->ddesc.bcdDevice),
2733 (udev->flags.usb_mode == USB_MODE_HOST) ? "host" : "device",
2734 udev->port_no
2736 , udev->parent_hub != NULL ?
2737 udev->parent_hub->ugen_name :
2738 device_get_nameunit(device_get_parent(udev->bus->bdev))
2750 if (iface->idesc == NULL)
2772 udev->ugen_name,
2773 udev->ugen_name,
2775 UGETW(udev->ddesc.idVendor),
2776 UGETW(udev->ddesc.idProduct),
2777 udev->ddesc.bDeviceClass,
2778 udev->ddesc.bDeviceSubClass,
2780 UGETW(udev->ddesc.bcdDevice),
2781 (udev->flags.usb_mode == USB_MODE_HOST) ? "host" : "device",
2782 iface->idesc->bInterfaceNumber,
2783 iface->idesc->bNumEndpoints,
2784 iface->idesc->bInterfaceClass,
2785 iface->idesc->bInterfaceSubClass,
2786 iface->idesc->bInterfaceProtocol);
2795 /*------------------------------------------------------------------------*
2806 *------------------------------------------------------------------------*/
2815 * Free any USB FIFOs on the given interface:
2818 f = udev->fifo[i];
2823 if (iface_index == f->iface_index) {
2824 if (f->methods != &usb_ugen_methods) {
2826 * Don't free any non-generic FIFOs in
2831 if ((f->dev_ep_index == 0) &&
2832 (f->fs_ep_max == 0)) {
2837 if ((f->methods == &usb_ugen_methods) &&
2838 (f->dev_ep_index == 0) &&
2840 (f->fs_ep_max == 0)) {
2854 /*------------------------------------------------------------------------*
2858 * 0: Peer cannot do resume signalling.
2859 * Else: Peer can do resume signalling.
2860 *------------------------------------------------------------------------*/
2866 cdp = udev->cdesc;
2867 if ((cdp != NULL) && (udev->flags.usb_mode == USB_MODE_HOST)) {
2868 return (cdp->bmAttributes & UC_REMOTE_WAKEUP);
2879 DPRINTF("udev %p state %s -> %s\n", udev,
2880 usb_statestr(udev->state), usb_statestr(state));
2885 udev->state = state;
2889 if (udev->bus->methods->device_state_change != NULL)
2890 (udev->bus->methods->device_state_change) (udev);
2898 return (udev->state);
2904 return (udev->state > USB_STATE_DETACHED);
2915 if (sx_xlocked(&udev->enum_sx))
2918 sx_xlock(&udev->enum_sx);
2919 sx_xlock(&udev->sr_sx);
2937 if (sx_xlocked(&udev->enum_sx))
2939 if (sx_xlock_sig(&udev->enum_sx))
2941 if (sx_xlock_sig(&udev->sr_sx)) {
2942 sx_xunlock(&udev->enum_sx);
2956 sx_xunlock(&udev->enum_sx);
2957 sx_xunlock(&udev->sr_sx);
2960 /* The following function locks suspend and resume. */
2965 sx_xlock(&udev->sr_sx);
2974 /* The following function unlocks suspend and resume. */
2980 sx_xunlock(&udev->sr_sx);
2991 return (sx_xlocked(&udev->enum_sx));
3002 if (sx_xlocked(&udev->ctrl_sx))
3004 sx_xlock(&udev->ctrl_sx);
3007 * We need to allow suspend and resume at this point, else the
3018 sx_xunlock(&udev->ctrl_sx);
3021 * Restore the suspend and resume lock after we have unlocked
3029 * The following function is used to set the per-interface specific
3032 * pnpinfo of an interface will be reset at device detach or when
3034 * returns zero on success, else a USB_ERR_XXX failure code.
3046 if (iface->pnpinfo != NULL) {
3047 free(iface->pnpinfo, M_USBDEV);
3048 iface->pnpinfo = NULL;
3054 iface->pnpinfo = strdup(pnpinfo, M_USBDEV);
3055 if (iface->pnpinfo == NULL)
3067 if (udev->autoQuirk[x] == 0 ||
3068 udev->autoQuirk[x] == quirk) {
3069 udev->autoQuirk[x] = quirk;
3088 /* Prevent re-enumeration */
3091 if (udev->bus->methods->set_endpoint_mode != NULL) {
3092 error = (udev->bus->methods->set_endpoint_mode) (
3101 ep->ep_mode = ep_mode;
3111 return (ep->ep_mode);