aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2007-05-09 18:01:10 -0400
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2007-05-09 18:01:10 -0400
commit7662d046df09e80680b77b68de896beab45e675e (patch)
treeea2281c59399b3867fb37e1005a0f0e0d2170c5d
parent1497943ee692aa7519fa972d0e3a339649bf3a96 (diff)
ide: move IDE settings handling to ide-proc.c
* move __ide_add_setting() ide_add_setting() __ide_remove_setting() auto_remove_settings() ide_find_setting_by_name() ide_read_setting() ide_write_setting() set_xfer_rate() ide_add_generic_settings() ide_register_subdriver() ide_unregister_subdriver() from ide.c to ide-proc.c * set_{io_32bit,pio_mode,using_dma}() cannot be marked static now, fix it * rename ide_[un]register_subdriver() to ide_proc_[un]register_driver(), update device drivers to use new names * add CONFIG_IDE_PROC_FS=n versions of ide_proc_[un]register_driver() and ide_add_generic_settings() * make ide_find_setting_by_name(), ide_{read,write}_setting() and ide_{add,remove}_proc_entries() static * cover IDE settings code in device drivers with CONFIG_IDE_PROC_FS #ifdef, also while at it cover with CONFIG_IDE_PROC_FS #ifdef ide_driver_t.proc * remove bogus comment from ide.h * cover with CONFIG_IDE_PROC_FS #ifdef .proc and .settings in ide_drive_t Besides saner code this patch results in the IDE core smaller by ~2 kB (on x86-32) and IDE disk driver by ~1 kB (ditto) when CONFIG_IDE_PROC_FS=n. Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
-rw-r--r--drivers/ide/ide-cd.c14
-rw-r--r--drivers/ide/ide-disk.c16
-rw-r--r--drivers/ide/ide-floppy.c16
-rw-r--r--drivers/ide/ide-proc.c310
-rw-r--r--drivers/ide/ide-tape.c17
-rw-r--r--drivers/ide/ide.c313
-rw-r--r--drivers/scsi/ide-scsi.c16
-rw-r--r--include/linux/ide.h39
8 files changed, 378 insertions, 363 deletions
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 29408cfd9869..252ab8295edf 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -3059,10 +3059,14 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
3059 return nslots; 3059 return nslots;
3060} 3060}
3061 3061
3062#ifdef CONFIG_IDE_PROC_FS
3062static void ide_cdrom_add_settings(ide_drive_t *drive) 3063static void ide_cdrom_add_settings(ide_drive_t *drive)
3063{ 3064{
3064 ide_add_setting(drive, "dsc_overlap", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->dsc_overlap, NULL); 3065 ide_add_setting(drive, "dsc_overlap", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->dsc_overlap, NULL);
3065} 3066}
3067#else
3068static inline void ide_cdrom_add_settings(ide_drive_t *drive) { ; }
3069#endif
3066 3070
3067/* 3071/*
3068 * standard prep_rq_fn that builds 10 byte cmds 3072 * standard prep_rq_fn that builds 10 byte cmds
@@ -3291,7 +3295,7 @@ static void ide_cd_remove(ide_drive_t *drive)
3291{ 3295{
3292 struct cdrom_info *info = drive->driver_data; 3296 struct cdrom_info *info = drive->driver_data;
3293 3297
3294 ide_unregister_subdriver(drive, info->driver); 3298 ide_proc_unregister_driver(drive, info->driver);
3295 3299
3296 del_gendisk(info->disk); 3300 del_gendisk(info->disk);
3297 3301
@@ -3336,8 +3340,6 @@ static ide_proc_entry_t idecd_proc[] = {
3336 { "capacity", S_IFREG|S_IRUGO, proc_idecd_read_capacity, NULL }, 3340 { "capacity", S_IFREG|S_IRUGO, proc_idecd_read_capacity, NULL },
3337 { NULL, 0, NULL, NULL } 3341 { NULL, 0, NULL, NULL }
3338}; 3342};
3339#else
3340# define idecd_proc NULL
3341#endif 3343#endif
3342 3344
3343static ide_driver_t ide_cdrom_driver = { 3345static ide_driver_t ide_cdrom_driver = {
@@ -3355,7 +3357,9 @@ static ide_driver_t ide_cdrom_driver = {
3355 .end_request = ide_end_request, 3357 .end_request = ide_end_request,
3356 .error = __ide_error, 3358 .error = __ide_error,
3357 .abort = __ide_abort, 3359 .abort = __ide_abort,
3360#ifdef CONFIG_IDE_PROC_FS
3358 .proc = idecd_proc, 3361 .proc = idecd_proc,
3362#endif
3359}; 3363};
3360 3364
3361static int idecd_open(struct inode * inode, struct file * file) 3365static int idecd_open(struct inode * inode, struct file * file)
@@ -3517,7 +3521,7 @@ static int ide_cd_probe(ide_drive_t *drive)
3517 3521
3518 ide_init_disk(g, drive); 3522 ide_init_disk(g, drive);
3519 3523
3520 ide_register_subdriver(drive, &ide_cdrom_driver); 3524 ide_proc_register_driver(drive, &ide_cdrom_driver);
3521 3525
3522 kref_init(&info->kref); 3526 kref_init(&info->kref);
3523 3527
@@ -3534,7 +3538,7 @@ static int ide_cd_probe(ide_drive_t *drive)
3534 g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE; 3538 g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE;
3535 if (ide_cdrom_setup(drive)) { 3539 if (ide_cdrom_setup(drive)) {
3536 struct cdrom_device_info *devinfo = &info->devinfo; 3540 struct cdrom_device_info *devinfo = &info->devinfo;
3537 ide_unregister_subdriver(drive, &ide_cdrom_driver); 3541 ide_proc_unregister_driver(drive, &ide_cdrom_driver);
3538 kfree(info->buffer); 3542 kfree(info->buffer);
3539 kfree(info->toc); 3543 kfree(info->toc);
3540 kfree(info->changer_info); 3544 kfree(info->changer_info);
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index fb162cb3ebf5..7fff773f2df7 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -560,7 +560,6 @@ static sector_t idedisk_capacity (ide_drive_t *drive)
560} 560}
561 561
562#ifdef CONFIG_IDE_PROC_FS 562#ifdef CONFIG_IDE_PROC_FS
563
564static int smart_enable(ide_drive_t *drive) 563static int smart_enable(ide_drive_t *drive)
565{ 564{
566 ide_task_t args; 565 ide_task_t args;
@@ -678,11 +677,6 @@ static ide_proc_entry_t idedisk_proc[] = {
678 { "smart_thresholds", S_IFREG|S_IRUSR, proc_idedisk_read_smart_thresholds, NULL }, 677 { "smart_thresholds", S_IFREG|S_IRUSR, proc_idedisk_read_smart_thresholds, NULL },
679 { NULL, 0, NULL, NULL } 678 { NULL, 0, NULL, NULL }
680}; 679};
681
682#else
683
684#define idedisk_proc NULL
685
686#endif /* CONFIG_IDE_PROC_FS */ 680#endif /* CONFIG_IDE_PROC_FS */
687 681
688static void idedisk_prepare_flush(request_queue_t *q, struct request *rq) 682static void idedisk_prepare_flush(request_queue_t *q, struct request *rq)
@@ -881,6 +875,7 @@ static int set_lba_addressing(ide_drive_t *drive, int arg)
881 return 0; 875 return 0;
882} 876}
883 877
878#ifdef CONFIG_IDE_PROC_FS
884static void idedisk_add_settings(ide_drive_t *drive) 879static void idedisk_add_settings(ide_drive_t *drive)
885{ 880{
886 struct hd_driveid *id = drive->id; 881 struct hd_driveid *id = drive->id;
@@ -898,6 +893,9 @@ static void idedisk_add_settings(ide_drive_t *drive)
898 ide_add_setting(drive, "failures", SETTING_RW, TYPE_INT, 0, 65535, 1, 1, &drive->failures, NULL); 893 ide_add_setting(drive, "failures", SETTING_RW, TYPE_INT, 0, 65535, 1, 1, &drive->failures, NULL);
899 ide_add_setting(drive, "max_failures", SETTING_RW, TYPE_INT, 0, 65535, 1, 1, &drive->max_failures, NULL); 894 ide_add_setting(drive, "max_failures", SETTING_RW, TYPE_INT, 0, 65535, 1, 1, &drive->max_failures, NULL);
900} 895}
896#else
897static inline void idedisk_add_settings(ide_drive_t *drive) { ; }
898#endif
901 899
902static void idedisk_setup (ide_drive_t *drive) 900static void idedisk_setup (ide_drive_t *drive)
903{ 901{
@@ -1016,7 +1014,7 @@ static void ide_disk_remove(ide_drive_t *drive)
1016 struct ide_disk_obj *idkp = drive->driver_data; 1014 struct ide_disk_obj *idkp = drive->driver_data;
1017 struct gendisk *g = idkp->disk; 1015 struct gendisk *g = idkp->disk;
1018 1016
1019 ide_unregister_subdriver(drive, idkp->driver); 1017 ide_proc_unregister_driver(drive, idkp->driver);
1020 1018
1021 del_gendisk(g); 1019 del_gendisk(g);
1022 1020
@@ -1081,7 +1079,9 @@ static ide_driver_t idedisk_driver = {
1081 .end_request = ide_end_request, 1079 .end_request = ide_end_request,
1082 .error = __ide_error, 1080 .error = __ide_error,
1083 .abort = __ide_abort, 1081 .abort = __ide_abort,
1082#ifdef CONFIG_IDE_PROC_FS
1084 .proc = idedisk_proc, 1083 .proc = idedisk_proc,
1084#endif
1085}; 1085};
1086 1086
1087static int idedisk_open(struct inode *inode, struct file *filp) 1087static int idedisk_open(struct inode *inode, struct file *filp)
@@ -1257,7 +1257,7 @@ static int ide_disk_probe(ide_drive_t *drive)
1257 1257
1258 ide_init_disk(g, drive); 1258 ide_init_disk(g, drive);
1259 1259
1260 ide_register_subdriver(drive, &idedisk_driver); 1260 ide_proc_register_driver(drive, &idedisk_driver);
1261 1261
1262 kref_init(&idkp->kref); 1262 kref_init(&idkp->kref);
1263 1263
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 38fe45cf4019..f429be88c4f9 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -1811,6 +1811,7 @@ static int idefloppy_identify_device (ide_drive_t *drive,struct hd_driveid *id)
1811 return 0; 1811 return 0;
1812} 1812}
1813 1813
1814#ifdef CONFIG_IDE_PROC_FS
1814static void idefloppy_add_settings(ide_drive_t *drive) 1815static void idefloppy_add_settings(ide_drive_t *drive)
1815{ 1816{
1816 idefloppy_floppy_t *floppy = drive->driver_data; 1817 idefloppy_floppy_t *floppy = drive->driver_data;
@@ -1823,6 +1824,9 @@ static void idefloppy_add_settings(ide_drive_t *drive)
1823 ide_add_setting(drive, "bios_sect", SETTING_RW, TYPE_BYTE, 0, 63, 1, 1, &drive->bios_sect, NULL); 1824 ide_add_setting(drive, "bios_sect", SETTING_RW, TYPE_BYTE, 0, 63, 1, 1, &drive->bios_sect, NULL);
1824 ide_add_setting(drive, "ticks", SETTING_RW, TYPE_BYTE, 0, 255, 1, 1, &floppy->ticks, NULL); 1825 ide_add_setting(drive, "ticks", SETTING_RW, TYPE_BYTE, 0, 255, 1, 1, &floppy->ticks, NULL);
1825} 1826}
1827#else
1828static inline void idefloppy_add_settings(ide_drive_t *drive) { ; }
1829#endif
1826 1830
1827/* 1831/*
1828 * Driver initialization. 1832 * Driver initialization.
@@ -1873,7 +1877,7 @@ static void ide_floppy_remove(ide_drive_t *drive)
1873 idefloppy_floppy_t *floppy = drive->driver_data; 1877 idefloppy_floppy_t *floppy = drive->driver_data;
1874 struct gendisk *g = floppy->disk; 1878 struct gendisk *g = floppy->disk;
1875 1879
1876 ide_unregister_subdriver(drive, floppy->driver); 1880 ide_proc_unregister_driver(drive, floppy->driver);
1877 1881
1878 del_gendisk(g); 1882 del_gendisk(g);
1879 1883
@@ -1893,7 +1897,6 @@ static void ide_floppy_release(struct kref *kref)
1893} 1897}
1894 1898
1895#ifdef CONFIG_IDE_PROC_FS 1899#ifdef CONFIG_IDE_PROC_FS
1896
1897static int proc_idefloppy_read_capacity 1900static int proc_idefloppy_read_capacity
1898 (char *page, char **start, off_t off, int count, int *eof, void *data) 1901 (char *page, char **start, off_t off, int count, int *eof, void *data)
1899{ 1902{
@@ -1909,11 +1912,6 @@ static ide_proc_entry_t idefloppy_proc[] = {
1909 { "geometry", S_IFREG|S_IRUGO, proc_ide_read_geometry, NULL }, 1912 { "geometry", S_IFREG|S_IRUGO, proc_ide_read_geometry, NULL },
1910 { NULL, 0, NULL, NULL } 1913 { NULL, 0, NULL, NULL }
1911}; 1914};
1912
1913#else
1914
1915#define idefloppy_proc NULL
1916
1917#endif /* CONFIG_IDE_PROC_FS */ 1915#endif /* CONFIG_IDE_PROC_FS */
1918 1916
1919static int ide_floppy_probe(ide_drive_t *); 1917static int ide_floppy_probe(ide_drive_t *);
@@ -1933,7 +1931,9 @@ static ide_driver_t idefloppy_driver = {
1933 .end_request = idefloppy_do_end_request, 1931 .end_request = idefloppy_do_end_request,
1934 .error = __ide_error, 1932 .error = __ide_error,
1935 .abort = __ide_abort, 1933 .abort = __ide_abort,
1934#ifdef CONFIG_IDE_PROC_FS
1936 .proc = idefloppy_proc, 1935 .proc = idefloppy_proc,
1936#endif
1937}; 1937};
1938 1938
1939static int idefloppy_open(struct inode *inode, struct file *filp) 1939static int idefloppy_open(struct inode *inode, struct file *filp)
@@ -2159,7 +2159,7 @@ static int ide_floppy_probe(ide_drive_t *drive)
2159 2159
2160 ide_init_disk(g, drive); 2160 ide_init_disk(g, drive);
2161 2161
2162 ide_register_subdriver(drive, &idefloppy_driver); 2162 ide_proc_register_driver(drive, &idefloppy_driver);
2163 2163
2164 kref_init(&floppy->kref); 2164 kref_init(&floppy->kref);
2165 2165
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index a9e0b30fb1f2..949a6f609d84 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -3,6 +3,8 @@
3 * 3 *
4 * Copyright (C) 1997-1998 Mark Lord 4 * Copyright (C) 1997-1998 Mark Lord
5 * Copyright (C) 2003 Red Hat <alan@redhat.com> 5 * Copyright (C) 2003 Red Hat <alan@redhat.com>
6 *
7 * Some code was moved here from ide.c, see it for original copyrights.
6 */ 8 */
7 9
8/* 10/*
@@ -121,6 +123,265 @@ static int proc_ide_read_identify
121 PROC_IDE_READ_RETURN(page,start,off,count,eof,len); 123 PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
122} 124}
123 125
126/**
127 * __ide_add_setting - add an ide setting option
128 * @drive: drive to use
129 * @name: setting name
130 * @rw: true if the function is read write
131 * @data_type: type of data
132 * @min: range minimum
133 * @max: range maximum
134 * @mul_factor: multiplication scale
135 * @div_factor: divison scale
136 * @data: private data field
137 * @set: setting
138 * @auto_remove: setting auto removal flag
139 *
140 * Removes the setting named from the device if it is present.
141 * The function takes the settings_lock to protect against
142 * parallel changes. This function must not be called from IRQ
143 * context. Returns 0 on success or -1 on failure.
144 *
145 * BUGS: This code is seriously over-engineered. There is also
146 * magic about how the driver specific features are setup. If
147 * a driver is attached we assume the driver settings are auto
148 * remove.
149 */
150
151static int __ide_add_setting(ide_drive_t *drive, const char *name, int rw, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set, int auto_remove)
152{
153 ide_settings_t **p = (ide_settings_t **) &drive->settings, *setting = NULL;
154
155 down(&ide_setting_sem);
156 while ((*p) && strcmp((*p)->name, name) < 0)
157 p = &((*p)->next);
158 if ((setting = kzalloc(sizeof(*setting), GFP_KERNEL)) == NULL)
159 goto abort;
160 if ((setting->name = kmalloc(strlen(name) + 1, GFP_KERNEL)) == NULL)
161 goto abort;
162 strcpy(setting->name, name);
163 setting->rw = rw;
164 setting->data_type = data_type;
165 setting->min = min;
166 setting->max = max;
167 setting->mul_factor = mul_factor;
168 setting->div_factor = div_factor;
169 setting->data = data;
170 setting->set = set;
171
172 setting->next = *p;
173 if (auto_remove)
174 setting->auto_remove = 1;
175 *p = setting;
176 up(&ide_setting_sem);
177 return 0;
178abort:
179 up(&ide_setting_sem);
180 kfree(setting);
181 return -1;
182}
183
184int ide_add_setting(ide_drive_t *drive, const char *name, int rw, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set)
185{
186 return __ide_add_setting(drive, name, rw, data_type, min, max, mul_factor, div_factor, data, set, 1);
187}
188
189EXPORT_SYMBOL(ide_add_setting);
190
191/**
192 * __ide_remove_setting - remove an ide setting option
193 * @drive: drive to use
194 * @name: setting name
195 *
196 * Removes the setting named from the device if it is present.
197 * The caller must hold the setting semaphore.
198 */
199
200static void __ide_remove_setting (ide_drive_t *drive, char *name)
201{
202 ide_settings_t **p, *setting;
203
204 p = (ide_settings_t **) &drive->settings;
205
206 while ((*p) && strcmp((*p)->name, name))
207 p = &((*p)->next);
208 if ((setting = (*p)) == NULL)
209 return;
210
211 (*p) = setting->next;
212
213 kfree(setting->name);
214 kfree(setting);
215}
216
217/**
218 * auto_remove_settings - remove driver specific settings
219 * @drive: drive
220 *
221 * Automatically remove all the driver specific settings for this
222 * drive. This function may not be called from IRQ context. The
223 * caller must hold ide_setting_sem.
224 */
225
226static void auto_remove_settings (ide_drive_t *drive)
227{
228 ide_settings_t *setting;
229repeat:
230 setting = drive->settings;
231 while (setting) {
232 if (setting->auto_remove) {
233 __ide_remove_setting(drive, setting->name);
234 goto repeat;
235 }
236 setting = setting->next;
237 }
238}
239
240/**
241 * ide_find_setting_by_name - find a drive specific setting
242 * @drive: drive to scan
243 * @name: setting name
244 *
245 * Scan's the device setting table for a matching entry and returns
246 * this or NULL if no entry is found. The caller must hold the
247 * setting semaphore
248 */
249
250static ide_settings_t *ide_find_setting_by_name(ide_drive_t *drive, char *name)
251{
252 ide_settings_t *setting = drive->settings;
253
254 while (setting) {
255 if (strcmp(setting->name, name) == 0)
256 break;
257 setting = setting->next;
258 }
259 return setting;
260}
261
262/**
263 * ide_read_setting - read an IDE setting
264 * @drive: drive to read from
265 * @setting: drive setting
266 *
267 * Read a drive setting and return the value. The caller
268 * must hold the ide_setting_sem when making this call.
269 *
270 * BUGS: the data return and error are the same return value
271 * so an error -EINVAL and true return of the same value cannot
272 * be told apart
273 */
274
275static int ide_read_setting(ide_drive_t *drive, ide_settings_t *setting)
276{
277 int val = -EINVAL;
278 unsigned long flags;
279
280 if ((setting->rw & SETTING_READ)) {
281 spin_lock_irqsave(&ide_lock, flags);
282 switch(setting->data_type) {
283 case TYPE_BYTE:
284 val = *((u8 *) setting->data);
285 break;
286 case TYPE_SHORT:
287 val = *((u16 *) setting->data);
288 break;
289 case TYPE_INT:
290 val = *((u32 *) setting->data);
291 break;
292 }
293 spin_unlock_irqrestore(&ide_lock, flags);
294 }
295 return val;
296}
297
298/**
299 * ide_write_setting - read an IDE setting
300 * @drive: drive to read from
301 * @setting: drive setting
302 * @val: value
303 *
304 * Write a drive setting if it is possible. The caller
305 * must hold the ide_setting_sem when making this call.
306 *
307 * BUGS: the data return and error are the same return value
308 * so an error -EINVAL and true return of the same value cannot
309 * be told apart
310 *
311 * FIXME: This should be changed to enqueue a special request
312 * to the driver to change settings, and then wait on a sema for completion.
313 * The current scheme of polling is kludgy, though safe enough.
314 */
315
316static int ide_write_setting(ide_drive_t *drive, ide_settings_t *setting, int val)
317{
318 if (!capable(CAP_SYS_ADMIN))
319 return -EACCES;
320 if (setting->set)
321 return setting->set(drive, val);
322 if (!(setting->rw & SETTING_WRITE))
323 return -EPERM;
324 if (val < setting->min || val > setting->max)
325 return -EINVAL;
326 if (ide_spin_wait_hwgroup(drive))
327 return -EBUSY;
328 switch (setting->data_type) {
329 case TYPE_BYTE:
330 *((u8 *) setting->data) = val;
331 break;
332 case TYPE_SHORT:
333 *((u16 *) setting->data) = val;
334 break;
335 case TYPE_INT:
336 *((u32 *) setting->data) = val;
337 break;
338 }
339 spin_unlock_irq(&ide_lock);
340 return 0;
341}
342
343static int set_xfer_rate (ide_drive_t *drive, int arg)
344{
345 int err;
346
347 if (arg < 0 || arg > 70)
348 return -EINVAL;
349
350 err = ide_wait_cmd(drive,
351 WIN_SETFEATURES, (u8) arg,
352 SETFEATURES_XFER, 0, NULL);
353
354 if (!err && arg) {
355 ide_set_xfer_rate(drive, (u8) arg);
356 ide_driveid_update(drive);
357 }
358 return err;
359}
360
361/**
362 * ide_add_generic_settings - generic ide settings
363 * @drive: drive being configured
364 *
365 * Add the generic parts of the system settings to the /proc files.
366 * The caller must not be holding the ide_setting_sem.
367 */
368
369void ide_add_generic_settings (ide_drive_t *drive)
370{
371/*
372 * drive setting name read/write access data type min max mul_factor div_factor data pointer set function
373 */
374 __ide_add_setting(drive, "io_32bit", drive->no_io_32bit ? SETTING_READ : SETTING_RW, TYPE_BYTE, 0, 1 + (SUPPORT_VLB_SYNC << 1), 1, 1, &drive->io_32bit, set_io_32bit, 0);
375 __ide_add_setting(drive, "keepsettings", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->keep_settings, NULL, 0);
376 __ide_add_setting(drive, "nice1", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->nice1, NULL, 0);
377 __ide_add_setting(drive, "pio_mode", SETTING_WRITE, TYPE_BYTE, 0, 255, 1, 1, NULL, set_pio_mode, 0);
378 __ide_add_setting(drive, "unmaskirq", drive->no_unmask ? SETTING_READ : SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->unmask, NULL, 0);
379 __ide_add_setting(drive, "using_dma", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->using_dma, set_using_dma, 0);
380 __ide_add_setting(drive, "init_speed", SETTING_RW, TYPE_BYTE, 0, 70, 1, 1, &drive->init_speed, NULL, 0);
381 __ide_add_setting(drive, "current_speed", SETTING_RW, TYPE_BYTE, 0, 70, 1, 1, &drive->current_speed, set_xfer_rate, 0);
382 __ide_add_setting(drive, "number", SETTING_RW, TYPE_BYTE, 0, 3, 1, 1, &drive->dn, NULL, 0);
383}
384
124static void proc_ide_settings_warn(void) 385static void proc_ide_settings_warn(void)
125{ 386{
126 static int warned = 0; 387 static int warned = 0;
@@ -399,7 +660,7 @@ static ide_proc_entry_t generic_drive_entries[] = {
399 { NULL, 0, NULL, NULL } 660 { NULL, 0, NULL, NULL }
400}; 661};
401 662
402void ide_add_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p, void *data) 663static void ide_add_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p, void *data)
403{ 664{
404 struct proc_dir_entry *ent; 665 struct proc_dir_entry *ent;
405 666
@@ -415,7 +676,7 @@ void ide_add_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p, void
415 } 676 }
416} 677}
417 678
418void ide_remove_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p) 679static void ide_remove_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p)
419{ 680{
420 if (!dir || !p) 681 if (!dir || !p)
421 return; 682 return;
@@ -425,6 +686,51 @@ void ide_remove_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p)
425 } 686 }
426} 687}
427 688
689void ide_proc_register_driver(ide_drive_t *drive, ide_driver_t *driver)
690{
691 ide_add_proc_entries(drive->proc, driver->proc, drive);
692}
693
694EXPORT_SYMBOL(ide_proc_register_driver);
695
696/**
697 * ide_proc_unregister_driver - remove driver specific data
698 * @drive: drive
699 * @driver: driver
700 *
701 * Clean up the driver specific /proc files and IDE settings
702 * for a given drive.
703 *
704 * Takes ide_setting_sem and ide_lock.
705 * Caller must hold none of the locks.
706 */
707
708void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t *driver)
709{
710 unsigned long flags;
711
712 ide_remove_proc_entries(drive->proc, driver->proc);
713
714 down(&ide_setting_sem);
715 spin_lock_irqsave(&ide_lock, flags);
716 /*
717 * ide_setting_sem protects the settings list
718 * ide_lock protects the use of settings
719 *
720 * so we need to hold both, ide_settings_sem because we want to
721 * modify the settings list, and ide_lock because we cannot take
722 * a setting out that is being used.
723 *
724 * OTOH both ide_{read,write}_setting are only ever used under
725 * ide_setting_sem.
726 */
727 auto_remove_settings(drive);
728 spin_unlock_irqrestore(&ide_lock, flags);
729 up(&ide_setting_sem);
730}
731
732EXPORT_SYMBOL(ide_proc_unregister_driver);
733
428static void create_proc_ide_drives(ide_hwif_t *hwif) 734static void create_proc_ide_drives(ide_hwif_t *hwif)
429{ 735{
430 int d; 736 int d;
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index fa0d22de37a7..e82bfa5e0ab8 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -4561,6 +4561,8 @@ static void idetape_get_blocksize_from_block_descriptor(ide_drive_t *drive)
4561 printk(KERN_INFO "ide-tape: Adjusted block size - %d\n", tape->tape_block_size); 4561 printk(KERN_INFO "ide-tape: Adjusted block size - %d\n", tape->tape_block_size);
4562#endif /* IDETAPE_DEBUG_INFO */ 4562#endif /* IDETAPE_DEBUG_INFO */
4563} 4563}
4564
4565#ifdef CONFIG_IDE_PROC_FS
4564static void idetape_add_settings (ide_drive_t *drive) 4566static void idetape_add_settings (ide_drive_t *drive)
4565{ 4567{
4566 idetape_tape_t *tape = drive->driver_data; 4568 idetape_tape_t *tape = drive->driver_data;
@@ -4583,6 +4585,9 @@ static void idetape_add_settings (ide_drive_t *drive)
4583 ide_add_setting(drive, "avg_speed", SETTING_READ, TYPE_INT, 0, 0xffff, 1, 1, &tape->avg_speed, NULL); 4585 ide_add_setting(drive, "avg_speed", SETTING_READ, TYPE_INT, 0, 0xffff, 1, 1, &tape->avg_speed, NULL);
4584 ide_add_setting(drive, "debug_level", SETTING_RW, TYPE_INT, 0, 0xffff, 1, 1, &tape->debug_level, NULL); 4586 ide_add_setting(drive, "debug_level", SETTING_RW, TYPE_INT, 0, 0xffff, 1, 1, &tape->debug_level, NULL);
4585} 4587}
4588#else
4589static inline void idetape_add_settings(ide_drive_t *drive) { ; }
4590#endif
4586 4591
4587/* 4592/*
4588 * ide_setup is called to: 4593 * ide_setup is called to:
@@ -4703,7 +4708,7 @@ static void ide_tape_remove(ide_drive_t *drive)
4703{ 4708{
4704 idetape_tape_t *tape = drive->driver_data; 4709 idetape_tape_t *tape = drive->driver_data;
4705 4710
4706 ide_unregister_subdriver(drive, tape->driver); 4711 ide_proc_unregister_driver(drive, tape->driver);
4707 4712
4708 ide_unregister_region(tape->disk); 4713 ide_unregister_region(tape->disk);
4709 4714
@@ -4731,7 +4736,6 @@ static void ide_tape_release(struct kref *kref)
4731} 4736}
4732 4737
4733#ifdef CONFIG_IDE_PROC_FS 4738#ifdef CONFIG_IDE_PROC_FS
4734
4735static int proc_idetape_read_name 4739static int proc_idetape_read_name
4736 (char *page, char **start, off_t off, int count, int *eof, void *data) 4740 (char *page, char **start, off_t off, int count, int *eof, void *data)
4737{ 4741{
@@ -4749,11 +4753,6 @@ static ide_proc_entry_t idetape_proc[] = {
4749 { "name", S_IFREG|S_IRUGO, proc_idetape_read_name, NULL }, 4753 { "name", S_IFREG|S_IRUGO, proc_idetape_read_name, NULL },
4750 { NULL, 0, NULL, NULL } 4754 { NULL, 0, NULL, NULL }
4751}; 4755};
4752
4753#else
4754
4755#define idetape_proc NULL
4756
4757#endif 4756#endif
4758 4757
4759static int ide_tape_probe(ide_drive_t *); 4758static int ide_tape_probe(ide_drive_t *);
@@ -4773,7 +4772,9 @@ static ide_driver_t idetape_driver = {
4773 .end_request = idetape_end_request, 4772 .end_request = idetape_end_request,
4774 .error = __ide_error, 4773 .error = __ide_error,
4775 .abort = __ide_abort, 4774 .abort = __ide_abort,
4775#ifdef CONFIG_IDE_PROC_FS
4776 .proc = idetape_proc, 4776 .proc = idetape_proc,
4777#endif
4777}; 4778};
4778 4779
4779/* 4780/*
@@ -4864,7 +4865,7 @@ static int ide_tape_probe(ide_drive_t *drive)
4864 4865
4865 ide_init_disk(g, drive); 4866 ide_init_disk(g, drive);
4866 4867
4867 ide_register_subdriver(drive, &idetape_driver); 4868 ide_proc_register_driver(drive, &idetape_driver);
4868 4869
4869 kref_init(&tape->kref); 4870 kref_init(&tape->kref);
4870 4871
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 8793a960210c..614c5fd43cd2 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -826,178 +826,6 @@ DECLARE_MUTEX(ide_setting_sem);
826EXPORT_SYMBOL_GPL(ide_setting_sem); 826EXPORT_SYMBOL_GPL(ide_setting_sem);
827 827
828/** 828/**
829 * __ide_add_setting - add an ide setting option
830 * @drive: drive to use
831 * @name: setting name
832 * @rw: true if the function is read write
833 * @data_type: type of data
834 * @min: range minimum
835 * @max: range maximum
836 * @mul_factor: multiplication scale
837 * @div_factor: divison scale
838 * @data: private data field
839 * @set: setting
840 * @auto_remove: setting auto removal flag
841 *
842 * Removes the setting named from the device if it is present.
843 * The function takes the settings_lock to protect against
844 * parallel changes. This function must not be called from IRQ
845 * context. Returns 0 on success or -1 on failure.
846 *
847 * BUGS: This code is seriously over-engineered. There is also
848 * magic about how the driver specific features are setup. If
849 * a driver is attached we assume the driver settings are auto
850 * remove.
851 */
852
853static int __ide_add_setting(ide_drive_t *drive, const char *name, int rw, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set, int auto_remove)
854{
855 ide_settings_t **p = (ide_settings_t **) &drive->settings, *setting = NULL;
856
857 down(&ide_setting_sem);
858 while ((*p) && strcmp((*p)->name, name) < 0)
859 p = &((*p)->next);
860 if ((setting = kzalloc(sizeof(*setting), GFP_KERNEL)) == NULL)
861 goto abort;
862 if ((setting->name = kmalloc(strlen(name) + 1, GFP_KERNEL)) == NULL)
863 goto abort;
864 strcpy(setting->name, name);
865 setting->rw = rw;
866 setting->data_type = data_type;
867 setting->min = min;
868 setting->max = max;
869 setting->mul_factor = mul_factor;
870 setting->div_factor = div_factor;
871 setting->data = data;
872 setting->set = set;
873
874 setting->next = *p;
875 if (auto_remove)
876 setting->auto_remove = 1;
877 *p = setting;
878 up(&ide_setting_sem);
879 return 0;
880abort:
881 up(&ide_setting_sem);
882 kfree(setting);
883 return -1;
884}
885
886int ide_add_setting(ide_drive_t *drive, const char *name, int rw, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set)
887{
888 return __ide_add_setting(drive, name, rw, data_type, min, max, mul_factor, div_factor, data, set, 1);
889}
890
891EXPORT_SYMBOL(ide_add_setting);
892
893/**
894 * __ide_remove_setting - remove an ide setting option
895 * @drive: drive to use
896 * @name: setting name
897 *
898 * Removes the setting named from the device if it is present.
899 * The caller must hold the setting semaphore.
900 */
901
902static void __ide_remove_setting (ide_drive_t *drive, char *name)
903{
904 ide_settings_t **p, *setting;
905
906 p = (ide_settings_t **) &drive->settings;
907
908 while ((*p) && strcmp((*p)->name, name))
909 p = &((*p)->next);
910 if ((setting = (*p)) == NULL)
911 return;
912
913 (*p) = setting->next;
914
915 kfree(setting->name);
916 kfree(setting);
917}
918
919/**
920 * ide_find_setting_by_name - find a drive specific setting
921 * @drive: drive to scan
922 * @name: setting name
923 *
924 * Scan's the device setting table for a matching entry and returns
925 * this or NULL if no entry is found. The caller must hold the
926 * setting semaphore
927 */
928
929ide_settings_t *ide_find_setting_by_name (ide_drive_t *drive, char *name)
930{
931 ide_settings_t *setting = drive->settings;
932
933 while (setting) {
934 if (strcmp(setting->name, name) == 0)
935 break;
936 setting = setting->next;
937 }
938 return setting;
939}
940
941/**
942 * auto_remove_settings - remove driver specific settings
943 * @drive: drive
944 *
945 * Automatically remove all the driver specific settings for this
946 * drive. This function may not be called from IRQ context. The
947 * caller must hold ide_setting_sem.
948 */
949
950static void auto_remove_settings (ide_drive_t *drive)
951{
952 ide_settings_t *setting;
953repeat:
954 setting = drive->settings;
955 while (setting) {
956 if (setting->auto_remove) {
957 __ide_remove_setting(drive, setting->name);
958 goto repeat;
959 }
960 setting = setting->next;
961 }
962}
963
964/**
965 * ide_read_setting - read an IDE setting
966 * @drive: drive to read from
967 * @setting: drive setting
968 *
969 * Read a drive setting and return the value. The caller
970 * must hold the ide_setting_sem when making this call.
971 *
972 * BUGS: the data return and error are the same return value
973 * so an error -EINVAL and true return of the same value cannot
974 * be told apart
975 */
976
977int ide_read_setting (ide_drive_t *drive, ide_settings_t *setting)
978{
979 int val = -EINVAL;
980 unsigned long flags;
981
982 if ((setting->rw & SETTING_READ)) {
983 spin_lock_irqsave(&ide_lock, flags);
984 switch(setting->data_type) {
985 case TYPE_BYTE:
986 val = *((u8 *) setting->data);
987 break;
988 case TYPE_SHORT:
989 val = *((u16 *) setting->data);
990 break;
991 case TYPE_INT:
992 val = *((u32 *) setting->data);
993 break;
994 }
995 spin_unlock_irqrestore(&ide_lock, flags);
996 }
997 return val;
998}
999
1000/**
1001 * ide_spin_wait_hwgroup - wait for group 829 * ide_spin_wait_hwgroup - wait for group
1002 * @drive: drive in the group 830 * @drive: drive in the group
1003 * 831 *
@@ -1030,52 +858,7 @@ int ide_spin_wait_hwgroup (ide_drive_t *drive)
1030 858
1031EXPORT_SYMBOL(ide_spin_wait_hwgroup); 859EXPORT_SYMBOL(ide_spin_wait_hwgroup);
1032 860
1033/** 861int set_io_32bit(ide_drive_t *drive, int arg)
1034 * ide_write_setting - read an IDE setting
1035 * @drive: drive to read from
1036 * @setting: drive setting
1037 * @val: value
1038 *
1039 * Write a drive setting if it is possible. The caller
1040 * must hold the ide_setting_sem when making this call.
1041 *
1042 * BUGS: the data return and error are the same return value
1043 * so an error -EINVAL and true return of the same value cannot
1044 * be told apart
1045 *
1046 * FIXME: This should be changed to enqueue a special request
1047 * to the driver to change settings, and then wait on a sema for completion.
1048 * The current scheme of polling is kludgy, though safe enough.
1049 */
1050
1051int ide_write_setting (ide_drive_t *drive, ide_settings_t *setting, int val)
1052{
1053 if (!capable(CAP_SYS_ADMIN))
1054 return -EACCES;
1055 if (setting->set)
1056 return setting->set(drive, val);
1057 if (!(setting->rw & SETTING_WRITE))
1058 return -EPERM;
1059 if (val < setting->min || val > setting->max)
1060 return -EINVAL;
1061 if (ide_spin_wait_hwgroup(drive))
1062 return -EBUSY;
1063 switch (setting->data_type) {
1064 case TYPE_BYTE:
1065 *((u8 *) setting->data) = val;
1066 break;
1067 case TYPE_SHORT:
1068 *((u16 *) setting->data) = val;
1069 break;
1070 case TYPE_INT:
1071 *((u32 *) setting->data) = val;
1072 break;
1073 }
1074 spin_unlock_irq(&ide_lock);
1075 return 0;
1076}
1077
1078static int set_io_32bit(ide_drive_t *drive, int arg)
1079{ 862{
1080 if (drive->no_io_32bit) 863 if (drive->no_io_32bit)
1081 return -EPERM; 864 return -EPERM;
@@ -1104,7 +887,7 @@ static int set_ksettings(ide_drive_t *drive, int arg)
1104 return 0; 887 return 0;
1105} 888}
1106 889
1107static int set_using_dma (ide_drive_t *drive, int arg) 890int set_using_dma(ide_drive_t *drive, int arg)
1108{ 891{
1109#ifdef CONFIG_BLK_DEV_IDEDMA 892#ifdef CONFIG_BLK_DEV_IDEDMA
1110 ide_hwif_t *hwif = drive->hwif; 893 ide_hwif_t *hwif = drive->hwif;
@@ -1152,7 +935,7 @@ out:
1152#endif 935#endif
1153} 936}
1154 937
1155static int set_pio_mode (ide_drive_t *drive, int arg) 938int set_pio_mode(ide_drive_t *drive, int arg)
1156{ 939{
1157 struct request rq; 940 struct request rq;
1158 941
@@ -1186,48 +969,6 @@ static int set_unmaskirq(ide_drive_t *drive, int arg)
1186 return 0; 969 return 0;
1187} 970}
1188 971
1189static int set_xfer_rate (ide_drive_t *drive, int arg)
1190{
1191 int err;
1192
1193 if (arg < 0 || arg > 70)
1194 return -EINVAL;
1195
1196 err = ide_wait_cmd(drive,
1197 WIN_SETFEATURES, (u8) arg,
1198 SETFEATURES_XFER, 0, NULL);
1199
1200 if (!err && arg) {
1201 ide_set_xfer_rate(drive, (u8) arg);
1202 ide_driveid_update(drive);
1203 }
1204 return err;
1205}
1206
1207/**
1208 * ide_add_generic_settings - generic ide settings
1209 * @drive: drive being configured
1210 *
1211 * Add the generic parts of the system settings to the /proc files.
1212 * The caller must not be holding the ide_setting_sem.
1213 */
1214
1215void ide_add_generic_settings (ide_drive_t *drive)
1216{
1217/*
1218 * drive setting name read/write access data type min max mul_factor div_factor data pointer set function
1219 */
1220 __ide_add_setting(drive, "io_32bit", drive->no_io_32bit ? SETTING_READ : SETTING_RW, TYPE_BYTE, 0, 1 + (SUPPORT_VLB_SYNC << 1), 1, 1, &drive->io_32bit, set_io_32bit, 0);
1221 __ide_add_setting(drive, "keepsettings", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->keep_settings, NULL, 0);
1222 __ide_add_setting(drive, "nice1", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->nice1, NULL, 0);
1223 __ide_add_setting(drive, "pio_mode", SETTING_WRITE, TYPE_BYTE, 0, 255, 1, 1, NULL, set_pio_mode, 0);
1224 __ide_add_setting(drive, "unmaskirq", drive->no_unmask ? SETTING_READ : SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->unmask, NULL, 0);
1225 __ide_add_setting(drive, "using_dma", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->using_dma, set_using_dma, 0);
1226 __ide_add_setting(drive, "init_speed", SETTING_RW, TYPE_BYTE, 0, 70, 1, 1, &drive->init_speed, NULL, 0);
1227 __ide_add_setting(drive, "current_speed", SETTING_RW, TYPE_BYTE, 0, 70, 1, 1, &drive->current_speed, set_xfer_rate, 0);
1228 __ide_add_setting(drive, "number", SETTING_RW, TYPE_BYTE, 0, 3, 1, 1, &drive->dn, NULL, 0);
1229}
1230
1231/** 972/**
1232 * system_bus_clock - clock guess 973 * system_bus_clock - clock guess
1233 * 974 *
@@ -1922,54 +1663,6 @@ static void __init probe_for_hwifs (void)
1922#endif 1663#endif
1923} 1664}
1924 1665
1925void ide_register_subdriver(ide_drive_t *drive, ide_driver_t *driver)
1926{
1927#ifdef CONFIG_IDE_PROC_FS
1928 ide_add_proc_entries(drive->proc, driver->proc, drive);
1929#endif
1930}
1931
1932EXPORT_SYMBOL(ide_register_subdriver);
1933
1934/**
1935 * ide_unregister_subdriver - disconnect drive from driver
1936 * @drive: drive to unplug
1937 * @driver: driver
1938 *
1939 * Disconnect a drive from the driver it was attached to and then
1940 * clean up the various proc files and other objects attached to it.
1941 *
1942 * Takes ide_setting_sem and ide_lock.
1943 * Caller must hold none of the locks.
1944 */
1945
1946void ide_unregister_subdriver(ide_drive_t *drive, ide_driver_t *driver)
1947{
1948 unsigned long flags;
1949
1950#ifdef CONFIG_IDE_PROC_FS
1951 ide_remove_proc_entries(drive->proc, driver->proc);
1952#endif
1953 down(&ide_setting_sem);
1954 spin_lock_irqsave(&ide_lock, flags);
1955 /*
1956 * ide_setting_sem protects the settings list
1957 * ide_lock protects the use of settings
1958 *
1959 * so we need to hold both, ide_settings_sem because we want to
1960 * modify the settings list, and ide_lock because we cannot take
1961 * a setting out that is being used.
1962 *
1963 * OTOH both ide_{read,write}_setting are only ever used under
1964 * ide_setting_sem.
1965 */
1966 auto_remove_settings(drive);
1967 spin_unlock_irqrestore(&ide_lock, flags);
1968 up(&ide_setting_sem);
1969}
1970
1971EXPORT_SYMBOL(ide_unregister_subdriver);
1972
1973/* 1666/*
1974 * Probe module 1667 * Probe module
1975 */ 1668 */
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 4388b8ab69a1..8263f752809d 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -721,6 +721,7 @@ static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *r
721 return ide_stopped; 721 return ide_stopped;
722} 722}
723 723
724#ifdef CONFIG_IDE_PROC_FS
724static void idescsi_add_settings(ide_drive_t *drive) 725static void idescsi_add_settings(ide_drive_t *drive)
725{ 726{
726 idescsi_scsi_t *scsi = drive_to_idescsi(drive); 727 idescsi_scsi_t *scsi = drive_to_idescsi(drive);
@@ -734,6 +735,9 @@ static void idescsi_add_settings(ide_drive_t *drive)
734 ide_add_setting(drive, "transform", SETTING_RW, TYPE_INT, 0, 3, 1, 1, &scsi->transform, NULL); 735 ide_add_setting(drive, "transform", SETTING_RW, TYPE_INT, 0, 3, 1, 1, &scsi->transform, NULL);
735 ide_add_setting(drive, "log", SETTING_RW, TYPE_INT, 0, 1, 1, 1, &scsi->log, NULL); 736 ide_add_setting(drive, "log", SETTING_RW, TYPE_INT, 0, 1, 1, 1, &scsi->log, NULL);
736} 737}
738#else
739static inline void idescsi_add_settings(ide_drive_t *drive) { ; }
740#endif
737 741
738/* 742/*
739 * Driver initialization. 743 * Driver initialization.
@@ -756,7 +760,7 @@ static void ide_scsi_remove(ide_drive_t *drive)
756 struct ide_scsi_obj *scsi = scsihost_to_idescsi(scsihost); 760 struct ide_scsi_obj *scsi = scsihost_to_idescsi(scsihost);
757 struct gendisk *g = scsi->disk; 761 struct gendisk *g = scsi->disk;
758 762
759 ide_unregister_subdriver(drive, scsi->driver); 763 ide_proc_unregister_driver(drive, scsi->driver);
760 764
761 ide_unregister_region(g); 765 ide_unregister_region(g);
762 766
@@ -775,8 +779,6 @@ static ide_proc_entry_t idescsi_proc[] = {
775 { "capacity", S_IFREG|S_IRUGO, proc_ide_read_capacity, NULL }, 779 { "capacity", S_IFREG|S_IRUGO, proc_ide_read_capacity, NULL },
776 { NULL, 0, NULL, NULL } 780 { NULL, 0, NULL, NULL }
777}; 781};
778#else
779# define idescsi_proc NULL
780#endif 782#endif
781 783
782static ide_driver_t idescsi_driver = { 784static ide_driver_t idescsi_driver = {
@@ -790,11 +792,13 @@ static ide_driver_t idescsi_driver = {
790 .version = IDESCSI_VERSION, 792 .version = IDESCSI_VERSION,
791 .media = ide_scsi, 793 .media = ide_scsi,
792 .supports_dsc_overlap = 0, 794 .supports_dsc_overlap = 0,
793 .proc = idescsi_proc,
794 .do_request = idescsi_do_request, 795 .do_request = idescsi_do_request,
795 .end_request = idescsi_end_request, 796 .end_request = idescsi_end_request,
796 .error = idescsi_atapi_error, 797 .error = idescsi_atapi_error,
797 .abort = idescsi_atapi_abort, 798 .abort = idescsi_atapi_abort,
799#ifdef CONFIG_IDE_PROC_FS
800 .proc = idescsi_proc,
801#endif
798}; 802};
799 803
800static int idescsi_ide_open(struct inode *inode, struct file *filp) 804static int idescsi_ide_open(struct inode *inode, struct file *filp)
@@ -1153,7 +1157,7 @@ static int ide_scsi_probe(ide_drive_t *drive)
1153 idescsi->host = host; 1157 idescsi->host = host;
1154 idescsi->disk = g; 1158 idescsi->disk = g;
1155 g->private_data = &idescsi->driver; 1159 g->private_data = &idescsi->driver;
1156 ide_register_subdriver(drive, &idescsi_driver); 1160 ide_proc_register_driver(drive, &idescsi_driver);
1157 err = 0; 1161 err = 0;
1158 idescsi_setup(drive, idescsi); 1162 idescsi_setup(drive, idescsi);
1159 g->fops = &idescsi_ops; 1163 g->fops = &idescsi_ops;
@@ -1165,7 +1169,7 @@ static int ide_scsi_probe(ide_drive_t *drive)
1165 } 1169 }
1166 /* fall through on error */ 1170 /* fall through on error */
1167 ide_unregister_region(g); 1171 ide_unregister_region(g);
1168 ide_unregister_subdriver(drive, &idescsi_driver); 1172 ide_proc_unregister_driver(drive, &idescsi_driver);
1169 1173
1170 put_disk(g); 1174 put_disk(g);
1171out_host_put: 1175out_host_put:
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 591a0b55e31c..477b8c6be727 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -559,9 +559,10 @@ typedef struct ide_drive_s {
559 struct ide_drive_s *next; /* circular list of hwgroup drives */ 559 struct ide_drive_s *next; /* circular list of hwgroup drives */
560 void *driver_data; /* extra driver data */ 560 void *driver_data; /* extra driver data */
561 struct hd_driveid *id; /* drive model identification info */ 561 struct hd_driveid *id; /* drive model identification info */
562#ifdef CONFIG_IDE_PROC_FS
562 struct proc_dir_entry *proc; /* /proc/ide/ directory entry */ 563 struct proc_dir_entry *proc; /* /proc/ide/ directory entry */
563 struct ide_settings_s *settings;/* /proc/ide/ drive settings */ 564 struct ide_settings_s *settings;/* /proc/ide/ drive settings */
564 565#endif
565 struct hwif_s *hwif; /* actually (ide_hwif_t *) */ 566 struct hwif_s *hwif; /* actually (ide_hwif_t *) */
566 567
567 unsigned long sleep; /* sleep until this time */ 568 unsigned long sleep; /* sleep until this time */
@@ -858,8 +859,15 @@ typedef struct hwgroup_s {
858 unsigned char cmd_buf[4]; 859 unsigned char cmd_buf[4];
859} ide_hwgroup_t; 860} ide_hwgroup_t;
860 861
861/* structure attached to the request for IDE_TASK_CMDS */ 862typedef struct ide_driver_s ide_driver_t;
863
864extern struct semaphore ide_setting_sem;
862 865
866int set_io_32bit(ide_drive_t *, int);
867int set_pio_mode(ide_drive_t *, int);
868int set_using_dma(ide_drive_t *, int);
869
870#ifdef CONFIG_IDE_PROC_FS
863/* 871/*
864 * configurable drive settings 872 * configurable drive settings
865 */ 873 */
@@ -887,12 +895,7 @@ typedef struct ide_settings_s {
887 struct ide_settings_s *next; 895 struct ide_settings_s *next;
888} ide_settings_t; 896} ide_settings_t;
889 897
890extern struct semaphore ide_setting_sem;
891int ide_add_setting(ide_drive_t *, const char *, int, int, int, int, int, int, void *, ide_procset_t *set); 898int ide_add_setting(ide_drive_t *, const char *, int, int, int, int, int, int, void *, ide_procset_t *set);
892extern ide_settings_t *ide_find_setting_by_name(ide_drive_t *drive, char *name);
893extern int ide_read_setting(ide_drive_t *t, ide_settings_t *setting);
894extern int ide_write_setting(ide_drive_t *drive, ide_settings_t *setting, int val);
895extern void ide_add_generic_settings(ide_drive_t *drive);
896 899
897/* 900/*
898 * /proc/ide interface 901 * /proc/ide interface
@@ -904,15 +907,17 @@ typedef struct {
904 write_proc_t *write_proc; 907 write_proc_t *write_proc;
905} ide_proc_entry_t; 908} ide_proc_entry_t;
906 909
907#ifdef CONFIG_IDE_PROC_FS
908extern struct proc_dir_entry *proc_ide_root; 910extern struct proc_dir_entry *proc_ide_root;
909 911
910void proc_ide_create(void); 912void proc_ide_create(void);
911void proc_ide_destroy(void); 913void proc_ide_destroy(void);
912void create_proc_ide_interfaces(void); 914void create_proc_ide_interfaces(void);
913void destroy_proc_ide_interface(ide_hwif_t *); 915void destroy_proc_ide_interface(ide_hwif_t *);
914void ide_add_proc_entries(struct proc_dir_entry *, ide_proc_entry_t *, void *); 916void ide_proc_register_driver(ide_drive_t *, ide_driver_t *);
915void ide_remove_proc_entries(struct proc_dir_entry *, ide_proc_entry_t *); 917void ide_proc_unregister_driver(ide_drive_t *, ide_driver_t *);
918
919void ide_add_generic_settings(ide_drive_t *);
920
916read_proc_t proc_ide_read_capacity; 921read_proc_t proc_ide_read_capacity;
917read_proc_t proc_ide_read_geometry; 922read_proc_t proc_ide_read_geometry;
918 923
@@ -940,6 +945,9 @@ static inline void proc_ide_create(void) { ; }
940static inline void proc_ide_destroy(void) { ; } 945static inline void proc_ide_destroy(void) { ; }
941static inline void create_proc_ide_interfaces(void) { ; } 946static inline void create_proc_ide_interfaces(void) { ; }
942static inline void destroy_proc_ide_interface(ide_hwif_t *hwif) { ; } 947static inline void destroy_proc_ide_interface(ide_hwif_t *hwif) { ; }
948static inline void ide_proc_register_driver(ide_drive_t *drive, ide_driver_t *driver) { ; }
949static inline void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t *driver) { ; }
950static inline void ide_add_generic_settings(ide_drive_t *drive) { ; }
943#define PROC_IDE_READ_RETURN(page,start,off,count,eof,len) return 0; 951#define PROC_IDE_READ_RETURN(page,start,off,count,eof,len) return 0;
944#endif 952#endif
945 953
@@ -982,7 +990,7 @@ enum {
982 * The gendriver.owner field should be set to the module owner of this driver. 990 * The gendriver.owner field should be set to the module owner of this driver.
983 * The gendriver.name field should be set to the name of this driver 991 * The gendriver.name field should be set to the name of this driver
984 */ 992 */
985typedef struct ide_driver_s { 993struct ide_driver_s {
986 const char *version; 994 const char *version;
987 u8 media; 995 u8 media;
988 unsigned supports_dsc_overlap : 1; 996 unsigned supports_dsc_overlap : 1;
@@ -990,12 +998,14 @@ typedef struct ide_driver_s {
990 int (*end_request)(ide_drive_t *, int, int); 998 int (*end_request)(ide_drive_t *, int, int);
991 ide_startstop_t (*error)(ide_drive_t *, struct request *rq, u8, u8); 999 ide_startstop_t (*error)(ide_drive_t *, struct request *rq, u8, u8);
992 ide_startstop_t (*abort)(ide_drive_t *, struct request *rq); 1000 ide_startstop_t (*abort)(ide_drive_t *, struct request *rq);
993 ide_proc_entry_t *proc;
994 struct device_driver gen_driver; 1001 struct device_driver gen_driver;
995 int (*probe)(ide_drive_t *); 1002 int (*probe)(ide_drive_t *);
996 void (*remove)(ide_drive_t *); 1003 void (*remove)(ide_drive_t *);
997 void (*shutdown)(ide_drive_t *); 1004 void (*shutdown)(ide_drive_t *);
998} ide_driver_t; 1005#ifdef CONFIG_IDE_PROC_FS
1006 ide_proc_entry_t *proc;
1007#endif
1008};
999 1009
1000#define to_ide_driver(drv) container_of(drv, ide_driver_t, gen_driver) 1010#define to_ide_driver(drv) container_of(drv, ide_driver_t, gen_driver)
1001 1011
@@ -1205,9 +1215,6 @@ extern void default_hwif_iops(ide_hwif_t *);
1205extern void default_hwif_mmiops(ide_hwif_t *); 1215extern void default_hwif_mmiops(ide_hwif_t *);
1206extern void default_hwif_transport(ide_hwif_t *); 1216extern void default_hwif_transport(ide_hwif_t *);
1207 1217
1208void ide_register_subdriver(ide_drive_t *, ide_driver_t *);
1209void ide_unregister_subdriver(ide_drive_t *, ide_driver_t *);
1210
1211#define ON_BOARD 1 1218#define ON_BOARD 1
1212#define NEVER_BOARD 0 1219#define NEVER_BOARD 0
1213 1220