]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/UefiScsiLib/UefiScsiLib.c
Correct the calculating time out for BDS
[mirror_edk2.git] / MdePkg / Library / UefiScsiLib / UefiScsiLib.c
CommitLineData
bf231ea6
A
1/** @file\r
2 UEFI SCSI Library implementation\r
3\r
4 Copyright (c) 2006 - 2007, Intel Corporation.<BR>\r
5 All rights reserved. This program and the accompanying materials \r
6 are licensed and made available under the terms and conditions of the BSD License \r
7 which accompanies this distribution. The full text of the license may be found at \r
8 http://opensource.org/licenses/bsd-license.php \r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
12\r
13**/\r
a02e796b 14\r
bf231ea6
A
15\r
16#include <PiDxe.h>\r
a02e796b 17#include <Library/ScsiLib.h>\r
18#include <Library/BaseMemoryLib.h>\r
19\r
a3589760 20#include <IndustryStandard/Scsi.h>\r
a02e796b 21\r
bf231ea6 22\r
a3589760 23/**\r
bf231ea6 24 Function test the ready status of the SCSI unit.\r
a3589760 25\r
26 @param[in] ScsiIo A pointer to SCSI IO protocol.\r
27 @param[in] Timeout The length of timeout period.\r
8069d49e
LG
28 @param[in out] SenseData A pointer to the sense data that \r
29 was generated by the execution of the SCSI Request Packet.\r
30 @param[in out] SenseDataLength On input, the length in bytes of the SenseData buffer. On\r
31 output, the number of bytes written to the SenseData buffer.\r
a3589760 32 @param[out] HostAdapterStatus The status of Host Adapter.\r
33 @param[out] TargetStatus The status of the target.\r
34\r
bf231ea6
A
35 @retval EFI_SUCCESS The status of the unit is tested successfully.\r
36 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, \r
37 but the entire DataBuffer could not be transferred.\r
38 The actual number of bytes transferred is returned\r
39 in InTransferLength.\r
40 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because \r
41 there are too many SCSI Command Packets already \r
42 queued.\r
43 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send \r
44 the SCSI Request Packet.\r
8069d49e 45 @retval EFI_INVALID_PARAMETER The contents of CommandPacket are invalid, or ScsiIo is NULL. \r
bf231ea6
A
46 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet\r
47 is not supported by the SCSI initiator(i.e., SCSI \r
48 Host Controller).\r
49 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI \r
50 Request Packet to execute.\r
a3589760 51\r
bf231ea6 52**/\r
a02e796b 53EFI_STATUS\r
d35be2a4 54ScsiTestUnitReadyCommand (\r
a02e796b 55 IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
56 IN UINT64 Timeout,\r
8069d49e
LG
57 IN OUT VOID *SenseData,\r
58 IN OUT UINT8 *SenseDataLength,\r
a02e796b 59 OUT UINT8 *HostAdapterStatus,\r
60 OUT UINT8 *TargetStatus\r
61 )\r
a02e796b 62{\r
63 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;\r
64 UINT64 Lun;\r
65 UINT8 *Target;\r
66 UINT8 TargetArray[EFI_SCSI_TARGET_MAX_BYTES];\r
67 EFI_STATUS Status;\r
68 UINT8 Cdb[6];\r
69\r
8069d49e
LG
70 ASSERT (SenseDataLength != NULL);\r
71 ASSERT (HostAdapterStatus != NULL);\r
72 ASSERT (TargetStatus != NULL);\r
73 \r
74 if (ScsiIo == NULL) {\r
75 return EFI_INVALID_PARAMETER;\r
76 }\r
a02e796b 77\r
78 ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));\r
79 ZeroMem (Cdb, 6);\r
80\r
81 CommandPacket.Timeout = Timeout;\r
82 CommandPacket.InDataBuffer = NULL;\r
83 CommandPacket.InTransferLength= 0;\r
84 CommandPacket.OutDataBuffer = NULL;\r
85 CommandPacket.OutTransferLength= 0;\r
86 CommandPacket.SenseData = SenseData;\r
87 CommandPacket.Cdb = Cdb;\r
88 //\r
89 // Fill Cdb for Test Unit Ready Command\r
90 //\r
91 Target = &TargetArray[0];\r
92 ScsiIo->GetDeviceLocation (ScsiIo, &Target, &Lun);\r
93\r
94 Cdb[0] = EFI_SCSI_OP_TEST_UNIT_READY;\r
95 Cdb[1] = (UINT8) (Lun & 0xe0);\r
96 CommandPacket.CdbLength = (UINT8) 6;\r
97 CommandPacket.SenseDataLength = *SenseDataLength;\r
98\r
99 Status = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);\r
100\r
101 *HostAdapterStatus = CommandPacket.HostAdapterStatus;\r
102 *TargetStatus = CommandPacket.TargetStatus;\r
103 *SenseDataLength = CommandPacket.SenseDataLength;\r
104\r
105 return Status;\r
106}\r
107\r
bf231ea6 108\r
a3589760 109/**\r
bf231ea6 110 Function to submit SCSI inquiry command.\r
a3589760 111\r
112 @param[in] ScsiIo SCSI IO Protocol to use\r
113 @param[in] Timeout The length of timeout period.\r
114 @param[out] SenseData A pointer to output sense data.\r
8069d49e
LG
115 @param[in out] SenseDataLength On input, the length in bytes of the SenseData buffer. On\r
116 output, the number of bytes written to the SenseData buffer.\r
a3589760 117 @param[out] HostAdapterStatus The status of Host Adapter.\r
118 @param[out] TargetStatus The status of the target.\r
8069d49e 119 @param[in] InquirydataBuffer A pointer to inquiry data buffer.\r
a3589760 120 @param[in,out] InquiryDataLength The length of inquiry data buffer.\r
121 @param[in] EnableVitalProductData Boolean to enable Vital Product Data.\r
122\r
bf231ea6
A
123 @retval EFI_SUCCESS The status of the unit is tested successfully.\r
124 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, \r
125 but the entire DataBuffer could not be transferred.\r
126 The actual number of bytes transferred is returned\r
127 in TransferLength.\r
128 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because \r
129 there are too many SCSI Command Packets already \r
130 queued.\r
131 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send \r
132 the SCSI Request Packet.\r
8069d49e 133 @retval EFI_INVALID_PARAMETER The contents of CommandPacket are invalid, or ScsiIo is NULL.\r
bf231ea6
A
134 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet\r
135 is not supported by the SCSI initiator(i.e., SCSI \r
136 Host Controller).\r
137 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI \r
138 Request Packet to execute.\r
a3589760 139\r
bf231ea6 140**/\r
a02e796b 141EFI_STATUS\r
d35be2a4 142ScsiInquiryCommand (\r
a02e796b 143 IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
144 IN UINT64 Timeout,\r
145 IN VOID *SenseData,\r
146 IN OUT UINT8 *SenseDataLength,\r
147 OUT UINT8 *HostAdapterStatus,\r
148 OUT UINT8 *TargetStatus,\r
8069d49e 149 IN VOID *InquiryDataBuffer,\r
a02e796b 150 IN OUT UINT32 *InquiryDataLength,\r
151 IN BOOLEAN EnableVitalProductData\r
152 )\r
a02e796b 153{\r
154 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;\r
155 UINT64 Lun;\r
156 UINT8 *Target;\r
157 UINT8 TargetArray[EFI_SCSI_TARGET_MAX_BYTES];\r
158 EFI_STATUS Status;\r
159 UINT8 Cdb[6];\r
160\r
8069d49e
LG
161 ASSERT (SenseDataLength != NULL);\r
162 ASSERT (HostAdapterStatus != NULL);\r
163 ASSERT (TargetStatus != NULL);\r
164 ASSERT (InquiryDataLength != NULL);\r
165 \r
166 if (ScsiIo == NULL) {\r
167 return EFI_INVALID_PARAMETER;\r
168 }\r
169\r
a02e796b 170 ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));\r
171 ZeroMem (Cdb, 6);\r
172\r
173 CommandPacket.Timeout = Timeout;\r
174 CommandPacket.InDataBuffer = InquiryDataBuffer;\r
175 CommandPacket.InTransferLength= *InquiryDataLength;\r
176 CommandPacket.SenseData = SenseData;\r
177 CommandPacket.SenseDataLength = *SenseDataLength;\r
178 CommandPacket.Cdb = Cdb;\r
179\r
180 Target = &TargetArray[0];\r
181 ScsiIo->GetDeviceLocation (ScsiIo, &Target, &Lun);\r
182\r
183 Cdb[0] = EFI_SCSI_OP_INQUIRY;\r
184 Cdb[1] = (UINT8) (Lun & 0xe0);\r
185 if (EnableVitalProductData) {\r
186 Cdb[1] |= 0x01;\r
187 }\r
188\r
189 if (*InquiryDataLength > 0xff) {\r
190 *InquiryDataLength = 0xff;\r
191 }\r
192\r
193 Cdb[4] = (UINT8) (*InquiryDataLength);\r
194 CommandPacket.CdbLength = (UINT8) 6;\r
195 CommandPacket.DataDirection = EFI_SCSI_DATA_IN;\r
196\r
197 Status = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);\r
198\r
199 *HostAdapterStatus = CommandPacket.HostAdapterStatus;\r
200 *TargetStatus = CommandPacket.TargetStatus;\r
201 *SenseDataLength = CommandPacket.SenseDataLength;\r
202 *InquiryDataLength = CommandPacket.InTransferLength;\r
203\r
204 return Status;\r
205}\r
206\r
bf231ea6 207\r
a3589760 208/**\r
bf231ea6 209 Function to submit SCSI mode sense 10 command.\r
a3589760 210\r
211 @param[in] ScsiIo A pointer to SCSI IO protocol.\r
212 @param[in] Timeout The length of timeout period.\r
213 @param[out] SenseData A pointer to output sense data.\r
8069d49e
LG
214 @param[in out] SenseDataLength On input, the length in bytes of the SenseData buffer. On\r
215 output, the number of bytes written to the SenseData buffer.\r
a3589760 216 @param[out] HostAdapterStatus The status of Host Adapter.\r
217 @param[out] TargetStatus The status of the target.\r
218 @param[in] DataBuffer A pointer to input data buffer.\r
219 @param[in,out] DataLength The length of input data buffer.\r
220 @param[in] DBDField The DBD Field (Optional).\r
221 @param[in] PageControl Page Control.\r
222 @param[in] PageCode Page code.\r
223\r
bf231ea6 224 @retval EFI_SUCCESS The status of the unit is tested successfully.\r
c7a54f25 225 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, \r
bf231ea6
A
226 but the entire DataBuffer could not be transferred.\r
227 The actual number of bytes transferred is returned\r
228 in TransferLength.\r
229 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because \r
230 there are too many SCSI Command Packets already \r
231 queued.\r
232 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send \r
233 the SCSI Request Packet.\r
8069d49e 234 @retval EFI_INVALID_PARAMETER The contents of CommandPacket are invalid, or ScsiIo is NULL. \r
bf231ea6
A
235 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet\r
236 is not supported by the SCSI initiator(i.e., SCSI \r
237 Host Controller).\r
238 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI \r
239 Request Packet to execute.\r
a3589760 240\r
bf231ea6 241**/\r
a02e796b 242EFI_STATUS\r
d35be2a4 243ScsiModeSense10Command (\r
a02e796b 244 IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
245 IN UINT64 Timeout,\r
246 IN VOID *SenseData,\r
247 IN OUT UINT8 *SenseDataLength,\r
248 OUT UINT8 *HostAdapterStatus,\r
249 OUT UINT8 *TargetStatus,\r
250 IN VOID *DataBuffer,\r
251 IN OUT UINT32 *DataLength,\r
252 IN UINT8 DBDField, OPTIONAL\r
253 IN UINT8 PageControl,\r
254 IN UINT8 PageCode\r
255 )\r
a02e796b 256{\r
257 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;\r
258 UINT64 Lun;\r
259 UINT8 *Target;\r
260 UINT8 TargetArray[EFI_SCSI_TARGET_MAX_BYTES];\r
261 EFI_STATUS Status;\r
262 UINT8 Cdb[10];\r
263\r
8069d49e
LG
264 ASSERT (SenseDataLength != NULL);\r
265 ASSERT (HostAdapterStatus != NULL);\r
266 ASSERT (TargetStatus != NULL);\r
267 ASSERT (DataLength != NULL);\r
268 \r
269 if (ScsiIo == NULL) {\r
270 return EFI_INVALID_PARAMETER;\r
271 }\r
272\r
a02e796b 273 ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));\r
274 ZeroMem (Cdb, 10);\r
275\r
276 CommandPacket.Timeout = Timeout;\r
277 CommandPacket.InDataBuffer = DataBuffer;\r
278 CommandPacket.SenseData = SenseData;\r
279 CommandPacket.InTransferLength= *DataLength;\r
280 CommandPacket.Cdb = Cdb;\r
281 //\r
282 // Fill Cdb for Mode Sense (10) Command\r
283 //\r
284 Target = &TargetArray[0];\r
285 ScsiIo->GetDeviceLocation (ScsiIo, &Target, &Lun);\r
286\r
287 Cdb[0] = EFI_SCSI_OP_MODE_SEN10;\r
581e82a1 288 Cdb[1] = (UINT8) ((Lun & 0xe0) + ((DBDField << 3) & 0x08));\r
a02e796b 289 Cdb[2] = (UINT8) ((PageControl & 0xc0) | (PageCode & 0x3f));\r
290 Cdb[7] = (UINT8) (*DataLength >> 8);\r
291 Cdb[8] = (UINT8) (*DataLength);\r
292\r
293 CommandPacket.CdbLength = 10;\r
294 CommandPacket.DataDirection = EFI_SCSI_DATA_IN;\r
295 CommandPacket.SenseDataLength = *SenseDataLength;\r
296\r
297 Status = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);\r
298\r
299 *HostAdapterStatus = CommandPacket.HostAdapterStatus;\r
300 *TargetStatus = CommandPacket.TargetStatus;\r
301 *SenseDataLength = CommandPacket.SenseDataLength;\r
302 *DataLength = CommandPacket.InTransferLength;\r
303\r
304 return Status;\r
305}\r
306\r
bf231ea6 307\r
a3589760 308/**\r
bf231ea6 309 Function to submit SCSI request sense command.\r
a3589760 310\r
8069d49e
LG
311 @param[in] ScsiIo A pointer to SCSI IO protocol.\r
312 @param[in] Timeout The length of timeout period.\r
313 @param[in] SenseData A pointer to output sense data.\r
314 @param[in out] SenseDataLength On input, the length in bytes of the SenseData buffer. On\r
315 output, the number of bytes written to the SenseData buffer.\r
316 @param[out] HostAdapterStatus The status of Host Adapter.\r
317 @param[out] TargetStatus The status of the target.\r
a3589760 318\r
319 @retval EFI_SUCCESS Valid data returned\r
bf231ea6 320 @retval EFI_SUCCESS The status of the unit is tested successfully.\r
c7a54f25 321 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, \r
bf231ea6
A
322 but the entire DataBuffer could not be transferred.\r
323 The actual number of bytes transferred is returned\r
324 in TransferLength.\r
325 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because \r
326 there are too many SCSI Command Packets already \r
327 queued.\r
328 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send \r
329 the SCSI Request Packet.\r
8069d49e 330 @retval EFI_INVALID_PARAMETER The contents of CommandPacket are invalid, or ScsiIo is NULL.\r
bf231ea6
A
331 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet\r
332 is not supported by the SCSI initiator(i.e., SCSI \r
333 Host Controller).\r
334 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI \r
335 Request Packet to execute.\r
a3589760 336\r
bf231ea6 337**/\r
a02e796b 338EFI_STATUS\r
d35be2a4 339ScsiRequestSenseCommand (\r
a02e796b 340 IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
341 IN UINT64 Timeout,\r
342 IN VOID *SenseData,\r
343 IN OUT UINT8 *SenseDataLength,\r
344 OUT UINT8 *HostAdapterStatus,\r
345 OUT UINT8 *TargetStatus\r
346 )\r
a02e796b 347{\r
348 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;\r
349 UINT64 Lun;\r
350 UINT8 *Target;\r
351 UINT8 TargetArray[EFI_SCSI_TARGET_MAX_BYTES];\r
352 EFI_STATUS Status;\r
353 UINT8 Cdb[6];\r
354\r
8069d49e
LG
355 ASSERT (SenseDataLength != NULL);\r
356 ASSERT (HostAdapterStatus != NULL);\r
357 ASSERT (TargetStatus != NULL);\r
358 \r
359 if (ScsiIo == NULL) {\r
360 return EFI_INVALID_PARAMETER;\r
361 }\r
362\r
a02e796b 363 ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));\r
364 ZeroMem (Cdb, 6);\r
365\r
366 CommandPacket.Timeout = Timeout;\r
367 CommandPacket.InDataBuffer = SenseData;\r
368 CommandPacket.SenseData = NULL;\r
369 CommandPacket.InTransferLength= *SenseDataLength;\r
370 CommandPacket.Cdb = Cdb;\r
371 //\r
372 // Fill Cdb for Request Sense Command\r
373 //\r
374 Target = &TargetArray[0];\r
375 ScsiIo->GetDeviceLocation (ScsiIo, &Target, &Lun);\r
376\r
377 Cdb[0] = EFI_SCSI_OP_REQUEST_SENSE;\r
378 Cdb[1] = (UINT8) (Lun & 0xe0);\r
379 Cdb[4] = (UINT8) (*SenseDataLength);\r
380\r
381 CommandPacket.CdbLength = (UINT8) 6;\r
382 CommandPacket.DataDirection = EFI_SCSI_DATA_IN;\r
383 CommandPacket.SenseDataLength = 0;\r
384\r
385 Status = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);\r
386\r
387 *HostAdapterStatus = CommandPacket.HostAdapterStatus;\r
388 *TargetStatus = CommandPacket.TargetStatus;\r
389 *SenseDataLength = (UINT8) CommandPacket.InTransferLength;\r
390\r
391 return Status;\r
392}\r
393\r
bf231ea6 394\r
a3589760 395/**\r
bf231ea6
A
396 Function to submit read capacity command.\r
397\r
a3589760 398 @param[in] ScsiIo A pointer to SCSI IO protocol.\r
399 @param[in] Timeout The length of timeout period.\r
400 @param[out] SenseData A pointer to output sense data.\r
8069d49e
LG
401 @param[in out] SenseDataLength On input, the length in bytes of the SenseData buffer. On\r
402 output, the number of bytes written to the SenseData buffer.\r
a3589760 403 @param[out] HostAdapterStatus The status of Host Adapter.\r
404 @param[out] TargetStatus The status of the target.\r
405 @param[out] DataBuffer A pointer to a data buffer.\r
406 @param[in,out] DataLength The length of data buffer.\r
407 @param[in] PMI Partial medium indicator.\r
408\r
bf231ea6 409 @retval EFI_SUCCESS The status of the unit is tested successfully.\r
c7a54f25 410 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, \r
bf231ea6
A
411 but the entire DataBuffer could not be transferred.\r
412 The actual number of bytes transferred is returned\r
413 in TransferLength.\r
414 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because \r
415 there are too many SCSI Command Packets already \r
416 queued.\r
417 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send \r
418 the SCSI Request Packet.\r
8069d49e 419 @retval EFI_INVALID_PARAMETER The contents of CommandPacket are invalid, or ScsiIo is NULL.\r
bf231ea6
A
420 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet\r
421 is not supported by the SCSI initiator(i.e., SCSI \r
422 Host Controller).\r
423 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI \r
424 Request Packet to execute.\r
a3589760 425\r
bf231ea6 426**/\r
a02e796b 427EFI_STATUS\r
d35be2a4 428ScsiReadCapacityCommand (\r
a02e796b 429 IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
430 IN UINT64 Timeout,\r
431 IN VOID *SenseData,\r
432 IN OUT UINT8 *SenseDataLength,\r
433 OUT UINT8 *HostAdapterStatus,\r
434 OUT UINT8 *TargetStatus,\r
435 OUT VOID *DataBuffer,\r
436 IN OUT UINT32 *DataLength,\r
437 IN BOOLEAN PMI\r
438 )\r
a02e796b 439{\r
440 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;\r
441 UINT64 Lun;\r
442 UINT8 *Target;\r
443 UINT8 TargetArray[EFI_SCSI_TARGET_MAX_BYTES];\r
444 EFI_STATUS Status;\r
445 UINT8 Cdb[10];\r
446\r
8069d49e
LG
447 ASSERT (SenseDataLength != NULL);\r
448 ASSERT (HostAdapterStatus != NULL);\r
449 ASSERT (TargetStatus != NULL);\r
450 ASSERT (DataLength != NULL);\r
451 \r
452 if (ScsiIo == NULL) {\r
453 return EFI_INVALID_PARAMETER;\r
454 }\r
455\r
a02e796b 456 ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));\r
457 ZeroMem (Cdb, 10);\r
458\r
459 CommandPacket.Timeout = Timeout;\r
460 CommandPacket.InDataBuffer = DataBuffer;\r
461 CommandPacket.SenseData = SenseData;\r
462 CommandPacket.InTransferLength= *DataLength;\r
463 CommandPacket.Cdb = Cdb;\r
464 //\r
465 // Fill Cdb for Read Capacity Command\r
466 //\r
467 Target = &TargetArray[0];\r
468 ScsiIo->GetDeviceLocation (ScsiIo, &Target, &Lun);\r
469\r
470 Cdb[0] = EFI_SCSI_OP_READ_CAPACITY;\r
471 Cdb[1] = (UINT8) (Lun & 0xe0);\r
472 if (!PMI) {\r
473 //\r
474 // Partial medium indicator,if PMI is FALSE, the Cdb.2 ~ Cdb.5 MUST BE ZERO.\r
475 //\r
476 ZeroMem ((Cdb + 2), 4);\r
477 } else {\r
478 Cdb[8] |= 0x01;\r
479 }\r
480\r
481 CommandPacket.CdbLength = 10;\r
482 CommandPacket.DataDirection = EFI_SCSI_DATA_IN;\r
483 CommandPacket.SenseDataLength = *SenseDataLength;\r
484\r
485 Status = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);\r
486\r
487 *HostAdapterStatus = CommandPacket.HostAdapterStatus;\r
488 *TargetStatus = CommandPacket.TargetStatus;\r
489 *SenseDataLength = CommandPacket.SenseDataLength;\r
490 *DataLength = CommandPacket.InTransferLength;\r
491\r
492 return Status;\r
493}\r
494\r
bf231ea6 495\r
a3589760 496/**\r
bf231ea6 497 Function to submit read 10 command.\r
a3589760 498\r
499 @param[in] ScsiIo A pointer to SCSI IO protocol.\r
500 @param[in] Timeout The length of timeout period.\r
501 @param[out] SenseData A pointer to output sense data.\r
8069d49e
LG
502 @param[in out] SenseDataLength On input, the length in bytes of the SenseData buffer. On\r
503 output, the number of bytes written to the SenseData buffer.\r
a3589760 504 @param[out] HostAdapterStatus The status of Host Adapter.\r
505 @param[out] TargetStatus The status of the target.\r
506 @param[out] DataBuffer Read 10 command data.\r
507 @param[in,out] DataLength The length of data buffer.\r
508 @param[in] StartLba The start address of LBA.\r
509 @param[in] SectorSize The sector size.\r
510\r
bf231ea6 511 @retval EFI_SUCCESS The status of the unit is tested successfully.\r
c7a54f25 512 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, \r
bf231ea6
A
513 but the entire DataBuffer could not be transferred.\r
514 The actual number of bytes transferred is returned\r
515 in TransferLength.\r
516 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because \r
517 there are too many SCSI Command Packets already \r
518 queued.\r
519 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send \r
520 the SCSI Request Packet.\r
8069d49e 521 @retval EFI_INVALID_PARAMETER The contents of CommandPacket are invalid, or ScsiIo is NULL.\r
bf231ea6
A
522 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet\r
523 is not supported by the SCSI initiator(i.e., SCSI \r
524 Host Controller).\r
525 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI \r
526 Request Packet to execute.\r
a3589760 527\r
bf231ea6 528**/\r
a02e796b 529EFI_STATUS\r
d35be2a4 530ScsiRead10Command (\r
a02e796b 531 IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
532 IN UINT64 Timeout,\r
533 IN VOID *SenseData,\r
534 IN OUT UINT8 *SenseDataLength,\r
535 OUT UINT8 *HostAdapterStatus,\r
536 OUT UINT8 *TargetStatus,\r
537 OUT VOID *DataBuffer,\r
538 IN OUT UINT32 *DataLength,\r
539 IN UINT32 StartLba,\r
540 IN UINT32 SectorSize\r
541 )\r
a02e796b 542{\r
543 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;\r
544 UINT64 Lun;\r
545 UINT8 *Target;\r
546 UINT8 TargetArray[EFI_SCSI_TARGET_MAX_BYTES];\r
547 EFI_STATUS Status;\r
548 UINT8 Cdb[10];\r
549\r
8069d49e
LG
550 ASSERT (SenseDataLength != NULL);\r
551 ASSERT (HostAdapterStatus != NULL);\r
552 ASSERT (TargetStatus != NULL);\r
553 ASSERT (DataLength != NULL);\r
554 \r
555 if (ScsiIo == NULL) {\r
556 return EFI_INVALID_PARAMETER;\r
557 }\r
558\r
a02e796b 559 ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));\r
560 ZeroMem (Cdb, 10);\r
561\r
562 CommandPacket.Timeout = Timeout;\r
563 CommandPacket.InDataBuffer = DataBuffer;\r
564 CommandPacket.SenseData = SenseData;\r
565 CommandPacket.InTransferLength= *DataLength;\r
566 CommandPacket.Cdb = Cdb;\r
567 //\r
568 // Fill Cdb for Read (10) Command\r
569 //\r
570 Target = &TargetArray[0];\r
571 ScsiIo->GetDeviceLocation (ScsiIo, &Target, &Lun);\r
572\r
573 Cdb[0] = EFI_SCSI_OP_READ10;\r
574 Cdb[1] = (UINT8) (Lun & 0xe0);\r
575 Cdb[2] = (UINT8) (StartLba >> 24);\r
576 Cdb[3] = (UINT8) (StartLba >> 16);\r
577 Cdb[4] = (UINT8) (StartLba >> 8);\r
578 Cdb[5] = (UINT8) (StartLba & 0xff);\r
579 Cdb[7] = (UINT8) (SectorSize >> 8);\r
580 Cdb[8] = (UINT8) (SectorSize & 0xff);\r
581\r
582 CommandPacket.CdbLength = 10;\r
583 CommandPacket.DataDirection = EFI_SCSI_DATA_IN;\r
584 CommandPacket.SenseDataLength = *SenseDataLength;\r
585\r
586 Status = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);\r
587\r
588 *HostAdapterStatus = CommandPacket.HostAdapterStatus;\r
589 *TargetStatus = CommandPacket.TargetStatus;\r
590 *SenseDataLength = CommandPacket.SenseDataLength;\r
591 *DataLength = CommandPacket.InTransferLength;\r
592\r
593 return Status;\r
594}\r
595\r
bf231ea6 596\r
a3589760 597/**\r
bf231ea6 598 Function to submit SCSI write 10 command.\r
a3589760 599\r
600 @param[in] ScsiIo SCSI IO Protocol to use\r
601 @param[in] Timeout The length of timeout period.\r
602 @param[out] SenseData A pointer to output sense data.\r
8069d49e
LG
603 @param[in out] SenseDataLength On input, the length in bytes of the SenseData buffer. On\r
604 output, the number of bytes written to the SenseData buffer.\r
a3589760 605 @param[out] HostAdapterStatus The status of Host Adapter.\r
606 @param[out] TargetStatus The status of the target.\r
607 @param[out] DataBuffer A pointer to a data buffer.\r
608 @param[in,out] DataLength The length of data buffer.\r
609 @param[in] StartLba The start address of LBA.\r
610 @param[in] SectorSize The sector size.\r
611\r
bf231ea6 612 @retval EFI_SUCCESS The status of the unit is tested successfully.\r
c7a54f25 613 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, \r
bf231ea6
A
614 but the entire DataBuffer could not be transferred.\r
615 The actual number of bytes transferred is returned\r
616 in InTransferLength.\r
617 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because \r
618 there are too many SCSI Command Packets already \r
619 queued.\r
620 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send \r
621 the SCSI Request Packet.\r
8069d49e 622 @retval EFI_INVALID_PARAMETER The contents of CommandPacket are invalid, or ScsiIo is NULL.\r
bf231ea6
A
623 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet\r
624 is not supported by the SCSI initiator(i.e., SCSI \r
625 Host Controller).\r
626 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI \r
627 Request Packet to execute.\r
a3589760 628\r
bf231ea6 629**/\r
a02e796b 630EFI_STATUS\r
d35be2a4 631ScsiWrite10Command (\r
a02e796b 632 IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
633 IN UINT64 Timeout,\r
634 IN VOID *SenseData,\r
635 IN OUT UINT8 *SenseDataLength,\r
636 OUT UINT8 *HostAdapterStatus,\r
637 OUT UINT8 *TargetStatus,\r
638 OUT VOID *DataBuffer,\r
639 IN OUT UINT32 *DataLength,\r
640 IN UINT32 StartLba,\r
641 IN UINT32 SectorSize\r
642 )\r
a02e796b 643{\r
644 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;\r
645 UINT64 Lun;\r
646 UINT8 *Target;\r
647 UINT8 TargetArray[EFI_SCSI_TARGET_MAX_BYTES];\r
648 EFI_STATUS Status;\r
649 UINT8 Cdb[10];\r
650\r
8069d49e
LG
651 ASSERT (SenseDataLength != NULL);\r
652 ASSERT (HostAdapterStatus != NULL);\r
653 ASSERT (TargetStatus != NULL);\r
654 ASSERT (DataLength != NULL);\r
655 \r
656 if (ScsiIo == NULL) {\r
657 return EFI_INVALID_PARAMETER;\r
658 }\r
659\r
a02e796b 660 ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));\r
661 ZeroMem (Cdb, 10);\r
662\r
663 CommandPacket.Timeout = Timeout;\r
664 CommandPacket.OutDataBuffer = DataBuffer;\r
665 CommandPacket.SenseData = SenseData;\r
666 CommandPacket.OutTransferLength= *DataLength;\r
667 CommandPacket.Cdb = Cdb;\r
668 //\r
669 // Fill Cdb for Write (10) Command\r
670 //\r
671 Target = &TargetArray[0];\r
672 ScsiIo->GetDeviceLocation (ScsiIo, &Target, &Lun);\r
673\r
674 Cdb[0] = EFI_SCSI_OP_WRITE10;\r
675 Cdb[1] = (UINT8) (Lun & 0xe0);\r
676 Cdb[2] = (UINT8) (StartLba >> 24);\r
677 Cdb[3] = (UINT8) (StartLba >> 16);\r
678 Cdb[4] = (UINT8) (StartLba >> 8);\r
679 Cdb[5] = (UINT8) StartLba;\r
680 Cdb[7] = (UINT8) (SectorSize >> 8);\r
681 Cdb[8] = (UINT8) SectorSize;\r
682\r
683 CommandPacket.CdbLength = 10;\r
684 CommandPacket.DataDirection = EFI_SCSI_DATA_OUT;\r
685 CommandPacket.SenseDataLength = *SenseDataLength;\r
686\r
687 Status = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);\r
688\r
689 *HostAdapterStatus = CommandPacket.HostAdapterStatus;\r
690 *TargetStatus = CommandPacket.TargetStatus;\r
691 *SenseDataLength = CommandPacket.SenseDataLength;\r
ba7e162e 692 *DataLength = CommandPacket.OutTransferLength;\r
a02e796b 693\r
694 return Status;\r
695}\r