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