ide: (hopefully) fix VDMA for CS5520

* Set the correct hwif->dma_base for the second channel in
  ide_get_or_set_dma_base().

* Remove DMA enable code from cs5520_set_pio_mode(), this can
  be handled by the generic ->dma_host_on method now.

* Add VDMA check to ide_config_drive_speed().

* drive->using_dma was never enabled since cs5520 host driver's
  ->ide_dma_on method overrided the generic ->ide_dma_on (so
  __ide_dma_on() was never called, drive->using_dma was never set
  and VDMA was never used since it depends on drive->using_dma).

  Fix it by using ->dma_host_on method instead of ->ide_dma_on
  (also add matching ->dma_host_off method).
Acked-by: NSergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: NBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
上级 29ec683f
...@@ -799,7 +799,7 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) ...@@ -799,7 +799,7 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
skip: skip:
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
if (speed >= XFER_SW_DMA_0) if (speed >= XFER_SW_DMA_0 || (hwif->host_flags & IDE_HFLAG_VDMA))
hwif->dma_host_on(drive); hwif->dma_host_on(drive);
else if (hwif->ide_dma_on) /* check if host supports DMA */ else if (hwif->ide_dma_on) /* check if host supports DMA */
hwif->dma_off_quietly(drive); hwif->dma_off_quietly(drive);
......
...@@ -71,7 +71,6 @@ static void cs5520_set_pio_mode(ide_drive_t *drive, const u8 pio) ...@@ -71,7 +71,6 @@ static void cs5520_set_pio_mode(ide_drive_t *drive, const u8 pio)
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *pdev = hwif->pci_dev; struct pci_dev *pdev = hwif->pci_dev;
int controller = drive->dn > 1 ? 1 : 0; int controller = drive->dn > 1 ? 1 : 0;
u8 reg;
/* FIXME: if DMA = 1 do we need to set the DMA bit here ? */ /* FIXME: if DMA = 1 do we need to set the DMA bit here ? */
...@@ -91,11 +90,6 @@ static void cs5520_set_pio_mode(ide_drive_t *drive, const u8 pio) ...@@ -91,11 +90,6 @@ static void cs5520_set_pio_mode(ide_drive_t *drive, const u8 pio)
pci_write_config_byte(pdev, 0x66 + 4*controller + (drive->dn&1), pci_write_config_byte(pdev, 0x66 + 4*controller + (drive->dn&1),
(cs5520_pio_clocks[pio].recovery << 4) | (cs5520_pio_clocks[pio].recovery << 4) |
(cs5520_pio_clocks[pio].assert)); (cs5520_pio_clocks[pio].assert));
/* Set the DMA enable/disable flag */
reg = inb(hwif->dma_base + 0x02 + 8*controller);
reg |= 1<<((drive->dn&1)+5);
outb(reg, hwif->dma_base + 0x02 + 8*controller);
} }
static void cs5520_set_dma_mode(ide_drive_t *drive, const u8 speed) static void cs5520_set_dma_mode(ide_drive_t *drive, const u8 speed)
...@@ -109,13 +103,23 @@ static void cs5520_set_dma_mode(ide_drive_t *drive, const u8 speed) ...@@ -109,13 +103,23 @@ static void cs5520_set_dma_mode(ide_drive_t *drive, const u8 speed)
* We wrap the DMA activate to set the vdma flag. This is needed * We wrap the DMA activate to set the vdma flag. This is needed
* so that the IDE DMA layer issues PIO not DMA commands over the * so that the IDE DMA layer issues PIO not DMA commands over the
* DMA channel * DMA channel
*
* ATAPI is harder so disable it for now using IDE_HFLAG_NO_ATAPI_DMA
*/ */
static int cs5520_dma_on(ide_drive_t *drive) static void cs5520_dma_host_on(ide_drive_t *drive)
{ {
/* ATAPI is harder so leave it for now */ if (drive->using_dma)
drive->vdma = 1; drive->vdma = 1;
return 0;
ide_dma_host_on(drive);
}
static void cs5520_dma_host_off(ide_drive_t *drive)
{
drive->vdma = 0;
ide_dma_host_off(drive);
} }
static void __devinit init_hwif_cs5520(ide_hwif_t *hwif) static void __devinit init_hwif_cs5520(ide_hwif_t *hwif)
...@@ -126,7 +130,8 @@ static void __devinit init_hwif_cs5520(ide_hwif_t *hwif) ...@@ -126,7 +130,8 @@ static void __devinit init_hwif_cs5520(ide_hwif_t *hwif)
if (hwif->dma_base == 0) if (hwif->dma_base == 0)
return; return;
hwif->ide_dma_on = &cs5520_dma_on; hwif->dma_host_on = &cs5520_dma_host_on;
hwif->dma_host_off = &cs5520_dma_host_off;
} }
#define DECLARE_CS_DEV(name_str) \ #define DECLARE_CS_DEV(name_str) \
......
...@@ -165,13 +165,17 @@ static unsigned long ide_get_or_set_dma_base(const struct ide_port_info *d, ide_ ...@@ -165,13 +165,17 @@ static unsigned long ide_get_or_set_dma_base(const struct ide_port_info *d, ide_
dma_base = pci_resource_start(dev, baridx); dma_base = pci_resource_start(dev, baridx);
if (dma_base == 0) if (dma_base == 0) {
printk(KERN_ERR "%s: DMA base is invalid\n", d->name); printk(KERN_ERR "%s: DMA base is invalid\n", d->name);
return 0;
}
} }
if ((d->host_flags & IDE_HFLAG_CS5520) == 0 && dma_base) { if (hwif->channel)
dma_base += 8;
if ((d->host_flags & IDE_HFLAG_CS5520) == 0) {
u8 simplex_stat = 0; u8 simplex_stat = 0;
dma_base += hwif->channel ? 8 : 0;
switch(dev->device) { switch(dev->device) {
case PCI_DEVICE_ID_AL_M5219: case PCI_DEVICE_ID_AL_M5219:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册