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