aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2008-04-07 09:47:22 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-04-17 15:44:25 -0400
commit071f44b1d2c051641b62a3571223314737ccbe59 (patch)
treea07794c8109e5d82a78223ae0159eadbf862c463 /drivers/ata
parent48515f6c006c2a9d7b624ee8ad068018c2d3fe0e (diff)
libata: implement PMP helpers
Implement helpers to test whether PMP is supported, attached and determine pmp number to use when issuing SRST to a link. While at it, move ata_is_host_link() so that it's together with the two new PMP helpers. This change simplifies LLDs and helps making PMP support optional. Signed-off-by: Tejun Heo <htejun@gmail.com>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/ahci.c30
-rw-r--r--drivers/ata/libata-acpi.c2
-rw-r--r--drivers/ata/libata-core.c4
-rw-r--r--drivers/ata/libata-eh.c14
-rw-r--r--drivers/ata/libata-pmp.c6
-rw-r--r--drivers/ata/libata-scsi.c6
-rw-r--r--drivers/ata/sata_sil24.c27
7 files changed, 29 insertions, 60 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 6281f7f9eae6..0de6432ee026 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -260,8 +260,6 @@ static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
260static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class, 260static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class,
261 unsigned long deadline); 261 unsigned long deadline);
262static void ahci_postreset(struct ata_link *link, unsigned int *class); 262static void ahci_postreset(struct ata_link *link, unsigned int *class);
263static int ahci_pmp_softreset(struct ata_link *link, unsigned int *class,
264 unsigned long deadline);
265static void ahci_error_handler(struct ata_port *ap); 263static void ahci_error_handler(struct ata_port *ap);
266static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); 264static void ahci_post_internal_cmd(struct ata_queued_cmd *qc);
267static int ahci_port_resume(struct ata_port *ap); 265static int ahci_port_resume(struct ata_port *ap);
@@ -301,7 +299,7 @@ static struct ata_port_operations ahci_ops = {
301 .softreset = ahci_softreset, 299 .softreset = ahci_softreset,
302 .hardreset = ahci_hardreset, 300 .hardreset = ahci_hardreset,
303 .postreset = ahci_postreset, 301 .postreset = ahci_postreset,
304 .pmp_softreset = ahci_pmp_softreset, 302 .pmp_softreset = ahci_softreset,
305 .error_handler = ahci_error_handler, 303 .error_handler = ahci_error_handler,
306 .post_internal_cmd = ahci_post_internal_cmd, 304 .post_internal_cmd = ahci_post_internal_cmd,
307 .dev_config = ahci_dev_config, 305 .dev_config = ahci_dev_config,
@@ -1263,10 +1261,11 @@ static int ahci_check_ready(struct ata_link *link)
1263 return 0; 1261 return 0;
1264} 1262}
1265 1263
1266static int ahci_do_softreset(struct ata_link *link, unsigned int *class, 1264static int ahci_softreset(struct ata_link *link, unsigned int *class,
1267 int pmp, unsigned long deadline) 1265 unsigned long deadline)
1268{ 1266{
1269 struct ata_port *ap = link->ap; 1267 struct ata_port *ap = link->ap;
1268 int pmp = sata_srst_pmp(link);
1270 const char *reason = NULL; 1269 const char *reason = NULL;
1271 unsigned long now, msecs; 1270 unsigned long now, msecs;
1272 struct ata_taskfile tf; 1271 struct ata_taskfile tf;
@@ -1326,17 +1325,6 @@ static int ahci_do_softreset(struct ata_link *link, unsigned int *class,
1326 return rc; 1325 return rc;
1327} 1326}
1328 1327
1329static int ahci_softreset(struct ata_link *link, unsigned int *class,
1330 unsigned long deadline)
1331{
1332 int pmp = 0;
1333
1334 if (link->ap->flags & ATA_FLAG_PMP)
1335 pmp = SATA_PMP_CTRL_PORT;
1336
1337 return ahci_do_softreset(link, class, pmp, deadline);
1338}
1339
1340static int ahci_hardreset(struct ata_link *link, unsigned int *class, 1328static int ahci_hardreset(struct ata_link *link, unsigned int *class,
1341 unsigned long deadline) 1329 unsigned long deadline)
1342{ 1330{
@@ -1457,12 +1445,6 @@ static void ahci_postreset(struct ata_link *link, unsigned int *class)
1457 } 1445 }
1458} 1446}
1459 1447
1460static int ahci_pmp_softreset(struct ata_link *link, unsigned int *class,
1461 unsigned long deadline)
1462{
1463 return ahci_do_softreset(link, class, link->pmp, deadline);
1464}
1465
1466static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl) 1448static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl)
1467{ 1449{
1468 struct scatterlist *sg; 1450 struct scatterlist *sg;
@@ -1581,7 +1563,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
1581 unk[0], unk[1], unk[2], unk[3]); 1563 unk[0], unk[1], unk[2], unk[3]);
1582 } 1564 }
1583 1565
1584 if (ap->nr_pmp_links && (irq_stat & PORT_IRQ_BAD_PMP)) { 1566 if (sata_pmp_attached(ap) && (irq_stat & PORT_IRQ_BAD_PMP)) {
1585 active_ehi->err_mask |= AC_ERR_HSM; 1567 active_ehi->err_mask |= AC_ERR_HSM;
1586 active_ehi->action |= ATA_EH_RESET; 1568 active_ehi->action |= ATA_EH_RESET;
1587 ata_ehi_push_desc(active_ehi, "incorrect PMP"); 1569 ata_ehi_push_desc(active_ehi, "incorrect PMP");
@@ -1847,7 +1829,7 @@ static int ahci_port_resume(struct ata_port *ap)
1847 ahci_power_up(ap); 1829 ahci_power_up(ap);
1848 ahci_start_port(ap); 1830 ahci_start_port(ap);
1849 1831
1850 if (ap->nr_pmp_links) 1832 if (sata_pmp_attached(ap))
1851 ahci_pmp_attach(ap); 1833 ahci_pmp_attach(ap);
1852 else 1834 else
1853 ahci_pmp_detach(ap); 1835 ahci_pmp_detach(ap);
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index bf98a566adac..f88a4f940e11 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -77,7 +77,7 @@ void ata_acpi_associate_sata_port(struct ata_port *ap)
77{ 77{
78 WARN_ON(!(ap->flags & ATA_FLAG_ACPI_SATA)); 78 WARN_ON(!(ap->flags & ATA_FLAG_ACPI_SATA));
79 79
80 if (!ap->nr_pmp_links) { 80 if (!sata_pmp_attached(ap)) {
81 acpi_integer adr = SATA_ADR(ap->port_no, NO_PORT_MULT); 81 acpi_integer adr = SATA_ADR(ap->port_no, NO_PORT_MULT);
82 82
83 ap->link.device->acpi_handle = 83 ap->link.device->acpi_handle =
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index b2d5d63fb6c9..3401248180c9 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -2278,7 +2278,7 @@ int ata_dev_configure(struct ata_device *dev)
2278 * changed notifications and ATAPI ANs. 2278 * changed notifications and ATAPI ANs.
2279 */ 2279 */
2280 if ((ap->flags & ATA_FLAG_AN) && ata_id_has_atapi_AN(id) && 2280 if ((ap->flags & ATA_FLAG_AN) && ata_id_has_atapi_AN(id) &&
2281 (!ap->nr_pmp_links || 2281 (!sata_pmp_attached(ap) ||
2282 sata_scr_read(&ap->link, SCR_NOTIFICATION, &sntf) == 0)) { 2282 sata_scr_read(&ap->link, SCR_NOTIFICATION, &sntf) == 0)) {
2283 unsigned int err_mask; 2283 unsigned int err_mask;
2284 2284
@@ -3623,7 +3623,7 @@ int sata_link_hardreset(struct ata_link *link, const unsigned long *timing,
3623 if (online) 3623 if (online)
3624 *online = true; 3624 *online = true;
3625 3625
3626 if ((link->ap->flags & ATA_FLAG_PMP) && ata_is_host_link(link)) { 3626 if (sata_pmp_supported(link->ap) && ata_is_host_link(link)) {
3627 /* If PMP is supported, we have to do follow-up SRST. 3627 /* If PMP is supported, we have to do follow-up SRST.
3628 * Some PMPs don't send D2H Reg FIS after hardreset if 3628 * Some PMPs don't send D2H Reg FIS after hardreset if
3629 * the first port is empty. Wait only for 3629 * the first port is empty. Wait only for
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 4ec1397434c0..99f83bdc572b 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -873,9 +873,9 @@ int sata_async_notification(struct ata_port *ap)
873 if (rc == 0) 873 if (rc == 0)
874 sata_scr_write(&ap->link, SCR_NOTIFICATION, sntf); 874 sata_scr_write(&ap->link, SCR_NOTIFICATION, sntf);
875 875
876 if (!ap->nr_pmp_links || rc) { 876 if (!sata_pmp_attached(ap) || rc) {
877 /* PMP is not attached or SNTF is not available */ 877 /* PMP is not attached or SNTF is not available */
878 if (!ap->nr_pmp_links) { 878 if (!sata_pmp_attached(ap)) {
879 /* PMP is not attached. Check whether ATAPI 879 /* PMP is not attached. Check whether ATAPI
880 * AN is configured. If so, notify media 880 * AN is configured. If so, notify media
881 * change. 881 * change.
@@ -1853,7 +1853,7 @@ void ata_eh_autopsy(struct ata_port *ap)
1853 /* Autopsy of fanout ports can affect host link autopsy. 1853 /* Autopsy of fanout ports can affect host link autopsy.
1854 * Perform host link autopsy last. 1854 * Perform host link autopsy last.
1855 */ 1855 */
1856 if (ap->nr_pmp_links) 1856 if (sata_pmp_attached(ap))
1857 ata_eh_link_autopsy(&ap->link); 1857 ata_eh_link_autopsy(&ap->link);
1858} 1858}
1859 1859
@@ -2076,7 +2076,7 @@ static int ata_eh_followup_srst_needed(struct ata_link *link,
2076 } 2076 }
2077 if (rc != 0) 2077 if (rc != 0)
2078 return 0; 2078 return 0;
2079 if ((link->ap->flags & ATA_FLAG_PMP) && ata_is_host_link(link)) 2079 if (sata_pmp_supported(link->ap) && ata_is_host_link(link))
2080 return 1; 2080 return 1;
2081 return 0; 2081 return 0;
2082} 2082}
@@ -2668,7 +2668,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
2668 /* if PMP is attached, this function only deals with 2668 /* if PMP is attached, this function only deals with
2669 * downstream links, port should stay thawed. 2669 * downstream links, port should stay thawed.
2670 */ 2670 */
2671 if (!ap->nr_pmp_links) 2671 if (!sata_pmp_attached(ap))
2672 ata_eh_freeze_port(ap); 2672 ata_eh_freeze_port(ap);
2673 2673
2674 ata_port_for_each_link(link, ap) { 2674 ata_port_for_each_link(link, ap) {
@@ -2687,7 +2687,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
2687 } 2687 }
2688 } 2688 }
2689 2689
2690 if (!ap->nr_pmp_links) 2690 if (!sata_pmp_attached(ap))
2691 ata_eh_thaw_port(ap); 2691 ata_eh_thaw_port(ap);
2692 } 2692 }
2693 2693
@@ -2731,7 +2731,7 @@ dev_fail:
2731 /* PMP reset requires working host port. 2731 /* PMP reset requires working host port.
2732 * Can't retry if it's frozen. 2732 * Can't retry if it's frozen.
2733 */ 2733 */
2734 if (ap->nr_pmp_links) 2734 if (sata_pmp_attached(ap))
2735 goto out; 2735 goto out;
2736 break; 2736 break;
2737 } 2737 }
diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c
index bb10c0630791..ff1822a7da38 100644
--- a/drivers/ata/libata-pmp.c
+++ b/drivers/ata/libata-pmp.c
@@ -411,7 +411,7 @@ int sata_pmp_attach(struct ata_device *dev)
411 int rc; 411 int rc;
412 412
413 /* is it hanging off the right place? */ 413 /* is it hanging off the right place? */
414 if (!(ap->flags & ATA_FLAG_PMP)) { 414 if (!sata_pmp_supported(ap)) {
415 ata_dev_printk(dev, KERN_ERR, 415 ata_dev_printk(dev, KERN_ERR,
416 "host does not support Port Multiplier\n"); 416 "host does not support Port Multiplier\n");
417 return -EINVAL; 417 return -EINVAL;
@@ -876,7 +876,7 @@ static int sata_pmp_eh_recover(struct ata_port *ap)
876 876
877 retry: 877 retry:
878 /* PMP attached? */ 878 /* PMP attached? */
879 if (!ap->nr_pmp_links) { 879 if (!sata_pmp_attached(ap)) {
880 rc = ata_eh_recover(ap, ops->prereset, ops->softreset, 880 rc = ata_eh_recover(ap, ops->prereset, ops->softreset,
881 ops->hardreset, ops->postreset, NULL); 881 ops->hardreset, ops->postreset, NULL);
882 if (rc) { 882 if (rc) {
@@ -983,7 +983,7 @@ static int sata_pmp_eh_recover(struct ata_port *ap)
983 if (ap->pflags & ATA_PFLAG_UNLOADING) 983 if (ap->pflags & ATA_PFLAG_UNLOADING)
984 return rc; 984 return rc;
985 985
986 if (!ap->nr_pmp_links) 986 if (!sata_pmp_attached(ap))
987 goto retry; 987 goto retry;
988 988
989 if (--pmp_tries) { 989 if (--pmp_tries) {
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index a70881c408e5..fedf62de9460 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -2617,7 +2617,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
2617 2617
2618static struct ata_device *ata_find_dev(struct ata_port *ap, int devno) 2618static struct ata_device *ata_find_dev(struct ata_port *ap, int devno)
2619{ 2619{
2620 if (ap->nr_pmp_links == 0) { 2620 if (!sata_pmp_attached(ap)) {
2621 if (likely(devno < ata_link_max_devices(&ap->link))) 2621 if (likely(devno < ata_link_max_devices(&ap->link)))
2622 return &ap->link.device[devno]; 2622 return &ap->link.device[devno];
2623 } else { 2623 } else {
@@ -2634,7 +2634,7 @@ static struct ata_device *__ata_scsi_find_dev(struct ata_port *ap,
2634 int devno; 2634 int devno;
2635 2635
2636 /* skip commands not addressed to targets we simulate */ 2636 /* skip commands not addressed to targets we simulate */
2637 if (ap->nr_pmp_links == 0) { 2637 if (!sata_pmp_attached(ap)) {
2638 if (unlikely(scsidev->channel || scsidev->lun)) 2638 if (unlikely(scsidev->channel || scsidev->lun))
2639 return NULL; 2639 return NULL;
2640 devno = scsidev->id; 2640 devno = scsidev->id;
@@ -3492,7 +3492,7 @@ static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
3492 if (lun != SCAN_WILD_CARD && lun) 3492 if (lun != SCAN_WILD_CARD && lun)
3493 return -EINVAL; 3493 return -EINVAL;
3494 3494
3495 if (ap->nr_pmp_links == 0) { 3495 if (!sata_pmp_attached(ap)) {
3496 if (channel != SCAN_WILD_CARD && channel) 3496 if (channel != SCAN_WILD_CARD && channel)
3497 return -EINVAL; 3497 return -EINVAL;
3498 devno = id; 3498 devno = id;
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index 6039614e956c..068789361895 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -354,8 +354,6 @@ static int sil24_softreset(struct ata_link *link, unsigned int *class,
354 unsigned long deadline); 354 unsigned long deadline);
355static int sil24_hardreset(struct ata_link *link, unsigned int *class, 355static int sil24_hardreset(struct ata_link *link, unsigned int *class,
356 unsigned long deadline); 356 unsigned long deadline);
357static int sil24_pmp_softreset(struct ata_link *link, unsigned int *class,
358 unsigned long deadline);
359static int sil24_pmp_hardreset(struct ata_link *link, unsigned int *class, 357static int sil24_pmp_hardreset(struct ata_link *link, unsigned int *class,
360 unsigned long deadline); 358 unsigned long deadline);
361static void sil24_error_handler(struct ata_port *ap); 359static void sil24_error_handler(struct ata_port *ap);
@@ -408,7 +406,7 @@ static struct ata_port_operations sil24_ops = {
408 .thaw = sil24_thaw, 406 .thaw = sil24_thaw,
409 .softreset = sil24_softreset, 407 .softreset = sil24_softreset,
410 .hardreset = sil24_hardreset, 408 .hardreset = sil24_hardreset,
411 .pmp_softreset = sil24_pmp_softreset, 409 .pmp_softreset = sil24_softreset,
412 .pmp_hardreset = sil24_pmp_hardreset, 410 .pmp_hardreset = sil24_pmp_hardreset,
413 .error_handler = sil24_error_handler, 411 .error_handler = sil24_error_handler,
414 .post_internal_cmd = sil24_post_internal_cmd, 412 .post_internal_cmd = sil24_post_internal_cmd,
@@ -588,7 +586,7 @@ static int sil24_init_port(struct ata_port *ap)
588 u32 tmp; 586 u32 tmp;
589 587
590 /* clear PMP error status */ 588 /* clear PMP error status */
591 if (ap->nr_pmp_links) 589 if (sata_pmp_attached(ap))
592 sil24_clear_pmp(ap); 590 sil24_clear_pmp(ap);
593 591
594 writel(PORT_CS_INIT, port + PORT_CTRL_STAT); 592 writel(PORT_CS_INIT, port + PORT_CTRL_STAT);
@@ -653,10 +651,11 @@ static int sil24_exec_polled_cmd(struct ata_port *ap, int pmp,
653 return rc; 651 return rc;
654} 652}
655 653
656static int sil24_do_softreset(struct ata_link *link, unsigned int *class, 654static int sil24_softreset(struct ata_link *link, unsigned int *class,
657 int pmp, unsigned long deadline) 655 unsigned long deadline)
658{ 656{
659 struct ata_port *ap = link->ap; 657 struct ata_port *ap = link->ap;
658 int pmp = sata_srst_pmp(link);
660 unsigned long timeout_msec = 0; 659 unsigned long timeout_msec = 0;
661 struct ata_taskfile tf; 660 struct ata_taskfile tf;
662 const char *reason; 661 const char *reason;
@@ -706,12 +705,6 @@ static int sil24_do_softreset(struct ata_link *link, unsigned int *class,
706 return -EIO; 705 return -EIO;
707} 706}
708 707
709static int sil24_softreset(struct ata_link *link, unsigned int *class,
710 unsigned long deadline)
711{
712 return sil24_do_softreset(link, class, SATA_PMP_CTRL_PORT, deadline);
713}
714
715static int sil24_hardreset(struct ata_link *link, unsigned int *class, 708static int sil24_hardreset(struct ata_link *link, unsigned int *class,
716 unsigned long deadline) 709 unsigned long deadline)
717{ 710{
@@ -926,12 +919,6 @@ static void sil24_pmp_detach(struct ata_port *ap)
926 sil24_config_pmp(ap, 0); 919 sil24_config_pmp(ap, 0);
927} 920}
928 921
929static int sil24_pmp_softreset(struct ata_link *link, unsigned int *class,
930 unsigned long deadline)
931{
932 return sil24_do_softreset(link, class, link->pmp, deadline);
933}
934
935static int sil24_pmp_hardreset(struct ata_link *link, unsigned int *class, 922static int sil24_pmp_hardreset(struct ata_link *link, unsigned int *class,
936 unsigned long deadline) 923 unsigned long deadline)
937{ 924{
@@ -1034,7 +1021,7 @@ static void sil24_error_intr(struct ata_port *ap)
1034 } 1021 }
1035 1022
1036 /* find out the offending link and qc */ 1023 /* find out the offending link and qc */
1037 if (ap->nr_pmp_links) { 1024 if (sata_pmp_attached(ap)) {
1038 context = readl(port + PORT_CONTEXT); 1025 context = readl(port + PORT_CONTEXT);
1039 pmp = (context >> 5) & 0xf; 1026 pmp = (context >> 5) & 0xf;
1040 1027
@@ -1082,7 +1069,7 @@ static void sil24_error_intr(struct ata_port *ap)
1082 ehi->action |= action; 1069 ehi->action |= action;
1083 1070
1084 /* if PMP, resume */ 1071 /* if PMP, resume */
1085 if (ap->nr_pmp_links) 1072 if (sata_pmp_attached(ap))
1086 writel(PORT_CS_PMP_RESUME, port + PORT_CTRL_STAT); 1073 writel(PORT_CS_PMP_RESUME, port + PORT_CTRL_STAT);
1087 } 1074 }
1088 1075