aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libiscsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/libiscsi.c')
-rw-r--r--drivers/scsi/libiscsi.c533
1 files changed, 414 insertions, 119 deletions
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 2673a11a949..c542d0e95e6 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -68,8 +68,7 @@ iscsi_check_assign_cmdsn(struct iscsi_session *session, struct iscsi_nopin *hdr)
68EXPORT_SYMBOL_GPL(iscsi_check_assign_cmdsn); 68EXPORT_SYMBOL_GPL(iscsi_check_assign_cmdsn);
69 69
70void iscsi_prep_unsolicit_data_pdu(struct iscsi_cmd_task *ctask, 70void iscsi_prep_unsolicit_data_pdu(struct iscsi_cmd_task *ctask,
71 struct iscsi_data *hdr, 71 struct iscsi_data *hdr)
72 int transport_data_cnt)
73{ 72{
74 struct iscsi_conn *conn = ctask->conn; 73 struct iscsi_conn *conn = ctask->conn;
75 74
@@ -82,14 +81,12 @@ void iscsi_prep_unsolicit_data_pdu(struct iscsi_cmd_task *ctask,
82 81
83 hdr->itt = ctask->hdr->itt; 82 hdr->itt = ctask->hdr->itt;
84 hdr->exp_statsn = cpu_to_be32(conn->exp_statsn); 83 hdr->exp_statsn = cpu_to_be32(conn->exp_statsn);
85 84 hdr->offset = cpu_to_be32(ctask->unsol_offset);
86 hdr->offset = cpu_to_be32(ctask->total_length -
87 transport_data_cnt -
88 ctask->unsol_count);
89 85
90 if (ctask->unsol_count > conn->max_xmit_dlength) { 86 if (ctask->unsol_count > conn->max_xmit_dlength) {
91 hton24(hdr->dlength, conn->max_xmit_dlength); 87 hton24(hdr->dlength, conn->max_xmit_dlength);
92 ctask->data_count = conn->max_xmit_dlength; 88 ctask->data_count = conn->max_xmit_dlength;
89 ctask->unsol_offset += ctask->data_count;
93 hdr->flags = 0; 90 hdr->flags = 0;
94 } else { 91 } else {
95 hton24(hdr->dlength, ctask->unsol_count); 92 hton24(hdr->dlength, ctask->unsol_count);
@@ -125,6 +122,7 @@ static void iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask)
125 memcpy(hdr->cdb, sc->cmnd, sc->cmd_len); 122 memcpy(hdr->cdb, sc->cmnd, sc->cmd_len);
126 memset(&hdr->cdb[sc->cmd_len], 0, MAX_COMMAND_SIZE - sc->cmd_len); 123 memset(&hdr->cdb[sc->cmd_len], 0, MAX_COMMAND_SIZE - sc->cmd_len);
127 124
125 ctask->data_count = 0;
128 if (sc->sc_data_direction == DMA_TO_DEVICE) { 126 if (sc->sc_data_direction == DMA_TO_DEVICE) {
129 hdr->flags |= ISCSI_FLAG_CMD_WRITE; 127 hdr->flags |= ISCSI_FLAG_CMD_WRITE;
130 /* 128 /*
@@ -143,6 +141,7 @@ static void iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask)
143 */ 141 */
144 ctask->imm_count = 0; 142 ctask->imm_count = 0;
145 ctask->unsol_count = 0; 143 ctask->unsol_count = 0;
144 ctask->unsol_offset = 0;
146 ctask->unsol_datasn = 0; 145 ctask->unsol_datasn = 0;
147 146
148 if (session->imm_data_en) { 147 if (session->imm_data_en) {
@@ -156,9 +155,12 @@ static void iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask)
156 } else 155 } else
157 zero_data(ctask->hdr->dlength); 156 zero_data(ctask->hdr->dlength);
158 157
159 if (!session->initial_r2t_en) 158 if (!session->initial_r2t_en) {
160 ctask->unsol_count = min(session->first_burst, 159 ctask->unsol_count = min(session->first_burst,
161 ctask->total_length) - ctask->imm_count; 160 ctask->total_length) - ctask->imm_count;
161 ctask->unsol_offset = ctask->imm_count;
162 }
163
162 if (!ctask->unsol_count) 164 if (!ctask->unsol_count)
163 /* No unsolicit Data-Out's */ 165 /* No unsolicit Data-Out's */
164 ctask->hdr->flags |= ISCSI_FLAG_CMD_FINAL; 166 ctask->hdr->flags |= ISCSI_FLAG_CMD_FINAL;
@@ -177,24 +179,51 @@ EXPORT_SYMBOL_GPL(iscsi_prep_scsi_cmd_pdu);
177 179
178/** 180/**
179 * iscsi_complete_command - return command back to scsi-ml 181 * iscsi_complete_command - return command back to scsi-ml
180 * @session: iscsi session
181 * @ctask: iscsi cmd task 182 * @ctask: iscsi cmd task
182 * 183 *
183 * Must be called with session lock. 184 * Must be called with session lock.
184 * This function returns the scsi command to scsi-ml and returns 185 * This function returns the scsi command to scsi-ml and returns
185 * the cmd task to the pool of available cmd tasks. 186 * the cmd task to the pool of available cmd tasks.
186 */ 187 */
187static void iscsi_complete_command(struct iscsi_session *session, 188static void iscsi_complete_command(struct iscsi_cmd_task *ctask)
188 struct iscsi_cmd_task *ctask)
189{ 189{
190 struct iscsi_session *session = ctask->conn->session;
190 struct scsi_cmnd *sc = ctask->sc; 191 struct scsi_cmnd *sc = ctask->sc;
191 192
193 ctask->state = ISCSI_TASK_COMPLETED;
192 ctask->sc = NULL; 194 ctask->sc = NULL;
195 /* SCSI eh reuses commands to verify us */
196 sc->SCp.ptr = NULL;
193 list_del_init(&ctask->running); 197 list_del_init(&ctask->running);
194 __kfifo_put(session->cmdpool.queue, (void*)&ctask, sizeof(void*)); 198 __kfifo_put(session->cmdpool.queue, (void*)&ctask, sizeof(void*));
195 sc->scsi_done(sc); 199 sc->scsi_done(sc);
196} 200}
197 201
202static void __iscsi_get_ctask(struct iscsi_cmd_task *ctask)
203{
204 atomic_inc(&ctask->refcount);
205}
206
207static void iscsi_get_ctask(struct iscsi_cmd_task *ctask)
208{
209 spin_lock_bh(&ctask->conn->session->lock);
210 __iscsi_get_ctask(ctask);
211 spin_unlock_bh(&ctask->conn->session->lock);
212}
213
214static void __iscsi_put_ctask(struct iscsi_cmd_task *ctask)
215{
216 if (atomic_dec_and_test(&ctask->refcount))
217 iscsi_complete_command(ctask);
218}
219
220static void iscsi_put_ctask(struct iscsi_cmd_task *ctask)
221{
222 spin_lock_bh(&ctask->conn->session->lock);
223 __iscsi_put_ctask(ctask);
224 spin_unlock_bh(&ctask->conn->session->lock);
225}
226
198/** 227/**
199 * iscsi_cmd_rsp - SCSI Command Response processing 228 * iscsi_cmd_rsp - SCSI Command Response processing
200 * @conn: iscsi connection 229 * @conn: iscsi connection
@@ -271,10 +300,53 @@ out:
271 (long)sc, sc->result, ctask->itt); 300 (long)sc, sc->result, ctask->itt);
272 conn->scsirsp_pdus_cnt++; 301 conn->scsirsp_pdus_cnt++;
273 302
274 iscsi_complete_command(conn->session, ctask); 303 __iscsi_put_ctask(ctask);
275 return rc; 304 return rc;
276} 305}
277 306
307static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
308{
309 struct iscsi_tm_rsp *tmf = (struct iscsi_tm_rsp *)hdr;
310
311 conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
312 conn->tmfrsp_pdus_cnt++;
313
314 if (conn->tmabort_state != TMABORT_INITIAL)
315 return;
316
317 if (tmf->response == ISCSI_TMF_RSP_COMPLETE)
318 conn->tmabort_state = TMABORT_SUCCESS;
319 else if (tmf->response == ISCSI_TMF_RSP_NO_TASK)
320 conn->tmabort_state = TMABORT_NOT_FOUND;
321 else
322 conn->tmabort_state = TMABORT_FAILED;
323 wake_up(&conn->ehwait);
324}
325
326static int iscsi_handle_reject(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
327 char *data, int datalen)
328{
329 struct iscsi_reject *reject = (struct iscsi_reject *)hdr;
330 struct iscsi_hdr rejected_pdu;
331 uint32_t itt;
332
333 conn->exp_statsn = be32_to_cpu(reject->statsn) + 1;
334
335 if (reject->reason == ISCSI_REASON_DATA_DIGEST_ERROR) {
336 if (ntoh24(reject->dlength) > datalen)
337 return ISCSI_ERR_PROTO;
338
339 if (ntoh24(reject->dlength) >= sizeof(struct iscsi_hdr)) {
340 memcpy(&rejected_pdu, data, sizeof(struct iscsi_hdr));
341 itt = rejected_pdu.itt & ISCSI_ITT_MASK;
342 printk(KERN_ERR "itt 0x%x had pdu (op 0x%x) rejected "
343 "due to DataDigest error.\n", itt,
344 rejected_pdu.opcode);
345 }
346 }
347 return 0;
348}
349
278/** 350/**
279 * __iscsi_complete_pdu - complete pdu 351 * __iscsi_complete_pdu - complete pdu
280 * @conn: iscsi conn 352 * @conn: iscsi conn
@@ -316,7 +388,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
316 BUG_ON((void*)ctask != ctask->sc->SCp.ptr); 388 BUG_ON((void*)ctask != ctask->sc->SCp.ptr);
317 if (hdr->flags & ISCSI_FLAG_DATA_STATUS) { 389 if (hdr->flags & ISCSI_FLAG_DATA_STATUS) {
318 conn->scsirsp_pdus_cnt++; 390 conn->scsirsp_pdus_cnt++;
319 iscsi_complete_command(session, ctask); 391 __iscsi_put_ctask(ctask);
320 } 392 }
321 break; 393 break;
322 case ISCSI_OP_R2T: 394 case ISCSI_OP_R2T:
@@ -340,6 +412,10 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
340 412
341 switch(opcode) { 413 switch(opcode) {
342 case ISCSI_OP_LOGOUT_RSP: 414 case ISCSI_OP_LOGOUT_RSP:
415 if (datalen) {
416 rc = ISCSI_ERR_PROTO;
417 break;
418 }
343 conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; 419 conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
344 /* fall through */ 420 /* fall through */
345 case ISCSI_OP_LOGIN_RSP: 421 case ISCSI_OP_LOGIN_RSP:
@@ -348,7 +424,8 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
348 * login related PDU's exp_statsn is handled in 424 * login related PDU's exp_statsn is handled in
349 * userspace 425 * userspace
350 */ 426 */
351 rc = iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen); 427 if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen))
428 rc = ISCSI_ERR_CONN_FAILED;
352 list_del(&mtask->running); 429 list_del(&mtask->running);
353 if (conn->login_mtask != mtask) 430 if (conn->login_mtask != mtask)
354 __kfifo_put(session->mgmtpool.queue, 431 __kfifo_put(session->mgmtpool.queue,
@@ -360,25 +437,17 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
360 break; 437 break;
361 } 438 }
362 439
363 conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; 440 iscsi_tmf_rsp(conn, hdr);
364 conn->tmfrsp_pdus_cnt++;
365 if (conn->tmabort_state == TMABORT_INITIAL) {
366 conn->tmabort_state =
367 ((struct iscsi_tm_rsp *)hdr)->
368 response == ISCSI_TMF_RSP_COMPLETE ?
369 TMABORT_SUCCESS:TMABORT_FAILED;
370 /* unblock eh_abort() */
371 wake_up(&conn->ehwait);
372 }
373 break; 441 break;
374 case ISCSI_OP_NOOP_IN: 442 case ISCSI_OP_NOOP_IN:
375 if (hdr->ttt != ISCSI_RESERVED_TAG) { 443 if (hdr->ttt != ISCSI_RESERVED_TAG || datalen) {
376 rc = ISCSI_ERR_PROTO; 444 rc = ISCSI_ERR_PROTO;
377 break; 445 break;
378 } 446 }
379 conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; 447 conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
380 448
381 rc = iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen); 449 if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen))
450 rc = ISCSI_ERR_CONN_FAILED;
382 list_del(&mtask->running); 451 list_del(&mtask->running);
383 if (conn->login_mtask != mtask) 452 if (conn->login_mtask != mtask)
384 __kfifo_put(session->mgmtpool.queue, 453 __kfifo_put(session->mgmtpool.queue,
@@ -389,19 +458,27 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
389 break; 458 break;
390 } 459 }
391 } else if (itt == ISCSI_RESERVED_TAG) { 460 } else if (itt == ISCSI_RESERVED_TAG) {
461 rc = iscsi_check_assign_cmdsn(session,
462 (struct iscsi_nopin*)hdr);
463 if (rc)
464 goto done;
465
392 switch(opcode) { 466 switch(opcode) {
393 case ISCSI_OP_NOOP_IN: 467 case ISCSI_OP_NOOP_IN:
394 if (!datalen) { 468 if (datalen) {
395 rc = iscsi_check_assign_cmdsn(session,
396 (struct iscsi_nopin*)hdr);
397 if (!rc && hdr->ttt != ISCSI_RESERVED_TAG)
398 rc = iscsi_recv_pdu(conn->cls_conn,
399 hdr, NULL, 0);
400 } else
401 rc = ISCSI_ERR_PROTO; 469 rc = ISCSI_ERR_PROTO;
470 break;
471 }
472
473 if (hdr->ttt == ISCSI_RESERVED_TAG)
474 break;
475
476 if (iscsi_recv_pdu(conn->cls_conn, hdr, NULL, 0))
477 rc = ISCSI_ERR_CONN_FAILED;
402 break; 478 break;
403 case ISCSI_OP_REJECT: 479 case ISCSI_OP_REJECT:
404 /* we need sth like iscsi_reject_rsp()*/ 480 rc = iscsi_handle_reject(conn, hdr, data, datalen);
481 break;
405 case ISCSI_OP_ASYNC_EVENT: 482 case ISCSI_OP_ASYNC_EVENT:
406 conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; 483 conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
407 /* we need sth like iscsi_async_event_rsp() */ 484 /* we need sth like iscsi_async_event_rsp() */
@@ -537,7 +614,9 @@ static int iscsi_data_xmit(struct iscsi_conn *conn)
537 BUG_ON(conn->ctask && conn->mtask); 614 BUG_ON(conn->ctask && conn->mtask);
538 615
539 if (conn->ctask) { 616 if (conn->ctask) {
617 iscsi_get_ctask(conn->ctask);
540 rc = tt->xmit_cmd_task(conn, conn->ctask); 618 rc = tt->xmit_cmd_task(conn, conn->ctask);
619 iscsi_put_ctask(conn->ctask);
541 if (rc) 620 if (rc)
542 goto again; 621 goto again;
543 /* done with this in-progress ctask */ 622 /* done with this in-progress ctask */
@@ -568,20 +647,31 @@ static int iscsi_data_xmit(struct iscsi_conn *conn)
568 } 647 }
569 648
570 /* process command queue */ 649 /* process command queue */
571 while (__kfifo_get(conn->xmitqueue, (void*)&conn->ctask, 650 spin_lock_bh(&conn->session->lock);
572 sizeof(void*))) { 651 while (!list_empty(&conn->xmitqueue)) {
573 /* 652 /*
574 * iscsi tcp may readd the task to the xmitqueue to send 653 * iscsi tcp may readd the task to the xmitqueue to send
575 * write data 654 * write data
576 */ 655 */
577 spin_lock_bh(&conn->session->lock); 656 conn->ctask = list_entry(conn->xmitqueue.next,
578 if (list_empty(&conn->ctask->running)) 657 struct iscsi_cmd_task, running);
579 list_add_tail(&conn->ctask->running, &conn->run_list); 658 conn->ctask->state = ISCSI_TASK_RUNNING;
659 list_move_tail(conn->xmitqueue.next, &conn->run_list);
660 __iscsi_get_ctask(conn->ctask);
580 spin_unlock_bh(&conn->session->lock); 661 spin_unlock_bh(&conn->session->lock);
662
581 rc = tt->xmit_cmd_task(conn, conn->ctask); 663 rc = tt->xmit_cmd_task(conn, conn->ctask);
582 if (rc) 664 if (rc)
583 goto again; 665 goto again;
666
667 spin_lock_bh(&conn->session->lock);
668 __iscsi_put_ctask(conn->ctask);
669 if (rc) {
670 spin_unlock_bh(&conn->session->lock);
671 goto again;
672 }
584 } 673 }
674 spin_unlock_bh(&conn->session->lock);
585 /* done with this ctask */ 675 /* done with this ctask */
586 conn->ctask = NULL; 676 conn->ctask = NULL;
587 677
@@ -629,6 +719,7 @@ enum {
629 FAILURE_SESSION_FAILED, 719 FAILURE_SESSION_FAILED,
630 FAILURE_SESSION_FREED, 720 FAILURE_SESSION_FREED,
631 FAILURE_WINDOW_CLOSED, 721 FAILURE_WINDOW_CLOSED,
722 FAILURE_OOM,
632 FAILURE_SESSION_TERMINATE, 723 FAILURE_SESSION_TERMINATE,
633 FAILURE_SESSION_IN_RECOVERY, 724 FAILURE_SESSION_IN_RECOVERY,
634 FAILURE_SESSION_RECOVERY_TIMEOUT, 725 FAILURE_SESSION_RECOVERY_TIMEOUT,
@@ -644,6 +735,7 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
644 735
645 sc->scsi_done = done; 736 sc->scsi_done = done;
646 sc->result = 0; 737 sc->result = 0;
738 sc->SCp.ptr = NULL;
647 739
648 host = sc->device->host; 740 host = sc->device->host;
649 session = iscsi_hostdata(host->hostdata); 741 session = iscsi_hostdata(host->hostdata);
@@ -687,10 +779,16 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
687 779
688 conn = session->leadconn; 780 conn = session->leadconn;
689 781
690 __kfifo_get(session->cmdpool.queue, (void*)&ctask, sizeof(void*)); 782 if (!__kfifo_get(session->cmdpool.queue, (void*)&ctask,
783 sizeof(void*))) {
784 reason = FAILURE_OOM;
785 goto reject;
786 }
691 sc->SCp.phase = session->age; 787 sc->SCp.phase = session->age;
692 sc->SCp.ptr = (char *)ctask; 788 sc->SCp.ptr = (char *)ctask;
693 789
790 atomic_set(&ctask->refcount, 1);
791 ctask->state = ISCSI_TASK_PENDING;
694 ctask->mtask = NULL; 792 ctask->mtask = NULL;
695 ctask->conn = conn; 793 ctask->conn = conn;
696 ctask->sc = sc; 794 ctask->sc = sc;
@@ -700,11 +798,12 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
700 798
701 session->tt->init_cmd_task(ctask); 799 session->tt->init_cmd_task(ctask);
702 800
703 __kfifo_put(conn->xmitqueue, (void*)&ctask, sizeof(void*)); 801 list_add_tail(&ctask->running, &conn->xmitqueue);
704 debug_scsi( 802 debug_scsi(
705 "ctask enq [%s cid %d sc %lx itt 0x%x len %d cmdsn %d win %d]\n", 803 "ctask enq [%s cid %d sc %p cdb 0x%x itt 0x%x len %d cmdsn %d "
804 "win %d]\n",
706 sc->sc_data_direction == DMA_TO_DEVICE ? "write" : "read", 805 sc->sc_data_direction == DMA_TO_DEVICE ? "write" : "read",
707 conn->id, (long)sc, ctask->itt, sc->request_bufflen, 806 conn->id, sc, sc->cmnd[0], ctask->itt, sc->request_bufflen,
708 session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1); 807 session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1);
709 spin_unlock(&session->lock); 808 spin_unlock(&session->lock);
710 809
@@ -977,31 +1076,27 @@ static int iscsi_exec_abort_task(struct scsi_cmnd *sc,
977/* 1076/*
978 * xmit mutex and session lock must be held 1077 * xmit mutex and session lock must be held
979 */ 1078 */
980#define iscsi_remove_task(tasktype) \ 1079static struct iscsi_mgmt_task *
981static struct iscsi_##tasktype * \ 1080iscsi_remove_mgmt_task(struct kfifo *fifo, uint32_t itt)
982iscsi_remove_##tasktype(struct kfifo *fifo, uint32_t itt) \ 1081{
983{ \ 1082 int i, nr_tasks = __kfifo_len(fifo) / sizeof(void*);
984 int i, nr_tasks = __kfifo_len(fifo) / sizeof(void*); \ 1083 struct iscsi_mgmt_task *task;
985 struct iscsi_##tasktype *task; \ 1084
986 \ 1085 debug_scsi("searching %d tasks\n", nr_tasks);
987 debug_scsi("searching %d tasks\n", nr_tasks); \ 1086
988 \ 1087 for (i = 0; i < nr_tasks; i++) {
989 for (i = 0; i < nr_tasks; i++) { \ 1088 __kfifo_get(fifo, (void*)&task, sizeof(void*));
990 __kfifo_get(fifo, (void*)&task, sizeof(void*)); \ 1089 debug_scsi("check task %u\n", task->itt);
991 debug_scsi("check task %u\n", task->itt); \ 1090
992 \ 1091 if (task->itt == itt) {
993 if (task->itt == itt) { \ 1092 debug_scsi("matched task\n");
994 debug_scsi("matched task\n"); \ 1093 return task;
995 return task; \ 1094 }
996 } \
997 \
998 __kfifo_put(fifo, (void*)&task, sizeof(void*)); \
999 } \
1000 return NULL; \
1001}
1002 1095
1003iscsi_remove_task(mgmt_task); 1096 __kfifo_put(fifo, (void*)&task, sizeof(void*));
1004iscsi_remove_task(cmd_task); 1097 }
1098 return NULL;
1099}
1005 1100
1006static int iscsi_ctask_mtask_cleanup(struct iscsi_cmd_task *ctask) 1101static int iscsi_ctask_mtask_cleanup(struct iscsi_cmd_task *ctask)
1007{ 1102{
@@ -1027,25 +1122,39 @@ static void fail_command(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
1027{ 1122{
1028 struct scsi_cmnd *sc; 1123 struct scsi_cmnd *sc;
1029 1124
1030 conn->session->tt->cleanup_cmd_task(conn, ctask);
1031 iscsi_ctask_mtask_cleanup(ctask);
1032
1033 sc = ctask->sc; 1125 sc = ctask->sc;
1034 if (!sc) 1126 if (!sc)
1035 return; 1127 return;
1128
1129 conn->session->tt->cleanup_cmd_task(conn, ctask);
1130 iscsi_ctask_mtask_cleanup(ctask);
1131
1036 sc->result = err; 1132 sc->result = err;
1037 sc->resid = sc->request_bufflen; 1133 sc->resid = sc->request_bufflen;
1038 iscsi_complete_command(conn->session, ctask); 1134 /* release ref from queuecommand */
1135 __iscsi_put_ctask(ctask);
1039} 1136}
1040 1137
1041int iscsi_eh_abort(struct scsi_cmnd *sc) 1138int iscsi_eh_abort(struct scsi_cmnd *sc)
1042{ 1139{
1043 struct iscsi_cmd_task *ctask = (struct iscsi_cmd_task *)sc->SCp.ptr; 1140 struct iscsi_cmd_task *ctask;
1044 struct iscsi_conn *conn = ctask->conn; 1141 struct iscsi_conn *conn;
1045 struct iscsi_session *session = conn->session; 1142 struct iscsi_session *session;
1046 struct iscsi_cmd_task *pending_ctask;
1047 int rc; 1143 int rc;
1048 1144
1145 /*
1146 * if session was ISCSI_STATE_IN_RECOVERY then we may not have
1147 * got the command.
1148 */
1149 if (!sc->SCp.ptr) {
1150 debug_scsi("sc never reached iscsi layer or it completed.\n");
1151 return SUCCESS;
1152 }
1153
1154 ctask = (struct iscsi_cmd_task *)sc->SCp.ptr;
1155 conn = ctask->conn;
1156 session = conn->session;
1157
1049 conn->eh_abort_cnt++; 1158 conn->eh_abort_cnt++;
1050 debug_scsi("aborting [sc %p itt 0x%x]\n", sc, ctask->itt); 1159 debug_scsi("aborting [sc %p itt 0x%x]\n", sc, ctask->itt);
1051 1160
@@ -1061,8 +1170,11 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
1061 goto failed; 1170 goto failed;
1062 1171
1063 /* ctask completed before time out */ 1172 /* ctask completed before time out */
1064 if (!ctask->sc) 1173 if (!ctask->sc) {
1065 goto success; 1174 spin_unlock_bh(&session->lock);
1175 debug_scsi("sc completed while abort in progress\n");
1176 goto success_rel_mutex;
1177 }
1066 1178
1067 /* what should we do here ? */ 1179 /* what should we do here ? */
1068 if (conn->ctask == ctask) { 1180 if (conn->ctask == ctask) {
@@ -1071,17 +1183,8 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
1071 goto failed; 1183 goto failed;
1072 } 1184 }
1073 1185
1074 /* check for the easy pending cmd abort */ 1186 if (ctask->state == ISCSI_TASK_PENDING)
1075 pending_ctask = iscsi_remove_cmd_task(conn->xmitqueue, ctask->itt); 1187 goto success_cleanup;
1076 if (pending_ctask) {
1077 /* iscsi_tcp queues write transfers on the xmitqueue */
1078 if (list_empty(&pending_ctask->running)) {
1079 debug_scsi("found pending task\n");
1080 goto success;
1081 } else
1082 __kfifo_put(conn->xmitqueue, (void*)&pending_ctask,
1083 sizeof(void*));
1084 }
1085 1188
1086 conn->tmabort_state = TMABORT_INITIAL; 1189 conn->tmabort_state = TMABORT_INITIAL;
1087 1190
@@ -1089,25 +1192,31 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
1089 rc = iscsi_exec_abort_task(sc, ctask); 1192 rc = iscsi_exec_abort_task(sc, ctask);
1090 spin_lock_bh(&session->lock); 1193 spin_lock_bh(&session->lock);
1091 1194
1092 iscsi_ctask_mtask_cleanup(ctask);
1093 if (rc || sc->SCp.phase != session->age || 1195 if (rc || sc->SCp.phase != session->age ||
1094 session->state != ISCSI_STATE_LOGGED_IN) 1196 session->state != ISCSI_STATE_LOGGED_IN)
1095 goto failed; 1197 goto failed;
1198 iscsi_ctask_mtask_cleanup(ctask);
1096 1199
1097 /* ctask completed before tmf abort response */ 1200 switch (conn->tmabort_state) {
1098 if (!ctask->sc) { 1201 case TMABORT_SUCCESS:
1099 debug_scsi("sc completed while abort in progress\n"); 1202 goto success_cleanup;
1100 goto success; 1203 case TMABORT_NOT_FOUND:
1101 } 1204 if (!ctask->sc) {
1102 1205 /* ctask completed before tmf abort response */
1103 if (conn->tmabort_state != TMABORT_SUCCESS) { 1206 spin_unlock_bh(&session->lock);
1207 debug_scsi("sc completed while abort in progress\n");
1208 goto success_rel_mutex;
1209 }
1210 /* fall through */
1211 default:
1212 /* timedout or failed */
1104 spin_unlock_bh(&session->lock); 1213 spin_unlock_bh(&session->lock);
1105 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); 1214 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
1106 spin_lock_bh(&session->lock); 1215 spin_lock_bh(&session->lock);
1107 goto failed; 1216 goto failed;
1108 } 1217 }
1109 1218
1110success: 1219success_cleanup:
1111 debug_scsi("abort success [sc %lx itt 0x%x]\n", (long)sc, ctask->itt); 1220 debug_scsi("abort success [sc %lx itt 0x%x]\n", (long)sc, ctask->itt);
1112 spin_unlock_bh(&session->lock); 1221 spin_unlock_bh(&session->lock);
1113 1222
@@ -1121,6 +1230,7 @@ success:
1121 spin_unlock(&session->lock); 1230 spin_unlock(&session->lock);
1122 write_unlock_bh(conn->recv_lock); 1231 write_unlock_bh(conn->recv_lock);
1123 1232
1233success_rel_mutex:
1124 mutex_unlock(&conn->xmitmutex); 1234 mutex_unlock(&conn->xmitmutex);
1125 return SUCCESS; 1235 return SUCCESS;
1126 1236
@@ -1263,6 +1373,7 @@ iscsi_session_setup(struct iscsi_transport *iscsit,
1263 if (cmd_task_size) 1373 if (cmd_task_size)
1264 ctask->dd_data = &ctask[1]; 1374 ctask->dd_data = &ctask[1];
1265 ctask->itt = cmd_i; 1375 ctask->itt = cmd_i;
1376 INIT_LIST_HEAD(&ctask->running);
1266 } 1377 }
1267 1378
1268 spin_lock_init(&session->lock); 1379 spin_lock_init(&session->lock);
@@ -1282,18 +1393,24 @@ iscsi_session_setup(struct iscsi_transport *iscsit,
1282 if (mgmt_task_size) 1393 if (mgmt_task_size)
1283 mtask->dd_data = &mtask[1]; 1394 mtask->dd_data = &mtask[1];
1284 mtask->itt = ISCSI_MGMT_ITT_OFFSET + cmd_i; 1395 mtask->itt = ISCSI_MGMT_ITT_OFFSET + cmd_i;
1396 INIT_LIST_HEAD(&mtask->running);
1285 } 1397 }
1286 1398
1287 if (scsi_add_host(shost, NULL)) 1399 if (scsi_add_host(shost, NULL))
1288 goto add_host_fail; 1400 goto add_host_fail;
1289 1401
1402 if (!try_module_get(iscsit->owner))
1403 goto cls_session_fail;
1404
1290 cls_session = iscsi_create_session(shost, iscsit, 0); 1405 cls_session = iscsi_create_session(shost, iscsit, 0);
1291 if (!cls_session) 1406 if (!cls_session)
1292 goto cls_session_fail; 1407 goto module_put;
1293 *(unsigned long*)shost->hostdata = (unsigned long)cls_session; 1408 *(unsigned long*)shost->hostdata = (unsigned long)cls_session;
1294 1409
1295 return cls_session; 1410 return cls_session;
1296 1411
1412module_put:
1413 module_put(iscsit->owner);
1297cls_session_fail: 1414cls_session_fail:
1298 scsi_remove_host(shost); 1415 scsi_remove_host(shost);
1299add_host_fail: 1416add_host_fail:
@@ -1317,14 +1434,18 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session)
1317{ 1434{
1318 struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); 1435 struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
1319 struct iscsi_session *session = iscsi_hostdata(shost->hostdata); 1436 struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
1437 struct module *owner = cls_session->transport->owner;
1320 1438
1321 scsi_remove_host(shost); 1439 scsi_remove_host(shost);
1322 1440
1323 iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds); 1441 iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds);
1324 iscsi_pool_free(&session->cmdpool, (void**)session->cmds); 1442 iscsi_pool_free(&session->cmdpool, (void**)session->cmds);
1325 1443
1444 kfree(session->targetname);
1445
1326 iscsi_destroy_session(cls_session); 1446 iscsi_destroy_session(cls_session);
1327 scsi_host_put(shost); 1447 scsi_host_put(shost);
1448 module_put(owner);
1328} 1449}
1329EXPORT_SYMBOL_GPL(iscsi_session_teardown); 1450EXPORT_SYMBOL_GPL(iscsi_session_teardown);
1330 1451
@@ -1355,12 +1476,7 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, uint32_t conn_idx)
1355 conn->tmabort_state = TMABORT_INITIAL; 1476 conn->tmabort_state = TMABORT_INITIAL;
1356 INIT_LIST_HEAD(&conn->run_list); 1477 INIT_LIST_HEAD(&conn->run_list);
1357 INIT_LIST_HEAD(&conn->mgmt_run_list); 1478 INIT_LIST_HEAD(&conn->mgmt_run_list);
1358 1479 INIT_LIST_HEAD(&conn->xmitqueue);
1359 /* initialize general xmit PDU commands queue */
1360 conn->xmitqueue = kfifo_alloc(session->cmds_max * sizeof(void*),
1361 GFP_KERNEL, NULL);
1362 if (conn->xmitqueue == ERR_PTR(-ENOMEM))
1363 goto xmitqueue_alloc_fail;
1364 1480
1365 /* initialize general immediate & non-immediate PDU commands queue */ 1481 /* initialize general immediate & non-immediate PDU commands queue */
1366 conn->immqueue = kfifo_alloc(session->mgmtpool_max * sizeof(void*), 1482 conn->immqueue = kfifo_alloc(session->mgmtpool_max * sizeof(void*),
@@ -1388,7 +1504,7 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, uint32_t conn_idx)
1388 data = kmalloc(DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH, GFP_KERNEL); 1504 data = kmalloc(DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH, GFP_KERNEL);
1389 if (!data) 1505 if (!data)
1390 goto login_mtask_data_alloc_fail; 1506 goto login_mtask_data_alloc_fail;
1391 conn->login_mtask->data = data; 1507 conn->login_mtask->data = conn->data = data;
1392 1508
1393 init_timer(&conn->tmabort_timer); 1509 init_timer(&conn->tmabort_timer);
1394 mutex_init(&conn->xmitmutex); 1510 mutex_init(&conn->xmitmutex);
@@ -1404,8 +1520,6 @@ login_mtask_alloc_fail:
1404mgmtqueue_alloc_fail: 1520mgmtqueue_alloc_fail:
1405 kfifo_free(conn->immqueue); 1521 kfifo_free(conn->immqueue);
1406immqueue_alloc_fail: 1522immqueue_alloc_fail:
1407 kfifo_free(conn->xmitqueue);
1408xmitqueue_alloc_fail:
1409 iscsi_destroy_conn(cls_conn); 1523 iscsi_destroy_conn(cls_conn);
1410 return NULL; 1524 return NULL;
1411} 1525}
@@ -1426,12 +1540,6 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
1426 1540
1427 set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); 1541 set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
1428 mutex_lock(&conn->xmitmutex); 1542 mutex_lock(&conn->xmitmutex);
1429 if (conn->c_stage == ISCSI_CONN_INITIAL_STAGE) {
1430 if (session->tt->suspend_conn_recv)
1431 session->tt->suspend_conn_recv(conn);
1432
1433 session->tt->terminate_conn(conn);
1434 }
1435 1543
1436 spin_lock_bh(&session->lock); 1544 spin_lock_bh(&session->lock);
1437 conn->c_stage = ISCSI_CONN_CLEANUP_WAIT; 1545 conn->c_stage = ISCSI_CONN_CLEANUP_WAIT;
@@ -1468,7 +1576,8 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
1468 } 1576 }
1469 1577
1470 spin_lock_bh(&session->lock); 1578 spin_lock_bh(&session->lock);
1471 kfree(conn->login_mtask->data); 1579 kfree(conn->data);
1580 kfree(conn->persistent_address);
1472 __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask, 1581 __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask,
1473 sizeof(void*)); 1582 sizeof(void*));
1474 list_del(&conn->item); 1583 list_del(&conn->item);
@@ -1483,7 +1592,6 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
1483 session->cmdsn = session->max_cmdsn = session->exp_cmdsn = 1; 1592 session->cmdsn = session->max_cmdsn = session->exp_cmdsn = 1;
1484 spin_unlock_bh(&session->lock); 1593 spin_unlock_bh(&session->lock);
1485 1594
1486 kfifo_free(conn->xmitqueue);
1487 kfifo_free(conn->immqueue); 1595 kfifo_free(conn->immqueue);
1488 kfifo_free(conn->mgmtqueue); 1596 kfifo_free(conn->mgmtqueue);
1489 1597
@@ -1496,11 +1604,19 @@ int iscsi_conn_start(struct iscsi_cls_conn *cls_conn)
1496 struct iscsi_conn *conn = cls_conn->dd_data; 1604 struct iscsi_conn *conn = cls_conn->dd_data;
1497 struct iscsi_session *session = conn->session; 1605 struct iscsi_session *session = conn->session;
1498 1606
1499 if (session == NULL) { 1607 if (!session) {
1500 printk(KERN_ERR "iscsi: can't start unbound connection\n"); 1608 printk(KERN_ERR "iscsi: can't start unbound connection\n");
1501 return -EPERM; 1609 return -EPERM;
1502 } 1610 }
1503 1611
1612 if ((session->imm_data_en || !session->initial_r2t_en) &&
1613 session->first_burst > session->max_burst) {
1614 printk("iscsi: invalid burst lengths: "
1615 "first_burst %d max_burst %d\n",
1616 session->first_burst, session->max_burst);
1617 return -EINVAL;
1618 }
1619
1504 spin_lock_bh(&session->lock); 1620 spin_lock_bh(&session->lock);
1505 conn->c_stage = ISCSI_CONN_STARTED; 1621 conn->c_stage = ISCSI_CONN_STARTED;
1506 session->state = ISCSI_STATE_LOGGED_IN; 1622 session->state = ISCSI_STATE_LOGGED_IN;
@@ -1566,7 +1682,7 @@ static void fail_all_commands(struct iscsi_conn *conn)
1566 struct iscsi_cmd_task *ctask, *tmp; 1682 struct iscsi_cmd_task *ctask, *tmp;
1567 1683
1568 /* flush pending */ 1684 /* flush pending */
1569 while (__kfifo_get(conn->xmitqueue, (void*)&ctask, sizeof(void*))) { 1685 list_for_each_entry_safe(ctask, tmp, &conn->xmitqueue, running) {
1570 debug_scsi("failing pending sc %p itt 0x%x\n", ctask->sc, 1686 debug_scsi("failing pending sc %p itt 0x%x\n", ctask->sc,
1571 ctask->itt); 1687 ctask->itt);
1572 fail_command(conn, ctask, DID_BUS_BUSY << 16); 1688 fail_command(conn, ctask, DID_BUS_BUSY << 16);
@@ -1609,8 +1725,9 @@ static void iscsi_start_session_recovery(struct iscsi_session *session,
1609 set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); 1725 set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
1610 spin_unlock_bh(&session->lock); 1726 spin_unlock_bh(&session->lock);
1611 1727
1612 if (session->tt->suspend_conn_recv) 1728 write_lock_bh(conn->recv_lock);
1613 session->tt->suspend_conn_recv(conn); 1729 set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx);
1730 write_unlock_bh(conn->recv_lock);
1614 1731
1615 mutex_lock(&conn->xmitmutex); 1732 mutex_lock(&conn->xmitmutex);
1616 /* 1733 /*
@@ -1629,7 +1746,6 @@ static void iscsi_start_session_recovery(struct iscsi_session *session,
1629 } 1746 }
1630 } 1747 }
1631 1748
1632 session->tt->terminate_conn(conn);
1633 /* 1749 /*
1634 * flush queues. 1750 * flush queues.
1635 */ 1751 */
@@ -1697,6 +1813,185 @@ int iscsi_conn_bind(struct iscsi_cls_session *cls_session,
1697} 1813}
1698EXPORT_SYMBOL_GPL(iscsi_conn_bind); 1814EXPORT_SYMBOL_GPL(iscsi_conn_bind);
1699 1815
1816
1817int iscsi_set_param(struct iscsi_cls_conn *cls_conn,
1818 enum iscsi_param param, char *buf, int buflen)
1819{
1820 struct iscsi_conn *conn = cls_conn->dd_data;
1821 struct iscsi_session *session = conn->session;
1822 uint32_t value;
1823
1824 switch(param) {
1825 case ISCSI_PARAM_MAX_RECV_DLENGTH:
1826 sscanf(buf, "%d", &conn->max_recv_dlength);
1827 break;
1828 case ISCSI_PARAM_MAX_XMIT_DLENGTH:
1829 sscanf(buf, "%d", &conn->max_xmit_dlength);
1830 break;
1831 case ISCSI_PARAM_HDRDGST_EN:
1832 sscanf(buf, "%d", &conn->hdrdgst_en);
1833 break;
1834 case ISCSI_PARAM_DATADGST_EN:
1835 sscanf(buf, "%d", &conn->datadgst_en);
1836 break;
1837 case ISCSI_PARAM_INITIAL_R2T_EN:
1838 sscanf(buf, "%d", &session->initial_r2t_en);
1839 break;
1840 case ISCSI_PARAM_MAX_R2T:
1841 sscanf(buf, "%d", &session->max_r2t);
1842 break;
1843 case ISCSI_PARAM_IMM_DATA_EN:
1844 sscanf(buf, "%d", &session->imm_data_en);
1845 break;
1846 case ISCSI_PARAM_FIRST_BURST:
1847 sscanf(buf, "%d", &session->first_burst);
1848 break;
1849 case ISCSI_PARAM_MAX_BURST:
1850 sscanf(buf, "%d", &session->max_burst);
1851 break;
1852 case ISCSI_PARAM_PDU_INORDER_EN:
1853 sscanf(buf, "%d", &session->pdu_inorder_en);
1854 break;
1855 case ISCSI_PARAM_DATASEQ_INORDER_EN:
1856 sscanf(buf, "%d", &session->dataseq_inorder_en);
1857 break;
1858 case ISCSI_PARAM_ERL:
1859 sscanf(buf, "%d", &session->erl);
1860 break;
1861 case ISCSI_PARAM_IFMARKER_EN:
1862 sscanf(buf, "%d", &value);
1863 BUG_ON(value);
1864 break;
1865 case ISCSI_PARAM_OFMARKER_EN:
1866 sscanf(buf, "%d", &value);
1867 BUG_ON(value);
1868 break;
1869 case ISCSI_PARAM_EXP_STATSN:
1870 sscanf(buf, "%u", &conn->exp_statsn);
1871 break;
1872 case ISCSI_PARAM_TARGET_NAME:
1873 /* this should not change between logins */
1874 if (session->targetname)
1875 break;
1876
1877 session->targetname = kstrdup(buf, GFP_KERNEL);
1878 if (!session->targetname)
1879 return -ENOMEM;
1880 break;
1881 case ISCSI_PARAM_TPGT:
1882 sscanf(buf, "%d", &session->tpgt);
1883 break;
1884 case ISCSI_PARAM_PERSISTENT_PORT:
1885 sscanf(buf, "%d", &conn->persistent_port);
1886 break;
1887 case ISCSI_PARAM_PERSISTENT_ADDRESS:
1888 /*
1889 * this is the address returned in discovery so it should
1890 * not change between logins.
1891 */
1892 if (conn->persistent_address)
1893 break;
1894
1895 conn->persistent_address = kstrdup(buf, GFP_KERNEL);
1896 if (!conn->persistent_address)
1897 return -ENOMEM;
1898 break;
1899 default:
1900 return -ENOSYS;
1901 }
1902
1903 return 0;
1904}
1905EXPORT_SYMBOL_GPL(iscsi_set_param);
1906
1907int iscsi_session_get_param(struct iscsi_cls_session *cls_session,
1908 enum iscsi_param param, char *buf)
1909{
1910 struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
1911 struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
1912 int len;
1913
1914 switch(param) {
1915 case ISCSI_PARAM_INITIAL_R2T_EN:
1916 len = sprintf(buf, "%d\n", session->initial_r2t_en);
1917 break;
1918 case ISCSI_PARAM_MAX_R2T:
1919 len = sprintf(buf, "%hu\n", session->max_r2t);
1920 break;
1921 case ISCSI_PARAM_IMM_DATA_EN:
1922 len = sprintf(buf, "%d\n", session->imm_data_en);
1923 break;
1924 case ISCSI_PARAM_FIRST_BURST:
1925 len = sprintf(buf, "%u\n", session->first_burst);
1926 break;
1927 case ISCSI_PARAM_MAX_BURST:
1928 len = sprintf(buf, "%u\n", session->max_burst);
1929 break;
1930 case ISCSI_PARAM_PDU_INORDER_EN:
1931 len = sprintf(buf, "%d\n", session->pdu_inorder_en);
1932 break;
1933 case ISCSI_PARAM_DATASEQ_INORDER_EN:
1934 len = sprintf(buf, "%d\n", session->dataseq_inorder_en);
1935 break;
1936 case ISCSI_PARAM_ERL:
1937 len = sprintf(buf, "%d\n", session->erl);
1938 break;
1939 case ISCSI_PARAM_TARGET_NAME:
1940 len = sprintf(buf, "%s\n", session->targetname);
1941 break;
1942 case ISCSI_PARAM_TPGT:
1943 len = sprintf(buf, "%d\n", session->tpgt);
1944 break;
1945 default:
1946 return -ENOSYS;
1947 }
1948
1949 return len;
1950}
1951EXPORT_SYMBOL_GPL(iscsi_session_get_param);
1952
1953int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
1954 enum iscsi_param param, char *buf)
1955{
1956 struct iscsi_conn *conn = cls_conn->dd_data;
1957 int len;
1958
1959 switch(param) {
1960 case ISCSI_PARAM_MAX_RECV_DLENGTH:
1961 len = sprintf(buf, "%u\n", conn->max_recv_dlength);
1962 break;
1963 case ISCSI_PARAM_MAX_XMIT_DLENGTH:
1964 len = sprintf(buf, "%u\n", conn->max_xmit_dlength);
1965 break;
1966 case ISCSI_PARAM_HDRDGST_EN:
1967 len = sprintf(buf, "%d\n", conn->hdrdgst_en);
1968 break;
1969 case ISCSI_PARAM_DATADGST_EN:
1970 len = sprintf(buf, "%d\n", conn->datadgst_en);
1971 break;
1972 case ISCSI_PARAM_IFMARKER_EN:
1973 len = sprintf(buf, "%d\n", conn->ifmarker_en);
1974 break;
1975 case ISCSI_PARAM_OFMARKER_EN:
1976 len = sprintf(buf, "%d\n", conn->ofmarker_en);
1977 break;
1978 case ISCSI_PARAM_EXP_STATSN:
1979 len = sprintf(buf, "%u\n", conn->exp_statsn);
1980 break;
1981 case ISCSI_PARAM_PERSISTENT_PORT:
1982 len = sprintf(buf, "%d\n", conn->persistent_port);
1983 break;
1984 case ISCSI_PARAM_PERSISTENT_ADDRESS:
1985 len = sprintf(buf, "%s\n", conn->persistent_address);
1986 break;
1987 default:
1988 return -ENOSYS;
1989 }
1990
1991 return len;
1992}
1993EXPORT_SYMBOL_GPL(iscsi_conn_get_param);
1994
1700MODULE_AUTHOR("Mike Christie"); 1995MODULE_AUTHOR("Mike Christie");
1701MODULE_DESCRIPTION("iSCSI library functions"); 1996MODULE_DESCRIPTION("iSCSI library functions");
1702MODULE_LICENSE("GPL"); 1997MODULE_LICENSE("GPL");