static int ata_amd_setmode(device_t dev, int target, int mode) { device_t parent = device_get_parent(dev); struct ata_pci_controller *ctlr = device_get_softc(parent); struct ata_channel *ch = device_get_softc(dev); int devno = (ch->unit << 1) + target; int piomode; static const uint8_t timings[] = { 0xa8, 0x65, 0x42, 0x22, 0x20, 0xa8, 0x22, 0x20 }; static const uint8_t modes[] = { 0xc2, 0xc1, 0xc0, 0xc4, 0xc5, 0xc6, 0xc7 }; int reg = 0x53 - devno; mode = min(mode, ctlr->chip->max_dma); if (ctlr->chip->cfg1 & AMD_CABLE) { if (ata_dma_check_80pin && mode > ATA_UDMA2 && !(pci_read_config(parent, 0x42, 1) & (1 << devno))) { ata_print_cable(dev, "controller"); mode = ATA_UDMA2; } } /* Set UDMA timings. */ if (mode >= ATA_UDMA0) { pci_write_config(parent, reg, modes[mode & ATA_MODE_MASK], 1); piomode = ATA_PIO4; } else { pci_write_config(parent, reg, 0x8b, 1); piomode = mode; } /* Set WDMA/PIO timings. */ pci_write_config(parent, reg - 0x08, timings[ata_mode2idx(piomode)], 1); return (mode); }
static int ata_highpoint_check_80pin(device_t dev, int mode) { device_t parent = device_get_parent(dev); struct ata_pci_controller *ctlr = device_get_softc(parent); struct ata_channel *ch = device_get_softc(dev); u_int8_t reg, val, res; if (ctlr->chip->cfg1 == HPT_374 && pci_get_function(parent) == 1) { reg = ch->unit ? 0x57 : 0x53; val = pci_read_config(parent, reg, 1); pci_write_config(parent, reg, val | 0x80, 1); } else { reg = 0x5b; val = pci_read_config(parent, reg, 1); pci_write_config(parent, reg, val & 0xfe, 1); } res = pci_read_config(parent, 0x5a, 1) & (ch->unit ? 0x1:0x2); pci_write_config(parent, reg, val, 1); if (ata_dma_check_80pin && mode > ATA_UDMA2 && res) { ata_print_cable(dev, "controller"); mode = ATA_UDMA2; } return mode; }
int ata_check_80pin(device_t dev, int mode) { struct ata_device *atadev = device_get_softc(dev); if (mode > ATA_UDMA2 && !(atadev->param.hwres & ATA_CABLE_ID)) { ata_print_cable(dev, "device"); mode = ATA_UDMA2; } return mode; }
static int ata_ali_setmode(device_t dev, int target, int mode) { device_t parent = device_get_parent(dev); struct ata_pci_controller *ctlr = device_get_softc(parent); struct ata_channel *ch = device_get_softc(dev); int devno = (ch->unit << 1) + target; int piomode; static const uint32_t piotimings[] = { 0x006d0003, 0x00580002, 0x00440001, 0x00330001, 0x00310001, 0x006d0003, 0x00330001, 0x00310001 }; static const uint8_t udma[] = {0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x0f, 0x0d}; uint32_t word54; mode = min(mode, ctlr->chip->max_dma); if (ctlr->chip->cfg2 & ALI_NEW && ctlr->chip->chiprev < 0xc7) { if (ata_dma_check_80pin && mode > ATA_UDMA2 && pci_read_config(parent, 0x4a, 1) & (1 << ch->unit)) { ata_print_cable(dev, "controller"); mode = ATA_UDMA2; } } if (ctlr->chip->cfg2 & ALI_OLD) { /* doesn't support ATAPI DMA on write */ ch->flags |= ATA_ATAPI_DMA_RO; if (ch->devices & ATA_ATAPI_MASTER && ch->devices & ATA_ATAPI_SLAVE) { /* doesn't support ATAPI DMA on two ATAPI devices */ device_printf(dev, "two atapi devices on this channel," " no DMA\n"); mode = min(mode, ATA_PIO_MAX); } } /* Set UDMA mode */ word54 = pci_read_config(parent, 0x54, 4); if (mode >= ATA_UDMA0) { word54 &= ~(0x000f000f << (devno << 2)); word54 |= (((udma[mode&ATA_MODE_MASK]<<16)|0x05)<<(devno<<2)); piomode = ATA_PIO4; } else { word54 &= ~(0x0008000f << (devno << 2)); piomode = mode; } pci_write_config(parent, 0x54, word54, 4); /* Set PIO/WDMA mode */ pci_write_config(parent, 0x58 + (ch->unit << 2), piotimings[ata_mode2idx(piomode)], 4); return (mode); }
static int ata_sii_setmode(device_t dev, int target, int mode) { device_t parent = device_get_parent(dev); struct ata_pci_controller *ctlr = device_get_softc(parent); struct ata_channel *ch = device_get_softc(dev); int rego = (ch->unit << 4) + (target << 1); int mreg = ch->unit ? 0x84 : 0x80; int mask = 0x03 << (target << 2); int mval = pci_read_config(parent, mreg, 1) & ~mask; int piomode; u_int8_t preg = 0xa4 + rego; u_int8_t dreg = 0xa8 + rego; u_int8_t ureg = 0xac + rego; static const uint16_t piotimings[] = { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 }; static const uint16_t dmatimings[] = { 0x2208, 0x10c2, 0x10c1 }; static const uint8_t udmatimings[] = { 0xf, 0xb, 0x7, 0x5, 0x3, 0x2, 0x1 }; mode = min(mode, ctlr->chip->max_dma); if (ctlr->chip->cfg2 & SII_SETCLK) { if (ata_dma_check_80pin && mode > ATA_UDMA2 && (pci_read_config(parent, 0x79, 1) & (ch->unit ? 0x02 : 0x01))) { ata_print_cable(dev, "controller"); mode = ATA_UDMA2; } } if (mode >= ATA_UDMA0) { pci_write_config(parent, mreg, mval | (0x03 << (target << 2)), 1); pci_write_config(parent, ureg, (pci_read_config(parent, ureg, 1) & ~0x3f) | udmatimings[mode & ATA_MODE_MASK], 1); piomode = ATA_PIO4; } else if (mode >= ATA_WDMA0) { pci_write_config(parent, mreg, mval | (0x02 << (target << 2)), 1); pci_write_config(parent, dreg, dmatimings[mode & ATA_MODE_MASK], 2); piomode = (mode == ATA_WDMA0) ? ATA_PIO0 : (mode == ATA_WDMA1) ? ATA_PIO3 : ATA_PIO4; } else { pci_write_config(parent, mreg, mval | (0x01 << (target << 2)), 1); piomode = mode; } pci_write_config(parent, preg, piotimings[ata_mode2idx(piomode)], 2); return (mode); }
static int ata_jmicron_setmode(device_t dev, int target, int mode) { struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); mode = min(mode, ctlr->chip->max_dma); /* check for 80pin cable present */ if (ata_dma_check_80pin && mode > ATA_UDMA2 && pci_read_config(dev, 0x40, 1) & 0x08) { ata_print_cable(dev, "controller"); mode = ATA_UDMA2; } /* Nothing to do to setup mode, the controller snoop SET_FEATURE cmd. */ return (mode); }
static void ata_amd_setmode(device_t dev, int mode) { device_t gparent = GRANDPARENT(dev); struct ata_pci_controller *ctlr = device_get_softc(gparent); struct ata_channel *ch = device_get_softc(device_get_parent(dev)); struct ata_device *atadev = device_get_softc(dev); u_int8_t timings[] = { 0xa8, 0x65, 0x42, 0x22, 0x20, 0x42, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }; int modes[7] = { 0xc2, 0xc1, 0xc0, 0xc4, 0xc5, 0xc6, 0xc7 }; int devno = (ch->unit << 1) + atadev->unit; int reg = 0x53 - devno; int error; mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma); if (ctlr->chip->cfg1 & AMD_CABLE) { if (mode > ATA_UDMA2 && !(pci_read_config(gparent, 0x42, 1) & (1 << devno))) { ata_print_cable(dev, "controller"); mode = ATA_UDMA2; } } else mode = ata_check_80pin(dev, mode); error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode); if (bootverbose) device_printf(dev, "%ssetting %s on %s chip\n", (error) ? "FAILURE " : "", ata_mode2str(mode), ctlr->chip->text); if (!error) { pci_write_config(gparent, reg - 0x08, timings[ata_mode2idx(mode)], 1); if (mode >= ATA_UDMA0) pci_write_config(gparent, reg, modes[mode & ATA_MODE_MASK], 1); else pci_write_config(gparent, reg, 0x8b, 1); atadev->mode = mode; } }
static int ata_sis_setmode(device_t dev, int target, int mode) { device_t parent = device_get_parent(dev); struct ata_pci_controller *ctlr = device_get_softc(parent); struct ata_channel *ch = device_get_softc(dev); int devno = (ch->unit << 1) + target; mode = min(mode, ctlr->chip->max_dma); if (ctlr->chip->cfg1 == SIS_133NEW) { if (ata_dma_check_80pin && mode > ATA_UDMA2 && pci_read_config(parent, ch->unit ? 0x52 : 0x50,2) & 0x8000) { ata_print_cable(dev, "controller"); mode = ATA_UDMA2; } } else { if (ata_dma_check_80pin && mode > ATA_UDMA2 && pci_read_config(parent, 0x48, 1)&(ch->unit ? 0x20 : 0x10)) { ata_print_cable(dev, "controller"); mode = ATA_UDMA2; } } switch (ctlr->chip->cfg1) { case SIS_133NEW: { static const uint32_t timings[] = { 0x28269008, 0x0c266008, 0x04263008, 0x0c0a3008, 0x05093008, 0x22196008, 0x0c0a3008, 0x05093008, 0x050939fc, 0x050936ac, 0x0509347c, 0x0509325c, 0x0509323c, 0x0509322c, 0x0509321c }; u_int32_t reg; reg = (pci_read_config(parent, 0x57, 1)&0x40?0x70:0x40)+(devno<<2); pci_write_config(parent, reg, timings[ata_mode2idx(mode)], 4); break; } case SIS_133OLD: { static const uint16_t timings[] = { 0x00cb, 0x0067, 0x0044, 0x0033, 0x0031, 0x0044, 0x0033, 0x0031, 0x8f31, 0x8a31, 0x8731, 0x8531, 0x8331, 0x8231, 0x8131 }; u_int16_t reg = 0x40 + (devno << 1); pci_write_config(parent, reg, timings[ata_mode2idx(mode)], 2); break; } case SIS_100NEW: { static const uint16_t timings[] = { 0x00cb, 0x0067, 0x0044, 0x0033, 0x0031, 0x0044, 0x0033, 0x0031, 0x8b31, 0x8731, 0x8531, 0x8431, 0x8231, 0x8131 }; u_int16_t reg = 0x40 + (devno << 1); pci_write_config(parent, reg, timings[ata_mode2idx(mode)], 2); break; } case SIS_100OLD: case SIS_66: case SIS_33: { static const uint16_t timings[] = { 0x0c0b, 0x0607, 0x0404, 0x0303, 0x0301, 0x0404, 0x0303, 0x0301, 0xf301, 0xd301, 0xb301, 0xa301, 0x9301, 0x8301 }; u_int16_t reg = 0x40 + (devno << 1); pci_write_config(parent, reg, timings[ata_mode2idx(mode)], 2); break; } } return (mode); }