コード例 #1
0
ファイル: siimage.c プロジェクト: BackupTheBerlios/wl530g-svn
static int siimage_busproc (ide_drive_t * drive, int state)
{
	ide_hwif_t *hwif	= HWIF(drive);
	u32 stat_config		= 0;
	unsigned long addr	= siimage_selreg(hwif, 0);

	if (hwif->mmio) {
		stat_config = hwif->INL(addr);
	} else
		pci_read_config_dword(hwif->pci_dev, addr, &stat_config);

	switch (state) {
		case BUSSTATE_ON:
			hwif->drives[0].failures = 0;
			hwif->drives[1].failures = 0;
			break;
		case BUSSTATE_OFF:
			hwif->drives[0].failures = hwif->drives[0].max_failures + 1;
			hwif->drives[1].failures = hwif->drives[1].max_failures + 1;
			break;
		case BUSSTATE_TRISTATE:
			hwif->drives[0].failures = hwif->drives[0].max_failures + 1;
			hwif->drives[1].failures = hwif->drives[1].max_failures + 1;
			break;
		default:
			return -EINVAL;
	}
	hwif->bus_state = state;
	return 0;
}
コード例 #2
0
ファイル: siimage.c プロジェクト: BackupTheBerlios/wl530g-svn
static void siimage_reset (ide_drive_t *drive)
{
	ide_hwif_t *hwif	= HWIF(drive);
	u8 reset		= 0;
	unsigned long addr	= siimage_selreg(hwif, 0);

	if (hwif->mmio) {
		reset = hwif->INB(addr);
		hwif->OUTB((reset|0x03), addr);
		/* FIXME:posting */
		udelay(25);
		hwif->OUTB(reset, addr);
		(void) hwif->INB(addr);
	} else {
		pci_read_config_byte(hwif->pci_dev, addr, &reset);
		pci_write_config_byte(hwif->pci_dev, addr, reset|0x03);
		udelay(25);
		pci_write_config_byte(hwif->pci_dev, addr, reset);
		pci_read_config_byte(hwif->pci_dev, addr, &reset);
	}

	if (SATA_STATUS_REG) {
		u32 sata_stat = hwif->INL(SATA_STATUS_REG);
		printk(KERN_WARNING "%s: reset phy, status=0x%08x, %s\n",
			hwif->name, sata_stat, __FUNCTION__);
		if (!(sata_stat)) {
			printk(KERN_WARNING "%s: reset phy dead, status=0x%08x\n",
				hwif->name, sata_stat);
			drive->failures++;
		}
	}

}
コード例 #3
0
ファイル: siimage.c プロジェクト: Tigrouzen/k1099
static int sil_sata_busproc(ide_drive_t * drive, int state)
{
    ide_hwif_t *hwif	= HWIF(drive);
    struct pci_dev *dev	= to_pci_dev(hwif->dev);
    u32 stat_config		= 0;
    unsigned long addr	= siimage_selreg(hwif, 0);

    if (hwif->mmio)
        stat_config = readl((void __iomem *)addr);
    else
        pci_read_config_dword(dev, addr, &stat_config);

    switch (state) {
    case BUSSTATE_ON:
        hwif->drives[0].failures = 0;
        hwif->drives[1].failures = 0;
        break;
    case BUSSTATE_OFF:
        hwif->drives[0].failures = hwif->drives[0].max_failures + 1;
        hwif->drives[1].failures = hwif->drives[1].max_failures + 1;
        break;
    case BUSSTATE_TRISTATE:
        hwif->drives[0].failures = hwif->drives[0].max_failures + 1;
        hwif->drives[1].failures = hwif->drives[1].max_failures + 1;
        break;
    default:
        return -EINVAL;
    }
    hwif->bus_state = state;
    return 0;
}
コード例 #4
0
static u8 sil_cable_detect(ide_hwif_t *hwif)
{
	struct pci_dev *dev	= to_pci_dev(hwif->dev);
	unsigned long addr	= siimage_selreg(hwif, 0);
	u8 ata66		= sil_ioread8(dev, addr);

	return (ata66 & 0x01) ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
}
コード例 #5
0
static int sil_test_irq(ide_hwif_t *hwif)
{
	struct pci_dev *dev	= to_pci_dev(hwif->dev);
	unsigned long addr	= siimage_selreg(hwif, 1);
	u8 val			= sil_ioread8(dev, addr);

	
	return (val & 8) ? 1 : 0;
}
コード例 #6
0
ファイル: siimage.c プロジェクト: BackupTheBerlios/wl530g-svn
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);
	}
}
コード例 #7
0
ファイル: siimage.c プロジェクト: BackupTheBerlios/wl530g-svn
static unsigned int __init ata66_siimage (ide_hwif_t *hwif)
{
	unsigned long addr = siimage_selreg(hwif, 0);
	if (pci_get_drvdata(hwif->pci_dev) == NULL) {
		u8 ata66 = 0;
		pci_read_config_byte(hwif->pci_dev, addr, &ata66);
		return (ata66 & 0x01) ? 1 : 0;
	}

	return (hwif->INB(addr) & 0x01) ? 1 : 0;
}
コード例 #8
0
ファイル: siimage.c プロジェクト: Tigrouzen/k1099
static u8 __devinit ata66_siimage(ide_hwif_t *hwif)
{
    struct pci_dev *dev = to_pci_dev(hwif->dev);
    unsigned long addr = siimage_selreg(hwif, 0);
    u8 ata66 = 0;

    if (pci_get_drvdata(dev) == NULL)
        pci_read_config_byte(dev, addr, &ata66);
    else
        ata66 = hwif->INB(addr);

    return (ata66 & 0x01) ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
}
コード例 #9
0
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);
}
コード例 #10
0
ファイル: siimage.c プロジェクト: BackupTheBerlios/wl530g-svn
/* returns 1 if dma irq issued, 0 otherwise */
static int siimage_io_ide_dma_test_irq (ide_drive_t *drive)
{
	ide_hwif_t *hwif	= HWIF(drive);
	u8 dma_altstat		= 0;
	unsigned long addr	= siimage_selreg(hwif, 1);

	/* return 1 if INTR asserted */
	if ((hwif->INB(hwif->dma_status) & 4) == 4)
		return 1;

	/* return 1 if Device INTR asserted */
	pci_read_config_byte(hwif->pci_dev, addr, &dma_altstat);
	if (dma_altstat & 8)
		return 0;	//return 1;
	return 0;
}
コード例 #11
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);
}
コード例 #12
0
ファイル: siimage.c プロジェクト: BackupTheBerlios/wl530g-svn
static int siimage_mmio_ide_dma_count (ide_drive_t *drive)
{
#ifdef SIIMAGE_VIRTUAL_DMAPIO
	struct request *rq	= HWGROUP(drive)->rq;
	ide_hwif_t *hwif	= HWIF(drive);
	u32 count		= (rq->nr_sectors * SECTOR_SIZE);
	u32 rcount		= 0;
	unsigned long addr	= siimage_selreg(hwif, 0x1C);

	hwif->OUTL(count, addr);
	rcount = hwif->INL(addr);

	printk("\n%s: count = %d, rcount = %d, nr_sectors = %lu\n",
		drive->name, count, rcount, rq->nr_sectors);

#endif /* SIIMAGE_VIRTUAL_DMAPIO */
	return __ide_dma_count(drive);
}
コード例 #13
0
ファイル: siimage.c プロジェクト: BackupTheBerlios/wl530g-svn
static byte siimage_taskfile_timing (ide_hwif_t *hwif)
{
	u16 timing	= 0x328a;
	unsigned long addr = siimage_selreg(hwif, 2);

	if (hwif->mmio)
		timing = hwif->INW(addr);
	else
		pci_read_config_word(hwif->pci_dev, addr, &timing);

	switch (timing) {
		case 0x10c1:	return 4;
		case 0x10c3:	return 3;
		case 0x1104:
		case 0x1281:	return 2;
		case 0x2283:	return 1;
		case 0x328a:
		default:	return 0;
	}
}
コード例 #14
0
ファイル: siimage.c プロジェクト: Tigrouzen/k1099
static int siimage_mmio_ide_dma_test_irq (ide_drive_t *drive)
{
    ide_hwif_t *hwif	= HWIF(drive);
    unsigned long addr	= siimage_selreg(hwif, 0x1);
    void __iomem *sata_error_addr
        = (void __iomem *)hwif->sata_scr[SATA_ERROR_OFFSET];

    if (sata_error_addr) {
        unsigned long base = (unsigned long)hwif->hwif_data;
        u32 ext_stat = readl((void __iomem *)(base + 0x10));
        u8 watchdog = 0;

        if (ext_stat & ((hwif->channel) ? 0x40 : 0x10)) {
            u32 sata_error = readl(sata_error_addr);

            writel(sata_error, sata_error_addr);
            watchdog = (sata_error & 0x00680000) ? 1 : 0;
            printk(KERN_WARNING "%s: sata_error = 0x%08x, "
                   "watchdog = %d, %s\n",
                   drive->name, sata_error, watchdog,
                   __FUNCTION__);

        } else {
            watchdog = (ext_stat & 0x8000) ? 1 : 0;
        }
        ext_stat >>= 16;

        if (!(ext_stat & 0x0404) && !watchdog)
            return 0;
    }

    /* return 1 if INTR asserted */
    if ((readb((void __iomem *)hwif->dma_status) & 0x04) == 0x04)
        return 1;

    /* return 1 if Device INTR asserted */
    if ((readb((void __iomem *)addr) & 8) == 8)
        return 0;	//return 1;

    return 0;
}
コード例 #15
0
ファイル: siimage.c プロジェクト: BackupTheBerlios/wl530g-svn
static int siimage_mmio_ide_dma_test_irq (ide_drive_t *drive)
{
	ide_hwif_t *hwif	= HWIF(drive);
	unsigned long base	= (unsigned long)hwif->hwif_data;
	unsigned long addr	= siimage_selreg(hwif, 0x1);

	if (SATA_ERROR_REG) {
		u32 ext_stat = hwif->INL(base + 0x10);
		u8 watchdog = 0;
		if (ext_stat & ((hwif->channel) ? 0x40 : 0x10)) {
			u32 sata_error = hwif->INL(SATA_ERROR_REG);
			hwif->OUTL(sata_error, SATA_ERROR_REG);
			watchdog = (sata_error & 0x00680000) ? 1 : 0;
#if 1
			printk(KERN_WARNING "%s: sata_error = 0x%08x, "
				"watchdog = %d, %s\n",
				drive->name, sata_error, watchdog,
				__FUNCTION__);
#endif

		} else {
			watchdog = (ext_stat & 0x8000) ? 1 : 0;
		}
		ext_stat >>= 16;

		if (!(ext_stat & 0x0404) && !watchdog)
			return 0;
	}

	/* return 1 if INTR asserted */
	if ((hwif->INB(hwif->dma_status) & 0x04) == 0x04)
		return 1;

	/* return 1 if Device INTR asserted */
	if ((hwif->INB(addr) & 8) == 8)
		return 0;	//return 1;

	return 0;
}
コード例 #16
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);
    }
}