FreeBSD kernel CAM code
ctl_util.c
Go to the documentation of this file.
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>
63#include <cam/ctl/ctl_util.h>
64
67 const char *description;
68};
69
72 const char *description;
73};
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
84static 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
100void
101ctl_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
107
109 ctsio = &io->scsiio;
110 cdb = (struct scsi_test_unit_ready *)ctsio->cdb;
111
112 cdb->opcode = TEST_UNIT_READY;
113 cdb->control = control;
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
124void
125ctl_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
133
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);
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
154void
155ctl_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
163
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;
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
183void
184ctl_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
192
194 ctsio = &io->scsiio;
195 cdb = (struct scsi_report_luns *)ctsio->cdb;
196
197 cdb->opcode = REPORT_LUNS;
199 scsi_ulto4b(data_len, cdb->length);
200 cdb->control = control;
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
212void
213ctl_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
222
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;
238 if (read_buffer != 0)
240 else
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
251void
252ctl_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
260
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
340 if (read_op != 0)
342 else
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
352void
353ctl_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
361
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
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
383void
384ctl_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
391
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;
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;
410}
411
412void
413ctl_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
420
422 cdb = (struct scsi_read_capacity_16 *)io->scsiio.cdb;
423
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
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;
442}
443
444void
445ctl_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{
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
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;
490}
491
492void
493ctl_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
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;
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;
519}
520
521void
522ctl_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{
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
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
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 }
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;
570}
571
572void
573ctl_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
581
582 cdb = (struct scsi_per_res_in *)io->scsiio.cdb;
584 cdb->action = action;
585 scsi_ulto2b(data_len, cdb->length);
586 cdb->control = control;
587
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;
596}
597
598void
599ctl_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
609
610 cdb = (struct scsi_per_res_out *)io->scsiio.cdb;
611 params = (struct scsi_per_res_out_parms *)data_ptr;
612
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
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;
653
654}
655
656void
657ctl_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
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
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;
678}
679
680#ifndef _KERNEL
681union ctl_io *
682ctl_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
692bailout:
693 return (io);
694}
695
696void
697ctl_scsi_free_io(union ctl_io *io)
698{
699 free(io);
700}
701
702void
703ctl_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
716const char *
718{
719 unsigned int i;
720
721 for (i = 0; i < (sizeof(ctl_task_table)/sizeof(ctl_task_table[0]));
722 i++) {
724 return (ctl_task_table[i].description);
725 }
726 }
727
728 return (NULL);
729}
730
731void
732ctl_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, Prio: %d\n",
744 io->scsiio.tag_num, io->scsiio.tag_type,
745 io->scsiio.priority);
746 break;
747 case CTL_IO_TASK:
748 sbuf_cat(sb, path_str);
749 task_desc = ctl_scsi_task_string(&io->taskio);
750 if (task_desc == NULL)
751 sbuf_printf(sb, "Unknown Task Action %d (%#x)",
753 else
754 sbuf_printf(sb, "Task Action: %s", task_desc);
755 switch (io->taskio.task_action) {
757 sbuf_printf(sb, " Tag: %#x/%d\n",
758 io->taskio.tag_num, io->taskio.tag_type);
759 break;
760 default:
761 sbuf_printf(sb, "\n");
762 break;
763 }
764 break;
765 default:
766 break;
767 }
768}
769
770void
771ctl_io_error_sbuf(union ctl_io *io, struct scsi_inquiry_data *inq_data,
772 struct sbuf *sb)
773{
774 struct ctl_status_desc *status_desc;
775 char path_str[64];
776 unsigned int i;
777
778 ctl_io_sbuf(io, sb);
779
780 status_desc = NULL;
781 for (i = 0; i < (sizeof(ctl_status_table)/sizeof(ctl_status_table[0]));
782 i++) {
783 if ((io->io_hdr.status & CTL_STATUS_MASK) ==
785 status_desc = &ctl_status_table[i];
786 break;
787 }
788 }
789
790 ctl_scsi_path_string(io, path_str, sizeof(path_str));
791
792 sbuf_cat(sb, path_str);
793 if (status_desc == NULL)
794 sbuf_printf(sb, "CTL Status: Unknown status %#x\n",
795 io->io_hdr.status);
796 else
797 sbuf_printf(sb, "CTL Status: %s\n", status_desc->description);
798
799 if ((io->io_hdr.io_type == CTL_IO_SCSI)
801 sbuf_cat(sb, path_str);
802 sbuf_printf(sb, "SCSI Status: %s\n",
804
806 ctl_scsi_sense_sbuf(&io->scsiio, inq_data,
807 sb, SSS_FLAG_NONE);
808 }
809}
810
811char *
812ctl_io_string(union ctl_io *io, char *str, int str_len)
813{
814 struct sbuf sb;
815
816 sbuf_new(&sb, str, str_len, SBUF_FIXEDLEN);
817 ctl_io_sbuf(io, &sb);
818 sbuf_finish(&sb);
819 return (sbuf_data(&sb));
820}
821
822char *
823ctl_io_error_string(union ctl_io *io, struct scsi_inquiry_data *inq_data,
824 char *str, int str_len)
825{
826 struct sbuf sb;
827
828 sbuf_new(&sb, str, str_len, SBUF_FIXEDLEN);
829 ctl_io_error_sbuf(io, inq_data, &sb);
830 sbuf_finish(&sb);
831 return (sbuf_data(&sb));
832}
833
834#ifdef _KERNEL
835
836void
838{
839 char str[512];
840
841 printf("%s", ctl_io_string(io, str, sizeof(str)));
842}
843
844void
845ctl_io_error_print(union ctl_io *io, struct scsi_inquiry_data *inq_data)
846{
847 char str[512];
848
849 printf("%s", ctl_io_error_string(io, inq_data, str, sizeof(str)));
850
851}
852
853void
855{
856 char str[128];
857 char path_str[64];
858 struct sbuf sb;
859 int i, j, len;
860
861 if (io->io_hdr.io_type != CTL_IO_SCSI)
862 return;
864 return;
865 if (io->scsiio.kern_sg_entries > 0) /* XXX: Implement */
866 return;
867 ctl_scsi_path_string(io, path_str, sizeof(path_str));
868 len = min(io->scsiio.kern_data_len, 4096);
869 for (i = 0; i < len; ) {
870 sbuf_new(&sb, str, sizeof(str), SBUF_FIXEDLEN);
871 sbuf_cat(&sb, path_str);
872 sbuf_printf(&sb, " %#6x:%04x:", io->scsiio.tag_num, i);
873 for (j = 0; j < 16 && i < len; i++, j++) {
874 if (j == 8)
875 sbuf_cat(&sb, " ");
876 sbuf_printf(&sb, " %02x", io->scsiio.kern_data_ptr[i]);
877 }
878 sbuf_cat(&sb, "\n");
879 sbuf_finish(&sb);
880 printf("%s", sbuf_data(&sb));
881 }
882}
883
884#else /* _KERNEL */
885
886void
887ctl_io_error_print(union ctl_io *io, struct scsi_inquiry_data *inq_data,
888 FILE *ofile)
889{
890 char str[512];
891
892 fprintf(ofile, "%s", ctl_io_error_string(io, inq_data, str,
893 sizeof(str)));
894}
895
896#endif /* _KERNEL */
897
898/*
899 * vim: ts=8
900 */
@ CTL_IO_SCSI
Definition: ctl_io.h:191
@ CTL_IO_TASK
Definition: ctl_io.h:192
ctl_tag_type
Definition: ctl_io.h:253
ctl_task_type
Definition: ctl_io.h:342
@ CTL_TASK_LUN_RESET
Definition: ctl_io.h:348
@ CTL_TASK_QUERY_ASYNC_EVENT
Definition: ctl_io.h:355
@ CTL_TASK_BUS_RESET
Definition: ctl_io.h:350
@ CTL_TASK_QUERY_TASK_SET
Definition: ctl_io.h:354
@ CTL_TASK_PORT_LOGIN
Definition: ctl_io.h:351
@ CTL_TASK_PORT_LOGOUT
Definition: ctl_io.h:352
@ CTL_TASK_CLEAR_ACA
Definition: ctl_io.h:345
@ CTL_TASK_ABORT_TASK
Definition: ctl_io.h:343
@ CTL_TASK_CLEAR_TASK_SET
Definition: ctl_io.h:346
@ CTL_TASK_TARGET_RESET
Definition: ctl_io.h:349
@ CTL_TASK_ABORT_TASK_SET
Definition: ctl_io.h:344
@ CTL_TASK_QUERY_TASK
Definition: ctl_io.h:353
@ CTL_TASK_I_T_NEXUS_RESET
Definition: ctl_io.h:347
ctl_io_status
Definition: ctl_io.h:68
@ CTL_SUCCESS
Definition: ctl_io.h:70
@ CTL_SCSI_ERROR
Definition: ctl_io.h:74
@ CTL_CMD_ABORTED
Definition: ctl_io.h:75
@ CTL_ERROR
Definition: ctl_io.h:73
@ CTL_SEL_TIMEOUT
Definition: ctl_io.h:72
@ CTL_CMD_TIMEOUT
Definition: ctl_io.h:71
@ CTL_STATUS_NONE
Definition: ctl_io.h:69
@ CTL_STATUS_MASK
Definition: ctl_io.h:76
@ CTL_FLAG_DATA_NONE
Definition: ctl_io.h:89
@ CTL_FLAG_BUS_ADDR
Definition: ctl_io.h:102
@ CTL_FLAG_DATA_IN
Definition: ctl_io.h:87
@ CTL_FLAG_DATA_OUT
Definition: ctl_io.h:88
int ctl_scsi_command_string(struct ctl_scsiio *ctsio, struct scsi_inquiry_data *inq_data, struct sbuf *sb)
Definition: ctl_scsi_all.c:102
const char * ctl_scsi_status_string(struct ctl_scsiio *ctsio)
Definition: ctl_scsi_all.c:66
void ctl_scsi_path_string(union ctl_io *io, char *path_str, int len)
Definition: ctl_scsi_all.c:115
int ctl_scsi_sense_sbuf(struct ctl_scsiio *ctsio, struct scsi_inquiry_data *inq_data, struct sbuf *sb, scsi_sense_string_flags flags)
Definition: ctl_scsi_all.c:127
void ctl_scsi_read_capacity_16(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len, uint64_t addr, int reladr, int pmi, ctl_tag_type tag_type, uint8_t control)
Definition: ctl_util.c:413
void ctl_scsi_start_stop(union ctl_io *io, int start, int load_eject, int immediate, int power_conditions, ctl_tag_type tag_type, uint8_t control)
Definition: ctl_util.c:493
char * ctl_io_string(union ctl_io *io, char *str, int str_len)
Definition: ctl_util.c:812
void ctl_scsi_persistent_res_in(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len, int action, ctl_tag_type tag_type, uint8_t control)
Definition: ctl_util.c:573
void ctl_io_sbuf(union ctl_io *io, struct sbuf *sb)
Definition: ctl_util.c:732
void ctl_scsi_read_write(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len, int read_op, uint8_t byte2, int minimum_cdb_size, uint64_t lba, uint32_t num_blocks, ctl_tag_type tag_type, uint8_t control)
Definition: ctl_util.c:252
char * ctl_io_error_string(union ctl_io *io, struct scsi_inquiry_data *inq_data, char *str, int str_len)
Definition: ctl_util.c:823
void ctl_io_print(union ctl_io *io)
Definition: ctl_util.c:837
static struct ctl_status_desc ctl_status_table[]
Definition: ctl_util.c:74
__FBSDID("$FreeBSD$")
static struct ctl_task_desc ctl_task_table[]
Definition: ctl_util.c:84
void ctl_scsi_tur(union ctl_io *io, ctl_tag_type tag_type, uint8_t control)
Definition: ctl_util.c:101
void ctl_scsi_read_capacity(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len, uint32_t addr, int reladr, int pmi, ctl_tag_type tag_type, uint8_t control)
Definition: ctl_util.c:384
void ctl_scsi_inquiry(union ctl_io *io, uint8_t *data_ptr, int32_t data_len, uint8_t byte2, uint8_t page_code, ctl_tag_type tag_type, uint8_t control)
Definition: ctl_util.c:125
void ctl_data_print(union ctl_io *io)
Definition: ctl_util.c:854
void ctl_scsi_read_write_buffer(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len, int read_buffer, uint8_t mode, uint8_t buffer_id, uint32_t buffer_offset, ctl_tag_type tag_type, uint8_t control)
Definition: ctl_util.c:213
const char * ctl_scsi_task_string(struct ctl_taskio *taskio)
Definition: ctl_util.c:717
void ctl_io_error_sbuf(union ctl_io *io, struct scsi_inquiry_data *inq_data, struct sbuf *sb)
Definition: ctl_util.c:771
void ctl_scsi_request_sense(union ctl_io *io, uint8_t *data_ptr, int32_t data_len, uint8_t byte2, ctl_tag_type tag_type, uint8_t control)
Definition: ctl_util.c:155
void ctl_scsi_persistent_res_out(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len, int action, int type, uint64_t key, uint64_t sa_key, ctl_tag_type tag_type, uint8_t control)
Definition: ctl_util.c:599
void ctl_scsi_maintenance_in(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len, uint8_t action, ctl_tag_type tag_type, uint8_t control)
Definition: ctl_util.c:657
void ctl_scsi_write_same(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len, uint8_t byte2, uint64_t lba, uint32_t num_blocks, ctl_tag_type tag_type, uint8_t control)
Definition: ctl_util.c:353
void ctl_scsi_sync_cache(union ctl_io *io, int immed, int reladr, int minimum_cdb_size, uint64_t starting_lba, uint32_t block_count, ctl_tag_type tag_type, uint8_t control)
Definition: ctl_util.c:522
void ctl_scsi_mode_sense(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len, int dbd, int llbaa, uint8_t page_code, uint8_t pc, uint8_t subpage, int minimum_cdb_size, ctl_tag_type tag_type, uint8_t control)
Definition: ctl_util.c:445
void ctl_io_error_print(union ctl_io *io, struct scsi_inquiry_data *inq_data)
Definition: ctl_util.c:845
void ctl_scsi_report_luns(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len, uint8_t select_report, ctl_tag_type tag_type, uint8_t control)
Definition: ctl_util.c:184
#define ctl_scsi_zero_io(io)
Definition: ctl_util.h:103
#define SSS_IMMED
Definition: scsi_all.h:1416
#define WRITE_BUFFER
Definition: scsi_all.h:2103
#define REPORT_LUNS
Definition: scsi_all.h:2133
#define START_STOP_UNIT
Definition: scsi_all.h:2088
#define MODE_SENSE_6
Definition: scsi_all.h:2087
#define SRC16_RELADR
Definition: scsi_all.h:2928
#define MAINTENANCE_IN
Definition: scsi_all.h:2136
#define READ_6
Definition: scsi_all.h:2083
#define SCSI_STATUS_CHECK_COND
Definition: scsi_all.h:3692
#define SYNCHRONIZE_CACHE_16
Definition: scsi_all.h:2128
#define PERSISTENT_RES_OUT
Definition: scsi_all.h:2115
#define PERSISTENT_RES_IN
Definition: scsi_all.h:2114
#define SSC_RELADR
Definition: scsi_all.h:953
#define SRC16_SERVICE_ACTION
Definition: scsi_all.h:2923
#define WRITE_16
Definition: scsi_all.h:2123
#define WRITE_6
Definition: scsi_all.h:2084
#define SSS_LOEJ
Definition: scsi_all.h:1420
#define SMS_DBD
Definition: scsi_all.h:190
#define SYNCHRONIZE_CACHE
Definition: scsi_all.h:2101
static __inline void scsi_ulto2b(u_int32_t val, u_int8_t *bytes)
Definition: scsi_all.h:4374
#define SSC_IMMED
Definition: scsi_all.h:952
#define SSS_START
Definition: scsi_all.h:1419
#define SMS10_LLBAA
Definition: scsi_all.h:219
#define SRC16_PMI
Definition: scsi_all.h:2927
#define WRITE_12
Definition: scsi_all.h:2140
#define RWB_MODE
Definition: scsi_all.h:1022
@ SSS_FLAG_NONE
Definition: scsi_all.h:3755
#define MODE_SENSE_10
Definition: scsi_all.h:2113
static __inline void scsi_ulto4b(u_int32_t val, u_int8_t *bytes)
Definition: scsi_all.h:4391
static __inline void scsi_u64to8b(u_int64_t val, u_int8_t *bytes)
Definition: scsi_all.h:4401
#define WRITE_10
Definition: scsi_all.h:2097
#define SERVICE_ACTION_IN
Definition: scsi_all.h:2132
#define SRC_PMI
Definition: scsi_all.h:2916
#define TEST_UNIT_READY
Definition: scsi_all.h:2081
#define READ_16
Definition: scsi_all.h:2121
#define READ_BUFFER
Definition: scsi_all.h:2104
static __inline void scsi_ulto3b(u_int32_t val, u_int8_t *bytes)
Definition: scsi_all.h:4382
#define READ_10
Definition: scsi_all.h:2096
#define SSD_FULL_SIZE
Definition: scsi_all.h:3251
#define WRITE_SAME_16
Definition: scsi_all.h:2129
#define INQUIRY
Definition: scsi_all.h:2085
#define SRC_RELADR
Definition: scsi_all.h:2912
#define REQUEST_SENSE
Definition: scsi_all.h:2082
#define READ_12
Definition: scsi_all.h:2139
#define READ_CAPACITY
Definition: scsi_all.h:2095
ctl_io_type io_type
Definition: ctl_io.h:224
struct ctl_nexus nexus
Definition: ctl_io.h:226
uint32_t status
Definition: ctl_io.h:229
uint32_t flags
Definition: ctl_io.h:228
void * pool
Definition: ctl_io.h:245
uint32_t initid
Definition: ctl_io.h:196
uint32_t ext_data_len
Definition: ctl_io.h:283
uint32_t kern_sg_entries
Definition: ctl_io.h:290
uint8_t * ext_data_ptr
Definition: ctl_io.h:282
uint32_t kern_data_len
Definition: ctl_io.h:306
uint8_t priority
Definition: ctl_io.h:330
uint8_t scsi_status
Definition: ctl_io.h:328
uint32_t ext_data_filled
Definition: ctl_io.h:284
uint8_t cdb[CTL_MAX_CDBLEN]
Definition: ctl_io.h:335
uint8_t cdb_len
Definition: ctl_io.h:334
uint32_t tag_num
Definition: ctl_io.h:332
ctl_tag_type tag_type
Definition: ctl_io.h:333
uint32_t ext_sg_entries
Definition: ctl_io.h:281
uint8_t * kern_data_ptr
Definition: ctl_io.h:297
uint8_t sense_len
Definition: ctl_io.h:327
ctl_io_status status
Definition: ctl_util.c:66
const char * description
Definition: ctl_util.c:67
ctl_task_type task_action
Definition: ctl_util.c:71
const char * description
Definition: ctl_util.c:72
ctl_task_type task_action
Definition: ctl_io.h:375
ctl_tag_type tag_type
Definition: ctl_io.h:377
uint32_t tag_num
Definition: ctl_io.h:376
u_int8_t length[2]
Definition: scsi_all.h:182
u_int8_t control
Definition: scsi_all.h:183
u_int8_t opcode
Definition: scsi_all.h:177
u_int8_t page_code
Definition: scsi_all.h:181
u_int8_t byte2
Definition: scsi_all.h:178
uint8_t length[4]
Definition: scsi_all.h:1474
u_int8_t subpage
Definition: scsi_all.h:221
u_int8_t length[2]
Definition: scsi_all.h:223
u_int8_t byte2
Definition: scsi_all.h:218
u_int8_t opcode
Definition: scsi_all.h:217
u_int8_t control
Definition: scsi_all.h:224
u_int8_t control
Definition: scsi_all.h:212
u_int8_t byte2
Definition: scsi_all.h:189
u_int8_t subpage
Definition: scsi_all.h:208
u_int8_t opcode
Definition: scsi_all.h:188
u_int8_t length
Definition: scsi_all.h:211
u_int8_t page
Definition: scsi_all.h:191
u_int8_t control
Definition: scsi_all.h:303
u_int8_t length[2]
Definition: scsi_all.h:301
u_int8_t action
Definition: scsi_all.h:295
u_int8_t opcode
Definition: scsi_all.h:294
u_int8_t key[8]
Definition: scsi_all.h:314
struct scsi_per_res_key res_key
Definition: scsi_all.h:431
u_int8_t serv_act_res_key[8]
Definition: scsi_all.h:432
u_int8_t length[4]
Definition: scsi_all.h:425
u_int8_t opcode
Definition: scsi_all.h:396
u_int8_t scope_type
Definition: scsi_all.h:408
u_int8_t control
Definition: scsi_all.h:426
u_int8_t action
Definition: scsi_all.h:397
uint8_t alloc_len[4]
Definition: scsi_all.h:2926
u_int8_t addr[4]
Definition: scsi_all.h:2913
u_int8_t control
Definition: scsi_all.h:2917
uint8_t opcode
Definition: scsi_all.h:2996
uint8_t length[4]
Definition: scsi_all.h:3006
uint8_t select_report
Definition: scsi_all.h:3004
uint8_t control
Definition: scsi_all.h:3008
u_int8_t opcode
Definition: scsi_all.h:121
u_int8_t byte2
Definition: scsi_all.h:122
u_int8_t length
Definition: scsi_all.h:125
u_int8_t control
Definition: scsi_all.h:126
u_int8_t length[2]
Definition: scsi_all.h:1288
u_int8_t control
Definition: scsi_all.h:1289
u_int8_t addr[4]
Definition: scsi_all.h:1286
u_int8_t reserved
Definition: scsi_all.h:1287
u_int8_t opcode
Definition: scsi_all.h:1279
u_int8_t byte2
Definition: scsi_all.h:1285
u_int8_t byte2
Definition: scsi_all.h:1298
u_int8_t addr[4]
Definition: scsi_all.h:1299
u_int8_t reserved
Definition: scsi_all.h:1301
u_int8_t control
Definition: scsi_all.h:1302
u_int8_t opcode
Definition: scsi_all.h:1294
u_int8_t length[4]
Definition: scsi_all.h:1300
u_int8_t control
Definition: scsi_all.h:1315
u_int8_t reserved
Definition: scsi_all.h:1314
u_int8_t opcode
Definition: scsi_all.h:1307
u_int8_t addr[8]
Definition: scsi_all.h:1312
u_int8_t byte2
Definition: scsi_all.h:1311
u_int8_t length[4]
Definition: scsi_all.h:1313
u_int8_t opcode
Definition: scsi_all.h:1269
u_int8_t control
Definition: scsi_all.h:1274
u_int8_t addr[3]
Definition: scsi_all.h:1270
u_int8_t length
Definition: scsi_all.h:1273
uint8_t lb_count[4]
Definition: scsi_all.h:965
uint8_t begin_lba[8]
Definition: scsi_all.h:964
u_int8_t begin_lba[4]
Definition: scsi_all.h:954
u_int8_t lb_count[2]
Definition: scsi_all.h:956
u_int8_t byte2
Definition: scsi_all.h:951
u_int8_t control
Definition: scsi_all.h:957
u_int8_t opcode
Definition: scsi_all.h:950
u_int8_t offset[3]
Definition: scsi_all.h:1053
u_int8_t buffer_id
Definition: scsi_all.h:1052
u_int8_t opcode
Definition: scsi_all.h:1050
u_int8_t byte2
Definition: scsi_all.h:1051
u_int8_t length[3]
Definition: scsi_all.h:1054
u_int8_t control
Definition: scsi_all.h:1055
uint8_t addr[8]
Definition: scsi_all.h:1348
uint8_t length[4]
Definition: scsi_all.h:1349
Definition: ctl_io.h:586
struct ctl_taskio taskio
Definition: ctl_io.h:589
struct ctl_scsiio scsiio
Definition: ctl_io.h:588
struct ctl_io_hdr io_hdr
Definition: ctl_io.h:587