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