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