diff options
| -rw-r--r-- | drivers/ide/ide-cd.c | 8 | ||||
| -rw-r--r-- | drivers/ide/ide-disk.c | 66 | ||||
| -rw-r--r-- | drivers/ide/ide-floppy.c | 20 | ||||
| -rw-r--r-- | drivers/ide/ide-io.c | 40 | ||||
| -rw-r--r-- | drivers/ide/ide-ioctls.c | 21 | ||||
| -rw-r--r-- | drivers/ide/ide-proc.c | 102 | ||||
| -rw-r--r-- | drivers/ide/ide-tape.c | 48 | ||||
| -rw-r--r-- | drivers/ide/ide.c | 81 | ||||
| -rw-r--r-- | drivers/scsi/ide-scsi.c | 34 | ||||
| -rw-r--r-- | include/linux/ide.h | 138 |
10 files changed, 274 insertions, 284 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 | ||
| 1812 | ide_devset_rw(dsc_overlap, 0, 1, dsc_overlap); | 1812 | ide_devset_rw_field(dsc_overlap, dsc_overlap); |
| 1813 | 1813 | ||
| 1814 | static const struct ide_devset *idecd_settings[] = { | 1814 | static 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 | ||
| 702 | ide_devset_rw(acoustic, acoustic); | ||
| 703 | ide_devset_rw(address, addressing); | ||
| 704 | ide_devset_rw(multcount, multcount); | ||
| 705 | ide_devset_rw(wcache, wcache); | ||
| 706 | |||
| 707 | ide_devset_rw_sync(nowerr, nowerr); | ||
| 708 | |||
| 705 | #ifdef CONFIG_IDE_PROC_FS | 709 | #ifdef CONFIG_IDE_PROC_FS |
| 706 | ide_devset_rw_nolock(acoustic, 0, 254, acoustic); | 710 | ide_devset_rw_field(bios_cyl, bios_cyl); |
| 707 | ide_devset_rw_nolock(address, 0, 2, addressing); | 711 | ide_devset_rw_field(bios_head, bios_head); |
| 708 | ide_devset_rw_nolock(multcount, 0, 16, multcount); | 712 | ide_devset_rw_field(bios_sect, bios_sect); |
| 709 | ide_devset_rw_nolock(nowerr, 0, 1, nowerr); | 713 | ide_devset_rw_field(failures, failures); |
| 710 | ide_devset_rw_nolock(wcache, 0, 1, wcache); | 714 | ide_devset_rw_field(lun, lun); |
| 711 | 715 | ide_devset_rw_field(max_failures, max_failures); | |
| 712 | ide_devset_rw(bios_cyl, 0, 65535, bios_cyl); | 716 | |
| 713 | ide_devset_rw(bios_head, 0, 255, bios_head); | 717 | static const struct ide_proc_devset idedisk_settings[] = { |
| 714 | ide_devset_rw(bios_sect, 0, 63, bios_sect); | 718 | IDE_PROC_DEVSET(acoustic, 0, 254), |
| 715 | ide_devset_rw(failures, 0, 65535, failures); | 719 | IDE_PROC_DEVSET(address, 0, 2), |
| 716 | ide_devset_rw(lun, 0, 7, lun); | 720 | IDE_PROC_DEVSET(bios_cyl, 0, 65535), |
| 717 | ide_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), | |
| 719 | static 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 | ||
| 1003 | static const struct ide_ioctl_devset ide_disk_ioctl_settings[] = { | 1001 | static 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 |
| 632 | ide_devset_rw(bios_cyl, 0, 1023, bios_cyl); | 632 | ide_devset_rw_field(bios_cyl, bios_cyl); |
| 633 | ide_devset_rw(bios_head, 0, 255, bios_head); | 633 | ide_devset_rw_field(bios_head, bios_head); |
| 634 | ide_devset_rw(bios_sect, 0, 63, bios_sect); | 634 | ide_devset_rw_field(bios_sect, bios_sect); |
| 635 | 635 | ||
| 636 | static int get_ticks(ide_drive_t *drive) | 636 | static 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 | ||
| 649 | IDE_DEVSET(ticks, S_RW, 0, 255, get_ticks, set_ticks); | 649 | IDE_DEVSET(ticks, DS_SYNC, get_ticks, set_ticks); |
| 650 | 650 | ||
| 651 | static const struct ide_devset *idefloppy_settings[] = { | 651 | static 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 | ||
| 719 | int 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 | } | ||
| 745 | EXPORT_SYMBOL_GPL(ide_devset_execute); | ||
| 746 | |||
| 719 | static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq) | 747 | static 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 | ||
| 8 | static const struct ide_ioctl_devset ide_ioctl_settings[] = { | 8 | static 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, | |||
| 33 | read_val: | 34 | read_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 | ||
| 127 | static const struct ide_devset *ide_find_setting(const struct ide_devset **st, | 127 | static |
| 128 | char *name) | 128 | const 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 | ||
| 151 | static int ide_read_setting(ide_drive_t *drive, | 152 | static 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 | ||
| 185 | static int ide_write_setting(ide_drive_t *drive, | 187 | static 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 | ||
| 203 | static ide_devset_get(xfer_rate, current_speed); | 202 | ide_devset_get(xfer_rate, current_speed); |
| 204 | 203 | ||
| 205 | static int set_xfer_rate (ide_drive_t *drive, int arg) | 204 | static 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 | ||
| 229 | ide_devset_rw_nolock(current_speed, 0, 70, xfer_rate); | 228 | ide_devset_rw(current_speed, xfer_rate); |
| 230 | ide_devset_rw_nolock(io_32bit, 0, 1 + (SUPPORT_VLB_SYNC << 1), io_32bit); | 229 | ide_devset_rw_field(init_speed, init_speed); |
| 231 | ide_devset_rw_nolock(keepsettings, 0, 1, ksettings); | 230 | ide_devset_rw_field(nice1, nice1); |
| 232 | ide_devset_rw_nolock(unmaskirq, 0, 1, unmaskirq); | 231 | ide_devset_rw_field(number, dn); |
| 233 | ide_devset_rw_nolock(using_dma, 0, 1, using_dma); | 232 | |
| 234 | 233 | static const struct ide_proc_devset ide_generic_settings[] = { | |
| 235 | ide_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), | |
| 237 | ide_devset_rw(init_speed, 0, 70, init_speed); | 236 | IDE_PROC_DEVSET(io_32bit, 0, 1 + (SUPPORT_VLB_SYNC << 1)), |
| 238 | ide_devset_rw(nice1, 0, 1, nice1); | 237 | IDE_PROC_DEVSET(keepsettings, 0, 1), |
| 239 | ide_devset_rw(number, 0, 3, dn); | 238 | IDE_PROC_DEVSET(nice1, 0, 1), |
| 240 | 239 | IDE_PROC_DEVSET(number, 0, 3), | |
| 241 | static 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 | ||
| 254 | static void proc_ide_settings_warn(void) | 246 | static void proc_ide_settings_warn(void) |
| @@ -266,7 +258,8 @@ static void proc_ide_settings_warn(void) | |||
| 266 | static int proc_ide_read_settings | 258 | static 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) \ |
| 2192 | ide_tape_devset_get(_name, _field) \ | 2192 | ide_tape_devset_get(_name, _field) \ |
| 2193 | ide_tape_devset_set(_name, _field) \ | 2193 | ide_tape_devset_set(_name, _field) \ |
| 2194 | __IDE_DEVSET(_name, S_RW, _min, _max, get_##_name, set_##_name, _mulf, _divf) | 2194 | IDE_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) \ |
| 2197 | ide_tape_devset_get(_name, _field) \ | 2197 | ide_tape_devset_get(_name, _field) \ |
| 2198 | __IDE_DEVSET(_name, S_READ, _min, _max, get_##_name, NULL, _mulf, _divf) | 2198 | IDE_DEVSET(_name, 0, get_##_name, NULL) |
| 2199 | 2199 | ||
| 2200 | static int mulf_tdsc(ide_drive_t *drive) { return 1000; } | 2200 | static int mulf_tdsc(ide_drive_t *drive) { return 1000; } |
| 2201 | static int divf_tdsc(ide_drive_t *drive) { return HZ; } | 2201 | static int divf_tdsc(ide_drive_t *drive) { return HZ; } |
| 2202 | static int divf_buffer(ide_drive_t *drive) { return 2; } | 2202 | static int divf_buffer(ide_drive_t *drive) { return 2; } |
| 2203 | static int divf_buffer_size(ide_drive_t *drive) { return 1024; } | 2203 | static int divf_buffer_size(ide_drive_t *drive) { return 1024; } |
| 2204 | 2204 | ||
| 2205 | ide_devset_rw(dsc_overlap, 0, 1, dsc_overlap); | 2205 | ide_devset_rw_field(dsc_overlap, dsc_overlap); |
| 2206 | 2206 | ||
| 2207 | ide_tape_devset_rw(debug_mask, 0, 0xffff, debug_mask, NULL, NULL); | 2207 | ide_tape_devset_rw_field(debug_mask, debug_mask); |
| 2208 | ide_tape_devset_rw(tdsc, IDETAPE_DSC_RW_MIN, IDETAPE_DSC_RW_MAX, | 2208 | ide_tape_devset_rw_field(tdsc, best_dsc_rw_freq); |
| 2209 | best_dsc_rw_freq, mulf_tdsc, divf_tdsc); | 2209 | |
| 2210 | 2210 | ide_tape_devset_r_field(avg_speed, avg_speed); | |
| 2211 | ide_tape_devset_r(avg_speed, 0, 0xffff, avg_speed, NULL, NULL); | 2211 | ide_tape_devset_r_field(speed, caps[14]); |
| 2212 | ide_tape_devset_r(speed, 0, 0xffff, caps[14], NULL, NULL); | 2212 | ide_tape_devset_r_field(buffer, caps[16]); |
| 2213 | ide_tape_devset_r(buffer, 0, 0xffff, caps[16], NULL, divf_buffer); | 2213 | ide_tape_devset_r_field(buffer_size, buffer_size); |
| 2214 | ide_tape_devset_r(buffer_size, 0, 0xffff, buffer_size, NULL, divf_buffer_size); | 2214 | |
| 2215 | 2215 | static const struct ide_proc_devset idetape_settings[] = { | |
| 2216 | static 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 | ||
| 251 | DEFINE_MUTEX(ide_setting_mtx); | 251 | DEFINE_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 | |||
| 262 | int 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 | |||
| 284 | EXPORT_SYMBOL(ide_spin_wait_hwgroup); | ||
| 285 | |||
| 286 | ide_devset_get(io_32bit, io_32bit); | 253 | ide_devset_get(io_32bit, io_32bit); |
| 287 | 254 | ||
| 288 | int set_io_32bit(ide_drive_t *drive, int arg) | 255 | static 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 | ||
| 306 | ide_devset_get(ksettings, keep_settings); | 268 | ide_devset_get(ksettings, keep_settings); |
| 307 | 269 | ||
| 308 | int set_ksettings(ide_drive_t *drive, int arg) | 270 | static 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 | ||
| 321 | ide_devset_get(using_dma, using_dma); | 280 | ide_devset_get(using_dma, using_dma); |
| 322 | 281 | ||
| 323 | int set_using_dma(ide_drive_t *drive, int arg) | 282 | static 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); | ||
| 361 | out: | 304 | out: |
| 362 | return err; | 305 | return err; |
| 363 | #else | 306 | #else |
| @@ -368,7 +311,7 @@ out: | |||
| 368 | #endif | 311 | #endif |
| 369 | } | 312 | } |
| 370 | 313 | ||
| 371 | int set_pio_mode(ide_drive_t *drive, int arg) | 314 | static 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 | ||
| 399 | ide_devset_get(unmaskirq, unmask); | 342 | ide_devset_get(unmaskirq, unmask); |
| 400 | 343 | ||
| 401 | int set_unmaskirq(ide_drive_t *drive, int arg) | 344 | static 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 | |||
| 360 | ide_gen_devset_rw(io_32bit, io_32bit); | ||
| 361 | ide_gen_devset_rw(keepsettings, ksettings); | ||
| 362 | ide_gen_devset_rw(unmaskirq, unmaskirq); | ||
| 363 | ide_gen_devset_rw(using_dma, using_dma); | ||
| 364 | __IDE_DEVSET(pio_mode, 0, NULL, set_pio_mode); | ||
| 365 | |||
| 417 | static int generic_ide_suspend(struct device *dev, pm_message_t mesg) | 366 | static 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; |
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 27c01e368977..90212ac33be3 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c | |||
| @@ -400,25 +400,25 @@ static int set_##name(ide_drive_t *drive, int arg) \ | |||
| 400 | return 0; \ | 400 | return 0; \ |
| 401 | } | 401 | } |
| 402 | 402 | ||
| 403 | #define ide_scsi_devset_rw(_name, _min, _max, _field) \ | 403 | #define ide_scsi_devset_rw_field(_name, _field) \ |
| 404 | ide_scsi_devset_get(_name, _field); \ | 404 | ide_scsi_devset_get(_name, _field); \ |
| 405 | ide_scsi_devset_set(_name, _field); \ | 405 | ide_scsi_devset_set(_name, _field); \ |
| 406 | IDE_DEVSET(_name, S_RW, _min, _max, get_##_name, set_##_name) | 406 | IDE_DEVSET(_name, DS_SYNC, get_##_name, set_##_name); |
| 407 | 407 | ||
| 408 | ide_devset_rw(bios_cyl, 0, 1023, bios_cyl); | 408 | ide_devset_rw_field(bios_cyl, bios_cyl); |
| 409 | ide_devset_rw(bios_head, 0, 255, bios_head); | 409 | ide_devset_rw_field(bios_head, bios_head); |
| 410 | ide_devset_rw(bios_sect, 0, 63, bios_sect); | 410 | ide_devset_rw_field(bios_sect, bios_sect); |
| 411 | 411 | ||
| 412 | ide_scsi_devset_rw(transform, 0, 3, transform); | 412 | ide_scsi_devset_rw_field(transform, transform); |
| 413 | ide_scsi_devset_rw(log, 0, 1, log); | 413 | ide_scsi_devset_rw_field(log, log); |
| 414 | 414 | ||
| 415 | static const struct ide_devset *idescsi_settings[] = { | 415 | static const struct ide_proc_devset idescsi_settings[] = { |
| 416 | &ide_devset_bios_cyl, | 416 | IDE_PROC_DEVSET(bios_cyl, 0, 1023), |
| 417 | &ide_devset_bios_head, | 417 | IDE_PROC_DEVSET(bios_head, 0, 255), |
| 418 | &ide_devset_bios_sect, | 418 | IDE_PROC_DEVSET(bios_sect, 0, 63), |
| 419 | &ide_devset_log, | 419 | IDE_PROC_DEVSET(log, 0, 1), |
| 420 | &ide_devset_transform, | 420 | IDE_PROC_DEVSET(transform, 0, 3), |
| 421 | NULL | 421 | { 0 }, |
| 422 | }; | 422 | }; |
| 423 | #endif | 423 | #endif |
| 424 | 424 | ||
diff --git a/include/linux/ide.h b/include/linux/ide.h index a9eced25acce..a9d82d6e6bdd 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h | |||
| @@ -161,6 +161,7 @@ enum { | |||
| 161 | * Values should be in the range of 0x20 to 0x3f. | 161 | * Values should be in the range of 0x20 to 0x3f. |
| 162 | */ | 162 | */ |
| 163 | #define REQ_DRIVE_RESET 0x20 | 163 | #define REQ_DRIVE_RESET 0x20 |
| 164 | #define REQ_DEVSET_EXEC 0x21 | ||
| 164 | 165 | ||
| 165 | /* | 166 | /* |
| 166 | * Check for an interrupt and acknowledge the interrupt status | 167 | * Check for an interrupt and acknowledge the interrupt status |
| @@ -405,7 +406,7 @@ struct ide_drive_s { | |||
| 405 | u16 *id; /* identification info */ | 406 | u16 *id; /* identification info */ |
| 406 | #ifdef CONFIG_IDE_PROC_FS | 407 | #ifdef CONFIG_IDE_PROC_FS |
| 407 | struct proc_dir_entry *proc; /* /proc/ide/ directory entry */ | 408 | struct proc_dir_entry *proc; /* /proc/ide/ directory entry */ |
| 408 | const struct ide_devset **settings; /* /proc/ide/ drive settings */ | 409 | const struct ide_proc_devset *settings; /* /proc/ide/ drive settings */ |
| 409 | #endif | 410 | #endif |
| 410 | struct hwif_s *hwif; /* actually (ide_hwif_t *) */ | 411 | struct hwif_s *hwif; /* actually (ide_hwif_t *) */ |
| 411 | 412 | ||
| @@ -707,29 +708,62 @@ typedef struct ide_driver_s ide_driver_t; | |||
| 707 | 708 | ||
| 708 | extern struct mutex ide_setting_mtx; | 709 | extern struct mutex ide_setting_mtx; |
| 709 | 710 | ||
| 710 | int get_io_32bit(ide_drive_t *); | 711 | /* |
| 711 | int set_io_32bit(ide_drive_t *, int); | 712 | * configurable drive settings |
| 712 | int get_ksettings(ide_drive_t *); | 713 | */ |
| 713 | int set_ksettings(ide_drive_t *, int); | 714 | |
| 714 | int set_pio_mode(ide_drive_t *, int); | 715 | #define DS_SYNC (1 << 0) |
| 715 | int get_unmaskirq(ide_drive_t *); | 716 | |
| 716 | int set_unmaskirq(ide_drive_t *, int); | 717 | struct ide_devset { |
| 717 | int get_using_dma(ide_drive_t *); | 718 | int (*get)(ide_drive_t *); |
| 718 | int set_using_dma(ide_drive_t *, int); | 719 | int (*set)(ide_drive_t *, int); |
| 720 | unsigned int flags; | ||
| 721 | }; | ||
| 722 | |||
| 723 | #define __DEVSET(_flags, _get, _set) { \ | ||
| 724 | .flags = _flags, \ | ||
| 725 | .get = _get, \ | ||
| 726 | .set = _set, \ | ||
| 727 | } | ||
| 719 | 728 | ||
| 720 | #define ide_devset_get(name, field) \ | 729 | #define ide_devset_get(name, field) \ |
| 721 | int get_##name(ide_drive_t *drive) \ | 730 | static int get_##name(ide_drive_t *drive) \ |
| 722 | { \ | 731 | { \ |
| 723 | return drive->field; \ | 732 | return drive->field; \ |
| 724 | } | 733 | } |
| 725 | 734 | ||
| 726 | #define ide_devset_set(name, field) \ | 735 | #define ide_devset_set(name, field) \ |
| 727 | int set_##name(ide_drive_t *drive, int arg) \ | 736 | static int set_##name(ide_drive_t *drive, int arg) \ |
| 728 | { \ | 737 | { \ |
| 729 | drive->field = arg; \ | 738 | drive->field = arg; \ |
| 730 | return 0; \ | 739 | return 0; \ |
| 731 | } | 740 | } |
| 732 | 741 | ||
| 742 | #define __IDE_DEVSET(_name, _flags, _get, _set) \ | ||
| 743 | const struct ide_devset ide_devset_##_name = \ | ||
| 744 | __DEVSET(_flags, _get, _set) | ||
| 745 | |||
| 746 | #define IDE_DEVSET(_name, _flags, _get, _set) \ | ||
| 747 | static __IDE_DEVSET(_name, _flags, _get, _set) | ||
| 748 | |||
| 749 | #define ide_devset_rw(_name, _func) \ | ||
| 750 | IDE_DEVSET(_name, 0, get_##_func, set_##_func) | ||
| 751 | |||
| 752 | #define ide_devset_w(_name, _func) \ | ||
| 753 | IDE_DEVSET(_name, 0, NULL, set_##_func) | ||
| 754 | |||
| 755 | #define ide_devset_rw_sync(_name, _func) \ | ||
| 756 | IDE_DEVSET(_name, DS_SYNC, get_##_func, set_##_func) | ||
| 757 | |||
| 758 | #define ide_decl_devset(_name) \ | ||
| 759 | extern const struct ide_devset ide_devset_##_name | ||
| 760 | |||
| 761 | ide_decl_devset(io_32bit); | ||
| 762 | ide_decl_devset(keepsettings); | ||
| 763 | ide_decl_devset(pio_mode); | ||
| 764 | ide_decl_devset(unmaskirq); | ||
| 765 | ide_decl_devset(using_dma); | ||
| 766 | |||
| 733 | /* ATAPI packet command flags */ | 767 | /* ATAPI packet command flags */ |
| 734 | enum { | 768 | enum { |
| 735 | /* set when an error is considered normal - no retry (ide-tape) */ | 769 | /* set when an error is considered normal - no retry (ide-tape) */ |
| @@ -797,60 +831,34 @@ struct ide_atapi_pc { | |||
| 797 | 831 | ||
| 798 | #ifdef CONFIG_IDE_PROC_FS | 832 | #ifdef CONFIG_IDE_PROC_FS |
| 799 | /* | 833 | /* |
| 800 | * configurable drive settings | 834 | * /proc/ide interface |
| 801 | */ | 835 | */ |
| 802 | 836 | ||
| 803 | #define S_READ (1 << 0) | 837 | #define ide_devset_rw_field(_name, _field) \ |
| 804 | #define S_WRITE (1 << 1) | 838 | ide_devset_get(_name, _field); \ |
| 805 | #define S_RW (S_READ | S_WRITE) | 839 | ide_devset_set(_name, _field); \ |
| 806 | #define S_NOLOCK (1 << 2) | 840 | IDE_DEVSET(_name, DS_SYNC, get_##_name, set_##_name) |
| 807 | 841 | ||
| 808 | struct ide_devset { | 842 | struct ide_proc_devset { |
| 809 | const char *name; | 843 | const char *name; |
| 810 | unsigned int flags; | 844 | const struct ide_devset *setting; |
| 811 | int min, max; | 845 | int min, max; |
| 812 | int (*get)(ide_drive_t *); | 846 | int (*mulf)(ide_drive_t *); |
| 813 | int (*set)(ide_drive_t *, int); | 847 | int (*divf)(ide_drive_t *); |
| 814 | int (*mulf)(ide_drive_t *); | ||
| 815 | int (*divf)(ide_drive_t *); | ||
| 816 | }; | 848 | }; |
| 817 | 849 | ||
| 818 | #define __DEVSET(_name, _flags, _min, _max, _get, _set, _mulf, _divf) { \ | 850 | #define __IDE_PROC_DEVSET(_name, _min, _max, _mulf, _divf) { \ |
| 819 | .name = __stringify(_name), \ | 851 | .name = __stringify(_name), \ |
| 820 | .flags = _flags, \ | 852 | .setting = &ide_devset_##_name, \ |
| 821 | .min = _min, \ | 853 | .min = _min, \ |
| 822 | .max = _max, \ | 854 | .max = _max, \ |
| 823 | .get = _get, \ | 855 | .mulf = _mulf, \ |
| 824 | .set = _set, \ | 856 | .divf = _divf, \ |
| 825 | .mulf = _mulf, \ | ||
| 826 | .divf = _divf, \ | ||
| 827 | } | 857 | } |
| 828 | 858 | ||
| 829 | #define __IDE_DEVSET(_name, _flags, _min, _max, _get, _set, _mulf, _divf) \ | 859 | #define IDE_PROC_DEVSET(_name, _min, _max) \ |
| 830 | static const struct ide_devset ide_devset_##_name = \ | 860 | __IDE_PROC_DEVSET(_name, _min, _max, NULL, NULL) |
| 831 | __DEVSET(_name, _flags, _min, _max, _get, _set, _mulf, _divf) | ||
| 832 | |||
| 833 | #define IDE_DEVSET(_name, _flags, _min, _max, _get, _set) \ | ||
| 834 | __IDE_DEVSET(_name, _flags, _min, _max, _get, _set, NULL, NULL) | ||
| 835 | |||
| 836 | #define ide_devset_rw_nolock(_name, _min, _max, _func) \ | ||
| 837 | IDE_DEVSET(_name, S_RW | S_NOLOCK, _min, _max, get_##_func, set_##_func) | ||
| 838 | 861 | ||
| 839 | #define ide_devset_w_nolock(_name, _min, _max, _func) \ | ||
| 840 | IDE_DEVSET(_name, S_WRITE | S_NOLOCK, _min, _max, NULL, set_##_func) | ||
| 841 | |||
| 842 | #define ide_devset_rw(_name, _min, _max, _field) \ | ||
| 843 | static ide_devset_get(_name, _field); \ | ||
| 844 | static ide_devset_set(_name, _field); \ | ||
| 845 | IDE_DEVSET(_name, S_RW, _min, _max, get_##_name, set_##_name) | ||
| 846 | |||
| 847 | #define ide_devset_r(_name, _min, _max, _field) \ | ||
| 848 | ide_devset_get(_name, _field) \ | ||
| 849 | IDE_DEVSET(_name, S_READ, _min, _max, get_##_name, NULL) | ||
| 850 | |||
| 851 | /* | ||
| 852 | * /proc/ide interface | ||
| 853 | */ | ||
| 854 | typedef struct { | 862 | typedef struct { |
| 855 | const char *name; | 863 | const char *name; |
| 856 | mode_t mode; | 864 | mode_t mode; |
| @@ -948,8 +956,8 @@ struct ide_driver_s { | |||
| 948 | void (*resume)(ide_drive_t *); | 956 | void (*resume)(ide_drive_t *); |
| 949 | void (*shutdown)(ide_drive_t *); | 957 | void (*shutdown)(ide_drive_t *); |
| 950 | #ifdef CONFIG_IDE_PROC_FS | 958 | #ifdef CONFIG_IDE_PROC_FS |
| 951 | ide_proc_entry_t *proc; | 959 | ide_proc_entry_t *proc; |
| 952 | const struct ide_devset **settings; | 960 | const struct ide_proc_devset *settings; |
| 953 | #endif | 961 | #endif |
| 954 | }; | 962 | }; |
| 955 | 963 | ||
| @@ -961,9 +969,7 @@ void ide_device_put(ide_drive_t *); | |||
| 961 | struct ide_ioctl_devset { | 969 | struct ide_ioctl_devset { |
| 962 | unsigned int get_ioctl; | 970 | unsigned int get_ioctl; |
| 963 | unsigned int set_ioctl; | 971 | unsigned int set_ioctl; |
| 964 | 972 | const struct ide_devset *setting; | |
| 965 | int (*get)(ide_drive_t *); | ||
| 966 | int (*set)(ide_drive_t *, int); | ||
| 967 | }; | 973 | }; |
| 968 | 974 | ||
| 969 | int ide_setting_ioctl(ide_drive_t *, struct block_device *, unsigned int, | 975 | int ide_setting_ioctl(ide_drive_t *, struct block_device *, unsigned int, |
| @@ -1002,6 +1008,9 @@ int ide_wait_stat(ide_startstop_t *, ide_drive_t *, u8, u8, unsigned long); | |||
| 1002 | 1008 | ||
| 1003 | extern ide_startstop_t ide_do_reset (ide_drive_t *); | 1009 | extern ide_startstop_t ide_do_reset (ide_drive_t *); |
| 1004 | 1010 | ||
| 1011 | extern int ide_devset_execute(ide_drive_t *drive, | ||
| 1012 | const struct ide_devset *setting, int arg); | ||
| 1013 | |||
| 1005 | extern void ide_do_drive_cmd(ide_drive_t *, struct request *); | 1014 | extern void ide_do_drive_cmd(ide_drive_t *, struct request *); |
| 1006 | 1015 | ||
| 1007 | extern void ide_end_drive_cmd(ide_drive_t *, u8, u8); | 1016 | extern void ide_end_drive_cmd(ide_drive_t *, u8, u8); |
| @@ -1191,7 +1200,6 @@ extern int ide_wait_not_busy(ide_hwif_t *hwif, unsigned long timeout); | |||
| 1191 | 1200 | ||
| 1192 | extern void ide_stall_queue(ide_drive_t *drive, unsigned long timeout); | 1201 | extern void ide_stall_queue(ide_drive_t *drive, unsigned long timeout); |
| 1193 | 1202 | ||
| 1194 | extern int ide_spin_wait_hwgroup(ide_drive_t *); | ||
| 1195 | extern void ide_timer_expiry(unsigned long); | 1203 | extern void ide_timer_expiry(unsigned long); |
| 1196 | extern irqreturn_t ide_intr(int irq, void *dev_id); | 1204 | extern irqreturn_t ide_intr(int irq, void *dev_id); |
| 1197 | extern void do_ide_request(struct request_queue *); | 1205 | extern void do_ide_request(struct request_queue *); |
