diff options
author | Tejun Heo <htejun@gmail.com> | 2006-02-10 09:58:48 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2006-02-10 10:30:11 -0500 |
commit | 3a39746a5290445ea4238f21ac260e42106c1454 (patch) | |
tree | 7b667c30b70b2c140782974e34c2826ea85e9a07 /drivers/scsi/libata-core.c | |
parent | c5014de8a74f442a4441f21f690d8aae5dc8b432 (diff) |
[PATCH] libata: make new reset act identical to ->phy_reset register-wise
This patch makes std component operations act identical to ->phy_reset
register-wise except for SError clearing on sata_std_hardreset.
Note that if a driver only implements/uses hardreset, it should not
use ata_std_probeinit() to avoid extra sata_phy_resume() and
ata_busy_sleep() compared to ->phy_reset.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/scsi/libata-core.c')
-rw-r--r-- | drivers/scsi/libata-core.c | 51 |
1 files changed, 34 insertions, 17 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index b938c7a37664..8424bd9ee26d 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -1924,11 +1924,20 @@ static int sata_phy_resume(struct ata_port *ap) | |||
1924 | * | 1924 | * |
1925 | * @ap is about to be probed. Initialize it. This function is | 1925 | * @ap is about to be probed. Initialize it. This function is |
1926 | * to be used as standard callback for ata_drive_probe_reset(). | 1926 | * to be used as standard callback for ata_drive_probe_reset(). |
1927 | * | ||
1928 | * NOTE!!! Do not use this function as probeinit if a low level | ||
1929 | * driver implements only hardreset. Just pass NULL as probeinit | ||
1930 | * in that case. Using this function is probably okay but doing | ||
1931 | * so makes reset sequence different from the original | ||
1932 | * ->phy_reset implementation and Jeff nervous. :-P | ||
1927 | */ | 1933 | */ |
1928 | extern void ata_std_probeinit(struct ata_port *ap) | 1934 | extern void ata_std_probeinit(struct ata_port *ap) |
1929 | { | 1935 | { |
1930 | if (ap->flags & ATA_FLAG_SATA && ap->ops->scr_read) | 1936 | if (ap->flags & ATA_FLAG_SATA && ap->ops->scr_read) { |
1931 | sata_phy_resume(ap); | 1937 | sata_phy_resume(ap); |
1938 | if (sata_dev_present(ap)) | ||
1939 | ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); | ||
1940 | } | ||
1932 | } | 1941 | } |
1933 | 1942 | ||
1934 | /** | 1943 | /** |
@@ -1954,20 +1963,17 @@ int ata_std_softreset(struct ata_port *ap, int verbose, unsigned int *classes) | |||
1954 | 1963 | ||
1955 | DPRINTK("ENTER\n"); | 1964 | DPRINTK("ENTER\n"); |
1956 | 1965 | ||
1966 | if (ap->ops->scr_read && !sata_dev_present(ap)) { | ||
1967 | classes[0] = ATA_DEV_NONE; | ||
1968 | goto out; | ||
1969 | } | ||
1970 | |||
1957 | /* determine if device 0/1 are present */ | 1971 | /* determine if device 0/1 are present */ |
1958 | if (ata_devchk(ap, 0)) | 1972 | if (ata_devchk(ap, 0)) |
1959 | devmask |= (1 << 0); | 1973 | devmask |= (1 << 0); |
1960 | if (slave_possible && ata_devchk(ap, 1)) | 1974 | if (slave_possible && ata_devchk(ap, 1)) |
1961 | devmask |= (1 << 1); | 1975 | devmask |= (1 << 1); |
1962 | 1976 | ||
1963 | /* devchk reports device presence without actual device on | ||
1964 | * most SATA controllers. Check SStatus and turn devmask off | ||
1965 | * if link is offline. Note that we should continue resetting | ||
1966 | * even when it seems like there's no device. | ||
1967 | */ | ||
1968 | if (ap->ops->scr_read && !sata_dev_present(ap)) | ||
1969 | devmask = 0; | ||
1970 | |||
1971 | /* select device 0 again */ | 1977 | /* select device 0 again */ |
1972 | ap->ops->dev_select(ap, 0); | 1978 | ap->ops->dev_select(ap, 0); |
1973 | 1979 | ||
@@ -1989,6 +1995,7 @@ int ata_std_softreset(struct ata_port *ap, int verbose, unsigned int *classes) | |||
1989 | if (slave_possible && err != 0x81) | 1995 | if (slave_possible && err != 0x81) |
1990 | classes[1] = ata_dev_try_classify(ap, 1, &err); | 1996 | classes[1] = ata_dev_try_classify(ap, 1, &err); |
1991 | 1997 | ||
1998 | out: | ||
1992 | DPRINTK("EXIT, classes[0]=%u [1]=%u\n", classes[0], classes[1]); | 1999 | DPRINTK("EXIT, classes[0]=%u [1]=%u\n", classes[0], classes[1]); |
1993 | return 0; | 2000 | return 0; |
1994 | } | 2001 | } |
@@ -2047,6 +2054,8 @@ int sata_std_hardreset(struct ata_port *ap, int verbose, unsigned int *class) | |||
2047 | return -EIO; | 2054 | return -EIO; |
2048 | } | 2055 | } |
2049 | 2056 | ||
2057 | ap->ops->dev_select(ap, 0); /* probably unnecessary */ | ||
2058 | |||
2050 | *class = ata_dev_try_classify(ap, 0, NULL); | 2059 | *class = ata_dev_try_classify(ap, 0, NULL); |
2051 | 2060 | ||
2052 | DPRINTK("EXIT, class=%u\n", *class); | 2061 | DPRINTK("EXIT, class=%u\n", *class); |
@@ -2081,11 +2090,9 @@ void ata_std_postreset(struct ata_port *ap, unsigned int *classes) | |||
2081 | if (ap->cbl == ATA_CBL_SATA) | 2090 | if (ap->cbl == ATA_CBL_SATA) |
2082 | sata_print_link_status(ap); | 2091 | sata_print_link_status(ap); |
2083 | 2092 | ||
2084 | /* bail out if no device is present */ | 2093 | /* re-enable interrupts */ |
2085 | if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE) { | 2094 | if (ap->ioaddr.ctl_addr) /* FIXME: hack. create a hook instead */ |
2086 | DPRINTK("EXIT, no device\n"); | 2095 | ata_irq_on(ap); |
2087 | return; | ||
2088 | } | ||
2089 | 2096 | ||
2090 | /* is double-select really necessary? */ | 2097 | /* is double-select really necessary? */ |
2091 | if (classes[0] != ATA_DEV_NONE) | 2098 | if (classes[0] != ATA_DEV_NONE) |
@@ -2093,9 +2100,19 @@ void ata_std_postreset(struct ata_port *ap, unsigned int *classes) | |||
2093 | if (classes[1] != ATA_DEV_NONE) | 2100 | if (classes[1] != ATA_DEV_NONE) |
2094 | ap->ops->dev_select(ap, 0); | 2101 | ap->ops->dev_select(ap, 0); |
2095 | 2102 | ||
2096 | /* re-enable interrupts & set up device control */ | 2103 | /* bail out if no device is present */ |
2097 | if (ap->ioaddr.ctl_addr) /* FIXME: hack. create a hook instead */ | 2104 | if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE) { |
2098 | ata_irq_on(ap); | 2105 | DPRINTK("EXIT, no device\n"); |
2106 | return; | ||
2107 | } | ||
2108 | |||
2109 | /* set up device control */ | ||
2110 | if (ap->ioaddr.ctl_addr) { | ||
2111 | if (ap->flags & ATA_FLAG_MMIO) | ||
2112 | writeb(ap->ctl, (void __iomem *) ap->ioaddr.ctl_addr); | ||
2113 | else | ||
2114 | outb(ap->ctl, ap->ioaddr.ctl_addr); | ||
2115 | } | ||
2099 | 2116 | ||
2100 | DPRINTK("EXIT\n"); | 2117 | DPRINTK("EXIT\n"); |
2101 | } | 2118 | } |