| .. | .. |
|---|
| 14 | 14 | * Linux-USB host controller driver. USB traffic is simulated; there's |
|---|
| 15 | 15 | * no need for USB hardware. Use this with two other drivers: |
|---|
| 16 | 16 | * |
|---|
| 17 | | - * - Gadget driver, responding to requests (slave); |
|---|
| 17 | + * - Gadget driver, responding to requests (device); |
|---|
| 18 | 18 | * - Host-side device driver, as already familiar in Linux. |
|---|
| 19 | 19 | * |
|---|
| 20 | 20 | * Having this all in one kernel can help some stages of development, |
|---|
| .. | .. |
|---|
| 261 | 261 | spinlock_t lock; |
|---|
| 262 | 262 | |
|---|
| 263 | 263 | /* |
|---|
| 264 | | - * SLAVE/GADGET side support |
|---|
| 264 | + * DEVICE/GADGET side support |
|---|
| 265 | 265 | */ |
|---|
| 266 | 266 | struct dummy_ep ep[DUMMY_ENDPOINTS]; |
|---|
| 267 | 267 | int address; |
|---|
| .. | .. |
|---|
| 276 | 276 | unsigned pullup:1; |
|---|
| 277 | 277 | |
|---|
| 278 | 278 | /* |
|---|
| 279 | | - * MASTER/HOST side support |
|---|
| 279 | + * HOST side support |
|---|
| 280 | 280 | */ |
|---|
| 281 | 281 | struct dummy_hcd *hs_hcd; |
|---|
| 282 | 282 | struct dummy_hcd *ss_hcd; |
|---|
| .. | .. |
|---|
| 323 | 323 | |
|---|
| 324 | 324 | /*-------------------------------------------------------------------------*/ |
|---|
| 325 | 325 | |
|---|
| 326 | | -/* SLAVE/GADGET SIDE UTILITY ROUTINES */ |
|---|
| 326 | +/* DEVICE/GADGET SIDE UTILITY ROUTINES */ |
|---|
| 327 | 327 | |
|---|
| 328 | 328 | /* called with spinlock held */ |
|---|
| 329 | 329 | static void nuke(struct dummy *dum, struct dummy_ep *ep) |
|---|
| .. | .. |
|---|
| 427 | 427 | |
|---|
| 428 | 428 | /* caller must hold lock */ |
|---|
| 429 | 429 | static void set_link_state(struct dummy_hcd *dum_hcd) |
|---|
| 430 | + __must_hold(&dum->lock) |
|---|
| 430 | 431 | { |
|---|
| 431 | 432 | struct dummy *dum = dum_hcd->dum; |
|---|
| 432 | 433 | unsigned int power_bit; |
|---|
| .. | .. |
|---|
| 485 | 486 | |
|---|
| 486 | 487 | /*-------------------------------------------------------------------------*/ |
|---|
| 487 | 488 | |
|---|
| 488 | | -/* SLAVE/GADGET SIDE DRIVER |
|---|
| 489 | +/* DEVICE/GADGET SIDE DRIVER |
|---|
| 489 | 490 | * |
|---|
| 490 | 491 | * This only tracks gadget state. All the work is done when the host |
|---|
| 491 | 492 | * side tries some (emulated) i/o operation. Real device controller |
|---|
| .. | .. |
|---|
| 566 | 567 | if (max <= 1024) |
|---|
| 567 | 568 | break; |
|---|
| 568 | 569 | /* save a return statement */ |
|---|
| 569 | | - /* fall through */ |
|---|
| 570 | + fallthrough; |
|---|
| 570 | 571 | case USB_SPEED_FULL: |
|---|
| 571 | 572 | if (max <= 64) |
|---|
| 572 | 573 | break; |
|---|
| 573 | 574 | /* save a return statement */ |
|---|
| 574 | | - /* fall through */ |
|---|
| 575 | + fallthrough; |
|---|
| 575 | 576 | default: |
|---|
| 576 | 577 | if (max <= 8) |
|---|
| 577 | 578 | break; |
|---|
| .. | .. |
|---|
| 589 | 590 | if (max <= 1024) |
|---|
| 590 | 591 | break; |
|---|
| 591 | 592 | /* save a return statement */ |
|---|
| 592 | | - /* fall through */ |
|---|
| 593 | + fallthrough; |
|---|
| 593 | 594 | case USB_SPEED_FULL: |
|---|
| 594 | 595 | if (max <= 1023) |
|---|
| 595 | 596 | break; |
|---|
| .. | .. |
|---|
| 618 | 619 | _ep->name, |
|---|
| 619 | 620 | desc->bEndpointAddress & 0x0f, |
|---|
| 620 | 621 | (desc->bEndpointAddress & USB_DIR_IN) ? "in" : "out", |
|---|
| 621 | | - ({ char *val; |
|---|
| 622 | | - switch (usb_endpoint_type(desc)) { |
|---|
| 623 | | - case USB_ENDPOINT_XFER_BULK: |
|---|
| 624 | | - val = "bulk"; |
|---|
| 625 | | - break; |
|---|
| 626 | | - case USB_ENDPOINT_XFER_ISOC: |
|---|
| 627 | | - val = "iso"; |
|---|
| 628 | | - break; |
|---|
| 629 | | - case USB_ENDPOINT_XFER_INT: |
|---|
| 630 | | - val = "intr"; |
|---|
| 631 | | - break; |
|---|
| 632 | | - default: |
|---|
| 633 | | - val = "ctrl"; |
|---|
| 634 | | - break; |
|---|
| 635 | | - } val; }), |
|---|
| 622 | + usb_ep_type_string(usb_endpoint_type(desc)), |
|---|
| 636 | 623 | max, ep->stream_en ? "enabled" : "disabled"); |
|---|
| 637 | 624 | |
|---|
| 638 | 625 | /* at this point real hardware should be NAKing transfers |
|---|
| .. | .. |
|---|
| 985 | 972 | * hardware can be built with discrete components, so the gadget API doesn't |
|---|
| 986 | 973 | * require that assumption. |
|---|
| 987 | 974 | * |
|---|
| 988 | | - * For this emulator, it might be convenient to create a usb slave device |
|---|
| 975 | + * For this emulator, it might be convenient to create a usb device |
|---|
| 989 | 976 | * for each driver that registers: just add to a big root hub. |
|---|
| 990 | 977 | */ |
|---|
| 991 | 978 | |
|---|
| .. | .. |
|---|
| 1009 | 996 | } |
|---|
| 1010 | 997 | |
|---|
| 1011 | 998 | /* |
|---|
| 1012 | | - * SLAVE side init ... the layer above hardware, which |
|---|
| 999 | + * DEVICE side init ... the layer above hardware, which |
|---|
| 1013 | 1000 | * can't enumerate without help from the driver we're binding. |
|---|
| 1014 | 1001 | */ |
|---|
| 1015 | 1002 | |
|---|
| .. | .. |
|---|
| 1155 | 1142 | .suspend = dummy_udc_suspend, |
|---|
| 1156 | 1143 | .resume = dummy_udc_resume, |
|---|
| 1157 | 1144 | .driver = { |
|---|
| 1158 | | - .name = (char *) gadget_name, |
|---|
| 1145 | + .name = gadget_name, |
|---|
| 1159 | 1146 | }, |
|---|
| 1160 | 1147 | }; |
|---|
| 1161 | 1148 | |
|---|
| .. | .. |
|---|
| 1171 | 1158 | return index; |
|---|
| 1172 | 1159 | } |
|---|
| 1173 | 1160 | |
|---|
| 1174 | | -/* MASTER/HOST SIDE DRIVER |
|---|
| 1161 | +/* HOST SIDE DRIVER |
|---|
| 1175 | 1162 | * |
|---|
| 1176 | 1163 | * this uses the hcd framework to hook up to host side drivers. |
|---|
| 1177 | 1164 | * its root hub will only have one device, otherwise it acts like |
|---|
| .. | .. |
|---|
| 1601 | 1588 | |
|---|
| 1602 | 1589 | /** |
|---|
| 1603 | 1590 | * handle_control_request() - handles all control transfers |
|---|
| 1604 | | - * @dum: pointer to dummy (the_controller) |
|---|
| 1591 | + * @dum_hcd: pointer to dummy (the_controller) |
|---|
| 1605 | 1592 | * @urb: the urb request to handle |
|---|
| 1606 | 1593 | * @setup: pointer to the setup data for a USB device control |
|---|
| 1607 | 1594 | * request |
|---|
| .. | .. |
|---|
| 1963 | 1950 | * this almost certainly polls too fast. |
|---|
| 1964 | 1951 | */ |
|---|
| 1965 | 1952 | limit = max(limit, periodic_bytes(dum, ep)); |
|---|
| 1966 | | - /* FALLTHROUGH */ |
|---|
| 1953 | + fallthrough; |
|---|
| 1967 | 1954 | |
|---|
| 1968 | 1955 | default: |
|---|
| 1969 | 1956 | treat_control_like_bulk: |
|---|
| .. | .. |
|---|
| 2134 | 2121 | dum_hcd->port_status &= ~USB_PORT_STAT_POWER; |
|---|
| 2135 | 2122 | set_link_state(dum_hcd); |
|---|
| 2136 | 2123 | break; |
|---|
| 2137 | | - default: |
|---|
| 2124 | + case USB_PORT_FEAT_ENABLE: |
|---|
| 2125 | + case USB_PORT_FEAT_C_ENABLE: |
|---|
| 2126 | + case USB_PORT_FEAT_C_SUSPEND: |
|---|
| 2127 | + /* Not allowed for USB-3 */ |
|---|
| 2128 | + if (hcd->speed == HCD_USB3) |
|---|
| 2129 | + goto error; |
|---|
| 2130 | + fallthrough; |
|---|
| 2131 | + case USB_PORT_FEAT_C_CONNECTION: |
|---|
| 2132 | + case USB_PORT_FEAT_C_RESET: |
|---|
| 2138 | 2133 | dum_hcd->port_status &= ~(1 << wValue); |
|---|
| 2139 | 2134 | set_link_state(dum_hcd); |
|---|
| 2135 | + break; |
|---|
| 2136 | + default: |
|---|
| 2137 | + /* Disallow INDICATOR and C_OVER_CURRENT */ |
|---|
| 2138 | + goto error; |
|---|
| 2140 | 2139 | } |
|---|
| 2141 | 2140 | break; |
|---|
| 2142 | 2141 | case GetHubDescriptor: |
|---|
| .. | .. |
|---|
| 2272 | 2271 | "supported for USB 2.0 roothub\n"); |
|---|
| 2273 | 2272 | goto error; |
|---|
| 2274 | 2273 | } |
|---|
| 2275 | | - /* FALLS THROUGH */ |
|---|
| 2274 | + fallthrough; |
|---|
| 2276 | 2275 | case USB_PORT_FEAT_RESET: |
|---|
| 2276 | + if (!(dum_hcd->port_status & USB_PORT_STAT_CONNECTION)) |
|---|
| 2277 | + break; |
|---|
| 2277 | 2278 | /* if it's already enabled, disable */ |
|---|
| 2278 | 2279 | if (hcd->speed == HCD_USB3) { |
|---|
| 2279 | | - dum_hcd->port_status = 0; |
|---|
| 2280 | 2280 | dum_hcd->port_status = |
|---|
| 2281 | 2281 | (USB_SS_PORT_STAT_POWER | |
|---|
| 2282 | 2282 | USB_PORT_STAT_CONNECTION | |
|---|
| 2283 | 2283 | USB_PORT_STAT_RESET); |
|---|
| 2284 | | - } else |
|---|
| 2284 | + } else { |
|---|
| 2285 | 2285 | dum_hcd->port_status &= ~(USB_PORT_STAT_ENABLE |
|---|
| 2286 | 2286 | | USB_PORT_STAT_LOW_SPEED |
|---|
| 2287 | 2287 | | USB_PORT_STAT_HIGH_SPEED); |
|---|
| 2288 | + dum_hcd->port_status |= USB_PORT_STAT_RESET; |
|---|
| 2289 | + } |
|---|
| 2288 | 2290 | /* |
|---|
| 2289 | 2291 | * We want to reset device status. All but the |
|---|
| 2290 | 2292 | * Self powered feature |
|---|
| .. | .. |
|---|
| 2296 | 2298 | * interval? Is it still 50msec as for HS? |
|---|
| 2297 | 2299 | */ |
|---|
| 2298 | 2300 | dum_hcd->re_timeout = jiffies + msecs_to_jiffies(50); |
|---|
| 2299 | | - /* FALLS THROUGH */ |
|---|
| 2300 | | - default: |
|---|
| 2301 | | - if (hcd->speed == HCD_USB3) { |
|---|
| 2302 | | - if ((dum_hcd->port_status & |
|---|
| 2303 | | - USB_SS_PORT_STAT_POWER) != 0) { |
|---|
| 2304 | | - dum_hcd->port_status |= (1 << wValue); |
|---|
| 2305 | | - } |
|---|
| 2306 | | - } else |
|---|
| 2307 | | - if ((dum_hcd->port_status & |
|---|
| 2308 | | - USB_PORT_STAT_POWER) != 0) { |
|---|
| 2309 | | - dum_hcd->port_status |= (1 << wValue); |
|---|
| 2310 | | - } |
|---|
| 2311 | 2301 | set_link_state(dum_hcd); |
|---|
| 2302 | + break; |
|---|
| 2303 | + case USB_PORT_FEAT_C_CONNECTION: |
|---|
| 2304 | + case USB_PORT_FEAT_C_RESET: |
|---|
| 2305 | + case USB_PORT_FEAT_C_ENABLE: |
|---|
| 2306 | + case USB_PORT_FEAT_C_SUSPEND: |
|---|
| 2307 | + /* Not allowed for USB-3, and ignored for USB-2 */ |
|---|
| 2308 | + if (hcd->speed == HCD_USB3) |
|---|
| 2309 | + goto error; |
|---|
| 2310 | + break; |
|---|
| 2311 | + default: |
|---|
| 2312 | + /* Disallow TEST, INDICATOR, and C_OVER_CURRENT */ |
|---|
| 2313 | + goto error; |
|---|
| 2312 | 2314 | } |
|---|
| 2313 | 2315 | break; |
|---|
| 2314 | 2316 | case GetPortErrorCount: |
|---|
| .. | .. |
|---|
| 2471 | 2473 | struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd); |
|---|
| 2472 | 2474 | |
|---|
| 2473 | 2475 | /* |
|---|
| 2474 | | - * MASTER side init ... we emulate a root hub that'll only ever |
|---|
| 2475 | | - * talk to one device (the slave side). Also appears in sysfs, |
|---|
| 2476 | + * HOST side init ... we emulate a root hub that'll only ever |
|---|
| 2477 | + * talk to one device (the gadget side). Also appears in sysfs, |
|---|
| 2476 | 2478 | * just like more familiar pci-based HCDs. |
|---|
| 2477 | 2479 | */ |
|---|
| 2478 | 2480 | if (!usb_hcd_is_primary_hcd(hcd)) |
|---|
| .. | .. |
|---|
| 2741 | 2743 | .suspend = dummy_hcd_suspend, |
|---|
| 2742 | 2744 | .resume = dummy_hcd_resume, |
|---|
| 2743 | 2745 | .driver = { |
|---|
| 2744 | | - .name = (char *) driver_name, |
|---|
| 2746 | + .name = driver_name, |
|---|
| 2745 | 2747 | }, |
|---|
| 2746 | 2748 | }; |
|---|
| 2747 | 2749 | |
|---|