diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2007-10-11 17:54:00 -0400 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2007-10-11 17:54:00 -0400 |
commit | ca1997c1f35891b9e5d6c71ac587f97216886194 (patch) | |
tree | ddb48cc80f4884cc8d614eec27d02e5011bc953b | |
parent | 55f17e8da1f02ce0a36303a3f266c45045004cf5 (diff) |
sgiioc4: use ide_tune_dma()
* Add DRV_NAME define and use it instead of sgiioc4_chipset.name.
* Remove no longer needed sgiioc4_chipset.
* Remove needless clearing of ->atapi_dma from ide_dma_sgiioc4().
* Fix ide_dma_sgiioc4() to return success/failure. Check return value in
sgiioc4_ide_setup_pci_device() and set hwif->autodma accordingly. Also add
missing setting of drive->autodma.
* Add sgiioc4_speedproc() (implementation of ->speedproc method).
* Fix ->mwdma_mask (MWDMA2 mask is 0x04 not 0x02) and remove incorrect
->swdma_mask. Also remove needless initialization of ->ultra_mask.
* Use ide_tune_dma() in sgiioc4_ide_dma_check(), this fixes following bugs:
- DMA capability bit not being checked on the device
- DMA blacklist not being checked
- MWDMA2 mode support by device not being checked
Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Jeremy Higdon <jeremy@sgi.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
-rw-r--r-- | drivers/ide/pci/sgiioc4.c | 86 |
1 files changed, 43 insertions, 43 deletions
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index 38f63d19c3b9..c292e1de1d56 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c | |||
@@ -34,6 +34,8 @@ | |||
34 | 34 | ||
35 | #include <linux/ide.h> | 35 | #include <linux/ide.h> |
36 | 36 | ||
37 | #define DRV_NAME "SGIIOC4" | ||
38 | |||
37 | /* IOC4 Specific Definitions */ | 39 | /* IOC4 Specific Definitions */ |
38 | #define IOC4_CMD_OFFSET 0x100 | 40 | #define IOC4_CMD_OFFSET 0x100 |
39 | #define IOC4_CTRL_OFFSET 0x120 | 41 | #define IOC4_CTRL_OFFSET 0x120 |
@@ -289,15 +291,26 @@ static void sgiioc4_dma_off_quietly(ide_drive_t *drive) | |||
289 | drive->hwif->dma_host_off(drive); | 291 | drive->hwif->dma_host_off(drive); |
290 | } | 292 | } |
291 | 293 | ||
294 | static int sgiioc4_speedproc(ide_drive_t *drive, const u8 speed) | ||
295 | { | ||
296 | if (speed != XFER_MW_DMA_2) | ||
297 | return 1; | ||
298 | |||
299 | return ide_config_drive_speed(drive, speed); | ||
300 | } | ||
301 | |||
292 | static int sgiioc4_ide_dma_check(ide_drive_t *drive) | 302 | static int sgiioc4_ide_dma_check(ide_drive_t *drive) |
293 | { | 303 | { |
294 | /* FIXME: check for available DMA modes */ | 304 | if (ide_tune_dma(drive)) |
295 | if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) { | ||
296 | printk(KERN_WARNING "%s: couldn't set MWDMA2 mode, " | ||
297 | "using PIO instead\n", drive->name); | ||
298 | return -1; | ||
299 | } else | ||
300 | return 0; | 305 | return 0; |
306 | |||
307 | /* | ||
308 | * ->set_pio_mode is not implemented currently | ||
309 | * so this is just for the completness | ||
310 | */ | ||
311 | ide_set_max_pio(drive); | ||
312 | |||
313 | return -1; | ||
301 | } | 314 | } |
302 | 315 | ||
303 | /* returns 1 if dma irq issued, 0 otherwise */ | 316 | /* returns 1 if dma irq issued, 0 otherwise */ |
@@ -353,7 +366,7 @@ sgiioc4_INB(unsigned long port) | |||
353 | } | 366 | } |
354 | 367 | ||
355 | /* Creates a dma map for the scatter-gather list entries */ | 368 | /* Creates a dma map for the scatter-gather list entries */ |
356 | static void __devinit | 369 | static int __devinit |
357 | ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base) | 370 | ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base) |
358 | { | 371 | { |
359 | void __iomem *virt_dma_base; | 372 | void __iomem *virt_dma_base; |
@@ -369,7 +382,7 @@ ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base) | |||
369 | "ALREADY in use\n", | 382 | "ALREADY in use\n", |
370 | __FUNCTION__, hwif->name, (void *) dma_base, | 383 | __FUNCTION__, hwif->name, (void *) dma_base, |
371 | (void *) dma_base + num_ports - 1); | 384 | (void *) dma_base + num_ports - 1); |
372 | goto dma_alloc_failure; | 385 | return -1; |
373 | } | 386 | } |
374 | 387 | ||
375 | virt_dma_base = ioremap(dma_base, num_ports); | 388 | virt_dma_base = ioremap(dma_base, num_ports); |
@@ -395,7 +408,7 @@ ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base) | |||
395 | 408 | ||
396 | if (pad) { | 409 | if (pad) { |
397 | ide_set_hwifdata(hwif, pad); | 410 | ide_set_hwifdata(hwif, pad); |
398 | return; | 411 | return 0; |
399 | } | 412 | } |
400 | 413 | ||
401 | pci_free_consistent(hwif->pci_dev, | 414 | pci_free_consistent(hwif->pci_dev, |
@@ -413,10 +426,7 @@ dma_pci_alloc_failure: | |||
413 | dma_remap_failure: | 426 | dma_remap_failure: |
414 | release_mem_region(dma_base, num_ports); | 427 | release_mem_region(dma_base, num_ports); |
415 | 428 | ||
416 | dma_alloc_failure: | 429 | return -1; |
417 | /* Disable DMA because we couldnot allocate any DMA maps */ | ||
418 | hwif->autodma = 0; | ||
419 | hwif->atapi_dma = 0; | ||
420 | } | 430 | } |
421 | 431 | ||
422 | /* Initializes the IOC4 DMA Engine */ | 432 | /* Initializes the IOC4 DMA Engine */ |
@@ -581,14 +591,11 @@ static void __devinit | |||
581 | ide_init_sgiioc4(ide_hwif_t * hwif) | 591 | ide_init_sgiioc4(ide_hwif_t * hwif) |
582 | { | 592 | { |
583 | hwif->mmio = 1; | 593 | hwif->mmio = 1; |
584 | hwif->autodma = 1; | ||
585 | hwif->atapi_dma = 1; | 594 | hwif->atapi_dma = 1; |
586 | hwif->ultra_mask = 0x0; /* Disable Ultra DMA */ | 595 | hwif->mwdma_mask = 0x04; |
587 | hwif->mwdma_mask = 0x2; /* Multimode-2 DMA */ | ||
588 | hwif->swdma_mask = 0x2; | ||
589 | hwif->pio_mask = 0x00; | 596 | hwif->pio_mask = 0x00; |
590 | hwif->set_pio_mode = NULL; /* Sets timing for PIO mode */ | 597 | hwif->set_pio_mode = NULL; /* Sets timing for PIO mode */ |
591 | hwif->speedproc = NULL; /* Sets timing for DMA &/or PIO modes */ | 598 | hwif->speedproc = &sgiioc4_speedproc; |
592 | hwif->selectproc = NULL;/* Use the default routine to select drive */ | 599 | hwif->selectproc = NULL;/* Use the default routine to select drive */ |
593 | hwif->reset_poll = NULL;/* No HBA specific reset_poll needed */ | 600 | hwif->reset_poll = NULL;/* No HBA specific reset_poll needed */ |
594 | hwif->pre_reset = NULL; /* No HBA specific pre_set needed */ | 601 | hwif->pre_reset = NULL; /* No HBA specific pre_set needed */ |
@@ -615,7 +622,7 @@ ide_init_sgiioc4(ide_hwif_t * hwif) | |||
615 | } | 622 | } |
616 | 623 | ||
617 | static int __devinit | 624 | static int __devinit |
618 | sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d) | 625 | sgiioc4_ide_setup_pci_device(struct pci_dev *dev) |
619 | { | 626 | { |
620 | unsigned long cmd_base, dma_base, irqport; | 627 | unsigned long cmd_base, dma_base, irqport; |
621 | unsigned long bar0, cmd_phys_base, ctl; | 628 | unsigned long bar0, cmd_phys_base, ctl; |
@@ -632,7 +639,8 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d) | |||
632 | break; | 639 | break; |
633 | } | 640 | } |
634 | if (h == MAX_HWIFS) { | 641 | if (h == MAX_HWIFS) { |
635 | printk(KERN_ERR "%s: too many IDE interfaces, no room in table\n", d->name); | 642 | printk(KERN_ERR "%s: too many IDE interfaces, no room in table\n", |
643 | DRV_NAME); | ||
636 | return -ENOMEM; | 644 | return -ENOMEM; |
637 | } | 645 | } |
638 | 646 | ||
@@ -641,7 +649,7 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d) | |||
641 | virt_base = ioremap(bar0, pci_resource_len(dev, 0)); | 649 | virt_base = ioremap(bar0, pci_resource_len(dev, 0)); |
642 | if (virt_base == NULL) { | 650 | if (virt_base == NULL) { |
643 | printk(KERN_ERR "%s: Unable to remap BAR 0 address: 0x%lx\n", | 651 | printk(KERN_ERR "%s: Unable to remap BAR 0 address: 0x%lx\n", |
644 | d->name, bar0); | 652 | DRV_NAME, bar0); |
645 | return -ENOMEM; | 653 | return -ENOMEM; |
646 | } | 654 | } |
647 | cmd_base = (unsigned long) virt_base + IOC4_CMD_OFFSET; | 655 | cmd_base = (unsigned long) virt_base + IOC4_CMD_OFFSET; |
@@ -672,7 +680,6 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d) | |||
672 | hwif->chipset = ide_pci; | 680 | hwif->chipset = ide_pci; |
673 | hwif->pci_dev = dev; | 681 | hwif->pci_dev = dev; |
674 | hwif->channel = 0; /* Single Channel chip */ | 682 | hwif->channel = 0; /* Single Channel chip */ |
675 | hwif->cds = (struct ide_pci_device_s *) d; | ||
676 | hwif->gendev.parent = &dev->dev;/* setup proper ancestral information */ | 683 | hwif->gendev.parent = &dev->dev;/* setup proper ancestral information */ |
677 | 684 | ||
678 | /* The IOC4 uses MMIO rather than Port IO. */ | 685 | /* The IOC4 uses MMIO rather than Port IO. */ |
@@ -683,11 +690,14 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d) | |||
683 | 690 | ||
684 | ide_init_sgiioc4(hwif); | 691 | ide_init_sgiioc4(hwif); |
685 | 692 | ||
686 | if (dma_base) | 693 | hwif->autodma = 0; |
687 | ide_dma_sgiioc4(hwif, dma_base); | 694 | |
688 | else | 695 | if (dma_base && ide_dma_sgiioc4(hwif, dma_base) == 0) { |
696 | hwif->autodma = 1; | ||
697 | hwif->drives[1].autodma = hwif->drives[0].autodma = 1; | ||
698 | } else | ||
689 | printk(KERN_INFO "%s: %s Bus-Master DMA disabled\n", | 699 | printk(KERN_INFO "%s: %s Bus-Master DMA disabled\n", |
690 | hwif->name, d->name); | 700 | hwif->name, DRV_NAME); |
691 | 701 | ||
692 | if (probe_hwif_init(hwif)) | 702 | if (probe_hwif_init(hwif)) |
693 | return -EIO; | 703 | return -EIO; |
@@ -699,7 +709,7 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d) | |||
699 | } | 709 | } |
700 | 710 | ||
701 | static unsigned int __devinit | 711 | static unsigned int __devinit |
702 | pci_init_sgiioc4(struct pci_dev *dev, ide_pci_device_t * d) | 712 | pci_init_sgiioc4(struct pci_dev *dev) |
703 | { | 713 | { |
704 | unsigned int class_rev; | 714 | unsigned int class_rev; |
705 | int ret; | 715 | int ret; |
@@ -707,30 +717,20 @@ pci_init_sgiioc4(struct pci_dev *dev, ide_pci_device_t * d) | |||
707 | pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); | 717 | pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); |
708 | class_rev &= 0xff; | 718 | class_rev &= 0xff; |
709 | printk(KERN_INFO "%s: IDE controller at PCI slot %s, revision %d\n", | 719 | printk(KERN_INFO "%s: IDE controller at PCI slot %s, revision %d\n", |
710 | d->name, pci_name(dev), class_rev); | 720 | DRV_NAME, pci_name(dev), class_rev); |
711 | if (class_rev < IOC4_SUPPORTED_FIRMWARE_REV) { | 721 | if (class_rev < IOC4_SUPPORTED_FIRMWARE_REV) { |
712 | printk(KERN_ERR "Skipping %s IDE controller in slot %s: " | 722 | printk(KERN_ERR "Skipping %s IDE controller in slot %s: " |
713 | "firmware is obsolete - please upgrade to revision" | 723 | "firmware is obsolete - please upgrade to " |
714 | "46 or higher\n", d->name, pci_name(dev)); | 724 | "revision46 or higher\n", |
725 | DRV_NAME, pci_name(dev)); | ||
715 | ret = -EAGAIN; | 726 | ret = -EAGAIN; |
716 | goto out; | 727 | goto out; |
717 | } | 728 | } |
718 | ret = sgiioc4_ide_setup_pci_device(dev, d); | 729 | ret = sgiioc4_ide_setup_pci_device(dev); |
719 | out: | 730 | out: |
720 | return ret; | 731 | return ret; |
721 | } | 732 | } |
722 | 733 | ||
723 | static ide_pci_device_t sgiioc4_chipset __devinitdata = { | ||
724 | /* Channel 0 */ | ||
725 | .name = "SGIIOC4", | ||
726 | .init_hwif = ide_init_sgiioc4, | ||
727 | .init_dma = ide_dma_sgiioc4, | ||
728 | .autodma = AUTODMA, | ||
729 | /* SGI IOC4 doesn't have enablebits. */ | ||
730 | .bootable = ON_BOARD, | ||
731 | .host_flags = IDE_HFLAG_SINGLE, | ||
732 | }; | ||
733 | |||
734 | int | 734 | int |
735 | ioc4_ide_attach_one(struct ioc4_driver_data *idd) | 735 | ioc4_ide_attach_one(struct ioc4_driver_data *idd) |
736 | { | 736 | { |
@@ -740,7 +740,7 @@ ioc4_ide_attach_one(struct ioc4_driver_data *idd) | |||
740 | if (idd->idd_variant == IOC4_VARIANT_PCI_RT) | 740 | if (idd->idd_variant == IOC4_VARIANT_PCI_RT) |
741 | return 0; | 741 | return 0; |
742 | 742 | ||
743 | return pci_init_sgiioc4(idd->idd_pdev, &sgiioc4_chipset); | 743 | return pci_init_sgiioc4(idd->idd_pdev); |
744 | } | 744 | } |
745 | 745 | ||
746 | static struct ioc4_submodule ioc4_ide_submodule = { | 746 | static struct ioc4_submodule ioc4_ide_submodule = { |