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_LUN_RESET, "LUN Reset"},
88 {CTL_TASK_TARGET_RESET, "Target Reset"},
89 {CTL_TASK_BUS_RESET, "Bus Reset"},
90 {CTL_TASK_PORT_LOGIN, "Port Login"},
91 {CTL_TASK_PORT_LOGOUT, "Port Logout"}
95 ctl_scsi_tur(union ctl_io *io, ctl_tag_type tag_type, uint8_t control)
97 struct ctl_scsiio *ctsio;
98 struct scsi_test_unit_ready *cdb;
100 ctl_scsi_zero_io(io);
102 io->io_hdr.io_type = CTL_IO_SCSI;
104 cdb = (struct scsi_test_unit_ready *)ctsio->cdb;
106 cdb->opcode = TEST_UNIT_READY;
107 cdb->control = control;
108 io->io_hdr.flags = CTL_FLAG_DATA_NONE;
109 ctsio->tag_type = tag_type;
110 ctsio->cdb_len = sizeof(*cdb);
111 ctsio->ext_data_len = 0;
112 ctsio->ext_data_ptr = NULL;
113 ctsio->ext_sg_entries = 0;
114 ctsio->ext_data_filled = 0;
115 ctsio->sense_len = SSD_FULL_SIZE;
119 ctl_scsi_inquiry(union ctl_io *io, uint8_t *data_ptr, int32_t data_len,
120 uint8_t byte2, uint8_t page_code, ctl_tag_type tag_type,
123 struct ctl_scsiio *ctsio;
124 struct scsi_inquiry *cdb;
126 ctl_scsi_zero_io(io);
128 io->io_hdr.io_type = CTL_IO_SCSI;
130 cdb = (struct scsi_inquiry *)ctsio->cdb;
132 cdb->opcode = INQUIRY;
134 cdb->page_code = page_code;
135 cdb->control = control;
136 scsi_ulto2b(data_len, cdb->length);
137 io->io_hdr.io_type = CTL_IO_SCSI;
138 io->io_hdr.flags = CTL_FLAG_DATA_IN;
139 ctsio->tag_type = tag_type;
140 ctsio->cdb_len = sizeof(*cdb);
141 ctsio->ext_data_len = data_len;
142 ctsio->ext_data_ptr = data_ptr;
143 ctsio->ext_sg_entries = 0;
144 ctsio->ext_data_filled = 0;
145 ctsio->sense_len = SSD_FULL_SIZE;
149 ctl_scsi_request_sense(union ctl_io *io, uint8_t *data_ptr,
150 int32_t data_len, uint8_t byte2, ctl_tag_type tag_type,
153 struct ctl_scsiio *ctsio;
154 struct scsi_request_sense *cdb;
156 ctl_scsi_zero_io(io);
158 io->io_hdr.io_type = CTL_IO_SCSI;
160 cdb = (struct scsi_request_sense *)ctsio->cdb;
162 cdb->opcode = REQUEST_SENSE;
164 cdb->control = control;
165 cdb->length = data_len;
166 io->io_hdr.io_type = CTL_IO_SCSI;
167 io->io_hdr.flags = CTL_FLAG_DATA_IN;
168 ctsio->tag_type = tag_type;
169 ctsio->cdb_len = sizeof(*cdb);
170 ctsio->ext_data_ptr = data_ptr;
171 ctsio->ext_data_len = data_len;
172 ctsio->ext_sg_entries = 0;
173 ctsio->ext_data_filled = 0;
174 ctsio->sense_len = SSD_FULL_SIZE;
178 ctl_scsi_report_luns(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len,
179 uint8_t select_report, ctl_tag_type tag_type,
182 struct ctl_scsiio *ctsio;
183 struct scsi_report_luns *cdb;
185 ctl_scsi_zero_io(io);
187 io->io_hdr.io_type = CTL_IO_SCSI;
189 cdb = (struct scsi_report_luns *)ctsio->cdb;
191 cdb->opcode = REPORT_LUNS;
192 cdb->select_report = select_report;
193 scsi_ulto4b(data_len, cdb->length);
194 cdb->control = control;
195 io->io_hdr.io_type = CTL_IO_SCSI;
196 io->io_hdr.flags = CTL_FLAG_DATA_IN;
197 ctsio->tag_type = tag_type;
198 ctsio->cdb_len = sizeof(*cdb);
199 ctsio->ext_data_ptr = data_ptr;
200 ctsio->ext_data_len = data_len;
201 ctsio->ext_sg_entries = 0;
202 ctsio->ext_data_filled = 0;
203 ctsio->sense_len = SSD_FULL_SIZE;
207 ctl_scsi_read_write_buffer(union ctl_io *io, uint8_t *data_ptr,
208 uint32_t data_len, int read_buffer, uint8_t mode,
209 uint8_t buffer_id, uint32_t buffer_offset,
210 ctl_tag_type tag_type, uint8_t control)
212 struct ctl_scsiio *ctsio;
213 struct scsi_write_buffer *cdb;
215 ctl_scsi_zero_io(io);
217 io->io_hdr.io_type = CTL_IO_SCSI;
219 cdb = (struct scsi_write_buffer *)ctsio->cdb;
221 if (read_buffer != 0)
222 cdb->opcode = READ_BUFFER;
224 cdb->opcode = WRITE_BUFFER;
226 cdb->byte2 = mode & RWB_MODE;
227 cdb->buffer_id = buffer_id;
228 scsi_ulto3b(buffer_offset, cdb->offset);
229 scsi_ulto3b(data_len, cdb->length);
230 cdb->control = control;
231 io->io_hdr.io_type = CTL_IO_SCSI;
232 if (read_buffer != 0)
233 io->io_hdr.flags = CTL_FLAG_DATA_IN;
235 io->io_hdr.flags = CTL_FLAG_DATA_OUT;
236 ctsio->tag_type = tag_type;
237 ctsio->cdb_len = sizeof(*cdb);
238 ctsio->ext_data_ptr = data_ptr;
239 ctsio->ext_data_len = data_len;
240 ctsio->ext_sg_entries = 0;
241 ctsio->ext_data_filled = 0;
242 ctsio->sense_len = SSD_FULL_SIZE;
246 ctl_scsi_read_write(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len,
247 int read_op, uint8_t byte2, int minimum_cdb_size,
248 uint64_t lba, uint32_t num_blocks, ctl_tag_type tag_type,
251 struct ctl_scsiio *ctsio;
253 ctl_scsi_zero_io(io);
255 io->io_hdr.io_type = CTL_IO_SCSI;
259 * Pick out the smallest CDB that will hold the user's request.
260 * minimum_cdb_size allows cranking the CDB size up, even for
261 * requests that would not normally need a large CDB. This can be
262 * useful for testing (e.g. to make sure READ_16 support works without
263 * having an array larger than 2TB) and for compatibility -- e.g.
264 * if your device doesn't support READ_6. (ATAPI drives don't.)
266 if ((minimum_cdb_size < 10)
267 && ((lba & 0x1fffff) == lba)
268 && ((num_blocks & 0xff) == num_blocks)
270 struct scsi_rw_6 *cdb;
273 * Note that according to SBC-2, the target should return 256
274 * blocks if the transfer length in a READ(6) or WRITE(6) CDB
275 * is set to 0. Since it's possible that some targets
276 * won't do the right thing, we only send a READ(6) or
277 * WRITE(6) for transfer sizes up to and including 255 blocks.
279 cdb = (struct scsi_rw_6 *)ctsio->cdb;
281 cdb->opcode = (read_op) ? READ_6 : WRITE_6;
282 scsi_ulto3b(lba, cdb->addr);
283 cdb->length = num_blocks & 0xff;
284 cdb->control = control;
286 ctsio->cdb_len = sizeof(*cdb);
288 } else if ((minimum_cdb_size < 12)
289 && ((num_blocks & 0xffff) == num_blocks)
290 && ((lba & 0xffffffff) == lba)) {
291 struct scsi_rw_10 *cdb;
293 cdb = (struct scsi_rw_10 *)ctsio->cdb;
295 cdb->opcode = (read_op) ? READ_10 : WRITE_10;
297 scsi_ulto4b(lba, cdb->addr);
299 scsi_ulto2b(num_blocks, cdb->length);
300 cdb->control = control;
302 ctsio->cdb_len = sizeof(*cdb);
303 } else if ((minimum_cdb_size < 16)
304 && ((num_blocks & 0xffffffff) == num_blocks)
305 && ((lba & 0xffffffff) == lba)) {
306 struct scsi_rw_12 *cdb;
308 cdb = (struct scsi_rw_12 *)ctsio->cdb;
310 cdb->opcode = (read_op) ? READ_12 : WRITE_12;
312 scsi_ulto4b(lba, cdb->addr);
313 scsi_ulto4b(num_blocks, cdb->length);
315 cdb->control = control;
317 ctsio->cdb_len = sizeof(*cdb);
319 struct scsi_rw_16 *cdb;
321 cdb = (struct scsi_rw_16 *)ctsio->cdb;
323 cdb->opcode = (read_op) ? READ_16 : WRITE_16;
325 scsi_u64to8b(lba, cdb->addr);
326 scsi_ulto4b(num_blocks, cdb->length);
328 cdb->control = control;
330 ctsio->cdb_len = sizeof(*cdb);
333 io->io_hdr.io_type = CTL_IO_SCSI;
335 io->io_hdr.flags = CTL_FLAG_DATA_IN;
337 io->io_hdr.flags = CTL_FLAG_DATA_OUT;
338 ctsio->tag_type = tag_type;
339 ctsio->ext_data_ptr = data_ptr;
340 ctsio->ext_data_len = data_len;
341 ctsio->ext_sg_entries = 0;
342 ctsio->ext_data_filled = 0;
343 ctsio->sense_len = SSD_FULL_SIZE;
347 ctl_scsi_read_capacity(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len,
348 uint32_t addr, int reladr, int pmi,
349 ctl_tag_type tag_type, uint8_t control)
351 struct scsi_read_capacity *cdb;
353 ctl_scsi_zero_io(io);
355 io->io_hdr.io_type = CTL_IO_SCSI;
356 cdb = (struct scsi_read_capacity *)io->scsiio.cdb;
358 cdb->opcode = READ_CAPACITY;
360 cdb->byte2 = SRC_RELADR;
363 scsi_ulto4b(addr, cdb->addr);
364 cdb->control = control;
365 io->io_hdr.io_type = CTL_IO_SCSI;
366 io->io_hdr.flags = CTL_FLAG_DATA_IN;
367 io->scsiio.tag_type = tag_type;
368 io->scsiio.ext_data_ptr = data_ptr;
369 io->scsiio.ext_data_len = data_len;
370 io->scsiio.ext_sg_entries = 0;
371 io->scsiio.ext_data_filled = 0;
372 io->scsiio.sense_len = SSD_FULL_SIZE;
376 ctl_scsi_read_capacity_16(union ctl_io *io, uint8_t *data_ptr,
377 uint32_t data_len, uint64_t addr, int reladr,
378 int pmi, ctl_tag_type tag_type, uint8_t control)
380 struct scsi_read_capacity_16 *cdb;
382 ctl_scsi_zero_io(io);
384 io->io_hdr.io_type = CTL_IO_SCSI;
385 cdb = (struct scsi_read_capacity_16 *)io->scsiio.cdb;
387 cdb->opcode = SERVICE_ACTION_IN;
388 cdb->service_action = SRC16_SERVICE_ACTION;
390 cdb->reladr |= SRC16_RELADR;
392 cdb->reladr |= SRC16_PMI;
393 scsi_u64to8b(addr, cdb->addr);
394 scsi_ulto4b(data_len, cdb->alloc_len);
395 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;
408 ctl_scsi_mode_sense(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len,
409 int dbd, int llbaa, uint8_t page_code, uint8_t pc,
410 uint8_t subpage, int minimum_cdb_size,
411 ctl_tag_type tag_type, uint8_t control)
413 ctl_scsi_zero_io(io);
415 if ((minimum_cdb_size < 10)
417 && (data_len < 256)) {
418 struct scsi_mode_sense_6 *cdb;
420 cdb = (struct scsi_mode_sense_6 *)io->scsiio.cdb;
422 cdb->opcode = MODE_SENSE_6;
424 cdb->byte2 |= SMS_DBD;
425 cdb->page = page_code | pc;
426 cdb->subpage = subpage;
427 cdb->length = data_len;
428 cdb->control = control;
430 struct scsi_mode_sense_10 *cdb;
432 cdb = (struct scsi_mode_sense_10 *)io->scsiio.cdb;
434 cdb->opcode = MODE_SENSE_10;
436 cdb->byte2 |= SMS_DBD;
438 cdb->byte2 |= SMS10_LLBAA;
439 cdb->page = page_code | pc;
440 cdb->subpage = subpage;
441 scsi_ulto2b(data_len, cdb->length);
442 cdb->control = control;
445 io->io_hdr.io_type = CTL_IO_SCSI;
446 io->io_hdr.flags = CTL_FLAG_DATA_IN;
447 io->scsiio.tag_type = tag_type;
448 io->scsiio.ext_data_ptr = data_ptr;
449 io->scsiio.ext_data_len = data_len;
450 io->scsiio.ext_sg_entries = 0;
451 io->scsiio.ext_data_filled = 0;
452 io->scsiio.sense_len = SSD_FULL_SIZE;
456 ctl_scsi_start_stop(union ctl_io *io, int start, int load_eject, int immediate,
457 int power_conditions, int onoffline __unused,
458 ctl_tag_type tag_type, uint8_t control)
460 struct scsi_start_stop_unit *cdb;
462 cdb = (struct scsi_start_stop_unit *)io->scsiio.cdb;
464 ctl_scsi_zero_io(io);
466 cdb->opcode = START_STOP_UNIT;
468 cdb->byte2 |= SSS_IMMED;
471 cdb->byte2 |= SSS_ONOFFLINE;
473 cdb->how = power_conditions;
475 cdb->how |= SSS_LOEJ;
477 cdb->how |= SSS_START;
478 cdb->control = control;
479 io->io_hdr.io_type = CTL_IO_SCSI;
480 io->io_hdr.flags = CTL_FLAG_DATA_NONE;
481 io->scsiio.tag_type = tag_type;
482 io->scsiio.ext_data_ptr = NULL;
483 io->scsiio.ext_data_len = 0;
484 io->scsiio.ext_sg_entries = 0;
485 io->scsiio.ext_data_filled = 0;
486 io->scsiio.sense_len = SSD_FULL_SIZE;
490 ctl_scsi_sync_cache(union ctl_io *io, int immed, int reladr,
491 int minimum_cdb_size, uint64_t starting_lba,
492 uint32_t block_count, ctl_tag_type tag_type,
495 ctl_scsi_zero_io(io);
497 if ((minimum_cdb_size < 16)
498 && ((block_count & 0xffff) == block_count)
499 && ((starting_lba & 0xffffffff) == starting_lba)) {
500 struct scsi_sync_cache *cdb;
502 cdb = (struct scsi_sync_cache *)io->scsiio.cdb;
504 cdb->opcode = SYNCHRONIZE_CACHE;
506 cdb->byte2 |= SSC_RELADR;
509 cdb->byte2 |= SSC_IMMED;
511 scsi_ulto4b(starting_lba, cdb->begin_lba);
512 scsi_ulto2b(block_count, cdb->lb_count);
513 cdb->control = control;
515 struct scsi_sync_cache_16 *cdb;
517 cdb = (struct scsi_sync_cache_16 *)io->scsiio.cdb;
519 cdb->opcode = SYNCHRONIZE_CACHE_16;
521 cdb->byte2 |= SSC_RELADR;
524 cdb->byte2 |= SSC_IMMED;
526 scsi_u64to8b(starting_lba, cdb->begin_lba);
527 scsi_ulto4b(block_count, cdb->lb_count);
528 cdb->control = control;
530 io->io_hdr.io_type = CTL_IO_SCSI;
531 io->io_hdr.flags = CTL_FLAG_DATA_NONE;
532 io->scsiio.tag_type = tag_type;
533 io->scsiio.ext_data_ptr = NULL;
534 io->scsiio.ext_data_len = 0;
535 io->scsiio.ext_sg_entries = 0;
536 io->scsiio.ext_data_filled = 0;
537 io->scsiio.sense_len = SSD_FULL_SIZE;
541 ctl_scsi_persistent_res_in(union ctl_io *io, uint8_t *data_ptr,
542 uint32_t data_len, int action,
543 ctl_tag_type tag_type, uint8_t control)
546 struct scsi_per_res_in *cdb;
548 ctl_scsi_zero_io(io);
550 cdb = (struct scsi_per_res_in *)io->scsiio.cdb;
551 cdb->opcode = PERSISTENT_RES_IN;
552 cdb->action = action;
553 scsi_ulto2b(data_len, cdb->length);
554 cdb->control = control;
556 io->io_hdr.io_type = CTL_IO_SCSI;
557 io->io_hdr.flags = CTL_FLAG_DATA_IN;
558 io->scsiio.tag_type = tag_type;
559 io->scsiio.ext_data_ptr = data_ptr;
560 io->scsiio.ext_data_len = data_len;
561 io->scsiio.ext_sg_entries = 0;
562 io->scsiio.ext_data_filled = 0;
563 io->scsiio.sense_len = SSD_FULL_SIZE;
567 ctl_scsi_persistent_res_out(union ctl_io *io, uint8_t *data_ptr,
568 uint32_t data_len, int action, int type,
569 uint64_t key, uint64_t sa_key,
570 ctl_tag_type tag_type, uint8_t control)
573 struct scsi_per_res_out *cdb;
574 struct scsi_per_res_out_parms *params;
576 ctl_scsi_zero_io(io);
578 cdb = (struct scsi_per_res_out *)io->scsiio.cdb;
579 params = (struct scsi_per_res_out_parms *)data_ptr;
581 cdb->opcode = PERSISTENT_RES_OUT;
585 cdb->action = action;
607 scsi_ulto4b(data_len, cdb->length);
608 cdb->control = control;
610 scsi_u64to8b(key, params->res_key.key);
611 scsi_u64to8b(sa_key, params->serv_act_res_key);
613 io->io_hdr.io_type = CTL_IO_SCSI;
614 io->io_hdr.flags = CTL_FLAG_DATA_OUT;
615 io->scsiio.tag_type = tag_type;
616 io->scsiio.ext_data_ptr = data_ptr;
617 io->scsiio.ext_data_len = data_len;
618 io->scsiio.ext_sg_entries = 0;
619 io->scsiio.ext_data_filled = 0;
620 io->scsiio.sense_len = SSD_FULL_SIZE;
625 ctl_scsi_maintenance_in(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len,
626 uint8_t action, ctl_tag_type tag_type, uint8_t control)
628 struct scsi_maintenance_in *cdb;
630 ctl_scsi_zero_io(io);
632 cdb = (struct scsi_maintenance_in *)io->scsiio.cdb;
633 cdb->opcode = MAINTENANCE_IN;
635 scsi_ulto4b(data_len, cdb->length);
636 cdb->control = control;
638 io->io_hdr.io_type = CTL_IO_SCSI;
639 io->io_hdr.flags = CTL_FLAG_DATA_IN;
640 io->scsiio.tag_type = tag_type;
641 io->scsiio.ext_data_ptr = data_ptr;
642 io->scsiio.ext_data_len = data_len;
643 io->scsiio.ext_sg_entries = 0;
644 io->scsiio.ext_data_filled = 0;
645 io->scsiio.sense_len = SSD_FULL_SIZE;
650 ctl_scsi_alloc_io(struct ctl_id initid)
654 io = (union ctl_io *)malloc(sizeof(*io));
658 io->io_hdr.nexus.initid = initid;
665 ctl_scsi_free_io(union ctl_io *io)
670 #endif /* !_KERNEL */
672 ctl_scsi_zero_io(union ctl_io *io)
679 pool_ref = io->io_hdr.pool;
681 memset(io, 0, sizeof(*io));
683 io->io_hdr.pool = pool_ref;
687 ctl_scsi_task_string(struct ctl_taskio *taskio)
691 for (i = 0; i < (sizeof(ctl_task_table)/sizeof(ctl_task_table[0]));
693 if (taskio->task_action == ctl_task_table[i].task_action) {
694 return (ctl_task_table[i].description);
702 ctl_io_error_sbuf(union ctl_io *io, struct scsi_inquiry_data *inq_data,
705 struct ctl_status_desc *status_desc;
711 for (i = 0; i < (sizeof(ctl_status_table)/sizeof(ctl_status_table[0]));
713 if ((io->io_hdr.status & CTL_STATUS_MASK) ==
714 ctl_status_table[i].status) {
715 status_desc = &ctl_status_table[i];
720 ctl_scsi_path_string(io, path_str, sizeof(path_str));
722 switch (io->io_hdr.io_type) {
724 sbuf_cat(sb, path_str);
726 ctl_scsi_command_string(&io->scsiio, NULL, sb);
728 sbuf_printf(sb, "\n");
730 sbuf_printf(sb, "%sTag: 0x%04x, Type: %d\n", path_str,
731 io->scsiio.tag_num, io->scsiio.tag_type);
734 const char *task_desc;
736 sbuf_cat(sb, path_str);
738 task_desc = ctl_scsi_task_string(&io->taskio);
740 if (task_desc == NULL)
741 sbuf_printf(sb, "Unknown Task Action %d (%#x)",
742 io->taskio.task_action,
743 io->taskio.task_action);
745 sbuf_printf(sb, "Task Action: %s", task_desc);
747 sbuf_printf(sb, "\n");
749 switch (io->taskio.task_action) {
750 case CTL_TASK_ABORT_TASK:
751 case CTL_TASK_ABORT_TASK_SET:
752 case CTL_TASK_CLEAR_TASK_SET:
753 sbuf_printf(sb, "%sTag: 0x%04x, Type: %d\n", path_str,
755 io->taskio.tag_type);
766 sbuf_cat(sb, path_str);
767 if (status_desc == NULL)
768 sbuf_printf(sb, "CTL Status: Unknown status %#x\n",
771 sbuf_printf(sb, "CTL Status: %s\n", status_desc->description);
773 if ((io->io_hdr.io_type == CTL_IO_SCSI)
774 && ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_SCSI_ERROR)) {
775 sbuf_cat(sb, path_str);
776 sbuf_printf(sb, "SCSI Status: %s\n",
777 ctl_scsi_status_string(&io->scsiio));
779 if (io->scsiio.scsi_status == SCSI_STATUS_CHECK_COND)
780 ctl_scsi_sense_sbuf(&io->scsiio, inq_data,
786 ctl_io_error_string(union ctl_io *io, struct scsi_inquiry_data *inq_data,
787 char *str, int str_len)
791 sbuf_new(&sb, str, str_len, SBUF_FIXEDLEN);
793 ctl_io_error_sbuf(io, inq_data, &sb);
797 return (sbuf_data(&sb));
803 ctl_io_error_print(union ctl_io *io, struct scsi_inquiry_data *inq_data)
810 message = io_error_string(io, inq_data, str, sizeof(str));
812 for (line = strsep(&message, "\n"); line != NULL;
813 line = strsep(&message, "\n")) {
814 csevent_log(CSC_CTL | CSC_SHELF_SW | CTL_ERROR_REPORT,
815 csevent_LogType_Trace,
816 csevent_Severity_Information,
817 csevent_AlertLevel_Green,
818 csevent_FRU_Firmware,
819 csevent_FRU_Unknown, "%s", line);
822 printf("%s", ctl_io_error_string(io, inq_data, str, sizeof(str)));
830 ctl_io_error_print(union ctl_io *io, struct scsi_inquiry_data *inq_data,
835 fprintf(ofile, "%s", ctl_io_error_string(io, inq_data, str,