diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-07-28 23:18:56 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-07-28 23:18:56 +0000 |
commit | 4d657aa39d5bcae60c2c11bf8fb66692ddd1c9e7 (patch) | |
tree | 30f3b08741a4d4b98b16bd99ea2757ff715d1c11 /drivers/ide | |
parent | eed6b7c84cc33f229f6fecd884d9a22af5bec514 (diff) |
Merge with 2.4.0-test5 final.
Diffstat (limited to 'drivers/ide')
-rw-r--r-- | drivers/ide/cmd64x.c | 65 | ||||
-rw-r--r-- | drivers/ide/hpt366.c | 24 | ||||
-rw-r--r-- | drivers/ide/ide-dma.c | 14 | ||||
-rw-r--r-- | drivers/ide/ide-features.c | 4 | ||||
-rw-r--r-- | drivers/ide/ide-pci.c | 4 | ||||
-rw-r--r-- | drivers/ide/ide-tape.c | 4 | ||||
-rw-r--r-- | drivers/ide/ide.c | 35 | ||||
-rw-r--r-- | drivers/ide/pdc202xx.c | 102 |
8 files changed, 220 insertions, 32 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; diff --git a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c index 74d3018c5..270cacc61 100644 --- a/drivers/ide/hpt366.c +++ b/drivers/ide/hpt366.c @@ -45,6 +45,7 @@ extern char *ide_dmafunc_verbose(ide_dma_action_t dmafunc); const char *quirk_drives[] = { "QUANTUM FIREBALLlct08 08", "QUANTUM FIREBALLP KA6.4", + "QUANTUM FIREBALLP LM20.4", "QUANTUM FIREBALLP LM20.5", NULL }; @@ -224,6 +225,14 @@ static unsigned int pci_rev_check_hpt3xx (struct pci_dev *dev) return ((int) (class_rev > 0x02) ? 1 : 0); } +static unsigned int pci_rev2_check_hpt3xx (struct pci_dev *dev) +{ + unsigned int class_rev; + pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); + class_rev &= 0xff; + return ((int) (class_rev > 0x01) ? 1 : 0); +} + static int check_in_drive_lists (ide_drive_t *drive, const char **list) { struct hd_driveid *id = drive->id; @@ -469,6 +478,11 @@ int hpt3xx_quirkproc (ide_drive_t *drive) void hpt3xx_intrproc (ide_drive_t *drive) { + if (drive->quirk_list) { + /* drives in the quirk_list may not like intr setups/cleanups */ + } else { + OUT_BYTE((drive)->ctl|2, HWIF(drive)->io_ports[IDE_CONTROL_OFFSET]); + } } void hpt3xx_maskproc (ide_drive_t *drive, int mask) @@ -556,11 +570,15 @@ no_dma_set: */ int hpt366_dmaproc (ide_dma_action_t func, ide_drive_t *drive) { - byte reg50h = 0, reg52h = 0, reg5ah = 0; + byte reg50h = 0, reg52h = 0, reg5ah = 0, dma_stat = 0; + unsigned long dma_base = HWIF(drive)->dma_base; switch (func) { case ide_dma_check: return config_drive_xfer_rate(drive); + case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */ + dma_stat = inb(dma_base+2); + return (dma_stat & 4) == 4; /* return 1 if INTR asserted */ case ide_dma_lostirq: pci_read_config_byte(HWIF(drive)->pci_dev, 0x50, ®50h); pci_read_config_byte(HWIF(drive)->pci_dev, 0x52, ®52h); @@ -651,6 +669,10 @@ void __init ide_init_hpt366 (ide_hwif_t *hwif) hwif->intrproc = &hpt3xx_intrproc; hwif->maskproc = &hpt3xx_maskproc; + if (pci_rev2_check_hpt3xx(hwif->pci_dev)) { + /* do nothing now but will split device types */ + } + #ifdef CONFIG_BLK_DEV_IDEDMA if (hwif->dma_base) { if (pci_rev_check_hpt3xx(hwif->pci_dev)) { diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index e9a34afc1..c15e7ee38 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -423,6 +423,14 @@ static int dma_timer_expiry (ide_drive_t *drive) printk("%s: dma_timer_expiry: dma status == 0x%02x\n", drive->name, dma_stat); #endif /* DEBUG */ +#if 1 + HWGROUP(drive)->expiry = NULL; /* one free ride for now */ +#endif + + if (dma_stat & 2) { /* ERROR */ + byte stat = GET_STAT(); + return ide_error(drive, "dma_timer_expiry", stat); + } if (dma_stat & 1) /* DMAing */ return WAIT_CMD; return 0; @@ -495,6 +503,12 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive) 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); +#if 0 /* do not set unless you know what you are doing */ + if (dma_stat & 4) { + byte stat = GET_STAT(); + outb(dma_base+2, dma_stat & 0xE4); + } +#endif return (dma_stat & 4) == 4; /* return 1 if INTR asserted */ case ide_dma_bad_drive: case ide_dma_good_drive: diff --git a/drivers/ide/ide-features.c b/drivers/ide/ide-features.c index 967b91e55..e46d16e7f 100644 --- a/drivers/ide/ide-features.c +++ b/drivers/ide/ide-features.c @@ -39,8 +39,6 @@ #include <asm/io.h> #include <asm/bitops.h> -#define SETFEATURES_CONTROL_REG (0) /* some arch's may need */ - /* * A Verbose noise maker for debugging on the attempted transfer rates. */ @@ -310,7 +308,7 @@ int ide_config_drive_speed (ide_drive_t *drive, byte speed) OUT_BYTE(speed, IDE_NSECTOR_REG); OUT_BYTE(SETFEATURES_XFER, IDE_FEATURE_REG); OUT_BYTE(WIN_SETFEATURES, IDE_COMMAND_REG); - if ((IDE_CONTROL_REG) && (SETFEATURES_CONTROL_REG)) + if ((IDE_CONTROL_REG) && (drive->quirk_list == 2)) OUT_BYTE(drive->ctl, IDE_CONTROL_REG); udelay(1); /* diff --git a/drivers/ide/ide-pci.c b/drivers/ide/ide-pci.c index 8c9354394..b09b889d7 100644 --- a/drivers/ide/ide-pci.c +++ b/drivers/ide/ide-pci.c @@ -39,6 +39,7 @@ #define DEVID_VP_IDE ((ide_pci_devid_t){PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1}) #define DEVID_PDC20246 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20246}) #define DEVID_PDC20262 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20262}) +#define DEVID_PDC20265 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20265}) #define DEVID_PDC20267 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20267}) #define DEVID_RZ1000 ((ide_pci_devid_t){PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000}) #define DEVID_RZ1001 ((ide_pci_devid_t){PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1001}) @@ -318,6 +319,7 @@ static ide_pci_device_t ide_pci_chipsets[] __initdata = { {DEVID_VP_IDE, "VP_IDE", PCI_VIA82CXXX, ATA66_VIA82CXXX,INIT_VIA82CXXX, DMA_VIA82CXXX, {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, ON_BOARD, 0 }, {DEVID_PDC20246,"PDC20246", PCI_PDC202XX, NULL, INIT_PDC202XX, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 16 }, {DEVID_PDC20262,"PDC20262", PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 48 }, + {DEVID_PDC20265,"PDC20265", PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 48 }, {DEVID_PDC20267,"PDC20267", PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 48 }, {DEVID_RZ1000, "RZ1000", NULL, NULL, INIT_RZ1000, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_RZ1001, "RZ1001", NULL, NULL, INIT_RZ1000, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, @@ -362,6 +364,7 @@ static unsigned int __init ide_special_settings (struct pci_dev *dev, const char case PCI_DEVICE_ID_TTI_HPT366: case PCI_DEVICE_ID_PROMISE_20246: case PCI_DEVICE_ID_PROMISE_20262: + case PCI_DEVICE_ID_PROMISE_20265: case PCI_DEVICE_ID_PROMISE_20267: case PCI_DEVICE_ID_ARTOP_ATP850UF: case PCI_DEVICE_ID_ARTOP_ATP860: @@ -633,6 +636,7 @@ check_if_enabled: hwif->autodma = 1; if (IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20246) || IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20262) || + IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20265) || IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20267) || IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6210) || IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6260) || diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 298603394..f36dbd8ff 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -3913,10 +3913,14 @@ static int idetape_get_logical_blk (ide_drive_t *drive, int logical_blk_num, int #endif clear_bit(IDETAPE_PIPELINE_ERROR, &tape->flags); position = idetape_read_position(drive); + if (position >= 3000 && position < 3080) + position += 32; if (position >= 2980 && position < 3000) position = 3000; else position += 60; + if (position >= 2980 && position < 3000) + position = 3000; printk(KERN_INFO "ide-tape: %s: blank block detected, positioning tape to block %d\n", tape->name, position); idetape_position_tape(drive, position, 0, 1); cnt += 40; diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 6fe3f9d36..d9ef9510f 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -481,13 +481,27 @@ void atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecoun */ static inline int drive_is_ready (ide_drive_t *drive) { + byte stat = 0; if (drive->waiting_for_dma) return HWIF(drive)->dmaproc(ide_dma_test_irq, drive); #if 0 udelay(1); /* need to guarantee 400ns since last command was issued */ #endif -// if (GET_STAT() & BUSY_STAT) /* Note: this may clear a pending IRQ!! */ - if (IN_BYTE(IDE_ALTSTATUS_REG) & BUSY_STAT) + +#ifdef CONFIG_IDEPCI_SHARE_IRQ + /* + * We do a passive status test under shared PCI interrupts on + * cards that truly share the ATA side interrupt, but may also share + * an interrupt with another pci card/device. We make no assumptions + * about possible isa-pnp and pci-pnp issues yet. + */ + if (IDE_CONTROL_REG) + stat = GET_ALTSTAT(); + else +#endif /* CONFIG_IDEPCI_SHARE_IRQ */ + stat = GET_STAT(); /* Note: this may clear a pending IRQ!! */ + + if (stat & BUSY_STAT) return 0; /* drive busy: definitely not interrupting */ return 1; /* drive ready: *might* be interrupting */ } @@ -2635,6 +2649,22 @@ static int ide_ioctl (struct inode *inode, struct file *file, } drive->nice1 = (arg >> IDE_NICE_1) & 1; return 0; + case HDIO_DRIVE_RESET: + if (!capable(CAP_SYS_ADMIN)) return -EACCES; + (void) ide_do_reset(drive); + if (drive->suspend_reset) { +/* + * APM WAKE UP todo !! + * int nogoodpower = 1; + * while(nogoodpower) { + * check_power1() or check_power2() + * nogoodpower = 0; + * } + * HWIF(drive)->multiproc(drive); + */ + return ide_revalidate_disk(inode->i_rdev); + } + return 0; case BLKROSET: case BLKROGET: @@ -3469,6 +3499,7 @@ int ide_register_subdriver (ide_drive_t *drive, ide_driver_t *driver, int versio drive->nice1 = 1; } drive->revalidate = 1; + drive->suspend_reset = 0; #ifdef CONFIG_PROC_FS ide_add_proc_entries(drive->proc, generic_subdriver_entries, drive); ide_add_proc_entries(drive->proc, driver->proc, drive); diff --git a/drivers/ide/pdc202xx.c b/drivers/ide/pdc202xx.c index 66a123841..6385cd81b 100644 --- a/drivers/ide/pdc202xx.c +++ b/drivers/ide/pdc202xx.c @@ -101,11 +101,18 @@ char *pdc202xx_ultra_verbose (u32 drive_pci, u16 slow_cable) return(pdc202xx_dma_verbose(drive_pci)); } -static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count) +char *pdc202xx_interrupt_verbose (u8 sc1d) { - char *p = buffer; + char *p = NULL; + p += sprintf(p,"0x%02x ", sc1d); + return (char *)p; +} + +static char * pdc202xx_info (char *buf, struct pci_dev *dev) +{ + char *p = buf; - u32 bibma = pci_resource_start(bmide_dev, 4); + u32 bibma = pci_resource_start(dev, 4); u32 reg60h = 0, reg64h = 0, reg68h = 0, reg6ch = 0; u16 reg50h = 0, pmask = (1<<10), smask = (1<<11); u8 hi = 0, lo = 0; @@ -125,16 +132,19 @@ static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count u8 sc1e = inb_p((unsigned short)bibma + 0x1e); u8 sc1f = inb_p((unsigned short)bibma + 0x1f); - pci_read_config_word(bmide_dev, 0x50, ®50h); - pci_read_config_dword(bmide_dev, 0x60, ®60h); - pci_read_config_dword(bmide_dev, 0x64, ®64h); - pci_read_config_dword(bmide_dev, 0x68, ®68h); - pci_read_config_dword(bmide_dev, 0x6c, ®6ch); + pci_read_config_word(dev, 0x50, ®50h); + pci_read_config_dword(dev, 0x60, ®60h); + pci_read_config_dword(dev, 0x64, ®64h); + pci_read_config_dword(dev, 0x68, ®68h); + pci_read_config_dword(dev, 0x6c, ®6ch); - switch(bmide_dev->device) { + switch(dev->device) { case PCI_DEVICE_ID_PROMISE_20267: p += sprintf(p, "\n PDC20267 Chipset.\n"); break; + case PCI_DEVICE_ID_PROMISE_20265: + p += sprintf(p, "\n PDC20265 Chipset.\n"); + break; case PCI_DEVICE_ID_PROMISE_20262: p += sprintf(p, "\n PDC20262 Chipset.\n"); break; @@ -174,10 +184,12 @@ static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count (sc1b & 0x01) ? "MASTER" : "PCI "); p += sprintf(p, " %s %s\n", (sc1d & 0x08) ? "Error " : + ((sc1d & 0x05) == 0x05) ? "Not My INTR " : (sc1d & 0x04) ? "Interrupting" : (sc1d & 0x02) ? "FIFO Full " : (sc1d & 0x01) ? "FIFO Empty " : "????????????", (sc1d & 0x80) ? "Error " : + ((sc1d & 0x50) == 0x50) ? "Not My INTR " : (sc1d & 0x40) ? "Interrupting" : (sc1d & 0x20) ? "FIFO Full " : (sc1d & 0x10) ? "FIFO Empty " : "????????????"); @@ -195,13 +207,27 @@ static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count #if 0 p += sprintf(p, "--------------- Can ATAPI DMA ---------------\n"); #endif - + return (char *)p; +} + +static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count) +{ + char *p = buffer; + p = pdc202xx_info(buffer, bmide_dev); return p-buffer; /* => must be less than 4k! */ } #endif /* defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS) */ byte pdc202xx_proc = 0; +const char *pdc_quirk_drives[] = { + "QUANTUM FIREBALLlct08 08", + "QUANTUM FIREBALLP KA6.4", + "QUANTUM FIREBALLP LM20.4", + "QUANTUM FIREBALLP LM20.5", + NULL +}; + extern char *ide_xfer_verbose (byte xfer_rate); /* A Register */ @@ -314,6 +340,26 @@ static void decode_registers (byte registers, byte value) #endif /* PDC202XX_DECODE_REGISTER_INFO */ +static int check_in_drive_lists (ide_drive_t *drive, const char **list) +{ + struct hd_driveid *id = drive->id; + + if (pdc_quirk_drives == list) { + while (*list) { + if (strstr(id->model, *list++)) { + return 2; + } + } + } else { + while (*list) { + if (!strcmp(*list++,id->model)) { + return 1; + } + } + } + return 0; +} + static int pdc202xx_tune_chipset (ide_drive_t *drive, byte speed) { ide_hwif_t *hwif = HWIF(drive); @@ -473,7 +519,7 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra) byte CLKSPD = IN_BYTE(high_16 + 0x11); byte udma_33 = ultra ? (inb(high_16 + 0x001f) & 1) : 0; byte udma_66 = ((eighty_ninty_three(drive)) && udma_33) ? 1 : 0; - byte udma_100 = ((dev->device == PCI_DEVICE_ID_PROMISE_20267) && udma_66) ? 1 : 0; + byte udma_100 = (((dev->device == PCI_DEVICE_ID_PROMISE_20265) || (dev->device == PCI_DEVICE_ID_PROMISE_20267)) && udma_66) ? 1 : 0; /* * Set the control register to use the 66Mhz system @@ -655,14 +701,37 @@ no_dma_set: return HWIF(drive)->dmaproc(dma_func, drive); } +int pdc202xx_quirkproc (ide_drive_t *drive) +{ + return ((int) check_in_drive_lists(drive, pdc_quirk_drives)); +} + /* * pdc202xx_dmaproc() initiates/aborts (U)DMA read/write operations on a drive. */ int pdc202xx_dmaproc (ide_dma_action_t func, ide_drive_t *drive) { + byte dma_stat = 0, sc1d = 0; + unsigned long high_16 = pci_resource_start(HWIF(drive)->pci_dev, 4); + unsigned long dma_base = HWIF(drive)->dma_base; + switch (func) { case ide_dma_check: return config_drive_xfer_rate(drive); + case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */ + dma_stat = inb(dma_base+2); + sc1d = inb(high_16 + 0x001d); + if (HWIF(drive)->channel) { + if ((sc1d & 0x50) == 0x50) goto somebody_else; + else if ((sc1d & 0x40) == 0x40) + return (dma_stat & 4) == 4; + } else { + if ((sc1d & 0x05) == 0x05) goto somebody_else; + else if ((sc1d & 0x04) == 0x04) + return (dma_stat & 4) == 4; + } +somebody_else: + return (dma_stat & 4) == 4; /* return 1 if INTR asserted */ case ide_dma_lostirq: case ide_dma_timeout: if (HWIF(drive)->resetproc != NULL) @@ -696,6 +765,7 @@ unsigned int __init pci_init_pdc202xx (struct pci_dev *dev, const char *name) byte secondary_mode = inb(high_16 + 0x001b); if ((dev->device == PCI_DEVICE_ID_PROMISE_20262) || + (dev->device == PCI_DEVICE_ID_PROMISE_20265) || (dev->device == PCI_DEVICE_ID_PROMISE_20267)) { int i = 0; /* @@ -725,7 +795,7 @@ unsigned int __init pci_init_pdc202xx (struct pci_dev *dev, const char *name) byte irq = 0, irq2 = 0; pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); pci_read_config_byte(dev, (PCI_INTERRUPT_LINE)|0x80, &irq2); /* 0xbc */ - if ((irq != irq2) && (dev->device != PCI_DEVICE_ID_PROMISE_20267)) { + if ((irq != irq2) && (dev->device != PCI_DEVICE_ID_PROMISE_20265) && (dev->device != PCI_DEVICE_ID_PROMISE_20267)) { pci_write_config_byte(dev, (PCI_INTERRUPT_LINE)|0x80, irq); /* 0xbc */ printk("%s: pci-config space interrupt mirror fixed.\n", name); } @@ -779,17 +849,21 @@ unsigned int __init ata66_pdc202xx (ide_hwif_t *hwif) unsigned short CIS; pci_read_config_word(hwif->pci_dev, 0x50, &CIS); - return ((CIS & mask) ? 0 : 1); + return ((CIS & mask) ? 0 : 1); } void __init ide_init_pdc202xx (ide_hwif_t *hwif) { hwif->tuneproc = &pdc202xx_tune_drive; hwif->speedproc = &pdc202xx_tune_chipset; + hwif->quirkproc = &pdc202xx_quirkproc; if ((hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20262) || - (hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20267)) + (hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20265) || + (hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20267)) { hwif->resetproc = &pdc202xx_reset; + hwif->tri_proc = &pdc202xx_tristate; + } #ifdef CONFIG_BLK_DEV_IDEDMA if (hwif->dma_base) { |