Print this page
NEX-9981 Deadman timer panic from idm_refcnt_wait_ref thread while offlining iSCSI targets
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
NEX-6018 Return of the walking dead idm_refcnt_wait_ref comstar threads
Reviewed by:  Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by:  Evan Layton <evan.layton@nexenta.com>
NEX-3746 Panic seen if iSCSI Initiator sends a SCSI Response packet to target
NEX-3777 COMSTAR iscsi/io test can panic the target running 5.0
NEX-3785 This is on 5.0 release and iSCSI target can panic while running iSCSI mpxio disable test
Reviewed by: Steve Peng <steve.peng@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
NEX-2359 iSCSI target connection handling is missing refcount audit information
re #10417 rb2398 incorrect handling in iscsit of duplicate PDUs with cmdsn > expsn
re #9966: sysretq doesn't properly handle non-canonical addresses
re #9966: sysretq doesn't properly handle non-canonical addresses
--HG--
branch : stable-4.0
re #9822 - libiscsi test panics COMSTAR
--HG--
branch : stable-4.0
re #9822 - libiscsi test panics COMSTAR


   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  23  *
  24  * Copyright 2014, 2015 Nexenta Systems, Inc. All rights reserved.
  25  * Copyright (c) 2017, Joyent, Inc.  All rights reserved.
  26  */
  27 
  28 #include <sys/cpuvar.h>
  29 #include <sys/types.h>
  30 #include <sys/conf.h>
  31 #include <sys/stat.h>
  32 #include <sys/file.h>
  33 #include <sys/ddi.h>
  34 #include <sys/sunddi.h>
  35 #include <sys/modctl.h>
  36 #include <sys/sysmacros.h>
  37 #include <sys/socket.h>
  38 #include <sys/strsubr.h>
  39 #include <sys/nvpair.h>
  40 
  41 #include <sys/stmf.h>
  42 #include <sys/stmf_ioctl.h>
  43 #include <sys/portif.h>
  44 #include <sys/idm/idm.h>


 547                 if (rc != 0) {
 548                         goto cleanup;
 549                 }
 550 
 551                 /* Translate nvlist */
 552                 rc = it_nv_to_config(cfg_nvlist, &cfg);
 553                 if (rc != 0) {
 554                         cmn_err(CE_WARN, "Configuration is invalid");
 555                         goto cleanup;
 556                 }
 557 
 558                 /* Update config */
 559                 rc = iscsit_config_merge(cfg);
 560                 /* FALLTHROUGH */
 561 
 562 cleanup:
 563                 if (cfg)
 564                         it_config_free_cmn(cfg);
 565                 if (cfg_pnvlist)
 566                         kmem_free(cfg_pnvlist, setcfg.set_cfg_pnvlist_len);

 567                 nvlist_free(cfg_nvlist);
 568 
 569                 /*
 570                  * Now that the reconfig is complete set our state back to
 571                  * enabled.
 572                  */
 573                 mutex_enter(&iscsit_global.global_state_mutex);
 574                 iscsit_global.global_svc_state = ISE_ENABLED;
 575                 mutex_exit(&iscsit_global.global_state_mutex);
 576                 break;
 577         case ISCSIT_IOC_ENABLE_SVC: {
 578                 iscsit_hostinfo_t hostinfo;
 579 
 580                 if (ddi_copyin((void *)argp, &hostinfo.length,
 581                     sizeof (hostinfo.length), flag) != 0) {
 582                         mutex_enter(&iscsit_global.global_state_mutex);
 583                         iscsit_global.global_svc_state = ISE_DISABLED;
 584                         mutex_exit(&iscsit_global.global_state_mutex);
 585                         return (EFAULT);
 586                 }


 975                 /*
 976                  * We rely on the fact that STMF tracks outstanding
 977                  * buffer transfers and will free all of our buffers
 978                  * before freeing the task so we don't need to
 979                  * explicitly free the buffers from iscsit/idm
 980                  */
 981                 if (itask->it_stmf_abort) {
 982                         mutex_exit(&itask->it_mutex);
 983                         /*
 984                          * Task is no longer active
 985                          */
 986                         iscsit_task_done(itask);
 987 
 988                         /*
 989                          * STMF has already asked for this task to be aborted
 990                          *
 991                          * STMF specification is wrong... says to return
 992                          * STMF_ABORTED, the code actually looks for
 993                          * STMF_ABORT_SUCCESS.
 994                          */
 995                         stmf_task_lport_aborted(itask->it_stmf_task,
 996                             STMF_ABORT_SUCCESS, STMF_IOF_LPORT_DONE);
 997                         return;
 998                 } else {
 999                         mutex_exit(&itask->it_mutex);
1000                         /*
1001                          * Tell STMF to stop processing the task.
1002                          */
1003                         stmf_abort(STMF_QUEUE_TASK_ABORT, itask->it_stmf_task,
1004                             STMF_ABORTED, NULL);
1005                         return;
1006                 }
1007                 /*NOTREACHED*/
1008         default:
1009                 ASSERT(0);
1010         }
1011 }
1012 
1013 /*ARGSUSED*/
1014 idm_status_t
1015 iscsit_client_notify(idm_conn_t *ic, idm_client_notify_t icn,


1207                 mutex_exit(&iscsit_global.global_state_mutex);
1208                 return (IDM_STATUS_FAIL);
1209         }
1210         iscsit_global_hold();
1211         mutex_exit(&iscsit_global.global_state_mutex);
1212 
1213         /*
1214          * Allocate an associated iscsit structure to represent this
1215          * connection.  We shouldn't really create a session until we
1216          * get the first login PDU.
1217          */
1218         ict = kmem_zalloc(sizeof (*ict), KM_SLEEP);
1219 
1220         ict->ict_ic = ic;
1221         ict->ict_statsn = 1;
1222         ict->ict_keepalive_ttt = IDM_TASKIDS_MAX; /* Avoid IDM TT range */
1223         ic->ic_handle = ict;
1224         mutex_init(&ict->ict_mutex, NULL, MUTEX_DRIVER, NULL);
1225         mutex_init(&ict->ict_statsn_mutex, NULL, MUTEX_DRIVER, NULL);
1226         idm_refcnt_init(&ict->ict_refcnt, ict);

1227 
1228         /*
1229          * Initialize login state machine
1230          */
1231         if (iscsit_login_sm_init(ict) != IDM_STATUS_SUCCESS) {
1232                 iscsit_global_rele();
1233                 /*
1234                  * Cleanup the ict after idm notifies us about this failure
1235                  */
1236                 return (IDM_STATUS_FAIL);
1237         }
1238 
1239         return (IDM_STATUS_SUCCESS);
1240 }
1241 
1242 idm_status_t
1243 iscsit_conn_reinstate(iscsit_conn_t *reinstate_ict, iscsit_conn_t *new_ict)
1244 {
1245         idm_status_t    result;
1246 


1352                     ((cbuf->cb_num_elems > 0) && (i < ISCSIT_RXPDU_QUEUE_LEN));
1353                     i++) {
1354                         if (((rx_pdu = cbuf->cb_buffer[i]) != NULL) &&
1355                             (rx_pdu->isp_ic == ic)) {
1356                                 /* conn is lost, drop the pdu */
1357                                 DTRACE_PROBE3(scrubbing__staging__queue,
1358                                     iscsit_sess_t *, ist, idm_conn_t *, ic,
1359                                     idm_pdu_t *, rx_pdu);
1360                                 idm_pdu_complete(rx_pdu, IDM_STATUS_FAIL);
1361                                 cbuf->cb_buffer[i] = NULL;
1362                                 cbuf->cb_num_elems--;
1363                                 iscsit_conn_dispatch_rele(ict);
1364                         }
1365                 }
1366                 mutex_exit(&ist->ist_sn_mutex);
1367         }
1368         /*
1369          * Make sure there aren't any PDU's transitioning from the receive
1370          * handler to the dispatch taskq.
1371          */



1372         idm_refcnt_wait_ref(&ict->ict_dispatch_refcnt);
1373 
1374         return (IDM_STATUS_SUCCESS);
1375 }
1376 
1377 static idm_status_t
1378 iscsit_conn_destroy(idm_conn_t *ic)
1379 {
1380         iscsit_conn_t *ict = ic->ic_handle;
1381 
1382         mutex_enter(&ict->ict_mutex);
1383         ict->ict_destroyed = B_TRUE;
1384         mutex_exit(&ict->ict_mutex);
1385 
1386         /* Generate session state machine event */
1387         if (ict->ict_sess != NULL) {
1388                 /*
1389                  * Session state machine will call iscsit_conn_destroy_done()
1390                  * when it has removed references to this connection.
1391                  */
1392                 iscsit_sess_sm_event(ict->ict_sess, SE_CONN_FAIL, ict);
1393         }
1394 

1395         idm_refcnt_wait_ref(&ict->ict_refcnt);
1396         /*
1397          * The session state machine does not need to post
1398          * events to IDM any longer, so it is safe to set
1399          * the idm connection reference to NULL
1400          */
1401         ict->ict_ic = NULL;
1402 
1403         /* Reap the login state machine */
1404         iscsit_login_sm_fini(ict);
1405 
1406         /* Clean up any text command remnants */
1407         iscsit_text_cmd_fini(ict);
1408 
1409         mutex_destroy(&ict->ict_mutex);

1410         idm_refcnt_destroy(&ict->ict_refcnt);
1411         kmem_free(ict, sizeof (*ict));
1412 
1413         iscsit_global_rele();
1414 
1415         return (IDM_STATUS_SUCCESS);
1416 }
1417 
1418 void
1419 iscsit_conn_logout(iscsit_conn_t *ict)
1420 {
1421         /*
1422          * If the iscsi connection is active, then
1423          * logout the IDM connection by sending a
1424          * CE_LOGOUT_SESSION_SUCCESS, else, no action
1425          * needs to be taken because the connection
1426          * is already in the teardown process.
1427          */
1428         mutex_enter(&ict->ict_mutex);
1429         if (ict->ict_lost == B_FALSE && ict->ict_destroyed == B_FALSE) {


1871         iscsit_task->it_stmf_abort = B_TRUE;
1872         if (iscsit_task->it_aborted) {
1873                 mutex_exit(&iscsit_task->it_mutex);
1874                 /*
1875                  * Task is no longer active
1876                  */
1877                 iscsit_task_done(iscsit_task);
1878 
1879                 /*
1880                  * STMF specification is wrong... says to return
1881                  * STMF_ABORTED, the code actually looks for
1882                  * STMF_ABORT_SUCCESS.
1883                  */
1884                 return (STMF_ABORT_SUCCESS);
1885         } else {
1886                 mutex_exit(&iscsit_task->it_mutex);
1887                 /*
1888                  * Call IDM to abort the task.  Due to a variety of
1889                  * circumstances the task may already be in the process of
1890                  * aborting.
1891                  * We'll let IDM worry about rationalizing all that except
1892                  * for one particular instance.  If the state of the task
1893                  * is TASK_COMPLETE, we need to indicate to the framework
1894                  * that we are in fact done.  This typically happens with
1895                  * framework-initiated task management type requests
1896                  * (e.g. abort task).
1897                  */
1898                 if (idt->idt_state == TASK_COMPLETE) {
1899                         idm_refcnt_wait_ref(&idt->idt_refcnt);
1900                         return (STMF_ABORT_SUCCESS);
1901                 } else {
1902                         idm_task_abort(idt->idt_ic, idt, AT_TASK_MGMT_ABORT);
1903                         return (STMF_SUCCESS);
1904                 }
1905         }
1906 
1907         /*NOTREACHED*/
1908 }
1909 
1910 /*ARGSUSED*/
1911 void
1912 iscsit_ctl(stmf_local_port_t *lport, int cmd, void *arg)
1913 {
1914         iscsit_tgt_t            *iscsit_tgt;
1915 
1916         ASSERT((cmd == STMF_CMD_LPORT_ONLINE) ||
1917             (cmd == STMF_ACK_LPORT_ONLINE_COMPLETE) ||
1918             (cmd == STMF_CMD_LPORT_OFFLINE) ||
1919             (cmd == STMF_ACK_LPORT_OFFLINE_COMPLETE));
1920 
1921         iscsit_tgt = (iscsit_tgt_t *)lport->lport_port_private;
1922 
1923         switch (cmd) {
1924         case STMF_CMD_LPORT_ONLINE:
1925                 iscsit_tgt_sm_event(iscsit_tgt, TE_STMF_ONLINE_REQ);


1945         switch (idmrc) {
1946         case IDM_STATUS_SUCCESS:
1947                 return (STMF_SUCCESS);
1948         default:
1949                 return (STMF_FAILURE);
1950         }
1951         /*NOTREACHED*/
1952 }
1953 
1954 void
1955 iscsit_op_scsi_cmd(idm_conn_t *ic, idm_pdu_t *rx_pdu)
1956 {
1957         iscsit_conn_t           *ict = ic->ic_handle;
1958 
1959         if (iscsit_check_cmdsn_and_queue(rx_pdu)) {
1960                 iscsit_post_scsi_cmd(ic, rx_pdu);
1961         }
1962         iscsit_process_pdu_in_queue(ict->ict_sess);
1963 }
1964 















1965 /*
1966  * ISCSI protocol
1967  */
1968 
1969 void
1970 iscsit_post_scsi_cmd(idm_conn_t *ic, idm_pdu_t *rx_pdu)
1971 {
1972         iscsit_conn_t           *ict;
1973         iscsit_task_t           *itask;
1974         scsi_task_t             *task;
1975         iscsit_buf_t            *ibuf;
1976         iscsi_scsi_cmd_hdr_t    *iscsi_scsi =
1977             (iscsi_scsi_cmd_hdr_t *)rx_pdu->isp_hdr;
1978         iscsi_addl_hdr_t        *ahs_hdr;
1979         uint16_t                addl_cdb_len = 0;
1980 
1981         ict = ic->ic_handle;



1982 






1983         itask = iscsit_task_alloc(ict);
1984         if (itask == NULL) {
1985                 /* Finish processing request */
1986                 iscsit_set_cmdsn(ict, rx_pdu);
1987 
1988                 iscsit_send_direct_scsi_resp(ict, rx_pdu,
1989                     ISCSI_STATUS_CMD_COMPLETED, STATUS_BUSY);
1990                 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS);
1991                 return;
1992         }
1993 
1994         /*
1995          * Note CmdSN and ITT in task.  IDM will have already validated this
1996          * request against the connection state so we don't need to check
1997          * that (the connection may have changed state in the meantime but
1998          * we will catch that when we try to send a response)
1999          */
2000         itask->it_cmdsn = ntohl(iscsi_scsi->cmdsn);
2001         itask->it_itt = iscsi_scsi->itt;
2002 




   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2017 Nexenta Systems, Inc.

  24  * Copyright (c) 2017, Joyent, Inc.  All rights reserved.
  25  */
  26 
  27 #include <sys/cpuvar.h>
  28 #include <sys/types.h>
  29 #include <sys/conf.h>
  30 #include <sys/stat.h>
  31 #include <sys/file.h>
  32 #include <sys/ddi.h>
  33 #include <sys/sunddi.h>
  34 #include <sys/modctl.h>
  35 #include <sys/sysmacros.h>
  36 #include <sys/socket.h>
  37 #include <sys/strsubr.h>
  38 #include <sys/nvpair.h>
  39 
  40 #include <sys/stmf.h>
  41 #include <sys/stmf_ioctl.h>
  42 #include <sys/portif.h>
  43 #include <sys/idm/idm.h>


 546                 if (rc != 0) {
 547                         goto cleanup;
 548                 }
 549 
 550                 /* Translate nvlist */
 551                 rc = it_nv_to_config(cfg_nvlist, &cfg);
 552                 if (rc != 0) {
 553                         cmn_err(CE_WARN, "Configuration is invalid");
 554                         goto cleanup;
 555                 }
 556 
 557                 /* Update config */
 558                 rc = iscsit_config_merge(cfg);
 559                 /* FALLTHROUGH */
 560 
 561 cleanup:
 562                 if (cfg)
 563                         it_config_free_cmn(cfg);
 564                 if (cfg_pnvlist)
 565                         kmem_free(cfg_pnvlist, setcfg.set_cfg_pnvlist_len);
 566                 if (cfg_nvlist)
 567                         nvlist_free(cfg_nvlist);
 568 
 569                 /*
 570                  * Now that the reconfig is complete set our state back to
 571                  * enabled.
 572                  */
 573                 mutex_enter(&iscsit_global.global_state_mutex);
 574                 iscsit_global.global_svc_state = ISE_ENABLED;
 575                 mutex_exit(&iscsit_global.global_state_mutex);
 576                 break;
 577         case ISCSIT_IOC_ENABLE_SVC: {
 578                 iscsit_hostinfo_t hostinfo;
 579 
 580                 if (ddi_copyin((void *)argp, &hostinfo.length,
 581                     sizeof (hostinfo.length), flag) != 0) {
 582                         mutex_enter(&iscsit_global.global_state_mutex);
 583                         iscsit_global.global_svc_state = ISE_DISABLED;
 584                         mutex_exit(&iscsit_global.global_state_mutex);
 585                         return (EFAULT);
 586                 }


 975                 /*
 976                  * We rely on the fact that STMF tracks outstanding
 977                  * buffer transfers and will free all of our buffers
 978                  * before freeing the task so we don't need to
 979                  * explicitly free the buffers from iscsit/idm
 980                  */
 981                 if (itask->it_stmf_abort) {
 982                         mutex_exit(&itask->it_mutex);
 983                         /*
 984                          * Task is no longer active
 985                          */
 986                         iscsit_task_done(itask);
 987 
 988                         /*
 989                          * STMF has already asked for this task to be aborted
 990                          *
 991                          * STMF specification is wrong... says to return
 992                          * STMF_ABORTED, the code actually looks for
 993                          * STMF_ABORT_SUCCESS.
 994                          */
 995                         stmf_task_lport_aborted_unlocked(itask->it_stmf_task,
 996                             STMF_ABORT_SUCCESS, STMF_IOF_LPORT_DONE);
 997                         return;
 998                 } else {
 999                         mutex_exit(&itask->it_mutex);
1000                         /*
1001                          * Tell STMF to stop processing the task.
1002                          */
1003                         stmf_abort(STMF_QUEUE_TASK_ABORT, itask->it_stmf_task,
1004                             STMF_ABORTED, NULL);
1005                         return;
1006                 }
1007                 /*NOTREACHED*/
1008         default:
1009                 ASSERT(0);
1010         }
1011 }
1012 
1013 /*ARGSUSED*/
1014 idm_status_t
1015 iscsit_client_notify(idm_conn_t *ic, idm_client_notify_t icn,


1207                 mutex_exit(&iscsit_global.global_state_mutex);
1208                 return (IDM_STATUS_FAIL);
1209         }
1210         iscsit_global_hold();
1211         mutex_exit(&iscsit_global.global_state_mutex);
1212 
1213         /*
1214          * Allocate an associated iscsit structure to represent this
1215          * connection.  We shouldn't really create a session until we
1216          * get the first login PDU.
1217          */
1218         ict = kmem_zalloc(sizeof (*ict), KM_SLEEP);
1219 
1220         ict->ict_ic = ic;
1221         ict->ict_statsn = 1;
1222         ict->ict_keepalive_ttt = IDM_TASKIDS_MAX; /* Avoid IDM TT range */
1223         ic->ic_handle = ict;
1224         mutex_init(&ict->ict_mutex, NULL, MUTEX_DRIVER, NULL);
1225         mutex_init(&ict->ict_statsn_mutex, NULL, MUTEX_DRIVER, NULL);
1226         idm_refcnt_init(&ict->ict_refcnt, ict);
1227         idm_refcnt_init(&ict->ict_dispatch_refcnt, ict);
1228 
1229         /*
1230          * Initialize login state machine
1231          */
1232         if (iscsit_login_sm_init(ict) != IDM_STATUS_SUCCESS) {
1233                 iscsit_global_rele();
1234                 /*
1235                  * Cleanup the ict after idm notifies us about this failure
1236                  */
1237                 return (IDM_STATUS_FAIL);
1238         }
1239 
1240         return (IDM_STATUS_SUCCESS);
1241 }
1242 
1243 idm_status_t
1244 iscsit_conn_reinstate(iscsit_conn_t *reinstate_ict, iscsit_conn_t *new_ict)
1245 {
1246         idm_status_t    result;
1247 


1353                     ((cbuf->cb_num_elems > 0) && (i < ISCSIT_RXPDU_QUEUE_LEN));
1354                     i++) {
1355                         if (((rx_pdu = cbuf->cb_buffer[i]) != NULL) &&
1356                             (rx_pdu->isp_ic == ic)) {
1357                                 /* conn is lost, drop the pdu */
1358                                 DTRACE_PROBE3(scrubbing__staging__queue,
1359                                     iscsit_sess_t *, ist, idm_conn_t *, ic,
1360                                     idm_pdu_t *, rx_pdu);
1361                                 idm_pdu_complete(rx_pdu, IDM_STATUS_FAIL);
1362                                 cbuf->cb_buffer[i] = NULL;
1363                                 cbuf->cb_num_elems--;
1364                                 iscsit_conn_dispatch_rele(ict);
1365                         }
1366                 }
1367                 mutex_exit(&ist->ist_sn_mutex);
1368         }
1369         /*
1370          * Make sure there aren't any PDU's transitioning from the receive
1371          * handler to the dispatch taskq.
1372          */
1373         if (idm_refcnt_is_held(&ict->ict_dispatch_refcnt) < 0) {
1374                 cmn_err(CE_WARN, "Possible hang in iscsit_conn_lost");
1375         }
1376         idm_refcnt_wait_ref(&ict->ict_dispatch_refcnt);
1377 
1378         return (IDM_STATUS_SUCCESS);
1379 }
1380 
1381 static idm_status_t
1382 iscsit_conn_destroy(idm_conn_t *ic)
1383 {
1384         iscsit_conn_t *ict = ic->ic_handle;
1385 
1386         mutex_enter(&ict->ict_mutex);
1387         ict->ict_destroyed = B_TRUE;
1388         mutex_exit(&ict->ict_mutex);
1389 
1390         /* Generate session state machine event */
1391         if (ict->ict_sess != NULL) {




1392                 iscsit_sess_sm_event(ict->ict_sess, SE_CONN_FAIL, ict);
1393         }
1394 
1395         idm_refcnt_wait_ref(&ict->ict_dispatch_refcnt);
1396         idm_refcnt_wait_ref(&ict->ict_refcnt);
1397         /*
1398          * The session state machine does not need to post
1399          * events to IDM any longer, so it is safe to set
1400          * the idm connection reference to NULL
1401          */
1402         ict->ict_ic = NULL;
1403 
1404         /* Reap the login state machine */
1405         iscsit_login_sm_fini(ict);
1406 
1407         /* Clean up any text command remnants */
1408         iscsit_text_cmd_fini(ict);
1409 
1410         mutex_destroy(&ict->ict_mutex);
1411         idm_refcnt_destroy(&ict->ict_dispatch_refcnt);
1412         idm_refcnt_destroy(&ict->ict_refcnt);
1413         kmem_free(ict, sizeof (*ict));
1414 
1415         iscsit_global_rele();
1416 
1417         return (IDM_STATUS_SUCCESS);
1418 }
1419 
1420 void
1421 iscsit_conn_logout(iscsit_conn_t *ict)
1422 {
1423         /*
1424          * If the iscsi connection is active, then
1425          * logout the IDM connection by sending a
1426          * CE_LOGOUT_SESSION_SUCCESS, else, no action
1427          * needs to be taken because the connection
1428          * is already in the teardown process.
1429          */
1430         mutex_enter(&ict->ict_mutex);
1431         if (ict->ict_lost == B_FALSE && ict->ict_destroyed == B_FALSE) {


1873         iscsit_task->it_stmf_abort = B_TRUE;
1874         if (iscsit_task->it_aborted) {
1875                 mutex_exit(&iscsit_task->it_mutex);
1876                 /*
1877                  * Task is no longer active
1878                  */
1879                 iscsit_task_done(iscsit_task);
1880 
1881                 /*
1882                  * STMF specification is wrong... says to return
1883                  * STMF_ABORTED, the code actually looks for
1884                  * STMF_ABORT_SUCCESS.
1885                  */
1886                 return (STMF_ABORT_SUCCESS);
1887         } else {
1888                 mutex_exit(&iscsit_task->it_mutex);
1889                 /*
1890                  * Call IDM to abort the task.  Due to a variety of
1891                  * circumstances the task may already be in the process of
1892                  * aborting.






1893                  */
1894                 return (idm_task_abort(idt->idt_ic, idt, AT_TASK_MGMT_ABORT));





1895         }

1896 
1897         /*NOTREACHED*/
1898 }
1899 
1900 /*ARGSUSED*/
1901 void
1902 iscsit_ctl(stmf_local_port_t *lport, int cmd, void *arg)
1903 {
1904         iscsit_tgt_t            *iscsit_tgt;
1905 
1906         ASSERT((cmd == STMF_CMD_LPORT_ONLINE) ||
1907             (cmd == STMF_ACK_LPORT_ONLINE_COMPLETE) ||
1908             (cmd == STMF_CMD_LPORT_OFFLINE) ||
1909             (cmd == STMF_ACK_LPORT_OFFLINE_COMPLETE));
1910 
1911         iscsit_tgt = (iscsit_tgt_t *)lport->lport_port_private;
1912 
1913         switch (cmd) {
1914         case STMF_CMD_LPORT_ONLINE:
1915                 iscsit_tgt_sm_event(iscsit_tgt, TE_STMF_ONLINE_REQ);


1935         switch (idmrc) {
1936         case IDM_STATUS_SUCCESS:
1937                 return (STMF_SUCCESS);
1938         default:
1939                 return (STMF_FAILURE);
1940         }
1941         /*NOTREACHED*/
1942 }
1943 
1944 void
1945 iscsit_op_scsi_cmd(idm_conn_t *ic, idm_pdu_t *rx_pdu)
1946 {
1947         iscsit_conn_t           *ict = ic->ic_handle;
1948 
1949         if (iscsit_check_cmdsn_and_queue(rx_pdu)) {
1950                 iscsit_post_scsi_cmd(ic, rx_pdu);
1951         }
1952         iscsit_process_pdu_in_queue(ict->ict_sess);
1953 }
1954 
1955 static int
1956 iscsit_validate_idm_pdu(idm_pdu_t *rx_pdu)
1957 {
1958         iscsi_scsi_cmd_hdr_t    *iscsi_scsi =
1959             (iscsi_scsi_cmd_hdr_t *)rx_pdu->isp_hdr;
1960 
1961         if ((iscsi_scsi->scb[0] == SCMD_READ) ||
1962             (iscsi_scsi->scb[0] == SCMD_READ_G1) ||
1963             (iscsi_scsi->scb[0] == SCMD_READ_G4)) {
1964                 if (iscsi_scsi->flags & ISCSI_FLAG_CMD_WRITE)
1965                         return (IDM_STATUS_FAIL);
1966         }
1967         return (IDM_STATUS_SUCCESS);
1968 }
1969 
1970 /*
1971  * ISCSI protocol
1972  */
1973 
1974 void
1975 iscsit_post_scsi_cmd(idm_conn_t *ic, idm_pdu_t *rx_pdu)
1976 {
1977         iscsit_conn_t           *ict;
1978         iscsit_task_t           *itask;
1979         scsi_task_t             *task;
1980         iscsit_buf_t            *ibuf;
1981         iscsi_scsi_cmd_hdr_t    *iscsi_scsi =
1982             (iscsi_scsi_cmd_hdr_t *)rx_pdu->isp_hdr;
1983         iscsi_addl_hdr_t        *ahs_hdr;
1984         uint16_t                addl_cdb_len = 0;
1985 
1986         ict = ic->ic_handle;
1987         if (iscsit_validate_idm_pdu(rx_pdu) != IDM_STATUS_SUCCESS) {
1988                 /* Finish processing request */
1989                 iscsit_set_cmdsn(ict, rx_pdu);
1990 
1991                 iscsit_send_direct_scsi_resp(ict, rx_pdu,
1992                     ISCSI_STATUS_CMD_COMPLETED, STATUS_CHECK);
1993                 idm_pdu_complete(rx_pdu, IDM_STATUS_PROTOCOL_ERROR);
1994                 return;
1995         }
1996 
1997         itask = iscsit_task_alloc(ict);
1998         if (itask == NULL) {
1999                 /* Finish processing request */
2000                 iscsit_set_cmdsn(ict, rx_pdu);
2001 
2002                 iscsit_send_direct_scsi_resp(ict, rx_pdu,
2003                     ISCSI_STATUS_CMD_COMPLETED, STATUS_BUSY);
2004                 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS);
2005                 return;
2006         }
2007 
2008         /*
2009          * Note CmdSN and ITT in task.  IDM will have already validated this
2010          * request against the connection state so we don't need to check
2011          * that (the connection may have changed state in the meantime but
2012          * we will catch that when we try to send a response)
2013          */
2014         itask->it_cmdsn = ntohl(iscsi_scsi->cmdsn);
2015         itask->it_itt = iscsi_scsi->itt;
2016