示例#1
0
/* Can be called directly from ide.c. */
int __init ht6560b_init(void)
{
	ide_hwif_t *hwif, *mate;
	static u8 idx[4] = { 0, 1, 0xff, 0xff };
	int t;

	if (probe_ht6560b == 0)
		return -ENODEV;

	hwif = &ide_hwifs[0];
	mate = &ide_hwifs[1];

	if (!request_region(HT_CONFIG_PORT, 1, hwif->name)) {
		printk(KERN_NOTICE "%s: HT_CONFIG_PORT not found\n",
			__FUNCTION__);
		return -ENODEV;
	}

	if (!try_to_init_ht6560b()) {
		printk(KERN_NOTICE "%s: HBA not found\n", __FUNCTION__);
		goto release_region;
	}

	hwif->chipset = ide_ht6560b;
	hwif->selectproc = &ht6560b_selectproc;
	hwif->host_flags = IDE_HFLAG_ABUSE_PREFETCH;
	hwif->pio_mask = ATA_PIO5;
	hwif->set_pio_mode = &ht6560b_set_pio_mode;
	hwif->serialized = 1;	/* is this needed? */
	hwif->mate = mate;

	mate->chipset = ide_ht6560b;
	mate->selectproc = &ht6560b_selectproc;
	mate->host_flags = IDE_HFLAG_ABUSE_PREFETCH;
	mate->pio_mask = ATA_PIO5;
	mate->set_pio_mode = &ht6560b_set_pio_mode;
	mate->serialized = 1;	/* is this needed? */
	mate->mate = hwif;
	mate->channel = 1;

	/*
	 * Setting default configurations for drives
	 */
	t = (HT_CONFIG_DEFAULT << 8);
	t |= HT_TIMING_DEFAULT;
	hwif->drives[0].drive_data = t;
	hwif->drives[1].drive_data = t;

	t |= (HT_SECONDARY_IF << 8);
	mate->drives[0].drive_data = t;
	mate->drives[1].drive_data = t;

	ide_device_add(idx);

	return 0;

release_region:
	release_region(HT_CONFIG_PORT, 1);
	return -ENODEV;
}
示例#2
0
文件: ide-cs.c 项目: Tigrouzen/k1099
static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle)
{
    ide_hwif_t *hwif;
    hw_regs_t hw;
    int i;
    u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };

    memset(&hw, 0, sizeof(hw));
    ide_std_init_ports(&hw, io, ctl);
    hw.irq = irq;
    hw.chipset = ide_pci;
    hw.dev = &handle->dev;

    hwif = ide_deprecated_find_port(hw.io_ports[IDE_DATA_OFFSET]);
    if (hwif == NULL)
	return -1;

    i = hwif->index;

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

    ide_init_port_hw(hwif, &hw);
    hwif->quirkproc = &ide_undecoded_slave;

    idx[0] = i;

    ide_device_add(idx, NULL);

    return hwif->present ? i : -1;
}
示例#3
0
文件: ide-cs.c 项目: 274914765/C
static ide_hwif_t *idecs_register(unsigned long io, unsigned long ctl,
                unsigned long irq, struct pcmcia_device *handle)
{
    ide_hwif_t *hwif;
    hw_regs_t hw;
    int i;
    u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };

    if (!request_region(io, 8, DRV_NAME)) {
    printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n",
            DRV_NAME, io, io + 7);
    return NULL;
    }

    if (!request_region(ctl, 1, DRV_NAME)) {
    printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n",
            DRV_NAME, ctl);
    release_region(io, 8);
    return NULL;
    }

    memset(&hw, 0, sizeof(hw));
    ide_std_init_ports(&hw, io, ctl);
    hw.irq = irq;
    hw.chipset = ide_pci;
    hw.dev = &handle->dev;

    hwif = ide_find_port();
    if (hwif == NULL)
    goto out_release;

    i = hwif->index;

    ide_init_port_data(hwif, i);
    ide_init_port_hw(hwif, &hw);
    hwif->port_ops = &idecs_port_ops;

    idx[0] = i;

    ide_device_add(idx, NULL);

    if (hwif->present)
    return hwif;

    /* retry registration in case device is still spinning up */
    for (i = 0; i < 10; i++) {
    msleep(100);
    ide_port_scan(hwif);
    if (hwif->present)
        return hwif;
    }

    return hwif;

out_release:
    release_region(ctl, 1);
    release_region(io, 8);
    return NULL;
}
示例#4
0
static int __devinit
delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id)
{
	unsigned long base;
	hw_regs_t hw;
	ide_hwif_t *hwif = NULL;
	int i, rc;
	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };

	rc = pci_enable_device(dev);
	if (rc) {
		printk(KERN_ERR "delkin_cb: pci_enable_device failed (%d)\n", rc);
		return rc;
	}
	rc = pci_request_regions(dev, "delkin_cb");
	if (rc) {
		printk(KERN_ERR "delkin_cb: pci_request_regions failed (%d)\n", rc);
		pci_disable_device(dev);
		return rc;
	}
	base = pci_resource_start(dev, 0);
	outb(0x02, base + 0x1e);	/* set nIEN to block interrupts */
	inb(base + 0x17);		/* read status to clear interrupts */
	for (i = 0; i < sizeof(setup); ++i) {
		if (setup[i])
			outb(setup[i], base + i);
	}

	memset(&hw, 0, sizeof(hw));
	ide_std_init_ports(&hw, base + 0x10, base + 0x1e);
	hw.irq = dev->irq;
	hw.dev = &dev->dev;
	hw.chipset = ide_pci;		/* this enables IRQ sharing */

	hwif = ide_find_port();
	if (hwif == NULL)
		goto out_disable;

	i = hwif->index;

	ide_init_port_data(hwif, i);
	ide_init_port_hw(hwif, &hw);

	idx[0] = i;

	ide_device_add(idx, &delkin_cb_port_info);

	pci_set_drvdata(dev, hwif);

	return 0;

out_disable:
	pci_release_regions(dev);
	pci_disable_device(dev);
	return -ENODEV;
}
static int __init ide_4drives_init(void)
{
	ide_hwif_t *hwif, *mate;
	unsigned long base = 0x1f0, ctl = 0x3f6;
	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
	hw_regs_t hw;

	if (probe_4drives == 0)
		return -ENODEV;

	if (!request_region(base, 8, DRV_NAME)) {
		printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n",
				DRV_NAME, base, base + 7);
		return -EBUSY;
	}

	if (!request_region(ctl, 1, DRV_NAME)) {
		printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n",
				DRV_NAME, ctl);
		release_region(base, 8);
		return -EBUSY;
	}

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

	ide_std_init_ports(&hw, base, ctl);
	hw.irq = 14;
	hw.chipset = ide_4drives;

	hwif = ide_find_port();
	if (hwif) {
		ide_init_port_hw(hwif, &hw);
		idx[0] = hwif->index;
	}

	mate = ide_find_port();
	if (mate) {
		ide_init_port_hw(mate, &hw);
		mate->drives[0].select.all ^= 0x20;
		mate->drives[1].select.all ^= 0x20;
		idx[1] = mate->index;

		if (hwif) {
			hwif->mate = mate;
			mate->mate = hwif;
			hwif->serialized = mate->serialized = 1;
		}
	}

	ide_device_add(idx, NULL);

	return 0;
}
示例#6
0
文件: ide-pnp.c 项目: 274914765/C
static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
{
    hw_regs_t hw;
    ide_hwif_t *hwif;
    unsigned long base, ctl;

    if (!(pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && pnp_irq_valid(dev, 0)))
        return -1;

    base = pnp_port_start(dev, 0);
    ctl = pnp_port_start(dev, 1);

    if (!request_region(base, 8, DRV_NAME)) {
        printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n",
                DRV_NAME, base, base + 7);
        return -EBUSY;
    }

    if (!request_region(ctl, 1, DRV_NAME)) {
        printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n",
                DRV_NAME, ctl);
        release_region(base, 8);
        return -EBUSY;
    }

    memset(&hw, 0, sizeof(hw));
    ide_std_init_ports(&hw, base, ctl);
    hw.irq = pnp_irq(dev, 0);
    hw.chipset = ide_generic;

    hwif = ide_find_port();
    if (hwif) {
        u8 index = hwif->index;
        u8 idx[4] = { index, 0xff, 0xff, 0xff };

        ide_init_port_data(hwif, index);
        ide_init_port_hw(hwif, &hw);

        printk(KERN_INFO "ide%d: generic PnP IDE interface\n", index);
        pnp_set_drvdata(dev, hwif);

        ide_device_add(idx, NULL);

        return 0;
    }

    release_region(ctl, 1);
    release_region(base, 8);

    return -1;
}
示例#7
0
static int __init dtc2278_probe(void)
{
	unsigned long flags;
	ide_hwif_t *hwif, *mate;
	static u8 idx[4] = { 0, 1, 0xff, 0xff };

	hwif = &ide_hwifs[0];
	mate = &ide_hwifs[1];

	if (hwif->chipset != ide_unknown || mate->chipset != ide_unknown)
		return 1;

	local_irq_save(flags);
	/*
	 * This enables the second interface
	 */
	outb_p(4,0xb0);
	inb(0x3f6);
	outb_p(0x20,0xb4);
	inb(0x3f6);
#ifdef ALWAYS_SET_DTC2278_PIO_MODE
	/*
	 * This enables PIO mode4 (3?) on the first interface
	 * and may solve start-up problems for some people.
	 */
	sub22(1,0xc3);
	sub22(0,0xa0);
#endif
	local_irq_restore(flags);

	hwif->serialized = 1;
	hwif->chipset = ide_dtc2278;
	hwif->pio_mask = ATA_PIO4;
	hwif->set_pio_mode = &dtc2278_set_pio_mode;
	hwif->drives[0].no_unmask = 1;
	hwif->drives[1].no_unmask = 1;
	hwif->mate = mate;

	mate->serialized = 1;
	mate->chipset = ide_dtc2278;
	mate->pio_mask = ATA_PIO4;
	mate->drives[0].no_unmask = 1;
	mate->drives[1].no_unmask = 1;
	mate->mate = hwif;
	mate->channel = 1;

	ide_device_add(idx);

	return 0;
}
示例#8
0
文件: macide.c 项目: 274914765/C
static int __init macide_init(void)
{
    ide_hwif_t *hwif;
    ide_ack_intr_t *ack_intr;
    unsigned long base;
    int irq;
    hw_regs_t hw;

    if (!MACH_IS_MAC)
        return -ENODEV;

    switch (macintosh_config->ide_type) {
    case MAC_IDE_QUADRA:
        base = IDE_BASE;
        ack_intr = macide_ack_intr;
        irq = IRQ_NUBUS_F;
        break;
    case MAC_IDE_PB:
        base = IDE_BASE;
        ack_intr = macide_ack_intr;
        irq = IRQ_NUBUS_C;
        break;
    case MAC_IDE_BABOON:
        base = BABOON_BASE;
        ack_intr = NULL;
        irq = IRQ_BABOON_1;
        break;
    default:
        return -ENODEV;
    }

    printk(KERN_INFO "ide: Macintosh %s IDE controller\n",
             mac_ide_name[macintosh_config->ide_type - 1]);

    macide_setup_ports(&hw, base, irq, ack_intr);

    hwif = ide_find_port();
    if (hwif) {
        u8 index = hwif->index;
        u8 idx[4] = { index, 0xff, 0xff, 0xff };

        ide_init_port_data(hwif, index);
        ide_init_port_hw(hwif, &hw);

        ide_device_add(idx, NULL);
    }

    return 0;
}
示例#9
0
static int __devinit
rapide_probe(struct expansion_card *ec, const struct ecard_id *id)
{
	ide_hwif_t *hwif;
	void __iomem *base;
	int ret;
	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };

	ret = ecard_request_resources(ec);
	if (ret)
		goto out;

	base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0);
	if (!base) {
		ret = -ENOMEM;
		goto release;
	}

	hwif = rapide_locate_hwif(base, base + 0x818, 1 << 6, ec->irq);
	if (hwif) {
		hwif->hwif_data = base;
		hwif->gendev.parent = &ec->dev;
		hwif->noprobe = 0;

		idx[0] = hwif->index;

		ide_device_add(idx);

		ecard_set_drvdata(ec, hwif);
		goto out;
	}

 release:
	ecard_release_resources(ec);
 out:
	return ret;
}
示例#10
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;
}
示例#11
0
static int __init gayle_init(void)
{
    int a4000, i;
    u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };

    if (!MACH_IS_AMIGA)
        return -ENODEV;

    if ((a4000 = AMIGAHW_PRESENT(A4000_IDE)) || AMIGAHW_PRESENT(A1200_IDE))
        goto found;

#ifdef CONFIG_ZORRO
    if (zorro_find_device(ZORRO_PROD_MTEC_VIPER_MK_V_E_MATRIX_530_SCSI_IDE,
                          NULL))
        goto found;
#endif
    return -ENODEV;

found:
    printk(KERN_INFO "ide: Gayle IDE controller (A%d style%s)\n",
           a4000 ? 4000 : 1200,
#ifdef CONFIG_BLK_DEV_IDEDOUBLER
           ide_doubler ? ", IDE doubler" :
#endif
           "");

    for (i = 0; i < GAYLE_NUM_PROBE_HWIFS; i++) {
        unsigned long base, ctrlport, irqport;
        ide_ack_intr_t *ack_intr;
        hw_regs_t hw;
        ide_hwif_t *hwif;
        unsigned long phys_base, res_start, res_n;

        if (a4000) {
            phys_base = GAYLE_BASE_4000;
            irqport = (unsigned long)ZTWO_VADDR(GAYLE_IRQ_4000);
            ack_intr = gayle_ack_intr_a4000;
        } else {
            phys_base = GAYLE_BASE_1200;
            irqport = (unsigned long)ZTWO_VADDR(GAYLE_IRQ_1200);
            ack_intr = gayle_ack_intr_a1200;
        }
        /*
         * FIXME: we now have selectable modes between mmio v/s iomio
         */

        phys_base += i*GAYLE_NEXT_PORT;

        res_start = ((unsigned long)phys_base) & ~(GAYLE_NEXT_PORT-1);
        res_n = GAYLE_IDEREG_SIZE;

        if (!request_mem_region(res_start, res_n, "IDE"))
            continue;

        base = (unsigned long)ZTWO_VADDR(phys_base);
        ctrlport = GAYLE_HAS_CONTROL_REG ? (base + GAYLE_CONTROL) : 0;

        gayle_setup_ports(&hw, base, ctrlport, irqport, ack_intr);

        hwif = ide_find_port();
        if (hwif) {
            u8 index = hwif->index;

            ide_init_port_hw(hwif, &hw);

            idx[i] = index;
        } else
            release_mem_region(res_start, res_n);
    }

    ide_device_add(idx, NULL);

    return 0;
}
示例#12
0
文件: buddha.c 项目: Tigrouzen/k1099
static int __init buddha_init(void)
{
	hw_regs_t hw;
	ide_hwif_t *hwif;
	int i;

	struct zorro_dev *z = NULL;
	u_long buddha_board = 0;
	BuddhaType type;
	int buddha_num_hwifs;

	while ((z = zorro_find_device(ZORRO_WILDCARD, z))) {
		unsigned long board;
		u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };

		if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA) {
			buddha_num_hwifs = BUDDHA_NUM_HWIFS;
			type=BOARD_BUDDHA;
		} else if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_CATWEASEL) {
			buddha_num_hwifs = CATWEASEL_NUM_HWIFS;
			type=BOARD_CATWEASEL;
		} else if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF) {
			buddha_num_hwifs = XSURF_NUM_HWIFS;
			type=BOARD_XSURF;
		} else 
			continue;
		
		board = z->resource.start;

/*
 * FIXME: we now have selectable mmio v/s iomio transports.
 */

		if(type != BOARD_XSURF) {
			if (!request_mem_region(board+BUDDHA_BASE1, 0x800, "IDE"))
				continue;
		} else {
			if (!request_mem_region(board+XSURF_BASE1, 0x1000, "IDE"))
				continue;
			if (!request_mem_region(board+XSURF_BASE2, 0x1000, "IDE"))
				goto fail_base2;
			if (!request_mem_region(board+XSURF_IRQ1, 0x8, "IDE")) {
				release_mem_region(board+XSURF_BASE2, 0x1000);
fail_base2:
				release_mem_region(board+XSURF_BASE1, 0x1000);
				continue;
			}
		}	  
		buddha_board = ZTWO_VADDR(board);
		
		/* write to BUDDHA_IRQ_MR to enable the board IRQ */
		/* X-Surf doesn't have this.  IRQs are always on */
		if (type != BOARD_XSURF)
			z_writeb(0, buddha_board+BUDDHA_IRQ_MR);

		printk(KERN_INFO "ide: %s IDE controller\n",
				 buddha_board_name[type]);

		for (i = 0; i < buddha_num_hwifs; i++) {
			unsigned long base, ctl, irq_port;
			ide_ack_intr_t *ack_intr;

			if (type != BOARD_XSURF) {
				base = buddha_board + buddha_bases[i];
				ctl = base + BUDDHA_CONTROL;
				irq_port = buddha_board + buddha_irqports[i];
				ack_intr = buddha_ack_intr;
			} else {
				base = buddha_board + xsurf_bases[i];
				/* X-Surf has no CS1* (Control/AltStat) */
				ctl = 0;
				irq_port = buddha_board + xsurf_irqports[i];
				ack_intr = xsurf_ack_intr;
			}

			buddha_setup_ports(&hw, base, ctl, irq_port, ack_intr);

			hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
			if (hwif) {
				u8 index = hwif->index;

				ide_init_port_data(hwif, index);
				ide_init_port_hw(hwif, &hw);

				hwif->mmio = 1;

				idx[i] = index;
			}
		}

		ide_device_add(idx, NULL);
	}

	return 0;
}
示例#13
0
文件: sgiioc4.c 项目: maraz/linux-2.6
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;
}
示例#14
0
文件: swarm.c 项目: 274914765/C
/*
 * 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;
}
示例#15
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;
}