]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbio.c
Initial import.
[mirror_edk2.git] / EdkModulePkg / Bus / Usb / UsbBus / Dxe / usbio.c
CommitLineData
878ddf1f 1/*++\r
2\r
3Copyright (c) 2006, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12 Module Name:\r
13\r
14 UsbIo.c\r
15\r
16 Abstract:\r
17\r
18 USB I/O Abstraction Driver\r
19\r
20 Revision History\r
21\r
22--*/\r
23\r
24#include "usbbus.h"\r
25\r
26//\r
27// USB I/O Support Function Prototypes\r
28//\r
29STATIC\r
30EFI_STATUS\r
31EFIAPI\r
32UsbControlTransfer (\r
33 IN EFI_USB_IO_PROTOCOL *This,\r
34 IN EFI_USB_DEVICE_REQUEST *Request,\r
35 IN EFI_USB_DATA_DIRECTION Direction,\r
36 IN UINT32 Timeout,\r
37 IN OUT VOID *Data, OPTIONAL\r
38 IN UINTN DataLength, OPTIONAL\r
39 OUT UINT32 *Status\r
40 );\r
41\r
42STATIC\r
43EFI_STATUS\r
44EFIAPI\r
45UsbBulkTransfer (\r
46 IN EFI_USB_IO_PROTOCOL *This,\r
47 IN UINT8 DeviceEndpoint,\r
48 IN OUT VOID *Data,\r
49 IN OUT UINTN *DataLength,\r
50 IN UINTN Timeout,\r
51 OUT UINT32 *Status\r
52 );\r
53\r
54STATIC\r
55EFI_STATUS\r
56EFIAPI\r
57UsbAsyncInterruptTransfer (\r
58 IN EFI_USB_IO_PROTOCOL * This,\r
59 IN UINT8 DeviceEndpoint,\r
60 IN BOOLEAN IsNewTransfer,\r
61 IN UINTN PollingInterval, OPTIONAL\r
62 IN UINTN DataLength, OPTIONAL\r
63 IN EFI_ASYNC_USB_TRANSFER_CALLBACK InterruptCallBack, OPTIONAL\r
64 IN VOID *Context OPTIONAL\r
65 );\r
66\r
67STATIC\r
68EFI_STATUS\r
69EFIAPI\r
70UsbSyncInterruptTransfer (\r
71 IN EFI_USB_IO_PROTOCOL *This,\r
72 IN UINT8 DeviceEndpoint,\r
73 IN OUT VOID *Data,\r
74 IN OUT UINTN *DataLength,\r
75 IN UINTN Timeout,\r
76 OUT UINT32 *Status\r
77 );\r
78\r
79STATIC\r
80EFI_STATUS\r
81EFIAPI\r
82UsbIsochronousTransfer (\r
83 IN EFI_USB_IO_PROTOCOL *This,\r
84 IN UINT8 DeviceEndpoint,\r
85 IN OUT VOID *Data,\r
86 IN UINTN DataLength,\r
87 OUT UINT32 *Status\r
88 );\r
89\r
90STATIC\r
91EFI_STATUS\r
92EFIAPI\r
93UsbAsyncIsochronousTransfer (\r
94 IN EFI_USB_IO_PROTOCOL * This,\r
95 IN UINT8 DeviceEndpoint,\r
96 IN OUT VOID *Data,\r
97 IN UINTN DataLength,\r
98 IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack,\r
99 IN VOID *Context OPTIONAL\r
100 );\r
101\r
102extern\r
103EFI_STATUS\r
104EFIAPI\r
105UsbPortReset (\r
106 IN EFI_USB_IO_PROTOCOL *This\r
107 );\r
108\r
109STATIC\r
110EFI_STATUS\r
111EFIAPI\r
112UsbGetDeviceDescriptor (\r
113 IN EFI_USB_IO_PROTOCOL *This,\r
114 OUT EFI_USB_DEVICE_DESCRIPTOR *DeviceDescriptor\r
115 );\r
116\r
117STATIC\r
118EFI_STATUS\r
119EFIAPI\r
120UsbGetActiveConfigDescriptor (\r
121 IN EFI_USB_IO_PROTOCOL *This,\r
122 OUT EFI_USB_CONFIG_DESCRIPTOR *ConfigurationDescriptor\r
123 );\r
124\r
125STATIC\r
126EFI_STATUS\r
127EFIAPI\r
128UsbGetInterfaceDescriptor (\r
129 IN EFI_USB_IO_PROTOCOL *This,\r
130 OUT EFI_USB_INTERFACE_DESCRIPTOR *InterfaceDescriptor\r
131 );\r
132\r
133STATIC\r
134EFI_STATUS\r
135EFIAPI\r
136UsbGetEndpointDescriptor (\r
137 IN EFI_USB_IO_PROTOCOL *This,\r
138 IN UINT8 EndpointIndex,\r
139 OUT EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDescriptor\r
140 );\r
141\r
142STATIC\r
143EFI_STATUS\r
144EFIAPI\r
145UsbGetStringDescriptor (\r
146 IN EFI_USB_IO_PROTOCOL *This,\r
147 IN UINT16 LangID,\r
148 IN UINT8 StringIndex,\r
149 OUT CHAR16 **String\r
150 );\r
151\r
152STATIC\r
153EFI_STATUS\r
154EFIAPI\r
155UsbGetSupportedLanguages (\r
156 IN EFI_USB_IO_PROTOCOL *This,\r
157 OUT UINT16 **LangIDTable,\r
158 OUT UINT16 *TableSize\r
159 );\r
160\r
161//\r
162// USB I/O Interface structure\r
163//\r
164STATIC EFI_USB_IO_PROTOCOL UsbIoInterface = {\r
165 UsbControlTransfer,\r
166 UsbBulkTransfer,\r
167 UsbAsyncInterruptTransfer,\r
168 UsbSyncInterruptTransfer,\r
169 UsbIsochronousTransfer,\r
170 UsbAsyncIsochronousTransfer,\r
171 UsbGetDeviceDescriptor,\r
172 UsbGetActiveConfigDescriptor,\r
173 UsbGetInterfaceDescriptor,\r
174 UsbGetEndpointDescriptor,\r
175 UsbGetStringDescriptor,\r
176 UsbGetSupportedLanguages,\r
177 UsbPortReset\r
178};\r
179\r
180VOID\r
181InitializeUsbIoInstance (\r
182 IN USB_IO_CONTROLLER_DEVICE *UsbIoController\r
183 )\r
184{\r
185 //\r
186 // Copy EFI_USB_IO protocol instance\r
187 //\r
188 CopyMem (\r
189 &UsbIoController->UsbIo,\r
190 &UsbIoInterface,\r
191 sizeof (EFI_USB_IO_PROTOCOL)\r
192 );\r
193}\r
194//\r
195// Implementation\r
196//\r
197STATIC\r
198EFI_STATUS\r
199EFIAPI\r
200UsbControlTransfer (\r
201 IN EFI_USB_IO_PROTOCOL *This,\r
202 IN EFI_USB_DEVICE_REQUEST *Request,\r
203 IN EFI_USB_DATA_DIRECTION Direction,\r
204 IN UINT32 Timeout,\r
205 IN OUT VOID *Data, OPTIONAL\r
206 IN UINTN DataLength, OPTIONAL\r
207 OUT UINT32 *Status\r
208 )\r
209/*++\r
210\r
211 Routine Description:\r
212 This function is used to manage a USB device with a control transfer pipe.\r
213\r
214 Arguments:\r
215 This - Indicates calling context.\r
216 Request - A pointer to the USB device request that will be sent to\r
217 the USB device.\r
218 Direction - Indicates the data direction.\r
219 Data - A pointer to the buffer of data that will be transmitted\r
220 to USB device or received from USB device.\r
221 Timeout - Indicates the transfer should be completed within this time\r
222 frame.\r
223 DataLength - The size, in bytes, of the data buffer specified by Data.\r
224 Status - A pointer to the result of the USB transfer.\r
225\r
226 Returns:\r
227 EFI_SUCCESS\r
228 EFI_INVALID_PARAMETER\r
229 EFI_OUT_OF_RESOURCES\r
230 EFI_TIMEOUT\r
231 EFI_DEVICE_ERROR\r
232\r
233--*/\r
234{\r
235 USB_IO_CONTROLLER_DEVICE *UsbIoController;\r
236 EFI_USB_HC_PROTOCOL *UsbHCInterface;\r
237 EFI_STATUS RetStatus;\r
238 USB_IO_DEVICE *UsbIoDevice;\r
239 UINT8 MaxPacketLength;\r
240 UINT32 TransferResult;\r
241 BOOLEAN Disconnected;\r
242 //\r
243 // Parameters Checking\r
244 //\r
245 if (Status == NULL) {\r
246 return EFI_INVALID_PARAMETER;\r
247 }\r
248 \r
249 //\r
250 // leave the HostController's ControlTransfer\r
251 // to perform other parameters checking\r
252 //\r
253 UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);\r
254 UsbIoDevice = UsbIoController->UsbDevice;\r
255 UsbHCInterface = UsbIoDevice->BusController->UsbHCInterface;\r
256 MaxPacketLength = UsbIoDevice->DeviceDescriptor.MaxPacketSize0;\r
257\r
258 \r
259 if (Request->Request == USB_DEV_CLEAR_FEATURE && \r
260 Request->RequestType == 0x02 && \r
261 Request->Value == EfiUsbEndpointHalt) {\r
262 //\r
263 //Reduce the remove delay time for system response\r
264 //\r
265 IsDeviceDisconnected (UsbIoController, &Disconnected);\r
266 if (!EFI_ERROR (Status) && Disconnected == TRUE) {\r
267 DEBUG ((gUSBErrorLevel, "Device is disconnected when trying reset\n"));\r
268 return EFI_DEVICE_ERROR;\r
269 }\r
270 }\r
271\r
272\r
273\r
274 //\r
275 // using HostController's ControlTransfer to complete the request\r
276 //\r
277 RetStatus = UsbHCInterface->ControlTransfer (\r
278 UsbHCInterface,\r
279 UsbIoDevice->DeviceAddress,\r
280 UsbIoDevice->IsSlowDevice,\r
281 MaxPacketLength,\r
282 Request,\r
283 Direction,\r
284 Data,\r
285 &DataLength,\r
286 (UINTN) Timeout,\r
287 &TransferResult\r
288 );\r
289 *Status = TransferResult;\r
290\r
291 if (Request->Request == USB_DEV_CLEAR_FEATURE && \r
292 Request->RequestType == 0x02 && \r
293 Request->Value == EfiUsbEndpointHalt) {\r
294 //\r
295 // This is a UsbClearEndpointHalt request\r
296 // Need to clear data toggle\r
297 // Request.Index == EndpointAddress\r
298 //\r
299 if (!EFI_ERROR (RetStatus) && TransferResult == EFI_USB_NOERROR) {\r
300 SetDataToggleBit (\r
301 This,\r
302 (UINT8) Request->Index,\r
303 0\r
304 );\r
305 }\r
306 }\r
307 return RetStatus;\r
308}\r
309\r
310STATIC\r
311EFI_STATUS\r
312EFIAPI\r
313UsbBulkTransfer (\r
314 IN EFI_USB_IO_PROTOCOL *This,\r
315 IN UINT8 DeviceEndpoint,\r
316 IN OUT VOID *Data,\r
317 IN OUT UINTN *DataLength,\r
318 IN UINTN Timeout,\r
319 OUT UINT32 *Status\r
320 )\r
321/*++\r
322\r
323 Routine Description:\r
324 This function is used to manage a USB device with the bulk transfer pipe.\r
325\r
326 Arguments:\r
327 This - Indicates calling context.\r
328 DeviceEndpoint - The destination USB device endpoint to which the device\r
329 request is being sent.\r
330 Data - A pointer to the buffer of data that will be transmitted\r
331 to USB device or received from USB device.\r
332 DataLength - On input, the size, in bytes, of the data buffer\r
333 specified by Data. On output, the number of bytes that\r
334 were actually transferred.\r
335 Timeout - Indicates the transfer should be completed within this\r
336 time frame.\r
337 Status - This parameter indicates the USB transfer status.\r
338\r
339 Returns:\r
340 EFI_SUCCESS\r
341 EFI_INVALID_PARAMETER\r
342 EFI_OUT_OF_RESOURCES\r
343 EFI_TIMEOUT\r
344 EFI_DEVICE_ERROR\r
345\r
346--*/\r
347{\r
348 USB_IO_DEVICE *UsbIoDev;\r
349 UINT8 MaxPacketLength;\r
350 UINT8 DataToggle;\r
351 UINT8 OldToggle;\r
352 EFI_STATUS RetStatus;\r
353 EFI_USB_HC_PROTOCOL *UsbHCInterface;\r
354 USB_IO_CONTROLLER_DEVICE *UsbIoController;\r
355 ENDPOINT_DESC_LIST_ENTRY *EndPointListEntry;\r
356 UINT32 TransferResult;\r
357\r
358 UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);\r
359 UsbIoDev = UsbIoController->UsbDevice;\r
360 UsbHCInterface = UsbIoDev->BusController->UsbHCInterface;\r
361\r
362 //\r
363 // Parameters Checking\r
364 //\r
365 if ((DeviceEndpoint & 0x7F) == 0) {\r
366 return EFI_INVALID_PARAMETER;\r
367 }\r
368\r
369 if ((DeviceEndpoint & 0x7F) > 15) {\r
370 return EFI_INVALID_PARAMETER;\r
371 }\r
372\r
373 if (Status == NULL) {\r
374 return EFI_INVALID_PARAMETER;\r
375 }\r
376\r
377 EndPointListEntry = FindEndPointListEntry (\r
378 This,\r
379 DeviceEndpoint\r
380 );\r
381\r
382 if (EndPointListEntry == NULL) {\r
383 return EFI_INVALID_PARAMETER;\r
384 }\r
385\r
386 if ((EndPointListEntry->EndpointDescriptor.Attributes & 0x03) != 0x02) {\r
387 return EFI_INVALID_PARAMETER;\r
388 }\r
389 \r
390 //\r
391 // leave the HostController's BulkTransfer\r
392 // to perform other parameters checking\r
393 //\r
394 GetDeviceEndPointMaxPacketLength (\r
395 This,\r
396 DeviceEndpoint,\r
397 &MaxPacketLength\r
398 );\r
399\r
400 GetDataToggleBit (\r
401 This,\r
402 DeviceEndpoint,\r
403 &DataToggle\r
404 );\r
405\r
406 OldToggle = DataToggle;\r
407\r
408 //\r
409 // using HostController's BulkTransfer to complete the request\r
410 //\r
411 RetStatus = UsbHCInterface->BulkTransfer (\r
412 UsbHCInterface,\r
413 UsbIoDev->DeviceAddress,\r
414 DeviceEndpoint,\r
415 MaxPacketLength,\r
416 Data,\r
417 DataLength,\r
418 &DataToggle,\r
419 Timeout,\r
420 &TransferResult\r
421 );\r
422\r
423 if (OldToggle != DataToggle) {\r
424 //\r
425 // Write the toggle back\r
426 //\r
427 SetDataToggleBit (\r
428 This,\r
429 DeviceEndpoint,\r
430 DataToggle\r
431 );\r
432 }\r
433\r
434 *Status = TransferResult;\r
435\r
436 return RetStatus;\r
437}\r
438\r
439STATIC\r
440EFI_STATUS\r
441EFIAPI\r
442UsbSyncInterruptTransfer (\r
443 IN EFI_USB_IO_PROTOCOL *This,\r
444 IN UINT8 DeviceEndpoint,\r
445 IN OUT VOID *Data,\r
446 IN OUT UINTN *DataLength,\r
447 IN UINTN Timeout,\r
448 OUT UINT32 *Status\r
449 )\r
450/*++\r
451\r
452 Routine Description:\r
453 Usb Sync Interrupt Transfer\r
454\r
455 Arguments:\r
456 This - Indicates calling context.\r
457 DeviceEndpoint - The destination USB device endpoint to which the device\r
458 request is being sent.\r
459 Data - A pointer to the buffer of data that will be transmitted\r
460 to USB device or received from USB device.\r
461 DataLength - On input, the size, in bytes, of the data buffer\r
462 specified by Data. On output, the number of bytes that\r
463 were actually transferred.\r
464 Timeout - Indicates the transfer should be completed within this\r
465 time frame.\r
466 Status - This parameter indicates the USB transfer status.\r
467\r
468 Returns:\r
469 EFI_SUCCESS\r
470 EFI_INVALID_PARAMETER\r
471 EFI_OUT_OF_RESOURCES\r
472 EFI_TIMEOUT\r
473 EFI_DEVICE_ERROR\r
474\r
475--*/\r
476{\r
477 USB_IO_DEVICE *UsbIoDev;\r
478 UINT8 MaxPacketLength;\r
479 UINT8 DataToggle;\r
480 UINT8 OldToggle;\r
481 EFI_STATUS RetStatus;\r
482 EFI_USB_HC_PROTOCOL *UsbHCInterface;\r
483 USB_IO_CONTROLLER_DEVICE *UsbIoController;\r
484 ENDPOINT_DESC_LIST_ENTRY *EndPointListEntry;\r
485\r
486 //\r
487 // Parameters Checking\r
488 //\r
489 if ((DeviceEndpoint & 0x7F) == 0) {\r
490 return EFI_INVALID_PARAMETER;\r
491 }\r
492\r
493 if ((DeviceEndpoint & 0x7F) > 15) {\r
494 return EFI_INVALID_PARAMETER;\r
495 }\r
496\r
497 if (Status == NULL) {\r
498 return EFI_INVALID_PARAMETER;\r
499 }\r
500\r
501 EndPointListEntry = FindEndPointListEntry (\r
502 This,\r
503 DeviceEndpoint\r
504 );\r
505\r
506 if (EndPointListEntry == NULL) {\r
507 return EFI_INVALID_PARAMETER;\r
508 }\r
509\r
510 if ((EndPointListEntry->EndpointDescriptor.Attributes & 0x03) != 0x03) {\r
511 return EFI_INVALID_PARAMETER;\r
512 }\r
513 \r
514 //\r
515 // leave the HostController's SyncInterruptTransfer\r
516 // to perform other parameters checking\r
517 //\r
518 UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);\r
519 UsbIoDev = UsbIoController->UsbDevice;\r
520 UsbHCInterface = UsbIoDev->BusController->UsbHCInterface;\r
521\r
522 GetDeviceEndPointMaxPacketLength (\r
523 This,\r
524 DeviceEndpoint,\r
525 &MaxPacketLength\r
526 );\r
527\r
528 GetDataToggleBit (\r
529 This,\r
530 DeviceEndpoint,\r
531 &DataToggle\r
532 );\r
533\r
534 OldToggle = DataToggle;\r
535 //\r
536 // using HostController's SyncInterruptTransfer to complete the request\r
537 //\r
538 RetStatus = UsbHCInterface->SyncInterruptTransfer (\r
539 UsbHCInterface,\r
540 UsbIoDev->DeviceAddress,\r
541 DeviceEndpoint,\r
542 UsbIoDev->IsSlowDevice,\r
543 MaxPacketLength,\r
544 Data,\r
545 DataLength,\r
546 &DataToggle,\r
547 Timeout,\r
548 Status\r
549 );\r
550\r
551 if (OldToggle != DataToggle) {\r
552 //\r
553 // Write the toggle back\r
554 //\r
555 SetDataToggleBit (\r
556 This,\r
557 DeviceEndpoint,\r
558 DataToggle\r
559 );\r
560 }\r
561\r
562 return RetStatus;\r
563}\r
564\r
565STATIC\r
566EFI_STATUS\r
567EFIAPI\r
568UsbAsyncInterruptTransfer (\r
569 IN EFI_USB_IO_PROTOCOL *This,\r
570 IN UINT8 DeviceEndpoint,\r
571 IN BOOLEAN IsNewTransfer,\r
572 IN UINTN PollingInterval, OPTIONAL\r
573 IN UINTN DataLength, OPTIONAL\r
574 IN EFI_ASYNC_USB_TRANSFER_CALLBACK InterruptCallBack, OPTIONAL\r
575 IN VOID *Context OPTIONAL\r
576 )\r
577/*++\r
578\r
579 Routine Description:\r
580 Usb Async Interrput Transfer\r
581\r
582 Arguments:\r
583 This - Indicates calling context.\r
584 DeviceEndpoint - The destination USB device endpoint to which the\r
585 device request is being sent.\r
586 IsNewTransfer - If TRUE, a new transfer will be submitted to USB\r
587 controller. If FALSE, the interrupt transfer is\r
588 deleted from the device's interrupt transfer queue.\r
589 PollingInterval - Indicates the periodic rate, in milliseconds, that\r
590 the transfer is to be executed.\r
591 DataLength - Specifies the length, in bytes, of the data to be\r
592 received from the USB device.\r
593 InterruptCallback - The Callback function. This function is called if\r
594 the asynchronous interrupt transfer is completed.\r
595 Context - Passed to InterruptCallback \r
596 Returns:\r
597 EFI_SUCCESS\r
598 EFI_INVALID_PARAMETER\r
599 EFI_OUT_OF_RESOURCES\r
600\r
601--*/\r
602{\r
603 USB_IO_DEVICE *UsbIoDev;\r
604 UINT8 MaxPacketLength;\r
605 UINT8 DataToggle;\r
606 EFI_USB_HC_PROTOCOL *UsbHCInterface;\r
607 EFI_STATUS RetStatus;\r
608 USB_IO_CONTROLLER_DEVICE *UsbIoController;\r
609 ENDPOINT_DESC_LIST_ENTRY *EndpointListEntry;\r
610\r
611 //\r
612 // Check endpoint\r
613 //\r
614 if ((DeviceEndpoint & 0x7F) == 0) {\r
615 return EFI_INVALID_PARAMETER;\r
616 }\r
617\r
618 if ((DeviceEndpoint & 0x7F) > 15) {\r
619 return EFI_INVALID_PARAMETER;\r
620 }\r
621\r
622 EndpointListEntry = FindEndPointListEntry (\r
623 This,\r
624 DeviceEndpoint\r
625 );\r
626\r
627 if (EndpointListEntry == NULL) {\r
628 return EFI_INVALID_PARAMETER;\r
629 }\r
630\r
631 if ((EndpointListEntry->EndpointDescriptor.Attributes & 0x03) != 0x03) {\r
632 return EFI_INVALID_PARAMETER;\r
633 }\r
634\r
635 UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);\r
636 UsbIoDev = UsbIoController->UsbDevice;\r
637 UsbHCInterface = UsbIoDev->BusController->UsbHCInterface;\r
638\r
639 if (!IsNewTransfer) {\r
640 //\r
641 // Delete this transfer\r
642 //\r
643 UsbHCInterface->AsyncInterruptTransfer (\r
644 UsbHCInterface,\r
645 UsbIoDev->DeviceAddress,\r
646 DeviceEndpoint,\r
647 UsbIoDev->IsSlowDevice,\r
648 0,\r
649 FALSE,\r
650 &DataToggle,\r
651 PollingInterval,\r
652 DataLength,\r
653 NULL,\r
654 NULL\r
655 );\r
656\r
657 //\r
658 // We need to store the toggle value\r
659 //\r
660 SetDataToggleBit (\r
661 This,\r
662 DeviceEndpoint,\r
663 DataToggle\r
664 );\r
665\r
666 return EFI_SUCCESS;\r
667 }\r
668\r
669 GetDeviceEndPointMaxPacketLength (\r
670 This,\r
671 DeviceEndpoint,\r
672 &MaxPacketLength\r
673 );\r
674\r
675 GetDataToggleBit (\r
676 This,\r
677 DeviceEndpoint,\r
678 &DataToggle\r
679 );\r
680\r
681 RetStatus = UsbHCInterface->AsyncInterruptTransfer (\r
682 UsbHCInterface,\r
683 UsbIoDev->DeviceAddress,\r
684 DeviceEndpoint,\r
685 UsbIoDev->IsSlowDevice,\r
686 MaxPacketLength,\r
687 TRUE,\r
688 &DataToggle,\r
689 PollingInterval,\r
690 DataLength,\r
691 InterruptCallBack,\r
692 Context\r
693 );\r
694\r
695 return RetStatus;\r
696}\r
697\r
698STATIC\r
699EFI_STATUS\r
700EFIAPI\r
701UsbIsochronousTransfer (\r
702 IN EFI_USB_IO_PROTOCOL *This,\r
703 IN UINT8 DeviceEndpoint,\r
704 IN OUT VOID *Data,\r
705 IN UINTN DataLength,\r
706 OUT UINT32 *Status\r
707 )\r
708/*++\r
709\r
710 Routine Description:\r
711 Usb Isochronous Transfer\r
712\r
713 Arguments:\r
714 This - Indicates calling context.\r
715 DeviceEndpoint - The destination USB device endpoint to which the\r
716 device request is being sent.\r
717 Data - A pointer to the buffer of data that will be\r
718 transmitted to USB device or received from USB device.\r
719 DataLength - The size, in bytes, of the data buffer specified by\r
720 Data.\r
721 Status - This parameter indicates the USB transfer status.\r
722\r
723 Returns:\r
724 EFI_SUCCESS\r
725 EFI_INVALID_PARAMETER\r
726 EFI_OUT_OF_RESOURCES\r
727 EFI_TIMEOUT\r
728 EFI_DEVICE_ERROR\r
729 EFI_UNSUPPORTED\r
730--*/\r
731{\r
732 //\r
733 // Currently we don't support this transfer\r
734 //\r
735 return EFI_UNSUPPORTED;\r
736}\r
737\r
738STATIC\r
739EFI_STATUS\r
740EFIAPI\r
741UsbAsyncIsochronousTransfer (\r
742 IN EFI_USB_IO_PROTOCOL *This,\r
743 IN UINT8 DeviceEndpoint,\r
744 IN OUT VOID *Data,\r
745 IN UINTN DataLength,\r
746 IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack,\r
747 IN VOID *Context OPTIONAL\r
748 )\r
749/*++\r
750\r
751Routine Description:\r
752\r
753 Usb Async Isochronous Transfer\r
754\r
755Arguments:\r
756\r
757 This - EFI_USB_IO_PROTOCOL\r
758 DeviceEndpoint - DeviceEndpoint number\r
759 Data - Data to transfer\r
760 DataLength - DataLength\r
761 IsochronousCallBack - Isochronous CallBack function\r
762 Context - Passed to IsochronousCallBack function\r
763Returns:\r
764\r
765 EFI_UNSUPPORTED - Unsupported now\r
766\r
767--*/\r
768{\r
769 //\r
770 // Currently we don't support this transfer\r
771 //\r
772 return EFI_UNSUPPORTED;\r
773}\r
774//\r
775// Here is new definitions\r
776//\r
777STATIC\r
778EFI_STATUS\r
779EFIAPI\r
780UsbGetDeviceDescriptor (\r
781 IN EFI_USB_IO_PROTOCOL *This,\r
782 OUT EFI_USB_DEVICE_DESCRIPTOR *DeviceDescriptor\r
783 )\r
784/*++\r
785\r
786 Routine Description:\r
787 Retrieves the USB Device Descriptor.\r
788\r
789 Arguments:\r
790 This - Indicates the calling context.\r
791 DeviceDescriptor - A pointer to the caller allocated USB Device\r
792 Descriptor.\r
793\r
794 Returns:\r
795 EFI_SUCCESS\r
796 EFI_INVALID_PARAMETER\r
797 EFI_NOT_FOUND\r
798\r
799--*/\r
800{\r
801 USB_IO_CONTROLLER_DEVICE *UsbIoController;\r
802 USB_IO_DEVICE *UsbIoDev;\r
803\r
804 //\r
805 // This function just wrapps UsbGetDeviceDescriptor.\r
806 //\r
807 \r
808 if (DeviceDescriptor == NULL) {\r
809 return EFI_INVALID_PARAMETER;\r
810 }\r
811\r
812 UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);\r
813 UsbIoDev = UsbIoController->UsbDevice;\r
814\r
815 if (!UsbIoDev->IsConfigured) {\r
816 return EFI_NOT_FOUND;\r
817 }\r
818\r
819 CopyMem (\r
820 DeviceDescriptor,\r
821 &UsbIoDev->DeviceDescriptor,\r
822 sizeof (EFI_USB_DEVICE_DESCRIPTOR)\r
823 );\r
824\r
825 return EFI_SUCCESS;\r
826}\r
827\r
828STATIC\r
829EFI_STATUS\r
830EFIAPI\r
831UsbGetActiveConfigDescriptor (\r
832 IN EFI_USB_IO_PROTOCOL *This,\r
833 OUT EFI_USB_CONFIG_DESCRIPTOR *ConfigurationDescriptor\r
834 )\r
835/*++\r
836\r
837 Routine Description:\r
838 Retrieves the current USB configuration Descriptor.\r
839\r
840 Arguments:\r
841 This - Indicates the calling context.\r
842 ConfigurationDescriptor - A pointer to the caller allocated USB active\r
843 Configuration Descriptor.\r
844\r
845 Returns:\r
846 EFI_SUCCESS\r
847 EFI_INVALID_PARAMETER\r
848 EFI_NOT_FOUND\r
849\r
850--*/\r
851{\r
852 USB_IO_DEVICE *UsbIoDev;\r
853 USB_IO_CONTROLLER_DEVICE *UsbIoController;\r
854\r
855 //\r
856 // This function just wrapps UsbGetActiveConfigDescriptor.\r
857 //\r
858 if (ConfigurationDescriptor == NULL) {\r
859 return EFI_INVALID_PARAMETER;\r
860 }\r
861\r
862 UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);\r
863 UsbIoDev = UsbIoController->UsbDevice;\r
864\r
865 if (!UsbIoDev->IsConfigured) {\r
866 return EFI_NOT_FOUND;\r
867 }\r
868\r
869 CopyMem (\r
870 ConfigurationDescriptor,\r
871 &(UsbIoDev->ActiveConfig->CongfigDescriptor),\r
872 sizeof (EFI_USB_CONFIG_DESCRIPTOR)\r
873 );\r
874\r
875 return EFI_SUCCESS;\r
876}\r
877\r
878STATIC\r
879EFI_STATUS\r
880EFIAPI\r
881UsbGetInterfaceDescriptor (\r
882 IN EFI_USB_IO_PROTOCOL *This,\r
883 OUT EFI_USB_INTERFACE_DESCRIPTOR *InterfaceDescriptor\r
884 )\r
885/*++\r
886\r
887 Routine Description:\r
888 Retrieves the interface Descriptor for that controller.\r
889\r
890 Arguments:\r
891 This - Indicates the calling context.\r
892 InterfaceDescriptor - A pointer to the caller allocated USB interface\r
893 Descriptor.\r
894\r
895 Returns:\r
896 EFI_SUCCESS\r
897 EFI_INVALID_PARAMETER\r
898 EFI_NOT_FOUND\r
899\r
900--*/\r
901{\r
902 INTERFACE_DESC_LIST_ENTRY *InterfaceListEntry;\r
903\r
904 if (InterfaceDescriptor == NULL) {\r
905 return EFI_INVALID_PARAMETER;\r
906 }\r
907\r
908 InterfaceListEntry = FindInterfaceListEntry (This);\r
909\r
910 if (InterfaceListEntry == NULL) {\r
911 return EFI_NOT_FOUND;\r
912 }\r
913\r
914 CopyMem (\r
915 InterfaceDescriptor,\r
916 &(InterfaceListEntry->InterfaceDescriptor),\r
917 sizeof (EFI_USB_INTERFACE_DESCRIPTOR)\r
918 );\r
919\r
920 return EFI_SUCCESS;\r
921}\r
922\r
923STATIC\r
924EFI_STATUS\r
925EFIAPI\r
926UsbGetEndpointDescriptor (\r
927 IN EFI_USB_IO_PROTOCOL *This,\r
928 IN UINT8 EndpointIndex,\r
929 OUT EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDescriptor\r
930 )\r
931/*++\r
932\r
933 Routine Description:\r
934 Retrieves the endpoint Descriptor for a given endpoint.\r
935\r
936 Arguments:\r
937 This - Indicates the calling context.\r
938 EndpointIndex - Indicates which endpoint descriptor to retrieve.\r
939 The valid range is 0..15.\r
940 EndpointDescriptor - A pointer to the caller allocated USB Endpoint\r
941 Descriptor of a USB controller.\r
942\r
943 Returns:\r
944 EFI_SUCCESS - The endpoint descriptor was retrieved successfully.\r
945 EFI_INVALID_PARAMETER - EndpointIndex is not valid.\r
946 - EndpointDescriptor is NULL.\r
947 EFI_NOT_FOUND - The endpoint descriptor cannot be found.\r
948 The device may not be correctly configured.\r
949\r
950--*/\r
951{\r
952 INTERFACE_DESC_LIST_ENTRY *InterfaceListEntry;\r
953 LIST_ENTRY *EndpointListHead;\r
954 ENDPOINT_DESC_LIST_ENTRY *EndpointListEntry;\r
955\r
956 if (EndpointDescriptor == NULL) {\r
957 return EFI_INVALID_PARAMETER;\r
958 }\r
959\r
960 if (EndpointIndex > 15) {\r
961 return EFI_INVALID_PARAMETER;\r
962 }\r
963\r
964 InterfaceListEntry = FindInterfaceListEntry (This);\r
965\r
966 if (InterfaceListEntry == NULL) {\r
967 return EFI_NOT_FOUND;\r
968 }\r
969\r
970 EndpointListHead = (LIST_ENTRY *) (&InterfaceListEntry->EndpointDescListHead);\r
971 EndpointListEntry = (ENDPOINT_DESC_LIST_ENTRY *) (EndpointListHead->ForwardLink);\r
972\r
973 if (EndpointIndex >= InterfaceListEntry->InterfaceDescriptor.NumEndpoints) {\r
974 return EFI_NOT_FOUND;\r
975 }\r
976 //\r
977 // Loop all endpoint descriptor to get match one.\r
978 //\r
979 while (EndpointIndex != 0) {\r
980 EndpointListEntry = (ENDPOINT_DESC_LIST_ENTRY *) (EndpointListEntry->Link.ForwardLink);\r
981 EndpointIndex--;\r
982 }\r
983\r
984 CopyMem (\r
985 EndpointDescriptor,\r
986 &EndpointListEntry->EndpointDescriptor,\r
987 sizeof (EFI_USB_ENDPOINT_DESCRIPTOR)\r
988 );\r
989\r
990 return EFI_SUCCESS;\r
991}\r
992\r
993STATIC\r
994EFI_STATUS\r
995EFIAPI\r
996UsbGetSupportedLanguages (\r
997 IN EFI_USB_IO_PROTOCOL *This,\r
998 OUT UINT16 **LangIDTable,\r
999 OUT UINT16 *TableSize\r
1000 )\r
1001/*++\r
1002\r
1003 Routine Description:\r
1004 Get all the languages that the USB device supports\r
1005\r
1006 Arguments:\r
1007 This - Indicates the calling context.\r
1008 LangIDTable - Language ID for the string the caller wants to get.\r
1009 TableSize - The size, in bytes, of the table LangIDTable.\r
1010\r
1011 Returns:\r
1012 EFI_SUCCESS\r
1013 EFI_NOT_FOUND\r
1014\r
1015--*/\r
1016{\r
1017 USB_IO_DEVICE *UsbIoDev;\r
1018 USB_IO_CONTROLLER_DEVICE *UsbIoController;\r
1019 UINTN Index;\r
1020 BOOLEAN Found;\r
1021\r
1022 UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);\r
1023 UsbIoDev = UsbIoController->UsbDevice;\r
1024\r
1025 Found = FALSE;\r
1026 Index = 0;\r
1027 //\r
1028 // Loop language table\r
1029 //\r
1030 while (UsbIoDev->LangID[Index]) {\r
1031 Found = TRUE;\r
1032 Index++;\r
1033 }\r
1034\r
1035 if (!Found) {\r
1036 return EFI_NOT_FOUND;\r
1037 }\r
1038\r
1039 *LangIDTable = UsbIoDev->LangID;\r
1040 *TableSize = (UINT16) Index;\r
1041\r
1042 return EFI_SUCCESS;\r
1043}\r
1044\r
1045STATIC\r
1046EFI_STATUS\r
1047EFIAPI\r
1048UsbGetStringDescriptor (\r
1049 IN EFI_USB_IO_PROTOCOL *This,\r
1050 IN UINT16 LangID,\r
1051 IN UINT8 StringIndex,\r
1052 OUT CHAR16 **String\r
1053 )\r
1054/*++\r
1055\r
1056 Routine Description:\r
1057 Get a given string descriptor\r
1058\r
1059 Arguments:\r
1060 This - Indicates the calling context.\r
1061 LangID - The Language ID for the string being retrieved.\r
1062 StringIndex - The ID of the string being retrieved.\r
1063 String - A pointer to a buffer allocated by this function\r
1064 with AllocatePool() to store the string. If this\r
1065 function returns EFI_SUCCESS, it stores the string\r
1066 the caller wants to get. The caller should release\r
1067 the string buffer with FreePool() after the string\r
1068 is not used any more.\r
1069 Returns:\r
1070 EFI_SUCCESS\r
1071 EFI_NOT_FOUND\r
1072 EFI_OUT_OF_RESOURCES\r
1073\r
1074--*/\r
1075{\r
1076 UINT32 Status;\r
1077 EFI_STATUS Result;\r
1078 EFI_USB_STRING_DESCRIPTOR *StrDescriptor;\r
1079 UINT8 *Buffer;\r
1080 CHAR16 *UsbString;\r
1081 UINT16 TempBuffer;\r
1082 USB_IO_DEVICE *UsbIoDev;\r
1083 UINT8 Index;\r
1084 BOOLEAN Found;\r
1085 USB_IO_CONTROLLER_DEVICE *UsbIoController;\r
1086\r
1087 if (StringIndex == 0) {\r
1088 return EFI_NOT_FOUND;\r
1089 }\r
1090 //\r
1091 // Search LanguageID, check if it is supported by this device\r
1092 //\r
1093 if (LangID == 0) {\r
1094 return EFI_NOT_FOUND;\r
1095 }\r
1096\r
1097 UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);\r
1098 UsbIoDev = UsbIoController->UsbDevice;\r
1099\r
1100 Found = FALSE;\r
1101 Index = 0;\r
1102 while (UsbIoDev->LangID[Index]) {\r
1103 if (UsbIoDev->LangID[Index] == LangID) {\r
1104 Found = TRUE;\r
1105 break;\r
1106 }\r
1107\r
1108 Index++;\r
1109 }\r
1110\r
1111 if (!Found) {\r
1112 return EFI_NOT_FOUND;\r
1113 }\r
1114 //\r
1115 // Get String Length\r
1116 //\r
1117 Result = UsbGetString (\r
1118 This,\r
1119 LangID,\r
1120 StringIndex,\r
1121 &TempBuffer,\r
1122 2,\r
1123 &Status\r
1124 );\r
1125 if (EFI_ERROR (Result)) {\r
1126 return EFI_NOT_FOUND;\r
1127 }\r
1128\r
1129 StrDescriptor = (EFI_USB_STRING_DESCRIPTOR *) &TempBuffer;\r
1130\r
1131 if (StrDescriptor->Length == 0) {\r
1132 return EFI_UNSUPPORTED;\r
1133 }\r
1134\r
1135 Buffer = AllocateZeroPool (StrDescriptor->Length);\r
1136 if (Buffer == NULL) {\r
1137 return EFI_OUT_OF_RESOURCES;\r
1138 }\r
1139\r
1140 Result = UsbGetString (\r
1141 This,\r
1142 LangID,\r
1143 StringIndex,\r
1144 Buffer,\r
1145 StrDescriptor->Length,\r
1146 &Status\r
1147 );\r
1148\r
1149 if (EFI_ERROR (Result)) {\r
1150 gBS->FreePool (Buffer);\r
1151 return EFI_NOT_FOUND;\r
1152 }\r
1153\r
1154 StrDescriptor = (EFI_USB_STRING_DESCRIPTOR *) Buffer;\r
1155\r
1156 //\r
1157 // UsbString is a UNICODE string\r
1158 //\r
1159 UsbString = AllocateZeroPool (StrDescriptor->Length);\r
1160 if (UsbString == NULL) {\r
1161 gBS->FreePool (Buffer);\r
1162 return EFI_OUT_OF_RESOURCES;\r
1163 }\r
1164\r
1165 CopyMem (\r
1166 (VOID *) UsbString,\r
1167 Buffer + 2,\r
1168 StrDescriptor->Length - 2\r
1169 );\r
1170\r
1171 *String = UsbString;\r
1172\r
1173 gBS->FreePool (Buffer);\r
1174\r
1175 return EFI_SUCCESS;\r
1176}\r