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 #include <linux/ctype.h> 17 #include <linux/init.h> 18 #include <linux/module.h> 19 20 #include <asm/debug.h> 21 #include <asm/uaccess.h> 22 #include <asm/ipl.h> 23 24 /* This is ugly... */ 25 #define PRINTK_HEADER "dasd_devmap:" 26 27 #include "dasd_int.h" 28 29 struct kmem_cache *dasd_page_cache; 30 EXPORT_SYMBOL_GPL(dasd_page_cache); 31 32 /* 33 * dasd_devmap_t is used to store the features and the relation 34 * between device number and device index. To find a dasd_devmap_t 35 * that corresponds to a device number of a device index each 36 * dasd_devmap_t is added to two linked lists, one to search by 37 * the device number and one to search by the device index. As 38 * soon as big minor numbers are available the device index list 39 * can be removed since the device number will then be identical 40 * to the device index. 41 */ 42 struct dasd_devmap { 43 struct list_head list; 44 char bus_id[BUS_ID_SIZE]; 45 unsigned int devindex; 46 unsigned short features; 47 struct dasd_device *device; 48 struct dasd_uid uid; 49 }; 50 51 /* 52 * dasd_server_ssid_map contains a globally unique storage server subsystem ID. 53 * dasd_server_ssid_list contains the list of all subsystem IDs accessed by 54 * the DASD device driver. 55 */ 56 struct dasd_server_ssid_map { 57 struct list_head list; 58 struct system_id { 59 char vendor[4]; 60 char serial[15]; 61 __u16 ssid; 62 } sid; 63 }; 64 65 static struct list_head dasd_server_ssid_list; 66 67 /* 68 * Parameter parsing functions for dasd= parameter. The syntax is: 69 * <devno> : (0x)?[0-9a-fA-F]+ 70 * <busid> : [0-0a-f]\.[0-9a-f]\.(0x)?[0-9a-fA-F]+ 71 * <feature> : ro 72 * <feature_list> : \(<feature>(:<feature>)*\) 73 * <devno-range> : <devno>(-<devno>)?<feature_list>? 74 * <busid-range> : <busid>(-<busid>)?<feature_list>? 75 * <devices> : <devno-range>|<busid-range> 76 * <dasd_module> : dasd_diag_mod|dasd_eckd_mod|dasd_fba_mod 77 * 78 * <dasd> : autodetect|probeonly|<devices>(,<devices>)* 79 */ 80 81 int dasd_probeonly = 0; /* is true, when probeonly mode is active */ 82 int dasd_autodetect = 0; /* is true, when autodetection is active */ 83 int dasd_nopav = 0; /* is true, when PAV is disabled */ 84 EXPORT_SYMBOL_GPL(dasd_nopav); 85 86 /* 87 * char *dasd[] is intended to hold the ranges supplied by the dasd= statement 88 * it is named 'dasd' to directly be filled by insmod with the comma separated 89 * strings when running as a module. 90 */ 91 static char *dasd[256]; 92 module_param_array(dasd, charp, NULL, 0); 93 94 /* 95 * Single spinlock to protect devmap and servermap structures and lists. 96 */ 97 static DEFINE_SPINLOCK(dasd_devmap_lock); 98 99 /* 100 * Hash lists for devmap structures. 101 */ 102 static struct list_head dasd_hashlists[256]; 103 int dasd_max_devindex; 104 105 static struct dasd_devmap *dasd_add_busid(char *, int); 106 107 static inline int 108 dasd_hash_busid(char *bus_id) 109 { 110 int hash, i; 111 112 hash = 0; 113 for (i = 0; (i < BUS_ID_SIZE) && *bus_id; i++, bus_id++) 114 hash += *bus_id; 115 return hash & 0xff; 116 } 117 118 #ifndef MODULE 119 /* 120 * The parameter parsing functions for builtin-drivers are called 121 * before kmalloc works. Store the pointers to the parameters strings 122 * into dasd[] for later processing. 123 */ 124 static int __init 125 dasd_call_setup(char *str) 126 { 127 static int count = 0; 128 129 if (count < 256) 130 dasd[count++] = str; 131 return 1; 132 } 133 134 __setup ("dasd=", dasd_call_setup); 135 #endif /* #ifndef MODULE */ 136 137 #define DASD_IPLDEV "ipldev" 138 139 /* 140 * Read a device busid/devno from a string. 141 */ 142 static int 143 dasd_busid(char **str, int *id0, int *id1, int *devno) 144 { 145 int val, old_style; 146 147 /* Interpret ipldev busid */ 148 if (strncmp(DASD_IPLDEV, *str, strlen(DASD_IPLDEV)) == 0) { 149 if (ipl_info.type != IPL_TYPE_CCW) { 150 MESSAGE(KERN_ERR, "%s", "ipl device is not a ccw " 151 "device"); 152 return -EINVAL; 153 } 154 *id0 = 0; 155 *id1 = ipl_info.data.ccw.dev_id.ssid; 156 *devno = ipl_info.data.ccw.dev_id.devno; 157 *str += strlen(DASD_IPLDEV); 158 159 return 0; 160 } 161 /* check for leading '0x' */ 162 old_style = 0; 163 if ((*str)[0] == '0' && (*str)[1] == 'x') { 164 *str += 2; 165 old_style = 1; 166 } 167 if (!isxdigit((*str)[0])) /* We require at least one hex digit */ 168 return -EINVAL; 169 val = simple_strtoul(*str, str, 16); 170 if (old_style || (*str)[0] != '.') { 171 *id0 = *id1 = 0; 172 if (val < 0 || val > 0xffff) 173 return -EINVAL; 174 *devno = val; 175 return 0; 176 } 177 /* New style x.y.z busid */ 178 if (val < 0 || val > 0xff) 179 return -EINVAL; 180 *id0 = val; 181 (*str)++; 182 if (!isxdigit((*str)[0])) /* We require at least one hex digit */ 183 return -EINVAL; 184 val = simple_strtoul(*str, str, 16); 185 if (val < 0 || val > 0xff || (*str)++[0] != '.') 186 return -EINVAL; 187 *id1 = val; 188 if (!isxdigit((*str)[0])) /* We require at least one hex digit */ 189 return -EINVAL; 190 val = simple_strtoul(*str, str, 16); 191 if (val < 0 || val > 0xffff) 192 return -EINVAL; 193 *devno = val; 194 return 0; 195 } 196 197 /* 198 * Read colon separated list of dasd features. Currently there is 199 * only one: "ro" for read-only devices. The default feature set 200 * is empty (value 0). 201 */ 202 static int 203 dasd_feature_list(char *str, char **endp) 204 { 205 int features, len, rc; 206 207 rc = 0; 208 if (*str != '(') { 209 *endp = str; 210 return DASD_FEATURE_DEFAULT; 211 } 212 str++; 213 features = 0; 214 215 while (1) { 216 for (len = 0; 217 str[len] && str[len] != ':' && str[len] != ')'; len++); 218 if (len == 2 && !strncmp(str, "ro", 2)) 219 features |= DASD_FEATURE_READONLY; 220 else if (len == 4 && !strncmp(str, "diag", 4)) 221 features |= DASD_FEATURE_USEDIAG; 222 else if (len == 6 && !strncmp(str, "erplog", 6)) 223 features |= DASD_FEATURE_ERPLOG; 224 else { 225 MESSAGE(KERN_WARNING, 226 "unsupported feature: %*s, " 227 "ignoring setting", len, str); 228 rc = -EINVAL; 229 } 230 str += len; 231 if (*str != ':') 232 break; 233 str++; 234 } 235 if (*str != ')') { 236 MESSAGE(KERN_WARNING, "%s", 237 "missing ')' in dasd parameter string\n"); 238 rc = -EINVAL; 239 } else 240 str++; 241 *endp = str; 242 if (rc != 0) 243 return rc; 244 return features; 245 } 246 247 /* 248 * Try to match the first element on the comma separated parse string 249 * with one of the known keywords. If a keyword is found, take the approprate 250 * action and return a pointer to the residual string. If the first element 251 * could not be matched to any keyword then return an error code. 252 */ 253 static char * 254 dasd_parse_keyword( char *parsestring ) { 255 256 char *nextcomma, *residual_str; 257 int length; 258 259 nextcomma = strchr(parsestring,','); 260 if (nextcomma) { 261 length = nextcomma - parsestring; 262 residual_str = nextcomma + 1; 263 } else { 264 length = strlen(parsestring); 265 residual_str = parsestring + length; 266 } 267 if (strncmp("autodetect", parsestring, length) == 0) { 268 dasd_autodetect = 1; 269 MESSAGE (KERN_INFO, "%s", 270 "turning to autodetection mode"); 271 return residual_str; 272 } 273 if (strncmp("probeonly", parsestring, length) == 0) { 274 dasd_probeonly = 1; 275 MESSAGE(KERN_INFO, "%s", 276 "turning to probeonly mode"); 277 return residual_str; 278 } 279 if (strncmp("nopav", parsestring, length) == 0) { 280 if (MACHINE_IS_VM) 281 MESSAGE(KERN_INFO, "%s", "'nopav' not supported on VM"); 282 else { 283 dasd_nopav = 1; 284 MESSAGE(KERN_INFO, "%s", "disable PAV mode"); 285 } 286 return residual_str; 287 } 288 if (strncmp("fixedbuffers", parsestring, length) == 0) { 289 if (dasd_page_cache) 290 return residual_str; 291 dasd_page_cache = 292 kmem_cache_create("dasd_page_cache", PAGE_SIZE, 293 PAGE_SIZE, SLAB_CACHE_DMA, 294 NULL); 295 if (!dasd_page_cache) 296 MESSAGE(KERN_WARNING, "%s", "Failed to create slab, " 297 "fixed buffer mode disabled."); 298 else 299 MESSAGE (KERN_INFO, "%s", 300 "turning on fixed buffer mode"); 301 return residual_str; 302 } 303 return ERR_PTR(-EINVAL); 304 } 305 306 /* 307 * Try to interprete the first element on the comma separated parse string 308 * as a device number or a range of devices. If the interpretation is 309 * successfull, create the matching dasd_devmap entries and return a pointer 310 * to the residual string. 311 * If interpretation fails or in case of an error, return an error code. 312 */ 313 static char * 314 dasd_parse_range( char *parsestring ) { 315 316 struct dasd_devmap *devmap; 317 int from, from_id0, from_id1; 318 int to, to_id0, to_id1; 319 int features, rc; 320 char bus_id[BUS_ID_SIZE+1], *str; 321 322 str = parsestring; 323 rc = dasd_busid(&str, &from_id0, &from_id1, &from); 324 if (rc == 0) { 325 to = from; 326 to_id0 = from_id0; 327 to_id1 = from_id1; 328 if (*str == '-') { 329 str++; 330 rc = dasd_busid(&str, &to_id0, &to_id1, &to); 331 } 332 } 333 if (rc == 0 && 334 (from_id0 != to_id0 || from_id1 != to_id1 || from > to)) 335 rc = -EINVAL; 336 if (rc) { 337 MESSAGE(KERN_ERR, "Invalid device range %s", parsestring); 338 return ERR_PTR(rc); 339 } 340 features = dasd_feature_list(str, &str); 341 if (features < 0) 342 return ERR_PTR(-EINVAL); 343 /* each device in dasd= parameter should be set initially online */ 344 features |= DASD_FEATURE_INITIAL_ONLINE; 345 while (from <= to) { 346 sprintf(bus_id, "%01x.%01x.%04x", 347 from_id0, from_id1, from++); 348 devmap = dasd_add_busid(bus_id, features); 349 if (IS_ERR(devmap)) 350 return (char *)devmap; 351 } 352 if (*str == ',') 353 return str + 1; 354 if (*str == '\0') 355 return str; 356 MESSAGE(KERN_WARNING, 357 "junk at end of dasd parameter string: %s\n", str); 358 return ERR_PTR(-EINVAL); 359 } 360 361 static char * 362 dasd_parse_next_element( char *parsestring ) { 363 char * residual_str; 364 residual_str = dasd_parse_keyword(parsestring); 365 if (!IS_ERR(residual_str)) 366 return residual_str; 367 residual_str = dasd_parse_range(parsestring); 368 return residual_str; 369 } 370 371 /* 372 * Parse parameters stored in dasd[] 373 * The 'dasd=...' parameter allows to specify a comma separated list of 374 * keywords and device ranges. When the dasd driver is build into the kernel, 375 * the complete list will be stored as one element of the dasd[] array. 376 * When the dasd driver is build as a module, then the list is broken into 377 * it's elements and each dasd[] entry contains one element. 378 */ 379 int 380 dasd_parse(void) 381 { 382 int rc, i; 383 char *parsestring; 384 385 rc = 0; 386 for (i = 0; i < 256; i++) { 387 if (dasd[i] == NULL) 388 break; 389 parsestring = dasd[i]; 390 /* loop over the comma separated list in the parsestring */ 391 while (*parsestring) { 392 parsestring = dasd_parse_next_element(parsestring); 393 if(IS_ERR(parsestring)) { 394 rc = PTR_ERR(parsestring); 395 break; 396 } 397 } 398 if (rc) { 399 DBF_EVENT(DBF_ALERT, "%s", "invalid range found"); 400 break; 401 } 402 } 403 return rc; 404 } 405 406 /* 407 * Add a devmap for the device specified by busid. It is possible that 408 * the devmap already exists (dasd= parameter). The order of the devices 409 * added through this function will define the kdevs for the individual 410 * devices. 411 */ 412 static struct dasd_devmap * 413 dasd_add_busid(char *bus_id, int features) 414 { 415 struct dasd_devmap *devmap, *new, *tmp; 416 int hash; 417 418 new = (struct dasd_devmap *) 419 kzalloc(sizeof(struct dasd_devmap), GFP_KERNEL); 420 if (!new) 421 return ERR_PTR(-ENOMEM); 422 spin_lock(&dasd_devmap_lock); 423 devmap = NULL; 424 hash = dasd_hash_busid(bus_id); 425 list_for_each_entry(tmp, &dasd_hashlists[hash], list) 426 if (strncmp(tmp->bus_id, bus_id, BUS_ID_SIZE) == 0) { 427 devmap = tmp; 428 break; 429 } 430 if (!devmap) { 431 /* This bus_id is new. */ 432 new->devindex = dasd_max_devindex++; 433 strncpy(new->bus_id, bus_id, BUS_ID_SIZE); 434 new->features = features; 435 new->device = NULL; 436 list_add(&new->list, &dasd_hashlists[hash]); 437 devmap = new; 438 new = NULL; 439 } 440 spin_unlock(&dasd_devmap_lock); 441 kfree(new); 442 return devmap; 443 } 444 445 /* 446 * Find devmap for device with given bus_id. 447 */ 448 static struct dasd_devmap * 449 dasd_find_busid(char *bus_id) 450 { 451 struct dasd_devmap *devmap, *tmp; 452 int hash; 453 454 spin_lock(&dasd_devmap_lock); 455 devmap = ERR_PTR(-ENODEV); 456 hash = dasd_hash_busid(bus_id); 457 list_for_each_entry(tmp, &dasd_hashlists[hash], list) { 458 if (strncmp(tmp->bus_id, bus_id, BUS_ID_SIZE) == 0) { 459 devmap = tmp; 460 break; 461 } 462 } 463 spin_unlock(&dasd_devmap_lock); 464 return devmap; 465 } 466 467 /* 468 * Check if busid has been added to the list of dasd ranges. 469 */ 470 int 471 dasd_busid_known(char *bus_id) 472 { 473 return IS_ERR(dasd_find_busid(bus_id)) ? -ENOENT : 0; 474 } 475 476 /* 477 * Forget all about the device numbers added so far. 478 * This may only be called at module unload or system shutdown. 479 */ 480 static void 481 dasd_forget_ranges(void) 482 { 483 struct dasd_devmap *devmap, *n; 484 int i; 485 486 spin_lock(&dasd_devmap_lock); 487 for (i = 0; i < 256; i++) { 488 list_for_each_entry_safe(devmap, n, &dasd_hashlists[i], list) { 489 BUG_ON(devmap->device != NULL); 490 list_del(&devmap->list); 491 kfree(devmap); 492 } 493 } 494 spin_unlock(&dasd_devmap_lock); 495 } 496 497 /* 498 * Find the device struct by its device index. 499 */ 500 struct dasd_device * 501 dasd_device_from_devindex(int devindex) 502 { 503 struct dasd_devmap *devmap, *tmp; 504 struct dasd_device *device; 505 int i; 506 507 spin_lock(&dasd_devmap_lock); 508 devmap = NULL; 509 for (i = 0; (i < 256) && !devmap; i++) 510 list_for_each_entry(tmp, &dasd_hashlists[i], list) 511 if (tmp->devindex == devindex) { 512 /* Found the devmap for the device. */ 513 devmap = tmp; 514 break; 515 } 516 if (devmap && devmap->device) { 517 device = devmap->device; 518 dasd_get_device(device); 519 } else 520 device = ERR_PTR(-ENODEV); 521 spin_unlock(&dasd_devmap_lock); 522 return device; 523 } 524 525 /* 526 * Return devmap for cdev. If no devmap exists yet, create one and 527 * connect it to the cdev. 528 */ 529 static struct dasd_devmap * 530 dasd_devmap_from_cdev(struct ccw_device *cdev) 531 { 532 struct dasd_devmap *devmap; 533 534 devmap = dasd_find_busid(cdev->dev.bus_id); 535 if (IS_ERR(devmap)) 536 devmap = dasd_add_busid(cdev->dev.bus_id, 537 DASD_FEATURE_DEFAULT); 538 return devmap; 539 } 540 541 /* 542 * Create a dasd device structure for cdev. 543 */ 544 struct dasd_device * 545 dasd_create_device(struct ccw_device *cdev) 546 { 547 struct dasd_devmap *devmap; 548 struct dasd_device *device; 549 unsigned long flags; 550 int rc; 551 552 devmap = dasd_devmap_from_cdev(cdev); 553 if (IS_ERR(devmap)) 554 return (void *) devmap; 555 556 device = dasd_alloc_device(); 557 if (IS_ERR(device)) 558 return device; 559 atomic_set(&device->ref_count, 3); 560 561 spin_lock(&dasd_devmap_lock); 562 if (!devmap->device) { 563 devmap->device = device; 564 device->devindex = devmap->devindex; 565 device->features = devmap->features; 566 get_device(&cdev->dev); 567 device->cdev = cdev; 568 rc = 0; 569 } else 570 /* Someone else was faster. */ 571 rc = -EBUSY; 572 spin_unlock(&dasd_devmap_lock); 573 574 if (rc) { 575 dasd_free_device(device); 576 return ERR_PTR(rc); 577 } 578 579 spin_lock_irqsave(get_ccwdev_lock(cdev), flags); 580 cdev->dev.driver_data = device; 581 spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); 582 583 return device; 584 } 585 586 /* 587 * Wait queue for dasd_delete_device waits. 588 */ 589 static DECLARE_WAIT_QUEUE_HEAD(dasd_delete_wq); 590 591 /* 592 * Remove a dasd device structure. The passed referenced 593 * is destroyed. 594 */ 595 void 596 dasd_delete_device(struct dasd_device *device) 597 { 598 struct ccw_device *cdev; 599 struct dasd_devmap *devmap; 600 unsigned long flags; 601 602 /* First remove device pointer from devmap. */ 603 devmap = dasd_find_busid(device->cdev->dev.bus_id); 604 BUG_ON(IS_ERR(devmap)); 605 spin_lock(&dasd_devmap_lock); 606 if (devmap->device != device) { 607 spin_unlock(&dasd_devmap_lock); 608 dasd_put_device(device); 609 return; 610 } 611 devmap->device = NULL; 612 spin_unlock(&dasd_devmap_lock); 613 614 /* Disconnect dasd_device structure from ccw_device structure. */ 615 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); 616 device->cdev->dev.driver_data = NULL; 617 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); 618 619 /* 620 * Drop ref_count by 3, one for the devmap reference, one for 621 * the cdev reference and one for the passed reference. 622 */ 623 atomic_sub(3, &device->ref_count); 624 625 /* Wait for reference counter to drop to zero. */ 626 wait_event(dasd_delete_wq, atomic_read(&device->ref_count) == 0); 627 628 /* Disconnect dasd_device structure from ccw_device structure. */ 629 cdev = device->cdev; 630 device->cdev = NULL; 631 632 /* Put ccw_device structure. */ 633 put_device(&cdev->dev); 634 635 /* Now the device structure can be freed. */ 636 dasd_free_device(device); 637 } 638 639 /* 640 * Reference counter dropped to zero. Wake up waiter 641 * in dasd_delete_device. 642 */ 643 void 644 dasd_put_device_wake(struct dasd_device *device) 645 { 646 wake_up(&dasd_delete_wq); 647 } 648 649 /* 650 * Return dasd_device structure associated with cdev. 651 * This function needs to be called with the ccw device 652 * lock held. It can be used from interrupt context. 653 */ 654 struct dasd_device * 655 dasd_device_from_cdev_locked(struct ccw_device *cdev) 656 { 657 struct dasd_device *device = cdev->dev.driver_data; 658 659 if (!device) 660 return ERR_PTR(-ENODEV); 661 dasd_get_device(device); 662 return device; 663 } 664 665 /* 666 * Return dasd_device structure associated with cdev. 667 */ 668 struct dasd_device * 669 dasd_device_from_cdev(struct ccw_device *cdev) 670 { 671 struct dasd_device *device; 672 unsigned long flags; 673 674 spin_lock_irqsave(get_ccwdev_lock(cdev), flags); 675 device = dasd_device_from_cdev_locked(cdev); 676 spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); 677 return device; 678 } 679 680 /* 681 * SECTION: files in sysfs 682 */ 683 684 /* 685 * readonly controls the readonly status of a dasd 686 */ 687 static ssize_t 688 dasd_ro_show(struct device *dev, struct device_attribute *attr, char *buf) 689 { 690 struct dasd_devmap *devmap; 691 int ro_flag; 692 693 devmap = dasd_find_busid(dev->bus_id); 694 if (!IS_ERR(devmap)) 695 ro_flag = (devmap->features & DASD_FEATURE_READONLY) != 0; 696 else 697 ro_flag = (DASD_FEATURE_DEFAULT & DASD_FEATURE_READONLY) != 0; 698 return snprintf(buf, PAGE_SIZE, ro_flag ? "1\n" : "0\n"); 699 } 700 701 static ssize_t 702 dasd_ro_store(struct device *dev, struct device_attribute *attr, 703 const char *buf, size_t count) 704 { 705 struct dasd_devmap *devmap; 706 int val; 707 char *endp; 708 709 devmap = dasd_devmap_from_cdev(to_ccwdev(dev)); 710 if (IS_ERR(devmap)) 711 return PTR_ERR(devmap); 712 713 val = simple_strtoul(buf, &endp, 0); 714 if (((endp + 1) < (buf + count)) || (val > 1)) 715 return -EINVAL; 716 717 spin_lock(&dasd_devmap_lock); 718 if (val) 719 devmap->features |= DASD_FEATURE_READONLY; 720 else 721 devmap->features &= ~DASD_FEATURE_READONLY; 722 if (devmap->device) 723 devmap->device->features = devmap->features; 724 if (devmap->device && devmap->device->gdp) 725 set_disk_ro(devmap->device->gdp, val); 726 spin_unlock(&dasd_devmap_lock); 727 return count; 728 } 729 730 static DEVICE_ATTR(readonly, 0644, dasd_ro_show, dasd_ro_store); 731 /* 732 * erplog controls the logging of ERP related data 733 * (e.g. failing channel programs). 734 */ 735 static ssize_t 736 dasd_erplog_show(struct device *dev, struct device_attribute *attr, char *buf) 737 { 738 struct dasd_devmap *devmap; 739 int erplog; 740 741 devmap = dasd_find_busid(dev->bus_id); 742 if (!IS_ERR(devmap)) 743 erplog = (devmap->features & DASD_FEATURE_ERPLOG) != 0; 744 else 745 erplog = (DASD_FEATURE_DEFAULT & DASD_FEATURE_ERPLOG) != 0; 746 return snprintf(buf, PAGE_SIZE, erplog ? "1\n" : "0\n"); 747 } 748 749 static ssize_t 750 dasd_erplog_store(struct device *dev, struct device_attribute *attr, 751 const char *buf, size_t count) 752 { 753 struct dasd_devmap *devmap; 754 int val; 755 char *endp; 756 757 devmap = dasd_devmap_from_cdev(to_ccwdev(dev)); 758 if (IS_ERR(devmap)) 759 return PTR_ERR(devmap); 760 761 val = simple_strtoul(buf, &endp, 0); 762 if (((endp + 1) < (buf + count)) || (val > 1)) 763 return -EINVAL; 764 765 spin_lock(&dasd_devmap_lock); 766 if (val) 767 devmap->features |= DASD_FEATURE_ERPLOG; 768 else 769 devmap->features &= ~DASD_FEATURE_ERPLOG; 770 if (devmap->device) 771 devmap->device->features = devmap->features; 772 spin_unlock(&dasd_devmap_lock); 773 return count; 774 } 775 776 static DEVICE_ATTR(erplog, 0644, dasd_erplog_show, dasd_erplog_store); 777 778 /* 779 * use_diag controls whether the driver should use diag rather than ssch 780 * to talk to the device 781 */ 782 static ssize_t 783 dasd_use_diag_show(struct device *dev, struct device_attribute *attr, char *buf) 784 { 785 struct dasd_devmap *devmap; 786 int use_diag; 787 788 devmap = dasd_find_busid(dev->bus_id); 789 if (!IS_ERR(devmap)) 790 use_diag = (devmap->features & DASD_FEATURE_USEDIAG) != 0; 791 else 792 use_diag = (DASD_FEATURE_DEFAULT & DASD_FEATURE_USEDIAG) != 0; 793 return sprintf(buf, use_diag ? "1\n" : "0\n"); 794 } 795 796 static ssize_t 797 dasd_use_diag_store(struct device *dev, struct device_attribute *attr, 798 const char *buf, size_t count) 799 { 800 struct dasd_devmap *devmap; 801 ssize_t rc; 802 int val; 803 char *endp; 804 805 devmap = dasd_devmap_from_cdev(to_ccwdev(dev)); 806 if (IS_ERR(devmap)) 807 return PTR_ERR(devmap); 808 809 val = simple_strtoul(buf, &endp, 0); 810 if (((endp + 1) < (buf + count)) || (val > 1)) 811 return -EINVAL; 812 813 spin_lock(&dasd_devmap_lock); 814 /* Changing diag discipline flag is only allowed in offline state. */ 815 rc = count; 816 if (!devmap->device) { 817 if (val) 818 devmap->features |= DASD_FEATURE_USEDIAG; 819 else 820 devmap->features &= ~DASD_FEATURE_USEDIAG; 821 } else 822 rc = -EPERM; 823 spin_unlock(&dasd_devmap_lock); 824 return rc; 825 } 826 827 static DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store); 828 829 static ssize_t 830 dasd_discipline_show(struct device *dev, struct device_attribute *attr, 831 char *buf) 832 { 833 struct dasd_device *device; 834 ssize_t len; 835 836 device = dasd_device_from_cdev(to_ccwdev(dev)); 837 if (!IS_ERR(device) && device->discipline) { 838 len = snprintf(buf, PAGE_SIZE, "%s\n", 839 device->discipline->name); 840 dasd_put_device(device); 841 } else 842 len = snprintf(buf, PAGE_SIZE, "none\n"); 843 return len; 844 } 845 846 static DEVICE_ATTR(discipline, 0444, dasd_discipline_show, NULL); 847 848 static ssize_t 849 dasd_device_status_show(struct device *dev, struct device_attribute *attr, 850 char *buf) 851 { 852 struct dasd_device *device; 853 ssize_t len; 854 855 device = dasd_device_from_cdev(to_ccwdev(dev)); 856 if (!IS_ERR(device)) { 857 switch (device->state) { 858 case DASD_STATE_NEW: 859 len = snprintf(buf, PAGE_SIZE, "new\n"); 860 break; 861 case DASD_STATE_KNOWN: 862 len = snprintf(buf, PAGE_SIZE, "detected\n"); 863 break; 864 case DASD_STATE_BASIC: 865 len = snprintf(buf, PAGE_SIZE, "basic\n"); 866 break; 867 case DASD_STATE_UNFMT: 868 len = snprintf(buf, PAGE_SIZE, "unformatted\n"); 869 break; 870 case DASD_STATE_READY: 871 len = snprintf(buf, PAGE_SIZE, "ready\n"); 872 break; 873 case DASD_STATE_ONLINE: 874 len = snprintf(buf, PAGE_SIZE, "online\n"); 875 break; 876 default: 877 len = snprintf(buf, PAGE_SIZE, "no stat\n"); 878 break; 879 } 880 dasd_put_device(device); 881 } else 882 len = snprintf(buf, PAGE_SIZE, "unknown\n"); 883 return len; 884 } 885 886 static DEVICE_ATTR(status, 0444, dasd_device_status_show, NULL); 887 888 static ssize_t 889 dasd_alias_show(struct device *dev, struct device_attribute *attr, char *buf) 890 { 891 struct dasd_devmap *devmap; 892 int alias; 893 894 devmap = dasd_find_busid(dev->bus_id); 895 spin_lock(&dasd_devmap_lock); 896 if (!IS_ERR(devmap)) 897 alias = devmap->uid.alias; 898 else 899 alias = 0; 900 spin_unlock(&dasd_devmap_lock); 901 902 return sprintf(buf, alias ? "1\n" : "0\n"); 903 } 904 905 static DEVICE_ATTR(alias, 0444, dasd_alias_show, NULL); 906 907 static ssize_t 908 dasd_vendor_show(struct device *dev, struct device_attribute *attr, char *buf) 909 { 910 struct dasd_devmap *devmap; 911 char *vendor; 912 913 devmap = dasd_find_busid(dev->bus_id); 914 spin_lock(&dasd_devmap_lock); 915 if (!IS_ERR(devmap) && strlen(devmap->uid.vendor) > 0) 916 vendor = devmap->uid.vendor; 917 else 918 vendor = ""; 919 spin_unlock(&dasd_devmap_lock); 920 921 return snprintf(buf, PAGE_SIZE, "%s\n", vendor); 922 } 923 924 static DEVICE_ATTR(vendor, 0444, dasd_vendor_show, NULL); 925 926 #define UID_STRLEN ( /* vendor */ 3 + 1 + /* serial */ 14 + 1 +\ 927 /* SSID */ 4 + 1 + /* unit addr */ 2 + 1) 928 929 static ssize_t 930 dasd_uid_show(struct device *dev, struct device_attribute *attr, char *buf) 931 { 932 struct dasd_devmap *devmap; 933 char uid[UID_STRLEN]; 934 935 devmap = dasd_find_busid(dev->bus_id); 936 spin_lock(&dasd_devmap_lock); 937 if (!IS_ERR(devmap) && strlen(devmap->uid.vendor) > 0) 938 snprintf(uid, sizeof(uid), "%s.%s.%04x.%02x", 939 devmap->uid.vendor, devmap->uid.serial, 940 devmap->uid.ssid, devmap->uid.unit_addr); 941 else 942 uid[0] = 0; 943 spin_unlock(&dasd_devmap_lock); 944 945 return snprintf(buf, PAGE_SIZE, "%s\n", uid); 946 } 947 948 static DEVICE_ATTR(uid, 0444, dasd_uid_show, NULL); 949 950 /* 951 * extended error-reporting 952 */ 953 static ssize_t 954 dasd_eer_show(struct device *dev, struct device_attribute *attr, char *buf) 955 { 956 struct dasd_devmap *devmap; 957 int eer_flag; 958 959 devmap = dasd_find_busid(dev->bus_id); 960 if (!IS_ERR(devmap) && devmap->device) 961 eer_flag = dasd_eer_enabled(devmap->device); 962 else 963 eer_flag = 0; 964 return snprintf(buf, PAGE_SIZE, eer_flag ? "1\n" : "0\n"); 965 } 966 967 static ssize_t 968 dasd_eer_store(struct device *dev, struct device_attribute *attr, 969 const char *buf, size_t count) 970 { 971 struct dasd_devmap *devmap; 972 int val, rc; 973 char *endp; 974 975 devmap = dasd_devmap_from_cdev(to_ccwdev(dev)); 976 if (IS_ERR(devmap)) 977 return PTR_ERR(devmap); 978 if (!devmap->device) 979 return -ENODEV; 980 981 val = simple_strtoul(buf, &endp, 0); 982 if (((endp + 1) < (buf + count)) || (val > 1)) 983 return -EINVAL; 984 985 if (val) { 986 rc = dasd_eer_enable(devmap->device); 987 if (rc) 988 return rc; 989 } else 990 dasd_eer_disable(devmap->device); 991 return count; 992 } 993 994 static DEVICE_ATTR(eer_enabled, 0644, dasd_eer_show, dasd_eer_store); 995 996 static struct attribute * dasd_attrs[] = { 997 &dev_attr_readonly.attr, 998 &dev_attr_discipline.attr, 999 &dev_attr_status.attr, 1000 &dev_attr_alias.attr, 1001 &dev_attr_vendor.attr, 1002 &dev_attr_uid.attr, 1003 &dev_attr_use_diag.attr, 1004 &dev_attr_eer_enabled.attr, 1005 &dev_attr_erplog.attr, 1006 NULL, 1007 }; 1008 1009 static struct attribute_group dasd_attr_group = { 1010 .attrs = dasd_attrs, 1011 }; 1012 1013 /* 1014 * Return copy of the device unique identifier. 1015 */ 1016 int 1017 dasd_get_uid(struct ccw_device *cdev, struct dasd_uid *uid) 1018 { 1019 struct dasd_devmap *devmap; 1020 1021 devmap = dasd_find_busid(cdev->dev.bus_id); 1022 if (IS_ERR(devmap)) 1023 return PTR_ERR(devmap); 1024 spin_lock(&dasd_devmap_lock); 1025 *uid = devmap->uid; 1026 spin_unlock(&dasd_devmap_lock); 1027 return 0; 1028 } 1029 1030 /* 1031 * Register the given device unique identifier into devmap struct. 1032 * In addition check if the related storage server subsystem ID is already 1033 * contained in the dasd_server_ssid_list. If subsystem ID is not contained, 1034 * create new entry. 1035 * Return 0 if server was already in serverlist, 1036 * 1 if the server was added successful 1037 * <0 in case of error. 1038 */ 1039 int 1040 dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid) 1041 { 1042 struct dasd_devmap *devmap; 1043 struct dasd_server_ssid_map *srv, *tmp; 1044 1045 devmap = dasd_find_busid(cdev->dev.bus_id); 1046 if (IS_ERR(devmap)) 1047 return PTR_ERR(devmap); 1048 1049 /* generate entry for server_ssid_map */ 1050 srv = (struct dasd_server_ssid_map *) 1051 kzalloc(sizeof(struct dasd_server_ssid_map), GFP_KERNEL); 1052 if (!srv) 1053 return -ENOMEM; 1054 strncpy(srv->sid.vendor, uid->vendor, sizeof(srv->sid.vendor) - 1); 1055 strncpy(srv->sid.serial, uid->serial, sizeof(srv->sid.serial) - 1); 1056 srv->sid.ssid = uid->ssid; 1057 1058 /* server is already contained ? */ 1059 spin_lock(&dasd_devmap_lock); 1060 devmap->uid = *uid; 1061 list_for_each_entry(tmp, &dasd_server_ssid_list, list) { 1062 if (!memcmp(&srv->sid, &tmp->sid, 1063 sizeof(struct system_id))) { 1064 kfree(srv); 1065 srv = NULL; 1066 break; 1067 } 1068 } 1069 1070 /* add servermap to serverlist */ 1071 if (srv) 1072 list_add(&srv->list, &dasd_server_ssid_list); 1073 spin_unlock(&dasd_devmap_lock); 1074 1075 return (srv ? 1 : 0); 1076 } 1077 EXPORT_SYMBOL_GPL(dasd_set_uid); 1078 1079 /* 1080 * Return value of the specified feature. 1081 */ 1082 int 1083 dasd_get_feature(struct ccw_device *cdev, int feature) 1084 { 1085 struct dasd_devmap *devmap; 1086 1087 devmap = dasd_find_busid(cdev->dev.bus_id); 1088 if (IS_ERR(devmap)) 1089 return PTR_ERR(devmap); 1090 1091 return ((devmap->features & feature) != 0); 1092 } 1093 1094 /* 1095 * Set / reset given feature. 1096 * Flag indicates wether to set (!=0) or the reset (=0) the feature. 1097 */ 1098 int 1099 dasd_set_feature(struct ccw_device *cdev, int feature, int flag) 1100 { 1101 struct dasd_devmap *devmap; 1102 1103 devmap = dasd_find_busid(cdev->dev.bus_id); 1104 if (IS_ERR(devmap)) 1105 return PTR_ERR(devmap); 1106 1107 spin_lock(&dasd_devmap_lock); 1108 if (flag) 1109 devmap->features |= feature; 1110 else 1111 devmap->features &= ~feature; 1112 if (devmap->device) 1113 devmap->device->features = devmap->features; 1114 spin_unlock(&dasd_devmap_lock); 1115 return 0; 1116 } 1117 1118 1119 int 1120 dasd_add_sysfs_files(struct ccw_device *cdev) 1121 { 1122 return sysfs_create_group(&cdev->dev.kobj, &dasd_attr_group); 1123 } 1124 1125 void 1126 dasd_remove_sysfs_files(struct ccw_device *cdev) 1127 { 1128 sysfs_remove_group(&cdev->dev.kobj, &dasd_attr_group); 1129 } 1130 1131 1132 int 1133 dasd_devmap_init(void) 1134 { 1135 int i; 1136 1137 /* Initialize devmap structures. */ 1138 dasd_max_devindex = 0; 1139 for (i = 0; i < 256; i++) 1140 INIT_LIST_HEAD(&dasd_hashlists[i]); 1141 1142 /* Initialize servermap structure. */ 1143 INIT_LIST_HEAD(&dasd_server_ssid_list); 1144 return 0; 1145 } 1146 1147 void 1148 dasd_devmap_exit(void) 1149 { 1150 dasd_forget_ranges(); 1151 } 1152