linux/drivers/s390/block/dasd_devmap.c
<<
>>
Prefs
   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 > 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        int rc = 0;
 319        char *tmp;
 320
 321        tmp = kstrdup(range, GFP_KERNEL);
 322        if (!tmp)
 323                return -ENOMEM;
 324
 325        if (dasd_evaluate_range_param(tmp, &from_str, &to_str, &features_str)) {
 326                rc = -EINVAL;
 327                goto out;
 328        }
 329
 330        if (dasd_busid(from_str, &from_id0, &from_id1, &from)) {
 331                rc = -EINVAL;
 332                goto out;
 333        }
 334
 335        to = from;
 336        to_id0 = from_id0;
 337        to_id1 = from_id1;
 338        if (to_str) {
 339                if (dasd_busid(to_str, &to_id0, &to_id1, &to)) {
 340                        rc = -EINVAL;
 341                        goto out;
 342                }
 343                if (from_id0 != to_id0 || from_id1 != to_id1 || from > to) {
 344                        pr_err("%s is not a valid device range\n", range);
 345                        rc = -EINVAL;
 346                        goto out;
 347                }
 348        }
 349
 350        features = dasd_feature_list(features_str);
 351        if (features < 0) {
 352                rc = -EINVAL;
 353                goto out;
 354        }
 355        /* each device in dasd= parameter should be set initially online */
 356        features |= DASD_FEATURE_INITIAL_ONLINE;
 357        while (from <= to) {
 358                sprintf(bus_id, "%01x.%01x.%04x", from_id0, from_id1, from++);
 359                devmap = dasd_add_busid(bus_id, features);
 360                if (IS_ERR(devmap)) {
 361                        rc = PTR_ERR(devmap);
 362                        goto out;
 363                }
 364        }
 365
 366out:
 367        kfree(tmp);
 368
 369        return rc;
 370}
 371
 372/*
 373 * Parse parameters stored in dasd[]
 374 * The 'dasd=...' parameter allows to specify a comma separated list of
 375 * keywords and device ranges. The parameters in that list will be stored as
 376 * separate elementes in dasd[].
 377 */
 378int __init dasd_parse(void)
 379{
 380        int rc, i;
 381        char *cur;
 382
 383        rc = 0;
 384        for (i = 0; i < DASD_MAX_PARAMS; i++) {
 385                cur = dasd[i];
 386                if (!cur)
 387                        break;
 388                if (*cur == '\0')
 389                        continue;
 390
 391                rc = dasd_parse_keyword(cur);
 392                if (rc)
 393                        rc = dasd_parse_range(cur);
 394
 395                if (rc)
 396                        break;
 397        }
 398
 399        return rc;
 400}
 401
 402/*
 403 * Add a devmap for the device specified by busid. It is possible that
 404 * the devmap already exists (dasd= parameter). The order of the devices
 405 * added through this function will define the kdevs for the individual
 406 * devices.
 407 */
 408static struct dasd_devmap *
 409dasd_add_busid(const char *bus_id, int features)
 410{
 411        struct dasd_devmap *devmap, *new, *tmp;
 412        int hash;
 413
 414        new = kzalloc(sizeof(struct dasd_devmap), GFP_KERNEL);
 415        if (!new)
 416                return ERR_PTR(-ENOMEM);
 417        spin_lock(&dasd_devmap_lock);
 418        devmap = NULL;
 419        hash = dasd_hash_busid(bus_id);
 420        list_for_each_entry(tmp, &dasd_hashlists[hash], list)
 421                if (strncmp(tmp->bus_id, bus_id, DASD_BUS_ID_SIZE) == 0) {
 422                        devmap = tmp;
 423                        break;
 424                }
 425        if (!devmap) {
 426                /* This bus_id is new. */
 427                new->devindex = dasd_max_devindex++;
 428                strncpy(new->bus_id, bus_id, DASD_BUS_ID_SIZE);
 429                new->features = features;
 430                new->device = NULL;
 431                list_add(&new->list, &dasd_hashlists[hash]);
 432                devmap = new;
 433                new = NULL;
 434        }
 435        spin_unlock(&dasd_devmap_lock);
 436        kfree(new);
 437        return devmap;
 438}
 439
 440/*
 441 * Find devmap for device with given bus_id.
 442 */
 443static struct dasd_devmap *
 444dasd_find_busid(const char *bus_id)
 445{
 446        struct dasd_devmap *devmap, *tmp;
 447        int hash;
 448
 449        spin_lock(&dasd_devmap_lock);
 450        devmap = ERR_PTR(-ENODEV);
 451        hash = dasd_hash_busid(bus_id);
 452        list_for_each_entry(tmp, &dasd_hashlists[hash], list) {
 453                if (strncmp(tmp->bus_id, bus_id, DASD_BUS_ID_SIZE) == 0) {
 454                        devmap = tmp;
 455                        break;
 456                }
 457        }
 458        spin_unlock(&dasd_devmap_lock);
 459        return devmap;
 460}
 461
 462/*
 463 * Check if busid has been added to the list of dasd ranges.
 464 */
 465int
 466dasd_busid_known(const char *bus_id)
 467{
 468        return IS_ERR(dasd_find_busid(bus_id)) ? -ENOENT : 0;
 469}
 470
 471/*
 472 * Forget all about the device numbers added so far.
 473 * This may only be called at module unload or system shutdown.
 474 */
 475static void
 476dasd_forget_ranges(void)
 477{
 478        struct dasd_devmap *devmap, *n;
 479        int i;
 480
 481        spin_lock(&dasd_devmap_lock);
 482        for (i = 0; i < 256; i++) {
 483                list_for_each_entry_safe(devmap, n, &dasd_hashlists[i], list) {
 484                        BUG_ON(devmap->device != NULL);
 485                        list_del(&devmap->list);
 486                        kfree(devmap);
 487                }
 488        }
 489        spin_unlock(&dasd_devmap_lock);
 490}
 491
 492/*
 493 * Find the device struct by its device index.
 494 */
 495struct dasd_device *
 496dasd_device_from_devindex(int devindex)
 497{
 498        struct dasd_devmap *devmap, *tmp;
 499        struct dasd_device *device;
 500        int i;
 501
 502        spin_lock(&dasd_devmap_lock);
 503        devmap = NULL;
 504        for (i = 0; (i < 256) && !devmap; i++)
 505                list_for_each_entry(tmp, &dasd_hashlists[i], list)
 506                        if (tmp->devindex == devindex) {
 507                                /* Found the devmap for the device. */
 508                                devmap = tmp;
 509                                break;
 510                        }
 511        if (devmap && devmap->device) {
 512                device = devmap->device;
 513                dasd_get_device(device);
 514        } else
 515                device = ERR_PTR(-ENODEV);
 516        spin_unlock(&dasd_devmap_lock);
 517        return device;
 518}
 519
 520/*
 521 * Return devmap for cdev. If no devmap exists yet, create one and
 522 * connect it to the cdev.
 523 */
 524static struct dasd_devmap *
 525dasd_devmap_from_cdev(struct ccw_device *cdev)
 526{
 527        struct dasd_devmap *devmap;
 528
 529        devmap = dasd_find_busid(dev_name(&cdev->dev));
 530        if (IS_ERR(devmap))
 531                devmap = dasd_add_busid(dev_name(&cdev->dev),
 532                                        DASD_FEATURE_DEFAULT);
 533        return devmap;
 534}
 535
 536/*
 537 * Create a dasd device structure for cdev.
 538 */
 539struct dasd_device *
 540dasd_create_device(struct ccw_device *cdev)
 541{
 542        struct dasd_devmap *devmap;
 543        struct dasd_device *device;
 544        unsigned long flags;
 545        int rc;
 546
 547        devmap = dasd_devmap_from_cdev(cdev);
 548        if (IS_ERR(devmap))
 549                return (void *) devmap;
 550
 551        device = dasd_alloc_device();
 552        if (IS_ERR(device))
 553                return device;
 554        atomic_set(&device->ref_count, 3);
 555
 556        spin_lock(&dasd_devmap_lock);
 557        if (!devmap->device) {
 558                devmap->device = device;
 559                device->devindex = devmap->devindex;
 560                device->features = devmap->features;
 561                get_device(&cdev->dev);
 562                device->cdev = cdev;
 563                rc = 0;
 564        } else
 565                /* Someone else was faster. */
 566                rc = -EBUSY;
 567        spin_unlock(&dasd_devmap_lock);
 568
 569        if (rc) {
 570                dasd_free_device(device);
 571                return ERR_PTR(rc);
 572        }
 573
 574        spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
 575        dev_set_drvdata(&cdev->dev, device);
 576        spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
 577
 578        return device;
 579}
 580
 581/*
 582 * Wait queue for dasd_delete_device waits.
 583 */
 584static DECLARE_WAIT_QUEUE_HEAD(dasd_delete_wq);
 585
 586/*
 587 * Remove a dasd device structure. The passed referenced
 588 * is destroyed.
 589 */
 590void
 591dasd_delete_device(struct dasd_device *device)
 592{
 593        struct ccw_device *cdev;
 594        struct dasd_devmap *devmap;
 595        unsigned long flags;
 596
 597        /* First remove device pointer from devmap. */
 598        devmap = dasd_find_busid(dev_name(&device->cdev->dev));
 599        BUG_ON(IS_ERR(devmap));
 600        spin_lock(&dasd_devmap_lock);
 601        if (devmap->device != device) {
 602                spin_unlock(&dasd_devmap_lock);
 603                dasd_put_device(device);
 604                return;
 605        }
 606        devmap->device = NULL;
 607        spin_unlock(&dasd_devmap_lock);
 608
 609        /* Disconnect dasd_device structure from ccw_device structure. */
 610        spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
 611        dev_set_drvdata(&device->cdev->dev, NULL);
 612        spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
 613
 614        /*
 615         * Drop ref_count by 3, one for the devmap reference, one for
 616         * the cdev reference and one for the passed reference.
 617         */
 618        atomic_sub(3, &device->ref_count);
 619
 620        /* Wait for reference counter to drop to zero. */
 621        wait_event(dasd_delete_wq, atomic_read(&device->ref_count) == 0);
 622
 623        dasd_generic_free_discipline(device);
 624        /* Disconnect dasd_device structure from ccw_device structure. */
 625        cdev = device->cdev;
 626        device->cdev = NULL;
 627
 628        /* Put ccw_device structure. */
 629        put_device(&cdev->dev);
 630
 631        /* Now the device structure can be freed. */
 632        dasd_free_device(device);
 633}
 634
 635/*
 636 * Reference counter dropped to zero. Wake up waiter
 637 * in dasd_delete_device.
 638 */
 639void
 640dasd_put_device_wake(struct dasd_device *device)
 641{
 642        wake_up(&dasd_delete_wq);
 643}
 644EXPORT_SYMBOL_GPL(dasd_put_device_wake);
 645
 646/*
 647 * Return dasd_device structure associated with cdev.
 648 * This function needs to be called with the ccw device
 649 * lock held. It can be used from interrupt context.
 650 */
 651struct dasd_device *
 652dasd_device_from_cdev_locked(struct ccw_device *cdev)
 653{
 654        struct dasd_device *device = dev_get_drvdata(&cdev->dev);
 655
 656        if (!device)
 657                return ERR_PTR(-ENODEV);
 658        dasd_get_device(device);
 659        return device;
 660}
 661
 662/*
 663 * Return dasd_device structure associated with cdev.
 664 */
 665struct dasd_device *
 666dasd_device_from_cdev(struct ccw_device *cdev)
 667{
 668        struct dasd_device *device;
 669        unsigned long flags;
 670
 671        spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
 672        device = dasd_device_from_cdev_locked(cdev);
 673        spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
 674        return device;
 675}
 676
 677void dasd_add_link_to_gendisk(struct gendisk *gdp, struct dasd_device *device)
 678{
 679        struct dasd_devmap *devmap;
 680
 681        devmap = dasd_find_busid(dev_name(&device->cdev->dev));
 682        if (IS_ERR(devmap))
 683                return;
 684        spin_lock(&dasd_devmap_lock);
 685        gdp->private_data = devmap;
 686        spin_unlock(&dasd_devmap_lock);
 687}
 688
 689struct dasd_device *dasd_device_from_gendisk(struct gendisk *gdp)
 690{
 691        struct dasd_device *device;
 692        struct dasd_devmap *devmap;
 693
 694        if (!gdp->private_data)
 695                return NULL;
 696        device = NULL;
 697        spin_lock(&dasd_devmap_lock);
 698        devmap = gdp->private_data;
 699        if (devmap && devmap->device) {
 700                device = devmap->device;
 701                dasd_get_device(device);
 702        }
 703        spin_unlock(&dasd_devmap_lock);
 704        return device;
 705}
 706
 707/*
 708 * SECTION: files in sysfs
 709 */
 710
 711/*
 712 * failfast controls the behaviour, if no path is available
 713 */
 714static ssize_t dasd_ff_show(struct device *dev, struct device_attribute *attr,
 715                            char *buf)
 716{
 717        struct dasd_devmap *devmap;
 718        int ff_flag;
 719
 720        devmap = dasd_find_busid(dev_name(dev));
 721        if (!IS_ERR(devmap))
 722                ff_flag = (devmap->features & DASD_FEATURE_FAILFAST) != 0;
 723        else
 724                ff_flag = (DASD_FEATURE_DEFAULT & DASD_FEATURE_FAILFAST) != 0;
 725        return snprintf(buf, PAGE_SIZE, ff_flag ? "1\n" : "0\n");
 726}
 727
 728static ssize_t dasd_ff_store(struct device *dev, struct device_attribute *attr,
 729              const char *buf, size_t count)
 730{
 731        unsigned int val;
 732        int rc;
 733
 734        if (kstrtouint(buf, 0, &val) || val > 1)
 735                return -EINVAL;
 736
 737        rc = dasd_set_feature(to_ccwdev(dev), DASD_FEATURE_FAILFAST, val);
 738
 739        return rc ? : count;
 740}
 741
 742static DEVICE_ATTR(failfast, 0644, dasd_ff_show, dasd_ff_store);
 743
 744/*
 745 * readonly controls the readonly status of a dasd
 746 */
 747static ssize_t
 748dasd_ro_show(struct device *dev, struct device_attribute *attr, char *buf)
 749{
 750        struct dasd_devmap *devmap;
 751        struct dasd_device *device;
 752        int ro_flag = 0;
 753
 754        devmap = dasd_find_busid(dev_name(dev));
 755        if (IS_ERR(devmap))
 756                goto out;
 757
 758        ro_flag = !!(devmap->features & DASD_FEATURE_READONLY);
 759
 760        spin_lock(&dasd_devmap_lock);
 761        device = devmap->device;
 762        if (device)
 763                ro_flag |= test_bit(DASD_FLAG_DEVICE_RO, &device->flags);
 764        spin_unlock(&dasd_devmap_lock);
 765
 766out:
 767        return snprintf(buf, PAGE_SIZE, ro_flag ? "1\n" : "0\n");
 768}
 769
 770static ssize_t
 771dasd_ro_store(struct device *dev, struct device_attribute *attr,
 772              const char *buf, size_t count)
 773{
 774        struct ccw_device *cdev = to_ccwdev(dev);
 775        struct dasd_device *device;
 776        unsigned long flags;
 777        unsigned int val;
 778        int rc;
 779
 780        if (kstrtouint(buf, 0, &val) || val > 1)
 781                return -EINVAL;
 782
 783        rc = dasd_set_feature(cdev, DASD_FEATURE_READONLY, val);
 784        if (rc)
 785                return rc;
 786
 787        device = dasd_device_from_cdev(cdev);
 788        if (IS_ERR(device))
 789                return count;
 790
 791        spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
 792        val = val || test_bit(DASD_FLAG_DEVICE_RO, &device->flags);
 793
 794        if (!device->block || !device->block->gdp ||
 795            test_bit(DASD_FLAG_OFFLINE, &device->flags)) {
 796                spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
 797                goto out;
 798        }
 799        /* Increase open_count to avoid losing the block device */
 800        atomic_inc(&device->block->open_count);
 801        spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
 802
 803        set_disk_ro(device->block->gdp, val);
 804        atomic_dec(&device->block->open_count);
 805
 806out:
 807        dasd_put_device(device);
 808
 809        return count;
 810}
 811
 812static DEVICE_ATTR(readonly, 0644, dasd_ro_show, dasd_ro_store);
 813/*
 814 * erplog controls the logging of ERP related data
 815 * (e.g. failing channel programs).
 816 */
 817static ssize_t
 818dasd_erplog_show(struct device *dev, struct device_attribute *attr, char *buf)
 819{
 820        struct dasd_devmap *devmap;
 821        int erplog;
 822
 823        devmap = dasd_find_busid(dev_name(dev));
 824        if (!IS_ERR(devmap))
 825                erplog = (devmap->features & DASD_FEATURE_ERPLOG) != 0;
 826        else
 827                erplog = (DASD_FEATURE_DEFAULT & DASD_FEATURE_ERPLOG) != 0;
 828        return snprintf(buf, PAGE_SIZE, erplog ? "1\n" : "0\n");
 829}
 830
 831static ssize_t
 832dasd_erplog_store(struct device *dev, struct device_attribute *attr,
 833              const char *buf, size_t count)
 834{
 835        unsigned int val;
 836        int rc;
 837
 838        if (kstrtouint(buf, 0, &val) || val > 1)
 839                return -EINVAL;
 840
 841        rc = dasd_set_feature(to_ccwdev(dev), DASD_FEATURE_ERPLOG, val);
 842
 843        return rc ? : count;
 844}
 845
 846static DEVICE_ATTR(erplog, 0644, dasd_erplog_show, dasd_erplog_store);
 847
 848/*
 849 * use_diag controls whether the driver should use diag rather than ssch
 850 * to talk to the device
 851 */
 852static ssize_t
 853dasd_use_diag_show(struct device *dev, struct device_attribute *attr, char *buf)
 854{
 855        struct dasd_devmap *devmap;
 856        int use_diag;
 857
 858        devmap = dasd_find_busid(dev_name(dev));
 859        if (!IS_ERR(devmap))
 860                use_diag = (devmap->features & DASD_FEATURE_USEDIAG) != 0;
 861        else
 862                use_diag = (DASD_FEATURE_DEFAULT & DASD_FEATURE_USEDIAG) != 0;
 863        return sprintf(buf, use_diag ? "1\n" : "0\n");
 864}
 865
 866static ssize_t
 867dasd_use_diag_store(struct device *dev, struct device_attribute *attr,
 868                    const char *buf, size_t count)
 869{
 870        struct dasd_devmap *devmap;
 871        unsigned int val;
 872        ssize_t rc;
 873
 874        devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
 875        if (IS_ERR(devmap))
 876                return PTR_ERR(devmap);
 877
 878        if (kstrtouint(buf, 0, &val) || val > 1)
 879                return -EINVAL;
 880
 881        spin_lock(&dasd_devmap_lock);
 882        /* Changing diag discipline flag is only allowed in offline state. */
 883        rc = count;
 884        if (!devmap->device && !(devmap->features & DASD_FEATURE_USERAW)) {
 885                if (val)
 886                        devmap->features |= DASD_FEATURE_USEDIAG;
 887                else
 888                        devmap->features &= ~DASD_FEATURE_USEDIAG;
 889        } else
 890                rc = -EPERM;
 891        spin_unlock(&dasd_devmap_lock);
 892        return rc;
 893}
 894
 895static DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store);
 896
 897/*
 898 * use_raw controls whether the driver should give access to raw eckd data or
 899 * operate in standard mode
 900 */
 901static ssize_t
 902dasd_use_raw_show(struct device *dev, struct device_attribute *attr, char *buf)
 903{
 904        struct dasd_devmap *devmap;
 905        int use_raw;
 906
 907        devmap = dasd_find_busid(dev_name(dev));
 908        if (!IS_ERR(devmap))
 909                use_raw = (devmap->features & DASD_FEATURE_USERAW) != 0;
 910        else
 911                use_raw = (DASD_FEATURE_DEFAULT & DASD_FEATURE_USERAW) != 0;
 912        return sprintf(buf, use_raw ? "1\n" : "0\n");
 913}
 914
 915static ssize_t
 916dasd_use_raw_store(struct device *dev, struct device_attribute *attr,
 917                    const char *buf, size_t count)
 918{
 919        struct dasd_devmap *devmap;
 920        ssize_t rc;
 921        unsigned long val;
 922
 923        devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
 924        if (IS_ERR(devmap))
 925                return PTR_ERR(devmap);
 926
 927        if ((kstrtoul(buf, 10, &val) != 0) || val > 1)
 928                return -EINVAL;
 929
 930        spin_lock(&dasd_devmap_lock);
 931        /* Changing diag discipline flag is only allowed in offline state. */
 932        rc = count;
 933        if (!devmap->device && !(devmap->features & DASD_FEATURE_USEDIAG)) {
 934                if (val)
 935                        devmap->features |= DASD_FEATURE_USERAW;
 936                else
 937                        devmap->features &= ~DASD_FEATURE_USERAW;
 938        } else
 939                rc = -EPERM;
 940        spin_unlock(&dasd_devmap_lock);
 941        return rc;
 942}
 943
 944static DEVICE_ATTR(raw_track_access, 0644, dasd_use_raw_show,
 945                   dasd_use_raw_store);
 946
 947static ssize_t
 948dasd_safe_offline_store(struct device *dev, struct device_attribute *attr,
 949                        const char *buf, size_t count)
 950{
 951        struct ccw_device *cdev = to_ccwdev(dev);
 952        struct dasd_device *device;
 953        unsigned long flags;
 954        int rc;
 955
 956        spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
 957        device = dasd_device_from_cdev_locked(cdev);
 958        if (IS_ERR(device)) {
 959                rc = PTR_ERR(device);
 960                spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
 961                goto out;
 962        }
 963
 964        if (test_bit(DASD_FLAG_OFFLINE, &device->flags) ||
 965            test_bit(DASD_FLAG_SAFE_OFFLINE_RUNNING, &device->flags)) {
 966                /* Already doing offline processing */
 967                dasd_put_device(device);
 968                spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
 969                rc = -EBUSY;
 970                goto out;
 971        }
 972
 973        set_bit(DASD_FLAG_SAFE_OFFLINE, &device->flags);
 974        dasd_put_device(device);
 975        spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
 976
 977        rc = ccw_device_set_offline(cdev);
 978
 979out:
 980        return rc ? rc : count;
 981}
 982
 983static DEVICE_ATTR(safe_offline, 0200, NULL, dasd_safe_offline_store);
 984
 985static ssize_t
 986dasd_access_show(struct device *dev, struct device_attribute *attr,
 987                 char *buf)
 988{
 989        struct ccw_device *cdev = to_ccwdev(dev);
 990        struct dasd_device *device;
 991        int count;
 992
 993        device = dasd_device_from_cdev(cdev);
 994        if (IS_ERR(device))
 995                return PTR_ERR(device);
 996
 997        if (!device->discipline)
 998                count = -ENODEV;
 999        else if (!device->discipline->host_access_count)
1000                count = -EOPNOTSUPP;
1001        else
1002                count = device->discipline->host_access_count(device);
1003
1004        dasd_put_device(device);
1005        if (count < 0)
1006                return count;
1007
1008        return sprintf(buf, "%d\n", count);
1009}
1010
1011static DEVICE_ATTR(host_access_count, 0444, dasd_access_show, NULL);
1012
1013static ssize_t
1014dasd_discipline_show(struct device *dev, struct device_attribute *attr,
1015                     char *buf)
1016{
1017        struct dasd_device *device;
1018        ssize_t len;
1019
1020        device = dasd_device_from_cdev(to_ccwdev(dev));
1021        if (IS_ERR(device))
1022                goto out;
1023        else if (!device->discipline) {
1024                dasd_put_device(device);
1025                goto out;
1026        } else {
1027                len = snprintf(buf, PAGE_SIZE, "%s\n",
1028                               device->discipline->name);
1029                dasd_put_device(device);
1030                return len;
1031        }
1032out:
1033        len = snprintf(buf, PAGE_SIZE, "none\n");
1034        return len;
1035}
1036
1037static DEVICE_ATTR(discipline, 0444, dasd_discipline_show, NULL);
1038
1039static ssize_t
1040dasd_device_status_show(struct device *dev, struct device_attribute *attr,
1041                     char *buf)
1042{
1043        struct dasd_device *device;
1044        ssize_t len;
1045
1046        device = dasd_device_from_cdev(to_ccwdev(dev));
1047        if (!IS_ERR(device)) {
1048                switch (device->state) {
1049                case DASD_STATE_NEW:
1050                        len = snprintf(buf, PAGE_SIZE, "new\n");
1051                        break;
1052                case DASD_STATE_KNOWN:
1053                        len = snprintf(buf, PAGE_SIZE, "detected\n");
1054                        break;
1055                case DASD_STATE_BASIC:
1056                        len = snprintf(buf, PAGE_SIZE, "basic\n");
1057                        break;
1058                case DASD_STATE_UNFMT:
1059                        len = snprintf(buf, PAGE_SIZE, "unformatted\n");
1060                        break;
1061                case DASD_STATE_READY:
1062                        len = snprintf(buf, PAGE_SIZE, "ready\n");
1063                        break;
1064                case DASD_STATE_ONLINE:
1065                        len = snprintf(buf, PAGE_SIZE, "online\n");
1066                        break;
1067                default:
1068                        len = snprintf(buf, PAGE_SIZE, "no stat\n");
1069                        break;
1070                }
1071                dasd_put_device(device);
1072        } else
1073                len = snprintf(buf, PAGE_SIZE, "unknown\n");
1074        return len;
1075}
1076
1077static DEVICE_ATTR(status, 0444, dasd_device_status_show, NULL);
1078
1079static ssize_t dasd_alias_show(struct device *dev,
1080                               struct device_attribute *attr, char *buf)
1081{
1082        struct dasd_device *device;
1083        struct dasd_uid uid;
1084
1085        device = dasd_device_from_cdev(to_ccwdev(dev));
1086        if (IS_ERR(device))
1087                return sprintf(buf, "0\n");
1088
1089        if (device->discipline && device->discipline->get_uid &&
1090            !device->discipline->get_uid(device, &uid)) {
1091                if (uid.type == UA_BASE_PAV_ALIAS ||
1092                    uid.type == UA_HYPER_PAV_ALIAS) {
1093                        dasd_put_device(device);
1094                        return sprintf(buf, "1\n");
1095                }
1096        }
1097        dasd_put_device(device);
1098
1099        return sprintf(buf, "0\n");
1100}
1101
1102static DEVICE_ATTR(alias, 0444, dasd_alias_show, NULL);
1103
1104static ssize_t dasd_vendor_show(struct device *dev,
1105                                struct device_attribute *attr, char *buf)
1106{
1107        struct dasd_device *device;
1108        struct dasd_uid uid;
1109        char *vendor;
1110
1111        device = dasd_device_from_cdev(to_ccwdev(dev));
1112        vendor = "";
1113        if (IS_ERR(device))
1114                return snprintf(buf, PAGE_SIZE, "%s\n", vendor);
1115
1116        if (device->discipline && device->discipline->get_uid &&
1117            !device->discipline->get_uid(device, &uid))
1118                        vendor = uid.vendor;
1119
1120        dasd_put_device(device);
1121
1122        return snprintf(buf, PAGE_SIZE, "%s\n", vendor);
1123}
1124
1125static DEVICE_ATTR(vendor, 0444, dasd_vendor_show, NULL);
1126
1127#define UID_STRLEN ( /* vendor */ 3 + 1 + /* serial    */ 14 + 1 +\
1128                     /* SSID   */ 4 + 1 + /* unit addr */ 2 + 1 +\
1129                     /* vduit */ 32 + 1)
1130
1131static ssize_t
1132dasd_uid_show(struct device *dev, struct device_attribute *attr, char *buf)
1133{
1134        struct dasd_device *device;
1135        struct dasd_uid uid;
1136        char uid_string[UID_STRLEN];
1137        char ua_string[3];
1138
1139        device = dasd_device_from_cdev(to_ccwdev(dev));
1140        uid_string[0] = 0;
1141        if (IS_ERR(device))
1142                return snprintf(buf, PAGE_SIZE, "%s\n", uid_string);
1143
1144        if (device->discipline && device->discipline->get_uid &&
1145            !device->discipline->get_uid(device, &uid)) {
1146                switch (uid.type) {
1147                case UA_BASE_DEVICE:
1148                        snprintf(ua_string, sizeof(ua_string), "%02x",
1149                                 uid.real_unit_addr);
1150                        break;
1151                case UA_BASE_PAV_ALIAS:
1152                        snprintf(ua_string, sizeof(ua_string), "%02x",
1153                                 uid.base_unit_addr);
1154                        break;
1155                case UA_HYPER_PAV_ALIAS:
1156                        snprintf(ua_string, sizeof(ua_string), "xx");
1157                        break;
1158                default:
1159                        /* should not happen, treat like base device */
1160                        snprintf(ua_string, sizeof(ua_string), "%02x",
1161                                 uid.real_unit_addr);
1162                        break;
1163                }
1164
1165                if (strlen(uid.vduit) > 0)
1166                        snprintf(uid_string, sizeof(uid_string),
1167                                 "%s.%s.%04x.%s.%s",
1168                                 uid.vendor, uid.serial, uid.ssid, ua_string,
1169                                 uid.vduit);
1170                else
1171                        snprintf(uid_string, sizeof(uid_string),
1172                                 "%s.%s.%04x.%s",
1173                                 uid.vendor, uid.serial, uid.ssid, ua_string);
1174        }
1175        dasd_put_device(device);
1176
1177        return snprintf(buf, PAGE_SIZE, "%s\n", uid_string);
1178}
1179static DEVICE_ATTR(uid, 0444, dasd_uid_show, NULL);
1180
1181/*
1182 * extended error-reporting
1183 */
1184static ssize_t
1185dasd_eer_show(struct device *dev, struct device_attribute *attr, char *buf)
1186{
1187        struct dasd_devmap *devmap;
1188        int eer_flag;
1189
1190        devmap = dasd_find_busid(dev_name(dev));
1191        if (!IS_ERR(devmap) && devmap->device)
1192                eer_flag = dasd_eer_enabled(devmap->device);
1193        else
1194                eer_flag = 0;
1195        return snprintf(buf, PAGE_SIZE, eer_flag ? "1\n" : "0\n");
1196}
1197
1198static ssize_t
1199dasd_eer_store(struct device *dev, struct device_attribute *attr,
1200               const char *buf, size_t count)
1201{
1202        struct dasd_device *device;
1203        unsigned int val;
1204        int rc = 0;
1205
1206        device = dasd_device_from_cdev(to_ccwdev(dev));
1207        if (IS_ERR(device))
1208                return PTR_ERR(device);
1209
1210        if (kstrtouint(buf, 0, &val) || val > 1)
1211                return -EINVAL;
1212
1213        if (val)
1214                rc = dasd_eer_enable(device);
1215        else
1216                dasd_eer_disable(device);
1217
1218        dasd_put_device(device);
1219
1220        return rc ? : count;
1221}
1222
1223static DEVICE_ATTR(eer_enabled, 0644, dasd_eer_show, dasd_eer_store);
1224
1225/*
1226 * expiration time for default requests
1227 */
1228static ssize_t
1229dasd_expires_show(struct device *dev, struct device_attribute *attr, char *buf)
1230{
1231        struct dasd_device *device;
1232        int len;
1233
1234        device = dasd_device_from_cdev(to_ccwdev(dev));
1235        if (IS_ERR(device))
1236                return -ENODEV;
1237        len = snprintf(buf, PAGE_SIZE, "%lu\n", device->default_expires);
1238        dasd_put_device(device);
1239        return len;
1240}
1241
1242static ssize_t
1243dasd_expires_store(struct device *dev, struct device_attribute *attr,
1244               const char *buf, size_t count)
1245{
1246        struct dasd_device *device;
1247        unsigned long val;
1248
1249        device = dasd_device_from_cdev(to_ccwdev(dev));
1250        if (IS_ERR(device))
1251                return -ENODEV;
1252
1253        if ((kstrtoul(buf, 10, &val) != 0) ||
1254            (val > DASD_EXPIRES_MAX) || val == 0) {
1255                dasd_put_device(device);
1256                return -EINVAL;
1257        }
1258
1259        if (val)
1260                device->default_expires = val;
1261
1262        dasd_put_device(device);
1263        return count;
1264}
1265
1266static DEVICE_ATTR(expires, 0644, dasd_expires_show, dasd_expires_store);
1267
1268static ssize_t
1269dasd_retries_show(struct device *dev, struct device_attribute *attr, char *buf)
1270{
1271        struct dasd_device *device;
1272        int len;
1273
1274        device = dasd_device_from_cdev(to_ccwdev(dev));
1275        if (IS_ERR(device))
1276                return -ENODEV;
1277        len = snprintf(buf, PAGE_SIZE, "%lu\n", device->default_retries);
1278        dasd_put_device(device);
1279        return len;
1280}
1281
1282static ssize_t
1283dasd_retries_store(struct device *dev, struct device_attribute *attr,
1284                   const char *buf, size_t count)
1285{
1286        struct dasd_device *device;
1287        unsigned long val;
1288
1289        device = dasd_device_from_cdev(to_ccwdev(dev));
1290        if (IS_ERR(device))
1291                return -ENODEV;
1292
1293        if ((kstrtoul(buf, 10, &val) != 0) ||
1294            (val > DASD_RETRIES_MAX)) {
1295                dasd_put_device(device);
1296                return -EINVAL;
1297        }
1298
1299        if (val)
1300                device->default_retries = val;
1301
1302        dasd_put_device(device);
1303        return count;
1304}
1305
1306static DEVICE_ATTR(retries, 0644, dasd_retries_show, dasd_retries_store);
1307
1308static ssize_t
1309dasd_timeout_show(struct device *dev, struct device_attribute *attr,
1310                  char *buf)
1311{
1312        struct dasd_device *device;
1313        int len;
1314
1315        device = dasd_device_from_cdev(to_ccwdev(dev));
1316        if (IS_ERR(device))
1317                return -ENODEV;
1318        len = snprintf(buf, PAGE_SIZE, "%lu\n", device->blk_timeout);
1319        dasd_put_device(device);
1320        return len;
1321}
1322
1323static ssize_t
1324dasd_timeout_store(struct device *dev, struct device_attribute *attr,
1325                   const char *buf, size_t count)
1326{
1327        struct dasd_device *device;
1328        struct request_queue *q;
1329        unsigned long val;
1330
1331        device = dasd_device_from_cdev(to_ccwdev(dev));
1332        if (IS_ERR(device) || !device->block)
1333                return -ENODEV;
1334
1335        if ((kstrtoul(buf, 10, &val) != 0) ||
1336            val > UINT_MAX / HZ) {
1337                dasd_put_device(device);
1338                return -EINVAL;
1339        }
1340        q = device->block->request_queue;
1341        if (!q) {
1342                dasd_put_device(device);
1343                return -ENODEV;
1344        }
1345
1346        device->blk_timeout = val;
1347
1348        blk_queue_rq_timeout(q, device->blk_timeout * HZ);
1349
1350        dasd_put_device(device);
1351        return count;
1352}
1353
1354static DEVICE_ATTR(timeout, 0644,
1355                   dasd_timeout_show, dasd_timeout_store);
1356
1357
1358static ssize_t
1359dasd_path_reset_store(struct device *dev, struct device_attribute *attr,
1360                      const char *buf, size_t count)
1361{
1362        struct dasd_device *device;
1363        unsigned int val;
1364
1365        device = dasd_device_from_cdev(to_ccwdev(dev));
1366        if (IS_ERR(device))
1367                return -ENODEV;
1368
1369        if ((kstrtouint(buf, 16, &val) != 0) || val > 0xff)
1370                val = 0;
1371
1372        if (device->discipline && device->discipline->reset_path)
1373                device->discipline->reset_path(device, (__u8) val);
1374
1375        dasd_put_device(device);
1376        return count;
1377}
1378
1379static DEVICE_ATTR(path_reset, 0200, NULL, dasd_path_reset_store);
1380
1381static ssize_t dasd_hpf_show(struct device *dev, struct device_attribute *attr,
1382                             char *buf)
1383{
1384        struct dasd_device *device;
1385        int hpf;
1386
1387        device = dasd_device_from_cdev(to_ccwdev(dev));
1388        if (IS_ERR(device))
1389                return -ENODEV;
1390        if (!device->discipline || !device->discipline->hpf_enabled) {
1391                dasd_put_device(device);
1392                return snprintf(buf, PAGE_SIZE, "%d\n", dasd_nofcx);
1393        }
1394        hpf = device->discipline->hpf_enabled(device);
1395        dasd_put_device(device);
1396        return snprintf(buf, PAGE_SIZE, "%d\n", hpf);
1397}
1398
1399static DEVICE_ATTR(hpf, 0444, dasd_hpf_show, NULL);
1400
1401static ssize_t dasd_reservation_policy_show(struct device *dev,
1402                                            struct device_attribute *attr,
1403                                            char *buf)
1404{
1405        struct dasd_devmap *devmap;
1406        int rc = 0;
1407
1408        devmap = dasd_find_busid(dev_name(dev));
1409        if (IS_ERR(devmap)) {
1410                rc = snprintf(buf, PAGE_SIZE, "ignore\n");
1411        } else {
1412                spin_lock(&dasd_devmap_lock);
1413                if (devmap->features & DASD_FEATURE_FAILONSLCK)
1414                        rc = snprintf(buf, PAGE_SIZE, "fail\n");
1415                else
1416                        rc = snprintf(buf, PAGE_SIZE, "ignore\n");
1417                spin_unlock(&dasd_devmap_lock);
1418        }
1419        return rc;
1420}
1421
1422static ssize_t dasd_reservation_policy_store(struct device *dev,
1423                                             struct device_attribute *attr,
1424                                             const char *buf, size_t count)
1425{
1426        struct ccw_device *cdev = to_ccwdev(dev);
1427        int rc;
1428
1429        if (sysfs_streq("ignore", buf))
1430                rc = dasd_set_feature(cdev, DASD_FEATURE_FAILONSLCK, 0);
1431        else if (sysfs_streq("fail", buf))
1432                rc = dasd_set_feature(cdev, DASD_FEATURE_FAILONSLCK, 1);
1433        else
1434                rc = -EINVAL;
1435
1436        return rc ? : count;
1437}
1438
1439static DEVICE_ATTR(reservation_policy, 0644,
1440                   dasd_reservation_policy_show, dasd_reservation_policy_store);
1441
1442static ssize_t dasd_reservation_state_show(struct device *dev,
1443                                           struct device_attribute *attr,
1444                                           char *buf)
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 snprintf(buf, PAGE_SIZE, "none\n");
1452
1453        if (test_bit(DASD_FLAG_IS_RESERVED, &device->flags))
1454                rc = snprintf(buf, PAGE_SIZE, "reserved\n");
1455        else if (test_bit(DASD_FLAG_LOCK_STOLEN, &device->flags))
1456                rc = snprintf(buf, PAGE_SIZE, "lost\n");
1457        else
1458                rc = snprintf(buf, PAGE_SIZE, "none\n");
1459        dasd_put_device(device);
1460        return rc;
1461}
1462
1463static ssize_t dasd_reservation_state_store(struct device *dev,
1464                                            struct device_attribute *attr,
1465                                            const char *buf, size_t count)
1466{
1467        struct dasd_device *device;
1468        int rc = 0;
1469
1470        device = dasd_device_from_cdev(to_ccwdev(dev));
1471        if (IS_ERR(device))
1472                return -ENODEV;
1473        if (sysfs_streq("reset", buf))
1474                clear_bit(DASD_FLAG_LOCK_STOLEN, &device->flags);
1475        else
1476                rc = -EINVAL;
1477        dasd_put_device(device);
1478
1479        if (rc)
1480                return rc;
1481        else
1482                return count;
1483}
1484
1485static DEVICE_ATTR(last_known_reservation_state, 0644,
1486                   dasd_reservation_state_show, dasd_reservation_state_store);
1487
1488static ssize_t dasd_pm_show(struct device *dev,
1489                              struct device_attribute *attr, char *buf)
1490{
1491        struct dasd_device *device;
1492        u8 opm, nppm, cablepm, cuirpm, hpfpm, ifccpm;
1493
1494        device = dasd_device_from_cdev(to_ccwdev(dev));
1495        if (IS_ERR(device))
1496                return sprintf(buf, "0\n");
1497
1498        opm = dasd_path_get_opm(device);
1499        nppm = dasd_path_get_nppm(device);
1500        cablepm = dasd_path_get_cablepm(device);
1501        cuirpm = dasd_path_get_cuirpm(device);
1502        hpfpm = dasd_path_get_hpfpm(device);
1503        ifccpm = dasd_path_get_ifccpm(device);
1504        dasd_put_device(device);
1505
1506        return sprintf(buf, "%02x %02x %02x %02x %02x %02x\n", opm, nppm,
1507                       cablepm, cuirpm, hpfpm, ifccpm);
1508}
1509
1510static DEVICE_ATTR(path_masks, 0444, dasd_pm_show, NULL);
1511
1512/*
1513 * threshold value for IFCC/CCC errors
1514 */
1515static ssize_t
1516dasd_path_threshold_show(struct device *dev,
1517                          struct device_attribute *attr, char *buf)
1518{
1519        struct dasd_device *device;
1520        int len;
1521
1522        device = dasd_device_from_cdev(to_ccwdev(dev));
1523        if (IS_ERR(device))
1524                return -ENODEV;
1525        len = snprintf(buf, PAGE_SIZE, "%lu\n", device->path_thrhld);
1526        dasd_put_device(device);
1527        return len;
1528}
1529
1530static ssize_t
1531dasd_path_threshold_store(struct device *dev, struct device_attribute *attr,
1532                           const char *buf, size_t count)
1533{
1534        struct dasd_device *device;
1535        unsigned long flags;
1536        unsigned long val;
1537
1538        device = dasd_device_from_cdev(to_ccwdev(dev));
1539        if (IS_ERR(device))
1540                return -ENODEV;
1541
1542        if (kstrtoul(buf, 10, &val) != 0 || val > DASD_THRHLD_MAX) {
1543                dasd_put_device(device);
1544                return -EINVAL;
1545        }
1546        spin_lock_irqsave(get_ccwdev_lock(to_ccwdev(dev)), flags);
1547        device->path_thrhld = val;
1548        spin_unlock_irqrestore(get_ccwdev_lock(to_ccwdev(dev)), flags);
1549        dasd_put_device(device);
1550        return count;
1551}
1552
1553static DEVICE_ATTR(path_threshold, 0644, dasd_path_threshold_show,
1554                   dasd_path_threshold_store);
1555/*
1556 * interval for IFCC/CCC checks
1557 * meaning time with no IFCC/CCC error before the error counter
1558 * gets reset
1559 */
1560static ssize_t
1561dasd_path_interval_show(struct device *dev,
1562                        struct device_attribute *attr, char *buf)
1563{
1564        struct dasd_device *device;
1565        int len;
1566
1567        device = dasd_device_from_cdev(to_ccwdev(dev));
1568        if (IS_ERR(device))
1569                return -ENODEV;
1570        len = snprintf(buf, PAGE_SIZE, "%lu\n", device->path_interval);
1571        dasd_put_device(device);
1572        return len;
1573}
1574
1575static ssize_t
1576dasd_path_interval_store(struct device *dev, struct device_attribute *attr,
1577               const char *buf, size_t count)
1578{
1579        struct dasd_device *device;
1580        unsigned long flags;
1581        unsigned long val;
1582
1583        device = dasd_device_from_cdev(to_ccwdev(dev));
1584        if (IS_ERR(device))
1585                return -ENODEV;
1586
1587        if ((kstrtoul(buf, 10, &val) != 0) ||
1588            (val > DASD_INTERVAL_MAX) || val == 0) {
1589                dasd_put_device(device);
1590                return -EINVAL;
1591        }
1592        spin_lock_irqsave(get_ccwdev_lock(to_ccwdev(dev)), flags);
1593        if (val)
1594                device->path_interval = val;
1595        spin_unlock_irqrestore(get_ccwdev_lock(to_ccwdev(dev)), flags);
1596        dasd_put_device(device);
1597        return count;
1598}
1599
1600static DEVICE_ATTR(path_interval, 0644, dasd_path_interval_show,
1601                   dasd_path_interval_store);
1602
1603
1604static struct attribute * dasd_attrs[] = {
1605        &dev_attr_readonly.attr,
1606        &dev_attr_discipline.attr,
1607        &dev_attr_status.attr,
1608        &dev_attr_alias.attr,
1609        &dev_attr_vendor.attr,
1610        &dev_attr_uid.attr,
1611        &dev_attr_use_diag.attr,
1612        &dev_attr_raw_track_access.attr,
1613        &dev_attr_eer_enabled.attr,
1614        &dev_attr_erplog.attr,
1615        &dev_attr_failfast.attr,
1616        &dev_attr_expires.attr,
1617        &dev_attr_retries.attr,
1618        &dev_attr_timeout.attr,
1619        &dev_attr_reservation_policy.attr,
1620        &dev_attr_last_known_reservation_state.attr,
1621        &dev_attr_safe_offline.attr,
1622        &dev_attr_host_access_count.attr,
1623        &dev_attr_path_masks.attr,
1624        &dev_attr_path_threshold.attr,
1625        &dev_attr_path_interval.attr,
1626        &dev_attr_path_reset.attr,
1627        &dev_attr_hpf.attr,
1628        NULL,
1629};
1630
1631static const struct attribute_group dasd_attr_group = {
1632        .attrs = dasd_attrs,
1633};
1634
1635/*
1636 * Return value of the specified feature.
1637 */
1638int
1639dasd_get_feature(struct ccw_device *cdev, int feature)
1640{
1641        struct dasd_devmap *devmap;
1642
1643        devmap = dasd_find_busid(dev_name(&cdev->dev));
1644        if (IS_ERR(devmap))
1645                return PTR_ERR(devmap);
1646
1647        return ((devmap->features & feature) != 0);
1648}
1649
1650/*
1651 * Set / reset given feature.
1652 * Flag indicates whether to set (!=0) or the reset (=0) the feature.
1653 */
1654int
1655dasd_set_feature(struct ccw_device *cdev, int feature, int flag)
1656{
1657        struct dasd_devmap *devmap;
1658
1659        devmap = dasd_devmap_from_cdev(cdev);
1660        if (IS_ERR(devmap))
1661                return PTR_ERR(devmap);
1662
1663        spin_lock(&dasd_devmap_lock);
1664        if (flag)
1665                devmap->features |= feature;
1666        else
1667                devmap->features &= ~feature;
1668        if (devmap->device)
1669                devmap->device->features = devmap->features;
1670        spin_unlock(&dasd_devmap_lock);
1671        return 0;
1672}
1673EXPORT_SYMBOL(dasd_set_feature);
1674
1675
1676int
1677dasd_add_sysfs_files(struct ccw_device *cdev)
1678{
1679        return sysfs_create_group(&cdev->dev.kobj, &dasd_attr_group);
1680}
1681
1682void
1683dasd_remove_sysfs_files(struct ccw_device *cdev)
1684{
1685        sysfs_remove_group(&cdev->dev.kobj, &dasd_attr_group);
1686}
1687
1688
1689int
1690dasd_devmap_init(void)
1691{
1692        int i;
1693
1694        /* Initialize devmap structures. */
1695        dasd_max_devindex = 0;
1696        for (i = 0; i < 256; i++)
1697                INIT_LIST_HEAD(&dasd_hashlists[i]);
1698        return 0;
1699}
1700
1701void
1702dasd_devmap_exit(void)
1703{
1704        dasd_forget_ranges();
1705}
1706