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