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 * Copyright 2000 by Cisco Systems, Inc. All rights reserved.
23 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
25 *
26 * iSCSI Pseudo HBA Driver
27 */
28
29 #include <sys/socket.h> /* networking stuff */
30 #include <sys/t_kuser.h> /* networking stuff */
31 #include <sys/tihdr.h> /* networking stuff */
32 #include <sys/strsubr.h> /* networking stuff */
33 #include <netinet/tcp.h> /* TCP_NODELAY */
34 #include <sys/socketvar.h> /* _ALLOC_SLEEP */
35 #include <sys/strsun.h> /* DB_TYPE() */
36 #include <sys/scsi/generic/sense.h>
37
38 #include "iscsi.h" /* iscsi driver */
39 #include <sys/iscsi_protocol.h> /* iscsi protocol */
40
41 #define ISCSI_INI_TASK_TTT 0xffffffff
42 #define ISCSI_CONN_TIEMOUT_DETECT 20
43
44 boolean_t iscsi_io_logging = B_FALSE;
45
46 #define ISCSI_CHECK_SCSI_READ(ICHK_CMD, ICHK_HDR, ICHK_LEN, ICHK_TYPE) \
47 if (idm_pattern_checking) { \
48 struct scsi_pkt *pkt = (ICHK_CMD)->cmd_un.scsi.pkt; \
49 if (((ICHK_HDR)->response == 0) && \
50 ((ICHK_HDR)->cmd_status == 0) && \
51 ((pkt->pkt_cdbp[0] == SCMD_READ_G1) || \
52 (pkt->pkt_cdbp[0] == SCMD_READ_G4) || \
53 (pkt->pkt_cdbp[0] == SCMD_READ) || \
54 (pkt->pkt_cdbp[0] == SCMD_READ_G5))) { \
55 idm_buf_t *idb = (ICHK_CMD)->cmd_un.scsi.ibp_ibuf; \
56 IDM_BUFPAT_CHECK(idb, ICHK_LEN, ICHK_TYPE); \
57 } \
58 }
59
60 /* Size of structure scsi_arq_status without sense data. */
61 #define ISCSI_ARQ_STATUS_NOSENSE_LEN (sizeof (struct scsi_arq_status) - \
62 sizeof (struct scsi_extended_sense))
63
64 /* generic io helpers */
65 static uint32_t n2h24(uchar_t *ptr);
66 static int iscsi_sna_lt(uint32_t n1, uint32_t n2);
67 void iscsi_update_flow_control(iscsi_sess_t *isp,
68 uint32_t max, uint32_t exp);
69 static iscsi_status_t iscsi_rx_process_scsi_itt_to_icmdp(iscsi_sess_t *isp,
70 idm_conn_t *ic, iscsi_scsi_rsp_hdr_t *ihp, iscsi_cmd_t **icmdp);
71 static iscsi_status_t iscsi_rx_process_itt_to_icmdp(iscsi_sess_t *isp,
72 iscsi_hdr_t *ihp, iscsi_cmd_t **icmdp);
73 static void iscsi_process_rsp_status(iscsi_sess_t *isp, iscsi_conn_t *icp,
74 idm_status_t status);
75 static void iscsi_drop_conn_cleanup(iscsi_conn_t *icp);
76 static boolean_t iscsi_nop_timeout_checks(iscsi_cmd_t *icmdp);
77 /* callbacks from idm */
78 static idm_pdu_cb_t iscsi_tx_done;
79
80 /* receivers */
81 static idm_status_t iscsi_rx_process_nop(idm_conn_t *ic, idm_pdu_t *pdu);
82 static idm_status_t iscsi_rx_process_data_rsp(idm_conn_t *ic,
83 idm_pdu_t *pdu);
84 static idm_status_t iscsi_rx_process_cmd_rsp(idm_conn_t *ic, idm_pdu_t *pdu);
85 static idm_status_t iscsi_rx_process_reject_rsp(idm_conn_t *ic,
86 idm_pdu_t *pdu);
87
88 static idm_status_t iscsi_rx_process_rejected_tsk_mgt(idm_conn_t *ic,
89 iscsi_hdr_t *old_ihp);
90 static idm_status_t iscsi_rx_process_task_mgt_rsp(idm_conn_t *ic,
91 idm_pdu_t *pdu);
92 static idm_status_t iscsi_rx_process_logout_rsp(idm_conn_t *ic,
93 idm_pdu_t *pdu);
94 static idm_status_t iscsi_rx_process_async_rsp(idm_conn_t *ic,
95 idm_pdu_t *pdu);
96 static idm_status_t iscsi_rx_process_text_rsp(idm_conn_t *ic,
97 idm_pdu_t *pdu);
98
99 /* senders */
100 static iscsi_status_t iscsi_tx_scsi(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
101 static iscsi_status_t iscsi_tx_nop(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
102 static iscsi_status_t iscsi_tx_abort(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
103 static iscsi_status_t iscsi_tx_reset(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
104 static iscsi_status_t iscsi_tx_logout(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
105 static iscsi_status_t iscsi_tx_text(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
106
107
108 /* helpers */
109 static void iscsi_logout_start(void *arg);
110 static void iscsi_handle_passthru_callback(struct scsi_pkt *pkt);
111 static void iscsi_handle_nop(iscsi_conn_t *icp, uint32_t itt, uint32_t ttt);
112
113 static void iscsi_timeout_checks(iscsi_sess_t *isp);
114 static void iscsi_nop_checks(iscsi_sess_t *isp);
115 static boolean_t iscsi_decode_sense(uint8_t *sense_data, iscsi_cmd_t *icmdp);
116 static void iscsi_flush_cmd_after_reset(uint32_t cmd_sn, uint16_t lun_num,
117 iscsi_conn_t *icp);
118
119 /*
120 * This file contains the main guts of the iSCSI protocol layer.
121 * It's broken into 5 sections; Basic helper functions, RX IO path,
122 * TX IO path, Completion (IC) IO path, and watchdog (WD) routines.
123 *
124 * The IO flow model is similiar to the below diagram. The
125 * iscsi session, connection and command state machines are used
126 * to drive IO through this flow diagram. Reference those files
127 * to get a detailed description of their respective state models
128 * prior to their xxx_state_machine_function().
129 *
130 * tran_start() -> CMD_E1 TX_THREAD RX_THREAD
131 * | T T
132 * V T T
133 * PENDING_Q --CMD_E2--> ACTIVE_Q - --CMD_E3--+
134 * T \ C T |
135 * T \M T |
136 * D T |
137 * WD_THREAD TT|TT T |
138 * /E T |
139 * / 6 T |
140 * ABORTING_Q<- --CMD_E3--+
141 * T |
142 * T T |
143 * T |
144 * callback() <--CMD_E#-- COMPLETION_Q <------------+
145 * T
146 * T
147 * IC_THREAD
148 *
149 * External and internal command are ran thru this same state
150 * machine. All commands enter the state machine by receiving an
151 * ISCSI_CMD_EVENT_E1. This event places the command into the
152 * PENDING_Q. Next when resources are available the TX_THREAD
153 * issues a E2 event on the command. This sends the command
154 * to the TCP stack and places the command on the ACTIVE_Q. While
155 * on the PENDIING_Q and ACTIVE_Q, the command is monitored via the
156 * WD_THREAD to ensure the pkt_time has not elapsed. If elapsed the
157 * command is issued an E6(timeout) event which moves either (if pending)
158 * completed the command or (if active) moves the command to the
159 * aborting queue and issues a SCSI TASK MANAGEMENT ABORT command
160 * to cancel the IO request. If the original command is completed
161 * or the TASK MANAGEMENT command completes the command is moved
162 * to the COMPLETION_Q via a E3 event. The IC_THREAD then processes
163 * the COMPLETION_Q and issues the scsi_pkt callback. This
164 * callback can not be processed directly from the RX_THREAD
165 * because the callback might call back into the iscsi driver
166 * causing a deadlock condition.
167 *
168 * For more details on the complete CMD state machine reference
169 * the state machine diagram in iscsi_cmd.c. The connection state
170 * machine is driven via IO events in this file. Then session
171 * events are driven by the connection events. For complete
172 * details on these state machines reference iscsi_sess.c and
173 * iscsi_conn.c
174 */
175
176
177 /*
178 * +--------------------------------------------------------------------+
179 * | io helper routines |
180 * +--------------------------------------------------------------------+
181 */
182
183 /*
184 * n2h24 - native to host 24 bit integer translation.
185 */
186 static uint32_t
n2h24(uchar_t * ptr)187 n2h24(uchar_t *ptr)
188 {
189 uint32_t idx;
190 bcopy(ptr, &idx, 3);
191 return (ntohl(idx) >> 8);
192 }
193
194 /*
195 * iscsi_sna_lt - Serial Number Arithmetic, 32 bits, less than, RFC1982
196 */
197 static int
iscsi_sna_lt(uint32_t n1,uint32_t n2)198 iscsi_sna_lt(uint32_t n1, uint32_t n2)
199 {
200 return ((n1 != n2) &&
201 (((n1 < n2) && ((n2 - n1) < ISCSI_SNA32_CHECK)) ||
202 ((n1 > n2) && ((n1 - n2) > ISCSI_SNA32_CHECK))));
203 }
204
205 /*
206 * iscsi_sna_lte - Serial Number Arithmetic, 32 bits, less than or equal,
207 * RFC1982
208 */
209 int
iscsi_sna_lte(uint32_t n1,uint32_t n2)210 iscsi_sna_lte(uint32_t n1, uint32_t n2)
211 {
212 return ((n1 == n2) ||
213 (((n1 < n2) && ((n2 - n1) < ISCSI_SNA32_CHECK)) ||
214 ((n1 > n2) && ((n1 - n2) > ISCSI_SNA32_CHECK))));
215 }
216
217 /*
218 * iscsi_update_flow_control - Update expcmdsn and maxcmdsn iSCSI
219 * flow control information for a session
220 */
221 void
iscsi_update_flow_control(iscsi_sess_t * isp,uint32_t max,uint32_t exp)222 iscsi_update_flow_control(iscsi_sess_t *isp, uint32_t max, uint32_t exp)
223 {
224 ASSERT(isp != NULL);
225 ASSERT(mutex_owned(&isp->sess_cmdsn_mutex));
226
227 if (!iscsi_sna_lt(max, (exp - 1))) {
228
229 if (!iscsi_sna_lte(exp, isp->sess_expcmdsn)) {
230 isp->sess_expcmdsn = exp;
231 }
232
233 if (!iscsi_sna_lte(max, isp->sess_maxcmdsn)) {
234 isp->sess_maxcmdsn = max;
235 if (iscsi_sna_lte(isp->sess_cmdsn,
236 isp->sess_maxcmdsn)) {
237 /*
238 * the window is open again - schedule
239 * to send any held tasks soon
240 */
241 iscsi_sess_redrive_io(isp);
242 }
243 }
244 }
245 }
246
247
248 /*
249 * +--------------------------------------------------------------------+
250 * | io receive and processing routines |
251 * +--------------------------------------------------------------------+
252 */
253
254 /*
255 * iscsi_rx_scsi_rsp - called from idm
256 * For each opcode type fan out the processing.
257 */
258 void
iscsi_rx_scsi_rsp(idm_conn_t * ic,idm_pdu_t * pdu)259 iscsi_rx_scsi_rsp(idm_conn_t *ic, idm_pdu_t *pdu)
260 {
261 iscsi_conn_t *icp;
262 iscsi_sess_t *isp;
263 iscsi_hdr_t *ihp;
264 idm_status_t status;
265
266 ASSERT(ic != NULL);
267 ASSERT(pdu != NULL);
268 icp = ic->ic_handle;
269 ASSERT(icp != NULL);
270 ihp = (iscsi_hdr_t *)pdu->isp_hdr;
271 ASSERT(ihp != NULL);
272 isp = icp->conn_sess;
273 ASSERT(isp != NULL);
274
275 /* reset the session timer when we receive the response */
276 isp->sess_rx_lbolt = icp->conn_rx_lbolt = ddi_get_lbolt();
277
278 /* fan out the hdr processing */
279 switch (ihp->opcode & ISCSI_OPCODE_MASK) {
280 case ISCSI_OP_SCSI_DATA_RSP:
281 status = iscsi_rx_process_data_rsp(ic, pdu);
282 break;
283 case ISCSI_OP_SCSI_RSP:
284 status = iscsi_rx_process_cmd_rsp(ic, pdu);
285 idm_pdu_complete(pdu, status);
286 break;
287 default:
288 cmn_err(CE_WARN, "iscsi connection(%u) protocol error - "
289 "received pdu with unsupported opcode 0x%02x",
290 icp->conn_oid, ihp->opcode);
291 status = IDM_STATUS_PROTOCOL_ERROR;
292 }
293 iscsi_process_rsp_status(isp, icp, status);
294 }
295
296 void
iscsi_task_cleanup(int opcode,iscsi_cmd_t * icmdp)297 iscsi_task_cleanup(int opcode, iscsi_cmd_t *icmdp)
298 {
299 struct buf *bp;
300 idm_buf_t *ibp, *obp;
301 idm_task_t *itp;
302
303 itp = icmdp->cmd_itp;
304 ASSERT(itp != NULL);
305 ASSERT((opcode == ISCSI_OP_SCSI_DATA_RSP) ||
306 (opcode == ISCSI_OP_SCSI_RSP));
307
308 bp = icmdp->cmd_un.scsi.bp;
309 ibp = icmdp->cmd_un.scsi.ibp_ibuf;
310 obp = icmdp->cmd_un.scsi.ibp_obuf;
311 ISCSI_IO_LOG(CE_NOTE, "DEBUG: task_cleanup: itp: %p opcode: %d "
312 "icmdp: %p bp: %p ibp: %p", (void *)itp, opcode,
313 (void *)icmdp, (void *)bp, (void *)ibp);
314 if (bp && bp->b_bcount) {
315 if (ibp != NULL && bp->b_flags & B_READ) {
316 idm_buf_unbind_in(itp, ibp);
317 idm_buf_free(ibp);
318 icmdp->cmd_un.scsi.ibp_ibuf = NULL;
319 } else if (obp != NULL && !(bp->b_flags & B_READ)) {
320 idm_buf_unbind_out(itp, obp);
321 idm_buf_free(obp);
322 icmdp->cmd_un.scsi.ibp_obuf = NULL;
323 }
324 }
325
326 idm_task_done(itp);
327 }
328
329 idm_status_t
iscsi_rx_chk(iscsi_conn_t * icp,iscsi_sess_t * isp,iscsi_scsi_rsp_hdr_t * irhp,iscsi_cmd_t ** icmdp)330 iscsi_rx_chk(iscsi_conn_t *icp, iscsi_sess_t *isp,
331 iscsi_scsi_rsp_hdr_t *irhp, iscsi_cmd_t **icmdp)
332 {
333 iscsi_status_t rval;
334
335 mutex_enter(&isp->sess_cmdsn_mutex);
336
337 if (icp->conn_expstatsn == ntohl(irhp->statsn)) {
338 icp->conn_expstatsn++;
339 } else {
340 cmn_err(CE_WARN, "iscsi connection(%u/%x) protocol error - "
341 "received status out of order itt:0x%x statsn:0x%x "
342 "expstatsn:0x%x", icp->conn_oid, irhp->opcode,
343 irhp->itt, ntohl(irhp->statsn), icp->conn_expstatsn);
344 mutex_exit(&isp->sess_cmdsn_mutex);
345 return (IDM_STATUS_PROTOCOL_ERROR);
346 }
347
348 /* get icmdp so we can cleanup on error */
349 if ((irhp->opcode == ISCSI_OP_SCSI_DATA_RSP) ||
350 (irhp->opcode == ISCSI_OP_SCSI_RSP)) {
351 rval = iscsi_rx_process_scsi_itt_to_icmdp(isp, icp->conn_ic,
352 irhp, icmdp);
353 } else {
354 rval = iscsi_rx_process_itt_to_icmdp(isp,
355 (iscsi_hdr_t *)irhp, icmdp);
356 }
357
358 if (!ISCSI_SUCCESS(rval)) {
359 mutex_exit(&isp->sess_cmdsn_mutex);
360 return (IDM_STATUS_PROTOCOL_ERROR);
361 }
362
363 /* update expcmdsn and maxcmdsn */
364 iscsi_update_flow_control(isp, ntohl(irhp->maxcmdsn),
365 ntohl(irhp->expcmdsn));
366 mutex_exit(&isp->sess_cmdsn_mutex);
367 return (IDM_STATUS_SUCCESS);
368 }
369
370 static void
iscsi_cmd_rsp_chk(iscsi_cmd_t * icmdp,iscsi_scsi_rsp_hdr_t * issrhp)371 iscsi_cmd_rsp_chk(iscsi_cmd_t *icmdp, iscsi_scsi_rsp_hdr_t *issrhp)
372 {
373 struct scsi_pkt *pkt;
374 size_t data_transferred;
375
376 pkt = icmdp->cmd_un.scsi.pkt;
377 pkt->pkt_resid = 0;
378 data_transferred = icmdp->cmd_un.scsi.data_transferred;
379 /* Check the residual count */
380 if ((icmdp->cmd_un.scsi.bp) &&
381 (data_transferred != icmdp->cmd_un.scsi.bp->b_bcount)) {
382 /*
383 * We didn't xfer the expected amount of data -
384 * the residual_count in the header is only
385 * valid if the underflow flag is set.
386 */
387 if (issrhp->flags & ISCSI_FLAG_CMD_UNDERFLOW) {
388 pkt->pkt_resid = ntohl(issrhp->residual_count);
389 } else {
390 if (icmdp->cmd_un.scsi.bp->b_bcount >
391 data_transferred) {
392 /*
393 * Some data fell on the floor
394 * somehow - probably a CRC error
395 */
396 pkt->pkt_resid =
397 icmdp->cmd_un.scsi.bp->b_bcount -
398 data_transferred;
399 }
400 }
401 ISCSI_IO_LOG(CE_NOTE,
402 "DEBUG: iscsi_rx_cmd_rsp_chk: itt: %u"
403 "data_trans != b_count data_transferred: %lu "
404 "b_count: %lu cmd_status: %d flags: %d resid: %lu",
405 issrhp->itt, data_transferred,
406 icmdp->cmd_un.scsi.bp->b_bcount,
407 issrhp->cmd_status & STATUS_MASK,
408 issrhp->flags, pkt->pkt_resid);
409 }
410 /* set flags that tell SCSA that the command is complete */
411 if (icmdp->cmd_crc_error_seen == B_FALSE) {
412 /* Set successful completion */
413 pkt->pkt_reason = CMD_CMPLT;
414 if (icmdp->cmd_un.scsi.bp) {
415 pkt->pkt_state |= (STATE_XFERRED_DATA |
416 STATE_GOT_STATUS);
417 } else {
418 pkt->pkt_state |= STATE_GOT_STATUS;
419 }
420 } else {
421 /*
422 * Some of the data was found to have an incorrect
423 * error at the protocol error.
424 */
425 pkt->pkt_reason = CMD_PER_FAIL;
426 pkt->pkt_statistics |= STAT_PERR;
427 if (icmdp->cmd_un.scsi.bp) {
428 pkt->pkt_resid =
429 icmdp->cmd_un.scsi.bp->b_bcount;
430 } else {
431 pkt->pkt_resid = 0;
432 }
433 }
434 }
435
436 static boolean_t
iscsi_cmd_rsp_cmd_status(iscsi_cmd_t * icmdp,iscsi_scsi_rsp_hdr_t * issrhp,uint8_t * data)437 iscsi_cmd_rsp_cmd_status(iscsi_cmd_t *icmdp, iscsi_scsi_rsp_hdr_t *issrhp,
438 uint8_t *data)
439 {
440 int32_t dlength;
441 struct scsi_arq_status *arqstat;
442 size_t senselen;
443 int32_t statuslen;
444 int32_t sensebuf_len;
445 struct scsi_pkt *pkt;
446 boolean_t affect = B_FALSE;
447 int32_t senselen_to_copy;
448
449 pkt = icmdp->cmd_un.scsi.pkt;
450 dlength = n2h24(issrhp->dlength);
451
452 /*
453 * Process iSCSI Cmd Response Status
454 * RFC 3720 Sectionn 10.4.2.
455 */
456 switch (issrhp->cmd_status & STATUS_MASK) {
457 case STATUS_GOOD:
458 /* pass SCSI status up stack */
459 if (pkt->pkt_scbp) {
460 pkt->pkt_scbp[0] = issrhp->cmd_status;
461 }
462 break;
463 case STATUS_CHECK:
464 /*
465 * Verify we received a sense buffer and
466 * that there is the correct amount of
467 * request sense space to copy it to.
468 */
469 if ((dlength > 1) &&
470 (pkt->pkt_scbp != NULL) &&
471 (icmdp->cmd_un.scsi.statuslen >=
472 sizeof (struct scsi_arq_status))) {
473 /*
474 * If a bad command status is received we
475 * need to reset the pkt_resid to zero.
476 * The target driver compares its value
477 * before checking other error flags.
478 * (ex. check conditions)
479 */
480 pkt->pkt_resid = 0;
481
482 /* get sense length from first 2 bytes */
483 senselen = ((data[0] << 8) | data[1]) &
484 (size_t)0xFFFF;
485 ISCSI_IO_LOG(CE_NOTE,
486 "DEBUG: iscsi_rx_cmd_rsp_cmd_status status_check: "
487 "dlen: %d scbp: %p statuslen: %d arq: %d senselen:"
488 " %lu", dlength, (void *)pkt->pkt_scbp,
489 icmdp->cmd_un.scsi.statuslen,
490 (int)sizeof (struct scsi_arq_status),
491 senselen);
492
493 /* Sanity-check on the sense length */
494 if ((senselen + 2) > dlength) {
495 senselen = dlength - 2;
496 }
497
498 /*
499 * If there was a Data Digest error then
500 * the sense data cannot be trusted.
501 */
502 if (icmdp->cmd_crc_error_seen) {
503 senselen = 0;
504 }
505
506 /* automatic request sense */
507 arqstat =
508 (struct scsi_arq_status *)pkt->pkt_scbp;
509
510 /* pass SCSI status up stack */
511 *((uchar_t *)&arqstat->sts_status) =
512 issrhp->cmd_status;
513
514 /*
515 * Set the status for the automatic
516 * request sense command
517 */
518 arqstat->sts_rqpkt_state = (STATE_GOT_BUS |
519 STATE_GOT_TARGET | STATE_SENT_CMD |
520 STATE_XFERRED_DATA | STATE_GOT_STATUS |
521 STATE_ARQ_DONE);
522
523 *((uchar_t *)&arqstat->sts_rqpkt_status) =
524 STATUS_GOOD;
525
526 arqstat->sts_rqpkt_reason = CMD_CMPLT;
527 statuslen = icmdp->cmd_un.scsi.statuslen;
528
529 if (senselen == 0) {
530 /* auto request sense failed */
531 arqstat->sts_rqpkt_status.sts_chk = 1;
532 arqstat->sts_rqpkt_resid = statuslen;
533 } else if (senselen < statuslen) {
534 /* auto request sense short */
535 arqstat->sts_rqpkt_resid = statuslen - senselen;
536 } else {
537 /* auto request sense complete */
538 arqstat->sts_rqpkt_resid = 0;
539 }
540 arqstat->sts_rqpkt_statistics = 0;
541 pkt->pkt_state |= STATE_ARQ_DONE;
542
543 if (icmdp->cmd_misc_flags & ISCSI_CMD_MISCFLAG_XARQ) {
544 pkt->pkt_state |= STATE_XARQ_DONE;
545 }
546
547 /*
548 * Calculate size of space reserved for sense data in
549 * pkt->pkt_scbp.
550 */
551 sensebuf_len = statuslen - ISCSI_ARQ_STATUS_NOSENSE_LEN;
552
553 /* copy auto request sense */
554 senselen_to_copy = min(senselen, sensebuf_len);
555 if (senselen_to_copy > 0) {
556 bcopy(&data[2], (uchar_t *)&arqstat->
557 sts_sensedata, senselen_to_copy);
558
559 affect = iscsi_decode_sense(
560 (uint8_t *)&arqstat->sts_sensedata, icmdp);
561 }
562 arqstat->sts_rqpkt_resid = sensebuf_len -
563 senselen_to_copy;
564 ISCSI_IO_LOG(CE_NOTE, "DEBUG: iscsi_cmd_rsp_cmd_status:"
565 " sts_rqpkt_resid: %d pkt_scblen: %d senselen: %lu"
566 " sensebuf_len: %d senselen_to_copy: %d affect: %d",
567 arqstat->sts_rqpkt_resid, pkt->pkt_scblen, senselen,
568 sensebuf_len, senselen_to_copy, affect);
569 break;
570 }
571 /* FALLTHRU */
572 case STATUS_BUSY:
573 case STATUS_RESERVATION_CONFLICT:
574 case STATUS_QFULL:
575 case STATUS_ACA_ACTIVE:
576 default:
577 /*
578 * If a bad command status is received we need to
579 * reset the pkt_resid to zero. The target driver
580 * compares its value before checking other error
581 * flags. (ex. check conditions)
582 */
583 ISCSI_IO_LOG(CE_NOTE,
584 "DEBUG: iscsi_rx_cmd_rsp_cmd_status: status: "
585 "%d cmd_status: %d dlen: %u scbp: %p statuslen: %d "
586 "arg_len: %d", issrhp->cmd_status & STATUS_MASK,
587 issrhp->cmd_status, dlength, (void *)pkt->pkt_scbp,
588 icmdp->cmd_un.scsi.statuslen,
589 (int)sizeof (struct scsi_arq_status));
590 pkt->pkt_resid = 0;
591 /* pass SCSI status up stack */
592 if (pkt->pkt_scbp) {
593 pkt->pkt_scbp[0] = issrhp->cmd_status;
594 }
595 }
596
597 return (affect);
598 }
599
600 /*
601 * iscsi_rx_process_login_pdup - Process login response PDU. This function
602 * copies the data into the connection context so that the login code can
603 * interpret it.
604 */
605
606 idm_status_t
iscsi_rx_process_login_pdu(idm_conn_t * ic,idm_pdu_t * pdu)607 iscsi_rx_process_login_pdu(idm_conn_t *ic, idm_pdu_t *pdu)
608 {
609 iscsi_conn_t *icp;
610
611 icp = ic->ic_handle;
612
613 /*
614 * Copy header and data into connection structure so iscsi_login()
615 * can process it.
616 */
617 mutex_enter(&icp->conn_login_mutex);
618 /*
619 * If conn_login_state != LOGIN_TX then we are not ready to handle
620 * this login response and we should just drop it.
621 */
622 if (icp->conn_login_state == LOGIN_TX) {
623 icp->conn_login_datalen = pdu->isp_datalen;
624 bcopy(pdu->isp_hdr, &icp->conn_login_resp_hdr,
625 sizeof (iscsi_hdr_t));
626 /*
627 * Login code is sloppy with it's NULL handling so make sure
628 * we don't leave any stale data in there.
629 */
630 bzero(icp->conn_login_data, icp->conn_login_max_data_length);
631 bcopy(pdu->isp_data, icp->conn_login_data,
632 MIN(pdu->isp_datalen, icp->conn_login_max_data_length));
633 iscsi_login_update_state_locked(icp, LOGIN_RX);
634 }
635 mutex_exit(&icp->conn_login_mutex);
636
637 return (IDM_STATUS_SUCCESS);
638 }
639
640 /*
641 * iscsi_rx_process_cmd_rsp - Process received scsi command response. This
642 * will contain sense data if the command was not successful. This data needs
643 * to be copied into the scsi_pkt. Otherwise we just complete the IO.
644 */
645 static idm_status_t
iscsi_rx_process_cmd_rsp(idm_conn_t * ic,idm_pdu_t * pdu)646 iscsi_rx_process_cmd_rsp(idm_conn_t *ic, idm_pdu_t *pdu)
647 {
648 iscsi_conn_t *icp = ic->ic_handle;
649 iscsi_sess_t *isp = icp->conn_sess;
650 iscsi_scsi_rsp_hdr_t *issrhp = (iscsi_scsi_rsp_hdr_t *)pdu->isp_hdr;
651 uint8_t *data = pdu->isp_data;
652 iscsi_cmd_t *icmdp = NULL;
653 struct scsi_pkt *pkt = NULL;
654 idm_status_t rval;
655 struct buf *bp;
656 boolean_t flush = B_FALSE;
657 uint32_t cmd_sn = 0;
658 uint16_t lun_num = 0;
659
660 /* make sure we get status in order */
661 mutex_enter(&icp->conn_queue_active.mutex);
662
663 if ((rval = iscsi_rx_chk(icp, isp, issrhp,
664 &icmdp)) != IDM_STATUS_SUCCESS) {
665 if (icmdp != NULL) {
666 iscsi_task_cleanup(issrhp->opcode, icmdp);
667 }
668 mutex_exit(&icp->conn_queue_active.mutex);
669 return (rval);
670 }
671
672 /*
673 * If we are in "idm aborting" state then we shouldn't continue
674 * to process this command. By definition this command is no longer
675 * on the active queue so we shouldn't try to remove it either.
676 */
677 mutex_enter(&icmdp->cmd_mutex);
678 if (icmdp->cmd_state == ISCSI_CMD_STATE_IDM_ABORTING) {
679 mutex_exit(&icmdp->cmd_mutex);
680 mutex_exit(&icp->conn_queue_active.mutex);
681 return (IDM_STATUS_SUCCESS);
682 }
683 mutex_exit(&icmdp->cmd_mutex);
684
685 /* Get the IDM buffer and bytes transferred */
686 bp = icmdp->cmd_un.scsi.bp;
687 if (ic->ic_conn_flags & IDM_CONN_USE_SCOREBOARD) {
688 /* Transport tracks bytes transferred so use those counts */
689 if (bp && (bp->b_flags & B_READ)) {
690 icmdp->cmd_un.scsi.data_transferred +=
691 icmdp->cmd_itp->idt_rx_bytes;
692 } else {
693 icmdp->cmd_un.scsi.data_transferred +=
694 icmdp->cmd_itp->idt_tx_bytes;
695 }
696 } else {
697 /*
698 * Some transports cannot track the bytes transferred on
699 * the initiator side (like iSER) so we have to use the
700 * status info. If the response field indicates that
701 * the command actually completed then we will assume
702 * the data_transferred value represents the entire buffer
703 * unless the resid field says otherwise. This is a bit
704 * unintuitive but it's really impossible to know what
705 * has been transferred without detailed consideration
706 * of the SCSI status and sense key and that is outside
707 * the scope of the transport. Instead the target/class driver
708 * can consider these values along with the resid and figure
709 * it out. The data_transferred concept is just belt and
710 * suspenders anyway -- RFC 3720 actually explicitly rejects
711 * scoreboarding ("Initiators SHOULD NOT keep track of the
712 * data transferred to or from the target (scoreboarding)")
713 * perhaps for this very reason.
714 */
715 if (issrhp->response != 0) {
716 icmdp->cmd_un.scsi.data_transferred = 0;
717 } else {
718 icmdp->cmd_un.scsi.data_transferred =
719 (bp == NULL) ? 0 : bp->b_bcount;
720 if (issrhp->flags & ISCSI_FLAG_CMD_UNDERFLOW) {
721 icmdp->cmd_un.scsi.data_transferred -=
722 ntohl(issrhp->residual_count);
723 }
724 }
725 }
726
727 ISCSI_CHECK_SCSI_READ(icmdp, issrhp,
728 icmdp->cmd_un.scsi.data_transferred,
729 BP_CHECK_THOROUGH);
730
731 ISCSI_IO_LOG(CE_NOTE, "DEBUG: rx_process_cmd_rsp: ic: %p pdu: %p itt:"
732 " %x expcmdsn: %x sess_cmd: %x sess_expcmdsn: %x data_transfered:"
733 " %lu ibp: %p obp: %p", (void *)ic, (void *)pdu, issrhp->itt,
734 issrhp->expcmdsn, isp->sess_cmdsn, isp->sess_expcmdsn,
735 icmdp->cmd_un.scsi.data_transferred,
736 (void *)icmdp->cmd_un.scsi.ibp_ibuf,
737 (void *)icmdp->cmd_un.scsi.ibp_obuf);
738
739 iscsi_task_cleanup(issrhp->opcode, icmdp);
740
741 if (issrhp->response) {
742 /* The target failed the command. */
743 ISCSI_IO_LOG(CE_NOTE, "DEBUG: rx_process_cmd_rsp: ic: %p pdu:"
744 " %p response: %d bcount: %lu", (void *)ic, (void *)pdu,
745 issrhp->response, icmdp->cmd_un.scsi.bp->b_bcount);
746 pkt = icmdp->cmd_un.scsi.pkt;
747 pkt->pkt_reason = CMD_TRAN_ERR;
748 if (icmdp->cmd_un.scsi.bp) {
749 pkt->pkt_resid = icmdp->cmd_un.scsi.bp->b_bcount;
750 } else {
751 pkt->pkt_resid = 0;
752 }
753 } else {
754 /* success */
755 iscsi_cmd_rsp_chk(icmdp, issrhp);
756 flush = iscsi_cmd_rsp_cmd_status(icmdp, issrhp, data);
757
758 ASSERT(icmdp->cmd_lun == NULL || icmdp->cmd_lun->lun_num ==
759 (icmdp->cmd_un.scsi.lun & ISCSI_LUN_MASK));
760
761 if (flush == B_TRUE) {
762 cmd_sn = icmdp->cmd_sn;
763 lun_num = icmdp->cmd_un.scsi.lun & ISCSI_LUN_MASK;
764 }
765 }
766
767 iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E3, isp);
768 if (flush == B_TRUE) {
769 iscsi_flush_cmd_after_reset(cmd_sn, lun_num, icp);
770 }
771 mutex_exit(&icp->conn_queue_active.mutex);
772 return (IDM_STATUS_SUCCESS);
773 }
774
775 static void
iscsi_data_rsp_pkt(iscsi_cmd_t * icmdp,iscsi_data_rsp_hdr_t * idrhp)776 iscsi_data_rsp_pkt(iscsi_cmd_t *icmdp, iscsi_data_rsp_hdr_t *idrhp)
777 {
778 struct buf *bp = NULL;
779 size_t data_transferred;
780 struct scsi_pkt *pkt;
781
782 bp = icmdp->cmd_un.scsi.bp;
783 pkt = icmdp->cmd_un.scsi.pkt;
784 data_transferred = icmdp->cmd_un.scsi.data_transferred;
785 /*
786 * The command* must be completed now, since we won't get a command
787 * response PDU. The cmd_status and residual_count are
788 * not meaningful unless status_present is set.
789 */
790 pkt->pkt_resid = 0;
791 /* Check the residual count */
792 if (bp && (data_transferred != bp->b_bcount)) {
793 /*
794 * We didn't xfer the expected amount of data -
795 * the residual_count in the header is only valid
796 * if the underflow flag is set.
797 */
798 if (idrhp->flags & ISCSI_FLAG_DATA_UNDERFLOW) {
799 pkt->pkt_resid = ntohl(idrhp->residual_count);
800 ISCSI_IO_LOG(CE_NOTE, "DEBUG: iscsi_data_rsp_pkt: "
801 "underflow: itt: %d "
802 "transferred: %lu count: %lu", idrhp->itt,
803 data_transferred, bp->b_bcount);
804 } else {
805 if (bp->b_bcount > data_transferred) {
806 /* Some data fell on the floor somehw */
807 ISCSI_IO_LOG(CE_NOTE, "DEBUG: "
808 "iscsi_data_rsp_pkt: data fell: itt: %d "
809 "transferred: %lu count: %lu", idrhp->itt,
810 data_transferred, bp->b_bcount);
811 pkt->pkt_resid =
812 bp->b_bcount - data_transferred;
813 }
814 }
815 }
816
817 pkt->pkt_reason = CMD_CMPLT;
818 pkt->pkt_state |= (STATE_XFERRED_DATA | STATE_GOT_STATUS);
819
820 if (((idrhp->cmd_status & STATUS_MASK) != STATUS_GOOD) &&
821 (icmdp->cmd_un.scsi.statuslen >=
822 sizeof (struct scsi_arq_status)) && pkt->pkt_scbp) {
823
824 /*
825 * Not supposed to get exception status here!
826 * We have no request sense data so just do the
827 * best we can
828 */
829 struct scsi_arq_status *arqstat =
830 (struct scsi_arq_status *)pkt->pkt_scbp;
831
832
833 bzero(arqstat, sizeof (struct scsi_arq_status));
834
835 *((uchar_t *)&arqstat->sts_status) =
836 idrhp->cmd_status;
837
838 /* sense residual is set to whole size of sense buffer */
839 arqstat->sts_rqpkt_resid = icmdp->cmd_un.scsi.statuslen -
840 ISCSI_ARQ_STATUS_NOSENSE_LEN;
841 ISCSI_IO_LOG(CE_NOTE, "DEBUG: iscsi_data_rsp_pkt: "
842 "exception status: itt: %d resid: %d",
843 idrhp->itt, arqstat->sts_rqpkt_resid);
844
845 } else if (pkt->pkt_scbp) {
846 /* just pass along the status we got */
847 pkt->pkt_scbp[0] = idrhp->cmd_status;
848 }
849 }
850
851 /*
852 * iscsi_rx_process_data_rsp -
853 * This currently processes the final data sequence denoted by the data response
854 * PDU Status bit being set. We will not receive the SCSI response.
855 * This bit denotes that the PDU is the successful completion of the
856 * command.
857 */
858 static idm_status_t
iscsi_rx_process_data_rsp(idm_conn_t * ic,idm_pdu_t * pdu)859 iscsi_rx_process_data_rsp(idm_conn_t *ic, idm_pdu_t *pdu)
860 {
861 iscsi_sess_t *isp = NULL;
862 iscsi_data_rsp_hdr_t *idrhp = (iscsi_data_rsp_hdr_t *)pdu->isp_hdr;
863 iscsi_cmd_t *icmdp = NULL;
864 struct buf *bp = NULL;
865 iscsi_conn_t *icp = ic->ic_handle;
866 idm_buf_t *ibp;
867 idm_status_t rval;
868
869
870 /* should only call this when the data rsp contains final rsp */
871 ASSERT(idrhp->flags & ISCSI_FLAG_DATA_STATUS);
872 isp = icp->conn_sess;
873
874 mutex_enter(&icp->conn_queue_active.mutex);
875 if ((rval = iscsi_rx_chk(icp, isp, (iscsi_scsi_rsp_hdr_t *)idrhp,
876 &icmdp)) != IDM_STATUS_SUCCESS) {
877 if (icmdp != NULL) {
878 iscsi_task_cleanup(idrhp->opcode, icmdp);
879 }
880 mutex_exit(&icp->conn_queue_active.mutex);
881 return (rval);
882 }
883
884 /*
885 * If we are in "idm aborting" state then we shouldn't continue
886 * to process this command. By definition this command is no longer
887 * on the active queue so we shouldn't try to remove it either.
888 */
889 mutex_enter(&icmdp->cmd_mutex);
890 if (icmdp->cmd_state == ISCSI_CMD_STATE_IDM_ABORTING) {
891 mutex_exit(&icmdp->cmd_mutex);
892 mutex_exit(&icp->conn_queue_active.mutex);
893 return (IDM_STATUS_SUCCESS);
894 }
895 mutex_exit(&icmdp->cmd_mutex);
896
897 /*
898 * Holding the pending/active queue locks across the
899 * iscsi_rx_data call later in this function may cause
900 * deadlock during fault injections. Instead remove
901 * the cmd from the active queue and release the locks.
902 * Then before returning or completing the command
903 * return the cmd to the active queue and reacquire
904 * the locks.
905 */
906 iscsi_dequeue_active_cmd(icp, icmdp);
907
908 mutex_exit(&icp->conn_queue_active.mutex);
909
910 /* shorthand some values */
911 bp = icmdp->cmd_un.scsi.bp;
912
913 /*
914 * some poorly behaved targets have been observed
915 * sending data-in pdu's during a write operation
916 */
917 if (bp != NULL) {
918 if (!(bp->b_flags & B_READ)) {
919 cmn_err(CE_WARN,
920 "iscsi connection(%u) protocol error - "
921 "received data response during write operation "
922 "itt:0x%x",
923 icp->conn_oid, idrhp->itt);
924 mutex_enter(&icp->conn_queue_active.mutex);
925 iscsi_enqueue_active_cmd(icp, icmdp);
926 mutex_exit(&icp->conn_queue_active.mutex);
927 return (IDM_STATUS_PROTOCOL_ERROR);
928 }
929 }
930
931 ibp = icmdp->cmd_un.scsi.ibp_ibuf;
932 if (ibp == NULL) {
933 /*
934 * After the check of bp above we *should* have a corresponding
935 * idm_buf_t (ibp). It's possible that the original call
936 * to idm_buf_alloc failed due to a pending connection state
937 * transition in which case this value can be NULL. It's
938 * highly unlikely that the connection would be shutting down
939 * *and* we manage to process a data response and get to this
940 * point in the code but just in case we should check for it.
941 * This isn't really a protocol error -- we are almost certainly
942 * closing the connection anyway so just return a generic error.
943 */
944 mutex_enter(&icp->conn_queue_active.mutex);
945 iscsi_enqueue_active_cmd(icp, icmdp);
946 mutex_exit(&icp->conn_queue_active.mutex);
947 return (IDM_STATUS_FAIL);
948 }
949
950 if (ic->ic_conn_flags & IDM_CONN_USE_SCOREBOARD) {
951 icmdp->cmd_un.scsi.data_transferred =
952 icmdp->cmd_itp->idt_rx_bytes;
953 } else {
954 icmdp->cmd_un.scsi.data_transferred = bp->b_bcount;
955 if (idrhp->flags & ISCSI_FLAG_CMD_UNDERFLOW) {
956 icmdp->cmd_un.scsi.data_transferred -=
957 ntohl(idrhp->residual_count);
958 }
959 }
960
961 ISCSI_IO_LOG(CE_NOTE, "DEBUG: rx_process_data_rsp: icp: %p pdu: %p "
962 "itt: %d ibp: %p icmdp: %p xfer_len: %lu transferred: %lu dlen: %u",
963 (void *)icp, (void *)pdu, idrhp->itt, (void *)bp, (void *)icmdp,
964 (ibp == NULL) ? 0 : ibp->idb_xfer_len,
965 icmdp->cmd_un.scsi.data_transferred,
966 n2h24(idrhp->dlength));
967
968 iscsi_task_cleanup(idrhp->opcode, icmdp);
969
970 iscsi_data_rsp_pkt(icmdp, idrhp);
971
972 mutex_enter(&icp->conn_queue_active.mutex);
973 iscsi_enqueue_active_cmd(icp, icmdp);
974 iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E3, isp);
975 mutex_exit(&icp->conn_queue_active.mutex);
976
977 return (IDM_STATUS_SUCCESS);
978 }
979
980 /*
981 * iscsi_rx_process_nop - Process a received nop. If nop is in response
982 * to a ping we sent update stats. If initiated by the target we need
983 * to response back to the target with a nop. Schedule the response.
984 */
985 /* ARGSUSED */
986 static idm_status_t
iscsi_rx_process_nop(idm_conn_t * ic,idm_pdu_t * pdu)987 iscsi_rx_process_nop(idm_conn_t *ic, idm_pdu_t *pdu)
988 {
989 iscsi_sess_t *isp = NULL;
990 iscsi_nop_in_hdr_t *inihp = (iscsi_nop_in_hdr_t *)pdu->isp_hdr;
991 iscsi_cmd_t *icmdp = NULL;
992 iscsi_conn_t *icp = ic->ic_handle;
993
994 if (icp->conn_expstatsn != ntohl(inihp->statsn)) {
995 cmn_err(CE_WARN, "iscsi connection(%u/%x) protocol error - "
996 "received status out of order itt:0x%x statsn:0x%x "
997 "expstatsn:0x%x", icp->conn_oid, inihp->opcode, inihp->itt,
998 ntohl(inihp->statsn), icp->conn_expstatsn);
999 return (IDM_STATUS_PROTOCOL_ERROR);
1000 }
1001 isp = icp->conn_sess;
1002 ASSERT(isp != NULL);
1003 mutex_enter(&isp->sess_queue_pending.mutex);
1004 mutex_enter(&icp->conn_queue_active.mutex);
1005 mutex_enter(&isp->sess_cmdsn_mutex);
1006 if (inihp->itt != ISCSI_RSVD_TASK_TAG) {
1007 if (!ISCSI_SUCCESS(iscsi_rx_process_itt_to_icmdp(
1008 isp, (iscsi_hdr_t *)inihp, &icmdp))) {
1009 cmn_err(CE_WARN, "iscsi connection(%u) protocol error "
1010 "- can not find cmd for itt:0x%x",
1011 icp->conn_oid, inihp->itt);
1012 mutex_exit(&isp->sess_cmdsn_mutex);
1013 mutex_exit(&icp->conn_queue_active.mutex);
1014 mutex_exit(&isp->sess_queue_pending.mutex);
1015 return (IDM_STATUS_PROTOCOL_ERROR);
1016 }
1017 }
1018
1019 /* update expcmdsn and maxcmdsn */
1020 iscsi_update_flow_control(isp, ntohl(inihp->maxcmdsn),
1021 ntohl(inihp->expcmdsn));
1022 mutex_exit(&isp->sess_cmdsn_mutex);
1023
1024 if ((inihp->itt != ISCSI_RSVD_TASK_TAG) &&
1025 (inihp->ttt == ISCSI_RSVD_TASK_TAG)) {
1026 /* This is the only type of nop that incs. the expstatsn */
1027 icp->conn_expstatsn++;
1028
1029 /*
1030 * This is a targets response to our nop
1031 */
1032 iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E3, isp);
1033 } else if (inihp->ttt != ISCSI_RSVD_TASK_TAG) {
1034 /*
1035 * Target requested a nop. Send one.
1036 */
1037 iscsi_handle_nop(icp, ISCSI_RSVD_TASK_TAG, inihp->ttt);
1038 } else {
1039 /*
1040 * This is a target-initiated ping that doesn't expect
1041 * a response; nothing to do except update our flow control
1042 * (which we do in all cases above).
1043 */
1044 /* EMPTY */
1045 }
1046 mutex_exit(&icp->conn_queue_active.mutex);
1047 mutex_exit(&isp->sess_queue_pending.mutex);
1048
1049 return (IDM_STATUS_SUCCESS);
1050 }
1051
1052
1053 /*
1054 * iscsi_rx_process_reject_rsp - The server rejected a PDU
1055 */
1056 static idm_status_t
iscsi_rx_process_reject_rsp(idm_conn_t * ic,idm_pdu_t * pdu)1057 iscsi_rx_process_reject_rsp(idm_conn_t *ic, idm_pdu_t *pdu)
1058 {
1059 iscsi_reject_rsp_hdr_t *irrhp = (iscsi_reject_rsp_hdr_t *)pdu->isp_hdr;
1060 iscsi_sess_t *isp = NULL;
1061 uint32_t dlength = 0;
1062 iscsi_hdr_t *old_ihp = NULL;
1063 iscsi_conn_t *icp = ic->ic_handle;
1064 uint8_t *data = pdu->isp_data;
1065 idm_status_t status = IDM_STATUS_SUCCESS;
1066 int i = 0;
1067
1068 ASSERT(data != NULL);
1069 isp = icp->conn_sess;
1070 ASSERT(isp != NULL);
1071
1072 /*
1073 * In RFC3720 section 10.17, this 4 bytes should be all 0xff.
1074 */
1075 for (i = 0; i < 4; i++) {
1076 if (irrhp->must_be_ff[i] != 0xff) {
1077 return (IDM_STATUS_PROTOCOL_ERROR);
1078 }
1079 }
1080 mutex_enter(&isp->sess_cmdsn_mutex);
1081
1082 if (icp->conn_expstatsn == ntohl(irrhp->statsn)) {
1083 icp->conn_expstatsn++;
1084 } else {
1085 cmn_err(CE_WARN, "iscsi connection(%u/%x) protocol error - "
1086 "received status out of order statsn:0x%x "
1087 "expstatsn:0x%x", icp->conn_oid, irrhp->opcode,
1088 ntohl(irrhp->statsn), icp->conn_expstatsn);
1089 mutex_exit(&isp->sess_cmdsn_mutex);
1090 return (IDM_STATUS_PROTOCOL_ERROR);
1091 }
1092 /* update expcmdsn and maxcmdsn */
1093 iscsi_update_flow_control(isp, ntohl(irrhp->maxcmdsn),
1094 ntohl(irrhp->expcmdsn));
1095
1096 mutex_exit(&isp->sess_cmdsn_mutex);
1097
1098 /* If we don't have the rejected header we can't do anything */
1099 dlength = n2h24(irrhp->dlength);
1100 if (dlength < sizeof (iscsi_hdr_t)) {
1101 return (IDM_STATUS_PROTOCOL_ERROR);
1102 }
1103
1104 /* map old ihp */
1105 old_ihp = (iscsi_hdr_t *)data;
1106
1107 switch (irrhp->reason) {
1108 /*
1109 * ISCSI_REJECT_IMM_CMD_REJECT - Immediate Command Reject
1110 * too many immediate commands (original cmd can be resent)
1111 */
1112 case ISCSI_REJECT_IMM_CMD_REJECT:
1113 /*
1114 * We have exceeded the server's capacity for outstanding
1115 * immediate commands. This must be a task management
1116 * command so try to find it in the abortingqueue and
1117 * complete it.
1118 */
1119 if (!(old_ihp->opcode & ISCSI_OP_IMMEDIATE)) {
1120 /* Rejecting IMM but old old_hdr wasn't IMM */
1121 return (IDM_STATUS_PROTOCOL_ERROR);
1122 }
1123
1124 /*
1125 * We only send NOP and TASK_MGT as IMM. All other
1126 * cases should be considered as a protocol error.
1127 */
1128 switch (old_ihp->opcode & ISCSI_OPCODE_MASK) {
1129 case ISCSI_OP_NOOP_OUT:
1130 /*
1131 * A ping was rejected - treat this like
1132 * ping response. The down side is we
1133 * didn't get an updated MaxCmdSn.
1134 */
1135 break;
1136 case ISCSI_OP_SCSI_TASK_MGT_MSG:
1137 status =
1138 iscsi_rx_process_rejected_tsk_mgt(ic, old_ihp);
1139 break;
1140 default:
1141 cmn_err(CE_WARN, "iscsi connection(%u) protocol error "
1142 "- received a reject for a command(0x%02x) not "
1143 "sent as an immediate", icp->conn_oid,
1144 old_ihp->opcode);
1145 status = IDM_STATUS_PROTOCOL_ERROR;
1146 break;
1147 }
1148 break;
1149
1150 /*
1151 * For the rest of the reject cases just use the general
1152 * hammer of dis/reconnecting. This will resolve all
1153 * noted issues although could be more graceful.
1154 */
1155 case ISCSI_REJECT_DATA_DIGEST_ERROR:
1156 case ISCSI_REJECT_CMD_BEFORE_LOGIN:
1157 case ISCSI_REJECT_SNACK_REJECT:
1158 case ISCSI_REJECT_PROTOCOL_ERROR:
1159 case ISCSI_REJECT_CMD_NOT_SUPPORTED:
1160 case ISCSI_REJECT_TASK_IN_PROGRESS:
1161 case ISCSI_REJECT_INVALID_DATA_ACK:
1162 case ISCSI_REJECT_INVALID_PDU_FIELD:
1163 case ISCSI_REJECT_LONG_OPERATION_REJECT:
1164 case ISCSI_REJECT_NEGOTIATION_RESET:
1165 default:
1166 cmn_err(CE_WARN, "iscsi connection(%u/%x) closing connection - "
1167 "target requested reason:0x%x",
1168 icp->conn_oid, irrhp->opcode, irrhp->reason);
1169 status = IDM_STATUS_PROTOCOL_ERROR;
1170 break;
1171 }
1172
1173 return (status);
1174 }
1175
1176
1177 /*
1178 * iscsi_rx_process_rejected_tsk_mgt -
1179 */
1180 /* ARGSUSED */
1181 static idm_status_t
iscsi_rx_process_rejected_tsk_mgt(idm_conn_t * ic,iscsi_hdr_t * old_ihp)1182 iscsi_rx_process_rejected_tsk_mgt(idm_conn_t *ic, iscsi_hdr_t *old_ihp)
1183 {
1184 iscsi_sess_t *isp = NULL;
1185 iscsi_cmd_t *icmdp = NULL;
1186 iscsi_conn_t *icp = ic->ic_handle;
1187
1188 isp = icp->conn_sess;
1189 ASSERT(old_ihp != NULL);
1190 ASSERT(isp != NULL);
1191
1192 mutex_enter(&icp->conn_queue_active.mutex);
1193 mutex_enter(&isp->sess_cmdsn_mutex);
1194 if (!ISCSI_SUCCESS(iscsi_rx_process_itt_to_icmdp(
1195 isp, old_ihp, &icmdp))) {
1196 mutex_exit(&isp->sess_cmdsn_mutex);
1197 mutex_exit(&icp->conn_queue_active.mutex);
1198 return (IDM_STATUS_PROTOCOL_ERROR);
1199 }
1200 mutex_exit(&isp->sess_cmdsn_mutex);
1201
1202 switch (icmdp->cmd_type) {
1203 case ISCSI_CMD_TYPE_ABORT:
1204 case ISCSI_CMD_TYPE_RESET:
1205 iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E4,
1206 icp->conn_sess);
1207 break;
1208 /* We don't send any other task mgr types */
1209 default:
1210 ASSERT(B_FALSE);
1211 break;
1212 }
1213 mutex_exit(&icp->conn_queue_active.mutex);
1214
1215 return (IDM_STATUS_SUCCESS);
1216 }
1217
1218
1219 /*
1220 * iscsi_rx_process_task_mgt_rsp -
1221 */
1222 /* ARGSUSED */
1223 static idm_status_t
iscsi_rx_process_task_mgt_rsp(idm_conn_t * ic,idm_pdu_t * pdu)1224 iscsi_rx_process_task_mgt_rsp(idm_conn_t *ic, idm_pdu_t *pdu)
1225 {
1226 iscsi_sess_t *isp = NULL;
1227 iscsi_scsi_task_mgt_rsp_hdr_t *istmrhp = NULL;
1228 iscsi_cmd_t *icmdp = NULL;
1229 iscsi_conn_t *icp = ic->ic_handle;
1230 idm_status_t status = IDM_STATUS_SUCCESS;
1231
1232 isp = icp->conn_sess;
1233 istmrhp = (iscsi_scsi_task_mgt_rsp_hdr_t *)pdu->isp_hdr;
1234
1235 mutex_enter(&icp->conn_queue_active.mutex);
1236 if ((status = iscsi_rx_chk(icp, isp, (iscsi_scsi_rsp_hdr_t *)istmrhp,
1237 &icmdp)) != IDM_STATUS_SUCCESS) {
1238 mutex_exit(&icp->conn_queue_active.mutex);
1239 return (status);
1240 }
1241
1242 switch (icmdp->cmd_type) {
1243 case ISCSI_CMD_TYPE_ABORT:
1244 case ISCSI_CMD_TYPE_RESET:
1245 switch (istmrhp->response) {
1246 case SCSI_TCP_TM_RESP_COMPLETE:
1247 /* success */
1248 iscsi_cmd_state_machine(icmdp,
1249 ISCSI_CMD_EVENT_E3, isp);
1250 break;
1251 case SCSI_TCP_TM_RESP_NO_TASK:
1252 /*
1253 * If the array no longer knows about
1254 * an ABORT RTT and we no longer have
1255 * a parent SCSI command it was just
1256 * completed, free this ABORT resource.
1257 * Otherwise FALLTHRU this will flag a
1258 * protocol problem.
1259 */
1260 if ((icmdp->cmd_type == ISCSI_CMD_TYPE_ABORT) &&
1261 (icmdp->cmd_un.abort.icmdp == NULL)) {
1262 iscsi_cmd_state_machine(icmdp,
1263 ISCSI_CMD_EVENT_E4, isp);
1264 break;
1265 }
1266 /* FALLTHRU */
1267 case SCSI_TCP_TM_RESP_REJECTED:
1268 /*
1269 * If the target rejects our reset task,
1270 * we should record the response and complete
1271 * this command with the result.
1272 */
1273 if (icmdp->cmd_type == ISCSI_CMD_TYPE_RESET) {
1274 icmdp->cmd_un.reset.response =
1275 istmrhp->response;
1276 iscsi_cmd_state_machine(icmdp,
1277 ISCSI_CMD_EVENT_E3, isp);
1278 break;
1279 }
1280 /* FALLTHRU */
1281 case SCSI_TCP_TM_RESP_NO_LUN:
1282 case SCSI_TCP_TM_RESP_TASK_ALLEGIANT:
1283 case SCSI_TCP_TM_RESP_NO_FAILOVER:
1284 case SCSI_TCP_TM_RESP_IN_PRGRESS:
1285 default:
1286 /*
1287 * Something is out of sync. Flush
1288 * active queues and resync the
1289 * the connection to try and recover
1290 * to a known state.
1291 */
1292 status = IDM_STATUS_PROTOCOL_ERROR;
1293 }
1294 break;
1295
1296 default:
1297 cmn_err(CE_WARN, "iscsi connection(%u) protocol error - "
1298 "received a task mgt response for a non-task mgt "
1299 "cmd itt:0x%x type:%d", icp->conn_oid, istmrhp->itt,
1300 icmdp->cmd_type);
1301 status = IDM_STATUS_PROTOCOL_ERROR;
1302 break;
1303 }
1304
1305 mutex_exit(&icp->conn_queue_active.mutex);
1306 return (status);
1307 }
1308
1309
1310 /*
1311 * iscsi_rx_process_logout_rsp -
1312 *
1313 */
1314 /* ARGSUSED */
1315 idm_status_t
iscsi_rx_process_logout_rsp(idm_conn_t * ic,idm_pdu_t * pdu)1316 iscsi_rx_process_logout_rsp(idm_conn_t *ic, idm_pdu_t *pdu)
1317 {
1318 iscsi_conn_t *icp = ic->ic_handle;
1319 iscsi_logout_rsp_hdr_t *ilrhp =
1320 (iscsi_logout_rsp_hdr_t *)pdu->isp_hdr;
1321 iscsi_cmd_t *icmdp = NULL;
1322 iscsi_sess_t *isp;
1323 idm_status_t status = IDM_STATUS_SUCCESS;
1324
1325 isp = icp->conn_sess;
1326
1327 if (icp->conn_expstatsn != ntohl(ilrhp->statsn)) {
1328 cmn_err(CE_WARN, "iscsi connection(%u/%x) protocol error - "
1329 "received status out of order itt:0x%x statsn:0x%x "
1330 "expstatsn:0x%x", icp->conn_oid, ilrhp->opcode, ilrhp->itt,
1331 ntohl(ilrhp->statsn), icp->conn_expstatsn);
1332 return (IDM_STATUS_PROTOCOL_ERROR);
1333 }
1334
1335 mutex_enter(&icp->conn_queue_active.mutex);
1336 mutex_enter(&isp->sess_cmdsn_mutex);
1337 if (ilrhp->itt != ISCSI_RSVD_TASK_TAG) {
1338 if (!ISCSI_SUCCESS(iscsi_rx_process_itt_to_icmdp(
1339 isp, (iscsi_hdr_t *)ilrhp, &icmdp))) {
1340 mutex_exit(&isp->sess_cmdsn_mutex);
1341 mutex_exit(&icp->conn_queue_active.mutex);
1342 return (IDM_STATUS_PROTOCOL_ERROR);
1343 }
1344 }
1345
1346 /* update expcmdsn and maxcmdsn */
1347 iscsi_update_flow_control(isp, ntohl(ilrhp->maxcmdsn),
1348 ntohl(ilrhp->expcmdsn));
1349 mutex_exit(&isp->sess_cmdsn_mutex);
1350
1351 ISCSI_IO_LOG(CE_NOTE,
1352 "DEBUG: iscsi_rx_process_logout_rsp: response: %d",
1353 ilrhp->response);
1354 switch (ilrhp->response) {
1355 case ISCSI_LOGOUT_CID_NOT_FOUND:
1356 /*
1357 * If the target doesn't know about our connection
1358 * then we can consider our self disconnected.
1359 */
1360 /* FALLTHRU */
1361 case ISCSI_LOGOUT_RECOVERY_UNSUPPORTED:
1362 /*
1363 * We don't support ErrorRecovery levels above 0
1364 * currently so consider this success.
1365 */
1366 /* FALLTHRU */
1367 case ISCSI_LOGOUT_CLEANUP_FAILED:
1368 /*
1369 * per spec. "cleanup failed for various reasons."
1370 * Although those various reasons are undefined.
1371 * Not sure what to do here. So fake success,
1372 * which will disconnect the connection.
1373 */
1374 /* FALLTHRU */
1375 case ISCSI_LOGOUT_SUCCESS:
1376 iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E3, isp);
1377 mutex_exit(&icp->conn_queue_active.mutex);
1378 iscsi_drop_conn_cleanup(icp);
1379 break;
1380 default:
1381 mutex_exit(&icp->conn_queue_active.mutex);
1382 status = IDM_STATUS_PROTOCOL_ERROR;
1383 break;
1384
1385 }
1386 return (status);
1387 }
1388
1389 /*
1390 * iscsi_rx_process_async_rsp
1391 *
1392 */
1393 /* ARGSUSED */
1394 static idm_status_t
iscsi_rx_process_async_rsp(idm_conn_t * ic,idm_pdu_t * pdu)1395 iscsi_rx_process_async_rsp(idm_conn_t *ic, idm_pdu_t *pdu)
1396 {
1397 iscsi_conn_t *icp = ic->ic_handle;
1398 iscsi_sess_t *isp = icp->conn_sess;
1399 idm_status_t rval = IDM_STATUS_SUCCESS;
1400 iscsi_task_t *itp;
1401 iscsi_async_evt_hdr_t *iaehp =
1402 (iscsi_async_evt_hdr_t *)pdu->isp_hdr;
1403
1404 ASSERT(icp != NULL);
1405 ASSERT(pdu != NULL);
1406 ASSERT(isp != NULL);
1407
1408 mutex_enter(&isp->sess_cmdsn_mutex);
1409 if (icp->conn_expstatsn == ntohl(iaehp->statsn)) {
1410 icp->conn_expstatsn++;
1411 } else {
1412 cmn_err(CE_WARN, "iscsi connection(%u) protocol error - "
1413 "received status out of order statsn:0x%x "
1414 "expstatsn:0x%x", icp->conn_oid,
1415 ntohl(iaehp->statsn), icp->conn_expstatsn);
1416 mutex_exit(&isp->sess_cmdsn_mutex);
1417 return (IDM_STATUS_PROTOCOL_ERROR);
1418 }
1419 mutex_exit(&isp->sess_cmdsn_mutex);
1420
1421 switch (iaehp->async_event) {
1422 case ISCSI_ASYNC_EVENT_SCSI_EVENT:
1423 /*
1424 * SCSI asynchronous event is reported in
1425 * the sense data. Sense data that accompanies
1426 * the report in the data segment identifies the
1427 * condition. If the target supports SCSI
1428 * asynchronous events reporting (see [SAM2])
1429 * as indicated in the stardard INQUIRY data
1430 * (see [SPC3]), its use may be enabled by
1431 * parameters in the SCSI control mode page
1432 * (see [SPC3]).
1433 *
1434 * T-10 has removed SCSI asunchronous events
1435 * from the standard. Although we have seen
1436 * a couple targets still spending these requests.
1437 * Those targets were specifically sending them
1438 * for notification of a LUN/Volume change
1439 * (ex. LUN addition/removal). Fire the enumeration
1440 * to handle the change.
1441 */
1442 if (isp->sess_type == ISCSI_SESS_TYPE_NORMAL) {
1443 rw_enter(&isp->sess_state_rwlock, RW_READER);
1444 if (isp->sess_state == ISCSI_SESS_STATE_LOGGED_IN) {
1445 (void) iscsi_sess_enum_request(isp, B_FALSE,
1446 isp->sess_state_event_count);
1447 }
1448 rw_exit(&isp->sess_state_rwlock);
1449 }
1450 break;
1451
1452 case ISCSI_ASYNC_EVENT_REQUEST_LOGOUT:
1453 /*
1454 * We've been asked to logout by the target --
1455 * we need to treat this differently from a normal logout
1456 * due to a discovery failure. Normal logouts result in
1457 * an N3 event to the session state machine and an offline
1458 * of the lun. In this case we want to put the connection
1459 * into "failed" state and generate N5 to the session state
1460 * machine since the initiator logged out at the target's
1461 * request. To track this we set a flag indicating we
1462 * received this async logout request from the tharget
1463 */
1464 mutex_enter(&icp->conn_state_mutex);
1465 icp->conn_async_logout = B_TRUE;
1466 mutex_exit(&icp->conn_state_mutex);
1467
1468 /* Hold is released in iscsi_handle_logout. */
1469 idm_conn_hold(ic);
1470
1471 /* Target has requested this connection to logout. */
1472 itp = kmem_zalloc(sizeof (iscsi_task_t), KM_SLEEP);
1473 itp->t_arg = icp;
1474 itp->t_blocking = B_FALSE;
1475 if (ddi_taskq_dispatch(isp->sess_login_taskq,
1476 (void(*)())iscsi_logout_start, itp, DDI_SLEEP) !=
1477 DDI_SUCCESS) {
1478 idm_conn_rele(ic);
1479 /* Disconnect if we couldn't dispatch the task */
1480 idm_ini_conn_disconnect(ic);
1481 }
1482 break;
1483
1484 case ISCSI_ASYNC_EVENT_DROPPING_CONNECTION:
1485 /*
1486 * Target is going to drop our connection.
1487 * param1 - CID which will be dropped.
1488 * param2 - Min time to reconnect.
1489 * param3 - Max time to reconnect.
1490 *
1491 * For now just let fail as another disconnect.
1492 *
1493 * MC/S Once we support > 1 connections then
1494 * we need to check the CID and drop that
1495 * specific connection.
1496 */
1497 iscsi_conn_set_login_min_max(icp, iaehp->param2,
1498 iaehp->param3);
1499 idm_ini_conn_disconnect(ic);
1500 break;
1501
1502 case ISCSI_ASYNC_EVENT_DROPPING_ALL_CONNECTIONS:
1503 /*
1504 * Target is going to drop ALL connections.
1505 * param2 - Min time to reconnect.
1506 * param3 - Max time to reconnect.
1507 *
1508 * For now just let fail as anyother disconnect.
1509 *
1510 * MC/S Once we support more than > 1 connections
1511 * then we need to drop all connections on the
1512 * session.
1513 */
1514 iscsi_conn_set_login_min_max(icp, iaehp->param2,
1515 iaehp->param3);
1516 idm_ini_conn_disconnect(ic);
1517 break;
1518
1519 case ISCSI_ASYNC_EVENT_PARAM_NEGOTIATION:
1520 /*
1521 * Target requests parameter negotiation
1522 * on this connection.
1523 *
1524 * The initiator must honor this request. For
1525 * now we will request a logout. We can't
1526 * just ignore this or it might force corruption?
1527 */
1528
1529 /* Hold is released in iscsi_handle_logout */
1530 idm_conn_hold(ic);
1531 itp = kmem_zalloc(sizeof (iscsi_task_t), KM_SLEEP);
1532 itp->t_arg = icp;
1533 itp->t_blocking = B_FALSE;
1534 if (ddi_taskq_dispatch(isp->sess_login_taskq,
1535 (void(*)())iscsi_logout_start, itp, DDI_SLEEP) !=
1536 DDI_SUCCESS) {
1537 /* Disconnect if we couldn't dispatch the task */
1538 idm_conn_rele(ic);
1539 idm_ini_conn_disconnect(ic);
1540 }
1541 break;
1542
1543 case ISCSI_ASYNC_EVENT_VENDOR_SPECIFIC:
1544 /*
1545 * We currently don't handle any vendor
1546 * specific async events. So just ignore
1547 * the request.
1548 */
1549 idm_ini_conn_disconnect(ic);
1550 break;
1551 default:
1552 rval = IDM_STATUS_PROTOCOL_ERROR;
1553 }
1554
1555 return (rval);
1556 }
1557
1558 /*
1559 * iscsi_rx_process_text_rsp - processes iSCSI text response. It sets
1560 * the cmd_result field of the command data structure with the actual
1561 * status value instead of returning the status value. The return value
1562 * is SUCCESS in order to let iscsi_handle_text control the operation of
1563 * a text request.
1564 * Text requests are a handled a little different than other types of
1565 * iSCSI commands because the initiator sends additional empty text requests
1566 * in order to obtain the remaining responses required to complete the
1567 * request. iscsi_handle_text controls the operation of text request, while
1568 * iscsi_rx_process_text_rsp just process the current response.
1569 */
1570 static idm_status_t
iscsi_rx_process_text_rsp(idm_conn_t * ic,idm_pdu_t * pdu)1571 iscsi_rx_process_text_rsp(idm_conn_t *ic, idm_pdu_t *pdu)
1572 {
1573 iscsi_sess_t *isp = NULL;
1574 iscsi_text_rsp_hdr_t *ithp =
1575 (iscsi_text_rsp_hdr_t *)pdu->isp_hdr;
1576 iscsi_conn_t *icp = ic->ic_handle;
1577 iscsi_cmd_t *icmdp = NULL;
1578 boolean_t final = B_FALSE;
1579 uint32_t data_len;
1580 uint8_t *data = pdu->isp_data;
1581 idm_status_t rval;
1582
1583 isp = icp->conn_sess;
1584
1585 mutex_enter(&icp->conn_queue_active.mutex);
1586 if ((rval = iscsi_rx_chk(icp, isp, (iscsi_scsi_rsp_hdr_t *)ithp,
1587 &icmdp)) != IDM_STATUS_SUCCESS) {
1588 mutex_exit(&icp->conn_queue_active.mutex);
1589 return (rval);
1590 }
1591
1592 /* update local final response flag */
1593 if (ithp->flags & ISCSI_FLAG_FINAL) {
1594 final = B_TRUE;
1595 }
1596
1597 /*
1598 * validate received TTT value. RFC3720 specifies the following:
1599 * - F bit set to 1 MUST have a reserved TTT value 0xffffffff
1600 * - F bit set to 0 MUST have a non-reserved TTT value !0xffffffff
1601 * In addition, the received TTT value must not change between
1602 * responses of a long text response
1603 */
1604 if (((final == B_TRUE) && (ithp->ttt != ISCSI_RSVD_TASK_TAG)) ||
1605 ((final == B_FALSE) && (ithp->ttt == ISCSI_RSVD_TASK_TAG))) {
1606 icmdp->cmd_result = ISCSI_STATUS_PROTOCOL_ERROR;
1607 icmdp->cmd_un.text.stage = ISCSI_CMD_TEXT_FINAL_RSP;
1608 mutex_exit(&icp->conn_queue_active.mutex);
1609 cmn_err(CE_WARN, "iscsi connection(%u) protocol error - "
1610 "received text response with invalid flags:0x%x or "
1611 "ttt:0x%x", icp->conn_oid, ithp->flags, ithp->itt);
1612 return (IDM_STATUS_PROTOCOL_ERROR);
1613 }
1614
1615 if ((icmdp->cmd_un.text.stage == ISCSI_CMD_TEXT_INITIAL_REQ) &&
1616 (ithp->ttt == ISCSI_RSVD_TASK_TAG) &&
1617 (final == B_FALSE)) {
1618 /* TTT should have matched reserved value */
1619 icmdp->cmd_result = ISCSI_STATUS_PROTOCOL_ERROR;
1620 icmdp->cmd_un.text.stage = ISCSI_CMD_TEXT_FINAL_RSP;
1621 mutex_exit(&icp->conn_queue_active.mutex);
1622 cmn_err(CE_WARN, "iscsi connection(%u) protocol "
1623 "error - received text response with invalid "
1624 "ttt:0x%x", icp->conn_oid, ithp->ttt);
1625 return (IDM_STATUS_PROTOCOL_ERROR);
1626 }
1627
1628 /*
1629 * If this is first response, save away TTT value for later use
1630 * in a long text request/response sequence
1631 */
1632 if (icmdp->cmd_un.text.stage == ISCSI_CMD_TEXT_INITIAL_REQ) {
1633 icmdp->cmd_un.text.ttt = ithp->ttt;
1634 }
1635
1636 data_len = ntoh24(ithp->dlength);
1637
1638 /* check whether enough buffer available to copy data */
1639 if ((icmdp->cmd_un.text.total_rx_len + data_len) >
1640 icmdp->cmd_un.text.buf_len) {
1641 icmdp->cmd_un.text.total_rx_len += data_len;
1642 icmdp->cmd_result = ISCSI_STATUS_DATA_OVERFLOW;
1643 /*
1644 * DATA_OVERFLOW will result in a SUCCESS return so that
1645 * iscsi_handle_text can continue to obtain the remaining
1646 * text response if needed.
1647 */
1648 } else {
1649 char *buf_data = (icmdp->cmd_un.text.buf +
1650 icmdp->cmd_un.text.offset);
1651
1652 bcopy(data, buf_data, data_len);
1653 icmdp->cmd_un.text.offset += data_len;
1654 icmdp->cmd_un.text.total_rx_len += data_len;
1655 icmdp->cmd_result = ISCSI_STATUS_SUCCESS;
1656 bcopy(ithp->rsvd4, icmdp->cmd_un.text.lun,
1657 sizeof (icmdp->cmd_un.text.lun));
1658 }
1659
1660 /* update stage */
1661 if (final == B_TRUE) {
1662 icmdp->cmd_un.text.stage = ISCSI_CMD_TEXT_FINAL_RSP;
1663 } else {
1664 icmdp->cmd_un.text.stage = ISCSI_CMD_TEXT_CONTINUATION;
1665 }
1666
1667 iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E3, isp);
1668 mutex_exit(&icp->conn_queue_active.mutex);
1669 return (IDM_STATUS_SUCCESS);
1670 }
1671
1672 /*
1673 * iscsi_rx_process_scsi_itt_to_icmdp - Lookup itt using IDM to find matching
1674 * icmdp. Verify itt in hdr and icmdp are the same.
1675 */
1676 static iscsi_status_t
iscsi_rx_process_scsi_itt_to_icmdp(iscsi_sess_t * isp,idm_conn_t * ic,iscsi_scsi_rsp_hdr_t * ihp,iscsi_cmd_t ** icmdp)1677 iscsi_rx_process_scsi_itt_to_icmdp(iscsi_sess_t *isp, idm_conn_t *ic,
1678 iscsi_scsi_rsp_hdr_t *ihp, iscsi_cmd_t **icmdp)
1679 {
1680 idm_task_t *itp;
1681
1682 ASSERT(isp != NULL);
1683 ASSERT(ihp != NULL);
1684 ASSERT(icmdp != NULL);
1685 ASSERT(mutex_owned(&isp->sess_cmdsn_mutex));
1686 itp = idm_task_find_and_complete(ic, ihp->itt, ISCSI_INI_TASK_TTT);
1687 if (itp == NULL) {
1688 cmn_err(CE_WARN, "iscsi session(%u) protocol error - "
1689 "received unknown itt:0x%x - protocol error",
1690 isp->sess_oid, ihp->itt);
1691 return (ISCSI_STATUS_INTERNAL_ERROR);
1692 }
1693 *icmdp = itp->idt_private;
1694
1695 idm_task_rele(itp);
1696
1697 return (ISCSI_STATUS_SUCCESS);
1698
1699 }
1700
1701 /*
1702 * iscsi_rx_process_itt_to_icmdp - Lookup itt in the session's
1703 * cmd table to find matching icmdp. Verify itt in hdr and
1704 * icmdp are the same.
1705 */
1706 static iscsi_status_t
iscsi_rx_process_itt_to_icmdp(iscsi_sess_t * isp,iscsi_hdr_t * ihp,iscsi_cmd_t ** icmdp)1707 iscsi_rx_process_itt_to_icmdp(iscsi_sess_t *isp, iscsi_hdr_t *ihp,
1708 iscsi_cmd_t **icmdp)
1709 {
1710 int cmd_table_idx = 0;
1711
1712 ASSERT(isp != NULL);
1713 ASSERT(ihp != NULL);
1714 ASSERT(icmdp != NULL);
1715 ASSERT(mutex_owned(&isp->sess_cmdsn_mutex));
1716
1717 /* try to find an associated iscsi_pkt */
1718 cmd_table_idx = (ihp->itt - IDM_TASKIDS_MAX) % ISCSI_CMD_TABLE_SIZE;
1719 if (isp->sess_cmd_table[cmd_table_idx] == NULL) {
1720 cmn_err(CE_WARN, "iscsi session(%u) protocol error - "
1721 "received unknown itt:0x%x - protocol error",
1722 isp->sess_oid, ihp->itt);
1723 return (ISCSI_STATUS_INTERNAL_ERROR);
1724 }
1725
1726 /* verify itt */
1727 if (isp->sess_cmd_table[cmd_table_idx]->cmd_itt != ihp->itt) {
1728 cmn_err(CE_WARN, "iscsi session(%u) received itt:0x%x "
1729 " which is out of sync with itt:0x%x", isp->sess_oid,
1730 ihp->itt, isp->sess_cmd_table[cmd_table_idx]->cmd_itt);
1731 return (ISCSI_STATUS_INTERNAL_ERROR);
1732 }
1733
1734 /* ensure that icmdp is still in Active state */
1735 if (isp->sess_cmd_table[cmd_table_idx]->cmd_state !=
1736 ISCSI_CMD_STATE_ACTIVE) {
1737 cmn_err(CE_WARN, "iscsi session(%u) received itt:0x%x "
1738 "but icmdp (%p) is not in active state",
1739 isp->sess_oid, ihp->itt,
1740 (void *)isp->sess_cmd_table[cmd_table_idx]);
1741 return (ISCSI_STATUS_INTERNAL_ERROR);
1742 }
1743
1744 /* make sure this is a SCSI cmd */
1745 *icmdp = isp->sess_cmd_table[cmd_table_idx];
1746
1747 return (ISCSI_STATUS_SUCCESS);
1748 }
1749
1750 /*
1751 * +--------------------------------------------------------------------+
1752 * | End of protocol receive routines |
1753 * +--------------------------------------------------------------------+
1754 */
1755
1756 /*
1757 * +--------------------------------------------------------------------+
1758 * | Beginning of protocol send routines |
1759 * +--------------------------------------------------------------------+
1760 */
1761
1762
1763 /*
1764 * iscsi_tx_thread - This thread is the driving point for all
1765 * iSCSI PDUs after login. No PDUs should call idm_pdu_tx()
1766 * directly they should be funneled through iscsi_tx_thread.
1767 */
1768 void
iscsi_tx_thread(iscsi_thread_t * thread,void * arg)1769 iscsi_tx_thread(iscsi_thread_t *thread, void *arg)
1770 {
1771 iscsi_conn_t *icp = (iscsi_conn_t *)arg;
1772 iscsi_sess_t *isp = NULL;
1773 iscsi_cmd_t *icmdp = NULL;
1774 clock_t tout;
1775 int ret = 1;
1776
1777 ASSERT(icp != NULL);
1778 isp = icp->conn_sess;
1779 ASSERT(isp != NULL);
1780 ASSERT(thread != NULL);
1781 ASSERT(thread->signature == SIG_ISCSI_THREAD);
1782
1783 tout = SEC_TO_TICK(1);
1784 /*
1785 * Transfer icmdps until shutdown by owning session.
1786 */
1787 while (ret != 0) {
1788
1789 isp->sess_window_open = B_TRUE;
1790 /*
1791 * While the window is open, there are commands available
1792 * to send and the session state allows those commands to
1793 * be sent try to transfer them.
1794 */
1795 mutex_enter(&isp->sess_queue_pending.mutex);
1796 while ((isp->sess_window_open == B_TRUE) &&
1797 ((icmdp = isp->sess_queue_pending.head) != NULL)) {
1798 if (((icmdp->cmd_type != ISCSI_CMD_TYPE_SCSI) &&
1799 (ISCSI_CONN_STATE_FULL_FEATURE(icp->conn_state))) ||
1800 (icp->conn_state == ISCSI_CONN_STATE_LOGGED_IN)) {
1801
1802 /* update command with this connection info */
1803 icmdp->cmd_conn = icp;
1804 /* attempt to send this command */
1805 iscsi_cmd_state_machine(icmdp,
1806 ISCSI_CMD_EVENT_E2, isp);
1807
1808 ASSERT(!mutex_owned(
1809 &isp->sess_queue_pending.mutex));
1810 mutex_enter(&isp->sess_queue_pending.mutex);
1811 } else {
1812 while (icmdp != NULL) {
1813 if ((icmdp->cmd_type !=
1814 ISCSI_CMD_TYPE_SCSI) &&
1815 (ISCSI_CONN_STATE_FULL_FEATURE
1816 (icp->conn_state) != B_TRUE)) {
1817 icmdp->cmd_misc_flags |=
1818 ISCSI_CMD_MISCFLAG_STUCK;
1819 } else if (icp->conn_state !=
1820 ISCSI_CONN_STATE_LOGGED_IN) {
1821 icmdp->cmd_misc_flags |=
1822 ISCSI_CMD_MISCFLAG_STUCK;
1823 }
1824 icmdp = icmdp->cmd_next;
1825 }
1826 break;
1827 }
1828 }
1829 mutex_exit(&isp->sess_queue_pending.mutex);
1830
1831 /*
1832 * Go to sleep until there is something new
1833 * to process (awoken via cv_boardcast).
1834 * Or the timer goes off.
1835 */
1836 ret = iscsi_thread_wait(thread, tout);
1837 }
1838
1839 }
1840
1841
1842 /*
1843 * iscsi_tx_cmd - transfers icmdp across wire as iscsi pdu
1844 *
1845 * Just prior to sending the command to the networking layer the
1846 * pending queue lock will be dropped. At this point only local
1847 * resources will be used, not the icmdp. Holding the queue lock
1848 * across the networking call can lead to a hang. (This is due
1849 * to the the target driver and networking layers competing use
1850 * of the timeout() resources and the queue lock being held for
1851 * both sides.) Upon the completion of this command the lock
1852 * will have been re-acquired.
1853 */
1854 iscsi_status_t
iscsi_tx_cmd(iscsi_sess_t * isp,iscsi_cmd_t * icmdp)1855 iscsi_tx_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp)
1856 {
1857 iscsi_status_t rval = ISCSI_STATUS_INTERNAL_ERROR;
1858
1859 ASSERT(isp != NULL);
1860 ASSERT(icmdp != NULL);
1861
1862 /* transfer specific command type */
1863 switch (icmdp->cmd_type) {
1864 case ISCSI_CMD_TYPE_SCSI:
1865 rval = iscsi_tx_scsi(isp, icmdp);
1866 break;
1867 case ISCSI_CMD_TYPE_NOP:
1868 rval = iscsi_tx_nop(isp, icmdp);
1869 break;
1870 case ISCSI_CMD_TYPE_ABORT:
1871 rval = iscsi_tx_abort(isp, icmdp);
1872 break;
1873 case ISCSI_CMD_TYPE_RESET:
1874 rval = iscsi_tx_reset(isp, icmdp);
1875 break;
1876 case ISCSI_CMD_TYPE_LOGOUT:
1877 rval = iscsi_tx_logout(isp, icmdp);
1878 break;
1879 case ISCSI_CMD_TYPE_TEXT:
1880 rval = iscsi_tx_text(isp, icmdp);
1881 break;
1882 default:
1883 cmn_err(CE_WARN, "iscsi_tx_cmd: invalid cmdtype: %d",
1884 icmdp->cmd_type);
1885 ASSERT(FALSE);
1886 }
1887
1888 ASSERT(!mutex_owned(&isp->sess_queue_pending.mutex));
1889 return (rval);
1890 }
1891
1892 /*
1893 * a variable length cdb can be up to 16K, but we obviously don't want
1894 * to put that on the stack; go with 200 bytes; if we get something
1895 * bigger than that we will kmem_alloc a buffer
1896 */
1897 #define DEF_CDB_LEN 200
1898
1899 /*
1900 * given the size of the cdb, return how many bytes the header takes,
1901 * which is the sizeof addl_hdr_t + the CDB size, minus the 16 bytes
1902 * stored in the basic header, minus sizeof (ahs_extscb)
1903 */
1904 #define ADDLHDRSZ(x) (sizeof (iscsi_addl_hdr_t) + (x) - \
1905 16 - 4)
1906
1907 static void
iscsi_tx_init_hdr(iscsi_sess_t * isp,iscsi_conn_t * icp,iscsi_text_hdr_t * ihp,int opcode,iscsi_cmd_t * icmdp)1908 iscsi_tx_init_hdr(iscsi_sess_t *isp, iscsi_conn_t *icp,
1909 iscsi_text_hdr_t *ihp, int opcode, iscsi_cmd_t *icmdp)
1910 {
1911 ihp->opcode = opcode;
1912 ihp->itt = icmdp->cmd_itt;
1913 mutex_enter(&isp->sess_cmdsn_mutex);
1914 icmdp->cmd_sn = isp->sess_cmdsn;
1915 ihp->cmdsn = htonl(isp->sess_cmdsn);
1916 isp->sess_cmdsn++;
1917 mutex_exit(&isp->sess_cmdsn_mutex);
1918 ihp->expstatsn = htonl(icp->conn_expstatsn);
1919 icp->conn_laststatsn = icp->conn_expstatsn;
1920 }
1921
1922
1923 static void
iscsi_tx_scsi_data(iscsi_cmd_t * icmdp,iscsi_scsi_cmd_hdr_t * ihp,iscsi_conn_t * icp,idm_pdu_t * pdu)1924 iscsi_tx_scsi_data(iscsi_cmd_t *icmdp, iscsi_scsi_cmd_hdr_t *ihp,
1925 iscsi_conn_t *icp, idm_pdu_t *pdu)
1926 {
1927 struct buf *bp = NULL;
1928 size_t buflen = 0;
1929 uint32_t first_burst_length = 0;
1930 struct scsi_pkt *pkt;
1931
1932 pkt = icmdp->cmd_un.scsi.pkt;
1933 bp = icmdp->cmd_un.scsi.bp;
1934 if ((bp != NULL) && bp->b_bcount) {
1935 buflen = bp->b_bcount;
1936 first_burst_length =
1937 icp->conn_params.first_burst_length;
1938
1939 if (bp->b_flags & B_READ) {
1940 ihp->flags = ISCSI_FLAG_FINAL;
1941 /*
1942 * fix problem where OS sends bp (B_READ &
1943 * b_bcount!=0) for a TUR or START_STOP.
1944 * (comment came from cisco code.)
1945 */
1946 if ((pkt->pkt_cdbp[0] != SCMD_TEST_UNIT_READY) &&
1947 (pkt->pkt_cdbp[0] != SCMD_START_STOP)) {
1948 ihp->flags |= ISCSI_FLAG_CMD_READ;
1949 ihp->data_length = htonl(buflen);
1950 }
1951 } else {
1952 ihp->flags = ISCSI_FLAG_CMD_WRITE;
1953 /*
1954 * FinalBit on the the iSCSI PDU denotes this
1955 * is the last PDU in the sequence.
1956 *
1957 * initial_r2t = true means R2T is required
1958 * for additional PDU, so there will be no more
1959 * unsolicited PDUs following
1960 */
1961 if (icp->conn_params.initial_r2t) {
1962 ihp->flags |= ISCSI_FLAG_FINAL;
1963 }
1964
1965 /* Check if we should send ImmediateData */
1966 if (icp->conn_params.immediate_data) {
1967 pdu->isp_data =
1968 (uint8_t *)icmdp->
1969 cmd_un.scsi.bp->b_un.b_addr;
1970
1971 pdu->isp_datalen = MIN(MIN(buflen,
1972 first_burst_length),
1973 icmdp->cmd_conn->conn_params.
1974 max_xmit_data_seg_len);
1975
1976 /*
1977 * if everything fits immediate, or
1978 * we can send all burst data immediate
1979 * (not unsol), set F
1980 */
1981 /*
1982 * XXX This doesn't look right -- it's not
1983 * clear how we can handle transmitting
1984 * any unsolicited data. It looks like
1985 * we only support immediate data. So what
1986 * happens if we don't set ISCSI_FLAG_FINAL?
1987 *
1988 * Unless there's magic code somewhere that
1989 * is sending the remaining PDU's we should
1990 * simply set ISCSI_FLAG_FINAL and forget
1991 * about sending unsolicited data. The big
1992 * win is the immediate data anyway for small
1993 * PDU's.
1994 */
1995 if ((pdu->isp_datalen == buflen) ||
1996 (pdu->isp_datalen == first_burst_length)) {
1997 ihp->flags |= ISCSI_FLAG_FINAL;
1998 }
1999
2000 hton24(ihp->dlength, pdu->isp_datalen);
2001 }
2002 /* total data transfer length */
2003 ihp->data_length = htonl(buflen);
2004 }
2005 } else {
2006 ihp->flags = ISCSI_FLAG_FINAL;
2007 }
2008 icmdp->cmd_un.scsi.data_transferred += pdu->isp_datalen;
2009 /* XXX How is this different from the code above? */
2010 /* will idm send the next data command up to burst length? */
2011 /* send the burstlen if we haven't sent immediate data */
2012 /* CRM: should idm send difference min(buflen, first_burst) and imm? */
2013 /* (MIN(first_burst_length, buflen) - imdata > 0) */
2014 /* CRM_LATER: change this to generate unsolicited pdu */
2015 if ((buflen > 0) &&
2016 ((bp->b_flags & B_READ) == 0) &&
2017 (icp->conn_params.initial_r2t == 0) &&
2018 pdu->isp_datalen == 0) {
2019
2020 pdu->isp_datalen = MIN(first_burst_length, buflen);
2021 if ((pdu->isp_datalen == buflen) ||
2022 (pdu->isp_datalen == first_burst_length)) {
2023 ihp->flags |= ISCSI_FLAG_FINAL;
2024 }
2025 pdu->isp_data = (uint8_t *)icmdp->cmd_un.scsi.bp->b_un.b_addr;
2026 hton24(ihp->dlength, pdu->isp_datalen);
2027 }
2028 }
2029
2030 static void
iscsi_tx_scsi_init_pkt(iscsi_cmd_t * icmdp,iscsi_scsi_cmd_hdr_t * ihp)2031 iscsi_tx_scsi_init_pkt(iscsi_cmd_t *icmdp, iscsi_scsi_cmd_hdr_t *ihp)
2032 {
2033 struct scsi_pkt *pkt;
2034
2035 pkt = icmdp->cmd_un.scsi.pkt;
2036 pkt->pkt_state = (STATE_GOT_BUS | STATE_GOT_TARGET);
2037 pkt->pkt_reason = CMD_INCOMPLETE;
2038
2039 /* tagged queuing */
2040 if (pkt->pkt_flags & FLAG_HTAG) {
2041 ihp->flags |= ISCSI_ATTR_HEAD_OF_QUEUE;
2042 } else if (pkt->pkt_flags & FLAG_OTAG) {
2043 ihp->flags |= ISCSI_ATTR_ORDERED;
2044 } else if (pkt->pkt_flags & FLAG_STAG) {
2045 ihp->flags |= ISCSI_ATTR_SIMPLE;
2046 } else {
2047 /* ihp->flags |= ISCSI_ATTR_UNTAGGED; */
2048 /* EMPTY */
2049 }
2050
2051 /* iscsi states lun is based on spc.2 */
2052 ISCSI_LUN_BYTE_COPY(ihp->lun, icmdp->cmd_un.scsi.lun);
2053
2054 if (icmdp->cmd_un.scsi.cmdlen <= 16) {
2055 /* copy the SCSI Command Block into the PDU */
2056 bcopy(pkt->pkt_cdbp, ihp->scb,
2057 icmdp->cmd_un.scsi.cmdlen);
2058 } else {
2059 iscsi_addl_hdr_t *iahp;
2060
2061 iahp = (iscsi_addl_hdr_t *)ihp;
2062
2063 ihp->hlength = (ADDLHDRSZ(icmdp->cmd_un.scsi.cmdlen) -
2064 sizeof (iscsi_scsi_cmd_hdr_t) + 3) / 4;
2065 iahp->ahs_hlen_hi = 0;
2066 iahp->ahs_hlen_lo = (icmdp->cmd_un.scsi.cmdlen - 15);
2067 iahp->ahs_key = 0x01;
2068 iahp->ahs_resv = 0;
2069 bcopy(pkt->pkt_cdbp, ihp->scb, 16);
2070 bcopy(((char *)pkt->pkt_cdbp) + 16, &iahp->ahs_extscb[0],
2071 icmdp->cmd_un.scsi.cmdlen);
2072 }
2073
2074 /*
2075 * Update all values before transfering.
2076 * We should never touch the icmdp after
2077 * transfering if there is no more data
2078 * to send. The only case the idm_pdu_tx()
2079 * will fail is a on a connection disconnect
2080 * in that case the command will be flushed.
2081 */
2082 pkt->pkt_state |= STATE_SENT_CMD;
2083 }
2084
2085 static void
iscsi_tx_scsi_init_task(iscsi_cmd_t * icmdp,iscsi_conn_t * icp,iscsi_scsi_cmd_hdr_t * ihp)2086 iscsi_tx_scsi_init_task(iscsi_cmd_t *icmdp, iscsi_conn_t *icp,
2087 iscsi_scsi_cmd_hdr_t *ihp)
2088 {
2089 idm_task_t *itp;
2090 struct buf *bp = NULL;
2091 uint32_t data_length;
2092
2093 bp = icmdp->cmd_un.scsi.bp;
2094
2095 itp = icmdp->cmd_itp;
2096 ASSERT(itp != NULL);
2097 data_length = ntohl(ihp->data_length);
2098 ISCSI_IO_LOG(CE_NOTE,
2099 "DEBUG: iscsi_tx_init_task: task_start: %p idt_tt: %x cmdsn: %x "
2100 "sess_cmdsn: %x cmd: %p "
2101 "cmdtype: %d datalen: %u",
2102 (void *)itp, itp->idt_tt, ihp->cmdsn, icp->conn_sess->sess_cmdsn,
2103 (void *)icmdp, icmdp->cmd_type, data_length);
2104 if (data_length > 0) {
2105 if (bp->b_flags & B_READ) {
2106 icmdp->cmd_un.scsi.ibp_ibuf =
2107 idm_buf_alloc(icp->conn_ic,
2108 bp->b_un.b_addr, bp->b_bcount);
2109 if (icmdp->cmd_un.scsi.ibp_ibuf)
2110 idm_buf_bind_in(itp,
2111 icmdp->cmd_un.scsi.ibp_ibuf);
2112 } else {
2113 icmdp->cmd_un.scsi.ibp_obuf =
2114 idm_buf_alloc(icp->conn_ic,
2115 bp->b_un.b_addr, bp->b_bcount);
2116 if (icmdp->cmd_un.scsi.ibp_obuf)
2117 idm_buf_bind_out(itp,
2118 icmdp->cmd_un.scsi.ibp_obuf);
2119 }
2120 ISCSI_IO_LOG(CE_NOTE,
2121 "DEBUG: pdu_tx: task_start(%s): %p ic: %p idt_tt: %x "
2122 "cmdsn: %x sess_cmdsn: %x sess_expcmdsn: %x obuf: %p "
2123 "cmdp: %p cmdtype: %d "
2124 "buflen: %lu " "bpaddr: %p datalen: %u ",
2125 bp->b_flags & B_READ ? "B_READ" : "B_WRITE",
2126 (void *)itp, (void *)icp->conn_ic,
2127 itp->idt_tt, ihp->cmdsn,
2128 icp->conn_sess->sess_cmdsn,
2129 icp->conn_sess->sess_expcmdsn,
2130 (void *)icmdp->cmd_un.scsi.ibp_ibuf,
2131 (void *)icmdp, icmdp->cmd_type, bp->b_bcount,
2132 (void *)bp->b_un.b_addr,
2133 data_length);
2134 }
2135
2136 /*
2137 * Task is now active
2138 */
2139 idm_task_start(itp, ISCSI_INI_TASK_TTT);
2140 }
2141
2142 /*
2143 * iscsi_tx_scsi -
2144 *
2145 */
2146 static iscsi_status_t
iscsi_tx_scsi(iscsi_sess_t * isp,iscsi_cmd_t * icmdp)2147 iscsi_tx_scsi(iscsi_sess_t *isp, iscsi_cmd_t *icmdp)
2148 {
2149 iscsi_status_t rval = ISCSI_STATUS_SUCCESS;
2150 iscsi_conn_t *icp = NULL;
2151 struct scsi_pkt *pkt = NULL;
2152 iscsi_scsi_cmd_hdr_t *ihp = NULL;
2153 int cdblen = 0;
2154 idm_pdu_t *pdu;
2155 int len;
2156
2157 ASSERT(isp != NULL);
2158 ASSERT(icmdp != NULL);
2159
2160 pdu = kmem_zalloc(sizeof (idm_pdu_t), KM_SLEEP);
2161
2162 pkt = icmdp->cmd_un.scsi.pkt;
2163 ASSERT(pkt != NULL);
2164 icp = icmdp->cmd_conn;
2165 ASSERT(icp != NULL);
2166
2167 /* Reset counts in case we are on a retry */
2168 icmdp->cmd_un.scsi.data_transferred = 0;
2169
2170 if (icmdp->cmd_un.scsi.cmdlen > DEF_CDB_LEN) {
2171 cdblen = icmdp->cmd_un.scsi.cmdlen;
2172 ihp = kmem_zalloc(ADDLHDRSZ(cdblen), KM_SLEEP);
2173 len = ADDLHDRSZ(cdblen);
2174 } else {
2175 /*
2176 * only bzero the basic header; the additional header
2177 * will be set up correctly later, if needed
2178 */
2179 ihp = kmem_zalloc(sizeof (iscsi_scsi_cmd_hdr_t), KM_SLEEP);
2180 len = sizeof (iscsi_scsi_cmd_hdr_t);
2181 }
2182
2183 iscsi_tx_init_hdr(isp, icp, (iscsi_text_hdr_t *)ihp,
2184 ISCSI_OP_SCSI_CMD, icmdp);
2185
2186 idm_pdu_init(pdu, icp->conn_ic, (void *)icmdp, &iscsi_tx_done);
2187 idm_pdu_init_hdr(pdu, (uint8_t *)ihp, len);
2188 pdu->isp_data = NULL;
2189 pdu->isp_datalen = 0;
2190
2191 /*
2192 * Sestion 12.11 of the iSCSI specification has a good table
2193 * describing when uncolicited data and/or immediate data
2194 * should be sent.
2195 */
2196
2197 iscsi_tx_scsi_data(icmdp, ihp, icp, pdu);
2198
2199 iscsi_tx_scsi_init_pkt(icmdp, ihp);
2200
2201 /* Calls idm_task_start */
2202 iscsi_tx_scsi_init_task(icmdp, icp, ihp);
2203
2204 mutex_exit(&isp->sess_queue_pending.mutex);
2205
2206 idm_pdu_tx(pdu);
2207
2208 icmdp->cmd_misc_flags |= ISCSI_CMD_MISCFLAG_SENT;
2209
2210 return (rval);
2211 }
2212
2213
2214 /* ARGSUSED */
2215 static void
iscsi_tx_done(idm_pdu_t * pdu,idm_status_t status)2216 iscsi_tx_done(idm_pdu_t *pdu, idm_status_t status)
2217 {
2218 kmem_free((iscsi_hdr_t *)pdu->isp_hdr, pdu->isp_hdrlen);
2219 kmem_free(pdu, sizeof (idm_pdu_t));
2220 }
2221
2222
2223 static void
iscsi_tx_pdu(iscsi_conn_t * icp,int opcode,void * hdr,int hdrlen,iscsi_cmd_t * icmdp)2224 iscsi_tx_pdu(iscsi_conn_t *icp, int opcode, void *hdr, int hdrlen,
2225 iscsi_cmd_t *icmdp)
2226 {
2227 idm_pdu_t *tx_pdu;
2228 iscsi_hdr_t *ihp = (iscsi_hdr_t *)hdr;
2229
2230 tx_pdu = kmem_zalloc(sizeof (idm_pdu_t), KM_SLEEP);
2231 ASSERT(tx_pdu != NULL);
2232
2233 idm_pdu_init(tx_pdu, icp->conn_ic, icmdp, &iscsi_tx_done);
2234 idm_pdu_init_hdr(tx_pdu, hdr, hdrlen);
2235 if (opcode == ISCSI_OP_TEXT_CMD) {
2236 idm_pdu_init_data(tx_pdu,
2237 (uint8_t *)icmdp->cmd_un.text.buf,
2238 ntoh24(ihp->dlength));
2239 }
2240
2241 mutex_exit(&icp->conn_sess->sess_queue_pending.mutex);
2242 idm_pdu_tx(tx_pdu);
2243 icmdp->cmd_misc_flags |= ISCSI_CMD_MISCFLAG_SENT;
2244 }
2245
2246
2247 /*
2248 * iscsi_tx_nop -
2249 *
2250 */
2251 static iscsi_status_t
iscsi_tx_nop(iscsi_sess_t * isp,iscsi_cmd_t * icmdp)2252 iscsi_tx_nop(iscsi_sess_t *isp, iscsi_cmd_t *icmdp)
2253 {
2254 iscsi_status_t rval = ISCSI_STATUS_SUCCESS;
2255 iscsi_conn_t *icp = NULL;
2256 iscsi_nop_out_hdr_t *inohp;
2257
2258 ASSERT(isp != NULL);
2259 ASSERT(icmdp != NULL);
2260 icp = icmdp->cmd_conn;
2261 ASSERT(icp != NULL);
2262
2263 inohp = kmem_zalloc(sizeof (iscsi_nop_out_hdr_t), KM_SLEEP);
2264 ASSERT(inohp != NULL);
2265
2266 inohp->opcode = ISCSI_OP_NOOP_OUT | ISCSI_OP_IMMEDIATE;
2267 inohp->flags = ISCSI_FLAG_FINAL;
2268 inohp->itt = icmdp->cmd_itt;
2269 inohp->ttt = icmdp->cmd_ttt;
2270 mutex_enter(&isp->sess_cmdsn_mutex);
2271 icmdp->cmd_sn = isp->sess_cmdsn;
2272 inohp->cmdsn = htonl(isp->sess_cmdsn);
2273 mutex_exit(&isp->sess_cmdsn_mutex);
2274 inohp->expstatsn = htonl(icp->conn_expstatsn);
2275 icp->conn_laststatsn = icp->conn_expstatsn;
2276 iscsi_tx_pdu(icp, ISCSI_OP_NOOP_OUT, inohp,
2277 sizeof (iscsi_nop_out_hdr_t), icmdp);
2278 return (rval);
2279 }
2280
2281
2282 /*
2283 * iscsi_tx_abort -
2284 *
2285 */
2286 static iscsi_status_t
iscsi_tx_abort(iscsi_sess_t * isp,iscsi_cmd_t * icmdp)2287 iscsi_tx_abort(iscsi_sess_t *isp, iscsi_cmd_t *icmdp)
2288 {
2289 iscsi_status_t rval = ISCSI_STATUS_SUCCESS;
2290 iscsi_conn_t *icp = NULL;
2291 iscsi_scsi_task_mgt_hdr_t *istmh;
2292
2293 ASSERT(isp != NULL);
2294 ASSERT(icmdp != NULL);
2295 icp = icmdp->cmd_conn;
2296 ASSERT(icp != NULL);
2297
2298 istmh = kmem_zalloc(sizeof (iscsi_scsi_task_mgt_hdr_t), KM_SLEEP);
2299 ASSERT(istmh != NULL);
2300 mutex_enter(&isp->sess_cmdsn_mutex);
2301 icmdp->cmd_sn = isp->sess_cmdsn;
2302 istmh->cmdsn = htonl(isp->sess_cmdsn);
2303 mutex_exit(&isp->sess_cmdsn_mutex);
2304 istmh->expstatsn = htonl(icp->conn_expstatsn);
2305 icp->conn_laststatsn = icp->conn_expstatsn;
2306 istmh->itt = icmdp->cmd_itt;
2307 istmh->opcode = ISCSI_OP_SCSI_TASK_MGT_MSG | ISCSI_OP_IMMEDIATE;
2308 istmh->function = ISCSI_FLAG_FINAL | ISCSI_TM_FUNC_ABORT_TASK;
2309 ISCSI_LUN_BYTE_COPY(istmh->lun,
2310 icmdp->cmd_un.abort.icmdp->cmd_un.scsi.lun);
2311 istmh->rtt = icmdp->cmd_un.abort.icmdp->cmd_itt;
2312 iscsi_tx_pdu(icp, ISCSI_OP_SCSI_TASK_MGT_MSG, istmh,
2313 sizeof (iscsi_scsi_task_mgt_hdr_t), icmdp);
2314
2315 return (rval);
2316 }
2317
2318
2319 /*
2320 * iscsi_tx_reset -
2321 *
2322 */
2323 static iscsi_status_t
iscsi_tx_reset(iscsi_sess_t * isp,iscsi_cmd_t * icmdp)2324 iscsi_tx_reset(iscsi_sess_t *isp, iscsi_cmd_t *icmdp)
2325 {
2326 iscsi_status_t rval = ISCSI_STATUS_SUCCESS;
2327 iscsi_conn_t *icp = NULL;
2328 iscsi_scsi_task_mgt_hdr_t *istmh;
2329
2330 ASSERT(isp != NULL);
2331 ASSERT(icmdp != NULL);
2332 icp = icmdp->cmd_conn;
2333 ASSERT(icp != NULL);
2334
2335 istmh = kmem_zalloc(sizeof (iscsi_scsi_task_mgt_hdr_t), KM_SLEEP);
2336 ASSERT(istmh != NULL);
2337 istmh->opcode = ISCSI_OP_SCSI_TASK_MGT_MSG | ISCSI_OP_IMMEDIATE;
2338 mutex_enter(&isp->sess_cmdsn_mutex);
2339 icmdp->cmd_sn = isp->sess_cmdsn;
2340 istmh->cmdsn = htonl(isp->sess_cmdsn);
2341 mutex_exit(&isp->sess_cmdsn_mutex);
2342 istmh->expstatsn = htonl(icp->conn_expstatsn);
2343 istmh->itt = icmdp->cmd_itt;
2344
2345 switch (icmdp->cmd_un.reset.level) {
2346 case RESET_LUN:
2347 istmh->function = ISCSI_FLAG_FINAL |
2348 ISCSI_TM_FUNC_LOGICAL_UNIT_RESET;
2349 ISCSI_LUN_BYTE_COPY(istmh->lun, icmdp->cmd_lun->lun_num);
2350 break;
2351 case RESET_TARGET:
2352 case RESET_BUS:
2353 istmh->function = ISCSI_FLAG_FINAL |
2354 ISCSI_TM_FUNC_TARGET_WARM_RESET;
2355 break;
2356 default:
2357 /* unsupported / unknown level */
2358 ASSERT(FALSE);
2359 break;
2360 }
2361
2362 iscsi_tx_pdu(icp, ISCSI_OP_SCSI_TASK_MGT_MSG, istmh,
2363 sizeof (iscsi_scsi_task_mgt_hdr_t), icmdp);
2364
2365 return (rval);
2366 }
2367
2368
2369 /*
2370 * iscsi_tx_logout -
2371 *
2372 */
2373 static iscsi_status_t
iscsi_tx_logout(iscsi_sess_t * isp,iscsi_cmd_t * icmdp)2374 iscsi_tx_logout(iscsi_sess_t *isp, iscsi_cmd_t *icmdp)
2375 {
2376 iscsi_status_t rval = ISCSI_STATUS_SUCCESS;
2377 iscsi_conn_t *icp = NULL;
2378 iscsi_logout_hdr_t *ilh;
2379
2380 ASSERT(isp != NULL);
2381 ASSERT(icmdp != NULL);
2382 icp = icmdp->cmd_conn;
2383 ASSERT(icp != NULL);
2384
2385 ilh = kmem_zalloc(sizeof (iscsi_logout_hdr_t), KM_SLEEP);
2386 ilh->opcode = ISCSI_OP_LOGOUT_CMD | ISCSI_OP_IMMEDIATE;
2387 ilh->flags = ISCSI_FLAG_FINAL | ISCSI_LOGOUT_REASON_CLOSE_SESSION;
2388 ilh->itt = icmdp->cmd_itt;
2389 ilh->cid = icp->conn_cid;
2390 mutex_enter(&isp->sess_cmdsn_mutex);
2391 icmdp->cmd_sn = isp->sess_cmdsn;
2392 ilh->cmdsn = htonl(isp->sess_cmdsn);
2393 mutex_exit(&isp->sess_cmdsn_mutex);
2394 ilh->expstatsn = htonl(icp->conn_expstatsn);
2395 iscsi_tx_pdu(icp, ISCSI_OP_LOGOUT_CMD, ilh,
2396 sizeof (iscsi_logout_hdr_t), icmdp);
2397
2398 return (rval);
2399 }
2400
2401 /*
2402 * iscsi_tx_text - setup iSCSI text request header and send PDU with
2403 * data given in the buffer attached to the command. For a single
2404 * text request, the target may need to send its response in multiple
2405 * text response. In this case, empty text requests are sent after
2406 * each received response to notify the target the initiator is ready
2407 * for more response. For the initial request, the data_len field in
2408 * the text specific portion of a command is set to the amount of data
2409 * the initiator wants to send as part of the request. If additional
2410 * empty text requests are required for long responses, the data_len
2411 * field is set to 0 by the iscsi_handle_text function.
2412 */
2413 static iscsi_status_t
iscsi_tx_text(iscsi_sess_t * isp,iscsi_cmd_t * icmdp)2414 iscsi_tx_text(iscsi_sess_t *isp, iscsi_cmd_t *icmdp)
2415 {
2416 iscsi_status_t rval = ISCSI_STATUS_SUCCESS;
2417 iscsi_conn_t *icp = NULL;
2418 iscsi_text_hdr_t *ith;
2419
2420 ASSERT(icmdp != NULL);
2421 icp = icmdp->cmd_conn;
2422 ASSERT(icp != NULL);
2423
2424 ith = kmem_zalloc(sizeof (iscsi_text_hdr_t), KM_SLEEP);
2425 ASSERT(ith != NULL);
2426 ith->flags = ISCSI_FLAG_FINAL;
2427 hton24(ith->dlength, icmdp->cmd_un.text.data_len);
2428 ith->ttt = icmdp->cmd_un.text.ttt;
2429 iscsi_tx_init_hdr(isp, icp, (iscsi_text_hdr_t *)ith,
2430 ISCSI_OP_TEXT_CMD, icmdp);
2431 bcopy(icmdp->cmd_un.text.lun, ith->rsvd4, sizeof (ith->rsvd4));
2432
2433 iscsi_tx_pdu(icp, ISCSI_OP_TEXT_CMD, ith, sizeof (iscsi_text_hdr_t),
2434 icmdp);
2435
2436 return (rval);
2437 }
2438
2439 /*
2440 * +--------------------------------------------------------------------+
2441 * | End of protocol send routines |
2442 * +--------------------------------------------------------------------+
2443 */
2444
2445 /*
2446 * iscsi_handle_abort -
2447 *
2448 */
2449 void
iscsi_handle_abort(void * arg)2450 iscsi_handle_abort(void *arg)
2451 {
2452 iscsi_sess_t *isp = NULL;
2453 iscsi_cmd_t *icmdp = (iscsi_cmd_t *)arg;
2454 iscsi_cmd_t *new_icmdp;
2455 iscsi_conn_t *icp;
2456
2457 ASSERT(icmdp != NULL);
2458 icp = icmdp->cmd_conn;
2459 ASSERT(icp != NULL);
2460 isp = icp->conn_sess;
2461 ASSERT(isp != NULL);
2462
2463 /* there should only be one abort */
2464 ASSERT(icmdp->cmd_un.scsi.abort_icmdp == NULL);
2465
2466 new_icmdp = iscsi_cmd_alloc(icp, KM_SLEEP);
2467 new_icmdp->cmd_type = ISCSI_CMD_TYPE_ABORT;
2468 new_icmdp->cmd_lun = icmdp->cmd_lun;
2469 new_icmdp->cmd_un.abort.icmdp = icmdp;
2470 new_icmdp->cmd_conn = icmdp->cmd_conn;
2471 icmdp->cmd_un.scsi.abort_icmdp = new_icmdp;
2472
2473 /* pending queue mutex is already held by timeout_checks */
2474 iscsi_cmd_state_machine(new_icmdp, ISCSI_CMD_EVENT_E1, isp);
2475 }
2476
2477 /*
2478 * Callback from IDM indicating that the task has been suspended or aborted.
2479 */
2480 void
iscsi_task_aborted(idm_task_t * idt,idm_status_t status)2481 iscsi_task_aborted(idm_task_t *idt, idm_status_t status)
2482 {
2483 iscsi_cmd_t *icmdp = idt->idt_private;
2484 iscsi_conn_t *icp = icmdp->cmd_conn;
2485 iscsi_sess_t *isp = icp->conn_sess;
2486
2487 ASSERT(icmdp->cmd_conn != NULL);
2488
2489 switch (status) {
2490 case IDM_STATUS_SUSPENDED:
2491 /*
2492 * If the task is suspended, it may be aborted later,
2493 * so we can ignore this notification.
2494 */
2495 break;
2496
2497 case IDM_STATUS_ABORTED:
2498 mutex_enter(&icp->conn_queue_active.mutex);
2499 iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E9, isp);
2500 mutex_exit(&icp->conn_queue_active.mutex);
2501 break;
2502
2503 default:
2504 /*
2505 * Unexpected status.
2506 */
2507 ASSERT(0);
2508 }
2509
2510 }
2511
2512 /*
2513 * iscsi_handle_nop -
2514 *
2515 */
2516 static void
iscsi_handle_nop(iscsi_conn_t * icp,uint32_t itt,uint32_t ttt)2517 iscsi_handle_nop(iscsi_conn_t *icp, uint32_t itt, uint32_t ttt)
2518 {
2519 iscsi_sess_t *isp = NULL;
2520 iscsi_cmd_t *icmdp = NULL;
2521
2522 ASSERT(icp != NULL);
2523 isp = icp->conn_sess;
2524 ASSERT(isp != NULL);
2525
2526 icmdp = iscsi_cmd_alloc(icp, KM_NOSLEEP);
2527 if (icmdp == NULL) {
2528 return;
2529 }
2530
2531 icmdp->cmd_type = ISCSI_CMD_TYPE_NOP;
2532 icmdp->cmd_itt = itt;
2533 icmdp->cmd_ttt = ttt;
2534 icmdp->cmd_lun = NULL;
2535 icp->conn_nop_lbolt = ddi_get_lbolt();
2536
2537 iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E1, isp);
2538 }
2539
2540 /*
2541 * iscsi_handle_reset - send reset request to the target
2542 *
2543 */
2544 iscsi_status_t
iscsi_handle_reset(iscsi_sess_t * isp,int level,iscsi_lun_t * ilp)2545 iscsi_handle_reset(iscsi_sess_t *isp, int level, iscsi_lun_t *ilp)
2546 {
2547 iscsi_status_t rval = ISCSI_STATUS_SUCCESS;
2548 iscsi_conn_t *icp;
2549 iscsi_cmd_t icmd;
2550
2551 ASSERT(isp != NULL);
2552
2553 if (level == RESET_LUN) {
2554 rw_enter(&isp->sess_lun_list_rwlock, RW_WRITER);
2555 ASSERT(ilp != NULL);
2556 if (ilp->lun_state & ISCSI_LUN_STATE_BUSY) {
2557 rw_exit(&isp->sess_lun_list_rwlock);
2558 return (ISCSI_STATUS_SUCCESS);
2559 }
2560 ilp->lun_state |= ISCSI_LUN_STATE_BUSY;
2561 rw_exit(&isp->sess_lun_list_rwlock);
2562 } else {
2563 mutex_enter(&isp->sess_reset_mutex);
2564 if (isp->sess_reset_in_progress == B_TRUE) {
2565 /*
2566 * If the reset is in progress, it is unnecessary
2567 * to send reset to the target redunantly.
2568 */
2569 mutex_exit(&isp->sess_reset_mutex);
2570 return (ISCSI_STATUS_SUCCESS);
2571 }
2572 isp->sess_reset_in_progress = B_TRUE;
2573 mutex_exit(&isp->sess_reset_mutex);
2574 }
2575
2576 bzero(&icmd, sizeof (iscsi_cmd_t));
2577 icmd.cmd_sig = ISCSI_SIG_CMD;
2578 icmd.cmd_state = ISCSI_CMD_STATE_FREE;
2579 icmd.cmd_type = ISCSI_CMD_TYPE_RESET;
2580 icmd.cmd_lun = ilp;
2581 icmd.cmd_un.reset.level = level;
2582 icmd.cmd_result = ISCSI_STATUS_SUCCESS;
2583 icmd.cmd_completed = B_FALSE;
2584 icmd.cmd_un.reset.response = SCSI_TCP_TM_RESP_COMPLETE;
2585
2586 mutex_init(&icmd.cmd_mutex, NULL, MUTEX_DRIVER, NULL);
2587 cv_init(&icmd.cmd_completion, NULL, CV_DRIVER, NULL);
2588 /*
2589 * If we received an IO and we are not in the
2590 * LOGGED_IN state we are in the process of
2591 * failing. Just respond that we are BUSY.
2592 */
2593 rw_enter(&isp->sess_state_rwlock, RW_READER);
2594 if (!ISCSI_SESS_STATE_FULL_FEATURE(isp->sess_state)) {
2595 /* We aren't connected to the target fake success */
2596 rw_exit(&isp->sess_state_rwlock);
2597
2598 if (level == RESET_LUN) {
2599 rw_enter(&isp->sess_lun_list_rwlock, RW_WRITER);
2600 ilp->lun_state &= ~ISCSI_LUN_STATE_BUSY;
2601 rw_exit(&isp->sess_lun_list_rwlock);
2602 } else {
2603 mutex_enter(&isp->sess_reset_mutex);
2604 isp->sess_reset_in_progress = B_FALSE;
2605 mutex_exit(&isp->sess_reset_mutex);
2606 }
2607
2608 return (ISCSI_STATUS_SUCCESS);
2609 }
2610
2611 mutex_enter(&isp->sess_queue_pending.mutex);
2612 iscsi_cmd_state_machine(&icmd, ISCSI_CMD_EVENT_E1, isp);
2613 mutex_exit(&isp->sess_queue_pending.mutex);
2614 rw_exit(&isp->sess_state_rwlock);
2615
2616 /* stall until completed */
2617 mutex_enter(&icmd.cmd_mutex);
2618 while (icmd.cmd_completed == B_FALSE) {
2619 cv_wait(&icmd.cmd_completion, &icmd.cmd_mutex);
2620 }
2621 mutex_exit(&icmd.cmd_mutex);
2622
2623 /* copy rval */
2624 rval = icmd.cmd_result;
2625
2626 if (rval == ISCSI_STATUS_SUCCESS) {
2627 /*
2628 * Reset was successful. We need to flush
2629 * all active IOs.
2630 */
2631 rw_enter(&isp->sess_conn_list_rwlock, RW_READER);
2632 icp = isp->sess_conn_list;
2633 while (icp != NULL) {
2634 iscsi_cmd_t *t_icmdp = NULL;
2635 iscsi_cmd_t *next_icmdp = NULL;
2636
2637 mutex_enter(&icp->conn_queue_active.mutex);
2638 t_icmdp = icp->conn_queue_active.head;
2639 while (t_icmdp != NULL) {
2640 next_icmdp = t_icmdp->cmd_next;
2641 mutex_enter(&t_icmdp->cmd_mutex);
2642 if (!(t_icmdp->cmd_misc_flags &
2643 ISCSI_CMD_MISCFLAG_SENT)) {
2644 /*
2645 * Although this command is in the
2646 * active queue, it has not been sent.
2647 * Skip it.
2648 */
2649 mutex_exit(&t_icmdp->cmd_mutex);
2650 t_icmdp = next_icmdp;
2651 continue;
2652 }
2653 if (level == RESET_LUN) {
2654 if (icmd.cmd_lun == NULL ||
2655 t_icmdp->cmd_lun == NULL ||
2656 (icmd.cmd_lun->lun_num !=
2657 t_icmdp->cmd_lun->lun_num)) {
2658 mutex_exit(&t_icmdp->cmd_mutex);
2659 t_icmdp = next_icmdp;
2660 continue;
2661 }
2662 }
2663
2664 if (icmd.cmd_sn == t_icmdp->cmd_sn) {
2665 /*
2666 * This command may be replied with
2667 * UA sense key later. So currently
2668 * it is not a suitable time to flush
2669 * it. Mark its flag with FLUSH. There
2670 * is no harm to keep it for a while.
2671 */
2672 t_icmdp->cmd_misc_flags |=
2673 ISCSI_CMD_MISCFLAG_FLUSH;
2674 if (t_icmdp->cmd_type ==
2675 ISCSI_CMD_TYPE_SCSI) {
2676 t_icmdp->cmd_un.scsi.pkt_stat |=
2677 STAT_BUS_RESET;
2678 }
2679 mutex_exit(&t_icmdp->cmd_mutex);
2680 } else if ((icmd.cmd_sn > t_icmdp->cmd_sn) ||
2681 ((t_icmdp->cmd_sn - icmd.cmd_sn) >
2682 ISCSI_CMD_SN_WRAP)) {
2683 /*
2684 * This reset request must act on all
2685 * the commnds from the same session
2686 * having a CmdSN lower than the task
2687 * mangement CmdSN. So flush these
2688 * commands here.
2689 */
2690 if (t_icmdp->cmd_type ==
2691 ISCSI_CMD_TYPE_SCSI) {
2692 t_icmdp->cmd_un.scsi.pkt_stat |=
2693 STAT_BUS_RESET;
2694 }
2695 mutex_exit(&t_icmdp->cmd_mutex);
2696 iscsi_cmd_state_machine(t_icmdp,
2697 ISCSI_CMD_EVENT_E7, isp);
2698 } else {
2699 mutex_exit(&t_icmdp->cmd_mutex);
2700 }
2701
2702 t_icmdp = next_icmdp;
2703 }
2704
2705 mutex_exit(&icp->conn_queue_active.mutex);
2706 icp = icp->conn_next;
2707 }
2708 rw_exit(&isp->sess_conn_list_rwlock);
2709 }
2710
2711 /* clean up */
2712 cv_destroy(&icmd.cmd_completion);
2713 mutex_destroy(&icmd.cmd_mutex);
2714
2715 if (level == RESET_LUN) {
2716 rw_enter(&isp->sess_lun_list_rwlock, RW_WRITER);
2717 ilp->lun_state &= ~ISCSI_LUN_STATE_BUSY;
2718 rw_exit(&isp->sess_lun_list_rwlock);
2719 } else {
2720 mutex_enter(&isp->sess_reset_mutex);
2721 isp->sess_reset_in_progress = B_FALSE;
2722 mutex_exit(&isp->sess_reset_mutex);
2723 }
2724
2725 return (rval);
2726 }
2727
2728 /*
2729 * iscsi_logout_start - task handler for deferred logout
2730 * Acquire a hold before call, released in iscsi_handle_logout
2731 */
2732 static void
iscsi_logout_start(void * arg)2733 iscsi_logout_start(void *arg)
2734 {
2735 iscsi_task_t *itp = (iscsi_task_t *)arg;
2736 iscsi_conn_t *icp;
2737
2738 icp = (iscsi_conn_t *)itp->t_arg;
2739
2740 mutex_enter(&icp->conn_state_mutex);
2741 (void) iscsi_handle_logout(icp);
2742 mutex_exit(&icp->conn_state_mutex);
2743 }
2744
2745 /*
2746 * iscsi_handle_logout - This function will issue a logout for
2747 * the session from a specific connection.
2748 * Acquire idm_conn_hold before call. Released internally.
2749 */
2750 iscsi_status_t
iscsi_handle_logout(iscsi_conn_t * icp)2751 iscsi_handle_logout(iscsi_conn_t *icp)
2752 {
2753 iscsi_sess_t *isp;
2754 idm_conn_t *ic;
2755 iscsi_cmd_t *icmdp;
2756 int rval;
2757
2758 ASSERT(icp != NULL);
2759 isp = icp->conn_sess;
2760 ic = icp->conn_ic;
2761 ASSERT(isp != NULL);
2762 ASSERT(isp->sess_hba != NULL);
2763 ASSERT(mutex_owned(&icp->conn_state_mutex));
2764
2765 /*
2766 * If the connection has already gone down (e.g. if the transport
2767 * failed between when this LOGOUT was generated and now) then we
2768 * can and must skip sending the LOGOUT. Check the same condition
2769 * we use below to determine that connection has "settled".
2770 */
2771 if ((icp->conn_state == ISCSI_CONN_STATE_FREE) ||
2772 (icp->conn_state == ISCSI_CONN_STATE_FAILED) ||
2773 (icp->conn_state == ISCSI_CONN_STATE_POLLING)) {
2774 idm_conn_rele(ic);
2775 return (0);
2776 }
2777
2778 icmdp = iscsi_cmd_alloc(icp, KM_SLEEP);
2779 ASSERT(icmdp != NULL);
2780 icmdp->cmd_type = ISCSI_CMD_TYPE_LOGOUT;
2781 icmdp->cmd_result = ISCSI_STATUS_SUCCESS;
2782 icmdp->cmd_completed = B_FALSE;
2783
2784 mutex_enter(&isp->sess_queue_pending.mutex);
2785 iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E1, isp);
2786 mutex_exit(&isp->sess_queue_pending.mutex);
2787
2788 /*
2789 * release connection state mutex to avoid a deadlock. This
2790 * function is called from within the connection state
2791 * machine with the lock held. When the logout response is
2792 * received another call to the connection state machine
2793 * occurs which causes the deadlock
2794 */
2795 mutex_exit(&icp->conn_state_mutex);
2796
2797 /* stall until completed */
2798 mutex_enter(&icmdp->cmd_mutex);
2799 while (icmdp->cmd_completed == B_FALSE) {
2800 cv_wait(&icmdp->cmd_completion, &icmdp->cmd_mutex);
2801 }
2802 mutex_exit(&icmdp->cmd_mutex);
2803 mutex_enter(&icp->conn_state_mutex);
2804
2805 /* copy rval */
2806 rval = icmdp->cmd_result;
2807
2808 /* clean up */
2809 iscsi_cmd_free(icmdp);
2810
2811 if (rval != 0) {
2812 /* If the logout failed then drop the connection */
2813 idm_ini_conn_disconnect(icp->conn_ic);
2814 }
2815
2816 /* stall until connection settles */
2817 while ((icp->conn_state != ISCSI_CONN_STATE_FREE) &&
2818 (icp->conn_state != ISCSI_CONN_STATE_FAILED) &&
2819 (icp->conn_state != ISCSI_CONN_STATE_POLLING)) {
2820 /* wait for transition */
2821 cv_wait(&icp->conn_state_change, &icp->conn_state_mutex);
2822 }
2823
2824 idm_conn_rele(ic);
2825
2826 /*
2827 * Return value reflects whether the logout command completed --
2828 * regardless of the return value the connection is closed and
2829 * ready for reconnection.
2830 */
2831 return (rval);
2832 }
2833
2834
2835 /*
2836 * iscsi_handle_text - main control function for iSCSI text requests. This
2837 * function handles allocating the command, sending initial text request, and
2838 * handling long response sequence.
2839 * If a data overflow condition occurs, iscsi_handle_text continues to
2840 * receive responses until the all data has been recieved. This allows
2841 * the full data length to be returned to the caller.
2842 */
2843 iscsi_status_t
iscsi_handle_text(iscsi_conn_t * icp,char * buf,uint32_t buf_len,uint32_t data_len,uint32_t * rx_data_len)2844 iscsi_handle_text(iscsi_conn_t *icp, char *buf, uint32_t buf_len,
2845 uint32_t data_len, uint32_t *rx_data_len)
2846 {
2847 iscsi_sess_t *isp;
2848 iscsi_cmd_t *icmdp;
2849 iscsi_status_t rval = ISCSI_STATUS_SUCCESS;
2850
2851 ASSERT(icp != NULL);
2852 ASSERT(buf != NULL);
2853 ASSERT(rx_data_len != NULL);
2854
2855 isp = icp->conn_sess;
2856 ASSERT(isp != NULL);
2857
2858 /*
2859 * Ensure data for text request command is not greater
2860 * than the negotiated maximum receive data seqment length.
2861 *
2862 * Although iSCSI allows for long text requests (multiple
2863 * pdus), this function places a restriction on text
2864 * requests to ensure it is handled by a single PDU.
2865 */
2866 if (data_len > icp->conn_params.max_xmit_data_seg_len) {
2867 return (ISCSI_STATUS_CMD_FAILED);
2868 }
2869
2870 icmdp = iscsi_cmd_alloc(icp, KM_SLEEP);
2871 ASSERT(icmdp != NULL);
2872
2873 icmdp->cmd_type = ISCSI_CMD_TYPE_TEXT;
2874 icmdp->cmd_result = ISCSI_STATUS_SUCCESS;
2875 icmdp->cmd_misc_flags &= ~ISCSI_CMD_MISCFLAG_FREE;
2876 icmdp->cmd_completed = B_FALSE;
2877
2878 icmdp->cmd_un.text.buf = buf;
2879 icmdp->cmd_un.text.buf_len = buf_len;
2880 icmdp->cmd_un.text.offset = 0;
2881 icmdp->cmd_un.text.data_len = data_len;
2882 icmdp->cmd_un.text.total_rx_len = 0;
2883 icmdp->cmd_un.text.ttt = ISCSI_RSVD_TASK_TAG;
2884 icmdp->cmd_un.text.stage = ISCSI_CMD_TEXT_INITIAL_REQ;
2885
2886 long_text_response:
2887 rw_enter(&isp->sess_state_rwlock, RW_READER);
2888 if (!ISCSI_SESS_STATE_FULL_FEATURE(isp->sess_state)) {
2889 iscsi_cmd_free(icmdp);
2890 rw_exit(&isp->sess_state_rwlock);
2891 return (ISCSI_STATUS_NO_CONN_LOGGED_IN);
2892 }
2893
2894 mutex_enter(&isp->sess_queue_pending.mutex);
2895 iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E1, isp);
2896 mutex_exit(&isp->sess_queue_pending.mutex);
2897 rw_exit(&isp->sess_state_rwlock);
2898
2899 /* stall until completed */
2900 mutex_enter(&icmdp->cmd_mutex);
2901 while (icmdp->cmd_completed == B_FALSE) {
2902 cv_wait(&icmdp->cmd_completion, &icmdp->cmd_mutex);
2903 }
2904 mutex_exit(&icmdp->cmd_mutex);
2905
2906 /*
2907 * check if error occured. If data overflow occured, continue on
2908 * to ensure we get all data so that the full data length can be
2909 * returned to the user
2910 */
2911 if ((icmdp->cmd_result != ISCSI_STATUS_SUCCESS) &&
2912 (icmdp->cmd_result != ISCSI_STATUS_DATA_OVERFLOW)) {
2913 cmn_err(CE_NOTE, "iscsi: SendTarget discovery failed (%d)",
2914 icmdp->cmd_result);
2915 rval = icmdp->cmd_result;
2916 iscsi_cmd_free(icmdp);
2917 return (rval);
2918 }
2919
2920 /* check if this was a partial text PDU */
2921 if (icmdp->cmd_un.text.stage != ISCSI_CMD_TEXT_FINAL_RSP) {
2922 /*
2923 * If a paritial text rexponse received, send an empty
2924 * text request. This follows the behaviour specified
2925 * in RFC3720 regarding long text responses.
2926 */
2927 icmdp->cmd_misc_flags &= ~ISCSI_CMD_MISCFLAG_FREE;
2928 icmdp->cmd_completed = B_FALSE;
2929 icmdp->cmd_un.text.data_len = 0;
2930 icmdp->cmd_un.text.stage = ISCSI_CMD_TEXT_CONTINUATION;
2931 goto long_text_response;
2932 }
2933
2934 /*
2935 * set total received data length. If data overflow this would be
2936 * amount of data that would have been received if buffer large
2937 * enough.
2938 */
2939 *rx_data_len = icmdp->cmd_un.text.total_rx_len;
2940
2941 /* copy rval */
2942 rval = icmdp->cmd_result;
2943
2944 /* clean up */
2945 iscsi_cmd_free(icmdp);
2946
2947 return (rval);
2948 }
2949
2950 /*
2951 * iscsi_handle_passthru - This function is used to send a uscsi_cmd
2952 * to a specific target lun. This routine is used for internal purposes
2953 * during enumeration and via the ISCSI_USCSICMD IOCTL. We restrict
2954 * the CDBs that can be issued to a target/lun to INQUIRY, REPORT_LUNS,
2955 * and READ_CAPACITY for security purposes.
2956 *
2957 * The logic here is broken into three phases.
2958 * 1) Allocate and initialize a pkt/icmdp
2959 * 2) Send the pkt/icmdp
2960 * 3) cv_wait for completion
2961 */
2962 iscsi_status_t
iscsi_handle_passthru(iscsi_sess_t * isp,uint16_t lun,struct uscsi_cmd * ucmdp)2963 iscsi_handle_passthru(iscsi_sess_t *isp, uint16_t lun, struct uscsi_cmd *ucmdp)
2964 {
2965 iscsi_status_t rval;
2966 iscsi_cmd_t *icmdp;
2967 struct scsi_pkt *pkt;
2968 struct buf *bp;
2969 struct scsi_arq_status *arqstat;
2970 int statuslen;
2971
2972 ASSERT(isp != NULL);
2973 ASSERT(ucmdp != NULL);
2974
2975 if (ucmdp->uscsi_rqlen > SENSE_LENGTH) {
2976 /*
2977 * The caller provided sense buffer large enough for additional
2978 * sense bytes. We need to allocate pkt_scbp to fit them there
2979 * too.
2980 */
2981 statuslen = ucmdp->uscsi_rqlen + ISCSI_ARQ_STATUS_NOSENSE_LEN;
2982 } else {
2983 /* The default size of pkt_scbp */
2984 statuslen = sizeof (struct scsi_arq_status);
2985 }
2986
2987 /*
2988 * Step 1. Setup structs - KM_SLEEP will always succeed
2989 */
2990 bp = kmem_zalloc(sizeof (struct buf), KM_SLEEP);
2991 ASSERT(bp != NULL);
2992 pkt = kmem_zalloc(sizeof (struct scsi_pkt), KM_SLEEP);
2993 ASSERT(pkt != NULL);
2994 icmdp = iscsi_cmd_alloc(NULL, KM_SLEEP);
2995 ASSERT(icmdp != NULL);
2996
2997 /* setup bp structure */
2998 bp->b_flags = B_READ;
2999 bp->b_bcount = ucmdp->uscsi_buflen;
3000 bp->b_un.b_addr = ucmdp->uscsi_bufaddr;
3001
3002 /* setup scsi_pkt structure */
3003 pkt->pkt_ha_private = icmdp;
3004 pkt->pkt_scbp = kmem_zalloc(statuslen, KM_SLEEP);
3005 pkt->pkt_cdbp = kmem_zalloc(ucmdp->uscsi_cdblen, KM_SLEEP);
3006 /* callback routine for passthru, will wake cv_wait */
3007 pkt->pkt_comp = iscsi_handle_passthru_callback;
3008 pkt->pkt_time = ucmdp->uscsi_timeout;
3009
3010 /* setup iscsi_cmd structure */
3011 icmdp->cmd_lun = NULL;
3012 icmdp->cmd_type = ISCSI_CMD_TYPE_SCSI;
3013 icmdp->cmd_un.scsi.lun = lun;
3014 icmdp->cmd_un.scsi.pkt = pkt;
3015 icmdp->cmd_un.scsi.bp = bp;
3016 bcopy(ucmdp->uscsi_cdb, pkt->pkt_cdbp, ucmdp->uscsi_cdblen);
3017 icmdp->cmd_un.scsi.cmdlen = ucmdp->uscsi_cdblen;
3018 icmdp->cmd_un.scsi.statuslen = statuslen;
3019 icmdp->cmd_crc_error_seen = B_FALSE;
3020 icmdp->cmd_completed = B_FALSE;
3021 icmdp->cmd_result = ISCSI_STATUS_SUCCESS;
3022
3023 /*
3024 * Step 2. Push IO onto pending queue. If we aren't in
3025 * FULL_FEATURE we need to fail the IO.
3026 */
3027 rw_enter(&isp->sess_state_rwlock, RW_READER);
3028 if (!ISCSI_SESS_STATE_FULL_FEATURE(isp->sess_state)) {
3029 rw_exit(&isp->sess_state_rwlock);
3030
3031 iscsi_cmd_free(icmdp);
3032 kmem_free(pkt->pkt_cdbp, ucmdp->uscsi_cdblen);
3033 kmem_free(pkt->pkt_scbp, statuslen);
3034 kmem_free(pkt, sizeof (struct scsi_pkt));
3035 kmem_free(bp, sizeof (struct buf));
3036
3037 return (ISCSI_STATUS_CMD_FAILED);
3038 }
3039
3040 mutex_enter(&isp->sess_queue_pending.mutex);
3041 iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E1, isp);
3042 mutex_exit(&isp->sess_queue_pending.mutex);
3043 rw_exit(&isp->sess_state_rwlock);
3044
3045 /*
3046 * Step 3. Wait on cv_wait for completion routine
3047 */
3048 mutex_enter(&icmdp->cmd_mutex);
3049 while (icmdp->cmd_completed == B_FALSE) {
3050 cv_wait(&icmdp->cmd_completion, &icmdp->cmd_mutex);
3051 }
3052 mutex_exit(&icmdp->cmd_mutex);
3053
3054 /* copy rval */
3055 rval = icmdp->cmd_result;
3056
3057 ucmdp->uscsi_resid = pkt->pkt_resid;
3058
3059 /* update scsi status */
3060 arqstat = (struct scsi_arq_status *)pkt->pkt_scbp;
3061 ucmdp->uscsi_status = ((char *)&arqstat->sts_status)[0];
3062
3063 /* copy request sense buffers if caller gave space */
3064 if ((ucmdp->uscsi_rqlen > 0) &&
3065 (ucmdp->uscsi_rqbuf != NULL)) {
3066 ASSERT(ucmdp->uscsi_rqlen >= arqstat->sts_rqpkt_resid);
3067 ucmdp->uscsi_rqresid = arqstat->sts_rqpkt_resid;
3068 bcopy(&arqstat->sts_sensedata, ucmdp->uscsi_rqbuf,
3069 ucmdp->uscsi_rqlen - arqstat->sts_rqpkt_resid);
3070 }
3071
3072 if ((ucmdp->uscsi_status == STATUS_CHECK) &&
3073 ((icmdp->cmd_misc_flags & ISCSI_CMD_MISCFLAG_INTERNAL)) == B_TRUE) {
3074 /*
3075 * Internal SCSI commands received status
3076 */
3077 (void) iscsi_decode_sense(
3078 (uint8_t *)&arqstat->sts_sensedata, icmdp);
3079 }
3080
3081 /* clean up */
3082 iscsi_cmd_free(icmdp);
3083 kmem_free(pkt->pkt_cdbp, ucmdp->uscsi_cdblen);
3084 kmem_free(pkt->pkt_scbp, statuslen);
3085 kmem_free(pkt, sizeof (struct scsi_pkt));
3086 kmem_free(bp, sizeof (struct buf));
3087
3088 return (rval);
3089 }
3090
3091
3092 /*
3093 * iscsi_handle_passthru_callback -
3094 *
3095 */
3096 static void
iscsi_handle_passthru_callback(struct scsi_pkt * pkt)3097 iscsi_handle_passthru_callback(struct scsi_pkt *pkt)
3098 {
3099 iscsi_cmd_t *icmdp = NULL;
3100
3101 ASSERT(pkt != NULL);
3102 icmdp = (iscsi_cmd_t *)pkt->pkt_ha_private;
3103 ASSERT(icmdp != NULL);
3104
3105 mutex_enter(&icmdp->cmd_mutex);
3106 icmdp->cmd_completed = B_TRUE;
3107 icmdp->cmd_result = ISCSI_STATUS_SUCCESS;
3108 cv_broadcast(&icmdp->cmd_completion);
3109 mutex_exit(&icmdp->cmd_mutex);
3110
3111 }
3112
3113 /*
3114 * IDM callbacks
3115 */
3116 void
iscsi_build_hdr(idm_task_t * idm_task,idm_pdu_t * pdu,uint8_t opcode)3117 iscsi_build_hdr(idm_task_t *idm_task, idm_pdu_t *pdu, uint8_t opcode)
3118 {
3119 iscsi_cmd_t *icmdp = idm_task->idt_private;
3120 iscsi_conn_t *icp = icmdp->cmd_conn;
3121 iscsi_data_hdr_t *ihp = (iscsi_data_hdr_t *)pdu->isp_hdr;
3122
3123 mutex_enter(&icmdp->cmd_mutex);
3124 if (opcode == ISCSI_OP_SCSI_DATA) {
3125 uint32_t data_sn;
3126 uint32_t lun;
3127 icmdp = idm_task->idt_private;
3128 icp = icmdp->cmd_conn;
3129 ihp->opcode = opcode;
3130 ihp->itt = icmdp->cmd_itt;
3131 ihp->ttt = idm_task->idt_r2t_ttt;
3132 ihp->expstatsn = htonl(icp->conn_expstatsn);
3133 icp->conn_laststatsn = icp->conn_expstatsn;
3134 data_sn = ntohl(ihp->datasn);
3135 data_sn++;
3136 lun = icmdp->cmd_un.scsi.lun;
3137 ISCSI_LUN_BYTE_COPY(ihp->lun, lun);
3138 /* CRM: upate_flow_control */
3139 ISCSI_IO_LOG(CE_NOTE, "DEBUG: iscsi_build_hdr"
3140 "(ISCSI_OP_SCSI_DATA): task: %p icp: %p ic: %p itt: %x "
3141 "exp: %d data_sn: %d", (void *)idm_task, (void *)icp,
3142 (void *)icp->conn_ic, ihp->itt, icp->conn_expstatsn,
3143 data_sn);
3144 } else {
3145 cmn_err(CE_WARN, "iscsi_build_hdr: unprocessed build "
3146 "header opcode: %x", opcode);
3147 }
3148 mutex_exit(&icmdp->cmd_mutex);
3149 }
3150
3151 static void
iscsi_process_rsp_status(iscsi_sess_t * isp,iscsi_conn_t * icp,idm_status_t status)3152 iscsi_process_rsp_status(iscsi_sess_t *isp, iscsi_conn_t *icp,
3153 idm_status_t status)
3154 {
3155 switch (status) {
3156 case IDM_STATUS_SUCCESS:
3157 if ((isp->sess_state == ISCSI_SESS_STATE_IN_FLUSH) &&
3158 (icp->conn_queue_active.count == 0)) {
3159 iscsi_drop_conn_cleanup(icp);
3160 }
3161 break;
3162 case IDM_STATUS_PROTOCOL_ERROR:
3163 KSTAT_INC_CONN_ERR_PROTOCOL(icp);
3164 iscsi_drop_conn_cleanup(icp);
3165 break;
3166 default:
3167 break;
3168 }
3169 }
3170
3171 static void
iscsi_drop_conn_cleanup(iscsi_conn_t * icp)3172 iscsi_drop_conn_cleanup(iscsi_conn_t *icp) {
3173 mutex_enter(&icp->conn_state_mutex);
3174 idm_ini_conn_disconnect(icp->conn_ic);
3175 mutex_exit(&icp->conn_state_mutex);
3176 }
3177
3178 void
iscsi_rx_error_pdu(idm_conn_t * ic,idm_pdu_t * pdu,idm_status_t status)3179 iscsi_rx_error_pdu(idm_conn_t *ic, idm_pdu_t *pdu, idm_status_t status)
3180 {
3181 iscsi_conn_t *icp = (iscsi_conn_t *)ic->ic_handle;
3182 iscsi_sess_t *isp;
3183
3184 ASSERT(icp != NULL);
3185 isp = icp->conn_sess;
3186 ASSERT(isp != NULL);
3187 iscsi_process_rsp_status(isp, icp, status);
3188 idm_pdu_complete(pdu, status);
3189 }
3190
3191 void
iscsi_rx_misc_pdu(idm_conn_t * ic,idm_pdu_t * pdu)3192 iscsi_rx_misc_pdu(idm_conn_t *ic, idm_pdu_t *pdu)
3193 {
3194 iscsi_conn_t *icp;
3195 iscsi_hdr_t *ihp = (iscsi_hdr_t *)pdu->isp_hdr;
3196 iscsi_sess_t *isp;
3197 idm_status_t status;
3198
3199 icp = ic->ic_handle;
3200 isp = icp->conn_sess;
3201 isp->sess_rx_lbolt = icp->conn_rx_lbolt = ddi_get_lbolt();
3202 switch (ihp->opcode & ISCSI_OPCODE_MASK) {
3203 case ISCSI_OP_LOGIN_RSP:
3204 status = iscsi_rx_process_login_pdu(ic, pdu);
3205 idm_pdu_complete(pdu, status);
3206 break;
3207 case ISCSI_OP_LOGOUT_RSP:
3208 status = iscsi_rx_process_logout_rsp(ic, pdu);
3209 idm_pdu_complete(pdu, status);
3210 break;
3211 case ISCSI_OP_REJECT_MSG:
3212 status = iscsi_rx_process_reject_rsp(ic, pdu);
3213 break;
3214 case ISCSI_OP_SCSI_TASK_MGT_RSP:
3215 status = iscsi_rx_process_task_mgt_rsp(ic, pdu);
3216 idm_pdu_complete(pdu, status);
3217 break;
3218 case ISCSI_OP_NOOP_IN:
3219 status = iscsi_rx_process_nop(ic, pdu);
3220 idm_pdu_complete(pdu, status);
3221 break;
3222 case ISCSI_OP_ASYNC_EVENT:
3223 status = iscsi_rx_process_async_rsp(ic, pdu);
3224 break;
3225 case ISCSI_OP_TEXT_RSP:
3226 status = iscsi_rx_process_text_rsp(ic, pdu);
3227 idm_pdu_complete(pdu, status);
3228 break;
3229 default:
3230 cmn_err(CE_WARN, "iscsi connection(%u) protocol error "
3231 "- received misc unsupported opcode 0x%02x",
3232 icp->conn_oid, ihp->opcode);
3233 status = IDM_STATUS_PROTOCOL_ERROR;
3234 break;
3235 }
3236 iscsi_process_rsp_status(isp, icp, status);
3237 }
3238
3239 /*
3240 * +--------------------------------------------------------------------+
3241 * | Beginning of completion routines |
3242 * +--------------------------------------------------------------------+
3243 */
3244
3245 /*
3246 * iscsi_ic_thread -
3247 */
3248 void
iscsi_ic_thread(iscsi_thread_t * thread,void * arg)3249 iscsi_ic_thread(iscsi_thread_t *thread, void *arg)
3250 {
3251 iscsi_sess_t *isp = (iscsi_sess_t *)arg;
3252 int ret;
3253 iscsi_queue_t q;
3254 iscsi_cmd_t *icmdp;
3255 iscsi_cmd_t *next_icmdp;
3256
3257 ASSERT(isp != NULL);
3258 ASSERT(thread != NULL);
3259 ASSERT(thread->signature == SIG_ISCSI_THREAD);
3260
3261 for (;;) {
3262
3263 /*
3264 * We wait till iodone or somebody else wakes us up.
3265 */
3266 ret = iscsi_thread_wait(thread, -1);
3267
3268 /*
3269 * The value should never be negative since we never timeout.
3270 */
3271 ASSERT(ret >= 0);
3272
3273 q.count = 0;
3274 q.head = NULL;
3275 q.tail = NULL;
3276 mutex_enter(&isp->sess_queue_completion.mutex);
3277 icmdp = isp->sess_queue_completion.head;
3278 while (icmdp != NULL) {
3279 next_icmdp = icmdp->cmd_next;
3280 mutex_enter(&icmdp->cmd_mutex);
3281 /*
3282 * check if the associated r2t/abort has finished
3283 * yet. If not, don't complete the command.
3284 */
3285 if ((icmdp->cmd_un.scsi.r2t_icmdp == NULL) &&
3286 (icmdp->cmd_un.scsi.abort_icmdp == NULL)) {
3287 mutex_exit(&icmdp->cmd_mutex);
3288 (void) iscsi_dequeue_cmd(&isp->
3289 sess_queue_completion.head,
3290 &isp->sess_queue_completion.tail,
3291 icmdp);
3292 --isp->sess_queue_completion.count;
3293 iscsi_enqueue_cmd_head(&q.head,
3294 &q.tail, icmdp);
3295 } else {
3296 mutex_exit(&icmdp->cmd_mutex);
3297 }
3298 icmdp = next_icmdp;
3299 }
3300 mutex_exit(&isp->sess_queue_completion.mutex);
3301 icmdp = q.head;
3302 while (icmdp != NULL) {
3303 next_icmdp = icmdp->cmd_next;
3304 iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E8, isp);
3305 icmdp = next_icmdp;
3306 }
3307
3308 if (ret > 0)
3309 /* Somebody woke us up to work */
3310 continue;
3311 else
3312 /*
3313 * Somebody woke us up to kill ourselves. We will
3314 * make sure, however that the completion queue is
3315 * empty before leaving. After we've done that it
3316 * is the originator of the signal that has to make
3317 * sure no other SCSI command is posted.
3318 */
3319 break;
3320 }
3321
3322 }
3323
3324 /*
3325 * iscsi_iodone -
3326 *
3327 */
3328 void
iscsi_iodone(iscsi_sess_t * isp,iscsi_cmd_t * icmdp)3329 iscsi_iodone(iscsi_sess_t *isp, iscsi_cmd_t *icmdp)
3330 {
3331 struct scsi_pkt *pkt = NULL;
3332 struct buf *bp = icmdp->cmd_un.scsi.bp;
3333
3334 ASSERT(isp != NULL);
3335 ASSERT(icmdp != NULL);
3336 pkt = icmdp->cmd_un.scsi.pkt;
3337 ASSERT(pkt != NULL);
3338
3339 ASSERT(icmdp->cmd_un.scsi.abort_icmdp == NULL);
3340 ASSERT(icmdp->cmd_un.scsi.r2t_icmdp == NULL);
3341 if (pkt->pkt_reason == CMD_CMPLT) {
3342 if (bp) {
3343 if (bp->b_flags & B_READ) {
3344 KSTAT_SESS_RX_IO_DONE(isp, bp->b_bcount);
3345 } else {
3346 KSTAT_SESS_TX_IO_DONE(isp, bp->b_bcount);
3347 }
3348 }
3349 }
3350
3351 if (pkt->pkt_flags & FLAG_NOINTR) {
3352 cv_broadcast(&icmdp->cmd_completion);
3353 mutex_exit(&icmdp->cmd_mutex);
3354 } else {
3355 /*
3356 * Release mutex. As soon as callback is
3357 * issued the caller may destroy the command.
3358 */
3359 mutex_exit(&icmdp->cmd_mutex);
3360 /*
3361 * We can't just directly call the pk_comp routine. In
3362 * many error cases the target driver will use the calling
3363 * thread to re-drive error handling (reset, retries...)
3364 * back into the hba driver (iscsi). If the target redrives
3365 * a reset back into the iscsi driver off this thead we have
3366 * a chance of deadlocking. So instead use the io completion
3367 * thread.
3368 */
3369 (*icmdp->cmd_un.scsi.pkt->pkt_comp)(icmdp->cmd_un.scsi.pkt);
3370 }
3371 }
3372
3373 /*
3374 * +--------------------------------------------------------------------+
3375 * | End of completion routines |
3376 * +--------------------------------------------------------------------+
3377 */
3378
3379 /*
3380 * +--------------------------------------------------------------------+
3381 * | Beginning of watchdog routines |
3382 * +--------------------------------------------------------------------+
3383 */
3384
3385 /*
3386 * iscsi_watchdog_thread -
3387 *
3388 */
3389 void
iscsi_wd_thread(iscsi_thread_t * thread,void * arg)3390 iscsi_wd_thread(iscsi_thread_t *thread, void *arg)
3391 {
3392 iscsi_sess_t *isp = (iscsi_sess_t *)arg;
3393 int rc = 1;
3394
3395 ASSERT(isp != NULL);
3396
3397 while (rc != NULL) {
3398
3399 iscsi_timeout_checks(isp);
3400 iscsi_nop_checks(isp);
3401
3402 rc = iscsi_thread_wait(thread, SEC_TO_TICK(1));
3403 }
3404 }
3405
3406 /*
3407 * iscsi_timeout_checks -
3408 *
3409 */
3410 static void
iscsi_timeout_checks(iscsi_sess_t * isp)3411 iscsi_timeout_checks(iscsi_sess_t *isp)
3412 {
3413 clock_t now = ddi_get_lbolt();
3414 iscsi_conn_t *icp;
3415 iscsi_cmd_t *icmdp, *nicmdp;
3416
3417 ASSERT(isp != NULL);
3418
3419 /* PENDING */
3420 rw_enter(&isp->sess_state_rwlock, RW_READER);
3421 mutex_enter(&isp->sess_queue_pending.mutex);
3422 for (icmdp = isp->sess_queue_pending.head;
3423 icmdp; icmdp = nicmdp) {
3424 nicmdp = icmdp->cmd_next;
3425
3426 /* Skip entries with no timeout */
3427 if (icmdp->cmd_lbolt_timeout == 0)
3428 continue;
3429
3430 /*
3431 * Skip pending queue entries for cmd_type values that depend
3432 * on having an open cmdsn window for successfull transition
3433 * from pending to the active (i.e. ones that depend on
3434 * sess_cmdsn .vs. sess_maxcmdsn). For them, the timer starts
3435 * when they are successfully moved to the active queue by
3436 * iscsi_cmd_state_pending() code.
3437 */
3438 /*
3439 * If the cmd is stuck, at least give it a chance
3440 * to timeout
3441 */
3442 if (((icmdp->cmd_type == ISCSI_CMD_TYPE_SCSI) ||
3443 (icmdp->cmd_type == ISCSI_CMD_TYPE_TEXT)) &&
3444 !(icmdp->cmd_misc_flags & ISCSI_CMD_MISCFLAG_STUCK))
3445 continue;
3446
3447 /* Skip if timeout still in the future */
3448 if (now <= icmdp->cmd_lbolt_timeout)
3449 continue;
3450
3451 /* timeout */
3452 iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E6, isp);
3453 }
3454 mutex_exit(&isp->sess_queue_pending.mutex);
3455 rw_exit(&isp->sess_state_rwlock);
3456
3457 rw_enter(&isp->sess_conn_list_rwlock, RW_READER);
3458 icp = isp->sess_conn_list;
3459 while (icp != NULL) {
3460
3461 icp->conn_timeout = B_FALSE;
3462 /* ACTIVE */
3463 mutex_enter(&icp->conn_state_mutex);
3464 mutex_enter(&isp->sess_queue_pending.mutex);
3465 mutex_enter(&icp->conn_queue_active.mutex);
3466 for (icmdp = icp->conn_queue_active.head;
3467 icmdp; icmdp = nicmdp) {
3468 nicmdp = icmdp->cmd_next;
3469
3470 if (iscsi_nop_timeout_checks(icmdp) == B_TRUE) {
3471 icp->conn_timeout = B_TRUE;
3472 }
3473
3474 /* Skip entries with no timeout */
3475 if (icmdp->cmd_lbolt_timeout == 0)
3476 continue;
3477
3478 /*
3479 * Skip if command is not active or not needed
3480 * to flush.
3481 */
3482 if (icmdp->cmd_state != ISCSI_CMD_STATE_ACTIVE &&
3483 !(icmdp->cmd_misc_flags & ISCSI_CMD_MISCFLAG_FLUSH))
3484 continue;
3485
3486 /* Skip if timeout still in the future */
3487 if (now <= icmdp->cmd_lbolt_timeout)
3488 continue;
3489
3490 if (icmdp->cmd_misc_flags & ISCSI_CMD_MISCFLAG_FLUSH) {
3491 /*
3492 * This command is left during target reset,
3493 * we can flush it now.
3494 */
3495 iscsi_cmd_state_machine(icmdp,
3496 ISCSI_CMD_EVENT_E7, isp);
3497 } else if (icmdp->cmd_state == ISCSI_CMD_STATE_ACTIVE) {
3498 /* timeout */
3499 iscsi_cmd_state_machine(icmdp,
3500 ISCSI_CMD_EVENT_E6, isp);
3501 }
3502
3503 }
3504 mutex_exit(&icp->conn_queue_active.mutex);
3505 mutex_exit(&isp->sess_queue_pending.mutex);
3506 mutex_exit(&icp->conn_state_mutex);
3507
3508 icp = icp->conn_next;
3509 }
3510
3511 icp = isp->sess_conn_list;
3512 while (icp != NULL) {
3513 if (icp->conn_timeout == B_TRUE) {
3514 /* timeout on this connect detected */
3515 idm_ini_conn_disconnect(icp->conn_ic);
3516 icp->conn_timeout = B_FALSE;
3517 }
3518 icp = icp->conn_next;
3519 }
3520 rw_exit(&isp->sess_conn_list_rwlock);
3521 }
3522
3523 /*
3524 * iscsi_nop_checks - sends a NOP on idle connections
3525 *
3526 * This function walks the connections on a session and
3527 * issues NOPs on those connections that are in FULL
3528 * FEATURE mode and have not received data for the
3529 * time period specified by iscsi_nop_delay (global).
3530 */
3531 static void
iscsi_nop_checks(iscsi_sess_t * isp)3532 iscsi_nop_checks(iscsi_sess_t *isp)
3533 {
3534 iscsi_conn_t *icp;
3535
3536 ASSERT(isp != NULL);
3537
3538 if (isp->sess_type == ISCSI_SESS_TYPE_DISCOVERY) {
3539 return;
3540 }
3541
3542 rw_enter(&isp->sess_conn_list_rwlock, RW_READER);
3543 icp = isp->sess_conn_act;
3544 if (icp != NULL) {
3545
3546 mutex_enter(&icp->conn_state_mutex);
3547 if ((ISCSI_CONN_STATE_FULL_FEATURE(icp->conn_state)) &&
3548 (ddi_get_lbolt() > isp->sess_conn_act->conn_rx_lbolt +
3549 SEC_TO_TICK(iscsi_nop_delay)) && (ddi_get_lbolt() >
3550 isp->sess_conn_act->conn_nop_lbolt +
3551 SEC_TO_TICK(iscsi_nop_delay))) {
3552
3553 /*
3554 * We haven't received anything from the
3555 * target is a defined period of time,
3556 * send NOP to see if the target is alive.
3557 */
3558 mutex_enter(&isp->sess_queue_pending.mutex);
3559 iscsi_handle_nop(isp->sess_conn_act,
3560 0, ISCSI_RSVD_TASK_TAG);
3561 mutex_exit(&isp->sess_queue_pending.mutex);
3562 }
3563 mutex_exit(&icp->conn_state_mutex);
3564
3565 icp = icp->conn_next;
3566 }
3567 rw_exit(&isp->sess_conn_list_rwlock);
3568 }
3569
3570 static boolean_t
iscsi_nop_timeout_checks(iscsi_cmd_t * icmdp)3571 iscsi_nop_timeout_checks(iscsi_cmd_t *icmdp)
3572 {
3573 if (icmdp->cmd_type == ISCSI_CMD_TYPE_NOP) {
3574 if ((ddi_get_lbolt() - icmdp->cmd_lbolt_active) >
3575 SEC_TO_TICK(ISCSI_CONN_TIEMOUT_DETECT)) {
3576 return (B_TRUE);
3577 } else {
3578 return (B_FALSE);
3579 }
3580 }
3581 return (B_FALSE);
3582 }
3583 /*
3584 * +--------------------------------------------------------------------+
3585 * | End of wd routines |
3586 * +--------------------------------------------------------------------+
3587 */
3588
3589 /*
3590 * iscsi_flush_cmd_after_reset - flush commands after reset
3591 *
3592 * Here we will flush all the commands for a specified LUN whose cmdsn is less
3593 * than the one received with the Unit Attention.
3594 */
3595 static void
iscsi_flush_cmd_after_reset(uint32_t cmd_sn,uint16_t lun_num,iscsi_conn_t * icp)3596 iscsi_flush_cmd_after_reset(uint32_t cmd_sn, uint16_t lun_num,
3597 iscsi_conn_t *icp)
3598 {
3599 iscsi_cmd_t *t_icmdp = NULL;
3600 iscsi_cmd_t *next_icmdp = NULL;
3601
3602 ASSERT(icp != NULL);
3603
3604 t_icmdp = icp->conn_queue_active.head;
3605 while (t_icmdp != NULL) {
3606 next_icmdp = t_icmdp->cmd_next;
3607 mutex_enter(&t_icmdp->cmd_mutex);
3608 /*
3609 * We will flush the commands whose cmdsn is less than the one
3610 * got Unit Attention.
3611 * Here we will check for wrap by subtracting and compare to
3612 * 1/2 of a 32 bit number, if greater then we wrapped.
3613 */
3614 if ((t_icmdp->cmd_misc_flags & ISCSI_CMD_MISCFLAG_SENT) &&
3615 ((cmd_sn > t_icmdp->cmd_sn) ||
3616 ((t_icmdp->cmd_sn - cmd_sn) >
3617 ISCSI_CMD_SN_WRAP))) {
3618 /*
3619 * Internally generated SCSI commands do not have
3620 * t_icmdp->cmd_lun set, but the LUN can be retrieved
3621 * from t_icmdp->cmd_un.scsi.lun.
3622 */
3623 if ((t_icmdp->cmd_lun != NULL &&
3624 t_icmdp->cmd_lun->lun_num == lun_num) ||
3625 (t_icmdp->cmd_type == ISCSI_CMD_TYPE_SCSI &&
3626 (t_icmdp->cmd_un.scsi.lun & ISCSI_LUN_MASK) ==
3627 lun_num)) {
3628 t_icmdp->cmd_misc_flags |=
3629 ISCSI_CMD_MISCFLAG_FLUSH;
3630 if (t_icmdp->cmd_type == ISCSI_CMD_TYPE_SCSI) {
3631 t_icmdp->cmd_un.scsi.pkt_stat |=
3632 STAT_BUS_RESET;
3633 }
3634 }
3635 }
3636 mutex_exit(&t_icmdp->cmd_mutex);
3637 t_icmdp = next_icmdp;
3638 }
3639 }
3640
3641 /*
3642 * iscsi_decode_sense - decode the sense data in the cmd response
3643 * and take proper actions
3644 */
3645 static boolean_t
iscsi_decode_sense(uint8_t * sense_data,iscsi_cmd_t * icmdp)3646 iscsi_decode_sense(uint8_t *sense_data, iscsi_cmd_t *icmdp)
3647 {
3648 uint8_t sense_key = 0;
3649 uint8_t asc = 0;
3650 uint8_t ascq = 0;
3651 boolean_t flush_io = B_FALSE;
3652 boolean_t reconfig_lun = B_FALSE;
3653 iscsi_sess_t *isp = NULL;
3654
3655 ASSERT(sense_data != NULL);
3656
3657 isp = icmdp->cmd_conn->conn_sess;
3658
3659 sense_key = scsi_sense_key(sense_data);
3660 switch (sense_key) {
3661 case KEY_UNIT_ATTENTION:
3662 asc = scsi_sense_asc(sense_data);
3663 switch (asc) {
3664 case ISCSI_SCSI_RESET_SENSE_CODE:
3665 /*
3666 * POWER ON, RESET, OR BUS_DEVICE RESET
3667 * OCCURRED
3668 */
3669 flush_io = B_TRUE;
3670 break;
3671 case ISCSI_SCSI_LUNCHANGED_CODE:
3672 ascq = scsi_sense_ascq(sense_data);
3673 if (ascq == ISCSI_SCSI_LUNCHANGED_ASCQ)
3674 reconfig_lun = B_TRUE;
3675 default:
3676 break;
3677 }
3678 break;
3679 default:
3680 /*
3681 * Currently we don't care
3682 * about other sense key.
3683 */
3684 break;
3685 }
3686
3687 if (reconfig_lun == B_TRUE) {
3688 rw_enter(&isp->sess_state_rwlock, RW_READER);
3689 if ((isp->sess_state == ISCSI_SESS_STATE_LOGGED_IN) &&
3690 (iscsi_sess_enum_request(isp, B_FALSE,
3691 isp->sess_state_event_count) !=
3692 ISCSI_SESS_ENUM_SUBMITTED)) {
3693 cmn_err(CE_WARN, "Unable to commit re-enumeration for"
3694 " session(%u) %s", isp->sess_oid, isp->sess_name);
3695 }
3696 rw_exit(&isp->sess_state_rwlock);
3697 }
3698
3699 return (flush_io);
3700 }
3701