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