+/**\r
+ Starts the USB mass storage device with this driver.\r
+\r
+ This function consumes USB I/O Portocol, intializes USB mass storage device,\r
+ installs Block I/O Protocol, and submits Asynchronous Interrupt\r
+ Transfer to manage the USB mass storage device.\r
+\r
+ @param This The USB mass storage driver binding protocol.\r
+ @param Controller The USB mass storage device to start on\r
+ @param RemainingDevicePath The remaining device path.\r
+\r
+ @retval EFI_SUCCESS This driver supports this device.\r
+ @retval EFI_UNSUPPORTED This driver does not support this device.\r
+ @retval EFI_DEVICE_ERROR This driver cannot be started due to device Error.\r
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.\r
+ @retval EFI_ALREADY_STARTED This driver has been started.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+USBMassDriverBindingStart (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ )\r
+{\r
+ USB_MASS_TRANSPORT *Transport;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
+ VOID *Context;\r
+ UINT8 MaxLun;\r
+ EFI_STATUS Status;\r
+ EFI_USB_IO_PROTOCOL *UsbIo; \r
+ EFI_TPL OldTpl;\r
+\r
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+\r
+ Transport = NULL;\r
+ Context = NULL;\r
+ MaxLun = 0;\r
+\r
+ Status = UsbMassInitTransport (This, Controller, &Transport, &Context, &MaxLun);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "USBMassDriverBindingStart: UsbMassInitTransport (%r)\n", Status));\r
+ goto Exit;\r
+ }\r
+ if (MaxLun == 0) {\r
+ //\r
+ // Initialize data for device that does not support multiple LUNSs.\r
+ //\r
+ Status = UsbMassInitNonLun (This, Controller, Transport, Context);\r
+ if (EFI_ERROR (Status)) { \r
+ DEBUG ((EFI_D_ERROR, "USBMassDriverBindingStart: UsbMassInitNonLun (%r)\n", Status));\r
+ }\r
+ } else {\r
+ //\r
+ // Open device path to prepare for appending Device Logic Unit node.\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ (VOID **) &DevicePath,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ \r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "USBMassDriverBindingStart: OpenDevicePathProtocol By Driver (%r)\n", Status));\r
+ goto Exit;\r
+ }\r
+\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiUsbIoProtocolGuid,\r
+ (VOID **) &UsbIo,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ \r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "USBMassDriverBindingStart: OpenUsbIoProtocol By Driver (%r)\n", Status));\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ goto Exit;\r
+ }\r
+\r
+ //\r
+ // Initialize data for device that supports multiple LUNSs.\r
+ // EFI_SUCCESS is returned if at least 1 LUN is initialized successfully.\r
+ //\r
+ Status = UsbMassInitMultiLun (This, Controller, Transport, Context, DevicePath, MaxLun);\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiUsbIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ DEBUG ((EFI_D_ERROR, "USBMassDriverBindingStart: UsbMassInitMultiLun (%r) with Maxlun=%d\n", Status, MaxLun));\r
+ }\r
+ }\r
+Exit:\r
+ gBS->RestoreTPL (OldTpl);\r
+ return Status;\r
+}\r
+\r