示例#1
0
int ide_register_hw_with_fixup(hw_regs_t *hw, int initializing,
			       ide_hwif_t **hwifp,
			       void(*fixup)(ide_hwif_t *hwif))
{
	int index, retry = 1;
	ide_hwif_t *hwif;
	do {
		for (index = 0; index < MAX_HWIFS; ++index) {
			hwif = &ide_hwifs[index];
			if (hwif->hw.io_ports[IDE_DATA_OFFSET] == hw->io_ports[IDE_DATA_OFFSET])
				goto found;
		}
		for (index = 0; index < MAX_HWIFS; ++index) {
			hwif = &ide_hwifs[index];
			if (hwif->hold)
				continue;
			if ((!hwif->present && !hwif->mate && !initializing) ||
			    (!hwif->hw.io_ports[IDE_DATA_OFFSET] && initializing))
				goto found;
		}
		for (index = 0; index < MAX_HWIFS; index++)
			ide_unregister(index);
	} while (retry--);
	return -1;
found:
	if (hwif->present){
		ide_unregister(index);
	}
	else if (!hwif->hold) {
		init_hwif_data(hwif, index);
		init_hwif_default(hwif, index);
	}
	if (hwif->present)
		return -1;
	memcpy(&hwif->hw, hw, sizeof(*hw));
	memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports));
	hwif->irq = hw->irq;
	hwif->noprobe = 0;
	hwif->chipset = hw->chipset;
	hwif->gendev.parent = hw->dev;

	if (!initializing) {
		probe_hwif_init_with_fixup(hwif, fixup);
		ide_proc_register_port(hwif);
	}

	if (hwifp)
		*hwifp = hwif;
	return (initializing || hwif->present) ? index : -1;
}
示例#2
0
文件: sgiioc4.c 项目: Mr-Aloof/wl500g
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;
}