/*
- * linux/drivers/ide/pci/cs5530.c Version 0.71 Mar 10 2007
+ * linux/drivers/ide/pci/cs5530.c Version 0.74 Jul 28 2007
*
* Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2000 Mark Lord <mlord@pobox.com>
#define CS5530_BAD_PIO(timings) (((timings)&~0x80000000)==0x0000e132)
#define CS5530_BASEREG(hwif) (((hwif)->dma_base & ~0xf) + ((hwif)->channel ? 0x30 : 0x20))
+static void cs5530_tunepio(ide_drive_t *drive, u8 pio)
+{
+ unsigned long basereg = CS5530_BASEREG(drive->hwif);
+ unsigned int format = (inl(basereg + 4) >> 31) & 1;
+
+ outl(cs5530_pio_timings[format][pio], basereg + ((drive->dn & 1)<<3));
+}
+
/**
- * cs5530_tuneproc - select/set PIO modes
+ * cs5530_set_pio_mode - set PIO mode
+ * @drive: drive
+ * @pio: PIO mode number
*
- * cs5530_tuneproc() handles selection/setting of PIO modes
- * for both the chipset and drive.
+ * Handles setting of PIO mode for both the chipset and drive.
*
- * The ide_init_cs5530() routine guarantees that all drives
+ * The init_hwif_cs5530() routine guarantees that all drives
* will have valid default PIO timings set up before we get here.
*/
-static void cs5530_tuneproc (ide_drive_t *drive, u8 pio) /* pio=255 means "autotune" */
+static void cs5530_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- ide_hwif_t *hwif = HWIF(drive);
- unsigned int format;
- unsigned long basereg = CS5530_BASEREG(hwif);
- static u8 modes[5] = { XFER_PIO_0, XFER_PIO_1, XFER_PIO_2, XFER_PIO_3, XFER_PIO_4};
-
- pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
- if (!cs5530_set_xfer_mode(drive, modes[pio])) {
- format = (inl(basereg + 4) >> 31) & 1;
- outl(cs5530_pio_timings[format][pio],
- basereg+(drive->select.b.unit<<3));
- }
+ if (cs5530_set_xfer_mode(drive, XFER_PIO_0 + pio) == 0)
+ cs5530_tunepio(drive, pio);
}
/**
static int cs5530_config_dma(ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
- unsigned int reg, timings = 0;
- unsigned long basereg;
- u8 unit = drive->dn & 1, mode = 0;
+ if (ide_tune_dma(drive))
+ return 0;
- /*
- * Default to DMA-off in case we run into trouble here.
- */
- hwif->dma_off_quietly(drive);
+ return 1;
+}
- if (ide_use_dma(drive))
- mode = ide_max_dma_mode(drive);
+static int cs5530_tune_chipset(ide_drive_t *drive, const u8 mode)
+{
+ unsigned long basereg;
+ unsigned int reg, timings = 0;
/*
* Tell the drive to switch to the new mode; abort on failure.
*/
- if (!mode || cs5530_set_xfer_mode(drive, mode))
+ if (cs5530_set_xfer_mode(drive, mode))
return 1; /* failure */
/*
BUG();
break;
}
- basereg = CS5530_BASEREG(hwif);
+ basereg = CS5530_BASEREG(drive->hwif);
reg = inl(basereg + 4); /* get drive0 config register */
timings |= reg & 0x80000000; /* preserve PIO format bit */
- if (unit == 0) { /* are we configuring drive0? */
+ if ((drive-> dn & 1) == 0) { /* are we configuring drive0? */
outl(timings, basereg + 4); /* write drive0 config register */
} else {
if (timings & 0x00100000)
struct pci_dev *master_0 = NULL, *cs5530_0 = NULL;
unsigned long flags;
+ if (pci_resource_start(dev, 4) == 0)
+ return -EFAULT;
+
dev = NULL;
while ((dev = pci_get_device(PCI_VENDOR_ID_CYRIX, PCI_ANY_ID, dev)) != NULL) {
switch (dev->device) {
*/
pci_set_master(cs5530_0);
- pci_set_mwi(cs5530_0);
+ pci_try_set_mwi(cs5530_0);
/*
* Set PCI CacheLineSize to 16-bytes:
if (hwif->mate)
hwif->serialized = hwif->mate->serialized = 1;
- hwif->tuneproc = &cs5530_tuneproc;
+ hwif->set_pio_mode = &cs5530_set_pio_mode;
+ hwif->speedproc = &cs5530_tune_chipset;
+
basereg = CS5530_BASEREG(hwif);
d0_timings = inl(basereg + 0);
if (CS5530_BAD_PIO(d0_timings)) {
/* needs autotuning later */
}
+ if (hwif->dma_base == 0)
+ return;
+
hwif->atapi_dma = 1;
hwif->ultra_mask = 0x07;
hwif->mwdma_mask = 0x07;
.name = "CS5530",
.init_chipset = init_chipset_cs5530,
.init_hwif = init_hwif_cs5530,
- .channels = 2,
.autodma = AUTODMA,
.bootable = ON_BOARD,
+ .pio_mask = ATA_PIO4,
};
static int __devinit cs5530_init_one(struct pci_dev *dev, const struct pci_device_id *id)