diff options
Diffstat (limited to 'drivers/infiniband/ulp/iser/iscsi_iser.c')
-rw-r--r-- | drivers/infiniband/ulp/iser/iscsi_iser.c | 82 |
1 files changed, 42 insertions, 40 deletions
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index 7b1468869066..baecca1ed42a 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c | |||
@@ -124,15 +124,23 @@ error: | |||
124 | 124 | ||
125 | 125 | ||
126 | /** | 126 | /** |
127 | * iscsi_iser_cmd_init - Initialize iSCSI SCSI_READ or SCSI_WRITE commands | 127 | * iscsi_iser_task_init - Initialize ctask |
128 | * @ctask: iscsi ctask | ||
128 | * | 129 | * |
129 | **/ | 130 | * Initialize the ctask for the scsi command or mgmt command. |
131 | */ | ||
130 | static int | 132 | static int |
131 | iscsi_iser_cmd_init(struct iscsi_cmd_task *ctask) | 133 | iscsi_iser_task_init(struct iscsi_cmd_task *ctask) |
132 | { | 134 | { |
133 | struct iscsi_iser_conn *iser_conn = ctask->conn->dd_data; | 135 | struct iscsi_iser_conn *iser_conn = ctask->conn->dd_data; |
134 | struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data; | 136 | struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data; |
135 | 137 | ||
138 | /* mgmt ctask */ | ||
139 | if (!ctask->sc) { | ||
140 | iser_ctask->desc.data = ctask->data; | ||
141 | return 0; | ||
142 | } | ||
143 | |||
136 | iser_ctask->command_sent = 0; | 144 | iser_ctask->command_sent = 0; |
137 | iser_ctask->iser_conn = iser_conn; | 145 | iser_ctask->iser_conn = iser_conn; |
138 | iser_ctask_rdma_init(iser_ctask); | 146 | iser_ctask_rdma_init(iser_ctask); |
@@ -140,9 +148,9 @@ iscsi_iser_cmd_init(struct iscsi_cmd_task *ctask) | |||
140 | } | 148 | } |
141 | 149 | ||
142 | /** | 150 | /** |
143 | * iscsi_mtask_xmit - xmit management(immediate) task | 151 | * iscsi_iser_mtask_xmit - xmit management(immediate) ctask |
144 | * @conn: iscsi connection | 152 | * @conn: iscsi connection |
145 | * @mtask: task management task | 153 | * @ctask: ctask management ctask |
146 | * | 154 | * |
147 | * Notes: | 155 | * Notes: |
148 | * The function can return -EAGAIN in which case caller must | 156 | * The function can return -EAGAIN in which case caller must |
@@ -151,20 +159,19 @@ iscsi_iser_cmd_init(struct iscsi_cmd_task *ctask) | |||
151 | * | 159 | * |
152 | **/ | 160 | **/ |
153 | static int | 161 | static int |
154 | iscsi_iser_mtask_xmit(struct iscsi_conn *conn, | 162 | iscsi_iser_mtask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) |
155 | struct iscsi_mgmt_task *mtask) | ||
156 | { | 163 | { |
157 | int error = 0; | 164 | int error = 0; |
158 | 165 | ||
159 | debug_scsi("mtask deq [cid %d itt 0x%x]\n", conn->id, mtask->itt); | 166 | debug_scsi("ctask deq [cid %d itt 0x%x]\n", conn->id, ctask->itt); |
160 | 167 | ||
161 | error = iser_send_control(conn, mtask); | 168 | error = iser_send_control(conn, ctask); |
162 | 169 | ||
163 | /* since iser xmits control with zero copy, mtasks can not be recycled | 170 | /* since iser xmits control with zero copy, ctasks can not be recycled |
164 | * right after sending them. | 171 | * right after sending them. |
165 | * The recycling scheme is based on whether a response is expected | 172 | * The recycling scheme is based on whether a response is expected |
166 | * - if yes, the mtask is recycled at iscsi_complete_pdu | 173 | * - if yes, the ctask is recycled at iscsi_complete_pdu |
167 | * - if no, the mtask is recycled at iser_snd_completion | 174 | * - if no, the ctask is recycled at iser_snd_completion |
168 | */ | 175 | */ |
169 | if (error && error != -ENOBUFS) | 176 | if (error && error != -ENOBUFS) |
170 | iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); | 177 | iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); |
@@ -173,7 +180,7 @@ iscsi_iser_mtask_xmit(struct iscsi_conn *conn, | |||
173 | } | 180 | } |
174 | 181 | ||
175 | static int | 182 | static int |
176 | iscsi_iser_ctask_xmit_unsol_data(struct iscsi_conn *conn, | 183 | iscsi_iser_task_xmit_unsol_data(struct iscsi_conn *conn, |
177 | struct iscsi_cmd_task *ctask) | 184 | struct iscsi_cmd_task *ctask) |
178 | { | 185 | { |
179 | struct iscsi_data hdr; | 186 | struct iscsi_data hdr; |
@@ -190,24 +197,27 @@ iscsi_iser_ctask_xmit_unsol_data(struct iscsi_conn *conn, | |||
190 | error = iser_send_data_out(conn, ctask, &hdr); | 197 | error = iser_send_data_out(conn, ctask, &hdr); |
191 | if (error) { | 198 | if (error) { |
192 | ctask->unsol_datasn--; | 199 | ctask->unsol_datasn--; |
193 | goto iscsi_iser_ctask_xmit_unsol_data_exit; | 200 | goto iscsi_iser_task_xmit_unsol_data_exit; |
194 | } | 201 | } |
195 | ctask->unsol_count -= ctask->data_count; | 202 | ctask->unsol_count -= ctask->data_count; |
196 | debug_scsi("Need to send %d more as data-out PDUs\n", | 203 | debug_scsi("Need to send %d more as data-out PDUs\n", |
197 | ctask->unsol_count); | 204 | ctask->unsol_count); |
198 | } | 205 | } |
199 | 206 | ||
200 | iscsi_iser_ctask_xmit_unsol_data_exit: | 207 | iscsi_iser_task_xmit_unsol_data_exit: |
201 | return error; | 208 | return error; |
202 | } | 209 | } |
203 | 210 | ||
204 | static int | 211 | static int |
205 | iscsi_iser_ctask_xmit(struct iscsi_conn *conn, | 212 | iscsi_iser_task_xmit(struct iscsi_cmd_task *ctask) |
206 | struct iscsi_cmd_task *ctask) | ||
207 | { | 213 | { |
214 | struct iscsi_conn *conn = ctask->conn; | ||
208 | struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data; | 215 | struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data; |
209 | int error = 0; | 216 | int error = 0; |
210 | 217 | ||
218 | if (!ctask->sc) | ||
219 | return iscsi_iser_mtask_xmit(conn, ctask); | ||
220 | |||
211 | if (ctask->sc->sc_data_direction == DMA_TO_DEVICE) { | 221 | if (ctask->sc->sc_data_direction == DMA_TO_DEVICE) { |
212 | BUG_ON(scsi_bufflen(ctask->sc) == 0); | 222 | BUG_ON(scsi_bufflen(ctask->sc) == 0); |
213 | 223 | ||
@@ -223,25 +233,29 @@ iscsi_iser_ctask_xmit(struct iscsi_conn *conn, | |||
223 | if (!iser_ctask->command_sent) { | 233 | if (!iser_ctask->command_sent) { |
224 | error = iser_send_command(conn, ctask); | 234 | error = iser_send_command(conn, ctask); |
225 | if (error) | 235 | if (error) |
226 | goto iscsi_iser_ctask_xmit_exit; | 236 | goto iscsi_iser_task_xmit_exit; |
227 | iser_ctask->command_sent = 1; | 237 | iser_ctask->command_sent = 1; |
228 | } | 238 | } |
229 | 239 | ||
230 | /* Send unsolicited data-out PDU(s) if necessary */ | 240 | /* Send unsolicited data-out PDU(s) if necessary */ |
231 | if (ctask->unsol_count) | 241 | if (ctask->unsol_count) |
232 | error = iscsi_iser_ctask_xmit_unsol_data(conn, ctask); | 242 | error = iscsi_iser_task_xmit_unsol_data(conn, ctask); |
233 | 243 | ||
234 | iscsi_iser_ctask_xmit_exit: | 244 | iscsi_iser_task_xmit_exit: |
235 | if (error && error != -ENOBUFS) | 245 | if (error && error != -ENOBUFS) |
236 | iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); | 246 | iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); |
237 | return error; | 247 | return error; |
238 | } | 248 | } |
239 | 249 | ||
240 | static void | 250 | static void |
241 | iscsi_iser_cleanup_ctask(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | 251 | iscsi_iser_cleanup_task(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) |
242 | { | 252 | { |
243 | struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data; | 253 | struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data; |
244 | 254 | ||
255 | /* mgmt tasks do not need special cleanup */ | ||
256 | if (!ctask->sc) | ||
257 | return; | ||
258 | |||
245 | if (iser_ctask->status == ISER_TASK_STATUS_STARTED) { | 259 | if (iser_ctask->status == ISER_TASK_STATUS_STARTED) { |
246 | iser_ctask->status = ISER_TASK_STATUS_COMPLETED; | 260 | iser_ctask->status = ISER_TASK_STATUS_COMPLETED; |
247 | iser_ctask_rdma_finalize(iser_ctask); | 261 | iser_ctask_rdma_finalize(iser_ctask); |
@@ -394,10 +408,8 @@ iscsi_iser_session_create(struct Scsi_Host *shost, | |||
394 | struct iscsi_cls_session *cls_session; | 408 | struct iscsi_cls_session *cls_session; |
395 | struct iscsi_session *session; | 409 | struct iscsi_session *session; |
396 | int i; | 410 | int i; |
397 | struct iscsi_cmd_task *ctask; | 411 | struct iscsi_cmd_task *ctask; |
398 | struct iscsi_mgmt_task *mtask; | ||
399 | struct iscsi_iser_cmd_task *iser_ctask; | 412 | struct iscsi_iser_cmd_task *iser_ctask; |
400 | struct iser_desc *desc; | ||
401 | 413 | ||
402 | if (shost) { | 414 | if (shost) { |
403 | printk(KERN_ERR "iscsi_tcp: invalid shost %d.\n", | 415 | printk(KERN_ERR "iscsi_tcp: invalid shost %d.\n", |
@@ -425,28 +437,19 @@ iscsi_iser_session_create(struct Scsi_Host *shost, | |||
425 | cls_session = iscsi_session_setup(&iscsi_iser_transport, shost, | 437 | cls_session = iscsi_session_setup(&iscsi_iser_transport, shost, |
426 | ISCSI_DEF_XMIT_CMDS_MAX, | 438 | ISCSI_DEF_XMIT_CMDS_MAX, |
427 | sizeof(struct iscsi_iser_cmd_task), | 439 | sizeof(struct iscsi_iser_cmd_task), |
428 | sizeof(struct iser_desc), | ||
429 | initial_cmdsn); | 440 | initial_cmdsn); |
430 | if (!cls_session) | 441 | if (!cls_session) |
431 | goto remove_host; | 442 | goto remove_host; |
432 | session = cls_session->dd_data; | 443 | session = cls_session->dd_data; |
433 | 444 | ||
434 | shost->can_queue = session->cmds_max; | 445 | shost->can_queue = session->scsi_cmds_max; |
435 | /* libiscsi setup itts, data and pool so just set desc fields */ | 446 | /* libiscsi setup itts, data and pool so just set desc fields */ |
436 | for (i = 0; i < session->cmds_max; i++) { | 447 | for (i = 0; i < session->cmds_max; i++) { |
437 | ctask = session->cmds[i]; | 448 | ctask = session->cmds[i]; |
438 | iser_ctask = ctask->dd_data; | 449 | iser_ctask = ctask->dd_data; |
439 | ctask->hdr = (struct iscsi_cmd *)&iser_ctask->desc.iscsi_header; | 450 | ctask->hdr = (struct iscsi_cmd *)&iser_ctask->desc.iscsi_header; |
440 | ctask->hdr_max = sizeof(iser_ctask->desc.iscsi_header); | 451 | ctask->hdr_max = sizeof(iser_ctask->desc.iscsi_header); |
441 | } | 452 | } |
442 | |||
443 | for (i = 0; i < session->mgmtpool_max; i++) { | ||
444 | mtask = session->mgmt_cmds[i]; | ||
445 | desc = mtask->dd_data; | ||
446 | mtask->hdr = &desc->iscsi_header; | ||
447 | desc->data = mtask->data; | ||
448 | } | ||
449 | |||
450 | return cls_session; | 453 | return cls_session; |
451 | 454 | ||
452 | remove_host: | 455 | remove_host: |
@@ -659,10 +662,9 @@ static struct iscsi_transport iscsi_iser_transport = { | |||
659 | /* IO */ | 662 | /* IO */ |
660 | .send_pdu = iscsi_conn_send_pdu, | 663 | .send_pdu = iscsi_conn_send_pdu, |
661 | .get_stats = iscsi_iser_conn_get_stats, | 664 | .get_stats = iscsi_iser_conn_get_stats, |
662 | .init_cmd_task = iscsi_iser_cmd_init, | 665 | .init_task = iscsi_iser_task_init, |
663 | .xmit_cmd_task = iscsi_iser_ctask_xmit, | 666 | .xmit_task = iscsi_iser_task_xmit, |
664 | .xmit_mgmt_task = iscsi_iser_mtask_xmit, | 667 | .cleanup_task = iscsi_iser_cleanup_task, |
665 | .cleanup_cmd_task = iscsi_iser_cleanup_ctask, | ||
666 | /* recovery */ | 668 | /* recovery */ |
667 | .session_recovery_timedout = iscsi_session_recovery_timedout, | 669 | .session_recovery_timedout = iscsi_session_recovery_timedout, |
668 | 670 | ||