1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  24  * Copyright (c) 2013 by Delphix. All rights reserved.
  25  */
  26 
  27 #include <sys/conf.h>
  28 #include <sys/file.h>
  29 #include <sys/ddi.h>
  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>
  35 #include <sys/disp.h>
  36 #include <sys/byteorder.h>
  37 #include <sys/atomic.h>
  38 #include <sys/sdt.h>
  39 #include <sys/dkio.h>
  40 
  41 #include <sys/stmf.h>
  42 #include <sys/lpif.h>
  43 #include <sys/portif.h>
  44 #include <sys/stmf_ioctl.h>
  45 #include <sys/stmf_sbd_ioctl.h>
  46 
  47 #include "stmf_sbd.h"
  48 #include "sbd_impl.h"
  49 
  50 #define SCSI2_CONFLICT_FREE_CMDS(cdb)   ( \
  51         /* ----------------------- */                                      \
  52         /* Refer Both              */                                      \
  53         /* SPC-2 (rev 20) Table 10 */                                      \
  54         /* SPC-3 (rev 23) Table 31 */                                      \
  55         /* ----------------------- */                                      \
  56         ((cdb[0]) == SCMD_INQUIRY)                                      || \
  57         ((cdb[0]) == SCMD_LOG_SENSE_G1)                                 || \
  58         ((cdb[0]) == SCMD_RELEASE)                                      || \
  59         ((cdb[0]) == SCMD_RELEASE_G1)                                   || \
  60         ((cdb[0]) == SCMD_REPORT_LUNS)                                  || \
  61         ((cdb[0]) == SCMD_REQUEST_SENSE)                                || \
  62         /* PREVENT ALLOW MEDIUM REMOVAL with prevent == 0 */               \
  63         ((((cdb[0]) == SCMD_DOORLOCK) && (((cdb[4]) & 0x3) == 0)))  || \
  64         /* SERVICE ACTION IN with READ MEDIA SERIAL NUMBER (0x01) */       \
  65         (((cdb[0]) == SCMD_SVC_ACTION_IN_G5) && (                          \
  66             ((cdb[1]) & 0x1F) == 0x01))                                     || \
  67         /* MAINTENANCE IN with service actions REPORT ALIASES (0x0Bh) */   \
  68         /* REPORT DEVICE IDENTIFIER (0x05)  REPORT PRIORITY (0x0Eh) */     \
  69         /* REPORT TARGET PORT GROUPS (0x0A) REPORT TIMESTAMP (0x0F) */     \
  70         (((cdb[0]) == SCMD_MAINTENANCE_IN) && (                            \
  71             (((cdb[1]) & 0x1F) == 0x0B) ||                                 \
  72             (((cdb[1]) & 0x1F) == 0x05) ||                                 \
  73             (((cdb[1]) & 0x1F) == 0x0E) ||                                 \
  74             (((cdb[1]) & 0x1F) == 0x0A) ||                                 \
  75             (((cdb[1]) & 0x1F) == 0x0F)))                           || \
  76         /* ----------------------- */                                      \
  77         /* SBC-3 (rev 17) Table 3  */                                      \
  78         /* ----------------------- */                                      \
  79         /* READ CAPACITY(10) */                                            \
  80         ((cdb[0]) == SCMD_READ_CAPACITY)                                || \
  81         /* READ CAPACITY(16) */                                            \
  82         (((cdb[0]) == SCMD_SVC_ACTION_IN_G4) && (                          \
  83             ((cdb[1]) & 0x1F) == 0x10))                                     || \
  84         /* START STOP UNIT with START bit 0 and POWER CONDITION 0  */      \
  85         (((cdb[0]) == SCMD_START_STOP) && (                                \
  86             (((cdb[4]) & 0xF0) == 0) && (((cdb[4]) & 0x01) == 0))))
  87 /* End of SCSI2_CONFLICT_FREE_CMDS */
  88 
  89 stmf_status_t sbd_lu_reset_state(stmf_lu_t *lu);
  90 static void sbd_handle_sync_cache(struct scsi_task *task,
  91     struct stmf_data_buf *initial_dbuf);
  92 void sbd_handle_read_xfer_completion(struct scsi_task *task,
  93     sbd_cmd_t *scmd, struct stmf_data_buf *dbuf);
  94 void sbd_handle_short_write_xfer_completion(scsi_task_t *task,
  95     stmf_data_buf_t *dbuf);
  96 void sbd_handle_short_write_transfers(scsi_task_t *task,
  97     stmf_data_buf_t *dbuf, uint32_t cdb_xfer_size);
  98 void sbd_handle_mode_select_xfer(scsi_task_t *task, uint8_t *buf,
  99     uint32_t buflen);
 100 void sbd_handle_mode_select(scsi_task_t *task, stmf_data_buf_t *dbuf);
 101 void sbd_handle_identifying_info(scsi_task_t *task, stmf_data_buf_t *dbuf);
 102 
 103 static void sbd_handle_unmap_xfer(scsi_task_t *task, uint8_t *buf,
 104     uint32_t buflen);
 105 static void sbd_handle_unmap(scsi_task_t *task, stmf_data_buf_t *dbuf);
 106 
 107 extern void sbd_pgr_initialize_it(scsi_task_t *, sbd_it_data_t *);
 108 extern int sbd_pgr_reservation_conflict(scsi_task_t *);
 109 extern void sbd_pgr_reset(sbd_lu_t *);
 110 extern void sbd_pgr_remove_it_handle(sbd_lu_t *, sbd_it_data_t *);
 111 extern void sbd_handle_pgr_in_cmd(scsi_task_t *, stmf_data_buf_t *);
 112 extern void sbd_handle_pgr_out_cmd(scsi_task_t *, stmf_data_buf_t *);
 113 extern void sbd_handle_pgr_out_data(scsi_task_t *, stmf_data_buf_t *);
 114 void sbd_do_sgl_write_xfer(struct scsi_task *task, sbd_cmd_t *scmd,
 115     int first_xfer);
 116 static void sbd_handle_write_same(scsi_task_t *task,
 117     struct stmf_data_buf *initial_dbuf);
 118 static void sbd_do_write_same_xfer(struct scsi_task *task, sbd_cmd_t *scmd,
 119     struct stmf_data_buf *dbuf, uint8_t dbuf_reusable);
 120 static void sbd_handle_write_same_xfer_completion(struct scsi_task *task,
 121     sbd_cmd_t *scmd, struct stmf_data_buf *dbuf, uint8_t dbuf_reusable);
 122 /*
 123  * IMPORTANT NOTE:
 124  * =================
 125  * The whole world here is based on the assumption that everything within
 126  * a scsi task executes in a single threaded manner, even the aborts.
 127  * Dont ever change that. There wont be any performance gain but there
 128  * will be tons of race conditions.
 129  */
 130 
 131 void
 132 sbd_do_read_xfer(struct scsi_task *task, sbd_cmd_t *scmd,
 133                                         struct stmf_data_buf *dbuf)
 134 {
 135         sbd_lu_t *sl = (sbd_lu_t *)task->task_lu->lu_provider_private;
 136         uint64_t laddr;
 137         uint32_t len, buflen, iolen;
 138         int ndx;
 139         int bufs_to_take;
 140 
 141         /* Lets try not to hog all the buffers the port has. */
 142         bufs_to_take = ((task->task_max_nbufs > 2) &&
 143             (task->task_cmd_xfer_length < (32 * 1024))) ? 2 :
 144             task->task_max_nbufs;
 145 
 146         len = scmd->len > dbuf->db_buf_size ? dbuf->db_buf_size : scmd->len;
 147         laddr = scmd->addr + scmd->current_ro;
 148 
 149         for (buflen = 0, ndx = 0; (buflen < len) &&
 150             (ndx < dbuf->db_sglist_length); ndx++) {
 151                 iolen = min(len - buflen, dbuf->db_sglist[ndx].seg_length);
 152                 if (iolen == 0)
 153                         break;
 154                 if (sbd_data_read(sl, task, laddr, (uint64_t)iolen,
 155                     dbuf->db_sglist[ndx].seg_addr) != STMF_SUCCESS) {
 156                         scmd->flags |= SBD_SCSI_CMD_XFER_FAIL;
 157                         /* Do not need to do xfer anymore, just complete it */
 158                         dbuf->db_data_size = 0;
 159                         dbuf->db_xfer_status = STMF_SUCCESS;
 160                         sbd_handle_read_xfer_completion(task, scmd, dbuf);
 161                         return;
 162                 }
 163                 buflen += iolen;
 164                 laddr += (uint64_t)iolen;
 165         }
 166         dbuf->db_relative_offset = scmd->current_ro;
 167         dbuf->db_data_size = buflen;
 168         dbuf->db_flags = DB_DIRECTION_TO_RPORT;
 169         (void) stmf_xfer_data(task, dbuf, 0);
 170         scmd->len -= buflen;
 171         scmd->current_ro += buflen;
 172         if (scmd->len && (scmd->nbufs < bufs_to_take)) {
 173                 uint32_t maxsize, minsize, old_minsize;
 174 
 175                 maxsize = (scmd->len > (128*1024)) ? 128*1024 : scmd->len;
 176                 minsize = maxsize >> 2;
 177                 do {
 178                         /*
 179                          * A bad port implementation can keep on failing the
 180                          * the request but keep on sending us a false
 181                          * minsize.
 182                          */
 183                         old_minsize = minsize;
 184                         dbuf = stmf_alloc_dbuf(task, maxsize, &minsize, 0);
 185                 } while ((dbuf == NULL) && (old_minsize > minsize) &&
 186                     (minsize >= 512));
 187                 if (dbuf == NULL) {
 188                         return;
 189                 }
 190                 scmd->nbufs++;
 191                 sbd_do_read_xfer(task, scmd, dbuf);
 192         }
 193 }
 194 
 195 /*
 196  * sbd_zcopy: Bail-out switch for reduced copy path.
 197  *
 198  * 0 - read & write off
 199  * 1 - read & write on
 200  * 2 - only read on
 201  * 4 - only write on
 202  */
 203 int sbd_zcopy = 1;      /* enable zcopy read & write path */
 204 uint32_t sbd_max_xfer_len = 0;          /* Valid if non-zero */
 205 uint32_t sbd_1st_xfer_len = 0;          /* Valid if non-zero */
 206 uint32_t sbd_copy_threshold = 0;                /* Valid if non-zero */
 207 
 208 static void
 209 sbd_do_sgl_read_xfer(struct scsi_task *task, sbd_cmd_t *scmd, int first_xfer)
 210 {
 211         sbd_lu_t *sl = (sbd_lu_t *)task->task_lu->lu_provider_private;
 212         sbd_zvol_io_t *zvio;
 213         int ret, final_xfer;
 214         uint64_t offset;
 215         uint32_t xfer_len, max_len, first_len;
 216         stmf_status_t xstat;
 217         stmf_data_buf_t *dbuf;
 218         uint_t nblks;
 219         uint64_t blksize = sl->sl_blksize;
 220         size_t db_private_sz;
 221         uintptr_t pad;
 222 
 223         ASSERT(rw_read_held(&sl->sl_access_state_lock));
 224         ASSERT((sl->sl_flags & SL_MEDIA_LOADED) != 0);
 225 
 226         /*
 227          * Calculate the limits on xfer_len to the minimum of :
 228          *    - task limit
 229          *    - lun limit
 230          *    - sbd global limit if set
 231          *    - first xfer limit if set
 232          *
 233          * First, protect against silly over-ride value
 234          */
 235         if (sbd_max_xfer_len && ((sbd_max_xfer_len % DEV_BSIZE) != 0)) {
 236                 cmn_err(CE_WARN, "sbd_max_xfer_len invalid %d, resetting\n",
 237                     sbd_max_xfer_len);
 238                 sbd_max_xfer_len = 0;
 239         }
 240         if (sbd_1st_xfer_len && ((sbd_1st_xfer_len % DEV_BSIZE) != 0)) {
 241                 cmn_err(CE_WARN, "sbd_1st_xfer_len invalid %d, resetting\n",
 242                     sbd_1st_xfer_len);
 243                 sbd_1st_xfer_len = 0;
 244         }
 245 
 246         max_len = MIN(task->task_max_xfer_len, sl->sl_max_xfer_len);
 247         if (sbd_max_xfer_len)
 248                 max_len = MIN(max_len, sbd_max_xfer_len);
 249         /*
 250          * Special case the first xfer if hints are set.
 251          */
 252         if (first_xfer && (sbd_1st_xfer_len || task->task_1st_xfer_len)) {
 253                 /* global over-ride has precedence */
 254                 if (sbd_1st_xfer_len)
 255                         first_len = sbd_1st_xfer_len;
 256                 else
 257                         first_len = task->task_1st_xfer_len;
 258         } else {
 259                 first_len = 0;
 260         }
 261 
 262         while (scmd->len && scmd->nbufs < task->task_max_nbufs) {
 263 
 264                 xfer_len = MIN(max_len, scmd->len);
 265                 if (first_len) {
 266                         xfer_len = MIN(xfer_len, first_len);
 267                         first_len = 0;
 268                 }
 269                 if (scmd->len == xfer_len) {
 270                         final_xfer = 1;
 271                 } else {
 272                         /*
 273                          * Attempt to end xfer on a block boundary.
 274                          * The only way this does not happen is if the
 275                          * xfer_len is small enough to stay contained
 276                          * within the same block.
 277                          */
 278                         uint64_t xfer_offset, xfer_aligned_end;
 279 
 280                         final_xfer = 0;
 281                         xfer_offset = scmd->addr + scmd->current_ro;
 282                         xfer_aligned_end =
 283                             P2ALIGN(xfer_offset+xfer_len, blksize);
 284                         if (xfer_aligned_end > xfer_offset)
 285                                 xfer_len = xfer_aligned_end - xfer_offset;
 286                 }
 287                 /*
 288                  * Allocate object to track the read and reserve
 289                  * enough space for scatter/gather list.
 290                  */
 291                 offset = scmd->addr + scmd->current_ro;
 292                 nblks = sbd_zvol_numsegs(sl, offset, xfer_len);
 293 
 294                 db_private_sz = sizeof (*zvio) + sizeof (uintptr_t) /* PAD */ +
 295                     (nblks * sizeof (stmf_sglist_ent_t));
 296                 dbuf = stmf_alloc(STMF_STRUCT_DATA_BUF, db_private_sz,
 297                     AF_DONTZERO);
 298                 /*
 299                  * Setup the dbuf
 300                  *
 301                  * XXX Framework does not handle variable length sglists
 302                  * properly, so setup db_lu_private and db_port_private
 303                  * fields here. db_stmf_private is properly set for
 304                  * calls to stmf_free.
 305                  */
 306                 if (dbuf->db_port_private == NULL) {
 307                         /*
 308                          * XXX Framework assigns space to PP after db_sglist[0]
 309                          */
 310                         cmn_err(CE_PANIC, "db_port_private == NULL");
 311                 }
 312                 pad = (uintptr_t)&dbuf->db_sglist[nblks];
 313                 dbuf->db_lu_private = (void *)P2ROUNDUP(pad, sizeof (pad));
 314                 dbuf->db_port_private = NULL;
 315                 dbuf->db_buf_size = xfer_len;
 316                 dbuf->db_data_size = xfer_len;
 317                 dbuf->db_relative_offset = scmd->current_ro;
 318                 dbuf->db_sglist_length = (uint16_t)nblks;
 319                 dbuf->db_xfer_status = 0;
 320                 dbuf->db_handle = 0;
 321 
 322                 dbuf->db_flags = (DB_DONT_CACHE | DB_DONT_REUSE |
 323                     DB_DIRECTION_TO_RPORT | DB_LU_DATA_BUF);
 324                 if (final_xfer)
 325                         dbuf->db_flags |= DB_SEND_STATUS_GOOD;
 326 
 327                 zvio = dbuf->db_lu_private;
 328                 /* Need absolute offset for zvol access */
 329                 zvio->zvio_offset = offset;
 330                 zvio->zvio_flags = ZVIO_SYNC;
 331 
 332                 /*
 333                  * Accounting for start of read.
 334                  * Note there is no buffer address for the probe yet.
 335                  */
 336                 DTRACE_PROBE5(backing__store__read__start, sbd_lu_t *, sl,
 337                     uint8_t *, NULL, uint64_t, xfer_len,
 338                     uint64_t, offset, scsi_task_t *, task);
 339 
 340                 ret = sbd_zvol_alloc_read_bufs(sl, dbuf);
 341 
 342                 DTRACE_PROBE6(backing__store__read__end, sbd_lu_t *, sl,
 343                     uint8_t *, NULL, uint64_t, xfer_len,
 344                     uint64_t, offset, int, ret, scsi_task_t *, task);
 345 
 346                 if (ret != 0) {
 347                         /*
 348                          * Read failure from the backend.
 349                          */
 350                         stmf_free(dbuf);
 351                         if (scmd->nbufs == 0) {
 352                                 /* nothing queued, just finish */
 353                                 scmd->flags &= ~SBD_SCSI_CMD_ACTIVE;
 354                                 stmf_scsilib_send_status(task, STATUS_CHECK,
 355                                     STMF_SAA_READ_ERROR);
 356                                 rw_exit(&sl->sl_access_state_lock);
 357                         } else {
 358                                 /* process failure when other dbufs finish */
 359                                 scmd->flags |= SBD_SCSI_CMD_XFER_FAIL;
 360                         }
 361                         return;
 362                 }
 363 
 364 
 365                 /*
 366                  * Allow PP to do setup
 367                  */
 368                 xstat = stmf_setup_dbuf(task, dbuf, 0);
 369                 if (xstat != STMF_SUCCESS) {
 370                         /*
 371                          * This could happen if the driver cannot get the
 372                          * DDI resources it needs for this request.
 373                          * If other dbufs are queued, try again when the next
 374                          * one completes, otherwise give up.
 375                          */
 376                         sbd_zvol_rele_read_bufs(sl, dbuf);
 377                         stmf_free(dbuf);
 378                         if (scmd->nbufs > 0) {
 379                                 /* completion of previous dbuf will retry */
 380                                 return;
 381                         }
 382                         /*
 383                          * Done with this command.
 384                          */
 385                         scmd->flags &= ~SBD_SCSI_CMD_ACTIVE;
 386                         if (first_xfer)
 387                                 stmf_scsilib_send_status(task, STATUS_QFULL, 0);
 388                         else
 389                                 stmf_scsilib_send_status(task, STATUS_CHECK,
 390                                     STMF_SAA_READ_ERROR);
 391                         rw_exit(&sl->sl_access_state_lock);
 392                         return;
 393                 }
 394                 /*
 395                  * dbuf is now queued on task
 396                  */
 397                 scmd->nbufs++;
 398 
 399                 /* XXX leave this in for FW? */
 400                 DTRACE_PROBE4(sbd__xfer, struct scsi_task *, task,
 401                     struct stmf_data_buf *, dbuf, uint64_t, offset,
 402                     uint32_t, xfer_len);
 403                 /*
 404                  * Do not pass STMF_IOF_LU_DONE so that the zvol
 405                  * state can be released in the completion callback.
 406                  */
 407                 xstat = stmf_xfer_data(task, dbuf, 0);
 408                 switch (xstat) {
 409                 case STMF_SUCCESS:
 410                         break;
 411                 case STMF_BUSY:
 412                         /*
 413                          * The dbuf is queued on the task, but unknown
 414                          * to the PP, thus no completion will occur.
 415                          */
 416                         sbd_zvol_rele_read_bufs(sl, dbuf);
 417                         stmf_teardown_dbuf(task, dbuf);
 418                         stmf_free(dbuf);
 419                         scmd->nbufs--;
 420                         if (scmd->nbufs > 0) {
 421                                 /* completion of previous dbuf will retry */
 422                                 return;
 423                         }
 424                         /*
 425                          * Done with this command.
 426                          */
 427                         rw_exit(&sl->sl_access_state_lock);
 428                         scmd->flags &= ~SBD_SCSI_CMD_ACTIVE;
 429                         if (first_xfer)
 430                                 stmf_scsilib_send_status(task, STATUS_QFULL, 0);
 431                         else
 432                                 stmf_scsilib_send_status(task, STATUS_CHECK,
 433                                     STMF_SAA_READ_ERROR);
 434                         return;
 435                 case STMF_ABORTED:
 436                         /*
 437                          * Completion from task_done will cleanup
 438                          */
 439                         scmd->flags &= ~SBD_SCSI_CMD_ACTIVE;
 440                         return;
 441                 }
 442                 /*
 443                  * Update the xfer progress.
 444                  */
 445                 ASSERT(scmd->len >= xfer_len);
 446                 scmd->len -= xfer_len;
 447                 scmd->current_ro += xfer_len;
 448         }
 449 }
 450 
 451 void
 452 sbd_handle_read_xfer_completion(struct scsi_task *task, sbd_cmd_t *scmd,
 453                                 struct stmf_data_buf *dbuf)
 454 {
 455         if (dbuf->db_xfer_status != STMF_SUCCESS) {
 456                 stmf_abort(STMF_QUEUE_TASK_ABORT, task,
 457                     dbuf->db_xfer_status, NULL);
 458                 return;
 459         }
 460         task->task_nbytes_transferred += dbuf->db_data_size;
 461         if (scmd->len == 0 || scmd->flags & SBD_SCSI_CMD_XFER_FAIL) {
 462                 stmf_free_dbuf(task, dbuf);
 463                 scmd->nbufs--;
 464                 if (scmd->nbufs)
 465                         return; /* wait for all buffers to complete */
 466                 scmd->flags &= ~SBD_SCSI_CMD_ACTIVE;
 467                 if (scmd->flags & SBD_SCSI_CMD_XFER_FAIL)
 468                         stmf_scsilib_send_status(task, STATUS_CHECK,
 469                             STMF_SAA_READ_ERROR);
 470                 else
 471                         stmf_scsilib_send_status(task, STATUS_GOOD, 0);
 472                 return;
 473         }
 474         if (dbuf->db_flags & DB_DONT_REUSE) {
 475                 /* allocate new dbuf */
 476                 uint32_t maxsize, minsize, old_minsize;
 477                 stmf_free_dbuf(task, dbuf);
 478 
 479                 maxsize = (scmd->len > (128*1024)) ? 128*1024 : scmd->len;
 480                 minsize = maxsize >> 2;
 481                 do {
 482                         old_minsize = minsize;
 483                         dbuf = stmf_alloc_dbuf(task, maxsize, &minsize, 0);
 484                 } while ((dbuf == NULL) && (old_minsize > minsize) &&
 485                     (minsize >= 512));
 486                 if (dbuf == NULL) {
 487                         scmd->nbufs --;
 488                         if (scmd->nbufs == 0) {
 489                                 stmf_abort(STMF_QUEUE_TASK_ABORT, task,
 490                                     STMF_ALLOC_FAILURE, NULL);
 491                         }
 492                         return;
 493                 }
 494         }
 495         sbd_do_read_xfer(task, scmd, dbuf);
 496 }
 497 
 498 /*
 499  * This routine must release the DMU resources and free the dbuf
 500  * in all cases.  If this is the final dbuf of the task, then drop
 501  * the reader lock on the LU state. If there are no errors and more
 502  * work to do, then queue more xfer operations.
 503  */
 504 void
 505 sbd_handle_sgl_read_xfer_completion(struct scsi_task *task, sbd_cmd_t *scmd,
 506                                 struct stmf_data_buf *dbuf)
 507 {
 508         sbd_lu_t *sl = (sbd_lu_t *)task->task_lu->lu_provider_private;
 509         stmf_status_t xfer_status;
 510         uint32_t data_size;
 511         int scmd_err;
 512 
 513         ASSERT(dbuf->db_lu_private);
 514         ASSERT(scmd->cmd_type == SBD_CMD_SCSI_READ);
 515 
 516         scmd->nbufs--;       /* account for this dbuf */
 517         /*
 518          * Release the DMU resources.
 519          */
 520         sbd_zvol_rele_read_bufs(sl, dbuf);
 521         /*
 522          * Release the dbuf after retrieving needed fields.
 523          */
 524         xfer_status = dbuf->db_xfer_status;
 525         data_size = dbuf->db_data_size;
 526         stmf_teardown_dbuf(task, dbuf);
 527         stmf_free(dbuf);
 528         /*
 529          * Release the state lock if this is the last completion.
 530          * If this is the last dbuf on task and all data has been
 531          * transferred or an error encountered, then no more dbufs
 532          * will be queued.
 533          */
 534         scmd_err = (((scmd->flags & SBD_SCSI_CMD_ACTIVE) == 0) ||
 535             (scmd->flags & SBD_SCSI_CMD_XFER_FAIL) ||
 536             (xfer_status != STMF_SUCCESS));
 537         if (scmd->nbufs == 0 && (scmd->len == 0 || scmd_err)) {
 538                 /* all DMU state has been released */
 539                 rw_exit(&sl->sl_access_state_lock);
 540         }
 541 
 542         /*
 543          * If there have been no errors, either complete the task
 544          * or issue more data xfer operations.
 545          */
 546         if (!scmd_err) {
 547                 /*
 548                  * This chunk completed successfully
 549                  */
 550                 task->task_nbytes_transferred += data_size;
 551                 if (scmd->nbufs == 0 && scmd->len == 0) {
 552                         /*
 553                          * This command completed successfully
 554                          *
 555                          * Status was sent along with data, so no status
 556                          * completion will occur. Tell stmf we are done.
 557                          */
 558                         scmd->flags &= ~SBD_SCSI_CMD_ACTIVE;
 559                         stmf_task_lu_done(task);
 560                         return;
 561                 }
 562                 /*
 563                  * Start more xfers
 564                  */
 565                 sbd_do_sgl_read_xfer(task, scmd, 0);
 566                 return;
 567         }
 568         /*
 569          * Sort out the failure
 570          */
 571         if (scmd->flags & SBD_SCSI_CMD_ACTIVE) {
 572                 /*
 573                  * If a previous error occurred, leave the command active
 574                  * and wait for the last completion to send the status check.
 575                  */
 576                 if (scmd->flags & SBD_SCSI_CMD_XFER_FAIL) {
 577                         if (scmd->nbufs == 0) {
 578                                 scmd->flags &= ~SBD_SCSI_CMD_ACTIVE;
 579                                 stmf_scsilib_send_status(task, STATUS_CHECK,
 580                                     STMF_SAA_READ_ERROR);
 581                         }
 582                         return;
 583                 }
 584                 /*
 585                  * Must have been a failure on current dbuf
 586                  */
 587                 ASSERT(xfer_status != STMF_SUCCESS);
 588                 scmd->flags &= ~SBD_SCSI_CMD_ACTIVE;
 589                 stmf_abort(STMF_QUEUE_TASK_ABORT, task, xfer_status, NULL);
 590         }
 591 }
 592 
 593 void
 594 sbd_handle_sgl_write_xfer_completion(struct scsi_task *task, sbd_cmd_t *scmd,
 595                                 struct stmf_data_buf *dbuf)
 596 {
 597         sbd_zvol_io_t *zvio = dbuf->db_lu_private;
 598         sbd_lu_t *sl = (sbd_lu_t *)task->task_lu->lu_provider_private;
 599         int ret;
 600         int scmd_err, scmd_xfer_done;
 601         stmf_status_t xfer_status = dbuf->db_xfer_status;
 602         uint32_t data_size = dbuf->db_data_size;
 603 
 604         ASSERT(zvio);
 605 
 606         /*
 607          * Allow PP to free up resources before releasing the write bufs
 608          * as writing to the backend could take some time.
 609          */
 610         stmf_teardown_dbuf(task, dbuf);
 611 
 612         scmd->nbufs--;       /* account for this dbuf */
 613         /*
 614          * All data was queued and this is the last completion,
 615          * but there could still be an error.
 616          */
 617         scmd_xfer_done = (scmd->len == 0 && scmd->nbufs == 0);
 618         scmd_err = (((scmd->flags & SBD_SCSI_CMD_ACTIVE) == 0) ||
 619             (scmd->flags & SBD_SCSI_CMD_XFER_FAIL) ||
 620             (xfer_status != STMF_SUCCESS));
 621 
 622         DTRACE_PROBE5(backing__store__write__start, sbd_lu_t *, sl,
 623             uint8_t *, NULL, uint64_t, data_size,
 624             uint64_t, zvio->zvio_offset, scsi_task_t *, task);
 625 
 626         if (scmd_err) {
 627                 /* just return the write buffers */
 628                 sbd_zvol_rele_write_bufs_abort(sl, dbuf);
 629                 ret = 0;
 630         } else {
 631                 if (scmd_xfer_done)
 632                         zvio->zvio_flags = ZVIO_COMMIT;
 633                 else
 634                         zvio->zvio_flags = 0;
 635                 /* write the data */
 636                 ret = sbd_zvol_rele_write_bufs(sl, dbuf);
 637         }
 638 
 639         DTRACE_PROBE6(backing__store__write__end, sbd_lu_t *, sl,
 640             uint8_t *, NULL, uint64_t, data_size,
 641             uint64_t, zvio->zvio_offset, int, ret,  scsi_task_t *, task);
 642 
 643         if (ret != 0) {
 644                 /* update the error flag */
 645                 scmd->flags |= SBD_SCSI_CMD_XFER_FAIL;
 646                 scmd_err = 1;
 647         }
 648 
 649         /* Release the dbuf */
 650         stmf_free(dbuf);
 651 
 652         /*
 653          * Release the state lock if this is the last completion.
 654          * If this is the last dbuf on task and all data has been
 655          * transferred or an error encountered, then no more dbufs
 656          * will be queued.
 657          */
 658         if (scmd->nbufs == 0 && (scmd->len == 0 || scmd_err)) {
 659                 /* all DMU state has been released */
 660                 rw_exit(&sl->sl_access_state_lock);
 661         }
 662         /*
 663          * If there have been no errors, either complete the task
 664          * or issue more data xfer operations.
 665          */
 666         if (!scmd_err) {
 667                 /* This chunk completed successfully */
 668                 task->task_nbytes_transferred += data_size;
 669                 if (scmd_xfer_done) {
 670                         /* This command completed successfully */
 671                         scmd->flags &= ~SBD_SCSI_CMD_ACTIVE;
 672                         if ((scmd->flags & SBD_SCSI_CMD_SYNC_WRITE) &&
 673                             (sbd_flush_data_cache(sl, 0) != SBD_SUCCESS)) {
 674                                 stmf_scsilib_send_status(task, STATUS_CHECK,
 675                                     STMF_SAA_WRITE_ERROR);
 676                         } else {
 677                                 stmf_scsilib_send_status(task, STATUS_GOOD, 0);
 678                         }
 679                         return;
 680                 }
 681                 /*
 682                  * Start more xfers
 683                  */
 684                 sbd_do_sgl_write_xfer(task, scmd, 0);
 685                 return;
 686         }
 687         /*
 688          * Sort out the failure
 689          */
 690         if (scmd->flags & SBD_SCSI_CMD_ACTIVE) {
 691                 if (scmd->flags & SBD_SCSI_CMD_XFER_FAIL) {
 692                         if (scmd->nbufs == 0) {
 693                                 scmd->flags &= ~SBD_SCSI_CMD_ACTIVE;
 694                                 stmf_scsilib_send_status(task, STATUS_CHECK,
 695                                     STMF_SAA_WRITE_ERROR);
 696                         }
 697                         /*
 698                          * Leave the command active until last dbuf completes.
 699                          */
 700                         return;
 701                 }
 702                 scmd->flags &= ~SBD_SCSI_CMD_ACTIVE;
 703                 ASSERT(xfer_status != STMF_SUCCESS);
 704                 stmf_abort(STMF_QUEUE_TASK_ABORT, task, xfer_status, NULL);
 705         }
 706 }
 707 
 708 /*
 709  * Handle a copy operation using the zvol interface.
 710  *
 711  * Similar to the sbd_data_read/write path, except it goes directly through
 712  * the zvol interfaces. It can pass a port provider sglist in the
 713  * form of uio which is lost through the vn_rdwr path.
 714  *
 715  * Returns:
 716  *      STMF_SUCCESS - request handled
 717  *      STMF_FAILURE - request not handled, caller must deal with error
 718  */
 719 static stmf_status_t
 720 sbd_copy_rdwr(scsi_task_t *task, uint64_t laddr, stmf_data_buf_t *dbuf,
 721     int cmd, int commit)
 722 {
 723         sbd_lu_t                *sl = task->task_lu->lu_provider_private;
 724         struct uio              uio;
 725         struct iovec            *iov, *tiov, iov1[8];
 726         uint32_t                len, resid;
 727         int                     ret, i, iovcnt, flags;
 728         boolean_t               is_read;
 729 
 730         ASSERT(cmd == SBD_CMD_SCSI_READ || cmd == SBD_CMD_SCSI_WRITE);
 731 
 732         is_read = (cmd == SBD_CMD_SCSI_READ) ? B_TRUE : B_FALSE;
 733         iovcnt = dbuf->db_sglist_length;
 734         /* use the stack for small iovecs */
 735         if (iovcnt > 8) {
 736                 iov = kmem_alloc(iovcnt * sizeof (*iov), KM_SLEEP);
 737         } else {
 738                 iov = &iov1[0];
 739         }
 740 
 741         /* Convert dbuf sglist to iovec format */
 742         len = dbuf->db_data_size;
 743         resid = len;
 744         tiov = iov;
 745         for (i = 0; i < iovcnt; i++) {
 746                 tiov->iov_base = (caddr_t)dbuf->db_sglist[i].seg_addr;
 747                 tiov->iov_len = MIN(resid, dbuf->db_sglist[i].seg_length);
 748                 resid -= tiov->iov_len;
 749                 tiov++;
 750         }
 751         if (resid != 0) {
 752                 cmn_err(CE_WARN, "inconsistant sglist rem %d", resid);
 753                 if (iov != &iov1[0])
 754                         kmem_free(iov, iovcnt * sizeof (*iov));
 755                 return (STMF_FAILURE);
 756         }
 757         /* Setup the uio struct */
 758         uio.uio_iov = iov;
 759         uio.uio_iovcnt = iovcnt;
 760         uio.uio_loffset = laddr;
 761         uio.uio_segflg = (short)UIO_SYSSPACE;
 762         uio.uio_resid = (uint64_t)len;
 763         uio.uio_llimit = RLIM64_INFINITY;
 764 
 765         if (is_read == B_TRUE) {
 766                 uio.uio_fmode = FREAD;
 767                 uio.uio_extflg = UIO_COPY_CACHED;
 768                 DTRACE_PROBE5(backing__store__read__start, sbd_lu_t *, sl,
 769                     uint8_t *, NULL, uint64_t, len, uint64_t, laddr,
 770                     scsi_task_t *, task);
 771 
 772                 /* Fetch the data */
 773                 ret = sbd_zvol_copy_read(sl, &uio);
 774 
 775                 DTRACE_PROBE6(backing__store__read__end, sbd_lu_t *, sl,
 776                     uint8_t *, NULL, uint64_t, len, uint64_t, laddr, int, ret,
 777                     scsi_task_t *, task);
 778         } else {
 779                 uio.uio_fmode = FWRITE;
 780                 uio.uio_extflg = UIO_COPY_DEFAULT;
 781                 DTRACE_PROBE5(backing__store__write__start, sbd_lu_t *, sl,
 782                     uint8_t *, NULL, uint64_t, len, uint64_t, laddr,
 783                     scsi_task_t *, task);
 784 
 785                 flags = (commit) ? ZVIO_COMMIT : 0;
 786                 /* Write the data */
 787                 ret = sbd_zvol_copy_write(sl, &uio, flags);
 788 
 789                 DTRACE_PROBE6(backing__store__write__end, sbd_lu_t *, sl,
 790                     uint8_t *, NULL, uint64_t, len, uint64_t, laddr, int, ret,
 791                     scsi_task_t *, task);
 792         }
 793 
 794         if (iov != &iov1[0])
 795                 kmem_free(iov, iovcnt * sizeof (*iov));
 796         if (ret != 0) {
 797                 /* Backend I/O error */
 798                 return (STMF_FAILURE);
 799         }
 800         return (STMF_SUCCESS);
 801 }
 802 
 803 void
 804 sbd_handle_read(struct scsi_task *task, struct stmf_data_buf *initial_dbuf)
 805 {
 806         uint64_t lba, laddr;
 807         uint32_t len;
 808         uint8_t op = task->task_cdb[0];
 809         sbd_lu_t *sl = (sbd_lu_t *)task->task_lu->lu_provider_private;
 810         sbd_cmd_t *scmd;
 811         stmf_data_buf_t *dbuf;
 812         int fast_path;
 813 
 814         if (op == SCMD_READ) {
 815                 lba = READ_SCSI21(&task->task_cdb[1], uint64_t);
 816                 len = (uint32_t)task->task_cdb[4];
 817 
 818                 if (len == 0) {
 819                         len = 256;
 820                 }
 821         } else if (op == SCMD_READ_G1) {
 822                 lba = READ_SCSI32(&task->task_cdb[2], uint64_t);
 823                 len = READ_SCSI16(&task->task_cdb[7], uint32_t);
 824         } else if (op == SCMD_READ_G5) {
 825                 lba = READ_SCSI32(&task->task_cdb[2], uint64_t);
 826                 len = READ_SCSI32(&task->task_cdb[6], uint32_t);
 827         } else if (op == SCMD_READ_G4) {
 828                 lba = READ_SCSI64(&task->task_cdb[2], uint64_t);
 829                 len = READ_SCSI32(&task->task_cdb[10], uint32_t);
 830         } else {
 831                 stmf_scsilib_send_status(task, STATUS_CHECK,
 832                     STMF_SAA_INVALID_OPCODE);
 833                 return;
 834         }
 835 
 836         laddr = lba << sl->sl_data_blocksize_shift;
 837         len <<= sl->sl_data_blocksize_shift;
 838 
 839         if ((laddr + (uint64_t)len) > sl->sl_lu_size) {
 840                 stmf_scsilib_send_status(task, STATUS_CHECK,
 841                     STMF_SAA_LBA_OUT_OF_RANGE);
 842                 return;
 843         }
 844 
 845         task->task_cmd_xfer_length = len;
 846         if (task->task_additional_flags & TASK_AF_NO_EXPECTED_XFER_LENGTH) {
 847                 task->task_expected_xfer_length = len;
 848         }
 849 
 850         if (len != task->task_expected_xfer_length) {
 851                 fast_path = 0;
 852                 len = (len > task->task_expected_xfer_length) ?
 853                     task->task_expected_xfer_length : len;
 854         } else {
 855                 fast_path = 1;
 856         }
 857 
 858         if (len == 0) {
 859                 stmf_scsilib_send_status(task, STATUS_GOOD, 0);
 860                 return;
 861         }
 862 
 863         /*
 864          * Determine if this read can directly use DMU buffers.
 865          */
 866         if (sbd_zcopy & (2|1) &&            /* Debug switch */
 867             initial_dbuf == NULL &&             /* No PP buffer passed in */
 868             sl->sl_flags & SL_CALL_ZVOL &&       /* zvol backing store */
 869             (task->task_additional_flags &
 870             TASK_AF_ACCEPT_LU_DBUF))            /* PP allows it */
 871         {
 872                 /*
 873                  * Reduced copy path
 874                  */
 875                 uint32_t copy_threshold, minsize;
 876                 int ret;
 877 
 878                 /*
 879                  * The sl_access_state_lock will be held shared
 880                  * for the entire request and released when all
 881                  * dbufs have completed.
 882                  */
 883                 rw_enter(&sl->sl_access_state_lock, RW_READER);
 884                 if ((sl->sl_flags & SL_MEDIA_LOADED) == 0) {
 885                         rw_exit(&sl->sl_access_state_lock);
 886                         stmf_scsilib_send_status(task, STATUS_CHECK,
 887                             STMF_SAA_READ_ERROR);
 888                         return;
 889                 }
 890 
 891                 /*
 892                  * Check if setup is more expensive than copying the data.
 893                  *
 894                  * Use the global over-ride sbd_zcopy_threshold if set.
 895                  */
 896                 copy_threshold = (sbd_copy_threshold > 0) ?
 897                     sbd_copy_threshold : task->task_copy_threshold;
 898                 minsize = len;
 899                 if (len < copy_threshold &&
 900                     (dbuf = stmf_alloc_dbuf(task, len, &minsize, 0)) != 0) {
 901 
 902                         ret = sbd_copy_rdwr(task, laddr, dbuf,
 903                             SBD_CMD_SCSI_READ, 0);
 904                         /* done with the backend */
 905                         rw_exit(&sl->sl_access_state_lock);
 906                         if (ret != 0) {
 907                                 /* backend error */
 908                                 stmf_scsilib_send_status(task, STATUS_CHECK,
 909                                     STMF_SAA_READ_ERROR);
 910                         } else {
 911                                 /* send along good data */
 912                                 dbuf->db_relative_offset = 0;
 913                                 dbuf->db_data_size = len;
 914                                 dbuf->db_flags = DB_SEND_STATUS_GOOD |
 915                                     DB_DIRECTION_TO_RPORT;
 916                                 /* XXX keep for FW? */
 917                                 DTRACE_PROBE4(sbd__xfer,
 918                                     struct scsi_task *, task,
 919                                     struct stmf_data_buf *, dbuf,
 920                                     uint64_t, laddr, uint32_t, len);
 921                                 (void) stmf_xfer_data(task, dbuf,
 922                                     STMF_IOF_LU_DONE);
 923                         }
 924                         return;
 925                 }
 926 
 927                 /* committed to reduced copy */
 928                 if (task->task_lu_private) {
 929                         scmd = (sbd_cmd_t *)task->task_lu_private;
 930                 } else {
 931                         scmd = (sbd_cmd_t *)kmem_alloc(sizeof (sbd_cmd_t),
 932                             KM_SLEEP);
 933                         task->task_lu_private = scmd;
 934                 }
 935                 /*
 936                  * Setup scmd to track read progress.
 937                  */
 938                 scmd->flags = SBD_SCSI_CMD_ACTIVE;
 939                 scmd->cmd_type = SBD_CMD_SCSI_READ;
 940                 scmd->nbufs = 0;
 941                 scmd->addr = laddr;
 942                 scmd->len = len;
 943                 scmd->current_ro = 0;
 944 
 945                 /*
 946                  * Kick-off the read.
 947                  */
 948                 sbd_do_sgl_read_xfer(task, scmd, 1);
 949                 return;
 950         }
 951 
 952         if (initial_dbuf == NULL) {
 953                 uint32_t maxsize, minsize, old_minsize;
 954 
 955                 maxsize = (len > (128*1024)) ? 128*1024 : len;
 956                 minsize = maxsize >> 2;
 957                 do {
 958                         old_minsize = minsize;
 959                         initial_dbuf = stmf_alloc_dbuf(task, maxsize,
 960                             &minsize, 0);
 961                 } while ((initial_dbuf == NULL) && (old_minsize > minsize) &&
 962                     (minsize >= 512));
 963                 if (initial_dbuf == NULL) {
 964                         stmf_scsilib_send_status(task, STATUS_QFULL, 0);
 965                         return;
 966                 }
 967         }
 968         dbuf = initial_dbuf;
 969 
 970         if ((dbuf->db_buf_size >= len) && fast_path &&
 971             (dbuf->db_sglist_length == 1)) {
 972                 if (sbd_data_read(sl, task, laddr, (uint64_t)len,
 973                     dbuf->db_sglist[0].seg_addr) == STMF_SUCCESS) {
 974                         dbuf->db_relative_offset = 0;
 975                         dbuf->db_data_size = len;
 976                         dbuf->db_flags = DB_SEND_STATUS_GOOD |
 977                             DB_DIRECTION_TO_RPORT;
 978                         /* XXX keep for FW? */
 979                         DTRACE_PROBE4(sbd__xfer, struct scsi_task *, task,
 980                             struct stmf_data_buf *, dbuf,
 981                             uint64_t, laddr, uint32_t, len);
 982                         (void) stmf_xfer_data(task, dbuf, STMF_IOF_LU_DONE);
 983                 } else {
 984                         stmf_scsilib_send_status(task, STATUS_CHECK,
 985                             STMF_SAA_READ_ERROR);
 986                 }
 987                 return;
 988         }
 989 
 990         if (task->task_lu_private) {
 991                 scmd = (sbd_cmd_t *)task->task_lu_private;
 992         } else {
 993                 scmd = (sbd_cmd_t *)kmem_alloc(sizeof (sbd_cmd_t), KM_SLEEP);
 994                 task->task_lu_private = scmd;
 995         }
 996         scmd->flags = SBD_SCSI_CMD_ACTIVE;
 997         scmd->cmd_type = SBD_CMD_SCSI_READ;
 998         scmd->nbufs = 1;
 999         scmd->addr = laddr;
1000         scmd->len = len;
1001         scmd->current_ro = 0;
1002 
1003         sbd_do_read_xfer(task, scmd, dbuf);
1004 }
1005 
1006 void
1007 sbd_do_write_xfer(struct scsi_task *task, sbd_cmd_t *scmd,
1008     struct stmf_data_buf *dbuf, uint8_t dbuf_reusable)
1009 {
1010         uint32_t len;
1011         int bufs_to_take;
1012 
1013         if (scmd->len == 0) {
1014                 goto DO_WRITE_XFER_DONE;
1015         }
1016 
1017         /* Lets try not to hog all the buffers the port has. */
1018         bufs_to_take = ((task->task_max_nbufs > 2) &&
1019             (task->task_cmd_xfer_length < (32 * 1024))) ? 2 :
1020             task->task_max_nbufs;
1021 
1022         if ((dbuf != NULL) &&
1023             ((dbuf->db_flags & DB_DONT_REUSE) || (dbuf_reusable == 0))) {
1024                 /* free current dbuf and allocate a new one */
1025                 stmf_free_dbuf(task, dbuf);
1026                 dbuf = NULL;
1027         }
1028         if (scmd->nbufs >= bufs_to_take) {
1029                 goto DO_WRITE_XFER_DONE;
1030         }
1031         if (dbuf == NULL) {
1032                 uint32_t maxsize, minsize, old_minsize;
1033 
1034                 maxsize = (scmd->len > (128*1024)) ? 128*1024 :
1035                     scmd->len;
1036                 minsize = maxsize >> 2;
1037                 do {
1038                         old_minsize = minsize;
1039                         dbuf = stmf_alloc_dbuf(task, maxsize, &minsize, 0);
1040                 } while ((dbuf == NULL) && (old_minsize > minsize) &&
1041                     (minsize >= 512));
1042                 if (dbuf == NULL) {
1043                         if (scmd->nbufs == 0) {
1044                                 stmf_abort(STMF_QUEUE_TASK_ABORT, task,
1045                                     STMF_ALLOC_FAILURE, NULL);
1046                         }
1047                         return;
1048                 }
1049         }
1050 
1051         len = scmd->len > dbuf->db_buf_size ? dbuf->db_buf_size :
1052             scmd->len;
1053 
1054         dbuf->db_relative_offset = scmd->current_ro;
1055         dbuf->db_data_size = len;
1056         dbuf->db_flags = DB_DIRECTION_FROM_RPORT;
1057         (void) stmf_xfer_data(task, dbuf, 0);
1058         scmd->nbufs++; /* outstanding port xfers and bufs used */
1059         scmd->len -= len;
1060         scmd->current_ro += len;
1061 
1062         if ((scmd->len != 0) && (scmd->nbufs < bufs_to_take)) {
1063                 sbd_do_write_xfer(task, scmd, NULL, 0);
1064         }
1065         return;
1066 
1067 DO_WRITE_XFER_DONE:
1068         if (dbuf != NULL) {
1069                 stmf_free_dbuf(task, dbuf);
1070         }
1071 }
1072 
1073 void
1074 sbd_do_sgl_write_xfer(struct scsi_task *task, sbd_cmd_t *scmd, int first_xfer)
1075 {
1076         sbd_lu_t *sl = (sbd_lu_t *)task->task_lu->lu_provider_private;
1077         sbd_zvol_io_t *zvio;
1078         int ret;
1079         uint32_t xfer_len, max_len, first_len;
1080         stmf_status_t xstat;
1081         stmf_data_buf_t *dbuf;
1082         uint_t nblks;
1083         uint64_t blksize = sl->sl_blksize;
1084         uint64_t offset;
1085         size_t db_private_sz;
1086         uintptr_t pad;
1087 
1088         ASSERT(rw_read_held(&sl->sl_access_state_lock));
1089         ASSERT((sl->sl_flags & SL_MEDIA_LOADED) != 0);
1090 
1091         /*
1092          * Calculate the limits on xfer_len to the minimum of :
1093          *    - task limit
1094          *    - lun limit
1095          *    - sbd global limit if set
1096          *    - first xfer limit if set
1097          *
1098          * First, protect against silly over-ride value
1099          */
1100         if (sbd_max_xfer_len && ((sbd_max_xfer_len % DEV_BSIZE) != 0)) {
1101                 cmn_err(CE_WARN, "sbd_max_xfer_len invalid %d, resetting\n",
1102                     sbd_max_xfer_len);
1103                 sbd_max_xfer_len = 0;
1104         }
1105         if (sbd_1st_xfer_len && ((sbd_1st_xfer_len % DEV_BSIZE) != 0)) {
1106                 cmn_err(CE_WARN, "sbd_1st_xfer_len invalid %d, resetting\n",
1107                     sbd_1st_xfer_len);
1108                 sbd_1st_xfer_len = 0;
1109         }
1110 
1111         max_len = MIN(task->task_max_xfer_len, sl->sl_max_xfer_len);
1112         if (sbd_max_xfer_len)
1113                 max_len = MIN(max_len, sbd_max_xfer_len);
1114         /*
1115          * Special case the first xfer if hints are set.
1116          */
1117         if (first_xfer && (sbd_1st_xfer_len || task->task_1st_xfer_len)) {
1118                 /* global over-ride has precedence */
1119                 if (sbd_1st_xfer_len)
1120                         first_len = sbd_1st_xfer_len;
1121                 else
1122                         first_len = task->task_1st_xfer_len;
1123         } else {
1124                 first_len = 0;
1125         }
1126 
1127 
1128         while (scmd->len && scmd->nbufs < task->task_max_nbufs) {
1129 
1130                 xfer_len = MIN(max_len, scmd->len);
1131                 if (first_len) {
1132                         xfer_len = MIN(xfer_len, first_len);
1133                         first_len = 0;
1134                 }
1135                 if (xfer_len < scmd->len) {
1136                         /*
1137                          * Attempt to end xfer on a block boundary.
1138                          * The only way this does not happen is if the
1139                          * xfer_len is small enough to stay contained
1140                          * within the same block.
1141                          */
1142                         uint64_t xfer_offset, xfer_aligned_end;
1143 
1144                         xfer_offset = scmd->addr + scmd->current_ro;
1145                         xfer_aligned_end =
1146                             P2ALIGN(xfer_offset+xfer_len, blksize);
1147                         if (xfer_aligned_end > xfer_offset)
1148                                 xfer_len = xfer_aligned_end - xfer_offset;
1149                 }
1150                 /*
1151                  * Allocate object to track the write and reserve
1152                  * enough space for scatter/gather list.
1153                  */
1154                 offset = scmd->addr + scmd->current_ro;
1155                 nblks = sbd_zvol_numsegs(sl, offset, xfer_len);
1156                 db_private_sz = sizeof (*zvio) + sizeof (uintptr_t) /* PAD */ +
1157                     (nblks * sizeof (stmf_sglist_ent_t));
1158                 dbuf = stmf_alloc(STMF_STRUCT_DATA_BUF, db_private_sz,
1159                     AF_DONTZERO);
1160 
1161                 /*
1162                  * Setup the dbuf
1163                  *
1164                  * XXX Framework does not handle variable length sglists
1165                  * properly, so setup db_lu_private and db_port_private
1166                  * fields here. db_stmf_private is properly set for
1167                  * calls to stmf_free.
1168                  */
1169                 if (dbuf->db_port_private == NULL) {
1170                         /*
1171                          * XXX Framework assigns space to PP after db_sglist[0]
1172                          */
1173                         cmn_err(CE_PANIC, "db_port_private == NULL");
1174                 }
1175                 pad = (uintptr_t)&dbuf->db_sglist[nblks];
1176                 dbuf->db_lu_private = (void *)P2ROUNDUP(pad, sizeof (pad));
1177                 dbuf->db_port_private = NULL;
1178                 dbuf->db_buf_size = xfer_len;
1179                 dbuf->db_data_size = xfer_len;
1180                 dbuf->db_relative_offset = scmd->current_ro;
1181                 dbuf->db_sglist_length = (uint16_t)nblks;
1182                 dbuf->db_xfer_status = 0;
1183                 dbuf->db_handle = 0;
1184                 dbuf->db_flags = (DB_DONT_CACHE | DB_DONT_REUSE |
1185                     DB_DIRECTION_FROM_RPORT | DB_LU_DATA_BUF);
1186 
1187                 zvio = dbuf->db_lu_private;
1188                 zvio->zvio_offset = offset;
1189 
1190                 /* get the buffers */
1191                 ret = sbd_zvol_alloc_write_bufs(sl, dbuf);
1192                 if (ret != 0) {
1193                         /*
1194                          * Could not allocate buffers from the backend;
1195                          * treat it like an IO error.
1196                          */
1197                         stmf_free(dbuf);
1198                         scmd->flags |= SBD_SCSI_CMD_XFER_FAIL;
1199                         if (scmd->nbufs == 0) {
1200                                 /*
1201                                  * Nothing queued, so no completions coming
1202                                  */
1203                                 stmf_scsilib_send_status(task, STATUS_CHECK,
1204                                     STMF_SAA_WRITE_ERROR);
1205                                 rw_exit(&sl->sl_access_state_lock);
1206                         }
1207                         /*
1208                          * Completions of previous buffers will cleanup.
1209                          */
1210                         return;
1211                 }
1212 
1213                 /*
1214                  * Allow PP to do setup
1215                  */
1216                 xstat = stmf_setup_dbuf(task, dbuf, 0);
1217                 if (xstat != STMF_SUCCESS) {
1218                         /*
1219                          * This could happen if the driver cannot get the
1220                          * DDI resources it needs for this request.
1221                          * If other dbufs are queued, try again when the next
1222                          * one completes, otherwise give up.
1223                          */
1224                         sbd_zvol_rele_write_bufs_abort(sl, dbuf);
1225                         stmf_free(dbuf);
1226                         if (scmd->nbufs > 0) {
1227                                 /* completion of previous dbuf will retry */
1228                                 return;
1229                         }
1230                         /*
1231                          * Done with this command.
1232                          */
1233                         scmd->flags &= ~SBD_SCSI_CMD_ACTIVE;
1234                         if (first_xfer)
1235                                 stmf_scsilib_send_status(task, STATUS_QFULL, 0);
1236                         else
1237                                 stmf_scsilib_send_status(task, STATUS_CHECK,
1238                                     STMF_SAA_WRITE_ERROR);
1239                         rw_exit(&sl->sl_access_state_lock);
1240                         return;
1241                 }
1242 
1243                 /*
1244                  * dbuf is now queued on task
1245                  */
1246                 scmd->nbufs++;
1247 
1248                 xstat = stmf_xfer_data(task, dbuf, 0);
1249                 switch (xstat) {
1250                 case STMF_SUCCESS:
1251                         break;
1252                 case STMF_BUSY:
1253                         /*
1254                          * The dbuf is queued on the task, but unknown
1255                          * to the PP, thus no completion will occur.
1256                          */
1257                         sbd_zvol_rele_write_bufs_abort(sl, dbuf);
1258                         stmf_teardown_dbuf(task, dbuf);
1259                         stmf_free(dbuf);
1260                         scmd->nbufs--;
1261                         if (scmd->nbufs > 0) {
1262                                 /* completion of previous dbuf will retry */
1263                                 return;
1264                         }
1265                         /*
1266                          * Done with this command.
1267                          */
1268                         scmd->flags &= ~SBD_SCSI_CMD_ACTIVE;
1269                         if (first_xfer)
1270                                 stmf_scsilib_send_status(task, STATUS_QFULL, 0);
1271                         else
1272                                 stmf_scsilib_send_status(task, STATUS_CHECK,
1273                                     STMF_SAA_WRITE_ERROR);
1274                         rw_exit(&sl->sl_access_state_lock);
1275                         return;
1276                 case STMF_ABORTED:
1277                         /*
1278                          * Completion code will cleanup.
1279                          */
1280                         scmd->flags |= SBD_SCSI_CMD_XFER_FAIL;
1281                         return;
1282                 }
1283                 /*
1284                  * Update the xfer progress.
1285                  */
1286                 scmd->len -= xfer_len;
1287                 scmd->current_ro += xfer_len;
1288         }
1289 }
1290 
1291 void
1292 sbd_handle_write_xfer_completion(struct scsi_task *task, sbd_cmd_t *scmd,
1293     struct stmf_data_buf *dbuf, uint8_t dbuf_reusable)
1294 {
1295         sbd_lu_t *sl = (sbd_lu_t *)task->task_lu->lu_provider_private;
1296         uint64_t laddr;
1297         uint32_t buflen, iolen;
1298         int ndx;
1299 
1300         if (scmd->nbufs > 0) {
1301                 /*
1302                  * Decrement the count to indicate the port xfer
1303                  * into the dbuf has completed even though the buf is
1304                  * still in use here in the LU provider.
1305                  */
1306                 scmd->nbufs--;
1307         }
1308 
1309         if (dbuf->db_xfer_status != STMF_SUCCESS) {
1310                 stmf_abort(STMF_QUEUE_TASK_ABORT, task,
1311                     dbuf->db_xfer_status, NULL);
1312                 return;
1313         }
1314 
1315         if (scmd->flags & SBD_SCSI_CMD_XFER_FAIL) {
1316                 goto WRITE_XFER_DONE;
1317         }
1318 
1319         if (scmd->len != 0) {
1320                 /*
1321                  * Initiate the next port xfer to occur in parallel
1322                  * with writing this buf.
1323                  */
1324                 sbd_do_write_xfer(task, scmd, NULL, 0);
1325         }
1326 
1327         laddr = scmd->addr + dbuf->db_relative_offset;
1328 
1329         /*
1330          * If this is going to a zvol, use the direct call to
1331          * sbd_zvol_copy_{read,write}. The direct call interface is
1332          * restricted to PPs that accept sglists, but that is not required.
1333          */
1334         if (sl->sl_flags & SL_CALL_ZVOL &&
1335             (task->task_additional_flags & TASK_AF_ACCEPT_LU_DBUF) &&
1336             (sbd_zcopy & (4|1))) {
1337                 int commit;
1338 
1339                 commit = (scmd->len == 0 && scmd->nbufs == 0);
1340                 if (sbd_copy_rdwr(task, laddr, dbuf, SBD_CMD_SCSI_WRITE,
1341                     commit) != STMF_SUCCESS)
1342                         scmd->flags |= SBD_SCSI_CMD_XFER_FAIL;
1343                 buflen = dbuf->db_data_size;
1344         } else {
1345                 for (buflen = 0, ndx = 0; (buflen < dbuf->db_data_size) &&
1346                     (ndx < dbuf->db_sglist_length); ndx++) {
1347                         iolen = min(dbuf->db_data_size - buflen,
1348                             dbuf->db_sglist[ndx].seg_length);
1349                         if (iolen == 0)
1350                                 break;
1351                         if (sbd_data_write(sl, task, laddr, (uint64_t)iolen,
1352                             dbuf->db_sglist[ndx].seg_addr) != STMF_SUCCESS) {
1353                                 scmd->flags |= SBD_SCSI_CMD_XFER_FAIL;
1354                                 break;
1355                         }
1356                         buflen += iolen;
1357                         laddr += (uint64_t)iolen;
1358                 }
1359         }
1360         task->task_nbytes_transferred += buflen;
1361 WRITE_XFER_DONE:
1362         if (scmd->len == 0 || scmd->flags & SBD_SCSI_CMD_XFER_FAIL) {
1363                 stmf_free_dbuf(task, dbuf);
1364                 if (scmd->nbufs)
1365                         return; /* wait for all buffers to complete */
1366                 scmd->flags &= ~SBD_SCSI_CMD_ACTIVE;
1367                 if (scmd->flags & SBD_SCSI_CMD_XFER_FAIL) {
1368                         stmf_scsilib_send_status(task, STATUS_CHECK,
1369                             STMF_SAA_WRITE_ERROR);
1370                 } else {
1371                         /*
1372                          * If SYNC_WRITE flag is on then we need to flush
1373                          * cache before sending status.
1374                          * Note: this may be a no-op because of how
1375                          * SL_WRITEBACK_CACHE_DISABLE and
1376                          * SL_FLUSH_ON_DISABLED_WRITECACHE are set, but not
1377                          * worth code complexity of checking those in this code
1378                          * path, SBD_SCSI_CMD_SYNC_WRITE is rarely set.
1379                          */
1380                         if ((scmd->flags & SBD_SCSI_CMD_SYNC_WRITE) &&
1381                             (sbd_flush_data_cache(sl, 0) != SBD_SUCCESS)) {
1382                                 stmf_scsilib_send_status(task, STATUS_CHECK,
1383                                     STMF_SAA_WRITE_ERROR);
1384                         } else {
1385                                 stmf_scsilib_send_status(task, STATUS_GOOD, 0);
1386                         }
1387                 }
1388                 return;
1389         }
1390         sbd_do_write_xfer(task, scmd, dbuf, dbuf_reusable);
1391 }
1392 
1393 /*
1394  * Return true if copy avoidance is beneficial.
1395  */
1396 static int
1397 sbd_zcopy_write_useful(scsi_task_t *task, uint64_t laddr, uint32_t len,
1398     uint64_t blksize)
1399 {
1400         /*
1401          * If there is a global copy threshold over-ride, use it.
1402          * Otherwise use the PP value with the caveat that at least
1403          * 1/2 the data must avoid being copied to be useful.
1404          */
1405         if (sbd_copy_threshold > 0) {
1406                 return (len >= sbd_copy_threshold);
1407         } else {
1408                 uint64_t no_copy_span;
1409 
1410                 /* sub-blocksize writes always copy */
1411                 if (len < task->task_copy_threshold || len < blksize)
1412                         return (0);
1413                 /*
1414                  * Calculate amount of data that will avoid the copy path.
1415                  * The calculation is only valid if len >= blksize.
1416                  */
1417                 no_copy_span = P2ALIGN(laddr+len, blksize) -
1418                     P2ROUNDUP(laddr, blksize);
1419                 return (no_copy_span >= len/2);
1420         }
1421 }
1422 
1423 void
1424 sbd_handle_write(struct scsi_task *task, struct stmf_data_buf *initial_dbuf)
1425 {
1426         uint64_t lba, laddr;
1427         uint32_t len;
1428         uint8_t op = task->task_cdb[0], do_immediate_data = 0;
1429         sbd_lu_t *sl = (sbd_lu_t *)task->task_lu->lu_provider_private;
1430         sbd_cmd_t *scmd;
1431         stmf_data_buf_t *dbuf;
1432         uint8_t sync_wr_flag = 0;
1433 
1434         if (sl->sl_flags & SL_WRITE_PROTECTED) {
1435                 stmf_scsilib_send_status(task, STATUS_CHECK,
1436                     STMF_SAA_WRITE_PROTECTED);
1437                 return;
1438         }
1439         if (op == SCMD_WRITE) {
1440                 lba = READ_SCSI21(&task->task_cdb[1], uint64_t);
1441                 len = (uint32_t)task->task_cdb[4];
1442 
1443                 if (len == 0) {
1444                         len = 256;
1445                 }
1446         } else if (op == SCMD_WRITE_G1) {
1447                 lba = READ_SCSI32(&task->task_cdb[2], uint64_t);
1448                 len = READ_SCSI16(&task->task_cdb[7], uint32_t);
1449         } else if (op == SCMD_WRITE_G5) {
1450                 lba = READ_SCSI32(&task->task_cdb[2], uint64_t);
1451                 len = READ_SCSI32(&task->task_cdb[6], uint32_t);
1452         } else if (op == SCMD_WRITE_G4) {
1453                 lba = READ_SCSI64(&task->task_cdb[2], uint64_t);
1454                 len = READ_SCSI32(&task->task_cdb[10], uint32_t);
1455         } else if (op == SCMD_WRITE_VERIFY) {
1456                 lba = READ_SCSI32(&task->task_cdb[2], uint64_t);
1457                 len = READ_SCSI16(&task->task_cdb[7], uint32_t);
1458                 sync_wr_flag = SBD_SCSI_CMD_SYNC_WRITE;
1459         } else if (op == SCMD_WRITE_VERIFY_G5) {
1460                 lba = READ_SCSI32(&task->task_cdb[2], uint64_t);
1461                 len = READ_SCSI32(&task->task_cdb[6], uint32_t);
1462                 sync_wr_flag = SBD_SCSI_CMD_SYNC_WRITE;
1463         } else if (op == SCMD_WRITE_VERIFY_G4) {
1464                 lba = READ_SCSI64(&task->task_cdb[2], uint64_t);
1465                 len = READ_SCSI32(&task->task_cdb[10], uint32_t);
1466                 sync_wr_flag = SBD_SCSI_CMD_SYNC_WRITE;
1467         } else {
1468                 stmf_scsilib_send_status(task, STATUS_CHECK,
1469                     STMF_SAA_INVALID_OPCODE);
1470                 return;
1471         }
1472 
1473         laddr = lba << sl->sl_data_blocksize_shift;
1474         len <<= sl->sl_data_blocksize_shift;
1475 
1476         if ((laddr + (uint64_t)len) > sl->sl_lu_size) {
1477                 stmf_scsilib_send_status(task, STATUS_CHECK,
1478                     STMF_SAA_LBA_OUT_OF_RANGE);
1479                 return;
1480         }
1481 
1482         task->task_cmd_xfer_length = len;
1483         if (task->task_additional_flags & TASK_AF_NO_EXPECTED_XFER_LENGTH) {
1484                 task->task_expected_xfer_length = len;
1485         }
1486 
1487         len = (len > task->task_expected_xfer_length) ?
1488             task->task_expected_xfer_length : len;
1489 
1490         if (len == 0) {
1491                 stmf_scsilib_send_status(task, STATUS_GOOD, 0);
1492                 return;
1493         }
1494 
1495         if (sbd_zcopy & (4|1) &&            /* Debug switch */
1496             initial_dbuf == NULL &&             /* No PP buf passed in */
1497             sl->sl_flags & SL_CALL_ZVOL &&       /* zvol backing store */
1498             (task->task_additional_flags &
1499             TASK_AF_ACCEPT_LU_DBUF) &&          /* PP allows it */
1500             sbd_zcopy_write_useful(task, laddr, len, sl->sl_blksize)) {
1501 
1502                 /*
1503                  * XXX Note that disallowing initial_dbuf will eliminate
1504                  * iSCSI from participating. For small writes, that is
1505                  * probably ok. For large writes, it may be best to just
1506                  * copy the data from the initial dbuf and use zcopy for
1507                  * the rest.
1508                  */
1509                 rw_enter(&sl->sl_access_state_lock, RW_READER);
1510                 if ((sl->sl_flags & SL_MEDIA_LOADED) == 0) {
1511                         rw_exit(&sl->sl_access_state_lock);
1512                         stmf_scsilib_send_status(task, STATUS_CHECK,
1513                             STMF_SAA_READ_ERROR);
1514                         return;
1515                 }
1516                 /*
1517                  * Setup scmd to track the write progress.
1518                  */
1519                 if (task->task_lu_private) {
1520                         scmd = (sbd_cmd_t *)task->task_lu_private;
1521                 } else {
1522                         scmd = (sbd_cmd_t *)kmem_alloc(sizeof (sbd_cmd_t),
1523                             KM_SLEEP);
1524                         task->task_lu_private = scmd;
1525                 }
1526                 scmd->flags = SBD_SCSI_CMD_ACTIVE | sync_wr_flag;
1527                 scmd->cmd_type = SBD_CMD_SCSI_WRITE;
1528                 scmd->nbufs = 0;
1529                 scmd->addr = laddr;
1530                 scmd->len = len;
1531                 scmd->current_ro = 0;
1532                 sbd_do_sgl_write_xfer(task, scmd, 1);
1533                 return;
1534         }
1535 
1536         if ((initial_dbuf != NULL) && (task->task_flags & TF_INITIAL_BURST)) {
1537                 if (initial_dbuf->db_data_size > len) {
1538                         if (initial_dbuf->db_data_size >
1539                             task->task_expected_xfer_length) {
1540                                 /* protocol error */
1541                                 stmf_abort(STMF_QUEUE_TASK_ABORT, task,
1542                                     STMF_INVALID_ARG, NULL);
1543                                 return;
1544                         }
1545                         initial_dbuf->db_data_size = len;
1546                 }
1547                 do_immediate_data = 1;
1548         }
1549         dbuf = initial_dbuf;
1550 
1551         if (task->task_lu_private) {
1552                 scmd = (sbd_cmd_t *)task->task_lu_private;
1553         } else {
1554                 scmd = (sbd_cmd_t *)kmem_alloc(sizeof (sbd_cmd_t), KM_SLEEP);
1555                 task->task_lu_private = scmd;
1556         }
1557         scmd->flags = SBD_SCSI_CMD_ACTIVE | sync_wr_flag;
1558         scmd->cmd_type = SBD_CMD_SCSI_WRITE;
1559         scmd->nbufs = 0;
1560         scmd->addr = laddr;
1561         scmd->len = len;
1562         scmd->current_ro = 0;
1563 
1564         if (do_immediate_data) {
1565                 /*
1566                  * Account for data passed in this write command
1567                  */
1568                 (void) stmf_xfer_data(task, dbuf, STMF_IOF_STATS_ONLY);
1569                 scmd->len -= dbuf->db_data_size;
1570                 scmd->current_ro += dbuf->db_data_size;
1571                 dbuf->db_xfer_status = STMF_SUCCESS;
1572                 sbd_handle_write_xfer_completion(task, scmd, dbuf, 0);
1573         } else {
1574                 sbd_do_write_xfer(task, scmd, dbuf, 0);
1575         }
1576 }
1577 
1578 /*
1579  * Utility routine to handle small non performance data transfers to the
1580  * initiators. dbuf is an initial data buf (if any), 'p' points to a data
1581  * buffer which is source of data for transfer, cdb_xfer_size is the
1582  * transfer size based on CDB, cmd_xfer_size is the actual amount of data
1583  * which this command would transfer (the size of data pointed to by 'p').
1584  */
1585 void
1586 sbd_handle_short_read_transfers(scsi_task_t *task, stmf_data_buf_t *dbuf,
1587     uint8_t *p, uint32_t cdb_xfer_size, uint32_t cmd_xfer_size)
1588 {
1589         uint32_t bufsize, ndx;
1590         sbd_cmd_t *scmd;
1591 
1592         cmd_xfer_size = min(cmd_xfer_size, cdb_xfer_size);
1593 
1594         task->task_cmd_xfer_length = cmd_xfer_size;
1595         if (task->task_additional_flags & TASK_AF_NO_EXPECTED_XFER_LENGTH) {
1596                 task->task_expected_xfer_length = cmd_xfer_size;
1597         } else {
1598                 cmd_xfer_size = min(cmd_xfer_size,
1599                     task->task_expected_xfer_length);
1600         }
1601 
1602         if (cmd_xfer_size == 0) {
1603                 stmf_scsilib_send_status(task, STATUS_CHECK,
1604                     STMF_SAA_INVALID_FIELD_IN_CDB);
1605                 return;
1606         }
1607         if (dbuf == NULL) {
1608                 uint32_t minsize = cmd_xfer_size;
1609 
1610                 dbuf = stmf_alloc_dbuf(task, cmd_xfer_size, &minsize, 0);
1611         }
1612         if (dbuf == NULL) {
1613                 stmf_scsilib_send_status(task, STATUS_QFULL, 0);
1614                 return;
1615         }
1616 
1617         for (bufsize = 0, ndx = 0; bufsize < cmd_xfer_size; ndx++) {
1618                 uint8_t *d;
1619                 uint32_t s;
1620 
1621                 d = dbuf->db_sglist[ndx].seg_addr;
1622                 s = min((cmd_xfer_size - bufsize),
1623                     dbuf->db_sglist[ndx].seg_length);
1624                 bcopy(p+bufsize, d, s);
1625                 bufsize += s;
1626         }
1627         dbuf->db_relative_offset = 0;
1628         dbuf->db_data_size = cmd_xfer_size;
1629         dbuf->db_flags = DB_DIRECTION_TO_RPORT;
1630 
1631         if (task->task_lu_private == NULL) {
1632                 task->task_lu_private =
1633                     kmem_alloc(sizeof (sbd_cmd_t), KM_SLEEP);
1634         }
1635         scmd = (sbd_cmd_t *)task->task_lu_private;
1636 
1637         scmd->cmd_type = SBD_CMD_SMALL_READ;
1638         scmd->flags = SBD_SCSI_CMD_ACTIVE;
1639         (void) stmf_xfer_data(task, dbuf, 0);
1640 }
1641 
1642 void
1643 sbd_handle_short_read_xfer_completion(struct scsi_task *task, sbd_cmd_t *scmd,
1644                                 struct stmf_data_buf *dbuf)
1645 {
1646         if (dbuf->db_xfer_status != STMF_SUCCESS) {
1647                 stmf_abort(STMF_QUEUE_TASK_ABORT, task,
1648                     dbuf->db_xfer_status, NULL);
1649                 return;
1650         }
1651         task->task_nbytes_transferred = dbuf->db_data_size;
1652         scmd->flags &= ~SBD_SCSI_CMD_ACTIVE;
1653         stmf_scsilib_send_status(task, STATUS_GOOD, 0);
1654 }
1655 
1656 void
1657 sbd_handle_short_write_transfers(scsi_task_t *task,
1658     stmf_data_buf_t *dbuf, uint32_t cdb_xfer_size)
1659 {
1660         sbd_cmd_t *scmd;
1661 
1662         task->task_cmd_xfer_length = cdb_xfer_size;
1663         if (task->task_additional_flags & TASK_AF_NO_EXPECTED_XFER_LENGTH) {
1664                 task->task_expected_xfer_length = cdb_xfer_size;
1665         } else {
1666                 cdb_xfer_size = min(cdb_xfer_size,
1667                     task->task_expected_xfer_length);
1668         }
1669 
1670         if (cdb_xfer_size == 0) {
1671                 stmf_scsilib_send_status(task, STATUS_CHECK,
1672                     STMF_SAA_INVALID_FIELD_IN_CDB);
1673                 return;
1674         }
1675         if (task->task_lu_private == NULL) {
1676                 task->task_lu_private = kmem_zalloc(sizeof (sbd_cmd_t),
1677                     KM_SLEEP);
1678         } else {
1679                 bzero(task->task_lu_private, sizeof (sbd_cmd_t));
1680         }
1681         scmd = (sbd_cmd_t *)task->task_lu_private;
1682         scmd->cmd_type = SBD_CMD_SMALL_WRITE;
1683         scmd->flags = SBD_SCSI_CMD_ACTIVE;
1684         scmd->len = cdb_xfer_size;
1685         if (dbuf == NULL) {
1686                 uint32_t minsize = cdb_xfer_size;
1687 
1688                 dbuf = stmf_alloc_dbuf(task, cdb_xfer_size, &minsize, 0);
1689                 if (dbuf == NULL) {
1690                         stmf_abort(STMF_QUEUE_TASK_ABORT, task,
1691                             STMF_ALLOC_FAILURE, NULL);
1692                         return;
1693                 }
1694                 dbuf->db_data_size = cdb_xfer_size;
1695                 dbuf->db_relative_offset = 0;
1696                 dbuf->db_flags = DB_DIRECTION_FROM_RPORT;
1697                 (void) stmf_xfer_data(task, dbuf, 0);
1698         } else {
1699                 if (dbuf->db_data_size < cdb_xfer_size) {
1700                         stmf_abort(STMF_QUEUE_TASK_ABORT, task,
1701                             STMF_ABORTED, NULL);
1702                         return;
1703                 }
1704                 dbuf->db_data_size = cdb_xfer_size;
1705                 sbd_handle_short_write_xfer_completion(task, dbuf);
1706         }
1707 }
1708 
1709 void
1710 sbd_handle_short_write_xfer_completion(scsi_task_t *task,
1711     stmf_data_buf_t *dbuf)
1712 {
1713         sbd_cmd_t *scmd;
1714         stmf_status_t st_ret;
1715         sbd_lu_t *sl = (sbd_lu_t *)task->task_lu->lu_provider_private;
1716 
1717         /*
1718          * For now lets assume we will get only one sglist element
1719          * for short writes. If that ever changes, we should allocate
1720          * a local buffer and copy all the sg elements to one linear space.
1721          */
1722         if ((dbuf->db_xfer_status != STMF_SUCCESS) ||
1723             (dbuf->db_sglist_length > 1)) {
1724                 stmf_abort(STMF_QUEUE_TASK_ABORT, task,
1725                     dbuf->db_xfer_status, NULL);
1726                 return;
1727         }
1728 
1729         task->task_nbytes_transferred = dbuf->db_data_size;
1730         scmd = (sbd_cmd_t *)task->task_lu_private;
1731         scmd->flags &= ~SBD_SCSI_CMD_ACTIVE;
1732 
1733         /* Lets find out who to call */
1734         switch (task->task_cdb[0]) {
1735         case SCMD_MODE_SELECT:
1736         case SCMD_MODE_SELECT_G1:
1737                 if (sl->sl_access_state == SBD_LU_STANDBY) {
1738                         st_ret = stmf_proxy_scsi_cmd(task, dbuf);
1739                         if (st_ret != STMF_SUCCESS) {
1740                                 stmf_scsilib_send_status(task, STATUS_CHECK,
1741                                     STMF_SAA_LU_NO_ACCESS_UNAVAIL);
1742                         }
1743                 } else {
1744                         sbd_handle_mode_select_xfer(task,
1745                             dbuf->db_sglist[0].seg_addr, dbuf->db_data_size);
1746                 }
1747                 break;
1748         case SCMD_UNMAP:
1749                 sbd_handle_unmap_xfer(task,
1750                     dbuf->db_sglist[0].seg_addr, dbuf->db_data_size);
1751                 break;
1752         case SCMD_PERSISTENT_RESERVE_OUT:
1753                 if (sl->sl_access_state == SBD_LU_STANDBY) {
1754                         st_ret = stmf_proxy_scsi_cmd(task, dbuf);
1755                         if (st_ret != STMF_SUCCESS) {
1756                                 stmf_scsilib_send_status(task, STATUS_CHECK,
1757                                     STMF_SAA_LU_NO_ACCESS_UNAVAIL);
1758                         }
1759                 } else {
1760                         sbd_handle_pgr_out_data(task, dbuf);
1761                 }
1762                 break;
1763         default:
1764                 /* This should never happen */
1765                 stmf_abort(STMF_QUEUE_TASK_ABORT, task,
1766                     STMF_ABORTED, NULL);
1767         }
1768 }
1769 
1770 void
1771 sbd_handle_read_capacity(struct scsi_task *task,
1772     struct stmf_data_buf *initial_dbuf)
1773 {
1774         sbd_lu_t *sl = (sbd_lu_t *)task->task_lu->lu_provider_private;
1775         uint32_t cdb_len;
1776         uint8_t p[32];
1777         uint64_t s;
1778         uint16_t blksize;
1779 
1780         s = sl->sl_lu_size >> sl->sl_data_blocksize_shift;
1781         s--;
1782         blksize = ((uint16_t)1) << sl->sl_data_blocksize_shift;
1783 
1784         switch (task->task_cdb[0]) {
1785         case SCMD_READ_CAPACITY:
1786                 if (s & 0xffffffff00000000ull) {
1787                         p[0] = p[1] = p[2] = p[3] = 0xFF;
1788                 } else {
1789                         p[0] = (s >> 24) & 0xff;
1790                         p[1] = (s >> 16) & 0xff;
1791                         p[2] = (s >> 8) & 0xff;
1792                         p[3] = s & 0xff;
1793                 }
1794                 p[4] = 0; p[5] = 0;
1795                 p[6] = (blksize >> 8) & 0xff;
1796                 p[7] = blksize & 0xff;
1797                 sbd_handle_short_read_transfers(task, initial_dbuf, p, 8, 8);
1798                 break;
1799 
1800         case SCMD_SVC_ACTION_IN_G4:
1801                 cdb_len = READ_SCSI32(&task->task_cdb[10], uint32_t);
1802                 bzero(p, 32);
1803                 p[0] = (s >> 56) & 0xff;
1804                 p[1] = (s >> 48) & 0xff;
1805                 p[2] = (s >> 40) & 0xff;
1806                 p[3] = (s >> 32) & 0xff;
1807                 p[4] = (s >> 24) & 0xff;
1808                 p[5] = (s >> 16) & 0xff;
1809                 p[6] = (s >> 8) & 0xff;
1810                 p[7] = s & 0xff;
1811                 p[10] = (blksize >> 8) & 0xff;
1812                 p[11] = blksize & 0xff;
1813                 if (sl->sl_flags & SL_UNMAP_ENABLED) {
1814                         p[14] = 0x80;
1815                 }
1816                 sbd_handle_short_read_transfers(task, initial_dbuf, p,
1817                     cdb_len, 32);
1818                 break;
1819         }
1820 }
1821 
1822 void
1823 sbd_calc_geometry(uint64_t s, uint16_t blksize, uint8_t *nsectors,
1824     uint8_t *nheads, uint32_t *ncyl)
1825 {
1826         if (s < (4ull * 1024ull * 1024ull * 1024ull)) {
1827                 *nsectors = 32;
1828                 *nheads = 8;
1829         } else {
1830                 *nsectors = 254;
1831                 *nheads = 254;
1832         }
1833         *ncyl = s / ((uint64_t)blksize * (uint64_t)(*nsectors) *
1834             (uint64_t)(*nheads));
1835 }
1836 
1837 void
1838 sbd_handle_mode_sense(struct scsi_task *task,
1839     struct stmf_data_buf *initial_dbuf, uint8_t *buf)
1840 {
1841         sbd_lu_t *sl = (sbd_lu_t *)task->task_lu->lu_provider_private;
1842         uint32_t cmd_size, n;
1843         uint8_t *cdb;
1844         uint32_t ncyl;
1845         uint8_t nsectors, nheads;
1846         uint8_t page, ctrl, header_size, pc_valid;
1847         uint16_t nbytes;
1848         uint8_t *p;
1849         uint64_t s = sl->sl_lu_size;
1850         uint32_t dev_spec_param_offset;
1851 
1852         p = buf;        /* buf is assumed to be zeroed out and large enough */
1853         n = 0;
1854         cdb = &task->task_cdb[0];
1855         page = cdb[2] & 0x3F;
1856         ctrl = (cdb[2] >> 6) & 3;
1857         cmd_size = (cdb[0] == SCMD_MODE_SENSE) ? cdb[4] :
1858             READ_SCSI16(&cdb[7], uint32_t);
1859 
1860         if (cdb[0] == SCMD_MODE_SENSE) {
1861                 header_size = 4;
1862                 dev_spec_param_offset = 2;
1863         } else {
1864                 header_size = 8;
1865                 dev_spec_param_offset = 3;
1866         }
1867 
1868         /* Now validate the command */
1869         if ((cdb[2] == 0) || (page == MODEPAGE_ALLPAGES) || (page == 0x08) ||
1870             (page == 0x0A) || (page == 0x03) || (page == 0x04)) {
1871                 pc_valid = 1;
1872         } else {
1873                 pc_valid = 0;
1874         }
1875         if ((cmd_size < header_size) || (pc_valid == 0)) {
1876                 stmf_scsilib_send_status(task, STATUS_CHECK,
1877                     STMF_SAA_INVALID_FIELD_IN_CDB);
1878                 return;
1879         }
1880 
1881         /* We will update the length in the mode header at the end */
1882 
1883         /* Block dev device specific param in mode param header has wp bit */
1884         if (sl->sl_flags & SL_WRITE_PROTECTED) {
1885                 p[n + dev_spec_param_offset] = BIT_7;
1886         }
1887         n += header_size;
1888         /* We are not going to return any block descriptor */
1889 
1890         nbytes = ((uint16_t)1) << sl->sl_data_blocksize_shift;
1891         sbd_calc_geometry(s, nbytes, &nsectors, &nheads, &ncyl);
1892 
1893         if ((page == 0x03) || (page == MODEPAGE_ALLPAGES)) {
1894                 p[n] = 0x03;
1895                 p[n+1] = 0x16;
1896                 if (ctrl != 1) {
1897                         p[n + 11] = nsectors;
1898                         p[n + 12] = nbytes >> 8;
1899                         p[n + 13] = nbytes & 0xff;
1900                         p[n + 20] = 0x80;
1901                 }
1902                 n += 24;
1903         }
1904         if ((page == 0x04) || (page == MODEPAGE_ALLPAGES)) {
1905                 p[n] = 0x04;
1906                 p[n + 1] = 0x16;
1907                 if (ctrl != 1) {
1908                         p[n + 2] = ncyl >> 16;
1909                         p[n + 3] = ncyl >> 8;
1910                         p[n + 4] = ncyl & 0xff;
1911                         p[n + 5] = nheads;
1912                         p[n + 20] = 0x15;
1913                         p[n + 21] = 0x18;
1914                 }
1915                 n += 24;
1916         }
1917         if ((page == MODEPAGE_CACHING) || (page == MODEPAGE_ALLPAGES)) {
1918                 struct mode_caching *mode_caching_page;
1919 
1920                 mode_caching_page = (struct mode_caching *)&p[n];
1921 
1922                 mode_caching_page->mode_page.code = MODEPAGE_CACHING;
1923                 mode_caching_page->mode_page.ps = 1; /* A saveable page */
1924                 mode_caching_page->mode_page.length = 0x12;
1925 
1926                 switch (ctrl) {
1927                 case (0):
1928                         /* Current */
1929                         if ((sl->sl_flags & SL_WRITEBACK_CACHE_DISABLE) == 0) {
1930                                 mode_caching_page->wce = 1;
1931                         }
1932                         break;
1933 
1934                 case (1):
1935                         /* Changeable */
1936                         if ((sl->sl_flags &
1937                             SL_WRITEBACK_CACHE_SET_UNSUPPORTED) == 0) {
1938                                 mode_caching_page->wce = 1;
1939                         }
1940                         break;
1941 
1942                 default:
1943                         if ((sl->sl_flags &
1944                             SL_SAVED_WRITE_CACHE_DISABLE) == 0) {
1945                                 mode_caching_page->wce = 1;
1946                         }
1947                         break;
1948                 }
1949                 n += (sizeof (struct mode_page) +
1950                     mode_caching_page->mode_page.length);
1951         }
1952         if ((page == MODEPAGE_CTRL_MODE) || (page == MODEPAGE_ALLPAGES)) {
1953                 struct mode_control_scsi3 *mode_control_page;
1954 
1955                 mode_control_page = (struct mode_control_scsi3 *)&p[n];
1956 
1957                 mode_control_page->mode_page.code = MODEPAGE_CTRL_MODE;
1958                 mode_control_page->mode_page.length =
1959                     PAGELENGTH_MODE_CONTROL_SCSI3;
1960                 if (ctrl != 1) {
1961                         /* If not looking for changeable values, report this. */
1962                         mode_control_page->que_mod = CTRL_QMOD_UNRESTRICT;
1963                 }
1964                 n += (sizeof (struct mode_page) +
1965                     mode_control_page->mode_page.length);
1966         }
1967 
1968         if (cdb[0] == SCMD_MODE_SENSE) {
1969                 if (n > 255) {
1970                         stmf_scsilib_send_status(task, STATUS_CHECK,
1971                             STMF_SAA_INVALID_FIELD_IN_CDB);
1972                         return;
1973                 }
1974                 /*
1975                  * Mode parameter header length doesn't include the number
1976                  * of bytes in the length field, so adjust the count.
1977                  * Byte count minus header length field size.
1978                  */
1979                 buf[0] = (n - 1) & 0xff;
1980         } else {
1981                 /* Byte count minus header length field size. */
1982                 buf[1] = (n - 2) & 0xff;
1983                 buf[0] = ((n - 2) >> 8) & 0xff;
1984         }
1985 
1986         sbd_handle_short_read_transfers(task, initial_dbuf, buf,
1987             cmd_size, n);
1988 }
1989 
1990 void
1991 sbd_handle_mode_select(scsi_task_t *task, stmf_data_buf_t *dbuf)
1992 {
1993         uint32_t cmd_xfer_len;
1994 
1995         if (task->task_cdb[0] == SCMD_MODE_SELECT) {
1996                 cmd_xfer_len = (uint32_t)task->task_cdb[4];
1997         } else {
1998                 cmd_xfer_len = READ_SCSI16(&task->task_cdb[7], uint32_t);
1999         }
2000 
2001         if ((task->task_cdb[1] & 0xFE) != 0x10) {
2002                 stmf_scsilib_send_status(task, STATUS_CHECK,
2003                     STMF_SAA_INVALID_FIELD_IN_CDB);
2004                 return;
2005         }
2006 
2007         if (cmd_xfer_len == 0) {
2008                 /* zero byte mode selects are allowed */
2009                 stmf_scsilib_send_status(task, STATUS_GOOD, 0);
2010                 return;
2011         }
2012 
2013         sbd_handle_short_write_transfers(task, dbuf, cmd_xfer_len);
2014 }
2015 
2016 void
2017 sbd_handle_mode_select_xfer(scsi_task_t *task, uint8_t *buf, uint32_t buflen)
2018 {
2019         sbd_lu_t *sl = (sbd_lu_t *)task->task_lu->lu_provider_private;
2020         sbd_it_data_t *it;
2021         int hdr_len, bd_len;
2022         sbd_status_t sret;
2023         int i;
2024 
2025         if (task->task_cdb[0] == SCMD_MODE_SELECT) {
2026                 hdr_len = 4;
2027         } else {
2028                 hdr_len = 8;
2029         }
2030 
2031         if (buflen < hdr_len)
2032                 goto mode_sel_param_len_err;
2033 
2034         bd_len = hdr_len == 4 ? buf[3] : READ_SCSI16(&buf[6], int);
2035 
2036         if (buflen < (hdr_len + bd_len + 2))
2037                 goto mode_sel_param_len_err;
2038 
2039         buf += hdr_len + bd_len;
2040         buflen -= hdr_len + bd_len;
2041 
2042         if ((buf[0] != 8) || (buflen != ((uint32_t)buf[1] + 2))) {
2043                 goto mode_sel_param_len_err;
2044         }
2045 
2046         if (buf[2] & 0xFB) {
2047                 goto mode_sel_param_field_err;
2048         }
2049 
2050         for (i = 3; i < (buf[1] + 2); i++) {
2051                 if (buf[i]) {
2052                         goto mode_sel_param_field_err;
2053                 }
2054         }
2055 
2056         sret = SBD_SUCCESS;
2057 
2058         /* All good. Lets handle the write cache change, if any */
2059         if (buf[2] & BIT_2) {
2060                 sret = sbd_wcd_set(0, sl);
2061         } else {
2062                 sret = sbd_wcd_set(1, sl);
2063         }
2064 
2065         if (sret != SBD_SUCCESS) {
2066                 stmf_scsilib_send_status(task, STATUS_CHECK,
2067                     STMF_SAA_WRITE_ERROR);
2068                 return;
2069         }
2070 
2071         /* set on the device passed, now set the flags */
2072         mutex_enter(&sl->sl_lock);
2073         if (buf[2] & BIT_2) {
2074                 sl->sl_flags &= ~SL_WRITEBACK_CACHE_DISABLE;
2075         } else {
2076                 sl->sl_flags |= SL_WRITEBACK_CACHE_DISABLE;
2077         }
2078 
2079         for (it = sl->sl_it_list; it != NULL; it = it->sbd_it_next) {
2080                 if (it == task->task_lu_itl_handle)
2081                         continue;
2082                 it->sbd_it_ua_conditions |= SBD_UA_MODE_PARAMETERS_CHANGED;
2083         }
2084 
2085         if (task->task_cdb[1] & 1) {
2086                 if (buf[2] & BIT_2) {
2087                         sl->sl_flags &= ~SL_SAVED_WRITE_CACHE_DISABLE;
2088                 } else {
2089                         sl->sl_flags |= SL_SAVED_WRITE_CACHE_DISABLE;
2090                 }
2091                 mutex_exit(&sl->sl_lock);
2092                 sret = sbd_write_lu_info(sl);
2093         } else {
2094                 mutex_exit(&sl->sl_lock);
2095         }
2096         if (sret == SBD_SUCCESS) {
2097                 stmf_scsilib_send_status(task, STATUS_GOOD, 0);
2098         } else {
2099                 stmf_scsilib_send_status(task, STATUS_CHECK,
2100                     STMF_SAA_WRITE_ERROR);
2101         }
2102         return;
2103 
2104 mode_sel_param_len_err:
2105         stmf_scsilib_send_status(task, STATUS_CHECK,
2106             STMF_SAA_PARAM_LIST_LENGTH_ERROR);
2107         return;
2108 mode_sel_param_field_err:
2109         stmf_scsilib_send_status(task, STATUS_CHECK,
2110             STMF_SAA_INVALID_FIELD_IN_PARAM_LIST);
2111 }
2112 
2113 /*
2114  * Command support added from SPC-4 r24
2115  * Supports info type 0, 2, 127
2116  */
2117 void
2118 sbd_handle_identifying_info(struct scsi_task *task,
2119     stmf_data_buf_t *initial_dbuf)
2120 {
2121         sbd_lu_t *sl = (sbd_lu_t *)task->task_lu->lu_provider_private;
2122         uint8_t *cdb;
2123         uint32_t cmd_size;
2124         uint32_t param_len;
2125         uint32_t xfer_size;
2126         uint8_t info_type;
2127         uint8_t *buf, *p;
2128 
2129         cdb = &task->task_cdb[0];
2130         cmd_size = READ_SCSI32(&cdb[6], uint32_t);
2131         info_type = cdb[10]>>1;
2132 
2133         /* Validate the command */
2134         if (cmd_size < 4) {
2135                 stmf_scsilib_send_status(task, STATUS_CHECK,
2136                     STMF_SAA_INVALID_FIELD_IN_CDB);
2137                 return;
2138         }
2139 
2140         p = buf = kmem_zalloc(260, KM_SLEEP);
2141 
2142         switch (info_type) {
2143                 case 0:
2144                         /*
2145                          * No value is supplied but this info type
2146                          * is mandatory.
2147                          */
2148                         xfer_size = 4;
2149                         break;
2150                 case 2:
2151                         mutex_enter(&sl->sl_lock);
2152                         param_len = strlcpy((char *)(p+4), sl->sl_alias, 256);
2153                         mutex_exit(&sl->sl_lock);
2154                         /* text info must be null terminated */
2155                         if (++param_len > 256)
2156                                 param_len = 256;
2157                         SCSI_WRITE16(p+2, param_len);
2158                         xfer_size = param_len + 4;
2159                         break;
2160                 case 127:
2161                         /* 0 and 2 descriptor supported */
2162                         SCSI_WRITE16(p+2, 8); /* set param length */
2163                         p += 8;
2164                         *p = 4; /* set type to 2 (7 hi bits) */
2165                         p += 2;
2166                         SCSI_WRITE16(p, 256); /* 256 max length */
2167                         xfer_size = 12;
2168                         break;
2169                 default:
2170                         stmf_scsilib_send_status(task, STATUS_CHECK,
2171                             STMF_SAA_INVALID_FIELD_IN_CDB);
2172                         kmem_free(buf, 260);
2173                         return;
2174         }
2175         sbd_handle_short_read_transfers(task, initial_dbuf, buf,
2176             cmd_size, xfer_size);
2177         kmem_free(buf, 260);
2178 }
2179 
2180 /*
2181  * This function parse through a string, passed to it as a pointer to a string,
2182  * by adjusting the pointer to the first non-space character and returns
2183  * the count/length of the first bunch of non-space characters. Multiple
2184  * Management URLs are stored as a space delimited string in sl_mgmt_url
2185  * field of sbd_lu_t. This function is used to retrieve one url at a time.
2186  *
2187  * i/p : pointer to pointer to a url string
2188  * o/p : Adjust the pointer to the url to the first non white character
2189  *       and returns the length of the URL
2190  */
2191 uint16_t
2192 sbd_parse_mgmt_url(char **url_addr) {
2193         uint16_t url_length = 0;
2194         char *url;
2195         url = *url_addr;
2196 
2197         while (*url != '\0') {
2198                 if (*url == ' ' || *url == '\t' || *url == '\n') {
2199                         (*url_addr)++;
2200                         url = *url_addr;
2201                 } else {
2202                         break;
2203                 }
2204         }
2205 
2206         while (*url != '\0') {
2207                 if (*url == ' ' || *url == '\t' ||
2208                     *url == '\n' || *url == '\0') {
2209                         break;
2210                 }
2211                 url++;
2212                 url_length++;
2213         }
2214         return (url_length);
2215 }
2216 
2217 /* Try to make this the size of a kmem allocation cache. */
2218 static uint_t sbd_write_same_optimal_chunk = 128 * 1024;
2219 
2220 static sbd_status_t
2221 sbd_write_same_data(struct scsi_task *task, sbd_cmd_t *scmd)
2222 {
2223         sbd_lu_t *sl = (sbd_lu_t *)task->task_lu->lu_provider_private;
2224         uint64_t addr, len, sz_done;
2225         uint32_t big_buf_size, xfer_size, off;
2226         uint8_t *big_buf;
2227         sbd_status_t ret;
2228 
2229         if (task->task_cdb[0] == SCMD_WRITE_SAME_G1) {
2230                 addr = READ_SCSI32(&task->task_cdb[2], uint64_t);
2231                 len = READ_SCSI16(&task->task_cdb[7], uint64_t);
2232         } else {
2233                 addr = READ_SCSI64(&task->task_cdb[2], uint64_t);
2234                 len = READ_SCSI32(&task->task_cdb[10], uint64_t);
2235         }
2236         addr <<= sl->sl_data_blocksize_shift;
2237         len <<= sl->sl_data_blocksize_shift;
2238 
2239         /*
2240          * Reminders:
2241          *    "len" is total size of what we wish to "write same".
2242          *
2243          *    xfer_size will be scmd->trans_data_len, which is the length
2244          *    of the pattern we wish to replicate over "len".  We replicate
2245          *    "xfer_size" of pattern over "len".
2246          *
2247          *    big_buf_size is set to an ideal actual-write size for an output
2248          *    operation.  It may be the same as "len".  If it's not, it should
2249          *    be an exact multiple of "xfer_size" so we don't get pattern
2250          *    breakage until the very end of "len".
2251          */
2252         big_buf_size = len > sbd_write_same_optimal_chunk ?
2253             sbd_write_same_optimal_chunk : (uint32_t)len;
2254         xfer_size = scmd->trans_data_len;
2255 
2256         /*
2257          * All transfers should be an integral multiple of the sector size.
2258          */
2259         ASSERT((big_buf_size % xfer_size) == 0);
2260 
2261         /*
2262          * Don't sleep for the allocation, and don't make the system
2263          * reclaim memory.  Trade higher I/Os if in a low-memory situation.
2264          */
2265         big_buf = kmem_alloc(big_buf_size, KM_NOSLEEP | KM_NORMALPRI);
2266 
2267         if (big_buf == NULL) {
2268                 /*
2269                  * Just send it in terms of of the transmitted data.  This
2270                  * will be very slow.
2271                  */
2272                 DTRACE_PROBE1(write__same__low__memory, uint64_t, big_buf_size);
2273                 big_buf = scmd->trans_data;
2274                 big_buf_size = scmd->trans_data_len;
2275         } else {
2276                 /*
2277                  * We already ASSERT()ed big_buf_size is an integral multiple
2278                  * of xfer_size.
2279                  */
2280                 for (off = 0; off < big_buf_size; off += xfer_size)
2281                         bcopy(scmd->trans_data, big_buf + off, xfer_size);
2282         }
2283 
2284         /* Do the actual I/O.  Recycle xfer_size now to be write size. */
2285         DTRACE_PROBE1(write__same__io__begin, uint64_t, len);
2286         for (sz_done = 0; sz_done < len; sz_done += (uint64_t)xfer_size) {
2287                 xfer_size = ((big_buf_size + sz_done) <= len) ? big_buf_size :
2288                     len - sz_done;
2289                 ret = sbd_data_write(sl, task, addr + sz_done,
2290                     (uint64_t)xfer_size, big_buf);
2291                 if (ret != SBD_SUCCESS)
2292                         break;
2293         }
2294         DTRACE_PROBE2(write__same__io__end, uint64_t, len, uint64_t, sz_done);
2295 
2296         if (big_buf != scmd->trans_data)
2297                 kmem_free(big_buf, big_buf_size);
2298 
2299         return (ret);
2300 }
2301 
2302 static void
2303 sbd_handle_write_same_xfer_completion(struct scsi_task *task, sbd_cmd_t *scmd,
2304     struct stmf_data_buf *dbuf, uint8_t dbuf_reusable)
2305 {
2306         uint64_t laddr;
2307         uint32_t buflen, iolen;
2308         int ndx, ret;
2309 
2310         if (dbuf->db_xfer_status != STMF_SUCCESS) {
2311                 stmf_abort(STMF_QUEUE_TASK_ABORT, task,
2312                     dbuf->db_xfer_status, NULL);
2313                 return;
2314         }
2315 
2316         if (scmd->flags & SBD_SCSI_CMD_XFER_FAIL) {
2317                 goto write_same_xfer_done;
2318         }
2319 
2320         if (scmd->len != 0) {
2321                 /*
2322                  * Initiate the next port xfer to occur in parallel
2323                  * with writing this buf.
2324                  */
2325                 sbd_do_write_same_xfer(task, scmd, NULL, 0);
2326         }
2327 
2328         laddr = dbuf->db_relative_offset;
2329 
2330         for (buflen = 0, ndx = 0; (buflen < dbuf->db_data_size) &&
2331             (ndx < dbuf->db_sglist_length); ndx++) {
2332                 iolen = min(dbuf->db_data_size - buflen,
2333                     dbuf->db_sglist[ndx].seg_length);
2334                 if (iolen == 0)
2335                         break;
2336                 bcopy(dbuf->db_sglist[ndx].seg_addr, &scmd->trans_data[laddr],
2337                     iolen);
2338                 buflen += iolen;
2339                 laddr += (uint64_t)iolen;
2340         }
2341         task->task_nbytes_transferred += buflen;
2342 
2343 write_same_xfer_done:
2344         if (scmd->len == 0 || scmd->flags & SBD_SCSI_CMD_XFER_FAIL) {
2345                 stmf_free_dbuf(task, dbuf);
2346                 scmd->flags &= ~SBD_SCSI_CMD_ACTIVE;
2347                 if (scmd->flags & SBD_SCSI_CMD_XFER_FAIL) {
2348                         stmf_scsilib_send_status(task, STATUS_CHECK,
2349                             STMF_SAA_WRITE_ERROR);
2350                 } else {
2351                         ret = sbd_write_same_data(task, scmd);
2352                         if (ret != SBD_SUCCESS) {
2353                                 stmf_scsilib_send_status(task, STATUS_CHECK,
2354                                     STMF_SAA_WRITE_ERROR);
2355                         } else {
2356                                 stmf_scsilib_send_status(task, STATUS_GOOD, 0);
2357                         }
2358                 }
2359                 /*
2360                  * Only way we should get here is via handle_write_same(),
2361                  * and that should make the following assertion always pass.
2362                  */
2363                 ASSERT((scmd->flags & SBD_SCSI_CMD_TRANS_DATA) &&
2364                     scmd->trans_data != NULL);
2365                 kmem_free(scmd->trans_data, scmd->trans_data_len);
2366                 scmd->flags &= ~SBD_SCSI_CMD_TRANS_DATA;
2367                 return;
2368         }
2369         sbd_do_write_same_xfer(task, scmd, dbuf, dbuf_reusable);
2370 }
2371 
2372 static void
2373 sbd_do_write_same_xfer(struct scsi_task *task, sbd_cmd_t *scmd,
2374     struct stmf_data_buf *dbuf, uint8_t dbuf_reusable)
2375 {
2376         uint32_t len;
2377 
2378         if (scmd->len == 0) {
2379                 if (dbuf != NULL)
2380                         stmf_free_dbuf(task, dbuf);
2381                 return;
2382         }
2383 
2384         if ((dbuf != NULL) &&
2385             ((dbuf->db_flags & DB_DONT_REUSE) || (dbuf_reusable == 0))) {
2386                 /* free current dbuf and allocate a new one */
2387                 stmf_free_dbuf(task, dbuf);
2388                 dbuf = NULL;
2389         }
2390         if (dbuf == NULL) {
2391                 uint32_t maxsize, minsize, old_minsize;
2392 
2393                 maxsize = (scmd->len > (128*1024)) ? 128*1024 :
2394                     scmd->len;
2395                 minsize = maxsize >> 2;
2396                 do {
2397                         old_minsize = minsize;
2398                         dbuf = stmf_alloc_dbuf(task, maxsize, &minsize, 0);
2399                 } while ((dbuf == NULL) && (old_minsize > minsize) &&
2400                     (minsize >= 512));
2401                 if (dbuf == NULL) {
2402                         if (scmd->nbufs == 0) {
2403                                 stmf_abort(STMF_QUEUE_TASK_ABORT, task,
2404                                     STMF_ALLOC_FAILURE, NULL);
2405                         }
2406                         return;
2407                 }
2408         }
2409 
2410         len = scmd->len > dbuf->db_buf_size ? dbuf->db_buf_size :
2411             scmd->len;
2412 
2413         dbuf->db_relative_offset = scmd->current_ro;
2414         dbuf->db_data_size = len;
2415         dbuf->db_flags = DB_DIRECTION_FROM_RPORT;
2416         (void) stmf_xfer_data(task, dbuf, 0);
2417         scmd->nbufs++; /* outstanding port xfers and bufs used */
2418         scmd->len -= len;
2419         scmd->current_ro += len;
2420 }
2421 
2422 static void
2423 sbd_handle_write_same(scsi_task_t *task, struct stmf_data_buf *initial_dbuf)
2424 {
2425         sbd_lu_t *sl = (sbd_lu_t *)task->task_lu->lu_provider_private;
2426         uint64_t addr, len;
2427         sbd_cmd_t *scmd;
2428         stmf_data_buf_t *dbuf;
2429         uint8_t unmap;
2430         uint8_t do_immediate_data = 0;
2431 
2432         task->task_cmd_xfer_length = 0;
2433         if (task->task_additional_flags &
2434             TASK_AF_NO_EXPECTED_XFER_LENGTH) {
2435                 task->task_expected_xfer_length = 0;
2436         }
2437         if (sl->sl_flags & SL_WRITE_PROTECTED) {
2438                 stmf_scsilib_send_status(task, STATUS_CHECK,
2439                     STMF_SAA_WRITE_PROTECTED);
2440                 return;
2441         }
2442         if (task->task_cdb[1] & 0xF7) {
2443                 stmf_scsilib_send_status(task, STATUS_CHECK,
2444                     STMF_SAA_INVALID_FIELD_IN_CDB);
2445                 return;
2446         }
2447         unmap = task->task_cdb[1] & 0x08;
2448         if (unmap && ((sl->sl_flags & SL_UNMAP_ENABLED) == 0)) {
2449                 stmf_scsilib_send_status(task, STATUS_CHECK,
2450                     STMF_SAA_INVALID_FIELD_IN_CDB);
2451                 return;
2452         }
2453         if (task->task_cdb[0] == SCMD_WRITE_SAME_G1) {
2454                 addr = READ_SCSI32(&task->task_cdb[2], uint64_t);
2455                 len = READ_SCSI16(&task->task_cdb[7], uint64_t);
2456         } else {
2457                 addr = READ_SCSI64(&task->task_cdb[2], uint64_t);
2458                 len = READ_SCSI32(&task->task_cdb[10], uint64_t);
2459         }
2460         if (len == 0) {
2461                 stmf_scsilib_send_status(task, STATUS_CHECK,
2462                     STMF_SAA_INVALID_FIELD_IN_CDB);
2463                 return;
2464         }
2465         addr <<= sl->sl_data_blocksize_shift;
2466         len <<= sl->sl_data_blocksize_shift;
2467 
2468         /* Check if the command is for the unmap function */
2469         if (unmap) {
2470                 if (sbd_unmap(sl, addr, len) != 0) {
2471                         stmf_scsilib_send_status(task, STATUS_CHECK,
2472                             STMF_SAA_LBA_OUT_OF_RANGE);
2473                 } else {
2474                         stmf_scsilib_send_status(task, STATUS_GOOD, 0);
2475                 }
2476                 return;
2477         }
2478 
2479         /* Write same function */
2480 
2481         task->task_cmd_xfer_length = 1 << sl->sl_data_blocksize_shift;
2482         if (task->task_additional_flags &
2483             TASK_AF_NO_EXPECTED_XFER_LENGTH) {
2484                 task->task_expected_xfer_length = task->task_cmd_xfer_length;
2485         }
2486         if ((addr + len) > sl->sl_lu_size) {
2487                 stmf_scsilib_send_status(task, STATUS_CHECK,
2488                     STMF_SAA_LBA_OUT_OF_RANGE);
2489                 return;
2490         }
2491 
2492         /* For rest of this I/O the transfer length is 1 block */
2493         len = ((uint64_t)1) << sl->sl_data_blocksize_shift;
2494 
2495         /* Some basic checks */
2496         if ((len == 0) || (len != task->task_expected_xfer_length)) {
2497                 stmf_scsilib_send_status(task, STATUS_CHECK,
2498                     STMF_SAA_INVALID_FIELD_IN_CDB);
2499                 return;
2500         }
2501 
2502 
2503         if ((initial_dbuf != NULL) && (task->task_flags & TF_INITIAL_BURST)) {
2504                 if (initial_dbuf->db_data_size > len) {
2505                         if (initial_dbuf->db_data_size >
2506                             task->task_expected_xfer_length) {
2507                                 /* protocol error */
2508                                 stmf_abort(STMF_QUEUE_TASK_ABORT, task,
2509                                     STMF_INVALID_ARG, NULL);
2510                                 return;
2511                         }
2512                         initial_dbuf->db_data_size = (uint32_t)len;
2513                 }
2514                 do_immediate_data = 1;
2515         }
2516         dbuf = initial_dbuf;
2517 
2518         if (task->task_lu_private) {
2519                 scmd = (sbd_cmd_t *)task->task_lu_private;
2520         } else {
2521                 scmd = (sbd_cmd_t *)kmem_alloc(sizeof (sbd_cmd_t), KM_SLEEP);
2522                 task->task_lu_private = scmd;
2523         }
2524         scmd->flags = SBD_SCSI_CMD_ACTIVE | SBD_SCSI_CMD_TRANS_DATA;
2525         scmd->cmd_type = SBD_CMD_SCSI_WRITE;
2526         scmd->nbufs = 0;
2527         scmd->len = (uint32_t)len;
2528         scmd->trans_data_len = (uint32_t)len;
2529         scmd->trans_data = kmem_alloc((size_t)len, KM_SLEEP);
2530         scmd->current_ro = 0;
2531 
2532         if (do_immediate_data) {
2533                 /*
2534                  * Account for data passed in this write command
2535                  */
2536                 (void) stmf_xfer_data(task, dbuf, STMF_IOF_STATS_ONLY);
2537                 scmd->len -= dbuf->db_data_size;
2538                 scmd->current_ro += dbuf->db_data_size;
2539                 dbuf->db_xfer_status = STMF_SUCCESS;
2540                 sbd_handle_write_same_xfer_completion(task, scmd, dbuf, 0);
2541         } else {
2542                 sbd_do_write_same_xfer(task, scmd, dbuf, 0);
2543         }
2544 }
2545 
2546 static void
2547 sbd_handle_unmap(scsi_task_t *task, stmf_data_buf_t *dbuf)
2548 {
2549         uint32_t cmd_xfer_len;
2550 
2551         cmd_xfer_len = READ_SCSI16(&task->task_cdb[7], uint32_t);
2552 
2553         if (task->task_cdb[1] & 1) {
2554                 stmf_scsilib_send_status(task, STATUS_CHECK,
2555                     STMF_SAA_INVALID_FIELD_IN_CDB);
2556                 return;
2557         }
2558 
2559         if (cmd_xfer_len == 0) {
2560                 task->task_cmd_xfer_length = 0;
2561                 if (task->task_additional_flags &
2562                     TASK_AF_NO_EXPECTED_XFER_LENGTH) {
2563                         task->task_expected_xfer_length = 0;
2564                 }
2565                 stmf_scsilib_send_status(task, STATUS_GOOD, 0);
2566                 return;
2567         }
2568 
2569         sbd_handle_short_write_transfers(task, dbuf, cmd_xfer_len);
2570 }
2571 
2572 static void
2573 sbd_handle_unmap_xfer(scsi_task_t *task, uint8_t *buf, uint32_t buflen)
2574 {
2575         sbd_lu_t *sl = (sbd_lu_t *)task->task_lu->lu_provider_private;
2576         uint32_t ulen, dlen, num_desc;
2577         uint64_t addr, len;
2578         uint8_t *p;
2579         int ret;
2580 
2581         if (buflen < 24) {
2582                 stmf_scsilib_send_status(task, STATUS_CHECK,
2583                     STMF_SAA_INVALID_FIELD_IN_CDB);
2584                 return;
2585         }
2586         ulen = READ_SCSI16(buf, uint32_t);
2587         dlen = READ_SCSI16(buf + 2, uint32_t);
2588         num_desc = dlen >> 4;
2589         if (((ulen + 2) != buflen) || ((dlen + 8) != buflen) || (dlen & 0xf) ||
2590             (num_desc == 0)) {
2591                 stmf_scsilib_send_status(task, STATUS_CHECK,
2592                     STMF_SAA_INVALID_FIELD_IN_CDB);
2593                 return;
2594         }
2595 
2596         for (p = buf + 8; num_desc; num_desc--, p += 16) {
2597                 addr = READ_SCSI64(p, uint64_t);
2598                 addr <<= sl->sl_data_blocksize_shift;
2599                 len = READ_SCSI32(p+8, uint64_t);
2600                 len <<= sl->sl_data_blocksize_shift;
2601                 ret = sbd_unmap(sl, addr, len);
2602                 if (ret != 0) {
2603                         stmf_scsilib_send_status(task, STATUS_CHECK,
2604                             STMF_SAA_LBA_OUT_OF_RANGE);
2605                         return;
2606                 }
2607         }
2608 
2609 unmap_done:
2610         stmf_scsilib_send_status(task, STATUS_GOOD, 0);
2611 }
2612 
2613 void
2614 sbd_handle_inquiry(struct scsi_task *task, struct stmf_data_buf *initial_dbuf)
2615 {
2616         sbd_lu_t *sl = (sbd_lu_t *)task->task_lu->lu_provider_private;
2617         uint8_t *cdbp = (uint8_t *)&task->task_cdb[0];
2618         uint8_t *p;
2619         uint8_t byte0;
2620         uint8_t page_length;
2621         uint16_t bsize = 512;
2622         uint16_t cmd_size;
2623         uint32_t xfer_size = 4;
2624         uint32_t mgmt_url_size = 0;
2625         uint8_t exp;
2626         uint64_t s;
2627         char *mgmt_url = NULL;
2628 
2629 
2630         byte0 = DTYPE_DIRECT;
2631         /*
2632          * Basic protocol checks.
2633          */
2634 
2635         if ((((cdbp[1] & 1) == 0) && cdbp[2]) || cdbp[5]) {
2636                 stmf_scsilib_send_status(task, STATUS_CHECK,
2637                     STMF_SAA_INVALID_FIELD_IN_CDB);
2638                 return;
2639         }
2640 
2641         /*
2642          * Zero byte allocation length is not an error.  Just
2643          * return success.
2644          */
2645 
2646         cmd_size = (((uint16_t)cdbp[3]) << 8) | cdbp[4];
2647 
2648         if (cmd_size == 0) {
2649                 task->task_cmd_xfer_length = 0;
2650                 if (task->task_additional_flags &
2651                     TASK_AF_NO_EXPECTED_XFER_LENGTH) {
2652                         task->task_expected_xfer_length = 0;
2653                 }
2654                 stmf_scsilib_send_status(task, STATUS_GOOD, 0);
2655                 return;
2656         }
2657 
2658         /*
2659          * Standard inquiry
2660          */
2661 
2662         if ((cdbp[1] & 1) == 0) {
2663                 int     i;
2664                 struct scsi_inquiry *inq;
2665 
2666                 p = (uint8_t *)kmem_zalloc(bsize, KM_SLEEP);
2667                 inq = (struct scsi_inquiry *)p;
2668 
2669                 page_length = 69;
2670                 xfer_size = page_length + 5;
2671 
2672                 inq->inq_dtype = DTYPE_DIRECT;
2673                 inq->inq_ansi = 5;   /* SPC-3 */
2674                 inq->inq_hisup = 1;
2675                 inq->inq_rdf = 2;    /* Response data format for SPC-3 */
2676                 inq->inq_len = page_length;
2677 
2678                 inq->inq_tpgs = TPGS_FAILOVER_IMPLICIT;
2679                 inq->inq_cmdque = 1;
2680 
2681                 if (sl->sl_flags & SL_VID_VALID) {
2682                         bcopy(sl->sl_vendor_id, inq->inq_vid, 8);
2683                 } else {
2684                         bcopy(sbd_vendor_id, inq->inq_vid, 8);
2685                 }
2686 
2687                 if (sl->sl_flags & SL_PID_VALID) {
2688                         bcopy(sl->sl_product_id, inq->inq_pid, 16);
2689                 } else {
2690                         bcopy(sbd_product_id, inq->inq_pid, 16);
2691                 }
2692 
2693                 if (sl->sl_flags & SL_REV_VALID) {
2694                         bcopy(sl->sl_revision, inq->inq_revision, 4);
2695                 } else {
2696                         bcopy(sbd_revision, inq->inq_revision, 4);
2697                 }
2698 
2699                 /* Adding Version Descriptors */
2700                 i = 0;
2701                 /* SAM-3 no version */
2702                 inq->inq_vd[i].inq_vd_msb = 0x00;
2703                 inq->inq_vd[i].inq_vd_lsb = 0x60;
2704                 i++;
2705 
2706                 /* transport */
2707                 switch (task->task_lport->lport_id->protocol_id) {
2708                 case PROTOCOL_FIBRE_CHANNEL:
2709                         inq->inq_vd[i].inq_vd_msb = 0x09;
2710                         inq->inq_vd[i].inq_vd_lsb = 0x00;
2711                         i++;
2712                         break;
2713 
2714                 case PROTOCOL_PARALLEL_SCSI:
2715                 case PROTOCOL_SSA:
2716                 case PROTOCOL_IEEE_1394:
2717                         /* Currently no claims of conformance */
2718                         break;
2719 
2720                 case PROTOCOL_SRP:
2721                         inq->inq_vd[i].inq_vd_msb = 0x09;
2722                         inq->inq_vd[i].inq_vd_lsb = 0x40;
2723                         i++;
2724                         break;
2725 
2726                 case PROTOCOL_iSCSI:
2727                         inq->inq_vd[i].inq_vd_msb = 0x09;
2728                         inq->inq_vd[i].inq_vd_lsb = 0x60;
2729                         i++;
2730                         break;
2731 
2732                 case PROTOCOL_SAS:
2733                 case PROTOCOL_ADT:
2734                 case PROTOCOL_ATAPI:
2735                 default:
2736                         /* Currently no claims of conformance */
2737                         break;
2738                 }
2739 
2740                 /* SPC-3 no version */
2741                 inq->inq_vd[i].inq_vd_msb = 0x03;
2742                 inq->inq_vd[i].inq_vd_lsb = 0x00;
2743                 i++;
2744 
2745                 /* SBC-2 no version */
2746                 inq->inq_vd[i].inq_vd_msb = 0x03;
2747                 inq->inq_vd[i].inq_vd_lsb = 0x20;
2748 
2749                 sbd_handle_short_read_transfers(task, initial_dbuf, p, cmd_size,
2750                     min(cmd_size, xfer_size));
2751                 kmem_free(p, bsize);
2752 
2753                 return;
2754         }
2755 
2756         rw_enter(&sbd_global_prop_lock, RW_READER);
2757         if (sl->sl_mgmt_url) {
2758                 mgmt_url_size = strlen(sl->sl_mgmt_url);
2759                 mgmt_url = sl->sl_mgmt_url;
2760         } else if (sbd_mgmt_url) {
2761                 mgmt_url_size = strlen(sbd_mgmt_url);
2762                 mgmt_url = sbd_mgmt_url;
2763         }
2764 
2765         /*
2766          * EVPD handling
2767          */
2768 
2769         /* Default 512 bytes may not be enough, increase bsize if necessary */
2770         if (cdbp[2] == 0x83 || cdbp[2] == 0x85) {
2771                 if (bsize <  cmd_size)
2772                         bsize = cmd_size;
2773         }
2774         p = (uint8_t *)kmem_zalloc(bsize, KM_SLEEP);
2775 
2776         switch (cdbp[2]) {
2777         case 0x00:
2778                 page_length = 4 + (mgmt_url_size ? 1 : 0);
2779                 if (sl->sl_flags & SL_UNMAP_ENABLED)
2780                         page_length += 2;
2781 
2782                 p[0] = byte0;
2783                 p[3] = page_length;
2784                 /* Supported VPD pages in ascending order */
2785                 {
2786                         uint8_t i = 5;
2787 
2788                         p[i++] = 0x80;
2789                         p[i++] = 0x83;
2790                         if (mgmt_url_size != 0)
2791                                 p[i++] = 0x85;
2792                         p[i++] = 0x86;
2793                         if (sl->sl_flags & SL_UNMAP_ENABLED) {
2794                                 p[i++] = 0xb0;
2795                                 p[i++] = 0xb2;
2796                         }
2797                 }
2798                 xfer_size = page_length + 4;
2799                 break;
2800 
2801         case 0x80:
2802                 if (sl->sl_serial_no_size) {
2803                         page_length = sl->sl_serial_no_size;
2804                         bcopy(sl->sl_serial_no, p + 4, sl->sl_serial_no_size);
2805                 } else {
2806                         /* if no serial num is specified set 4 spaces */
2807                         page_length = 4;
2808                         bcopy("    ", p + 4, 4);
2809                 }
2810                 p[0] = byte0;
2811                 p[1] = 0x80;
2812                 p[3] = page_length;
2813                 xfer_size = page_length + 4;
2814                 break;
2815 
2816         case 0x83:
2817                 xfer_size = stmf_scsilib_prepare_vpd_page83(task, p,
2818                     bsize, byte0, STMF_VPD_LU_ID|STMF_VPD_TARGET_ID|
2819                     STMF_VPD_TP_GROUP|STMF_VPD_RELATIVE_TP_ID);
2820                 break;
2821 
2822         case 0x85:
2823                 if (mgmt_url_size == 0) {
2824                         stmf_scsilib_send_status(task, STATUS_CHECK,
2825                             STMF_SAA_INVALID_FIELD_IN_CDB);
2826                         goto err_done;
2827                 }
2828                 {
2829                         uint16_t idx, newidx, sz, url_size;
2830                         char *url;
2831 
2832                         p[0] = byte0;
2833                         p[1] = 0x85;
2834 
2835                         idx = 4;
2836                         url = mgmt_url;
2837                         url_size = sbd_parse_mgmt_url(&url);
2838                         /* Creating Network Service Descriptors */
2839                         while (url_size != 0) {
2840                                 /* Null terminated and 4 Byte aligned */
2841                                 sz = url_size + 1;
2842                                 sz += (sz % 4) ? 4 - (sz % 4) : 0;
2843                                 newidx = idx + sz + 4;
2844 
2845                                 if (newidx < bsize) {
2846                                         /*
2847                                          * SPC-3r23 : Table 320  (Sec 7.6.5)
2848                                          * (Network service descriptor format
2849                                          *
2850                                          * Note: Hard coding service type as
2851                                          * "Storage Configuration Service".
2852                                          */
2853                                         p[idx] = 1;
2854                                         SCSI_WRITE16(p + idx + 2, sz);
2855                                         bcopy(url, p + idx + 4, url_size);
2856                                         xfer_size = newidx + 4;
2857                                 }
2858                                 idx = newidx;
2859 
2860                                 /* skip to next mgmt url if any */
2861                                 url += url_size;
2862                                 url_size = sbd_parse_mgmt_url(&url);
2863                         }
2864 
2865                         /* Total descriptor length */
2866                         SCSI_WRITE16(p + 2, idx - 4);
2867                         break;
2868                 }
2869 
2870         case 0x86:
2871                 page_length = 0x3c;
2872 
2873                 p[0] = byte0;
2874                 p[1] = 0x86;            /* Page 86 response */
2875                 p[3] = page_length;
2876 
2877                 /*
2878                  * Bits 0, 1, and 2 will need to be updated
2879                  * to reflect the queue tag handling if/when
2880                  * that is implemented.  For now, we're going
2881                  * to claim support only for Simple TA.
2882                  */
2883                 p[5] = 1;
2884                 xfer_size = page_length + 4;
2885                 break;
2886 
2887         case 0xb0:
2888                 if ((sl->sl_flags & SL_UNMAP_ENABLED) == 0) {
2889                         stmf_scsilib_send_status(task, STATUS_CHECK,
2890                             STMF_SAA_INVALID_FIELD_IN_CDB);
2891                         goto err_done;
2892                 }
2893                 page_length = 0x3c;
2894                 p[0] = byte0;
2895                 p[1] = 0xb0;
2896                 p[3] = page_length;
2897                 p[20] = p[21] = p[22] = p[23] = 0xFF;
2898                 p[24] = p[25] = p[26] = p[27] = 0xFF;
2899                 xfer_size = page_length + 4;
2900                 break;
2901 
2902         case 0xb2:
2903                 if ((sl->sl_flags & SL_UNMAP_ENABLED) == 0) {
2904                         stmf_scsilib_send_status(task, STATUS_CHECK,
2905                             STMF_SAA_INVALID_FIELD_IN_CDB);
2906                         goto err_done;
2907                 }
2908                 page_length = 4;
2909                 p[0] = byte0;
2910                 p[1] = 0xb2;
2911                 p[3] = page_length;
2912 
2913                 exp = (uint8_t)sl->sl_data_blocksize_shift;
2914                 s = sl->sl_lu_size >> sl->sl_data_blocksize_shift;
2915                 while (s & ((uint64_t)0xFFFFFFFF80000000ull)) {
2916                         s >>= 1;
2917                         exp++;
2918                 }
2919                 p[4] = exp;
2920                 p[5] = 0xc0;
2921                 xfer_size = page_length + 4;
2922                 break;
2923 
2924         default:
2925                 stmf_scsilib_send_status(task, STATUS_CHECK,
2926                     STMF_SAA_INVALID_FIELD_IN_CDB);
2927                 goto err_done;
2928         }
2929 
2930         sbd_handle_short_read_transfers(task, initial_dbuf, p, cmd_size,
2931             min(cmd_size, xfer_size));
2932 err_done:
2933         kmem_free(p, bsize);
2934         rw_exit(&sbd_global_prop_lock);
2935 }
2936 
2937 stmf_status_t
2938 sbd_task_alloc(struct scsi_task *task)
2939 {
2940         if ((task->task_lu_private =
2941             kmem_alloc(sizeof (sbd_cmd_t), KM_NOSLEEP)) != NULL) {
2942                 sbd_cmd_t *scmd = (sbd_cmd_t *)task->task_lu_private;
2943                 scmd->flags = 0;
2944                 return (STMF_SUCCESS);
2945         }
2946         return (STMF_ALLOC_FAILURE);
2947 }
2948 
2949 void
2950 sbd_remove_it_handle(sbd_lu_t *sl, sbd_it_data_t *it)
2951 {
2952         sbd_it_data_t **ppit;
2953 
2954         sbd_pgr_remove_it_handle(sl, it);
2955         mutex_enter(&sl->sl_lock);
2956         for (ppit = &sl->sl_it_list; *ppit != NULL;
2957             ppit = &((*ppit)->sbd_it_next)) {
2958                 if ((*ppit) == it) {
2959                         *ppit = it->sbd_it_next;
2960                         break;
2961                 }
2962         }
2963         mutex_exit(&sl->sl_lock);
2964 
2965         DTRACE_PROBE2(itl__nexus__end, stmf_lu_t *, sl->sl_lu,
2966             sbd_it_data_t *, it);
2967 
2968         kmem_free(it, sizeof (*it));
2969 }
2970 
2971 void
2972 sbd_check_and_clear_scsi2_reservation(sbd_lu_t *sl, sbd_it_data_t *it)
2973 {
2974         mutex_enter(&sl->sl_lock);
2975         if ((sl->sl_flags & SL_LU_HAS_SCSI2_RESERVATION) == 0) {
2976                 /* If we dont have any reservations, just get out. */
2977                 mutex_exit(&sl->sl_lock);
2978                 return;
2979         }
2980 
2981         if (it == NULL) {
2982                 /* Find the I_T nexus which is holding the reservation. */
2983                 for (it = sl->sl_it_list; it != NULL; it = it->sbd_it_next) {
2984                         if (it->sbd_it_flags & SBD_IT_HAS_SCSI2_RESERVATION) {
2985                                 ASSERT(it->sbd_it_session_id ==
2986                                     sl->sl_rs_owner_session_id);
2987                                 break;
2988                         }
2989                 }
2990                 ASSERT(it != NULL);
2991         } else {
2992                 /*
2993                  * We were passed an I_T nexus. If this nexus does not hold
2994                  * the reservation, do nothing. This is why this function is
2995                  * called "check_and_clear".
2996                  */
2997                 if ((it->sbd_it_flags & SBD_IT_HAS_SCSI2_RESERVATION) == 0) {
2998                         mutex_exit(&sl->sl_lock);
2999                         return;
3000                 }
3001         }
3002         it->sbd_it_flags &= ~SBD_IT_HAS_SCSI2_RESERVATION;
3003         sl->sl_flags &= ~SL_LU_HAS_SCSI2_RESERVATION;
3004         mutex_exit(&sl->sl_lock);
3005 }
3006 
3007 
3008 
3009 void
3010 sbd_new_task(struct scsi_task *task, struct stmf_data_buf *initial_dbuf)
3011 {
3012         sbd_lu_t *sl = (sbd_lu_t *)task->task_lu->lu_provider_private;
3013         sbd_it_data_t *it;
3014         uint8_t cdb0, cdb1;
3015         stmf_status_t st_ret;
3016 
3017         if ((it = task->task_lu_itl_handle) == NULL) {
3018                 mutex_enter(&sl->sl_lock);
3019                 for (it = sl->sl_it_list; it != NULL; it = it->sbd_it_next) {
3020                         if (it->sbd_it_session_id ==
3021                             task->task_session->ss_session_id) {
3022                                 mutex_exit(&sl->sl_lock);
3023                                 stmf_scsilib_send_status(task, STATUS_BUSY, 0);
3024                                 return;
3025                         }
3026                 }
3027                 it = (sbd_it_data_t *)kmem_zalloc(sizeof (*it), KM_NOSLEEP);
3028                 if (it == NULL) {
3029                         mutex_exit(&sl->sl_lock);
3030                         stmf_scsilib_send_status(task, STATUS_BUSY, 0);
3031                         return;
3032                 }
3033                 it->sbd_it_session_id = task->task_session->ss_session_id;
3034                 bcopy(task->task_lun_no, it->sbd_it_lun, 8);
3035                 it->sbd_it_next = sl->sl_it_list;
3036                 sl->sl_it_list = it;
3037                 mutex_exit(&sl->sl_lock);
3038 
3039                 DTRACE_PROBE1(itl__nexus__start, scsi_task *, task);
3040 
3041                 sbd_pgr_initialize_it(task, it);
3042                 if (stmf_register_itl_handle(task->task_lu, task->task_lun_no,
3043                     task->task_session, it->sbd_it_session_id, it)
3044                     != STMF_SUCCESS) {
3045                         sbd_remove_it_handle(sl, it);
3046                         stmf_scsilib_send_status(task, STATUS_BUSY, 0);
3047                         return;
3048                 }
3049                 task->task_lu_itl_handle = it;
3050                 if (sl->sl_access_state != SBD_LU_STANDBY) {
3051                         it->sbd_it_ua_conditions = SBD_UA_POR;
3052                 }
3053         } else if (it->sbd_it_flags & SBD_IT_PGR_CHECK_FLAG) {
3054                 mutex_enter(&sl->sl_lock);
3055                 it->sbd_it_flags &= ~SBD_IT_PGR_CHECK_FLAG;
3056                 mutex_exit(&sl->sl_lock);
3057                 sbd_pgr_initialize_it(task, it);
3058         }
3059 
3060         if (task->task_mgmt_function) {
3061                 stmf_scsilib_handle_task_mgmt(task);
3062                 return;
3063         }
3064 
3065         /*
3066          * if we're transitioning between access
3067          * states, return NOT READY
3068          */
3069         if (sl->sl_access_state == SBD_LU_TRANSITION_TO_STANDBY ||
3070             sl->sl_access_state == SBD_LU_TRANSITION_TO_ACTIVE) {
3071                 stmf_scsilib_send_status(task, STATUS_CHECK,
3072                     STMF_SAA_LU_NO_ACCESS_UNAVAIL);
3073                 return;
3074         }
3075 
3076         /* Checking ua conditions as per SAM3R14 5.3.2 specified order */
3077         if ((it->sbd_it_ua_conditions) && (task->task_cdb[0] != SCMD_INQUIRY)) {
3078                 uint32_t saa = 0;
3079 
3080                 mutex_enter(&sl->sl_lock);
3081                 if (it->sbd_it_ua_conditions & SBD_UA_POR) {
3082                         it->sbd_it_ua_conditions &= ~SBD_UA_POR;
3083                         saa = STMF_SAA_POR;
3084                 }
3085                 mutex_exit(&sl->sl_lock);
3086                 if (saa) {
3087                         stmf_scsilib_send_status(task, STATUS_CHECK, saa);
3088                         return;
3089                 }
3090         }
3091 
3092         /* Reservation conflict checks */
3093         if (sl->sl_access_state == SBD_LU_ACTIVE) {
3094                 if (SBD_PGR_RSVD(sl->sl_pgr)) {
3095                         if (sbd_pgr_reservation_conflict(task)) {
3096                                 stmf_scsilib_send_status(task,
3097                                     STATUS_RESERVATION_CONFLICT, 0);
3098                                 return;
3099                         }
3100                 } else if ((sl->sl_flags & SL_LU_HAS_SCSI2_RESERVATION) &&
3101                     ((it->sbd_it_flags & SBD_IT_HAS_SCSI2_RESERVATION) == 0)) {
3102                         if (!(SCSI2_CONFLICT_FREE_CMDS(task->task_cdb))) {
3103                                 stmf_scsilib_send_status(task,
3104                                     STATUS_RESERVATION_CONFLICT, 0);
3105                                 return;
3106                         }
3107                 }
3108         }
3109 
3110         /* Rest of the ua conndition checks */
3111         if ((it->sbd_it_ua_conditions) && (task->task_cdb[0] != SCMD_INQUIRY)) {
3112                 uint32_t saa = 0;
3113 
3114                 mutex_enter(&sl->sl_lock);
3115                 if (it->sbd_it_ua_conditions & SBD_UA_CAPACITY_CHANGED) {
3116                         it->sbd_it_ua_conditions &= ~SBD_UA_CAPACITY_CHANGED;
3117                         if ((task->task_cdb[0] == SCMD_READ_CAPACITY) ||
3118                             ((task->task_cdb[0] == SCMD_SVC_ACTION_IN_G4) &&
3119                             (task->task_cdb[1] ==
3120                             SSVC_ACTION_READ_CAPACITY_G4))) {
3121                                 saa = 0;
3122                         } else {
3123                                 saa = STMF_SAA_CAPACITY_DATA_HAS_CHANGED;
3124                         }
3125                 } else if (it->sbd_it_ua_conditions &
3126                     SBD_UA_MODE_PARAMETERS_CHANGED) {
3127                         it->sbd_it_ua_conditions &=
3128                             ~SBD_UA_MODE_PARAMETERS_CHANGED;
3129                         saa = STMF_SAA_MODE_PARAMETERS_CHANGED;
3130                 } else if (it->sbd_it_ua_conditions &
3131                     SBD_UA_ASYMMETRIC_ACCESS_CHANGED) {
3132                         it->sbd_it_ua_conditions &=
3133                             ~SBD_UA_ASYMMETRIC_ACCESS_CHANGED;
3134                         saa = STMF_SAA_ASYMMETRIC_ACCESS_CHANGED;
3135                 } else if (it->sbd_it_ua_conditions &
3136                     SBD_UA_ACCESS_STATE_TRANSITION) {
3137                         it->sbd_it_ua_conditions &=
3138                             ~SBD_UA_ACCESS_STATE_TRANSITION;
3139                         saa = STMF_SAA_LU_NO_ACCESS_TRANSITION;
3140                 } else {
3141                         it->sbd_it_ua_conditions = 0;
3142                         saa = 0;
3143                 }
3144                 mutex_exit(&sl->sl_lock);
3145                 if (saa) {
3146                         stmf_scsilib_send_status(task, STATUS_CHECK, saa);
3147                         return;
3148                 }
3149         }
3150 
3151         cdb0 = task->task_cdb[0];
3152         cdb1 = task->task_cdb[1];
3153 
3154         if (sl->sl_access_state == SBD_LU_STANDBY) {
3155                 if (cdb0 != SCMD_INQUIRY &&
3156                     cdb0 != SCMD_MODE_SENSE &&
3157                     cdb0 != SCMD_MODE_SENSE_G1 &&
3158                     cdb0 != SCMD_MODE_SELECT &&
3159                     cdb0 != SCMD_MODE_SELECT_G1 &&
3160                     cdb0 != SCMD_RESERVE &&
3161                     cdb0 != SCMD_RELEASE &&
3162                     cdb0 != SCMD_PERSISTENT_RESERVE_OUT &&
3163                     cdb0 != SCMD_PERSISTENT_RESERVE_IN &&
3164                     cdb0 != SCMD_REQUEST_SENSE &&
3165                     cdb0 != SCMD_READ_CAPACITY &&
3166                     cdb0 != SCMD_TEST_UNIT_READY &&
3167                     cdb0 != SCMD_START_STOP &&
3168                     cdb0 != SCMD_READ &&
3169                     cdb0 != SCMD_READ_G1 &&
3170                     cdb0 != SCMD_READ_G4 &&
3171                     cdb0 != SCMD_READ_G5 &&
3172                     !(cdb0 == SCMD_SVC_ACTION_IN_G4 &&
3173                     cdb1 == SSVC_ACTION_READ_CAPACITY_G4) &&
3174                     !(cdb0 == SCMD_MAINTENANCE_IN &&
3175                     (cdb1 & 0x1F) == 0x05) &&
3176                     !(cdb0 == SCMD_MAINTENANCE_IN &&
3177                     (cdb1 & 0x1F) == 0x0A)) {
3178                         stmf_scsilib_send_status(task, STATUS_CHECK,
3179                             STMF_SAA_LU_NO_ACCESS_STANDBY);
3180                         return;
3181                 }
3182 
3183                 /*
3184                  * is this a short write?
3185                  * if so, we'll need to wait until we have the buffer
3186                  * before proxying the command
3187                  */
3188                 switch (cdb0) {
3189                         case SCMD_MODE_SELECT:
3190                         case SCMD_MODE_SELECT_G1:
3191                         case SCMD_PERSISTENT_RESERVE_OUT:
3192                                 break;
3193                         default:
3194                                 st_ret = stmf_proxy_scsi_cmd(task,
3195                                     initial_dbuf);
3196                                 if (st_ret != STMF_SUCCESS) {
3197                                         stmf_scsilib_send_status(task,
3198                                             STATUS_CHECK,
3199                                             STMF_SAA_LU_NO_ACCESS_UNAVAIL);
3200                                 }
3201                                 return;
3202                 }
3203         }
3204 
3205         cdb0 = task->task_cdb[0] & 0x1F;
3206 
3207         if ((cdb0 == SCMD_READ) || (cdb0 == SCMD_WRITE)) {
3208                 if (task->task_additional_flags & TASK_AF_PORT_LOAD_HIGH) {
3209                         stmf_scsilib_send_status(task, STATUS_QFULL, 0);
3210                         return;
3211                 }
3212                 if (cdb0 == SCMD_READ) {
3213                         sbd_handle_read(task, initial_dbuf);
3214                         return;
3215                 }
3216                 sbd_handle_write(task, initial_dbuf);
3217                 return;
3218         }
3219 
3220         cdb0 = task->task_cdb[0];
3221         cdb1 = task->task_cdb[1];
3222 
3223         if (cdb0 == SCMD_INQUIRY) {             /* Inquiry */
3224                 sbd_handle_inquiry(task, initial_dbuf);
3225                 return;
3226         }
3227 
3228         if (cdb0  == SCMD_PERSISTENT_RESERVE_OUT) {
3229                 sbd_handle_pgr_out_cmd(task, initial_dbuf);
3230                 return;
3231         }
3232 
3233         if (cdb0  == SCMD_PERSISTENT_RESERVE_IN) {
3234                 sbd_handle_pgr_in_cmd(task, initial_dbuf);
3235                 return;
3236         }
3237 
3238         if (cdb0 == SCMD_RELEASE) {
3239                 if (cdb1) {
3240                         stmf_scsilib_send_status(task, STATUS_CHECK,
3241                             STMF_SAA_INVALID_FIELD_IN_CDB);
3242                         return;
3243                 }
3244 
3245                 mutex_enter(&sl->sl_lock);
3246                 if (sl->sl_flags & SL_LU_HAS_SCSI2_RESERVATION) {
3247                         /* If not owner don't release it, just return good */
3248                         if (it->sbd_it_session_id !=
3249                             sl->sl_rs_owner_session_id) {
3250                                 mutex_exit(&sl->sl_lock);
3251                                 stmf_scsilib_send_status(task, STATUS_GOOD, 0);
3252                                 return;
3253                         }
3254                 }
3255                 sl->sl_flags &= ~SL_LU_HAS_SCSI2_RESERVATION;
3256                 it->sbd_it_flags &= ~SBD_IT_HAS_SCSI2_RESERVATION;
3257                 mutex_exit(&sl->sl_lock);
3258                 stmf_scsilib_send_status(task, STATUS_GOOD, 0);
3259                 return;
3260         }
3261 
3262         if (cdb0 == SCMD_RESERVE) {
3263                 if (cdb1) {
3264                         stmf_scsilib_send_status(task, STATUS_CHECK,
3265                             STMF_SAA_INVALID_FIELD_IN_CDB);
3266                         return;
3267                 }
3268 
3269                 mutex_enter(&sl->sl_lock);
3270                 if (sl->sl_flags & SL_LU_HAS_SCSI2_RESERVATION) {
3271                         /* If not owner, return conflict status */
3272                         if (it->sbd_it_session_id !=
3273                             sl->sl_rs_owner_session_id) {
3274                                 mutex_exit(&sl->sl_lock);
3275                                 stmf_scsilib_send_status(task,
3276                                     STATUS_RESERVATION_CONFLICT, 0);
3277                                 return;
3278                         }
3279                 }
3280                 sl->sl_flags |= SL_LU_HAS_SCSI2_RESERVATION;
3281                 it->sbd_it_flags |= SBD_IT_HAS_SCSI2_RESERVATION;
3282                 sl->sl_rs_owner_session_id = it->sbd_it_session_id;
3283                 mutex_exit(&sl->sl_lock);
3284                 stmf_scsilib_send_status(task, STATUS_GOOD, 0);
3285                 return;
3286         }
3287 
3288         if (cdb0 == SCMD_REQUEST_SENSE) {
3289                 /*
3290                  * LU provider needs to store unretrieved sense data
3291                  * (e.g. after power-on/reset).  For now, we'll just
3292                  * return good status with no sense.
3293                  */
3294 
3295                 if ((cdb1 & ~1) || task->task_cdb[2] || task->task_cdb[3] ||
3296                     task->task_cdb[5]) {
3297                         stmf_scsilib_send_status(task, STATUS_CHECK,
3298                             STMF_SAA_INVALID_FIELD_IN_CDB);
3299                 } else {
3300                         stmf_scsilib_send_status(task, STATUS_GOOD, 0);
3301                 }
3302 
3303                 return;
3304         }
3305 
3306         /* Report Target Port Groups */
3307         if ((cdb0 == SCMD_MAINTENANCE_IN) &&
3308             ((cdb1 & 0x1F) == 0x0A)) {
3309                 stmf_scsilib_handle_report_tpgs(task, initial_dbuf);
3310                 return;
3311         }
3312 
3313         /* Report Identifying Information */
3314         if ((cdb0 == SCMD_MAINTENANCE_IN) &&
3315             ((cdb1 & 0x1F) == 0x05)) {
3316                 sbd_handle_identifying_info(task, initial_dbuf);
3317                 return;
3318         }
3319 
3320         if (cdb0 == SCMD_START_STOP) {                  /* Start stop */
3321                 task->task_cmd_xfer_length = 0;
3322                 if (task->task_cdb[4] & 0xFC) {
3323                         stmf_scsilib_send_status(task, STATUS_CHECK,
3324                             STMF_SAA_INVALID_FIELD_IN_CDB);
3325                         return;
3326                 }
3327                 if (task->task_cdb[4] & 2) {
3328                         stmf_scsilib_send_status(task, STATUS_CHECK,
3329                             STMF_SAA_INVALID_FIELD_IN_CDB);
3330                 } else {
3331                         stmf_scsilib_send_status(task, STATUS_GOOD, 0);
3332                 }
3333                 return;
3334 
3335         }
3336 
3337         if ((cdb0 == SCMD_MODE_SENSE) || (cdb0 == SCMD_MODE_SENSE_G1)) {
3338                 uint8_t *p;
3339                 p = kmem_zalloc(512, KM_SLEEP);
3340                 sbd_handle_mode_sense(task, initial_dbuf, p);
3341                 kmem_free(p, 512);
3342                 return;
3343         }
3344 
3345         if ((cdb0 == SCMD_MODE_SELECT) || (cdb0 == SCMD_MODE_SELECT_G1)) {
3346                 sbd_handle_mode_select(task, initial_dbuf);
3347                 return;
3348         }
3349 
3350         if ((cdb0 == SCMD_UNMAP) && (sl->sl_flags & SL_UNMAP_ENABLED)) {
3351                 sbd_handle_unmap(task, initial_dbuf);
3352                 return;
3353         }
3354 
3355         if ((cdb0 == SCMD_WRITE_SAME_G4) || (cdb0 == SCMD_WRITE_SAME_G1)) {
3356                 sbd_handle_write_same(task, initial_dbuf);
3357                 return;
3358         }
3359 
3360         if (cdb0 == SCMD_TEST_UNIT_READY) {     /* Test unit ready */
3361                 task->task_cmd_xfer_length = 0;
3362                 stmf_scsilib_send_status(task, STATUS_GOOD, 0);
3363                 return;
3364         }
3365 
3366         if (cdb0 == SCMD_READ_CAPACITY) {               /* Read Capacity */
3367                 sbd_handle_read_capacity(task, initial_dbuf);
3368                 return;
3369         }
3370 
3371         if (cdb0 == SCMD_SVC_ACTION_IN_G4) { /* Read Capacity or read long */
3372                 if (cdb1 == SSVC_ACTION_READ_CAPACITY_G4) {
3373                         sbd_handle_read_capacity(task, initial_dbuf);
3374                         return;
3375                 /*
3376                  * } else if (cdb1 == SSVC_ACTION_READ_LONG_G4) {
3377                  *      sbd_handle_read(task, initial_dbuf);
3378                  *      return;
3379                  */
3380                 }
3381         }
3382 
3383         /*
3384          * if (cdb0 == SCMD_SVC_ACTION_OUT_G4) {
3385          *      if (cdb1 == SSVC_ACTION_WRITE_LONG_G4) {
3386          *               sbd_handle_write(task, initial_dbuf);
3387          *              return;
3388          *      }
3389          * }
3390          */
3391 
3392         if (cdb0 == SCMD_VERIFY) {
3393                 /*
3394                  * Something more likely needs to be done here.
3395                  */
3396                 task->task_cmd_xfer_length = 0;
3397                 stmf_scsilib_send_status(task, STATUS_GOOD, 0);
3398                 return;
3399         }
3400 
3401         if (cdb0 == SCMD_SYNCHRONIZE_CACHE ||
3402             cdb0 == SCMD_SYNCHRONIZE_CACHE_G4) {
3403                 sbd_handle_sync_cache(task, initial_dbuf);
3404                 return;
3405         }
3406 
3407         /*
3408          * Write and Verify use the same path as write, but don't clutter the
3409          * performance path above with checking for write_verify opcodes.  We
3410          * rely on zfs's integrity checks for the "Verify" part of Write &
3411          * Verify.  (Even if we did a read to "verify" we'd merely be reading
3412          * cache, not actual media.)
3413          * Therefore we
3414          *   a) only support this if sbd_is_zvol, and
3415          *   b) run the IO through the normal write path with a forced
3416          *      sbd_flush_data_cache at the end.
3417          */
3418 
3419         if ((sl->sl_flags & SL_ZFS_META) && (
3420             cdb0 == SCMD_WRITE_VERIFY ||
3421             cdb0 == SCMD_WRITE_VERIFY_G4 ||
3422             cdb0 == SCMD_WRITE_VERIFY_G5)) {
3423                 sbd_handle_write(task, initial_dbuf);
3424                 return;
3425         }
3426 
3427         stmf_scsilib_send_status(task, STATUS_CHECK, STMF_SAA_INVALID_OPCODE);
3428 }
3429 
3430 void
3431 sbd_dbuf_xfer_done(struct scsi_task *task, struct stmf_data_buf *dbuf)
3432 {
3433         sbd_cmd_t *scmd = (sbd_cmd_t *)task->task_lu_private;
3434 
3435         if (dbuf->db_flags & DB_LU_DATA_BUF) {
3436                 /*
3437                  * Buffers passed in from the LU always complete
3438                  * even if the task is no longer active.
3439                  */
3440                 ASSERT(task->task_additional_flags & TASK_AF_ACCEPT_LU_DBUF);
3441                 ASSERT(scmd);
3442                 switch (scmd->cmd_type) {
3443                 case (SBD_CMD_SCSI_READ):
3444                         sbd_handle_sgl_read_xfer_completion(task, scmd, dbuf);
3445                         break;
3446                 case (SBD_CMD_SCSI_WRITE):
3447                         sbd_handle_sgl_write_xfer_completion(task, scmd, dbuf);
3448                         break;
3449                 default:
3450                         cmn_err(CE_PANIC, "Unknown cmd type, task = %p",
3451                             (void *)task);
3452                         break;
3453                 }
3454                 return;
3455         }
3456 
3457         if ((scmd == NULL) || ((scmd->flags & SBD_SCSI_CMD_ACTIVE) == 0))
3458                 return;
3459 
3460         switch (scmd->cmd_type) {
3461         case (SBD_CMD_SCSI_READ):
3462                 sbd_handle_read_xfer_completion(task, scmd, dbuf);
3463                 break;
3464 
3465         case (SBD_CMD_SCSI_WRITE):
3466                 if ((task->task_cdb[0] == SCMD_WRITE_SAME_G1) ||
3467                     (task->task_cdb[0] == SCMD_WRITE_SAME_G4)) {
3468                         sbd_handle_write_same_xfer_completion(task, scmd, dbuf,
3469                             1);
3470                 } else {
3471                         sbd_handle_write_xfer_completion(task, scmd, dbuf, 1);
3472                 }
3473                 break;
3474 
3475         case (SBD_CMD_SMALL_READ):
3476                 sbd_handle_short_read_xfer_completion(task, scmd, dbuf);
3477                 break;
3478 
3479         case (SBD_CMD_SMALL_WRITE):
3480                 sbd_handle_short_write_xfer_completion(task, dbuf);
3481                 break;
3482 
3483         default:
3484                 cmn_err(CE_PANIC, "Unknown cmd type, task = %p", (void *)task);
3485                 break;
3486         }
3487 }
3488 
3489 /* ARGSUSED */
3490 void
3491 sbd_send_status_done(struct scsi_task *task)
3492 {
3493         cmn_err(CE_PANIC,
3494             "sbd_send_status_done: this should not have been called");
3495 }
3496 
3497 void
3498 sbd_task_free(struct scsi_task *task)
3499 {
3500         if (task->task_lu_private) {
3501                 sbd_cmd_t *scmd = (sbd_cmd_t *)task->task_lu_private;
3502                 if (scmd->flags & SBD_SCSI_CMD_ACTIVE) {
3503                         cmn_err(CE_PANIC, "cmd is active, task = %p",
3504                             (void *)task);
3505                 }
3506                 kmem_free(scmd, sizeof (sbd_cmd_t));
3507         }
3508 }
3509 
3510 /*
3511  * Aborts are synchronus w.r.t. I/O AND
3512  * All the I/O which SBD does is synchronous AND
3513  * Everything within a task is single threaded.
3514  *   IT MEANS
3515  * If this function is called, we are doing nothing with this task
3516  * inside of sbd module.
3517  */
3518 /* ARGSUSED */
3519 stmf_status_t
3520 sbd_abort(struct stmf_lu *lu, int abort_cmd, void *arg, uint32_t flags)
3521 {
3522         sbd_lu_t *sl = (sbd_lu_t *)lu->lu_provider_private;
3523         scsi_task_t *task;
3524 
3525         if (abort_cmd == STMF_LU_RESET_STATE) {
3526                 return (sbd_lu_reset_state(lu));
3527         }
3528 
3529         if (abort_cmd == STMF_LU_ITL_HANDLE_REMOVED) {
3530                 sbd_check_and_clear_scsi2_reservation(sl, (sbd_it_data_t *)arg);
3531                 sbd_remove_it_handle(sl, (sbd_it_data_t *)arg);
3532                 return (STMF_SUCCESS);
3533         }
3534 
3535         ASSERT(abort_cmd == STMF_LU_ABORT_TASK);
3536         task = (scsi_task_t *)arg;
3537         if (task->task_lu_private) {
3538                 sbd_cmd_t *scmd = (sbd_cmd_t *)task->task_lu_private;
3539 
3540                 if (scmd->flags & SBD_SCSI_CMD_ACTIVE) {
3541                         if (scmd->flags & SBD_SCSI_CMD_TRANS_DATA) {
3542                                 kmem_free(scmd->trans_data,
3543                                     scmd->trans_data_len);
3544                                 scmd->flags &= ~SBD_SCSI_CMD_TRANS_DATA;
3545                         }
3546                         scmd->flags &= ~SBD_SCSI_CMD_ACTIVE;
3547                         return (STMF_ABORT_SUCCESS);
3548                 }
3549         }
3550 
3551         return (STMF_NOT_FOUND);
3552 }
3553 
3554 /*
3555  * This function is called during task clean-up if the
3556  * DB_LU_FLAG is set on the dbuf. This should only be called for
3557  * abort processing after sbd_abort has been called for the task.
3558  */
3559 void
3560 sbd_dbuf_free(struct scsi_task *task, struct stmf_data_buf *dbuf)
3561 {
3562         sbd_cmd_t *scmd = (sbd_cmd_t *)task->task_lu_private;
3563         sbd_lu_t *sl = (sbd_lu_t *)task->task_lu->lu_provider_private;
3564 
3565         ASSERT(dbuf->db_lu_private);
3566         ASSERT(scmd && scmd->nbufs > 0);
3567         ASSERT((scmd->flags & SBD_SCSI_CMD_ACTIVE) == 0);
3568         ASSERT(dbuf->db_flags & DB_LU_DATA_BUF);
3569         ASSERT(task->task_additional_flags & TASK_AF_ACCEPT_LU_DBUF);
3570         ASSERT((curthread->t_flag & T_INTR_THREAD) == 0);
3571 
3572         if (scmd->cmd_type == SBD_CMD_SCSI_READ) {
3573                 sbd_zvol_rele_read_bufs(sl, dbuf);
3574         } else if (scmd->cmd_type == SBD_CMD_SCSI_WRITE) {
3575                 sbd_zvol_rele_write_bufs_abort(sl, dbuf);
3576         } else {
3577                 cmn_err(CE_PANIC, "Unknown cmd type %d, task = %p",
3578                     scmd->cmd_type, (void *)task);
3579         }
3580         if (--scmd->nbufs == 0)
3581                 rw_exit(&sl->sl_access_state_lock);
3582         stmf_teardown_dbuf(task, dbuf);
3583         stmf_free(dbuf);
3584 }
3585 
3586 /* ARGSUSED */
3587 void
3588 sbd_ctl(struct stmf_lu *lu, int cmd, void *arg)
3589 {
3590         sbd_lu_t *sl = (sbd_lu_t *)lu->lu_provider_private;
3591         stmf_change_status_t st;
3592 
3593         ASSERT((cmd == STMF_CMD_LU_ONLINE) ||
3594             (cmd == STMF_CMD_LU_OFFLINE) ||
3595             (cmd == STMF_ACK_LU_ONLINE_COMPLETE) ||
3596             (cmd == STMF_ACK_LU_OFFLINE_COMPLETE));
3597 
3598         st.st_completion_status = STMF_SUCCESS;
3599         st.st_additional_info = NULL;
3600 
3601         switch (cmd) {
3602         case STMF_CMD_LU_ONLINE:
3603                 if (sl->sl_state == STMF_STATE_ONLINE)
3604                         st.st_completion_status = STMF_ALREADY;
3605                 else if (sl->sl_state != STMF_STATE_OFFLINE)
3606                         st.st_completion_status = STMF_FAILURE;
3607                 if (st.st_completion_status == STMF_SUCCESS) {
3608                         sl->sl_state = STMF_STATE_ONLINE;
3609                         sl->sl_state_not_acked = 1;
3610                 }
3611                 (void) stmf_ctl(STMF_CMD_LU_ONLINE_COMPLETE, lu, &st);
3612                 break;
3613 
3614         case STMF_CMD_LU_OFFLINE:
3615                 if (sl->sl_state == STMF_STATE_OFFLINE)
3616                         st.st_completion_status = STMF_ALREADY;
3617                 else if (sl->sl_state != STMF_STATE_ONLINE)
3618                         st.st_completion_status = STMF_FAILURE;
3619                 if (st.st_completion_status == STMF_SUCCESS) {
3620                         sl->sl_flags &= ~(SL_MEDIUM_REMOVAL_PREVENTED |
3621                             SL_LU_HAS_SCSI2_RESERVATION);
3622                         sl->sl_state = STMF_STATE_OFFLINE;
3623                         sl->sl_state_not_acked = 1;
3624                         sbd_pgr_reset(sl);
3625                 }
3626                 (void) stmf_ctl(STMF_CMD_LU_OFFLINE_COMPLETE, lu, &st);
3627                 break;
3628 
3629         case STMF_ACK_LU_ONLINE_COMPLETE:
3630                 /* Fallthrough */
3631         case STMF_ACK_LU_OFFLINE_COMPLETE:
3632                 sl->sl_state_not_acked = 0;
3633                 break;
3634 
3635         }
3636 }
3637 
3638 /* ARGSUSED */
3639 stmf_status_t
3640 sbd_info(uint32_t cmd, stmf_lu_t *lu, void *arg, uint8_t *buf,
3641     uint32_t *bufsizep)
3642 {
3643         return (STMF_NOT_SUPPORTED);
3644 }
3645 
3646 stmf_status_t
3647 sbd_lu_reset_state(stmf_lu_t *lu)
3648 {
3649         sbd_lu_t *sl = (sbd_lu_t *)lu->lu_provider_private;
3650 
3651         mutex_enter(&sl->sl_lock);
3652         if (sl->sl_flags & SL_SAVED_WRITE_CACHE_DISABLE) {
3653                 sl->sl_flags |= SL_WRITEBACK_CACHE_DISABLE;
3654                 mutex_exit(&sl->sl_lock);
3655                 if (sl->sl_access_state == SBD_LU_ACTIVE) {
3656                         (void) sbd_wcd_set(1, sl);
3657                 }
3658         } else {
3659                 sl->sl_flags &= ~SL_WRITEBACK_CACHE_DISABLE;
3660                 mutex_exit(&sl->sl_lock);
3661                 if (sl->sl_access_state == SBD_LU_ACTIVE) {
3662                         (void) sbd_wcd_set(0, sl);
3663                 }
3664         }
3665         sbd_pgr_reset(sl);
3666         sbd_check_and_clear_scsi2_reservation(sl, NULL);
3667         if (stmf_deregister_all_lu_itl_handles(lu) != STMF_SUCCESS) {
3668                 return (STMF_FAILURE);
3669         }
3670         return (STMF_SUCCESS);
3671 }
3672 
3673 sbd_status_t
3674 sbd_flush_data_cache(sbd_lu_t *sl, int fsync_done)
3675 {
3676         int r = 0;
3677         int ret;
3678 
3679         if (fsync_done)
3680                 goto over_fsync;
3681         if ((sl->sl_data_vtype == VREG) || (sl->sl_data_vtype == VBLK)) {
3682                 if (VOP_FSYNC(sl->sl_data_vp, FSYNC, kcred, NULL))
3683                         return (SBD_FAILURE);
3684         }
3685 over_fsync:
3686         if (((sl->sl_data_vtype == VCHR) || (sl->sl_data_vtype == VBLK)) &&
3687             ((sl->sl_flags & SL_NO_DATA_DKIOFLUSH) == 0)) {
3688                 ret = VOP_IOCTL(sl->sl_data_vp, DKIOCFLUSHWRITECACHE, NULL,
3689                     FKIOCTL, kcred, &r, NULL);
3690                 if ((ret == ENOTTY) || (ret == ENOTSUP)) {
3691                         mutex_enter(&sl->sl_lock);
3692                         sl->sl_flags |= SL_NO_DATA_DKIOFLUSH;
3693                         mutex_exit(&sl->sl_lock);
3694                 } else if (ret != 0) {
3695                         return (SBD_FAILURE);
3696                 }
3697         }
3698 
3699         return (SBD_SUCCESS);
3700 }
3701 
3702 /* ARGSUSED */
3703 static void
3704 sbd_handle_sync_cache(struct scsi_task *task,
3705     struct stmf_data_buf *initial_dbuf)
3706 {
3707         sbd_lu_t *sl = (sbd_lu_t *)task->task_lu->lu_provider_private;
3708         uint64_t        lba, laddr;
3709         sbd_status_t    sret;
3710         uint32_t        len;
3711         int             is_g4 = 0;
3712         int             immed;
3713 
3714         task->task_cmd_xfer_length = 0;
3715         /*
3716          * Determine if this is a 10 or 16 byte CDB
3717          */
3718 
3719         if (task->task_cdb[0] == SCMD_SYNCHRONIZE_CACHE_G4)
3720                 is_g4 = 1;
3721 
3722         /*
3723          * Determine other requested parameters
3724          *
3725          * We don't have a non-volatile cache, so don't care about SYNC_NV.
3726          * Do not support the IMMED bit.
3727          */
3728 
3729         immed = (task->task_cdb[1] & 0x02);
3730 
3731         if (immed) {
3732                 stmf_scsilib_send_status(task, STATUS_CHECK,
3733                     STMF_SAA_INVALID_FIELD_IN_CDB);
3734                 return;
3735         }
3736 
3737         /*
3738          * Check to be sure we're not being asked to sync an LBA
3739          * that is out of range.  While checking, verify reserved fields.
3740          */
3741 
3742         if (is_g4) {
3743                 if ((task->task_cdb[1] & 0xf9) || task->task_cdb[14] ||
3744                     task->task_cdb[15]) {
3745                         stmf_scsilib_send_status(task, STATUS_CHECK,
3746                             STMF_SAA_INVALID_FIELD_IN_CDB);
3747                         return;
3748                 }
3749 
3750                 lba = READ_SCSI64(&task->task_cdb[2], uint64_t);
3751                 len = READ_SCSI32(&task->task_cdb[10], uint32_t);
3752         } else {
3753                 if ((task->task_cdb[1] & 0xf9) || task->task_cdb[6] ||
3754                     task->task_cdb[9]) {
3755                         stmf_scsilib_send_status(task, STATUS_CHECK,
3756                             STMF_SAA_INVALID_FIELD_IN_CDB);
3757                         return;
3758                 }
3759 
3760                 lba = READ_SCSI32(&task->task_cdb[2], uint64_t);
3761                 len = READ_SCSI16(&task->task_cdb[7], uint32_t);
3762         }
3763 
3764         laddr = lba << sl->sl_data_blocksize_shift;
3765         len <<= sl->sl_data_blocksize_shift;
3766 
3767         if ((laddr + (uint64_t)len) > sl->sl_lu_size) {
3768                 stmf_scsilib_send_status(task, STATUS_CHECK,
3769                     STMF_SAA_LBA_OUT_OF_RANGE);
3770                 return;
3771         }
3772 
3773         sret = sbd_flush_data_cache(sl, 0);
3774         if (sret != SBD_SUCCESS) {
3775                 stmf_scsilib_send_status(task, STATUS_CHECK,
3776                     STMF_SAA_WRITE_ERROR);
3777                 return;
3778         }
3779 
3780         stmf_scsilib_send_status(task, STATUS_GOOD, 0);
3781 }