aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide
diff options
context:
space:
mode:
authorElias Oltmanns <eo@nebensachen.de>2008-10-10 16:39:40 -0400
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-10-10 16:39:40 -0400
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 7ea90de55058..465a92ca0179 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -1809,11 +1809,11 @@ static ide_proc_entry_t idecd_proc[] = {
1809 { NULL, 0, NULL, NULL } 1809 { NULL, 0, NULL, NULL }
1810}; 1810};
1811 1811
1812ide_devset_rw(dsc_overlap, 0, 1, dsc_overlap); 1812ide_devset_rw_field(dsc_overlap, dsc_overlap);
1813 1813
1814static const struct ide_devset *idecd_settings[] = { 1814static const struct ide_proc_devset idecd_settings[] = {
1815 &ide_devset_dsc_overlap, 1815 IDE_PROC_DEVSET(dsc_overlap, 0, 1),
1816 NULL 1816 { 0 },
1817}; 1817};
1818#endif 1818#endif
1819 1819
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 119063470820..01846f244b40 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)
575 if (arg < 0 || arg > 1) 575 if (arg < 0 || arg > 1)
576 return -EINVAL; 576 return -EINVAL;
577 577
578 if (ide_spin_wait_hwgroup(drive))
579 return -EBUSY;
580 drive->nowerr = arg; 578 drive->nowerr = arg;
581 drive->bad_wstat = arg ? BAD_R_STAT : BAD_W_STAT; 579 drive->bad_wstat = arg ? BAD_R_STAT : BAD_W_STAT;
582 spin_unlock_irq(&ide_lock);
583 return 0; 580 return 0;
584} 581}
585 582
@@ -702,33 +699,34 @@ static int set_addressing(ide_drive_t *drive, int arg)
702 return 0; 699 return 0;
703} 700}
704 701
702ide_devset_rw(acoustic, acoustic);
703ide_devset_rw(address, addressing);
704ide_devset_rw(multcount, multcount);
705ide_devset_rw(wcache, wcache);
706
707ide_devset_rw_sync(nowerr, nowerr);
708
705#ifdef CONFIG_IDE_PROC_FS 709#ifdef CONFIG_IDE_PROC_FS
706ide_devset_rw_nolock(acoustic, 0, 254, acoustic); 710ide_devset_rw_field(bios_cyl, bios_cyl);
707ide_devset_rw_nolock(address, 0, 2, addressing); 711ide_devset_rw_field(bios_head, bios_head);
708ide_devset_rw_nolock(multcount, 0, 16, multcount); 712ide_devset_rw_field(bios_sect, bios_sect);
709ide_devset_rw_nolock(nowerr, 0, 1, nowerr); 713ide_devset_rw_field(failures, failures);
710ide_devset_rw_nolock(wcache, 0, 1, wcache); 714ide_devset_rw_field(lun, lun);
711 715ide_devset_rw_field(max_failures, max_failures);
712ide_devset_rw(bios_cyl, 0, 65535, bios_cyl); 716
713ide_devset_rw(bios_head, 0, 255, bios_head); 717static const struct ide_proc_devset idedisk_settings[] = {
714ide_devset_rw(bios_sect, 0, 63, bios_sect); 718 IDE_PROC_DEVSET(acoustic, 0, 254),
715ide_devset_rw(failures, 0, 65535, failures); 719 IDE_PROC_DEVSET(address, 0, 2),
716ide_devset_rw(lun, 0, 7, lun); 720 IDE_PROC_DEVSET(bios_cyl, 0, 65535),
717ide_devset_rw(max_failures, 0, 65535, max_failures); 721 IDE_PROC_DEVSET(bios_head, 0, 255),
718 722 IDE_PROC_DEVSET(bios_sect, 0, 63),
719static const struct ide_devset *idedisk_settings[] = { 723 IDE_PROC_DEVSET(failures, 0, 65535),
720 &ide_devset_acoustic, 724 IDE_PROC_DEVSET(lun, 0, 7),
721 &ide_devset_address, 725 IDE_PROC_DEVSET(max_failures, 0, 65535),
722 &ide_devset_bios_cyl, 726 IDE_PROC_DEVSET(multcount, 0, 16),
723 &ide_devset_bios_head, 727 IDE_PROC_DEVSET(nowerr, 0, 1),
724 &ide_devset_bios_sect, 728 IDE_PROC_DEVSET(wcache, 0, 1),
725 &ide_devset_failures, 729 { 0 },
726 &ide_devset_lun,
727 &ide_devset_max_failures,
728 &ide_devset_multcount,
729 &ide_devset_nowerr,
730 &ide_devset_wcache,
731 NULL
732}; 730};
733#endif 731#endif
734 732
@@ -1001,11 +999,11 @@ static int idedisk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1001} 999}
1002 1000
1003static const struct ide_ioctl_devset ide_disk_ioctl_settings[] = { 1001static const struct ide_ioctl_devset ide_disk_ioctl_settings[] = {
1004{ HDIO_GET_ADDRESS, HDIO_SET_ADDRESS, get_addressing, set_addressing }, 1002{ HDIO_GET_ADDRESS, HDIO_SET_ADDRESS, &ide_devset_address },
1005{ HDIO_GET_MULTCOUNT, HDIO_SET_MULTCOUNT, get_multcount, set_multcount }, 1003{ HDIO_GET_MULTCOUNT, HDIO_SET_MULTCOUNT, &ide_devset_multcount },
1006{ HDIO_GET_NOWERR, HDIO_SET_NOWERR, get_nowerr, set_nowerr }, 1004{ HDIO_GET_NOWERR, HDIO_SET_NOWERR, &ide_devset_nowerr },
1007{ HDIO_GET_WCACHE, HDIO_SET_WCACHE, get_wcache, set_wcache }, 1005{ HDIO_GET_WCACHE, HDIO_SET_WCACHE, &ide_devset_wcache },
1008{ HDIO_GET_ACOUSTIC, HDIO_SET_ACOUSTIC, get_acoustic, set_acoustic }, 1006{ HDIO_GET_ACOUSTIC, HDIO_SET_ACOUSTIC, &ide_devset_acoustic },
1009{ 0 } 1007{ 0 }
1010}; 1008};
1011 1009
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index a63aba2c8265..d36f155470a4 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)
629} 629}
630 630
631#ifdef CONFIG_IDE_PROC_FS 631#ifdef CONFIG_IDE_PROC_FS
632ide_devset_rw(bios_cyl, 0, 1023, bios_cyl); 632ide_devset_rw_field(bios_cyl, bios_cyl);
633ide_devset_rw(bios_head, 0, 255, bios_head); 633ide_devset_rw_field(bios_head, bios_head);
634ide_devset_rw(bios_sect, 0, 63, bios_sect); 634ide_devset_rw_field(bios_sect, bios_sect);
635 635
636static int get_ticks(ide_drive_t *drive) 636static int get_ticks(ide_drive_t *drive)
637{ 637{
@@ -646,14 +646,14 @@ static int set_ticks(ide_drive_t *drive, int arg)
646 return 0; 646 return 0;
647} 647}
648 648
649IDE_DEVSET(ticks, S_RW, 0, 255, get_ticks, set_ticks); 649IDE_DEVSET(ticks, DS_SYNC, get_ticks, set_ticks);
650 650
651static const struct ide_devset *idefloppy_settings[] = { 651static const struct ide_proc_devset idefloppy_settings[] = {
652 &ide_devset_bios_cyl, 652 IDE_PROC_DEVSET(bios_cyl, 0, 1023),
653 &ide_devset_bios_head, 653 IDE_PROC_DEVSET(bios_head, 0, 255),
654 &ide_devset_bios_sect, 654 IDE_PROC_DEVSET(bios_sect, 0, 63),
655 &ide_devset_ticks, 655 IDE_PROC_DEVSET(ticks, 0, 255),
656 NULL 656 { 0 },
657}; 657};
658#endif 658#endif
659 659
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index ec6664b0d3a9..1c51949833be 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,
716 return ide_stopped; 716 return ide_stopped;
717} 717}
718 718
719int ide_devset_execute(ide_drive_t *drive, const struct ide_devset *setting,
720 int arg)
721{
722 struct request_queue *q = drive->queue;
723 struct request *rq;
724 int ret = 0;
725
726 if (!(setting->flags & DS_SYNC))
727 return setting->set(drive, arg);
728
729 rq = blk_get_request(q, READ, GFP_KERNEL);
730 if (!rq)
731 return -ENOMEM;
732
733 rq->cmd_type = REQ_TYPE_SPECIAL;
734 rq->cmd_len = 5;
735 rq->cmd[0] = REQ_DEVSET_EXEC;
736 *(int *)&rq->cmd[1] = arg;
737 rq->special = setting->set;
738
739 if (blk_execute_rq(q, NULL, rq, 0))
740 ret = rq->errors;
741 blk_put_request(rq);
742
743 return ret;
744}
745EXPORT_SYMBOL_GPL(ide_devset_execute);
746
719static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq) 747static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq)
720{ 748{
721 switch (rq->cmd[0]) { 749 switch (rq->cmd[0]) {
750 case REQ_DEVSET_EXEC:
751 {
752 int err, (*setfunc)(ide_drive_t *, int) = rq->special;
753
754 err = setfunc(drive, *(int *)&rq->cmd[1]);
755 if (err)
756 rq->errors = err;
757 else
758 err = 1;
759 ide_end_request(drive, err, 0);
760 return ide_stopped;
761 }
722 case REQ_DRIVE_RESET: 762 case REQ_DRIVE_RESET:
723 return ide_do_reset(drive); 763 return ide_do_reset(drive);
724 default: 764 default:
diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c
index 7a0d62e7286b..cf01564901af 100644
--- a/drivers/ide/ide-ioctls.c
+++ b/drivers/ide/ide-ioctls.c
@@ -6,11 +6,11 @@
6#include <linux/ide.h> 6#include <linux/ide.h>
7 7
8static const struct ide_ioctl_devset ide_ioctl_settings[] = { 8static const struct ide_ioctl_devset ide_ioctl_settings[] = {
9{ HDIO_GET_32BIT, HDIO_SET_32BIT, get_io_32bit, set_io_32bit }, 9{ HDIO_GET_32BIT, HDIO_SET_32BIT, &ide_devset_io_32bit },
10{ HDIO_GET_KEEPSETTINGS, HDIO_SET_KEEPSETTINGS, get_ksettings, set_ksettings }, 10{ HDIO_GET_KEEPSETTINGS, HDIO_SET_KEEPSETTINGS, &ide_devset_keepsettings },
11{ HDIO_GET_UNMASKINTR, HDIO_SET_UNMASKINTR, get_unmaskirq, set_unmaskirq }, 11{ HDIO_GET_UNMASKINTR, HDIO_SET_UNMASKINTR, &ide_devset_unmaskirq },
12{ HDIO_GET_DMA, HDIO_SET_DMA, get_using_dma, set_using_dma }, 12{ HDIO_GET_DMA, HDIO_SET_DMA, &ide_devset_using_dma },
13{ -1, HDIO_SET_PIO_MODE, NULL, set_pio_mode }, 13{ -1, HDIO_SET_PIO_MODE, &ide_devset_pio_mode },
14{ 0 } 14{ 0 }
15}; 15};
16 16
@@ -18,13 +18,14 @@ int ide_setting_ioctl(ide_drive_t *drive, struct block_device *bdev,
18 unsigned int cmd, unsigned long arg, 18 unsigned int cmd, unsigned long arg,
19 const struct ide_ioctl_devset *s) 19 const struct ide_ioctl_devset *s)
20{ 20{
21 const struct ide_devset *ds;
21 unsigned long flags; 22 unsigned long flags;
22 int err = -EOPNOTSUPP; 23 int err = -EOPNOTSUPP;
23 24
24 for (; s->get_ioctl; s++) { 25 for (; (ds = s->setting); s++) {
25 if (s->get && s->get_ioctl == cmd) 26 if (ds->get && s->get_ioctl == cmd)
26 goto read_val; 27 goto read_val;
27 else if (s->set && s->set_ioctl == cmd) 28 else if (ds->set && s->set_ioctl == cmd)
28 goto set_val; 29 goto set_val;
29 } 30 }
30 31
@@ -33,7 +34,7 @@ int ide_setting_ioctl(ide_drive_t *drive, struct block_device *bdev,
33read_val: 34read_val:
34 mutex_lock(&ide_setting_mtx); 35 mutex_lock(&ide_setting_mtx);
35 spin_lock_irqsave(&ide_lock, flags); 36 spin_lock_irqsave(&ide_lock, flags);
36 err = s->get(drive); 37 err = ds->get(drive);
37 spin_unlock_irqrestore(&ide_lock, flags); 38 spin_unlock_irqrestore(&ide_lock, flags);
38 mutex_unlock(&ide_setting_mtx); 39 mutex_unlock(&ide_setting_mtx);
39 return err >= 0 ? put_user(err, (long __user *)arg) : err; 40 return err >= 0 ? put_user(err, (long __user *)arg) : err;
@@ -46,7 +47,7 @@ set_val:
46 err = -EACCES; 47 err = -EACCES;
47 else { 48 else {
48 mutex_lock(&ide_setting_mtx); 49 mutex_lock(&ide_setting_mtx);
49 err = s->set(drive, arg); 50 err = ide_devset_execute(drive, ds, arg);
50 mutex_unlock(&ide_setting_mtx); 51 mutex_unlock(&ide_setting_mtx);
51 } 52 }
52 } 53 }
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index 6489c647be82..e7030a491463 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -124,15 +124,16 @@ static int proc_ide_read_identify
124 * setting semaphore 124 * setting semaphore
125 */ 125 */
126 126
127static const struct ide_devset *ide_find_setting(const struct ide_devset **st, 127static
128 char *name) 128const struct ide_proc_devset *ide_find_setting(const struct ide_proc_devset *st,
129 char *name)
129{ 130{
130 while (*st) { 131 while (st->name) {
131 if (strcmp((*st)->name, name) == 0) 132 if (strcmp(st->name, name) == 0)
132 break; 133 break;
133 st++; 134 st++;
134 } 135 }
135 return *st; 136 return st->name ? st : NULL;
136} 137}
137 138
138/** 139/**
@@ -149,15 +150,16 @@ static const struct ide_devset *ide_find_setting(const struct ide_devset **st,
149 */ 150 */
150 151
151static int ide_read_setting(ide_drive_t *drive, 152static int ide_read_setting(ide_drive_t *drive,
152 const struct ide_devset *setting) 153 const struct ide_proc_devset *setting)
153{ 154{
155 const struct ide_devset *ds = setting->setting;
154 int val = -EINVAL; 156 int val = -EINVAL;
155 157
156 if ((setting->flags & S_READ)) { 158 if (ds->get) {
157 unsigned long flags; 159 unsigned long flags;
158 160
159 spin_lock_irqsave(&ide_lock, flags); 161 spin_lock_irqsave(&ide_lock, flags);
160 val = setting->get(drive); 162 val = ds->get(drive);
161 spin_unlock_irqrestore(&ide_lock, flags); 163 spin_unlock_irqrestore(&ide_lock, flags);
162 } 164 }
163 165
@@ -183,24 +185,21 @@ static int ide_read_setting(ide_drive_t *drive,
183 */ 185 */
184 186
185static int ide_write_setting(ide_drive_t *drive, 187static int ide_write_setting(ide_drive_t *drive,
186 const struct ide_devset *setting, int val) 188 const struct ide_proc_devset *setting, int val)
187{ 189{
190 const struct ide_devset *ds = setting->setting;
191
188 if (!capable(CAP_SYS_ADMIN)) 192 if (!capable(CAP_SYS_ADMIN))
189 return -EACCES; 193 return -EACCES;
190 if (setting->set && (setting->flags & S_NOLOCK)) 194 if (!ds->set)
191 return setting->set(drive, val);
192 if (!(setting->flags & S_WRITE))
193 return -EPERM; 195 return -EPERM;
194 if (val < setting->min || val > setting->max) 196 if ((ds->flags & DS_SYNC)
197 && (val < setting->min || val > setting->max))
195 return -EINVAL; 198 return -EINVAL;
196 if (ide_spin_wait_hwgroup(drive)) 199 return ide_devset_execute(drive, ds, val);
197 return -EBUSY;
198 setting->set(drive, val);
199 spin_unlock_irq(&ide_lock);
200 return 0;
201} 200}
202 201
203static ide_devset_get(xfer_rate, current_speed); 202ide_devset_get(xfer_rate, current_speed);
204 203
205static int set_xfer_rate (ide_drive_t *drive, int arg) 204static int set_xfer_rate (ide_drive_t *drive, int arg)
206{ 205{
@@ -226,29 +225,22 @@ static int set_xfer_rate (ide_drive_t *drive, int arg)
226 return err; 225 return err;
227} 226}
228 227
229ide_devset_rw_nolock(current_speed, 0, 70, xfer_rate); 228ide_devset_rw(current_speed, xfer_rate);
230ide_devset_rw_nolock(io_32bit, 0, 1 + (SUPPORT_VLB_SYNC << 1), io_32bit); 229ide_devset_rw_field(init_speed, init_speed);
231ide_devset_rw_nolock(keepsettings, 0, 1, ksettings); 230ide_devset_rw_field(nice1, nice1);
232ide_devset_rw_nolock(unmaskirq, 0, 1, unmaskirq); 231ide_devset_rw_field(number, dn);
233ide_devset_rw_nolock(using_dma, 0, 1, using_dma); 232
234 233static const struct ide_proc_devset ide_generic_settings[] = {
235ide_devset_w_nolock(pio_mode, 0, 255, pio_mode); 234 IDE_PROC_DEVSET(current_speed, 0, 70),
236 235 IDE_PROC_DEVSET(init_speed, 0, 70),
237ide_devset_rw(init_speed, 0, 70, init_speed); 236 IDE_PROC_DEVSET(io_32bit, 0, 1 + (SUPPORT_VLB_SYNC << 1)),
238ide_devset_rw(nice1, 0, 1, nice1); 237 IDE_PROC_DEVSET(keepsettings, 0, 1),
239ide_devset_rw(number, 0, 3, dn); 238 IDE_PROC_DEVSET(nice1, 0, 1),
240 239 IDE_PROC_DEVSET(number, 0, 3),
241static const struct ide_devset *ide_generic_settings[] = { 240 IDE_PROC_DEVSET(pio_mode, 0, 255),
242 &ide_devset_current_speed, 241 IDE_PROC_DEVSET(unmaskirq, 0, 1),
243 &ide_devset_init_speed, 242 IDE_PROC_DEVSET(using_dma, 0, 1),
244 &ide_devset_io_32bit, 243 { 0 },
245 &ide_devset_keepsettings,
246 &ide_devset_nice1,
247 &ide_devset_number,
248 &ide_devset_pio_mode,
249 &ide_devset_unmaskirq,
250 &ide_devset_using_dma,
251 NULL
252}; 244};
253 245
254static void proc_ide_settings_warn(void) 246static void proc_ide_settings_warn(void)
@@ -266,7 +258,8 @@ static void proc_ide_settings_warn(void)
266static int proc_ide_read_settings 258static int proc_ide_read_settings
267 (char *page, char **start, off_t off, int count, int *eof, void *data) 259 (char *page, char **start, off_t off, int count, int *eof, void *data)
268{ 260{
269 const struct ide_devset *setting, **g, **d; 261 const struct ide_proc_devset *setting, *g, *d;
262 const struct ide_devset *ds;
270 ide_drive_t *drive = (ide_drive_t *) data; 263 ide_drive_t *drive = (ide_drive_t *) data;
271 char *out = page; 264 char *out = page;
272 int len, rc, mul_factor, div_factor; 265 int len, rc, mul_factor, div_factor;
@@ -278,17 +271,17 @@ static int proc_ide_read_settings
278 d = drive->settings; 271 d = drive->settings;
279 out += sprintf(out, "name\t\t\tvalue\t\tmin\t\tmax\t\tmode\n"); 272 out += sprintf(out, "name\t\t\tvalue\t\tmin\t\tmax\t\tmode\n");
280 out += sprintf(out, "----\t\t\t-----\t\t---\t\t---\t\t----\n"); 273 out += sprintf(out, "----\t\t\t-----\t\t---\t\t---\t\t----\n");
281 while (*g || (d && *d)) { 274 while (g->name || (d && d->name)) {
282 /* read settings in the alphabetical order */ 275 /* read settings in the alphabetical order */
283 if (*g && d && *d) { 276 if (g->name && d && d->name) {
284 if (strcmp((*d)->name, (*g)->name) < 0) 277 if (strcmp(d->name, g->name) < 0)
285 setting = *d++; 278 setting = d++;
286 else 279 else
287 setting = *g++; 280 setting = g++;
288 } else if (d && *d) { 281 } else if (d && d->name) {
289 setting = *d++; 282 setting = d++;
290 } else 283 } else
291 setting = *g++; 284 setting = g++;
292 mul_factor = setting->mulf ? setting->mulf(drive) : 1; 285 mul_factor = setting->mulf ? setting->mulf(drive) : 1;
293 div_factor = setting->divf ? setting->divf(drive) : 1; 286 div_factor = setting->divf ? setting->divf(drive) : 1;
294 out += sprintf(out, "%-24s", setting->name); 287 out += sprintf(out, "%-24s", setting->name);
@@ -298,9 +291,10 @@ static int proc_ide_read_settings
298 else 291 else
299 out += sprintf(out, "%-16s", "write-only"); 292 out += sprintf(out, "%-16s", "write-only");
300 out += sprintf(out, "%-16d%-16d", (setting->min * mul_factor + div_factor - 1) / div_factor, setting->max * mul_factor / div_factor); 293 out += sprintf(out, "%-16d%-16d", (setting->min * mul_factor + div_factor - 1) / div_factor, setting->max * mul_factor / div_factor);
301 if (setting->flags & S_READ) 294 ds = setting->setting;
295 if (ds->get)
302 out += sprintf(out, "r"); 296 out += sprintf(out, "r");
303 if (setting->flags & S_WRITE) 297 if (ds->set)
304 out += sprintf(out, "w"); 298 out += sprintf(out, "w");
305 out += sprintf(out, "\n"); 299 out += sprintf(out, "\n");
306 } 300 }
@@ -319,7 +313,7 @@ static int proc_ide_write_settings(struct file *file, const char __user *buffer,
319 int for_real = 0, mul_factor, div_factor; 313 int for_real = 0, mul_factor, div_factor;
320 unsigned long n; 314 unsigned long n;
321 315
322 const struct ide_devset *setting; 316 const struct ide_proc_devset *setting;
323 char *buf, *s; 317 char *buf, *s;
324 318
325 if (!capable(CAP_SYS_ADMIN)) 319 if (!capable(CAP_SYS_ADMIN))
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 25190966ed39..f8c84df4a0bc 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) \
2188 return 0; \ 2188 return 0; \
2189} 2189}
2190 2190
2191#define ide_tape_devset_rw(_name, _min, _max, _field, _mulf, _divf) \ 2191#define ide_tape_devset_rw_field(_name, _field) \
2192ide_tape_devset_get(_name, _field) \ 2192ide_tape_devset_get(_name, _field) \
2193ide_tape_devset_set(_name, _field) \ 2193ide_tape_devset_set(_name, _field) \
2194__IDE_DEVSET(_name, S_RW, _min, _max, get_##_name, set_##_name, _mulf, _divf) 2194IDE_DEVSET(_name, DS_SYNC, get_##_name, set_##_name)
2195 2195
2196#define ide_tape_devset_r(_name, _min, _max, _field, _mulf, _divf) \ 2196#define ide_tape_devset_r_field(_name, _field) \
2197ide_tape_devset_get(_name, _field) \ 2197ide_tape_devset_get(_name, _field) \
2198__IDE_DEVSET(_name, S_READ, _min, _max, get_##_name, NULL, _mulf, _divf) 2198IDE_DEVSET(_name, 0, get_##_name, NULL)
2199 2199
2200static int mulf_tdsc(ide_drive_t *drive) { return 1000; } 2200static int mulf_tdsc(ide_drive_t *drive) { return 1000; }
2201static int divf_tdsc(ide_drive_t *drive) { return HZ; } 2201static int divf_tdsc(ide_drive_t *drive) { return HZ; }
2202static int divf_buffer(ide_drive_t *drive) { return 2; } 2202static int divf_buffer(ide_drive_t *drive) { return 2; }
2203static int divf_buffer_size(ide_drive_t *drive) { return 1024; } 2203static int divf_buffer_size(ide_drive_t *drive) { return 1024; }
2204 2204
2205ide_devset_rw(dsc_overlap, 0, 1, dsc_overlap); 2205ide_devset_rw_field(dsc_overlap, dsc_overlap);
2206 2206
2207ide_tape_devset_rw(debug_mask, 0, 0xffff, debug_mask, NULL, NULL); 2207ide_tape_devset_rw_field(debug_mask, debug_mask);
2208ide_tape_devset_rw(tdsc, IDETAPE_DSC_RW_MIN, IDETAPE_DSC_RW_MAX, 2208ide_tape_devset_rw_field(tdsc, best_dsc_rw_freq);
2209 best_dsc_rw_freq, mulf_tdsc, divf_tdsc); 2209
2210 2210ide_tape_devset_r_field(avg_speed, avg_speed);
2211ide_tape_devset_r(avg_speed, 0, 0xffff, avg_speed, NULL, NULL); 2211ide_tape_devset_r_field(speed, caps[14]);
2212ide_tape_devset_r(speed, 0, 0xffff, caps[14], NULL, NULL); 2212ide_tape_devset_r_field(buffer, caps[16]);
2213ide_tape_devset_r(buffer, 0, 0xffff, caps[16], NULL, divf_buffer); 2213ide_tape_devset_r_field(buffer_size, buffer_size);
2214ide_tape_devset_r(buffer_size, 0, 0xffff, buffer_size, NULL, divf_buffer_size); 2214
2215 2215static const struct ide_proc_devset idetape_settings[] = {
2216static const struct ide_devset *idetape_settings[] = { 2216 __IDE_PROC_DEVSET(avg_speed, 0, 0xffff, NULL, NULL),
2217 &ide_devset_avg_speed, 2217 __IDE_PROC_DEVSET(buffer, 0, 0xffff, NULL, divf_buffer),
2218 &ide_devset_buffer, 2218 __IDE_PROC_DEVSET(buffer_size, 0, 0xffff, NULL, divf_buffer_size),
2219 &ide_devset_buffer_size, 2219 __IDE_PROC_DEVSET(debug_mask, 0, 0xffff, NULL, NULL),
2220 &ide_devset_debug_mask, 2220 __IDE_PROC_DEVSET(dsc_overlap, 0, 1, NULL, NULL),
2221 &ide_devset_dsc_overlap, 2221 __IDE_PROC_DEVSET(speed, 0, 0xffff, NULL, NULL),
2222 &ide_devset_speed, 2222 __IDE_PROC_DEVSET(tdsc, IDETAPE_DSC_RW_MIN, IDETAPE_DSC_RW_MAX,
2223 &ide_devset_tdsc, 2223 mulf_tdsc, divf_tdsc),
2224 NULL 2224 { 0 },
2225}; 2225};
2226#endif 2226#endif
2227 2227
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 349d7fa75585..9dcf5aed92cb 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)
250 250
251DEFINE_MUTEX(ide_setting_mtx); 251DEFINE_MUTEX(ide_setting_mtx);
252 252
253/**
254 * ide_spin_wait_hwgroup - wait for group
255 * @drive: drive in the group
256 *
257 * Wait for an IDE device group to go non busy and then return
258 * holding the ide_lock which guards the hwgroup->busy status
259 * and right to use it.
260 */
261
262int ide_spin_wait_hwgroup (ide_drive_t *drive)
263{
264 ide_hwgroup_t *hwgroup = HWGROUP(drive);
265 unsigned long timeout = jiffies + (3 * HZ);
266
267 spin_lock_irq(&ide_lock);
268
269 while (hwgroup->busy) {
270 unsigned long lflags;
271 spin_unlock_irq(&ide_lock);
272 local_irq_set(lflags);
273 if (time_after(jiffies, timeout)) {
274 local_irq_restore(lflags);
275 printk(KERN_ERR "%s: channel busy\n", drive->name);
276 return -EBUSY;
277 }
278 local_irq_restore(lflags);
279 spin_lock_irq(&ide_lock);
280 }
281 return 0;
282}
283
284EXPORT_SYMBOL(ide_spin_wait_hwgroup);
285
286ide_devset_get(io_32bit, io_32bit); 253ide_devset_get(io_32bit, io_32bit);
287 254
288int set_io_32bit(ide_drive_t *drive, int arg) 255static int set_io_32bit(ide_drive_t *drive, int arg)
289{ 256{
290 if (drive->no_io_32bit) 257 if (drive->no_io_32bit)
291 return -EPERM; 258 return -EPERM;
@@ -293,37 +260,28 @@ int set_io_32bit(ide_drive_t *drive, int arg)
293 if (arg < 0 || arg > 1 + (SUPPORT_VLB_SYNC << 1)) 260 if (arg < 0 || arg > 1 + (SUPPORT_VLB_SYNC << 1))
294 return -EINVAL; 261 return -EINVAL;
295 262
296 if (ide_spin_wait_hwgroup(drive))
297 return -EBUSY;
298
299 drive->io_32bit = arg; 263 drive->io_32bit = arg;
300 264
301 spin_unlock_irq(&ide_lock);
302
303 return 0; 265 return 0;
304} 266}
305 267
306ide_devset_get(ksettings, keep_settings); 268ide_devset_get(ksettings, keep_settings);
307 269
308int set_ksettings(ide_drive_t *drive, int arg) 270static int set_ksettings(ide_drive_t *drive, int arg)
309{ 271{
310 if (arg < 0 || arg > 1) 272 if (arg < 0 || arg > 1)
311 return -EINVAL; 273 return -EINVAL;
312 274
313 if (ide_spin_wait_hwgroup(drive))
314 return -EBUSY;
315 drive->keep_settings = arg; 275 drive->keep_settings = arg;
316 spin_unlock_irq(&ide_lock);
317 276
318 return 0; 277 return 0;
319} 278}
320 279
321ide_devset_get(using_dma, using_dma); 280ide_devset_get(using_dma, using_dma);
322 281
323int set_using_dma(ide_drive_t *drive, int arg) 282static int set_using_dma(ide_drive_t *drive, int arg)
324{ 283{
325#ifdef CONFIG_BLK_DEV_IDEDMA 284#ifdef CONFIG_BLK_DEV_IDEDMA
326 ide_hwif_t *hwif = drive->hwif;
327 int err = -EPERM; 285 int err = -EPERM;
328 286
329 if (arg < 0 || arg > 1) 287 if (arg < 0 || arg > 1)
@@ -332,18 +290,9 @@ int set_using_dma(ide_drive_t *drive, int arg)
332 if (ata_id_has_dma(drive->id) == 0) 290 if (ata_id_has_dma(drive->id) == 0)
333 goto out; 291 goto out;
334 292
335 if (hwif->dma_ops == NULL) 293 if (drive->hwif->dma_ops == NULL)
336 goto out; 294 goto out;
337 295
338 err = -EBUSY;
339 if (ide_spin_wait_hwgroup(drive))
340 goto out;
341 /*
342 * set ->busy flag, unlock and let it ride
343 */
344 hwif->hwgroup->busy = 1;
345 spin_unlock_irq(&ide_lock);
346
347 err = 0; 296 err = 0;
348 297
349 if (arg) { 298 if (arg) {
@@ -352,12 +301,6 @@ int set_using_dma(ide_drive_t *drive, int arg)
352 } else 301 } else
353 ide_dma_off(drive); 302 ide_dma_off(drive);
354 303
355 /*
356 * lock, clear ->busy flag and unlock before leaving
357 */
358 spin_lock_irq(&ide_lock);
359 hwif->hwgroup->busy = 0;
360 spin_unlock_irq(&ide_lock);
361out: 304out:
362 return err; 305 return err;
363#else 306#else
@@ -368,7 +311,7 @@ out:
368#endif 311#endif
369} 312}
370 313
371int set_pio_mode(ide_drive_t *drive, int arg) 314static int set_pio_mode(ide_drive_t *drive, int arg)
372{ 315{
373 struct request *rq; 316 struct request *rq;
374 ide_hwif_t *hwif = drive->hwif; 317 ide_hwif_t *hwif = drive->hwif;
@@ -398,7 +341,7 @@ int set_pio_mode(ide_drive_t *drive, int arg)
398 341
399ide_devset_get(unmaskirq, unmask); 342ide_devset_get(unmaskirq, unmask);
400 343
401int set_unmaskirq(ide_drive_t *drive, int arg) 344static int set_unmaskirq(ide_drive_t *drive, int arg)
402{ 345{
403 if (drive->no_unmask) 346 if (drive->no_unmask)
404 return -EPERM; 347 return -EPERM;
@@ -406,14 +349,20 @@ int set_unmaskirq(ide_drive_t *drive, int arg)
406 if (arg < 0 || arg > 1) 349 if (arg < 0 || arg > 1)
407 return -EINVAL; 350 return -EINVAL;
408 351
409 if (ide_spin_wait_hwgroup(drive))
410 return -EBUSY;
411 drive->unmask = arg; 352 drive->unmask = arg;
412 spin_unlock_irq(&ide_lock);
413 353
414 return 0; 354 return 0;
415} 355}
416 356
357#define ide_gen_devset_rw(_name, _func) \
358__IDE_DEVSET(_name, DS_SYNC, get_##_func, set_##_func)
359
360ide_gen_devset_rw(io_32bit, io_32bit);
361ide_gen_devset_rw(keepsettings, ksettings);
362ide_gen_devset_rw(unmaskirq, unmaskirq);
363ide_gen_devset_rw(using_dma, using_dma);
364__IDE_DEVSET(pio_mode, 0, NULL, set_pio_mode);
365
417static int generic_ide_suspend(struct device *dev, pm_message_t mesg) 366static int generic_ide_suspend(struct device *dev, pm_message_t mesg)
418{ 367{
419 ide_drive_t *drive = dev->driver_data; 368 ide_drive_t *drive = dev->driver_data;