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