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