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