aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRobert Hancock <hancockrwd@gmail.com>2009-09-20 19:02:31 -0400
committerJeff Garzik <jgarzik@redhat.com>2009-10-06 00:23:03 -0400
commit4c521c8ef0e802f88f1d80352dd1b3d6a6aa1cc8 (patch)
treeb8334dd5aac9cd5739ba270e0c699e14701bd561 /drivers
parentc21c8066be5a2870b3e047616e03e9e56a4701a4 (diff)
ahci: display all AHCI 1.3 HBA capability flags (v2)
Update the AHCI driver to display all of the HBA capabilities defined in the AHCI 1.3 specification. Some of these are in a new CAP2 (HBA Capabilities Extended) register which is only defined on AHCI 1.2 or later. The spec says that undefined registers should always return 0 on read, but to be safe we assume a value of 0 unless the controller reports AHCI version 1.2 or later. The value can also be retrieved through sysfs as with the existing capability field. For example, on an Intel Ibex Peak (PCH) controller: ahci 0000:00:1f.2: flags: 64bit ncq sntf stag pm led clo pmp pio slum part ems sxs apst We don't do anything special with the new flags yet. Also, change the code that displays the flags to use the same bit enumerations that are used to control actual operation. Signed-off-by: Robert Hancock <hancockrwd@gmail.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/ahci.c86
1 files changed, 66 insertions, 20 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index c95015986c94..a47d309df2f2 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -122,6 +122,7 @@ enum {
122 HOST_VERSION = 0x10, /* AHCI spec. version compliancy */ 122 HOST_VERSION = 0x10, /* AHCI spec. version compliancy */
123 HOST_EM_LOC = 0x1c, /* Enclosure Management location */ 123 HOST_EM_LOC = 0x1c, /* Enclosure Management location */
124 HOST_EM_CTL = 0x20, /* Enclosure Management Control */ 124 HOST_EM_CTL = 0x20, /* Enclosure Management Control */
125 HOST_CAP2 = 0x24, /* host capabilities, extended */
125 126
126 /* HOST_CTL bits */ 127 /* HOST_CTL bits */
127 HOST_RESET = (1 << 0), /* reset controller; self-clear */ 128 HOST_RESET = (1 << 0), /* reset controller; self-clear */
@@ -129,16 +130,29 @@ enum {
129 HOST_AHCI_EN = (1 << 31), /* AHCI enabled */ 130 HOST_AHCI_EN = (1 << 31), /* AHCI enabled */
130 131
131 /* HOST_CAP bits */ 132 /* HOST_CAP bits */
133 HOST_CAP_SXS = (1 << 5), /* Supports External SATA */
132 HOST_CAP_EMS = (1 << 6), /* Enclosure Management support */ 134 HOST_CAP_EMS = (1 << 6), /* Enclosure Management support */
133 HOST_CAP_SSC = (1 << 14), /* Slumber capable */ 135 HOST_CAP_CCC = (1 << 7), /* Command Completion Coalescing */
136 HOST_CAP_PART = (1 << 13), /* Partial state capable */
137 HOST_CAP_SSC = (1 << 14), /* Slumber state capable */
138 HOST_CAP_PIO_MULTI = (1 << 15), /* PIO multiple DRQ support */
139 HOST_CAP_FBS = (1 << 16), /* FIS-based switching support */
134 HOST_CAP_PMP = (1 << 17), /* Port Multiplier support */ 140 HOST_CAP_PMP = (1 << 17), /* Port Multiplier support */
141 HOST_CAP_ONLY = (1 << 18), /* Supports AHCI mode only */
135 HOST_CAP_CLO = (1 << 24), /* Command List Override support */ 142 HOST_CAP_CLO = (1 << 24), /* Command List Override support */
143 HOST_CAP_LED = (1 << 25), /* Supports activity LED */
136 HOST_CAP_ALPM = (1 << 26), /* Aggressive Link PM support */ 144 HOST_CAP_ALPM = (1 << 26), /* Aggressive Link PM support */
137 HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */ 145 HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */
146 HOST_CAP_MPS = (1 << 28), /* Mechanical presence switch */
138 HOST_CAP_SNTF = (1 << 29), /* SNotification register */ 147 HOST_CAP_SNTF = (1 << 29), /* SNotification register */
139 HOST_CAP_NCQ = (1 << 30), /* Native Command Queueing */ 148 HOST_CAP_NCQ = (1 << 30), /* Native Command Queueing */
140 HOST_CAP_64 = (1 << 31), /* PCI DAC (64-bit DMA) support */ 149 HOST_CAP_64 = (1 << 31), /* PCI DAC (64-bit DMA) support */
141 150
151 /* HOST_CAP2 bits */
152 HOST_CAP2_BOH = (1 << 0), /* BIOS/OS handoff supported */
153 HOST_CAP2_NVMHCI = (1 << 1), /* NVMHCI supported */
154 HOST_CAP2_APST = (1 << 2), /* Automatic partial to slumber */
155
142 /* registers for each SATA port */ 156 /* registers for each SATA port */
143 PORT_LST_ADDR = 0x00, /* command list DMA addr */ 157 PORT_LST_ADDR = 0x00, /* command list DMA addr */
144 PORT_LST_ADDR_HI = 0x04, /* command list DMA addr hi */ 158 PORT_LST_ADDR_HI = 0x04, /* command list DMA addr hi */
@@ -267,8 +281,10 @@ struct ahci_em_priv {
267struct ahci_host_priv { 281struct ahci_host_priv {
268 unsigned int flags; /* AHCI_HFLAG_* */ 282 unsigned int flags; /* AHCI_HFLAG_* */
269 u32 cap; /* cap to use */ 283 u32 cap; /* cap to use */
284 u32 cap2; /* cap2 to use */
270 u32 port_map; /* port map to use */ 285 u32 port_map; /* port map to use */
271 u32 saved_cap; /* saved initial cap */ 286 u32 saved_cap; /* saved initial cap */
287 u32 saved_cap2; /* saved initial cap2 */
272 u32 saved_port_map; /* saved initial port_map */ 288 u32 saved_port_map; /* saved initial port_map */
273 u32 em_loc; /* enclosure management location */ 289 u32 em_loc; /* enclosure management location */
274}; 290};
@@ -331,12 +347,15 @@ static void ahci_init_sw_activity(struct ata_link *link);
331 347
332static ssize_t ahci_show_host_caps(struct device *dev, 348static ssize_t ahci_show_host_caps(struct device *dev,
333 struct device_attribute *attr, char *buf); 349 struct device_attribute *attr, char *buf);
350static ssize_t ahci_show_host_cap2(struct device *dev,
351 struct device_attribute *attr, char *buf);
334static ssize_t ahci_show_host_version(struct device *dev, 352static ssize_t ahci_show_host_version(struct device *dev,
335 struct device_attribute *attr, char *buf); 353 struct device_attribute *attr, char *buf);
336static ssize_t ahci_show_port_cmd(struct device *dev, 354static ssize_t ahci_show_port_cmd(struct device *dev,
337 struct device_attribute *attr, char *buf); 355 struct device_attribute *attr, char *buf);
338 356
339DEVICE_ATTR(ahci_host_caps, S_IRUGO, ahci_show_host_caps, NULL); 357DEVICE_ATTR(ahci_host_caps, S_IRUGO, ahci_show_host_caps, NULL);
358DEVICE_ATTR(ahci_host_cap2, S_IRUGO, ahci_show_host_cap2, NULL);
340DEVICE_ATTR(ahci_host_version, S_IRUGO, ahci_show_host_version, NULL); 359DEVICE_ATTR(ahci_host_version, S_IRUGO, ahci_show_host_version, NULL);
341DEVICE_ATTR(ahci_port_cmd, S_IRUGO, ahci_show_port_cmd, NULL); 360DEVICE_ATTR(ahci_port_cmd, S_IRUGO, ahci_show_port_cmd, NULL);
342 361
@@ -345,6 +364,7 @@ static struct device_attribute *ahci_shost_attrs[] = {
345 &dev_attr_em_message_type, 364 &dev_attr_em_message_type,
346 &dev_attr_em_message, 365 &dev_attr_em_message,
347 &dev_attr_ahci_host_caps, 366 &dev_attr_ahci_host_caps,
367 &dev_attr_ahci_host_cap2,
348 &dev_attr_ahci_host_version, 368 &dev_attr_ahci_host_version,
349 &dev_attr_ahci_port_cmd, 369 &dev_attr_ahci_port_cmd,
350 NULL 370 NULL
@@ -733,6 +753,16 @@ static ssize_t ahci_show_host_caps(struct device *dev,
733 return sprintf(buf, "%x\n", hpriv->cap); 753 return sprintf(buf, "%x\n", hpriv->cap);
734} 754}
735 755
756static ssize_t ahci_show_host_cap2(struct device *dev,
757 struct device_attribute *attr, char *buf)
758{
759 struct Scsi_Host *shost = class_to_shost(dev);
760 struct ata_port *ap = ata_shost_to_port(shost);
761 struct ahci_host_priv *hpriv = ap->host->private_data;
762
763 return sprintf(buf, "%x\n", hpriv->cap2);
764}
765
736static ssize_t ahci_show_host_version(struct device *dev, 766static ssize_t ahci_show_host_version(struct device *dev,
737 struct device_attribute *attr, char *buf) 767 struct device_attribute *attr, char *buf)
738{ 768{
@@ -772,7 +802,7 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
772 struct ahci_host_priv *hpriv) 802 struct ahci_host_priv *hpriv)
773{ 803{
774 void __iomem *mmio = pcim_iomap_table(pdev)[AHCI_PCI_BAR]; 804 void __iomem *mmio = pcim_iomap_table(pdev)[AHCI_PCI_BAR];
775 u32 cap, port_map; 805 u32 cap, cap2, vers, port_map;
776 int i; 806 int i;
777 int mv; 807 int mv;
778 808
@@ -785,6 +815,14 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
785 hpriv->saved_cap = cap = readl(mmio + HOST_CAP); 815 hpriv->saved_cap = cap = readl(mmio + HOST_CAP);
786 hpriv->saved_port_map = port_map = readl(mmio + HOST_PORTS_IMPL); 816 hpriv->saved_port_map = port_map = readl(mmio + HOST_PORTS_IMPL);
787 817
818 /* CAP2 register is only defined for AHCI 1.2 and later */
819 vers = readl(mmio + HOST_VERSION);
820 if ((vers >> 16) > 1 ||
821 ((vers >> 16) == 1 && (vers & 0xFFFF) >= 0x200))
822 hpriv->saved_cap2 = cap2 = readl(mmio + HOST_CAP2);
823 else
824 hpriv->saved_cap2 = cap2 = 0;
825
788 /* some chips have errata preventing 64bit use */ 826 /* some chips have errata preventing 64bit use */
789 if ((cap & HOST_CAP_64) && (hpriv->flags & AHCI_HFLAG_32BIT_ONLY)) { 827 if ((cap & HOST_CAP_64) && (hpriv->flags & AHCI_HFLAG_32BIT_ONLY)) {
790 dev_printk(KERN_INFO, &pdev->dev, 828 dev_printk(KERN_INFO, &pdev->dev,
@@ -870,6 +908,7 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
870 908
871 /* record values to use during operation */ 909 /* record values to use during operation */
872 hpriv->cap = cap; 910 hpriv->cap = cap;
911 hpriv->cap2 = cap2;
873 hpriv->port_map = port_map; 912 hpriv->port_map = port_map;
874} 913}
875 914
@@ -888,6 +927,8 @@ static void ahci_restore_initial_config(struct ata_host *host)
888 void __iomem *mmio = host->iomap[AHCI_PCI_BAR]; 927 void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
889 928
890 writel(hpriv->saved_cap, mmio + HOST_CAP); 929 writel(hpriv->saved_cap, mmio + HOST_CAP);
930 if (hpriv->saved_cap2)
931 writel(hpriv->saved_cap2, mmio + HOST_CAP2);
891 writel(hpriv->saved_port_map, mmio + HOST_PORTS_IMPL); 932 writel(hpriv->saved_port_map, mmio + HOST_PORTS_IMPL);
892 (void) readl(mmio + HOST_PORTS_IMPL); /* flush */ 933 (void) readl(mmio + HOST_PORTS_IMPL); /* flush */
893} 934}
@@ -2535,13 +2576,14 @@ static void ahci_print_info(struct ata_host *host)
2535 struct ahci_host_priv *hpriv = host->private_data; 2576 struct ahci_host_priv *hpriv = host->private_data;
2536 struct pci_dev *pdev = to_pci_dev(host->dev); 2577 struct pci_dev *pdev = to_pci_dev(host->dev);
2537 void __iomem *mmio = host->iomap[AHCI_PCI_BAR]; 2578 void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
2538 u32 vers, cap, impl, speed; 2579 u32 vers, cap, cap2, impl, speed;
2539 const char *speed_s; 2580 const char *speed_s;
2540 u16 cc; 2581 u16 cc;
2541 const char *scc_s; 2582 const char *scc_s;
2542 2583
2543 vers = readl(mmio + HOST_VERSION); 2584 vers = readl(mmio + HOST_VERSION);
2544 cap = hpriv->cap; 2585 cap = hpriv->cap;
2586 cap2 = hpriv->cap2;
2545 impl = hpriv->port_map; 2587 impl = hpriv->port_map;
2546 2588
2547 speed = (cap >> 20) & 0xf; 2589 speed = (cap >> 20) & 0xf;
@@ -2584,25 +2626,29 @@ static void ahci_print_info(struct ata_host *host)
2584 "flags: " 2626 "flags: "
2585 "%s%s%s%s%s%s%s" 2627 "%s%s%s%s%s%s%s"
2586 "%s%s%s%s%s%s%s" 2628 "%s%s%s%s%s%s%s"
2587 "%s\n" 2629 "%s%s%s%s%s%s\n"
2588 , 2630 ,
2589 2631
2590 cap & (1 << 31) ? "64bit " : "", 2632 cap & HOST_CAP_64 ? "64bit " : "",
2591 cap & (1 << 30) ? "ncq " : "", 2633 cap & HOST_CAP_NCQ ? "ncq " : "",
2592 cap & (1 << 29) ? "sntf " : "", 2634 cap & HOST_CAP_SNTF ? "sntf " : "",
2593 cap & (1 << 28) ? "ilck " : "", 2635 cap & HOST_CAP_MPS ? "ilck " : "",
2594 cap & (1 << 27) ? "stag " : "", 2636 cap & HOST_CAP_SSS ? "stag " : "",
2595 cap & (1 << 26) ? "pm " : "", 2637 cap & HOST_CAP_ALPM ? "pm " : "",
2596 cap & (1 << 25) ? "led " : "", 2638 cap & HOST_CAP_LED ? "led " : "",
2597 2639 cap & HOST_CAP_CLO ? "clo " : "",
2598 cap & (1 << 24) ? "clo " : "", 2640 cap & HOST_CAP_ONLY ? "only " : "",
2599 cap & (1 << 19) ? "nz " : "", 2641 cap & HOST_CAP_PMP ? "pmp " : "",
2600 cap & (1 << 18) ? "only " : "", 2642 cap & HOST_CAP_FBS ? "fbs " : "",
2601 cap & (1 << 17) ? "pmp " : "", 2643 cap & HOST_CAP_PIO_MULTI ? "pio " : "",
2602 cap & (1 << 15) ? "pio " : "", 2644 cap & HOST_CAP_SSC ? "slum " : "",
2603 cap & (1 << 14) ? "slum " : "", 2645 cap & HOST_CAP_PART ? "part " : "",
2604 cap & (1 << 13) ? "part " : "", 2646 cap & HOST_CAP_CCC ? "ccc " : "",
2605 cap & (1 << 6) ? "ems ": "" 2647 cap & HOST_CAP_EMS ? "ems " : "",
2648 cap & HOST_CAP_SXS ? "sxs " : "",
2649 cap2 & HOST_CAP2_APST ? "apst " : "",
2650 cap2 & HOST_CAP2_NVMHCI ? "nvmp " : "",
2651 cap2 & HOST_CAP2_BOH ? "boh " : ""
2606 ); 2652 );
2607} 2653}
2608 2654