diff options
author | Christoph Hellwig <hch@lst.de> | 2015-05-22 05:12:40 -0400 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2015-05-22 10:36:34 -0400 |
commit | b90c48d0c11efe373a42a60e66e2ac2a503c287b (patch) | |
tree | 77e00f5aa9a3a63d7596601e884ae1d1a27d2860 | |
parent | e75ec752d725b7b612c0b2db1bca50a9e53c0879 (diff) |
nvme: split nvme_trans_send_fw_cmd
This function handles two totally different opcodes, so split it.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r-- | drivers/block/nvme-scsi.c | 93 |
1 files changed, 47 insertions, 46 deletions
diff --git a/drivers/block/nvme-scsi.c b/drivers/block/nvme-scsi.c index f1c90f273132..60415b52fd34 100644 --- a/drivers/block/nvme-scsi.c +++ b/drivers/block/nvme-scsi.c | |||
@@ -1554,10 +1554,25 @@ static int nvme_trans_power_state(struct nvme_ns *ns, struct sg_io_hdr *hdr, | |||
1554 | return res; | 1554 | return res; |
1555 | } | 1555 | } |
1556 | 1556 | ||
1557 | /* Write Buffer Helper Functions */ | 1557 | static int nvme_trans_send_activate_fw_cmd(struct nvme_ns *ns, struct sg_io_hdr *hdr, |
1558 | /* Also using this for Format Unit with hdr passed as NULL, and buffer_id, 0 */ | 1558 | u8 buffer_id) |
1559 | { | ||
1560 | struct nvme_command c; | ||
1561 | int nvme_sc; | ||
1562 | int res; | ||
1563 | |||
1564 | memset(&c, 0, sizeof(c)); | ||
1565 | c.common.opcode = nvme_admin_activate_fw; | ||
1566 | c.common.cdw10[0] = cpu_to_le32(buffer_id | NVME_FWACT_REPL_ACTV); | ||
1567 | |||
1568 | nvme_sc = nvme_submit_sync_cmd(ns->queue, &c); | ||
1569 | res = nvme_trans_status_code(hdr, nvme_sc); | ||
1570 | if (res) | ||
1571 | return res; | ||
1572 | return nvme_sc; | ||
1573 | } | ||
1559 | 1574 | ||
1560 | static int nvme_trans_send_fw_cmd(struct nvme_ns *ns, struct sg_io_hdr *hdr, | 1575 | static int nvme_trans_send_download_fw_cmd(struct nvme_ns *ns, struct sg_io_hdr *hdr, |
1561 | u8 opcode, u32 tot_len, u32 offset, | 1576 | u8 opcode, u32 tot_len, u32 offset, |
1562 | u8 buffer_id) | 1577 | u8 buffer_id) |
1563 | { | 1578 | { |
@@ -1569,38 +1584,31 @@ static int nvme_trans_send_fw_cmd(struct nvme_ns *ns, struct sg_io_hdr *hdr, | |||
1569 | unsigned length; | 1584 | unsigned length; |
1570 | 1585 | ||
1571 | memset(&c, 0, sizeof(c)); | 1586 | memset(&c, 0, sizeof(c)); |
1572 | c.common.opcode = opcode; | 1587 | c.common.opcode = nvme_admin_download_fw; |
1573 | if (opcode == nvme_admin_download_fw) { | ||
1574 | if (hdr->iovec_count > 0) { | ||
1575 | /* Assuming SGL is not allowed for this command */ | ||
1576 | res = nvme_trans_completion(hdr, | ||
1577 | SAM_STAT_CHECK_CONDITION, | ||
1578 | ILLEGAL_REQUEST, | ||
1579 | SCSI_ASC_INVALID_CDB, | ||
1580 | SCSI_ASCQ_CAUSE_NOT_REPORTABLE); | ||
1581 | goto out; | ||
1582 | } | ||
1583 | iod = nvme_map_user_pages(dev, DMA_TO_DEVICE, | ||
1584 | (unsigned long)hdr->dxferp, tot_len); | ||
1585 | if (IS_ERR(iod)) { | ||
1586 | res = PTR_ERR(iod); | ||
1587 | goto out; | ||
1588 | } | ||
1589 | length = nvme_setup_prps(dev, iod, tot_len, GFP_KERNEL); | ||
1590 | if (length != tot_len) { | ||
1591 | res = -ENOMEM; | ||
1592 | goto out_unmap; | ||
1593 | } | ||
1594 | 1588 | ||
1595 | c.dlfw.prp1 = cpu_to_le64(sg_dma_address(iod->sg)); | 1589 | if (hdr->iovec_count > 0) { |
1596 | c.dlfw.prp2 = cpu_to_le64(iod->first_dma); | 1590 | /* Assuming SGL is not allowed for this command */ |
1597 | c.dlfw.numd = cpu_to_le32((tot_len/BYTES_TO_DWORDS) - 1); | 1591 | return nvme_trans_completion(hdr, |
1598 | c.dlfw.offset = cpu_to_le32(offset/BYTES_TO_DWORDS); | 1592 | SAM_STAT_CHECK_CONDITION, |
1599 | } else if (opcode == nvme_admin_activate_fw) { | 1593 | ILLEGAL_REQUEST, |
1600 | u32 cdw10 = buffer_id | NVME_FWACT_REPL_ACTV; | 1594 | SCSI_ASC_INVALID_CDB, |
1601 | c.common.cdw10[0] = cpu_to_le32(cdw10); | 1595 | SCSI_ASCQ_CAUSE_NOT_REPORTABLE); |
1596 | } | ||
1597 | iod = nvme_map_user_pages(dev, DMA_TO_DEVICE, | ||
1598 | (unsigned long)hdr->dxferp, tot_len); | ||
1599 | if (IS_ERR(iod)) | ||
1600 | return PTR_ERR(iod); | ||
1601 | length = nvme_setup_prps(dev, iod, tot_len, GFP_KERNEL); | ||
1602 | if (length != tot_len) { | ||
1603 | res = -ENOMEM; | ||
1604 | goto out_unmap; | ||
1602 | } | 1605 | } |
1603 | 1606 | ||
1607 | c.dlfw.prp1 = cpu_to_le64(sg_dma_address(iod->sg)); | ||
1608 | c.dlfw.prp2 = cpu_to_le64(iod->first_dma); | ||
1609 | c.dlfw.numd = cpu_to_le32((tot_len/BYTES_TO_DWORDS) - 1); | ||
1610 | c.dlfw.offset = cpu_to_le32(offset/BYTES_TO_DWORDS); | ||
1611 | |||
1604 | nvme_sc = nvme_submit_sync_cmd(dev->admin_q, &c); | 1612 | nvme_sc = nvme_submit_sync_cmd(dev->admin_q, &c); |
1605 | res = nvme_trans_status_code(hdr, nvme_sc); | 1613 | res = nvme_trans_status_code(hdr, nvme_sc); |
1606 | if (res) | 1614 | if (res) |
@@ -1609,11 +1617,8 @@ static int nvme_trans_send_fw_cmd(struct nvme_ns *ns, struct sg_io_hdr *hdr, | |||
1609 | res = nvme_sc; | 1617 | res = nvme_sc; |
1610 | 1618 | ||
1611 | out_unmap: | 1619 | out_unmap: |
1612 | if (opcode == nvme_admin_download_fw) { | 1620 | nvme_unmap_user_pages(dev, DMA_TO_DEVICE, iod); |
1613 | nvme_unmap_user_pages(dev, DMA_TO_DEVICE, iod); | 1621 | nvme_free_iod(dev, iod); |
1614 | nvme_free_iod(dev, iod); | ||
1615 | } | ||
1616 | out: | ||
1617 | return res; | 1622 | return res; |
1618 | } | 1623 | } |
1619 | 1624 | ||
@@ -2769,7 +2774,7 @@ static int nvme_trans_format_unit(struct nvme_ns *ns, struct sg_io_hdr *hdr, | |||
2769 | } | 2774 | } |
2770 | 2775 | ||
2771 | /* Attempt to activate any previously downloaded firmware image */ | 2776 | /* Attempt to activate any previously downloaded firmware image */ |
2772 | res = nvme_trans_send_fw_cmd(ns, hdr, nvme_admin_activate_fw, 0, 0, 0); | 2777 | res = nvme_trans_send_activate_fw_cmd(ns, hdr, 0); |
2773 | 2778 | ||
2774 | /* Determine Block size and count and send format command */ | 2779 | /* Determine Block size and count and send format command */ |
2775 | res = nvme_trans_fmt_set_blk_size_count(ns, hdr); | 2780 | res = nvme_trans_fmt_set_blk_size_count(ns, hdr); |
@@ -2829,24 +2834,20 @@ static int nvme_trans_write_buffer(struct nvme_ns *ns, struct sg_io_hdr *hdr, | |||
2829 | 2834 | ||
2830 | switch (mode) { | 2835 | switch (mode) { |
2831 | case DOWNLOAD_SAVE_ACTIVATE: | 2836 | case DOWNLOAD_SAVE_ACTIVATE: |
2832 | res = nvme_trans_send_fw_cmd(ns, hdr, nvme_admin_download_fw, | 2837 | res = nvme_trans_send_download_fw_cmd(ns, hdr, nvme_admin_download_fw, |
2833 | parm_list_length, buffer_offset, | 2838 | parm_list_length, buffer_offset, |
2834 | buffer_id); | 2839 | buffer_id); |
2835 | if (res != SNTI_TRANSLATION_SUCCESS) | 2840 | if (res != SNTI_TRANSLATION_SUCCESS) |
2836 | goto out; | 2841 | goto out; |
2837 | res = nvme_trans_send_fw_cmd(ns, hdr, nvme_admin_activate_fw, | 2842 | res = nvme_trans_send_activate_fw_cmd(ns, hdr, buffer_id); |
2838 | parm_list_length, buffer_offset, | ||
2839 | buffer_id); | ||
2840 | break; | 2843 | break; |
2841 | case DOWNLOAD_SAVE_DEFER_ACTIVATE: | 2844 | case DOWNLOAD_SAVE_DEFER_ACTIVATE: |
2842 | res = nvme_trans_send_fw_cmd(ns, hdr, nvme_admin_download_fw, | 2845 | res = nvme_trans_send_download_fw_cmd(ns, hdr, nvme_admin_download_fw, |
2843 | parm_list_length, buffer_offset, | 2846 | parm_list_length, buffer_offset, |
2844 | buffer_id); | 2847 | buffer_id); |
2845 | break; | 2848 | break; |
2846 | case ACTIVATE_DEFERRED_MICROCODE: | 2849 | case ACTIVATE_DEFERRED_MICROCODE: |
2847 | res = nvme_trans_send_fw_cmd(ns, hdr, nvme_admin_activate_fw, | 2850 | res = nvme_trans_send_activate_fw_cmd(ns, hdr, buffer_id); |
2848 | parm_list_length, buffer_offset, | ||
2849 | buffer_id); | ||
2850 | break; | 2851 | break; |
2851 | default: | 2852 | default: |
2852 | res = nvme_trans_completion(hdr, SAM_STAT_CHECK_CONDITION, | 2853 | res = nvme_trans_completion(hdr, SAM_STAT_CHECK_CONDITION, |