17f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz#include <linux/kernel.h>
238789fda295689689d064c0157bc363b1837b5e6Paul Gortmaker#include <linux/export.h>
37f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz#include <linux/ide.h>
47f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz
59f36d31437922354d104a2db407f397e79e4027eBartlomiej Zolnierkiewiczstatic void ide_legacy_init_one(struct ide_hw **hws, struct ide_hw *hw,
67f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz				u8 port_no, const struct ide_port_info *d,
77f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz				unsigned long config)
87f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz{
97f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz	unsigned long base, ctl;
107f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz	int irq;
117f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz
127f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz	if (port_no == 0) {
137f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz		base = 0x1f0;
147f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz		ctl  = 0x3f6;
157f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz		irq  = 14;
167f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz	} else {
177f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz		base = 0x170;
187f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz		ctl  = 0x376;
197f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz		irq  = 15;
207f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz	}
217f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz
227f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz	if (!request_region(base, 8, d->name)) {
237f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz		printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n",
247f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz				d->name, base, base + 7);
257f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz		return;
267f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz	}
277f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz
287f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz	if (!request_region(ctl, 1, d->name)) {
297f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz		printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n",
307f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz				d->name, ctl);
317f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz		release_region(base, 8);
327f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz		return;
337f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz	}
347f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz
357f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz	ide_std_init_ports(hw, base, ctl);
367f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz	hw->irq = irq;
377f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz	hw->config = config;
387f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz
397f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz	hws[port_no] = hw;
407f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz}
417f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz
427f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewiczint ide_legacy_device_add(const struct ide_port_info *d, unsigned long config)
437f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz{
449f36d31437922354d104a2db407f397e79e4027eBartlomiej Zolnierkiewicz	struct ide_hw hw[2], *hws[] = { NULL, NULL };
457f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz
467f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz	memset(&hw, 0, sizeof(hw));
477f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz
487f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz	if ((d->host_flags & IDE_HFLAG_QD_2ND_PORT) == 0)
497f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz		ide_legacy_init_one(hws, &hw[0], 0, d, config);
507f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz	ide_legacy_init_one(hws, &hw[1], 1, d, config);
517f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz
527f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz	if (hws[0] == NULL && hws[1] == NULL &&
537f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz	    (d->host_flags & IDE_HFLAG_SINGLE))
547f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz		return -ENOENT;
557f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz
56dca3983059a4481e4ae97bbf0ac4b4c21429e1a5Bartlomiej Zolnierkiewicz	return ide_host_add(d, hws, 2, NULL);
577f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej Zolnierkiewicz}
587f92b11c1cc0e865fc64f3148eda87fff74920e1Bartlomiej ZolnierkiewiczEXPORT_SYMBOL_GPL(ide_legacy_device_add);
59