Example #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);
}
static int
ata_cmd_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 treg = 0x54 + ((devno < 3) ? (devno << 1) : 7);
	int ureg = ch->unit ? 0x7b : 0x73;
	int piomode;
	static const uint8_t piotimings[] =
	    { 0xa9, 0x57, 0x44, 0x32, 0x3f, 0x87, 0x32, 0x3f };
	static const uint8_t udmatimings[][2] =
	    { { 0x31,  0xc2 }, { 0x21,  0x82 }, { 0x11,  0x42 },
	      { 0x25,  0x8a }, { 0x15,  0x4a }, { 0x05,  0x0a } };

	mode = min(mode, ctlr->chip->max_dma);
	if (mode >= ATA_UDMA0) {        
		u_int8_t umode = pci_read_config(parent, ureg, 1);

	        umode &= ~(target == 0 ? 0x35 : 0xca);
		umode |= udmatimings[mode & ATA_MODE_MASK][target];
		pci_write_config(parent, ureg, umode, 1);
		piomode = ATA_PIO4;
	} else { 
		pci_write_config(parent, ureg, 
			     pci_read_config(parent, ureg, 1) &
			     ~(target == 0 ? 0x35 : 0xca), 1);
		piomode = mode;
	}
	pci_write_config(parent, treg, piotimings[ata_mode2idx(piomode)], 1);
	return (mode);
}
Example #3
0
static int
ata_nvidia_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 = 0x63 - devno;

	mode = min(mode, ctlr->chip->max_dma);

	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;
	}
	pci_write_config(parent, reg - 0x08, timings[ata_mode2idx(piomode)], 1);
	return (mode);
}
Example #4
0
static int
ata_national_setmode(device_t dev, int target, int mode)
{
	device_t parent = device_get_parent(dev);
	struct ata_channel *ch = device_get_softc(dev);
	int devno = (ch->unit << 1) + target;
	int piomode;
	static const uint32_t piotiming[] =
	    { 0x9172d132, 0x21717121, 0x00803020, 0x20102010, 0x00100010,
	      0x9172d132, 0x20102010, 0x00100010 };
	static const uint32_t dmatiming[] =
	    { 0x80077771, 0x80012121, 0x80002020 };
	static const uint32_t udmatiming[] =
	    { 0x80921250, 0x80911140, 0x80911030 };

	mode = min(mode, ATA_UDMA2);

	if (mode >= ATA_UDMA0) {
	    pci_write_config(parent, 0x44 + (devno << 3),
			     udmatiming[mode & ATA_MODE_MASK], 4);
	    piomode = ATA_PIO4;
	} else if (mode >= ATA_WDMA0) {
	    pci_write_config(parent, 0x44 + (devno << 3),
			     dmatiming[mode & ATA_MODE_MASK], 4);
	    piomode = mode;
	} else {
	    pci_write_config(parent, 0x44 + (devno << 3),
			     pci_read_config(parent, 0x44 + (devno << 3), 4) |
			     0x80000000, 4);
	    piomode = mode;
	}
	pci_write_config(parent, 0x40 + (devno << 3),
			 piotiming[ata_mode2idx(piomode)], 4);
	return (mode);
}
Example #5
0
static int
ata_via_old_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 reg = 0x53 - devno;
	int piomode;
	static const uint8_t timings[] =
	    { 0xa8, 0x65, 0x42, 0x22, 0x20, 0xa8, 0x22, 0x20 };
	static const uint8_t modes[][7] = {
	    { 0xc2, 0xc1, 0xc0, 0x00, 0x00, 0x00, 0x00 },   /* VIA ATA33 */
	    { 0xee, 0xec, 0xea, 0xe9, 0xe8, 0x00, 0x00 },   /* VIA ATA66 */
	    { 0xf7, 0xf6, 0xf4, 0xf2, 0xf1, 0xf0, 0x00 },   /* VIA ATA100 */
	    { 0xf7, 0xf7, 0xf6, 0xf4, 0xf2, 0xf1, 0xf0 } }; /* VIA ATA133 */

	mode = min(mode, ctlr->chip->max_dma);
	/* Set UDMA timings */
	if (mode >= ATA_UDMA0) {
	    pci_write_config(parent, reg,
			     modes[ctlr->chip->cfg1][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);
}
Example #6
0
static int
ata_via_new_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);

	if ((ctlr->chip->cfg2 & VIABAR) && (ch->unit > 1)) {
	    int piomode;
    	    static const uint8_t pio_timings[] =
		{ 0xa8, 0x65, 0x65, 0x32, 0x20 };
	    static const uint8_t dma_timings[] =
		{ 0xee, 0xe8, 0xe6, 0xe4, 0xe2, 0xe1, 0xe0 };

	    /* This chip can't do WDMA. */
	    if (mode >= ATA_WDMA0 && mode < ATA_UDMA0)
		mode = ATA_PIO4;
	    if (mode >= ATA_UDMA0) {
		pci_write_config(parent, 0xb3,
				 dma_timings[mode & ATA_MODE_MASK], 1);
		piomode = ATA_PIO4;
	    } else
		piomode = mode;
	    pci_write_config(parent, 0xab, pio_timings[ata_mode2idx(piomode)], 1);
	} else
		mode = ata_sata_setmode(dev, target, mode);
	return (mode);
}
Example #7
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);
}
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 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;
    }
}
Example #10
0
static int
ata_highpoint_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;
	static const uint32_t timings33[][4] = {
	/*    HPT366      HPT370      HPT372      HPT374           mode */
	{ 0x40d0a7aa, 0x06914e57, 0x0d029d5e, 0x0ac1f48a },     /* PIO 0 */
	{ 0x40d0a7a3, 0x06914e43, 0x0d029d26, 0x0ac1f465 },     /* PIO 1 */
	{ 0x40d0a753, 0x06514e33, 0x0c829ca6, 0x0a81f454 },     /* PIO 2 */
	{ 0x40c8a742, 0x06514e22, 0x0c829c84, 0x0a81f443 },     /* PIO 3 */
	{ 0x40c8a731, 0x06514e21, 0x0c829c62, 0x0a81f442 },     /* PIO 4 */
	{ 0x20c8a797, 0x26514e97, 0x2c82922e, 0x228082ea },     /* MWDMA 0 */
	{ 0x20c8a732, 0x26514e33, 0x2c829266, 0x22808254 },     /* MWDMA 1 */
	{ 0x20c8a731, 0x26514e21, 0x2c829262, 0x22808242 },     /* MWDMA 2 */
	{ 0x10c8a731, 0x16514e31, 0x1c829c62, 0x121882ea },     /* UDMA 0 */
	{ 0x10cba731, 0x164d4e31, 0x1c9a9c62, 0x12148254 },     /* UDMA 1 */
	{ 0x10caa731, 0x16494e31, 0x1c929c62, 0x120c8242 },     /* UDMA 2 */
	{ 0x10cfa731, 0x166d4e31, 0x1c8e9c62, 0x128c8242 },     /* UDMA 3 */
	{ 0x10c9a731, 0x16454e31, 0x1c8a9c62, 0x12ac8242 },     /* UDMA 4 */
	{ 0,          0x16454e31, 0x1c8a9c62, 0x12848242 },     /* UDMA 5 */
	{ 0,          0,          0x1c869c62, 0x12808242 }      /* UDMA 6 */
	};

	mode = min(mode, ctlr->chip->max_dma);
	mode = ata_highpoint_check_80pin(dev, mode);
	/*
	 * most if not all HPT chips cant really handle that the device is
	 * running at ATA_UDMA6/ATA133 speed, so we cheat at set the device to
         * a max of ATA_UDMA5/ATA100 to guard against suboptimal performance
	 */
	mode = min(mode, ATA_UDMA5);
	pci_write_config(parent, 0x40 + (devno << 2),
			 timings33[ata_mode2idx(mode)][ctlr->chip->cfg1], 4);
	return (mode);
}
Example #11
0
static int
ata_cyrix_setmode(device_t dev, int target, int mode)
{
	struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
	struct ata_channel *ch = device_get_softc(dev);
	int devno = (ch->unit << 1) + target;
	int piomode;
	static const uint32_t piotiming[] = 
	    { 0x00009172, 0x00012171, 0x00020080, 0x00032010, 0x00040010 };
	static const uint32_t dmatiming[] =
	    { 0x00077771, 0x00012121, 0x00002020 };
	static const uint32_t udmatiming[] =
	    { 0x00921250, 0x00911140, 0x00911030 };

	mode = min(mode, ATA_UDMA2);
	/* dont try to set the mode if we dont have the resource */
	if (ctlr->r_res1) {
		if (mode >= ATA_UDMA0) {
			/* Set UDMA timings, and PIO4. */
			ATA_OUTL(ch->r_io[ATA_BMCMD_PORT].res,
			    0x24 + (devno << 3), udmatiming[mode & ATA_MODE_MASK]);
			piomode = ATA_PIO4;
		} else if (mode >= ATA_WDMA0) {
			/* Set WDMA timings, and respective PIO mode. */
			ATA_OUTL(ch->r_io[ATA_BMCMD_PORT].res,
			    0x24 + (devno << 3), dmatiming[mode & ATA_MODE_MASK]);
		        piomode = (mode == ATA_WDMA0) ? ATA_PIO0 :
			    (mode == ATA_WDMA1) ? ATA_PIO3 : ATA_PIO4;
		} else
			piomode = mode;
		/* Set PIO mode calculated above. */
		ATA_OUTL(ch->r_io[ATA_BMCMD_PORT].res,
		    0x20 + (devno << 3), piotiming[ata_mode2idx(piomode)]);
	}
	return (mode);
}
Example #12
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);
}
Example #13
0
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;
    }
}
Example #14
0
/*
 ****************************************************************
 *	Inicializa o DMA para os Controladores PATA		*
 ****************************************************************
 */
void
ata_sis_pata_setmode (PCIDATA *pci, ATA_DEVICE *adp, int mode)
{
 	ATA_PCI_CTLR		*ctlrp = pci->pci_dev_info_ptr;
	const ATA_CHIP_ID	*idp = ctlrp->ac_idp;
	int			devno;

	devno = (adp->ad_channel->ch_unit << 1) + adp->ad_devno;

	mode  = ata_limit_mode (adp, mode, idp->ch_max_dma);

	if (idp->ch_cfg1 == SIS133NEW)
	{
		if (mode > ATA_UDMA2 && pci_read (pci, adp->ad_channel->ch_unit ? 0x52 : 0x50, 2) & 0x8000)
		{
			mode = ATA_UDMA2;
			printf ("ata[%d,%d]: DMA limitado a %s\n", ATA_DEVNO, ata_dmamode_to_str (mode));
		}
	}
	else
	{
		if (mode > ATA_UDMA2 &&	pci_read (pci, 0x48, 1) & (adp->ad_channel->ch_unit ? 0x20 : 0x10))
		{
			mode = ATA_UDMA2;
			printf ("ata[%d,%d]: DMA limitado a %s\n", ATA_DEVNO, ata_dmamode_to_str (mode));
		}
	}

	if (ata_command (adp, ATA_C_SETFEATURES, 0, mode, ATA_C_F_SETXFER, 0))
		return;

	switch (idp->ch_cfg1)
	{
	    case SIS133NEW:
	    {
		ulong timings[] = 
		{
			0x28269008, 0x0c266008, 0x04263008, 0x0c0a3008, 0x05093008,
			0x22196008, 0x0c0a3008, 0x05093008, 0x050939fc, 0x050936ac,
			0x0509347c, 0x0509325c, 0x0509323c, 0x0509322c, 0x0509321c
		};
		ulong reg;

		reg = (pci_read (pci, 0x57, 1) & 0x40?0x70 : 0x40) + (devno << 2);

		pci_write (pci, reg, timings[ata_mode2idx (mode)], 4);
		break;
	    }

	    case SIS133OLD:
	    {
		ushort timings[] =
		{
			0x00cb, 0x0067, 0x0044, 0x0033, 0x0031, 0x0044, 0x0033, 0x0031,
		 	0x8f31, 0x8a31, 0x8731, 0x8531, 0x8331, 0x8231, 0x8131
		};
		ushort reg = 0x40 + (devno << 1);

		pci_write (pci, reg, timings[ata_mode2idx (mode)], 2);
		break;
	    }

	    case SIS100NEW:
	    {
		ushort timings[] =
		{
			0x00cb, 0x0067, 0x0044, 0x0033, 0x0031, 0x0044, 0x0033,
			0x0031, 0x8b31, 0x8731, 0x8531, 0x8431, 0x8231, 0x8131
		};
		ushort reg = 0x40 + (devno << 1);

		pci_write (pci, reg, timings[ata_mode2idx (mode)], 2);
		break;
	    }

	    case SIS100OLD:
	    case SIS66:
	    case SIS33:
	    {
		ushort timings[] =
		{
			0x0c0b, 0x0607, 0x0404, 0x0303, 0x0301, 0x0404, 0x0303,
			0x0301, 0xf301, 0xd301, 0xb301, 0xa301, 0x9301, 0x8301
		};
		ushort reg = 0x40 + (devno << 1);

		pci_write (pci, reg, timings[ata_mode2idx (mode)], 2);
		break;
	    }
	}

	adp->ad_transfer_mode = mode;

}	/* end ata_sis_pata_setmode */