aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Wolstenholme <daniel@wolstenholme.net>2007-01-09 05:59:21 -0500
committerJeff Garzik <jeff@garzik.org>2007-02-09 17:39:31 -0500
commit7cbaa86b937b0b1fab95c159989f6a3c00bbcf78 (patch)
tree90dff6c4d7233793bdb00037024af49d6dab3ad1
parent553c4aa630af7bc885e056d0436e4eb7f238579b (diff)
[libata] sata_vsc: support PCI MSI
Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/ata/sata_vsc.c44
1 files changed, 41 insertions, 3 deletions
diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c
index 0fa1b89f76d5..1a5f3578894d 100644
--- a/drivers/ata/sata_vsc.c
+++ b/drivers/ata/sata_vsc.c
@@ -94,8 +94,14 @@ enum {
94 VSC_SATA_INT_ERROR_P | VSC_SATA_INT_ERROR_R | \ 94 VSC_SATA_INT_ERROR_P | VSC_SATA_INT_ERROR_R | \
95 VSC_SATA_INT_ERROR_E | VSC_SATA_INT_ERROR_M | \ 95 VSC_SATA_INT_ERROR_E | VSC_SATA_INT_ERROR_M | \
96 VSC_SATA_INT_PHY_CHANGE), 96 VSC_SATA_INT_PHY_CHANGE),
97
98 /* Host private flags (hp_flags) */
99 VSC_SATA_HP_FLAG_MSI = (1 << 0),
97}; 100};
98 101
102struct vsc_sata_host_priv {
103 u32 hp_flags;
104};
99 105
100#define is_vsc_sata_int_err(port_idx, int_status) \ 106#define is_vsc_sata_int_err(port_idx, int_status) \
101 (int_status & (VSC_SATA_INT_ERROR << (8 * port_idx))) 107 (int_status & (VSC_SATA_INT_ERROR << (8 * port_idx)))
@@ -118,6 +124,20 @@ static void vsc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg,
118} 124}
119 125
120 126
127static void vsc_sata_host_stop(struct ata_host_set *host_set)
128{
129 struct vsc_sata_host_priv *hpriv = host_set->private_data;
130 struct pci_dev *pdev = to_pci_dev(host_set->dev);
131
132 if (hpriv->hp_flags & VSC_SATA_HP_FLAG_MSI)
133 pci_disable_msi(pdev);
134 else
135 pci_intx(pdev, 0);
136 kfree (hpriv);
137 ata_pci_host_stop(host_set);
138}
139
140
121static void vsc_intr_mask_update(struct ata_port *ap, u8 ctl) 141static void vsc_intr_mask_update(struct ata_port *ap, u8 ctl)
122{ 142{
123 void __iomem *mask_addr; 143 void __iomem *mask_addr;
@@ -312,7 +332,7 @@ static const struct ata_port_operations vsc_sata_ops = {
312 .scr_write = vsc_sata_scr_write, 332 .scr_write = vsc_sata_scr_write,
313 .port_start = ata_port_start, 333 .port_start = ata_port_start,
314 .port_stop = ata_port_stop, 334 .port_stop = ata_port_stop,
315 .host_stop = ata_pci_host_stop, 335 .host_stop = vsc_sata_host_stop,
316}; 336};
317 337
318static void __devinit vsc_sata_setup_port(struct ata_ioports *port, unsigned long base) 338static void __devinit vsc_sata_setup_port(struct ata_ioports *port, unsigned long base)
@@ -341,6 +361,7 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
341{ 361{
342 static int printed_version; 362 static int printed_version;
343 struct ata_probe_ent *probe_ent = NULL; 363 struct ata_probe_ent *probe_ent = NULL;
364 struct vsc_sata_host_priv *hpriv;
344 unsigned long base; 365 unsigned long base;
345 int pci_dev_busy = 0; 366 int pci_dev_busy = 0;
346 void __iomem *mmio_base; 367 void __iomem *mmio_base;
@@ -382,6 +403,7 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
382 rc = -ENOMEM; 403 rc = -ENOMEM;
383 goto err_out_regions; 404 goto err_out_regions;
384 } 405 }
406
385 memset(probe_ent, 0, sizeof(*probe_ent)); 407 memset(probe_ent, 0, sizeof(*probe_ent));
386 probe_ent->dev = pci_dev_to_dev(pdev); 408 probe_ent->dev = pci_dev_to_dev(pdev);
387 INIT_LIST_HEAD(&probe_ent->node); 409 INIT_LIST_HEAD(&probe_ent->node);
@@ -393,19 +415,33 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
393 } 415 }
394 base = (unsigned long) mmio_base; 416 base = (unsigned long) mmio_base;
395 417
418 hpriv = kmalloc(sizeof(*hpriv), GFP_KERNEL);
419 if (!hpriv) {
420 rc = -ENOMEM;
421 goto err_out_iounmap;
422 }
423 memset(hpriv, 0, sizeof(*hpriv));
424
396 /* 425 /*
397 * Due to a bug in the chip, the default cache line size can't be used 426 * Due to a bug in the chip, the default cache line size can't be used
398 */ 427 */
399 pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x80); 428 pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x80);
400 429
430 if (pci_enable_msi(pdev) == 0) {
431 hpriv->hp_flags |= VSC_SATA_HP_FLAG_MSI;
432 pci_intx(pdev, 0);
433 }
434 else
435 probe_ent->irq_flags = IRQF_SHARED;
436
401 probe_ent->sht = &vsc_sata_sht; 437 probe_ent->sht = &vsc_sata_sht;
402 probe_ent->port_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | 438 probe_ent->port_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
403 ATA_FLAG_MMIO; 439 ATA_FLAG_MMIO;
404 probe_ent->port_ops = &vsc_sata_ops; 440 probe_ent->port_ops = &vsc_sata_ops;
405 probe_ent->n_ports = 4; 441 probe_ent->n_ports = 4;
406 probe_ent->irq = pdev->irq; 442 probe_ent->irq = pdev->irq;
407 probe_ent->irq_flags = IRQF_SHARED;
408 probe_ent->mmio_base = mmio_base; 443 probe_ent->mmio_base = mmio_base;
444 probe_ent->private_data = hpriv;
409 445
410 /* We don't care much about the PIO/UDMA masks, but the core won't like us 446 /* We don't care much about the PIO/UDMA masks, but the core won't like us
411 * if we don't fill these 447 * if we don't fill these
@@ -432,10 +468,12 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
432 468
433 /* FIXME: check ata_device_add return value */ 469 /* FIXME: check ata_device_add return value */
434 ata_device_add(probe_ent); 470 ata_device_add(probe_ent);
435 kfree(probe_ent);
436 471
472 kfree(probe_ent);
437 return 0; 473 return 0;
438 474
475err_out_iounmap:
476 pci_iounmap(pdev, mmio_base);
439err_out_free_ent: 477err_out_free_ent:
440 kfree(probe_ent); 478 kfree(probe_ent);
441err_out_regions: 479err_out_regions: