summaryrefslogtreecommitdiffstats
path: root/drivers/ide/cmd64x.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-07-28 23:18:56 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-07-28 23:18:56 +0000
commit4d657aa39d5bcae60c2c11bf8fb66692ddd1c9e7 (patch)
tree30f3b08741a4d4b98b16bd99ea2757ff715d1c11 /drivers/ide/cmd64x.c
parenteed6b7c84cc33f229f6fecd884d9a22af5bec514 (diff)
Merge with 2.4.0-test5 final.
Diffstat (limited to 'drivers/ide/cmd64x.c')
-rw-r--r--drivers/ide/cmd64x.c65
1 files changed, 53 insertions, 12 deletions
diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c
index 6e45bf0e0..80688e5a3 100644
--- a/drivers/ide/cmd64x.c
+++ b/drivers/ide/cmd64x.c
@@ -54,9 +54,9 @@
#define ARTTIM1 0x55
#define DRWTIM1 0x56
#define ARTTIM23 0x57
-#define ARTTIM23_INTR_CH1 0x04
#define ARTTIM23_DIS_RA2 0x04
#define ARTTIM23_DIS_RA3 0x08
+#define ARTTIM23_INTR_CH1 0x10
#define ARTTIM2 0x57
#define ARTTIM3 0x57
#define DRWTIM23 0x58
@@ -160,7 +160,6 @@ static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count)
((reg7b&0x00)==0x00)?(((reg7b&0x0A)==0x0A)?"5":"2"):"X"):"?" );
p += sprintf(p, "PIO Mode: %s %s %s %s\n",
"?", "?", "?", "?");
-
p += sprintf(p, " %s %s\n",
(reg50 & CFR_INTR_CH0) ? "interrupting" : "polling ",
(reg57 & ARTTIM23_INTR_CH1) ? "interrupting" : "polling");
@@ -589,9 +588,45 @@ no_dma_set:
static int cmd64x_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
{
+ byte dma_stat = 0;
+ byte dma_alt_stat = 0;
+ byte mask = (HWIF(drive)->channel) ? MRDMODE_INTR_CH1 : MRDMODE_INTR_CH0;
+ unsigned long dma_base = HWIF(drive)->dma_base;
+ struct pci_dev *dev = HWIF(drive)->pci_dev;
+ byte jack_slap = ((dev->device == PCI_DEVICE_ID_CMD_648) || (dev->device == PCI_DEVICE_ID_CMD_649)) ? 1 : 0;
+
switch (func) {
case ide_dma_check:
return cmd64x_config_drive_for_dma(drive);
+ case ide_dma_end: /* returns 1 on error, 0 otherwise */
+ drive->waiting_for_dma = 0;
+ outb(inb(dma_base)&~1, dma_base); /* stop DMA */
+ dma_stat = inb(dma_base+2); /* get DMA status */
+ outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
+ if (jack_slap) {
+ byte dma_intr = 0;
+ byte dma_mask = (HWIF(drive)->channel) ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0;
+ byte dma_reg = (HWIF(drive)->channel) ? ARTTIM2 : CFR;
+ (void) pci_read_config_byte(dev, dma_reg, &dma_intr);
+ /*
+ * DAMN BMIDE is not connected to PCI space!
+ * Have to manually jack-slap that bitch!
+ * To allow the PCI side to read incoming interrupts.
+ */
+ (void) pci_write_config_byte(dev, dma_reg, dma_intr|dma_mask); /* clear the INTR bit */
+ }
+ ide_destroy_dmatable(drive); /* purge DMA mappings */
+ return (dma_stat & 7) != 4; /* verify good DMA status */
+ case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */
+ dma_stat = inb(dma_base+2);
+ (void) pci_read_config_byte(dev, MRDMODE, &dma_alt_stat);
+#ifdef DEBUG
+ printk("%s: dma_stat: 0x%02x dma_alt_stat: 0x%02x mask: 0x%02x\n", drive->name, dma_stat, dma_alt_stat, mask);
+#endif
+ if (!(dma_alt_stat & mask)) {
+ return 0;
+ }
+ return (dma_stat & 4) == 4; /* return 1 if INTR asserted */
default:
break;
}
@@ -609,17 +644,22 @@ static int cmd646_1_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
unsigned long dma_base = hwif->dma_base;
byte dma_stat;
- if (func == ide_dma_end) {
- drive->waiting_for_dma = 0;
- dma_stat = inb(dma_base+2); /* get DMA status */
- outb(inb(dma_base)&~1, dma_base); /* stop DMA */
- outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
- ide_destroy_dmatable(drive); /* and free any DMA resources */
- return (dma_stat & 7) != 4; /* verify good DMA status */
+ switch (func) {
+ case ide_dma_check:
+ return cmd64x_config_drive_for_dma(drive);
+ case ide_dma_end:
+ drive->waiting_for_dma = 0;
+ dma_stat = inb(dma_base+2); /* get DMA status */
+ outb(inb(dma_base)&~1, dma_base); /* stop DMA */
+ outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
+ ide_destroy_dmatable(drive); /* and free any DMA resources */
+ return (dma_stat & 7) != 4; /* verify good DMA status */
+ default:
+ break;
}
/* Other cases are done by generic IDE-DMA code. */
- return cmd64x_dmaproc(func, drive);
+ return ide_dmaproc(func, drive);
}
#endif /* CONFIG_BLK_DEV_IDEDMA */
@@ -671,6 +711,7 @@ unsigned int __init pci_init_cmd64x (struct pci_dev *dev, const char *name)
(void) pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0x10);
#endif
+
/* Setup interrupts. */
(void) pci_read_config_byte(dev, MRDMODE, &mrdmode);
mrdmode &= ~(0x30);
@@ -728,8 +769,8 @@ void __init ide_init_cmd64x (ide_hwif_t *hwif)
pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
class_rev &= 0xff;
- hwif->tuneproc = &cmd64x_tuneproc;
- hwif->speedproc = &cmd64x_tune_chipset;
+ hwif->tuneproc = &cmd64x_tuneproc;
+ hwif->speedproc = &cmd64x_tune_chipset;
hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1;