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 Nexenta Systems, 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>
  44 #include <sys/idm/idm_conn_sm.h>
 
 
 927                  * If/when we switch to userland processing these PDU's
 928                  * will be handled by iscsitd.
 929                  */
 930                 iscsit_deferred_dispatch(rx_pdu);
 931                 break;
 932         default:
 933                 /* Protocol error */
 934                 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS);
 935                 idm_conn_event(ic, CE_TRANSPORT_FAIL, NULL);
 936                 break;
 937         }
 938 }
 939 
 940 /*ARGSUSED*/
 941 void
 942 iscsit_rx_pdu_error(idm_conn_t *ic, idm_pdu_t *rx_pdu, idm_status_t status)
 943 {
 944         idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS);
 945 }
 946 
 947 void
 948 iscsit_task_aborted(idm_task_t *idt, idm_status_t status)
 949 {
 950         iscsit_task_t *itask = idt->idt_private;
 951 
 952         switch (status) {
 953         case IDM_STATUS_SUSPENDED:
 954                 break;
 955         case IDM_STATUS_ABORTED:
 956                 mutex_enter(&itask->it_mutex);
 957                 itask->it_aborted = B_TRUE;
 958                 /*
 959                  * We rely on the fact that STMF tracks outstanding
 960                  * buffer transfers and will free all of our buffers
 961                  * before freeing the task so we don't need to
 962                  * explicitly free the buffers from iscsit/idm
 963                  */
 964                 if (itask->it_stmf_abort) {
 965                         mutex_exit(&itask->it_mutex);
 966                         /*
 967                          * Task is no longer active
 
2374                  */
2375                 rtt = iscsi_tm->rtt;
2376                 itask = (iscsit_task_t *)idm_task_find_by_handle(ict->ict_ic,
2377                     (uintptr_t)rtt);
2378 
2379                 if (itask == NULL) {
2380                         cmdsn = ntohl(iscsi_tm->cmdsn);
2381                         refcmdsn = ntohl(iscsi_tm->refcmdsn);
2382 
2383                         /*
2384                          * Task was not found. But the SCSI command could be
2385                          * on the rxpdu wait queue. If RefCmdSN is within
2386                          * the CmdSN window and less than CmdSN of the TM
2387                          * function, return "Function Complete". Otherwise,
2388                          * return "Task Does Not Exist".
2389                          */
2390 
2391                         if (iscsit_cmdsn_in_window(ict, refcmdsn) &&
2392                             iscsit_sna_lt(refcmdsn, cmdsn)) {
2393                                 mutex_enter(&ict->ict_sess->ist_sn_mutex);
2394                                 (void) iscsit_remove_pdu_from_queue(
2395                                     ict->ict_sess, refcmdsn);
2396                                 iscsit_conn_dispatch_rele(ict);
2397                                 mutex_exit(&ict->ict_sess->ist_sn_mutex);
2398                                 iscsit_send_task_mgmt_resp(tm_resp_pdu,
2399                                     SCSI_TCP_TM_RESP_COMPLETE);
2400                         } else {
2401                                 iscsit_send_task_mgmt_resp(tm_resp_pdu,
2402                                     SCSI_TCP_TM_RESP_NO_TASK);
2403                         }
2404                 } else {
2405 
2406                         /*
2407                          * Tell STMF to abort the task.  This will do no harm
2408                          * if the task is already complete.
2409                          */
2410                         stmf_abort(STMF_QUEUE_TASK_ABORT, itask->it_stmf_task,
2411                             STMF_ABORTED, NULL);
2412 
2413                         /*
2414                          * Make sure the task hasn't already completed
2415                          */
2416                         mutex_enter(&itask->it_idm_task->idt_mutex);
 
 | 
 
 
   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  */
  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>
  44 #include <sys/idm/idm_conn_sm.h>
 
 
 927                  * If/when we switch to userland processing these PDU's
 928                  * will be handled by iscsitd.
 929                  */
 930                 iscsit_deferred_dispatch(rx_pdu);
 931                 break;
 932         default:
 933                 /* Protocol error */
 934                 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS);
 935                 idm_conn_event(ic, CE_TRANSPORT_FAIL, NULL);
 936                 break;
 937         }
 938 }
 939 
 940 /*ARGSUSED*/
 941 void
 942 iscsit_rx_pdu_error(idm_conn_t *ic, idm_pdu_t *rx_pdu, idm_status_t status)
 943 {
 944         idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS);
 945 }
 946 
 947 /*
 948  * iscsit_rx_scsi_rsp -- cause the connection to be closed if response rx'd
 949  *
 950  * A target sends an SCSI Response PDU, it should never receive one.
 951  * This has been seen when running the Codemonicon suite of tests which
 952  * does negative testing of the protocol. If such a condition occurs using
 953  * a normal initiator it most likely means there's data corruption in the
 954  * header and that's grounds for dropping the connection as well.
 955  */
 956 void
 957 iscsit_rx_scsi_rsp(idm_conn_t *ic, idm_pdu_t *rx_pdu)
 958 {
 959         idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS);
 960         idm_conn_event(ic, CE_TRANSPORT_FAIL, NULL);
 961 }
 962 
 963 void
 964 iscsit_task_aborted(idm_task_t *idt, idm_status_t status)
 965 {
 966         iscsit_task_t *itask = idt->idt_private;
 967 
 968         switch (status) {
 969         case IDM_STATUS_SUSPENDED:
 970                 break;
 971         case IDM_STATUS_ABORTED:
 972                 mutex_enter(&itask->it_mutex);
 973                 itask->it_aborted = B_TRUE;
 974                 /*
 975                  * We rely on the fact that STMF tracks outstanding
 976                  * buffer transfers and will free all of our buffers
 977                  * before freeing the task so we don't need to
 978                  * explicitly free the buffers from iscsit/idm
 979                  */
 980                 if (itask->it_stmf_abort) {
 981                         mutex_exit(&itask->it_mutex);
 982                         /*
 983                          * Task is no longer active
 
2390                  */
2391                 rtt = iscsi_tm->rtt;
2392                 itask = (iscsit_task_t *)idm_task_find_by_handle(ict->ict_ic,
2393                     (uintptr_t)rtt);
2394 
2395                 if (itask == NULL) {
2396                         cmdsn = ntohl(iscsi_tm->cmdsn);
2397                         refcmdsn = ntohl(iscsi_tm->refcmdsn);
2398 
2399                         /*
2400                          * Task was not found. But the SCSI command could be
2401                          * on the rxpdu wait queue. If RefCmdSN is within
2402                          * the CmdSN window and less than CmdSN of the TM
2403                          * function, return "Function Complete". Otherwise,
2404                          * return "Task Does Not Exist".
2405                          */
2406 
2407                         if (iscsit_cmdsn_in_window(ict, refcmdsn) &&
2408                             iscsit_sna_lt(refcmdsn, cmdsn)) {
2409                                 mutex_enter(&ict->ict_sess->ist_sn_mutex);
2410                                 if (iscsit_remove_pdu_from_queue(
2411                                     ict->ict_sess, refcmdsn)) {
2412                                         iscsit_conn_dispatch_rele(ict);
2413                                 }
2414                                 mutex_exit(&ict->ict_sess->ist_sn_mutex);
2415                                 iscsit_send_task_mgmt_resp(tm_resp_pdu,
2416                                     SCSI_TCP_TM_RESP_COMPLETE);
2417                         } else {
2418                                 iscsit_send_task_mgmt_resp(tm_resp_pdu,
2419                                     SCSI_TCP_TM_RESP_NO_TASK);
2420                         }
2421                 } else {
2422 
2423                         /*
2424                          * Tell STMF to abort the task.  This will do no harm
2425                          * if the task is already complete.
2426                          */
2427                         stmf_abort(STMF_QUEUE_TASK_ABORT, itask->it_stmf_task,
2428                             STMF_ABORTED, NULL);
2429 
2430                         /*
2431                          * Make sure the task hasn't already completed
2432                          */
2433                         mutex_enter(&itask->it_idm_task->idt_mutex);
 
 |