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