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