diff options
author | Alessandro Rubini <rubini@gnudd.com> | 2012-01-06 07:33:39 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2012-01-08 19:24:06 -0500 |
commit | 318893e1429a9d50569a0379d1e20b0ecc45c555 (patch) | |
tree | 78ae2f04ce3706867cf6f957271ff467b3416cf3 /drivers/ata | |
parent | 909fefc2511120ec71178f752c195c7b0b30269e (diff) |
ahci: support the STA2X11 I/O Hub
The AHCI controller found in the STA2X11 chip uses BAR number 0
instead of 5. Also, the chip's fixup code sets a special DMA mask
for all of its PCI functions, and the mask must be preserved here.
Signed-off-by: Alessandro Rubini <rubini@gnudd.com>
Acked-by: Giancarlo Asnaghi <giancarlo.asnaghi@st.com>
Cc: Alan Cox <alan@linux.intel.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/ahci.c | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index cf26222a93c5..d07bf0366d99 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -52,7 +52,8 @@ | |||
52 | #define DRV_VERSION "3.0" | 52 | #define DRV_VERSION "3.0" |
53 | 53 | ||
54 | enum { | 54 | enum { |
55 | AHCI_PCI_BAR = 5, | 55 | AHCI_PCI_BAR_STA2X11 = 0, |
56 | AHCI_PCI_BAR_STANDARD = 5, | ||
56 | }; | 57 | }; |
57 | 58 | ||
58 | enum board_ids { | 59 | enum board_ids { |
@@ -375,6 +376,9 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
375 | { PCI_VDEVICE(SI, 0x1185), board_ahci }, /* SiS 968 */ | 376 | { PCI_VDEVICE(SI, 0x1185), board_ahci }, /* SiS 968 */ |
376 | { PCI_VDEVICE(SI, 0x0186), board_ahci }, /* SiS 968 */ | 377 | { PCI_VDEVICE(SI, 0x0186), board_ahci }, /* SiS 968 */ |
377 | 378 | ||
379 | /* ST Microelectronics */ | ||
380 | { PCI_VDEVICE(STMICRO, 0xCC06), board_ahci }, /* ST ConneXt */ | ||
381 | |||
378 | /* Marvell */ | 382 | /* Marvell */ |
379 | { PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv }, /* 6145 */ | 383 | { PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv }, /* 6145 */ |
380 | { PCI_VDEVICE(MARVELL, 0x6121), board_ahci_mv }, /* 6121 */ | 384 | { PCI_VDEVICE(MARVELL, 0x6121), board_ahci_mv }, /* 6121 */ |
@@ -622,6 +626,13 @@ static int ahci_configure_dma_masks(struct pci_dev *pdev, int using_dac) | |||
622 | { | 626 | { |
623 | int rc; | 627 | int rc; |
624 | 628 | ||
629 | /* | ||
630 | * If the device fixup already set the dma_mask to some non-standard | ||
631 | * value, don't extend it here. This happens on STA2X11, for example. | ||
632 | */ | ||
633 | if (pdev->dma_mask && pdev->dma_mask < DMA_BIT_MASK(32)) | ||
634 | return 0; | ||
635 | |||
625 | if (using_dac && | 636 | if (using_dac && |
626 | !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { | 637 | !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { |
627 | rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); | 638 | rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); |
@@ -1026,6 +1037,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1026 | struct ahci_host_priv *hpriv; | 1037 | struct ahci_host_priv *hpriv; |
1027 | struct ata_host *host; | 1038 | struct ata_host *host; |
1028 | int n_ports, i, rc; | 1039 | int n_ports, i, rc; |
1040 | int ahci_pci_bar = AHCI_PCI_BAR_STANDARD; | ||
1029 | 1041 | ||
1030 | VPRINTK("ENTER\n"); | 1042 | VPRINTK("ENTER\n"); |
1031 | 1043 | ||
@@ -1057,6 +1069,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1057 | dev_info(&pdev->dev, | 1069 | dev_info(&pdev->dev, |
1058 | "PDC42819 can only drive SATA devices with this driver\n"); | 1070 | "PDC42819 can only drive SATA devices with this driver\n"); |
1059 | 1071 | ||
1072 | /* The Connext uses non-standard BAR */ | ||
1073 | if (pdev->vendor == PCI_VENDOR_ID_STMICRO && pdev->device == 0xCC06) | ||
1074 | ahci_pci_bar = AHCI_PCI_BAR_STA2X11; | ||
1075 | |||
1060 | /* acquire resources */ | 1076 | /* acquire resources */ |
1061 | rc = pcim_enable_device(pdev); | 1077 | rc = pcim_enable_device(pdev); |
1062 | if (rc) | 1078 | if (rc) |
@@ -1065,7 +1081,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1065 | /* AHCI controllers often implement SFF compatible interface. | 1081 | /* AHCI controllers often implement SFF compatible interface. |
1066 | * Grab all PCI BARs just in case. | 1082 | * Grab all PCI BARs just in case. |
1067 | */ | 1083 | */ |
1068 | rc = pcim_iomap_regions_request_all(pdev, 1 << AHCI_PCI_BAR, DRV_NAME); | 1084 | rc = pcim_iomap_regions_request_all(pdev, 1 << ahci_pci_bar, DRV_NAME); |
1069 | if (rc == -EBUSY) | 1085 | if (rc == -EBUSY) |
1070 | pcim_pin_device(pdev); | 1086 | pcim_pin_device(pdev); |
1071 | if (rc) | 1087 | if (rc) |
@@ -1108,7 +1124,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1108 | if ((hpriv->flags & AHCI_HFLAG_NO_MSI) || pci_enable_msi(pdev)) | 1124 | if ((hpriv->flags & AHCI_HFLAG_NO_MSI) || pci_enable_msi(pdev)) |
1109 | pci_intx(pdev, 1); | 1125 | pci_intx(pdev, 1); |
1110 | 1126 | ||
1111 | hpriv->mmio = pcim_iomap_table(pdev)[AHCI_PCI_BAR]; | 1127 | hpriv->mmio = pcim_iomap_table(pdev)[ahci_pci_bar]; |
1112 | 1128 | ||
1113 | /* save initial config */ | 1129 | /* save initial config */ |
1114 | ahci_pci_save_initial_config(pdev, hpriv); | 1130 | ahci_pci_save_initial_config(pdev, hpriv); |
@@ -1172,8 +1188,8 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1172 | for (i = 0; i < host->n_ports; i++) { | 1188 | for (i = 0; i < host->n_ports; i++) { |
1173 | struct ata_port *ap = host->ports[i]; | 1189 | struct ata_port *ap = host->ports[i]; |
1174 | 1190 | ||
1175 | ata_port_pbar_desc(ap, AHCI_PCI_BAR, -1, "abar"); | 1191 | ata_port_pbar_desc(ap, ahci_pci_bar, -1, "abar"); |
1176 | ata_port_pbar_desc(ap, AHCI_PCI_BAR, | 1192 | ata_port_pbar_desc(ap, ahci_pci_bar, |
1177 | 0x100 + ap->port_no * 0x80, "port"); | 1193 | 0x100 + ap->port_no * 0x80, "port"); |
1178 | 1194 | ||
1179 | /* set enclosure management message type */ | 1195 | /* set enclosure management message type */ |