|
@@ -48,12 +48,6 @@ typedef unsigned char byte; /* used everywhere */
|
|
|
#define ERROR_RESET 3 /* Reset controller every 4th retry */
|
|
|
#define ERROR_RECAL 1 /* Recalibrate every 2nd retry */
|
|
|
|
|
|
-/*
|
|
|
- * state flags
|
|
|
- */
|
|
|
-
|
|
|
-#define DMA_PIO_RETRY 1 /* retrying in PIO */
|
|
|
-
|
|
|
#define HWIF(drive) ((ide_hwif_t *)((drive)->hwif))
|
|
|
#define HWGROUP(drive) ((ide_hwgroup_t *)(HWIF(drive)->hwgroup))
|
|
|
|
|
@@ -162,6 +156,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
|
|
@@ -268,8 +264,6 @@ static inline int __ide_default_irq(unsigned long base)
|
|
|
* set_geometry : respecify drive geometry
|
|
|
* recalibrate : seek to cyl 0
|
|
|
* set_multmode : set multmode count
|
|
|
- * set_tune : tune interface for drive
|
|
|
- * serviced : service command
|
|
|
* reserved : unused
|
|
|
*/
|
|
|
typedef union {
|
|
@@ -278,42 +272,10 @@ typedef union {
|
|
|
unsigned set_geometry : 1;
|
|
|
unsigned recalibrate : 1;
|
|
|
unsigned set_multmode : 1;
|
|
|
- unsigned set_tune : 1;
|
|
|
- unsigned serviced : 1;
|
|
|
- unsigned reserved : 3;
|
|
|
+ unsigned reserved : 5;
|
|
|
} b;
|
|
|
} special_t;
|
|
|
|
|
|
-/*
|
|
|
- * ATA-IDE Select Register, aka Device-Head
|
|
|
- *
|
|
|
- * head : always zeros here
|
|
|
- * unit : drive select number: 0/1
|
|
|
- * bit5 : always 1
|
|
|
- * lba : using LBA instead of CHS
|
|
|
- * bit7 : always 1
|
|
|
- */
|
|
|
-typedef union {
|
|
|
- unsigned all : 8;
|
|
|
- struct {
|
|
|
-#if defined(__LITTLE_ENDIAN_BITFIELD)
|
|
|
- unsigned head : 4;
|
|
|
- unsigned unit : 1;
|
|
|
- unsigned bit5 : 1;
|
|
|
- unsigned lba : 1;
|
|
|
- unsigned bit7 : 1;
|
|
|
-#elif defined(__BIG_ENDIAN_BITFIELD)
|
|
|
- unsigned bit7 : 1;
|
|
|
- unsigned lba : 1;
|
|
|
- unsigned bit5 : 1;
|
|
|
- unsigned unit : 1;
|
|
|
- unsigned head : 4;
|
|
|
-#else
|
|
|
-#error "Please fix <asm/byteorder.h>"
|
|
|
-#endif
|
|
|
- } b;
|
|
|
-} select_t, ata_select_t;
|
|
|
-
|
|
|
/*
|
|
|
* Status returned from various ide_ functions
|
|
|
*/
|
|
@@ -322,6 +284,175 @@ 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) */
|
|
|
+ PC_FLAG_ABORT = (1 << 0),
|
|
|
+ PC_FLAG_SUPPRESS_ERROR = (1 << 1),
|
|
|
+ PC_FLAG_WAIT_FOR_DSC = (1 << 2),
|
|
|
+ PC_FLAG_DMA_OK = (1 << 3),
|
|
|
+ PC_FLAG_DMA_IN_PROGRESS = (1 << 4),
|
|
|
+ PC_FLAG_DMA_ERROR = (1 << 5),
|
|
|
+ PC_FLAG_WRITING = (1 << 6),
|
|
|
+ /* command timed out */
|
|
|
+ PC_FLAG_TIMEDOUT = (1 << 7),
|
|
|
+};
|
|
|
+
|
|
|
+/*
|
|
|
+ * With each packet command, we allocate a buffer of IDE_PC_BUFFER_SIZE bytes.
|
|
|
+ * This is used for several packet commands (not for READ/WRITE commands).
|
|
|
+ */
|
|
|
+#define IDE_PC_BUFFER_SIZE 256
|
|
|
+
|
|
|
+struct ide_atapi_pc {
|
|
|
+ /* actual packet bytes */
|
|
|
+ u8 c[12];
|
|
|
+ /* incremented on each retry */
|
|
|
+ int retries;
|
|
|
+ int error;
|
|
|
+
|
|
|
+ /* bytes to transfer */
|
|
|
+ int req_xfer;
|
|
|
+ /* bytes actually transferred */
|
|
|
+ int xferred;
|
|
|
+
|
|
|
+ /* data buffer */
|
|
|
+ u8 *buf;
|
|
|
+ /* current buffer position */
|
|
|
+ u8 *cur_pos;
|
|
|
+ int buf_size;
|
|
|
+ /* missing/available data on the current buffer */
|
|
|
+ int b_count;
|
|
|
+
|
|
|
+ /* the corresponding request */
|
|
|
+ struct request *rq;
|
|
|
+
|
|
|
+ unsigned long flags;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * those are more or less driver-specific and some of them are subject
|
|
|
+ * to change/removal later.
|
|
|
+ */
|
|
|
+ u8 pc_buf[IDE_PC_BUFFER_SIZE];
|
|
|
+
|
|
|
+ /* idetape only */
|
|
|
+ struct idetape_bh *bh;
|
|
|
+ char *b_data;
|
|
|
+
|
|
|
+ /* idescsi only for now */
|
|
|
+ struct scatterlist *sg;
|
|
|
+ unsigned int sg_cnt;
|
|
|
+
|
|
|
+ struct scsi_cmnd *scsi_cmd;
|
|
|
+ void (*done) (struct scsi_cmnd *);
|
|
|
+
|
|
|
+ unsigned long timeout;
|
|
|
+};
|
|
|
+
|
|
|
struct ide_devset;
|
|
|
struct ide_driver_s;
|
|
|
|
|
@@ -394,6 +525,62 @@ enum {
|
|
|
IDE_AFLAG_NO_AUTOCLOSE = (1 << 29),
|
|
|
};
|
|
|
|
|
|
+/* device flags */
|
|
|
+enum {
|
|
|
+ /* restore settings after device reset */
|
|
|
+ IDE_DFLAG_KEEP_SETTINGS = (1 << 0),
|
|
|
+ /* device is using DMA for read/write */
|
|
|
+ IDE_DFLAG_USING_DMA = (1 << 1),
|
|
|
+ /* okay to unmask other IRQs */
|
|
|
+ IDE_DFLAG_UNMASK = (1 << 2),
|
|
|
+ /* don't attempt flushes */
|
|
|
+ IDE_DFLAG_NOFLUSH = (1 << 3),
|
|
|
+ /* DSC overlap */
|
|
|
+ IDE_DFLAG_DSC_OVERLAP = (1 << 4),
|
|
|
+ /* give potential excess bandwidth */
|
|
|
+ IDE_DFLAG_NICE1 = (1 << 5),
|
|
|
+ /* device is physically present */
|
|
|
+ IDE_DFLAG_PRESENT = (1 << 6),
|
|
|
+ /* device ejected hint */
|
|
|
+ IDE_DFLAG_DEAD = (1 << 7),
|
|
|
+ /* id read from device (synthetic if not set) */
|
|
|
+ IDE_DFLAG_ID_READ = (1 << 8),
|
|
|
+ IDE_DFLAG_NOPROBE = (1 << 9),
|
|
|
+ /* need to do check_media_change() */
|
|
|
+ IDE_DFLAG_REMOVABLE = (1 << 10),
|
|
|
+ /* needed for removable devices */
|
|
|
+ IDE_DFLAG_ATTACH = (1 << 11),
|
|
|
+ IDE_DFLAG_FORCED_GEOM = (1 << 12),
|
|
|
+ /* disallow setting unmask bit */
|
|
|
+ IDE_DFLAG_NO_UNMASK = (1 << 13),
|
|
|
+ /* disallow enabling 32-bit I/O */
|
|
|
+ IDE_DFLAG_NO_IO_32BIT = (1 << 14),
|
|
|
+ /* for removable only: door lock/unlock works */
|
|
|
+ IDE_DFLAG_DOORLOCKING = (1 << 15),
|
|
|
+ /* disallow DMA */
|
|
|
+ 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),
|
|
|
+ /* status of write cache */
|
|
|
+ IDE_DFLAG_WCACHE = (1 << 23),
|
|
|
+ /* used for ignoring ATA_DF */
|
|
|
+ IDE_DFLAG_NOWERR = (1 << 24),
|
|
|
+ /* 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)
|
|
|
+};
|
|
|
+
|
|
|
struct ide_drive_s {
|
|
|
char name[4]; /* drive name, such as "hda" */
|
|
|
char driver_req[10]; /* requests specific driver */
|
|
@@ -410,43 +597,19 @@ struct ide_drive_s {
|
|
|
#endif
|
|
|
struct hwif_s *hwif; /* actually (ide_hwif_t *) */
|
|
|
|
|
|
+ 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 */
|
|
|
- select_t select; /* basic drive/head select reg value */
|
|
|
|
|
|
+ u8 select; /* basic drive/head select reg value */
|
|
|
u8 retry_pio; /* retrying dma capable host in pio */
|
|
|
- u8 state; /* retry state */
|
|
|
u8 waiting_for_dma; /* dma currently in progress */
|
|
|
-
|
|
|
- unsigned keep_settings : 1; /* restore settings after drive reset */
|
|
|
- unsigned using_dma : 1; /* disk is using dma for read/write */
|
|
|
- unsigned unmask : 1; /* okay to unmask other irqs */
|
|
|
- unsigned noflush : 1; /* don't attempt flushes */
|
|
|
- unsigned dsc_overlap : 1; /* DSC overlap */
|
|
|
- unsigned nice1 : 1; /* give potential excess bandwidth */
|
|
|
- unsigned present : 1; /* drive is physically present */
|
|
|
- unsigned dead : 1; /* device ejected hint */
|
|
|
- unsigned id_read : 1; /* 1=id read from disk 0 = synthetic */
|
|
|
- unsigned noprobe : 1; /* from: hdx=noprobe */
|
|
|
- unsigned removable : 1; /* 1 if need to do check_media_change */
|
|
|
- unsigned attach : 1; /* needed for removable devices */
|
|
|
- unsigned forced_geom : 1; /* 1 if hdx=c,h,s was given at boot */
|
|
|
- unsigned no_unmask : 1; /* disallow setting unmask bit */
|
|
|
- unsigned no_io_32bit : 1; /* disallow enabling 32bit I/O */
|
|
|
- unsigned doorlocking : 1; /* for removable only: door lock/unlock works */
|
|
|
- unsigned nodma : 1; /* disallow DMA */
|
|
|
- unsigned blocked : 1; /* 1=powermanagment told us not to do anything, so sleep nicely */
|
|
|
- unsigned scsi : 1; /* 0=default, 1=ide-scsi emulation */
|
|
|
- unsigned sleeping : 1; /* 1=sleeping & sleep field valid */
|
|
|
- unsigned post_reset : 1;
|
|
|
- unsigned udma33_warned : 1;
|
|
|
- unsigned addressing : 2; /* 0=28-bit, 1=48-bit, 2=48-bit doing 28-bit */
|
|
|
- unsigned wcache : 1; /* status of write cache */
|
|
|
- unsigned nowerr : 1; /* used for ignoring ATA_DF */
|
|
|
+ u8 dma; /* atapi dma flag */
|
|
|
|
|
|
u8 quirk_list; /* considered quirky, set for a specific host */
|
|
|
u8 init_speed; /* transfer rate set at boot */
|
|
@@ -458,7 +621,6 @@ struct ide_drive_s {
|
|
|
u8 ready_stat; /* min status value for drive ready */
|
|
|
u8 mult_count; /* current multiple sector setting */
|
|
|
u8 mult_req; /* requested multiple sector setting */
|
|
|
- u8 tune_req; /* requested drive tuning setting */
|
|
|
u8 io_32bit; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */
|
|
|
u8 bad_wstat; /* used for ignoring ATA_DF */
|
|
|
u8 head; /* "real" number of heads */
|
|
@@ -466,6 +628,9 @@ struct ide_drive_s {
|
|
|
u8 bios_head; /* BIOS/fdisk/LILO number of heads */
|
|
|
u8 bios_sect; /* BIOS/fdisk/LILO sectors per track */
|
|
|
|
|
|
+ /* delay this long before sending packet command */
|
|
|
+ u8 pc_delay;
|
|
|
+
|
|
|
unsigned int bios_cyl; /* BIOS/fdisk/LILO number of cyls */
|
|
|
unsigned int cyl; /* "real" number of cyls */
|
|
|
unsigned int drive_data; /* used by set_pio_mode/selectproc */
|
|
@@ -477,6 +642,9 @@ struct ide_drive_s {
|
|
|
|
|
|
int lun; /* logical unit */
|
|
|
int crc_count; /* crc counter to reduce drive speed */
|
|
|
+
|
|
|
+ unsigned long debug_mask; /* debugging levels switch */
|
|
|
+
|
|
|
#ifdef CONFIG_BLK_DEV_IDEACPI
|
|
|
struct ide_acpi_drive_link *acpidata;
|
|
|
#endif
|
|
@@ -484,17 +652,32 @@ struct ide_drive_s {
|
|
|
struct device gendev;
|
|
|
struct completion gendev_rel_comp; /* to deal with device release() */
|
|
|
|
|
|
+ /* current packet command */
|
|
|
+ struct ide_atapi_pc *pc;
|
|
|
+
|
|
|
/* callback for packet commands */
|
|
|
- void (*pc_callback)(struct ide_drive_s *);
|
|
|
+ void (*pc_callback)(struct ide_drive_s *, int);
|
|
|
+
|
|
|
+ void (*pc_update_buffers)(struct ide_drive_s *, struct ide_atapi_pc *);
|
|
|
+ int (*pc_io_buffers)(struct ide_drive_s *, struct ide_atapi_pc *,
|
|
|
+ unsigned int, int);
|
|
|
|
|
|
unsigned long atapi_flags;
|
|
|
+
|
|
|
+ struct ide_atapi_pc request_sense_pc;
|
|
|
+ struct request request_sense_rq;
|
|
|
};
|
|
|
|
|
|
typedef struct ide_drive_s ide_drive_t;
|
|
|
|
|
|
-#define to_ide_device(dev)container_of(dev, ide_drive_t, gendev)
|
|
|
+#define to_ide_device(dev) container_of(dev, ide_drive_t, gendev)
|
|
|
+
|
|
|
+#define to_ide_drv(obj, cont_type) \
|
|
|
+ container_of(obj, struct cont_type, kref)
|
|
|
+
|
|
|
+#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 {
|
|
@@ -528,6 +711,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
|
|
@@ -544,6 +728,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 *);
|
|
@@ -606,12 +791,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 */
|
|
@@ -621,6 +810,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;
|
|
@@ -649,15 +840,15 @@ typedef struct hwif_s {
|
|
|
|
|
|
void *hwif_data; /* extra hwif data */
|
|
|
|
|
|
- unsigned dma;
|
|
|
-
|
|
|
#ifdef CONFIG_BLK_DEV_IDEACPI
|
|
|
struct ide_acpi_hwif_link *acpidata;
|
|
|
#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 *);
|
|
@@ -739,6 +930,22 @@ static int set_##name(ide_drive_t *drive, int arg) \
|
|
|
return 0; \
|
|
|
}
|
|
|
|
|
|
+#define ide_devset_get_flag(name, flag) \
|
|
|
+static int get_##name(ide_drive_t *drive) \
|
|
|
+{ \
|
|
|
+ return !!(drive->dev_flags & flag); \
|
|
|
+}
|
|
|
+
|
|
|
+#define ide_devset_set_flag(name, flag) \
|
|
|
+static int set_##name(ide_drive_t *drive, int arg) \
|
|
|
+{ \
|
|
|
+ if (arg) \
|
|
|
+ drive->dev_flags |= flag; \
|
|
|
+ else \
|
|
|
+ drive->dev_flags &= ~flag; \
|
|
|
+ return 0; \
|
|
|
+}
|
|
|
+
|
|
|
#define __IDE_DEVSET(_name, _flags, _get, _set) \
|
|
|
const struct ide_devset ide_devset_##_name = \
|
|
|
__DEVSET(_flags, _get, _set)
|
|
@@ -752,8 +959,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
|
|
@@ -764,71 +974,6 @@ ide_decl_devset(pio_mode);
|
|
|
ide_decl_devset(unmaskirq);
|
|
|
ide_decl_devset(using_dma);
|
|
|
|
|
|
-/* ATAPI packet command flags */
|
|
|
-enum {
|
|
|
- /* set when an error is considered normal - no retry (ide-tape) */
|
|
|
- PC_FLAG_ABORT = (1 << 0),
|
|
|
- PC_FLAG_SUPPRESS_ERROR = (1 << 1),
|
|
|
- PC_FLAG_WAIT_FOR_DSC = (1 << 2),
|
|
|
- PC_FLAG_DMA_OK = (1 << 3),
|
|
|
- PC_FLAG_DMA_IN_PROGRESS = (1 << 4),
|
|
|
- PC_FLAG_DMA_ERROR = (1 << 5),
|
|
|
- PC_FLAG_WRITING = (1 << 6),
|
|
|
- /* command timed out */
|
|
|
- PC_FLAG_TIMEDOUT = (1 << 7),
|
|
|
-};
|
|
|
-
|
|
|
-/*
|
|
|
- * With each packet command, we allocate a buffer of IDE_PC_BUFFER_SIZE bytes.
|
|
|
- * This is used for several packet commands (not for READ/WRITE commands).
|
|
|
- */
|
|
|
-#define IDE_PC_BUFFER_SIZE 256
|
|
|
-
|
|
|
-struct ide_atapi_pc {
|
|
|
- /* actual packet bytes */
|
|
|
- u8 c[12];
|
|
|
- /* incremented on each retry */
|
|
|
- int retries;
|
|
|
- int error;
|
|
|
-
|
|
|
- /* bytes to transfer */
|
|
|
- int req_xfer;
|
|
|
- /* bytes actually transferred */
|
|
|
- int xferred;
|
|
|
-
|
|
|
- /* data buffer */
|
|
|
- u8 *buf;
|
|
|
- /* current buffer position */
|
|
|
- u8 *cur_pos;
|
|
|
- int buf_size;
|
|
|
- /* missing/available data on the current buffer */
|
|
|
- int b_count;
|
|
|
-
|
|
|
- /* the corresponding request */
|
|
|
- struct request *rq;
|
|
|
-
|
|
|
- unsigned long flags;
|
|
|
-
|
|
|
- /*
|
|
|
- * those are more or less driver-specific and some of them are subject
|
|
|
- * to change/removal later.
|
|
|
- */
|
|
|
- u8 pc_buf[IDE_PC_BUFFER_SIZE];
|
|
|
-
|
|
|
- /* idetape only */
|
|
|
- struct idetape_bh *bh;
|
|
|
- char *b_data;
|
|
|
-
|
|
|
- /* idescsi only for now */
|
|
|
- struct scatterlist *sg;
|
|
|
- unsigned int sg_cnt;
|
|
|
-
|
|
|
- struct scsi_cmnd *scsi_cmd;
|
|
|
- void (*done) (struct scsi_cmnd *);
|
|
|
-
|
|
|
- unsigned long timeout;
|
|
|
-};
|
|
|
-
|
|
|
#ifdef CONFIG_IDE_PROC_FS
|
|
|
/*
|
|
|
* /proc/ide interface
|
|
@@ -839,6 +984,11 @@ ide_devset_get(_name, _field); \
|
|
|
ide_devset_set(_name, _field); \
|
|
|
IDE_DEVSET(_name, DS_SYNC, get_##_name, set_##_name)
|
|
|
|
|
|
+#define ide_devset_rw_flag(_name, _field) \
|
|
|
+ide_devset_get_flag(_name, _field); \
|
|
|
+ide_devset_set_flag(_name, _field); \
|
|
|
+IDE_DEVSET(_name, DS_SYNC, get_##_name, set_##_name)
|
|
|
+
|
|
|
struct ide_proc_devset {
|
|
|
const char *name;
|
|
|
const struct ide_devset *setting;
|
|
@@ -905,37 +1055,55 @@ static inline void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t *
|
|
|
#define PROC_IDE_READ_RETURN(page,start,off,count,eof,len) return 0;
|
|
|
#endif
|
|
|
|
|
|
+enum {
|
|
|
+ /* enter/exit functions */
|
|
|
+ IDE_DBG_FUNC = (1 << 0),
|
|
|
+ /* sense key/asc handling */
|
|
|
+ IDE_DBG_SENSE = (1 << 1),
|
|
|
+ /* packet commands handling */
|
|
|
+ IDE_DBG_PC = (1 << 2),
|
|
|
+ /* request handling */
|
|
|
+ IDE_DBG_RQ = (1 << 3),
|
|
|
+ /* driver probing/setup */
|
|
|
+ IDE_DBG_PROBE = (1 << 4),
|
|
|
+};
|
|
|
+
|
|
|
+/* DRV_NAME has to be defined in the driver before using the macro below */
|
|
|
+#define __ide_debug_log(lvl, fmt, args...) \
|
|
|
+{ \
|
|
|
+ if (unlikely(drive->debug_mask & lvl)) \
|
|
|
+ printk(KERN_INFO DRV_NAME ": " fmt, ## args); \
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
- * Power Management step value (rq->pm->pm_step).
|
|
|
- *
|
|
|
- * The step value starts at 0 (ide_pm_state_start_suspend) for a
|
|
|
- * suspend operation or 1000 (ide_pm_state_start_resume) for a
|
|
|
- * resume operation.
|
|
|
+ * Power Management state machine (rq->pm->pm_step).
|
|
|
*
|
|
|
- * For each step, the core calls the subdriver start_power_step() first.
|
|
|
+ * For each step, the core calls ide_start_power_step() first.
|
|
|
* This can return:
|
|
|
* - ide_stopped : In this case, the core calls us back again unless
|
|
|
* step have been set to ide_power_state_completed.
|
|
|
* - ide_started : In this case, the channel is left busy until an
|
|
|
* async event (interrupt) occurs.
|
|
|
- * Typically, start_power_step() will issue a taskfile request with
|
|
|
+ * Typically, ide_start_power_step() will issue a taskfile request with
|
|
|
* do_rw_taskfile().
|
|
|
*
|
|
|
- * Upon reception of the interrupt, the core will call complete_power_step()
|
|
|
+ * Upon reception of the interrupt, the core will call ide_complete_power_step()
|
|
|
* with the error code if any. This routine should update the step value
|
|
|
* and return. It should not start a new request. The core will call
|
|
|
- * start_power_step for the new step value, unless step have been set to
|
|
|
- * ide_power_state_completed.
|
|
|
- *
|
|
|
- * Subdrivers are expected to define their own additional power
|
|
|
- * steps from 1..999 for suspend and from 1001..1999 for resume,
|
|
|
- * other values are reserved for future use.
|
|
|
+ * ide_start_power_step() for the new step value, unless step have been
|
|
|
+ * set to IDE_PM_COMPLETED.
|
|
|
*/
|
|
|
-
|
|
|
enum {
|
|
|
- ide_pm_state_completed = -1,
|
|
|
- ide_pm_state_start_suspend = 0,
|
|
|
- ide_pm_state_start_resume = 1000,
|
|
|
+ IDE_PM_START_SUSPEND,
|
|
|
+ IDE_PM_FLUSH_CACHE = IDE_PM_START_SUSPEND,
|
|
|
+ IDE_PM_STANDBY,
|
|
|
+
|
|
|
+ IDE_PM_START_RESUME,
|
|
|
+ IDE_PM_RESTORE_PIO = IDE_PM_START_RESUME,
|
|
|
+ IDE_PM_IDLE,
|
|
|
+ IDE_PM_RESTORE_DMA,
|
|
|
+
|
|
|
+ IDE_PM_COMPLETED,
|
|
|
};
|
|
|
|
|
|
/*
|
|
@@ -946,7 +1114,6 @@ enum {
|
|
|
*/
|
|
|
struct ide_driver_s {
|
|
|
const char *version;
|
|
|
- u8 media;
|
|
|
ide_startstop_t (*do_request)(ide_drive_t *, struct request *, sector_t);
|
|
|
int (*end_request)(ide_drive_t *, int, int);
|
|
|
ide_startstop_t (*error)(ide_drive_t *, struct request *rq, u8, u8);
|
|
@@ -1015,110 +1182,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);
|
|
@@ -1150,6 +1213,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.
|
|
|
*
|
|
@@ -1163,24 +1233,22 @@ enum {
|
|
|
REQ_IDETAPE_WRITE = (1 << 3),
|
|
|
};
|
|
|
|
|
|
-void ide_queue_pc_head(ide_drive_t *, struct gendisk *, struct ide_atapi_pc *,
|
|
|
- struct request *);
|
|
|
int ide_queue_pc_tail(ide_drive_t *, struct gendisk *, struct ide_atapi_pc *);
|
|
|
|
|
|
int ide_do_test_unit_ready(ide_drive_t *, struct gendisk *);
|
|
|
int ide_do_start_stop(ide_drive_t *, struct gendisk *, int);
|
|
|
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_scsi_expiry(ide_drive_t *);
|
|
|
|
|
|
-ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,
|
|
|
- ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry,
|
|
|
- void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *),
|
|
|
- void (*retry_pc)(ide_drive_t *), void (*dsc_handle)(ide_drive_t *),
|
|
|
- int (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned int,
|
|
|
- int));
|
|
|
-ide_startstop_t ide_transfer_pc(ide_drive_t *, struct ide_atapi_pc *,
|
|
|
- ide_handler_t *, unsigned int, ide_expiry_t *);
|
|
|
-ide_startstop_t ide_issue_pc(ide_drive_t *, struct ide_atapi_pc *,
|
|
|
- ide_handler_t *, unsigned int, ide_expiry_t *);
|
|
|
+ide_startstop_t ide_issue_pc(ide_drive_t *, unsigned int, ide_expiry_t *);
|
|
|
|
|
|
ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *);
|
|
|
|
|
@@ -1358,6 +1426,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 *);
|
|
|
|
|
@@ -1375,25 +1444,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; }
|
|
@@ -1404,11 +1477,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);
|
|
@@ -1436,7 +1506,6 @@ void ide_undecoded_slave(ide_drive_t *);
|
|
|
|
|
|
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 *,
|
|
@@ -1547,6 +1616,6 @@ static inline ide_drive_t *ide_get_pair_dev(ide_drive_t *drive)
|
|
|
{
|
|
|
ide_drive_t *peer = &drive->hwif->drives[(drive->dn ^ 1) & 1];
|
|
|
|
|
|
- return peer->present ? peer : NULL;
|
|
|
+ return (peer->dev_flags & IDE_DFLAG_PRESENT) ? peer : NULL;
|
|
|
}
|
|
|
#endif /* _IDE_H */
|