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