From 002c8054fa8d0f1afce2b0c728be32d338b9293a Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 2 Apr 2006 17:54:46 +0900 Subject: [PATCH] libata: implement ata_dev_absent() For the time being we cannot use ata_dev_present() as it was renamed to ata_dev_enabled() but we still need presence test. Implement negation of the test. Conveniently, the negated result is needed in more places. This is suggested by Jeff Garzik. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index c6883ba8cba9..0f8e3720edd9 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -682,6 +682,11 @@ static inline unsigned int ata_class_disabled(unsigned int class) return class == ATA_DEV_ATA_UNSUP || class == ATA_DEV_ATAPI_UNSUP; } +static inline unsigned int ata_class_absent(unsigned int class) +{ + return !ata_class_enabled(class) && !ata_class_disabled(class); +} + static inline unsigned int ata_dev_enabled(const struct ata_device *dev) { return ata_class_enabled(dev->class); @@ -692,6 +697,11 @@ static inline unsigned int ata_dev_disabled(const struct ata_device *dev) return ata_class_disabled(dev->class); } +static inline unsigned int ata_dev_absent(const struct ata_device *dev) +{ + return ata_class_absent(dev->class); +} + static inline u8 ata_chk_status(struct ata_port *ap) { return ap->ops->check_status(ap); -- cgit v1.2.2 From 1c3fae4d7eb121933341443c37d3bbee43c0fb68 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 2 Apr 2006 20:53:28 +0900 Subject: [PATCH] libata: implement ap->sata_spd_limit and helpers ap->sata_spd_limit contrains SATA PHY speed of the port. It is initialized to the configured value prior to probing thus preserving BIOS configured value. hardreset is responsible for applying SPD limit and sata_std_hardreset() is updated to do that. SATA SPD limit will be used to enhance failure handling during probing and later by EH. This patch also normalizes some comments around affected code. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 0f8e3720edd9..a5207e66ca52 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -397,6 +397,7 @@ struct ata_port { unsigned int mwdma_mask; unsigned int udma_mask; unsigned int cbl; /* cable type; ATA_CBL_xxx */ + unsigned int sata_spd_limit; /* SATA PHY speed limit */ struct ata_device device[ATA_MAX_DEVICES]; -- cgit v1.2.2 From 14d2bac1877ed4e2cc940d1680db1a4f29225811 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 2 Apr 2006 17:54:46 +0900 Subject: [PATCH] libata: improve ata_bus_probe() Improve ata_bus_probe() such that configuration failures are handled better. Each device is given ATA_PROBE_MAX_TRIES chances, but any non-transient error (revalidation failure with -ENODEV, configuration failure with -EINVAL...) disables the device directly. Any IO error results in SATA PHY speed down and ata_set_mode() failure lowers transfer mode. The last try always puts a device into PIO-0. After each failure, the whole port is reset to make sure that the controller and all the devices are in a known and stable state. The reset also applies SATA SPD configuration if necessary. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index a5207e66ca52..a4a1e6304e78 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -211,6 +211,9 @@ enum { /* Masks for port functions */ ATA_PORT_PRIMARY = (1 << 0), ATA_PORT_SECONDARY = (1 << 1), + + /* how hard are we gonna try to probe/recover devices */ + ATA_PROBE_MAX_TRIES = 3, }; enum hsm_task_states { -- cgit v1.2.2 From c43c555c3a6db7f0b55fd9b66d7ecff16e827d4e Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 2 Apr 2006 18:51:52 +0900 Subject: [PATCH] libata: ATA_FLAG_IN_EH is not used, kill it Kill unused flag ATA_FLAG_IN_EH. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index a4a1e6304e78..e20b0bfbd5f2 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -152,7 +152,6 @@ enum { ATA_FLAG_IRQ_MASK = (1 << 14), /* Mask IRQ in PIO xfers */ ATA_FLAG_FLUSH_PORT_TASK = (1 << 15), /* Flush port task */ - ATA_FLAG_IN_EH = (1 << 16), /* EH in progress */ ATA_QCFLAG_ACTIVE = (1 << 1), /* cmd not yet ack'd to scsi lyer */ ATA_QCFLAG_SG = (1 << 3), /* have s/g table? */ -- cgit v1.2.2 From 949b38af40a0b88b7267908b1554a45b97b5b737 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 2 Apr 2006 18:51:52 +0900 Subject: [PATCH] libata: clean up constants * Reorder ATA_DFLAG_* such that feature flags determined by ata_dev_configure() are on lower bits. Reserve lower eight bits for this purpose and allocate dynamic flags from bit 8. * Reorder ATA_FLAG_* such that feature flags determined during driver initiailization are on bits 0:15, dynamic flags on 16:23 and LLDD specific flags on 24:31. * Kill trailing white space and lower-case an one line comment for consistency. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 61 ++++++++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 29 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index e20b0bfbd5f2..b7488a31e320 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -120,9 +120,10 @@ enum { ATA_SHT_USE_CLUSTERING = 1, /* struct ata_device stuff */ - ATA_DFLAG_LBA48 = (1 << 0), /* device supports LBA48 */ - ATA_DFLAG_PIO = (1 << 1), /* device currently in PIO mode */ - ATA_DFLAG_LBA = (1 << 2), /* device supports LBA */ + ATA_DFLAG_LBA = (1 << 0), /* device supports LBA */ + ATA_DFLAG_LBA48 = (1 << 1), /* device supports LBA48 */ + + ATA_DFLAG_PIO = (1 << 8), /* device currently in PIO mode */ ATA_DEV_UNKNOWN = 0, /* unknown device */ ATA_DEV_ATA = 1, /* ATA device */ @@ -132,32 +133,34 @@ enum { ATA_DEV_NONE = 5, /* no device */ /* struct ata_port flags */ - ATA_FLAG_SLAVE_POSS = (1 << 1), /* host supports slave dev */ + ATA_FLAG_SLAVE_POSS = (1 << 0), /* host supports slave dev */ /* (doesn't imply presence) */ - ATA_FLAG_PORT_DISABLED = (1 << 2), /* port is disabled, ignore it */ - ATA_FLAG_SATA = (1 << 3), - ATA_FLAG_NO_LEGACY = (1 << 4), /* no legacy mode check */ - ATA_FLAG_SRST = (1 << 5), /* (obsolete) use ATA SRST, not E.D.D. */ - ATA_FLAG_MMIO = (1 << 6), /* use MMIO, not PIO */ - ATA_FLAG_SATA_RESET = (1 << 7), /* (obsolete) use COMRESET */ - ATA_FLAG_PIO_DMA = (1 << 8), /* PIO cmds via DMA */ - ATA_FLAG_NOINTR = (1 << 9), /* FIXME: Remove this once - * proper HSM is in place. */ - ATA_FLAG_DEBUGMSG = (1 << 10), - ATA_FLAG_NO_ATAPI = (1 << 11), /* No ATAPI support */ - - ATA_FLAG_SUSPENDED = (1 << 12), /* port is suspended */ - - ATA_FLAG_PIO_LBA48 = (1 << 13), /* Host DMA engine is LBA28 only */ - ATA_FLAG_IRQ_MASK = (1 << 14), /* Mask IRQ in PIO xfers */ - - ATA_FLAG_FLUSH_PORT_TASK = (1 << 15), /* Flush port task */ - - ATA_QCFLAG_ACTIVE = (1 << 1), /* cmd not yet ack'd to scsi lyer */ - ATA_QCFLAG_SG = (1 << 3), /* have s/g table? */ - ATA_QCFLAG_SINGLE = (1 << 4), /* no s/g, just a single buffer */ + ATA_FLAG_SATA = (1 << 1), + ATA_FLAG_NO_LEGACY = (1 << 2), /* no legacy mode check */ + ATA_FLAG_MMIO = (1 << 3), /* use MMIO, not PIO */ + ATA_FLAG_SRST = (1 << 4), /* (obsolete) use ATA SRST, not E.D.D. */ + ATA_FLAG_SATA_RESET = (1 << 5), /* (obsolete) use COMRESET */ + 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_NOINTR = (1 << 16), /* FIXME: Remove this once + * proper HSM is in place. */ + ATA_FLAG_DEBUGMSG = (1 << 17), + ATA_FLAG_FLUSH_PORT_TASK = (1 << 18), /* flush port task */ + + ATA_FLAG_PORT_DISABLED = (1 << 19), /* port is disabled, ignore it */ + ATA_FLAG_SUSPENDED = (1 << 20), /* port is suspended */ + + /* bits 24:31 of ap->flags are reserved for LLDD specific flags */ + + /* struct ata_queued_cmd flags */ + ATA_QCFLAG_ACTIVE = (1 << 0), /* cmd not yet ack'd to scsi lyer */ + ATA_QCFLAG_SG = (1 << 1), /* have s/g table? */ + ATA_QCFLAG_SINGLE = (1 << 2), /* no s/g, just a single buffer */ ATA_QCFLAG_DMAMAP = ATA_QCFLAG_SG | ATA_QCFLAG_SINGLE, - ATA_QCFLAG_EH_SCHEDULED = (1 << 5), /* EH scheduled */ + ATA_QCFLAG_EH_SCHEDULED = (1 << 3), /* EH scheduled */ /* host set flags */ ATA_HOST_SIMPLEX = (1 << 0), /* Host is simplex, one DMA channel per host_set only */ @@ -206,8 +209,8 @@ enum { /* size of buffer to pad xfers ending on unaligned boundaries */ ATA_DMA_PAD_SZ = 4, ATA_DMA_PAD_BUF_SZ = ATA_DMA_PAD_SZ * ATA_MAX_QUEUE, - - /* Masks for port functions */ + + /* masks for port functions */ ATA_PORT_PRIMARY = (1 << 0), ATA_PORT_SECONDARY = (1 << 1), -- cgit v1.2.2 From 198e0fed9e59461fc1890dd8b75ec72d14638873 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 2 Apr 2006 18:51:52 +0900 Subject: [PATCH] libata: rename ATA_FLAG_PORT_DISABLED to ATA_FLAG_DISABLED Rename ATA_FLAG_PORT_DISABLED to ATA_FLAG_DISABLED for consistency. (ATA_FLAG_* are always about ports). Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index b7488a31e320..890262f44d0a 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -150,7 +150,7 @@ enum { ATA_FLAG_DEBUGMSG = (1 << 17), ATA_FLAG_FLUSH_PORT_TASK = (1 << 18), /* flush port task */ - ATA_FLAG_PORT_DISABLED = (1 << 19), /* port is disabled, ignore it */ + ATA_FLAG_DISABLED = (1 << 19), /* port is disabled, ignore it */ ATA_FLAG_SUSPENDED = (1 << 20), /* port is suspended */ /* bits 24:31 of ap->flags are reserved for LLDD specific flags */ -- cgit v1.2.2 From ea1dd4e13010eb9dd5ffb4bfabbb472bc238bebb Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 2 Apr 2006 18:51:53 +0900 Subject: [PATCH] libata: clear only affected flags during ata_dev_configure() ata_dev_configure() should not clear dynamic device flags determined elsewhere. Lower eight bits are reserved for feature flags, define ATA_DFLAG_CFG_MASK and clear only those bits before configuring device. Without this patch, ATA_DFLAG_PIO gets turned off during revalidation making PIO mode unuseable. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 890262f44d0a..cbbc821fe22c 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -122,6 +122,7 @@ enum { /* struct ata_device stuff */ ATA_DFLAG_LBA = (1 << 0), /* device supports LBA */ ATA_DFLAG_LBA48 = (1 << 1), /* device supports LBA48 */ + ATA_DFLAG_CFG_MASK = (1 << 8) - 1, ATA_DFLAG_PIO = (1 << 8), /* device currently in PIO mode */ -- cgit v1.2.2 From 2719736779da2c7fbb17d3de16c817b429bfeb9c Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 2 Apr 2006 18:51:53 +0900 Subject: [PATCH] libata: add ATA_QCFLAG_IO Add a new qc flag ATA_QCFLAG_IO. This flag gets set for normal IO commands originating from SCSI midlayer. This information will be used by EH to determine transfer speed reconfiguration. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index cbbc821fe22c..a6d829cb0567 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -161,7 +161,8 @@ enum { ATA_QCFLAG_SG = (1 << 1), /* have s/g table? */ ATA_QCFLAG_SINGLE = (1 << 2), /* no s/g, just a single buffer */ ATA_QCFLAG_DMAMAP = ATA_QCFLAG_SG | ATA_QCFLAG_SINGLE, - ATA_QCFLAG_EH_SCHEDULED = (1 << 3), /* EH scheduled */ + ATA_QCFLAG_IO = (1 << 3), /* standard IO command */ + ATA_QCFLAG_EH_SCHEDULED = (1 << 4), /* EH scheduled */ /* host set flags */ ATA_HOST_SIMPLEX = (1 << 0), /* Host is simplex, one DMA channel per host_set only */ -- cgit v1.2.2 From ece1d63619df010b8c4f08e43755e2a03f3b6eed Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 2 Apr 2006 18:51:53 +0900 Subject: [PATCH] libata: separate out libata-eh.c A lot of EH codes are about to be added to libata. Separate out libata-eh.c. ata_scsi_timed_out(), ata_scsi_error(), ata_qc_timeout(), ata_eng_timeout(), ata_eh_qc_complete() and ata_eh_qc_retry() are moved. No code is changed by this patch. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index a6d829cb0567..75bdee09c307 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -531,9 +531,6 @@ 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); extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)); -extern int ata_scsi_error(struct Scsi_Host *host); -extern void ata_eh_qc_complete(struct ata_queued_cmd *qc); -extern void ata_eh_qc_retry(struct ata_queued_cmd *qc); extern int ata_scsi_release(struct Scsi_Host *host); extern unsigned int ata_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc); extern int ata_scsi_device_resume(struct scsi_device *); @@ -582,7 +579,6 @@ extern void ata_bmdma_stop(struct ata_queued_cmd *qc); extern u8 ata_bmdma_status(struct ata_port *ap); extern void ata_bmdma_irq_clear(struct ata_port *ap); extern void __ata_qc_complete(struct ata_queued_cmd *qc); -extern void ata_eng_timeout(struct ata_port *ap); extern void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev, struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)); @@ -637,6 +633,14 @@ extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bit extern unsigned long ata_pci_default_filter(const struct ata_port *, struct ata_device *, unsigned long); #endif /* CONFIG_PCI */ +/* + * EH + */ +extern int ata_scsi_error(struct Scsi_Host *host); +extern void ata_eng_timeout(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); + static inline int ata_sg_is_last(struct scatterlist *sg, struct ata_queued_cmd *qc) -- cgit v1.2.2