Commit f3505013 authored by Jitendra Bhivare's avatar Jitendra Bhivare Committed by Martin K. Petersen

scsi: be2iscsi: Fix use of invalidate command table req

Remove shared structure inv_tbl in phba for all sessions to post
invalidation IOCTL.
Always allocate and then free the table after use in reset handler.
Abort handler needs just one instance so define it on stack.
Add checks for BE_INVLDT_CMD_TBL_SZ to not exceed invalidation
command table size in IOCTL.
Signed-off-by: default avatarJitendra Bhivare <jitendra.bhivare@broadcom.com>
Reviewed-by: default avatarHannes Reinecke <hare@suse.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 19099dc3
...@@ -225,9 +225,9 @@ static int beiscsi_eh_abort(struct scsi_cmnd *sc) ...@@ -225,9 +225,9 @@ static int beiscsi_eh_abort(struct scsi_cmnd *sc)
struct beiscsi_conn *beiscsi_conn; struct beiscsi_conn *beiscsi_conn;
struct beiscsi_hba *phba; struct beiscsi_hba *phba;
struct iscsi_session *session; struct iscsi_session *session;
struct invalidate_command_table *inv_tbl; struct invldt_cmd_tbl inv_tbl;
struct be_dma_mem nonemb_cmd; struct be_dma_mem nonemb_cmd;
unsigned int cid, tag, num_invalidate; unsigned int cid, tag;
int rc; int rc;
cls_session = starget_to_session(scsi_target(sc->device)); cls_session = starget_to_session(scsi_target(sc->device));
...@@ -247,35 +247,30 @@ static int beiscsi_eh_abort(struct scsi_cmnd *sc) ...@@ -247,35 +247,30 @@ static int beiscsi_eh_abort(struct scsi_cmnd *sc)
return SUCCESS; return SUCCESS;
} }
spin_unlock_bh(&session->frwd_lock); spin_unlock_bh(&session->frwd_lock);
/* Invalidate WRB Posted for this Task */
AMAP_SET_BITS(struct amap_iscsi_wrb, invld,
aborted_io_task->pwrb_handle->pwrb,
1);
conn = aborted_task->conn; conn = aborted_task->conn;
beiscsi_conn = conn->dd_data; beiscsi_conn = conn->dd_data;
phba = beiscsi_conn->phba; phba = beiscsi_conn->phba;
/* Invalidate WRB Posted for this Task */
AMAP_SET_BITS(struct amap_iscsi_wrb, invld,
aborted_io_task->pwrb_handle->pwrb,
1);
/* invalidate iocb */ /* invalidate iocb */
cid = beiscsi_conn->beiscsi_conn_cid; cid = beiscsi_conn->beiscsi_conn_cid;
inv_tbl = phba->inv_tbl; inv_tbl.cid = cid;
memset(inv_tbl, 0x0, sizeof(*inv_tbl)); inv_tbl.icd = aborted_io_task->psgl_handle->sgl_index;
inv_tbl->cid = cid; nonemb_cmd.size = sizeof(union be_invldt_cmds_params);
inv_tbl->icd = aborted_io_task->psgl_handle->sgl_index; nonemb_cmd.va = pci_zalloc_consistent(phba->ctrl.pdev,
num_invalidate = 1; nonemb_cmd.size,
nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev, &nonemb_cmd.dma);
sizeof(struct invalidate_commands_params_in),
&nonemb_cmd.dma);
if (nonemb_cmd.va == NULL) { if (nonemb_cmd.va == NULL) {
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_EH, beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_EH,
"BM_%d : Failed to allocate memory for" "BM_%d : Failed to allocate memory for"
"mgmt_invalidate_icds\n"); "mgmt_invalidate_icds\n");
return FAILED; return FAILED;
} }
nonemb_cmd.size = sizeof(struct invalidate_commands_params_in);
tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, tag = mgmt_invalidate_icds(phba, &inv_tbl, 1, cid, &nonemb_cmd);
cid, &nonemb_cmd);
if (!tag) { if (!tag) {
beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_EH, beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_EH,
"BM_%d : mgmt_invalidate_icds could not be" "BM_%d : mgmt_invalidate_icds could not be"
...@@ -303,10 +298,10 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc) ...@@ -303,10 +298,10 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc)
struct beiscsi_hba *phba; struct beiscsi_hba *phba;
struct iscsi_session *session; struct iscsi_session *session;
struct iscsi_cls_session *cls_session; struct iscsi_cls_session *cls_session;
struct invalidate_command_table *inv_tbl; struct invldt_cmd_tbl *inv_tbl;
struct be_dma_mem nonemb_cmd; struct be_dma_mem nonemb_cmd;
unsigned int cid, tag, i, num_invalidate; unsigned int cid, tag, i, nents;
int rc; int rc, more = 0;
/* invalidate iocbs */ /* invalidate iocbs */
cls_session = starget_to_session(scsi_target(sc->device)); cls_session = starget_to_session(scsi_target(sc->device));
...@@ -320,9 +315,15 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc) ...@@ -320,9 +315,15 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc)
beiscsi_conn = conn->dd_data; beiscsi_conn = conn->dd_data;
phba = beiscsi_conn->phba; phba = beiscsi_conn->phba;
cid = beiscsi_conn->beiscsi_conn_cid; cid = beiscsi_conn->beiscsi_conn_cid;
inv_tbl = phba->inv_tbl;
memset(inv_tbl, 0x0, sizeof(*inv_tbl) * BE2_CMDS_PER_CXN); inv_tbl = kcalloc(BE_INVLDT_CMD_TBL_SZ, sizeof(*inv_tbl), GFP_KERNEL);
num_invalidate = 0; if (!inv_tbl) {
spin_unlock_bh(&session->frwd_lock);
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_EH,
"BM_%d : invldt_cmd_tbl alloc failed\n");
return FAILED;
}
nents = 0;
for (i = 0; i < conn->session->cmds_max; i++) { for (i = 0; i < conn->session->cmds_max; i++) {
abrt_task = conn->session->cmds[i]; abrt_task = conn->session->cmds[i];
abrt_io_task = abrt_task->dd_data; abrt_io_task = abrt_task->dd_data;
...@@ -331,33 +332,47 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc) ...@@ -331,33 +332,47 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc)
if (sc->device->lun != abrt_task->sc->device->lun) if (sc->device->lun != abrt_task->sc->device->lun)
continue; continue;
/**
* Can't fit in more cmds? Normally this won't happen b'coz
* BEISCSI_CMD_PER_LUN is same as BE_INVLDT_CMD_TBL_SZ.
*/
if (nents == BE_INVLDT_CMD_TBL_SZ) {
more = 1;
break;
}
/* Invalidate WRB Posted for this Task */ /* Invalidate WRB Posted for this Task */
AMAP_SET_BITS(struct amap_iscsi_wrb, invld, AMAP_SET_BITS(struct amap_iscsi_wrb, invld,
abrt_io_task->pwrb_handle->pwrb, abrt_io_task->pwrb_handle->pwrb,
1); 1);
inv_tbl->cid = cid; inv_tbl[nents].cid = cid;
inv_tbl->icd = abrt_io_task->psgl_handle->sgl_index; inv_tbl[nents].icd = abrt_io_task->psgl_handle->sgl_index;
num_invalidate++; nents++;
inv_tbl++;
} }
spin_unlock_bh(&session->frwd_lock); spin_unlock_bh(&session->frwd_lock);
inv_tbl = phba->inv_tbl;
nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev, if (more) {
sizeof(struct invalidate_commands_params_in), beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_EH,
&nonemb_cmd.dma); "BM_%d : number of cmds exceeds size of invalidation table\n");
kfree(inv_tbl);
return FAILED;
}
nonemb_cmd.size = sizeof(union be_invldt_cmds_params);
nonemb_cmd.va = pci_zalloc_consistent(phba->ctrl.pdev,
nonemb_cmd.size,
&nonemb_cmd.dma);
if (nonemb_cmd.va == NULL) { if (nonemb_cmd.va == NULL) {
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_EH, beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_EH,
"BM_%d : Failed to allocate memory for" "BM_%d : Failed to allocate memory for"
"mgmt_invalidate_icds\n"); "mgmt_invalidate_icds\n");
kfree(inv_tbl);
return FAILED; return FAILED;
} }
nonemb_cmd.size = sizeof(struct invalidate_commands_params_in); tag = mgmt_invalidate_icds(phba, inv_tbl, nents,
memset(nonemb_cmd.va, 0, nonemb_cmd.size);
tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate,
cid, &nonemb_cmd); cid, &nonemb_cmd);
kfree(inv_tbl);
if (!tag) { if (!tag) {
beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_EH, beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_EH,
"BM_%d : mgmt_invalidate_icds could not be" "BM_%d : mgmt_invalidate_icds could not be"
......
...@@ -57,7 +57,6 @@ ...@@ -57,7 +57,6 @@
#define BE2_IO_DEPTH 1024 #define BE2_IO_DEPTH 1024
#define BE2_MAX_SESSIONS 256 #define BE2_MAX_SESSIONS 256
#define BE2_CMDS_PER_CXN 128
#define BE2_TMFS 16 #define BE2_TMFS 16
#define BE2_NOPOUT_REQ 16 #define BE2_NOPOUT_REQ 16
#define BE2_SGE 32 #define BE2_SGE 32
...@@ -72,8 +71,13 @@ ...@@ -72,8 +71,13 @@
#define BEISCSI_SGLIST_ELEMENTS 30 #define BEISCSI_SGLIST_ELEMENTS 30
#define BEISCSI_CMD_PER_LUN 128 /* scsi_host->cmd_per_lun */ /**
#define BEISCSI_MAX_SECTORS 1024 /* scsi_host->max_sectors */ * BE_INVLDT_CMD_TBL_SZ is 128 which is total number commands that can
* be invalidated at a time, consider it before changing the value of
* BEISCSI_CMD_PER_LUN.
*/
#define BEISCSI_CMD_PER_LUN 128 /* scsi_host->cmd_per_lun */
#define BEISCSI_MAX_SECTORS 1024 /* scsi_host->max_sectors */
#define BEISCSI_TEMPLATE_HDR_PER_CXN_SIZE 128 /* Template size per cxn */ #define BEISCSI_TEMPLATE_HDR_PER_CXN_SIZE 128 /* Template size per cxn */
#define BEISCSI_MAX_CMD_LEN 16 /* scsi_host->max_cmd_len */ #define BEISCSI_MAX_CMD_LEN 16 /* scsi_host->max_cmd_len */
...@@ -272,11 +276,6 @@ struct hba_parameters { ...@@ -272,11 +276,6 @@ struct hba_parameters {
unsigned int num_sge; unsigned int num_sge;
}; };
struct invalidate_command_table {
unsigned short icd;
unsigned short cid;
} __packed;
#define BEISCSI_GET_ULP_FROM_CRI(phwi_ctrlr, cri) \ #define BEISCSI_GET_ULP_FROM_CRI(phwi_ctrlr, cri) \
(phwi_ctrlr->wrb_context[cri].ulp_num) (phwi_ctrlr->wrb_context[cri].ulp_num)
struct hwi_wrb_context { struct hwi_wrb_context {
...@@ -430,7 +429,6 @@ struct beiscsi_hba { ...@@ -430,7 +429,6 @@ struct beiscsi_hba {
struct be_ctrl_info ctrl; struct be_ctrl_info ctrl;
unsigned int generation; unsigned int generation;
unsigned int interface_handle; unsigned int interface_handle;
struct invalidate_command_table inv_tbl[128];
struct be_aic_obj aic_obj[MAX_CPUS]; struct be_aic_obj aic_obj[MAX_CPUS];
unsigned int attr_log_enable; unsigned int attr_log_enable;
......
...@@ -129,7 +129,7 @@ unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl, ...@@ -129,7 +129,7 @@ unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl,
} }
unsigned int mgmt_invalidate_icds(struct beiscsi_hba *phba, unsigned int mgmt_invalidate_icds(struct beiscsi_hba *phba,
struct invalidate_command_table *inv_tbl, struct invldt_cmd_tbl *inv_tbl,
unsigned int num_invalidate, unsigned int cid, unsigned int num_invalidate, unsigned int cid,
struct be_dma_mem *nonemb_cmd) struct be_dma_mem *nonemb_cmd)
...@@ -137,9 +137,12 @@ unsigned int mgmt_invalidate_icds(struct beiscsi_hba *phba, ...@@ -137,9 +137,12 @@ unsigned int mgmt_invalidate_icds(struct beiscsi_hba *phba,
struct be_ctrl_info *ctrl = &phba->ctrl; struct be_ctrl_info *ctrl = &phba->ctrl;
struct be_mcc_wrb *wrb; struct be_mcc_wrb *wrb;
struct be_sge *sge; struct be_sge *sge;
struct invalidate_commands_params_in *req; struct invldt_cmds_params_in *req;
unsigned int i, tag; unsigned int i, tag;
if (num_invalidate > BE_INVLDT_CMD_TBL_SZ)
return 0;
mutex_lock(&ctrl->mbox_lock); mutex_lock(&ctrl->mbox_lock);
wrb = alloc_mcc_wrb(phba, &tag); wrb = alloc_mcc_wrb(phba, &tag);
if (!wrb) { if (!wrb) {
...@@ -158,10 +161,9 @@ unsigned int mgmt_invalidate_icds(struct beiscsi_hba *phba, ...@@ -158,10 +161,9 @@ unsigned int mgmt_invalidate_icds(struct beiscsi_hba *phba,
req->ref_handle = 0; req->ref_handle = 0;
req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE; req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE;
for (i = 0; i < num_invalidate; i++) { for (i = 0; i < num_invalidate; i++) {
req->table[i].icd = inv_tbl->icd; req->table[i].icd = inv_tbl[i].icd;
req->table[i].cid = inv_tbl->cid; req->table[i].cid = inv_tbl[i].cid;
req->icd_count++; req->icd_count++;
inv_tbl++;
} }
sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma)); sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF); sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
......
...@@ -104,10 +104,6 @@ int mgmt_open_connection(struct beiscsi_hba *phba, ...@@ -104,10 +104,6 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
unsigned int mgmt_upload_connection(struct beiscsi_hba *phba, unsigned int mgmt_upload_connection(struct beiscsi_hba *phba,
unsigned short cid, unsigned short cid,
unsigned int upload_flag); unsigned int upload_flag);
unsigned int mgmt_invalidate_icds(struct beiscsi_hba *phba,
struct invalidate_command_table *inv_tbl,
unsigned int num_invalidate, unsigned int cid,
struct be_dma_mem *nonemb_cmd);
unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl, unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl,
struct beiscsi_hba *phba, struct beiscsi_hba *phba,
struct bsg_job *job, struct bsg_job *job,
...@@ -134,24 +130,31 @@ union iscsi_invalidate_connection_params { ...@@ -134,24 +130,31 @@ union iscsi_invalidate_connection_params {
struct iscsi_invalidate_connection_params_out response; struct iscsi_invalidate_connection_params_out response;
} __packed; } __packed;
struct invalidate_commands_params_in { #define BE_INVLDT_CMD_TBL_SZ 128
struct invldt_cmd_tbl {
unsigned short icd;
unsigned short cid;
} __packed;
struct invldt_cmds_params_in {
struct be_cmd_req_hdr hdr; struct be_cmd_req_hdr hdr;
unsigned int ref_handle; unsigned int ref_handle;
unsigned int icd_count; unsigned int icd_count;
struct invalidate_command_table table[128]; struct invldt_cmd_tbl table[BE_INVLDT_CMD_TBL_SZ];
unsigned short cleanup_type; unsigned short cleanup_type;
unsigned short unused; unsigned short unused;
} __packed; } __packed;
struct invalidate_commands_params_out { struct invldt_cmds_params_out {
struct be_cmd_resp_hdr hdr;
unsigned int ref_handle; unsigned int ref_handle;
unsigned int icd_count; unsigned int icd_count;
unsigned int icd_status[128]; unsigned int icd_status[BE_INVLDT_CMD_TBL_SZ];
} __packed; } __packed;
union invalidate_commands_params { union be_invldt_cmds_params {
struct invalidate_commands_params_in request; struct invldt_cmds_params_in request;
struct invalidate_commands_params_out response; struct invldt_cmds_params_out response;
} __packed; } __packed;
struct mgmt_hba_attributes { struct mgmt_hba_attributes {
...@@ -231,16 +234,6 @@ struct be_bsg_vendor_cmd { ...@@ -231,16 +234,6 @@ struct be_bsg_vendor_cmd {
#define GET_MGMT_CONTROLLER_WS(phba) (phba->pmgmt_ws) #define GET_MGMT_CONTROLLER_WS(phba) (phba->pmgmt_ws)
/* MGMT CMD flags */
#define MGMT_CMDH_FREE (1<<0)
/* --- MGMT_ERROR_CODES --- */
/* Error Codes returned in the status field of the CMD response header */
#define MGMT_STATUS_SUCCESS 0 /* The CMD completed without errors */
#define MGMT_STATUS_FAILED 1 /* Error status in the Status field of */
/* the CMD_RESPONSE_HEADER */
#define ISCSI_GET_PDU_TEMPLATE_ADDRESS(pc, pa) {\ #define ISCSI_GET_PDU_TEMPLATE_ADDRESS(pc, pa) {\
pa->lo = phba->init_mem[ISCSI_MEM_GLOBAL_HEADER].mem_array[0].\ pa->lo = phba->init_mem[ISCSI_MEM_GLOBAL_HEADER].mem_array[0].\
bus_address.u.a32.address_lo; \ bus_address.u.a32.address_lo; \
...@@ -265,6 +258,11 @@ struct beiscsi_endpoint { ...@@ -265,6 +258,11 @@ struct beiscsi_endpoint {
u16 cid_vld; u16 cid_vld;
}; };
unsigned int mgmt_invalidate_icds(struct beiscsi_hba *phba,
struct invldt_cmd_tbl *inv_tbl,
unsigned int num_invalidate, unsigned int cid,
struct be_dma_mem *nonemb_cmd);
unsigned int mgmt_invalidate_connection(struct beiscsi_hba *phba, unsigned int mgmt_invalidate_connection(struct beiscsi_hba *phba,
struct beiscsi_endpoint *beiscsi_ep, struct beiscsi_endpoint *beiscsi_ep,
unsigned short cid, unsigned short cid,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment