From fc085150b491bfc186efbca90a14cf907a3060a9 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 10 Oct 2006 14:28:11 -0700 Subject: [PATCH] libata: add 40pin "short" cable support, honour drive side speed detection [deweerdt@free.fr: build fix] Signed-off-by: Alan Cox Signed-off-by: Frederik Deweerdt Cc: Tejun Heo Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- include/linux/ata.h | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/ata.h b/include/linux/ata.h index d8944190702..1df941648a5 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -200,8 +200,9 @@ enum { ATA_CBL_NONE = 0, ATA_CBL_PATA40 = 1, ATA_CBL_PATA80 = 2, - ATA_CBL_PATA_UNK = 3, - ATA_CBL_SATA = 4, + ATA_CBL_PATA40_SHORT = 3, /* 40 wire cable to high UDMA spec */ + ATA_CBL_PATA_UNK = 4, + ATA_CBL_SATA = 5, /* SATA Status and Control Registers */ SCR_STATUS = 0, @@ -342,6 +343,15 @@ static inline int ata_id_is_cfa(const u16 *id) return 0; } +static inline int ata_drive_40wire(const u16 *dev_id) +{ + if (ata_id_major_version(dev_id) >= 5 && ata_id_is_sata(dev_id)) + return 0; /* SATA */ + if (dev_id[93] & 0x4000) + return 0; /* 80 wire */ + return 1; +} + static inline int atapi_cdb_len(const u16 *dev_id) { u16 tmp = dev_id[0] & 0x3; -- cgit v1.2.3 From 6919a0a6cfdad9e83d02cef5973826acd416560c Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 27 Oct 2006 19:08:46 -0700 Subject: [PATCH] libata: Revamp blacklist support to allow multiple kinds of blacklisting flaws Signed-off-by: Alan Cox Cc: Jeff Garzik Cc: Tejun Heo Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- include/linux/libata.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index abd2debebca..2300fcc37f8 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -307,6 +307,8 @@ enum { (some horkage may be drive/controller pair dependant */ ATA_HORKAGE_DIAGNOSTIC = (1 << 0), /* Failed boot diag */ + ATA_HORKAGE_NODMA = (1 << 1), /* DMA problems */ + ATA_HORKAGE_NONCQ = (1 << 2), /* Don't use NCQ */ }; enum hsm_task_states { @@ -787,6 +789,7 @@ extern void ata_id_string(const u16 *id, unsigned char *s, unsigned int ofs, unsigned int len); extern void ata_id_c_string(const u16 *id, unsigned char *s, unsigned int ofs, unsigned int len); +extern unsigned long ata_device_blacklisted(const struct ata_device *dev); extern void ata_bmdma_setup (struct ata_queued_cmd *qc); extern void ata_bmdma_start (struct ata_queued_cmd *qc); extern void ata_bmdma_stop(struct ata_queued_cmd *qc); -- cgit v1.2.3 From a20c9e820864e18b59d2a4f2f04e8b6053986c95 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 27 Oct 2006 19:08:48 -0700 Subject: [PATCH] ata: Generic platform_device libata driver needs a changelog Signed-off-by: Paul Mundt Acked-by: Russell King Cc: Jeff Garzik Cc: Tejun Heo Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- include/linux/pata_platform.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 include/linux/pata_platform.h (limited to 'include') diff --git a/include/linux/pata_platform.h b/include/linux/pata_platform.h new file mode 100644 index 00000000000..2d5fd647e0e --- /dev/null +++ b/include/linux/pata_platform.h @@ -0,0 +1,13 @@ +#ifndef __LINUX_PATA_PLATFORM_H +#define __LINUX_PATA_PLATFORM_H + +struct pata_platform_info { + /* + * I/O port shift, for platforms with ports that are + * constantly spaced and need larger than the 1-byte + * spacing used by ata_std_ports(). + */ + unsigned int ioport_shift; +}; + +#endif /* __LINUX_PATA_PLATFORM_H */ -- cgit v1.2.3 From d1adc1bbd6dde3e05a91e2d3e6ab42d202ea61d5 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 9 Oct 2006 18:32:15 +0900 Subject: [PATCH] libata: handle 0xff status properly libata waits for !BSY even when the status register reports 0xff. This causes long boot delays when D8 isn't pulled down properly. This patch does the followings. * don't wait if status register is 0xff in all wait functions * make ata_busy_sleep() return 0 on success and -errno on failure. -ENODEV is returned on 0xff status and -EBUSY on other failures. * make ata_bus_softreset() succeed on 0xff status. 0xff status is not reset failure. It indicates no device. This removes unnecessary retries on such ports. Note that the code change assumes unoccupied port reporting 0xff status does not produce valid device signature. Signed-off-by: Tejun Heo Cc: Joe Jin Signed-off-by: Jeff Garzik --- include/linux/libata.h | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index 2300fcc37f8..6c003d852a8 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -746,9 +746,8 @@ extern int ata_scsi_device_suspend(struct scsi_device *, pm_message_t mesg); extern int ata_host_suspend(struct ata_host *host, pm_message_t mesg); extern void ata_host_resume(struct ata_host *host); extern int ata_ratelimit(void); -extern unsigned int ata_busy_sleep(struct ata_port *ap, - unsigned long timeout_pat, - unsigned long timeout); +extern int ata_busy_sleep(struct ata_port *ap, + unsigned long timeout_pat, unsigned long timeout); extern void ata_port_queue_task(struct ata_port *ap, void (*fn)(void *), void *data, unsigned long delay); extern u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val, @@ -1064,7 +1063,7 @@ static inline u8 ata_busy_wait(struct ata_port *ap, unsigned int bits, udelay(10); status = ata_chk_status(ap); max--; - } while ((status & bits) && (max > 0)); + } while (status != 0xff && (status & bits) && (max > 0)); return status; } @@ -1085,7 +1084,7 @@ static inline u8 ata_wait_idle(struct ata_port *ap) { u8 status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000); - if (status & (ATA_BUSY | ATA_DRQ)) { + if (status != 0xff && (status & (ATA_BUSY | ATA_DRQ))) { unsigned long l = ap->ioaddr.status_addr; if (ata_msg_warn(ap)) printk(KERN_WARNING "ATA: abnormal status 0x%X on port 0x%lX\n", -- cgit v1.2.3 From 90088bb41200b4da962282dfd45db82544adac3b Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 9 Oct 2006 11:10:26 +0900 Subject: [PATCH] libata: move ata_irq_on() into libata-sff.c ata_irq_on() isn't used outside of libata core layer. The function is TF/SFF interface specific but currently used by core path with some hack too. Move it from include/linux/libata.h to drivers/ata/libata-sff.c. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 31 ------------------------------- 1 file changed, 31 deletions(-) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index 6c003d852a8..d3bf7b936c3 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1149,37 +1149,6 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc) qc->result_tf.feature = 0; } -/** - * ata_irq_on - Enable interrupts on a port. - * @ap: Port on which interrupts are enabled. - * - * Enable interrupts on a legacy IDE device using MMIO or PIO, - * wait for idle, clear any pending interrupts. - * - * LOCKING: - * Inherited from caller. - */ - -static inline u8 ata_irq_on(struct ata_port *ap) -{ - struct ata_ioports *ioaddr = &ap->ioaddr; - u8 tmp; - - ap->ctl &= ~ATA_NIEN; - ap->last_ctl = ap->ctl; - - if (ap->flags & ATA_FLAG_MMIO) - writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr); - else - outb(ap->ctl, ioaddr->ctl_addr); - tmp = ata_wait_idle(ap); - - ap->ops->irq_clear(ap); - - return tmp; -} - - /** * ata_irq_ack - Acknowledge a device interrupt. * @ap: Port on which interrupts are enabled. -- cgit v1.2.3 From b6103f6d1659e2024776bc759d28613fb36344a8 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 1 Nov 2006 17:59:53 +0900 Subject: [PATCH] libata: separate out and export sata_port_hardreset() Separate out sata_port_hardreset() from sata_std_hardreset(). This will be used by LLD hardreset implementation and later by PMP. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index d3bf7b936c3..41fa0890dbf 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -702,6 +702,8 @@ 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_port_hardreset(struct ata_port *ap, + const unsigned long *timing); extern int sata_std_hardreset(struct ata_port *ap, unsigned int *class); extern void ata_std_postreset(struct ata_port *ap, unsigned int *classes); extern void ata_port_disable(struct ata_port *); -- cgit v1.2.3 From efdaedc443e935eda82e9e78a6e65d1f993d242f Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 1 Nov 2006 18:38:52 +0900 Subject: [PATCH] libata: implement ATA_EHI_PRINTINFO Implement ehi flag ATA_EHI_PRINTINFO. This flag is set when device configuration needs to print out device info. This used to be handled by @print_info argument to ata_dev_configure() but LLDs also need to know about it in ->dev_config() callback. This patch replaces @print_info w/ ATA_EHI_PRINTINFO and make sata_sil print workaround messages only on the initial configuration. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index 41fa0890dbf..949484627e6 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -283,6 +283,7 @@ enum { ATA_EHI_QUIET = (1 << 3), /* be quiet */ ATA_EHI_DID_RESET = (1 << 16), /* already reset this port */ + ATA_EHI_PRINTINFO = (1 << 17), /* print configuration info */ ATA_EHI_RESET_MODIFIER_MASK = ATA_EHI_RESUME_LINK, -- cgit v1.2.3 From baa1e78a834c917984a4659fd282f712c17ee3bf Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 1 Nov 2006 18:39:27 +0900 Subject: [PATCH] libata: implement ATA_EHI_SETMODE and ATA_EHI_POST_SETMODE libata EH used to perform ata_set_mode() iff the EH session performed reset as indicated by ATA_EHI_DID_RESET. This is incorrect because ->dev_config() called by revalidation is allowed to modify transfer mode which ata_set_mode() should take care of. This patch implements the following two flags. * ATA_EHI_SETMODE: set during EH to schedule ata_set_mode(). Both new device attachment and revalidation set this flag. * ATA_EHI_POST_SETMODE: set while the device is revalidated after ata_set_mode(). Post-setmode revalidation is different from initial configuaration and EH revalidation in that ->dev_config() is not allowed tune transfer mode. LLD can use this flag to determine whether it's allowed to tune transfer mode. Note that POST_SETMODE ->dev_config() is guaranteed to be preceded by non-POST_SETMODE ->dev_config(). Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index 949484627e6..0d0ddeaee73 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -284,6 +284,8 @@ enum { ATA_EHI_DID_RESET = (1 << 16), /* already reset this port */ ATA_EHI_PRINTINFO = (1 << 17), /* print configuration info */ + ATA_EHI_SETMODE = (1 << 18), /* configure transfer mode */ + ATA_EHI_POST_SETMODE = (1 << 19), /* revaildating after setmode */ ATA_EHI_RESET_MODIFIER_MASK = ATA_EHI_RESUME_LINK, -- cgit v1.2.3 From 0df0d0a0ea9ffcee4e56f96cd9d9e32b0644eb21 Mon Sep 17 00:00:00 2001 From: Alessandro Zummo Date: Tue, 14 Nov 2006 13:43:21 -0500 Subject: [libata] ARM: add ixp4xx PATA driver Signed-off-by: Alessandro Zummo Signed-off-by: Jeff Garzik --- include/asm-arm/arch-ixp4xx/platform.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'include') diff --git a/include/asm-arm/arch-ixp4xx/platform.h b/include/asm-arm/arch-ixp4xx/platform.h index 8d10a918769..ab194e5f665 100644 --- a/include/asm-arm/arch-ixp4xx/platform.h +++ b/include/asm-arm/arch-ixp4xx/platform.h @@ -86,6 +86,19 @@ struct ixp4xx_i2c_pins { unsigned long scl_pin; }; +/* + * This structure provide a means for the board setup code + * to give information to th pata_ixp4xx driver. It is + * passed as platform_data. + */ +struct ixp4xx_pata_data { + volatile u32 *cs0_cfg; + volatile u32 *cs1_cfg; + unsigned long cs0_bits; + unsigned long cs1_bits; + void __iomem *cs0; + void __iomem *cs1; +}; struct sys_timer; -- cgit v1.2.3 From 6fc49adb9417b9c793e8f88d485387bb89ceb733 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 11 Nov 2006 20:10:45 +0900 Subject: [PATCH] libata: use FLUSH_EXT only when driver is larger than LBA28 limit Many drives support LBA48 even when its capacity is smaller than 1<<28, as LBA48 is required for many functionalities. FLUSH_EXT is mandatory for drives w/ LBA48 support. Interestingly, at least one of such drives (ST960812A) has problems dealing with FLUSH_EXT. It eventually completes the command but takes around 7 seconds to finish in many cases thus drastically slowing down IO transactions. This seems to be a firmware bug which sneaked into production probably because no other ATA driver including linux IDE issues FLUSH_EXT to drives which report support for LBA48 & FLUSH_EXT but is smaller than 1<<28 blocks. This patch adds ATA_DFLAG_FLUSH_EXT which is set iff the drive supports LBA48 & FLUSH_EXT and is larger than LBA28 limit. Both cache flush paths are updated to issue FLUSH_EXT only when the flag is set. Note that the changed behavior is more inline with the rest of libata. libata prefers shorter commands whenever possible. Signed-off-by: Tejun Heo Cc: Danny Kukawka Cc: Stefan Seyfried Signed-off-by: Jeff Garzik --- include/linux/libata.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index 0d0ddeaee73..36e233cc388 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -140,6 +140,7 @@ enum { ATA_DFLAG_LBA48 = (1 << 1), /* device supports LBA48 */ ATA_DFLAG_CDB_INTR = (1 << 2), /* device asserts INTRQ when ready for CDB */ ATA_DFLAG_NCQ = (1 << 3), /* device supports NCQ */ + ATA_DFLAG_FLUSH_EXT = (1 << 4), /* do FLUSH_EXT instead of FLUSH */ ATA_DFLAG_CFG_MASK = (1 << 8) - 1, ATA_DFLAG_PIO = (1 << 8), /* device limited to PIO mode */ -- cgit v1.2.3 From 55a8e2c83ce50548dfef74bb19dfe2b809cb3099 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 10 Nov 2006 18:08:10 +0900 Subject: [PATCH] libata: implement presence detection via polling IDENTIFY On some controllers (ICHs in piix mode), there is *NO* reliable way to determine device presence other than issuing IDENTIFY and see how the transaction proceeds by watching the TF status register. libata acted this way before irq-pio and phantom devices caused very little problem but now that IDENTIFY is performed using IRQ drive PIO, such phantom devices now result in multiple 30sec timeouts during boot. This patch implements ATA_FLAG_DETECT_POLLING. If a LLD sets this flag, libata core issues the initial IDENTIFY in polling mode and if the initial data transfer fails w/ HSM violation, the port is considered to be empty thus replicating the old libata and IDE behavior. Signed-off-by: Jeff Garzik --- include/linux/libata.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index 36e233cc388..9080789913f 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -176,6 +176,8 @@ enum { ATA_FLAG_SKIP_D2H_BSY = (1 << 12), /* can't wait for the first D2H * Register FIS clearing BSY */ ATA_FLAG_DEBUGMSG = (1 << 13), + ATA_FLAG_DETECT_POLLING = (1 << 14), /* detect device presence by + * polling IDENTIFY */ /* The following flag belongs to ap->pflags but is kept in * ap->flags because it's referenced in many LLDs and will be @@ -335,6 +337,7 @@ enum ata_completion_errors { AC_ERR_SYSTEM = (1 << 6), /* system error */ AC_ERR_INVALID = (1 << 7), /* invalid argument */ AC_ERR_OTHER = (1 << 8), /* unknown */ + AC_ERR_NODEV_HINT = (1 << 9), /* polling device detection hint */ }; /* forward declarations */ -- cgit v1.2.3 From 582982e6991d6718ddadf8751072b50a850dde48 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 17 Nov 2006 12:05:11 +0900 Subject: [PATCH] libata: remove unused HSM_ST_UNKNOWN HSM_ST_UNKNOWN is not used anywhere. Its value is zero and supposed to serve sanity check purpose but HSM_ST_IDLE is used for that purpose. This unused state causes confusion. After a port is initialized but before the first command is executed, the idle hsm state is UNKNOWN. However, once a command has completed, the idle hsm state is IDLE. This defeats sanity check in ata_pio_task() for the first command. This patch removes HSM_ST_UNKNOWN and consequently make HSM_ST_IDLE the default state. Signed-off-by: Tejun Heo --- include/linux/libata.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index 9080789913f..6013211ac7d 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -318,7 +318,6 @@ enum { }; enum hsm_task_states { - HSM_ST_UNKNOWN, /* state unknown */ HSM_ST_IDLE, /* no command on going */ HSM_ST, /* (waiting the device to) transfer data */ HSM_ST_LAST, /* (waiting the device to) complete command */ -- cgit v1.2.3 From 3d3cca37559e3ab2b574eda11ed5207ccdb8980a Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 16 Nov 2006 10:50:50 +0900 Subject: [PATCH] libata: implement ATA_FLAG_SETXFER_POLLING and use it in pata_via, take #2 This patch implements ATA_FLAG_SETXFER_POLLING and use in pata_via. If this flag is set, transfer mode setting performed by polling not by interrupt. This should help those controllers which raise interrupt before the command is actually complete on SETXFER. Rationale for this approach. * uses existing facility and relatively simple * no busy sleep in the interrupt handler * updating drivers is easy While at it, kill now unused flag ATA_FLAG_SRST in pata_via. Signed-off-by: Tejun Heo --- include/linux/libata.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index 6013211ac7d..8b57b6a806c 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -178,6 +178,7 @@ enum { ATA_FLAG_DEBUGMSG = (1 << 13), ATA_FLAG_DETECT_POLLING = (1 << 14), /* detect device presence by * polling IDENTIFY */ + ATA_FLAG_SETXFER_POLLING= (1 << 15), /* use polling for SETXFER */ /* The following flag belongs to ap->pflags but is kept in * ap->flags because it's referenced in many LLDs and will be -- cgit v1.2.3 From 800b399669ad495ad4361d134df87401ae36f44f Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 3 Dec 2006 21:34:13 +0900 Subject: [PATCH] libata: always use polling IDENTIFY libata switched to IRQ-driven IDENTIFY when IRQ-driven PIO was introduced. This has caused a lot of problems including device misdetection and phantom device. ATA_FLAG_DETECT_POLLING was added recently to selectively use polling IDENTIFY on problemetic drivers but many controllers and devices are affected by this problem and trying to adding ATA_FLAG_DETECT_POLLING for each such case is diffcult and not very rewarding. This patch makes libata always use polling IDENTIFY. This is consistent with libata's original behavior and drivers/ide's behavior. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index 8b57b6a806c..202283b5df9 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -176,9 +176,7 @@ enum { ATA_FLAG_SKIP_D2H_BSY = (1 << 12), /* can't wait for the first D2H * Register FIS clearing BSY */ ATA_FLAG_DEBUGMSG = (1 << 13), - ATA_FLAG_DETECT_POLLING = (1 << 14), /* detect device presence by - * polling IDENTIFY */ - ATA_FLAG_SETXFER_POLLING= (1 << 15), /* use polling for SETXFER */ + ATA_FLAG_SETXFER_POLLING= (1 << 14), /* use polling for SETXFER */ /* The following flag belongs to ap->pflags but is kept in * ap->flags because it's referenced in many LLDs and will be -- cgit v1.2.3