diff options
Diffstat (limited to 'drivers/ata/sata_sil.c')
| -rw-r--r-- | drivers/ata/sata_sil.c | 118 |
1 files changed, 59 insertions, 59 deletions
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c index 917b7ea4ef7c..0a1e417f309c 100644 --- a/drivers/ata/sata_sil.c +++ b/drivers/ata/sata_sil.c | |||
| @@ -46,7 +46,7 @@ | |||
| 46 | #include <linux/libata.h> | 46 | #include <linux/libata.h> |
| 47 | 47 | ||
| 48 | #define DRV_NAME "sata_sil" | 48 | #define DRV_NAME "sata_sil" |
| 49 | #define DRV_VERSION "2.1" | 49 | #define DRV_VERSION "2.2" |
| 50 | 50 | ||
| 51 | enum { | 51 | enum { |
| 52 | SIL_MMIO_BAR = 5, | 52 | SIL_MMIO_BAR = 5, |
| @@ -114,11 +114,10 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); | |||
| 114 | #ifdef CONFIG_PM | 114 | #ifdef CONFIG_PM |
| 115 | static int sil_pci_device_resume(struct pci_dev *pdev); | 115 | static int sil_pci_device_resume(struct pci_dev *pdev); |
| 116 | #endif | 116 | #endif |
| 117 | static void sil_dev_config(struct ata_port *ap, struct ata_device *dev); | 117 | static void sil_dev_config(struct ata_device *dev); |
| 118 | static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg); | 118 | static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg); |
| 119 | static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); | 119 | static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); |
| 120 | static void sil_post_set_mode (struct ata_port *ap); | 120 | static int sil_set_mode (struct ata_port *ap, struct ata_device **r_failed); |
| 121 | static irqreturn_t sil_interrupt(int irq, void *dev_instance); | ||
| 122 | static void sil_freeze(struct ata_port *ap); | 121 | static void sil_freeze(struct ata_port *ap); |
| 123 | static void sil_thaw(struct ata_port *ap); | 122 | static void sil_thaw(struct ata_port *ap); |
| 124 | 123 | ||
| @@ -197,7 +196,7 @@ static const struct ata_port_operations sil_ops = { | |||
| 197 | .check_status = ata_check_status, | 196 | .check_status = ata_check_status, |
| 198 | .exec_command = ata_exec_command, | 197 | .exec_command = ata_exec_command, |
| 199 | .dev_select = ata_std_dev_select, | 198 | .dev_select = ata_std_dev_select, |
| 200 | .post_set_mode = sil_post_set_mode, | 199 | .set_mode = sil_set_mode, |
| 201 | .bmdma_setup = ata_bmdma_setup, | 200 | .bmdma_setup = ata_bmdma_setup, |
| 202 | .bmdma_start = ata_bmdma_start, | 201 | .bmdma_start = ata_bmdma_start, |
| 203 | .bmdma_stop = ata_bmdma_stop, | 202 | .bmdma_stop = ata_bmdma_stop, |
| @@ -209,7 +208,6 @@ static const struct ata_port_operations sil_ops = { | |||
| 209 | .thaw = sil_thaw, | 208 | .thaw = sil_thaw, |
| 210 | .error_handler = ata_bmdma_error_handler, | 209 | .error_handler = ata_bmdma_error_handler, |
| 211 | .post_internal_cmd = ata_bmdma_post_internal_cmd, | 210 | .post_internal_cmd = ata_bmdma_post_internal_cmd, |
| 212 | .irq_handler = sil_interrupt, | ||
| 213 | .irq_clear = ata_bmdma_irq_clear, | 211 | .irq_clear = ata_bmdma_irq_clear, |
| 214 | .irq_on = ata_irq_on, | 212 | .irq_on = ata_irq_on, |
| 215 | .irq_ack = ata_irq_ack, | 213 | .irq_ack = ata_irq_ack, |
| @@ -221,7 +219,6 @@ static const struct ata_port_operations sil_ops = { | |||
| 221 | static const struct ata_port_info sil_port_info[] = { | 219 | static const struct ata_port_info sil_port_info[] = { |
| 222 | /* sil_3112 */ | 220 | /* sil_3112 */ |
| 223 | { | 221 | { |
| 224 | .sht = &sil_sht, | ||
| 225 | .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE, | 222 | .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE, |
| 226 | .pio_mask = 0x1f, /* pio0-4 */ | 223 | .pio_mask = 0x1f, /* pio0-4 */ |
| 227 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 224 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
| @@ -230,7 +227,6 @@ static const struct ata_port_info sil_port_info[] = { | |||
| 230 | }, | 227 | }, |
| 231 | /* sil_3112_no_sata_irq */ | 228 | /* sil_3112_no_sata_irq */ |
| 232 | { | 229 | { |
| 233 | .sht = &sil_sht, | ||
| 234 | .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE | | 230 | .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE | |
| 235 | SIL_FLAG_NO_SATA_IRQ, | 231 | SIL_FLAG_NO_SATA_IRQ, |
| 236 | .pio_mask = 0x1f, /* pio0-4 */ | 232 | .pio_mask = 0x1f, /* pio0-4 */ |
| @@ -240,7 +236,6 @@ static const struct ata_port_info sil_port_info[] = { | |||
| 240 | }, | 236 | }, |
| 241 | /* sil_3512 */ | 237 | /* sil_3512 */ |
| 242 | { | 238 | { |
| 243 | .sht = &sil_sht, | ||
| 244 | .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT, | 239 | .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT, |
| 245 | .pio_mask = 0x1f, /* pio0-4 */ | 240 | .pio_mask = 0x1f, /* pio0-4 */ |
| 246 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 241 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
| @@ -249,7 +244,6 @@ static const struct ata_port_info sil_port_info[] = { | |||
| 249 | }, | 244 | }, |
| 250 | /* sil_3114 */ | 245 | /* sil_3114 */ |
| 251 | { | 246 | { |
| 252 | .sht = &sil_sht, | ||
| 253 | .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT, | 247 | .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT, |
| 254 | .pio_mask = 0x1f, /* pio0-4 */ | 248 | .pio_mask = 0x1f, /* pio0-4 */ |
| 255 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 249 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
| @@ -297,7 +291,16 @@ static unsigned char sil_get_device_cache_line(struct pci_dev *pdev) | |||
| 297 | return cache_line; | 291 | return cache_line; |
| 298 | } | 292 | } |
| 299 | 293 | ||
| 300 | static void sil_post_set_mode (struct ata_port *ap) | 294 | /** |
| 295 | * sil_set_mode - wrap set_mode functions | ||
| 296 | * @ap: port to set up | ||
| 297 | * @r_failed: returned device when we fail | ||
| 298 | * | ||
| 299 | * Wrap the libata method for device setup as after the setup we need | ||
| 300 | * to inspect the results and do some configuration work | ||
| 301 | */ | ||
| 302 | |||
| 303 | static int sil_set_mode (struct ata_port *ap, struct ata_device **r_failed) | ||
| 301 | { | 304 | { |
| 302 | struct ata_host *host = ap->host; | 305 | struct ata_host *host = ap->host; |
| 303 | struct ata_device *dev; | 306 | struct ata_device *dev; |
| @@ -305,6 +308,11 @@ static void sil_post_set_mode (struct ata_port *ap) | |||
| 305 | void __iomem *addr = mmio_base + sil_port[ap->port_no].xfer_mode; | 308 | void __iomem *addr = mmio_base + sil_port[ap->port_no].xfer_mode; |
| 306 | u32 tmp, dev_mode[2]; | 309 | u32 tmp, dev_mode[2]; |
| 307 | unsigned int i; | 310 | unsigned int i; |
| 311 | int rc; | ||
| 312 | |||
| 313 | rc = ata_do_set_mode(ap, r_failed); | ||
| 314 | if (rc) | ||
| 315 | return rc; | ||
| 308 | 316 | ||
| 309 | for (i = 0; i < 2; i++) { | 317 | for (i = 0; i < 2; i++) { |
| 310 | dev = &ap->device[i]; | 318 | dev = &ap->device[i]; |
| @@ -323,6 +331,7 @@ static void sil_post_set_mode (struct ata_port *ap) | |||
| 323 | tmp |= (dev_mode[1] << 4); | 331 | tmp |= (dev_mode[1] << 4); |
| 324 | writel(tmp, addr); | 332 | writel(tmp, addr); |
| 325 | readl(addr); /* flush */ | 333 | readl(addr); /* flush */ |
| 334 | return 0; | ||
| 326 | } | 335 | } |
| 327 | 336 | ||
| 328 | static inline void __iomem *sil_scr_addr(struct ata_port *ap, unsigned int sc_reg) | 337 | static inline void __iomem *sil_scr_addr(struct ata_port *ap, unsigned int sc_reg) |
| @@ -521,7 +530,6 @@ static void sil_thaw(struct ata_port *ap) | |||
| 521 | 530 | ||
| 522 | /** | 531 | /** |
| 523 | * sil_dev_config - Apply device/host-specific errata fixups | 532 | * sil_dev_config - Apply device/host-specific errata fixups |
| 524 | * @ap: Port containing device to be examined | ||
| 525 | * @dev: Device to be examined | 533 | * @dev: Device to be examined |
| 526 | * | 534 | * |
| 527 | * After the IDENTIFY [PACKET] DEVICE step is complete, and a | 535 | * After the IDENTIFY [PACKET] DEVICE step is complete, and a |
| @@ -548,8 +556,9 @@ static void sil_thaw(struct ata_port *ap) | |||
| 548 | * appreciated. | 556 | * appreciated. |
| 549 | * - But then again UDMA5 is hardly anything to complain about | 557 | * - But then again UDMA5 is hardly anything to complain about |
| 550 | */ | 558 | */ |
| 551 | static void sil_dev_config(struct ata_port *ap, struct ata_device *dev) | 559 | static void sil_dev_config(struct ata_device *dev) |
| 552 | { | 560 | { |
| 561 | struct ata_port *ap = dev->ap; | ||
| 553 | int print_info = ap->eh_context.i.flags & ATA_EHI_PRINTINFO; | 562 | int print_info = ap->eh_context.i.flags & ATA_EHI_PRINTINFO; |
| 554 | unsigned int n, quirks = 0; | 563 | unsigned int n, quirks = 0; |
| 555 | unsigned char model_num[ATA_ID_PROD_LEN + 1]; | 564 | unsigned char model_num[ATA_ID_PROD_LEN + 1]; |
| @@ -583,10 +592,10 @@ static void sil_dev_config(struct ata_port *ap, struct ata_device *dev) | |||
| 583 | } | 592 | } |
| 584 | } | 593 | } |
| 585 | 594 | ||
| 586 | static void sil_init_controller(struct pci_dev *pdev, | 595 | static void sil_init_controller(struct ata_host *host) |
| 587 | int n_ports, unsigned long port_flags, | ||
| 588 | void __iomem *mmio_base) | ||
| 589 | { | 596 | { |
| 597 | struct pci_dev *pdev = to_pci_dev(host->dev); | ||
| 598 | void __iomem *mmio_base = host->iomap[SIL_MMIO_BAR]; | ||
| 590 | u8 cls; | 599 | u8 cls; |
| 591 | u32 tmp; | 600 | u32 tmp; |
| 592 | int i; | 601 | int i; |
| @@ -596,7 +605,7 @@ static void sil_init_controller(struct pci_dev *pdev, | |||
| 596 | if (cls) { | 605 | if (cls) { |
| 597 | cls >>= 3; | 606 | cls >>= 3; |
| 598 | cls++; /* cls = (line_size/8)+1 */ | 607 | cls++; /* cls = (line_size/8)+1 */ |
| 599 | for (i = 0; i < n_ports; i++) | 608 | for (i = 0; i < host->n_ports; i++) |
| 600 | writew(cls << 8 | cls, | 609 | writew(cls << 8 | cls, |
| 601 | mmio_base + sil_port[i].fifo_cfg); | 610 | mmio_base + sil_port[i].fifo_cfg); |
| 602 | } else | 611 | } else |
| @@ -604,10 +613,10 @@ static void sil_init_controller(struct pci_dev *pdev, | |||
| 604 | "cache line size not set. Driver may not function\n"); | 613 | "cache line size not set. Driver may not function\n"); |
| 605 | 614 | ||
| 606 | /* Apply R_ERR on DMA activate FIS errata workaround */ | 615 | /* Apply R_ERR on DMA activate FIS errata workaround */ |
| 607 | if (port_flags & SIL_FLAG_RERR_ON_DMA_ACT) { | 616 | if (host->ports[0]->flags & SIL_FLAG_RERR_ON_DMA_ACT) { |
| 608 | int cnt; | 617 | int cnt; |
| 609 | 618 | ||
| 610 | for (i = 0, cnt = 0; i < n_ports; i++) { | 619 | for (i = 0, cnt = 0; i < host->n_ports; i++) { |
| 611 | tmp = readl(mmio_base + sil_port[i].sfis_cfg); | 620 | tmp = readl(mmio_base + sil_port[i].sfis_cfg); |
| 612 | if ((tmp & 0x3) != 0x01) | 621 | if ((tmp & 0x3) != 0x01) |
| 613 | continue; | 622 | continue; |
| @@ -620,7 +629,7 @@ static void sil_init_controller(struct pci_dev *pdev, | |||
| 620 | } | 629 | } |
| 621 | } | 630 | } |
| 622 | 631 | ||
| 623 | if (n_ports == 4) { | 632 | if (host->n_ports == 4) { |
| 624 | /* flip the magic "make 4 ports work" bit */ | 633 | /* flip the magic "make 4 ports work" bit */ |
| 625 | tmp = readl(mmio_base + sil_port[2].bmdma); | 634 | tmp = readl(mmio_base + sil_port[2].bmdma); |
| 626 | if ((tmp & SIL_INTR_STEERING) == 0) | 635 | if ((tmp & SIL_INTR_STEERING) == 0) |
| @@ -632,15 +641,26 @@ static void sil_init_controller(struct pci_dev *pdev, | |||
| 632 | static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | 641 | static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) |
| 633 | { | 642 | { |
| 634 | static int printed_version; | 643 | static int printed_version; |
| 635 | struct device *dev = &pdev->dev; | 644 | int board_id = ent->driver_data; |
| 636 | struct ata_probe_ent *probe_ent; | 645 | const struct ata_port_info *ppi[] = { &sil_port_info[board_id], NULL }; |
| 646 | struct ata_host *host; | ||
| 637 | void __iomem *mmio_base; | 647 | void __iomem *mmio_base; |
| 638 | int rc; | 648 | int n_ports, rc; |
| 639 | unsigned int i; | 649 | unsigned int i; |
| 640 | 650 | ||
| 641 | if (!printed_version++) | 651 | if (!printed_version++) |
| 642 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); | 652 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); |
| 643 | 653 | ||
| 654 | /* allocate host */ | ||
| 655 | n_ports = 2; | ||
| 656 | if (board_id == sil_3114) | ||
| 657 | n_ports = 4; | ||
| 658 | |||
| 659 | host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); | ||
| 660 | if (!host) | ||
| 661 | return -ENOMEM; | ||
| 662 | |||
| 663 | /* acquire resources and fill host */ | ||
| 644 | rc = pcim_enable_device(pdev); | 664 | rc = pcim_enable_device(pdev); |
| 645 | if (rc) | 665 | if (rc) |
| 646 | return rc; | 666 | return rc; |
| @@ -650,6 +670,7 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 650 | pcim_pin_device(pdev); | 670 | pcim_pin_device(pdev); |
| 651 | if (rc) | 671 | if (rc) |
| 652 | return rc; | 672 | return rc; |
| 673 | host->iomap = pcim_iomap_table(pdev); | ||
| 653 | 674 | ||
| 654 | rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); | 675 | rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); |
| 655 | if (rc) | 676 | if (rc) |
| @@ -658,45 +679,25 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 658 | if (rc) | 679 | if (rc) |
| 659 | return rc; | 680 | return rc; |
| 660 | 681 | ||
| 661 | probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL); | 682 | mmio_base = host->iomap[SIL_MMIO_BAR]; |
| 662 | if (probe_ent == NULL) | ||
| 663 | return -ENOMEM; | ||
| 664 | 683 | ||
| 665 | INIT_LIST_HEAD(&probe_ent->node); | 684 | for (i = 0; i < host->n_ports; i++) { |
| 666 | probe_ent->dev = pci_dev_to_dev(pdev); | 685 | struct ata_ioports *ioaddr = &host->ports[i]->ioaddr; |
| 667 | probe_ent->port_ops = sil_port_info[ent->driver_data].port_ops; | 686 | |
| 668 | probe_ent->sht = sil_port_info[ent->driver_data].sht; | 687 | ioaddr->cmd_addr = mmio_base + sil_port[i].tf; |
| 669 | probe_ent->n_ports = (ent->driver_data == sil_3114) ? 4 : 2; | 688 | ioaddr->altstatus_addr = |
| 670 | probe_ent->pio_mask = sil_port_info[ent->driver_data].pio_mask; | 689 | ioaddr->ctl_addr = mmio_base + sil_port[i].ctl; |
| 671 | probe_ent->mwdma_mask = sil_port_info[ent->driver_data].mwdma_mask; | 690 | ioaddr->bmdma_addr = mmio_base + sil_port[i].bmdma; |
| 672 | probe_ent->udma_mask = sil_port_info[ent->driver_data].udma_mask; | 691 | ioaddr->scr_addr = mmio_base + sil_port[i].scr; |
| 673 | probe_ent->irq = pdev->irq; | 692 | ata_std_ports(ioaddr); |
| 674 | probe_ent->irq_flags = IRQF_SHARED; | ||
| 675 | probe_ent->port_flags = sil_port_info[ent->driver_data].flags; | ||
| 676 | |||
| 677 | probe_ent->iomap = pcim_iomap_table(pdev); | ||
| 678 | |||
| 679 | mmio_base = probe_ent->iomap[SIL_MMIO_BAR]; | ||
| 680 | |||
| 681 | for (i = 0; i < probe_ent->n_ports; i++) { | ||
| 682 | probe_ent->port[i].cmd_addr = mmio_base + sil_port[i].tf; | ||
| 683 | probe_ent->port[i].altstatus_addr = | ||
| 684 | probe_ent->port[i].ctl_addr = mmio_base + sil_port[i].ctl; | ||
| 685 | probe_ent->port[i].bmdma_addr = mmio_base + sil_port[i].bmdma; | ||
| 686 | probe_ent->port[i].scr_addr = mmio_base + sil_port[i].scr; | ||
| 687 | ata_std_ports(&probe_ent->port[i]); | ||
| 688 | } | 693 | } |
| 689 | 694 | ||
| 690 | sil_init_controller(pdev, probe_ent->n_ports, probe_ent->port_flags, | 695 | /* initialize and activate */ |
| 691 | mmio_base); | 696 | sil_init_controller(host); |
| 692 | 697 | ||
| 693 | pci_set_master(pdev); | 698 | pci_set_master(pdev); |
| 694 | 699 | return ata_host_activate(host, pdev->irq, sil_interrupt, IRQF_SHARED, | |
| 695 | if (!ata_device_add(probe_ent)) | 700 | &sil_sht); |
| 696 | return -ENODEV; | ||
| 697 | |||
| 698 | devm_kfree(dev, probe_ent); | ||
| 699 | return 0; | ||
| 700 | } | 701 | } |
| 701 | 702 | ||
| 702 | #ifdef CONFIG_PM | 703 | #ifdef CONFIG_PM |
| @@ -709,8 +710,7 @@ static int sil_pci_device_resume(struct pci_dev *pdev) | |||
| 709 | if (rc) | 710 | if (rc) |
| 710 | return rc; | 711 | return rc; |
| 711 | 712 | ||
| 712 | sil_init_controller(pdev, host->n_ports, host->ports[0]->flags, | 713 | sil_init_controller(host); |
| 713 | host->iomap[SIL_MMIO_BAR]); | ||
| 714 | ata_host_resume(host); | 714 | ata_host_resume(host); |
| 715 | 715 | ||
| 716 | return 0; | 716 | return 0; |
