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