Пример #1
0
/*
 * Something like this really should be in generic code, but isn't.
 */
static ide_hwif_t *
rapide_locate_hwif(void __iomem *base, void __iomem *ctrl, unsigned int sz, int irq)
{
	unsigned long port = (unsigned long)base;
	ide_hwif_t *hwif;
	int index, i;

	for (index = 0; index < MAX_HWIFS; ++index) {
		hwif = ide_hwifs + index;
		if (hwif->io_ports[IDE_DATA_OFFSET] == port)
			goto found;
	}

	for (index = 0; index < MAX_HWIFS; ++index) {
		hwif = ide_hwifs + index;
		if (hwif->io_ports[IDE_DATA_OFFSET] == 0)
			goto found;
	}

	return NULL;

 found:
	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
		hwif->hw.io_ports[i] = port;
		hwif->io_ports[i] = port;
		port += sz;
	}
	hwif->hw.io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
	hwif->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
	hwif->hw.irq = hwif->irq = irq;
	hwif->mmio = 1;
	default_hwif_mmiops(hwif);

	return hwif;
}
Пример #2
0
static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif)
{
	struct pci_dev *dev	= to_pci_dev(hwif->dev);
	void *addr		= pci_get_drvdata(dev);
	u8 ch			= hwif->channel;
	struct ide_io_ports *io_ports = &hwif->io_ports;
	unsigned long base;

	/*
	 *	Fill in the basic hwif bits
	 */
	hwif->host_flags |= IDE_HFLAG_MMIO;
	default_hwif_mmiops(hwif);
	hwif->hwif_data	= addr;

	/*
	 *	Now set up the hw. We have to do this ourselves as the
	 *	MMIO layout isn't the same as the standard port based I/O.
	 */
	memset(io_ports, 0, sizeof(*io_ports));

	base = (unsigned long)addr;
	if (ch)
		base += 0xC0;
	else
		base += 0x80;

	/*
	 *	The buffered task file doesn't have status/control, so we
	 *	can't currently use it sanely since we want to use LBA48 mode.
	 */
	io_ports->data_addr	= base;
	io_ports->error_addr	= base + 1;
	io_ports->nsect_addr	= base + 2;
	io_ports->lbal_addr	= base + 3;
	io_ports->lbam_addr	= base + 4;
	io_ports->lbah_addr	= base + 5;
	io_ports->device_addr	= base + 6;
	io_ports->status_addr	= base + 7;
	io_ports->ctl_addr	= base + 10;

	if (pdev_is_sata(dev)) {
		base = (unsigned long)addr;
		if (ch)
			base += 0x80;
		hwif->sata_scr[SATA_STATUS_OFFSET]	= base + 0x104;
		hwif->sata_scr[SATA_ERROR_OFFSET]	= base + 0x108;
		hwif->sata_scr[SATA_CONTROL_OFFSET]	= base + 0x100;
	}

	hwif->irq = dev->irq;

	hwif->dma_base = (unsigned long)addr + (ch ? 0x08 : 0x00);

	hwif->mmio = 1;
}
Пример #3
0
static ide_hwif_t *
rapide_locate_hwif(void __iomem *base, void __iomem *ctrl, unsigned int sz, int irq)
{
	unsigned long port = (unsigned long)base;
	ide_hwif_t *hwif = ide_find_port(port);
	int i;

	if (hwif == NULL)
		goto out;

	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
		hwif->io_ports[i] = port;
		port += sz;
	}
	hwif->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
	hwif->irq = irq;
	hwif->mmio = 1;
	default_hwif_mmiops(hwif);
out:
	return hwif;
}
Пример #4
0
static void __devinit
ide_init_sgiioc4(ide_hwif_t * hwif)
{
	hwif->mmio = 2;
	hwif->autodma = 1;
	hwif->atapi_dma = 1;
	hwif->ultra_mask = 0x0;	/* Disable Ultra DMA */
	hwif->mwdma_mask = 0x2;	/* Multimode-2 DMA  */
	hwif->swdma_mask = 0x2;
	hwif->tuneproc = NULL;	/* Sets timing for PIO mode */
	hwif->speedproc = NULL;	/* Sets timing for DMA &/or PIO modes */
	hwif->selectproc = NULL;/* Use the default routine to select drive */
	hwif->reset_poll = NULL;/* No HBA specific reset_poll needed */
	hwif->pre_reset = NULL;	/* No HBA specific pre_set needed */
	hwif->resetproc = &sgiioc4_resetproc;/* Reset DMA engine,
						clear interrupts */
	hwif->intrproc = NULL;	/* Enable or Disable interrupt from drive */
	hwif->maskproc = &sgiioc4_maskproc;	/* Mask on/off NIEN register */
	hwif->quirkproc = NULL;
	hwif->busproc = NULL;

	hwif->dma_setup = &sgiioc4_ide_dma_setup;
	hwif->dma_start = &sgiioc4_ide_dma_start;
	hwif->ide_dma_end = &sgiioc4_ide_dma_end;
	hwif->ide_dma_check = &sgiioc4_ide_dma_check;
	hwif->ide_dma_on = &sgiioc4_ide_dma_on;
	hwif->ide_dma_off_quietly = &sgiioc4_ide_dma_off_quietly;
	hwif->ide_dma_test_irq = &sgiioc4_ide_dma_test_irq;
	hwif->ide_dma_host_on = &sgiioc4_ide_dma_host_on;
	hwif->ide_dma_host_off = &sgiioc4_ide_dma_host_off;
	hwif->ide_dma_lostirq = &sgiioc4_ide_dma_lostirq;
	hwif->ide_dma_timeout = &__ide_dma_timeout;

	/*
	 * The IOC4 uses MMIO rather than Port IO.
	 * It also needs special workarounds for INB.
	 */
	default_hwif_mmiops(hwif);
	hwif->INB = &sgiioc4_INB;
}
Пример #5
0
/*
 * swarm_ide_probe - if the board header indicates the existence of
 * Generic Bus IDE, allocate a HWIF for it.
 */
static int __devinit swarm_ide_probe(struct device *dev)
{
    ide_hwif_t *hwif;
    u8 __iomem *base;
    phys_t offset, size;
    int i;

    if (!SIBYTE_HAVE_IDE)
        return -ENODEV;

    /* Find an empty slot.  */
    for (i = 0; i < MAX_HWIFS; i++)
        if (!ide_hwifs[i].io_ports[IDE_DATA_OFFSET])
            break;
    if (i >= MAX_HWIFS) {
        printk(KERN_ERR DRV_NAME ": no free slot for interface\n");
        return -ENOMEM;
    }

    hwif = ide_hwifs + i;

    base = ioremap(A_IO_EXT_BASE, 0x800);
    offset = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_START_ADDR, IDE_CS));
    size = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_MULT_SIZE, IDE_CS));
    iounmap(base);

    offset = G_IO_START_ADDR(offset) << S_IO_ADDRBASE;
    size = (G_IO_MULT_SIZE(size) + 1) << S_IO_REGSIZE;
    if (offset < A_PHYS_GENBUS || offset >= A_PHYS_GENBUS_END) {
        printk(KERN_INFO DRV_NAME
               ": IDE interface at GenBus disabled\n");
        return -EBUSY;
    }

    printk(KERN_INFO DRV_NAME ": IDE interface at GenBus slot %i\n",
           IDE_CS);

    swarm_ide_resource.start = offset;
    swarm_ide_resource.end = offset + size - 1;
    if (request_resource(&iomem_resource, &swarm_ide_resource)) {
        printk(KERN_ERR DRV_NAME
               ": can't request I/O memory resource\n");
        return -EBUSY;
    }

    base = ioremap(offset, size);

    /* Setup MMIO ops.  */
    default_hwif_mmiops(hwif);
    /* Prevent resource map manipulation.  */
    hwif->mmio = 2;
    hwif->noprobe = 0;

    for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
        hwif->hw.io_ports[i] =
            (unsigned long)(base + ((0x1f0 + i) << 5));
    hwif->hw.io_ports[IDE_CONTROL_OFFSET] =
        (unsigned long)(base + (0x3f6 << 5));
    hwif->hw.irq = K_INT_GB_IDE;

    memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
    hwif->irq = hwif->hw.irq;

    dev_set_drvdata(dev, hwif);

    return 0;
}
Пример #6
0
static int __devinit plat_ide_probe(struct platform_device *pdev)
{
    struct resource *res_base, *res_alt, *res_irq;
    void __iomem *base, *alt_base;
    ide_hwif_t *hwif;
    struct pata_platform_info *pdata;
    u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
    int ret = 0;
    int mmio = 0;
    hw_regs_t hw;

    pdata = pdev->dev.platform_data;

    /* get a pointer to the register memory */
    res_base = platform_get_resource(pdev, IORESOURCE_IO, 0);
    res_alt = platform_get_resource(pdev, IORESOURCE_IO, 1);

    if (!res_base || !res_alt) {
        res_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        res_alt = platform_get_resource(pdev, IORESOURCE_MEM, 1);
        if (!res_base || !res_alt) {
            ret = -ENOMEM;
            goto out;
        }
        mmio = 1;
    }

    res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
    if (!res_irq) {
        ret = -EINVAL;
        goto out;
    }

    if (mmio) {
        base = devm_ioremap(&pdev->dev,
            res_base->start, res_base->end - res_base->start + 1);
        alt_base = devm_ioremap(&pdev->dev,
            res_alt->start, res_alt->end - res_alt->start + 1);
    } else {
        base = devm_ioport_map(&pdev->dev,
            res_base->start, res_base->end - res_base->start + 1);
        alt_base = devm_ioport_map(&pdev->dev,
            res_alt->start, res_alt->end - res_alt->start + 1);
    }

    hwif = ide_find_port();
    if (!hwif) {
        ret = -ENODEV;
        goto out;
    }

    memset(&hw, 0, sizeof(hw));
    plat_ide_setup_ports(&hw, base, alt_base, pdata, res_irq->start);
    hw.dev = &pdev->dev;

    ide_init_port_hw(hwif, &hw);

    if (mmio) {
        hwif->host_flags = IDE_HFLAG_MMIO;
        default_hwif_mmiops(hwif);
    }

    idx[0] = hwif->index;

    ide_device_add(idx, NULL);

    platform_set_drvdata(pdev, hwif);

    return 0;

out:
    return ret;
}
Пример #7
0
static int __devinit
sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d)
{
	unsigned long cmd_base, dma_base, irqport;
	unsigned long bar0, cmd_phys_base, ctl;
	void __iomem *virt_base;
	ide_hwif_t *hwif;
	int h;

	/*
	 * Find an empty HWIF; if none available, return -ENOMEM.
	 */
	for (h = 0; h < MAX_HWIFS; ++h) {
		hwif = &ide_hwifs[h];
		if (hwif->chipset == ide_unknown)
			break;
	}
	if (h == MAX_HWIFS) {
		printk(KERN_ERR "%s: too many IDE interfaces, no room in table\n", d->name);
		return -ENOMEM;
	}

	/*  Get the CmdBlk and CtrlBlk Base Registers */
	bar0 = pci_resource_start(dev, 0);
	virt_base = ioremap(bar0, pci_resource_len(dev, 0));
	if (virt_base == NULL) {
		printk(KERN_ERR "%s: Unable to remap BAR 0 address: 0x%lx\n",
			d->name, bar0);
		return -ENOMEM;
	}
	cmd_base = (unsigned long) virt_base + IOC4_CMD_OFFSET;
	ctl = (unsigned long) virt_base + IOC4_CTRL_OFFSET;
	irqport = (unsigned long) virt_base + IOC4_INTR_OFFSET;
	dma_base = pci_resource_start(dev, 0) + IOC4_DMA_OFFSET;

	cmd_phys_base = bar0 + IOC4_CMD_OFFSET;
	if (!request_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE,
	    hwif->name)) {
		printk(KERN_ERR
			"%s : %s -- ERROR, Addresses "
			"0x%p to 0x%p ALREADY in use\n",
		       __FUNCTION__, hwif->name, (void *) cmd_phys_base,
		       (void *) cmd_phys_base + IOC4_CMD_CTL_BLK_SIZE);
		return -ENOMEM;
	}

	if (hwif->io_ports[IDE_DATA_OFFSET] != cmd_base) {
		/* Initialize the IO registers */
		sgiioc4_init_hwif_ports(&hwif->hw, cmd_base, ctl, irqport);
		memcpy(hwif->io_ports, hwif->hw.io_ports,
		       sizeof (hwif->io_ports));
		hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
	}

	hwif->irq = dev->irq;
	hwif->chipset = ide_pci;
	hwif->pci_dev = dev;
	hwif->channel = 0;	/* Single Channel chip */
	hwif->cds = (struct ide_pci_device_s *) d;
	hwif->gendev.parent = &dev->dev;/* setup proper ancestral information */

	/* The IOC4 uses MMIO rather than Port IO. */
	default_hwif_mmiops(hwif);

	/* Initializing chipset IRQ Registers */
	writel(0x03, (void __iomem *)(irqport + IOC4_INTR_SET * 4));

	ide_init_sgiioc4(hwif);

	if (dma_base)
		ide_dma_sgiioc4(hwif, dma_base);
	else
		printk(KERN_INFO "%s: %s Bus-Master DMA disabled\n",
		       hwif->name, d->name);

	if (probe_hwif_init(hwif))
		return -EIO;

	/* Create /proc/ide entries */
	ide_proc_register_port(hwif);

	return 0;
}
Пример #8
0
static void __init init_mmio_iops_siimage (ide_hwif_t *hwif)
{
	struct pci_dev *dev	= hwif->pci_dev;
	void *addr		= pci_get_drvdata(dev);
	u8 ch			= hwif->channel;
	hw_regs_t		hw;
	unsigned long		base;

	/*
	 *	Fill in the basic HWIF bits
	 */

	default_hwif_mmiops(hwif);
	hwif->hwif_data			= addr;

	/*
	 *	Now set up the hw. We have to do this ourselves as
	 *	the MMIO layout isnt the same as the the standard port
	 *	based I/O
	 */
	 
	memset(&hw, 0, sizeof(hw_regs_t));
	hw.priv				= addr;

	base				= (unsigned long)addr;
	if(ch)
		base += 0xC0;
	else
		base += 0x80;

	/*
	 *	The buffered task file doesn't have status/control
	 *	so we can't currently use it sanely since we want to
	 *	use LBA48 mode.
	 */	
//	base += 0x10;
//      hwif->addressing = 1;

	hw.io_ports[IDE_DATA_OFFSET]	= base;
	hw.io_ports[IDE_ERROR_OFFSET]	= base + 1;
	hw.io_ports[IDE_NSECTOR_OFFSET]	= base + 2;
	hw.io_ports[IDE_SECTOR_OFFSET]	= base + 3;
	hw.io_ports[IDE_LCYL_OFFSET]	= base + 4;
	hw.io_ports[IDE_HCYL_OFFSET]	= base + 5;
	hw.io_ports[IDE_SELECT_OFFSET]	= base + 6;
	hw.io_ports[IDE_STATUS_OFFSET]	= base + 7;
	hw.io_ports[IDE_CONTROL_OFFSET]	= base + 10;

	hw.io_ports[IDE_IRQ_OFFSET]	= 0;

        if (pdev_is_sata(dev)) {
        	base = (unsigned long) addr;
        	if(ch)
        		base += 0x80;
		hw.sata_scr[SATA_STATUS_OFFSET]	= base + 0x104;
		hw.sata_scr[SATA_ERROR_OFFSET]	= base + 0x108;
		hw.sata_scr[SATA_CONTROL_OFFSET]= base + 0x100;
		hw.sata_misc[SATA_MISC_OFFSET]	= base + 0x140;
		hw.sata_misc[SATA_PHY_OFFSET]	= base + 0x144;
		hw.sata_misc[SATA_IEN_OFFSET]	= base + 0x148;
	}

	hw.irq				= hwif->pci_dev->irq;

	memcpy(&hwif->hw, &hw, sizeof(hw));
	memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports));

	if (is_sata(hwif)) {
		memcpy(hwif->sata_scr, hwif->hw.sata_scr, sizeof(hwif->hw.sata_scr));
		memcpy(hwif->sata_misc, hwif->hw.sata_misc, sizeof(hwif->hw.sata_misc));
	}

	hwif->irq			= hw.irq;

       	base = (unsigned long) addr;

#ifdef SIIMAGE_LARGE_DMA
/* Watch the brackets - even Ken and Dennis get some language design wrong */
	hwif->dma_base			= base + (ch ? 0x18 : 0x10);
	hwif->dma_base2			= base + (ch ? 0x08 : 0x00);
	hwif->dma_prdtable		= hwif->dma_base2 + 4;
#else /* ! SIIMAGE_LARGE_DMA */
	hwif->dma_base			= base + (ch ? 0x08 : 0x00);
	hwif->dma_base2			= base + (ch ? 0x18 : 0x10);
#endif /* SIIMAGE_LARGE_DMA */
	hwif->mmio			= 2;
}
Пример #9
0
static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif)
{
	struct pci_dev *dev	= hwif->pci_dev;
	void *addr		= pci_get_drvdata(dev);
	u8 ch			= hwif->channel;
	hw_regs_t		hw;
	unsigned long		base;

	/*
	 *	Fill in the basic HWIF bits
	 */

	default_hwif_mmiops(hwif);
	hwif->hwif_data			= addr;

	/*
	 *	Now set up the hw. We have to do this ourselves as
	 *	the MMIO layout isnt the same as the the standard port
	 *	based I/O
	 */

	memset(&hw, 0, sizeof(hw_regs_t));

	base = (unsigned long)addr;
	if (ch)
		base += 0xC0;
	else
		base += 0x80;

	/*
	 *	The buffered task file doesn't have status/control
	 *	so we can't currently use it sanely since we want to
	 *	use LBA48 mode.
	 */	
	hw.io_ports[IDE_DATA_OFFSET]	= base;
	hw.io_ports[IDE_ERROR_OFFSET]	= base + 1;
	hw.io_ports[IDE_NSECTOR_OFFSET]	= base + 2;
	hw.io_ports[IDE_SECTOR_OFFSET]	= base + 3;
	hw.io_ports[IDE_LCYL_OFFSET]	= base + 4;
	hw.io_ports[IDE_HCYL_OFFSET]	= base + 5;
	hw.io_ports[IDE_SELECT_OFFSET]	= base + 6;
	hw.io_ports[IDE_STATUS_OFFSET]	= base + 7;
	hw.io_ports[IDE_CONTROL_OFFSET]	= base + 10;

	hw.io_ports[IDE_IRQ_OFFSET]	= 0;

	if (pdev_is_sata(dev)) {
		base = (unsigned long)addr;
		if (ch)
			base += 0x80;
		hwif->sata_scr[SATA_STATUS_OFFSET]	= base + 0x104;
		hwif->sata_scr[SATA_ERROR_OFFSET]	= base + 0x108;
		hwif->sata_scr[SATA_CONTROL_OFFSET]	= base + 0x100;
		hwif->sata_misc[SATA_MISC_OFFSET]	= base + 0x140;
		hwif->sata_misc[SATA_PHY_OFFSET]	= base + 0x144;
		hwif->sata_misc[SATA_IEN_OFFSET]	= base + 0x148;
	}

	memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports));

	hwif->irq = dev->irq;

	hwif->dma_base = (unsigned long)addr + (ch ? 0x08 : 0x00);
	hwif->mmio			= 2;
}
Пример #10
0
static int __devinit
sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
{
	unsigned long cmd_base, irqport;
	unsigned long bar0, cmd_phys_base, ctl;
	void __iomem *virt_base;
	ide_hwif_t *hwif;
	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
	hw_regs_t hw;
	struct ide_port_info d = sgiioc4_port_info;

	/*  Get the CmdBlk and CtrlBlk Base Registers */
	bar0 = pci_resource_start(dev, 0);
	virt_base = ioremap(bar0, pci_resource_len(dev, 0));
	if (virt_base == NULL) {
		printk(KERN_ERR "%s: Unable to remap BAR 0 address: 0x%lx\n",
				DRV_NAME, bar0);
		return -ENOMEM;
	}
	cmd_base = (unsigned long) virt_base + IOC4_CMD_OFFSET;
	ctl = (unsigned long) virt_base + IOC4_CTRL_OFFSET;
	irqport = (unsigned long) virt_base + IOC4_INTR_OFFSET;

	cmd_phys_base = bar0 + IOC4_CMD_OFFSET;
	if (!request_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE,
	    DRV_NAME)) {
		printk(KERN_ERR
			"%s : %s -- ERROR, Addresses "
			"0x%p to 0x%p ALREADY in use\n",
		       __func__, DRV_NAME, (void *) cmd_phys_base,
		       (void *) cmd_phys_base + IOC4_CMD_CTL_BLK_SIZE);
		return -ENOMEM;
	}

	/* Initialize the IO registers */
	memset(&hw, 0, sizeof(hw));
	sgiioc4_init_hwif_ports(&hw, cmd_base, ctl, irqport);
	hw.irq = dev->irq;
	hw.chipset = ide_pci;
	hw.dev = &dev->dev;

	hwif = ide_find_port_slot(&d);
	if (hwif == NULL)
		goto err;

	ide_init_port_hw(hwif, &hw);

	/* The IOC4 uses MMIO rather than Port IO. */
	default_hwif_mmiops(hwif);

	/* Initializing chipset IRQ Registers */
	writel(0x03, (void __iomem *)(irqport + IOC4_INTR_SET * 4));

	hwif->INB = &sgiioc4_INB;

	idx[0] = hwif->index;

	if (ide_device_add(idx, &d))
		return -EIO;

	return 0;
err:
	release_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE);
	iounmap(virt_base);
	return -ENOMEM;
}
Пример #11
0
static int __init tcf_register(unsigned long dataport,int irq)
{
       ide_hwif_t *hwif;
       //int i,ret;

       

       hwif = tscf_find_hwif(dataport);
       
       if (hwif) {
               //int i;

               memset(&hwif->hw, 0, sizeof(hw_regs_t));

               /*
                * Ensure we're using MMIO
                */
               default_hwif_mmiops(hwif);
               hwif->mmio = 1;

               hwif->io_ports[IDE_DATA_OFFSET] =    (unsigned long)ioremap(TS7800_CF_DATA_PHYS_BASE,1);

               hwif->io_ports[IDE_ERROR_OFFSET] =   (unsigned long)ioremap(TS7800_CF_CMD_PHYS_BASE,1);
               hwif->io_ports[IDE_NSECTOR_OFFSET] = (unsigned long)ioremap(TS7800_CF_CMD_PHYS_BASE + 0x1,1);
               hwif->io_ports[IDE_SECTOR_OFFSET] =  (unsigned long)ioremap(TS7800_CF_CMD_PHYS_BASE + 0x2,1);
               hwif->io_ports[IDE_LCYL_OFFSET] =    (unsigned long)ioremap(TS7800_CF_CMD_PHYS_BASE + 0x3,1);
               hwif->io_ports[IDE_HCYL_OFFSET] =    (unsigned long)ioremap(TS7800_CF_CMD_PHYS_BASE + 0x4,1);
               hwif->io_ports[IDE_SELECT_OFFSET] =  (unsigned long)ioremap(TS7800_CF_CMD_PHYS_BASE + 0x5,1);
               hwif->io_ports[IDE_STATUS_OFFSET] =  (unsigned long)ioremap(TS7800_CF_CMD_PHYS_BASE + 0x6,1);
               
               hwif->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ioremap(TS7800_CF_AUX_PHYS_BASE,1);



               

               /*
               * This is the dma channel number assigned to this IDE interface. Until
               * dma is enabled for this interface, we set it to NO_DMA.
               */
               hwif->hw.dma = NO_DMA;
               hwif->dma = NO_DMA;

 
               hwif->hw.irq  = irq;
               hwif->irq     = irq;
               hwif->noprobe = 0;
               hwif->chipset = ide_generic;
               //hwif->chipset = ide_forced;
               
               
               probe_hwif_init(hwif);                                          
                                                                               
               //ide_proc_register_port(hwif);
	       create_proc_ide_interfaces();
	       //ide_register_hw(hwif,NULL);
 
       }

        printk("Technologic Systems TS-7800 IDE initialization - driver version 1.0, 12/27/07. \n");

        return 0;
}
Пример #12
0
static void __init init_mmio_iops_siimage (ide_hwif_t *hwif)
{
	struct pci_dev *dev	= hwif->pci_dev;
	unsigned long addr	= (unsigned long) pci_get_drvdata(hwif->pci_dev);
	u8 ch			= hwif->channel;
//	u16 i			= 0;
	hw_regs_t hw;

	default_hwif_mmiops(hwif);
	memset(&hw, 0, sizeof(hw_regs_t));

#if 1
#ifdef SIIMAGE_BUFFERED_TASKFILE
	hw.io_ports[IDE_DATA_OFFSET]	= DEVADDR((ch) ? 0xD0 : 0x90);
	hw.io_ports[IDE_ERROR_OFFSET]	= DEVADDR((ch) ? 0xD1 : 0x91);
	hw.io_ports[IDE_NSECTOR_OFFSET]	= DEVADDR((ch) ? 0xD2 : 0x92);
	hw.io_ports[IDE_SECTOR_OFFSET]	= DEVADDR((ch) ? 0xD3 : 0x93);
	hw.io_ports[IDE_LCYL_OFFSET]	= DEVADDR((ch) ? 0xD4 : 0x94);
	hw.io_ports[IDE_HCYL_OFFSET]	= DEVADDR((ch) ? 0xD5 : 0x95);
	hw.io_ports[IDE_SELECT_OFFSET]	= DEVADDR((ch) ? 0xD6 : 0x96);
	hw.io_ports[IDE_STATUS_OFFSET]	= DEVADDR((ch) ? 0xD7 : 0x97);
	hw.io_ports[IDE_CONTROL_OFFSET]	= DEVADDR((ch) ? 0xDA : 0x9A);
#else /* ! SIIMAGE_BUFFERED_TASKFILE */
	hw.io_ports[IDE_DATA_OFFSET]	= DEVADDR((ch) ? 0xC0 : 0x80);
	hw.io_ports[IDE_ERROR_OFFSET]	= DEVADDR((ch) ? 0xC1 : 0x81);
	hw.io_ports[IDE_NSECTOR_OFFSET]	= DEVADDR((ch) ? 0xC2 : 0x82);
	hw.io_ports[IDE_SECTOR_OFFSET]	= DEVADDR((ch) ? 0xC3 : 0x83);
	hw.io_ports[IDE_LCYL_OFFSET]	= DEVADDR((ch) ? 0xC4 : 0x84);
	hw.io_ports[IDE_HCYL_OFFSET]	= DEVADDR((ch) ? 0xC5 : 0x85);
	hw.io_ports[IDE_SELECT_OFFSET]	= DEVADDR((ch) ? 0xC6 : 0x86);
	hw.io_ports[IDE_STATUS_OFFSET]	= DEVADDR((ch) ? 0xC7 : 0x87);
	hw.io_ports[IDE_CONTROL_OFFSET]	= DEVADDR((ch) ? 0xCA : 0x8A);
#endif /* SIIMAGE_BUFFERED_TASKFILE */
#else
#ifdef SIIMAGE_BUFFERED_TASKFILE
	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
		hw.io_ports[i] = DEVADDR((ch) ? 0xD0 : 0x90)|(i);
	hw.io_ports[IDE_CONTROL_OFFSET] = DEVADDR((ch) ? 0xDA : 0x9A);
#else /* ! SIIMAGE_BUFFERED_TASKFILE */
	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
		hw.io_ports[i] = DEVADDR((ch) ? 0xC0 : 0x80)|(i);
	hw.io_ports[IDE_CONTROL_OFFSET] = DEVADDR((ch) ? 0xCA : 0x8A);
#endif /* SIIMAGE_BUFFERED_TASKFILE */
#endif

#if 0
	printk(KERN_DEBUG "%s: ", hwif->name);
	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
		printk("0x%08x ", DEVADDR((ch) ? 0xC0 : 0x80)|(i));
	printk("0x%08x ", DEVADDR((ch) ? 0xCA : 0x8A)|(i));
#endif

	hw.io_ports[IDE_IRQ_OFFSET]	= 0;

        if (dev->device == PCI_DEVICE_ID_SII_3112) {
		hw.sata_scr[SATA_STATUS_OFFSET]	= DEVADDR((ch) ? 0x184 : 0x104);
		hw.sata_scr[SATA_ERROR_OFFSET]	= DEVADDR((ch) ? 0x188 : 0x108);
		hw.sata_scr[SATA_CONTROL_OFFSET]= DEVADDR((ch) ? 0x180 : 0x100);
		hw.sata_misc[SATA_MISC_OFFSET]	= DEVADDR((ch) ? 0x1C0 : 0x140);
		hw.sata_misc[SATA_PHY_OFFSET]	= DEVADDR((ch) ? 0x1C4 : 0x144);
		hw.sata_misc[SATA_IEN_OFFSET]	= DEVADDR((ch) ? 0x1C8 : 0x148);
	}

	hw.priv				= (void *) addr;
//	hw.priv				= pci_get_drvdata(hwif->pci_dev);
	hw.irq				= hwif->pci_dev->irq;

	memcpy(&hwif->hw, &hw, sizeof(hw));
	memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports));

	if (hwif->pci_dev->device == PCI_DEVICE_ID_SII_3112) {
		memcpy(hwif->sata_scr, hwif->hw.sata_scr, sizeof(hwif->hw.sata_scr));
		memcpy(hwif->sata_misc, hwif->hw.sata_misc, sizeof(hwif->hw.sata_misc));
	}

#ifdef SIIMAGE_BUFFERED_TASKFILE
        hwif->addressing = 1;
#endif /* SIIMAGE_BUFFERED_TASKFILE */
	hwif->irq			= hw.irq;
	hwif->hwif_data			= pci_get_drvdata(hwif->pci_dev);

#ifdef SIIMAGE_LARGE_DMA
	hwif->dma_base			= DEVADDR((ch) ? 0x18 : 0x10);
	hwif->dma_base2			= DEVADDR((ch) ? 0x08 : 0x00);
	hwif->dma_prdtable		= (hwif->dma_base2 + 4);
#else /* ! SIIMAGE_LARGE_DMA */
	hwif->dma_base			= DEVADDR((ch) ? 0x08 : 0x00);
	hwif->dma_base2			= DEVADDR((ch) ? 0x18 : 0x10);
#endif /* SIIMAGE_LARGE_DMA */
	hwif->mmio			= 2;
}
Пример #13
0
/*
 * swarm_ide_probe - if the board header indicates the existence of
 * Generic Bus IDE, allocate a HWIF for it.
 */
static int __devinit swarm_ide_probe(struct device *dev)
{
    ide_hwif_t *hwif;
    u8 __iomem *base;
    phys_t offset, size;
    hw_regs_t hw;
    int i;
    u8 idx[] = { 0xff, 0xff, 0xff, 0xff };

    if (!SIBYTE_HAVE_IDE)
        return -ENODEV;

    hwif = ide_find_port();
    if (hwif == NULL) {
        printk(KERN_ERR DRV_NAME ": no free slot for interface\n");
        return -ENOMEM;
    }

    base = ioremap(A_IO_EXT_BASE, 0x800);
    offset = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_START_ADDR, IDE_CS));
    size = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_MULT_SIZE, IDE_CS));
    iounmap(base);

    offset = G_IO_START_ADDR(offset) << S_IO_ADDRBASE;
    size = (G_IO_MULT_SIZE(size) + 1) << S_IO_REGSIZE;
    if (offset < A_PHYS_GENBUS || offset >= A_PHYS_GENBUS_END) {
        printk(KERN_INFO DRV_NAME
               ": IDE interface at GenBus disabled\n");
        return -EBUSY;
    }

    printk(KERN_INFO DRV_NAME ": IDE interface at GenBus slot %i\n",
           IDE_CS);

    swarm_ide_resource.start = offset;
    swarm_ide_resource.end = offset + size - 1;
    if (request_resource(&iomem_resource, &swarm_ide_resource)) {
        printk(KERN_ERR DRV_NAME
               ": can't request I/O memory resource\n");
        return -EBUSY;
    }

    base = ioremap(offset, size);

    /* Setup MMIO ops.  */
    hwif->host_flags = IDE_HFLAG_MMIO;
    default_hwif_mmiops(hwif);

    for (i = 0; i <= 7; i++)
        hw.io_ports_array[i] =
                (unsigned long)(base + ((0x1f0 + i) << 5));
    hw.io_ports.ctl_addr =
                (unsigned long)(base + (0x3f6 << 5));
    hw.irq = K_INT_GB_IDE;
    hw.chipset = ide_generic;

    ide_init_port_hw(hwif, &hw);

    idx[0] = hwif->index;

    ide_device_add(idx, NULL);

    dev_set_drvdata(dev, hwif);

    return 0;
}
Пример #14
0
static int __devinit palm_bk3710_probe(struct platform_device *pdev)
{
	struct clk *clk;
	struct resource *mem, *irq;
	ide_hwif_t *hwif;
	unsigned long base, rate;
	int i;
	hw_regs_t hw;
	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };

	clk = clk_get(&pdev->dev, "IDECLK");
	if (IS_ERR(clk))
		return -ENODEV;

	clk_enable(clk);
	rate = clk_get_rate(clk);
	ideclk_period = 1000000000UL / rate;

	/* Register the IDE interface with Linux ATA Interface */
	memset(&hw, 0, sizeof(hw));

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (mem == NULL) {
		printk(KERN_ERR "failed to get memory region resource\n");
		return -ENODEV;
	}

	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (irq == NULL) {
		printk(KERN_ERR "failed to get IRQ resource\n");
		return -ENODEV;
	}

	if (request_mem_region(mem->start, mem->end - mem->start + 1,
			       "palm_bk3710") == NULL) {
		printk(KERN_ERR "failed to request memory region\n");
		return -EBUSY;
	}

	base = IO_ADDRESS(mem->start);

	/* Configure the Palm Chip controller */
	palm_bk3710_chipinit((void __iomem *)base);

	for (i = 0; i < IDE_NR_PORTS - 2; i++)
		hw.io_ports[i] = base + IDE_PALM_ATA_PRI_REG_OFFSET + i;
	hw.io_ports[IDE_CONTROL_OFFSET] = base + IDE_PALM_ATA_PRI_CTL_OFFSET;
	hw.irq = irq->start;
	hw.chipset = ide_palm3710;

	hwif = ide_deprecated_find_port(hw.io_ports[IDE_DATA_OFFSET]);
	if (hwif == NULL)
		goto out;

	i = hwif->index;

	if (hwif->present)
		ide_unregister(i, 0, 1);
	else if (!hwif->hold)
		ide_init_port_data(hwif, i);

	ide_init_port_hw(hwif, &hw);
	hwif->fixup = NULL;

	hwif->tuneproc	= &palm_bk3710_tune_drive;
	hwif->speedproc = &palm_bk3710_tune_chipset;
	hwif->mmio = 2;
	default_hwif_mmiops(hwif);

	if (rate >= 100000000)
		hwif->ultra_mask = 0x3f;  /* UDMA Mode 5 */
	else
		hwif->ultra_mask = 0x1f;  /* UDMA Mode 4 */
	hwif->mwdma_mask = 0x7;
	hwif->drives[0].autotune = 1;
	hwif->drives[1].autotune = 1;

	hwif->ide_dma_check = &palm_bk3710_config_drive_xfer_rate;
	hwif->udma_four = 1;

	if (!noautodma)
		hwif->autodma = 1;
	hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma;

	ide_setup_dma(hwif, base, 8);

	idx[0] = i;

	ide_device_add(idx);

	if (!hwif->present)
		goto out;

	return 0;
out:
	printk(KERN_WARNING "Palm Chip BK3710 IDE Register Fail\n");
	return -ENODEV;
}