trm290: cannot call ide_setup_dma()

The TRM-290 chip is *not* SFF-8038i compatible and therefore can *not* call
ide_setup_dma() -- fix this and also cleanup the code a bit...

Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
This commit is contained in:
Sergei Shtylyov 2008-02-01 23:09:29 +01:00 committed by Bartlomiej Zolnierkiewicz
parent f9afd18b58
commit 4e5a68aeb6
2 changed files with 43 additions and 32 deletions

View file

@ -933,6 +933,8 @@ static int ide_dma_iobase(ide_hwif_t *hwif, unsigned long base, unsigned int por
void ide_setup_dma(ide_hwif_t *hwif, unsigned long base, unsigned num_ports) void ide_setup_dma(ide_hwif_t *hwif, unsigned long base, unsigned num_ports)
{ {
u8 dma_stat;
if (ide_dma_iobase(hwif, base, num_ports)) if (ide_dma_iobase(hwif, base, num_ports))
return; return;
@ -971,13 +973,10 @@ void ide_setup_dma(ide_hwif_t *hwif, unsigned long base, unsigned num_ports)
if (!hwif->dma_lost_irq) if (!hwif->dma_lost_irq)
hwif->dma_lost_irq = &ide_dma_lost_irq; hwif->dma_lost_irq = &ide_dma_lost_irq;
if (hwif->chipset != ide_trm290) { dma_stat = hwif->INB(hwif->dma_status);
u8 dma_stat = hwif->INB(hwif->dma_status); printk(KERN_CONT ", BIOS settings: %s:%s, %s:%s\n",
printk(", BIOS settings: %s:%s, %s:%s", hwif->drives[0].name, (dma_stat & 0x20) ? "DMA" : "PIO",
hwif->drives[0].name, (dma_stat & 0x20) ? "DMA" : "pio", hwif->drives[1].name, (dma_stat & 0x40) ? "DMA" : "PIO");
hwif->drives[1].name, (dma_stat & 0x40) ? "DMA" : "pio");
}
printk("\n");
} }
EXPORT_SYMBOL_GPL(ide_setup_dma); EXPORT_SYMBOL_GPL(ide_setup_dma);

View file

@ -1,5 +1,5 @@
/* /*
* linux/drivers/ide/pci/trm290.c Version 1.05 Dec. 26, 2007 * linux/drivers/ide/pci/trm290.c Version 1.05 Dec. 30, 2007
* *
* Copyright (c) 1997-1998 Mark Lord * Copyright (c) 1997-1998 Mark Lord
* Copyright (c) 2007 MontaVista Software, Inc. <source@mvista.com> * Copyright (c) 2007 MontaVista Software, Inc. <source@mvista.com>
@ -209,10 +209,10 @@ static int trm290_dma_setup(ide_drive_t *drive)
} }
/* select DMA xfer */ /* select DMA xfer */
trm290_prepare_drive(drive, 1); trm290_prepare_drive(drive, 1);
outl(hwif->dmatable_dma | rw, hwif->dma_command); outl(hwif->dmatable_dma | rw, hwif->dma_base);
drive->waiting_for_dma = 1; drive->waiting_for_dma = 1;
/* start DMA */ /* start DMA */
outw((count * 2) - 1, hwif->dma_status); outw(count * 2 - 1, hwif->dma_base + 2);
return 0; return 0;
} }
@ -222,23 +222,21 @@ static void trm290_dma_start(ide_drive_t *drive)
static int trm290_ide_dma_end (ide_drive_t *drive) static int trm290_ide_dma_end (ide_drive_t *drive)
{ {
ide_hwif_t *hwif = HWIF(drive); u16 status;
u16 status = 0;
drive->waiting_for_dma = 0; drive->waiting_for_dma = 0;
/* purge DMA mappings */ /* purge DMA mappings */
ide_destroy_dmatable(drive); ide_destroy_dmatable(drive);
status = inw(hwif->dma_status); status = inw(HWIF(drive)->dma_base + 2);
return (status != 0x00ff); return status != 0x00ff;
} }
static int trm290_ide_dma_test_irq (ide_drive_t *drive) static int trm290_ide_dma_test_irq (ide_drive_t *drive)
{ {
ide_hwif_t *hwif = HWIF(drive); u16 status;
u16 status = 0;
status = inw(hwif->dma_status); status = inw(HWIF(drive)->dma_base + 2);
return (status == 0x00ff); return status == 0x00ff;
} }
static void trm290_dma_host_set(ide_drive_t *drive, int on) static void trm290_dma_host_set(ide_drive_t *drive, int on)
@ -247,21 +245,37 @@ static void trm290_dma_host_set(ide_drive_t *drive, int on)
static void __devinit init_hwif_trm290(ide_hwif_t *hwif) static void __devinit init_hwif_trm290(ide_hwif_t *hwif)
{ {
unsigned int cfgbase = 0; struct pci_dev *dev = hwif->pci_dev;
unsigned int cfg_base = pci_resource_start(dev, 4);
unsigned long flags; unsigned long flags;
u8 reg = 0; u8 reg = 0;
struct pci_dev *dev = hwif->pci_dev;
cfgbase = pci_resource_start(dev, 4); if ((dev->class & 5) && cfg_base)
if ((dev->class & 5) && cfgbase) { printk(KERN_INFO "TRM290: chip");
hwif->config_data = cfgbase; else {
printk(KERN_INFO "TRM290: chip config base at 0x%04lx\n", cfg_base = 0x3df0;
hwif->config_data); printk(KERN_INFO "TRM290: using default");
} else {
hwif->config_data = 0x3df0;
printk(KERN_INFO "TRM290: using default config base at 0x%04lx\n",
hwif->config_data);
} }
printk(KERN_CONT " config base at 0x%04x\n", cfg_base);
hwif->config_data = cfg_base;
hwif->dma_base = (cfg_base + 4) ^ (hwif->channel ? 0x80 : 0);
printk(KERN_INFO " %s: BM-DMA at 0x%04lx-0x%04lx",
hwif->name, hwif->dma_base, hwif->dma_base + 3);
if (!request_region(hwif->dma_base, 4, hwif->name)) {
printk(KERN_CONT " -- Error, ports in use.\n");
return;
}
hwif->dmatable_cpu = pci_alloc_consistent(dev, PRD_ENTRIES * PRD_BYTES,
&hwif->dmatable_dma);
if (!hwif->dmatable_cpu) {
printk(KERN_CONT " -- Error, unable to allocate DMA table.\n");
release_region(hwif->dma_base, 4);
return;
}
printk(KERN_CONT "\n");
local_irq_save(flags); local_irq_save(flags);
/* put config reg into first byte of hwif->select_data */ /* put config reg into first byte of hwif->select_data */
@ -276,15 +290,13 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif)
outb(reg, hwif->config_data + 3); outb(reg, hwif->config_data + 3);
local_irq_restore(flags); local_irq_restore(flags);
if ((reg & 0x10)) if (reg & 0x10)
/* legacy mode */ /* legacy mode */
hwif->irq = hwif->channel ? 15 : 14; hwif->irq = hwif->channel ? 15 : 14;
else if (!hwif->irq && hwif->mate && hwif->mate->irq) else if (!hwif->irq && hwif->mate && hwif->mate->irq)
/* sharing IRQ with mate */ /* sharing IRQ with mate */
hwif->irq = hwif->mate->irq; hwif->irq = hwif->mate->irq;
ide_setup_dma(hwif, (hwif->config_data + 4) ^ (hwif->channel ? 0x0080 : 0x0000), 3);
hwif->dma_host_set = &trm290_dma_host_set; hwif->dma_host_set = &trm290_dma_host_set;
hwif->dma_setup = &trm290_dma_setup; hwif->dma_setup = &trm290_dma_setup;
hwif->dma_exec_cmd = &trm290_dma_exec_cmd; hwif->dma_exec_cmd = &trm290_dma_exec_cmd;