2 * Copyright (c) 2003 Silicon Graphics International Corp.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
30 * $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/ctl_util.c#2 $
33 * CAM Target Layer SCSI library
35 * Author: Ken Merry <ken@FreeBSD.org>
38 #include <sys/cdefs.h>
39 __FBSDID("$FreeBSD$");
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>
54 #endif /* __KERNEL__ */
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>
63 struct ctl_status_desc {
65 const char *description;
68 struct ctl_task_desc {
69 ctl_task_type task_action;
70 const char *description;
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"},
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"}
96 ctl_scsi_tur(union ctl_io *io, ctl_tag_type tag_type, uint8_t control)
98 struct ctl_scsiio *ctsio;
99 struct scsi_test_unit_ready *cdb;
101 ctl_scsi_zero_io(io);
103 io->io_hdr.io_type = CTL_IO_SCSI;
105 cdb = (struct scsi_test_unit_ready *)ctsio->cdb;
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;
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,
124 struct ctl_scsiio *ctsio;
125 struct scsi_inquiry *cdb;
127 ctl_scsi_zero_io(io);
129 io->io_hdr.io_type = CTL_IO_SCSI;
131 cdb = (struct scsi_inquiry *)ctsio->cdb;
133 cdb->opcode = INQUIRY;
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;
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,
154 struct ctl_scsiio *ctsio;
155 struct scsi_request_sense *cdb;
157 ctl_scsi_zero_io(io);
159 io->io_hdr.io_type = CTL_IO_SCSI;
161 cdb = (struct scsi_request_sense *)ctsio->cdb;
163 cdb->opcode = REQUEST_SENSE;
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;
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,
183 struct ctl_scsiio *ctsio;
184 struct scsi_report_luns *cdb;
186 ctl_scsi_zero_io(io);
188 io->io_hdr.io_type = CTL_IO_SCSI;
190 cdb = (struct scsi_report_luns *)ctsio->cdb;
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;
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)
213 struct ctl_scsiio *ctsio;
214 struct scsi_write_buffer *cdb;
216 ctl_scsi_zero_io(io);
218 io->io_hdr.io_type = CTL_IO_SCSI;
220 cdb = (struct scsi_write_buffer *)ctsio->cdb;
222 if (read_buffer != 0)
223 cdb->opcode = READ_BUFFER;
225 cdb->opcode = WRITE_BUFFER;
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;
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;
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,
252 struct ctl_scsiio *ctsio;
254 ctl_scsi_zero_io(io);
256 io->io_hdr.io_type = CTL_IO_SCSI;
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.)
267 if ((minimum_cdb_size < 10)
268 && ((lba & 0x1fffff) == lba)
269 && ((num_blocks & 0xff) == num_blocks)
271 struct scsi_rw_6 *cdb;
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.
280 cdb = (struct scsi_rw_6 *)ctsio->cdb;
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;
287 ctsio->cdb_len = sizeof(*cdb);
289 } else if ((minimum_cdb_size < 12)
290 && ((num_blocks & 0xffff) == num_blocks)
291 && ((lba & 0xffffffff) == lba)) {
292 struct scsi_rw_10 *cdb;
294 cdb = (struct scsi_rw_10 *)ctsio->cdb;
296 cdb->opcode = (read_op) ? READ_10 : WRITE_10;
298 scsi_ulto4b(lba, cdb->addr);
300 scsi_ulto2b(num_blocks, cdb->length);
301 cdb->control = control;
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;
309 cdb = (struct scsi_rw_12 *)ctsio->cdb;
311 cdb->opcode = (read_op) ? READ_12 : WRITE_12;
313 scsi_ulto4b(lba, cdb->addr);
314 scsi_ulto4b(num_blocks, cdb->length);
316 cdb->control = control;
318 ctsio->cdb_len = sizeof(*cdb);
320 struct scsi_rw_16 *cdb;
322 cdb = (struct scsi_rw_16 *)ctsio->cdb;
324 cdb->opcode = (read_op) ? READ_16 : WRITE_16;
326 scsi_u64to8b(lba, cdb->addr);
327 scsi_ulto4b(num_blocks, cdb->length);
329 cdb->control = control;
331 ctsio->cdb_len = sizeof(*cdb);
334 io->io_hdr.io_type = CTL_IO_SCSI;
336 io->io_hdr.flags = CTL_FLAG_DATA_IN;
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;
348 ctl_scsi_read_capacity(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len,
349 uint32_t addr, int reladr, int pmi,
350 ctl_tag_type tag_type, uint8_t control)
352 struct scsi_read_capacity *cdb;
354 ctl_scsi_zero_io(io);
356 io->io_hdr.io_type = CTL_IO_SCSI;
357 cdb = (struct scsi_read_capacity *)io->scsiio.cdb;
359 cdb->opcode = READ_CAPACITY;
361 cdb->byte2 = SRC_RELADR;
364 scsi_ulto4b(addr, cdb->addr);
365 cdb->control = control;
366 io->io_hdr.io_type = CTL_IO_SCSI;
367 io->io_hdr.flags = CTL_FLAG_DATA_IN;
368 io->scsiio.tag_type = tag_type;
369 io->scsiio.ext_data_ptr = data_ptr;
370 io->scsiio.ext_data_len = data_len;
371 io->scsiio.ext_sg_entries = 0;
372 io->scsiio.ext_data_filled = 0;
373 io->scsiio.sense_len = SSD_FULL_SIZE;
377 ctl_scsi_read_capacity_16(union ctl_io *io, uint8_t *data_ptr,
378 uint32_t data_len, uint64_t addr, int reladr,
379 int pmi, ctl_tag_type tag_type, uint8_t control)
381 struct scsi_read_capacity_16 *cdb;
383 ctl_scsi_zero_io(io);
385 io->io_hdr.io_type = CTL_IO_SCSI;
386 cdb = (struct scsi_read_capacity_16 *)io->scsiio.cdb;
388 cdb->opcode = SERVICE_ACTION_IN;
389 cdb->service_action = SRC16_SERVICE_ACTION;
391 cdb->reladr |= SRC16_RELADR;
393 cdb->reladr |= SRC16_PMI;
394 scsi_u64to8b(addr, cdb->addr);
395 scsi_ulto4b(data_len, cdb->alloc_len);
396 cdb->control = control;
398 io->io_hdr.io_type = CTL_IO_SCSI;
399 io->io_hdr.flags = CTL_FLAG_DATA_IN;
400 io->scsiio.tag_type = tag_type;
401 io->scsiio.ext_data_ptr = data_ptr;
402 io->scsiio.ext_data_len = data_len;
403 io->scsiio.ext_sg_entries = 0;
404 io->scsiio.ext_data_filled = 0;
405 io->scsiio.sense_len = SSD_FULL_SIZE;
409 ctl_scsi_mode_sense(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len,
410 int dbd, int llbaa, uint8_t page_code, uint8_t pc,
411 uint8_t subpage, int minimum_cdb_size,
412 ctl_tag_type tag_type, uint8_t control)
414 ctl_scsi_zero_io(io);
416 if ((minimum_cdb_size < 10)
418 && (data_len < 256)) {
419 struct scsi_mode_sense_6 *cdb;
421 cdb = (struct scsi_mode_sense_6 *)io->scsiio.cdb;
423 cdb->opcode = MODE_SENSE_6;
425 cdb->byte2 |= SMS_DBD;
426 cdb->page = page_code | pc;
427 cdb->subpage = subpage;
428 cdb->length = data_len;
429 cdb->control = control;
431 struct scsi_mode_sense_10 *cdb;
433 cdb = (struct scsi_mode_sense_10 *)io->scsiio.cdb;
435 cdb->opcode = MODE_SENSE_10;
437 cdb->byte2 |= SMS_DBD;
439 cdb->byte2 |= SMS10_LLBAA;
440 cdb->page = page_code | pc;
441 cdb->subpage = subpage;
442 scsi_ulto2b(data_len, cdb->length);
443 cdb->control = control;
446 io->io_hdr.io_type = CTL_IO_SCSI;
447 io->io_hdr.flags = CTL_FLAG_DATA_IN;
448 io->scsiio.tag_type = tag_type;
449 io->scsiio.ext_data_ptr = data_ptr;
450 io->scsiio.ext_data_len = data_len;
451 io->scsiio.ext_sg_entries = 0;
452 io->scsiio.ext_data_filled = 0;
453 io->scsiio.sense_len = SSD_FULL_SIZE;
457 ctl_scsi_start_stop(union ctl_io *io, int start, int load_eject, int immediate,
458 int power_conditions, int onoffline __unused,
459 ctl_tag_type tag_type, uint8_t control)
461 struct scsi_start_stop_unit *cdb;
463 cdb = (struct scsi_start_stop_unit *)io->scsiio.cdb;
465 ctl_scsi_zero_io(io);
467 cdb->opcode = START_STOP_UNIT;
469 cdb->byte2 |= SSS_IMMED;
472 cdb->byte2 |= SSS_ONOFFLINE;
474 cdb->how = power_conditions;
476 cdb->how |= SSS_LOEJ;
478 cdb->how |= SSS_START;
479 cdb->control = control;
480 io->io_hdr.io_type = CTL_IO_SCSI;
481 io->io_hdr.flags = CTL_FLAG_DATA_NONE;
482 io->scsiio.tag_type = tag_type;
483 io->scsiio.ext_data_ptr = NULL;
484 io->scsiio.ext_data_len = 0;
485 io->scsiio.ext_sg_entries = 0;
486 io->scsiio.ext_data_filled = 0;
487 io->scsiio.sense_len = SSD_FULL_SIZE;
491 ctl_scsi_sync_cache(union ctl_io *io, int immed, int reladr,
492 int minimum_cdb_size, uint64_t starting_lba,
493 uint32_t block_count, ctl_tag_type tag_type,
496 ctl_scsi_zero_io(io);
498 if ((minimum_cdb_size < 16)
499 && ((block_count & 0xffff) == block_count)
500 && ((starting_lba & 0xffffffff) == starting_lba)) {
501 struct scsi_sync_cache *cdb;
503 cdb = (struct scsi_sync_cache *)io->scsiio.cdb;
505 cdb->opcode = SYNCHRONIZE_CACHE;
507 cdb->byte2 |= SSC_RELADR;
510 cdb->byte2 |= SSC_IMMED;
512 scsi_ulto4b(starting_lba, cdb->begin_lba);
513 scsi_ulto2b(block_count, cdb->lb_count);
514 cdb->control = control;
516 struct scsi_sync_cache_16 *cdb;
518 cdb = (struct scsi_sync_cache_16 *)io->scsiio.cdb;
520 cdb->opcode = SYNCHRONIZE_CACHE_16;
522 cdb->byte2 |= SSC_RELADR;
525 cdb->byte2 |= SSC_IMMED;
527 scsi_u64to8b(starting_lba, cdb->begin_lba);
528 scsi_ulto4b(block_count, cdb->lb_count);
529 cdb->control = control;
531 io->io_hdr.io_type = CTL_IO_SCSI;
532 io->io_hdr.flags = CTL_FLAG_DATA_NONE;
533 io->scsiio.tag_type = tag_type;
534 io->scsiio.ext_data_ptr = NULL;
535 io->scsiio.ext_data_len = 0;
536 io->scsiio.ext_sg_entries = 0;
537 io->scsiio.ext_data_filled = 0;
538 io->scsiio.sense_len = SSD_FULL_SIZE;
542 ctl_scsi_persistent_res_in(union ctl_io *io, uint8_t *data_ptr,
543 uint32_t data_len, int action,
544 ctl_tag_type tag_type, uint8_t control)
547 struct scsi_per_res_in *cdb;
549 ctl_scsi_zero_io(io);
551 cdb = (struct scsi_per_res_in *)io->scsiio.cdb;
552 cdb->opcode = PERSISTENT_RES_IN;
553 cdb->action = action;
554 scsi_ulto2b(data_len, cdb->length);
555 cdb->control = control;
557 io->io_hdr.io_type = CTL_IO_SCSI;
558 io->io_hdr.flags = CTL_FLAG_DATA_IN;
559 io->scsiio.tag_type = tag_type;
560 io->scsiio.ext_data_ptr = data_ptr;
561 io->scsiio.ext_data_len = data_len;
562 io->scsiio.ext_sg_entries = 0;
563 io->scsiio.ext_data_filled = 0;
564 io->scsiio.sense_len = SSD_FULL_SIZE;
568 ctl_scsi_persistent_res_out(union ctl_io *io, uint8_t *data_ptr,
569 uint32_t data_len, int action, int type,
570 uint64_t key, uint64_t sa_key,
571 ctl_tag_type tag_type, uint8_t control)
574 struct scsi_per_res_out *cdb;
575 struct scsi_per_res_out_parms *params;
577 ctl_scsi_zero_io(io);
579 cdb = (struct scsi_per_res_out *)io->scsiio.cdb;
580 params = (struct scsi_per_res_out_parms *)data_ptr;
582 cdb->opcode = PERSISTENT_RES_OUT;
586 cdb->action = action;
608 scsi_ulto4b(data_len, cdb->length);
609 cdb->control = control;
611 scsi_u64to8b(key, params->res_key.key);
612 scsi_u64to8b(sa_key, params->serv_act_res_key);
614 io->io_hdr.io_type = CTL_IO_SCSI;
615 io->io_hdr.flags = CTL_FLAG_DATA_OUT;
616 io->scsiio.tag_type = tag_type;
617 io->scsiio.ext_data_ptr = data_ptr;
618 io->scsiio.ext_data_len = data_len;
619 io->scsiio.ext_sg_entries = 0;
620 io->scsiio.ext_data_filled = 0;
621 io->scsiio.sense_len = SSD_FULL_SIZE;
626 ctl_scsi_maintenance_in(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len,
627 uint8_t action, ctl_tag_type tag_type, uint8_t control)
629 struct scsi_maintenance_in *cdb;
631 ctl_scsi_zero_io(io);
633 cdb = (struct scsi_maintenance_in *)io->scsiio.cdb;
634 cdb->opcode = MAINTENANCE_IN;
636 scsi_ulto4b(data_len, cdb->length);
637 cdb->control = control;
639 io->io_hdr.io_type = CTL_IO_SCSI;
640 io->io_hdr.flags = CTL_FLAG_DATA_IN;
641 io->scsiio.tag_type = tag_type;
642 io->scsiio.ext_data_ptr = data_ptr;
643 io->scsiio.ext_data_len = data_len;
644 io->scsiio.ext_sg_entries = 0;
645 io->scsiio.ext_data_filled = 0;
646 io->scsiio.sense_len = SSD_FULL_SIZE;
651 ctl_scsi_alloc_io(struct ctl_id initid)
655 io = (union ctl_io *)malloc(sizeof(*io));
659 io->io_hdr.nexus.initid = initid;
666 ctl_scsi_free_io(union ctl_io *io)
671 #endif /* !_KERNEL */
673 ctl_scsi_zero_io(union ctl_io *io)
680 pool_ref = io->io_hdr.pool;
682 memset(io, 0, sizeof(*io));
684 io->io_hdr.pool = pool_ref;
688 ctl_scsi_task_string(struct ctl_taskio *taskio)
692 for (i = 0; i < (sizeof(ctl_task_table)/sizeof(ctl_task_table[0]));
694 if (taskio->task_action == ctl_task_table[i].task_action) {
695 return (ctl_task_table[i].description);
703 ctl_io_error_sbuf(union ctl_io *io, struct scsi_inquiry_data *inq_data,
706 struct ctl_status_desc *status_desc;
712 for (i = 0; i < (sizeof(ctl_status_table)/sizeof(ctl_status_table[0]));
714 if ((io->io_hdr.status & CTL_STATUS_MASK) ==
715 ctl_status_table[i].status) {
716 status_desc = &ctl_status_table[i];
721 ctl_scsi_path_string(io, path_str, sizeof(path_str));
723 switch (io->io_hdr.io_type) {
725 sbuf_cat(sb, path_str);
727 ctl_scsi_command_string(&io->scsiio, NULL, sb);
729 sbuf_printf(sb, "\n");
731 sbuf_printf(sb, "%sTag: 0x%04x, Type: %d\n", path_str,
732 io->scsiio.tag_num, io->scsiio.tag_type);
735 const char *task_desc;
737 sbuf_cat(sb, path_str);
739 task_desc = ctl_scsi_task_string(&io->taskio);
741 if (task_desc == NULL)
742 sbuf_printf(sb, "Unknown Task Action %d (%#x)",
743 io->taskio.task_action,
744 io->taskio.task_action);
746 sbuf_printf(sb, "Task Action: %s", task_desc);
748 sbuf_printf(sb, "\n");
750 switch (io->taskio.task_action) {
751 case CTL_TASK_ABORT_TASK:
752 case CTL_TASK_ABORT_TASK_SET:
753 case CTL_TASK_CLEAR_TASK_SET:
754 sbuf_printf(sb, "%sTag: 0x%04x, Type: %d\n", path_str,
756 io->taskio.tag_type);
767 sbuf_cat(sb, path_str);
768 if (status_desc == NULL)
769 sbuf_printf(sb, "CTL Status: Unknown status %#x\n",
772 sbuf_printf(sb, "CTL Status: %s\n", status_desc->description);
774 if ((io->io_hdr.io_type == CTL_IO_SCSI)
775 && ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_SCSI_ERROR)) {
776 sbuf_cat(sb, path_str);
777 sbuf_printf(sb, "SCSI Status: %s\n",
778 ctl_scsi_status_string(&io->scsiio));
780 if (io->scsiio.scsi_status == SCSI_STATUS_CHECK_COND)
781 ctl_scsi_sense_sbuf(&io->scsiio, inq_data,
787 ctl_io_error_string(union ctl_io *io, struct scsi_inquiry_data *inq_data,
788 char *str, int str_len)
792 sbuf_new(&sb, str, str_len, SBUF_FIXEDLEN);
794 ctl_io_error_sbuf(io, inq_data, &sb);
798 return (sbuf_data(&sb));
804 ctl_io_error_print(union ctl_io *io, struct scsi_inquiry_data *inq_data)
811 message = io_error_string(io, inq_data, str, sizeof(str));
813 for (line = strsep(&message, "\n"); line != NULL;
814 line = strsep(&message, "\n")) {
815 csevent_log(CSC_CTL | CSC_SHELF_SW | CTL_ERROR_REPORT,
816 csevent_LogType_Trace,
817 csevent_Severity_Information,
818 csevent_AlertLevel_Green,
819 csevent_FRU_Firmware,
820 csevent_FRU_Unknown, "%s", line);
823 printf("%s", ctl_io_error_string(io, inq_data, str, sizeof(str)));
831 ctl_io_error_print(union ctl_io *io, struct scsi_inquiry_data *inq_data,
836 fprintf(ofile, "%s", ctl_io_error_string(io, inq_data, str,