.. | .. |
---|
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 | |
---|