aboutsummaryrefslogtreecommitdiff
path: root/drivers/ide
diff options
context:
space:
mode:
authorElias Oltmanns <eo@nebensachen.de>2008-10-10 22:39:40 +0200
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-10-10 22:39:40 +0200
commit92f1f8fd8040e7b50a67a850a935509bb01201bb (patch)
treedf27468982bc64f0a6fdc54f05153e382ca63a1b /drivers/ide
parentd6e2955a6b82d2312b5ff885ce13c8ab54d59d96 (diff)
ide: Remove ide_spin_wait_hwgroup() and use special requests instead
Use a special request for serialisation purposes and get rid of the awkward ide_spin_wait_hwgroup(). This also involves converting the ide_devset structure so it can be shared by the /proc and the ioctl code. Signed-off-by: Elias Oltmanns <eo@nebensachen.de> [bart: use rq->cmd[] directly] Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide')
-rw-r--r--drivers/ide/ide-cd.c8
-rw-r--r--drivers/ide/ide-disk.c66
-rw-r--r--drivers/ide/ide-floppy.c20
-rw-r--r--drivers/ide/ide-io.c40
-rw-r--r--drivers/ide/ide-ioctls.c21
-rw-r--r--drivers/ide/ide-proc.c102
-rw-r--r--drivers/ide/ide-tape.c48
-rw-r--r--drivers/ide/ide.c81
8 files changed, 184 insertions, 202 deletions
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 7ea90de5505..465a92ca017 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -1809,11 +1809,11 @@ static ide_proc_entry_t idecd_proc[] = {
{ NULL, 0, NULL, NULL }
};
-ide_devset_rw(dsc_overlap, 0, 1, dsc_overlap);
+ide_devset_rw_field(dsc_overlap, dsc_overlap);
-static const struct ide_devset *idecd_settings[] = {
- &ide_devset_dsc_overlap,
- NULL
+static const struct ide_proc_devset idecd_settings[] = {
+ IDE_PROC_DEVSET(dsc_overlap, 0, 1),
+ { 0 },
};
#endif
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 11906347082..01846f244b4 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -575,11 +575,8 @@ static int set_nowerr(ide_drive_t *drive, int arg)
if (arg < 0 || arg > 1)
return -EINVAL;
- if (ide_spin_wait_hwgroup(drive))
- return -EBUSY;
drive->nowerr = arg;
drive->bad_wstat = arg ? BAD_R_STAT : BAD_W_STAT;
- spin_unlock_irq(&ide_lock);
return 0;
}
@@ -702,33 +699,34 @@ static int set_addressing(ide_drive_t *drive, int arg)
return 0;
}
+ide_devset_rw(acoustic, acoustic);
+ide_devset_rw(address, addressing);
+ide_devset_rw(multcount, multcount);
+ide_devset_rw(wcache, wcache);
+
+ide_devset_rw_sync(nowerr, nowerr);
+
#ifdef CONFIG_IDE_PROC_FS
-ide_devset_rw_nolock(acoustic, 0, 254, acoustic);
-ide_devset_rw_nolock(address, 0, 2, addressing);
-ide_devset_rw_nolock(multcount, 0, 16, multcount);
-ide_devset_rw_nolock(nowerr, 0, 1, nowerr);
-ide_devset_rw_nolock(wcache, 0, 1, wcache);
-
-ide_devset_rw(bios_cyl, 0, 65535, bios_cyl);
-ide_devset_rw(bios_head, 0, 255, bios_head);
-ide_devset_rw(bios_sect, 0, 63, bios_sect);
-ide_devset_rw(failures, 0, 65535, failures);
-ide_devset_rw(lun, 0, 7, lun);
-ide_devset_rw(max_failures, 0, 65535, max_failures);
-
-static const struct ide_devset *idedisk_settings[] = {
- &ide_devset_acoustic,
- &ide_devset_address,
- &ide_devset_bios_cyl,
- &ide_devset_bios_head,
- &ide_devset_bios_sect,
- &ide_devset_failures,
- &ide_devset_lun,
- &ide_devset_max_failures,
- &ide_devset_multcount,
- &ide_devset_nowerr,
- &ide_devset_wcache,
- NULL
+ide_devset_rw_field(bios_cyl, bios_cyl);
+ide_devset_rw_field(bios_head, bios_head);
+ide_devset_rw_field(bios_sect, bios_sect);
+ide_devset_rw_field(failures, failures);
+ide_devset_rw_field(lun, lun);
+ide_devset_rw_field(max_failures, max_failures);
+
+static const struct ide_proc_devset idedisk_settings[] = {
+ IDE_PROC_DEVSET(acoustic, 0, 254),
+ IDE_PROC_DEVSET(address, 0, 2),
+ IDE_PROC_DEVSET(bios_cyl, 0, 65535),
+ IDE_PROC_DEVSET(bios_head, 0, 255),
+ IDE_PROC_DEVSET(bios_sect, 0, 63),
+ IDE_PROC_DEVSET(failures, 0, 65535),
+ IDE_PROC_DEVSET(lun, 0, 7),
+ IDE_PROC_DEVSET(max_failures, 0, 65535),
+ IDE_PROC_DEVSET(multcount, 0, 16),
+ IDE_PROC_DEVSET(nowerr, 0, 1),
+ IDE_PROC_DEVSET(wcache, 0, 1),
+ { 0 },
};
#endif
@@ -1001,11 +999,11 @@ static int idedisk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
}
static const struct ide_ioctl_devset ide_disk_ioctl_settings[] = {
-{ HDIO_GET_ADDRESS, HDIO_SET_ADDRESS, get_addressing, set_addressing },
-{ HDIO_GET_MULTCOUNT, HDIO_SET_MULTCOUNT, get_multcount, set_multcount },
-{ HDIO_GET_NOWERR, HDIO_SET_NOWERR, get_nowerr, set_nowerr },
-{ HDIO_GET_WCACHE, HDIO_SET_WCACHE, get_wcache, set_wcache },
-{ HDIO_GET_ACOUSTIC, HDIO_SET_ACOUSTIC, get_acoustic, set_acoustic },
+{ HDIO_GET_ADDRESS, HDIO_SET_ADDRESS, &ide_devset_address },
+{ HDIO_GET_MULTCOUNT, HDIO_SET_MULTCOUNT, &ide_devset_multcount },
+{ HDIO_GET_NOWERR, HDIO_SET_NOWERR, &ide_devset_nowerr },
+{ HDIO_GET_WCACHE, HDIO_SET_WCACHE, &ide_devset_wcache },
+{ HDIO_GET_ACOUSTIC, HDIO_SET_ACOUSTIC, &ide_devset_acoustic },
{ 0 }
};
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index a63aba2c826..d36f155470a 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -629,9 +629,9 @@ static sector_t idefloppy_capacity(ide_drive_t *drive)
}
#ifdef CONFIG_IDE_PROC_FS
-ide_devset_rw(bios_cyl, 0, 1023, bios_cyl);
-ide_devset_rw(bios_head, 0, 255, bios_head);
-ide_devset_rw(bios_sect, 0, 63, bios_sect);
+ide_devset_rw_field(bios_cyl, bios_cyl);
+ide_devset_rw_field(bios_head, bios_head);
+ide_devset_rw_field(bios_sect, bios_sect);
static int get_ticks(ide_drive_t *drive)
{
@@ -646,14 +646,14 @@ static int set_ticks(ide_drive_t *drive, int arg)
return 0;
}
-IDE_DEVSET(ticks, S_RW, 0, 255, get_ticks, set_ticks);
+IDE_DEVSET(ticks, DS_SYNC, get_ticks, set_ticks);
-static const struct ide_devset *idefloppy_settings[] = {
- &ide_devset_bios_cyl,
- &ide_devset_bios_head,
- &ide_devset_bios_sect,
- &ide_devset_ticks,
- NULL
+static const struct ide_proc_devset idefloppy_settings[] = {
+ IDE_PROC_DEVSET(bios_cyl, 0, 1023),
+ IDE_PROC_DEVSET(bios_head, 0, 255),
+ IDE_PROC_DEVSET(bios_sect, 0, 63),
+ IDE_PROC_DEVSET(ticks, 0, 255),
+ { 0 },
};
#endif
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index ec6664b0d3a..1c51949833b 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -716,9 +716,49 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
return ide_stopped;
}
+int ide_devset_execute(ide_drive_t *drive, const struct ide_devset *setting,
+ int arg)
+{
+ struct request_queue *q = drive->queue;
+ struct request *rq;
+ int ret = 0;
+
+ if (!(setting->flags & DS_SYNC))
+ return setting->set(drive, arg);
+
+ rq = blk_get_request(q, READ, GFP_KERNEL);
+ if (!rq)
+ return -ENOMEM;
+
+ rq->cmd_type = REQ_TYPE_SPECIAL;
+ rq->cmd_len = 5;
+ rq->cmd[0] = REQ_DEVSET_EXEC;
+ *(int *)&rq->cmd[1] = arg;
+ rq->special = setting->set;
+
+ if (blk_execute_rq(q, NULL, rq, 0))
+ ret = rq->errors;
+ blk_put_request(rq);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(ide_devset_execute);
+
static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq)
{
switch (rq->cmd[0]) {
+ case REQ_DEVSET_EXEC:
+ {
+ int err, (*setfunc)(ide_drive_t *, int) = rq->special;
+
+ err = setfunc(drive, *(int *)&rq->cmd[1]);
+ if (err)
+ rq->errors = err;
+ else
+ err = 1;
+ ide_end_request(drive, err, 0);
+ return ide_stopped;
+ }
case REQ_DRIVE_RESET:
return ide_do_reset(drive);
default:
diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c
index 7a0d62e7286..cf01564901a 100644
--- a/drivers/ide/ide-ioctls.c
+++ b/drivers/ide/ide-ioctls.c
@@ -6,11 +6,11 @@
#include <linux/ide.h>
static const struct ide_ioctl_devset ide_ioctl_settings[] = {
-{ HDIO_GET_32BIT, HDIO_SET_32BIT, get_io_32bit, set_io_32bit },
-{ HDIO_GET_KEEPSETTINGS, HDIO_SET_KEEPSETTINGS, get_ksettings, set_ksettings },
-{ HDIO_GET_UNMASKINTR, HDIO_SET_UNMASKINTR, get_unmaskirq, set_unmaskirq },
-{ HDIO_GET_DMA, HDIO_SET_DMA, get_using_dma, set_using_dma },
-{ -1, HDIO_SET_PIO_MODE, NULL, set_pio_mode },
+{ HDIO_GET_32BIT, HDIO_SET_32BIT, &ide_devset_io_32bit },
+{ HDIO_GET_KEEPSETTINGS, HDIO_SET_KEEPSETTINGS, &ide_devset_keepsettings },
+{ HDIO_GET_UNMASKINTR, HDIO_SET_UNMASKINTR, &ide_devset_unmaskirq },
+{ HDIO_GET_DMA, HDIO_SET_DMA, &ide_devset_using_dma },
+{ -1, HDIO_SET_PIO_MODE, &ide_devset_pio_mode },
{ 0 }
};
@@ -18,13 +18,14 @@ int ide_setting_ioctl(ide_drive_t *drive, struct block_device *bdev,
unsigned int cmd, unsigned long arg,
const struct ide_ioctl_devset *s)
{
+ const struct ide_devset *ds;
unsigned long flags;
int err = -EOPNOTSUPP;
- for (; s->get_ioctl; s++) {
- if (s->get && s->get_ioctl == cmd)
+ for (; (ds = s->setting); s++) {
+ if (ds->get && s->get_ioctl == cmd)
goto read_val;
- else if (s->set && s->set_ioctl == cmd)
+ else if (ds->set && s->set_ioctl == cmd)
goto set_val;
}
@@ -33,7 +34,7 @@ int ide_setting_ioctl(ide_drive_t *drive, struct block_device *bdev,
read_val:
mutex_lock(&ide_setting_mtx);
spin_lock_irqsave(&ide_lock, flags);
- err = s->get(drive);
+ err = ds->get(drive);
spin_unlock_irqrestore(&ide_lock, flags);
mutex_unlock(&ide_setting_mtx);
return err >= 0 ? put_user(err, (long __user *)arg) : err;
@@ -46,7 +47,7 @@ set_val:
err = -EACCES;
else {
mutex_lock(&ide_setting_mtx);
- err = s->set(drive, arg);
+ err = ide_devset_execute(drive, ds, arg);
mutex_unlock(&ide_setting_mtx);
}
}
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index 6489c647be8..e7030a49146 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -124,15 +124,16 @@ static int proc_ide_read_identify
* setting semaphore
*/
-static const struct ide_devset *ide_find_setting(const struct ide_devset **st,
- char *name)
+static
+const struct ide_proc_devset *ide_find_setting(const struct ide_proc_devset *st,
+ char *name)
{
- while (*st) {
- if (strcmp((*st)->name, name) == 0)
+ while (st->name) {
+ if (strcmp(st->name, name) == 0)
break;
st++;
}
- return *st;
+ return st->name ? st : NULL;
}
/**
@@ -149,15 +150,16 @@ static const struct ide_devset *ide_find_setting(const struct ide_devset **st,
*/
static int ide_read_setting(ide_drive_t *drive,
- const struct ide_devset *setting)
+ const struct ide_proc_devset *setting)
{
+ const struct ide_devset *ds = setting->setting;
int val = -EINVAL;
- if ((setting->flags & S_READ)) {
+ if (ds->get) {
unsigned long flags;
spin_lock_irqsave(&ide_lock, flags);
- val = setting->get(drive);
+ val = ds->get(drive);
spin_unlock_irqrestore(&ide_lock, flags);
}
@@ -183,24 +185,21 @@ static int ide_read_setting(ide_drive_t *drive,
*/
static int ide_write_setting(ide_drive_t *drive,
- const struct ide_devset *setting, int val)
+ const struct ide_proc_devset *setting, int val)
{
+ const struct ide_devset *ds = setting->setting;
+
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
- if (setting->set && (setting->flags & S_NOLOCK))
- return setting->set(drive, val);
- if (!(setting->flags & S_WRITE))
+ if (!ds->set)
return -EPERM;
- if (val < setting->min || val > setting->max)
+ if ((ds->flags & DS_SYNC)
+ && (val < setting->min || val > setting->max))
return -EINVAL;
- if (ide_spin_wait_hwgroup(drive))
- return -EBUSY;
- setting->set(drive, val);
- spin_unlock_irq(&ide_lock);
- return 0;
+ return ide_devset_execute(drive, ds, val);
}
-static ide_devset_get(xfer_rate, current_speed);
+ide_devset_get(xfer_rate, current_speed);
static int set_xfer_rate (ide_drive_t *drive, int arg)
{
@@ -226,29 +225,22 @@ static int set_xfer_rate (ide_drive_t *drive, int arg)
return err;
}
-ide_devset_rw_nolock(current_speed, 0, 70, xfer_rate);
-ide_devset_rw_nolock(io_32bit, 0, 1 + (SUPPORT_VLB_SYNC << 1), io_32bit);
-ide_devset_rw_nolock(keepsettings, 0, 1, ksettings);
-ide_devset_rw_nolock(unmaskirq, 0, 1, unmaskirq);
-ide_devset_rw_nolock(using_dma, 0, 1, using_dma);
-
-ide_devset_w_nolock(pio_mode, 0, 255, pio_mode);
-
-ide_devset_rw(init_speed, 0, 70, init_speed);
-ide_devset_rw(nice1, 0, 1, nice1);
-ide_devset_rw(number, 0, 3, dn);
-
-static const struct ide_devset *ide_generic_settings[] = {
- &ide_devset_current_speed,
- &ide_devset_init_speed,
- &ide_devset_io_32bit,
- &ide_devset_keepsettings,
- &ide_devset_nice1,
- &ide_devset_number,
- &ide_devset_pio_mode,
- &ide_devset_unmaskirq,
- &ide_devset_using_dma,
- NULL
+ide_devset_rw(current_speed, xfer_rate);
+ide_devset_rw_field(init_speed, init_speed);
+ide_devset_rw_field(nice1, nice1);
+ide_devset_rw_field(number, dn);
+
+static const struct ide_proc_devset ide_generic_settings[] = {
+ IDE_PROC_DEVSET(current_speed, 0, 70),
+ IDE_PROC_DEVSET(init_speed, 0, 70),
+ IDE_PROC_DEVSET(io_32bit, 0, 1 + (SUPPORT_VLB_SYNC << 1)),
+ IDE_PROC_DEVSET(keepsettings, 0, 1),
+ IDE_PROC_DEVSET(nice1, 0, 1),
+ IDE_PROC_DEVSET(number, 0, 3),
+ IDE_PROC_DEVSET(pio_mode, 0, 255),
+ IDE_PROC_DEVSET(unmaskirq, 0, 1),
+ IDE_PROC_DEVSET(using_dma, 0, 1),
+ { 0 },
};
static void proc_ide_settings_warn(void)
@@ -266,7 +258,8 @@ static void proc_ide_settings_warn(void)
static int proc_ide_read_settings
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
- const struct ide_devset *setting, **g, **d;
+ const struct ide_proc_devset *setting, *g, *d;
+ const struct ide_devset *ds;
ide_drive_t *drive = (ide_drive_t *) data;
char *out = page;
int len, rc, mul_factor, div_factor;
@@ -278,17 +271,17 @@ static int proc_ide_read_settings
d = drive->settings;
out += sprintf(out, "name\t\t\tvalue\t\tmin\t\tmax\t\tmode\n");
out += sprintf(out, "----\t\t\t-----\t\t---\t\t---\t\t----\n");
- while (*g || (d && *d)) {
+ while (g->name || (d && d->name)) {
/* read settings in the alphabetical order */
- if (*g && d && *d) {
- if (strcmp((*d)->name, (*g)->name) < 0)
- setting = *d++;
+ if (g->name && d && d->name) {
+ if (strcmp(d->name, g->name) < 0)
+ setting = d++;
else
- setting = *g++;
- } else if (d && *d) {
- setting = *d++;
+ setting = g++;
+ } else if (d && d->name) {
+ setting = d++;
} else
- setting = *g++;
+ setting = g++;
mul_factor = setting->mulf ? setting->mulf(drive) : 1;
div_factor = setting->divf ? setting->divf(drive) : 1;
out += sprintf(out, "%-24s", setting->name);
@@ -298,9 +291,10 @@ static int proc_ide_read_settings
else
out += sprintf(out, "%-16s", "write-only");
out += sprintf(out, "%-16d%-16d", (setting->min * mul_factor + div_factor - 1) / div_factor, setting->max * mul_factor / div_factor);
- if (setting->flags & S_READ)
+ ds = setting->setting;
+ if (ds->get)
out += sprintf(out, "r");
- if (setting->flags & S_WRITE)
+ if (ds->set)
out += sprintf(out, "w");
out += sprintf(out, "\n");
}
@@ -319,7 +313,7 @@ static int proc_ide_write_settings(struct file *file, const char __user *buffer,
int for_real = 0, mul_factor, div_factor;
unsigned long n;
- const struct ide_devset *setting;
+ const struct ide_proc_devset *setting;
char *buf, *s;
if (!capable(CAP_SYS_ADMIN))
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 25190966ed3..f8c84df4a0b 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -2188,40 +2188,40 @@ static int set_##name(ide_drive_t *drive, int arg) \
return 0; \
}
-#define ide_tape_devset_rw(_name, _min, _max, _field, _mulf, _divf) \
+#define ide_tape_devset_rw_field(_name, _field) \
ide_tape_devset_get(_name, _field) \
ide_tape_devset_set(_name, _field) \
-__IDE_DEVSET(_name, S_RW, _min, _max, get_##_name, set_##_name, _mulf, _divf)
+IDE_DEVSET(_name, DS_SYNC, get_##_name, set_##_name)
-#define ide_tape_devset_r(_name, _min, _max, _field, _mulf, _divf) \
+#define ide_tape_devset_r_field(_name, _field) \
ide_tape_devset_get(_name, _field) \
-__IDE_DEVSET(_name, S_READ, _min, _max, get_##_name, NULL, _mulf, _divf)
+IDE_DEVSET(_name, 0, get_##_name, NULL)
static int mulf_tdsc(ide_drive_t *drive) { return 1000; }
static int divf_tdsc(ide_drive_t *drive) { return HZ; }
static int divf_buffer(ide_drive_t *drive) { return 2; }
static int divf_buffer_size(ide_drive_t *drive) { return 1024; }
-ide_devset_rw(dsc_overlap, 0, 1, dsc_overlap);
-
-ide_tape_devset_rw(debug_mask, 0, 0xffff, debug_mask, NULL, NULL);
-ide_tape_devset_rw(tdsc, IDETAPE_DSC_RW_MIN, IDETAPE_DSC_RW_MAX,
- best_dsc_rw_freq, mulf_tdsc, divf_tdsc);
-
-ide_tape_devset_r(avg_speed, 0, 0xffff, avg_speed, NULL, NULL);
-ide_tape_devset_r(speed, 0, 0xffff, caps[14], NULL, NULL);
-ide_tape_devset_r(buffer, 0, 0xffff, caps[16], NULL, divf_buffer);
-ide_tape_devset_r(buffer_size, 0, 0xffff, buffer_size, NULL, divf_buffer_size);
-
-static const struct ide_devset *idetape_settings[] = {
- &ide_devset_avg_speed,
- &ide_devset_buffer,
- &ide_devset_buffer_size,
- &ide_devset_debug_mask,
- &ide_devset_dsc_overlap,
- &ide_devset_speed,
- &ide_devset_tdsc,
- NULL
+ide_devset_rw_field(dsc_overlap, dsc_overlap);
+
+ide_tape_devset_rw_field(debug_mask, debug_mask);
+ide_tape_devset_rw_field(tdsc, best_dsc_rw_freq);
+
+ide_tape_devset_r_field(avg_speed, avg_speed);
+ide_tape_devset_r_field(speed, caps[14]);
+ide_tape_devset_r_field(buffer, caps[16]);
+ide_tape_devset_r_field(buffer_size, buffer_size);
+
+static const struct ide_proc_devset idetape_settings[] = {
+ __IDE_PROC_DEVSET(avg_speed, 0, 0xffff, NULL, NULL),
+ __IDE_PROC_DEVSET(buffer, 0, 0xffff, NULL, divf_buffer),
+ __IDE_PROC_DEVSET(buffer_size, 0, 0xffff, NULL, divf_buffer_size),
+ __IDE_PROC_DEVSET(debug_mask, 0, 0xffff, NULL, NULL),
+ __IDE_PROC_DEVSET(dsc_overlap, 0, 1, NULL, NULL),
+ __IDE_PROC_DEVSET(speed, 0, 0xffff, NULL, NULL),
+ __IDE_PROC_DEVSET(tdsc, IDETAPE_DSC_RW_MIN, IDETAPE_DSC_RW_MAX,
+ mulf_tdsc, divf_tdsc),
+ { 0 },
};
#endif
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 349d7fa7558..9dcf5aed92c 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -250,42 +250,9 @@ void ide_init_port_hw(ide_hwif_t *hwif, hw_regs_t *hw)
DEFINE_MUTEX(ide_setting_mtx);
-/**
- * ide_spin_wait_hwgroup - wait for group
- * @drive: drive in the group
- *
- * Wait for an IDE device group to go non busy and then return
- * holding the ide_lock which guards the hwgroup->busy status
- * and right to use it.
- */
-
-int ide_spin_wait_hwgroup (ide_drive_t *drive)
-{
- ide_hwgroup_t *hwgroup = HWGROUP(drive);
- unsigned long timeout = jiffies + (3 * HZ);
-
- spin_lock_irq(&ide_lock);
-
- while (hwgroup->busy) {
- unsigned long lflags;
- spin_unlock_irq(&ide_lock);
- local_irq_set(lflags);
- if (time_after(jiffies, timeout)) {
- local_irq_restore(lflags);
- printk(KERN_ERR "%s: channel busy\n", drive->name);
- return -EBUSY;
- }
- local_irq_restore(lflags);
- spin_lock_irq(&ide_lock);
- }
- return 0;
-}
-
-EXPORT_SYMBOL(ide_spin_wait_hwgroup);
-
ide_devset_get(io_32bit, io_32bit);
-int set_io_32bit(ide_drive_t *drive, int arg)
+static int set_io_32bit(ide_drive_t *drive, int arg)
{
if (drive->no_io_32bit)
return -EPERM;
@@ -293,37 +260,28 @@ int set_io_32bit(ide_drive_t *drive, int arg)
if (arg < 0 || arg > 1 + (SUPPORT_VLB_SYNC << 1))
return -EINVAL;
- if (ide_spin_wait_hwgroup(drive))
- return -EBUSY;
-
drive->io_32bit = arg;
- spin_unlock_irq(&ide_lock);
-
return 0;
}
ide_devset_get(ksettings, keep_settings);
-int set_ksettings(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;
}
ide_devset_get(using_dma, using_dma);
-int set_using_dma(ide_drive_t *drive, int arg)
+static 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)
@@ -332,18 +290,9 @@ int set_using_dma(ide_drive_t *drive, int arg)
if (ata_id_has_dma(drive->id) == 0)
goto out;
- if (hwif->dma_ops == NULL)
+ if (drive->hwif->dma_ops == NULL)
goto out;
- err = -EBUSY;
- if (ide_spin_wait_hwgroup(drive))
- goto out;
- /*
- * set ->busy flag, unlock and let it ride
- */
- hwif->hwgroup->busy = 1;
- spin_unlock_irq(&ide_lock);
-
err = 0;
if (arg) {
@@ -352,12 +301,6 @@ int set_using_dma(ide_drive_t *drive, int arg)
} else
ide_dma_off(drive);
- /*
- * lock, clear ->busy flag and unlock before leaving
- */
- spin_lock_irq(&ide_lock);
- hwif->hwgroup->busy = 0;
- spin_unlock_irq(&ide_lock);
out:
return err;
#else
@@ -368,7 +311,7 @@ out:
#endif
}
-int set_pio_mode(ide_drive_t *drive, int arg)
+static int set_pio_mode(ide_drive_t *drive, int arg)
{
struct request *rq;
ide_hwif_t *hwif = drive->hwif;
@@ -398,7 +341,7 @@ int set_pio_mode(ide_drive_t *drive, int arg)
ide_devset_get(unmaskirq, unmask);
-int set_unmaskirq(ide_drive_t *drive, int arg)
+static int set_unmaskirq(ide_drive_t *drive, int arg)
{
if (drive->no_unmask)
return -EPERM;
@@ -406,14 +349,20 @@ int set_unmaskirq(ide_drive_t *drive, int arg)
if (arg < 0 || arg > 1)
return -EINVAL;
- if (ide_spin_wait_hwgroup(drive))
- return -EBUSY;
drive->unmask = arg;
- spin_unlock_irq(&ide_lock);
return 0;
}
+#define ide_gen_devset_rw(_name, _func) \
+__IDE_DEVSET(_name, DS_SYNC, get_##_func, set_##_func)
+
+ide_gen_devset_rw(io_32bit, io_32bit);
+ide_gen_devset_rw(keepsettings, ksettings);
+ide_gen_devset_rw(unmaskirq, unmaskirq);
+ide_gen_devset_rw(using_dma, using_dma);
+__IDE_DEVSET(pio_mode, 0, NULL, set_pio_mode);
+
static int generic_ide_suspend(struct device *dev, pm_message_t mesg)
{
ide_drive_t *drive = dev->driver_data;