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
|