]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Bus/Pci/IdeBusPei/AtapiPeim.c
MdeModulePkg: Change use of EFI_D_* to DEBUG_*
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / IdeBusPei / AtapiPeim.c
1 /** @file
2 PEIM to produce gEfiPeiVirtualBlockIoPpiGuid & gEfiPeiVirtualBlockIo2PpiGuid PPI for
3 ATA controllers in the platform.
4
5 This PPI can be consumed by PEIM which produce gEfiPeiDeviceRecoveryModulePpiGuid
6 for Atapi CD ROM device.
7
8 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
9
10 SPDX-License-Identifier: BSD-2-Clause-Patent
11
12 **/
13
14 #include "AtapiPeim.h"
15
16 /**
17 Initializes the Atapi Block Io PPI.
18
19 @param[in] FileHandle Handle of the file being invoked.
20 @param[in] PeiServices Describes the list of possible PEI Services.
21
22 @retval EFI_SUCCESS Operation performed successfully.
23 @retval EFI_OUT_OF_RESOURCES Not enough memory to allocate.
24
25 **/
26 EFI_STATUS
27 EFIAPI
28 AtapiPeimEntry (
29 IN EFI_PEI_FILE_HANDLE FileHandle,
30 IN CONST EFI_PEI_SERVICES **PeiServices
31 )
32 {
33 PEI_ATA_CONTROLLER_PPI *AtaControllerPpi;
34 EFI_STATUS Status;
35 ATAPI_BLK_IO_DEV *AtapiBlkIoDev;
36
37 Status = PeiServicesRegisterForShadow (FileHandle);
38 if (!EFI_ERROR (Status)) {
39 return Status;
40 }
41
42 Status = PeiServicesLocatePpi (
43 &gPeiAtaControllerPpiGuid,
44 0,
45 NULL,
46 (VOID **) &AtaControllerPpi
47 );
48 ASSERT_EFI_ERROR (Status);
49
50 AtapiBlkIoDev = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (*AtapiBlkIoDev)));
51 if (AtapiBlkIoDev == NULL) {
52 return EFI_OUT_OF_RESOURCES;
53 }
54
55 AtapiBlkIoDev->Signature = ATAPI_BLK_IO_DEV_SIGNATURE;
56 AtapiBlkIoDev->AtaControllerPpi = AtaControllerPpi;
57
58 //
59 // atapi device enumeration and build private data
60 //
61 AtapiEnumerateDevices (AtapiBlkIoDev);
62
63 AtapiBlkIoDev->AtapiBlkIo.GetNumberOfBlockDevices = AtapiGetNumberOfBlockDevices;
64 AtapiBlkIoDev->AtapiBlkIo.GetBlockDeviceMediaInfo = AtapiGetBlockDeviceMediaInfo;
65 AtapiBlkIoDev->AtapiBlkIo.ReadBlocks = AtapiReadBlocks;
66 AtapiBlkIoDev->AtapiBlkIo2.Revision = EFI_PEI_RECOVERY_BLOCK_IO2_PPI_REVISION;
67 AtapiBlkIoDev->AtapiBlkIo2.GetNumberOfBlockDevices = AtapiGetNumberOfBlockDevices2;
68 AtapiBlkIoDev->AtapiBlkIo2.GetBlockDeviceMediaInfo = AtapiGetBlockDeviceMediaInfo2;
69 AtapiBlkIoDev->AtapiBlkIo2.ReadBlocks = AtapiReadBlocks2;
70
71 AtapiBlkIoDev->PpiDescriptor.Flags = EFI_PEI_PPI_DESCRIPTOR_PPI;
72 AtapiBlkIoDev->PpiDescriptor.Guid = &gEfiPeiVirtualBlockIoPpiGuid;
73 AtapiBlkIoDev->PpiDescriptor.Ppi = &AtapiBlkIoDev->AtapiBlkIo;
74
75 AtapiBlkIoDev->PpiDescriptor2.Flags = (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
76 AtapiBlkIoDev->PpiDescriptor2.Guid = &gEfiPeiVirtualBlockIo2PpiGuid;
77 AtapiBlkIoDev->PpiDescriptor2.Ppi = &AtapiBlkIoDev->AtapiBlkIo2;
78
79 DEBUG ((DEBUG_INFO, "Atatpi Device Count is %d\n", AtapiBlkIoDev->DeviceCount));
80 if (AtapiBlkIoDev->DeviceCount != 0) {
81 Status = PeiServicesInstallPpi (&AtapiBlkIoDev->PpiDescriptor);
82 if (EFI_ERROR (Status)) {
83 return EFI_OUT_OF_RESOURCES;
84 }
85 }
86
87 return EFI_SUCCESS;
88 }
89
90 /**
91 Gets the count of block I/O devices that one specific block driver detects.
92
93 This function is used for getting the count of block I/O devices that one
94 specific block driver detects. To the PEI ATAPI driver, it returns the number
95 of all the detected ATAPI devices it detects during the enumeration process.
96 To the PEI legacy floppy driver, it returns the number of all the legacy
97 devices it finds during its enumeration process. If no device is detected,
98 then the function will return zero.
99
100 @param[in] PeiServices General-purpose services that are available
101 to every PEIM.
102 @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI
103 instance.
104 @param[out] NumberBlockDevices The number of block I/O devices discovered.
105
106 @retval EFI_SUCCESS Operation performed successfully.
107
108 **/
109 EFI_STATUS
110 EFIAPI
111 AtapiGetNumberOfBlockDevices (
112 IN EFI_PEI_SERVICES **PeiServices,
113 IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
114 OUT UINTN *NumberBlockDevices
115 )
116 {
117 ATAPI_BLK_IO_DEV *AtapiBlkIoDev;
118
119 AtapiBlkIoDev = NULL;
120
121 AtapiBlkIoDev = PEI_RECOVERY_ATAPI_FROM_BLKIO_THIS (This);
122
123 *NumberBlockDevices = AtapiBlkIoDev->DeviceCount;
124
125 return EFI_SUCCESS;
126 }
127
128 /**
129 Gets a block device's media information.
130
131 This function will provide the caller with the specified block device's media
132 information. If the media changes, calling this function will update the media
133 information accordingly.
134
135 @param[in] PeiServices General-purpose services that are available to every
136 PEIM
137 @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI instance.
138 @param[in] DeviceIndex Specifies the block device to which the function wants
139 to talk. Because the driver that implements Block I/O
140 PPIs will manage multiple block devices, the PPIs that
141 want to talk to a single device must specify the
142 device index that was assigned during the enumeration
143 process. This index is a number from one to
144 NumberBlockDevices.
145 @param[out] MediaInfo The media information of the specified block media.
146 The caller is responsible for the ownership of this
147 data structure.
148
149 @retval EFI_SUCCESS Media information about the specified block device
150 was obtained successfully.
151 @retval EFI_DEVICE_ERROR Cannot get the media information due to a hardware
152 error.
153 @retval Others Other failure occurs.
154
155 **/
156 EFI_STATUS
157 EFIAPI
158 AtapiGetBlockDeviceMediaInfo (
159 IN EFI_PEI_SERVICES **PeiServices,
160 IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
161 IN UINTN DeviceIndex,
162 OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo
163 )
164 {
165 UINTN DeviceCount;
166 ATAPI_BLK_IO_DEV *AtapiBlkIoDev;
167 EFI_STATUS Status;
168 UINTN Index;
169
170 AtapiBlkIoDev = NULL;
171
172 if (This == NULL || MediaInfo == NULL) {
173 return EFI_INVALID_PARAMETER;
174 }
175
176 AtapiBlkIoDev = PEI_RECOVERY_ATAPI_FROM_BLKIO_THIS (This);
177
178 DeviceCount = AtapiBlkIoDev->DeviceCount;
179
180 //
181 // DeviceIndex is a value from 1 to NumberBlockDevices.
182 //
183 if ((DeviceIndex < 1) || (DeviceIndex > DeviceCount) || (DeviceIndex > MAX_IDE_DEVICES)) {
184 return EFI_INVALID_PARAMETER;
185 }
186
187 Index = DeviceIndex - 1;
188
189 //
190 // probe media and retrieve latest media information
191 //
192 DEBUG ((DEBUG_INFO, "Atatpi GetInfo DevicePosition is %d\n", AtapiBlkIoDev->DeviceInfo[Index].DevicePosition));
193 DEBUG ((DEBUG_INFO, "Atatpi GetInfo DeviceType is %d\n", AtapiBlkIoDev->DeviceInfo[Index].MediaInfo.DeviceType));
194 DEBUG ((DEBUG_INFO, "Atatpi GetInfo MediaPresent is %d\n", AtapiBlkIoDev->DeviceInfo[Index].MediaInfo.MediaPresent));
195 DEBUG ((DEBUG_INFO, "Atatpi GetInfo BlockSize is 0x%x\n", AtapiBlkIoDev->DeviceInfo[Index].MediaInfo.BlockSize));
196 DEBUG ((DEBUG_INFO, "Atatpi GetInfo LastBlock is 0x%x\n", AtapiBlkIoDev->DeviceInfo[Index].MediaInfo.LastBlock));
197
198 Status = DetectMedia (
199 AtapiBlkIoDev,
200 AtapiBlkIoDev->DeviceInfo[Index].DevicePosition,
201 &AtapiBlkIoDev->DeviceInfo[Index].MediaInfo,
202 &AtapiBlkIoDev->DeviceInfo[Index].MediaInfo2
203 );
204 if (Status != EFI_SUCCESS) {
205 return EFI_DEVICE_ERROR;
206 }
207
208 DEBUG ((DEBUG_INFO, "Atatpi GetInfo DevicePosition is %d\n", AtapiBlkIoDev->DeviceInfo[Index].DevicePosition));
209 DEBUG ((DEBUG_INFO, "Atatpi GetInfo DeviceType is %d\n", AtapiBlkIoDev->DeviceInfo[Index].MediaInfo.DeviceType));
210 DEBUG ((DEBUG_INFO, "Atatpi GetInfo MediaPresent is %d\n", AtapiBlkIoDev->DeviceInfo[Index].MediaInfo.MediaPresent));
211 DEBUG ((DEBUG_INFO, "Atatpi GetInfo BlockSize is 0x%x\n", AtapiBlkIoDev->DeviceInfo[Index].MediaInfo.BlockSize));
212 DEBUG ((DEBUG_INFO, "Atatpi GetInfo LastBlock is 0x%x\n", AtapiBlkIoDev->DeviceInfo[Index].MediaInfo.LastBlock));
213
214 //
215 // Get media info from AtapiBlkIoDev
216 //
217 CopyMem (MediaInfo, &AtapiBlkIoDev->DeviceInfo[Index].MediaInfo, sizeof(EFI_PEI_BLOCK_IO_MEDIA));
218
219 return EFI_SUCCESS;
220 }
221
222 /**
223 Reads the requested number of blocks from the specified block device.
224
225 The function reads the requested number of blocks from the device. All the
226 blocks are read, or an error is returned. If there is no media in the device,
227 the function returns EFI_NO_MEDIA.
228
229 @param[in] PeiServices General-purpose services that are available to
230 every PEIM.
231 @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI instance.
232 @param[in] DeviceIndex Specifies the block device to which the function wants
233 to talk. Because the driver that implements Block I/O
234 PPIs will manage multiple block devices, the PPIs that
235 want to talk to a single device must specify the device
236 index that was assigned during the enumeration process.
237 This index is a number from one to NumberBlockDevices.
238 @param[in] StartLBA The starting logical block address (LBA) to read from
239 on the device
240 @param[in] BufferSize The size of the Buffer in bytes. This number must be
241 a multiple of the intrinsic block size of the device.
242 @param[out] Buffer A pointer to the destination buffer for the data.
243 The caller is responsible for the ownership of the
244 buffer.
245
246 @retval EFI_SUCCESS The data was read correctly from the device.
247 @retval EFI_DEVICE_ERROR The device reported an error while attempting
248 to perform the read operation.
249 @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not
250 valid, or the buffer is not properly aligned.
251 @retval EFI_NO_MEDIA There is no media in the device.
252 @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of
253 the intrinsic block size of the device.
254
255 **/
256 EFI_STATUS
257 EFIAPI
258 AtapiReadBlocks (
259 IN EFI_PEI_SERVICES **PeiServices,
260 IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
261 IN UINTN DeviceIndex,
262 IN EFI_PEI_LBA StartLBA,
263 IN UINTN BufferSize,
264 OUT VOID *Buffer
265 )
266 {
267
268 EFI_PEI_BLOCK_IO_MEDIA MediaInfo;
269 EFI_STATUS Status;
270 UINTN NumberOfBlocks;
271 UINTN BlockSize;
272 ATAPI_BLK_IO_DEV *AtapiBlkIoDev;
273
274 AtapiBlkIoDev = NULL;
275
276 if (This == NULL) {
277 return EFI_INVALID_PARAMETER;
278 }
279
280 AtapiBlkIoDev = PEI_RECOVERY_ATAPI_FROM_BLKIO_THIS (This);
281
282 if (Buffer == NULL) {
283 return EFI_INVALID_PARAMETER;
284 }
285
286 if (BufferSize == 0) {
287 return EFI_SUCCESS;
288 }
289
290 Status = AtapiGetBlockDeviceMediaInfo (
291 PeiServices,
292 This,
293 DeviceIndex,
294 &MediaInfo
295 );
296 if (Status != EFI_SUCCESS) {
297 return EFI_DEVICE_ERROR;
298 }
299
300 if (!MediaInfo.MediaPresent) {
301 return EFI_NO_MEDIA;
302 }
303
304 BlockSize = MediaInfo.BlockSize;
305
306 if (BufferSize % BlockSize != 0) {
307 return EFI_BAD_BUFFER_SIZE;
308 }
309
310 NumberOfBlocks = BufferSize / BlockSize;
311
312 if ((StartLBA + NumberOfBlocks - 1) > AtapiBlkIoDev->DeviceInfo[DeviceIndex - 1].MediaInfo2.LastBlock) {
313 return EFI_INVALID_PARAMETER;
314 }
315
316 Status = ReadSectors (
317 AtapiBlkIoDev,
318 AtapiBlkIoDev->DeviceInfo[DeviceIndex - 1].DevicePosition,
319 Buffer,
320 StartLBA,
321 NumberOfBlocks,
322 BlockSize
323 );
324 if (EFI_ERROR (Status)) {
325 return EFI_DEVICE_ERROR;
326 }
327
328 return EFI_SUCCESS;
329 }
330
331 /**
332 Gets the count of block I/O devices that one specific block driver detects.
333
334 This function is used for getting the count of block I/O devices that one
335 specific block driver detects. To the PEI ATAPI driver, it returns the number
336 of all the detected ATAPI devices it detects during the enumeration process.
337 To the PEI legacy floppy driver, it returns the number of all the legacy
338 devices it finds during its enumeration process. If no device is detected,
339 then the function will return zero.
340
341 @param[in] PeiServices General-purpose services that are available
342 to every PEIM.
343 @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI
344 instance.
345 @param[out] NumberBlockDevices The number of block I/O devices discovered.
346
347 @retval EFI_SUCCESS Operation performed successfully.
348
349 **/
350 EFI_STATUS
351 EFIAPI
352 AtapiGetNumberOfBlockDevices2 (
353 IN EFI_PEI_SERVICES **PeiServices,
354 IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This,
355 OUT UINTN *NumberBlockDevices
356 )
357 {
358 EFI_STATUS Status;
359 ATAPI_BLK_IO_DEV *AtapiBlkIoDev;
360
361 AtapiBlkIoDev = PEI_RECOVERY_ATAPI_FROM_BLKIO2_THIS (This);
362
363 Status = AtapiGetNumberOfBlockDevices (
364 PeiServices,
365 &AtapiBlkIoDev->AtapiBlkIo,
366 NumberBlockDevices
367 );
368
369 return Status;
370 }
371
372 /**
373 Gets a block device's media information.
374
375 This function will provide the caller with the specified block device's media
376 information. If the media changes, calling this function will update the media
377 information accordingly.
378
379 @param[in] PeiServices General-purpose services that are available to every
380 PEIM
381 @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI instance.
382 @param[in] DeviceIndex Specifies the block device to which the function wants
383 to talk. Because the driver that implements Block I/O
384 PPIs will manage multiple block devices, the PPIs that
385 want to talk to a single device must specify the
386 device index that was assigned during the enumeration
387 process. This index is a number from one to
388 NumberBlockDevices.
389 @param[out] MediaInfo The media information of the specified block media.
390 The caller is responsible for the ownership of this
391 data structure.
392
393 @retval EFI_SUCCESS Media information about the specified block device
394 was obtained successfully.
395 @retval EFI_DEVICE_ERROR Cannot get the media information due to a hardware
396 error.
397 @retval Others Other failure occurs.
398
399 **/
400 EFI_STATUS
401 EFIAPI
402 AtapiGetBlockDeviceMediaInfo2 (
403 IN EFI_PEI_SERVICES **PeiServices,
404 IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This,
405 IN UINTN DeviceIndex,
406 OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo
407 )
408 {
409 ATAPI_BLK_IO_DEV *AtapiBlkIoDev;
410 EFI_STATUS Status;
411 EFI_PEI_BLOCK_IO_MEDIA Media;
412
413 AtapiBlkIoDev = NULL;
414
415 if (This == NULL || MediaInfo == NULL) {
416 return EFI_INVALID_PARAMETER;
417 }
418
419 AtapiBlkIoDev = PEI_RECOVERY_ATAPI_FROM_BLKIO2_THIS (This);
420
421 Status = AtapiGetBlockDeviceMediaInfo (
422 PeiServices,
423 &AtapiBlkIoDev->AtapiBlkIo,
424 DeviceIndex,
425 &Media
426 );
427 if (EFI_ERROR (Status)) {
428 return Status;
429 }
430 //
431 // Get media info from AtapiBlkIoDev
432 //
433 CopyMem (MediaInfo, &AtapiBlkIoDev->DeviceInfo[DeviceIndex - 1].MediaInfo2, sizeof(EFI_PEI_BLOCK_IO2_MEDIA));
434
435 return EFI_SUCCESS;
436 }
437
438 /**
439 Reads the requested number of blocks from the specified block device.
440
441 The function reads the requested number of blocks from the device. All the
442 blocks are read, or an error is returned. If there is no media in the device,
443 the function returns EFI_NO_MEDIA.
444
445 @param[in] PeiServices General-purpose services that are available to
446 every PEIM.
447 @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI instance.
448 @param[in] DeviceIndex Specifies the block device to which the function wants
449 to talk. Because the driver that implements Block I/O
450 PPIs will manage multiple block devices, the PPIs that
451 want to talk to a single device must specify the device
452 index that was assigned during the enumeration process.
453 This index is a number from one to NumberBlockDevices.
454 @param[in] StartLBA The starting logical block address (LBA) to read from
455 on the device
456 @param[in] BufferSize The size of the Buffer in bytes. This number must be
457 a multiple of the intrinsic block size of the device.
458 @param[out] Buffer A pointer to the destination buffer for the data.
459 The caller is responsible for the ownership of the
460 buffer.
461
462 @retval EFI_SUCCESS The data was read correctly from the device.
463 @retval EFI_DEVICE_ERROR The device reported an error while attempting
464 to perform the read operation.
465 @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not
466 valid, or the buffer is not properly aligned.
467 @retval EFI_NO_MEDIA There is no media in the device.
468 @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of
469 the intrinsic block size of the device.
470
471 **/
472 EFI_STATUS
473 EFIAPI
474 AtapiReadBlocks2 (
475 IN EFI_PEI_SERVICES **PeiServices,
476 IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This,
477 IN UINTN DeviceIndex,
478 IN EFI_PEI_LBA StartLBA,
479 IN UINTN BufferSize,
480 OUT VOID *Buffer
481 )
482 {
483 EFI_STATUS Status;
484 ATAPI_BLK_IO_DEV *AtapiBlkIoDev;
485
486 AtapiBlkIoDev = NULL;
487
488 if (This == NULL) {
489 return EFI_INVALID_PARAMETER;
490 }
491
492 AtapiBlkIoDev = PEI_RECOVERY_ATAPI_FROM_BLKIO2_THIS (This);
493
494 Status = AtapiReadBlocks (
495 PeiServices,
496 &AtapiBlkIoDev->AtapiBlkIo,
497 DeviceIndex,
498 StartLBA,
499 BufferSize,
500 Buffer
501 );
502
503 return Status;
504 }
505
506
507 /**
508 Enumerate Atapi devices.
509
510 This function is used to enumerate Atatpi device in Ide channel.
511
512 @param[in] AtapiBlkIoDev A pointer to atapi block IO device
513
514 **/
515 VOID
516 AtapiEnumerateDevices (
517 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev
518 )
519 {
520 UINT8 Index1;
521 UINT8 Index2;
522 UINTN DevicePosition;
523 EFI_PEI_BLOCK_IO_MEDIA MediaInfo;
524 EFI_PEI_BLOCK_IO2_MEDIA MediaInfo2;
525 EFI_STATUS Status;
526 UINTN DeviceCount;
527 UINT16 CommandBlockBaseAddr;
528 UINT16 ControlBlockBaseAddr;
529 UINT32 IdeEnabledNumber;
530 IDE_REGS_BASE_ADDR IdeRegsBaseAddr[MAX_IDE_CHANNELS];
531
532 DeviceCount = 0;
533 DevicePosition = 0;
534
535 //
536 // Scan IDE bus for ATAPI devices
537 //
538
539 //
540 // Enable Sata and IDE controller.
541 //
542 AtapiBlkIoDev->AtaControllerPpi->EnableAtaChannel (
543 (EFI_PEI_SERVICES **) GetPeiServicesTablePointer(),
544 AtapiBlkIoDev->AtaControllerPpi,
545 PEI_ICH_IDE_PRIMARY | PEI_ICH_IDE_SECONDARY
546 );
547
548 //
549 // Allow SATA Devices to spin-up. This is needed if
550 // SEC and PEI phase is too short, for example Release Build.
551 //
552 DEBUG ((DEBUG_INFO, "Delay for %d seconds for SATA devices to spin-up\n", PcdGet16 (PcdSataSpinUpDelayInSecForRecoveryPath)));
553 MicroSecondDelay (PcdGet16 (PcdSataSpinUpDelayInSecForRecoveryPath) * 1000 * 1000); //
554
555 //
556 // Get four channels (primary or secondary Pata, Sata Channel) Command and Control Regs Base address.
557 //
558 IdeEnabledNumber = AtapiBlkIoDev->AtaControllerPpi->GetIdeRegsBaseAddr (
559 (EFI_PEI_SERVICES **) GetPeiServicesTablePointer(),
560 AtapiBlkIoDev->AtaControllerPpi,
561 IdeRegsBaseAddr
562 );
563
564 //
565 // Using Command and Control Regs Base Address to fill other registers.
566 //
567 for (Index1 = 0; Index1 < IdeEnabledNumber; Index1 ++) {
568 CommandBlockBaseAddr = IdeRegsBaseAddr[Index1].CommandBlockBaseAddr;
569 AtapiBlkIoDev->IdeIoPortReg[Index1].Data = CommandBlockBaseAddr;
570 AtapiBlkIoDev->IdeIoPortReg[Index1].Reg1.Feature = (UINT16) (CommandBlockBaseAddr + 0x1);
571 AtapiBlkIoDev->IdeIoPortReg[Index1].SectorCount = (UINT16) (CommandBlockBaseAddr + 0x2);
572 AtapiBlkIoDev->IdeIoPortReg[Index1].SectorNumber = (UINT16) (CommandBlockBaseAddr + 0x3);
573 AtapiBlkIoDev->IdeIoPortReg[Index1].CylinderLsb = (UINT16) (CommandBlockBaseAddr + 0x4);
574 AtapiBlkIoDev->IdeIoPortReg[Index1].CylinderMsb = (UINT16) (CommandBlockBaseAddr + 0x5);
575 AtapiBlkIoDev->IdeIoPortReg[Index1].Head = (UINT16) (CommandBlockBaseAddr + 0x6);
576 AtapiBlkIoDev->IdeIoPortReg[Index1].Reg.Command = (UINT16) (CommandBlockBaseAddr + 0x7);
577
578 ControlBlockBaseAddr = IdeRegsBaseAddr[Index1].ControlBlockBaseAddr;
579 AtapiBlkIoDev->IdeIoPortReg[Index1].Alt.DeviceControl = ControlBlockBaseAddr;
580 AtapiBlkIoDev->IdeIoPortReg[Index1].DriveAddress = (UINT16) (ControlBlockBaseAddr + 0x1);
581
582 //
583 // Scan IDE bus for ATAPI devices IDE or Sata device
584 //
585 for (Index2 = IdeMaster; Index2 < IdeMaxDevice; Index2++) {
586 //
587 // Pata & Sata, Primary & Secondary channel, Master & Slave device
588 //
589 DevicePosition = Index1 * 2 + Index2;
590
591 if (DiscoverAtapiDevice (AtapiBlkIoDev, DevicePosition, &MediaInfo, &MediaInfo2)) {
592 //
593 // ATAPI Device at DevicePosition is found.
594 //
595 AtapiBlkIoDev->DeviceInfo[DeviceCount].DevicePosition = DevicePosition;
596 //
597 // Retrieve Media Info
598 //
599 Status = DetectMedia (AtapiBlkIoDev, DevicePosition, &MediaInfo, &MediaInfo2);
600 CopyMem (&(AtapiBlkIoDev->DeviceInfo[DeviceCount].MediaInfo), &MediaInfo, sizeof (MediaInfo));
601 CopyMem (&(AtapiBlkIoDev->DeviceInfo[DeviceCount].MediaInfo2), &MediaInfo2, sizeof (MediaInfo2));
602
603 DEBUG ((DEBUG_INFO, "Atatpi Device Position is %d\n", DevicePosition));
604 DEBUG ((DEBUG_INFO, "Atatpi DeviceType is %d\n", MediaInfo.DeviceType));
605 DEBUG ((DEBUG_INFO, "Atatpi MediaPresent is %d\n", MediaInfo.MediaPresent));
606 DEBUG ((DEBUG_INFO, "Atatpi BlockSize is 0x%x\n", MediaInfo.BlockSize));
607
608 if (EFI_ERROR (Status)) {
609 AtapiBlkIoDev->DeviceInfo[DeviceCount].MediaInfo.MediaPresent = FALSE;
610 AtapiBlkIoDev->DeviceInfo[DeviceCount].MediaInfo.LastBlock = 0;
611 AtapiBlkIoDev->DeviceInfo[DeviceCount].MediaInfo2.MediaPresent = FALSE;
612 AtapiBlkIoDev->DeviceInfo[DeviceCount].MediaInfo2.LastBlock = 0;
613 }
614 DeviceCount += 1;
615 }
616 }
617 }
618
619 AtapiBlkIoDev->DeviceCount = DeviceCount;
620 }
621
622 /**
623 Detect Atapi devices.
624
625 @param[in] AtapiBlkIoDev A pointer to atapi block IO device.
626 @param[in] DevicePosition An integer to signify device position.
627 @param[out] MediaInfo The media information of the specified block media.
628 @param[out] MediaInfo2 The media information 2 of the specified block media.
629
630 @retval TRUE Atapi device exists in specified position.
631 @retval FALSE Atapi device does not exist in specified position.
632
633 **/
634 BOOLEAN
635 DiscoverAtapiDevice (
636 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
637 IN UINTN DevicePosition,
638 OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo,
639 OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo2
640 )
641 {
642 EFI_STATUS Status;
643
644 if (!DetectIDEController (AtapiBlkIoDev, DevicePosition)) {
645 return FALSE;
646 }
647 //
648 // test if it is an ATAPI device (only supported device)
649 //
650 if (ATAPIIdentify (AtapiBlkIoDev, DevicePosition) == EFI_SUCCESS) {
651
652 Status = Inquiry (AtapiBlkIoDev, DevicePosition, MediaInfo, MediaInfo2);
653 if (!EFI_ERROR (Status)) {
654 return TRUE;
655 }
656 }
657
658 return FALSE;
659 }
660
661 /**
662 Check power mode of Atapi devices.
663
664 @param[in] AtapiBlkIoDev A pointer to atapi block IO device.
665 @param[in] DevicePosition An integer to signify device position.
666 @param[in] AtaCommand The Ata Command passed in.
667
668 @retval EFI_SUCCESS The Atapi device support power mode.
669 @retval EFI_NOT_FOUND The Atapi device not found.
670 @retval EFI_TIMEOUT Atapi command transaction is time out.
671 @retval EFI_ABORTED Atapi command abort.
672
673 **/
674 EFI_STATUS
675 CheckPowerMode (
676 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
677 IN UINTN DevicePosition,
678 IN UINT8 AtaCommand
679 )
680 {
681 UINT8 Channel;
682 UINT8 Device;
683 UINT16 StatusRegister;
684 UINT16 HeadRegister;
685 UINT16 CommandRegister;
686 UINT16 ErrorRegister;
687 UINT16 SectorCountRegister;
688 EFI_STATUS Status;
689 UINT8 StatusValue;
690 UINT8 ErrorValue;
691 UINT8 SectorCountValue;
692
693 Channel = (UINT8) (DevicePosition / 2);
694 Device = (UINT8) (DevicePosition % 2);
695
696 ASSERT (Channel < MAX_IDE_CHANNELS);
697
698 StatusRegister = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg.Status;
699 HeadRegister = AtapiBlkIoDev->IdeIoPortReg[Channel].Head;
700 CommandRegister = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg.Command;
701 ErrorRegister = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg1.Error;
702 SectorCountRegister = AtapiBlkIoDev->IdeIoPortReg[Channel].SectorCount;
703
704 //
705 // select device
706 //
707 IoWrite8 (HeadRegister, (UINT8) ((Device << 4) | 0xe0));
708
709 //
710 // refresh the SectorCount register
711 //
712 SectorCountValue = 0x55;
713 IoWrite8 (SectorCountRegister, SectorCountValue);
714
715 //
716 // select device
717 //
718 IoWrite8 (HeadRegister, (UINT8) ((Device << 4) | 0xe0));
719
720 Status = DRDYReady (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), 100);
721
722 //
723 // select device
724 //
725 IoWrite8 (HeadRegister, (UINT8) ((Device << 4) | 0xe0));
726 //
727 // send 'check power' commandd via Command Register
728 //
729 IoWrite8 (CommandRegister, AtaCommand);
730
731 Status = WaitForBSYClear (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), 3000);
732 if (EFI_ERROR (Status)) {
733 return EFI_TIMEOUT;
734 }
735
736 StatusValue = IoRead8 (StatusRegister);
737
738 //
739 // command returned status is DRDY, indicating device supports the command,
740 // so device is present.
741 //
742 if ((StatusValue & ATA_STSREG_DRDY) == ATA_STSREG_DRDY) {
743 return EFI_SUCCESS;
744 }
745
746 SectorCountValue = IoRead8 (SectorCountRegister);
747
748 //
749 // command returned status is ERR & ABRT_ERR, indicating device does not support
750 // the command, so device is present.
751 //
752 if ((StatusValue & ATA_STSREG_ERR) == ATA_STSREG_ERR) {
753 ErrorValue = IoRead8 (ErrorRegister);
754 if ((ErrorValue & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {
755 return EFI_ABORTED;
756 } else {
757 //
758 // According to spec, no other error code is valid
759 //
760 return EFI_NOT_FOUND;
761 }
762 }
763
764 if ((SectorCountValue == 0x00) || (SectorCountValue == 0x80) || (SectorCountValue == 0xff)) {
765 //
766 // Write SectorCount 0x55 but return valid state value. Maybe no device
767 // exists or some slow kind of ATAPI device exists.
768 //
769 IoWrite8 (HeadRegister, (UINT8) ((Device << 4) | 0xe0));
770
771 //
772 // write 0x55 and 0xaa to SectorCounter register,
773 // if the data could be written into the register,
774 // indicating the device is present, otherwise the device is not present.
775 //
776 SectorCountValue = 0x55;
777 IoWrite8 (SectorCountRegister, SectorCountValue);
778 MicroSecondDelay (10000);
779
780 SectorCountValue = IoRead8 (SectorCountRegister);
781 if (SectorCountValue != 0x55) {
782 return EFI_NOT_FOUND;
783 }
784 //
785 // Send a "ATAPI TEST UNIT READY" command ... slow but accurate
786 //
787 Status = TestUnitReady (AtapiBlkIoDev, DevicePosition);
788 return Status;
789 }
790
791 return EFI_NOT_FOUND;
792 }
793
794 /**
795 Detect if an IDE controller exists in specified position.
796
797 @param[in] AtapiBlkIoDev A pointer to atapi block IO device.
798 @param[in] DevicePosition An integer to signify device position.
799
800 @retval TRUE The Atapi device exists.
801 @retval FALSE The Atapi device does not present.
802
803 **/
804 BOOLEAN
805 DetectIDEController (
806 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
807 IN UINTN DevicePosition
808 )
809 {
810 UINT8 Channel;
811 EFI_STATUS Status;
812 UINT8 AtaCommand;
813
814 Channel = (UINT8) (DevicePosition / 2);
815
816 ASSERT (Channel < MAX_IDE_CHANNELS);
817 //
818 // Wait 31 seconds for BSY clear
819 //
820 Status = WaitForBSYClear (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), 31000);
821 if (EFI_ERROR (Status)) {
822 return FALSE;
823 }
824 //
825 // Send 'check power' command for IDE device
826 //
827 AtaCommand = 0xE5;
828 Status = CheckPowerMode (AtapiBlkIoDev, DevicePosition, AtaCommand);
829 if ((Status == EFI_ABORTED) || (Status == EFI_SUCCESS)) {
830 return TRUE;
831 }
832
833 return FALSE;
834 }
835
836 /**
837 Wait specified time interval to poll for BSY bit clear in the Status Register.
838
839 @param[in] AtapiBlkIoDev A pointer to atapi block IO device.
840 @param[in] IdeIoRegisters A pointer to IDE IO registers.
841 @param[in] TimeoutInMilliSeconds Time specified in milliseconds.
842
843 @retval EFI_SUCCESS BSY bit is cleared in the specified time interval.
844 @retval EFI_TIMEOUT BSY bit is not cleared in the specified time interval.
845
846 **/
847 EFI_STATUS
848 WaitForBSYClear (
849 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
850 IN IDE_BASE_REGISTERS *IdeIoRegisters,
851 IN UINTN TimeoutInMilliSeconds
852 )
853 {
854 UINTN Delay;
855 UINT16 StatusRegister;
856 UINT8 StatusValue;
857
858 StatusValue = 0;
859
860 StatusRegister = IdeIoRegisters->Reg.Status;
861
862 Delay = ((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 250) + 1;
863 do {
864 StatusValue = IoRead8 (StatusRegister);
865 if ((StatusValue & ATA_STSREG_BSY) == 0x00) {
866 break;
867 }
868 MicroSecondDelay (250);
869
870 Delay--;
871
872 } while (Delay != 0);
873
874 if (Delay == 0) {
875 return EFI_TIMEOUT;
876 }
877
878 return EFI_SUCCESS;
879 }
880
881 /**
882 Wait specified time interval to poll for DRDY bit set in the Status register.
883
884 @param[in] AtapiBlkIoDev A pointer to atapi block IO device.
885 @param[in] IdeIoRegisters A pointer to IDE IO registers.
886 @param[in] TimeoutInMilliSeconds Time specified in milliseconds.
887
888 @retval EFI_SUCCESS DRDY bit is set in the specified time interval.
889 @retval EFI_TIMEOUT DRDY bit is not set in the specified time interval.
890
891 **/
892 EFI_STATUS
893 DRDYReady (
894 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
895 IN IDE_BASE_REGISTERS *IdeIoRegisters,
896 IN UINTN TimeoutInMilliSeconds
897 )
898 {
899 UINTN Delay;
900 UINT16 StatusRegister;
901 UINT8 StatusValue;
902 UINT8 ErrValue;
903
904 StatusValue = 0;
905
906 StatusRegister = IdeIoRegisters->Reg.Status;
907
908 Delay = ((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 250) + 1;
909 do {
910 StatusValue = IoRead8 (StatusRegister);
911 //
912 // BSY == 0 , DRDY == 1
913 //
914 if ((StatusValue & (ATA_STSREG_DRDY | ATA_STSREG_BSY)) == ATA_STSREG_DRDY) {
915 break;
916 }
917
918 if ((StatusValue & (ATA_STSREG_ERR | ATA_STSREG_BSY)) == ATA_STSREG_ERR) {
919 ErrValue = IoRead8 (IdeIoRegisters->Reg1.Error);
920 if ((ErrValue & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {
921 return EFI_ABORTED;
922 }
923 }
924
925 MicroSecondDelay (250);
926
927 Delay--;
928
929 } while (Delay != 0);
930
931 if (Delay == 0) {
932 return EFI_TIMEOUT;
933 }
934
935 return EFI_SUCCESS;
936 }
937
938 /**
939 Wait specified time interval to poll for DRQ bit clear in the Status Register.
940
941 @param[in] AtapiBlkIoDev A pointer to atapi block IO device.
942 @param[in] IdeIoRegisters A pointer to IDE IO registers.
943 @param[in] TimeoutInMilliSeconds Time specified in milliseconds.
944
945 @retval EFI_SUCCESS DRQ bit is cleared in the specified time interval.
946 @retval EFI_TIMEOUT DRQ bit is not cleared in the specified time interval.
947
948 **/
949 EFI_STATUS
950 DRQClear (
951 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
952 IN IDE_BASE_REGISTERS *IdeIoRegisters,
953 IN UINTN TimeoutInMilliSeconds
954 )
955 {
956 UINTN Delay;
957 UINT16 StatusRegister;
958 UINT8 StatusValue;
959 UINT8 ErrValue;
960
961 StatusValue = 0;
962
963 StatusRegister = IdeIoRegisters->Reg.Status;
964
965 Delay = ((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 250) + 1;
966 do {
967
968 StatusValue = IoRead8 (StatusRegister);
969
970 //
971 // wait for BSY == 0 and DRQ == 0
972 //
973 if ((StatusValue & (ATA_STSREG_DRQ | ATA_STSREG_BSY)) == 0) {
974 break;
975 }
976
977 if ((StatusValue & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) {
978 ErrValue = IoRead8 (IdeIoRegisters->Reg1.Error);
979 if ((ErrValue & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {
980 return EFI_ABORTED;
981 }
982 }
983
984 MicroSecondDelay (250);
985
986 Delay--;
987 } while (Delay != 0);
988
989 if (Delay == 0) {
990 return EFI_TIMEOUT;
991 }
992
993 return EFI_SUCCESS;
994 }
995
996 /**
997 Wait specified time interval to poll for DRQ bit clear in the Alternate Status Register.
998
999 @param[in] AtapiBlkIoDev A pointer to atapi block IO device.
1000 @param[in] IdeIoRegisters A pointer to IDE IO registers.
1001 @param[in] TimeoutInMilliSeconds Time specified in milliseconds.
1002
1003 @retval EFI_SUCCESS DRQ bit is cleared in the specified time interval.
1004 @retval EFI_TIMEOUT DRQ bit is not cleared in the specified time interval.
1005
1006 **/
1007 EFI_STATUS
1008 DRQClear2 (
1009 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
1010 IN IDE_BASE_REGISTERS *IdeIoRegisters,
1011 IN UINTN TimeoutInMilliSeconds
1012 )
1013 {
1014 UINTN Delay;
1015 UINT16 AltStatusRegister;
1016 UINT8 AltStatusValue;
1017 UINT8 ErrValue;
1018
1019 AltStatusValue = 0;
1020
1021 AltStatusRegister = IdeIoRegisters->Alt.AltStatus;
1022
1023 Delay = ((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 250) + 1;
1024 do {
1025
1026 AltStatusValue = IoRead8 (AltStatusRegister);
1027
1028 //
1029 // wait for BSY == 0 and DRQ == 0
1030 //
1031 if ((AltStatusValue & (ATA_STSREG_DRQ | ATA_STSREG_BSY)) == 0) {
1032 break;
1033 }
1034
1035 if ((AltStatusValue & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) {
1036 ErrValue = IoRead8 (IdeIoRegisters->Reg1.Error);
1037 if ((ErrValue & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {
1038 return EFI_ABORTED;
1039 }
1040 }
1041
1042 MicroSecondDelay (250);
1043
1044 Delay--;
1045 } while (Delay != 0);
1046
1047 if (Delay == 0) {
1048 return EFI_TIMEOUT;
1049 }
1050
1051 return EFI_SUCCESS;
1052 }
1053
1054 /**
1055 Wait specified time interval to poll for DRQ bit set in the Status Register.
1056
1057 @param[in] AtapiBlkIoDev A pointer to atapi block IO device.
1058 @param[in] IdeIoRegisters A pointer to IDE IO registers.
1059 @param[in] TimeoutInMilliSeconds Time specified in milliseconds.
1060
1061 @retval EFI_SUCCESS DRQ bit is set in the specified time interval.
1062 @retval EFI_TIMEOUT DRQ bit is not set in the specified time interval.
1063 @retval EFI_ABORTED Operation Aborted.
1064
1065 **/
1066 EFI_STATUS
1067 DRQReady (
1068 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
1069 IN IDE_BASE_REGISTERS *IdeIoRegisters,
1070 IN UINTN TimeoutInMilliSeconds
1071 )
1072 {
1073 UINTN Delay;
1074 UINT16 StatusRegister;
1075 UINT8 StatusValue;
1076 UINT8 ErrValue;
1077
1078 StatusValue = 0;
1079 ErrValue = 0;
1080
1081 StatusRegister = IdeIoRegisters->Reg.Status;
1082
1083 Delay = ((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 250) + 1;
1084 do {
1085 //
1086 // read Status Register will clear interrupt
1087 //
1088 StatusValue = IoRead8 (StatusRegister);
1089
1090 //
1091 // BSY==0,DRQ==1
1092 //
1093 if ((StatusValue & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) {
1094 break;
1095 }
1096
1097 if ((StatusValue & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) {
1098
1099 ErrValue = IoRead8 (IdeIoRegisters->Reg1.Error);
1100 if ((ErrValue & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {
1101 return EFI_ABORTED;
1102 }
1103 }
1104 MicroSecondDelay (250);
1105
1106 Delay--;
1107 } while (Delay != 0);
1108
1109 if (Delay == 0) {
1110 return EFI_TIMEOUT;
1111 }
1112
1113 return EFI_SUCCESS;
1114 }
1115
1116 /**
1117 Wait specified time interval to poll for DRQ bit set in the Alternate Status Register.
1118
1119 @param[in] AtapiBlkIoDev A pointer to atapi block IO device.
1120 @param[in] IdeIoRegisters A pointer to IDE IO registers.
1121 @param[in] TimeoutInMilliSeconds Time specified in milliseconds.
1122
1123 @retval EFI_SUCCESS DRQ bit is set in the specified time interval.
1124 @retval EFI_TIMEOUT DRQ bit is not set in the specified time interval.
1125 @retval EFI_ABORTED Operation Aborted.
1126
1127 **/
1128 EFI_STATUS
1129 DRQReady2 (
1130 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
1131 IN IDE_BASE_REGISTERS *IdeIoRegisters,
1132 IN UINTN TimeoutInMilliSeconds
1133 )
1134 {
1135 UINTN Delay;
1136 UINT16 AltStatusRegister;
1137 UINT8 AltStatusValue;
1138 UINT8 ErrValue;
1139
1140 AltStatusValue = 0;
1141
1142 AltStatusRegister = IdeIoRegisters->Alt.AltStatus;
1143
1144 Delay = ((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 250) + 1;
1145 do {
1146
1147 AltStatusValue = IoRead8 (AltStatusRegister);
1148
1149 //
1150 // BSY==0,DRQ==1
1151 //
1152 if ((AltStatusValue & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) {
1153 break;
1154 }
1155
1156 if ((AltStatusValue & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) {
1157
1158 ErrValue = IoRead8 (IdeIoRegisters->Reg1.Error);
1159 if ((ErrValue & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {
1160 return EFI_ABORTED;
1161 }
1162 }
1163 MicroSecondDelay (250);
1164
1165 Delay--;
1166 } while (Delay != 0);
1167
1168 if (Delay == 0) {
1169 return EFI_TIMEOUT;
1170 }
1171
1172 return EFI_SUCCESS;
1173 }
1174
1175 /**
1176 Check if there is an error in Status Register.
1177
1178 @param[in] AtapiBlkIoDev A pointer to atapi block IO device.
1179 @param[in] StatusReg The address to IDE IO registers.
1180
1181 @retval EFI_SUCCESS Operation success.
1182 @retval EFI_DEVICE_ERROR Device error.
1183
1184 **/
1185 EFI_STATUS
1186 CheckErrorStatus (
1187 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
1188 IN UINT16 StatusReg
1189 )
1190 {
1191 UINT8 StatusValue;
1192
1193 StatusValue = IoRead8 (StatusReg);
1194
1195 if ((StatusValue & (ATA_STSREG_ERR | ATA_STSREG_DWF | ATA_STSREG_CORR)) == 0) {
1196
1197 return EFI_SUCCESS;
1198 }
1199
1200 return EFI_DEVICE_ERROR;
1201
1202 }
1203
1204 /**
1205 Idendify Atapi devices.
1206
1207 @param[in] AtapiBlkIoDev A pointer to atapi block IO device.
1208 @param[in] DevicePosition An integer to signify device position.
1209
1210 @retval EFI_SUCCESS Identify successfully.
1211 @retval EFI_DEVICE_ERROR Device cannot be identified successfully.
1212
1213 **/
1214 EFI_STATUS
1215 ATAPIIdentify (
1216 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
1217 IN UINTN DevicePosition
1218 )
1219 {
1220 ATAPI_IDENTIFY_DATA AtapiIdentifyData;
1221 UINT8 Channel;
1222 UINT8 Device;
1223 UINT16 StatusReg;
1224 UINT16 HeadReg;
1225 UINT16 CommandReg;
1226 UINT16 DataReg;
1227 UINT16 SectorCountReg;
1228 UINT16 SectorNumberReg;
1229 UINT16 CylinderLsbReg;
1230 UINT16 CylinderMsbReg;
1231
1232 UINT32 WordCount;
1233 UINT32 Increment;
1234 UINT32 Index;
1235 UINT32 ByteCount;
1236 UINT16 *Buffer16;
1237
1238 EFI_STATUS Status;
1239
1240 ByteCount = sizeof (AtapiIdentifyData);
1241 Buffer16 = (UINT16 *) &AtapiIdentifyData;
1242
1243 Channel = (UINT8) (DevicePosition / 2);
1244 Device = (UINT8) (DevicePosition % 2);
1245
1246 ASSERT (Channel < MAX_IDE_CHANNELS);
1247
1248 StatusReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg.Status;
1249 HeadReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Head;
1250 CommandReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg.Command;
1251 DataReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Data;
1252 SectorCountReg = AtapiBlkIoDev->IdeIoPortReg[Channel].SectorCount;
1253 SectorNumberReg = AtapiBlkIoDev->IdeIoPortReg[Channel].SectorNumber;
1254 CylinderLsbReg = AtapiBlkIoDev->IdeIoPortReg[Channel].CylinderLsb;
1255 CylinderMsbReg = AtapiBlkIoDev->IdeIoPortReg[Channel].CylinderMsb;
1256
1257 //
1258 // Send ATAPI Identify Command to get IDENTIFY data.
1259 //
1260 if (WaitForBSYClear (
1261 AtapiBlkIoDev,
1262 &(AtapiBlkIoDev->IdeIoPortReg[Channel]),
1263 ATATIMEOUT
1264 ) != EFI_SUCCESS) {
1265 return EFI_DEVICE_ERROR;
1266 }
1267 //
1268 // select device via Head/Device register.
1269 // Before write Head/Device register, BSY and DRQ must be 0.
1270 //
1271 if (DRQClear2 (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), ATATIMEOUT) != EFI_SUCCESS) {
1272 return EFI_DEVICE_ERROR;
1273 }
1274 //
1275 // e0:1110,0000-- bit7 and bit5 are reserved bits.
1276 // bit6 set means LBA mode
1277 //
1278 IoWrite8 (HeadReg, (UINT8) ((Device << 4) | 0xe0));
1279
1280 //
1281 // set all the command parameters
1282 // Before write to all the following registers, BSY and DRQ must be 0.
1283 //
1284 if (DRQClear2 (
1285 AtapiBlkIoDev,
1286 &(AtapiBlkIoDev->IdeIoPortReg[Channel]),
1287 ATATIMEOUT
1288 ) != EFI_SUCCESS) {
1289
1290 return EFI_DEVICE_ERROR;
1291 }
1292
1293 IoWrite8 (SectorCountReg, 0);
1294 IoWrite8 (SectorNumberReg, 0);
1295 IoWrite8 (CylinderLsbReg, 0);
1296 IoWrite8 (CylinderMsbReg, 0);
1297
1298 //
1299 // send command via Command Register
1300 //
1301 IoWrite8 (CommandReg, ATA_CMD_IDENTIFY_DEVICE);
1302
1303 //
1304 // According to PIO data in protocol, host can perform a series of reads to the
1305 // data register after each time device set DRQ ready;
1306 // The data size of "a series of read" is command specific.
1307 // For most ATA command, data size received from device will not exceed 1 sector,
1308 // hense the data size for "a series of read" can be the whole data size of one command request.
1309 // For ATA command such as Read Sector command, whole data size of one ATA command request is often larger
1310 // than 1 sector, according to the Read Sector command, the data size of "a series of read" is exactly
1311 // 1 sector.
1312 // Here for simplification reason, we specify the data size for "a series of read" to
1313 // 1 sector (256 words) if whole data size of one ATA commmand request is larger than 256 words.
1314 //
1315 Increment = 256;
1316 //
1317 // 256 words
1318 //
1319 WordCount = 0;
1320 //
1321 // WordCount is used to record bytes of currently transfered data
1322 //
1323 while (WordCount < ByteCount / 2) {
1324 //
1325 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.
1326 //
1327 Status = DRQReady2 (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), ATATIMEOUT);
1328 if (Status != EFI_SUCCESS) {
1329 return Status;
1330 }
1331
1332 if (CheckErrorStatus (AtapiBlkIoDev, StatusReg) != EFI_SUCCESS) {
1333
1334 return EFI_DEVICE_ERROR;
1335 }
1336 //
1337 // Get the byte count for one series of read
1338 //
1339 if ((WordCount + Increment) > ByteCount / 2) {
1340 Increment = ByteCount / 2 - WordCount;
1341 }
1342 //
1343 // perform a series of read without check DRQ ready
1344 //
1345 for (Index = 0; Index < Increment; Index++) {
1346 *Buffer16++ = IoRead16 (DataReg);
1347 }
1348
1349 WordCount += Increment;
1350
1351 }
1352 //
1353 // while
1354 //
1355 if (DRQClear (
1356 AtapiBlkIoDev,
1357 &(AtapiBlkIoDev->IdeIoPortReg[Channel]),
1358 ATATIMEOUT
1359 ) != EFI_SUCCESS) {
1360 return CheckErrorStatus (AtapiBlkIoDev, StatusReg);
1361 }
1362
1363 return EFI_SUCCESS;
1364
1365 }
1366
1367 /**
1368 Sends out ATAPI Test Unit Ready Packet Command to the specified device
1369 to find out whether device is accessible.
1370
1371 @param[in] AtapiBlkIoDev A pointer to atapi block IO device.
1372 @param[in] DevicePosition An integer to signify device position.
1373
1374 @retval EFI_SUCCESS TestUnit command executed successfully.
1375 @retval EFI_DEVICE_ERROR Device cannot be executed TestUnit command successfully.
1376
1377 **/
1378 EFI_STATUS
1379 TestUnitReady (
1380 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
1381 IN UINTN DevicePosition
1382 )
1383 {
1384 ATAPI_PACKET_COMMAND Packet;
1385 EFI_STATUS Status;
1386
1387 //
1388 // fill command packet
1389 //
1390 ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
1391 Packet.TestUnitReady.opcode = ATA_CMD_TEST_UNIT_READY;
1392
1393 //
1394 // send command packet
1395 //
1396 Status = AtapiPacketCommandIn (AtapiBlkIoDev, DevicePosition, &Packet, NULL, 0, ATAPITIMEOUT);
1397 return Status;
1398 }
1399
1400 /**
1401 Send out ATAPI commands conforms to the Packet Command with PIO Data In Protocol.
1402
1403 @param[in] AtapiBlkIoDev A pointer to atapi block IO device.
1404 @param[in] DevicePosition An integer to signify device position.
1405 @param[in] Packet A pointer to ATAPI command packet.
1406 @param[in] Buffer Buffer to contain requested transfer data from device.
1407 @param[in] ByteCount Requested transfer data length.
1408 @param[in] TimeoutInMilliSeconds Time out value, in unit of milliseconds.
1409
1410 @retval EFI_SUCCESS Command executed successfully.
1411 @retval EFI_DEVICE_ERROR Device cannot be executed command successfully.
1412
1413 **/
1414 EFI_STATUS
1415 AtapiPacketCommandIn (
1416 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
1417 IN UINTN DevicePosition,
1418 IN ATAPI_PACKET_COMMAND *Packet,
1419 IN UINT16 *Buffer,
1420 IN UINT32 ByteCount,
1421 IN UINTN TimeoutInMilliSeconds
1422 )
1423 {
1424 UINT8 Channel;
1425 UINT8 Device;
1426 UINT16 StatusReg;
1427 UINT16 HeadReg;
1428 UINT16 CommandReg;
1429 UINT16 FeatureReg;
1430 UINT16 CylinderLsbReg;
1431 UINT16 CylinderMsbReg;
1432 UINT16 DeviceControlReg;
1433 UINT16 DataReg;
1434 EFI_STATUS Status;
1435 UINT32 Count;
1436 UINT16 *CommandIndex;
1437 UINT16 *PtrBuffer;
1438 UINT32 Index;
1439 UINT8 StatusValue;
1440 UINT32 WordCount;
1441
1442 //
1443 // required transfer data in word unit.
1444 //
1445 UINT32 RequiredWordCount;
1446
1447 //
1448 // actual transfer data in word unit.
1449 //
1450 UINT32 ActualWordCount;
1451
1452 Channel = (UINT8) (DevicePosition / 2);
1453 Device = (UINT8) (DevicePosition % 2);
1454
1455 ASSERT (Channel < MAX_IDE_CHANNELS);
1456
1457 StatusReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg.Status;
1458 HeadReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Head;
1459 CommandReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg.Command;
1460 FeatureReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg1.Feature;
1461 CylinderLsbReg = AtapiBlkIoDev->IdeIoPortReg[Channel].CylinderLsb;
1462 CylinderMsbReg = AtapiBlkIoDev->IdeIoPortReg[Channel].CylinderMsb;
1463 DeviceControlReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Alt.DeviceControl;
1464 DataReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Data;
1465
1466 //
1467 // Set all the command parameters by fill related registers.
1468 // Before write to all the following registers, BSY and DRQ must be 0.
1469 //
1470 if (DRQClear2 (
1471 AtapiBlkIoDev,
1472 &(AtapiBlkIoDev->IdeIoPortReg[Channel]),
1473 ATATIMEOUT
1474 ) != EFI_SUCCESS) {
1475 return EFI_DEVICE_ERROR;
1476 }
1477 //
1478 // Select device via Device/Head Register.
1479 // DEFAULT_CMD: 0xa0 (1010,0000)
1480 //
1481 IoWrite8 (HeadReg, (UINT8) ((Device << 4) | ATA_DEFAULT_CMD));
1482
1483 //
1484 // No OVL; No DMA
1485 //
1486 IoWrite8 (FeatureReg, 0x00);
1487
1488 //
1489 // set the transfersize to MAX_ATAPI_BYTE_COUNT to let the device
1490 // determine how many data should be transfered.
1491 //
1492 IoWrite8 (CylinderLsbReg, (UINT8) (ATAPI_MAX_BYTE_COUNT & 0x00ff));
1493 IoWrite8 (CylinderMsbReg, (UINT8) (ATAPI_MAX_BYTE_COUNT >> 8));
1494
1495 //
1496 // DEFAULT_CTL:0x0a (0000,1010)
1497 // Disable interrupt
1498 //
1499 IoWrite8 (DeviceControlReg, ATA_DEFAULT_CTL);
1500
1501 //
1502 // Send Packet command to inform device
1503 // that the following data bytes are command packet.
1504 //
1505 IoWrite8 (CommandReg, ATA_CMD_PACKET);
1506
1507 Status = DRQReady (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), TimeoutInMilliSeconds);
1508 if (Status != EFI_SUCCESS) {
1509 return Status;
1510 }
1511 //
1512 // Send out command packet
1513 //
1514 CommandIndex = Packet->Data16;
1515 for (Count = 0; Count < 6; Count++, CommandIndex++) {
1516 IoWrite16 (DataReg, *CommandIndex);
1517 MicroSecondDelay (10);
1518 }
1519
1520 StatusValue = IoRead8 (StatusReg);
1521 if ((StatusValue & ATA_STSREG_ERR) == ATA_STSREG_ERR) {
1522 //
1523 // Trouble! Something's wrong here... Wait some time and return. 3 second is
1524 // supposed to be long enough for a device reset latency or error recovery
1525 //
1526 MicroSecondDelay (3000000);
1527 return EFI_DEVICE_ERROR;
1528 }
1529
1530 if (Buffer == NULL || ByteCount == 0) {
1531 return EFI_SUCCESS;
1532 }
1533 //
1534 // call PioReadWriteData() function to get
1535 // requested transfer data form device.
1536 //
1537 PtrBuffer = Buffer;
1538 RequiredWordCount = ByteCount / 2;
1539 //
1540 // ActuralWordCount means the word count of data really transfered.
1541 //
1542 ActualWordCount = 0;
1543
1544 Status = EFI_SUCCESS;
1545 while ((Status == EFI_SUCCESS) && (ActualWordCount < RequiredWordCount)) {
1546 //
1547 // before each data transfer stream, the host should poll DRQ bit ready,
1548 // which informs device is ready to transfer data.
1549 //
1550 if (DRQReady2 (
1551 AtapiBlkIoDev,
1552 &(AtapiBlkIoDev->IdeIoPortReg[Channel]),
1553 TimeoutInMilliSeconds
1554 ) != EFI_SUCCESS) {
1555 return CheckErrorStatus (AtapiBlkIoDev, StatusReg);
1556 }
1557 //
1558 // read Status Register will clear interrupt
1559 //
1560 StatusValue = IoRead8 (StatusReg);
1561
1562 //
1563 // get current data transfer size from Cylinder Registers.
1564 //
1565 WordCount = IoRead8 (CylinderMsbReg) << 8;
1566 WordCount = WordCount | IoRead8 (CylinderLsbReg);
1567 WordCount = WordCount & 0xffff;
1568 WordCount /= 2;
1569
1570 //
1571 // perform a series data In/Out.
1572 //
1573 for (Index = 0; (Index < WordCount) && (ActualWordCount < RequiredWordCount); Index++, ActualWordCount++) {
1574
1575 *PtrBuffer = IoRead16 (DataReg);
1576
1577 PtrBuffer++;
1578
1579 }
1580
1581 if (((ATAPI_REQUEST_SENSE_CMD *) Packet)->opcode == ATA_CMD_REQUEST_SENSE && ActualWordCount >= 4) {
1582 RequiredWordCount = MIN (
1583 RequiredWordCount,
1584 (UINT32) (4 + (((ATAPI_REQUEST_SENSE_DATA *) Buffer)->addnl_sense_length / 2))
1585 );
1586 }
1587
1588 }
1589 //
1590 // After data transfer is completed, normally, DRQ bit should clear.
1591 //
1592 Status = DRQClear2 (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), TimeoutInMilliSeconds);
1593 if (Status != EFI_SUCCESS) {
1594 return EFI_DEVICE_ERROR;
1595 }
1596 //
1597 // read status register to check whether error happens.
1598 //
1599 Status = CheckErrorStatus (AtapiBlkIoDev, StatusReg);
1600 return Status;
1601 }
1602
1603 /**
1604 Sends out ATAPI Inquiry Packet Command to the specified device.
1605 This command will return INQUIRY data of the device.
1606
1607 @param[in] AtapiBlkIoDev A pointer to atapi block IO device.
1608 @param[in] DevicePosition An integer to signify device position.
1609 @param[out] MediaInfo The media information of the specified block media.
1610 @param[out] MediaInfo2 The media information 2 of the specified block media.
1611
1612 @retval EFI_SUCCESS Command executed successfully.
1613 @retval EFI_DEVICE_ERROR Device cannot be executed command successfully.
1614 @retval EFI_UNSUPPORTED Unsupported device type.
1615
1616 **/
1617 EFI_STATUS
1618 Inquiry (
1619 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
1620 IN UINTN DevicePosition,
1621 OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo,
1622 OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo2
1623 )
1624 {
1625 ATAPI_PACKET_COMMAND Packet;
1626 EFI_STATUS Status;
1627 ATAPI_INQUIRY_DATA Idata;
1628
1629 //
1630 // prepare command packet for the ATAPI Inquiry Packet Command.
1631 //
1632 ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
1633 ZeroMem (&Idata, sizeof (ATAPI_INQUIRY_DATA));
1634
1635 Packet.Inquiry.opcode = ATA_CMD_INQUIRY;
1636 Packet.Inquiry.page_code = 0;
1637 Packet.Inquiry.allocation_length = (UINT8) sizeof (ATAPI_INQUIRY_DATA);
1638
1639 //
1640 // Send command packet and get requested Inquiry data.
1641 //
1642 Status = AtapiPacketCommandIn (
1643 AtapiBlkIoDev,
1644 DevicePosition,
1645 &Packet,
1646 (UINT16 *) (&Idata),
1647 sizeof (ATAPI_INQUIRY_DATA),
1648 ATAPITIMEOUT
1649 //50
1650 );
1651
1652 if (Status != EFI_SUCCESS) {
1653 return EFI_DEVICE_ERROR;
1654 }
1655 //
1656 // Identify device type via INQUIRY data.
1657 //
1658 switch (Idata.peripheral_type & 0x1f) {
1659 case 0x00:
1660 //
1661 // Magnetic Disk
1662 //
1663 MediaInfo->DeviceType = IdeLS120;
1664 MediaInfo->MediaPresent = FALSE;
1665 MediaInfo->LastBlock = 0;
1666 MediaInfo->BlockSize = 0x200;
1667 MediaInfo2->InterfaceType = MSG_ATAPI_DP;
1668 MediaInfo2->RemovableMedia = TRUE;
1669 MediaInfo2->MediaPresent = FALSE;
1670 MediaInfo2->ReadOnly = FALSE;
1671 MediaInfo2->BlockSize = 0x200;
1672 MediaInfo2->LastBlock = 0;
1673 break;
1674
1675 case 0x05:
1676 //
1677 // CD-ROM
1678 //
1679 MediaInfo->DeviceType = IdeCDROM;
1680 MediaInfo->MediaPresent = FALSE;
1681 MediaInfo->LastBlock = 0;
1682 MediaInfo->BlockSize = 0x800;
1683 MediaInfo2->InterfaceType = MSG_ATAPI_DP;
1684 MediaInfo2->RemovableMedia = TRUE;
1685 MediaInfo2->MediaPresent = FALSE;
1686 MediaInfo2->ReadOnly = TRUE;
1687 MediaInfo2->BlockSize = 0x200;
1688 MediaInfo2->LastBlock = 0;
1689 break;
1690
1691 default:
1692 return EFI_UNSUPPORTED;
1693 }
1694
1695 return EFI_SUCCESS;
1696 }
1697
1698 /**
1699 Used before read/write blocks from/to ATAPI device media.
1700 Since ATAPI device media is removable, it is necessary to detect
1701 whether media is present and get current present media's information.
1702
1703 @param[in] AtapiBlkIoDev A pointer to atapi block IO device.
1704 @param[in] DevicePosition An integer to signify device position.
1705 @param[in, out] MediaInfo The media information of the specified block media.
1706 @param[in, out] MediaInfo2 The media information 2 of the specified block media.
1707
1708 @retval EFI_SUCCESS Command executed successfully.
1709 @retval EFI_DEVICE_ERROR Some device errors happen.
1710 @retval EFI_OUT_OF_RESOURCES Can not allocate required resources.
1711
1712 **/
1713 EFI_STATUS
1714 DetectMedia (
1715 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
1716 IN UINTN DevicePosition,
1717 IN OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo,
1718 IN OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo2
1719 )
1720 {
1721
1722 UINTN Index;
1723 UINTN RetryNum;
1724 UINTN MaxRetryNum;
1725 ATAPI_REQUEST_SENSE_DATA *SenseBuffers;
1726 BOOLEAN NeedReadCapacity;
1727 BOOLEAN NeedRetry;
1728 EFI_STATUS Status;
1729 UINT8 SenseCounts;
1730
1731 SenseBuffers = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (*SenseBuffers)));
1732 if (SenseBuffers == NULL) {
1733 return EFI_OUT_OF_RESOURCES;
1734 }
1735
1736 //
1737 // Test Unit Ready command is used to detect whether device is accessible,
1738 // the device will produce corresponding Sense data.
1739 //
1740 for (Index = 0; Index < 2; Index++) {
1741
1742 Status = TestUnitReady (AtapiBlkIoDev, DevicePosition);
1743 if (Status != EFI_SUCCESS) {
1744 Status = ResetDevice (AtapiBlkIoDev, DevicePosition, FALSE);
1745
1746 if (Status != EFI_SUCCESS) {
1747 ResetDevice (AtapiBlkIoDev, DevicePosition, TRUE);
1748 }
1749
1750 } else {
1751 break;
1752 }
1753 }
1754
1755 SenseCounts = MAX_SENSE_KEY_COUNT;
1756 Status = EFI_SUCCESS;
1757 NeedReadCapacity = TRUE;
1758
1759 for (Index = 0; Index < 5; Index++) {
1760 SenseCounts = MAX_SENSE_KEY_COUNT;
1761 Status = RequestSense (
1762 AtapiBlkIoDev,
1763 DevicePosition,
1764 SenseBuffers,
1765 &SenseCounts
1766 );
1767 DEBUG ((DEBUG_INFO, "Atapi Request Sense Count is %d\n", SenseCounts));
1768 if (IsDeviceStateUnclear (SenseBuffers, SenseCounts) || IsNoMedia (SenseBuffers, SenseCounts)) {
1769 //
1770 // We are not sure whether the media is present or not, try again
1771 //
1772 TestUnitReady (AtapiBlkIoDev, DevicePosition);
1773 } else {
1774 break;
1775 }
1776 }
1777
1778 if (Status == EFI_SUCCESS) {
1779
1780 if (IsNoMedia (SenseBuffers, SenseCounts)) {
1781
1782 NeedReadCapacity = FALSE;
1783 MediaInfo->MediaPresent = FALSE;
1784 MediaInfo->LastBlock = 0;
1785 MediaInfo2->MediaPresent = FALSE;
1786 MediaInfo2->LastBlock = 0;
1787 }
1788
1789 if (IsMediaError (SenseBuffers, SenseCounts)) {
1790 return EFI_DEVICE_ERROR;
1791 }
1792 }
1793
1794 if (NeedReadCapacity) {
1795 //
1796 // at most retry 5 times
1797 //
1798 MaxRetryNum = 5;
1799 RetryNum = 1;
1800 //
1801 // initial retry once
1802 //
1803 for (Index = 0; (Index < RetryNum) && (Index < MaxRetryNum); Index++) {
1804
1805 Status = ReadCapacity (AtapiBlkIoDev, DevicePosition, MediaInfo, MediaInfo2);
1806 MicroSecondDelay (200000);
1807 SenseCounts = MAX_SENSE_KEY_COUNT;
1808
1809 if (Status != EFI_SUCCESS) {
1810
1811 Status = RequestSense (AtapiBlkIoDev, DevicePosition, SenseBuffers, &SenseCounts);
1812 //
1813 // If Request Sense data failed, reset the device and retry.
1814 //
1815 if (Status != EFI_SUCCESS) {
1816
1817 Status = ResetDevice (AtapiBlkIoDev, DevicePosition, FALSE);
1818 //
1819 // if ATAPI soft reset fail,
1820 // use stronger reset mechanism -- ATA soft reset.
1821 //
1822 if (Status != EFI_SUCCESS) {
1823 ResetDevice (AtapiBlkIoDev, DevicePosition, TRUE);
1824 }
1825
1826 RetryNum++;
1827 //
1828 // retry once more
1829 //
1830 continue;
1831 }
1832 //
1833 // No Media
1834 //
1835 if (IsNoMedia (SenseBuffers, SenseCounts)) {
1836
1837 MediaInfo->MediaPresent = FALSE;
1838 MediaInfo->LastBlock = 0;
1839 MediaInfo2->MediaPresent = FALSE;
1840 MediaInfo2->LastBlock = 0;
1841 break;
1842 }
1843
1844 if (IsMediaError (SenseBuffers, SenseCounts)) {
1845 return EFI_DEVICE_ERROR;
1846 }
1847
1848 if (!IsDriveReady (SenseBuffers, SenseCounts, &NeedRetry)) {
1849 //
1850 // Drive not ready: if NeedRetry, then retry once more;
1851 // else return error
1852 //
1853 if (NeedRetry) {
1854 RetryNum++;
1855 continue;
1856 } else {
1857 return EFI_DEVICE_ERROR;
1858 }
1859 }
1860 //
1861 // if read capacity fail not for above reasons, retry once more
1862 //
1863 RetryNum++;
1864
1865 }
1866
1867 }
1868
1869 }
1870
1871 return EFI_SUCCESS;
1872 }
1873
1874 /**
1875 Reset specified Atapi device.
1876
1877 @param[in] AtapiBlkIoDev A pointer to atapi block IO device.
1878 @param[in] DevicePosition An integer to signify device position.
1879 @param[in] Extensive If TRUE, use ATA soft reset, otherwise use Atapi soft reset.
1880
1881 @retval EFI_SUCCESS Command executed successfully.
1882 @retval EFI_DEVICE_ERROR Some device errors happen.
1883
1884 **/
1885 EFI_STATUS
1886 ResetDevice (
1887 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
1888 IN UINTN DevicePosition,
1889 IN BOOLEAN Extensive
1890 )
1891 {
1892 UINT8 DevControl;
1893 UINT8 Command;
1894 UINT8 DeviceSelect;
1895 UINT16 DeviceControlReg;
1896 UINT16 CommandReg;
1897 UINT16 HeadReg;
1898 UINT8 Channel;
1899 UINT8 Device;
1900
1901 Channel = (UINT8) (DevicePosition / 2);
1902 Device = (UINT8) (DevicePosition % 2);
1903
1904 ASSERT (Channel < MAX_IDE_CHANNELS);
1905
1906 DeviceControlReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Alt.DeviceControl;
1907 CommandReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg.Command;
1908 HeadReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Head;
1909
1910 if (Extensive) {
1911
1912 DevControl = 0;
1913 DevControl |= ATA_CTLREG_SRST;
1914 //
1915 // set SRST bit to initiate soft reset
1916 //
1917 DevControl |= BIT1;
1918 //
1919 // disable Interrupt
1920 //
1921 IoWrite8 (DeviceControlReg, DevControl);
1922
1923 //
1924 // Wait 10us
1925 //
1926 MicroSecondDelay (10);
1927
1928 //
1929 // Clear SRST bit
1930 //
1931 DevControl &= 0xfb;
1932 //
1933 // 0xfb:1111,1011
1934 //
1935 IoWrite8 (DeviceControlReg, DevControl);
1936
1937 //
1938 // slave device needs at most 31s to clear BSY
1939 //
1940 if (WaitForBSYClear (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), 31000) == EFI_TIMEOUT) {
1941 return EFI_DEVICE_ERROR;
1942 }
1943
1944 } else {
1945 //
1946 // for ATAPI device, no need to wait DRDY ready after device selecting.
1947 // bit7 and bit5 are both set to 1 for backward compatibility
1948 //
1949 DeviceSelect = (UINT8) (((BIT7 | BIT5) | (Device << 4)));
1950 IoWrite8 (HeadReg, DeviceSelect);
1951
1952 Command = ATA_CMD_SOFT_RESET;
1953 IoWrite8 (CommandReg, Command);
1954
1955 //
1956 // BSY cleared is the only status return to the host by the device when reset is completed
1957 // slave device needs at most 31s to clear BSY
1958 //
1959 if (WaitForBSYClear (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), 31000) != EFI_SUCCESS) {
1960 return EFI_DEVICE_ERROR;
1961 }
1962 //
1963 // stall 5 seconds to make the device status stable
1964 //
1965 MicroSecondDelay (STALL_1_SECONDS * 5);
1966 }
1967
1968 return EFI_SUCCESS;
1969
1970 }
1971
1972 /**
1973 Sends out ATAPI Request Sense Packet Command to the specified device.
1974
1975 @param[in] AtapiBlkIoDev A pointer to atapi block IO device.
1976 @param[in] DevicePosition An integer to signify device position.
1977 @param[in] SenseBuffers Pointer to sense buffer.
1978 @param[in, out] SenseCounts Length of sense buffer.
1979
1980 @retval EFI_SUCCESS Command executed successfully.
1981 @retval EFI_DEVICE_ERROR Some device errors happen.
1982
1983 **/
1984 EFI_STATUS
1985 RequestSense (
1986 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
1987 IN UINTN DevicePosition,
1988 IN ATAPI_REQUEST_SENSE_DATA *SenseBuffers,
1989 IN OUT UINT8 *SenseCounts
1990 )
1991 {
1992 EFI_STATUS Status;
1993 ATAPI_REQUEST_SENSE_DATA *Sense;
1994 UINT16 *Ptr;
1995 BOOLEAN SenseReq;
1996 ATAPI_PACKET_COMMAND Packet;
1997
1998 ZeroMem (SenseBuffers, sizeof (ATAPI_REQUEST_SENSE_DATA) * (*SenseCounts));
1999 //
2000 // fill command packet for Request Sense Packet Command
2001 //
2002 ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
2003 Packet.RequestSence.opcode = ATA_CMD_REQUEST_SENSE;
2004 Packet.RequestSence.allocation_length = (UINT8) sizeof (ATAPI_REQUEST_SENSE_DATA);
2005
2006 Ptr = (UINT16 *) SenseBuffers;
2007 //
2008 // initialize pointer
2009 //
2010 *SenseCounts = 0;
2011 //
2012 // request sense data from device continiously until no sense data exists in the device.
2013 //
2014 for (SenseReq = TRUE; SenseReq;) {
2015
2016 Sense = (ATAPI_REQUEST_SENSE_DATA *) Ptr;
2017
2018 //
2019 // send out Request Sense Packet Command and get one Sense data form device
2020 //
2021 Status = AtapiPacketCommandIn (
2022 AtapiBlkIoDev,
2023 DevicePosition,
2024 &Packet,
2025 Ptr,
2026 sizeof (ATAPI_REQUEST_SENSE_DATA),
2027 ATAPITIMEOUT
2028 );
2029 //
2030 // failed to get Sense data
2031 //
2032 if (Status != EFI_SUCCESS) {
2033 if (*SenseCounts == 0) {
2034 return EFI_DEVICE_ERROR;
2035 } else {
2036 return EFI_SUCCESS;
2037 }
2038 }
2039
2040 (*SenseCounts)++;
2041
2042 if (*SenseCounts > MAX_SENSE_KEY_COUNT) {
2043 return EFI_SUCCESS;
2044 }
2045 //
2046 // We limit MAX sense data count to 20 in order to avoid dead loop. Some
2047 // incompatible ATAPI devices don't retrive NO_SENSE when there is no media.
2048 // In this case, dead loop occurs if we don't have a gatekeeper. 20 is
2049 // supposed to be large enough for any ATAPI device.
2050 //
2051 if ((Sense->sense_key != ATA_SK_NO_SENSE) && ((*SenseCounts) < 20)) {
2052
2053 Ptr += sizeof (ATAPI_REQUEST_SENSE_DATA) / 2;
2054 //
2055 // Ptr is word based pointer
2056 //
2057 } else {
2058 //
2059 // when no sense key, skip out the loop
2060 //
2061 SenseReq = FALSE;
2062 }
2063 }
2064
2065 return EFI_SUCCESS;
2066 }
2067
2068 /**
2069 Sends out ATAPI Read Capacity Packet Command to the specified device.
2070 This command will return the information regarding the capacity of the
2071 media in the device.
2072
2073 @param[in] AtapiBlkIoDev A pointer to atapi block IO device.
2074 @param[in] DevicePosition An integer to signify device position.
2075 @param[in, out] MediaInfo The media information of the specified block media.
2076 @param[in, out] MediaInfo2 The media information 2 of the specified block media.
2077
2078 @retval EFI_SUCCESS Command executed successfully.
2079 @retval EFI_DEVICE_ERROR Some device errors happen.
2080
2081 **/
2082 EFI_STATUS
2083 ReadCapacity (
2084 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
2085 IN UINTN DevicePosition,
2086 IN OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo,
2087 IN OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo2
2088 )
2089 {
2090 EFI_STATUS Status;
2091 ATAPI_PACKET_COMMAND Packet;
2092
2093 //
2094 // used for capacity data returned from ATAPI device
2095 //
2096 ATAPI_READ_CAPACITY_DATA Data;
2097 ATAPI_READ_FORMAT_CAPACITY_DATA FormatData;
2098
2099 ZeroMem (&Data, sizeof (Data));
2100 ZeroMem (&FormatData, sizeof (FormatData));
2101
2102 if (MediaInfo->DeviceType == IdeCDROM) {
2103
2104 ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
2105 Packet.Inquiry.opcode = ATA_CMD_READ_CAPACITY;
2106 Status = AtapiPacketCommandIn (
2107 AtapiBlkIoDev,
2108 DevicePosition,
2109 &Packet,
2110 (UINT16 *) (&Data),
2111 sizeof (ATAPI_READ_CAPACITY_DATA),
2112 ATAPITIMEOUT
2113 );
2114
2115 } else {
2116 //
2117 // DeviceType == IdeLS120
2118 //
2119 ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
2120 Packet.ReadFormatCapacity.opcode = ATA_CMD_READ_FORMAT_CAPACITY;
2121 Packet.ReadFormatCapacity.allocation_length_lo = 12;
2122 Status = AtapiPacketCommandIn (
2123 AtapiBlkIoDev,
2124 DevicePosition,
2125 &Packet,
2126 (UINT16 *) (&FormatData),
2127 sizeof (ATAPI_READ_FORMAT_CAPACITY_DATA),
2128 ATAPITIMEOUT*10
2129 );
2130 }
2131
2132 if (Status == EFI_SUCCESS) {
2133
2134 if (MediaInfo->DeviceType == IdeCDROM) {
2135
2136 MediaInfo->LastBlock = ((UINT32) Data.LastLba3 << 24) | (Data.LastLba2 << 16) | (Data.LastLba1 << 8) | Data.LastLba0;
2137 MediaInfo->MediaPresent = TRUE;
2138 //
2139 // Because the user data portion in the sector of the Data CD supported
2140 // is always 800h
2141 //
2142 MediaInfo->BlockSize = 0x800;
2143
2144 MediaInfo2->LastBlock = MediaInfo->LastBlock;
2145 MediaInfo2->MediaPresent = MediaInfo->MediaPresent;
2146 MediaInfo2->BlockSize = (UINT32)MediaInfo->BlockSize;
2147 }
2148
2149 if (MediaInfo->DeviceType == IdeLS120) {
2150
2151 if (FormatData.DesCode == 3) {
2152 MediaInfo->MediaPresent = FALSE;
2153 MediaInfo->LastBlock = 0;
2154 MediaInfo2->MediaPresent = FALSE;
2155 MediaInfo2->LastBlock = 0;
2156 } else {
2157 MediaInfo->LastBlock = ((UINT32) FormatData.LastLba3 << 24) |
2158 (FormatData.LastLba2 << 16) |
2159 (FormatData.LastLba1 << 8) |
2160 FormatData.LastLba0;
2161 MediaInfo->LastBlock--;
2162
2163 MediaInfo->MediaPresent = TRUE;
2164
2165 MediaInfo->BlockSize = 0x200;
2166
2167 MediaInfo2->LastBlock = MediaInfo->LastBlock;
2168 MediaInfo2->MediaPresent = MediaInfo->MediaPresent;
2169 MediaInfo2->BlockSize = (UINT32)MediaInfo->BlockSize;
2170
2171 }
2172 }
2173
2174 return EFI_SUCCESS;
2175
2176 } else {
2177 return EFI_DEVICE_ERROR;
2178 }
2179 }
2180
2181 /**
2182 Perform read from disk in block unit.
2183
2184 @param[in] AtapiBlkIoDev A pointer to atapi block IO device.
2185 @param[in] DevicePosition An integer to signify device position.
2186 @param[in] Buffer Buffer to contain read data.
2187 @param[in] StartLba Starting LBA address.
2188 @param[in] NumberOfBlocks Number of blocks to read.
2189 @param[in] BlockSize Size of each block.
2190
2191 @retval EFI_SUCCESS Command executed successfully.
2192 @retval EFI_DEVICE_ERROR Some device errors happen.
2193
2194 **/
2195 EFI_STATUS
2196 ReadSectors (
2197 IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev,
2198 IN UINTN DevicePosition,
2199 IN VOID *Buffer,
2200 IN EFI_PEI_LBA StartLba,
2201 IN UINTN NumberOfBlocks,
2202 IN UINTN BlockSize
2203 )
2204 {
2205
2206 ATAPI_PACKET_COMMAND Packet;
2207 ATAPI_READ10_CMD *Read10Packet;
2208 EFI_STATUS Status;
2209 UINTN BlocksRemaining;
2210 UINT32 Lba32;
2211 UINT32 ByteCount;
2212 UINT16 SectorCount;
2213 VOID *PtrBuffer;
2214 UINT16 MaxBlock;
2215
2216 //
2217 // fill command packet for Read(10) command
2218 //
2219 ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
2220 Read10Packet = &Packet.Read10;
2221 Lba32 = (UINT32) StartLba;
2222 PtrBuffer = Buffer;
2223
2224 //
2225 // limit the data bytes that can be transfered by one Read(10) Command
2226 //
2227 MaxBlock = (UINT16) (0x10000 / BlockSize);
2228 //
2229 // (64k bytes)
2230 //
2231 BlocksRemaining = NumberOfBlocks;
2232
2233 Status = EFI_SUCCESS;
2234 while (BlocksRemaining > 0) {
2235
2236 if (BlocksRemaining <= MaxBlock) {
2237 SectorCount = (UINT16) BlocksRemaining;
2238 } else {
2239 SectorCount = MaxBlock;
2240 }
2241 //
2242 // fill the Packet data sturcture
2243 //
2244 Read10Packet->opcode = ATA_CMD_READ_10;
2245
2246 //
2247 // Lba0 ~ Lba3 specify the start logical block address of the data transfer.
2248 // Lba0 is MSB, Lba3 is LSB
2249 //
2250 Read10Packet->Lba3 = (UINT8) (Lba32 & 0xff);
2251 Read10Packet->Lba2 = (UINT8) (Lba32 >> 8);
2252 Read10Packet->Lba1 = (UINT8) (Lba32 >> 16);
2253 Read10Packet->Lba0 = (UINT8) (Lba32 >> 24);
2254
2255 //
2256 // TranLen0 ~ TranLen1 specify the transfer length in block unit.
2257 // TranLen0 is MSB, TranLen is LSB
2258 //
2259 Read10Packet->TranLen1 = (UINT8) (SectorCount & 0xff);
2260 Read10Packet->TranLen0 = (UINT8) (SectorCount >> 8);
2261
2262 ByteCount = (UINT32) (SectorCount * BlockSize);
2263
2264 Status = AtapiPacketCommandIn (
2265 AtapiBlkIoDev,
2266 DevicePosition,
2267 &Packet,
2268 (UINT16 *) PtrBuffer,
2269 ByteCount,
2270 ATAPILONGTIMEOUT
2271 );
2272 if (Status != EFI_SUCCESS) {
2273 return Status;
2274 }
2275
2276 Lba32 += SectorCount;
2277 PtrBuffer = (UINT8 *) PtrBuffer + SectorCount * BlockSize;
2278 BlocksRemaining -= SectorCount;
2279 }
2280
2281 return Status;
2282 }
2283
2284 /**
2285 Check if there is media according to sense data.
2286
2287 @param[in] SenseData Pointer to sense data.
2288 @param[in] SenseCounts Count of sense data.
2289
2290 @retval TRUE No media
2291 @retval FALSE Media exists
2292
2293 **/
2294 BOOLEAN
2295 IsNoMedia (
2296 IN ATAPI_REQUEST_SENSE_DATA *SenseData,
2297 IN UINTN SenseCounts
2298 )
2299 {
2300 ATAPI_REQUEST_SENSE_DATA *SensePtr;
2301 UINTN Index;
2302 BOOLEAN IsNoMedia;
2303
2304 IsNoMedia = FALSE;
2305
2306 SensePtr = SenseData;
2307
2308 for (Index = 0; Index < SenseCounts; Index++) {
2309
2310 if ((SensePtr->sense_key == ATA_SK_NOT_READY) && (SensePtr->addnl_sense_code == ATA_ASC_NO_MEDIA)) {
2311 IsNoMedia = TRUE;
2312 }
2313
2314 SensePtr++;
2315 }
2316
2317 return IsNoMedia;
2318 }
2319
2320 /**
2321 Check if device state is unclear according to sense data.
2322
2323 @param[in] SenseData Pointer to sense data.
2324 @param[in] SenseCounts Count of sense data.
2325
2326 @retval TRUE Device state is unclear
2327 @retval FALSE Device state is clear
2328
2329 **/
2330 BOOLEAN
2331 IsDeviceStateUnclear (
2332 IN ATAPI_REQUEST_SENSE_DATA *SenseData,
2333 IN UINTN SenseCounts
2334 )
2335 {
2336 ATAPI_REQUEST_SENSE_DATA *SensePtr;
2337 UINTN Index;
2338 BOOLEAN Unclear;
2339
2340 Unclear = FALSE;
2341
2342 SensePtr = SenseData;
2343
2344 for (Index = 0; Index < SenseCounts; Index++) {
2345
2346 if (SensePtr->sense_key == 0x06) {
2347 //
2348 // Sense key is 0x06 means the device is just be reset or media just
2349 // changed. The current state of the device is unclear.
2350 //
2351 Unclear = TRUE;
2352 break;
2353 }
2354
2355 SensePtr++;
2356 }
2357
2358 return Unclear;
2359 }
2360
2361 /**
2362 Check if there is media error according to sense data.
2363
2364 @param[in] SenseData Pointer to sense data.
2365 @param[in] SenseCounts Count of sense data.
2366
2367 @retval TRUE Media error
2368 @retval FALSE No media error
2369
2370 **/
2371 BOOLEAN
2372 IsMediaError (
2373 IN ATAPI_REQUEST_SENSE_DATA *SenseData,
2374 IN UINTN SenseCounts
2375 )
2376 {
2377 ATAPI_REQUEST_SENSE_DATA *SensePtr;
2378 UINTN Index;
2379 BOOLEAN IsError;
2380
2381 IsError = FALSE;
2382
2383 SensePtr = SenseData;
2384
2385 for (Index = 0; Index < SenseCounts; Index++) {
2386
2387 switch (SensePtr->sense_key) {
2388
2389 case ATA_SK_MEDIUM_ERROR:
2390 switch (SensePtr->addnl_sense_code) {
2391 case ATA_ASC_MEDIA_ERR1:
2392 //
2393 // fall through
2394 //
2395 case ATA_ASC_MEDIA_ERR2:
2396 //
2397 // fall through
2398 //
2399 case ATA_ASC_MEDIA_ERR3:
2400 //
2401 // fall through
2402 //
2403 case ATA_ASC_MEDIA_ERR4:
2404 IsError = TRUE;
2405 break;
2406
2407 default:
2408 break;
2409 }
2410
2411 break;
2412
2413 case ATA_SK_NOT_READY:
2414 switch (SensePtr->addnl_sense_code) {
2415 case ATA_ASC_MEDIA_UPSIDE_DOWN:
2416 IsError = TRUE;
2417 break;
2418
2419 default:
2420 break;
2421 }
2422 break;
2423
2424 default:
2425 break;
2426 }
2427
2428 SensePtr++;
2429 }
2430
2431 return IsError;
2432 }
2433
2434 /**
2435 Check if drive is ready according to sense data.
2436
2437 @param[in] SenseData Pointer to sense data.
2438 @param[in] SenseCounts Count of sense data.
2439 @param[out] NeedRetry Indicate if retry is needed.
2440
2441 @retval TRUE Drive ready
2442 @retval FALSE Drive not ready
2443
2444 **/
2445 BOOLEAN
2446 IsDriveReady (
2447 IN ATAPI_REQUEST_SENSE_DATA *SenseData,
2448 IN UINTN SenseCounts,
2449 OUT BOOLEAN *NeedRetry
2450 )
2451 {
2452 ATAPI_REQUEST_SENSE_DATA *SensePtr;
2453 UINTN Index;
2454 BOOLEAN IsReady;
2455
2456 IsReady = TRUE;
2457 *NeedRetry = FALSE;
2458
2459 SensePtr = SenseData;
2460
2461 for (Index = 0; Index < SenseCounts; Index++) {
2462
2463 switch (SensePtr->sense_key) {
2464
2465 case ATA_SK_NOT_READY:
2466 switch (SensePtr->addnl_sense_code) {
2467 case ATA_ASC_NOT_READY:
2468 switch (SensePtr->addnl_sense_code_qualifier) {
2469 case ATA_ASCQ_IN_PROGRESS:
2470 IsReady = FALSE;
2471 *NeedRetry = TRUE;
2472 break;
2473
2474 default:
2475 IsReady = FALSE;
2476 *NeedRetry = FALSE;
2477 break;
2478 }
2479 break;
2480
2481 default:
2482 break;
2483 }
2484 break;
2485
2486 default:
2487 break;
2488 }
2489
2490 SensePtr++;
2491 }
2492
2493 return IsReady;
2494 }