Home | History | Annotate | Download | only in stmf_sbd
      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 2010 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #include <sys/conf.h>
     27 #include <sys/file.h>
     28 #include <sys/ddi.h>
     29 #include <sys/sunddi.h>
     30 #include <sys/modctl.h>
     31 #include <sys/scsi/scsi.h>
     32 #include <sys/scsi/impl/scsi_reset_notify.h>
     33 #include <sys/scsi/generic/mode.h>
     34 #include <sys/disp.h>
     35 #include <sys/byteorder.h>
     36 #include <sys/atomic.h>
     37 #include <sys/sdt.h>
     38 #include <sys/dkio.h>
     39 
     40 #include <stmf.h>
     41 #include <lpif.h>
     42 #include <portif.h>
     43 #include <stmf_ioctl.h>
     44 #include <stmf_sbd.h>
     45 #include <stmf_sbd_ioctl.h>
     46 #include <sbd_impl.h>
     47 
     48 #define	SCSI2_CONFLICT_FREE_CMDS(cdb)	( \
     49 	/* ----------------------- */                                      \
     50 	/* Refer Both		   */                                      \
     51 	/* SPC-2 (rev 20) Table 10 */                                      \
     52 	/* SPC-3 (rev 23) Table 31 */                                      \
     53 	/* ----------------------- */                                      \
     54 	((cdb[0]) == SCMD_INQUIRY)					|| \
     55 	((cdb[0]) == SCMD_LOG_SENSE_G1)					|| \
     56 	((cdb[0]) == SCMD_RELEASE)					|| \
     57 	((cdb[0]) == SCMD_RELEASE_G1)					|| \
     58 	((cdb[0]) == SCMD_REPORT_LUNS)					|| \
     59 	((cdb[0]) == SCMD_REQUEST_SENSE)				|| \
     60 	/* PREVENT ALLOW MEDIUM REMOVAL with prevent == 0 */               \
     61 	((((cdb[0]) == SCMD_DOORLOCK) && (((cdb[4]) & 0x3) == 0)))	|| \
     62 	/* SERVICE ACTION IN with READ MEDIA SERIAL NUMBER (0x01) */       \
     63 	(((cdb[0]) == SCMD_SVC_ACTION_IN_G5) && (                          \
     64 	    ((cdb[1]) & 0x1F) == 0x01))					|| \
     65 	/* MAINTENANCE IN with service actions REPORT ALIASES (0x0Bh) */   \
     66 	/* REPORT DEVICE IDENTIFIER (0x05)  REPORT PRIORITY (0x0Eh) */     \
     67 	/* REPORT TARGET PORT GROUPS (0x0A) REPORT TIMESTAMP (0x0F) */     \
     68 	(((cdb[0]) == SCMD_MAINTENANCE_IN) && (                            \
     69 	    (((cdb[1]) & 0x1F) == 0x0B) ||                                 \
     70 	    (((cdb[1]) & 0x1F) == 0x05) ||                                 \
     71 	    (((cdb[1]) & 0x1F) == 0x0E) ||                                 \
     72 	    (((cdb[1]) & 0x1F) == 0x0A) ||                                 \
     73 	    (((cdb[1]) & 0x1F) == 0x0F)))				|| \
     74 	/* ----------------------- */                                      \
     75 	/* SBC-3 (rev 17) Table 3  */                                      \
     76 	/* ----------------------- */                                      \
     77 	/* READ CAPACITY(10) */                                            \
     78 	((cdb[0]) == SCMD_READ_CAPACITY)				|| \
     79 	/* READ CAPACITY(16) */                                            \
     80 	(((cdb[0]) == SCMD_SVC_ACTION_IN_G4) && (                          \
     81 	    ((cdb[1]) & 0x1F) == 0x10))					|| \
     82 	/* START STOP UNIT with START bit 0 and POWER CONDITION 0  */      \
     83 	(((cdb[0]) == SCMD_START_STOP) && (                                \
     84 	    (((cdb[4]) & 0xF0) == 0) && (((cdb[4]) & 0x01) == 0))))
     85 /* End of SCSI2_CONFLICT_FREE_CMDS */
     86 
     87 stmf_status_t sbd_lu_reset_state(stmf_lu_t *lu);
     88 static void sbd_handle_sync_cache(struct scsi_task *task,
     89     struct stmf_data_buf *initial_dbuf);
     90 void sbd_handle_read_xfer_completion(struct scsi_task *task,
     91     sbd_cmd_t *scmd, struct stmf_data_buf *dbuf);
     92 void sbd_handle_short_write_xfer_completion(scsi_task_t *task,
     93     stmf_data_buf_t *dbuf);
     94 void sbd_handle_short_write_transfers(scsi_task_t *task,
     95     stmf_data_buf_t *dbuf, uint32_t cdb_xfer_size);
     96 static void sbd_handle_sync_cache(struct scsi_task *task,
     97     struct stmf_data_buf *initial_dbuf);
     98 void sbd_handle_mode_select_xfer(scsi_task_t *task, uint8_t *buf,
     99     uint32_t buflen);
    100 void sbd_handle_mode_select(scsi_task_t *task, stmf_data_buf_t *dbuf);
    101 
    102 extern void sbd_pgr_initialize_it(scsi_task_t *);
    103 extern int sbd_pgr_reservation_conflict(scsi_task_t *);
    104 extern void sbd_pgr_reset(sbd_lu_t *);
    105 extern void sbd_pgr_remove_it_handle(sbd_lu_t *, sbd_it_data_t *);
    106 extern void sbd_handle_pgr_in_cmd(scsi_task_t *, stmf_data_buf_t *);
    107 extern void sbd_handle_pgr_out_cmd(scsi_task_t *, stmf_data_buf_t *);
    108 extern void sbd_handle_pgr_out_data(scsi_task_t *, stmf_data_buf_t *);
    109 /*
    110  * IMPORTANT NOTE:
    111  * =================
    112  * The whole world here is based on the assumption that everything within
    113  * a scsi task executes in a single threaded manner, even the aborts.
    114  * Dont ever change that. There wont be any performance gain but there
    115  * will be tons of race conditions.
    116  */
    117 
    118 void
    119 sbd_do_read_xfer(struct scsi_task *task, sbd_cmd_t *scmd,
    120 					struct stmf_data_buf *dbuf)
    121 {
    122 	sbd_lu_t *sl = (sbd_lu_t *)task->task_lu->lu_provider_private;
    123 	uint64_t laddr;
    124 	uint32_t len, buflen, iolen;
    125 	int ndx;
    126 	int bufs_to_take;
    127 
    128 	/* Lets try not to hog all the buffers the port has. */
    129 	bufs_to_take = ((task->task_max_nbufs > 2) &&
    130 	    (task->task_cmd_xfer_length < (32 * 1024))) ? 2 :
    131 	    task->task_max_nbufs;
    132 
    133 	len = scmd->len > dbuf->db_buf_size ? dbuf->db_buf_size : scmd->len;
    134 	laddr = scmd->addr + scmd->current_ro;
    135 
    136 	for (buflen = 0, ndx = 0; (buflen < len) &&
    137 	    (ndx < dbuf->db_sglist_length); ndx++) {
    138 		iolen = min(len - buflen, dbuf->db_sglist[ndx].seg_length);
    139 		if (iolen == 0)
    140 			break;
    141 		if (sbd_data_read(sl, laddr, (uint64_t)iolen,
    142 		    dbuf->db_sglist[ndx].seg_addr) != STMF_SUCCESS) {
    143 			scmd->flags |= SBD_SCSI_CMD_XFER_FAIL;
    144 			/* Do not need to do xfer anymore, just complete it */
    145 			dbuf->db_data_size = 0;
    146 			dbuf->db_xfer_status = STMF_SUCCESS;
    147 			sbd_handle_read_xfer_completion(task, scmd, dbuf);
    148 			return;
    149 		}
    150 		buflen += iolen;
    151 		laddr += (uint64_t)iolen;
    152 	}
    153 	dbuf->db_relative_offset = scmd->current_ro;
    154 	dbuf->db_data_size = buflen;
    155 	dbuf->db_flags = DB_DIRECTION_TO_RPORT;
    156 	(void) stmf_xfer_data(task, dbuf, 0);
    157 	scmd->len -= buflen;
    158 	scmd->current_ro += buflen;
    159 	if (scmd->len && (scmd->nbufs < bufs_to_take)) {
    160 		uint32_t maxsize, minsize, old_minsize;
    161 
    162 		maxsize = (scmd->len > (128*1024)) ? 128*1024 : scmd->len;
    163 		minsize = maxsize >> 2;
    164 		do {
    165 			/*
    166 			 * A bad port implementation can keep on failing the
    167 			 * the request but keep on sending us a false
    168 			 * minsize.
    169 			 */
    170 			old_minsize = minsize;
    171 			dbuf = stmf_alloc_dbuf(task, maxsize, &minsize, 0);
    172 		} while ((dbuf == NULL) && (old_minsize > minsize) &&
    173 		    (minsize >= 512));
    174 		if (dbuf == NULL) {
    175 			return;
    176 		}
    177 		scmd->nbufs++;
    178 		sbd_do_read_xfer(task, scmd, dbuf);
    179 	}
    180 }
    181 
    182 void
    183 sbd_handle_read_xfer_completion(struct scsi_task *task, sbd_cmd_t *scmd,
    184 				struct stmf_data_buf *dbuf)
    185 {
    186 	if (dbuf->db_xfer_status != STMF_SUCCESS) {
    187 		stmf_abort(STMF_QUEUE_TASK_ABORT, task,
    188 		    dbuf->db_xfer_status, NULL);
    189 		return;
    190 	}
    191 	task->task_nbytes_transferred += dbuf->db_data_size;
    192 	if (scmd->len == 0 || scmd->flags & SBD_SCSI_CMD_XFER_FAIL) {
    193 		stmf_free_dbuf(task, dbuf);
    194 		scmd->nbufs--;
    195 		if (scmd->nbufs)
    196 			return;	/* wait for all buffers to complete */
    197 		scmd->flags &= ~SBD_SCSI_CMD_ACTIVE;
    198 		if (scmd->flags & SBD_SCSI_CMD_XFER_FAIL)
    199 			stmf_scsilib_send_status(task, STATUS_CHECK,
    200 			    STMF_SAA_READ_ERROR);
    201 		else
    202 			stmf_scsilib_send_status(task, STATUS_GOOD, 0);
    203 		return;
    204 	}
    205 	if (dbuf->db_flags & DB_DONT_REUSE) {
    206 		/* allocate new dbuf */
    207 		uint32_t maxsize, minsize, old_minsize;
    208 		stmf_free_dbuf(task, dbuf);
    209 
    210 		maxsize = (scmd->len > (128*1024)) ? 128*1024 : scmd->len;
    211 		minsize = maxsize >> 2;
    212 		do {
    213 			old_minsize = minsize;
    214 			dbuf = stmf_alloc_dbuf(task, maxsize, &minsize, 0);
    215 		} while ((dbuf == NULL) && (old_minsize > minsize) &&
    216 		    (minsize >= 512));
    217 		if (dbuf == NULL) {
    218 			scmd->nbufs --;
    219 			if (scmd->nbufs == 0) {
    220 				stmf_abort(STMF_QUEUE_TASK_ABORT, task,
    221 				    STMF_ALLOC_FAILURE, NULL);
    222 			}
    223 			return;
    224 		}
    225 	}
    226 	sbd_do_read_xfer(task, scmd, dbuf);
    227 }
    228 
    229 void
    230 sbd_handle_read(struct scsi_task *task, struct stmf_data_buf *initial_dbuf)
    231 {
    232 	uint64_t lba, laddr;
    233 	uint32_t len;
    234 	uint8_t op = task->task_cdb[0];
    235 	sbd_lu_t *sl = (sbd_lu_t *)task->task_lu->lu_provider_private;
    236 	sbd_cmd_t *scmd;
    237 	stmf_data_buf_t *dbuf;
    238 	int fast_path;
    239 
    240 	if (op == SCMD_READ) {
    241 		lba = READ_SCSI21(&task->task_cdb[1], uint64_t);
    242 		len = (uint32_t)task->task_cdb[4];
    243 
    244 		if (len == 0) {
    245 			len = 256;
    246 		}
    247 	} else if (op == SCMD_READ_G1) {
    248 		lba = READ_SCSI32(&task->task_cdb[2], uint64_t);
    249 		len = READ_SCSI16(&task->task_cdb[7], uint32_t);
    250 	} else if (op == SCMD_READ_G5) {
    251 		lba = READ_SCSI32(&task->task_cdb[2], uint64_t);
    252 		len = READ_SCSI32(&task->task_cdb[6], uint32_t);
    253 	} else if (op == SCMD_READ_G4) {
    254 		lba = READ_SCSI64(&task->task_cdb[2], uint64_t);
    255 		len = READ_SCSI32(&task->task_cdb[10], uint32_t);
    256 	} else {
    257 		stmf_scsilib_send_status(task, STATUS_CHECK,
    258 		    STMF_SAA_INVALID_OPCODE);
    259 		return;
    260 	}
    261 
    262 	laddr = lba << sl->sl_data_blocksize_shift;
    263 	len <<= sl->sl_data_blocksize_shift;
    264 
    265 	if ((laddr + (uint64_t)len) > sl->sl_lu_size) {
    266 		stmf_scsilib_send_status(task, STATUS_CHECK,
    267 		    STMF_SAA_LBA_OUT_OF_RANGE);
    268 		return;
    269 	}
    270 
    271 	task->task_cmd_xfer_length = len;
    272 	if (task->task_additional_flags & TASK_AF_NO_EXPECTED_XFER_LENGTH) {
    273 		task->task_expected_xfer_length = len;
    274 	}
    275 
    276 	if (len != task->task_expected_xfer_length) {
    277 		fast_path = 0;
    278 		len = (len > task->task_expected_xfer_length) ?
    279 		    task->task_expected_xfer_length : len;
    280 	} else {
    281 		fast_path = 1;
    282 	}
    283 
    284 	if (len == 0) {
    285 		stmf_scsilib_send_status(task, STATUS_GOOD, 0);
    286 		return;
    287 	}
    288 
    289 	if (initial_dbuf == NULL) {
    290 		uint32_t maxsize, minsize, old_minsize;
    291 
    292 		maxsize = (len > (128*1024)) ? 128*1024 : len;
    293 		minsize = maxsize >> 2;
    294 		do {
    295 			old_minsize = minsize;
    296 			initial_dbuf = stmf_alloc_dbuf(task, maxsize,
    297 			    &minsize, 0);
    298 		} while ((initial_dbuf == NULL) && (old_minsize > minsize) &&
    299 		    (minsize >= 512));
    300 		if (initial_dbuf == NULL) {
    301 			stmf_scsilib_send_status(task, STATUS_QFULL, 0);
    302 			return;
    303 		}
    304 	}
    305 	dbuf = initial_dbuf;
    306 
    307 	if ((dbuf->db_buf_size >= len) && fast_path &&
    308 	    (dbuf->db_sglist_length == 1)) {
    309 		if (sbd_data_read(sl, laddr, (uint64_t)len,
    310 		    dbuf->db_sglist[0].seg_addr) == STMF_SUCCESS) {
    311 			dbuf->db_relative_offset = 0;
    312 			dbuf->db_data_size = len;
    313 			dbuf->db_flags = DB_SEND_STATUS_GOOD |
    314 			    DB_DIRECTION_TO_RPORT;
    315 			(void) stmf_xfer_data(task, dbuf, STMF_IOF_LU_DONE);
    316 		} else {
    317 			stmf_scsilib_send_status(task, STATUS_CHECK,
    318 			    STMF_SAA_READ_ERROR);
    319 		}
    320 		return;
    321 	}
    322 
    323 	if (task->task_lu_private) {
    324 		scmd = (sbd_cmd_t *)task->task_lu_private;
    325 	} else {
    326 		scmd = (sbd_cmd_t *)kmem_alloc(sizeof (sbd_cmd_t), KM_SLEEP);
    327 		task->task_lu_private = scmd;
    328 	}
    329 	scmd->flags = SBD_SCSI_CMD_ACTIVE;
    330 	scmd->cmd_type = SBD_CMD_SCSI_READ;
    331 	scmd->nbufs = 1;
    332 	scmd->addr = laddr;
    333 	scmd->len = len;
    334 	scmd->current_ro = 0;
    335 
    336 	sbd_do_read_xfer(task, scmd, dbuf);
    337 }
    338 
    339 void
    340 sbd_do_write_xfer(struct scsi_task *task, sbd_cmd_t *scmd,
    341     struct stmf_data_buf *dbuf, uint8_t dbuf_reusable)
    342 {
    343 	uint32_t len;
    344 	int bufs_to_take;
    345 
    346 	if (scmd->len == 0) {
    347 		goto DO_WRITE_XFER_DONE;
    348 	}
    349 
    350 	/* Lets try not to hog all the buffers the port has. */
    351 	bufs_to_take = ((task->task_max_nbufs > 2) &&
    352 	    (task->task_cmd_xfer_length < (32 * 1024))) ? 2 :
    353 	    task->task_max_nbufs;
    354 
    355 	if ((dbuf != NULL) &&
    356 	    ((dbuf->db_flags & DB_DONT_REUSE) || (dbuf_reusable == 0))) {
    357 		/* free current dbuf and allocate a new one */
    358 		stmf_free_dbuf(task, dbuf);
    359 		dbuf = NULL;
    360 	}
    361 	if (scmd->nbufs >= bufs_to_take) {
    362 		goto DO_WRITE_XFER_DONE;
    363 	}
    364 	if (dbuf == NULL) {
    365 		uint32_t maxsize, minsize, old_minsize;
    366 
    367 		maxsize = (scmd->len > (128*1024)) ? 128*1024 :
    368 		    scmd->len;
    369 		minsize = maxsize >> 2;
    370 		do {
    371 			old_minsize = minsize;
    372 			dbuf = stmf_alloc_dbuf(task, maxsize, &minsize, 0);
    373 		} while ((dbuf == NULL) && (old_minsize > minsize) &&
    374 		    (minsize >= 512));
    375 		if (dbuf == NULL) {
    376 			if (scmd->nbufs == 0) {
    377 				stmf_abort(STMF_QUEUE_TASK_ABORT, task,
    378 				    STMF_ALLOC_FAILURE, NULL);
    379 			}
    380 			return;
    381 		}
    382 	}
    383 
    384 	len = scmd->len > dbuf->db_buf_size ? dbuf->db_buf_size :
    385 	    scmd->len;
    386 
    387 	dbuf->db_relative_offset = scmd->current_ro;
    388 	dbuf->db_data_size = len;
    389 	dbuf->db_flags = DB_DIRECTION_FROM_RPORT;
    390 	(void) stmf_xfer_data(task, dbuf, 0);
    391 	scmd->nbufs++; /* outstanding port xfers and bufs used */
    392 	scmd->len -= len;
    393 	scmd->current_ro += len;
    394 
    395 	if ((scmd->len != 0) && (scmd->nbufs < bufs_to_take)) {
    396 		sbd_do_write_xfer(task, scmd, NULL, 0);
    397 	}
    398 	return;
    399 
    400 DO_WRITE_XFER_DONE:
    401 	if (dbuf != NULL) {
    402 		stmf_free_dbuf(task, dbuf);
    403 	}
    404 }
    405 
    406 void
    407 sbd_handle_write_xfer_completion(struct scsi_task *task, sbd_cmd_t *scmd,
    408     struct stmf_data_buf *dbuf, uint8_t dbuf_reusable)
    409 {
    410 	sbd_lu_t *sl = (sbd_lu_t *)task->task_lu->lu_provider_private;
    411 	uint64_t laddr;
    412 	uint32_t buflen, iolen;
    413 	int ndx;
    414 
    415 	if (scmd->nbufs > 0) {
    416 		/*
    417 		 * Decrement the count to indicate the port xfer
    418 		 * into the dbuf has completed even though the buf is
    419 		 * still in use here in the LU provider.
    420 		 */
    421 		scmd->nbufs--;
    422 	}
    423 
    424 	if (dbuf->db_xfer_status != STMF_SUCCESS) {
    425 		stmf_abort(STMF_QUEUE_TASK_ABORT, task,
    426 		    dbuf->db_xfer_status, NULL);
    427 		return;
    428 	}
    429 
    430 	if (scmd->flags & SBD_SCSI_CMD_XFER_FAIL) {
    431 		goto WRITE_XFER_DONE;
    432 	}
    433 
    434 	if (scmd->len != 0) {
    435 		/*
    436 		 * Initiate the next port xfer to occur in parallel
    437 		 * with writing this buf.
    438 		 */
    439 		sbd_do_write_xfer(task, scmd, NULL, 0);
    440 	}
    441 
    442 	laddr = scmd->addr + dbuf->db_relative_offset;
    443 
    444 	for (buflen = 0, ndx = 0; (buflen < dbuf->db_data_size) &&
    445 	    (ndx < dbuf->db_sglist_length); ndx++) {
    446 		iolen = min(dbuf->db_data_size - buflen,
    447 		    dbuf->db_sglist[ndx].seg_length);
    448 		if (iolen == 0)
    449 			break;
    450 		if (sbd_data_write(sl, laddr, (uint64_t)iolen,
    451 		    dbuf->db_sglist[ndx].seg_addr) != STMF_SUCCESS) {
    452 			scmd->flags |= SBD_SCSI_CMD_XFER_FAIL;
    453 			break;
    454 		}
    455 		buflen += iolen;
    456 		laddr += (uint64_t)iolen;
    457 	}
    458 	task->task_nbytes_transferred += buflen;
    459 WRITE_XFER_DONE:
    460 	if (scmd->len == 0 || scmd->flags & SBD_SCSI_CMD_XFER_FAIL) {
    461 		stmf_free_dbuf(task, dbuf);
    462 		if (scmd->nbufs)
    463 			return;	/* wait for all buffers to complete */
    464 		scmd->flags &= ~SBD_SCSI_CMD_ACTIVE;
    465 		if (scmd->flags & SBD_SCSI_CMD_XFER_FAIL)
    466 			stmf_scsilib_send_status(task, STATUS_CHECK,
    467 			    STMF_SAA_WRITE_ERROR);
    468 		else
    469 			stmf_scsilib_send_status(task, STATUS_GOOD, 0);
    470 		return;
    471 	}
    472 	sbd_do_write_xfer(task, scmd, dbuf, dbuf_reusable);
    473 }
    474 
    475 void
    476 sbd_handle_write(struct scsi_task *task, struct stmf_data_buf *initial_dbuf)
    477 {
    478 	uint64_t lba, laddr;
    479 	uint32_t len;
    480 	uint8_t op = task->task_cdb[0], do_immediate_data = 0;
    481 	sbd_lu_t *sl = (sbd_lu_t *)task->task_lu->lu_provider_private;
    482 	sbd_cmd_t *scmd;
    483 	stmf_data_buf_t *dbuf;
    484 
    485 	if (sl->sl_flags & SL_WRITE_PROTECTED) {
    486 		stmf_scsilib_send_status(task, STATUS_CHECK,
    487 		    STMF_SAA_WRITE_PROTECTED);
    488 		return;
    489 	}
    490 	if (op == SCMD_WRITE) {
    491 		lba = READ_SCSI21(&task->task_cdb[1], uint64_t);
    492 		len = (uint32_t)task->task_cdb[4];
    493 
    494 		if (len == 0) {
    495 			len = 256;
    496 		}
    497 	} else if (op == SCMD_WRITE_G1) {
    498 		lba = READ_SCSI32(&task->task_cdb[2], uint64_t);
    499 		len = READ_SCSI16(&task->task_cdb[7], uint32_t);
    500 	} else if (op == SCMD_WRITE_G5) {
    501 		lba = READ_SCSI32(&task->task_cdb[2], uint64_t);
    502 		len = READ_SCSI32(&task->task_cdb[6], uint32_t);
    503 	} else if (op == SCMD_WRITE_G4) {
    504 		lba = READ_SCSI64(&task->task_cdb[2], uint64_t);
    505 		len = READ_SCSI32(&task->task_cdb[10], uint32_t);
    506 	} else {
    507 		stmf_scsilib_send_status(task, STATUS_CHECK,
    508 		    STMF_SAA_INVALID_OPCODE);
    509 		return;
    510 	}
    511 
    512 	laddr = lba << sl->sl_data_blocksize_shift;
    513 	len <<= sl->sl_data_blocksize_shift;
    514 
    515 	if ((laddr + (uint64_t)len) > sl->sl_lu_size) {
    516 		stmf_scsilib_send_status(task, STATUS_CHECK,
    517 		    STMF_SAA_LBA_OUT_OF_RANGE);
    518 		return;
    519 	}
    520 
    521 	task->task_cmd_xfer_length = len;
    522 	if (task->task_additional_flags & TASK_AF_NO_EXPECTED_XFER_LENGTH) {
    523 		task->task_expected_xfer_length = len;
    524 	}
    525 
    526 	len = (len > task->task_expected_xfer_length) ?
    527 	    task->task_expected_xfer_length : len;
    528 
    529 	if (len == 0) {
    530 		stmf_scsilib_send_status(task, STATUS_GOOD, 0);
    531 		return;
    532 	}
    533 
    534 	if ((initial_dbuf != NULL) && (task->task_flags & TF_INITIAL_BURST)) {
    535 		if (initial_dbuf->db_data_size > len) {
    536 			if (initial_dbuf->db_data_size >
    537 			    task->task_expected_xfer_length) {
    538 				/* protocol error */
    539 				stmf_abort(STMF_QUEUE_TASK_ABORT, task,
    540 				    STMF_INVALID_ARG, NULL);
    541 				return;
    542 			}
    543 			initial_dbuf->db_data_size = len;
    544 		}
    545 		do_immediate_data = 1;
    546 	}
    547 	dbuf = initial_dbuf;
    548 
    549 	if (task->task_lu_private) {
    550 		scmd = (sbd_cmd_t *)task->task_lu_private;
    551 	} else {
    552 		scmd = (sbd_cmd_t *)kmem_alloc(sizeof (sbd_cmd_t), KM_SLEEP);
    553 		task->task_lu_private = scmd;
    554 	}
    555 	scmd->flags = SBD_SCSI_CMD_ACTIVE;
    556 	scmd->cmd_type = SBD_CMD_SCSI_WRITE;
    557 	scmd->nbufs = 0;
    558 	scmd->addr = laddr;
    559 	scmd->len = len;
    560 	scmd->current_ro = 0;
    561 
    562 	if (do_immediate_data) {
    563 		scmd->len -= dbuf->db_data_size;
    564 		scmd->current_ro += dbuf->db_data_size;
    565 		dbuf->db_xfer_status = STMF_SUCCESS;
    566 		sbd_handle_write_xfer_completion(task, scmd, dbuf, 0);
    567 	} else {
    568 		sbd_do_write_xfer(task, scmd, dbuf, 0);
    569 	}
    570 }
    571 
    572 /*
    573  * Utility routine to handle small non performance data transfers to the
    574  * initiators. dbuf is an initial data buf (if any), 'p' points to a data
    575  * buffer which is source of data for transfer, cdb_xfer_size is the
    576  * transfer size based on CDB, cmd_xfer_size is the actual amount of data
    577  * which this command would transfer (the size of data pointed to by 'p').
    578  */
    579 void
    580 sbd_handle_short_read_transfers(scsi_task_t *task, stmf_data_buf_t *dbuf,
    581     uint8_t *p, uint32_t cdb_xfer_size, uint32_t cmd_xfer_size)
    582 {
    583 	uint32_t bufsize, ndx;
    584 	sbd_cmd_t *scmd;
    585 
    586 	cmd_xfer_size = min(cmd_xfer_size, cdb_xfer_size);
    587 
    588 	task->task_cmd_xfer_length = cmd_xfer_size;
    589 	if (task->task_additional_flags & TASK_AF_NO_EXPECTED_XFER_LENGTH) {
    590 		task->task_expected_xfer_length = cmd_xfer_size;
    591 	} else {
    592 		cmd_xfer_size = min(cmd_xfer_size,
    593 		    task->task_expected_xfer_length);
    594 	}
    595 
    596 	if (cmd_xfer_size == 0) {
    597 		stmf_scsilib_send_status(task, STATUS_CHECK,
    598 		    STMF_SAA_INVALID_FIELD_IN_CDB);
    599 		return;
    600 	}
    601 	if (dbuf == NULL) {
    602 		uint32_t minsize = cmd_xfer_size;
    603 
    604 		dbuf = stmf_alloc_dbuf(task, cmd_xfer_size, &minsize, 0);
    605 	}
    606 	if (dbuf == NULL) {
    607 		stmf_scsilib_send_status(task, STATUS_QFULL, 0);
    608 		return;
    609 	}
    610 
    611 	for (bufsize = 0, ndx = 0; bufsize < cmd_xfer_size; ndx++) {
    612 		uint8_t *d;
    613 		uint32_t s;
    614 
    615 		d = dbuf->db_sglist[ndx].seg_addr;
    616 		s = min((cmd_xfer_size - bufsize),
    617 		    dbuf->db_sglist[ndx].seg_length);
    618 		bcopy(p+bufsize, d, s);
    619 		bufsize += s;
    620 	}
    621 	dbuf->db_relative_offset = 0;
    622 	dbuf->db_data_size = cmd_xfer_size;
    623 	dbuf->db_flags = DB_DIRECTION_TO_RPORT;
    624 
    625 	if (task->task_lu_private == NULL) {
    626 		task->task_lu_private =
    627 		    kmem_alloc(sizeof (sbd_cmd_t), KM_SLEEP);
    628 	}
    629 	scmd = (sbd_cmd_t *)task->task_lu_private;
    630 
    631 	scmd->cmd_type = SBD_CMD_SMALL_READ;
    632 	scmd->flags = SBD_SCSI_CMD_ACTIVE;
    633 	(void) stmf_xfer_data(task, dbuf, 0);
    634 }
    635 
    636 void
    637 sbd_handle_short_read_xfer_completion(struct scsi_task *task, sbd_cmd_t *scmd,
    638 				struct stmf_data_buf *dbuf)
    639 {
    640 	if (dbuf->db_xfer_status != STMF_SUCCESS) {
    641 		stmf_abort(STMF_QUEUE_TASK_ABORT, task,
    642 		    dbuf->db_xfer_status, NULL);
    643 		return;
    644 	}
    645 	task->task_nbytes_transferred = dbuf->db_data_size;
    646 	scmd->flags &= ~SBD_SCSI_CMD_ACTIVE;
    647 	stmf_scsilib_send_status(task, STATUS_GOOD, 0);
    648 }
    649 
    650 void
    651 sbd_handle_short_write_transfers(scsi_task_t *task,
    652     stmf_data_buf_t *dbuf, uint32_t cdb_xfer_size)
    653 {
    654 	sbd_cmd_t *scmd;
    655 
    656 	task->task_cmd_xfer_length = cdb_xfer_size;
    657 	if (task->task_additional_flags & TASK_AF_NO_EXPECTED_XFER_LENGTH) {
    658 		task->task_expected_xfer_length = cdb_xfer_size;
    659 	} else {
    660 		cdb_xfer_size = min(cdb_xfer_size,
    661 		    task->task_expected_xfer_length);
    662 	}
    663 
    664 	if (cdb_xfer_size == 0) {
    665 		stmf_scsilib_send_status(task, STATUS_CHECK,
    666 		    STMF_SAA_INVALID_FIELD_IN_CDB);
    667 		return;
    668 	}
    669 	if (task->task_lu_private == NULL) {
    670 		task->task_lu_private = kmem_zalloc(sizeof (sbd_cmd_t),
    671 		    KM_SLEEP);
    672 	} else {
    673 		bzero(task->task_lu_private, sizeof (sbd_cmd_t));
    674 	}
    675 	scmd = (sbd_cmd_t *)task->task_lu_private;
    676 	scmd->cmd_type = SBD_CMD_SMALL_WRITE;
    677 	scmd->flags = SBD_SCSI_CMD_ACTIVE;
    678 	scmd->len = cdb_xfer_size;
    679 	if (dbuf == NULL) {
    680 		uint32_t minsize = cdb_xfer_size;
    681 
    682 		dbuf = stmf_alloc_dbuf(task, cdb_xfer_size, &minsize, 0);
    683 		if (dbuf == NULL) {
    684 			stmf_abort(STMF_QUEUE_TASK_ABORT, task,
    685 			    STMF_ALLOC_FAILURE, NULL);
    686 			return;
    687 		}
    688 		dbuf->db_data_size = cdb_xfer_size;
    689 		dbuf->db_relative_offset = 0;
    690 		dbuf->db_flags = DB_DIRECTION_FROM_RPORT;
    691 		(void) stmf_xfer_data(task, dbuf, 0);
    692 	} else {
    693 		if (dbuf->db_data_size < cdb_xfer_size) {
    694 			stmf_abort(STMF_QUEUE_TASK_ABORT, task,
    695 			    STMF_ABORTED, NULL);
    696 			return;
    697 		}
    698 		dbuf->db_data_size = cdb_xfer_size;
    699 		sbd_handle_short_write_xfer_completion(task, dbuf);
    700 	}
    701 }
    702 
    703 void
    704 sbd_handle_short_write_xfer_completion(scsi_task_t *task,
    705     stmf_data_buf_t *dbuf)
    706 {
    707 	sbd_cmd_t *scmd;
    708 	stmf_status_t st_ret;
    709 	sbd_lu_t *sl = (sbd_lu_t *)task->task_lu->lu_provider_private;
    710 
    711 	/*
    712 	 * For now lets assume we will get only one sglist element
    713 	 * for short writes. If that ever changes, we should allocate
    714 	 * a local buffer and copy all the sg elements to one linear space.
    715 	 */
    716 	if ((dbuf->db_xfer_status != STMF_SUCCESS) ||
    717 	    (dbuf->db_sglist_length > 1)) {
    718 		stmf_abort(STMF_QUEUE_TASK_ABORT, task,
    719 		    dbuf->db_xfer_status, NULL);
    720 		return;
    721 	}
    722 
    723 	task->task_nbytes_transferred = dbuf->db_data_size;
    724 	scmd = (sbd_cmd_t *)task->task_lu_private;
    725 	scmd->flags &= ~SBD_SCSI_CMD_ACTIVE;
    726 
    727 	/* Lets find out who to call */
    728 	switch (task->task_cdb[0]) {
    729 	case SCMD_MODE_SELECT:
    730 	case SCMD_MODE_SELECT_G1:
    731 		if (sl->sl_access_state == SBD_LU_STANDBY) {
    732 			st_ret = stmf_proxy_scsi_cmd(task, dbuf);
    733 			if (st_ret != STMF_SUCCESS) {
    734 				stmf_scsilib_send_status(task, STATUS_CHECK,
    735 				    STMF_SAA_LU_NO_ACCESS_UNAVAIL);
    736 			}
    737 		} else {
    738 			sbd_handle_mode_select_xfer(task,
    739 			    dbuf->db_sglist[0].seg_addr, dbuf->db_data_size);
    740 		}
    741 		break;
    742 	case SCMD_PERSISTENT_RESERVE_OUT:
    743 		if (sl->sl_access_state == SBD_LU_STANDBY) {
    744 			st_ret = stmf_proxy_scsi_cmd(task, dbuf);
    745 			if (st_ret != STMF_SUCCESS) {
    746 				stmf_scsilib_send_status(task, STATUS_CHECK,
    747 				    STMF_SAA_LU_NO_ACCESS_UNAVAIL);
    748 			}
    749 		} else {
    750 			sbd_handle_pgr_out_data(task, dbuf);
    751 		}
    752 		break;
    753 	default:
    754 		/* This should never happen */
    755 		stmf_abort(STMF_QUEUE_TASK_ABORT, task,
    756 		    STMF_ABORTED, NULL);
    757 	}
    758 }
    759 
    760 void
    761 sbd_handle_read_capacity(struct scsi_task *task,
    762     struct stmf_data_buf *initial_dbuf)
    763 {
    764 	sbd_lu_t *sl = (sbd_lu_t *)task->task_lu->lu_provider_private;
    765 	uint32_t cdb_len;
    766 	uint8_t p[32];
    767 	uint64_t s;
    768 	uint16_t blksize;
    769 
    770 	s = sl->sl_lu_size >> sl->sl_data_blocksize_shift;
    771 	s--;
    772 	blksize = ((uint16_t)1) << sl->sl_data_blocksize_shift;
    773 
    774 	switch (task->task_cdb[0]) {
    775 	case SCMD_READ_CAPACITY:
    776 		if (s & 0xffffffff00000000ull) {
    777 			p[0] = p[1] = p[2] = p[3] = 0xFF;
    778 		} else {
    779 			p[0] = (s >> 24) & 0xff;
    780 			p[1] = (s >> 16) & 0xff;
    781 			p[2] = (s >> 8) & 0xff;
    782 			p[3] = s & 0xff;
    783 		}
    784 		p[4] = 0; p[5] = 0;
    785 		p[6] = (blksize >> 8) & 0xff;
    786 		p[7] = blksize & 0xff;
    787 		sbd_handle_short_read_transfers(task, initial_dbuf, p, 8, 8);
    788 		break;
    789 
    790 	case SCMD_SVC_ACTION_IN_G4:
    791 		cdb_len = READ_SCSI32(&task->task_cdb[10], uint32_t);
    792 		bzero(p, 32);
    793 		p[0] = (s >> 56) & 0xff;
    794 		p[1] = (s >> 48) & 0xff;
    795 		p[2] = (s >> 40) & 0xff;
    796 		p[3] = (s >> 32) & 0xff;
    797 		p[4] = (s >> 24) & 0xff;
    798 		p[5] = (s >> 16) & 0xff;
    799 		p[6] = (s >> 8) & 0xff;
    800 		p[7] = s & 0xff;
    801 		p[10] = (blksize >> 8) & 0xff;
    802 		p[11] = blksize & 0xff;
    803 		sbd_handle_short_read_transfers(task, initial_dbuf, p,
    804 		    cdb_len, 32);
    805 		break;
    806 	}
    807 }
    808 
    809 void
    810 sbd_calc_geometry(uint64_t s, uint16_t blksize, uint8_t *nsectors,
    811     uint8_t *nheads, uint32_t *ncyl)
    812 {
    813 	if (s < (4ull * 1024ull * 1024ull * 1024ull)) {
    814 		*nsectors = 32;
    815 		*nheads = 8;
    816 	} else {
    817 		*nsectors = 254;
    818 		*nheads = 254;
    819 	}
    820 	*ncyl = s / ((uint64_t)blksize * (uint64_t)(*nsectors) *
    821 	    (uint64_t)(*nheads));
    822 }
    823 
    824 void
    825 sbd_handle_mode_sense(struct scsi_task *task,
    826     struct stmf_data_buf *initial_dbuf, uint8_t *buf)
    827 {
    828 	sbd_lu_t *sl = (sbd_lu_t *)task->task_lu->lu_provider_private;
    829 	uint32_t cmd_size, n;
    830 	uint8_t *cdb;
    831 	uint32_t ncyl;
    832 	uint8_t nsectors, nheads;
    833 	uint8_t page, ctrl, header_size, pc_valid;
    834 	uint16_t nbytes;
    835 	uint8_t *p;
    836 	uint64_t s = sl->sl_lu_size;
    837 	uint32_t dev_spec_param_offset;
    838 
    839 	p = buf;	/* buf is assumed to be zeroed out and large enough */
    840 	n = 0;
    841 	cdb = &task->task_cdb[0];
    842 	page = cdb[2] & 0x3F;
    843 	ctrl = (cdb[2] >> 6) & 3;
    844 	cmd_size = (cdb[0] == SCMD_MODE_SENSE) ? cdb[4] :
    845 	    READ_SCSI16(&cdb[7], uint32_t);
    846 
    847 	if (cdb[0] == SCMD_MODE_SENSE) {
    848 		header_size = 4;
    849 		dev_spec_param_offset = 2;
    850 	} else {
    851 		header_size = 8;
    852 		dev_spec_param_offset = 3;
    853 	}
    854 
    855 	/* Now validate the command */
    856 	if ((cdb[2] == 0) || (page == MODEPAGE_ALLPAGES) || (page == 0x08) ||
    857 	    (page == 0x0A) || (page == 0x03) || (page == 0x04)) {
    858 		pc_valid = 1;
    859 	} else {
    860 		pc_valid = 0;
    861 	}
    862 	if ((cmd_size < header_size) || (pc_valid == 0)) {
    863 		stmf_scsilib_send_status(task, STATUS_CHECK,
    864 		    STMF_SAA_INVALID_FIELD_IN_CDB);
    865 		return;
    866 	}
    867 
    868 	/* We will update the length in the mode header at the end */
    869 
    870 	/* Block dev device specific param in mode param header has wp bit */
    871 	if (sl->sl_flags & SL_WRITE_PROTECTED) {
    872 		p[n + dev_spec_param_offset] = BIT_7;
    873 	}
    874 	n += header_size;
    875 	/* We are not going to return any block descriptor */
    876 
    877 	nbytes = ((uint16_t)1) << sl->sl_data_blocksize_shift;
    878 	sbd_calc_geometry(s, nbytes, &nsectors, &nheads, &ncyl);
    879 
    880 	if ((page == 0x03) || (page == MODEPAGE_ALLPAGES)) {
    881 		p[n] = 0x03;
    882 		p[n+1] = 0x16;
    883 		if (ctrl != 1) {
    884 			p[n + 11] = nsectors;
    885 			p[n + 12] = nbytes >> 8;
    886 			p[n + 13] = nbytes & 0xff;
    887 			p[n + 20] = 0x80;
    888 		}
    889 		n += 24;
    890 	}
    891 	if ((page == 0x04) || (page == MODEPAGE_ALLPAGES)) {
    892 		p[n] = 0x04;
    893 		p[n + 1] = 0x16;
    894 		if (ctrl != 1) {
    895 			p[n + 2] = ncyl >> 16;
    896 			p[n + 3] = ncyl >> 8;
    897 			p[n + 4] = ncyl & 0xff;
    898 			p[n + 5] = nheads;
    899 			p[n + 20] = 0x15;
    900 			p[n + 21] = 0x18;
    901 		}
    902 		n += 24;
    903 	}
    904 	if ((page == MODEPAGE_CACHING) || (page == MODEPAGE_ALLPAGES)) {
    905 		struct mode_caching *mode_caching_page;
    906 
    907 		mode_caching_page = (struct mode_caching *)&p[n];
    908 
    909 		mode_caching_page->mode_page.code = MODEPAGE_CACHING;
    910 		mode_caching_page->mode_page.ps = 1; /* A saveable page */
    911 		mode_caching_page->mode_page.length = 0x12;
    912 
    913 		switch (ctrl) {
    914 		case (0):
    915 			/* Current */
    916 			if ((sl->sl_flags & SL_WRITEBACK_CACHE_DISABLE) == 0) {
    917 				mode_caching_page->wce = 1;
    918 			}
    919 			break;
    920 
    921 		case (1):
    922 			/* Changeable */
    923 			if ((sl->sl_flags &
    924 			    SL_WRITEBACK_CACHE_SET_UNSUPPORTED) == 0) {
    925 				mode_caching_page->wce = 1;
    926 			}
    927 			break;
    928 
    929 		default:
    930 			if ((sl->sl_flags &
    931 			    SL_SAVED_WRITE_CACHE_DISABLE) == 0) {
    932 				mode_caching_page->wce = 1;
    933 			}
    934 			break;
    935 		}
    936 		n += (sizeof (struct mode_page) +
    937 		    mode_caching_page->mode_page.length);
    938 	}
    939 	if ((page == MODEPAGE_CTRL_MODE) || (page == MODEPAGE_ALLPAGES)) {
    940 		struct mode_control_scsi3 *mode_control_page;
    941 
    942 		mode_control_page = (struct mode_control_scsi3 *)&p[n];
    943 
    944 		mode_control_page->mode_page.code = MODEPAGE_CTRL_MODE;
    945 		mode_control_page->mode_page.length =
    946 		    PAGELENGTH_MODE_CONTROL_SCSI3;
    947 		if (ctrl != 1) {
    948 			/* If not looking for changeable values, report this. */
    949 			mode_control_page->que_mod = CTRL_QMOD_UNRESTRICT;
    950 		}
    951 		n += (sizeof (struct mode_page) +
    952 		    mode_control_page->mode_page.length);
    953 	}
    954 
    955 	if (cdb[0] == SCMD_MODE_SENSE) {
    956 		if (n > 255) {
    957 			stmf_scsilib_send_status(task, STATUS_CHECK,
    958 			    STMF_SAA_INVALID_FIELD_IN_CDB);
    959 			return;
    960 		}
    961 		/*
    962 		 * Mode parameter header length doesn't include the number
    963 		 * of bytes in the length field, so adjust the count.
    964 		 * Byte count minus header length field size.
    965 		 */
    966 		buf[0] = (n - 1) & 0xff;
    967 	} else {
    968 		/* Byte count minus header length field size. */
    969 		buf[1] = (n - 2) & 0xff;
    970 		buf[0] = ((n - 2) >> 8) & 0xff;
    971 	}
    972 
    973 	sbd_handle_short_read_transfers(task, initial_dbuf, buf,
    974 	    cmd_size, n);
    975 }
    976 
    977 void
    978 sbd_handle_mode_select(scsi_task_t *task, stmf_data_buf_t *dbuf)
    979 {
    980 	uint32_t cmd_xfer_len;
    981 
    982 	if (task->task_cdb[0] == SCMD_MODE_SELECT) {
    983 		cmd_xfer_len = (uint32_t)task->task_cdb[4];
    984 	} else {
    985 		cmd_xfer_len = READ_SCSI16(&task->task_cdb[7], uint32_t);
    986 	}
    987 
    988 	if ((task->task_cdb[1] & 0xFE) != 0x10) {
    989 		stmf_scsilib_send_status(task, STATUS_CHECK,
    990 		    STMF_SAA_INVALID_FIELD_IN_CDB);
    991 		return;
    992 	}
    993 
    994 	if (cmd_xfer_len == 0) {
    995 		/* zero byte mode selects are allowed */
    996 		stmf_scsilib_send_status(task, STATUS_GOOD, 0);
    997 		return;
    998 	}
    999 
   1000 	sbd_handle_short_write_transfers(task, dbuf, cmd_xfer_len);
   1001 }
   1002 
   1003 void
   1004 sbd_handle_mode_select_xfer(scsi_task_t *task, uint8_t *buf, uint32_t buflen)
   1005 {
   1006 	sbd_lu_t *sl = (sbd_lu_t *)task->task_lu->lu_provider_private;
   1007 	sbd_it_data_t *it;
   1008 	int hdr_len, bd_len;
   1009 	sbd_status_t sret;
   1010 	int i;
   1011 
   1012 	if (task->task_cdb[0] == SCMD_MODE_SELECT) {
   1013 		hdr_len = 4;
   1014 	} else {
   1015 		hdr_len = 8;
   1016 	}
   1017 
   1018 	if (buflen < hdr_len)
   1019 		goto mode_sel_param_len_err;
   1020 
   1021 	bd_len = hdr_len == 4 ? buf[3] : READ_SCSI16(&buf[6], int);
   1022 
   1023 	if (buflen < (hdr_len + bd_len + 2))
   1024 		goto mode_sel_param_len_err;
   1025 
   1026 	buf += hdr_len + bd_len;
   1027 	buflen -= hdr_len + bd_len;
   1028 
   1029 	if ((buf[0] != 8) || (buflen != ((uint32_t)buf[1] + 2))) {
   1030 		goto mode_sel_param_len_err;
   1031 	}
   1032 
   1033 	if (buf[2] & 0xFB) {
   1034 		goto mode_sel_param_field_err;
   1035 	}
   1036 
   1037 	for (i = 3; i < (buf[1] + 2); i++) {
   1038 		if (buf[i]) {
   1039 			goto mode_sel_param_field_err;
   1040 		}
   1041 	}
   1042 
   1043 	sret = SBD_SUCCESS;
   1044 
   1045 	/* All good. Lets handle the write cache change, if any */
   1046 	if (buf[2] & BIT_2) {
   1047 		sret = sbd_wcd_set(0, sl);
   1048 	} else {
   1049 		sret = sbd_wcd_set(1, sl);
   1050 	}
   1051 
   1052 	if (sret != SBD_SUCCESS) {
   1053 		stmf_scsilib_send_status(task, STATUS_CHECK,
   1054 		    STMF_SAA_WRITE_ERROR);
   1055 		return;
   1056 	}
   1057 
   1058 	/* set on the device passed, now set the flags */
   1059 	mutex_enter(&sl->sl_lock);
   1060 	if (buf[2] & BIT_2) {
   1061 		sl->sl_flags &= ~SL_WRITEBACK_CACHE_DISABLE;
   1062 	} else {
   1063 		sl->sl_flags |= SL_WRITEBACK_CACHE_DISABLE;
   1064 	}
   1065 
   1066 	for (it = sl->sl_it_list; it != NULL; it = it->sbd_it_next) {
   1067 		if (it == task->task_lu_itl_handle)
   1068 			continue;
   1069 		it->sbd_it_ua_conditions |= SBD_UA_MODE_PARAMETERS_CHANGED;
   1070 	}
   1071 
   1072 	if (task->task_cdb[1] & 1) {
   1073 		if (buf[2] & BIT_2) {
   1074 			sl->sl_flags &= ~SL_SAVED_WRITE_CACHE_DISABLE;
   1075 		} else {
   1076 			sl->sl_flags |= SL_SAVED_WRITE_CACHE_DISABLE;
   1077 		}
   1078 		mutex_exit(&sl->sl_lock);
   1079 		sret = sbd_write_lu_info(sl);
   1080 	} else {
   1081 		mutex_exit(&sl->sl_lock);
   1082 	}
   1083 	if (sret == SBD_SUCCESS) {
   1084 		stmf_scsilib_send_status(task, STATUS_GOOD, 0);
   1085 	} else {
   1086 		stmf_scsilib_send_status(task, STATUS_CHECK,
   1087 		    STMF_SAA_WRITE_ERROR);
   1088 	}
   1089 	return;
   1090 
   1091 mode_sel_param_len_err:
   1092 	stmf_scsilib_send_status(task, STATUS_CHECK,
   1093 	    STMF_SAA_PARAM_LIST_LENGTH_ERROR);
   1094 	return;
   1095 mode_sel_param_field_err:
   1096 	stmf_scsilib_send_status(task, STATUS_CHECK,
   1097 	    STMF_SAA_INVALID_FIELD_IN_PARAM_LIST);
   1098 }
   1099 
   1100 /*
   1101  * This function parse through a string, passed to it as a pointer to a string,
   1102  * by adjusting the pointer to the first non-space character and returns
   1103  * the count/length of the first bunch of non-space characters. Multiple
   1104  * Management URLs are stored as a space delimited string in sl_mgmt_url
   1105  * field of sbd_lu_t. This function is used to retrieve one url at a time.
   1106  *
   1107  * i/p : pointer to pointer to a url string
   1108  * o/p : Adjust the pointer to the url to the first non white character
   1109  *       and returns the length of the URL
   1110  */
   1111 uint16_t
   1112 sbd_parse_mgmt_url(char **url_addr) {
   1113 	uint16_t url_length = 0;
   1114 	char *url;
   1115 	url = *url_addr;
   1116 
   1117 	while (*url != '\0') {
   1118 		if (*url == ' ' || *url == '\t' || *url == '\n') {
   1119 			(*url_addr)++;
   1120 			url = *url_addr;
   1121 		} else {
   1122 			break;
   1123 		}
   1124 	}
   1125 
   1126 	while (*url != '\0') {
   1127 		if (*url == ' ' || *url == '\t' ||
   1128 		    *url == '\n' || *url == '\0') {
   1129 			break;
   1130 		}
   1131 		url++;
   1132 		url_length++;
   1133 	}
   1134 	return (url_length);
   1135 }
   1136 
   1137 void
   1138 sbd_handle_inquiry(struct scsi_task *task, struct stmf_data_buf *initial_dbuf)
   1139 {
   1140 	sbd_lu_t *sl = (sbd_lu_t *)task->task_lu->lu_provider_private;
   1141 	uint8_t *cdbp = (uint8_t *)&task->task_cdb[0];
   1142 	uint8_t *p;
   1143 	uint8_t byte0;
   1144 	uint8_t page_length;
   1145 	uint16_t bsize = 512;
   1146 	uint16_t cmd_size;
   1147 	uint32_t xfer_size = 4;
   1148 	uint32_t mgmt_url_size = 0;
   1149 	char *mgmt_url = NULL;
   1150 
   1151 
   1152 	byte0 = DTYPE_DIRECT;
   1153 	/*
   1154 	 * Basic protocol checks.
   1155 	 */
   1156 
   1157 	if ((((cdbp[1] & 1) == 0) && cdbp[2]) || cdbp[5]) {
   1158 		stmf_scsilib_send_status(task, STATUS_CHECK,
   1159 		    STMF_SAA_INVALID_FIELD_IN_CDB);
   1160 		return;
   1161 	}
   1162 
   1163 	/*
   1164 	 * Zero byte allocation length is not an error.  Just
   1165 	 * return success.
   1166 	 */
   1167 
   1168 	cmd_size = (((uint16_t)cdbp[3]) << 8) | cdbp[4];
   1169 
   1170 	if (cmd_size == 0) {
   1171 		task->task_cmd_xfer_length = 0;
   1172 		if (task->task_additional_flags &
   1173 		    TASK_AF_NO_EXPECTED_XFER_LENGTH) {
   1174 			task->task_expected_xfer_length = 0;
   1175 		}
   1176 		stmf_scsilib_send_status(task, STATUS_GOOD, 0);
   1177 		return;
   1178 	}
   1179 
   1180 	/*
   1181 	 * Standard inquiry
   1182 	 */
   1183 
   1184 	if ((cdbp[1] & 1) == 0) {
   1185 		int	i;
   1186 		struct scsi_inquiry *inq;
   1187 
   1188 		p = (uint8_t *)kmem_zalloc(bsize, KM_SLEEP);
   1189 		inq = (struct scsi_inquiry *)p;
   1190 
   1191 		page_length = 69;
   1192 		xfer_size = page_length + 5;
   1193 
   1194 		inq->inq_dtype = DTYPE_DIRECT;
   1195 		inq->inq_ansi = 5;	/* SPC-3 */
   1196 		inq->inq_hisup = 1;
   1197 		inq->inq_rdf = 2;	/* Response data format for SPC-3 */
   1198 		inq->inq_len = page_length;
   1199 
   1200 		inq->inq_tpgs = TPGS_FAILOVER_IMPLICIT;
   1201 		inq->inq_cmdque = 1;
   1202 
   1203 		if (sl->sl_flags & SL_VID_VALID) {
   1204 			bcopy(sl->sl_vendor_id, inq->inq_vid, 8);
   1205 		} else {
   1206 			bcopy(sbd_vendor_id, inq->inq_vid, 8);
   1207 		}
   1208 
   1209 		if (sl->sl_flags & SL_PID_VALID) {
   1210 			bcopy(sl->sl_product_id, inq->inq_pid, 16);
   1211 		} else {
   1212 			bcopy(sbd_product_id, inq->inq_pid, 16);
   1213 		}
   1214 
   1215 		if (sl->sl_flags & SL_REV_VALID) {
   1216 			bcopy(sl->sl_revision, inq->inq_revision, 4);
   1217 		} else {
   1218 			bcopy(sbd_revision, inq->inq_revision, 4);
   1219 		}
   1220 
   1221 		/* Adding Version Descriptors */
   1222 		i = 0;
   1223 		/* SAM-3 no version */
   1224 		inq->inq_vd[i].inq_vd_msb = 0x00;
   1225 		inq->inq_vd[i].inq_vd_lsb = 0x60;
   1226 		i++;
   1227 
   1228 		/* transport */
   1229 		switch (task->task_lport->lport_id->protocol_id) {
   1230 		case PROTOCOL_FIBRE_CHANNEL:
   1231 			inq->inq_vd[i].inq_vd_msb = 0x09;
   1232 			inq->inq_vd[i].inq_vd_lsb = 0x00;
   1233 			i++;
   1234 			break;
   1235 
   1236 		case PROTOCOL_PARALLEL_SCSI:
   1237 		case PROTOCOL_SSA:
   1238 		case PROTOCOL_IEEE_1394:
   1239 			/* Currently no claims of conformance */
   1240 			break;
   1241 
   1242 		case PROTOCOL_SRP:
   1243 			inq->inq_vd[i].inq_vd_msb = 0x09;
   1244 			inq->inq_vd[i].inq_vd_lsb = 0x40;
   1245 			i++;
   1246 			break;
   1247 
   1248 		case PROTOCOL_iSCSI:
   1249 			inq->inq_vd[i].inq_vd_msb = 0x09;
   1250 			inq->inq_vd[i].inq_vd_lsb = 0x60;
   1251 			i++;
   1252 			break;
   1253 
   1254 		case PROTOCOL_SAS:
   1255 		case PROTOCOL_ADT:
   1256 		case PROTOCOL_ATAPI:
   1257 		default:
   1258 			/* Currently no claims of conformance */
   1259 			break;
   1260 		}
   1261 
   1262 		/* SPC-3 no version */
   1263 		inq->inq_vd[i].inq_vd_msb = 0x03;
   1264 		inq->inq_vd[i].inq_vd_lsb = 0x00;
   1265 		i++;
   1266 
   1267 		/* SBC-2 no version */
   1268 		inq->inq_vd[i].inq_vd_msb = 0x03;
   1269 		inq->inq_vd[i].inq_vd_lsb = 0x20;
   1270 
   1271 		sbd_handle_short_read_transfers(task, initial_dbuf, p, cmd_size,
   1272 		    min(cmd_size, xfer_size));
   1273 		kmem_free(p, bsize);
   1274 
   1275 		return;
   1276 	}
   1277 
   1278 	rw_enter(&sbd_global_prop_lock, RW_READER);
   1279 	if (sl->sl_mgmt_url) {
   1280 		mgmt_url_size = strlen(sl->sl_mgmt_url);
   1281 		mgmt_url = sl->sl_mgmt_url;
   1282 	} else if (sbd_mgmt_url) {
   1283 		mgmt_url_size = strlen(sbd_mgmt_url);
   1284 		mgmt_url = sbd_mgmt_url;
   1285 	}
   1286 
   1287 	/*
   1288 	 * EVPD handling
   1289 	 */
   1290 
   1291 	/* Default 512 bytes may not be enough, increase bsize if necessary */
   1292 	if (cdbp[2] == 0x83 || cdbp[2] == 0x85) {
   1293 		if (bsize <  cmd_size)
   1294 			bsize = cmd_size;
   1295 	}
   1296 	p = (uint8_t *)kmem_zalloc(bsize, KM_SLEEP);
   1297 
   1298 	switch (cdbp[2]) {
   1299 	case 0x00:
   1300 		page_length = 4 + (mgmt_url_size ? 1 : 0);
   1301 
   1302 		p[0] = byte0;
   1303 		p[3] = page_length;
   1304 		/* Supported VPD pages in ascending order */
   1305 		{
   1306 			uint8_t i = 5;
   1307 
   1308 			p[i++] = 0x80;
   1309 			p[i++] = 0x83;
   1310 			if (mgmt_url_size != 0)
   1311 				p[i++] = 0x85;
   1312 			p[i++] = 0x86;
   1313 		}
   1314 		xfer_size = page_length + 4;
   1315 		break;
   1316 
   1317 	case 0x80:
   1318 		if (sl->sl_serial_no_size) {
   1319 			page_length = sl->sl_serial_no_size;
   1320 			bcopy(sl->sl_serial_no, p + 4, sl->sl_serial_no_size);
   1321 		} else {
   1322 			/* if no serial num is specified set 4 spaces */
   1323 			page_length = 4;
   1324 			bcopy("    ", p + 4, 4);
   1325 		}
   1326 		p[0] = byte0;
   1327 		p[1] = 0x80;
   1328 		p[3] = page_length;
   1329 		xfer_size = page_length + 4;
   1330 		break;
   1331 
   1332 	case 0x83:
   1333 		xfer_size = stmf_scsilib_prepare_vpd_page83(task, p,
   1334 		    bsize, byte0, STMF_VPD_LU_ID|STMF_VPD_TARGET_ID|
   1335 		    STMF_VPD_TP_GROUP|STMF_VPD_RELATIVE_TP_ID);
   1336 		break;
   1337 
   1338 	case 0x85:
   1339 		if (mgmt_url_size == 0) {
   1340 			stmf_scsilib_send_status(task, STATUS_CHECK,
   1341 			    STMF_SAA_INVALID_FIELD_IN_CDB);
   1342 			goto err_done;
   1343 		}
   1344 		{
   1345 			uint16_t idx, newidx, sz, url_size;
   1346 			char *url;
   1347 
   1348 			p[0] = byte0;
   1349 			p[1] = 0x85;
   1350 
   1351 			idx = 4;
   1352 			url = mgmt_url;
   1353 			url_size = sbd_parse_mgmt_url(&url);
   1354 			/* Creating Network Service Descriptors */
   1355 			while (url_size != 0) {
   1356 				/* Null terminated and 4 Byte aligned */
   1357 				sz = url_size + 1;
   1358 				sz += (sz % 4) ? 4 - (sz % 4) : 0;
   1359 				newidx = idx + sz + 4;
   1360 
   1361 				if (newidx < bsize) {
   1362 					/*
   1363 					 * SPC-3r23 : Table 320  (Sec 7.6.5)
   1364 					 * (Network service descriptor format
   1365 					 *
   1366 					 * Note: Hard coding service type as
   1367 					 * "Storage Configuration Service".
   1368 					 */
   1369 					p[idx] = 1;
   1370 					SCSI_WRITE16(p + idx + 2, sz);
   1371 					bcopy(url, p + idx + 4, url_size);
   1372 					xfer_size = newidx + 4;
   1373 				}
   1374 				idx = newidx;
   1375 
   1376 				/* skip to next mgmt url if any */
   1377 				url += url_size;
   1378 				url_size = sbd_parse_mgmt_url(&url);
   1379 			}
   1380 
   1381 			/* Total descriptor length */
   1382 			SCSI_WRITE16(p + 2, idx - 4);
   1383 			break;
   1384 		}
   1385 
   1386 	case 0x86:
   1387 		page_length = 0x3c;
   1388 
   1389 		p[0] = byte0;
   1390 		p[1] = 0x86;		/* Page 86 response */
   1391 		p[3] = page_length;
   1392 
   1393 		/*
   1394 		 * Bits 0, 1, and 2 will need to be updated
   1395 		 * to reflect the queue tag handling if/when
   1396 		 * that is implemented.  For now, we're going
   1397 		 * to claim support only for Simple TA.
   1398 		 */
   1399 		p[5] = 1;
   1400 		xfer_size = page_length + 4;
   1401 		break;
   1402 
   1403 	default:
   1404 		stmf_scsilib_send_status(task, STATUS_CHECK,
   1405 		    STMF_SAA_INVALID_FIELD_IN_CDB);
   1406 		goto err_done;
   1407 	}
   1408 
   1409 	sbd_handle_short_read_transfers(task, initial_dbuf, p, cmd_size,
   1410 	    min(cmd_size, xfer_size));
   1411 err_done:
   1412 	kmem_free(p, bsize);
   1413 	rw_exit(&sbd_global_prop_lock);
   1414 }
   1415 
   1416 stmf_status_t
   1417 sbd_task_alloc(struct scsi_task *task)
   1418 {
   1419 	if ((task->task_lu_private =
   1420 	    kmem_alloc(sizeof (sbd_cmd_t), KM_NOSLEEP)) != NULL) {
   1421 		sbd_cmd_t *scmd = (sbd_cmd_t *)task->task_lu_private;
   1422 		scmd->flags = 0;
   1423 		return (STMF_SUCCESS);
   1424 	}
   1425 	return (STMF_ALLOC_FAILURE);
   1426 }
   1427 
   1428 void
   1429 sbd_remove_it_handle(sbd_lu_t *sl, sbd_it_data_t *it)
   1430 {
   1431 	sbd_it_data_t **ppit;
   1432 
   1433 	sbd_pgr_remove_it_handle(sl, it);
   1434 	mutex_enter(&sl->sl_lock);
   1435 	for (ppit = &sl->sl_it_list; *ppit != NULL;
   1436 	    ppit = &((*ppit)->sbd_it_next)) {
   1437 		if ((*ppit) == it) {
   1438 			*ppit = it->sbd_it_next;
   1439 			break;
   1440 		}
   1441 	}
   1442 	mutex_exit(&sl->sl_lock);
   1443 
   1444 	DTRACE_PROBE2(itl__nexus__end, stmf_lu_t *, sl->sl_lu,
   1445 	    sbd_it_data_t *, it);
   1446 
   1447 	kmem_free(it, sizeof (*it));
   1448 }
   1449 
   1450 void
   1451 sbd_check_and_clear_scsi2_reservation(sbd_lu_t *sl, sbd_it_data_t *it)
   1452 {
   1453 	mutex_enter(&sl->sl_lock);
   1454 	if ((sl->sl_flags & SL_LU_HAS_SCSI2_RESERVATION) == 0) {
   1455 		/* If we dont have any reservations, just get out. */
   1456 		mutex_exit(&sl->sl_lock);
   1457 		return;
   1458 	}
   1459 
   1460 	if (it == NULL) {
   1461 		/* Find the I_T nexus which is holding the reservation. */
   1462 		for (it = sl->sl_it_list; it != NULL; it = it->sbd_it_next) {
   1463 			if (it->sbd_it_flags & SBD_IT_HAS_SCSI2_RESERVATION) {
   1464 				ASSERT(it->sbd_it_session_id ==
   1465 				    sl->sl_rs_owner_session_id);
   1466 				break;
   1467 			}
   1468 		}
   1469 		ASSERT(it != NULL);
   1470 	} else {
   1471 		/*
   1472 		 * We were passed an I_T nexus. If this nexus does not hold
   1473 		 * the reservation, do nothing. This is why this function is
   1474 		 * called "check_and_clear".
   1475 		 */
   1476 		if ((it->sbd_it_flags & SBD_IT_HAS_SCSI2_RESERVATION) == 0) {
   1477 			mutex_exit(&sl->sl_lock);
   1478 			return;
   1479 		}
   1480 	}
   1481 	it->sbd_it_flags &= ~SBD_IT_HAS_SCSI2_RESERVATION;
   1482 	sl->sl_flags &= ~SL_LU_HAS_SCSI2_RESERVATION;
   1483 	mutex_exit(&sl->sl_lock);
   1484 }
   1485 
   1486 
   1487 
   1488 void
   1489 sbd_new_task(struct scsi_task *task, struct stmf_data_buf *initial_dbuf)
   1490 {
   1491 	sbd_lu_t *sl = (sbd_lu_t *)task->task_lu->lu_provider_private;
   1492 	sbd_it_data_t *it;
   1493 	uint8_t cdb0, cdb1;
   1494 	stmf_status_t st_ret;
   1495 
   1496 	if ((it = task->task_lu_itl_handle) == NULL) {
   1497 		mutex_enter(&sl->sl_lock);
   1498 		for (it = sl->sl_it_list; it != NULL; it = it->sbd_it_next) {
   1499 			if (it->sbd_it_session_id ==
   1500 			    task->task_session->ss_session_id) {
   1501 				mutex_exit(&sl->sl_lock);
   1502 				stmf_scsilib_send_status(task, STATUS_BUSY, 0);
   1503 				return;
   1504 			}
   1505 		}
   1506 		it = (sbd_it_data_t *)kmem_zalloc(sizeof (*it), KM_NOSLEEP);
   1507 		if (it == NULL) {
   1508 			mutex_exit(&sl->sl_lock);
   1509 			stmf_scsilib_send_status(task, STATUS_BUSY, 0);
   1510 			return;
   1511 		}
   1512 		it->sbd_it_session_id = task->task_session->ss_session_id;
   1513 		bcopy(task->task_lun_no, it->sbd_it_lun, 8);
   1514 		it->sbd_it_next = sl->sl_it_list;
   1515 		sl->sl_it_list = it;
   1516 		mutex_exit(&sl->sl_lock);
   1517 
   1518 		DTRACE_PROBE1(itl__nexus__start, scsi_task *, task);
   1519 
   1520 		sbd_pgr_initialize_it(task);
   1521 		if (stmf_register_itl_handle(task->task_lu, task->task_lun_no,
   1522 		    task->task_session, it->sbd_it_session_id, it)
   1523 		    != STMF_SUCCESS) {
   1524 			sbd_remove_it_handle(sl, it);
   1525 			stmf_scsilib_send_status(task, STATUS_BUSY, 0);
   1526 			return;
   1527 		}
   1528 		task->task_lu_itl_handle = it;
   1529 		if (sl->sl_access_state != SBD_LU_STANDBY) {
   1530 			it->sbd_it_ua_conditions = SBD_UA_POR;
   1531 		}
   1532 	} else if (it->sbd_it_flags & SBD_IT_PGR_CHECK_FLAG) {
   1533 		sbd_pgr_initialize_it(task);
   1534 		mutex_enter(&sl->sl_lock);
   1535 		it->sbd_it_flags &= ~SBD_IT_PGR_CHECK_FLAG;
   1536 		mutex_exit(&sl->sl_lock);
   1537 	}
   1538 
   1539 	if (task->task_mgmt_function) {
   1540 		stmf_scsilib_handle_task_mgmt(task);
   1541 		return;
   1542 	}
   1543 
   1544 	/*
   1545 	 * if we're transitioning between access
   1546 	 * states, return NOT READY
   1547 	 */
   1548 	if (sl->sl_access_state == SBD_LU_TRANSITION_TO_STANDBY ||
   1549 	    sl->sl_access_state == SBD_LU_TRANSITION_TO_ACTIVE) {
   1550 		stmf_scsilib_send_status(task, STATUS_CHECK,
   1551 		    STMF_SAA_LU_NO_ACCESS_UNAVAIL);
   1552 		return;
   1553 	}
   1554 
   1555 	/* Checking ua conditions as per SAM3R14 5.3.2 specified order */
   1556 	if ((it->sbd_it_ua_conditions) && (task->task_cdb[0] != SCMD_INQUIRY)) {
   1557 		uint32_t saa = 0;
   1558 
   1559 		mutex_enter(&sl->sl_lock);
   1560 		if (it->sbd_it_ua_conditions & SBD_UA_POR) {
   1561 			it->sbd_it_ua_conditions &= ~SBD_UA_POR;
   1562 			saa = STMF_SAA_POR;
   1563 		}
   1564 		mutex_exit(&sl->sl_lock);
   1565 		if (saa) {
   1566 			stmf_scsilib_send_status(task, STATUS_CHECK, saa);
   1567 			return;
   1568 		}
   1569 	}
   1570 
   1571 	/* Reservation conflict checks */
   1572 	if (sl->sl_access_state != SBD_LU_STANDBY) {
   1573 		if (SBD_PGR_RSVD(sl->sl_pgr)) {
   1574 			if (sbd_pgr_reservation_conflict(task)) {
   1575 				stmf_scsilib_send_status(task,
   1576 				    STATUS_RESERVATION_CONFLICT, 0);
   1577 				return;
   1578 			}
   1579 		} else if ((sl->sl_flags & SL_LU_HAS_SCSI2_RESERVATION) &&
   1580 		    ((it->sbd_it_flags & SBD_IT_HAS_SCSI2_RESERVATION) == 0)) {
   1581 			if (!(SCSI2_CONFLICT_FREE_CMDS(task->task_cdb))) {
   1582 				stmf_scsilib_send_status(task,
   1583 				    STATUS_RESERVATION_CONFLICT, 0);
   1584 				return;
   1585 			}
   1586 		}
   1587 	}
   1588 
   1589 	/* Rest of the ua conndition checks */
   1590 	if ((it->sbd_it_ua_conditions) && (task->task_cdb[0] != SCMD_INQUIRY)) {
   1591 		uint32_t saa = 0;
   1592 
   1593 		mutex_enter(&sl->sl_lock);
   1594 		if (it->sbd_it_ua_conditions & SBD_UA_CAPACITY_CHANGED) {
   1595 			it->sbd_it_ua_conditions &= ~SBD_UA_CAPACITY_CHANGED;
   1596 			if ((task->task_cdb[0] == SCMD_READ_CAPACITY) ||
   1597 			    ((task->task_cdb[0] == SCMD_SVC_ACTION_IN_G4) &&
   1598 			    (task->task_cdb[1] ==
   1599 			    SSVC_ACTION_READ_CAPACITY_G4))) {
   1600 				saa = 0;
   1601 			} else {
   1602 				saa = STMF_SAA_CAPACITY_DATA_HAS_CHANGED;
   1603 			}
   1604 		} else if (it->sbd_it_ua_conditions &
   1605 		    SBD_UA_MODE_PARAMETERS_CHANGED) {
   1606 			it->sbd_it_ua_conditions &=
   1607 			    ~SBD_UA_MODE_PARAMETERS_CHANGED;
   1608 			saa = STMF_SAA_MODE_PARAMETERS_CHANGED;
   1609 		} else if (it->sbd_it_ua_conditions &
   1610 		    SBD_UA_ASYMMETRIC_ACCESS_CHANGED) {
   1611 			it->sbd_it_ua_conditions &=
   1612 			    ~SBD_UA_ASYMMETRIC_ACCESS_CHANGED;
   1613 			saa = STMF_SAA_ASYMMETRIC_ACCESS_CHANGED;
   1614 		} else if (it->sbd_it_ua_conditions &
   1615 		    SBD_UA_ACCESS_STATE_TRANSITION) {
   1616 			it->sbd_it_ua_conditions &=
   1617 			    ~SBD_UA_ACCESS_STATE_TRANSITION;
   1618 			saa = STMF_SAA_LU_NO_ACCESS_TRANSITION;
   1619 		} else {
   1620 			it->sbd_it_ua_conditions = 0;
   1621 			saa = 0;
   1622 		}
   1623 		mutex_exit(&sl->sl_lock);
   1624 		if (saa) {
   1625 			stmf_scsilib_send_status(task, STATUS_CHECK, saa);
   1626 			return;
   1627 		}
   1628 	}
   1629 
   1630 	cdb0 = task->task_cdb[0];
   1631 	cdb1 = task->task_cdb[1];
   1632 
   1633 	if (sl->sl_access_state == SBD_LU_STANDBY) {
   1634 		if (cdb0 != SCMD_INQUIRY &&
   1635 		    cdb0 != SCMD_MODE_SENSE &&
   1636 		    cdb0 != SCMD_MODE_SENSE_G1 &&
   1637 		    cdb0 != SCMD_MODE_SELECT &&
   1638 		    cdb0 != SCMD_MODE_SELECT_G1 &&
   1639 		    cdb0 != SCMD_RESERVE &&
   1640 		    cdb0 != SCMD_RELEASE &&
   1641 		    cdb0 != SCMD_PERSISTENT_RESERVE_OUT &&
   1642 		    cdb0 != SCMD_PERSISTENT_RESERVE_IN &&
   1643 		    cdb0 != SCMD_REQUEST_SENSE &&
   1644 		    cdb0 != SCMD_READ_CAPACITY &&
   1645 		    !(cdb0 == SCMD_SVC_ACTION_IN_G4 &&
   1646 		    cdb1 == SSVC_ACTION_READ_CAPACITY_G4) &&
   1647 		    !(cdb0 == SCMD_MAINTENANCE_IN &&
   1648 		    (cdb1 & 0x1F) == 0x0A)) {
   1649 			stmf_scsilib_send_status(task, STATUS_CHECK,
   1650 			    STMF_SAA_LU_NO_ACCESS_STANDBY);
   1651 			return;
   1652 		}
   1653 
   1654 		/*
   1655 		 * is this a short write?
   1656 		 * if so, we'll need to wait until we have the buffer
   1657 		 * before proxying the command
   1658 		 */
   1659 		switch (cdb0) {
   1660 			case SCMD_MODE_SELECT:
   1661 			case SCMD_MODE_SELECT_G1:
   1662 			case SCMD_PERSISTENT_RESERVE_OUT:
   1663 				break;
   1664 			default:
   1665 				st_ret = stmf_proxy_scsi_cmd(task,
   1666 				    initial_dbuf);
   1667 				if (st_ret != STMF_SUCCESS) {
   1668 					stmf_scsilib_send_status(task,
   1669 					    STATUS_CHECK,
   1670 					    STMF_SAA_LU_NO_ACCESS_UNAVAIL);
   1671 				}
   1672 				return;
   1673 		}
   1674 	}
   1675 
   1676 	cdb0 = task->task_cdb[0] & 0x1F;
   1677 
   1678 	if ((cdb0 == SCMD_READ) || (cdb0 == SCMD_WRITE)) {
   1679 		if (task->task_additional_flags & TASK_AF_PORT_LOAD_HIGH) {
   1680 			stmf_scsilib_send_status(task, STATUS_QFULL, 0);
   1681 			return;
   1682 		}
   1683 		if (cdb0 == SCMD_READ) {
   1684 			sbd_handle_read(task, initial_dbuf);
   1685 			return;
   1686 		}
   1687 		sbd_handle_write(task, initial_dbuf);
   1688 		return;
   1689 	}
   1690 
   1691 	cdb0 = task->task_cdb[0];
   1692 	cdb1 = task->task_cdb[1];
   1693 
   1694 	if (cdb0 == SCMD_INQUIRY) {		/* Inquiry */
   1695 		sbd_handle_inquiry(task, initial_dbuf);
   1696 		return;
   1697 	}
   1698 
   1699 	if (cdb0  == SCMD_PERSISTENT_RESERVE_OUT) {
   1700 		sbd_handle_pgr_out_cmd(task, initial_dbuf);
   1701 		return;
   1702 	}
   1703 
   1704 	if (cdb0  == SCMD_PERSISTENT_RESERVE_IN) {
   1705 		sbd_handle_pgr_in_cmd(task, initial_dbuf);
   1706 		return;
   1707 	}
   1708 
   1709 	if (cdb0 == SCMD_RELEASE) {
   1710 		if (cdb1) {
   1711 			stmf_scsilib_send_status(task, STATUS_CHECK,
   1712 			    STMF_SAA_INVALID_FIELD_IN_CDB);
   1713 			return;
   1714 		}
   1715 
   1716 		mutex_enter(&sl->sl_lock);
   1717 		if (sl->sl_flags & SL_LU_HAS_SCSI2_RESERVATION) {
   1718 			/* If not owner don't release it, just return good */
   1719 			if (it->sbd_it_session_id !=
   1720 			    sl->sl_rs_owner_session_id) {
   1721 				mutex_exit(&sl->sl_lock);
   1722 				stmf_scsilib_send_status(task, STATUS_GOOD, 0);
   1723 				return;
   1724 			}
   1725 		}
   1726 		sl->sl_flags &= ~SL_LU_HAS_SCSI2_RESERVATION;
   1727 		it->sbd_it_flags &= ~SBD_IT_HAS_SCSI2_RESERVATION;
   1728 		mutex_exit(&sl->sl_lock);
   1729 		stmf_scsilib_send_status(task, STATUS_GOOD, 0);
   1730 		return;
   1731 	}
   1732 
   1733 	if (cdb0 == SCMD_RESERVE) {
   1734 		if (cdb1) {
   1735 			stmf_scsilib_send_status(task, STATUS_CHECK,
   1736 			    STMF_SAA_INVALID_FIELD_IN_CDB);
   1737 			return;
   1738 		}
   1739 
   1740 		mutex_enter(&sl->sl_lock);
   1741 		if (sl->sl_flags & SL_LU_HAS_SCSI2_RESERVATION) {
   1742 			/* If not owner, return conflict status */
   1743 			if (it->sbd_it_session_id !=
   1744 			    sl->sl_rs_owner_session_id) {
   1745 				mutex_exit(&sl->sl_lock);
   1746 				stmf_scsilib_send_status(task,
   1747 				    STATUS_RESERVATION_CONFLICT, 0);
   1748 				return;
   1749 			}
   1750 		}
   1751 		sl->sl_flags |= SL_LU_HAS_SCSI2_RESERVATION;
   1752 		it->sbd_it_flags |= SBD_IT_HAS_SCSI2_RESERVATION;
   1753 		sl->sl_rs_owner_session_id = it->sbd_it_session_id;
   1754 		mutex_exit(&sl->sl_lock);
   1755 		stmf_scsilib_send_status(task, STATUS_GOOD, 0);
   1756 		return;
   1757 	}
   1758 
   1759 	if (cdb0 == SCMD_REQUEST_SENSE) {
   1760 		/*
   1761 		 * LU provider needs to store unretrieved sense data
   1762 		 * (e.g. after power-on/reset).  For now, we'll just
   1763 		 * return good status with no sense.
   1764 		 */
   1765 
   1766 		if ((cdb1 & ~1) || task->task_cdb[2] || task->task_cdb[3] ||
   1767 		    task->task_cdb[5]) {
   1768 			stmf_scsilib_send_status(task, STATUS_CHECK,
   1769 			    STMF_SAA_INVALID_FIELD_IN_CDB);
   1770 		} else {
   1771 			stmf_scsilib_send_status(task, STATUS_GOOD, 0);
   1772 		}
   1773 
   1774 		return;
   1775 	}
   1776 
   1777 	/* Report Target Port Groups */
   1778 	if ((cdb0 == SCMD_MAINTENANCE_IN) &&
   1779 	    ((cdb1 & 0x1F) == 0x0A)) {
   1780 		stmf_scsilib_handle_report_tpgs(task, initial_dbuf);
   1781 		return;
   1782 	}
   1783 
   1784 	if (cdb0 == SCMD_START_STOP) {			/* Start stop */
   1785 		task->task_cmd_xfer_length = 0;
   1786 		if (task->task_cdb[4] & 0xFC) {
   1787 			stmf_scsilib_send_status(task, STATUS_CHECK,
   1788 			    STMF_SAA_INVALID_FIELD_IN_CDB);
   1789 			return;
   1790 		}
   1791 		if (task->task_cdb[4] & 2) {
   1792 			stmf_scsilib_send_status(task, STATUS_CHECK,
   1793 			    STMF_SAA_INVALID_FIELD_IN_CDB);
   1794 		} else {
   1795 			stmf_scsilib_send_status(task, STATUS_GOOD, 0);
   1796 		}
   1797 		return;
   1798 
   1799 	}
   1800 
   1801 	if ((cdb0 == SCMD_MODE_SENSE) || (cdb0 == SCMD_MODE_SENSE_G1)) {
   1802 		uint8_t *p;
   1803 		p = kmem_zalloc(512, KM_SLEEP);
   1804 		sbd_handle_mode_sense(task, initial_dbuf, p);
   1805 		kmem_free(p, 512);
   1806 		return;
   1807 	}
   1808 
   1809 	if ((cdb0 == SCMD_MODE_SELECT) || (cdb0 == SCMD_MODE_SELECT_G1)) {
   1810 		sbd_handle_mode_select(task, initial_dbuf);
   1811 		return;
   1812 	}
   1813 
   1814 	if (cdb0 == SCMD_TEST_UNIT_READY) {	/* Test unit ready */
   1815 		task->task_cmd_xfer_length = 0;
   1816 		stmf_scsilib_send_status(task, STATUS_GOOD, 0);
   1817 		return;
   1818 	}
   1819 
   1820 	if (cdb0 == SCMD_READ_CAPACITY) {		/* Read Capacity */
   1821 		sbd_handle_read_capacity(task, initial_dbuf);
   1822 		return;
   1823 	}
   1824 
   1825 	if (cdb0 == SCMD_SVC_ACTION_IN_G4) { 	/* Read Capacity or read long */
   1826 		if (cdb1 == SSVC_ACTION_READ_CAPACITY_G4) {
   1827 			sbd_handle_read_capacity(task, initial_dbuf);
   1828 			return;
   1829 		/*
   1830 		 * } else if (cdb1 == SSVC_ACTION_READ_LONG_G4) {
   1831 		 * 	sbd_handle_read(task, initial_dbuf);
   1832 		 * 	return;
   1833 		 */
   1834 		}
   1835 	}
   1836 
   1837 	/*
   1838 	 * if (cdb0 == SCMD_SVC_ACTION_OUT_G4) {
   1839 	 *	if (cdb1 == SSVC_ACTION_WRITE_LONG_G4) {
   1840 	 *		 sbd_handle_write(task, initial_dbuf);
   1841 	 * 		return;
   1842 	 *	}
   1843 	 * }
   1844 	 */
   1845 
   1846 	if (cdb0 == SCMD_VERIFY) {
   1847 		/*
   1848 		 * Something more likely needs to be done here.
   1849 		 */
   1850 		task->task_cmd_xfer_length = 0;
   1851 		stmf_scsilib_send_status(task, STATUS_GOOD, 0);
   1852 		return;
   1853 	}
   1854 
   1855 	if (cdb0 == SCMD_SYNCHRONIZE_CACHE ||
   1856 	    cdb0 == SCMD_SYNCHRONIZE_CACHE_G4) {
   1857 		sbd_handle_sync_cache(task, initial_dbuf);
   1858 		return;
   1859 	}
   1860 
   1861 	stmf_scsilib_send_status(task, STATUS_CHECK, STMF_SAA_INVALID_OPCODE);
   1862 }
   1863 
   1864 void
   1865 sbd_dbuf_xfer_done(struct scsi_task *task, struct stmf_data_buf *dbuf)
   1866 {
   1867 	sbd_cmd_t *scmd = NULL;
   1868 
   1869 	scmd = (sbd_cmd_t *)task->task_lu_private;
   1870 	if ((scmd == NULL) || ((scmd->flags & SBD_SCSI_CMD_ACTIVE) == 0))
   1871 		return;
   1872 
   1873 	switch (scmd->cmd_type) {
   1874 	case (SBD_CMD_SCSI_READ):
   1875 		sbd_handle_read_xfer_completion(task, scmd, dbuf);
   1876 		break;
   1877 
   1878 	case (SBD_CMD_SCSI_WRITE):
   1879 		sbd_handle_write_xfer_completion(task, scmd, dbuf, 1);
   1880 		break;
   1881 
   1882 	case (SBD_CMD_SMALL_READ):
   1883 		sbd_handle_short_read_xfer_completion(task, scmd, dbuf);
   1884 		break;
   1885 
   1886 	case (SBD_CMD_SMALL_WRITE):
   1887 		sbd_handle_short_write_xfer_completion(task, dbuf);
   1888 		break;
   1889 
   1890 	default:
   1891 		cmn_err(CE_PANIC, "Unknown cmd type, task = %p", (void *)task);
   1892 		break;
   1893 	}
   1894 }
   1895 
   1896 /* ARGSUSED */
   1897 void
   1898 sbd_send_status_done(struct scsi_task *task)
   1899 {
   1900 	cmn_err(CE_PANIC,
   1901 	    "sbd_send_status_done: this should not have been called");
   1902 }
   1903 
   1904 void
   1905 sbd_task_free(struct scsi_task *task)
   1906 {
   1907 	if (task->task_lu_private) {
   1908 		sbd_cmd_t *scmd = (sbd_cmd_t *)task->task_lu_private;
   1909 		if (scmd->flags & SBD_SCSI_CMD_ACTIVE) {
   1910 			cmn_err(CE_PANIC, "cmd is active, task = %p",
   1911 			    (void *)task);
   1912 		}
   1913 		kmem_free(scmd, sizeof (sbd_cmd_t));
   1914 	}
   1915 }
   1916 
   1917 /*
   1918  * Aborts are synchronus w.r.t. I/O AND
   1919  * All the I/O which SBD does is synchronous AND
   1920  * Everything within a task is single threaded.
   1921  *   IT MEANS
   1922  * If this function is called, we are doing nothing with this task
   1923  * inside of sbd module.
   1924  */
   1925 /* ARGSUSED */
   1926 stmf_status_t
   1927 sbd_abort(struct stmf_lu *lu, int abort_cmd, void *arg, uint32_t flags)
   1928 {
   1929 	sbd_lu_t *sl = (sbd_lu_t *)lu->lu_provider_private;
   1930 	scsi_task_t *task;
   1931 
   1932 	if (abort_cmd == STMF_LU_RESET_STATE) {
   1933 		return (sbd_lu_reset_state(lu));
   1934 	}
   1935 
   1936 	if (abort_cmd == STMF_LU_ITL_HANDLE_REMOVED) {
   1937 		sbd_check_and_clear_scsi2_reservation(sl, (sbd_it_data_t *)arg);
   1938 		sbd_remove_it_handle(sl, (sbd_it_data_t *)arg);
   1939 		return (STMF_SUCCESS);
   1940 	}
   1941 
   1942 	ASSERT(abort_cmd == STMF_LU_ABORT_TASK);
   1943 	task = (scsi_task_t *)arg;
   1944 	if (task->task_lu_private) {
   1945 		sbd_cmd_t *scmd = (sbd_cmd_t *)task->task_lu_private;
   1946 
   1947 		if (scmd->flags & SBD_SCSI_CMD_ACTIVE) {
   1948 			scmd->flags &= ~SBD_SCSI_CMD_ACTIVE;
   1949 			return (STMF_ABORT_SUCCESS);
   1950 		}
   1951 	}
   1952 
   1953 	return (STMF_NOT_FOUND);
   1954 }
   1955 
   1956 /* ARGSUSED */
   1957 void
   1958 sbd_ctl(struct stmf_lu *lu, int cmd, void *arg)
   1959 {
   1960 	sbd_lu_t *sl = (sbd_lu_t *)lu->lu_provider_private;
   1961 	stmf_change_status_t st;
   1962 
   1963 	ASSERT((cmd == STMF_CMD_LU_ONLINE) ||
   1964 	    (cmd == STMF_CMD_LU_OFFLINE) ||
   1965 	    (cmd == STMF_ACK_LU_ONLINE_COMPLETE) ||
   1966 	    (cmd == STMF_ACK_LU_OFFLINE_COMPLETE));
   1967 
   1968 	st.st_completion_status = STMF_SUCCESS;
   1969 	st.st_additional_info = NULL;
   1970 
   1971 	switch (cmd) {
   1972 	case STMF_CMD_LU_ONLINE:
   1973 		if (sl->sl_state == STMF_STATE_ONLINE)
   1974 			st.st_completion_status = STMF_ALREADY;
   1975 		else if (sl->sl_state != STMF_STATE_OFFLINE)
   1976 			st.st_completion_status = STMF_FAILURE;
   1977 		if (st.st_completion_status == STMF_SUCCESS) {
   1978 			sl->sl_state = STMF_STATE_ONLINE;
   1979 			sl->sl_state_not_acked = 1;
   1980 		}
   1981 		(void) stmf_ctl(STMF_CMD_LU_ONLINE_COMPLETE, lu, &st);
   1982 		break;
   1983 
   1984 	case STMF_CMD_LU_OFFLINE:
   1985 		if (sl->sl_state == STMF_STATE_OFFLINE)
   1986 			st.st_completion_status = STMF_ALREADY;
   1987 		else if (sl->sl_state != STMF_STATE_ONLINE)
   1988 			st.st_completion_status = STMF_FAILURE;
   1989 		if (st.st_completion_status == STMF_SUCCESS) {
   1990 			sl->sl_flags &= ~(SL_MEDIUM_REMOVAL_PREVENTED |
   1991 			    SL_LU_HAS_SCSI2_RESERVATION);
   1992 			sl->sl_state = STMF_STATE_OFFLINE;
   1993 			sl->sl_state_not_acked = 1;
   1994 			sbd_pgr_reset(sl);
   1995 		}
   1996 		(void) stmf_ctl(STMF_CMD_LU_OFFLINE_COMPLETE, lu, &st);
   1997 		break;
   1998 
   1999 	case STMF_ACK_LU_ONLINE_COMPLETE:
   2000 		/* Fallthrough */
   2001 	case STMF_ACK_LU_OFFLINE_COMPLETE:
   2002 		sl->sl_state_not_acked = 0;
   2003 		break;
   2004 
   2005 	}
   2006 }
   2007 
   2008 /* ARGSUSED */
   2009 stmf_status_t
   2010 sbd_info(uint32_t cmd, stmf_lu_t *lu, void *arg, uint8_t *buf,
   2011     uint32_t *bufsizep)
   2012 {
   2013 	return (STMF_NOT_SUPPORTED);
   2014 }
   2015 
   2016 stmf_status_t
   2017 sbd_lu_reset_state(stmf_lu_t *lu)
   2018 {
   2019 	sbd_lu_t *sl = (sbd_lu_t *)lu->lu_provider_private;
   2020 
   2021 	mutex_enter(&sl->sl_lock);
   2022 	if (sl->sl_flags & SL_SAVED_WRITE_CACHE_DISABLE) {
   2023 		sl->sl_flags |= SL_WRITEBACK_CACHE_DISABLE;
   2024 		mutex_exit(&sl->sl_lock);
   2025 		if (sl->sl_access_state == SBD_LU_ACTIVE) {
   2026 			(void) sbd_wcd_set(1, sl);
   2027 		}
   2028 	} else {
   2029 		sl->sl_flags &= ~SL_WRITEBACK_CACHE_DISABLE;
   2030 		mutex_exit(&sl->sl_lock);
   2031 		if (sl->sl_access_state == SBD_LU_ACTIVE) {
   2032 			(void) sbd_wcd_set(0, sl);
   2033 		}
   2034 	}
   2035 	sbd_pgr_reset(sl);
   2036 	sbd_check_and_clear_scsi2_reservation(sl, NULL);
   2037 	if (stmf_deregister_all_lu_itl_handles(lu) != STMF_SUCCESS) {
   2038 		return (STMF_FAILURE);
   2039 	}
   2040 	return (STMF_SUCCESS);
   2041 }
   2042 
   2043 sbd_status_t
   2044 sbd_flush_data_cache(sbd_lu_t *sl, int fsync_done)
   2045 {
   2046 	int r = 0;
   2047 	int ret;
   2048 
   2049 	if (fsync_done)
   2050 		goto over_fsync;
   2051 	if ((sl->sl_data_vtype == VREG) || (sl->sl_data_vtype == VBLK)) {
   2052 		if (VOP_FSYNC(sl->sl_data_vp, FSYNC, kcred, NULL))
   2053 			return (SBD_FAILURE);
   2054 	}
   2055 over_fsync:
   2056 	if (((sl->sl_data_vtype == VCHR) || (sl->sl_data_vtype == VBLK)) &&
   2057 	    ((sl->sl_flags & SL_NO_DATA_DKIOFLUSH) == 0)) {
   2058 		ret = VOP_IOCTL(sl->sl_data_vp, DKIOCFLUSHWRITECACHE, NULL,
   2059 		    FKIOCTL, kcred, &r, NULL);
   2060 		if ((ret == ENOTTY) || (ret == ENOTSUP)) {
   2061 			mutex_enter(&sl->sl_lock);
   2062 			sl->sl_flags |= SL_NO_DATA_DKIOFLUSH;
   2063 			mutex_exit(&sl->sl_lock);
   2064 		} else if (ret != 0) {
   2065 			return (SBD_FAILURE);
   2066 		}
   2067 	}
   2068 
   2069 	return (SBD_SUCCESS);
   2070 }
   2071 
   2072 /* ARGSUSED */
   2073 static void
   2074 sbd_handle_sync_cache(struct scsi_task *task,
   2075     struct stmf_data_buf *initial_dbuf)
   2076 {
   2077 	sbd_lu_t *sl = (sbd_lu_t *)task->task_lu->lu_provider_private;
   2078 	uint64_t	lba, laddr;
   2079 	sbd_status_t	sret;
   2080 	uint32_t	len;
   2081 	int		is_g4 = 0;
   2082 	int		immed;
   2083 
   2084 	task->task_cmd_xfer_length = 0;
   2085 	/*
   2086 	 * Determine if this is a 10 or 16 byte CDB
   2087 	 */
   2088 
   2089 	if (task->task_cdb[0] == SCMD_SYNCHRONIZE_CACHE_G4)
   2090 		is_g4 = 1;
   2091 
   2092 	/*
   2093 	 * Determine other requested parameters
   2094 	 *
   2095 	 * We don't have a non-volatile cache, so don't care about SYNC_NV.
   2096 	 * Do not support the IMMED bit.
   2097 	 */
   2098 
   2099 	immed = (task->task_cdb[1] & 0x02);
   2100 
   2101 	if (immed) {
   2102 		stmf_scsilib_send_status(task, STATUS_CHECK,
   2103 		    STMF_SAA_INVALID_FIELD_IN_CDB);
   2104 		return;
   2105 	}
   2106 
   2107 	/*
   2108 	 * Check to be sure we're not being asked to sync an LBA
   2109 	 * that is out of range.  While checking, verify reserved fields.
   2110 	 */
   2111 
   2112 	if (is_g4) {
   2113 		if ((task->task_cdb[1] & 0xf9) || task->task_cdb[14] ||
   2114 		    task->task_cdb[15]) {
   2115 			stmf_scsilib_send_status(task, STATUS_CHECK,
   2116 			    STMF_SAA_INVALID_FIELD_IN_CDB);
   2117 			return;
   2118 		}
   2119 
   2120 		lba = READ_SCSI64(&task->task_cdb[2], uint64_t);
   2121 		len = READ_SCSI32(&task->task_cdb[10], uint32_t);
   2122 	} else {
   2123 		if ((task->task_cdb[1] & 0xf9) || task->task_cdb[6] ||
   2124 		    task->task_cdb[9]) {
   2125 			stmf_scsilib_send_status(task, STATUS_CHECK,
   2126 			    STMF_SAA_INVALID_FIELD_IN_CDB);
   2127 			return;
   2128 		}
   2129 
   2130 		lba = READ_SCSI32(&task->task_cdb[2], uint64_t);
   2131 		len = READ_SCSI16(&task->task_cdb[7], uint32_t);
   2132 	}
   2133 
   2134 	laddr = lba << sl->sl_data_blocksize_shift;
   2135 	len <<= sl->sl_data_blocksize_shift;
   2136 
   2137 	if ((laddr + (uint64_t)len) > sl->sl_lu_size) {
   2138 		stmf_scsilib_send_status(task, STATUS_CHECK,
   2139 		    STMF_SAA_LBA_OUT_OF_RANGE);
   2140 		return;
   2141 	}
   2142 
   2143 	sret = sbd_flush_data_cache(sl, 0);
   2144 	if (sret != SBD_SUCCESS) {
   2145 		stmf_scsilib_send_status(task, STATUS_CHECK,
   2146 		    STMF_SAA_WRITE_ERROR);
   2147 		return;
   2148 	}
   2149 
   2150 	stmf_scsilib_send_status(task, STATUS_GOOD, 0);
   2151 }
   2152