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