*/
#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
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) */
/* 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_AFLAG_LE_SPEED_FIELDS = (1 << 17),
/* 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),
/* Requires BH algorithm for packets */
IDE_AFLAG_ZIP_DRIVE = (1 << 20),
- /* Write protect */
- IDE_AFLAG_WP = (1 << 21),
/* Supports format progress report */
IDE_AFLAG_SRFP = (1 << 22),
/* retrying in PIO */
IDE_DFLAG_DMA_PIO_RETRY = (1 << 25),
IDE_DFLAG_LBA = (1 << 26),
+ /* don't unload heads */
+ IDE_DFLAG_NO_UNLOAD = (1 << 27),
+ /* heads unloaded, please don't reset port */
+ IDE_DFLAG_PARKED = (1 << 28),
+ IDE_DFLAG_MEDIA_CHANGED = (1 << 29),
+ /* write protect */
+ IDE_DFLAG_WP = (1 << 30),
+ IDE_DFLAG_FORMAT_IN_PROGRESS = (1 << 31),
};
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 */
#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 {
* @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
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 *);
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 */
/* 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;
#endif
} ____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 *);
#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
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);
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.
*
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 *);
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; }
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);
void ide_port_apply_params(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 *,