xref: /linux/drivers/s390/block/dasd_devmap.c (revision b233b28eac0cc37d07c2d007ea08c86c778c5af4)
1 /*
2  * File...........: linux/drivers/s390/block/dasd_devmap.c
3  * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
4  *		    Horst Hummel <Horst.Hummel@de.ibm.com>
5  *		    Carsten Otte <Cotte@de.ibm.com>
6  *		    Martin Schwidefsky <schwidefsky@de.ibm.com>
7  * Bugreports.to..: <Linux390@de.ibm.com>
8  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001
9  *
10  * Device mapping and dasd= parameter parsing functions. All devmap
11  * functions may not be called from interrupt context. In particular
12  * dasd_get_device is a no-no from interrupt context.
13  *
14  */
15 
16 #include <linux/ctype.h>
17 #include <linux/init.h>
18 #include <linux/module.h>
19 
20 #include <asm/debug.h>
21 #include <asm/uaccess.h>
22 #include <asm/ipl.h>
23 
24 /* This is ugly... */
25 #define PRINTK_HEADER "dasd_devmap:"
26 #define DASD_BUS_ID_SIZE 20
27 
28 #include "dasd_int.h"
29 
30 struct kmem_cache *dasd_page_cache;
31 EXPORT_SYMBOL_GPL(dasd_page_cache);
32 
33 /*
34  * dasd_devmap_t is used to store the features and the relation
35  * between device number and device index. To find a dasd_devmap_t
36  * that corresponds to a device number of a device index each
37  * dasd_devmap_t is added to two linked lists, one to search by
38  * the device number and one to search by the device index. As
39  * soon as big minor numbers are available the device index list
40  * can be removed since the device number will then be identical
41  * to the device index.
42  */
43 struct dasd_devmap {
44 	struct list_head list;
45 	char bus_id[DASD_BUS_ID_SIZE];
46         unsigned int devindex;
47         unsigned short features;
48 	struct dasd_device *device;
49 	struct dasd_uid uid;
50 };
51 
52 /*
53  * Parameter parsing functions for dasd= parameter. The syntax is:
54  *   <devno>		: (0x)?[0-9a-fA-F]+
55  *   <busid>		: [0-0a-f]\.[0-9a-f]\.(0x)?[0-9a-fA-F]+
56  *   <feature>		: ro
57  *   <feature_list>	: \(<feature>(:<feature>)*\)
58  *   <devno-range>	: <devno>(-<devno>)?<feature_list>?
59  *   <busid-range>	: <busid>(-<busid>)?<feature_list>?
60  *   <devices>		: <devno-range>|<busid-range>
61  *   <dasd_module>	: dasd_diag_mod|dasd_eckd_mod|dasd_fba_mod
62  *
63  *   <dasd>		: autodetect|probeonly|<devices>(,<devices>)*
64  */
65 
66 int dasd_probeonly =  0;	/* is true, when probeonly mode is active */
67 int dasd_autodetect = 0;	/* is true, when autodetection is active */
68 int dasd_nopav = 0;		/* is true, when PAV is disabled */
69 EXPORT_SYMBOL_GPL(dasd_nopav);
70 
71 /*
72  * char *dasd[] is intended to hold the ranges supplied by the dasd= statement
73  * it is named 'dasd' to directly be filled by insmod with the comma separated
74  * strings when running as a module.
75  */
76 static char *dasd[256];
77 module_param_array(dasd, charp, NULL, 0);
78 
79 /*
80  * Single spinlock to protect devmap and servermap structures and lists.
81  */
82 static DEFINE_SPINLOCK(dasd_devmap_lock);
83 
84 /*
85  * Hash lists for devmap structures.
86  */
87 static struct list_head dasd_hashlists[256];
88 int dasd_max_devindex;
89 
90 static struct dasd_devmap *dasd_add_busid(const char *, int);
91 
92 static inline int
93 dasd_hash_busid(const char *bus_id)
94 {
95 	int hash, i;
96 
97 	hash = 0;
98 	for (i = 0; (i < DASD_BUS_ID_SIZE) && *bus_id; i++, bus_id++)
99 		hash += *bus_id;
100 	return hash & 0xff;
101 }
102 
103 #ifndef MODULE
104 /*
105  * The parameter parsing functions for builtin-drivers are called
106  * before kmalloc works. Store the pointers to the parameters strings
107  * into dasd[] for later processing.
108  */
109 static int __init
110 dasd_call_setup(char *str)
111 {
112 	static int count = 0;
113 
114 	if (count < 256)
115 		dasd[count++] = str;
116 	return 1;
117 }
118 
119 __setup ("dasd=", dasd_call_setup);
120 #endif	/* #ifndef MODULE */
121 
122 #define	DASD_IPLDEV	"ipldev"
123 
124 /*
125  * Read a device busid/devno from a string.
126  */
127 static int
128 dasd_busid(char **str, int *id0, int *id1, int *devno)
129 {
130 	int val, old_style;
131 
132 	/* Interpret ipldev busid */
133 	if (strncmp(DASD_IPLDEV, *str, strlen(DASD_IPLDEV)) == 0) {
134 		if (ipl_info.type != IPL_TYPE_CCW) {
135 			MESSAGE(KERN_ERR, "%s", "ipl device is not a ccw "
136 				"device");
137 			return -EINVAL;
138 		}
139 		*id0 = 0;
140 		*id1 = ipl_info.data.ccw.dev_id.ssid;
141 		*devno = ipl_info.data.ccw.dev_id.devno;
142 		*str += strlen(DASD_IPLDEV);
143 
144 		return 0;
145 	}
146 	/* check for leading '0x' */
147 	old_style = 0;
148 	if ((*str)[0] == '0' && (*str)[1] == 'x') {
149 		*str += 2;
150 		old_style = 1;
151 	}
152 	if (!isxdigit((*str)[0]))	/* We require at least one hex digit */
153 		return -EINVAL;
154 	val = simple_strtoul(*str, str, 16);
155 	if (old_style || (*str)[0] != '.') {
156 		*id0 = *id1 = 0;
157 		if (val < 0 || val > 0xffff)
158 			return -EINVAL;
159 		*devno = val;
160 		return 0;
161 	}
162 	/* New style x.y.z busid */
163 	if (val < 0 || val > 0xff)
164 		return -EINVAL;
165 	*id0 = val;
166 	(*str)++;
167 	if (!isxdigit((*str)[0]))	/* We require at least one hex digit */
168 		return -EINVAL;
169 	val = simple_strtoul(*str, str, 16);
170 	if (val < 0 || val > 0xff || (*str)++[0] != '.')
171 		return -EINVAL;
172 	*id1 = val;
173 	if (!isxdigit((*str)[0]))	/* We require at least one hex digit */
174 		return -EINVAL;
175 	val = simple_strtoul(*str, str, 16);
176 	if (val < 0 || val > 0xffff)
177 		return -EINVAL;
178 	*devno = val;
179 	return 0;
180 }
181 
182 /*
183  * Read colon separated list of dasd features. Currently there is
184  * only one: "ro" for read-only devices. The default feature set
185  * is empty (value 0).
186  */
187 static int
188 dasd_feature_list(char *str, char **endp)
189 {
190 	int features, len, rc;
191 
192 	rc = 0;
193 	if (*str != '(') {
194 		*endp = str;
195 		return DASD_FEATURE_DEFAULT;
196 	}
197 	str++;
198 	features = 0;
199 
200 	while (1) {
201 		for (len = 0;
202 		     str[len] && str[len] != ':' && str[len] != ')'; len++);
203 		if (len == 2 && !strncmp(str, "ro", 2))
204 			features |= DASD_FEATURE_READONLY;
205 		else if (len == 4 && !strncmp(str, "diag", 4))
206 			features |= DASD_FEATURE_USEDIAG;
207 		else if (len == 6 && !strncmp(str, "erplog", 6))
208 			features |= DASD_FEATURE_ERPLOG;
209 		else if (len == 8 && !strncmp(str, "failfast", 8))
210 			features |= DASD_FEATURE_FAILFAST;
211 		else {
212 			MESSAGE(KERN_WARNING,
213 				"unsupported feature: %*s, "
214 				"ignoring setting", len, str);
215 			rc = -EINVAL;
216 		}
217 		str += len;
218 		if (*str != ':')
219 			break;
220 		str++;
221 	}
222 	if (*str != ')') {
223 		MESSAGE(KERN_WARNING, "%s",
224 			"missing ')' in dasd parameter string\n");
225 		rc = -EINVAL;
226 	} else
227 		str++;
228 	*endp = str;
229 	if (rc != 0)
230 		return rc;
231 	return features;
232 }
233 
234 /*
235  * Try to match the first element on the comma separated parse string
236  * with one of the known keywords. If a keyword is found, take the approprate
237  * action and return a pointer to the residual string. If the first element
238  * could not be matched to any keyword then return an error code.
239  */
240 static char *
241 dasd_parse_keyword( char *parsestring ) {
242 
243 	char *nextcomma, *residual_str;
244 	int length;
245 
246 	nextcomma = strchr(parsestring,',');
247 	if (nextcomma) {
248 		length = nextcomma - parsestring;
249 		residual_str = nextcomma + 1;
250 	} else {
251 		length = strlen(parsestring);
252 		residual_str = parsestring + length;
253         }
254 	if (strncmp("autodetect", parsestring, length) == 0) {
255 		dasd_autodetect = 1;
256 		MESSAGE (KERN_INFO, "%s",
257 			 "turning to autodetection mode");
258                 return residual_str;
259         }
260 	if (strncmp("probeonly", parsestring, length) == 0) {
261 		dasd_probeonly = 1;
262 		MESSAGE(KERN_INFO, "%s",
263 			"turning to probeonly mode");
264                 return residual_str;
265         }
266 	if (strncmp("nopav", parsestring, length) == 0) {
267 		if (MACHINE_IS_VM)
268 			MESSAGE(KERN_INFO, "%s", "'nopav' not supported on VM");
269 		else {
270 			dasd_nopav = 1;
271 			MESSAGE(KERN_INFO, "%s", "disable PAV mode");
272 		}
273 		return residual_str;
274 	}
275 	if (strncmp("fixedbuffers", parsestring, length) == 0) {
276 		if (dasd_page_cache)
277 			return residual_str;
278 		dasd_page_cache =
279 			kmem_cache_create("dasd_page_cache", PAGE_SIZE,
280 					  PAGE_SIZE, SLAB_CACHE_DMA,
281 					  NULL);
282 		if (!dasd_page_cache)
283 			MESSAGE(KERN_WARNING, "%s", "Failed to create slab, "
284 				"fixed buffer mode disabled.");
285 		else
286 			MESSAGE (KERN_INFO, "%s",
287 				 "turning on fixed buffer mode");
288                 return residual_str;
289         }
290 	return ERR_PTR(-EINVAL);
291 }
292 
293 /*
294  * Try to interprete the first element on the comma separated parse string
295  * as a device number or a range of devices. If the interpretation is
296  * successfull, create the matching dasd_devmap entries and return a pointer
297  * to the residual string.
298  * If interpretation fails or in case of an error, return an error code.
299  */
300 static char *
301 dasd_parse_range( char *parsestring ) {
302 
303 	struct dasd_devmap *devmap;
304 	int from, from_id0, from_id1;
305 	int to, to_id0, to_id1;
306 	int features, rc;
307 	char bus_id[DASD_BUS_ID_SIZE+1], *str;
308 
309 	str = parsestring;
310 	rc = dasd_busid(&str, &from_id0, &from_id1, &from);
311 	if (rc == 0) {
312 		to = from;
313 		to_id0 = from_id0;
314 		to_id1 = from_id1;
315 		if (*str == '-') {
316 			str++;
317 			rc = dasd_busid(&str, &to_id0, &to_id1, &to);
318 		}
319 	}
320 	if (rc == 0 &&
321 	    (from_id0 != to_id0 || from_id1 != to_id1 || from > to))
322 		rc = -EINVAL;
323 	if (rc) {
324 		MESSAGE(KERN_ERR, "Invalid device range %s", parsestring);
325 		return ERR_PTR(rc);
326 	}
327 	features = dasd_feature_list(str, &str);
328 	if (features < 0)
329 		return ERR_PTR(-EINVAL);
330 	/* each device in dasd= parameter should be set initially online */
331 	features |= DASD_FEATURE_INITIAL_ONLINE;
332 	while (from <= to) {
333 		sprintf(bus_id, "%01x.%01x.%04x",
334 			from_id0, from_id1, from++);
335 		devmap = dasd_add_busid(bus_id, features);
336 		if (IS_ERR(devmap))
337 			return (char *)devmap;
338 	}
339 	if (*str == ',')
340 		return str + 1;
341 	if (*str == '\0')
342 		return str;
343 	MESSAGE(KERN_WARNING,
344 		"junk at end of dasd parameter string: %s\n", str);
345 	return ERR_PTR(-EINVAL);
346 }
347 
348 static char *
349 dasd_parse_next_element( char *parsestring ) {
350 	char * residual_str;
351 	residual_str = dasd_parse_keyword(parsestring);
352 	if (!IS_ERR(residual_str))
353 		return residual_str;
354 	residual_str = dasd_parse_range(parsestring);
355 	return residual_str;
356 }
357 
358 /*
359  * Parse parameters stored in dasd[]
360  * The 'dasd=...' parameter allows to specify a comma separated list of
361  * keywords and device ranges. When the dasd driver is build into the kernel,
362  * the complete list will be stored as one element of the dasd[] array.
363  * When the dasd driver is build as a module, then the list is broken into
364  * it's elements and each dasd[] entry contains one element.
365  */
366 int
367 dasd_parse(void)
368 {
369 	int rc, i;
370 	char *parsestring;
371 
372 	rc = 0;
373 	for (i = 0; i < 256; i++) {
374 		if (dasd[i] == NULL)
375 			break;
376 		parsestring = dasd[i];
377 		/* loop over the comma separated list in the parsestring */
378 		while (*parsestring) {
379 			parsestring = dasd_parse_next_element(parsestring);
380 			if(IS_ERR(parsestring)) {
381 				rc = PTR_ERR(parsestring);
382 				break;
383 			}
384 		}
385 		if (rc) {
386 			DBF_EVENT(DBF_ALERT, "%s", "invalid range found");
387 			break;
388 		}
389 	}
390 	return rc;
391 }
392 
393 /*
394  * Add a devmap for the device specified by busid. It is possible that
395  * the devmap already exists (dasd= parameter). The order of the devices
396  * added through this function will define the kdevs for the individual
397  * devices.
398  */
399 static struct dasd_devmap *
400 dasd_add_busid(const char *bus_id, int features)
401 {
402 	struct dasd_devmap *devmap, *new, *tmp;
403 	int hash;
404 
405 	new = (struct dasd_devmap *)
406 		kzalloc(sizeof(struct dasd_devmap), GFP_KERNEL);
407 	if (!new)
408 		return ERR_PTR(-ENOMEM);
409 	spin_lock(&dasd_devmap_lock);
410 	devmap = NULL;
411 	hash = dasd_hash_busid(bus_id);
412 	list_for_each_entry(tmp, &dasd_hashlists[hash], list)
413 		if (strncmp(tmp->bus_id, bus_id, DASD_BUS_ID_SIZE) == 0) {
414 			devmap = tmp;
415 			break;
416 		}
417 	if (!devmap) {
418 		/* This bus_id is new. */
419 		new->devindex = dasd_max_devindex++;
420 		strncpy(new->bus_id, bus_id, DASD_BUS_ID_SIZE);
421 		new->features = features;
422 		new->device = NULL;
423 		list_add(&new->list, &dasd_hashlists[hash]);
424 		devmap = new;
425 		new = NULL;
426 	}
427 	spin_unlock(&dasd_devmap_lock);
428 	kfree(new);
429 	return devmap;
430 }
431 
432 /*
433  * Find devmap for device with given bus_id.
434  */
435 static struct dasd_devmap *
436 dasd_find_busid(const char *bus_id)
437 {
438 	struct dasd_devmap *devmap, *tmp;
439 	int hash;
440 
441 	spin_lock(&dasd_devmap_lock);
442 	devmap = ERR_PTR(-ENODEV);
443 	hash = dasd_hash_busid(bus_id);
444 	list_for_each_entry(tmp, &dasd_hashlists[hash], list) {
445 		if (strncmp(tmp->bus_id, bus_id, DASD_BUS_ID_SIZE) == 0) {
446 			devmap = tmp;
447 			break;
448 		}
449 	}
450 	spin_unlock(&dasd_devmap_lock);
451 	return devmap;
452 }
453 
454 /*
455  * Check if busid has been added to the list of dasd ranges.
456  */
457 int
458 dasd_busid_known(const char *bus_id)
459 {
460 	return IS_ERR(dasd_find_busid(bus_id)) ? -ENOENT : 0;
461 }
462 
463 /*
464  * Forget all about the device numbers added so far.
465  * This may only be called at module unload or system shutdown.
466  */
467 static void
468 dasd_forget_ranges(void)
469 {
470 	struct dasd_devmap *devmap, *n;
471 	int i;
472 
473 	spin_lock(&dasd_devmap_lock);
474 	for (i = 0; i < 256; i++) {
475 		list_for_each_entry_safe(devmap, n, &dasd_hashlists[i], list) {
476 			BUG_ON(devmap->device != NULL);
477 			list_del(&devmap->list);
478 			kfree(devmap);
479 		}
480 	}
481 	spin_unlock(&dasd_devmap_lock);
482 }
483 
484 /*
485  * Find the device struct by its device index.
486  */
487 struct dasd_device *
488 dasd_device_from_devindex(int devindex)
489 {
490 	struct dasd_devmap *devmap, *tmp;
491 	struct dasd_device *device;
492 	int i;
493 
494 	spin_lock(&dasd_devmap_lock);
495 	devmap = NULL;
496 	for (i = 0; (i < 256) && !devmap; i++)
497 		list_for_each_entry(tmp, &dasd_hashlists[i], list)
498 			if (tmp->devindex == devindex) {
499 				/* Found the devmap for the device. */
500 				devmap = tmp;
501 				break;
502 			}
503 	if (devmap && devmap->device) {
504 		device = devmap->device;
505 		dasd_get_device(device);
506 	} else
507 		device = ERR_PTR(-ENODEV);
508 	spin_unlock(&dasd_devmap_lock);
509 	return device;
510 }
511 
512 /*
513  * Return devmap for cdev. If no devmap exists yet, create one and
514  * connect it to the cdev.
515  */
516 static struct dasd_devmap *
517 dasd_devmap_from_cdev(struct ccw_device *cdev)
518 {
519 	struct dasd_devmap *devmap;
520 
521 	devmap = dasd_find_busid(dev_name(&cdev->dev));
522 	if (IS_ERR(devmap))
523 		devmap = dasd_add_busid(dev_name(&cdev->dev),
524 					DASD_FEATURE_DEFAULT);
525 	return devmap;
526 }
527 
528 /*
529  * Create a dasd device structure for cdev.
530  */
531 struct dasd_device *
532 dasd_create_device(struct ccw_device *cdev)
533 {
534 	struct dasd_devmap *devmap;
535 	struct dasd_device *device;
536 	unsigned long flags;
537 	int rc;
538 
539 	devmap = dasd_devmap_from_cdev(cdev);
540 	if (IS_ERR(devmap))
541 		return (void *) devmap;
542 
543 	device = dasd_alloc_device();
544 	if (IS_ERR(device))
545 		return device;
546 	atomic_set(&device->ref_count, 3);
547 
548 	spin_lock(&dasd_devmap_lock);
549 	if (!devmap->device) {
550 		devmap->device = device;
551 		device->devindex = devmap->devindex;
552 		device->features = devmap->features;
553 		get_device(&cdev->dev);
554 		device->cdev = cdev;
555 		rc = 0;
556 	} else
557 		/* Someone else was faster. */
558 		rc = -EBUSY;
559 	spin_unlock(&dasd_devmap_lock);
560 
561 	if (rc) {
562 		dasd_free_device(device);
563 		return ERR_PTR(rc);
564 	}
565 
566 	spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
567 	dev_set_drvdata(&cdev->dev, device);
568 	spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
569 
570 	return device;
571 }
572 
573 /*
574  * Wait queue for dasd_delete_device waits.
575  */
576 static DECLARE_WAIT_QUEUE_HEAD(dasd_delete_wq);
577 
578 /*
579  * Remove a dasd device structure. The passed referenced
580  * is destroyed.
581  */
582 void
583 dasd_delete_device(struct dasd_device *device)
584 {
585 	struct ccw_device *cdev;
586 	struct dasd_devmap *devmap;
587 	unsigned long flags;
588 
589 	/* First remove device pointer from devmap. */
590 	devmap = dasd_find_busid(dev_name(&device->cdev->dev));
591 	BUG_ON(IS_ERR(devmap));
592 	spin_lock(&dasd_devmap_lock);
593 	if (devmap->device != device) {
594 		spin_unlock(&dasd_devmap_lock);
595 		dasd_put_device(device);
596 		return;
597 	}
598 	devmap->device = NULL;
599 	spin_unlock(&dasd_devmap_lock);
600 
601 	/* Disconnect dasd_device structure from ccw_device structure. */
602 	spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
603 	dev_set_drvdata(&device->cdev->dev, NULL);
604 	spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
605 
606 	/*
607 	 * Drop ref_count by 3, one for the devmap reference, one for
608 	 * the cdev reference and one for the passed reference.
609 	 */
610 	atomic_sub(3, &device->ref_count);
611 
612 	/* Wait for reference counter to drop to zero. */
613 	wait_event(dasd_delete_wq, atomic_read(&device->ref_count) == 0);
614 
615 	/* Disconnect dasd_device structure from ccw_device structure. */
616 	cdev = device->cdev;
617 	device->cdev = NULL;
618 
619 	/* Put ccw_device structure. */
620 	put_device(&cdev->dev);
621 
622 	/* Now the device structure can be freed. */
623 	dasd_free_device(device);
624 }
625 
626 /*
627  * Reference counter dropped to zero. Wake up waiter
628  * in dasd_delete_device.
629  */
630 void
631 dasd_put_device_wake(struct dasd_device *device)
632 {
633 	wake_up(&dasd_delete_wq);
634 }
635 
636 /*
637  * Return dasd_device structure associated with cdev.
638  * This function needs to be called with the ccw device
639  * lock held. It can be used from interrupt context.
640  */
641 struct dasd_device *
642 dasd_device_from_cdev_locked(struct ccw_device *cdev)
643 {
644 	struct dasd_device *device = dev_get_drvdata(&cdev->dev);
645 
646 	if (!device)
647 		return ERR_PTR(-ENODEV);
648 	dasd_get_device(device);
649 	return device;
650 }
651 
652 /*
653  * Return dasd_device structure associated with cdev.
654  */
655 struct dasd_device *
656 dasd_device_from_cdev(struct ccw_device *cdev)
657 {
658 	struct dasd_device *device;
659 	unsigned long flags;
660 
661 	spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
662 	device = dasd_device_from_cdev_locked(cdev);
663 	spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
664 	return device;
665 }
666 
667 /*
668  * SECTION: files in sysfs
669  */
670 
671 /*
672  * failfast controls the behaviour, if no path is available
673  */
674 static ssize_t dasd_ff_show(struct device *dev, struct device_attribute *attr,
675 			    char *buf)
676 {
677 	struct dasd_devmap *devmap;
678 	int ff_flag;
679 
680 	devmap = dasd_find_busid(dev_name(dev));
681 	if (!IS_ERR(devmap))
682 		ff_flag = (devmap->features & DASD_FEATURE_FAILFAST) != 0;
683 	else
684 		ff_flag = (DASD_FEATURE_DEFAULT & DASD_FEATURE_FAILFAST) != 0;
685 	return snprintf(buf, PAGE_SIZE, ff_flag ? "1\n" : "0\n");
686 }
687 
688 static ssize_t dasd_ff_store(struct device *dev, struct device_attribute *attr,
689 	      const char *buf, size_t count)
690 {
691 	struct dasd_devmap *devmap;
692 	int val;
693 	char *endp;
694 
695 	devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
696 	if (IS_ERR(devmap))
697 		return PTR_ERR(devmap);
698 
699 	val = simple_strtoul(buf, &endp, 0);
700 	if (((endp + 1) < (buf + count)) || (val > 1))
701 		return -EINVAL;
702 
703 	spin_lock(&dasd_devmap_lock);
704 	if (val)
705 		devmap->features |= DASD_FEATURE_FAILFAST;
706 	else
707 		devmap->features &= ~DASD_FEATURE_FAILFAST;
708 	if (devmap->device)
709 		devmap->device->features = devmap->features;
710 	spin_unlock(&dasd_devmap_lock);
711 	return count;
712 }
713 
714 static DEVICE_ATTR(failfast, 0644, dasd_ff_show, dasd_ff_store);
715 
716 /*
717  * readonly controls the readonly status of a dasd
718  */
719 static ssize_t
720 dasd_ro_show(struct device *dev, struct device_attribute *attr, char *buf)
721 {
722 	struct dasd_devmap *devmap;
723 	int ro_flag;
724 
725 	devmap = dasd_find_busid(dev_name(dev));
726 	if (!IS_ERR(devmap))
727 		ro_flag = (devmap->features & DASD_FEATURE_READONLY) != 0;
728 	else
729 		ro_flag = (DASD_FEATURE_DEFAULT & DASD_FEATURE_READONLY) != 0;
730 	return snprintf(buf, PAGE_SIZE, ro_flag ? "1\n" : "0\n");
731 }
732 
733 static ssize_t
734 dasd_ro_store(struct device *dev, struct device_attribute *attr,
735 	      const char *buf, size_t count)
736 {
737 	struct dasd_devmap *devmap;
738 	int val;
739 	char *endp;
740 
741 	devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
742 	if (IS_ERR(devmap))
743 		return PTR_ERR(devmap);
744 
745 	val = simple_strtoul(buf, &endp, 0);
746 	if (((endp + 1) < (buf + count)) || (val > 1))
747 		return -EINVAL;
748 
749 	spin_lock(&dasd_devmap_lock);
750 	if (val)
751 		devmap->features |= DASD_FEATURE_READONLY;
752 	else
753 		devmap->features &= ~DASD_FEATURE_READONLY;
754 	if (devmap->device)
755 		devmap->device->features = devmap->features;
756 	if (devmap->device && devmap->device->block
757 	    && devmap->device->block->gdp)
758 		set_disk_ro(devmap->device->block->gdp, val);
759 	spin_unlock(&dasd_devmap_lock);
760 	return count;
761 }
762 
763 static DEVICE_ATTR(readonly, 0644, dasd_ro_show, dasd_ro_store);
764 /*
765  * erplog controls the logging of ERP related data
766  * (e.g. failing channel programs).
767  */
768 static ssize_t
769 dasd_erplog_show(struct device *dev, struct device_attribute *attr, char *buf)
770 {
771 	struct dasd_devmap *devmap;
772 	int erplog;
773 
774 	devmap = dasd_find_busid(dev_name(dev));
775 	if (!IS_ERR(devmap))
776 		erplog = (devmap->features & DASD_FEATURE_ERPLOG) != 0;
777 	else
778 		erplog = (DASD_FEATURE_DEFAULT & DASD_FEATURE_ERPLOG) != 0;
779 	return snprintf(buf, PAGE_SIZE, erplog ? "1\n" : "0\n");
780 }
781 
782 static ssize_t
783 dasd_erplog_store(struct device *dev, struct device_attribute *attr,
784 	      const char *buf, size_t count)
785 {
786 	struct dasd_devmap *devmap;
787 	int val;
788 	char *endp;
789 
790 	devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
791 	if (IS_ERR(devmap))
792 		return PTR_ERR(devmap);
793 
794 	val = simple_strtoul(buf, &endp, 0);
795 	if (((endp + 1) < (buf + count)) || (val > 1))
796 		return -EINVAL;
797 
798 	spin_lock(&dasd_devmap_lock);
799 	if (val)
800 		devmap->features |= DASD_FEATURE_ERPLOG;
801 	else
802 		devmap->features &= ~DASD_FEATURE_ERPLOG;
803 	if (devmap->device)
804 		devmap->device->features = devmap->features;
805 	spin_unlock(&dasd_devmap_lock);
806 	return count;
807 }
808 
809 static DEVICE_ATTR(erplog, 0644, dasd_erplog_show, dasd_erplog_store);
810 
811 /*
812  * use_diag controls whether the driver should use diag rather than ssch
813  * to talk to the device
814  */
815 static ssize_t
816 dasd_use_diag_show(struct device *dev, struct device_attribute *attr, char *buf)
817 {
818 	struct dasd_devmap *devmap;
819 	int use_diag;
820 
821 	devmap = dasd_find_busid(dev_name(dev));
822 	if (!IS_ERR(devmap))
823 		use_diag = (devmap->features & DASD_FEATURE_USEDIAG) != 0;
824 	else
825 		use_diag = (DASD_FEATURE_DEFAULT & DASD_FEATURE_USEDIAG) != 0;
826 	return sprintf(buf, use_diag ? "1\n" : "0\n");
827 }
828 
829 static ssize_t
830 dasd_use_diag_store(struct device *dev, struct device_attribute *attr,
831 		    const char *buf, size_t count)
832 {
833 	struct dasd_devmap *devmap;
834 	ssize_t rc;
835 	int val;
836 	char *endp;
837 
838 	devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
839 	if (IS_ERR(devmap))
840 		return PTR_ERR(devmap);
841 
842 	val = simple_strtoul(buf, &endp, 0);
843 	if (((endp + 1) < (buf + count)) || (val > 1))
844 		return -EINVAL;
845 
846 	spin_lock(&dasd_devmap_lock);
847 	/* Changing diag discipline flag is only allowed in offline state. */
848 	rc = count;
849 	if (!devmap->device) {
850 		if (val)
851 			devmap->features |= DASD_FEATURE_USEDIAG;
852 		else
853 			devmap->features &= ~DASD_FEATURE_USEDIAG;
854 	} else
855 		rc = -EPERM;
856 	spin_unlock(&dasd_devmap_lock);
857 	return rc;
858 }
859 
860 static DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store);
861 
862 static ssize_t
863 dasd_discipline_show(struct device *dev, struct device_attribute *attr,
864 		     char *buf)
865 {
866 	struct dasd_device *device;
867 	ssize_t len;
868 
869 	device = dasd_device_from_cdev(to_ccwdev(dev));
870 	if (!IS_ERR(device) && device->discipline) {
871 		len = snprintf(buf, PAGE_SIZE, "%s\n",
872 			       device->discipline->name);
873 		dasd_put_device(device);
874 	} else
875 		len = snprintf(buf, PAGE_SIZE, "none\n");
876 	return len;
877 }
878 
879 static DEVICE_ATTR(discipline, 0444, dasd_discipline_show, NULL);
880 
881 static ssize_t
882 dasd_device_status_show(struct device *dev, struct device_attribute *attr,
883 		     char *buf)
884 {
885 	struct dasd_device *device;
886 	ssize_t len;
887 
888 	device = dasd_device_from_cdev(to_ccwdev(dev));
889 	if (!IS_ERR(device)) {
890 		switch (device->state) {
891 		case DASD_STATE_NEW:
892 			len = snprintf(buf, PAGE_SIZE, "new\n");
893 			break;
894 		case DASD_STATE_KNOWN:
895 			len = snprintf(buf, PAGE_SIZE, "detected\n");
896 			break;
897 		case DASD_STATE_BASIC:
898 			len = snprintf(buf, PAGE_SIZE, "basic\n");
899 			break;
900 		case DASD_STATE_UNFMT:
901 			len = snprintf(buf, PAGE_SIZE, "unformatted\n");
902 			break;
903 		case DASD_STATE_READY:
904 			len = snprintf(buf, PAGE_SIZE, "ready\n");
905 			break;
906 		case DASD_STATE_ONLINE:
907 			len = snprintf(buf, PAGE_SIZE, "online\n");
908 			break;
909 		default:
910 			len = snprintf(buf, PAGE_SIZE, "no stat\n");
911 			break;
912 		}
913 		dasd_put_device(device);
914 	} else
915 		len = snprintf(buf, PAGE_SIZE, "unknown\n");
916 	return len;
917 }
918 
919 static DEVICE_ATTR(status, 0444, dasd_device_status_show, NULL);
920 
921 static ssize_t
922 dasd_alias_show(struct device *dev, struct device_attribute *attr, char *buf)
923 {
924 	struct dasd_devmap *devmap;
925 	int alias;
926 
927 	devmap = dasd_find_busid(dev_name(dev));
928 	spin_lock(&dasd_devmap_lock);
929 	if (IS_ERR(devmap) || strlen(devmap->uid.vendor) == 0) {
930 		spin_unlock(&dasd_devmap_lock);
931 		return sprintf(buf, "0\n");
932 	}
933 	if (devmap->uid.type == UA_BASE_PAV_ALIAS ||
934 	    devmap->uid.type == UA_HYPER_PAV_ALIAS)
935 		alias = 1;
936 	else
937 		alias = 0;
938 	spin_unlock(&dasd_devmap_lock);
939 	return sprintf(buf, alias ? "1\n" : "0\n");
940 }
941 
942 static DEVICE_ATTR(alias, 0444, dasd_alias_show, NULL);
943 
944 static ssize_t
945 dasd_vendor_show(struct device *dev, struct device_attribute *attr, char *buf)
946 {
947 	struct dasd_devmap *devmap;
948 	char *vendor;
949 
950 	devmap = dasd_find_busid(dev_name(dev));
951 	spin_lock(&dasd_devmap_lock);
952 	if (!IS_ERR(devmap) && strlen(devmap->uid.vendor) > 0)
953 		vendor = devmap->uid.vendor;
954 	else
955 		vendor = "";
956 	spin_unlock(&dasd_devmap_lock);
957 
958 	return snprintf(buf, PAGE_SIZE, "%s\n", vendor);
959 }
960 
961 static DEVICE_ATTR(vendor, 0444, dasd_vendor_show, NULL);
962 
963 #define UID_STRLEN ( /* vendor */ 3 + 1 + /* serial    */ 14 + 1 +\
964 		     /* SSID   */ 4 + 1 + /* unit addr */ 2 + 1 +\
965 		     /* vduit */ 32 + 1)
966 
967 static ssize_t
968 dasd_uid_show(struct device *dev, struct device_attribute *attr, char *buf)
969 {
970 	struct dasd_devmap *devmap;
971 	char uid_string[UID_STRLEN];
972 	char ua_string[3];
973 	struct dasd_uid *uid;
974 
975 	devmap = dasd_find_busid(dev_name(dev));
976 	spin_lock(&dasd_devmap_lock);
977 	if (IS_ERR(devmap) || strlen(devmap->uid.vendor) == 0) {
978 		spin_unlock(&dasd_devmap_lock);
979 		return sprintf(buf, "\n");
980 	}
981 	uid = &devmap->uid;
982 	switch (uid->type) {
983 	case UA_BASE_DEVICE:
984 		sprintf(ua_string, "%02x", uid->real_unit_addr);
985 		break;
986 	case UA_BASE_PAV_ALIAS:
987 		sprintf(ua_string, "%02x", uid->base_unit_addr);
988 		break;
989 	case UA_HYPER_PAV_ALIAS:
990 		sprintf(ua_string, "xx");
991 		break;
992 	default:
993 		/* should not happen, treat like base device */
994 		sprintf(ua_string, "%02x", uid->real_unit_addr);
995 		break;
996 	}
997 	if (strlen(uid->vduit) > 0)
998 		snprintf(uid_string, sizeof(uid_string),
999 			 "%s.%s.%04x.%s.%s",
1000 			 uid->vendor, uid->serial,
1001 			 uid->ssid, ua_string,
1002 			 uid->vduit);
1003 	else
1004 		snprintf(uid_string, sizeof(uid_string),
1005 			 "%s.%s.%04x.%s",
1006 			 uid->vendor, uid->serial,
1007 			 uid->ssid, ua_string);
1008 	spin_unlock(&dasd_devmap_lock);
1009 	return snprintf(buf, PAGE_SIZE, "%s\n", uid_string);
1010 }
1011 
1012 static DEVICE_ATTR(uid, 0444, dasd_uid_show, NULL);
1013 
1014 /*
1015  * extended error-reporting
1016  */
1017 static ssize_t
1018 dasd_eer_show(struct device *dev, struct device_attribute *attr, char *buf)
1019 {
1020 	struct dasd_devmap *devmap;
1021 	int eer_flag;
1022 
1023 	devmap = dasd_find_busid(dev_name(dev));
1024 	if (!IS_ERR(devmap) && devmap->device)
1025 		eer_flag = dasd_eer_enabled(devmap->device);
1026 	else
1027 		eer_flag = 0;
1028 	return snprintf(buf, PAGE_SIZE, eer_flag ? "1\n" : "0\n");
1029 }
1030 
1031 static ssize_t
1032 dasd_eer_store(struct device *dev, struct device_attribute *attr,
1033 	       const char *buf, size_t count)
1034 {
1035 	struct dasd_devmap *devmap;
1036 	int val, rc;
1037 	char *endp;
1038 
1039 	devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
1040 	if (IS_ERR(devmap))
1041 		return PTR_ERR(devmap);
1042 	if (!devmap->device)
1043 		return -ENODEV;
1044 
1045 	val = simple_strtoul(buf, &endp, 0);
1046 	if (((endp + 1) < (buf + count)) || (val > 1))
1047 		return -EINVAL;
1048 
1049 	if (val) {
1050 		rc = dasd_eer_enable(devmap->device);
1051 		if (rc)
1052 			return rc;
1053 	} else
1054 		dasd_eer_disable(devmap->device);
1055 	return count;
1056 }
1057 
1058 static DEVICE_ATTR(eer_enabled, 0644, dasd_eer_show, dasd_eer_store);
1059 
1060 static struct attribute * dasd_attrs[] = {
1061 	&dev_attr_readonly.attr,
1062 	&dev_attr_discipline.attr,
1063 	&dev_attr_status.attr,
1064 	&dev_attr_alias.attr,
1065 	&dev_attr_vendor.attr,
1066 	&dev_attr_uid.attr,
1067 	&dev_attr_use_diag.attr,
1068 	&dev_attr_eer_enabled.attr,
1069 	&dev_attr_erplog.attr,
1070 	&dev_attr_failfast.attr,
1071 	NULL,
1072 };
1073 
1074 static struct attribute_group dasd_attr_group = {
1075 	.attrs = dasd_attrs,
1076 };
1077 
1078 /*
1079  * Return copy of the device unique identifier.
1080  */
1081 int
1082 dasd_get_uid(struct ccw_device *cdev, struct dasd_uid *uid)
1083 {
1084 	struct dasd_devmap *devmap;
1085 
1086 	devmap = dasd_find_busid(dev_name(&cdev->dev));
1087 	if (IS_ERR(devmap))
1088 		return PTR_ERR(devmap);
1089 	spin_lock(&dasd_devmap_lock);
1090 	*uid = devmap->uid;
1091 	spin_unlock(&dasd_devmap_lock);
1092 	return 0;
1093 }
1094 
1095 /*
1096  * Register the given device unique identifier into devmap struct.
1097  * In addition check if the related storage server subsystem ID is already
1098  * contained in the dasd_server_ssid_list. If subsystem ID is not contained,
1099  * create new entry.
1100  * Return 0 if server was already in serverlist,
1101  *	  1 if the server was added successful
1102  *	 <0 in case of error.
1103  */
1104 int
1105 dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid)
1106 {
1107 	struct dasd_devmap *devmap;
1108 
1109 	devmap = dasd_find_busid(dev_name(&cdev->dev));
1110 	if (IS_ERR(devmap))
1111 		return PTR_ERR(devmap);
1112 
1113 	spin_lock(&dasd_devmap_lock);
1114 	devmap->uid = *uid;
1115 	spin_unlock(&dasd_devmap_lock);
1116 
1117 	return 0;
1118 }
1119 EXPORT_SYMBOL_GPL(dasd_set_uid);
1120 
1121 /*
1122  * Return value of the specified feature.
1123  */
1124 int
1125 dasd_get_feature(struct ccw_device *cdev, int feature)
1126 {
1127 	struct dasd_devmap *devmap;
1128 
1129 	devmap = dasd_find_busid(dev_name(&cdev->dev));
1130 	if (IS_ERR(devmap))
1131 		return PTR_ERR(devmap);
1132 
1133 	return ((devmap->features & feature) != 0);
1134 }
1135 
1136 /*
1137  * Set / reset given feature.
1138  * Flag indicates wether to set (!=0) or the reset (=0) the feature.
1139  */
1140 int
1141 dasd_set_feature(struct ccw_device *cdev, int feature, int flag)
1142 {
1143 	struct dasd_devmap *devmap;
1144 
1145 	devmap = dasd_find_busid(dev_name(&cdev->dev));
1146 	if (IS_ERR(devmap))
1147 		return PTR_ERR(devmap);
1148 
1149 	spin_lock(&dasd_devmap_lock);
1150 	if (flag)
1151 		devmap->features |= feature;
1152 	else
1153 		devmap->features &= ~feature;
1154 	if (devmap->device)
1155 		devmap->device->features = devmap->features;
1156 	spin_unlock(&dasd_devmap_lock);
1157 	return 0;
1158 }
1159 
1160 
1161 int
1162 dasd_add_sysfs_files(struct ccw_device *cdev)
1163 {
1164 	return sysfs_create_group(&cdev->dev.kobj, &dasd_attr_group);
1165 }
1166 
1167 void
1168 dasd_remove_sysfs_files(struct ccw_device *cdev)
1169 {
1170 	sysfs_remove_group(&cdev->dev.kobj, &dasd_attr_group);
1171 }
1172 
1173 
1174 int
1175 dasd_devmap_init(void)
1176 {
1177 	int i;
1178 
1179 	/* Initialize devmap structures. */
1180 	dasd_max_devindex = 0;
1181 	for (i = 0; i < 256; i++)
1182 		INIT_LIST_HEAD(&dasd_hashlists[i]);
1183 	return 0;
1184 }
1185 
1186 void
1187 dasd_devmap_exit(void)
1188 {
1189 	dasd_forget_ranges();
1190 }
1191