diff options
Diffstat (limited to 'drivers/ata/pata_cs5520.c')
-rw-r--r-- | drivers/ata/pata_cs5520.c | 130 |
1 files changed, 71 insertions, 59 deletions
diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c index b5b27baa0be1..79bef0d1fad3 100644 --- a/drivers/ata/pata_cs5520.c +++ b/drivers/ata/pata_cs5520.c | |||
@@ -186,7 +186,6 @@ static struct ata_port_operations cs5520_port_ops = { | |||
186 | .qc_issue = ata_qc_issue_prot, | 186 | .qc_issue = ata_qc_issue_prot, |
187 | .data_xfer = ata_data_xfer, | 187 | .data_xfer = ata_data_xfer, |
188 | 188 | ||
189 | .irq_handler = ata_interrupt, | ||
190 | .irq_clear = ata_bmdma_irq_clear, | 189 | .irq_clear = ata_bmdma_irq_clear, |
191 | .irq_on = ata_irq_on, | 190 | .irq_on = ata_irq_on, |
192 | .irq_ack = ata_irq_ack, | 191 | .irq_ack = ata_irq_ack, |
@@ -194,91 +193,104 @@ static struct ata_port_operations cs5520_port_ops = { | |||
194 | .port_start = ata_port_start, | 193 | .port_start = ata_port_start, |
195 | }; | 194 | }; |
196 | 195 | ||
197 | static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_device_id *id) | 196 | static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_device_id *id) |
198 | { | 197 | { |
198 | struct ata_port_info pi = { | ||
199 | .flags = ATA_FLAG_SLAVE_POSS, | ||
200 | .pio_mask = 0x1f, | ||
201 | .port_ops = &cs5520_port_ops, | ||
202 | }; | ||
203 | const struct ata_port_info *ppi[2]; | ||
199 | u8 pcicfg; | 204 | u8 pcicfg; |
200 | void __iomem *iomap[5]; | 205 | void *iomap[5]; |
201 | static struct ata_probe_ent probe[2]; | 206 | struct ata_host *host; |
202 | int ports = 0; | 207 | struct ata_ioports *ioaddr; |
208 | int i, rc; | ||
203 | 209 | ||
204 | /* IDE port enable bits */ | 210 | /* IDE port enable bits */ |
205 | pci_read_config_byte(dev, 0x60, &pcicfg); | 211 | pci_read_config_byte(pdev, 0x60, &pcicfg); |
206 | 212 | ||
207 | /* Check if the ATA ports are enabled */ | 213 | /* Check if the ATA ports are enabled */ |
208 | if ((pcicfg & 3) == 0) | 214 | if ((pcicfg & 3) == 0) |
209 | return -ENODEV; | 215 | return -ENODEV; |
210 | 216 | ||
217 | ppi[0] = ppi[1] = &ata_dummy_port_info; | ||
218 | if (pcicfg & 1) | ||
219 | ppi[0] = π | ||
220 | if (pcicfg & 2) | ||
221 | ppi[1] = π | ||
222 | |||
211 | if ((pcicfg & 0x40) == 0) { | 223 | if ((pcicfg & 0x40) == 0) { |
212 | printk(KERN_WARNING DRV_NAME ": DMA mode disabled. Enabling.\n"); | 224 | dev_printk(KERN_WARNING, &pdev->dev, |
213 | pci_write_config_byte(dev, 0x60, pcicfg | 0x40); | 225 | "DMA mode disabled. Enabling.\n"); |
226 | pci_write_config_byte(pdev, 0x60, pcicfg | 0x40); | ||
214 | } | 227 | } |
215 | 228 | ||
229 | pi.mwdma_mask = id->driver_data; | ||
230 | |||
231 | host = ata_host_alloc_pinfo(&pdev->dev, ppi, 2); | ||
232 | if (!host) | ||
233 | return -ENOMEM; | ||
234 | |||
216 | /* Perform set up for DMA */ | 235 | /* Perform set up for DMA */ |
217 | if (pci_enable_device_bars(dev, 1<<2)) { | 236 | if (pci_enable_device_bars(pdev, 1<<2)) { |
218 | printk(KERN_ERR DRV_NAME ": unable to configure BAR2.\n"); | 237 | printk(KERN_ERR DRV_NAME ": unable to configure BAR2.\n"); |
219 | return -ENODEV; | 238 | return -ENODEV; |
220 | } | 239 | } |
221 | pci_set_master(dev); | 240 | |
222 | if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) { | 241 | if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { |
223 | printk(KERN_ERR DRV_NAME ": unable to configure DMA mask.\n"); | 242 | printk(KERN_ERR DRV_NAME ": unable to configure DMA mask.\n"); |
224 | return -ENODEV; | 243 | return -ENODEV; |
225 | } | 244 | } |
226 | if (pci_set_consistent_dma_mask(dev, DMA_32BIT_MASK)) { | 245 | if (pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) { |
227 | printk(KERN_ERR DRV_NAME ": unable to configure consistent DMA mask.\n"); | 246 | printk(KERN_ERR DRV_NAME ": unable to configure consistent DMA mask.\n"); |
228 | return -ENODEV; | 247 | return -ENODEV; |
229 | } | 248 | } |
230 | 249 | ||
231 | /* Map IO ports */ | 250 | /* Map IO ports and initialize host accordingly */ |
232 | iomap[0] = devm_ioport_map(&dev->dev, 0x1F0, 8); | 251 | iomap[0] = devm_ioport_map(&pdev->dev, 0x1F0, 8); |
233 | iomap[1] = devm_ioport_map(&dev->dev, 0x3F6, 1); | 252 | iomap[1] = devm_ioport_map(&pdev->dev, 0x3F6, 1); |
234 | iomap[2] = devm_ioport_map(&dev->dev, 0x170, 8); | 253 | iomap[2] = devm_ioport_map(&pdev->dev, 0x170, 8); |
235 | iomap[3] = devm_ioport_map(&dev->dev, 0x376, 1); | 254 | iomap[3] = devm_ioport_map(&pdev->dev, 0x376, 1); |
236 | iomap[4] = pcim_iomap(dev, 2, 0); | 255 | iomap[4] = pcim_iomap(pdev, 2, 0); |
237 | 256 | ||
238 | if (!iomap[0] || !iomap[1] || !iomap[2] || !iomap[3] || !iomap[4]) | 257 | if (!iomap[0] || !iomap[1] || !iomap[2] || !iomap[3] || !iomap[4]) |
239 | return -ENOMEM; | 258 | return -ENOMEM; |
240 | 259 | ||
241 | /* We have to do our own plumbing as the PCI setup for this | 260 | ioaddr = &host->ports[0]->ioaddr; |
242 | chipset is non-standard so we can't punt to the libata code */ | 261 | ioaddr->cmd_addr = iomap[0]; |
243 | 262 | ioaddr->ctl_addr = iomap[1]; | |
244 | INIT_LIST_HEAD(&probe[0].node); | 263 | ioaddr->altstatus_addr = iomap[1]; |
245 | probe[0].dev = pci_dev_to_dev(dev); | 264 | ioaddr->bmdma_addr = iomap[4]; |
246 | probe[0].port_ops = &cs5520_port_ops; | 265 | ata_std_ports(ioaddr); |
247 | probe[0].sht = &cs5520_sht; | 266 | |
248 | probe[0].pio_mask = 0x1F; | 267 | ioaddr = &host->ports[1]->ioaddr; |
249 | probe[0].mwdma_mask = id->driver_data; | 268 | ioaddr->cmd_addr = iomap[2]; |
250 | probe[0].irq = 14; | 269 | ioaddr->ctl_addr = iomap[3]; |
251 | probe[0].irq_flags = 0; | 270 | ioaddr->altstatus_addr = iomap[3]; |
252 | probe[0].port_flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST; | 271 | ioaddr->bmdma_addr = iomap[4] + 8; |
253 | probe[0].n_ports = 1; | 272 | ata_std_ports(ioaddr); |
254 | probe[0].port[0].cmd_addr = iomap[0]; | 273 | |
255 | probe[0].port[0].ctl_addr = iomap[1]; | 274 | /* activate the host */ |
256 | probe[0].port[0].altstatus_addr = iomap[1]; | 275 | pci_set_master(pdev); |
257 | probe[0].port[0].bmdma_addr = iomap[4]; | 276 | rc = ata_host_start(host); |
258 | 277 | if (rc) | |
259 | /* The secondary lurks at different addresses but is otherwise | 278 | return rc; |
260 | the same beastie */ | 279 | |
261 | 280 | for (i = 0; i < 2; i++) { | |
262 | probe[1] = probe[0]; | 281 | static const int irq[] = { 14, 15 }; |
263 | INIT_LIST_HEAD(&probe[1].node); | 282 | struct ata_port *ap = host->ports[0]; |
264 | probe[1].irq = 15; | 283 | |
265 | probe[1].port[0].cmd_addr = iomap[2]; | 284 | if (ata_port_is_dummy(ap)) |
266 | probe[1].port[0].ctl_addr = iomap[3]; | 285 | continue; |
267 | probe[1].port[0].altstatus_addr = iomap[3]; | 286 | |
268 | probe[1].port[0].bmdma_addr = iomap[4] + 8; | 287 | rc = devm_request_irq(&pdev->dev, irq[ap->port_no], |
269 | 288 | ata_interrupt, 0, DRV_NAME, host); | |
270 | /* Let libata fill in the port details */ | 289 | if (rc) |
271 | ata_std_ports(&probe[0].port[0]); | 290 | return rc; |
272 | ata_std_ports(&probe[1].port[0]); | 291 | } |
273 | 292 | ||
274 | /* Now add the ports that are active */ | 293 | return ata_host_register(host, &cs5520_sht); |
275 | if (pcicfg & 1) | ||
276 | ports += ata_device_add(&probe[0]); | ||
277 | if (pcicfg & 2) | ||
278 | ports += ata_device_add(&probe[1]); | ||
279 | if (ports) | ||
280 | return 0; | ||
281 | return -ENODEV; | ||
282 | } | 294 | } |
283 | 295 | ||
284 | /** | 296 | /** |