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