aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/be2iscsi/be_main.c134
-rw-r--r--drivers/scsi/be2iscsi/be_main.h7
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.c14
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.h8
4 files changed, 145 insertions, 18 deletions
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 4d269b434a78..eab31a515de3 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -58,6 +58,123 @@ static int beiscsi_slave_configure(struct scsi_device *sdev)
58 return 0; 58 return 0;
59} 59}
60 60
61static int beiscsi_eh_abort(struct scsi_cmnd *sc)
62{
63 struct iscsi_cls_session *cls_session;
64 struct iscsi_task *aborted_task = (struct iscsi_task *)sc->SCp.ptr;
65 struct beiscsi_io_task *aborted_io_task;
66 struct iscsi_conn *conn;
67 struct beiscsi_conn *beiscsi_conn;
68 struct beiscsi_hba *phba;
69 struct iscsi_session *session;
70 struct invalidate_command_table *inv_tbl;
71 unsigned int cid, tag, num_invalidate;
72
73 cls_session = starget_to_session(scsi_target(sc->device));
74 session = cls_session->dd_data;
75
76 spin_lock_bh(&session->lock);
77 if (!aborted_task || !aborted_task->sc) {
78 /* we raced */
79 spin_unlock_bh(&session->lock);
80 return SUCCESS;
81 }
82
83 aborted_io_task = aborted_task->dd_data;
84 if (!aborted_io_task->scsi_cmnd) {
85 /* raced or invalid command */
86 spin_unlock_bh(&session->lock);
87 return SUCCESS;
88 }
89 spin_unlock_bh(&session->lock);
90 conn = aborted_task->conn;
91 beiscsi_conn = conn->dd_data;
92 phba = beiscsi_conn->phba;
93
94 /* invalidate iocb */
95 cid = beiscsi_conn->beiscsi_conn_cid;
96 inv_tbl = phba->inv_tbl;
97 memset(inv_tbl, 0x0, sizeof(*inv_tbl));
98 inv_tbl->cid = cid;
99 inv_tbl->icd = aborted_io_task->psgl_handle->sgl_index;
100 num_invalidate = 1;
101 tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, cid);
102 if (!tag) {
103 shost_printk(KERN_WARNING, phba->shost,
104 "mgmt_invalidate_icds could not be"
105 " submitted\n");
106 return FAILED;
107 } else {
108 wait_event_interruptible(phba->ctrl.mcc_wait[tag],
109 phba->ctrl.mcc_numtag[tag]);
110 free_mcc_tag(&phba->ctrl, tag);
111 }
112
113 return iscsi_eh_abort(sc);
114}
115
116static int beiscsi_eh_device_reset(struct scsi_cmnd *sc)
117{
118 struct iscsi_task *abrt_task;
119 struct beiscsi_io_task *abrt_io_task;
120 struct iscsi_conn *conn;
121 struct beiscsi_conn *beiscsi_conn;
122 struct beiscsi_hba *phba;
123 struct iscsi_session *session;
124 struct iscsi_cls_session *cls_session;
125 struct invalidate_command_table *inv_tbl;
126 unsigned int cid, tag, i, num_invalidate;
127 int rc = FAILED;
128
129 /* invalidate iocbs */
130 cls_session = starget_to_session(scsi_target(sc->device));
131 session = cls_session->dd_data;
132 spin_lock_bh(&session->lock);
133 if (!session->leadconn || session->state != ISCSI_STATE_LOGGED_IN)
134 goto unlock;
135
136 conn = session->leadconn;
137 beiscsi_conn = conn->dd_data;
138 phba = beiscsi_conn->phba;
139 cid = beiscsi_conn->beiscsi_conn_cid;
140 inv_tbl = phba->inv_tbl;
141 memset(inv_tbl, 0x0, sizeof(*inv_tbl) * BE2_CMDS_PER_CXN);
142 num_invalidate = 0;
143 for (i = 0; i < conn->session->cmds_max; i++) {
144 abrt_task = conn->session->cmds[i];
145 abrt_io_task = abrt_task->dd_data;
146 if (!abrt_task->sc || abrt_task->state == ISCSI_TASK_FREE)
147 continue;
148
149 if (abrt_task->sc->device->lun != abrt_task->sc->device->lun)
150 continue;
151
152 inv_tbl->cid = cid;
153 inv_tbl->icd = abrt_io_task->psgl_handle->sgl_index;
154 num_invalidate++;
155 inv_tbl++;
156 }
157 spin_unlock_bh(&session->lock);
158 inv_tbl = phba->inv_tbl;
159
160 tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, cid);
161 if (!tag) {
162 shost_printk(KERN_WARNING, phba->shost,
163 "mgmt_invalidate_icds could not be"
164 " submitted\n");
165 return FAILED;
166 } else {
167 wait_event_interruptible(phba->ctrl.mcc_wait[tag],
168 phba->ctrl.mcc_numtag[tag]);
169 free_mcc_tag(&phba->ctrl, tag);
170 }
171
172 return iscsi_eh_device_reset(sc);
173unlock:
174 spin_unlock_bh(&session->lock);
175 return rc;
176}
177
61/*------------------- PCI Driver operations and data ----------------- */ 178/*------------------- PCI Driver operations and data ----------------- */
62static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = { 179static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = {
63 { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) }, 180 { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
@@ -74,11 +191,11 @@ static struct scsi_host_template beiscsi_sht = {
74 .name = "ServerEngines 10Gbe open-iscsi Initiator Driver", 191 .name = "ServerEngines 10Gbe open-iscsi Initiator Driver",
75 .proc_name = DRV_NAME, 192 .proc_name = DRV_NAME,
76 .queuecommand = iscsi_queuecommand, 193 .queuecommand = iscsi_queuecommand,
77 .eh_abort_handler = iscsi_eh_abort,
78 .change_queue_depth = iscsi_change_queue_depth, 194 .change_queue_depth = iscsi_change_queue_depth,
79 .slave_configure = beiscsi_slave_configure, 195 .slave_configure = beiscsi_slave_configure,
80 .target_alloc = iscsi_target_alloc, 196 .target_alloc = iscsi_target_alloc,
81 .eh_device_reset_handler = iscsi_eh_device_reset, 197 .eh_abort_handler = beiscsi_eh_abort,
198 .eh_device_reset_handler = beiscsi_eh_device_reset,
82 .eh_target_reset_handler = iscsi_eh_session_reset, 199 .eh_target_reset_handler = iscsi_eh_session_reset,
83 .sg_tablesize = BEISCSI_SGLIST_ELEMENTS, 200 .sg_tablesize = BEISCSI_SGLIST_ELEMENTS,
84 .can_queue = BE2_IO_DEPTH, 201 .can_queue = BE2_IO_DEPTH,
@@ -3486,9 +3603,9 @@ static int beiscsi_mtask(struct iscsi_task *task)
3486 struct hwi_wrb_context *pwrb_context; 3603 struct hwi_wrb_context *pwrb_context;
3487 struct wrb_handle *pwrb_handle; 3604 struct wrb_handle *pwrb_handle;
3488 unsigned int doorbell = 0; 3605 unsigned int doorbell = 0;
3489 unsigned int i, cid; 3606 struct invalidate_command_table *inv_tbl;
3490 struct iscsi_task *aborted_task; 3607 struct iscsi_task *aborted_task;
3491 unsigned int tag; 3608 unsigned int i, cid, tag, num_invalidate;
3492 3609
3493 cid = beiscsi_conn->beiscsi_conn_cid; 3610 cid = beiscsi_conn->beiscsi_conn_cid;
3494 pwrb = io_task->pwrb_handle->pwrb; 3611 pwrb = io_task->pwrb_handle->pwrb;
@@ -3538,9 +3655,12 @@ static int beiscsi_mtask(struct iscsi_task *task)
3538 if (!aborted_io_task->scsi_cmnd) 3655 if (!aborted_io_task->scsi_cmnd)
3539 return 0; 3656 return 0;
3540 3657
3541 tag = mgmt_invalidate_icds(phba, 3658 inv_tbl = phba->inv_tbl;
3542 aborted_io_task->psgl_handle->sgl_index, 3659 memset(inv_tbl, 0x0, sizeof(*inv_tbl));
3543 cid); 3660 inv_tbl->cid = cid;
3661 inv_tbl->icd = aborted_io_task->psgl_handle->sgl_index;
3662 num_invalidate = 1;
3663 tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, cid);
3544 if (!tag) { 3664 if (!tag) {
3545 shost_printk(KERN_WARNING, phba->shost, 3665 shost_printk(KERN_WARNING, phba->shost,
3546 "mgmt_invalidate_icds could not be" 3666 "mgmt_invalidate_icds could not be"
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index c53a80ab796c..d4d31dc09088 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -257,6 +257,11 @@ struct hba_parameters {
257 unsigned int num_sge; 257 unsigned int num_sge;
258}; 258};
259 259
260struct invalidate_command_table {
261 unsigned short icd;
262 unsigned short cid;
263} __packed;
264
260struct beiscsi_hba { 265struct beiscsi_hba {
261 struct hba_parameters params; 266 struct hba_parameters params;
262 struct hwi_controller *phwi_ctrlr; 267 struct hwi_controller *phwi_ctrlr;
@@ -329,6 +334,8 @@ struct beiscsi_hba {
329 struct work_struct work_cqs; /* The work being queued */ 334 struct work_struct work_cqs; /* The work being queued */
330 struct be_ctrl_info ctrl; 335 struct be_ctrl_info ctrl;
331 unsigned int generation; 336 unsigned int generation;
337 struct invalidate_command_table inv_tbl[128];
338
332}; 339};
333 340
334struct beiscsi_session { 341struct beiscsi_session {
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index 317bcd042ced..72617b650a7e 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -145,14 +145,15 @@ unsigned char mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute)
145} 145}
146 146
147unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba, 147unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
148 unsigned int icd, unsigned int cid) 148 struct invalidate_command_table *inv_tbl,
149 unsigned int num_invalidate, unsigned int cid)
149{ 150{
150 struct be_dma_mem nonemb_cmd; 151 struct be_dma_mem nonemb_cmd;
151 struct be_ctrl_info *ctrl = &phba->ctrl; 152 struct be_ctrl_info *ctrl = &phba->ctrl;
152 struct be_mcc_wrb *wrb; 153 struct be_mcc_wrb *wrb;
153 struct be_sge *sge; 154 struct be_sge *sge;
154 struct invalidate_commands_params_in *req; 155 struct invalidate_commands_params_in *req;
155 unsigned int tag = 0; 156 unsigned int i, tag = 0;
156 157
157 spin_lock(&ctrl->mbox_lock); 158 spin_lock(&ctrl->mbox_lock);
158 tag = alloc_mcc_tag(phba); 159 tag = alloc_mcc_tag(phba);
@@ -183,9 +184,12 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
183 sizeof(*req)); 184 sizeof(*req));
184 req->ref_handle = 0; 185 req->ref_handle = 0;
185 req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE; 186 req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE;
186 req->icd_count = 0; 187 for (i = 0; i < num_invalidate; i++) {
187 req->table[req->icd_count].icd = icd; 188 req->table[i].icd = inv_tbl->icd;
188 req->table[req->icd_count].cid = cid; 189 req->table[i].cid = inv_tbl->cid;
190 req->icd_count++;
191 inv_tbl++;
192 }
189 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma)); 193 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
190 sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF); 194 sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
191 sge->len = cpu_to_le32(nonemb_cmd.size); 195 sge->len = cpu_to_le32(nonemb_cmd.size);
diff --git a/drivers/scsi/be2iscsi/be_mgmt.h b/drivers/scsi/be2iscsi/be_mgmt.h
index ecead6a5aa56..3d316b82feb1 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.h
+++ b/drivers/scsi/be2iscsi/be_mgmt.h
@@ -94,7 +94,8 @@ unsigned char mgmt_upload_connection(struct beiscsi_hba *phba,
94 unsigned short cid, 94 unsigned short cid,
95 unsigned int upload_flag); 95 unsigned int upload_flag);
96unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba, 96unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
97 unsigned int icd, unsigned int cid); 97 struct invalidate_command_table *inv_tbl,
98 unsigned int num_invalidate, unsigned int cid);
98 99
99struct iscsi_invalidate_connection_params_in { 100struct iscsi_invalidate_connection_params_in {
100 struct be_cmd_req_hdr hdr; 101 struct be_cmd_req_hdr hdr;
@@ -116,11 +117,6 @@ union iscsi_invalidate_connection_params {
116 struct iscsi_invalidate_connection_params_out response; 117 struct iscsi_invalidate_connection_params_out response;
117} __packed; 118} __packed;
118 119
119struct invalidate_command_table {
120 unsigned short icd;
121 unsigned short cid;
122} __packed;
123
124struct invalidate_commands_params_in { 120struct invalidate_commands_params_in {
125 struct be_cmd_req_hdr hdr; 121 struct be_cmd_req_hdr hdr;
126 unsigned int ref_handle; 122 unsigned int ref_handle;