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