11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
259bca8cc995428c34d8cdfadfa87c8e3f01c4340Bartlomiej Zolnierkiewicz *  Copyright (C) 1994-1998	    Linus Torvalds & authors (see below)
3fc410698ebf7abfb64f0e2337b871298557f0575Pavel Machek *  Copyright (C) 2003-2005, 2007   Bartlomiej Zolnierkiewicz
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  Mostly written by Mark Lord  <mlord@pobox.com>
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *                and Gadi Oxman <gadio@netvision.net.il>
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *                and Andre Hedrick <andre@linux-ide.org>
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  See linux/MAINTAINERS for address of current maintainer.
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This is the multiple IDE interface driver, as evolved from hd.c.
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * It supports up to MAX_HWIFS IDE interfaces, on one or more IRQs
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *   (usually 14 & 15).
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * There can be up to two drives per interface, as per the ATA-2 spec.
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ...
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  From hd.c:
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  |
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  | It traverses the request-list, using interrupts to jump between functions.
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  | As nearly all functions can be called within interrupts, we may not sleep.
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  | Special care is recommended.  Have Fun!
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  |
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  | modified by Drew Eckhardt to check nr of hd's from the CMOS.
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  |
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  | Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  | in the early extended-partition checks and added DM partitions.
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  |
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  | Early work on error handling by Mika Liljeberg (liljeber@cs.Helsinki.FI).
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  |
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  | IRQ-unmask, drive-id, multiple-mode, support for ">16 heads",
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  | and general streamlining by Mark Lord (mlord@pobox.com).
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  October, 1994 -- Complete line-by-line overhaul for linux 1.1.x, by:
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	Mark Lord	(mlord@pobox.com)		(IDE Perf.Pkg)
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	Delman Lee	(delman@ieee.org)		("Mr. atdisk2")
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	Scott Snyder	(snyder@fnald0.fnal.gov)	(ATAPI IDE cd-rom)
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  This was a rewrite of just about everything from hd.c, though some original
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  code is still sprinkled about.  Think of it as a major evolution, with
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  inspiration from lots of linux users, esp.  hamish@zot.apana.org.au
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h>
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/types.h>
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/string.h>
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h>
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/interrupt.h>
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/major.h>
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/errno.h>
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/genhd.h>
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h>
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/pci.h>
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/ide.h>
583ceca727fe3a38dd8d7a3adf938fefda83eee8afBartlomiej Zolnierkiewicz#include <linux/hdreg.h>
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/completion.h>
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/device.h>
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
62f74c91413ec6140ee0553180c5f56fdd27c22a2eBartlomiej Zolnierkiewiczstruct class *ide_port_class;
63f74c91413ec6140ee0553180c5f56fdd27c22a2eBartlomiej Zolnierkiewicz
6408da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz/**
6508da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz * ide_device_get	-	get an additional reference to a ide_drive_t
6608da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz * @drive:	device to get a reference to
6708da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz *
6808da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz * Gets a reference to the ide_drive_t and increments the use count of the
6908da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz * underlying LLDD module.
7008da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz */
7108da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewiczint ide_device_get(ide_drive_t *drive)
7208da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz{
7308da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz	struct device *host_dev;
7408da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz	struct module *module;
7508da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz
7608da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz	if (!get_device(&drive->gendev))
7708da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz		return -ENXIO;
7808da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz
7908da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz	host_dev = drive->hwif->host->dev[0];
8008da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz	module = host_dev ? host_dev->driver->owner : NULL;
8108da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz
8208da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz	if (module && !try_module_get(module)) {
8308da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz		put_device(&drive->gendev);
8408da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz		return -ENXIO;
8508da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz	}
8608da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz
8708da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz	return 0;
8808da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz}
8908da591e14cf87247ec09b17c350235157a92fc3Bartlomiej ZolnierkiewiczEXPORT_SYMBOL_GPL(ide_device_get);
9008da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz
9108da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz/**
9208da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz * ide_device_put	-	release a reference to a ide_drive_t
9308da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz * @drive:	device to release a reference on
9408da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz *
9508da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz * Release a reference to the ide_drive_t and decrements the use count of
9608da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz * the underlying LLDD module.
9708da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz */
9808da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewiczvoid ide_device_put(ide_drive_t *drive)
9908da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz{
10008da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz#ifdef CONFIG_MODULE_UNLOAD
10108da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz	struct device *host_dev = drive->hwif->host->dev[0];
10208da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz	struct module *module = host_dev ? host_dev->driver->owner : NULL;
10308da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz
10408da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz	if (module)
10508da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz		module_put(module);
10608da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz#endif
10708da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz	put_device(&drive->gendev);
10808da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz}
10908da591e14cf87247ec09b17c350235157a92fc3Bartlomiej ZolnierkiewiczEXPORT_SYMBOL_GPL(ide_device_put);
11008da591e14cf87247ec09b17c350235157a92fc3Bartlomiej Zolnierkiewicz
1118604affde9d4f52f04342d6a37c77d95fa167e7aBartlomiej Zolnierkiewiczstatic int ide_bus_match(struct device *dev, struct device_driver *drv)
1128604affde9d4f52f04342d6a37c77d95fa167e7aBartlomiej Zolnierkiewicz{
1138604affde9d4f52f04342d6a37c77d95fa167e7aBartlomiej Zolnierkiewicz	return 1;
1148604affde9d4f52f04342d6a37c77d95fa167e7aBartlomiej Zolnierkiewicz}
1158604affde9d4f52f04342d6a37c77d95fa167e7aBartlomiej Zolnierkiewicz
1167eff2e7a8b65c25920207324e56611150eb1cd9aKay Sieversstatic int ide_uevent(struct device *dev, struct kobj_uevent_env *env)
117263756ec228f1cdd49fc50b1f87001a4cebdfe12Kay Sievers{
118263756ec228f1cdd49fc50b1f87001a4cebdfe12Kay Sievers	ide_drive_t *drive = to_ide_device(dev);
1197eff2e7a8b65c25920207324e56611150eb1cd9aKay Sievers
120ebdab07dad3d3a008e519b0a028e1e1ad5ecaef0Bartlomiej Zolnierkiewicz	add_uevent_var(env, "MEDIA=%s", ide_media_string(drive));
1217eff2e7a8b65c25920207324e56611150eb1cd9aKay Sievers	add_uevent_var(env, "DRIVENAME=%s", drive->name);
122ebdab07dad3d3a008e519b0a028e1e1ad5ecaef0Bartlomiej Zolnierkiewicz	add_uevent_var(env, "MODALIAS=ide:m-%s", ide_media_string(drive));
123263756ec228f1cdd49fc50b1f87001a4cebdfe12Kay Sievers	return 0;
124263756ec228f1cdd49fc50b1f87001a4cebdfe12Kay Sievers}
125263756ec228f1cdd49fc50b1f87001a4cebdfe12Kay Sievers
1264031bbe4bbec6c0fe50412ef7fb43a270b0f29f1Russell Kingstatic int generic_ide_probe(struct device *dev)
1274031bbe4bbec6c0fe50412ef7fb43a270b0f29f1Russell King{
1284031bbe4bbec6c0fe50412ef7fb43a270b0f29f1Russell King	ide_drive_t *drive = to_ide_device(dev);
1297f3c868ba78e486bd9d7569f884dd46d8f59bb18Bartlomiej Zolnierkiewicz	struct ide_driver *drv = to_ide_driver(dev->driver);
1304031bbe4bbec6c0fe50412ef7fb43a270b0f29f1Russell King
1314031bbe4bbec6c0fe50412ef7fb43a270b0f29f1Russell King	return drv->probe ? drv->probe(drive) : -ENODEV;
1324031bbe4bbec6c0fe50412ef7fb43a270b0f29f1Russell King}
1334031bbe4bbec6c0fe50412ef7fb43a270b0f29f1Russell King
1344031bbe4bbec6c0fe50412ef7fb43a270b0f29f1Russell Kingstatic int generic_ide_remove(struct device *dev)
1354031bbe4bbec6c0fe50412ef7fb43a270b0f29f1Russell King{
1364031bbe4bbec6c0fe50412ef7fb43a270b0f29f1Russell King	ide_drive_t *drive = to_ide_device(dev);
1377f3c868ba78e486bd9d7569f884dd46d8f59bb18Bartlomiej Zolnierkiewicz	struct ide_driver *drv = to_ide_driver(dev->driver);
1384031bbe4bbec6c0fe50412ef7fb43a270b0f29f1Russell King
1394031bbe4bbec6c0fe50412ef7fb43a270b0f29f1Russell King	if (drv->remove)
1404031bbe4bbec6c0fe50412ef7fb43a270b0f29f1Russell King		drv->remove(drive);
1414031bbe4bbec6c0fe50412ef7fb43a270b0f29f1Russell King
1424031bbe4bbec6c0fe50412ef7fb43a270b0f29f1Russell King	return 0;
1434031bbe4bbec6c0fe50412ef7fb43a270b0f29f1Russell King}
1444031bbe4bbec6c0fe50412ef7fb43a270b0f29f1Russell King
1454031bbe4bbec6c0fe50412ef7fb43a270b0f29f1Russell Kingstatic void generic_ide_shutdown(struct device *dev)
1464031bbe4bbec6c0fe50412ef7fb43a270b0f29f1Russell King{
1474031bbe4bbec6c0fe50412ef7fb43a270b0f29f1Russell King	ide_drive_t *drive = to_ide_device(dev);
1487f3c868ba78e486bd9d7569f884dd46d8f59bb18Bartlomiej Zolnierkiewicz	struct ide_driver *drv = to_ide_driver(dev->driver);
1494031bbe4bbec6c0fe50412ef7fb43a270b0f29f1Russell King
1504031bbe4bbec6c0fe50412ef7fb43a270b0f29f1Russell King	if (dev->driver && drv->shutdown)
1514031bbe4bbec6c0fe50412ef7fb43a270b0f29f1Russell King		drv->shutdown(drive);
1524031bbe4bbec6c0fe50412ef7fb43a270b0f29f1Russell King}
1534031bbe4bbec6c0fe50412ef7fb43a270b0f29f1Russell King
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct bus_type ide_bus_type = {
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.name		= "ide",
1568604affde9d4f52f04342d6a37c77d95fa167e7aBartlomiej Zolnierkiewicz	.match		= ide_bus_match,
157263756ec228f1cdd49fc50b1f87001a4cebdfe12Kay Sievers	.uevent		= ide_uevent,
1584031bbe4bbec6c0fe50412ef7fb43a270b0f29f1Russell King	.probe		= generic_ide_probe,
1594031bbe4bbec6c0fe50412ef7fb43a270b0f29f1Russell King	.remove		= generic_ide_remove,
1604031bbe4bbec6c0fe50412ef7fb43a270b0f29f1Russell King	.shutdown	= generic_ide_shutdown,
161263756ec228f1cdd49fc50b1f87001a4cebdfe12Kay Sievers	.dev_attrs	= ide_dev_attrs,
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.suspend	= generic_ide_suspend,
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.resume		= generic_ide_resume,
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1668604affde9d4f52f04342d6a37c77d95fa167e7aBartlomiej ZolnierkiewiczEXPORT_SYMBOL_GPL(ide_bus_type);
1678604affde9d4f52f04342d6a37c77d95fa167e7aBartlomiej Zolnierkiewicz
168ebae41a5a0583fb732c41445df4ac2c41016df74Bartlomiej Zolnierkiewiczint ide_vlb_clk;
169ebae41a5a0583fb732c41445df4ac2c41016df74Bartlomiej ZolnierkiewiczEXPORT_SYMBOL_GPL(ide_vlb_clk);
170ebae41a5a0583fb732c41445df4ac2c41016df74Bartlomiej Zolnierkiewicz
171ebae41a5a0583fb732c41445df4ac2c41016df74Bartlomiej Zolnierkiewiczmodule_param_named(vlb_clock, ide_vlb_clk, int, 0);
172ebae41a5a0583fb732c41445df4ac2c41016df74Bartlomiej ZolnierkiewiczMODULE_PARM_DESC(vlb_clock, "VLB clock frequency (in MHz)");
173ebae41a5a0583fb732c41445df4ac2c41016df74Bartlomiej Zolnierkiewicz
174ebae41a5a0583fb732c41445df4ac2c41016df74Bartlomiej Zolnierkiewiczint ide_pci_clk;
175ebae41a5a0583fb732c41445df4ac2c41016df74Bartlomiej ZolnierkiewiczEXPORT_SYMBOL_GPL(ide_pci_clk);
176ebae41a5a0583fb732c41445df4ac2c41016df74Bartlomiej Zolnierkiewicz
177ebae41a5a0583fb732c41445df4ac2c41016df74Bartlomiej Zolnierkiewiczmodule_param_named(pci_clock, ide_pci_clk, int, 0);
178ebae41a5a0583fb732c41445df4ac2c41016df74Bartlomiej ZolnierkiewiczMODULE_PARM_DESC(pci_clock, "PCI bus clock frequency (in MHz)");
179ebae41a5a0583fb732c41445df4ac2c41016df74Bartlomiej Zolnierkiewicz
1801a8bff5b404909436fcf03cac167a76ceaaa5547Rusty Russellstatic int ide_set_dev_param_mask(const char *s, const struct kernel_param *kp)
1816e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz{
1826e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz	int a, b, i, j = 1;
1836e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz	unsigned int *dev_param_mask = (unsigned int *)kp->arg;
1846e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz
1850af80c04e2f2e45ae09fceb17df8050f828a5c40David Fries	/* controller . device (0 or 1) [ : 1 (set) | 0 (clear) ] */
1866e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz	if (sscanf(s, "%d.%d:%d", &a, &b, &j) != 3 &&
1876e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz	    sscanf(s, "%d.%d", &a, &b) != 2)
1886e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz		return -EINVAL;
1896e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz
1906e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz	i = a * MAX_DRIVES + b;
1916e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz
1926e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz	if (i >= MAX_HWIFS * MAX_DRIVES || j < 0 || j > 1)
1936e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz		return -EINVAL;
1946e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz
1956e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz	if (j)
1966e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz		*dev_param_mask |= (1 << i);
1976e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz	else
1980af80c04e2f2e45ae09fceb17df8050f828a5c40David Fries		*dev_param_mask &= ~(1 << i);
1996e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz
2006e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz	return 0;
2016e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz}
2026e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz
2031a8bff5b404909436fcf03cac167a76ceaaa5547Rusty Russellstatic struct kernel_param_ops param_ops_ide_dev_mask = {
2041a8bff5b404909436fcf03cac167a76ceaaa5547Rusty Russell	.set = ide_set_dev_param_mask
2051a8bff5b404909436fcf03cac167a76ceaaa5547Rusty Russell};
2061a8bff5b404909436fcf03cac167a76ceaaa5547Rusty Russell
2071a8bff5b404909436fcf03cac167a76ceaaa5547Rusty Russell#define param_check_ide_dev_mask(name, p) param_check_uint(name, p)
2081a8bff5b404909436fcf03cac167a76ceaaa5547Rusty Russell
2096e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewiczstatic unsigned int ide_nodma;
2106e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz
2111a8bff5b404909436fcf03cac167a76ceaaa5547Rusty Russellmodule_param_named(nodma, ide_nodma, ide_dev_mask, 0);
2126e87543a94fb2a966c81a61fc91246592f9719daBartlomiej ZolnierkiewiczMODULE_PARM_DESC(nodma, "disallow DMA for a device");
2136e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz
2146e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewiczstatic unsigned int ide_noflush;
2156e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz
2161a8bff5b404909436fcf03cac167a76ceaaa5547Rusty Russellmodule_param_named(noflush, ide_noflush, ide_dev_mask, 0);
2176e87543a94fb2a966c81a61fc91246592f9719daBartlomiej ZolnierkiewiczMODULE_PARM_DESC(noflush, "disable flush requests for a device");
2186e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz
219075affcbe01d4d7cefcd0e30a98df1253bcf8d92Bartlomiej Zolnierkiewiczstatic unsigned int ide_nohpa;
220075affcbe01d4d7cefcd0e30a98df1253bcf8d92Bartlomiej Zolnierkiewicz
2211a8bff5b404909436fcf03cac167a76ceaaa5547Rusty Russellmodule_param_named(nohpa, ide_nohpa, ide_dev_mask, 0);
222075affcbe01d4d7cefcd0e30a98df1253bcf8d92Bartlomiej ZolnierkiewiczMODULE_PARM_DESC(nohpa, "disable Host Protected Area for a device");
223075affcbe01d4d7cefcd0e30a98df1253bcf8d92Bartlomiej Zolnierkiewicz
2246e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewiczstatic unsigned int ide_noprobe;
2256e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz
2261a8bff5b404909436fcf03cac167a76ceaaa5547Rusty Russellmodule_param_named(noprobe, ide_noprobe, ide_dev_mask, 0);
2276e87543a94fb2a966c81a61fc91246592f9719daBartlomiej ZolnierkiewiczMODULE_PARM_DESC(noprobe, "skip probing for a device");
2286e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz
2296e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewiczstatic unsigned int ide_nowerr;
2306e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz
2311a8bff5b404909436fcf03cac167a76ceaaa5547Rusty Russellmodule_param_named(nowerr, ide_nowerr, ide_dev_mask, 0);
2323a7d24841ad794ae64c90d7d00d62a83741912aaBartlomiej ZolnierkiewiczMODULE_PARM_DESC(nowerr, "ignore the ATA_DF bit for a device");
2336e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz
2344706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewiczstatic unsigned int ide_cdroms;
2354706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz
2361a8bff5b404909436fcf03cac167a76ceaaa5547Rusty Russellmodule_param_named(cdrom, ide_cdroms, ide_dev_mask, 0);
2374706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej ZolnierkiewiczMODULE_PARM_DESC(cdrom, "force device as a CD-ROM");
2384706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz
2394706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewiczstruct chs_geom {
2404706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz	unsigned int	cyl;
2414706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz	u8		head;
2424706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz	u8		sect;
2434706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz};
2444706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz
2454706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewiczstatic unsigned int ide_disks;
2464706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewiczstatic struct chs_geom ide_disks_chs[MAX_HWIFS * MAX_DRIVES];
2474706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz
2484706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewiczstatic int ide_set_disk_chs(const char *str, struct kernel_param *kp)
2494706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz{
2504706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz	int a, b, c = 0, h = 0, s = 0, i, j = 1;
2514706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz
2520af80c04e2f2e45ae09fceb17df8050f828a5c40David Fries	/* controller . device (0 or 1) : Cylinders , Heads , Sectors */
2530af80c04e2f2e45ae09fceb17df8050f828a5c40David Fries	/* controller . device (0 or 1) : 1 (use CHS) | 0 (ignore CHS) */
2544706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz	if (sscanf(str, "%d.%d:%d,%d,%d", &a, &b, &c, &h, &s) != 5 &&
2554706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz	    sscanf(str, "%d.%d:%d", &a, &b, &j) != 3)
2564706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz		return -EINVAL;
2574706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz
2584706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz	i = a * MAX_DRIVES + b;
2594706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz
2604706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz	if (i >= MAX_HWIFS * MAX_DRIVES || j < 0 || j > 1)
2614706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz		return -EINVAL;
2624706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz
2634706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz	if (c > INT_MAX || h > 255 || s > 255)
2644706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz		return -EINVAL;
2654706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz
2664706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz	if (j)
2674706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz		ide_disks |= (1 << i);
2684706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz	else
2690af80c04e2f2e45ae09fceb17df8050f828a5c40David Fries		ide_disks &= ~(1 << i);
2704706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz
2714706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz	ide_disks_chs[i].cyl  = c;
2724706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz	ide_disks_chs[i].head = h;
2734706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz	ide_disks_chs[i].sect = s;
2744706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz
2754706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz	return 0;
2764706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz}
2774706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz
2784706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewiczmodule_param_call(chs, ide_set_disk_chs, NULL, NULL, 0);
2794706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej ZolnierkiewiczMODULE_PARM_DESC(chs, "force device as a disk (using CHS)");
2804706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz
281123995b97136cb41fa282f0ed2385f2c8066df96Bartlomiej Zolnierkiewiczstatic void ide_dev_apply_params(ide_drive_t *drive, u8 unit)
2826e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz{
283123995b97136cb41fa282f0ed2385f2c8066df96Bartlomiej Zolnierkiewicz	int i = drive->hwif->index * MAX_DRIVES + unit;
2846e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz
2856e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz	if (ide_nodma & (1 << i)) {
2866e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz		printk(KERN_INFO "ide: disallowing DMA for %s\n", drive->name);
28797100fc816badbbc162644cfde7ad39ae9211fb4Bartlomiej Zolnierkiewicz		drive->dev_flags |= IDE_DFLAG_NODMA;
2886e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz	}
2896e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz	if (ide_noflush & (1 << i)) {
2906e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz		printk(KERN_INFO "ide: disabling flush requests for %s\n",
2916e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz				 drive->name);
29297100fc816badbbc162644cfde7ad39ae9211fb4Bartlomiej Zolnierkiewicz		drive->dev_flags |= IDE_DFLAG_NOFLUSH;
2936e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz	}
294075affcbe01d4d7cefcd0e30a98df1253bcf8d92Bartlomiej Zolnierkiewicz	if (ide_nohpa & (1 << i)) {
295075affcbe01d4d7cefcd0e30a98df1253bcf8d92Bartlomiej Zolnierkiewicz		printk(KERN_INFO "ide: disabling Host Protected Area for %s\n",
296075affcbe01d4d7cefcd0e30a98df1253bcf8d92Bartlomiej Zolnierkiewicz				 drive->name);
297075affcbe01d4d7cefcd0e30a98df1253bcf8d92Bartlomiej Zolnierkiewicz		drive->dev_flags |= IDE_DFLAG_NOHPA;
298075affcbe01d4d7cefcd0e30a98df1253bcf8d92Bartlomiej Zolnierkiewicz	}
2996e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz	if (ide_noprobe & (1 << i)) {
3006e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz		printk(KERN_INFO "ide: skipping probe for %s\n", drive->name);
30197100fc816badbbc162644cfde7ad39ae9211fb4Bartlomiej Zolnierkiewicz		drive->dev_flags |= IDE_DFLAG_NOPROBE;
3026e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz	}
3036e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz	if (ide_nowerr & (1 << i)) {
3043a7d24841ad794ae64c90d7d00d62a83741912aaBartlomiej Zolnierkiewicz		printk(KERN_INFO "ide: ignoring the ATA_DF bit for %s\n",
3056e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz				 drive->name);
3066e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz		drive->bad_wstat = BAD_R_STAT;
3076e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz	}
3084706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz	if (ide_cdroms & (1 << i)) {
3094706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz		printk(KERN_INFO "ide: forcing %s as a CD-ROM\n", drive->name);
31097100fc816badbbc162644cfde7ad39ae9211fb4Bartlomiej Zolnierkiewicz		drive->dev_flags |= IDE_DFLAG_PRESENT;
3114706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz		drive->media = ide_cdrom;
3124706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz		/* an ATAPI device ignores DRDY */
3134706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz		drive->ready_stat = 0;
3144706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz	}
3154706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz	if (ide_disks & (1 << i)) {
3164706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz		drive->cyl  = drive->bios_cyl  = ide_disks_chs[i].cyl;
3174706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz		drive->head = drive->bios_head = ide_disks_chs[i].head;
3184706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz		drive->sect = drive->bios_sect = ide_disks_chs[i].sect;
31997100fc816badbbc162644cfde7ad39ae9211fb4Bartlomiej Zolnierkiewicz
3204706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz		printk(KERN_INFO "ide: forcing %s as a disk (%d/%d/%d)\n",
3214706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz				 drive->name,
3224706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz				 drive->cyl, drive->head, drive->sect);
32397100fc816badbbc162644cfde7ad39ae9211fb4Bartlomiej Zolnierkiewicz
32497100fc816badbbc162644cfde7ad39ae9211fb4Bartlomiej Zolnierkiewicz		drive->dev_flags |= IDE_DFLAG_FORCED_GEOM | IDE_DFLAG_PRESENT;
3254706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz		drive->media = ide_disk;
3263a7d24841ad794ae64c90d7d00d62a83741912aaBartlomiej Zolnierkiewicz		drive->ready_stat = ATA_DRDY;
3274706a7e03a03d6d206a93a49a0c723dd612cf8e9Bartlomiej Zolnierkiewicz	}
3286e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz}
3296e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz
3309fd91d959f1a19d1bfa46d97cbbbb55641ce26a6Bartlomiej Zolnierkiewiczstatic unsigned int ide_ignore_cable;
3319fd91d959f1a19d1bfa46d97cbbbb55641ce26a6Bartlomiej Zolnierkiewicz
3329fd91d959f1a19d1bfa46d97cbbbb55641ce26a6Bartlomiej Zolnierkiewiczstatic int ide_set_ignore_cable(const char *s, struct kernel_param *kp)
3339fd91d959f1a19d1bfa46d97cbbbb55641ce26a6Bartlomiej Zolnierkiewicz{
3349fd91d959f1a19d1bfa46d97cbbbb55641ce26a6Bartlomiej Zolnierkiewicz	int i, j = 1;
3359fd91d959f1a19d1bfa46d97cbbbb55641ce26a6Bartlomiej Zolnierkiewicz
3360af80c04e2f2e45ae09fceb17df8050f828a5c40David Fries	/* controller (ignore) */
3370af80c04e2f2e45ae09fceb17df8050f828a5c40David Fries	/* controller : 1 (ignore) | 0 (use) */
3389fd91d959f1a19d1bfa46d97cbbbb55641ce26a6Bartlomiej Zolnierkiewicz	if (sscanf(s, "%d:%d", &i, &j) != 2 && sscanf(s, "%d", &i) != 1)
3399fd91d959f1a19d1bfa46d97cbbbb55641ce26a6Bartlomiej Zolnierkiewicz		return -EINVAL;
3409fd91d959f1a19d1bfa46d97cbbbb55641ce26a6Bartlomiej Zolnierkiewicz
3419fd91d959f1a19d1bfa46d97cbbbb55641ce26a6Bartlomiej Zolnierkiewicz	if (i >= MAX_HWIFS || j < 0 || j > 1)
3429fd91d959f1a19d1bfa46d97cbbbb55641ce26a6Bartlomiej Zolnierkiewicz		return -EINVAL;
3439fd91d959f1a19d1bfa46d97cbbbb55641ce26a6Bartlomiej Zolnierkiewicz
3449fd91d959f1a19d1bfa46d97cbbbb55641ce26a6Bartlomiej Zolnierkiewicz	if (j)
3459fd91d959f1a19d1bfa46d97cbbbb55641ce26a6Bartlomiej Zolnierkiewicz		ide_ignore_cable |= (1 << i);
3469fd91d959f1a19d1bfa46d97cbbbb55641ce26a6Bartlomiej Zolnierkiewicz	else
3470af80c04e2f2e45ae09fceb17df8050f828a5c40David Fries		ide_ignore_cable &= ~(1 << i);
3489fd91d959f1a19d1bfa46d97cbbbb55641ce26a6Bartlomiej Zolnierkiewicz
3499fd91d959f1a19d1bfa46d97cbbbb55641ce26a6Bartlomiej Zolnierkiewicz	return 0;
3509fd91d959f1a19d1bfa46d97cbbbb55641ce26a6Bartlomiej Zolnierkiewicz}
3519fd91d959f1a19d1bfa46d97cbbbb55641ce26a6Bartlomiej Zolnierkiewicz
3529fd91d959f1a19d1bfa46d97cbbbb55641ce26a6Bartlomiej Zolnierkiewiczmodule_param_call(ignore_cable, ide_set_ignore_cable, NULL, NULL, 0);
3539fd91d959f1a19d1bfa46d97cbbbb55641ce26a6Bartlomiej ZolnierkiewiczMODULE_PARM_DESC(ignore_cable, "ignore cable detection");
3549fd91d959f1a19d1bfa46d97cbbbb55641ce26a6Bartlomiej Zolnierkiewicz
3559fd91d959f1a19d1bfa46d97cbbbb55641ce26a6Bartlomiej Zolnierkiewiczvoid ide_port_apply_params(ide_hwif_t *hwif)
3569fd91d959f1a19d1bfa46d97cbbbb55641ce26a6Bartlomiej Zolnierkiewicz{
3572bd24a1cfc99d242c2cff9a6b74ca49fcaac3fb6Bartlomiej Zolnierkiewicz	ide_drive_t *drive;
3586e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz	int i;
3596e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz
3609fd91d959f1a19d1bfa46d97cbbbb55641ce26a6Bartlomiej Zolnierkiewicz	if (ide_ignore_cable & (1 << hwif->index)) {
3619fd91d959f1a19d1bfa46d97cbbbb55641ce26a6Bartlomiej Zolnierkiewicz		printk(KERN_INFO "ide: ignoring cable detection for %s\n",
3629fd91d959f1a19d1bfa46d97cbbbb55641ce26a6Bartlomiej Zolnierkiewicz				 hwif->name);
3639fd91d959f1a19d1bfa46d97cbbbb55641ce26a6Bartlomiej Zolnierkiewicz		hwif->cbl = ATA_CBL_PATA40_SHORT;
3649fd91d959f1a19d1bfa46d97cbbbb55641ce26a6Bartlomiej Zolnierkiewicz	}
3656e87543a94fb2a966c81a61fc91246592f9719daBartlomiej Zolnierkiewicz
3662bd24a1cfc99d242c2cff9a6b74ca49fcaac3fb6Bartlomiej Zolnierkiewicz	ide_port_for_each_dev(i, drive, hwif)
3672bd24a1cfc99d242c2cff9a6b74ca49fcaac3fb6Bartlomiej Zolnierkiewicz		ide_dev_apply_params(drive, i);
3689fd91d959f1a19d1bfa46d97cbbbb55641ce26a6Bartlomiej Zolnierkiewicz}
3699fd91d959f1a19d1bfa46d97cbbbb55641ce26a6Bartlomiej Zolnierkiewicz
3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This is gets invoked once during initialization, to set *everything* up
3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init ide_init(void)
3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
375349ae23fe7379a42973bcb1c85f7d43ec583c17dRandy Dunlap	int ret;
376349ae23fe7379a42973bcb1c85f7d43ec583c17dRandy Dunlap
377eba8ff946177ca38dfde0bf1d8ce0703c45c49b9Bartlomiej Zolnierkiewicz	printk(KERN_INFO "Uniform Multi-Platform E-IDE driver\n");
378537f06c5deaffbbe155bcc898369f889e7f3e647Bartlomiej Zolnierkiewicz
379349ae23fe7379a42973bcb1c85f7d43ec583c17dRandy Dunlap	ret = bus_register(&ide_bus_type);
380349ae23fe7379a42973bcb1c85f7d43ec583c17dRandy Dunlap	if (ret < 0) {
381349ae23fe7379a42973bcb1c85f7d43ec583c17dRandy Dunlap		printk(KERN_WARNING "IDE: bus_register error: %d\n", ret);
382349ae23fe7379a42973bcb1c85f7d43ec583c17dRandy Dunlap		return ret;
383349ae23fe7379a42973bcb1c85f7d43ec583c17dRandy Dunlap	}
3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
385f74c91413ec6140ee0553180c5f56fdd27c22a2eBartlomiej Zolnierkiewicz	ide_port_class = class_create(THIS_MODULE, "ide_port");
386f74c91413ec6140ee0553180c5f56fdd27c22a2eBartlomiej Zolnierkiewicz	if (IS_ERR(ide_port_class)) {
387f74c91413ec6140ee0553180c5f56fdd27c22a2eBartlomiej Zolnierkiewicz		ret = PTR_ERR(ide_port_class);
388f74c91413ec6140ee0553180c5f56fdd27c22a2eBartlomiej Zolnierkiewicz		goto out_port_class;
389f74c91413ec6140ee0553180c5f56fdd27c22a2eBartlomiej Zolnierkiewicz	}
390f74c91413ec6140ee0553180c5f56fdd27c22a2eBartlomiej Zolnierkiewicz
3918b803bd184e3f6892284d4b50801b9ec85cd9b96Bartlomiej Zolnierkiewicz	ide_acpi_init();
3928b803bd184e3f6892284d4b50801b9ec85cd9b96Bartlomiej Zolnierkiewicz
3935cbf79cdb37be2aa2a1b4fa94144526b14557060Bartlomiej Zolnierkiewicz	proc_ide_create();
3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
396f74c91413ec6140ee0553180c5f56fdd27c22a2eBartlomiej Zolnierkiewicz
397f74c91413ec6140ee0553180c5f56fdd27c22a2eBartlomiej Zolnierkiewiczout_port_class:
398f74c91413ec6140ee0553180c5f56fdd27c22a2eBartlomiej Zolnierkiewicz	bus_unregister(&ide_bus_type);
399f74c91413ec6140ee0553180c5f56fdd27c22a2eBartlomiej Zolnierkiewicz
400f74c91413ec6140ee0553180c5f56fdd27c22a2eBartlomiej Zolnierkiewicz	return ret;
4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
403931ee0dc5c69e8113233d21942681ab8fecde7f9Bartlomiej Zolnierkiewiczstatic void __exit ide_exit(void)
4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	proc_ide_destroy();
4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
407f74c91413ec6140ee0553180c5f56fdd27c22a2eBartlomiej Zolnierkiewicz	class_destroy(ide_port_class);
408f74c91413ec6140ee0553180c5f56fdd27c22a2eBartlomiej Zolnierkiewicz
4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	bus_unregister(&ide_bus_type);
4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(ide_init);
413931ee0dc5c69e8113233d21942681ab8fecde7f9Bartlomiej Zolnierkiewiczmodule_exit(ide_exit);
4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
415931ee0dc5c69e8113233d21942681ab8fecde7f9Bartlomiej ZolnierkiewiczMODULE_LICENSE("GPL");
416