static void ata_micron_setmode(device_t dev, int mode) { struct ata_device *atadev = device_get_softc(dev); mode = ata_limit_mode(dev, mode, ATA_UDMA2); mode = ata_check_80pin(dev, mode); if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode)) atadev->mode = 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 void ata_ati_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); int devno = (ch->unit << 1) + atadev->unit; int offset = (devno ^ 0x01) << 3; int error; int piomode; static const uint8_t piotimings[] = { 0x5d, 0x47, 0x34, 0x22, 0x20, 0x34, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }; static const uint8_t dmatimings[] = { 0x77, 0x21, 0x20 }; mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma); 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) { if (mode >= ATA_UDMA0) { /* Set UDMA mode, enable UDMA, set WDMA2/PIO4 */ pci_write_config(gparent, 0x56, (pci_read_config(gparent, 0x56, 2) & ~(0xf << (devno << 2))) | ((mode & ATA_MODE_MASK) << (devno << 2)), 2); pci_write_config(gparent, 0x54, pci_read_config(gparent, 0x54, 1) | (0x01 << devno), 1); pci_write_config(gparent, 0x44, (pci_read_config(gparent, 0x44, 4) & ~(0xff << offset)) | (dmatimings[2] << offset), 4); piomode = ATA_PIO4; } else if (mode >= ATA_WDMA0) { /* Disable UDMA, set WDMA mode and timings, calculate PIO. */ pci_write_config(gparent, 0x54, pci_read_config(gparent, 0x54, 1) & ~(0x01 << devno), 1); pci_write_config(gparent, 0x44, (pci_read_config(gparent, 0x44, 4) & ~(0xff << offset)) | (dmatimings[mode & ATA_MODE_MASK] << offset), 4); piomode = (mode == ATA_WDMA0) ? ATA_PIO0 : (mode == ATA_WDMA1) ? ATA_PIO3 : ATA_PIO4; } else { /* Disable UDMA, set requested PIO. */ pci_write_config(gparent, 0x54, pci_read_config(gparent, 0x54, 1) & ~(0x01 << devno), 1); piomode = mode; } /* Set PIO mode and timings, calculated above. */ pci_write_config(gparent, 0x4a, (pci_read_config(gparent, 0x4a, 2) & ~(0xf << (devno << 2))) | ((piomode - ATA_PIO0) << (devno<<2)),2); pci_write_config(gparent, 0x40, (pci_read_config(gparent, 0x40, 4) & ~(0xff << offset)) | (piotimings[ata_mode2idx(piomode)] << offset), 4); atadev->mode = mode; } }