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