Skip to content

Commit

Permalink
[SCSI] be2iscsi: Cleanup of resets for device and target
Browse files Browse the repository at this point in the history
This patch cleans up device and target reset handling
for the driver

Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: Jayamohan Kallickal <jayamohank@serverengines.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
  • Loading branch information
Jayamohan Kallickal authored and James Bottomley committed Mar 3, 2010
1 parent 309ce15 commit 4183122
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 18 deletions.
134 changes: 127 additions & 7 deletions drivers/scsi/be2iscsi/be_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,123 @@ static int beiscsi_slave_configure(struct scsi_device *sdev)
return 0;
}

static int beiscsi_eh_abort(struct scsi_cmnd *sc)
{
struct iscsi_cls_session *cls_session;
struct iscsi_task *aborted_task = (struct iscsi_task *)sc->SCp.ptr;
struct beiscsi_io_task *aborted_io_task;
struct iscsi_conn *conn;
struct beiscsi_conn *beiscsi_conn;
struct beiscsi_hba *phba;
struct iscsi_session *session;
struct invalidate_command_table *inv_tbl;
unsigned int cid, tag, num_invalidate;

cls_session = starget_to_session(scsi_target(sc->device));
session = cls_session->dd_data;

spin_lock_bh(&session->lock);
if (!aborted_task || !aborted_task->sc) {
/* we raced */
spin_unlock_bh(&session->lock);
return SUCCESS;
}

aborted_io_task = aborted_task->dd_data;
if (!aborted_io_task->scsi_cmnd) {
/* raced or invalid command */
spin_unlock_bh(&session->lock);
return SUCCESS;
}
spin_unlock_bh(&session->lock);
conn = aborted_task->conn;
beiscsi_conn = conn->dd_data;
phba = beiscsi_conn->phba;

/* invalidate iocb */
cid = beiscsi_conn->beiscsi_conn_cid;
inv_tbl = phba->inv_tbl;
memset(inv_tbl, 0x0, sizeof(*inv_tbl));
inv_tbl->cid = cid;
inv_tbl->icd = aborted_io_task->psgl_handle->sgl_index;
num_invalidate = 1;
tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, cid);
if (!tag) {
shost_printk(KERN_WARNING, phba->shost,
"mgmt_invalidate_icds could not be"
" submitted\n");
return FAILED;
} else {
wait_event_interruptible(phba->ctrl.mcc_wait[tag],
phba->ctrl.mcc_numtag[tag]);
free_mcc_tag(&phba->ctrl, tag);
}

return iscsi_eh_abort(sc);
}

static int beiscsi_eh_device_reset(struct scsi_cmnd *sc)
{
struct iscsi_task *abrt_task;
struct beiscsi_io_task *abrt_io_task;
struct iscsi_conn *conn;
struct beiscsi_conn *beiscsi_conn;
struct beiscsi_hba *phba;
struct iscsi_session *session;
struct iscsi_cls_session *cls_session;
struct invalidate_command_table *inv_tbl;
unsigned int cid, tag, i, num_invalidate;
int rc = FAILED;

/* invalidate iocbs */
cls_session = starget_to_session(scsi_target(sc->device));
session = cls_session->dd_data;
spin_lock_bh(&session->lock);
if (!session->leadconn || session->state != ISCSI_STATE_LOGGED_IN)
goto unlock;

conn = session->leadconn;
beiscsi_conn = conn->dd_data;
phba = beiscsi_conn->phba;
cid = beiscsi_conn->beiscsi_conn_cid;
inv_tbl = phba->inv_tbl;
memset(inv_tbl, 0x0, sizeof(*inv_tbl) * BE2_CMDS_PER_CXN);
num_invalidate = 0;
for (i = 0; i < conn->session->cmds_max; i++) {
abrt_task = conn->session->cmds[i];
abrt_io_task = abrt_task->dd_data;
if (!abrt_task->sc || abrt_task->state == ISCSI_TASK_FREE)
continue;

if (abrt_task->sc->device->lun != abrt_task->sc->device->lun)
continue;

inv_tbl->cid = cid;
inv_tbl->icd = abrt_io_task->psgl_handle->sgl_index;
num_invalidate++;
inv_tbl++;
}
spin_unlock_bh(&session->lock);
inv_tbl = phba->inv_tbl;

tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, cid);
if (!tag) {
shost_printk(KERN_WARNING, phba->shost,
"mgmt_invalidate_icds could not be"
" submitted\n");
return FAILED;
} else {
wait_event_interruptible(phba->ctrl.mcc_wait[tag],
phba->ctrl.mcc_numtag[tag]);
free_mcc_tag(&phba->ctrl, tag);
}

return iscsi_eh_device_reset(sc);
unlock:
spin_unlock_bh(&session->lock);
return rc;
}

/*------------------- PCI Driver operations and data ----------------- */
static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = {
{ PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
Expand All @@ -74,11 +191,11 @@ static struct scsi_host_template beiscsi_sht = {
.name = "ServerEngines 10Gbe open-iscsi Initiator Driver",
.proc_name = DRV_NAME,
.queuecommand = iscsi_queuecommand,
.eh_abort_handler = iscsi_eh_abort,
.change_queue_depth = iscsi_change_queue_depth,
.slave_configure = beiscsi_slave_configure,
.target_alloc = iscsi_target_alloc,
.eh_device_reset_handler = iscsi_eh_device_reset,
.eh_abort_handler = beiscsi_eh_abort,
.eh_device_reset_handler = beiscsi_eh_device_reset,
.eh_target_reset_handler = iscsi_eh_session_reset,
.sg_tablesize = BEISCSI_SGLIST_ELEMENTS,
.can_queue = BE2_IO_DEPTH,
Expand Down Expand Up @@ -3486,9 +3603,9 @@ static int beiscsi_mtask(struct iscsi_task *task)
struct hwi_wrb_context *pwrb_context;
struct wrb_handle *pwrb_handle;
unsigned int doorbell = 0;
unsigned int i, cid;
struct invalidate_command_table *inv_tbl;
struct iscsi_task *aborted_task;
unsigned int tag;
unsigned int i, cid, tag, num_invalidate;

cid = beiscsi_conn->beiscsi_conn_cid;
pwrb = io_task->pwrb_handle->pwrb;
Expand Down Expand Up @@ -3538,9 +3655,12 @@ static int beiscsi_mtask(struct iscsi_task *task)
if (!aborted_io_task->scsi_cmnd)
return 0;

tag = mgmt_invalidate_icds(phba,
aborted_io_task->psgl_handle->sgl_index,
cid);
inv_tbl = phba->inv_tbl;
memset(inv_tbl, 0x0, sizeof(*inv_tbl));
inv_tbl->cid = cid;
inv_tbl->icd = aborted_io_task->psgl_handle->sgl_index;
num_invalidate = 1;
tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, cid);
if (!tag) {
shost_printk(KERN_WARNING, phba->shost,
"mgmt_invalidate_icds could not be"
Expand Down
7 changes: 7 additions & 0 deletions drivers/scsi/be2iscsi/be_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,11 @@ struct hba_parameters {
unsigned int num_sge;
};

struct invalidate_command_table {
unsigned short icd;
unsigned short cid;
} __packed;

struct beiscsi_hba {
struct hba_parameters params;
struct hwi_controller *phwi_ctrlr;
Expand Down Expand Up @@ -329,6 +334,8 @@ struct beiscsi_hba {
struct work_struct work_cqs; /* The work being queued */
struct be_ctrl_info ctrl;
unsigned int generation;
struct invalidate_command_table inv_tbl[128];

};

struct beiscsi_session {
Expand Down
14 changes: 9 additions & 5 deletions drivers/scsi/be2iscsi/be_mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,14 +145,15 @@ unsigned char mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute)
}

unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
unsigned int icd, unsigned int cid)
struct invalidate_command_table *inv_tbl,
unsigned int num_invalidate, unsigned int cid)
{
struct be_dma_mem nonemb_cmd;
struct be_ctrl_info *ctrl = &phba->ctrl;
struct be_mcc_wrb *wrb;
struct be_sge *sge;
struct invalidate_commands_params_in *req;
unsigned int tag = 0;
unsigned int i, tag = 0;

spin_lock(&ctrl->mbox_lock);
tag = alloc_mcc_tag(phba);
Expand Down Expand Up @@ -183,9 +184,12 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
sizeof(*req));
req->ref_handle = 0;
req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE;
req->icd_count = 0;
req->table[req->icd_count].icd = icd;
req->table[req->icd_count].cid = cid;
for (i = 0; i < num_invalidate; i++) {
req->table[i].icd = inv_tbl->icd;
req->table[i].cid = inv_tbl->cid;
req->icd_count++;
inv_tbl++;
}
sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
sge->len = cpu_to_le32(nonemb_cmd.size);
Expand Down
8 changes: 2 additions & 6 deletions drivers/scsi/be2iscsi/be_mgmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ unsigned char mgmt_upload_connection(struct beiscsi_hba *phba,
unsigned short cid,
unsigned int upload_flag);
unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
unsigned int icd, unsigned int cid);
struct invalidate_command_table *inv_tbl,
unsigned int num_invalidate, unsigned int cid);

struct iscsi_invalidate_connection_params_in {
struct be_cmd_req_hdr hdr;
Expand All @@ -116,11 +117,6 @@ union iscsi_invalidate_connection_params {
struct iscsi_invalidate_connection_params_out response;
} __packed;

struct invalidate_command_table {
unsigned short icd;
unsigned short cid;
} __packed;

struct invalidate_commands_params_in {
struct be_cmd_req_hdr hdr;
unsigned int ref_handle;
Expand Down

0 comments on commit 4183122

Please sign in to comment.