]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBot.c
Clean up DEC files:
[mirror_edk2.git] / MdeModulePkg / Bus / Usb / UsbMassStorageDxe / UsbMassBot.c
CommitLineData
e237e7ae 1/** @file\r
d80ed2a7 2 Implementation of the USB mass storage Bulk-Only Transport protocol,\r
3 according to USB Mass Storage Class Bulk-Only Transport, Revision 1.0.\r
cc5166ff 4\r
c6e797ae 5Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>\r
cd5ebaa0 6This program and the accompanying materials\r
e237e7ae 7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
cc5166ff 14**/\r
e237e7ae 15\r
3e03cb4d 16#include "UsbMassBoot.h"\r
cc5166ff 17#include "UsbMassBot.h"\r
e237e7ae 18\r
d80ed2a7 19//\r
20// Definition of USB BOT Transport Protocol\r
21//\r
22USB_MASS_TRANSPORT mUsbBotTransport = {\r
23 USB_MASS_STORE_BOT,\r
24 UsbBotInit,\r
25 UsbBotExecCommand,\r
26 UsbBotResetDevice,\r
27 UsbBotGetMaxLun,\r
28 UsbBotCleanUp\r
29};\r
e237e7ae 30\r
31/**\r
d80ed2a7 32 Initializes USB BOT protocol.\r
33\r
34 This function initializes the USB mass storage class BOT protocol.\r
e237e7ae 35 It will save its context which is a USB_BOT_PROTOCOL structure\r
36 in the Context if Context isn't NULL.\r
37\r
d80ed2a7 38 @param UsbIo The USB I/O Protocol instance\r
39 @param Context The buffer to save the context to\r
e237e7ae 40\r
d80ed2a7 41 @retval EFI_SUCCESS The device is successfully initialized.\r
e237e7ae 42 @retval EFI_UNSUPPORTED The transport protocol doesn't support the device.\r
d80ed2a7 43 @retval Other The USB BOT initialization fails.\r
e237e7ae 44\r
45**/\r
e237e7ae 46EFI_STATUS\r
47UsbBotInit (\r
d80ed2a7 48 IN EFI_USB_IO_PROTOCOL *UsbIo,\r
e237e7ae 49 OUT VOID **Context OPTIONAL\r
50 )\r
51{\r
52 USB_BOT_PROTOCOL *UsbBot;\r
53 EFI_USB_INTERFACE_DESCRIPTOR *Interface;\r
54 EFI_USB_ENDPOINT_DESCRIPTOR EndPoint;\r
55 EFI_STATUS Status;\r
56 UINT8 Index;\r
57\r
58 //\r
d80ed2a7 59 // Allocate the BOT context for USB_BOT_PROTOCOL and two endpoint descriptors.\r
e237e7ae 60 //\r
3e03cb4d 61 UsbBot = AllocateZeroPool (sizeof (USB_BOT_PROTOCOL) + 2 * sizeof (EFI_USB_ENDPOINT_DESCRIPTOR));\r
d80ed2a7 62 ASSERT (UsbBot != NULL);\r
e237e7ae 63\r
64 UsbBot->UsbIo = UsbIo;\r
65\r
66 //\r
67 // Get the interface descriptor and validate that it\r
d80ed2a7 68 // is a USB Mass Storage BOT interface.\r
e237e7ae 69 //\r
70 Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &UsbBot->Interface);\r
71\r
72 if (EFI_ERROR (Status)) {\r
e237e7ae 73 goto ON_ERROR;\r
74 }\r
75\r
76 Interface = &UsbBot->Interface;\r
77\r
78 if (Interface->InterfaceProtocol != USB_MASS_STORE_BOT) {\r
79 Status = EFI_UNSUPPORTED;\r
80 goto ON_ERROR;\r
81 }\r
82\r
83 //\r
84 // Locate and save the first bulk-in and bulk-out endpoint\r
85 //\r
86 for (Index = 0; Index < Interface->NumEndpoints; Index++) {\r
87 Status = UsbIo->UsbGetEndpointDescriptor (UsbIo, Index, &EndPoint);\r
88\r
89 if (EFI_ERROR (Status) || !USB_IS_BULK_ENDPOINT (EndPoint.Attributes)) {\r
90 continue;\r
91 }\r
92\r
93 if (USB_IS_IN_ENDPOINT (EndPoint.EndpointAddress) &&\r
94 (UsbBot->BulkInEndpoint == NULL)) {\r
95\r
96 UsbBot->BulkInEndpoint = (EFI_USB_ENDPOINT_DESCRIPTOR *) (UsbBot + 1);\r
84b5c78e 97 CopyMem(UsbBot->BulkInEndpoint, &EndPoint, sizeof (EndPoint));\r
e237e7ae 98 }\r
99\r
100 if (USB_IS_OUT_ENDPOINT (EndPoint.EndpointAddress) &&\r
101 (UsbBot->BulkOutEndpoint == NULL)) {\r
102\r
103 UsbBot->BulkOutEndpoint = (EFI_USB_ENDPOINT_DESCRIPTOR *) (UsbBot + 1) + 1;\r
3e03cb4d 104 CopyMem (UsbBot->BulkOutEndpoint, &EndPoint, sizeof(EndPoint));\r
e237e7ae 105 }\r
106 }\r
107\r
d80ed2a7 108 //\r
109 // If bulk-in or bulk-out endpoint is not found, report error.\r
110 //\r
e237e7ae 111 if ((UsbBot->BulkInEndpoint == NULL) || (UsbBot->BulkOutEndpoint == NULL)) {\r
e237e7ae 112 Status = EFI_UNSUPPORTED;\r
113 goto ON_ERROR;\r
114 }\r
115\r
116 //\r
d80ed2a7 117 // The USB BOT protocol uses CBWTag to match the CBW and CSW.\r
e237e7ae 118 //\r
119 UsbBot->CbwTag = 0x01;\r
120\r
121 if (Context != NULL) {\r
122 *Context = UsbBot;\r
123 } else {\r
c92e277d 124 FreePool (UsbBot);\r
e237e7ae 125 }\r
126\r
127 return EFI_SUCCESS;\r
128\r
129ON_ERROR:\r
c92e277d 130 FreePool (UsbBot);\r
e237e7ae 131 return Status;\r
132}\r
133\r
e237e7ae 134/**\r
cc5166ff 135 Send the command to the device using Bulk-Out endpoint.\r
e237e7ae 136\r
d80ed2a7 137 This function sends the command to the device using Bulk-Out endpoint.\r
138 BOT transfer is composed of three phases: Command, Data, and Status.\r
139 This is the Command phase.\r
140\r
e237e7ae 141 @param UsbBot The USB BOT device\r
142 @param Cmd The command to transfer to device\r
d80ed2a7 143 @param CmdLen The length of the command\r
e237e7ae 144 @param DataDir The direction of the data\r
145 @param TransLen The expected length of the data\r
c7e39923 146 @param Lun The number of logic unit\r
e237e7ae 147\r
e237e7ae 148 @retval EFI_SUCCESS The command is sent to the device.\r
d80ed2a7 149 @retval EFI_NOT_READY The device return NAK to the transfer\r
e237e7ae 150 @retval Others Failed to send the command to device\r
151\r
152**/\r
e237e7ae 153EFI_STATUS\r
154UsbBotSendCommand (\r
155 IN USB_BOT_PROTOCOL *UsbBot,\r
156 IN UINT8 *Cmd,\r
157 IN UINT8 CmdLen,\r
158 IN EFI_USB_DATA_DIRECTION DataDir,\r
c7e39923 159 IN UINT32 TransLen,\r
160 IN UINT8 Lun\r
e237e7ae 161 )\r
162{\r
163 USB_BOT_CBW Cbw;\r
164 EFI_STATUS Status;\r
165 UINT32 Result;\r
166 UINTN DataLen;\r
167 UINTN Timeout;\r
168\r
169 ASSERT ((CmdLen > 0) && (CmdLen <= USB_BOT_MAX_CMDLEN));\r
170\r
171 //\r
d80ed2a7 172 // Fill in the Command Block Wrapper.\r
e237e7ae 173 //\r
174 Cbw.Signature = USB_BOT_CBW_SIGNATURE;\r
175 Cbw.Tag = UsbBot->CbwTag;\r
176 Cbw.DataLen = TransLen;\r
d80ed2a7 177 Cbw.Flag = (UINT8) ((DataDir == EfiUsbDataIn) ? BIT7 : 0);\r
c7e39923 178 Cbw.Lun = Lun;\r
e237e7ae 179 Cbw.CmdLen = CmdLen;\r
180\r
181 ZeroMem (Cbw.CmdBlock, USB_BOT_MAX_CMDLEN);\r
182 CopyMem (Cbw.CmdBlock, Cmd, CmdLen);\r
183\r
d80ed2a7 184 Result = 0;\r
185 DataLen = sizeof (USB_BOT_CBW);\r
186 Timeout = USB_BOT_SEND_CBW_TIMEOUT / USB_MASS_1_MILLISECOND;\r
e237e7ae 187\r
188 //\r
d80ed2a7 189 // Use USB I/O Protocol to send the Command Block Wrapper to the device.\r
e237e7ae 190 //\r
191 Status = UsbBot->UsbIo->UsbBulkTransfer (\r
192 UsbBot->UsbIo,\r
193 UsbBot->BulkOutEndpoint->EndpointAddress,\r
194 &Cbw,\r
195 &DataLen,\r
196 Timeout,\r
197 &Result\r
198 );\r
e237e7ae 199 if (EFI_ERROR (Status)) {\r
200 if (USB_IS_ERROR (Result, EFI_USB_ERR_STALL) && DataDir == EfiUsbDataOut) {\r
d80ed2a7 201 //\r
202 // Respond to Bulk-Out endpoint stall with a Reset Recovery,\r
203 // according to section 5.3.1 of USB Mass Storage Class Bulk-Only Transport Spec, v1.0.\r
204 //\r
e237e7ae 205 UsbBotResetDevice (UsbBot, FALSE);\r
206 } else if (USB_IS_ERROR (Result, EFI_USB_ERR_NAK)) {\r
207 Status = EFI_NOT_READY;\r
208 }\r
209 }\r
210\r
211 return Status;\r
212}\r
213\r
214\r
215/**\r
d80ed2a7 216 Transfer the data between the device and host.\r
217\r
218 This function transfers the data between the device and host.\r
219 BOT transfer is composed of three phases: Command, Data, and Status.\r
220 This is the Data phase.\r
e237e7ae 221\r
222 @param UsbBot The USB BOT device\r
223 @param DataDir The direction of the data\r
224 @param Data The buffer to hold data\r
225 @param TransLen The expected length of the data\r
226 @param Timeout The time to wait the command to complete\r
227\r
228 @retval EFI_SUCCESS The data is transferred\r
d80ed2a7 229 @retval EFI_SUCCESS No data to transfer\r
230 @retval EFI_NOT_READY The device return NAK to the transfer\r
e237e7ae 231 @retval Others Failed to transfer data\r
232\r
233**/\r
e237e7ae 234EFI_STATUS\r
235UsbBotDataTransfer (\r
236 IN USB_BOT_PROTOCOL *UsbBot,\r
237 IN EFI_USB_DATA_DIRECTION DataDir,\r
238 IN OUT UINT8 *Data,\r
239 IN OUT UINTN *TransLen,\r
240 IN UINT32 Timeout\r
241 )\r
242{\r
243 EFI_USB_ENDPOINT_DESCRIPTOR *Endpoint;\r
244 EFI_STATUS Status;\r
245 UINT32 Result;\r
246\r
247 //\r
d80ed2a7 248 // If no data to transfer, just return EFI_SUCCESS.\r
e237e7ae 249 //\r
250 if ((DataDir == EfiUsbNoData) || (*TransLen == 0)) {\r
251 return EFI_SUCCESS;\r
252 }\r
253\r
254 //\r
255 // Select the endpoint then issue the transfer\r
256 //\r
257 if (DataDir == EfiUsbDataIn) {\r
258 Endpoint = UsbBot->BulkInEndpoint;\r
259 } else {\r
260 Endpoint = UsbBot->BulkOutEndpoint;\r
261 }\r
262\r
263 Result = 0;\r
41e8ff27 264 Timeout = Timeout / USB_MASS_1_MILLISECOND;\r
e237e7ae 265\r
266 Status = UsbBot->UsbIo->UsbBulkTransfer (\r
267 UsbBot->UsbIo,\r
268 Endpoint->EndpointAddress,\r
269 Data,\r
270 TransLen,\r
271 Timeout,\r
272 &Result\r
273 );\r
274 if (EFI_ERROR (Status)) {\r
e237e7ae 275 if (USB_IS_ERROR (Result, EFI_USB_ERR_STALL)) {\r
efe9186f 276 DEBUG ((EFI_D_INFO, "UsbBotDataTransfer: (%r)\n", Status)); \r
277 DEBUG ((EFI_D_INFO, "UsbBotDataTransfer: DataIn Stall\n"));\r
e237e7ae 278 UsbClearEndpointStall (UsbBot->UsbIo, Endpoint->EndpointAddress);\r
279 } else if (USB_IS_ERROR (Result, EFI_USB_ERR_NAK)) {\r
280 Status = EFI_NOT_READY;\r
efe9186f 281 } else {\r
282 DEBUG ((EFI_D_ERROR, "UsbBotDataTransfer: (%r)\n", Status));\r
283 }\r
284 if(Status == EFI_TIMEOUT){\r
285 UsbBotResetDevice(UsbBot, FALSE);\r
e237e7ae 286 }\r
287 }\r
288\r
289 return Status;\r
290}\r
291\r
292\r
293/**\r
d80ed2a7 294 Get the command execution status from device.\r
295\r
296 This function gets the command execution status from device.\r
297 BOT transfer is composed of three phases: Command, Data, and Status.\r
298 This is the Status phase.\r
e237e7ae 299\r
d80ed2a7 300 This function returns the transfer status of the BOT's CSW status,\r
301 and returns the high level command execution result in Result. So\r
302 even if EFI_SUCCESS is returned, the command may still have failed.\r
e237e7ae 303\r
d80ed2a7 304 @param UsbBot The USB BOT device.\r
305 @param TransLen The expected length of the data.\r
306 @param CmdStatus The result of the command execution.\r
307\r
308 @retval EFI_SUCCESS Command execute result is retrieved and in the Result.\r
309 @retval Other Error occurred when trying to get status.\r
e237e7ae 310\r
311**/\r
e237e7ae 312EFI_STATUS\r
313UsbBotGetStatus (\r
314 IN USB_BOT_PROTOCOL *UsbBot,\r
315 IN UINT32 TransLen,\r
316 OUT UINT8 *CmdStatus\r
317 )\r
318{\r
319 USB_BOT_CSW Csw;\r
320 UINTN Len;\r
321 UINT8 Endpoint;\r
322 EFI_STATUS Status;\r
323 UINT32 Result;\r
324 EFI_USB_IO_PROTOCOL *UsbIo;\r
325 UINT32 Index;\r
326 UINTN Timeout;\r
1c619535 327\r
e237e7ae 328 *CmdStatus = USB_BOT_COMMAND_ERROR;\r
329 Status = EFI_DEVICE_ERROR;\r
330 Endpoint = UsbBot->BulkInEndpoint->EndpointAddress;\r
331 UsbIo = UsbBot->UsbIo;\r
41e8ff27 332 Timeout = USB_BOT_RECV_CSW_TIMEOUT / USB_MASS_1_MILLISECOND;\r
e237e7ae 333\r
41e8ff27 334 for (Index = 0; Index < USB_BOT_RECV_CSW_RETRY; Index++) {\r
e237e7ae 335 //\r
d80ed2a7 336 // Attemp to the read Command Status Wrapper from bulk in endpoint\r
e237e7ae 337 //\r
338 ZeroMem (&Csw, sizeof (USB_BOT_CSW));\r
339 Result = 0;\r
340 Len = sizeof (USB_BOT_CSW);\r
341 Status = UsbIo->UsbBulkTransfer (\r
342 UsbIo,\r
343 Endpoint,\r
344 &Csw,\r
345 &Len,\r
346 Timeout,\r
347 &Result\r
348 );\r
349 if (EFI_ERROR(Status)) {\r
e237e7ae 350 if (USB_IS_ERROR (Result, EFI_USB_ERR_STALL)) {\r
e237e7ae 351 UsbClearEndpointStall (UsbIo, Endpoint);\r
352 }\r
353 continue;\r
354 }\r
355\r
356 if (Csw.Signature != USB_BOT_CSW_SIGNATURE) {\r
357 //\r
d80ed2a7 358 // CSW is invalid, so perform reset recovery\r
e237e7ae 359 //\r
e237e7ae 360 Status = UsbBotResetDevice (UsbBot, FALSE);\r
361 } else if (Csw.CmdStatus == USB_BOT_COMMAND_ERROR) {\r
362 //\r
d80ed2a7 363 // Respond phase error also needs reset recovery\r
e237e7ae 364 //\r
e237e7ae 365 Status = UsbBotResetDevice (UsbBot, FALSE);\r
366 } else {\r
e237e7ae 367 *CmdStatus = Csw.CmdStatus;\r
368 break;\r
369 }\r
370 }\r
371 //\r
d80ed2a7 372 //The tag is increased even if there is an error.\r
e237e7ae 373 //\r
374 UsbBot->CbwTag++;\r
375\r
376 return Status;\r
377}\r
378\r
379\r
380/**\r
d80ed2a7 381 Call the USB Mass Storage Class BOT protocol to issue\r
cc5166ff 382 the command/data/status circle to execute the commands.\r
e237e7ae 383\r
384 @param Context The context of the BOT protocol, that is,\r
385 USB_BOT_PROTOCOL\r
386 @param Cmd The high level command\r
387 @param CmdLen The command length\r
388 @param DataDir The direction of the data transfer\r
389 @param Data The buffer to hold data\r
390 @param DataLen The length of the data\r
c7e39923 391 @param Lun The number of logic unit\r
e237e7ae 392 @param Timeout The time to wait command\r
393 @param CmdStatus The result of high level command execution\r
394\r
d80ed2a7 395 @retval EFI_SUCCESS The command is executed successfully.\r
cc5166ff 396 @retval Other Failed to excute command\r
e237e7ae 397\r
398**/\r
e237e7ae 399EFI_STATUS\r
400UsbBotExecCommand (\r
401 IN VOID *Context,\r
402 IN VOID *Cmd,\r
403 IN UINT8 CmdLen,\r
404 IN EFI_USB_DATA_DIRECTION DataDir,\r
405 IN VOID *Data,\r
406 IN UINT32 DataLen,\r
c7e39923 407 IN UINT8 Lun,\r
e237e7ae 408 IN UINT32 Timeout,\r
409 OUT UINT32 *CmdStatus\r
410 )\r
411{\r
412 USB_BOT_PROTOCOL *UsbBot;\r
413 EFI_STATUS Status;\r
414 UINTN TransLen;\r
415 UINT8 Result;\r
416\r
417 *CmdStatus = USB_MASS_CMD_FAIL;\r
418 UsbBot = (USB_BOT_PROTOCOL *) Context;\r
419\r
420 //\r
421 // Send the command to the device. Return immediately if device\r
422 // rejects the command.\r
423 //\r
c7e39923 424 Status = UsbBotSendCommand (UsbBot, Cmd, CmdLen, DataDir, DataLen, Lun);\r
e237e7ae 425 if (EFI_ERROR (Status)) {\r
1c619535 426 DEBUG ((EFI_D_ERROR, "UsbBotExecCommand: UsbBotSendCommand (%r)\n", Status));\r
e237e7ae 427 return Status;\r
428 }\r
429\r
430 //\r
431 // Transfer the data. Don't return immediately even data transfer\r
432 // failed. The host should attempt to receive the CSW no matter\r
d80ed2a7 433 // whether it succeeds or fails.\r
e237e7ae 434 //\r
435 TransLen = (UINTN) DataLen;\r
436 UsbBotDataTransfer (UsbBot, DataDir, Data, &TransLen, Timeout);\r
437\r
438 //\r
439 // Get the status, if that succeeds, interpret the result\r
440 //\r
441 Status = UsbBotGetStatus (UsbBot, DataLen, &Result);\r
442 if (EFI_ERROR (Status)) {\r
1c619535 443 DEBUG ((EFI_D_ERROR, "UsbBotExecCommand: UsbBotGetStatus (%r)\n", Status));\r
e237e7ae 444 return Status;\r
445 }\r
446\r
447 if (Result == 0) {\r
448 *CmdStatus = USB_MASS_CMD_SUCCESS;\r
449 }\r
450\r
451 return EFI_SUCCESS;\r
452}\r
453\r
454\r
455/**\r
d80ed2a7 456 Reset the USB mass storage device by BOT protocol.\r
e237e7ae 457\r
458 @param Context The context of the BOT protocol, that is,\r
cc5166ff 459 USB_BOT_PROTOCOL.\r
d80ed2a7 460 @param ExtendedVerification If FALSE, just issue Bulk-Only Mass Storage Reset request.\r
461 If TRUE, additionally reset parent hub port.\r
e237e7ae 462\r
cc5166ff 463 @retval EFI_SUCCESS The device is reset.\r
464 @retval Others Failed to reset the device..\r
e237e7ae 465\r
466**/\r
e237e7ae 467EFI_STATUS\r
468UsbBotResetDevice (\r
469 IN VOID *Context,\r
d80ed2a7 470 IN BOOLEAN ExtendedVerification\r
e237e7ae 471 )\r
472{\r
473 USB_BOT_PROTOCOL *UsbBot;\r
474 EFI_USB_DEVICE_REQUEST Request;\r
475 EFI_STATUS Status;\r
476 UINT32 Result;\r
477 UINT32 Timeout;\r
478\r
479 UsbBot = (USB_BOT_PROTOCOL *) Context;\r
480\r
481 if (ExtendedVerification) {\r
482 //\r
483 // If we need to do strictly reset, reset its parent hub port\r
484 //\r
485 Status = UsbBot->UsbIo->UsbPortReset (UsbBot->UsbIo);\r
486 if (EFI_ERROR (Status)) {\r
c6e797ae 487 return EFI_DEVICE_ERROR;\r
e237e7ae 488 }\r
489 }\r
490\r
491 //\r
d80ed2a7 492 // Issue a class specific Bulk-Only Mass Storage Reset request,\r
493 // according to section 3.1 of USB Mass Storage Class Bulk-Only Transport Spec, v1.0.\r
e237e7ae 494 //\r
d80ed2a7 495 Request.RequestType = 0x21;\r
e237e7ae 496 Request.Request = USB_BOT_RESET_REQUEST;\r
497 Request.Value = 0;\r
498 Request.Index = UsbBot->Interface.InterfaceNumber;\r
499 Request.Length = 0;\r
41e8ff27 500 Timeout = USB_BOT_RESET_DEVICE_TIMEOUT / USB_MASS_1_MILLISECOND;\r
e237e7ae 501\r
502 Status = UsbBot->UsbIo->UsbControlTransfer (\r
503 UsbBot->UsbIo,\r
504 &Request,\r
505 EfiUsbNoData,\r
506 Timeout,\r
507 NULL,\r
508 0,\r
509 &Result\r
510 );\r
511\r
512 if (EFI_ERROR (Status)) {\r
c6e797ae 513 return EFI_DEVICE_ERROR;\r
e237e7ae 514 }\r
515\r
516 //\r
517 // The device shall NAK the host's request until the reset is\r
518 // complete. We can use this to sync the device and host. For\r
d80ed2a7 519 // now just stall 100ms to wait for the device.\r
e237e7ae 520 //\r
41e8ff27 521 gBS->Stall (USB_BOT_RESET_DEVICE_STALL);\r
e237e7ae 522\r
523 //\r
524 // Clear the Bulk-In and Bulk-Out stall condition.\r
525 //\r
526 UsbClearEndpointStall (UsbBot->UsbIo, UsbBot->BulkInEndpoint->EndpointAddress);\r
527 UsbClearEndpointStall (UsbBot->UsbIo, UsbBot->BulkOutEndpoint->EndpointAddress);\r
d80ed2a7 528\r
e237e7ae 529 return Status;\r
530}\r
531\r
c7e39923 532\r
cc5166ff 533/**\r
d80ed2a7 534 Get the max LUN (Logical Unit Number) of USB mass storage device.\r
c7e39923 535\r
cc5166ff 536 @param Context The context of the BOT protocol, that is, USB_BOT_PROTOCOL\r
d80ed2a7 537 @param MaxLun Return pointer to the max number of LUN. (e.g. MaxLun=1 means LUN0 and\r
538 LUN1 in all.)\r
c7e39923 539\r
d80ed2a7 540 @retval EFI_SUCCESS Max LUN is got successfully.\r
541 @retval Others Fail to execute this request.\r
c7e39923 542\r
cc5166ff 543**/\r
c7e39923 544EFI_STATUS\r
545UsbBotGetMaxLun (\r
546 IN VOID *Context,\r
d80ed2a7 547 OUT UINT8 *MaxLun\r
c7e39923 548 )\r
c7e39923 549{\r
550 USB_BOT_PROTOCOL *UsbBot;\r
551 EFI_USB_DEVICE_REQUEST Request;\r
552 EFI_STATUS Status;\r
553 UINT32 Result;\r
554 UINT32 Timeout;\r
555\r
556 ASSERT (Context);\r
557 \r
558 UsbBot = (USB_BOT_PROTOCOL *) Context;\r
559\r
560 //\r
561 // Issue a class specific Bulk-Only Mass Storage get max lun reqest.\r
d80ed2a7 562 // according to section 3.2 of USB Mass Storage Class Bulk-Only Transport Spec, v1.0.\r
c7e39923 563 //\r
d80ed2a7 564 Request.RequestType = 0xA1;\r
c7e39923 565 Request.Request = USB_BOT_GETLUN_REQUEST;\r
566 Request.Value = 0;\r
567 Request.Index = UsbBot->Interface.InterfaceNumber;\r
568 Request.Length = 1;\r
569 Timeout = USB_BOT_RESET_DEVICE_TIMEOUT / USB_MASS_1_MILLISECOND;\r
570\r
571 Status = UsbBot->UsbIo->UsbControlTransfer (\r
572 UsbBot->UsbIo,\r
573 &Request,\r
574 EfiUsbDataIn,\r
575 Timeout,\r
d80ed2a7 576 (VOID *) MaxLun,\r
c7e39923 577 1,\r
578 &Result\r
579 );\r
580\r
c7e39923 581 return Status;\r
582}\r
e237e7ae 583\r
584/**\r
cc5166ff 585 Clean up the resource used by this BOT protocol.\r
e237e7ae 586\r
d80ed2a7 587 @param Context The context of the BOT protocol, that is, USB_BOT_PROTOCOL.\r
e237e7ae 588\r
d80ed2a7 589 @retval EFI_SUCCESS The resource is cleaned up.\r
e237e7ae 590\r
591**/\r
e237e7ae 592EFI_STATUS\r
d80ed2a7 593UsbBotCleanUp (\r
e237e7ae 594 IN VOID *Context\r
595 )\r
596{\r
c92e277d 597 FreePool (Context);\r
e237e7ae 598 return EFI_SUCCESS;\r
599}\r
600\r