示例#1
0
文件: siimage.c 项目: Tigrouzen/k1099
static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
    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);
    struct pci_dev *dev	= to_pci_dev(hwif->dev);
    u16 ultra = 0, multi	= 0;
    u8 mode = 0, unit	= drive->select.b.unit;
    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(dev, 0x8A, &scsc);
        pci_read_config_byte(dev, addr_mask, &mode);
        pci_read_config_word(dev, ma, &multi);
        pci_read_config_word(dev, ua, &ultra);
    }

    mode &= ~((unit) ? 0x30 : 0x03);
    ultra &= ~0x3F;
    scsc = ((scsc & 0x30) == 0x00) ? 0 : 1;

    scsc = is_sata(hwif) ? 1 : scsc;

    if (speed >= XFER_UDMA_0) {
        multi = dma[2];
        ultra |= (scsc ? ultra6[speed - XFER_UDMA_0] :
                  ultra5[speed - XFER_UDMA_0]);
        mode |= (unit ? 0x30 : 0x03);
    } else {
        multi = dma[speed - XFER_MW_DMA_0];
        mode |= (unit ? 0x20 : 0x02);
    }

    if (hwif->mmio) {
        hwif->OUTB(mode, base + addr_mask);
        hwif->OUTW(multi, ma);
        hwif->OUTW(ultra, ua);
    } else {
        pci_write_config_byte(dev, addr_mask, mode);
        pci_write_config_word(dev, ma, multi);
        pci_write_config_word(dev, ua, ultra);
    }
}
static void sil_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
	static const u8 ultra6[] = { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 };
	static const u8 ultra5[] = { 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01 };
	static const u16 dma[]	 = { 0x2208, 0x10C2, 0x10C1 };

	struct pci_dev *dev	= to_pci_dev(hwif->dev);
	unsigned long base	= (unsigned long)hwif->hwif_data;
	u16 ultra = 0, multi	= 0;
	u8 mode = 0, unit	= drive->dn & 1;
	u8 mmio			= (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
	u8 scsc = 0, addr_mask	= hwif->channel ? (mmio ? 0xF4 : 0x84)
						: (mmio ? 0xB4 : 0x80);
	unsigned long ma	= siimage_seldev(drive, 0x08);
	unsigned long ua	= siimage_seldev(drive, 0x0C);
	const u8 speed		= drive->dma_mode;

	scsc  = sil_ioread8 (dev, base + (mmio ? 0x4A : 0x8A));
	mode  = sil_ioread8 (dev, base + addr_mask);
	multi = sil_ioread16(dev, ma);
	ultra = sil_ioread16(dev, ua);

	mode  &= ~(unit ? 0x30 : 0x03);
	ultra &= ~0x3F;
	scsc = ((scsc & 0x30) == 0x00) ? 0 : 1;

	scsc = is_sata(hwif) ? 1 : scsc;

	if (speed >= XFER_UDMA_0) {
		multi  = dma[2];
		ultra |= scsc ? ultra6[speed - XFER_UDMA_0] :
				ultra5[speed - XFER_UDMA_0];
		mode  |= unit ? 0x30 : 0x03;
	} else {
		multi = dma[speed - XFER_MW_DMA_0];
		mode |= unit ? 0x20 : 0x02;
	}

	sil_iowrite8 (dev, mode, base + addr_mask);
	sil_iowrite16(dev, multi, ma);
	sil_iowrite16(dev, ultra, ua);
}
示例#3
0
static void siimage_tuneproc (ide_drive_t *drive, byte mode_wanted)
{
	ide_hwif_t *hwif	= HWIF(drive);
	u32 speedt		= 0;
	u16 speedp		= 0;
	unsigned long addr	= siimage_seldev(drive, 0x04);
	unsigned long tfaddr	= siimage_selreg(hwif, 0x02);
	
	/* cheat for now and use the docs */
	switch(mode_wanted) {
		case 4:	
			speedp = 0x10c1; 
			speedt = 0x10c1;
			break;
		case 3:	
			speedp = 0x10C3; 
			speedt = 0x10C3;
			break;
		case 2:	
			speedp = 0x1104; 
			speedt = 0x1281;
			break;
		case 1:		
			speedp = 0x2283; 
			speedt = 0x1281;
			break;
		case 0:
		default:
			speedp = 0x328A; 
			speedt = 0x328A;
			break;
	}
	if (hwif->mmio)
	{
		hwif->OUTW(speedt, addr);
		hwif->OUTW(speedp, tfaddr);
		/* Now set up IORDY */
		if(mode_wanted == 3 || mode_wanted == 4)
			hwif->OUTW(hwif->INW(tfaddr-2)|0x200, tfaddr-2);
		else
			hwif->OUTW(hwif->INW(tfaddr-2)&~0x200, tfaddr-2);
	}
	else
	{
		pci_write_config_word(hwif->pci_dev, addr, speedp);
		pci_write_config_word(hwif->pci_dev, tfaddr, speedt);
		pci_read_config_word(hwif->pci_dev, tfaddr-2, &speedp);
		speedp &= ~0x200;
		/* Set IORDY for mode 3 or 4 */
		if(mode_wanted == 3 || mode_wanted == 4)
			speedp |= 0x200;
		pci_write_config_word(hwif->pci_dev, tfaddr-2, speedp);
	}
}
static void sil_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
	static const u16 tf_speed[]   = { 0x328a, 0x2283, 0x1281, 0x10c3, 0x10c1 };
	static const u16 data_speed[] = { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 };

	struct pci_dev *dev	= to_pci_dev(hwif->dev);
	ide_drive_t *pair	= ide_get_pair_dev(drive);
	u32 speedt		= 0;
	u16 speedp		= 0;
	unsigned long addr	= siimage_seldev(drive, 0x04);
	unsigned long tfaddr	= siimage_selreg(hwif,	0x02);
	unsigned long base	= (unsigned long)hwif->hwif_data;
	const u8 pio		= drive->pio_mode - XFER_PIO_0;
	u8 tf_pio		= pio;
	u8 mmio			= (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
	u8 addr_mask		= hwif->channel ? (mmio ? 0xF4 : 0x84)
						: (mmio ? 0xB4 : 0x80);
	u8 mode			= 0;
	u8 unit			= drive->dn & 1;

	
	if (pair) {
		u8 pair_pio = pair->pio_mode - XFER_PIO_0;

		if (pair_pio < tf_pio)
			tf_pio = pair_pio;
	}

	
	speedp = data_speed[pio];
	speedt = tf_speed[tf_pio];

	sil_iowrite16(dev, speedp, addr);
	sil_iowrite16(dev, speedt, tfaddr);

	
	speedp = sil_ioread16(dev, tfaddr - 2);
	speedp &= ~0x200;

	mode = sil_ioread8(dev, base + addr_mask);
	mode &= ~(unit ? 0x30 : 0x03);

	if (ide_pio_need_iordy(drive, pio)) {
		speedp |= 0x200;
		mode |= unit ? 0x10 : 0x01;
	}

	sil_iowrite16(dev, speedp, tfaddr - 2);
	sil_iowrite8(dev, mode, base + addr_mask);
}
示例#5
0
文件: siimage.c 项目: maraz/linux-2.6
static void sil_set_pio_mode(ide_drive_t *drive, u8 pio)
{
	static const u16 tf_speed[]   = { 0x328a, 0x2283, 0x1281, 0x10c3, 0x10c1 };
	static const u16 data_speed[] = { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 };

	ide_hwif_t *hwif	= HWIF(drive);
	struct pci_dev *dev	= to_pci_dev(hwif->dev);
	ide_drive_t *pair	= ide_get_paired_drive(drive);
	u32 speedt		= 0;
	u16 speedp		= 0;
	unsigned long addr	= siimage_seldev(drive, 0x04);
	unsigned long tfaddr	= siimage_selreg(hwif,	0x02);
	unsigned long base	= (unsigned long)hwif->hwif_data;
	u8 tf_pio		= pio;
	u8 mmio			= (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
	u8 addr_mask		= hwif->channel ? (mmio ? 0xF4 : 0x84)
						: (mmio ? 0xB4 : 0x80);
	u8 mode			= 0;
	u8 unit			= drive->select.b.unit;

	/* trim *taskfile* PIO to the slowest of the master/slave */
	if (pair->present) {
		u8 pair_pio = ide_get_best_pio_mode(pair, 255, 4);

		if (pair_pio < tf_pio)
			tf_pio = pair_pio;
	}

	/* cheat for now and use the docs */
	speedp = data_speed[pio];
	speedt = tf_speed[tf_pio];

	sil_iowrite16(dev, speedp, addr);
	sil_iowrite16(dev, speedt, tfaddr);

	/* now set up IORDY */
	speedp = sil_ioread16(dev, tfaddr - 2);
	speedp &= ~0x200;
	if (pio > 2)
		speedp |= 0x200;
	sil_iowrite16(dev, speedp, tfaddr - 2);

	mode = sil_ioread8(dev, base + addr_mask);
	mode &= ~(unit ? 0x30 : 0x03);
	mode |= unit ? 0x10 : 0x01;
	sil_iowrite8(dev, mode, base + addr_mask);
}
示例#6
0
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));
}
示例#7
0
文件: siimage.c 项目: Tigrouzen/k1099
static void sil_set_pio_mode(ide_drive_t *drive, u8 pio)
{
    const u16 tf_speed[]	= { 0x328a, 0x2283, 0x1281, 0x10c3, 0x10c1 };
    const u16 data_speed[]	= { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 };

    ide_hwif_t *hwif	= HWIF(drive);
    ide_drive_t *pair	= ide_get_paired_drive(drive);
    u32 speedt		= 0;
    u16 speedp		= 0;
    unsigned long addr	= siimage_seldev(drive, 0x04);
    unsigned long tfaddr	= siimage_selreg(hwif, 0x02);
    unsigned long base	= (unsigned long)hwif->hwif_data;
    u8 tf_pio		= pio;
    u8 addr_mask		= hwif->channel ? (hwif->mmio ? 0xF4 : 0x84)
                          : (hwif->mmio ? 0xB4 : 0x80);
    u8 mode			= 0;
    u8 unit			= drive->select.b.unit;

    /* trim *taskfile* PIO to the slowest of the master/slave */
    if (pair->present) {
        u8 pair_pio = ide_get_best_pio_mode(pair, 255, 4);

        if (pair_pio < tf_pio)
            tf_pio = pair_pio;
    }

    /* cheat for now and use the docs */
    speedp = data_speed[pio];
    speedt = tf_speed[tf_pio];

    if (hwif->mmio) {
        hwif->OUTW(speedp, addr);
        hwif->OUTW(speedt, tfaddr);
        /* Now set up IORDY */
        if (pio > 2)
            hwif->OUTW(hwif->INW(tfaddr-2)|0x200, tfaddr-2);
        else
            hwif->OUTW(hwif->INW(tfaddr-2)&~0x200, tfaddr-2);

        mode = hwif->INB(base + addr_mask);
        mode &= ~(unit ? 0x30 : 0x03);
        mode |= (unit ? 0x10 : 0x01);
        hwif->OUTB(mode, base + addr_mask);
    } else {
        struct pci_dev *dev = to_pci_dev(hwif->dev);

        pci_write_config_word(dev, addr, speedp);
        pci_write_config_word(dev, tfaddr, speedt);
        pci_read_config_word(dev, tfaddr - 2, &speedp);
        speedp &= ~0x200;
        /* Set IORDY for mode 3 or 4 */
        if (pio > 2)
            speedp |= 0x200;
        pci_write_config_word(dev, tfaddr - 2, speedp);

        pci_read_config_byte(dev, addr_mask, &mode);
        mode &= ~(unit ? 0x30 : 0x03);
        mode |= (unit ? 0x10 : 0x01);
        pci_write_config_byte(dev, addr_mask, mode);
    }
}