static int hpt34x_tune_chipset (ide_drive_t *drive, u8 xferspeed) { struct pci_dev *dev = HWIF(drive)->pci_dev; u8 speed = ide_rate_filter(drive, xferspeed); u32 reg1= 0, tmp1 = 0, reg2 = 0, tmp2 = 0; u8 hi_speed, lo_speed; hi_speed = speed >> 4; lo_speed = speed & 0x0f; if (hi_speed & 7) { hi_speed = (hi_speed & 4) ? 0x01 : 0x10; } else { lo_speed <<= 5; lo_speed >>= 5; } pci_read_config_dword(dev, 0x44, ®1); pci_read_config_dword(dev, 0x48, ®2); tmp1 = ((lo_speed << (3*drive->dn)) | (reg1 & ~(7 << (3*drive->dn)))); tmp2 = ((hi_speed << drive->dn) | (reg2 & ~(0x11 << drive->dn))); pci_write_config_dword(dev, 0x44, tmp1); pci_write_config_dword(dev, 0x48, tmp2); #if HPT343_DEBUG_DRIVE_INFO printk("%s: %s drive%d (0x%04x 0x%04x) (0x%04x 0x%04x)" \ " (0x%02x 0x%02x)\n", drive->name, ide_xfer_verbose(speed), drive->dn, reg1, tmp1, reg2, tmp2, hi_speed, lo_speed); #endif /* HPT343_DEBUG_DRIVE_INFO */ return(ide_config_drive_speed(drive, speed)); }
static int aec6210_tune_chipset (ide_drive_t *drive, u8 xferspeed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; u16 d_conf = 0; u8 speed = ide_rate_filter(aec62xx_ratemask(drive), xferspeed); u8 ultra = 0, ultra_conf = 0; u8 tmp0 = 0, tmp1 = 0, tmp2 = 0; unsigned long flags; local_irq_save(flags); pci_read_config_word(dev, 0x40|(2*drive->dn), &d_conf); tmp0 = pci_bus_clock_list(speed, BUSCLOCK(dev)); SPLIT_BYTE(tmp0,tmp1,tmp2); MAKE_WORD(d_conf,tmp1,tmp2); pci_write_config_word(dev, 0x40|(2*drive->dn), d_conf); tmp1 = 0x00; tmp2 = 0x00; pci_read_config_byte(dev, 0x54, &ultra); tmp1 = ((0x00 << (2*drive->dn)) | (ultra & ~(3 << (2*drive->dn)))); ultra_conf = pci_bus_clock_list_ultra(speed, BUSCLOCK(dev)); tmp2 = ((ultra_conf << (2*drive->dn)) | (tmp1 & ~(3 << (2*drive->dn)))); pci_write_config_byte(dev, 0x54, tmp2); local_irq_restore(flags); return(ide_config_drive_speed(drive, speed)); }
static int tc86c001_tune_chipset(ide_drive_t *drive, u8 speed) { ide_hwif_t *hwif = HWIF(drive); unsigned long scr_port = hwif->config_data + (drive->dn ? 0x02 : 0x00); u16 mode, scr = hwif->INW(scr_port); speed = ide_rate_filter(tc86c001_ratemask(drive), speed); switch (speed) { case XFER_UDMA_4: mode = 0x00c0; break; case XFER_UDMA_3: mode = 0x00b0; break; case XFER_UDMA_2: mode = 0x00a0; break; case XFER_UDMA_1: mode = 0x0090; break; case XFER_UDMA_0: mode = 0x0080; break; case XFER_MW_DMA_2: mode = 0x0070; break; case XFER_MW_DMA_1: mode = 0x0060; break; case XFER_MW_DMA_0: mode = 0x0050; break; case XFER_PIO_4: mode = 0x0400; break; case XFER_PIO_3: mode = 0x0300; break; case XFER_PIO_2: mode = 0x0200; break; case XFER_PIO_1: mode = 0x0100; break; case XFER_PIO_0: default: mode = 0x0000; break; } scr &= (speed < XFER_MW_DMA_0) ? 0xf8ff : 0xff0f; scr |= mode; outw(scr, scr_port); return ide_config_drive_speed(drive, speed); }
static int slc90e66_tune_chipset (ide_drive_t *drive, u8 xferspeed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; u8 maslave = hwif->channel ? 0x42 : 0x40; u8 speed = ide_rate_filter(slc90e66_ratemask(drive), xferspeed); int sitre = 0, a_speed = 7 << (drive->dn * 4); int u_speed = 0, u_flag = 1 << drive->dn; u16 reg4042, reg44, reg48, reg4a; pci_read_config_word(dev, maslave, ®4042); sitre = (reg4042 & 0x4000) ? 1 : 0; pci_read_config_word(dev, 0x44, ®44); pci_read_config_word(dev, 0x48, ®48); pci_read_config_word(dev, 0x4a, ®4a); switch(speed) { #ifdef CONFIG_BLK_DEV_IDEDMA case XFER_UDMA_4: u_speed = 4 << (drive->dn * 4); break; case XFER_UDMA_3: u_speed = 3 << (drive->dn * 4); break; case XFER_UDMA_2: u_speed = 2 << (drive->dn * 4); break; case XFER_UDMA_1: u_speed = 1 << (drive->dn * 4); break; case XFER_UDMA_0: u_speed = 0 << (drive->dn * 4); break; case XFER_MW_DMA_2: case XFER_MW_DMA_1: case XFER_SW_DMA_2: break; #endif /* CONFIG_BLK_DEV_IDEDMA */ case XFER_PIO_4: case XFER_PIO_3: case XFER_PIO_2: case XFER_PIO_0: break; default: return -1; } if (speed >= XFER_UDMA_0) { if (!(reg48 & u_flag)) pci_write_config_word(dev, 0x48, reg48|u_flag); /* FIXME: (reg4a & a_speed) ? */ if ((reg4a & u_speed) != u_speed) { pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); pci_read_config_word(dev, 0x4a, ®4a); pci_write_config_word(dev, 0x4a, reg4a|u_speed); } } else { if (reg48 & u_flag) pci_write_config_word(dev, 0x48, reg48 & ~u_flag); if (reg4a & a_speed) pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); } slc90e66_tune_drive(drive, slc90e66_dma_2_pio(speed)); return (ide_config_drive_speed(drive, speed)); }
static int triflex_tune_chipset(ide_drive_t *drive, u8 xferspeed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; u8 channel_offset = hwif->channel ? 0x74 : 0x70; u16 timing = 0; u32 triflex_timings = 0; u8 unit = (drive->select.b.unit & 0x01); u8 speed = ide_rate_filter(0, xferspeed); pci_read_config_dword(dev, channel_offset, &triflex_timings); switch(speed) { case XFER_MW_DMA_2: timing = 0x0103; break; case XFER_MW_DMA_1: timing = 0x0203; break; case XFER_MW_DMA_0: timing = 0x0808; break; case XFER_SW_DMA_2: case XFER_SW_DMA_1: case XFER_SW_DMA_0: timing = 0x0f0f; break; case XFER_PIO_4: timing = 0x0202; break; case XFER_PIO_3: timing = 0x0204; break; case XFER_PIO_2: timing = 0x0404; break; case XFER_PIO_1: timing = 0x0508; break; case XFER_PIO_0: timing = 0x0808; break; default: return -1; } triflex_timings &= ~(0xFFFF << (16 * unit)); triflex_timings |= (timing << (16 * unit)); pci_write_config_dword(dev, channel_offset, triflex_timings); return (ide_config_drive_speed(drive, speed)); }
static int palm_bk3710_tune_chipset(ide_drive_t *drive, u8 speed) { int is_slave = drive->dn & 1; void __iomem *base = (void *)drive->hwif->dma_base; speed = ide_rate_filter(palm_bk3710_ratemask(drive), speed); if (speed >= XFER_UDMA_0) { palm_bk3710_setudmamode(base, is_slave, speed - XFER_UDMA_0); } else { palm_bk3710_setdmamode(base, is_slave, drive->id->eide_dma_min, speed); } return ide_config_drive_speed(drive, speed); }
static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed) { u8 udma_modes[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; u8 dma_modes[] = { 0x77, 0x21, 0x20 }; u8 pio_modes[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 }; u8 drive_pci[] = { 0x41, 0x40, 0x43, 0x42 }; u8 drive_pci2[] = { 0x45, 0x44, 0x47, 0x46 }; ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; u8 speed; u8 pio = ide_get_best_pio_mode(drive, 255, 5, NULL); u8 unit = (drive->select.b.unit & 0x01); u8 csb5 = svwks_csb_check(dev); u8 ultra_enable = 0, ultra_timing = 0; u8 dma_timing = 0, pio_timing = 0; u16 csb5_pio = 0; if (xferspeed == 255) /* PIO auto-tuning */ speed = XFER_PIO_0 + pio; else speed = ide_rate_filter(svwks_ratemask(drive), xferspeed); /* If we are about to put a disk into UDMA mode we screwed up. Our code assumes we never _ever_ do this on an OSB4 */ if(dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4 && drive->media == ide_disk && speed >= XFER_UDMA_0) BUG(); pci_read_config_byte(dev, drive_pci[drive->dn], &pio_timing); pci_read_config_byte(dev, drive_pci2[drive->dn], &dma_timing); pci_read_config_byte(dev, (0x56|hwif->channel), &ultra_timing); pci_read_config_word(dev, 0x4A, &csb5_pio); pci_read_config_byte(dev, 0x54, &ultra_enable); /* Per Specified Design by OEM, and ASIC Architect */ if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) || (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) { if (!drive->init_speed) { u8 dma_stat = hwif->INB(hwif->dma_status); dma_pio: if (((ultra_enable << (7-drive->dn) & 0x80) == 0x80) && ((dma_stat & (1<<(5+unit))) == (1<<(5+unit)))) { drive->current_speed = drive->init_speed = XFER_UDMA_0 + udma_modes[(ultra_timing >> (4*unit)) & ~(0xF0)]; return 0; } else if ((dma_timing) &&
static int pdcnew_new_tune_chipset (ide_drive_t *drive, u8 xferspeed) { ide_hwif_t *hwif = HWIF(drive); unsigned long indexreg = hwif->dma_vendor1; unsigned long datareg = hwif->dma_vendor3; u8 thold = 0x10; u8 adj = (drive->dn%2) ? 0x08 : 0x00; u8 speed = ide_rate_filter(pdcnew_ratemask(drive), xferspeed); if (speed == XFER_UDMA_2) { hwif->OUTB((thold + adj), indexreg); hwif->OUTB((hwif->INB(datareg) & 0x7f), datareg); } switch (speed) { case XFER_UDMA_7: speed = XFER_UDMA_6; case XFER_UDMA_6: set_ultra(0x1a, 0x01, 0xcb); break; case XFER_UDMA_5: set_ultra(0x1a, 0x02, 0xcb); break; case XFER_UDMA_4: set_ultra(0x1a, 0x03, 0xcd); break; case XFER_UDMA_3: set_ultra(0x1a, 0x05, 0xcd); break; case XFER_UDMA_2: set_ultra(0x2a, 0x07, 0xcd); break; case XFER_UDMA_1: set_ultra(0x3a, 0x0a, 0xd0); break; case XFER_UDMA_0: set_ultra(0x4a, 0x0f, 0xd5); break; case XFER_MW_DMA_2: set_ata2(0x69, 0x25); break; case XFER_MW_DMA_1: set_ata2(0x6b, 0x27); break; case XFER_MW_DMA_0: set_ata2(0xdf, 0x5f); break; case XFER_PIO_4: set_pio(0x23, 0x09, 0x25); break; case XFER_PIO_3: set_pio(0x27, 0x0d, 0x35); break; case XFER_PIO_2: set_pio(0x23, 0x26, 0x64); break; case XFER_PIO_1: set_pio(0x46, 0x29, 0xa4); break; case XFER_PIO_0: set_pio(0xfb, 0x2b, 0xac); break; default: ; } return (ide_config_drive_speed(drive, speed)); }
static int aec6260_tune_chipset (ide_drive_t *drive, u8 xferspeed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; u8 speed = ide_rate_filter(aec62xx_ratemask(drive), xferspeed); u8 unit = (drive->select.b.unit & 0x01); u8 tmp1 = 0, tmp2 = 0; u8 ultra = 0, drive_conf = 0, ultra_conf = 0; unsigned long flags; local_irq_save(flags); pci_read_config_byte(dev, 0x40|drive->dn, &drive_conf); drive_conf = pci_bus_clock_list(speed, BUSCLOCK(dev)); pci_write_config_byte(dev, 0x40|drive->dn, drive_conf); pci_read_config_byte(dev, (0x44|hwif->channel), &ultra); tmp1 = ((0x00 << (4*unit)) | (ultra & ~(7 << (4*unit)))); ultra_conf = pci_bus_clock_list_ultra(speed, BUSCLOCK(dev)); tmp2 = ((ultra_conf << (4*unit)) | (tmp1 & ~(7 << (4*unit)))); pci_write_config_byte(dev, (0x44|hwif->channel), tmp2); local_irq_restore(flags); return(ide_config_drive_speed(drive, speed)); }
static int pdcnew_tune_chipset(ide_drive_t *drive, u8 speed) { ide_hwif_t *hwif = HWIF(drive); u8 adj = (drive->dn & 1) ? 0x08 : 0x00; int err; speed = ide_rate_filter(pdcnew_ratemask(drive), speed); /* * Issue SETFEATURES_XFER to the drive first. PDC202xx hardware will * automatically set the timing registers based on 100 MHz PLL output. */ err = ide_config_drive_speed(drive, speed); /* * As we set up the PLL to output 133 MHz for UltraDMA/133 capable * chips, we must override the default register settings... */ if (max_dma_rate(hwif->pci_dev) == 4) { u8 mode = speed & 0x07; switch (speed) { case XFER_UDMA_6: case XFER_UDMA_5: case XFER_UDMA_4: case XFER_UDMA_3: case XFER_UDMA_2: case XFER_UDMA_1: case XFER_UDMA_0: set_indexed_reg(hwif, 0x10 + adj, udma_timings[mode].reg10); set_indexed_reg(hwif, 0x11 + adj, udma_timings[mode].reg11); set_indexed_reg(hwif, 0x12 + adj, udma_timings[mode].reg12); break; case XFER_MW_DMA_2: case XFER_MW_DMA_1: case XFER_MW_DMA_0: set_indexed_reg(hwif, 0x0e + adj, mwdma_timings[mode].reg0e); set_indexed_reg(hwif, 0x0f + adj, mwdma_timings[mode].reg0f); break; case XFER_PIO_4: case XFER_PIO_3: case XFER_PIO_2: case XFER_PIO_1: case XFER_PIO_0: set_indexed_reg(hwif, 0x0c + adj, pio_timings[mode].reg0c); set_indexed_reg(hwif, 0x0d + adj, pio_timings[mode].reg0d); set_indexed_reg(hwif, 0x13 + adj, pio_timings[mode].reg13); break; default: printk(KERN_ERR "pdc202xx_new: " "Unknown speed %d ignored\n", speed); } } else if (speed == XFER_UDMA_2) { /* Set tHOLD bit to 0 if using UDMA mode 2 */ u8 tmp = get_indexed_reg(hwif, 0x10 + adj); set_indexed_reg(hwif, 0x10 + adj, tmp & 0x7f); } return err; }
static int cmd64x_tune_chipset (ide_drive_t *drive, u8 xferspeed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; u8 unit = (drive->select.b.unit & 0x01); u8 regU = 0, pciU = (hwif->channel) ? UDIDETCR1 : UDIDETCR0; u8 regD = 0, pciD = (hwif->channel) ? BMIDESR1 : BMIDESR0; u8 speed = ide_rate_filter(cmd64x_ratemask(drive), xferspeed); if (speed > XFER_PIO_4) { (void) pci_read_config_byte(dev, pciD, ®D); (void) pci_read_config_byte(dev, pciU, ®U); regD &= ~(unit ? 0x40 : 0x20); regU &= ~(unit ? 0xCA : 0x35); (void) pci_write_config_byte(dev, pciD, regD); (void) pci_write_config_byte(dev, pciU, regU); (void) pci_read_config_byte(dev, pciD, ®D); (void) pci_read_config_byte(dev, pciU, ®U); } switch(speed) { case XFER_UDMA_5: regU |= (unit ? 0x0A : 0x05); break; case XFER_UDMA_4: regU |= (unit ? 0x4A : 0x15); break; case XFER_UDMA_3: regU |= (unit ? 0x8A : 0x25); break; case XFER_UDMA_2: regU |= (unit ? 0x42 : 0x11); break; case XFER_UDMA_1: regU |= (unit ? 0x82 : 0x21); break; case XFER_UDMA_0: regU |= (unit ? 0xC2 : 0x31); break; case XFER_MW_DMA_2: regD |= (unit ? 0x40 : 0x10); break; case XFER_MW_DMA_1: regD |= (unit ? 0x80 : 0x20); break; case XFER_MW_DMA_0: regD |= (unit ? 0xC0 : 0x30); break; case XFER_SW_DMA_2: regD |= (unit ? 0x40 : 0x10); break; case XFER_SW_DMA_1: regD |= (unit ? 0x80 : 0x20); break; case XFER_SW_DMA_0: regD |= (unit ? 0xC0 : 0x30); break; case XFER_PIO_4: cmd64x_tuneproc(drive, 4); break; case XFER_PIO_3: cmd64x_tuneproc(drive, 3); break; case XFER_PIO_2: cmd64x_tuneproc(drive, 2); break; case XFER_PIO_1: cmd64x_tuneproc(drive, 1); break; case XFER_PIO_0: cmd64x_tuneproc(drive, 0); break; default: return 1; } if (speed > XFER_PIO_4) { (void) pci_write_config_byte(dev, pciU, regU); regD |= (unit ? 0x40 : 0x20); (void) pci_write_config_byte(dev, pciD, regD); } return (ide_config_drive_speed(drive, speed)); }
static int piix_tune_chipset (ide_drive_t *drive, u8 xferspeed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; u8 maslave = hwif->channel ? 0x42 : 0x40; u8 speed = ide_rate_filter(piix_ratemask(drive), xferspeed); int a_speed = 3 << (drive->dn * 4); int u_flag = 1 << drive->dn; int v_flag = 0x01 << drive->dn; int w_flag = 0x10 << drive->dn; int u_speed = 0; int sitre; u16 reg4042, reg4a; u8 reg48, reg54, reg55; pci_read_config_word(dev, maslave, ®4042); sitre = (reg4042 & 0x4000) ? 1 : 0; pci_read_config_byte(dev, 0x48, ®48); pci_read_config_word(dev, 0x4a, ®4a); pci_read_config_byte(dev, 0x54, ®54); pci_read_config_byte(dev, 0x55, ®55); switch(speed) { case XFER_UDMA_4: case XFER_UDMA_2: u_speed = 2 << (drive->dn * 4); break; case XFER_UDMA_5: case XFER_UDMA_3: case XFER_UDMA_1: u_speed = 1 << (drive->dn * 4); break; case XFER_UDMA_0: u_speed = 0 << (drive->dn * 4); break; case XFER_MW_DMA_2: case XFER_MW_DMA_1: case XFER_SW_DMA_2: break; case XFER_PIO_4: case XFER_PIO_3: case XFER_PIO_2: case XFER_PIO_0: break; default: return -1; } if (speed >= XFER_UDMA_0) { if (!(reg48 & u_flag)) pci_write_config_byte(dev, 0x48, reg48 | u_flag); if (speed == XFER_UDMA_5) { pci_write_config_byte(dev, 0x55, (u8) reg55|w_flag); } else { pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag); } if ((reg4a & a_speed) != u_speed) pci_write_config_word(dev, 0x4a, (reg4a & ~a_speed) | u_speed); if (speed > XFER_UDMA_2) { if (!(reg54 & v_flag)) pci_write_config_byte(dev, 0x54, reg54 | v_flag); } else pci_write_config_byte(dev, 0x54, reg54 & ~v_flag); } else { if (reg48 & u_flag) pci_write_config_byte(dev, 0x48, reg48 & ~u_flag); if (reg4a & a_speed) pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); if (reg54 & v_flag) pci_write_config_byte(dev, 0x54, reg54 & ~v_flag); if (reg55 & w_flag) pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag); } piix_tune_drive(drive, piix_dma_2_pio(speed)); return (ide_config_drive_speed(drive, speed)); }
static int siimage_tune_chipset (ide_drive_t *drive, byte xferspeed) { u8 ultra6[] = { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 }; u8 ultra5[] = { 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01 }; u16 dma[] = { 0x2208, 0x10C2, 0x10C1 }; ide_hwif_t *hwif = HWIF(drive); u16 ultra = 0, multi = 0; u8 mode = 0, unit = drive->select.b.unit; u8 speed = ide_rate_filter(siimage_ratemask(drive), xferspeed); unsigned long base = (unsigned long)hwif->hwif_data; u8 scsc = 0, addr_mask = ((hwif->channel) ? ((hwif->mmio) ? 0xF4 : 0x84) : ((hwif->mmio) ? 0xB4 : 0x80)); unsigned long ma = siimage_seldev(drive, 0x08); unsigned long ua = siimage_seldev(drive, 0x0C); if (hwif->mmio) { scsc = hwif->INB(base + 0x4A); mode = hwif->INB(base + addr_mask); multi = hwif->INW(ma); ultra = hwif->INW(ua); } else { pci_read_config_byte(hwif->pci_dev, 0x8A, &scsc); pci_read_config_byte(hwif->pci_dev, addr_mask, &mode); pci_read_config_word(hwif->pci_dev, ma, &multi); pci_read_config_word(hwif->pci_dev, ua, &ultra); } mode &= ~((unit) ? 0x30 : 0x03); ultra &= ~0x3F; scsc = ((scsc & 0x30) == 0x00) ? 0 : 1; scsc = is_sata(hwif) ? 1 : scsc; switch(speed) { case XFER_PIO_4: case XFER_PIO_3: case XFER_PIO_2: case XFER_PIO_1: case XFER_PIO_0: siimage_tuneproc(drive, (speed - XFER_PIO_0)); mode |= ((unit) ? 0x10 : 0x01); break; case XFER_MW_DMA_2: case XFER_MW_DMA_1: case XFER_MW_DMA_0: multi = dma[speed - XFER_MW_DMA_0]; mode |= ((unit) ? 0x20 : 0x02); config_siimage_chipset_for_pio(drive, 0); break; case XFER_UDMA_6: case XFER_UDMA_5: case XFER_UDMA_4: case XFER_UDMA_3: case XFER_UDMA_2: case XFER_UDMA_1: case XFER_UDMA_0: multi = dma[2]; ultra |= ((scsc) ? (ultra6[speed - XFER_UDMA_0]) : (ultra5[speed - XFER_UDMA_0])); mode |= ((unit) ? 0x30 : 0x03); config_siimage_chipset_for_pio(drive, 0); break; default: return 1; } if (hwif->mmio) { hwif->OUTB(mode, base + addr_mask); hwif->OUTW(multi, ma); hwif->OUTW(ultra, ua); } else { pci_write_config_byte(hwif->pci_dev, addr_mask, mode); pci_write_config_word(hwif->pci_dev, ma, multi); pci_write_config_word(hwif->pci_dev, ua, ultra); } return (ide_config_drive_speed(drive, speed)); }
static int jmicron_tune_chipset (ide_drive_t *drive, byte xferspeed) { u8 speed = ide_rate_filter(drive, xferspeed); return ide_config_drive_speed(drive, speed); }
static int siimage_tune_chipset (ide_drive_t *drive, byte xferspeed) { u8 ultra6[] = { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 }; u8 ultra5[] = { 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01 }; u16 dma[] = { 0x2208, 0x10C2, 0x10C1 }; ide_hwif_t *hwif = HWIF(drive); u16 ultra = 0, multi = 0; u8 mode = 0, unit = drive->select.b.unit; u8 speed = ide_rate_filter(siimage_ratemask(drive), xferspeed); u8 scsc = 0, addr_mask = ((hwif->channel) ? ((hwif->mmio) ? 0xF4 : 0x84) : ((hwif->mmio) ? 0xB4 : 0x80)); if (hwif->mmio) { scsc = hwif->INB(HWIFADDR(0x4A)); mode = hwif->INB(HWIFADDR(addr_mask)); multi = hwif->INW(SELADDR(0x08|(unit<<unit))); ultra = hwif->INW(SELADDR(0x0C|(unit<<unit))); } else { pci_read_config_byte(hwif->pci_dev, 0x8A, &scsc); pci_read_config_byte(hwif->pci_dev, addr_mask, &mode); pci_read_config_word(hwif->pci_dev, SELREG(0x08|(unit<<unit)), &multi); pci_read_config_word(hwif->pci_dev, SELREG(0x0C|(unit<<unit)), &ultra); } mode &= ~((unit) ? 0x30 : 0x03); ultra &= ~0x3F; scsc = ((scsc & 0x30) == 0x00) ? 0 : 1; scsc = (hwif->pci_dev->device == PCI_DEVICE_ID_SII_3112) ? 1 : scsc; switch(speed) { case XFER_PIO_4: case XFER_PIO_3: case XFER_PIO_2: case XFER_PIO_1: case XFER_PIO_0: siimage_tuneproc(drive, (speed - XFER_PIO_0)); mode |= ((unit) ? 0x10 : 0x01); break; case XFER_MW_DMA_2: case XFER_MW_DMA_1: case XFER_MW_DMA_0: multi = dma[speed - XFER_MW_DMA_0]; mode |= ((unit) ? 0x20 : 0x02); config_siimage_chipset_for_pio(drive, 0); break; case XFER_UDMA_6: case XFER_UDMA_5: case XFER_UDMA_4: case XFER_UDMA_3: case XFER_UDMA_2: case XFER_UDMA_1: case XFER_UDMA_0: multi = dma[2]; ultra |= ((scsc) ? (ultra6[speed - XFER_UDMA_0]) : (ultra5[speed - XFER_UDMA_0])); mode |= ((unit) ? 0x30 : 0x03); config_siimage_chipset_for_pio(drive, 0); break; default: return 1; } if (hwif->mmio) { hwif->OUTB(mode, HWIFADDR(addr_mask)); hwif->OUTW(multi, SELADDR(0x08|(unit<<unit))); hwif->OUTW(ultra, SELADDR(0x0C|(unit<<unit))); } else { pci_write_config_byte(hwif->pci_dev, addr_mask, mode); pci_write_config_word(hwif->pci_dev, SELREG(0x08|(unit<<unit)), multi); pci_write_config_word(hwif->pci_dev, SELREG(0x0C|(unit<<unit)), ultra); } return (ide_config_drive_speed(drive, speed)); }