ide-proc.c revision d9270a3f1d5b6f9de58250e8ecdba4c48c54c20b
1/*
2 *  Copyright (C) 1997-1998	Mark Lord
3 *  Copyright (C) 2003		Red Hat <alan@redhat.com>
4 *
5 *  Some code was moved here from ide.c, see it for original copyrights.
6 */
7
8/*
9 * This is the /proc/ide/ filesystem implementation.
10 *
11 * Drive/Driver settings can be retrieved by reading the drive's
12 * "settings" files.  e.g.    "cat /proc/ide0/hda/settings"
13 * To write a new value "val" into a specific setting "name", use:
14 *   echo "name:val" >/proc/ide/ide0/hda/settings
15 *
16 * Also useful, "cat /proc/ide0/hda/[identify, smart_values,
17 * smart_thresholds, capabilities]" will issue an IDENTIFY /
18 * PACKET_IDENTIFY / SMART_READ_VALUES / SMART_READ_THRESHOLDS /
19 * SENSE CAPABILITIES command to /dev/hda, and then dump out the
20 * returned data as 256 16-bit words.  The "hdparm" utility will
21 * be updated someday soon to use this mechanism.
22 *
23 */
24
25#include <linux/module.h>
26
27#include <asm/uaccess.h>
28#include <linux/errno.h>
29#include <linux/proc_fs.h>
30#include <linux/stat.h>
31#include <linux/mm.h>
32#include <linux/pci.h>
33#include <linux/ctype.h>
34#include <linux/hdreg.h>
35#include <linux/ide.h>
36#include <linux/seq_file.h>
37
38#include <asm/io.h>
39
40static struct proc_dir_entry *proc_ide_root;
41
42static int proc_ide_read_imodel
43	(char *page, char **start, off_t off, int count, int *eof, void *data)
44{
45	ide_hwif_t	*hwif = (ide_hwif_t *) data;
46	int		len;
47	const char	*name;
48
49	/*
50	 * Neither ide_unknown nor ide_forced should be set at this point.
51	 */
52	switch (hwif->chipset) {
53		case ide_generic:	name = "generic";	break;
54		case ide_pci:		name = "pci";		break;
55		case ide_cmd640:	name = "cmd640";	break;
56		case ide_dtc2278:	name = "dtc2278";	break;
57		case ide_ali14xx:	name = "ali14xx";	break;
58		case ide_qd65xx:	name = "qd65xx";	break;
59		case ide_umc8672:	name = "umc8672";	break;
60		case ide_ht6560b:	name = "ht6560b";	break;
61		case ide_rz1000:	name = "rz1000";	break;
62		case ide_trm290:	name = "trm290";	break;
63		case ide_cmd646:	name = "cmd646";	break;
64		case ide_cy82c693:	name = "cy82c693";	break;
65		case ide_4drives:	name = "4drives";	break;
66		case ide_pmac:		name = "mac-io";	break;
67		case ide_au1xxx:	name = "au1xxx";	break;
68		case ide_etrax100:	name = "etrax100";	break;
69		case ide_acorn:		name = "acorn";		break;
70		default:		name = "(unknown)";	break;
71	}
72	len = sprintf(page, "%s\n", name);
73	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
74}
75
76static int proc_ide_read_mate
77	(char *page, char **start, off_t off, int count, int *eof, void *data)
78{
79	ide_hwif_t	*hwif = (ide_hwif_t *) data;
80	int		len;
81
82	if (hwif && hwif->mate && hwif->mate->present)
83		len = sprintf(page, "%s\n", hwif->mate->name);
84	else
85		len = sprintf(page, "(none)\n");
86	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
87}
88
89static int proc_ide_read_channel
90	(char *page, char **start, off_t off, int count, int *eof, void *data)
91{
92	ide_hwif_t	*hwif = (ide_hwif_t *) data;
93	int		len;
94
95	page[0] = hwif->channel ? '1' : '0';
96	page[1] = '\n';
97	len = 2;
98	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
99}
100
101static int proc_ide_read_identify
102	(char *page, char **start, off_t off, int count, int *eof, void *data)
103{
104	ide_drive_t	*drive = (ide_drive_t *)data;
105	int		len = 0, i = 0;
106	int		err = 0;
107
108	len = sprintf(page, "\n");
109
110	if (drive) {
111		unsigned short *val = (unsigned short *) page;
112
113		err = taskfile_lib_get_identify(drive, page);
114		if (!err) {
115			char *out = ((char *)page) + (SECTOR_WORDS * 4);
116			page = out;
117			do {
118				out += sprintf(out, "%04x%c",
119					le16_to_cpu(*val), (++i & 7) ? ' ' : '\n');
120				val += 1;
121			} while (i < (SECTOR_WORDS * 2));
122			len = out - page;
123		}
124	}
125	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
126}
127
128/**
129 *	__ide_add_setting	-	add an ide setting option
130 *	@drive: drive to use
131 *	@name: setting name
132 *	@rw: true if the function is read write
133 *	@data_type: type of data
134 *	@min: range minimum
135 *	@max: range maximum
136 *	@mul_factor: multiplication scale
137 *	@div_factor: divison scale
138 *	@data: private data field
139 *	@set: setting
140 *	@auto_remove: setting auto removal flag
141 *
142 *	Removes the setting named from the device if it is present.
143 *	The function takes the settings_lock to protect against
144 *	parallel changes. This function must not be called from IRQ
145 *	context. Returns 0 on success or -1 on failure.
146 *
147 *	BUGS: This code is seriously over-engineered. There is also
148 *	magic about how the driver specific features are setup. If
149 *	a driver is attached we assume the driver settings are auto
150 *	remove.
151 */
152
153static 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)
154{
155	ide_settings_t **p = (ide_settings_t **) &drive->settings, *setting = NULL;
156
157	mutex_lock(&ide_setting_mtx);
158	while ((*p) && strcmp((*p)->name, name) < 0)
159		p = &((*p)->next);
160	if ((setting = kzalloc(sizeof(*setting), GFP_KERNEL)) == NULL)
161		goto abort;
162	if ((setting->name = kmalloc(strlen(name) + 1, GFP_KERNEL)) == NULL)
163		goto abort;
164	strcpy(setting->name, name);
165	setting->rw = rw;
166	setting->data_type = data_type;
167	setting->min = min;
168	setting->max = max;
169	setting->mul_factor = mul_factor;
170	setting->div_factor = div_factor;
171	setting->data = data;
172	setting->set = set;
173
174	setting->next = *p;
175	if (auto_remove)
176		setting->auto_remove = 1;
177	*p = setting;
178	mutex_unlock(&ide_setting_mtx);
179	return 0;
180abort:
181	mutex_unlock(&ide_setting_mtx);
182	kfree(setting);
183	return -1;
184}
185
186int 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)
187{
188	return __ide_add_setting(drive, name, rw, data_type, min, max, mul_factor, div_factor, data, set, 1);
189}
190
191EXPORT_SYMBOL(ide_add_setting);
192
193/**
194 *	__ide_remove_setting	-	remove an ide setting option
195 *	@drive: drive to use
196 *	@name: setting name
197 *
198 *	Removes the setting named from the device if it is present.
199 *	The caller must hold the setting semaphore.
200 */
201
202static void __ide_remove_setting (ide_drive_t *drive, char *name)
203{
204	ide_settings_t **p, *setting;
205
206	p = (ide_settings_t **) &drive->settings;
207
208	while ((*p) && strcmp((*p)->name, name))
209		p = &((*p)->next);
210	if ((setting = (*p)) == NULL)
211		return;
212
213	(*p) = setting->next;
214
215	kfree(setting->name);
216	kfree(setting);
217}
218
219/**
220 *	auto_remove_settings	-	remove driver specific settings
221 *	@drive: drive
222 *
223 *	Automatically remove all the driver specific settings for this
224 *	drive. This function may not be called from IRQ context. The
225 *	caller must hold ide_setting_mtx.
226 */
227
228static void auto_remove_settings (ide_drive_t *drive)
229{
230	ide_settings_t *setting;
231repeat:
232	setting = drive->settings;
233	while (setting) {
234		if (setting->auto_remove) {
235			__ide_remove_setting(drive, setting->name);
236			goto repeat;
237		}
238		setting = setting->next;
239	}
240}
241
242/**
243 *	ide_find_setting_by_name	-	find a drive specific setting
244 *	@drive: drive to scan
245 *	@name: setting name
246 *
247 *	Scan's the device setting table for a matching entry and returns
248 *	this or NULL if no entry is found. The caller must hold the
249 *	setting semaphore
250 */
251
252static ide_settings_t *ide_find_setting_by_name(ide_drive_t *drive, char *name)
253{
254	ide_settings_t *setting = drive->settings;
255
256	while (setting) {
257		if (strcmp(setting->name, name) == 0)
258			break;
259		setting = setting->next;
260	}
261	return setting;
262}
263
264/**
265 *	ide_read_setting	-	read an IDE setting
266 *	@drive: drive to read from
267 *	@setting: drive setting
268 *
269 *	Read a drive setting and return the value. The caller
270 *	must hold the ide_setting_mtx when making this call.
271 *
272 *	BUGS: the data return and error are the same return value
273 *	so an error -EINVAL and true return of the same value cannot
274 *	be told apart
275 */
276
277static int ide_read_setting(ide_drive_t *drive, ide_settings_t *setting)
278{
279	int		val = -EINVAL;
280	unsigned long	flags;
281
282	if ((setting->rw & SETTING_READ)) {
283		spin_lock_irqsave(&ide_lock, flags);
284		switch(setting->data_type) {
285			case TYPE_BYTE:
286				val = *((u8 *) setting->data);
287				break;
288			case TYPE_SHORT:
289				val = *((u16 *) setting->data);
290				break;
291			case TYPE_INT:
292				val = *((u32 *) setting->data);
293				break;
294		}
295		spin_unlock_irqrestore(&ide_lock, flags);
296	}
297	return val;
298}
299
300/**
301 *	ide_write_setting	-	read an IDE setting
302 *	@drive: drive to read from
303 *	@setting: drive setting
304 *	@val: value
305 *
306 *	Write a drive setting if it is possible. The caller
307 *	must hold the ide_setting_mtx when making this call.
308 *
309 *	BUGS: the data return and error are the same return value
310 *	so an error -EINVAL and true return of the same value cannot
311 *	be told apart
312 *
313 *	FIXME:  This should be changed to enqueue a special request
314 *	to the driver to change settings, and then wait on a sema for completion.
315 *	The current scheme of polling is kludgy, though safe enough.
316 */
317
318static int ide_write_setting(ide_drive_t *drive, ide_settings_t *setting, int val)
319{
320	if (!capable(CAP_SYS_ADMIN))
321		return -EACCES;
322	if (setting->set)
323		return setting->set(drive, val);
324	if (!(setting->rw & SETTING_WRITE))
325		return -EPERM;
326	if (val < setting->min || val > setting->max)
327		return -EINVAL;
328	if (ide_spin_wait_hwgroup(drive))
329		return -EBUSY;
330	switch (setting->data_type) {
331		case TYPE_BYTE:
332			*((u8 *) setting->data) = val;
333			break;
334		case TYPE_SHORT:
335			*((u16 *) setting->data) = val;
336			break;
337		case TYPE_INT:
338			*((u32 *) setting->data) = val;
339			break;
340	}
341	spin_unlock_irq(&ide_lock);
342	return 0;
343}
344
345static int set_xfer_rate (ide_drive_t *drive, int arg)
346{
347	ide_task_t task;
348	int err;
349
350	if (arg < 0 || arg > 70)
351		return -EINVAL;
352
353	memset(&task, 0, sizeof(task));
354	task.tf.command = WIN_SETFEATURES;
355	task.tf.feature = SETFEATURES_XFER;
356	task.tf.nsect   = (u8)arg;
357	task.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT |
358			IDE_TFLAG_IN_NSECT;
359
360	err = ide_no_data_taskfile(drive, &task);
361
362	if (!err && arg) {
363		ide_set_xfer_rate(drive, (u8) arg);
364		ide_driveid_update(drive);
365	}
366	return err;
367}
368
369/**
370 *	ide_add_generic_settings	-	generic ide settings
371 *	@drive: drive being configured
372 *
373 *	Add the generic parts of the system settings to the /proc files.
374 *	The caller must not be holding the ide_setting_mtx.
375 */
376
377void ide_add_generic_settings (ide_drive_t *drive)
378{
379/*
380 *			  drive		setting name		read/write access				data type	min	max				mul_factor	div_factor	data pointer			set function
381 */
382	__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);
383	__ide_add_setting(drive,	"keepsettings",		SETTING_RW,					TYPE_BYTE,	0,	1,				1,		1,		&drive->keep_settings,		NULL,		0);
384	__ide_add_setting(drive,	"nice1",		SETTING_RW,					TYPE_BYTE,	0,	1,				1,		1,		&drive->nice1,			NULL,		0);
385	__ide_add_setting(drive,	"pio_mode",		SETTING_WRITE,					TYPE_BYTE,	0,	255,				1,		1,		NULL,				set_pio_mode,	0);
386	__ide_add_setting(drive,	"unmaskirq",		drive->no_unmask ? SETTING_READ : SETTING_RW,	TYPE_BYTE,	0,	1,				1,		1,		&drive->unmask,			NULL,		0);
387	__ide_add_setting(drive,	"using_dma",		SETTING_RW,					TYPE_BYTE,	0,	1,				1,		1,		&drive->using_dma,		set_using_dma,	0);
388	__ide_add_setting(drive,	"init_speed",		SETTING_RW,					TYPE_BYTE,	0,	70,				1,		1,		&drive->init_speed,		NULL,		0);
389	__ide_add_setting(drive,	"current_speed",	SETTING_RW,					TYPE_BYTE,	0,	70,				1,		1,		&drive->current_speed,		set_xfer_rate,	0);
390	__ide_add_setting(drive,	"number",		SETTING_RW,					TYPE_BYTE,	0,	3,				1,		1,		&drive->dn,			NULL,		0);
391}
392
393static void proc_ide_settings_warn(void)
394{
395	static int warned = 0;
396
397	if (warned)
398		return;
399
400	printk(KERN_WARNING "Warning: /proc/ide/hd?/settings interface is "
401			    "obsolete, and will be removed soon!\n");
402	warned = 1;
403}
404
405static int proc_ide_read_settings
406	(char *page, char **start, off_t off, int count, int *eof, void *data)
407{
408	ide_drive_t	*drive = (ide_drive_t *) data;
409	ide_settings_t	*setting = (ide_settings_t *) drive->settings;
410	char		*out = page;
411	int		len, rc, mul_factor, div_factor;
412
413	proc_ide_settings_warn();
414
415	mutex_lock(&ide_setting_mtx);
416	out += sprintf(out, "name\t\t\tvalue\t\tmin\t\tmax\t\tmode\n");
417	out += sprintf(out, "----\t\t\t-----\t\t---\t\t---\t\t----\n");
418	while(setting) {
419		mul_factor = setting->mul_factor;
420		div_factor = setting->div_factor;
421		out += sprintf(out, "%-24s", setting->name);
422		if ((rc = ide_read_setting(drive, setting)) >= 0)
423			out += sprintf(out, "%-16d", rc * mul_factor / div_factor);
424		else
425			out += sprintf(out, "%-16s", "write-only");
426		out += sprintf(out, "%-16d%-16d", (setting->min * mul_factor + div_factor - 1) / div_factor, setting->max * mul_factor / div_factor);
427		if (setting->rw & SETTING_READ)
428			out += sprintf(out, "r");
429		if (setting->rw & SETTING_WRITE)
430			out += sprintf(out, "w");
431		out += sprintf(out, "\n");
432		setting = setting->next;
433	}
434	len = out - page;
435	mutex_unlock(&ide_setting_mtx);
436	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
437}
438
439#define MAX_LEN	30
440
441static int proc_ide_write_settings(struct file *file, const char __user *buffer,
442				   unsigned long count, void *data)
443{
444	ide_drive_t	*drive = (ide_drive_t *) data;
445	char		name[MAX_LEN + 1];
446	int		for_real = 0;
447	unsigned long	n;
448	ide_settings_t	*setting;
449	char *buf, *s;
450
451	if (!capable(CAP_SYS_ADMIN))
452		return -EACCES;
453
454	proc_ide_settings_warn();
455
456	if (count >= PAGE_SIZE)
457		return -EINVAL;
458
459	s = buf = (char *)__get_free_page(GFP_USER);
460	if (!buf)
461		return -ENOMEM;
462
463	if (copy_from_user(buf, buffer, count)) {
464		free_page((unsigned long)buf);
465		return -EFAULT;
466	}
467
468	buf[count] = '\0';
469
470	/*
471	 * Skip over leading whitespace
472	 */
473	while (count && isspace(*s)) {
474		--count;
475		++s;
476	}
477	/*
478	 * Do one full pass to verify all parameters,
479	 * then do another to actually write the new settings.
480	 */
481	do {
482		char *p = s;
483		n = count;
484		while (n > 0) {
485			unsigned val;
486			char *q = p;
487
488			while (n > 0 && *p != ':') {
489				--n;
490				p++;
491			}
492			if (*p != ':')
493				goto parse_error;
494			if (p - q > MAX_LEN)
495				goto parse_error;
496			memcpy(name, q, p - q);
497			name[p - q] = 0;
498
499			if (n > 0) {
500				--n;
501				p++;
502			} else
503				goto parse_error;
504
505			val = simple_strtoul(p, &q, 10);
506			n -= q - p;
507			p = q;
508			if (n > 0 && !isspace(*p))
509				goto parse_error;
510			while (n > 0 && isspace(*p)) {
511				--n;
512				++p;
513			}
514
515			mutex_lock(&ide_setting_mtx);
516			setting = ide_find_setting_by_name(drive, name);
517			if (!setting)
518			{
519				mutex_unlock(&ide_setting_mtx);
520				goto parse_error;
521			}
522			if (for_real)
523				ide_write_setting(drive, setting, val * setting->div_factor / setting->mul_factor);
524			mutex_unlock(&ide_setting_mtx);
525		}
526	} while (!for_real++);
527	free_page((unsigned long)buf);
528	return count;
529parse_error:
530	free_page((unsigned long)buf);
531	printk("proc_ide_write_settings(): parse error\n");
532	return -EINVAL;
533}
534
535int proc_ide_read_capacity
536	(char *page, char **start, off_t off, int count, int *eof, void *data)
537{
538	int len = sprintf(page,"%llu\n", (long long)0x7fffffff);
539	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
540}
541
542EXPORT_SYMBOL_GPL(proc_ide_read_capacity);
543
544int proc_ide_read_geometry
545	(char *page, char **start, off_t off, int count, int *eof, void *data)
546{
547	ide_drive_t	*drive = (ide_drive_t *) data;
548	char		*out = page;
549	int		len;
550
551	out += sprintf(out,"physical     %d/%d/%d\n",
552			drive->cyl, drive->head, drive->sect);
553	out += sprintf(out,"logical      %d/%d/%d\n",
554			drive->bios_cyl, drive->bios_head, drive->bios_sect);
555
556	len = out - page;
557	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
558}
559
560EXPORT_SYMBOL(proc_ide_read_geometry);
561
562static int proc_ide_read_dmodel
563	(char *page, char **start, off_t off, int count, int *eof, void *data)
564{
565	ide_drive_t	*drive = (ide_drive_t *) data;
566	struct hd_driveid *id = drive->id;
567	int		len;
568
569	len = sprintf(page, "%.40s\n",
570		(id && id->model[0]) ? (char *)id->model : "(none)");
571	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
572}
573
574static int proc_ide_read_driver
575	(char *page, char **start, off_t off, int count, int *eof, void *data)
576{
577	ide_drive_t	*drive = (ide_drive_t *) data;
578	struct device	*dev = &drive->gendev;
579	ide_driver_t	*ide_drv;
580	int		len;
581
582	if (dev->driver) {
583		ide_drv = container_of(dev->driver, ide_driver_t, gen_driver);
584		len = sprintf(page, "%s version %s\n",
585				dev->driver->name, ide_drv->version);
586	} else
587		len = sprintf(page, "ide-default version 0.9.newide\n");
588	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
589}
590
591static int ide_replace_subdriver(ide_drive_t *drive, const char *driver)
592{
593	struct device *dev = &drive->gendev;
594	int ret = 1;
595	int err;
596
597	device_release_driver(dev);
598	/* FIXME: device can still be in use by previous driver */
599	strlcpy(drive->driver_req, driver, sizeof(drive->driver_req));
600	err = device_attach(dev);
601	if (err < 0)
602		printk(KERN_WARNING "IDE: %s: device_attach error: %d\n",
603			__FUNCTION__, err);
604	drive->driver_req[0] = 0;
605	if (dev->driver == NULL) {
606		err = device_attach(dev);
607		if (err < 0)
608			printk(KERN_WARNING
609				"IDE: %s: device_attach(2) error: %d\n",
610				__FUNCTION__, err);
611	}
612	if (dev->driver && !strcmp(dev->driver->name, driver))
613		ret = 0;
614
615	return ret;
616}
617
618static int proc_ide_write_driver
619	(struct file *file, const char __user *buffer, unsigned long count, void *data)
620{
621	ide_drive_t	*drive = (ide_drive_t *) data;
622	char name[32];
623
624	if (!capable(CAP_SYS_ADMIN))
625		return -EACCES;
626	if (count > 31)
627		count = 31;
628	if (copy_from_user(name, buffer, count))
629		return -EFAULT;
630	name[count] = '\0';
631	if (ide_replace_subdriver(drive, name))
632		return -EINVAL;
633	return count;
634}
635
636static int proc_ide_read_media
637	(char *page, char **start, off_t off, int count, int *eof, void *data)
638{
639	ide_drive_t	*drive = (ide_drive_t *) data;
640	const char	*media;
641	int		len;
642
643	switch (drive->media) {
644		case ide_disk:	media = "disk\n";
645				break;
646		case ide_cdrom:	media = "cdrom\n";
647				break;
648		case ide_tape:	media = "tape\n";
649				break;
650		case ide_floppy:media = "floppy\n";
651				break;
652		case ide_optical:media = "optical\n";
653				break;
654		default:	media = "UNKNOWN\n";
655				break;
656	}
657	strcpy(page,media);
658	len = strlen(media);
659	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
660}
661
662static ide_proc_entry_t generic_drive_entries[] = {
663	{ "driver",	S_IFREG|S_IRUGO,	proc_ide_read_driver,	proc_ide_write_driver },
664	{ "identify",	S_IFREG|S_IRUSR,	proc_ide_read_identify,	NULL },
665	{ "media",	S_IFREG|S_IRUGO,	proc_ide_read_media,	NULL },
666	{ "model",	S_IFREG|S_IRUGO,	proc_ide_read_dmodel,	NULL },
667	{ "settings",	S_IFREG|S_IRUSR|S_IWUSR,proc_ide_read_settings,	proc_ide_write_settings },
668	{ NULL,	0, NULL, NULL }
669};
670
671static void ide_add_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p, void *data)
672{
673	struct proc_dir_entry *ent;
674
675	if (!dir || !p)
676		return;
677	while (p->name != NULL) {
678		ent = create_proc_entry(p->name, p->mode, dir);
679		if (!ent) return;
680		ent->data = data;
681		ent->read_proc = p->read_proc;
682		ent->write_proc = p->write_proc;
683		p++;
684	}
685}
686
687static void ide_remove_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p)
688{
689	if (!dir || !p)
690		return;
691	while (p->name != NULL) {
692		remove_proc_entry(p->name, dir);
693		p++;
694	}
695}
696
697void ide_proc_register_driver(ide_drive_t *drive, ide_driver_t *driver)
698{
699	ide_add_proc_entries(drive->proc, driver->proc, drive);
700}
701
702EXPORT_SYMBOL(ide_proc_register_driver);
703
704/**
705 *	ide_proc_unregister_driver	-	remove driver specific data
706 *	@drive: drive
707 *	@driver: driver
708 *
709 *	Clean up the driver specific /proc files and IDE settings
710 *	for a given drive.
711 *
712 *	Takes ide_setting_mtx and ide_lock.
713 *	Caller must hold none of the locks.
714 */
715
716void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t *driver)
717{
718	unsigned long flags;
719
720	ide_remove_proc_entries(drive->proc, driver->proc);
721
722	mutex_lock(&ide_setting_mtx);
723	spin_lock_irqsave(&ide_lock, flags);
724	/*
725	 * ide_setting_mtx protects the settings list
726	 * ide_lock protects the use of settings
727	 *
728	 * so we need to hold both, ide_settings_sem because we want to
729	 * modify the settings list, and ide_lock because we cannot take
730	 * a setting out that is being used.
731	 *
732	 * OTOH both ide_{read,write}_setting are only ever used under
733	 * ide_setting_mtx.
734	 */
735	auto_remove_settings(drive);
736	spin_unlock_irqrestore(&ide_lock, flags);
737	mutex_unlock(&ide_setting_mtx);
738}
739
740EXPORT_SYMBOL(ide_proc_unregister_driver);
741
742void ide_proc_port_register_devices(ide_hwif_t *hwif)
743{
744	int	d;
745	struct proc_dir_entry *ent;
746	struct proc_dir_entry *parent = hwif->proc;
747	char name[64];
748
749	for (d = 0; d < MAX_DRIVES; d++) {
750		ide_drive_t *drive = &hwif->drives[d];
751
752		if (!drive->present)
753			continue;
754		if (drive->proc)
755			continue;
756
757		drive->proc = proc_mkdir(drive->name, parent);
758		if (drive->proc)
759			ide_add_proc_entries(drive->proc, generic_drive_entries, drive);
760		sprintf(name,"ide%d/%s", (drive->name[2]-'a')/2, drive->name);
761		ent = proc_symlink(drive->name, proc_ide_root, name);
762		if (!ent) return;
763	}
764}
765
766static void destroy_proc_ide_device(ide_hwif_t *hwif, ide_drive_t *drive)
767{
768	if (drive->proc) {
769		ide_remove_proc_entries(drive->proc, generic_drive_entries);
770		remove_proc_entry(drive->name, proc_ide_root);
771		remove_proc_entry(drive->name, hwif->proc);
772		drive->proc = NULL;
773	}
774}
775
776static void destroy_proc_ide_drives(ide_hwif_t *hwif)
777{
778	int	d;
779
780	for (d = 0; d < MAX_DRIVES; d++) {
781		ide_drive_t *drive = &hwif->drives[d];
782		if (drive->proc)
783			destroy_proc_ide_device(hwif, drive);
784	}
785}
786
787static ide_proc_entry_t hwif_entries[] = {
788	{ "channel",	S_IFREG|S_IRUGO,	proc_ide_read_channel,	NULL },
789	{ "mate",	S_IFREG|S_IRUGO,	proc_ide_read_mate,	NULL },
790	{ "model",	S_IFREG|S_IRUGO,	proc_ide_read_imodel,	NULL },
791	{ NULL,	0, NULL, NULL }
792};
793
794void ide_proc_register_port(ide_hwif_t *hwif)
795{
796	if (!hwif->proc) {
797		hwif->proc = proc_mkdir(hwif->name, proc_ide_root);
798
799		if (!hwif->proc)
800			return;
801
802		ide_add_proc_entries(hwif->proc, hwif_entries, hwif);
803	}
804}
805
806#ifdef CONFIG_BLK_DEV_IDEPCI
807void ide_pci_create_host_proc(const char *name, get_info_t *get_info)
808{
809	create_proc_info_entry(name, 0, proc_ide_root, get_info);
810}
811
812EXPORT_SYMBOL_GPL(ide_pci_create_host_proc);
813#endif
814
815void ide_proc_unregister_port(ide_hwif_t *hwif)
816{
817	if (hwif->proc) {
818		destroy_proc_ide_drives(hwif);
819		ide_remove_proc_entries(hwif->proc, hwif_entries);
820		remove_proc_entry(hwif->name, proc_ide_root);
821		hwif->proc = NULL;
822	}
823}
824
825static int proc_print_driver(struct device_driver *drv, void *data)
826{
827	ide_driver_t *ide_drv = container_of(drv, ide_driver_t, gen_driver);
828	struct seq_file *s = data;
829
830	seq_printf(s, "%s version %s\n", drv->name, ide_drv->version);
831
832	return 0;
833}
834
835static int ide_drivers_show(struct seq_file *s, void *p)
836{
837	int err;
838
839	err = bus_for_each_drv(&ide_bus_type, NULL, s, proc_print_driver);
840	if (err < 0)
841		printk(KERN_WARNING "IDE: %s: bus_for_each_drv error: %d\n",
842			__FUNCTION__, err);
843	return 0;
844}
845
846static int ide_drivers_open(struct inode *inode, struct file *file)
847{
848	return single_open(file, &ide_drivers_show, NULL);
849}
850
851static const struct file_operations ide_drivers_operations = {
852	.open		= ide_drivers_open,
853	.read		= seq_read,
854	.llseek		= seq_lseek,
855	.release	= single_release,
856};
857
858void proc_ide_create(void)
859{
860	struct proc_dir_entry *entry;
861
862	proc_ide_root = proc_mkdir("ide", NULL);
863
864	if (!proc_ide_root)
865		return;
866
867	entry = create_proc_entry("drivers", 0, proc_ide_root);
868	if (entry)
869		entry->proc_fops = &ide_drivers_operations;
870}
871
872void proc_ide_destroy(void)
873{
874	remove_proc_entry("drivers", proc_ide_root);
875	remove_proc_entry("ide", NULL);
876}
877