aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2015-05-22 05:12:40 -0400
committerJens Axboe <axboe@fb.com>2015-05-22 10:36:34 -0400
commitb90c48d0c11efe373a42a60e66e2ac2a503c287b (patch)
tree77e00f5aa9a3a63d7596601e884ae1d1a27d2860
parente75ec752d725b7b612c0b2db1bca50a9e53c0879 (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.c93
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 */ 1557static 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
1560static int nvme_trans_send_fw_cmd(struct nvme_ns *ns, struct sg_io_hdr *hdr, 1575static 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,