Message ID | AANLkTinyJdTYXgpfvmw8vRBEFOc+SdCKe9hBZbGk1oLd@mail.gmail.com |
---|---|
State | Not Applicable |
Delegated to: | David Miller |
Headers | show |
Hello, On 12/01/2010 06:53 AM, Lin Mac wrote: > While using multiplier with CONFIG_SATA_PMP enabled, or using disks directly > without CONFIG_SATA_PMP have no issue. > > It is because sata_srst_pmp always return SATA_PMP_CTRL_PORT(15), > which casued ahci_do_softreset with pmp 15, which is not needed for > disks connected directly. SRST w/ PMP==15 is the standard defined way to probe devices for PMP capable controllers. > With SPMH3726-P rev:2.1.2, ata_dev_classify would report ATA_DEV_UNKNOWN on > ahci_hardreset. While with a Segate Barracuda 1TB SATA HD, it is ATA_DEV_ATA. > Therefore, the pmp returned by sata_srst_pmp should depends on the class > reported by ahci_hardreset. IIRC, PMP should return the signature of the first device after hardreset. At any rate, the standard sanctioned way to probe is SRST w/ PMP==15. > This patch does 2 things: > 1. ata_eh_reset calls ata_do_reset upon SRST without clearing classes, to be > used by sata_srst_pmp to decide pmp. > 2. sata_srst_pmp returns SATA_PMP_CTRL_PORT only when class is ATA_DEV_PMP or > ATA_DEV_UNKNOWN So, no, this isn't acceptable. You're making the behavior deviate from the standard for all controllers and devices to work around a faulty, rather obscure controller. If you want to work around, please implement a workaround which is specific to the controller in question. Thanks.
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index ebc08d6..21f343b 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -1301,9 +1301,9 @@ EXPORT_SYMBOL_GPL(ahci_check_ready); static int ahci_softreset(struct ata_link *link, unsigned int *class, unsigned long deadline) { - int pmp = sata_srst_pmp(link); + int pmp = sata_srst_pmp(link, class); - DPRINTK("ENTER\n"); + DPRINTK("ENTER pmp=%d\n", pmp); return ahci_do_softreset(link, class, pmp, deadline, ahci_check_ready); } diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 5e59050..ca43f33 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -2703,7 +2703,8 @@ int ata_eh_reset(struct ata_link *link, int classify, } ata_eh_about_to_do(link, NULL, ATA_EH_RESET); - rc = ata_do_reset(link, reset, classes, deadline, true); + rc = ata_do_reset(link, reset, classes, deadline, + false); if (rc) { failed_link = link; goto fail; diff --git a/include/linux/libata.h b/include/linux/libata.h index d947b12..792745d 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1239,9 +1239,10 @@ static inline int ata_is_host_link(const struct ata_link *link) } #endif /* CONFIG_SATA_PMP */ -static inline int sata_srst_pmp(struct ata_link *link) +static inline int sata_srst_pmp(struct ata_link *link, unsigned int *class) { - if (sata_pmp_supported(link->ap) && ata_is_host_link(link)) + if (sata_pmp_supported(link->ap) && ata_is_host_link(link) && + (*class == ATA_DEV_PMP || *class == ATA_DEV_UNKNOWN)) return SATA_PMP_CTRL_PORT; return link->pmp;