Commit be60d12a authored by Jens Axboe's avatar Jens Axboe

ns87145 update

parent 5b4d1cf0
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
#include <asm/io.h> #include <asm/io.h>
#include "ns87415.h"
static unsigned int ns87415_count = 0, ns87415_control[MAX_HWIFS] = { 0 }; static unsigned int ns87415_count = 0, ns87415_control[MAX_HWIFS] = { 0 };
/* /*
...@@ -81,51 +83,64 @@ static void ns87415_selectproc (ide_drive_t *drive) ...@@ -81,51 +83,64 @@ static void ns87415_selectproc (ide_drive_t *drive)
} }
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
static int ns87415_dmaproc(ide_dma_action_t func, ide_drive_t *drive) static int ns87415_ide_dma_end (ide_drive_t *drive)
{ {
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
byte dma_stat; u8 dma_stat = 0, dma_cmd = 0;
switch (func) { drive->waiting_for_dma = 0;
case ide_dma_end: /* returns 1 on error, 0 otherwise */ dma_stat = hwif->INB(hwif->dma_status);
drive->waiting_for_dma = 0; /* get dma command mode */
dma_stat = IN_BYTE(hwif->dma_base+2); dma_cmd = hwif->INB(hwif->dma_command);
/* stop DMA */ /* stop DMA */
OUT_BYTE(IN_BYTE(hwif->dma_base)&~1, hwif->dma_base); hwif->OUTB(dma_cmd & ~1, hwif->dma_command);
/* from ERRATA: clear the INTR & ERROR bits */ /* from ERRATA: clear the INTR & ERROR bits */
OUT_BYTE(IN_BYTE(hwif->dma_base)|6, hwif->dma_base); dma_cmd = hwif->INB(hwif->dma_command);
/* and free any DMA resources */ hwif->OUTB(dma_cmd|6, hwif->dma_command);
ide_destroy_dmatable(drive); /* and free any DMA resources */
/* verify good DMA status */ ide_destroy_dmatable(drive);
return (dma_stat & 7) != 4; /* verify good DMA status */
case ide_dma_write: return (dma_stat & 7) != 4;
case ide_dma_read: }
/* select DMA xfer */
ns87415_prepare_drive(drive, 1); static int ns87415_ide_dma_read (ide_drive_t *drive)
/* use standard DMA stuff */ {
if (!ide_dmaproc(func, drive)) /* select DMA xfer */
return 0; ns87415_prepare_drive(drive, 1);
/* DMA failed: select PIO xfer */ if (!(__ide_dma_read(drive)))
ns87415_prepare_drive(drive, 0); return 0;
return 1; /* DMA failed: select PIO xfer */
case ide_dma_check: ns87415_prepare_drive(drive, 0);
if (drive->media != ide_disk) return 1;
return ide_dmaproc(ide_dma_off_quietly, drive); }
/* Fallthrough... */
default: static int ns87415_ide_dma_write (ide_drive_t *drive)
return ide_dmaproc(func, drive); /* use standard DMA stuff */ {
} /* select DMA xfer */
ns87415_prepare_drive(drive, 1);
if (!(__ide_dma_write(drive)))
return 0;
/* DMA failed: select PIO xfer */
ns87415_prepare_drive(drive, 0);
return 1;
}
static int ns87415_ide_dma_check (ide_drive_t *drive)
{
if (drive->media != ide_disk)
return HWIF(drive)->ide_dma_off_quietly(drive);
return __ide_dma_check(drive);
} }
#endif /* CONFIG_BLK_DEV_IDEDMA */ #endif /* CONFIG_BLK_DEV_IDEDMA */
void __init ide_init_ns87415 (ide_hwif_t *hwif) static void __init init_hwif_ns87415 (ide_hwif_t *hwif)
{ {
struct pci_dev *dev = hwif->pci_dev; struct pci_dev *dev = hwif->pci_dev;
unsigned int ctrl, using_inta; unsigned int ctrl, using_inta;
byte progif; u8 progif;
#ifdef __sparc_v9__ #ifdef __sparc_v9__
int timeout; int timeout;
byte stat; u8 stat;
#endif #endif
hwif->autodma = 0; hwif->autodma = 0;
...@@ -173,12 +188,12 @@ void __init ide_init_ns87415 (ide_hwif_t *hwif) ...@@ -173,12 +188,12 @@ void __init ide_init_ns87415 (ide_hwif_t *hwif)
* to SELECT_DRIVE() properly during first probe_hwif(). * to SELECT_DRIVE() properly during first probe_hwif().
*/ */
timeout = 10000; timeout = 10000;
OUT_BYTE(12, hwif->io_ports[IDE_CONTROL_OFFSET]); hwif->OUTB(12, hwif->io_ports[IDE_CONTROL_OFFSET]);
udelay(10); udelay(10);
OUT_BYTE(8, hwif->io_ports[IDE_CONTROL_OFFSET]); hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]);
do { do {
udelay(50); udelay(50);
stat = IN_BYTE(hwif->io_ports[IDE_STATUS_OFFSET]); stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]);
if (stat == 0xff) if (stat == 0xff)
break; break;
} while ((stat & BUSY_STAT) && --timeout); } while ((stat & BUSY_STAT) && --timeout);
...@@ -194,11 +209,46 @@ void __init ide_init_ns87415 (ide_hwif_t *hwif) ...@@ -194,11 +209,46 @@ void __init ide_init_ns87415 (ide_hwif_t *hwif)
return; return;
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
OUT_BYTE(0x60, hwif->dma_base + 2); hwif->OUTB(0x60, hwif->dma_status);
hwif->dmaproc = &ns87415_dmaproc; hwif->ide_dma_read = &ns87415_ide_dma_read;
#ifdef CONFIG_IDEDMA_AUTO hwif->ide_dma_write = &ns87415_ide_dma_write;
hwif->ide_dma_check = &ns87415_ide_dma_check;
hwif->ide_dma_end = &ns87415_ide_dma_end;
if (!noautodma) if (!noautodma)
hwif->autodma = 1; hwif->autodma = 1;
#endif /* CONFIG_IDEDMA_AUTO */ hwif->drives[0].autodma = hwif->autodma;
hwif->drives[1].autodma = hwif->autodma;
#endif /* CONFIG_BLK_DEV_IDEDMA */ #endif /* CONFIG_BLK_DEV_IDEDMA */
} }
static void __init init_dma_ns87415 (ide_hwif_t *hwif, unsigned long dmabase)
{
ide_setup_dma(hwif, dmabase, 8);
}
extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);
static void __init init_setup_ns87415 (struct pci_dev *dev, ide_pci_device_t *d)
{
ide_setup_pci_device(dev, d);
}
int __init ns87415_scan_pcidev (struct pci_dev *dev)
{
ide_pci_device_t *d;
if (dev->vendor != PCI_VENDOR_ID_NS)
return 0;
for (d = ns87415_chipsets; d && d->vendor && d->device; ++d) {
if (((d->vendor == dev->vendor) &&
(d->device == dev->device)) &&
(d->init_setup)) {
d->init_setup(dev, d);
return 1;
}
}
return 0;
}
#ifndef NS87415_H
#define NS87415_H
#include <linux/config.h>
#include <linux/pci.h>
#include <linux/ide.h>
static void init_setup_ns87415(struct pci_dev *, ide_pci_device_t *);
static void init_hwif_ns87415(ide_hwif_t *);
static void init_dma_ns87415(ide_hwif_t *, unsigned long);
static ide_pci_device_t ns87415_chipsets[] __initdata = {
{
vendor: PCI_VENDOR_ID_NS,
device: PCI_DEVICE_ID_NS_87415,
name: "NS87415",
init_setup: init_setup_ns87415,
init_chipset: NULL,
init_iops: NULL,
init_hwif: init_hwif_ns87415,
init_dma: init_dma_ns87415,
channels: 2,
autodma: AUTODMA,
enablebits: {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
bootable: ON_BOARD,
extra: 0,
},{
vendor: 0,
device: 0,
channels: 0,
bootable: EOL,
}
};
#endif /* NS87415_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment