Commit be60d12a authored by Jens Axboe's avatar Jens Axboe

ns87145 update

parent 5b4d1cf0
......@@ -24,6 +24,8 @@
#include <asm/io.h>
#include "ns87415.h"
static unsigned int ns87415_count = 0, ns87415_control[MAX_HWIFS] = { 0 };
/*
......@@ -81,51 +83,64 @@ static void ns87415_selectproc (ide_drive_t *drive)
}
#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);
byte dma_stat;
switch (func) {
case ide_dma_end: /* returns 1 on error, 0 otherwise */
drive->waiting_for_dma = 0;
dma_stat = IN_BYTE(hwif->dma_base+2);
/* stop DMA */
OUT_BYTE(IN_BYTE(hwif->dma_base)&~1, hwif->dma_base);
/* from ERRATA: clear the INTR & ERROR bits */
OUT_BYTE(IN_BYTE(hwif->dma_base)|6, hwif->dma_base);
/* and free any DMA resources */
ide_destroy_dmatable(drive);
/* verify good DMA status */
return (dma_stat & 7) != 4;
case ide_dma_write:
case ide_dma_read:
/* select DMA xfer */
ns87415_prepare_drive(drive, 1);
/* use standard DMA stuff */
if (!ide_dmaproc(func, drive))
return 0;
/* DMA failed: select PIO xfer */
ns87415_prepare_drive(drive, 0);
return 1;
case ide_dma_check:
if (drive->media != ide_disk)
return ide_dmaproc(ide_dma_off_quietly, drive);
/* Fallthrough... */
default:
return ide_dmaproc(func, drive); /* use standard DMA stuff */
}
ide_hwif_t *hwif = HWIF(drive);
u8 dma_stat = 0, dma_cmd = 0;
drive->waiting_for_dma = 0;
dma_stat = hwif->INB(hwif->dma_status);
/* get dma command mode */
dma_cmd = hwif->INB(hwif->dma_command);
/* stop DMA */
hwif->OUTB(dma_cmd & ~1, hwif->dma_command);
/* from ERRATA: clear the INTR & ERROR bits */
dma_cmd = hwif->INB(hwif->dma_command);
hwif->OUTB(dma_cmd|6, hwif->dma_command);
/* and free any DMA resources */
ide_destroy_dmatable(drive);
/* verify good DMA status */
return (dma_stat & 7) != 4;
}
static int ns87415_ide_dma_read (ide_drive_t *drive)
{
/* select DMA xfer */
ns87415_prepare_drive(drive, 1);
if (!(__ide_dma_read(drive)))
return 0;
/* DMA failed: select PIO xfer */
ns87415_prepare_drive(drive, 0);
return 1;
}
static int ns87415_ide_dma_write (ide_drive_t *drive)
{
/* 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 */
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;
unsigned int ctrl, using_inta;
byte progif;
u8 progif;
#ifdef __sparc_v9__
int timeout;
byte stat;
u8 stat;
#endif
hwif->autodma = 0;
......@@ -173,12 +188,12 @@ void __init ide_init_ns87415 (ide_hwif_t *hwif)
* to SELECT_DRIVE() properly during first probe_hwif().
*/
timeout = 10000;
OUT_BYTE(12, hwif->io_ports[IDE_CONTROL_OFFSET]);
hwif->OUTB(12, hwif->io_ports[IDE_CONTROL_OFFSET]);
udelay(10);
OUT_BYTE(8, hwif->io_ports[IDE_CONTROL_OFFSET]);
hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]);
do {
udelay(50);
stat = IN_BYTE(hwif->io_ports[IDE_STATUS_OFFSET]);
stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]);
if (stat == 0xff)
break;
} while ((stat & BUSY_STAT) && --timeout);
......@@ -194,11 +209,46 @@ void __init ide_init_ns87415 (ide_hwif_t *hwif)
return;
#ifdef CONFIG_BLK_DEV_IDEDMA
OUT_BYTE(0x60, hwif->dma_base + 2);
hwif->dmaproc = &ns87415_dmaproc;
#ifdef CONFIG_IDEDMA_AUTO
hwif->OUTB(0x60, hwif->dma_status);
hwif->ide_dma_read = &ns87415_ide_dma_read;
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)
hwif->autodma = 1;
#endif /* CONFIG_IDEDMA_AUTO */
hwif->drives[0].autodma = hwif->autodma;
hwif->drives[1].autodma = hwif->autodma;
#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