usb_device.c revision 192500
1184610Salfred/* $FreeBSD: head/sys/dev/usb/usb_device.c 192500 2009-05-21 01:05:21Z thompsa $ */ 2184610Salfred/*- 3184610Salfred * Copyright (c) 2008 Hans Petter Selasky. All rights reserved. 4184610Salfred * 5184610Salfred * Redistribution and use in source and binary forms, with or without 6184610Salfred * modification, are permitted provided that the following conditions 7184610Salfred * are met: 8184610Salfred * 1. Redistributions of source code must retain the above copyright 9184610Salfred * notice, this list of conditions and the following disclaimer. 10184610Salfred * 2. Redistributions in binary form must reproduce the above copyright 11184610Salfred * notice, this list of conditions and the following disclaimer in the 12184610Salfred * documentation and/or other materials provided with the distribution. 13184610Salfred * 14184610Salfred * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15184610Salfred * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16184610Salfred * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17184610Salfred * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18184610Salfred * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19184610Salfred * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20184610Salfred * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21184610Salfred * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22184610Salfred * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23184610Salfred * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24184610Salfred * SUCH DAMAGE. 25184610Salfred */ 26184610Salfred 27188942Sthompsa#include <dev/usb/usb_mfunc.h> 28188942Sthompsa#include <dev/usb/usb_error.h> 29188942Sthompsa#include <dev/usb/usb.h> 30188942Sthompsa#include <dev/usb/usb_ioctl.h> 31188746Sthompsa#include "usbdevs.h" 32184610Salfred 33184610Salfred#define USB_DEBUG_VAR usb2_debug 34184610Salfred 35188942Sthompsa#include <dev/usb/usb_core.h> 36188942Sthompsa#include <dev/usb/usb_debug.h> 37188942Sthompsa#include <dev/usb/usb_process.h> 38188942Sthompsa#include <dev/usb/usb_device.h> 39188942Sthompsa#include <dev/usb/usb_busdma.h> 40188942Sthompsa#include <dev/usb/usb_transfer.h> 41188942Sthompsa#include <dev/usb/usb_parse.h> 42188942Sthompsa#include <dev/usb/usb_request.h> 43188942Sthompsa#include <dev/usb/usb_dynamic.h> 44188942Sthompsa#include <dev/usb/usb_hub.h> 45188942Sthompsa#include <dev/usb/usb_util.h> 46188942Sthompsa#include <dev/usb/usb_mbuf.h> 47190180Sthompsa#include <dev/usb/usb_msctest.h> 48190180Sthompsa#if USB_HAVE_UGEN 49188942Sthompsa#include <dev/usb/usb_dev.h> 50188942Sthompsa#include <dev/usb/usb_generic.h> 51190180Sthompsa#endif 52184610Salfred 53188942Sthompsa#include <dev/usb/quirk/usb_quirk.h> 54184610Salfred 55188942Sthompsa#include <dev/usb/usb_controller.h> 56188942Sthompsa#include <dev/usb/usb_bus.h> 57184610Salfred 58190754Sthompsa/* function prototypes */ 59184610Salfred 60190730Sthompsastatic void usb2_init_pipe(struct usb2_device *, uint8_t, 61185948Sthompsa struct usb2_endpoint_descriptor *, struct usb2_pipe *); 62190730Sthompsastatic void usb2_unconfigure(struct usb2_device *, uint8_t); 63190730Sthompsastatic void usb2_detach_device(struct usb2_device *, uint8_t, uint8_t); 64185948Sthompsastatic void usb2_detach_device_sub(struct usb2_device *, device_t *, 65185948Sthompsa uint8_t); 66185948Sthompsastatic uint8_t usb2_probe_and_attach_sub(struct usb2_device *, 67185948Sthompsa struct usb2_attach_arg *); 68185948Sthompsastatic void usb2_init_attach_arg(struct usb2_device *, 69185948Sthompsa struct usb2_attach_arg *); 70185948Sthompsastatic void usb2_suspend_resume_sub(struct usb2_device *, device_t, 71185948Sthompsa uint8_t); 72185948Sthompsastatic void usb2_clear_stall_proc(struct usb2_proc_msg *_pm); 73190730Sthompsausb2_error_t usb2_config_parse(struct usb2_device *, uint8_t, uint8_t); 74190180Sthompsa#if USB_HAVE_STRINGS 75185948Sthompsastatic void usb2_check_strings(struct usb2_device *); 76190180Sthompsa#endif 77190191Sthompsa#if USB_HAVE_UGEN 78185948Sthompsastatic void usb2_notify_addq(const char *type, struct usb2_device *); 79185948Sthompsastatic void usb2_fifo_free_wrap(struct usb2_device *, uint8_t, uint8_t); 80189172Sthompsastatic struct cdev *usb2_make_dev(struct usb2_device *, int, int); 81189110Sthompsastatic void usb2_cdev_create(struct usb2_device *); 82189110Sthompsastatic void usb2_cdev_free(struct usb2_device *); 83189110Sthompsastatic void usb2_cdev_cleanup(void *); 84189599Sthompsa#endif 85184610Salfred 86184610Salfred/* This variable is global to allow easy access to it: */ 87184610Salfred 88184610Salfredint usb2_template = 0; 89184610Salfred 90184610SalfredSYSCTL_INT(_hw_usb2, OID_AUTO, template, CTLFLAG_RW, 91184610Salfred &usb2_template, 0, "Selected USB device side template"); 92184610Salfred 93191498Sthompsastatic const char* statestr[USB_STATE_MAX] = { 94191498Sthompsa [USB_STATE_DETACHED] = "DETACHED", 95191498Sthompsa [USB_STATE_ATTACHED] = "ATTACHED", 96191498Sthompsa [USB_STATE_POWERED] = "POWERED", 97191498Sthompsa [USB_STATE_ADDRESSED] = "ADDRESSED", 98191498Sthompsa [USB_STATE_CONFIGURED] = "CONFIGURED", 99191498Sthompsa}; 100184610Salfred 101191498Sthompsaconst char * 102192500Sthompsausb2_statestr(enum usb_dev_state state) 103191498Sthompsa{ 104191824Sthompsa return ((state < USB_STATE_MAX) ? statestr[state] : "UNKNOWN"); 105191498Sthompsa} 106191498Sthompsa 107184610Salfred/*------------------------------------------------------------------------* 108184610Salfred * usb2_get_pipe_by_addr 109184610Salfred * 110184610Salfred * This function searches for an USB pipe by endpoint address and 111184610Salfred * direction. 112184610Salfred * 113184610Salfred * Returns: 114184610Salfred * NULL: Failure 115184610Salfred * Else: Success 116184610Salfred *------------------------------------------------------------------------*/ 117184610Salfredstruct usb2_pipe * 118184610Salfredusb2_get_pipe_by_addr(struct usb2_device *udev, uint8_t ea_val) 119184610Salfred{ 120184610Salfred struct usb2_pipe *pipe = udev->pipes; 121190731Sthompsa struct usb2_pipe *pipe_end = udev->pipes + udev->pipes_max; 122184610Salfred enum { 123184610Salfred EA_MASK = (UE_DIR_IN | UE_DIR_OUT | UE_ADDR), 124184610Salfred }; 125184610Salfred 126184610Salfred /* 127184610Salfred * According to the USB specification not all bits are used 128184610Salfred * for the endpoint address. Keep defined bits only: 129184610Salfred */ 130184610Salfred ea_val &= EA_MASK; 131184610Salfred 132184610Salfred /* 133184610Salfred * Iterate accross all the USB pipes searching for a match 134184610Salfred * based on the endpoint address: 135184610Salfred */ 136184610Salfred for (; pipe != pipe_end; pipe++) { 137184610Salfred 138184610Salfred if (pipe->edesc == NULL) { 139184610Salfred continue; 140184610Salfred } 141184610Salfred /* do the mask and check the value */ 142184610Salfred if ((pipe->edesc->bEndpointAddress & EA_MASK) == ea_val) { 143184610Salfred goto found; 144184610Salfred } 145184610Salfred } 146184610Salfred 147184610Salfred /* 148184610Salfred * The default pipe is always present and is checked separately: 149184610Salfred */ 150184610Salfred if ((udev->default_pipe.edesc) && 151184610Salfred ((udev->default_pipe.edesc->bEndpointAddress & EA_MASK) == ea_val)) { 152184610Salfred pipe = &udev->default_pipe; 153184610Salfred goto found; 154184610Salfred } 155184610Salfred return (NULL); 156184610Salfred 157184610Salfredfound: 158184610Salfred return (pipe); 159184610Salfred} 160184610Salfred 161184610Salfred/*------------------------------------------------------------------------* 162184610Salfred * usb2_get_pipe 163184610Salfred * 164184610Salfred * This function searches for an USB pipe based on the information 165184610Salfred * given by the passed "struct usb2_config" pointer. 166184610Salfred * 167184610Salfred * Return values: 168184610Salfred * NULL: No match. 169184610Salfred * Else: Pointer to "struct usb2_pipe". 170184610Salfred *------------------------------------------------------------------------*/ 171184610Salfredstruct usb2_pipe * 172184610Salfredusb2_get_pipe(struct usb2_device *udev, uint8_t iface_index, 173184610Salfred const struct usb2_config *setup) 174184610Salfred{ 175184610Salfred struct usb2_pipe *pipe = udev->pipes; 176190731Sthompsa struct usb2_pipe *pipe_end = udev->pipes + udev->pipes_max; 177184610Salfred uint8_t index = setup->ep_index; 178184610Salfred uint8_t ea_mask; 179184610Salfred uint8_t ea_val; 180184610Salfred uint8_t type_mask; 181184610Salfred uint8_t type_val; 182184610Salfred 183184610Salfred DPRINTFN(10, "udev=%p iface_index=%d address=0x%x " 184184610Salfred "type=0x%x dir=0x%x index=%d\n", 185184610Salfred udev, iface_index, setup->endpoint, 186184610Salfred setup->type, setup->direction, setup->ep_index); 187184610Salfred 188190734Sthompsa /* check USB mode */ 189190734Sthompsa 190192499Sthompsa if (setup->usb_mode != USB_MODE_DUAL && 191192499Sthompsa udev->flags.usb_mode != setup->usb_mode) { 192190734Sthompsa /* wrong mode - no pipe */ 193190734Sthompsa return (NULL); 194190734Sthompsa } 195190734Sthompsa 196184610Salfred /* setup expected endpoint direction mask and value */ 197184610Salfred 198190732Sthompsa if (setup->direction == UE_DIR_RX) { 199190732Sthompsa ea_mask = (UE_DIR_IN | UE_DIR_OUT); 200192499Sthompsa ea_val = (udev->flags.usb_mode == USB_MODE_DEVICE) ? 201190732Sthompsa UE_DIR_OUT : UE_DIR_IN; 202190732Sthompsa } else if (setup->direction == UE_DIR_TX) { 203190732Sthompsa ea_mask = (UE_DIR_IN | UE_DIR_OUT); 204192499Sthompsa ea_val = (udev->flags.usb_mode == USB_MODE_DEVICE) ? 205190732Sthompsa UE_DIR_IN : UE_DIR_OUT; 206190732Sthompsa } else if (setup->direction == UE_DIR_ANY) { 207184610Salfred /* match any endpoint direction */ 208184610Salfred ea_mask = 0; 209184610Salfred ea_val = 0; 210184610Salfred } else { 211184610Salfred /* match the given endpoint direction */ 212184610Salfred ea_mask = (UE_DIR_IN | UE_DIR_OUT); 213184610Salfred ea_val = (setup->direction & (UE_DIR_IN | UE_DIR_OUT)); 214184610Salfred } 215184610Salfred 216184610Salfred /* setup expected endpoint address */ 217184610Salfred 218184610Salfred if (setup->endpoint == UE_ADDR_ANY) { 219184610Salfred /* match any endpoint address */ 220184610Salfred } else { 221184610Salfred /* match the given endpoint address */ 222184610Salfred ea_mask |= UE_ADDR; 223184610Salfred ea_val |= (setup->endpoint & UE_ADDR); 224184610Salfred } 225184610Salfred 226184610Salfred /* setup expected endpoint type */ 227184610Salfred 228184610Salfred if (setup->type == UE_BULK_INTR) { 229184610Salfred /* this will match BULK and INTERRUPT endpoints */ 230184610Salfred type_mask = 2; 231184610Salfred type_val = 2; 232184610Salfred } else if (setup->type == UE_TYPE_ANY) { 233184610Salfred /* match any endpoint type */ 234184610Salfred type_mask = 0; 235184610Salfred type_val = 0; 236184610Salfred } else { 237184610Salfred /* match the given endpoint type */ 238184610Salfred type_mask = UE_XFERTYPE; 239184610Salfred type_val = (setup->type & UE_XFERTYPE); 240184610Salfred } 241184610Salfred 242184610Salfred /* 243184610Salfred * Iterate accross all the USB pipes searching for a match 244184610Salfred * based on the endpoint address. Note that we are searching 245184610Salfred * the pipes from the beginning of the "udev->pipes" array. 246184610Salfred */ 247184610Salfred for (; pipe != pipe_end; pipe++) { 248184610Salfred 249184610Salfred if ((pipe->edesc == NULL) || 250184610Salfred (pipe->iface_index != iface_index)) { 251184610Salfred continue; 252184610Salfred } 253184610Salfred /* do the masks and check the values */ 254184610Salfred 255184610Salfred if (((pipe->edesc->bEndpointAddress & ea_mask) == ea_val) && 256184610Salfred ((pipe->edesc->bmAttributes & type_mask) == type_val)) { 257184610Salfred if (!index--) { 258184610Salfred goto found; 259184610Salfred } 260184610Salfred } 261184610Salfred } 262184610Salfred 263184610Salfred /* 264184610Salfred * Match against default pipe last, so that "any pipe", "any 265184610Salfred * address" and "any direction" returns the first pipe of the 266184610Salfred * interface. "iface_index" and "direction" is ignored: 267184610Salfred */ 268184610Salfred if ((udev->default_pipe.edesc) && 269184610Salfred ((udev->default_pipe.edesc->bEndpointAddress & ea_mask) == ea_val) && 270184610Salfred ((udev->default_pipe.edesc->bmAttributes & type_mask) == type_val) && 271184610Salfred (!index)) { 272184610Salfred pipe = &udev->default_pipe; 273184610Salfred goto found; 274184610Salfred } 275184610Salfred return (NULL); 276184610Salfred 277184610Salfredfound: 278184610Salfred return (pipe); 279184610Salfred} 280184610Salfred 281184610Salfred/*------------------------------------------------------------------------* 282184610Salfred * usb2_interface_count 283184610Salfred * 284184610Salfred * This function stores the number of USB interfaces excluding 285184610Salfred * alternate settings, which the USB config descriptor reports into 286184610Salfred * the unsigned 8-bit integer pointed to by "count". 287184610Salfred * 288184610Salfred * Returns: 289184610Salfred * 0: Success 290184610Salfred * Else: Failure 291184610Salfred *------------------------------------------------------------------------*/ 292184610Salfredusb2_error_t 293184610Salfredusb2_interface_count(struct usb2_device *udev, uint8_t *count) 294184610Salfred{ 295184610Salfred if (udev->cdesc == NULL) { 296184610Salfred *count = 0; 297184610Salfred return (USB_ERR_NOT_CONFIGURED); 298184610Salfred } 299190730Sthompsa *count = udev->ifaces_max; 300184610Salfred return (USB_ERR_NORMAL_COMPLETION); 301184610Salfred} 302184610Salfred 303184610Salfred 304184610Salfred/*------------------------------------------------------------------------* 305190730Sthompsa * usb2_init_pipe 306184610Salfred * 307184610Salfred * This function will initialise the USB pipe structure pointed to by 308190730Sthompsa * the "pipe" argument. The structure pointed to by "pipe" must be 309190730Sthompsa * zeroed before calling this function. 310184610Salfred *------------------------------------------------------------------------*/ 311184610Salfredstatic void 312190730Sthompsausb2_init_pipe(struct usb2_device *udev, uint8_t iface_index, 313184610Salfred struct usb2_endpoint_descriptor *edesc, struct usb2_pipe *pipe) 314184610Salfred{ 315190730Sthompsa struct usb2_bus_methods *methods; 316189110Sthompsa 317190730Sthompsa methods = udev->bus->methods; 318184610Salfred 319190730Sthompsa (methods->pipe_init) (udev, edesc, pipe); 320184610Salfred 321184610Salfred /* initialise USB pipe structure */ 322184610Salfred pipe->edesc = edesc; 323184610Salfred pipe->iface_index = iface_index; 324184610Salfred TAILQ_INIT(&pipe->pipe_q.head); 325184610Salfred pipe->pipe_q.command = &usb2_pipe_start; 326184610Salfred 327190735Sthompsa /* the pipe is not supported by the hardware */ 328190735Sthompsa if (pipe->methods == NULL) 329190735Sthompsa return; 330190735Sthompsa 331184610Salfred /* clear stall, if any */ 332190730Sthompsa if (methods->clear_stall != NULL) { 333184824Sthompsa USB_BUS_LOCK(udev->bus); 334190730Sthompsa (methods->clear_stall) (udev, pipe); 335184824Sthompsa USB_BUS_UNLOCK(udev->bus); 336184610Salfred } 337184610Salfred} 338184610Salfred 339190730Sthompsa/*-----------------------------------------------------------------------* 340188985Sthompsa * usb2_pipe_foreach 341188985Sthompsa * 342188985Sthompsa * This function will iterate all the USB endpoints except the control 343188985Sthompsa * endpoint. This function is NULL safe. 344188985Sthompsa * 345188985Sthompsa * Return values: 346188985Sthompsa * NULL: End of USB pipes 347188985Sthompsa * Else: Pointer to next USB pipe 348188985Sthompsa *------------------------------------------------------------------------*/ 349188985Sthompsastruct usb2_pipe * 350188985Sthompsausb2_pipe_foreach(struct usb2_device *udev, struct usb2_pipe *pipe) 351188985Sthompsa{ 352190731Sthompsa struct usb2_pipe *pipe_end = udev->pipes + udev->pipes_max; 353188985Sthompsa 354188985Sthompsa /* be NULL safe */ 355188985Sthompsa if (udev == NULL) 356188985Sthompsa return (NULL); 357188985Sthompsa 358188985Sthompsa /* get next pipe */ 359188985Sthompsa if (pipe == NULL) 360188985Sthompsa pipe = udev->pipes; 361188985Sthompsa else 362188985Sthompsa pipe++; 363188985Sthompsa 364188985Sthompsa /* find next allocated pipe */ 365188985Sthompsa while (pipe != pipe_end) { 366188985Sthompsa if (pipe->edesc != NULL) 367188985Sthompsa return (pipe); 368188985Sthompsa pipe++; 369188985Sthompsa } 370188985Sthompsa return (NULL); 371188985Sthompsa} 372188985Sthompsa 373188985Sthompsa/*------------------------------------------------------------------------* 374190730Sthompsa * usb2_unconfigure 375184610Salfred * 376190730Sthompsa * This function will free all USB interfaces and USB pipes belonging 377190730Sthompsa * to an USB device. 378190730Sthompsa * 379190730Sthompsa * Flag values, see "USB_UNCFG_FLAG_XXX". 380184610Salfred *------------------------------------------------------------------------*/ 381190730Sthompsastatic void 382190730Sthompsausb2_unconfigure(struct usb2_device *udev, uint8_t flag) 383184610Salfred{ 384190730Sthompsa uint8_t do_unlock; 385184610Salfred 386190730Sthompsa /* automatic locking */ 387190730Sthompsa if (sx_xlocked(udev->default_sx + 1)) { 388190730Sthompsa do_unlock = 0; 389190730Sthompsa } else { 390190730Sthompsa do_unlock = 1; 391190730Sthompsa sx_xlock(udev->default_sx + 1); 392184610Salfred } 393184610Salfred 394190730Sthompsa /* detach all interface drivers */ 395190730Sthompsa usb2_detach_device(udev, USB_IFACE_INDEX_ANY, flag); 396184610Salfred 397190730Sthompsa#if USB_HAVE_UGEN 398190730Sthompsa /* free all FIFOs except control endpoint FIFOs */ 399190730Sthompsa usb2_fifo_free_wrap(udev, USB_IFACE_INDEX_ANY, flag); 400184610Salfred 401184610Salfred /* 402190730Sthompsa * Free all cdev's, if any. 403184610Salfred */ 404190730Sthompsa usb2_cdev_free(udev); 405190730Sthompsa#endif 406184610Salfred 407190180Sthompsa#if USB_HAVE_COMPAT_LINUX 408184610Salfred /* free Linux compat device, if any */ 409184610Salfred if (udev->linux_dev) { 410184610Salfred usb_linux_free_device(udev->linux_dev); 411184610Salfred udev->linux_dev = NULL; 412184610Salfred } 413190180Sthompsa#endif 414184610Salfred 415190730Sthompsa usb2_config_parse(udev, USB_IFACE_INDEX_ANY, USB_CFG_FREE); 416184610Salfred 417190730Sthompsa /* free "cdesc" after "ifaces" and "pipes", if any */ 418190727Sthompsa if (udev->cdesc != NULL) { 419192499Sthompsa if (udev->flags.usb_mode != USB_MODE_DEVICE) 420190727Sthompsa free(udev->cdesc, M_USB); 421184610Salfred udev->cdesc = NULL; 422184610Salfred } 423184610Salfred /* set unconfigured state */ 424184610Salfred udev->curr_config_no = USB_UNCONFIG_NO; 425184610Salfred udev->curr_config_index = USB_UNCONFIG_INDEX; 426190730Sthompsa 427190730Sthompsa if (do_unlock) { 428190730Sthompsa sx_unlock(udev->default_sx + 1); 429190730Sthompsa } 430184610Salfred} 431184610Salfred 432184610Salfred/*------------------------------------------------------------------------* 433184610Salfred * usb2_set_config_index 434184610Salfred * 435184610Salfred * This function selects configuration by index, independent of the 436184610Salfred * actual configuration number. This function should not be used by 437184610Salfred * USB drivers. 438184610Salfred * 439184610Salfred * Returns: 440184610Salfred * 0: Success 441184610Salfred * Else: Failure 442184610Salfred *------------------------------------------------------------------------*/ 443184610Salfredusb2_error_t 444184610Salfredusb2_set_config_index(struct usb2_device *udev, uint8_t index) 445184610Salfred{ 446184610Salfred struct usb2_status ds; 447184610Salfred struct usb2_config_descriptor *cdp; 448184610Salfred uint16_t power; 449184610Salfred uint16_t max_power; 450184610Salfred uint8_t selfpowered; 451184610Salfred uint8_t do_unlock; 452184610Salfred usb2_error_t err; 453184610Salfred 454184610Salfred DPRINTFN(6, "udev=%p index=%d\n", udev, index); 455184610Salfred 456184610Salfred /* automatic locking */ 457184610Salfred if (sx_xlocked(udev->default_sx + 1)) { 458184610Salfred do_unlock = 0; 459184610Salfred } else { 460184610Salfred do_unlock = 1; 461184610Salfred sx_xlock(udev->default_sx + 1); 462184610Salfred } 463184610Salfred 464190730Sthompsa usb2_unconfigure(udev, USB_UNCFG_FLAG_FREE_SUBDEV); 465184610Salfred 466184610Salfred if (index == USB_UNCONFIG_INDEX) { 467184610Salfred /* 468184610Salfred * Leave unallocated when unconfiguring the 469190730Sthompsa * device. "usb2_unconfigure()" will also reset 470184610Salfred * the current config number and index. 471184610Salfred */ 472188986Sthompsa err = usb2_req_set_config(udev, NULL, USB_UNCONFIG_NO); 473191494Sthompsa if (udev->state == USB_STATE_CONFIGURED) 474191494Sthompsa usb2_set_device_state(udev, USB_STATE_ADDRESSED); 475184610Salfred goto done; 476184610Salfred } 477184610Salfred /* get the full config descriptor */ 478192499Sthompsa if (udev->flags.usb_mode == USB_MODE_DEVICE) { 479190727Sthompsa /* save some memory */ 480191402Sthompsa err = usb2_req_get_descriptor_ptr(udev, &cdp, 481191402Sthompsa (UDESC_CONFIG << 8) | index); 482190727Sthompsa } else { 483190727Sthompsa /* normal request */ 484190727Sthompsa err = usb2_req_get_config_desc_full(udev, 485190727Sthompsa NULL, &cdp, M_USB, index); 486190727Sthompsa } 487184610Salfred if (err) { 488184610Salfred goto done; 489184610Salfred } 490184610Salfred /* set the new config descriptor */ 491184610Salfred 492184610Salfred udev->cdesc = cdp; 493184610Salfred 494184610Salfred /* Figure out if the device is self or bus powered. */ 495184610Salfred selfpowered = 0; 496184610Salfred if ((!udev->flags.uq_bus_powered) && 497184610Salfred (cdp->bmAttributes & UC_SELF_POWERED) && 498192499Sthompsa (udev->flags.usb_mode == USB_MODE_HOST)) { 499184610Salfred /* May be self powered. */ 500184610Salfred if (cdp->bmAttributes & UC_BUS_POWERED) { 501184610Salfred /* Must ask device. */ 502190743Sthompsa err = usb2_req_get_device_status(udev, NULL, &ds); 503190743Sthompsa if (err) { 504190743Sthompsa DPRINTFN(0, "could not read " 505190743Sthompsa "device status: %s\n", 506190743Sthompsa usb2_errstr(err)); 507190743Sthompsa } else if (UGETW(ds.wStatus) & UDS_SELF_POWERED) { 508190743Sthompsa selfpowered = 1; 509184610Salfred } 510190743Sthompsa DPRINTF("status=0x%04x \n", 511190743Sthompsa UGETW(ds.wStatus)); 512184610Salfred } else 513184610Salfred selfpowered = 1; 514184610Salfred } 515184610Salfred DPRINTF("udev=%p cdesc=%p (addr %d) cno=%d attr=0x%02x, " 516184610Salfred "selfpowered=%d, power=%d\n", 517184610Salfred udev, cdp, 518190328Sthompsa udev->address, cdp->bConfigurationValue, cdp->bmAttributes, 519184610Salfred selfpowered, cdp->bMaxPower * 2); 520184610Salfred 521184610Salfred /* Check if we have enough power. */ 522184610Salfred power = cdp->bMaxPower * 2; 523184610Salfred 524184610Salfred if (udev->parent_hub) { 525184610Salfred max_power = udev->parent_hub->hub->portpower; 526184610Salfred } else { 527184610Salfred max_power = USB_MAX_POWER; 528184610Salfred } 529184610Salfred 530184610Salfred if (power > max_power) { 531184610Salfred DPRINTFN(0, "power exceeded %d > %d\n", power, max_power); 532184610Salfred err = USB_ERR_NO_POWER; 533184610Salfred goto done; 534184610Salfred } 535184610Salfred /* Only update "self_powered" in USB Host Mode */ 536192499Sthompsa if (udev->flags.usb_mode == USB_MODE_HOST) { 537184610Salfred udev->flags.self_powered = selfpowered; 538184610Salfred } 539184610Salfred udev->power = power; 540184610Salfred udev->curr_config_no = cdp->bConfigurationValue; 541184610Salfred udev->curr_config_index = index; 542191494Sthompsa usb2_set_device_state(udev, USB_STATE_CONFIGURED); 543184610Salfred 544184610Salfred /* Set the actual configuration value. */ 545188986Sthompsa err = usb2_req_set_config(udev, NULL, cdp->bConfigurationValue); 546184610Salfred if (err) { 547184610Salfred goto done; 548184610Salfred } 549190730Sthompsa 550190730Sthompsa err = usb2_config_parse(udev, USB_IFACE_INDEX_ANY, USB_CFG_ALLOC); 551190730Sthompsa if (err) { 552190730Sthompsa goto done; 553184610Salfred } 554190730Sthompsa 555190730Sthompsa err = usb2_config_parse(udev, USB_IFACE_INDEX_ANY, USB_CFG_INIT); 556190730Sthompsa if (err) { 557190730Sthompsa goto done; 558190730Sthompsa } 559190730Sthompsa 560189599Sthompsa#if USB_HAVE_UGEN 561189110Sthompsa /* create device nodes for each endpoint */ 562189110Sthompsa usb2_cdev_create(udev); 563189599Sthompsa#endif 564184610Salfred 565184610Salfreddone: 566184610Salfred DPRINTF("error=%s\n", usb2_errstr(err)); 567184610Salfred if (err) { 568190730Sthompsa usb2_unconfigure(udev, USB_UNCFG_FLAG_FREE_SUBDEV); 569184610Salfred } 570184610Salfred if (do_unlock) { 571184610Salfred sx_unlock(udev->default_sx + 1); 572184610Salfred } 573184610Salfred return (err); 574184610Salfred} 575184610Salfred 576184610Salfred/*------------------------------------------------------------------------* 577190730Sthompsa * usb2_config_parse 578190730Sthompsa * 579190730Sthompsa * This function will allocate and free USB interfaces and USB pipes, 580190730Sthompsa * parse the USB configuration structure and initialise the USB pipes 581190730Sthompsa * and interfaces. If "iface_index" is not equal to 582190730Sthompsa * "USB_IFACE_INDEX_ANY" then the "cmd" parameter is the 583190730Sthompsa * alternate_setting to be selected for the given interface. Else the 584190730Sthompsa * "cmd" parameter is defined by "USB_CFG_XXX". "iface_index" can be 585190730Sthompsa * "USB_IFACE_INDEX_ANY" or a valid USB interface index. This function 586190730Sthompsa * is typically called when setting the configuration or when setting 587190730Sthompsa * an alternate interface. 588190730Sthompsa * 589190730Sthompsa * Returns: 590190730Sthompsa * 0: Success 591190730Sthompsa * Else: Failure 592190730Sthompsa *------------------------------------------------------------------------*/ 593190730Sthompsausb2_error_t 594190730Sthompsausb2_config_parse(struct usb2_device *udev, uint8_t iface_index, uint8_t cmd) 595190730Sthompsa{ 596190730Sthompsa struct usb2_idesc_parse_state ips; 597190730Sthompsa struct usb2_interface_descriptor *id; 598190730Sthompsa struct usb2_endpoint_descriptor *ed; 599190730Sthompsa struct usb2_interface *iface; 600190730Sthompsa struct usb2_pipe *pipe; 601190730Sthompsa usb2_error_t err; 602190730Sthompsa uint8_t ep_curr; 603190730Sthompsa uint8_t ep_max; 604190730Sthompsa uint8_t temp; 605190730Sthompsa uint8_t do_init; 606190730Sthompsa uint8_t alt_index; 607190730Sthompsa 608190730Sthompsa if (iface_index != USB_IFACE_INDEX_ANY) { 609190730Sthompsa /* parameter overload */ 610190730Sthompsa alt_index = cmd; 611190730Sthompsa cmd = USB_CFG_INIT; 612190730Sthompsa } else { 613190730Sthompsa /* not used */ 614190730Sthompsa alt_index = 0; 615190730Sthompsa } 616190730Sthompsa 617190730Sthompsa err = 0; 618190730Sthompsa 619190730Sthompsa DPRINTFN(5, "iface_index=%d cmd=%d\n", 620190730Sthompsa iface_index, cmd); 621190730Sthompsa 622190730Sthompsa if (cmd == USB_CFG_FREE) 623190730Sthompsa goto cleanup; 624190730Sthompsa 625190730Sthompsa if (cmd == USB_CFG_INIT) { 626190730Sthompsa sx_assert(udev->default_sx + 1, SA_LOCKED); 627190730Sthompsa 628190730Sthompsa /* check for in-use pipes */ 629190730Sthompsa 630190730Sthompsa pipe = udev->pipes; 631190730Sthompsa ep_max = udev->pipes_max; 632190730Sthompsa while (ep_max--) { 633190730Sthompsa /* look for matching pipes */ 634190730Sthompsa if ((iface_index == USB_IFACE_INDEX_ANY) || 635190730Sthompsa (iface_index == pipe->iface_index)) { 636190730Sthompsa if (pipe->refcount != 0) { 637190730Sthompsa /* 638190730Sthompsa * This typically indicates a 639190730Sthompsa * more serious error. 640190730Sthompsa */ 641190730Sthompsa err = USB_ERR_IN_USE; 642190730Sthompsa } else { 643190730Sthompsa /* reset pipe */ 644190730Sthompsa memset(pipe, 0, sizeof(*pipe)); 645190730Sthompsa /* make sure we don't zero the pipe again */ 646190730Sthompsa pipe->iface_index = USB_IFACE_INDEX_ANY; 647190730Sthompsa } 648190730Sthompsa } 649190730Sthompsa pipe++; 650190730Sthompsa } 651190730Sthompsa 652190730Sthompsa if (err) 653190730Sthompsa return (err); 654190730Sthompsa } 655190730Sthompsa 656190730Sthompsa memset(&ips, 0, sizeof(ips)); 657190730Sthompsa 658190730Sthompsa ep_curr = 0; 659190730Sthompsa ep_max = 0; 660190730Sthompsa 661190730Sthompsa while ((id = usb2_idesc_foreach(udev->cdesc, &ips))) { 662190730Sthompsa 663190730Sthompsa /* check for interface overflow */ 664190730Sthompsa if (ips.iface_index == USB_IFACE_MAX) 665190730Sthompsa break; /* crazy */ 666190730Sthompsa 667190730Sthompsa iface = udev->ifaces + ips.iface_index; 668190730Sthompsa 669190730Sthompsa /* check for specific interface match */ 670190730Sthompsa 671190730Sthompsa if (cmd == USB_CFG_INIT) { 672190730Sthompsa if ((iface_index != USB_IFACE_INDEX_ANY) && 673190730Sthompsa (iface_index != ips.iface_index)) { 674190730Sthompsa /* wrong interface */ 675190730Sthompsa do_init = 0; 676190730Sthompsa } else if (alt_index != ips.iface_index_alt) { 677190730Sthompsa /* wrong alternate setting */ 678190730Sthompsa do_init = 0; 679190730Sthompsa } else { 680190730Sthompsa /* initialise interface */ 681190730Sthompsa do_init = 1; 682190730Sthompsa } 683190730Sthompsa } else 684190730Sthompsa do_init = 0; 685190730Sthompsa 686190730Sthompsa /* check for new interface */ 687190730Sthompsa if (ips.iface_index_alt == 0) { 688190730Sthompsa /* update current number of endpoints */ 689190730Sthompsa ep_curr = ep_max; 690190730Sthompsa } 691190730Sthompsa /* check for init */ 692190730Sthompsa if (do_init) { 693190730Sthompsa /* setup the USB interface structure */ 694190730Sthompsa iface->idesc = id; 695190730Sthompsa /* default setting */ 696190730Sthompsa iface->parent_iface_index = USB_IFACE_INDEX_ANY; 697190730Sthompsa /* set alternate index */ 698190730Sthompsa iface->alt_index = alt_index; 699190730Sthompsa } 700190730Sthompsa 701190730Sthompsa DPRINTFN(5, "found idesc nendpt=%d\n", id->bNumEndpoints); 702190730Sthompsa 703190730Sthompsa ed = (struct usb2_endpoint_descriptor *)id; 704190730Sthompsa 705190730Sthompsa temp = ep_curr; 706190730Sthompsa 707190730Sthompsa /* iterate all the endpoint descriptors */ 708190730Sthompsa while ((ed = usb2_edesc_foreach(udev->cdesc, ed))) { 709190730Sthompsa 710190730Sthompsa if (temp == USB_EP_MAX) 711190730Sthompsa break; /* crazy */ 712190730Sthompsa 713190730Sthompsa pipe = udev->pipes + temp; 714190730Sthompsa 715190730Sthompsa if (do_init) { 716190730Sthompsa usb2_init_pipe(udev, 717190730Sthompsa ips.iface_index, ed, pipe); 718190730Sthompsa } 719190730Sthompsa 720190730Sthompsa temp ++; 721190730Sthompsa 722190730Sthompsa /* find maximum number of endpoints */ 723190730Sthompsa if (ep_max < temp) 724190730Sthompsa ep_max = temp; 725190730Sthompsa 726190730Sthompsa /* optimalisation */ 727190730Sthompsa id = (struct usb2_interface_descriptor *)ed; 728190730Sthompsa } 729190730Sthompsa } 730190730Sthompsa 731190730Sthompsa /* NOTE: It is valid to have no interfaces and no endpoints! */ 732190730Sthompsa 733190730Sthompsa if (cmd == USB_CFG_ALLOC) { 734190730Sthompsa udev->ifaces_max = ips.iface_index; 735190730Sthompsa udev->ifaces = NULL; 736190730Sthompsa if (udev->ifaces_max != 0) { 737190730Sthompsa udev->ifaces = malloc(sizeof(*iface) * udev->ifaces_max, 738190730Sthompsa M_USB, M_WAITOK | M_ZERO); 739190730Sthompsa if (udev->ifaces == NULL) { 740190730Sthompsa err = USB_ERR_NOMEM; 741190730Sthompsa goto done; 742190730Sthompsa } 743190730Sthompsa } 744191398Sthompsa if (ep_max != 0) { 745191398Sthompsa udev->pipes = malloc(sizeof(*pipe) * ep_max, 746190730Sthompsa M_USB, M_WAITOK | M_ZERO); 747190730Sthompsa if (udev->pipes == NULL) { 748190730Sthompsa err = USB_ERR_NOMEM; 749190730Sthompsa goto done; 750190730Sthompsa } 751191398Sthompsa } else { 752191398Sthompsa udev->pipes = NULL; 753190730Sthompsa } 754191398Sthompsa USB_BUS_LOCK(udev->bus); 755191398Sthompsa udev->pipes_max = ep_max; 756191398Sthompsa /* reset any ongoing clear-stall */ 757191398Sthompsa udev->pipe_curr = NULL; 758191398Sthompsa USB_BUS_UNLOCK(udev->bus); 759190730Sthompsa } 760190730Sthompsa 761190730Sthompsadone: 762190730Sthompsa if (err) { 763190730Sthompsa if (cmd == USB_CFG_ALLOC) { 764190730Sthompsacleanup: 765191398Sthompsa USB_BUS_LOCK(udev->bus); 766191398Sthompsa udev->pipes_max = 0; 767191398Sthompsa /* reset any ongoing clear-stall */ 768191398Sthompsa udev->pipe_curr = NULL; 769191398Sthompsa USB_BUS_UNLOCK(udev->bus); 770191398Sthompsa 771190730Sthompsa /* cleanup */ 772190730Sthompsa if (udev->ifaces != NULL) 773190730Sthompsa free(udev->ifaces, M_USB); 774190730Sthompsa if (udev->pipes != NULL) 775190730Sthompsa free(udev->pipes, M_USB); 776190730Sthompsa 777190730Sthompsa udev->ifaces = NULL; 778190730Sthompsa udev->pipes = NULL; 779190730Sthompsa udev->ifaces_max = 0; 780190730Sthompsa } 781190730Sthompsa } 782190730Sthompsa return (err); 783190730Sthompsa} 784190730Sthompsa 785190730Sthompsa/*------------------------------------------------------------------------* 786184610Salfred * usb2_set_alt_interface_index 787184610Salfred * 788184610Salfred * This function will select an alternate interface index for the 789184610Salfred * given interface index. The interface should not be in use when this 790188986Sthompsa * function is called. That means there should not be any open USB 791188986Sthompsa * transfers. Else an error is returned. If the alternate setting is 792188986Sthompsa * already set this function will simply return success. This function 793188986Sthompsa * is called in Host mode and Device mode! 794184610Salfred * 795184610Salfred * Returns: 796184610Salfred * 0: Success 797184610Salfred * Else: Failure 798184610Salfred *------------------------------------------------------------------------*/ 799184610Salfredusb2_error_t 800184610Salfredusb2_set_alt_interface_index(struct usb2_device *udev, 801184610Salfred uint8_t iface_index, uint8_t alt_index) 802184610Salfred{ 803184610Salfred struct usb2_interface *iface = usb2_get_iface(udev, iface_index); 804184610Salfred usb2_error_t err; 805184610Salfred uint8_t do_unlock; 806184610Salfred 807184610Salfred /* automatic locking */ 808184610Salfred if (sx_xlocked(udev->default_sx + 1)) { 809184610Salfred do_unlock = 0; 810184610Salfred } else { 811184610Salfred do_unlock = 1; 812184610Salfred sx_xlock(udev->default_sx + 1); 813184610Salfred } 814184610Salfred if (iface == NULL) { 815184610Salfred err = USB_ERR_INVAL; 816184610Salfred goto done; 817184610Salfred } 818192499Sthompsa if (udev->flags.usb_mode == USB_MODE_DEVICE) { 819190730Sthompsa usb2_detach_device(udev, iface_index, 820190730Sthompsa USB_UNCFG_FLAG_FREE_SUBDEV); 821188986Sthompsa } else { 822188986Sthompsa if (iface->alt_index == alt_index) { 823188986Sthompsa /* 824188986Sthompsa * Optimise away duplicate setting of 825188986Sthompsa * alternate setting in USB Host Mode! 826188986Sthompsa */ 827188986Sthompsa err = 0; 828188986Sthompsa goto done; 829188986Sthompsa } 830184610Salfred } 831189599Sthompsa#if USB_HAVE_UGEN 832185087Salfred /* 833185087Salfred * Free all generic FIFOs for this interface, except control 834185087Salfred * endpoint FIFOs: 835185087Salfred */ 836184610Salfred usb2_fifo_free_wrap(udev, iface_index, 0); 837189599Sthompsa#endif 838190730Sthompsa 839190730Sthompsa err = usb2_config_parse(udev, iface_index, alt_index); 840184610Salfred if (err) { 841184610Salfred goto done; 842184610Salfred } 843188986Sthompsa err = usb2_req_set_alt_interface_no(udev, NULL, iface_index, 844184610Salfred iface->idesc->bAlternateSetting); 845184610Salfred 846184610Salfreddone: 847184610Salfred if (do_unlock) { 848184610Salfred sx_unlock(udev->default_sx + 1); 849184610Salfred } 850184610Salfred return (err); 851184610Salfred} 852184610Salfred 853184610Salfred/*------------------------------------------------------------------------* 854184610Salfred * usb2_set_endpoint_stall 855184610Salfred * 856184610Salfred * This function is used to make a BULK or INTERRUPT endpoint 857184610Salfred * send STALL tokens. 858184610Salfred * 859184610Salfred * Returns: 860184610Salfred * 0: Success 861184610Salfred * Else: Failure 862184610Salfred *------------------------------------------------------------------------*/ 863184610Salfredusb2_error_t 864184610Salfredusb2_set_endpoint_stall(struct usb2_device *udev, struct usb2_pipe *pipe, 865184610Salfred uint8_t do_stall) 866184610Salfred{ 867184610Salfred struct usb2_xfer *xfer; 868184610Salfred uint8_t et; 869184610Salfred uint8_t was_stalled; 870184610Salfred 871184610Salfred if (pipe == NULL) { 872184610Salfred /* nothing to do */ 873184610Salfred DPRINTF("Cannot find endpoint\n"); 874184610Salfred /* 875184610Salfred * Pretend that the clear or set stall request is 876184610Salfred * successful else some USB host stacks can do 877184610Salfred * strange things, especially when a control endpoint 878184610Salfred * stalls. 879184610Salfred */ 880184610Salfred return (0); 881184610Salfred } 882184610Salfred et = (pipe->edesc->bmAttributes & UE_XFERTYPE); 883184610Salfred 884184610Salfred if ((et != UE_BULK) && 885184610Salfred (et != UE_INTERRUPT)) { 886184610Salfred /* 887184610Salfred * Should not stall control 888184610Salfred * nor isochronous endpoints. 889184610Salfred */ 890184610Salfred DPRINTF("Invalid endpoint\n"); 891184610Salfred return (0); 892184610Salfred } 893184824Sthompsa USB_BUS_LOCK(udev->bus); 894184610Salfred 895184610Salfred /* store current stall state */ 896184610Salfred was_stalled = pipe->is_stalled; 897184610Salfred 898184610Salfred /* check for no change */ 899184610Salfred if (was_stalled && do_stall) { 900184610Salfred /* if the pipe is already stalled do nothing */ 901184824Sthompsa USB_BUS_UNLOCK(udev->bus); 902184610Salfred DPRINTF("No change\n"); 903184610Salfred return (0); 904184610Salfred } 905184610Salfred /* set stalled state */ 906184610Salfred pipe->is_stalled = 1; 907184610Salfred 908184610Salfred if (do_stall || (!was_stalled)) { 909184610Salfred if (!was_stalled) { 910184610Salfred /* lookup the current USB transfer, if any */ 911184610Salfred xfer = pipe->pipe_q.curr; 912184610Salfred } else { 913184610Salfred xfer = NULL; 914184610Salfred } 915184610Salfred 916184610Salfred /* 917184610Salfred * If "xfer" is non-NULL the "set_stall" method will 918184610Salfred * complete the USB transfer like in case of a timeout 919184610Salfred * setting the error code "USB_ERR_STALLED". 920184610Salfred */ 921184610Salfred (udev->bus->methods->set_stall) (udev, xfer, pipe); 922184610Salfred } 923184610Salfred if (!do_stall) { 924184610Salfred pipe->toggle_next = 0; /* reset data toggle */ 925184610Salfred pipe->is_stalled = 0; /* clear stalled state */ 926184610Salfred 927184610Salfred (udev->bus->methods->clear_stall) (udev, pipe); 928184610Salfred 929184610Salfred /* start up the current or next transfer, if any */ 930184610Salfred usb2_command_wrapper(&pipe->pipe_q, pipe->pipe_q.curr); 931184610Salfred } 932184824Sthompsa USB_BUS_UNLOCK(udev->bus); 933184610Salfred return (0); 934184610Salfred} 935184610Salfred 936184610Salfred/*------------------------------------------------------------------------* 937184610Salfred * usb2_reset_iface_endpoints - used in USB device side mode 938184610Salfred *------------------------------------------------------------------------*/ 939184610Salfredusb2_error_t 940184610Salfredusb2_reset_iface_endpoints(struct usb2_device *udev, uint8_t iface_index) 941184610Salfred{ 942184610Salfred struct usb2_pipe *pipe; 943184610Salfred struct usb2_pipe *pipe_end; 944184610Salfred usb2_error_t err; 945184610Salfred 946184610Salfred pipe = udev->pipes; 947190731Sthompsa pipe_end = udev->pipes + udev->pipes_max; 948184610Salfred 949184610Salfred for (; pipe != pipe_end; pipe++) { 950184610Salfred 951184610Salfred if ((pipe->edesc == NULL) || 952184610Salfred (pipe->iface_index != iface_index)) { 953184610Salfred continue; 954184610Salfred } 955184610Salfred /* simulate a clear stall from the peer */ 956184610Salfred err = usb2_set_endpoint_stall(udev, pipe, 0); 957184610Salfred if (err) { 958184610Salfred /* just ignore */ 959184610Salfred } 960184610Salfred } 961184610Salfred return (0); 962184610Salfred} 963184610Salfred 964184610Salfred/*------------------------------------------------------------------------* 965184610Salfred * usb2_detach_device_sub 966184610Salfred * 967184610Salfred * This function will try to detach an USB device. If it fails a panic 968184610Salfred * will result. 969190730Sthompsa * 970190730Sthompsa * Flag values, see "USB_UNCFG_FLAG_XXX". 971184610Salfred *------------------------------------------------------------------------*/ 972184610Salfredstatic void 973184610Salfredusb2_detach_device_sub(struct usb2_device *udev, device_t *ppdev, 974190730Sthompsa uint8_t flag) 975184610Salfred{ 976184610Salfred device_t dev; 977184610Salfred int err; 978184610Salfred 979190730Sthompsa if (!(flag & USB_UNCFG_FLAG_FREE_SUBDEV)) { 980184610Salfred 981184610Salfred *ppdev = NULL; 982184610Salfred 983184610Salfred } else if (*ppdev) { 984184610Salfred 985184610Salfred /* 986184610Salfred * NOTE: It is important to clear "*ppdev" before deleting 987184610Salfred * the child due to some device methods being called late 988184610Salfred * during the delete process ! 989184610Salfred */ 990184610Salfred dev = *ppdev; 991184610Salfred *ppdev = NULL; 992184610Salfred 993184610Salfred device_printf(dev, "at %s, port %d, addr %d " 994184610Salfred "(disconnected)\n", 995184610Salfred device_get_nameunit(udev->parent_dev), 996184610Salfred udev->port_no, udev->address); 997184610Salfred 998184610Salfred if (device_is_attached(dev)) { 999191824Sthompsa if (udev->flags.peer_suspended) { 1000184610Salfred err = DEVICE_RESUME(dev); 1001184610Salfred if (err) { 1002184610Salfred device_printf(dev, "Resume failed!\n"); 1003184610Salfred } 1004184610Salfred } 1005184610Salfred if (device_detach(dev)) { 1006184610Salfred goto error; 1007184610Salfred } 1008184610Salfred } 1009184610Salfred if (device_delete_child(udev->parent_dev, dev)) { 1010184610Salfred goto error; 1011184610Salfred } 1012184610Salfred } 1013184610Salfred return; 1014184610Salfred 1015184610Salfrederror: 1016184610Salfred /* Detach is not allowed to fail in the USB world */ 1017184610Salfred panic("An USB driver would not detach!\n"); 1018184610Salfred} 1019184610Salfred 1020184610Salfred/*------------------------------------------------------------------------* 1021184610Salfred * usb2_detach_device 1022184610Salfred * 1023184610Salfred * The following function will detach the matching interfaces. 1024184610Salfred * This function is NULL safe. 1025190730Sthompsa * 1026190730Sthompsa * Flag values, see "USB_UNCFG_FLAG_XXX". 1027184610Salfred *------------------------------------------------------------------------*/ 1028184610Salfredvoid 1029184610Salfredusb2_detach_device(struct usb2_device *udev, uint8_t iface_index, 1030190730Sthompsa uint8_t flag) 1031184610Salfred{ 1032184610Salfred struct usb2_interface *iface; 1033184610Salfred uint8_t i; 1034184610Salfred 1035184610Salfred if (udev == NULL) { 1036184610Salfred /* nothing to do */ 1037184610Salfred return; 1038184610Salfred } 1039184610Salfred DPRINTFN(4, "udev=%p\n", udev); 1040184610Salfred 1041190730Sthompsa sx_assert(udev->default_sx + 1, SA_LOCKED); 1042184610Salfred 1043184610Salfred /* 1044184610Salfred * First detach the child to give the child's detach routine a 1045184610Salfred * chance to detach the sub-devices in the correct order. 1046184610Salfred * Then delete the child using "device_delete_child()" which 1047184610Salfred * will detach all sub-devices from the bottom and upwards! 1048184610Salfred */ 1049184610Salfred if (iface_index != USB_IFACE_INDEX_ANY) { 1050184610Salfred i = iface_index; 1051184610Salfred iface_index = i + 1; 1052184610Salfred } else { 1053184610Salfred i = 0; 1054184610Salfred iface_index = USB_IFACE_MAX; 1055184610Salfred } 1056184610Salfred 1057184610Salfred /* do the detach */ 1058184610Salfred 1059184610Salfred for (; i != iface_index; i++) { 1060184610Salfred 1061184610Salfred iface = usb2_get_iface(udev, i); 1062184610Salfred if (iface == NULL) { 1063184610Salfred /* looks like the end of the USB interfaces */ 1064184610Salfred break; 1065184610Salfred } 1066190730Sthompsa usb2_detach_device_sub(udev, &iface->subdev, flag); 1067184610Salfred } 1068184610Salfred} 1069184610Salfred 1070184610Salfred/*------------------------------------------------------------------------* 1071184610Salfred * usb2_probe_and_attach_sub 1072184610Salfred * 1073184610Salfred * Returns: 1074184610Salfred * 0: Success 1075184610Salfred * Else: Failure 1076184610Salfred *------------------------------------------------------------------------*/ 1077184610Salfredstatic uint8_t 1078184610Salfredusb2_probe_and_attach_sub(struct usb2_device *udev, 1079184610Salfred struct usb2_attach_arg *uaa) 1080184610Salfred{ 1081184610Salfred struct usb2_interface *iface; 1082184610Salfred device_t dev; 1083184610Salfred int err; 1084184610Salfred 1085184610Salfred iface = uaa->iface; 1086184610Salfred if (iface->parent_iface_index != USB_IFACE_INDEX_ANY) { 1087184610Salfred /* leave interface alone */ 1088184610Salfred return (0); 1089184610Salfred } 1090184610Salfred dev = iface->subdev; 1091184610Salfred if (dev) { 1092184610Salfred 1093184610Salfred /* clean up after module unload */ 1094184610Salfred 1095184610Salfred if (device_is_attached(dev)) { 1096184610Salfred /* already a device there */ 1097184610Salfred return (0); 1098184610Salfred } 1099184610Salfred /* clear "iface->subdev" as early as possible */ 1100184610Salfred 1101184610Salfred iface->subdev = NULL; 1102184610Salfred 1103184610Salfred if (device_delete_child(udev->parent_dev, dev)) { 1104184610Salfred 1105184610Salfred /* 1106184610Salfred * Panic here, else one can get a double call 1107184610Salfred * to device_detach(). USB devices should 1108184610Salfred * never fail on detach! 1109184610Salfred */ 1110184610Salfred panic("device_delete_child() failed!\n"); 1111184610Salfred } 1112184610Salfred } 1113184610Salfred if (uaa->temp_dev == NULL) { 1114184610Salfred 1115184610Salfred /* create a new child */ 1116184610Salfred uaa->temp_dev = device_add_child(udev->parent_dev, NULL, -1); 1117184610Salfred if (uaa->temp_dev == NULL) { 1118184610Salfred device_printf(udev->parent_dev, 1119184610Salfred "Device creation failed!\n"); 1120184610Salfred return (1); /* failure */ 1121184610Salfred } 1122184610Salfred device_set_ivars(uaa->temp_dev, uaa); 1123184610Salfred device_quiet(uaa->temp_dev); 1124184610Salfred } 1125184610Salfred /* 1126184610Salfred * Set "subdev" before probe and attach so that "devd" gets 1127184610Salfred * the information it needs. 1128184610Salfred */ 1129184610Salfred iface->subdev = uaa->temp_dev; 1130184610Salfred 1131184610Salfred if (device_probe_and_attach(iface->subdev) == 0) { 1132184610Salfred /* 1133184610Salfred * The USB attach arguments are only available during probe 1134184610Salfred * and attach ! 1135184610Salfred */ 1136184610Salfred uaa->temp_dev = NULL; 1137184610Salfred device_set_ivars(iface->subdev, NULL); 1138184610Salfred 1139191824Sthompsa if (udev->flags.peer_suspended) { 1140184610Salfred err = DEVICE_SUSPEND(iface->subdev); 1141191397Sthompsa if (err) 1142191397Sthompsa device_printf(iface->subdev, "Suspend failed\n"); 1143184610Salfred } 1144184610Salfred return (0); /* success */ 1145184610Salfred } else { 1146184610Salfred /* No USB driver found */ 1147184610Salfred iface->subdev = NULL; 1148184610Salfred } 1149184610Salfred return (1); /* failure */ 1150184610Salfred} 1151184610Salfred 1152184610Salfred/*------------------------------------------------------------------------* 1153184610Salfred * usb2_set_parent_iface 1154184610Salfred * 1155184610Salfred * Using this function will lock the alternate interface setting on an 1156184610Salfred * interface. It is typically used for multi interface drivers. In USB 1157184610Salfred * device side mode it is assumed that the alternate interfaces all 1158184610Salfred * have the same endpoint descriptors. The default parent index value 1159184610Salfred * is "USB_IFACE_INDEX_ANY". Then the alternate setting value is not 1160184610Salfred * locked. 1161184610Salfred *------------------------------------------------------------------------*/ 1162184610Salfredvoid 1163184610Salfredusb2_set_parent_iface(struct usb2_device *udev, uint8_t iface_index, 1164184610Salfred uint8_t parent_index) 1165184610Salfred{ 1166184610Salfred struct usb2_interface *iface; 1167184610Salfred 1168184610Salfred iface = usb2_get_iface(udev, iface_index); 1169184610Salfred if (iface) { 1170184610Salfred iface->parent_iface_index = parent_index; 1171184610Salfred } 1172184610Salfred} 1173184610Salfred 1174184610Salfredstatic void 1175184610Salfredusb2_init_attach_arg(struct usb2_device *udev, 1176184610Salfred struct usb2_attach_arg *uaa) 1177184610Salfred{ 1178184610Salfred bzero(uaa, sizeof(*uaa)); 1179184610Salfred 1180184610Salfred uaa->device = udev; 1181192499Sthompsa uaa->usb_mode = udev->flags.usb_mode; 1182184610Salfred uaa->port = udev->port_no; 1183184610Salfred 1184184610Salfred uaa->info.idVendor = UGETW(udev->ddesc.idVendor); 1185184610Salfred uaa->info.idProduct = UGETW(udev->ddesc.idProduct); 1186184610Salfred uaa->info.bcdDevice = UGETW(udev->ddesc.bcdDevice); 1187184610Salfred uaa->info.bDeviceClass = udev->ddesc.bDeviceClass; 1188184610Salfred uaa->info.bDeviceSubClass = udev->ddesc.bDeviceSubClass; 1189184610Salfred uaa->info.bDeviceProtocol = udev->ddesc.bDeviceProtocol; 1190184610Salfred uaa->info.bConfigIndex = udev->curr_config_index; 1191184610Salfred uaa->info.bConfigNum = udev->curr_config_no; 1192184610Salfred} 1193184610Salfred 1194184610Salfred/*------------------------------------------------------------------------* 1195184610Salfred * usb2_probe_and_attach 1196184610Salfred * 1197184610Salfred * This function is called from "uhub_explore_sub()", 1198184610Salfred * "usb2_handle_set_config()" and "usb2_handle_request()". 1199184610Salfred * 1200184610Salfred * Returns: 1201184610Salfred * 0: Success 1202184610Salfred * Else: A control transfer failed 1203184610Salfred *------------------------------------------------------------------------*/ 1204184610Salfredusb2_error_t 1205184610Salfredusb2_probe_and_attach(struct usb2_device *udev, uint8_t iface_index) 1206184610Salfred{ 1207184610Salfred struct usb2_attach_arg uaa; 1208184610Salfred struct usb2_interface *iface; 1209184610Salfred uint8_t i; 1210184610Salfred uint8_t j; 1211184610Salfred uint8_t do_unlock; 1212184610Salfred 1213184610Salfred if (udev == NULL) { 1214184610Salfred DPRINTF("udev == NULL\n"); 1215184610Salfred return (USB_ERR_INVAL); 1216184610Salfred } 1217184610Salfred /* automatic locking */ 1218184610Salfred if (sx_xlocked(udev->default_sx + 1)) { 1219184610Salfred do_unlock = 0; 1220184610Salfred } else { 1221184610Salfred do_unlock = 1; 1222184610Salfred sx_xlock(udev->default_sx + 1); 1223184610Salfred } 1224184610Salfred 1225184610Salfred if (udev->curr_config_index == USB_UNCONFIG_INDEX) { 1226184610Salfred /* do nothing - no configuration has been set */ 1227184610Salfred goto done; 1228184610Salfred } 1229184610Salfred /* setup USB attach arguments */ 1230184610Salfred 1231184610Salfred usb2_init_attach_arg(udev, &uaa); 1232184610Salfred 1233184610Salfred /* Check if only one interface should be probed: */ 1234184610Salfred if (iface_index != USB_IFACE_INDEX_ANY) { 1235184610Salfred i = iface_index; 1236184610Salfred j = i + 1; 1237184610Salfred } else { 1238184610Salfred i = 0; 1239184610Salfred j = USB_IFACE_MAX; 1240184610Salfred } 1241184610Salfred 1242184610Salfred /* Do the probe and attach */ 1243184610Salfred for (; i != j; i++) { 1244184610Salfred 1245184610Salfred iface = usb2_get_iface(udev, i); 1246184610Salfred if (iface == NULL) { 1247184610Salfred /* 1248184610Salfred * Looks like the end of the USB 1249184610Salfred * interfaces ! 1250184610Salfred */ 1251184610Salfred DPRINTFN(2, "end of interfaces " 1252184610Salfred "at %u\n", i); 1253184610Salfred break; 1254184610Salfred } 1255184610Salfred if (iface->idesc == NULL) { 1256184610Salfred /* no interface descriptor */ 1257184610Salfred continue; 1258184610Salfred } 1259184610Salfred uaa.iface = iface; 1260184610Salfred 1261184610Salfred uaa.info.bInterfaceClass = 1262184610Salfred iface->idesc->bInterfaceClass; 1263184610Salfred uaa.info.bInterfaceSubClass = 1264184610Salfred iface->idesc->bInterfaceSubClass; 1265184610Salfred uaa.info.bInterfaceProtocol = 1266184610Salfred iface->idesc->bInterfaceProtocol; 1267184610Salfred uaa.info.bIfaceIndex = i; 1268184610Salfred uaa.info.bIfaceNum = 1269184610Salfred iface->idesc->bInterfaceNumber; 1270184610Salfred uaa.use_generic = 0; 1271184610Salfred 1272184610Salfred DPRINTFN(2, "iclass=%u/%u/%u iindex=%u/%u\n", 1273184610Salfred uaa.info.bInterfaceClass, 1274184610Salfred uaa.info.bInterfaceSubClass, 1275184610Salfred uaa.info.bInterfaceProtocol, 1276184610Salfred uaa.info.bIfaceIndex, 1277184610Salfred uaa.info.bIfaceNum); 1278184610Salfred 1279184610Salfred /* try specific interface drivers first */ 1280184610Salfred 1281184610Salfred if (usb2_probe_and_attach_sub(udev, &uaa)) { 1282184610Salfred /* ignore */ 1283184610Salfred } 1284184610Salfred /* try generic interface drivers last */ 1285184610Salfred 1286184610Salfred uaa.use_generic = 1; 1287184610Salfred 1288184610Salfred if (usb2_probe_and_attach_sub(udev, &uaa)) { 1289184610Salfred /* ignore */ 1290184610Salfred } 1291184610Salfred } 1292184610Salfred 1293184610Salfred if (uaa.temp_dev) { 1294184610Salfred /* remove the last created child; it is unused */ 1295184610Salfred 1296184610Salfred if (device_delete_child(udev->parent_dev, uaa.temp_dev)) { 1297184610Salfred DPRINTFN(0, "device delete child failed!\n"); 1298184610Salfred } 1299184610Salfred } 1300184610Salfreddone: 1301184610Salfred if (do_unlock) { 1302184610Salfred sx_unlock(udev->default_sx + 1); 1303184610Salfred } 1304184610Salfred return (0); 1305184610Salfred} 1306184610Salfred 1307184610Salfred/*------------------------------------------------------------------------* 1308184610Salfred * usb2_suspend_resume_sub 1309184610Salfred * 1310184610Salfred * This function is called when the suspend or resume methods should 1311184610Salfred * be executed on an USB device. 1312184610Salfred *------------------------------------------------------------------------*/ 1313184610Salfredstatic void 1314184610Salfredusb2_suspend_resume_sub(struct usb2_device *udev, device_t dev, uint8_t do_suspend) 1315184610Salfred{ 1316184610Salfred int err; 1317184610Salfred 1318184610Salfred if (dev == NULL) { 1319184610Salfred return; 1320184610Salfred } 1321184610Salfred if (!device_is_attached(dev)) { 1322184610Salfred return; 1323184610Salfred } 1324184610Salfred if (do_suspend) { 1325184610Salfred err = DEVICE_SUSPEND(dev); 1326184610Salfred } else { 1327184610Salfred err = DEVICE_RESUME(dev); 1328184610Salfred } 1329184610Salfred if (err) { 1330184610Salfred device_printf(dev, "%s failed!\n", 1331184610Salfred do_suspend ? "Suspend" : "Resume"); 1332184610Salfred } 1333184610Salfred} 1334184610Salfred 1335184610Salfred/*------------------------------------------------------------------------* 1336186730Salfred * usb2_suspend_resume 1337184610Salfred * 1338184610Salfred * The following function will suspend or resume the USB device. 1339184610Salfred * 1340184610Salfred * Returns: 1341184610Salfred * 0: Success 1342184610Salfred * Else: Failure 1343184610Salfred *------------------------------------------------------------------------*/ 1344184610Salfredusb2_error_t 1345184610Salfredusb2_suspend_resume(struct usb2_device *udev, uint8_t do_suspend) 1346184610Salfred{ 1347184610Salfred struct usb2_interface *iface; 1348184610Salfred uint8_t i; 1349184610Salfred 1350184610Salfred if (udev == NULL) { 1351184610Salfred /* nothing to do */ 1352184610Salfred return (0); 1353184610Salfred } 1354184610Salfred DPRINTFN(4, "udev=%p do_suspend=%d\n", udev, do_suspend); 1355184610Salfred 1356184610Salfred sx_assert(udev->default_sx + 1, SA_LOCKED); 1357184610Salfred 1358184824Sthompsa USB_BUS_LOCK(udev->bus); 1359184610Salfred /* filter the suspend events */ 1360191824Sthompsa if (udev->flags.peer_suspended == do_suspend) { 1361184824Sthompsa USB_BUS_UNLOCK(udev->bus); 1362184610Salfred /* nothing to do */ 1363184610Salfred return (0); 1364184610Salfred } 1365191824Sthompsa udev->flags.peer_suspended = do_suspend; 1366184824Sthompsa USB_BUS_UNLOCK(udev->bus); 1367184610Salfred 1368184610Salfred /* do the suspend or resume */ 1369184610Salfred 1370184610Salfred for (i = 0; i != USB_IFACE_MAX; i++) { 1371184610Salfred 1372184610Salfred iface = usb2_get_iface(udev, i); 1373184610Salfred if (iface == NULL) { 1374184610Salfred /* looks like the end of the USB interfaces */ 1375184610Salfred break; 1376184610Salfred } 1377184610Salfred usb2_suspend_resume_sub(udev, iface->subdev, do_suspend); 1378184610Salfred } 1379184610Salfred return (0); 1380184610Salfred} 1381184610Salfred 1382184610Salfred/*------------------------------------------------------------------------* 1383184610Salfred * usb2_clear_stall_proc 1384184610Salfred * 1385184610Salfred * This function performs generic USB clear stall operations. 1386184610Salfred *------------------------------------------------------------------------*/ 1387184610Salfredstatic void 1388184610Salfredusb2_clear_stall_proc(struct usb2_proc_msg *_pm) 1389184610Salfred{ 1390184610Salfred struct usb2_clear_stall_msg *pm = (void *)_pm; 1391184610Salfred struct usb2_device *udev = pm->udev; 1392184610Salfred 1393184610Salfred /* Change lock */ 1394184824Sthompsa USB_BUS_UNLOCK(udev->bus); 1395184610Salfred mtx_lock(udev->default_mtx); 1396184610Salfred 1397184610Salfred /* Start clear stall callback */ 1398184610Salfred usb2_transfer_start(udev->default_xfer[1]); 1399184610Salfred 1400184610Salfred /* Change lock */ 1401184610Salfred mtx_unlock(udev->default_mtx); 1402184824Sthompsa USB_BUS_LOCK(udev->bus); 1403184610Salfred} 1404184610Salfred 1405184610Salfred/*------------------------------------------------------------------------* 1406184610Salfred * usb2_alloc_device 1407184610Salfred * 1408184610Salfred * This function allocates a new USB device. This function is called 1409184610Salfred * when a new device has been put in the powered state, but not yet in 1410184610Salfred * the addressed state. Get initial descriptor, set the address, get 1411184610Salfred * full descriptor and get strings. 1412184610Salfred * 1413184610Salfred * Return values: 1414184610Salfred * 0: Failure 1415184610Salfred * Else: Success 1416184610Salfred *------------------------------------------------------------------------*/ 1417184610Salfredstruct usb2_device * 1418184610Salfredusb2_alloc_device(device_t parent_dev, struct usb2_bus *bus, 1419192499Sthompsa struct usb2_device *parent_hub, uint8_t depth, uint8_t port_index, 1420192500Sthompsa uint8_t port_no, enum usb_dev_speed speed, enum usb_hc_mode mode) 1421184610Salfred{ 1422184610Salfred struct usb2_attach_arg uaa; 1423184610Salfred struct usb2_device *udev; 1424184610Salfred struct usb2_device *adev; 1425184610Salfred struct usb2_device *hub; 1426184610Salfred uint8_t *scratch_ptr; 1427184610Salfred uint32_t scratch_size; 1428184610Salfred usb2_error_t err; 1429184610Salfred uint8_t device_index; 1430184610Salfred 1431184610Salfred DPRINTF("parent_dev=%p, bus=%p, parent_hub=%p, depth=%u, " 1432192499Sthompsa "port_index=%u, port_no=%u, speed=%u, usb_mode=%u\n", 1433184610Salfred parent_dev, bus, parent_hub, depth, port_index, port_no, 1434192499Sthompsa speed, mode); 1435184610Salfred 1436184610Salfred /* 1437184610Salfred * Find an unused device index. In USB Host mode this is the 1438184610Salfred * same as the device address. 1439184610Salfred * 1440187170Sthompsa * Device index zero is not used and device index 1 should 1441187170Sthompsa * always be the root hub. 1442184610Salfred */ 1443187171Sthompsa for (device_index = USB_ROOT_HUB_ADDR; 1444187171Sthompsa (device_index != bus->devices_max) && 1445187171Sthompsa (bus->devices[device_index] != NULL); 1446187171Sthompsa device_index++) /* nop */; 1447187171Sthompsa 1448187171Sthompsa if (device_index == bus->devices_max) { 1449187171Sthompsa device_printf(bus->bdev, 1450187171Sthompsa "No free USB device index for new device!\n"); 1451187171Sthompsa return (NULL); 1452184610Salfred } 1453184610Salfred 1454184610Salfred if (depth > 0x10) { 1455184610Salfred device_printf(bus->bdev, 1456184610Salfred "Invalid device depth!\n"); 1457184610Salfred return (NULL); 1458184610Salfred } 1459184610Salfred udev = malloc(sizeof(*udev), M_USB, M_WAITOK | M_ZERO); 1460184610Salfred if (udev == NULL) { 1461184610Salfred return (NULL); 1462184610Salfred } 1463184610Salfred /* initialise our SX-lock */ 1464184610Salfred sx_init(udev->default_sx, "0123456789ABCDEF - USB device SX lock" + depth); 1465184610Salfred 1466184610Salfred /* initialise our SX-lock */ 1467184610Salfred sx_init(udev->default_sx + 1, "0123456789ABCDEF - USB config SX lock" + depth); 1468184610Salfred 1469184610Salfred usb2_cv_init(udev->default_cv, "WCTRL"); 1470184610Salfred usb2_cv_init(udev->default_cv + 1, "UGONE"); 1471184610Salfred 1472184610Salfred /* initialise our mutex */ 1473184610Salfred mtx_init(udev->default_mtx, "USB device mutex", NULL, MTX_DEF); 1474184610Salfred 1475184610Salfred /* initialise generic clear stall */ 1476184610Salfred udev->cs_msg[0].hdr.pm_callback = &usb2_clear_stall_proc; 1477184610Salfred udev->cs_msg[0].udev = udev; 1478184610Salfred udev->cs_msg[1].hdr.pm_callback = &usb2_clear_stall_proc; 1479184610Salfred udev->cs_msg[1].udev = udev; 1480184610Salfred 1481184610Salfred /* initialise some USB device fields */ 1482184610Salfred udev->parent_hub = parent_hub; 1483184610Salfred udev->parent_dev = parent_dev; 1484184610Salfred udev->port_index = port_index; 1485184610Salfred udev->port_no = port_no; 1486184610Salfred udev->depth = depth; 1487184610Salfred udev->bus = bus; 1488184610Salfred udev->address = USB_START_ADDR; /* default value */ 1489190181Sthompsa udev->plugtime = (usb2_ticks_t)ticks; 1490191494Sthompsa usb2_set_device_state(udev, USB_STATE_POWERED); 1491186730Salfred /* 1492186730Salfred * We need to force the power mode to "on" because there are plenty 1493186730Salfred * of USB devices out there that do not work very well with 1494186730Salfred * automatic suspend and resume! 1495186730Salfred */ 1496184610Salfred udev->power_mode = USB_POWER_MODE_ON; 1497186730Salfred udev->pwr_save.last_xfer_time = ticks; 1498184610Salfred /* we are not ready yet */ 1499184610Salfred udev->refcount = 1; 1500184610Salfred 1501184610Salfred /* set up default endpoint descriptor */ 1502184610Salfred udev->default_ep_desc.bLength = sizeof(udev->default_ep_desc); 1503184610Salfred udev->default_ep_desc.bDescriptorType = UDESC_ENDPOINT; 1504184610Salfred udev->default_ep_desc.bEndpointAddress = USB_CONTROL_ENDPOINT; 1505184610Salfred udev->default_ep_desc.bmAttributes = UE_CONTROL; 1506184610Salfred udev->default_ep_desc.wMaxPacketSize[0] = USB_MAX_IPACKET; 1507184610Salfred udev->default_ep_desc.wMaxPacketSize[1] = 0; 1508184610Salfred udev->default_ep_desc.bInterval = 0; 1509184610Salfred udev->ddesc.bMaxPacketSize = USB_MAX_IPACKET; 1510184610Salfred 1511184610Salfred udev->speed = speed; 1512192499Sthompsa udev->flags.usb_mode = mode; 1513184610Salfred 1514184610Salfred /* search for our High Speed USB HUB, if any */ 1515184610Salfred 1516184610Salfred adev = udev; 1517184610Salfred hub = udev->parent_hub; 1518184610Salfred 1519184610Salfred while (hub) { 1520184610Salfred if (hub->speed == USB_SPEED_HIGH) { 1521184610Salfred udev->hs_hub_addr = hub->address; 1522191395Sthompsa udev->parent_hs_hub = hub; 1523184610Salfred udev->hs_port_no = adev->port_no; 1524184610Salfred break; 1525184610Salfred } 1526184610Salfred adev = hub; 1527184610Salfred hub = hub->parent_hub; 1528184610Salfred } 1529184610Salfred 1530184610Salfred /* init the default pipe */ 1531190730Sthompsa usb2_init_pipe(udev, 0, 1532184610Salfred &udev->default_ep_desc, 1533184610Salfred &udev->default_pipe); 1534184610Salfred 1535184610Salfred /* set device index */ 1536184610Salfred udev->device_index = device_index; 1537184610Salfred 1538190191Sthompsa#if USB_HAVE_UGEN 1539189599Sthompsa /* Create ugen name */ 1540189599Sthompsa snprintf(udev->ugen_name, sizeof(udev->ugen_name), 1541189599Sthompsa USB_GENERIC_NAME "%u.%u", device_get_unit(bus->bdev), 1542189599Sthompsa device_index); 1543190191Sthompsa LIST_INIT(&udev->pd_list); 1544190191Sthompsa 1545189110Sthompsa /* Create the control endpoint device */ 1546189172Sthompsa udev->default_dev = usb2_make_dev(udev, 0, FREAD|FWRITE); 1547189599Sthompsa 1548189110Sthompsa /* Create a link from /dev/ugenX.X to the default endpoint */ 1549189110Sthompsa make_dev_alias(udev->default_dev, udev->ugen_name); 1550189599Sthompsa#endif 1551192499Sthompsa if (udev->flags.usb_mode == USB_MODE_HOST) { 1552184610Salfred 1553188986Sthompsa err = usb2_req_set_address(udev, NULL, device_index); 1554184610Salfred 1555184610Salfred /* This is the new USB device address from now on */ 1556184610Salfred 1557184610Salfred udev->address = device_index; 1558184610Salfred 1559184610Salfred /* 1560184610Salfred * We ignore any set-address errors, hence there are 1561184610Salfred * buggy USB devices out there that actually receive 1562184610Salfred * the SETUP PID, but manage to set the address before 1563184610Salfred * the STATUS stage is ACK'ed. If the device responds 1564184610Salfred * to the subsequent get-descriptor at the new 1565184610Salfred * address, then we know that the set-address command 1566184610Salfred * was successful. 1567184610Salfred */ 1568184610Salfred if (err) { 1569184610Salfred DPRINTFN(0, "set address %d failed " 1570190739Sthompsa "(%s, ignored)\n", udev->address, 1571190739Sthompsa usb2_errstr(err)); 1572184610Salfred } 1573184610Salfred /* allow device time to set new address */ 1574188986Sthompsa usb2_pause_mtx(NULL, 1575188411Sthompsa USB_MS_TO_TICKS(USB_SET_ADDRESS_SETTLE)); 1576184610Salfred } else { 1577184610Salfred /* We are not self powered */ 1578184610Salfred udev->flags.self_powered = 0; 1579184610Salfred 1580184610Salfred /* Set unconfigured state */ 1581184610Salfred udev->curr_config_no = USB_UNCONFIG_NO; 1582184610Salfred udev->curr_config_index = USB_UNCONFIG_INDEX; 1583184610Salfred 1584184610Salfred /* Setup USB descriptors */ 1585184610Salfred err = (usb2_temp_setup_by_index_p) (udev, usb2_template); 1586184610Salfred if (err) { 1587184610Salfred DPRINTFN(0, "setting up USB template failed maybe the USB " 1588184610Salfred "template module has not been loaded\n"); 1589184610Salfred goto done; 1590184610Salfred } 1591184610Salfred } 1592191494Sthompsa usb2_set_device_state(udev, USB_STATE_ADDRESSED); 1593184610Salfred 1594184610Salfred /* 1595184610Salfred * Get the first 8 bytes of the device descriptor ! 1596184610Salfred * 1597184610Salfred * NOTE: "usb2_do_request" will check the device descriptor 1598184610Salfred * next time we do a request to see if the maximum packet size 1599184610Salfred * changed! The 8 first bytes of the device descriptor 1600184610Salfred * contains the maximum packet size to use on control endpoint 1601184610Salfred * 0. If this value is different from "USB_MAX_IPACKET" a new 1602184610Salfred * USB control request will be setup! 1603184610Salfred */ 1604188986Sthompsa err = usb2_req_get_desc(udev, NULL, NULL, &udev->ddesc, 1605184610Salfred USB_MAX_IPACKET, USB_MAX_IPACKET, 0, UDESC_DEVICE, 0, 0); 1606184610Salfred if (err) { 1607184610Salfred DPRINTFN(0, "getting device descriptor " 1608190739Sthompsa "at addr %d failed, %s!\n", udev->address, 1609190739Sthompsa usb2_errstr(err)); 1610186730Salfred /* XXX try to re-enumerate the device */ 1611188986Sthompsa err = usb2_req_re_enumerate(udev, NULL); 1612186730Salfred if (err) { 1613186730Salfred goto done; 1614186730Salfred } 1615184610Salfred } 1616184610Salfred DPRINTF("adding unit addr=%d, rev=%02x, class=%d, " 1617184610Salfred "subclass=%d, protocol=%d, maxpacket=%d, len=%d, speed=%d\n", 1618184610Salfred udev->address, UGETW(udev->ddesc.bcdUSB), 1619184610Salfred udev->ddesc.bDeviceClass, 1620184610Salfred udev->ddesc.bDeviceSubClass, 1621184610Salfred udev->ddesc.bDeviceProtocol, 1622184610Salfred udev->ddesc.bMaxPacketSize, 1623184610Salfred udev->ddesc.bLength, 1624184610Salfred udev->speed); 1625184610Salfred 1626184610Salfred /* get the full device descriptor */ 1627188986Sthompsa err = usb2_req_get_device_desc(udev, NULL, &udev->ddesc); 1628184610Salfred if (err) { 1629184610Salfred DPRINTF("addr=%d, getting full desc failed\n", 1630184610Salfred udev->address); 1631184610Salfred goto done; 1632184610Salfred } 1633184610Salfred /* 1634184610Salfred * Setup temporary USB attach args so that we can figure out some 1635184610Salfred * basic quirks for this device. 1636184610Salfred */ 1637184610Salfred usb2_init_attach_arg(udev, &uaa); 1638184610Salfred 1639184610Salfred if (usb2_test_quirk(&uaa, UQ_BUS_POWERED)) { 1640184610Salfred udev->flags.uq_bus_powered = 1; 1641184610Salfred } 1642184610Salfred if (usb2_test_quirk(&uaa, UQ_NO_STRINGS)) { 1643184610Salfred udev->flags.no_strings = 1; 1644184610Salfred } 1645184610Salfred /* 1646184610Salfred * Workaround for buggy USB devices. 1647184610Salfred * 1648184610Salfred * It appears that some string-less USB chips will crash and 1649184610Salfred * disappear if any attempts are made to read any string 1650184610Salfred * descriptors. 1651184610Salfred * 1652184610Salfred * Try to detect such chips by checking the strings in the USB 1653184610Salfred * device descriptor. If no strings are present there we 1654184610Salfred * simply disable all USB strings. 1655184610Salfred */ 1656184610Salfred scratch_ptr = udev->bus->scratch[0].data; 1657184610Salfred scratch_size = sizeof(udev->bus->scratch[0].data); 1658184610Salfred 1659184610Salfred if (udev->ddesc.iManufacturer || 1660184610Salfred udev->ddesc.iProduct || 1661184610Salfred udev->ddesc.iSerialNumber) { 1662184610Salfred /* read out the language ID string */ 1663188986Sthompsa err = usb2_req_get_string_desc(udev, NULL, 1664184610Salfred (char *)scratch_ptr, 4, scratch_size, 1665184610Salfred USB_LANGUAGE_TABLE); 1666184610Salfred } else { 1667184610Salfred err = USB_ERR_INVAL; 1668184610Salfred } 1669184610Salfred 1670184610Salfred if (err || (scratch_ptr[0] < 4)) { 1671184610Salfred udev->flags.no_strings = 1; 1672184610Salfred } else { 1673184610Salfred /* pick the first language as the default */ 1674184610Salfred udev->langid = UGETW(scratch_ptr + 2); 1675184610Salfred } 1676184610Salfred 1677184610Salfred /* assume 100mA bus powered for now. Changed when configured. */ 1678184610Salfred udev->power = USB_MIN_POWER; 1679184610Salfred 1680190180Sthompsa#if USB_HAVE_STRINGS 1681184610Salfred /* get serial number string */ 1682184610Salfred err = usb2_req_get_string_any 1683188986Sthompsa (udev, NULL, (char *)scratch_ptr, 1684184610Salfred scratch_size, udev->ddesc.iSerialNumber); 1685184610Salfred 1686184610Salfred strlcpy(udev->serial, (char *)scratch_ptr, sizeof(udev->serial)); 1687184610Salfred 1688184610Salfred /* get manufacturer string */ 1689184610Salfred err = usb2_req_get_string_any 1690188986Sthompsa (udev, NULL, (char *)scratch_ptr, 1691184610Salfred scratch_size, udev->ddesc.iManufacturer); 1692184610Salfred 1693184610Salfred strlcpy(udev->manufacturer, (char *)scratch_ptr, sizeof(udev->manufacturer)); 1694184610Salfred 1695184610Salfred /* get product string */ 1696184610Salfred err = usb2_req_get_string_any 1697188986Sthompsa (udev, NULL, (char *)scratch_ptr, 1698184610Salfred scratch_size, udev->ddesc.iProduct); 1699184610Salfred 1700184610Salfred strlcpy(udev->product, (char *)scratch_ptr, sizeof(udev->product)); 1701184610Salfred 1702184610Salfred /* finish up all the strings */ 1703184610Salfred usb2_check_strings(udev); 1704190180Sthompsa#endif 1705184610Salfred 1706192499Sthompsa if (udev->flags.usb_mode == USB_MODE_HOST) { 1707184610Salfred uint8_t config_index; 1708184610Salfred uint8_t config_quirk; 1709186730Salfred uint8_t set_config_failed = 0; 1710184610Salfred 1711184610Salfred /* 1712184610Salfred * Most USB devices should attach to config index 0 by 1713184610Salfred * default 1714184610Salfred */ 1715184610Salfred if (usb2_test_quirk(&uaa, UQ_CFG_INDEX_0)) { 1716184610Salfred config_index = 0; 1717184610Salfred config_quirk = 1; 1718184610Salfred } else if (usb2_test_quirk(&uaa, UQ_CFG_INDEX_1)) { 1719184610Salfred config_index = 1; 1720184610Salfred config_quirk = 1; 1721184610Salfred } else if (usb2_test_quirk(&uaa, UQ_CFG_INDEX_2)) { 1722184610Salfred config_index = 2; 1723184610Salfred config_quirk = 1; 1724184610Salfred } else if (usb2_test_quirk(&uaa, UQ_CFG_INDEX_3)) { 1725184610Salfred config_index = 3; 1726184610Salfred config_quirk = 1; 1727184610Salfred } else if (usb2_test_quirk(&uaa, UQ_CFG_INDEX_4)) { 1728184610Salfred config_index = 4; 1729184610Salfred config_quirk = 1; 1730184610Salfred } else { 1731184610Salfred config_index = 0; 1732184610Salfred config_quirk = 0; 1733184610Salfred } 1734184610Salfred 1735184610Salfredrepeat_set_config: 1736184610Salfred 1737184610Salfred DPRINTF("setting config %u\n", config_index); 1738184610Salfred 1739184610Salfred /* get the USB device configured */ 1740184610Salfred err = usb2_set_config_index(udev, config_index); 1741184610Salfred if (err) { 1742186730Salfred if (udev->ddesc.bNumConfigurations != 0) { 1743186730Salfred if (!set_config_failed) { 1744186730Salfred set_config_failed = 1; 1745186730Salfred /* XXX try to re-enumerate the device */ 1746186730Salfred err = usb2_req_re_enumerate( 1747188986Sthompsa udev, NULL); 1748186730Salfred if (err == 0) 1749186730Salfred goto repeat_set_config; 1750186730Salfred } 1751186730Salfred DPRINTFN(0, "Failure selecting " 1752186730Salfred "configuration index %u: %s, port %u, " 1753186730Salfred "addr %u (ignored)\n", 1754186730Salfred config_index, usb2_errstr(err), udev->port_no, 1755186730Salfred udev->address); 1756186730Salfred } 1757186730Salfred /* 1758186730Salfred * Some USB devices do not have any 1759186730Salfred * configurations. Ignore any set config 1760186730Salfred * failures! 1761186730Salfred */ 1762186730Salfred err = 0; 1763184610Salfred } else if (config_quirk) { 1764184610Salfred /* user quirk selects configuration index */ 1765184610Salfred } else if ((config_index + 1) < udev->ddesc.bNumConfigurations) { 1766184610Salfred 1767184610Salfred if ((udev->cdesc->bNumInterface < 2) && 1768190730Sthompsa (usb2_get_no_descriptors(udev->cdesc, 1769190730Sthompsa UDESC_ENDPOINT) == 0)) { 1770184610Salfred DPRINTFN(0, "Found no endpoints " 1771184610Salfred "(trying next config)!\n"); 1772184610Salfred config_index++; 1773184610Salfred goto repeat_set_config; 1774184610Salfred } 1775184610Salfred if (config_index == 0) { 1776184610Salfred /* 1777184610Salfred * Try to figure out if we have an 1778184610Salfred * auto-install disk there: 1779184610Salfred */ 1780185290Salfred if (usb2_test_autoinstall(udev, 0, 0) == 0) { 1781184610Salfred DPRINTFN(0, "Found possible auto-install " 1782184610Salfred "disk (trying next config)\n"); 1783184610Salfred config_index++; 1784184610Salfred goto repeat_set_config; 1785184610Salfred } 1786184610Salfred } 1787186730Salfred } else if (usb2_test_huawei_autoinst_p(udev, &uaa) == 0) { 1788185290Salfred DPRINTFN(0, "Found Huawei auto-install disk!\n"); 1789185290Salfred err = USB_ERR_STALLED; /* fake an error */ 1790184610Salfred } 1791184610Salfred } else { 1792184610Salfred err = 0; /* set success */ 1793184610Salfred } 1794184610Salfred 1795184610Salfred DPRINTF("new dev (addr %d), udev=%p, parent_hub=%p\n", 1796184610Salfred udev->address, udev, udev->parent_hub); 1797184610Salfred 1798184610Salfred /* register our device - we are ready */ 1799184610Salfred usb2_bus_port_set_device(bus, parent_hub ? 1800184610Salfred parent_hub->hub->ports + port_index : NULL, udev, device_index); 1801184610Salfred 1802189599Sthompsa#if USB_HAVE_UGEN 1803190191Sthompsa /* Symlink the ugen device name */ 1804189110Sthompsa udev->ugen_symlink = usb2_alloc_symlink(udev->ugen_name); 1805190191Sthompsa 1806190191Sthompsa /* Announce device */ 1807189110Sthompsa printf("%s: <%s> at %s\n", udev->ugen_name, udev->manufacturer, 1808184610Salfred device_get_nameunit(udev->bus->bdev)); 1809190727Sthompsa 1810184610Salfred usb2_notify_addq("+", udev); 1811190191Sthompsa#endif 1812184610Salfreddone: 1813184610Salfred if (err) { 1814184610Salfred /* free device */ 1815190730Sthompsa usb2_free_device(udev, 1816190730Sthompsa USB_UNCFG_FLAG_FREE_SUBDEV | 1817190730Sthompsa USB_UNCFG_FLAG_FREE_EP0); 1818184610Salfred udev = NULL; 1819184610Salfred } 1820184610Salfred return (udev); 1821184610Salfred} 1822184610Salfred 1823189599Sthompsa#if USB_HAVE_UGEN 1824189110Sthompsastatic struct cdev * 1825189172Sthompsausb2_make_dev(struct usb2_device *udev, int ep, int mode) 1826189110Sthompsa{ 1827189110Sthompsa struct usb2_fs_privdata* pd; 1828189110Sthompsa char devname[20]; 1829189110Sthompsa 1830189110Sthompsa /* Store information to locate ourselves again later */ 1831189110Sthompsa pd = malloc(sizeof(struct usb2_fs_privdata), M_USBDEV, 1832189110Sthompsa M_WAITOK | M_ZERO); 1833189110Sthompsa pd->bus_index = device_get_unit(udev->bus->bdev); 1834189110Sthompsa pd->dev_index = udev->device_index; 1835189110Sthompsa pd->ep_addr = ep; 1836189110Sthompsa pd->mode = mode; 1837189110Sthompsa 1838189110Sthompsa /* Now, create the device itself */ 1839189172Sthompsa snprintf(devname, sizeof(devname), "%u.%u.%u", 1840189173Sthompsa pd->bus_index, pd->dev_index, pd->ep_addr); 1841189110Sthompsa pd->cdev = make_dev(&usb2_devsw, 0, UID_ROOT, 1842189110Sthompsa GID_OPERATOR, 0600, USB_DEVICE_DIR "/%s", devname); 1843189110Sthompsa pd->cdev->si_drv1 = pd; 1844189110Sthompsa 1845189110Sthompsa return (pd->cdev); 1846189110Sthompsa} 1847189110Sthompsa 1848189110Sthompsastatic void 1849189110Sthompsausb2_cdev_create(struct usb2_device *udev) 1850189110Sthompsa{ 1851189173Sthompsa struct usb2_config_descriptor *cd; 1852189172Sthompsa struct usb2_endpoint_descriptor *ed; 1853189172Sthompsa struct usb2_descriptor *desc; 1854189110Sthompsa struct usb2_fs_privdata* pd; 1855189110Sthompsa struct cdev *dev; 1856189172Sthompsa int inmode, outmode, inmask, outmask, mode; 1857189172Sthompsa uint8_t ep; 1858189110Sthompsa 1859189110Sthompsa KASSERT(LIST_FIRST(&udev->pd_list) == NULL, ("stale cdev entries")); 1860189110Sthompsa 1861189110Sthompsa DPRINTFN(2, "Creating device nodes\n"); 1862189110Sthompsa 1863189110Sthompsa if (usb2_get_mode(udev) == USB_MODE_DEVICE) { 1864189110Sthompsa inmode = FWRITE; 1865189110Sthompsa outmode = FREAD; 1866189110Sthompsa } else { /* USB_MODE_HOST */ 1867189110Sthompsa inmode = FREAD; 1868189110Sthompsa outmode = FWRITE; 1869189110Sthompsa } 1870189110Sthompsa 1871189172Sthompsa inmask = 0; 1872189172Sthompsa outmask = 0; 1873189172Sthompsa desc = NULL; 1874189110Sthompsa 1875189172Sthompsa /* 1876189172Sthompsa * Collect all used endpoint numbers instead of just 1877189172Sthompsa * generating 16 static endpoints. 1878189172Sthompsa */ 1879189173Sthompsa cd = usb2_get_config_descriptor(udev); 1880189172Sthompsa while ((desc = usb2_desc_foreach(cd, desc))) { 1881189172Sthompsa /* filter out all endpoint descriptors */ 1882189172Sthompsa if ((desc->bDescriptorType == UDESC_ENDPOINT) && 1883189172Sthompsa (desc->bLength >= sizeof(*ed))) { 1884189172Sthompsa ed = (struct usb2_endpoint_descriptor *)desc; 1885189110Sthompsa 1886189172Sthompsa /* update masks */ 1887189172Sthompsa ep = ed->bEndpointAddress; 1888189172Sthompsa if (UE_GET_DIR(ep) == UE_DIR_OUT) 1889189172Sthompsa outmask |= 1 << UE_GET_ADDR(ep); 1890189172Sthompsa else 1891189172Sthompsa inmask |= 1 << UE_GET_ADDR(ep); 1892189110Sthompsa } 1893189110Sthompsa } 1894189172Sthompsa 1895189172Sthompsa /* Create all available endpoints except EP0 */ 1896189172Sthompsa for (ep = 1; ep < 16; ep++) { 1897189172Sthompsa mode = inmask & (1 << ep) ? inmode : 0; 1898189172Sthompsa mode |= outmask & (1 << ep) ? outmode : 0; 1899189172Sthompsa if (mode == 0) 1900189172Sthompsa continue; /* no IN or OUT endpoint */ 1901189172Sthompsa 1902189172Sthompsa dev = usb2_make_dev(udev, ep, mode); 1903189172Sthompsa pd = dev->si_drv1; 1904189172Sthompsa LIST_INSERT_HEAD(&udev->pd_list, pd, pd_next); 1905189172Sthompsa } 1906189110Sthompsa} 1907189110Sthompsa 1908189110Sthompsastatic void 1909189110Sthompsausb2_cdev_free(struct usb2_device *udev) 1910189110Sthompsa{ 1911189110Sthompsa struct usb2_fs_privdata* pd; 1912189110Sthompsa 1913189110Sthompsa DPRINTFN(2, "Freeing device nodes\n"); 1914189110Sthompsa 1915189110Sthompsa while ((pd = LIST_FIRST(&udev->pd_list)) != NULL) { 1916189110Sthompsa KASSERT(pd->cdev->si_drv1 == pd, ("privdata corrupt")); 1917189110Sthompsa 1918189110Sthompsa destroy_dev_sched_cb(pd->cdev, usb2_cdev_cleanup, pd); 1919189110Sthompsa pd->cdev = NULL; 1920189110Sthompsa LIST_REMOVE(pd, pd_next); 1921189110Sthompsa } 1922189110Sthompsa} 1923189110Sthompsa 1924189110Sthompsastatic void 1925189110Sthompsausb2_cdev_cleanup(void* arg) 1926189110Sthompsa{ 1927189110Sthompsa free(arg, M_USBDEV); 1928189110Sthompsa} 1929189599Sthompsa#endif 1930189110Sthompsa 1931184610Salfred/*------------------------------------------------------------------------* 1932184610Salfred * usb2_free_device 1933184610Salfred * 1934184610Salfred * This function is NULL safe and will free an USB device. 1935190730Sthompsa * 1936190730Sthompsa * Flag values, see "USB_UNCFG_FLAG_XXX". 1937184610Salfred *------------------------------------------------------------------------*/ 1938184610Salfredvoid 1939190730Sthompsausb2_free_device(struct usb2_device *udev, uint8_t flag) 1940184610Salfred{ 1941190730Sthompsa struct usb2_bus *bus; 1942184610Salfred 1943190730Sthompsa if (udev == NULL) 1944190730Sthompsa return; /* already freed */ 1945190730Sthompsa 1946184610Salfred DPRINTFN(4, "udev=%p port=%d\n", udev, udev->port_no); 1947184610Salfred 1948191494Sthompsa bus = udev->bus; 1949191494Sthompsa usb2_set_device_state(udev, USB_STATE_DETACHED); 1950190730Sthompsa 1951190191Sthompsa#if USB_HAVE_UGEN 1952184610Salfred usb2_notify_addq("-", udev); 1953184610Salfred 1954189110Sthompsa printf("%s: <%s> at %s (disconnected)\n", udev->ugen_name, 1955189110Sthompsa udev->manufacturer, device_get_nameunit(bus->bdev)); 1956184610Salfred 1957189110Sthompsa /* Destroy UGEN symlink, if any */ 1958184610Salfred if (udev->ugen_symlink) { 1959184610Salfred usb2_free_symlink(udev->ugen_symlink); 1960184610Salfred udev->ugen_symlink = NULL; 1961184610Salfred } 1962190191Sthompsa#endif 1963184610Salfred /* 1964184610Salfred * Unregister our device first which will prevent any further 1965184610Salfred * references: 1966184610Salfred */ 1967184610Salfred usb2_bus_port_set_device(bus, udev->parent_hub ? 1968184610Salfred udev->parent_hub->hub->ports + udev->port_index : NULL, 1969184610Salfred NULL, USB_ROOT_HUB_ADDR); 1970184610Salfred 1971189599Sthompsa#if USB_HAVE_UGEN 1972184610Salfred /* wait for all pending references to go away: */ 1973184610Salfred mtx_lock(&usb2_ref_lock); 1974184610Salfred udev->refcount--; 1975184610Salfred while (udev->refcount != 0) { 1976184610Salfred usb2_cv_wait(udev->default_cv + 1, &usb2_ref_lock); 1977184610Salfred } 1978184610Salfred mtx_unlock(&usb2_ref_lock); 1979190730Sthompsa 1980190730Sthompsa destroy_dev_sched_cb(udev->default_dev, usb2_cdev_cleanup, 1981190730Sthompsa udev->default_dev->si_drv1); 1982189599Sthompsa#endif 1983184610Salfred 1984192499Sthompsa if (udev->flags.usb_mode == USB_MODE_DEVICE) { 1985184610Salfred /* stop receiving any control transfers (Device Side Mode) */ 1986184610Salfred usb2_transfer_unsetup(udev->default_xfer, USB_DEFAULT_XFER_MAX); 1987184610Salfred } 1988184610Salfred 1989190730Sthompsa /* the following will get the device unconfigured in software */ 1990190730Sthompsa usb2_unconfigure(udev, flag); 1991184610Salfred 1992184610Salfred /* unsetup any leftover default USB transfers */ 1993184610Salfred usb2_transfer_unsetup(udev->default_xfer, USB_DEFAULT_XFER_MAX); 1994184610Salfred 1995187174Sthompsa /* template unsetup, if any */ 1996184610Salfred (usb2_temp_unsetup_p) (udev); 1997184610Salfred 1998187174Sthompsa /* 1999187174Sthompsa * Make sure that our clear-stall messages are not queued 2000187174Sthompsa * anywhere: 2001187174Sthompsa */ 2002187174Sthompsa USB_BUS_LOCK(udev->bus); 2003187174Sthompsa usb2_proc_mwait(&udev->bus->non_giant_callback_proc, 2004187174Sthompsa &udev->cs_msg[0], &udev->cs_msg[1]); 2005187174Sthompsa USB_BUS_UNLOCK(udev->bus); 2006187174Sthompsa 2007184610Salfred sx_destroy(udev->default_sx); 2008184610Salfred sx_destroy(udev->default_sx + 1); 2009184610Salfred 2010184610Salfred usb2_cv_destroy(udev->default_cv); 2011184610Salfred usb2_cv_destroy(udev->default_cv + 1); 2012184610Salfred 2013184610Salfred mtx_destroy(udev->default_mtx); 2014190191Sthompsa#if USB_HAVE_UGEN 2015189110Sthompsa KASSERT(LIST_FIRST(&udev->pd_list) == NULL, ("leaked cdev entries")); 2016190191Sthompsa#endif 2017184610Salfred 2018184610Salfred /* free device */ 2019184610Salfred free(udev, M_USB); 2020184610Salfred} 2021184610Salfred 2022184610Salfred/*------------------------------------------------------------------------* 2023184610Salfred * usb2_get_iface 2024184610Salfred * 2025184610Salfred * This function is the safe way to get the USB interface structure 2026184610Salfred * pointer by interface index. 2027184610Salfred * 2028184610Salfred * Return values: 2029184610Salfred * NULL: Interface not present. 2030184610Salfred * Else: Pointer to USB interface structure. 2031184610Salfred *------------------------------------------------------------------------*/ 2032184610Salfredstruct usb2_interface * 2033184610Salfredusb2_get_iface(struct usb2_device *udev, uint8_t iface_index) 2034184610Salfred{ 2035184610Salfred struct usb2_interface *iface = udev->ifaces + iface_index; 2036184610Salfred 2037190730Sthompsa if (iface_index >= udev->ifaces_max) 2038184610Salfred return (NULL); 2039184610Salfred return (iface); 2040184610Salfred} 2041184610Salfred 2042184610Salfred/*------------------------------------------------------------------------* 2043184610Salfred * usb2_find_descriptor 2044184610Salfred * 2045184610Salfred * This function will lookup the first descriptor that matches the 2046184610Salfred * criteria given by the arguments "type" and "subtype". Descriptors 2047184610Salfred * will only be searched within the interface having the index 2048184610Salfred * "iface_index". If the "id" argument points to an USB descriptor, 2049184610Salfred * it will be skipped before the search is started. This allows 2050184610Salfred * searching for multiple descriptors using the same criteria. Else 2051184610Salfred * the search is started after the interface descriptor. 2052184610Salfred * 2053184610Salfred * Return values: 2054184610Salfred * NULL: End of descriptors 2055184610Salfred * Else: A descriptor matching the criteria 2056184610Salfred *------------------------------------------------------------------------*/ 2057184610Salfredvoid * 2058184610Salfredusb2_find_descriptor(struct usb2_device *udev, void *id, uint8_t iface_index, 2059184610Salfred uint8_t type, uint8_t type_mask, 2060184610Salfred uint8_t subtype, uint8_t subtype_mask) 2061184610Salfred{ 2062184610Salfred struct usb2_descriptor *desc; 2063184610Salfred struct usb2_config_descriptor *cd; 2064184610Salfred struct usb2_interface *iface; 2065184610Salfred 2066184610Salfred cd = usb2_get_config_descriptor(udev); 2067184610Salfred if (cd == NULL) { 2068184610Salfred return (NULL); 2069184610Salfred } 2070184610Salfred if (id == NULL) { 2071184610Salfred iface = usb2_get_iface(udev, iface_index); 2072184610Salfred if (iface == NULL) { 2073184610Salfred return (NULL); 2074184610Salfred } 2075184610Salfred id = usb2_get_interface_descriptor(iface); 2076184610Salfred if (id == NULL) { 2077184610Salfred return (NULL); 2078184610Salfred } 2079184610Salfred } 2080184610Salfred desc = (void *)id; 2081184610Salfred 2082184610Salfred while ((desc = usb2_desc_foreach(cd, desc))) { 2083184610Salfred 2084184610Salfred if (desc->bDescriptorType == UDESC_INTERFACE) { 2085184610Salfred break; 2086184610Salfred } 2087184610Salfred if (((desc->bDescriptorType & type_mask) == type) && 2088184610Salfred ((desc->bDescriptorSubtype & subtype_mask) == subtype)) { 2089184610Salfred return (desc); 2090184610Salfred } 2091184610Salfred } 2092184610Salfred return (NULL); 2093184610Salfred} 2094184610Salfred 2095184610Salfred/*------------------------------------------------------------------------* 2096184610Salfred * usb2_devinfo 2097184610Salfred * 2098184610Salfred * This function will dump information from the device descriptor 2099184610Salfred * belonging to the USB device pointed to by "udev", to the string 2100184610Salfred * pointed to by "dst_ptr" having a maximum length of "dst_len" bytes 2101184610Salfred * including the terminating zero. 2102184610Salfred *------------------------------------------------------------------------*/ 2103184610Salfredvoid 2104184610Salfredusb2_devinfo(struct usb2_device *udev, char *dst_ptr, uint16_t dst_len) 2105184610Salfred{ 2106184610Salfred struct usb2_device_descriptor *udd = &udev->ddesc; 2107184610Salfred uint16_t bcdDevice; 2108184610Salfred uint16_t bcdUSB; 2109184610Salfred 2110184610Salfred bcdUSB = UGETW(udd->bcdUSB); 2111184610Salfred bcdDevice = UGETW(udd->bcdDevice); 2112184610Salfred 2113184610Salfred if (udd->bDeviceClass != 0xFF) { 2114184610Salfred snprintf(dst_ptr, dst_len, "%s %s, class %d/%d, rev %x.%02x/" 2115190191Sthompsa "%x.%02x, addr %d", 2116190191Sthompsa#if USB_HAVE_STRINGS 2117190191Sthompsa udev->manufacturer, udev->product, 2118190191Sthompsa#else 2119190191Sthompsa "-", "-", 2120190191Sthompsa#endif 2121184610Salfred udd->bDeviceClass, udd->bDeviceSubClass, 2122184610Salfred (bcdUSB >> 8), bcdUSB & 0xFF, 2123184610Salfred (bcdDevice >> 8), bcdDevice & 0xFF, 2124184610Salfred udev->address); 2125184610Salfred } else { 2126184610Salfred snprintf(dst_ptr, dst_len, "%s %s, rev %x.%02x/" 2127190191Sthompsa "%x.%02x, addr %d", 2128190191Sthompsa#if USB_HAVE_STRINGS 2129190191Sthompsa udev->manufacturer, udev->product, 2130190191Sthompsa#else 2131190191Sthompsa "-", "-", 2132190191Sthompsa#endif 2133184610Salfred (bcdUSB >> 8), bcdUSB & 0xFF, 2134184610Salfred (bcdDevice >> 8), bcdDevice & 0xFF, 2135184610Salfred udev->address); 2136184610Salfred } 2137184610Salfred} 2138184610Salfred 2139190180Sthompsa#if USB_HAVE_STRINGS 2140184610Salfred#if USB_VERBOSE 2141184610Salfred/* 2142184610Salfred * Descriptions of of known vendors and devices ("products"). 2143184610Salfred */ 2144184610Salfredstruct usb_knowndev { 2145184610Salfred uint16_t vendor; 2146184610Salfred uint16_t product; 2147184610Salfred uint32_t flags; 2148184610Salfred const char *vendorname; 2149184610Salfred const char *productname; 2150184610Salfred}; 2151184610Salfred 2152184610Salfred#define USB_KNOWNDEV_NOPROD 0x01 /* match on vendor only */ 2153184610Salfred 2154188746Sthompsa#include "usbdevs.h" 2155188746Sthompsa#include "usbdevs_data.h" 2156184610Salfred#endif /* USB_VERBOSE */ 2157184610Salfred 2158184610Salfred/*------------------------------------------------------------------------* 2159184610Salfred * usb2_check_strings 2160184610Salfred * 2161184610Salfred * This function checks the manufacturer and product strings and will 2162184610Salfred * fill in defaults for missing strings. 2163184610Salfred *------------------------------------------------------------------------*/ 2164184610Salfredstatic void 2165184610Salfredusb2_check_strings(struct usb2_device *udev) 2166184610Salfred{ 2167184610Salfred struct usb2_device_descriptor *udd = &udev->ddesc; 2168184610Salfred const char *vendor; 2169184610Salfred const char *product; 2170184610Salfred 2171184610Salfred#if USB_VERBOSE 2172184610Salfred const struct usb_knowndev *kdp; 2173184610Salfred 2174184610Salfred#endif 2175184610Salfred uint16_t vendor_id; 2176184610Salfred uint16_t product_id; 2177184610Salfred 2178184610Salfred usb2_trim_spaces(udev->manufacturer); 2179184610Salfred usb2_trim_spaces(udev->product); 2180184610Salfred 2181184610Salfred if (udev->manufacturer[0]) { 2182184610Salfred vendor = udev->manufacturer; 2183184610Salfred } else { 2184184610Salfred vendor = NULL; 2185184610Salfred } 2186184610Salfred 2187184610Salfred if (udev->product[0]) { 2188184610Salfred product = udev->product; 2189184610Salfred } else { 2190184610Salfred product = NULL; 2191184610Salfred } 2192184610Salfred 2193184610Salfred vendor_id = UGETW(udd->idVendor); 2194184610Salfred product_id = UGETW(udd->idProduct); 2195184610Salfred 2196184610Salfred#if USB_VERBOSE 2197184610Salfred if (vendor == NULL || product == NULL) { 2198184610Salfred 2199184610Salfred for (kdp = usb_knowndevs; 2200184610Salfred kdp->vendorname != NULL; 2201184610Salfred kdp++) { 2202184610Salfred if (kdp->vendor == vendor_id && 2203184610Salfred (kdp->product == product_id || 2204184610Salfred (kdp->flags & USB_KNOWNDEV_NOPROD) != 0)) 2205184610Salfred break; 2206184610Salfred } 2207184610Salfred if (kdp->vendorname != NULL) { 2208184610Salfred if (vendor == NULL) 2209184610Salfred vendor = kdp->vendorname; 2210184610Salfred if (product == NULL) 2211184610Salfred product = (kdp->flags & USB_KNOWNDEV_NOPROD) == 0 ? 2212184610Salfred kdp->productname : NULL; 2213184610Salfred } 2214184610Salfred } 2215184610Salfred#endif 2216184610Salfred if (vendor && *vendor) { 2217184610Salfred if (udev->manufacturer != vendor) { 2218184610Salfred strlcpy(udev->manufacturer, vendor, 2219184610Salfred sizeof(udev->manufacturer)); 2220184610Salfred } 2221184610Salfred } else { 2222184610Salfred snprintf(udev->manufacturer, 2223184610Salfred sizeof(udev->manufacturer), "vendor 0x%04x", vendor_id); 2224184610Salfred } 2225184610Salfred 2226184610Salfred if (product && *product) { 2227184610Salfred if (udev->product != product) { 2228184610Salfred strlcpy(udev->product, product, 2229184610Salfred sizeof(udev->product)); 2230184610Salfred } 2231184610Salfred } else { 2232184610Salfred snprintf(udev->product, 2233184610Salfred sizeof(udev->product), "product 0x%04x", product_id); 2234184610Salfred } 2235184610Salfred} 2236190180Sthompsa#endif 2237184610Salfred 2238188411Sthompsa/* 2239188411Sthompsa * Returns: 2240188411Sthompsa * See: USB_MODE_XXX 2241188411Sthompsa */ 2242192499Sthompsaenum usb_hc_mode 2243188411Sthompsausb2_get_mode(struct usb2_device *udev) 2244188411Sthompsa{ 2245192499Sthompsa return (udev->flags.usb_mode); 2246188411Sthompsa} 2247188411Sthompsa 2248188411Sthompsa/* 2249188411Sthompsa * Returns: 2250188411Sthompsa * See: USB_SPEED_XXX 2251188411Sthompsa */ 2252192500Sthompsaenum usb_dev_speed 2253184610Salfredusb2_get_speed(struct usb2_device *udev) 2254184610Salfred{ 2255184610Salfred return (udev->speed); 2256184610Salfred} 2257184610Salfred 2258186730Salfreduint32_t 2259186730Salfredusb2_get_isoc_fps(struct usb2_device *udev) 2260186730Salfred{ 2261186730Salfred ; /* indent fix */ 2262186730Salfred switch (udev->speed) { 2263186730Salfred case USB_SPEED_LOW: 2264186730Salfred case USB_SPEED_FULL: 2265186730Salfred return (1000); 2266186730Salfred default: 2267186730Salfred return (8000); 2268186730Salfred } 2269186730Salfred} 2270186730Salfred 2271184610Salfredstruct usb2_device_descriptor * 2272184610Salfredusb2_get_device_descriptor(struct usb2_device *udev) 2273184610Salfred{ 2274184610Salfred if (udev == NULL) 2275184610Salfred return (NULL); /* be NULL safe */ 2276184610Salfred return (&udev->ddesc); 2277184610Salfred} 2278184610Salfred 2279184610Salfredstruct usb2_config_descriptor * 2280184610Salfredusb2_get_config_descriptor(struct usb2_device *udev) 2281184610Salfred{ 2282184610Salfred if (udev == NULL) 2283184610Salfred return (NULL); /* be NULL safe */ 2284184610Salfred return (udev->cdesc); 2285184610Salfred} 2286184610Salfred 2287184610Salfred/*------------------------------------------------------------------------* 2288184610Salfred * usb2_test_quirk - test a device for a given quirk 2289184610Salfred * 2290184610Salfred * Return values: 2291184610Salfred * 0: The USB device does not have the given quirk. 2292184610Salfred * Else: The USB device has the given quirk. 2293184610Salfred *------------------------------------------------------------------------*/ 2294184610Salfreduint8_t 2295184610Salfredusb2_test_quirk(const struct usb2_attach_arg *uaa, uint16_t quirk) 2296184610Salfred{ 2297184610Salfred uint8_t found; 2298184610Salfred 2299184610Salfred found = (usb2_test_quirk_p) (&uaa->info, quirk); 2300184610Salfred return (found); 2301184610Salfred} 2302184610Salfred 2303184610Salfredstruct usb2_interface_descriptor * 2304184610Salfredusb2_get_interface_descriptor(struct usb2_interface *iface) 2305184610Salfred{ 2306184610Salfred if (iface == NULL) 2307184610Salfred return (NULL); /* be NULL safe */ 2308184610Salfred return (iface->idesc); 2309184610Salfred} 2310184610Salfred 2311184610Salfreduint8_t 2312184610Salfredusb2_get_interface_altindex(struct usb2_interface *iface) 2313184610Salfred{ 2314184610Salfred return (iface->alt_index); 2315184610Salfred} 2316184610Salfred 2317184610Salfreduint8_t 2318184610Salfredusb2_get_bus_index(struct usb2_device *udev) 2319184610Salfred{ 2320184610Salfred return ((uint8_t)device_get_unit(udev->bus->bdev)); 2321184610Salfred} 2322184610Salfred 2323184610Salfreduint8_t 2324184610Salfredusb2_get_device_index(struct usb2_device *udev) 2325184610Salfred{ 2326184610Salfred return (udev->device_index); 2327184610Salfred} 2328184610Salfred 2329190191Sthompsa#if USB_HAVE_UGEN 2330184610Salfred/*------------------------------------------------------------------------* 2331184610Salfred * usb2_notify_addq 2332184610Salfred * 2333184610Salfred * This function will generate events for dev. 2334184610Salfred *------------------------------------------------------------------------*/ 2335184610Salfredstatic void 2336184610Salfredusb2_notify_addq(const char *type, struct usb2_device *udev) 2337184610Salfred{ 2338184610Salfred char *data = NULL; 2339184610Salfred struct malloc_type *mt; 2340184610Salfred 2341184610Salfred mtx_lock(&malloc_mtx); 2342184610Salfred mt = malloc_desc2type("bus"); /* XXX M_BUS */ 2343184610Salfred mtx_unlock(&malloc_mtx); 2344184610Salfred if (mt == NULL) 2345184610Salfred return; 2346184610Salfred 2347184610Salfred data = malloc(512, mt, M_NOWAIT); 2348184610Salfred if (data == NULL) 2349184610Salfred return; 2350184610Salfred 2351184610Salfred /* String it all together. */ 2352190306Skan snprintf(data, 1024, 2353190306Skan "%s" 2354190306Skan "%s " 2355190306Skan "vendor=0x%04x " 2356190306Skan "product=0x%04x " 2357190306Skan "devclass=0x%02x " 2358190306Skan "devsubclass=0x%02x " 2359190306Skan "sernum=\"%s\" " 2360190306Skan "at " 2361190306Skan "port=%u " 2362190306Skan "on " 2363190306Skan "%s\n", 2364190306Skan type, 2365190306Skan udev->ugen_name, 2366190306Skan UGETW(udev->ddesc.idVendor), 2367190306Skan UGETW(udev->ddesc.idProduct), 2368190306Skan udev->ddesc.bDeviceClass, 2369190306Skan udev->ddesc.bDeviceSubClass, 2370190191Sthompsa#if USB_HAVE_STRINGS 2371190306Skan udev->serial, 2372190191Sthompsa#else 2373190306Skan "", 2374190191Sthompsa#endif 2375190306Skan udev->port_no, 2376190306Skan udev->parent_hub != NULL ? 2377190306Skan udev->parent_hub->ugen_name : 2378190306Skan device_get_nameunit(device_get_parent(udev->bus->bdev))); 2379190306Skan 2380184610Salfred devctl_queue_data(data); 2381184610Salfred} 2382184610Salfred 2383184610Salfred/*------------------------------------------------------------------------* 2384184610Salfred * usb2_fifo_free_wrap 2385184610Salfred * 2386185087Salfred * This function will free the FIFOs. 2387185087Salfred * 2388190730Sthompsa * Description of "flag" argument: If the USB_UNCFG_FLAG_FREE_EP0 flag 2389190730Sthompsa * is set and "iface_index" is set to "USB_IFACE_INDEX_ANY", we free 2390190730Sthompsa * all FIFOs. If the USB_UNCFG_FLAG_FREE_EP0 flag is not set and 2391190730Sthompsa * "iface_index" is set to "USB_IFACE_INDEX_ANY", we free all non 2392190730Sthompsa * control endpoint FIFOs. If "iface_index" is not set to 2393190730Sthompsa * "USB_IFACE_INDEX_ANY" the flag has no effect. 2394184610Salfred *------------------------------------------------------------------------*/ 2395184610Salfredstatic void 2396184610Salfredusb2_fifo_free_wrap(struct usb2_device *udev, 2397185087Salfred uint8_t iface_index, uint8_t flag) 2398184610Salfred{ 2399184610Salfred struct usb2_fifo *f; 2400184610Salfred uint16_t i; 2401184610Salfred 2402184610Salfred /* 2403184610Salfred * Free any USB FIFOs on the given interface: 2404184610Salfred */ 2405184610Salfred for (i = 0; i != USB_FIFO_MAX; i++) { 2406184610Salfred f = udev->fifo[i]; 2407184610Salfred if (f == NULL) { 2408184610Salfred continue; 2409184610Salfred } 2410185087Salfred /* Check if the interface index matches */ 2411185087Salfred if (iface_index == f->iface_index) { 2412185087Salfred if (f->methods != &usb2_ugen_methods) { 2413185087Salfred /* 2414185087Salfred * Don't free any non-generic FIFOs in 2415185087Salfred * this case. 2416185087Salfred */ 2417185087Salfred continue; 2418185087Salfred } 2419185290Salfred if ((f->dev_ep_index == 0) && 2420185290Salfred (f->fs_xfer == NULL)) { 2421185290Salfred /* no need to free this FIFO */ 2422185087Salfred continue; 2423185087Salfred } 2424185087Salfred } else if (iface_index == USB_IFACE_INDEX_ANY) { 2425185087Salfred if ((f->methods == &usb2_ugen_methods) && 2426190730Sthompsa (f->dev_ep_index == 0) && 2427190730Sthompsa (!(flag & USB_UNCFG_FLAG_FREE_EP0)) && 2428185290Salfred (f->fs_xfer == NULL)) { 2429185290Salfred /* no need to free this FIFO */ 2430185087Salfred continue; 2431185087Salfred } 2432185087Salfred } else { 2433185290Salfred /* no need to free this FIFO */ 2434184610Salfred continue; 2435184610Salfred } 2436185290Salfred /* free this FIFO */ 2437185087Salfred usb2_fifo_free(f); 2438184610Salfred } 2439184610Salfred} 2440189599Sthompsa#endif 2441186730Salfred 2442186730Salfred/*------------------------------------------------------------------------* 2443186730Salfred * usb2_peer_can_wakeup 2444186730Salfred * 2445186730Salfred * Return values: 2446186730Salfred * 0: Peer cannot do resume signalling. 2447186730Salfred * Else: Peer can do resume signalling. 2448186730Salfred *------------------------------------------------------------------------*/ 2449186730Salfreduint8_t 2450186730Salfredusb2_peer_can_wakeup(struct usb2_device *udev) 2451186730Salfred{ 2452186730Salfred const struct usb2_config_descriptor *cdp; 2453186730Salfred 2454186730Salfred cdp = udev->cdesc; 2455192499Sthompsa if ((cdp != NULL) && (udev->flags.usb_mode == USB_MODE_HOST)) { 2456186730Salfred return (cdp->bmAttributes & UC_REMOTE_WAKEUP); 2457186730Salfred } 2458186730Salfred return (0); /* not supported */ 2459186730Salfred} 2460191494Sthompsa 2461191494Sthompsavoid 2462192500Sthompsausb2_set_device_state(struct usb2_device *udev, enum usb_dev_state state) 2463191494Sthompsa{ 2464191494Sthompsa 2465191494Sthompsa KASSERT(state < USB_STATE_MAX, ("invalid udev state")); 2466191494Sthompsa 2467191494Sthompsa DPRINTF("udev %p state %s -> %s\n", udev, 2468191498Sthompsa usb2_statestr(udev->state), usb2_statestr(state)); 2469191494Sthompsa udev->state = state; 2470191494Sthompsa} 2471191494Sthompsa 2472191824Sthompsauint8_t 2473191494Sthompsausb2_device_attached(struct usb2_device *udev) 2474191494Sthompsa{ 2475191494Sthompsa return (udev->state > USB_STATE_DETACHED); 2476191494Sthompsa} 2477