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