]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/UefiUsbLib/UsbDxeLib.c
Code Scrub:
[mirror_edk2.git] / MdePkg / Library / UefiUsbLib / UsbDxeLib.c
1 /** @file
2
3 The library provides the USB Standard Device Requests defined
4 in Usb specification 9.4 section.
5
6 Copyright (c) 2004 - 2007, Intel Corporation All rights
7 reserved. This program and the accompanying materials are
8 licensed and made available under the terms and conditions of
9 the BSD License which accompanies this distribution. The full
10 text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php
12
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15
16 **/
17
18 #include "UefiUsbLibInternal.h"
19
20
21 /**
22 Get the descriptor of the specified USB device.
23
24 Submit a USB get descriptor request for the USB device specified by UsbIo, Value,
25 and Index, and return the descriptor in the buffer specified by Descriptor.
26 The status of the transfer is returned in Status.
27 If UsbIo is NULL, then ASSERT().
28 If Descriptor is NULL, then ASSERT().
29 If Status is NULL, then ASSERT().
30
31 @param UsbIo A pointer to the USB I/O Protocol instance for the specific USB target.
32 @param Value The device request value.
33 @param Index The device request index.
34 @param DescriptorLength The size, in bytes, of Descriptor.
35 @param Descriptor A pointer to the descriptor buffer to get.
36 @param Status A pointer to the status of the transfer.
37
38 @retval EFI_SUCCESS The request executed successfully.
39 @retval EFI_OUT_OF_RESOURCES The request could not be completed because the
40 buffer specifed by DescriptorLength and Descriptor
41 is not large enough to hold the result of the request.
42 @retval EFI_TIMEOUT A timeout occurred executing the request.
43 @retval EFI_DEVICE_ERROR The request failed due to a device error. The transfer
44 status is returned in Status.
45
46 **/
47 EFI_STATUS
48 EFIAPI
49 UsbGetDescriptor (
50 IN EFI_USB_IO_PROTOCOL *UsbIo,
51 IN UINT16 Value,
52 IN UINT16 Index,
53 IN UINT16 DescriptorLength,
54 OUT VOID *Descriptor,
55 OUT UINT32 *Status
56 )
57 {
58 EFI_USB_DEVICE_REQUEST DevReq;
59
60 ASSERT (UsbIo != NULL);
61 ASSERT (Descriptor != NULL);
62 ASSERT (Status != NULL);
63
64 ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
65
66 DevReq.RequestType = USB_DEV_GET_DESCRIPTOR_REQ_TYPE;
67 DevReq.Request = USB_REQ_GET_DESCRIPTOR;
68 DevReq.Value = Value;
69 DevReq.Index = Index;
70 DevReq.Length = DescriptorLength;
71
72 return UsbIo->UsbControlTransfer (
73 UsbIo,
74 &DevReq,
75 EfiUsbDataIn,
76 TIMEOUT_VALUE,
77 Descriptor,
78 DescriptorLength,
79 Status
80 );
81 }
82
83
84 /**
85 Set the descriptor of the specified USB device.
86
87 Submit a USB set descriptor request for the USB device specified by UsbIo,
88 Value, and Index, and set the descriptor using the buffer specified by DesriptorLength
89 and Descriptor. The status of the transfer is returned in Status.
90 If UsbIo is NULL, then ASSERT().
91 If Descriptor is NULL, then ASSERT().
92 If Status is NULL, then ASSERT().
93
94 @param UsbIo A pointer to the USB I/O Protocol instance for the specific USB target.
95 @param Value The device request value.
96 @param Index The device request index.
97 @param DescriptorLength The size, in bytes, of Descriptor.
98 @param Descriptor A pointer to the descriptor buffer to set.
99 @param Status A pointer to the status of the transfer.
100
101 @retval EFI_SUCCESS The request executed successfully.
102 @retval EFI_TIMEOUT A timeout occurred executing the request.
103 @retval EFI_DEVICE_ERROR The request failed due to a device error.
104 The transfer status is returned in Status.
105
106 **/
107 EFI_STATUS
108 EFIAPI
109 UsbSetDescriptor (
110 IN EFI_USB_IO_PROTOCOL *UsbIo,
111 IN UINT16 Value,
112 IN UINT16 Index,
113 IN UINT16 DescriptorLength,
114 IN VOID *Descriptor,
115 OUT UINT32 *Status
116 )
117 {
118 EFI_USB_DEVICE_REQUEST DevReq;
119
120 ASSERT (UsbIo != NULL);
121 ASSERT (Descriptor != NULL);
122 ASSERT (Status != NULL);
123
124 ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
125
126 DevReq.RequestType = USB_DEV_SET_DESCRIPTOR_REQ_TYPE;
127 DevReq.Request = USB_REQ_SET_DESCRIPTOR;
128 DevReq.Value = Value;
129 DevReq.Index = Index;
130 DevReq.Length = DescriptorLength;
131
132 return UsbIo->UsbControlTransfer (
133 UsbIo,
134 &DevReq,
135 EfiUsbDataOut,
136 TIMEOUT_VALUE,
137 Descriptor,
138 DescriptorLength,
139 Status
140 );
141 }
142
143
144 /**
145 Get the interface setting of the specified USB device.
146
147 Submit a USB get interface request for the USB device specified by UsbIo,
148 and Interface, and place the result in the buffer specified by AlternateSetting.
149 The status of the transfer is returned in Status.
150 If UsbIo is NULL, then ASSERT().
151 If AlternateSetting is NULL, then ASSERT().
152 If Status is NULL, then ASSERT().
153
154 @param UsbIo A pointer to the USB I/O Protocol instance for the specific USB target.
155 @param Interface The interface index value.
156 @param AlternateSetting A pointer to the alternate setting to be retrieved.
157 @param Status A pointer to the status of the transfer.
158
159 @retval EFI_SUCCESS The request executed successfully.
160 @retval EFI_TIMEOUT A timeout occurred executing the request.
161 @retval EFI_DEVICE_ERROR The request failed due to a device error.
162 The transfer status is returned in Status.
163
164 **/
165 EFI_STATUS
166 EFIAPI
167 UsbGetInterface (
168 IN EFI_USB_IO_PROTOCOL *UsbIo,
169 IN UINT16 Interface,
170 OUT UINT8 *AlternateSetting,
171 OUT UINT32 *Status
172 )
173 {
174 EFI_USB_DEVICE_REQUEST DevReq;
175
176 ASSERT (UsbIo != NULL);
177 ASSERT (AlternateSetting != NULL);
178 ASSERT (Status != NULL);
179
180 ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
181
182 DevReq.RequestType = USB_DEV_GET_INTERFACE_REQ_TYPE;
183 DevReq.Request = USB_REQ_GET_INTERFACE;
184 DevReq.Index = Interface;
185 DevReq.Length = 1;
186
187 return UsbIo->UsbControlTransfer (
188 UsbIo,
189 &DevReq,
190 EfiUsbDataIn,
191 TIMEOUT_VALUE,
192 AlternateSetting,
193 1,
194 Status
195 );
196 }
197
198
199 /**
200 Set the interface setting of the specified USB device.
201
202 Submit a USB set interface request for the USB device specified by UsbIo, and
203 Interface, and set the alternate setting to the value specified by AlternateSetting.
204 The status of the transfer is returned in Status.
205 If UsbIo is NULL, then ASSERT().
206 If Status is NULL, then ASSERT().
207
208 @param UsbIo A pointer to the USB I/O Protocol instance for the specific USB target.
209 @param Interface The interface index value.
210 @param AlternateSetting The alternate setting to be set.
211 @param Status A pointer to the status of the transfer.
212
213 @retval EFI_SUCCESS The request executed successfully.
214 @retval EFI_TIMEOUT A timeout occurred executing the request.
215 @retval EFI_SUCCESS The request failed due to a device error.
216 The transfer status is returned in Status.
217
218 **/
219 EFI_STATUS
220 EFIAPI
221 UsbSetInterface (
222 IN EFI_USB_IO_PROTOCOL *UsbIo,
223 IN UINT16 Interface,
224 IN UINT16 AlternateSetting,
225 OUT UINT32 *Status
226 )
227 {
228 EFI_USB_DEVICE_REQUEST DevReq;
229
230 ASSERT (UsbIo != NULL);
231 ASSERT (Status != NULL);
232
233 ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
234
235 DevReq.RequestType = USB_DEV_SET_INTERFACE_REQ_TYPE;
236 DevReq.Request = USB_REQ_SET_INTERFACE;
237 DevReq.Value = AlternateSetting;
238 DevReq.Index = Interface;
239
240 return UsbIo->UsbControlTransfer (
241 UsbIo,
242 &DevReq,
243 EfiUsbNoData,
244 TIMEOUT_VALUE,
245 NULL,
246 0,
247 Status
248 );
249 }
250
251
252 /**
253 Get the device configuration.
254
255 Submit a USB get configuration request for the USB device specified by UsbIo
256 and place the result in the buffer specified by ConfigurationValue. The status
257 of the transfer is returned in Status.
258 If UsbIo is NULL, then ASSERT().
259 If ConfigurationValue is NULL, then ASSERT().
260 If Status is NULL, then ASSERT().
261
262 @param UsbIo A pointer to the USB I/O Protocol instance for the specific USB target.
263 @param ConfigurationValue A pointer to the device configuration to be retrieved.
264 @param Status A pointer to the status of the transfer.
265
266 @retval EFI_SUCCESS The request executed successfully.
267 @retval EFI_TIMEOUT A timeout occurred executing the request.
268 @retval EFI_DEVICE_ERROR The request failed due to a device error.
269 The transfer status is returned in Status.
270
271 **/
272 EFI_STATUS
273 EFIAPI
274 UsbGetConfiguration (
275 IN EFI_USB_IO_PROTOCOL *UsbIo,
276 OUT UINT8 *ConfigurationValue,
277 OUT UINT32 *Status
278 )
279 {
280 EFI_USB_DEVICE_REQUEST DevReq;
281
282 ASSERT (UsbIo != NULL);
283 ASSERT (ConfigurationValue != NULL);
284 ASSERT (Status != NULL);
285
286 ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
287
288 DevReq.RequestType = USB_DEV_GET_CONFIGURATION_REQ_TYPE;
289 DevReq.Request = USB_REQ_GET_CONFIG;
290 DevReq.Length = 1;
291
292 return UsbIo->UsbControlTransfer (
293 UsbIo,
294 &DevReq,
295 EfiUsbDataIn,
296 TIMEOUT_VALUE,
297 ConfigurationValue,
298 1,
299 Status
300 );
301 }
302
303
304 /**
305 Set the device configuration.
306
307 Submit a USB set configuration request for the USB device specified by UsbIo
308 and set the device configuration to the value specified by ConfigurationValue.
309 The status of the transfer is returned in Status.
310 If UsbIo is NULL, then ASSERT().
311 If Status is NULL, then ASSERT().
312
313 @param UsbIo A pointer to the USB I/O Protocol instance for the specific USB target.
314 @param ConfigurationValue The device configuration value to be set.
315 @param Status A pointer to the status of the transfer.
316
317 @retval EFI_SUCCESS The request executed successfully.
318 @retval EFI_TIMEOUT A timeout occurred executing the request.
319 @retval EFI_DEVICE_ERROR The request failed due to a device error.
320 The transfer status is returned in Status.
321
322 **/
323 EFI_STATUS
324 EFIAPI
325 UsbSetConfiguration (
326 IN EFI_USB_IO_PROTOCOL *UsbIo,
327 IN UINT16 ConfigurationValue,
328 OUT UINT32 *Status
329 )
330 {
331 EFI_USB_DEVICE_REQUEST DevReq;
332
333 ASSERT (UsbIo != NULL);
334 ASSERT (Status != NULL);
335
336 ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
337
338 DevReq.RequestType = USB_DEV_SET_CONFIGURATION_REQ_TYPE;
339 DevReq.Request = USB_REQ_SET_CONFIG;
340 DevReq.Value = ConfigurationValue;
341
342 return UsbIo->UsbControlTransfer (
343 UsbIo,
344 &DevReq,
345 EfiUsbNoData,
346 TIMEOUT_VALUE,
347 NULL,
348 0,
349 Status
350 );
351 }
352
353
354 /**
355 Set the specified feature of the specified device.
356
357 Submit a USB set device feature request for the USB device specified by UsbIo,
358 Recipient, and Target to the value specified by Value. The status of the
359 transfer is returned in Status.
360 If UsbIo is NULL, then ASSERT().
361 If Status is NULL, then ASSERT().
362
363 @param UsbIo A pointer to the USB I/O Protocol instance for the specific USB target.
364 @param Recipient The USB data recipient type (i.e. Device, Interface, Endpoint).
365 Type USB_TYPES_DEFINITION is defined in the MDE Package Industry
366 Standard include file Usb.h.
367 @param Value The value of the feature to be set.
368 @param Target The index of the device to be set.
369 @param Status A pointer to the status of the transfer.
370
371 @retval EFI_SUCCESS The request executed successfully.
372 @retval EFI_TIMEOUT A timeout occurred executing the request.
373 @retval EFI_DEVICE_ERROR The request failed due to a device error.
374 The transfer status is returned in Status.
375
376 **/
377 EFI_STATUS
378 EFIAPI
379 UsbSetFeature (
380 IN EFI_USB_IO_PROTOCOL *UsbIo,
381 IN USB_TYPES_DEFINITION Recipient,
382 IN UINT16 Value,
383 IN UINT16 Target,
384 OUT UINT32 *Status
385 )
386 {
387 EFI_USB_DEVICE_REQUEST DevReq;
388
389 ASSERT (UsbIo != NULL);
390 ASSERT (Status != NULL);
391
392 ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
393
394 switch (Recipient) {
395
396 case USB_TARGET_DEVICE:
397 DevReq.RequestType = USB_DEV_SET_FEATURE_REQ_TYPE_D;
398 break;
399
400 case USB_TARGET_INTERFACE:
401 DevReq.RequestType = USB_DEV_SET_FEATURE_REQ_TYPE_I;
402 break;
403
404 case USB_TARGET_ENDPOINT:
405 DevReq.RequestType = USB_DEV_SET_FEATURE_REQ_TYPE_E;
406 break;
407 }
408 //
409 // Fill device request, see USB1.1 spec
410 //
411 DevReq.Request = USB_REQ_SET_FEATURE;
412 DevReq.Value = Value;
413 DevReq.Index = Target;
414
415
416 return UsbIo->UsbControlTransfer (
417 UsbIo,
418 &DevReq,
419 EfiUsbNoData,
420 TIMEOUT_VALUE,
421 NULL,
422 0,
423 Status
424 );
425 }
426
427
428 /**
429 Clear the specified feature of the specified device.
430
431 Submit a USB clear device feature request for the USB device specified by UsbIo,
432 Recipient, and Target to the value specified by Value. The status of the transfer
433 is returned in Status.
434 If UsbIo is NULL, then ASSERT().
435 If Status is NULL, then ASSERT().
436
437 @param UsbIo A pointer to the USB I/O Protocol instance for the specific USB target.
438 @param Recipient The USB data recipient type (i.e. Device, Interface, Endpoint).
439 Type USB_TYPES_DEFINITION is defined in the MDE Package Industry Standard
440 include file Usb.h.
441 @param Value The value of the feature to be cleared.
442 @param Target The index of the device to be cleared.
443 @param Status A pointer to the status of the transfer.
444
445 @retval EFI_SUCCESS The request executed successfully.
446 @retval EFI_TIMEOUT A timeout occurred executing the request.
447 @retval EFI_DEVICE_ERROR The request failed due to a device error.
448 The transfer status is returned in Status.
449
450 **/
451 EFI_STATUS
452 EFIAPI
453 UsbClearFeature (
454 IN EFI_USB_IO_PROTOCOL *UsbIo,
455 IN USB_TYPES_DEFINITION Recipient,
456 IN UINT16 Value,
457 IN UINT16 Target,
458 OUT UINT32 *Status
459 )
460 {
461 EFI_USB_DEVICE_REQUEST DevReq;
462
463 ASSERT (UsbIo != NULL);
464 ASSERT (Status != NULL);
465
466
467 ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
468
469 switch (Recipient) {
470
471 case USB_TARGET_DEVICE:
472 DevReq.RequestType = USB_DEV_CLEAR_FEATURE_REQ_TYPE_D;
473 break;
474
475 case USB_TARGET_INTERFACE:
476 DevReq.RequestType = USB_DEV_CLEAR_FEATURE_REQ_TYPE_I;
477 break;
478
479 case USB_TARGET_ENDPOINT:
480 DevReq.RequestType = USB_DEV_CLEAR_FEATURE_REQ_TYPE_E;
481 break;
482 }
483 //
484 // Fill device request, see USB1.1 spec
485 //
486 DevReq.Request = USB_REQ_CLEAR_FEATURE;
487 DevReq.Value = Value;
488 DevReq.Index = Target;
489
490
491 return UsbIo->UsbControlTransfer (
492 UsbIo,
493 &DevReq,
494 EfiUsbNoData,
495 TIMEOUT_VALUE,
496 NULL,
497 0,
498 Status
499 );
500 }
501
502
503 /**
504 Get the status of the specified device.
505
506 Submit a USB device get status request for the USB device specified by UsbIo,
507 Recipient, and Target and place the result in the buffer specified by DeviceStatus.
508 The status of the transfer is returned in Status.
509 If UsbIo is NULL, then ASSERT().
510 If DeviceStatus is NULL, then ASSERT().
511 If Status is NULL, then ASSERT().
512
513 @param UsbIo A pointer to the USB I/O Protocol instance for the specific USB target.
514 @param Recipient The USB data recipient type (i.e. Device, Interface, Endpoint).
515 Type USB_TYPES_DEFINITION is defined in the MDE Package Industry Standard
516 include file Usb.h.
517 @param Target The index of the device to be get the status of.
518 @param DeviceStatus A pointer to the device status to be retrieved.
519 @param Status A pointer to the status of the transfer.
520
521 @retval EFI_SUCCESS The request executed successfully.
522 @retval EFI_TIMEOUT A timeout occurred executing the request.
523 @retval EFI_DEVICE_ERROR The request failed due to a device error.
524 The transfer status is returned in Status.
525
526 **/
527 EFI_STATUS
528 EFIAPI
529 UsbGetStatus (
530 IN EFI_USB_IO_PROTOCOL *UsbIo,
531 IN USB_TYPES_DEFINITION Recipient,
532 IN UINT16 Target,
533 OUT UINT16 *DeviceStatus,
534 OUT UINT32 *Status
535 )
536 {
537 EFI_USB_DEVICE_REQUEST DevReq;
538
539 ASSERT (UsbIo != NULL);
540 ASSERT (DeviceStatus != NULL);
541 ASSERT (Status != NULL);
542
543 ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
544
545 switch (Recipient) {
546
547 case USB_TARGET_DEVICE:
548 DevReq.RequestType = USB_DEV_GET_STATUS_REQ_TYPE_D;
549 break;
550
551 case USB_TARGET_INTERFACE:
552 DevReq.RequestType = USB_DEV_GET_STATUS_REQ_TYPE_I;
553 break;
554
555 case USB_TARGET_ENDPOINT:
556 DevReq.RequestType = USB_DEV_GET_STATUS_REQ_TYPE_E;
557 break;
558 }
559 //
560 // Fill device request, see USB1.1 spec
561 //
562 DevReq.Request = USB_REQ_GET_STATUS;
563 DevReq.Value = 0;
564 DevReq.Index = Target;
565 DevReq.Length = 2;
566
567 return UsbIo->UsbControlTransfer (
568 UsbIo,
569 &DevReq,
570 EfiUsbDataIn,
571 TIMEOUT_VALUE,
572 DeviceStatus,
573 2,
574 Status
575 );
576 }
577
578
579 /**
580 Clear halt feature of the specified usb endpoint.
581
582 Retrieve the USB endpoint descriptor specified by UsbIo and EndPoint.
583 If the USB endpoint descriptor can not be retrieved, then return EFI_NOT_FOUND.
584 If the endpoint descriptor is found, then clear the halt fature of this USB endpoint.
585 The status of the transfer is returned in Status.
586 If UsbIo is NULL, then ASSERT().
587 If Status is NULL, then ASSERT().
588
589 @param UsbIo A pointer to the USB I/O Protocol instance for the specific USB target.
590 @param Endpoint The endpoint address.
591 @param Status A pointer to the status of the transfer.
592
593 @retval EFI_SUCCESS The request executed successfully.
594 @retval EFI_TIMEOUT A timeout occurred executing the request.
595 @retval EFI_DEVICE_ERROR The request failed due to a device error.
596 The transfer status is returned in Status.
597 @retval EFI_NOT_FOUND The specified USB endpoint descriptor can not be found
598
599 **/
600 EFI_STATUS
601 EFIAPI
602 UsbClearEndpointHalt (
603 IN EFI_USB_IO_PROTOCOL *UsbIo,
604 IN UINT8 Endpoint,
605 OUT UINT32 *Status
606 )
607 {
608 EFI_STATUS Result;
609 EFI_USB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
610 EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
611 UINT8 Index;
612
613 ASSERT (UsbIo != NULL);
614 ASSERT (Status != NULL);
615
616 ZeroMem (&EndpointDescriptor, sizeof (EFI_USB_ENDPOINT_DESCRIPTOR));
617 //
618 // First seach the endpoint descriptor for that endpoint addr
619 //
620 Result = UsbIo->UsbGetInterfaceDescriptor (
621 UsbIo,
622 &InterfaceDescriptor
623 );
624 if (EFI_ERROR (Result)) {
625 return Result;
626 }
627
628 for (Index = 0; Index < InterfaceDescriptor.NumEndpoints; Index++) {
629 Result = UsbIo->UsbGetEndpointDescriptor (
630 UsbIo,
631 Index,
632 &EndpointDescriptor
633 );
634 if (EFI_ERROR (Result)) {
635 continue;
636 }
637
638 if (EndpointDescriptor.EndpointAddress == Endpoint) {
639 break;
640 }
641 }
642
643 if (Index == InterfaceDescriptor.NumEndpoints) {
644 //
645 // No such endpoint
646 //
647 return EFI_NOT_FOUND;
648 }
649
650 Result = UsbClearFeature (
651 UsbIo,
652 USB_TARGET_ENDPOINT,
653 USB_FEATURE_ENDPOINT_HALT,
654 EndpointDescriptor.EndpointAddress,
655 Status
656 );
657
658 return Result;
659 }