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