Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1/*
2 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
3 * Horst Hummel <Horst.Hummel@de.ibm.com>
4 * Carsten Otte <Cotte@de.ibm.com>
5 * Martin Schwidefsky <schwidefsky@de.ibm.com>
6 * Bugreports.to..: <Linux390@de.ibm.com>
7 * Copyright IBM Corp. 1999,2001
8 *
9 * Device mapping and dasd= parameter parsing functions. All devmap
10 * functions may not be called from interrupt context. In particular
11 * dasd_get_device is a no-no from interrupt context.
12 *
13 */
14
15#define KMSG_COMPONENT "dasd"
16
17#include <linux/ctype.h>
18#include <linux/init.h>
19#include <linux/module.h>
20#include <linux/slab.h>
21
22#include <asm/debug.h>
23#include <linux/uaccess.h>
24#include <asm/ipl.h>
25
26/* This is ugly... */
27#define PRINTK_HEADER "dasd_devmap:"
28#define DASD_BUS_ID_SIZE 20
29#define DASD_MAX_PARAMS 256
30
31#include "dasd_int.h"
32
33struct kmem_cache *dasd_page_cache;
34EXPORT_SYMBOL_GPL(dasd_page_cache);
35
36/*
37 * dasd_devmap_t is used to store the features and the relation
38 * between device number and device index. To find a dasd_devmap_t
39 * that corresponds to a device number of a device index each
40 * dasd_devmap_t is added to two linked lists, one to search by
41 * the device number and one to search by the device index. As
42 * soon as big minor numbers are available the device index list
43 * can be removed since the device number will then be identical
44 * to the device index.
45 */
46struct dasd_devmap {
47 struct list_head list;
48 char bus_id[DASD_BUS_ID_SIZE];
49 unsigned int devindex;
50 unsigned short features;
51 struct dasd_device *device;
52};
53
54/*
55 * Parameter parsing functions for dasd= parameter. The syntax is:
56 * <devno> : (0x)?[0-9a-fA-F]+
57 * <busid> : [0-0a-f]\.[0-9a-f]\.(0x)?[0-9a-fA-F]+
58 * <feature> : ro
59 * <feature_list> : \(<feature>(:<feature>)*\)
60 * <devno-range> : <devno>(-<devno>)?<feature_list>?
61 * <busid-range> : <busid>(-<busid>)?<feature_list>?
62 * <devices> : <devno-range>|<busid-range>
63 * <dasd_module> : dasd_diag_mod|dasd_eckd_mod|dasd_fba_mod
64 *
65 * <dasd> : autodetect|probeonly|<devices>(,<devices>)*
66 */
67
68int dasd_probeonly = 0; /* is true, when probeonly mode is active */
69int dasd_autodetect = 0; /* is true, when autodetection is active */
70int dasd_nopav = 0; /* is true, when PAV is disabled */
71EXPORT_SYMBOL_GPL(dasd_nopav);
72int dasd_nofcx; /* disable High Performance Ficon */
73EXPORT_SYMBOL_GPL(dasd_nofcx);
74
75/*
76 * char *dasd[] is intended to hold the ranges supplied by the dasd= statement
77 * it is named 'dasd' to directly be filled by insmod with the comma separated
78 * strings when running as a module.
79 */
80static char *dasd[DASD_MAX_PARAMS];
81module_param_array(dasd, charp, NULL, S_IRUGO);
82
83/*
84 * Single spinlock to protect devmap and servermap structures and lists.
85 */
86static DEFINE_SPINLOCK(dasd_devmap_lock);
87
88/*
89 * Hash lists for devmap structures.
90 */
91static struct list_head dasd_hashlists[256];
92int dasd_max_devindex;
93
94static struct dasd_devmap *dasd_add_busid(const char *, int);
95
96static inline int
97dasd_hash_busid(const char *bus_id)
98{
99 int hash, i;
100
101 hash = 0;
102 for (i = 0; (i < DASD_BUS_ID_SIZE) && *bus_id; i++, bus_id++)
103 hash += *bus_id;
104 return hash & 0xff;
105}
106
107#ifndef MODULE
108static int __init dasd_call_setup(char *opt)
109{
110 static int i __initdata;
111 char *tmp;
112
113 while (i < DASD_MAX_PARAMS) {
114 tmp = strsep(&opt, ",");
115 if (!tmp)
116 break;
117
118 dasd[i++] = tmp;
119 }
120
121 return 1;
122}
123
124__setup ("dasd=", dasd_call_setup);
125#endif /* #ifndef MODULE */
126
127#define DASD_IPLDEV "ipldev"
128
129/*
130 * Read a device busid/devno from a string.
131 */
132static int __init dasd_busid(char *str, int *id0, int *id1, int *devno)
133{
134 unsigned int val;
135 char *tok;
136
137 /* Interpret ipldev busid */
138 if (strncmp(DASD_IPLDEV, str, strlen(DASD_IPLDEV)) == 0) {
139 if (ipl_info.type != IPL_TYPE_CCW) {
140 pr_err("The IPL device is not a CCW device\n");
141 return -EINVAL;
142 }
143 *id0 = 0;
144 *id1 = ipl_info.data.ccw.dev_id.ssid;
145 *devno = ipl_info.data.ccw.dev_id.devno;
146
147 return 0;
148 }
149
150 /* Old style 0xXXXX or XXXX */
151 if (!kstrtouint(str, 16, &val)) {
152 *id0 = *id1 = 0;
153 if (val < 0 || val > 0xffff)
154 return -EINVAL;
155 *devno = val;
156 return 0;
157 }
158
159 /* New style x.y.z busid */
160 tok = strsep(&str, ".");
161 if (kstrtouint(tok, 16, &val) || val > 0xff)
162 return -EINVAL;
163 *id0 = val;
164
165 tok = strsep(&str, ".");
166 if (kstrtouint(tok, 16, &val) || val > 0xff)
167 return -EINVAL;
168 *id1 = val;
169
170 tok = strsep(&str, ".");
171 if (kstrtouint(tok, 16, &val) || val > 0xffff)
172 return -EINVAL;
173 *devno = val;
174
175 return 0;
176}
177
178/*
179 * Read colon separated list of dasd features.
180 */
181static int __init dasd_feature_list(char *str)
182{
183 int features, len, rc;
184
185 features = 0;
186 rc = 0;
187
188 if (!str)
189 return DASD_FEATURE_DEFAULT;
190
191 while (1) {
192 for (len = 0;
193 str[len] && str[len] != ':' && str[len] != ')'; len++);
194 if (len == 2 && !strncmp(str, "ro", 2))
195 features |= DASD_FEATURE_READONLY;
196 else if (len == 4 && !strncmp(str, "diag", 4))
197 features |= DASD_FEATURE_USEDIAG;
198 else if (len == 3 && !strncmp(str, "raw", 3))
199 features |= DASD_FEATURE_USERAW;
200 else if (len == 6 && !strncmp(str, "erplog", 6))
201 features |= DASD_FEATURE_ERPLOG;
202 else if (len == 8 && !strncmp(str, "failfast", 8))
203 features |= DASD_FEATURE_FAILFAST;
204 else {
205 pr_warn("%*s is not a supported device option\n",
206 len, str);
207 rc = -EINVAL;
208 }
209 str += len;
210 if (*str != ':')
211 break;
212 str++;
213 }
214
215 return rc ? : features;
216}
217
218/*
219 * Try to match the first element on the comma separated parse string
220 * with one of the known keywords. If a keyword is found, take the approprate
221 * action and return a pointer to the residual string. If the first element
222 * could not be matched to any keyword then return an error code.
223 */
224static int __init dasd_parse_keyword(char *keyword)
225{
226 int length = strlen(keyword);
227
228 if (strncmp("autodetect", keyword, length) == 0) {
229 dasd_autodetect = 1;
230 pr_info("The autodetection mode has been activated\n");
231 return 0;
232 }
233 if (strncmp("probeonly", keyword, length) == 0) {
234 dasd_probeonly = 1;
235 pr_info("The probeonly mode has been activated\n");
236 return 0;
237 }
238 if (strncmp("nopav", keyword, length) == 0) {
239 if (MACHINE_IS_VM)
240 pr_info("'nopav' is not supported on z/VM\n");
241 else {
242 dasd_nopav = 1;
243 pr_info("PAV support has be deactivated\n");
244 }
245 return 0;
246 }
247 if (strncmp("nofcx", keyword, length) == 0) {
248 dasd_nofcx = 1;
249 pr_info("High Performance FICON support has been "
250 "deactivated\n");
251 return 0;
252 }
253 if (strncmp("fixedbuffers", keyword, length) == 0) {
254 if (dasd_page_cache)
255 return 0;
256 dasd_page_cache =
257 kmem_cache_create("dasd_page_cache", PAGE_SIZE,
258 PAGE_SIZE, SLAB_CACHE_DMA,
259 NULL);
260 if (!dasd_page_cache)
261 DBF_EVENT(DBF_WARNING, "%s", "Failed to create slab, "
262 "fixed buffer mode disabled.");
263 else
264 DBF_EVENT(DBF_INFO, "%s",
265 "turning on fixed buffer mode");
266 return 0;
267 }
268
269 return -EINVAL;
270}
271
272/*
273 * Split a string of a device range into its pieces and return the from, to, and
274 * feature parts separately.
275 * e.g.:
276 * 0.0.1234-0.0.5678(ro:erplog) -> from: 0.0.1234 to: 0.0.5678 features: ro:erplog
277 * 0.0.8765(raw) -> from: 0.0.8765 to: null features: raw
278 * 0x4321 -> from: 0x4321 to: null features: null
279 */
280static int __init dasd_evaluate_range_param(char *range, char **from_str,
281 char **to_str, char **features_str)
282{
283 int rc = 0;
284
285 /* Do we have a range or a single device? */
286 if (strchr(range, '-')) {
287 *from_str = strsep(&range, "-");
288 *to_str = strsep(&range, "(");
289 *features_str = strsep(&range, ")");
290 } else {
291 *from_str = strsep(&range, "(");
292 *features_str = strsep(&range, ")");
293 }
294
295 if (*features_str && !range) {
296 pr_warn("A closing parenthesis ')' is missing in the dasd= parameter\n");
297 rc = -EINVAL;
298 }
299
300 return rc;
301}
302
303/*
304 * Try to interprete the range string as a device number or a range of devices.
305 * If the interpretation is successful, create the matching dasd_devmap entries.
306 * If interpretation fails or in case of an error, return an error code.
307 */
308static int __init dasd_parse_range(const char *range)
309{
310 struct dasd_devmap *devmap;
311 int from, from_id0, from_id1;
312 int to, to_id0, to_id1;
313 int features;
314 char bus_id[DASD_BUS_ID_SIZE + 1];
315 char *features_str = NULL;
316 char *from_str = NULL;
317 char *to_str = NULL;
318 size_t len = strlen(range) + 1;
319 char tmp[len];
320
321 strlcpy(tmp, range, len);
322
323 if (dasd_evaluate_range_param(tmp, &from_str, &to_str, &features_str))
324 goto out_err;
325
326 if (dasd_busid(from_str, &from_id0, &from_id1, &from))
327 goto out_err;
328
329 to = from;
330 to_id0 = from_id0;
331 to_id1 = from_id1;
332 if (to_str) {
333 if (dasd_busid(to_str, &to_id0, &to_id1, &to))
334 goto out_err;
335 if (from_id0 != to_id0 || from_id1 != to_id1 || from > to) {
336 pr_err("%s is not a valid device range\n", range);
337 goto out_err;
338 }
339 }
340
341 features = dasd_feature_list(features_str);
342 if (features < 0)
343 goto out_err;
344 /* each device in dasd= parameter should be set initially online */
345 features |= DASD_FEATURE_INITIAL_ONLINE;
346 while (from <= to) {
347 sprintf(bus_id, "%01x.%01x.%04x", from_id0, from_id1, from++);
348 devmap = dasd_add_busid(bus_id, features);
349 if (IS_ERR(devmap))
350 return PTR_ERR(devmap);
351 }
352
353 return 0;
354
355out_err:
356 return -EINVAL;
357}
358
359/*
360 * Parse parameters stored in dasd[]
361 * The 'dasd=...' parameter allows to specify a comma separated list of
362 * keywords and device ranges. The parameters in that list will be stored as
363 * separate elementes in dasd[].
364 */
365int __init dasd_parse(void)
366{
367 int rc, i;
368 char *cur;
369
370 rc = 0;
371 for (i = 0; i < DASD_MAX_PARAMS; i++) {
372 cur = dasd[i];
373 if (!cur)
374 break;
375 if (*cur == '\0')
376 continue;
377
378 rc = dasd_parse_keyword(cur);
379 if (rc)
380 rc = dasd_parse_range(cur);
381
382 if (rc)
383 break;
384 }
385
386 return rc;
387}
388
389/*
390 * Add a devmap for the device specified by busid. It is possible that
391 * the devmap already exists (dasd= parameter). The order of the devices
392 * added through this function will define the kdevs for the individual
393 * devices.
394 */
395static struct dasd_devmap *
396dasd_add_busid(const char *bus_id, int features)
397{
398 struct dasd_devmap *devmap, *new, *tmp;
399 int hash;
400
401 new = kzalloc(sizeof(struct dasd_devmap), GFP_KERNEL);
402 if (!new)
403 return ERR_PTR(-ENOMEM);
404 spin_lock(&dasd_devmap_lock);
405 devmap = NULL;
406 hash = dasd_hash_busid(bus_id);
407 list_for_each_entry(tmp, &dasd_hashlists[hash], list)
408 if (strncmp(tmp->bus_id, bus_id, DASD_BUS_ID_SIZE) == 0) {
409 devmap = tmp;
410 break;
411 }
412 if (!devmap) {
413 /* This bus_id is new. */
414 new->devindex = dasd_max_devindex++;
415 strncpy(new->bus_id, bus_id, DASD_BUS_ID_SIZE);
416 new->features = features;
417 new->device = NULL;
418 list_add(&new->list, &dasd_hashlists[hash]);
419 devmap = new;
420 new = NULL;
421 }
422 spin_unlock(&dasd_devmap_lock);
423 kfree(new);
424 return devmap;
425}
426
427/*
428 * Find devmap for device with given bus_id.
429 */
430static struct dasd_devmap *
431dasd_find_busid(const char *bus_id)
432{
433 struct dasd_devmap *devmap, *tmp;
434 int hash;
435
436 spin_lock(&dasd_devmap_lock);
437 devmap = ERR_PTR(-ENODEV);
438 hash = dasd_hash_busid(bus_id);
439 list_for_each_entry(tmp, &dasd_hashlists[hash], list) {
440 if (strncmp(tmp->bus_id, bus_id, DASD_BUS_ID_SIZE) == 0) {
441 devmap = tmp;
442 break;
443 }
444 }
445 spin_unlock(&dasd_devmap_lock);
446 return devmap;
447}
448
449/*
450 * Check if busid has been added to the list of dasd ranges.
451 */
452int
453dasd_busid_known(const char *bus_id)
454{
455 return IS_ERR(dasd_find_busid(bus_id)) ? -ENOENT : 0;
456}
457
458/*
459 * Forget all about the device numbers added so far.
460 * This may only be called at module unload or system shutdown.
461 */
462static void
463dasd_forget_ranges(void)
464{
465 struct dasd_devmap *devmap, *n;
466 int i;
467
468 spin_lock(&dasd_devmap_lock);
469 for (i = 0; i < 256; i++) {
470 list_for_each_entry_safe(devmap, n, &dasd_hashlists[i], list) {
471 BUG_ON(devmap->device != NULL);
472 list_del(&devmap->list);
473 kfree(devmap);
474 }
475 }
476 spin_unlock(&dasd_devmap_lock);
477}
478
479/*
480 * Find the device struct by its device index.
481 */
482struct dasd_device *
483dasd_device_from_devindex(int devindex)
484{
485 struct dasd_devmap *devmap, *tmp;
486 struct dasd_device *device;
487 int i;
488
489 spin_lock(&dasd_devmap_lock);
490 devmap = NULL;
491 for (i = 0; (i < 256) && !devmap; i++)
492 list_for_each_entry(tmp, &dasd_hashlists[i], list)
493 if (tmp->devindex == devindex) {
494 /* Found the devmap for the device. */
495 devmap = tmp;
496 break;
497 }
498 if (devmap && devmap->device) {
499 device = devmap->device;
500 dasd_get_device(device);
501 } else
502 device = ERR_PTR(-ENODEV);
503 spin_unlock(&dasd_devmap_lock);
504 return device;
505}
506
507/*
508 * Return devmap for cdev. If no devmap exists yet, create one and
509 * connect it to the cdev.
510 */
511static struct dasd_devmap *
512dasd_devmap_from_cdev(struct ccw_device *cdev)
513{
514 struct dasd_devmap *devmap;
515
516 devmap = dasd_find_busid(dev_name(&cdev->dev));
517 if (IS_ERR(devmap))
518 devmap = dasd_add_busid(dev_name(&cdev->dev),
519 DASD_FEATURE_DEFAULT);
520 return devmap;
521}
522
523/*
524 * Create a dasd device structure for cdev.
525 */
526struct dasd_device *
527dasd_create_device(struct ccw_device *cdev)
528{
529 struct dasd_devmap *devmap;
530 struct dasd_device *device;
531 unsigned long flags;
532 int rc;
533
534 devmap = dasd_devmap_from_cdev(cdev);
535 if (IS_ERR(devmap))
536 return (void *) devmap;
537
538 device = dasd_alloc_device();
539 if (IS_ERR(device))
540 return device;
541 atomic_set(&device->ref_count, 3);
542
543 spin_lock(&dasd_devmap_lock);
544 if (!devmap->device) {
545 devmap->device = device;
546 device->devindex = devmap->devindex;
547 device->features = devmap->features;
548 get_device(&cdev->dev);
549 device->cdev = cdev;
550 rc = 0;
551 } else
552 /* Someone else was faster. */
553 rc = -EBUSY;
554 spin_unlock(&dasd_devmap_lock);
555
556 if (rc) {
557 dasd_free_device(device);
558 return ERR_PTR(rc);
559 }
560
561 spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
562 dev_set_drvdata(&cdev->dev, device);
563 spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
564
565 return device;
566}
567
568/*
569 * Wait queue for dasd_delete_device waits.
570 */
571static DECLARE_WAIT_QUEUE_HEAD(dasd_delete_wq);
572
573/*
574 * Remove a dasd device structure. The passed referenced
575 * is destroyed.
576 */
577void
578dasd_delete_device(struct dasd_device *device)
579{
580 struct ccw_device *cdev;
581 struct dasd_devmap *devmap;
582 unsigned long flags;
583
584 /* First remove device pointer from devmap. */
585 devmap = dasd_find_busid(dev_name(&device->cdev->dev));
586 BUG_ON(IS_ERR(devmap));
587 spin_lock(&dasd_devmap_lock);
588 if (devmap->device != device) {
589 spin_unlock(&dasd_devmap_lock);
590 dasd_put_device(device);
591 return;
592 }
593 devmap->device = NULL;
594 spin_unlock(&dasd_devmap_lock);
595
596 /* Disconnect dasd_device structure from ccw_device structure. */
597 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
598 dev_set_drvdata(&device->cdev->dev, NULL);
599 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
600
601 /*
602 * Drop ref_count by 3, one for the devmap reference, one for
603 * the cdev reference and one for the passed reference.
604 */
605 atomic_sub(3, &device->ref_count);
606
607 /* Wait for reference counter to drop to zero. */
608 wait_event(dasd_delete_wq, atomic_read(&device->ref_count) == 0);
609
610 dasd_generic_free_discipline(device);
611 /* Disconnect dasd_device structure from ccw_device structure. */
612 cdev = device->cdev;
613 device->cdev = NULL;
614
615 /* Put ccw_device structure. */
616 put_device(&cdev->dev);
617
618 /* Now the device structure can be freed. */
619 dasd_free_device(device);
620}
621
622/*
623 * Reference counter dropped to zero. Wake up waiter
624 * in dasd_delete_device.
625 */
626void
627dasd_put_device_wake(struct dasd_device *device)
628{
629 wake_up(&dasd_delete_wq);
630}
631EXPORT_SYMBOL_GPL(dasd_put_device_wake);
632
633/*
634 * Return dasd_device structure associated with cdev.
635 * This function needs to be called with the ccw device
636 * lock held. It can be used from interrupt context.
637 */
638struct dasd_device *
639dasd_device_from_cdev_locked(struct ccw_device *cdev)
640{
641 struct dasd_device *device = dev_get_drvdata(&cdev->dev);
642
643 if (!device)
644 return ERR_PTR(-ENODEV);
645 dasd_get_device(device);
646 return device;
647}
648
649/*
650 * Return dasd_device structure associated with cdev.
651 */
652struct dasd_device *
653dasd_device_from_cdev(struct ccw_device *cdev)
654{
655 struct dasd_device *device;
656 unsigned long flags;
657
658 spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
659 device = dasd_device_from_cdev_locked(cdev);
660 spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
661 return device;
662}
663
664void dasd_add_link_to_gendisk(struct gendisk *gdp, struct dasd_device *device)
665{
666 struct dasd_devmap *devmap;
667
668 devmap = dasd_find_busid(dev_name(&device->cdev->dev));
669 if (IS_ERR(devmap))
670 return;
671 spin_lock(&dasd_devmap_lock);
672 gdp->private_data = devmap;
673 spin_unlock(&dasd_devmap_lock);
674}
675
676struct dasd_device *dasd_device_from_gendisk(struct gendisk *gdp)
677{
678 struct dasd_device *device;
679 struct dasd_devmap *devmap;
680
681 if (!gdp->private_data)
682 return NULL;
683 device = NULL;
684 spin_lock(&dasd_devmap_lock);
685 devmap = gdp->private_data;
686 if (devmap && devmap->device) {
687 device = devmap->device;
688 dasd_get_device(device);
689 }
690 spin_unlock(&dasd_devmap_lock);
691 return device;
692}
693
694/*
695 * SECTION: files in sysfs
696 */
697
698/*
699 * failfast controls the behaviour, if no path is available
700 */
701static ssize_t dasd_ff_show(struct device *dev, struct device_attribute *attr,
702 char *buf)
703{
704 struct dasd_devmap *devmap;
705 int ff_flag;
706
707 devmap = dasd_find_busid(dev_name(dev));
708 if (!IS_ERR(devmap))
709 ff_flag = (devmap->features & DASD_FEATURE_FAILFAST) != 0;
710 else
711 ff_flag = (DASD_FEATURE_DEFAULT & DASD_FEATURE_FAILFAST) != 0;
712 return snprintf(buf, PAGE_SIZE, ff_flag ? "1\n" : "0\n");
713}
714
715static ssize_t dasd_ff_store(struct device *dev, struct device_attribute *attr,
716 const char *buf, size_t count)
717{
718 unsigned int val;
719 int rc;
720
721 if (kstrtouint(buf, 0, &val) || val > 1)
722 return -EINVAL;
723
724 rc = dasd_set_feature(to_ccwdev(dev), DASD_FEATURE_FAILFAST, val);
725
726 return rc ? : count;
727}
728
729static DEVICE_ATTR(failfast, 0644, dasd_ff_show, dasd_ff_store);
730
731/*
732 * readonly controls the readonly status of a dasd
733 */
734static ssize_t
735dasd_ro_show(struct device *dev, struct device_attribute *attr, char *buf)
736{
737 struct dasd_devmap *devmap;
738 int ro_flag;
739
740 devmap = dasd_find_busid(dev_name(dev));
741 if (!IS_ERR(devmap))
742 ro_flag = (devmap->features & DASD_FEATURE_READONLY) != 0;
743 else
744 ro_flag = (DASD_FEATURE_DEFAULT & DASD_FEATURE_READONLY) != 0;
745 return snprintf(buf, PAGE_SIZE, ro_flag ? "1\n" : "0\n");
746}
747
748static ssize_t
749dasd_ro_store(struct device *dev, struct device_attribute *attr,
750 const char *buf, size_t count)
751{
752 struct ccw_device *cdev = to_ccwdev(dev);
753 struct dasd_device *device;
754 unsigned long flags;
755 unsigned int val;
756 int rc;
757
758 if (kstrtouint(buf, 0, &val) || val > 1)
759 return -EINVAL;
760
761 rc = dasd_set_feature(cdev, DASD_FEATURE_READONLY, val);
762 if (rc)
763 return rc;
764
765 device = dasd_device_from_cdev(cdev);
766 if (IS_ERR(device))
767 return PTR_ERR(device);
768
769 spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
770 val = val || test_bit(DASD_FLAG_DEVICE_RO, &device->flags);
771
772 if (!device->block || !device->block->gdp ||
773 test_bit(DASD_FLAG_OFFLINE, &device->flags)) {
774 spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
775 goto out;
776 }
777 /* Increase open_count to avoid losing the block device */
778 atomic_inc(&device->block->open_count);
779 spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
780
781 set_disk_ro(device->block->gdp, val);
782 atomic_dec(&device->block->open_count);
783
784out:
785 dasd_put_device(device);
786
787 return count;
788}
789
790static DEVICE_ATTR(readonly, 0644, dasd_ro_show, dasd_ro_store);
791/*
792 * erplog controls the logging of ERP related data
793 * (e.g. failing channel programs).
794 */
795static ssize_t
796dasd_erplog_show(struct device *dev, struct device_attribute *attr, char *buf)
797{
798 struct dasd_devmap *devmap;
799 int erplog;
800
801 devmap = dasd_find_busid(dev_name(dev));
802 if (!IS_ERR(devmap))
803 erplog = (devmap->features & DASD_FEATURE_ERPLOG) != 0;
804 else
805 erplog = (DASD_FEATURE_DEFAULT & DASD_FEATURE_ERPLOG) != 0;
806 return snprintf(buf, PAGE_SIZE, erplog ? "1\n" : "0\n");
807}
808
809static ssize_t
810dasd_erplog_store(struct device *dev, struct device_attribute *attr,
811 const char *buf, size_t count)
812{
813 unsigned int val;
814 int rc;
815
816 if (kstrtouint(buf, 0, &val) || val > 1)
817 return -EINVAL;
818
819 rc = dasd_set_feature(to_ccwdev(dev), DASD_FEATURE_ERPLOG, val);
820
821 return rc ? : count;
822}
823
824static DEVICE_ATTR(erplog, 0644, dasd_erplog_show, dasd_erplog_store);
825
826/*
827 * use_diag controls whether the driver should use diag rather than ssch
828 * to talk to the device
829 */
830static ssize_t
831dasd_use_diag_show(struct device *dev, struct device_attribute *attr, char *buf)
832{
833 struct dasd_devmap *devmap;
834 int use_diag;
835
836 devmap = dasd_find_busid(dev_name(dev));
837 if (!IS_ERR(devmap))
838 use_diag = (devmap->features & DASD_FEATURE_USEDIAG) != 0;
839 else
840 use_diag = (DASD_FEATURE_DEFAULT & DASD_FEATURE_USEDIAG) != 0;
841 return sprintf(buf, use_diag ? "1\n" : "0\n");
842}
843
844static ssize_t
845dasd_use_diag_store(struct device *dev, struct device_attribute *attr,
846 const char *buf, size_t count)
847{
848 struct dasd_devmap *devmap;
849 unsigned int val;
850 ssize_t rc;
851
852 devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
853 if (IS_ERR(devmap))
854 return PTR_ERR(devmap);
855
856 if (kstrtouint(buf, 0, &val) || val > 1)
857 return -EINVAL;
858
859 spin_lock(&dasd_devmap_lock);
860 /* Changing diag discipline flag is only allowed in offline state. */
861 rc = count;
862 if (!devmap->device && !(devmap->features & DASD_FEATURE_USERAW)) {
863 if (val)
864 devmap->features |= DASD_FEATURE_USEDIAG;
865 else
866 devmap->features &= ~DASD_FEATURE_USEDIAG;
867 } else
868 rc = -EPERM;
869 spin_unlock(&dasd_devmap_lock);
870 return rc;
871}
872
873static DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store);
874
875/*
876 * use_raw controls whether the driver should give access to raw eckd data or
877 * operate in standard mode
878 */
879static ssize_t
880dasd_use_raw_show(struct device *dev, struct device_attribute *attr, char *buf)
881{
882 struct dasd_devmap *devmap;
883 int use_raw;
884
885 devmap = dasd_find_busid(dev_name(dev));
886 if (!IS_ERR(devmap))
887 use_raw = (devmap->features & DASD_FEATURE_USERAW) != 0;
888 else
889 use_raw = (DASD_FEATURE_DEFAULT & DASD_FEATURE_USERAW) != 0;
890 return sprintf(buf, use_raw ? "1\n" : "0\n");
891}
892
893static ssize_t
894dasd_use_raw_store(struct device *dev, struct device_attribute *attr,
895 const char *buf, size_t count)
896{
897 struct dasd_devmap *devmap;
898 ssize_t rc;
899 unsigned long val;
900
901 devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
902 if (IS_ERR(devmap))
903 return PTR_ERR(devmap);
904
905 if ((kstrtoul(buf, 10, &val) != 0) || val > 1)
906 return -EINVAL;
907
908 spin_lock(&dasd_devmap_lock);
909 /* Changing diag discipline flag is only allowed in offline state. */
910 rc = count;
911 if (!devmap->device && !(devmap->features & DASD_FEATURE_USEDIAG)) {
912 if (val)
913 devmap->features |= DASD_FEATURE_USERAW;
914 else
915 devmap->features &= ~DASD_FEATURE_USERAW;
916 } else
917 rc = -EPERM;
918 spin_unlock(&dasd_devmap_lock);
919 return rc;
920}
921
922static DEVICE_ATTR(raw_track_access, 0644, dasd_use_raw_show,
923 dasd_use_raw_store);
924
925static ssize_t
926dasd_safe_offline_store(struct device *dev, struct device_attribute *attr,
927 const char *buf, size_t count)
928{
929 struct ccw_device *cdev = to_ccwdev(dev);
930 struct dasd_device *device;
931 int rc;
932
933 device = dasd_device_from_cdev(cdev);
934 if (IS_ERR(device)) {
935 rc = PTR_ERR(device);
936 goto out;
937 }
938
939 if (test_bit(DASD_FLAG_OFFLINE, &device->flags) ||
940 test_bit(DASD_FLAG_SAFE_OFFLINE_RUNNING, &device->flags)) {
941 /* Already doing offline processing */
942 dasd_put_device(device);
943 rc = -EBUSY;
944 goto out;
945 }
946
947 set_bit(DASD_FLAG_SAFE_OFFLINE, &device->flags);
948 dasd_put_device(device);
949
950 rc = ccw_device_set_offline(cdev);
951
952out:
953 return rc ? rc : count;
954}
955
956static DEVICE_ATTR(safe_offline, 0200, NULL, dasd_safe_offline_store);
957
958static ssize_t
959dasd_access_show(struct device *dev, struct device_attribute *attr,
960 char *buf)
961{
962 struct ccw_device *cdev = to_ccwdev(dev);
963 struct dasd_device *device;
964 int count;
965
966 device = dasd_device_from_cdev(cdev);
967 if (IS_ERR(device))
968 return PTR_ERR(device);
969
970 if (!device->discipline)
971 count = -ENODEV;
972 else if (!device->discipline->host_access_count)
973 count = -EOPNOTSUPP;
974 else
975 count = device->discipline->host_access_count(device);
976
977 dasd_put_device(device);
978 if (count < 0)
979 return count;
980
981 return sprintf(buf, "%d\n", count);
982}
983
984static DEVICE_ATTR(host_access_count, 0444, dasd_access_show, NULL);
985
986static ssize_t
987dasd_discipline_show(struct device *dev, struct device_attribute *attr,
988 char *buf)
989{
990 struct dasd_device *device;
991 ssize_t len;
992
993 device = dasd_device_from_cdev(to_ccwdev(dev));
994 if (IS_ERR(device))
995 goto out;
996 else if (!device->discipline) {
997 dasd_put_device(device);
998 goto out;
999 } else {
1000 len = snprintf(buf, PAGE_SIZE, "%s\n",
1001 device->discipline->name);
1002 dasd_put_device(device);
1003 return len;
1004 }
1005out:
1006 len = snprintf(buf, PAGE_SIZE, "none\n");
1007 return len;
1008}
1009
1010static DEVICE_ATTR(discipline, 0444, dasd_discipline_show, NULL);
1011
1012static ssize_t
1013dasd_device_status_show(struct device *dev, struct device_attribute *attr,
1014 char *buf)
1015{
1016 struct dasd_device *device;
1017 ssize_t len;
1018
1019 device = dasd_device_from_cdev(to_ccwdev(dev));
1020 if (!IS_ERR(device)) {
1021 switch (device->state) {
1022 case DASD_STATE_NEW:
1023 len = snprintf(buf, PAGE_SIZE, "new\n");
1024 break;
1025 case DASD_STATE_KNOWN:
1026 len = snprintf(buf, PAGE_SIZE, "detected\n");
1027 break;
1028 case DASD_STATE_BASIC:
1029 len = snprintf(buf, PAGE_SIZE, "basic\n");
1030 break;
1031 case DASD_STATE_UNFMT:
1032 len = snprintf(buf, PAGE_SIZE, "unformatted\n");
1033 break;
1034 case DASD_STATE_READY:
1035 len = snprintf(buf, PAGE_SIZE, "ready\n");
1036 break;
1037 case DASD_STATE_ONLINE:
1038 len = snprintf(buf, PAGE_SIZE, "online\n");
1039 break;
1040 default:
1041 len = snprintf(buf, PAGE_SIZE, "no stat\n");
1042 break;
1043 }
1044 dasd_put_device(device);
1045 } else
1046 len = snprintf(buf, PAGE_SIZE, "unknown\n");
1047 return len;
1048}
1049
1050static DEVICE_ATTR(status, 0444, dasd_device_status_show, NULL);
1051
1052static ssize_t dasd_alias_show(struct device *dev,
1053 struct device_attribute *attr, char *buf)
1054{
1055 struct dasd_device *device;
1056 struct dasd_uid uid;
1057
1058 device = dasd_device_from_cdev(to_ccwdev(dev));
1059 if (IS_ERR(device))
1060 return sprintf(buf, "0\n");
1061
1062 if (device->discipline && device->discipline->get_uid &&
1063 !device->discipline->get_uid(device, &uid)) {
1064 if (uid.type == UA_BASE_PAV_ALIAS ||
1065 uid.type == UA_HYPER_PAV_ALIAS) {
1066 dasd_put_device(device);
1067 return sprintf(buf, "1\n");
1068 }
1069 }
1070 dasd_put_device(device);
1071
1072 return sprintf(buf, "0\n");
1073}
1074
1075static DEVICE_ATTR(alias, 0444, dasd_alias_show, NULL);
1076
1077static ssize_t dasd_vendor_show(struct device *dev,
1078 struct device_attribute *attr, char *buf)
1079{
1080 struct dasd_device *device;
1081 struct dasd_uid uid;
1082 char *vendor;
1083
1084 device = dasd_device_from_cdev(to_ccwdev(dev));
1085 vendor = "";
1086 if (IS_ERR(device))
1087 return snprintf(buf, PAGE_SIZE, "%s\n", vendor);
1088
1089 if (device->discipline && device->discipline->get_uid &&
1090 !device->discipline->get_uid(device, &uid))
1091 vendor = uid.vendor;
1092
1093 dasd_put_device(device);
1094
1095 return snprintf(buf, PAGE_SIZE, "%s\n", vendor);
1096}
1097
1098static DEVICE_ATTR(vendor, 0444, dasd_vendor_show, NULL);
1099
1100#define UID_STRLEN ( /* vendor */ 3 + 1 + /* serial */ 14 + 1 +\
1101 /* SSID */ 4 + 1 + /* unit addr */ 2 + 1 +\
1102 /* vduit */ 32 + 1)
1103
1104static ssize_t
1105dasd_uid_show(struct device *dev, struct device_attribute *attr, char *buf)
1106{
1107 struct dasd_device *device;
1108 struct dasd_uid uid;
1109 char uid_string[UID_STRLEN];
1110 char ua_string[3];
1111
1112 device = dasd_device_from_cdev(to_ccwdev(dev));
1113 uid_string[0] = 0;
1114 if (IS_ERR(device))
1115 return snprintf(buf, PAGE_SIZE, "%s\n", uid_string);
1116
1117 if (device->discipline && device->discipline->get_uid &&
1118 !device->discipline->get_uid(device, &uid)) {
1119 switch (uid.type) {
1120 case UA_BASE_DEVICE:
1121 snprintf(ua_string, sizeof(ua_string), "%02x",
1122 uid.real_unit_addr);
1123 break;
1124 case UA_BASE_PAV_ALIAS:
1125 snprintf(ua_string, sizeof(ua_string), "%02x",
1126 uid.base_unit_addr);
1127 break;
1128 case UA_HYPER_PAV_ALIAS:
1129 snprintf(ua_string, sizeof(ua_string), "xx");
1130 break;
1131 default:
1132 /* should not happen, treat like base device */
1133 snprintf(ua_string, sizeof(ua_string), "%02x",
1134 uid.real_unit_addr);
1135 break;
1136 }
1137
1138 if (strlen(uid.vduit) > 0)
1139 snprintf(uid_string, sizeof(uid_string),
1140 "%s.%s.%04x.%s.%s",
1141 uid.vendor, uid.serial, uid.ssid, ua_string,
1142 uid.vduit);
1143 else
1144 snprintf(uid_string, sizeof(uid_string),
1145 "%s.%s.%04x.%s",
1146 uid.vendor, uid.serial, uid.ssid, ua_string);
1147 }
1148 dasd_put_device(device);
1149
1150 return snprintf(buf, PAGE_SIZE, "%s\n", uid_string);
1151}
1152static DEVICE_ATTR(uid, 0444, dasd_uid_show, NULL);
1153
1154/*
1155 * extended error-reporting
1156 */
1157static ssize_t
1158dasd_eer_show(struct device *dev, struct device_attribute *attr, char *buf)
1159{
1160 struct dasd_devmap *devmap;
1161 int eer_flag;
1162
1163 devmap = dasd_find_busid(dev_name(dev));
1164 if (!IS_ERR(devmap) && devmap->device)
1165 eer_flag = dasd_eer_enabled(devmap->device);
1166 else
1167 eer_flag = 0;
1168 return snprintf(buf, PAGE_SIZE, eer_flag ? "1\n" : "0\n");
1169}
1170
1171static ssize_t
1172dasd_eer_store(struct device *dev, struct device_attribute *attr,
1173 const char *buf, size_t count)
1174{
1175 struct dasd_device *device;
1176 unsigned int val;
1177 int rc = 0;
1178
1179 device = dasd_device_from_cdev(to_ccwdev(dev));
1180 if (IS_ERR(device))
1181 return PTR_ERR(device);
1182
1183 if (kstrtouint(buf, 0, &val) || val > 1)
1184 return -EINVAL;
1185
1186 if (val)
1187 rc = dasd_eer_enable(device);
1188 else
1189 dasd_eer_disable(device);
1190
1191 dasd_put_device(device);
1192
1193 return rc ? : count;
1194}
1195
1196static DEVICE_ATTR(eer_enabled, 0644, dasd_eer_show, dasd_eer_store);
1197
1198/*
1199 * expiration time for default requests
1200 */
1201static ssize_t
1202dasd_expires_show(struct device *dev, struct device_attribute *attr, char *buf)
1203{
1204 struct dasd_device *device;
1205 int len;
1206
1207 device = dasd_device_from_cdev(to_ccwdev(dev));
1208 if (IS_ERR(device))
1209 return -ENODEV;
1210 len = snprintf(buf, PAGE_SIZE, "%lu\n", device->default_expires);
1211 dasd_put_device(device);
1212 return len;
1213}
1214
1215static ssize_t
1216dasd_expires_store(struct device *dev, struct device_attribute *attr,
1217 const char *buf, size_t count)
1218{
1219 struct dasd_device *device;
1220 unsigned long val;
1221
1222 device = dasd_device_from_cdev(to_ccwdev(dev));
1223 if (IS_ERR(device))
1224 return -ENODEV;
1225
1226 if ((kstrtoul(buf, 10, &val) != 0) ||
1227 (val > DASD_EXPIRES_MAX) || val == 0) {
1228 dasd_put_device(device);
1229 return -EINVAL;
1230 }
1231
1232 if (val)
1233 device->default_expires = val;
1234
1235 dasd_put_device(device);
1236 return count;
1237}
1238
1239static DEVICE_ATTR(expires, 0644, dasd_expires_show, dasd_expires_store);
1240
1241static ssize_t
1242dasd_retries_show(struct device *dev, struct device_attribute *attr, char *buf)
1243{
1244 struct dasd_device *device;
1245 int len;
1246
1247 device = dasd_device_from_cdev(to_ccwdev(dev));
1248 if (IS_ERR(device))
1249 return -ENODEV;
1250 len = snprintf(buf, PAGE_SIZE, "%lu\n", device->default_retries);
1251 dasd_put_device(device);
1252 return len;
1253}
1254
1255static ssize_t
1256dasd_retries_store(struct device *dev, struct device_attribute *attr,
1257 const char *buf, size_t count)
1258{
1259 struct dasd_device *device;
1260 unsigned long val;
1261
1262 device = dasd_device_from_cdev(to_ccwdev(dev));
1263 if (IS_ERR(device))
1264 return -ENODEV;
1265
1266 if ((kstrtoul(buf, 10, &val) != 0) ||
1267 (val > DASD_RETRIES_MAX)) {
1268 dasd_put_device(device);
1269 return -EINVAL;
1270 }
1271
1272 if (val)
1273 device->default_retries = val;
1274
1275 dasd_put_device(device);
1276 return count;
1277}
1278
1279static DEVICE_ATTR(retries, 0644, dasd_retries_show, dasd_retries_store);
1280
1281static ssize_t
1282dasd_timeout_show(struct device *dev, struct device_attribute *attr,
1283 char *buf)
1284{
1285 struct dasd_device *device;
1286 int len;
1287
1288 device = dasd_device_from_cdev(to_ccwdev(dev));
1289 if (IS_ERR(device))
1290 return -ENODEV;
1291 len = snprintf(buf, PAGE_SIZE, "%lu\n", device->blk_timeout);
1292 dasd_put_device(device);
1293 return len;
1294}
1295
1296static ssize_t
1297dasd_timeout_store(struct device *dev, struct device_attribute *attr,
1298 const char *buf, size_t count)
1299{
1300 struct dasd_device *device;
1301 struct request_queue *q;
1302 unsigned long val, flags;
1303
1304 device = dasd_device_from_cdev(to_ccwdev(dev));
1305 if (IS_ERR(device) || !device->block)
1306 return -ENODEV;
1307
1308 if ((kstrtoul(buf, 10, &val) != 0) ||
1309 val > UINT_MAX / HZ) {
1310 dasd_put_device(device);
1311 return -EINVAL;
1312 }
1313 q = device->block->request_queue;
1314 if (!q) {
1315 dasd_put_device(device);
1316 return -ENODEV;
1317 }
1318 spin_lock_irqsave(&device->block->request_queue_lock, flags);
1319 if (!val)
1320 blk_queue_rq_timed_out(q, NULL);
1321 else
1322 blk_queue_rq_timed_out(q, dasd_times_out);
1323
1324 device->blk_timeout = val;
1325
1326 blk_queue_rq_timeout(q, device->blk_timeout * HZ);
1327 spin_unlock_irqrestore(&device->block->request_queue_lock, flags);
1328
1329 dasd_put_device(device);
1330 return count;
1331}
1332
1333static DEVICE_ATTR(timeout, 0644,
1334 dasd_timeout_show, dasd_timeout_store);
1335
1336
1337static ssize_t
1338dasd_path_reset_store(struct device *dev, struct device_attribute *attr,
1339 const char *buf, size_t count)
1340{
1341 struct dasd_device *device;
1342 unsigned int val;
1343
1344 device = dasd_device_from_cdev(to_ccwdev(dev));
1345 if (IS_ERR(device))
1346 return -ENODEV;
1347
1348 if ((kstrtouint(buf, 16, &val) != 0) || val > 0xff)
1349 val = 0;
1350
1351 if (device->discipline && device->discipline->reset_path)
1352 device->discipline->reset_path(device, (__u8) val);
1353
1354 dasd_put_device(device);
1355 return count;
1356}
1357
1358static DEVICE_ATTR(path_reset, 0200, NULL, dasd_path_reset_store);
1359
1360static ssize_t dasd_hpf_show(struct device *dev, struct device_attribute *attr,
1361 char *buf)
1362{
1363 struct dasd_device *device;
1364 int hpf;
1365
1366 device = dasd_device_from_cdev(to_ccwdev(dev));
1367 if (IS_ERR(device))
1368 return -ENODEV;
1369 if (!device->discipline || !device->discipline->hpf_enabled) {
1370 dasd_put_device(device);
1371 return snprintf(buf, PAGE_SIZE, "%d\n", dasd_nofcx);
1372 }
1373 hpf = device->discipline->hpf_enabled(device);
1374 dasd_put_device(device);
1375 return snprintf(buf, PAGE_SIZE, "%d\n", hpf);
1376}
1377
1378static DEVICE_ATTR(hpf, 0444, dasd_hpf_show, NULL);
1379
1380static ssize_t dasd_reservation_policy_show(struct device *dev,
1381 struct device_attribute *attr,
1382 char *buf)
1383{
1384 struct dasd_devmap *devmap;
1385 int rc = 0;
1386
1387 devmap = dasd_find_busid(dev_name(dev));
1388 if (IS_ERR(devmap)) {
1389 rc = snprintf(buf, PAGE_SIZE, "ignore\n");
1390 } else {
1391 spin_lock(&dasd_devmap_lock);
1392 if (devmap->features & DASD_FEATURE_FAILONSLCK)
1393 rc = snprintf(buf, PAGE_SIZE, "fail\n");
1394 else
1395 rc = snprintf(buf, PAGE_SIZE, "ignore\n");
1396 spin_unlock(&dasd_devmap_lock);
1397 }
1398 return rc;
1399}
1400
1401static ssize_t dasd_reservation_policy_store(struct device *dev,
1402 struct device_attribute *attr,
1403 const char *buf, size_t count)
1404{
1405 struct ccw_device *cdev = to_ccwdev(dev);
1406 int rc;
1407
1408 if (sysfs_streq("ignore", buf))
1409 rc = dasd_set_feature(cdev, DASD_FEATURE_FAILONSLCK, 0);
1410 else if (sysfs_streq("fail", buf))
1411 rc = dasd_set_feature(cdev, DASD_FEATURE_FAILONSLCK, 1);
1412 else
1413 rc = -EINVAL;
1414
1415 return rc ? : count;
1416}
1417
1418static DEVICE_ATTR(reservation_policy, 0644,
1419 dasd_reservation_policy_show, dasd_reservation_policy_store);
1420
1421static ssize_t dasd_reservation_state_show(struct device *dev,
1422 struct device_attribute *attr,
1423 char *buf)
1424{
1425 struct dasd_device *device;
1426 int rc = 0;
1427
1428 device = dasd_device_from_cdev(to_ccwdev(dev));
1429 if (IS_ERR(device))
1430 return snprintf(buf, PAGE_SIZE, "none\n");
1431
1432 if (test_bit(DASD_FLAG_IS_RESERVED, &device->flags))
1433 rc = snprintf(buf, PAGE_SIZE, "reserved\n");
1434 else if (test_bit(DASD_FLAG_LOCK_STOLEN, &device->flags))
1435 rc = snprintf(buf, PAGE_SIZE, "lost\n");
1436 else
1437 rc = snprintf(buf, PAGE_SIZE, "none\n");
1438 dasd_put_device(device);
1439 return rc;
1440}
1441
1442static ssize_t dasd_reservation_state_store(struct device *dev,
1443 struct device_attribute *attr,
1444 const char *buf, size_t count)
1445{
1446 struct dasd_device *device;
1447 int rc = 0;
1448
1449 device = dasd_device_from_cdev(to_ccwdev(dev));
1450 if (IS_ERR(device))
1451 return -ENODEV;
1452 if (sysfs_streq("reset", buf))
1453 clear_bit(DASD_FLAG_LOCK_STOLEN, &device->flags);
1454 else
1455 rc = -EINVAL;
1456 dasd_put_device(device);
1457
1458 if (rc)
1459 return rc;
1460 else
1461 return count;
1462}
1463
1464static DEVICE_ATTR(last_known_reservation_state, 0644,
1465 dasd_reservation_state_show, dasd_reservation_state_store);
1466
1467static ssize_t dasd_pm_show(struct device *dev,
1468 struct device_attribute *attr, char *buf)
1469{
1470 struct dasd_device *device;
1471 u8 opm, nppm, cablepm, cuirpm, hpfpm, ifccpm;
1472
1473 device = dasd_device_from_cdev(to_ccwdev(dev));
1474 if (IS_ERR(device))
1475 return sprintf(buf, "0\n");
1476
1477 opm = dasd_path_get_opm(device);
1478 nppm = dasd_path_get_nppm(device);
1479 cablepm = dasd_path_get_cablepm(device);
1480 cuirpm = dasd_path_get_cuirpm(device);
1481 hpfpm = dasd_path_get_hpfpm(device);
1482 ifccpm = dasd_path_get_ifccpm(device);
1483 dasd_put_device(device);
1484
1485 return sprintf(buf, "%02x %02x %02x %02x %02x %02x\n", opm, nppm,
1486 cablepm, cuirpm, hpfpm, ifccpm);
1487}
1488
1489static DEVICE_ATTR(path_masks, 0444, dasd_pm_show, NULL);
1490
1491/*
1492 * threshold value for IFCC/CCC errors
1493 */
1494static ssize_t
1495dasd_path_threshold_show(struct device *dev,
1496 struct device_attribute *attr, char *buf)
1497{
1498 struct dasd_device *device;
1499 int len;
1500
1501 device = dasd_device_from_cdev(to_ccwdev(dev));
1502 if (IS_ERR(device))
1503 return -ENODEV;
1504 len = snprintf(buf, PAGE_SIZE, "%lu\n", device->path_thrhld);
1505 dasd_put_device(device);
1506 return len;
1507}
1508
1509static ssize_t
1510dasd_path_threshold_store(struct device *dev, struct device_attribute *attr,
1511 const char *buf, size_t count)
1512{
1513 struct dasd_device *device;
1514 unsigned long flags;
1515 unsigned long val;
1516
1517 device = dasd_device_from_cdev(to_ccwdev(dev));
1518 if (IS_ERR(device))
1519 return -ENODEV;
1520
1521 if (kstrtoul(buf, 10, &val) != 0 || val > DASD_THRHLD_MAX) {
1522 dasd_put_device(device);
1523 return -EINVAL;
1524 }
1525 spin_lock_irqsave(get_ccwdev_lock(to_ccwdev(dev)), flags);
1526 device->path_thrhld = val;
1527 spin_unlock_irqrestore(get_ccwdev_lock(to_ccwdev(dev)), flags);
1528 dasd_put_device(device);
1529 return count;
1530}
1531
1532static DEVICE_ATTR(path_threshold, 0644, dasd_path_threshold_show,
1533 dasd_path_threshold_store);
1534/*
1535 * interval for IFCC/CCC checks
1536 * meaning time with no IFCC/CCC error before the error counter
1537 * gets reset
1538 */
1539static ssize_t
1540dasd_path_interval_show(struct device *dev,
1541 struct device_attribute *attr, char *buf)
1542{
1543 struct dasd_device *device;
1544 int len;
1545
1546 device = dasd_device_from_cdev(to_ccwdev(dev));
1547 if (IS_ERR(device))
1548 return -ENODEV;
1549 len = snprintf(buf, PAGE_SIZE, "%lu\n", device->path_interval);
1550 dasd_put_device(device);
1551 return len;
1552}
1553
1554static ssize_t
1555dasd_path_interval_store(struct device *dev, struct device_attribute *attr,
1556 const char *buf, size_t count)
1557{
1558 struct dasd_device *device;
1559 unsigned long flags;
1560 unsigned long val;
1561
1562 device = dasd_device_from_cdev(to_ccwdev(dev));
1563 if (IS_ERR(device))
1564 return -ENODEV;
1565
1566 if ((kstrtoul(buf, 10, &val) != 0) ||
1567 (val > DASD_INTERVAL_MAX) || val == 0) {
1568 dasd_put_device(device);
1569 return -EINVAL;
1570 }
1571 spin_lock_irqsave(get_ccwdev_lock(to_ccwdev(dev)), flags);
1572 if (val)
1573 device->path_interval = val;
1574 spin_unlock_irqrestore(get_ccwdev_lock(to_ccwdev(dev)), flags);
1575 dasd_put_device(device);
1576 return count;
1577}
1578
1579static DEVICE_ATTR(path_interval, 0644, dasd_path_interval_show,
1580 dasd_path_interval_store);
1581
1582
1583static struct attribute * dasd_attrs[] = {
1584 &dev_attr_readonly.attr,
1585 &dev_attr_discipline.attr,
1586 &dev_attr_status.attr,
1587 &dev_attr_alias.attr,
1588 &dev_attr_vendor.attr,
1589 &dev_attr_uid.attr,
1590 &dev_attr_use_diag.attr,
1591 &dev_attr_raw_track_access.attr,
1592 &dev_attr_eer_enabled.attr,
1593 &dev_attr_erplog.attr,
1594 &dev_attr_failfast.attr,
1595 &dev_attr_expires.attr,
1596 &dev_attr_retries.attr,
1597 &dev_attr_timeout.attr,
1598 &dev_attr_reservation_policy.attr,
1599 &dev_attr_last_known_reservation_state.attr,
1600 &dev_attr_safe_offline.attr,
1601 &dev_attr_host_access_count.attr,
1602 &dev_attr_path_masks.attr,
1603 &dev_attr_path_threshold.attr,
1604 &dev_attr_path_interval.attr,
1605 &dev_attr_path_reset.attr,
1606 &dev_attr_hpf.attr,
1607 NULL,
1608};
1609
1610static struct attribute_group dasd_attr_group = {
1611 .attrs = dasd_attrs,
1612};
1613
1614/*
1615 * Return value of the specified feature.
1616 */
1617int
1618dasd_get_feature(struct ccw_device *cdev, int feature)
1619{
1620 struct dasd_devmap *devmap;
1621
1622 devmap = dasd_find_busid(dev_name(&cdev->dev));
1623 if (IS_ERR(devmap))
1624 return PTR_ERR(devmap);
1625
1626 return ((devmap->features & feature) != 0);
1627}
1628
1629/*
1630 * Set / reset given feature.
1631 * Flag indicates whether to set (!=0) or the reset (=0) the feature.
1632 */
1633int
1634dasd_set_feature(struct ccw_device *cdev, int feature, int flag)
1635{
1636 struct dasd_devmap *devmap;
1637
1638 devmap = dasd_devmap_from_cdev(cdev);
1639 if (IS_ERR(devmap))
1640 return PTR_ERR(devmap);
1641
1642 spin_lock(&dasd_devmap_lock);
1643 if (flag)
1644 devmap->features |= feature;
1645 else
1646 devmap->features &= ~feature;
1647 if (devmap->device)
1648 devmap->device->features = devmap->features;
1649 spin_unlock(&dasd_devmap_lock);
1650 return 0;
1651}
1652
1653
1654int
1655dasd_add_sysfs_files(struct ccw_device *cdev)
1656{
1657 return sysfs_create_group(&cdev->dev.kobj, &dasd_attr_group);
1658}
1659
1660void
1661dasd_remove_sysfs_files(struct ccw_device *cdev)
1662{
1663 sysfs_remove_group(&cdev->dev.kobj, &dasd_attr_group);
1664}
1665
1666
1667int
1668dasd_devmap_init(void)
1669{
1670 int i;
1671
1672 /* Initialize devmap structures. */
1673 dasd_max_devindex = 0;
1674 for (i = 0; i < 256; i++)
1675 INIT_LIST_HEAD(&dasd_hashlists[i]);
1676 return 0;
1677}
1678
1679void
1680dasd_devmap_exit(void)
1681{
1682 dasd_forget_ranges();
1683}