]> git.proxmox.com Git - mirror_edk2.git/blob - EdkModulePkg/Bus/Usb/UsbCbi/Dxe/Cbi1/cbi1.c
Make EdkModulePkg pass Intel IPF compiler with /W4 /WX switches, solving warning...
[mirror_edk2.git] / EdkModulePkg / Bus / Usb / UsbCbi / Dxe / Cbi1 / cbi1.c
1 /*++
2
3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 cbi1.c
15
16 Abstract:
17 cbi1 transportation protocol implementation files
18
19 --*/
20
21 #include "cbi.h"
22
23 //
24 // CBI Function prototypes
25 //
26 STATIC
27 EFI_STATUS
28 CBI1CommandPhase (
29 IN USB_CBI_DEVICE *UsbCbiDev,
30 IN VOID *Command,
31 IN UINT8 CommandSize,
32 OUT UINT32 *Result
33 );
34
35 STATIC
36 EFI_STATUS
37 CBI1DataPhase (
38 IN USB_CBI_DEVICE *UsbCbiDev,
39 IN UINT32 DataSize,
40 IN OUT VOID *DataBuffer,
41 IN EFI_USB_DATA_DIRECTION Direction,
42 IN UINT16 Timeout,
43 OUT UINT32 *Result
44 );
45
46 //
47 // USB Atapi implementation
48 //
49 STATIC
50 EFI_STATUS
51 EFIAPI
52 CBI1AtapiCommand (
53 IN EFI_USB_ATAPI_PROTOCOL *This,
54 IN VOID *Command,
55 IN UINT8 CommandSize,
56 IN VOID *DataBuffer,
57 IN UINT32 BufferLength,
58 IN EFI_USB_DATA_DIRECTION Direction,
59 IN UINT16 TimeOutInMilliSeconds
60 );
61
62 STATIC
63 EFI_STATUS
64 EFIAPI
65 CBI1MassStorageReset (
66 IN EFI_USB_ATAPI_PROTOCOL *This,
67 IN BOOLEAN ExtendedVerification
68 );
69
70 //
71 // CBI1 Driver Binding Protocol
72 //
73 STATIC
74 EFI_STATUS
75 EFIAPI
76 CBI1DriverBindingSupported (
77 IN EFI_DRIVER_BINDING_PROTOCOL *This,
78 IN EFI_HANDLE ControllerHandle,
79 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
80 );
81
82 STATIC
83 EFI_STATUS
84 EFIAPI
85 CBI1DriverBindingStart (
86 IN EFI_DRIVER_BINDING_PROTOCOL *This,
87 IN EFI_HANDLE ControllerHandle,
88 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
89 );
90
91 STATIC
92 EFI_STATUS
93 EFIAPI
94 CBI1DriverBindingStop (
95 IN EFI_DRIVER_BINDING_PROTOCOL *This,
96 IN EFI_HANDLE ControllerHandle,
97 IN UINTN NumberOfChildren,
98 IN EFI_HANDLE *ChildHandleBuffer
99 );
100
101 STATIC
102 VOID
103 Cbi1ReportStatusCode (
104 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
105 IN EFI_STATUS_CODE_TYPE CodeType,
106 IN EFI_STATUS_CODE_VALUE Value
107 );
108
109
110 EFI_DRIVER_BINDING_PROTOCOL gUsbCbi1DriverBinding = {
111 CBI1DriverBindingSupported,
112 CBI1DriverBindingStart,
113 CBI1DriverBindingStop,
114 0xa,
115 NULL,
116 NULL
117 };
118
119 STATIC EFI_USB_ATAPI_PROTOCOL CBI1AtapiProtocol = {
120 CBI1AtapiCommand,
121 CBI1MassStorageReset,
122 0
123 };
124
125 //
126 // CBI1 Driver Binding implementation
127 //
128 STATIC
129 EFI_STATUS
130 EFIAPI
131 CBI1DriverBindingSupported (
132 IN EFI_DRIVER_BINDING_PROTOCOL *This,
133 IN EFI_HANDLE ControllerHandle,
134 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
135 )
136 /*++
137
138 Routine Description:
139 Test to see if this driver supports ControllerHandle. Any ControllerHandle
140 than contains a BlockIo and DiskIo protocol can be supported.
141
142 Arguments:
143 This - Protocol instance pointer.
144 ControllerHandle - Handle of device to test
145 RemainingDevicePath - Not used
146
147 Returns:
148 EFI_SUCCESS - This driver supports this device
149 EFI_ALREADY_STARTED - This driver is already running on this device
150 other - This driver does not support this device
151
152 --*/
153 {
154 EFI_STATUS Status;
155 EFI_USB_IO_PROTOCOL *UsbIo;
156 EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
157
158 //
159 // Check if the Controller supports USB IO protocol
160 //
161 Status = gBS->OpenProtocol (
162 ControllerHandle,
163 &gEfiUsbIoProtocolGuid,
164 (VOID **) &UsbIo,
165 This->DriverBindingHandle,
166 ControllerHandle,
167 EFI_OPEN_PROTOCOL_BY_DRIVER
168 );
169 if (EFI_ERROR (Status)) {
170 return Status;
171 }
172 //
173 // Get the Controller interface descriptor
174 //
175 Status = UsbIo->UsbGetInterfaceDescriptor (
176 UsbIo,
177 &InterfaceDescriptor
178 );
179 if (EFI_ERROR (Status)) {
180 goto Exit;
181 }
182 //
183 // Bug here: just let Vendor specific CBI protocol get supported
184 //
185 if (!((InterfaceDescriptor.InterfaceClass == 0xFF) &&
186 (InterfaceDescriptor.InterfaceProtocol == 0))) {
187 Status = EFI_UNSUPPORTED;
188 goto Exit;
189 }
190
191 Exit:
192 gBS->CloseProtocol (
193 ControllerHandle,
194 &gEfiUsbIoProtocolGuid,
195 This->DriverBindingHandle,
196 ControllerHandle
197 );
198 return Status;
199
200 }
201
202 STATIC
203 EFI_STATUS
204 EFIAPI
205 CBI1DriverBindingStart (
206 IN EFI_DRIVER_BINDING_PROTOCOL *This,
207 IN EFI_HANDLE ControllerHandle,
208 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
209 )
210 /*++
211
212 Routine Description:
213 Start this driver on ControllerHandle by opening a Block IO and Disk IO
214 protocol, reading Device Path, and creating a child handle with a
215 Disk IO and device path protocol.
216
217 Arguments:
218 This - Protocol instance pointer.
219 ControllerHandle - Handle of device to bind driver to
220 RemainingDevicePath - Not used
221
222 Returns:
223 EFI_SUCCESS - This driver is added to DeviceHandle
224 EFI_ALREADY_STARTED - This driver is already running on DeviceHandle
225 other - This driver does not support this device
226
227 --*/
228 {
229 USB_CBI_DEVICE *UsbCbiDev;
230 UINT8 Index;
231 EFI_USB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
232 EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
233 EFI_STATUS Status;
234 EFI_USB_IO_PROTOCOL *UsbIo;
235 BOOLEAN Found;
236
237 Found = FALSE;
238 //
239 // Check if the Controller supports USB IO protocol
240 //
241 UsbCbiDev = NULL;
242
243 Status = gBS->OpenProtocol (
244 ControllerHandle,
245 &gEfiUsbIoProtocolGuid,
246 (VOID **) &UsbIo,
247 This->DriverBindingHandle,
248 ControllerHandle,
249 EFI_OPEN_PROTOCOL_BY_DRIVER
250 );
251 if (EFI_ERROR (Status)) {
252 return Status;
253 }
254 //
255 // Get the controller interface descriptor
256 //
257 Status = UsbIo->UsbGetInterfaceDescriptor (
258 UsbIo,
259 &InterfaceDescriptor
260 );
261 if (EFI_ERROR (Status)) {
262 goto ErrorExit;
263 }
264
265 CBI1AtapiProtocol.CommandProtocol = InterfaceDescriptor.InterfaceSubClass;
266
267 UsbCbiDev = AllocateZeroPool (sizeof (USB_CBI_DEVICE));
268 if (UsbCbiDev == NULL) {
269 Status = EFI_OUT_OF_RESOURCES;
270 goto ErrorExit;
271 }
272
273 UsbCbiDev->Signature = USB_CBI_DEVICE_SIGNATURE;
274 UsbCbiDev->UsbIo = UsbIo;
275 CopyMem (&UsbCbiDev->InterfaceDescriptor, &InterfaceDescriptor, sizeof (InterfaceDescriptor));
276 CopyMem (&UsbCbiDev->UsbAtapiProtocol , &CBI1AtapiProtocol, sizeof (CBI1AtapiProtocol));
277
278 //
279 // Get the Device Path Protocol on Controller's handle
280 //
281 Status = gBS->OpenProtocol (
282 ControllerHandle,
283 &gEfiDevicePathProtocolGuid,
284 (VOID **) &UsbCbiDev->DevicePath,
285 This->DriverBindingHandle,
286 ControllerHandle,
287 EFI_OPEN_PROTOCOL_GET_PROTOCOL
288 );
289
290 if (EFI_ERROR (Status)) {
291 goto ErrorExit;
292 }
293
294 for (Index = 0; Index < InterfaceDescriptor.NumEndpoints; Index++) {
295 UsbIo->UsbGetEndpointDescriptor (
296 UsbIo,
297 Index,
298 &EndpointDescriptor
299 );
300
301 //
302 // We parse bulk endpoint
303 //
304 if (EndpointDescriptor.Attributes == 0x02) {
305 if (EndpointDescriptor.EndpointAddress & 0x80) {
306 CopyMem (&UsbCbiDev->BulkInEndpointDescriptor, &EndpointDescriptor, sizeof (EndpointDescriptor));
307 } else {
308 CopyMem (&UsbCbiDev->BulkOutEndpointDescriptor, &EndpointDescriptor, sizeof (EndpointDescriptor));
309 }
310
311 Found = TRUE;
312 }
313 //
314 // We parse interrupt endpoint
315 //
316 if (EndpointDescriptor.Attributes == 0x03) {
317 CopyMem (&UsbCbiDev->InterruptEndpointDescriptor, &EndpointDescriptor, sizeof (EndpointDescriptor));
318 Found = TRUE;
319 }
320
321 }
322 //
323 // Double check we have these
324 //
325 if (!Found) {
326 goto ErrorExit;
327 }
328 //
329 // After installing Usb-Atapi protocol onto this handle
330 // it will be called by upper layer drivers such as Fat
331 //
332 Cbi1ReportStatusCode (
333 UsbCbiDev->DevicePath,
334 EFI_PROGRESS_CODE,
335 (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_ENABLE)
336 );
337
338 Status = gBS->InstallProtocolInterface (
339 &ControllerHandle,
340 &gEfiUsbAtapiProtocolGuid,
341 EFI_NATIVE_INTERFACE,
342 &UsbCbiDev->UsbAtapiProtocol
343 );
344
345 if (EFI_ERROR (Status)) {
346 goto ErrorExit;
347 }
348
349 UsbCbiDev->ControllerNameTable = NULL;
350 AddUnicodeString (
351 "eng",
352 gUsbCbi1ComponentName.SupportedLanguages,
353 &UsbCbiDev->ControllerNameTable,
354 (CHAR16 *) L"Usb Cbi1 Mass Storage"
355 );
356
357 return EFI_SUCCESS;
358
359 ErrorExit:
360 gBS->CloseProtocol (
361 ControllerHandle,
362 &gEfiUsbIoProtocolGuid,
363 This->DriverBindingHandle,
364 ControllerHandle
365 );
366 if (UsbCbiDev != NULL) {
367 gBS->FreePool (UsbCbiDev);
368 }
369
370 return Status;
371
372 }
373
374 STATIC
375 EFI_STATUS
376 EFIAPI
377 CBI1DriverBindingStop (
378 IN EFI_DRIVER_BINDING_PROTOCOL *This,
379 IN EFI_HANDLE ControllerHandle,
380 IN UINTN NumberOfChildren,
381 IN EFI_HANDLE *ChildHandleBuffer
382 )
383 /*++
384
385 Routine Description:
386 Stop this driver on ControllerHandle. Support stoping any child handles
387 created by this driver.
388
389 Arguments:
390 This - Protocol instance pointer.
391 ControllerHandle - Handle of device to stop driver on
392 NumberOfChildren - Number of Children in the ChildHandleBuffer
393 ChildHandleBuffer - List of handles for the children we need to stop.
394
395 Returns:
396 EFI_SUCCESS - This driver is removed DeviceHandle
397 EFI_UNSUPPORTED - Can't open the gEfiUsbAtapiProtocolGuid protocol
398 other - This driver was not removed from this device
399
400 --*/
401 {
402 EFI_STATUS Status;
403 EFI_USB_ATAPI_PROTOCOL *CBI1AtapiProtocol;
404 USB_CBI_DEVICE *UsbCbiDev;
405
406 //
407 // Get our context back.
408 //
409 Status = gBS->OpenProtocol (
410 ControllerHandle,
411 &gEfiUsbAtapiProtocolGuid,
412 (VOID **) &CBI1AtapiProtocol,
413 This->DriverBindingHandle,
414 ControllerHandle,
415 EFI_OPEN_PROTOCOL_GET_PROTOCOL
416 );
417 if (EFI_ERROR (Status)) {
418 return EFI_UNSUPPORTED;
419 }
420
421 UsbCbiDev = USB_CBI_DEVICE_FROM_THIS (CBI1AtapiProtocol);
422
423 Cbi1ReportStatusCode (
424 UsbCbiDev->DevicePath,
425 EFI_PROGRESS_CODE,
426 (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_DISABLE)
427 );
428
429 Status = gBS->UninstallProtocolInterface (
430 ControllerHandle,
431 &gEfiUsbAtapiProtocolGuid,
432 &UsbCbiDev->UsbAtapiProtocol
433 );
434 if (EFI_ERROR (Status)) {
435 return Status;
436 }
437
438 Status = gBS->CloseProtocol (
439 ControllerHandle,
440 &gEfiUsbIoProtocolGuid,
441 This->DriverBindingHandle,
442 ControllerHandle
443 );
444 gBS->FreePool (UsbCbiDev);
445
446 return Status;
447
448 }
449 //
450 // CBI1 command
451 //
452 STATIC
453 EFI_STATUS
454 CBI1CommandPhase (
455 IN USB_CBI_DEVICE *UsbCbiDev,
456 IN VOID *Command,
457 IN UINT8 CommandSize,
458 OUT UINT32 *Result
459 )
460 /*++
461
462 Routine Description:
463 In order to make consistence, CBI transportation protocol does only use
464 the first 3 parameters. Other parameters are not used here.
465
466 Arguments:
467 UsbCbiDev - USB_CBI_DEVICE
468 Command - Command to send
469 CommandSize - Command Size
470 Result - Result to return
471
472 Returns:
473 EFI_SUCCESS - This driver is removed DeviceHandle
474 other - This driver was not removed from this device
475 --*/
476 {
477 EFI_STATUS Status;
478 EFI_USB_IO_PROTOCOL *UsbIo;
479 EFI_USB_DEVICE_REQUEST Request;
480 UINT32 TimeOutInMilliSeconds;
481
482 UsbIo = UsbCbiDev->UsbIo;
483
484 ZeroMem (&Request, sizeof (EFI_USB_DEVICE_REQUEST));
485
486 //
487 // Device request see CBI specification
488 //
489 Request.RequestType = 0x21;
490 Request.Length = CommandSize;
491
492 TimeOutInMilliSeconds = 1000;
493
494 Status = UsbIo->UsbControlTransfer (
495 UsbIo,
496 &Request,
497 EfiUsbDataOut,
498 TimeOutInMilliSeconds,
499 Command,
500 CommandSize,
501 Result
502 );
503
504 return Status;
505 }
506
507 STATIC
508 EFI_STATUS
509 CBI1DataPhase (
510 IN USB_CBI_DEVICE *UsbCbiDev,
511 IN UINT32 DataSize,
512 IN OUT VOID *DataBuffer,
513 IN EFI_USB_DATA_DIRECTION Direction,
514 IN UINT16 Timeout,
515 OUT UINT32 *Result
516 )
517 /*++
518
519 Routine Description:
520
521 CBI1 Data Phase
522
523 Arguments:
524
525 UsbCbiDev - USB_CBI_DEVICE
526 DataSize - Data Size
527 DataBuffer - Data Buffer
528 Direction - IN/OUT/NODATA
529 Timeout - Time out value in milliseconds
530 Result - Transfer result
531
532 Returns:
533
534 EFI_SUCCESS - Success
535
536 --*/
537 {
538 EFI_STATUS Status;
539 EFI_USB_IO_PROTOCOL *UsbIo;
540 UINT8 EndpointAddr;
541 UINTN Remain;
542 UINTN Increment;
543 UINT32 MaxPacketLen;
544 UINT8 *BufferPtr;
545
546 UsbIo = UsbCbiDev->UsbIo;
547
548 Remain = DataSize;
549 BufferPtr = (UINT8 *) DataBuffer;
550
551 //
552 // retrieve the the max packet length of the given endpoint
553 //
554 if (Direction == EfiUsbDataIn) {
555 MaxPacketLen = (UsbCbiDev->BulkInEndpointDescriptor).MaxPacketSize;
556 EndpointAddr = (UsbCbiDev->BulkInEndpointDescriptor).EndpointAddress;
557 } else {
558 MaxPacketLen = (UsbCbiDev->BulkOutEndpointDescriptor).MaxPacketSize;
559 EndpointAddr = (UsbCbiDev->BulkOutEndpointDescriptor).EndpointAddress;
560 }
561
562 while (Remain > 0) {
563 //
564 // Using 15 packets to aVOID Bitstuff error
565 //
566 if (Remain > 15 * MaxPacketLen) {
567 Increment = 15 * MaxPacketLen;
568 } else {
569 Increment = Remain;
570 }
571
572 Status = UsbIo->UsbBulkTransfer (
573 UsbIo,
574 EndpointAddr,
575 BufferPtr,
576 &Increment,
577 Timeout,
578 Result
579 );
580
581 if (EFI_ERROR (Status)) {
582 goto ErrorExit;
583 }
584
585 BufferPtr += Increment;
586 Remain -= Increment;
587 }
588
589 return EFI_SUCCESS;
590
591 ErrorExit:
592
593 if (Direction == EfiUsbDataIn) {
594 Cbi1ReportStatusCode (
595 UsbCbiDev->DevicePath,
596 EFI_ERROR_CODE | EFI_ERROR_MINOR,
597 (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_EC_INPUT_ERROR)
598 );
599 } else {
600 Cbi1ReportStatusCode (
601 UsbCbiDev->DevicePath,
602 EFI_ERROR_CODE | EFI_ERROR_MINOR,
603 (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_EC_OUTPUT_ERROR)
604 );
605 }
606
607 if (((*Result) & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {
608 //
609 // just endpoint stall happens
610 //
611 UsbClearEndpointHalt (
612 UsbIo,
613 EndpointAddr,
614 Result
615 );
616 }
617
618 return Status;
619 }
620 //
621 // CBI1 USB ATAPI Protocol
622 //
623 STATIC
624 EFI_STATUS
625 EFIAPI
626 CBI1MassStorageReset (
627 IN EFI_USB_ATAPI_PROTOCOL *This,
628 IN BOOLEAN ExtendedVerification
629 )
630 /*++
631
632 Routine Description:
633 Reset CBI Devices
634
635 Arguments:
636 This - Protocol instance pointer.
637 ExtendedVerification - TRUE if we need to do strictly reset.
638
639 Returns:
640 EFI_SUCCESS - Command succeeded.
641 EFI_DEVICE_ERROR - Command failed.
642
643 --*/
644 {
645 UINT8 ResetCommand[12];
646 EFI_USB_IO_PROTOCOL *UsbIo;
647 USB_CBI_DEVICE *UsbCbiDev;
648 UINT8 EndpointAddr;
649 UINT32 Result;
650
651 UsbCbiDev = USB_CBI_DEVICE_FROM_THIS (This);
652 UsbIo = UsbCbiDev->UsbIo;
653
654 Cbi1ReportStatusCode (
655 UsbCbiDev->DevicePath,
656 EFI_PROGRESS_CODE,
657 (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_RESET)
658 );
659
660 if (ExtendedVerification) {
661 UsbIo->UsbPortReset (UsbIo);
662 }
663 //
664 // CBI reset command protocol
665 //
666 SetMem (ResetCommand, sizeof (ResetCommand), 0xff);
667 ResetCommand[0] = 0x1d;
668 ResetCommand[1] = 0x04;
669
670 CBI1CommandPhase (
671 UsbCbiDev,
672 ResetCommand,
673 12,
674 &Result
675 );
676
677 //
678 // clear bulk in endpoint stall feature
679 //
680 EndpointAddr = UsbCbiDev->BulkInEndpointDescriptor.EndpointAddress;
681 UsbClearEndpointHalt (
682 UsbIo,
683 EndpointAddr,
684 &Result
685 );
686
687 //
688 // clear bulk out endpoint stall feature
689 //
690 EndpointAddr = UsbCbiDev->BulkOutEndpointDescriptor.EndpointAddress;
691 UsbClearEndpointHalt (
692 UsbIo,
693 EndpointAddr,
694 &Result
695 );
696
697 return EFI_SUCCESS;
698
699 }
700
701 STATIC
702 EFI_STATUS
703 EFIAPI
704 CBI1AtapiCommand (
705 IN EFI_USB_ATAPI_PROTOCOL *This,
706 IN VOID *Command,
707 IN UINT8 CommandSize,
708 IN VOID *DataBuffer,
709 IN UINT32 BufferLength,
710 IN EFI_USB_DATA_DIRECTION Direction,
711 IN UINT16 TimeOutInMilliSeconds
712 )
713 /*++
714
715 Routine Description:
716 Send ATAPI command using CBI1 protocol.
717
718 Arguments:
719 This - Protocol instance pointer.
720 Command - Command buffer
721 CommandSize - Size of Command Buffer
722 DataBuffer - Data buffer
723 BufferLength - Length of Data buffer
724 Direction - Data direction of this command
725 TimeOutInMilliSeconds - Timeout value in ms
726
727 Returns:
728 EFI_SUCCESS - Command succeeded.
729 EFI_DEVICE_ERROR - Command failed.
730
731 --*/
732 {
733 EFI_STATUS Status;
734 USB_CBI_DEVICE *UsbCbiDev;
735 UINT32 Result;
736 UINT8 Index;
737 UINT8 MaxRetryNum;
738
739 UsbCbiDev = USB_CBI_DEVICE_FROM_THIS (This);
740
741 MaxRetryNum = 3;
742
743 for (Index = 0; Index < MaxRetryNum; Index++) {
744
745 //
746 // First send ATAPI command through CBI1
747 //
748 Status = CBI1CommandPhase (
749 UsbCbiDev,
750 Command,
751 CommandSize,
752 &Result
753 );
754 if (EFI_ERROR (Status)) {
755
756 switch (Result) {
757
758 case EFI_USB_NOERROR:
759 case EFI_USB_ERR_STALL:
760 case EFI_USB_ERR_SYSTEM:
761 return EFI_DEVICE_ERROR;
762
763 default:
764 continue;
765 break;
766 }
767 } else {
768 break;
769 }
770 }
771
772 if (Index == MaxRetryNum) {
773 return EFI_DEVICE_ERROR;
774 }
775
776 for (Index = 0; Index < MaxRetryNum; Index++) {
777 //
778 // Send/Get Data if there is a Data Stage
779 //
780 switch (Direction) {
781
782 case EfiUsbDataIn:
783 case EfiUsbDataOut:
784 Status = CBI1DataPhase (
785 UsbCbiDev,
786 BufferLength,
787 DataBuffer,
788 Direction,
789 TimeOutInMilliSeconds,
790 &Result
791 );
792
793 if (EFI_ERROR (Status)) {
794 switch (Result) {
795
796 case EFI_USB_NOERROR:
797 case EFI_USB_ERR_STALL:
798 case EFI_USB_ERR_SYSTEM:
799 return EFI_DEVICE_ERROR;
800
801 default:
802 continue;
803 break;
804 }
805
806 } else {
807
808 return EFI_SUCCESS;
809 }
810 break;
811
812 case EfiUsbNoData:
813 return EFI_SUCCESS;
814 }
815 }
816 //
817 // If goes here, means met error.
818 //
819 return EFI_DEVICE_ERROR;
820 }
821
822 STATIC
823 VOID
824 Cbi1ReportStatusCode (
825 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
826 IN EFI_STATUS_CODE_TYPE CodeType,
827 IN EFI_STATUS_CODE_VALUE Value
828 )
829 /*++
830
831 Routine Description:
832 Report Status Code in Usb Cbi1 Driver
833
834 Arguments:
835 DevicePath - Use this to get Device Path
836 CodeType - Status Code Type
837 CodeValue - Status Code Value
838
839 Returns:
840 None
841
842 --*/
843 {
844 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
845 CodeType,
846 Value,
847 DevicePath
848 );
849
850 }