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