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 <asm/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
  30#include "dasd_int.h"
  31
  32struct kmem_cache *dasd_page_cache;
  33EXPORT_SYMBOL_GPL(dasd_page_cache);
  34
  35/*
  36 * dasd_devmap_t is used to store the features and the relation
  37 * between device number and device index. To find a dasd_devmap_t
  38 * that corresponds to a device number of a device index each
  39 * dasd_devmap_t is added to two linked lists, one to search by
  40 * the device number and one to search by the device index. As
  41 * soon as big minor numbers are available the device index list
  42 * can be removed since the device number will then be identical
  43 * to the device index.
  44 */
  45struct dasd_devmap {
  46        struct list_head list;
  47        char bus_id[DASD_BUS_ID_SIZE];
  48        unsigned int devindex;
  49        unsigned short features;
  50        struct dasd_device *device;
  51};
  52
  53/*
  54 * Parameter parsing functions for dasd= parameter. The syntax is:
  55 *   <devno>            : (0x)?[0-9a-fA-F]+
  56 *   <busid>            : [0-0a-f]\.[0-9a-f]\.(0x)?[0-9a-fA-F]+
  57 *   <feature>          : ro
  58 *   <feature_list>     : \(<feature>(:<feature>)*\)
  59 *   <devno-range>      : <devno>(-<devno>)?<feature_list>?
  60 *   <busid-range>      : <busid>(-<busid>)?<feature_list>?
  61 *   <devices>          : <devno-range>|<busid-range>
  62 *   <dasd_module>      : dasd_diag_mod|dasd_eckd_mod|dasd_fba_mod
  63 *
  64 *   <dasd>             : autodetect|probeonly|<devices>(,<devices>)*
  65 */
  66
  67int dasd_probeonly =  0;        /* is true, when probeonly mode is active */
  68int dasd_autodetect = 0;        /* is true, when autodetection is active */
  69int dasd_nopav = 0;             /* is true, when PAV is disabled */
  70EXPORT_SYMBOL_GPL(dasd_nopav);
  71int dasd_nofcx;                 /* disable High Performance Ficon */
  72EXPORT_SYMBOL_GPL(dasd_nofcx);
  73
  74/*
  75 * char *dasd[] is intended to hold the ranges supplied by the dasd= statement
  76 * it is named 'dasd' to directly be filled by insmod with the comma separated
  77 * strings when running as a module.
  78 */
  79static char *dasd[256];
  80module_param_array(dasd, charp, NULL, 0);
  81
  82/*
  83 * Single spinlock to protect devmap and servermap structures and lists.
  84 */
  85static DEFINE_SPINLOCK(dasd_devmap_lock);
  86
  87/*
  88 * Hash lists for devmap structures.
  89 */
  90static struct list_head dasd_hashlists[256];
  91int dasd_max_devindex;
  92
  93static struct dasd_devmap *dasd_add_busid(const char *, int);
  94
  95static inline int
  96dasd_hash_busid(const char *bus_id)
  97{
  98        int hash, i;
  99
 100        hash = 0;
 101        for (i = 0; (i < DASD_BUS_ID_SIZE) && *bus_id; i++, bus_id++)
 102                hash += *bus_id;
 103        return hash & 0xff;
 104}
 105
 106#ifndef MODULE
 107/*
 108 * The parameter parsing functions for builtin-drivers are called
 109 * before kmalloc works. Store the pointers to the parameters strings
 110 * into dasd[] for later processing.
 111 */
 112static int __init
 113dasd_call_setup(char *str)
 114{
 115        static int count = 0;
 116
 117        if (count < 256)
 118                dasd[count++] = str;
 119        return 1;
 120}
 121
 122__setup ("dasd=", dasd_call_setup);
 123#endif  /* #ifndef MODULE */
 124
 125#define DASD_IPLDEV     "ipldev"
 126
 127/*
 128 * Read a device busid/devno from a string.
 129 */
 130static int
 131
 132dasd_busid(char **str, int *id0, int *id1, int *devno)
 133{
 134        int val, old_style;
 135
 136        /* Interpret ipldev busid */
 137        if (strncmp(DASD_IPLDEV, *str, strlen(DASD_IPLDEV)) == 0) {
 138                if (ipl_info.type != IPL_TYPE_CCW) {
 139                        pr_err("The IPL device is not a CCW device\n");
 140                        return -EINVAL;
 141                }
 142                *id0 = 0;
 143                *id1 = ipl_info.data.ccw.dev_id.ssid;
 144                *devno = ipl_info.data.ccw.dev_id.devno;
 145                *str += strlen(DASD_IPLDEV);
 146
 147                return 0;
 148        }
 149        /* check for leading '0x' */
 150        old_style = 0;
 151        if ((*str)[0] == '0' && (*str)[1] == 'x') {
 152                *str += 2;
 153                old_style = 1;
 154        }
 155        if (!isxdigit((*str)[0]))       /* We require at least one hex digit */
 156                return -EINVAL;
 157        val = simple_strtoul(*str, str, 16);
 158        if (old_style || (*str)[0] != '.') {
 159                *id0 = *id1 = 0;
 160                if (val < 0 || val > 0xffff)
 161                        return -EINVAL;
 162                *devno = val;
 163                return 0;
 164        }
 165        /* New style x.y.z busid */
 166        if (val < 0 || val > 0xff)
 167                return -EINVAL;
 168        *id0 = val;
 169        (*str)++;
 170        if (!isxdigit((*str)[0]))       /* We require at least one hex digit */
 171                return -EINVAL;
 172        val = simple_strtoul(*str, str, 16);
 173        if (val < 0 || val > 0xff || (*str)++[0] != '.')
 174                return -EINVAL;
 175        *id1 = val;
 176        if (!isxdigit((*str)[0]))       /* We require at least one hex digit */
 177                return -EINVAL;
 178        val = simple_strtoul(*str, str, 16);
 179        if (val < 0 || val > 0xffff)
 180                return -EINVAL;
 181        *devno = val;
 182        return 0;
 183}
 184
 185/*
 186 * Read colon separated list of dasd features. Currently there is
 187 * only one: "ro" for read-only devices. The default feature set
 188 * is empty (value 0).
 189 */
 190static int
 191dasd_feature_list(char *str, char **endp)
 192{
 193        int features, len, rc;
 194
 195        rc = 0;
 196        if (*str != '(') {
 197                *endp = str;
 198                return DASD_FEATURE_DEFAULT;
 199        }
 200        str++;
 201        features = 0;
 202
 203        while (1) {
 204                for (len = 0;
 205                     str[len] && str[len] != ':' && str[len] != ')'; len++);
 206                if (len == 2 && !strncmp(str, "ro", 2))
 207                        features |= DASD_FEATURE_READONLY;
 208                else if (len == 4 && !strncmp(str, "diag", 4))
 209                        features |= DASD_FEATURE_USEDIAG;
 210                else if (len == 3 && !strncmp(str, "raw", 3))
 211                        features |= DASD_FEATURE_USERAW;
 212                else if (len == 6 && !strncmp(str, "erplog", 6))
 213                        features |= DASD_FEATURE_ERPLOG;
 214                else if (len == 8 && !strncmp(str, "failfast", 8))
 215                        features |= DASD_FEATURE_FAILFAST;
 216                else {
 217                        pr_warning("%*s is not a supported device option\n",
 218                                   len, str);
 219                        rc = -EINVAL;
 220                }
 221                str += len;
 222                if (*str != ':')
 223                        break;
 224                str++;
 225        }
 226        if (*str != ')') {
 227                pr_warning("A closing parenthesis ')' is missing in the "
 228                           "dasd= parameter\n");
 229                rc = -EINVAL;
 230        } else
 231                str++;
 232        *endp = str;
 233        if (rc != 0)
 234                return rc;
 235        return features;
 236}
 237
 238/*
 239 * Try to match the first element on the comma separated parse string
 240 * with one of the known keywords. If a keyword is found, take the approprate
 241 * action and return a pointer to the residual string. If the first element
 242 * could not be matched to any keyword then return an error code.
 243 */
 244static char *
 245dasd_parse_keyword( char *parsestring ) {
 246
 247        char *nextcomma, *residual_str;
 248        int length;
 249
 250        nextcomma = strchr(parsestring,',');
 251        if (nextcomma) {
 252                length = nextcomma - parsestring;
 253                residual_str = nextcomma + 1;
 254        } else {
 255                length = strlen(parsestring);
 256                residual_str = parsestring + length;
 257        }
 258        if (strncmp("autodetect", parsestring, length) == 0) {
 259                dasd_autodetect = 1;
 260                pr_info("The autodetection mode has been activated\n");
 261                return residual_str;
 262        }
 263        if (strncmp("probeonly", parsestring, length) == 0) {
 264                dasd_probeonly = 1;
 265                pr_info("The probeonly mode has been activated\n");
 266                return residual_str;
 267        }
 268        if (strncmp("nopav", parsestring, length) == 0) {
 269                if (MACHINE_IS_VM)
 270                        pr_info("'nopav' is not supported on z/VM\n");
 271                else {
 272                        dasd_nopav = 1;
 273                        pr_info("PAV support has be deactivated\n");
 274                }
 275                return residual_str;
 276        }
 277        if (strncmp("nofcx", parsestring, length) == 0) {
 278                dasd_nofcx = 1;
 279                pr_info("High Performance FICON support has been "
 280                        "deactivated\n");
 281                return residual_str;
 282        }
 283        if (strncmp("fixedbuffers", parsestring, length) == 0) {
 284                if (dasd_page_cache)
 285                        return residual_str;
 286                dasd_page_cache =
 287                        kmem_cache_create("dasd_page_cache", PAGE_SIZE,
 288                                          PAGE_SIZE, SLAB_CACHE_DMA,
 289                                          NULL);
 290                if (!dasd_page_cache)
 291                        DBF_EVENT(DBF_WARNING, "%s", "Failed to create slab, "
 292                                "fixed buffer mode disabled.");
 293                else
 294                        DBF_EVENT(DBF_INFO, "%s",
 295                                 "turning on fixed buffer mode");
 296                return residual_str;
 297        }
 298        return ERR_PTR(-EINVAL);
 299}
 300
 301/*
 302 * Try to interprete the first element on the comma separated parse string
 303 * as a device number or a range of devices. If the interpretation is
 304 * successful, create the matching dasd_devmap entries and return a pointer
 305 * to the residual string.
 306 * If interpretation fails or in case of an error, return an error code.
 307 */
 308static char *
 309dasd_parse_range( char *parsestring ) {
 310
 311        struct dasd_devmap *devmap;
 312        int from, from_id0, from_id1;
 313        int to, to_id0, to_id1;
 314        int features, rc;
 315        char bus_id[DASD_BUS_ID_SIZE+1], *str;
 316
 317        str = parsestring;
 318        rc = dasd_busid(&str, &from_id0, &from_id1, &from);
 319        if (rc == 0) {
 320                to = from;
 321                to_id0 = from_id0;
 322                to_id1 = from_id1;
 323                if (*str == '-') {
 324                        str++;
 325                        rc = dasd_busid(&str, &to_id0, &to_id1, &to);
 326                }
 327        }
 328        if (rc == 0 &&
 329            (from_id0 != to_id0 || from_id1 != to_id1 || from > to))
 330                rc = -EINVAL;
 331        if (rc) {
 332                pr_err("%s is not a valid device range\n", parsestring);
 333                return ERR_PTR(rc);
 334        }
 335        features = dasd_feature_list(str, &str);
 336        if (features < 0)
 337                return ERR_PTR(-EINVAL);
 338        /* each device in dasd= parameter should be set initially online */
 339        features |= DASD_FEATURE_INITIAL_ONLINE;
 340        while (from <= to) {
 341                sprintf(bus_id, "%01x.%01x.%04x",
 342                        from_id0, from_id1, from++);
 343                devmap = dasd_add_busid(bus_id, features);
 344                if (IS_ERR(devmap))
 345                        return (char *)devmap;
 346        }
 347        if (*str == ',')
 348                return str + 1;
 349        if (*str == '\0')
 350                return str;
 351        pr_warning("The dasd= parameter value %s has an invalid ending\n",
 352                   str);
 353        return ERR_PTR(-EINVAL);
 354}
 355
 356static char *
 357dasd_parse_next_element( char *parsestring ) {
 358        char * residual_str;
 359        residual_str = dasd_parse_keyword(parsestring);
 360        if (!IS_ERR(residual_str))
 361                return residual_str;
 362        residual_str = dasd_parse_range(parsestring);
 363        return residual_str;
 364}
 365
 366/*
 367 * Parse parameters stored in dasd[]
 368 * The 'dasd=...' parameter allows to specify a comma separated list of
 369 * keywords and device ranges. When the dasd driver is build into the kernel,
 370 * the complete list will be stored as one element of the dasd[] array.
 371 * When the dasd driver is build as a module, then the list is broken into
 372 * it's elements and each dasd[] entry contains one element.
 373 */
 374int
 375dasd_parse(void)
 376{
 377        int rc, i;
 378        char *parsestring;
 379
 380        rc = 0;
 381        for (i = 0; i < 256; i++) {
 382                if (dasd[i] == NULL)
 383                        break;
 384                parsestring = dasd[i];
 385                /* loop over the comma separated list in the parsestring */
 386                while (*parsestring) {
 387                        parsestring = dasd_parse_next_element(parsestring);
 388                        if(IS_ERR(parsestring)) {
 389                                rc = PTR_ERR(parsestring);
 390                                break;
 391                        }
 392                }
 393                if (rc) {
 394                        DBF_EVENT(DBF_ALERT, "%s", "invalid range found");
 395                        break;
 396                }
 397        }
 398        return rc;
 399}
 400
 401/*
 402 * Add a devmap for the device specified by busid. It is possible that
 403 * the devmap already exists (dasd= parameter). The order of the devices
 404 * added through this function will define the kdevs for the individual
 405 * devices.
 406 */
 407static struct dasd_devmap *
 408dasd_add_busid(const char *bus_id, int features)
 409{
 410        struct dasd_devmap *devmap, *new, *tmp;
 411        int hash;
 412
 413        new = (struct dasd_devmap *)
 414                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        /* Disconnect dasd_device structure from ccw_device structure. */
 624        cdev = device->cdev;
 625        device->cdev = NULL;
 626
 627        /* Put ccw_device structure. */
 628        put_device(&cdev->dev);
 629
 630        /* Now the device structure can be freed. */
 631        dasd_free_device(device);
 632}
 633
 634/*
 635 * Reference counter dropped to zero. Wake up waiter
 636 * in dasd_delete_device.
 637 */
 638void
 639dasd_put_device_wake(struct dasd_device *device)
 640{
 641        wake_up(&dasd_delete_wq);
 642}
 643EXPORT_SYMBOL_GPL(dasd_put_device_wake);
 644
 645/*
 646 * Return dasd_device structure associated with cdev.
 647 * This function needs to be called with the ccw device
 648 * lock held. It can be used from interrupt context.
 649 */
 650struct dasd_device *
 651dasd_device_from_cdev_locked(struct ccw_device *cdev)
 652{
 653        struct dasd_device *device = dev_get_drvdata(&cdev->dev);
 654
 655        if (!device)
 656                return ERR_PTR(-ENODEV);
 657        dasd_get_device(device);
 658        return device;
 659}
 660
 661/*
 662 * Return dasd_device structure associated with cdev.
 663 */
 664struct dasd_device *
 665dasd_device_from_cdev(struct ccw_device *cdev)
 666{
 667        struct dasd_device *device;
 668        unsigned long flags;
 669
 670        spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
 671        device = dasd_device_from_cdev_locked(cdev);
 672        spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
 673        return device;
 674}
 675
 676void dasd_add_link_to_gendisk(struct gendisk *gdp, struct dasd_device *device)
 677{
 678        struct dasd_devmap *devmap;
 679
 680        devmap = dasd_find_busid(dev_name(&device->cdev->dev));
 681        if (IS_ERR(devmap))
 682                return;
 683        spin_lock(&dasd_devmap_lock);
 684        gdp->private_data = devmap;
 685        spin_unlock(&dasd_devmap_lock);
 686}
 687
 688struct dasd_device *dasd_device_from_gendisk(struct gendisk *gdp)
 689{
 690        struct dasd_device *device;
 691        struct dasd_devmap *devmap;
 692
 693        if (!gdp->private_data)
 694                return NULL;
 695        device = NULL;
 696        spin_lock(&dasd_devmap_lock);
 697        devmap = gdp->private_data;
 698        if (devmap && devmap->device) {
 699                device = devmap->device;
 700                dasd_get_device(device);
 701        }
 702        spin_unlock(&dasd_devmap_lock);
 703        return device;
 704}
 705
 706/*
 707 * SECTION: files in sysfs
 708 */
 709
 710/*
 711 * failfast controls the behaviour, if no path is available
 712 */
 713static ssize_t dasd_ff_show(struct device *dev, struct device_attribute *attr,
 714                            char *buf)
 715{
 716        struct dasd_devmap *devmap;
 717        int ff_flag;
 718
 719        devmap = dasd_find_busid(dev_name(dev));
 720        if (!IS_ERR(devmap))
 721                ff_flag = (devmap->features & DASD_FEATURE_FAILFAST) != 0;
 722        else
 723                ff_flag = (DASD_FEATURE_DEFAULT & DASD_FEATURE_FAILFAST) != 0;
 724        return snprintf(buf, PAGE_SIZE, ff_flag ? "1\n" : "0\n");
 725}
 726
 727static ssize_t dasd_ff_store(struct device *dev, struct device_attribute *attr,
 728              const char *buf, size_t count)
 729{
 730        struct dasd_devmap *devmap;
 731        int val;
 732        char *endp;
 733
 734        devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
 735        if (IS_ERR(devmap))
 736                return PTR_ERR(devmap);
 737
 738        val = simple_strtoul(buf, &endp, 0);
 739        if (((endp + 1) < (buf + count)) || (val > 1))
 740                return -EINVAL;
 741
 742        spin_lock(&dasd_devmap_lock);
 743        if (val)
 744                devmap->features |= DASD_FEATURE_FAILFAST;
 745        else
 746                devmap->features &= ~DASD_FEATURE_FAILFAST;
 747        if (devmap->device)
 748                devmap->device->features = devmap->features;
 749        spin_unlock(&dasd_devmap_lock);
 750        return count;
 751}
 752
 753static DEVICE_ATTR(failfast, 0644, dasd_ff_show, dasd_ff_store);
 754
 755/*
 756 * readonly controls the readonly status of a dasd
 757 */
 758static ssize_t
 759dasd_ro_show(struct device *dev, struct device_attribute *attr, char *buf)
 760{
 761        struct dasd_devmap *devmap;
 762        int ro_flag;
 763
 764        devmap = dasd_find_busid(dev_name(dev));
 765        if (!IS_ERR(devmap))
 766                ro_flag = (devmap->features & DASD_FEATURE_READONLY) != 0;
 767        else
 768                ro_flag = (DASD_FEATURE_DEFAULT & DASD_FEATURE_READONLY) != 0;
 769        return snprintf(buf, PAGE_SIZE, ro_flag ? "1\n" : "0\n");
 770}
 771
 772static ssize_t
 773dasd_ro_store(struct device *dev, struct device_attribute *attr,
 774              const char *buf, size_t count)
 775{
 776        struct dasd_devmap *devmap;
 777        struct dasd_device *device;
 778        int val;
 779        char *endp;
 780
 781        devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
 782        if (IS_ERR(devmap))
 783                return PTR_ERR(devmap);
 784
 785        val = simple_strtoul(buf, &endp, 0);
 786        if (((endp + 1) < (buf + count)) || (val > 1))
 787                return -EINVAL;
 788
 789        spin_lock(&dasd_devmap_lock);
 790        if (val)
 791                devmap->features |= DASD_FEATURE_READONLY;
 792        else
 793                devmap->features &= ~DASD_FEATURE_READONLY;
 794        device = devmap->device;
 795        if (device) {
 796                device->features = devmap->features;
 797                val = val || test_bit(DASD_FLAG_DEVICE_RO, &device->flags);
 798        }
 799        spin_unlock(&dasd_devmap_lock);
 800        if (device && device->block && device->block->gdp)
 801                set_disk_ro(device->block->gdp, val);
 802        return count;
 803}
 804
 805static DEVICE_ATTR(readonly, 0644, dasd_ro_show, dasd_ro_store);
 806/*
 807 * erplog controls the logging of ERP related data
 808 * (e.g. failing channel programs).
 809 */
 810static ssize_t
 811dasd_erplog_show(struct device *dev, struct device_attribute *attr, char *buf)
 812{
 813        struct dasd_devmap *devmap;
 814        int erplog;
 815
 816        devmap = dasd_find_busid(dev_name(dev));
 817        if (!IS_ERR(devmap))
 818                erplog = (devmap->features & DASD_FEATURE_ERPLOG) != 0;
 819        else
 820                erplog = (DASD_FEATURE_DEFAULT & DASD_FEATURE_ERPLOG) != 0;
 821        return snprintf(buf, PAGE_SIZE, erplog ? "1\n" : "0\n");
 822}
 823
 824static ssize_t
 825dasd_erplog_store(struct device *dev, struct device_attribute *attr,
 826              const char *buf, size_t count)
 827{
 828        struct dasd_devmap *devmap;
 829        int val;
 830        char *endp;
 831
 832        devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
 833        if (IS_ERR(devmap))
 834                return PTR_ERR(devmap);
 835
 836        val = simple_strtoul(buf, &endp, 0);
 837        if (((endp + 1) < (buf + count)) || (val > 1))
 838                return -EINVAL;
 839
 840        spin_lock(&dasd_devmap_lock);
 841        if (val)
 842                devmap->features |= DASD_FEATURE_ERPLOG;
 843        else
 844                devmap->features &= ~DASD_FEATURE_ERPLOG;
 845        if (devmap->device)
 846                devmap->device->features = devmap->features;
 847        spin_unlock(&dasd_devmap_lock);
 848        return count;
 849}
 850
 851static DEVICE_ATTR(erplog, 0644, dasd_erplog_show, dasd_erplog_store);
 852
 853/*
 854 * use_diag controls whether the driver should use diag rather than ssch
 855 * to talk to the device
 856 */
 857static ssize_t
 858dasd_use_diag_show(struct device *dev, struct device_attribute *attr, char *buf)
 859{
 860        struct dasd_devmap *devmap;
 861        int use_diag;
 862
 863        devmap = dasd_find_busid(dev_name(dev));
 864        if (!IS_ERR(devmap))
 865                use_diag = (devmap->features & DASD_FEATURE_USEDIAG) != 0;
 866        else
 867                use_diag = (DASD_FEATURE_DEFAULT & DASD_FEATURE_USEDIAG) != 0;
 868        return sprintf(buf, use_diag ? "1\n" : "0\n");
 869}
 870
 871static ssize_t
 872dasd_use_diag_store(struct device *dev, struct device_attribute *attr,
 873                    const char *buf, size_t count)
 874{
 875        struct dasd_devmap *devmap;
 876        ssize_t rc;
 877        int val;
 878        char *endp;
 879
 880        devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
 881        if (IS_ERR(devmap))
 882                return PTR_ERR(devmap);
 883
 884        val = simple_strtoul(buf, &endp, 0);
 885        if (((endp + 1) < (buf + count)) || (val > 1))
 886                return -EINVAL;
 887
 888        spin_lock(&dasd_devmap_lock);
 889        /* Changing diag discipline flag is only allowed in offline state. */
 890        rc = count;
 891        if (!devmap->device && !(devmap->features & DASD_FEATURE_USERAW)) {
 892                if (val)
 893                        devmap->features |= DASD_FEATURE_USEDIAG;
 894                else
 895                        devmap->features &= ~DASD_FEATURE_USEDIAG;
 896        } else
 897                rc = -EPERM;
 898        spin_unlock(&dasd_devmap_lock);
 899        return rc;
 900}
 901
 902static DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store);
 903
 904/*
 905 * use_raw controls whether the driver should give access to raw eckd data or
 906 * operate in standard mode
 907 */
 908static ssize_t
 909dasd_use_raw_show(struct device *dev, struct device_attribute *attr, char *buf)
 910{
 911        struct dasd_devmap *devmap;
 912        int use_raw;
 913
 914        devmap = dasd_find_busid(dev_name(dev));
 915        if (!IS_ERR(devmap))
 916                use_raw = (devmap->features & DASD_FEATURE_USERAW) != 0;
 917        else
 918                use_raw = (DASD_FEATURE_DEFAULT & DASD_FEATURE_USERAW) != 0;
 919        return sprintf(buf, use_raw ? "1\n" : "0\n");
 920}
 921
 922static ssize_t
 923dasd_use_raw_store(struct device *dev, struct device_attribute *attr,
 924                    const char *buf, size_t count)
 925{
 926        struct dasd_devmap *devmap;
 927        ssize_t rc;
 928        unsigned long val;
 929
 930        devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
 931        if (IS_ERR(devmap))
 932                return PTR_ERR(devmap);
 933
 934        if ((strict_strtoul(buf, 10, &val) != 0) || val > 1)
 935                return -EINVAL;
 936
 937        spin_lock(&dasd_devmap_lock);
 938        /* Changing diag discipline flag is only allowed in offline state. */
 939        rc = count;
 940        if (!devmap->device && !(devmap->features & DASD_FEATURE_USEDIAG)) {
 941                if (val)
 942                        devmap->features |= DASD_FEATURE_USERAW;
 943                else
 944                        devmap->features &= ~DASD_FEATURE_USERAW;
 945        } else
 946                rc = -EPERM;
 947        spin_unlock(&dasd_devmap_lock);
 948        return rc;
 949}
 950
 951static DEVICE_ATTR(raw_track_access, 0644, dasd_use_raw_show,
 952                   dasd_use_raw_store);
 953
 954static ssize_t
 955dasd_discipline_show(struct device *dev, struct device_attribute *attr,
 956                     char *buf)
 957{
 958        struct dasd_device *device;
 959        ssize_t len;
 960
 961        device = dasd_device_from_cdev(to_ccwdev(dev));
 962        if (IS_ERR(device))
 963                goto out;
 964        else if (!device->discipline) {
 965                dasd_put_device(device);
 966                goto out;
 967        } else {
 968                len = snprintf(buf, PAGE_SIZE, "%s\n",
 969                               device->discipline->name);
 970                dasd_put_device(device);
 971                return len;
 972        }
 973out:
 974        len = snprintf(buf, PAGE_SIZE, "none\n");
 975        return len;
 976}
 977
 978static DEVICE_ATTR(discipline, 0444, dasd_discipline_show, NULL);
 979
 980static ssize_t
 981dasd_device_status_show(struct device *dev, struct device_attribute *attr,
 982                     char *buf)
 983{
 984        struct dasd_device *device;
 985        ssize_t len;
 986
 987        device = dasd_device_from_cdev(to_ccwdev(dev));
 988        if (!IS_ERR(device)) {
 989                switch (device->state) {
 990                case DASD_STATE_NEW:
 991                        len = snprintf(buf, PAGE_SIZE, "new\n");
 992                        break;
 993                case DASD_STATE_KNOWN:
 994                        len = snprintf(buf, PAGE_SIZE, "detected\n");
 995                        break;
 996                case DASD_STATE_BASIC:
 997                        len = snprintf(buf, PAGE_SIZE, "basic\n");
 998                        break;
 999                case DASD_STATE_UNFMT:
1000                        len = snprintf(buf, PAGE_SIZE, "unformatted\n");
1001                        break;
1002                case DASD_STATE_READY:
1003                        len = snprintf(buf, PAGE_SIZE, "ready\n");
1004                        break;
1005                case DASD_STATE_ONLINE:
1006                        len = snprintf(buf, PAGE_SIZE, "online\n");
1007                        break;
1008                default:
1009                        len = snprintf(buf, PAGE_SIZE, "no stat\n");
1010                        break;
1011                }
1012                dasd_put_device(device);
1013        } else
1014                len = snprintf(buf, PAGE_SIZE, "unknown\n");
1015        return len;
1016}
1017
1018static DEVICE_ATTR(status, 0444, dasd_device_status_show, NULL);
1019
1020static ssize_t dasd_alias_show(struct device *dev,
1021                               struct device_attribute *attr, char *buf)
1022{
1023        struct dasd_device *device;
1024        struct dasd_uid uid;
1025
1026        device = dasd_device_from_cdev(to_ccwdev(dev));
1027        if (IS_ERR(device))
1028                return sprintf(buf, "0\n");
1029
1030        if (device->discipline && device->discipline->get_uid &&
1031            !device->discipline->get_uid(device, &uid)) {
1032                if (uid.type == UA_BASE_PAV_ALIAS ||
1033                    uid.type == UA_HYPER_PAV_ALIAS) {
1034                        dasd_put_device(device);
1035                        return sprintf(buf, "1\n");
1036                }
1037        }
1038        dasd_put_device(device);
1039
1040        return sprintf(buf, "0\n");
1041}
1042
1043static DEVICE_ATTR(alias, 0444, dasd_alias_show, NULL);
1044
1045static ssize_t dasd_vendor_show(struct device *dev,
1046                                struct device_attribute *attr, char *buf)
1047{
1048        struct dasd_device *device;
1049        struct dasd_uid uid;
1050        char *vendor;
1051
1052        device = dasd_device_from_cdev(to_ccwdev(dev));
1053        vendor = "";
1054        if (IS_ERR(device))
1055                return snprintf(buf, PAGE_SIZE, "%s\n", vendor);
1056
1057        if (device->discipline && device->discipline->get_uid &&
1058            !device->discipline->get_uid(device, &uid))
1059                        vendor = uid.vendor;
1060
1061        dasd_put_device(device);
1062
1063        return snprintf(buf, PAGE_SIZE, "%s\n", vendor);
1064}
1065
1066static DEVICE_ATTR(vendor, 0444, dasd_vendor_show, NULL);
1067
1068#define UID_STRLEN ( /* vendor */ 3 + 1 + /* serial    */ 14 + 1 +\
1069                     /* SSID   */ 4 + 1 + /* unit addr */ 2 + 1 +\
1070                     /* vduit */ 32 + 1)
1071
1072static ssize_t
1073dasd_uid_show(struct device *dev, struct device_attribute *attr, char *buf)
1074{
1075        struct dasd_device *device;
1076        struct dasd_uid uid;
1077        char uid_string[UID_STRLEN];
1078        char ua_string[3];
1079
1080        device = dasd_device_from_cdev(to_ccwdev(dev));
1081        uid_string[0] = 0;
1082        if (IS_ERR(device))
1083                return snprintf(buf, PAGE_SIZE, "%s\n", uid_string);
1084
1085        if (device->discipline && device->discipline->get_uid &&
1086            !device->discipline->get_uid(device, &uid)) {
1087                switch (uid.type) {
1088                case UA_BASE_DEVICE:
1089                        snprintf(ua_string, sizeof(ua_string), "%02x",
1090                                 uid.real_unit_addr);
1091                        break;
1092                case UA_BASE_PAV_ALIAS:
1093                        snprintf(ua_string, sizeof(ua_string), "%02x",
1094                                 uid.base_unit_addr);
1095                        break;
1096                case UA_HYPER_PAV_ALIAS:
1097                        snprintf(ua_string, sizeof(ua_string), "xx");
1098                        break;
1099                default:
1100                        /* should not happen, treat like base device */
1101                        snprintf(ua_string, sizeof(ua_string), "%02x",
1102                                 uid.real_unit_addr);
1103                        break;
1104                }
1105
1106                if (strlen(uid.vduit) > 0)
1107                        snprintf(uid_string, sizeof(uid_string),
1108                                 "%s.%s.%04x.%s.%s",
1109                                 uid.vendor, uid.serial, uid.ssid, ua_string,
1110                                 uid.vduit);
1111                else
1112                        snprintf(uid_string, sizeof(uid_string),
1113                                 "%s.%s.%04x.%s",
1114                                 uid.vendor, uid.serial, uid.ssid, ua_string);
1115        }
1116        dasd_put_device(device);
1117
1118        return snprintf(buf, PAGE_SIZE, "%s\n", uid_string);
1119}
1120static DEVICE_ATTR(uid, 0444, dasd_uid_show, NULL);
1121
1122/*
1123 * extended error-reporting
1124 */
1125static ssize_t
1126dasd_eer_show(struct device *dev, struct device_attribute *attr, char *buf)
1127{
1128        struct dasd_devmap *devmap;
1129        int eer_flag;
1130
1131        devmap = dasd_find_busid(dev_name(dev));
1132        if (!IS_ERR(devmap) && devmap->device)
1133                eer_flag = dasd_eer_enabled(devmap->device);
1134        else
1135                eer_flag = 0;
1136        return snprintf(buf, PAGE_SIZE, eer_flag ? "1\n" : "0\n");
1137}
1138
1139static ssize_t
1140dasd_eer_store(struct device *dev, struct device_attribute *attr,
1141               const char *buf, size_t count)
1142{
1143        struct dasd_devmap *devmap;
1144        int val, rc;
1145        char *endp;
1146
1147        devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
1148        if (IS_ERR(devmap))
1149                return PTR_ERR(devmap);
1150        if (!devmap->device)
1151                return -ENODEV;
1152
1153        val = simple_strtoul(buf, &endp, 0);
1154        if (((endp + 1) < (buf + count)) || (val > 1))
1155                return -EINVAL;
1156
1157        if (val) {
1158                rc = dasd_eer_enable(devmap->device);
1159                if (rc)
1160                        return rc;
1161        } else
1162                dasd_eer_disable(devmap->device);
1163        return count;
1164}
1165
1166static DEVICE_ATTR(eer_enabled, 0644, dasd_eer_show, dasd_eer_store);
1167
1168/*
1169 * expiration time for default requests
1170 */
1171static ssize_t
1172dasd_expires_show(struct device *dev, struct device_attribute *attr, char *buf)
1173{
1174        struct dasd_device *device;
1175        int len;
1176
1177        device = dasd_device_from_cdev(to_ccwdev(dev));
1178        if (IS_ERR(device))
1179                return -ENODEV;
1180        len = snprintf(buf, PAGE_SIZE, "%lu\n", device->default_expires);
1181        dasd_put_device(device);
1182        return len;
1183}
1184
1185static ssize_t
1186dasd_expires_store(struct device *dev, struct device_attribute *attr,
1187               const char *buf, size_t count)
1188{
1189        struct dasd_device *device;
1190        unsigned long val;
1191
1192        device = dasd_device_from_cdev(to_ccwdev(dev));
1193        if (IS_ERR(device))
1194                return -ENODEV;
1195
1196        if ((strict_strtoul(buf, 10, &val) != 0) ||
1197            (val > DASD_EXPIRES_MAX) || val == 0) {
1198                dasd_put_device(device);
1199                return -EINVAL;
1200        }
1201
1202        if (val)
1203                device->default_expires = val;
1204
1205        dasd_put_device(device);
1206        return count;
1207}
1208
1209static DEVICE_ATTR(expires, 0644, dasd_expires_show, dasd_expires_store);
1210
1211static ssize_t dasd_reservation_policy_show(struct device *dev,
1212                                            struct device_attribute *attr,
1213                                            char *buf)
1214{
1215        struct dasd_devmap *devmap;
1216        int rc = 0;
1217
1218        devmap = dasd_find_busid(dev_name(dev));
1219        if (IS_ERR(devmap)) {
1220                rc = snprintf(buf, PAGE_SIZE, "ignore\n");
1221        } else {
1222                spin_lock(&dasd_devmap_lock);
1223                if (devmap->features & DASD_FEATURE_FAILONSLCK)
1224                        rc = snprintf(buf, PAGE_SIZE, "fail\n");
1225                else
1226                        rc = snprintf(buf, PAGE_SIZE, "ignore\n");
1227                spin_unlock(&dasd_devmap_lock);
1228        }
1229        return rc;
1230}
1231
1232static ssize_t dasd_reservation_policy_store(struct device *dev,
1233                                             struct device_attribute *attr,
1234                                             const char *buf, size_t count)
1235{
1236        struct dasd_devmap *devmap;
1237        int rc;
1238
1239        devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
1240        if (IS_ERR(devmap))
1241                return PTR_ERR(devmap);
1242        rc = 0;
1243        spin_lock(&dasd_devmap_lock);
1244        if (sysfs_streq("ignore", buf))
1245                devmap->features &= ~DASD_FEATURE_FAILONSLCK;
1246        else if (sysfs_streq("fail", buf))
1247                devmap->features |= DASD_FEATURE_FAILONSLCK;
1248        else
1249                rc = -EINVAL;
1250        if (devmap->device)
1251                devmap->device->features = devmap->features;
1252        spin_unlock(&dasd_devmap_lock);
1253        if (rc)
1254                return rc;
1255        else
1256                return count;
1257}
1258
1259static DEVICE_ATTR(reservation_policy, 0644,
1260                   dasd_reservation_policy_show, dasd_reservation_policy_store);
1261
1262static ssize_t dasd_reservation_state_show(struct device *dev,
1263                                           struct device_attribute *attr,
1264                                           char *buf)
1265{
1266        struct dasd_device *device;
1267        int rc = 0;
1268
1269        device = dasd_device_from_cdev(to_ccwdev(dev));
1270        if (IS_ERR(device))
1271                return snprintf(buf, PAGE_SIZE, "none\n");
1272
1273        if (test_bit(DASD_FLAG_IS_RESERVED, &device->flags))
1274                rc = snprintf(buf, PAGE_SIZE, "reserved\n");
1275        else if (test_bit(DASD_FLAG_LOCK_STOLEN, &device->flags))
1276                rc = snprintf(buf, PAGE_SIZE, "lost\n");
1277        else
1278                rc = snprintf(buf, PAGE_SIZE, "none\n");
1279        dasd_put_device(device);
1280        return rc;
1281}
1282
1283static ssize_t dasd_reservation_state_store(struct device *dev,
1284                                            struct device_attribute *attr,
1285                                            const char *buf, size_t count)
1286{
1287        struct dasd_device *device;
1288        int rc = 0;
1289
1290        device = dasd_device_from_cdev(to_ccwdev(dev));
1291        if (IS_ERR(device))
1292                return -ENODEV;
1293        if (sysfs_streq("reset", buf))
1294                clear_bit(DASD_FLAG_LOCK_STOLEN, &device->flags);
1295        else
1296                rc = -EINVAL;
1297        dasd_put_device(device);
1298
1299        if (rc)
1300                return rc;
1301        else
1302                return count;
1303}
1304
1305static DEVICE_ATTR(last_known_reservation_state, 0644,
1306                   dasd_reservation_state_show, dasd_reservation_state_store);
1307
1308static struct attribute * dasd_attrs[] = {
1309        &dev_attr_readonly.attr,
1310        &dev_attr_discipline.attr,
1311        &dev_attr_status.attr,
1312        &dev_attr_alias.attr,
1313        &dev_attr_vendor.attr,
1314        &dev_attr_uid.attr,
1315        &dev_attr_use_diag.attr,
1316        &dev_attr_raw_track_access.attr,
1317        &dev_attr_eer_enabled.attr,
1318        &dev_attr_erplog.attr,
1319        &dev_attr_failfast.attr,
1320        &dev_attr_expires.attr,
1321        &dev_attr_reservation_policy.attr,
1322        &dev_attr_last_known_reservation_state.attr,
1323        NULL,
1324};
1325
1326static struct attribute_group dasd_attr_group = {
1327        .attrs = dasd_attrs,
1328};
1329
1330/*
1331 * Return value of the specified feature.
1332 */
1333int
1334dasd_get_feature(struct ccw_device *cdev, int feature)
1335{
1336        struct dasd_devmap *devmap;
1337
1338        devmap = dasd_find_busid(dev_name(&cdev->dev));
1339        if (IS_ERR(devmap))
1340                return PTR_ERR(devmap);
1341
1342        return ((devmap->features & feature) != 0);
1343}
1344
1345/*
1346 * Set / reset given feature.
1347 * Flag indicates wether to set (!=0) or the reset (=0) the feature.
1348 */
1349int
1350dasd_set_feature(struct ccw_device *cdev, int feature, int flag)
1351{
1352        struct dasd_devmap *devmap;
1353
1354        devmap = dasd_find_busid(dev_name(&cdev->dev));
1355        if (IS_ERR(devmap))
1356                return PTR_ERR(devmap);
1357
1358        spin_lock(&dasd_devmap_lock);
1359        if (flag)
1360                devmap->features |= feature;
1361        else
1362                devmap->features &= ~feature;
1363        if (devmap->device)
1364                devmap->device->features = devmap->features;
1365        spin_unlock(&dasd_devmap_lock);
1366        return 0;
1367}
1368
1369
1370int
1371dasd_add_sysfs_files(struct ccw_device *cdev)
1372{
1373        return sysfs_create_group(&cdev->dev.kobj, &dasd_attr_group);
1374}
1375
1376void
1377dasd_remove_sysfs_files(struct ccw_device *cdev)
1378{
1379        sysfs_remove_group(&cdev->dev.kobj, &dasd_attr_group);
1380}
1381
1382
1383int
1384dasd_devmap_init(void)
1385{
1386        int i;
1387
1388        /* Initialize devmap structures. */
1389        dasd_max_devindex = 0;
1390        for (i = 0; i < 256; i++)
1391                INIT_LIST_HEAD(&dasd_hashlists[i]);
1392        return 0;
1393}
1394
1395void
1396dasd_devmap_exit(void)
1397{
1398        dasd_forget_ranges();
1399}
1400