|
@@ -100,59 +100,28 @@ static u8 sl82c105_tune_pio(ide_drive_t *drive, u8 pio)
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
- * Configure the drive and the chipset for DMA
|
|
|
+ * Configure the drive for DMA.
|
|
|
+ * We'll program the chipset only when DMA is actually turned on.
|
|
|
*/
|
|
|
-static int config_for_dma (ide_drive_t *drive)
|
|
|
+static int config_for_dma(ide_drive_t *drive)
|
|
|
{
|
|
|
- ide_hwif_t *hwif = HWIF(drive);
|
|
|
- struct pci_dev *dev = hwif->pci_dev;
|
|
|
- unsigned int reg;
|
|
|
-
|
|
|
DBG(("config_for_dma(drive:%s)\n", drive->name));
|
|
|
|
|
|
- reg = (hwif->channel ? 0x4c : 0x44) + (drive->select.b.unit ? 4 : 0);
|
|
|
-
|
|
|
if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0)
|
|
|
- return 1;
|
|
|
+ return 0;
|
|
|
|
|
|
- pci_write_config_word(dev, reg, 0x0240);
|
|
|
-
|
|
|
- return 0;
|
|
|
+ return ide_dma_enable(drive);
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
- * Check to see if the drive and
|
|
|
- * chipset is capable of DMA mode
|
|
|
+ * Check to see if the drive and chipset are capable of DMA mode.
|
|
|
*/
|
|
|
-
|
|
|
-static int sl82c105_check_drive (ide_drive_t *drive)
|
|
|
+static int sl82c105_ide_dma_check(ide_drive_t *drive)
|
|
|
{
|
|
|
- ide_hwif_t *hwif = HWIF(drive);
|
|
|
-
|
|
|
- DBG(("sl82c105_check_drive(drive:%s)\n", drive->name));
|
|
|
-
|
|
|
- do {
|
|
|
- struct hd_driveid *id = drive->id;
|
|
|
+ DBG(("sl82c105_ide_dma_check(drive:%s)\n", drive->name));
|
|
|
|
|
|
- if (!drive->autodma)
|
|
|
- break;
|
|
|
-
|
|
|
- if (!id || !(id->capability & 1))
|
|
|
- break;
|
|
|
-
|
|
|
- /* Consult the list of known "bad" drives */
|
|
|
- if (__ide_dma_bad_drive(drive))
|
|
|
- break;
|
|
|
-
|
|
|
- if (id->field_valid & 2) {
|
|
|
- if ((id->dma_mword & hwif->mwdma_mask) ||
|
|
|
- (id->dma_1word & hwif->swdma_mask))
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- if (__ide_dma_good_drive(drive) && id->eide_dma_time < 150)
|
|
|
- return 0;
|
|
|
- } while (0);
|
|
|
+ if (ide_use_dma(drive) && config_for_dma(drive))
|
|
|
+ return 0;
|
|
|
|
|
|
return -1;
|
|
|
}
|
|
@@ -181,14 +150,14 @@ static inline void sl82c105_reset_host(struct pci_dev *dev)
|
|
|
* This function is called when the IDE timer expires, the drive
|
|
|
* indicates that it is READY, and we were waiting for DMA to complete.
|
|
|
*/
|
|
|
-static int sl82c105_ide_dma_lost_irq(ide_drive_t *drive)
|
|
|
+static int sl82c105_ide_dma_lostirq(ide_drive_t *drive)
|
|
|
{
|
|
|
- ide_hwif_t *hwif = HWIF(drive);
|
|
|
- struct pci_dev *dev = hwif->pci_dev;
|
|
|
- u32 val, mask = hwif->channel ? CTRL_IDE_IRQB : CTRL_IDE_IRQA;
|
|
|
- unsigned long dma_base = hwif->dma_base;
|
|
|
+ ide_hwif_t *hwif = HWIF(drive);
|
|
|
+ struct pci_dev *dev = hwif->pci_dev;
|
|
|
+ u32 val, mask = hwif->channel ? CTRL_IDE_IRQB : CTRL_IDE_IRQA;
|
|
|
+ u8 dma_cmd;
|
|
|
|
|
|
- printk("sl82c105: lost IRQ: resetting host\n");
|
|
|
+ printk("sl82c105: lost IRQ, resetting host\n");
|
|
|
|
|
|
/*
|
|
|
* Check the raw interrupt from the drive.
|
|
@@ -201,15 +170,15 @@ static int sl82c105_ide_dma_lost_irq(ide_drive_t *drive)
|
|
|
* Was DMA enabled? If so, disable it - we're resetting the
|
|
|
* host. The IDE layer will be handling the drive for us.
|
|
|
*/
|
|
|
- val = inb(dma_base);
|
|
|
- if (val & 1) {
|
|
|
- outb(val & ~1, dma_base);
|
|
|
+ dma_cmd = inb(hwif->dma_command);
|
|
|
+ if (dma_cmd & 1) {
|
|
|
+ outb(dma_cmd & ~1, hwif->dma_command);
|
|
|
printk("sl82c105: DMA was enabled\n");
|
|
|
}
|
|
|
|
|
|
sl82c105_reset_host(dev);
|
|
|
|
|
|
- /* ide_dmaproc would return 1, so we do as well */
|
|
|
+ /* __ide_dma_lostirq would return 1, so we do as well */
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
@@ -221,10 +190,10 @@ static int sl82c105_ide_dma_lost_irq(ide_drive_t *drive)
|
|
|
* The generic IDE core will have disabled the BMEN bit before this
|
|
|
* function is called.
|
|
|
*/
|
|
|
-static void sl82c105_ide_dma_start(ide_drive_t *drive)
|
|
|
+static void sl82c105_dma_start(ide_drive_t *drive)
|
|
|
{
|
|
|
- ide_hwif_t *hwif = HWIF(drive);
|
|
|
- struct pci_dev *dev = hwif->pci_dev;
|
|
|
+ ide_hwif_t *hwif = HWIF(drive);
|
|
|
+ struct pci_dev *dev = hwif->pci_dev;
|
|
|
|
|
|
sl82c105_reset_host(dev);
|
|
|
ide_dma_start(drive);
|
|
@@ -232,8 +201,8 @@ static void sl82c105_ide_dma_start(ide_drive_t *drive)
|
|
|
|
|
|
static int sl82c105_ide_dma_timeout(ide_drive_t *drive)
|
|
|
{
|
|
|
- ide_hwif_t *hwif = HWIF(drive);
|
|
|
- struct pci_dev *dev = hwif->pci_dev;
|
|
|
+ ide_hwif_t *hwif = HWIF(drive);
|
|
|
+ struct pci_dev *dev = hwif->pci_dev;
|
|
|
|
|
|
DBG(("sl82c105_ide_dma_timeout(drive:%s)\n", drive->name));
|
|
|
|
|
@@ -241,14 +210,20 @@ static int sl82c105_ide_dma_timeout(ide_drive_t *drive)
|
|
|
return __ide_dma_timeout(drive);
|
|
|
}
|
|
|
|
|
|
-static int sl82c105_ide_dma_on (ide_drive_t *drive)
|
|
|
+static int sl82c105_ide_dma_on(ide_drive_t *drive)
|
|
|
{
|
|
|
+ struct pci_dev *dev = HWIF(drive)->pci_dev;
|
|
|
+ int rc, reg = 0x44 + drive->dn * 4;
|
|
|
+
|
|
|
DBG(("sl82c105_ide_dma_on(drive:%s)\n", drive->name));
|
|
|
|
|
|
- if (config_for_dma(drive))
|
|
|
- return 1;
|
|
|
- printk(KERN_INFO "%s: DMA enabled\n", drive->name);
|
|
|
- return __ide_dma_on(drive);
|
|
|
+ rc = __ide_dma_on(drive);
|
|
|
+ if (rc == 0) {
|
|
|
+ pci_write_config_word(dev, reg, 0x0200);
|
|
|
+
|
|
|
+ printk(KERN_INFO "%s: DMA enabled\n", drive->name);
|
|
|
+ }
|
|
|
+ return rc;
|
|
|
}
|
|
|
|
|
|
static void sl82c105_dma_off_quietly(ide_drive_t *drive)
|
|
@@ -272,8 +247,8 @@ static void sl82c105_dma_off_quietly(ide_drive_t *drive)
|
|
|
*/
|
|
|
static void sl82c105_selectproc(ide_drive_t *drive)
|
|
|
{
|
|
|
- ide_hwif_t *hwif = HWIF(drive);
|
|
|
- struct pci_dev *dev = hwif->pci_dev;
|
|
|
+ ide_hwif_t *hwif = HWIF(drive);
|
|
|
+ struct pci_dev *dev = hwif->pci_dev;
|
|
|
u32 val, old, mask;
|
|
|
|
|
|
//DBG(("sl82c105_selectproc(drive:%s)\n", drive->name));
|
|
@@ -373,7 +348,7 @@ static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const c
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
- * Initialise the chip
|
|
|
+ * Initialise IDE channel
|
|
|
*/
|
|
|
static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
|
|
|
{
|
|
@@ -398,11 +373,6 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
|
|
|
*/
|
|
|
hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
|
|
|
|
|
|
- hwif->atapi_dma = 0;
|
|
|
- hwif->mwdma_mask = 0;
|
|
|
- hwif->swdma_mask = 0;
|
|
|
- hwif->autodma = 0;
|
|
|
-
|
|
|
if (!hwif->dma_base)
|
|
|
return;
|
|
|
|
|
@@ -412,27 +382,27 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
|
|
|
* Never ever EVER under any circumstances enable
|
|
|
* DMA when the bridge is this old.
|
|
|
*/
|
|
|
- printk(" %s: Winbond 553 bridge revision %d, BM-DMA disabled\n",
|
|
|
- hwif->name, rev);
|
|
|
- } else {
|
|
|
- hwif->atapi_dma = 1;
|
|
|
- hwif->mwdma_mask = 0x04;
|
|
|
-
|
|
|
- hwif->ide_dma_check = &sl82c105_check_drive;
|
|
|
- hwif->ide_dma_on = &sl82c105_ide_dma_on;
|
|
|
- hwif->dma_off_quietly = &sl82c105_dma_off_quietly;
|
|
|
- hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq;
|
|
|
- hwif->dma_start = &sl82c105_ide_dma_start;
|
|
|
- hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout;
|
|
|
-
|
|
|
- if (!noautodma)
|
|
|
- hwif->autodma = 1;
|
|
|
- hwif->drives[0].autodma = hwif->autodma;
|
|
|
- hwif->drives[1].autodma = hwif->autodma;
|
|
|
-
|
|
|
- if (hwif->mate)
|
|
|
- hwif->serialized = hwif->mate->serialized = 1;
|
|
|
+ printk(" %s: Winbond W83C553 bridge revision %d, "
|
|
|
+ "BM-DMA disabled\n", hwif->name, rev);
|
|
|
+ return;
|
|
|
}
|
|
|
+
|
|
|
+ hwif->atapi_dma = 1;
|
|
|
+ hwif->mwdma_mask = 0x04;
|
|
|
+
|
|
|
+ hwif->ide_dma_check = &sl82c105_ide_dma_check;
|
|
|
+ hwif->ide_dma_on = &sl82c105_ide_dma_on;
|
|
|
+ hwif->dma_off_quietly = &sl82c105_dma_off_quietly;
|
|
|
+ hwif->ide_dma_lostirq = &sl82c105_ide_dma_lostirq;
|
|
|
+ hwif->dma_start = &sl82c105_dma_start;
|
|
|
+ hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout;
|
|
|
+
|
|
|
+ if (!noautodma)
|
|
|
+ hwif->autodma = 1;
|
|
|
+ hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma;
|
|
|
+
|
|
|
+ if (hwif->mate)
|
|
|
+ hwif->serialized = hwif->mate->serialized = 1;
|
|
|
}
|
|
|
|
|
|
static ide_pci_device_t sl82c105_chipset __devinitdata = {
|