#include <asm/system.h>
#include <asm/io.h>
#include <asm/semaphore.h>
+#include <asm/mutex.h>
/******************************************************************************
* IDE driver configuration options (play with these as desired):
char name[4]; /* drive name, such as "hda" */
char driver_req[10]; /* requests specific driver */
- request_queue_t *queue; /* request queue */
+ struct request_queue *queue; /* request queue */
struct request *rq; /* current request */
struct ide_drive_s *next; /* circular list of hwgroup drives */
select_t select; /* basic drive/head select reg value */
u8 keep_settings; /* restore settings after drive reset */
- u8 autodma; /* device can safely use dma on host */
u8 using_dma; /* disk is using dma for read/write */
u8 retry_pio; /* retrying dma capable host in pio */
u8 state; /* retry state */
unsigned nice0 : 1; /* give obvious excess bandwidth */
unsigned nice2 : 1; /* give a share in our own bandwidth */
unsigned doorlocking : 1; /* for removable only: door lock/unlock works */
+ unsigned nodma : 1; /* disallow DMA */
unsigned autotune : 2; /* 0=default, 1=autotune, 2=noautotune */
unsigned remap_0_to_1 : 1; /* 0=noremap, 1=remap 0->1 (for EZDrive) */
unsigned blocked : 1; /* 1=powermanagment told us not to do anything, so sleep nicely */
unsigned int bios_cyl; /* BIOS/fdisk/LILO number of cyls */
unsigned int cyl; /* "real" number of cyls */
- unsigned int drive_data; /* use by tuneproc/selectproc */
+ unsigned int drive_data; /* used by set_pio_mode/selectproc */
unsigned int failures; /* current failure count */
unsigned int max_failures; /* maximum allowed failure count */
u64 probed_capacity;/* initial reported media capacity (ide-cd only currently) */
u8 straight8; /* Alan's straight 8 check */
u8 bus_state; /* power state of the IDE bus */
+ u16 host_flags;
+
+ u8 pio_mask;
+
u8 atapi_dma; /* host supports atapi_dma */
u8 ultra_mask;
u8 mwdma_mask;
u8 swdma_mask;
+ u8 cbl; /* cable type */
+
hwif_chipset_t chipset; /* sub-module for tuning.. */
struct pci_dev *pci_dev; /* for pci chipsets */
#if 0
ide_hwif_ops_t *hwifops;
#else
- /* routine to tune PIO mode for drives */
- void (*tuneproc)(ide_drive_t *, u8);
- /* routine to retune DMA modes for drives */
- int (*speedproc)(ide_drive_t *, u8);
+ /* routine to program host for PIO mode */
+ void (*set_pio_mode)(ide_drive_t *, const u8);
+ /* routine to program host for DMA mode */
+ void (*set_dma_mode)(ide_drive_t *, const u8);
/* tweaks hardware to select drive */
void (*selectproc)(ide_drive_t *);
/* chipset polling based on hba specifics */
/* driver soft-power interface */
int (*busproc)(ide_drive_t *, int);
#endif
+ u8 (*mdma_filter)(ide_drive_t *);
u8 (*udma_filter)(ide_drive_t *);
void (*ata_input_data)(ide_drive_t *, void *, u32);
void (*dma_exec_cmd)(ide_drive_t *, u8);
void (*dma_start)(ide_drive_t *);
int (*ide_dma_end)(ide_drive_t *drive);
- int (*ide_dma_check)(ide_drive_t *drive);
int (*ide_dma_on)(ide_drive_t *drive);
void (*dma_off_quietly)(ide_drive_t *drive);
int (*ide_dma_test_irq)(ide_drive_t *drive);
void (*ide_dma_clear_irq)(ide_drive_t *drive);
void (*dma_host_on)(ide_drive_t *drive);
void (*dma_host_off)(ide_drive_t *drive);
- int (*ide_dma_lostirq)(ide_drive_t *drive);
- int (*ide_dma_timeout)(ide_drive_t *drive);
+ void (*dma_lost_irq)(ide_drive_t *drive);
+ void (*dma_timeout)(ide_drive_t *drive);
void (*OUTB)(u8 addr, unsigned long port);
void (*OUTBSYNC)(ide_drive_t *drive, u8 addr, unsigned long port);
unsigned int nsect;
unsigned int nleft;
- unsigned int cursg;
+ struct scatterlist *cursg;
unsigned int cursg_ofs;
int rqsize; /* max sectors per request */
unsigned serialized : 1; /* serialized all channel operation */
unsigned sharing_irq: 1; /* 1 = sharing irq with another hwif */
unsigned reset : 1; /* reset after probe */
- unsigned autodma : 1; /* auto-attempt using DMA at boot */
- unsigned udma_four : 1; /* 1=ATA-66 capable, 0=default */
unsigned no_lba48 : 1; /* 1 = cannot do LBA48 */
unsigned no_lba48_dma : 1; /* 1 = cannot do LBA48 DMA */
unsigned auto_poll : 1; /* supports nop auto-poll */
typedef struct ide_driver_s ide_driver_t;
-extern struct semaphore ide_setting_sem;
+extern struct mutex ide_setting_mtx;
int set_io_32bit(ide_drive_t *, int);
int set_pio_mode(ide_drive_t *, int);
struct device_driver gen_driver;
int (*probe)(ide_drive_t *);
void (*remove)(ide_drive_t *);
+ void (*resume)(ide_drive_t *);
void (*shutdown)(ide_drive_t *);
#ifdef CONFIG_IDE_PROC_FS
ide_proc_entry_t *proc;
*/
extern void ide_fixstring(u8 *, const int, const int);
-/*
- * This routine busy-waits for the drive status to be not "busy".
- * It then checks the status for all of the "good" bits and none
- * of the "bad" bits, and if all is okay it returns 0. All other
- * cases return 1 after doing "*startstop = ide_error()", and the
- * caller should return the updated value of "startstop" in this case.
- * "startstop" is unchanged when the function returns 0;
- * (startstop, drive, good, bad, timeout)
- */
-extern int ide_wait_stat(ide_startstop_t *, ide_drive_t *, u8, u8, unsigned long);
+int ide_wait_stat(ide_startstop_t *, ide_drive_t *, u8, u8, unsigned long);
/*
* Start a reset operation for an IDE interface.
extern void ide_init_drive_cmd (struct request *rq);
/*
- * this function returns error location sector offset in case of a write error
- */
-extern u64 ide_get_error_location(ide_drive_t *, char *);
-
-/*
* "action" parameter type for ide_do_drive_cmd() below.
*/
typedef enum {
extern void QUIRK_LIST(ide_drive_t *);
extern int drive_is_ready(ide_drive_t *);
-extern int wait_for_ready(ide_drive_t *, int /* timeout */);
/*
* taskfile io for disks for now...and builds request from ide_ioctl
extern int ide_spin_wait_hwgroup(ide_drive_t *);
extern void ide_timer_expiry(unsigned long);
extern irqreturn_t ide_intr(int irq, void *dev_id);
-extern void do_ide_request(request_queue_t *);
+extern void do_ide_request(struct request_queue *);
void ide_init_disk(struct gendisk *, ide_drive_t *);
extern int ideprobe_init(void);
+#ifdef CONFIG_IDEPCI_PCIBUS_ORDER
extern void ide_scan_pcibus(int scan_direction) __init;
extern int __ide_pci_register_driver(struct pci_driver *driver, struct module *owner, const char *mod_name);
#define ide_pci_register_driver(d) __ide_pci_register_driver(d, THIS_MODULE, KBUILD_MODNAME)
+#else
+#define ide_pci_register_driver(d) pci_register_driver(d)
+#endif
+
void ide_pci_setup_ports(struct pci_dev *, struct ide_pci_device_s *, int, ata_index_t *);
extern void ide_setup_pci_noise (struct pci_dev *dev, struct ide_pci_device_s *d);
enum {
/* Uses ISA control ports not PCI ones. */
- IDEPCI_FLAG_ISA_PORTS = (1 << 0),
+ IDE_HFLAG_ISA_PORTS = (1 << 0),
+ /* single port device */
+ IDE_HFLAG_SINGLE = (1 << 1),
+ /* don't use legacy PIO blacklist */
+ IDE_HFLAG_PIO_NO_BLACKLIST = (1 << 2),
+ /* don't use conservative PIO "downgrade" */
+ IDE_HFLAG_PIO_NO_DOWNGRADE = (1 << 3),
+ /* use PIO8/9 for prefetch off/on */
+ IDE_HFLAG_ABUSE_PREFETCH = (1 << 4),
+ /* use PIO6/7 for fast-devsel off/on */
+ IDE_HFLAG_ABUSE_FAST_DEVSEL = (1 << 5),
+ /* use 100-102 and 200-202 PIO values to set DMA modes */
+ IDE_HFLAG_ABUSE_DMA_MODES = (1 << 6),
+ /*
+ * keep DMA setting when programming PIO mode, may be used only
+ * for hosts which have separate PIO and DMA timings (ie. PMAC)
+ */
+ IDE_HFLAG_SET_PIO_MODE_KEEP_DMA = (1 << 7),
+ /* program host for the transfer mode after programming device */
+ IDE_HFLAG_POST_SET_MODE = (1 << 8),
+ /* don't program host/device for the transfer mode ("smart" hosts) */
+ IDE_HFLAG_NO_SET_MODE = (1 << 9),
+ /* trust BIOS for programming chipset/device for DMA */
+ IDE_HFLAG_TRUST_BIOS_FOR_DMA = (1 << 10),
+ /* host uses VDMA */
+ IDE_HFLAG_VDMA = (1 << 11),
};
typedef struct ide_pci_device_s {
void (*init_hwif)(ide_hwif_t *);
void (*init_dma)(ide_hwif_t *, unsigned long);
void (*fixup)(ide_hwif_t *);
- u8 channels;
u8 autodma;
ide_pci_enablebit_t enablebits[2];
u8 bootable;
unsigned int extra;
struct ide_pci_device_s *next;
- u8 flags;
+ u16 host_flags;
+ u8 pio_mask;
u8 udma_mask;
} ide_pci_device_t;
#define BAD_DMA_DRIVE 0
#define GOOD_DMA_DRIVE 1
-#ifdef CONFIG_BLK_DEV_IDEDMA
struct drive_list_entry {
const char *id_model;
const char *id_firmware;
};
int ide_in_drive_list(struct hd_driveid *, const struct drive_list_entry *);
+
+#ifdef CONFIG_BLK_DEV_IDEDMA
int __ide_dma_bad_drive(ide_drive_t *);
-int __ide_dma_good_drive(ide_drive_t *);
-int ide_use_dma(ide_drive_t *);
-u8 ide_max_dma_mode(ide_drive_t *);
-int ide_tune_dma(ide_drive_t *);
+
+u8 ide_find_dma_mode(ide_drive_t *, u8);
+
+static inline u8 ide_max_dma_mode(ide_drive_t *drive)
+{
+ return ide_find_dma_mode(drive, XFER_UDMA_6);
+}
+
void ide_dma_off(ide_drive_t *);
void ide_dma_verbose(ide_drive_t *);
int ide_set_dma(ide_drive_t *);
void ide_dma_off_quietly(ide_drive_t *);
void ide_dma_host_on(ide_drive_t *);
extern int __ide_dma_on(ide_drive_t *);
-extern int __ide_dma_check(ide_drive_t *);
extern int ide_dma_setup(ide_drive_t *);
extern void ide_dma_start(ide_drive_t *);
extern int __ide_dma_end(ide_drive_t *);
-extern int __ide_dma_lostirq(ide_drive_t *);
-extern int __ide_dma_timeout(ide_drive_t *);
+extern void ide_dma_lost_irq(ide_drive_t *);
+extern void ide_dma_timeout(ide_drive_t *);
#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
#else
-static inline int ide_use_dma(ide_drive_t *drive) { return 0; }
+static inline u8 ide_find_dma_mode(ide_drive_t *drive, u8 speed) { return 0; }
static inline u8 ide_max_dma_mode(ide_drive_t *drive) { return 0; }
-static inline int ide_tune_dma(ide_drive_t *drive) { return 0; }
static inline void ide_dma_off(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; }
extern void ide_acpi_get_timing(ide_hwif_t *hwif);
extern void ide_acpi_push_timing(ide_hwif_t *hwif);
extern void ide_acpi_init(ide_hwif_t *hwif);
+extern void ide_acpi_set_state(ide_hwif_t *hwif, int on);
#else
static inline int ide_acpi_exec_tfs(ide_drive_t *drive) { return 0; }
static inline void ide_acpi_get_timing(ide_hwif_t *hwif) { ; }
static inline void ide_acpi_push_timing(ide_hwif_t *hwif) { ; }
static inline void ide_acpi_init(ide_hwif_t *hwif) { ; }
+static inline void ide_acpi_set_state(ide_hwif_t *hwif, int on) {}
#endif
extern int ide_hwif_request_regions(ide_hwif_t *hwif);
}
/* ide-lib.c */
-u8 ide_rate_filter(ide_drive_t *, u8);
-extern int ide_dma_enable(ide_drive_t *drive);
extern char *ide_xfer_verbose(u8 xfer_rate);
extern void ide_toggle_bounce(ide_drive_t *drive, int on);
extern int ide_set_xfer_rate(ide_drive_t *drive, u8 rate);
-int ide_use_fast_pio(ide_drive_t *);
+
+static inline int ide_dev_has_iordy(struct hd_driveid *id)
+{
+ return ((id->field_valid & 2) && (id->capability & 8)) ? 1 : 0;
+}
+
+static inline int ide_dev_is_sata(struct hd_driveid *id)
+{
+ /*
+ * See if word 93 is 0 AND drive is at least ATA-5 compatible
+ * verifying that word 80 by casting it to a signed type --
+ * this trick allows us to filter out the reserved values of
+ * 0x0000 and 0xffff along with the earlier ATA revisions...
+ */
+ if (id->hw_config == 0 && (short)id->major_rev_num >= 0x0020)
+ return 1;
+ return 0;
+}
u8 ide_dump_status(ide_drive_t *, const char *, u8);
/* active + recovery (+ setup for some chips) */
} ide_pio_timings_t;
-typedef struct ide_pio_data_s {
- u8 pio_mode;
- u8 use_iordy;
- u8 overridden;
- unsigned int cycle_time;
-} ide_pio_data_t;
-
-extern u8 ide_get_best_pio_mode (ide_drive_t *drive, u8 mode_wanted, u8 max_mode, ide_pio_data_t *d);
+unsigned int ide_pio_cycle_time(ide_drive_t *, u8);
+u8 ide_get_best_pio_mode(ide_drive_t *, u8, u8);
extern const ide_pio_timings_t ide_pio_timings[6];
+int ide_set_pio_mode(ide_drive_t *, u8);
+int ide_set_dma_mode(ide_drive_t *, u8);
+
+void ide_set_pio(ide_drive_t *, u8);
+
+static inline void ide_set_max_pio(ide_drive_t *drive)
+{
+ ide_set_pio(drive, 255);
+}
extern spinlock_t ide_lock;
-extern struct semaphore ide_cfg_sem;
+extern struct mutex ide_cfg_mtx;
/*
* Structure locking:
*
- * ide_cfg_sem and ide_lock together protect changes to
+ * ide_cfg_mtx and ide_lock together protect changes to
* ide_hwif_t->{next,hwgroup}
* ide_drive_t->next
*