1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2003 Silicon Graphics International Corp. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions, and the following disclaimer, 12 * without modification. 13 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 14 * substantially similar to the "NO WARRANTY" disclaimer below 15 * ("Disclaimer") and any redistribution must be conditioned upon 16 * including a substantially similar Disclaimer requirement for further 17 * binary redistribution. 18 * 19 * NO WARRANTY 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 29 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGES. 31 * 32 * $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/ctl_util.c#2 $ 33 */ 34 /* 35 * CAM Target Layer SCSI library 36 * 37 * Author: Ken Merry <ken@FreeBSD.org> 38 */ 39 40 #ifdef _KERNEL 41 #include <sys/param.h> 42 #include <sys/systm.h> 43 #include <sys/kernel.h> 44 #include <sys/types.h> 45 #include <sys/malloc.h> 46 #else /* __KERNEL__ */ 47 #include <sys/types.h> 48 #include <sys/time.h> 49 #include <stdint.h> 50 #include <stdio.h> 51 #include <stdlib.h> 52 #include <string.h> 53 #endif /* __KERNEL__ */ 54 #include <sys/sbuf.h> 55 #include <sys/queue.h> 56 #include <sys/callout.h> 57 #include <cam/scsi/scsi_all.h> 58 #include <cam/ctl/ctl_io.h> 59 #include <cam/ctl/ctl_scsi_all.h> 60 #include <cam/ctl/ctl_util.h> 61 62 struct ctl_status_desc { 63 ctl_io_status status; 64 const char *description; 65 }; 66 67 struct ctl_task_desc { 68 ctl_task_type task_action; 69 const char *description; 70 }; 71 static struct ctl_status_desc ctl_status_table[] = { 72 {CTL_STATUS_NONE, "No Status"}, 73 {CTL_SUCCESS, "Command Completed Successfully"}, 74 {CTL_CMD_TIMEOUT, "Command Timed Out"}, 75 {CTL_SEL_TIMEOUT, "Selection Timeout"}, 76 {CTL_ERROR, "Command Failed"}, 77 {CTL_SCSI_ERROR, "SCSI Error"}, 78 {CTL_CMD_ABORTED, "Command Aborted"}, 79 }; 80 81 static struct ctl_task_desc ctl_task_table[] = { 82 {CTL_TASK_ABORT_TASK, "Abort Task"}, 83 {CTL_TASK_ABORT_TASK_SET, "Abort Task Set"}, 84 {CTL_TASK_CLEAR_ACA, "Clear ACA"}, 85 {CTL_TASK_CLEAR_TASK_SET, "Clear Task Set"}, 86 {CTL_TASK_I_T_NEXUS_RESET, "I_T Nexus Reset"}, 87 {CTL_TASK_LUN_RESET, "LUN Reset"}, 88 {CTL_TASK_TARGET_RESET, "Target Reset"}, 89 {CTL_TASK_BUS_RESET, "Bus Reset"}, 90 {CTL_TASK_PORT_LOGIN, "Port Login"}, 91 {CTL_TASK_PORT_LOGOUT, "Port Logout"}, 92 {CTL_TASK_QUERY_TASK, "Query Task"}, 93 {CTL_TASK_QUERY_TASK_SET, "Query Task Set"}, 94 {CTL_TASK_QUERY_ASYNC_EVENT, "Query Async Event"} 95 }; 96 97 void 98 ctl_scsi_tur(union ctl_io *io, ctl_tag_type tag_type, uint8_t control) 99 { 100 struct ctl_scsiio *ctsio; 101 struct scsi_test_unit_ready *cdb; 102 103 ctl_scsi_zero_io(io); 104 105 io->io_hdr.io_type = CTL_IO_SCSI; 106 ctsio = &io->scsiio; 107 cdb = (struct scsi_test_unit_ready *)ctsio->cdb; 108 109 cdb->opcode = TEST_UNIT_READY; 110 cdb->control = control; 111 io->io_hdr.flags = CTL_FLAG_DATA_NONE; 112 ctsio->tag_type = tag_type; 113 ctsio->cdb_len = sizeof(*cdb); 114 ctsio->ext_data_len = 0; 115 ctsio->ext_data_ptr = NULL; 116 ctsio->ext_sg_entries = 0; 117 ctsio->ext_data_filled = 0; 118 ctsio->sense_len = SSD_FULL_SIZE; 119 } 120 121 void 122 ctl_scsi_inquiry(union ctl_io *io, uint8_t *data_ptr, int32_t data_len, 123 uint8_t byte2, uint8_t page_code, ctl_tag_type tag_type, 124 uint8_t control) 125 { 126 struct ctl_scsiio *ctsio; 127 struct scsi_inquiry *cdb; 128 129 ctl_scsi_zero_io(io); 130 131 io->io_hdr.io_type = CTL_IO_SCSI; 132 ctsio = &io->scsiio; 133 cdb = (struct scsi_inquiry *)ctsio->cdb; 134 135 cdb->opcode = INQUIRY; 136 cdb->byte2 = byte2; 137 cdb->page_code = page_code; 138 cdb->control = control; 139 scsi_ulto2b(data_len, cdb->length); 140 io->io_hdr.io_type = CTL_IO_SCSI; 141 io->io_hdr.flags = CTL_FLAG_DATA_IN; 142 ctsio->tag_type = tag_type; 143 ctsio->cdb_len = sizeof(*cdb); 144 ctsio->ext_data_len = data_len; 145 ctsio->ext_data_ptr = data_ptr; 146 ctsio->ext_sg_entries = 0; 147 ctsio->ext_data_filled = 0; 148 ctsio->sense_len = SSD_FULL_SIZE; 149 } 150 151 void 152 ctl_scsi_request_sense(union ctl_io *io, uint8_t *data_ptr, 153 int32_t data_len, uint8_t byte2, ctl_tag_type tag_type, 154 uint8_t control) 155 { 156 struct ctl_scsiio *ctsio; 157 struct scsi_request_sense *cdb; 158 159 ctl_scsi_zero_io(io); 160 161 io->io_hdr.io_type = CTL_IO_SCSI; 162 ctsio = &io->scsiio; 163 cdb = (struct scsi_request_sense *)ctsio->cdb; 164 165 cdb->opcode = REQUEST_SENSE; 166 cdb->byte2 = byte2; 167 cdb->control = control; 168 cdb->length = data_len; 169 io->io_hdr.io_type = CTL_IO_SCSI; 170 io->io_hdr.flags = CTL_FLAG_DATA_IN; 171 ctsio->tag_type = tag_type; 172 ctsio->cdb_len = sizeof(*cdb); 173 ctsio->ext_data_ptr = data_ptr; 174 ctsio->ext_data_len = data_len; 175 ctsio->ext_sg_entries = 0; 176 ctsio->ext_data_filled = 0; 177 ctsio->sense_len = SSD_FULL_SIZE; 178 } 179 180 void 181 ctl_scsi_report_luns(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len, 182 uint8_t select_report, ctl_tag_type tag_type, 183 uint8_t control) 184 { 185 struct ctl_scsiio *ctsio; 186 struct scsi_report_luns *cdb; 187 188 ctl_scsi_zero_io(io); 189 190 io->io_hdr.io_type = CTL_IO_SCSI; 191 ctsio = &io->scsiio; 192 cdb = (struct scsi_report_luns *)ctsio->cdb; 193 194 cdb->opcode = REPORT_LUNS; 195 cdb->select_report = select_report; 196 scsi_ulto4b(data_len, cdb->length); 197 cdb->control = control; 198 io->io_hdr.io_type = CTL_IO_SCSI; 199 io->io_hdr.flags = CTL_FLAG_DATA_IN; 200 ctsio->tag_type = tag_type; 201 ctsio->cdb_len = sizeof(*cdb); 202 ctsio->ext_data_ptr = data_ptr; 203 ctsio->ext_data_len = data_len; 204 ctsio->ext_sg_entries = 0; 205 ctsio->ext_data_filled = 0; 206 ctsio->sense_len = SSD_FULL_SIZE; 207 } 208 209 void 210 ctl_scsi_read_write_buffer(union ctl_io *io, uint8_t *data_ptr, 211 uint32_t data_len, int read_buffer, uint8_t mode, 212 uint8_t buffer_id, uint32_t buffer_offset, 213 ctl_tag_type tag_type, uint8_t control) 214 { 215 struct ctl_scsiio *ctsio; 216 struct scsi_write_buffer *cdb; 217 218 ctl_scsi_zero_io(io); 219 220 io->io_hdr.io_type = CTL_IO_SCSI; 221 ctsio = &io->scsiio; 222 cdb = (struct scsi_write_buffer *)ctsio->cdb; 223 224 if (read_buffer != 0) 225 cdb->opcode = READ_BUFFER; 226 else 227 cdb->opcode = WRITE_BUFFER; 228 229 cdb->byte2 = mode & RWB_MODE; 230 cdb->buffer_id = buffer_id; 231 scsi_ulto3b(buffer_offset, cdb->offset); 232 scsi_ulto3b(data_len, cdb->length); 233 cdb->control = control; 234 io->io_hdr.io_type = CTL_IO_SCSI; 235 if (read_buffer != 0) 236 io->io_hdr.flags = CTL_FLAG_DATA_IN; 237 else 238 io->io_hdr.flags = CTL_FLAG_DATA_OUT; 239 ctsio->tag_type = tag_type; 240 ctsio->cdb_len = sizeof(*cdb); 241 ctsio->ext_data_ptr = data_ptr; 242 ctsio->ext_data_len = data_len; 243 ctsio->ext_sg_entries = 0; 244 ctsio->ext_data_filled = 0; 245 ctsio->sense_len = SSD_FULL_SIZE; 246 } 247 248 void 249 ctl_scsi_read_write(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len, 250 int read_op, uint8_t byte2, int minimum_cdb_size, 251 uint64_t lba, uint32_t num_blocks, ctl_tag_type tag_type, 252 uint8_t control) 253 { 254 struct ctl_scsiio *ctsio; 255 256 ctl_scsi_zero_io(io); 257 258 io->io_hdr.io_type = CTL_IO_SCSI; 259 ctsio = &io->scsiio; 260 261 /* 262 * Pick out the smallest CDB that will hold the user's request. 263 * minimum_cdb_size allows cranking the CDB size up, even for 264 * requests that would not normally need a large CDB. This can be 265 * useful for testing (e.g. to make sure READ_16 support works without 266 * having an array larger than 2TB) and for compatibility -- e.g. 267 * if your device doesn't support READ_6. (ATAPI drives don't.) 268 */ 269 if ((minimum_cdb_size < 10) 270 && ((lba & 0x1fffff) == lba) 271 && ((num_blocks & 0xff) == num_blocks) 272 && (byte2 == 0)) { 273 struct scsi_rw_6 *cdb; 274 275 /* 276 * Note that according to SBC-2, the target should return 256 277 * blocks if the transfer length in a READ(6) or WRITE(6) CDB 278 * is set to 0. Since it's possible that some targets 279 * won't do the right thing, we only send a READ(6) or 280 * WRITE(6) for transfer sizes up to and including 255 blocks. 281 */ 282 cdb = (struct scsi_rw_6 *)ctsio->cdb; 283 284 cdb->opcode = (read_op) ? READ_6 : WRITE_6; 285 scsi_ulto3b(lba, cdb->addr); 286 cdb->length = num_blocks & 0xff; 287 cdb->control = control; 288 289 ctsio->cdb_len = sizeof(*cdb); 290 291 } else if ((minimum_cdb_size < 12) 292 && ((num_blocks & 0xffff) == num_blocks) 293 && ((lba & 0xffffffff) == lba)) { 294 struct scsi_rw_10 *cdb; 295 296 cdb = (struct scsi_rw_10 *)ctsio->cdb; 297 298 cdb->opcode = (read_op) ? READ_10 : WRITE_10; 299 cdb->byte2 = byte2; 300 scsi_ulto4b(lba, cdb->addr); 301 cdb->reserved = 0; 302 scsi_ulto2b(num_blocks, cdb->length); 303 cdb->control = control; 304 305 ctsio->cdb_len = sizeof(*cdb); 306 } else if ((minimum_cdb_size < 16) 307 && ((num_blocks & 0xffffffff) == num_blocks) 308 && ((lba & 0xffffffff) == lba)) { 309 struct scsi_rw_12 *cdb; 310 311 cdb = (struct scsi_rw_12 *)ctsio->cdb; 312 313 cdb->opcode = (read_op) ? READ_12 : WRITE_12; 314 cdb->byte2 = byte2; 315 scsi_ulto4b(lba, cdb->addr); 316 scsi_ulto4b(num_blocks, cdb->length); 317 cdb->reserved = 0; 318 cdb->control = control; 319 320 ctsio->cdb_len = sizeof(*cdb); 321 } else { 322 struct scsi_rw_16 *cdb; 323 324 cdb = (struct scsi_rw_16 *)ctsio->cdb; 325 326 cdb->opcode = (read_op) ? READ_16 : WRITE_16; 327 cdb->byte2 = byte2; 328 scsi_u64to8b(lba, cdb->addr); 329 scsi_ulto4b(num_blocks, cdb->length); 330 cdb->reserved = 0; 331 cdb->control = control; 332 333 ctsio->cdb_len = sizeof(*cdb); 334 } 335 336 io->io_hdr.io_type = CTL_IO_SCSI; 337 if (read_op != 0) 338 io->io_hdr.flags = CTL_FLAG_DATA_IN; 339 else 340 io->io_hdr.flags = CTL_FLAG_DATA_OUT; 341 ctsio->tag_type = tag_type; 342 ctsio->ext_data_ptr = data_ptr; 343 ctsio->ext_data_len = data_len; 344 ctsio->ext_sg_entries = 0; 345 ctsio->ext_data_filled = 0; 346 ctsio->sense_len = SSD_FULL_SIZE; 347 } 348 349 void 350 ctl_scsi_write_same(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len, 351 uint8_t byte2, uint64_t lba, uint32_t num_blocks, 352 ctl_tag_type tag_type, uint8_t control) 353 { 354 struct ctl_scsiio *ctsio; 355 struct scsi_write_same_16 *cdb; 356 357 ctl_scsi_zero_io(io); 358 359 io->io_hdr.io_type = CTL_IO_SCSI; 360 ctsio = &io->scsiio; 361 ctsio->cdb_len = sizeof(*cdb); 362 cdb = (struct scsi_write_same_16 *)ctsio->cdb; 363 cdb->opcode = WRITE_SAME_16; 364 cdb->byte2 = byte2; 365 scsi_u64to8b(lba, cdb->addr); 366 scsi_ulto4b(num_blocks, cdb->length); 367 cdb->group = 0; 368 cdb->control = control; 369 370 io->io_hdr.io_type = CTL_IO_SCSI; 371 io->io_hdr.flags = CTL_FLAG_DATA_OUT; 372 ctsio->tag_type = tag_type; 373 ctsio->ext_data_ptr = data_ptr; 374 ctsio->ext_data_len = data_len; 375 ctsio->ext_sg_entries = 0; 376 ctsio->ext_data_filled = 0; 377 ctsio->sense_len = SSD_FULL_SIZE; 378 } 379 380 void 381 ctl_scsi_read_capacity(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len, 382 uint32_t addr, int reladr, int pmi, 383 ctl_tag_type tag_type, uint8_t control) 384 { 385 struct scsi_read_capacity *cdb; 386 387 ctl_scsi_zero_io(io); 388 389 io->io_hdr.io_type = CTL_IO_SCSI; 390 cdb = (struct scsi_read_capacity *)io->scsiio.cdb; 391 392 cdb->opcode = READ_CAPACITY; 393 if (reladr) 394 cdb->byte2 = SRC_RELADR; 395 if (pmi) 396 cdb->pmi = SRC_PMI; 397 scsi_ulto4b(addr, cdb->addr); 398 cdb->control = control; 399 io->io_hdr.io_type = CTL_IO_SCSI; 400 io->io_hdr.flags = CTL_FLAG_DATA_IN; 401 io->scsiio.tag_type = tag_type; 402 io->scsiio.ext_data_ptr = data_ptr; 403 io->scsiio.ext_data_len = data_len; 404 io->scsiio.ext_sg_entries = 0; 405 io->scsiio.ext_data_filled = 0; 406 io->scsiio.sense_len = SSD_FULL_SIZE; 407 } 408 409 void 410 ctl_scsi_read_capacity_16(union ctl_io *io, uint8_t *data_ptr, 411 uint32_t data_len, uint64_t addr, int reladr, 412 int pmi, ctl_tag_type tag_type, uint8_t control) 413 { 414 struct scsi_read_capacity_16 *cdb; 415 416 ctl_scsi_zero_io(io); 417 418 io->io_hdr.io_type = CTL_IO_SCSI; 419 cdb = (struct scsi_read_capacity_16 *)io->scsiio.cdb; 420 421 cdb->opcode = SERVICE_ACTION_IN; 422 cdb->service_action = SRC16_SERVICE_ACTION; 423 if (reladr) 424 cdb->reladr |= SRC16_RELADR; 425 if (pmi) 426 cdb->reladr |= SRC16_PMI; 427 scsi_u64to8b(addr, cdb->addr); 428 scsi_ulto4b(data_len, cdb->alloc_len); 429 cdb->control = control; 430 431 io->io_hdr.io_type = CTL_IO_SCSI; 432 io->io_hdr.flags = CTL_FLAG_DATA_IN; 433 io->scsiio.tag_type = tag_type; 434 io->scsiio.ext_data_ptr = data_ptr; 435 io->scsiio.ext_data_len = data_len; 436 io->scsiio.ext_sg_entries = 0; 437 io->scsiio.ext_data_filled = 0; 438 io->scsiio.sense_len = SSD_FULL_SIZE; 439 } 440 441 void 442 ctl_scsi_mode_sense(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len, 443 int dbd, int llbaa, uint8_t page_code, uint8_t pc, 444 uint8_t subpage, int minimum_cdb_size, 445 ctl_tag_type tag_type, uint8_t control) 446 { 447 ctl_scsi_zero_io(io); 448 449 if ((minimum_cdb_size < 10) 450 && (llbaa == 0) 451 && (data_len < 256)) { 452 struct scsi_mode_sense_6 *cdb; 453 454 cdb = (struct scsi_mode_sense_6 *)io->scsiio.cdb; 455 456 cdb->opcode = MODE_SENSE_6; 457 if (dbd) 458 cdb->byte2 |= SMS_DBD; 459 cdb->page = page_code | pc; 460 cdb->subpage = subpage; 461 cdb->length = data_len; 462 cdb->control = control; 463 } else { 464 struct scsi_mode_sense_10 *cdb; 465 466 cdb = (struct scsi_mode_sense_10 *)io->scsiio.cdb; 467 468 cdb->opcode = MODE_SENSE_10; 469 if (dbd) 470 cdb->byte2 |= SMS_DBD; 471 if (llbaa) 472 cdb->byte2 |= SMS10_LLBAA; 473 cdb->page = page_code | pc; 474 cdb->subpage = subpage; 475 scsi_ulto2b(data_len, cdb->length); 476 cdb->control = control; 477 } 478 479 io->io_hdr.io_type = CTL_IO_SCSI; 480 io->io_hdr.flags = CTL_FLAG_DATA_IN; 481 io->scsiio.tag_type = tag_type; 482 io->scsiio.ext_data_ptr = data_ptr; 483 io->scsiio.ext_data_len = data_len; 484 io->scsiio.ext_sg_entries = 0; 485 io->scsiio.ext_data_filled = 0; 486 io->scsiio.sense_len = SSD_FULL_SIZE; 487 } 488 489 void 490 ctl_scsi_start_stop(union ctl_io *io, int start, int load_eject, int immediate, 491 int power_conditions, ctl_tag_type tag_type, uint8_t control) 492 { 493 struct scsi_start_stop_unit *cdb; 494 495 cdb = (struct scsi_start_stop_unit *)io->scsiio.cdb; 496 497 ctl_scsi_zero_io(io); 498 499 cdb->opcode = START_STOP_UNIT; 500 if (immediate) 501 cdb->byte2 |= SSS_IMMED; 502 cdb->how = power_conditions; 503 if (load_eject) 504 cdb->how |= SSS_LOEJ; 505 if (start) 506 cdb->how |= SSS_START; 507 cdb->control = control; 508 io->io_hdr.io_type = CTL_IO_SCSI; 509 io->io_hdr.flags = CTL_FLAG_DATA_NONE; 510 io->scsiio.tag_type = tag_type; 511 io->scsiio.ext_data_ptr = NULL; 512 io->scsiio.ext_data_len = 0; 513 io->scsiio.ext_sg_entries = 0; 514 io->scsiio.ext_data_filled = 0; 515 io->scsiio.sense_len = SSD_FULL_SIZE; 516 } 517 518 void 519 ctl_scsi_sync_cache(union ctl_io *io, int immed, int reladr, 520 int minimum_cdb_size, uint64_t starting_lba, 521 uint32_t block_count, ctl_tag_type tag_type, 522 uint8_t control) 523 { 524 ctl_scsi_zero_io(io); 525 526 if ((minimum_cdb_size < 16) 527 && ((block_count & 0xffff) == block_count) 528 && ((starting_lba & 0xffffffff) == starting_lba)) { 529 struct scsi_sync_cache *cdb; 530 531 cdb = (struct scsi_sync_cache *)io->scsiio.cdb; 532 533 cdb->opcode = SYNCHRONIZE_CACHE; 534 if (reladr) 535 cdb->byte2 |= SSC_RELADR; 536 537 if (immed) 538 cdb->byte2 |= SSC_IMMED; 539 540 scsi_ulto4b(starting_lba, cdb->begin_lba); 541 scsi_ulto2b(block_count, cdb->lb_count); 542 cdb->control = control; 543 } else { 544 struct scsi_sync_cache_16 *cdb; 545 546 cdb = (struct scsi_sync_cache_16 *)io->scsiio.cdb; 547 548 cdb->opcode = SYNCHRONIZE_CACHE_16; 549 if (reladr) 550 cdb->byte2 |= SSC_RELADR; 551 552 if (immed) 553 cdb->byte2 |= SSC_IMMED; 554 555 scsi_u64to8b(starting_lba, cdb->begin_lba); 556 scsi_ulto4b(block_count, cdb->lb_count); 557 cdb->control = control; 558 } 559 io->io_hdr.io_type = CTL_IO_SCSI; 560 io->io_hdr.flags = CTL_FLAG_DATA_NONE; 561 io->scsiio.tag_type = tag_type; 562 io->scsiio.ext_data_ptr = NULL; 563 io->scsiio.ext_data_len = 0; 564 io->scsiio.ext_sg_entries = 0; 565 io->scsiio.ext_data_filled = 0; 566 io->scsiio.sense_len = SSD_FULL_SIZE; 567 } 568 569 void 570 ctl_scsi_persistent_res_in(union ctl_io *io, uint8_t *data_ptr, 571 uint32_t data_len, int action, 572 ctl_tag_type tag_type, uint8_t control) 573 { 574 575 struct scsi_per_res_in *cdb; 576 577 ctl_scsi_zero_io(io); 578 579 cdb = (struct scsi_per_res_in *)io->scsiio.cdb; 580 cdb->opcode = PERSISTENT_RES_IN; 581 cdb->action = action; 582 scsi_ulto2b(data_len, cdb->length); 583 cdb->control = control; 584 585 io->io_hdr.io_type = CTL_IO_SCSI; 586 io->io_hdr.flags = CTL_FLAG_DATA_IN; 587 io->scsiio.tag_type = tag_type; 588 io->scsiio.ext_data_ptr = data_ptr; 589 io->scsiio.ext_data_len = data_len; 590 io->scsiio.ext_sg_entries = 0; 591 io->scsiio.ext_data_filled = 0; 592 io->scsiio.sense_len = SSD_FULL_SIZE; 593 } 594 595 void 596 ctl_scsi_persistent_res_out(union ctl_io *io, uint8_t *data_ptr, 597 uint32_t data_len, int action, int type, 598 uint64_t key, uint64_t sa_key, 599 ctl_tag_type tag_type, uint8_t control) 600 { 601 602 struct scsi_per_res_out *cdb; 603 struct scsi_per_res_out_parms *params; 604 605 ctl_scsi_zero_io(io); 606 607 cdb = (struct scsi_per_res_out *)io->scsiio.cdb; 608 params = (struct scsi_per_res_out_parms *)data_ptr; 609 610 cdb->opcode = PERSISTENT_RES_OUT; 611 if (action == 5) 612 cdb->action = 6; 613 else 614 cdb->action = action; 615 switch(type) 616 { 617 case 0: 618 cdb->scope_type = 1; 619 break; 620 case 1: 621 cdb->scope_type = 3; 622 break; 623 case 2: 624 cdb->scope_type = 5; 625 break; 626 case 3: 627 cdb->scope_type = 6; 628 break; 629 case 4: 630 cdb->scope_type = 7; 631 break; 632 case 5: 633 cdb->scope_type = 8; 634 break; 635 } 636 scsi_ulto4b(data_len, cdb->length); 637 cdb->control = control; 638 639 scsi_u64to8b(key, params->res_key.key); 640 scsi_u64to8b(sa_key, params->serv_act_res_key); 641 642 io->io_hdr.io_type = CTL_IO_SCSI; 643 io->io_hdr.flags = CTL_FLAG_DATA_OUT; 644 io->scsiio.tag_type = tag_type; 645 io->scsiio.ext_data_ptr = data_ptr; 646 io->scsiio.ext_data_len = data_len; 647 io->scsiio.ext_sg_entries = 0; 648 io->scsiio.ext_data_filled = 0; 649 io->scsiio.sense_len = SSD_FULL_SIZE; 650 651 } 652 653 void 654 ctl_scsi_maintenance_in(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len, 655 uint8_t action, ctl_tag_type tag_type, uint8_t control) 656 { 657 struct scsi_maintenance_in *cdb; 658 659 ctl_scsi_zero_io(io); 660 661 cdb = (struct scsi_maintenance_in *)io->scsiio.cdb; 662 cdb->opcode = MAINTENANCE_IN; 663 cdb->byte2 = action; 664 scsi_ulto4b(data_len, cdb->length); 665 cdb->control = control; 666 667 io->io_hdr.io_type = CTL_IO_SCSI; 668 io->io_hdr.flags = CTL_FLAG_DATA_IN; 669 io->scsiio.tag_type = tag_type; 670 io->scsiio.ext_data_ptr = data_ptr; 671 io->scsiio.ext_data_len = data_len; 672 io->scsiio.ext_sg_entries = 0; 673 io->scsiio.ext_data_filled = 0; 674 io->scsiio.sense_len = SSD_FULL_SIZE; 675 } 676 677 #ifndef _KERNEL 678 union ctl_io * 679 ctl_scsi_alloc_io(uint32_t initid) 680 { 681 union ctl_io *io; 682 683 io = (union ctl_io *)malloc(sizeof(*io)); 684 if (io == NULL) 685 goto bailout; 686 687 io->io_hdr.nexus.initid = initid; 688 689 bailout: 690 return (io); 691 } 692 693 void 694 ctl_scsi_free_io(union ctl_io *io) 695 { 696 free(io); 697 } 698 699 void 700 ctl_scsi_zero_io(union ctl_io *io) 701 { 702 void *pool_ref; 703 704 if (io == NULL) 705 return; 706 707 pool_ref = io->io_hdr.pool; 708 memset(io, 0, sizeof(*io)); 709 io->io_hdr.pool = pool_ref; 710 } 711 #endif /* !_KERNEL */ 712 713 const char * 714 ctl_scsi_task_string(struct ctl_taskio *taskio) 715 { 716 unsigned int i; 717 718 for (i = 0; i < (sizeof(ctl_task_table)/sizeof(ctl_task_table[0])); 719 i++) { 720 if (taskio->task_action == ctl_task_table[i].task_action) { 721 return (ctl_task_table[i].description); 722 } 723 } 724 725 return (NULL); 726 } 727 728 void 729 ctl_io_sbuf(union ctl_io *io, struct sbuf *sb) 730 { 731 const char *task_desc; 732 char path_str[64]; 733 734 ctl_scsi_path_string(io, path_str, sizeof(path_str)); 735 736 switch (io->io_hdr.io_type) { 737 case CTL_IO_SCSI: 738 sbuf_cat(sb, path_str); 739 ctl_scsi_command_string(&io->scsiio, NULL, sb); 740 sbuf_printf(sb, " Tag: %#jx/%d, Prio: %d\n", 741 io->scsiio.tag_num, io->scsiio.tag_type, 742 io->scsiio.priority); 743 break; 744 case CTL_IO_TASK: 745 sbuf_cat(sb, path_str); 746 task_desc = ctl_scsi_task_string(&io->taskio); 747 if (task_desc == NULL) 748 sbuf_printf(sb, "Unknown Task Action %d (%#x)", 749 io->taskio.task_action, io->taskio.task_action); 750 else 751 sbuf_printf(sb, "Task Action: %s", task_desc); 752 switch (io->taskio.task_action) { 753 case CTL_TASK_ABORT_TASK: 754 sbuf_printf(sb, " Tag: %#jx/%d\n", 755 io->taskio.tag_num, io->taskio.tag_type); 756 break; 757 default: 758 sbuf_putc(sb, '\n'); 759 break; 760 } 761 break; 762 default: 763 break; 764 } 765 } 766 767 void 768 ctl_io_error_sbuf(union ctl_io *io, struct scsi_inquiry_data *inq_data, 769 struct sbuf *sb) 770 { 771 struct ctl_status_desc *status_desc; 772 char path_str[64]; 773 unsigned int i; 774 775 ctl_io_sbuf(io, sb); 776 777 status_desc = NULL; 778 for (i = 0; i < (sizeof(ctl_status_table)/sizeof(ctl_status_table[0])); 779 i++) { 780 if ((io->io_hdr.status & CTL_STATUS_MASK) == 781 ctl_status_table[i].status) { 782 status_desc = &ctl_status_table[i]; 783 break; 784 } 785 } 786 787 ctl_scsi_path_string(io, path_str, sizeof(path_str)); 788 789 sbuf_cat(sb, path_str); 790 if (status_desc == NULL) 791 sbuf_printf(sb, "CTL Status: Unknown status %#x\n", 792 io->io_hdr.status); 793 else 794 sbuf_printf(sb, "CTL Status: %s\n", status_desc->description); 795 796 if ((io->io_hdr.io_type == CTL_IO_SCSI) 797 && ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_SCSI_ERROR)) { 798 sbuf_cat(sb, path_str); 799 sbuf_printf(sb, "SCSI Status: %s\n", 800 ctl_scsi_status_string(&io->scsiio)); 801 802 if (io->scsiio.scsi_status == SCSI_STATUS_CHECK_COND) 803 ctl_scsi_sense_sbuf(&io->scsiio, inq_data, 804 sb, SSS_FLAG_NONE); 805 } 806 } 807 808 char * 809 ctl_io_string(union ctl_io *io, char *str, int str_len) 810 { 811 struct sbuf sb; 812 813 sbuf_new(&sb, str, str_len, SBUF_FIXEDLEN); 814 ctl_io_sbuf(io, &sb); 815 sbuf_finish(&sb); 816 return (sbuf_data(&sb)); 817 } 818 819 char * 820 ctl_io_error_string(union ctl_io *io, struct scsi_inquiry_data *inq_data, 821 char *str, int str_len) 822 { 823 struct sbuf sb; 824 825 sbuf_new(&sb, str, str_len, SBUF_FIXEDLEN); 826 ctl_io_error_sbuf(io, inq_data, &sb); 827 sbuf_finish(&sb); 828 return (sbuf_data(&sb)); 829 } 830 831 #ifdef _KERNEL 832 833 void 834 ctl_io_print(union ctl_io *io) 835 { 836 char str[512]; 837 838 printf("%s", ctl_io_string(io, str, sizeof(str))); 839 } 840 841 void 842 ctl_io_error_print(union ctl_io *io, struct scsi_inquiry_data *inq_data) 843 { 844 char str[512]; 845 846 printf("%s", ctl_io_error_string(io, inq_data, str, sizeof(str))); 847 848 } 849 850 void 851 ctl_data_print(union ctl_io *io) 852 { 853 char str[128]; 854 char path_str[64]; 855 struct sbuf sb; 856 int i, j, len; 857 858 if (io->io_hdr.io_type != CTL_IO_SCSI) 859 return; 860 if (io->io_hdr.flags & CTL_FLAG_BUS_ADDR) 861 return; 862 if (io->scsiio.kern_sg_entries > 0) /* XXX: Implement */ 863 return; 864 ctl_scsi_path_string(io, path_str, sizeof(path_str)); 865 len = min(io->scsiio.kern_data_len, 4096); 866 for (i = 0; i < len; ) { 867 sbuf_new(&sb, str, sizeof(str), SBUF_FIXEDLEN); 868 sbuf_cat(&sb, path_str); 869 sbuf_printf(&sb, " %#jx:%04x:", io->scsiio.tag_num, i); 870 for (j = 0; j < 16 && i < len; i++, j++) { 871 if (j == 8) 872 sbuf_cat(&sb, " "); 873 sbuf_printf(&sb, " %02x", io->scsiio.kern_data_ptr[i]); 874 } 875 sbuf_cat(&sb, "\n"); 876 sbuf_finish(&sb); 877 printf("%s", sbuf_data(&sb)); 878 } 879 } 880 881 #else /* _KERNEL */ 882 883 void 884 ctl_io_error_print(union ctl_io *io, struct scsi_inquiry_data *inq_data, 885 FILE *ofile) 886 { 887 char str[512]; 888 889 fprintf(ofile, "%s", ctl_io_error_string(io, inq_data, str, 890 sizeof(str))); 891 } 892 893 #endif /* _KERNEL */ 894 895 /* 896 * vim: ts=8 897 */ 898