at v3.2 35 kB view raw
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 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[256]; 81module_param_array(dasd, charp, NULL, 0); 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 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 */ 113static int __init 114dasd_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 */ 131static int 132 133dasd_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 */ 191static int 192dasd_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 */ 245static char * 246dasd_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 * successful, 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 */ 309static char * 310dasd_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 357static char * 358dasd_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 */ 375int 376dasd_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 */ 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 = (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 */ 444static struct dasd_devmap * 445dasd_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 */ 466int 467dasd_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 */ 476static void 477dasd_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 */ 496struct dasd_device * 497dasd_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 */ 525static struct dasd_devmap * 526dasd_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 */ 540struct dasd_device * 541dasd_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 */ 585static DECLARE_WAIT_QUEUE_HEAD(dasd_delete_wq); 586 587/* 588 * Remove a dasd device structure. The passed referenced 589 * is destroyed. 590 */ 591void 592dasd_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 */ 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 struct dasd_devmap *devmap; 732 int val; 733 char *endp; 734 735 devmap = dasd_devmap_from_cdev(to_ccwdev(dev)); 736 if (IS_ERR(devmap)) 737 return PTR_ERR(devmap); 738 739 val = simple_strtoul(buf, &endp, 0); 740 if (((endp + 1) < (buf + count)) || (val > 1)) 741 return -EINVAL; 742 743 spin_lock(&dasd_devmap_lock); 744 if (val) 745 devmap->features |= DASD_FEATURE_FAILFAST; 746 else 747 devmap->features &= ~DASD_FEATURE_FAILFAST; 748 if (devmap->device) 749 devmap->device->features = devmap->features; 750 spin_unlock(&dasd_devmap_lock); 751 return count; 752} 753 754static DEVICE_ATTR(failfast, 0644, dasd_ff_show, dasd_ff_store); 755 756/* 757 * readonly controls the readonly status of a dasd 758 */ 759static ssize_t 760dasd_ro_show(struct device *dev, struct device_attribute *attr, char *buf) 761{ 762 struct dasd_devmap *devmap; 763 int ro_flag; 764 765 devmap = dasd_find_busid(dev_name(dev)); 766 if (!IS_ERR(devmap)) 767 ro_flag = (devmap->features & DASD_FEATURE_READONLY) != 0; 768 else 769 ro_flag = (DASD_FEATURE_DEFAULT & DASD_FEATURE_READONLY) != 0; 770 return snprintf(buf, PAGE_SIZE, ro_flag ? "1\n" : "0\n"); 771} 772 773static ssize_t 774dasd_ro_store(struct device *dev, struct device_attribute *attr, 775 const char *buf, size_t count) 776{ 777 struct dasd_devmap *devmap; 778 struct dasd_device *device; 779 int val; 780 char *endp; 781 782 devmap = dasd_devmap_from_cdev(to_ccwdev(dev)); 783 if (IS_ERR(devmap)) 784 return PTR_ERR(devmap); 785 786 val = simple_strtoul(buf, &endp, 0); 787 if (((endp + 1) < (buf + count)) || (val > 1)) 788 return -EINVAL; 789 790 spin_lock(&dasd_devmap_lock); 791 if (val) 792 devmap->features |= DASD_FEATURE_READONLY; 793 else 794 devmap->features &= ~DASD_FEATURE_READONLY; 795 device = devmap->device; 796 if (device) { 797 device->features = devmap->features; 798 val = val || test_bit(DASD_FLAG_DEVICE_RO, &device->flags); 799 } 800 spin_unlock(&dasd_devmap_lock); 801 if (device && device->block && device->block->gdp) 802 set_disk_ro(device->block->gdp, val); 803 return count; 804} 805 806static DEVICE_ATTR(readonly, 0644, dasd_ro_show, dasd_ro_store); 807/* 808 * erplog controls the logging of ERP related data 809 * (e.g. failing channel programs). 810 */ 811static ssize_t 812dasd_erplog_show(struct device *dev, struct device_attribute *attr, char *buf) 813{ 814 struct dasd_devmap *devmap; 815 int erplog; 816 817 devmap = dasd_find_busid(dev_name(dev)); 818 if (!IS_ERR(devmap)) 819 erplog = (devmap->features & DASD_FEATURE_ERPLOG) != 0; 820 else 821 erplog = (DASD_FEATURE_DEFAULT & DASD_FEATURE_ERPLOG) != 0; 822 return snprintf(buf, PAGE_SIZE, erplog ? "1\n" : "0\n"); 823} 824 825static ssize_t 826dasd_erplog_store(struct device *dev, struct device_attribute *attr, 827 const char *buf, size_t count) 828{ 829 struct dasd_devmap *devmap; 830 int val; 831 char *endp; 832 833 devmap = dasd_devmap_from_cdev(to_ccwdev(dev)); 834 if (IS_ERR(devmap)) 835 return PTR_ERR(devmap); 836 837 val = simple_strtoul(buf, &endp, 0); 838 if (((endp + 1) < (buf + count)) || (val > 1)) 839 return -EINVAL; 840 841 spin_lock(&dasd_devmap_lock); 842 if (val) 843 devmap->features |= DASD_FEATURE_ERPLOG; 844 else 845 devmap->features &= ~DASD_FEATURE_ERPLOG; 846 if (devmap->device) 847 devmap->device->features = devmap->features; 848 spin_unlock(&dasd_devmap_lock); 849 return count; 850} 851 852static DEVICE_ATTR(erplog, 0644, dasd_erplog_show, dasd_erplog_store); 853 854/* 855 * use_diag controls whether the driver should use diag rather than ssch 856 * to talk to the device 857 */ 858static ssize_t 859dasd_use_diag_show(struct device *dev, struct device_attribute *attr, char *buf) 860{ 861 struct dasd_devmap *devmap; 862 int use_diag; 863 864 devmap = dasd_find_busid(dev_name(dev)); 865 if (!IS_ERR(devmap)) 866 use_diag = (devmap->features & DASD_FEATURE_USEDIAG) != 0; 867 else 868 use_diag = (DASD_FEATURE_DEFAULT & DASD_FEATURE_USEDIAG) != 0; 869 return sprintf(buf, use_diag ? "1\n" : "0\n"); 870} 871 872static ssize_t 873dasd_use_diag_store(struct device *dev, struct device_attribute *attr, 874 const char *buf, size_t count) 875{ 876 struct dasd_devmap *devmap; 877 ssize_t rc; 878 int val; 879 char *endp; 880 881 devmap = dasd_devmap_from_cdev(to_ccwdev(dev)); 882 if (IS_ERR(devmap)) 883 return PTR_ERR(devmap); 884 885 val = simple_strtoul(buf, &endp, 0); 886 if (((endp + 1) < (buf + count)) || (val > 1)) 887 return -EINVAL; 888 889 spin_lock(&dasd_devmap_lock); 890 /* Changing diag discipline flag is only allowed in offline state. */ 891 rc = count; 892 if (!devmap->device && !(devmap->features & DASD_FEATURE_USERAW)) { 893 if (val) 894 devmap->features |= DASD_FEATURE_USEDIAG; 895 else 896 devmap->features &= ~DASD_FEATURE_USEDIAG; 897 } else 898 rc = -EPERM; 899 spin_unlock(&dasd_devmap_lock); 900 return rc; 901} 902 903static DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store); 904 905/* 906 * use_raw controls whether the driver should give access to raw eckd data or 907 * operate in standard mode 908 */ 909static ssize_t 910dasd_use_raw_show(struct device *dev, struct device_attribute *attr, char *buf) 911{ 912 struct dasd_devmap *devmap; 913 int use_raw; 914 915 devmap = dasd_find_busid(dev_name(dev)); 916 if (!IS_ERR(devmap)) 917 use_raw = (devmap->features & DASD_FEATURE_USERAW) != 0; 918 else 919 use_raw = (DASD_FEATURE_DEFAULT & DASD_FEATURE_USERAW) != 0; 920 return sprintf(buf, use_raw ? "1\n" : "0\n"); 921} 922 923static ssize_t 924dasd_use_raw_store(struct device *dev, struct device_attribute *attr, 925 const char *buf, size_t count) 926{ 927 struct dasd_devmap *devmap; 928 ssize_t rc; 929 unsigned long val; 930 931 devmap = dasd_devmap_from_cdev(to_ccwdev(dev)); 932 if (IS_ERR(devmap)) 933 return PTR_ERR(devmap); 934 935 if ((strict_strtoul(buf, 10, &val) != 0) || val > 1) 936 return -EINVAL; 937 938 spin_lock(&dasd_devmap_lock); 939 /* Changing diag discipline flag is only allowed in offline state. */ 940 rc = count; 941 if (!devmap->device && !(devmap->features & DASD_FEATURE_USEDIAG)) { 942 if (val) 943 devmap->features |= DASD_FEATURE_USERAW; 944 else 945 devmap->features &= ~DASD_FEATURE_USERAW; 946 } else 947 rc = -EPERM; 948 spin_unlock(&dasd_devmap_lock); 949 return rc; 950} 951 952static DEVICE_ATTR(raw_track_access, 0644, dasd_use_raw_show, 953 dasd_use_raw_store); 954 955static ssize_t 956dasd_discipline_show(struct device *dev, struct device_attribute *attr, 957 char *buf) 958{ 959 struct dasd_device *device; 960 ssize_t len; 961 962 device = dasd_device_from_cdev(to_ccwdev(dev)); 963 if (IS_ERR(device)) 964 goto out; 965 else if (!device->discipline) { 966 dasd_put_device(device); 967 goto out; 968 } else { 969 len = snprintf(buf, PAGE_SIZE, "%s\n", 970 device->discipline->name); 971 dasd_put_device(device); 972 return len; 973 } 974out: 975 len = snprintf(buf, PAGE_SIZE, "none\n"); 976 return len; 977} 978 979static DEVICE_ATTR(discipline, 0444, dasd_discipline_show, NULL); 980 981static ssize_t 982dasd_device_status_show(struct device *dev, struct device_attribute *attr, 983 char *buf) 984{ 985 struct dasd_device *device; 986 ssize_t len; 987 988 device = dasd_device_from_cdev(to_ccwdev(dev)); 989 if (!IS_ERR(device)) { 990 switch (device->state) { 991 case DASD_STATE_NEW: 992 len = snprintf(buf, PAGE_SIZE, "new\n"); 993 break; 994 case DASD_STATE_KNOWN: 995 len = snprintf(buf, PAGE_SIZE, "detected\n"); 996 break; 997 case DASD_STATE_BASIC: 998 len = snprintf(buf, PAGE_SIZE, "basic\n"); 999 break; 1000 case DASD_STATE_UNFMT: 1001 len = snprintf(buf, PAGE_SIZE, "unformatted\n"); 1002 break; 1003 case DASD_STATE_READY: 1004 len = snprintf(buf, PAGE_SIZE, "ready\n"); 1005 break; 1006 case DASD_STATE_ONLINE: 1007 len = snprintf(buf, PAGE_SIZE, "online\n"); 1008 break; 1009 default: 1010 len = snprintf(buf, PAGE_SIZE, "no stat\n"); 1011 break; 1012 } 1013 dasd_put_device(device); 1014 } else 1015 len = snprintf(buf, PAGE_SIZE, "unknown\n"); 1016 return len; 1017} 1018 1019static DEVICE_ATTR(status, 0444, dasd_device_status_show, NULL); 1020 1021static ssize_t dasd_alias_show(struct device *dev, 1022 struct device_attribute *attr, char *buf) 1023{ 1024 struct dasd_device *device; 1025 struct dasd_uid uid; 1026 1027 device = dasd_device_from_cdev(to_ccwdev(dev)); 1028 if (IS_ERR(device)) 1029 return sprintf(buf, "0\n"); 1030 1031 if (device->discipline && device->discipline->get_uid && 1032 !device->discipline->get_uid(device, &uid)) { 1033 if (uid.type == UA_BASE_PAV_ALIAS || 1034 uid.type == UA_HYPER_PAV_ALIAS) { 1035 dasd_put_device(device); 1036 return sprintf(buf, "1\n"); 1037 } 1038 } 1039 dasd_put_device(device); 1040 1041 return sprintf(buf, "0\n"); 1042} 1043 1044static DEVICE_ATTR(alias, 0444, dasd_alias_show, NULL); 1045 1046static ssize_t dasd_vendor_show(struct device *dev, 1047 struct device_attribute *attr, char *buf) 1048{ 1049 struct dasd_device *device; 1050 struct dasd_uid uid; 1051 char *vendor; 1052 1053 device = dasd_device_from_cdev(to_ccwdev(dev)); 1054 vendor = ""; 1055 if (IS_ERR(device)) 1056 return snprintf(buf, PAGE_SIZE, "%s\n", vendor); 1057 1058 if (device->discipline && device->discipline->get_uid && 1059 !device->discipline->get_uid(device, &uid)) 1060 vendor = uid.vendor; 1061 1062 dasd_put_device(device); 1063 1064 return snprintf(buf, PAGE_SIZE, "%s\n", vendor); 1065} 1066 1067static DEVICE_ATTR(vendor, 0444, dasd_vendor_show, NULL); 1068 1069#define UID_STRLEN ( /* vendor */ 3 + 1 + /* serial */ 14 + 1 +\ 1070 /* SSID */ 4 + 1 + /* unit addr */ 2 + 1 +\ 1071 /* vduit */ 32 + 1) 1072 1073static ssize_t 1074dasd_uid_show(struct device *dev, struct device_attribute *attr, char *buf) 1075{ 1076 struct dasd_device *device; 1077 struct dasd_uid uid; 1078 char uid_string[UID_STRLEN]; 1079 char ua_string[3]; 1080 1081 device = dasd_device_from_cdev(to_ccwdev(dev)); 1082 uid_string[0] = 0; 1083 if (IS_ERR(device)) 1084 return snprintf(buf, PAGE_SIZE, "%s\n", uid_string); 1085 1086 if (device->discipline && device->discipline->get_uid && 1087 !device->discipline->get_uid(device, &uid)) { 1088 switch (uid.type) { 1089 case UA_BASE_DEVICE: 1090 snprintf(ua_string, sizeof(ua_string), "%02x", 1091 uid.real_unit_addr); 1092 break; 1093 case UA_BASE_PAV_ALIAS: 1094 snprintf(ua_string, sizeof(ua_string), "%02x", 1095 uid.base_unit_addr); 1096 break; 1097 case UA_HYPER_PAV_ALIAS: 1098 snprintf(ua_string, sizeof(ua_string), "xx"); 1099 break; 1100 default: 1101 /* should not happen, treat like base device */ 1102 snprintf(ua_string, sizeof(ua_string), "%02x", 1103 uid.real_unit_addr); 1104 break; 1105 } 1106 1107 if (strlen(uid.vduit) > 0) 1108 snprintf(uid_string, sizeof(uid_string), 1109 "%s.%s.%04x.%s.%s", 1110 uid.vendor, uid.serial, uid.ssid, ua_string, 1111 uid.vduit); 1112 else 1113 snprintf(uid_string, sizeof(uid_string), 1114 "%s.%s.%04x.%s", 1115 uid.vendor, uid.serial, uid.ssid, ua_string); 1116 } 1117 dasd_put_device(device); 1118 1119 return snprintf(buf, PAGE_SIZE, "%s\n", uid_string); 1120} 1121static DEVICE_ATTR(uid, 0444, dasd_uid_show, NULL); 1122 1123/* 1124 * extended error-reporting 1125 */ 1126static ssize_t 1127dasd_eer_show(struct device *dev, struct device_attribute *attr, char *buf) 1128{ 1129 struct dasd_devmap *devmap; 1130 int eer_flag; 1131 1132 devmap = dasd_find_busid(dev_name(dev)); 1133 if (!IS_ERR(devmap) && devmap->device) 1134 eer_flag = dasd_eer_enabled(devmap->device); 1135 else 1136 eer_flag = 0; 1137 return snprintf(buf, PAGE_SIZE, eer_flag ? "1\n" : "0\n"); 1138} 1139 1140static ssize_t 1141dasd_eer_store(struct device *dev, struct device_attribute *attr, 1142 const char *buf, size_t count) 1143{ 1144 struct dasd_devmap *devmap; 1145 int val, rc; 1146 char *endp; 1147 1148 devmap = dasd_devmap_from_cdev(to_ccwdev(dev)); 1149 if (IS_ERR(devmap)) 1150 return PTR_ERR(devmap); 1151 if (!devmap->device) 1152 return -ENODEV; 1153 1154 val = simple_strtoul(buf, &endp, 0); 1155 if (((endp + 1) < (buf + count)) || (val > 1)) 1156 return -EINVAL; 1157 1158 if (val) { 1159 rc = dasd_eer_enable(devmap->device); 1160 if (rc) 1161 return rc; 1162 } else 1163 dasd_eer_disable(devmap->device); 1164 return count; 1165} 1166 1167static DEVICE_ATTR(eer_enabled, 0644, dasd_eer_show, dasd_eer_store); 1168 1169/* 1170 * expiration time for default requests 1171 */ 1172static ssize_t 1173dasd_expires_show(struct device *dev, struct device_attribute *attr, char *buf) 1174{ 1175 struct dasd_device *device; 1176 int len; 1177 1178 device = dasd_device_from_cdev(to_ccwdev(dev)); 1179 if (IS_ERR(device)) 1180 return -ENODEV; 1181 len = snprintf(buf, PAGE_SIZE, "%lu\n", device->default_expires); 1182 dasd_put_device(device); 1183 return len; 1184} 1185 1186static ssize_t 1187dasd_expires_store(struct device *dev, struct device_attribute *attr, 1188 const char *buf, size_t count) 1189{ 1190 struct dasd_device *device; 1191 unsigned long val; 1192 1193 device = dasd_device_from_cdev(to_ccwdev(dev)); 1194 if (IS_ERR(device)) 1195 return -ENODEV; 1196 1197 if ((strict_strtoul(buf, 10, &val) != 0) || 1198 (val > DASD_EXPIRES_MAX) || val == 0) { 1199 dasd_put_device(device); 1200 return -EINVAL; 1201 } 1202 1203 if (val) 1204 device->default_expires = val; 1205 1206 dasd_put_device(device); 1207 return count; 1208} 1209 1210static DEVICE_ATTR(expires, 0644, dasd_expires_show, dasd_expires_store); 1211 1212static ssize_t dasd_reservation_policy_show(struct device *dev, 1213 struct device_attribute *attr, 1214 char *buf) 1215{ 1216 struct dasd_devmap *devmap; 1217 int rc = 0; 1218 1219 devmap = dasd_find_busid(dev_name(dev)); 1220 if (IS_ERR(devmap)) { 1221 rc = snprintf(buf, PAGE_SIZE, "ignore\n"); 1222 } else { 1223 spin_lock(&dasd_devmap_lock); 1224 if (devmap->features & DASD_FEATURE_FAILONSLCK) 1225 rc = snprintf(buf, PAGE_SIZE, "fail\n"); 1226 else 1227 rc = snprintf(buf, PAGE_SIZE, "ignore\n"); 1228 spin_unlock(&dasd_devmap_lock); 1229 } 1230 return rc; 1231} 1232 1233static ssize_t dasd_reservation_policy_store(struct device *dev, 1234 struct device_attribute *attr, 1235 const char *buf, size_t count) 1236{ 1237 struct dasd_devmap *devmap; 1238 int rc; 1239 1240 devmap = dasd_devmap_from_cdev(to_ccwdev(dev)); 1241 if (IS_ERR(devmap)) 1242 return PTR_ERR(devmap); 1243 rc = 0; 1244 spin_lock(&dasd_devmap_lock); 1245 if (sysfs_streq("ignore", buf)) 1246 devmap->features &= ~DASD_FEATURE_FAILONSLCK; 1247 else if (sysfs_streq("fail", buf)) 1248 devmap->features |= DASD_FEATURE_FAILONSLCK; 1249 else 1250 rc = -EINVAL; 1251 if (devmap->device) 1252 devmap->device->features = devmap->features; 1253 spin_unlock(&dasd_devmap_lock); 1254 if (rc) 1255 return rc; 1256 else 1257 return count; 1258} 1259 1260static DEVICE_ATTR(reservation_policy, 0644, 1261 dasd_reservation_policy_show, dasd_reservation_policy_store); 1262 1263static ssize_t dasd_reservation_state_show(struct device *dev, 1264 struct device_attribute *attr, 1265 char *buf) 1266{ 1267 struct dasd_device *device; 1268 int rc = 0; 1269 1270 device = dasd_device_from_cdev(to_ccwdev(dev)); 1271 if (IS_ERR(device)) 1272 return snprintf(buf, PAGE_SIZE, "none\n"); 1273 1274 if (test_bit(DASD_FLAG_IS_RESERVED, &device->flags)) 1275 rc = snprintf(buf, PAGE_SIZE, "reserved\n"); 1276 else if (test_bit(DASD_FLAG_LOCK_STOLEN, &device->flags)) 1277 rc = snprintf(buf, PAGE_SIZE, "lost\n"); 1278 else 1279 rc = snprintf(buf, PAGE_SIZE, "none\n"); 1280 dasd_put_device(device); 1281 return rc; 1282} 1283 1284static ssize_t dasd_reservation_state_store(struct device *dev, 1285 struct device_attribute *attr, 1286 const char *buf, size_t count) 1287{ 1288 struct dasd_device *device; 1289 int rc = 0; 1290 1291 device = dasd_device_from_cdev(to_ccwdev(dev)); 1292 if (IS_ERR(device)) 1293 return -ENODEV; 1294 if (sysfs_streq("reset", buf)) 1295 clear_bit(DASD_FLAG_LOCK_STOLEN, &device->flags); 1296 else 1297 rc = -EINVAL; 1298 dasd_put_device(device); 1299 1300 if (rc) 1301 return rc; 1302 else 1303 return count; 1304} 1305 1306static DEVICE_ATTR(last_known_reservation_state, 0644, 1307 dasd_reservation_state_show, dasd_reservation_state_store); 1308 1309static struct attribute * dasd_attrs[] = { 1310 &dev_attr_readonly.attr, 1311 &dev_attr_discipline.attr, 1312 &dev_attr_status.attr, 1313 &dev_attr_alias.attr, 1314 &dev_attr_vendor.attr, 1315 &dev_attr_uid.attr, 1316 &dev_attr_use_diag.attr, 1317 &dev_attr_raw_track_access.attr, 1318 &dev_attr_eer_enabled.attr, 1319 &dev_attr_erplog.attr, 1320 &dev_attr_failfast.attr, 1321 &dev_attr_expires.attr, 1322 &dev_attr_reservation_policy.attr, 1323 &dev_attr_last_known_reservation_state.attr, 1324 NULL, 1325}; 1326 1327static struct attribute_group dasd_attr_group = { 1328 .attrs = dasd_attrs, 1329}; 1330 1331/* 1332 * Return value of the specified feature. 1333 */ 1334int 1335dasd_get_feature(struct ccw_device *cdev, int feature) 1336{ 1337 struct dasd_devmap *devmap; 1338 1339 devmap = dasd_find_busid(dev_name(&cdev->dev)); 1340 if (IS_ERR(devmap)) 1341 return PTR_ERR(devmap); 1342 1343 return ((devmap->features & feature) != 0); 1344} 1345 1346/* 1347 * Set / reset given feature. 1348 * Flag indicates wether to set (!=0) or the reset (=0) the feature. 1349 */ 1350int 1351dasd_set_feature(struct ccw_device *cdev, int feature, int flag) 1352{ 1353 struct dasd_devmap *devmap; 1354 1355 devmap = dasd_find_busid(dev_name(&cdev->dev)); 1356 if (IS_ERR(devmap)) 1357 return PTR_ERR(devmap); 1358 1359 spin_lock(&dasd_devmap_lock); 1360 if (flag) 1361 devmap->features |= feature; 1362 else 1363 devmap->features &= ~feature; 1364 if (devmap->device) 1365 devmap->device->features = devmap->features; 1366 spin_unlock(&dasd_devmap_lock); 1367 return 0; 1368} 1369 1370 1371int 1372dasd_add_sysfs_files(struct ccw_device *cdev) 1373{ 1374 return sysfs_create_group(&cdev->dev.kobj, &dasd_attr_group); 1375} 1376 1377void 1378dasd_remove_sysfs_files(struct ccw_device *cdev) 1379{ 1380 sysfs_remove_group(&cdev->dev.kobj, &dasd_attr_group); 1381} 1382 1383 1384int 1385dasd_devmap_init(void) 1386{ 1387 int i; 1388 1389 /* Initialize devmap structures. */ 1390 dasd_max_devindex = 0; 1391 for (i = 0; i < 256; i++) 1392 INIT_LIST_HEAD(&dasd_hashlists[i]); 1393 return 0; 1394} 1395 1396void 1397dasd_devmap_exit(void) 1398{ 1399 dasd_forget_ranges(); 1400}