ide: /proc/ide/hd*/settings rework

* Add struct ide_devset, S_* flags, *DEVSET() & ide*_devset_*() macros.

* Add 'const struct ide_devset **settings' to ide_driver_t.

* Use 'const struct ide_devset **settings' in ide_drive_t instead of
  'struct ide_settings_s *settings'.  Then convert core code and device
  drivers to use struct ide_devset and co.:

  - device settings are no longer allocated dynamically for each device
    but instead there is an unique struct ide_devset instance per setting

  - device driver keeps the pointer to the table of pointers to its
    settings in ide_driver_t.settings

  - generic settings are kept in ide_generic_setting[]

  - ide_proc_[un]register_driver(), ide_find_setting_by_name(),
    ide_{read,write}_setting() and proc_ide_{read,write}_settings()
    are updated accordingly

  - ide*_add_settings() are removed

* Remove no longer used __ide_add_setting(), ide_add_setting(),
  __ide_remove_setting() and auto_remove_settings().

* Remove no longer used TYPE_*, SETTING_*, ide_procset_t
  and ide_settings_t.

* ->keep_settings, ->using_dma, ->unmask, ->noflush, ->dsc_overlap,
  ->nice1, ->addressing, ->wcache and ->nowerr ide_drive_t fields
  can now be bitfield flags.

While at it:

* Rename ide_find_setting_by_name() to ide_find_setting().

* Rename write_wcache() to set_wcache().

There should be no functional changes caused by this patch.
Signed-off-by: default avatarBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
parent 263138a0
...@@ -1809,13 +1809,12 @@ static ide_proc_entry_t idecd_proc[] = { ...@@ -1809,13 +1809,12 @@ static ide_proc_entry_t idecd_proc[] = {
{ NULL, 0, NULL, NULL } { NULL, 0, NULL, NULL }
}; };
static void ide_cdrom_add_settings(ide_drive_t *drive) ide_devset_rw(dsc_overlap, 0, 1, dsc_overlap);
{
ide_add_setting(drive, "dsc_overlap", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, static const struct ide_devset *idecd_settings[] = {
&drive->dsc_overlap, NULL); &ide_devset_dsc_overlap,
} NULL
#else };
static inline void ide_cdrom_add_settings(ide_drive_t *drive) { ; }
#endif #endif
static const struct cd_list_entry ide_cd_quirks_list[] = { static const struct cd_list_entry ide_cd_quirks_list[] = {
...@@ -1926,7 +1925,6 @@ static int ide_cdrom_setup(ide_drive_t *drive) ...@@ -1926,7 +1925,6 @@ static int ide_cdrom_setup(ide_drive_t *drive)
} }
ide_proc_register_driver(drive, cd->driver); ide_proc_register_driver(drive, cd->driver);
ide_cdrom_add_settings(drive);
return 0; return 0;
} }
...@@ -1977,6 +1975,7 @@ static ide_driver_t ide_cdrom_driver = { ...@@ -1977,6 +1975,7 @@ static ide_driver_t ide_cdrom_driver = {
.error = __ide_error, .error = __ide_error,
#ifdef CONFIG_IDE_PROC_FS #ifdef CONFIG_IDE_PROC_FS
.proc = idecd_proc, .proc = idecd_proc,
.settings = idecd_settings,
#endif #endif
}; };
......
...@@ -599,6 +599,8 @@ static void idedisk_prepare_flush(struct request_queue *q, struct request *rq) ...@@ -599,6 +599,8 @@ static void idedisk_prepare_flush(struct request_queue *q, struct request *rq)
rq->special = task; rq->special = task;
} }
ide_devset_get(multcount, mult_count);
/* /*
* This is tightly woven into the driver->do_special can not touch. * This is tightly woven into the driver->do_special can not touch.
* DON'T do it again until a total personality rewrite is committed. * DON'T do it again until a total personality rewrite is committed.
...@@ -625,6 +627,8 @@ static int set_multcount(ide_drive_t *drive, int arg) ...@@ -625,6 +627,8 @@ static int set_multcount(ide_drive_t *drive, int arg)
return (drive->mult_count == arg) ? 0 : -EIO; return (drive->mult_count == arg) ? 0 : -EIO;
} }
ide_devset_get(nowerr, nowerr);
static int set_nowerr(ide_drive_t *drive, int arg) static int set_nowerr(ide_drive_t *drive, int arg)
{ {
if (arg < 0 || arg > 1) if (arg < 0 || arg > 1)
...@@ -673,7 +677,9 @@ static void update_ordered(ide_drive_t *drive) ...@@ -673,7 +677,9 @@ static void update_ordered(ide_drive_t *drive)
blk_queue_ordered(drive->queue, ordered, prep_fn); blk_queue_ordered(drive->queue, ordered, prep_fn);
} }
static int write_cache(ide_drive_t *drive, int arg) ide_devset_get(wcache, wcache);
static int set_wcache(ide_drive_t *drive, int arg)
{ {
ide_task_t args; ide_task_t args;
int err = 1; int err = 1;
...@@ -710,6 +716,8 @@ static int do_idedisk_flushcache(ide_drive_t *drive) ...@@ -710,6 +716,8 @@ static int do_idedisk_flushcache(ide_drive_t *drive)
return ide_no_data_taskfile(drive, &args); return ide_no_data_taskfile(drive, &args);
} }
ide_devset_get(acoustic, acoustic);
static int set_acoustic(ide_drive_t *drive, int arg) static int set_acoustic(ide_drive_t *drive, int arg)
{ {
ide_task_t args; ide_task_t args;
...@@ -727,6 +735,8 @@ static int set_acoustic(ide_drive_t *drive, int arg) ...@@ -727,6 +735,8 @@ static int set_acoustic(ide_drive_t *drive, int arg)
return 0; return 0;
} }
ide_devset_get(lba_addressing, addressing);
/* /*
* drive->addressing: * drive->addressing:
* 0: 28-bit * 0: 28-bit
...@@ -750,33 +760,33 @@ static int set_lba_addressing(ide_drive_t *drive, int arg) ...@@ -750,33 +760,33 @@ static int set_lba_addressing(ide_drive_t *drive, int arg)
} }
#ifdef CONFIG_IDE_PROC_FS #ifdef CONFIG_IDE_PROC_FS
static void idedisk_add_settings(ide_drive_t *drive) ide_devset_rw_nolock(acoustic, 0, 254, acoustic);
{ ide_devset_rw_nolock(address, 0, 2, lba_addressing);
ide_add_setting(drive, "bios_cyl", SETTING_RW, TYPE_INT, 0, 65535, 1, 1, ide_devset_rw_nolock(multcount, 0, 16, multcount);
&drive->bios_cyl, NULL); ide_devset_rw_nolock(nowerr, 0, 1, nowerr);
ide_add_setting(drive, "bios_head", SETTING_RW, TYPE_BYTE, 0, 255, 1, 1, ide_devset_rw_nolock(wcache, 0, 1, wcache);
&drive->bios_head, NULL);
ide_add_setting(drive, "bios_sect", SETTING_RW, TYPE_BYTE, 0, 63, 1, 1, ide_devset_rw(bios_cyl, 0, 65535, bios_cyl);
&drive->bios_sect, NULL); ide_devset_rw(bios_head, 0, 255, bios_head);
ide_add_setting(drive, "address", SETTING_RW, TYPE_BYTE, 0, 2, 1, 1, ide_devset_rw(bios_sect, 0, 63, bios_sect);
&drive->addressing, set_lba_addressing); ide_devset_rw(failures, 0, 65535, failures);
ide_add_setting(drive, "multcount", SETTING_RW, TYPE_BYTE, 0, 16, 1, 1, ide_devset_rw(lun, 0, 7, lun);
&drive->mult_count, set_multcount); ide_devset_rw(max_failures, 0, 65535, max_failures);
ide_add_setting(drive, "nowerr", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1,
&drive->nowerr, set_nowerr); static const struct ide_devset *idedisk_settings[] = {
ide_add_setting(drive, "lun", SETTING_RW, TYPE_INT, 0, 7, 1, 1, &ide_devset_acoustic,
&drive->lun, NULL); &ide_devset_address,
ide_add_setting(drive, "wcache", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &ide_devset_bios_cyl,
&drive->wcache, write_cache); &ide_devset_bios_head,
ide_add_setting(drive, "acoustic", SETTING_RW, TYPE_BYTE, 0, 254, 1, 1, &ide_devset_bios_sect,
&drive->acoustic, set_acoustic); &ide_devset_failures,
ide_add_setting(drive, "failures", SETTING_RW, TYPE_INT, 0, 65535, 1, 1, &ide_devset_lun,
&drive->failures, NULL); &ide_devset_max_failures,
ide_add_setting(drive, "max_failures", SETTING_RW, TYPE_INT, 0, 65535, &ide_devset_multcount,
1, 1, &drive->max_failures, NULL); &ide_devset_nowerr,
} &ide_devset_wcache,
#else NULL
static inline void idedisk_add_settings(ide_drive_t *drive) { ; } };
#endif #endif
static void idedisk_setup(ide_drive_t *drive) static void idedisk_setup(ide_drive_t *drive)
...@@ -788,7 +798,6 @@ static void idedisk_setup(ide_drive_t *drive) ...@@ -788,7 +798,6 @@ static void idedisk_setup(ide_drive_t *drive)
unsigned long long capacity; unsigned long long capacity;
ide_proc_register_driver(drive, idkp->driver); ide_proc_register_driver(drive, idkp->driver);
idedisk_add_settings(drive);
if (drive->id_read == 0) if (drive->id_read == 0)
return; return;
...@@ -880,7 +889,7 @@ static void idedisk_setup(ide_drive_t *drive) ...@@ -880,7 +889,7 @@ static void idedisk_setup(ide_drive_t *drive)
if ((id[ATA_ID_CSFO] & 1) || ata_id_wcache_enabled(id)) if ((id[ATA_ID_CSFO] & 1) || ata_id_wcache_enabled(id))
drive->wcache = 1; drive->wcache = 1;
write_cache(drive, 1); set_wcache(drive, 1);
} }
static void ide_cacheflush_p(ide_drive_t *drive) static void ide_cacheflush_p(ide_drive_t *drive)
...@@ -976,6 +985,7 @@ static ide_driver_t idedisk_driver = { ...@@ -976,6 +985,7 @@ static ide_driver_t idedisk_driver = {
.error = __ide_error, .error = __ide_error,
#ifdef CONFIG_IDE_PROC_FS #ifdef CONFIG_IDE_PROC_FS
.proc = idedisk_proc, .proc = idedisk_proc,
.settings = idedisk_settings,
#endif #endif
}; };
...@@ -1056,19 +1066,18 @@ static int idedisk_ioctl(struct inode *inode, struct file *file, ...@@ -1056,19 +1066,18 @@ static int idedisk_ioctl(struct inode *inode, struct file *file,
struct block_device *bdev = inode->i_bdev; struct block_device *bdev = inode->i_bdev;
struct ide_disk_obj *idkp = ide_disk_g(bdev->bd_disk); struct ide_disk_obj *idkp = ide_disk_g(bdev->bd_disk);
ide_drive_t *drive = idkp->drive; ide_drive_t *drive = idkp->drive;
int err, (*setfunc)(ide_drive_t *, int); int err, (*getfunc)(ide_drive_t *), (*setfunc)(ide_drive_t *, int);
u8 *val;
switch (cmd) { switch (cmd) {
case HDIO_GET_ADDRESS: val = &drive->addressing; goto read_val; case HDIO_GET_ADDRESS: getfunc = get_lba_addressing; goto read_val;
case HDIO_GET_MULTCOUNT: val = &drive->mult_count; goto read_val; case HDIO_GET_MULTCOUNT: getfunc = get_multcount; goto read_val;
case HDIO_GET_NOWERR: val = &drive->nowerr; goto read_val; case HDIO_GET_NOWERR: getfunc = get_nowerr; goto read_val;
case HDIO_GET_WCACHE: val = &drive->wcache; goto read_val; case HDIO_GET_WCACHE: getfunc = get_wcache; goto read_val;
case HDIO_GET_ACOUSTIC: val = &drive->acoustic; goto read_val; case HDIO_GET_ACOUSTIC: getfunc = get_acoustic; goto read_val;
case HDIO_SET_ADDRESS: setfunc = set_lba_addressing; goto set_val; case HDIO_SET_ADDRESS: setfunc = set_lba_addressing; goto set_val;
case HDIO_SET_MULTCOUNT: setfunc = set_multcount; goto set_val; case HDIO_SET_MULTCOUNT: setfunc = set_multcount; goto set_val;
case HDIO_SET_NOWERR: setfunc = set_nowerr; goto set_val; case HDIO_SET_NOWERR: setfunc = set_nowerr; goto set_val;
case HDIO_SET_WCACHE: setfunc = write_cache; goto set_val; case HDIO_SET_WCACHE: setfunc = set_wcache; goto set_val;
case HDIO_SET_ACOUSTIC: setfunc = set_acoustic; goto set_val; case HDIO_SET_ACOUSTIC: setfunc = set_acoustic; goto set_val;
} }
...@@ -1077,7 +1086,7 @@ static int idedisk_ioctl(struct inode *inode, struct file *file, ...@@ -1077,7 +1086,7 @@ static int idedisk_ioctl(struct inode *inode, struct file *file,
read_val: read_val:
mutex_lock(&ide_setting_mtx); mutex_lock(&ide_setting_mtx);
spin_lock_irqsave(&ide_lock, flags); spin_lock_irqsave(&ide_lock, flags);
err = *val; err = getfunc(drive);
spin_unlock_irqrestore(&ide_lock, flags); spin_unlock_irqrestore(&ide_lock, flags);
mutex_unlock(&ide_setting_mtx); mutex_unlock(&ide_setting_mtx);
return err >= 0 ? put_user(err, (long __user *)arg) : err; return err >= 0 ? put_user(err, (long __user *)arg) : err;
......
...@@ -1007,21 +1007,32 @@ static int idefloppy_identify_device(ide_drive_t *drive, u16 *id) ...@@ -1007,21 +1007,32 @@ static int idefloppy_identify_device(ide_drive_t *drive, u16 *id)
} }
#ifdef CONFIG_IDE_PROC_FS #ifdef CONFIG_IDE_PROC_FS
static void idefloppy_add_settings(ide_drive_t *drive) 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);
static int get_ticks(ide_drive_t *drive)
{ {
idefloppy_floppy_t *floppy = drive->driver_data; idefloppy_floppy_t *floppy = drive->driver_data;
return floppy->ticks;
}
ide_add_setting(drive, "bios_cyl", SETTING_RW, TYPE_INT, 0, 1023, 1, 1, static int set_ticks(ide_drive_t *drive, int arg)
&drive->bios_cyl, NULL); {
ide_add_setting(drive, "bios_head", SETTING_RW, TYPE_BYTE, 0, 255, 1, 1, idefloppy_floppy_t *floppy = drive->driver_data;
&drive->bios_head, NULL); floppy->ticks = arg;
ide_add_setting(drive, "bios_sect", SETTING_RW, TYPE_BYTE, 0, 63, 1, 1, return 0;
&drive->bios_sect, NULL);
ide_add_setting(drive, "ticks", SETTING_RW, TYPE_BYTE, 0, 255, 1, 1,
&floppy->ticks, NULL);
} }
#else
static inline void idefloppy_add_settings(ide_drive_t *drive) { ; } IDE_DEVSET(ticks, S_RW, 0, 255, 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
};
#endif #endif
static void idefloppy_setup(ide_drive_t *drive, idefloppy_floppy_t *floppy) static void idefloppy_setup(ide_drive_t *drive, idefloppy_floppy_t *floppy)
...@@ -1063,7 +1074,6 @@ static void idefloppy_setup(ide_drive_t *drive, idefloppy_floppy_t *floppy) ...@@ -1063,7 +1074,6 @@ static void idefloppy_setup(ide_drive_t *drive, idefloppy_floppy_t *floppy)
(void) ide_floppy_get_capacity(drive); (void) ide_floppy_get_capacity(drive);
ide_proc_register_driver(drive, floppy->driver); ide_proc_register_driver(drive, floppy->driver);
idefloppy_add_settings(drive);
} }
static void ide_floppy_remove(ide_drive_t *drive) static void ide_floppy_remove(ide_drive_t *drive)
...@@ -1126,6 +1136,7 @@ static ide_driver_t idefloppy_driver = { ...@@ -1126,6 +1136,7 @@ static ide_driver_t idefloppy_driver = {
.error = __ide_error, .error = __ide_error,
#ifdef CONFIG_IDE_PROC_FS #ifdef CONFIG_IDE_PROC_FS
.proc = idefloppy_proc, .proc = idefloppy_proc,
.settings = idefloppy_settings,
#endif #endif
}; };
......
...@@ -1332,8 +1332,6 @@ static void hwif_register_devices(ide_hwif_t *hwif) ...@@ -1332,8 +1332,6 @@ static void hwif_register_devices(ide_hwif_t *hwif)
if (!drive->present) if (!drive->present)
continue; continue;
ide_add_generic_settings(drive);
snprintf(dev->bus_id, BUS_ID_SIZE, "%u.%u", hwif->index, i); snprintf(dev->bus_id, BUS_ID_SIZE, "%u.%u", hwif->index, i);
dev->parent = &hwif->gendev; dev->parent = &hwif->gendev;
dev->bus = &ide_bus_type; dev->bus = &ide_bus_type;
......
This diff is collapsed.
...@@ -2410,28 +2410,56 @@ static void idetape_get_mode_sense_results(ide_drive_t *drive) ...@@ -2410,28 +2410,56 @@ static void idetape_get_mode_sense_results(ide_drive_t *drive)
} }
#ifdef CONFIG_IDE_PROC_FS #ifdef CONFIG_IDE_PROC_FS
static void idetape_add_settings(ide_drive_t *drive) #define ide_tape_devset_get(name, field) \
{ static int get_##name(ide_drive_t *drive) \
idetape_tape_t *tape = drive->driver_data; { \
idetape_tape_t *tape = drive->driver_data; \
ide_add_setting(drive, "buffer", SETTING_READ, TYPE_SHORT, 0, 0xffff, return tape->field; \
1, 2, (u16 *)&tape->caps[16], NULL); }
ide_add_setting(drive, "speed", SETTING_READ, TYPE_SHORT, 0, 0xffff,
1, 1, (u16 *)&tape->caps[14], NULL); #define ide_tape_devset_set(name, field) \
ide_add_setting(drive, "buffer_size", SETTING_READ, TYPE_INT, 0, 0xffff, static int set_##name(ide_drive_t *drive, int arg) \
1, 1024, &tape->buffer_size, NULL); { \
ide_add_setting(drive, "tdsc", SETTING_RW, TYPE_INT, IDETAPE_DSC_RW_MIN, idetape_tape_t *tape = drive->driver_data; \
IDETAPE_DSC_RW_MAX, 1000, HZ, &tape->best_dsc_rw_freq, tape->field = arg; \
NULL); return 0; \
ide_add_setting(drive, "dsc_overlap", SETTING_RW, TYPE_BYTE, 0, 1, 1, }
1, &drive->dsc_overlap, NULL);
ide_add_setting(drive, "avg_speed", SETTING_READ, TYPE_INT, 0, 0xffff, #define ide_tape_devset_rw(_name, _min, _max, _field, _mulf, _divf) \
1, 1, &tape->avg_speed, NULL); ide_tape_devset_get(_name, _field) \
ide_add_setting(drive, "debug_mask", SETTING_RW, TYPE_INT, 0, 0xffff, 1, ide_tape_devset_set(_name, _field) \
1, &tape->debug_mask, NULL); __IDE_DEVSET(_name, S_RW, _min, _max, get_##_name, set_##_name, _mulf, _divf)
}
#else #define ide_tape_devset_r(_name, _min, _max, _field, _mulf, _divf) \
static inline void idetape_add_settings(ide_drive_t *drive) { ; } ide_tape_devset_get(_name, _field) \
__IDE_DEVSET(_name, S_READ, _min, _max, get_##_name, NULL, _mulf, _divf)
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
};
#endif #endif
/* /*
...@@ -2515,7 +2543,6 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor) ...@@ -2515,7 +2543,6 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor)
drive->using_dma ? ", DMA":""); drive->using_dma ? ", DMA":"");
ide_proc_register_driver(drive, tape->driver); ide_proc_register_driver(drive, tape->driver);
idetape_add_settings(drive);
} }
static void ide_tape_remove(ide_drive_t *drive) static void ide_tape_remove(ide_drive_t *drive)
...@@ -2586,6 +2613,7 @@ static ide_driver_t idetape_driver = { ...@@ -2586,6 +2613,7 @@ static ide_driver_t idetape_driver = {
.error = __ide_error, .error = __ide_error,
#ifdef CONFIG_IDE_PROC_FS #ifdef CONFIG_IDE_PROC_FS
.proc = idetape_proc, .proc = idetape_proc,
.settings = idetape_settings,
#endif #endif
}; };
......
...@@ -287,6 +287,8 @@ int ide_spin_wait_hwgroup (ide_drive_t *drive) ...@@ -287,6 +287,8 @@ int ide_spin_wait_hwgroup (ide_drive_t *drive)
EXPORT_SYMBOL(ide_spin_wait_hwgroup); EXPORT_SYMBOL(ide_spin_wait_hwgroup);
ide_devset_get(io_32bit, io_32bit);
int set_io_32bit(ide_drive_t *drive, int arg) int set_io_32bit(ide_drive_t *drive, int arg)
{ {
if (drive->no_io_32bit) if (drive->no_io_32bit)
...@@ -305,6 +307,8 @@ int set_io_32bit(ide_drive_t *drive, int arg) ...@@ -305,6 +307,8 @@ int set_io_32bit(ide_drive_t *drive, int arg)
return 0; return 0;
} }
ide_devset_get(ksettings, keep_settings);
int set_ksettings(ide_drive_t *drive, int arg) int set_ksettings(ide_drive_t *drive, int arg)
{ {
if (arg < 0 || arg > 1) if (arg < 0 || arg > 1)
...@@ -318,6 +322,8 @@ int set_ksettings(ide_drive_t *drive, int arg) ...@@ -318,6 +322,8 @@ int set_ksettings(ide_drive_t *drive, int arg)
return 0; return 0;
} }
ide_devset_get(using_dma, using_dma);
int set_using_dma(ide_drive_t *drive, int arg) int set_using_dma(ide_drive_t *drive, int arg)
{ {
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
...@@ -394,6 +400,8 @@ int set_pio_mode(ide_drive_t *drive, int arg) ...@@ -394,6 +400,8 @@ int set_pio_mode(ide_drive_t *drive, int arg)
return 0; return 0;
} }
ide_devset_get(unmaskirq, unmask);
int set_unmaskirq(ide_drive_t *drive, int arg) int set_unmaskirq(ide_drive_t *drive, int arg)
{ {
if (drive->no_unmask) if (drive->no_unmask)
...@@ -555,14 +563,13 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device ...@@ -555,14 +563,13 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device
{ {
unsigned long flags; unsigned long flags;
ide_driver_t *drv; ide_driver_t *drv;
int err = 0, (*setfunc)(ide_drive_t *, int); int err = 0, (*getfunc)(ide_drive_t *), (*setfunc)(ide_drive_t *, int);
u8 *val;
switch (cmd) { switch (cmd) {
case HDIO_GET_32BIT: val = &drive->io_32bit; goto read_val; case HDIO_GET_32BIT: getfunc = get_io_32bit; goto read_val;
case HDIO_GET_KEEPSETTINGS: val = &drive->keep_settings; goto read_val; case HDIO_GET_KEEPSETTINGS: getfunc = get_ksettings; goto read_val;
case HDIO_GET_UNMASKINTR: val = &drive->unmask; goto read_val; case HDIO_GET_UNMASKINTR: getfunc = get_unmaskirq; goto read_val;
case HDIO_GET_DMA: val = &drive->using_dma; goto read_val; case HDIO_GET_DMA: getfunc = get_using_dma; goto read_val;
case HDIO_SET_32BIT: setfunc = set_io_32bit; goto set_val; case HDIO_SET_32BIT: setfunc = set_io_32bit; goto set_val;
case HDIO_SET_KEEPSETTINGS: setfunc = set_ksettings; goto set_val; case HDIO_SET_KEEPSETTINGS: setfunc = set_ksettings; goto set_val;
case HDIO_SET_PIO_MODE: setfunc = set_pio_mode; goto set_val; case HDIO_SET_PIO_MODE: setfunc = set_pio_mode; goto set_val;
...@@ -638,7 +645,7 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device ...@@ -638,7 +645,7 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device
read_val: read_val:
mutex_lock(&ide_setting_mtx); mutex_lock(&ide_setting_mtx);
spin_lock_irqsave(&ide_lock, flags); spin_lock_irqsave(&ide_lock, flags);
err = *val; err = getfunc(drive);
spin_unlock_irqrestore(&ide_lock, flags); spin_unlock_irqrestore(&ide_lock, flags);
mutex_unlock(&ide_setting_mtx); mutex_unlock(&ide_setting_mtx);
return err >= 0 ? put_user(err, (long __user *)arg) : err; return err >= 0 ? put_user(err, (long __user *)arg) : err;
......
...@@ -429,21 +429,41 @@ static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *r ...@@ -429,21 +429,41 @@ static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *r
} }
#ifdef CONFIG_IDE_PROC_FS #ifdef CONFIG_IDE_PROC_FS
static void idescsi_add_settings(ide_drive_t *drive) #define ide_scsi_devset_get(name, field) \
{ static int get_##name(ide_drive_t *drive) \
idescsi_scsi_t *scsi = drive_to_idescsi(drive); { \
idescsi_scsi_t *scsi = drive_to_idescsi(drive); \
/* return scsi->field; \
* drive setting name read/write data type min max mul_factor div_factor data pointer set function }
*/
ide_add_setting(drive, "bios_cyl", SETTING_RW, TYPE_INT, 0, 1023, 1, 1, &drive->bios_cyl, NULL); #define ide_scsi_devset_set(name, field) \
ide_add_setting(drive, "bios_head", SETTING_RW, TYPE_BYTE, 0, 255, 1, 1, &drive->bios_head, NULL); static int set_##name(ide_drive_t *drive, int arg) \
ide_add_setting(drive, "bios_sect", SETTING_RW, TYPE_BYTE, 0, 63, 1, 1, &drive->bios_sect, NULL); { \
ide_add_setting(drive, "transform", SETTING_RW, TYPE_INT, 0, 3, 1, 1, &scsi->transform, NULL); idescsi_scsi_t *scsi = drive_to_idescsi(drive); \
ide_add_setting(drive, "log", SETTING_RW, TYPE_INT, 0, 1, 1, 1, &scsi->log, NULL); scsi->field = arg; \
} return 0; \
#else }
static inline void idescsi_add_settings(ide_drive_t *drive) { ; }
#define ide_scsi_devset_rw(_name, _min, _max, _field) \
ide_scsi_devset_get(_name, _field); \
ide_scsi_devset_set(_name, _field); \
IDE_DEVSET(_name, S_RW, _min, _max, get_##_name, set_##_name)
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_scsi_devset_rw(transform, 0, 3, transform);
ide_scsi_devset_rw(log, 0, 1, log);
static const struct ide_devset *idescsi_settings[] = {
&ide_devset_bios_cyl,
&ide_devset_bios_head,
&ide_devset_bios_sect,
&ide_devset_log,
&ide_devset_transform,
NULL
};
#endif #endif
/* /*
...@@ -461,7 +481,6 @@ static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi) ...@@ -461,7 +481,6 @@ static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi)
drive->pc_callback = ide_scsi_callback; drive->pc_callback = ide_scsi_callback;
ide_proc_register_driver(drive, scsi->driver); ide_proc_register_driver(drive, scsi->driver);
idescsi_add_settings(drive);
} }
static void ide_scsi_remove(ide_drive_t *drive) static void ide_scsi_remove(ide_drive_t *drive)
...@@ -509,6 +528,7 @@ static ide_driver_t idescsi_driver = { ...@@ -509,6 +528,7 @@ static ide_driver_t idescsi_driver = {
.error = idescsi_atapi_error, .error = idescsi_atapi_error,
#ifdef CONFIG_IDE_PROC_FS #ifdef CONFIG_IDE_PROC_FS
.proc = idescsi_proc, .proc = idescsi_proc,
.settings = idescsi_settings,
#endif #endif
}; };
......
...@@ -304,8 +304,8 @@ typedef enum { ...@@ -304,8 +304,8 @@ typedef enum {
ide_started, /* a drive operation was started, handler was set */ ide_started, /* a drive operation was started, handler was set */
} ide_startstop_t; } ide_startstop_t;
struct ide_devset;
struct ide_driver_s; struct ide_driver_s;
struct ide_settings_s;
#ifdef CONFIG_BLK_DEV_IDEACPI #ifdef CONFIG_BLK_DEV_IDEACPI
struct ide_acpi_drive_link; struct ide_acpi_drive_link;
...@@ -384,7 +384,7 @@ struct ide_drive_s { ...@@ -384,7 +384,7 @@ struct ide_drive_s {
u16 *id; /* identification info */ u16 *id; /* identification info */
#ifdef CONFIG_IDE_PROC_FS #ifdef CONFIG_IDE_PROC_FS
struct proc_dir_entry *proc; /* /proc/ide/ directory entry */ struct proc_dir_entry *proc; /* /proc/ide/ directory entry */
struct ide_settings_s *settings;/* /proc/ide/ drive settings */ const struct ide_devset **settings; /* /proc/ide/ drive settings */
#endif #endif
struct hwif_s *hwif; /* actually (ide_hwif_t *) */ struct hwif_s *hwif; /* actually (ide_hwif_t *) */
...@@ -396,16 +396,16 @@ struct ide_drive_s { ...@@ -396,16 +396,16 @@ struct ide_drive_s {
special_t special; /* special action flags */ special_t special; /* special action flags */
select_t select; /* basic drive/head select reg value */ select_t select; /* basic drive/head select reg value */
u8 keep_settings; /* restore settings after drive reset */
u8 using_dma; /* disk is using dma for read/write */
u8 retry_pio; /* retrying dma capable host in pio */ u8 retry_pio; /* retrying dma capable host in pio */
u8 state; /* retry state */ u8 state; /* retry state */
u8 waiting_for_dma; /* dma currently in progress */ u8 waiting_for_dma; /* dma currently in progress */
u8 unmask; /* okay to unmask other irqs */
u8 noflush; /* don't attempt flushes */
u8 dsc_overlap; /* DSC overlap */
u8 nice1; /* give potential excess bandwidth */
unsigned keep_settings : 1; /* restore settings after drive reset */
unsigned using_dma : 1; /* disk is using dma for read/write */
unsigned unmask : 1; /* okay to unmask other irqs */
unsigned noflush : 1; /* don't attempt flushes */
unsigned dsc_overlap : 1; /* DSC overlap */
unsigned nice1 : 1; /* give potential excess bandwidth */
unsigned present : 1; /* drive is physically present */ unsigned present : 1; /* drive is physically present */
unsigned dead : 1; /* device ejected hint */ unsigned dead : 1; /* device ejected hint */
unsigned id_read : 1; /* 1=id read from disk 0 = synthetic */ unsigned id_read : 1; /* 1=id read from disk 0 = synthetic */
...@@ -423,14 +423,15 @@ struct ide_drive_s { ...@@ -423,14 +423,15 @@ struct ide_drive_s {
unsigned sleeping : 1; /* 1=sleeping & sleep field valid */ unsigned sleeping : 1; /* 1=sleeping & sleep field valid */
unsigned post_reset : 1; unsigned post_reset : 1;
unsigned udma33_warned : 1; unsigned udma33_warned : 1;
unsigned addressing : 2; /* 0=28-bit, 1=48-bit, 2=48-bit doing 28-bit */
unsigned wcache : 1; /* status of write cache */
unsigned nowerr : 1; /* used for ignoring ATA_DF */
u8 addressing; /* 0=28-bit, 1=48-bit, 2=48-bit doing 28-bit */
u8 quirk_list; /* considered quirky, set for a specific host */ u8 quirk_list; /* considered quirky, set for a specific host */
u8 init_speed; /* transfer rate set at boot */ u8 init_speed; /* transfer rate set at boot */
u8 current_speed; /* current transfer rate set */ u8 current_speed; /* current transfer rate set */
u8 desired_speed; /* desired transfer rate set */ u8 desired_speed; /* desired transfer rate set */
u8 dn; /* now wide spread use */ u8 dn; /* now wide spread use */
u8 wcache; /* status of write cache */
u8 acoustic; /* acoustic management */ u8 acoustic; /* acoustic management */
u8 media; /* disk, cdrom, tape, floppy, ... */ u8 media; /* disk, cdrom, tape, floppy, ... */
u8 ready_stat; /* min status value for drive ready */ u8 ready_stat; /* min status value for drive ready */
...@@ -439,7 +440,6 @@ struct ide_drive_s { ...@@ -439,7 +440,6 @@ struct ide_drive_s {
u8 tune_req; /* requested drive tuning setting */ u8 tune_req; /* requested drive tuning setting */
u8 io_32bit; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */ u8 io_32bit; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */
u8 bad_wstat; /* used for ignoring ATA_DF */ u8 bad_wstat; /* used for ignoring ATA_DF */
u8 nowerr; /* used for ignoring ATA_DF */
u8 head; /* "real" number of heads */ u8 head; /* "real" number of heads */
u8 sect; /* "real" sectors per track */ u8 sect; /* "real" sectors per track */
u8 bios_head; /* BIOS/fdisk/LILO number of heads */ u8 bios_head; /* BIOS/fdisk/LILO number of heads */
...@@ -687,12 +687,29 @@ typedef struct ide_driver_s ide_driver_t; ...@@ -687,12 +687,29 @@ typedef struct ide_driver_s ide_driver_t;
extern struct mutex ide_setting_mtx; extern struct mutex ide_setting_mtx;
int get_io_32bit(ide_drive_t *);
int set_io_32bit(ide_drive_t *, int); int set_io_32bit(ide_drive_t *, int);
int get_ksettings(ide_drive_t *);
int set_ksettings(ide_drive_t *, int); int set_ksettings(ide_drive_t *, int);
int set_pio_mode(ide_drive_t *, int); int set_pio_mode(ide_drive_t *, int);
int get_unmaskirq(ide_drive_t *);
int set_unmaskirq(ide_drive_t *, int); int set_unmaskirq(ide_drive_t *, int);
int get_using_dma(ide_drive_t *);
int set_using_dma(ide_drive_t *, int); int set_using_dma(ide_drive_t *, int);
#define ide_devset_get(name, field) \
int get_##name(ide_drive_t *drive) \
{ \
return drive->field; \
}
#define ide_devset_set(name, field) \
int set_##name(ide_drive_t *drive, int arg) \
{ \
drive->field = arg; \
return 0; \
}
/* ATAPI packet command flags */ /* ATAPI packet command flags */
enum { enum {
/* set when an error is considered normal - no retry (ide-tape) */ /* set when an error is considered normal - no retry (ide-tape) */
...@@ -757,30 +774,53 @@ struct ide_atapi_pc { ...@@ -757,30 +774,53 @@ struct ide_atapi_pc {
* configurable drive settings * configurable drive settings
*/ */
#define TYPE_INT 0 #define S_READ (1 << 0)
#define TYPE_BYTE 1 #define S_WRITE (1 << 1)
#define TYPE_SHORT 2 #define S_RW (S_READ | S_WRITE)
#define S_NOLOCK (1 << 2)
#define SETTING_READ (1 << 0) struct ide_devset {
#define SETTING_WRITE (1 << 1) const char *name;
#define SETTING_RW (SETTING_READ | SETTING_WRITE) unsigned int flags;
int min, max;
int (*get)(ide_drive_t *);
int (*set)(ide_drive_t *, int);
int (*mulf)(ide_drive_t *);
int (*divf)(ide_drive_t *);
};
typedef int (ide_procset_t)(ide_drive_t *, int); #define __DEVSET(_name, _flags, _min, _max, _get, _set, _mulf, _divf) { \
typedef struct ide_settings_s { .name = __stringify(_name), \
char *name; .flags = _flags, \
int rw; .min = _min, \
int data_type; .max = _max, \
int min; .get = _get, \
int max; .set = _set, \
int mul_factor; .mulf = _mulf, \
int div_factor; .divf = _divf, \
void *data; }
ide_procset_t *set;
int auto_remove; #define __IDE_DEVSET(_name, _flags, _min, _max, _get, _set, _mulf, _divf) \
struct ide_settings_s *next; static const struct ide_devset ide_devset_##_name = \
} ide_settings_t; __DEVSET(_name, _flags, _min, _max, _get, _set, _mulf, _divf)
int ide_add_setting(ide_drive_t *, const char *, int, int, int, int, int, int, void *, ide_procset_t *set); #define IDE_DEVSET(_name, _flags, _min, _max, _get, _set) \
__IDE_DEVSET(_name, _flags, _min, _max, _get, _set, NULL, NULL)
#define ide_devset_rw_nolock(_name, _min, _max, _func) \
IDE_DEVSET(_name, S_RW | S_NOLOCK, _min, _max, get_##_func, set_##_func)
#define ide_devset_w_nolock(_name, _min, _max, _func) \
IDE_DEVSET(_name, S_WRITE | S_NOLOCK, _min, _max, NULL, set_##_func)
#define ide_devset_rw(_name, _min, _max, _field) \
static ide_devset_get(_name, _field); \
static ide_devset_set(_name, _field); \
IDE_DEVSET(_name, S_RW, _min, _max, get_##_name, set_##_name)
#define ide_devset_r(_name, _min, _max, _field) \
ide_devset_get(_name, _field) \
IDE_DEVSET(_name, S_READ, _min, _max, get_##_name, NULL)
/* /*
* /proc/ide interface * /proc/ide interface
...@@ -801,8 +841,6 @@ void ide_proc_unregister_port(ide_hwif_t *); ...@@ -801,8 +841,6 @@ void ide_proc_unregister_port(ide_hwif_t *);
void ide_proc_register_driver(ide_drive_t *, ide_driver_t *); void ide_proc_register_driver(ide_drive_t *, ide_driver_t *);
void ide_proc_unregister_driver(ide_drive_t *, ide_driver_t *); void ide_proc_unregister_driver(ide_drive_t *, ide_driver_t *);
void ide_add_generic_settings(ide_drive_t *);
read_proc_t proc_ide_read_capacity; read_proc_t proc_ide_read_capacity;
read_proc_t proc_ide_read_geometry; read_proc_t proc_ide_read_geometry;
...@@ -830,7 +868,6 @@ static inline void ide_proc_unregister_device(ide_drive_t *drive) { ; } ...@@ -830,7 +868,6 @@ static inline void ide_proc_unregister_device(ide_drive_t *drive) { ; }
static inline void ide_proc_unregister_port(ide_hwif_t *hwif) { ; } static inline void ide_proc_unregister_port(ide_hwif_t *hwif) { ; }
static inline void ide_proc_register_driver(ide_drive_t *drive, ide_driver_t *driver) { ; } static inline void ide_proc_register_driver(ide_drive_t *drive, ide_driver_t *driver) { ; }
static inline void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t *driver) { ; } static inline void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t *driver) { ; }
static inline void ide_add_generic_settings(ide_drive_t *drive) { ; }
#define PROC_IDE_READ_RETURN(page,start,off,count,eof,len) return 0; #define PROC_IDE_READ_RETURN(page,start,off,count,eof,len) return 0;
#endif #endif
...@@ -887,6 +924,7 @@ struct ide_driver_s { ...@@ -887,6 +924,7 @@ struct ide_driver_s {
void (*shutdown)(ide_drive_t *); void (*shutdown)(ide_drive_t *);
#ifdef CONFIG_IDE_PROC_FS #ifdef CONFIG_IDE_PROC_FS
ide_proc_entry_t *proc; ide_proc_entry_t *proc;
const struct ide_devset **settings;
#endif #endif
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment