1a6d42e7dSPeter Dunlap /*
2a6d42e7dSPeter Dunlap * CDDL HEADER START
3a6d42e7dSPeter Dunlap *
4a6d42e7dSPeter Dunlap * The contents of this file are subject to the terms of the
5a6d42e7dSPeter Dunlap * Common Development and Distribution License (the "License").
6a6d42e7dSPeter Dunlap * You may not use this file except in compliance with the License.
7a6d42e7dSPeter Dunlap *
8a6d42e7dSPeter Dunlap * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9a6d42e7dSPeter Dunlap * or http://www.opensolaris.org/os/licensing.
10a6d42e7dSPeter Dunlap * See the License for the specific language governing permissions
11a6d42e7dSPeter Dunlap * and limitations under the License.
12a6d42e7dSPeter Dunlap *
13a6d42e7dSPeter Dunlap * When distributing Covered Code, include this CDDL HEADER in each
14a6d42e7dSPeter Dunlap * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15a6d42e7dSPeter Dunlap * If applicable, add the following below this CDDL HEADER, with the
16a6d42e7dSPeter Dunlap * fields enclosed by brackets "[]" replaced with your own identifying
17a6d42e7dSPeter Dunlap * information: Portions Copyright [yyyy] [name of copyright owner]
18a6d42e7dSPeter Dunlap *
19a6d42e7dSPeter Dunlap * CDDL HEADER END
20a6d42e7dSPeter Dunlap */
21a6d42e7dSPeter Dunlap /*
22d618d68dSPriya Krishnan * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
233e2514dcSDan McDonald *
24*61dfa509SRick McNeal * Copyright 2017 Nexenta Systems, Inc.
252727bb05STim Kordas * Copyright (c) 2017, Joyent, Inc. All rights reserved.
266319b0c7SGarrett D'Amore */
27a6d42e7dSPeter Dunlap
28a6d42e7dSPeter Dunlap #include <sys/cpuvar.h>
29a6d42e7dSPeter Dunlap #include <sys/types.h>
30a6d42e7dSPeter Dunlap #include <sys/conf.h>
31a6d42e7dSPeter Dunlap #include <sys/stat.h>
32a6d42e7dSPeter Dunlap #include <sys/file.h>
33a6d42e7dSPeter Dunlap #include <sys/ddi.h>
34a6d42e7dSPeter Dunlap #include <sys/sunddi.h>
35a6d42e7dSPeter Dunlap #include <sys/modctl.h>
36a6d42e7dSPeter Dunlap #include <sys/sysmacros.h>
37a6d42e7dSPeter Dunlap #include <sys/socket.h>
38a6d42e7dSPeter Dunlap #include <sys/strsubr.h>
39a6d42e7dSPeter Dunlap #include <sys/nvpair.h>
40a6d42e7dSPeter Dunlap
41a6d42e7dSPeter Dunlap #include <sys/stmf.h>
42a6d42e7dSPeter Dunlap #include <sys/stmf_ioctl.h>
43a6d42e7dSPeter Dunlap #include <sys/portif.h>
44a6d42e7dSPeter Dunlap #include <sys/idm/idm.h>
45a6d42e7dSPeter Dunlap #include <sys/idm/idm_conn_sm.h>
464558d122SViswanathan Kannappan
474558d122SViswanathan Kannappan #include "iscsit_isns.h"
484558d122SViswanathan Kannappan #include "iscsit.h"
49a6d42e7dSPeter Dunlap
50a6d42e7dSPeter Dunlap #define ISCSIT_VERSION BUILD_DATE "-1.18dev"
51a6d42e7dSPeter Dunlap #define ISCSIT_NAME_VERSION "COMSTAR ISCSIT v" ISCSIT_VERSION
52a6d42e7dSPeter Dunlap
53a6d42e7dSPeter Dunlap /*
54a6d42e7dSPeter Dunlap * DDI entry points.
55a6d42e7dSPeter Dunlap */
56a6d42e7dSPeter Dunlap static int iscsit_drv_attach(dev_info_t *, ddi_attach_cmd_t);
57a6d42e7dSPeter Dunlap static int iscsit_drv_detach(dev_info_t *, ddi_detach_cmd_t);
58a6d42e7dSPeter Dunlap static int iscsit_drv_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
59a6d42e7dSPeter Dunlap static int iscsit_drv_open(dev_t *, int, int, cred_t *);
60a6d42e7dSPeter Dunlap static int iscsit_drv_close(dev_t, int, int, cred_t *);
61a6d42e7dSPeter Dunlap static boolean_t iscsit_drv_busy(void);
62a6d42e7dSPeter Dunlap static int iscsit_drv_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
63a6d42e7dSPeter Dunlap
64a6d42e7dSPeter Dunlap extern struct mod_ops mod_miscops;
65a6d42e7dSPeter Dunlap
66a6d42e7dSPeter Dunlap
67a6d42e7dSPeter Dunlap static struct cb_ops iscsit_cb_ops = {
68a6d42e7dSPeter Dunlap iscsit_drv_open, /* cb_open */
69a6d42e7dSPeter Dunlap iscsit_drv_close, /* cb_close */
70a6d42e7dSPeter Dunlap nodev, /* cb_strategy */
71a6d42e7dSPeter Dunlap nodev, /* cb_print */
72a6d42e7dSPeter Dunlap nodev, /* cb_dump */
73a6d42e7dSPeter Dunlap nodev, /* cb_read */
74a6d42e7dSPeter Dunlap nodev, /* cb_write */
75a6d42e7dSPeter Dunlap iscsit_drv_ioctl, /* cb_ioctl */
76a6d42e7dSPeter Dunlap nodev, /* cb_devmap */
77a6d42e7dSPeter Dunlap nodev, /* cb_mmap */
78a6d42e7dSPeter Dunlap nodev, /* cb_segmap */
79a6d42e7dSPeter Dunlap nochpoll, /* cb_chpoll */
80a6d42e7dSPeter Dunlap ddi_prop_op, /* cb_prop_op */
81a6d42e7dSPeter Dunlap NULL, /* cb_streamtab */
82a6d42e7dSPeter Dunlap D_MP, /* cb_flag */
83a6d42e7dSPeter Dunlap CB_REV, /* cb_rev */
84a6d42e7dSPeter Dunlap nodev, /* cb_aread */
85a6d42e7dSPeter Dunlap nodev, /* cb_awrite */
86a6d42e7dSPeter Dunlap };
87a6d42e7dSPeter Dunlap
88a6d42e7dSPeter Dunlap static struct dev_ops iscsit_dev_ops = {
89a6d42e7dSPeter Dunlap DEVO_REV, /* devo_rev */
90a6d42e7dSPeter Dunlap 0, /* devo_refcnt */
91a6d42e7dSPeter Dunlap iscsit_drv_getinfo, /* devo_getinfo */
92a6d42e7dSPeter Dunlap nulldev, /* devo_identify */
93a6d42e7dSPeter Dunlap nulldev, /* devo_probe */
94a6d42e7dSPeter Dunlap iscsit_drv_attach, /* devo_attach */
95a6d42e7dSPeter Dunlap iscsit_drv_detach, /* devo_detach */
96a6d42e7dSPeter Dunlap nodev, /* devo_reset */
97a6d42e7dSPeter Dunlap &iscsit_cb_ops, /* devo_cb_ops */
98a6d42e7dSPeter Dunlap NULL, /* devo_bus_ops */
99a6d42e7dSPeter Dunlap NULL, /* devo_power */
10063528ae4SJames Moore ddi_quiesce_not_needed, /* quiesce */
101a6d42e7dSPeter Dunlap };
102a6d42e7dSPeter Dunlap
103a6d42e7dSPeter Dunlap static struct modldrv modldrv = {
104a6d42e7dSPeter Dunlap &mod_driverops,
105a6d42e7dSPeter Dunlap "iSCSI Target",
106a6d42e7dSPeter Dunlap &iscsit_dev_ops,
107a6d42e7dSPeter Dunlap };
108a6d42e7dSPeter Dunlap
109a6d42e7dSPeter Dunlap static struct modlinkage modlinkage = {
110a6d42e7dSPeter Dunlap MODREV_1,
111a6d42e7dSPeter Dunlap &modldrv,
112a6d42e7dSPeter Dunlap NULL,
113a6d42e7dSPeter Dunlap };
114a6d42e7dSPeter Dunlap
115a6d42e7dSPeter Dunlap
116a6d42e7dSPeter Dunlap iscsit_global_t iscsit_global;
117a6d42e7dSPeter Dunlap
118a6d42e7dSPeter Dunlap kmem_cache_t *iscsit_status_pdu_cache;
119a6d42e7dSPeter Dunlap
120a6d42e7dSPeter Dunlap boolean_t iscsit_sm_logging = B_FALSE;
121a6d42e7dSPeter Dunlap
1223fc1e17eSPriya Krishnan kmutex_t login_sm_session_mutex;
1233fc1e17eSPriya Krishnan
124a6d42e7dSPeter Dunlap static idm_status_t iscsit_init(dev_info_t *dip);
125a6d42e7dSPeter Dunlap static idm_status_t iscsit_enable_svc(iscsit_hostinfo_t *hostinfo);
126a6d42e7dSPeter Dunlap static void iscsit_disable_svc(void);
127a6d42e7dSPeter Dunlap
1282727bb05STim Kordas static boolean_t
129d618d68dSPriya Krishnan iscsit_check_cmdsn_and_queue(idm_pdu_t *rx_pdu);
130d618d68dSPriya Krishnan
131d618d68dSPriya Krishnan static void
132d618d68dSPriya Krishnan iscsit_add_pdu_to_queue(iscsit_sess_t *ist, idm_pdu_t *rx_pdu);
133d618d68dSPriya Krishnan
134d618d68dSPriya Krishnan static idm_pdu_t *
135d618d68dSPriya Krishnan iscsit_remove_pdu_from_queue(iscsit_sess_t *ist, uint32_t cmdsn);
136d618d68dSPriya Krishnan
137d618d68dSPriya Krishnan static void
138d618d68dSPriya Krishnan iscsit_process_pdu_in_queue(iscsit_sess_t *ist);
139d618d68dSPriya Krishnan
140d618d68dSPriya Krishnan static void
141d618d68dSPriya Krishnan iscsit_rxpdu_queue_monitor_session(iscsit_sess_t *ist);
142d618d68dSPriya Krishnan
143d618d68dSPriya Krishnan static void
144d618d68dSPriya Krishnan iscsit_rxpdu_queue_monitor(void *arg);
145d618d68dSPriya Krishnan
146d618d68dSPriya Krishnan static void
147d618d68dSPriya Krishnan iscsit_post_staged_pdu(idm_pdu_t *rx_pdu);
148d618d68dSPriya Krishnan
149d618d68dSPriya Krishnan static void
150d618d68dSPriya Krishnan iscsit_post_scsi_cmd(idm_conn_t *ic, idm_pdu_t *rx_pdu);
151d618d68dSPriya Krishnan
152a6d42e7dSPeter Dunlap static void
153a6d42e7dSPeter Dunlap iscsit_op_scsi_task_mgmt(iscsit_conn_t *ict, idm_pdu_t *rx_pdu);
154a6d42e7dSPeter Dunlap
155a6d42e7dSPeter Dunlap static void
156a6d42e7dSPeter Dunlap iscsit_pdu_op_noop(iscsit_conn_t *ict, idm_pdu_t *rx_pdu);
157a6d42e7dSPeter Dunlap
158a6d42e7dSPeter Dunlap static void
159a6d42e7dSPeter Dunlap iscsit_pdu_op_login_cmd(iscsit_conn_t *ict, idm_pdu_t *rx_pdu);
160a6d42e7dSPeter Dunlap
161a6d42e7dSPeter Dunlap void
162a6d42e7dSPeter Dunlap iscsit_pdu_op_text_cmd(iscsit_conn_t *ict, idm_pdu_t *rx_pdu);
163a6d42e7dSPeter Dunlap
164a6d42e7dSPeter Dunlap static void
165a6d42e7dSPeter Dunlap iscsit_pdu_op_logout_cmd(iscsit_conn_t *ict, idm_pdu_t *rx_pdu);
166a6d42e7dSPeter Dunlap
167a6d42e7dSPeter Dunlap int iscsit_cmd_window();
168a6d42e7dSPeter Dunlap
169d618d68dSPriya Krishnan static int
170d618d68dSPriya Krishnan iscsit_sna_lt(uint32_t sn1, uint32_t sn2);
171d618d68dSPriya Krishnan
172a6d42e7dSPeter Dunlap void
173a6d42e7dSPeter Dunlap iscsit_set_cmdsn(iscsit_conn_t *ict, idm_pdu_t *rx_pdu);
174a6d42e7dSPeter Dunlap
175a6d42e7dSPeter Dunlap static void
176a6d42e7dSPeter Dunlap iscsit_deferred_dispatch(idm_pdu_t *rx_pdu);
177a6d42e7dSPeter Dunlap
178a6d42e7dSPeter Dunlap static void
179a6d42e7dSPeter Dunlap iscsit_deferred(void *rx_pdu_void);
180a6d42e7dSPeter Dunlap
181a6d42e7dSPeter Dunlap static idm_status_t
182a6d42e7dSPeter Dunlap iscsit_conn_accept(idm_conn_t *ic);
183a6d42e7dSPeter Dunlap
184a6d42e7dSPeter Dunlap static idm_status_t
185a6d42e7dSPeter Dunlap iscsit_ffp_enabled(idm_conn_t *ic);
186a6d42e7dSPeter Dunlap
187a6d42e7dSPeter Dunlap static idm_status_t
188a6d42e7dSPeter Dunlap iscsit_ffp_disabled(idm_conn_t *ic, idm_ffp_disable_t disable_class);
189a6d42e7dSPeter Dunlap
190a6d42e7dSPeter Dunlap static idm_status_t
191a6d42e7dSPeter Dunlap iscsit_conn_lost(idm_conn_t *ic);
192a6d42e7dSPeter Dunlap
193a6d42e7dSPeter Dunlap static idm_status_t
194a6d42e7dSPeter Dunlap iscsit_conn_destroy(idm_conn_t *ic);
195a6d42e7dSPeter Dunlap
196a6d42e7dSPeter Dunlap static stmf_data_buf_t *
197a6d42e7dSPeter Dunlap iscsit_dbuf_alloc(scsi_task_t *task, uint32_t size, uint32_t *pminsize,
198a6d42e7dSPeter Dunlap uint32_t flags);
199a6d42e7dSPeter Dunlap
200a6d42e7dSPeter Dunlap static void
201a6d42e7dSPeter Dunlap iscsit_dbuf_free(stmf_dbuf_store_t *ds, stmf_data_buf_t *dbuf);
202a6d42e7dSPeter Dunlap
203a6d42e7dSPeter Dunlap static void
204a6d42e7dSPeter Dunlap iscsit_buf_xfer_cb(idm_buf_t *idb, idm_status_t status);
205a6d42e7dSPeter Dunlap
206a6d42e7dSPeter Dunlap static void
207a6d42e7dSPeter Dunlap iscsit_send_good_status_done(idm_pdu_t *pdu, idm_status_t status);
208a6d42e7dSPeter Dunlap
209a6d42e7dSPeter Dunlap static void
210a6d42e7dSPeter Dunlap iscsit_send_status_done(idm_pdu_t *pdu, idm_status_t status);
211a6d42e7dSPeter Dunlap
212a6d42e7dSPeter Dunlap static stmf_status_t
213a6d42e7dSPeter Dunlap iscsit_idm_to_stmf(idm_status_t idmrc);
214a6d42e7dSPeter Dunlap
215a6d42e7dSPeter Dunlap static iscsit_task_t *
216a6d42e7dSPeter Dunlap iscsit_task_alloc(iscsit_conn_t *ict);
217a6d42e7dSPeter Dunlap
218a6d42e7dSPeter Dunlap static void
219a6d42e7dSPeter Dunlap iscsit_task_free(iscsit_task_t *itask);
220a6d42e7dSPeter Dunlap
221a6d42e7dSPeter Dunlap static iscsit_task_t *
222a6d42e7dSPeter Dunlap iscsit_tm_task_alloc(iscsit_conn_t *ict);
223a6d42e7dSPeter Dunlap
224a6d42e7dSPeter Dunlap static void
225a6d42e7dSPeter Dunlap iscsit_tm_task_free(iscsit_task_t *itask);
226a6d42e7dSPeter Dunlap
22772cf3143Speter dunlap static idm_status_t
22872cf3143Speter dunlap iscsit_task_start(iscsit_task_t *itask);
22972cf3143Speter dunlap
23072cf3143Speter dunlap static void
23172cf3143Speter dunlap iscsit_task_done(iscsit_task_t *itask);
23272cf3143Speter dunlap
233a6d42e7dSPeter Dunlap static int
234a6d42e7dSPeter Dunlap iscsit_status_pdu_constructor(void *pdu_void, void *arg, int flags);
235a6d42e7dSPeter Dunlap
236a6d42e7dSPeter Dunlap static void
237a6d42e7dSPeter Dunlap iscsit_pp_cb(struct stmf_port_provider *pp, int cmd, void *arg, uint32_t flags);
238a6d42e7dSPeter Dunlap
239a6d42e7dSPeter Dunlap static it_cfg_status_t
240a6d42e7dSPeter Dunlap iscsit_config_merge(it_config_t *cfg);
241a6d42e7dSPeter Dunlap
242a6d42e7dSPeter Dunlap static idm_status_t
243a6d42e7dSPeter Dunlap iscsit_login_fail(idm_conn_t *ic);
244a6d42e7dSPeter Dunlap
24572cf3143Speter dunlap static boolean_t iscsit_cmdsn_in_window(iscsit_conn_t *ict, uint32_t cmdsn);
24672cf3143Speter dunlap static void iscsit_send_direct_scsi_resp(iscsit_conn_t *ict, idm_pdu_t *rx_pdu,
24772cf3143Speter dunlap uint8_t response, uint8_t cmd_status);
24872cf3143Speter dunlap static void iscsit_send_task_mgmt_resp(idm_pdu_t *tm_resp_pdu,
24972cf3143Speter dunlap uint8_t tm_status);
25072cf3143Speter dunlap
251d618d68dSPriya Krishnan /*
252d618d68dSPriya Krishnan * MC/S: Out-of-order commands are staged on a session-wide wait
253d618d68dSPriya Krishnan * queue until a system-tunable threshold is reached. A separate
254d618d68dSPriya Krishnan * thread is used to scan the staging queue on all the session,
255d618d68dSPriya Krishnan * If a delayed PDU does not arrive within a timeout, the target
256d618d68dSPriya Krishnan * will advance to the staged PDU that is next in sequence, skipping
257d618d68dSPriya Krishnan * over the missing PDU(s) to go past a hole in the sequence.
258d618d68dSPriya Krishnan */
259d618d68dSPriya Krishnan volatile int rxpdu_queue_threshold = ISCSIT_RXPDU_QUEUE_THRESHOLD;
260d618d68dSPriya Krishnan
261d618d68dSPriya Krishnan static kmutex_t iscsit_rxpdu_queue_monitor_mutex;
262d618d68dSPriya Krishnan kthread_t *iscsit_rxpdu_queue_monitor_thr_id;
263d618d68dSPriya Krishnan static kt_did_t iscsit_rxpdu_queue_monitor_thr_did;
264d618d68dSPriya Krishnan static boolean_t iscsit_rxpdu_queue_monitor_thr_running;
265d618d68dSPriya Krishnan static kcondvar_t iscsit_rxpdu_queue_monitor_cv;
266d618d68dSPriya Krishnan
267a6d42e7dSPeter Dunlap int
_init(void)268a6d42e7dSPeter Dunlap _init(void)
269a6d42e7dSPeter Dunlap {
270a6d42e7dSPeter Dunlap int rc;
271a6d42e7dSPeter Dunlap
272a6d42e7dSPeter Dunlap rw_init(&iscsit_global.global_rwlock, NULL, RW_DRIVER, NULL);
2738c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States mutex_init(&iscsit_global.global_state_mutex, NULL,
2748c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States MUTEX_DRIVER, NULL);
275a6d42e7dSPeter Dunlap iscsit_global.global_svc_state = ISE_DETACHED;
276a6d42e7dSPeter Dunlap
277d618d68dSPriya Krishnan mutex_init(&iscsit_rxpdu_queue_monitor_mutex, NULL,
278d618d68dSPriya Krishnan MUTEX_DRIVER, NULL);
2793fc1e17eSPriya Krishnan mutex_init(&login_sm_session_mutex, NULL, MUTEX_DRIVER, NULL);
280d618d68dSPriya Krishnan iscsit_rxpdu_queue_monitor_thr_id = NULL;
281d618d68dSPriya Krishnan iscsit_rxpdu_queue_monitor_thr_running = B_FALSE;
282d618d68dSPriya Krishnan cv_init(&iscsit_rxpdu_queue_monitor_cv, NULL, CV_DEFAULT, NULL);
283d618d68dSPriya Krishnan
284a6d42e7dSPeter Dunlap if ((rc = mod_install(&modlinkage)) != 0) {
2858c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States mutex_destroy(&iscsit_global.global_state_mutex);
286a6d42e7dSPeter Dunlap rw_destroy(&iscsit_global.global_rwlock);
287a6d42e7dSPeter Dunlap return (rc);
288a6d42e7dSPeter Dunlap }
289a6d42e7dSPeter Dunlap
290a6d42e7dSPeter Dunlap return (rc);
291a6d42e7dSPeter Dunlap }
292a6d42e7dSPeter Dunlap
293a6d42e7dSPeter Dunlap int
_info(struct modinfo * modinfop)294a6d42e7dSPeter Dunlap _info(struct modinfo *modinfop)
295a6d42e7dSPeter Dunlap {
296a6d42e7dSPeter Dunlap return (mod_info(&modlinkage, modinfop));
297a6d42e7dSPeter Dunlap }
298a6d42e7dSPeter Dunlap
299a6d42e7dSPeter Dunlap int
_fini(void)300a6d42e7dSPeter Dunlap _fini(void)
301a6d42e7dSPeter Dunlap {
302a6d42e7dSPeter Dunlap int rc;
303a6d42e7dSPeter Dunlap
304a6d42e7dSPeter Dunlap rc = mod_remove(&modlinkage);
305a6d42e7dSPeter Dunlap
306a6d42e7dSPeter Dunlap if (rc == 0) {
307d618d68dSPriya Krishnan mutex_destroy(&iscsit_rxpdu_queue_monitor_mutex);
3083fc1e17eSPriya Krishnan mutex_destroy(&login_sm_session_mutex);
309d618d68dSPriya Krishnan cv_destroy(&iscsit_rxpdu_queue_monitor_cv);
3108c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States mutex_destroy(&iscsit_global.global_state_mutex);
311a6d42e7dSPeter Dunlap rw_destroy(&iscsit_global.global_rwlock);
312a6d42e7dSPeter Dunlap }
313a6d42e7dSPeter Dunlap
314a6d42e7dSPeter Dunlap return (rc);
315a6d42e7dSPeter Dunlap }
316a6d42e7dSPeter Dunlap
317a6d42e7dSPeter Dunlap /*
318a6d42e7dSPeter Dunlap * DDI entry points.
319a6d42e7dSPeter Dunlap */
320a6d42e7dSPeter Dunlap
321a6d42e7dSPeter Dunlap /* ARGSUSED */
322a6d42e7dSPeter Dunlap static int
iscsit_drv_getinfo(dev_info_t * dip,ddi_info_cmd_t cmd,void * arg,void ** result)323a6d42e7dSPeter Dunlap iscsit_drv_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg,
324a6d42e7dSPeter Dunlap void **result)
325a6d42e7dSPeter Dunlap {
326a6d42e7dSPeter Dunlap ulong_t instance = getminor((dev_t)arg);
327a6d42e7dSPeter Dunlap
328a6d42e7dSPeter Dunlap switch (cmd) {
329a6d42e7dSPeter Dunlap case DDI_INFO_DEVT2DEVINFO:
330a6d42e7dSPeter Dunlap *result = iscsit_global.global_dip;
331a6d42e7dSPeter Dunlap return (DDI_SUCCESS);
332a6d42e7dSPeter Dunlap
333a6d42e7dSPeter Dunlap case DDI_INFO_DEVT2INSTANCE:
334a6d42e7dSPeter Dunlap *result = (void *)instance;
335a6d42e7dSPeter Dunlap return (DDI_SUCCESS);
336a6d42e7dSPeter Dunlap
337a6d42e7dSPeter Dunlap default:
338a6d42e7dSPeter Dunlap break;
339a6d42e7dSPeter Dunlap }
340a6d42e7dSPeter Dunlap
341a6d42e7dSPeter Dunlap return (DDI_FAILURE);
342a6d42e7dSPeter Dunlap }
343a6d42e7dSPeter Dunlap
344a6d42e7dSPeter Dunlap static int
iscsit_drv_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)345a6d42e7dSPeter Dunlap iscsit_drv_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
346a6d42e7dSPeter Dunlap {
347a6d42e7dSPeter Dunlap if (cmd != DDI_ATTACH) {
348a6d42e7dSPeter Dunlap return (DDI_FAILURE);
349a6d42e7dSPeter Dunlap }
350a6d42e7dSPeter Dunlap
351a6d42e7dSPeter Dunlap if (ddi_get_instance(dip) != 0) {
352a6d42e7dSPeter Dunlap /* we only allow instance 0 to attach */
353a6d42e7dSPeter Dunlap return (DDI_FAILURE);
354a6d42e7dSPeter Dunlap }
355a6d42e7dSPeter Dunlap
356a6d42e7dSPeter Dunlap /* create the minor node */
357a6d42e7dSPeter Dunlap if (ddi_create_minor_node(dip, ISCSIT_MODNAME, S_IFCHR, 0,
358a6d42e7dSPeter Dunlap DDI_PSEUDO, 0) != DDI_SUCCESS) {
359a6d42e7dSPeter Dunlap cmn_err(CE_WARN, "iscsit_drv_attach: "
360a6d42e7dSPeter Dunlap "failed creating minor node");
361a6d42e7dSPeter Dunlap return (DDI_FAILURE);
362a6d42e7dSPeter Dunlap }
363a6d42e7dSPeter Dunlap
364a6d42e7dSPeter Dunlap if (iscsit_init(dip) != IDM_STATUS_SUCCESS) {
365a6d42e7dSPeter Dunlap cmn_err(CE_WARN, "iscsit_drv_attach: "
366a6d42e7dSPeter Dunlap "failed to initialize");
367a6d42e7dSPeter Dunlap ddi_remove_minor_node(dip, NULL);
368a6d42e7dSPeter Dunlap return (DDI_FAILURE);
369a6d42e7dSPeter Dunlap }
370a6d42e7dSPeter Dunlap
371a6d42e7dSPeter Dunlap iscsit_global.global_svc_state = ISE_DISABLED;
372a6d42e7dSPeter Dunlap iscsit_global.global_dip = dip;
373a6d42e7dSPeter Dunlap
374a6d42e7dSPeter Dunlap return (DDI_SUCCESS);
375a6d42e7dSPeter Dunlap }
376a6d42e7dSPeter Dunlap
377a6d42e7dSPeter Dunlap /*ARGSUSED*/
378a6d42e7dSPeter Dunlap static int
iscsit_drv_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)379a6d42e7dSPeter Dunlap iscsit_drv_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
380a6d42e7dSPeter Dunlap {
381a6d42e7dSPeter Dunlap if (cmd != DDI_DETACH)
382a6d42e7dSPeter Dunlap return (DDI_FAILURE);
383a6d42e7dSPeter Dunlap
3848c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States /*
3858c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States * drv_detach is called in a context that owns the
3868c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States * device node for the /dev/pseudo device. If this thread blocks
3878c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States * for any resource, other threads that need the /dev/pseudo device
3888c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States * may end up in a deadlock with this thread.Hence, we use a
3898c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States * separate lock just for the structures that drv_detach needs
3908c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States * to access.
3918c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States */
3928c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States mutex_enter(&iscsit_global.global_state_mutex);
393a6d42e7dSPeter Dunlap if (iscsit_drv_busy()) {
3948c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States mutex_exit(&iscsit_global.global_state_mutex);
395a6d42e7dSPeter Dunlap return (EBUSY);
396a6d42e7dSPeter Dunlap }
397a6d42e7dSPeter Dunlap
398a6d42e7dSPeter Dunlap iscsit_global.global_dip = NULL;
399a6d42e7dSPeter Dunlap ddi_remove_minor_node(dip, NULL);
400a6d42e7dSPeter Dunlap
401a6d42e7dSPeter Dunlap ldi_ident_release(iscsit_global.global_li);
402a6d42e7dSPeter Dunlap iscsit_global.global_svc_state = ISE_DETACHED;
403a6d42e7dSPeter Dunlap
4048c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States mutex_exit(&iscsit_global.global_state_mutex);
405a6d42e7dSPeter Dunlap
406a6d42e7dSPeter Dunlap return (DDI_SUCCESS);
407a6d42e7dSPeter Dunlap }
408a6d42e7dSPeter Dunlap
409a6d42e7dSPeter Dunlap /*ARGSUSED*/
410a6d42e7dSPeter Dunlap static int
iscsit_drv_open(dev_t * devp,int flag,int otyp,cred_t * credp)411a6d42e7dSPeter Dunlap iscsit_drv_open(dev_t *devp, int flag, int otyp, cred_t *credp)
412a6d42e7dSPeter Dunlap {
413a6d42e7dSPeter Dunlap return (0);
414a6d42e7dSPeter Dunlap }
415a6d42e7dSPeter Dunlap
416a6d42e7dSPeter Dunlap /* ARGSUSED */
417a6d42e7dSPeter Dunlap static int
iscsit_drv_close(dev_t dev,int flag,int otyp,cred_t * credp)418a6d42e7dSPeter Dunlap iscsit_drv_close(dev_t dev, int flag, int otyp, cred_t *credp)
419a6d42e7dSPeter Dunlap {
420a6d42e7dSPeter Dunlap return (0);
421a6d42e7dSPeter Dunlap }
422a6d42e7dSPeter Dunlap
423a6d42e7dSPeter Dunlap static boolean_t
iscsit_drv_busy(void)424a6d42e7dSPeter Dunlap iscsit_drv_busy(void)
425a6d42e7dSPeter Dunlap {
4268c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States ASSERT(MUTEX_HELD(&iscsit_global.global_state_mutex));
4278c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States
428a6d42e7dSPeter Dunlap switch (iscsit_global.global_svc_state) {
429a6d42e7dSPeter Dunlap case ISE_DISABLED:
430a6d42e7dSPeter Dunlap case ISE_DETACHED:
431a6d42e7dSPeter Dunlap return (B_FALSE);
432a6d42e7dSPeter Dunlap default:
433a6d42e7dSPeter Dunlap return (B_TRUE);
434a6d42e7dSPeter Dunlap }
435a6d42e7dSPeter Dunlap /* NOTREACHED */
436a6d42e7dSPeter Dunlap }
437a6d42e7dSPeter Dunlap
438a6d42e7dSPeter Dunlap /* ARGSUSED */
439a6d42e7dSPeter Dunlap static int
iscsit_drv_ioctl(dev_t drv,int cmd,intptr_t argp,int flag,cred_t * cred,int * retval)440a6d42e7dSPeter Dunlap iscsit_drv_ioctl(dev_t drv, int cmd, intptr_t argp, int flag, cred_t *cred,
441a6d42e7dSPeter Dunlap int *retval)
442a6d42e7dSPeter Dunlap {
443a6d42e7dSPeter Dunlap iscsit_ioc_set_config_t setcfg;
444a6d42e7dSPeter Dunlap iscsit_ioc_set_config32_t setcfg32;
44507a2bfd1SPeter Cudhea - Sun Microsystems - Burlington, MA United States char *cfg_pnvlist = NULL;
44607a2bfd1SPeter Cudhea - Sun Microsystems - Burlington, MA United States nvlist_t *cfg_nvlist = NULL;
44707a2bfd1SPeter Cudhea - Sun Microsystems - Burlington, MA United States it_config_t *cfg = NULL;
448a6d42e7dSPeter Dunlap idm_status_t idmrc;
449a6d42e7dSPeter Dunlap int rc = 0;
450a6d42e7dSPeter Dunlap
451a6d42e7dSPeter Dunlap if (drv_priv(cred) != 0) {
452a6d42e7dSPeter Dunlap return (EPERM);
453a6d42e7dSPeter Dunlap }
454a6d42e7dSPeter Dunlap
4558c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States mutex_enter(&iscsit_global.global_state_mutex);
456a6d42e7dSPeter Dunlap
457a6d42e7dSPeter Dunlap /*
458a6d42e7dSPeter Dunlap * Validate ioctl requests against global service state
459a6d42e7dSPeter Dunlap */
460a6d42e7dSPeter Dunlap switch (iscsit_global.global_svc_state) {
461a6d42e7dSPeter Dunlap case ISE_ENABLED:
462a6d42e7dSPeter Dunlap if (cmd == ISCSIT_IOC_DISABLE_SVC) {
463a6d42e7dSPeter Dunlap iscsit_global.global_svc_state = ISE_DISABLING;
464a6d42e7dSPeter Dunlap } else if (cmd == ISCSIT_IOC_ENABLE_SVC) {
465a6d42e7dSPeter Dunlap /* Already enabled */
4668c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States mutex_exit(&iscsit_global.global_state_mutex);
467a6d42e7dSPeter Dunlap return (0);
468a6d42e7dSPeter Dunlap } else {
469a6d42e7dSPeter Dunlap iscsit_global.global_svc_state = ISE_BUSY;
470a6d42e7dSPeter Dunlap }
471a6d42e7dSPeter Dunlap break;
472a6d42e7dSPeter Dunlap case ISE_DISABLED:
473a6d42e7dSPeter Dunlap if (cmd == ISCSIT_IOC_ENABLE_SVC) {
474a6d42e7dSPeter Dunlap iscsit_global.global_svc_state = ISE_ENABLING;
475a6d42e7dSPeter Dunlap } else if (cmd == ISCSIT_IOC_DISABLE_SVC) {
476a6d42e7dSPeter Dunlap /* Already disabled */
4778c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States mutex_exit(&iscsit_global.global_state_mutex);
478a6d42e7dSPeter Dunlap return (0);
479a6d42e7dSPeter Dunlap } else {
480a6d42e7dSPeter Dunlap rc = EFAULT;
481a6d42e7dSPeter Dunlap }
482a6d42e7dSPeter Dunlap break;
4838c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States case ISE_BUSY:
484a6d42e7dSPeter Dunlap case ISE_ENABLING:
485a6d42e7dSPeter Dunlap case ISE_DISABLING:
486a6d42e7dSPeter Dunlap rc = EAGAIN;
487a6d42e7dSPeter Dunlap break;
488a6d42e7dSPeter Dunlap case ISE_DETACHED:
489a6d42e7dSPeter Dunlap default:
490a6d42e7dSPeter Dunlap rc = EFAULT;
491a6d42e7dSPeter Dunlap break;
492a6d42e7dSPeter Dunlap }
493a6d42e7dSPeter Dunlap
4948c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States mutex_exit(&iscsit_global.global_state_mutex);
495a6d42e7dSPeter Dunlap if (rc != 0)
496a6d42e7dSPeter Dunlap return (rc);
497a6d42e7dSPeter Dunlap
498a6d42e7dSPeter Dunlap /* Handle ioctl request (enable/disable have already been handled) */
499a6d42e7dSPeter Dunlap switch (cmd) {
500a6d42e7dSPeter Dunlap case ISCSIT_IOC_SET_CONFIG:
50107a2bfd1SPeter Cudhea - Sun Microsystems - Burlington, MA United States /* Any errors must set state back to ISE_ENABLED */
502a6d42e7dSPeter Dunlap switch (ddi_model_convert_from(flag & FMODELS)) {
503a6d42e7dSPeter Dunlap case DDI_MODEL_ILP32:
504a6d42e7dSPeter Dunlap if (ddi_copyin((void *)argp, &setcfg32,
50507a2bfd1SPeter Cudhea - Sun Microsystems - Burlington, MA United States sizeof (iscsit_ioc_set_config32_t), flag) != 0) {
50607a2bfd1SPeter Cudhea - Sun Microsystems - Burlington, MA United States rc = EFAULT;
50707a2bfd1SPeter Cudhea - Sun Microsystems - Burlington, MA United States goto cleanup;
50807a2bfd1SPeter Cudhea - Sun Microsystems - Burlington, MA United States }
509a6d42e7dSPeter Dunlap
510a6d42e7dSPeter Dunlap setcfg.set_cfg_pnvlist =
511a6d42e7dSPeter Dunlap (char *)((uintptr_t)setcfg32.set_cfg_pnvlist);
512a6d42e7dSPeter Dunlap setcfg.set_cfg_vers = setcfg32.set_cfg_vers;
513a6d42e7dSPeter Dunlap setcfg.set_cfg_pnvlist_len =
514a6d42e7dSPeter Dunlap setcfg32.set_cfg_pnvlist_len;
515a6d42e7dSPeter Dunlap break;
516a6d42e7dSPeter Dunlap case DDI_MODEL_NONE:
517a6d42e7dSPeter Dunlap if (ddi_copyin((void *)argp, &setcfg,
51807a2bfd1SPeter Cudhea - Sun Microsystems - Burlington, MA United States sizeof (iscsit_ioc_set_config_t), flag) != 0) {
51907a2bfd1SPeter Cudhea - Sun Microsystems - Burlington, MA United States rc = EFAULT;
52007a2bfd1SPeter Cudhea - Sun Microsystems - Burlington, MA United States goto cleanup;
52107a2bfd1SPeter Cudhea - Sun Microsystems - Burlington, MA United States }
522a6d42e7dSPeter Dunlap break;
523fcc214c3SCharles Ting default:
524fcc214c3SCharles Ting rc = EFAULT;
525fcc214c3SCharles Ting goto cleanup;
526a6d42e7dSPeter Dunlap }
527a6d42e7dSPeter Dunlap
528a6d42e7dSPeter Dunlap /* Check API version */
529a6d42e7dSPeter Dunlap if (setcfg.set_cfg_vers != ISCSIT_API_VERS0) {
53007a2bfd1SPeter Cudhea - Sun Microsystems - Burlington, MA United States rc = EINVAL;
53107a2bfd1SPeter Cudhea - Sun Microsystems - Burlington, MA United States goto cleanup;
532a6d42e7dSPeter Dunlap }
533a6d42e7dSPeter Dunlap
534a6d42e7dSPeter Dunlap /* Config is in packed nvlist format so unpack it */
535a6d42e7dSPeter Dunlap cfg_pnvlist = kmem_alloc(setcfg.set_cfg_pnvlist_len,
536a6d42e7dSPeter Dunlap KM_SLEEP);
537a6d42e7dSPeter Dunlap ASSERT(cfg_pnvlist != NULL);
538a6d42e7dSPeter Dunlap
539a6d42e7dSPeter Dunlap if (ddi_copyin(setcfg.set_cfg_pnvlist, cfg_pnvlist,
540a6d42e7dSPeter Dunlap setcfg.set_cfg_pnvlist_len, flag) != 0) {
54107a2bfd1SPeter Cudhea - Sun Microsystems - Burlington, MA United States rc = EFAULT;
54207a2bfd1SPeter Cudhea - Sun Microsystems - Burlington, MA United States goto cleanup;
543a6d42e7dSPeter Dunlap }
544a6d42e7dSPeter Dunlap
54507a2bfd1SPeter Cudhea - Sun Microsystems - Burlington, MA United States rc = nvlist_unpack(cfg_pnvlist, setcfg.set_cfg_pnvlist_len,
54607a2bfd1SPeter Cudhea - Sun Microsystems - Burlington, MA United States &cfg_nvlist, KM_SLEEP);
54707a2bfd1SPeter Cudhea - Sun Microsystems - Burlington, MA United States if (rc != 0) {
54807a2bfd1SPeter Cudhea - Sun Microsystems - Burlington, MA United States goto cleanup;
549a6d42e7dSPeter Dunlap }
550a6d42e7dSPeter Dunlap
551a6d42e7dSPeter Dunlap /* Translate nvlist */
55207a2bfd1SPeter Cudhea - Sun Microsystems - Burlington, MA United States rc = it_nv_to_config(cfg_nvlist, &cfg);
55307a2bfd1SPeter Cudhea - Sun Microsystems - Burlington, MA United States if (rc != 0) {
554a6d42e7dSPeter Dunlap cmn_err(CE_WARN, "Configuration is invalid");
55507a2bfd1SPeter Cudhea - Sun Microsystems - Burlington, MA United States goto cleanup;
556a6d42e7dSPeter Dunlap }
557a6d42e7dSPeter Dunlap
558a6d42e7dSPeter Dunlap /* Update config */
55907a2bfd1SPeter Cudhea - Sun Microsystems - Burlington, MA United States rc = iscsit_config_merge(cfg);
56007a2bfd1SPeter Cudhea - Sun Microsystems - Burlington, MA United States /* FALLTHROUGH */
56107a2bfd1SPeter Cudhea - Sun Microsystems - Burlington, MA United States
56207a2bfd1SPeter Cudhea - Sun Microsystems - Burlington, MA United States cleanup:
56307a2bfd1SPeter Cudhea - Sun Microsystems - Burlington, MA United States if (cfg)
56407a2bfd1SPeter Cudhea - Sun Microsystems - Burlington, MA United States it_config_free_cmn(cfg);
56507a2bfd1SPeter Cudhea - Sun Microsystems - Burlington, MA United States if (cfg_pnvlist)
566a6d42e7dSPeter Dunlap kmem_free(cfg_pnvlist, setcfg.set_cfg_pnvlist_len);
567*61dfa509SRick McNeal if (cfg_nvlist)
568*61dfa509SRick McNeal nvlist_free(cfg_nvlist);
569a6d42e7dSPeter Dunlap
570a6d42e7dSPeter Dunlap /*
571a6d42e7dSPeter Dunlap * Now that the reconfig is complete set our state back to
572a6d42e7dSPeter Dunlap * enabled.
573a6d42e7dSPeter Dunlap */
5748c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States mutex_enter(&iscsit_global.global_state_mutex);
575a6d42e7dSPeter Dunlap iscsit_global.global_svc_state = ISE_ENABLED;
5768c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States mutex_exit(&iscsit_global.global_state_mutex);
577a6d42e7dSPeter Dunlap break;
578a6d42e7dSPeter Dunlap case ISCSIT_IOC_ENABLE_SVC: {
579a6d42e7dSPeter Dunlap iscsit_hostinfo_t hostinfo;
580a6d42e7dSPeter Dunlap
581a6d42e7dSPeter Dunlap if (ddi_copyin((void *)argp, &hostinfo.length,
582a6d42e7dSPeter Dunlap sizeof (hostinfo.length), flag) != 0) {
5838c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States mutex_enter(&iscsit_global.global_state_mutex);
584a6d42e7dSPeter Dunlap iscsit_global.global_svc_state = ISE_DISABLED;
5858c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States mutex_exit(&iscsit_global.global_state_mutex);
586a6d42e7dSPeter Dunlap return (EFAULT);
587a6d42e7dSPeter Dunlap }
588a6d42e7dSPeter Dunlap
589a6d42e7dSPeter Dunlap if (hostinfo.length > sizeof (hostinfo.fqhn))
590a6d42e7dSPeter Dunlap hostinfo.length = sizeof (hostinfo.fqhn);
591a6d42e7dSPeter Dunlap
592a6d42e7dSPeter Dunlap if (ddi_copyin((void *)((caddr_t)argp +
593a6d42e7dSPeter Dunlap sizeof (hostinfo.length)), &hostinfo.fqhn,
594a6d42e7dSPeter Dunlap hostinfo.length, flag) != 0) {
5958c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States mutex_enter(&iscsit_global.global_state_mutex);
596a6d42e7dSPeter Dunlap iscsit_global.global_svc_state = ISE_DISABLED;
5978c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States mutex_exit(&iscsit_global.global_state_mutex);
598a6d42e7dSPeter Dunlap return (EFAULT);
599a6d42e7dSPeter Dunlap }
600a6d42e7dSPeter Dunlap
601a6d42e7dSPeter Dunlap idmrc = iscsit_enable_svc(&hostinfo);
6028c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States mutex_enter(&iscsit_global.global_state_mutex);
603a6d42e7dSPeter Dunlap if (idmrc == IDM_STATUS_SUCCESS) {
604a6d42e7dSPeter Dunlap iscsit_global.global_svc_state = ISE_ENABLED;
605a6d42e7dSPeter Dunlap } else {
606a6d42e7dSPeter Dunlap rc = EIO;
607a6d42e7dSPeter Dunlap iscsit_global.global_svc_state = ISE_DISABLED;
608a6d42e7dSPeter Dunlap }
6098c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States mutex_exit(&iscsit_global.global_state_mutex);
610a6d42e7dSPeter Dunlap break;
611a6d42e7dSPeter Dunlap }
612a6d42e7dSPeter Dunlap case ISCSIT_IOC_DISABLE_SVC:
613a6d42e7dSPeter Dunlap iscsit_disable_svc();
6148c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States mutex_enter(&iscsit_global.global_state_mutex);
615a6d42e7dSPeter Dunlap iscsit_global.global_svc_state = ISE_DISABLED;
6168c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States mutex_exit(&iscsit_global.global_state_mutex);
617a6d42e7dSPeter Dunlap break;
61807a2bfd1SPeter Cudhea - Sun Microsystems - Burlington, MA United States
619a6d42e7dSPeter Dunlap default:
620a6d42e7dSPeter Dunlap rc = EINVAL;
6218c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States mutex_enter(&iscsit_global.global_state_mutex);
62207a2bfd1SPeter Cudhea - Sun Microsystems - Burlington, MA United States iscsit_global.global_svc_state = ISE_ENABLED;
6238c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States mutex_exit(&iscsit_global.global_state_mutex);
624a6d42e7dSPeter Dunlap }
625a6d42e7dSPeter Dunlap
626a6d42e7dSPeter Dunlap return (rc);
627a6d42e7dSPeter Dunlap }
628a6d42e7dSPeter Dunlap
629a6d42e7dSPeter Dunlap static idm_status_t
iscsit_init(dev_info_t * dip)630a6d42e7dSPeter Dunlap iscsit_init(dev_info_t *dip)
631a6d42e7dSPeter Dunlap {
632a6d42e7dSPeter Dunlap int rc;
633a6d42e7dSPeter Dunlap
634a6d42e7dSPeter Dunlap rc = ldi_ident_from_dip(dip, &iscsit_global.global_li);
635a6d42e7dSPeter Dunlap ASSERT(rc == 0); /* Failure indicates invalid argument */
636a6d42e7dSPeter Dunlap
637a6d42e7dSPeter Dunlap iscsit_global.global_svc_state = ISE_DISABLED;
638a6d42e7dSPeter Dunlap
639a6d42e7dSPeter Dunlap return (IDM_STATUS_SUCCESS);
640a6d42e7dSPeter Dunlap }
641a6d42e7dSPeter Dunlap
642a6d42e7dSPeter Dunlap /*
643a6d42e7dSPeter Dunlap * iscsit_enable_svc
644a6d42e7dSPeter Dunlap *
645a6d42e7dSPeter Dunlap * registers all the configured targets and target portals with STMF
646a6d42e7dSPeter Dunlap */
647a6d42e7dSPeter Dunlap static idm_status_t
iscsit_enable_svc(iscsit_hostinfo_t * hostinfo)648a6d42e7dSPeter Dunlap iscsit_enable_svc(iscsit_hostinfo_t *hostinfo)
649a6d42e7dSPeter Dunlap {
650a6d42e7dSPeter Dunlap stmf_port_provider_t *pp;
651a6d42e7dSPeter Dunlap stmf_dbuf_store_t *dbuf_store;
652a6d42e7dSPeter Dunlap boolean_t did_iscsit_isns_init;
653a6d42e7dSPeter Dunlap idm_status_t retval = IDM_STATUS_SUCCESS;
654a6d42e7dSPeter Dunlap
655a6d42e7dSPeter Dunlap ASSERT(iscsit_global.global_svc_state == ISE_ENABLING);
656a6d42e7dSPeter Dunlap
657a6d42e7dSPeter Dunlap /*
658a6d42e7dSPeter Dunlap * Make sure that can tell if we have partially allocated
659a6d42e7dSPeter Dunlap * in case we need to exit and tear down anything allocated.
660a6d42e7dSPeter Dunlap */
661a6d42e7dSPeter Dunlap iscsit_global.global_tsih_pool = NULL;
662a6d42e7dSPeter Dunlap iscsit_global.global_dbuf_store = NULL;
663a6d42e7dSPeter Dunlap iscsit_status_pdu_cache = NULL;
664a6d42e7dSPeter Dunlap pp = NULL;
665a6d42e7dSPeter Dunlap iscsit_global.global_pp = NULL;
666a6d42e7dSPeter Dunlap iscsit_global.global_default_tpg = NULL;
667a6d42e7dSPeter Dunlap did_iscsit_isns_init = B_FALSE;
668a6d42e7dSPeter Dunlap iscsit_global.global_dispatch_taskq = NULL;
669a6d42e7dSPeter Dunlap
670a6d42e7dSPeter Dunlap /* Setup remaining fields in iscsit_global_t */
671a6d42e7dSPeter Dunlap idm_refcnt_init(&iscsit_global.global_refcnt,
672a6d42e7dSPeter Dunlap &iscsit_global);
673a6d42e7dSPeter Dunlap
674a6d42e7dSPeter Dunlap avl_create(&iscsit_global.global_discovery_sessions,
675a6d42e7dSPeter Dunlap iscsit_sess_avl_compare, sizeof (iscsit_sess_t),
676a6d42e7dSPeter Dunlap offsetof(iscsit_sess_t, ist_tgt_ln));
677a6d42e7dSPeter Dunlap
678a6d42e7dSPeter Dunlap avl_create(&iscsit_global.global_target_list,
679a6d42e7dSPeter Dunlap iscsit_tgt_avl_compare, sizeof (iscsit_tgt_t),
680a6d42e7dSPeter Dunlap offsetof(iscsit_tgt_t, target_global_ln));
681a6d42e7dSPeter Dunlap
682a6d42e7dSPeter Dunlap list_create(&iscsit_global.global_deleted_target_list,
683a6d42e7dSPeter Dunlap sizeof (iscsit_tgt_t),
684a6d42e7dSPeter Dunlap offsetof(iscsit_tgt_t, target_global_deleted_ln));
685a6d42e7dSPeter Dunlap
686a6d42e7dSPeter Dunlap avl_create(&iscsit_global.global_tpg_list,
687a6d42e7dSPeter Dunlap iscsit_tpg_avl_compare, sizeof (iscsit_tpg_t),
688a6d42e7dSPeter Dunlap offsetof(iscsit_tpg_t, tpg_global_ln));
689a6d42e7dSPeter Dunlap
690a6d42e7dSPeter Dunlap avl_create(&iscsit_global.global_ini_list,
691a6d42e7dSPeter Dunlap iscsit_ini_avl_compare, sizeof (iscsit_ini_t),
692a6d42e7dSPeter Dunlap offsetof(iscsit_ini_t, ini_global_ln));
693a6d42e7dSPeter Dunlap
694a6d42e7dSPeter Dunlap iscsit_global.global_tsih_pool = vmem_create("iscsit_tsih_pool",
695a6d42e7dSPeter Dunlap (void *)1, ISCSI_MAX_TSIH, 1, NULL, NULL, NULL, 0,
696a6d42e7dSPeter Dunlap VM_SLEEP | VMC_IDENTIFIER);
697a6d42e7dSPeter Dunlap
698a6d42e7dSPeter Dunlap /*
699a6d42e7dSPeter Dunlap * Setup STMF dbuf store. Our buffers are bound to a specific
700a6d42e7dSPeter Dunlap * connection so we really can't let STMF cache buffers for us.
701a6d42e7dSPeter Dunlap * Consequently we'll just allocate one global buffer store.
702a6d42e7dSPeter Dunlap */
703a6d42e7dSPeter Dunlap dbuf_store = stmf_alloc(STMF_STRUCT_DBUF_STORE, 0, 0);
704a6d42e7dSPeter Dunlap if (dbuf_store == NULL) {
705a6d42e7dSPeter Dunlap retval = IDM_STATUS_FAIL;
706a6d42e7dSPeter Dunlap goto tear_down_and_return;
707a6d42e7dSPeter Dunlap }
708a6d42e7dSPeter Dunlap dbuf_store->ds_alloc_data_buf = iscsit_dbuf_alloc;
709a6d42e7dSPeter Dunlap dbuf_store->ds_free_data_buf = iscsit_dbuf_free;
710a6d42e7dSPeter Dunlap dbuf_store->ds_port_private = NULL;
711a6d42e7dSPeter Dunlap iscsit_global.global_dbuf_store = dbuf_store;
712a6d42e7dSPeter Dunlap
713a6d42e7dSPeter Dunlap /* Status PDU cache */
714a6d42e7dSPeter Dunlap iscsit_status_pdu_cache = kmem_cache_create("iscsit_status_pdu_cache",
715a6d42e7dSPeter Dunlap sizeof (idm_pdu_t) + sizeof (iscsi_scsi_rsp_hdr_t), 8,
716a6d42e7dSPeter Dunlap &iscsit_status_pdu_constructor,
717a6d42e7dSPeter Dunlap NULL, NULL, NULL, NULL, KM_SLEEP);
718a6d42e7dSPeter Dunlap
719a6d42e7dSPeter Dunlap /* Default TPG and portal */
720a6d42e7dSPeter Dunlap iscsit_global.global_default_tpg = iscsit_tpg_createdefault();
721a6d42e7dSPeter Dunlap if (iscsit_global.global_default_tpg == NULL) {
722a6d42e7dSPeter Dunlap retval = IDM_STATUS_FAIL;
723a6d42e7dSPeter Dunlap goto tear_down_and_return;
724a6d42e7dSPeter Dunlap }
725a6d42e7dSPeter Dunlap
726a6d42e7dSPeter Dunlap /* initialize isns client */
727a6d42e7dSPeter Dunlap (void) iscsit_isns_init(hostinfo);
728a6d42e7dSPeter Dunlap did_iscsit_isns_init = B_TRUE;
729a6d42e7dSPeter Dunlap
730a6d42e7dSPeter Dunlap /* Register port provider */
731a6d42e7dSPeter Dunlap pp = stmf_alloc(STMF_STRUCT_PORT_PROVIDER, 0, 0);
732a6d42e7dSPeter Dunlap if (pp == NULL) {
733a6d42e7dSPeter Dunlap retval = IDM_STATUS_FAIL;
734a6d42e7dSPeter Dunlap goto tear_down_and_return;
735a6d42e7dSPeter Dunlap }
736a6d42e7dSPeter Dunlap
737a6d42e7dSPeter Dunlap pp->pp_portif_rev = PORTIF_REV_1;
738a6d42e7dSPeter Dunlap pp->pp_instance = 0;
739a6d42e7dSPeter Dunlap pp->pp_name = ISCSIT_MODNAME;
740a6d42e7dSPeter Dunlap pp->pp_cb = iscsit_pp_cb;
741a6d42e7dSPeter Dunlap
742a6d42e7dSPeter Dunlap iscsit_global.global_pp = pp;
743a6d42e7dSPeter Dunlap
744a6d42e7dSPeter Dunlap
745a6d42e7dSPeter Dunlap if (stmf_register_port_provider(pp) != STMF_SUCCESS) {
746a6d42e7dSPeter Dunlap retval = IDM_STATUS_FAIL;
747a6d42e7dSPeter Dunlap goto tear_down_and_return;
748a6d42e7dSPeter Dunlap }
749a6d42e7dSPeter Dunlap
750a6d42e7dSPeter Dunlap iscsit_global.global_dispatch_taskq = taskq_create("iscsit_dispatch",
751a6d42e7dSPeter Dunlap 1, minclsyspri, 16, 16, TASKQ_PREPOPULATE);
752a6d42e7dSPeter Dunlap
753d618d68dSPriya Krishnan /* Scan staged PDUs, meaningful in MC/S situations */
754d618d68dSPriya Krishnan iscsit_rxpdu_queue_monitor_start();
755d618d68dSPriya Krishnan
756a6d42e7dSPeter Dunlap return (IDM_STATUS_SUCCESS);
757a6d42e7dSPeter Dunlap
758a6d42e7dSPeter Dunlap tear_down_and_return:
759a6d42e7dSPeter Dunlap
760a6d42e7dSPeter Dunlap if (iscsit_global.global_dispatch_taskq) {
761a6d42e7dSPeter Dunlap taskq_destroy(iscsit_global.global_dispatch_taskq);
762a6d42e7dSPeter Dunlap iscsit_global.global_dispatch_taskq = NULL;
763a6d42e7dSPeter Dunlap }
764a6d42e7dSPeter Dunlap
765a6d42e7dSPeter Dunlap if (did_iscsit_isns_init)
766a6d42e7dSPeter Dunlap iscsit_isns_fini();
767a6d42e7dSPeter Dunlap
768a6d42e7dSPeter Dunlap if (iscsit_global.global_default_tpg) {
769a6d42e7dSPeter Dunlap iscsit_tpg_destroydefault(iscsit_global.global_default_tpg);
770a6d42e7dSPeter Dunlap iscsit_global.global_default_tpg = NULL;
771a6d42e7dSPeter Dunlap }
772a6d42e7dSPeter Dunlap
773a6d42e7dSPeter Dunlap if (iscsit_global.global_pp)
774a6d42e7dSPeter Dunlap iscsit_global.global_pp = NULL;
775a6d42e7dSPeter Dunlap
776a6d42e7dSPeter Dunlap if (pp)
777a6d42e7dSPeter Dunlap stmf_free(pp);
778a6d42e7dSPeter Dunlap
779a6d42e7dSPeter Dunlap if (iscsit_status_pdu_cache) {
780a6d42e7dSPeter Dunlap kmem_cache_destroy(iscsit_status_pdu_cache);
781a6d42e7dSPeter Dunlap iscsit_status_pdu_cache = NULL;
782a6d42e7dSPeter Dunlap }
783a6d42e7dSPeter Dunlap
784a6d42e7dSPeter Dunlap if (iscsit_global.global_dbuf_store) {
785a6d42e7dSPeter Dunlap stmf_free(iscsit_global.global_dbuf_store);
786a6d42e7dSPeter Dunlap iscsit_global.global_dbuf_store = NULL;
787a6d42e7dSPeter Dunlap }
788a6d42e7dSPeter Dunlap
789a6d42e7dSPeter Dunlap if (iscsit_global.global_tsih_pool) {
790a6d42e7dSPeter Dunlap vmem_destroy(iscsit_global.global_tsih_pool);
791a6d42e7dSPeter Dunlap iscsit_global.global_tsih_pool = NULL;
792a6d42e7dSPeter Dunlap }
793a6d42e7dSPeter Dunlap
794a6d42e7dSPeter Dunlap avl_destroy(&iscsit_global.global_ini_list);
795a6d42e7dSPeter Dunlap avl_destroy(&iscsit_global.global_tpg_list);
796a6d42e7dSPeter Dunlap list_destroy(&iscsit_global.global_deleted_target_list);
797a6d42e7dSPeter Dunlap avl_destroy(&iscsit_global.global_target_list);
798a6d42e7dSPeter Dunlap avl_destroy(&iscsit_global.global_discovery_sessions);
799a6d42e7dSPeter Dunlap
800a6d42e7dSPeter Dunlap idm_refcnt_destroy(&iscsit_global.global_refcnt);
801a6d42e7dSPeter Dunlap
802a6d42e7dSPeter Dunlap return (retval);
803a6d42e7dSPeter Dunlap }
804a6d42e7dSPeter Dunlap
805a6d42e7dSPeter Dunlap /*
806a6d42e7dSPeter Dunlap * iscsit_disable_svc
807a6d42e7dSPeter Dunlap *
808a6d42e7dSPeter Dunlap * clean up all existing connections and deregister targets from STMF
809a6d42e7dSPeter Dunlap */
810a6d42e7dSPeter Dunlap static void
iscsit_disable_svc(void)811a6d42e7dSPeter Dunlap iscsit_disable_svc(void)
812a6d42e7dSPeter Dunlap {
813a6d42e7dSPeter Dunlap iscsit_sess_t *sess;
814a6d42e7dSPeter Dunlap
815a6d42e7dSPeter Dunlap ASSERT(iscsit_global.global_svc_state == ISE_DISABLING);
816a6d42e7dSPeter Dunlap
817d618d68dSPriya Krishnan iscsit_rxpdu_queue_monitor_stop();
818d618d68dSPriya Krishnan
819a6d42e7dSPeter Dunlap /* tear down discovery sessions */
820a6d42e7dSPeter Dunlap for (sess = avl_first(&iscsit_global.global_discovery_sessions);
821a6d42e7dSPeter Dunlap sess != NULL;
822a6d42e7dSPeter Dunlap sess = AVL_NEXT(&iscsit_global.global_discovery_sessions, sess))
823a6d42e7dSPeter Dunlap iscsit_sess_close(sess);
824a6d42e7dSPeter Dunlap
825a6d42e7dSPeter Dunlap /*
826a6d42e7dSPeter Dunlap * Passing NULL to iscsit_config_merge tells it to go to an empty
827a6d42e7dSPeter Dunlap * config.
828a6d42e7dSPeter Dunlap */
829a6d42e7dSPeter Dunlap (void) iscsit_config_merge(NULL);
830a6d42e7dSPeter Dunlap
831a6d42e7dSPeter Dunlap /*
832a6d42e7dSPeter Dunlap * Wait until there are no more global references
833a6d42e7dSPeter Dunlap */
834a6d42e7dSPeter Dunlap idm_refcnt_wait_ref(&iscsit_global.global_refcnt);
835a6d42e7dSPeter Dunlap idm_refcnt_destroy(&iscsit_global.global_refcnt);
836a6d42e7dSPeter Dunlap
837a6d42e7dSPeter Dunlap /*
838a6d42e7dSPeter Dunlap * Default TPG must be destroyed after global_refcnt is 0.
839a6d42e7dSPeter Dunlap */
840a6d42e7dSPeter Dunlap iscsit_tpg_destroydefault(iscsit_global.global_default_tpg);
841a6d42e7dSPeter Dunlap
842a6d42e7dSPeter Dunlap avl_destroy(&iscsit_global.global_discovery_sessions);
843a6d42e7dSPeter Dunlap list_destroy(&iscsit_global.global_deleted_target_list);
844a6d42e7dSPeter Dunlap avl_destroy(&iscsit_global.global_target_list);
845a6d42e7dSPeter Dunlap avl_destroy(&iscsit_global.global_tpg_list);
846a6d42e7dSPeter Dunlap avl_destroy(&iscsit_global.global_ini_list);
847a6d42e7dSPeter Dunlap
848a6d42e7dSPeter Dunlap taskq_destroy(iscsit_global.global_dispatch_taskq);
849a6d42e7dSPeter Dunlap
850a6d42e7dSPeter Dunlap iscsit_isns_fini();
851a6d42e7dSPeter Dunlap
852a6d42e7dSPeter Dunlap stmf_free(iscsit_global.global_dbuf_store);
853a6d42e7dSPeter Dunlap iscsit_global.global_dbuf_store = NULL;
854a6d42e7dSPeter Dunlap
855a6d42e7dSPeter Dunlap (void) stmf_deregister_port_provider(iscsit_global.global_pp);
856a6d42e7dSPeter Dunlap stmf_free(iscsit_global.global_pp);
857a6d42e7dSPeter Dunlap iscsit_global.global_pp = NULL;
858a6d42e7dSPeter Dunlap
859a6d42e7dSPeter Dunlap kmem_cache_destroy(iscsit_status_pdu_cache);
860a6d42e7dSPeter Dunlap iscsit_status_pdu_cache = NULL;
861a6d42e7dSPeter Dunlap
862a6d42e7dSPeter Dunlap vmem_destroy(iscsit_global.global_tsih_pool);
863a6d42e7dSPeter Dunlap iscsit_global.global_tsih_pool = NULL;
864a6d42e7dSPeter Dunlap }
865a6d42e7dSPeter Dunlap
866a6d42e7dSPeter Dunlap void
iscsit_global_hold()867a6d42e7dSPeter Dunlap iscsit_global_hold()
868a6d42e7dSPeter Dunlap {
8698c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States /*
8708c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States * To take out a global hold, we must either own the global
8718c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States * state mutex or we must be running inside of an ioctl that
8728c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States * has set the global state to ISE_BUSY, ISE_DISABLING, or
8738c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States * ISE_ENABLING. We don't track the "owner" for these flags,
8748c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States * so just checking if they are set is enough for now.
8758c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States */
8768c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States ASSERT((iscsit_global.global_svc_state == ISE_ENABLING) ||
8778c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States (iscsit_global.global_svc_state == ISE_DISABLING) ||
8788c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States (iscsit_global.global_svc_state == ISE_BUSY) ||
8798c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States MUTEX_HELD(&iscsit_global.global_state_mutex));
8808c629652SPeter Cudhea - Sun Microsystems - Burlington, MA United States
881a6d42e7dSPeter Dunlap idm_refcnt_hold(&iscsit_global.global_refcnt);
882a6d42e7dSPeter Dunlap }
883a6d42e7dSPeter Dunlap
884a6d42e7dSPeter Dunlap void
iscsit_global_rele()885a6d42e7dSPeter Dunlap iscsit_global_rele()
886a6d42e7dSPeter Dunlap {
887a6d42e7dSPeter Dunlap idm_refcnt_rele(&iscsit_global.global_refcnt);
888a6d42e7dSPeter Dunlap }
889a6d42e7dSPeter Dunlap
890a6d42e7dSPeter Dunlap void
iscsit_global_wait_ref()891a6d42e7dSPeter Dunlap iscsit_global_wait_ref()
892a6d42e7dSPeter Dunlap {
893a6d42e7dSPeter Dunlap idm_refcnt_wait_ref(&iscsit_global.global_refcnt);
894a6d42e7dSPeter Dunlap }
895a6d42e7dSPeter Dunlap
896a6d42e7dSPeter Dunlap /*
897a6d42e7dSPeter Dunlap * IDM callbacks
898a6d42e7dSPeter Dunlap */
899a6d42e7dSPeter Dunlap
900a6d42e7dSPeter Dunlap /*ARGSUSED*/
901a6d42e7dSPeter Dunlap void
iscsit_rx_pdu(idm_conn_t * ic,idm_pdu_t * rx_pdu)902a6d42e7dSPeter Dunlap iscsit_rx_pdu(idm_conn_t *ic, idm_pdu_t *rx_pdu)
903a6d42e7dSPeter Dunlap {
904a6d42e7dSPeter Dunlap iscsit_conn_t *ict = ic->ic_handle;
905a6d42e7dSPeter Dunlap switch (IDM_PDU_OPCODE(rx_pdu)) {
906a6d42e7dSPeter Dunlap case ISCSI_OP_SCSI_CMD:
907a6d42e7dSPeter Dunlap ASSERT(0); /* Shouldn't happen */
908a6d42e7dSPeter Dunlap idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS);
909a6d42e7dSPeter Dunlap break;
910a6d42e7dSPeter Dunlap case ISCSI_OP_SNACK_CMD:
911a6d42e7dSPeter Dunlap /*
912a6d42e7dSPeter Dunlap * We'll need to handle this when we support ERL1/2. For
913a6d42e7dSPeter Dunlap * now we treat it as a protocol error.
914a6d42e7dSPeter Dunlap */
915a6d42e7dSPeter Dunlap idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS);
9161f99504aSToomas Soome idm_conn_event(ic, CE_TRANSPORT_FAIL, 0);
917a6d42e7dSPeter Dunlap break;
918a6d42e7dSPeter Dunlap case ISCSI_OP_SCSI_TASK_MGT_MSG:
919d618d68dSPriya Krishnan if (iscsit_check_cmdsn_and_queue(rx_pdu)) {
920d618d68dSPriya Krishnan iscsit_set_cmdsn(ict, rx_pdu);
921d618d68dSPriya Krishnan iscsit_op_scsi_task_mgmt(ict, rx_pdu);
922d618d68dSPriya Krishnan }
923a6d42e7dSPeter Dunlap break;
924a6d42e7dSPeter Dunlap case ISCSI_OP_NOOP_OUT:
925a6d42e7dSPeter Dunlap case ISCSI_OP_LOGIN_CMD:
926a6d42e7dSPeter Dunlap case ISCSI_OP_TEXT_CMD:
927a6d42e7dSPeter Dunlap case ISCSI_OP_LOGOUT_CMD:
928a6d42e7dSPeter Dunlap /*
929a6d42e7dSPeter Dunlap * If/when we switch to userland processing these PDU's
930a6d42e7dSPeter Dunlap * will be handled by iscsitd.
931a6d42e7dSPeter Dunlap */
932a6d42e7dSPeter Dunlap iscsit_deferred_dispatch(rx_pdu);
933a6d42e7dSPeter Dunlap break;
934a6d42e7dSPeter Dunlap default:
935a6d42e7dSPeter Dunlap /* Protocol error */
936a6d42e7dSPeter Dunlap idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS);
9371f99504aSToomas Soome idm_conn_event(ic, CE_TRANSPORT_FAIL, 0);
938a6d42e7dSPeter Dunlap break;
939a6d42e7dSPeter Dunlap }
940a6d42e7dSPeter Dunlap }
941a6d42e7dSPeter Dunlap
942a6d42e7dSPeter Dunlap /*ARGSUSED*/
943a6d42e7dSPeter Dunlap void
iscsit_rx_pdu_error(idm_conn_t * ic,idm_pdu_t * rx_pdu,idm_status_t status)944a6d42e7dSPeter Dunlap iscsit_rx_pdu_error(idm_conn_t *ic, idm_pdu_t *rx_pdu, idm_status_t status)
945a6d42e7dSPeter Dunlap {
946a6d42e7dSPeter Dunlap idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS);
947a6d42e7dSPeter Dunlap }
948a6d42e7dSPeter Dunlap
949a481fa48SRick McNeal /*
950a481fa48SRick McNeal * iscsit_rx_scsi_rsp -- cause the connection to be closed if response rx'd
951a481fa48SRick McNeal *
952a481fa48SRick McNeal * A target sends an SCSI Response PDU, it should never receive one.
953a481fa48SRick McNeal * This has been seen when running the Codemonicon suite of tests which
954a481fa48SRick McNeal * does negative testing of the protocol. If such a condition occurs using
955a481fa48SRick McNeal * a normal initiator it most likely means there's data corruption in the
956a481fa48SRick McNeal * header and that's grounds for dropping the connection as well.
957a481fa48SRick McNeal */
958a481fa48SRick McNeal void
iscsit_rx_scsi_rsp(idm_conn_t * ic,idm_pdu_t * rx_pdu)959a481fa48SRick McNeal iscsit_rx_scsi_rsp(idm_conn_t *ic, idm_pdu_t *rx_pdu)
960a481fa48SRick McNeal {
961a481fa48SRick McNeal idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS);
9621f99504aSToomas Soome idm_conn_event(ic, CE_TRANSPORT_FAIL, 0);
963a481fa48SRick McNeal }
964a481fa48SRick McNeal
965a6d42e7dSPeter Dunlap void
iscsit_task_aborted(idm_task_t * idt,idm_status_t status)966a6d42e7dSPeter Dunlap iscsit_task_aborted(idm_task_t *idt, idm_status_t status)
967a6d42e7dSPeter Dunlap {
968a6d42e7dSPeter Dunlap iscsit_task_t *itask = idt->idt_private;
969a6d42e7dSPeter Dunlap
970a6d42e7dSPeter Dunlap switch (status) {
971a6d42e7dSPeter Dunlap case IDM_STATUS_SUSPENDED:
972a6d42e7dSPeter Dunlap break;
973a6d42e7d