1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * dcssblk.c -- the S/390 block driver for dcss memory 4 * 5 * Authors: Carsten Otte, Stefan Weinhuber, Gerald Schaefer 6 */ 7 8 #define pr_fmt(fmt) "dcssblk: " fmt 9 10 #include <linux/module.h> 11 #include <linux/moduleparam.h> 12 #include <linux/ctype.h> 13 #include <linux/errno.h> 14 #include <linux/init.h> 15 #include <linux/slab.h> 16 #include <linux/blkdev.h> 17 #include <linux/completion.h> 18 #include <linux/interrupt.h> 19 #include <linux/uio.h> 20 #include <linux/dax.h> 21 #include <linux/io.h> 22 #include <asm/extmem.h> 23 24 #define DCSSBLK_NAME "dcssblk" 25 #define DCSSBLK_MINORS_PER_DISK 1 26 #define DCSSBLK_PARM_LEN 400 27 #define DCSS_BUS_ID_SIZE 20 28 29 static int dcssblk_open(struct gendisk *disk, blk_mode_t mode); 30 static void dcssblk_release(struct gendisk *disk); 31 static void dcssblk_submit_bio(struct bio *bio); 32 static long dcssblk_dax_direct_access(struct dax_device *dax_dev, pgoff_t pgoff, 33 long nr_pages, enum dax_access_mode mode, void **kaddr, 34 unsigned long *pfn); 35 36 static char dcssblk_segments[DCSSBLK_PARM_LEN] = "\0"; 37 38 static int dcssblk_major; 39 static const struct block_device_operations dcssblk_devops = { 40 .owner = THIS_MODULE, 41 .submit_bio = dcssblk_submit_bio, 42 .open = dcssblk_open, 43 .release = dcssblk_release, 44 }; 45 46 static int dcssblk_dax_zero_page_range(struct dax_device *dax_dev, 47 pgoff_t pgoff, size_t nr_pages) 48 { 49 long rc; 50 void *kaddr; 51 52 rc = dax_direct_access(dax_dev, pgoff, nr_pages, DAX_ACCESS, 53 &kaddr, NULL); 54 if (rc < 0) 55 return dax_mem2blk_err(rc); 56 57 memset(kaddr, 0, nr_pages << PAGE_SHIFT); 58 dax_flush(dax_dev, kaddr, nr_pages << PAGE_SHIFT); 59 return 0; 60 } 61 62 static const struct dax_operations dcssblk_dax_ops = { 63 .direct_access = dcssblk_dax_direct_access, 64 .zero_page_range = dcssblk_dax_zero_page_range, 65 }; 66 67 struct dcssblk_dev_info { 68 struct list_head lh; 69 struct device dev; 70 char segment_name[DCSS_BUS_ID_SIZE]; 71 atomic_t use_count; 72 struct gendisk *gd; 73 unsigned long start; 74 unsigned long end; 75 int segment_type; 76 unsigned char save_pending; 77 unsigned char is_shared; 78 int num_of_segments; 79 struct list_head seg_list; 80 struct dax_device *dax_dev; 81 struct dev_pagemap pgmap; 82 void *pgmap_addr; 83 }; 84 85 struct segment_info { 86 struct list_head lh; 87 char segment_name[DCSS_BUS_ID_SIZE]; 88 unsigned long start; 89 unsigned long end; 90 int segment_type; 91 }; 92 93 static ssize_t dcssblk_add_store(struct device * dev, struct device_attribute *attr, const char * buf, 94 size_t count); 95 static ssize_t dcssblk_remove_store(struct device * dev, struct device_attribute *attr, const char * buf, 96 size_t count); 97 98 static DEVICE_ATTR(add, S_IWUSR, NULL, dcssblk_add_store); 99 static DEVICE_ATTR(remove, S_IWUSR, NULL, dcssblk_remove_store); 100 101 static struct device *dcssblk_root_dev; 102 103 static LIST_HEAD(dcssblk_devices); 104 static struct rw_semaphore dcssblk_devices_sem; 105 106 /* 107 * release function for segment device. 108 */ 109 static void 110 dcssblk_release_segment(struct device *dev) 111 { 112 struct dcssblk_dev_info *dev_info; 113 struct segment_info *entry, *temp; 114 115 dev_info = container_of(dev, struct dcssblk_dev_info, dev); 116 list_for_each_entry_safe(entry, temp, &dev_info->seg_list, lh) { 117 list_del(&entry->lh); 118 kfree(entry); 119 } 120 kfree(dev_info); 121 module_put(THIS_MODULE); 122 } 123 124 /* 125 * get a minor number. needs to be called with 126 * down_write(&dcssblk_devices_sem) and the 127 * device needs to be enqueued before the semaphore is 128 * freed. 129 */ 130 static int 131 dcssblk_assign_free_minor(struct dcssblk_dev_info *dev_info) 132 { 133 int minor, found; 134 struct dcssblk_dev_info *entry; 135 136 if (dev_info == NULL) 137 return -EINVAL; 138 for (minor = 0; minor < (1<<MINORBITS); minor++) { 139 found = 0; 140 // test if minor available 141 list_for_each_entry(entry, &dcssblk_devices, lh) 142 if (minor == entry->gd->first_minor) 143 found++; 144 if (!found) break; // got unused minor 145 } 146 if (found) 147 return -EBUSY; 148 dev_info->gd->first_minor = minor; 149 return 0; 150 } 151 152 /* 153 * get the struct dcssblk_dev_info from dcssblk_devices 154 * for the given name. 155 * down_read(&dcssblk_devices_sem) must be held. 156 */ 157 static struct dcssblk_dev_info * 158 dcssblk_get_device_by_name(char *name) 159 { 160 struct dcssblk_dev_info *entry; 161 162 list_for_each_entry(entry, &dcssblk_devices, lh) { 163 if (!strcmp(name, entry->segment_name)) { 164 return entry; 165 } 166 } 167 return NULL; 168 } 169 170 /* 171 * get the struct segment_info from seg_list 172 * for the given name. 173 * down_read(&dcssblk_devices_sem) must be held. 174 */ 175 static struct segment_info * 176 dcssblk_get_segment_by_name(char *name) 177 { 178 struct dcssblk_dev_info *dev_info; 179 struct segment_info *entry; 180 181 list_for_each_entry(dev_info, &dcssblk_devices, lh) { 182 list_for_each_entry(entry, &dev_info->seg_list, lh) { 183 if (!strcmp(name, entry->segment_name)) 184 return entry; 185 } 186 } 187 return NULL; 188 } 189 190 /* 191 * get the highest address of the multi-segment block. 192 */ 193 static unsigned long 194 dcssblk_find_highest_addr(struct dcssblk_dev_info *dev_info) 195 { 196 unsigned long highest_addr; 197 struct segment_info *entry; 198 199 highest_addr = 0; 200 list_for_each_entry(entry, &dev_info->seg_list, lh) { 201 if (highest_addr < entry->end) 202 highest_addr = entry->end; 203 } 204 return highest_addr; 205 } 206 207 /* 208 * get the lowest address of the multi-segment block. 209 */ 210 static unsigned long 211 dcssblk_find_lowest_addr(struct dcssblk_dev_info *dev_info) 212 { 213 int set_first; 214 unsigned long lowest_addr; 215 struct segment_info *entry; 216 217 set_first = 0; 218 lowest_addr = 0; 219 list_for_each_entry(entry, &dev_info->seg_list, lh) { 220 if (set_first == 0) { 221 lowest_addr = entry->start; 222 set_first = 1; 223 } else { 224 if (lowest_addr > entry->start) 225 lowest_addr = entry->start; 226 } 227 } 228 return lowest_addr; 229 } 230 231 /* 232 * Check continuity of segments. 233 */ 234 static int 235 dcssblk_is_continuous(struct dcssblk_dev_info *dev_info) 236 { 237 int i, j, rc; 238 struct segment_info *sort_list, *entry, temp; 239 240 if (dev_info->num_of_segments <= 1) 241 return 0; 242 243 sort_list = kzalloc_objs(struct segment_info, dev_info->num_of_segments, 244 GFP_KERNEL); 245 if (sort_list == NULL) 246 return -ENOMEM; 247 i = 0; 248 list_for_each_entry(entry, &dev_info->seg_list, lh) { 249 memcpy(&sort_list[i], entry, sizeof(struct segment_info)); 250 i++; 251 } 252 253 /* sort segments */ 254 for (i = 0; i < dev_info->num_of_segments; i++) 255 for (j = 0; j < dev_info->num_of_segments; j++) 256 if (sort_list[j].start > sort_list[i].start) { 257 memcpy(&temp, &sort_list[i], 258 sizeof(struct segment_info)); 259 memcpy(&sort_list[i], &sort_list[j], 260 sizeof(struct segment_info)); 261 memcpy(&sort_list[j], &temp, 262 sizeof(struct segment_info)); 263 } 264 265 /* check continuity */ 266 for (i = 0; i < dev_info->num_of_segments - 1; i++) { 267 if ((sort_list[i].end + 1) != sort_list[i+1].start) { 268 pr_err("Adjacent DCSSs %s and %s are not " 269 "contiguous\n", sort_list[i].segment_name, 270 sort_list[i+1].segment_name); 271 rc = -EINVAL; 272 goto out; 273 } 274 /* EN and EW are allowed in a block device */ 275 if (sort_list[i].segment_type != sort_list[i+1].segment_type) { 276 if (!(sort_list[i].segment_type & SEGMENT_EXCLUSIVE) || 277 (sort_list[i].segment_type == SEG_TYPE_ER) || 278 !(sort_list[i+1].segment_type & 279 SEGMENT_EXCLUSIVE) || 280 (sort_list[i+1].segment_type == SEG_TYPE_ER)) { 281 pr_err("DCSS %s and DCSS %s have " 282 "incompatible types\n", 283 sort_list[i].segment_name, 284 sort_list[i+1].segment_name); 285 rc = -EINVAL; 286 goto out; 287 } 288 } 289 } 290 rc = 0; 291 out: 292 kfree(sort_list); 293 return rc; 294 } 295 296 /* 297 * Load a segment 298 */ 299 static int 300 dcssblk_load_segment(char *name, struct segment_info **seg_info) 301 { 302 int rc; 303 304 /* already loaded? */ 305 down_read(&dcssblk_devices_sem); 306 *seg_info = dcssblk_get_segment_by_name(name); 307 up_read(&dcssblk_devices_sem); 308 if (*seg_info != NULL) 309 return -EEXIST; 310 311 /* get a struct segment_info */ 312 *seg_info = kzalloc_obj(struct segment_info); 313 if (*seg_info == NULL) 314 return -ENOMEM; 315 316 strscpy((*seg_info)->segment_name, name); 317 318 /* load the segment */ 319 rc = segment_load(name, SEGMENT_SHARED, 320 &(*seg_info)->start, &(*seg_info)->end); 321 if (rc < 0) { 322 segment_warning(rc, (*seg_info)->segment_name); 323 kfree(*seg_info); 324 } else { 325 INIT_LIST_HEAD(&(*seg_info)->lh); 326 (*seg_info)->segment_type = rc; 327 } 328 return rc; 329 } 330 331 /* 332 * device attribute for switching shared/nonshared (exclusive) 333 * operation (show + store) 334 */ 335 static ssize_t 336 dcssblk_shared_show(struct device *dev, struct device_attribute *attr, char *buf) 337 { 338 struct dcssblk_dev_info *dev_info; 339 340 dev_info = container_of(dev, struct dcssblk_dev_info, dev); 341 return sysfs_emit(buf, dev_info->is_shared ? "1\n" : "0\n"); 342 } 343 344 static ssize_t 345 dcssblk_shared_store(struct device *dev, struct device_attribute *attr, const char *inbuf, size_t count) 346 { 347 struct dcssblk_dev_info *dev_info; 348 struct segment_info *entry, *temp; 349 int rc; 350 351 if ((count > 1) && (inbuf[1] != '\n') && (inbuf[1] != '\0')) 352 return -EINVAL; 353 down_write(&dcssblk_devices_sem); 354 dev_info = container_of(dev, struct dcssblk_dev_info, dev); 355 if (atomic_read(&dev_info->use_count)) { 356 rc = -EBUSY; 357 goto out; 358 } 359 if (inbuf[0] == '1') { 360 /* reload segments in shared mode */ 361 list_for_each_entry(entry, &dev_info->seg_list, lh) { 362 rc = segment_modify_shared(entry->segment_name, 363 SEGMENT_SHARED); 364 if (rc < 0) { 365 BUG_ON(rc == -EINVAL); 366 if (rc != -EAGAIN) 367 goto removeseg; 368 } 369 } 370 dev_info->is_shared = 1; 371 switch (dev_info->segment_type) { 372 case SEG_TYPE_SR: 373 case SEG_TYPE_ER: 374 case SEG_TYPE_SC: 375 set_disk_ro(dev_info->gd, 1); 376 } 377 } else if (inbuf[0] == '0') { 378 /* reload segments in exclusive mode */ 379 if (dev_info->segment_type == SEG_TYPE_SC) { 380 pr_err("DCSS %s is of type SC and cannot be " 381 "loaded as exclusive-writable\n", 382 dev_info->segment_name); 383 rc = -EINVAL; 384 goto out; 385 } 386 list_for_each_entry(entry, &dev_info->seg_list, lh) { 387 rc = segment_modify_shared(entry->segment_name, 388 SEGMENT_EXCLUSIVE); 389 if (rc < 0) { 390 BUG_ON(rc == -EINVAL); 391 if (rc != -EAGAIN) 392 goto removeseg; 393 } 394 } 395 dev_info->is_shared = 0; 396 set_disk_ro(dev_info->gd, 0); 397 } else { 398 rc = -EINVAL; 399 goto out; 400 } 401 rc = count; 402 goto out; 403 404 removeseg: 405 pr_err("DCSS device %s is removed after a failed access mode " 406 "change\n", dev_info->segment_name); 407 temp = entry; 408 list_for_each_entry(entry, &dev_info->seg_list, lh) { 409 if (entry != temp) 410 segment_unload(entry->segment_name); 411 } 412 list_del(&dev_info->lh); 413 up_write(&dcssblk_devices_sem); 414 415 dax_remove_host(dev_info->gd); 416 kill_dax(dev_info->dax_dev); 417 put_dax(dev_info->dax_dev); 418 if (dev_info->pgmap_addr) 419 devm_memunmap_pages(&dev_info->dev, &dev_info->pgmap); 420 del_gendisk(dev_info->gd); 421 put_disk(dev_info->gd); 422 423 if (device_remove_file_self(dev, attr)) { 424 device_unregister(dev); 425 put_device(dev); 426 } 427 return rc; 428 out: 429 up_write(&dcssblk_devices_sem); 430 return rc; 431 } 432 static DEVICE_ATTR(shared, S_IWUSR | S_IRUSR, dcssblk_shared_show, 433 dcssblk_shared_store); 434 435 /* 436 * device attribute for save operation on current copy 437 * of the segment. If the segment is busy, saving will 438 * become pending until it gets released, which can be 439 * undone by storing a non-true value to this entry. 440 * (show + store) 441 */ 442 static ssize_t 443 dcssblk_save_show(struct device *dev, struct device_attribute *attr, char *buf) 444 { 445 struct dcssblk_dev_info *dev_info; 446 447 dev_info = container_of(dev, struct dcssblk_dev_info, dev); 448 return sysfs_emit(buf, dev_info->save_pending ? "1\n" : "0\n"); 449 } 450 451 static ssize_t 452 dcssblk_save_store(struct device *dev, struct device_attribute *attr, const char *inbuf, size_t count) 453 { 454 struct dcssblk_dev_info *dev_info; 455 struct segment_info *entry; 456 457 if ((count > 1) && (inbuf[1] != '\n') && (inbuf[1] != '\0')) 458 return -EINVAL; 459 dev_info = container_of(dev, struct dcssblk_dev_info, dev); 460 461 down_write(&dcssblk_devices_sem); 462 if (inbuf[0] == '1') { 463 if (atomic_read(&dev_info->use_count) == 0) { 464 // device is idle => we save immediately 465 pr_info("All DCSSs that map to device %s are " 466 "saved\n", dev_info->segment_name); 467 list_for_each_entry(entry, &dev_info->seg_list, lh) { 468 if (entry->segment_type == SEG_TYPE_EN || 469 entry->segment_type == SEG_TYPE_SN) 470 pr_warn("DCSS %s is of type SN or EN" 471 " and cannot be saved\n", 472 entry->segment_name); 473 else 474 segment_save(entry->segment_name); 475 } 476 } else { 477 // device is busy => we save it when it becomes 478 // idle in dcssblk_release 479 pr_info("Device %s is in use, its DCSSs will be " 480 "saved when it becomes idle\n", 481 dev_info->segment_name); 482 dev_info->save_pending = 1; 483 } 484 } else if (inbuf[0] == '0') { 485 if (dev_info->save_pending) { 486 // device is busy & the user wants to undo his save 487 // request 488 dev_info->save_pending = 0; 489 pr_info("A pending save request for device %s " 490 "has been canceled\n", 491 dev_info->segment_name); 492 } 493 } else { 494 up_write(&dcssblk_devices_sem); 495 return -EINVAL; 496 } 497 up_write(&dcssblk_devices_sem); 498 return count; 499 } 500 static DEVICE_ATTR(save, S_IWUSR | S_IRUSR, dcssblk_save_show, 501 dcssblk_save_store); 502 503 /* 504 * device attribute for showing all segments in a device 505 */ 506 static ssize_t 507 dcssblk_seglist_show(struct device *dev, struct device_attribute *attr, 508 char *buf) 509 { 510 struct dcssblk_dev_info *dev_info; 511 struct segment_info *entry; 512 int i; 513 514 i = 0; 515 down_read(&dcssblk_devices_sem); 516 dev_info = container_of(dev, struct dcssblk_dev_info, dev); 517 list_for_each_entry(entry, &dev_info->seg_list, lh) 518 i += sysfs_emit_at(buf, i, "%s\n", entry->segment_name); 519 up_read(&dcssblk_devices_sem); 520 return i; 521 } 522 static DEVICE_ATTR(seglist, S_IRUSR, dcssblk_seglist_show, NULL); 523 524 static struct attribute *dcssblk_dev_attrs[] = { 525 &dev_attr_shared.attr, 526 &dev_attr_save.attr, 527 &dev_attr_seglist.attr, 528 NULL, 529 }; 530 static struct attribute_group dcssblk_dev_attr_group = { 531 .attrs = dcssblk_dev_attrs, 532 }; 533 static const struct attribute_group *dcssblk_dev_attr_groups[] = { 534 &dcssblk_dev_attr_group, 535 NULL, 536 }; 537 538 static int dcssblk_setup_dax(struct dcssblk_dev_info *dev_info) 539 { 540 struct dax_device *dax_dev; 541 542 dax_dev = alloc_dax(dev_info, &dcssblk_dax_ops); 543 if (IS_ERR(dax_dev)) 544 return PTR_ERR(dax_dev); 545 set_dax_synchronous(dax_dev); 546 dev_info->dax_dev = dax_dev; 547 return dax_add_host(dev_info->dax_dev, dev_info->gd); 548 } 549 550 /* 551 * device attribute for adding devices 552 */ 553 static ssize_t 554 dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 555 { 556 struct queue_limits lim = { 557 .logical_block_size = 4096, 558 .features = BLK_FEAT_DAX, 559 }; 560 int rc, i, j, num_of_segments; 561 struct dcssblk_dev_info *dev_info; 562 struct segment_info *seg_info, *temp; 563 char *local_buf; 564 void *addr; 565 unsigned long seg_byte_size; 566 567 dev_info = NULL; 568 seg_info = NULL; 569 if (dev != dcssblk_root_dev) { 570 rc = -EINVAL; 571 goto out_nobuf; 572 } 573 if ((count < 1) || (buf[0] == '\0') || (buf[0] == '\n')) { 574 rc = -ENAMETOOLONG; 575 goto out_nobuf; 576 } 577 578 local_buf = kmalloc(count + 1, GFP_KERNEL); 579 if (local_buf == NULL) { 580 rc = -ENOMEM; 581 goto out_nobuf; 582 } 583 584 /* 585 * parse input 586 */ 587 num_of_segments = 0; 588 for (i = 0; (i < count && (buf[i] != '\0') && (buf[i] != '\n')); i++) { 589 for (j = i; j < count && 590 (buf[j] != ':') && 591 (buf[j] != '\0') && 592 (buf[j] != '\n'); j++) { 593 local_buf[j-i] = toupper(buf[j]); 594 } 595 local_buf[j-i] = '\0'; 596 if (((j - i) == 0) || ((j - i) > 8)) { 597 rc = -ENAMETOOLONG; 598 goto seg_list_del; 599 } 600 601 rc = dcssblk_load_segment(local_buf, &seg_info); 602 if (rc < 0) 603 goto seg_list_del; 604 /* 605 * get a struct dcssblk_dev_info 606 */ 607 if (num_of_segments == 0) { 608 dev_info = kzalloc_obj(struct dcssblk_dev_info, 609 GFP_KERNEL); 610 if (dev_info == NULL) { 611 rc = -ENOMEM; 612 goto out; 613 } 614 strscpy(dev_info->segment_name, local_buf); 615 dev_info->segment_type = seg_info->segment_type; 616 INIT_LIST_HEAD(&dev_info->seg_list); 617 } 618 list_add_tail(&seg_info->lh, &dev_info->seg_list); 619 num_of_segments++; 620 i = j; 621 622 if ((buf[j] == '\0') || (buf[j] == '\n')) 623 break; 624 } 625 626 /* no trailing colon at the end of the input */ 627 if ((i > 0) && (buf[i-1] == ':')) { 628 rc = -ENAMETOOLONG; 629 goto seg_list_del; 630 } 631 strscpy(local_buf, buf, i + 1); 632 dev_info->num_of_segments = num_of_segments; 633 rc = dcssblk_is_continuous(dev_info); 634 if (rc < 0) 635 goto seg_list_del; 636 637 dev_info->start = dcssblk_find_lowest_addr(dev_info); 638 dev_info->end = dcssblk_find_highest_addr(dev_info); 639 640 dev_set_name(&dev_info->dev, "%s", dev_info->segment_name); 641 dev_info->dev.release = dcssblk_release_segment; 642 dev_info->dev.groups = dcssblk_dev_attr_groups; 643 INIT_LIST_HEAD(&dev_info->lh); 644 dev_info->gd = blk_alloc_disk(&lim, NUMA_NO_NODE); 645 if (IS_ERR(dev_info->gd)) { 646 rc = PTR_ERR(dev_info->gd); 647 goto seg_list_del; 648 } 649 dev_info->gd->major = dcssblk_major; 650 dev_info->gd->minors = DCSSBLK_MINORS_PER_DISK; 651 dev_info->gd->fops = &dcssblk_devops; 652 dev_info->gd->private_data = dev_info; 653 dev_info->gd->flags |= GENHD_FL_NO_PART; 654 655 seg_byte_size = (dev_info->end - dev_info->start + 1); 656 set_capacity(dev_info->gd, seg_byte_size >> 9); // size in sectors 657 pr_info("Loaded %s with total size %lu bytes and capacity %lu " 658 "sectors\n", local_buf, seg_byte_size, seg_byte_size >> 9); 659 660 dev_info->save_pending = 0; 661 dev_info->is_shared = 1; 662 dev_info->dev.parent = dcssblk_root_dev; 663 664 /* 665 *get minor, add to list 666 */ 667 down_write(&dcssblk_devices_sem); 668 if (dcssblk_get_segment_by_name(local_buf)) { 669 rc = -EEXIST; 670 goto release_gd; 671 } 672 rc = dcssblk_assign_free_minor(dev_info); 673 if (rc) 674 goto release_gd; 675 scnprintf(dev_info->gd->disk_name, sizeof(dev_info->gd->disk_name), 676 "dcssblk%d", dev_info->gd->first_minor); 677 list_add_tail(&dev_info->lh, &dcssblk_devices); 678 679 if (!try_module_get(THIS_MODULE)) { 680 rc = -ENODEV; 681 goto dev_list_del; 682 } 683 /* 684 * register the device 685 */ 686 rc = device_register(&dev_info->dev); 687 if (rc) 688 goto put_dev; 689 690 if (!IS_ALIGNED(dev_info->start, SUBSECTION_SIZE) || 691 !IS_ALIGNED(dev_info->end + 1, SUBSECTION_SIZE)) { 692 pr_info("DCSS %s is not aligned to %lu bytes, DAX support disabled\n", 693 local_buf, SUBSECTION_SIZE); 694 } else { 695 dev_info->pgmap.type = MEMORY_DEVICE_FS_DAX; 696 dev_info->pgmap.range.start = dev_info->start; 697 dev_info->pgmap.range.end = dev_info->end; 698 dev_info->pgmap.nr_range = 1; 699 addr = devm_memremap_pages(&dev_info->dev, &dev_info->pgmap); 700 if (IS_ERR(addr)) { 701 rc = PTR_ERR(addr); 702 goto put_dev; 703 } 704 dev_info->pgmap_addr = addr; 705 rc = dcssblk_setup_dax(dev_info); 706 if (rc) 707 goto out_dax; 708 pr_info("DAX support enabled for DCSS %s\n", local_buf); 709 } 710 711 get_device(&dev_info->dev); 712 rc = device_add_disk(&dev_info->dev, dev_info->gd, NULL); 713 if (rc) 714 goto out_dax_host; 715 716 switch (dev_info->segment_type) { 717 case SEG_TYPE_SR: 718 case SEG_TYPE_ER: 719 case SEG_TYPE_SC: 720 set_disk_ro(dev_info->gd,1); 721 break; 722 default: 723 set_disk_ro(dev_info->gd,0); 724 break; 725 } 726 up_write(&dcssblk_devices_sem); 727 rc = count; 728 goto out; 729 730 out_dax_host: 731 put_device(&dev_info->dev); 732 dax_remove_host(dev_info->gd); 733 out_dax: 734 kill_dax(dev_info->dax_dev); 735 put_dax(dev_info->dax_dev); 736 if (dev_info->pgmap_addr) 737 devm_memunmap_pages(&dev_info->dev, &dev_info->pgmap); 738 put_dev: 739 list_del(&dev_info->lh); 740 put_disk(dev_info->gd); 741 list_for_each_entry(seg_info, &dev_info->seg_list, lh) { 742 segment_unload(seg_info->segment_name); 743 } 744 put_device(&dev_info->dev); 745 up_write(&dcssblk_devices_sem); 746 goto out; 747 dev_list_del: 748 list_del(&dev_info->lh); 749 release_gd: 750 put_disk(dev_info->gd); 751 up_write(&dcssblk_devices_sem); 752 seg_list_del: 753 if (dev_info == NULL) 754 goto out; 755 list_for_each_entry_safe(seg_info, temp, &dev_info->seg_list, lh) { 756 list_del(&seg_info->lh); 757 segment_unload(seg_info->segment_name); 758 kfree(seg_info); 759 } 760 kfree(dev_info); 761 out: 762 kfree(local_buf); 763 out_nobuf: 764 return rc; 765 } 766 767 /* 768 * device attribute for removing devices 769 */ 770 static ssize_t 771 dcssblk_remove_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 772 { 773 struct dcssblk_dev_info *dev_info; 774 struct segment_info *entry; 775 int rc, i; 776 char *local_buf; 777 778 if (dev != dcssblk_root_dev) { 779 return -EINVAL; 780 } 781 local_buf = kmalloc(count + 1, GFP_KERNEL); 782 if (local_buf == NULL) { 783 return -ENOMEM; 784 } 785 /* 786 * parse input 787 */ 788 for (i = 0; (i < count && (*(buf+i)!='\0') && (*(buf+i)!='\n')); i++) { 789 local_buf[i] = toupper(buf[i]); 790 } 791 local_buf[i] = '\0'; 792 if ((i == 0) || (i > 8)) { 793 rc = -ENAMETOOLONG; 794 goto out_buf; 795 } 796 797 down_write(&dcssblk_devices_sem); 798 dev_info = dcssblk_get_device_by_name(local_buf); 799 if (dev_info == NULL) { 800 up_write(&dcssblk_devices_sem); 801 pr_warn("Device %s cannot be removed because it is not a known device\n", 802 local_buf); 803 rc = -ENODEV; 804 goto out_buf; 805 } 806 if (atomic_read(&dev_info->use_count) != 0) { 807 up_write(&dcssblk_devices_sem); 808 pr_warn("Device %s cannot be removed while it is in use\n", 809 local_buf); 810 rc = -EBUSY; 811 goto out_buf; 812 } 813 814 list_del(&dev_info->lh); 815 /* unload all related segments */ 816 list_for_each_entry(entry, &dev_info->seg_list, lh) 817 segment_unload(entry->segment_name); 818 up_write(&dcssblk_devices_sem); 819 820 dax_remove_host(dev_info->gd); 821 kill_dax(dev_info->dax_dev); 822 put_dax(dev_info->dax_dev); 823 if (dev_info->pgmap_addr) 824 devm_memunmap_pages(&dev_info->dev, &dev_info->pgmap); 825 del_gendisk(dev_info->gd); 826 put_disk(dev_info->gd); 827 828 device_unregister(&dev_info->dev); 829 put_device(&dev_info->dev); 830 831 rc = count; 832 out_buf: 833 kfree(local_buf); 834 return rc; 835 } 836 837 static int 838 dcssblk_open(struct gendisk *disk, blk_mode_t mode) 839 { 840 struct dcssblk_dev_info *dev_info = disk->private_data; 841 int rc; 842 843 if (NULL == dev_info) { 844 rc = -ENODEV; 845 goto out; 846 } 847 atomic_inc(&dev_info->use_count); 848 rc = 0; 849 out: 850 return rc; 851 } 852 853 static void 854 dcssblk_release(struct gendisk *disk) 855 { 856 struct dcssblk_dev_info *dev_info = disk->private_data; 857 struct segment_info *entry; 858 859 if (!dev_info) { 860 WARN_ON(1); 861 return; 862 } 863 down_write(&dcssblk_devices_sem); 864 if (atomic_dec_and_test(&dev_info->use_count) 865 && (dev_info->save_pending)) { 866 pr_info("Device %s has become idle and is being saved " 867 "now\n", dev_info->segment_name); 868 list_for_each_entry(entry, &dev_info->seg_list, lh) { 869 if (entry->segment_type == SEG_TYPE_EN || 870 entry->segment_type == SEG_TYPE_SN) 871 pr_warn("DCSS %s is of type SN or EN and cannot" 872 " be saved\n", entry->segment_name); 873 else 874 segment_save(entry->segment_name); 875 } 876 dev_info->save_pending = 0; 877 } 878 up_write(&dcssblk_devices_sem); 879 } 880 881 static void 882 dcssblk_submit_bio(struct bio *bio) 883 { 884 struct dcssblk_dev_info *dev_info; 885 struct bio_vec bvec; 886 struct bvec_iter iter; 887 unsigned long index; 888 void *page_addr; 889 unsigned long source_addr; 890 unsigned long bytes_done; 891 892 bytes_done = 0; 893 dev_info = bio->bi_bdev->bd_disk->private_data; 894 if (dev_info == NULL) 895 goto fail; 896 if (!IS_ALIGNED(bio->bi_iter.bi_sector, 8) || 897 !IS_ALIGNED(bio->bi_iter.bi_size, PAGE_SIZE)) 898 /* Request is not page-aligned. */ 899 goto fail; 900 /* verify data transfer direction */ 901 if (dev_info->is_shared) { 902 switch (dev_info->segment_type) { 903 case SEG_TYPE_SR: 904 case SEG_TYPE_ER: 905 case SEG_TYPE_SC: 906 /* cannot write to these segments */ 907 if (bio_data_dir(bio) == WRITE) { 908 pr_warn("Writing to %s failed because it is a read-only device\n", 909 dev_name(&dev_info->dev)); 910 goto fail; 911 } 912 } 913 } 914 915 index = (bio->bi_iter.bi_sector >> 3); 916 bio_for_each_segment(bvec, bio, iter) { 917 page_addr = bvec_virt(&bvec); 918 source_addr = dev_info->start + (index<<12) + bytes_done; 919 if (unlikely(!IS_ALIGNED((unsigned long)page_addr, PAGE_SIZE) || 920 !IS_ALIGNED(bvec.bv_len, PAGE_SIZE))) 921 // More paranoia. 922 goto fail; 923 if (bio_data_dir(bio) == READ) 924 memcpy(page_addr, __va(source_addr), bvec.bv_len); 925 else 926 memcpy(__va(source_addr), page_addr, bvec.bv_len); 927 bytes_done += bvec.bv_len; 928 } 929 bio_endio(bio); 930 return; 931 fail: 932 bio_io_error(bio); 933 } 934 935 static long 936 __dcssblk_direct_access(struct dcssblk_dev_info *dev_info, pgoff_t pgoff, 937 long nr_pages, void **kaddr, unsigned long *pfn) 938 { 939 resource_size_t offset = pgoff * PAGE_SIZE; 940 unsigned long dev_sz; 941 942 dev_sz = dev_info->end - dev_info->start + 1; 943 if (kaddr) 944 *kaddr = __va(dev_info->start + offset); 945 if (pfn) 946 *pfn = PFN_DOWN(dev_info->start + offset); 947 948 return (dev_sz - offset) / PAGE_SIZE; 949 } 950 951 static long 952 dcssblk_dax_direct_access(struct dax_device *dax_dev, pgoff_t pgoff, 953 long nr_pages, enum dax_access_mode mode, void **kaddr, 954 unsigned long *pfn) 955 { 956 struct dcssblk_dev_info *dev_info = dax_get_private(dax_dev); 957 958 return __dcssblk_direct_access(dev_info, pgoff, nr_pages, kaddr, pfn); 959 } 960 961 static void 962 dcssblk_check_params(void) 963 { 964 int rc, i, j, k; 965 char buf[DCSSBLK_PARM_LEN + 1]; 966 struct dcssblk_dev_info *dev_info; 967 968 for (i = 0; (i < DCSSBLK_PARM_LEN) && (dcssblk_segments[i] != '\0'); 969 i++) { 970 for (j = i; (j < DCSSBLK_PARM_LEN) && 971 (dcssblk_segments[j] != ',') && 972 (dcssblk_segments[j] != '\0') && 973 (dcssblk_segments[j] != '('); j++) 974 { 975 buf[j-i] = dcssblk_segments[j]; 976 } 977 buf[j-i] = '\0'; 978 rc = dcssblk_add_store(dcssblk_root_dev, NULL, buf, j-i); 979 if ((rc >= 0) && (dcssblk_segments[j] == '(')) { 980 for (k = 0; (buf[k] != ':') && (buf[k] != '\0'); k++) 981 buf[k] = toupper(buf[k]); 982 buf[k] = '\0'; 983 if (!strncmp(&dcssblk_segments[j], "(local)", 7)) { 984 down_read(&dcssblk_devices_sem); 985 dev_info = dcssblk_get_device_by_name(buf); 986 up_read(&dcssblk_devices_sem); 987 if (dev_info) 988 dcssblk_shared_store(&dev_info->dev, 989 NULL, "0\n", 2); 990 } 991 } 992 while ((dcssblk_segments[j] != ',') && 993 (dcssblk_segments[j] != '\0')) 994 { 995 j++; 996 } 997 if (dcssblk_segments[j] == '\0') 998 break; 999 i = j; 1000 } 1001 } 1002 1003 /* 1004 * The init/exit functions. 1005 */ 1006 static void __exit 1007 dcssblk_exit(void) 1008 { 1009 root_device_unregister(dcssblk_root_dev); 1010 unregister_blkdev(dcssblk_major, DCSSBLK_NAME); 1011 } 1012 1013 static int __init 1014 dcssblk_init(void) 1015 { 1016 int rc; 1017 1018 dcssblk_root_dev = root_device_register("dcssblk"); 1019 if (IS_ERR(dcssblk_root_dev)) 1020 return PTR_ERR(dcssblk_root_dev); 1021 rc = device_create_file(dcssblk_root_dev, &dev_attr_add); 1022 if (rc) 1023 goto out_root; 1024 rc = device_create_file(dcssblk_root_dev, &dev_attr_remove); 1025 if (rc) 1026 goto out_root; 1027 rc = register_blkdev(0, DCSSBLK_NAME); 1028 if (rc < 0) 1029 goto out_root; 1030 dcssblk_major = rc; 1031 init_rwsem(&dcssblk_devices_sem); 1032 1033 dcssblk_check_params(); 1034 return 0; 1035 1036 out_root: 1037 root_device_unregister(dcssblk_root_dev); 1038 1039 return rc; 1040 } 1041 1042 module_init(dcssblk_init); 1043 module_exit(dcssblk_exit); 1044 1045 module_param_string(segments, dcssblk_segments, DCSSBLK_PARM_LEN, 0444); 1046 MODULE_PARM_DESC(segments, "Name of DCSS segment(s) to be loaded, " 1047 "comma-separated list, names in each set separated " 1048 "by commas are separated by colons, each set contains " 1049 "names of contiguous segments and each name max. 8 chars.\n" 1050 "Adding \"(local)\" to the end of each set equals echoing 0 " 1051 "to /sys/devices/dcssblk/<device name>/shared after loading " 1052 "the contiguous segments - \n" 1053 "e.g. segments=\"mydcss1,mydcss2:mydcss3,mydcss4(local)\""); 1054 1055 MODULE_DESCRIPTION("S/390 block driver for DCSS memory"); 1056 MODULE_LICENSE("GPL"); 1057