sbd_scsi.c revision b77b9231da168bb31490f65bf2697f6031b7f601
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER START
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The contents of this file are subject to the terms of the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Common Development and Distribution License (the "License").
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You may not use this file except in compliance with the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * See the License for the specific language governing permissions
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * and limitations under the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * When distributing Covered Code, include this CDDL HEADER in each
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If applicable, add the following below this CDDL HEADER, with the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * fields enclosed by brackets "[]" replaced with your own identifying
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * information: Portions Copyright [yyyy] [name of copyright owner]
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER END
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States#include <sys/scsi/generic/mode.h>
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States#include <sys/disp.h>
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States#include <sys/stmf.h>
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States#include <sys/lpif.h>
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States#include <sys/portif.h>
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States#include <sys/stmf_ioctl.h>
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States#define SCSI2_CONFLICT_FREE_CMDS(cdb) ( \
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States /* ----------------------- */ \
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States /* Refer Both */ \
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States /* SPC-2 (rev 20) Table 10 */ \
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States /* SPC-3 (rev 23) Table 31 */ \
1fdeec650620e8498c06f832ea4bd2292f7e9632joyce mcintosh /* ----------------------- */ \
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States ((cdb[0]) == SCMD_LOG_SENSE_G1) || \
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States ((cdb[0]) == SCMD_RELEASE) || \
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States ((cdb[0]) == SCMD_REPORT_LUNS) || \
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* PREVENT ALLOW MEDIUM REMOVAL with prevent == 0 */ \
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas ((((cdb[0]) == SCMD_DOORLOCK) && (((cdb[4]) & 0x3) == 0))) || \
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas /* SERVICE ACTION IN with READ MEDIA SERIAL NUMBER (0x01) */ \
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas /* MAINTENANCE IN with service actions REPORT ALIASES (0x0Bh) */ \
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas /* REPORT DEVICE IDENTIFIER (0x05) REPORT PRIORITY (0x0Eh) */ \
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States /* REPORT TARGET PORT GROUPS (0x0A) REPORT TIMESTAMP (0x0F) */ \
3db3f65c6274eb042354801a308c8e9bc4994553amw /* ----------------------- */ \
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas /* SBC-3 (rev 17) Table 3 */ \
1fdeec650620e8498c06f832ea4bd2292f7e9632joyce mcintosh /* ----------------------- */ \
1fdeec650620e8498c06f832ea4bd2292f7e9632joyce mcintosh /* READ CAPACITY(10) */ \
1fdeec650620e8498c06f832ea4bd2292f7e9632joyce mcintosh /* READ CAPACITY(16) */ \
a4b239dfde5f1d873c730c047e87e5714ebddbb7jose borrego /* START STOP UNIT with START bit 0 and POWER CONDITION 0 */ \
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright (((cdb[4]) & 0xF0) == 0) && (((cdb[4]) & 0x01) == 0))))
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wright/* End of SCSI2_CONFLICT_FREE_CMDS */
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wrightstatic void sbd_handle_sync_cache(struct scsi_task *task,
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wrightvoid sbd_handle_read_xfer_completion(struct scsi_task *task,
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States sbd_cmd_t *scmd, struct stmf_data_buf *dbuf);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statesvoid sbd_handle_short_write_xfer_completion(scsi_task_t *task,
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States stmf_data_buf_t *dbuf);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statesvoid sbd_handle_short_write_transfers(scsi_task_t *task,
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States stmf_data_buf_t *dbuf, uint32_t cdb_xfer_size);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statesvoid sbd_handle_mode_select_xfer(scsi_task_t *task, uint8_t *buf,
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States uint32_t buflen);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statesvoid sbd_handle_mode_select(scsi_task_t *task, stmf_data_buf_t *dbuf);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statesvoid sbd_handle_identifying_info(scsi_task_t *task, stmf_data_buf_t *dbuf);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statesstatic void sbd_handle_unmap_xfer(scsi_task_t *task, uint8_t *buf,
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States uint32_t buflen);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statesstatic void sbd_handle_unmap(scsi_task_t *task, stmf_data_buf_t *dbuf);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statesstatic void sbd_handle_write_same(scsi_task_t *task);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statesextern void sbd_pgr_initialize_it(scsi_task_t *, sbd_it_data_t *);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwextern void sbd_pgr_remove_it_handle(sbd_lu_t *, sbd_it_data_t *);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwextern void sbd_handle_pgr_in_cmd(scsi_task_t *, stmf_data_buf_t *);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwextern void sbd_handle_pgr_out_cmd(scsi_task_t *, stmf_data_buf_t *);
int first_xfer);
int ndx;
int bufs_to_take;
if (iolen == 0)
sbd_max_xfer_len = 0;
sbd_1st_xfer_len = 0;
if (sbd_max_xfer_len)
if (sbd_1st_xfer_len)
first_len = 0;
if (first_len) {
first_len = 0;
final_xfer = 0;
if (final_xfer)
if (ret != 0) {
if (first_xfer)
switch (xstat) {
case STMF_SUCCESS:
case STMF_BUSY:
if (first_xfer)
case STMF_ABORTED:
int scmd_err;
if (!scmd_err) {
int ret;
if (scmd_err) {
ret = 0;
if (scmd_xfer_done)
if (ret != 0) {
if (!scmd_err) {
if (scmd_xfer_done) {
* Similar to the sbd_data_read/write path, except it goes directly through
static stmf_status_t
for (i = 0; i < iovcnt; i++) {
tiov++;
if (resid != 0) {
return (STMF_FAILURE);
if (ret != 0) {
return (STMF_FAILURE);
return (STMF_SUCCESS);
int fast_path;
if (len == 0) {
fast_path = 0;
if (len == 0) {
int ret;
SBD_CMD_SCSI_READ, 0);
if (ret != 0) {
KM_SLEEP);
&minsize, 0);
int bufs_to_take;
goto DO_WRITE_XFER_DONE;
goto DO_WRITE_XFER_DONE;
int ret;
sbd_max_xfer_len = 0;
sbd_1st_xfer_len = 0;
if (sbd_max_xfer_len)
if (sbd_1st_xfer_len)
first_len = 0;
if (first_len) {
first_len = 0;
if (ret != 0) {
if (first_xfer)
switch (xstat) {
case STMF_SUCCESS:
case STMF_BUSY:
if (first_xfer)
case STMF_ABORTED:
int ndx;
goto WRITE_XFER_DONE;
int commit;
if (iolen == 0)
if (sbd_copy_threshold > 0) {
if (len == 0) {
if (len == 0) {
KM_SLEEP);
if (do_immediate_data) {
if (cmd_xfer_size == 0) {
uint8_t *d;
uint32_t s;
bufsize += s;
if (cdb_xfer_size == 0) {
KM_SLEEP);
case SCMD_MODE_SELECT:
case SCMD_MODE_SELECT_G1:
case SCMD_UNMAP:
uint64_t s;
case SCMD_READ_CAPACITY:
case SCMD_SVC_ACTION_IN_G4:
uint8_t *p;
pc_valid = 0;
n += header_size;
switch (ctrl) {
SL_WRITEBACK_CACHE_SET_UNSUPPORTED) == 0) {
SL_SAVED_WRITE_CACHE_DISABLE) == 0) {
n += (sizeof (struct mode_page) +
n += (sizeof (struct mode_page) +
cmd_size, n);
if (cmd_xfer_len == 0) {
goto mode_sel_param_len_err;
goto mode_sel_param_len_err;
goto mode_sel_param_len_err;
goto mode_sel_param_field_err;
if (buf[i]) {
goto mode_sel_param_field_err;
switch (info_type) {
char *url;
(*url_addr)++;
url++;
url_length++;
return (url_length);
uint8_t *p;
if (cmd_xfer_len == 0) {
uint8_t *p;
int ret;
(num_desc == 0)) {
if (ret != 0) {
uint8_t *p;
uint64_t s;
if (cmd_size == 0) {
case PROTOCOL_FIBRE_CHANNEL:
case PROTOCOL_PARALLEL_SCSI:
case PROTOCOL_SSA:
case PROTOCOL_IEEE_1394:
case PROTOCOL_SRP:
case PROTOCOL_iSCSI:
case PROTOCOL_SAS:
case PROTOCOL_ADT:
case PROTOCOL_ATAPI:
} else if (sbd_mgmt_url) {
p[0] = byte0;
if (mgmt_url_size != 0)
p[0] = byte0;
if (mgmt_url_size == 0) {
goto err_done;
char *url;
p[0] = byte0;
while (url_size != 0) {
p[0] = byte0;
goto err_done;
p[0] = byte0;
goto err_done;
p[0] = byte0;
exp++;
goto err_done;
return (STMF_SUCCESS);
return (STMF_ALLOC_FAILURE);
!= STMF_SUCCESS) {
if (saa) {
saa = 0;
saa = 0;
if (saa) {
switch (cdb0) {
case SCMD_MODE_SELECT:
case SCMD_MODE_SELECT_G1:
if (cdb1) {
if (cdb1) {
uint8_t *p;
case (SBD_CMD_SCSI_READ):
case (SBD_CMD_SCSI_WRITE):
(void *)task);
case (SBD_CMD_SCSI_READ):
case (SBD_CMD_SCSI_WRITE):
case (SBD_CMD_SMALL_READ):
case (SBD_CMD_SMALL_WRITE):
(void *)task);
* Aborts are synchronus w.r.t. I/O AND
return (STMF_SUCCESS);
return (STMF_ABORT_SUCCESS);
return (STMF_NOT_FOUND);
switch (cmd) {
case STMF_CMD_LU_ONLINE:
case STMF_CMD_LU_OFFLINE:
return (STMF_NOT_SUPPORTED);
return (STMF_FAILURE);
return (STMF_SUCCESS);
int ret;
if (fsync_done)
goto over_fsync;
return (SBD_FAILURE);
} else if (ret != 0) {
return (SBD_FAILURE);
return (SBD_SUCCESS);
int is_g4 = 0;
int immed;
if (immed) {
if (is_g4) {