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