[PATCH] IDE: claim extra DMA ports regardless of channel
authorSergei Shtylylov <sshtylyov@ru.mvista.com>
Tue, 3 Oct 2006 08:14:13 +0000 (01:14 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Tue, 3 Oct 2006 15:04:07 +0000 (08:04 -0700)
- Claim extra DMA I/O ports regardless of what IDE channels are
  present/enabled.

- Remove extra ports handling from ide_mapped_mmio_dma() since it's not
  applicable to the custom-mapping IDE drivers.

Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Cc: Bartlomiej Zolnierkiewicz <B.Zolnierkiewicz@elka.pw.edu.pl>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
drivers/ide/ide-dma.c
drivers/ide/ide.c
include/linux/ide.h

index c3546fe..9937fa7 100644 (file)
@@ -798,9 +798,9 @@ static int ide_release_dma_engine(ide_hwif_t *hwif)
 
 static int ide_release_iomio_dma(ide_hwif_t *hwif)
 {
-       if ((hwif->dma_extra) && (hwif->channel == 0))
-               release_region((hwif->dma_base + 16), hwif->dma_extra);
        release_region(hwif->dma_base, 8);
+       if (hwif->extra_ports)
+               release_region(hwif->extra_base, hwif->extra_ports);
        if (hwif->dma_base2)
                release_region(hwif->dma_base, 8);
        return 1;
@@ -840,9 +840,7 @@ static int ide_mapped_mmio_dma(ide_hwif_t *hwif, unsigned long base, unsigned in
 {
        printk(KERN_INFO "    %s: MMIO-DMA ", hwif->name);
 
-       hwif->dma_base = base;
-       if (hwif->cds->extra && hwif->channel == 0)
-               hwif->dma_extra = hwif->cds->extra;
+       hwif->dma_base = base;
 
        if(hwif->mate)
                hwif->dma_master = (hwif->channel) ? hwif->mate->dma_base : base;
@@ -854,17 +852,29 @@ static int ide_mapped_mmio_dma(ide_hwif_t *hwif, unsigned long base, unsigned in
 static int ide_iomio_dma(ide_hwif_t *hwif, unsigned long base, unsigned int ports)
 {
        printk(KERN_INFO "    %s: BM-DMA at 0x%04lx-0x%04lx",
-               hwif->name, base, base + ports - 1);
+              hwif->name, base, base + ports - 1);
+
        if (!request_region(base, ports, hwif->name)) {
                printk(" -- Error, ports in use.\n");
                return 1;
        }
+
        hwif->dma_base = base;
-       if ((hwif->cds->extra) && (hwif->channel == 0)) {
-               request_region(base+16, hwif->cds->extra, hwif->cds->name);
-               hwif->dma_extra = hwif->cds->extra;
+
+       if (hwif->cds->extra) {
+               hwif->extra_base = base + (hwif->channel ? 8 : 16);
+
+               if (!hwif->mate || !hwif->mate->extra_ports) {
+                       if (!request_region(hwif->extra_base,
+                                           hwif->cds->extra, hwif->cds->name)) {
+                               printk(" -- Error, extra ports in use.\n");
+                               release_region(base, ports);
+                               return 1;
+                       }
+                       hwif->extra_ports = hwif->cds->extra;
+               }
        }
-       
+
        if(hwif->mate)
                hwif->dma_master = (hwif->channel) ? hwif->mate->dma_base : base;
        else
@@ -874,6 +884,8 @@ static int ide_iomio_dma(ide_hwif_t *hwif, unsigned long base, unsigned int port
                {
                        printk(" -- Error, secondary ports in use.\n");
                        release_region(base, ports);
+                       if (hwif->extra_ports)
+                               release_region(hwif->extra_base, hwif->extra_ports);
                        return 1;
                }
        }
index 2b1a138..8c3f062 100644 (file)
@@ -450,7 +450,7 @@ void ide_hwif_release_regions(ide_hwif_t *hwif)
  *     @hwif: hwif to update
  *     @tmp_hwif: template
  *
- *     Restore hwif to a previous state by copying most settngs
+ *     Restore hwif to a previous state by copying most settings
  *     from the template.
  */
 
@@ -539,9 +539,10 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
        hwif->dma_vendor3               = tmp_hwif->dma_vendor3;
        hwif->dma_prdtable              = tmp_hwif->dma_prdtable;
 
-       hwif->dma_extra                 = tmp_hwif->dma_extra;
        hwif->config_data               = tmp_hwif->config_data;
        hwif->select_data               = tmp_hwif->select_data;
+       hwif->extra_base                = tmp_hwif->extra_base;
+       hwif->extra_ports               = tmp_hwif->extra_ports;
        hwif->autodma                   = tmp_hwif->autodma;
        hwif->udma_four                 = tmp_hwif->udma_four;
        hwif->no_dsc                    = tmp_hwif->no_dsc;
@@ -550,7 +551,7 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
 }
 
 /**
- *     ide_unregister          -       free an ide interface
+ *     ide_unregister          -       free an IDE interface
  *     @index: index of interface (will change soon to a pointer)
  *
  *     Perform the final unregister of an IDE interface. At the moment
@@ -563,8 +564,8 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
  *     deadlocking the IDE layer. The shutdown callback is called
  *     before we take the lock and free resources. It is up to the
  *     caller to be sure there is no pending I/O here, and that
- *     the interfce will not be reopened (present/vanishing locking
- *     isnt yet done btw). After we commit to the final kill we
+ *     the interface will not be reopened (present/vanishing locking
+ *     isn't yet done BTW). After we commit to the final kill we
  *     call the cleanup callback with the ide locks held.
  *
  *     Unregister restores the hwif structures to the default state.
@@ -674,6 +675,9 @@ void ide_unregister(unsigned int index)
                hwif->dma_status = 0;
                hwif->dma_vendor3 = 0;
                hwif->dma_prdtable = 0;
+
+               hwif->extra_base  = 0;
+               hwif->extra_ports = 0;
        }
 
        /* copy original settings */
index 9962045..11608cd 100644 (file)
@@ -775,10 +775,12 @@ typedef struct hwif_s {
        unsigned long   dma_prdtable;   /* actual prd table address */
        unsigned long   dma_base2;      /* extended base addr for dma ports */
 
-       unsigned        dma_extra;      /* extra addr for dma ports */
        unsigned long   config_data;    /* for use by chipset-specific code */
        unsigned long   select_data;    /* for use by chipset-specific code */
 
+       unsigned long   extra_base;     /* extra addr for dma ports */
+       unsigned        extra_ports;    /* number of extra dma ports */
+
        unsigned        noprobe    : 1; /* don't probe for this interface */
        unsigned        present    : 1; /* this interface exists */
        unsigned        hold       : 1; /* this interface is always present */