]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdePkg/Library/UefiScsiLib/UefiScsiLib.c
Code Scrub the common includes in MdePkg.
[mirror_edk2.git] / MdePkg / Library / UefiScsiLib / UefiScsiLib.c
... / ...
CommitLineData
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
14\r
15\r
16#include <PiDxe.h>\r
17#include <Library/DebugLib.h>\r
18#include <Library/ScsiLib.h>\r
19#include <Library/BaseMemoryLib.h>\r
20\r
21#include <IndustryStandard/Scsi.h>\r
22\r
23\r
24/**\r
25 Function test the ready status of the SCSI unit.\r
26\r
27 @param[in] ScsiIo A pointer to SCSI IO protocol.\r
28 @param[in] Timeout The length of timeout period.\r
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
33 @param[out] HostAdapterStatus The status of Host Adapter.\r
34 @param[out] TargetStatus The status of the target.\r
35\r
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
46 @retval EFI_INVALID_PARAMETER The contents of CommandPacket are invalid, or ScsiIo is NULL. \r
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
52\r
53**/\r
54EFI_STATUS\r
55EFIAPI\r
56ScsiTestUnitReadyCommand (\r
57 IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
58 IN UINT64 Timeout,\r
59 IN OUT VOID *SenseData,\r
60 IN OUT UINT8 *SenseDataLength,\r
61 OUT UINT8 *HostAdapterStatus,\r
62 OUT UINT8 *TargetStatus\r
63 )\r
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
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
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
110\r
111/**\r
112 Function to submit SCSI inquiry command.\r
113\r
114 @param[in] ScsiIo SCSI IO Protocol to use\r
115 @param[in] Timeout The length of timeout period.\r
116 @param[out] SenseData A pointer to output sense data.\r
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
119 @param[out] HostAdapterStatus The status of Host Adapter.\r
120 @param[out] TargetStatus The status of the target.\r
121 @param[in] InquirydataBuffer A pointer to inquiry data buffer.\r
122 @param[in,out] InquiryDataLength The length of inquiry data buffer.\r
123 @param[in] EnableVitalProductData Boolean to enable Vital Product Data.\r
124\r
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
135 @retval EFI_INVALID_PARAMETER The contents of CommandPacket are invalid, or ScsiIo is NULL.\r
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
141\r
142**/\r
143EFI_STATUS\r
144EFIAPI\r
145ScsiInquiryCommand (\r
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
152 IN VOID *InquiryDataBuffer,\r
153 IN OUT UINT32 *InquiryDataLength,\r
154 IN BOOLEAN EnableVitalProductData\r
155 )\r
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
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
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
210\r
211/**\r
212 Function to submit SCSI mode sense 10 command.\r
213\r
214 @param[in] ScsiIo A pointer to SCSI IO protocol.\r
215 @param[in] Timeout The length of timeout period.\r
216 @param[out] SenseData A pointer to output sense data.\r
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
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
222 @param[in,out] DataLength The length of input data buffer.\r
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
227 @retval EFI_SUCCESS The status of the unit is tested successfully.\r
228 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, \r
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
237 @retval EFI_INVALID_PARAMETER The contents of CommandPacket are invalid, or ScsiIo is NULL. \r
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
243\r
244**/\r
245EFI_STATUS\r
246EFIAPI\r
247ScsiModeSense10Command (\r
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
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
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
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
292 Cdb[1] = (UINT8) ((Lun & 0xe0) + ((DBDField << 3) & 0x08));\r
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
311\r
312/**\r
313 Function to submit SCSI request sense command.\r
314\r
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
322\r
323 @retval EFI_SUCCESS Valid data returned\r
324 @retval EFI_SUCCESS The status of the unit is tested successfully.\r
325 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, \r
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
334 @retval EFI_INVALID_PARAMETER The contents of CommandPacket are invalid, or ScsiIo is NULL.\r
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
340\r
341**/\r
342EFI_STATUS\r
343EFIAPI\r
344ScsiRequestSenseCommand (\r
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
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
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
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
399\r
400/**\r
401 Function to submit read capacity command.\r
402\r
403 @param[in] ScsiIo A pointer to SCSI IO protocol.\r
404 @param[in] Timeout The length of timeout period.\r
405 @param[out] SenseData A pointer to output sense data.\r
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
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
411 @param[in,out] DataLength The length of data buffer.\r
412 @param[in] PMI Partial medium indicator.\r
413\r
414 @retval EFI_SUCCESS The status of the unit is tested successfully.\r
415 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, \r
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
424 @retval EFI_INVALID_PARAMETER The contents of CommandPacket are invalid, or ScsiIo is NULL.\r
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
430\r
431**/\r
432EFI_STATUS\r
433EFIAPI\r
434ScsiReadCapacityCommand (\r
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
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
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
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
501\r
502/**\r
503 Function to submit read 10 command.\r
504\r
505 @param[in] ScsiIo A pointer to SCSI IO protocol.\r
506 @param[in] Timeout The length of timeout period.\r
507 @param[out] SenseData A pointer to output sense data.\r
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
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
513 @param[in,out] DataLength The length of data buffer.\r
514 @param[in] StartLba The start address of LBA.\r
515 @param[in] SectorSize The sector size.\r
516\r
517 @retval EFI_SUCCESS The status of the unit is tested successfully.\r
518 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, \r
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
527 @retval EFI_INVALID_PARAMETER The contents of CommandPacket are invalid, or ScsiIo is NULL.\r
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
533\r
534**/\r
535EFI_STATUS\r
536EFIAPI\r
537ScsiRead10Command (\r
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
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
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
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
603\r
604/**\r
605 Function to submit SCSI write 10 command.\r
606\r
607 @param[in] ScsiIo SCSI IO Protocol to use\r
608 @param[in] Timeout The length of timeout period.\r
609 @param[out] 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
611 output, the number of bytes written to the SenseData buffer.\r
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
615 @param[in,out] DataLength The length of data buffer.\r
616 @param[in] StartLba The start address of LBA.\r
617 @param[in] SectorSize The sector size.\r
618\r
619 @retval EFI_SUCCESS The status of the unit is tested successfully.\r
620 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, \r
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
629 @retval EFI_INVALID_PARAMETER The contents of CommandPacket are invalid, or ScsiIo is NULL.\r
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
635\r
636**/\r
637EFI_STATUS\r
638EFIAPI\r
639ScsiWrite10Command (\r
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
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
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
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
700 *DataLength = CommandPacket.OutTransferLength;\r
701\r
702 return Status;\r
703}\r
704\r