1/*- 2 * Copyright (c) 2003 Silicon Graphics International Corp. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions, and the following disclaimer, 10 * without modification. 11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12 * substantially similar to the "NO WARRANTY" disclaimer below 13 * ("Disclaimer") and any redistribution must be conditioned upon 14 * including a substantially similar Disclaimer requirement for further 15 * binary redistribution. 16 * 17 * NO WARRANTY 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 27 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGES. 29 * 30 * $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/ctl_util.c#2 $ 31 */ 32/* 33 * CAM Target Layer SCSI library 34 * 35 * Author: Ken Merry <ken@FreeBSD.org> 36 */ 37 38#include <sys/cdefs.h> 39__FBSDID("$FreeBSD: stable/11/sys/cam/ctl/ctl_util.c 361732 2020-06-02 20:38:53Z mav $"); 40 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 63struct ctl_status_desc { 64 ctl_io_status status; 65 const char *description; 66}; 67 68struct ctl_task_desc { 69 ctl_task_type task_action; 70 const char *description; 71}; 72static 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 82static 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 98void 99ctl_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 122void 123ctl_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 152void 153ctl_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 181void 182ctl_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 210void 211ctl_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 249void 250ctl_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 350void 351ctl_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 381void 382ctl_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 410void 411ctl_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 442void 443ctl_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 490void 491ctl_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 519void 520ctl_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 570void 571ctl_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 596void 597ctl_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 654void 655ctl_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 679union ctl_io * 680ctl_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 690bailout: 691 return (io); 692} 693 694void 695ctl_scsi_free_io(union ctl_io *io) 696{ 697 free(io); 698} 699 700void 701ctl_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 714const char * 715ctl_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 729void 730ctl_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: %#x/%d\n", 742 io->scsiio.tag_num, io->scsiio.tag_type); 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: %#x/%d\n", 755 io->taskio.tag_num, io->taskio.tag_type); 756 break; 757 default: 758 sbuf_printf(sb, "\n"); 759 break; 760 } 761 break; 762 default: 763 break; 764 } 765} 766 767void 768ctl_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 808char * 809ctl_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 819char * 820ctl_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 833void 834ctl_io_print(union ctl_io *io) 835{ 836 char str[512]; 837 838 printf("%s", ctl_io_string(io, str, sizeof(str))); 839} 840 841void 842ctl_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 850void 851ctl_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, " %#6x:%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 883void 884ctl_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