Пример #1
0
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);
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
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);
}
Пример #5
0
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);
}
Пример #6
0
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);
}
Пример #7
0
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;
    }
}
Пример #8
0
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);
}