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