ide: move IDE settings handling to ide-proc.c

* move
	__ide_add_setting()
	ide_add_setting()
	__ide_remove_setting()
	auto_remove_settings()
	ide_find_setting_by_name()
	ide_read_setting()
	ide_write_setting()
	set_xfer_rate()
	ide_add_generic_settings()
	ide_register_subdriver()
	ide_unregister_subdriver()

  from ide.c to ide-proc.c

* set_{io_32bit,pio_mode,using_dma}() cannot be marked static now, fix it

* rename ide_[un]register_subdriver() to ide_proc_[un]register_driver(),
  update device drivers to use new names

* add CONFIG_IDE_PROC_FS=n versions of ide_proc_[un]register_driver()
  and ide_add_generic_settings()

* make ide_find_setting_by_name(), ide_{read,write}_setting()
  and ide_{add,remove}_proc_entries() static

* cover IDE settings code in device drivers with CONFIG_IDE_PROC_FS #ifdef,
  also while at it cover with CONFIG_IDE_PROC_FS #ifdef ide_driver_t.proc

* remove bogus comment from ide.h

* cover with CONFIG_IDE_PROC_FS #ifdef .proc and .settings in ide_drive_t

Besides saner code this patch results in the IDE core smaller by ~2 kB
(on x86-32) and IDE disk driver by ~1 kB (ditto) when CONFIG_IDE_PROC_FS=n.

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
This commit is contained in:
Bartlomiej Zolnierkiewicz
2007-05-10 00:01:10 +02:00
부모 1497943ee6
커밋 7662d046df
8개의 변경된 파일378개의 추가작업 그리고 363개의 파일을 삭제

파일 보기

@@ -825,178 +825,6 @@ DECLARE_MUTEX(ide_setting_sem);
EXPORT_SYMBOL_GPL(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
* @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 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->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 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, 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_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:
val = *((u32 *) setting->data);
break;
}
spin_unlock_irqrestore(&ide_lock, flags);
}
return val;
}
/**
* ide_spin_wait_hwgroup - wait for group
* @drive: drive in the group
@@ -1030,52 +858,7 @@ 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)
{
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
if (setting->set)
return setting->set(drive, val);
if (!(setting->rw & SETTING_WRITE))
return -EPERM;
if (val < setting->min || val > setting->max)
return -EINVAL;
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;
}
spin_unlock_irq(&ide_lock);
return 0;
}
static int set_io_32bit(ide_drive_t *drive, int arg)
int set_io_32bit(ide_drive_t *drive, int arg)
{
if (drive->no_io_32bit)
return -EPERM;
@@ -1104,7 +887,7 @@ static int set_ksettings(ide_drive_t *drive, int arg)
return 0;
}
static int set_using_dma (ide_drive_t *drive, int arg)
int set_using_dma(ide_drive_t *drive, int arg)
{
#ifdef CONFIG_BLK_DEV_IDEDMA
ide_hwif_t *hwif = drive->hwif;
@@ -1152,7 +935,7 @@ out:
#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;
@@ -1186,48 +969,6 @@ static int set_unmaskirq(ide_drive_t *drive, int arg)
return 0;
}
static int set_xfer_rate (ide_drive_t *drive, int arg)
{
int err;
if (arg < 0 || arg > 70)
return -EINVAL;
err = ide_wait_cmd(drive,
WIN_SETFEATURES, (u8) arg,
SETFEATURES_XFER, 0, NULL);
if (!err && arg) {
ide_set_xfer_rate(drive, (u8) arg);
ide_driveid_update(drive);
}
return err;
}
/**
* ide_add_generic_settings - generic ide settings
* @drive: drive being configured
*
* Add the generic parts of the system settings to the /proc files.
* The caller must not be holding the ide_setting_sem.
*/
void ide_add_generic_settings (ide_drive_t *drive)
{
/*
* drive setting name read/write access 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, TYPE_BYTE, 0, 1 + (SUPPORT_VLB_SYNC << 1), 1, 1, &drive->io_32bit, set_io_32bit, 0);
__ide_add_setting(drive, "keepsettings", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->keep_settings, NULL, 0);
__ide_add_setting(drive, "nice1", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->nice1, NULL, 0);
__ide_add_setting(drive, "pio_mode", SETTING_WRITE, TYPE_BYTE, 0, 255, 1, 1, NULL, set_pio_mode, 0);
__ide_add_setting(drive, "unmaskirq", drive->no_unmask ? SETTING_READ : SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->unmask, NULL, 0);
__ide_add_setting(drive, "using_dma", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->using_dma, set_using_dma, 0);
__ide_add_setting(drive, "init_speed", SETTING_RW, TYPE_BYTE, 0, 70, 1, 1, &drive->init_speed, NULL, 0);
__ide_add_setting(drive, "current_speed", SETTING_RW, TYPE_BYTE, 0, 70, 1, 1, &drive->current_speed, set_xfer_rate, 0);
__ide_add_setting(drive, "number", SETTING_RW, TYPE_BYTE, 0, 3, 1, 1, &drive->dn, NULL, 0);
}
/**
* system_bus_clock - clock guess
*
@@ -1922,54 +1663,6 @@ static void __init probe_for_hwifs (void)
#endif
}
void ide_register_subdriver(ide_drive_t *drive, ide_driver_t *driver)
{
#ifdef CONFIG_IDE_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_IDE_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
*/