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