diff options
| author | Paul Mackerras <paulus@samba.org> | 2007-05-10 21:08:37 +1000 | 
|---|---|---|
| committer | Paul Mackerras <paulus@samba.org> | 2007-05-10 21:08:37 +1000 | 
| commit | 2ecf042ef530dd0943e41d84b6344f507941af3e (patch) | |
| tree | 73100361dd74e3f80f14c7c81ba4675948983f44 /drivers/ide/ide.c | |
| parent | 32a56ebb24f23da1bbaf24292acf85b6c04526ab (diff) | |
| parent | de5603748af8bf7deac403e6ba92887f8d18e812 (diff) | |
Merge branch 'linux-2.6'
Diffstat (limited to 'drivers/ide/ide.c')
| -rw-r--r-- | drivers/ide/ide.c | 470 | 
1 files changed, 90 insertions, 380 deletions
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index ae5bf2be6f5..f2b547ff772 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -168,12 +168,11 @@ static const u8 ide_hwif_to_major[] = { IDE0_MAJOR, IDE1_MAJOR,  static int idebus_parameter;	/* holds the "idebus=" parameter */  static int system_bus_speed;	/* holds what we think is VESA/PCI bus speed */ -static int initializing;	/* set while initializing built-in drivers */  DECLARE_MUTEX(ide_cfg_sem);   __cacheline_aligned_in_smp DEFINE_SPINLOCK(ide_lock); -#ifdef CONFIG_BLK_DEV_IDEPCI +#ifdef CONFIG_IDEPCI_PCIBUS_ORDER  static int ide_scan_direction; /* THIS was formerly 2.2.x pci=reverse */  #endif @@ -216,9 +215,6 @@ static void init_hwif_data(ide_hwif_t *hwif, unsigned int index)  	hwif->bus_state	= BUSSTATE_ON;  	hwif->atapi_dma = 0;		/* disable all atapi dma */  -	hwif->ultra_mask = 0x80;	/* disable all ultra */ -	hwif->mwdma_mask = 0x80;	/* disable all mwdma */ -	hwif->swdma_mask = 0x80;	/* disable all swdma */  	init_completion(&hwif->gendev_rel_comp); @@ -305,9 +301,7 @@ static void __init init_ide_data (void)  #endif  	}  #ifdef CONFIG_IDE_ARM -	initializing = 1;  	ide_arm_init(); -	initializing = 0;  #endif  } @@ -353,10 +347,6 @@ static int ide_system_bus_speed(void)  	return system_bus_speed;  } -#ifdef CONFIG_PROC_FS -struct proc_dir_entry *proc_ide_root; -#endif -  static struct resource* hwif_request_region(ide_hwif_t *hwif,  					    unsigned long addr, int num)  { @@ -480,6 +470,7 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)  	hwif->tuneproc			= tmp_hwif->tuneproc;  	hwif->speedproc			= tmp_hwif->speedproc; +	hwif->udma_filter		= tmp_hwif->udma_filter;  	hwif->selectproc		= tmp_hwif->selectproc;  	hwif->reset_poll		= tmp_hwif->reset_poll;  	hwif->pre_reset			= tmp_hwif->pre_reset; @@ -599,7 +590,7 @@ void ide_unregister(unsigned int index)  	spin_unlock_irq(&ide_lock); -	destroy_proc_ide_interface(hwif); +	ide_proc_unregister_port(hwif);  	hwgroup = hwif->hwgroup;  	/* @@ -751,6 +742,7 @@ void ide_setup_ports (	hw_regs_t *hw,  /**   *	ide_register_hw_with_fixup	-	register IDE interface   *	@hw: hardware registers + *	@initializing: set while initializing built-in drivers   *	@hwifp: pointer to returned hwif   *	@fixup: fixup function   * @@ -760,7 +752,9 @@ void ide_setup_ports (	hw_regs_t *hw,   *	Returns -1 on error.   */ -int ide_register_hw_with_fixup(hw_regs_t *hw, ide_hwif_t **hwifp, void(*fixup)(ide_hwif_t *hwif)) +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; @@ -801,7 +795,7 @@ found:  	if (!initializing) {  		probe_hwif_init_with_fixup(hwif, fixup); -		create_proc_ide_interfaces(); +		ide_proc_register_port(hwif);  	}  	if (hwifp) @@ -812,9 +806,9 @@ found:  EXPORT_SYMBOL(ide_register_hw_with_fixup); -int ide_register_hw(hw_regs_t *hw, ide_hwif_t **hwifp) +int ide_register_hw(hw_regs_t *hw, int initializing, ide_hwif_t **hwifp)  { -	return ide_register_hw_with_fixup(hw, hwifp, NULL); +	return ide_register_hw_with_fixup(hw, initializing, hwifp, NULL);  }  EXPORT_SYMBOL(ide_register_hw); @@ -825,205 +819,7 @@ EXPORT_SYMBOL(ide_register_hw);  DECLARE_MUTEX(ide_setting_sem); -/** - *	__ide_add_setting	-	add an ide setting option - *	@drive: drive to use - *	@name: setting name - *	@rw: true if the function is read write - *	@read_ioctl: function to call on read - *	@write_ioctl: function to call on write - *	@data_type: type of data - *	@min: range minimum - *	@max: range maximum - *	@mul_factor: multiplication scale - *	@div_factor: divison scale - *	@data: private data field - *	@set: setting - *	@auto_remove: setting auto removal flag - * - *	Removes the setting named from the device if it is present. - *	The function takes the settings_lock to protect against  - *	parallel changes. This function must not be called from IRQ - *	context. Returns 0 on success or -1 on failure. - * - *	BUGS: This code is seriously over-engineered. There is also - *	magic about how the driver specific features are setup. If - *	a driver is attached we assume the driver settings are auto - *	remove. - */ - -static int __ide_add_setting(ide_drive_t *drive, const char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set, int auto_remove) -{ -	ide_settings_t **p = (ide_settings_t **) &drive->settings, *setting = NULL; - -	down(&ide_setting_sem); -	while ((*p) && strcmp((*p)->name, name) < 0) -		p = &((*p)->next); -	if ((setting = kzalloc(sizeof(*setting), GFP_KERNEL)) == NULL) -		goto abort; -	if ((setting->name = kmalloc(strlen(name) + 1, GFP_KERNEL)) == NULL) -		goto abort; -	strcpy(setting->name, name); -	setting->rw = rw; -	setting->read_ioctl = read_ioctl; -	setting->write_ioctl = write_ioctl; -	setting->data_type = data_type; -	setting->min = min; -	setting->max = max; -	setting->mul_factor = mul_factor; -	setting->div_factor = div_factor; -	setting->data = data; -	setting->set = set; -	 -	setting->next = *p; -	if (auto_remove) -		setting->auto_remove = 1; -	*p = setting; -	up(&ide_setting_sem); -	return 0; -abort: -	up(&ide_setting_sem); -	kfree(setting); -	return -1; -} - -int ide_add_setting(ide_drive_t *drive, const char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set) -{ -	return __ide_add_setting(drive, name, rw, read_ioctl, write_ioctl, data_type, min, max, mul_factor, div_factor, data, set, 1); -} - -EXPORT_SYMBOL(ide_add_setting); - -/** - *	__ide_remove_setting	-	remove an ide setting option - *	@drive: drive to use - *	@name: setting name - * - *	Removes the setting named from the device if it is present. - *	The caller must hold the setting semaphore. - */ -  -static void __ide_remove_setting (ide_drive_t *drive, char *name) -{ -	ide_settings_t **p, *setting; - -	p = (ide_settings_t **) &drive->settings; - -	while ((*p) && strcmp((*p)->name, name)) -		p = &((*p)->next); -	if ((setting = (*p)) == NULL) -		return; - -	(*p) = setting->next; -	 -	kfree(setting->name); -	kfree(setting); -} - -/** - *	ide_find_setting_by_ioctl	-	find a drive specific ioctl - *	@drive: drive to scan - *	@cmd: ioctl command to handle - * - *	Scan's the device setting table for a matching entry and returns - *	this or NULL if no entry is found. The caller must hold the - *	setting semaphore - */ -  -static ide_settings_t *ide_find_setting_by_ioctl (ide_drive_t *drive, int cmd) -{ -	ide_settings_t *setting = drive->settings; - -	while (setting) { -		if (setting->read_ioctl == cmd || setting->write_ioctl == cmd) -			break; -		setting = setting->next; -	} -	 -	return setting; -} - -/** - *	ide_find_setting_by_name	-	find a drive specific setting - *	@drive: drive to scan - *	@name: setting name - * - *	Scan's the device setting table for a matching entry and returns - *	this or NULL if no entry is found. The caller must hold the - *	setting semaphore - */ -  -ide_settings_t *ide_find_setting_by_name (ide_drive_t *drive, char *name) -{ -	ide_settings_t *setting = drive->settings; - -	while (setting) { -		if (strcmp(setting->name, name) == 0) -			break; -		setting = setting->next; -	} -	return setting; -} - -/** - *	auto_remove_settings	-	remove driver specific settings - *	@drive: drive - * - *	Automatically remove all the driver specific settings for this - *	drive. This function may not be called from IRQ context. The - *	caller must hold ide_setting_sem. - */ -  -static void auto_remove_settings (ide_drive_t *drive) -{ -	ide_settings_t *setting; -repeat: -	setting = drive->settings; -	while (setting) { -		if (setting->auto_remove) { -			__ide_remove_setting(drive, setting->name); -			goto repeat; -		} -		setting = setting->next; -	} -} - -/** - *	ide_read_setting	-	read an IDE setting - *	@drive: drive to read from - *	@setting: drive setting - * - *	Read a drive setting and return the value. The caller - *	must hold the ide_setting_sem when making this call. - * - *	BUGS: the data return and error are the same return value - *	so an error -EINVAL and true return of the same value cannot - *	be told apart - */ -  -int ide_read_setting (ide_drive_t *drive, ide_settings_t *setting) -{ -	int		val = -EINVAL; -	unsigned long	flags; - -	if ((setting->rw & SETTING_READ)) { -		spin_lock_irqsave(&ide_lock, flags); -		switch(setting->data_type) { -			case TYPE_BYTE: -				val = *((u8 *) setting->data); -				break; -			case TYPE_SHORT: -				val = *((u16 *) setting->data); -				break; -			case TYPE_INT: -			case TYPE_INTA: -				val = *((u32 *) setting->data); -				break; -		} -		spin_unlock_irqrestore(&ide_lock, flags); -	} -	return val; -} +EXPORT_SYMBOL_GPL(ide_setting_sem);  /**   *	ide_spin_wait_hwgroup	-	wait for group @@ -1058,61 +854,14 @@ int ide_spin_wait_hwgroup (ide_drive_t *drive)  EXPORT_SYMBOL(ide_spin_wait_hwgroup); -/** - *	ide_write_setting	-	read an IDE setting - *	@drive: drive to read from - *	@setting: drive setting - *	@val: value - * - *	Write a drive setting if it is possible. The caller - *	must hold the ide_setting_sem when making this call. - * - *	BUGS: the data return and error are the same return value - *	so an error -EINVAL and true return of the same value cannot - *	be told apart - * - *	FIXME:  This should be changed to enqueue a special request - *	to the driver to change settings, and then wait on a sema for completion. - *	The current scheme of polling is kludgy, though safe enough. - */ - -int ide_write_setting (ide_drive_t *drive, ide_settings_t *setting, int val) +int set_io_32bit(ide_drive_t *drive, int arg)  { -	int i; -	u32 *p; - -	if (!capable(CAP_SYS_ADMIN)) -		return -EACCES; -	if (!(setting->rw & SETTING_WRITE)) +	if (drive->no_io_32bit)  		return -EPERM; -	if (val < setting->min || val > setting->max) + +	if (arg < 0 || arg > 1 + (SUPPORT_VLB_SYNC << 1))  		return -EINVAL; -	if (setting->set) -		return setting->set(drive, val); -	if (ide_spin_wait_hwgroup(drive)) -		return -EBUSY; -	switch (setting->data_type) { -		case TYPE_BYTE: -			*((u8 *) setting->data) = val; -			break; -		case TYPE_SHORT: -			*((u16 *) setting->data) = val; -			break; -		case TYPE_INT: -			*((u32 *) setting->data) = val; -			break; -		case TYPE_INTA: -			p = (u32 *) setting->data; -			for (i = 0; i < 1 << PARTN_BITS; i++, p++) -				*p = val; -			break; -	} -	spin_unlock_irq(&ide_lock); -	return 0; -} -static int set_io_32bit(ide_drive_t *drive, int arg) -{  	drive->io_32bit = arg;  #ifdef CONFIG_BLK_DEV_DTC2278  	if (HWIF(drive)->chipset == ide_dtc2278) @@ -1121,12 +870,28 @@ static int set_io_32bit(ide_drive_t *drive, int arg)  	return 0;  } -static int set_using_dma (ide_drive_t *drive, int arg) +static int set_ksettings(ide_drive_t *drive, int arg) +{ +	if (arg < 0 || arg > 1) +		return -EINVAL; + +	if (ide_spin_wait_hwgroup(drive)) +		return -EBUSY; +	drive->keep_settings = arg; +	spin_unlock_irq(&ide_lock); + +	return 0; +} + +int set_using_dma(ide_drive_t *drive, int arg)  {  #ifdef CONFIG_BLK_DEV_IDEDMA  	ide_hwif_t *hwif = drive->hwif;  	int err = -EPERM; +	if (arg < 0 || arg > 1) +		return -EINVAL; +  	if (!drive->id || !(drive->id->capability & 1))  		goto out; @@ -1159,14 +924,20 @@ static int set_using_dma (ide_drive_t *drive, int arg)  out:  	return err;  #else +	if (arg < 0 || arg > 1) +		return -EINVAL; +  	return -EPERM;  #endif  } -static int set_pio_mode (ide_drive_t *drive, int arg) +int set_pio_mode(ide_drive_t *drive, int arg)  {  	struct request rq; +	if (arg < 0 || arg > 255) +		return -EINVAL; +  	if (!HWIF(drive)->tuneproc)  		return -ENOSYS;  	if (drive->special.b.set_tune) @@ -1178,42 +949,20 @@ static int set_pio_mode (ide_drive_t *drive, int arg)  	return 0;  } -static int set_xfer_rate (ide_drive_t *drive, int arg) +static int set_unmaskirq(ide_drive_t *drive, int arg)  { -	int err = ide_wait_cmd(drive, -			WIN_SETFEATURES, (u8) arg, -			SETFEATURES_XFER, 0, NULL); +	if (drive->no_unmask) +		return -EPERM; -	if (!err && arg) { -		ide_set_xfer_rate(drive, (u8) arg); -		ide_driveid_update(drive); -	} -	return err; -} +	if (arg < 0 || arg > 1) +		return -EINVAL; -/** - *	ide_add_generic_settings	-	generic ide settings - *	@drive: drive being configured - * - *	Add the generic parts of the system settings to the /proc files and - *	ioctls for this IDE device. The caller must not be holding the - *	ide_setting_sem. - */ +	if (ide_spin_wait_hwgroup(drive)) +		return -EBUSY; +	drive->unmask = arg; +	spin_unlock_irq(&ide_lock); -void ide_add_generic_settings (ide_drive_t *drive) -{ -/* - *			  drive		setting name		read/write access				read ioctl		write ioctl		data type	min	max				mul_factor	div_factor	data pointer			set function - */ -	__ide_add_setting(drive,	"io_32bit",		drive->no_io_32bit ? SETTING_READ : SETTING_RW,	HDIO_GET_32BIT,		HDIO_SET_32BIT,		TYPE_BYTE,	0,	1 + (SUPPORT_VLB_SYNC << 1),	1,		1,		&drive->io_32bit,		set_io_32bit,	0); -	__ide_add_setting(drive,	"keepsettings",		SETTING_RW,					HDIO_GET_KEEPSETTINGS,	HDIO_SET_KEEPSETTINGS,	TYPE_BYTE,	0,	1,				1,		1,		&drive->keep_settings,		NULL,		0); -	__ide_add_setting(drive,	"nice1",		SETTING_RW,					-1,			-1,			TYPE_BYTE,	0,	1,				1,		1,		&drive->nice1,			NULL,		0); -	__ide_add_setting(drive,	"pio_mode",		SETTING_WRITE,					-1,			HDIO_SET_PIO_MODE,	TYPE_BYTE,	0,	255,				1,		1,		NULL,				set_pio_mode,	0); -	__ide_add_setting(drive,	"unmaskirq",		drive->no_unmask ? SETTING_READ : SETTING_RW,	HDIO_GET_UNMASKINTR,	HDIO_SET_UNMASKINTR,	TYPE_BYTE,	0,	1,				1,		1,		&drive->unmask,			NULL,		0); -	__ide_add_setting(drive,	"using_dma",		SETTING_RW,					HDIO_GET_DMA,		HDIO_SET_DMA,		TYPE_BYTE,	0,	1,				1,		1,		&drive->using_dma,		set_using_dma,	0); -	__ide_add_setting(drive,	"init_speed",		SETTING_RW,					-1,			-1,			TYPE_BYTE,	0,	70,				1,		1,		&drive->init_speed,		NULL,		0); -	__ide_add_setting(drive,	"current_speed",	SETTING_RW,					-1,			-1,			TYPE_BYTE,	0,	70,				1,		1,		&drive->current_speed,		set_xfer_rate,	0); -	__ide_add_setting(drive,	"number",		SETTING_RW,					-1,			-1,			TYPE_BYTE,	0,	3,				1,		1,		&drive->dn,			NULL,		0); +	return 0;  }  /** @@ -1285,27 +1034,23 @@ static int generic_ide_resume(struct device *dev)  int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device *bdev,  			unsigned int cmd, unsigned long arg)  { -	ide_settings_t *setting; +	unsigned long flags;  	ide_driver_t *drv; -	int err = 0;  	void __user *p = (void __user *)arg; +	int err = 0, (*setfunc)(ide_drive_t *, int); +	u8 *val; -	down(&ide_setting_sem); -	if ((setting = ide_find_setting_by_ioctl(drive, cmd)) != NULL) { -		if (cmd == setting->read_ioctl) { -			err = ide_read_setting(drive, setting); -			up(&ide_setting_sem); -			return err >= 0 ? put_user(err, (long __user *)arg) : err; -		} else { -			if (bdev != bdev->bd_contains) -				err = -EINVAL; -			else -				err = ide_write_setting(drive, setting, arg); -			up(&ide_setting_sem); -			return err; -		} +	switch (cmd) { +	case HDIO_GET_32BIT:	    val = &drive->io_32bit;	 goto read_val; +	case HDIO_GET_KEEPSETTINGS: val = &drive->keep_settings; goto read_val; +	case HDIO_GET_UNMASKINTR:   val = &drive->unmask;	 goto read_val; +	case HDIO_GET_DMA:	    val = &drive->using_dma;	 goto read_val; +	case HDIO_SET_32BIT:	    setfunc = set_io_32bit;	 goto set_val; +	case HDIO_SET_KEEPSETTINGS: setfunc = set_ksettings;	 goto set_val; +	case HDIO_SET_PIO_MODE:	    setfunc = set_pio_mode;	 goto set_val; +	case HDIO_SET_UNMASKINTR:   setfunc = set_unmaskirq;	 goto set_val; +	case HDIO_SET_DMA:	    setfunc = set_using_dma;	 goto set_val;  	} -	up(&ide_setting_sem);  	switch (cmd) {  		case HDIO_OBSOLETE_IDENTITY: @@ -1359,7 +1104,7 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device  			ide_init_hwif_ports(&hw, (unsigned long) args[0],  					    (unsigned long) args[1], NULL);  			hw.irq = args[2]; -			if (ide_register_hw(&hw, NULL) == -1) +			if (ide_register_hw(&hw, 0, NULL) == -1)  				return -EIO;  			return 0;  		} @@ -1434,6 +1179,28 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device  		default:  			return -EINVAL;  	} + +read_val: +	down(&ide_setting_sem); +	spin_lock_irqsave(&ide_lock, flags); +	err = *val; +	spin_unlock_irqrestore(&ide_lock, flags); +	up(&ide_setting_sem); +	return err >= 0 ? put_user(err, (long __user *)arg) : err; + +set_val: +	if (bdev != bdev->bd_contains) +		err = -EINVAL; +	else { +		if (!capable(CAP_SYS_ADMIN)) +			err = -EACCES; +		else { +			down(&ide_setting_sem); +			err = setfunc(drive, arg); +			up(&ide_setting_sem); +		} +	} +	return err;  }  EXPORT_SYMBOL(generic_ide_ioctl); @@ -1566,13 +1333,13 @@ static int __init ide_setup(char *s)  		return 1;  	} -#ifdef CONFIG_BLK_DEV_IDEPCI +#ifdef CONFIG_IDEPCI_PCIBUS_ORDER  	if (!strcmp(s, "ide=reverse")) {  		ide_scan_direction = 1;  		printk(" : Enabled support for IDE inverse scan order.\n");  		return 1;  	} -#endif /* CONFIG_BLK_DEV_IDEPCI */ +#endif  #ifdef CONFIG_BLK_DEV_IDEACPI  	if (!strcmp(s, "ide=noacpi")) { @@ -1832,9 +1599,9 @@ extern void __init h8300_ide_init(void);   */  static void __init probe_for_hwifs (void)  { -#ifdef CONFIG_BLK_DEV_IDEPCI +#ifdef CONFIG_IDEPCI_PCIBUS_ORDER  	ide_scan_pcibus(ide_scan_direction); -#endif /* CONFIG_BLK_DEV_IDEPCI */ +#endif  #ifdef CONFIG_ETRAX_IDE  	{ @@ -1892,54 +1659,6 @@ static void __init probe_for_hwifs (void)  #endif  } -void ide_register_subdriver(ide_drive_t *drive, ide_driver_t *driver) -{ -#ifdef CONFIG_PROC_FS -	ide_add_proc_entries(drive->proc, driver->proc, drive); -#endif -} - -EXPORT_SYMBOL(ide_register_subdriver); - -/** - *	ide_unregister_subdriver	-	disconnect drive from driver - *	@drive: drive to unplug - *	@driver: driver - * - *	Disconnect a drive from the driver it was attached to and then - *	clean up the various proc files and other objects attached to it. - * - *	Takes ide_setting_sem and ide_lock. - *	Caller must hold none of the locks. - */ - -void ide_unregister_subdriver(ide_drive_t *drive, ide_driver_t *driver) -{ -	unsigned long flags; -	 -#ifdef CONFIG_PROC_FS -	ide_remove_proc_entries(drive->proc, driver->proc); -#endif -	down(&ide_setting_sem); -	spin_lock_irqsave(&ide_lock, flags); -	/* -	 * ide_setting_sem protects the settings list -	 * ide_lock protects the use of settings -	 * -	 * so we need to hold both, ide_settings_sem because we want to -	 * modify the settings list, and ide_lock because we cannot take -	 * a setting out that is being used. -	 * -	 * OTOH both ide_{read,write}_setting are only ever used under -	 * ide_setting_sem. -	 */ -	auto_remove_settings(drive); -	spin_unlock_irqrestore(&ide_lock, flags); -	up(&ide_setting_sem); -} - -EXPORT_SYMBOL(ide_unregister_subdriver); -  /*   * Probe module   */ @@ -2071,9 +1790,7 @@ static int __init ide_init(void)  	init_ide_data(); -#ifdef CONFIG_PROC_FS -	proc_ide_root = proc_mkdir("ide", NULL); -#endif +	proc_ide_create();  #ifdef CONFIG_BLK_DEV_ALI14XX  	if (probe_ali14xx) @@ -2096,14 +1813,9 @@ static int __init ide_init(void)  		(void)qd65xx_init();  #endif -	initializing = 1;  	/* Probe for special PCI and other "known" interface chipsets. */  	probe_for_hwifs(); -	initializing = 0; -#ifdef CONFIG_PROC_FS -	proc_ide_create(); -#endif  	return 0;  } @@ -2143,9 +1855,7 @@ void __exit cleanup_module (void)  	pnpide_exit();  #endif -#ifdef CONFIG_PROC_FS  	proc_ide_destroy(); -#endif  	bus_unregister(&ide_bus_type);  }  | 
