Home | History | Annotate | Download | only in iscsitgtd
      1 /*
      2  * CDDL HEADER START
      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 /*
     23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 /*
     28  * This file contains methods to handle the iSCSI Full Feature Phase aspects
     29  * of the protocol.
     30  */
     31 
     32 #include <unistd.h>
     33 #include <poll.h>
     34 #include <strings.h>
     35 #include <stdlib.h>
     36 #include <sys/types.h>
     37 #include <assert.h>
     38 #include <stdio.h>
     39 #include <errno.h>
     40 #include <utility.h>
     41 #include <netinet/in.h>
     42 #include <inttypes.h>
     43 #include <sys/socket.h>
     44 #include <sys/iscsi_protocol.h>
     45 
     46 #include <arpa/inet.h>
     47 
     48 #include "iscsi_ffp.h"
     49 #include "iscsi_cmd.h"
     50 #include "t10_spc.h"
     51 #include "utility.h"
     52 #include "iscsi_provider_impl.h"
     53 
     54 static Boolean_t handle_text_msg(iscsi_conn_t *, iscsi_hdr_t *, char *, int);
     55 static Boolean_t handle_logout_msg(iscsi_conn_t *, iscsi_hdr_t *, char *, int);
     56 static Boolean_t handle_scsi_cmd(iscsi_conn_t *, iscsi_hdr_t *, char *, int);
     57 static Boolean_t handle_noop_cmd(iscsi_conn_t *, iscsi_hdr_t *, char *, int);
     58 static Boolean_t handle_scsi_data(iscsi_conn_t *, iscsi_hdr_t *, char *, int);
     59 static Boolean_t handle_task_mgt(iscsi_conn_t *, iscsi_hdr_t *, char *, int);
     60 static Boolean_t dataout_delayed(iscsi_cmd_t *cmd, msg_type_t type);
     61 void dataout_callback(t10_cmd_t *t, char *data, size_t *xfer);
     62 
     63 Boolean_t
     64 iscsi_full_feature(iscsi_conn_t *c)
     65 {
     66 	iscsi_hdr_t	h;
     67 	Boolean_t	rval		= False;
     68 	char		debug[128];
     69 	char		*ahs		= NULL;
     70 	int		cc;
     71 	int		ahslen;
     72 
     73 	if ((cc = recv(c->c_fd, &h, sizeof (h), MSG_WAITALL)) != sizeof (h)) {
     74 		if (errno == ECONNRESET) {
     75 			(void) snprintf(debug, sizeof (debug),
     76 			    "CON%x  full_feature -- initiator reset socket\n",
     77 			    c->c_num);
     78 		} else {
     79 			(void) snprintf(debug, sizeof (debug),
     80 			    "CON%x full_feature(got-%d, expect-%d), errno=%d\n",
     81 			    c->c_num, cc, sizeof (h), errno);
     82 		}
     83 		queue_str(c->c_mgmtq, Q_CONN_ERRS, msg_log, debug);
     84 		conn_state(c, T8);
     85 		return (False);
     86 	}
     87 
     88 	/*
     89 	 * Look to see if there's an Additional Header Segment available.
     90 	 * If so, read it in.
     91 	 */
     92 	if ((ahslen = (h.hlength * sizeof (uint32_t))) != 0) {
     93 		if ((ahs = malloc(ahslen)) == NULL)
     94 			return (False);
     95 		if (recv(c->c_fd, ahs, ahslen, MSG_WAITALL) != ahslen) {
     96 			(void) snprintf(debug, sizeof (debug),
     97 			    "CON%x  Failed to read in AHS", c->c_num);
     98 			queue_str(c->c_mgmtq, Q_CONN_ERRS, msg_log, debug);
     99 			free(ahs);
    100 			return (False);
    101 		}
    102 	}
    103 
    104 	(void) pthread_mutex_lock(&c->c_state_mutex);
    105 	if (c->c_state != S5_LOGGED_IN && c->c_state != S7_LOGOUT_REQUESTED) {
    106 		(void) snprintf(debug, sizeof (debug),
    107 		    "CON%x  full_feature -- not in S5_LOGGED_IN state\n",
    108 		    c->c_num);
    109 		queue_str(c->c_mgmtq, Q_CONN_ERRS, msg_log, debug);
    110 		if (ahs != NULL)
    111 			free(ahs);
    112 		(void) pthread_mutex_unlock(&c->c_state_mutex);
    113 		return (False);
    114 	}
    115 	(void) pthread_mutex_unlock(&c->c_state_mutex);
    116 
    117 	if (c->c_header_digest == True) {
    118 		uint32_t	crc_actual;
    119 		uint32_t	crc_calculated;
    120 
    121 		(void) recv(c->c_fd, (char *)&crc_actual,
    122 		    sizeof (crc_actual), MSG_WAITALL);
    123 		crc_calculated = iscsi_crc32c((void *)&h, sizeof (h));
    124 		if (ahslen)
    125 			crc_calculated = iscsi_crc32c_continued(ahs,
    126 			    ahslen, crc_calculated);
    127 		if (crc_actual != crc_calculated) {
    128 			(void) snprintf(debug, sizeof (debug),
    129 			    "CON%x  CRC error: actual 0x%x v. calc 0x%x",
    130 			    c->c_num, crc_actual, crc_calculated);
    131 			queue_str(c->c_mgmtq, Q_CONN_ERRS, msg_log, debug);
    132 			if (ahs != NULL)
    133 				free(ahs);
    134 			return (False);
    135 		}
    136 	}
    137 
    138 	if (c->c_sess->s_type == SessionDiscovery) {
    139 		switch (h.opcode & ISCSI_OPCODE_MASK) {
    140 		default:
    141 			/*
    142 			 * Need to handle the error case here.
    143 			 */
    144 			(void) snprintf(debug, sizeof (debug),
    145 			    "CON%x  Wrong opcode for Discovery, %d",
    146 			    c->c_num, h.opcode & ISCSI_OPCODE_MASK);
    147 			queue_str(c->c_mgmtq, Q_CONN_ERRS, msg_log, debug);
    148 			rval = False;
    149 			break;
    150 
    151 		case ISCSI_OP_LOGOUT_CMD:
    152 			/*
    153 			 * This will transition from S5_LOGGED_IN
    154 			 * to S6_IN_LOGOUT to S1_FREE;
    155 			 */
    156 			rval = handle_logout_msg(c, &h, ahs, ahslen);
    157 			break;
    158 
    159 		case ISCSI_OP_TEXT_CMD:
    160 			rval = handle_text_msg(c, &h, ahs, ahslen);
    161 			break;
    162 		}
    163 	} else {
    164 		iscsi_cmd_remove(c, ntohl(h.expstatsn));
    165 		switch (h.opcode & ISCSI_OPCODE_MASK) {
    166 		case ISCSI_OP_NOOP_OUT:
    167 			rval = handle_noop_cmd(c, &h, ahs, ahslen);
    168 			break;
    169 
    170 		case ISCSI_OP_SCSI_CMD:
    171 			rval = handle_scsi_cmd(c, &h, ahs, ahslen);
    172 			break;
    173 
    174 		case ISCSI_OP_SCSI_TASK_MGT_MSG:
    175 			rval = handle_task_mgt(c, &h, ahs, ahslen);
    176 			break;
    177 
    178 		case ISCSI_OP_LOGIN_CMD:
    179 			/*
    180 			 * This is an illegal state transition. Should
    181 			 * we drop the connection?
    182 			 */
    183 			break;
    184 
    185 		case ISCSI_OP_TEXT_CMD:
    186 			rval = handle_text_msg(c, &h, ahs, ahslen);
    187 			break;
    188 
    189 		case ISCSI_OP_SCSI_DATA:
    190 			rval = handle_scsi_data(c, &h, ahs, ahslen);
    191 			break;
    192 
    193 		case ISCSI_OP_LOGOUT_CMD:
    194 			/*
    195 			 * This will transition from S5_LOGGED_IN
    196 			 * to S6_IN_LOGOUT.
    197 			 */
    198 			rval = handle_logout_msg(c, &h, ahs, ahslen);
    199 			break;
    200 
    201 		case ISCSI_OP_SNACK_CMD:
    202 		default:
    203 			(void) snprintf(debug, sizeof (debug),
    204 			    "CON%x  Opcode: %d not handled",
    205 			    c->c_num, h.opcode & ISCSI_OPCODE_MASK);
    206 			queue_str(c->c_mgmtq, Q_CONN_ERRS, msg_log, debug);
    207 			conn_state(c, T8);
    208 			rval = True;
    209 			break;
    210 		}
    211 	}
    212 
    213 	if (ahs != NULL)
    214 		free(ahs);
    215 	return (rval);
    216 }
    217 
    218 /*ARGSUSED*/
    219 static Boolean_t
    220 handle_task_mgt(iscsi_conn_t *c, iscsi_hdr_t *p, char *ahs, int ahslen)
    221 {
    222 	iscsi_scsi_task_mgt_hdr_t	*hp = (iscsi_scsi_task_mgt_hdr_t *)p;
    223 	iscsi_scsi_task_mgt_rsp_hdr_t	*rsp;
    224 	iscsi_cmd_t			*cmd;
    225 	uint32_t			lun;
    226 	Boolean_t			lu_reset	= False;
    227 
    228 	if (spc_decode_lu_addr(&hp->lun[0], 8, &lun) == False)
    229 		return (False);
    230 
    231 	if (ISCSI_TASK_COMMAND_ENABLED()) {
    232 		uiscsiproto_t info;
    233 
    234 		info.uip_target_addr = &c->c_target_sockaddr;
    235 		info.uip_initiator_addr = &c->c_initiator_sockaddr;
    236 
    237 		info.uip_target = c->c_sess->s_t_name;
    238 		info.uip_initiator = c->c_sess->s_i_name;
    239 		info.uip_lun = lun;
    240 
    241 		info.uip_itt = hp->itt;
    242 		info.uip_ttt = hp->itt;
    243 
    244 		info.uip_cmdsn = ntohl(hp->cmdsn);
    245 		info.uip_statsn = ntohl(hp->expstatsn);
    246 		info.uip_datasn = ntohl(hp->expdatasn);
    247 
    248 		info.uip_datalen = ntoh24(hp->dlength);
    249 		info.uip_flags = 0;
    250 
    251 		ISCSI_TASK_COMMAND(&info);
    252 	}
    253 
    254 	if ((rsp = calloc(1, sizeof (*rsp))) == NULL)
    255 		return (False);
    256 
    257 	rsp->opcode	= ISCSI_OP_SCSI_TASK_MGT_RSP;
    258 	rsp->flags	= ISCSI_FLAG_FINAL;
    259 	rsp->itt	= hp->itt;
    260 
    261 	(void) pthread_mutex_lock(&c->c_mutex);
    262 	rsp->statsn	= htonl(c->c_statsn++);
    263 	(void) pthread_mutex_unlock(&c->c_mutex);
    264 
    265 	(void) pthread_mutex_lock(&c->c_sess->s_mutex);
    266 	if (ntohl(hp->cmdsn) > c->c_sess->s_seencmdsn)
    267 		c->c_sess->s_seencmdsn = ntohl(hp->cmdsn);
    268 	(void) pthread_mutex_unlock(&c->c_sess->s_mutex);
    269 
    270 	queue_prt(c->c_mgmtq, Q_CONN_NONIO,
    271 	    "CON%x  PDU(Task Mgt): %s, cmdsn 0x%x\n",
    272 	    c->c_num,
    273 	    task_to_str(hp->function & ISCSI_FLAG_TASK_MGMT_FUNCTION_MASK),
    274 	    ntohl(hp->cmdsn));
    275 
    276 	switch (hp->function & ISCSI_FLAG_TASK_MGMT_FUNCTION_MASK) {
    277 	case ISCSI_TM_FUNC_ABORT_TASK:
    278 		queue_prt(c->c_mgmtq, Q_CONN_NONIO,
    279 		    "CON%x  Abort ITT 0x%x\n", c->c_num, hp->rtt);
    280 		if ((cmd = iscsi_cmd_find(c, hp->rtt, FindITT)) == NULL) {
    281 			queue_prt(c->c_mgmtq, Q_CONN_ERRS,
    282 			    "CON%x  Invalid AbortTask rtt 0x%x\n",
    283 			    c->c_num, hp->rtt);
    284 			rsp->response = SCSI_TCP_TM_RESP_NO_TASK;
    285 		} else {
    286 			(void) pthread_mutex_lock(&c->c_mutex);
    287 			iscsi_cmd_cancel(c, cmd);
    288 			(void) pthread_mutex_unlock(&c->c_mutex);
    289 			rsp->response = SCSI_TCP_TM_RESP_COMPLETE;
    290 		}
    291 		break;
    292 
    293 	case ISCSI_TM_FUNC_ABORT_TASK_SET:
    294 		/* ---- This is actually "Function not support" ---- */
    295 		rsp->response = SCSI_TCP_TM_RESP_IN_PRGRESS;
    296 		break;
    297 
    298 	case ISCSI_TM_FUNC_CLEAR_ACA:
    299 		/* ---- This is actually "Function not support" ---- */
    300 		rsp->response = SCSI_TCP_TM_RESP_IN_PRGRESS;
    301 		break;
    302 
    303 	case ISCSI_TM_FUNC_CLEAR_TASK_SET:
    304 		/* ---- This is actually "Function not support" ---- */
    305 		rsp->response = SCSI_TCP_TM_RESP_IN_PRGRESS;
    306 		break;
    307 
    308 	case ISCSI_TM_FUNC_LOGICAL_UNIT_RESET:
    309 		lu_reset	= True;
    310 	/*FALLTHRU*/
    311 	case ISCSI_TM_FUNC_TARGET_WARM_RESET:
    312 		(void) pthread_mutex_lock(&c->c_mutex);
    313 		for (cmd = c->c_cmd_head; cmd; cmd = cmd->c_next) {
    314 			if (((hp->function &
    315 			    ISCSI_FLAG_TASK_MGMT_FUNCTION_MASK) ==
    316 			    ISCSI_TM_FUNC_TARGET_WARM_RESET) ||
    317 			    (lun == cmd->c_lun)) {
    318 				iscsi_cmd_cancel(c, cmd);
    319 
    320 			}
    321 		}
    322 		(void) pthread_mutex_unlock(&c->c_mutex);
    323 
    324 		if (lu_reset == True)
    325 			queue_message_set(c->c_sessq, 0, msg_reset_lu,
    326 			    (void *)(uintptr_t)lun);
    327 		else
    328 			queue_message_set(c->c_sessq, 0, msg_reset_targ, 0);
    329 		rsp->response = SCSI_TCP_TM_RESP_COMPLETE;
    330 		break;
    331 
    332 	case ISCSI_TM_FUNC_TARGET_COLD_RESET:
    333 		/*
    334 		 * According to the specification a cold reset should
    335 		 * close *all* connections on the target, not just those
    336 		 * for this current session.
    337 		 */
    338 		queue_message_set(c->c_sessq, 0, msg_reset_targ, (void *)1);
    339 		conn_state(c, T8);
    340 		break;
    341 
    342 	case ISCSI_TM_FUNC_TASK_REASSIGN:
    343 	default:
    344 		/* ---- This is actually "Function not support" ---- */
    345 		rsp->response = SCSI_TCP_TM_RESP_IN_PRGRESS;
    346 		break;
    347 	}
    348 
    349 	(void) pthread_mutex_lock(&c->c_state_mutex);
    350 	if (c->c_state == S5_LOGGED_IN)
    351 		queue_message_set(c->c_dataq,
    352 		    hp->opcode & ISCSI_OP_IMMEDIATE ? Q_HIGH : 0,
    353 		    msg_send_pkt, rsp);
    354 	(void) pthread_mutex_unlock(&c->c_state_mutex);
    355 	return (True);
    356 }
    357 
    358 /*ARGSUSED*/
    359 static Boolean_t
    360 handle_noop_cmd(iscsi_conn_t *c, iscsi_hdr_t *p, char *ahs, int ahslen)
    361 {
    362 	iscsi_nop_out_hdr_t	*hp = (iscsi_nop_out_hdr_t *)p;
    363 	iscsi_nop_in_hdr_t	*in;
    364 
    365 	if (ISCSI_NOP_RECEIVE_ENABLED()) {
    366 		uiscsiproto_t info;
    367 
    368 		info.uip_target_addr = &c->c_target_sockaddr;
    369 		info.uip_initiator_addr = &c->c_initiator_sockaddr;
    370 
    371 		info.uip_target = c->c_sess->s_t_name;
    372 		info.uip_initiator = c->c_sess->s_i_name;
    373 		info.uip_lun = 0;
    374 
    375 		info.uip_itt = hp->itt;
    376 		info.uip_ttt = hp->ttt;
    377 
    378 		info.uip_cmdsn = ntohl(hp->cmdsn);
    379 		info.uip_statsn = ntohl(hp->expstatsn);
    380 		info.uip_datasn = 0;
    381 
    382 		info.uip_datalen = ntoh24(hp->dlength);
    383 		info.uip_flags = hp->flags;
    384 
    385 		ISCSI_NOP_RECEIVE(&info);
    386 	}
    387 
    388 	/*
    389 	 * Just an answer to our ping
    390 	 */
    391 	if (hp->ttt != ISCSI_RSVD_TASK_TAG)
    392 		return (True);
    393 
    394 	if ((in = calloc(1, sizeof (*in))) == NULL) {
    395 		queue_prt(c->c_mgmtq, Q_CONN_ERRS,
    396 		    "CON%x  NopIn -- failed to malloc space for header",
    397 		    c->c_num);
    398 		return (False);
    399 	}
    400 
    401 	in->opcode = ISCSI_OP_NOOP_IN;
    402 	in->flags = ISCSI_FLAG_FINAL;
    403 	/*
    404 	 * Need to handle possible data associated with NOP-Out
    405 	 */
    406 	bcopy(hp->lun, in->lun, 8);
    407 	in->itt		= hp->itt;
    408 	in->ttt		= ISCSI_RSVD_TASK_TAG;
    409 	(void) pthread_mutex_lock(&c->c_sess->s_mutex);
    410 	if (ntohl(hp->cmdsn) > c->c_sess->s_seencmdsn)
    411 		c->c_sess->s_seencmdsn = ntohl(hp->cmdsn);
    412 	(void) pthread_mutex_unlock(&c->c_sess->s_mutex);
    413 
    414 	(void) pthread_mutex_lock(&c->c_state_mutex);
    415 	if (c->c_state == S5_LOGGED_IN)
    416 		queue_message_set(c->c_dataq,
    417 		    hp->opcode & ISCSI_OP_IMMEDIATE ? Q_HIGH : 0,
    418 		    msg_send_pkt, in);
    419 	(void) pthread_mutex_unlock(&c->c_state_mutex);
    420 	return (True);
    421 }
    422 
    423 /*ARGSUSED*/
    424 static Boolean_t
    425 handle_scsi_data(iscsi_conn_t *c, iscsi_hdr_t *p, char *ahs, int ahslen)
    426 {
    427 	iscsi_data_hdr_t	*hp = (iscsi_data_hdr_t *)p;
    428 	int			dlen = ntoh24(hp->dlength);
    429 	iscsi_cmd_t		*cmd;
    430 
    431 	if (ISCSI_DATA_RECEIVE_ENABLED()) {
    432 		uiscsiproto_t info;
    433 
    434 		info.uip_target_addr = &c->c_target_sockaddr;
    435 		info.uip_initiator_addr = &c->c_initiator_sockaddr;
    436 
    437 		info.uip_target = c->c_sess->s_t_name;
    438 		info.uip_initiator = c->c_sess->s_i_name;
    439 		info.uip_lun = 0;
    440 
    441 		info.uip_itt = hp->itt;
    442 		info.uip_ttt = hp->itt;
    443 
    444 		info.uip_cmdsn = 0;
    445 		info.uip_statsn = ntohl(hp->expstatsn);
    446 		info.uip_datasn = ntohl(hp->datasn);
    447 
    448 		info.uip_datalen = dlen;
    449 		info.uip_flags = hp->flags;
    450 
    451 		ISCSI_DATA_RECEIVE(&info);
    452 	}
    453 
    454 	if ((cmd = iscsi_cmd_find(c, hp->ttt, FindTTT)) == NULL) {
    455 		queue_prt(c->c_mgmtq, Q_CONN_ERRS,
    456 		    "CON%x  failed to find ttt 0x%x\n", c->c_num, hp->ttt);
    457 		/*
    458 		 * Need to handle error case.
    459 		 */
    460 		return (False);
    461 	}
    462 	cmd->c_opcode = hp->opcode & ISCSI_OPCODE_MASK;
    463 
    464 	/*
    465 	 * assert(cmd->c_lun == hp->lun[1]);
    466 	 * Previously this check was done, but is caused a problem with
    467 	 * the RedHat initiator. There was a discussion on the IPS alias
    468 	 * around this very topic. Even though section 10.7.4 states:
    469 	 *    "If the Target Transfer Tag is provided, then the LUN field
    470 	 *    MUST hold a valid value and be consistent with whatever was
    471 	 *    specified with the command; otherwise, the LUN field is
    472 	 *    reserved."
    473 	 * Everyone agreed though that for a DataOut command the LUN field
    474 	 * wasn't required to be valid because the TTT gives the Target
    475 	 * enough information to complete the command.
    476 	 */
    477 	assert(cmd->c_allegiance == c);
    478 	assert(cmd->c_itt == hp->itt);
    479 
    480 	cmd->c_offset_out	= ntohl(hp->offset);
    481 	cmd->c_data_len		= dlen;
    482 	(void) pthread_mutex_lock(&c->c_mutex);
    483 	(void) pthread_mutex_lock(&c->c_state_mutex);
    484 	if (c->c_state == S5_LOGGED_IN) {
    485 		if (cmd->c_state != CmdCanceled) {
    486 			t10_cmd_shoot_event(cmd->c_t10_cmd, T10_Cmd_T4);
    487 		}
    488 	}
    489 	(void) pthread_mutex_unlock(&c->c_state_mutex);
    490 	(void) pthread_mutex_unlock(&c->c_mutex);
    491 
    492 #ifdef FULL_DEBUG
    493 	queue_prt(c->c_mgmtq, Q_CONN_IO,
    494 	    "CON%x  PDU(DataOut) TTT 0x%x, offset=0x%x, len=0x%x\n",
    495 	    c->c_num, cmd->c_ttt, cmd->c_t10_cmd->c_offset, dlen);
    496 #endif
    497 
    498 	return (dataout_delayed(cmd, msg_cmd_data_out));
    499 }
    500 
    501 static Boolean_t
    502 handle_scsi_cmd(iscsi_conn_t *c, iscsi_hdr_t *p, char *ahs, int ahslen)
    503 {
    504 	iscsi_scsi_cmd_hdr_t	*hp	= (iscsi_scsi_cmd_hdr_t *)p;
    505 	int			dlen	= ntoh24(hp->dlength);
    506 	iscsi_cmd_t		*cmd;
    507 
    508 	(void) pthread_mutex_lock(&c->c_sess->s_mutex);
    509 	if (ntohl(hp->cmdsn) > c->c_sess->s_seencmdsn)
    510 		c->c_sess->s_seencmdsn = ntohl(hp->cmdsn);
    511 	(void) pthread_mutex_unlock(&c->c_sess->s_mutex);
    512 
    513 	if ((cmd = iscsi_cmd_alloc(c, hp->opcode & ISCSI_OPCODE_MASK)) == NULL)
    514 		return (False);
    515 
    516 	bcopy(hp->scb, cmd->c_scb_default, sizeof (cmd->c_scb_default));
    517 	cmd->c_scb	= cmd->c_scb_default;
    518 	cmd->c_scb_len	= sizeof (cmd->c_scb_default);
    519 	cmd->c_data_len	= dlen;
    520 
    521 	if (ahslen) {
    522 
    523 		/*
    524 		 * Additional Header Section ----
    525 		 *
    526 		 * For Object Storage Devices the SCB is quite large. On
    527 		 * the order of 140 bytes which means the data must be
    528 		 * found in the AHS.
    529 		 */
    530 		uint16_t	hslen;
    531 		uint16_t	next_seg;
    532 		uint8_t		hstyp;
    533 
    534 		do {
    535 			/*
    536 			 * Find this header segment's length and type
    537 			 */
    538 			bcopy(ahs, &hslen, sizeof (hslen));
    539 			hslen = ntohs(hslen);
    540 			hstyp = ahs[2];
    541 
    542 			switch (hstyp) {
    543 			/* ---- Extended CDB ---- */
    544 			case 1:
    545 				/*
    546 				 * The hslen accounts for the reserved
    547 				 * data byte in the segment. So the first
    548 				 * sixteen bytes are in hp->scb with the
    549 				 * remainder here. By only adding 15 bytes
    550 				 * we allocate the correct amount of space
    551 				 */
    552 				cmd->c_scb_extended = malloc(hslen + 15);
    553 				cmd->c_scb_len = hslen + 15;
    554 				if (cmd->c_scb_extended == NULL)
    555 					return (False);
    556 
    557 				/*
    558 				 * First 16 bytes of extended SCB are
    559 				 * found in the normal location.
    560 				 */
    561 				bcopy(hp->scb, cmd->c_scb_extended, 16);
    562 				bcopy(&ahs[4], &cmd->c_scb_extended[16],
    563 				    hslen - 16);
    564 				cmd->c_scb = cmd->c_scb_extended;
    565 				break;
    566 
    567 			/* ---- Expected bidirectional read data len ---- */
    568 			case 2:
    569 				/*
    570 				 * We shouldn't need this since we're
    571 				 * not prealloc'ing resources. If that should
    572 				 * change or the need for error checking
    573 				 * here's the spot to locate the data.
    574 				 */
    575 				break;
    576 			}
    577 
    578 			/*
    579 			 * hslen contains the effective length in bytes of
    580 			 * segment, excluding type and length (not including
    581 			 * padding). Each segment is padded to a 4 byte
    582 			 * boundary.
    583 			 */
    584 			next_seg = ((hslen + sizeof (hslen) +
    585 			    sizeof (hstyp) + 3) & ~3);
    586 			ahs += next_seg;
    587 			ahslen -= next_seg;
    588 
    589 		} while (ahslen);
    590 	}
    591 
    592 	/*
    593 	 * XXX Need to handle error case better.
    594 	 */
    595 	if (spc_decode_lu_addr(&hp->lun[0], sizeof (hp->lun), &cmd->c_lun) ==
    596 	    False) {
    597 		return (False);
    598 	}
    599 
    600 	if (ISCSI_SCSI_COMMAND_ENABLED()) {
    601 		uiscsiproto_t info;
    602 		uiscsicmd_t uc;
    603 
    604 		info.uip_target_addr = &c->c_target_sockaddr;
    605 		info.uip_initiator_addr = &c->c_initiator_sockaddr;
    606 
    607 		info.uip_target = c->c_sess->s_t_name;
    608 		info.uip_initiator = c->c_sess->s_i_name;
    609 		info.uip_lun = cmd->c_lun;
    610 
    611 		info.uip_itt = hp->itt;
    612 		info.uip_ttt = ISCSI_RSVD_TASK_TAG;
    613 
    614 		info.uip_cmdsn = ntohl(hp->cmdsn);
    615 		info.uip_statsn = ntohl(hp->expstatsn);
    616 		info.uip_datasn = 0;
    617 
    618 		info.uip_datalen = dlen;
    619 		info.uip_flags = hp->flags;
    620 
    621 		uc.uic_len = cmd->c_scb_len;
    622 		uc.uic_cdb = cmd->c_scb;
    623 
    624 		ISCSI_SCSI_COMMAND(&info, &uc);
    625 	}
    626 
    627 	cmd->c_itt		= hp->itt;
    628 	cmd->c_cmdsn		= ntohl(hp->cmdsn);
    629 	cmd->c_dlen_expected	= ntohl(hp->data_length);
    630 	cmd->c_writeop		= hp->flags & ISCSI_FLAG_CMD_WRITE ?
    631 	    True : False;
    632 
    633 #ifdef FULL_DEBUG
    634 	queue_prt(c->c_mgmtq, Q_CONN_IO,
    635 	    "CON%x  PDU(SCSI Cmd, TA=%d) CmdSN 0x%x ITT 0x%x TTT 0x%x "
    636 	    "LUN[%02x] id=%p\n", c->c_num,
    637 	    hp->flags & ISCSI_FLAG_CMD_ATTR_MASK, cmd->c_cmdsn, cmd->c_itt,
    638 	    cmd->c_ttt, cmd->c_lun, cmd);
    639 #endif
    640 
    641 	if (dlen && (hp->flags & ISCSI_FLAG_CMD_WRITE)) {
    642 		/*
    643 		 * NOTE: This should only occur if ImmediateData==Yes.
    644 		 * We can handle this even if the initiator violates
    645 		 * the specification so no need to worry. Use the rule
    646 		 * of "Be strict in what is sent, but lenient in what
    647 		 * is accepted."
    648 		 */
    649 		return (dataout_delayed(cmd, msg_cmd_send));
    650 	} else {
    651 		(void) pthread_mutex_lock(&c->c_state_mutex);
    652 		if (c->c_state == S5_LOGGED_IN)
    653 			queue_message_set(c->c_sessq, 0,
    654 			    msg_cmd_send, (void *)cmd);
    655 		(void) pthread_mutex_unlock(&c->c_state_mutex);
    656 		return (True);
    657 	}
    658 }
    659 
    660 /*
    661  * []----
    662  * | handle_text_msg -- process incoming test parameters
    663  * |
    664  * | NOTE: Need to handle continuation packets sent by the initiator.
    665  * []----
    666  */
    667 /*ARGSUSED*/
    668 static Boolean_t
    669 handle_text_msg(iscsi_conn_t *c, iscsi_hdr_t *p, char *ahs, int ahslen)
    670 {
    671 	iscsi_text_rsp_hdr_t	rsp;
    672 	iscsi_text_hdr_t	*hp		= (iscsi_text_hdr_t *)p;
    673 	char			*text		= NULL;
    674 	int			text_length	= 0;
    675 	Boolean_t		release_at_end	= False;
    676 	int			dlen		= ntoh24(hp->dlength);
    677 
    678 	if (ISCSI_TEXT_COMMAND_ENABLED()) {
    679 		uiscsiproto_t info;
    680 		char nil = '\0';
    681 
    682 		info.uip_initiator = c->c_sess->s_i_name;
    683 		info.uip_target_addr = &c->c_target_sockaddr;
    684 		info.uip_initiator_addr = &c->c_initiator_sockaddr;
    685 
    686 		info.uip_target = c->c_sess->s_t_name;
    687 		info.uip_initiator = c->c_sess->s_i_name;
    688 		info.uip_target = &nil;
    689 		info.uip_lun = 0;
    690 
    691 		info.uip_itt = hp->itt;
    692 		info.uip_ttt = hp->ttt;
    693 
    694 		info.uip_cmdsn = ntohl(hp->cmdsn);
    695 		info.uip_statsn = ntohl(hp->expstatsn);
    696 		info.uip_datasn = 0;
    697 
    698 		info.uip_datalen = dlen;
    699 		info.uip_flags = hp->flags;
    700 
    701 		ISCSI_TEXT_COMMAND(&info);
    702 	}
    703 
    704 	bzero(&rsp, sizeof (rsp));
    705 	rsp.opcode	= ISCSI_OP_TEXT_RSP;
    706 	rsp.itt		= hp->itt;
    707 
    708 	queue_prt(c->c_mgmtq, Q_CONN_NONIO, "CON%x  PDU(Text Message)\n",
    709 	    c->c_num);
    710 
    711 	/*
    712 	 * Need to determine if this incoming text PDU is an initial message
    713 	 * or a continuation.
    714 	 */
    715 	if (hp->ttt == ISCSI_RSVD_TASK_TAG) {
    716 
    717 		/* ---- Initial text PDU, so parse the incoming data ---- */
    718 		if (parse_text(c, dlen, &text, &text_length, NULL) == False) {
    719 			queue_prt(c->c_mgmtq, Q_CONN_ERRS,
    720 			    "Failed to parse Text\n");
    721 			if (text) {
    722 				/*
    723 				 * It's possible that we started to create
    724 				 * a response, but yet an error occurred.
    725 				 * Release the partial text response if that
    726 				 * occurred.
    727 				 */
    728 				free(text);
    729 			}
    730 			return (False);
    731 		}
    732 
    733 		/*
    734 		 * 10.11.4 --
    735 		 * When the target receives a Text Request with the Target
    736 		 * Transfer Tag set to the reserved value of 0xffffffff, it
    737 		 * resets its internal information (resets state) associated
    738 		 * with the given Initiator Task Tag (restarts the negotiation).
    739 		 */
    740 		if (c->c_text_area != NULL)
    741 			free(c->c_text_area);
    742 
    743 		c->c_text_area = text;
    744 		if (text_length > c->c_max_recv_data) {
    745 
    746 			/*
    747 			 * Too much data to send at once, break it up into
    748 			 * multiple transfers.
    749 			 */
    750 			rsp.flags	= ISCSI_FLAG_TEXT_CONTINUE;
    751 			rsp.ttt		= 1;
    752 			c->c_text_len	= text_length;
    753 			text_length	= c->c_max_recv_data;
    754 			c->c_text_sent	= text_length;
    755 		} else {
    756 			rsp.flags	= ISCSI_FLAG_FINAL;
    757 			rsp.ttt		= ISCSI_RSVD_TASK_TAG;
    758 			release_at_end	= True;
    759 		}
    760 	} else {
    761 
    762 		/* ---- Continuation of previous text request ---- */
    763 		text_length	= c->c_text_len - c->c_text_sent;
    764 		text		= c->c_text_area + c->c_text_sent;
    765 		if (text_length > c->c_max_recv_data) {
    766 			rsp.flags	= ISCSI_FLAG_TEXT_CONTINUE;
    767 			rsp.ttt		= 1;
    768 			text_length	= c->c_max_recv_data;
    769 			c->c_text_sent	+= text_length;
    770 		} else {
    771 			rsp.flags	= ISCSI_FLAG_FINAL;
    772 			rsp.ttt		= ISCSI_RSVD_TASK_TAG;
    773 			release_at_end	= True;
    774 		}
    775 	}
    776 
    777 	queue_prt(c->c_mgmtq, Q_CONN_NONIO,
    778 	    "CON%x  Text PDU: flags=0x%02x, ttt=0x%08x, len=%d\n",
    779 	    c->c_num, rsp.flags, rsp.ttt, text_length);
    780 
    781 	hton24(rsp.dlength, text_length);
    782 	(void) pthread_mutex_lock(&c->c_mutex);
    783 	rsp.statsn	= htonl(c->c_statsn++);
    784 	(void) pthread_mutex_lock(&c->c_sess->s_mutex);
    785 	if (ntohl(hp->cmdsn) > c->c_sess->s_seencmdsn)
    786 		c->c_sess->s_seencmdsn = ntohl(hp->cmdsn);
    787 	rsp.maxcmdsn	= htonl(iscsi_cmd_window(c) + c->c_sess->s_seencmdsn);
    788 	rsp.expcmdsn	= htonl(c->c_sess->s_seencmdsn + 1);
    789 	(void) pthread_mutex_unlock(&c->c_sess->s_mutex);
    790 	(void) pthread_mutex_unlock(&c->c_mutex);
    791 
    792 	if (ISCSI_TEXT_RESPONSE_ENABLED()) {
    793 		uiscsiproto_t info;
    794 		char nil = '\0';
    795 
    796 		info.uip_target_addr = &c->c_target_sockaddr;
    797 		info.uip_initiator_addr = &c->c_initiator_sockaddr;
    798 
    799 		info.uip_target = c->c_sess->s_t_name;
    800 		info.uip_initiator = c->c_sess->s_i_name;
    801 		info.uip_initiator = c->c_sess->s_i_name;
    802 		info.uip_target = &nil;
    803 		info.uip_lun = 0;
    804 
    805 		info.uip_itt = rsp.itt;
    806 		info.uip_ttt = rsp.ttt;
    807 
    808 		info.uip_cmdsn = ntohl(rsp.expcmdsn);
    809 		info.uip_statsn = ntohl(rsp.statsn);
    810 		info.uip_datasn = 0;
    811 
    812 		info.uip_datalen = text_length;
    813 		info.uip_flags = rsp.flags;
    814 
    815 		ISCSI_TEXT_RESPONSE(&info);
    816 	}
    817 
    818 	send_iscsi_pkt(c, (iscsi_hdr_t *)&rsp, text);
    819 
    820 	if (release_at_end == True) {
    821 		free(c->c_text_area);
    822 		c->c_text_area = NULL;
    823 	}
    824 	return (True);
    825 }
    826 
    827 /*ARGSUSED*/
    828 static Boolean_t
    829 handle_logout_msg(iscsi_conn_t *c, iscsi_hdr_t *p, char *ahs, int ahslen)
    830 {
    831 	iscsi_logout_rsp_hdr_t	*rsp;
    832 	iscsi_logout_hdr_t	*hp = (iscsi_logout_hdr_t *)p;
    833 	char			debug[80];
    834 
    835 	if (ISCSI_LOGOUT_COMMAND_ENABLED()) {
    836 		uiscsiproto_t info;
    837 		char nil = '\0';
    838 
    839 		info.uip_target_addr = &c->c_target_sockaddr;
    840 		info.uip_initiator_addr = &c->c_initiator_sockaddr;
    841 
    842 		info.uip_target = c->c_sess->s_t_name;
    843 		info.uip_initiator = c->c_sess->s_i_name;
    844 		info.uip_initiator = c->c_sess->s_i_name;
    845 		info.uip_target = &nil;
    846 		info.uip_lun = 0;
    847 
    848 		info.uip_itt = hp->itt;
    849 		info.uip_ttt = ISCSI_RSVD_TASK_TAG;
    850 
    851 		info.uip_cmdsn = ntohl(hp->cmdsn);
    852 		info.uip_statsn = ntohl(hp->expstatsn);
    853 		info.uip_datasn = 0;
    854 
    855 		info.uip_datalen = ntoh24(hp->dlength);
    856 		info.uip_flags = hp->flags;
    857 
    858 		ISCSI_LOGOUT_COMMAND(&info);
    859 	}
    860 
    861 	if ((rsp = calloc(1, sizeof (*rsp))) == NULL)
    862 		return (False);
    863 
    864 	(void) snprintf(debug, sizeof (debug),
    865 	    "CON%x  PDU(Logout Request)", c->c_num);
    866 	queue_str(c->c_mgmtq, Q_CONN_NONIO, msg_log, debug);
    867 
    868 	(void) pthread_mutex_lock(&c->c_mutex);
    869 	(void) pthread_mutex_lock(&c->c_sess->s_mutex);
    870 	if (hp->cmdsn > c->c_sess->s_seencmdsn)
    871 		c->c_sess->s_seencmdsn = htonl(hp->cmdsn);
    872 	rsp->expcmdsn = htonl(c->c_sess->s_seencmdsn + 1);
    873 	rsp->maxcmdsn = htonl(iscsi_cmd_window(c) +
    874 	    c->c_sess->s_seencmdsn);
    875 	(void) pthread_mutex_unlock(&c->c_sess->s_mutex);
    876 	(void) pthread_mutex_unlock(&c->c_mutex);
    877 
    878 	rsp->opcode	= ISCSI_OP_LOGOUT_RSP;
    879 	rsp->flags	= ISCSI_FLAG_FINAL;
    880 	rsp->itt	= hp->itt;
    881 	(void) pthread_mutex_lock(&c->c_mutex);
    882 	rsp->statsn	= htonl(c->c_statsn++);
    883 	(void) pthread_mutex_unlock(&c->c_mutex);
    884 
    885 	c->c_last_pkg	= (iscsi_hdr_t *)rsp;
    886 
    887 	/*
    888 	 * Call the state transition last. This will send out
    889 	 * an asynchronous message to shutdown the session and STE.
    890 	 * Once that's complete a shutdown reply will be sent to
    891 	 * the transmit connection thread. That will cause another
    892 	 * transition to T13 which expects to send out this logout
    893 	 * response.
    894 	 */
    895 	if (c->c_state == S7_LOGOUT_REQUESTED)
    896 		conn_state(c, T10);
    897 	else
    898 		conn_state(c, T9);
    899 
    900 	return (True);
    901 }
    902 
    903 /*
    904  * dataout_delayed -- possibly copy data from initiator
    905  *
    906  * If DataDigests are enabled copy the data from the socket into a buffer
    907  * and perform the CRC check now.
    908  *
    909  * If MaxConnections==1 don't copy the data now and wait until the STE is
    910  * ready to copy the data directly from the socket to it's final location.
    911  * This is extremely beneficial when using mmap'd data.
    912  * NOTE:
    913  *    (1) For this to work we must not use the queues and instead
    914  *        call the STE functions directly. If the queues are used
    915  *        this routine must pause until STE processes the data to
    916  *        prevent this thread from attempting to read data from
    917  *        the socket as if it's the next PDU header.
    918  *    (2) Currently we don't call STE directly. To prevent a performance
    919  *        issue we'll have the code in place to support calling
    920  *        STE directly, but any time MaxConnections is greater than 0
    921  *        we'll copy the buffer. This will be removed at some future
    922  *        point.
    923  */
    924 static Boolean_t
    925 dataout_delayed(iscsi_cmd_t *cmd, msg_type_t type)
    926 {
    927 	iscsi_conn_t	*c	= cmd->c_allegiance;
    928 	int		dlen	= cmd->c_data_len;
    929 	int		cc;
    930 	uint32_t	crc_calc;
    931 	uint32_t	crc_actual;
    932 	char		pad_buf[ISCSI_PAD_WORD_LEN - 1];
    933 	char		pad_len;
    934 	char		debug[80];
    935 
    936 	cmd->c_dataout_cb = dataout_callback;
    937 
    938 	if (cmd->c_data == NULL) {
    939 		if ((cmd->c_data = (char *)malloc(dlen)) == NULL) {
    940 			(void) pthread_mutex_lock(&c->c_mutex);
    941 			t10_cmd_shoot_event(cmd->c_t10_cmd, T10_Cmd_T5);
    942 			iscsi_cmd_free(c, cmd);
    943 			(void) pthread_mutex_unlock(&c->c_mutex);
    944 			return (False);
    945 		}
    946 		cmd->c_data_alloc = True;
    947 	}
    948 
    949 	if ((cc = recv(c->c_fd, cmd->c_data, dlen, MSG_WAITALL)) != dlen) {
    950 		if (errno == ECONNRESET) {
    951 			queue_prt(c->c_mgmtq, Q_CONN_ERRS,
    952 			    "CON%x  dataout_delayed -- "
    953 			    "initiator reset socket\n", c->c_num);
    954 		} else {
    955 			queue_prt(c->c_mgmtq, Q_CONN_ERRS,
    956 			    "CON%x  recv(got-%d, expect-%d), errno=%d\n",
    957 			    c->c_num, cc, dlen, errno);
    958 		}
    959 
    960 		(void) pthread_mutex_lock(&c->c_mutex);
    961 		t10_cmd_shoot_event(cmd->c_t10_cmd, T10_Cmd_T5);
    962 		iscsi_cmd_free(c, cmd);
    963 		(void) pthread_mutex_unlock(&c->c_mutex);
    964 		conn_state(c, T8);
    965 		return (True);
    966 	}
    967 
    968 	pad_len = ((ISCSI_PAD_WORD_LEN -
    969 	    (dlen & (ISCSI_PAD_WORD_LEN - 1))) & (ISCSI_PAD_WORD_LEN - 1));
    970 
    971 	if (pad_len) {
    972 		if (recv(c->c_fd, pad_buf, pad_len, MSG_WAITALL) != pad_len) {
    973 			if (errno == ECONNRESET) {
    974 				queue_prt(c->c_mgmtq, Q_CONN_ERRS,
    975 				    "CON%x  dataout_delayed -- "
    976 				    "initiator reset socket\n", c->c_num);
    977 			} else {
    978 				queue_prt(c->c_mgmtq, Q_CONN_ERRS,
    979 				    "CON%x Pad Word read errno=%d\n", c->c_num,
    980 				    errno);
    981 			}
    982 
    983 			(void) pthread_mutex_lock(&c->c_mutex);
    984 			t10_cmd_shoot_event(cmd->c_t10_cmd, T10_Cmd_T5);
    985 			iscsi_cmd_free(c, cmd);
    986 			(void) pthread_mutex_unlock(&c->c_mutex);
    987 			conn_state(c, T8);
    988 			return (True);
    989 		}
    990 	}
    991 
    992 	if (c->c_data_digest == True) {
    993 		if (recv(c->c_fd, (char *)&crc_actual, sizeof (crc_actual),
    994 		    MSG_WAITALL) != sizeof (crc_actual)) {
    995 			if (errno == ECONNRESET) {
    996 				queue_prt(c->c_mgmtq, Q_CONN_ERRS,
    997 				    "CON%x  dataout_delayed -- "
    998 				    "initiator reset socket\n", c->c_num);
    999 			} else {
   1000 				queue_prt(c->c_mgmtq, Q_CONN_ERRS,
   1001 				    "CON%x  CRC32 read errno=%d\n", c->c_num,
   1002 				    errno);
   1003 			}
   1004 
   1005 			(void) pthread_mutex_lock(&c->c_mutex);
   1006 			t10_cmd_shoot_event(cmd->c_t10_cmd, T10_Cmd_T5);
   1007 			iscsi_cmd_free(c, cmd);
   1008 			(void) pthread_mutex_unlock(&c->c_mutex);
   1009 			conn_state(c, T8);
   1010 			return (True);
   1011 		}
   1012 		crc_calc = iscsi_crc32c((void *)cmd->c_data, dlen);
   1013 		if (crc_calc != crc_actual) {
   1014 
   1015 			(void) snprintf(debug, sizeof (debug),
   1016 			    "CON%x  CRC Error: actual %x vs. calc 0x%x",
   1017 			    c->c_num, crc_actual, crc_calc);
   1018 
   1019 			/*
   1020 			 * NOTE: Need to think about this one some more.
   1021 			 * Just because we get a data error doesn't mean
   1022 			 * we should drop the connection. Look at the
   1023 			 * spec and determine what's the appropriate
   1024 			 * error recovery for this issue.
   1025 			 */
   1026 			(void) pthread_mutex_lock(&c->c_mutex);
   1027 			t10_cmd_shoot_event(cmd->c_t10_cmd, T10_Cmd_T5);
   1028 			iscsi_cmd_free(c, cmd);
   1029 			(void) pthread_mutex_unlock(&c->c_mutex);
   1030 			conn_state(c, T8);
   1031 			return (True);
   1032 		}
   1033 	}
   1034 
   1035 	/*
   1036 	 * We'll update the offset with the amount of data that
   1037 	 * has been received. During a SCSI response PDU this value
   1038 	 * will be used to determine if there's an overrun condition.
   1039 	 */
   1040 	cmd->c_offset_out += dlen;
   1041 
   1042 	(void) pthread_mutex_lock(&c->c_mutex);
   1043 	(void) pthread_mutex_lock(&c->c_state_mutex);
   1044 	if (c->c_state == S5_LOGGED_IN) {
   1045 		if ((cmd->c_state == CmdCanceled) &&
   1046 		    (type == msg_cmd_data_out))
   1047 			t10_cmd_shoot_event(cmd->c_t10_cmd, T10_Cmd_T5);
   1048 		else
   1049 			queue_message_set(c->c_sessq, 0, type, (void *)cmd);
   1050 	} else if (cmd->c_state == CmdCanceled) {
   1051 		t10_cmd_shoot_event(cmd->c_t10_cmd, T10_Cmd_T5);
   1052 	}
   1053 	(void) pthread_mutex_unlock(&c->c_state_mutex);
   1054 	(void) pthread_mutex_unlock(&c->c_mutex);
   1055 
   1056 	/*
   1057 	 * The else case here is if we're calling STE directly and the data
   1058 	 * will be read from the socket when STE is ready for it.
   1059 	 */
   1060 
   1061 	return (True);
   1062 }
   1063 
   1064 /*
   1065  * []----
   1066  * | dataout_callback -- copy data from socket to emulation buffer
   1067  * []----
   1068  */
   1069 void
   1070 dataout_callback(t10_cmd_t *t, char *data, size_t *xfer)
   1071 {
   1072 	iscsi_cmd_t	*cmd	= (iscsi_cmd_t *)T10_TRANS_ID(t);
   1073 	iscsi_conn_t	*c	= cmd->c_allegiance;
   1074 	int		dlen	= cmd->c_data_len;
   1075 	int		cc;
   1076 	char		pad_buf[ISCSI_PAD_WORD_LEN - 1];
   1077 	char		pad_len = 0;
   1078 
   1079 	pad_len = ((ISCSI_PAD_WORD_LEN -
   1080 	    (dlen & (ISCSI_PAD_WORD_LEN - 1))) &
   1081 	    (ISCSI_PAD_WORD_LEN - 1));
   1082 
   1083 
   1084 	if (T10_DATA(t) != NULL) {
   1085 		assert(T10_DATA(t) == cmd->c_data);
   1086 		assert(cmd->c_data_alloc == True);
   1087 		free(T10_DATA(t));
   1088 		T10_DATA(t)		= NULL;
   1089 		cmd->c_data		= NULL;
   1090 		cmd->c_data_alloc	= False;
   1091 		return;
   1092 	}
   1093 
   1094 	if ((cc = recv(c->c_fd, data, dlen, MSG_WAITALL)) != dlen) {
   1095 		if (errno == ECONNRESET) {
   1096 			queue_prt(c->c_mgmtq, Q_CONN_ERRS,
   1097 			    "CON%x  data_callback -- initiator reset socket\n",
   1098 			    c->c_num);
   1099 		} else {
   1100 			queue_prt(c->c_mgmtq, Q_CONN_ERRS,
   1101 			    "CON%x  recv(got-%d, expect-%d) errno=%d",
   1102 			    c->c_num, cc, dlen, errno);
   1103 		}
   1104 
   1105 		conn_state(c, T8);
   1106 		goto finish;
   1107 	}
   1108 
   1109 	if (pad_len) {
   1110 		if (recv(c->c_fd, pad_buf, pad_len, MSG_WAITALL) != pad_len) {
   1111 			if (errno == ECONNRESET) {
   1112 				queue_prt(c->c_mgmtq, Q_CONN_ERRS,
   1113 				    "CON%x  data_callback -- "
   1114 				    "initiator reset socket\n", c->c_num);
   1115 			} else {
   1116 				queue_prt(c->c_mgmtq, Q_CONN_ERRS,
   1117 				    "CON%x data_callback -- "
   1118 				    "pad read errno=%d\n", c->c_num, errno);
   1119 			}
   1120 			conn_state(c, T8);
   1121 			goto finish;
   1122 		}
   1123 	}
   1124 
   1125 finish:
   1126 	*xfer = cc;
   1127 	/* ---- Send msg that receive side of the connection can go ---- */
   1128 	(void) sema_post(&c->c_datain);
   1129 }
   1130