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