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