1. Sync Tcp4 protocol definitions to match UEFI 2.1
[people/mcb30/edk2.git] / edk2 / MdeModulePkg / Bus / Usb / UsbMassStorageDxe / UsbMassImpl.c
1 /** @file\r
2 \r
3 Copyright (c) 2007, Intel Corporation\r
4 All rights reserved. This program and the accompanying materials\r
5 are licensed and made available under the terms and conditions of the BSD License\r
6 which accompanies this distribution.  The full text of the license may be found at\r
7 http://opensource.org/licenses/bsd-license.php\r
8 \r
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11 \r
12 Module Name:\r
13 \r
14   UsbMassImpl.c\r
15 \r
16 Abstract:\r
17 \r
18   The implementation of USB mass storage class device driver.\r
19   The command set supported is "USB Mass Storage Specification\r
20   for Bootability".\r
21 \r
22 Revision History\r
23 \r
24 \r
25 **/\r
26 \r
27 #include "UsbMassImpl.h"\r
28 \r
29 //\r
30 // The underlying transport protocol. CBI support isn't included\r
31 // in the current build. It is being obseleted by the standard\r
32 // body. If you want to enable it, remove the if directive here,\r
33 // then add the UsbMassCbi.c/.h to the driver's inf file.\r
34 //\r
35 STATIC\r
36 USB_MASS_TRANSPORT *mUsbMassTransport[] = {\r
37   &mUsbCbi0Transport,\r
38   &mUsbCbi1Transport,\r
39   &mUsbBotTransport,\r
40   NULL\r
41 };\r
42 \r
43 UINTN mUsbMscInfo  = DEBUG_INFO;\r
44 UINTN mUsbMscError = DEBUG_ERROR;\r
45 \r
46 \r
47 /**\r
48   Retrieve the media parameters such as disk gemotric for the\r
49   device's BLOCK IO protocol.\r
50 \r
51   @param  UsbMass                The USB mass storage device\r
52 \r
53   @retval EFI_SUCCESS            The media parameters is updated successfully.\r
54   @retval Others                 Failed to get the media parameters.\r
55 \r
56 **/\r
57 EFI_STATUS\r
58 UsbMassInitMedia (\r
59   IN USB_MASS_DEVICE          *UsbMass\r
60   )\r
61 {\r
62   EFI_BLOCK_IO_MEDIA          *Media;\r
63   EFI_STATUS                  Status;\r
64   UINTN                       Index;\r
65 \r
66   Media = &UsbMass->BlockIoMedia;\r
67 \r
68   //\r
69   // Initialize the MediaPrsent/ReadOnly and others to the default.\r
70   // We are not forced to get it right at this time, check UEFI2.0\r
71   // spec for more information:\r
72   //\r
73   // MediaPresent: This field shows the media present status as\r
74   //               of the most recent ReadBlocks or WriteBlocks call.\r
75   //\r
76   // ReadOnly    : This field shows the read-only status as of the\r
77   //               recent WriteBlocks call.\r
78   //\r
79   // but remember to update MediaId/MediaPresent/ReadOnly status\r
80   // after ReadBlocks and WriteBlocks\r
81   //\r
82   Media->MediaPresent     = FALSE;\r
83   Media->LogicalPartition = FALSE;\r
84   Media->ReadOnly         = FALSE;\r
85   Media->WriteCaching     = FALSE;\r
86   Media->IoAlign          = 0;\r
87 \r
88   //\r
89   // Some device may spend several seconds before it is ready.\r
90   // Try several times before giving up. Wait 5s at most.\r
91   //\r
92   Status = EFI_SUCCESS;\r
93 \r
94   for (Index = 0; Index < USB_BOOT_WAIT_RETRY; Index++) {\r
95 \r
96     Status = UsbBootGetParams (UsbMass);\r
97     if ((Status != EFI_MEDIA_CHANGED)\r
98         && (Status != EFI_NOT_READY)\r
99         && (Status != EFI_TIMEOUT)) {\r
100       break;\r
101     }\r
102 \r
103     Status = UsbBootIsUnitReady (UsbMass);\r
104     if (EFI_ERROR (Status)) {\r
105       gBS->Stall (USB_BOOT_UNIT_READY_STALL * (Index + 1));\r
106     }\r
107 \r
108   }\r
109 \r
110   return Status;\r
111 }\r
112 \r
113 \r
114 /**\r
115   Reset the block device. ExtendedVerification is ignored for this.\r
116 \r
117   @param  This                   The BLOCK IO protocol\r
118   @param  ExtendedVerification   Whether to execute extended verfication.\r
119 \r
120   @retval EFI_SUCCESS            The device is successfully resetted.\r
121   @retval Others                 Failed to reset the device.\r
122 \r
123 **/\r
124 EFI_STATUS\r
125 UsbMassReset (\r
126   IN EFI_BLOCK_IO_PROTOCOL    *This,\r
127   IN BOOLEAN                  ExtendedVerification\r
128   )\r
129 {\r
130   USB_MASS_DEVICE *UsbMass;\r
131 \r
132   UsbMass = USB_MASS_DEVICE_FROM_BLOCKIO (This);\r
133   return UsbMass->Transport->Reset (UsbMass->Context, ExtendedVerification);\r
134 }\r
135 \r
136 \r
137 /**\r
138   Read some blocks of data from the block device.\r
139 \r
140   @param  This                   The Block IO protocol\r
141   @param  MediaId                The media's ID of the device for current request\r
142   @param  Lba                    The start block number\r
143   @param  BufferSize             The size of buffer to read data in\r
144   @param  Buffer                 The buffer to read data to\r
145 \r
146   @retval EFI_SUCCESS            The data is successfully read\r
147   @retval EFI_NO_MEDIA           Media isn't present\r
148   @retval EFI_MEDIA_CHANGED      The device media has been changed, that is,\r
149                                  MediaId changed\r
150   @retval EFI_INVALID_PARAMETER  Some parameters are invalid, such as Buffer is\r
151                                  NULL.\r
152   @retval EFI_BAD_BUFFER_SIZE    The buffer size isn't a multiple of media's block\r
153                                  size,  or overflow the last block number.\r
154 \r
155 **/\r
156 EFI_STATUS\r
157 UsbMassReadBlocks (\r
158   IN EFI_BLOCK_IO_PROTOCOL    *This,\r
159   IN UINT32                   MediaId,\r
160   IN EFI_LBA                  Lba,\r
161   IN UINTN                    BufferSize,\r
162   OUT VOID                    *Buffer\r
163   )\r
164 {\r
165   USB_MASS_DEVICE     *UsbMass;\r
166   EFI_BLOCK_IO_MEDIA  *Media;\r
167   EFI_STATUS          Status;\r
168   UINTN               TotalBlock;\r
169 \r
170   UsbMass = USB_MASS_DEVICE_FROM_BLOCKIO (This);\r
171   Media   = &UsbMass->BlockIoMedia;\r
172 \r
173   //\r
174   // First, validate the parameters\r
175   //\r
176   if ((Buffer == NULL) || (BufferSize == 0)) {\r
177     return EFI_INVALID_PARAMETER;\r
178   }\r
179 \r
180   //\r
181   // If it is a remoable media, such as CD-Rom or Usb-Floppy,\r
182   // if, need to detect the media before each rw, while Usb-Flash\r
183   // needn't. However, it's hard to identify Usb-Floppy between\r
184   // Usb-Flash by now, so detect media every time.\r
185   //\r
186   Status = UsbBootDetectMedia (UsbMass);\r
187   if (EFI_ERROR (Status)) {\r
188     DEBUG ((mUsbMscError, "UsbMassReadBlocks: UsbBootDetectMedia (%r)\n", Status));\r
189     return Status;\r
190   }\r
191 \r
192   //\r
193   // Make sure BlockSize and LBA is consistent with BufferSize\r
194   //\r
195   if ((BufferSize % Media->BlockSize) != 0) {\r
196     return EFI_BAD_BUFFER_SIZE;\r
197   }\r
198 \r
199   TotalBlock = BufferSize / Media->BlockSize;\r
200 \r
201   if (Lba + TotalBlock - 1 > Media->LastBlock) {\r
202     return EFI_BAD_BUFFER_SIZE;\r
203   }\r
204 \r
205   Status = UsbBootReadBlocks (UsbMass, (UINT32) Lba, TotalBlock, Buffer);\r
206   if (EFI_ERROR (Status)) {\r
207     DEBUG ((mUsbMscError, "UsbMassReadBlocks: UsbBootReadBlocks (%r) -> Reset\n", Status));\r
208     UsbMassReset (This, TRUE);\r
209   }\r
210 \r
211   return Status;\r
212 }\r
213 \r
214 \r
215 /**\r
216   Write some blocks of data to the block device.\r
217 \r
218   @param  This                   The Block IO protocol\r
219   @param  MediaId                The media's ID of the device for current request\r
220   @param  Lba                    The start block number\r
221   @param  BufferSize             The size of buffer to write data to\r
222   @param  Buffer                 The buffer to write data to\r
223 \r
224   @retval EFI_SUCCESS            The data is successfully written\r
225   @retval EFI_NO_MEDIA           Media isn't present\r
226   @retval EFI_MEDIA_CHANGED      The device media has been changed, that is,\r
227                                  MediaId changed\r
228   @retval EFI_INVALID_PARAMETER  Some parameters are invalid, such as Buffer is\r
229                                  NULL.\r
230   @retval EFI_BAD_BUFFER_SIZE    The buffer size isn't a multiple of media's block\r
231                                  size,\r
232 \r
233 **/\r
234 EFI_STATUS\r
235 UsbMassWriteBlocks (\r
236   IN EFI_BLOCK_IO_PROTOCOL    *This,\r
237   IN UINT32                   MediaId,\r
238   IN EFI_LBA                  Lba,\r
239   IN UINTN                    BufferSize,\r
240   IN VOID                     *Buffer\r
241   )\r
242 {\r
243   USB_MASS_DEVICE     *UsbMass;\r
244   EFI_BLOCK_IO_MEDIA  *Media;\r
245   EFI_STATUS          Status;\r
246   UINTN               TotalBlock;\r
247 \r
248   UsbMass = USB_MASS_DEVICE_FROM_BLOCKIO (This);\r
249   Media   = &UsbMass->BlockIoMedia;\r
250 \r
251   //\r
252   // First, validate the parameters\r
253   //\r
254   if ((Buffer == NULL) || (BufferSize == 0)) {\r
255     return EFI_INVALID_PARAMETER;\r
256   }\r
257 \r
258   //\r
259   // If it is a remoable media, such as CD-Rom or Usb-Floppy,\r
260   // if, need to detect the media before each rw, while Usb-Flash\r
261   // needn't. However, it's hard to identify Usb-Floppy between\r
262   // Usb-Flash by now, so detect media every time.\r
263   //\r
264   Status = UsbBootDetectMedia (UsbMass);\r
265   if (EFI_ERROR (Status)) {\r
266     DEBUG ((mUsbMscError, "UsbMassWriteBlocks: UsbBootDetectMedia (%r)\n", Status));\r
267     return Status;\r
268   }\r
269 \r
270   //\r
271   // Make sure BlockSize and LBA is consistent with BufferSize\r
272   //\r
273   if ((BufferSize % Media->BlockSize) != 0) {\r
274     return EFI_BAD_BUFFER_SIZE;\r
275   }\r
276 \r
277   TotalBlock = BufferSize / Media->BlockSize;\r
278 \r
279   if (Lba + TotalBlock - 1 > Media->LastBlock) {\r
280     return EFI_BAD_BUFFER_SIZE;\r
281   }\r
282 \r
283   //\r
284   // Try to write the data even the device is marked as ReadOnly,\r
285   // and clear the status should the write succeed.\r
286   //\r
287   Status = UsbBootWriteBlocks (UsbMass, (UINT32) Lba, TotalBlock, Buffer);\r
288   if (EFI_ERROR (Status)) {\r
289     DEBUG ((mUsbMscError, "UsbMassWriteBlocks: UsbBootWriteBlocks (%r) -> Reset\n", Status));\r
290     UsbMassReset (This, TRUE);\r
291   }\r
292 \r
293   return Status;\r
294 }\r
295 \r
296 \r
297 /**\r
298   Flush the cached writes to disks. USB mass storage device doesn't\r
299   support write cache, so return EFI_SUCCESS directly.\r
300 \r
301   @param  This                   The BLOCK IO protocol\r
302 \r
303   @retval EFI_SUCCESS            Always returns success\r
304 \r
305 **/\r
306 EFI_STATUS\r
307 UsbMassFlushBlocks (\r
308   IN EFI_BLOCK_IO_PROTOCOL  *This\r
309   )\r
310 {\r
311   return EFI_SUCCESS;\r
312 }\r
313 \r
314 \r
315 /**\r
316   Check whether the controller is a supported USB mass storage.\r
317 \r
318   @param  This                   The USB mass driver's driver binding.\r
319   @param  Controller             The device to test against.\r
320   @param  RemainingDevicePath    The remaining device path\r
321 \r
322   @retval EFI_SUCCESS            This device is a supported USB mass storage.\r
323   @retval EFI_UNSUPPORTED        The device isn't supported\r
324   @retval Others                 Some error happened.\r
325 \r
326 **/\r
327 EFI_STATUS\r
328 EFIAPI\r
329 USBMassDriverBindingSupported (\r
330   IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
331   IN EFI_HANDLE                   Controller,\r
332   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath\r
333   )\r
334 {\r
335   EFI_USB_IO_PROTOCOL           *UsbIo;\r
336   EFI_USB_INTERFACE_DESCRIPTOR  Interface;\r
337   USB_MASS_TRANSPORT            *Transport;\r
338   EFI_STATUS                    Status;\r
339   INTN                          Index;\r
340 \r
341   //\r
342   // Check whether the controlelr support USB_IO\r
343   //\r
344   Status = gBS->OpenProtocol (\r
345                   Controller,\r
346                   &gEfiUsbIoProtocolGuid,\r
347                   (VOID **) &UsbIo,\r
348                   This->DriverBindingHandle,\r
349                   Controller,\r
350                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
351                   );\r
352   if (EFI_ERROR (Status)) {\r
353     return Status;\r
354   }\r
355 \r
356   //\r
357   // Get the interface to check the USB class and find a transport\r
358   // protocol handler.\r
359   //\r
360   Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &Interface);\r
361   if (EFI_ERROR (Status)) {\r
362     goto ON_EXIT;\r
363   }\r
364 \r
365   Status = EFI_UNSUPPORTED;\r
366 \r
367   if (Interface.InterfaceClass != USB_MASS_STORE_CLASS) {\r
368     goto ON_EXIT;\r
369   }\r
370 \r
371   for (Index = 0; mUsbMassTransport[Index] != NULL; Index++) {\r
372     Transport = mUsbMassTransport[Index];\r
373     if (Interface.InterfaceProtocol == Transport->Protocol) {\r
374       Status = Transport->Init (UsbIo, Controller, NULL);\r
375       break;\r
376     }\r
377   }\r
378 \r
379   DEBUG ((mUsbMscInfo, "Found a USB mass store device %r\n", Status));\r
380 \r
381 ON_EXIT:\r
382   gBS->CloseProtocol (\r
383         Controller,\r
384         &gEfiUsbIoProtocolGuid,\r
385         This->DriverBindingHandle,\r
386         Controller\r
387         );\r
388 \r
389   return Status;\r
390 }\r
391 \r
392 \r
393 /**\r
394   Start the USB mass storage device on the controller. It will\r
395   install a BLOCK_IO protocol on the device if everything is OK.\r
396 \r
397   @param  This                   The USB mass storage driver binding.\r
398   @param  Controller             The USB mass storage device to start on\r
399   @param  RemainingDevicePath    The remaining device path.\r
400 \r
401   @retval EFI_SUCCESS            The driver has started on the device.\r
402   @retval EFI_OUT_OF_RESOURCES   Failed to allocate memory\r
403   @retval Others                 Failed to start the driver on the device.\r
404 \r
405 **/\r
406 EFI_STATUS\r
407 EFIAPI\r
408 USBMassDriverBindingStart (\r
409   IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
410   IN EFI_HANDLE                   Controller,\r
411   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath\r
412   )\r
413 {\r
414   EFI_USB_IO_PROTOCOL           *UsbIo;\r
415   EFI_USB_INTERFACE_DESCRIPTOR  Interface;\r
416   USB_MASS_DEVICE               *UsbMass;\r
417   USB_MASS_TRANSPORT            *Transport;\r
418   EFI_STATUS                    Status;\r
419   UINTN                         Index;\r
420 \r
421   Status = gBS->OpenProtocol (\r
422                   Controller,\r
423                   &gEfiUsbIoProtocolGuid,\r
424                   (VOID **) &UsbIo,\r
425                   This->DriverBindingHandle,\r
426                   Controller,\r
427                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
428                   );\r
429 \r
430   if (EFI_ERROR (Status)) {\r
431     return Status;\r
432   }\r
433 \r
434   UsbMass = AllocateZeroPool (sizeof (USB_MASS_DEVICE));\r
435   if (UsbMass == NULL) {\r
436     return EFI_OUT_OF_RESOURCES;\r
437   }\r
438 \r
439   //\r
440   // Initialize the transport protocols\r
441   //\r
442   Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &Interface);\r
443   if (EFI_ERROR (Status)) {\r
444     DEBUG ((mUsbMscError, "USBMassDriverBindingStart: UsbIo->UsbGetInterfaceDescriptor (%r)\n", Status));\r
445     goto ON_ERROR;\r
446   }\r
447 \r
448   Status = EFI_UNSUPPORTED;\r
449 \r
450   for (Index = 0; mUsbMassTransport[Index] != NULL; Index++) {\r
451     Transport = mUsbMassTransport[Index];\r
452 \r
453     if (Interface.InterfaceProtocol == Transport->Protocol) {\r
454       UsbMass->Transport = Transport;\r
455       Status             = Transport->Init (UsbIo, Controller, &UsbMass->Context);\r
456       break;\r
457     }\r
458   }\r
459 \r
460   if (EFI_ERROR (Status)) {\r
461     DEBUG ((mUsbMscError, "USBMassDriverBindingStart: Transport->Init (%r)\n", Status));\r
462     goto ON_ERROR;\r
463   }\r
464 \r
465   UsbMass->Signature            = USB_MASS_SIGNATURE;\r
466   UsbMass->Controller           = Controller;\r
467   UsbMass->UsbIo                = UsbIo;\r
468   UsbMass->BlockIo.Media        = &UsbMass->BlockIoMedia;\r
469   UsbMass->BlockIo.Reset        = UsbMassReset;\r
470   UsbMass->BlockIo.ReadBlocks   = UsbMassReadBlocks;\r
471   UsbMass->BlockIo.WriteBlocks  = UsbMassWriteBlocks;\r
472   UsbMass->BlockIo.FlushBlocks  = UsbMassFlushBlocks;\r
473   UsbMass->OpticalStorage       = FALSE;\r
474 \r
475   //\r
476   // Get the storage's parameters, such as last block number.\r
477   // then install the BLOCK_IO\r
478   //\r
479   Status = UsbMassInitMedia (UsbMass);\r
480   if (!EFI_ERROR (Status)) {\r
481     if ((UsbMass->Pdt != USB_PDT_DIRECT_ACCESS) &&\r
482          (UsbMass->Pdt != USB_PDT_CDROM) &&\r
483          (UsbMass->Pdt != USB_PDT_OPTICAL) &&\r
484          (UsbMass->Pdt != USB_PDT_SIMPLE_DIRECT)) {\r
485       DEBUG ((mUsbMscError, "USBMassDriverBindingStart: Found an unsupported peripheral type[%d]\n", UsbMass->Pdt));\r
486       goto ON_ERROR;\r
487     }\r
488   } else if (Status != EFI_NO_MEDIA){\r
489     DEBUG ((mUsbMscError, "USBMassDriverBindingStart: UsbMassInitMedia (%r)\n", Status));\r
490     goto ON_ERROR;\r
491   }\r
492 \r
493   Status = gBS->InstallProtocolInterface (\r
494                   &Controller,\r
495                   &gEfiBlockIoProtocolGuid,\r
496                   EFI_NATIVE_INTERFACE,\r
497                   &UsbMass->BlockIo\r
498                   );\r
499   if (EFI_ERROR (Status)) {\r
500     goto ON_ERROR;\r
501   }\r
502 \r
503   return EFI_SUCCESS;\r
504 \r
505 ON_ERROR:\r
506   gBS->FreePool (UsbMass);\r
507 \r
508   gBS->CloseProtocol (\r
509         Controller,\r
510         &gEfiUsbIoProtocolGuid,\r
511         This->DriverBindingHandle,\r
512         Controller\r
513         );\r
514 \r
515   return Status;\r
516 }\r
517 \r
518 \r
519 /**\r
520   Stop controlling the device.\r
521 \r
522   @param  This                   The USB mass storage driver binding\r
523   @param  Controller             The device controller controlled by the driver.\r
524   @param  NumberOfChildren       The number of children of this device\r
525   @param  ChildHandleBuffer      The buffer of children handle.\r
526 \r
527   @retval EFI_SUCCESS            The driver stopped from controlling the device.\r
528   @retval Others                 Failed to stop the driver\r
529 \r
530 **/\r
531 EFI_STATUS\r
532 EFIAPI\r
533 USBMassDriverBindingStop (\r
534   IN  EFI_DRIVER_BINDING_PROTOCOL *This,\r
535   IN  EFI_HANDLE                  Controller,\r
536   IN  UINTN                       NumberOfChildren,\r
537   IN  EFI_HANDLE                  *ChildHandleBuffer\r
538   )\r
539 {\r
540   EFI_STATUS            Status;\r
541   USB_MASS_DEVICE       *UsbMass;\r
542   EFI_BLOCK_IO_PROTOCOL *BlockIo;\r
543 \r
544   //\r
545   // First, get our context back from the BLOCK_IO\r
546   //\r
547   Status = gBS->OpenProtocol (\r
548                   Controller,\r
549                   &gEfiBlockIoProtocolGuid,\r
550                   (VOID **) &BlockIo,\r
551                   This->DriverBindingHandle,\r
552                   Controller,\r
553                   EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
554                   );\r
555 \r
556   if (EFI_ERROR (Status)) {\r
557     return Status;\r
558   }\r
559 \r
560   UsbMass = USB_MASS_DEVICE_FROM_BLOCKIO (BlockIo);\r
561 \r
562   //\r
563   // Uninstall Block I/O protocol from the device handle,\r
564   // then call the transport protocol to stop itself.\r
565   //\r
566   Status = gBS->UninstallProtocolInterface (\r
567                   Controller,\r
568                   &gEfiBlockIoProtocolGuid,\r
569                   &UsbMass->BlockIo\r
570                   );\r
571   if (EFI_ERROR (Status)) {\r
572     return Status;\r
573   }\r
574 \r
575   gBS->CloseProtocol (\r
576         Controller,\r
577         &gEfiUsbIoProtocolGuid,\r
578         This->DriverBindingHandle,\r
579         Controller\r
580         );\r
581 \r
582   UsbMass->Transport->Fini (UsbMass->Context);\r
583   gBS->FreePool (UsbMass);\r
584 \r
585   return EFI_SUCCESS;\r
586 }\r
587 \r
588 EFI_DRIVER_BINDING_PROTOCOL gUSBMassDriverBinding = {\r
589   USBMassDriverBindingSupported,\r
590   USBMassDriverBindingStart,\r
591   USBMassDriverBindingStop,\r
592   0x11,\r
593   NULL,\r
594   NULL\r
595 };\r
596 \r
597 EFI_STATUS\r
598 EFIAPI\r
599 USBMassStorageEntryPoint (\r
600   IN EFI_HANDLE               ImageHandle,\r
601   IN EFI_SYSTEM_TABLE         *SystemTable\r
602   )\r
603 /*++\r
604 \r
605 Routine Description:\r
606 \r
607   The entry point for the driver, which will install the driver binding and\r
608   component name protocol\r
609 \r
610 Arguments:\r
611 \r
612   ImageHandle - The image handle of this driver\r
613   SystemTable - The system table\r
614 \r
615 Returns:\r
616 \r
617   EFI_SUCCESS - the protocols are installed OK\r
618   Others      - Failed to install protocols.\r
619 \r
620 --*/\r
621 {\r
622   EFI_STATUS  Status;\r
623 \r
624   //\r
625   // Install driver binding protocol\r
626   //\r
627   Status = EfiLibInstallAllDriverProtocols (\r
628              ImageHandle,\r
629              SystemTable,\r
630              &gUSBMassDriverBinding,\r
631              ImageHandle,\r
632              &gUsbMassStorageComponentName,\r
633              NULL,\r
634              NULL\r
635              );\r
636 \r
637   return Status;\r
638 }\r