]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Bus/Usb/UsbCbi/Dxe/Cbi1/cbi1.c
Move the share file: cbi.h to Cbi0 and Cbi1 directory.
[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
120 0x10,\r
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
312 CopyMem (&UsbCbiDev->BulkInEndpointDescriptor, &EndpointDescriptor, sizeof(EndpointDescriptor));\r
313 //UsbCbiDev->BulkInEndpointDescriptor = EndpointDescriptor;\r
314 } else {\r
315 CopyMem (&UsbCbiDev->BulkOutEndpointDescriptor, &EndpointDescriptor, sizeof(EndpointDescriptor));\r
316 //UsbCbiDev->BulkOutEndpointDescriptor = EndpointDescriptor;\r
317 }\r
318\r
319 Found = TRUE;\r
320 }\r
321 //\r
322 // We parse interrupt endpoint\r
323 //\r
324 if (EndpointDescriptor.Attributes == 0x03) {\r
325 CopyMem (&UsbCbiDev->InterruptEndpointDescriptor, &EndpointDescriptor, sizeof(EndpointDescriptor));\r
326 //UsbCbiDev->InterruptEndpointDescriptor = EndpointDescriptor;\r
327 Found = TRUE;\r
328 }\r
329\r
330 }\r
331 //\r
332 // Double check we have these\r
333 //\r
334 if (!Found) {\r
335 goto ErrorExit;\r
336 }\r
337 //\r
338 // After installing Usb-Atapi protocol onto this handle\r
339 // it will be called by upper layer drivers such as Fat\r
340 //\r
341 Cbi1ReportStatusCode (\r
342 UsbCbiDev->DevicePath,\r
343 EFI_PROGRESS_CODE,\r
344 (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_ENABLE)\r
345 );\r
346\r
347 Status = gBS->InstallProtocolInterface (\r
348 &ControllerHandle,\r
349 &gEfiUsbAtapiProtocolGuid,\r
350 EFI_NATIVE_INTERFACE,\r
351 &UsbCbiDev->UsbAtapiProtocol\r
352 );\r
353\r
354 if (EFI_ERROR (Status)) {\r
355 goto ErrorExit;\r
356 }\r
357\r
358 return EFI_SUCCESS;\r
359\r
360ErrorExit:\r
361 gBS->CloseProtocol (\r
362 ControllerHandle,\r
363 &gEfiUsbIoProtocolGuid,\r
364 This->DriverBindingHandle,\r
365 ControllerHandle\r
366 );\r
367 if (UsbCbiDev != NULL) {\r
368 gBS->FreePool (UsbCbiDev);\r
369 }\r
370\r
371 return Status;\r
372\r
373}\r
374\r
375STATIC\r
376EFI_STATUS\r
377EFIAPI\r
378CBI1DriverBindingStop (\r
379 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
380 IN EFI_HANDLE ControllerHandle,\r
381 IN UINTN NumberOfChildren,\r
382 IN EFI_HANDLE *ChildHandleBuffer\r
383 )\r
384/*++\r
385\r
386 Routine Description:\r
387 Stop this driver on ControllerHandle. Support stoping any child handles \r
388 created by this driver.\r
389\r
390 Arguments:\r
391 This - Protocol instance pointer.\r
392 ControllerHandle - Handle of device to stop driver on \r
393 NumberOfChildren - Number of Children in the ChildHandleBuffer\r
394 ChildHandleBuffer - List of handles for the children we need to stop.\r
395\r
396 Returns:\r
397 EFI_SUCCESS - This driver is removed DeviceHandle\r
398 EFI_UNSUPPORTED - Can't open the gEfiUsbAtapiProtocolGuid protocol \r
399 other - This driver was not removed from this device\r
400 \r
401--*/\r
402{\r
403 EFI_STATUS Status;\r
404 EFI_USB_ATAPI_PROTOCOL *CBI1AtapiProtocol;\r
405 USB_CBI_DEVICE *UsbCbiDev;\r
406 EFI_USB_IO_PROTOCOL *UsbIo;\r
407\r
408 //\r
409 // Get our context back.\r
410 //\r
411 Status = gBS->OpenProtocol (\r
412 ControllerHandle,\r
413 &gEfiUsbAtapiProtocolGuid,\r
414 (VOID **) &CBI1AtapiProtocol,\r
415 This->DriverBindingHandle,\r
416 ControllerHandle,\r
417 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
418 );\r
419 if (EFI_ERROR (Status)) {\r
420 return EFI_UNSUPPORTED;\r
421 }\r
422\r
423 UsbCbiDev = USB_CBI_DEVICE_FROM_THIS (CBI1AtapiProtocol);\r
424\r
425 UsbIo = UsbCbiDev->UsbIo;\r
426\r
427 Cbi1ReportStatusCode (\r
428 UsbCbiDev->DevicePath,\r
429 EFI_PROGRESS_CODE,\r
430 (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_DISABLE)\r
431 );\r
432\r
433 Status = gBS->UninstallProtocolInterface (\r
434 ControllerHandle,\r
435 &gEfiUsbAtapiProtocolGuid,\r
436 &UsbCbiDev->UsbAtapiProtocol\r
437 );\r
438 if (EFI_ERROR (Status)) {\r
439 return Status;\r
440 }\r
441\r
442 Status = gBS->CloseProtocol (\r
443 ControllerHandle,\r
444 &gEfiUsbIoProtocolGuid,\r
445 This->DriverBindingHandle,\r
446 ControllerHandle\r
447 );\r
448 gBS->FreePool (UsbCbiDev);\r
449\r
450 return Status;\r
451\r
452}\r
453//\r
454// CBI1 command\r
455//\r
456STATIC\r
457EFI_STATUS\r
458CBI1CommandPhase (\r
459 IN USB_CBI_DEVICE *UsbCbiDev,\r
460 IN VOID *Command,\r
461 IN UINT8 CommandSize,\r
462 OUT UINT32 *Result\r
463 )\r
464/*++\r
465\r
466 Routine Description:\r
467 In order to make consistence, CBI transportation protocol does only use\r
468 the first 3 parameters. Other parameters are not used here.\r
469\r
470 Arguments:\r
471 UsbCbiDev - USB_CBI_DEVICE\r
472 Command - Command to send \r
473 CommandSize - Command Size\r
474 Result - Result to return\r
475\r
476 Returns:\r
477 EFI_SUCCESS - This driver is removed DeviceHandle\r
478 other - This driver was not removed from this device \r
479--*/\r
480{\r
481 EFI_STATUS Status;\r
482 EFI_USB_IO_PROTOCOL *UsbIo;\r
483 EFI_USB_DEVICE_REQUEST Request;\r
484 UINT32 TimeOutInMilliSeconds;\r
485\r
486 UsbIo = UsbCbiDev->UsbIo;\r
487\r
488 ZeroMem (&Request, sizeof (EFI_USB_DEVICE_REQUEST));\r
489\r
490 //\r
491 // Device request see CBI specification\r
492 //\r
493 Request.RequestType = 0x21;\r
494 Request.Length = CommandSize;\r
495\r
496 TimeOutInMilliSeconds = 1000;\r
497\r
498 Status = UsbIo->UsbControlTransfer (\r
499 UsbIo,\r
500 &Request,\r
501 EfiUsbDataOut,\r
502 TimeOutInMilliSeconds,\r
503 Command,\r
504 CommandSize,\r
505 Result\r
506 );\r
507\r
508 return Status;\r
509}\r
510\r
511STATIC\r
512EFI_STATUS\r
513CBI1DataPhase (\r
514 IN USB_CBI_DEVICE *UsbCbiDev,\r
515 IN UINT32 DataSize,\r
516 IN OUT VOID *DataBuffer,\r
517 IN EFI_USB_DATA_DIRECTION Direction,\r
518 IN UINT16 Timeout,\r
519 OUT UINT32 *Result\r
520 )\r
521/*++\r
522\r
523Routine Description:\r
524\r
525 CBI1 Data Phase\r
526\r
527Arguments:\r
528\r
529 UsbCbiDev - USB_CBI_DEVICE\r
530 DataSize - Data Size\r
531 DataBuffer - Data Buffer\r
532 Direction - IN/OUT/NODATA\r
533 Timeout - Time out value in milliseconds\r
534 Result - Transfer result\r
535\r
536Returns:\r
537\r
538 EFI_SUCCESS - Success\r
539\r
540--*/\r
541{\r
542 EFI_STATUS Status;\r
543 EFI_USB_IO_PROTOCOL *UsbIo;\r
544 UINT8 EndpointAddr;\r
545 UINTN Remain;\r
546 UINTN Increment;\r
547 UINT32 MaxPacketLen;\r
548 UINT8 *BufferPtr;\r
549\r
550 UsbIo = UsbCbiDev->UsbIo;\r
551\r
552 Remain = DataSize;\r
553 BufferPtr = (UINT8 *) DataBuffer;\r
554\r
555 //\r
556 // retrieve the the max packet length of the given endpoint\r
557 //\r
558 if (Direction == EfiUsbDataIn) {\r
559 MaxPacketLen = (UsbCbiDev->BulkInEndpointDescriptor).MaxPacketSize;\r
560 EndpointAddr = (UsbCbiDev->BulkInEndpointDescriptor).EndpointAddress;\r
561 } else {\r
562 MaxPacketLen = (UsbCbiDev->BulkOutEndpointDescriptor).MaxPacketSize;\r
563 EndpointAddr = (UsbCbiDev->BulkOutEndpointDescriptor).EndpointAddress;\r
564 }\r
565\r
566 while (Remain > 0) {\r
567 //\r
568 // Using 15 packets to aVOID Bitstuff error\r
569 //\r
570 if (Remain > 15 * MaxPacketLen) {\r
571 Increment = 15 * MaxPacketLen;\r
572 } else {\r
573 Increment = Remain;\r
574 }\r
575\r
576 Status = UsbIo->UsbBulkTransfer (\r
577 UsbIo,\r
578 EndpointAddr,\r
579 BufferPtr,\r
580 &Increment,\r
581 Timeout,\r
582 Result\r
583 );\r
584\r
585 if (EFI_ERROR (Status)) {\r
586 goto ErrorExit;\r
587 }\r
588\r
589 BufferPtr += Increment;\r
590 Remain -= Increment;\r
591 }\r
592\r
593 return EFI_SUCCESS;\r
594\r
595ErrorExit:\r
596\r
597 if (Direction == EfiUsbDataIn) {\r
598 Cbi1ReportStatusCode (\r
599 UsbCbiDev->DevicePath,\r
600 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
601 (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_EC_INPUT_ERROR)\r
602 );\r
603 } else {\r
604 Cbi1ReportStatusCode (\r
605 UsbCbiDev->DevicePath,\r
606 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
607 (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_EC_OUTPUT_ERROR)\r
608 );\r
609 }\r
610\r
611 if (((*Result) & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {\r
612 //\r
613 // just endpoint stall happens\r
614 //\r
615 UsbClearEndpointHalt (\r
616 UsbIo,\r
617 EndpointAddr,\r
618 Result\r
619 );\r
620 }\r
621\r
622 return Status;\r
623}\r
624//\r
625// CBI1 USB ATAPI Protocol\r
626//\r
627STATIC\r
628EFI_STATUS\r
629EFIAPI\r
630CBI1MassStorageReset (\r
631 IN EFI_USB_ATAPI_PROTOCOL *This,\r
632 IN BOOLEAN ExtendedVerification\r
633 )\r
634/*++\r
635\r
636 Routine Description:\r
637 Reset CBI Devices\r
638 \r
639 Arguments:\r
640 This - Protocol instance pointer.\r
641 ExtendedVerification - TRUE if we need to do strictly reset.\r
642\r
643 Returns:\r
644 EFI_SUCCESS - Command succeeded.\r
645 EFI_DEVICE_ERROR - Command failed.\r
646\r
647--*/\r
648{\r
649 UINT8 ResetCommand[12];\r
650 EFI_STATUS Status;\r
651 EFI_USB_IO_PROTOCOL *UsbIo;\r
652 USB_CBI_DEVICE *UsbCbiDev;\r
653 UINT8 EndpointAddr;\r
654 UINT32 Result;\r
655\r
656 UsbCbiDev = USB_CBI_DEVICE_FROM_THIS (This);\r
657 UsbIo = UsbCbiDev->UsbIo;\r
658\r
659 Cbi1ReportStatusCode (\r
660 UsbCbiDev->DevicePath,\r
661 EFI_PROGRESS_CODE,\r
662 (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_RESET)\r
663 );\r
664\r
665 if (ExtendedVerification) {\r
666 UsbIo->UsbPortReset (UsbIo);\r
667 }\r
668 //\r
669 // CBI reset command protocol\r
670 //\r
671 SetMem (ResetCommand, sizeof (ResetCommand), 0xff);\r
672 ResetCommand[0] = 0x1d;\r
673 ResetCommand[1] = 0x04;\r
674\r
675 Status = CBI1CommandPhase (\r
676 UsbCbiDev,\r
677 ResetCommand,\r
678 12,\r
679 &Result\r
680 );\r
681\r
682 //\r
683 // clear bulk in endpoint stall feature\r
684 //\r
685 EndpointAddr = UsbCbiDev->BulkInEndpointDescriptor.EndpointAddress;\r
686 UsbClearEndpointHalt (\r
687 UsbIo,\r
688 EndpointAddr,\r
689 &Result\r
690 );\r
691\r
692 //\r
693 // clear bulk out endpoint stall feature\r
694 //\r
695 EndpointAddr = UsbCbiDev->BulkOutEndpointDescriptor.EndpointAddress;\r
696 UsbClearEndpointHalt (\r
697 UsbIo,\r
698 EndpointAddr,\r
699 &Result\r
700 );\r
701\r
702 return EFI_SUCCESS;\r
703\r
704}\r
705\r
706STATIC\r
707EFI_STATUS\r
708EFIAPI\r
709CBI1AtapiCommand (\r
710 IN EFI_USB_ATAPI_PROTOCOL *This,\r
711 IN VOID *Command,\r
712 IN UINT8 CommandSize,\r
713 IN VOID *DataBuffer,\r
714 IN UINT32 BufferLength,\r
715 IN EFI_USB_DATA_DIRECTION Direction,\r
716 IN UINT16 TimeOutInMilliSeconds\r
717 )\r
718/*++\r
719\r
720 Routine Description:\r
721 Send ATAPI command using CBI1 protocol.\r
722 \r
723 Arguments:\r
724 This - Protocol instance pointer.\r
725 Command - Command buffer \r
726 CommandSize - Size of Command Buffer\r
727 DataBuffer - Data buffer\r
728 BufferLength - Length of Data buffer\r
729 Direction - Data direction of this command\r
730 TimeOutInMilliSeconds - Timeout value in ms\r
731\r
732 Returns:\r
733 EFI_SUCCESS - Command succeeded.\r
734 EFI_DEVICE_ERROR - Command failed.\r
735\r
736--*/\r
737{\r
738 EFI_STATUS Status;\r
739 USB_CBI_DEVICE *UsbCbiDev;\r
740 UINT32 Result;\r
741 UINT8 Index;\r
742 UINT8 MaxRetryNum;\r
743\r
744 UsbCbiDev = USB_CBI_DEVICE_FROM_THIS (This);\r
745\r
746 MaxRetryNum = 3;\r
747\r
748 for (Index = 0; Index < MaxRetryNum; Index++) {\r
749 \r
750 //\r
751 // First send ATAPI command through CBI1\r
752 //\r
753 Status = CBI1CommandPhase (\r
754 UsbCbiDev,\r
755 Command,\r
756 CommandSize,\r
757 &Result\r
758 );\r
759 if (EFI_ERROR (Status)) {\r
760\r
761 switch (Result) {\r
762\r
763 case EFI_USB_NOERROR:\r
764 case EFI_USB_ERR_STALL:\r
765 case EFI_USB_ERR_SYSTEM:\r
766 return EFI_DEVICE_ERROR;\r
767\r
768 default:\r
769 continue;\r
770 break;\r
771 }\r
772 } else {\r
773 break;\r
774 }\r
775 }\r
776\r
777 if (Index == MaxRetryNum) {\r
778 return EFI_DEVICE_ERROR;\r
779 }\r
780\r
781 for (Index = 0; Index < MaxRetryNum; Index++) {\r
782 //\r
783 // Send/Get Data if there is a Data Stage\r
784 //\r
785 switch (Direction) {\r
786\r
787 case EfiUsbDataIn:\r
788 case EfiUsbDataOut:\r
789 Status = CBI1DataPhase (\r
790 UsbCbiDev,\r
791 BufferLength,\r
792 DataBuffer,\r
793 Direction,\r
794 TimeOutInMilliSeconds,\r
795 &Result\r
796 );\r
797\r
798 if (EFI_ERROR (Status)) {\r
799 switch (Result) {\r
800\r
801 case EFI_USB_NOERROR:\r
802 case EFI_USB_ERR_STALL:\r
803 case EFI_USB_ERR_SYSTEM:\r
804 return EFI_DEVICE_ERROR;\r
805\r
806 default:\r
807 continue;\r
808 break;\r
809 }\r
810\r
811 } else {\r
812\r
813 return EFI_SUCCESS;\r
814 }\r
815 break;\r
816\r
817 case EfiUsbNoData:\r
818 return EFI_SUCCESS;\r
819 }\r
820 }\r
821 //\r
822 // If goes here, means met error.\r
823 //\r
824 return EFI_DEVICE_ERROR;\r
825}\r
826\r
827VOID\r
828Cbi1ReportStatusCode (\r
829 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
830 IN EFI_STATUS_CODE_TYPE CodeType,\r
831 IN EFI_STATUS_CODE_VALUE Value\r
832 )\r
833/*++\r
834\r
835 Routine Description:\r
836 Report Status Code in Usb Cbi1 Driver\r
837\r
838 Arguments:\r
839 DevicePath - Use this to get Device Path\r
840 CodeType - Status Code Type\r
841 CodeValue - Status Code Value\r
842\r
843 Returns:\r
844 None\r
845\r
846--*/\r
847{\r
848 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
849 CodeType,\r
850 Value,\r
851 DevicePath\r
852 );\r
853\r
854}\r