diff options
Diffstat (limited to 'drivers/ata/pata_cs5520.c')
-rw-r--r-- | drivers/ata/pata_cs5520.c | 145 |
1 files changed, 73 insertions, 72 deletions
diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c index 55cc293e7487..79bef0d1fad3 100644 --- a/drivers/ata/pata_cs5520.c +++ b/drivers/ata/pata_cs5520.c | |||
@@ -139,18 +139,6 @@ static void cs5520_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
139 | cs5520_set_timings(ap, adev, adev->pio_mode); | 139 | cs5520_set_timings(ap, adev, adev->pio_mode); |
140 | } | 140 | } |
141 | 141 | ||
142 | |||
143 | static int cs5520_pre_reset(struct ata_port *ap) | ||
144 | { | ||
145 | ap->cbl = ATA_CBL_PATA40; | ||
146 | return ata_std_prereset(ap); | ||
147 | } | ||
148 | |||
149 | static void cs5520_error_handler(struct ata_port *ap) | ||
150 | { | ||
151 | return ata_bmdma_drive_eh(ap, cs5520_pre_reset, ata_std_softreset, NULL, ata_std_postreset); | ||
152 | } | ||
153 | |||
154 | static struct scsi_host_template cs5520_sht = { | 142 | static struct scsi_host_template cs5520_sht = { |
155 | .module = THIS_MODULE, | 143 | .module = THIS_MODULE, |
156 | .name = DRV_NAME, | 144 | .name = DRV_NAME, |
@@ -186,8 +174,9 @@ static struct ata_port_operations cs5520_port_ops = { | |||
186 | 174 | ||
187 | .freeze = ata_bmdma_freeze, | 175 | .freeze = ata_bmdma_freeze, |
188 | .thaw = ata_bmdma_thaw, | 176 | .thaw = ata_bmdma_thaw, |
189 | .error_handler = cs5520_error_handler, | 177 | .error_handler = ata_bmdma_error_handler, |
190 | .post_internal_cmd = ata_bmdma_post_internal_cmd, | 178 | .post_internal_cmd = ata_bmdma_post_internal_cmd, |
179 | .cable_detect = ata_cable_40wire, | ||
191 | 180 | ||
192 | .bmdma_setup = ata_bmdma_setup, | 181 | .bmdma_setup = ata_bmdma_setup, |
193 | .bmdma_start = ata_bmdma_start, | 182 | .bmdma_start = ata_bmdma_start, |
@@ -197,7 +186,6 @@ static struct ata_port_operations cs5520_port_ops = { | |||
197 | .qc_issue = ata_qc_issue_prot, | 186 | .qc_issue = ata_qc_issue_prot, |
198 | .data_xfer = ata_data_xfer, | 187 | .data_xfer = ata_data_xfer, |
199 | 188 | ||
200 | .irq_handler = ata_interrupt, | ||
201 | .irq_clear = ata_bmdma_irq_clear, | 189 | .irq_clear = ata_bmdma_irq_clear, |
202 | .irq_on = ata_irq_on, | 190 | .irq_on = ata_irq_on, |
203 | .irq_ack = ata_irq_ack, | 191 | .irq_ack = ata_irq_ack, |
@@ -205,91 +193,104 @@ static struct ata_port_operations cs5520_port_ops = { | |||
205 | .port_start = ata_port_start, | 193 | .port_start = ata_port_start, |
206 | }; | 194 | }; |
207 | 195 | ||
208 | 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) |
209 | { | 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]; | ||
210 | u8 pcicfg; | 204 | u8 pcicfg; |
211 | void __iomem *iomap[5]; | 205 | void *iomap[5]; |
212 | static struct ata_probe_ent probe[2]; | 206 | struct ata_host *host; |
213 | int ports = 0; | 207 | struct ata_ioports *ioaddr; |
208 | int i, rc; | ||
214 | 209 | ||
215 | /* IDE port enable bits */ | 210 | /* IDE port enable bits */ |
216 | pci_read_config_byte(dev, 0x60, &pcicfg); | 211 | pci_read_config_byte(pdev, 0x60, &pcicfg); |
217 | 212 | ||
218 | /* Check if the ATA ports are enabled */ | 213 | /* Check if the ATA ports are enabled */ |
219 | if ((pcicfg & 3) == 0) | 214 | if ((pcicfg & 3) == 0) |
220 | return -ENODEV; | 215 | return -ENODEV; |
221 | 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 | |||
222 | if ((pcicfg & 0x40) == 0) { | 223 | if ((pcicfg & 0x40) == 0) { |
223 | printk(KERN_WARNING DRV_NAME ": DMA mode disabled. Enabling.\n"); | 224 | dev_printk(KERN_WARNING, &pdev->dev, |
224 | pci_write_config_byte(dev, 0x60, pcicfg | 0x40); | 225 | "DMA mode disabled. Enabling.\n"); |
226 | pci_write_config_byte(pdev, 0x60, pcicfg | 0x40); | ||
225 | } | 227 | } |
226 | 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 | |||
227 | /* Perform set up for DMA */ | 235 | /* Perform set up for DMA */ |
228 | if (pci_enable_device_bars(dev, 1<<2)) { | 236 | if (pci_enable_device_bars(pdev, 1<<2)) { |
229 | printk(KERN_ERR DRV_NAME ": unable to configure BAR2.\n"); | 237 | printk(KERN_ERR DRV_NAME ": unable to configure BAR2.\n"); |
230 | return -ENODEV; | 238 | return -ENODEV; |
231 | } | 239 | } |
232 | pci_set_master(dev); | 240 | |
233 | if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) { | 241 | if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { |
234 | printk(KERN_ERR DRV_NAME ": unable to configure DMA mask.\n"); | 242 | printk(KERN_ERR DRV_NAME ": unable to configure DMA mask.\n"); |
235 | return -ENODEV; | 243 | return -ENODEV; |
236 | } | 244 | } |
237 | if (pci_set_consistent_dma_mask(dev, DMA_32BIT_MASK)) { | 245 | if (pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) { |
238 | 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"); |
239 | return -ENODEV; | 247 | return -ENODEV; |
240 | } | 248 | } |
241 | 249 | ||
242 | /* Map IO ports */ | 250 | /* Map IO ports and initialize host accordingly */ |
243 | iomap[0] = devm_ioport_map(&dev->dev, 0x1F0, 8); | 251 | iomap[0] = devm_ioport_map(&pdev->dev, 0x1F0, 8); |
244 | iomap[1] = devm_ioport_map(&dev->dev, 0x3F6, 1); | 252 | iomap[1] = devm_ioport_map(&pdev->dev, 0x3F6, 1); |
245 | iomap[2] = devm_ioport_map(&dev->dev, 0x170, 8); | 253 | iomap[2] = devm_ioport_map(&pdev->dev, 0x170, 8); |
246 | iomap[3] = devm_ioport_map(&dev->dev, 0x376, 1); | 254 | iomap[3] = devm_ioport_map(&pdev->dev, 0x376, 1); |
247 | iomap[4] = pcim_iomap(dev, 2, 0); | 255 | iomap[4] = pcim_iomap(pdev, 2, 0); |
248 | 256 | ||
249 | if (!iomap[0] || !iomap[1] || !iomap[2] || !iomap[3] || !iomap[4]) | 257 | if (!iomap[0] || !iomap[1] || !iomap[2] || !iomap[3] || !iomap[4]) |
250 | return -ENOMEM; | 258 | return -ENOMEM; |
251 | 259 | ||
252 | /* We have to do our own plumbing as the PCI setup for this | 260 | ioaddr = &host->ports[0]->ioaddr; |
253 | chipset is non-standard so we can't punt to the libata code */ | 261 | ioaddr->cmd_addr = iomap[0]; |
254 | 262 | ioaddr->ctl_addr = iomap[1]; | |
255 | INIT_LIST_HEAD(&probe[0].node); | 263 | ioaddr->altstatus_addr = iomap[1]; |
256 | probe[0].dev = pci_dev_to_dev(dev); | 264 | ioaddr->bmdma_addr = iomap[4]; |
257 | probe[0].port_ops = &cs5520_port_ops; | 265 | ata_std_ports(ioaddr); |
258 | probe[0].sht = &cs5520_sht; | 266 | |
259 | probe[0].pio_mask = 0x1F; | 267 | ioaddr = &host->ports[1]->ioaddr; |
260 | probe[0].mwdma_mask = id->driver_data; | 268 | ioaddr->cmd_addr = iomap[2]; |
261 | probe[0].irq = 14; | 269 | ioaddr->ctl_addr = iomap[3]; |
262 | probe[0].irq_flags = 0; | 270 | ioaddr->altstatus_addr = iomap[3]; |
263 | probe[0].port_flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST; | 271 | ioaddr->bmdma_addr = iomap[4] + 8; |
264 | probe[0].n_ports = 1; | 272 | ata_std_ports(ioaddr); |
265 | probe[0].port[0].cmd_addr = iomap[0]; | 273 | |
266 | probe[0].port[0].ctl_addr = iomap[1]; | 274 | /* activate the host */ |
267 | probe[0].port[0].altstatus_addr = iomap[1]; | 275 | pci_set_master(pdev); |
268 | probe[0].port[0].bmdma_addr = iomap[4]; | 276 | rc = ata_host_start(host); |
269 | 277 | if (rc) | |
270 | /* The secondary lurks at different addresses but is otherwise | 278 | return rc; |
271 | the same beastie */ | 279 | |
272 | 280 | for (i = 0; i < 2; i++) { | |
273 | probe[1] = probe[0]; | 281 | static const int irq[] = { 14, 15 }; |
274 | INIT_LIST_HEAD(&probe[1].node); | 282 | struct ata_port *ap = host->ports[0]; |
275 | probe[1].irq = 15; | 283 | |
276 | probe[1].port[0].cmd_addr = iomap[2]; | 284 | if (ata_port_is_dummy(ap)) |
277 | probe[1].port[0].ctl_addr = iomap[3]; | 285 | continue; |
278 | probe[1].port[0].altstatus_addr = iomap[3]; | 286 | |
279 | probe[1].port[0].bmdma_addr = iomap[4] + 8; | 287 | rc = devm_request_irq(&pdev->dev, irq[ap->port_no], |
280 | 288 | ata_interrupt, 0, DRV_NAME, host); | |
281 | /* Let libata fill in the port details */ | 289 | if (rc) |
282 | ata_std_ports(&probe[0].port[0]); | 290 | return rc; |
283 | ata_std_ports(&probe[1].port[0]); | 291 | } |
284 | 292 | ||
285 | /* Now add the ports that are active */ | 293 | return ata_host_register(host, &cs5520_sht); |
286 | if (pcicfg & 1) | ||
287 | ports += ata_device_add(&probe[0]); | ||
288 | if (pcicfg & 2) | ||
289 | ports += ata_device_add(&probe[1]); | ||
290 | if (ports) | ||
291 | return 0; | ||
292 | return -ENODEV; | ||
293 | } | 294 | } |
294 | 295 | ||
295 | /** | 296 | /** |