[S390] dasd deadlock after state change pending interrupt.
[linux-2.6.git] / drivers / s390 / block / dasd_devmap.c
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 kmem_cache_t *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                 dasd_nopav = 1;
262                 MESSAGE(KERN_INFO, "%s", "disable PAV mode");
263                 return residual_str;
264         }
265         if (strncmp("fixedbuffers", parsestring, length) == 0) {
266                 if (dasd_page_cache)
267                         return residual_str;
268                 dasd_page_cache =
269                         kmem_cache_create("dasd_page_cache", PAGE_SIZE,
270                                           PAGE_SIZE, SLAB_CACHE_DMA,
271                                           NULL, NULL );
272                 if (!dasd_page_cache)
273                         MESSAGE(KERN_WARNING, "%s", "Failed to create slab, "
274                                 "fixed buffer mode disabled.");
275                 else
276                         MESSAGE (KERN_INFO, "%s",
277                                  "turning on fixed buffer mode");
278                 return residual_str;
279         }
280         return ERR_PTR(-EINVAL);
281 }
282
283 /*
284  * Try to interprete the first element on the comma separated parse string
285  * as a device number or a range of devices. If the interpretation is
286  * successfull, create the matching dasd_devmap entries and return a pointer
287  * to the residual string.
288  * If interpretation fails or in case of an error, return an error code.
289  */
290 static char *
291 dasd_parse_range( char *parsestring ) {
292
293         struct dasd_devmap *devmap;
294         int from, from_id0, from_id1;
295         int to, to_id0, to_id1;
296         int features, rc;
297         char bus_id[BUS_ID_SIZE+1], *str;
298
299         str = parsestring;
300         rc = dasd_busid(&str, &from_id0, &from_id1, &from);
301         if (rc == 0) {
302                 to = from;
303                 to_id0 = from_id0;
304                 to_id1 = from_id1;
305                 if (*str == '-') {
306                         str++;
307                         rc = dasd_busid(&str, &to_id0, &to_id1, &to);
308                 }
309         }
310         if (rc == 0 &&
311             (from_id0 != to_id0 || from_id1 != to_id1 || from > to))
312                 rc = -EINVAL;
313         if (rc) {
314                 MESSAGE(KERN_ERR, "Invalid device range %s", parsestring);
315                 return ERR_PTR(rc);
316         }
317         features = dasd_feature_list(str, &str);
318         if (features < 0)
319                 return ERR_PTR(-EINVAL);
320         /* each device in dasd= parameter should be set initially online */
321         features |= DASD_FEATURE_INITIAL_ONLINE;
322         while (from <= to) {
323                 sprintf(bus_id, "%01x.%01x.%04x",
324                         from_id0, from_id1, from++);
325                 devmap = dasd_add_busid(bus_id, features);
326                 if (IS_ERR(devmap))
327                         return (char *)devmap;
328         }
329         if (*str == ',')
330                 return str + 1;
331         if (*str == '\0')
332                 return str;
333         MESSAGE(KERN_WARNING,
334                 "junk at end of dasd parameter string: %s\n", str);
335         return ERR_PTR(-EINVAL);
336 }
337
338 static inline char *
339 dasd_parse_next_element( char *parsestring ) {
340         char * residual_str;
341         residual_str = dasd_parse_keyword(parsestring);
342         if (!IS_ERR(residual_str))
343                 return residual_str;
344         residual_str = dasd_parse_range(parsestring);
345         return residual_str;
346 }
347
348 /*
349  * Parse parameters stored in dasd[]
350  * The 'dasd=...' parameter allows to specify a comma separated list of
351  * keywords and device ranges. When the dasd driver is build into the kernel,
352  * the complete list will be stored as one element of the dasd[] array.
353  * When the dasd driver is build as a module, then the list is broken into
354  * it's elements and each dasd[] entry contains one element.
355  */
356 int
357 dasd_parse(void)
358 {
359         int rc, i;
360         char *parsestring;
361
362         rc = 0;
363         for (i = 0; i < 256; i++) {
364                 if (dasd[i] == NULL)
365                         break;
366                 parsestring = dasd[i];
367                 /* loop over the comma separated list in the parsestring */
368                 while (*parsestring) {
369                         parsestring = dasd_parse_next_element(parsestring);
370                         if(IS_ERR(parsestring)) {
371                                 rc = PTR_ERR(parsestring);
372                                 break;
373                         }
374                 }
375                 if (rc) {
376                         DBF_EVENT(DBF_ALERT, "%s", "invalid range found");
377                         break;
378                 }
379         }
380         return rc;
381 }
382
383 /*
384  * Add a devmap for the device specified by busid. It is possible that
385  * the devmap already exists (dasd= parameter). The order of the devices
386  * added through this function will define the kdevs for the individual
387  * devices.
388  */
389 static struct dasd_devmap *
390 dasd_add_busid(char *bus_id, int features)
391 {
392         struct dasd_devmap *devmap, *new, *tmp;
393         int hash;
394
395         new = (struct dasd_devmap *)
396                 kzalloc(sizeof(struct dasd_devmap), GFP_KERNEL);
397         if (!new)
398                 return ERR_PTR(-ENOMEM);
399         spin_lock(&dasd_devmap_lock);
400         devmap = NULL;
401         hash = dasd_hash_busid(bus_id);
402         list_for_each_entry(tmp, &dasd_hashlists[hash], list)
403                 if (strncmp(tmp->bus_id, bus_id, BUS_ID_SIZE) == 0) {
404                         devmap = tmp;
405                         break;
406                 }
407         if (!devmap) {
408                 /* This bus_id is new. */
409                 new->devindex = dasd_max_devindex++;
410                 strncpy(new->bus_id, bus_id, BUS_ID_SIZE);
411                 new->features = features;
412                 new->device = NULL;
413                 list_add(&new->list, &dasd_hashlists[hash]);
414                 devmap = new;
415                 new = NULL;
416         }
417         spin_unlock(&dasd_devmap_lock);
418         kfree(new);
419         return devmap;
420 }
421
422 /*
423  * Find devmap for device with given bus_id.
424  */
425 static struct dasd_devmap *
426 dasd_find_busid(char *bus_id)
427 {
428         struct dasd_devmap *devmap, *tmp;
429         int hash;
430
431         spin_lock(&dasd_devmap_lock);
432         devmap = ERR_PTR(-ENODEV);
433         hash = dasd_hash_busid(bus_id);
434         list_for_each_entry(tmp, &dasd_hashlists[hash], list) {
435                 if (strncmp(tmp->bus_id, bus_id, BUS_ID_SIZE) == 0) {
436                         devmap = tmp;
437                         break;
438                 }
439         }
440         spin_unlock(&dasd_devmap_lock);
441         return devmap;
442 }
443
444 /*
445  * Check if busid has been added to the list of dasd ranges.
446  */
447 int
448 dasd_busid_known(char *bus_id)
449 {
450         return IS_ERR(dasd_find_busid(bus_id)) ? -ENOENT : 0;
451 }
452
453 /*
454  * Forget all about the device numbers added so far.
455  * This may only be called at module unload or system shutdown.
456  */
457 static void
458 dasd_forget_ranges(void)
459 {
460         struct dasd_devmap *devmap, *n;
461         int i;
462
463         spin_lock(&dasd_devmap_lock);
464         for (i = 0; i < 256; i++) {
465                 list_for_each_entry_safe(devmap, n, &dasd_hashlists[i], list) {
466                         BUG_ON(devmap->device != NULL);
467                         list_del(&devmap->list);
468                         kfree(devmap);
469                 }
470         }
471         spin_unlock(&dasd_devmap_lock);
472 }
473
474 /*
475  * Find the device struct by its device index.
476  */
477 struct dasd_device *
478 dasd_device_from_devindex(int devindex)
479 {
480         struct dasd_devmap *devmap, *tmp;
481         struct dasd_device *device;
482         int i;
483
484         spin_lock(&dasd_devmap_lock);
485         devmap = NULL;
486         for (i = 0; (i < 256) && !devmap; i++)
487                 list_for_each_entry(tmp, &dasd_hashlists[i], list)
488                         if (tmp->devindex == devindex) {
489                                 /* Found the devmap for the device. */
490                                 devmap = tmp;
491                                 break;
492                         }
493         if (devmap && devmap->device) {
494                 device = devmap->device;
495                 dasd_get_device(device);
496         } else
497                 device = ERR_PTR(-ENODEV);
498         spin_unlock(&dasd_devmap_lock);
499         return device;
500 }
501
502 /*
503  * Return devmap for cdev. If no devmap exists yet, create one and
504  * connect it to the cdev.
505  */
506 static struct dasd_devmap *
507 dasd_devmap_from_cdev(struct ccw_device *cdev)
508 {
509         struct dasd_devmap *devmap;
510
511         devmap = dasd_find_busid(cdev->dev.bus_id);
512         if (IS_ERR(devmap))
513                 devmap = dasd_add_busid(cdev->dev.bus_id,
514                                         DASD_FEATURE_DEFAULT);
515         return devmap;
516 }
517
518 /*
519  * Create a dasd device structure for cdev.
520  */
521 struct dasd_device *
522 dasd_create_device(struct ccw_device *cdev)
523 {
524         struct dasd_devmap *devmap;
525         struct dasd_device *device;
526         unsigned long flags;
527         int rc;
528
529         devmap = dasd_devmap_from_cdev(cdev);
530         if (IS_ERR(devmap))
531                 return (void *) devmap;
532
533         device = dasd_alloc_device();
534         if (IS_ERR(device))
535                 return device;
536         atomic_set(&device->ref_count, 3);
537
538         spin_lock(&dasd_devmap_lock);
539         if (!devmap->device) {
540                 devmap->device = device;
541                 device->devindex = devmap->devindex;
542                 device->features = devmap->features;
543                 get_device(&cdev->dev);
544                 device->cdev = cdev;
545                 rc = 0;
546         } else
547                 /* Someone else was faster. */
548                 rc = -EBUSY;
549         spin_unlock(&dasd_devmap_lock);
550
551         if (rc) {
552                 dasd_free_device(device);
553                 return ERR_PTR(rc);
554         }
555
556         spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
557         cdev->dev.driver_data = device;
558         spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
559
560         return device;
561 }
562
563 /*
564  * Wait queue for dasd_delete_device waits.
565  */
566 static DECLARE_WAIT_QUEUE_HEAD(dasd_delete_wq);
567
568 /*
569  * Remove a dasd device structure. The passed referenced
570  * is destroyed.
571  */
572 void
573 dasd_delete_device(struct dasd_device *device)
574 {
575         struct ccw_device *cdev;
576         struct dasd_devmap *devmap;
577         unsigned long flags;
578
579         /* First remove device pointer from devmap. */
580         devmap = dasd_find_busid(device->cdev->dev.bus_id);
581         BUG_ON(IS_ERR(devmap));
582         spin_lock(&dasd_devmap_lock);
583         if (devmap->device != device) {
584                 spin_unlock(&dasd_devmap_lock);
585                 dasd_put_device(device);
586                 return;
587         }
588         devmap->device = NULL;
589         spin_unlock(&dasd_devmap_lock);
590
591         /* Disconnect dasd_device structure from ccw_device structure. */
592         spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
593         device->cdev->dev.driver_data = NULL;
594         spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
595
596         /*
597          * Drop ref_count by 3, one for the devmap reference, one for
598          * the cdev reference and one for the passed reference.
599          */
600         atomic_sub(3, &device->ref_count);
601
602         /* Wait for reference counter to drop to zero. */
603         wait_event(dasd_delete_wq, atomic_read(&device->ref_count) == 0);
604
605         /* Disconnect dasd_device structure from ccw_device structure. */
606         cdev = device->cdev;
607         device->cdev = NULL;
608
609         /* Put ccw_device structure. */
610         put_device(&cdev->dev);
611
612         /* Now the device structure can be freed. */
613         dasd_free_device(device);
614 }
615
616 /*
617  * Reference counter dropped to zero. Wake up waiter
618  * in dasd_delete_device.
619  */
620 void
621 dasd_put_device_wake(struct dasd_device *device)
622 {
623         wake_up(&dasd_delete_wq);
624 }
625
626 /*
627  * Return dasd_device structure associated with cdev.
628  * This function needs to be called with the ccw device
629  * lock held. It can be used from interrupt context.
630  */
631 struct dasd_device *
632 dasd_device_from_cdev_locked(struct ccw_device *cdev)
633 {
634         struct dasd_device *device = cdev->dev.driver_data;
635
636         if (!device)
637                 return ERR_PTR(-ENODEV);
638         dasd_get_device(device);
639         return device;
640 }
641
642 /*
643  * Return dasd_device structure associated with cdev.
644  */
645 struct dasd_device *
646 dasd_device_from_cdev(struct ccw_device *cdev)
647 {
648         struct dasd_device *device;
649         unsigned long flags;
650
651         spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
652         device = dasd_device_from_cdev_locked(cdev);
653         spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
654         return device;
655 }
656
657 /*
658  * SECTION: files in sysfs
659  */
660
661 /*
662  * readonly controls the readonly status of a dasd
663  */
664 static ssize_t
665 dasd_ro_show(struct device *dev, struct device_attribute *attr, char *buf)
666 {
667         struct dasd_devmap *devmap;
668         int ro_flag;
669
670         devmap = dasd_find_busid(dev->bus_id);
671         if (!IS_ERR(devmap))
672                 ro_flag = (devmap->features & DASD_FEATURE_READONLY) != 0;
673         else
674                 ro_flag = (DASD_FEATURE_DEFAULT & DASD_FEATURE_READONLY) != 0;
675         return snprintf(buf, PAGE_SIZE, ro_flag ? "1\n" : "0\n");
676 }
677
678 static ssize_t
679 dasd_ro_store(struct device *dev, struct device_attribute *attr,
680               const char *buf, size_t count)
681 {
682         struct dasd_devmap *devmap;
683         int ro_flag;
684
685         devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
686         if (IS_ERR(devmap))
687                 return PTR_ERR(devmap);
688         ro_flag = buf[0] == '1';
689         spin_lock(&dasd_devmap_lock);
690         if (ro_flag)
691                 devmap->features |= DASD_FEATURE_READONLY;
692         else
693                 devmap->features &= ~DASD_FEATURE_READONLY;
694         if (devmap->device)
695                 devmap->device->features = devmap->features;
696         if (devmap->device && devmap->device->gdp)
697                 set_disk_ro(devmap->device->gdp, ro_flag);
698         spin_unlock(&dasd_devmap_lock);
699         return count;
700 }
701
702 static DEVICE_ATTR(readonly, 0644, dasd_ro_show, dasd_ro_store);
703
704 /*
705  * use_diag controls whether the driver should use diag rather than ssch
706  * to talk to the device
707  */
708 static ssize_t
709 dasd_use_diag_show(struct device *dev, struct device_attribute *attr, char *buf)
710 {
711         struct dasd_devmap *devmap;
712         int use_diag;
713
714         devmap = dasd_find_busid(dev->bus_id);
715         if (!IS_ERR(devmap))
716                 use_diag = (devmap->features & DASD_FEATURE_USEDIAG) != 0;
717         else
718                 use_diag = (DASD_FEATURE_DEFAULT & DASD_FEATURE_USEDIAG) != 0;
719         return sprintf(buf, use_diag ? "1\n" : "0\n");
720 }
721
722 static ssize_t
723 dasd_use_diag_store(struct device *dev, struct device_attribute *attr,
724                     const char *buf, size_t count)
725 {
726         struct dasd_devmap *devmap;
727         ssize_t rc;
728         int use_diag;
729
730         devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
731         if (IS_ERR(devmap))
732                 return PTR_ERR(devmap);
733         use_diag = buf[0] == '1';
734         spin_lock(&dasd_devmap_lock);
735         /* Changing diag discipline flag is only allowed in offline state. */
736         rc = count;
737         if (!devmap->device) {
738                 if (use_diag)
739                         devmap->features |= DASD_FEATURE_USEDIAG;
740                 else
741                         devmap->features &= ~DASD_FEATURE_USEDIAG;
742         } else
743                 rc = -EPERM;
744         spin_unlock(&dasd_devmap_lock);
745         return rc;
746 }
747
748 static DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store);
749
750 static ssize_t
751 dasd_discipline_show(struct device *dev, struct device_attribute *attr,
752                      char *buf)
753 {
754         struct dasd_device *device;
755         ssize_t len;
756
757         device = dasd_device_from_cdev(to_ccwdev(dev));
758         if (!IS_ERR(device) && device->discipline) {
759                 len = snprintf(buf, PAGE_SIZE, "%s\n",
760                                device->discipline->name);
761                 dasd_put_device(device);
762         } else
763                 len = snprintf(buf, PAGE_SIZE, "none\n");
764         return len;
765 }
766
767 static DEVICE_ATTR(discipline, 0444, dasd_discipline_show, NULL);
768
769 static ssize_t
770 dasd_alias_show(struct device *dev, struct device_attribute *attr, char *buf)
771 {
772         struct dasd_devmap *devmap;
773         int alias;
774
775         devmap = dasd_find_busid(dev->bus_id);
776         spin_lock(&dasd_devmap_lock);
777         if (!IS_ERR(devmap))
778                 alias = devmap->uid.alias;
779         else
780                 alias = 0;
781         spin_unlock(&dasd_devmap_lock);
782
783         return sprintf(buf, alias ? "1\n" : "0\n");
784 }
785
786 static DEVICE_ATTR(alias, 0444, dasd_alias_show, NULL);
787
788 static ssize_t
789 dasd_vendor_show(struct device *dev, struct device_attribute *attr, char *buf)
790 {
791         struct dasd_devmap *devmap;
792         char *vendor;
793
794         devmap = dasd_find_busid(dev->bus_id);
795         spin_lock(&dasd_devmap_lock);
796         if (!IS_ERR(devmap) && strlen(devmap->uid.vendor) > 0)
797                 vendor = devmap->uid.vendor;
798         else
799                 vendor = "";
800         spin_unlock(&dasd_devmap_lock);
801
802         return snprintf(buf, PAGE_SIZE, "%s\n", vendor);
803 }
804
805 static DEVICE_ATTR(vendor, 0444, dasd_vendor_show, NULL);
806
807 #define UID_STRLEN ( /* vendor */ 3 + 1 + /* serial    */ 14 + 1 +\
808                      /* SSID   */ 4 + 1 + /* unit addr */ 2 + 1)
809
810 static ssize_t
811 dasd_uid_show(struct device *dev, struct device_attribute *attr, char *buf)
812 {
813         struct dasd_devmap *devmap;
814         char uid[UID_STRLEN];
815
816         devmap = dasd_find_busid(dev->bus_id);
817         spin_lock(&dasd_devmap_lock);
818         if (!IS_ERR(devmap) && strlen(devmap->uid.vendor) > 0)
819                 snprintf(uid, sizeof(uid), "%s.%s.%04x.%02x",
820                          devmap->uid.vendor, devmap->uid.serial,
821                          devmap->uid.ssid, devmap->uid.unit_addr);
822         else
823                 uid[0] = 0;
824         spin_unlock(&dasd_devmap_lock);
825
826         return snprintf(buf, PAGE_SIZE, "%s\n", uid);
827 }
828
829 static DEVICE_ATTR(uid, 0444, dasd_uid_show, NULL);
830
831 /*
832  * extended error-reporting
833  */
834 static ssize_t
835 dasd_eer_show(struct device *dev, struct device_attribute *attr, char *buf)
836 {
837         struct dasd_devmap *devmap;
838         int eer_flag;
839
840         devmap = dasd_find_busid(dev->bus_id);
841         if (!IS_ERR(devmap) && devmap->device)
842                 eer_flag = dasd_eer_enabled(devmap->device);
843         else
844                 eer_flag = 0;
845         return snprintf(buf, PAGE_SIZE, eer_flag ? "1\n" : "0\n");
846 }
847
848 static ssize_t
849 dasd_eer_store(struct device *dev, struct device_attribute *attr,
850                const char *buf, size_t count)
851 {
852         struct dasd_devmap *devmap;
853         int rc;
854
855         devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
856         if (IS_ERR(devmap))
857                 return PTR_ERR(devmap);
858         if (!devmap->device)
859                 return count;
860         if (buf[0] == '1') {
861                 rc = dasd_eer_enable(devmap->device);
862                 if (rc)
863                         return rc;
864         } else
865                 dasd_eer_disable(devmap->device);
866         return count;
867 }
868
869 static DEVICE_ATTR(eer_enabled, 0644, dasd_eer_show, dasd_eer_store);
870
871 static struct attribute * dasd_attrs[] = {
872         &dev_attr_readonly.attr,
873         &dev_attr_discipline.attr,
874         &dev_attr_alias.attr,
875         &dev_attr_vendor.attr,
876         &dev_attr_uid.attr,
877         &dev_attr_use_diag.attr,
878         &dev_attr_eer_enabled.attr,
879         NULL,
880 };
881
882 static struct attribute_group dasd_attr_group = {
883         .attrs = dasd_attrs,
884 };
885
886 /*
887  * Return copy of the device unique identifier.
888  */
889 int
890 dasd_get_uid(struct ccw_device *cdev, struct dasd_uid *uid)
891 {
892         struct dasd_devmap *devmap;
893
894         devmap = dasd_find_busid(cdev->dev.bus_id);
895         if (IS_ERR(devmap))
896                 return PTR_ERR(devmap);
897         spin_lock(&dasd_devmap_lock);
898         *uid = devmap->uid;
899         spin_unlock(&dasd_devmap_lock);
900         return 0;
901 }
902
903 /*
904  * Register the given device unique identifier into devmap struct.
905  * In addition check if the related storage server subsystem ID is already
906  * contained in the dasd_server_ssid_list. If subsystem ID is not contained,
907  * create new entry.
908  * Return 0 if server was already in serverlist,
909  *        1 if the server was added successful
910  *       <0 in case of error.
911  */
912 int
913 dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid)
914 {
915         struct dasd_devmap *devmap;
916         struct dasd_server_ssid_map *srv, *tmp;
917
918         devmap = dasd_find_busid(cdev->dev.bus_id);
919         if (IS_ERR(devmap))
920                 return PTR_ERR(devmap);
921
922         /* generate entry for server_ssid_map */
923         srv = (struct dasd_server_ssid_map *)
924                 kzalloc(sizeof(struct dasd_server_ssid_map), GFP_KERNEL);
925         if (!srv)
926                 return -ENOMEM;
927         strncpy(srv->sid.vendor, uid->vendor, sizeof(srv->sid.vendor) - 1);
928         strncpy(srv->sid.serial, uid->serial, sizeof(srv->sid.serial) - 1);
929         srv->sid.ssid = uid->ssid;
930
931         /* server is already contained ? */
932         spin_lock(&dasd_devmap_lock);
933         devmap->uid = *uid;
934         list_for_each_entry(tmp, &dasd_server_ssid_list, list) {
935                 if (!memcmp(&srv->sid, &tmp->sid,
936                             sizeof(struct system_id))) {
937                         kfree(srv);
938                         srv = NULL;
939                         break;
940                 }
941         }
942
943         /* add servermap to serverlist */
944         if (srv)
945                 list_add(&srv->list, &dasd_server_ssid_list);
946         spin_unlock(&dasd_devmap_lock);
947
948         return (srv ? 1 : 0);
949 }
950 EXPORT_SYMBOL_GPL(dasd_set_uid);
951
952 /*
953  * Return value of the specified feature.
954  */
955 int
956 dasd_get_feature(struct ccw_device *cdev, int feature)
957 {
958         struct dasd_devmap *devmap;
959
960         devmap = dasd_find_busid(cdev->dev.bus_id);
961         if (IS_ERR(devmap))
962                 return PTR_ERR(devmap);
963
964         return ((devmap->features & feature) != 0);
965 }
966
967 /*
968  * Set / reset given feature.
969  * Flag indicates wether to set (!=0) or the reset (=0) the feature.
970  */
971 int
972 dasd_set_feature(struct ccw_device *cdev, int feature, int flag)
973 {
974         struct dasd_devmap *devmap;
975
976         devmap = dasd_find_busid(cdev->dev.bus_id);
977         if (IS_ERR(devmap))
978                 return PTR_ERR(devmap);
979
980         spin_lock(&dasd_devmap_lock);
981         if (flag)
982                 devmap->features |= feature;
983         else
984                 devmap->features &= ~feature;
985         if (devmap->device)
986                 devmap->device->features = devmap->features;
987         spin_unlock(&dasd_devmap_lock);
988         return 0;
989 }
990
991
992 int
993 dasd_add_sysfs_files(struct ccw_device *cdev)
994 {
995         return sysfs_create_group(&cdev->dev.kobj, &dasd_attr_group);
996 }
997
998 void
999 dasd_remove_sysfs_files(struct ccw_device *cdev)
1000 {
1001         sysfs_remove_group(&cdev->dev.kobj, &dasd_attr_group);
1002 }
1003
1004
1005 int
1006 dasd_devmap_init(void)
1007 {
1008         int i;
1009
1010         /* Initialize devmap structures. */
1011         dasd_max_devindex = 0;
1012         for (i = 0; i < 256; i++)
1013                 INIT_LIST_HEAD(&dasd_hashlists[i]);
1014
1015         /* Initialize servermap structure. */
1016         INIT_LIST_HEAD(&dasd_server_ssid_list);
1017         return 0;
1018 }
1019
1020 void
1021 dasd_devmap_exit(void)
1022 {
1023         dasd_forget_ranges();
1024 }