X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=include%2Flinux%2Flibata.h;h=66c3100c2b94c19dc2eb581e000ce5fce24deb75;hb=7f1cbe51ffc1273bcded36742ede4b6ebef1b640;hp=7c9e280a48298c00cd1147c2e6400c57be2817f8;hpb=88e490340ea4c3a2ebc0187a4339912e2fc1a081;p=safe%2Fjmp%2Flinux-2.6 diff --git a/include/linux/libata.h b/include/linux/libata.h index 7c9e280..66c3100 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -109,9 +110,10 @@ enum { ATA_MAX_PORTS = 8, ATA_DEF_QUEUE = 1, /* tag ATA_MAX_QUEUE - 1 is reserved for internal commands */ - ATA_MAX_QUEUE = 2, + ATA_MAX_QUEUE = 32, ATA_TAG_INTERNAL = ATA_MAX_QUEUE - 1, ATA_MAX_SECTORS = 200, /* FIXME */ + ATA_MAX_SECTORS_LBA48 = 65535, ATA_MAX_BUS = 2, ATA_DEF_BUSY_WAIT = 10000, ATA_SHORT_PAUSE = (HZ >> 6) + 1, @@ -129,6 +131,11 @@ enum { ATA_DFLAG_CFG_MASK = (1 << 8) - 1, ATA_DFLAG_PIO = (1 << 8), /* device currently in PIO mode */ + ATA_DFLAG_SUSPENDED = (1 << 9), /* device suspended */ + ATA_DFLAG_INIT_MASK = (1 << 16) - 1, + + ATA_DFLAG_DETACH = (1 << 16), + ATA_DFLAG_DETACHED = (1 << 17), ATA_DEV_UNKNOWN = 0, /* unknown device */ ATA_DEV_ATA = 1, /* ATA device */ @@ -148,22 +155,34 @@ enum { ATA_FLAG_NO_ATAPI = (1 << 6), /* No ATAPI support */ ATA_FLAG_PIO_DMA = (1 << 7), /* PIO cmds via DMA */ ATA_FLAG_PIO_LBA48 = (1 << 8), /* Host DMA engine is LBA28 only */ - ATA_FLAG_IRQ_MASK = (1 << 9), /* Mask IRQ in PIO xfers */ - ATA_FLAG_PIO_POLLING = (1 << 10), /* use polling PIO if LLD - * doesn't handle PIO interrupts */ - ATA_FLAG_NCQ = (1 << 11), /* host supports NCQ */ - - ATA_FLAG_DEBUGMSG = (1 << 14), - ATA_FLAG_FLUSH_PORT_TASK = (1 << 15), /* flush port task */ + ATA_FLAG_PIO_POLLING = (1 << 9), /* use polling PIO if LLD + * doesn't handle PIO interrupts */ + ATA_FLAG_NCQ = (1 << 10), /* host supports NCQ */ + ATA_FLAG_HRST_TO_RESUME = (1 << 11), /* hardreset to resume phy */ + ATA_FLAG_SKIP_D2H_BSY = (1 << 12), /* can't wait for the first D2H + * Register FIS clearing BSY */ + ATA_FLAG_DEBUGMSG = (1 << 13), + + /* The following flag belongs to ap->pflags but is kept in + * ap->flags because it's referenced in many LLDs and will be + * removed in not-too-distant future. + */ + ATA_FLAG_DISABLED = (1 << 23), /* port is disabled, ignore it */ - ATA_FLAG_EH_PENDING = (1 << 16), /* EH pending */ - ATA_FLAG_FROZEN = (1 << 17), /* port is frozen */ - ATA_FLAG_RECOVERED = (1 << 18), /* recovery action performed */ + /* bits 24:31 of ap->flags are reserved for LLD specific flags */ - ATA_FLAG_DISABLED = (1 << 22), /* port is disabled, ignore it */ - ATA_FLAG_SUSPENDED = (1 << 23), /* port is suspended (power) */ + /* struct ata_port pflags */ + ATA_PFLAG_EH_PENDING = (1 << 0), /* EH pending */ + ATA_PFLAG_EH_IN_PROGRESS = (1 << 1), /* EH in progress */ + ATA_PFLAG_FROZEN = (1 << 2), /* port is frozen */ + ATA_PFLAG_RECOVERED = (1 << 3), /* recovery action performed */ + ATA_PFLAG_LOADING = (1 << 4), /* boot/loading probe */ + ATA_PFLAG_UNLOADING = (1 << 5), /* module is unloading */ + ATA_PFLAG_SCSI_HOTPLUG = (1 << 6), /* SCSI hotplug scheduled */ - /* bits 24:31 of ap->flags are reserved for LLDD specific flags */ + ATA_PFLAG_FLUSH_PORT_TASK = (1 << 16), /* flush port task */ + ATA_PFLAG_SUSPENDED = (1 << 17), /* port is suspended (power) */ + ATA_PFLAG_PM_PENDING = (1 << 18), /* PM operation pending */ /* struct ata_queued_cmd flags */ ATA_QCFLAG_ACTIVE = (1 << 0), /* cmd not yet ack'd to scsi lyer */ @@ -236,11 +255,23 @@ enum { ATA_EH_REVALIDATE = (1 << 0), ATA_EH_SOFTRESET = (1 << 1), ATA_EH_HARDRESET = (1 << 2), + ATA_EH_SUSPEND = (1 << 3), + ATA_EH_RESUME = (1 << 4), + ATA_EH_PM_FREEZE = (1 << 5), ATA_EH_RESET_MASK = ATA_EH_SOFTRESET | ATA_EH_HARDRESET, + ATA_EH_PERDEV_MASK = ATA_EH_REVALIDATE | ATA_EH_SUSPEND | + ATA_EH_RESUME | ATA_EH_PM_FREEZE, /* ata_eh_info->flags */ - ATA_EHI_DID_RESET = (1 << 0), /* already reset this port */ + ATA_EHI_HOTPLUGGED = (1 << 0), /* could have been hotplugged */ + ATA_EHI_RESUME_LINK = (1 << 1), /* resume link (reset modifier) */ + ATA_EHI_NO_AUTOPSY = (1 << 2), /* no autopsy */ + ATA_EHI_QUIET = (1 << 3), /* be quiet */ + + ATA_EHI_DID_RESET = (1 << 16), /* already reset this port */ + + ATA_EHI_RESET_MODIFIER_MASK = ATA_EHI_RESUME_LINK, /* max repeat if error condition is still set after ->error_handler */ ATA_EH_MAX_REPEAT = 5, @@ -249,6 +280,15 @@ enum { ATA_PROBE_MAX_TRIES = 3, ATA_EH_RESET_TRIES = 3, ATA_EH_DEV_TRIES = 3, + + /* Drive spinup time (time from power-on to the first D2H FIS) + * in msecs - 8s currently. Failing to get ready in this time + * isn't critical. It will result in reset failure for + * controllers which can't wait for the first D2H FIS. libata + * will retry, so it just has to be long enough to spin up + * most devices. + */ + ATA_SPINUP_WAIT = 8000, }; enum hsm_task_states { @@ -281,9 +321,9 @@ struct ata_queued_cmd; /* typedefs */ typedef void (*ata_qc_cb_t) (struct ata_queued_cmd *qc); -typedef void (*ata_probeinit_fn_t)(struct ata_port *); -typedef int (*ata_reset_fn_t)(struct ata_port *, unsigned int *); -typedef void (*ata_postreset_fn_t)(struct ata_port *ap, unsigned int *); +typedef int (*ata_prereset_fn_t)(struct ata_port *ap); +typedef int (*ata_reset_fn_t)(struct ata_port *ap, unsigned int *classes); +typedef void (*ata_postreset_fn_t)(struct ata_port *ap, unsigned int *classes); struct ata_ioports { unsigned long cmd_addr; @@ -334,7 +374,8 @@ struct ata_host_set { unsigned long flags; int simplex_claimed; /* Keep seperate in case we ever need to do this locked */ - struct ata_port * ports[0]; + struct ata_host_set *next; /* for legacy mode */ + struct ata_port *ports[0]; }; struct ata_queued_cmd { @@ -398,10 +439,12 @@ struct ata_ering { struct ata_device { struct ata_port *ap; - u64 n_sectors; /* size of device, if ATA */ + unsigned int devno; /* 0 or 1 */ unsigned long flags; /* ATA_DFLAG_xxx */ + struct scsi_device *sdev; /* attached SCSI device */ + /* n_sector is used as CLEAR_OFFSET, read comment above CLEAR_OFFSET */ + u64 n_sectors; /* size of device, if ATA */ unsigned int class; /* ATA_DEV_xxx */ - unsigned int devno; /* 0 or 1 */ u16 id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */ u8 pio_mode; u8 dma_mode; @@ -427,12 +470,22 @@ struct ata_device { struct ata_ering ering; }; +/* Offset into struct ata_device. Fields above it are maintained + * acress device init. Fields below are zeroed. + */ +#define ATA_DEVICE_CLEAR_OFFSET offsetof(struct ata_device, n_sectors) + struct ata_eh_info { struct ata_device *dev; /* offending device */ u32 serror; /* SError from LLDD */ unsigned int err_mask; /* port-wide err_mask */ unsigned int action; /* ATA_EH_* action mask */ + unsigned int dev_action[ATA_MAX_DEVICES]; /* dev EH action */ unsigned int flags; /* ATA_EHI_* flags */ + + unsigned long hotplug_timestamp; + unsigned int probe_mask; + char desc[ATA_EH_DESC_LEN]; int desc_len; }; @@ -440,12 +493,16 @@ struct ata_eh_info { struct ata_eh_context { struct ata_eh_info i; int tries[ATA_MAX_DEVICES]; + unsigned int classes[ATA_MAX_DEVICES]; + unsigned int did_probe_mask; }; struct ata_port { struct Scsi_Host *host; /* our co-allocated scsi host */ const struct ata_port_operations *ops; + spinlock_t *lock; unsigned long flags; /* ATA_FLAG_xxx */ + unsigned int pflags; /* ATA_PFLAG_xxx */ unsigned int id; /* unique id req'd by scsi midlyr */ unsigned int port_no; /* unique port #; from zero */ unsigned int hard_port_no; /* hardware port #; from zero */ @@ -464,6 +521,7 @@ struct ata_port { unsigned int mwdma_mask; unsigned int udma_mask; unsigned int cbl; /* cable type; ATA_CBL_xxx */ + unsigned int hw_sata_spd_limit; unsigned int sata_spd_limit; /* SATA PHY speed limit */ /* record runtime error info, protected by host_set lock */ @@ -474,19 +532,28 @@ struct ata_port { struct ata_device device[ATA_MAX_DEVICES]; struct ata_queued_cmd qcmd[ATA_MAX_QUEUE]; - unsigned long qactive; + unsigned long qc_allocated; + unsigned int qc_active; + unsigned int active_tag; + u32 sactive; struct ata_host_stats stats; struct ata_host_set *host_set; struct device *dev; struct work_struct port_task; + struct work_struct hotplug_task; + struct work_struct scsi_rescan_task; unsigned int hsm_task_state; u32 msg_enable; struct list_head eh_done_q; + wait_queue_head_t eh_wait_q; + + pm_message_t pm_mesg; + int *pm_result; void *private_data; @@ -512,7 +579,6 @@ struct ata_port_operations { void (*phy_reset) (struct ata_port *ap); /* obsolete */ void (*set_mode) (struct ata_port *ap); - int (*probe_reset) (struct ata_port *ap, unsigned int *classes); void (*post_set_mode) (struct ata_port *ap); @@ -521,6 +587,8 @@ struct ata_port_operations { void (*bmdma_setup) (struct ata_queued_cmd *qc); void (*bmdma_start) (struct ata_queued_cmd *qc); + void (*data_xfer) (struct ata_device *, unsigned char *, unsigned int, int); + void (*qc_prep) (struct ata_queued_cmd *qc); unsigned int (*qc_issue) (struct ata_queued_cmd *qc); @@ -541,6 +609,9 @@ struct ata_port_operations { void (*scr_write) (struct ata_port *ap, unsigned int sc_reg, u32 val); + int (*port_suspend) (struct ata_port *ap, pm_message_t mesg); + int (*port_resume) (struct ata_port *ap); + int (*port_start) (struct ata_port *ap); void (*port_stop) (struct ata_port *ap); @@ -574,16 +645,27 @@ struct ata_timing { #define FIT(v,vmin,vmax) max_t(short,min_t(short,v,vmax),vmin) +extern const unsigned long sata_deb_timing_normal[]; +extern const unsigned long sata_deb_timing_hotplug[]; +extern const unsigned long sata_deb_timing_long[]; + +static inline const unsigned long * +sata_ehc_deb_timing(struct ata_eh_context *ehc) +{ + if (ehc->i.flags & ATA_EHI_HOTPLUGGED) + return sata_deb_timing_hotplug; + else + return sata_deb_timing_normal; +} + extern void ata_port_probe(struct ata_port *); extern void __sata_phy_reset(struct ata_port *ap); extern void sata_phy_reset(struct ata_port *ap); extern void ata_bus_reset(struct ata_port *ap); extern int sata_set_spd(struct ata_port *ap); -extern int ata_drive_probe_reset(struct ata_port *ap, - ata_probeinit_fn_t probeinit, - ata_reset_fn_t softreset, ata_reset_fn_t hardreset, - ata_postreset_fn_t postreset, unsigned int *classes); -extern void ata_std_probeinit(struct ata_port *ap); +extern int sata_phy_debounce(struct ata_port *ap, const unsigned long *param); +extern int sata_phy_resume(struct ata_port *ap, const unsigned long *param); +extern int ata_std_prereset(struct ata_port *ap); extern int ata_std_softreset(struct ata_port *ap, unsigned int *classes); extern int sata_std_hardreset(struct ata_port *ap, unsigned int *class); extern void ata_std_postreset(struct ata_port *ap, unsigned int *classes); @@ -594,11 +676,14 @@ extern void ata_std_ports(struct ata_ioports *ioaddr); extern int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, unsigned int n_ports); extern void ata_pci_remove_one (struct pci_dev *pdev); +extern void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t state); +extern void ata_pci_device_do_resume(struct pci_dev *pdev); extern int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t state); extern int ata_pci_device_resume(struct pci_dev *pdev); extern int ata_pci_clear_simplex(struct pci_dev *pdev); #endif /* CONFIG_PCI */ extern int ata_device_add(const struct ata_probe_ent *ent); +extern void ata_port_detach(struct ata_port *ap); extern void ata_host_set_remove(struct ata_host_set *host_set); extern int ata_scsi_detect(struct scsi_host_template *sht); extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg); @@ -613,8 +698,9 @@ extern int ata_port_online(struct ata_port *ap); extern int ata_port_offline(struct ata_port *ap); extern int ata_scsi_device_resume(struct scsi_device *); extern int ata_scsi_device_suspend(struct scsi_device *, pm_message_t state); -extern int ata_device_resume(struct ata_device *); -extern int ata_device_suspend(struct ata_device *, pm_message_t state); +extern int ata_host_set_suspend(struct ata_host_set *host_set, + pm_message_t mesg); +extern void ata_host_set_resume(struct ata_host_set *host_set); extern int ata_ratelimit(void); extern unsigned int ata_busy_sleep(struct ata_port *ap, unsigned long timeout_pat, @@ -637,11 +723,16 @@ extern void ata_std_dev_select (struct ata_port *ap, unsigned int device); extern u8 ata_check_status(struct ata_port *ap); extern u8 ata_altstatus(struct ata_port *ap); extern void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf); -extern int ata_std_probe_reset(struct ata_port *ap, unsigned int *classes); extern int ata_port_start (struct ata_port *ap); extern void ata_port_stop (struct ata_port *ap); extern void ata_host_stop (struct ata_host_set *host_set); extern irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs); +extern void ata_mmio_data_xfer(struct ata_device *adev, unsigned char *buf, + unsigned int buflen, int write_data); +extern void ata_pio_data_xfer(struct ata_device *adev, unsigned char *buf, + unsigned int buflen, int write_data); +extern void ata_pio_data_xfer_noirq(struct ata_device *adev, unsigned char *buf, + unsigned int buflen, int write_data); extern void ata_qc_prep(struct ata_queued_cmd *qc); extern void ata_noop_qc_prep(struct ata_queued_cmd *qc); extern unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc); @@ -661,19 +752,26 @@ extern u8 ata_bmdma_status(struct ata_port *ap); extern void ata_bmdma_irq_clear(struct ata_port *ap); extern void ata_bmdma_freeze(struct ata_port *ap); extern void ata_bmdma_thaw(struct ata_port *ap); -extern void ata_bmdma_drive_eh(struct ata_port *ap, +extern void ata_bmdma_drive_eh(struct ata_port *ap, ata_prereset_fn_t prereset, ata_reset_fn_t softreset, ata_reset_fn_t hardreset, ata_postreset_fn_t postreset); extern void ata_bmdma_error_handler(struct ata_port *ap); extern void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc); +extern int ata_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc, + u8 status, int in_wq); extern void ata_qc_complete(struct ata_queued_cmd *qc); +extern int ata_qc_complete_multiple(struct ata_port *ap, u32 qc_active, + void (*finish_qc)(struct ata_queued_cmd *)); extern void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)); extern int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[]); extern int ata_scsi_slave_config(struct scsi_device *sdev); +extern void ata_scsi_slave_destroy(struct scsi_device *sdev); +extern int ata_scsi_change_queue_depth(struct scsi_device *sdev, + int queue_depth); extern struct ata_device *ata_dev_pair(struct ata_device *adev); /* @@ -735,8 +833,9 @@ extern void ata_eh_thaw_port(struct ata_port *ap); extern void ata_eh_qc_complete(struct ata_queued_cmd *qc); extern void ata_eh_qc_retry(struct ata_queued_cmd *qc); -extern void ata_do_eh(struct ata_port *ap, ata_reset_fn_t softreset, - ata_reset_fn_t hardreset, ata_postreset_fn_t postreset); +extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset, + ata_reset_fn_t softreset, ata_reset_fn_t hardreset, + ata_postreset_fn_t postreset); /* * printk helpers @@ -761,6 +860,24 @@ extern void ata_do_eh(struct ata_port *ap, ata_reset_fn_t softreset, (ehi)->desc_len = 0; \ } while (0) +static inline void __ata_ehi_hotplugged(struct ata_eh_info *ehi) +{ + if (ehi->flags & ATA_EHI_HOTPLUGGED) + return; + + ehi->flags |= ATA_EHI_HOTPLUGGED | ATA_EHI_RESUME_LINK; + ehi->hotplug_timestamp = jiffies; + + ehi->action |= ATA_EH_SOFTRESET; + ehi->probe_mask |= (1 << ATA_MAX_DEVICES) - 1; +} + +static inline void ata_ehi_hotplugged(struct ata_eh_info *ehi) +{ + __ata_ehi_hotplugged(ehi); + ehi->err_mask |= AC_ERR_ATA_BUS; +} + /* * qc helpers */ @@ -811,6 +928,9 @@ static inline unsigned int ata_tag_internal(unsigned int tag) return tag == ATA_MAX_QUEUE - 1; } +/* + * device helpers + */ static inline unsigned int ata_class_enabled(unsigned int class) { return class == ATA_DEV_ATA || class == ATA_DEV_ATAPI; @@ -841,6 +961,22 @@ static inline unsigned int ata_dev_absent(const struct ata_device *dev) return ata_class_absent(dev->class); } +static inline unsigned int ata_dev_ready(const struct ata_device *dev) +{ + return ata_dev_enabled(dev) && !(dev->flags & ATA_DFLAG_SUSPENDED); +} + +/* + * port helpers + */ +static inline int ata_port_max_devices(const struct ata_port *ap) +{ + if (ap->flags & ATA_FLAG_SLAVE_POSS) + return 2; + return 1; +} + + static inline u8 ata_chk_status(struct ata_port *ap) { return ap->ops->check_status(ap); @@ -1054,7 +1190,7 @@ static inline int ata_try_flush_cache(const struct ata_device *dev) static inline unsigned int ac_err_mask(u8 status) { - if (status & ATA_BUSY) + if (status & (ATA_BUSY | ATA_DRQ)) return AC_ERR_HSM; if (status & (ATA_ERR | ATA_DF)) return AC_ERR_DEV;