aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-03-17 12:52:24 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-03-17 12:52:24 -0400
commitbde4f8fa8db2abd5ac9c542d76012d0fedab050f (patch)
tree1be905db5b97da31358851aee538fa19ea6381c4
parent84841384ec6ec57544b76e564514d3f9eb6c1901 (diff)
parentc40e7cb89f9d36924131ef708ff1f16a76611add (diff)
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev: ahci: Add Marvell 6121 SATA support pata_ali: use atapi_cmd_type() to determine cmd type instead of transfer size ahci: implement skip_host_reset parameter ahci: request all PCI BARs devres: implement pcim_iomap_regions_request_all() libata-acpi: improve dock event handling
-rw-r--r--drivers/ata/ahci.c72
-rw-r--r--drivers/ata/libata-acpi.c96
-rw-r--r--drivers/ata/pata_ali.c2
-rw-r--r--include/linux/pci.h2
-rw-r--r--lib/devres.c25
5 files changed, 145 insertions, 52 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 6978469eb16d..17ee6ed985d9 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -49,6 +49,10 @@
49#define DRV_NAME "ahci" 49#define DRV_NAME "ahci"
50#define DRV_VERSION "3.0" 50#define DRV_VERSION "3.0"
51 51
52static int ahci_skip_host_reset;
53module_param_named(skip_host_reset, ahci_skip_host_reset, int, 0444);
54MODULE_PARM_DESC(skip_host_reset, "skip global host reset (0=don't skip, 1=skip)");
55
52static int ahci_enable_alpm(struct ata_port *ap, 56static int ahci_enable_alpm(struct ata_port *ap,
53 enum link_pm policy); 57 enum link_pm policy);
54static void ahci_disable_alpm(struct ata_port *ap); 58static void ahci_disable_alpm(struct ata_port *ap);
@@ -587,6 +591,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
587 591
588 /* Marvell */ 592 /* Marvell */
589 { PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv }, /* 6145 */ 593 { PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv }, /* 6145 */
594 { PCI_VDEVICE(MARVELL, 0x6121), board_ahci_mv }, /* 6121 */
590 595
591 /* Generic, PCI class code for AHCI */ 596 /* Generic, PCI class code for AHCI */
592 { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 597 { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
@@ -661,6 +666,7 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
661 void __iomem *mmio = pcim_iomap_table(pdev)[AHCI_PCI_BAR]; 666 void __iomem *mmio = pcim_iomap_table(pdev)[AHCI_PCI_BAR];
662 u32 cap, port_map; 667 u32 cap, port_map;
663 int i; 668 int i;
669 int mv;
664 670
665 /* make sure AHCI mode is enabled before accessing CAP */ 671 /* make sure AHCI mode is enabled before accessing CAP */
666 ahci_enable_ahci(mmio); 672 ahci_enable_ahci(mmio);
@@ -696,12 +702,16 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
696 * presence register, as bit 4 (counting from 0) 702 * presence register, as bit 4 (counting from 0)
697 */ 703 */
698 if (hpriv->flags & AHCI_HFLAG_MV_PATA) { 704 if (hpriv->flags & AHCI_HFLAG_MV_PATA) {
705 if (pdev->device == 0x6121)
706 mv = 0x3;
707 else
708 mv = 0xf;
699 dev_printk(KERN_ERR, &pdev->dev, 709 dev_printk(KERN_ERR, &pdev->dev,
700 "MV_AHCI HACK: port_map %x -> %x\n", 710 "MV_AHCI HACK: port_map %x -> %x\n",
701 hpriv->port_map, 711 port_map,
702 hpriv->port_map & 0xf); 712 port_map & mv);
703 713
704 port_map &= 0xf; 714 port_map &= mv;
705 } 715 }
706 716
707 /* cross check port_map and cap.n_ports */ 717 /* cross check port_map and cap.n_ports */
@@ -1088,29 +1098,35 @@ static int ahci_reset_controller(struct ata_host *host)
1088 ahci_enable_ahci(mmio); 1098 ahci_enable_ahci(mmio);
1089 1099
1090 /* global controller reset */ 1100 /* global controller reset */
1091 tmp = readl(mmio + HOST_CTL); 1101 if (!ahci_skip_host_reset) {
1092 if ((tmp & HOST_RESET) == 0) { 1102 tmp = readl(mmio + HOST_CTL);
1093 writel(tmp | HOST_RESET, mmio + HOST_CTL); 1103 if ((tmp & HOST_RESET) == 0) {
1094 readl(mmio + HOST_CTL); /* flush */ 1104 writel(tmp | HOST_RESET, mmio + HOST_CTL);
1095 } 1105 readl(mmio + HOST_CTL); /* flush */
1106 }
1096 1107
1097 /* reset must complete within 1 second, or 1108 /* reset must complete within 1 second, or
1098 * the hardware should be considered fried. 1109 * the hardware should be considered fried.
1099 */ 1110 */
1100 ssleep(1); 1111 ssleep(1);
1101 1112
1102 tmp = readl(mmio + HOST_CTL); 1113 tmp = readl(mmio + HOST_CTL);
1103 if (tmp & HOST_RESET) { 1114 if (tmp & HOST_RESET) {
1104 dev_printk(KERN_ERR, host->dev, 1115 dev_printk(KERN_ERR, host->dev,
1105 "controller reset failed (0x%x)\n", tmp); 1116 "controller reset failed (0x%x)\n", tmp);
1106 return -EIO; 1117 return -EIO;
1107 } 1118 }
1108 1119
1109 /* turn on AHCI mode */ 1120 /* turn on AHCI mode */
1110 ahci_enable_ahci(mmio); 1121 ahci_enable_ahci(mmio);
1111 1122
1112 /* some registers might be cleared on reset. restore initial values */ 1123 /* Some registers might be cleared on reset. Restore
1113 ahci_restore_initial_config(host); 1124 * initial values.
1125 */
1126 ahci_restore_initial_config(host);
1127 } else
1128 dev_printk(KERN_INFO, host->dev,
1129 "skipping global host reset\n");
1114 1130
1115 if (pdev->vendor == PCI_VENDOR_ID_INTEL) { 1131 if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
1116 u16 tmp16; 1132 u16 tmp16;
@@ -1162,9 +1178,14 @@ static void ahci_init_controller(struct ata_host *host)
1162 int i; 1178 int i;
1163 void __iomem *port_mmio; 1179 void __iomem *port_mmio;
1164 u32 tmp; 1180 u32 tmp;
1181 int mv;
1165 1182
1166 if (hpriv->flags & AHCI_HFLAG_MV_PATA) { 1183 if (hpriv->flags & AHCI_HFLAG_MV_PATA) {
1167 port_mmio = __ahci_port_base(host, 4); 1184 if (pdev->device == 0x6121)
1185 mv = 2;
1186 else
1187 mv = 4;
1188 port_mmio = __ahci_port_base(host, mv);
1168 1189
1169 writel(0, port_mmio + PORT_IRQ_MASK); 1190 writel(0, port_mmio + PORT_IRQ_MASK);
1170 1191
@@ -2241,7 +2262,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
2241 if (rc) 2262 if (rc)
2242 return rc; 2263 return rc;
2243 2264
2244 rc = pcim_iomap_regions(pdev, 1 << AHCI_PCI_BAR, DRV_NAME); 2265 /* AHCI controllers often implement SFF compatible interface.
2266 * Grab all PCI BARs just in case.
2267 */
2268 rc = pcim_iomap_regions_request_all(pdev, 1 << AHCI_PCI_BAR, DRV_NAME);
2245 if (rc == -EBUSY) 2269 if (rc == -EBUSY)
2246 pcim_pin_device(pdev); 2270 pcim_pin_device(pdev);
2247 if (rc) 2271 if (rc)
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index 0770cb7391a4..bf98a566adac 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -118,45 +118,77 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap)
118 ap->pflags |= ATA_PFLAG_INIT_GTM_VALID; 118 ap->pflags |= ATA_PFLAG_INIT_GTM_VALID;
119} 119}
120 120
121static void ata_acpi_handle_hotplug(struct ata_port *ap, struct kobject *kobj, 121static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev,
122 u32 event) 122 u32 event)
123{ 123{
124 char event_string[12]; 124 char event_string[12];
125 char *envp[] = { event_string, NULL }; 125 char *envp[] = { event_string, NULL };
126 struct ata_eh_info *ehi = &ap->link.eh_info; 126 struct ata_eh_info *ehi;
127 127 struct kobject *kobj = NULL;
128 if (event == 0 || event == 1) { 128 int wait = 0;
129 unsigned long flags; 129 unsigned long flags;
130 spin_lock_irqsave(ap->lock, flags); 130
131 ata_ehi_clear_desc(ehi); 131 if (!ap)
132 ata_ehi_push_desc(ehi, "ACPI event"); 132 ap = dev->link->ap;
133 ata_ehi_hotplugged(ehi); 133 ehi = &ap->link.eh_info;
134 ata_port_freeze(ap); 134
135 spin_unlock_irqrestore(ap->lock, flags); 135 spin_lock_irqsave(ap->lock, flags);
136
137 switch (event) {
138 case ACPI_NOTIFY_BUS_CHECK:
139 case ACPI_NOTIFY_DEVICE_CHECK:
140 ata_ehi_push_desc(ehi, "ACPI event");
141 ata_ehi_hotplugged(ehi);
142 ata_port_freeze(ap);
143 break;
144
145 case ACPI_NOTIFY_EJECT_REQUEST:
146 ata_ehi_push_desc(ehi, "ACPI event");
147 if (dev)
148 dev->flags |= ATA_DFLAG_DETACH;
149 else {
150 struct ata_link *tlink;
151 struct ata_device *tdev;
152
153 ata_port_for_each_link(tlink, ap)
154 ata_link_for_each_dev(tdev, tlink)
155 tdev->flags |= ATA_DFLAG_DETACH;
156 }
157
158 ata_port_schedule_eh(ap);
159 wait = 1;
160 break;
136 } 161 }
137 162
163 if (dev) {
164 if (dev->sdev)
165 kobj = &dev->sdev->sdev_gendev.kobj;
166 } else
167 kobj = &ap->dev->kobj;
168
138 if (kobj) { 169 if (kobj) {
139 sprintf(event_string, "BAY_EVENT=%d", event); 170 sprintf(event_string, "BAY_EVENT=%d", event);
140 kobject_uevent_env(kobj, KOBJ_CHANGE, envp); 171 kobject_uevent_env(kobj, KOBJ_CHANGE, envp);
141 } 172 }
173
174 spin_unlock_irqrestore(ap->lock, flags);
175
176 if (wait)
177 ata_port_wait_eh(ap);
142} 178}
143 179
144static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data) 180static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data)
145{ 181{
146 struct ata_device *dev = data; 182 struct ata_device *dev = data;
147 struct kobject *kobj = NULL;
148 183
149 if (dev->sdev) 184 ata_acpi_handle_hotplug(NULL, dev, event);
150 kobj = &dev->sdev->sdev_gendev.kobj;
151
152 ata_acpi_handle_hotplug(dev->link->ap, kobj, event);
153} 185}
154 186
155static void ata_acpi_ap_notify(acpi_handle handle, u32 event, void *data) 187static void ata_acpi_ap_notify(acpi_handle handle, u32 event, void *data)
156{ 188{
157 struct ata_port *ap = data; 189 struct ata_port *ap = data;
158 190
159 ata_acpi_handle_hotplug(ap, &ap->dev->kobj, event); 191 ata_acpi_handle_hotplug(ap, NULL, event);
160} 192}
161 193
162/** 194/**
@@ -191,20 +223,30 @@ void ata_acpi_associate(struct ata_host *host)
191 else 223 else
192 ata_acpi_associate_ide_port(ap); 224 ata_acpi_associate_ide_port(ap);
193 225
194 if (ap->acpi_handle) 226 if (ap->acpi_handle) {
195 acpi_install_notify_handler (ap->acpi_handle, 227 acpi_install_notify_handler(ap->acpi_handle,
196 ACPI_SYSTEM_NOTIFY, 228 ACPI_SYSTEM_NOTIFY,
197 ata_acpi_ap_notify, 229 ata_acpi_ap_notify, ap);
198 ap); 230#if defined(CONFIG_ACPI_DOCK) || defined(CONFIG_ACPI_DOCK_MODULE)
231 /* we might be on a docking station */
232 register_hotplug_dock_device(ap->acpi_handle,
233 ata_acpi_ap_notify, ap);
234#endif
235 }
199 236
200 for (j = 0; j < ata_link_max_devices(&ap->link); j++) { 237 for (j = 0; j < ata_link_max_devices(&ap->link); j++) {
201 struct ata_device *dev = &ap->link.device[j]; 238 struct ata_device *dev = &ap->link.device[j];
202 239
203 if (dev->acpi_handle) 240 if (dev->acpi_handle) {
204 acpi_install_notify_handler (dev->acpi_handle, 241 acpi_install_notify_handler(dev->acpi_handle,
205 ACPI_SYSTEM_NOTIFY, 242 ACPI_SYSTEM_NOTIFY,
206 ata_acpi_dev_notify, 243 ata_acpi_dev_notify, dev);
207 dev); 244#if defined(CONFIG_ACPI_DOCK) || defined(CONFIG_ACPI_DOCK_MODULE)
245 /* we might be on a docking station */
246 register_hotplug_dock_device(dev->acpi_handle,
247 ata_acpi_dev_notify, dev);
248#endif
249 }
208 } 250 }
209 } 251 }
210} 252}
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c
index 7e68edf3c0f3..8786455c901d 100644
--- a/drivers/ata/pata_ali.c
+++ b/drivers/ata/pata_ali.c
@@ -295,7 +295,7 @@ static void ali_lock_sectors(struct ata_device *adev)
295static int ali_check_atapi_dma(struct ata_queued_cmd *qc) 295static int ali_check_atapi_dma(struct ata_queued_cmd *qc)
296{ 296{
297 /* If its not a media command, its not worth it */ 297 /* If its not a media command, its not worth it */
298 if (qc->nbytes < 2048) 298 if (atapi_cmd_type(qc->cdb[0]) == ATAPI_MISC)
299 return -EOPNOTSUPP; 299 return -EOPNOTSUPP;
300 return 0; 300 return 0;
301} 301}
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 9010f5458767..b7e4b633c69b 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1045,6 +1045,8 @@ void __iomem *pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen);
1045void pcim_iounmap(struct pci_dev *pdev, void __iomem *addr); 1045void pcim_iounmap(struct pci_dev *pdev, void __iomem *addr);
1046void __iomem * const *pcim_iomap_table(struct pci_dev *pdev); 1046void __iomem * const *pcim_iomap_table(struct pci_dev *pdev);
1047int pcim_iomap_regions(struct pci_dev *pdev, u16 mask, const char *name); 1047int pcim_iomap_regions(struct pci_dev *pdev, u16 mask, const char *name);
1048int pcim_iomap_regions_request_all(struct pci_dev *pdev, u16 mask,
1049 const char *name);
1048void pcim_iounmap_regions(struct pci_dev *pdev, u16 mask); 1050void pcim_iounmap_regions(struct pci_dev *pdev, u16 mask);
1049 1051
1050extern int pci_pci_problems; 1052extern int pci_pci_problems;
diff --git a/lib/devres.c b/lib/devres.c
index b1d336ce7f3d..edc27a5d1b73 100644
--- a/lib/devres.c
+++ b/lib/devres.c
@@ -298,6 +298,31 @@ int pcim_iomap_regions(struct pci_dev *pdev, u16 mask, const char *name)
298EXPORT_SYMBOL(pcim_iomap_regions); 298EXPORT_SYMBOL(pcim_iomap_regions);
299 299
300/** 300/**
301 * pcim_iomap_regions_request_all - Request all BARs and iomap specified ones
302 * @pdev: PCI device to map IO resources for
303 * @mask: Mask of BARs to iomap
304 * @name: Name used when requesting regions
305 *
306 * Request all PCI BARs and iomap regions specified by @mask.
307 */
308int pcim_iomap_regions_request_all(struct pci_dev *pdev, u16 mask,
309 const char *name)
310{
311 int request_mask = ((1 << 6) - 1) & ~mask;
312 int rc;
313
314 rc = pci_request_selected_regions(pdev, request_mask, name);
315 if (rc)
316 return rc;
317
318 rc = pcim_iomap_regions(pdev, mask, name);
319 if (rc)
320 pci_release_selected_regions(pdev, request_mask);
321 return rc;
322}
323EXPORT_SYMBOL(pcim_iomap_regions_request_all);
324
325/**
301 * pcim_iounmap_regions - Unmap and release PCI BARs 326 * pcim_iounmap_regions - Unmap and release PCI BARs
302 * @pdev: PCI device to map IO resources for 327 * @pdev: PCI device to map IO resources for
303 * @mask: Mask of BARs to unmap and release 328 * @mask: Mask of BARs to unmap and release