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 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 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)); }
/* * We only deal with PIO mode here - DMA mode 'using_dma' is not * initialised at the point that this function is called. */ static void tune_sl82c105(ide_drive_t *drive, byte pio) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; ide_pio_data_t p; unsigned short drv_ctrl = 0x909; unsigned int xfer_mode, reg; reg = (hwif->channel ? 0x4c : 0x44) + (drive->select.b.unit ? 4 : 0); pio = ide_get_best_pio_mode(drive, pio, 5, &p); switch (pio) { default: case 0: xfer_mode = XFER_PIO_0; break; case 1: xfer_mode = XFER_PIO_1; break; case 2: xfer_mode = XFER_PIO_2; break; case 3: xfer_mode = XFER_PIO_3; break; case 4: xfer_mode = XFER_PIO_4; break; } if (ide_config_drive_speed(drive, xfer_mode) == 0) drv_ctrl = get_timing_sl82c105(&p); pci_write_config_word(dev, reg, drv_ctrl); pci_read_config_word(dev, reg, &drv_ctrl); printk("%s: selected %s (%dns) (%04X)\n", drive->name, ide_xfer_verbose(xfer_mode), p.cycle_time, drv_ctrl); }
static int cs5520_tune_chipset(ide_drive_t *drive, u8 xferspeed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *pdev = hwif->pci_dev; u8 speed = min((u8)XFER_PIO_4, xferspeed); int pio = speed; u8 reg; int controller = drive->dn > 1 ? 1 : 0; int error; switch(speed) { case XFER_PIO_4: case XFER_PIO_3: case XFER_PIO_2: case XFER_PIO_1: case XFER_PIO_0: pio -= XFER_PIO_0; break; default: pio = 0; printk(KERN_ERR "cs55x0: bad ide timing.\n"); } printk("PIO clocking = %d\n", pio); /* FIXME: if DMA = 1 do we need to set the DMA bit here ? */ /* 8bit CAT/CRT - 8bit command timing for channel */ pci_write_config_byte(pdev, 0x62 + controller, (cs5520_pio_clocks[pio].recovery << 4) | (cs5520_pio_clocks[pio].assert)); /* 0x64 - 16bit Primary, 0x68 - 16bit Secondary */ /* FIXME: should these use address ? */ /* Data read timing */ pci_write_config_byte(pdev, 0x64 + 4*controller + (drive->dn&1), (cs5520_pio_clocks[pio].recovery << 4) | (cs5520_pio_clocks[pio].assert)); /* Write command timing */ pci_write_config_byte(pdev, 0x66 + 4*controller + (drive->dn&1), (cs5520_pio_clocks[pio].recovery << 4) | (cs5520_pio_clocks[pio].assert)); /* Set the DMA enable/disable flag */ reg = inb(hwif->dma_base + 0x02 + 8*controller); reg |= 1<<((drive->dn&1)+5); outb(reg, hwif->dma_base + 0x02 + 8*controller); error = ide_config_drive_speed(drive, speed); /* ATAPI is harder so leave it for now */ if(!error && drive->media == ide_disk) error = hwif->ide_dma_on(drive); return error; }
static int sgiioc4_ide_dma_check(ide_drive_t *drive) { /* FIXME: check for available DMA modes */ if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) { printk(KERN_WARNING "%s: couldn't set MWDMA2 mode, " "using PIO instead\n", drive->name); return -1; } else return 0; }
static void config_cmd64x_chipset_for_pio (ide_drive_t *drive, u8 set_speed) { u8 speed = 0x00; u8 set_pio = ide_get_best_pio_mode(drive, 4, 5, NULL); cmd64x_tuneproc(drive, set_pio); speed = XFER_PIO_0 + set_pio; if (set_speed) (void) 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 redwood_ide_tune_chipset (ide_drive_t *drive, byte speed) { int err=0; redwood_ide_tune_drive(drive, redwood_ide_dma_2_pio(speed)); if (!drive->init_speed) drive->init_speed = speed; err = ide_config_drive_speed(drive, speed); drive->current_speed = speed; return err; }
static int sgiioc4_ide_dma_check(ide_drive_t * drive) { if (ide_config_drive_speed(drive,XFER_MW_DMA_2)!=0) { printk(KERN_INFO "Couldnot set %s in Multimode-2 DMA mode | Drive %s using PIO instead\n", drive->name, drive->name); drive->using_dma = 0; } else drive->using_dma = 1; return 0; }
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 void config_siimage_chipset_for_pio (ide_drive_t *drive, byte set_speed) { u8 channel_timings = siimage_taskfile_timing(HWIF(drive)); u8 speed = 0, set_pio = ide_get_best_pio_mode(drive, 4, 5, NULL); /* WARNING PIO timing mess is going to happen b/w devices, argh */ if ((channel_timings != set_pio) && (set_pio > channel_timings)) set_pio = channel_timings; siimage_tuneproc(drive, set_pio); speed = XFER_PIO_0 + set_pio; if (set_speed) (void) 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 void palm_bk3710_tune_drive(ide_drive_t *drive, u8 pio) { ide_pio_data_t piodata; int is_slave = drive->dn & 1; ide_drive_t *mate; void __iomem *base = (void *)drive->hwif->dma_base; /* * Obtain the drive PIO data for tuning the Palm Chip registers */ pio = ide_get_best_pio_mode(drive, pio, 4, &piodata); mate = ide_get_paired_drive(drive); palm_bk3710_setpiomode(base, mate, is_slave, piodata.cycle_time, pio); (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio); }
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 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 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)); }
static int pdc202xx_tune_chipset (ide_drive_t *drive, byte speed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; unsigned int drive_conf; int err; byte drive_pci, AP, BP, CP, DP; byte TA = 0, TB = 0, TC = 0; switch (drive->dn) { case 0: drive_pci = 0x60; break; case 1: drive_pci = 0x64; break; case 2: drive_pci = 0x68; break; case 3: drive_pci = 0x6c; break; default: return -1; } if ((drive->media != ide_disk) && (speed < XFER_SW_DMA_0)) return -1; pci_read_config_dword(dev, drive_pci, &drive_conf); 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); #ifdef CONFIG_BLK_DEV_IDEDMA if (speed >= XFER_SW_DMA_0) { if ((BP & 0xF0) && (CP & 0x0F)) { /* clear DMA modes of upper 842 bits of B Register */ /* clear PIO forced mode upper 1 bit of B Register */ pci_write_config_byte(dev, (drive_pci)|0x01, BP & ~0xF0); pci_read_config_byte(dev, (drive_pci)|0x01, &BP); /* clear DMA modes of lower 8421 bits of C Register */ pci_write_config_byte(dev, (drive_pci)|0x02, CP & ~0x0F); pci_read_config_byte(dev, (drive_pci)|0x02, &CP); } } else { #else { #endif /* CONFIG_BLK_DEV_IDEDMA */ if ((AP & 0x0F) || (BP & 0x07)) { /* clear PIO modes of lower 8421 bits of A Register */ pci_write_config_byte(dev, (drive_pci), AP & ~0x0F); pci_read_config_byte(dev, (drive_pci), &AP); /* clear PIO modes of lower 421 bits of B Register */ pci_write_config_byte(dev, (drive_pci)|0x01, BP & ~0x07); 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), &AP); pci_read_config_byte(dev, (drive_pci)|0x01, &BP); pci_read_config_byte(dev, (drive_pci)|0x02, &CP); 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 */ 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 */ err = ide_config_drive_speed(drive, 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; } /* 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); }
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 void slc90e66_tune_drive (ide_drive_t *drive, u8 pio) { pio = ide_get_best_pio_mode(drive, pio, 4, NULL); slc90e66_tune_pio(drive, pio); (void) ide_config_drive_speed(drive, XFER_PIO_0 + pio); }
static int ps2_ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); struct ps2_dmatable *t = (struct ps2_dmatable *)hwif->dmatable; struct ata_dma_request *req = &t->ata_dma_request; int ret; #if !defined(GATHER_WRITE_DATA) ps2sif_dmadata_t *sdd; int cnt, i; #endif /* !GATHER_WRITE_DATA */ DPRINT("ps2_ide_dmaproc: %s\n", procfunc[func]); switch (func) { case ide_dma_off: printk("%s: DMA disabled\n", drive->name); case ide_dma_off_quietly: case ide_dma_on: drive->using_dma = (func == ide_dma_on); return 0; case ide_dma_check: /* only ide-disk DMA works... */ drive->using_dma = hwif->autodma && drive->media == ide_disk; /* TODO: always UltraDMA mode 4 */ if (drive->using_dma) { int ide_config_drive_speed (ide_drive_t *drive, byte speed); ide_config_drive_speed(drive, XFER_UDMA_4); } return 0; case ide_dma_read: #ifdef NO_DMA_READ return 1; #endif if (drive->media != ide_disk) return 0; if (!ps2_ide_build_dmatable(0, drive)) return 1; /* try PIO instead of DMA */ req->command = WIN_READDMA; req->devctrl = drive->ctl; drive->waiting_for_dma = 1; ide_set_handler(drive, &ide_dma_intr, WAIT_CMD); /* set nIEN for disable ATA interrupt */ /* (ATA interrupt is enabled in RPC handler) */ OUT_BYTE(drive->ctl|2, hwif->io_ports[IDE_CONTROL_OFFSET]); flush_cache_all(); do { ret = ps2sif_callrpc(&t->cd_ata, SIFNUM_DmaRead, SIF_RPCM_NOWAIT, (void *)req, sizeof(int) * 4 + sizeof(ps2sif_dmadata_t) * req->count, NULL, 0, NULL, NULL); switch (ret) { case 0: break; case -SIF_RPCE_SENDP: break; default: /* restore nIEN */ OUT_BYTE(drive->ctl, hwif->io_ports[IDE_CONTROL_OFFSET]); printk("ps2_ide_dmaproc(read): callrpc failed, result=%d\n", ret); drive->waiting_for_dma = 0; return 1; } } while (ret < 0); return 0; case ide_dma_write: #ifdef NO_DMA_WRITE return 1; #endif if (drive->media != ide_disk) return 0; if (!ps2_ide_build_dmatable(1, drive)) return 1; /* try PIO instead of DMA */ req->command = WIN_WRITEDMA; drive->waiting_for_dma = 1; ide_set_handler(drive, &ide_dma_intr, WAIT_CMD); flush_cache_all(); #if !defined(GATHER_WRITE_DATA) sdd = req->sdd; for (cnt = 0; cnt < req->count; cnt++) { while (ps2sif_setdma(sdd, 1) == 0) { i = 0x010000; while (i--) ; } sdd++; } #else /* GATHER_WRITE_DATA */ req->sdd[0].data = t->dma_buffer; req->sdd[0].addr = t->ata_iop_buffer; req->sdd[0].size = req->size; req->sdd[0].mode = 0; while (ps2sif_setdma(req->sdd, 1) == 0) { i = 0x010000; while (i--) ; } #endif do { ret = ps2sif_callrpc(&t->cd_ata, SIFNUM_DmaWrite, SIF_RPCM_NOWAIT, (void *)req, sizeof(int) * 4, NULL, 0, NULL, NULL); switch (ret) { case 0: break; case -SIF_RPCE_SENDP: break; default: printk("ps2_ide_dmaproc(write): callrpc failed, result=%d\n", ret); drive->waiting_for_dma = 0; return 1; } } while (ret < 0); return 0; case ide_dma_begin: /* TODO */ return 0; case ide_dma_end: /* returns 1 on error, 0 otherwise */ /* disable DMA transfer */ *SPD_R_XFR_CTRL = 0; *SPD_R_IF_CTRL = *SPD_R_IF_CTRL & ~IFC_DMA_EN; /* force break DMA */ if (!(*SPD_R_INTR_STAT & 0x0001)) { unsigned char if_ctrl; if_ctrl = *SPD_R_IF_CTRL; *SPD_R_IF_CTRL = IFC_ATA_RST; udelay(100); *SPD_R_IF_CTRL = if_ctrl; do { ret = ps2sif_callrpc(&t->cd_ata_end, 0, SIF_RPCM_NOWAIT, NULL, 0, NULL, 0, NULL, NULL); switch (ret) { case 0: break; case -SIF_RPCE_SENDP: break; default: printk("ps2_ide_dmaproc(end): callrpc failed, result=%d\n", ret); break; } } while (ret == -SIF_RPCE_SENDP); } drive->waiting_for_dma = 0; return 0; case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */ return (*SPD_R_INTR_STAT & 0x0001) ? 1 : 0; default: printk("ps2_ide_dmaproc: unsupported func: %d\n", func); return 1; } }
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 cs5530_set_xfer_mode (ide_drive_t *drive, u8 mode) { printk(KERN_DEBUG "%s: cs5530_set_xfer_mode(%s)\n", drive->name, ide_xfer_verbose(mode)); return (ide_config_drive_speed(drive, mode)); }
static void jmicron_tuneproc(ide_drive_t *drive, u8 pio) { pio = ide_get_best_pio_mode(drive, pio, 5); ide_config_drive_speed(drive, XFER_PIO_0 + pio); }
static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) { ide_startstop_t startstop; BUG_ON(!blk_rq_started(rq)); #ifdef DEBUG printk("%s: start_request: current=0x%08lx\n", drive->hwif->name, (unsigned long) rq); #endif /* bail early if we've exceeded max_failures */ if (drive->max_failures && (drive->failures > drive->max_failures)) { rq->cmd_flags |= REQ_FAILED; goto kill_rq; } if (blk_pm_request(rq)) ide_check_pm_state(drive, rq); SELECT_DRIVE(drive); if (ide_wait_stat(&startstop, drive, drive->ready_stat, ATA_BUSY | ATA_DRQ, WAIT_READY)) { printk(KERN_ERR "%s: drive not ready for command\n", drive->name); return startstop; } if (!drive->special.all) { struct ide_driver *drv; /* * We reset the drive so we need to issue a SETFEATURES. * Do it _after_ do_special() restored device parameters. */ if (drive->current_speed == 0xff) ide_config_drive_speed(drive, drive->desired_speed); if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) return execute_drive_cmd(drive, rq); else if (blk_pm_request(rq)) { struct request_pm_state *pm = rq->data; #ifdef DEBUG_PM printk("%s: start_power_step(step: %d)\n", drive->name, pm->pm_step); #endif startstop = ide_start_power_step(drive, rq); if (startstop == ide_stopped && pm->pm_step == IDE_PM_COMPLETED) ide_complete_pm_request(drive, rq); return startstop; } else if (!rq->rq_disk && blk_special_request(rq)) /* * TODO: Once all ULDs have been modified to * check for specific op codes rather than * blindly accepting any special request, the * check for ->rq_disk above may be replaced * by a more suitable mechanism or even * dropped entirely. */ return ide_special_rq(drive, rq); drv = *(struct ide_driver **)rq->rq_disk->private_data; return drv->do_request(drive, rq, rq->sector); } return do_special(drive); kill_rq: ide_kill_rq(drive, rq); return ide_stopped; }
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 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 void it8213_tuneproc(ide_drive_t *drive, u8 pio) { pio = ide_get_best_pio_mode(drive, pio, 4); it8213_tune_pio(drive, pio); ide_config_drive_speed(drive, XFER_PIO_0 + pio); }