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.
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.
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]
22 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
24 * Copyright (c) 2013 by Delphix. All rights reserved.
30 #include <sys/sunddi.h>
31 #include <sys/modctl.h>
32 #include <sys/scsi/scsi.h>
33 #include <sys/scsi/impl/scsi_reset_notify.h>
34 #include <sys/scsi/generic/mode.h>
36 #include <sys/byteorder.h>
37 #include <sys/atomic.h>
40 #include <sys/dkioc_free_util.h>
44 #include <sys/portif.h>
45 #include <sys/stmf_ioctl.h>
46 #include <sys/stmf_sbd_ioctl.h>
51 #define SCSI2_CONFLICT_FREE_CMDS(cdb) ( \
52 /* ----------------------- */ \
54 /* SPC-2 (rev 20) Table 10 */ \
55 /* SPC-3 (rev 23) Table 31 */ \
56 /* ----------------------- */ \
57 ((cdb[0]) == SCMD_INQUIRY) || \
58 ((cdb[0]) == SCMD_LOG_SENSE_G1) || \
59 ((cdb[0]) == SCMD_RELEASE) || \
60 ((cdb[0]) == SCMD_RELEASE_G1) || \
61 ((cdb[0]) == SCMD_REPORT_LUNS) || \
62 ((cdb[0]) == SCMD_REQUEST_SENSE) || \
63 /* PREVENT ALLOW MEDIUM REMOVAL with prevent == 0 */ \
64 ((((cdb[0]) == SCMD_DOORLOCK) && (((cdb[4]) & 0x3) == 0))) || \
65 /* SERVICE ACTION IN with READ MEDIA SERIAL NUMBER (0x01) */ \
66 (((cdb[0]) == SCMD_SVC_ACTION_IN_G5) && ( \
67 ((cdb[1]) & 0x1F) == 0x01)) || \
68 /* MAINTENANCE IN with service actions REPORT ALIASES (0x0Bh) */ \
69 /* REPORT DEVICE IDENTIFIER (0x05) REPORT PRIORITY (0x0Eh) */ \
70 /* REPORT TARGET PORT GROUPS (0x0A) REPORT TIMESTAMP (0x0F) */ \
71 (((cdb[0]) == SCMD_MAINTENANCE_IN) && ( \
72 (((cdb[1]) & 0x1F) == 0x0B) || \
73 (((cdb[1]) & 0x1F) == 0x05) || \
74 (((cdb[1]) & 0x1F) == 0x0E) || \
75 (((cdb[1]) & 0x1F) == 0x0A) || \
76 (((cdb[1]) & 0x1F) == 0x0F))) || \
77 /* ----------------------- */ \
78 /* SBC-3 (rev 17) Table 3 */ \
79 /* ----------------------- */ \
80 /* READ CAPACITY(10) */ \
81 ((cdb[0]) == SCMD_READ_CAPACITY) || \
82 /* READ CAPACITY(16) */ \
83 (((cdb[0]) == SCMD_SVC_ACTION_IN_G4) && ( \
84 ((cdb[1]) & 0x1F) == 0x10)) || \
85 /* START STOP UNIT with START bit 0 and POWER CONDITION 0 */ \
86 (((cdb[0]) == SCMD_START_STOP) && ( \
87 (((cdb[4]) & 0xF0) == 0) && (((cdb[4]) & 0x01) == 0))))
88 /* End of SCSI2_CONFLICT_FREE_CMDS */
90 stmf_status_t
sbd_lu_reset_state(stmf_lu_t
*lu
);
91 static void sbd_handle_sync_cache(struct scsi_task
*task
,
92 struct stmf_data_buf
*initial_dbuf
);
93 void sbd_handle_read_xfer_completion(struct scsi_task
*task
,
94 sbd_cmd_t
*scmd
, struct stmf_data_buf
*dbuf
);
95 void sbd_handle_short_write_xfer_completion(scsi_task_t
*task
,
96 stmf_data_buf_t
*dbuf
);
97 void sbd_handle_short_write_transfers(scsi_task_t
*task
,
98 stmf_data_buf_t
*dbuf
, uint32_t cdb_xfer_size
);
99 void sbd_handle_mode_select_xfer(scsi_task_t
*task
, uint8_t *buf
,
101 void sbd_handle_mode_select(scsi_task_t
*task
, stmf_data_buf_t
*dbuf
);
102 void sbd_handle_identifying_info(scsi_task_t
*task
, stmf_data_buf_t
*dbuf
);
104 static void sbd_handle_unmap_xfer(scsi_task_t
*task
, uint8_t *buf
,
106 static void sbd_handle_unmap(scsi_task_t
*task
, stmf_data_buf_t
*dbuf
);
108 extern void sbd_pgr_initialize_it(scsi_task_t
*, sbd_it_data_t
*);
109 extern int sbd_pgr_reservation_conflict(scsi_task_t
*);
110 extern void sbd_pgr_reset(sbd_lu_t
*);
111 extern void sbd_pgr_remove_it_handle(sbd_lu_t
*, sbd_it_data_t
*);
112 extern void sbd_handle_pgr_in_cmd(scsi_task_t
*, stmf_data_buf_t
*);
113 extern void sbd_handle_pgr_out_cmd(scsi_task_t
*, stmf_data_buf_t
*);
114 extern void sbd_handle_pgr_out_data(scsi_task_t
*, stmf_data_buf_t
*);
115 void sbd_do_sgl_write_xfer(struct scsi_task
*task
, sbd_cmd_t
*scmd
,
117 static void sbd_handle_write_same(scsi_task_t
*task
,
118 struct stmf_data_buf
*initial_dbuf
);
119 static void sbd_do_write_same_xfer(struct scsi_task
*task
, sbd_cmd_t
*scmd
,
120 struct stmf_data_buf
*dbuf
, uint8_t dbuf_reusable
);
121 static void sbd_handle_write_same_xfer_completion(struct scsi_task
*task
,
122 sbd_cmd_t
*scmd
, struct stmf_data_buf
*dbuf
, uint8_t dbuf_reusable
);
126 * The whole world here is based on the assumption that everything within
127 * a scsi task executes in a single threaded manner, even the aborts.
128 * Dont ever change that. There wont be any performance gain but there
129 * will be tons of race conditions.
133 sbd_do_read_xfer(struct scsi_task
*task
, sbd_cmd_t
*scmd
,
134 struct stmf_data_buf
*dbuf
)
136 sbd_lu_t
*sl
= (sbd_lu_t
*)task
->task_lu
->lu_provider_private
;
138 uint32_t len
, buflen
, iolen
;
142 /* Lets try not to hog all the buffers the port has. */
143 bufs_to_take
= ((task
->task_max_nbufs
> 2) &&
144 (task
->task_cmd_xfer_length
< (32 * 1024))) ? 2 :
145 task
->task_max_nbufs
;
147 len
= scmd
->len
> dbuf
->db_buf_size
? dbuf
->db_buf_size
: scmd
->len
;
148 laddr
= scmd
->addr
+ scmd
->current_ro
;
150 for (buflen
= 0, ndx
= 0; (buflen
< len
) &&
151 (ndx
< dbuf
->db_sglist_length
); ndx
++) {
152 iolen
= min(len
- buflen
, dbuf
->db_sglist
[ndx
].seg_length
);
155 if (sbd_data_read(sl
, task
, laddr
, (uint64_t)iolen
,
156 dbuf
->db_sglist
[ndx
].seg_addr
) != STMF_SUCCESS
) {
157 scmd
->flags
|= SBD_SCSI_CMD_XFER_FAIL
;
158 /* Do not need to do xfer anymore, just complete it */
159 dbuf
->db_data_size
= 0;
160 dbuf
->db_xfer_status
= STMF_SUCCESS
;
161 sbd_handle_read_xfer_completion(task
, scmd
, dbuf
);
165 laddr
+= (uint64_t)iolen
;
167 dbuf
->db_relative_offset
= scmd
->current_ro
;
168 dbuf
->db_data_size
= buflen
;
169 dbuf
->db_flags
= DB_DIRECTION_TO_RPORT
;
170 (void) stmf_xfer_data(task
, dbuf
, 0);
172 scmd
->current_ro
+= buflen
;
173 if (scmd
->len
&& (scmd
->nbufs
< bufs_to_take
)) {
174 uint32_t maxsize
, minsize
, old_minsize
;
176 maxsize
= (scmd
->len
> (128*1024)) ? 128*1024 : scmd
->len
;
177 minsize
= maxsize
>> 2;
180 * A bad port implementation can keep on failing the
181 * the request but keep on sending us a false
184 old_minsize
= minsize
;
185 dbuf
= stmf_alloc_dbuf(task
, maxsize
, &minsize
, 0);
186 } while ((dbuf
== NULL
) && (old_minsize
> minsize
) &&
192 sbd_do_read_xfer(task
, scmd
, dbuf
);
197 * sbd_zcopy: Bail-out switch for reduced copy path.
199 * 0 - read & write off
200 * 1 - read & write on
204 int sbd_zcopy
= 1; /* enable zcopy read & write path */
205 uint32_t sbd_max_xfer_len
= 0; /* Valid if non-zero */
206 uint32_t sbd_1st_xfer_len
= 0; /* Valid if non-zero */
207 uint32_t sbd_copy_threshold
= 0; /* Valid if non-zero */
210 sbd_do_sgl_read_xfer(struct scsi_task
*task
, sbd_cmd_t
*scmd
, int first_xfer
)
212 sbd_lu_t
*sl
= (sbd_lu_t
*)task
->task_lu
->lu_provider_private
;
216 uint32_t xfer_len
, max_len
, first_len
;
218 stmf_data_buf_t
*dbuf
;
220 uint64_t blksize
= sl
->sl_blksize
;
221 size_t db_private_sz
;
224 ASSERT(rw_read_held(&sl
->sl_access_state_lock
));
225 ASSERT((sl
->sl_flags
& SL_MEDIA_LOADED
) != 0);
228 * Calculate the limits on xfer_len to the minimum of :
231 * - sbd global limit if set
232 * - first xfer limit if set
234 * First, protect against silly over-ride value
236 if (sbd_max_xfer_len
&& ((sbd_max_xfer_len
% DEV_BSIZE
) != 0)) {
237 cmn_err(CE_WARN
, "sbd_max_xfer_len invalid %d, resetting\n",
239 sbd_max_xfer_len
= 0;
241 if (sbd_1st_xfer_len
&& ((sbd_1st_xfer_len
% DEV_BSIZE
) != 0)) {
242 cmn_err(CE_WARN
, "sbd_1st_xfer_len invalid %d, resetting\n",
244 sbd_1st_xfer_len
= 0;
247 max_len
= MIN(task
->task_max_xfer_len
, sl
->sl_max_xfer_len
);
248 if (sbd_max_xfer_len
)
249 max_len
= MIN(max_len
, sbd_max_xfer_len
);
251 * Special case the first xfer if hints are set.
253 if (first_xfer
&& (sbd_1st_xfer_len
|| task
->task_1st_xfer_len
)) {
254 /* global over-ride has precedence */
255 if (sbd_1st_xfer_len
)
256 first_len
= sbd_1st_xfer_len
;
258 first_len
= task
->task_1st_xfer_len
;
263 while (scmd
->len
&& scmd
->nbufs
< task
->task_max_nbufs
) {
265 xfer_len
= MIN(max_len
, scmd
->len
);
267 xfer_len
= MIN(xfer_len
, first_len
);
270 if (scmd
->len
== xfer_len
) {
274 * Attempt to end xfer on a block boundary.
275 * The only way this does not happen is if the
276 * xfer_len is small enough to stay contained
277 * within the same block.
279 uint64_t xfer_offset
, xfer_aligned_end
;
282 xfer_offset
= scmd
->addr
+ scmd
->current_ro
;
284 P2ALIGN(xfer_offset
+xfer_len
, blksize
);
285 if (xfer_aligned_end
> xfer_offset
)
286 xfer_len
= xfer_aligned_end
- xfer_offset
;
289 * Allocate object to track the read and reserve
290 * enough space for scatter/gather list.
292 offset
= scmd
->addr
+ scmd
->current_ro
;
293 nblks
= sbd_zvol_numsegs(sl
, offset
, xfer_len
);
295 db_private_sz
= sizeof (*zvio
) + sizeof (uintptr_t) /* PAD */ +
296 (nblks
* sizeof (stmf_sglist_ent_t
));
297 dbuf
= stmf_alloc(STMF_STRUCT_DATA_BUF
, db_private_sz
,
302 * XXX Framework does not handle variable length sglists
303 * properly, so setup db_lu_private and db_port_private
304 * fields here. db_stmf_private is properly set for
305 * calls to stmf_free.
307 if (dbuf
->db_port_private
== NULL
) {
309 * XXX Framework assigns space to PP after db_sglist[0]
311 cmn_err(CE_PANIC
, "db_port_private == NULL");
313 pad
= (uintptr_t)&dbuf
->db_sglist
[nblks
];
314 dbuf
->db_lu_private
= (void *)P2ROUNDUP(pad
, sizeof (pad
));
315 dbuf
->db_port_private
= NULL
;
316 dbuf
->db_buf_size
= xfer_len
;
317 dbuf
->db_data_size
= xfer_len
;
318 dbuf
->db_relative_offset
= scmd
->current_ro
;
319 dbuf
->db_sglist_length
= (uint16_t)nblks
;
320 dbuf
->db_xfer_status
= 0;
323 dbuf
->db_flags
= (DB_DONT_CACHE
| DB_DONT_REUSE
|
324 DB_DIRECTION_TO_RPORT
| DB_LU_DATA_BUF
);
326 dbuf
->db_flags
|= DB_SEND_STATUS_GOOD
;
328 zvio
= dbuf
->db_lu_private
;
329 /* Need absolute offset for zvol access */
330 zvio
->zvio_offset
= offset
;
331 zvio
->zvio_flags
= ZVIO_SYNC
;
334 * Accounting for start of read.
335 * Note there is no buffer address for the probe yet.
337 DTRACE_PROBE5(backing__store__read__start
, sbd_lu_t
*, sl
,
338 uint8_t *, NULL
, uint64_t, xfer_len
,
339 uint64_t, offset
, scsi_task_t
*, task
);
341 ret
= sbd_zvol_alloc_read_bufs(sl
, dbuf
);
343 DTRACE_PROBE6(backing__store__read__end
, sbd_lu_t
*, sl
,
344 uint8_t *, NULL
, uint64_t, xfer_len
,
345 uint64_t, offset
, int, ret
, scsi_task_t
*, task
);
349 * Read failure from the backend.
352 if (scmd
->nbufs
== 0) {
353 /* nothing queued, just finish */
354 scmd
->flags
&= ~SBD_SCSI_CMD_ACTIVE
;
355 stmf_scsilib_send_status(task
, STATUS_CHECK
,
356 STMF_SAA_READ_ERROR
);
357 rw_exit(&sl
->sl_access_state_lock
);
359 /* process failure when other dbufs finish */
360 scmd
->flags
|= SBD_SCSI_CMD_XFER_FAIL
;
367 * Allow PP to do setup
369 xstat
= stmf_setup_dbuf(task
, dbuf
, 0);
370 if (xstat
!= STMF_SUCCESS
) {
372 * This could happen if the driver cannot get the
373 * DDI resources it needs for this request.
374 * If other dbufs are queued, try again when the next
375 * one completes, otherwise give up.
377 sbd_zvol_rele_read_bufs(sl
, dbuf
);
379 if (scmd
->nbufs
> 0) {
380 /* completion of previous dbuf will retry */
384 * Done with this command.
386 scmd
->flags
&= ~SBD_SCSI_CMD_ACTIVE
;
388 stmf_scsilib_send_status(task
, STATUS_QFULL
, 0);
390 stmf_scsilib_send_status(task
, STATUS_CHECK
,
391 STMF_SAA_READ_ERROR
);
392 rw_exit(&sl
->sl_access_state_lock
);
396 * dbuf is now queued on task
400 /* XXX leave this in for FW? */
401 DTRACE_PROBE4(sbd__xfer
, struct scsi_task
*, task
,
402 struct stmf_data_buf
*, dbuf
, uint64_t, offset
,
405 * Do not pass STMF_IOF_LU_DONE so that the zvol
406 * state can be released in the completion callback.
408 xstat
= stmf_xfer_data(task
, dbuf
, 0);
414 * The dbuf is queued on the task, but unknown
415 * to the PP, thus no completion will occur.
417 sbd_zvol_rele_read_bufs(sl
, dbuf
);
418 stmf_teardown_dbuf(task
, dbuf
);
421 if (scmd
->nbufs
> 0) {
422 /* completion of previous dbuf will retry */
426 * Done with this command.
428 rw_exit(&sl
->sl_access_state_lock
);
429 scmd
->flags
&= ~SBD_SCSI_CMD_ACTIVE
;
431 stmf_scsilib_send_status(task
, STATUS_QFULL
, 0);
433 stmf_scsilib_send_status(task
, STATUS_CHECK
,
434 STMF_SAA_READ_ERROR
);
438 * Completion from task_done will cleanup
440 scmd
->flags
&= ~SBD_SCSI_CMD_ACTIVE
;
444 * Update the xfer progress.
446 ASSERT(scmd
->len
>= xfer_len
);
447 scmd
->len
-= xfer_len
;
448 scmd
->current_ro
+= xfer_len
;
453 sbd_handle_read_xfer_completion(struct scsi_task
*task
, sbd_cmd_t
*scmd
,
454 struct stmf_data_buf
*dbuf
)
456 if (dbuf
->db_xfer_status
!= STMF_SUCCESS
) {
457 stmf_abort(STMF_QUEUE_TASK_ABORT
, task
,
458 dbuf
->db_xfer_status
, NULL
);
461 task
->task_nbytes_transferred
+= dbuf
->db_data_size
;
462 if (scmd
->len
== 0 || scmd
->flags
& SBD_SCSI_CMD_XFER_FAIL
) {
463 stmf_free_dbuf(task
, dbuf
);
466 return; /* wait for all buffers to complete */
467 scmd
->flags
&= ~SBD_SCSI_CMD_ACTIVE
;
468 if (scmd
->flags
& SBD_SCSI_CMD_XFER_FAIL
)
469 stmf_scsilib_send_status(task
, STATUS_CHECK
,
470 STMF_SAA_READ_ERROR
);
472 stmf_scsilib_send_status(task
, STATUS_GOOD
, 0);
475 if (dbuf
->db_flags
& DB_DONT_REUSE
) {
476 /* allocate new dbuf */
477 uint32_t maxsize
, minsize
, old_minsize
;
478 stmf_free_dbuf(task
, dbuf
);
480 maxsize
= (scmd
->len
> (128*1024)) ? 128*1024 : scmd
->len
;
481 minsize
= maxsize
>> 2;
483 old_minsize
= minsize
;
484 dbuf
= stmf_alloc_dbuf(task
, maxsize
, &minsize
, 0);
485 } while ((dbuf
== NULL
) && (old_minsize
> minsize
) &&
489 if (scmd
->nbufs
== 0) {
490 stmf_abort(STMF_QUEUE_TASK_ABORT
, task
,
491 STMF_ALLOC_FAILURE
, NULL
);
496 sbd_do_read_xfer(task
, scmd
, dbuf
);
500 * This routine must release the DMU resources and free the dbuf
501 * in all cases. If this is the final dbuf of the task, then drop
502 * the reader lock on the LU state. If there are no errors and more
503 * work to do, then queue more xfer operations.
506 sbd_handle_sgl_read_xfer_completion(struct scsi_task
*task
, sbd_cmd_t
*scmd
,
507 struct stmf_data_buf
*dbuf
)
509 sbd_lu_t
*sl
= (sbd_lu_t
*)task
->task_lu
->lu_provider_private
;
510 stmf_status_t xfer_status
;
514 ASSERT(dbuf
->db_lu_private
);
515 ASSERT(scmd
->cmd_type
== SBD_CMD_SCSI_READ
);
517 scmd
->nbufs
--; /* account for this dbuf */
519 * Release the DMU resources.
521 sbd_zvol_rele_read_bufs(sl
, dbuf
);
523 * Release the dbuf after retrieving needed fields.
525 xfer_status
= dbuf
->db_xfer_status
;
526 data_size
= dbuf
->db_data_size
;
527 stmf_teardown_dbuf(task
, dbuf
);
530 * Release the state lock if this is the last completion.
531 * If this is the last dbuf on task and all data has been
532 * transferred or an error encountered, then no more dbufs
535 scmd_err
= (((scmd
->flags
& SBD_SCSI_CMD_ACTIVE
) == 0) ||
536 (scmd
->flags
& SBD_SCSI_CMD_XFER_FAIL
) ||
537 (xfer_status
!= STMF_SUCCESS
));
538 if (scmd
->nbufs
== 0 && (scmd
->len
== 0 || scmd_err
)) {
539 /* all DMU state has been released */
540 rw_exit(&sl
->sl_access_state_lock
);
544 * If there have been no errors, either complete the task
545 * or issue more data xfer operations.
549 * This chunk completed successfully
551 task
->task_nbytes_transferred
+= data_size
;
552 if (scmd
->nbufs
== 0 && scmd
->len
== 0) {
554 * This command completed successfully
556 * Status was sent along with data, so no status
557 * completion will occur. Tell stmf we are done.
559 scmd
->flags
&= ~SBD_SCSI_CMD_ACTIVE
;
560 stmf_task_lu_done(task
);
566 sbd_do_sgl_read_xfer(task
, scmd
, 0);
570 * Sort out the failure
572 if (scmd
->flags
& SBD_SCSI_CMD_ACTIVE
) {
574 * If a previous error occurred, leave the command active
575 * and wait for the last completion to send the status check.
577 if (scmd
->flags
& SBD_SCSI_CMD_XFER_FAIL
) {
578 if (scmd
->nbufs
== 0) {
579 scmd
->flags
&= ~SBD_SCSI_CMD_ACTIVE
;
580 stmf_scsilib_send_status(task
, STATUS_CHECK
,
581 STMF_SAA_READ_ERROR
);
586 * Must have been a failure on current dbuf
588 ASSERT(xfer_status
!= STMF_SUCCESS
);
589 scmd
->flags
&= ~SBD_SCSI_CMD_ACTIVE
;
590 stmf_abort(STMF_QUEUE_TASK_ABORT
, task
, xfer_status
, NULL
);
595 sbd_handle_sgl_write_xfer_completion(struct scsi_task
*task
, sbd_cmd_t
*scmd
,
596 struct stmf_data_buf
*dbuf
)
598 sbd_zvol_io_t
*zvio
= dbuf
->db_lu_private
;
599 sbd_lu_t
*sl
= (sbd_lu_t
*)task
->task_lu
->lu_provider_private
;
601 int scmd_err
, scmd_xfer_done
;
602 stmf_status_t xfer_status
= dbuf
->db_xfer_status
;
603 uint32_t data_size
= dbuf
->db_data_size
;
608 * Allow PP to free up resources before releasing the write bufs
609 * as writing to the backend could take some time.
611 stmf_teardown_dbuf(task
, dbuf
);
613 scmd
->nbufs
--; /* account for this dbuf */
615 * All data was queued and this is the last completion,
616 * but there could still be an error.
618 scmd_xfer_done
= (scmd
->len
== 0 && scmd
->nbufs
== 0);
619 scmd_err
= (((scmd
->flags
& SBD_SCSI_CMD_ACTIVE
) == 0) ||
620 (scmd
->flags
& SBD_SCSI_CMD_XFER_FAIL
) ||
621 (xfer_status
!= STMF_SUCCESS
));
623 DTRACE_PROBE5(backing__store__write__start
, sbd_lu_t
*, sl
,
624 uint8_t *, NULL
, uint64_t, data_size
,
625 uint64_t, zvio
->zvio_offset
, scsi_task_t
*, task
);
628 /* just return the write buffers */
629 sbd_zvol_rele_write_bufs_abort(sl
, dbuf
);
633 zvio
->zvio_flags
= ZVIO_COMMIT
;
635 zvio
->zvio_flags
= 0;
637 ret
= sbd_zvol_rele_write_bufs(sl
, dbuf
);
640 DTRACE_PROBE6(backing__store__write__end
, sbd_lu_t
*, sl
,
641 uint8_t *, NULL
, uint64_t, data_size
,
642 uint64_t, zvio
->zvio_offset
, int, ret
, scsi_task_t
*, task
);
645 /* update the error flag */
646 scmd
->flags
|= SBD_SCSI_CMD_XFER_FAIL
;
650 /* Release the dbuf */
654 * Release the state lock if this is the last completion.
655 * If this is the last dbuf on task and all data has been
656 * transferred or an error encountered, then no more dbufs
659 if (scmd
->nbufs
== 0 && (scmd
->len
== 0 || scmd_err
)) {
660 /* all DMU state has been released */
661 rw_exit(&sl
->sl_access_state_lock
);
664 * If there have been no errors, either complete the task
665 * or issue more data xfer operations.
668 /* This chunk completed successfully */
669 task
->task_nbytes_transferred
+= data_size
;
670 if (scmd_xfer_done
) {
671 /* This command completed successfully */
672 scmd
->flags
&= ~SBD_SCSI_CMD_ACTIVE
;
673 if ((scmd
->flags
& SBD_SCSI_CMD_SYNC_WRITE
) &&
674 (sbd_flush_data_cache(sl
, 0) != SBD_SUCCESS
)) {
675 stmf_scsilib_send_status(task
, STATUS_CHECK
,
676 STMF_SAA_WRITE_ERROR
);
678 stmf_scsilib_send_status(task
, STATUS_GOOD
, 0);
685 sbd_do_sgl_write_xfer(task
, scmd
, 0);
689 * Sort out the failure
691 if (scmd
->flags
& SBD_SCSI_CMD_ACTIVE
) {
692 if (scmd
->flags
& SBD_SCSI_CMD_XFER_FAIL
) {
693 if (scmd
->nbufs
== 0) {
694 scmd
->flags
&= ~SBD_SCSI_CMD_ACTIVE
;
695 stmf_scsilib_send_status(task
, STATUS_CHECK
,
696 STMF_SAA_WRITE_ERROR
);
699 * Leave the command active until last dbuf completes.
703 scmd
->flags
&= ~SBD_SCSI_CMD_ACTIVE
;
704 ASSERT(xfer_status
!= STMF_SUCCESS
);
705 stmf_abort(STMF_QUEUE_TASK_ABORT
, task
, xfer_status
, NULL
);
710 * Handle a copy operation using the zvol interface.
712 * Similar to the sbd_data_read/write path, except it goes directly through
713 * the zvol interfaces. It can pass a port provider sglist in the
714 * form of uio which is lost through the vn_rdwr path.
717 * STMF_SUCCESS - request handled
718 * STMF_FAILURE - request not handled, caller must deal with error
721 sbd_copy_rdwr(scsi_task_t
*task
, uint64_t laddr
, stmf_data_buf_t
*dbuf
,
724 sbd_lu_t
*sl
= task
->task_lu
->lu_provider_private
;
726 struct iovec
*iov
, *tiov
, iov1
[8];
728 int ret
, i
, iovcnt
, flags
;
731 ASSERT(cmd
== SBD_CMD_SCSI_READ
|| cmd
== SBD_CMD_SCSI_WRITE
);
733 is_read
= (cmd
== SBD_CMD_SCSI_READ
) ? B_TRUE
: B_FALSE
;
734 iovcnt
= dbuf
->db_sglist_length
;
735 /* use the stack for small iovecs */
737 iov
= kmem_alloc(iovcnt
* sizeof (*iov
), KM_SLEEP
);
742 /* Convert dbuf sglist to iovec format */
743 len
= dbuf
->db_data_size
;
746 for (i
= 0; i
< iovcnt
; i
++) {
747 tiov
->iov_base
= (caddr_t
)dbuf
->db_sglist
[i
].seg_addr
;
748 tiov
->iov_len
= MIN(resid
, dbuf
->db_sglist
[i
].seg_length
);
749 resid
-= tiov
->iov_len
;
753 cmn_err(CE_WARN
, "inconsistant sglist rem %d", resid
);
755 kmem_free(iov
, iovcnt
* sizeof (*iov
));
756 return (STMF_FAILURE
);
758 /* Setup the uio struct */
760 uio
.uio_iovcnt
= iovcnt
;
761 uio
.uio_loffset
= laddr
;
762 uio
.uio_segflg
= (short)UIO_SYSSPACE
;
763 uio
.uio_resid
= (uint64_t)len
;
764 uio
.uio_llimit
= RLIM64_INFINITY
;
766 if (is_read
== B_TRUE
) {
767 uio
.uio_fmode
= FREAD
;
768 uio
.uio_extflg
= UIO_COPY_CACHED
;
769 DTRACE_PROBE5(backing__store__read__start
, sbd_lu_t
*, sl
,
770 uint8_t *, NULL
, uint64_t, len
, uint64_t, laddr
,
771 scsi_task_t
*, task
);
774 ret
= sbd_zvol_copy_read(sl
, &uio
);
776 DTRACE_PROBE6(backing__store__read__end
, sbd_lu_t
*, sl
,
777 uint8_t *, NULL
, uint64_t, len
, uint64_t, laddr
, int, ret
,
778 scsi_task_t
*, task
);
780 uio
.uio_fmode
= FWRITE
;
781 uio
.uio_extflg
= UIO_COPY_DEFAULT
;
782 DTRACE_PROBE5(backing__store__write__start
, sbd_lu_t
*, sl
,
783 uint8_t *, NULL
, uint64_t, len
, uint64_t, laddr
,
784 scsi_task_t
*, task
);
786 flags
= (commit
) ? ZVIO_COMMIT
: 0;
788 ret
= sbd_zvol_copy_write(sl
, &uio
, flags
);
790 DTRACE_PROBE6(backing__store__write__end
, sbd_lu_t
*, sl
,
791 uint8_t *, NULL
, uint64_t, len
, uint64_t, laddr
, int, ret
,
792 scsi_task_t
*, task
);
796 kmem_free(iov
, iovcnt
* sizeof (*iov
));
798 /* Backend I/O error */
799 return (STMF_FAILURE
);
801 return (STMF_SUCCESS
);
805 sbd_handle_read(struct scsi_task
*task
, struct stmf_data_buf
*initial_dbuf
)
809 uint8_t op
= task
->task_cdb
[0];
810 sbd_lu_t
*sl
= (sbd_lu_t
*)task
->task_lu
->lu_provider_private
;
812 stmf_data_buf_t
*dbuf
;
815 if (op
== SCMD_READ
) {
816 lba
= READ_SCSI21(&task
->task_cdb
[1], uint64_t);
817 len
= (uint32_t)task
->task_cdb
[4];
822 } else if (op
== SCMD_READ_G1
) {
823 lba
= READ_SCSI32(&task
->task_cdb
[2], uint64_t);
824 len
= READ_SCSI16(&task
->task_cdb
[7], uint32_t);
825 } else if (op
== SCMD_READ_G5
) {
826 lba
= READ_SCSI32(&task
->task_cdb
[2], uint64_t);
827 len
= READ_SCSI32(&task
->task_cdb
[6], uint32_t);
828 } else if (op
== SCMD_READ_G4
) {
829 lba
= READ_SCSI64(&task
->task_cdb
[2], uint64_t);
830 len
= READ_SCSI32(&task
->task_cdb
[10], uint32_t);
832 stmf_scsilib_send_status(task
, STATUS_CHECK
,
833 STMF_SAA_INVALID_OPCODE
);
837 laddr
= lba
<< sl
->sl_data_blocksize_shift
;
838 len
<<= sl
->sl_data_blocksize_shift
;
840 if ((laddr
+ (uint64_t)len
) > sl
->sl_lu_size
) {
841 stmf_scsilib_send_status(task
, STATUS_CHECK
,
842 STMF_SAA_LBA_OUT_OF_RANGE
);
846 task
->task_cmd_xfer_length
= len
;
847 if (task
->task_additional_flags
& TASK_AF_NO_EXPECTED_XFER_LENGTH
) {
848 task
->task_expected_xfer_length
= len
;
851 if (len
!= task
->task_expected_xfer_length
) {
853 len
= (len
> task
->task_expected_xfer_length
) ?
854 task
->task_expected_xfer_length
: len
;
860 stmf_scsilib_send_status(task
, STATUS_GOOD
, 0);
865 * Determine if this read can directly use DMU buffers.
867 if (sbd_zcopy
& (2|1) && /* Debug switch */
868 initial_dbuf
== NULL
&& /* No PP buffer passed in */
869 sl
->sl_flags
& SL_CALL_ZVOL
&& /* zvol backing store */
870 (task
->task_additional_flags
&
871 TASK_AF_ACCEPT_LU_DBUF
)) /* PP allows it */
876 uint32_t copy_threshold
, minsize
;
880 * The sl_access_state_lock will be held shared
881 * for the entire request and released when all
882 * dbufs have completed.
884 rw_enter(&sl
->sl_access_state_lock
, RW_READER
);
885 if ((sl
->sl_flags
& SL_MEDIA_LOADED
) == 0) {
886 rw_exit(&sl
->sl_access_state_lock
);
887 stmf_scsilib_send_status(task
, STATUS_CHECK
,
888 STMF_SAA_READ_ERROR
);
893 * Check if setup is more expensive than copying the data.
895 * Use the global over-ride sbd_zcopy_threshold if set.
897 copy_threshold
= (sbd_copy_threshold
> 0) ?
898 sbd_copy_threshold
: task
->task_copy_threshold
;
900 if (len
< copy_threshold
&&
901 (dbuf
= stmf_alloc_dbuf(task
, len
, &minsize
, 0)) != 0) {
903 ret
= sbd_copy_rdwr(task
, laddr
, dbuf
,
904 SBD_CMD_SCSI_READ
, 0);
905 /* done with the backend */
906 rw_exit(&sl
->sl_access_state_lock
);
909 stmf_scsilib_send_status(task
, STATUS_CHECK
,
910 STMF_SAA_READ_ERROR
);
912 /* send along good data */
913 dbuf
->db_relative_offset
= 0;
914 dbuf
->db_data_size
= len
;
915 dbuf
->db_flags
= DB_SEND_STATUS_GOOD
|
916 DB_DIRECTION_TO_RPORT
;
917 /* XXX keep for FW? */
918 DTRACE_PROBE4(sbd__xfer
,
919 struct scsi_task
*, task
,
920 struct stmf_data_buf
*, dbuf
,
921 uint64_t, laddr
, uint32_t, len
);
922 (void) stmf_xfer_data(task
, dbuf
,
928 /* committed to reduced copy */
929 if (task
->task_lu_private
) {
930 scmd
= (sbd_cmd_t
*)task
->task_lu_private
;
932 scmd
= (sbd_cmd_t
*)kmem_alloc(sizeof (sbd_cmd_t
),
934 task
->task_lu_private
= scmd
;
937 * Setup scmd to track read progress.
939 scmd
->flags
= SBD_SCSI_CMD_ACTIVE
;
940 scmd
->cmd_type
= SBD_CMD_SCSI_READ
;
944 scmd
->current_ro
= 0;
949 sbd_do_sgl_read_xfer(task
, scmd
, 1);
953 if (initial_dbuf
== NULL
) {
954 uint32_t maxsize
, minsize
, old_minsize
;
956 maxsize
= (len
> (128*1024)) ? 128*1024 : len
;
957 minsize
= maxsize
>> 2;
959 old_minsize
= minsize
;
960 initial_dbuf
= stmf_alloc_dbuf(task
, maxsize
,
962 } while ((initial_dbuf
== NULL
) && (old_minsize
> minsize
) &&
964 if (initial_dbuf
== NULL
) {
965 stmf_scsilib_send_status(task
, STATUS_QFULL
, 0);
971 if ((dbuf
->db_buf_size
>= len
) && fast_path
&&
972 (dbuf
->db_sglist_length
== 1)) {
973 if (sbd_data_read(sl
, task
, laddr
, (uint64_t)len
,
974 dbuf
->db_sglist
[0].seg_addr
) == STMF_SUCCESS
) {
975 dbuf
->db_relative_offset
= 0;
976 dbuf
->db_data_size
= len
;
977 dbuf
->db_flags
= DB_SEND_STATUS_GOOD
|
978 DB_DIRECTION_TO_RPORT
;
979 /* XXX keep for FW? */
980 DTRACE_PROBE4(sbd__xfer
, struct scsi_task
*, task
,
981 struct stmf_data_buf
*, dbuf
,
982 uint64_t, laddr
, uint32_t, len
);
983 (void) stmf_xfer_data(task
, dbuf
, STMF_IOF_LU_DONE
);
985 stmf_scsilib_send_status(task
, STATUS_CHECK
,
986 STMF_SAA_READ_ERROR
);
991 if (task
->task_lu_private
) {
992 scmd
= (sbd_cmd_t
*)task
->task_lu_private
;
994 scmd
= (sbd_cmd_t
*)kmem_alloc(sizeof (sbd_cmd_t
), KM_SLEEP
);
995 task
->task_lu_private
= scmd
;
997 scmd
->flags
= SBD_SCSI_CMD_ACTIVE
;
998 scmd
->cmd_type
= SBD_CMD_SCSI_READ
;
1002 scmd
->current_ro
= 0;
1004 sbd_do_read_xfer(task
, scmd
, dbuf
);
1008 sbd_do_write_xfer(struct scsi_task
*task
, sbd_cmd_t
*scmd
,
1009 struct stmf_data_buf
*dbuf
, uint8_t dbuf_reusable
)
1014 if (scmd
->len
== 0) {
1015 goto DO_WRITE_XFER_DONE
;
1018 /* Lets try not to hog all the buffers the port has. */
1019 bufs_to_take
= ((task
->task_max_nbufs
> 2) &&
1020 (task
->task_cmd_xfer_length
< (32 * 1024))) ? 2 :
1021 task
->task_max_nbufs
;
1023 if ((dbuf
!= NULL
) &&
1024 ((dbuf
->db_flags
& DB_DONT_REUSE
) || (dbuf_reusable
== 0))) {
1025 /* free current dbuf and allocate a new one */
1026 stmf_free_dbuf(task
, dbuf
);
1029 if (scmd
->nbufs
>= bufs_to_take
) {
1030 goto DO_WRITE_XFER_DONE
;
1033 uint32_t maxsize
, minsize
, old_minsize
;
1035 maxsize
= (scmd
->len
> (128*1024)) ? 128*1024 :
1037 minsize
= maxsize
>> 2;
1039 old_minsize
= minsize
;
1040 dbuf
= stmf_alloc_dbuf(task
, maxsize
, &minsize
, 0);
1041 } while ((dbuf
== NULL
) && (old_minsize
> minsize
) &&
1044 if (scmd
->nbufs
== 0) {
1045 stmf_abort(STMF_QUEUE_TASK_ABORT
, task
,
1046 STMF_ALLOC_FAILURE
, NULL
);
1052 len
= scmd
->len
> dbuf
->db_buf_size
? dbuf
->db_buf_size
:
1055 dbuf
->db_relative_offset
= scmd
->current_ro
;
1056 dbuf
->db_data_size
= len
;
1057 dbuf
->db_flags
= DB_DIRECTION_FROM_RPORT
;
1058 (void) stmf_xfer_data(task
, dbuf
, 0);
1059 scmd
->nbufs
++; /* outstanding port xfers and bufs used */
1061 scmd
->current_ro
+= len
;
1063 if ((scmd
->len
!= 0) && (scmd
->nbufs
< bufs_to_take
)) {
1064 sbd_do_write_xfer(task
, scmd
, NULL
, 0);
1070 stmf_free_dbuf(task
, dbuf
);
1075 sbd_do_sgl_write_xfer(struct scsi_task
*task
, sbd_cmd_t
*scmd
, int first_xfer
)
1077 sbd_lu_t
*sl
= (sbd_lu_t
*)task
->task_lu
->lu_provider_private
;
1078 sbd_zvol_io_t
*zvio
;
1080 uint32_t xfer_len
, max_len
, first_len
;
1081 stmf_status_t xstat
;
1082 stmf_data_buf_t
*dbuf
;
1084 uint64_t blksize
= sl
->sl_blksize
;
1086 size_t db_private_sz
;
1089 ASSERT(rw_read_held(&sl
->sl_access_state_lock
));
1090 ASSERT((sl
->sl_flags
& SL_MEDIA_LOADED
) != 0);
1093 * Calculate the limits on xfer_len to the minimum of :
1096 * - sbd global limit if set
1097 * - first xfer limit if set
1099 * First, protect against silly over-ride value
1101 if (sbd_max_xfer_len
&& ((sbd_max_xfer_len
% DEV_BSIZE
) != 0)) {
1102 cmn_err(CE_WARN
, "sbd_max_xfer_len invalid %d, resetting\n",
1104 sbd_max_xfer_len
= 0;
1106 if (sbd_1st_xfer_len
&& ((sbd_1st_xfer_len
% DEV_BSIZE
) != 0)) {
1107 cmn_err(CE_WARN
, "sbd_1st_xfer_len invalid %d, resetting\n",
1109 sbd_1st_xfer_len
= 0;
1112 max_len
= MIN(task
->task_max_xfer_len
, sl
->sl_max_xfer_len
);
1113 if (sbd_max_xfer_len
)
1114 max_len
= MIN(max_len
, sbd_max_xfer_len
);
1116 * Special case the first xfer if hints are set.
1118 if (first_xfer
&& (sbd_1st_xfer_len
|| task
->task_1st_xfer_len
)) {
1119 /* global over-ride has precedence */
1120 if (sbd_1st_xfer_len
)
1121 first_len
= sbd_1st_xfer_len
;
1123 first_len
= task
->task_1st_xfer_len
;
1129 while (scmd
->len
&& scmd
->nbufs
< task
->task_max_nbufs
) {
1131 xfer_len
= MIN(max_len
, scmd
->len
);
1133 xfer_len
= MIN(xfer_len
, first_len
);
1136 if (xfer_len
< scmd
->len
) {
1138 * Attempt to end xfer on a block boundary.
1139 * The only way this does not happen is if the
1140 * xfer_len is small enough to stay contained
1141 * within the same block.
1143 uint64_t xfer_offset
, xfer_aligned_end
;
1145 xfer_offset
= scmd
->addr
+ scmd
->current_ro
;
1147 P2ALIGN(xfer_offset
+xfer_len
, blksize
);
1148 if (xfer_aligned_end
> xfer_offset
)
1149 xfer_len
= xfer_aligned_end
- xfer_offset
;
1152 * Allocate object to track the write and reserve
1153 * enough space for scatter/gather list.
1155 offset
= scmd
->addr
+ scmd
->current_ro
;
1156 nblks
= sbd_zvol_numsegs(sl
, offset
, xfer_len
);
1157 db_private_sz
= sizeof (*zvio
) + sizeof (uintptr_t) /* PAD */ +
1158 (nblks
* sizeof (stmf_sglist_ent_t
));
1159 dbuf
= stmf_alloc(STMF_STRUCT_DATA_BUF
, db_private_sz
,
1165 * XXX Framework does not handle variable length sglists
1166 * properly, so setup db_lu_private and db_port_private
1167 * fields here. db_stmf_private is properly set for
1168 * calls to stmf_free.
1170 if (dbuf
->db_port_private
== NULL
) {
1172 * XXX Framework assigns space to PP after db_sglist[0]
1174 cmn_err(CE_PANIC
, "db_port_private == NULL");
1176 pad
= (uintptr_t)&dbuf
->db_sglist
[nblks
];
1177 dbuf
->db_lu_private
= (void *)P2ROUNDUP(pad
, sizeof (pad
));
1178 dbuf
->db_port_private
= NULL
;
1179 dbuf
->db_buf_size
= xfer_len
;
1180 dbuf
->db_data_size
= xfer_len
;
1181 dbuf
->db_relative_offset
= scmd
->current_ro
;
1182 dbuf
->db_sglist_length
= (uint16_t)nblks
;
1183 dbuf
->db_xfer_status
= 0;
1184 dbuf
->db_handle
= 0;
1185 dbuf
->db_flags
= (DB_DONT_CACHE
| DB_DONT_REUSE
|
1186 DB_DIRECTION_FROM_RPORT
| DB_LU_DATA_BUF
);
1188 zvio
= dbuf
->db_lu_private
;
1189 zvio
->zvio_offset
= offset
;
1191 /* get the buffers */
1192 ret
= sbd_zvol_alloc_write_bufs(sl
, dbuf
);
1195 * Could not allocate buffers from the backend;
1196 * treat it like an IO error.
1199 scmd
->flags
|= SBD_SCSI_CMD_XFER_FAIL
;
1200 if (scmd
->nbufs
== 0) {
1202 * Nothing queued, so no completions coming
1204 stmf_scsilib_send_status(task
, STATUS_CHECK
,
1205 STMF_SAA_WRITE_ERROR
);
1206 rw_exit(&sl
->sl_access_state_lock
);
1209 * Completions of previous buffers will cleanup.
1215 * Allow PP to do setup
1217 xstat
= stmf_setup_dbuf(task
, dbuf
, 0);
1218 if (xstat
!= STMF_SUCCESS
) {
1220 * This could happen if the driver cannot get the
1221 * DDI resources it needs for this request.
1222 * If other dbufs are queued, try again when the next
1223 * one completes, otherwise give up.
1225 sbd_zvol_rele_write_bufs_abort(sl
, dbuf
);
1227 if (scmd
->nbufs
> 0) {
1228 /* completion of previous dbuf will retry */
1232 * Done with this command.
1234 scmd
->flags
&= ~SBD_SCSI_CMD_ACTIVE
;
1236 stmf_scsilib_send_status(task
, STATUS_QFULL
, 0);
1238 stmf_scsilib_send_status(task
, STATUS_CHECK
,
1239 STMF_SAA_WRITE_ERROR
);
1240 rw_exit(&sl
->sl_access_state_lock
);
1245 * dbuf is now queued on task
1249 xstat
= stmf_xfer_data(task
, dbuf
, 0);
1255 * The dbuf is queued on the task, but unknown
1256 * to the PP, thus no completion will occur.
1258 sbd_zvol_rele_write_bufs_abort(sl
, dbuf
);
1259 stmf_teardown_dbuf(task
, dbuf
);
1262 if (scmd
->nbufs
> 0) {
1263 /* completion of previous dbuf will retry */
1267 * Done with this command.
1269 scmd
->flags
&= ~SBD_SCSI_CMD_ACTIVE
;
1271 stmf_scsilib_send_status(task
, STATUS_QFULL
, 0);
1273 stmf_scsilib_send_status(task
, STATUS_CHECK
,
1274 STMF_SAA_WRITE_ERROR
);
1275 rw_exit(&sl
->sl_access_state_lock
);
1279 * Completion code will cleanup.
1281 scmd
->flags
|= SBD_SCSI_CMD_XFER_FAIL
;
1285 * Update the xfer progress.
1287 scmd
->len
-= xfer_len
;
1288 scmd
->current_ro
+= xfer_len
;
1293 sbd_handle_write_xfer_completion(struct scsi_task
*task
, sbd_cmd_t
*scmd
,
1294 struct stmf_data_buf
*dbuf
, uint8_t dbuf_reusable
)
1296 sbd_lu_t
*sl
= (sbd_lu_t
*)task
->task_lu
->lu_provider_private
;
1298 uint32_t buflen
, iolen
;
1301 if (scmd
->nbufs
> 0) {
1303 * Decrement the count to indicate the port xfer
1304 * into the dbuf has completed even though the buf is
1305 * still in use here in the LU provider.
1310 if (dbuf
->db_xfer_status
!= STMF_SUCCESS
) {
1311 stmf_abort(STMF_QUEUE_TASK_ABORT
, task
,
1312 dbuf
->db_xfer_status
, NULL
);
1316 if (scmd
->flags
& SBD_SCSI_CMD_XFER_FAIL
) {
1317 goto WRITE_XFER_DONE
;
1320 if (scmd
->len
!= 0) {
1322 * Initiate the next port xfer to occur in parallel
1323 * with writing this buf.
1325 sbd_do_write_xfer(task
, scmd
, NULL
, 0);
1328 laddr
= scmd
->addr
+ dbuf
->db_relative_offset
;
1331 * If this is going to a zvol, use the direct call to
1332 * sbd_zvol_copy_{read,write}. The direct call interface is
1333 * restricted to PPs that accept sglists, but that is not required.
1335 if (sl
->sl_flags
& SL_CALL_ZVOL
&&
1336 (task
->task_additional_flags
& TASK_AF_ACCEPT_LU_DBUF
) &&
1337 (sbd_zcopy
& (4|1))) {
1340 commit
= (scmd
->len
== 0 && scmd
->nbufs
== 0);
1341 if (sbd_copy_rdwr(task
, laddr
, dbuf
, SBD_CMD_SCSI_WRITE
,
1342 commit
) != STMF_SUCCESS
)
1343 scmd
->flags
|= SBD_SCSI_CMD_XFER_FAIL
;
1344 buflen
= dbuf
->db_data_size
;
1346 for (buflen
= 0, ndx
= 0; (buflen
< dbuf
->db_data_size
) &&
1347 (ndx
< dbuf
->db_sglist_length
); ndx
++) {
1348 iolen
= min(dbuf
->db_data_size
- buflen
,
1349 dbuf
->db_sglist
[ndx
].seg_length
);
1352 if (sbd_data_write(sl
, task
, laddr
, (uint64_t)iolen
,
1353 dbuf
->db_sglist
[ndx
].seg_addr
) != STMF_SUCCESS
) {
1354 scmd
->flags
|= SBD_SCSI_CMD_XFER_FAIL
;
1358 laddr
+= (uint64_t)iolen
;
1361 task
->task_nbytes_transferred
+= buflen
;
1363 if (scmd
->len
== 0 || scmd
->flags
& SBD_SCSI_CMD_XFER_FAIL
) {
1364 stmf_free_dbuf(task
, dbuf
);
1366 return; /* wait for all buffers to complete */
1367 scmd
->flags
&= ~SBD_SCSI_CMD_ACTIVE
;
1368 if (scmd
->flags
& SBD_SCSI_CMD_XFER_FAIL
) {
1369 stmf_scsilib_send_status(task
, STATUS_CHECK
,
1370 STMF_SAA_WRITE_ERROR
);
1373 * If SYNC_WRITE flag is on then we need to flush
1374 * cache before sending status.
1375 * Note: this may be a no-op because of how
1376 * SL_WRITEBACK_CACHE_DISABLE and
1377 * SL_FLUSH_ON_DISABLED_WRITECACHE are set, but not
1378 * worth code complexity of checking those in this code
1379 * path, SBD_SCSI_CMD_SYNC_WRITE is rarely set.
1381 if ((scmd
->flags
& SBD_SCSI_CMD_SYNC_WRITE
) &&
1382 (sbd_flush_data_cache(sl
, 0) != SBD_SUCCESS
)) {
1383 stmf_scsilib_send_status(task
, STATUS_CHECK
,
1384 STMF_SAA_WRITE_ERROR
);
1386 stmf_scsilib_send_status(task
, STATUS_GOOD
, 0);
1391 sbd_do_write_xfer(task
, scmd
, dbuf
, dbuf_reusable
);
1395 * Return true if copy avoidance is beneficial.
1398 sbd_zcopy_write_useful(scsi_task_t
*task
, uint64_t laddr
, uint32_t len
,
1402 * If there is a global copy threshold over-ride, use it.
1403 * Otherwise use the PP value with the caveat that at least
1404 * 1/2 the data must avoid being copied to be useful.
1406 if (sbd_copy_threshold
> 0) {
1407 return (len
>= sbd_copy_threshold
);
1409 uint64_t no_copy_span
;
1411 /* sub-blocksize writes always copy */
1412 if (len
< task
->task_copy_threshold
|| len
< blksize
)
1415 * Calculate amount of data that will avoid the copy path.
1416 * The calculation is only valid if len >= blksize.
1418 no_copy_span
= P2ALIGN(laddr
+len
, blksize
) -
1419 P2ROUNDUP(laddr
, blksize
);
1420 return (no_copy_span
>= len
/2);
1425 sbd_handle_write(struct scsi_task
*task
, struct stmf_data_buf
*initial_dbuf
)
1427 uint64_t lba
, laddr
;
1429 uint8_t op
= task
->task_cdb
[0], do_immediate_data
= 0;
1430 sbd_lu_t
*sl
= (sbd_lu_t
*)task
->task_lu
->lu_provider_private
;
1432 stmf_data_buf_t
*dbuf
;
1433 uint8_t sync_wr_flag
= 0;
1435 if (sl
->sl_flags
& SL_WRITE_PROTECTED
) {
1436 stmf_scsilib_send_status(task
, STATUS_CHECK
,
1437 STMF_SAA_WRITE_PROTECTED
);
1440 if (op
== SCMD_WRITE
) {
1441 lba
= READ_SCSI21(&task
->task_cdb
[1], uint64_t);
1442 len
= (uint32_t)task
->task_cdb
[4];
1447 } else if (op
== SCMD_WRITE_G1
) {
1448 lba
= READ_SCSI32(&task
->task_cdb
[2], uint64_t);
1449 len
= READ_SCSI16(&task
->task_cdb
[7], uint32_t);
1450 } else if (op
== SCMD_WRITE_G5
) {
1451 lba
= READ_SCSI32(&task
->task_cdb
[2], uint64_t);
1452 len
= READ_SCSI32(&task
->task_cdb
[6], uint32_t);
1453 } else if (op
== SCMD_WRITE_G4
) {
1454 lba
= READ_SCSI64(&task
->task_cdb
[2], uint64_t);
1455 len
= READ_SCSI32(&task
->task_cdb
[10], uint32_t);
1456 } else if (op
== SCMD_WRITE_VERIFY
) {
1457 lba
= READ_SCSI32(&task
->task_cdb
[2], uint64_t);
1458 len
= READ_SCSI16(&task
->task_cdb
[7], uint32_t);
1459 sync_wr_flag
= SBD_SCSI_CMD_SYNC_WRITE
;
1460 } else if (op
== SCMD_WRITE_VERIFY_G5
) {
1461 lba
= READ_SCSI32(&task
->task_cdb
[2], uint64_t);
1462 len
= READ_SCSI32(&task
->task_cdb
[6], uint32_t);
1463 sync_wr_flag
= SBD_SCSI_CMD_SYNC_WRITE
;
1464 } else if (op
== SCMD_WRITE_VERIFY_G4
) {
1465 lba
= READ_SCSI64(&task
->task_cdb
[2], uint64_t);
1466 len
= READ_SCSI32(&task
->task_cdb
[10], uint32_t);
1467 sync_wr_flag
= SBD_SCSI_CMD_SYNC_WRITE
;
1469 stmf_scsilib_send_status(task
, STATUS_CHECK
,
1470 STMF_SAA_INVALID_OPCODE
);
1474 laddr
= lba
<< sl
->sl_data_blocksize_shift
;
1475 len
<<= sl
->sl_data_blocksize_shift
;
1477 if ((laddr
+ (uint64_t)len
) > sl
->sl_lu_size
) {
1478 stmf_scsilib_send_status(task
, STATUS_CHECK
,
1479 STMF_SAA_LBA_OUT_OF_RANGE
);
1483 task
->task_cmd_xfer_length
= len
;
1484 if (task
->task_additional_flags
& TASK_AF_NO_EXPECTED_XFER_LENGTH
) {
1485 task
->task_expected_xfer_length
= len
;
1488 len
= (len
> task
->task_expected_xfer_length
) ?
1489 task
->task_expected_xfer_length
: len
;
1492 stmf_scsilib_send_status(task
, STATUS_GOOD
, 0);
1496 if (sbd_zcopy
& (4|1) && /* Debug switch */
1497 initial_dbuf
== NULL
&& /* No PP buf passed in */
1498 sl
->sl_flags
& SL_CALL_ZVOL
&& /* zvol backing store */
1499 (task
->task_additional_flags
&
1500 TASK_AF_ACCEPT_LU_DBUF
) && /* PP allows it */
1501 sbd_zcopy_write_useful(task
, laddr
, len
, sl
->sl_blksize
)) {
1504 * XXX Note that disallowing initial_dbuf will eliminate
1505 * iSCSI from participating. For small writes, that is
1506 * probably ok. For large writes, it may be best to just
1507 * copy the data from the initial dbuf and use zcopy for
1510 rw_enter(&sl
->sl_access_state_lock
, RW_READER
);
1511 if ((sl
->sl_flags
& SL_MEDIA_LOADED
) == 0) {
1512 rw_exit(&sl
->sl_access_state_lock
);
1513 stmf_scsilib_send_status(task
, STATUS_CHECK
,
1514 STMF_SAA_READ_ERROR
);
1518 * Setup scmd to track the write progress.
1520 if (task
->task_lu_private
) {
1521 scmd
= (sbd_cmd_t
*)task
->task_lu_private
;
1523 scmd
= (sbd_cmd_t
*)kmem_alloc(sizeof (sbd_cmd_t
),
1525 task
->task_lu_private
= scmd
;
1527 scmd
->flags
= SBD_SCSI_CMD_ACTIVE
| sync_wr_flag
;
1528 scmd
->cmd_type
= SBD_CMD_SCSI_WRITE
;
1532 scmd
->current_ro
= 0;
1533 sbd_do_sgl_write_xfer(task
, scmd
, 1);
1537 if ((initial_dbuf
!= NULL
) && (task
->task_flags
& TF_INITIAL_BURST
)) {
1538 if (initial_dbuf
->db_data_size
> len
) {
1539 if (initial_dbuf
->db_data_size
>
1540 task
->task_expected_xfer_length
) {
1541 /* protocol error */
1542 stmf_abort(STMF_QUEUE_TASK_ABORT
, task
,
1543 STMF_INVALID_ARG
, NULL
);
1546 initial_dbuf
->db_data_size
= len
;
1548 do_immediate_data
= 1;
1550 dbuf
= initial_dbuf
;
1552 if (task
->task_lu_private
) {
1553 scmd
= (sbd_cmd_t
*)task
->task_lu_private
;
1555 scmd
= (sbd_cmd_t
*)kmem_alloc(sizeof (sbd_cmd_t
), KM_SLEEP
);
1556 task
->task_lu_private
= scmd
;
1558 scmd
->flags
= SBD_SCSI_CMD_ACTIVE
| sync_wr_flag
;
1559 scmd
->cmd_type
= SBD_CMD_SCSI_WRITE
;
1563 scmd
->current_ro
= 0;
1565 if (do_immediate_data
) {
1567 * Account for data passed in this write command
1569 (void) stmf_xfer_data(task
, dbuf
, STMF_IOF_STATS_ONLY
);
1570 scmd
->len
-= dbuf
->db_data_size
;
1571 scmd
->current_ro
+= dbuf
->db_data_size
;
1572 dbuf
->db_xfer_status
= STMF_SUCCESS
;
1573 sbd_handle_write_xfer_completion(task
, scmd
, dbuf
, 0);
1575 sbd_do_write_xfer(task
, scmd
, dbuf
, 0);
1580 * Utility routine to handle small non performance data transfers to the
1581 * initiators. dbuf is an initial data buf (if any), 'p' points to a data
1582 * buffer which is source of data for transfer, cdb_xfer_size is the
1583 * transfer size based on CDB, cmd_xfer_size is the actual amount of data
1584 * which this command would transfer (the size of data pointed to by 'p').
1587 sbd_handle_short_read_transfers(scsi_task_t
*task
, stmf_data_buf_t
*dbuf
,
1588 uint8_t *p
, uint32_t cdb_xfer_size
, uint32_t cmd_xfer_size
)
1590 uint32_t bufsize
, ndx
;
1593 cmd_xfer_size
= min(cmd_xfer_size
, cdb_xfer_size
);
1595 task
->task_cmd_xfer_length
= cmd_xfer_size
;
1596 if (task
->task_additional_flags
& TASK_AF_NO_EXPECTED_XFER_LENGTH
) {
1597 task
->task_expected_xfer_length
= cmd_xfer_size
;
1599 cmd_xfer_size
= min(cmd_xfer_size
,
1600 task
->task_expected_xfer_length
);
1603 if (cmd_xfer_size
== 0) {
1604 stmf_scsilib_send_status(task
, STATUS_CHECK
,
1605 STMF_SAA_INVALID_FIELD_IN_CDB
);
1609 uint32_t minsize
= cmd_xfer_size
;
1611 dbuf
= stmf_alloc_dbuf(task
, cmd_xfer_size
, &minsize
, 0);
1614 stmf_scsilib_send_status(task
, STATUS_QFULL
, 0);
1618 for (bufsize
= 0, ndx
= 0; bufsize
< cmd_xfer_size
; ndx
++) {
1622 d
= dbuf
->db_sglist
[ndx
].seg_addr
;
1623 s
= min((cmd_xfer_size
- bufsize
),
1624 dbuf
->db_sglist
[ndx
].seg_length
);
1625 bcopy(p
+bufsize
, d
, s
);
1628 dbuf
->db_relative_offset
= 0;
1629 dbuf
->db_data_size
= cmd_xfer_size
;
1630 dbuf
->db_flags
= DB_DIRECTION_TO_RPORT
;
1632 if (task
->task_lu_private
== NULL
) {
1633 task
->task_lu_private
=
1634 kmem_alloc(sizeof (sbd_cmd_t
), KM_SLEEP
);
1636 scmd
= (sbd_cmd_t
*)task
->task_lu_private
;
1638 scmd
->cmd_type
= SBD_CMD_SMALL_READ
;
1639 scmd
->flags
= SBD_SCSI_CMD_ACTIVE
;
1640 (void) stmf_xfer_data(task
, dbuf
, 0);
1644 sbd_handle_short_read_xfer_completion(struct scsi_task
*task
, sbd_cmd_t
*scmd
,
1645 struct stmf_data_buf
*dbuf
)
1647 if (dbuf
->db_xfer_status
!= STMF_SUCCESS
) {
1648 stmf_abort(STMF_QUEUE_TASK_ABORT
, task
,
1649 dbuf
->db_xfer_status
, NULL
);
1652 task
->task_nbytes_transferred
= dbuf
->db_data_size
;
1653 scmd
->flags
&= ~SBD_SCSI_CMD_ACTIVE
;
1654 stmf_scsilib_send_status(task
, STATUS_GOOD
, 0);
1658 sbd_handle_short_write_transfers(scsi_task_t
*task
,
1659 stmf_data_buf_t
*dbuf
, uint32_t cdb_xfer_size
)
1663 task
->task_cmd_xfer_length
= cdb_xfer_size
;
1664 if (task
->task_additional_flags
& TASK_AF_NO_EXPECTED_XFER_LENGTH
) {
1665 task
->task_expected_xfer_length
= cdb_xfer_size
;
1667 cdb_xfer_size
= min(cdb_xfer_size
,
1668 task
->task_expected_xfer_length
);
1671 if (cdb_xfer_size
== 0) {
1672 stmf_scsilib_send_status(task
, STATUS_CHECK
,
1673 STMF_SAA_INVALID_FIELD_IN_CDB
);
1676 if (task
->task_lu_private
== NULL
) {
1677 task
->task_lu_private
= kmem_zalloc(sizeof (sbd_cmd_t
),
1680 bzero(task
->task_lu_private
, sizeof (sbd_cmd_t
));
1682 scmd
= (sbd_cmd_t
*)task
->task_lu_private
;
1683 scmd
->cmd_type
= SBD_CMD_SMALL_WRITE
;
1684 scmd
->flags
= SBD_SCSI_CMD_ACTIVE
;
1685 scmd
->len
= cdb_xfer_size
;
1687 uint32_t minsize
= cdb_xfer_size
;
1689 dbuf
= stmf_alloc_dbuf(task
, cdb_xfer_size
, &minsize
, 0);
1691 stmf_abort(STMF_QUEUE_TASK_ABORT
, task
,
1692 STMF_ALLOC_FAILURE
, NULL
);
1695 dbuf
->db_data_size
= cdb_xfer_size
;
1696 dbuf
->db_relative_offset
= 0;
1697 dbuf
->db_flags
= DB_DIRECTION_FROM_RPORT
;
1698 (void) stmf_xfer_data(task
, dbuf
, 0);
1700 if (dbuf
->db_data_size
< cdb_xfer_size
) {
1701 stmf_abort(STMF_QUEUE_TASK_ABORT
, task
,
1702 STMF_ABORTED
, NULL
);
1705 dbuf
->db_data_size
= cdb_xfer_size
;
1706 sbd_handle_short_write_xfer_completion(task
, dbuf
);
1711 sbd_handle_short_write_xfer_completion(scsi_task_t
*task
,
1712 stmf_data_buf_t
*dbuf
)
1715 stmf_status_t st_ret
;
1716 sbd_lu_t
*sl
= (sbd_lu_t
*)task
->task_lu
->lu_provider_private
;
1719 * For now lets assume we will get only one sglist element
1720 * for short writes. If that ever changes, we should allocate
1721 * a local buffer and copy all the sg elements to one linear space.
1723 if ((dbuf
->db_xfer_status
!= STMF_SUCCESS
) ||
1724 (dbuf
->db_sglist_length
> 1)) {
1725 stmf_abort(STMF_QUEUE_TASK_ABORT
, task
,
1726 dbuf
->db_xfer_status
, NULL
);
1730 task
->task_nbytes_transferred
= dbuf
->db_data_size
;
1731 scmd
= (sbd_cmd_t
*)task
->task_lu_private
;
1732 scmd
->flags
&= ~SBD_SCSI_CMD_ACTIVE
;
1734 /* Lets find out who to call */
1735 switch (task
->task_cdb
[0]) {
1736 case SCMD_MODE_SELECT
:
1737 case SCMD_MODE_SELECT_G1
:
1738 if (sl
->sl_access_state
== SBD_LU_STANDBY
) {
1739 st_ret
= stmf_proxy_scsi_cmd(task
, dbuf
);
1740 if (st_ret
!= STMF_SUCCESS
) {
1741 stmf_scsilib_send_status(task
, STATUS_CHECK
,
1742 STMF_SAA_LU_NO_ACCESS_UNAVAIL
);
1745 sbd_handle_mode_select_xfer(task
,
1746 dbuf
->db_sglist
[0].seg_addr
, dbuf
->db_data_size
);
1750 sbd_handle_unmap_xfer(task
,
1751 dbuf
->db_sglist
[0].seg_addr
, dbuf
->db_data_size
);
1753 case SCMD_PERSISTENT_RESERVE_OUT
:
1754 if (sl
->sl_access_state
== SBD_LU_STANDBY
) {
1755 st_ret
= stmf_proxy_scsi_cmd(task
, dbuf
);
1756 if (st_ret
!= STMF_SUCCESS
) {
1757 stmf_scsilib_send_status(task
, STATUS_CHECK
,
1758 STMF_SAA_LU_NO_ACCESS_UNAVAIL
);
1761 sbd_handle_pgr_out_data(task
, dbuf
);
1765 /* This should never happen */
1766 stmf_abort(STMF_QUEUE_TASK_ABORT
, task
,
1767 STMF_ABORTED
, NULL
);
1772 sbd_handle_read_capacity(struct scsi_task
*task
,
1773 struct stmf_data_buf
*initial_dbuf
)
1775 sbd_lu_t
*sl
= (sbd_lu_t
*)task
->task_lu
->lu_provider_private
;
1781 s
= sl
->sl_lu_size
>> sl
->sl_data_blocksize_shift
;
1783 blksize
= ((uint16_t)1) << sl
->sl_data_blocksize_shift
;
1785 switch (task
->task_cdb
[0]) {
1786 case SCMD_READ_CAPACITY
:
1787 if (s
& 0xffffffff00000000ull
) {
1788 p
[0] = p
[1] = p
[2] = p
[3] = 0xFF;
1790 p
[0] = (s
>> 24) & 0xff;
1791 p
[1] = (s
>> 16) & 0xff;
1792 p
[2] = (s
>> 8) & 0xff;
1796 p
[6] = (blksize
>> 8) & 0xff;
1797 p
[7] = blksize
& 0xff;
1798 sbd_handle_short_read_transfers(task
, initial_dbuf
, p
, 8, 8);
1801 case SCMD_SVC_ACTION_IN_G4
:
1802 cdb_len
= READ_SCSI32(&task
->task_cdb
[10], uint32_t);
1804 p
[0] = (s
>> 56) & 0xff;
1805 p
[1] = (s
>> 48) & 0xff;
1806 p
[2] = (s
>> 40) & 0xff;
1807 p
[3] = (s
>> 32) & 0xff;
1808 p
[4] = (s
>> 24) & 0xff;
1809 p
[5] = (s
>> 16) & 0xff;
1810 p
[6] = (s
>> 8) & 0xff;
1812 p
[10] = (blksize
>> 8) & 0xff;
1813 p
[11] = blksize
& 0xff;
1814 if (sl
->sl_flags
& SL_UNMAP_ENABLED
) {
1817 sbd_handle_short_read_transfers(task
, initial_dbuf
, p
,
1824 sbd_calc_geometry(uint64_t s
, uint16_t blksize
, uint8_t *nsectors
,
1825 uint8_t *nheads
, uint32_t *ncyl
)
1827 if (s
< (4ull * 1024ull * 1024ull * 1024ull)) {
1834 *ncyl
= s
/ ((uint64_t)blksize
* (uint64_t)(*nsectors
) *
1835 (uint64_t)(*nheads
));
1839 sbd_handle_mode_sense(struct scsi_task
*task
,
1840 struct stmf_data_buf
*initial_dbuf
, uint8_t *buf
)
1842 sbd_lu_t
*sl
= (sbd_lu_t
*)task
->task_lu
->lu_provider_private
;
1843 uint32_t cmd_size
, n
;
1846 uint8_t nsectors
, nheads
;
1847 uint8_t page
, ctrl
, header_size
, pc_valid
;
1850 uint64_t s
= sl
->sl_lu_size
;
1851 uint32_t dev_spec_param_offset
;
1853 p
= buf
; /* buf is assumed to be zeroed out and large enough */
1855 cdb
= &task
->task_cdb
[0];
1856 page
= cdb
[2] & 0x3F;
1857 ctrl
= (cdb
[2] >> 6) & 3;
1858 cmd_size
= (cdb
[0] == SCMD_MODE_SENSE
) ? cdb
[4] :
1859 READ_SCSI16(&cdb
[7], uint32_t);
1861 if (cdb
[0] == SCMD_MODE_SENSE
) {
1863 dev_spec_param_offset
= 2;
1866 dev_spec_param_offset
= 3;
1869 /* Now validate the command */
1870 if ((cdb
[2] == 0) || (page
== MODEPAGE_ALLPAGES
) || (page
== 0x08) ||
1871 (page
== 0x0A) || (page
== 0x03) || (page
== 0x04)) {
1876 if ((cmd_size
< header_size
) || (pc_valid
== 0)) {
1877 stmf_scsilib_send_status(task
, STATUS_CHECK
,
1878 STMF_SAA_INVALID_FIELD_IN_CDB
);
1882 /* We will update the length in the mode header at the end */
1884 /* Block dev device specific param in mode param header has wp bit */
1885 if (sl
->sl_flags
& SL_WRITE_PROTECTED
) {
1886 p
[n
+ dev_spec_param_offset
] = BIT_7
;
1889 /* We are not going to return any block descriptor */
1891 nbytes
= ((uint16_t)1) << sl
->sl_data_blocksize_shift
;
1892 sbd_calc_geometry(s
, nbytes
, &nsectors
, &nheads
, &ncyl
);
1894 if ((page
== 0x03) || (page
== MODEPAGE_ALLPAGES
)) {
1898 p
[n
+ 11] = nsectors
;
1899 p
[n
+ 12] = nbytes
>> 8;
1900 p
[n
+ 13] = nbytes
& 0xff;
1905 if ((page
== 0x04) || (page
== MODEPAGE_ALLPAGES
)) {
1909 p
[n
+ 2] = ncyl
>> 16;
1910 p
[n
+ 3] = ncyl
>> 8;
1911 p
[n
+ 4] = ncyl
& 0xff;
1918 if ((page
== MODEPAGE_CACHING
) || (page
== MODEPAGE_ALLPAGES
)) {
1919 struct mode_caching
*mode_caching_page
;
1921 mode_caching_page
= (struct mode_caching
*)&p
[n
];
1923 mode_caching_page
->mode_page
.code
= MODEPAGE_CACHING
;
1924 mode_caching_page
->mode_page
.ps
= 1; /* A saveable page */
1925 mode_caching_page
->mode_page
.length
= 0x12;
1930 if ((sl
->sl_flags
& SL_WRITEBACK_CACHE_DISABLE
) == 0) {
1931 mode_caching_page
->wce
= 1;
1938 SL_WRITEBACK_CACHE_SET_UNSUPPORTED
) == 0) {
1939 mode_caching_page
->wce
= 1;
1945 SL_SAVED_WRITE_CACHE_DISABLE
) == 0) {
1946 mode_caching_page
->wce
= 1;
1950 n
+= (sizeof (struct mode_page
) +
1951 mode_caching_page
->mode_page
.length
);
1953 if ((page
== MODEPAGE_CTRL_MODE
) || (page
== MODEPAGE_ALLPAGES
)) {
1954 struct mode_control_scsi3
*mode_control_page
;
1956 mode_control_page
= (struct mode_control_scsi3
*)&p
[n
];
1958 mode_control_page
->mode_page
.code
= MODEPAGE_CTRL_MODE
;
1959 mode_control_page
->mode_page
.length
=
1960 PAGELENGTH_MODE_CONTROL_SCSI3
;
1962 /* If not looking for changeable values, report this. */
1963 mode_control_page
->que_mod
= CTRL_QMOD_UNRESTRICT
;
1965 n
+= (sizeof (struct mode_page
) +
1966 mode_control_page
->mode_page
.length
);
1969 if (cdb
[0] == SCMD_MODE_SENSE
) {
1971 stmf_scsilib_send_status(task
, STATUS_CHECK
,
1972 STMF_SAA_INVALID_FIELD_IN_CDB
);
1976 * Mode parameter header length doesn't include the number
1977 * of bytes in the length field, so adjust the count.
1978 * Byte count minus header length field size.
1980 buf
[0] = (n
- 1) & 0xff;
1982 /* Byte count minus header length field size. */
1983 buf
[1] = (n
- 2) & 0xff;
1984 buf
[0] = ((n
- 2) >> 8) & 0xff;
1987 sbd_handle_short_read_transfers(task
, initial_dbuf
, buf
,
1992 sbd_handle_mode_select(scsi_task_t
*task
, stmf_data_buf_t
*dbuf
)
1994 uint32_t cmd_xfer_len
;
1996 if (task
->task_cdb
[0] == SCMD_MODE_SELECT
) {
1997 cmd_xfer_len
= (uint32_t)task
->task_cdb
[4];
1999 cmd_xfer_len
= READ_SCSI16(&task
->task_cdb
[7], uint32_t);
2002 if ((task
->task_cdb
[1] & 0xFE) != 0x10) {
2003 stmf_scsilib_send_status(task
, STATUS_CHECK
,
2004 STMF_SAA_INVALID_FIELD_IN_CDB
);
2008 if (cmd_xfer_len
== 0) {
2009 /* zero byte mode selects are allowed */
2010 stmf_scsilib_send_status(task
, STATUS_GOOD
, 0);
2014 sbd_handle_short_write_transfers(task
, dbuf
, cmd_xfer_len
);
2018 sbd_handle_mode_select_xfer(scsi_task_t
*task
, uint8_t *buf
, uint32_t buflen
)
2020 sbd_lu_t
*sl
= (sbd_lu_t
*)task
->task_lu
->lu_provider_private
;
2022 int hdr_len
, bd_len
;
2026 if (task
->task_cdb
[0] == SCMD_MODE_SELECT
) {
2032 if (buflen
< hdr_len
)
2033 goto mode_sel_param_len_err
;
2035 bd_len
= hdr_len
== 4 ? buf
[3] : READ_SCSI16(&buf
[6], int);
2037 if (buflen
< (hdr_len
+ bd_len
+ 2))
2038 goto mode_sel_param_len_err
;
2040 buf
+= hdr_len
+ bd_len
;
2041 buflen
-= hdr_len
+ bd_len
;
2043 if ((buf
[0] != 8) || (buflen
!= ((uint32_t)buf
[1] + 2))) {
2044 goto mode_sel_param_len_err
;
2047 if (buf
[2] & 0xFB) {
2048 goto mode_sel_param_field_err
;
2051 for (i
= 3; i
< (buf
[1] + 2); i
++) {
2053 goto mode_sel_param_field_err
;
2059 /* All good. Lets handle the write cache change, if any */
2060 if (buf
[2] & BIT_2
) {
2061 sret
= sbd_wcd_set(0, sl
);
2063 sret
= sbd_wcd_set(1, sl
);
2066 if (sret
!= SBD_SUCCESS
) {
2067 stmf_scsilib_send_status(task
, STATUS_CHECK
,
2068 STMF_SAA_WRITE_ERROR
);
2072 /* set on the device passed, now set the flags */
2073 mutex_enter(&sl
->sl_lock
);
2074 if (buf
[2] & BIT_2
) {
2075 sl
->sl_flags
&= ~SL_WRITEBACK_CACHE_DISABLE
;
2077 sl
->sl_flags
|= SL_WRITEBACK_CACHE_DISABLE
;
2080 for (it
= sl
->sl_it_list
; it
!= NULL
; it
= it
->sbd_it_next
) {
2081 if (it
== task
->task_lu_itl_handle
)
2083 it
->sbd_it_ua_conditions
|= SBD_UA_MODE_PARAMETERS_CHANGED
;
2086 if (task
->task_cdb
[1] & 1) {
2087 if (buf
[2] & BIT_2
) {
2088 sl
->sl_flags
&= ~SL_SAVED_WRITE_CACHE_DISABLE
;
2090 sl
->sl_flags
|= SL_SAVED_WRITE_CACHE_DISABLE
;
2092 mutex_exit(&sl
->sl_lock
);
2093 sret
= sbd_write_lu_info(sl
);
2095 mutex_exit(&sl
->sl_lock
);
2097 if (sret
== SBD_SUCCESS
) {
2098 stmf_scsilib_send_status(task
, STATUS_GOOD
, 0);
2100 stmf_scsilib_send_status(task
, STATUS_CHECK
,
2101 STMF_SAA_WRITE_ERROR
);
2105 mode_sel_param_len_err
:
2106 stmf_scsilib_send_status(task
, STATUS_CHECK
,
2107 STMF_SAA_PARAM_LIST_LENGTH_ERROR
);
2109 mode_sel_param_field_err
:
2110 stmf_scsilib_send_status(task
, STATUS_CHECK
,
2111 STMF_SAA_INVALID_FIELD_IN_PARAM_LIST
);
2115 * Command support added from SPC-4 r24
2116 * Supports info type 0, 2, 127
2119 sbd_handle_identifying_info(struct scsi_task
*task
,
2120 stmf_data_buf_t
*initial_dbuf
)
2122 sbd_lu_t
*sl
= (sbd_lu_t
*)task
->task_lu
->lu_provider_private
;
2130 cdb
= &task
->task_cdb
[0];
2131 cmd_size
= READ_SCSI32(&cdb
[6], uint32_t);
2132 info_type
= cdb
[10]>>1;
2134 /* Validate the command */
2136 stmf_scsilib_send_status(task
, STATUS_CHECK
,
2137 STMF_SAA_INVALID_FIELD_IN_CDB
);
2141 p
= buf
= kmem_zalloc(260, KM_SLEEP
);
2143 switch (info_type
) {
2146 * No value is supplied but this info type
2152 mutex_enter(&sl
->sl_lock
);
2153 param_len
= strlcpy((char *)(p
+4), sl
->sl_alias
, 256);
2154 mutex_exit(&sl
->sl_lock
);
2155 /* text info must be null terminated */
2156 if (++param_len
> 256)
2158 SCSI_WRITE16(p
+2, param_len
);
2159 xfer_size
= param_len
+ 4;
2162 /* 0 and 2 descriptor supported */
2163 SCSI_WRITE16(p
+2, 8); /* set param length */
2165 *p
= 4; /* set type to 2 (7 hi bits) */
2167 SCSI_WRITE16(p
, 256); /* 256 max length */
2171 stmf_scsilib_send_status(task
, STATUS_CHECK
,
2172 STMF_SAA_INVALID_FIELD_IN_CDB
);
2173 kmem_free(buf
, 260);
2176 sbd_handle_short_read_transfers(task
, initial_dbuf
, buf
,
2177 cmd_size
, xfer_size
);
2178 kmem_free(buf
, 260);
2182 * This function parse through a string, passed to it as a pointer to a string,
2183 * by adjusting the pointer to the first non-space character and returns
2184 * the count/length of the first bunch of non-space characters. Multiple
2185 * Management URLs are stored as a space delimited string in sl_mgmt_url
2186 * field of sbd_lu_t. This function is used to retrieve one url at a time.
2188 * i/p : pointer to pointer to a url string
2189 * o/p : Adjust the pointer to the url to the first non white character
2190 * and returns the length of the URL
2193 sbd_parse_mgmt_url(char **url_addr
)
2195 uint16_t url_length
= 0;
2199 while (*url
!= '\0') {
2200 if (*url
== ' ' || *url
== '\t' || *url
== '\n') {
2208 while (*url
!= '\0') {
2209 if (*url
== ' ' || *url
== '\t' ||
2210 *url
== '\n' || *url
== '\0') {
2216 return (url_length
);
2219 /* Try to make this the size of a kmem allocation cache. */
2220 static uint_t sbd_write_same_optimal_chunk
= 128 * 1024;
2223 sbd_write_same_data(struct scsi_task
*task
, sbd_cmd_t
*scmd
)
2225 sbd_lu_t
*sl
= (sbd_lu_t
*)task
->task_lu
->lu_provider_private
;
2226 uint64_t addr
, len
, sz_done
;
2227 uint32_t big_buf_size
, xfer_size
, off
;
2231 if (task
->task_cdb
[0] == SCMD_WRITE_SAME_G1
) {
2232 addr
= READ_SCSI32(&task
->task_cdb
[2], uint64_t);
2233 len
= READ_SCSI16(&task
->task_cdb
[7], uint64_t);
2235 addr
= READ_SCSI64(&task
->task_cdb
[2], uint64_t);
2236 len
= READ_SCSI32(&task
->task_cdb
[10], uint64_t);
2238 addr
<<= sl
->sl_data_blocksize_shift
;
2239 len
<<= sl
->sl_data_blocksize_shift
;
2243 * "len" is total size of what we wish to "write same".
2245 * xfer_size will be scmd->trans_data_len, which is the length
2246 * of the pattern we wish to replicate over "len". We replicate
2247 * "xfer_size" of pattern over "len".
2249 * big_buf_size is set to an ideal actual-write size for an output
2250 * operation. It may be the same as "len". If it's not, it should
2251 * be an exact multiple of "xfer_size" so we don't get pattern
2252 * breakage until the very end of "len".
2254 big_buf_size
= len
> sbd_write_same_optimal_chunk
?
2255 sbd_write_same_optimal_chunk
: (uint32_t)len
;
2256 xfer_size
= scmd
->trans_data_len
;
2259 * All transfers should be an integral multiple of the sector size.
2261 ASSERT((big_buf_size
% xfer_size
) == 0);
2264 * Don't sleep for the allocation, and don't make the system
2265 * reclaim memory. Trade higher I/Os if in a low-memory situation.
2267 big_buf
= kmem_alloc(big_buf_size
, KM_NOSLEEP
| KM_NORMALPRI
);
2269 if (big_buf
== NULL
) {
2271 * Just send it in terms of of the transmitted data. This
2272 * will be very slow.
2274 DTRACE_PROBE1(write__same__low__memory
, uint64_t, big_buf_size
);
2275 big_buf
= scmd
->trans_data
;
2276 big_buf_size
= scmd
->trans_data_len
;
2279 * We already ASSERT()ed big_buf_size is an integral multiple
2282 for (off
= 0; off
< big_buf_size
; off
+= xfer_size
)
2283 bcopy(scmd
->trans_data
, big_buf
+ off
, xfer_size
);
2286 /* Do the actual I/O. Recycle xfer_size now to be write size. */
2287 DTRACE_PROBE1(write__same__io__begin
, uint64_t, len
);
2288 for (sz_done
= 0; sz_done
< len
; sz_done
+= (uint64_t)xfer_size
) {
2289 xfer_size
= ((big_buf_size
+ sz_done
) <= len
) ? big_buf_size
:
2291 ret
= sbd_data_write(sl
, task
, addr
+ sz_done
,
2292 (uint64_t)xfer_size
, big_buf
);
2293 if (ret
!= SBD_SUCCESS
)
2296 DTRACE_PROBE2(write__same__io__end
, uint64_t, len
, uint64_t, sz_done
);
2298 if (big_buf
!= scmd
->trans_data
)
2299 kmem_free(big_buf
, big_buf_size
);
2305 sbd_handle_write_same_xfer_completion(struct scsi_task
*task
, sbd_cmd_t
*scmd
,
2306 struct stmf_data_buf
*dbuf
, uint8_t dbuf_reusable
)
2309 uint32_t buflen
, iolen
;
2312 if (dbuf
->db_xfer_status
!= STMF_SUCCESS
) {
2313 stmf_abort(STMF_QUEUE_TASK_ABORT
, task
,
2314 dbuf
->db_xfer_status
, NULL
);
2318 if (scmd
->flags
& SBD_SCSI_CMD_XFER_FAIL
) {
2319 goto write_same_xfer_done
;
2322 if (scmd
->len
!= 0) {
2324 * Initiate the next port xfer to occur in parallel
2325 * with writing this buf.
2327 sbd_do_write_same_xfer(task
, scmd
, NULL
, 0);
2330 laddr
= dbuf
->db_relative_offset
;
2332 for (buflen
= 0, ndx
= 0; (buflen
< dbuf
->db_data_size
) &&
2333 (ndx
< dbuf
->db_sglist_length
); ndx
++) {
2334 iolen
= min(dbuf
->db_data_size
- buflen
,
2335 dbuf
->db_sglist
[ndx
].seg_length
);
2338 bcopy(dbuf
->db_sglist
[ndx
].seg_addr
, &scmd
->trans_data
[laddr
],
2341 laddr
+= (uint64_t)iolen
;
2343 task
->task_nbytes_transferred
+= buflen
;
2345 write_same_xfer_done
:
2346 if (scmd
->len
== 0 || scmd
->flags
& SBD_SCSI_CMD_XFER_FAIL
) {
2347 stmf_free_dbuf(task
, dbuf
);
2348 scmd
->flags
&= ~SBD_SCSI_CMD_ACTIVE
;
2349 if (scmd
->flags
& SBD_SCSI_CMD_XFER_FAIL
) {
2350 stmf_scsilib_send_status(task
, STATUS_CHECK
,
2351 STMF_SAA_WRITE_ERROR
);
2353 ret
= sbd_write_same_data(task
, scmd
);
2354 if (ret
!= SBD_SUCCESS
) {
2355 stmf_scsilib_send_status(task
, STATUS_CHECK
,
2356 STMF_SAA_WRITE_ERROR
);
2358 stmf_scsilib_send_status(task
, STATUS_GOOD
, 0);
2362 * Only way we should get here is via handle_write_same(),
2363 * and that should make the following assertion always pass.
2365 ASSERT((scmd
->flags
& SBD_SCSI_CMD_TRANS_DATA
) &&
2366 scmd
->trans_data
!= NULL
);
2367 kmem_free(scmd
->trans_data
, scmd
->trans_data_len
);
2368 scmd
->flags
&= ~SBD_SCSI_CMD_TRANS_DATA
;
2371 sbd_do_write_same_xfer(task
, scmd
, dbuf
, dbuf_reusable
);
2375 sbd_do_write_same_xfer(struct scsi_task
*task
, sbd_cmd_t
*scmd
,
2376 struct stmf_data_buf
*dbuf
, uint8_t dbuf_reusable
)
2380 if (scmd
->len
== 0) {
2382 stmf_free_dbuf(task
, dbuf
);
2386 if ((dbuf
!= NULL
) &&
2387 ((dbuf
->db_flags
& DB_DONT_REUSE
) || (dbuf_reusable
== 0))) {
2388 /* free current dbuf and allocate a new one */
2389 stmf_free_dbuf(task
, dbuf
);
2393 uint32_t maxsize
, minsize
, old_minsize
;
2395 maxsize
= (scmd
->len
> (128*1024)) ? 128*1024 :
2397 minsize
= maxsize
>> 2;
2399 old_minsize
= minsize
;
2400 dbuf
= stmf_alloc_dbuf(task
, maxsize
, &minsize
, 0);
2401 } while ((dbuf
== NULL
) && (old_minsize
> minsize
) &&
2404 if (scmd
->nbufs
== 0) {
2405 stmf_abort(STMF_QUEUE_TASK_ABORT
, task
,
2406 STMF_ALLOC_FAILURE
, NULL
);
2412 len
= scmd
->len
> dbuf
->db_buf_size
? dbuf
->db_buf_size
:
2415 dbuf
->db_relative_offset
= scmd
->current_ro
;
2416 dbuf
->db_data_size
= len
;
2417 dbuf
->db_flags
= DB_DIRECTION_FROM_RPORT
;
2418 (void) stmf_xfer_data(task
, dbuf
, 0);
2419 scmd
->nbufs
++; /* outstanding port xfers and bufs used */
2421 scmd
->current_ro
+= len
;
2425 sbd_handle_write_same(scsi_task_t
*task
, struct stmf_data_buf
*initial_dbuf
)
2427 sbd_lu_t
*sl
= (sbd_lu_t
*)task
->task_lu
->lu_provider_private
;
2430 stmf_data_buf_t
*dbuf
;
2432 uint8_t do_immediate_data
= 0;
2434 task
->task_cmd_xfer_length
= 0;
2435 if (task
->task_additional_flags
&
2436 TASK_AF_NO_EXPECTED_XFER_LENGTH
) {
2437 task
->task_expected_xfer_length
= 0;
2439 if (sl
->sl_flags
& SL_WRITE_PROTECTED
) {
2440 stmf_scsilib_send_status(task
, STATUS_CHECK
,
2441 STMF_SAA_WRITE_PROTECTED
);
2444 if (task
->task_cdb
[1] & 0xF7) {
2445 stmf_scsilib_send_status(task
, STATUS_CHECK
,
2446 STMF_SAA_INVALID_FIELD_IN_CDB
);
2449 unmap
= task
->task_cdb
[1] & 0x08;
2450 if (unmap
&& ((sl
->sl_flags
& SL_UNMAP_ENABLED
) == 0)) {
2451 stmf_scsilib_send_status(task
, STATUS_CHECK
,
2452 STMF_SAA_INVALID_FIELD_IN_CDB
);
2455 if (task
->task_cdb
[0] == SCMD_WRITE_SAME_G1
) {
2456 addr
= READ_SCSI32(&task
->task_cdb
[2], uint64_t);
2457 len
= READ_SCSI16(&task
->task_cdb
[7], uint64_t);
2459 addr
= READ_SCSI64(&task
->task_cdb
[2], uint64_t);
2460 len
= READ_SCSI32(&task
->task_cdb
[10], uint64_t);
2463 stmf_scsilib_send_status(task
, STATUS_CHECK
,
2464 STMF_SAA_INVALID_FIELD_IN_CDB
);
2467 addr
<<= sl
->sl_data_blocksize_shift
;
2468 len
<<= sl
->sl_data_blocksize_shift
;
2470 /* Check if the command is for the unmap function */
2472 dkioc_free_list_t
*dfl
= kmem_zalloc(DFL_SZ(1), KM_SLEEP
);
2474 dfl
->dfl_num_exts
= 1;
2475 dfl
->dfl_exts
[0].dfle_start
= addr
;
2476 dfl
->dfl_exts
[0].dfle_length
= len
;
2477 if (sbd_unmap(sl
, dfl
) != 0) {
2478 stmf_scsilib_send_status(task
, STATUS_CHECK
,
2479 STMF_SAA_LBA_OUT_OF_RANGE
);
2481 stmf_scsilib_send_status(task
, STATUS_GOOD
, 0);
2487 /* Write same function */
2489 task
->task_cmd_xfer_length
= 1 << sl
->sl_data_blocksize_shift
;
2490 if (task
->task_additional_flags
&
2491 TASK_AF_NO_EXPECTED_XFER_LENGTH
) {
2492 task
->task_expected_xfer_length
= task
->task_cmd_xfer_length
;
2494 if ((addr
+ len
) > sl
->sl_lu_size
) {
2495 stmf_scsilib_send_status(task
, STATUS_CHECK
,
2496 STMF_SAA_LBA_OUT_OF_RANGE
);
2500 /* For rest of this I/O the transfer length is 1 block */
2501 len
= ((uint64_t)1) << sl
->sl_data_blocksize_shift
;
2503 /* Some basic checks */
2504 if ((len
== 0) || (len
!= task
->task_expected_xfer_length
)) {
2505 stmf_scsilib_send_status(task
, STATUS_CHECK
,
2506 STMF_SAA_INVALID_FIELD_IN_CDB
);
2511 if ((initial_dbuf
!= NULL
) && (task
->task_flags
& TF_INITIAL_BURST
)) {
2512 if (initial_dbuf
->db_data_size
> len
) {
2513 if (initial_dbuf
->db_data_size
>
2514 task
->task_expected_xfer_length
) {
2515 /* protocol error */
2516 stmf_abort(STMF_QUEUE_TASK_ABORT
, task
,
2517 STMF_INVALID_ARG
, NULL
);
2520 initial_dbuf
->db_data_size
= (uint32_t)len
;
2522 do_immediate_data
= 1;
2524 dbuf
= initial_dbuf
;
2526 if (task
->task_lu_private
) {
2527 scmd
= (sbd_cmd_t
*)task
->task_lu_private
;
2529 scmd
= (sbd_cmd_t
*)kmem_alloc(sizeof (sbd_cmd_t
), KM_SLEEP
);
2530 task
->task_lu_private
= scmd
;
2532 scmd
->flags
= SBD_SCSI_CMD_ACTIVE
| SBD_SCSI_CMD_TRANS_DATA
;
2533 scmd
->cmd_type
= SBD_CMD_SCSI_WRITE
;
2535 scmd
->len
= (uint32_t)len
;
2536 scmd
->trans_data_len
= (uint32_t)len
;
2537 scmd
->trans_data
= kmem_alloc((size_t)len
, KM_SLEEP
);
2538 scmd
->current_ro
= 0;
2540 if (do_immediate_data
) {
2542 * Account for data passed in this write command
2544 (void) stmf_xfer_data(task
, dbuf
, STMF_IOF_STATS_ONLY
);
2545 scmd
->len
-= dbuf
->db_data_size
;
2546 scmd
->current_ro
+= dbuf
->db_data_size
;
2547 dbuf
->db_xfer_status
= STMF_SUCCESS
;
2548 sbd_handle_write_same_xfer_completion(task
, scmd
, dbuf
, 0);
2550 sbd_do_write_same_xfer(task
, scmd
, dbuf
, 0);
2555 sbd_handle_unmap(scsi_task_t
*task
, stmf_data_buf_t
*dbuf
)
2557 uint32_t cmd_xfer_len
;
2559 cmd_xfer_len
= READ_SCSI16(&task
->task_cdb
[7], uint32_t);
2561 if (task
->task_cdb
[1] & 1) {
2562 stmf_scsilib_send_status(task
, STATUS_CHECK
,
2563 STMF_SAA_INVALID_FIELD_IN_CDB
);
2567 if (cmd_xfer_len
== 0) {
2568 task
->task_cmd_xfer_length
= 0;
2569 if (task
->task_additional_flags
&
2570 TASK_AF_NO_EXPECTED_XFER_LENGTH
) {
2571 task
->task_expected_xfer_length
= 0;
2573 stmf_scsilib_send_status(task
, STATUS_GOOD
, 0);
2577 sbd_handle_short_write_transfers(task
, dbuf
, cmd_xfer_len
);
2581 sbd_handle_unmap_xfer(scsi_task_t
*task
, uint8_t *buf
, uint32_t buflen
)
2583 sbd_lu_t
*sl
= (sbd_lu_t
*)task
->task_lu
->lu_provider_private
;
2584 uint32_t ulen
, dlen
, num_desc
;
2587 dkioc_free_list_t
*dfl
;
2592 stmf_scsilib_send_status(task
, STATUS_CHECK
,
2593 STMF_SAA_INVALID_FIELD_IN_CDB
);
2596 ulen
= READ_SCSI16(buf
, uint32_t);
2597 dlen
= READ_SCSI16(buf
+ 2, uint32_t);
2598 num_desc
= dlen
>> 4;
2599 if (((ulen
+ 2) != buflen
) || ((dlen
+ 8) != buflen
) || (dlen
& 0xf) ||
2601 stmf_scsilib_send_status(task
, STATUS_CHECK
,
2602 STMF_SAA_INVALID_FIELD_IN_CDB
);
2606 dfl
= kmem_zalloc(DFL_SZ(num_desc
), KM_SLEEP
);
2607 dfl
->dfl_num_exts
= num_desc
;
2608 for (p
= buf
+ 8, i
= 0; num_desc
; num_desc
--, p
+= 16, i
++) {
2609 addr
= READ_SCSI64(p
, uint64_t);
2610 addr
<<= sl
->sl_data_blocksize_shift
;
2611 len
= READ_SCSI32(p
+8, uint64_t);
2612 len
<<= sl
->sl_data_blocksize_shift
;
2613 /* Prepare a list of extents to unmap */
2614 dfl
->dfl_exts
[i
].dfle_start
= addr
;
2615 dfl
->dfl_exts
[i
].dfle_length
= len
;
2617 ASSERT(i
== dfl
->dfl_num_exts
);
2619 /* Finally execute the unmap operations in a single step */
2620 ret
= sbd_unmap(sl
, dfl
);
2623 stmf_scsilib_send_status(task
, STATUS_CHECK
,
2624 STMF_SAA_LBA_OUT_OF_RANGE
);
2628 stmf_scsilib_send_status(task
, STATUS_GOOD
, 0);
2632 sbd_handle_inquiry(struct scsi_task
*task
, struct stmf_data_buf
*initial_dbuf
)
2634 sbd_lu_t
*sl
= (sbd_lu_t
*)task
->task_lu
->lu_provider_private
;
2635 uint8_t *cdbp
= (uint8_t *)&task
->task_cdb
[0];
2638 uint8_t page_length
;
2639 uint16_t bsize
= 512;
2641 uint32_t xfer_size
= 4;
2642 uint32_t mgmt_url_size
= 0;
2645 char *mgmt_url
= NULL
;
2648 byte0
= DTYPE_DIRECT
;
2650 * Basic protocol checks.
2653 if ((((cdbp
[1] & 1) == 0) && cdbp
[2]) || cdbp
[5]) {
2654 stmf_scsilib_send_status(task
, STATUS_CHECK
,
2655 STMF_SAA_INVALID_FIELD_IN_CDB
);
2660 * Zero byte allocation length is not an error. Just
2664 cmd_size
= (((uint16_t)cdbp
[3]) << 8) | cdbp
[4];
2666 if (cmd_size
== 0) {
2667 task
->task_cmd_xfer_length
= 0;
2668 if (task
->task_additional_flags
&
2669 TASK_AF_NO_EXPECTED_XFER_LENGTH
) {
2670 task
->task_expected_xfer_length
= 0;
2672 stmf_scsilib_send_status(task
, STATUS_GOOD
, 0);
2680 if ((cdbp
[1] & 1) == 0) {
2682 struct scsi_inquiry
*inq
;
2684 p
= (uint8_t *)kmem_zalloc(bsize
, KM_SLEEP
);
2685 inq
= (struct scsi_inquiry
*)p
;
2688 xfer_size
= page_length
+ 5;
2690 inq
->inq_dtype
= DTYPE_DIRECT
;
2691 inq
->inq_ansi
= 5; /* SPC-3 */
2693 inq
->inq_rdf
= 2; /* Response data format for SPC-3 */
2694 inq
->inq_len
= page_length
;
2696 inq
->inq_tpgs
= TPGS_FAILOVER_IMPLICIT
;
2697 inq
->inq_cmdque
= 1;
2699 if (sl
->sl_flags
& SL_VID_VALID
) {
2700 bcopy(sl
->sl_vendor_id
, inq
->inq_vid
, 8);
2702 bcopy(sbd_vendor_id
, inq
->inq_vid
, 8);
2705 if (sl
->sl_flags
& SL_PID_VALID
) {
2706 bcopy(sl
->sl_product_id
, inq
->inq_pid
, 16);
2708 bcopy(sbd_product_id
, inq
->inq_pid
, 16);
2711 if (sl
->sl_flags
& SL_REV_VALID
) {
2712 bcopy(sl
->sl_revision
, inq
->inq_revision
, 4);
2714 bcopy(sbd_revision
, inq
->inq_revision
, 4);
2717 /* Adding Version Descriptors */
2719 /* SAM-3 no version */
2720 inq
->inq_vd
[i
].inq_vd_msb
= 0x00;
2721 inq
->inq_vd
[i
].inq_vd_lsb
= 0x60;
2725 switch (task
->task_lport
->lport_id
->protocol_id
) {
2726 case PROTOCOL_FIBRE_CHANNEL
:
2727 inq
->inq_vd
[i
].inq_vd_msb
= 0x09;
2728 inq
->inq_vd
[i
].inq_vd_lsb
= 0x00;
2732 case PROTOCOL_PARALLEL_SCSI
:
2734 case PROTOCOL_IEEE_1394
:
2735 /* Currently no claims of conformance */
2739 inq
->inq_vd
[i
].inq_vd_msb
= 0x09;
2740 inq
->inq_vd
[i
].inq_vd_lsb
= 0x40;
2744 case PROTOCOL_iSCSI
:
2745 inq
->inq_vd
[i
].inq_vd_msb
= 0x09;
2746 inq
->inq_vd
[i
].inq_vd_lsb
= 0x60;
2752 case PROTOCOL_ATAPI
:
2754 /* Currently no claims of conformance */
2758 /* SPC-3 no version */
2759 inq
->inq_vd
[i
].inq_vd_msb
= 0x03;
2760 inq
->inq_vd
[i
].inq_vd_lsb
= 0x00;
2763 /* SBC-2 no version */
2764 inq
->inq_vd
[i
].inq_vd_msb
= 0x03;
2765 inq
->inq_vd
[i
].inq_vd_lsb
= 0x20;
2767 sbd_handle_short_read_transfers(task
, initial_dbuf
, p
, cmd_size
,
2768 min(cmd_size
, xfer_size
));
2769 kmem_free(p
, bsize
);
2774 rw_enter(&sbd_global_prop_lock
, RW_READER
);
2775 if (sl
->sl_mgmt_url
) {
2776 mgmt_url_size
= strlen(sl
->sl_mgmt_url
);
2777 mgmt_url
= sl
->sl_mgmt_url
;
2778 } else if (sbd_mgmt_url
) {
2779 mgmt_url_size
= strlen(sbd_mgmt_url
);
2780 mgmt_url
= sbd_mgmt_url
;
2787 /* Default 512 bytes may not be enough, increase bsize if necessary */
2788 if (cdbp
[2] == 0x83 || cdbp
[2] == 0x85) {
2789 if (bsize
< cmd_size
)
2792 p
= (uint8_t *)kmem_zalloc(bsize
, KM_SLEEP
);
2796 page_length
= 4 + (mgmt_url_size
? 1 : 0);
2797 if (sl
->sl_flags
& SL_UNMAP_ENABLED
)
2802 /* Supported VPD pages in ascending order */
2808 if (mgmt_url_size
!= 0)
2811 if (sl
->sl_flags
& SL_UNMAP_ENABLED
) {
2816 xfer_size
= page_length
+ 4;
2820 if (sl
->sl_serial_no_size
) {
2821 page_length
= sl
->sl_serial_no_size
;
2822 bcopy(sl
->sl_serial_no
, p
+ 4, sl
->sl_serial_no_size
);
2824 /* if no serial num is specified set 4 spaces */
2826 bcopy(" ", p
+ 4, 4);
2831 xfer_size
= page_length
+ 4;
2835 xfer_size
= stmf_scsilib_prepare_vpd_page83(task
, p
,
2836 bsize
, byte0
, STMF_VPD_LU_ID
|STMF_VPD_TARGET_ID
|
2837 STMF_VPD_TP_GROUP
|STMF_VPD_RELATIVE_TP_ID
);
2841 if (mgmt_url_size
== 0) {
2842 stmf_scsilib_send_status(task
, STATUS_CHECK
,
2843 STMF_SAA_INVALID_FIELD_IN_CDB
);
2847 uint16_t idx
, newidx
, sz
, url_size
;
2855 url_size
= sbd_parse_mgmt_url(&url
);
2856 /* Creating Network Service Descriptors */
2857 while (url_size
!= 0) {
2858 /* Null terminated and 4 Byte aligned */
2860 sz
+= (sz
% 4) ? 4 - (sz
% 4) : 0;
2861 newidx
= idx
+ sz
+ 4;
2863 if (newidx
< bsize
) {
2865 * SPC-3r23 : Table 320 (Sec 7.6.5)
2866 * (Network service descriptor format
2868 * Note: Hard coding service type as
2869 * "Storage Configuration Service".
2872 SCSI_WRITE16(p
+ idx
+ 2, sz
);
2873 bcopy(url
, p
+ idx
+ 4, url_size
);
2874 xfer_size
= newidx
+ 4;
2878 /* skip to next mgmt url if any */
2880 url_size
= sbd_parse_mgmt_url(&url
);
2883 /* Total descriptor length */
2884 SCSI_WRITE16(p
+ 2, idx
- 4);
2892 p
[1] = 0x86; /* Page 86 response */
2896 * Bits 0, 1, and 2 will need to be updated
2897 * to reflect the queue tag handling if/when
2898 * that is implemented. For now, we're going
2899 * to claim support only for Simple TA.
2902 xfer_size
= page_length
+ 4;
2906 if ((sl
->sl_flags
& SL_UNMAP_ENABLED
) == 0) {
2907 stmf_scsilib_send_status(task
, STATUS_CHECK
,
2908 STMF_SAA_INVALID_FIELD_IN_CDB
);
2915 p
[20] = p
[21] = p
[22] = p
[23] = 0xFF;
2916 p
[24] = p
[25] = p
[26] = p
[27] = 0xFF;
2917 xfer_size
= page_length
+ 4;
2921 if ((sl
->sl_flags
& SL_UNMAP_ENABLED
) == 0) {
2922 stmf_scsilib_send_status(task
, STATUS_CHECK
,
2923 STMF_SAA_INVALID_FIELD_IN_CDB
);
2931 exp
= (uint8_t)sl
->sl_data_blocksize_shift
;
2932 s
= sl
->sl_lu_size
>> sl
->sl_data_blocksize_shift
;
2933 while (s
& ((uint64_t)0xFFFFFFFF80000000ull
)) {
2939 xfer_size
= page_length
+ 4;
2943 stmf_scsilib_send_status(task
, STATUS_CHECK
,
2944 STMF_SAA_INVALID_FIELD_IN_CDB
);
2948 sbd_handle_short_read_transfers(task
, initial_dbuf
, p
, cmd_size
,
2949 min(cmd_size
, xfer_size
));
2951 kmem_free(p
, bsize
);
2952 rw_exit(&sbd_global_prop_lock
);
2956 sbd_task_alloc(struct scsi_task
*task
)
2958 if ((task
->task_lu_private
=
2959 kmem_alloc(sizeof (sbd_cmd_t
), KM_NOSLEEP
)) != NULL
) {
2960 sbd_cmd_t
*scmd
= (sbd_cmd_t
*)task
->task_lu_private
;
2962 return (STMF_SUCCESS
);
2964 return (STMF_ALLOC_FAILURE
);
2968 sbd_remove_it_handle(sbd_lu_t
*sl
, sbd_it_data_t
*it
)
2970 sbd_it_data_t
**ppit
;
2972 sbd_pgr_remove_it_handle(sl
, it
);
2973 mutex_enter(&sl
->sl_lock
);
2974 for (ppit
= &sl
->sl_it_list
; *ppit
!= NULL
;
2975 ppit
= &((*ppit
)->sbd_it_next
)) {
2976 if ((*ppit
) == it
) {
2977 *ppit
= it
->sbd_it_next
;
2981 mutex_exit(&sl
->sl_lock
);
2983 DTRACE_PROBE2(itl__nexus__end
, stmf_lu_t
*, sl
->sl_lu
,
2984 sbd_it_data_t
*, it
);
2986 kmem_free(it
, sizeof (*it
));
2990 sbd_check_and_clear_scsi2_reservation(sbd_lu_t
*sl
, sbd_it_data_t
*it
)
2992 mutex_enter(&sl
->sl_lock
);
2993 if ((sl
->sl_flags
& SL_LU_HAS_SCSI2_RESERVATION
) == 0) {
2994 /* If we dont have any reservations, just get out. */
2995 mutex_exit(&sl
->sl_lock
);
3000 /* Find the I_T nexus which is holding the reservation. */
3001 for (it
= sl
->sl_it_list
; it
!= NULL
; it
= it
->sbd_it_next
) {
3002 if (it
->sbd_it_flags
& SBD_IT_HAS_SCSI2_RESERVATION
) {
3003 ASSERT(it
->sbd_it_session_id
==
3004 sl
->sl_rs_owner_session_id
);
3011 * We were passed an I_T nexus. If this nexus does not hold
3012 * the reservation, do nothing. This is why this function is
3013 * called "check_and_clear".
3015 if ((it
->sbd_it_flags
& SBD_IT_HAS_SCSI2_RESERVATION
) == 0) {
3016 mutex_exit(&sl
->sl_lock
);
3020 it
->sbd_it_flags
&= ~SBD_IT_HAS_SCSI2_RESERVATION
;
3021 sl
->sl_flags
&= ~SL_LU_HAS_SCSI2_RESERVATION
;
3022 mutex_exit(&sl
->sl_lock
);
3028 sbd_new_task(struct scsi_task
*task
, struct stmf_data_buf
*initial_dbuf
)
3030 sbd_lu_t
*sl
= (sbd_lu_t
*)task
->task_lu
->lu_provider_private
;
3033 stmf_status_t st_ret
;
3035 if ((it
= task
->task_lu_itl_handle
) == NULL
) {
3036 mutex_enter(&sl
->sl_lock
);
3037 for (it
= sl
->sl_it_list
; it
!= NULL
; it
= it
->sbd_it_next
) {
3038 if (it
->sbd_it_session_id
==
3039 task
->task_session
->ss_session_id
) {
3040 mutex_exit(&sl
->sl_lock
);
3041 stmf_scsilib_send_status(task
, STATUS_BUSY
, 0);
3045 it
= (sbd_it_data_t
*)kmem_zalloc(sizeof (*it
), KM_NOSLEEP
);
3047 mutex_exit(&sl
->sl_lock
);
3048 stmf_scsilib_send_status(task
, STATUS_BUSY
, 0);
3051 it
->sbd_it_session_id
= task
->task_session
->ss_session_id
;
3052 bcopy(task
->task_lun_no
, it
->sbd_it_lun
, 8);
3053 it
->sbd_it_next
= sl
->sl_it_list
;
3054 sl
->sl_it_list
= it
;
3055 mutex_exit(&sl
->sl_lock
);
3057 DTRACE_PROBE1(itl__nexus__start
, scsi_task
*, task
);
3059 sbd_pgr_initialize_it(task
, it
);
3060 if (stmf_register_itl_handle(task
->task_lu
, task
->task_lun_no
,
3061 task
->task_session
, it
->sbd_it_session_id
, it
)
3063 sbd_remove_it_handle(sl
, it
);
3064 stmf_scsilib_send_status(task
, STATUS_BUSY
, 0);
3067 task
->task_lu_itl_handle
= it
;
3068 if (sl
->sl_access_state
!= SBD_LU_STANDBY
) {
3069 it
->sbd_it_ua_conditions
= SBD_UA_POR
;
3071 } else if (it
->sbd_it_flags
& SBD_IT_PGR_CHECK_FLAG
) {
3072 mutex_enter(&sl
->sl_lock
);
3073 it
->sbd_it_flags
&= ~SBD_IT_PGR_CHECK_FLAG
;
3074 mutex_exit(&sl
->sl_lock
);
3075 sbd_pgr_initialize_it(task
, it
);
3078 if (task
->task_mgmt_function
) {
3079 stmf_scsilib_handle_task_mgmt(task
);
3084 * if we're transitioning between access
3085 * states, return NOT READY
3087 if (sl
->sl_access_state
== SBD_LU_TRANSITION_TO_STANDBY
||
3088 sl
->sl_access_state
== SBD_LU_TRANSITION_TO_ACTIVE
) {
3089 stmf_scsilib_send_status(task
, STATUS_CHECK
,
3090 STMF_SAA_LU_NO_ACCESS_UNAVAIL
);
3094 /* Checking ua conditions as per SAM3R14 5.3.2 specified order */
3095 if ((it
->sbd_it_ua_conditions
) && (task
->task_cdb
[0] != SCMD_INQUIRY
)) {
3098 mutex_enter(&sl
->sl_lock
);
3099 if (it
->sbd_it_ua_conditions
& SBD_UA_POR
) {
3100 it
->sbd_it_ua_conditions
&= ~SBD_UA_POR
;
3103 mutex_exit(&sl
->sl_lock
);
3105 stmf_scsilib_send_status(task
, STATUS_CHECK
, saa
);
3110 /* Reservation conflict checks */
3111 if (sl
->sl_access_state
== SBD_LU_ACTIVE
) {
3112 if (SBD_PGR_RSVD(sl
->sl_pgr
)) {
3113 if (sbd_pgr_reservation_conflict(task
)) {
3114 stmf_scsilib_send_status(task
,
3115 STATUS_RESERVATION_CONFLICT
, 0);
3118 } else if ((sl
->sl_flags
& SL_LU_HAS_SCSI2_RESERVATION
) &&
3119 ((it
->sbd_it_flags
& SBD_IT_HAS_SCSI2_RESERVATION
) == 0)) {
3120 if (!(SCSI2_CONFLICT_FREE_CMDS(task
->task_cdb
))) {
3121 stmf_scsilib_send_status(task
,
3122 STATUS_RESERVATION_CONFLICT
, 0);
3128 /* Rest of the ua conndition checks */
3129 if ((it
->sbd_it_ua_conditions
) && (task
->task_cdb
[0] != SCMD_INQUIRY
)) {
3132 mutex_enter(&sl
->sl_lock
);
3133 if (it
->sbd_it_ua_conditions
& SBD_UA_CAPACITY_CHANGED
) {
3134 it
->sbd_it_ua_conditions
&= ~SBD_UA_CAPACITY_CHANGED
;
3135 if ((task
->task_cdb
[0] == SCMD_READ_CAPACITY
) ||
3136 ((task
->task_cdb
[0] == SCMD_SVC_ACTION_IN_G4
) &&
3137 (task
->task_cdb
[1] ==
3138 SSVC_ACTION_READ_CAPACITY_G4
))) {
3141 saa
= STMF_SAA_CAPACITY_DATA_HAS_CHANGED
;
3143 } else if (it
->sbd_it_ua_conditions
&
3144 SBD_UA_MODE_PARAMETERS_CHANGED
) {
3145 it
->sbd_it_ua_conditions
&=
3146 ~SBD_UA_MODE_PARAMETERS_CHANGED
;
3147 saa
= STMF_SAA_MODE_PARAMETERS_CHANGED
;
3148 } else if (it
->sbd_it_ua_conditions
&
3149 SBD_UA_ASYMMETRIC_ACCESS_CHANGED
) {
3150 it
->sbd_it_ua_conditions
&=
3151 ~SBD_UA_ASYMMETRIC_ACCESS_CHANGED
;
3152 saa
= STMF_SAA_ASYMMETRIC_ACCESS_CHANGED
;
3153 } else if (it
->sbd_it_ua_conditions
&
3154 SBD_UA_ACCESS_STATE_TRANSITION
) {
3155 it
->sbd_it_ua_conditions
&=
3156 ~SBD_UA_ACCESS_STATE_TRANSITION
;
3157 saa
= STMF_SAA_LU_NO_ACCESS_TRANSITION
;
3159 it
->sbd_it_ua_conditions
= 0;
3162 mutex_exit(&sl
->sl_lock
);
3164 stmf_scsilib_send_status(task
, STATUS_CHECK
, saa
);
3169 cdb0
= task
->task_cdb
[0];
3170 cdb1
= task
->task_cdb
[1];
3172 if (sl
->sl_access_state
== SBD_LU_STANDBY
) {
3173 if (cdb0
!= SCMD_INQUIRY
&&
3174 cdb0
!= SCMD_MODE_SENSE
&&
3175 cdb0
!= SCMD_MODE_SENSE_G1
&&
3176 cdb0
!= SCMD_MODE_SELECT
&&
3177 cdb0
!= SCMD_MODE_SELECT_G1
&&
3178 cdb0
!= SCMD_RESERVE
&&
3179 cdb0
!= SCMD_RELEASE
&&
3180 cdb0
!= SCMD_PERSISTENT_RESERVE_OUT
&&
3181 cdb0
!= SCMD_PERSISTENT_RESERVE_IN
&&
3182 cdb0
!= SCMD_REQUEST_SENSE
&&
3183 cdb0
!= SCMD_READ_CAPACITY
&&
3184 cdb0
!= SCMD_TEST_UNIT_READY
&&
3185 cdb0
!= SCMD_START_STOP
&&
3186 cdb0
!= SCMD_READ
&&
3187 cdb0
!= SCMD_READ_G1
&&
3188 cdb0
!= SCMD_READ_G4
&&
3189 cdb0
!= SCMD_READ_G5
&&
3190 !(cdb0
== SCMD_SVC_ACTION_IN_G4
&&
3191 cdb1
== SSVC_ACTION_READ_CAPACITY_G4
) &&
3192 !(cdb0
== SCMD_MAINTENANCE_IN
&&
3193 (cdb1
& 0x1F) == 0x05) &&
3194 !(cdb0
== SCMD_MAINTENANCE_IN
&&
3195 (cdb1
& 0x1F) == 0x0A)) {
3196 stmf_scsilib_send_status(task
, STATUS_CHECK
,
3197 STMF_SAA_LU_NO_ACCESS_STANDBY
);
3202 * is this a short write?
3203 * if so, we'll need to wait until we have the buffer
3204 * before proxying the command
3207 case SCMD_MODE_SELECT
:
3208 case SCMD_MODE_SELECT_G1
:
3209 case SCMD_PERSISTENT_RESERVE_OUT
:
3212 st_ret
= stmf_proxy_scsi_cmd(task
,
3214 if (st_ret
!= STMF_SUCCESS
) {
3215 stmf_scsilib_send_status(task
,
3217 STMF_SAA_LU_NO_ACCESS_UNAVAIL
);
3223 cdb0
= task
->task_cdb
[0] & 0x1F;
3225 if ((cdb0
== SCMD_READ
) || (cdb0
== SCMD_WRITE
)) {
3226 if (task
->task_additional_flags
& TASK_AF_PORT_LOAD_HIGH
) {
3227 stmf_scsilib_send_status(task
, STATUS_QFULL
, 0);
3230 if (cdb0
== SCMD_READ
) {
3231 sbd_handle_read(task
, initial_dbuf
);
3234 sbd_handle_write(task
, initial_dbuf
);
3238 cdb0
= task
->task_cdb
[0];
3239 cdb1
= task
->task_cdb
[1];
3241 if (cdb0
== SCMD_INQUIRY
) { /* Inquiry */
3242 sbd_handle_inquiry(task
, initial_dbuf
);
3246 if (cdb0
== SCMD_PERSISTENT_RESERVE_OUT
) {
3247 sbd_handle_pgr_out_cmd(task
, initial_dbuf
);
3251 if (cdb0
== SCMD_PERSISTENT_RESERVE_IN
) {
3252 sbd_handle_pgr_in_cmd(task
, initial_dbuf
);
3256 if (cdb0
== SCMD_RELEASE
) {
3258 stmf_scsilib_send_status(task
, STATUS_CHECK
,
3259 STMF_SAA_INVALID_FIELD_IN_CDB
);
3263 mutex_enter(&sl
->sl_lock
);
3264 if (sl
->sl_flags
& SL_LU_HAS_SCSI2_RESERVATION
) {
3265 /* If not owner don't release it, just return good */
3266 if (it
->sbd_it_session_id
!=
3267 sl
->sl_rs_owner_session_id
) {
3268 mutex_exit(&sl
->sl_lock
);
3269 stmf_scsilib_send_status(task
, STATUS_GOOD
, 0);
3273 sl
->sl_flags
&= ~SL_LU_HAS_SCSI2_RESERVATION
;
3274 it
->sbd_it_flags
&= ~SBD_IT_HAS_SCSI2_RESERVATION
;
3275 mutex_exit(&sl
->sl_lock
);
3276 stmf_scsilib_send_status(task
, STATUS_GOOD
, 0);
3280 if (cdb0
== SCMD_RESERVE
) {
3282 stmf_scsilib_send_status(task
, STATUS_CHECK
,
3283 STMF_SAA_INVALID_FIELD_IN_CDB
);
3287 mutex_enter(&sl
->sl_lock
);
3288 if (sl
->sl_flags
& SL_LU_HAS_SCSI2_RESERVATION
) {
3289 /* If not owner, return conflict status */
3290 if (it
->sbd_it_session_id
!=
3291 sl
->sl_rs_owner_session_id
) {
3292 mutex_exit(&sl
->sl_lock
);
3293 stmf_scsilib_send_status(task
,
3294 STATUS_RESERVATION_CONFLICT
, 0);
3298 sl
->sl_flags
|= SL_LU_HAS_SCSI2_RESERVATION
;
3299 it
->sbd_it_flags
|= SBD_IT_HAS_SCSI2_RESERVATION
;
3300 sl
->sl_rs_owner_session_id
= it
->sbd_it_session_id
;
3301 mutex_exit(&sl
->sl_lock
);
3302 stmf_scsilib_send_status(task
, STATUS_GOOD
, 0);
3306 if (cdb0
== SCMD_REQUEST_SENSE
) {
3308 * LU provider needs to store unretrieved sense data
3309 * (e.g. after power-on/reset). For now, we'll just
3310 * return good status with no sense.
3313 if ((cdb1
& ~1) || task
->task_cdb
[2] || task
->task_cdb
[3] ||
3314 task
->task_cdb
[5]) {
3315 stmf_scsilib_send_status(task
, STATUS_CHECK
,
3316 STMF_SAA_INVALID_FIELD_IN_CDB
);
3318 stmf_scsilib_send_status(task
, STATUS_GOOD
, 0);
3324 /* Report Target Port Groups */
3325 if ((cdb0
== SCMD_MAINTENANCE_IN
) &&
3326 ((cdb1
& 0x1F) == 0x0A)) {
3327 stmf_scsilib_handle_report_tpgs(task
, initial_dbuf
);
3331 /* Report Identifying Information */
3332 if ((cdb0
== SCMD_MAINTENANCE_IN
) &&
3333 ((cdb1
& 0x1F) == 0x05)) {
3334 sbd_handle_identifying_info(task
, initial_dbuf
);
3338 if (cdb0
== SCMD_START_STOP
) { /* Start stop */
3339 task
->task_cmd_xfer_length
= 0;
3340 if (task
->task_cdb
[4] & 0xFC) {
3341 stmf_scsilib_send_status(task
, STATUS_CHECK
,
3342 STMF_SAA_INVALID_FIELD_IN_CDB
);
3345 if (task
->task_cdb
[4] & 2) {
3346 stmf_scsilib_send_status(task
, STATUS_CHECK
,
3347 STMF_SAA_INVALID_FIELD_IN_CDB
);
3349 stmf_scsilib_send_status(task
, STATUS_GOOD
, 0);
3355 if ((cdb0
== SCMD_MODE_SENSE
) || (cdb0
== SCMD_MODE_SENSE_G1
)) {
3357 p
= kmem_zalloc(512, KM_SLEEP
);
3358 sbd_handle_mode_sense(task
, initial_dbuf
, p
);
3363 if ((cdb0
== SCMD_MODE_SELECT
) || (cdb0
== SCMD_MODE_SELECT_G1
)) {
3364 sbd_handle_mode_select(task
, initial_dbuf
);
3368 if ((cdb0
== SCMD_UNMAP
) && (sl
->sl_flags
& SL_UNMAP_ENABLED
)) {
3369 sbd_handle_unmap(task
, initial_dbuf
);
3373 if ((cdb0
== SCMD_WRITE_SAME_G4
) || (cdb0
== SCMD_WRITE_SAME_G1
)) {
3374 sbd_handle_write_same(task
, initial_dbuf
);
3378 if (cdb0
== SCMD_TEST_UNIT_READY
) { /* Test unit ready */
3379 task
->task_cmd_xfer_length
= 0;
3380 stmf_scsilib_send_status(task
, STATUS_GOOD
, 0);
3384 if (cdb0
== SCMD_READ_CAPACITY
) { /* Read Capacity */
3385 sbd_handle_read_capacity(task
, initial_dbuf
);
3389 if (cdb0
== SCMD_SVC_ACTION_IN_G4
) { /* Read Capacity or read long */
3390 if (cdb1
== SSVC_ACTION_READ_CAPACITY_G4
) {
3391 sbd_handle_read_capacity(task
, initial_dbuf
);
3394 * } else if (cdb1 == SSVC_ACTION_READ_LONG_G4) {
3395 * sbd_handle_read(task, initial_dbuf);
3402 * if (cdb0 == SCMD_SVC_ACTION_OUT_G4) {
3403 * if (cdb1 == SSVC_ACTION_WRITE_LONG_G4) {
3404 * sbd_handle_write(task, initial_dbuf);
3410 if (cdb0
== SCMD_VERIFY
) {
3412 * Something more likely needs to be done here.
3414 task
->task_cmd_xfer_length
= 0;
3415 stmf_scsilib_send_status(task
, STATUS_GOOD
, 0);
3419 if (cdb0
== SCMD_SYNCHRONIZE_CACHE
||
3420 cdb0
== SCMD_SYNCHRONIZE_CACHE_G4
) {
3421 sbd_handle_sync_cache(task
, initial_dbuf
);
3426 * Write and Verify use the same path as write, but don't clutter the
3427 * performance path above with checking for write_verify opcodes. We
3428 * rely on zfs's integrity checks for the "Verify" part of Write &
3429 * Verify. (Even if we did a read to "verify" we'd merely be reading
3430 * cache, not actual media.)
3432 * a) only support this if sbd_is_zvol, and
3433 * b) run the IO through the normal write path with a forced
3434 * sbd_flush_data_cache at the end.
3437 if ((sl
->sl_flags
& SL_ZFS_META
) && (
3438 cdb0
== SCMD_WRITE_VERIFY
||
3439 cdb0
== SCMD_WRITE_VERIFY_G4
||
3440 cdb0
== SCMD_WRITE_VERIFY_G5
)) {
3441 sbd_handle_write(task
, initial_dbuf
);
3445 stmf_scsilib_send_status(task
, STATUS_CHECK
, STMF_SAA_INVALID_OPCODE
);
3449 sbd_dbuf_xfer_done(struct scsi_task
*task
, struct stmf_data_buf
*dbuf
)
3451 sbd_cmd_t
*scmd
= (sbd_cmd_t
*)task
->task_lu_private
;
3453 if (dbuf
->db_flags
& DB_LU_DATA_BUF
) {
3455 * Buffers passed in from the LU always complete
3456 * even if the task is no longer active.
3458 ASSERT(task
->task_additional_flags
& TASK_AF_ACCEPT_LU_DBUF
);
3460 switch (scmd
->cmd_type
) {
3461 case (SBD_CMD_SCSI_READ
):
3462 sbd_handle_sgl_read_xfer_completion(task
, scmd
, dbuf
);
3464 case (SBD_CMD_SCSI_WRITE
):
3465 sbd_handle_sgl_write_xfer_completion(task
, scmd
, dbuf
);
3468 cmn_err(CE_PANIC
, "Unknown cmd type, task = %p",
3475 if ((scmd
== NULL
) || ((scmd
->flags
& SBD_SCSI_CMD_ACTIVE
) == 0))
3478 switch (scmd
->cmd_type
) {
3479 case (SBD_CMD_SCSI_READ
):
3480 sbd_handle_read_xfer_completion(task
, scmd
, dbuf
);
3483 case (SBD_CMD_SCSI_WRITE
):
3484 if ((task
->task_cdb
[0] == SCMD_WRITE_SAME_G1
) ||
3485 (task
->task_cdb
[0] == SCMD_WRITE_SAME_G4
)) {
3486 sbd_handle_write_same_xfer_completion(task
, scmd
, dbuf
,
3489 sbd_handle_write_xfer_completion(task
, scmd
, dbuf
, 1);
3493 case (SBD_CMD_SMALL_READ
):
3494 sbd_handle_short_read_xfer_completion(task
, scmd
, dbuf
);
3497 case (SBD_CMD_SMALL_WRITE
):
3498 sbd_handle_short_write_xfer_completion(task
, dbuf
);
3502 cmn_err(CE_PANIC
, "Unknown cmd type, task = %p", (void *)task
);
3509 sbd_send_status_done(struct scsi_task
*task
)
3512 "sbd_send_status_done: this should not have been called");
3516 sbd_task_free(struct scsi_task
*task
)
3518 if (task
->task_lu_private
) {
3519 sbd_cmd_t
*scmd
= (sbd_cmd_t
*)task
->task_lu_private
;
3520 if (scmd
->flags
& SBD_SCSI_CMD_ACTIVE
) {
3521 cmn_err(CE_PANIC
, "cmd is active, task = %p",
3524 kmem_free(scmd
, sizeof (sbd_cmd_t
));
3529 * Aborts are synchronus w.r.t. I/O AND
3530 * All the I/O which SBD does is synchronous AND
3531 * Everything within a task is single threaded.
3533 * If this function is called, we are doing nothing with this task
3534 * inside of sbd module.
3538 sbd_abort(struct stmf_lu
*lu
, int abort_cmd
, void *arg
, uint32_t flags
)
3540 sbd_lu_t
*sl
= (sbd_lu_t
*)lu
->lu_provider_private
;
3543 if (abort_cmd
== STMF_LU_RESET_STATE
) {
3544 return (sbd_lu_reset_state(lu
));
3547 if (abort_cmd
== STMF_LU_ITL_HANDLE_REMOVED
) {
3548 sbd_check_and_clear_scsi2_reservation(sl
, (sbd_it_data_t
*)arg
);
3549 sbd_remove_it_handle(sl
, (sbd_it_data_t
*)arg
);
3550 return (STMF_SUCCESS
);
3553 ASSERT(abort_cmd
== STMF_LU_ABORT_TASK
);
3554 task
= (scsi_task_t
*)arg
;
3555 if (task
->task_lu_private
) {
3556 sbd_cmd_t
*scmd
= (sbd_cmd_t
*)task
->task_lu_private
;
3558 if (scmd
->flags
& SBD_SCSI_CMD_ACTIVE
) {
3559 if (scmd
->flags
& SBD_SCSI_CMD_TRANS_DATA
) {
3560 kmem_free(scmd
->trans_data
,
3561 scmd
->trans_data_len
);
3562 scmd
->flags
&= ~SBD_SCSI_CMD_TRANS_DATA
;
3564 scmd
->flags
&= ~SBD_SCSI_CMD_ACTIVE
;
3565 return (STMF_ABORT_SUCCESS
);
3569 return (STMF_NOT_FOUND
);
3573 * This function is called during task clean-up if the
3574 * DB_LU_FLAG is set on the dbuf. This should only be called for
3575 * abort processing after sbd_abort has been called for the task.
3578 sbd_dbuf_free(struct scsi_task
*task
, struct stmf_data_buf
*dbuf
)
3580 sbd_cmd_t
*scmd
= (sbd_cmd_t
*)task
->task_lu_private
;
3581 sbd_lu_t
*sl
= (sbd_lu_t
*)task
->task_lu
->lu_provider_private
;
3583 ASSERT(dbuf
->db_lu_private
);
3584 ASSERT(scmd
&& scmd
->nbufs
> 0);
3585 ASSERT((scmd
->flags
& SBD_SCSI_CMD_ACTIVE
) == 0);
3586 ASSERT(dbuf
->db_flags
& DB_LU_DATA_BUF
);
3587 ASSERT(task
->task_additional_flags
& TASK_AF_ACCEPT_LU_DBUF
);
3588 ASSERT((curthread
->t_flag
& T_INTR_THREAD
) == 0);
3590 if (scmd
->cmd_type
== SBD_CMD_SCSI_READ
) {
3591 sbd_zvol_rele_read_bufs(sl
, dbuf
);
3592 } else if (scmd
->cmd_type
== SBD_CMD_SCSI_WRITE
) {
3593 sbd_zvol_rele_write_bufs_abort(sl
, dbuf
);
3595 cmn_err(CE_PANIC
, "Unknown cmd type %d, task = %p",
3596 scmd
->cmd_type
, (void *)task
);
3598 if (--scmd
->nbufs
== 0)
3599 rw_exit(&sl
->sl_access_state_lock
);
3600 stmf_teardown_dbuf(task
, dbuf
);
3606 sbd_ctl(struct stmf_lu
*lu
, int cmd
, void *arg
)
3608 sbd_lu_t
*sl
= (sbd_lu_t
*)lu
->lu_provider_private
;
3609 stmf_change_status_t st
;
3611 ASSERT((cmd
== STMF_CMD_LU_ONLINE
) ||
3612 (cmd
== STMF_CMD_LU_OFFLINE
) ||
3613 (cmd
== STMF_ACK_LU_ONLINE_COMPLETE
) ||
3614 (cmd
== STMF_ACK_LU_OFFLINE_COMPLETE
));
3616 st
.st_completion_status
= STMF_SUCCESS
;
3617 st
.st_additional_info
= NULL
;
3620 case STMF_CMD_LU_ONLINE
:
3621 if (sl
->sl_state
== STMF_STATE_ONLINE
)
3622 st
.st_completion_status
= STMF_ALREADY
;
3623 else if (sl
->sl_state
!= STMF_STATE_OFFLINE
)
3624 st
.st_completion_status
= STMF_FAILURE
;
3625 if (st
.st_completion_status
== STMF_SUCCESS
) {
3626 sl
->sl_state
= STMF_STATE_ONLINE
;
3627 sl
->sl_state_not_acked
= 1;
3629 (void) stmf_ctl(STMF_CMD_LU_ONLINE_COMPLETE
, lu
, &st
);
3632 case STMF_CMD_LU_OFFLINE
:
3633 if (sl
->sl_state
== STMF_STATE_OFFLINE
)
3634 st
.st_completion_status
= STMF_ALREADY
;
3635 else if (sl
->sl_state
!= STMF_STATE_ONLINE
)
3636 st
.st_completion_status
= STMF_FAILURE
;
3637 if (st
.st_completion_status
== STMF_SUCCESS
) {
3638 sl
->sl_flags
&= ~(SL_MEDIUM_REMOVAL_PREVENTED
|
3639 SL_LU_HAS_SCSI2_RESERVATION
);
3640 sl
->sl_state
= STMF_STATE_OFFLINE
;
3641 sl
->sl_state_not_acked
= 1;
3644 (void) stmf_ctl(STMF_CMD_LU_OFFLINE_COMPLETE
, lu
, &st
);
3647 case STMF_ACK_LU_ONLINE_COMPLETE
:
3649 case STMF_ACK_LU_OFFLINE_COMPLETE
:
3650 sl
->sl_state_not_acked
= 0;
3658 sbd_info(uint32_t cmd
, stmf_lu_t
*lu
, void *arg
, uint8_t *buf
,
3661 return (STMF_NOT_SUPPORTED
);
3665 sbd_lu_reset_state(stmf_lu_t
*lu
)
3667 sbd_lu_t
*sl
= (sbd_lu_t
*)lu
->lu_provider_private
;
3669 mutex_enter(&sl
->sl_lock
);
3670 if (sl
->sl_flags
& SL_SAVED_WRITE_CACHE_DISABLE
) {
3671 sl
->sl_flags
|= SL_WRITEBACK_CACHE_DISABLE
;
3672 mutex_exit(&sl
->sl_lock
);
3673 if (sl
->sl_access_state
== SBD_LU_ACTIVE
) {
3674 (void) sbd_wcd_set(1, sl
);
3677 sl
->sl_flags
&= ~SL_WRITEBACK_CACHE_DISABLE
;
3678 mutex_exit(&sl
->sl_lock
);
3679 if (sl
->sl_access_state
== SBD_LU_ACTIVE
) {
3680 (void) sbd_wcd_set(0, sl
);
3684 sbd_check_and_clear_scsi2_reservation(sl
, NULL
);
3685 if (stmf_deregister_all_lu_itl_handles(lu
) != STMF_SUCCESS
) {
3686 return (STMF_FAILURE
);
3688 return (STMF_SUCCESS
);
3692 sbd_flush_data_cache(sbd_lu_t
*sl
, int fsync_done
)
3699 if ((sl
->sl_data_vtype
== VREG
) || (sl
->sl_data_vtype
== VBLK
)) {
3700 if (VOP_FSYNC(sl
->sl_data_vp
, FSYNC
, kcred
, NULL
))
3701 return (SBD_FAILURE
);
3704 if (((sl
->sl_data_vtype
== VCHR
) || (sl
->sl_data_vtype
== VBLK
)) &&
3705 ((sl
->sl_flags
& SL_NO_DATA_DKIOFLUSH
) == 0)) {
3706 ret
= VOP_IOCTL(sl
->sl_data_vp
, DKIOCFLUSHWRITECACHE
, NULL
,
3707 FKIOCTL
, kcred
, &r
, NULL
);
3708 if ((ret
== ENOTTY
) || (ret
== ENOTSUP
)) {
3709 mutex_enter(&sl
->sl_lock
);
3710 sl
->sl_flags
|= SL_NO_DATA_DKIOFLUSH
;
3711 mutex_exit(&sl
->sl_lock
);
3712 } else if (ret
!= 0) {
3713 return (SBD_FAILURE
);
3717 return (SBD_SUCCESS
);
3722 sbd_handle_sync_cache(struct scsi_task
*task
,
3723 struct stmf_data_buf
*initial_dbuf
)
3725 sbd_lu_t
*sl
= (sbd_lu_t
*)task
->task_lu
->lu_provider_private
;
3726 uint64_t lba
, laddr
;
3732 task
->task_cmd_xfer_length
= 0;
3734 * Determine if this is a 10 or 16 byte CDB
3737 if (task
->task_cdb
[0] == SCMD_SYNCHRONIZE_CACHE_G4
)
3741 * Determine other requested parameters
3743 * We don't have a non-volatile cache, so don't care about SYNC_NV.
3744 * Do not support the IMMED bit.
3747 immed
= (task
->task_cdb
[1] & 0x02);
3750 stmf_scsilib_send_status(task
, STATUS_CHECK
,
3751 STMF_SAA_INVALID_FIELD_IN_CDB
);
3756 * Check to be sure we're not being asked to sync an LBA
3757 * that is out of range. While checking, verify reserved fields.
3761 if ((task
->task_cdb
[1] & 0xf9) || task
->task_cdb
[14] ||
3762 task
->task_cdb
[15]) {
3763 stmf_scsilib_send_status(task
, STATUS_CHECK
,
3764 STMF_SAA_INVALID_FIELD_IN_CDB
);
3768 lba
= READ_SCSI64(&task
->task_cdb
[2], uint64_t);
3769 len
= READ_SCSI32(&task
->task_cdb
[10], uint32_t);
3771 if ((task
->task_cdb
[1] & 0xf9) || task
->task_cdb
[6] ||
3772 task
->task_cdb
[9]) {
3773 stmf_scsilib_send_status(task
, STATUS_CHECK
,
3774 STMF_SAA_INVALID_FIELD_IN_CDB
);
3778 lba
= READ_SCSI32(&task
->task_cdb
[2], uint64_t);
3779 len
= READ_SCSI16(&task
->task_cdb
[7], uint32_t);
3782 laddr
= lba
<< sl
->sl_data_blocksize_shift
;
3783 len
<<= sl
->sl_data_blocksize_shift
;
3785 if ((laddr
+ (uint64_t)len
) > sl
->sl_lu_size
) {
3786 stmf_scsilib_send_status(task
, STATUS_CHECK
,
3787 STMF_SAA_LBA_OUT_OF_RANGE
);
3791 sret
= sbd_flush_data_cache(sl
, 0);
3792 if (sret
!= SBD_SUCCESS
) {
3793 stmf_scsilib_send_status(task
, STATUS_CHECK
,
3794 STMF_SAA_WRITE_ERROR
);
3798 stmf_scsilib_send_status(task
, STATUS_GOOD
, 0);