/* $Id: IdeData.h $ */
/** @file
 * IdeData.h
 */

/*
 * Copyright (C) 2009-2010 Oracle Corporation
 *
 * This file is part of VirtualBox Open Source Edition (OSE), as
 * available from http://www.virtualbox.org. This file is free software;
 * you can redistribute it and/or modify it under the terms of the GNU
 * General Public License (GPL) as published by the Free Software
 * Foundation, in version 2 as it comes in the "COPYING" file of the
 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
 */

/** @file
  Header file for IDE Bus Driver's Data Structures

  Copyright (c) 2006 - 2007 Intel Corporation. <BR>
  All rights reserved. This program and the accompanying materials                          
  are licensed and made available under the terms and conditions of the BSD License         
  which accompanies this distribution.  The full text of the license may be found at        
  http://opensource.org/licenses/bsd-license.php                                            

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             

**/

#ifndef _IDE_DATA_H_
#define _IDE_DATA_H_

#include <IndustryStandard/Atapi.h>

//
// common constants
//
#define STALL_1_MILLI_SECOND  1000    // stall 1 ms
#define STALL_1_SECOND        1000000 // stall 1 second
typedef enum {
  IdePrimary    = 0,
  IdeSecondary  = 1,
  IdeMaxChannel = 2
} EFI_IDE_CHANNEL;

typedef enum {
  IdeMaster     = 0,
  IdeSlave      = 1,
  IdeMaxDevice  = 2
} EFI_IDE_DEVICE;

typedef enum {
  IdeMagnetic,                        /* ZIP Drive or LS120 Floppy Drive */
  IdeCdRom,                           /* ATAPI CDROM */
  IdeHardDisk,                        /* Hard Disk */
  Ide48bitAddressingHardDisk,         /* Hard Disk larger than 120GB */
  IdeUnknown
} IDE_DEVICE_TYPE;

typedef enum {
  SenseNoSenseKey,
  SenseDeviceNotReadyNoRetry,
  SenseDeviceNotReadyNeedRetry,
  SenseNoMedia,
  SenseMediaChange,
  SenseMediaError,
  SenseOtherSense
} SENSE_RESULT;

typedef enum {
  AtaUdmaReadOp,
  AtaUdmaReadExtOp,
  AtaUdmaWriteOp,
  AtaUdmaWriteExtOp
} ATA_UDMA_OPERATION;

//
// IDE Registers
//
typedef union {
  UINT16  Command;        /* when write */
  UINT16  Status;         /* when read */
} IDE_CMD_OR_STATUS;

typedef union {
  UINT16  Error;          /* when read */
  UINT16  Feature;        /* when write */
} IDE_ERROR_OR_FEATURE;

typedef union {
  UINT16  AltStatus;      /* when read */
  UINT16  DeviceControl;  /* when write */
} IDE_ALTSTATUS_OR_DEVICECONTROL;

//
// IDE registers set
//
typedef struct {
  UINT16                          Data;
  IDE_ERROR_OR_FEATURE            Reg1;
  UINT16                          SectorCount;
  UINT16                          SectorNumber;
  UINT16                          CylinderLsb;
  UINT16                          CylinderMsb;
  UINT16                          Head;
  IDE_CMD_OR_STATUS               Reg;

  IDE_ALTSTATUS_OR_DEVICECONTROL  Alt;
  UINT16                          DriveAddress;

  UINT16                          MasterSlave;
  UINT16                          BusMasterBaseAddr;
} IDE_BASE_REGISTERS;

//
// IDE registers' base addresses
//
typedef struct {
  UINT16  CommandBlockBaseAddr;
  UINT16  ControlBlockBaseAddr;
  UINT16  BusMasterBaseAddr;
} IDE_REGISTERS_BASE_ADDR;

//
// Bit definitions in Programming Interface byte of the Class Code field
// in PCI IDE controller's Configuration Space
//
#define IDE_PRIMARY_OPERATING_MODE            BIT0
#define IDE_PRIMARY_PROGRAMMABLE_INDICATOR    BIT1
#define IDE_SECONDARY_OPERATING_MODE          BIT2
#define IDE_SECONDARY_PROGRAMMABLE_INDICATOR  BIT3


//
// Bus Master Reg
//
#define BMIC_NREAD      BIT3
#define BMIC_START      BIT0
#define BMIS_INTERRUPT  BIT2
#define BMIS_ERROR      BIT1

#define BMICP_OFFSET    0x00
#define BMISP_OFFSET    0x02
#define BMIDP_OFFSET    0x04
#define BMICS_OFFSET    0x08
#define BMISS_OFFSET    0x0A
#define BMIDS_OFFSET    0x0C

//
// Time Out Value For IDE Device Polling
//

//
// ATATIMEOUT is used for waiting time out for ATA device
//

//
// 1 second
//
#define ATATIMEOUT  1000  

//
// ATAPITIMEOUT is used for waiting operation
// except read and write time out for ATAPI device
//

//
// 1 second
//
#define ATAPITIMEOUT  1000 

//
// ATAPILONGTIMEOUT is used for waiting read and
// write operation timeout for ATAPI device
//

//
// 2 seconds
//
#define CDROMLONGTIMEOUT  2000  

//
// 5 seconds
//
#define ATAPILONGTIMEOUT  5000  

//
// 10 seconds
//
#define ATASMARTTIMEOUT   10000


//
// ATAPI6 related data structure definition
//

//
// The maximum sectors count in 28 bit addressing mode
//
#define MAX_28BIT_ADDRESSING_CAPACITY 0xfffffff

#pragma pack(1)

typedef struct {
  UINT32  RegionBaseAddr;
  UINT16  ByteCount;
  UINT16  EndOfTable;
} IDE_DMA_PRD;

#pragma pack()

#define SETFEATURE        TRUE
#define CLEARFEATURE      FALSE

///
/// PIO mode definition
///
typedef enum _ATA_PIO_MODE_ {
  AtaPioModeBelow2,
  AtaPioMode2,
  AtaPioMode3,
  AtaPioMode4
} ATA_PIO_MODE;

//
// Multi word DMA definition
//
typedef enum _ATA_MDMA_MODE_ {
  AtaMdmaMode0,
  AtaMdmaMode1,
  AtaMdmaMode2
} ATA_MDMA_MODE;

//
// UDMA mode definition
//
typedef enum _ATA_UDMA_MODE_ {
  AtaUdmaMode0,
  AtaUdmaMode1,
  AtaUdmaMode2,
  AtaUdmaMode3,
  AtaUdmaMode4,
  AtaUdmaMode5
} ATA_UDMA_MODE;

#define ATA_MODE_CATEGORY_DEFAULT_PIO 0x00
#define ATA_MODE_CATEGORY_FLOW_PIO    0x01
#define ATA_MODE_CATEGORY_MDMA        0x04
#define ATA_MODE_CATEGORY_UDMA        0x08

#pragma pack(1)

typedef struct {
  UINT8 ModeNumber : 3;
  UINT8 ModeCategory : 5;
} ATA_TRANSFER_MODE;

typedef struct {
  UINT8 Sector;
  UINT8 Heads;
  UINT8 MultipleSector;
} ATA_DRIVE_PARMS;

#pragma pack()
//
// IORDY Sample Point field value
//
#define ISP_5_CLK 0
#define ISP_4_CLK 1
#define ISP_3_CLK 2
#define ISP_2_CLK 3

//
// Recovery Time field value
//
#define RECVY_4_CLK 0
#define RECVY_3_CLK 1
#define RECVY_2_CLK 2
#define RECVY_1_CLK 3

//
// Slave IDE Timing Register Enable
//
#define SITRE BIT14

//
// DMA Timing Enable Only Select 1
//
#define DTE1  BIT7

//
// Pre-fetch and Posting Enable Select 1
//
#define PPE1  BIT6

//
// IORDY Sample Point Enable Select 1
//
#define IE1 BIT5

//
// Fast Timing Bank Drive Select 1
//
#define TIME1 BIT4

//
// DMA Timing Enable Only Select 0
//
#define DTE0  BIT3

//
// Pre-fetch and Posting Enable Select 0
//
#define PPE0  BIT2

//
// IOREY Sample Point Enable Select 0
//
#define IE0 BIT1

//
// Fast Timing Bank Drive Select 0
//
#define TIME0 BIT0

#endif
