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