ide: merge ide_hwgroup_t with ide_hwif_t (v2)
[linux-2.6.git] / include / linux / ide.h
index a5e1888..f27f130 100644 (file)
 # define SUPPORT_VLB_SYNC 1
 #endif
 
-/*
- * Used to indicate "no IRQ", should be a value that cannot be an IRQ
- * number.
- */
-#define IDE_NO_IRQ             (-1)
-
 typedef unsigned char  byte;   /* used everywhere */
 
 /*
@@ -49,7 +42,6 @@ typedef unsigned char byte;   /* used everywhere */
 #define ERROR_RECAL    1       /* Recalibrate every 2nd retry */
 
 #define HWIF(drive)            ((ide_hwif_t *)((drive)->hwif))
-#define HWGROUP(drive)         ((ide_hwgroup_t *)(HWIF(drive)->hwgroup))
 
 /*
  * Definitions for accessing IDE controller registers
@@ -122,8 +114,6 @@ struct ide_io_ports {
 #define MAX_DRIVES     2       /* per interface; 2 assumed by lots of code */
 #define SECTOR_SIZE    512
 
-#define IDE_LARGE_SEEK(b1,b2,t)        (((b1) > (b2) + (t)) || ((b2) > (b1) + (t)))
-
 /*
  * Timeouts for various operations:
  */
@@ -156,6 +146,8 @@ enum {
  */
 #define REQ_DRIVE_RESET                0x20
 #define REQ_DEVSET_EXEC                0x21
+#define REQ_PARK_HEADS         0x22
+#define REQ_UNPARK_HEADS       0x23
 
 /*
  * Check for an interrupt and acknowledge the interrupt status
@@ -170,9 +162,7 @@ typedef int (ide_ack_intr_t)(struct hwif_s *);
 enum {         ide_unknown,    ide_generic,    ide_pci,
                ide_cmd640,     ide_dtc2278,    ide_ali14xx,
                ide_qd65xx,     ide_umc8672,    ide_ht6560b,
-               ide_rz1000,     ide_trm290,
-               ide_cmd646,     ide_cy82c693,   ide_4drives,
-               ide_pmac,       ide_acorn,
+               ide_4drives,    ide_pmac,       ide_acorn,
                ide_au1xxx,     ide_palm3710
 };
 
@@ -282,6 +272,110 @@ typedef enum {
        ide_started,    /* a drive operation was started, handler was set */
 } ide_startstop_t;
 
+enum {
+       IDE_TFLAG_LBA48                 = (1 << 0),
+       IDE_TFLAG_FLAGGED               = (1 << 2),
+       IDE_TFLAG_OUT_DATA              = (1 << 3),
+       IDE_TFLAG_OUT_HOB_FEATURE       = (1 << 4),
+       IDE_TFLAG_OUT_HOB_NSECT         = (1 << 5),
+       IDE_TFLAG_OUT_HOB_LBAL          = (1 << 6),
+       IDE_TFLAG_OUT_HOB_LBAM          = (1 << 7),
+       IDE_TFLAG_OUT_HOB_LBAH          = (1 << 8),
+       IDE_TFLAG_OUT_HOB               = IDE_TFLAG_OUT_HOB_FEATURE |
+                                         IDE_TFLAG_OUT_HOB_NSECT |
+                                         IDE_TFLAG_OUT_HOB_LBAL |
+                                         IDE_TFLAG_OUT_HOB_LBAM |
+                                         IDE_TFLAG_OUT_HOB_LBAH,
+       IDE_TFLAG_OUT_FEATURE           = (1 << 9),
+       IDE_TFLAG_OUT_NSECT             = (1 << 10),
+       IDE_TFLAG_OUT_LBAL              = (1 << 11),
+       IDE_TFLAG_OUT_LBAM              = (1 << 12),
+       IDE_TFLAG_OUT_LBAH              = (1 << 13),
+       IDE_TFLAG_OUT_TF                = IDE_TFLAG_OUT_FEATURE |
+                                         IDE_TFLAG_OUT_NSECT |
+                                         IDE_TFLAG_OUT_LBAL |
+                                         IDE_TFLAG_OUT_LBAM |
+                                         IDE_TFLAG_OUT_LBAH,
+       IDE_TFLAG_OUT_DEVICE            = (1 << 14),
+       IDE_TFLAG_WRITE                 = (1 << 15),
+       IDE_TFLAG_FLAGGED_SET_IN_FLAGS  = (1 << 16),
+       IDE_TFLAG_IN_DATA               = (1 << 17),
+       IDE_TFLAG_CUSTOM_HANDLER        = (1 << 18),
+       IDE_TFLAG_DMA_PIO_FALLBACK      = (1 << 19),
+       IDE_TFLAG_IN_HOB_FEATURE        = (1 << 20),
+       IDE_TFLAG_IN_HOB_NSECT          = (1 << 21),
+       IDE_TFLAG_IN_HOB_LBAL           = (1 << 22),
+       IDE_TFLAG_IN_HOB_LBAM           = (1 << 23),
+       IDE_TFLAG_IN_HOB_LBAH           = (1 << 24),
+       IDE_TFLAG_IN_HOB_LBA            = IDE_TFLAG_IN_HOB_LBAL |
+                                         IDE_TFLAG_IN_HOB_LBAM |
+                                         IDE_TFLAG_IN_HOB_LBAH,
+       IDE_TFLAG_IN_HOB                = IDE_TFLAG_IN_HOB_FEATURE |
+                                         IDE_TFLAG_IN_HOB_NSECT |
+                                         IDE_TFLAG_IN_HOB_LBA,
+       IDE_TFLAG_IN_FEATURE            = (1 << 1),
+       IDE_TFLAG_IN_NSECT              = (1 << 25),
+       IDE_TFLAG_IN_LBAL               = (1 << 26),
+       IDE_TFLAG_IN_LBAM               = (1 << 27),
+       IDE_TFLAG_IN_LBAH               = (1 << 28),
+       IDE_TFLAG_IN_LBA                = IDE_TFLAG_IN_LBAL |
+                                         IDE_TFLAG_IN_LBAM |
+                                         IDE_TFLAG_IN_LBAH,
+       IDE_TFLAG_IN_TF                 = IDE_TFLAG_IN_NSECT |
+                                         IDE_TFLAG_IN_LBA,
+       IDE_TFLAG_IN_DEVICE             = (1 << 29),
+       IDE_TFLAG_HOB                   = IDE_TFLAG_OUT_HOB |
+                                         IDE_TFLAG_IN_HOB,
+       IDE_TFLAG_TF                    = IDE_TFLAG_OUT_TF |
+                                         IDE_TFLAG_IN_TF,
+       IDE_TFLAG_DEVICE                = IDE_TFLAG_OUT_DEVICE |
+                                         IDE_TFLAG_IN_DEVICE,
+       /* force 16-bit I/O operations */
+       IDE_TFLAG_IO_16BIT              = (1 << 30),
+       /* ide_task_t was allocated using kmalloc() */
+       IDE_TFLAG_DYN                   = (1 << 31),
+};
+
+struct ide_taskfile {
+       u8      hob_data;       /*  0: high data byte (for TASKFILE IOCTL) */
+
+       u8      hob_feature;    /*  1-5: additional data to support LBA48 */
+       u8      hob_nsect;
+       u8      hob_lbal;
+       u8      hob_lbam;
+       u8      hob_lbah;
+
+       u8      data;           /*  6: low data byte (for TASKFILE IOCTL) */
+
+       union {                 /*  7: */
+               u8 error;       /*   read:  error */
+               u8 feature;     /*  write: feature */
+       };
+
+       u8      nsect;          /*  8: number of sectors */
+       u8      lbal;           /*  9: LBA low */
+       u8      lbam;           /* 10: LBA mid */
+       u8      lbah;           /* 11: LBA high */
+
+       u8      device;         /* 12: device select */
+
+       union {                 /* 13: */
+               u8 status;      /*  read: status  */
+               u8 command;     /* write: command */
+       };
+};
+
+typedef struct ide_task_s {
+       union {
+               struct ide_taskfile     tf;
+               u8                      tf_array[14];
+       };
+       u32                     tf_flags;
+       int                     data_phase;
+       struct request          *rq;            /* copy of request */
+       void                    *special;       /* valid_t generally */
+} ide_task_t;
+
 /* ATAPI packet command flags */
 enum {
        /* set when an error is considered normal - no retry (ide-tape) */
@@ -301,6 +395,7 @@ enum {
  * This is used for several packet commands (not for READ/WRITE commands).
  */
 #define IDE_PC_BUFFER_SIZE     256
+#define ATAPI_WAIT_PC          (60 * HZ)
 
 struct ide_atapi_pc {
        /* actual packet bytes */
@@ -355,68 +450,76 @@ struct ide_acpi_drive_link;
 struct ide_acpi_hwif_link;
 #endif
 
+struct ide_drive_s;
+
+struct ide_disk_ops {
+       int             (*check)(struct ide_drive_s *, const char *);
+       int             (*get_capacity)(struct ide_drive_s *);
+       void            (*setup)(struct ide_drive_s *);
+       void            (*flush)(struct ide_drive_s *);
+       int             (*init_media)(struct ide_drive_s *, struct gendisk *);
+       int             (*set_doorlock)(struct ide_drive_s *, struct gendisk *,
+                                       int);
+       ide_startstop_t (*do_request)(struct ide_drive_s *, struct request *,
+                                     sector_t);
+       int             (*end_request)(struct ide_drive_s *, int, int);
+       int             (*ioctl)(struct ide_drive_s *, struct block_device *,
+                                fmode_t, unsigned int, unsigned long);
+};
+
 /* ATAPI device flags */
 enum {
        IDE_AFLAG_DRQ_INTERRUPT         = (1 << 0),
-       IDE_AFLAG_MEDIA_CHANGED         = (1 << 1),
-       /* Drive cannot lock the door. */
-       IDE_AFLAG_NO_DOORLOCK           = (1 << 2),
 
        /* ide-cd */
        /* Drive cannot eject the disc. */
-       IDE_AFLAG_NO_EJECT              = (1 << 3),
+       IDE_AFLAG_NO_EJECT              = (1 << 1),
        /* Drive is a pre ATAPI 1.2 drive. */
-       IDE_AFLAG_PRE_ATAPI12           = (1 << 4),
+       IDE_AFLAG_PRE_ATAPI12           = (1 << 2),
        /* TOC addresses are in BCD. */
-       IDE_AFLAG_TOCADDR_AS_BCD        = (1 << 5),
+       IDE_AFLAG_TOCADDR_AS_BCD        = (1 << 3),
        /* TOC track numbers are in BCD. */
-       IDE_AFLAG_TOCTRACKS_AS_BCD      = (1 << 6),
+       IDE_AFLAG_TOCTRACKS_AS_BCD      = (1 << 4),
        /*
         * Drive does not provide data in multiples of SECTOR_SIZE
         * when more than one interrupt is needed.
         */
-       IDE_AFLAG_LIMIT_NFRAMES         = (1 << 7),
-       /* Seeking in progress. */
-       IDE_AFLAG_SEEKING               = (1 << 8),
+       IDE_AFLAG_LIMIT_NFRAMES         = (1 << 5),
        /* Saved TOC information is current. */
-       IDE_AFLAG_TOC_VALID             = (1 << 9),
+       IDE_AFLAG_TOC_VALID             = (1 << 6),
        /* We think that the drive door is locked. */
-       IDE_AFLAG_DOOR_LOCKED           = (1 << 10),
+       IDE_AFLAG_DOOR_LOCKED           = (1 << 7),
        /* SET_CD_SPEED command is unsupported. */
-       IDE_AFLAG_NO_SPEED_SELECT       = (1 << 11),
-       IDE_AFLAG_VERTOS_300_SSD        = (1 << 12),
-       IDE_AFLAG_VERTOS_600_ESD        = (1 << 13),
-       IDE_AFLAG_SANYO_3CD             = (1 << 14),
-       IDE_AFLAG_FULL_CAPS_PAGE        = (1 << 15),
-       IDE_AFLAG_PLAY_AUDIO_OK         = (1 << 16),
-       IDE_AFLAG_LE_SPEED_FIELDS       = (1 << 17),
+       IDE_AFLAG_NO_SPEED_SELECT       = (1 << 8),
+       IDE_AFLAG_VERTOS_300_SSD        = (1 << 9),
+       IDE_AFLAG_VERTOS_600_ESD        = (1 << 10),
+       IDE_AFLAG_SANYO_3CD             = (1 << 11),
+       IDE_AFLAG_FULL_CAPS_PAGE        = (1 << 12),
+       IDE_AFLAG_PLAY_AUDIO_OK         = (1 << 13),
+       IDE_AFLAG_LE_SPEED_FIELDS       = (1 << 14),
 
        /* ide-floppy */
-       /* Format in progress */
-       IDE_AFLAG_FORMAT_IN_PROGRESS    = (1 << 18),
        /* Avoid commands not supported in Clik drive */
-       IDE_AFLAG_CLIK_DRIVE            = (1 << 19),
+       IDE_AFLAG_CLIK_DRIVE            = (1 << 15),
        /* Requires BH algorithm for packets */
-       IDE_AFLAG_ZIP_DRIVE             = (1 << 20),
-       /* Write protect */
-       IDE_AFLAG_WP                    = (1 << 21),
+       IDE_AFLAG_ZIP_DRIVE             = (1 << 16),
        /* Supports format progress report */
-       IDE_AFLAG_SRFP                  = (1 << 22),
+       IDE_AFLAG_SRFP                  = (1 << 17),
 
        /* ide-tape */
-       IDE_AFLAG_IGNORE_DSC            = (1 << 23),
+       IDE_AFLAG_IGNORE_DSC            = (1 << 18),
        /* 0 When the tape position is unknown */
-       IDE_AFLAG_ADDRESS_VALID         = (1 << 24),
+       IDE_AFLAG_ADDRESS_VALID         = (1 << 19),
        /* Device already opened */
-       IDE_AFLAG_BUSY                  = (1 << 25),
+       IDE_AFLAG_BUSY                  = (1 << 20),
        /* Attempt to auto-detect the current user block size */
-       IDE_AFLAG_DETECT_BS             = (1 << 26),
+       IDE_AFLAG_DETECT_BS             = (1 << 21),
        /* Currently on a filemark */
-       IDE_AFLAG_FILEMARK              = (1 << 27),
+       IDE_AFLAG_FILEMARK              = (1 << 22),
        /* 0 = no tape is loaded, so we don't rewind after ejecting */
-       IDE_AFLAG_MEDIUM_PRESENT        = (1 << 28),
+       IDE_AFLAG_MEDIUM_PRESENT        = (1 << 23),
 
-       IDE_AFLAG_NO_AUTOCLOSE          = (1 << 29),
+       IDE_AFLAG_NO_AUTOCLOSE          = (1 << 24),
 };
 
 /* device flags */
@@ -455,20 +558,26 @@ enum {
        IDE_DFLAG_NODMA                 = (1 << 16),
        /* powermanagment told us not to do anything, so sleep nicely */
        IDE_DFLAG_BLOCKED               = (1 << 17),
-       /* ide-scsi emulation */
-       IDE_DFLAG_SCSI                  = (1 << 18),
        /* sleeping & sleep field valid */
-       IDE_DFLAG_SLEEPING              = (1 << 19),
-       IDE_DFLAG_POST_RESET            = (1 << 20),
-       IDE_DFLAG_UDMA33_WARNED         = (1 << 21),
-       IDE_DFLAG_LBA48                 = (1 << 22),
+       IDE_DFLAG_SLEEPING              = (1 << 18),
+       IDE_DFLAG_POST_RESET            = (1 << 19),
+       IDE_DFLAG_UDMA33_WARNED         = (1 << 20),
+       IDE_DFLAG_LBA48                 = (1 << 21),
        /* status of write cache */
-       IDE_DFLAG_WCACHE                = (1 << 23),
+       IDE_DFLAG_WCACHE                = (1 << 22),
        /* used for ignoring ATA_DF */
-       IDE_DFLAG_NOWERR                = (1 << 24),
+       IDE_DFLAG_NOWERR                = (1 << 23),
        /* retrying in PIO */
-       IDE_DFLAG_DMA_PIO_RETRY         = (1 << 25),
-       IDE_DFLAG_LBA                   = (1 << 26),
+       IDE_DFLAG_DMA_PIO_RETRY         = (1 << 24),
+       IDE_DFLAG_LBA                   = (1 << 25),
+       /* don't unload heads */
+       IDE_DFLAG_NO_UNLOAD             = (1 << 26),
+       /* heads unloaded, please don't reset port */
+       IDE_DFLAG_PARKED                = (1 << 27),
+       IDE_DFLAG_MEDIA_CHANGED         = (1 << 28),
+       /* write protect */
+       IDE_DFLAG_WP                    = (1 << 29),
+       IDE_DFLAG_FORMAT_IN_PROGRESS    = (1 << 30),
 };
 
 struct ide_drive_s {
@@ -478,7 +587,6 @@ struct ide_drive_s {
        struct request_queue    *queue; /* request queue */
 
        struct request          *rq;    /* current request */
-       struct ide_drive_s      *next;  /* circular list of hwgroup drives */
        void            *driver_data;   /* extra driver data */
        u16                     *id;    /* identification info */
 #ifdef CONFIG_IDE_PROC_FS
@@ -487,11 +595,11 @@ struct ide_drive_s {
 #endif
        struct hwif_s           *hwif;  /* actually (ide_hwif_t *) */
 
+       const struct ide_disk_ops *disk_ops;
+
        unsigned long dev_flags;
 
        unsigned long sleep;            /* sleep until this time */
-       unsigned long service_start;    /* time we started last request */
-       unsigned long service_time;     /* service time of last request */
        unsigned long timeout;          /* max time to wait for irq */
 
        special_t       special;        /* special action flags */
@@ -499,6 +607,7 @@ struct ide_drive_s {
        u8      select;                 /* basic drive/head select reg value */
        u8      retry_pio;              /* retrying dma capable host in pio */
        u8      waiting_for_dma;        /* dma currently in progress */
+       u8      dma;                    /* atapi dma flag */
 
         u8     quirk_list;     /* considered quirky, set for a specific host */
         u8     init_speed;     /* transfer rate set at boot */
@@ -567,7 +676,6 @@ typedef struct ide_drive_s ide_drive_t;
 #define ide_drv_g(disk, cont_type)     \
        container_of((disk)->private_data, struct cont_type, driver)
 
-struct ide_task_s;
 struct ide_port_info;
 
 struct ide_tp_ops {
@@ -601,6 +709,7 @@ extern const struct ide_tp_ops default_tp_ops;
  * @resetproc:         routine to reset controller after a disk reset
  * @maskproc:          special host masking for drive selection
  * @quirkproc:         check host's drive quirk list
+ * @clear_irq:         clear IRQ
  *
  * @mdma_filter:       filter MDMA modes
  * @udma_filter:       filter UDMA modes
@@ -617,6 +726,7 @@ struct ide_port_ops {
        void    (*resetproc)(ide_drive_t *);
        void    (*maskproc)(ide_drive_t *, int);
        void    (*quirkproc)(ide_drive_t *);
+       void    (*clear_irq)(ide_drive_t *);
 
        u8      (*mdma_filter)(ide_drive_t *);
        u8      (*udma_filter)(ide_drive_t *);
@@ -638,9 +748,7 @@ struct ide_dma_ops {
 struct ide_host;
 
 typedef struct hwif_s {
-       struct hwif_s *next;            /* for linked-list in ide_hwgroup_t */
        struct hwif_s *mate;            /* other hwif from same PCI chip */
-       struct hwgroup_s *hwgroup;      /* actually (ide_hwgroup_t *) */
        struct proc_dir_entry *proc;    /* /proc/ide/ directory entry */
 
        struct ide_host *host;
@@ -679,12 +787,16 @@ typedef struct hwif_s {
        const struct ide_port_ops       *port_ops;
        const struct ide_dma_ops        *dma_ops;
 
-       void (*ide_dma_clear_irq)(ide_drive_t *drive);
-
        /* dma physical region descriptor table (cpu view) */
        unsigned int    *dmatable_cpu;
        /* dma physical region descriptor table (dma view) */
        dma_addr_t      dmatable_dma;
+
+       /* maximum number of PRD table entries */
+       int prd_max_nents;
+       /* PRD entry size in bytes */
+       int prd_ent_size;
+
        /* Scatter-gather list used to build the above */
        struct scatterlist *sg_table;
        int sg_max_nents;               /* Maximum number of entries in it */
@@ -694,6 +806,8 @@ typedef struct hwif_s {
        /* data phase of the active command (currently only valid for PIO/DMA) */
        int             data_phase;
 
+       struct ide_task_s task;         /* current command */
+
        unsigned int nsect;
        unsigned int nleft;
        struct scatterlist *cursg;
@@ -711,9 +825,8 @@ typedef struct hwif_s {
        unsigned        extra_ports;    /* number of extra dma ports */
 
        unsigned        present    : 1; /* this interface exists */
-       unsigned        serialized : 1; /* serialized all channel operation */
-       unsigned        sharing_irq: 1; /* 1 = sharing irq with another hwif */
        unsigned        sg_mapped  : 1; /* sg_table and sg_nents are ready */
+       unsigned        busy       : 1; /* serializes devices on a port */
 
        struct device           gendev;
        struct device           *portdev;
@@ -725,17 +838,49 @@ typedef struct hwif_s {
 #ifdef CONFIG_BLK_DEV_IDEACPI
        struct ide_acpi_hwif_link *acpidata;
 #endif
+
+       /* IRQ handler, if active */
+       ide_startstop_t (*handler)(ide_drive_t *);
+
+       /* BOOL: polling active & poll_timeout field valid */
+       unsigned int polling : 1;
+
+       /* current drive */
+       ide_drive_t *cur_dev;
+
+       /* current request */
+       struct request *rq;
+
+       /* failsafe timer */
+       struct timer_list timer;
+       /* timeout value during long polls */
+       unsigned long poll_timeout;
+       /* queried upon timeouts */
+       int (*expiry)(ide_drive_t *);
+
+       int req_gen;
+       int req_gen_timer;
+
+       spinlock_t lock;
 } ____cacheline_internodealigned_in_smp ide_hwif_t;
 
+#define MAX_HOST_PORTS 4
+
 struct ide_host {
-       ide_hwif_t      *ports[MAX_HWIFS];
+       ide_hwif_t      *ports[MAX_HOST_PORTS];
        unsigned int    n_ports;
        struct device   *dev[2];
        unsigned int    (*init_chipset)(struct pci_dev *);
        unsigned long   host_flags;
        void            *host_priv;
+       ide_hwif_t      *cur_port;      /* for hosts requiring serialization */
+
+       /* used for hosts requiring serialization */
+       volatile long   host_busy;
 };
 
+#define IDE_HOST_BUSY 0
+
 /*
  *  internal ide interrupt handler type
  */
@@ -745,36 +890,6 @@ typedef int (ide_expiry_t)(ide_drive_t *);
 /* used by ide-cd, ide-floppy, etc. */
 typedef void (xfer_func_t)(ide_drive_t *, struct request *rq, void *, unsigned);
 
-typedef struct hwgroup_s {
-               /* irq handler, if active */
-       ide_startstop_t (*handler)(ide_drive_t *);
-
-               /* BOOL: protects all fields below */
-       volatile int busy;
-               /* BOOL: wake us up on timer expiry */
-       unsigned int sleeping   : 1;
-               /* BOOL: polling active & poll_timeout field valid */
-       unsigned int polling    : 1;
-
-               /* current drive */
-       ide_drive_t *drive;
-               /* ptr to current hwif in linked-list */
-       ide_hwif_t *hwif;
-
-               /* current request */
-       struct request *rq;
-
-               /* failsafe timer */
-       struct timer_list timer;
-               /* timeout value during long polls */
-       unsigned long poll_timeout;
-               /* queried upon timeouts */
-       int (*expiry)(ide_drive_t *);
-
-       int req_gen;
-       int req_gen_timer;
-} ide_hwgroup_t;
-
 typedef struct ide_driver_s ide_driver_t;
 
 extern struct mutex ide_setting_mtx;
@@ -839,8 +954,11 @@ IDE_DEVSET(_name, 0, get_##_func, set_##_func)
 #define ide_devset_w(_name, _func) \
 IDE_DEVSET(_name, 0, NULL, set_##_func)
 
-#define ide_devset_rw_sync(_name, _func) \
-IDE_DEVSET(_name, DS_SYNC, get_##_func, set_##_func)
+#define ide_ext_devset_rw(_name, _func) \
+__IDE_DEVSET(_name, 0, get_##_func, set_##_func)
+
+#define ide_ext_devset_rw_sync(_name, _func) \
+__IDE_DEVSET(_name, DS_SYNC, get_##_func, set_##_func)
 
 #define ide_decl_devset(_name) \
 extern const struct ide_devset ide_devset_##_name
@@ -983,6 +1101,14 @@ enum {
        IDE_PM_COMPLETED,
 };
 
+int generic_ide_suspend(struct device *, pm_message_t);
+int generic_ide_resume(struct device *);
+
+void ide_complete_power_step(ide_drive_t *, struct request *);
+ide_startstop_t ide_start_power_step(ide_drive_t *, struct request *);
+void ide_complete_pm_request(ide_drive_t *, struct request *);
+void ide_check_pm_state(ide_drive_t *, struct request *);
+
 /*
  * Subdrivers support.
  *
@@ -1000,8 +1126,8 @@ struct ide_driver_s {
        void            (*resume)(ide_drive_t *);
        void            (*shutdown)(ide_drive_t *);
 #ifdef CONFIG_IDE_PROC_FS
-       ide_proc_entry_t                *proc;
-       const struct ide_proc_devset    *settings;
+       ide_proc_entry_t *              (*proc_entries)(ide_drive_t *);
+       const struct ide_proc_devset *  (*proc_devsets)(ide_drive_t *);
 #endif
 };
 
@@ -1019,8 +1145,7 @@ struct ide_ioctl_devset {
 int ide_setting_ioctl(ide_drive_t *, struct block_device *, unsigned int,
                      unsigned long, const struct ide_ioctl_devset *);
 
-int generic_ide_ioctl(ide_drive_t *, struct file *, struct block_device *,
-                     unsigned, unsigned long);
+int generic_ide_ioctl(ide_drive_t *, struct block_device *, unsigned, unsigned long);
 
 extern int ide_vlb_clk;
 extern int ide_pci_clk;
@@ -1059,110 +1184,6 @@ extern void ide_do_drive_cmd(ide_drive_t *, struct request *);
 
 extern void ide_end_drive_cmd(ide_drive_t *, u8, u8);
 
-enum {
-       IDE_TFLAG_LBA48                 = (1 << 0),
-       IDE_TFLAG_FLAGGED               = (1 << 2),
-       IDE_TFLAG_OUT_DATA              = (1 << 3),
-       IDE_TFLAG_OUT_HOB_FEATURE       = (1 << 4),
-       IDE_TFLAG_OUT_HOB_NSECT         = (1 << 5),
-       IDE_TFLAG_OUT_HOB_LBAL          = (1 << 6),
-       IDE_TFLAG_OUT_HOB_LBAM          = (1 << 7),
-       IDE_TFLAG_OUT_HOB_LBAH          = (1 << 8),
-       IDE_TFLAG_OUT_HOB               = IDE_TFLAG_OUT_HOB_FEATURE |
-                                         IDE_TFLAG_OUT_HOB_NSECT |
-                                         IDE_TFLAG_OUT_HOB_LBAL |
-                                         IDE_TFLAG_OUT_HOB_LBAM |
-                                         IDE_TFLAG_OUT_HOB_LBAH,
-       IDE_TFLAG_OUT_FEATURE           = (1 << 9),
-       IDE_TFLAG_OUT_NSECT             = (1 << 10),
-       IDE_TFLAG_OUT_LBAL              = (1 << 11),
-       IDE_TFLAG_OUT_LBAM              = (1 << 12),
-       IDE_TFLAG_OUT_LBAH              = (1 << 13),
-       IDE_TFLAG_OUT_TF                = IDE_TFLAG_OUT_FEATURE |
-                                         IDE_TFLAG_OUT_NSECT |
-                                         IDE_TFLAG_OUT_LBAL |
-                                         IDE_TFLAG_OUT_LBAM |
-                                         IDE_TFLAG_OUT_LBAH,
-       IDE_TFLAG_OUT_DEVICE            = (1 << 14),
-       IDE_TFLAG_WRITE                 = (1 << 15),
-       IDE_TFLAG_FLAGGED_SET_IN_FLAGS  = (1 << 16),
-       IDE_TFLAG_IN_DATA               = (1 << 17),
-       IDE_TFLAG_CUSTOM_HANDLER        = (1 << 18),
-       IDE_TFLAG_DMA_PIO_FALLBACK      = (1 << 19),
-       IDE_TFLAG_IN_HOB_FEATURE        = (1 << 20),
-       IDE_TFLAG_IN_HOB_NSECT          = (1 << 21),
-       IDE_TFLAG_IN_HOB_LBAL           = (1 << 22),
-       IDE_TFLAG_IN_HOB_LBAM           = (1 << 23),
-       IDE_TFLAG_IN_HOB_LBAH           = (1 << 24),
-       IDE_TFLAG_IN_HOB_LBA            = IDE_TFLAG_IN_HOB_LBAL |
-                                         IDE_TFLAG_IN_HOB_LBAM |
-                                         IDE_TFLAG_IN_HOB_LBAH,
-       IDE_TFLAG_IN_HOB                = IDE_TFLAG_IN_HOB_FEATURE |
-                                         IDE_TFLAG_IN_HOB_NSECT |
-                                         IDE_TFLAG_IN_HOB_LBA,
-       IDE_TFLAG_IN_FEATURE            = (1 << 1),
-       IDE_TFLAG_IN_NSECT              = (1 << 25),
-       IDE_TFLAG_IN_LBAL               = (1 << 26),
-       IDE_TFLAG_IN_LBAM               = (1 << 27),
-       IDE_TFLAG_IN_LBAH               = (1 << 28),
-       IDE_TFLAG_IN_LBA                = IDE_TFLAG_IN_LBAL |
-                                         IDE_TFLAG_IN_LBAM |
-                                         IDE_TFLAG_IN_LBAH,
-       IDE_TFLAG_IN_TF                 = IDE_TFLAG_IN_NSECT |
-                                         IDE_TFLAG_IN_LBA,
-       IDE_TFLAG_IN_DEVICE             = (1 << 29),
-       IDE_TFLAG_HOB                   = IDE_TFLAG_OUT_HOB |
-                                         IDE_TFLAG_IN_HOB,
-       IDE_TFLAG_TF                    = IDE_TFLAG_OUT_TF |
-                                         IDE_TFLAG_IN_TF,
-       IDE_TFLAG_DEVICE                = IDE_TFLAG_OUT_DEVICE |
-                                         IDE_TFLAG_IN_DEVICE,
-       /* force 16-bit I/O operations */
-       IDE_TFLAG_IO_16BIT              = (1 << 30),
-       /* ide_task_t was allocated using kmalloc() */
-       IDE_TFLAG_DYN                   = (1 << 31),
-};
-
-struct ide_taskfile {
-       u8      hob_data;       /*  0: high data byte (for TASKFILE IOCTL) */
-
-       u8      hob_feature;    /*  1-5: additional data to support LBA48 */
-       u8      hob_nsect;
-       u8      hob_lbal;
-       u8      hob_lbam;
-       u8      hob_lbah;
-
-       u8      data;           /*  6: low data byte (for TASKFILE IOCTL) */
-
-       union {                 /*  7: */
-               u8 error;       /*   read:  error */
-               u8 feature;     /*  write: feature */
-       };
-
-       u8      nsect;          /*  8: number of sectors */
-       u8      lbal;           /*  9: LBA low */
-       u8      lbam;           /* 10: LBA mid */
-       u8      lbah;           /* 11: LBA high */
-
-       u8      device;         /* 12: device select */
-
-       union {                 /* 13: */
-               u8 status;      /*  read: status  */
-               u8 command;     /* write: command */
-       };
-};
-
-typedef struct ide_task_s {
-       union {
-               struct ide_taskfile     tf;
-               u8                      tf_array[14];
-       };
-       u32                     tf_flags;
-       int                     data_phase;
-       struct request          *rq;            /* copy of request */
-       void                    *special;       /* valid_t generally */
-} ide_task_t;
-
 void ide_tf_dump(const char *, struct ide_taskfile *);
 
 void ide_exec_command(ide_hwif_t *, u8);
@@ -1194,6 +1215,13 @@ int ide_check_atapi_device(ide_drive_t *, const char *);
 
 void ide_init_pc(struct ide_atapi_pc *);
 
+/* Disk head parking */
+extern wait_queue_head_t ide_park_wq;
+ssize_t ide_park_show(struct device *dev, struct device_attribute *attr,
+                     char *buf);
+ssize_t ide_park_store(struct device *dev, struct device_attribute *attr,
+                      const char *buf, size_t len);
+
 /*
  * Special requests for ide-tape block device strategy routine.
  *
@@ -1215,14 +1243,11 @@ int ide_set_media_lock(ide_drive_t *, struct gendisk *, int);
 void ide_create_request_sense_cmd(ide_drive_t *, struct ide_atapi_pc *);
 void ide_retry_pc(ide_drive_t *, struct gendisk *);
 
-static inline unsigned long ide_scsi_get_timeout(struct ide_atapi_pc *pc)
-{
-       return max_t(unsigned long, WAIT_CMD, pc->timeout - jiffies);
-}
+int ide_cd_expiry(ide_drive_t *);
 
-int ide_scsi_expiry(ide_drive_t *);
+int ide_cd_get_xferlen(struct request *);
 
-ide_startstop_t ide_issue_pc(ide_drive_t *, unsigned int, ide_expiry_t *);
+ide_startstop_t ide_issue_pc(ide_drive_t *);
 
 ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *);
 
@@ -1255,6 +1280,13 @@ extern int __ide_pci_register_driver(struct pci_driver *driver, struct module *o
 #define ide_pci_register_driver(d) pci_register_driver(d)
 #endif
 
+static inline int ide_pci_is_in_compatibility_mode(struct pci_dev *dev)
+{
+       if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && (dev->class & 5) != 5)
+               return 1;
+       return 0;
+}
+
 void ide_pci_setup_ports(struct pci_dev *, const struct ide_port_info *, int,
                         hw_regs_t *, hw_regs_t **);
 void ide_setup_pci_noise(struct pci_dev *, const struct ide_port_info *);
@@ -1328,12 +1360,13 @@ enum {
        IDE_HFLAG_LEGACY_IRQS           = (1 << 21),
        /* force use of legacy IRQs */
        IDE_HFLAG_FORCE_LEGACY_IRQS     = (1 << 22),
-       /* limit LBA48 requests to 256 sectors */
-       IDE_HFLAG_RQSIZE_256            = (1 << 23),
+       /* host is TRM290 */
+       IDE_HFLAG_TRM290                = (1 << 23),
        /* use 32-bit I/O ops */
        IDE_HFLAG_IO_32BIT              = (1 << 24),
        /* unmask IRQs */
        IDE_HFLAG_UNMASK_IRQS           = (1 << 25),
+       IDE_HFLAG_BROKEN_ALTSTATUS      = (1 << 26),
        /* serialize ports if DMA is possible (for sl82c105) */
        IDE_HFLAG_SERIALIZE_DMA         = (1 << 27),
        /* force host out of "simplex" mode */
@@ -1366,6 +1399,9 @@ struct ide_port_info {
 
        ide_pci_enablebit_t     enablebits[2];
        hwif_chipset_t          chipset;
+
+       u16                     max_sectors;    /* if < than the default one */
+
        u32                     host_flags;
        u8                      pio_mask;
        u8                      swdma_mask;
@@ -1400,6 +1436,7 @@ struct drive_list_entry {
 int ide_in_drive_list(u16 *, const struct drive_list_entry *);
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
+int ide_dma_good_drive(ide_drive_t *);
 int __ide_dma_bad_drive(ide_drive_t *);
 int ide_id_dma_bug(ide_drive_t *);
 
@@ -1417,25 +1454,29 @@ int ide_set_dma(ide_drive_t *);
 void ide_check_dma_crc(ide_drive_t *);
 ide_startstop_t ide_dma_intr(ide_drive_t *);
 
+int ide_allocate_dma_engine(ide_hwif_t *);
+void ide_release_dma_engine(ide_hwif_t *);
+
 int ide_build_sglist(ide_drive_t *, struct request *);
 void ide_destroy_dmatable(ide_drive_t *);
 
 #ifdef CONFIG_BLK_DEV_IDEDMA_SFF
+int config_drive_for_dma(ide_drive_t *);
 extern int ide_build_dmatable(ide_drive_t *, struct request *);
-int ide_allocate_dma_engine(ide_hwif_t *);
-void ide_release_dma_engine(ide_hwif_t *);
-
 void ide_dma_host_set(ide_drive_t *, int);
 extern int ide_dma_setup(ide_drive_t *);
 void ide_dma_exec_cmd(ide_drive_t *, u8);
 extern void ide_dma_start(ide_drive_t *);
-extern int __ide_dma_end(ide_drive_t *);
+int ide_dma_end(ide_drive_t *);
 int ide_dma_test_irq(ide_drive_t *);
-extern void ide_dma_lost_irq(ide_drive_t *);
-extern void ide_dma_timeout(ide_drive_t *);
 extern const struct ide_dma_ops sff_dma_ops;
+#else
+static inline int config_drive_for_dma(ide_drive_t *drive) { return 0; }
 #endif /* CONFIG_BLK_DEV_IDEDMA_SFF */
 
+void ide_dma_lost_irq(ide_drive_t *);
+void ide_dma_timeout(ide_drive_t *);
+
 #else
 static inline int ide_id_dma_bug(ide_drive_t *drive) { return 0; }
 static inline u8 ide_find_dma_mode(ide_drive_t *drive, u8 speed) { return 0; }
@@ -1446,11 +1487,8 @@ static inline void ide_dma_on(ide_drive_t *drive) { ; }
 static inline void ide_dma_verbose(ide_drive_t *drive) { ; }
 static inline int ide_set_dma(ide_drive_t *drive) { return 1; }
 static inline void ide_check_dma_crc(ide_drive_t *drive) { ; }
-#endif /* CONFIG_BLK_DEV_IDEDMA */
-
-#ifndef CONFIG_BLK_DEV_IDEDMA_SFF
 static inline void ide_release_dma_engine(ide_hwif_t *hwif) { ; }
-#endif
+#endif /* CONFIG_BLK_DEV_IDEDMA */
 
 #ifdef CONFIG_BLK_DEV_IDEACPI
 extern int ide_acpi_exec_tfs(ide_drive_t *drive);
@@ -1468,7 +1506,6 @@ static inline void ide_acpi_port_init_devices(ide_hwif_t *hwif) { ; }
 static inline void ide_acpi_set_state(ide_hwif_t *hwif, int on) {}
 #endif
 
-void ide_remove_port_from_hwgroup(ide_hwif_t *);
 void ide_unregister(ide_hwif_t *);
 
 void ide_register_region(struct gendisk *);
@@ -1477,8 +1514,8 @@ void ide_unregister_region(struct gendisk *);
 void ide_undecoded_slave(ide_drive_t *);
 
 void ide_port_apply_params(ide_hwif_t *);
+int ide_sysfs_register_port(ide_hwif_t *);
 
-struct ide_host *ide_host_alloc_all(const struct ide_port_info *, hw_regs_t **);
 struct ide_host *ide_host_alloc(const struct ide_port_info *, hw_regs_t **);
 void ide_host_free(struct ide_host *);
 int ide_host_register(struct ide_host *, const struct ide_port_info *,
@@ -1557,21 +1594,12 @@ static inline void ide_set_max_pio(ide_drive_t *drive)
 
 extern spinlock_t ide_lock;
 extern struct mutex ide_cfg_mtx;
-/*
- * Structure locking:
- *
- * ide_cfg_mtx and ide_lock together protect changes to
- * ide_hwif_t->{next,hwgroup}
- * ide_drive_t->next
- *
- * ide_hwgroup_t->busy: ide_lock
- * ide_hwgroup_t->hwif: ide_lock
- * ide_hwif_t->mate: constant, no locking
- * ide_drive_t->hwif: constant, no locking
- */
 
 #define local_irq_set(flags)   do { local_save_flags((flags)); local_irq_enable_in_hardirq(); } while (0)
 
+char *ide_media_string(ide_drive_t *);
+
+extern struct device_attribute ide_dev_attrs[];
 extern struct bus_type ide_bus_type;
 extern struct class *ide_port_class;