diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-06-19 22:45:37 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-06-19 22:45:37 +0000 |
commit | 6d403070f28cd44860fdb3a53be5da0275c65cf4 (patch) | |
tree | 0d0e7fe7b5fb7568d19e11d7d862b77a866ce081 /drivers/ide/pdc202xx.c | |
parent | ecf1bf5f6c2e668d03b0a9fb026db7aa41e292e1 (diff) |
Merge with 2.4.0-test1-ac21 + pile of MIPS cleanups to make merging
possible. Chainsawed RM200 kernel to compile again. Jazz machine
status unknown.
Diffstat (limited to 'drivers/ide/pdc202xx.c')
-rw-r--r-- | drivers/ide/pdc202xx.c | 159 |
1 files changed, 121 insertions, 38 deletions
diff --git a/drivers/ide/pdc202xx.c b/drivers/ide/pdc202xx.c index f16d33921..66a123841 100644 --- a/drivers/ide/pdc202xx.c +++ b/drivers/ide/pdc202xx.c @@ -1,7 +1,7 @@ /* * linux/drivers/ide/pdc202xx.c Version 0.30 Mar. 18, 2000 * - * Copyright (C) 1998-2000 Andre Hedrick (andre@suse.com) + * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> * May be copied or modified under the terms of the GNU General Public License * * Promise Ultra33 cards with BIOS v1.20 through 1.28 will need this @@ -12,6 +12,8 @@ * Promise Ultra66 cards with BIOS v1.11 this * compiled into the kernel if you have more than one card installed. * + * Promise Ultra100 cards. + * * The latest chipset code will support the following :: * Three Ultra33 controllers and 12 drives. * 8 are UDMA supported and 4 are limited to DMA mode 2 multi-word. @@ -51,6 +53,10 @@ #define DISPLAY_PDC202XX_TIMINGS +#ifndef SPLIT_BYTE +#define SPLIT_BYTE(B,H,L) ((H)=(B>>4), (L)=(B-((B>>4)<<4))) +#endif + #if defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS) #include <linux/stat.h> #include <linux/proc_fs.h> @@ -99,10 +105,25 @@ static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count { char *p = buffer; - u32 bibma = bmide_dev->resource[4].start; + u32 bibma = pci_resource_start(bmide_dev, 4); u32 reg60h = 0, reg64h = 0, reg68h = 0, reg6ch = 0; u16 reg50h = 0, pmask = (1<<10), smask = (1<<11); - u8 c0 = 0, c1 = 0; + u8 hi = 0, lo = 0; + + /* + * at that point bibma+0x2 et bibma+0xa are byte registers + * to investigate: + */ + u8 c0 = inb_p((unsigned short)bibma + 0x02); + u8 c1 = inb_p((unsigned short)bibma + 0x0a); + + u8 sc11 = inb_p((unsigned short)bibma + 0x11); + u8 sc1a = inb_p((unsigned short)bibma + 0x1a); + u8 sc1b = inb_p((unsigned short)bibma + 0x1b); + u8 sc1c = inb_p((unsigned short)bibma + 0x1c); + u8 sc1d = inb_p((unsigned short)bibma + 0x1d); + 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); @@ -110,14 +131,10 @@ static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count pci_read_config_dword(bmide_dev, 0x68, ®68h); pci_read_config_dword(bmide_dev, 0x6c, ®6ch); - /* - * at that point bibma+0x2 et bibma+0xa are byte registers - * to investigate: - */ - c0 = inb_p((unsigned short)bibma + 0x02); - c1 = inb_p((unsigned short)bibma + 0x0a); - - switch(bmide_dev->device) { + switch(bmide_dev->device) { + case PCI_DEVICE_ID_PROMISE_20267: + p += sprintf(p, "\n PDC20267 Chipset.\n"); + break; case PCI_DEVICE_ID_PROMISE_20262: p += sprintf(p, "\n PDC20262 Chipset.\n"); break; @@ -130,9 +147,40 @@ static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count break; } + p += sprintf(p, "------------------------------- General Status ---------------------------------\n"); + p += sprintf(p, "Burst Mode : %sabled\n", (sc1f & 0x01) ? "en" : "dis"); + p += sprintf(p, "Host Mode : %s\n", (sc1f & 0x08) ? "Tri-Stated" : "Normal"); + p += sprintf(p, "Bus Clocking : %s\n", + ((sc1f & 0xC0) == 0xC0) ? "100 External" : + ((sc1f & 0x80) == 0x80) ? "66 External" : + ((sc1f & 0x40) == 0x40) ? "33 External" : "33 PCI Internal"); + p += sprintf(p, "IO pad select : %s mA\n", + ((sc1c & 0x03) == 0x03) ? "10" : + ((sc1c & 0x02) == 0x02) ? "8" : + ((sc1c & 0x01) == 0x01) ? "6" : + ((sc1c & 0x00) == 0x00) ? "4" : "??"); + SPLIT_BYTE(sc1e, hi, lo); + p += sprintf(p, "Status Polling Period : %d\n", hi); + p += sprintf(p, "Interrupt Check Status Polling Delay : %d\n", lo); p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n"); - p += sprintf(p, " %sabled %sabled\n", - (c0&0x80)?"dis":" en",(c1&0x80)?"dis":" en"); + p += sprintf(p, " %s %s\n", + (c0&0x80)?"disabled":"enabled ", + (c1&0x80)?"disabled":"enabled "); + p += sprintf(p, "66 Clocking %s %s\n", + (sc11&0x02)?"enabled ":"disabled", + (sc11&0x08)?"enabled ":"disabled"); + p += sprintf(p, " Mode %s Mode %s\n", + (sc1a & 0x01) ? "MASTER" : "PCI ", + (sc1b & 0x01) ? "MASTER" : "PCI "); + p += sprintf(p, " %s %s\n", + (sc1d & 0x08) ? "Error " : + (sc1d & 0x04) ? "Interrupting" : + (sc1d & 0x02) ? "FIFO Full " : + (sc1d & 0x01) ? "FIFO Empty " : "????????????", + (sc1d & 0x80) ? "Error " : + (sc1d & 0x40) ? "Interrupting" : + (sc1d & 0x20) ? "FIFO Full " : + (sc1d & 0x10) ? "FIFO Empty " : "????????????"); p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n"); p += sprintf(p, "DMA enabled: %s %s %s %s\n", (c0&0x20)?"yes":"no ",(c0&0x40)?"yes":"no ",(c1&0x20)?"yes":"no ",(c1&0x40)?"yes":"no "); @@ -141,9 +189,13 @@ static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count pdc202xx_ultra_verbose(reg64h, (reg50h & pmask)), pdc202xx_ultra_verbose(reg68h, (reg50h & smask)), pdc202xx_ultra_verbose(reg6ch, (reg50h & smask))); - p += sprintf(p, " PIO Mode: %s %s %s %s\n", + p += sprintf(p, "PIO Mode: %s %s %s %s\n", pdc202xx_pio_verbose(reg60h),pdc202xx_pio_verbose(reg64h), pdc202xx_pio_verbose(reg68h),pdc202xx_pio_verbose(reg6ch)); +#if 0 + p += sprintf(p, "--------------- Can ATAPI DMA ---------------\n"); +#endif + return p-buffer; /* => must be less than 4k! */ } #endif /* defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS) */ @@ -324,6 +376,7 @@ static int pdc202xx_tune_chipset (ide_drive_t *drive, byte speed) switch(speed) { #ifdef CONFIG_BLK_DEV_IDEDMA + case XFER_UDMA_5: case XFER_UDMA_4: TB = 0x20; TC = 0x01; break; /* speed 8 == UDMA mode 4 */ case XFER_UDMA_3: TB = 0x40; TC = 0x02; break; /* speed 7 == UDMA mode 3 */ case XFER_UDMA_2: TB = 0x20; TC = 0x01; break; /* speed 6 == UDMA mode 2 */ @@ -408,7 +461,7 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra) struct hd_driveid *id = drive->id; ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; - unsigned long high_16 = dev->resource[4].start & PCI_BASE_ADDRESS_IO_MASK; + unsigned long high_16 = pci_resource_start(dev, 4); unsigned long dma_base = hwif->dma_base; byte unit = (drive->select.b.unit & 0x01); @@ -418,8 +471,9 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra) byte AP; unsigned short EP; byte CLKSPD = IN_BYTE(high_16 + 0x11); - byte udma_66 = ((id->hw_config & 0x2000) && (hwif->udma_four)) ? 1 : 0; 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; /* * Set the control register to use the 66Mhz system @@ -436,11 +490,15 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra) byte mask = hwif->channel ? 0x08 : 0x02; unsigned short c_mask = hwif->channel ? (1<<11) : (1<<10); - byte ultra_66 = ((id->dma_ultra & 0x0010) || (id->dma_ultra & 0x0008)) ? 1 : 0; + byte ultra_66 = ((id->dma_ultra & 0x0010) || + (id->dma_ultra & 0x0008)) ? 1 : 0; + byte ultra_100 = ((id->dma_ultra & 0x0020) || + (id->dma_ultra & 0x0010) || + (id->dma_ultra & 0x0008)) ? 1 : 0; pci_read_config_word(dev, 0x50, &EP); - if ((ultra_66) && (EP & c_mask)) { + if (((ultra_66) || (ultra_100)) && (EP & c_mask)) { #ifdef DEBUG printk("ULTRA66: %s channel of Ultra 66 requires an 80-pin cable for Ultra66 operation.\n", hwif->channel ? "Secondary", "Primary"); printk(" Switching to Ultra33 mode.\n"); @@ -449,13 +507,14 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra) /* Secondary : zero out fourth bit */ OUT_BYTE(CLKSPD & ~mask, (high_16 + 0x11)); } else { - if (ultra_66) { + if ((ultra_66) || (ultra_100)) { /* * check to make sure drive on same channel * is u66 capable */ if (hwif->drives[!(drive->dn%2)].id) { - if ((hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0010) || + if ((hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0020) || + (hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0010) || (hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0008)) { OUT_BYTE(CLKSPD | mask, (high_16 + 0x11)); } else { @@ -517,17 +576,18 @@ chipset_is_set: if (drive->media == ide_disk) /* PREFETCH_EN */ pci_write_config_byte(dev, (drive_pci), AP|PREFETCH_EN); - if ((id->dma_ultra & 0x0010) && (udma_66) && (udma_33)) speed = XFER_UDMA_4; - else if ((id->dma_ultra & 0x0008) && (udma_66) && (udma_33)) speed = XFER_UDMA_3; - else if ((id->dma_ultra & 0x0004) && (udma_33)) speed = XFER_UDMA_2; - else if ((id->dma_ultra & 0x0002) && (udma_33)) speed = XFER_UDMA_1; - else if ((id->dma_ultra & 0x0001) && (udma_33)) speed = XFER_UDMA_0; - else if (id->dma_mword & 0x0004) speed = XFER_MW_DMA_2; - else if (id->dma_mword & 0x0002) speed = XFER_MW_DMA_1; - else if (id->dma_mword & 0x0001) speed = XFER_MW_DMA_0; - else if (id->dma_1word & 0x0004) speed = XFER_SW_DMA_2; - else if (id->dma_1word & 0x0002) speed = XFER_SW_DMA_1; - else if (id->dma_1word & 0x0001) speed = XFER_SW_DMA_0; + if ((id->dma_ultra & 0x0020) && (udma_100)) speed = XFER_UDMA_5; + else if ((id->dma_ultra & 0x0010) && (udma_66)) speed = XFER_UDMA_4; + else if ((id->dma_ultra & 0x0008) && (udma_66)) speed = XFER_UDMA_3; + else if ((id->dma_ultra & 0x0004) && (udma_33)) speed = XFER_UDMA_2; + else if ((id->dma_ultra & 0x0002) && (udma_33)) speed = XFER_UDMA_1; + else if ((id->dma_ultra & 0x0001) && (udma_33)) speed = XFER_UDMA_0; + else if (id->dma_mword & 0x0004) speed = XFER_MW_DMA_2; + else if (id->dma_mword & 0x0002) speed = XFER_MW_DMA_1; + else if (id->dma_mword & 0x0001) speed = XFER_MW_DMA_0; + else if (id->dma_1word & 0x0004) speed = XFER_SW_DMA_2; + else if (id->dma_1word & 0x0002) speed = XFER_SW_DMA_1; + else if (id->dma_1word & 0x0001) speed = XFER_SW_DMA_0; else { /* restore original pci-config space */ pci_write_config_dword(dev, drive_pci, drive_conf); @@ -537,7 +597,7 @@ chipset_is_set: outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2); (void) pdc202xx_tune_chipset(drive, speed); - return ((int) ((id->dma_ultra >> 11) & 3) ? ide_dma_on : + return ((int) ((id->dma_ultra >> 11) & 7) ? ide_dma_on : ((id->dma_ultra >> 8) & 7) ? ide_dma_on : ((id->dma_mword >> 8) & 7) ? ide_dma_on : ((id->dma_1word >> 8) & 7) ? ide_dma_on : @@ -558,7 +618,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive) } dma_func = ide_dma_off_quietly; if (id->field_valid & 4) { - if (id->dma_ultra & 0x001F) { + if (id->dma_ultra & 0x002F) { /* Force if Capable UltraDMA */ dma_func = config_chipset_for_dma(drive, 1); if ((id->field_valid & 2) && @@ -603,6 +663,10 @@ int pdc202xx_dmaproc (ide_dma_action_t func, ide_drive_t *drive) switch (func) { case ide_dma_check: return config_drive_xfer_rate(drive); + case ide_dma_lostirq: + case ide_dma_timeout: + if (HWIF(drive)->resetproc != NULL) + HWIF(drive)->resetproc(drive); default: break; } @@ -610,14 +674,29 @@ int pdc202xx_dmaproc (ide_dma_action_t func, ide_drive_t *drive) } #endif /* CONFIG_BLK_DEV_IDEDMA */ +void pdc202xx_reset (ide_drive_t *drive) +{ + unsigned long high_16 = pci_resource_start(HWIF(drive)->pci_dev, 4); + byte udma_speed_flag = inb(high_16 + 0x001f); + int i = 0; + + OUT_BYTE(udma_speed_flag | 0x10, high_16 + 0x001f); + ide_delay_50ms(); + ide_delay_50ms(); + OUT_BYTE(udma_speed_flag & ~0x10, high_16 + 0x001f); + for (i = 0; i < 40; i++) + ide_delay_50ms(); +} + unsigned int __init pci_init_pdc202xx (struct pci_dev *dev, const char *name) { - unsigned long high_16 = dev->resource[4].start & PCI_BASE_ADDRESS_IO_MASK; + unsigned long high_16 = pci_resource_start(dev, 4); byte udma_speed_flag = inb(high_16 + 0x001f); byte primary_mode = inb(high_16 + 0x001a); byte secondary_mode = inb(high_16 + 0x001b); - if (dev->device == PCI_DEVICE_ID_PROMISE_20262) { + if ((dev->device == PCI_DEVICE_ID_PROMISE_20262) || + (dev->device == PCI_DEVICE_ID_PROMISE_20267)) { int i = 0; /* * software reset - this is required because the bios @@ -646,7 +725,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) { + if ((irq != irq2) && (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); } @@ -705,8 +784,12 @@ unsigned int __init ata66_pdc202xx (ide_hwif_t *hwif) void __init ide_init_pdc202xx (ide_hwif_t *hwif) { - hwif->tuneproc = &pdc202xx_tune_drive; - hwif->speedproc = &pdc202xx_tune_chipset; + hwif->tuneproc = &pdc202xx_tune_drive; + hwif->speedproc = &pdc202xx_tune_chipset; + + if ((hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20262) || + (hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20267)) + hwif->resetproc = &pdc202xx_reset; #ifdef CONFIG_BLK_DEV_IDEDMA if (hwif->dma_base) { |