From: Sergei Shtylylov - 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 Cc: Bartlomiej Zolnierkiewicz Cc: Alan Cox Signed-off-by: Andrew Morton --- drivers/ide/ide-dma.c | 32 ++++++++++++++++++++++---------- drivers/ide/ide.c | 14 +++++++++----- include/linux/ide.h | 4 +++- 3 files changed, 34 insertions(+), 16 deletions(-) diff -puN drivers/ide/ide.c~ide-claim-extra-dma-ports-regardless-of-channel drivers/ide/ide.c --- devel/drivers/ide/ide.c~ide-claim-extra-dma-ports-regardless-of-channel 2006-04-30 00:34:54.000000000 -0700 +++ devel-akpm/drivers/ide/ide.c 2006-04-30 00:34:54.000000000 -0700 @@ -451,7 +451,7 @@ void ide_hwif_release_regions(ide_hwif_t * @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. */ @@ -540,9 +540,10 @@ static void ide_hwif_restore(ide_hwif_t 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; @@ -551,7 +552,7 @@ static void ide_hwif_restore(ide_hwif_t } /** - * 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 @@ -564,8 +565,8 @@ static void ide_hwif_restore(ide_hwif_t * 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. @@ -675,6 +676,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 */ diff -puN drivers/ide/ide-dma.c~ide-claim-extra-dma-ports-regardless-of-channel drivers/ide/ide-dma.c --- devel/drivers/ide/ide-dma.c~ide-claim-extra-dma-ports-regardless-of-channel 2006-04-30 00:34:54.000000000 -0700 +++ devel-akpm/drivers/ide/ide-dma.c 2006-04-30 00:34:54.000000000 -0700 @@ -800,9 +800,9 @@ static int ide_release_dma_engine(ide_hw 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; @@ -842,9 +842,7 @@ static int ide_mapped_mmio_dma(ide_hwif_ { 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; @@ -856,17 +854,29 @@ static int ide_mapped_mmio_dma(ide_hwif_ 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 @@ -876,6 +886,8 @@ static int ide_iomio_dma(ide_hwif_t *hwi { 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; } } diff -puN include/linux/ide.h~ide-claim-extra-dma-ports-regardless-of-channel include/linux/ide.h --- devel/include/linux/ide.h~ide-claim-extra-dma-ports-regardless-of-channel 2006-04-30 00:34:54.000000000 -0700 +++ devel-akpm/include/linux/ide.h 2006-04-30 00:34:54.000000000 -0700 @@ -774,10 +774,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 */ _