qla2xxx: Add FC-NVMe Target support
Subsystems (3)
v2 cover qla2xxx: Add FC-NVMe Target support
Hi Christoph/Sagi,
I've corrected the mailing list and maintainers for this series.
This series adds support for FC-NVMe Target.
Patch #1 addes new qla_nvmet files for FC-NVMe Target support. Patch #2 adds Kconfig and Makefile changes to prepare code compile. Patch #3 and #4 has bulk of changes to handle FC-NVMe Target LS4 processing via Purex pass through path.
Note: All the patches in this series must be applied before they can be compilable.
These patches were cut against 4.15/scsi-queue.
Changes from v1 -> v2
o Fixed 0-day kernel warning and build regression.
Thanks,
Himanshu
Anil Gurumurthy (4):
qla2xxx_nvmet: Add files for FC-NVMe Target support
qla2xxx_nvmet: Added Makefile and Kconfig changes
qla2xxx_nvmet: Add FC-NVMe Target LS request handling
qla2xxx_nvmet: Add FC-NVMe Target handling
drivers/scsi/qla2xxx/Kconfig | 1 + drivers/scsi/qla2xxx/Makefile | 3 +- drivers/scsi/qla2xxx/qla_dbg.c | 1 + drivers/scsi/qla2xxx/qla_dbg.h | 2 + drivers/scsi/qla2xxx/qla_def.h | 35 +- drivers/scsi/qla2xxx/qla_fw.h | 263 +++++++++++ drivers/scsi/qla2xxx/qla_gbl.h | 17 +- drivers/scsi/qla2xxx/qla_gs.c | 15 +- drivers/scsi/qla2xxx/qla_init.c | 49 +- drivers/scsi/qla2xxx/qla_iocb.c | 42 +- drivers/scsi/qla2xxx/qla_isr.c | 70 +++ drivers/scsi/qla2xxx/qla_mbx.c | 100 +++- drivers/scsi/qla2xxx/qla_nvme.h | 33 -- drivers/scsi/qla2xxx/qla_nvmet.c | 783 ++++++++++++++++++++++++++++++++ drivers/scsi/qla2xxx/qla_nvmet.h | 130 ++++++ drivers/scsi/qla2xxx/qla_os.c | 75 ++- drivers/scsi/qla2xxx/qla_target.c | 932 +++++++++++++++++++++++++++++++++++++- drivers/scsi/qla2xxx/qla_target.h | 93 +++- 18 files changed, 2585 insertions(+), 59 deletions(-) create mode 100644 drivers/scsi/qla2xxx/qla_nvmet.c create mode 100644 drivers/scsi/qla2xxx/qla_nvmet.h
Signature · 1 line
2.12.0
PATCH v2 1/4 qla2xxx_nvmet: Add files for FC-NVMe Target support
From: Anil Gurumurthy <[email protected]>
--- drivers/scsi/qla2xxx/qla_nvmet.c | 783 +++++++++++++++++++++++++++++++++++++++ drivers/scsi/qla2xxx/qla_nvmet.h | 130 +++++++ 2 files changed, 913 insertions(+) create mode 100644 drivers/scsi/qla2xxx/qla_nvmet.c create mode 100644 drivers/scsi/qla2xxx/qla_nvmet.h
drivers/scsi/qla2xxx/qla_nvmet.c new file +783 -0
@@ -0,0 +1,783 @@ + +/* +* QLogic Fibre Channel HBA Driver +* Copyright (c) 2003-2017 QLogic Corporation +* +* See LICENSE.qla2xxx for copyright and licensing details. +*/ +#include <linux/scatterlist.h> +#include <linux/delay.h> +#include <linux/nvme.h> +#include <linux/nvme-fc.h> + +#include "qla_nvme.h" +#include "qla_nvmet.h" + +#if IS_ENABLED (CONFIG_NVME_TARGET_FC ) +static void qla_nvmet_send_resp_ctio (struct qla_qpair *qpair, +struct qla_nvmet_cmd *cmd,struct nvmefc_tgt_fcp_req *rsp); +static void qla_nvmet_send_abts_ctio (struct scsi_qla_host *vha, +struct abts_recv_from_24xx *abts,bool flag); + +/* +* qla_nvmet_targetport_delete - +* Invoked by the nvmet to indicate that the target port has +* been deleted +*/ +static void +qla_nvmet_targetport_delete (struct nvmet_fc_target_port *targetport) +{ +struct qla_nvmet_tgtport *tport = targetport->private; + +complete (&tport->tport_del); +} +#endif + +#if IS_ENABLED (CONFIG_NVME_TARGET_FC ) +/* +* qlt_nvmet_ls_done - +* Invoked by the firmware interface to indicate the completion +* of an LS cmd +* Free all associated resources of the LS cmd +*/ +static void qlt_nvmet_ls_done (void *ptr,int res) +{ +struct srb *sp = ptr; +struct srb_iocb *nvme = &sp->u.iocb_cmd; +struct nvmefc_tgt_ls_req *rsp = nvme->u.nvme.desc; +struct qla_nvmet_cmd *tgt_cmd = nvme->u.nvme.cmd; + +ql_log (ql_log_info, sp->vha,0x11000 , +"Done with NVME LS4 req\n" ); + +ql_log (ql_log_info, sp->vha,0x11001 , +"sp: %p vha: %p, rsp: %p, cmd: %p\n" , + sp, sp->vha, nvme->u.nvme.desc, nvme->u.nvme.cmd); + + rsp->done (rsp); +/* Free tgt_cmd */ +kfree (tgt_cmd->buf); +kfree (tgt_cmd); +qla2x00_rel_sp (sp); +} + +/* +* qla_nvmet_ls_rsp - +* Invoked by the nvme-t to complete the LS req. +* Prepare and send a response CTIO to the firmware. +*/ +static int +qla_nvmet_ls_rsp (struct nvmet_fc_target_port *tgtport, +struct nvmefc_tgt_ls_req *rsp) +{ +struct qla_nvmet_cmd *tgt_cmd = + container_of(rsp, struct qla_nvmet_cmd, cmd.ls_req); +struct scsi_qla_host *vha = tgt_cmd->vha; +struct srb_iocb *nvme; +int rval =QLA_FUNCTION_FAILED ; +srb_t *sp; + +ql_log (ql_log_info, vha,0x11002 , +"Dumping the NVMET-LS response buffer\n" ); +ql_dump_buffer (ql_dbg_disc + ql_dbg_buffer, vha,0x2075 , + (uint8_t *)rsp->rspbuf, rsp->rsplen); + +/* Alloc SRB structure */ + sp =qla2x00_get_sp (vha,NULL ,GFP_ATOMIC ); +if (!sp) { +ql_log (ql_log_info, vha,0x11003 ,"Failed to allocate SRB\n" ); +return -ENOMEM ; + } + + sp->type =SRB_NVMET_LS ; + sp->done = qlt_nvmet_ls_done; + sp->vha = vha; + sp->fcport = tgt_cmd->fcport; + + nvme = &sp->u.iocb_cmd; + nvme->u.nvme.rsp_dma = rsp->rspdma; + nvme->u.nvme.rsp_len = rsp->rsplen; + nvme->u.nvme.exchange_address = tgt_cmd->atio.u.pt_ls4.exchange_address; + nvme->u.nvme.nport_handle = tgt_cmd->atio.u.pt_ls4.nport_handle; + nvme->u.nvme.vp_index = tgt_cmd->atio.u.pt_ls4.vp_index; + + nvme->u.nvme.cmd = tgt_cmd;/* To be freed */ + nvme->u.nvme.desc = rsp;/* Call back to nvmet */ + + rval =qla2x00_start_sp (sp); +if (rval !=QLA_SUCCESS ) { +ql_log (ql_log_warn, vha,0x11004 , +"qla2x00_start_sp failed = %d\n" , rval); +return rval; + } + +return 0 ; +} + +/* +* qla_nvmet_fcp_op - +* Invoked by the nvme-t to complete the IO. +* Prepare and send a response CTIO to the firmware. +*/ +static int +qla_nvmet_fcp_op (struct nvmet_fc_target_port *tgtport, +struct nvmefc_tgt_fcp_req *rsp) +{ +struct qla_nvmet_cmd *tgt_cmd = + container_of(rsp, struct qla_nvmet_cmd, cmd.fcp_req); +struct scsi_qla_host *vha = tgt_cmd->vha; + +/* Prepare and send CTIO 82h */ +qla_nvmet_send_resp_ctio (vha->qpair, tgt_cmd, rsp); + +return 0 ; +} +/* +* qla_nvmet_fcp_abort_done +* free up the used resources +*/ +static void qla_nvmet_fcp_abort_done (void *ptr,int res) +{ +srb_t *sp = ptr; + +qla2x00_rel_sp (sp); +} + +/* +* qla_nvmet_fcp_abort - +* Invoked by the nvme-t to abort an IO +* Send an abort to the firmware +*/ +static void +qla_nvmet_fcp_abort (struct nvmet_fc_target_port *tgtport, +struct nvmefc_tgt_fcp_req *req) +{ +struct qla_nvmet_cmd *tgt_cmd = + container_of(req, struct qla_nvmet_cmd, cmd.fcp_req); +struct scsi_qla_host *vha = tgt_cmd->vha; +struct qla_hw_data *ha = vha->hw; +srb_t *sp; + +/* Alloc SRB structure */ + sp =qla2x00_get_sp (vha,NULL ,GFP_KERNEL ); +if (!sp) { +ql_log (ql_log_info, vha,0x11005 ,"Failed to allocate SRB\n" ); +return ; + } + + sp->type =SRB_NVMET_SEND_ABTS ; + sp->done = qla_nvmet_fcp_abort_done; + sp->vha = vha; + sp->fcport = tgt_cmd->fcport; + + ha->isp_ops->abort_command (sp); + +} + +/* +* qla_nvmet_fcp_req_release - +* Delete the cmd from the list and free the cmd +*/ + +static void +qla_nvmet_fcp_req_release (struct nvmet_fc_target_port *tgtport, +struct nvmefc_tgt_fcp_req *rsp) +{ +struct qla_nvmet_cmd *tgt_cmd = + container_of(rsp, struct qla_nvmet_cmd, cmd.fcp_req); +scsi_qla_host_t *vha = tgt_cmd->vha; +unsigned long flags; + +spin_lock_irqsave (&vha->cmd_list_lock, flags); +list_del (&tgt_cmd->cmd_list); +spin_unlock_irqrestore (&vha->cmd_list_lock, flags); + +kfree (tgt_cmd); +} + +static struct nvmet_fc_target_template qla_nvmet_fc_transport = { + .targetport_delete = qla_nvmet_targetport_delete, + .xmt_ls_rsp = qla_nvmet_ls_rsp, + .fcp_op = qla_nvmet_fcp_op, + .fcp_abort = qla_nvmet_fcp_abort, + .fcp_req_release = qla_nvmet_fcp_req_release, + .max_hw_queues =8 , + .max_sgl_segments =128 , + .max_dif_sgl_segments =64 , + .dma_boundary =0xFFFFFFFF , + .target_features =NVMET_FCTGTFEAT_READDATA_RSP | +NVMET_FCTGTFEAT_CMD_IN_ISR | +NVMET_FCTGTFEAT_OPDONE_IN_ISR , + .target_priv_sz =sizeof (struct nvme_private ), +}; +#endif +/* +* qla_nvmet_create_targetport - +* Create a targetport. Registers the template with the nvme-t +* layer +*/ +int qla_nvmet_create_targetport (struct scsi_qla_host *vha) +{ +#if IS_ENABLED (CONFIG_NVME_TARGET_FC ) +struct nvmet_fc_port_info pinfo; +struct qla_nvmet_tgtport *tport; +int error =0 ; + +ql_dbg (ql_dbg_nvme, vha,0xe081 , +"Creating target port for :%p\n" , vha); + +memset (&pinfo,0 , (sizeof (struct nvmet_fc_port_info ))); + pinfo.node_name =wwn_to_u64 (vha->node_name); + pinfo.port_name =wwn_to_u64 (vha->port_name); + pinfo.port_id = vha->d_id.b24; + + error =nvmet_fc_register_targetport (&pinfo, + &qla_nvmet_fc_transport, &vha->hw->pdev->dev, + &vha->targetport); + +if (error) { +ql_dbg (ql_dbg_nvme, vha,0xe082 , +"Cannot register NVME transport:%d\n" , error); +return error; + } + tport = (struct qla_nvmet_tgtport *)vha->targetport->private; + tport->vha = vha; +ql_dbg (ql_dbg_nvme, vha,0xe082 , +" Registered NVME transport:%p WWPN:%llx\n" , + tport, pinfo.port_name); +#endif +return 0 ; +} + +/* +* qla_nvmet_delete - +* Delete a targetport. +*/ +int qla_nvmet_delete (struct scsi_qla_host *vha) +{ +#if IS_ENABLED (CONFIG_NVME_TARGET_FC ) +struct qla_nvmet_tgtport *tport; + +if (!vha->flags.nvmet_enabled) +return 0 ; +if (vha->targetport) { + tport = (struct qla_nvmet_tgtport *)vha->targetport->private; + +ql_dbg (ql_dbg_nvme, vha,0xe083 , +"Deleting target port :%p\n" , tport); +init_completion (&tport->tport_del); +nvmet_fc_unregister_targetport (vha->targetport); +wait_for_completion_timeout (&tport->tport_del,5 ); + +nvmet_release_sessions (vha); + } +#endif +return 0 ; +} + +/* +* qla_nvmet_handle_ls - +* Handle a link service request from the initiator. +* Get the LS payload from the ATIO queue, invoke +* nvmet_fc_rcv_ls_req to pass the LS req to nvmet. +*/ +int qla_nvmet_handle_ls (struct scsi_qla_host *vha, +struct pt_ls4_rx_unsol *pt_ls4,void *buf) +{ +#if IS_ENABLED (CONFIG_NVME_TARGET_FC ) +struct qla_nvmet_cmd *tgt_cmd; +uint32_t size; +int ret; +uint32_t look_up_sid; +fc_port_t *sess =NULL ; + + look_up_sid = pt_ls4->s_id[2 ] <<16 | + pt_ls4->s_id[1 ] <<8 | pt_ls4->s_id[0 ]; + +ql_log (ql_log_info, vha,0x11005 , +"%s - Look UP sid: %#x\n" , __func__, look_up_sid); + + sess =qla_nvmet_find_sess_by_s_id (vha, look_up_sid); +if (unlikely (!sess)) +WARN_ON (1 ); + + size =cpu_to_le16 (pt_ls4->desc_len) +8 ; + + tgt_cmd =kzalloc (sizeof (struct qla_nvmet_cmd ),GFP_ATOMIC ); +if (tgt_cmd ==NULL ) { +ql_dbg (ql_dbg_nvme, vha,0xe084 , +"Memory allocation failed\n" ); +return -ENOMEM ; + } + tgt_cmd->vha = vha; + tgt_cmd->ox_id = pt_ls4->ox_id; + tgt_cmd->buf = buf; +/* Store the received nphdl, rx_exh_addr etc */ +memcpy (&tgt_cmd->atio.u.pt_ls4, pt_ls4,sizeof (struct pt_ls4_rx_unsol )); + tgt_cmd->fcport = sess; + +ql_log (ql_log_info, vha,0x11006 , +"Dumping the PURLS-ATIO request\n" ); +ql_dump_buffer (ql_dbg_disc + ql_dbg_buffer, vha,0x2075 , + (uint8_t *)pt_ls4,sizeof (struct pt_ls4_rx_unsol )); + +ql_log (ql_log_info, vha,0x11007 , +"Sending LS to nvmet buf: %p, len: %#x\n" , buf, size); + + ret =nvmet_fc_rcv_ls_req (vha->targetport, + &tgt_cmd->cmd.ls_req, buf, size); + +if (ret ==0 ) { +ql_log (ql_log_info, vha,0x11008 , +"LS req handled successfully\n" ); +return 0 ; + } +ql_log (ql_log_warn, vha,0x11009 , +"LS req failed\n" ); + +return ret; +#else +return 0 ; +#endif +} + +/* +* qla_nvmet_process_cmd - +* Handle NVME cmd request from the initiator. +* Get the NVME payload from the ATIO queue, invoke +* nvmet_fc_rcv_ls_req to pass the LS req to nvmet. +* On a failure send an abts to the initiator? +*/ +int qla_nvmet_process_cmd (struct scsi_qla_host *vha, +struct qla_nvmet_cmd *tgt_cmd) +{ +#if IS_ENABLED (CONFIG_NVME_TARGET_FC ) +int ret; +struct atio7_nvme_cmnd *nvme_cmd; + + nvme_cmd = (struct atio7_nvme_cmnd *)&tgt_cmd->nvme_cmd_iu; + + ret =nvmet_fc_rcv_fcp_req (vha->targetport, &tgt_cmd->cmd.fcp_req, + nvme_cmd, tgt_cmd->cmd_len); +if (ret !=0 ) { +ql_log (ql_log_warn, vha,0x1100a , +"%s-%d - Failed (ret: %#x) to process NVME command\n" , + __func__, __LINE__, ret); +/* Send ABTS to initator ? */ + } +#endif +return 0 ; +} + +/* +* qla_nvmet_handle_abts +* Handle an abort from the initiator +* Invoke nvmet_fc_rcv_fcp_abort to pass the abts to the nvmet +*/ +int qla_nvmet_handle_abts (struct scsi_qla_host *vha, +struct abts_recv_from_24xx *abts) +{ +#if IS_ENABLED (CONFIG_NVME_TARGET_FC ) +uint16_t ox_id =cpu_to_be16 (abts->fcp_hdr_le.ox_id); +unsigned long flags; +struct qla_nvmet_cmd *cmd =NULL ; + +/* Retrieve the cmd from cmd list */ +spin_lock_irqsave (&vha->cmd_list_lock, flags); +list_for_each_entry (cmd, &vha->qla_cmd_list, cmd_list) { +if (cmd->ox_id == ox_id) +break ;/* Found the cmd */ + } +spin_unlock_irqrestore (&vha->cmd_list_lock, flags); +if (!cmd) { +ql_log (ql_log_warn, vha,0x1100b , +"%s-%d - Command not found\n" , __func__, __LINE__); +/* Send a RJT */ +qla_nvmet_send_abts_ctio (vha, abts,0 ); +return 0 ; + } + +nvmet_fc_rcv_fcp_abort (vha->targetport, &cmd->cmd.fcp_req); +/* Send an ACC */ +qla_nvmet_send_abts_ctio (vha, abts,1 ); +#endif +return 0 ; +} + +#if IS_ENABLED (CONFIG_NVME_TARGET_FC ) +/* +* qla_nvmet_abts_done +* Complete the cmd back to the nvme-t and +* free up the used resources +*/ +static void qla_nvmet_abts_done (void *ptr,int res) +{ +srb_t *sp = ptr; + +qla2x00_rel_sp (sp); +} +/* +* qla_nvmet_fcp_done +* Complete the cmd back to the nvme-t and +* free up the used resources +*/ +static void qla_nvmet_fcp_done (void *ptr,int res) +{ +srb_t *sp = ptr; +struct nvmefc_tgt_fcp_req *rsp; + + rsp = sp->u.iocb_cmd.u.nvme.desc; + +if (res) { + rsp->fcp_error =NVME_SC_SUCCESS ; +if (rsp->op ==NVMET_FCOP_RSP ) + rsp->transferred_length =0 ; +else + rsp->transferred_length = rsp->transfer_length; + }else { + rsp->fcp_error =NVME_SC_DATA_XFER_ERROR ; + rsp->transferred_length =0 ; + } + rsp->done (rsp); +qla2x00_rel_sp (sp); +} + +/* +* qla_nvmet_send_resp_ctio +* Send the response CTIO to the firmware +*/ +static void qla_nvmet_send_resp_ctio (struct qla_qpair *qpair, +struct qla_nvmet_cmd *cmd,struct nvmefc_tgt_fcp_req *rsp_buf) +{ +struct atio_from_isp *atio = &cmd->atio; +struct ctio_nvme_to_27xx *ctio; +struct scsi_qla_host *vha = cmd->vha; +struct qla_hw_data *ha = vha->hw; +struct fcp_hdr *fchdr = &atio->u.nvme_isp27.fcp_hdr; +srb_t *sp; +unsigned long flags; +uint16_t temp, c_flags =0 ; +struct req_que *req = vha->hw->req_q_map[0 ]; +uint32_t req_cnt =1 ; +uint32_t *cur_dsd; +uint16_t avail_dsds; +uint16_t tot_dsds, i, cnt; +struct scatterlist *sgl, *sg; + +spin_lock_irqsave (&ha->hardware_lock, flags); + +/* Alloc SRB structure */ + sp =qla2x00_get_sp (vha, cmd->fcport,GFP_KERNEL ); +if (!sp) { +ql_log (ql_log_info, vha,0x1100c ,"Failed to allocate SRB\n" ); +spin_unlock_irqrestore (&ha->hardware_lock, flags); +return ; + } + + sp->type =SRB_NVMET_FCP ; + sp->name ="nvmet_fcp" ; + sp->done = qla_nvmet_fcp_done; + sp->u.iocb_cmd.u.nvme.desc = rsp_buf; + sp->u.iocb_cmd.u.nvme.cmd = cmd; + + ctio = (struct ctio_nvme_to_27xx *)qla2x00_alloc_iocbs (vha, sp); +if (!ctio) { +ql_dbg (ql_dbg_nvme, vha,0x3067 , +"qla2x00t(%ld): %s failed: unable to allocate request packet" , + vha->host_no, __func__); +spin_unlock_irqrestore (&ha->hardware_lock, flags); +return ; + } + + ctio->entry_type =CTIO_NVME ; + ctio->entry_count =1 ; + ctio->handle = sp->handle; + ctio->nport_handle =cpu_to_le16 (cmd->fcport->loop_id); + ctio->timeout =cpu_to_le16 (QLA_TGT_TIMEOUT ); + ctio->vp_index = vha->vp_idx; + ctio->initiator_id[0 ] = fchdr->s_id[2 ]; + ctio->initiator_id[1 ] = fchdr->s_id[1 ]; + ctio->initiator_id[2 ] = fchdr->s_id[0 ]; + ctio->exchange_addr = atio->u.nvme_isp27.exchange_addr; + temp =be16_to_cpu (fchdr->ox_id); + ctio->ox_id =cpu_to_le16 (temp); + tot_dsds = ctio->dseg_count =cpu_to_le16 (rsp_buf->sg_cnt); + c_flags = atio->u.nvme_isp27.attr <<9 ; + +if ((ctio->dseg_count >1 ) && (rsp_buf->op !=NVMET_FCOP_RSP )) { +/* Check for additional continuation IOCB space */ + req_cnt =qla24xx_calc_iocbs (vha, ctio->dseg_count); + ctio->entry_count = req_cnt; + +if (req->cnt < (req_cnt +2 )) { + cnt = (uint16_t )RD_REG_DWORD_RELAXED (req->req_q_out); + +if (req->ring_index < cnt) + req->cnt = cnt - req->ring_index; +else + req->cnt = req->length - + (req->ring_index - cnt); + +if (unlikely (req->cnt < (req_cnt +2 ))) { +ql_log (ql_log_warn, vha,0xfff , +"Running out of IOCB space for continuation IOCBs\n" ); + goto err_exit; + } + } + } + +switch (rsp_buf->op) { +case NVMET_FCOP_READDATA : +case NVMET_FCOP_READDATA_RSP : +/* Populate the CTIO resp with the SGL present in the rsp */ +ql_log (ql_log_info, vha,0x1100c , +"op: %#x, ox_id=%x c_flags=%x transfer_length: %#x req_cnt: %#x, tot_dsds: %#x\n" , + rsp_buf->op, ctio->ox_id, c_flags, + rsp_buf->transfer_length, req_cnt, tot_dsds); + + avail_dsds =1 ; + cur_dsd = (uint32_t *) + &ctio->u.nvme_status_mode0.dsd0[0 ]; + sgl = rsp_buf->sg; + +/* Load data segments */ +for_each_sg (sgl, sg, tot_dsds, i) { +dma_addr_t sle_dma; +cont_a64_entry_t *cont_pkt; + +/* Allocate additional continuation packets? */ +if (avail_dsds ==0 ) { +/* +* Five DSDs are available in the Cont +* Type 1 IOCB. +*/ + +/* Adjust ring index */ + req->ring_index++; +if (req->ring_index == req->length) { + req->ring_index =0 ; + req->ring_ptr = req->ring; + }else { + req->ring_ptr++; + } + cont_pkt = (cont_a64_entry_t *) + req->ring_ptr; + *((uint32_t *)(&cont_pkt->entry_type)) = +cpu_to_le32 (CONTINUE_A64_TYPE ); + + cur_dsd = (uint32_t *) + cont_pkt->dseg_0_address; + avail_dsds =5 ; + } + + sle_dma =sg_dma_address (sg); + *cur_dsd++ =cpu_to_le32 (LSD (sle_dma)); + *cur_dsd++ =cpu_to_le32 (MSD (sle_dma)); + *cur_dsd++ =cpu_to_le32 (sg_dma_len (sg)); + avail_dsds--; + } + + ctio->u.nvme_status_mode0.transfer_len = +cpu_to_le32 (rsp_buf->transfer_length); + ctio->u.nvme_status_mode0.relative_offset = +cpu_to_le32 (rsp_buf->offset); + ctio->flags =cpu_to_le16 (c_flags |0x2 ); + +if (rsp_buf->op ==NVMET_FCOP_READDATA_RSP ) { +if (rsp_buf->rsplen ==12 ) { + ctio->flags |= +NVMET_CTIO_STS_MODE0 | +NVMET_CTIO_SEND_STATUS ; + }else if (rsp_buf->rsplen ==32 ) { +struct nvme_fc_ersp_iu *ersp = + rsp_buf->rspaddr; +uint32_t iter =4 , *inbuf, *outbuf; + + ctio->flags |= +NVMET_CTIO_STS_MODE1 | +NVMET_CTIO_SEND_STATUS ; + inbuf = (uint32_t *) + &((uint8_t *)rsp_buf->rspaddr)[16 ]; + outbuf = (uint32_t *) + ctio->u.nvme_status_mode1.nvme_comp_q_entry; +for (; iter; iter--) + *outbuf++ =cpu_to_be32 (*inbuf++); + + ctio->u.nvme_status_mode1.rsp_seq_num = +cpu_to_be32 (ersp->rsn); + ctio->u.nvme_status_mode1.transfer_len = +cpu_to_be32 (ersp->xfrd_len); + }else +ql_log (ql_log_warn, vha,0x1100d , +"unhandled resp len = %x\n" , + rsp_buf->rsplen); + } +break ; + +case NVMET_FCOP_WRITEDATA : +/* Send transfer rdy */ +ql_log (ql_log_info, vha,0x1100e , +"FCOP_WRITE: ox_id=%x c_flags=%x transfer_length: %#x req_cnt: %#x, tot_dsds: %#x\n" , + ctio->ox_id, c_flags, rsp_buf->transfer_length, + req_cnt, tot_dsds); + + ctio->flags =cpu_to_le16 (c_flags |0x1 ); + + avail_dsds =1 ; + cur_dsd = (uint32_t *)&ctio->u.nvme_status_mode0.dsd0[0 ]; + sgl = rsp_buf->sg; + +/* Load data segments */ +for_each_sg (sgl, sg, tot_dsds, i) { +dma_addr_t sle_dma; +cont_a64_entry_t *cont_pkt; + +/* Allocate additional continuation packets? */ +if (avail_dsds ==0 ) { +/* +* Five DSDs are available in the Continuation +* Type 1 IOCB. +*/ + +/* Adjust ring index */ + req->ring_index++; +if (req->ring_index == req->length) { + req->ring_index =0 ; + req->ring_ptr = req->ring; + }else { + req->ring_ptr++; + } + cont_pkt = (cont_a64_entry_t *)req->ring_ptr; + *((uint32_t *)(&cont_pkt->entry_type)) = +cpu_to_le32 (CONTINUE_A64_TYPE ); + + cur_dsd = (uint32_t *)cont_pkt->dseg_0_address; + avail_dsds =5 ; + } + + sle_dma =sg_dma_address (sg); + *cur_dsd++ =cpu_to_le32 (LSD (sle_dma)); + *cur_dsd++ =cpu_to_le32 (MSD (sle_dma)); + *cur_dsd++ =cpu_to_le32 (sg_dma_len (sg)); + avail_dsds--; + } + + ctio->u.nvme_status_mode0.transfer_len = +cpu_to_le32 (rsp_buf->transfer_length); + ctio->u.nvme_status_mode0.relative_offset = +cpu_to_le32 (rsp_buf->offset); + +break ; +case NVMET_FCOP_RSP : +/* Send a response frame */ + ctio->flags =cpu_to_le16 (c_flags); +if (rsp_buf->rsplen ==12 ) { + ctio->flags |= +NVMET_CTIO_STS_MODE0 |NVMET_CTIO_SEND_STATUS ; + }else if (rsp_buf->rsplen ==32 ) { +struct nvme_fc_ersp_iu *ersp = rsp_buf->rspaddr; +uint32_t iter =4 , *inbuf, *outbuf; + + ctio->flags |= +NVMET_CTIO_STS_MODE1 |NVMET_CTIO_SEND_STATUS ; + inbuf = (uint32_t *) + &((uint8_t *)rsp_buf->rspaddr)[16 ]; + outbuf = (uint32_t *) + ctio->u.nvme_status_mode1.nvme_comp_q_entry; +for (; iter; iter--) + *outbuf++ =cpu_to_be32 (*inbuf++); + ctio->u.nvme_status_mode1.rsp_seq_num = +cpu_to_be32 (ersp->rsn); + ctio->u.nvme_status_mode1.transfer_len = +cpu_to_be32 (ersp->xfrd_len); + +ql_log (ql_log_info, vha,0x1100f , +"op: %#x, rsplen: %#x\n" , rsp_buf->op, + rsp_buf->rsplen); + }else +ql_log (ql_log_warn, vha,0x11010 , +"unhandled resp len = %x for op NVMET_FCOP_RSP\n" , + rsp_buf->rsplen); +break ; + } + +/* Memory Barrier */ +wmb (); + +qla2x00_start_iocbs (vha, vha->hw->req_q_map[0 ]); +err_exit: +spin_unlock_irqrestore (&ha->hardware_lock, flags); +} + +/* +* qla_nvmet_send_abts_ctio +* Send the abts CTIO to the firmware +*/ +static void qla_nvmet_send_abts_ctio (struct scsi_qla_host *vha, +struct abts_recv_from_24xx *rabts,bool flag) +{ +struct abts_resp_to_24xx *resp; +srb_t *sp; +uint32_t f_ctl; +uint8_t *p; + +/* Alloc SRB structure */ + sp =qla2x00_get_sp (vha,NULL ,GFP_ATOMIC ); +if (!sp) { +ql_log (ql_log_info, vha,0x11011 ,"Failed to allocate SRB\n" ); +return ; + } + + sp->type =SRB_NVMET_ABTS ; + sp->name ="nvmet_abts" ; + sp->done = qla_nvmet_abts_done; + + resp = (struct abts_resp_to_24xx *)qla2x00_alloc_iocbs (vha, sp); +if (!resp) { +ql_dbg (ql_dbg_nvme, vha,0x3067 , +"qla2x00t(%ld): %s failed: unable to allocate request packet" , + vha->host_no, __func__); +return ; + } + + resp->entry_type =ABTS_RESP_24XX ; + resp->entry_count =1 ; + resp->handle = sp->handle; + + resp->nport_handle = rabts->nport_handle; + resp->vp_index = rabts->vp_index; + resp->exchange_address = rabts->exchange_addr_to_abort; + resp->fcp_hdr_le = rabts->fcp_hdr_le; + f_ctl =cpu_to_le32 (F_CTL_EXCH_CONTEXT_RESP | +F_CTL_LAST_SEQ |F_CTL_END_SEQ | +F_CTL_SEQ_INITIATIVE ); + p = (uint8_t *)&f_ctl; + resp->fcp_hdr_le.f_ctl[0 ] = *p++; + resp->fcp_hdr_le.f_ctl[1 ] = *p++; + resp->fcp_hdr_le.f_ctl[2 ] = *p; + + resp->fcp_hdr_le.d_id[0 ] = rabts->fcp_hdr_le.s_id[0 ]; + resp->fcp_hdr_le.d_id[1 ] = rabts->fcp_hdr_le.s_id[1 ]; + resp->fcp_hdr_le.d_id[2 ] = rabts->fcp_hdr_le.s_id[2 ]; + resp->fcp_hdr_le.s_id[0 ] = rabts->fcp_hdr_le.d_id[0 ]; + resp->fcp_hdr_le.s_id[1 ] = rabts->fcp_hdr_le.d_id[1 ]; + resp->fcp_hdr_le.s_id[2 ] = rabts->fcp_hdr_le.d_id[2 ]; + +if (flag) {/* BA_ACC */ + resp->fcp_hdr_le.r_ctl =R_CTL_BASIC_LINK_SERV |R_CTL_B_ACC ; + resp->payload.ba_acct.seq_id_valid =SEQ_ID_INVALID ; + resp->payload.ba_acct.low_seq_cnt =0x0000 ; + resp->payload.ba_acct.high_seq_cnt =0xFFFF ; + resp->payload.ba_acct.ox_id = rabts->fcp_hdr_le.ox_id; + resp->payload.ba_acct.rx_id = rabts->fcp_hdr_le.rx_id; + }else { + resp->fcp_hdr_le.r_ctl =R_CTL_BASIC_LINK_SERV |R_CTL_B_RJT ; + resp->payload.ba_rjt.reason_code = +BA_RJT_REASON_CODE_UNABLE_TO_PERFORM ; + } +/* Memory Barrier */ +wmb (); + +qla2x00_start_iocbs (vha, vha->hw->req_q_map[0 ]); +} +#endif
drivers/scsi/qla2xxx/qla_nvmet.h new file +130 -0
130 lines not on this page · raw message
Signature · 1 line
2.12.0
PATCH v2 1/4 qla2xxx_nvmet: Add files for FC-NVMe Target support
Quoted 6 lines · Himanshu Madhani
drivers/scsi/qla2xxx/qla_nvmet.c new file +5
-0+static struct nvmet_fc_target_template qla_nvmet_fc_transport = { + .targetport_delete = qla_nvmet_targetport_delete, + .xmt_ls_rsp = qla_nvmet_ls_rsp, + .fcp_op = qla_nvmet_fcp_op, + .fcp_abort = qla_nvmet_fcp_abort,
drivers/scsi/qla2xxx/qla_nvmet.c line 212
Quoted 10 lines
drivers/scsi/qla2xxx/qla_nvmet.c new file +10
-0+ .fcp_req_release = qla_nvmet_fcp_req_release, + .max_hw_queues = 8, + .max_sgl_segments = 128, + .max_dif_sgl_segments = 64, + .dma_boundary = 0xFFFFFFFF, + .target_features =NVMET_FCTGTFEAT_READDATA_RSP | +NVMET_FCTGTFEAT_CMD_IN_ISR | + NVMET_FCTGTFEAT_OPDONE_IN_ISR, + .target_priv_sz = sizeof(struct nvme_private), +};
From the patch set prior:
Quoted 1 line
Agree we do nvme_fc* callbacks in deferred context, but without the
xxx_IN_ISR flag during NVMe Target template registration, we were running into crash due to recursive spin_lock held as part of CTIO response in our driver.
Can you look into removing this recursive spin lock ? ?? I don't think it's a good idea to be holding a spin lock when upcalling the transport.
-- james
PATCH v2 1/4 qla2xxx_nvmet: Add files for FC-NVMe Target support
Hi James,
Quoted 19 lines · James Smart
Quoted 6 lines · Himanshu Madhani
drivers/scsi/qla2xxx/qla_nvmet.c new file +5
-0+static struct nvmet_fc_target_template qla_nvmet_fc_transport = { + .targetport_delete = qla_nvmet_targetport_delete, + .xmt_ls_rsp = qla_nvmet_ls_rsp, + .fcp_op = qla_nvmet_fcp_op, + .fcp_abort = qla_nvmet_fcp_abort,drivers/scsi/qla2xxx/qla_nvmet.c line 212
Quoted 10 lines
drivers/scsi/qla2xxx/qla_nvmet.c new file +10
-0+ .fcp_req_release = qla_nvmet_fcp_req_release, + .max_hw_queues = 8, + .max_sgl_segments = 128, + .max_dif_sgl_segments = 64, + .dma_boundary = 0xFFFFFFFF, + .target_features =NVMET_FCTGTFEAT_READDATA_RSP | +NVMET_FCTGTFEAT_CMD_IN_ISR | + NVMET_FCTGTFEAT_OPDONE_IN_ISR, + .target_priv_sz = sizeof(struct nvme_private), +};From the patch set prior:
Quoted 7 lines
Quoted 1 line
Agree we do nvme_fc* callbacks in deferred context, but without the
xxx_IN_ISRflag during NVMe Target template registration, we were running into crash due to recursivespin_lockheld as part of CTIO response in our driver.Can you look into removing this recursive spin lock ? ?? I don't think it's a good idea to be holding a spin lock when upcalling the transport.
Yes, Will work on removing spin lock.
Quoted 3 lines
-- james
PATCH v2 2/4 qla2xxx_nvmet: Added Makefile and Kconfig changes
In reply to Himanshu MadhaniFrom: Anil Gurumurthy <[email protected]>
--- drivers/scsi/qla2xxx/Kconfig | 1 + drivers/scsi/qla2xxx/Makefile | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-)
drivers/scsi/qla2xxx/Kconfig +1 -0
@@ -3,6 +3,7 @@ config SCSI_QLA_FC depends on PCI && SCSI depends on SCSI_FC_ATTRS depends on NVME_FC || !NVME_FC + depends on NVME_TARGET_FC || !NVME_TARGET_FC select FW_LOADER select BTREE ---help---
drivers/scsi/qla2xxx/Makefile +2 -1
@@ -1,6 +1,7 @@ qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \ qla_dbg.o qla_sup.o qla_attr.o qla_mid.o qla_dfs.o qla_bsg.o \ - qla_nx.o qla_mr.o qla_nx2.o qla_target.o qla_tmpl.o qla_nvme.o + qla_nx.o qla_mr.o qla_nx2.o qla_target.o qla_tmpl.o qla_nvme.o \ + qla_nvmet.o obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx.o obj-$(CONFIG_TCM_QLA2XXX) += tcm_qla2xxx.o
Signature · 1 line
2.12.0
PATCH v2 3/4 qla2xxx_nvmet: Add FC-NVMe Target LS request handling
In reply to Himanshu MadhaniFrom: Anil Gurumurthy <[email protected]>
--- drivers/scsi/qla2xxx/qla_dbg.c | 1 + drivers/scsi/qla2xxx/qla_dbg.h | 2 ++ drivers/scsi/qla2xxx/qla_iocb.c | 42 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 44 insertions(+), 1 deletion(-)
drivers/scsi/qla2xxx/qla_dbg.c +1 -0
@@ -67,6 +67,7 @@* | Target Mode Management | 0xf09b | 0xf002 | * | | | 0xf046-0xf049 | * | Target Mode Task Management | 0x1000d | | +* | NVME | 0x11000 | | * ---------------------------------------------------------------------- */
drivers/scsi/qla2xxx/qla_dbg.h +2 -0
@@ -367,6 +367,8 @@ ql_log_qp(uint32_t, struct qla_qpair *, int32_t, const char *fmt, ...);#define ql_dbg_tgt_tmr 0x00001000/* Target mode task management */ #define ql_dbg_tgt_dif 0x00000800/* Target mode dif */ +#define ql_dbg_nvme 0x00000400/* NVME Target */ +extern int qla27xx_dump_mpi_ram (struct qla_hw_data *,uint32_t ,uint32_t *,uint32_t ,void **); extern int qla24xx_dump_ram(struct qla_hw_data *, uint32_t, uint32_t *,
drivers/scsi/qla2xxx/qla_iocb.c +41 -1
66 lines not on this page · raw message
Signature · 1 line
2.12.0
PATCH v2 4/4 qla2xxx_nvmet: Add FC-NVMe Target handling
In reply to Himanshu MadhaniFrom: Anil Gurumurthy <[email protected]>
This patch Adds following code in the driver to
support FC-NVMe Target
- Updated ql2xenablenvme to allow FC-NVMe Target operation
- Added LS Request handling for NVMe Target
- Added passthr IOCB for LS4 request
- Added CTIO for sending response to FW
- Added FC4 Registration for FC-NVMe Target
- Added PUREX IOCB support for login processing in FC-NVMe Target mode
- Added Continuation IOCB for PUREX
- Added Session creation with PUREX IOCB in FC-NVMe Target mode
--- drivers/scsi/qla2xxx/qla_def.h | 35 +- drivers/scsi/qla2xxx/qla_fw.h | 263 +++++++++++ drivers/scsi/qla2xxx/qla_gbl.h | 17 +- drivers/scsi/qla2xxx/qla_gs.c | 15 +- drivers/scsi/qla2xxx/qla_init.c | 49 +- drivers/scsi/qla2xxx/qla_isr.c | 70 +++ drivers/scsi/qla2xxx/qla_mbx.c | 100 +++- drivers/scsi/qla2xxx/qla_nvme.h | 33 -- drivers/scsi/qla2xxx/qla_os.c | 75 ++- drivers/scsi/qla2xxx/qla_target.c | 932 +++++++++++++++++++++++++++++++++++++- drivers/scsi/qla2xxx/qla_target.h | 93 +++- 11 files changed, 1625 insertions(+), 57 deletions(-)
drivers/scsi/qla2xxx/qla_def.h +34 -1
@@ -447,13 +447,21 @@ struct srb_iocb {uint32_t dl;uint32_t timeout_sec;struct list_head entry; +uint32_t exchange_address; +uint16_t nport_handle; +uint8_t vp_index; +void *cmd; } nvme; } u;struct timer_list timer;void (*timeout)(void *); }; - +struct srb_nvme_els_rsp { +dma_addr_t dma_addr; +void *dma_ptr; +void *ptr; +};/* Values for srb_ctx type */ #define SRB_LOGIN_CMD 1#define SRB_LOGOUT_CMD 2
@@ -476,6 +484,11 @@ struct srb_iocb {#define SRB_NVME_CMD 19#define SRB_NVME_LS 20#define SRB_PRLI_CMD 21 +#define SRB_NVME_ELS_RSP 22 +#define SRB_NVMET_LS 23 +#define SRB_NVMET_FCP 24 +#define SRB_NVMET_ABTS 25 +#define SRB_NVMET_SEND_ABTS 26enum {TYPE_SRB ,
@@ -505,6 +518,7 @@ typedef struct srb {struct srb_iocb iocb_cmd;struct bsg_job *bsg_job;struct srb_cmd scmd; +struct srb_nvme_els_rsp snvme_els; } u;void (*done)(void *,int );void (*free)(void *);
@@ -2250,6 +2264,15 @@ struct qlt_plogi_ack_t {void *fcport; }; +/* NVMET */ +struct qlt_purex_plogi_ack_t { +struct list_head list; +struct __fc_plogi rcvd_plogi; +port_id_t id; +int ref_count; +void *fcport; +}; +struct ct_sns_desc {struct ct_sns_pkt *ct_sns;dma_addr_t ct_sns_dma;
@@ -2346,6 +2369,8 @@ typedef struct fc_port {struct work_struct free_work;struct qlt_plogi_ack_t *plogi_link[QLT_PLOGI_LINK_MAX ]; +/* NVMET */ +struct qlt_purex_plogi_ack_t *purex_plogi_link[QLT_PLOGI_LINK_MAX ];uint16_t tgt_id;uint16_t old_tgt_id;
@@ -3125,6 +3150,7 @@ enum qla_work_type {QLA_EVT_UPD_FCPORT ,QLA_EVT_GNL ,QLA_EVT_NACK , + QLA_EVT_NEW_NVMET_SESS, };
@@ -4097,6 +4123,7 @@ typedef struct scsi_qla_host { uint32_t qpairs_req_created:1; uint32_t qpairs_rsp_created:1; uint32_t nvme_enabled:1; + uint32_t nvmet_enabled:1; } flags;atomic_t loop_state;
@@ -4139,6 +4166,7 @@ typedef struct scsi_qla_host {#define SET_ZIO_THRESHOLD_NEEDED 28#define DETECT_SFP_CHANGE 29#define N2N_LOGIN_NEEDED 30 +#define NVMET_PUREX 31unsigned long pci_flags;#define PFLG_DISCONNECTED 0/* PCI device removed */
@@ -4179,6 +4207,7 @@ typedef struct scsi_qla_host {uint8_t fabric_node_name[WWN_SIZE ];struct nvme_fc_local_port *nvme_local_port; +struct nvmet_fc_target_port *targetport;struct completion nvme_del_done;struct list_head nvme_rport_list;atomic_t nvme_active_aen_cnt;
@@ -4252,6 +4281,9 @@ typedef struct scsi_qla_host {uint8_t n2n_node_name[WWN_SIZE ];uint8_t n2n_port_name[WWN_SIZE ];uint16_t n2n_id; +/*NVMET*/ +struct list_head purex_atio_list; +struct completion purex_plogi_sess; } scsi_qla_host_t;struct qla27xx_image_status {
@@ -4512,6 +4544,7 @@ struct sff_8247_a0 { (IS_QLA27XX(_ha) || IS_QLA83XX(_ha)))#include "qla_target.h" +#include "qla_nvmet.h" #include "qla_gbl.h" #include "qla_dbg.h" #include "qla_inline.h"
drivers/scsi/qla2xxx/qla_fw.h +263 -0
269 lines not on this page · raw message
drivers/scsi/qla2xxx/qla_gbl.h +15 -2
@@ -299,7 +299,10 @@ extern int qla2x00_set_fw_options(scsi_qla_host_t *, uint16_t *);extern int -qla2x00_mbx_reg_test (scsi_qla_host_t *); +qla2x00_set_purex_mode (scsi_qla_host_t *vha); + +extern int +qla2x00_mbx_reg_test (scsi_qla_host_t *vha);extern int qla2x00_verify_checksum (scsi_qla_host_t *,uint32_t );
@@ -874,6 +877,16 @@ void qlt_update_host_map(struct scsi_qla_host *, port_id_t);void qlt_remove_target_resources (struct qla_hw_data *);void qlt_clr_qp_table (struct scsi_qla_host *vha); +extern int qla2x00_get_plogi_template (scsi_qla_host_t *vha,dma_addr_t buf, +uint16_t length); +extern void qlt_dequeue_purex (struct scsi_qla_host *vha); +int qla24xx_post_nvmet_newsess_work (struct scsi_qla_host *vha,port_id_t *id, +u8 *port_name,void *pla); +int qlt_send_els_resp (srb_t *sp,struct __els_pt *pkt); +extern void nvmet_release_sessions (struct scsi_qla_host *vha); +struct fc_port *qla_nvmet_find_sess_by_s_id (scsi_qla_host_t *vha, +const uint32_t s_id);void qla_nvme_cmpl_io (struct srb_iocb *); - +void qla24xx_nvmet_abts_resp_iocb (struct scsi_qla_host *vha, +struct abts_resp_to_24xx *pkt,struct req_que *req);#endif /* _QLA_GBL_H */
drivers/scsi/qla2xxx/qla_gs.c +10 -5
@@ -548,9 +548,10 @@ qla2x00_rft_id(scsi_qla_host_t *vha) ct_req->req.rft_id.port_id[1 ] = vha->d_id.b.area; ct_req->req.rft_id.port_id[2 ] = vha->d_id.b.al_pa; - ct_req->req.rft_id.fc4_types[2 ] =0x01 ;/* FCP-3 */ +if (!vha->flags.nvmet_enabled) + ct_req->req.rft_id.fc4_types[2 ] =0x01 ;/* FCP-3 */ -if (vha->flags.nvme_enabled) +if (vha->flags.nvme_enabled || vha->flags.nvmet_enabled) ct_req->req.rft_id.fc4_types[6 ] =1 ;/* NVMe type 28h */ /* Execute MS IOCB */ rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
@@ -592,6 +593,10 @@ qla2x00_rff_id(scsi_qla_host_t *vha, u8 type)return (QLA_SUCCESS ); } +/* only single mode for now */ +if ((vha->flags.nvmet_enabled) && (type ==FC4_TYPE_FCP_SCSI )) +return (QLA_SUCCESS ); + arg.iocb = ha->ms_iocb; arg.req_dma = ha->ct_sns_dma; arg.rsp_dma = ha->ct_sns_dma;
@@ -613,7 +618,7 @@ qla2x00_rff_id(scsi_qla_host_t *vha, u8 type) ct_req->req.rff_id.port_id[1 ] = vha->d_id.b.area; ct_req->req.rff_id.port_id[2 ] = vha->d_id.b.al_pa; -qlt_rff_id (vha, ct_req); +qlt_rff_id (vha, ct_req, type); ct_req->req.rff_id.fc4_type = type;/* SCSI - FCP */
@@ -2166,7 +2171,7 @@ qla2x00_fdmiv2_rpa(scsi_qla_host_t *vha) eiter->a.fc4_types[2 ], eiter->a.fc4_types[1]); -if (vha->flags.nvme_enabled) { +if (vha->flags.nvme_enabled || vha->flags.nvmet_enabled) { eiter->a.fc4_types[6 ] =1 ;/* NVMe type 28h */ ql_dbg(ql_dbg_disc, vha, 0x211f, "NVME FC4 Type = %02x 0x0 0x0 0x0 0x0 0x0.\n",
@@ -2370,7 +2375,7 @@ qla2x00_fdmiv2_rpa(scsi_qla_host_t *vha)"Port Active FC4 Type = %02x %02x.\n" , eiter->a.port_fc4_type[2], eiter->a.port_fc4_type[1]); -if (vha->flags.nvme_enabled) { +if (vha->flags.nvme_enabled || vha->flags.nvmet_enabled) { eiter->a.port_fc4_type[4 ] =0 ; eiter->a.port_fc4_type[5 ] =0 ; eiter->a.port_fc4_type[6 ] =1 ;/* NVMe type 28h */
drivers/scsi/qla2xxx/qla_init.c +44 -5
99 lines not on this page · raw message
drivers/scsi/qla2xxx/qla_isr.c +70 -0
104 lines not on this page · raw message
drivers/scsi/qla2xxx/qla_mbx.c +99 -1
120 lines not on this page · raw message
drivers/scsi/qla2xxx/qla_nvme.h +0 -33
@@ -103,39 +103,6 @@ struct pt_ls4_request {uint32_t dseg1_address[2 ];uint32_t dseg1_len; }; - -#define PT_LS4_UNSOL 0x56/* pass-up unsolicited rec FC-NVMe request */ -struct pt_ls4_rx_unsol { -uint8_t entry_type; -uint8_t entry_count; -uint16_t rsvd0; -uint16_t rsvd1; -uint8_t vp_index; -uint8_t rsvd2; -uint16_t rsvd3; -uint16_t nport_handle; -uint16_t frame_size; -uint16_t rsvd4; -uint32_t exchange_address; -uint8_t d_id[3 ]; -uint8_t r_ctl; -uint8_t s_id[3 ]; -uint8_t cs_ctl; -uint8_t f_ctl[3 ]; -uint8_t type; -uint16_t seq_cnt; -uint8_t df_ctl; -uint8_t seq_id; -uint16_t rx_id; -uint16_t ox_id; -uint32_t param; -uint32_t desc0; -#define PT_LS4_PAYLOAD_OFFSET 0x2c -#define PT_LS4_FIRST_PACKET_LEN 20 -uint32_t desc_len; -uint32_t payload[3 ]; -}; -/* * Global functions prototype in qla_nvme.c source file. */
drivers/scsi/qla2xxx/qla_os.c +73 -2
116 lines not on this page · raw message
drivers/scsi/qla2xxx/qla_target.c +925 -7
1,093 lines not on this page · raw message
drivers/scsi/qla2xxx/qla_target.h +92 -1
127 lines not on this page · raw message
Signature · 1 line
2.12.0
Christoph Hellwig
maintainerv2 cover qla2xxx: Add FC-NVMe Target support
In reply to Himanshu MadhaniBefore even looking at the patches: they seem to add a lot of new sparse warnings, mostly about endianess issues. Given that FC-NVMe is a mix of BE and LE structures getting this right is important. Please fix them up first.
v2 cover qla2xxx: Add FC-NVMe Target support
Quoted 7 lines · Christoph Hellwig
Before even looking at the patches: they seem to add a lot of new sparse warnings, mostly about endianess issues. Given that FC-NVMe is a mix of BE and LE structures getting this right is important. Please fix them up first.
Sure, will fix up endianess warnings and resubmit patches.
Thanks,
Himanshu