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