fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / include / linux / ata.h
index 94f77cc..1df9416 100644 (file)
@@ -40,6 +40,8 @@ enum {
        ATA_MAX_DEVICES         = 2,    /* per bus/port */
        ATA_MAX_PRD             = 256,  /* we could make these 256/256 */
        ATA_SECT_SIZE           = 512,
+       ATA_MAX_SECTORS         = 256,
+       ATA_MAX_SECTORS_LBA48   = 65535,/* TODO: 65536? */
 
        ATA_ID_WORDS            = 256,
        ATA_ID_SERNO_OFS        = 10,
@@ -97,6 +99,9 @@ enum {
        ATA_DRQ                 = (1 << 3),     /* data request i/o */
        ATA_ERR                 = (1 << 0),     /* have an error */
        ATA_SRST                = (1 << 2),     /* software reset */
+       ATA_ICRC                = (1 << 7),     /* interface CRC error */
+       ATA_UNC                 = (1 << 6),     /* uncorrectable media error */
+       ATA_IDNF                = (1 << 4),     /* ID not found */
        ATA_ABORTED             = (1 << 2),     /* command aborted */
 
        /* ATA command block registers */
@@ -130,6 +135,8 @@ enum {
        ATA_CMD_WRITE           = 0xCA,
        ATA_CMD_WRITE_EXT       = 0x35,
        ATA_CMD_WRITE_FUA_EXT   = 0x3D,
+       ATA_CMD_FPDMA_READ      = 0x60,
+       ATA_CMD_FPDMA_WRITE     = 0x61,
        ATA_CMD_PIO_READ        = 0x20,
        ATA_CMD_PIO_READ_EXT    = 0x24,
        ATA_CMD_PIO_WRITE       = 0x30,
@@ -146,6 +153,12 @@ enum {
        ATA_CMD_STANDBYNOW1     = 0xE0,
        ATA_CMD_IDLEIMMEDIATE   = 0xE1,
        ATA_CMD_INIT_DEV_PARAMS = 0x91,
+       ATA_CMD_READ_NATIVE_MAX = 0xF8,
+       ATA_CMD_READ_NATIVE_MAX_EXT = 0x27,
+       ATA_CMD_READ_LOG_EXT    = 0x2f,
+
+       /* READ_LOG_EXT pages */
+       ATA_LOG_SATA_NCQ        = 0x10,
 
        /* SETFEATURES stuff */
        SETFEATURES_XFER        = 0x03,
@@ -157,12 +170,16 @@ enum {
        XFER_UDMA_2             = 0x42,
        XFER_UDMA_1             = 0x41,
        XFER_UDMA_0             = 0x40,
+       XFER_MW_DMA_4           = 0x24, /* CFA only */
+       XFER_MW_DMA_3           = 0x23, /* CFA only */
        XFER_MW_DMA_2           = 0x22,
        XFER_MW_DMA_1           = 0x21,
        XFER_MW_DMA_0           = 0x20,
        XFER_SW_DMA_2           = 0x12,
        XFER_SW_DMA_1           = 0x11,
        XFER_SW_DMA_0           = 0x10,
+       XFER_PIO_6              = 0x0E, /* CFA only */
+       XFER_PIO_5              = 0x0D, /* CFA only */
        XFER_PIO_4              = 0x0C,
        XFER_PIO_3              = 0x0B,
        XFER_PIO_2              = 0x0A,
@@ -170,6 +187,9 @@ enum {
        XFER_PIO_0              = 0x08,
        XFER_PIO_SLOW           = 0x00,
 
+       SETFEATURES_WC_ON       = 0x02, /* Enable write cache */
+       SETFEATURES_WC_OFF      = 0x82, /* Disable write cache */
+
        /* ATAPI stuff */
        ATAPI_PKT_DMA           = (1 << 0),
        ATAPI_DMADIR            = (1 << 2),     /* ATAPI data dir:
@@ -180,8 +200,9 @@ enum {
        ATA_CBL_NONE            = 0,
        ATA_CBL_PATA40          = 1,
        ATA_CBL_PATA80          = 2,
-       ATA_CBL_PATA_UNK        = 3,
-       ATA_CBL_SATA            = 4,
+       ATA_CBL_PATA40_SHORT    = 3,            /* 40 wire cable to high UDMA spec */
+       ATA_CBL_PATA_UNK        = 4,
+       ATA_CBL_SATA            = 5,
 
        /* SATA Status and Control Registers */
        SCR_STATUS              = 0,
@@ -190,6 +211,16 @@ enum {
        SCR_ACTIVE              = 3,
        SCR_NOTIFICATION        = 4,
 
+       /* SError bits */
+       SERR_DATA_RECOVERED     = (1 << 0), /* recovered data error */
+       SERR_COMM_RECOVERED     = (1 << 1), /* recovered comm failure */
+       SERR_DATA               = (1 << 8), /* unrecovered data error */
+       SERR_PERSISTENT         = (1 << 9), /* persistent data/comm error */
+       SERR_PROTOCOL           = (1 << 10), /* protocol violation */
+       SERR_INTERNAL           = (1 << 11), /* host internal error */
+       SERR_PHYRDY_CHG         = (1 << 16), /* PHY RDY changed */
+       SERR_DEV_XCHG           = (1 << 26), /* device exchanged */
+
        /* struct ata_taskfile flags */
        ATA_TFLAG_LBA48         = (1 << 0), /* enable 48-bit LBA and "HOB" */
        ATA_TFLAG_ISADDR        = (1 << 1), /* enable r/w to nsect/lba regs */
@@ -197,6 +228,7 @@ enum {
        ATA_TFLAG_WRITE         = (1 << 3), /* data dir: host->dev==1 (write) */
        ATA_TFLAG_LBA           = (1 << 4), /* enable LBA */
        ATA_TFLAG_FUA           = (1 << 5), /* enable FUA */
+       ATA_TFLAG_POLLING       = (1 << 6), /* set nIEN to 1 and use polling */
 };
 
 enum ata_tf_protocols {
@@ -204,8 +236,8 @@ enum ata_tf_protocols {
        ATA_PROT_UNKNOWN,       /* unknown/invalid */
        ATA_PROT_NODATA,        /* no data */
        ATA_PROT_PIO,           /* PIO single sector */
-       ATA_PROT_PIO_MULT,      /* PIO multiple sector */
        ATA_PROT_DMA,           /* DMA */
+       ATA_PROT_NCQ,           /* NCQ */
        ATA_PROT_ATAPI,         /* packet command, PIO data xfer*/
        ATA_PROT_ATAPI_NODATA,  /* packet command, no data */
        ATA_PROT_ATAPI_DMA,     /* packet command with special DMA sauce */
@@ -250,15 +282,20 @@ struct ata_taskfile {
 #define ata_id_is_sata(id)     ((id)[93] == 0)
 #define ata_id_rahead_enabled(id) ((id)[85] & (1 << 6))
 #define ata_id_wcache_enabled(id) ((id)[85] & (1 << 5))
+#define ata_id_hpa_enabled(id) ((id)[85] & (1 << 10))
 #define ata_id_has_fua(id)     ((id)[84] & (1 << 6))
 #define ata_id_has_flush(id)   ((id)[83] & (1 << 12))
 #define ata_id_has_flush_ext(id) ((id)[83] & (1 << 13))
 #define ata_id_has_lba48(id)   ((id)[83] & (1 << 10))
+#define ata_id_has_hpa(id)     ((id)[82] & (1 << 10))
 #define ata_id_has_wcache(id)  ((id)[82] & (1 << 5))
 #define ata_id_has_pm(id)      ((id)[82] & (1 << 3))
 #define ata_id_has_lba(id)     ((id)[49] & (1 << 9))
 #define ata_id_has_dma(id)     ((id)[49] & (1 << 8))
+#define ata_id_has_ncq(id)     ((id)[76] & (1 << 8))
+#define ata_id_queue_depth(id) (((id)[75] & 0x1f) + 1)
 #define ata_id_removeable(id)  ((id)[0] & (1 << 7))
+#define ata_id_has_dword_io(id)        ((id)[50] & (1 << 0))
 #define ata_id_u32(id,n)       \
        (((u32) (id)[(n) + 1] << 16) | ((u32) (id)[(n)]))
 #define ata_id_u64(id,n)       \
@@ -267,10 +304,25 @@ struct ata_taskfile {
          ((u64) (id)[(n) + 1] << 16) | \
          ((u64) (id)[(n) + 0]) )
 
+#define ata_id_cdb_intr(id)    (((id)[0] & 0x60) == 0x20)
+
+static inline unsigned int ata_id_major_version(const u16 *id)
+{
+       unsigned int mver;
+
+       if (id[ATA_ID_MAJOR_VER] == 0xFFFF)
+               return 0;
+
+       for (mver = 14; mver >= 1; mver--)
+               if (id[ATA_ID_MAJOR_VER] & (1 << mver))
+                       break;
+       return mver;
+}
+
 static inline int ata_id_current_chs_valid(const u16 *id)
 {
-       /* For ATA-1 devices, if the INITIALIZE DEVICE PARAMETERS command 
-          has not been issued to the device then the values of 
+       /* For ATA-1 devices, if the INITIALIZE DEVICE PARAMETERS command
+          has not been issued to the device then the values of
           id[54] to id[56] are vendor specific. */
        return (id[53] & 0x01) && /* Current translation valid */
                id[54] &&  /* cylinders in current translation */
@@ -279,6 +331,27 @@ static inline int ata_id_current_chs_valid(const u16 *id)
                id[56];    /* sectors in current translation */
 }
 
+static inline int ata_id_is_cfa(const u16 *id)
+{
+       u16 v = id[0];
+       if (v == 0x848A)        /* Standard CF */
+               return 1;
+       /* Could be CF hiding as standard ATA */
+       if (ata_id_major_version(id) >= 3 &&  id[82] != 0xFFFF &&
+                       (id[82] & ( 1 << 2)))
+               return 1;
+       return 0;
+}
+
+static inline int ata_drive_40wire(const u16 *dev_id)
+{
+       if (ata_id_major_version(dev_id) >= 5 && ata_id_is_sata(dev_id))
+               return 0;       /* SATA */
+       if (dev_id[93] & 0x4000)
+               return 0;       /* 80 wire */
+       return 1;
+}
+
 static inline int atapi_cdb_len(const u16 *dev_id)
 {
        u16 tmp = dev_id[0] & 0x3;
@@ -296,10 +369,31 @@ static inline int is_atapi_taskfile(const struct ata_taskfile *tf)
               (tf->protocol == ATA_PROT_ATAPI_DMA);
 }
 
+static inline int is_multi_taskfile(struct ata_taskfile *tf)
+{
+       return (tf->command == ATA_CMD_READ_MULTI) ||
+              (tf->command == ATA_CMD_WRITE_MULTI) ||
+              (tf->command == ATA_CMD_READ_MULTI_EXT) ||
+              (tf->command == ATA_CMD_WRITE_MULTI_EXT) ||
+              (tf->command == ATA_CMD_WRITE_MULTI_FUA_EXT);
+}
+
 static inline int ata_ok(u8 status)
 {
        return ((status & (ATA_BUSY | ATA_DRDY | ATA_DF | ATA_DRQ | ATA_ERR))
                        == ATA_DRDY);
 }
 
+static inline int lba_28_ok(u64 block, u32 n_block)
+{
+       /* check the ending block number */
+       return ((block + n_block - 1) < ((u64)1 << 28)) && (n_block <= 256);
+}
+
+static inline int lba_48_ok(u64 block, u32 n_block)
+{
+       /* check the ending block number */
+       return ((block + n_block - 1) < ((u64)1 << 48)) && (n_block <= 65536);
+}
+
 #endif /* __LINUX_ATA_H__ */