]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/cam/ctl/ctl_util.c
devd.conf(5): Fix a mandoc related issue
[FreeBSD/FreeBSD.git] / sys / cam / ctl / ctl_util.c
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>
62 #include <cam/ctl/ctl_scsi_all.h>
63 #include <cam/ctl/ctl_util.h>
64
65 struct ctl_status_desc {
66         ctl_io_status status;
67         const char *description;
68 };
69
70 struct ctl_task_desc {
71         ctl_task_type   task_action;
72         const char      *description;
73 };
74 static struct ctl_status_desc ctl_status_table[] = {
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
84 static 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
100 void
101 ctl_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
106         ctl_scsi_zero_io(io);
107
108         io->io_hdr.io_type = CTL_IO_SCSI;
109         ctsio = &io->scsiio;
110         cdb = (struct scsi_test_unit_ready *)ctsio->cdb;
111
112         cdb->opcode = TEST_UNIT_READY;
113         cdb->control = control;
114         io->io_hdr.flags = CTL_FLAG_DATA_NONE;
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
124 void
125 ctl_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
132         ctl_scsi_zero_io(io);
133
134         io->io_hdr.io_type = CTL_IO_SCSI;
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);
143         io->io_hdr.io_type = CTL_IO_SCSI;
144         io->io_hdr.flags = CTL_FLAG_DATA_IN;
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
154 void
155 ctl_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
162         ctl_scsi_zero_io(io);
163
164         io->io_hdr.io_type = CTL_IO_SCSI;
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;
172         io->io_hdr.io_type = CTL_IO_SCSI;
173         io->io_hdr.flags = CTL_FLAG_DATA_IN;
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
183 void
184 ctl_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
191         ctl_scsi_zero_io(io);
192
193         io->io_hdr.io_type = CTL_IO_SCSI;
194         ctsio = &io->scsiio;
195         cdb = (struct scsi_report_luns *)ctsio->cdb;
196
197         cdb->opcode = REPORT_LUNS;
198         cdb->select_report = select_report;
199         scsi_ulto4b(data_len, cdb->length);
200         cdb->control = control;
201         io->io_hdr.io_type = CTL_IO_SCSI;
202         io->io_hdr.flags = CTL_FLAG_DATA_IN;
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
212 void
213 ctl_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
221         ctl_scsi_zero_io(io);
222
223         io->io_hdr.io_type = CTL_IO_SCSI;
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;
237         io->io_hdr.io_type = CTL_IO_SCSI;
238         if (read_buffer != 0)
239                 io->io_hdr.flags = CTL_FLAG_DATA_IN;
240         else
241                 io->io_hdr.flags = CTL_FLAG_DATA_OUT;
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
251 void
252 ctl_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
259         ctl_scsi_zero_io(io);
260
261         io->io_hdr.io_type = CTL_IO_SCSI;
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
339         io->io_hdr.io_type = CTL_IO_SCSI;
340         if (read_op != 0)
341                 io->io_hdr.flags = CTL_FLAG_DATA_IN;
342         else
343                 io->io_hdr.flags = CTL_FLAG_DATA_OUT;
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
352 void
353 ctl_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
360         ctl_scsi_zero_io(io);
361
362         io->io_hdr.io_type = CTL_IO_SCSI;
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
373         io->io_hdr.io_type = CTL_IO_SCSI;
374         io->io_hdr.flags = CTL_FLAG_DATA_OUT;
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
383 void
384 ctl_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
390         ctl_scsi_zero_io(io);
391
392         io->io_hdr.io_type = CTL_IO_SCSI;
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;
402         io->io_hdr.io_type = CTL_IO_SCSI;
403         io->io_hdr.flags = CTL_FLAG_DATA_IN;
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;
409         io->scsiio.sense_len = SSD_FULL_SIZE;
410 }
411
412 void
413 ctl_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
419         ctl_scsi_zero_io(io);
420
421         io->io_hdr.io_type = CTL_IO_SCSI;
422         cdb = (struct scsi_read_capacity_16 *)io->scsiio.cdb;
423
424         cdb->opcode = SERVICE_ACTION_IN;
425         cdb->service_action = SRC16_SERVICE_ACTION;
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
434         io->io_hdr.io_type = CTL_IO_SCSI;
435         io->io_hdr.flags = CTL_FLAG_DATA_IN;
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;
441         io->scsiio.sense_len = SSD_FULL_SIZE;
442 }
443
444 void
445 ctl_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 {
450         ctl_scsi_zero_io(io);
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
482         io->io_hdr.io_type = CTL_IO_SCSI;
483         io->io_hdr.flags = CTL_FLAG_DATA_IN;
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;
489         io->scsiio.sense_len = SSD_FULL_SIZE;
490 }
491
492 void
493 ctl_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
500         ctl_scsi_zero_io(io);
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;
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(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
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 void
703 ctl_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
716 const char *
717 ctl_scsi_task_string(struct ctl_taskio *taskio)
718 {
719         unsigned int i;
720
721         for (i = 0; i < (sizeof(ctl_task_table)/sizeof(ctl_task_table[0]));
722              i++) {
723                 if (taskio->task_action == ctl_task_table[i].task_action) {
724                         return (ctl_task_table[i].description);
725                 }
726         }
727
728         return (NULL);
729 }
730
731 void
732 ctl_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)",
752                             io->taskio.task_action, io->taskio.task_action);
753                 else
754                         sbuf_printf(sb, "Task Action: %s", task_desc);
755                 switch (io->taskio.task_action) {
756                 case CTL_TASK_ABORT_TASK:
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
770 void
771 ctl_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) ==
784                      ctl_status_table[i].status) {
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)
800          && ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_SCSI_ERROR)) {
801                 sbuf_cat(sb, path_str);
802                 sbuf_printf(sb, "SCSI Status: %s\n",
803                             ctl_scsi_status_string(&io->scsiio));
804
805                 if (io->scsiio.scsi_status == SCSI_STATUS_CHECK_COND)
806                         ctl_scsi_sense_sbuf(&io->scsiio, inq_data,
807                                             sb, SSS_FLAG_NONE);
808         }
809 }
810
811 char *
812 ctl_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
822 char *
823 ctl_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
836 void
837 ctl_io_print(union ctl_io *io)
838 {
839         char str[512];
840
841         printf("%s", ctl_io_string(io, str, sizeof(str)));
842 }
843
844 void
845 ctl_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
853 void
854 ctl_data_print(union ctl_io *io)
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;
863         if (io->io_hdr.flags & CTL_FLAG_BUS_ADDR)
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
886 void
887 ctl_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  */