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