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$"); 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 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 }; 94 95 void 96 ctl_scsi_tur(union ctl_io *io, ctl_tag_type tag_type, uint8_t control) 97 { 98 struct ctl_scsiio *ctsio; 99 struct scsi_test_unit_ready *cdb; 100 101 ctl_scsi_zero_io(io); 102 103 io->io_hdr.io_type = CTL_IO_SCSI; 104 ctsio = &io->scsiio; 105 cdb = (struct scsi_test_unit_ready *)ctsio->cdb; 106 107 cdb->opcode = TEST_UNIT_READY; 108 cdb->control = control; 109 io->io_hdr.flags = CTL_FLAG_DATA_NONE; 110 ctsio->tag_type = tag_type; 111 ctsio->cdb_len = sizeof(*cdb); 112 ctsio->ext_data_len = 0; 113 ctsio->ext_data_ptr = NULL; 114 ctsio->ext_sg_entries = 0; 115 ctsio->ext_data_filled = 0; 116 ctsio->sense_len = SSD_FULL_SIZE; 117 } 118 119 void 120 ctl_scsi_inquiry(union ctl_io *io, uint8_t *data_ptr, int32_t data_len, 121 uint8_t byte2, uint8_t page_code, ctl_tag_type tag_type, 122 uint8_t control) 123 { 124 struct ctl_scsiio *ctsio; 125 struct scsi_inquiry *cdb; 126 127 ctl_scsi_zero_io(io); 128 129 io->io_hdr.io_type = CTL_IO_SCSI; 130 ctsio = &io->scsiio; 131 cdb = (struct scsi_inquiry *)ctsio->cdb; 132 133 cdb->opcode = INQUIRY; 134 cdb->byte2 = byte2; 135 cdb->page_code = page_code; 136 cdb->control = control; 137 scsi_ulto2b(data_len, cdb->length); 138 io->io_hdr.io_type = CTL_IO_SCSI; 139 io->io_hdr.flags = CTL_FLAG_DATA_IN; 140 ctsio->tag_type = tag_type; 141 ctsio->cdb_len = sizeof(*cdb); 142 ctsio->ext_data_len = data_len; 143 ctsio->ext_data_ptr = data_ptr; 144 ctsio->ext_sg_entries = 0; 145 ctsio->ext_data_filled = 0; 146 ctsio->sense_len = SSD_FULL_SIZE; 147 } 148 149 void 150 ctl_scsi_request_sense(union ctl_io *io, uint8_t *data_ptr, 151 int32_t data_len, uint8_t byte2, ctl_tag_type tag_type, 152 uint8_t control) 153 { 154 struct ctl_scsiio *ctsio; 155 struct scsi_request_sense *cdb; 156 157 ctl_scsi_zero_io(io); 158 159 io->io_hdr.io_type = CTL_IO_SCSI; 160 ctsio = &io->scsiio; 161 cdb = (struct scsi_request_sense *)ctsio->cdb; 162 163 cdb->opcode = REQUEST_SENSE; 164 cdb->byte2 = byte2; 165 cdb->control = control; 166 cdb->length = data_len; 167 io->io_hdr.io_type = CTL_IO_SCSI; 168 io->io_hdr.flags = CTL_FLAG_DATA_IN; 169 ctsio->tag_type = tag_type; 170 ctsio->cdb_len = sizeof(*cdb); 171 ctsio->ext_data_ptr = data_ptr; 172 ctsio->ext_data_len = data_len; 173 ctsio->ext_sg_entries = 0; 174 ctsio->ext_data_filled = 0; 175 ctsio->sense_len = SSD_FULL_SIZE; 176 } 177 178 void 179 ctl_scsi_report_luns(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len, 180 uint8_t select_report, ctl_tag_type tag_type, 181 uint8_t control) 182 { 183 struct ctl_scsiio *ctsio; 184 struct scsi_report_luns *cdb; 185 186 ctl_scsi_zero_io(io); 187 188 io->io_hdr.io_type = CTL_IO_SCSI; 189 ctsio = &io->scsiio; 190 cdb = (struct scsi_report_luns *)ctsio->cdb; 191 192 cdb->opcode = REPORT_LUNS; 193 cdb->select_report = select_report; 194 scsi_ulto4b(data_len, cdb->length); 195 cdb->control = control; 196 io->io_hdr.io_type = CTL_IO_SCSI; 197 io->io_hdr.flags = CTL_FLAG_DATA_IN; 198 ctsio->tag_type = tag_type; 199 ctsio->cdb_len = sizeof(*cdb); 200 ctsio->ext_data_ptr = data_ptr; 201 ctsio->ext_data_len = data_len; 202 ctsio->ext_sg_entries = 0; 203 ctsio->ext_data_filled = 0; 204 ctsio->sense_len = SSD_FULL_SIZE; 205 } 206 207 void 208 ctl_scsi_read_write_buffer(union ctl_io *io, uint8_t *data_ptr, 209 uint32_t data_len, int read_buffer, uint8_t mode, 210 uint8_t buffer_id, uint32_t buffer_offset, 211 ctl_tag_type tag_type, uint8_t control) 212 { 213 struct ctl_scsiio *ctsio; 214 struct scsi_write_buffer *cdb; 215 216 ctl_scsi_zero_io(io); 217 218 io->io_hdr.io_type = CTL_IO_SCSI; 219 ctsio = &io->scsiio; 220 cdb = (struct scsi_write_buffer *)ctsio->cdb; 221 222 if (read_buffer != 0) 223 cdb->opcode = READ_BUFFER; 224 else 225 cdb->opcode = WRITE_BUFFER; 226 227 cdb->byte2 = mode & RWB_MODE; 228 cdb->buffer_id = buffer_id; 229 scsi_ulto3b(buffer_offset, cdb->offset); 230 scsi_ulto3b(data_len, cdb->length); 231 cdb->control = control; 232 io->io_hdr.io_type = CTL_IO_SCSI; 233 if (read_buffer != 0) 234 io->io_hdr.flags = CTL_FLAG_DATA_IN; 235 else 236 io->io_hdr.flags = CTL_FLAG_DATA_OUT; 237 ctsio->tag_type = tag_type; 238 ctsio->cdb_len = sizeof(*cdb); 239 ctsio->ext_data_ptr = data_ptr; 240 ctsio->ext_data_len = data_len; 241 ctsio->ext_sg_entries = 0; 242 ctsio->ext_data_filled = 0; 243 ctsio->sense_len = SSD_FULL_SIZE; 244 } 245 246 void 247 ctl_scsi_read_write(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len, 248 int read_op, uint8_t byte2, int minimum_cdb_size, 249 uint64_t lba, uint32_t num_blocks, ctl_tag_type tag_type, 250 uint8_t control) 251 { 252 struct ctl_scsiio *ctsio; 253 254 ctl_scsi_zero_io(io); 255 256 io->io_hdr.io_type = CTL_IO_SCSI; 257 ctsio = &io->scsiio; 258 259 /* 260 * Pick out the smallest CDB that will hold the user's request. 261 * minimum_cdb_size allows cranking the CDB size up, even for 262 * requests that would not normally need a large CDB. This can be 263 * useful for testing (e.g. to make sure READ_16 support works without 264 * having an array larger than 2TB) and for compatibility -- e.g. 265 * if your device doesn't support READ_6. (ATAPI drives don't.) 266 */ 267 if ((minimum_cdb_size < 10) 268 && ((lba & 0x1fffff) == lba) 269 && ((num_blocks & 0xff) == num_blocks) 270 && (byte2 == 0)) { 271 struct scsi_rw_6 *cdb; 272 273 /* 274 * Note that according to SBC-2, the target should return 256 275 * blocks if the transfer length in a READ(6) or WRITE(6) CDB 276 * is set to 0. Since it's possible that some targets 277 * won't do the right thing, we only send a READ(6) or 278 * WRITE(6) for transfer sizes up to and including 255 blocks. 279 */ 280 cdb = (struct scsi_rw_6 *)ctsio->cdb; 281 282 cdb->opcode = (read_op) ? READ_6 : WRITE_6; 283 scsi_ulto3b(lba, cdb->addr); 284 cdb->length = num_blocks & 0xff; 285 cdb->control = control; 286 287 ctsio->cdb_len = sizeof(*cdb); 288 289 } else if ((minimum_cdb_size < 12) 290 && ((num_blocks & 0xffff) == num_blocks) 291 && ((lba & 0xffffffff) == lba)) { 292 struct scsi_rw_10 *cdb; 293 294 cdb = (struct scsi_rw_10 *)ctsio->cdb; 295 296 cdb->opcode = (read_op) ? READ_10 : WRITE_10; 297 cdb->byte2 = byte2; 298 scsi_ulto4b(lba, cdb->addr); 299 cdb->reserved = 0; 300 scsi_ulto2b(num_blocks, cdb->length); 301 cdb->control = control; 302 303 ctsio->cdb_len = sizeof(*cdb); 304 } else if ((minimum_cdb_size < 16) 305 && ((num_blocks & 0xffffffff) == num_blocks) 306 && ((lba & 0xffffffff) == lba)) { 307 struct scsi_rw_12 *cdb; 308 309 cdb = (struct scsi_rw_12 *)ctsio->cdb; 310 311 cdb->opcode = (read_op) ? READ_12 : WRITE_12; 312 cdb->byte2 = byte2; 313 scsi_ulto4b(lba, cdb->addr); 314 scsi_ulto4b(num_blocks, cdb->length); 315 cdb->reserved = 0; 316 cdb->control = control; 317 318 ctsio->cdb_len = sizeof(*cdb); 319 } else { 320 struct scsi_rw_16 *cdb; 321 322 cdb = (struct scsi_rw_16 *)ctsio->cdb; 323 324 cdb->opcode = (read_op) ? READ_16 : WRITE_16; 325 cdb->byte2 = byte2; 326 scsi_u64to8b(lba, cdb->addr); 327 scsi_ulto4b(num_blocks, cdb->length); 328 cdb->reserved = 0; 329 cdb->control = control; 330 331 ctsio->cdb_len = sizeof(*cdb); 332 } 333 334 io->io_hdr.io_type = CTL_IO_SCSI; 335 if (read_op != 0) 336 io->io_hdr.flags = CTL_FLAG_DATA_IN; 337 else 338 io->io_hdr.flags = CTL_FLAG_DATA_OUT; 339 ctsio->tag_type = tag_type; 340 ctsio->ext_data_ptr = data_ptr; 341 ctsio->ext_data_len = data_len; 342 ctsio->ext_sg_entries = 0; 343 ctsio->ext_data_filled = 0; 344 ctsio->sense_len = SSD_FULL_SIZE; 345 } 346 347 void 348 ctl_scsi_write_same(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len, 349 uint8_t byte2, uint64_t lba, uint32_t num_blocks, 350 ctl_tag_type tag_type, uint8_t control) 351 { 352 struct ctl_scsiio *ctsio; 353 struct scsi_write_same_16 *cdb; 354 355 ctl_scsi_zero_io(io); 356 357 io->io_hdr.io_type = CTL_IO_SCSI; 358 ctsio = &io->scsiio; 359 ctsio->cdb_len = sizeof(*cdb); 360 cdb = (struct scsi_write_same_16 *)ctsio->cdb; 361 cdb->opcode = WRITE_SAME_16; 362 cdb->byte2 = byte2; 363 scsi_u64to8b(lba, cdb->addr); 364 scsi_ulto4b(num_blocks, cdb->length); 365 cdb->group = 0; 366 cdb->control = control; 367 368 io->io_hdr.io_type = CTL_IO_SCSI; 369 io->io_hdr.flags = CTL_FLAG_DATA_OUT; 370 ctsio->tag_type = tag_type; 371 ctsio->ext_data_ptr = data_ptr; 372 ctsio->ext_data_len = data_len; 373 ctsio->ext_sg_entries = 0; 374 ctsio->ext_data_filled = 0; 375 ctsio->sense_len = SSD_FULL_SIZE; 376 } 377 378 void 379 ctl_scsi_read_capacity(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len, 380 uint32_t addr, int reladr, int pmi, 381 ctl_tag_type tag_type, uint8_t control) 382 { 383 struct scsi_read_capacity *cdb; 384 385 ctl_scsi_zero_io(io); 386 387 io->io_hdr.io_type = CTL_IO_SCSI; 388 cdb = (struct scsi_read_capacity *)io->scsiio.cdb; 389 390 cdb->opcode = READ_CAPACITY; 391 if (reladr) 392 cdb->byte2 = SRC_RELADR; 393 if (pmi) 394 cdb->pmi = SRC_PMI; 395 scsi_ulto4b(addr, cdb->addr); 396 cdb->control = control; 397 io->io_hdr.io_type = CTL_IO_SCSI; 398 io->io_hdr.flags = CTL_FLAG_DATA_IN; 399 io->scsiio.tag_type = tag_type; 400 io->scsiio.ext_data_ptr = data_ptr; 401 io->scsiio.ext_data_len = data_len; 402 io->scsiio.ext_sg_entries = 0; 403 io->scsiio.ext_data_filled = 0; 404 io->scsiio.sense_len = SSD_FULL_SIZE; 405 } 406 407 void 408 ctl_scsi_read_capacity_16(union ctl_io *io, uint8_t *data_ptr, 409 uint32_t data_len, uint64_t addr, int reladr, 410 int pmi, ctl_tag_type tag_type, uint8_t control) 411 { 412 struct scsi_read_capacity_16 *cdb; 413 414 ctl_scsi_zero_io(io); 415 416 io->io_hdr.io_type = CTL_IO_SCSI; 417 cdb = (struct scsi_read_capacity_16 *)io->scsiio.cdb; 418 419 cdb->opcode = SERVICE_ACTION_IN; 420 cdb->service_action = SRC16_SERVICE_ACTION; 421 if (reladr) 422 cdb->reladr |= SRC16_RELADR; 423 if (pmi) 424 cdb->reladr |= SRC16_PMI; 425 scsi_u64to8b(addr, cdb->addr); 426 scsi_ulto4b(data_len, cdb->alloc_len); 427 cdb->control = control; 428 429 io->io_hdr.io_type = CTL_IO_SCSI; 430 io->io_hdr.flags = CTL_FLAG_DATA_IN; 431 io->scsiio.tag_type = tag_type; 432 io->scsiio.ext_data_ptr = data_ptr; 433 io->scsiio.ext_data_len = data_len; 434 io->scsiio.ext_sg_entries = 0; 435 io->scsiio.ext_data_filled = 0; 436 io->scsiio.sense_len = SSD_FULL_SIZE; 437 } 438 439 void 440 ctl_scsi_mode_sense(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len, 441 int dbd, int llbaa, uint8_t page_code, uint8_t pc, 442 uint8_t subpage, int minimum_cdb_size, 443 ctl_tag_type tag_type, uint8_t control) 444 { 445 ctl_scsi_zero_io(io); 446 447 if ((minimum_cdb_size < 10) 448 && (llbaa == 0) 449 && (data_len < 256)) { 450 struct scsi_mode_sense_6 *cdb; 451 452 cdb = (struct scsi_mode_sense_6 *)io->scsiio.cdb; 453 454 cdb->opcode = MODE_SENSE_6; 455 if (dbd) 456 cdb->byte2 |= SMS_DBD; 457 cdb->page = page_code | pc; 458 cdb->subpage = subpage; 459 cdb->length = data_len; 460 cdb->control = control; 461 } else { 462 struct scsi_mode_sense_10 *cdb; 463 464 cdb = (struct scsi_mode_sense_10 *)io->scsiio.cdb; 465 466 cdb->opcode = MODE_SENSE_10; 467 if (dbd) 468 cdb->byte2 |= SMS_DBD; 469 if (llbaa) 470 cdb->byte2 |= SMS10_LLBAA; 471 cdb->page = page_code | pc; 472 cdb->subpage = subpage; 473 scsi_ulto2b(data_len, cdb->length); 474 cdb->control = control; 475 } 476 477 io->io_hdr.io_type = CTL_IO_SCSI; 478 io->io_hdr.flags = CTL_FLAG_DATA_IN; 479 io->scsiio.tag_type = tag_type; 480 io->scsiio.ext_data_ptr = data_ptr; 481 io->scsiio.ext_data_len = data_len; 482 io->scsiio.ext_sg_entries = 0; 483 io->scsiio.ext_data_filled = 0; 484 io->scsiio.sense_len = SSD_FULL_SIZE; 485 } 486 487 void 488 ctl_scsi_start_stop(union ctl_io *io, int start, int load_eject, int immediate, 489 int power_conditions, int onoffline __unused, 490 ctl_tag_type tag_type, uint8_t control) 491 { 492 struct scsi_start_stop_unit *cdb; 493 494 cdb = (struct scsi_start_stop_unit *)io->scsiio.cdb; 495 496 ctl_scsi_zero_io(io); 497 498 cdb->opcode = START_STOP_UNIT; 499 if (immediate) 500 cdb->byte2 |= SSS_IMMED; 501 #ifdef NEEDTOPORT 502 if (onoffline) 503 cdb->byte2 |= SSS_ONOFFLINE; 504 #endif 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(struct ctl_id 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 #endif /* !_KERNEL */ 703 void 704 ctl_scsi_zero_io(union ctl_io *io) 705 { 706 void *pool_ref; 707 708 if (io == NULL) 709 return; 710 711 pool_ref = io->io_hdr.pool; 712 713 memset(io, 0, sizeof(*io)); 714 715 io->io_hdr.pool = pool_ref; 716 } 717 718 const char * 719 ctl_scsi_task_string(struct ctl_taskio *taskio) 720 { 721 unsigned int i; 722 723 for (i = 0; i < (sizeof(ctl_task_table)/sizeof(ctl_task_table[0])); 724 i++) { 725 if (taskio->task_action == ctl_task_table[i].task_action) { 726 return (ctl_task_table[i].description); 727 } 728 } 729 730 return (NULL); 731 } 732 733 void 734 ctl_io_sbuf(union ctl_io *io, struct sbuf *sb) 735 { 736 const char *task_desc; 737 char path_str[64]; 738 739 ctl_scsi_path_string(io, path_str, sizeof(path_str)); 740 741 switch (io->io_hdr.io_type) { 742 case CTL_IO_SCSI: 743 sbuf_cat(sb, path_str); 744 ctl_scsi_command_string(&io->scsiio, NULL, sb); 745 sbuf_printf(sb, " Tag: %#x/%d\n", 746 io->scsiio.tag_num, io->scsiio.tag_type); 747 break; 748 case CTL_IO_TASK: 749 sbuf_cat(sb, path_str); 750 task_desc = ctl_scsi_task_string(&io->taskio); 751 if (task_desc == NULL) 752 sbuf_printf(sb, "Unknown Task Action %d (%#x)", 753 io->taskio.task_action, io->taskio.task_action); 754 else 755 sbuf_printf(sb, "Task Action: %s", task_desc); 756 switch (io->taskio.task_action) { 757 case CTL_TASK_ABORT_TASK: 758 sbuf_printf(sb, " Tag: %#x/%d\n", 759 io->taskio.tag_num, io->taskio.tag_type); 760 break; 761 default: 762 sbuf_printf(sb, "\n"); 763 break; 764 } 765 break; 766 default: 767 break; 768 } 769 } 770 771 void 772 ctl_io_error_sbuf(union ctl_io *io, struct scsi_inquiry_data *inq_data, 773 struct sbuf *sb) 774 { 775 struct ctl_status_desc *status_desc; 776 char path_str[64]; 777 unsigned int i; 778 779 ctl_io_sbuf(io, sb); 780 781 status_desc = NULL; 782 for (i = 0; i < (sizeof(ctl_status_table)/sizeof(ctl_status_table[0])); 783 i++) { 784 if ((io->io_hdr.status & CTL_STATUS_MASK) == 785 ctl_status_table[i].status) { 786 status_desc = &ctl_status_table[i]; 787 break; 788 } 789 } 790 791 ctl_scsi_path_string(io, path_str, sizeof(path_str)); 792 793 sbuf_cat(sb, path_str); 794 if (status_desc == NULL) 795 sbuf_printf(sb, "CTL Status: Unknown status %#x\n", 796 io->io_hdr.status); 797 else 798 sbuf_printf(sb, "CTL Status: %s\n", status_desc->description); 799 800 if ((io->io_hdr.io_type == CTL_IO_SCSI) 801 && ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_SCSI_ERROR)) { 802 sbuf_cat(sb, path_str); 803 sbuf_printf(sb, "SCSI Status: %s\n", 804 ctl_scsi_status_string(&io->scsiio)); 805 806 if (io->scsiio.scsi_status == SCSI_STATUS_CHECK_COND) 807 ctl_scsi_sense_sbuf(&io->scsiio, inq_data, 808 sb, SSS_FLAG_NONE); 809 } 810 } 811 812 char * 813 ctl_io_string(union ctl_io *io, char *str, int str_len) 814 { 815 struct sbuf sb; 816 817 sbuf_new(&sb, str, str_len, SBUF_FIXEDLEN); 818 ctl_io_sbuf(io, &sb); 819 sbuf_finish(&sb); 820 return (sbuf_data(&sb)); 821 } 822 823 char * 824 ctl_io_error_string(union ctl_io *io, struct scsi_inquiry_data *inq_data, 825 char *str, int str_len) 826 { 827 struct sbuf sb; 828 829 sbuf_new(&sb, str, str_len, SBUF_FIXEDLEN); 830 ctl_io_error_sbuf(io, inq_data, &sb); 831 sbuf_finish(&sb); 832 return (sbuf_data(&sb)); 833 } 834 835 #ifdef _KERNEL 836 837 void 838 ctl_io_print(union ctl_io *io) 839 { 840 char str[512]; 841 842 printf("%s", ctl_io_string(io, str, sizeof(str))); 843 } 844 845 void 846 ctl_io_error_print(union ctl_io *io, struct scsi_inquiry_data *inq_data) 847 { 848 char str[512]; 849 #ifdef NEEDTOPORT 850 char *message; 851 char *line; 852 853 message = io_error_string(io, inq_data, str, sizeof(str)); 854 855 for (line = strsep(&message, "\n"); line != NULL; 856 line = strsep(&message, "\n")) { 857 csevent_log(CSC_CTL | CSC_SHELF_SW | CTL_ERROR_REPORT, 858 csevent_LogType_Trace, 859 csevent_Severity_Information, 860 csevent_AlertLevel_Green, 861 csevent_FRU_Firmware, 862 csevent_FRU_Unknown, "%s", line); 863 } 864 #else 865 printf("%s", ctl_io_error_string(io, inq_data, str, sizeof(str))); 866 #endif 867 868 } 869 870 void 871 ctl_data_print(union ctl_io *io) 872 { 873 char str[128]; 874 char path_str[64]; 875 struct sbuf sb; 876 int i, j, len; 877 878 if (io->io_hdr.io_type != CTL_IO_SCSI) 879 return; 880 if (io->io_hdr.flags & CTL_FLAG_BUS_ADDR) 881 return; 882 if (io->io_hdr.flags & CTL_FLAG_EDPTR_SGLIST) /* XXX: Implement */ 883 return; 884 ctl_scsi_path_string(io, path_str, sizeof(path_str)); 885 len = min(io->scsiio.kern_data_len, 4096); 886 for (i = 0; i < len; ) { 887 sbuf_new(&sb, str, sizeof(str), SBUF_FIXEDLEN); 888 sbuf_cat(&sb, path_str); 889 sbuf_printf(&sb, " %#6x:%04x:", io->scsiio.tag_num, i); 890 for (j = 0; j < 16 && i < len; i++, j++) { 891 if (j == 8) 892 sbuf_cat(&sb, " "); 893 sbuf_printf(&sb, " %02x", io->scsiio.kern_data_ptr[i]); 894 } 895 sbuf_cat(&sb, "\n"); 896 sbuf_finish(&sb); 897 printf("%s", sbuf_data(&sb)); 898 } 899 } 900 901 #else /* _KERNEL */ 902 903 void 904 ctl_io_error_print(union ctl_io *io, struct scsi_inquiry_data *inq_data, 905 FILE *ofile) 906 { 907 char str[512]; 908 909 fprintf(ofile, "%s", ctl_io_error_string(io, inq_data, str, 910 sizeof(str))); 911 } 912 913 #endif /* _KERNEL */ 914 915 /* 916 * vim: ts=8 917 */ 918