| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: iscsi_send.c,v 1.34 2017/02/25 12:03:57 mlelstv Exp $ */ | | 1 | /* $NetBSD: iscsi_send.c,v 1.35 2017/12/03 07:23:12 mlelstv Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2004,2005,2006,2011 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2004,2005,2006,2011 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Wasabi Systems, Inc. | | 8 | * by Wasabi Systems, Inc. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -385,27 +385,27 @@ iscsi_send_thread(void *par) | | | @@ -385,27 +385,27 @@ iscsi_send_thread(void *par) |
385 | /* If there's another connection available, transfer pending tasks */ | | 385 | /* If there's another connection available, transfer pending tasks */ |
386 | if (sess->active_connections && | | 386 | if (sess->active_connections && |
387 | TAILQ_FIRST(&conn->ccbs_waiting) != NULL) { | | 387 | TAILQ_FIRST(&conn->ccbs_waiting) != NULL) { |
388 | | | 388 | |
389 | reassign_tasks(conn); | | 389 | reassign_tasks(conn); |
390 | } else if (!conn->destroy && conn->Time2Wait) { | | 390 | } else if (!conn->destroy && conn->Time2Wait) { |
391 | DEBC(conn, 1, ("Time2Wait\n")); | | 391 | DEBC(conn, 1, ("Time2Wait\n")); |
392 | kpause("Time2Wait", false, conn->Time2Wait * hz, NULL); | | 392 | kpause("Time2Wait", false, conn->Time2Wait * hz, NULL); |
393 | DEBC(conn, 1, ("Time2Wait\n")); | | 393 | DEBC(conn, 1, ("Time2Wait\n")); |
394 | } | | 394 | } |
395 | /* notify event handlers of connection shutdown */ | | 395 | /* notify event handlers of connection shutdown */ |
396 | DEBC(conn, 1, ("%s\n", (conn->destroy) ? "TERMINATED" : "RECOVER")); | | 396 | DEBC(conn, 1, ("%s\n", (conn->destroy) ? "TERMINATED" : "RECOVER")); |
397 | add_event((conn->destroy) ? ISCSI_CONNECTION_TERMINATED | | 397 | add_event((conn->destroy) ? ISCSI_CONNECTION_TERMINATED |
398 | : ISCSI_RECOVER_CONNECTION, | | 398 | : ISCSI_RECOVER_CONNECTION, |
399 | sess->id, conn->id, conn->terminating); | | 399 | sess->id, conn->id, conn->terminating); |
400 | | | 400 | |
401 | DEBC(conn, 1, ("Waiting for conn_idle\n")); | | 401 | DEBC(conn, 1, ("Waiting for conn_idle\n")); |
402 | mutex_enter(&conn->lock); | | 402 | mutex_enter(&conn->lock); |
403 | if (!conn->destroy) | | 403 | if (!conn->destroy) |
404 | cv_timedwait(&conn->idle_cv, &conn->lock, CONNECTION_IDLE_TIMEOUT); | | 404 | cv_timedwait(&conn->idle_cv, &conn->lock, CONNECTION_IDLE_TIMEOUT); |
405 | mutex_exit(&conn->lock); | | 405 | mutex_exit(&conn->lock); |
406 | DEBC(conn, 1, ("Waited for conn_idle, destroy = %d\n", conn->destroy)); | | 406 | DEBC(conn, 1, ("Waited for conn_idle, destroy = %d\n", conn->destroy)); |
407 | | | 407 | |
408 | } while (!conn->destroy); | | 408 | } while (!conn->destroy); |
409 | | | 409 | |
410 | /* wake up anyone waiting for a PDU */ | | 410 | /* wake up anyone waiting for a PDU */ |
411 | mutex_enter(&conn->lock); | | 411 | mutex_enter(&conn->lock); |
| @@ -1241,30 +1241,35 @@ send_task_management(connection_t *conn, | | | @@ -1241,30 +1241,35 @@ send_task_management(connection_t *conn, |
1241 | { | | 1241 | { |
1242 | ccb_t *ccb; | | 1242 | ccb_t *ccb; |
1243 | pdu_t *ppdu; | | 1243 | pdu_t *ppdu; |
1244 | pdu_header_t *pdu; | | 1244 | pdu_header_t *pdu; |
1245 | | | 1245 | |
1246 | DEBC(conn, 5, ("Send_task_management, ref_ccb=%p, func = %d\n", | | 1246 | DEBC(conn, 5, ("Send_task_management, ref_ccb=%p, func = %d\n", |
1247 | ref_ccb, function)); | | 1247 | ref_ccb, function)); |
1248 | | | 1248 | |
1249 | if (function == TASK_REASSIGN && conn->session->ErrorRecoveryLevel < 2) | | 1249 | if (function == TASK_REASSIGN && conn->session->ErrorRecoveryLevel < 2) |
1250 | return ISCSI_STATUS_CANT_REASSIGN; | | 1250 | return ISCSI_STATUS_CANT_REASSIGN; |
1251 | | | 1251 | |
1252 | ccb = get_ccb(conn, xs == NULL); | | 1252 | ccb = get_ccb(conn, xs == NULL); |
1253 | /* can only happen if terminating... */ | | 1253 | /* can only happen if terminating... */ |
1254 | if (ccb == NULL) | | 1254 | if (ccb == NULL) { |
| | | 1255 | DEBC(conn, 0, ("send_task_management, ref_ccb=%p, xs=%p, term=%d. No CCB\n", |
| | | 1256 | ref_ccb, xs, conn->terminating)); |
1255 | return conn->terminating; | | 1257 | return conn->terminating; |
| | | 1258 | } |
1256 | ppdu = get_pdu(conn, xs == NULL); | | 1259 | ppdu = get_pdu(conn, xs == NULL); |
1257 | if (ppdu == NULL) { | | 1260 | if (ppdu == NULL) { |
| | | 1261 | DEBC(conn, 0, ("send_task_management, ref_ccb=%p, xs=%p, term=%d. No PDU\n", |
| | | 1262 | ref_ccb, xs, conn->terminating)); |
1258 | free_ccb(ccb); | | 1263 | free_ccb(ccb); |
1259 | return conn->terminating; | | 1264 | return conn->terminating; |
1260 | } | | 1265 | } |
1261 | | | 1266 | |
1262 | ccb->xs = xs; | | 1267 | ccb->xs = xs; |
1263 | | | 1268 | |
1264 | pdu = &ppdu->pdu; | | 1269 | pdu = &ppdu->pdu; |
1265 | pdu->Opcode = IOP_SCSI_Task_Management | OP_IMMEDIATE; | | 1270 | pdu->Opcode = IOP_SCSI_Task_Management | OP_IMMEDIATE; |
1266 | pdu->Flags = FLAG_FINAL | function; | | 1271 | pdu->Flags = FLAG_FINAL | function; |
1267 | | | 1272 | |
1268 | ccb->CmdSN = conn->session->CmdSN; | | 1273 | ccb->CmdSN = conn->session->CmdSN; |
1269 | pdu->p.task_req.CmdSN = htonl(ccb->CmdSN); | | 1274 | pdu->p.task_req.CmdSN = htonl(ccb->CmdSN); |
1270 | | | 1275 | |
| @@ -1479,26 +1484,27 @@ send_run_xfer(session_t *session, struct | | | @@ -1479,26 +1484,27 @@ send_run_xfer(session_t *session, struct |
1479 | | | 1484 | |
1480 | conn = assign_connection(session, waitok); | | 1485 | conn = assign_connection(session, waitok); |
1481 | | | 1486 | |
1482 | if (conn == NULL || conn->terminating || conn->state != ST_FULL_FEATURE) { | | 1487 | if (conn == NULL || conn->terminating || conn->state != ST_FULL_FEATURE) { |
1483 | xs->error = XS_SELTIMEOUT; | | 1488 | xs->error = XS_SELTIMEOUT; |
1484 | DEBC(conn, 10, ("run_xfer on dead connection\n")); | | 1489 | DEBC(conn, 10, ("run_xfer on dead connection\n")); |
1485 | scsipi_done(xs); | | 1490 | scsipi_done(xs); |
1486 | unref_session(session); | | 1491 | unref_session(session); |
1487 | return; | | 1492 | return; |
1488 | } | | 1493 | } |
1489 | | | 1494 | |
1490 | if (xs->xs_control & XS_CTL_RESET) { | | 1495 | if (xs->xs_control & XS_CTL_RESET) { |
1491 | if (send_task_management(conn, NULL, xs, TARGET_WARM_RESET)) { | | 1496 | if (send_task_management(conn, NULL, xs, TARGET_WARM_RESET)) { |
| | | 1497 | DEBC(conn, 0, ("send_task_management TARGET_WARM_RESET failed\n")); |
1492 | xs->error = XS_SELTIMEOUT; | | 1498 | xs->error = XS_SELTIMEOUT; |
1493 | scsipi_done(xs); | | 1499 | scsipi_done(xs); |
1494 | unref_session(session); | | 1500 | unref_session(session); |
1495 | } | | 1501 | } |
1496 | return; | | 1502 | return; |
1497 | } | | 1503 | } |
1498 | | | 1504 | |
1499 | ccb = get_ccb(conn, waitok); | | 1505 | ccb = get_ccb(conn, waitok); |
1500 | if (ccb == NULL) { | | 1506 | if (ccb == NULL) { |
1501 | xs->error = XS_BUSY; | | 1507 | xs->error = XS_BUSY; |
1502 | DEBC(conn, 5, ("No CCB in run_xfer, %d in use.\n", conn->usecount)); | | 1508 | DEBC(conn, 5, ("No CCB in run_xfer, %d in use.\n", conn->usecount)); |
1503 | scsipi_done(xs); | | 1509 | scsipi_done(xs); |
1504 | unref_session(session); | | 1510 | unref_session(session); |