]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Bus/Ata/AtaBusDxe/AtaPassThruExecute.c
Add missing status code in several modules.
[mirror_edk2.git] / MdeModulePkg / Bus / Ata / AtaBusDxe / AtaPassThruExecute.c
1 /** @file
2 This file implements ATA pass through transaction for ATA bus driver.
3
4 This file implements the low level execution of ATA pass through transaction.
5 It transforms the high level identity, read/write, reset command to ATA pass
6 through command and protocol.
7
8 NOTE: This file also implements the StorageSecurityCommandProtocol(SSP). For input
9 parameter SecurityProtocolSpecificData, ATA spec has no explicitly definition
10 for Security Protocol Specific layout. This implementation uses big endian for
11 Cylinder register.
12
13 Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
14 This program and the accompanying materials
15 are licensed and made available under the terms and conditions of the BSD License
16 which accompanies this distribution. The full text of the license may be found at
17 http://opensource.org/licenses/bsd-license.php
18
19 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
20 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
21
22
23 **/
24
25 #include "AtaBus.h"
26
27 #define ATA_CMD_TRUST_NON_DATA 0x5B
28 #define ATA_CMD_TRUST_RECEIVE 0x5C
29 #define ATA_CMD_TRUST_RECEIVE_DMA 0x5D
30 #define ATA_CMD_TRUST_SEND 0x5E
31 #define ATA_CMD_TRUST_SEND_DMA 0x5F
32
33 //
34 // Look up table (UdmaValid, IsWrite) for EFI_ATA_PASS_THRU_CMD_PROTOCOL
35 //
36 EFI_ATA_PASS_THRU_CMD_PROTOCOL mAtaPassThruCmdProtocols[][2] = {
37 {
38 EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_IN,
39 EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_OUT
40 },
41 {
42 EFI_ATA_PASS_THRU_PROTOCOL_UDMA_DATA_IN,
43 EFI_ATA_PASS_THRU_PROTOCOL_UDMA_DATA_OUT,
44 }
45 };
46
47 //
48 // Look up table (UdmaValid, Lba48Bit, IsIsWrite) for ATA_CMD
49 //
50 UINT8 mAtaCommands[][2][2] = {
51 {
52 {
53 ATA_CMD_READ_SECTORS, // 28-bit LBA; PIO read
54 ATA_CMD_WRITE_SECTORS // 28-bit LBA; PIO write
55 },
56 {
57 ATA_CMD_READ_SECTORS_EXT, // 48-bit LBA; PIO read
58 ATA_CMD_WRITE_SECTORS_EXT // 48-bit LBA; PIO write
59 }
60 },
61 {
62 {
63 ATA_CMD_READ_DMA, // 28-bit LBA; DMA read
64 ATA_CMD_WRITE_DMA // 28-bit LBA; DMA write
65 },
66 {
67 ATA_CMD_READ_DMA_EXT, // 48-bit LBA; DMA read
68 ATA_CMD_WRITE_DMA_EXT // 48-bit LBA; DMA write
69 }
70 }
71 };
72
73 //
74 // Look up table (UdmaValid, IsTrustSend) for ATA_CMD
75 //
76 UINT8 mAtaTrustCommands[2][2] = {
77 {
78 ATA_CMD_TRUST_RECEIVE, // PIO read
79 ATA_CMD_TRUST_SEND // PIO write
80 },
81 {
82 ATA_CMD_TRUST_RECEIVE_DMA, // DMA read
83 ATA_CMD_TRUST_SEND_DMA // DMA write
84 }
85 };
86
87
88 //
89 // Look up table (Lba48Bit) for maximum transfer block number
90 //
91 UINTN mMaxTransferBlockNumber[] = {
92 MAX_28BIT_TRANSFER_BLOCK_NUM,
93 MAX_48BIT_TRANSFER_BLOCK_NUM
94 };
95
96
97 /**
98 Wrapper for EFI_ATA_PASS_THRU_PROTOCOL.PassThru().
99
100 This function wraps the PassThru() invocation for ATA pass through function
101 for an ATA device. It assembles the ATA pass through command packet for ATA
102 transaction.
103
104 @param[in, out] AtaDevice The ATA child device involved for the operation.
105 @param[in, out] TaskPacket Pointer to a Pass Thru Command Packet. Optional,
106 if it is NULL, blocking mode, and use the packet
107 in AtaDevice. If it is not NULL, non blocking mode,
108 and pass down this Packet.
109 @param[in, out] Event If Event is NULL, then blocking I/O is performed.
110 If Event is not NULL and non-blocking I/O is
111 supported,then non-blocking I/O is performed,
112 and Event will be signaled when the write
113 request is completed.
114
115 @return The return status from EFI_ATA_PASS_THRU_PROTOCOL.PassThru().
116
117 **/
118 EFI_STATUS
119 AtaDevicePassThru (
120 IN OUT ATA_DEVICE *AtaDevice,
121 IN OUT EFI_ATA_PASS_THRU_COMMAND_PACKET *TaskPacket, OPTIONAL
122 IN OUT EFI_EVENT Event OPTIONAL
123 )
124 {
125 EFI_STATUS Status;
126 EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru;
127 EFI_ATA_PASS_THRU_COMMAND_PACKET *Packet;
128
129 //
130 // Assemble packet. If it is non blocking mode, the Ata driver should keep each
131 // subtask and clean them when the event is signaled.
132 //
133 if (TaskPacket != NULL) {
134 Packet = TaskPacket;
135 Packet->Asb = AllocateAlignedBuffer (AtaDevice, sizeof (EFI_ATA_STATUS_BLOCK));
136 if (Packet->Asb == NULL) {
137 return EFI_OUT_OF_RESOURCES;
138 }
139
140 CopyMem (Packet->Asb, AtaDevice->Asb, sizeof (EFI_ATA_STATUS_BLOCK));
141 Packet->Acb = AllocateCopyPool (sizeof (EFI_ATA_COMMAND_BLOCK), &AtaDevice->Acb);
142 } else {
143 Packet = &AtaDevice->Packet;
144 Packet->Asb = AtaDevice->Asb;
145 Packet->Acb = &AtaDevice->Acb;
146 }
147
148 AtaPassThru = AtaDevice->AtaBusDriverData->AtaPassThru;
149
150 Status = AtaPassThru->PassThru (
151 AtaPassThru,
152 AtaDevice->Port,
153 AtaDevice->PortMultiplierPort,
154 Packet,
155 Event
156 );
157 //
158 // Ensure ATA pass through caller and callee have the same
159 // interpretation of ATA pass through protocol.
160 //
161 ASSERT (Status != EFI_INVALID_PARAMETER);
162 ASSERT (Status != EFI_BAD_BUFFER_SIZE);
163
164 return Status;
165 }
166
167
168 /**
169 Wrapper for EFI_ATA_PASS_THRU_PROTOCOL.ResetDevice().
170
171 This function wraps the ResetDevice() invocation for ATA pass through function
172 for an ATA device.
173
174 @param AtaDevice The ATA child device involved for the operation.
175
176 @return The return status from EFI_ATA_PASS_THRU_PROTOCOL.PassThru().
177
178 **/
179 EFI_STATUS
180 ResetAtaDevice (
181 IN ATA_DEVICE *AtaDevice
182 )
183 {
184 EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru;
185
186 AtaPassThru = AtaDevice->AtaBusDriverData->AtaPassThru;
187
188 //
189 // Report Status Code to indicate reset happens
190 //
191 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
192 EFI_PROGRESS_CODE,
193 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_RESET),
194 AtaDevice->AtaBusDriverData->ParentDevicePath
195 );
196
197 return AtaPassThru->ResetDevice (
198 AtaPassThru,
199 AtaDevice->Port,
200 AtaDevice->PortMultiplierPort
201 );
202 }
203
204
205 /**
206 Prints ATA model name to ATA device structure.
207
208 This function converts ATA device model name from ATA identify data
209 to a string in ATA device structure. It needs to change the character
210 order in the original model name string.
211
212 @param AtaDevice The ATA child device involved for the operation.
213
214 **/
215 VOID
216 PrintAtaModelName (
217 IN OUT ATA_DEVICE *AtaDevice
218 )
219 {
220 UINTN Index;
221 CHAR8 *Source;
222 CHAR16 *Destination;
223
224 Source = AtaDevice->IdentifyData->ModelName;
225 Destination = AtaDevice->ModelName;
226
227 //
228 // Swap the byte order in the original module name.
229 //
230 for (Index = 0; Index < MAX_MODEL_NAME_LEN; Index += 2) {
231 Destination[Index] = Source[Index + 1];
232 Destination[Index + 1] = Source[Index];
233 }
234 AtaDevice->ModelName[MAX_MODEL_NAME_LEN] = L'\0';
235 }
236
237
238 /**
239 Gets ATA device Capacity according to ATA 6.
240
241 This function returns the capacity of the ATA device if it follows
242 ATA 6 to support 48 bit addressing.
243
244 @param AtaDevice The ATA child device involved for the operation.
245
246 @return The capacity of the ATA device or 0 if the device does not support
247 48-bit addressing defined in ATA 6.
248
249 **/
250 EFI_LBA
251 GetAtapi6Capacity (
252 IN ATA_DEVICE *AtaDevice
253 )
254 {
255 EFI_LBA Capacity;
256 EFI_LBA TmpLba;
257 UINTN Index;
258 ATA_IDENTIFY_DATA *IdentifyData;
259
260 IdentifyData = AtaDevice->IdentifyData;
261 if ((IdentifyData->command_set_supported_83 & BIT10) == 0) {
262 //
263 // The device doesn't support 48 bit addressing
264 //
265 return 0;
266 }
267
268 //
269 // 48 bit address feature set is supported, get maximum capacity
270 //
271 Capacity = 0;
272 for (Index = 0; Index < 4; Index++) {
273 //
274 // Lower byte goes first: word[100] is the lowest word, word[103] is highest
275 //
276 TmpLba = IdentifyData->maximum_lba_for_48bit_addressing[Index];
277 Capacity |= LShiftU64 (TmpLba, 16 * Index);
278 }
279
280 return Capacity;
281 }
282
283
284 /**
285 Identifies ATA device via the Identify data.
286
287 This function identifies the ATA device and initializes the Media information in
288 Block IO protocol interface.
289
290 @param AtaDevice The ATA child device involved for the operation.
291
292 @retval EFI_UNSUPPORTED The device is not a valid ATA device (hard disk).
293 @retval EFI_SUCCESS The device is successfully identified and Media information
294 is correctly initialized.
295
296 **/
297 EFI_STATUS
298 IdentifyAtaDevice (
299 IN OUT ATA_DEVICE *AtaDevice
300 )
301 {
302 ATA_IDENTIFY_DATA *IdentifyData;
303 EFI_BLOCK_IO_MEDIA *BlockMedia;
304 EFI_LBA Capacity;
305 UINT16 PhyLogicSectorSupport;
306 UINT16 UdmaMode;
307
308 IdentifyData = AtaDevice->IdentifyData;
309
310 if ((IdentifyData->config & BIT15) != 0) {
311 //
312 // This is not an hard disk
313 //
314 return EFI_UNSUPPORTED;
315 }
316
317 DEBUG ((EFI_D_INFO, "AtaBus - Identify Device: Port %x PortMultiplierPort %x\n", AtaDevice->Port, AtaDevice->PortMultiplierPort));
318
319 //
320 // Check whether the WORD 88 (supported UltraDMA by drive) is valid
321 //
322 if ((IdentifyData->field_validity & BIT2) != 0) {
323 UdmaMode = IdentifyData->ultra_dma_mode;
324 if ((UdmaMode & (BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6)) != 0) {
325 //
326 // If BIT0~BIT6 is selected, then UDMA is supported
327 //
328 AtaDevice->UdmaValid = TRUE;
329 }
330 }
331
332 Capacity = GetAtapi6Capacity (AtaDevice);
333 if (Capacity > MAX_28BIT_ADDRESSING_CAPACITY) {
334 //
335 // Capacity exceeds 120GB. 48-bit addressing is really needed
336 //
337 AtaDevice->Lba48Bit = TRUE;
338 } else {
339 //
340 // This is a hard disk <= 120GB capacity, treat it as normal hard disk
341 //
342 Capacity = ((UINT32)IdentifyData->user_addressable_sectors_hi << 16) | IdentifyData->user_addressable_sectors_lo;
343 AtaDevice->Lba48Bit = FALSE;
344 }
345
346 //
347 // Block Media Information:
348 //
349 BlockMedia = &AtaDevice->BlockMedia;
350 BlockMedia->LastBlock = Capacity - 1;
351 BlockMedia->IoAlign = AtaDevice->AtaBusDriverData->AtaPassThru->Mode->IoAlign;
352 //
353 // Check whether Long Physical Sector Feature is supported
354 //
355 PhyLogicSectorSupport = IdentifyData->phy_logic_sector_support;
356 if ((PhyLogicSectorSupport & (BIT14 | BIT15)) == BIT14) {
357 //
358 // Check whether one physical block contains multiple physical blocks
359 //
360 if ((PhyLogicSectorSupport & BIT13) != 0) {
361 BlockMedia->LogicalBlocksPerPhysicalBlock = (UINT32) (1 << (PhyLogicSectorSupport & 0x000f));
362 //
363 // Check lowest alignment of logical blocks within physical block
364 //
365 if ((IdentifyData->alignment_logic_in_phy_blocks & (BIT14 | BIT15)) == BIT14) {
366 BlockMedia->LowestAlignedLba = (EFI_LBA) ((BlockMedia->LogicalBlocksPerPhysicalBlock - ((UINT32)IdentifyData->alignment_logic_in_phy_blocks & 0x3fff)) %
367 BlockMedia->LogicalBlocksPerPhysicalBlock);
368 }
369 }
370 //
371 // Check logical block size
372 //
373 if ((PhyLogicSectorSupport & BIT12) != 0) {
374 BlockMedia->BlockSize = (UINT32) (((IdentifyData->logic_sector_size_hi << 16) | IdentifyData->logic_sector_size_lo) * sizeof (UINT16));
375 }
376 AtaDevice->BlockIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION2;
377 }
378 //
379 // Get ATA model name from identify data structure.
380 //
381 PrintAtaModelName (AtaDevice);
382
383 return EFI_SUCCESS;
384 }
385
386
387 /**
388 Discovers whether it is a valid ATA device.
389
390 This function issues ATA_CMD_IDENTIFY_DRIVE command to the ATA device to identify it.
391 If the command is executed successfully, it then identifies it and initializes
392 the Media information in Block IO protocol interface.
393
394 @param AtaDevice The ATA child device involved for the operation.
395
396 @retval EFI_SUCCESS The device is successfully identified and Media information
397 is correctly initialized.
398 @return others Some error occurs when discovering the ATA device.
399
400 **/
401 EFI_STATUS
402 DiscoverAtaDevice (
403 IN OUT ATA_DEVICE *AtaDevice
404 )
405 {
406 EFI_STATUS Status;
407 EFI_ATA_COMMAND_BLOCK *Acb;
408 EFI_ATA_PASS_THRU_COMMAND_PACKET *Packet;
409 UINTN Retry;
410
411 //
412 // Prepare for ATA command block.
413 //
414 Acb = ZeroMem (&AtaDevice->Acb, sizeof (EFI_ATA_COMMAND_BLOCK));
415 Acb->AtaCommand = ATA_CMD_IDENTIFY_DRIVE;
416 Acb->AtaDeviceHead = (UINT8) (BIT7 | BIT6 | BIT5 | (AtaDevice->PortMultiplierPort << 4));
417
418 //
419 // Prepare for ATA pass through packet.
420 //
421 Packet = ZeroMem (&AtaDevice->Packet, sizeof (EFI_ATA_PASS_THRU_COMMAND_PACKET));
422 Packet->InDataBuffer = AtaDevice->IdentifyData;
423 Packet->InTransferLength = sizeof (ATA_IDENTIFY_DATA);
424 Packet->Protocol = EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_IN;
425 Packet->Length = EFI_ATA_PASS_THRU_LENGTH_BYTES | EFI_ATA_PASS_THRU_LENGTH_SECTOR_COUNT;
426 Packet->Timeout = ATA_TIMEOUT;
427
428 Retry = MAX_RETRY_TIMES;
429 do {
430 Status = AtaDevicePassThru (AtaDevice, NULL, NULL);
431 if (!EFI_ERROR (Status)) {
432 //
433 // The command is issued successfully
434 //
435 Status = IdentifyAtaDevice (AtaDevice);
436 if (!EFI_ERROR (Status)) {
437 return Status;
438 }
439 }
440 } while (Retry-- > 0);
441
442 return Status;
443 }
444
445 /**
446 Transfer data from ATA device.
447
448 This function performs one ATA pass through transaction to transfer data from/to
449 ATA device. It chooses the appropriate ATA command and protocol to invoke PassThru
450 interface of ATA pass through.
451
452 @param[in, out] AtaDevice The ATA child device involved for the operation.
453 @param[in, out] TaskPacket Pointer to a Pass Thru Command Packet. Optional,
454 if it is NULL, blocking mode, and use the packet
455 in AtaDevice. If it is not NULL, non blocking mode,
456 and pass down this Packet.
457 @param[in, out] Buffer The pointer to the current transaction buffer.
458 @param[in] StartLba The starting logical block address to be accessed.
459 @param[in] TransferLength The block number or sector count of the transfer.
460 @param[in] IsWrite Indicates whether it is a write operation.
461 @param[in] Event If Event is NULL, then blocking I/O is performed.
462 If Event is not NULL and non-blocking I/O is
463 supported,then non-blocking I/O is performed,
464 and Event will be signaled when the write
465 request is completed.
466
467 @retval EFI_SUCCESS The data transfer is complete successfully.
468 @return others Some error occurs when transferring data.
469
470 **/
471 EFI_STATUS
472 TransferAtaDevice (
473 IN OUT ATA_DEVICE *AtaDevice,
474 IN OUT EFI_ATA_PASS_THRU_COMMAND_PACKET *TaskPacket, OPTIONAL
475 IN OUT VOID *Buffer,
476 IN EFI_LBA StartLba,
477 IN UINT32 TransferLength,
478 IN BOOLEAN IsWrite,
479 IN EFI_EVENT Event OPTIONAL
480 )
481 {
482 EFI_ATA_COMMAND_BLOCK *Acb;
483 EFI_ATA_PASS_THRU_COMMAND_PACKET *Packet;
484
485 //
486 // Ensure AtaDevice->UdmaValid, AtaDevice->Lba48Bit and IsWrite are valid boolean values
487 //
488 ASSERT ((UINTN) AtaDevice->UdmaValid < 2);
489 ASSERT ((UINTN) AtaDevice->Lba48Bit < 2);
490 ASSERT ((UINTN) IsWrite < 2);
491 //
492 // Prepare for ATA command block.
493 //
494 Acb = ZeroMem (&AtaDevice->Acb, sizeof (EFI_ATA_COMMAND_BLOCK));
495 Acb->AtaCommand = mAtaCommands[AtaDevice->UdmaValid][AtaDevice->Lba48Bit][IsWrite];
496 Acb->AtaSectorNumber = (UINT8) StartLba;
497 Acb->AtaCylinderLow = (UINT8) RShiftU64 (StartLba, 8);
498 Acb->AtaCylinderHigh = (UINT8) RShiftU64 (StartLba, 16);
499 Acb->AtaDeviceHead = (UINT8) (BIT7 | BIT6 | BIT5 | (AtaDevice->PortMultiplierPort << 4));
500 Acb->AtaSectorCount = (UINT8) TransferLength;
501 if (AtaDevice->Lba48Bit) {
502 Acb->AtaSectorNumberExp = (UINT8) RShiftU64 (StartLba, 24);
503 Acb->AtaCylinderLowExp = (UINT8) RShiftU64 (StartLba, 32);
504 Acb->AtaCylinderHighExp = (UINT8) RShiftU64 (StartLba, 40);
505 Acb->AtaSectorCountExp = (UINT8) (TransferLength >> 8);
506 } else {
507 Acb->AtaDeviceHead = (UINT8) (Acb->AtaDeviceHead | RShiftU64 (StartLba, 24));
508 }
509
510 //
511 // Prepare for ATA pass through packet.
512 //
513 if (TaskPacket != NULL) {
514 Packet = ZeroMem (TaskPacket, sizeof (EFI_ATA_PASS_THRU_COMMAND_PACKET));
515 } else {
516 Packet = ZeroMem (&AtaDevice->Packet, sizeof (EFI_ATA_PASS_THRU_COMMAND_PACKET));
517 }
518
519 if (IsWrite) {
520 Packet->OutDataBuffer = Buffer;
521 Packet->OutTransferLength = TransferLength;
522 } else {
523 Packet->InDataBuffer = Buffer;
524 Packet->InTransferLength = TransferLength;
525 }
526
527 Packet->Protocol = mAtaPassThruCmdProtocols[AtaDevice->UdmaValid][IsWrite];
528 Packet->Length = EFI_ATA_PASS_THRU_LENGTH_SECTOR_COUNT;
529 Packet->Timeout = ATA_TIMEOUT;
530
531 return AtaDevicePassThru (AtaDevice, TaskPacket, Event);
532 }
533
534 /**
535 Free SubTask.
536
537 @param[in, out] Task Pointer to task to be freed.
538
539 **/
540 VOID
541 EFIAPI
542 FreeAtaSubTask (
543 IN OUT ATA_BUS_ASYN_SUB_TASK *Task
544 )
545 {
546 if (Task->Packet.Asb != NULL) {
547 FreeAlignedBuffer (Task->Packet.Asb, sizeof (EFI_ATA_STATUS_BLOCK));
548 }
549 if (Task->Packet.Acb != NULL) {
550 FreePool (Task->Packet.Acb);
551 }
552
553 FreePool (Task);
554 }
555
556 /**
557 Call back funtion when the event is signaled.
558
559 @param[in] Event The Event this notify function registered to.
560 @param[in] Context Pointer to the context data registered to the
561 Event.
562
563 **/
564 VOID
565 EFIAPI
566 AtaNonBlockingCallBack (
567 IN EFI_EVENT Event,
568 IN VOID *Context
569 )
570 {
571 ATA_BUS_ASYN_SUB_TASK *Task;
572 ATA_BUS_ASYN_TASK *AtaTask;
573 ATA_DEVICE *AtaDevice;
574 LIST_ENTRY *Entry;
575 EFI_STATUS Status;
576
577 Task = (ATA_BUS_ASYN_SUB_TASK *) Context;
578 gBS->CloseEvent (Event);
579
580 AtaDevice = Task->AtaDevice;
581
582 //
583 // Check the command status.
584 // If there is error during the sub task source allocation, the error status
585 // should be returned to the caller directly, so here the Task->Token may already
586 // be deleted by the caller and no need to update the status.
587 //
588 if ((!(*Task->IsError)) && ((Task->Packet.Asb->AtaStatus & 0x01) == 0x01)) {
589 Task->Token->TransactionStatus = EFI_DEVICE_ERROR;
590 }
591 DEBUG ((
592 EFI_D_BLKIO,
593 "NON-BLOCKING EVENT FINISHED!- STATUS = %r\n",
594 Task->Token->TransactionStatus
595 ));
596
597 //
598 // Reduce the SubEventCount, till it comes to zero.
599 //
600 (*Task->UnsignalledEventCount) --;
601 DEBUG ((EFI_D_BLKIO, "UnsignalledEventCount = %d\n", *Task->UnsignalledEventCount));
602
603 //
604 // Remove the SubTask from the Task list.
605 //
606 RemoveEntryList (&Task->TaskEntry);
607 if ((*Task->UnsignalledEventCount) == 0) {
608 //
609 // All Sub tasks are done, then signal the upper layer event.
610 // Except there is error during the sub task source allocation.
611 //
612 if (!(*Task->IsError)) {
613 gBS->SignalEvent (Task->Token->Event);
614 DEBUG ((EFI_D_BLKIO, "Signal the upper layer event!\n"));
615 }
616
617 FreePool (Task->UnsignalledEventCount);
618 FreePool (Task->IsError);
619
620
621 //
622 // Finish all subtasks and move to the next task in AtaTaskList.
623 //
624 if (!IsListEmpty (&AtaDevice->AtaTaskList)) {
625 Entry = GetFirstNode (&AtaDevice->AtaTaskList);
626 AtaTask = ATA_AYNS_TASK_FROM_ENTRY (Entry);
627 DEBUG ((EFI_D_BLKIO, "Start to embark a new Ata Task\n"));
628 DEBUG ((EFI_D_BLKIO, "AtaTask->NumberOfBlocks = %x; AtaTask->Token=%x\n", AtaTask->NumberOfBlocks, AtaTask->Token));
629 Status = AccessAtaDevice (
630 AtaTask->AtaDevice,
631 AtaTask->Buffer,
632 AtaTask->StartLba,
633 AtaTask->NumberOfBlocks,
634 AtaTask->IsWrite,
635 AtaTask->Token
636 );
637 if (EFI_ERROR (Status)) {
638 AtaTask->Token->TransactionStatus = Status;
639 gBS->SignalEvent (AtaTask->Token->Event);
640 }
641 RemoveEntryList (Entry);
642 FreePool (AtaTask);
643 }
644 }
645
646 DEBUG ((
647 EFI_D_BLKIO,
648 "PACKET INFO: Write=%s, Length=%x, LowCylinder=%x, HighCylinder=%x, SectionNumber=%x\n",
649 Task->Packet.OutDataBuffer != NULL ? L"YES" : L"NO",
650 Task->Packet.OutDataBuffer != NULL ? Task->Packet.OutTransferLength : Task->Packet.InTransferLength,
651 Task->Packet.Acb->AtaCylinderLow,
652 Task->Packet.Acb->AtaCylinderHigh,
653 Task->Packet.Acb->AtaSectorCount
654 ));
655
656 //
657 // Free the buffer of SubTask.
658 //
659 FreeAtaSubTask (Task);
660 }
661
662 /**
663 Read or write a number of blocks from ATA device.
664
665 This function performs ATA pass through transactions to read/write data from/to
666 ATA device. It may separate the read/write request into several ATA pass through
667 transactions.
668
669 @param[in, out] AtaDevice The ATA child device involved for the operation.
670 @param[in, out] Buffer The pointer to the current transaction buffer.
671 @param[in] StartLba The starting logical block address to be accessed.
672 @param[in] NumberOfBlocks The block number or sector count of the transfer.
673 @param[in] IsWrite Indicates whether it is a write operation.
674 @param[in, out] Token A pointer to the token associated with the transaction.
675
676 @retval EFI_SUCCESS The data transfer is complete successfully.
677 @return others Some error occurs when transferring data.
678
679 **/
680 EFI_STATUS
681 AccessAtaDevice(
682 IN OUT ATA_DEVICE *AtaDevice,
683 IN OUT UINT8 *Buffer,
684 IN EFI_LBA StartLba,
685 IN UINTN NumberOfBlocks,
686 IN BOOLEAN IsWrite,
687 IN OUT EFI_BLOCK_IO2_TOKEN *Token
688 )
689 {
690 EFI_STATUS Status;
691 UINTN MaxTransferBlockNumber;
692 UINTN TransferBlockNumber;
693 UINTN BlockSize;
694 ATA_BUS_ASYN_SUB_TASK *SubTask;
695 UINTN *EventCount;
696 UINTN TempCount;
697 ATA_BUS_ASYN_TASK *AtaTask;
698 EFI_EVENT SubEvent;
699 UINTN Index;
700 BOOLEAN *IsError;
701 EFI_TPL OldTpl;
702
703 TempCount = 0;
704 Status = EFI_SUCCESS;
705 EventCount = NULL;
706 IsError = NULL;
707 Index = 0;
708 SubTask = NULL;
709 SubEvent = NULL;
710 AtaTask = NULL;
711
712 //
713 // Ensure AtaDevice->Lba48Bit is a valid boolean value
714 //
715 ASSERT ((UINTN) AtaDevice->Lba48Bit < 2);
716 MaxTransferBlockNumber = mMaxTransferBlockNumber[AtaDevice->Lba48Bit];
717 BlockSize = AtaDevice->BlockMedia.BlockSize;
718
719 //
720 // Initial the return status and shared account for Non Blocking.
721 //
722 if ((Token != NULL) && (Token->Event != NULL)) {
723 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
724 if (!IsListEmpty (&AtaDevice->AtaSubTaskList)) {
725 AtaTask = AllocateZeroPool (sizeof (ATA_BUS_ASYN_TASK));
726 if (AtaTask == NULL) {
727 gBS->RestoreTPL (OldTpl);
728 return EFI_OUT_OF_RESOURCES;
729 }
730 AtaTask->AtaDevice = AtaDevice;
731 AtaTask->Buffer = Buffer;
732 AtaTask->IsWrite = IsWrite;
733 AtaTask->NumberOfBlocks = NumberOfBlocks;
734 AtaTask->Signature = ATA_TASK_SIGNATURE;
735 AtaTask->StartLba = StartLba;
736 AtaTask->Token = Token;
737
738 InsertTailList (&AtaDevice->AtaTaskList, &AtaTask->TaskEntry);
739 gBS->RestoreTPL (OldTpl);
740 return EFI_SUCCESS;
741 }
742 gBS->RestoreTPL (OldTpl);
743
744 Token->TransactionStatus = EFI_SUCCESS;
745 EventCount = AllocateZeroPool (sizeof (UINTN));
746 if (EventCount == NULL) {
747 return EFI_OUT_OF_RESOURCES;
748 }
749
750 IsError = AllocateZeroPool (sizeof (BOOLEAN));
751 if (IsError == NULL) {
752 FreePool (EventCount);
753 return EFI_OUT_OF_RESOURCES;
754 }
755 DEBUG ((EFI_D_BLKIO, "Allocation IsError Addr=%x\n", IsError));
756 *IsError = FALSE;
757 TempCount = (NumberOfBlocks + MaxTransferBlockNumber - 1) / MaxTransferBlockNumber;
758 *EventCount = TempCount;
759 DEBUG ((EFI_D_BLKIO, "AccessAtaDevice, NumberOfBlocks=%x\n", NumberOfBlocks));
760 DEBUG ((EFI_D_BLKIO, "AccessAtaDevice, MaxTransferBlockNumber=%x\n", MaxTransferBlockNumber));
761 DEBUG ((EFI_D_BLKIO, "AccessAtaDevice, EventCount=%x\n", TempCount));
762 }else {
763 while (!IsListEmpty (&AtaDevice->AtaTaskList) || !IsListEmpty (&AtaDevice->AtaSubTaskList)) {
764 //
765 // Stall for 100us.
766 //
767 MicroSecondDelay (100);
768 }
769 }
770
771 do {
772 if (NumberOfBlocks > MaxTransferBlockNumber) {
773 TransferBlockNumber = MaxTransferBlockNumber;
774 NumberOfBlocks -= MaxTransferBlockNumber;
775 } else {
776 TransferBlockNumber = NumberOfBlocks;
777 NumberOfBlocks = 0;
778 }
779
780 //
781 // Create sub event for the sub ata task. Non-blocking mode.
782 //
783 if ((Token != NULL) && (Token->Event != NULL)) {
784 SubTask = NULL;
785 SubEvent = NULL;
786
787 SubTask = AllocateZeroPool (sizeof (ATA_BUS_ASYN_SUB_TASK));
788 if (SubTask == NULL) {
789 Status = EFI_OUT_OF_RESOURCES;
790 goto EXIT;
791 }
792
793 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
794 SubTask->UnsignalledEventCount = EventCount;
795 SubTask->Signature = ATA_SUB_TASK_SIGNATURE;
796 SubTask->AtaDevice = AtaDevice;
797 SubTask->Token = Token;
798 SubTask->IsError = IsError;
799 InsertTailList (&AtaDevice->AtaSubTaskList, &SubTask->TaskEntry);
800 gBS->RestoreTPL (OldTpl);
801
802 Status = gBS->CreateEvent (
803 EVT_NOTIFY_SIGNAL,
804 TPL_NOTIFY,
805 AtaNonBlockingCallBack,
806 SubTask,
807 &SubEvent
808 );
809 //
810 // If resource allocation fail, the un-signalled event count should equal to
811 // the original one minus the unassigned subtasks number.
812 //
813 if (EFI_ERROR (Status)) {
814 Status = EFI_OUT_OF_RESOURCES;
815 goto EXIT;
816 }
817
818 Status = TransferAtaDevice (AtaDevice, &SubTask->Packet, Buffer, StartLba, (UINT32) TransferBlockNumber, IsWrite, SubEvent);
819 } else {
820 //
821 // Blocking Mode.
822 //
823 DEBUG ((EFI_D_BLKIO, "Blocking AccessAtaDevice, TransferBlockNumber=%x; StartLba = %x\n", TransferBlockNumber, StartLba));
824 Status = TransferAtaDevice (AtaDevice, NULL, Buffer, StartLba, (UINT32) TransferBlockNumber, IsWrite, NULL);
825 }
826
827 if (EFI_ERROR (Status)) {
828 goto EXIT;
829 }
830
831 Index++;
832 StartLba += TransferBlockNumber;
833 Buffer += TransferBlockNumber * BlockSize;
834 } while (NumberOfBlocks > 0);
835
836 EXIT:
837 if ((Token != NULL) && (Token->Event != NULL)) {
838 //
839 // Release resource at non-blocking mode.
840 //
841 if (EFI_ERROR (Status)) {
842 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
843 Token->TransactionStatus = Status;
844 *EventCount = (*EventCount) - (TempCount - Index);
845 *IsError = TRUE;
846
847 if (*EventCount == 0) {
848 FreePool (EventCount);
849 FreePool (IsError);
850 }
851
852 if (SubTask != NULL) {
853 RemoveEntryList (&SubTask->TaskEntry);
854 FreeAtaSubTask (SubTask);
855 }
856
857 if (SubEvent != NULL) {
858 gBS->CloseEvent (SubEvent);
859 }
860 gBS->RestoreTPL (OldTpl);
861 }
862 }
863
864 return Status;
865 }
866
867 /**
868 Trust transfer data from/to ATA device.
869
870 This function performs one ATA pass through transaction to do a trust transfer from/to
871 ATA device. It chooses the appropriate ATA command and protocol to invoke PassThru
872 interface of ATA pass through.
873
874 @param AtaDevice The ATA child device involved for the operation.
875 @param Buffer The pointer to the current transaction buffer.
876 @param SecurityProtocolId The value of the "Security Protocol" parameter of
877 the security protocol command to be sent.
878 @param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter
879 of the security protocol command to be sent.
880 @param TransferLength The block number or sector count of the transfer.
881 @param IsTrustSend Indicates whether it is a trust send operation or not.
882 @param Timeout The timeout, in 100ns units, to use for the execution
883 of the security protocol command. A Timeout value of 0
884 means that this function will wait indefinitely for the
885 security protocol command to execute. If Timeout is greater
886 than zero, then this function will return EFI_TIMEOUT
887 if the time required to execute the receive data command
888 is greater than Timeout.
889 @param TransferLengthOut A pointer to a buffer to store the size in bytes of the data
890 written to the buffer. Ignore it when IsTrustSend is TRUE.
891
892 @retval EFI_SUCCESS The data transfer is complete successfully.
893 @return others Some error occurs when transferring data.
894
895 **/
896 EFI_STATUS
897 EFIAPI
898 TrustTransferAtaDevice (
899 IN OUT ATA_DEVICE *AtaDevice,
900 IN OUT VOID *Buffer,
901 IN UINT8 SecurityProtocolId,
902 IN UINT16 SecurityProtocolSpecificData,
903 IN UINTN TransferLength,
904 IN BOOLEAN IsTrustSend,
905 IN UINT64 Timeout,
906 OUT UINTN *TransferLengthOut
907 )
908 {
909 EFI_ATA_COMMAND_BLOCK *Acb;
910 EFI_ATA_PASS_THRU_COMMAND_PACKET *Packet;
911 EFI_STATUS Status;
912 VOID *NewBuffer;
913 EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru;
914
915 //
916 // Ensure AtaDevice->UdmaValid and IsTrustSend are valid boolean values
917 //
918 ASSERT ((UINTN) AtaDevice->UdmaValid < 2);
919 ASSERT ((UINTN) IsTrustSend < 2);
920 //
921 // Prepare for ATA command block.
922 //
923 Acb = ZeroMem (&AtaDevice->Acb, sizeof (EFI_ATA_COMMAND_BLOCK));
924 if (TransferLength == 0) {
925 Acb->AtaCommand = ATA_CMD_TRUST_NON_DATA;
926 } else {
927 Acb->AtaCommand = mAtaTrustCommands[AtaDevice->UdmaValid][IsTrustSend];
928 }
929 Acb->AtaFeatures = SecurityProtocolId;
930 Acb->AtaSectorCount = (UINT8) (TransferLength / 512);
931 Acb->AtaSectorNumber = (UINT8) ((TransferLength / 512) >> 8);
932 //
933 // NOTE: ATA Spec has no explicitly definition for Security Protocol Specific layout.
934 // Here use big endian for Cylinder register.
935 //
936 Acb->AtaCylinderHigh = (UINT8) SecurityProtocolSpecificData;
937 Acb->AtaCylinderLow = (UINT8) (SecurityProtocolSpecificData >> 8);
938 Acb->AtaDeviceHead = (UINT8) (BIT7 | BIT6 | BIT5 | (AtaDevice->PortMultiplierPort << 4));
939
940 //
941 // Prepare for ATA pass through packet.
942 //
943 Packet = ZeroMem (&AtaDevice->Packet, sizeof (EFI_ATA_PASS_THRU_COMMAND_PACKET));
944 if (TransferLength == 0) {
945 Packet->InTransferLength = 0;
946 Packet->OutTransferLength = 0;
947 Packet->Protocol = EFI_ATA_PASS_THRU_PROTOCOL_ATA_NON_DATA;
948 } else if (IsTrustSend) {
949 //
950 // Check the alignment of the incoming buffer prior to invoking underlying ATA PassThru
951 //
952 AtaPassThru = AtaDevice->AtaBusDriverData->AtaPassThru;
953 if ((AtaPassThru->Mode->IoAlign > 1) && !IS_ALIGNED (Buffer, AtaPassThru->Mode->IoAlign)) {
954 NewBuffer = AllocateAlignedBuffer (AtaDevice, TransferLength);
955 if (NewBuffer == NULL) {
956 return EFI_OUT_OF_RESOURCES;
957 }
958
959 CopyMem (NewBuffer, Buffer, TransferLength);
960 FreePool (Buffer);
961 Buffer = NewBuffer;
962 }
963 Packet->OutDataBuffer = Buffer;
964 Packet->OutTransferLength = (UINT32) TransferLength;
965 Packet->Protocol = mAtaPassThruCmdProtocols[AtaDevice->UdmaValid][IsTrustSend];
966 } else {
967 Packet->InDataBuffer = Buffer;
968 Packet->InTransferLength = (UINT32) TransferLength;
969 Packet->Protocol = mAtaPassThruCmdProtocols[AtaDevice->UdmaValid][IsTrustSend];
970 }
971 Packet->Length = EFI_ATA_PASS_THRU_LENGTH_BYTES;
972 Packet->Timeout = Timeout;
973
974 Status = AtaDevicePassThru (AtaDevice, NULL, NULL);
975 if (TransferLengthOut != NULL) {
976 if (! IsTrustSend) {
977 *TransferLengthOut = Packet->InTransferLength;
978 }
979 }
980 return Status;
981 }