]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Bus/Ata/AtaBusDxe/AtaPassThruExecute.c
Update the function's descriptions (which is in AtaBus, AtaAtapiPassThru, Partition...
[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 aslo 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 edian for
11 Cylinder register.
12
13 Copyright (c) 2009 - 2011, 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 (*AtaDevice->Asb));
136 CopyMem (Packet->Asb, AtaDevice->Asb, sizeof (*AtaDevice->Asb));
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 (%x %x)\n", (UINTN)AtaDevice->Port, (UINTN)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 (*Acb));
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 (*Packet));
409 Packet->InDataBuffer = AtaDevice->IdentifyData;
410 Packet->InTransferLength = sizeof (*AtaDevice->IdentifyData);
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 (*Acb));
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 (*Packet));
502 } else {
503 Packet = ZeroMem (&AtaDevice->Packet, sizeof (*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_TASK *Task
531 )
532 {
533 if (Task->Packet.Asb != NULL) {
534 FreeAlignedBuffer (Task->Packet.Asb, sizeof (Task->Packet.Asb));
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 registerd 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_TASK *Task;
559
560 Task = (ATA_BUS_ASYN_TASK *) Context;
561 gBS->CloseEvent (Event);
562
563 //
564 // Check the command status.
565 // If there is error during the sub task source allocation, the error status
566 // should be returned to the caller directly, so here the Task->Token may already
567 // be deleted by the caller and no need to update the status.
568 //
569 if ((!(*Task->IsError)) && (Task->Packet.Asb->AtaStatus & 0x01) == 0x01) {
570 Task->Token->TransactionStatus = EFI_DEVICE_ERROR;
571 }
572 DEBUG ((
573 DEBUG_INFO,
574 "NON-BLOCKING EVENT FINISHED!- STATUS = %r\n",
575 Task->Token->TransactionStatus
576 ));
577
578 //
579 // Reduce the SubEventCount, till it comes to zero.
580 //
581 (*Task->UnsignalledEventCount) --;
582 DEBUG ((DEBUG_INFO, "UnsignalledEventCount = %x\n", *Task->UnsignalledEventCount));
583
584 //
585 // Remove the SubTask from the Task list.
586 //
587 RemoveEntryList (&Task->TaskEntry);
588 if ((*Task->UnsignalledEventCount) == 0) {
589 //
590 // All Sub tasks are done, then signal the upper layyer event.
591 // Except there is error during the sub task source allocation.
592 //
593 if (!(*Task->IsError)) {
594 gBS->SignalEvent (Task->Token->Event);
595 DEBUG ((DEBUG_INFO, "Signal Up Level Event UnsignalledEventCount = %x!\n", *Task->UnsignalledEventCount));
596 }
597
598 FreePool (Task->UnsignalledEventCount);
599 FreePool (Task->IsError);
600 }
601
602 DEBUG ((
603 DEBUG_INFO,
604 "PACKET INFO: Write=%s, Lenght=%x, LowCylinder=%x, HighCylinder=%x,SectionNumber=%x",
605 Task->Packet.OutDataBuffer != NULL ? L"YES" : L"NO",
606 Task->Packet.OutDataBuffer != NULL ? Task->Packet.OutTransferLength : Task->Packet.InTransferLength,
607 Task->Packet.Acb->AtaCylinderLow,
608 Task->Packet.Acb->AtaCylinderHigh,
609 Task->Packet.Acb->AtaSectorCount
610 ));
611
612 //
613 // Free the buffer of SubTask.
614 //
615 FreeAtaSubTask (Task);
616 }
617
618 /**
619 Read or write a number of blocks from ATA device.
620
621 This function performs ATA pass through transactions to read/write data from/to
622 ATA device. It may separate the read/write request into several ATA pass through
623 transactions.
624
625 @param[in, out] AtaDevice The ATA child device involved for the operation.
626 @param[in, out] Buffer The pointer to the current transaction buffer.
627 @param[in] StartLba The starting logical block address to be accessed.
628 @param[in] NumberOfBlocks The block number or sector count of the transfer.
629 @param[in] IsWrite Indicates whether it is a write operation.
630 @param[in, out] Token A pointer to the token associated with the transaction.
631
632 @retval EFI_SUCCESS The data transfer is complete successfully.
633 @return others Some error occurs when transferring data.
634
635 **/
636 EFI_STATUS
637 AccessAtaDevice(
638 IN OUT ATA_DEVICE *AtaDevice,
639 IN OUT UINT8 *Buffer,
640 IN EFI_LBA StartLba,
641 IN UINTN NumberOfBlocks,
642 IN BOOLEAN IsWrite,
643 IN OUT EFI_BLOCK_IO2_TOKEN *Token
644 )
645 {
646 EFI_STATUS Status;
647 UINTN MaxTransferBlockNumber;
648 UINTN TransferBlockNumber;
649 UINTN BlockSize;
650 UINTN *EventCount;
651 UINTN TempCount;
652 ATA_BUS_ASYN_TASK *Task;
653 EFI_EVENT SubEvent;
654 UINTN Index;
655 BOOLEAN *IsError;
656 EFI_TPL OldTpl;
657
658 SubEvent = NULL;
659 TempCount = 0;
660 Status = EFI_SUCCESS;
661
662 EventCount = AllocateZeroPool (sizeof (UINTN));
663 if (EventCount == NULL) {
664 return EFI_OUT_OF_RESOURCES;
665 }
666
667 IsError = AllocateZeroPool (sizeof (BOOLEAN));
668 if (IsError == NULL) {
669 goto EXIT;
670 }
671 *IsError = FALSE;
672
673 //
674 // Initial the return status for Non Blocking.
675 //
676 if (Token != NULL && Token->Event != NULL) {
677 Token->TransactionStatus = EFI_SUCCESS;
678 }
679 //
680 // Ensure AtaDevice->Lba48Bit is a valid boolean value
681 //
682 ASSERT ((UINTN) AtaDevice->Lba48Bit < 2);
683 MaxTransferBlockNumber = mMaxTransferBlockNumber[AtaDevice->Lba48Bit];
684 BlockSize = AtaDevice->BlockMedia.BlockSize;
685
686 TempCount = (NumberOfBlocks + MaxTransferBlockNumber - 1) / MaxTransferBlockNumber;
687 *EventCount = TempCount;
688 Index = 0;
689
690 do {
691 if (NumberOfBlocks > MaxTransferBlockNumber) {
692 TransferBlockNumber = MaxTransferBlockNumber;
693 NumberOfBlocks -= MaxTransferBlockNumber;
694 } else {
695 TransferBlockNumber = NumberOfBlocks;
696 NumberOfBlocks = 0;
697 }
698
699 //
700 // Create sub event for the sub Ata task. Non-Blocking Mode.
701 //
702 if (Token != NULL && Token->Event != NULL) {
703 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
704 Task = AllocateZeroPool (sizeof (ATA_BUS_ASYN_TASK));
705 if (Task == NULL) {
706 //
707 // If resource allocation fail, reduce the total sub event counts.
708 //
709 *EventCount = (*EventCount) - (TempCount - Index);
710 *IsError = TRUE;
711 Token->TransactionStatus = EFI_OUT_OF_RESOURCES;
712 Status = EFI_OUT_OF_RESOURCES;
713
714 gBS->RestoreTPL (OldTpl);
715 goto EXIT;
716 }
717
718 Task->UnsignalledEventCount = EventCount;
719 Task->Token = Token;
720 Task->IsError = IsError;
721
722 InsertTailList (&AtaDevice->AtaTaskList, &Task->TaskEntry);
723
724 Status = gBS->CreateEvent (
725 EVT_NOTIFY_SIGNAL,
726 TPL_NOTIFY,
727 AtaNonBlockingCallBack,
728 Task,
729 &SubEvent
730 );
731 //
732 // If resource allocation fail, the un-signalled event count should equal to
733 // the original one minus the unassigned subtasks number.
734 //
735 if (EFI_ERROR (Status)) {
736 *EventCount = (*EventCount) - (TempCount - Index);
737 *IsError = TRUE;
738 gBS->RestoreTPL (OldTpl);
739 goto EXIT;
740 }
741 Index++;
742 gBS->RestoreTPL (OldTpl);
743
744 DEBUG ((EFI_D_INFO, "NON-BLOCKING SET EVENT START: WRITE = %d\n", IsWrite));
745 Status = TransferAtaDevice (AtaDevice, &Task->Packet, Buffer, StartLba, (UINT32) TransferBlockNumber, IsWrite, SubEvent);
746 DEBUG ((
747 EFI_D_INFO,
748 "NON-BLOCKING SET EVENT END:StartLba=%x, TransferBlockNumbers=%x, Status=%r\n",
749 StartLba,
750 TransferBlockNumber,
751 Status
752 ));
753 }else {
754 //
755 // Blocking Mode.
756 //
757 DEBUG ((EFI_D_INFO, "BLOCKING BLOCK I/O START: WRITE = %d\n", IsWrite));
758 Status = TransferAtaDevice (AtaDevice, NULL, Buffer, StartLba, (UINT32) TransferBlockNumber, IsWrite, NULL);
759 DEBUG ((
760 EFI_D_INFO,
761 "BLOCKING BLOCK I/O FINISHE - StartLba = %x; TransferBlockNumbers = %x, status = %r\n",
762 StartLba,
763 TransferBlockNumber,
764 Status
765 ));
766 }
767
768 if (EFI_ERROR (Status)) {
769 goto EXIT;
770 }
771
772 StartLba += TransferBlockNumber;
773 Buffer += TransferBlockNumber * BlockSize;
774 } while (NumberOfBlocks > 0);
775
776 EXIT:
777
778 if (*EventCount == 0) {
779 FreePool (EventCount);
780 FreePool (IsError);
781 }
782
783 return Status;
784 }
785
786 /**
787 Trust transfer data from/to ATA device.
788
789 This function performs one ATA pass through transaction to do a trust transfer from/to
790 ATA device. It chooses the appropriate ATA command and protocol to invoke PassThru
791 interface of ATA pass through.
792
793 @param AtaDevice The ATA child device involved for the operation.
794 @param Buffer The pointer to the current transaction buffer.
795 @param SecurityProtocolId The value of the "Security Protocol" parameter of
796 the security protocol command to be sent.
797 @param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter
798 of the security protocol command to be sent.
799 @param TransferLength The block number or sector count of the transfer.
800 @param IsTrustSend Indicates whether it is a trust send operation or not.
801 @param Timeout The timeout, in 100ns units, to use for the execution
802 of the security protocol command. A Timeout value of 0
803 means that this function will wait indefinitely for the
804 security protocol command to execute. If Timeout is greater
805 than zero, then this function will return EFI_TIMEOUT
806 if the time required to execute the receive data command
807 is greater than Timeout.
808 @param TransferLengthOut A pointer to a buffer to store the size in bytes of the data
809 written to the buffer. Ignore it when IsTrustSend is TRUE.
810
811 @retval EFI_SUCCESS The data transfer is complete successfully.
812 @return others Some error occurs when transferring data.
813
814 **/
815 EFI_STATUS
816 EFIAPI
817 TrustTransferAtaDevice (
818 IN OUT ATA_DEVICE *AtaDevice,
819 IN OUT VOID *Buffer,
820 IN UINT8 SecurityProtocolId,
821 IN UINT16 SecurityProtocolSpecificData,
822 IN UINTN TransferLength,
823 IN BOOLEAN IsTrustSend,
824 IN UINT64 Timeout,
825 OUT UINTN *TransferLengthOut
826 )
827 {
828 EFI_ATA_COMMAND_BLOCK *Acb;
829 EFI_ATA_PASS_THRU_COMMAND_PACKET *Packet;
830 EFI_STATUS Status;
831 VOID *NewBuffer;
832 EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru;
833
834 //
835 // Ensure AtaDevice->UdmaValid and IsTrustSend are valid boolean values
836 //
837 ASSERT ((UINTN) AtaDevice->UdmaValid < 2);
838 ASSERT ((UINTN) IsTrustSend < 2);
839 //
840 // Prepare for ATA command block.
841 //
842 Acb = ZeroMem (&AtaDevice->Acb, sizeof (*Acb));
843 if (TransferLength == 0) {
844 Acb->AtaCommand = ATA_CMD_TRUST_NON_DATA;
845 } else {
846 Acb->AtaCommand = mAtaTrustCommands[AtaDevice->UdmaValid][IsTrustSend];
847 }
848 Acb->AtaFeatures = SecurityProtocolId;
849 Acb->AtaSectorCount = (UINT8) (TransferLength / 512);
850 Acb->AtaSectorNumber = (UINT8) ((TransferLength / 512) >> 8);
851 //
852 // NOTE: ATA Spec has no explicitly definition for Security Protocol Specific layout.
853 // Here use big edian for Cylinder register.
854 //
855 Acb->AtaCylinderHigh = (UINT8) SecurityProtocolSpecificData;
856 Acb->AtaCylinderLow = (UINT8) (SecurityProtocolSpecificData >> 8);
857 Acb->AtaDeviceHead = (UINT8) (BIT7 | BIT6 | BIT5 | (AtaDevice->PortMultiplierPort << 4));
858
859 //
860 // Prepare for ATA pass through packet.
861 //
862 Packet = ZeroMem (&AtaDevice->Packet, sizeof (*Packet));
863 if (TransferLength == 0) {
864 Packet->InTransferLength = 0;
865 Packet->OutTransferLength = 0;
866 Packet->Protocol = EFI_ATA_PASS_THRU_PROTOCOL_ATA_NON_DATA;
867 } else if (IsTrustSend) {
868 //
869 // Check the alignment of the incoming buffer prior to invoking underlying ATA PassThru
870 //
871 AtaPassThru = AtaDevice->AtaBusDriverData->AtaPassThru;
872 if ((AtaPassThru->Mode->IoAlign > 1) && !IS_ALIGNED (Buffer, AtaPassThru->Mode->IoAlign)) {
873 NewBuffer = AllocateAlignedBuffer (AtaDevice, TransferLength);
874 CopyMem (NewBuffer, Buffer, TransferLength);
875 FreePool (Buffer);
876 Buffer = NewBuffer;
877 }
878 Packet->OutDataBuffer = Buffer;
879 Packet->OutTransferLength = (UINT32) TransferLength;
880 Packet->Protocol = mAtaPassThruCmdProtocols[AtaDevice->UdmaValid][IsTrustSend];
881 } else {
882 Packet->InDataBuffer = Buffer;
883 Packet->InTransferLength = (UINT32) TransferLength;
884 Packet->Protocol = mAtaPassThruCmdProtocols[AtaDevice->UdmaValid][IsTrustSend];
885 }
886 Packet->Length = EFI_ATA_PASS_THRU_LENGTH_BYTES;
887 Packet->Timeout = Timeout;
888
889 Status = AtaDevicePassThru (AtaDevice, NULL, NULL);
890 if (TransferLengthOut != NULL) {
891 if (! IsTrustSend) {
892 *TransferLengthOut = Packet->InTransferLength;
893 }
894 }
895 return Status;
896 }