diff options
Diffstat (limited to 'include/linux/ide.h')
-rw-r--r-- | include/linux/ide.h | 227 |
1 files changed, 124 insertions, 103 deletions
diff --git a/include/linux/ide.h b/include/linux/ide.h index 5f3e82ae901a..32fd77bb4436 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -48,13 +48,6 @@ typedef unsigned char byte; /* used everywhere */ #define ERROR_RECAL 1 /* Recalibrate every 2nd retry */ /* - * Tune flags - */ -#define IDE_TUNE_NOAUTO 2 -#define IDE_TUNE_AUTO 1 -#define IDE_TUNE_DEFAULT 0 - -/* * state flags */ @@ -68,23 +61,30 @@ typedef unsigned char byte; /* used everywhere */ */ #define IDE_NR_PORTS (10) -#define IDE_DATA_OFFSET (0) -#define IDE_ERROR_OFFSET (1) -#define IDE_NSECTOR_OFFSET (2) -#define IDE_SECTOR_OFFSET (3) -#define IDE_LCYL_OFFSET (4) -#define IDE_HCYL_OFFSET (5) -#define IDE_SELECT_OFFSET (6) -#define IDE_STATUS_OFFSET (7) -#define IDE_CONTROL_OFFSET (8) -#define IDE_IRQ_OFFSET (9) - -#define IDE_FEATURE_OFFSET IDE_ERROR_OFFSET -#define IDE_COMMAND_OFFSET IDE_STATUS_OFFSET -#define IDE_ALTSTATUS_OFFSET IDE_CONTROL_OFFSET -#define IDE_IREASON_OFFSET IDE_NSECTOR_OFFSET -#define IDE_BCOUNTL_OFFSET IDE_LCYL_OFFSET -#define IDE_BCOUNTH_OFFSET IDE_HCYL_OFFSET +struct ide_io_ports { + unsigned long data_addr; + + union { + unsigned long error_addr; /* read: error */ + unsigned long feature_addr; /* write: feature */ + }; + + unsigned long nsect_addr; + unsigned long lbal_addr; + unsigned long lbam_addr; + unsigned long lbah_addr; + + unsigned long device_addr; + + union { + unsigned long status_addr; /* read: status */ + unsigned long command_addr; /* write: command */ + }; + + unsigned long ctl_addr; + + unsigned long irq_addr; +}; #define OK_STAT(stat,good,bad) (((stat)&((good)|(bad)))==(good)) #define BAD_R_STAT (BUSY_STAT | ERR_STAT) @@ -163,14 +163,17 @@ typedef u8 hwif_chipset_t; * Structure to hold all information about the location of this port */ typedef struct hw_regs_s { - unsigned long io_ports[IDE_NR_PORTS]; /* task file registers */ + union { + struct ide_io_ports io_ports; + unsigned long io_ports_array[IDE_NR_PORTS]; + }; + int irq; /* our irq number */ ide_ack_intr_t *ack_intr; /* acknowledge interrupt */ hwif_chipset_t chipset; struct device *dev; } hw_regs_t; -struct hwif_s * ide_find_port(unsigned long); void ide_init_port_data(struct hwif_s *, unsigned int); void ide_init_port_hw(struct hwif_s *, hw_regs_t *); @@ -180,10 +183,10 @@ static inline void ide_std_init_ports(hw_regs_t *hw, { unsigned int i; - for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) - hw->io_ports[i] = io_addr++; + for (i = 0; i <= 7; i++) + hw->io_ports_array[i] = io_addr++; - hw->io_ports[IDE_CONTROL_OFFSET] = ctl_addr; + hw->io_ports.ctl_addr = ctl_addr; } #include <asm/ide.h> @@ -329,7 +332,6 @@ typedef struct ide_drive_s { unsigned atapi_overlap : 1; /* ATAPI overlap (not supported) */ 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 vdma : 1; /* 1=doing PIO over DMA 0=doing normal DMA */ @@ -388,6 +390,43 @@ typedef struct ide_drive_s { struct ide_port_info; +struct ide_port_ops { + /* host specific initialization of devices on a port */ + void (*port_init_devs)(struct hwif_s *); + /* 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 */ + int (*reset_poll)(ide_drive_t *); + /* chipset specific changes to default for device-hba resets */ + void (*pre_reset)(ide_drive_t *); + /* routine to reset controller after a disk reset */ + void (*resetproc)(ide_drive_t *); + /* special host masking for drive selection */ + void (*maskproc)(ide_drive_t *, int); + /* check host's drive quirk list */ + void (*quirkproc)(ide_drive_t *); + + u8 (*mdma_filter)(ide_drive_t *); + u8 (*udma_filter)(ide_drive_t *); + + u8 (*cable_detect)(struct hwif_s *); +}; + +struct ide_dma_ops { + void (*dma_host_set)(struct ide_drive_s *, int); + int (*dma_setup)(struct ide_drive_s *); + void (*dma_exec_cmd)(struct ide_drive_s *, u8); + void (*dma_start)(struct ide_drive_s *); + int (*dma_end)(struct ide_drive_s *); + int (*dma_test_irq)(struct ide_drive_s *); + void (*dma_lost_irq)(struct ide_drive_s *); + void (*dma_timeout)(struct ide_drive_s *); +}; + 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 */ @@ -396,8 +435,8 @@ typedef struct hwif_s { char name[6]; /* name of interface, eg. "ide0" */ - /* task file registers for pata and sata */ - unsigned long io_ports[IDE_NR_PORTS]; + struct ide_io_ports io_ports; + unsigned long sata_scr[SATA_NR_PORTS]; ide_drive_t drives[MAX_DRIVES]; /* drive info */ @@ -421,38 +460,12 @@ typedef struct hwif_s { struct device *dev; - const struct ide_port_info *cds; /* chipset device struct */ - ide_ack_intr_t *ack_intr; void (*rw_disk)(ide_drive_t *, struct request *); -#if 0 - ide_hwif_ops_t *hwifops; -#else - /* host specific initialization of devices on a port */ - void (*port_init_devs)(struct hwif_s *); - /* 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 */ - int (*reset_poll)(ide_drive_t *); - /* chipset specific changes to default for device-hba resets */ - void (*pre_reset)(ide_drive_t *); - /* routine to reset controller after a disk reset */ - void (*resetproc)(ide_drive_t *); - /* special host masking for drive selection */ - void (*maskproc)(ide_drive_t *, int); - /* check host's drive quirk list */ - void (*quirkproc)(ide_drive_t *); -#endif - u8 (*mdma_filter)(ide_drive_t *); - u8 (*udma_filter)(ide_drive_t *); - - u8 (*cable_detect)(struct hwif_s *); + const struct ide_port_ops *port_ops; + const struct ide_dma_ops *dma_ops; void (*ata_input_data)(ide_drive_t *, void *, u32); void (*ata_output_data)(ide_drive_t *, void *, u32); @@ -460,15 +473,7 @@ typedef struct hwif_s { void (*atapi_input_bytes)(ide_drive_t *, void *, u32); void (*atapi_output_bytes)(ide_drive_t *, void *, u32); - void (*dma_host_set)(ide_drive_t *, int); - int (*dma_setup)(ide_drive_t *); - 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_test_irq)(ide_drive_t *drive); void (*ide_dma_clear_irq)(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); @@ -515,14 +520,11 @@ typedef struct hwif_s { unsigned long extra_base; /* extra addr for dma ports */ unsigned extra_ports; /* number of extra dma ports */ - unsigned noprobe : 1; /* don't probe for this interface */ unsigned present : 1; /* this interface exists */ unsigned serialized : 1; /* serialized all channel operation */ unsigned sharing_irq: 1; /* 1 = sharing irq with another hwif */ - unsigned reset : 1; /* reset after probe */ unsigned sg_mapped : 1; /* sg_table and sg_nents are ready */ unsigned mmio : 1; /* host uses MMIO */ - unsigned straight8 : 1; /* Alan's straight 8 check */ struct device gendev; struct device *portdev; @@ -703,10 +705,6 @@ void ide_add_generic_settings(ide_drive_t *); read_proc_t proc_ide_read_capacity; read_proc_t proc_ide_read_geometry; -#ifdef CONFIG_BLK_DEV_IDEPCI -void ide_pci_create_host_proc(const char *, get_info_t *); -#endif - /* * Standard exit stuff: */ @@ -807,8 +805,21 @@ int generic_ide_ioctl(ide_drive_t *, struct file *, struct block_device *, unsig #ifndef _IDE_C extern ide_hwif_t ide_hwifs[]; /* master data repository */ #endif +extern int ide_noacpi; +extern int ide_acpigtf; +extern int ide_acpionboot; extern int noautodma; +extern int ide_vlb_clk; +extern int ide_pci_clk; + +ide_hwif_t *ide_find_port_slot(const struct ide_port_info *); + +static inline ide_hwif_t *ide_find_port(void) +{ + return ide_find_port_slot(NULL); +} + extern int ide_end_request (ide_drive_t *drive, int uptodate, int nrsecs); int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq, int uptodate, int nr_sectors); @@ -1004,10 +1015,15 @@ void ide_pci_setup_ports(struct pci_dev *, const struct ide_port_info *, int, u8 void ide_setup_pci_noise(struct pci_dev *, const struct ide_port_info *); #ifdef CONFIG_BLK_DEV_IDEDMA_PCI -void ide_hwif_setup_dma(ide_hwif_t *, const struct ide_port_info *); +int ide_pci_set_master(struct pci_dev *, const char *); +unsigned long ide_pci_dma_base(ide_hwif_t *, const struct ide_port_info *); +int ide_hwif_setup_dma(ide_hwif_t *, const struct ide_port_info *); #else -static inline void ide_hwif_setup_dma(ide_hwif_t *hwif, - const struct ide_port_info *d) { } +static inline int ide_hwif_setup_dma(ide_hwif_t *hwif, + const struct ide_port_info *d) +{ + return -EINVAL; +} #endif extern void default_hwif_iops(ide_hwif_t *); @@ -1027,8 +1043,8 @@ enum { 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), + /* set for the second port of QD65xx */ + IDE_HFLAG_QD_2ND_PORT = (1 << 3), /* use PIO8/9 for prefetch off/on */ IDE_HFLAG_ABUSE_PREFETCH = (1 << 4), /* use PIO6/7 for fast-devsel off/on */ @@ -1050,14 +1066,12 @@ enum { IDE_HFLAG_VDMA = (1 << 11), /* ATAPI DMA is unsupported */ IDE_HFLAG_NO_ATAPI_DMA = (1 << 12), - /* set if host is a "bootable" controller */ - IDE_HFLAG_BOOTABLE = (1 << 13), + /* set if host is a "non-bootable" controller */ + IDE_HFLAG_NON_BOOTABLE = (1 << 13), /* host doesn't support DMA */ IDE_HFLAG_NO_DMA = (1 << 14), /* check if host is PCI IDE device before allowing DMA */ IDE_HFLAG_NO_AUTODMA = (1 << 15), - /* don't autotune PIO */ - IDE_HFLAG_NO_AUTOTUNE = (1 << 16), /* host is CS5510/CS5520 */ IDE_HFLAG_CS5520 = IDE_HFLAG_VDMA, /* no LBA48 */ @@ -1079,8 +1093,8 @@ enum { /* unmask IRQs */ IDE_HFLAG_UNMASK_IRQS = (1 << 25), IDE_HFLAG_ABUSE_SET_DMA_MODE = (1 << 26), - /* host is CY82C693 */ - IDE_HFLAG_CY82C693 = (1 << 27), + /* serialize ports if DMA is possible (for sl82c105) */ + IDE_HFLAG_SERIALIZE_DMA = (1 << 27), /* force host out of "simplex" mode */ IDE_HFLAG_CLEAR_SIMPLEX = (1 << 28), /* DSC overlap is unsupported */ @@ -1092,9 +1106,9 @@ enum { }; #ifdef CONFIG_BLK_DEV_OFFBOARD -# define IDE_HFLAG_OFF_BOARD IDE_HFLAG_BOOTABLE -#else # define IDE_HFLAG_OFF_BOARD 0 +#else +# define IDE_HFLAG_OFF_BOARD IDE_HFLAG_NON_BOOTABLE #endif struct ide_port_info { @@ -1102,10 +1116,14 @@ struct ide_port_info { unsigned int (*init_chipset)(struct pci_dev *, const char *); void (*init_iops)(ide_hwif_t *); void (*init_hwif)(ide_hwif_t *); - void (*init_dma)(ide_hwif_t *, unsigned long); + int (*init_dma)(ide_hwif_t *, + const struct ide_port_info *); + + const struct ide_port_ops *port_ops; + const struct ide_dma_ops *dma_ops; + ide_pci_enablebit_t enablebits[2]; hwif_chipset_t chipset; - u8 extra; u32 host_flags; u8 pio_mask; u8 swdma_mask; @@ -1152,13 +1170,16 @@ void ide_destroy_dmatable(ide_drive_t *); #ifdef CONFIG_BLK_DEV_IDEDMA_SFF extern int ide_build_dmatable(ide_drive_t *, struct request *); -extern int ide_release_dma(ide_hwif_t *); -extern void ide_setup_dma(ide_hwif_t *, unsigned long); +int ide_allocate_dma_engine(ide_hwif_t *); +void ide_release_dma_engine(ide_hwif_t *); +void ide_setup_dma(ide_hwif_t *, unsigned long); 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_test_irq(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_SFF */ @@ -1176,7 +1197,7 @@ 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(ide_hwif_t *drive) {;} +static inline void ide_release_dma_engine(ide_hwif_t *hwif) { ; } #endif #ifdef CONFIG_BLK_DEV_IDEACPI @@ -1196,17 +1217,18 @@ static inline void ide_acpi_set_state(ide_hwif_t *hwif, int on) {} #endif void ide_remove_port_from_hwgroup(ide_hwif_t *); -extern int ide_hwif_request_regions(ide_hwif_t *hwif); -extern void ide_hwif_release_regions(ide_hwif_t* hwif); -void ide_unregister(unsigned int); +void ide_unregister(ide_hwif_t *); void ide_register_region(struct gendisk *); void ide_unregister_region(struct gendisk *); void ide_undecoded_slave(ide_drive_t *); +void ide_port_apply_params(ide_hwif_t *); + int ide_device_add_all(u8 *idx, const struct ide_port_info *); int ide_device_add(u8 idx[4], const struct ide_port_info *); +int ide_legacy_device_add(const struct ide_port_info *, unsigned long); void ide_port_unregister_devices(ide_hwif_t *); void ide_port_scan(ide_hwif_t *); @@ -1315,29 +1337,28 @@ static inline void ide_set_irq(ide_drive_t *drive, int on) { ide_hwif_t *hwif = drive->hwif; - hwif->OUTB(drive->ctl | (on ? 0 : 2), - hwif->io_ports[IDE_CONTROL_OFFSET]); + hwif->OUTB(drive->ctl | (on ? 0 : 2), hwif->io_ports.ctl_addr); } static inline u8 ide_read_status(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; - return hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]); + return hwif->INB(hwif->io_ports.status_addr); } static inline u8 ide_read_altstatus(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; - return hwif->INB(hwif->io_ports[IDE_CONTROL_OFFSET]); + return hwif->INB(hwif->io_ports.ctl_addr); } static inline u8 ide_read_error(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; - return hwif->INB(hwif->io_ports[IDE_ERROR_OFFSET]); + return hwif->INB(hwif->io_ports.error_addr); } /* @@ -1350,7 +1371,7 @@ static inline void ide_atapi_discard_data(ide_drive_t *drive, unsigned bcount) /* FIXME: use ->atapi_input_bytes */ while (bcount--) - (void)hwif->INB(hwif->io_ports[IDE_DATA_OFFSET]); + (void)hwif->INB(hwif->io_ports.data_addr); } static inline void ide_atapi_write_zeros(ide_drive_t *drive, unsigned bcount) @@ -1359,7 +1380,7 @@ static inline void ide_atapi_write_zeros(ide_drive_t *drive, unsigned bcount) /* FIXME: use ->atapi_output_bytes */ while (bcount--) - hwif->OUTB(0, hwif->io_ports[IDE_DATA_OFFSET]); + hwif->OUTB(0, hwif->io_ports.data_addr); } #endif /* _IDE_H */ |