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