A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

usb: introduce new control request API

Change-Id: I6545d8985ab683c026f28f6a7c0e23b40d0a6506

+168 -14
+144
docs/usb-api.md
··· 1 + Handling USB control requests 2 + ============================= 3 + 4 + API overview 5 + ------------ 6 + 7 + enum usb_control_response { 8 + USB_CONTROL_ACK, 9 + USB_CONTROL_STALL, 10 + USB_CONTROL_RECEIVE, 11 + }; 12 + 13 + void usb_core_control_request(struct usb_ctrlrequest* req, void* reqdata); 14 + void usb_core_control_complete(int status); 15 + void usb_drv_control_response(enum usb_control_response resp, 16 + void* data, int length); 17 + 18 + The two `usb_core` functions are common to all targets with a USB stack and 19 + are implemented in `usb_core.c`. The USB driver calls them to inform the core 20 + when a control request arrives or is completed. 21 + 22 + Each USB driver implements `usb_drv_control_response()`. The core calls this 23 + to let the driver know how to respond to each control request. 24 + 25 + ### Legacy API 26 + 27 + void usb_core_legacy_control_request(struct usb_ctrlrequest* req); 28 + 29 + The old control request API is available through this function. Drivers which 30 + don't yet implement the new API can use the legacy API instead. To support 31 + legacy drivers, the USB core implements all functions in the new API and 32 + emulates the old control request handling behavior, bugs included. 33 + 34 + This is intended as a stopgap measure so that old drivers keep working as-is. 35 + The core can start using the new API right away, and drivers can be ported 36 + one-by-one as time allows. Once all drivers are ported to the new API, all 37 + legacy driver support can be removed. 38 + 39 + Request handling process 40 + ------------------------ 41 + 42 + The driver submits control requests to the USB core one at a time. Once a 43 + request is submitted, it must be completed before the next request can be 44 + submitted. This mirrors normal USB operation. 45 + 46 + When the USB driver receives a setup packet from the host, it submits it 47 + to the core to begin handling the control transfer. The driver calls 48 + `usb_core_control_request(req, NULL)`, passing the setup packet in `req`. 49 + The second argument, `reqdata`, is not used at this time and is passed 50 + as `NULL`. 51 + 52 + The core processes the setup packet and calls `usb_drv_control_response()` 53 + when it's done. The allowed responses depend on the type of control transfer 54 + being processed. 55 + 56 + ### Non-data transfers 57 + 58 + - `USB_CONTROL_ACK`, to indicate the request was processed successfully. 59 + - `USB_CONTROL_STALL`, if the request is unsupported or cannot be processed. 60 + 61 + ### Control read transfers 62 + 63 + - `USB_CONTROL_ACK`, to indicate the request was processed successfully. 64 + The core must provide a valid `data` buffer with `length` not exceeding 65 + the `wLength` field in the setup packet; otherwise, driver behavior is 66 + undefined. The driver will transfer this data to the host during the 67 + data phase of the control transfer, and then acknowledge the host's OUT 68 + packet to complete the transfer successfully. 69 + - `USB_CONTROL_STALL`, if the request is unsupported or cannot be processed. 70 + 71 + ### Control write transfers 72 + 73 + The driver calls `usb_core_control_request()` twice to handle control writes. 74 + The first call allows the core to handle the setup packet, and if the core 75 + decides to accept the data phase, the second call is made when the data has 76 + been received without error. 77 + 78 + #### Setup phase 79 + 80 + The first call is made at the end of the setup phase, after receiving the 81 + setup packet. The driver passes `reqdata = NULL` to indicate this. 82 + 83 + The core can decide whether it wants to receive the data phase: 84 + 85 + - `USB_CONTROL_RECEIVE`, if the core wishes to continue to the data phase. 86 + The core must provide a valid `data` buffer with `length` greater than or 87 + equal to the `wLength` specified in the setup packet; otherwise, driver 88 + behavior is undefined. The driver will proceed to the data phase and store 89 + received data into the provided buffer. 90 + - `USB_CONTROL_STALL`, if the request is unsupported or cannot be processed. 91 + 92 + If the core accepts the data phase, the driver will re-submit the request 93 + when the data phase is completed correctly. If any error occurs during the 94 + data phase, the driver will not re-submit the request; instead, it will 95 + call `usb_core_control_complete()` with a non-zero status code. 96 + 97 + #### Status phase 98 + 99 + The second call to `usb_core_control_request()` is made at the end of the data 100 + phase. The `reqdata` passed by the driver is the same one that the core passed 101 + in its `USB_CONTROL_RECEIVE` response. 102 + 103 + The core's allowed responses are: 104 + 105 + - `USB_CONTROL_ACK`, to indicate the request was processed successfully. 106 + - `USB_CONTROL_STALL`, if the request is unsupported or cannot be processed. 107 + 108 + ### Request completion 109 + 110 + The driver will notify the core when a request has completed by calling 111 + `usb_core_control_complete()`. A status code of zero means the request was 112 + completed successfully; a non-zero code means it failed. Note that failure 113 + can occur even if the request was successful from the core's perspective. 114 + 115 + If the core response is `USB_CONTROL_STALL` at any point, the request is 116 + considered complete. In this case, the driver won't deliver a completion 117 + notification because it would be redundant. 118 + 119 + The driver may only complete a request after the core has provided a response 120 + to any pending `usb_core_control_request()` call. Specifically, if the core 121 + has not yet responded to a request, the driver needs to defer the completion 122 + notification until it sees the core's response. If the core's response is a 123 + stall, then the notification should be silently dropped. 124 + 125 + ### Notes 126 + 127 + - Driver behavior is undefined if the core makes an inappropriate response 128 + to a request, for example, responding with `USB_CONTROL_ACK` in the setup 129 + phase of a control write or `USB_CONTROL_RECEIVE` to a non-data request. 130 + The only permissible responses are the documented ones. 131 + 132 + - If a response requires a buffer, then `data` must be non-NULL unless the 133 + `length` is also zero. If a buffer is not required, the core must pass 134 + `data = NULL` and `length = 0`. Otherwise, driver behavior is undefined. 135 + There are two responses which require a buffer: 136 + + `USB_CONTROL_ACK` to a control read 137 + + `USB_CONTROL_RECEIVE` to the setup phase of a control write 138 + 139 + - Drivers must be prepared to accept a setup packet at any time, including 140 + in the middle of a control request. In such a case, devices are required 141 + to abort the ongoing request and start handling the new request. (This is 142 + intended as an error recovery mechanism and should not be abused by hosts 143 + in normal operation.) The driver must take care to notify the core of the 144 + current request's failure, and then submit the new request.
+1 -1
firmware/drivers/isp1583.c
··· 341 341 if (len == 8) 342 342 { 343 343 ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_STATUS; /* Acknowledge packet */ 344 - usb_core_control_request((struct usb_ctrlrequest*)setup_pkt_buf); 344 + usb_core_legacy_control_request((struct usb_ctrlrequest*)setup_pkt_buf); 345 345 } 346 346 else 347 347 {
+1 -1
firmware/drivers/m66591.c
··· 208 208 /* acknowledge packet recieved (clear valid) */ 209 209 M66591_INTSTAT_MAIN &= ~(1<<3); 210 210 211 - usb_core_control_request(&temp); 211 + usb_core_legacy_control_request(&temp); 212 212 } 213 213 214 214 /* This is a helper function, it is used to notife the stack that a transfer is
+1 -1
firmware/drivers/usb-designware.c
··· 741 741 && (usb_ctrlsetup.bRequest == USB_REQ_SET_ADDRESS)) 742 742 usb_dw_set_address(usb_ctrlsetup.wValue); 743 743 744 - usb_core_control_request(&usb_ctrlsetup); 744 + usb_core_legacy_control_request(&usb_ctrlsetup); 745 745 } 746 746 747 747 static void usb_dw_abort_endpoint(int epnum, enum usb_dw_epdir epdir)
+3 -1
firmware/export/usb_core.h
··· 51 51 52 52 void usb_core_init(void); 53 53 void usb_core_exit(void); 54 - void usb_core_control_request(struct usb_ctrlrequest* req); 54 + void usb_core_control_request(struct usb_ctrlrequest* req, void* data); 55 + void usb_core_control_complete(int status); 56 + void usb_core_legacy_control_request(struct usb_ctrlrequest* req); 55 57 void usb_core_transfer_complete(int endpoint,int dir,int status,int length); 56 58 void usb_core_bus_reset(void); 57 59 bool usb_core_any_exclusive_storage(void);
+8
firmware/export/usb_drv.h
··· 56 56 * -> usb_drv_int_enable(false) [ditto] 57 57 * -> soc specific controller/clock deinit */ 58 58 59 + enum usb_control_response { 60 + USB_CONTROL_ACK, 61 + USB_CONTROL_STALL, 62 + USB_CONTROL_RECEIVE, 63 + }; 64 + 59 65 /* one-time initialisation of the USB driver */ 60 66 void usb_drv_startup(void); 61 67 void usb_drv_int_enable(bool enable); /* Target implemented */ ··· 69 75 int usb_drv_send(int endpoint, void* ptr, int length); 70 76 int usb_drv_send_nonblocking(int endpoint, void* ptr, int length); 71 77 int usb_drv_recv_nonblocking(int endpoint, void* ptr, int length); 78 + void usb_drv_control_response(enum usb_control_response resp, 79 + void* data, int length); 72 80 void usb_drv_set_address(int address); 73 81 void usb_drv_reset_endpoint(int endpoint, bool send); 74 82 bool usb_drv_powered(void);
+2 -2
firmware/target/arm/as3525/usb-drv-as3525.c
··· 655 655 req->wIndex, 656 656 req->wLength); 657 657 658 - usb_core_control_request(&req_copy); 658 + usb_core_legacy_control_request(&req_copy); 659 659 setup_desc_init(setup_desc); 660 660 661 661 ep_sts &= ~USB_EP_STAT_SETUP_RCVD; ··· 760 760 got_set_configuration = 1; 761 761 762 762 set_config.wValue = USB_DEV_STS & USB_DEV_STS_MASK_CFG; 763 - usb_core_control_request(&set_config); 763 + usb_core_legacy_control_request(&set_config); 764 764 intr &= ~USB_DEV_INTR_SET_CONFIG; 765 765 } 766 766 if (intr & USB_DEV_INTR_EARLY_SUSPEND) {/* idle >3ms detected */
+1 -1
firmware/target/arm/rk27xx/usb-drv-rk27xx.c
··· 117 117 setup_data[1] = SETUP2; 118 118 119 119 /* pass setup data to the upper layer */ 120 - usb_core_control_request((struct usb_ctrlrequest*)setup_data); 120 + usb_core_legacy_control_request((struct usb_ctrlrequest*)setup_data); 121 121 } 122 122 123 123 static int max_pkt_size(struct endpoint_t *endp)
+1 -1
firmware/target/arm/tms320dm320/sansa-connect/tnetv105_usb_drv.c
··· 1181 1181 } 1182 1182 1183 1183 /* Process control packet */ 1184 - usb_core_control_request(&setup); 1184 + usb_core_legacy_control_request(&setup); 1185 1185 } 1186 1186 1187 1187 if (sysIntrStatus.f.ep0_in_ack)
+1 -1
firmware/target/arm/usb-drv-arc.c
··· 877 877 } 878 878 } 879 879 880 - usb_core_control_request((struct usb_ctrlrequest*)tmp); 880 + usb_core_legacy_control_request((struct usb_ctrlrequest*)tmp); 881 881 } 882 882 883 883 static void transfer_completed(void)
+1 -1
firmware/target/arm/usb-s3c6400x.c
··· 522 522 ep0_setup_pkt->bRequest == USB_REQ_SET_ADDRESS) 523 523 DCFG = (DCFG & ~bitm(DCFG, devadr)) | (ep0_setup_pkt->wValue << DCFG_devadr_bitp); 524 524 525 - usb_core_control_request(ep0_setup_pkt); 525 + usb_core_legacy_control_request(ep0_setup_pkt); 526 526 } 527 527 } 528 528
+1 -1
firmware/target/arm/usb-tcc.c
··· 251 251 DEBUG(2, "req: %02x %02d", req->bRequestType, req->bRequest); 252 252 } 253 253 254 - usb_core_control_request(req); 254 + usb_core_legacy_control_request(req); 255 255 } 256 256 257 257 static
+1 -1
firmware/target/mips/ingenic_jz47xx/usb-jz4740.c
··· 239 239 { 240 240 readFIFO(ep_recv, REG_USB_REG_COUNT0); 241 241 REG_USB_REG_CSR0 = csr0 | USB_CSR0_SVDOUTPKTRDY; /* clear OUTPKTRDY bit */ 242 - usb_core_control_request((struct usb_ctrlrequest*)ep_recv->buf); 242 + usb_core_legacy_control_request((struct usb_ctrlrequest*)ep_recv->buf); 243 243 } 244 244 } 245 245
+1 -1
firmware/target/mips/ingenic_jz47xx/usb-jz4760.c
··· 335 335 ep0_data_requested = true; 336 336 else ep0_data_supplied = true; 337 337 REG_USB_CSR0 = csr0; 338 - usb_core_control_request(&ep0_rx.request); 338 + usb_core_legacy_control_request(&ep0_rx.request); 339 339 ep_transfer_completed(ep_recv); 340 340 } 341 341 }
+1 -1
firmware/usbstack/usb_core.c
··· 977 977 } 978 978 979 979 /* called by usb_drv_int() */ 980 - void usb_core_control_request(struct usb_ctrlrequest* req) 980 + void usb_core_legacy_control_request(struct usb_ctrlrequest* req) 981 981 { 982 982 struct usb_transfer_completion_event_data* completion_event = 983 983 &ep_data[EP_CONTROL].completion_event[EP_DIR(USB_DIR_IN)];