Use the iscsi scsi_host_busy_iter helper so we are not digging into libiscsi structs and because the session cmds array is being removed. Signed-off-by: Mike Christie <michael.christie@xxxxxxxxxx> --- drivers/scsi/be2iscsi/be_main.c | 108 ++++++++++++++++++-------------- 1 file changed, 61 insertions(+), 47 deletions(-) diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index bcb12e674795..4d4e3d606e25 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -265,21 +265,63 @@ static int beiscsi_eh_abort(struct scsi_cmnd *sc) return iscsi_eh_abort(sc); } +struct beiscsi_invldt_cmd_tbl { + struct invldt_cmd_tbl tbl[BE_INVLDT_CMD_TBL_SZ]; + struct iscsi_task *task[BE_INVLDT_CMD_TBL_SZ]; +}; + +static bool beiscsi_dev_reset_sc_iter(struct scsi_cmnd *sc, void *data, + bool rsvd) +{ + struct iscsi_task *task = (struct iscsi_task *)sc->SCp.ptr; + struct iscsi_sc_iter_data *iter_data = data; + struct beiscsi_invldt_cmd_tbl *inv_tbl = iter_data->data; + struct beiscsi_conn *beiscsi_conn = iter_data->conn->dd_data; + struct beiscsi_hba *phba = beiscsi_conn->phba; + int nents = iter_data->rc; + struct beiscsi_io_task *io_task; + + /* + * 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 (iter_data->rc == BE_INVLDT_CMD_TBL_SZ) { + iter_data->rc = BE_INVLDT_CMD_TBL_SZ + 1; + return false; + } + + /* get a task ref till FW processes the req for the ICD used */ + __iscsi_get_task(task); + io_task = task->dd_data; + /* mark WRB invalid which have been not processed by FW yet */ + if (is_chip_be2_be3r(phba)) { + AMAP_SET_BITS(struct amap_iscsi_wrb, invld, + io_task->pwrb_handle->pwrb, 1); + } else { + AMAP_SET_BITS(struct amap_iscsi_wrb_v2, invld, + io_task->pwrb_handle->pwrb, 1); + } + + inv_tbl->tbl[nents].cid = beiscsi_conn->beiscsi_conn_cid; + inv_tbl->tbl[nents].icd = io_task->psgl_handle->sgl_index; + inv_tbl->task[nents] = task; + nents++; + + iter_data->rc = nents; + return true; +} + static int beiscsi_eh_device_reset(struct scsi_cmnd *sc) { - struct beiscsi_invldt_cmd_tbl { - struct invldt_cmd_tbl tbl[BE_INVLDT_CMD_TBL_SZ]; - struct iscsi_task *task[BE_INVLDT_CMD_TBL_SZ]; - } *inv_tbl; + struct iscsi_sc_iter_data iter_data; + struct beiscsi_invldt_cmd_tbl *inv_tbl; struct iscsi_cls_session *cls_session; struct beiscsi_conn *beiscsi_conn; - struct beiscsi_io_task *io_task; struct iscsi_session *session; struct beiscsi_hba *phba; struct iscsi_conn *conn; - struct iscsi_task *task; unsigned int i, nents; - int rc, more = 0; + int rc; cls_session = starget_to_session(scsi_target(sc->device)); session = cls_session->dd_data; @@ -302,56 +344,28 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc) "BM_%d : invldt_cmd_tbl alloc failed\n"); return FAILED; } - nents = 0; - /* take back_lock to prevent task from getting cleaned up under us */ - spin_lock(&session->back_lock); - for (i = 0; i < conn->session->cmds_max; i++) { - task = conn->session->cmds[i]; - if (!task->sc) - continue; - if (sc->device->lun != task->sc->device->lun) - 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; - } - - /* get a task ref till FW processes the req for the ICD used */ - __iscsi_get_task(task); - io_task = task->dd_data; - /* mark WRB invalid which have been not processed by FW yet */ - if (is_chip_be2_be3r(phba)) { - AMAP_SET_BITS(struct amap_iscsi_wrb, invld, - io_task->pwrb_handle->pwrb, 1); - } else { - AMAP_SET_BITS(struct amap_iscsi_wrb_v2, invld, - io_task->pwrb_handle->pwrb, 1); - } + iter_data.data = inv_tbl; + iter_data.lun = sc->device->lun; + iter_data.rc = 0; + iter_data.fn = beiscsi_dev_reset_sc_iter; - inv_tbl->tbl[nents].cid = beiscsi_conn->beiscsi_conn_cid; - inv_tbl->tbl[nents].icd = io_task->psgl_handle->sgl_index; - inv_tbl->task[nents] = task; - nents++; - } - spin_unlock(&session->back_lock); + iscsi_conn_for_each_sc(conn, &iter_data); spin_unlock_bh(&session->frwd_lock); - rc = SUCCESS; - if (!nents) - goto end_reset; - - if (more) { + nents = iter_data.rc; + if (nents > BE_INVLDT_CMD_TBL_SZ) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_EH, "BM_%d : number of cmds exceeds size of invalidation table\n"); + nents = BE_INVLDT_CMD_TBL_SZ; rc = FAILED; goto end_reset; } + rc = SUCCESS; + if (!nents) + goto end_reset; + if (beiscsi_mgmt_invalidate_icds(phba, &inv_tbl->tbl[0], nents)) { beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_EH, "BM_%d : cid %u scmds invalidation failed\n", -- 2.25.1