626fa22290a4f400e7a59ab5692f92389f79d3eb
[people/mcb30/edk2.git] / edk2 / MdePkg / Library / UefiUsbLib / UsbDxeLib.c
1 /*++\r
2 \r
3 Copyright (c) 2006, Intel Corporation                                                         \r
4 All rights reserved. This program and the accompanying materials                          \r
5 are licensed and made available under the terms and conditions of the BSD License         \r
6 which accompanies this distribution.  The full text of the license may be found at        \r
7 http://opensource.org/licenses/bsd-license.php                                            \r
8                                                                                           \r
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
11 \r
12  Module Name:\r
13 \r
14     UsbDxeLib.c\r
15 \r
16  Abstract:\r
17 \r
18    Common Dxe Libarary  for USB\r
19 \r
20  Revision History\r
21 \r
22 --*/\r
23 \r
24 #include "UefiUsbLibInternal.h"\r
25 \r
26 //\r
27 // Get Device Descriptor\r
28 //\r
29 EFI_STATUS\r
30 UsbGetDescriptor (\r
31   IN  EFI_USB_IO_PROTOCOL     *UsbIo,\r
32   IN  UINT16                  Value,\r
33   IN  UINT16                  Index,\r
34   IN  UINT16                  DescriptorLength,\r
35   OUT VOID                    *Descriptor,\r
36   OUT UINT32                  *Status\r
37   )\r
38 /*++\r
39 \r
40 Routine Description:\r
41 \r
42   Usb Get Descriptor\r
43 \r
44 Arguments:\r
45 \r
46   UsbIo             - EFI_USB_IO_PROTOCOL\r
47   Value             - Device Request Value\r
48   Index             - Device Request Index \r
49   DescriptorLength  - Descriptor Length\r
50   Descriptor        - Descriptor buffer to contain result\r
51   Status            - Transfer Status\r
52 Returns:\r
53   EFI_INVALID_PARAMETER - Parameter is error\r
54   EFI_SUCCESS           - Success\r
55   EFI_TIMEOUT           - Device has no response \r
56 \r
57 --*/\r
58 {\r
59   EFI_USB_DEVICE_REQUEST  DevReq;\r
60 \r
61   if (UsbIo == NULL) {\r
62     return EFI_INVALID_PARAMETER;\r
63   }\r
64 \r
65   ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));\r
66 \r
67   DevReq.RequestType  = USB_DEV_GET_DESCRIPTOR_REQ_TYPE;\r
68   DevReq.Request      = USB_DEV_GET_DESCRIPTOR;\r
69   DevReq.Value        = Value;\r
70   DevReq.Index        = Index;\r
71   DevReq.Length       = DescriptorLength;\r
72 \r
73   return UsbIo->UsbControlTransfer (\r
74                   UsbIo,\r
75                   &DevReq,\r
76                   EfiUsbDataIn,\r
77                   TIMEOUT_VALUE,\r
78                   Descriptor,\r
79                   DescriptorLength,\r
80                   Status\r
81                   );\r
82 }\r
83 //\r
84 // Set Device Descriptor\r
85 //\r
86 EFI_STATUS\r
87 UsbSetDescriptor (\r
88   IN  EFI_USB_IO_PROTOCOL     *UsbIo,\r
89   IN  UINT16                  Value,\r
90   IN  UINT16                  Index,\r
91   IN  UINT16                  DescriptorLength,\r
92   IN  VOID                    *Descriptor,\r
93   OUT UINT32                  *Status\r
94   )\r
95 /*++\r
96 \r
97 Routine Description:\r
98 \r
99   Usb Set Descriptor\r
100 \r
101 Arguments:\r
102 \r
103   UsbIo             - EFI_USB_IO_PROTOCOL\r
104   Value             - Device Request Value\r
105   Index             - Device Request Index \r
106   DescriptorLength  - Descriptor Length\r
107   Descriptor        - Descriptor buffer to set\r
108   Status            - Transfer Status\r
109 Returns:\r
110   EFI_INVALID_PARAMETER - Parameter is error\r
111   EFI_SUCCESS           - Success\r
112   EFI_TIMEOUT           - Device has no response \r
113 \r
114 --*/\r
115 {\r
116   EFI_USB_DEVICE_REQUEST  DevReq;\r
117 \r
118   if (UsbIo == NULL) {\r
119     return EFI_INVALID_PARAMETER;\r
120   }\r
121 \r
122   ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));\r
123 \r
124   DevReq.RequestType  = USB_DEV_SET_DESCRIPTOR_REQ_TYPE;\r
125   DevReq.Request      = USB_DEV_SET_DESCRIPTOR;\r
126   DevReq.Value        = Value;\r
127   DevReq.Index        = Index;\r
128   DevReq.Length       = DescriptorLength;\r
129 \r
130   return UsbIo->UsbControlTransfer (\r
131                   UsbIo,\r
132                   &DevReq,\r
133                   EfiUsbDataOut,\r
134                   TIMEOUT_VALUE,\r
135                   Descriptor,\r
136                   DescriptorLength,\r
137                   Status\r
138                   );\r
139 }\r
140 \r
141 //\r
142 // Get device Interface\r
143 //\r
144 EFI_STATUS\r
145 UsbGetDeviceInterface (\r
146   IN  EFI_USB_IO_PROTOCOL     *UsbIo,\r
147   IN  UINT16                  Index,\r
148   OUT UINT8                   *AltSetting,\r
149   OUT UINT32                  *Status\r
150   )\r
151 /*++\r
152 \r
153 Routine Description:\r
154 \r
155   Usb Get Device Interface\r
156 \r
157 Arguments:\r
158 \r
159   UsbIo       - EFI_USB_IO_PROTOCOL\r
160   Index       - Interface index value\r
161   AltSetting  - Alternate setting\r
162   Status      - Trasnsfer status\r
163 \r
164 Returns:\r
165 \r
166   EFI_INVALID_PARAMETER - Parameter is error\r
167   EFI_SUCCESS           - Success\r
168   EFI_TIMEOUT           - Device has no response \r
169 \r
170 \r
171 --*/\r
172 {\r
173   EFI_USB_DEVICE_REQUEST  DevReq;\r
174 \r
175   if (UsbIo == NULL) {\r
176     return EFI_INVALID_PARAMETER;\r
177   }\r
178 \r
179   ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));\r
180 \r
181   DevReq.RequestType  = USB_DEV_GET_INTERFACE_REQ_TYPE;\r
182   DevReq.Request      = USB_DEV_GET_INTERFACE;\r
183   DevReq.Index        = Index;\r
184   DevReq.Length       = 1;\r
185 \r
186   return UsbIo->UsbControlTransfer (\r
187                   UsbIo,\r
188                   &DevReq,\r
189                   EfiUsbDataIn,\r
190                   TIMEOUT_VALUE,\r
191                   AltSetting,\r
192                   1,\r
193                   Status\r
194                   );\r
195 }\r
196 //\r
197 // Set device interface\r
198 //\r
199 EFI_STATUS\r
200 UsbSetDeviceInterface (\r
201   IN  EFI_USB_IO_PROTOCOL     *UsbIo,\r
202   IN  UINT16                  InterfaceNo,\r
203   IN  UINT16                  AltSetting,\r
204   OUT UINT32                  *Status\r
205   )\r
206 /*++\r
207 \r
208 Routine Description:\r
209 \r
210   Usb Set Device Interface\r
211 \r
212 Arguments:\r
213 \r
214   UsbIo       - EFI_USB_IO_PROTOCOL\r
215   InterfaceNo - Interface Number\r
216   AltSetting  - Alternate setting\r
217   Status      - Trasnsfer status\r
218 \r
219 Returns:\r
220 \r
221   EFI_INVALID_PARAMETER - Parameter is error\r
222   EFI_SUCCESS           - Success\r
223   EFI_TIMEOUT           - Device has no response \r
224 \r
225 --*/\r
226 {\r
227   EFI_USB_DEVICE_REQUEST  DevReq;\r
228 \r
229   if (UsbIo == NULL) {\r
230     return EFI_INVALID_PARAMETER;\r
231   }\r
232 \r
233   ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));\r
234 \r
235   DevReq.RequestType  = USB_DEV_SET_INTERFACE_REQ_TYPE;\r
236   DevReq.Request      = USB_DEV_SET_INTERFACE;\r
237   DevReq.Value        = AltSetting;\r
238   DevReq.Index        = InterfaceNo;\r
239  \r
240 \r
241   return UsbIo->UsbControlTransfer (\r
242                   UsbIo,\r
243                   &DevReq,\r
244                   EfiUsbNoData,\r
245                   TIMEOUT_VALUE,\r
246                   NULL,\r
247                   0,\r
248                   Status\r
249                   );\r
250 }\r
251 //\r
252 // Get device configuration\r
253 //\r
254 EFI_STATUS\r
255 UsbGetDeviceConfiguration (\r
256   IN  EFI_USB_IO_PROTOCOL     *UsbIo,\r
257   OUT UINT8                   *ConfigValue,\r
258   OUT UINT32                  *Status\r
259   )\r
260 /*++\r
261 \r
262 Routine Description:\r
263 \r
264   Usb Get Device Configuration\r
265 \r
266 Arguments:\r
267 \r
268   UsbIo       - EFI_USB_IO_PROTOCOL\r
269   ConfigValue - Config Value\r
270   Status      - Transfer Status\r
271 \r
272 Returns:\r
273 \r
274   EFI_INVALID_PARAMETER - Parameter is error\r
275   EFI_SUCCESS           - Success\r
276   EFI_TIMEOUT           - Device has no response \r
277 \r
278 --*/\r
279 {\r
280   EFI_USB_DEVICE_REQUEST  DevReq;\r
281 \r
282   if (UsbIo == NULL) {\r
283     return EFI_INVALID_PARAMETER;\r
284   }\r
285 \r
286   ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));\r
287 \r
288   DevReq.RequestType  = USB_DEV_GET_CONFIGURATION_REQ_TYPE;\r
289   DevReq.Request      = USB_DEV_GET_CONFIGURATION;\r
290   DevReq.Length       = 1;\r
291 \r
292   return UsbIo->UsbControlTransfer (\r
293                   UsbIo,\r
294                   &DevReq,\r
295                   EfiUsbDataIn,\r
296                   TIMEOUT_VALUE,\r
297                   ConfigValue,\r
298                   1,\r
299                   Status\r
300                   );\r
301 }\r
302 //\r
303 // Set device configuration\r
304 //\r
305 EFI_STATUS\r
306 UsbSetDeviceConfiguration (\r
307   IN  EFI_USB_IO_PROTOCOL     *UsbIo,\r
308   IN  UINT16                  Value,\r
309   OUT UINT32                  *Status\r
310   )\r
311 /*++\r
312 \r
313 Routine Description:\r
314 \r
315   Usb Set Device Configuration\r
316 \r
317 Arguments:\r
318 \r
319   UsbIo   - EFI_USB_IO_PROTOCOL\r
320   Value   - Configuration Value to set\r
321   Status  - Transfer status\r
322 \r
323 Returns:\r
324 \r
325   EFI_INVALID_PARAMETER - Parameter is error\r
326   EFI_SUCCESS           - Success\r
327   EFI_TIMEOUT           - Device has no response \r
328 \r
329 --*/\r
330 {\r
331   EFI_USB_DEVICE_REQUEST  DevReq;\r
332 \r
333   if (UsbIo == NULL) {\r
334     return EFI_INVALID_PARAMETER;\r
335   }\r
336 \r
337   ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));\r
338 \r
339   DevReq.RequestType  = USB_DEV_SET_CONFIGURATION_REQ_TYPE;\r
340   DevReq.Request      = USB_DEV_SET_CONFIGURATION;\r
341   DevReq.Value        = Value;\r
342  \r
343   return UsbIo->UsbControlTransfer (\r
344                   UsbIo,\r
345                   &DevReq,\r
346                   EfiUsbNoData,\r
347                   TIMEOUT_VALUE,\r
348                   NULL,\r
349                   0,\r
350                   Status\r
351                   );\r
352 }\r
353 //\r
354 //  Set Device Feature\r
355 //\r
356 EFI_STATUS\r
357 UsbSetDeviceFeature (\r
358   IN  EFI_USB_IO_PROTOCOL     *UsbIo,\r
359   IN  EFI_USB_RECIPIENT       Recipient,\r
360   IN  UINT16                  Value,\r
361   IN  UINT16                  Target,\r
362   OUT UINT32                  *Status\r
363   )\r
364 /*++\r
365 \r
366 Routine Description:\r
367 \r
368   Usb Set Device Feature\r
369 \r
370 Arguments:\r
371 \r
372   UsbIo     - EFI_USB_IO_PROTOCOL\r
373   Recipient - Interface/Device/Endpoint\r
374   Value     - Request value\r
375   Target    - Request Index\r
376   Status    - Transfer status\r
377 \r
378 Returns:\r
379   \r
380   EFI_INVALID_PARAMETER - Parameter is error\r
381   EFI_SUCCESS           - Success\r
382   EFI_TIMEOUT           - Device has no response \r
383 \r
384 --*/\r
385 {\r
386   EFI_USB_DEVICE_REQUEST  DevReq;\r
387 \r
388   if (UsbIo == NULL) {\r
389     return EFI_INVALID_PARAMETER;\r
390   }\r
391 \r
392   ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));\r
393 \r
394   switch (Recipient) {\r
395 \r
396   case EfiUsbDevice:\r
397     DevReq.RequestType = 0x00;\r
398     break;\r
399 \r
400   case EfiUsbInterface:\r
401     DevReq.RequestType = 0x01;\r
402     break;\r
403 \r
404   case EfiUsbEndpoint:\r
405     DevReq.RequestType = 0x02;\r
406     break;\r
407   }\r
408   //\r
409   // Fill device request, see USB1.1 spec\r
410   //\r
411   DevReq.Request  = USB_DEV_SET_FEATURE;\r
412   DevReq.Value    = Value;\r
413   DevReq.Index    = Target;\r
414 \r
415 \r
416   return UsbIo->UsbControlTransfer (\r
417                   UsbIo,\r
418                   &DevReq,\r
419                   EfiUsbNoData,\r
420                   TIMEOUT_VALUE,\r
421                   NULL,\r
422                   0,\r
423                   Status\r
424                   );\r
425 }\r
426 //\r
427 // Clear Device Feature\r
428 //\r
429 EFI_STATUS\r
430 UsbClearDeviceFeature (\r
431   IN  EFI_USB_IO_PROTOCOL     *UsbIo,\r
432   IN  EFI_USB_RECIPIENT       Recipient,\r
433   IN  UINT16                  Value,\r
434   IN  UINT16                  Target,\r
435   OUT UINT32                  *Status\r
436   )\r
437 /*++\r
438 \r
439 Routine Description:\r
440 \r
441   Usb Clear Device Feature\r
442 \r
443 Arguments:\r
444 \r
445   UsbIo     - EFI_USB_IO_PROTOCOL\r
446   Recipient - Interface/Device/Endpoint\r
447   Value     - Request value\r
448   Target    - Request Index\r
449   Status    - Transfer status\r
450 \r
451 Returns:\r
452   \r
453   EFI_INVALID_PARAMETER - Parameter is error\r
454   EFI_SUCCESS           - Success\r
455   EFI_TIMEOUT           - Device has no response \r
456 \r
457 --*/\r
458 {\r
459   EFI_USB_DEVICE_REQUEST  DevReq;\r
460 \r
461   if (UsbIo == NULL) {\r
462     return EFI_INVALID_PARAMETER;\r
463   }\r
464 \r
465   ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));\r
466 \r
467   switch (Recipient) {\r
468 \r
469   case EfiUsbDevice:\r
470     DevReq.RequestType = 0x00;\r
471     break;\r
472 \r
473   case EfiUsbInterface:\r
474     DevReq.RequestType = 0x01;\r
475     break;\r
476 \r
477   case EfiUsbEndpoint:\r
478     DevReq.RequestType = 0x02;\r
479     break;\r
480   }\r
481   //\r
482   // Fill device request, see USB1.1 spec\r
483   //\r
484   DevReq.Request  = USB_DEV_CLEAR_FEATURE;\r
485   DevReq.Value    = Value;\r
486   DevReq.Index    = Target;\r
487 \r
488 \r
489   return UsbIo->UsbControlTransfer (\r
490                   UsbIo,\r
491                   &DevReq,\r
492                   EfiUsbNoData,\r
493                   TIMEOUT_VALUE,\r
494                   NULL,\r
495                   0,\r
496                   Status\r
497                   );\r
498 }\r
499 //\r
500 //  Get Device Status\r
501 //\r
502 EFI_STATUS\r
503 UsbGetDeviceStatus (\r
504   IN  EFI_USB_IO_PROTOCOL     *UsbIo,\r
505   IN  EFI_USB_RECIPIENT       Recipient,\r
506   IN  UINT16                  Target,\r
507   OUT UINT16                  *DevStatus,\r
508   OUT UINT32                  *Status\r
509   )\r
510 /*++\r
511 \r
512 Routine Description:\r
513 \r
514   Usb Get Device Status\r
515 \r
516 Arguments:\r
517 \r
518   UsbIo     - EFI_USB_IO_PROTOCOL\r
519   Recipient - Interface/Device/Endpoint\r
520   Target    - Request index\r
521   DevStatus - Device status\r
522   Status    - Transfer status\r
523 \r
524 Returns:\r
525   \r
526   EFI_INVALID_PARAMETER - Parameter is error\r
527   EFI_SUCCESS           - Success\r
528   EFI_TIMEOUT           - Device has no response \r
529 \r
530 --*/\r
531 {\r
532   EFI_USB_DEVICE_REQUEST  DevReq;\r
533 \r
534   if (UsbIo == NULL) {\r
535     return EFI_INVALID_PARAMETER;\r
536   }\r
537 \r
538   ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));\r
539 \r
540   switch (Recipient) {\r
541 \r
542   case EfiUsbDevice:\r
543     DevReq.RequestType = 0x80;\r
544     break;\r
545 \r
546   case EfiUsbInterface:\r
547     DevReq.RequestType = 0x81;\r
548     break;\r
549 \r
550   case EfiUsbEndpoint:\r
551     DevReq.RequestType = 0x82;\r
552     break;\r
553   }\r
554   //\r
555   // Fill device request, see USB1.1 spec\r
556   //\r
557   DevReq.Request  = USB_DEV_GET_STATUS;\r
558   DevReq.Value    = 0;\r
559   DevReq.Index    = Target;\r
560   DevReq.Length   = 2;\r
561 \r
562   return UsbIo->UsbControlTransfer (\r
563                   UsbIo,\r
564                   &DevReq,\r
565                   EfiUsbDataIn,\r
566                   TIMEOUT_VALUE,\r
567                   DevStatus,\r
568                   2,\r
569                   Status\r
570                   );\r
571 }\r
572 //\r
573 // Usb Get String\r
574 //\r
575 EFI_STATUS\r
576 UsbGetString (\r
577   IN  EFI_USB_IO_PROTOCOL     *UsbIo,\r
578   IN  UINT16                  LangID,\r
579   IN  UINT8                   Index,\r
580   IN  VOID                    *Buf,\r
581   IN  UINTN                   BufSize,\r
582   OUT UINT32                  *Status\r
583   )\r
584 /*++\r
585 \r
586 Routine Description:\r
587 \r
588   Usb Get String\r
589 \r
590 Arguments:\r
591 \r
592   UsbIo     - EFI_USB_IO_PROTOCOL\r
593   LangID    - Language ID\r
594   Index     - Request index\r
595   Buf       - Buffer to store string\r
596   BufSize   - Buffer size\r
597   Status    - Transfer status\r
598 \r
599 Returns:\r
600   \r
601   EFI_INVALID_PARAMETER - Parameter is error\r
602   EFI_SUCCESS           - Success\r
603   EFI_TIMEOUT           - Device has no response \r
604 \r
605 --*/\r
606 {\r
607   UINT16  Value;\r
608 \r
609   if (UsbIo == NULL) {\r
610     return EFI_INVALID_PARAMETER;\r
611   }\r
612   //\r
613   // Fill value, see USB1.1 spec\r
614   //\r
615   Value = (UINT16) ((USB_DT_STRING << 8) | Index);\r
616 \r
617   return UsbGetDescriptor (\r
618           UsbIo,\r
619           Value,\r
620           LangID,\r
621           (UINT16) BufSize,\r
622           Buf,\r
623           Status\r
624           );\r
625 }\r
626 \r
627 EFI_STATUS\r
628 UsbClearEndpointHalt (\r
629   IN  EFI_USB_IO_PROTOCOL     *UsbIo,\r
630   IN  UINT8                   EndpointNo,\r
631   OUT UINT32                  *Status\r
632   )\r
633 /*++\r
634 \r
635 Routine Description:\r
636 \r
637   Clear endpoint stall\r
638 \r
639 Arguments:\r
640 \r
641   UsbIo       - EFI_USB_IO_PROTOCOL\r
642   EndpointNo  - Endpoint Number\r
643   Status      - Transfer Status\r
644 \r
645 Returns:\r
646 \r
647   EFI_NOT_FOUND    - Can't find the Endpoint\r
648   EFI_DEVICE_ERROR - Hardware error\r
649   EFI_SUCCESS      - Success\r
650 \r
651 --*/\r
652 {\r
653   EFI_STATUS                    Result;\r
654   EFI_USB_ENDPOINT_DESCRIPTOR   EndpointDescriptor;\r
655   EFI_USB_INTERFACE_DESCRIPTOR  InterfaceDescriptor;\r
656   UINT8                         Index;\r
657 \r
658   ZeroMem (&EndpointDescriptor, sizeof (EFI_USB_ENDPOINT_DESCRIPTOR));\r
659   //\r
660   // First seach the endpoint descriptor for that endpoint addr\r
661   //\r
662   Result = UsbIo->UsbGetInterfaceDescriptor (\r
663                     UsbIo,\r
664                     &InterfaceDescriptor\r
665                     );\r
666   if (EFI_ERROR (Result)) {\r
667     return Result;\r
668   }\r
669 \r
670   for (Index = 0; Index < InterfaceDescriptor.NumEndpoints; Index++) {\r
671     Result = UsbIo->UsbGetEndpointDescriptor (\r
672                       UsbIo,\r
673                       Index,\r
674                       &EndpointDescriptor\r
675                       );\r
676     if (EFI_ERROR (Result)) {\r
677       continue;\r
678     }\r
679 \r
680     if (EndpointDescriptor.EndpointAddress == EndpointNo) {\r
681       break;\r
682     }\r
683   }\r
684 \r
685   if (Index == InterfaceDescriptor.NumEndpoints) {\r
686     //\r
687     // No such endpoint\r
688     //\r
689     return EFI_NOT_FOUND;\r
690   }\r
691 \r
692   Result = UsbClearDeviceFeature (\r
693             UsbIo,\r
694             EfiUsbEndpoint,\r
695             EfiUsbEndpointHalt,\r
696             EndpointDescriptor.EndpointAddress,\r
697             Status\r
698             );\r
699 \r
700   return Result;\r
701 }\r