diff options
author | Aidan MacDonald <amachronic@protonmail.com> | 2021-09-19 11:44:38 +0100 |
---|---|---|
committer | Aidan MacDonald <amachronic@protonmail.com> | 2021-10-16 15:58:43 -0400 |
commit | ec164c389c99d8129f9d6cacda2731bde9b08257 (patch) | |
tree | 224a2f675de8e6ce82f179b38cbe44326db30ddd | |
parent | 71cc1e78fd81818428cbd1b55fcf096979b529ef (diff) | |
download | rockbox-ec164c389c99d8129f9d6cacda2731bde9b08257.tar.gz rockbox-ec164c389c99d8129f9d6cacda2731bde9b08257.zip |
usb: introduce new control request API
Change-Id: I6545d8985ab683c026f28f6a7c0e23b40d0a6506
-rw-r--r-- | docs/usb-api.md | 144 | ||||
-rw-r--r-- | firmware/drivers/isp1583.c | 2 | ||||
-rw-r--r-- | firmware/drivers/m66591.c | 2 | ||||
-rw-r--r-- | firmware/drivers/usb-designware.c | 2 | ||||
-rw-r--r-- | firmware/export/usb_core.h | 4 | ||||
-rw-r--r-- | firmware/export/usb_drv.h | 8 | ||||
-rw-r--r-- | firmware/target/arm/as3525/usb-drv-as3525.c | 4 | ||||
-rw-r--r-- | firmware/target/arm/rk27xx/usb-drv-rk27xx.c | 2 | ||||
-rw-r--r-- | firmware/target/arm/tms320dm320/sansa-connect/tnetv105_usb_drv.c | 2 | ||||
-rw-r--r-- | firmware/target/arm/usb-drv-arc.c | 2 | ||||
-rw-r--r-- | firmware/target/arm/usb-s3c6400x.c | 2 | ||||
-rw-r--r-- | firmware/target/arm/usb-tcc.c | 2 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/usb-jz4740.c | 2 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/usb-jz4760.c | 2 | ||||
-rw-r--r-- | firmware/usbstack/usb_core.c | 2 |
15 files changed, 168 insertions, 14 deletions
diff --git a/docs/usb-api.md b/docs/usb-api.md new file mode 100644 index 0000000000..a21d6fd703 --- /dev/null +++ b/docs/usb-api.md | |||
@@ -0,0 +1,144 @@ | |||
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. | ||
diff --git a/firmware/drivers/isp1583.c b/firmware/drivers/isp1583.c index 18a4e9c720..e60339d9fc 100644 --- a/firmware/drivers/isp1583.c +++ b/firmware/drivers/isp1583.c | |||
@@ -341,7 +341,7 @@ static void usb_handle_setup_rx(void) | |||
341 | if (len == 8) | 341 | if (len == 8) |
342 | { | 342 | { |
343 | ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_STATUS; /* Acknowledge packet */ | 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 | else | 346 | else |
347 | { | 347 | { |
diff --git a/firmware/drivers/m66591.c b/firmware/drivers/m66591.c index 5da1908290..822585d882 100644 --- a/firmware/drivers/m66591.c +++ b/firmware/drivers/m66591.c | |||
@@ -208,7 +208,7 @@ static void control_received(void) { | |||
208 | /* acknowledge packet recieved (clear valid) */ | 208 | /* acknowledge packet recieved (clear valid) */ |
209 | M66591_INTSTAT_MAIN &= ~(1<<3); | 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 | /* This is a helper function, it is used to notife the stack that a transfer is | 214 | /* This is a helper function, it is used to notife the stack that a transfer is |
diff --git a/firmware/drivers/usb-designware.c b/firmware/drivers/usb-designware.c index ab4c6037b5..58b6a75180 100644 --- a/firmware/drivers/usb-designware.c +++ b/firmware/drivers/usb-designware.c | |||
@@ -741,7 +741,7 @@ static void usb_dw_handle_setup_received(void) | |||
741 | && (usb_ctrlsetup.bRequest == USB_REQ_SET_ADDRESS)) | 741 | && (usb_ctrlsetup.bRequest == USB_REQ_SET_ADDRESS)) |
742 | usb_dw_set_address(usb_ctrlsetup.wValue); | 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 | static void usb_dw_abort_endpoint(int epnum, enum usb_dw_epdir epdir) | 747 | static void usb_dw_abort_endpoint(int epnum, enum usb_dw_epdir epdir) |
diff --git a/firmware/export/usb_core.h b/firmware/export/usb_core.h index 78a80435e1..fe1f7459cf 100644 --- a/firmware/export/usb_core.h +++ b/firmware/export/usb_core.h | |||
@@ -51,7 +51,9 @@ struct usb_class_driver; | |||
51 | 51 | ||
52 | void usb_core_init(void); | 52 | void usb_core_init(void); |
53 | void usb_core_exit(void); | 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 | void usb_core_transfer_complete(int endpoint,int dir,int status,int length); | 57 | void usb_core_transfer_complete(int endpoint,int dir,int status,int length); |
56 | void usb_core_bus_reset(void); | 58 | void usb_core_bus_reset(void); |
57 | bool usb_core_any_exclusive_storage(void); | 59 | bool usb_core_any_exclusive_storage(void); |
diff --git a/firmware/export/usb_drv.h b/firmware/export/usb_drv.h index 01535c2786..3ef4db3c9c 100644 --- a/firmware/export/usb_drv.h +++ b/firmware/export/usb_drv.h | |||
@@ -56,6 +56,12 @@ | |||
56 | * -> usb_drv_int_enable(false) [ditto] | 56 | * -> usb_drv_int_enable(false) [ditto] |
57 | * -> soc specific controller/clock deinit */ | 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 | /* one-time initialisation of the USB driver */ | 65 | /* one-time initialisation of the USB driver */ |
60 | void usb_drv_startup(void); | 66 | void usb_drv_startup(void); |
61 | void usb_drv_int_enable(bool enable); /* Target implemented */ | 67 | void usb_drv_int_enable(bool enable); /* Target implemented */ |
@@ -69,6 +75,8 @@ bool usb_drv_stalled(int endpoint,bool in); | |||
69 | int usb_drv_send(int endpoint, void* ptr, int length); | 75 | int usb_drv_send(int endpoint, void* ptr, int length); |
70 | int usb_drv_send_nonblocking(int endpoint, void* ptr, int length); | 76 | int usb_drv_send_nonblocking(int endpoint, void* ptr, int length); |
71 | int usb_drv_recv_nonblocking(int endpoint, void* ptr, int length); | 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 | void usb_drv_set_address(int address); | 80 | void usb_drv_set_address(int address); |
73 | void usb_drv_reset_endpoint(int endpoint, bool send); | 81 | void usb_drv_reset_endpoint(int endpoint, bool send); |
74 | bool usb_drv_powered(void); | 82 | bool usb_drv_powered(void); |
diff --git a/firmware/target/arm/as3525/usb-drv-as3525.c b/firmware/target/arm/as3525/usb-drv-as3525.c index 8369edc400..d0875ed48c 100644 --- a/firmware/target/arm/as3525/usb-drv-as3525.c +++ b/firmware/target/arm/as3525/usb-drv-as3525.c | |||
@@ -655,7 +655,7 @@ static void handle_out_ep(int ep) | |||
655 | req->wIndex, | 655 | req->wIndex, |
656 | req->wLength); | 656 | req->wLength); |
657 | 657 | ||
658 | usb_core_control_request(&req_copy); | 658 | usb_core_legacy_control_request(&req_copy); |
659 | setup_desc_init(setup_desc); | 659 | setup_desc_init(setup_desc); |
660 | 660 | ||
661 | ep_sts &= ~USB_EP_STAT_SETUP_RCVD; | 661 | ep_sts &= ~USB_EP_STAT_SETUP_RCVD; |
@@ -760,7 +760,7 @@ void INT_USB_FUNC(void) | |||
760 | got_set_configuration = 1; | 760 | got_set_configuration = 1; |
761 | 761 | ||
762 | set_config.wValue = USB_DEV_STS & USB_DEV_STS_MASK_CFG; | 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 | intr &= ~USB_DEV_INTR_SET_CONFIG; | 764 | intr &= ~USB_DEV_INTR_SET_CONFIG; |
765 | } | 765 | } |
766 | if (intr & USB_DEV_INTR_EARLY_SUSPEND) {/* idle >3ms detected */ | 766 | if (intr & USB_DEV_INTR_EARLY_SUSPEND) {/* idle >3ms detected */ |
diff --git a/firmware/target/arm/rk27xx/usb-drv-rk27xx.c b/firmware/target/arm/rk27xx/usb-drv-rk27xx.c index aac271c47a..77860b5494 100644 --- a/firmware/target/arm/rk27xx/usb-drv-rk27xx.c +++ b/firmware/target/arm/rk27xx/usb-drv-rk27xx.c | |||
@@ -117,7 +117,7 @@ static void setup_received(void) | |||
117 | setup_data[1] = SETUP2; | 117 | setup_data[1] = SETUP2; |
118 | 118 | ||
119 | /* pass setup data to the upper layer */ | 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 | static int max_pkt_size(struct endpoint_t *endp) | 123 | static int max_pkt_size(struct endpoint_t *endp) |
diff --git a/firmware/target/arm/tms320dm320/sansa-connect/tnetv105_usb_drv.c b/firmware/target/arm/tms320dm320/sansa-connect/tnetv105_usb_drv.c index f1acc9c964..e5a9000f40 100644 --- a/firmware/target/arm/tms320dm320/sansa-connect/tnetv105_usb_drv.c +++ b/firmware/target/arm/tms320dm320/sansa-connect/tnetv105_usb_drv.c | |||
@@ -1181,7 +1181,7 @@ void VLYNQ(void) | |||
1181 | } | 1181 | } |
1182 | 1182 | ||
1183 | /* Process control packet */ | 1183 | /* Process control packet */ |
1184 | usb_core_control_request(&setup); | 1184 | usb_core_legacy_control_request(&setup); |
1185 | } | 1185 | } |
1186 | 1186 | ||
1187 | if (sysIntrStatus.f.ep0_in_ack) | 1187 | if (sysIntrStatus.f.ep0_in_ack) |
diff --git a/firmware/target/arm/usb-drv-arc.c b/firmware/target/arm/usb-drv-arc.c index 4c53108f12..22751f27f0 100644 --- a/firmware/target/arm/usb-drv-arc.c +++ b/firmware/target/arm/usb-drv-arc.c | |||
@@ -877,7 +877,7 @@ static void control_received(void) | |||
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 | static void transfer_completed(void) | 883 | static void transfer_completed(void) |
diff --git a/firmware/target/arm/usb-s3c6400x.c b/firmware/target/arm/usb-s3c6400x.c index 71d04e6f2a..0f3ecf8c00 100644 --- a/firmware/target/arm/usb-s3c6400x.c +++ b/firmware/target/arm/usb-s3c6400x.c | |||
@@ -522,7 +522,7 @@ static void handle_ep_int(int ep, bool out) | |||
522 | ep0_setup_pkt->bRequest == USB_REQ_SET_ADDRESS) | 522 | ep0_setup_pkt->bRequest == USB_REQ_SET_ADDRESS) |
523 | DCFG = (DCFG & ~bitm(DCFG, devadr)) | (ep0_setup_pkt->wValue << DCFG_devadr_bitp); | 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 | ||
diff --git a/firmware/target/arm/usb-tcc.c b/firmware/target/arm/usb-tcc.c index 8ce75b6764..53f101c471 100644 --- a/firmware/target/arm/usb-tcc.c +++ b/firmware/target/arm/usb-tcc.c | |||
@@ -251,7 +251,7 @@ void handle_control(void) | |||
251 | DEBUG(2, "req: %02x %02d", req->bRequestType, req->bRequest); | 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 | static | 257 | static |
diff --git a/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c b/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c index 8d04c54a68..07d24be380 100644 --- a/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c | |||
@@ -239,7 +239,7 @@ static void EP0_handler(void) | |||
239 | { | 239 | { |
240 | readFIFO(ep_recv, REG_USB_REG_COUNT0); | 240 | readFIFO(ep_recv, REG_USB_REG_COUNT0); |
241 | REG_USB_REG_CSR0 = csr0 | USB_CSR0_SVDOUTPKTRDY; /* clear OUTPKTRDY bit */ | 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 | ||
diff --git a/firmware/target/mips/ingenic_jz47xx/usb-jz4760.c b/firmware/target/mips/ingenic_jz47xx/usb-jz4760.c index 5dbf9455e3..6db4a25d5c 100644 --- a/firmware/target/mips/ingenic_jz47xx/usb-jz4760.c +++ b/firmware/target/mips/ingenic_jz47xx/usb-jz4760.c | |||
@@ -335,7 +335,7 @@ static void EP0_handler(void) | |||
335 | ep0_data_requested = true; | 335 | ep0_data_requested = true; |
336 | else ep0_data_supplied = true; | 336 | else ep0_data_supplied = true; |
337 | REG_USB_CSR0 = csr0; | 337 | REG_USB_CSR0 = csr0; |
338 | usb_core_control_request(&ep0_rx.request); | 338 | usb_core_legacy_control_request(&ep0_rx.request); |
339 | ep_transfer_completed(ep_recv); | 339 | ep_transfer_completed(ep_recv); |
340 | } | 340 | } |
341 | } | 341 | } |
diff --git a/firmware/usbstack/usb_core.c b/firmware/usbstack/usb_core.c index 50d93f7561..1f17872ba8 100644 --- a/firmware/usbstack/usb_core.c +++ b/firmware/usbstack/usb_core.c | |||
@@ -977,7 +977,7 @@ void usb_core_handle_notify(long id, intptr_t data) | |||
977 | } | 977 | } |
978 | 978 | ||
979 | /* called by usb_drv_int() */ | 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 | struct usb_transfer_completion_event_data* completion_event = | 982 | struct usb_transfer_completion_event_data* completion_event = |
983 | &ep_data[EP_CONTROL].completion_event[EP_DIR(USB_DIR_IN)]; | 983 | &ep_data[EP_CONTROL].completion_event[EP_DIR(USB_DIR_IN)]; |