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