📄 pdc202xx.c
字号:
pci_read_config_byte(dev, (drive_pci), &AP); pci_read_config_byte(dev, (drive_pci)|0x01, &BP); } } pci_read_config_byte(dev, (drive_pci), &AP); pci_read_config_byte(dev, (drive_pci)|0x01, &BP); pci_read_config_byte(dev, (drive_pci)|0x02, &CP); for ( i = 0; i < 2; i++) if (hwif->drives[i].present) id[i+j] = hwif->drives[i].id; /* get identify structs */ switch(speed) {#ifdef CONFIG_BLK_DEV_IDEDMA /* case XFER_UDMA_6: */ 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 */ case XFER_UDMA_1: TB = 0x40; TC = 0x02; break; /* speed 5 == UDMA mode 1 */ case XFER_UDMA_0: TB = 0x60; TC = 0x03; break; /* speed 4 == UDMA mode 0 */ case XFER_MW_DMA_2: TB = 0x60; TC = 0x03; break; /* speed 4 == MDMA mode 2 */ case XFER_MW_DMA_1: TB = 0x60; TC = 0x04; break; /* speed 3 == MDMA mode 1 */ case XFER_MW_DMA_0: TB = 0x60; TC = 0x05; break; /* speed 2 == MDMA mode 0 */ case XFER_SW_DMA_2: TB = 0x60; TC = 0x05; break; /* speed 0 == SDMA mode 2 */ case XFER_SW_DMA_1: TB = 0x80; TC = 0x06; break; /* speed 1 == SDMA mode 1 */ case XFER_SW_DMA_0: TB = 0xC0; TC = 0x0B; break; /* speed 0 == SDMA mode 0 */#endif /* CONFIG_BLK_DEV_IDEDMA */ case XFER_PIO_4: TA = 0x01; TB = 0x04; break; case XFER_PIO_3: TA = 0x02; TB = 0x06; break; case XFER_PIO_2: TA = 0x03; TB = 0x08; break; case XFER_PIO_1: TA = 0x05; TB = 0x0C; break; case XFER_PIO_0: default: TA = 0x09; TB = 0x13; break; }#ifdef CONFIG_BLK_DEV_IDEDMA if (speed >= XFER_SW_DMA_0) { pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB); pci_write_config_byte(dev, (drive_pci)|0x02, CP|TC); } else {#else {#endif /* CONFIG_BLK_DEV_IDEDMA */ pci_write_config_byte(dev, (drive_pci), AP|TA); pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB); }#if PDC202XX_DECODE_REGISTER_INFO pci_read_config_byte(dev, (drive_pci), &AP); pci_read_config_byte(dev, (drive_pci)|0x01, &BP); pci_read_config_byte(dev, (drive_pci)|0x02, &CP); pci_read_config_byte(dev, (drive_pci)|0x03, &DP); decode_registers(REG_A, AP); decode_registers(REG_B, BP); decode_registers(REG_C, CP); decode_registers(REG_D, DP);#endif /* PDC202XX_DECODE_REGISTER_INFO */ if (!drive->init_speed) drive->init_speed = speed; err = ide_config_drive_speed(drive, speed); drive->current_speed = speed;#if PDC202XX_DEBUG_DRIVE_INFO printk("%s: %s drive%d 0x%08x ", drive->name, ide_xfer_verbose(speed), drive->dn, drive_conf); pci_read_config_dword(dev, drive_pci, &drive_conf); printk("0x%08x\n", drive_conf);#endif /* PDC202XX_DEBUG_DRIVE_INFO */ return err;}static int pdc202xx_new_tune_chipset (ide_drive_t *drive, byte speed){ ide_hwif_t *hwif = HWIF(drive);#ifdef CONFIG_BLK_DEV_IDEDMA unsigned long indexreg = (hwif->dma_base + 1); unsigned long datareg = (hwif->dma_base + 3);#else struct pci_dev *dev = hwif->pci_dev; unsigned long high_16 = pci_resource_start(dev, 4); unsigned long indexreg = high_16 + (hwif->channel ? 0x09 : 0x01); unsigned long datareg = (indexreg + 2);#endif /* CONFIG_BLK_DEV_IDEDMA */ byte thold = 0x10; byte adj = (drive->dn%2) ? 0x08 : 0x00; int set_speed = 0, i=0, j=hwif->channel ? 2:0; int err; /* Setting tHOLD bit to 0 if using UDMA mode 2 */ if (speed == XFER_UDMA_2) { OUT_BYTE((thold + adj), indexreg); OUT_BYTE((IN_BYTE(datareg) & 0x7f), datareg); } /* We need to set ATA133 timing if ATA133 drives exist */ if (speed>=XFER_UDMA_6) set_speed=1; if (!drive->init_speed) drive->init_speed = speed;#if PDC202XX_DEBUG_DRIVE_INFO printk("%s: Before set_feature = %s, word88 = %#x\n", drive->name, ide_xfer_verbose(speed), drive->id->dma_ultra );#endif /* PDC202XX_DEBUG_DRIVE_INFO */ err = ide_config_drive_speed(drive, speed); drive->current_speed = speed; for ( i = 0 ; i < 2 ; i++) if (hwif->drives[i].present) { id[i+j] = hwif->drives[i].id; /* get identify structs */ speed_rate[i+j] = speed; /* get current speed */ } if (set_speed) { for (i=0; i<4; i++) { if (id[i]==NULL) continue; switch(speed_rate[i]) {#ifdef CONFIG_BLK_DEV_IDEDMA case XFER_UDMA_6: OUT_BYTE((0x10 + adj), indexreg); OUT_BYTE(0x1a, datareg); OUT_BYTE((0x11 + adj), indexreg); OUT_BYTE(0x01, datareg); OUT_BYTE((0x12 + adj), indexreg); OUT_BYTE(0xcb, datareg); break; case XFER_UDMA_5: OUT_BYTE((0x10 + adj), indexreg); OUT_BYTE(0x1a, datareg); OUT_BYTE((0x11 + adj), indexreg); OUT_BYTE(0x02, datareg); OUT_BYTE((0x12 + adj), indexreg); OUT_BYTE(0xcb, datareg); break; case XFER_UDMA_4: OUT_BYTE((0x10 + adj), indexreg); OUT_BYTE(0x1a, datareg); OUT_BYTE((0x11 + adj), indexreg); OUT_BYTE(0x03, datareg); OUT_BYTE((0x12 + adj), indexreg); OUT_BYTE(0xcd, datareg); break; case XFER_UDMA_3: OUT_BYTE((0x10 + adj), indexreg); OUT_BYTE(0x1a, datareg); OUT_BYTE((0x11 + adj), indexreg); OUT_BYTE(0x05, datareg); OUT_BYTE((0x12 + adj), indexreg); OUT_BYTE(0xcd, datareg); break; case XFER_UDMA_2: OUT_BYTE((0x10 + adj), indexreg); OUT_BYTE(0x2a, datareg); OUT_BYTE((0x11 + adj), indexreg); OUT_BYTE(0x07, datareg); OUT_BYTE((0x12 + adj), indexreg); OUT_BYTE(0xcd, datareg); break; case XFER_UDMA_1: OUT_BYTE((0x10 + adj), indexreg); OUT_BYTE(0x3a, datareg); OUT_BYTE((0x11 + adj), indexreg); OUT_BYTE(0x0a, datareg); OUT_BYTE((0x12 + adj), indexreg); OUT_BYTE(0xd0, datareg); break; case XFER_UDMA_0: OUT_BYTE((0x10 + adj), indexreg); OUT_BYTE(0x4a, datareg); OUT_BYTE((0x11 + adj), indexreg); OUT_BYTE(0x0f, datareg); OUT_BYTE((0x12 + adj), indexreg); OUT_BYTE(0xd5, datareg); break; case XFER_MW_DMA_2: OUT_BYTE((0x0e + adj), indexreg); OUT_BYTE(0x69, datareg); OUT_BYTE((0x0f + adj), indexreg); OUT_BYTE(0x25, datareg); break; case XFER_MW_DMA_1: OUT_BYTE((0x0e + adj), indexreg); OUT_BYTE(0x6b, datareg); OUT_BYTE((0x0f+ adj), indexreg); OUT_BYTE(0x27, datareg); break; case XFER_MW_DMA_0: OUT_BYTE((0x0e + adj), indexreg); OUT_BYTE(0xdf, datareg); OUT_BYTE((0x0f + adj), indexreg); OUT_BYTE(0x5f, datareg); break;#endif /* CONFIG_BLK_DEV_IDEDMA */ case XFER_PIO_4: OUT_BYTE((0x0c + adj), indexreg); OUT_BYTE(0x23, datareg); OUT_BYTE((0x0d + adj), indexreg); OUT_BYTE(0x09, datareg); OUT_BYTE((0x13 + adj), indexreg); OUT_BYTE(0x25, datareg); break; case XFER_PIO_3: OUT_BYTE((0x0c + adj), indexreg); OUT_BYTE(0x27, datareg); OUT_BYTE((0x0d + adj), indexreg); OUT_BYTE(0x0d, datareg); OUT_BYTE((0x13 + adj), indexreg); OUT_BYTE(0x35, datareg); break; case XFER_PIO_2: OUT_BYTE((0x0c + adj), indexreg); OUT_BYTE(0x23, datareg); OUT_BYTE((0x0d + adj), indexreg); OUT_BYTE(0x26, datareg); OUT_BYTE((0x13 + adj), indexreg); OUT_BYTE(0x64, datareg); break; case XFER_PIO_1: OUT_BYTE((0x0c + adj), indexreg); OUT_BYTE(0x46, datareg); OUT_BYTE((0x0d + adj), indexreg); OUT_BYTE(0x29, datareg); OUT_BYTE((0x13 + adj), indexreg); OUT_BYTE(0xa4, datareg); break; case XFER_PIO_0: OUT_BYTE((0x0c + adj), indexreg); OUT_BYTE(0xfb, datareg); OUT_BYTE((0x0d + adj), indexreg); OUT_BYTE(0x2b, datareg); OUT_BYTE((0x13 + adj), indexreg); OUT_BYTE(0xac, datareg); break; default: } } } return err;}/* 0 1 2 3 4 5 6 7 8 * 960, 480, 390, 300, 240, 180, 120, 90, 60 * 180, 150, 120, 90, 60 * DMA_Speed * 180, 120, 90, 90, 90, 60, 30 * 11, 5, 4, 3, 2, 1, 0 */static int config_chipset_for_pio (ide_drive_t *drive, byte pio){ byte speed = 0x00; pio = (pio == 5) ? 4 : pio; speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, pio, NULL); return ((int) pdc202xx_tune_chipset(drive, speed));}static void pdc202xx_tune_drive (ide_drive_t *drive, byte pio){ (void) config_chipset_for_pio(drive, pio);}#ifdef CONFIG_BLK_DEV_IDEDMAstatic 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 = pci_resource_start(dev, 4); unsigned long dma_base = hwif->dma_base; unsigned long indexreg = dma_base + 1; unsigned long datareg = dma_base + 3; byte iordy = 0x13; byte adj = (drive->dn%2) ? 0x08 : 0x00; byte cable = 0; byte new_chip = 0; byte unit = (drive->select.b.unit & 0x01); unsigned int drive_conf; byte drive_pci = 0; byte test1, test2, speed = -1; byte AP; unsigned short EP; byte CLKSPD = 0; byte clockreg = high_16 + 0x11; byte udma_33 = ultra; byte udma_66 = ((eighty_ninty_three(drive)) && udma_33) ? 1 : 0; byte udma_100 = 0; byte udma_133 = 0; 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_100 = ((id->dma_ultra & 0x0020) || (ultra_66)) ? 1 : 0; byte ultra_133 = ((id->dma_ultra & 0x0040) || (ultra_100)) ? 1 : 0; switch(dev->device) { case PCI_DEVICE_ID_PROMISE_20276: case PCI_DEVICE_ID_PROMISE_20275: case PCI_DEVICE_ID_PROMISE_20269: udma_133 = (udma_66) ? 1 : 0; udma_100 = (udma_66) ? 1 : 0; OUT_BYTE(0x0b, (hwif->dma_base + 1)); cable = ((IN_BYTE((hwif->dma_base + 3)) & 0x04)); new_chip = 1; break; case PCI_DEVICE_ID_PROMISE_20268: case PCI_DEVICE_ID_PROMISE_20270: udma_100 = (udma_66) ? 1 : 0; OUT_BYTE(0x0b, (hwif->dma_base + 1)); cable = ((IN_BYTE((hwif->dma_base + 3)) & 0x04)); new_chip = 1; break; case PCI_DEVICE_ID_PROMISE_20267: case PCI_DEVICE_ID_PROMISE_20265: udma_100 = (udma_66) ? 1 : 0; pci_read_config_word(dev, 0x50, &EP); cable = (EP & c_mask); new_chip = 0; CLKSPD = IN_BYTE(clockreg); break; case PCI_DEVICE_ID_PROMISE_20262: pci_read_config_word(dev, 0x50, &EP); cable = (EP & c_mask); new_chip = 0; CLKSPD = IN_BYTE(clockreg); break; default: udma_100 = 0; udma_133 = 0; cable = 0; new_chip = 1; break; } /* * Set the control register to use the 66Mhz system * clock for UDMA 3/4 mode operation. If one drive on * a channel is U66 capable but the other isn't we * fall back to U33 mode. The BIOS INT 13 hooks turn * the clock on then off for each read/write issued. I don't * do that here because it would require modifying the * kernel, seperating the fop routines from the kernel or * somehow hooking the fops calls. It may also be possible to * leave the 66Mhz clock on and readjust the timing * parameters. */ if (((ultra_66) || (ultra_100) || (ultra_133)) && (cable)) {#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");#endif /* DEBUG */ /* Primary : zero out second bit */ /* Secondary : zero out fourth bit */ //if (!new_chip) OUT_BYTE(CLKSPD & ~mask, clockreg); printk("Warning: %s channel requires an 80-pin cable for operation.\n", hwif->channel ? "Secondary":"Primary"); printk("%s reduced to Ultra33 mode.\n", drive->name); udma_66 = 0; udma_100 = 0; udma_133 = 0; } else { if ((ultra_66) || (ultra_100) || (ultra_133)) { /* * 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 & 0x0040) || (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, clockreg); } else { OUT_BYTE(CLKSPD & ~mask, clockreg); } } else { /* udma4 drive by itself */ OUT_BYTE(CLKSPD | mask, clockreg); } } } if (new_chip) goto chipset_is_set; switch(drive->dn) { case 0: drive_pci = 0x60; pci_read_config_dword(dev, drive_pci, &drive_conf); if ((drive_conf != 0x004ff304) && (drive_conf != 0x004ff3c4)) goto chipset_is_set; pci_read_config_byte(dev, (drive_pci), &test1); if (!(test1 & SYNC_ERRDY_EN)) pci_write_config_byte(dev, (drive_pci), test1|SYNC_ERRDY_EN); break; case 1: drive_pci = 0x64;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -