1 /* 2 * File...........: linux/drivers/s390/block/dasd_devmap.c 3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> 4 * Horst Hummel <Horst.Hummel@de.ibm.com> 5 * Carsten Otte <Cotte@de.ibm.com> 6 * Martin Schwidefsky <schwidefsky@de.ibm.com> 7 * Bugreports.to..: <Linux390@de.ibm.com> 8 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001 9 * 10 * Device mapping and dasd= parameter parsing functions. All devmap 11 * functions may not be called from interrupt context. In particular 12 * dasd_get_device is a no-no from interrupt context. 13 * 14 */ 15 16 #define KMSG_COMPONENT "dasd" 17 18 #include <linux/ctype.h> 19 #include <linux/init.h> 20 #include <linux/module.h> 21 #include <linux/slab.h> 22 23 #include <asm/debug.h> 24 #include <asm/uaccess.h> 25 #include <asm/ipl.h> 26 27 /* This is ugly... */ 28 #define PRINTK_HEADER "dasd_devmap:" 29 #define DASD_BUS_ID_SIZE 20 30 31 #include "dasd_int.h" 32 33 struct kmem_cache *dasd_page_cache; 34 EXPORT_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 */ 46 struct 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 68 int dasd_probeonly = 0; /* is true, when probeonly mode is active */ 69 int dasd_autodetect = 0; /* is true, when autodetection is active */ 70 int dasd_nopav = 0; /* is true, when PAV is disabled */ 71 EXPORT_SYMBOL_GPL(dasd_nopav); 72 int dasd_nofcx; /* disable High Performance Ficon */ 73 EXPORT_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 */ 80 static char *dasd[256]; 81 module_param_array(dasd, charp, NULL, 0); 82 83 /* 84 * Single spinlock to protect devmap and servermap structures and lists. 85 */ 86 static DEFINE_SPINLOCK(dasd_devmap_lock); 87 88 /* 89 * Hash lists for devmap structures. 90 */ 91 static struct list_head dasd_hashlists[256]; 92 int dasd_max_devindex; 93 94 static struct dasd_devmap *dasd_add_busid(const char *, int); 95 96 static inline int 97 dasd_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 108 /* 109 * The parameter parsing functions for builtin-drivers are called 110 * before kmalloc works. Store the pointers to the parameters strings 111 * into dasd[] for later processing. 112 */ 113 static int __init 114 dasd_call_setup(char *str) 115 { 116 static int count = 0; 117 118 if (count < 256) 119 dasd[count++] = str; 120 return 1; 121 } 122 123 __setup ("dasd=", dasd_call_setup); 124 #endif /* #ifndef MODULE */ 125 126 #define DASD_IPLDEV "ipldev" 127 128 /* 129 * Read a device busid/devno from a string. 130 */ 131 static int 132 133 dasd_busid(char **str, int *id0, int *id1, int *devno) 134 { 135 int val, old_style; 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 *str += strlen(DASD_IPLDEV); 147 148 return 0; 149 } 150 /* check for leading '0x' */ 151 old_style = 0; 152 if ((*str)[0] == '0' && (*str)[1] == 'x') { 153 *str += 2; 154 old_style = 1; 155 } 156 if (!isxdigit((*str)[0])) /* We require at least one hex digit */ 157 return -EINVAL; 158 val = simple_strtoul(*str, str, 16); 159 if (old_style || (*str)[0] != '.') { 160 *id0 = *id1 = 0; 161 if (val < 0 || val > 0xffff) 162 return -EINVAL; 163 *devno = val; 164 return 0; 165 } 166 /* New style x.y.z busid */ 167 if (val < 0 || val > 0xff) 168 return -EINVAL; 169 *id0 = val; 170 (*str)++; 171 if (!isxdigit((*str)[0])) /* We require at least one hex digit */ 172 return -EINVAL; 173 val = simple_strtoul(*str, str, 16); 174 if (val < 0 || val > 0xff || (*str)++[0] != '.') 175 return -EINVAL; 176 *id1 = val; 177 if (!isxdigit((*str)[0])) /* We require at least one hex digit */ 178 return -EINVAL; 179 val = simple_strtoul(*str, str, 16); 180 if (val < 0 || val > 0xffff) 181 return -EINVAL; 182 *devno = val; 183 return 0; 184 } 185 186 /* 187 * Read colon separated list of dasd features. Currently there is 188 * only one: "ro" for read-only devices. The default feature set 189 * is empty (value 0). 190 */ 191 static int 192 dasd_feature_list(char *str, char **endp) 193 { 194 int features, len, rc; 195 196 rc = 0; 197 if (*str != '(') { 198 *endp = str; 199 return DASD_FEATURE_DEFAULT; 200 } 201 str++; 202 features = 0; 203 204 while (1) { 205 for (len = 0; 206 str[len] && str[len] != ':' && str[len] != ')'; len++); 207 if (len == 2 && !strncmp(str, "ro", 2)) 208 features |= DASD_FEATURE_READONLY; 209 else if (len == 4 && !strncmp(str, "diag", 4)) 210 features |= DASD_FEATURE_USEDIAG; 211 else if (len == 3 && !strncmp(str, "raw", 3)) 212 features |= DASD_FEATURE_USERAW; 213 else if (len == 6 && !strncmp(str, "erplog", 6)) 214 features |= DASD_FEATURE_ERPLOG; 215 else if (len == 8 && !strncmp(str, "failfast", 8)) 216 features |= DASD_FEATURE_FAILFAST; 217 else { 218 pr_warning("%*s is not a supported device option\n", 219 len, str); 220 rc = -EINVAL; 221 } 222 str += len; 223 if (*str != ':') 224 break; 225 str++; 226 } 227 if (*str != ')') { 228 pr_warning("A closing parenthesis ')' is missing in the " 229 "dasd= parameter\n"); 230 rc = -EINVAL; 231 } else 232 str++; 233 *endp = str; 234 if (rc != 0) 235 return rc; 236 return features; 237 } 238 239 /* 240 * Try to match the first element on the comma separated parse string 241 * with one of the known keywords. If a keyword is found, take the approprate 242 * action and return a pointer to the residual string. If the first element 243 * could not be matched to any keyword then return an error code. 244 */ 245 static char * 246 dasd_parse_keyword( char *parsestring ) { 247 248 char *nextcomma, *residual_str; 249 int length; 250 251 nextcomma = strchr(parsestring,','); 252 if (nextcomma) { 253 length = nextcomma - parsestring; 254 residual_str = nextcomma + 1; 255 } else { 256 length = strlen(parsestring); 257 residual_str = parsestring + length; 258 } 259 if (strncmp("autodetect", parsestring, length) == 0) { 260 dasd_autodetect = 1; 261 pr_info("The autodetection mode has been activated\n"); 262 return residual_str; 263 } 264 if (strncmp("probeonly", parsestring, length) == 0) { 265 dasd_probeonly = 1; 266 pr_info("The probeonly mode has been activated\n"); 267 return residual_str; 268 } 269 if (strncmp("nopav", parsestring, length) == 0) { 270 if (MACHINE_IS_VM) 271 pr_info("'nopav' is not supported on z/VM\n"); 272 else { 273 dasd_nopav = 1; 274 pr_info("PAV support has be deactivated\n"); 275 } 276 return residual_str; 277 } 278 if (strncmp("nofcx", parsestring, length) == 0) { 279 dasd_nofcx = 1; 280 pr_info("High Performance FICON support has been " 281 "deactivated\n"); 282 return residual_str; 283 } 284 if (strncmp("fixedbuffers", parsestring, length) == 0) { 285 if (dasd_page_cache) 286 return residual_str; 287 dasd_page_cache = 288 kmem_cache_create("dasd_page_cache", PAGE_SIZE, 289 PAGE_SIZE, SLAB_CACHE_DMA, 290 NULL); 291 if (!dasd_page_cache) 292 DBF_EVENT(DBF_WARNING, "%s", "Failed to create slab, " 293 "fixed buffer mode disabled."); 294 else 295 DBF_EVENT(DBF_INFO, "%s", 296 "turning on fixed buffer mode"); 297 return residual_str; 298 } 299 return ERR_PTR(-EINVAL); 300 } 301 302 /* 303 * Try to interprete the first element on the comma separated parse string 304 * as a device number or a range of devices. If the interpretation is 305 * successfull, create the matching dasd_devmap entries and return a pointer 306 * to the residual string. 307 * If interpretation fails or in case of an error, return an error code. 308 */ 309 static char * 310 dasd_parse_range( char *parsestring ) { 311 312 struct dasd_devmap *devmap; 313 int from, from_id0, from_id1; 314 int to, to_id0, to_id1; 315 int features, rc; 316 char bus_id[DASD_BUS_ID_SIZE+1], *str; 317 318 str = parsestring; 319 rc = dasd_busid(&str, &from_id0, &from_id1, &from); 320 if (rc == 0) { 321 to = from; 322 to_id0 = from_id0; 323 to_id1 = from_id1; 324 if (*str == '-') { 325 str++; 326 rc = dasd_busid(&str, &to_id0, &to_id1, &to); 327 } 328 } 329 if (rc == 0 && 330 (from_id0 != to_id0 || from_id1 != to_id1 || from > to)) 331 rc = -EINVAL; 332 if (rc) { 333 pr_err("%s is not a valid device range\n", parsestring); 334 return ERR_PTR(rc); 335 } 336 features = dasd_feature_list(str, &str); 337 if (features < 0) 338 return ERR_PTR(-EINVAL); 339 /* each device in dasd= parameter should be set initially online */ 340 features |= DASD_FEATURE_INITIAL_ONLINE; 341 while (from <= to) { 342 sprintf(bus_id, "%01x.%01x.%04x", 343 from_id0, from_id1, from++); 344 devmap = dasd_add_busid(bus_id, features); 345 if (IS_ERR(devmap)) 346 return (char *)devmap; 347 } 348 if (*str == ',') 349 return str + 1; 350 if (*str == '\0') 351 return str; 352 pr_warning("The dasd= parameter value %s has an invalid ending\n", 353 str); 354 return ERR_PTR(-EINVAL); 355 } 356 357 static char * 358 dasd_parse_next_element( char *parsestring ) { 359 char * residual_str; 360 residual_str = dasd_parse_keyword(parsestring); 361 if (!IS_ERR(residual_str)) 362 return residual_str; 363 residual_str = dasd_parse_range(parsestring); 364 return residual_str; 365 } 366 367 /* 368 * Parse parameters stored in dasd[] 369 * The 'dasd=...' parameter allows to specify a comma separated list of 370 * keywords and device ranges. When the dasd driver is build into the kernel, 371 * the complete list will be stored as one element of the dasd[] array. 372 * When the dasd driver is build as a module, then the list is broken into 373 * it's elements and each dasd[] entry contains one element. 374 */ 375 int 376 dasd_parse(void) 377 { 378 int rc, i; 379 char *parsestring; 380 381 rc = 0; 382 for (i = 0; i < 256; i++) { 383 if (dasd[i] == NULL) 384 break; 385 parsestring = dasd[i]; 386 /* loop over the comma separated list in the parsestring */ 387 while (*parsestring) { 388 parsestring = dasd_parse_next_element(parsestring); 389 if(IS_ERR(parsestring)) { 390 rc = PTR_ERR(parsestring); 391 break; 392 } 393 } 394 if (rc) { 395 DBF_EVENT(DBF_ALERT, "%s", "invalid range found"); 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 */ 408 static struct dasd_devmap * 409 dasd_add_busid(const char *bus_id, int features) 410 { 411 struct dasd_devmap *devmap, *new, *tmp; 412 int hash; 413 414 new = (struct dasd_devmap *) 415 kzalloc(sizeof(struct dasd_devmap), GFP_KERNEL); 416 if (!new) 417 return ERR_PTR(-ENOMEM); 418 spin_lock(&dasd_devmap_lock); 419 devmap = NULL; 420 hash = dasd_hash_busid(bus_id); 421 list_for_each_entry(tmp, &dasd_hashlists[hash], list) 422 if (strncmp(tmp->bus_id, bus_id, DASD_BUS_ID_SIZE) == 0) { 423 devmap = tmp; 424 break; 425 } 426 if (!devmap) { 427 /* This bus_id is new. */ 428 new->devindex = dasd_max_devindex++; 429 strncpy(new->bus_id, bus_id, DASD_BUS_ID_SIZE); 430 new->features = features; 431 new->device = NULL; 432 list_add(&new->list, &dasd_hashlists[hash]); 433 devmap = new; 434 new = NULL; 435 } 436 spin_unlock(&dasd_devmap_lock); 437 kfree(new); 438 return devmap; 439 } 440 441 /* 442 * Find devmap for device with given bus_id. 443 */ 444 static struct dasd_devmap * 445 dasd_find_busid(const char *bus_id) 446 { 447 struct dasd_devmap *devmap, *tmp; 448 int hash; 449 450 spin_lock(&dasd_devmap_lock); 451 devmap = ERR_PTR(-ENODEV); 452 hash = dasd_hash_busid(bus_id); 453 list_for_each_entry(tmp, &dasd_hashlists[hash], list) { 454 if (strncmp(tmp->bus_id, bus_id, DASD_BUS_ID_SIZE) == 0) { 455 devmap = tmp; 456 break; 457 } 458 } 459 spin_unlock(&dasd_devmap_lock); 460 return devmap; 461 } 462 463 /* 464 * Check if busid has been added to the list of dasd ranges. 465 */ 466 int 467 dasd_busid_known(const char *bus_id) 468 { 469 return IS_ERR(dasd_find_busid(bus_id)) ? -ENOENT : 0; 470 } 471 472 /* 473 * Forget all about the device numbers added so far. 474 * This may only be called at module unload or system shutdown. 475 */ 476 static void 477 dasd_forget_ranges(void) 478 { 479 struct dasd_devmap *devmap, *n; 480 int i; 481 482 spin_lock(&dasd_devmap_lock); 483 for (i = 0; i < 256; i++) { 484 list_for_each_entry_safe(devmap, n, &dasd_hashlists[i], list) { 485 BUG_ON(devmap->device != NULL); 486 list_del(&devmap->list); 487 kfree(devmap); 488 } 489 } 490 spin_unlock(&dasd_devmap_lock); 491 } 492 493 /* 494 * Find the device struct by its device index. 495 */ 496 struct dasd_device * 497 dasd_device_from_devindex(int devindex) 498 { 499 struct dasd_devmap *devmap, *tmp; 500 struct dasd_device *device; 501 int i; 502 503 spin_lock(&dasd_devmap_lock); 504 devmap = NULL; 505 for (i = 0; (i < 256) && !devmap; i++) 506 list_for_each_entry(tmp, &dasd_hashlists[i], list) 507 if (tmp->devindex == devindex) { 508 /* Found the devmap for the device. */ 509 devmap = tmp; 510 break; 511 } 512 if (devmap && devmap->device) { 513 device = devmap->device; 514 dasd_get_device(device); 515 } else 516 device = ERR_PTR(-ENODEV); 517 spin_unlock(&dasd_devmap_lock); 518 return device; 519 } 520 521 /* 522 * Return devmap for cdev. If no devmap exists yet, create one and 523 * connect it to the cdev. 524 */ 525 static struct dasd_devmap * 526 dasd_devmap_from_cdev(struct ccw_device *cdev) 527 { 528 struct dasd_devmap *devmap; 529 530 devmap = dasd_find_busid(dev_name(&cdev->dev)); 531 if (IS_ERR(devmap)) 532 devmap = dasd_add_busid(dev_name(&cdev->dev), 533 DASD_FEATURE_DEFAULT); 534 return devmap; 535 } 536 537 /* 538 * Create a dasd device structure for cdev. 539 */ 540 struct dasd_device * 541 dasd_create_device(struct ccw_device *cdev) 542 { 543 struct dasd_devmap *devmap; 544 struct dasd_device *device; 545 unsigned long flags; 546 int rc; 547 548 devmap = dasd_devmap_from_cdev(cdev); 549 if (IS_ERR(devmap)) 550 return (void *) devmap; 551 552 device = dasd_alloc_device(); 553 if (IS_ERR(device)) 554 return device; 555 atomic_set(&device->ref_count, 3); 556 557 spin_lock(&dasd_devmap_lock); 558 if (!devmap->device) { 559 devmap->device = device; 560 device->devindex = devmap->devindex; 561 device->features = devmap->features; 562 get_device(&cdev->dev); 563 device->cdev = cdev; 564 rc = 0; 565 } else 566 /* Someone else was faster. */ 567 rc = -EBUSY; 568 spin_unlock(&dasd_devmap_lock); 569 570 if (rc) { 571 dasd_free_device(device); 572 return ERR_PTR(rc); 573 } 574 575 spin_lock_irqsave(get_ccwdev_lock(cdev), flags); 576 dev_set_drvdata(&cdev->dev, device); 577 spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); 578 579 return device; 580 } 581 582 /* 583 * Wait queue for dasd_delete_device waits. 584 */ 585 static DECLARE_WAIT_QUEUE_HEAD(dasd_delete_wq); 586 587 /* 588 * Remove a dasd device structure. The passed referenced 589 * is destroyed. 590 */ 591 void 592 dasd_delete_device(struct dasd_device *device) 593 { 594 struct ccw_device *cdev; 595 struct dasd_devmap *devmap; 596 unsigned long flags; 597 598 /* First remove device pointer from devmap. */ 599 devmap = dasd_find_busid(dev_name(&device->cdev->dev)); 600 BUG_ON(IS_ERR(devmap)); 601 spin_lock(&dasd_devmap_lock); 602 if (devmap->device != device) { 603 spin_unlock(&dasd_devmap_lock); 604 dasd_put_device(device); 605 return; 606 } 607 devmap->device = NULL; 608 spin_unlock(&dasd_devmap_lock); 609 610 /* Disconnect dasd_device structure from ccw_device structure. */ 611 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); 612 dev_set_drvdata(&device->cdev->dev, NULL); 613 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); 614 615 /* 616 * Drop ref_count by 3, one for the devmap reference, one for 617 * the cdev reference and one for the passed reference. 618 */ 619 atomic_sub(3, &device->ref_count); 620 621 /* Wait for reference counter to drop to zero. */ 622 wait_event(dasd_delete_wq, atomic_read(&device->ref_count) == 0); 623 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 */ 639 void 640 dasd_put_device_wake(struct dasd_device *device) 641 { 642 wake_up(&dasd_delete_wq); 643 } 644 EXPORT_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 */ 651 struct dasd_device * 652 dasd_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 */ 665 struct dasd_device * 666 dasd_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 677 /* 678 * SECTION: files in sysfs 679 */ 680 681 /* 682 * failfast controls the behaviour, if no path is available 683 */ 684 static ssize_t dasd_ff_show(struct device *dev, struct device_attribute *attr, 685 char *buf) 686 { 687 struct dasd_devmap *devmap; 688 int ff_flag; 689 690 devmap = dasd_find_busid(dev_name(dev)); 691 if (!IS_ERR(devmap)) 692 ff_flag = (devmap->features & DASD_FEATURE_FAILFAST) != 0; 693 else 694 ff_flag = (DASD_FEATURE_DEFAULT & DASD_FEATURE_FAILFAST) != 0; 695 return snprintf(buf, PAGE_SIZE, ff_flag ? "1\n" : "0\n"); 696 } 697 698 static ssize_t dasd_ff_store(struct device *dev, struct device_attribute *attr, 699 const char *buf, size_t count) 700 { 701 struct dasd_devmap *devmap; 702 int val; 703 char *endp; 704 705 devmap = dasd_devmap_from_cdev(to_ccwdev(dev)); 706 if (IS_ERR(devmap)) 707 return PTR_ERR(devmap); 708 709 val = simple_strtoul(buf, &endp, 0); 710 if (((endp + 1) < (buf + count)) || (val > 1)) 711 return -EINVAL; 712 713 spin_lock(&dasd_devmap_lock); 714 if (val) 715 devmap->features |= DASD_FEATURE_FAILFAST; 716 else 717 devmap->features &= ~DASD_FEATURE_FAILFAST; 718 if (devmap->device) 719 devmap->device->features = devmap->features; 720 spin_unlock(&dasd_devmap_lock); 721 return count; 722 } 723 724 static DEVICE_ATTR(failfast, 0644, dasd_ff_show, dasd_ff_store); 725 726 /* 727 * readonly controls the readonly status of a dasd 728 */ 729 static ssize_t 730 dasd_ro_show(struct device *dev, struct device_attribute *attr, char *buf) 731 { 732 struct dasd_devmap *devmap; 733 int ro_flag; 734 735 devmap = dasd_find_busid(dev_name(dev)); 736 if (!IS_ERR(devmap)) 737 ro_flag = (devmap->features & DASD_FEATURE_READONLY) != 0; 738 else 739 ro_flag = (DASD_FEATURE_DEFAULT & DASD_FEATURE_READONLY) != 0; 740 return snprintf(buf, PAGE_SIZE, ro_flag ? "1\n" : "0\n"); 741 } 742 743 static ssize_t 744 dasd_ro_store(struct device *dev, struct device_attribute *attr, 745 const char *buf, size_t count) 746 { 747 struct dasd_devmap *devmap; 748 struct dasd_device *device; 749 int val; 750 char *endp; 751 752 devmap = dasd_devmap_from_cdev(to_ccwdev(dev)); 753 if (IS_ERR(devmap)) 754 return PTR_ERR(devmap); 755 756 val = simple_strtoul(buf, &endp, 0); 757 if (((endp + 1) < (buf + count)) || (val > 1)) 758 return -EINVAL; 759 760 spin_lock(&dasd_devmap_lock); 761 if (val) 762 devmap->features |= DASD_FEATURE_READONLY; 763 else 764 devmap->features &= ~DASD_FEATURE_READONLY; 765 device = devmap->device; 766 if (device) { 767 device->features = devmap->features; 768 val = val || test_bit(DASD_FLAG_DEVICE_RO, &device->flags); 769 } 770 spin_unlock(&dasd_devmap_lock); 771 if (device && device->block && device->block->gdp) 772 set_disk_ro(device->block->gdp, val); 773 return count; 774 } 775 776 static DEVICE_ATTR(readonly, 0644, dasd_ro_show, dasd_ro_store); 777 /* 778 * erplog controls the logging of ERP related data 779 * (e.g. failing channel programs). 780 */ 781 static ssize_t 782 dasd_erplog_show(struct device *dev, struct device_attribute *attr, char *buf) 783 { 784 struct dasd_devmap *devmap; 785 int erplog; 786 787 devmap = dasd_find_busid(dev_name(dev)); 788 if (!IS_ERR(devmap)) 789 erplog = (devmap->features & DASD_FEATURE_ERPLOG) != 0; 790 else 791 erplog = (DASD_FEATURE_DEFAULT & DASD_FEATURE_ERPLOG) != 0; 792 return snprintf(buf, PAGE_SIZE, erplog ? "1\n" : "0\n"); 793 } 794 795 static ssize_t 796 dasd_erplog_store(struct device *dev, struct device_attribute *attr, 797 const char *buf, size_t count) 798 { 799 struct dasd_devmap *devmap; 800 int val; 801 char *endp; 802 803 devmap = dasd_devmap_from_cdev(to_ccwdev(dev)); 804 if (IS_ERR(devmap)) 805 return PTR_ERR(devmap); 806 807 val = simple_strtoul(buf, &endp, 0); 808 if (((endp + 1) < (buf + count)) || (val > 1)) 809 return -EINVAL; 810 811 spin_lock(&dasd_devmap_lock); 812 if (val) 813 devmap->features |= DASD_FEATURE_ERPLOG; 814 else 815 devmap->features &= ~DASD_FEATURE_ERPLOG; 816 if (devmap->device) 817 devmap->device->features = devmap->features; 818 spin_unlock(&dasd_devmap_lock); 819 return count; 820 } 821 822 static DEVICE_ATTR(erplog, 0644, dasd_erplog_show, dasd_erplog_store); 823 824 /* 825 * use_diag controls whether the driver should use diag rather than ssch 826 * to talk to the device 827 */ 828 static ssize_t 829 dasd_use_diag_show(struct device *dev, struct device_attribute *attr, char *buf) 830 { 831 struct dasd_devmap *devmap; 832 int use_diag; 833 834 devmap = dasd_find_busid(dev_name(dev)); 835 if (!IS_ERR(devmap)) 836 use_diag = (devmap->features & DASD_FEATURE_USEDIAG) != 0; 837 else 838 use_diag = (DASD_FEATURE_DEFAULT & DASD_FEATURE_USEDIAG) != 0; 839 return sprintf(buf, use_diag ? "1\n" : "0\n"); 840 } 841 842 static ssize_t 843 dasd_use_diag_store(struct device *dev, struct device_attribute *attr, 844 const char *buf, size_t count) 845 { 846 struct dasd_devmap *devmap; 847 ssize_t rc; 848 int val; 849 char *endp; 850 851 devmap = dasd_devmap_from_cdev(to_ccwdev(dev)); 852 if (IS_ERR(devmap)) 853 return PTR_ERR(devmap); 854 855 val = simple_strtoul(buf, &endp, 0); 856 if (((endp + 1) < (buf + count)) || (val > 1)) 857 return -EINVAL; 858 859 spin_lock(&dasd_devmap_lock); 860 /* Changing diag discipline flag is only allowed in offline state. */ 861 rc = count; 862 if (!devmap->device && !(devmap->features & DASD_FEATURE_USERAW)) { 863 if (val) 864 devmap->features |= DASD_FEATURE_USEDIAG; 865 else 866 devmap->features &= ~DASD_FEATURE_USEDIAG; 867 } else 868 rc = -EPERM; 869 spin_unlock(&dasd_devmap_lock); 870 return rc; 871 } 872 873 static DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store); 874 875 /* 876 * use_raw controls whether the driver should give access to raw eckd data or 877 * operate in standard mode 878 */ 879 static ssize_t 880 dasd_use_raw_show(struct device *dev, struct device_attribute *attr, char *buf) 881 { 882 struct dasd_devmap *devmap; 883 int use_raw; 884 885 devmap = dasd_find_busid(dev_name(dev)); 886 if (!IS_ERR(devmap)) 887 use_raw = (devmap->features & DASD_FEATURE_USERAW) != 0; 888 else 889 use_raw = (DASD_FEATURE_DEFAULT & DASD_FEATURE_USERAW) != 0; 890 return sprintf(buf, use_raw ? "1\n" : "0\n"); 891 } 892 893 static ssize_t 894 dasd_use_raw_store(struct device *dev, struct device_attribute *attr, 895 const char *buf, size_t count) 896 { 897 struct dasd_devmap *devmap; 898 ssize_t rc; 899 unsigned long val; 900 901 devmap = dasd_devmap_from_cdev(to_ccwdev(dev)); 902 if (IS_ERR(devmap)) 903 return PTR_ERR(devmap); 904 905 if ((strict_strtoul(buf, 10, &val) != 0) || val > 1) 906 return -EINVAL; 907 908 spin_lock(&dasd_devmap_lock); 909 /* Changing diag discipline flag is only allowed in offline state. */ 910 rc = count; 911 if (!devmap->device && !(devmap->features & DASD_FEATURE_USEDIAG)) { 912 if (val) 913 devmap->features |= DASD_FEATURE_USERAW; 914 else 915 devmap->features &= ~DASD_FEATURE_USERAW; 916 } else 917 rc = -EPERM; 918 spin_unlock(&dasd_devmap_lock); 919 return rc; 920 } 921 922 static DEVICE_ATTR(raw_track_access, 0644, dasd_use_raw_show, 923 dasd_use_raw_store); 924 925 static ssize_t 926 dasd_discipline_show(struct device *dev, struct device_attribute *attr, 927 char *buf) 928 { 929 struct dasd_device *device; 930 ssize_t len; 931 932 device = dasd_device_from_cdev(to_ccwdev(dev)); 933 if (IS_ERR(device)) 934 goto out; 935 else if (!device->discipline) { 936 dasd_put_device(device); 937 goto out; 938 } else { 939 len = snprintf(buf, PAGE_SIZE, "%s\n", 940 device->discipline->name); 941 dasd_put_device(device); 942 return len; 943 } 944 out: 945 len = snprintf(buf, PAGE_SIZE, "none\n"); 946 return len; 947 } 948 949 static DEVICE_ATTR(discipline, 0444, dasd_discipline_show, NULL); 950 951 static ssize_t 952 dasd_device_status_show(struct device *dev, struct device_attribute *attr, 953 char *buf) 954 { 955 struct dasd_device *device; 956 ssize_t len; 957 958 device = dasd_device_from_cdev(to_ccwdev(dev)); 959 if (!IS_ERR(device)) { 960 switch (device->state) { 961 case DASD_STATE_NEW: 962 len = snprintf(buf, PAGE_SIZE, "new\n"); 963 break; 964 case DASD_STATE_KNOWN: 965 len = snprintf(buf, PAGE_SIZE, "detected\n"); 966 break; 967 case DASD_STATE_BASIC: 968 len = snprintf(buf, PAGE_SIZE, "basic\n"); 969 break; 970 case DASD_STATE_UNFMT: 971 len = snprintf(buf, PAGE_SIZE, "unformatted\n"); 972 break; 973 case DASD_STATE_READY: 974 len = snprintf(buf, PAGE_SIZE, "ready\n"); 975 break; 976 case DASD_STATE_ONLINE: 977 len = snprintf(buf, PAGE_SIZE, "online\n"); 978 break; 979 default: 980 len = snprintf(buf, PAGE_SIZE, "no stat\n"); 981 break; 982 } 983 dasd_put_device(device); 984 } else 985 len = snprintf(buf, PAGE_SIZE, "unknown\n"); 986 return len; 987 } 988 989 static DEVICE_ATTR(status, 0444, dasd_device_status_show, NULL); 990 991 static ssize_t dasd_alias_show(struct device *dev, 992 struct device_attribute *attr, char *buf) 993 { 994 struct dasd_device *device; 995 struct dasd_uid uid; 996 997 device = dasd_device_from_cdev(to_ccwdev(dev)); 998 if (IS_ERR(device)) 999 return sprintf(buf, "0\n"); 1000 1001 if (device->discipline && device->discipline->get_uid && 1002 !device->discipline->get_uid(device, &uid)) { 1003 if (uid.type == UA_BASE_PAV_ALIAS || 1004 uid.type == UA_HYPER_PAV_ALIAS) { 1005 dasd_put_device(device); 1006 return sprintf(buf, "1\n"); 1007 } 1008 } 1009 dasd_put_device(device); 1010 1011 return sprintf(buf, "0\n"); 1012 } 1013 1014 static DEVICE_ATTR(alias, 0444, dasd_alias_show, NULL); 1015 1016 static ssize_t dasd_vendor_show(struct device *dev, 1017 struct device_attribute *attr, char *buf) 1018 { 1019 struct dasd_device *device; 1020 struct dasd_uid uid; 1021 char *vendor; 1022 1023 device = dasd_device_from_cdev(to_ccwdev(dev)); 1024 vendor = ""; 1025 if (IS_ERR(device)) 1026 return snprintf(buf, PAGE_SIZE, "%s\n", vendor); 1027 1028 if (device->discipline && device->discipline->get_uid && 1029 !device->discipline->get_uid(device, &uid)) 1030 vendor = uid.vendor; 1031 1032 dasd_put_device(device); 1033 1034 return snprintf(buf, PAGE_SIZE, "%s\n", vendor); 1035 } 1036 1037 static DEVICE_ATTR(vendor, 0444, dasd_vendor_show, NULL); 1038 1039 #define UID_STRLEN ( /* vendor */ 3 + 1 + /* serial */ 14 + 1 +\ 1040 /* SSID */ 4 + 1 + /* unit addr */ 2 + 1 +\ 1041 /* vduit */ 32 + 1) 1042 1043 static ssize_t 1044 dasd_uid_show(struct device *dev, struct device_attribute *attr, char *buf) 1045 { 1046 struct dasd_device *device; 1047 struct dasd_uid uid; 1048 char uid_string[UID_STRLEN]; 1049 char ua_string[3]; 1050 1051 device = dasd_device_from_cdev(to_ccwdev(dev)); 1052 uid_string[0] = 0; 1053 if (IS_ERR(device)) 1054 return snprintf(buf, PAGE_SIZE, "%s\n", uid_string); 1055 1056 if (device->discipline && device->discipline->get_uid && 1057 !device->discipline->get_uid(device, &uid)) { 1058 switch (uid.type) { 1059 case UA_BASE_DEVICE: 1060 snprintf(ua_string, sizeof(ua_string), "%02x", 1061 uid.real_unit_addr); 1062 break; 1063 case UA_BASE_PAV_ALIAS: 1064 snprintf(ua_string, sizeof(ua_string), "%02x", 1065 uid.base_unit_addr); 1066 break; 1067 case UA_HYPER_PAV_ALIAS: 1068 snprintf(ua_string, sizeof(ua_string), "xx"); 1069 break; 1070 default: 1071 /* should not happen, treat like base device */ 1072 snprintf(ua_string, sizeof(ua_string), "%02x", 1073 uid.real_unit_addr); 1074 break; 1075 } 1076 1077 if (strlen(uid.vduit) > 0) 1078 snprintf(uid_string, sizeof(uid_string), 1079 "%s.%s.%04x.%s.%s", 1080 uid.vendor, uid.serial, uid.ssid, ua_string, 1081 uid.vduit); 1082 else 1083 snprintf(uid_string, sizeof(uid_string), 1084 "%s.%s.%04x.%s", 1085 uid.vendor, uid.serial, uid.ssid, ua_string); 1086 } 1087 dasd_put_device(device); 1088 1089 return snprintf(buf, PAGE_SIZE, "%s\n", uid_string); 1090 } 1091 static DEVICE_ATTR(uid, 0444, dasd_uid_show, NULL); 1092 1093 /* 1094 * extended error-reporting 1095 */ 1096 static ssize_t 1097 dasd_eer_show(struct device *dev, struct device_attribute *attr, char *buf) 1098 { 1099 struct dasd_devmap *devmap; 1100 int eer_flag; 1101 1102 devmap = dasd_find_busid(dev_name(dev)); 1103 if (!IS_ERR(devmap) && devmap->device) 1104 eer_flag = dasd_eer_enabled(devmap->device); 1105 else 1106 eer_flag = 0; 1107 return snprintf(buf, PAGE_SIZE, eer_flag ? "1\n" : "0\n"); 1108 } 1109 1110 static ssize_t 1111 dasd_eer_store(struct device *dev, struct device_attribute *attr, 1112 const char *buf, size_t count) 1113 { 1114 struct dasd_devmap *devmap; 1115 int val, rc; 1116 char *endp; 1117 1118 devmap = dasd_devmap_from_cdev(to_ccwdev(dev)); 1119 if (IS_ERR(devmap)) 1120 return PTR_ERR(devmap); 1121 if (!devmap->device) 1122 return -ENODEV; 1123 1124 val = simple_strtoul(buf, &endp, 0); 1125 if (((endp + 1) < (buf + count)) || (val > 1)) 1126 return -EINVAL; 1127 1128 if (val) { 1129 rc = dasd_eer_enable(devmap->device); 1130 if (rc) 1131 return rc; 1132 } else 1133 dasd_eer_disable(devmap->device); 1134 return count; 1135 } 1136 1137 static DEVICE_ATTR(eer_enabled, 0644, dasd_eer_show, dasd_eer_store); 1138 1139 /* 1140 * expiration time for default requests 1141 */ 1142 static ssize_t 1143 dasd_expires_show(struct device *dev, struct device_attribute *attr, char *buf) 1144 { 1145 struct dasd_device *device; 1146 int len; 1147 1148 device = dasd_device_from_cdev(to_ccwdev(dev)); 1149 if (IS_ERR(device)) 1150 return -ENODEV; 1151 len = snprintf(buf, PAGE_SIZE, "%lu\n", device->default_expires); 1152 dasd_put_device(device); 1153 return len; 1154 } 1155 1156 static ssize_t 1157 dasd_expires_store(struct device *dev, struct device_attribute *attr, 1158 const char *buf, size_t count) 1159 { 1160 struct dasd_device *device; 1161 unsigned long val; 1162 1163 device = dasd_device_from_cdev(to_ccwdev(dev)); 1164 if (IS_ERR(device)) 1165 return -ENODEV; 1166 1167 if ((strict_strtoul(buf, 10, &val) != 0) || 1168 (val > DASD_EXPIRES_MAX) || val == 0) { 1169 dasd_put_device(device); 1170 return -EINVAL; 1171 } 1172 1173 if (val) 1174 device->default_expires = val; 1175 1176 dasd_put_device(device); 1177 return count; 1178 } 1179 1180 static DEVICE_ATTR(expires, 0644, dasd_expires_show, dasd_expires_store); 1181 1182 static ssize_t dasd_reservation_policy_show(struct device *dev, 1183 struct device_attribute *attr, 1184 char *buf) 1185 { 1186 struct dasd_devmap *devmap; 1187 int rc = 0; 1188 1189 devmap = dasd_find_busid(dev_name(dev)); 1190 if (IS_ERR(devmap)) { 1191 rc = snprintf(buf, PAGE_SIZE, "ignore\n"); 1192 } else { 1193 spin_lock(&dasd_devmap_lock); 1194 if (devmap->features & DASD_FEATURE_FAILONSLCK) 1195 rc = snprintf(buf, PAGE_SIZE, "fail\n"); 1196 else 1197 rc = snprintf(buf, PAGE_SIZE, "ignore\n"); 1198 spin_unlock(&dasd_devmap_lock); 1199 } 1200 return rc; 1201 } 1202 1203 static ssize_t dasd_reservation_policy_store(struct device *dev, 1204 struct device_attribute *attr, 1205 const char *buf, size_t count) 1206 { 1207 struct dasd_devmap *devmap; 1208 int rc; 1209 1210 devmap = dasd_devmap_from_cdev(to_ccwdev(dev)); 1211 if (IS_ERR(devmap)) 1212 return PTR_ERR(devmap); 1213 rc = 0; 1214 spin_lock(&dasd_devmap_lock); 1215 if (sysfs_streq("ignore", buf)) 1216 devmap->features &= ~DASD_FEATURE_FAILONSLCK; 1217 else if (sysfs_streq("fail", buf)) 1218 devmap->features |= DASD_FEATURE_FAILONSLCK; 1219 else 1220 rc = -EINVAL; 1221 if (devmap->device) 1222 devmap->device->features = devmap->features; 1223 spin_unlock(&dasd_devmap_lock); 1224 if (rc) 1225 return rc; 1226 else 1227 return count; 1228 } 1229 1230 static DEVICE_ATTR(reservation_policy, 0644, 1231 dasd_reservation_policy_show, dasd_reservation_policy_store); 1232 1233 static ssize_t dasd_reservation_state_show(struct device *dev, 1234 struct device_attribute *attr, 1235 char *buf) 1236 { 1237 struct dasd_device *device; 1238 int rc = 0; 1239 1240 device = dasd_device_from_cdev(to_ccwdev(dev)); 1241 if (IS_ERR(device)) 1242 return snprintf(buf, PAGE_SIZE, "none\n"); 1243 1244 if (test_bit(DASD_FLAG_IS_RESERVED, &device->flags)) 1245 rc = snprintf(buf, PAGE_SIZE, "reserved\n"); 1246 else if (test_bit(DASD_FLAG_LOCK_STOLEN, &device->flags)) 1247 rc = snprintf(buf, PAGE_SIZE, "lost\n"); 1248 else 1249 rc = snprintf(buf, PAGE_SIZE, "none\n"); 1250 dasd_put_device(device); 1251 return rc; 1252 } 1253 1254 static ssize_t dasd_reservation_state_store(struct device *dev, 1255 struct device_attribute *attr, 1256 const char *buf, size_t count) 1257 { 1258 struct dasd_device *device; 1259 int rc = 0; 1260 1261 device = dasd_device_from_cdev(to_ccwdev(dev)); 1262 if (IS_ERR(device)) 1263 return -ENODEV; 1264 if (sysfs_streq("reset", buf)) 1265 clear_bit(DASD_FLAG_LOCK_STOLEN, &device->flags); 1266 else 1267 rc = -EINVAL; 1268 dasd_put_device(device); 1269 1270 if (rc) 1271 return rc; 1272 else 1273 return count; 1274 } 1275 1276 static DEVICE_ATTR(last_known_reservation_state, 0644, 1277 dasd_reservation_state_show, dasd_reservation_state_store); 1278 1279 static struct attribute * dasd_attrs[] = { 1280 &dev_attr_readonly.attr, 1281 &dev_attr_discipline.attr, 1282 &dev_attr_status.attr, 1283 &dev_attr_alias.attr, 1284 &dev_attr_vendor.attr, 1285 &dev_attr_uid.attr, 1286 &dev_attr_use_diag.attr, 1287 &dev_attr_raw_track_access.attr, 1288 &dev_attr_eer_enabled.attr, 1289 &dev_attr_erplog.attr, 1290 &dev_attr_failfast.attr, 1291 &dev_attr_expires.attr, 1292 &dev_attr_reservation_policy.attr, 1293 &dev_attr_last_known_reservation_state.attr, 1294 NULL, 1295 }; 1296 1297 static struct attribute_group dasd_attr_group = { 1298 .attrs = dasd_attrs, 1299 }; 1300 1301 /* 1302 * Return value of the specified feature. 1303 */ 1304 int 1305 dasd_get_feature(struct ccw_device *cdev, int feature) 1306 { 1307 struct dasd_devmap *devmap; 1308 1309 devmap = dasd_find_busid(dev_name(&cdev->dev)); 1310 if (IS_ERR(devmap)) 1311 return PTR_ERR(devmap); 1312 1313 return ((devmap->features & feature) != 0); 1314 } 1315 1316 /* 1317 * Set / reset given feature. 1318 * Flag indicates wether to set (!=0) or the reset (=0) the feature. 1319 */ 1320 int 1321 dasd_set_feature(struct ccw_device *cdev, int feature, int flag) 1322 { 1323 struct dasd_devmap *devmap; 1324 1325 devmap = dasd_find_busid(dev_name(&cdev->dev)); 1326 if (IS_ERR(devmap)) 1327 return PTR_ERR(devmap); 1328 1329 spin_lock(&dasd_devmap_lock); 1330 if (flag) 1331 devmap->features |= feature; 1332 else 1333 devmap->features &= ~feature; 1334 if (devmap->device) 1335 devmap->device->features = devmap->features; 1336 spin_unlock(&dasd_devmap_lock); 1337 return 0; 1338 } 1339 1340 1341 int 1342 dasd_add_sysfs_files(struct ccw_device *cdev) 1343 { 1344 return sysfs_create_group(&cdev->dev.kobj, &dasd_attr_group); 1345 } 1346 1347 void 1348 dasd_remove_sysfs_files(struct ccw_device *cdev) 1349 { 1350 sysfs_remove_group(&cdev->dev.kobj, &dasd_attr_group); 1351 } 1352 1353 1354 int 1355 dasd_devmap_init(void) 1356 { 1357 int i; 1358 1359 /* Initialize devmap structures. */ 1360 dasd_max_devindex = 0; 1361 for (i = 0; i < 256; i++) 1362 INIT_LIST_HEAD(&dasd_hashlists[i]); 1363 return 0; 1364 } 1365 1366 void 1367 dasd_devmap_exit(void) 1368 { 1369 dasd_forget_ranges(); 1370 } 1371