Pull block driver updates from Jens Axboe: "Here are the block driver changes for 4.4. This pull request contains: - NVMe: - Refactor and moving of code to prepare for proper target support. From Christoph and Jay. - 32-bit nvme warning fix from Arnd. - Error initialization fix from me. - Proper namespace removal and reference counting support from Keith. - Device resume fix on IO failure, also from Keith. - Dependency fix from Keith, now that nvme isn't under the umbrella of the block anymore. - Target location and maintainers update from Jay. - From Ming Lei, the long awaited DIO/AIO support for loop. - Enable BD-RE writeable opens, from Georgios" * 'for-4.4/drivers' of git://git.kernel.dk/linux-block: (24 commits) Update target repo for nvme patch contributions NVMe: initialize error to '0' nvme: use an integer value to Linux errno values nvme: fix 32-bit build warning NVMe: Add explicit block config dependency nvme: include <linux/types.ĥ> in <linux/nvme.h> nvme: move to a new drivers/nvme/host directory nvme.h: add missing nvme_id_ctrl endianess annotations nvme: move hardware structures out of the uapi version of nvme.h nvme: add a local nvme.h header nvme: properly handle partially initialized queues in nvme_create_io_queues nvme: merge nvme_dev_start, nvme_dev_resume and nvme_async_probe nvme: factor reset code into a common helper nvme: merge nvme_dev_reset into nvme_reset_failed_dev nvme: delete dev from dev_list in nvme_reset NVMe: Simplify device resume on io queue failure NVMe: Namespace removal simplifications NVMe: Reference count open namespaces cdrom: Random writing support for BD-RE media block: loop: support DIO & AIO ...
Unified · Split
| @@ -7486,11 +7486,13 @@ F: drivers/video/fbdev/riva/ · 7485 unmodified lines | |||
| 7486 | F: drivers/video/fbdev/nvidia/ | 7486 | F: drivers/video/fbdev/nvidia/ |
| 7487 | 7487 | ||
| 7488 | NVM EXPRESS DRIVER | 7488 | NVM EXPRESS DRIVER |
| 7489 | M: Matthew Wilcox <willy@linux.intel.com> | 7489 | M: Keith Busch <keith.busch@intel.com> |
| 7490 | M: Jens Axboe <axboe@fb.com> | ||
| 7490 | L: linux-nvme@lists.infradead.org | 7491 | L: linux-nvme@lists.infradead.org |
| 7491 | T: git git://git.infradead.org/users/willy/linux-nvme.git | 7492 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git |
| 7493 | W: https://kernel.googlesource.com/pub/scm/linux/kernel/git/axboe/linux-block/ | ||
| 7492 | S: Supported | 7494 | S: Supported |
| 7493 | F: drivers/block/nvme* | 7495 | F: drivers/nvme/host/ |
| 7494 | F: include/linux/nvme.h | 7496 | F: include/linux/nvme.h |
| 7495 | 7497 | ||
| 7496 | NVMEM FRAMEWORK | 7498 | NVMEM FRAMEWORK |
| @@ -18,6 +18,8 @@ source "drivers/pnp/Kconfig" · 17 unmodified lines | |||
| 18 | 18 | ||
| 19 | source "drivers/block/Kconfig" | 19 | source "drivers/block/Kconfig" |
| 20 | 20 | ||
| 21 | source "drivers/nvme/Kconfig" | ||
| 22 | |||
| 21 | # misc before ide - BLK_DEV_SGIIOC4 depends on SGI_IOC4 | 23 | # misc before ide - BLK_DEV_SGIIOC4 depends on SGI_IOC4 |
| 22 | 24 | ||
| 23 | source "drivers/misc/Kconfig" | 25 | source "drivers/misc/Kconfig" |
| @@ -70,6 +70,7 @@ obj-$(CONFIG_NUBUS) += nubus/ · 69 unmodified lines | |||
| 70 | obj-y += macintosh/ | 70 | obj-y += macintosh/ |
| 71 | obj-$(CONFIG_IDE) += ide/ | 71 | obj-$(CONFIG_IDE) += ide/ |
| 72 | obj-$(CONFIG_SCSI) += scsi/ | 72 | obj-$(CONFIG_SCSI) += scsi/ |
| 73 | obj-y += nvme/ | ||
| 73 | obj-$(CONFIG_ATA) += ata/ | 74 | obj-$(CONFIG_ATA) += ata/ |
| 74 | obj-$(CONFIG_TARGET_CORE) += target/ | 75 | obj-$(CONFIG_TARGET_CORE) += target/ |
| 75 | obj-$(CONFIG_MTD) += mtd/ | 76 | obj-$(CONFIG_MTD) += mtd/ |
| @@ -310,17 +310,6 @@ config BLK_DEV_NBD · 309 unmodified lines | |||
| 310 | 310 | ||
| 311 | If unsure, say N. | 311 | If unsure, say N. |
| 312 | 312 | ||
| 313 | config BLK_DEV_NVME | ||
| 314 | tristate "NVM Express block device" | ||
| 315 | depends on PCI | ||
| 316 | ---help--- | ||
| 317 | The NVM Express driver is for solid state drives directly | ||
| 318 | connected to the PCI or PCI Express bus. If you know you | ||
| 319 | don't have one of these, it is safe to answer N. | ||
| 320 | |||
| 321 | To compile this driver as a module, choose M here: the | ||
| 322 | module will be called nvme. | ||
| 323 | |||
| 324 | config BLK_DEV_SKD | 313 | config BLK_DEV_SKD |
| 325 | tristate "STEC S1120 Block Driver" | 314 | tristate "STEC S1120 Block Driver" |
| 326 | depends on PCI | 315 | depends on PCI |
| @@ -22,7 +22,6 @@ obj-$(CONFIG_XILINX_SYSACE) += xsysace.o · 21 unmodified lines | |||
| 22 | obj-$(CONFIG_CDROM_PKTCDVD) += pktcdvd.o | 22 | obj-$(CONFIG_CDROM_PKTCDVD) += pktcdvd.o |
| 23 | obj-$(CONFIG_MG_DISK) += mg_disk.o | 23 | obj-$(CONFIG_MG_DISK) += mg_disk.o |
| 24 | obj-$(CONFIG_SUNVDC) += sunvdc.o | 24 | obj-$(CONFIG_SUNVDC) += sunvdc.o |
| 25 | obj-$(CONFIG_BLK_DEV_NVME) += nvme.o | ||
| 26 | obj-$(CONFIG_BLK_DEV_SKD) += skd.o | 25 | obj-$(CONFIG_BLK_DEV_SKD) += skd.o |
| 27 | obj-$(CONFIG_BLK_DEV_OSD) += osdblk.o | 26 | obj-$(CONFIG_BLK_DEV_OSD) += osdblk.o |
| 28 | 27 | ||
| @@ -44,6 +43,5 @@ obj-$(CONFIG_BLK_DEV_RSXX) += rsxx/ · 15 unmodified lines | |||
| 44 | obj-$(CONFIG_BLK_DEV_NULL_BLK) += null_blk.o | 43 | obj-$(CONFIG_BLK_DEV_NULL_BLK) += null_blk.o |
| 45 | obj-$(CONFIG_ZRAM) += zram/ | 44 | obj-$(CONFIG_ZRAM) += zram/ |
| 46 | 45 | ||
| 47 | nvme-y := nvme-core.o nvme-scsi.o | ||
| 48 | skd-y := skd_main.o | 46 | skd-y := skd_main.o |
| 49 | swim_mod-y := swim.o swim_asm.o | 47 | swim_mod-y := swim.o swim_asm.o |
| @@ -164,6 +164,62 @@ static loff_t get_loop_size(struct loop_device *lo, struct file *file) · 163 unmodified lines | |||
| 164 | return get_size(lo->lo_offset, lo->lo_sizelimit, file); | 164 | return get_size(lo->lo_offset, lo->lo_sizelimit, file); |
| 165 | } | 165 | } |
| 166 | 166 | ||
| 167 | static void __loop_update_dio(struct loop_device *lo, bool dio) | ||
| 168 | { | ||
| 169 | struct file *file = lo->lo_backing_file; | ||
| 170 | struct address_space *mapping = file->f_mapping; | ||
| 171 | struct inode *inode = mapping->host; | ||
| 172 | unsigned short sb_bsize = 0; | ||
| 173 | unsigned dio_align = 0; | ||
| 174 | bool use_dio; | ||
| 175 | |||
| 176 | if (inode->i_sb->s_bdev) { | ||
| 177 | sb_bsize = bdev_logical_block_size(inode->i_sb->s_bdev); | ||
| 178 | dio_align = sb_bsize - 1; | ||
| 179 | } | ||
| 180 | |||
| 181 | /* | ||
| 182 | * We support direct I/O only if lo_offset is aligned with the | ||
| 183 | * logical I/O size of backing device, and the logical block | ||
| 184 | * size of loop is bigger than the backing device's and the loop | ||
| 185 | * needn't transform transfer. | ||
| 186 | * | ||
| 187 | * TODO: the above condition may be loosed in the future, and | ||
| 188 | * direct I/O may be switched runtime at that time because most | ||
| 189 | * of requests in sane appplications should be PAGE_SIZE algined | ||
| 190 | */ | ||
| 191 | if (dio) { | ||
| 192 | if (queue_logical_block_size(lo->lo_queue) >= sb_bsize && | ||
| 193 | !(lo->lo_offset & dio_align) && | ||
| 194 | mapping->a_ops->direct_IO && | ||
| 195 | !lo->transfer) | ||
| 196 | use_dio = true; | ||
| 197 | else | ||
| 198 | use_dio = false; | ||
| 199 | } else { | ||
| 200 | use_dio = false; | ||
| 201 | } | ||
| 202 | |||
| 203 | if (lo->use_dio == use_dio) | ||
| 204 | return; | ||
| 205 | |||
| 206 | /* flush dirty pages before changing direct IO */ | ||
| 207 | vfs_fsync(file, 0); | ||
| 208 | |||
| 209 | /* | ||
| 210 | * The flag of LO_FLAGS_DIRECT_IO is handled similarly with | ||
| 211 | * LO_FLAGS_READ_ONLY, both are set from kernel, and losetup | ||
| 212 | * will get updated by ioctl(LOOP_GET_STATUS) | ||
| 213 | */ | ||
| 214 | blk_mq_freeze_queue(lo->lo_queue); | ||
| 215 | lo->use_dio = use_dio; | ||
| 216 | if (use_dio) | ||
| 217 | lo->lo_flags |= LO_FLAGS_DIRECT_IO; | ||
| 218 | else | ||
| 219 | lo->lo_flags &= ~LO_FLAGS_DIRECT_IO; | ||
| 220 | blk_mq_unfreeze_queue(lo->lo_queue); | ||
| 221 | } | ||
| 222 | |||
| 167 | static int | 223 | static int |
| 168 | figure_loop_size(struct loop_device *lo, loff_t offset, loff_t sizelimit) | 224 | figure_loop_size(struct loop_device *lo, loff_t offset, loff_t sizelimit) |
| 169 | { | 225 | { |
| @@ -389,6 +445,89 @@ static int lo_req_flush(struct loop_device *lo, struct request *rq) · 219 unmodified lines | |||
| 389 | return ret; | 445 | return ret; |
| 390 | } | 446 | } |
| 391 | 447 | ||
| 448 | static inline void handle_partial_read(struct loop_cmd *cmd, long bytes) | ||
| 449 | { | ||
| 450 | if (bytes < 0 || (cmd->rq->cmd_flags & REQ_WRITE)) | ||
| 451 | return; | ||
| 452 | |||
| 453 | if (unlikely(bytes < blk_rq_bytes(cmd->rq))) { | ||
| 454 | struct bio *bio = cmd->rq->bio; | ||
| 455 | |||
| 456 | bio_advance(bio, bytes); | ||
| 457 | zero_fill_bio(bio); | ||
| 458 | } | ||
| 459 | } | ||
| 460 | |||
| 461 | static void lo_rw_aio_complete(struct kiocb *iocb, long ret, long ret2) | ||
| 462 | { | ||
| 463 | struct loop_cmd *cmd = container_of(iocb, struct loop_cmd, iocb); | ||
| 464 | struct request *rq = cmd->rq; | ||
| 465 | |||
| 466 | handle_partial_read(cmd, ret); | ||
| 467 | |||
| 468 | if (ret > 0) | ||
| 469 | ret = 0; | ||
| 470 | else if (ret < 0) | ||
| 471 | ret = -EIO; | ||
| 472 | |||
| 473 | blk_mq_complete_request(rq, ret); | ||
| 474 | } | ||
| 475 | |||
| 476 | static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd, | ||
| 477 | loff_t pos, bool rw) | ||
| 478 | { | ||
| 479 | struct iov_iter iter; | ||
| 480 | struct bio_vec *bvec; | ||
| 481 | struct bio *bio = cmd->rq->bio; | ||
| 482 | struct file *file = lo->lo_backing_file; | ||
| 483 | int ret; | ||
| 484 | |||
| 485 | /* nomerge for loop request queue */ | ||
| 486 | WARN_ON(cmd->rq->bio != cmd->rq->biotail); | ||
| 487 | |||
| 488 | bvec = __bvec_iter_bvec(bio->bi_io_vec, bio->bi_iter); | ||
| 489 | iov_iter_bvec(&iter, ITER_BVEC | rw, bvec, | ||
| 490 | bio_segments(bio), blk_rq_bytes(cmd->rq)); | ||
| 491 | |||
| 492 | cmd->iocb.ki_pos = pos; | ||
| 493 | cmd->iocb.ki_filp = file; | ||
| 494 | cmd->iocb.ki_complete = lo_rw_aio_complete; | ||
| 495 | cmd->iocb.ki_flags = IOCB_DIRECT; | ||
| 496 | |||
| 497 | if (rw == WRITE) | ||
| 498 | ret = file->f_op->write_iter(&cmd->iocb, &iter); | ||
| 499 | else | ||
| 500 | ret = file->f_op->read_iter(&cmd->iocb, &iter); | ||
| 501 | |||
| 502 | if (ret != -EIOCBQUEUED) | ||
| 503 | cmd->iocb.ki_complete(&cmd->iocb, ret, 0); | ||
| 504 | return 0; | ||
| 505 | } | ||
| 506 | |||
| 507 | |||
| 508 | static inline int lo_rw_simple(struct loop_device *lo, | ||
| 509 | struct request *rq, loff_t pos, bool rw) | ||
| 510 | { | ||
| 511 | struct loop_cmd *cmd = blk_mq_rq_to_pdu(rq); | ||
| 512 | |||
| 513 | if (cmd->use_aio) | ||
| 514 | return lo_rw_aio(lo, cmd, pos, rw); | ||
| 515 | |||
| 516 | /* | ||
| 517 | * lo_write_simple and lo_read_simple should have been covered | ||
| 518 | * by io submit style function like lo_rw_aio(), one blocker | ||
| 519 | * is that lo_read_simple() need to call flush_dcache_page after | ||
| 520 | * the page is written from kernel, and it isn't easy to handle | ||
| 521 | * this in io submit style function which submits all segments | ||
| 522 | * of the req at one time. And direct read IO doesn't need to | ||
| 523 | * run flush_dcache_page(). | ||
| 524 | */ | ||
| 525 | if (rw == WRITE) | ||
| 526 | return lo_write_simple(lo, rq, pos); | ||
| 527 | else | ||
| 528 | return lo_read_simple(lo, rq, pos); | ||
| 529 | } | ||
| 530 | |||
| 392 | static int do_req_filebacked(struct loop_device *lo, struct request *rq) | 531 | static int do_req_filebacked(struct loop_device *lo, struct request *rq) |
| 393 | { | 532 | { |
| 394 | loff_t pos; | 533 | loff_t pos; |
| @@ -404,13 +543,13 @@ static int do_req_filebacked(struct loop_device *lo, struct request *rq) · 9 unmodified lines | |||
| 404 | else if (lo->transfer) | 543 | else if (lo->transfer) |
| 405 | ret = lo_write_transfer(lo, rq, pos); | 544 | ret = lo_write_transfer(lo, rq, pos); |
| 406 | else | 545 | else |
| 407 | ret = lo_write_simple(lo, rq, pos); | 546 | ret = lo_rw_simple(lo, rq, pos, WRITE); |
| 408 | 547 | ||
| 409 | } else { | 548 | } else { |
| 410 | if (lo->transfer) | 549 | if (lo->transfer) |
| 411 | ret = lo_read_transfer(lo, rq, pos); | 550 | ret = lo_read_transfer(lo, rq, pos); |
| 412 | else | 551 | else |
| 413 | ret = lo_read_simple(lo, rq, pos); | 552 | ret = lo_rw_simple(lo, rq, pos, READ); |
| 414 | } | 553 | } |
| 415 | 554 | ||
| 416 | return ret; | 555 | return ret; |
| @@ -421,6 +560,12 @@ struct switch_request { · 4 unmodified lines | |||
| 421 | struct completion wait; | 560 | struct completion wait; |
| 422 | }; | 561 | }; |
| 423 | 562 | ||
| 563 | static inline void loop_update_dio(struct loop_device *lo) | ||
| 564 | { | ||
| 565 | __loop_update_dio(lo, io_is_direct(lo->lo_backing_file) | | ||
| 566 | lo->use_dio); | ||
| 567 | } | ||
| 568 | |||
| 424 | /* | 569 | /* |
| 425 | * Do the actual switch; called from the BIO completion routine | 570 | * Do the actual switch; called from the BIO completion routine |
| 426 | */ | 571 | */ |
| @@ -441,6 +586,7 @@ static void do_loop_switch(struct loop_device *lo, struct switch_request *p) · 14 unmodified lines | |||
| 441 | mapping->host->i_bdev->bd_block_size : PAGE_SIZE; | 586 | mapping->host->i_bdev->bd_block_size : PAGE_SIZE; |
| 442 | lo->old_gfp_mask = mapping_gfp_mask(mapping); | 587 | lo->old_gfp_mask = mapping_gfp_mask(mapping); |
| 443 | mapping_set_gfp_mask(mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS)); | 588 | mapping_set_gfp_mask(mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS)); |
| 589 | loop_update_dio(lo); | ||
| 444 | } | 590 | } |
| 445 | 591 | ||
| 446 | /* | 592 | /* |
| @@ -627,11 +773,19 @@ static ssize_t loop_attr_partscan_show(struct loop_device *lo, char *buf) · 180 unmodified lines | |||
| 627 | return sprintf(buf, "%s\n", partscan ? "1" : "0"); | 773 | return sprintf(buf, "%s\n", partscan ? "1" : "0"); |
| 628 | } | 774 | } |
| 629 | 775 | ||
| 776 | static ssize_t loop_attr_dio_show(struct loop_device *lo, char *buf) | ||
| 777 | { | ||
| 778 | int dio = (lo->lo_flags & LO_FLAGS_DIRECT_IO); | ||
| 779 | |||
| 780 | return sprintf(buf, "%s\n", dio ? "1" : "0"); | ||
| 781 | } | ||
| 782 | |||
| 630 | LOOP_ATTR_RO(backing_file); | 783 | LOOP_ATTR_RO(backing_file); |
| 631 | LOOP_ATTR_RO(offset); | 784 | LOOP_ATTR_RO(offset); |
| 632 | LOOP_ATTR_RO(sizelimit); | 785 | LOOP_ATTR_RO(sizelimit); |
| 633 | LOOP_ATTR_RO(autoclear); | 786 | LOOP_ATTR_RO(autoclear); |
| 634 | LOOP_ATTR_RO(partscan); | 787 | LOOP_ATTR_RO(partscan); |
| 788 | LOOP_ATTR_RO(dio); | ||
| 635 | 789 | ||
| 636 | static struct attribute *loop_attrs[] = { | 790 | static struct attribute *loop_attrs[] = { |
| 637 | &loop_attr_backing_file.attr, | 791 | &loop_attr_backing_file.attr, |
| @@ -639,6 +793,7 @@ static struct attribute *loop_attrs[] = { · 1 unmodified line | |||
| 639 | &loop_attr_sizelimit.attr, | 793 | &loop_attr_sizelimit.attr, |
| 640 | &loop_attr_autoclear.attr, | 794 | &loop_attr_autoclear.attr, |
| 641 | &loop_attr_partscan.attr, | 795 | &loop_attr_partscan.attr, |
| 796 | &loop_attr_dio.attr, | ||
| 642 | NULL, | 797 | NULL, |
| 643 | }; | 798 | }; |
| 644 | 799 | ||
| @@ -688,6 +843,23 @@ static void loop_config_discard(struct loop_device *lo) · 43 unmodified lines | |||
| 688 | queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q); | 843 | queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q); |
| 689 | } | 844 | } |
| 690 | 845 | ||
| 846 | static void loop_unprepare_queue(struct loop_device *lo) | ||
| 847 | { | ||
| 848 | flush_kthread_worker(&lo->worker); | ||
| 849 | kthread_stop(lo->worker_task); | ||
| 850 | } | ||
| 851 | |||
| 852 | static int loop_prepare_queue(struct loop_device *lo) | ||
| 853 | { | ||
| 854 | init_kthread_worker(&lo->worker); | ||
| 855 | lo->worker_task = kthread_run(kthread_worker_fn, | ||
| 856 | &lo->worker, "loop%d", lo->lo_number); | ||
| 857 | if (IS_ERR(lo->worker_task)) | ||
| 858 | return -ENOMEM; | ||
| 859 | set_user_nice(lo->worker_task, MIN_NICE); | ||
| 860 | return 0; | ||
| 861 | } | ||
| 862 | |||
| 691 | static int loop_set_fd(struct loop_device *lo, fmode_t mode, | 863 | static int loop_set_fd(struct loop_device *lo, fmode_t mode, |
| 692 | struct block_device *bdev, unsigned int arg) | 864 | struct block_device *bdev, unsigned int arg) |
| 693 | { | 865 | { |
| @@ -745,17 +917,15 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, · 51 unmodified lines | |||
| 745 | size = get_loop_size(lo, file); | 917 | size = get_loop_size(lo, file); |
| 746 | if ((loff_t)(sector_t)size != size) | 918 | if ((loff_t)(sector_t)size != size) |
| 747 | goto out_putf; | 919 | goto out_putf; |
| 748 | error = -ENOMEM; | 920 | error = loop_prepare_queue(lo); |
| 749 | lo->wq = alloc_workqueue("kloopd%d", | 921 | if (error) |
| 750 | WQ_MEM_RECLAIM | WQ_HIGHPRI | WQ_UNBOUND, 16, | ||
| 751 | lo->lo_number); | ||
| 752 | if (!lo->wq) | ||
| 753 | goto out_putf; | 922 | goto out_putf; |
| 754 | 923 | ||
| 755 | error = 0; | 924 | error = 0; |
| 756 | 925 | ||
| 757 | set_device_ro(bdev, (lo_flags & LO_FLAGS_READ_ONLY) != 0); | 926 | set_device_ro(bdev, (lo_flags & LO_FLAGS_READ_ONLY) != 0); |
| 758 | 927 | ||
| 928 | lo->use_dio = false; | ||
| 759 | lo->lo_blocksize = lo_blocksize; | 929 | lo->lo_blocksize = lo_blocksize; |
| 760 | lo->lo_device = bdev; | 930 | lo->lo_device = bdev; |
| 761 | lo->lo_flags = lo_flags; | 931 | lo->lo_flags = lo_flags; |
| @@ -769,6 +939,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, · 7 unmodified lines | |||
| 769 | if (!(lo_flags & LO_FLAGS_READ_ONLY) && file->f_op->fsync) | 939 | if (!(lo_flags & LO_FLAGS_READ_ONLY) && file->f_op->fsync) |
| 770 | blk_queue_flush(lo->lo_queue, REQ_FLUSH); | 940 | blk_queue_flush(lo->lo_queue, REQ_FLUSH); |
| 771 | 941 | ||
| 942 | loop_update_dio(lo); | ||
| 772 | set_capacity(lo->lo_disk, size); | 943 | set_capacity(lo->lo_disk, size); |
| 773 | bd_set_size(bdev, size << 9); | 944 | bd_set_size(bdev, size << 9); |
| 774 | loop_sysfs_init(lo); | 945 | loop_sysfs_init(lo); |
| @@ -903,8 +1074,7 @@ static int loop_clr_fd(struct loop_device *lo) · 128 unmodified lines | |||
| 903 | lo->lo_flags = 0; | 1074 | lo->lo_flags = 0; |
| 904 | if (!part_shift) | 1075 | if (!part_shift) |
| 905 | lo->lo_disk->flags |= GENHD_FL_NO_PART_SCAN; | 1076 | lo->lo_disk->flags |= GENHD_FL_NO_PART_SCAN; |
| 906 | destroy_workqueue(lo->wq); | 1077 | loop_unprepare_queue(lo); |
| 907 | lo->wq = NULL; | ||
| 908 | mutex_unlock(&lo->lo_ctl_mutex); | 1078 | mutex_unlock(&lo->lo_ctl_mutex); |
| 909 | /* | 1079 | /* |
| 910 | * Need not hold lo_ctl_mutex to fput backing file. | 1080 | * Need not hold lo_ctl_mutex to fput backing file. |
| @@ -988,6 +1158,9 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) · 77 unmodified lines | |||
| 988 | lo->lo_key_owner = uid; | 1158 | lo->lo_key_owner = uid; |
| 989 | } | 1159 | } |
| 990 | 1160 | ||
| 1161 | /* update dio if lo_offset or transfer is changed */ | ||
| 1162 | __loop_update_dio(lo, lo->use_dio); | ||
| 1163 | |||
| 991 | return 0; | 1164 | return 0; |
| 992 | } | 1165 | } |
| 993 | 1166 | ||
| @@ -1138,6 +1311,20 @@ static int loop_set_capacity(struct loop_device *lo, struct block_device *bdev) · 144 unmodified lines | |||
| 1138 | return figure_loop_size(lo, lo->lo_offset, lo->lo_sizelimit); | 1311 | return figure_loop_size(lo, lo->lo_offset, lo->lo_sizelimit); |
| 1139 | } | 1312 | } |
| 1140 | 1313 | ||
| 1314 | static int loop_set_dio(struct loop_device *lo, unsigned long arg) | ||
| 1315 | { | ||
| 1316 | int error = -ENXIO; | ||
| 1317 | if (lo->lo_state != Lo_bound) | ||
| 1318 | goto out; | ||
| 1319 | |||
| 1320 | __loop_update_dio(lo, !!arg); | ||
| 1321 | if (lo->use_dio == !!arg) | ||
| 1322 | return 0; | ||
| 1323 | error = -EINVAL; | ||
| 1324 | out: | ||
| 1325 | return error; | ||
| 1326 | } | ||
| 1327 | |||
| 1141 | static int lo_ioctl(struct block_device *bdev, fmode_t mode, | 1328 | static int lo_ioctl(struct block_device *bdev, fmode_t mode, |
| 1142 | unsigned int cmd, unsigned long arg) | 1329 | unsigned int cmd, unsigned long arg) |
| 1143 | { | 1330 | { |
| @@ -1181,6 +1368,11 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, · 37 unmodified lines | |||
| 1181 | if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) | 1368 | if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) |
| 1182 | err = loop_set_capacity(lo, bdev); | 1369 | err = loop_set_capacity(lo, bdev); |
| 1183 | break; | 1370 | break; |
| 1371 | case LOOP_SET_DIRECT_IO: | ||
| 1372 | err = -EPERM; | ||
| 1373 | if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) | ||
| 1374 | err = loop_set_dio(lo, arg); | ||
| 1375 | break; | ||
| 1184 | default: | 1376 | default: |
| 1185 | err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL; | 1377 | err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL; |
| 1186 | } | 1378 | } |
| @@ -1461,23 +1653,13 @@ static int loop_queue_rq(struct blk_mq_hw_ctx *hctx, · 274 unmodified lines | |||
| 1461 | if (lo->lo_state != Lo_bound) | 1653 | if (lo->lo_state != Lo_bound) |
| 1462 | return -EIO; | 1654 | return -EIO; |
| 1463 | 1655 | ||
| 1464 | if (cmd->rq->cmd_flags & REQ_WRITE) { | 1656 | if (lo->use_dio && !(cmd->rq->cmd_flags & (REQ_FLUSH | |
| 1465 | struct loop_device *lo = cmd->rq->q->queuedata; | 1657 | REQ_DISCARD))) |
| 1466 | bool need_sched = true; | 1658 | cmd->use_aio = true; |
| 1467 | 1659 | else | |
| 1468 | spin_lock_irq(&lo->lo_lock); | 1660 | cmd->use_aio = false; |
| 1469 | if (lo->write_started) | ||
| 1470 | need_sched = false; | ||
| 1471 | else | ||
| 1472 | lo->write_started = true; | ||
| 1473 | list_add_tail(&cmd->list, &lo->write_cmd_head); | ||
| 1474 | spin_unlock_irq(&lo->lo_lock); | ||
| 1475 | 1661 | ||
| 1476 | if (need_sched) | 1662 | queue_kthread_work(&lo->worker, &cmd->work); |
| 1477 | queue_work(lo->wq, &lo->write_work); | ||
| 1478 | } else { | ||
| 1479 | queue_work(lo->wq, &cmd->read_work); | ||
| 1480 | } | ||
| 1481 | 1663 | ||
| 1482 | return BLK_MQ_RQ_QUEUE_OK; | 1664 | return BLK_MQ_RQ_QUEUE_OK; |
| 1483 | } | 1665 | } |
| @@ -1495,38 +1677,15 @@ static void loop_handle_cmd(struct loop_cmd *cmd) · 11 unmodified lines | |||
| 1495 | 1677 | ||
| 1496 | ret = do_req_filebacked(lo, cmd->rq); | 1678 | ret = do_req_filebacked(lo, cmd->rq); |
| 1497 | failed: | 1679 | failed: |
| 1498 | blk_mq_complete_request(cmd->rq, ret ? -EIO : 0); | 1680 | /* complete non-aio request */ |
| 1681 | if (!cmd->use_aio || ret) | ||
| 1682 | blk_mq_complete_request(cmd->rq, ret ? -EIO : 0); | ||
| 1499 | } | 1683 | } |
| 1500 | 1684 | ||
| 1501 | static void loop_queue_write_work(struct work_struct *work) | 1685 | static void loop_queue_work(struct kthread_work *work) |
| 1502 | { | ||
| 1503 | struct loop_device *lo = | ||
| 1504 | container_of(work, struct loop_device, write_work); | ||
| 1505 | LIST_HEAD(cmd_list); | ||
| 1506 | |||
| 1507 | spin_lock_irq(&lo->lo_lock); | ||
| 1508 | repeat: | ||
| 1509 | list_splice_init(&lo->write_cmd_head, &cmd_list); | ||
| 1510 | spin_unlock_irq(&lo->lo_lock); | ||
| 1511 | |||
| 1512 | while (!list_empty(&cmd_list)) { | ||
| 1513 | struct loop_cmd *cmd = list_first_entry(&cmd_list, | ||
| 1514 | struct loop_cmd, list); | ||
| 1515 | list_del_init(&cmd->list); | ||
| 1516 | loop_handle_cmd(cmd); | ||
| 1517 | } | ||
| 1518 | |||
| 1519 | spin_lock_irq(&lo->lo_lock); | ||
| 1520 | if (!list_empty(&lo->write_cmd_head)) | ||
| 1521 | goto repeat; | ||
| 1522 | lo->write_started = false; | ||
| 1523 | spin_unlock_irq(&lo->lo_lock); | ||
| 1524 | } | ||
| 1525 | |||
| 1526 | static void loop_queue_read_work(struct work_struct *work) | ||
| 1527 | { | 1686 | { |
| 1528 | struct loop_cmd *cmd = | 1687 | struct loop_cmd *cmd = |
| 1529 | container_of(work, struct loop_cmd, read_work); | 1688 | container_of(work, struct loop_cmd, work); |
| 1530 | 1689 | ||
| 1531 | loop_handle_cmd(cmd); | 1690 | loop_handle_cmd(cmd); |
| 1532 | } | 1691 | } |
| @@ -1538,7 +1697,7 @@ static int loop_init_request(void *data, struct request *rq, · 5 unmodified lines | |||
| 1538 | struct loop_cmd *cmd = blk_mq_rq_to_pdu(rq); | 1697 | struct loop_cmd *cmd = blk_mq_rq_to_pdu(rq); |
| 1539 | 1698 | ||
| 1540 | cmd->rq = rq; | 1699 | cmd->rq = rq; |
| 1541 | INIT_WORK(&cmd->read_work, loop_queue_read_work); | 1700 | init_kthread_work(&cmd->work, loop_queue_work); |
| 1542 | 1701 | ||
| 1543 | return 0; | 1702 | return 0; |
| 1544 | } | 1703 | } |
| @@ -1594,8 +1753,11 @@ static int loop_add(struct loop_device **l, int i) · 49 unmodified lines | |||
| 1594 | } | 1753 | } |
| 1595 | lo->lo_queue->queuedata = lo; | 1754 | lo->lo_queue->queuedata = lo; |
| 1596 | 1755 | ||
| 1597 | INIT_LIST_HEAD(&lo->write_cmd_head); | 1756 | /* |
| 1598 | INIT_WORK(&lo->write_work, loop_queue_write_work); | 1757 | * It doesn't make sense to enable merge because the I/O |
| 1758 | * submitted to backing file is handled page by page. | ||
| 1759 | */ | ||
| 1760 | queue_flag_set_unlocked(QUEUE_FLAG_NOMERGES, lo->lo_queue); | ||
| 1599 | 1761 | ||
| 1600 | disk = lo->lo_disk = alloc_disk(1 << part_shift); | 1762 | disk = lo->lo_disk = alloc_disk(1 << part_shift); |
| 1601 | if (!disk) | 1763 | if (!disk) |
| @@ -14,7 +14,7 @@ · 13 unmodified lines | |||
| 14 | #include <linux/blk-mq.h> | 14 | #include <linux/blk-mq.h> |
| 15 | #include <linux/spinlock.h> | 15 | #include <linux/spinlock.h> |
| 16 | #include <linux/mutex.h> | 16 | #include <linux/mutex.h> |
| 17 | #include <linux/workqueue.h> | 17 | #include <linux/kthread.h> |
| 18 | #include <uapi/linux/loop.h> | 18 | #include <uapi/linux/loop.h> |
| 19 | 19 | ||
| 20 | /* Possible states of device */ | 20 | /* Possible states of device */ |
| @@ -54,12 +54,11 @@ struct loop_device { · 33 unmodified lines | |||
| 54 | gfp_t old_gfp_mask; | 54 | gfp_t old_gfp_mask; |
| 55 | 55 | ||
| 56 | spinlock_t lo_lock; | 56 | spinlock_t lo_lock; |
| 57 | struct workqueue_struct *wq; | ||
| 58 | struct list_head write_cmd_head; | ||
| 59 | struct work_struct write_work; | ||
| 60 | bool write_started; | ||
| 61 | int lo_state; | 57 | int lo_state; |
| 62 | struct mutex lo_ctl_mutex; | 58 | struct mutex lo_ctl_mutex; |
| 59 | struct kthread_worker worker; | ||
| 60 | struct task_struct *worker_task; | ||
| 61 | bool use_dio; | ||
| 63 | 62 | ||
| 64 | struct request_queue *lo_queue; | 63 | struct request_queue *lo_queue; |
| 65 | struct blk_mq_tag_set tag_set; | 64 | struct blk_mq_tag_set tag_set; |
| @@ -67,9 +66,11 @@ struct loop_device { · 1 unmodified line | |||
| 67 | }; | 66 | }; |
| 68 | 67 | ||
| 69 | struct loop_cmd { | 68 | struct loop_cmd { |
| 70 | struct work_struct read_work; | 69 | struct kthread_work work; |
| 71 | struct request *rq; | 70 | struct request *rq; |
| 72 | struct list_head list; | 71 | struct list_head list; |
| 72 | bool use_aio; /* use AIO interface to handle I/O */ | ||
| 73 | struct kiocb iocb; | ||
| 73 | }; | 74 | }; |
| 74 | 75 | ||
| 75 | /* Support for loadable transfer modules */ | 76 | /* Support for loadable transfer modules */ |
| @@ -885,6 +885,7 @@ static int cdrom_is_dvd_rw(struct cdrom_device_info *cdi) · 884 unmodified lines | |||
| 885 | switch (cdi->mmc3_profile) { | 885 | switch (cdi->mmc3_profile) { |
| 886 | case 0x12: /* DVD-RAM */ | 886 | case 0x12: /* DVD-RAM */ |
| 887 | case 0x1A: /* DVD+RW */ | 887 | case 0x1A: /* DVD+RW */ |
| 888 | case 0x43: /* BD-RE */ | ||
| 888 | return 0; | 889 | return 0; |
| 889 | default: | 890 | default: |
| 890 | return 1; | 891 | return 1; |
| @@ -0,0 +1 @@ | |||
| 1 | source "drivers/nvme/host/Kconfig" | ||
| @@ -0,0 +1,2 @@ | |||
| 1 | |||
| 2 | obj-y += host/ | ||
| @@ -0,0 +1,10 @@ | |||
| 1 | config BLK_DEV_NVME | ||
| 2 | tristate "NVM Express block device" | ||
| 3 | depends on PCI && BLOCK | ||
| 4 | ---help--- | ||
| 5 | The NVM Express driver is for solid state drives directly | ||
| 6 | connected to the PCI or PCI Express bus. If you know you | ||
| 7 | don't have one of these, it is safe to answer N. | ||
| 8 | |||
| 9 | To compile this driver as a module, choose M here: the | ||
| 10 | module will be called nvme. | ||
| @@ -0,0 +1,4 @@ | |||
| 1 | |||
| 2 | obj-$(CONFIG_BLK_DEV_NVME) += nvme.o | ||
| 3 | |||
| 4 | nvme-y += pci.o scsi.o | ||
| @@ -0,0 +1,133 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2011-2014, Intel Corporation. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms and conditions of the GNU General Public License, | ||
| 6 | * version 2, as published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 11 | * more details. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #ifndef _NVME_H | ||
| 15 | #define _NVME_H | ||
| 16 | |||
| 17 | #include <linux/nvme.h> | ||
| 18 | #include <linux/pci.h> | ||
| 19 | #include <linux/kref.h> | ||
| 20 | #include <linux/blk-mq.h> | ||
| 21 | |||
| 22 | extern unsigned char nvme_io_timeout; | ||
| 23 | #define NVME_IO_TIMEOUT (nvme_io_timeout * HZ) | ||
| 24 | |||
| 25 | /* | ||
| 26 | * Represents an NVM Express device. Each nvme_dev is a PCI function. | ||
| 27 | */ | ||
| 28 | struct nvme_dev { | ||
| 29 | struct list_head node; | ||
| 30 | struct nvme_queue **queues; | ||
| 31 | struct request_queue *admin_q; | ||
| 32 | struct blk_mq_tag_set tagset; | ||
| 33 | struct blk_mq_tag_set admin_tagset; | ||
| 34 | u32 __iomem *dbs; | ||
| 35 | struct device *dev; | ||
| 36 | struct dma_pool *prp_page_pool; | ||
| 37 | struct dma_pool *prp_small_pool; | ||
| 38 | int instance; | ||
| 39 | unsigned queue_count; | ||
| 40 | unsigned online_queues; | ||
| 41 | unsigned max_qid; | ||
| 42 | int q_depth; | ||
| 43 | u32 db_stride; | ||
| 44 | u32 ctrl_config; | ||
| 45 | struct msix_entry *entry; | ||
| 46 | struct nvme_bar __iomem *bar; | ||
| 47 | struct list_head namespaces; | ||
| 48 | struct kref kref; | ||
| 49 | struct device *device; | ||
| 50 | struct work_struct reset_work; | ||
| 51 | struct work_struct probe_work; | ||
| 52 | struct work_struct scan_work; | ||
| 53 | char name[12]; | ||
| 54 | char serial[20]; | ||
| 55 | char model[40]; | ||
| 56 | char firmware_rev[8]; | ||
| 57 | bool subsystem; | ||
| 58 | u32 max_hw_sectors; | ||
| 59 | u32 stripe_size; | ||
| 60 | u32 page_size; | ||
| 61 | void __iomem *cmb; | ||
| 62 | dma_addr_t cmb_dma_addr; | ||
| 63 | u64 cmb_size; | ||
| 64 | u32 cmbsz; | ||
| 65 | u16 oncs; | ||
| 66 | u16 abort_limit; | ||
| 67 | u8 event_limit; | ||
| 68 | u8 vwc; | ||
| 69 | }; | ||
| 70 | |||
| 71 | /* | ||
| 72 | * An NVM Express namespace is equivalent to a SCSI LUN | ||
| 73 | */ | ||
| 74 | struct nvme_ns { | ||
| 75 | struct list_head list; | ||
| 76 | |||
| 77 | struct nvme_dev *dev; | ||
| 78 | struct request_queue *queue; | ||
| 79 | struct gendisk *disk; | ||
| 80 | struct kref kref; | ||
| 81 | |||
| 82 | unsigned ns_id; | ||
| 83 | int lba_shift; | ||
| 84 | u16 ms; | ||
| 85 | bool ext; | ||
| 86 | u8 pi_type; | ||
| 87 | u64 mode_select_num_blocks; | ||
| 88 | u32 mode_select_block_len; | ||
| 89 | }; | ||
| 90 | |||
| 91 | /* | ||
| 92 | * The nvme_iod describes the data in an I/O, including the list of PRP | ||
| 93 | * entries. You can't see it in this data structure because C doesn't let | ||
| 94 | * me express that. Use nvme_alloc_iod to ensure there's enough space | ||
| 95 | * allocated to store the PRP list. | ||
| 96 | */ | ||
| 97 | struct nvme_iod { | ||
| 98 | unsigned long private; /* For the use of the submitter of the I/O */ | ||
| 99 | int npages; /* In the PRP list. 0 means small pool in use */ | ||
| 100 | int offset; /* Of PRP list */ | ||
| 101 | int nents; /* Used in scatterlist */ | ||
| 102 | int length; /* Of data, in bytes */ | ||
| 103 | dma_addr_t first_dma; | ||
| 104 | struct scatterlist meta_sg[1]; /* metadata requires single contiguous buffer */ | ||
| 105 | struct scatterlist sg[0]; | ||
| 106 | }; | ||
| 107 | |||
| 108 | static inline u64 nvme_block_nr(struct nvme_ns *ns, sector_t sector) | ||
| 109 | { | ||
| 110 | return (sector >> (ns->lba_shift - 9)); | ||
| 111 | } | ||
| 112 | |||
| 113 | int nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd, | ||
| 114 | void *buf, unsigned bufflen); | ||
| 115 | int __nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd, | ||
| 116 | void *buffer, void __user *ubuffer, unsigned bufflen, | ||
| 117 | u32 *result, unsigned timeout); | ||
| 118 | int nvme_identify_ctrl(struct nvme_dev *dev, struct nvme_id_ctrl **id); | ||
| 119 | int nvme_identify_ns(struct nvme_dev *dev, unsigned nsid, | ||
| 120 | struct nvme_id_ns **id); | ||
| 121 | int nvme_get_log_page(struct nvme_dev *dev, struct nvme_smart_log **log); | ||
| 122 | int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid, | ||
| 123 | dma_addr_t dma_addr, u32 *result); | ||
| 124 | int nvme_set_features(struct nvme_dev *dev, unsigned fid, unsigned dword11, | ||
| 125 | dma_addr_t dma_addr, u32 *result); | ||
| 126 | |||
| 127 | struct sg_io_hdr; | ||
| 128 | |||
| 129 | int nvme_sg_io(struct nvme_ns *ns, struct sg_io_hdr __user *u_hdr); | ||
| 130 | int nvme_sg_io32(struct nvme_ns *ns, unsigned long arg); | ||
| 131 | int nvme_sg_get_version_num(int __user *ip); | ||
| 132 | |||
| 133 | #endif /* _NVME_H */ | ||
| @@ -12,7 +12,6 @@ · 11 unmodified lines | |||
| 12 | * more details. | 12 | * more details. |
| 13 | */ | 13 | */ |
| 14 | 14 | ||
| 15 | #include <linux/nvme.h> | ||
| 16 | #include <linux/bitops.h> | 15 | #include <linux/bitops.h> |
| 17 | #include <linux/blkdev.h> | 16 | #include <linux/blkdev.h> |
| 18 | #include <linux/blk-mq.h> | 17 | #include <linux/blk-mq.h> |
| @@ -43,6 +42,9 @@ · 24 unmodified lines | |||
| 43 | #include <scsi/sg.h> | 42 | #include <scsi/sg.h> |
| 44 | #include <asm-generic/io-64-nonatomic-lo-hi.h> | 43 | #include <asm-generic/io-64-nonatomic-lo-hi.h> |
| 45 | 44 | ||
| 45 | #include <uapi/linux/nvme_ioctl.h> | ||
| 46 | #include "nvme.h" | ||
| 47 | |||
| 46 | #define NVME_MINORS (1U << MINORBITS) | 48 | #define NVME_MINORS (1U << MINORBITS) |
| 47 | #define NVME_Q_DEPTH 1024 | 49 | #define NVME_Q_DEPTH 1024 |
| 48 | #define NVME_AQ_DEPTH 256 | 50 | #define NVME_AQ_DEPTH 256 |
| @@ -84,9 +86,10 @@ static wait_queue_head_t nvme_kthread_wait; · 35 unmodified lines | |||
| 84 | 86 | ||
| 85 | static struct class *nvme_class; | 87 | static struct class *nvme_class; |
| 86 | 88 | ||
| 87 | static void nvme_reset_failed_dev(struct work_struct *ws); | 89 | static int __nvme_reset(struct nvme_dev *dev); |
| 88 | static int nvme_reset(struct nvme_dev *dev); | 90 | static int nvme_reset(struct nvme_dev *dev); |
| 89 | static int nvme_process_cq(struct nvme_queue *nvmeq); | 91 | static int nvme_process_cq(struct nvme_queue *nvmeq); |
| 92 | static void nvme_dead_ctrl(struct nvme_dev *dev); | ||
| 90 | 93 | ||
| 91 | struct async_cmd_info { | 94 | struct async_cmd_info { |
| 92 | struct kthread_work work; | 95 | struct kthread_work work; |
| @@ -1283,18 +1286,13 @@ static void nvme_abort_req(struct request *req) · 1190 unmodified lines | |||
| 1283 | struct nvme_command cmd; | 1286 | struct nvme_command cmd; |
| 1284 | 1287 | ||
| 1285 | if (!nvmeq->qid || cmd_rq->aborted) { | 1288 | if (!nvmeq->qid || cmd_rq->aborted) { |
| 1286 | unsigned long flags; | 1289 | spin_lock(&dev_list_lock); |
| 1287 | 1290 | if (!__nvme_reset(dev)) { | |
| 1288 | spin_lock_irqsave(&dev_list_lock, flags); | 1291 | dev_warn(dev->dev, |
| 1289 | if (work_busy(&dev->reset_work)) | 1292 | "I/O %d QID %d timeout, reset controller\n", |
| 1290 | goto out; | 1293 | req->tag, nvmeq->qid); |
| 1291 | list_del_init(&dev->node); | 1294 | } |
| 1292 | dev_warn(dev->dev, "I/O %d QID %d timeout, reset controller\n", | 1295 | spin_unlock(&dev_list_lock); |
| 1293 | req->tag, nvmeq->qid); | ||
| 1294 | dev->reset_workfn = nvme_reset_failed_dev; | ||
| 1295 | queue_work(nvme_workq, &dev->reset_work); | ||
| 1296 | out: | ||
| 1297 | spin_unlock_irqrestore(&dev_list_lock, flags); | ||
| 1298 | return; | 1296 | return; |
| 1299 | } | 1297 | } |
| 1300 | 1298 | ||
| @@ -1949,6 +1947,20 @@ static int nvme_compat_ioctl(struct block_device *bdev, fmode_t mode, · 648 unmodified lines | |||
| 1949 | #define nvme_compat_ioctl NULL | 1947 | #define nvme_compat_ioctl NULL |
| 1950 | #endif | 1948 | #endif |
| 1951 | 1949 | ||
| 1950 | static void nvme_free_dev(struct kref *kref); | ||
| 1951 | static void nvme_free_ns(struct kref *kref) | ||
| 1952 | { | ||
| 1953 | struct nvme_ns *ns = container_of(kref, struct nvme_ns, kref); | ||
| 1954 | |||
| 1955 | spin_lock(&dev_list_lock); | ||
| 1956 | ns->disk->private_data = NULL; | ||
| 1957 | spin_unlock(&dev_list_lock); | ||
| 1958 | |||
| 1959 | kref_put(&ns->dev->kref, nvme_free_dev); | ||
| 1960 | put_disk(ns->disk); | ||
| 1961 | kfree(ns); | ||
| 1962 | } | ||
| 1963 | |||
| 1952 | static int nvme_open(struct block_device *bdev, fmode_t mode) | 1964 | static int nvme_open(struct block_device *bdev, fmode_t mode) |
| 1953 | { | 1965 | { |
| 1954 | int ret = 0; | 1966 | int ret = 0; |
| @@ -1958,21 +1970,17 @@ static int nvme_open(struct block_device *bdev, fmode_t mode) · 3 unmodified lines | |||
| 1958 | ns = bdev->bd_disk->private_data; | 1970 | ns = bdev->bd_disk->private_data; |
| 1959 | if (!ns) | 1971 | if (!ns) |
| 1960 | ret = -ENXIO; | 1972 | ret = -ENXIO; |
| 1961 | else if (!kref_get_unless_zero(&ns->dev->kref)) | 1973 | else if (!kref_get_unless_zero(&ns->kref)) |
| 1962 | ret = -ENXIO; | 1974 | ret = -ENXIO; |
| 1963 | spin_unlock(&dev_list_lock); | 1975 | spin_unlock(&dev_list_lock); |
| 1964 | 1976 | ||
| 1965 | return ret; | 1977 | return ret; |
| 1966 | } | 1978 | } |
| 1967 | 1979 | ||
| 1968 | static void nvme_free_dev(struct kref *kref); | ||
| 1969 | |||
| 1970 | static void nvme_release(struct gendisk *disk, fmode_t mode) | 1980 | static void nvme_release(struct gendisk *disk, fmode_t mode) |
| 1971 | { | 1981 | { |
| 1972 | struct nvme_ns *ns = disk->private_data; | 1982 | struct nvme_ns *ns = disk->private_data; |
| 1973 | struct nvme_dev *dev = ns->dev; | 1983 | kref_put(&ns->kref, nvme_free_ns); |
| 1974 | |||
| 1975 | kref_put(&dev->kref, nvme_free_dev); | ||
| 1976 | } | 1984 | } |
| 1977 | 1985 | ||
| 1978 | static int nvme_getgeo(struct block_device *bd, struct hd_geometry *geo) | 1986 | static int nvme_getgeo(struct block_device *bd, struct hd_geometry *geo) |
| @@ -2079,14 +2087,11 @@ static int nvme_kthread(void *data) · 100 unmodified lines | |||
| 2079 | 2087 | ||
| 2080 | if ((dev->subsystem && (csts & NVME_CSTS_NSSRO)) || | 2088 | if ((dev->subsystem && (csts & NVME_CSTS_NSSRO)) || |
| 2081 | csts & NVME_CSTS_CFS) { | 2089 | csts & NVME_CSTS_CFS) { |
| 2082 | if (work_busy(&dev->reset_work)) | 2090 | if (!__nvme_reset(dev)) { |
| 2083 | continue; | 2091 | dev_warn(dev->dev, |
| 2084 | list_del_init(&dev->node); | 2092 | "Failed status: %x, reset controller\n", |
| 2085 | dev_warn(dev->dev, | 2093 | readl(&dev->bar->csts)); |
| 2086 | "Failed status: %x, reset controller\n", | 2094 | } |
| 2087 | readl(&dev->bar->csts)); | ||
| 2088 | dev->reset_workfn = nvme_reset_failed_dev; | ||
| 2089 | queue_work(nvme_workq, &dev->reset_work); | ||
| 2090 | continue; | 2095 | continue; |
| 2091 | } | 2096 | } |
| 2092 | for (i = 0; i < dev->queue_count; i++) { | 2097 | for (i = 0; i < dev->queue_count; i++) { |
| @@ -2132,6 +2137,7 @@ static void nvme_alloc_ns(struct nvme_dev *dev, unsigned nsid) · 39 unmodified lines | |||
| 2132 | if (!disk) | 2137 | if (!disk) |
| 2133 | goto out_free_queue; | 2138 | goto out_free_queue; |
| 2134 | 2139 | ||
| 2140 | kref_init(&ns->kref); | ||
| 2135 | ns->ns_id = nsid; | 2141 | ns->ns_id = nsid; |
| 2136 | ns->disk = disk; | 2142 | ns->disk = disk; |
| 2137 | ns->lba_shift = 9; /* set to a default value for 512 until disk is validated */ | 2143 | ns->lba_shift = 9; /* set to a default value for 512 until disk is validated */ |
| @@ -2168,6 +2174,7 @@ static void nvme_alloc_ns(struct nvme_dev *dev, unsigned nsid) · 30 unmodified lines | |||
| 2168 | if (nvme_revalidate_disk(ns->disk)) | 2174 | if (nvme_revalidate_disk(ns->disk)) |
| 2169 | goto out_free_disk; | 2175 | goto out_free_disk; |
| 2170 | 2176 | ||
| 2177 | kref_get(&dev->kref); | ||
| 2171 | add_disk(ns->disk); | 2178 | add_disk(ns->disk); |
| 2172 | if (ns->ms) { | 2179 | if (ns->ms) { |
| 2173 | struct block_device *bd = bdget_disk(ns->disk, 0); | 2180 | struct block_device *bd = bdget_disk(ns->disk, 0); |
| @@ -2190,6 +2197,13 @@ static void nvme_alloc_ns(struct nvme_dev *dev, unsigned nsid) · 16 unmodified lines | |||
| 2190 | kfree(ns); | 2197 | kfree(ns); |
| 2191 | } | 2198 | } |
| 2192 | 2199 | ||
| 2200 | /* | ||
| 2201 | * Create I/O queues. Failing to create an I/O queue is not an issue, | ||
| 2202 | * we can continue with less than the desired amount of queues, and | ||
| 2203 | * even a controller without I/O queues an still be used to issue | ||
| 2204 | * admin commands. This might be useful to upgrade a buggy firmware | ||
| 2205 | * for example. | ||
| 2206 | */ | ||
| 2193 | static void nvme_create_io_queues(struct nvme_dev *dev) | 2207 | static void nvme_create_io_queues(struct nvme_dev *dev) |
| 2194 | { | 2208 | { |
| 2195 | unsigned i; | 2209 | unsigned i; |
| @@ -2199,8 +2213,10 @@ static void nvme_create_io_queues(struct nvme_dev *dev) · 3 unmodified lines | |||
| 2199 | break; | 2213 | break; |
| 2200 | 2214 | ||
| 2201 | for (i = dev->online_queues; i <= dev->queue_count - 1; i++) | 2215 | for (i = dev->online_queues; i <= dev->queue_count - 1; i++) |
| 2202 | if (nvme_create_queue(dev->queues[i], i)) | 2216 | if (nvme_create_queue(dev->queues[i], i)) { |
| 2217 | nvme_free_queues(dev, i); | ||
| 2203 | break; | 2218 | break; |
| 2219 | } | ||
| 2204 | } | 2220 | } |
| 2205 | 2221 | ||
| 2206 | static int set_queue_count(struct nvme_dev *dev, int count) | 2222 | static int set_queue_count(struct nvme_dev *dev, int count) |
| @@ -2363,18 +2379,6 @@ static int nvme_setup_io_queues(struct nvme_dev *dev) · 156 unmodified lines | |||
| 2363 | return result; | 2379 | return result; |
| 2364 | } | 2380 | } |
| 2365 | 2381 | ||
| 2366 | static void nvme_free_namespace(struct nvme_ns *ns) | ||
| 2367 | { | ||
| 2368 | list_del(&ns->list); | ||
| 2369 | |||
| 2370 | spin_lock(&dev_list_lock); | ||
| 2371 | ns->disk->private_data = NULL; | ||
| 2372 | spin_unlock(&dev_list_lock); | ||
| 2373 | |||
| 2374 | put_disk(ns->disk); | ||
| 2375 | kfree(ns); | ||
| 2376 | } | ||
| 2377 | |||
| 2378 | static int ns_cmp(void *priv, struct list_head *a, struct list_head *b) | 2382 | static int ns_cmp(void *priv, struct list_head *a, struct list_head *b) |
| 2379 | { | 2383 | { |
| 2380 | struct nvme_ns *nsa = container_of(a, struct nvme_ns, list); | 2384 | struct nvme_ns *nsa = container_of(a, struct nvme_ns, list); |
| @@ -2416,7 +2420,9 @@ static void nvme_ns_remove(struct nvme_ns *ns) · 35 unmodified lines | |||
| 2416 | if (kill || !blk_queue_dying(ns->queue)) { | 2420 | if (kill || !blk_queue_dying(ns->queue)) { |
| 2417 | blk_mq_abort_requeue_list(ns->queue); | 2421 | blk_mq_abort_requeue_list(ns->queue); |
| 2418 | blk_cleanup_queue(ns->queue); | 2422 | blk_cleanup_queue(ns->queue); |
| 2419 | } | 2423 | } |
| 2424 | list_del_init(&ns->list); | ||
| 2425 | kref_put(&ns->kref, nvme_free_ns); | ||
| 2420 | } | 2426 | } |
| 2421 | 2427 | ||
| 2422 | static void nvme_scan_namespaces(struct nvme_dev *dev, unsigned nn) | 2428 | static void nvme_scan_namespaces(struct nvme_dev *dev, unsigned nn) |
| @@ -2427,18 +2433,14 @@ static void nvme_scan_namespaces(struct nvme_dev *dev, unsigned nn) · 4 unmodified lines | |||
| 2427 | for (i = 1; i <= nn; i++) { | 2433 | for (i = 1; i <= nn; i++) { |
| 2428 | ns = nvme_find_ns(dev, i); | 2434 | ns = nvme_find_ns(dev, i); |
| 2429 | if (ns) { | 2435 | if (ns) { |
| 2430 | if (revalidate_disk(ns->disk)) { | 2436 | if (revalidate_disk(ns->disk)) |
| 2431 | nvme_ns_remove(ns); | 2437 | nvme_ns_remove(ns); |
| 2432 | nvme_free_namespace(ns); | ||
| 2433 | } | ||
| 2434 | } else | 2438 | } else |
| 2435 | nvme_alloc_ns(dev, i); | 2439 | nvme_alloc_ns(dev, i); |
| 2436 | } | 2440 | } |
| 2437 | list_for_each_entry_safe(ns, next, &dev->namespaces, list) { | 2441 | list_for_each_entry_safe(ns, next, &dev->namespaces, list) { |
| 2438 | if (ns->ns_id > nn) { | 2442 | if (ns->ns_id > nn) |
| 2439 | nvme_ns_remove(ns); | 2443 | nvme_ns_remove(ns); |
| 2440 | nvme_free_namespace(ns); | ||
| 2441 | } | ||
| 2442 | } | 2444 | } |
| 2443 | list_sort(NULL, &dev->namespaces, ns_cmp); | 2445 | list_sort(NULL, &dev->namespaces, ns_cmp); |
| 2444 | } | 2446 | } |
| @@ -2828,9 +2830,9 @@ static void nvme_dev_shutdown(struct nvme_dev *dev) · 383 unmodified lines | |||
| 2828 | 2830 | ||
| 2829 | static void nvme_dev_remove(struct nvme_dev *dev) | 2831 | static void nvme_dev_remove(struct nvme_dev *dev) |
| 2830 | { | 2832 | { |
| 2831 | struct nvme_ns *ns; | 2833 | struct nvme_ns *ns, *next; |
| 2832 | 2834 | ||
| 2833 | list_for_each_entry(ns, &dev->namespaces, list) | 2835 | list_for_each_entry_safe(ns, next, &dev->namespaces, list) |
| 2834 | nvme_ns_remove(ns); | 2836 | nvme_ns_remove(ns); |
| 2835 | } | 2837 | } |
| 2836 | 2838 | ||
| @@ -2886,21 +2888,12 @@ static void nvme_release_instance(struct nvme_dev *dev) · 49 unmodified lines | |||
| 2886 | spin_unlock(&dev_list_lock); | 2888 | spin_unlock(&dev_list_lock); |
| 2887 | } | 2889 | } |
| 2888 | 2890 | ||
| 2889 | static void nvme_free_namespaces(struct nvme_dev *dev) | ||
| 2890 | { | ||
| 2891 | struct nvme_ns *ns, *next; | ||
| 2892 | |||
| 2893 | list_for_each_entry_safe(ns, next, &dev->namespaces, list) | ||
| 2894 | nvme_free_namespace(ns); | ||
| 2895 | } | ||
| 2896 | |||
| 2897 | static void nvme_free_dev(struct kref *kref) | 2891 | static void nvme_free_dev(struct kref *kref) |
| 2898 | { | 2892 | { |
| 2899 | struct nvme_dev *dev = container_of(kref, struct nvme_dev, kref); | 2893 | struct nvme_dev *dev = container_of(kref, struct nvme_dev, kref); |
| 2900 | 2894 | ||
| 2901 | put_device(dev->dev); | 2895 | put_device(dev->dev); |
| 2902 | put_device(dev->device); | 2896 | put_device(dev->device); |
| 2903 | nvme_free_namespaces(dev); | ||
| 2904 | nvme_release_instance(dev); | 2897 | nvme_release_instance(dev); |
| 2905 | if (dev->tagset.tags) | 2898 | if (dev->tagset.tags) |
| 2906 | blk_mq_free_tag_set(&dev->tagset); | 2899 | blk_mq_free_tag_set(&dev->tagset); |
| @@ -2974,14 +2967,15 @@ static const struct file_operations nvme_dev_fops = { · 67 unmodified lines | |||
| 2974 | .compat_ioctl = nvme_dev_ioctl, | 2967 | .compat_ioctl = nvme_dev_ioctl, |
| 2975 | }; | 2968 | }; |
| 2976 | 2969 | ||
| 2977 | static int nvme_dev_start(struct nvme_dev *dev) | 2970 | static void nvme_probe_work(struct work_struct *work) |
| 2978 | { | 2971 | { |
| 2979 | int result; | 2972 | struct nvme_dev *dev = container_of(work, struct nvme_dev, probe_work); |
| 2980 | bool start_thread = false; | 2973 | bool start_thread = false; |
| 2974 | int result; | ||
| 2981 | 2975 | ||
| 2982 | result = nvme_dev_map(dev); | 2976 | result = nvme_dev_map(dev); |
| 2983 | if (result) | 2977 | if (result) |
| 2984 | return result; | 2978 | goto out; |
| 2985 | 2979 | ||
| 2986 | result = nvme_configure_admin_queue(dev); | 2980 | result = nvme_configure_admin_queue(dev); |
| 2987 | if (result) | 2981 | if (result) |
| @@ -3016,7 +3010,20 @@ static int nvme_dev_start(struct nvme_dev *dev) · 28 unmodified lines | |||
| 3016 | goto free_tags; | 3010 | goto free_tags; |
| 3017 | 3011 | ||
| 3018 | dev->event_limit = 1; | 3012 | dev->event_limit = 1; |
| 3019 | return result; | 3013 | |
| 3014 | /* | ||
| 3015 | * Keep the controller around but remove all namespaces if we don't have | ||
| 3016 | * any working I/O queue. | ||
| 3017 | */ | ||
| 3018 | if (dev->online_queues < 2) { | ||
| 3019 | dev_warn(dev->dev, "IO queues not created\n"); | ||
| 3020 | nvme_dev_remove(dev); | ||
| 3021 | } else { | ||
| 3022 | nvme_unfreeze_queues(dev); | ||
| 3023 | nvme_dev_add(dev); | ||
| 3024 | } | ||
| 3025 | |||
| 3026 | return; | ||
| 3020 | 3027 | ||
| 3021 | free_tags: | 3028 | free_tags: |
| 3022 | nvme_dev_remove_admin(dev); | 3029 | nvme_dev_remove_admin(dev); |
| @@ -3028,7 +3035,9 @@ static int nvme_dev_start(struct nvme_dev *dev) · 5 unmodified lines | |||
| 3028 | nvme_dev_list_remove(dev); | 3035 | nvme_dev_list_remove(dev); |
| 3029 | unmap: | 3036 | unmap: |
| 3030 | nvme_dev_unmap(dev); | 3037 | nvme_dev_unmap(dev); |
| 3031 | return result; | 3038 | out: |
| 3039 | if (!work_busy(&dev->reset_work)) | ||
| 3040 | nvme_dead_ctrl(dev); | ||
| 3032 | } | 3041 | } |
| 3033 | 3042 | ||
| 3034 | static int nvme_remove_dead_ctrl(void *arg) | 3043 | static int nvme_remove_dead_ctrl(void *arg) |
| @@ -3042,33 +3051,6 @@ static int nvme_remove_dead_ctrl(void *arg) · 7 unmodified lines | |||
| 3042 | return 0; | 3051 | return 0; |
| 3043 | } | 3052 | } |
| 3044 | 3053 | ||
| 3045 | static void nvme_remove_disks(struct work_struct *ws) | ||
| 3046 | { | ||
| 3047 | struct nvme_dev *dev = container_of(ws, struct nvme_dev, reset_work); | ||
| 3048 | |||
| 3049 | nvme_free_queues(dev, 1); | ||
| 3050 | nvme_dev_remove(dev); | ||
| 3051 | } | ||
| 3052 | |||
| 3053 | static int nvme_dev_resume(struct nvme_dev *dev) | ||
| 3054 | { | ||
| 3055 | int ret; | ||
| 3056 | |||
| 3057 | ret = nvme_dev_start(dev); | ||
| 3058 | if (ret) | ||
| 3059 | return ret; | ||
| 3060 | if (dev->online_queues < 2) { | ||
| 3061 | spin_lock(&dev_list_lock); | ||
| 3062 | dev->reset_workfn = nvme_remove_disks; | ||
| 3063 | queue_work(nvme_workq, &dev->reset_work); | ||
| 3064 | spin_unlock(&dev_list_lock); | ||
| 3065 | } else { | ||
| 3066 | nvme_unfreeze_queues(dev); | ||
| 3067 | nvme_dev_add(dev); | ||
| 3068 | } | ||
| 3069 | return 0; | ||
| 3070 | } | ||
| 3071 | |||
| 3072 | static void nvme_dead_ctrl(struct nvme_dev *dev) | 3054 | static void nvme_dead_ctrl(struct nvme_dev *dev) |
| 3073 | { | 3055 | { |
| 3074 | dev_warn(dev->dev, "Device failed to resume\n"); | 3056 | dev_warn(dev->dev, "Device failed to resume\n"); |
| @@ -3081,8 +3063,9 @@ static void nvme_dead_ctrl(struct nvme_dev *dev) · 6 unmodified lines | |||
| 3081 | } | 3063 | } |
| 3082 | } | 3064 | } |
| 3083 | 3065 | ||
| 3084 | static void nvme_dev_reset(struct nvme_dev *dev) | 3066 | static void nvme_reset_work(struct work_struct *ws) |
| 3085 | { | 3067 | { |
| 3068 | struct nvme_dev *dev = container_of(ws, struct nvme_dev, reset_work); | ||
| 3086 | bool in_probe = work_busy(&dev->probe_work); | 3069 | bool in_probe = work_busy(&dev->probe_work); |
| 3087 | 3070 | ||
| 3088 | nvme_dev_shutdown(dev); | 3071 | nvme_dev_shutdown(dev); |
| @@ -3102,31 +3085,24 @@ static void nvme_dev_reset(struct nvme_dev *dev) · 13 unmodified lines | |||
| 3102 | schedule_work(&dev->probe_work); | 3085 | schedule_work(&dev->probe_work); |
| 3103 | } | 3086 | } |
| 3104 | 3087 | ||
| 3105 | static void nvme_reset_failed_dev(struct work_struct *ws) | 3088 | static int __nvme_reset(struct nvme_dev *dev) |
| 3106 | { | ||
| 3107 | struct nvme_dev *dev = container_of(ws, struct nvme_dev, reset_work); | ||
| 3108 | nvme_dev_reset(dev); | ||
| 3109 | } | ||
| 3110 | |||
| 3111 | static void nvme_reset_workfn(struct work_struct *work) | ||
| 3112 | { | 3089 | { |
| 3113 | struct nvme_dev *dev = container_of(work, struct nvme_dev, reset_work); | 3090 | if (work_pending(&dev->reset_work)) |
| 3114 | dev->reset_workfn(work); | 3091 | return -EBUSY; |
| 3092 | list_del_init(&dev->node); | ||
| 3093 | queue_work(nvme_workq, &dev->reset_work); | ||
| 3094 | return 0; | ||
| 3115 | } | 3095 | } |
| 3116 | 3096 | ||
| 3117 | static int nvme_reset(struct nvme_dev *dev) | 3097 | static int nvme_reset(struct nvme_dev *dev) |
| 3118 | { | 3098 | { |
| 3119 | int ret = -EBUSY; | 3099 | int ret; |
| 3120 | 3100 | ||
| 3121 | if (!dev->admin_q || blk_queue_dying(dev->admin_q)) | 3101 | if (!dev->admin_q || blk_queue_dying(dev->admin_q)) |
| 3122 | return -ENODEV; | 3102 | return -ENODEV; |
| 3123 | 3103 | ||
| 3124 | spin_lock(&dev_list_lock); | 3104 | spin_lock(&dev_list_lock); |
| 3125 | if (!work_pending(&dev->reset_work)) { | 3105 | ret = __nvme_reset(dev); |
| 3126 | dev->reset_workfn = nvme_reset_failed_dev; | ||
| 3127 | queue_work(nvme_workq, &dev->reset_work); | ||
| 3128 | ret = 0; | ||
| 3129 | } | ||
| 3130 | spin_unlock(&dev_list_lock); | 3106 | spin_unlock(&dev_list_lock); |
| 3131 | 3107 | ||
| 3132 | if (!ret) { | 3108 | if (!ret) { |
| @@ -3153,7 +3129,6 @@ static ssize_t nvme_sysfs_reset(struct device *dev, · 20 unmodified lines | |||
| 3153 | } | 3129 | } |
| 3154 | static DEVICE_ATTR(reset_controller, S_IWUSR, NULL, nvme_sysfs_reset); | 3130 | static DEVICE_ATTR(reset_controller, S_IWUSR, NULL, nvme_sysfs_reset); |
| 3155 | 3131 | ||
| 3156 | static void nvme_async_probe(struct work_struct *work); | ||
| 3157 | static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) | 3132 | static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) |
| 3158 | { | 3133 | { |
| 3159 | int node, result = -ENOMEM; | 3134 | int node, result = -ENOMEM; |
| @@ -3176,8 +3151,7 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 16 unmodified lines | |||
| 3176 | goto free; | 3151 | goto free; |
| 3177 | 3152 | ||
| 3178 | INIT_LIST_HEAD(&dev->namespaces); | 3153 | INIT_LIST_HEAD(&dev->namespaces); |
| 3179 | dev->reset_workfn = nvme_reset_failed_dev; | 3154 | INIT_WORK(&dev->reset_work, nvme_reset_work); |
| 3180 | INIT_WORK(&dev->reset_work, nvme_reset_workfn); | ||
| 3181 | dev->dev = get_device(&pdev->dev); | 3155 | dev->dev = get_device(&pdev->dev); |
| 3182 | pci_set_drvdata(pdev, dev); | 3156 | pci_set_drvdata(pdev, dev); |
| 3183 | result = nvme_set_instance(dev); | 3157 | result = nvme_set_instance(dev); |
| @@ -3205,7 +3179,7 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 21 unmodified lines | |||
| 3205 | 3179 | ||
| 3206 | INIT_LIST_HEAD(&dev->node); | 3180 | INIT_LIST_HEAD(&dev->node); |
| 3207 | INIT_WORK(&dev->scan_work, nvme_dev_scan); | 3181 | INIT_WORK(&dev->scan_work, nvme_dev_scan); |
| 3208 | INIT_WORK(&dev->probe_work, nvme_async_probe); | 3182 | INIT_WORK(&dev->probe_work, nvme_probe_work); |
| 3209 | schedule_work(&dev->probe_work); | 3183 | schedule_work(&dev->probe_work); |
| 3210 | return 0; | 3184 | return 0; |
| 3211 | 3185 | ||
| @@ -3225,14 +3199,6 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 13 unmodified lines | |||
| 3225 | return result; | 3199 | return result; |
| 3226 | } | 3200 | } |
| 3227 | 3201 | ||
| 3228 | static void nvme_async_probe(struct work_struct *work) | ||
| 3229 | { | ||
| 3230 | struct nvme_dev *dev = container_of(work, struct nvme_dev, probe_work); | ||
| 3231 | |||
| 3232 | if (nvme_dev_resume(dev) && !work_busy(&dev->reset_work)) | ||
| 3233 | nvme_dead_ctrl(dev); | ||
| 3234 | } | ||
| 3235 | |||
| 3236 | static void nvme_reset_notify(struct pci_dev *pdev, bool prepare) | 3202 | static void nvme_reset_notify(struct pci_dev *pdev, bool prepare) |
| 3237 | { | 3203 | { |
| 3238 | struct nvme_dev *dev = pci_get_drvdata(pdev); | 3204 | struct nvme_dev *dev = pci_get_drvdata(pdev); |
| @@ -3240,7 +3206,7 @@ static void nvme_reset_notify(struct pci_dev *pdev, bool prepare) · 1 unmodified line | |||
| 3240 | if (prepare) | 3206 | if (prepare) |
| 3241 | nvme_dev_shutdown(dev); | 3207 | nvme_dev_shutdown(dev); |
| 3242 | else | 3208 | else |
| 3243 | nvme_dev_resume(dev); | 3209 | schedule_work(&dev->probe_work); |
| 3244 | } | 3210 | } |
| 3245 | 3211 | ||
| 3246 | static void nvme_shutdown(struct pci_dev *pdev) | 3212 | static void nvme_shutdown(struct pci_dev *pdev) |
| @@ -3294,10 +3260,7 @@ static int nvme_resume(struct device *dev) · 47 unmodified lines | |||
| 3294 | struct pci_dev *pdev = to_pci_dev(dev); | 3260 | struct pci_dev *pdev = to_pci_dev(dev); |
| 3295 | struct nvme_dev *ndev = pci_get_drvdata(pdev); | 3261 | struct nvme_dev *ndev = pci_get_drvdata(pdev); |
| 3296 | 3262 | ||
| 3297 | if (nvme_dev_resume(ndev) && !work_busy(&ndev->reset_work)) { | 3263 | schedule_work(&ndev->probe_work); |
| 3298 | ndev->reset_workfn = nvme_reset_failed_dev; | ||
| 3299 | queue_work(nvme_workq, &ndev->reset_work); | ||
| 3300 | } | ||
| 3301 | return 0; | 3264 | return 0; |
| 3302 | } | 3265 | } |
| 3303 | #endif | 3266 | #endif |
| @@ -17,7 +17,6 @@ · 16 unmodified lines | |||
| 17 | * each command is translated. | 17 | * each command is translated. |
| 18 | */ | 18 | */ |
| 19 | 19 | ||
| 20 | #include <linux/nvme.h> | ||
| 21 | #include <linux/bio.h> | 20 | #include <linux/bio.h> |
| 22 | #include <linux/bitops.h> | 21 | #include <linux/bitops.h> |
| 23 | #include <linux/blkdev.h> | 22 | #include <linux/blkdev.h> |
| @@ -45,6 +44,7 @@ · 21 unmodified lines | |||
| 45 | #include <scsi/sg.h> | 44 | #include <scsi/sg.h> |
| 46 | #include <scsi/scsi.h> | 45 | #include <scsi/scsi.h> |
| 47 | 46 | ||
| 47 | #include "nvme.h" | ||
| 48 | 48 | ||
| 49 | static int sg_version_num = 30534; /* 2 digits for each component */ | 49 | static int sg_version_num = 30534; /* 2 digits for each component */ |
| 50 | 50 | ||
| @@ -15,10 +15,7 @@ · 14 unmodified lines | |||
| 15 | #ifndef _LINUX_NVME_H | 15 | #ifndef _LINUX_NVME_H |
| 16 | #define _LINUX_NVME_H | 16 | #define _LINUX_NVME_H |
| 17 | 17 | ||
| 18 | #include <uapi/linux/nvme.h> | 18 | #include <linux/types.h> |
| 19 | #include <linux/pci.h> | ||
| 20 | #include <linux/kref.h> | ||
| 21 | #include <linux/blk-mq.h> | ||
| 22 | 19 | ||
| 23 | struct nvme_bar { | 20 | struct nvme_bar { |
| 24 | __u64 cap; /* Controller Capabilities */ | 21 | __u64 cap; /* Controller Capabilities */ |
| @@ -76,115 +73,528 @@ enum { · 51 unmodified lines | |||
| 76 | NVME_CSTS_SHST_MASK = 3 << 2, | 73 | NVME_CSTS_SHST_MASK = 3 << 2, |
| 77 | }; | 74 | }; |
| 78 | 75 | ||
| 79 | extern unsigned char nvme_io_timeout; | 76 | struct nvme_id_power_state { |
| 80 | #define NVME_IO_TIMEOUT (nvme_io_timeout * HZ) | 77 | __le16 max_power; /* centiwatts */ |
| 78 | __u8 rsvd2; | ||
| 79 | __u8 flags; | ||
| 80 | __le32 entry_lat; /* microseconds */ | ||
| 81 | __le32 exit_lat; /* microseconds */ | ||
| 82 | __u8 read_tput; | ||
| 83 | __u8 read_lat; | ||
| 84 | __u8 write_tput; | ||
| 85 | __u8 write_lat; | ||
| 86 | __le16 idle_power; | ||
| 87 | __u8 idle_scale; | ||
| 88 | __u8 rsvd19; | ||
| 89 | __le16 active_power; | ||
| 90 | __u8 active_work_scale; | ||
| 91 | __u8 rsvd23[9]; | ||
| 92 | }; | ||
| 81 | 93 | ||
| 82 | /* | 94 | enum { |
| 83 | * Represents an NVM Express device. Each nvme_dev is a PCI function. | 95 | NVME_PS_FLAGS_MAX_POWER_SCALE = 1 << 0, |
| 84 | */ | 96 | NVME_PS_FLAGS_NON_OP_STATE = 1 << 1, |
| 85 | struct nvme_dev { | ||
| 86 | struct list_head node; | ||
| 87 | struct nvme_queue **queues; | ||
| 88 | struct request_queue *admin_q; | ||
| 89 | struct blk_mq_tag_set tagset; | ||
| 90 | struct blk_mq_tag_set admin_tagset; | ||
| 91 | u32 __iomem *dbs; | ||
| 92 | struct device *dev; | ||
| 93 | struct dma_pool *prp_page_pool; | ||
| 94 | struct dma_pool *prp_small_pool; | ||
| 95 | int instance; | ||
| 96 | unsigned queue_count; | ||
| 97 | unsigned online_queues; | ||
| 98 | unsigned max_qid; | ||
| 99 | int q_depth; | ||
| 100 | u32 db_stride; | ||
| 101 | u32 ctrl_config; | ||
| 102 | struct msix_entry *entry; | ||
| 103 | struct nvme_bar __iomem *bar; | ||
| 104 | struct list_head namespaces; | ||
| 105 | struct kref kref; | ||
| 106 | struct device *device; | ||
| 107 | work_func_t reset_workfn; | ||
| 108 | struct work_struct reset_work; | ||
| 109 | struct work_struct probe_work; | ||
| 110 | struct work_struct scan_work; | ||
| 111 | char name[12]; | ||
| 112 | char serial[20]; | ||
| 113 | char model[40]; | ||
| 114 | char firmware_rev[8]; | ||
| 115 | bool subsystem; | ||
| 116 | u32 max_hw_sectors; | ||
| 117 | u32 stripe_size; | ||
| 118 | u32 page_size; | ||
| 119 | void __iomem *cmb; | ||
| 120 | dma_addr_t cmb_dma_addr; | ||
| 121 | u64 cmb_size; | ||
| 122 | u32 cmbsz; | ||
| 123 | u16 oncs; | ||
| 124 | u16 abort_limit; | ||
| 125 | u8 event_limit; | ||
| 126 | u8 vwc; | ||
| 127 | }; | 97 | }; |
| 128 | 98 | ||
| 129 | /* | 99 | struct nvme_id_ctrl { |
| 130 | * An NVM Express namespace is equivalent to a SCSI LUN | 100 | __le16 vid; |
| 131 | */ | 101 | __le16 ssvid; |
| 132 | struct nvme_ns { | 102 | char sn[20]; |
| 133 | struct list_head list; | 103 | char mn[40]; |
| 104 | char fr[8]; | ||
| 105 | __u8 rab; | ||
| 106 | __u8 ieee[3]; | ||
| 107 | __u8 mic; | ||
| 108 | __u8 mdts; | ||
| 109 | __le16 cntlid; | ||
| 110 | __le32 ver; | ||
| 111 | __u8 rsvd84[172]; | ||
| 112 | __le16 oacs; | ||
| 113 | __u8 acl; | ||
| 114 | __u8 aerl; | ||
| 115 | __u8 frmw; | ||
| 116 | __u8 lpa; | ||
| 117 | __u8 elpe; | ||
| 118 | __u8 npss; | ||
| 119 | __u8 avscc; | ||
| 120 | __u8 apsta; | ||
| 121 | __le16 wctemp; | ||
| 122 | __le16 cctemp; | ||
| 123 | __u8 rsvd270[242]; | ||
| 124 | __u8 sqes; | ||
| 125 | __u8 cqes; | ||
| 126 | __u8 rsvd514[2]; | ||
| 127 | __le32 nn; | ||
| 128 | __le16 oncs; | ||
| 129 | __le16 fuses; | ||
| 130 | __u8 fna; | ||
| 131 | __u8 vwc; | ||
| 132 | __le16 awun; | ||
| 133 | __le16 awupf; | ||
| 134 | __u8 nvscc; | ||
| 135 | __u8 rsvd531; | ||
| 136 | __le16 acwu; | ||
| 137 | __u8 rsvd534[2]; | ||
| 138 | __le32 sgls; | ||
| 139 | __u8 rsvd540[1508]; | ||
| 140 | struct nvme_id_power_state psd[32]; | ||
| 141 | __u8 vs[1024]; | ||
| 142 | }; | ||
| 134 | 143 | ||
| 135 | struct nvme_dev *dev; | 144 | enum { |
| 136 | struct request_queue *queue; | 145 | NVME_CTRL_ONCS_COMPARE = 1 << 0, |
| 137 | struct gendisk *disk; | 146 | NVME_CTRL_ONCS_WRITE_UNCORRECTABLE = 1 << 1, |
| 147 | NVME_CTRL_ONCS_DSM = 1 << 2, | ||
| 148 | NVME_CTRL_VWC_PRESENT = 1 << 0, | ||
| 149 | }; | ||
| 138 | 150 | ||
| 139 | unsigned ns_id; | 151 | struct nvme_lbaf { |
| 140 | int lba_shift; | 152 | __le16 ms; |
| 141 | u16 ms; | 153 | __u8 ds; |
| 142 | bool ext; | 154 | __u8 rp; |
| 143 | u8 pi_type; | ||
| 144 | u64 mode_select_num_blocks; | ||
| 145 | u32 mode_select_block_len; | ||
| 146 | }; | 155 | }; |
| 147 | 156 | ||
| 148 | /* | 157 | struct nvme_id_ns { |
| 149 | * The nvme_iod describes the data in an I/O, including the list of PRP | 158 | __le64 nsze; |
| 150 | * entries. You can't see it in this data structure because C doesn't let | 159 | __le64 ncap; |
| 151 | * me express that. Use nvme_alloc_iod to ensure there's enough space | 160 | __le64 nuse; |
| 152 | * allocated to store the PRP list. | 161 | __u8 nsfeat; |
| 153 | */ | 162 | __u8 nlbaf; |
| 154 | struct nvme_iod { | 163 | __u8 flbas; |
| 155 | unsigned long private; /* For the use of the submitter of the I/O */ | 164 | __u8 mc; |
| 156 | int npages; /* In the PRP list. 0 means small pool in use */ | 165 | __u8 dpc; |
| 157 | int offset; /* Of PRP list */ | 166 | __u8 dps; |
| 158 | int nents; /* Used in scatterlist */ | 167 | __u8 nmic; |
| 159 | int length; /* Of data, in bytes */ | 168 | __u8 rescap; |
| 160 | dma_addr_t first_dma; | 169 | __u8 fpi; |
| 161 | struct scatterlist meta_sg[1]; /* metadata requires single contiguous buffer */ | 170 | __u8 rsvd33; |
| 162 | struct scatterlist sg[0]; | 171 | __le16 nawun; |
| 163 | }; | 172 | __le16 nawupf; |
| 164 | 173 | __le16 nacwu; | |
| 165 | static inline u64 nvme_block_nr(struct nvme_ns *ns, sector_t sector) | 174 | __le16 nabsn; |
| 166 | { | 175 | __le16 nabo; |
| 167 | return (sector >> (ns->lba_shift - 9)); | 176 | __le16 nabspf; |
| 168 | } | 177 | __u16 rsvd46; |
| 169 | 178 | __le64 nvmcap[2]; | |
| 170 | int nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd, | 179 | __u8 rsvd64[40]; |
| 171 | void *buf, unsigned bufflen); | 180 | __u8 nguid[16]; |
| 172 | int __nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd, | 181 | __u8 eui64[8]; |
| 173 | void *buffer, void __user *ubuffer, unsigned bufflen, | 182 | struct nvme_lbaf lbaf[16]; |
| 174 | u32 *result, unsigned timeout); | 183 | __u8 rsvd192[192]; |
| 175 | int nvme_identify_ctrl(struct nvme_dev *dev, struct nvme_id_ctrl **id); | 184 | __u8 vs[3712]; |
| 176 | int nvme_identify_ns(struct nvme_dev *dev, unsigned nsid, | 185 | }; |
| 177 | struct nvme_id_ns **id); | 186 | |
| 178 | int nvme_get_log_page(struct nvme_dev *dev, struct nvme_smart_log **log); | 187 | enum { |
| 179 | int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid, | 188 | NVME_NS_FEAT_THIN = 1 << 0, |
| 180 | dma_addr_t dma_addr, u32 *result); | 189 | NVME_NS_FLBAS_LBA_MASK = 0xf, |
| 181 | int nvme_set_features(struct nvme_dev *dev, unsigned fid, unsigned dword11, | 190 | NVME_NS_FLBAS_META_EXT = 0x10, |
| 182 | dma_addr_t dma_addr, u32 *result); | 191 | NVME_LBAF_RP_BEST = 0, |
| 183 | 192 | NVME_LBAF_RP_BETTER = 1, | |
| 184 | struct sg_io_hdr; | 193 | NVME_LBAF_RP_GOOD = 2, |
| 185 | 194 | NVME_LBAF_RP_DEGRADED = 3, | |
| 186 | int nvme_sg_io(struct nvme_ns *ns, struct sg_io_hdr __user *u_hdr); | 195 | NVME_NS_DPC_PI_LAST = 1 << 4, |
| 187 | int nvme_sg_io32(struct nvme_ns *ns, unsigned long arg); | 196 | NVME_NS_DPC_PI_FIRST = 1 << 3, |
| 188 | int nvme_sg_get_version_num(int __user *ip); | 197 | NVME_NS_DPC_PI_TYPE3 = 1 << 2, |
| 198 | NVME_NS_DPC_PI_TYPE2 = 1 << 1, | ||
| 199 | NVME_NS_DPC_PI_TYPE1 = 1 << 0, | ||
| 200 | NVME_NS_DPS_PI_FIRST = 1 << 3, | ||
| 201 | NVME_NS_DPS_PI_MASK = 0x7, | ||
| 202 | NVME_NS_DPS_PI_TYPE1 = 1, | ||
| 203 | NVME_NS_DPS_PI_TYPE2 = 2, | ||
| 204 | NVME_NS_DPS_PI_TYPE3 = 3, | ||
| 205 | }; | ||
| 206 | |||
| 207 | struct nvme_smart_log { | ||
| 208 | __u8 critical_warning; | ||
| 209 | __u8 temperature[2]; | ||
| 210 | __u8 avail_spare; | ||
| 211 | __u8 spare_thresh; | ||
| 212 | __u8 percent_used; | ||
| 213 | __u8 rsvd6[26]; | ||
| 214 | __u8 data_units_read[16]; | ||
| 215 | __u8 data_units_written[16]; | ||
| 216 | __u8 host_reads[16]; | ||
| 217 | __u8 host_writes[16]; | ||
| 218 | __u8 ctrl_busy_time[16]; | ||
| 219 | __u8 power_cycles[16]; | ||
| 220 | __u8 power_on_hours[16]; | ||
| 221 | __u8 unsafe_shutdowns[16]; | ||
| 222 | __u8 media_errors[16]; | ||
| 223 | __u8 num_err_log_entries[16]; | ||
| 224 | __le32 warning_temp_time; | ||
| 225 | __le32 critical_comp_time; | ||
| 226 | __le16 temp_sensor[8]; | ||
| 227 | __u8 rsvd216[296]; | ||
| 228 | }; | ||
| 229 | |||
| 230 | enum { | ||
| 231 | NVME_SMART_CRIT_SPARE = 1 << 0, | ||
| 232 | NVME_SMART_CRIT_TEMPERATURE = 1 << 1, | ||
| 233 | NVME_SMART_CRIT_RELIABILITY = 1 << 2, | ||
| 234 | NVME_SMART_CRIT_MEDIA = 1 << 3, | ||
| 235 | NVME_SMART_CRIT_VOLATILE_MEMORY = 1 << 4, | ||
| 236 | }; | ||
| 237 | |||
| 238 | enum { | ||
| 239 | NVME_AER_NOTICE_NS_CHANGED = 0x0002, | ||
| 240 | }; | ||
| 241 | |||
| 242 | struct nvme_lba_range_type { | ||
| 243 | __u8 type; | ||
| 244 | __u8 attributes; | ||
| 245 | __u8 rsvd2[14]; | ||
| 246 | __u64 slba; | ||
| 247 | __u64 nlb; | ||
| 248 | __u8 guid[16]; | ||
| 249 | __u8 rsvd48[16]; | ||
| 250 | }; | ||
| 251 | |||
| 252 | enum { | ||
| 253 | NVME_LBART_TYPE_FS = 0x01, | ||
| 254 | NVME_LBART_TYPE_RAID = 0x02, | ||
| 255 | NVME_LBART_TYPE_CACHE = 0x03, | ||
| 256 | NVME_LBART_TYPE_SWAP = 0x04, | ||
| 257 | |||
| 258 | NVME_LBART_ATTRIB_TEMP = 1 << 0, | ||
| 259 | NVME_LBART_ATTRIB_HIDE = 1 << 1, | ||
| 260 | }; | ||
| 261 | |||
| 262 | struct nvme_reservation_status { | ||
| 263 | __le32 gen; | ||
| 264 | __u8 rtype; | ||
| 265 | __u8 regctl[2]; | ||
| 266 | __u8 resv5[2]; | ||
| 267 | __u8 ptpls; | ||
| 268 | __u8 resv10[13]; | ||
| 269 | struct { | ||
| 270 | __le16 cntlid; | ||
| 271 | __u8 rcsts; | ||
| 272 | __u8 resv3[5]; | ||
| 273 | __le64 hostid; | ||
| 274 | __le64 rkey; | ||
| 275 | } regctl_ds[]; | ||
| 276 | }; | ||
| 277 | |||
| 278 | /* I/O commands */ | ||
| 279 | |||
| 280 | enum nvme_opcode { | ||
| 281 | nvme_cmd_flush = 0x00, | ||
| 282 | nvme_cmd_write = 0x01, | ||
| 283 | nvme_cmd_read = 0x02, | ||
| 284 | nvme_cmd_write_uncor = 0x04, | ||
| 285 | nvme_cmd_compare = 0x05, | ||
| 286 | nvme_cmd_write_zeroes = 0x08, | ||
| 287 | nvme_cmd_dsm = 0x09, | ||
| 288 | nvme_cmd_resv_register = 0x0d, | ||
| 289 | nvme_cmd_resv_report = 0x0e, | ||
| 290 | nvme_cmd_resv_acquire = 0x11, | ||
| 291 | nvme_cmd_resv_release = 0x15, | ||
| 292 | }; | ||
| 293 | |||
| 294 | struct nvme_common_command { | ||
| 295 | __u8 opcode; | ||
| 296 | __u8 flags; | ||
| 297 | __u16 command_id; | ||
| 298 | __le32 nsid; | ||
| 299 | __le32 cdw2[2]; | ||
| 300 | __le64 metadata; | ||
| 301 | __le64 prp1; | ||
| 302 | __le64 prp2; | ||
| 303 | __le32 cdw10[6]; | ||
| 304 | }; | ||
| 305 | |||
| 306 | struct nvme_rw_command { | ||
| 307 | __u8 opcode; | ||
| 308 | __u8 flags; | ||
| 309 | __u16 command_id; | ||
| 310 | __le32 nsid; | ||
| 311 | __u64 rsvd2; | ||
| 312 | __le64 metadata; | ||
| 313 | __le64 prp1; | ||
| 314 | __le64 prp2; | ||
| 315 | __le64 slba; | ||
| 316 | __le16 length; | ||
| 317 | __le16 control; | ||
| 318 | __le32 dsmgmt; | ||
| 319 | __le32 reftag; | ||
| 320 | __le16 apptag; | ||
| 321 | __le16 appmask; | ||
| 322 | }; | ||
| 323 | |||
| 324 | enum { | ||
| 325 | NVME_RW_LR = 1 << 15, | ||
| 326 | NVME_RW_FUA = 1 << 14, | ||
| 327 | NVME_RW_DSM_FREQ_UNSPEC = 0, | ||
| 328 | NVME_RW_DSM_FREQ_TYPICAL = 1, | ||
| 329 | NVME_RW_DSM_FREQ_RARE = 2, | ||
| 330 | NVME_RW_DSM_FREQ_READS = 3, | ||
| 331 | NVME_RW_DSM_FREQ_WRITES = 4, | ||
| 332 | NVME_RW_DSM_FREQ_RW = 5, | ||
| 333 | NVME_RW_DSM_FREQ_ONCE = 6, | ||
| 334 | NVME_RW_DSM_FREQ_PREFETCH = 7, | ||
| 335 | NVME_RW_DSM_FREQ_TEMP = 8, | ||
| 336 | NVME_RW_DSM_LATENCY_NONE = 0 << 4, | ||
| 337 | NVME_RW_DSM_LATENCY_IDLE = 1 << 4, | ||
| 338 | NVME_RW_DSM_LATENCY_NORM = 2 << 4, | ||
| 339 | NVME_RW_DSM_LATENCY_LOW = 3 << 4, | ||
| 340 | NVME_RW_DSM_SEQ_REQ = 1 << 6, | ||
| 341 | NVME_RW_DSM_COMPRESSED = 1 << 7, | ||
| 342 | NVME_RW_PRINFO_PRCHK_REF = 1 << 10, | ||
| 343 | NVME_RW_PRINFO_PRCHK_APP = 1 << 11, | ||
| 344 | NVME_RW_PRINFO_PRCHK_GUARD = 1 << 12, | ||
| 345 | NVME_RW_PRINFO_PRACT = 1 << 13, | ||
| 346 | }; | ||
| 347 | |||
| 348 | struct nvme_dsm_cmd { | ||
| 349 | __u8 opcode; | ||
| 350 | __u8 flags; | ||
| 351 | __u16 command_id; | ||
| 352 | __le32 nsid; | ||
| 353 | __u64 rsvd2[2]; | ||
| 354 | __le64 prp1; | ||
| 355 | __le64 prp2; | ||
| 356 | __le32 nr; | ||
| 357 | __le32 attributes; | ||
| 358 | __u32 rsvd12[4]; | ||
| 359 | }; | ||
| 360 | |||
| 361 | enum { | ||
| 362 | NVME_DSMGMT_IDR = 1 << 0, | ||
| 363 | NVME_DSMGMT_IDW = 1 << 1, | ||
| 364 | NVME_DSMGMT_AD = 1 << 2, | ||
| 365 | }; | ||
| 366 | |||
| 367 | struct nvme_dsm_range { | ||
| 368 | __le32 cattr; | ||
| 369 | __le32 nlb; | ||
| 370 | __le64 slba; | ||
| 371 | }; | ||
| 372 | |||
| 373 | /* Admin commands */ | ||
| 374 | |||
| 375 | enum nvme_admin_opcode { | ||
| 376 | nvme_admin_delete_sq = 0x00, | ||
| 377 | nvme_admin_create_sq = 0x01, | ||
| 378 | nvme_admin_get_log_page = 0x02, | ||
| 379 | nvme_admin_delete_cq = 0x04, | ||
| 380 | nvme_admin_create_cq = 0x05, | ||
| 381 | nvme_admin_identify = 0x06, | ||
| 382 | nvme_admin_abort_cmd = 0x08, | ||
| 383 | nvme_admin_set_features = 0x09, | ||
| 384 | nvme_admin_get_features = 0x0a, | ||
| 385 | nvme_admin_async_event = 0x0c, | ||
| 386 | nvme_admin_activate_fw = 0x10, | ||
| 387 | nvme_admin_download_fw = 0x11, | ||
| 388 | nvme_admin_format_nvm = 0x80, | ||
| 389 | nvme_admin_security_send = 0x81, | ||
| 390 | nvme_admin_security_recv = 0x82, | ||
| 391 | }; | ||
| 392 | |||
| 393 | enum { | ||
| 394 | NVME_QUEUE_PHYS_CONTIG = (1 << 0), | ||
| 395 | NVME_CQ_IRQ_ENABLED = (1 << 1), | ||
| 396 | NVME_SQ_PRIO_URGENT = (0 << 1), | ||
| 397 | NVME_SQ_PRIO_HIGH = (1 << 1), | ||
| 398 | NVME_SQ_PRIO_MEDIUM = (2 << 1), | ||
| 399 | NVME_SQ_PRIO_LOW = (3 << 1), | ||
| 400 | NVME_FEAT_ARBITRATION = 0x01, | ||
| 401 | NVME_FEAT_POWER_MGMT = 0x02, | ||
| 402 | NVME_FEAT_LBA_RANGE = 0x03, | ||
| 403 | NVME_FEAT_TEMP_THRESH = 0x04, | ||
| 404 | NVME_FEAT_ERR_RECOVERY = 0x05, | ||
| 405 | NVME_FEAT_VOLATILE_WC = 0x06, | ||
| 406 | NVME_FEAT_NUM_QUEUES = 0x07, | ||
| 407 | NVME_FEAT_IRQ_COALESCE = 0x08, | ||
| 408 | NVME_FEAT_IRQ_CONFIG = 0x09, | ||
| 409 | NVME_FEAT_WRITE_ATOMIC = 0x0a, | ||
| 410 | NVME_FEAT_ASYNC_EVENT = 0x0b, | ||
| 411 | NVME_FEAT_AUTO_PST = 0x0c, | ||
| 412 | NVME_FEAT_SW_PROGRESS = 0x80, | ||
| 413 | NVME_FEAT_HOST_ID = 0x81, | ||
| 414 | NVME_FEAT_RESV_MASK = 0x82, | ||
| 415 | NVME_FEAT_RESV_PERSIST = 0x83, | ||
| 416 | NVME_LOG_ERROR = 0x01, | ||
| 417 | NVME_LOG_SMART = 0x02, | ||
| 418 | NVME_LOG_FW_SLOT = 0x03, | ||
| 419 | NVME_LOG_RESERVATION = 0x80, | ||
| 420 | NVME_FWACT_REPL = (0 << 3), | ||
| 421 | NVME_FWACT_REPL_ACTV = (1 << 3), | ||
| 422 | NVME_FWACT_ACTV = (2 << 3), | ||
| 423 | }; | ||
| 424 | |||
| 425 | struct nvme_identify { | ||
| 426 | __u8 opcode; | ||
| 427 | __u8 flags; | ||
| 428 | __u16 command_id; | ||
| 429 | __le32 nsid; | ||
| 430 | __u64 rsvd2[2]; | ||
| 431 | __le64 prp1; | ||
| 432 | __le64 prp2; | ||
| 433 | __le32 cns; | ||
| 434 | __u32 rsvd11[5]; | ||
| 435 | }; | ||
| 436 | |||
| 437 | struct nvme_features { | ||
| 438 | __u8 opcode; | ||
| 439 | __u8 flags; | ||
| 440 | __u16 command_id; | ||
| 441 | __le32 nsid; | ||
| 442 | __u64 rsvd2[2]; | ||
| 443 | __le64 prp1; | ||
| 444 | __le64 prp2; | ||
| 445 | __le32 fid; | ||
| 446 | __le32 dword11; | ||
| 447 | __u32 rsvd12[4]; | ||
| 448 | }; | ||
| 449 | |||
| 450 | struct nvme_create_cq { | ||
| 451 | __u8 opcode; | ||
| 452 | __u8 flags; | ||
| 453 | __u16 command_id; | ||
| 454 | __u32 rsvd1[5]; | ||
| 455 | __le64 prp1; | ||
| 456 | __u64 rsvd8; | ||
| 457 | __le16 cqid; | ||
| 458 | __le16 qsize; | ||
| 459 | __le16 cq_flags; | ||
| 460 | __le16 irq_vector; | ||
| 461 | __u32 rsvd12[4]; | ||
| 462 | }; | ||
| 463 | |||
| 464 | struct nvme_create_sq { | ||
| 465 | __u8 opcode; | ||
| 466 | __u8 flags; | ||
| 467 | __u16 command_id; | ||
| 468 | __u32 rsvd1[5]; | ||
| 469 | __le64 prp1; | ||
| 470 | __u64 rsvd8; | ||
| 471 | __le16 sqid; | ||
| 472 | __le16 qsize; | ||
| 473 | __le16 sq_flags; | ||
| 474 | __le16 cqid; | ||
| 475 | __u32 rsvd12[4]; | ||
| 476 | }; | ||
| 477 | |||
| 478 | struct nvme_delete_queue { | ||
| 479 | __u8 opcode; | ||
| 480 | __u8 flags; | ||
| 481 | __u16 command_id; | ||
| 482 | __u32 rsvd1[9]; | ||
| 483 | __le16 qid; | ||
| 484 | __u16 rsvd10; | ||
| 485 | __u32 rsvd11[5]; | ||
| 486 | }; | ||
| 487 | |||
| 488 | struct nvme_abort_cmd { | ||
| 489 | __u8 opcode; | ||
| 490 | __u8 flags; | ||
| 491 | __u16 command_id; | ||
| 492 | __u32 rsvd1[9]; | ||
| 493 | __le16 sqid; | ||
| 494 | __u16 cid; | ||
| 495 | __u32 rsvd11[5]; | ||
| 496 | }; | ||
| 497 | |||
| 498 | struct nvme_download_firmware { | ||
| 499 | __u8 opcode; | ||
| 500 | __u8 flags; | ||
| 501 | __u16 command_id; | ||
| 502 | __u32 rsvd1[5]; | ||
| 503 | __le64 prp1; | ||
| 504 | __le64 prp2; | ||
| 505 | __le32 numd; | ||
| 506 | __le32 offset; | ||
| 507 | __u32 rsvd12[4]; | ||
| 508 | }; | ||
| 509 | |||
| 510 | struct nvme_format_cmd { | ||
| 511 | __u8 opcode; | ||
| 512 | __u8 flags; | ||
| 513 | __u16 command_id; | ||
| 514 | __le32 nsid; | ||
| 515 | __u64 rsvd2[4]; | ||
| 516 | __le32 cdw10; | ||
| 517 | __u32 rsvd11[5]; | ||
| 518 | }; | ||
| 519 | |||
| 520 | struct nvme_command { | ||
| 521 | union { | ||
| 522 | struct nvme_common_command common; | ||
| 523 | struct nvme_rw_command rw; | ||
| 524 | struct nvme_identify identify; | ||
| 525 | struct nvme_features features; | ||
| 526 | struct nvme_create_cq create_cq; | ||
| 527 | struct nvme_create_sq create_sq; | ||
| 528 | struct nvme_delete_queue delete_queue; | ||
| 529 | struct nvme_download_firmware dlfw; | ||
| 530 | struct nvme_format_cmd format; | ||
| 531 | struct nvme_dsm_cmd dsm; | ||
| 532 | struct nvme_abort_cmd abort; | ||
| 533 | }; | ||
| 534 | }; | ||
| 535 | |||
| 536 | enum { | ||
| 537 | NVME_SC_SUCCESS = 0x0, | ||
| 538 | NVME_SC_INVALID_OPCODE = 0x1, | ||
| 539 | NVME_SC_INVALID_FIELD = 0x2, | ||
| 540 | NVME_SC_CMDID_CONFLICT = 0x3, | ||
| 541 | NVME_SC_DATA_XFER_ERROR = 0x4, | ||
| 542 | NVME_SC_POWER_LOSS = 0x5, | ||
| 543 | NVME_SC_INTERNAL = 0x6, | ||
| 544 | NVME_SC_ABORT_REQ = 0x7, | ||
| 545 | NVME_SC_ABORT_QUEUE = 0x8, | ||
| 546 | NVME_SC_FUSED_FAIL = 0x9, | ||
| 547 | NVME_SC_FUSED_MISSING = 0xa, | ||
| 548 | NVME_SC_INVALID_NS = 0xb, | ||
| 549 | NVME_SC_CMD_SEQ_ERROR = 0xc, | ||
| 550 | NVME_SC_SGL_INVALID_LAST = 0xd, | ||
| 551 | NVME_SC_SGL_INVALID_COUNT = 0xe, | ||
| 552 | NVME_SC_SGL_INVALID_DATA = 0xf, | ||
| 553 | NVME_SC_SGL_INVALID_METADATA = 0x10, | ||
| 554 | NVME_SC_SGL_INVALID_TYPE = 0x11, | ||
| 555 | NVME_SC_LBA_RANGE = 0x80, | ||
| 556 | NVME_SC_CAP_EXCEEDED = 0x81, | ||
| 557 | NVME_SC_NS_NOT_READY = 0x82, | ||
| 558 | NVME_SC_RESERVATION_CONFLICT = 0x83, | ||
| 559 | NVME_SC_CQ_INVALID = 0x100, | ||
| 560 | NVME_SC_QID_INVALID = 0x101, | ||
| 561 | NVME_SC_QUEUE_SIZE = 0x102, | ||
| 562 | NVME_SC_ABORT_LIMIT = 0x103, | ||
| 563 | NVME_SC_ABORT_MISSING = 0x104, | ||
| 564 | NVME_SC_ASYNC_LIMIT = 0x105, | ||
| 565 | NVME_SC_FIRMWARE_SLOT = 0x106, | ||
| 566 | NVME_SC_FIRMWARE_IMAGE = 0x107, | ||
| 567 | NVME_SC_INVALID_VECTOR = 0x108, | ||
| 568 | NVME_SC_INVALID_LOG_PAGE = 0x109, | ||
| 569 | NVME_SC_INVALID_FORMAT = 0x10a, | ||
| 570 | NVME_SC_FIRMWARE_NEEDS_RESET = 0x10b, | ||
| 571 | NVME_SC_INVALID_QUEUE = 0x10c, | ||
| 572 | NVME_SC_FEATURE_NOT_SAVEABLE = 0x10d, | ||
| 573 | NVME_SC_FEATURE_NOT_CHANGEABLE = 0x10e, | ||
| 574 | NVME_SC_FEATURE_NOT_PER_NS = 0x10f, | ||
| 575 | NVME_SC_FW_NEEDS_RESET_SUBSYS = 0x110, | ||
| 576 | NVME_SC_BAD_ATTRIBUTES = 0x180, | ||
| 577 | NVME_SC_INVALID_PI = 0x181, | ||
| 578 | NVME_SC_READ_ONLY = 0x182, | ||
| 579 | NVME_SC_WRITE_FAULT = 0x280, | ||
| 580 | NVME_SC_READ_ERROR = 0x281, | ||
| 581 | NVME_SC_GUARD_CHECK = 0x282, | ||
| 582 | NVME_SC_APPTAG_CHECK = 0x283, | ||
| 583 | NVME_SC_REFTAG_CHECK = 0x284, | ||
| 584 | NVME_SC_COMPARE_FAILED = 0x285, | ||
| 585 | NVME_SC_ACCESS_DENIED = 0x286, | ||
| 586 | NVME_SC_DNR = 0x4000, | ||
| 587 | }; | ||
| 588 | |||
| 589 | struct nvme_completion { | ||
| 590 | __le32 result; /* Used by admin commands to return data */ | ||
| 591 | __u32 rsvd; | ||
| 592 | __le16 sq_head; /* how much of this queue may be reclaimed */ | ||
| 593 | __le16 sq_id; /* submission queue that generated this entry */ | ||
| 594 | __u16 command_id; /* of the command which completed */ | ||
| 595 | __le16 status; /* did the command fail, and if so, why? */ | ||
| 596 | }; | ||
| 597 | |||
| 598 | #define NVME_VS(major, minor) (((major) << 16) | ((minor) << 8)) | ||
| 189 | 599 | ||
| 190 | #endif /* _LINUX_NVME_H */ | 600 | #endif /* _LINUX_NVME_H */ |
| @@ -21,6 +21,7 @@ enum { · 20 unmodified lines | |||
| 21 | LO_FLAGS_READ_ONLY = 1, | 21 | LO_FLAGS_READ_ONLY = 1, |
| 22 | LO_FLAGS_AUTOCLEAR = 4, | 22 | LO_FLAGS_AUTOCLEAR = 4, |
| 23 | LO_FLAGS_PARTSCAN = 8, | 23 | LO_FLAGS_PARTSCAN = 8, |
| 24 | LO_FLAGS_DIRECT_IO = 16, | ||
| 24 | }; | 25 | }; |
| 25 | 26 | ||
| 26 | #include <asm/posix_types.h> /* for __kernel_old_dev_t */ | 27 | #include <asm/posix_types.h> /* for __kernel_old_dev_t */ |
| @@ -86,6 +87,7 @@ struct loop_info64 { · 59 unmodified lines | |||
| 86 | #define LOOP_GET_STATUS64 0x4C05 | 87 | #define LOOP_GET_STATUS64 0x4C05 |
| 87 | #define LOOP_CHANGE_FD 0x4C06 | 88 | #define LOOP_CHANGE_FD 0x4C06 |
| 88 | #define LOOP_SET_CAPACITY 0x4C07 | 89 | #define LOOP_SET_CAPACITY 0x4C07 |
| 90 | #define LOOP_SET_DIRECT_IO 0x4C08 | ||
| 89 | 91 | ||
| 90 | /* /dev/loop-control interface */ | 92 | /* /dev/loop-control interface */ |
| 91 | #define LOOP_CTL_ADD 0x4C80 | 93 | #define LOOP_CTL_ADD 0x4C80 |
| @@ -1,589 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Definitions for the NVM Express interface | ||
| 3 | * Copyright (c) 2011-2014, Intel Corporation. | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms and conditions of the GNU General Public License, | ||
| 7 | * version 2, as published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 12 | * more details. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #ifndef _UAPI_LINUX_NVME_H | ||
| 16 | #define _UAPI_LINUX_NVME_H | ||
| 17 | |||
| 18 | #include <linux/types.h> | ||
| 19 | |||
| 20 | struct nvme_id_power_state { | ||
| 21 | __le16 max_power; /* centiwatts */ | ||
| 22 | __u8 rsvd2; | ||
| 23 | __u8 flags; | ||
| 24 | __le32 entry_lat; /* microseconds */ | ||
| 25 | __le32 exit_lat; /* microseconds */ | ||
| 26 | __u8 read_tput; | ||
| 27 | __u8 read_lat; | ||
| 28 | __u8 write_tput; | ||
| 29 | __u8 write_lat; | ||
| 30 | __le16 idle_power; | ||
| 31 | __u8 idle_scale; | ||
| 32 | __u8 rsvd19; | ||
| 33 | __le16 active_power; | ||
| 34 | __u8 active_work_scale; | ||
| 35 | __u8 rsvd23[9]; | ||
| 36 | }; | ||
| 37 | |||
| 38 | enum { | ||
| 39 | NVME_PS_FLAGS_MAX_POWER_SCALE = 1 << 0, | ||
| 40 | NVME_PS_FLAGS_NON_OP_STATE = 1 << 1, | ||
| 41 | }; | ||
| 42 | |||
| 43 | struct nvme_id_ctrl { | ||
| 44 | __le16 vid; | ||
| 45 | __le16 ssvid; | ||
| 46 | char sn[20]; | ||
| 47 | char mn[40]; | ||
| 48 | char fr[8]; | ||
| 49 | __u8 rab; | ||
| 50 | __u8 ieee[3]; | ||
| 51 | __u8 mic; | ||
| 52 | __u8 mdts; | ||
| 53 | __u16 cntlid; | ||
| 54 | __u32 ver; | ||
| 55 | __u8 rsvd84[172]; | ||
| 56 | __le16 oacs; | ||
| 57 | __u8 acl; | ||
| 58 | __u8 aerl; | ||
| 59 | __u8 frmw; | ||
| 60 | __u8 lpa; | ||
| 61 | __u8 elpe; | ||
| 62 | __u8 npss; | ||
| 63 | __u8 avscc; | ||
| 64 | __u8 apsta; | ||
| 65 | __le16 wctemp; | ||
| 66 | __le16 cctemp; | ||
| 67 | __u8 rsvd270[242]; | ||
| 68 | __u8 sqes; | ||
| 69 | __u8 cqes; | ||
| 70 | __u8 rsvd514[2]; | ||
| 71 | __le32 nn; | ||
| 72 | __le16 oncs; | ||
| 73 | __le16 fuses; | ||
| 74 | __u8 fna; | ||
| 75 | __u8 vwc; | ||
| 76 | __le16 awun; | ||
| 77 | __le16 awupf; | ||
| 78 | __u8 nvscc; | ||
| 79 | __u8 rsvd531; | ||
| 80 | __le16 acwu; | ||
| 81 | __u8 rsvd534[2]; | ||
| 82 | __le32 sgls; | ||
| 83 | __u8 rsvd540[1508]; | ||
| 84 | struct nvme_id_power_state psd[32]; | ||
| 85 | __u8 vs[1024]; | ||
| 86 | }; | ||
| 87 | |||
| 88 | enum { | ||
| 89 | NVME_CTRL_ONCS_COMPARE = 1 << 0, | ||
| 90 | NVME_CTRL_ONCS_WRITE_UNCORRECTABLE = 1 << 1, | ||
| 91 | NVME_CTRL_ONCS_DSM = 1 << 2, | ||
| 92 | NVME_CTRL_VWC_PRESENT = 1 << 0, | ||
| 93 | }; | ||
| 94 | |||
| 95 | struct nvme_lbaf { | ||
| 96 | __le16 ms; | ||
| 97 | __u8 ds; | ||
| 98 | __u8 rp; | ||
| 99 | }; | ||
| 100 | |||
| 101 | struct nvme_id_ns { | ||
| 102 | __le64 nsze; | ||
| 103 | __le64 ncap; | ||
| 104 | __le64 nuse; | ||
| 105 | __u8 nsfeat; | ||
| 106 | __u8 nlbaf; | ||
| 107 | __u8 flbas; | ||
| 108 | __u8 mc; | ||
| 109 | __u8 dpc; | ||
| 110 | __u8 dps; | ||
| 111 | __u8 nmic; | ||
| 112 | __u8 rescap; | ||
| 113 | __u8 fpi; | ||
| 114 | __u8 rsvd33; | ||
| 115 | __le16 nawun; | ||
| 116 | __le16 nawupf; | ||
| 117 | __le16 nacwu; | ||
| 118 | __le16 nabsn; | ||
| 119 | __le16 nabo; | ||
| 120 | __le16 nabspf; | ||
| 121 | __u16 rsvd46; | ||
| 122 | __le64 nvmcap[2]; | ||
| 123 | __u8 rsvd64[40]; | ||
| 124 | __u8 nguid[16]; | ||
| 125 | __u8 eui64[8]; | ||
| 126 | struct nvme_lbaf lbaf[16]; | ||
| 127 | __u8 rsvd192[192]; | ||
| 128 | __u8 vs[3712]; | ||
| 129 | }; | ||
| 130 | |||
| 131 | enum { | ||
| 132 | NVME_NS_FEAT_THIN = 1 << 0, | ||
| 133 | NVME_NS_FLBAS_LBA_MASK = 0xf, | ||
| 134 | NVME_NS_FLBAS_META_EXT = 0x10, | ||
| 135 | NVME_LBAF_RP_BEST = 0, | ||
| 136 | NVME_LBAF_RP_BETTER = 1, | ||
| 137 | NVME_LBAF_RP_GOOD = 2, | ||
| 138 | NVME_LBAF_RP_DEGRADED = 3, | ||
| 139 | NVME_NS_DPC_PI_LAST = 1 << 4, | ||
| 140 | NVME_NS_DPC_PI_FIRST = 1 << 3, | ||
| 141 | NVME_NS_DPC_PI_TYPE3 = 1 << 2, | ||
| 142 | NVME_NS_DPC_PI_TYPE2 = 1 << 1, | ||
| 143 | NVME_NS_DPC_PI_TYPE1 = 1 << 0, | ||
| 144 | NVME_NS_DPS_PI_FIRST = 1 << 3, | ||
| 145 | NVME_NS_DPS_PI_MASK = 0x7, | ||
| 146 | NVME_NS_DPS_PI_TYPE1 = 1, | ||
| 147 | NVME_NS_DPS_PI_TYPE2 = 2, | ||
| 148 | NVME_NS_DPS_PI_TYPE3 = 3, | ||
| 149 | }; | ||
| 150 | |||
| 151 | struct nvme_smart_log { | ||
| 152 | __u8 critical_warning; | ||
| 153 | __u8 temperature[2]; | ||
| 154 | __u8 avail_spare; | ||
| 155 | __u8 spare_thresh; | ||
| 156 | __u8 percent_used; | ||
| 157 | __u8 rsvd6[26]; | ||
| 158 | __u8 data_units_read[16]; | ||
| 159 | __u8 data_units_written[16]; | ||
| 160 | __u8 host_reads[16]; | ||
| 161 | __u8 host_writes[16]; | ||
| 162 | __u8 ctrl_busy_time[16]; | ||
| 163 | __u8 power_cycles[16]; | ||
| 164 | __u8 power_on_hours[16]; | ||
| 165 | __u8 unsafe_shutdowns[16]; | ||
| 166 | __u8 media_errors[16]; | ||
| 167 | __u8 num_err_log_entries[16]; | ||
| 168 | __le32 warning_temp_time; | ||
| 169 | __le32 critical_comp_time; | ||
| 170 | __le16 temp_sensor[8]; | ||
| 171 | __u8 rsvd216[296]; | ||
| 172 | }; | ||
| 173 | |||
| 174 | enum { | ||
| 175 | NVME_SMART_CRIT_SPARE = 1 << 0, | ||
| 176 | NVME_SMART_CRIT_TEMPERATURE = 1 << 1, | ||
| 177 | NVME_SMART_CRIT_RELIABILITY = 1 << 2, | ||
| 178 | NVME_SMART_CRIT_MEDIA = 1 << 3, | ||
| 179 | NVME_SMART_CRIT_VOLATILE_MEMORY = 1 << 4, | ||
| 180 | }; | ||
| 181 | |||
| 182 | enum { | ||
| 183 | NVME_AER_NOTICE_NS_CHANGED = 0x0002, | ||
| 184 | }; | ||
| 185 | |||
| 186 | struct nvme_lba_range_type { | ||
| 187 | __u8 type; | ||
| 188 | __u8 attributes; | ||
| 189 | __u8 rsvd2[14]; | ||
| 190 | __u64 slba; | ||
| 191 | __u64 nlb; | ||
| 192 | __u8 guid[16]; | ||
| 193 | __u8 rsvd48[16]; | ||
| 194 | }; | ||
| 195 | |||
| 196 | enum { | ||
| 197 | NVME_LBART_TYPE_FS = 0x01, | ||
| 198 | NVME_LBART_TYPE_RAID = 0x02, | ||
| 199 | NVME_LBART_TYPE_CACHE = 0x03, | ||
| 200 | NVME_LBART_TYPE_SWAP = 0x04, | ||
| 201 | |||
| 202 | NVME_LBART_ATTRIB_TEMP = 1 << 0, | ||
| 203 | NVME_LBART_ATTRIB_HIDE = 1 << 1, | ||
| 204 | }; | ||
| 205 | |||
| 206 | struct nvme_reservation_status { | ||
| 207 | __le32 gen; | ||
| 208 | __u8 rtype; | ||
| 209 | __u8 regctl[2]; | ||
| 210 | __u8 resv5[2]; | ||
| 211 | __u8 ptpls; | ||
| 212 | __u8 resv10[13]; | ||
| 213 | struct { | ||
| 214 | __le16 cntlid; | ||
| 215 | __u8 rcsts; | ||
| 216 | __u8 resv3[5]; | ||
| 217 | __le64 hostid; | ||
| 218 | __le64 rkey; | ||
| 219 | } regctl_ds[]; | ||
| 220 | }; | ||
| 221 | |||
| 222 | /* I/O commands */ | ||
| 223 | |||
| 224 | enum nvme_opcode { | ||
| 225 | nvme_cmd_flush = 0x00, | ||
| 226 | nvme_cmd_write = 0x01, | ||
| 227 | nvme_cmd_read = 0x02, | ||
| 228 | nvme_cmd_write_uncor = 0x04, | ||
| 229 | nvme_cmd_compare = 0x05, | ||
| 230 | nvme_cmd_write_zeroes = 0x08, | ||
| 231 | nvme_cmd_dsm = 0x09, | ||
| 232 | nvme_cmd_resv_register = 0x0d, | ||
| 233 | nvme_cmd_resv_report = 0x0e, | ||
| 234 | nvme_cmd_resv_acquire = 0x11, | ||
| 235 | nvme_cmd_resv_release = 0x15, | ||
| 236 | }; | ||
| 237 | |||
| 238 | struct nvme_common_command { | ||
| 239 | __u8 opcode; | ||
| 240 | __u8 flags; | ||
| 241 | __u16 command_id; | ||
| 242 | __le32 nsid; | ||
| 243 | __le32 cdw2[2]; | ||
| 244 | __le64 metadata; | ||
| 245 | __le64 prp1; | ||
| 246 | __le64 prp2; | ||
| 247 | __le32 cdw10[6]; | ||
| 248 | }; | ||
| 249 | |||
| 250 | struct nvme_rw_command { | ||
| 251 | __u8 opcode; | ||
| 252 | __u8 flags; | ||
| 253 | __u16 command_id; | ||
| 254 | __le32 nsid; | ||
| 255 | __u64 rsvd2; | ||
| 256 | __le64 metadata; | ||
| 257 | __le64 prp1; | ||
| 258 | __le64 prp2; | ||
| 259 | __le64 slba; | ||
| 260 | __le16 length; | ||
| 261 | __le16 control; | ||
| 262 | __le32 dsmgmt; | ||
| 263 | __le32 reftag; | ||
| 264 | __le16 apptag; | ||
| 265 | __le16 appmask; | ||
| 266 | }; | ||
| 267 | |||
| 268 | enum { | ||
| 269 | NVME_RW_LR = 1 << 15, | ||
| 270 | NVME_RW_FUA = 1 << 14, | ||
| 271 | NVME_RW_DSM_FREQ_UNSPEC = 0, | ||
| 272 | NVME_RW_DSM_FREQ_TYPICAL = 1, | ||
| 273 | NVME_RW_DSM_FREQ_RARE = 2, | ||
| 274 | NVME_RW_DSM_FREQ_READS = 3, | ||
| 275 | NVME_RW_DSM_FREQ_WRITES = 4, | ||
| 276 | NVME_RW_DSM_FREQ_RW = 5, | ||
| 277 | NVME_RW_DSM_FREQ_ONCE = 6, | ||
| 278 | NVME_RW_DSM_FREQ_PREFETCH = 7, | ||
| 279 | NVME_RW_DSM_FREQ_TEMP = 8, | ||
| 280 | NVME_RW_DSM_LATENCY_NONE = 0 << 4, | ||
| 281 | NVME_RW_DSM_LATENCY_IDLE = 1 << 4, | ||
| 282 | NVME_RW_DSM_LATENCY_NORM = 2 << 4, | ||
| 283 | NVME_RW_DSM_LATENCY_LOW = 3 << 4, | ||
| 284 | NVME_RW_DSM_SEQ_REQ = 1 << 6, | ||
| 285 | NVME_RW_DSM_COMPRESSED = 1 << 7, | ||
| 286 | NVME_RW_PRINFO_PRCHK_REF = 1 << 10, | ||
| 287 | NVME_RW_PRINFO_PRCHK_APP = 1 << 11, | ||
| 288 | NVME_RW_PRINFO_PRCHK_GUARD = 1 << 12, | ||
| 289 | NVME_RW_PRINFO_PRACT = 1 << 13, | ||
| 290 | }; | ||
| 291 | |||
| 292 | struct nvme_dsm_cmd { | ||
| 293 | __u8 opcode; | ||
| 294 | __u8 flags; | ||
| 295 | __u16 command_id; | ||
| 296 | __le32 nsid; | ||
| 297 | __u64 rsvd2[2]; | ||
| 298 | __le64 prp1; | ||
| 299 | __le64 prp2; | ||
| 300 | __le32 nr; | ||
| 301 | __le32 attributes; | ||
| 302 | __u32 rsvd12[4]; | ||
| 303 | }; | ||
| 304 | |||
| 305 | enum { | ||
| 306 | NVME_DSMGMT_IDR = 1 << 0, | ||
| 307 | NVME_DSMGMT_IDW = 1 << 1, | ||
| 308 | NVME_DSMGMT_AD = 1 << 2, | ||
| 309 | }; | ||
| 310 | |||
| 311 | struct nvme_dsm_range { | ||
| 312 | __le32 cattr; | ||
| 313 | __le32 nlb; | ||
| 314 | __le64 slba; | ||
| 315 | }; | ||
| 316 | |||
| 317 | /* Admin commands */ | ||
| 318 | |||
| 319 | enum nvme_admin_opcode { | ||
| 320 | nvme_admin_delete_sq = 0x00, | ||
| 321 | nvme_admin_create_sq = 0x01, | ||
| 322 | nvme_admin_get_log_page = 0x02, | ||
| 323 | nvme_admin_delete_cq = 0x04, | ||
| 324 | nvme_admin_create_cq = 0x05, | ||
| 325 | nvme_admin_identify = 0x06, | ||
| 326 | nvme_admin_abort_cmd = 0x08, | ||
| 327 | nvme_admin_set_features = 0x09, | ||
| 328 | nvme_admin_get_features = 0x0a, | ||
| 329 | nvme_admin_async_event = 0x0c, | ||
| 330 | nvme_admin_activate_fw = 0x10, | ||
| 331 | nvme_admin_download_fw = 0x11, | ||
| 332 | nvme_admin_format_nvm = 0x80, | ||
| 333 | nvme_admin_security_send = 0x81, | ||
| 334 | nvme_admin_security_recv = 0x82, | ||
| 335 | }; | ||
| 336 | |||
| 337 | enum { | ||
| 338 | NVME_QUEUE_PHYS_CONTIG = (1 << 0), | ||
| 339 | NVME_CQ_IRQ_ENABLED = (1 << 1), | ||
| 340 | NVME_SQ_PRIO_URGENT = (0 << 1), | ||
| 341 | NVME_SQ_PRIO_HIGH = (1 << 1), | ||
| 342 | NVME_SQ_PRIO_MEDIUM = (2 << 1), | ||
| 343 | NVME_SQ_PRIO_LOW = (3 << 1), | ||
| 344 | NVME_FEAT_ARBITRATION = 0x01, | ||
| 345 | NVME_FEAT_POWER_MGMT = 0x02, | ||
| 346 | NVME_FEAT_LBA_RANGE = 0x03, | ||
| 347 | NVME_FEAT_TEMP_THRESH = 0x04, | ||
| 348 | NVME_FEAT_ERR_RECOVERY = 0x05, | ||
| 349 | NVME_FEAT_VOLATILE_WC = 0x06, | ||
| 350 | NVME_FEAT_NUM_QUEUES = 0x07, | ||
| 351 | NVME_FEAT_IRQ_COALESCE = 0x08, | ||
| 352 | NVME_FEAT_IRQ_CONFIG = 0x09, | ||
| 353 | NVME_FEAT_WRITE_ATOMIC = 0x0a, | ||
| 354 | NVME_FEAT_ASYNC_EVENT = 0x0b, | ||
| 355 | NVME_FEAT_AUTO_PST = 0x0c, | ||
| 356 | NVME_FEAT_SW_PROGRESS = 0x80, | ||
| 357 | NVME_FEAT_HOST_ID = 0x81, | ||
| 358 | NVME_FEAT_RESV_MASK = 0x82, | ||
| 359 | NVME_FEAT_RESV_PERSIST = 0x83, | ||
| 360 | NVME_LOG_ERROR = 0x01, | ||
| 361 | NVME_LOG_SMART = 0x02, | ||
| 362 | NVME_LOG_FW_SLOT = 0x03, | ||
| 363 | NVME_LOG_RESERVATION = 0x80, | ||
| 364 | NVME_FWACT_REPL = (0 << 3), | ||
| 365 | NVME_FWACT_REPL_ACTV = (1 << 3), | ||
| 366 | NVME_FWACT_ACTV = (2 << 3), | ||
| 367 | }; | ||
| 368 | |||
| 369 | struct nvme_identify { | ||
| 370 | __u8 opcode; | ||
| 371 | __u8 flags; | ||
| 372 | __u16 command_id; | ||
| 373 | __le32 nsid; | ||
| 374 | __u64 rsvd2[2]; | ||
| 375 | __le64 prp1; | ||
| 376 | __le64 prp2; | ||
| 377 | __le32 cns; | ||
| 378 | __u32 rsvd11[5]; | ||
| 379 | }; | ||
| 380 | |||
| 381 | struct nvme_features { | ||
| 382 | __u8 opcode; | ||
| 383 | __u8 flags; | ||
| 384 | __u16 command_id; | ||
| 385 | __le32 nsid; | ||
| 386 | __u64 rsvd2[2]; | ||
| 387 | __le64 prp1; | ||
| 388 | __le64 prp2; | ||
| 389 | __le32 fid; | ||
| 390 | __le32 dword11; | ||
| 391 | __u32 rsvd12[4]; | ||
| 392 | }; | ||
| 393 | |||
| 394 | struct nvme_create_cq { | ||
| 395 | __u8 opcode; | ||
| 396 | __u8 flags; | ||
| 397 | __u16 command_id; | ||
| 398 | __u32 rsvd1[5]; | ||
| 399 | __le64 prp1; | ||
| 400 | __u64 rsvd8; | ||
| 401 | __le16 cqid; | ||
| 402 | __le16 qsize; | ||
| 403 | __le16 cq_flags; | ||
| 404 | __le16 irq_vector; | ||
| 405 | __u32 rsvd12[4]; | ||
| 406 | }; | ||
| 407 | |||
| 408 | struct nvme_create_sq { | ||
| 409 | __u8 opcode; | ||
| 410 | __u8 flags; | ||
| 411 | __u16 command_id; | ||
| 412 | __u32 rsvd1[5]; | ||
| 413 | __le64 prp1; | ||
| 414 | __u64 rsvd8; | ||
| 415 | __le16 sqid; | ||
| 416 | __le16 qsize; | ||
| 417 | __le16 sq_flags; | ||
| 418 | __le16 cqid; | ||
| 419 | __u32 rsvd12[4]; | ||
| 420 | }; | ||
| 421 | |||
| 422 | struct nvme_delete_queue { | ||
| 423 | __u8 opcode; | ||
| 424 | __u8 flags; | ||
| 425 | __u16 command_id; | ||
| 426 | __u32 rsvd1[9]; | ||
| 427 | __le16 qid; | ||
| 428 | __u16 rsvd10; | ||
| 429 | __u32 rsvd11[5]; | ||
| 430 | }; | ||
| 431 | |||
| 432 | struct nvme_abort_cmd { | ||
| 433 | __u8 opcode; | ||
| 434 | __u8 flags; | ||
| 435 | __u16 command_id; | ||
| 436 | __u32 rsvd1[9]; | ||
| 437 | __le16 sqid; | ||
| 438 | __u16 cid; | ||
| 439 | __u32 rsvd11[5]; | ||
| 440 | }; | ||
| 441 | |||
| 442 | struct nvme_download_firmware { | ||
| 443 | __u8 opcode; | ||
| 444 | __u8 flags; | ||
| 445 | __u16 command_id; | ||
| 446 | __u32 rsvd1[5]; | ||
| 447 | __le64 prp1; | ||
| 448 | __le64 prp2; | ||
| 449 | __le32 numd; | ||
| 450 | __le32 offset; | ||
| 451 | __u32 rsvd12[4]; | ||
| 452 | }; | ||
| 453 | |||
| 454 | struct nvme_format_cmd { | ||
| 455 | __u8 opcode; | ||
| 456 | __u8 flags; | ||
| 457 | __u16 command_id; | ||
| 458 | __le32 nsid; | ||
| 459 | __u64 rsvd2[4]; | ||
| 460 | __le32 cdw10; | ||
| 461 | __u32 rsvd11[5]; | ||
| 462 | }; | ||
| 463 | |||
| 464 | struct nvme_command { | ||
| 465 | union { | ||
| 466 | struct nvme_common_command common; | ||
| 467 | struct nvme_rw_command rw; | ||
| 468 | struct nvme_identify identify; | ||
| 469 | struct nvme_features features; | ||
| 470 | struct nvme_create_cq create_cq; | ||
| 471 | struct nvme_create_sq create_sq; | ||
| 472 | struct nvme_delete_queue delete_queue; | ||
| 473 | struct nvme_download_firmware dlfw; | ||
| 474 | struct nvme_format_cmd format; | ||
| 475 | struct nvme_dsm_cmd dsm; | ||
| 476 | struct nvme_abort_cmd abort; | ||
| 477 | }; | ||
| 478 | }; | ||
| 479 | |||
| 480 | enum { | ||
| 481 | NVME_SC_SUCCESS = 0x0, | ||
| 482 | NVME_SC_INVALID_OPCODE = 0x1, | ||
| 483 | NVME_SC_INVALID_FIELD = 0x2, | ||
| 484 | NVME_SC_CMDID_CONFLICT = 0x3, | ||
| 485 | NVME_SC_DATA_XFER_ERROR = 0x4, | ||
| 486 | NVME_SC_POWER_LOSS = 0x5, | ||
| 487 | NVME_SC_INTERNAL = 0x6, | ||
| 488 | NVME_SC_ABORT_REQ = 0x7, | ||
| 489 | NVME_SC_ABORT_QUEUE = 0x8, | ||
| 490 | NVME_SC_FUSED_FAIL = 0x9, | ||
| 491 | NVME_SC_FUSED_MISSING = 0xa, | ||
| 492 | NVME_SC_INVALID_NS = 0xb, | ||
| 493 | NVME_SC_CMD_SEQ_ERROR = 0xc, | ||
| 494 | NVME_SC_SGL_INVALID_LAST = 0xd, | ||
| 495 | NVME_SC_SGL_INVALID_COUNT = 0xe, | ||
| 496 | NVME_SC_SGL_INVALID_DATA = 0xf, | ||
| 497 | NVME_SC_SGL_INVALID_METADATA = 0x10, | ||
| 498 | NVME_SC_SGL_INVALID_TYPE = 0x11, | ||
| 499 | NVME_SC_LBA_RANGE = 0x80, | ||
| 500 | NVME_SC_CAP_EXCEEDED = 0x81, | ||
| 501 | NVME_SC_NS_NOT_READY = 0x82, | ||
| 502 | NVME_SC_RESERVATION_CONFLICT = 0x83, | ||
| 503 | NVME_SC_CQ_INVALID = 0x100, | ||
| 504 | NVME_SC_QID_INVALID = 0x101, | ||
| 505 | NVME_SC_QUEUE_SIZE = 0x102, | ||
| 506 | NVME_SC_ABORT_LIMIT = 0x103, | ||
| 507 | NVME_SC_ABORT_MISSING = 0x104, | ||
| 508 | NVME_SC_ASYNC_LIMIT = 0x105, | ||
| 509 | NVME_SC_FIRMWARE_SLOT = 0x106, | ||
| 510 | NVME_SC_FIRMWARE_IMAGE = 0x107, | ||
| 511 | NVME_SC_INVALID_VECTOR = 0x108, | ||
| 512 | NVME_SC_INVALID_LOG_PAGE = 0x109, | ||
| 513 | NVME_SC_INVALID_FORMAT = 0x10a, | ||
| 514 | NVME_SC_FIRMWARE_NEEDS_RESET = 0x10b, | ||
| 515 | NVME_SC_INVALID_QUEUE = 0x10c, | ||
| 516 | NVME_SC_FEATURE_NOT_SAVEABLE = 0x10d, | ||
| 517 | NVME_SC_FEATURE_NOT_CHANGEABLE = 0x10e, | ||
| 518 | NVME_SC_FEATURE_NOT_PER_NS = 0x10f, | ||
| 519 | NVME_SC_FW_NEEDS_RESET_SUBSYS = 0x110, | ||
| 520 | NVME_SC_BAD_ATTRIBUTES = 0x180, | ||
| 521 | NVME_SC_INVALID_PI = 0x181, | ||
| 522 | NVME_SC_READ_ONLY = 0x182, | ||
| 523 | NVME_SC_WRITE_FAULT = 0x280, | ||
| 524 | NVME_SC_READ_ERROR = 0x281, | ||
| 525 | NVME_SC_GUARD_CHECK = 0x282, | ||
| 526 | NVME_SC_APPTAG_CHECK = 0x283, | ||
| 527 | NVME_SC_REFTAG_CHECK = 0x284, | ||
| 528 | NVME_SC_COMPARE_FAILED = 0x285, | ||
| 529 | NVME_SC_ACCESS_DENIED = 0x286, | ||
| 530 | NVME_SC_DNR = 0x4000, | ||
| 531 | }; | ||
| 532 | |||
| 533 | struct nvme_completion { | ||
| 534 | __le32 result; /* Used by admin commands to return data */ | ||
| 535 | __u32 rsvd; | ||
| 536 | __le16 sq_head; /* how much of this queue may be reclaimed */ | ||
| 537 | __le16 sq_id; /* submission queue that generated this entry */ | ||
| 538 | __u16 command_id; /* of the command which completed */ | ||
| 539 | __le16 status; /* did the command fail, and if so, why? */ | ||
| 540 | }; | ||
| 541 | |||
| 542 | struct nvme_user_io { | ||
| 543 | __u8 opcode; | ||
| 544 | __u8 flags; | ||
| 545 | __u16 control; | ||
| 546 | __u16 nblocks; | ||
| 547 | __u16 rsvd; | ||
| 548 | __u64 metadata; | ||
| 549 | __u64 addr; | ||
| 550 | __u64 slba; | ||
| 551 | __u32 dsmgmt; | ||
| 552 | __u32 reftag; | ||
| 553 | __u16 apptag; | ||
| 554 | __u16 appmask; | ||
| 555 | }; | ||
| 556 | |||
| 557 | struct nvme_passthru_cmd { | ||
| 558 | __u8 opcode; | ||
| 559 | __u8 flags; | ||
| 560 | __u16 rsvd1; | ||
| 561 | __u32 nsid; | ||
| 562 | __u32 cdw2; | ||
| 563 | __u32 cdw3; | ||
| 564 | __u64 metadata; | ||
| 565 | __u64 addr; | ||
| 566 | __u32 metadata_len; | ||
| 567 | __u32 data_len; | ||
| 568 | __u32 cdw10; | ||
| 569 | __u32 cdw11; | ||
| 570 | __u32 cdw12; | ||
| 571 | __u32 cdw13; | ||
| 572 | __u32 cdw14; | ||
| 573 | __u32 cdw15; | ||
| 574 | __u32 timeout_ms; | ||
| 575 | __u32 result; | ||
| 576 | }; | ||
| 577 | |||
| 578 | #define NVME_VS(major, minor) (((major) << 16) | ((minor) << 8)) | ||
| 579 | |||
| 580 | #define nvme_admin_cmd nvme_passthru_cmd | ||
| 581 | |||
| 582 | #define NVME_IOCTL_ID _IO('N', 0x40) | ||
| 583 | #define NVME_IOCTL_ADMIN_CMD _IOWR('N', 0x41, struct nvme_admin_cmd) | ||
| 584 | #define NVME_IOCTL_SUBMIT_IO _IOW('N', 0x42, struct nvme_user_io) | ||
| 585 | #define NVME_IOCTL_IO_CMD _IOWR('N', 0x43, struct nvme_passthru_cmd) | ||
| 586 | #define NVME_IOCTL_RESET _IO('N', 0x44) | ||
| 587 | #define NVME_IOCTL_SUBSYS_RESET _IO('N', 0x45) | ||
| 588 | |||
| 589 | #endif /* _UAPI_LINUX_NVME_H */ | ||
| @@ -0,0 +1,65 @@ | |||
| 1 | /* | ||
| 2 | * Definitions for the NVM Express ioctl interface | ||
| 3 | * Copyright (c) 2011-2014, Intel Corporation. | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms and conditions of the GNU General Public License, | ||
| 7 | * version 2, as published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 12 | * more details. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #ifndef _UAPI_LINUX_NVME_IOCTL_H | ||
| 16 | #define _UAPI_LINUX_NVME_IOCTL_H | ||
| 17 | |||
| 18 | #include <linux/types.h> | ||
| 19 | |||
| 20 | struct nvme_user_io { | ||
| 21 | __u8 opcode; | ||
| 22 | __u8 flags; | ||
| 23 | __u16 control; | ||
| 24 | __u16 nblocks; | ||
| 25 | __u16 rsvd; | ||
| 26 | __u64 metadata; | ||
| 27 | __u64 addr; | ||
| 28 | __u64 slba; | ||
| 29 | __u32 dsmgmt; | ||
| 30 | __u32 reftag; | ||
| 31 | __u16 apptag; | ||
| 32 | __u16 appmask; | ||
| 33 | }; | ||
| 34 | |||
| 35 | struct nvme_passthru_cmd { | ||
| 36 | __u8 opcode; | ||
| 37 | __u8 flags; | ||
| 38 | __u16 rsvd1; | ||
| 39 | __u32 nsid; | ||
| 40 | __u32 cdw2; | ||
| 41 | __u32 cdw3; | ||
| 42 | __u64 metadata; | ||
| 43 | __u64 addr; | ||
| 44 | __u32 metadata_len; | ||
| 45 | __u32 data_len; | ||
| 46 | __u32 cdw10; | ||
| 47 | __u32 cdw11; | ||
| 48 | __u32 cdw12; | ||
| 49 | __u32 cdw13; | ||
| 50 | __u32 cdw14; | ||
| 51 | __u32 cdw15; | ||
| 52 | __u32 timeout_ms; | ||
| 53 | __u32 result; | ||
| 54 | }; | ||
| 55 | |||
| 56 | #define nvme_admin_cmd nvme_passthru_cmd | ||
| 57 | |||
| 58 | #define NVME_IOCTL_ID _IO('N', 0x40) | ||
| 59 | #define NVME_IOCTL_ADMIN_CMD _IOWR('N', 0x41, struct nvme_admin_cmd) | ||
| 60 | #define NVME_IOCTL_SUBMIT_IO _IOW('N', 0x42, struct nvme_user_io) | ||
| 61 | #define NVME_IOCTL_IO_CMD _IOWR('N', 0x43, struct nvme_passthru_cmd) | ||
| 62 | #define NVME_IOCTL_RESET _IO('N', 0x44) | ||
| 63 | #define NVME_IOCTL_SUBSYS_RESET _IO('N', 0x45) | ||
| 64 | |||
| 65 | #endif /* _UAPI_LINUX_NVME_IOCTL_H */ | ||