]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/cam/ctl/ctl_util.c
Merge llvm-project release/17.x llvmorg-17.0.5-0-g98bfdac5ce82
[FreeBSD/FreeBSD.git] / sys / cam / ctl / ctl_util.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
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 #ifdef _KERNEL
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/kernel.h>
44 #include <sys/types.h>
45 #include <sys/malloc.h>
46 #else /* __KERNEL__ */
47 #include <sys/types.h>
48 #include <sys/time.h>
49 #include <stdint.h>
50 #include <stdio.h>
51 #include <stdlib.h>
52 #include <string.h>
53 #endif /* __KERNEL__ */
54 #include <sys/sbuf.h>
55 #include <sys/queue.h>
56 #include <sys/callout.h>
57 #include <cam/scsi/scsi_all.h>
58 #include <cam/ctl/ctl_io.h>
59 #include <cam/ctl/ctl_scsi_all.h>
60 #include <cam/ctl/ctl_util.h>
61
62 struct ctl_status_desc {
63         ctl_io_status status;
64         const char *description;
65 };
66
67 struct ctl_task_desc {
68         ctl_task_type   task_action;
69         const char      *description;
70 };
71 static struct ctl_status_desc ctl_status_table[] = {
72         {CTL_STATUS_NONE, "No Status"},
73         {CTL_SUCCESS, "Command Completed Successfully"},
74         {CTL_CMD_TIMEOUT, "Command Timed Out"},
75         {CTL_SEL_TIMEOUT, "Selection Timeout"},
76         {CTL_ERROR, "Command Failed"},
77         {CTL_SCSI_ERROR, "SCSI Error"},
78         {CTL_CMD_ABORTED, "Command Aborted"},
79 };
80
81 static struct ctl_task_desc ctl_task_table[] = {
82         {CTL_TASK_ABORT_TASK, "Abort Task"},
83         {CTL_TASK_ABORT_TASK_SET, "Abort Task Set"},
84         {CTL_TASK_CLEAR_ACA, "Clear ACA"},
85         {CTL_TASK_CLEAR_TASK_SET, "Clear Task Set"},
86         {CTL_TASK_I_T_NEXUS_RESET, "I_T Nexus Reset"},
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"},
92         {CTL_TASK_QUERY_TASK, "Query Task"},
93         {CTL_TASK_QUERY_TASK_SET, "Query Task Set"},
94         {CTL_TASK_QUERY_ASYNC_EVENT, "Query Async Event"}
95 };
96
97 void
98 ctl_scsi_tur(union ctl_io *io, ctl_tag_type tag_type, uint8_t control)
99 {
100         struct ctl_scsiio *ctsio;
101         struct scsi_test_unit_ready *cdb;
102
103         ctl_scsi_zero_io(io);
104
105         io->io_hdr.io_type = CTL_IO_SCSI;
106         ctsio = &io->scsiio;
107         cdb = (struct scsi_test_unit_ready *)ctsio->cdb;
108
109         cdb->opcode = TEST_UNIT_READY;
110         cdb->control = control;
111         io->io_hdr.flags = CTL_FLAG_DATA_NONE;
112         ctsio->tag_type = tag_type;
113         ctsio->cdb_len = sizeof(*cdb);
114         ctsio->ext_data_len = 0;
115         ctsio->ext_data_ptr = NULL;
116         ctsio->ext_sg_entries = 0;
117         ctsio->ext_data_filled = 0;
118         ctsio->sense_len = SSD_FULL_SIZE;
119 }
120
121 void
122 ctl_scsi_inquiry(union ctl_io *io, uint8_t *data_ptr, int32_t data_len,
123                  uint8_t byte2, uint8_t page_code, ctl_tag_type tag_type,
124                  uint8_t control)
125 {
126         struct ctl_scsiio *ctsio;
127         struct scsi_inquiry *cdb;
128
129         ctl_scsi_zero_io(io);
130
131         io->io_hdr.io_type = CTL_IO_SCSI;
132         ctsio = &io->scsiio;
133         cdb = (struct scsi_inquiry *)ctsio->cdb;
134
135         cdb->opcode = INQUIRY;
136         cdb->byte2 = byte2;
137         cdb->page_code = page_code;
138         cdb->control = control;
139         scsi_ulto2b(data_len, cdb->length);
140         io->io_hdr.io_type = CTL_IO_SCSI;
141         io->io_hdr.flags = CTL_FLAG_DATA_IN;
142         ctsio->tag_type = tag_type;
143         ctsio->cdb_len = sizeof(*cdb);
144         ctsio->ext_data_len = data_len;
145         ctsio->ext_data_ptr = data_ptr;
146         ctsio->ext_sg_entries = 0;
147         ctsio->ext_data_filled = 0;
148         ctsio->sense_len = SSD_FULL_SIZE;
149 }
150
151 void
152 ctl_scsi_request_sense(union ctl_io *io, uint8_t *data_ptr,
153                        int32_t data_len, uint8_t byte2, ctl_tag_type tag_type,
154                        uint8_t control)
155 {
156         struct ctl_scsiio *ctsio;
157         struct scsi_request_sense *cdb;
158
159         ctl_scsi_zero_io(io);
160
161         io->io_hdr.io_type = CTL_IO_SCSI;
162         ctsio = &io->scsiio;
163         cdb = (struct scsi_request_sense *)ctsio->cdb;
164
165         cdb->opcode = REQUEST_SENSE;
166         cdb->byte2 = byte2;
167         cdb->control = control;
168         cdb->length = data_len;
169         io->io_hdr.io_type = CTL_IO_SCSI;
170         io->io_hdr.flags = CTL_FLAG_DATA_IN;
171         ctsio->tag_type = tag_type;
172         ctsio->cdb_len = sizeof(*cdb);
173         ctsio->ext_data_ptr = data_ptr;
174         ctsio->ext_data_len = data_len;
175         ctsio->ext_sg_entries = 0;
176         ctsio->ext_data_filled = 0;
177         ctsio->sense_len = SSD_FULL_SIZE;
178 }
179
180 void
181 ctl_scsi_report_luns(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len,
182                      uint8_t select_report, ctl_tag_type tag_type,
183                      uint8_t control)
184 {
185         struct ctl_scsiio *ctsio;
186         struct scsi_report_luns *cdb;
187
188         ctl_scsi_zero_io(io);
189
190         io->io_hdr.io_type = CTL_IO_SCSI;
191         ctsio = &io->scsiio;
192         cdb = (struct scsi_report_luns *)ctsio->cdb;
193
194         cdb->opcode = REPORT_LUNS;
195         cdb->select_report = select_report;
196         scsi_ulto4b(data_len, cdb->length);
197         cdb->control = control;
198         io->io_hdr.io_type = CTL_IO_SCSI;
199         io->io_hdr.flags = CTL_FLAG_DATA_IN;
200         ctsio->tag_type = tag_type;
201         ctsio->cdb_len = sizeof(*cdb);
202         ctsio->ext_data_ptr = data_ptr;
203         ctsio->ext_data_len = data_len;
204         ctsio->ext_sg_entries = 0;
205         ctsio->ext_data_filled = 0;
206         ctsio->sense_len = SSD_FULL_SIZE;
207 }
208
209 void
210 ctl_scsi_read_write_buffer(union ctl_io *io, uint8_t *data_ptr,
211                            uint32_t data_len, int read_buffer, uint8_t mode,
212                            uint8_t buffer_id, uint32_t buffer_offset,
213                            ctl_tag_type tag_type, uint8_t control)
214 {
215         struct ctl_scsiio *ctsio;
216         struct scsi_write_buffer *cdb;
217
218         ctl_scsi_zero_io(io);
219
220         io->io_hdr.io_type = CTL_IO_SCSI;
221         ctsio = &io->scsiio;
222         cdb = (struct scsi_write_buffer *)ctsio->cdb;
223
224         if (read_buffer != 0)
225                 cdb->opcode = READ_BUFFER;
226         else
227                 cdb->opcode = WRITE_BUFFER;
228
229         cdb->byte2 = mode & RWB_MODE;
230         cdb->buffer_id = buffer_id;
231         scsi_ulto3b(buffer_offset, cdb->offset);
232         scsi_ulto3b(data_len, cdb->length);
233         cdb->control = control;
234         io->io_hdr.io_type = CTL_IO_SCSI;
235         if (read_buffer != 0)
236                 io->io_hdr.flags = CTL_FLAG_DATA_IN;
237         else
238                 io->io_hdr.flags = CTL_FLAG_DATA_OUT;
239         ctsio->tag_type = tag_type;
240         ctsio->cdb_len = sizeof(*cdb);
241         ctsio->ext_data_ptr = data_ptr;
242         ctsio->ext_data_len = data_len;
243         ctsio->ext_sg_entries = 0;
244         ctsio->ext_data_filled = 0;
245         ctsio->sense_len = SSD_FULL_SIZE;
246 }
247
248 void
249 ctl_scsi_read_write(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len,
250                     int read_op, uint8_t byte2, int minimum_cdb_size,
251                     uint64_t lba, uint32_t num_blocks, ctl_tag_type tag_type,
252                     uint8_t control)
253 {
254         struct ctl_scsiio *ctsio;
255
256         ctl_scsi_zero_io(io);
257
258         io->io_hdr.io_type = CTL_IO_SCSI;
259         ctsio = &io->scsiio;
260
261         /*
262          * Pick out the smallest CDB that will hold the user's request.
263          * minimum_cdb_size allows cranking the CDB size up, even for
264          * requests that would not normally need a large CDB.  This can be
265          * useful for testing (e.g. to make sure READ_16 support works without
266          * having an array larger than 2TB) and for compatibility -- e.g.
267          * if your device doesn't support READ_6.  (ATAPI drives don't.)
268          */
269         if ((minimum_cdb_size < 10)
270          && ((lba & 0x1fffff) == lba)
271          && ((num_blocks & 0xff) == num_blocks)
272          && (byte2 == 0)) {
273                 struct scsi_rw_6 *cdb;
274
275                 /*
276                  * Note that according to SBC-2, the target should return 256
277                  * blocks if the transfer length in a READ(6) or WRITE(6) CDB
278                  * is set to 0.  Since it's possible that some targets
279                  * won't do the right thing, we only send a READ(6) or
280                  * WRITE(6) for transfer sizes up to and including 255 blocks.
281                  */
282                 cdb = (struct scsi_rw_6 *)ctsio->cdb;
283
284                 cdb->opcode = (read_op) ? READ_6 : WRITE_6;
285                 scsi_ulto3b(lba, cdb->addr);
286                 cdb->length = num_blocks & 0xff;
287                 cdb->control = control;
288
289                 ctsio->cdb_len = sizeof(*cdb);
290
291         } else if ((minimum_cdb_size < 12)
292                 && ((num_blocks & 0xffff) == num_blocks)
293                 && ((lba & 0xffffffff) == lba)) {
294                 struct scsi_rw_10 *cdb;
295
296                 cdb = (struct scsi_rw_10 *)ctsio->cdb;
297
298                 cdb->opcode = (read_op) ? READ_10 : WRITE_10;
299                 cdb->byte2 = byte2;
300                 scsi_ulto4b(lba, cdb->addr);
301                 cdb->reserved = 0;
302                 scsi_ulto2b(num_blocks, cdb->length);
303                 cdb->control = control;
304
305                 ctsio->cdb_len = sizeof(*cdb);
306         } else if ((minimum_cdb_size < 16)
307                 && ((num_blocks & 0xffffffff) == num_blocks)
308                 && ((lba & 0xffffffff) == lba)) {
309                 struct scsi_rw_12 *cdb;
310
311                 cdb = (struct scsi_rw_12 *)ctsio->cdb;
312
313                 cdb->opcode = (read_op) ? READ_12 : WRITE_12;
314                 cdb->byte2 = byte2;
315                 scsi_ulto4b(lba, cdb->addr);
316                 scsi_ulto4b(num_blocks, cdb->length);
317                 cdb->reserved = 0;
318                 cdb->control = control;
319
320                 ctsio->cdb_len = sizeof(*cdb);
321         } else {
322                 struct scsi_rw_16 *cdb;
323
324                 cdb = (struct scsi_rw_16 *)ctsio->cdb;
325
326                 cdb->opcode = (read_op) ? READ_16 : WRITE_16;
327                 cdb->byte2 = byte2;
328                 scsi_u64to8b(lba, cdb->addr);
329                 scsi_ulto4b(num_blocks, cdb->length);
330                 cdb->reserved = 0;
331                 cdb->control = control;
332
333                 ctsio->cdb_len = sizeof(*cdb);
334         }
335
336         io->io_hdr.io_type = CTL_IO_SCSI;
337         if (read_op != 0)
338                 io->io_hdr.flags = CTL_FLAG_DATA_IN;
339         else
340                 io->io_hdr.flags = CTL_FLAG_DATA_OUT;
341         ctsio->tag_type = tag_type;
342         ctsio->ext_data_ptr = data_ptr;
343         ctsio->ext_data_len = data_len;
344         ctsio->ext_sg_entries = 0;
345         ctsio->ext_data_filled = 0;
346         ctsio->sense_len = SSD_FULL_SIZE;
347 }
348
349 void
350 ctl_scsi_write_same(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len,
351                     uint8_t byte2, uint64_t lba, uint32_t num_blocks,
352                     ctl_tag_type tag_type, uint8_t control)
353 {
354         struct ctl_scsiio *ctsio;
355         struct scsi_write_same_16 *cdb;
356
357         ctl_scsi_zero_io(io);
358
359         io->io_hdr.io_type = CTL_IO_SCSI;
360         ctsio = &io->scsiio;
361         ctsio->cdb_len = sizeof(*cdb);
362         cdb = (struct scsi_write_same_16 *)ctsio->cdb;
363         cdb->opcode = WRITE_SAME_16;
364         cdb->byte2 = byte2;
365         scsi_u64to8b(lba, cdb->addr);
366         scsi_ulto4b(num_blocks, cdb->length);
367         cdb->group = 0;
368         cdb->control = control;
369
370         io->io_hdr.io_type = CTL_IO_SCSI;
371         io->io_hdr.flags = CTL_FLAG_DATA_OUT;
372         ctsio->tag_type = tag_type;
373         ctsio->ext_data_ptr = data_ptr;
374         ctsio->ext_data_len = data_len;
375         ctsio->ext_sg_entries = 0;
376         ctsio->ext_data_filled = 0;
377         ctsio->sense_len = SSD_FULL_SIZE;
378 }
379
380 void
381 ctl_scsi_read_capacity(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len,
382                        uint32_t addr, int reladr, int pmi,
383                        ctl_tag_type tag_type, uint8_t control)
384 {
385         struct scsi_read_capacity *cdb;
386
387         ctl_scsi_zero_io(io);
388
389         io->io_hdr.io_type = CTL_IO_SCSI;
390         cdb = (struct scsi_read_capacity *)io->scsiio.cdb;
391
392         cdb->opcode = READ_CAPACITY;
393         if (reladr)
394                 cdb->byte2 = SRC_RELADR;
395         if (pmi)
396                 cdb->pmi = SRC_PMI;
397         scsi_ulto4b(addr, cdb->addr);
398         cdb->control = control;
399         io->io_hdr.io_type = CTL_IO_SCSI;
400         io->io_hdr.flags = CTL_FLAG_DATA_IN;
401         io->scsiio.tag_type = tag_type;
402         io->scsiio.ext_data_ptr = data_ptr;
403         io->scsiio.ext_data_len = data_len;
404         io->scsiio.ext_sg_entries = 0;
405         io->scsiio.ext_data_filled = 0;
406         io->scsiio.sense_len = SSD_FULL_SIZE;
407 }
408
409 void
410 ctl_scsi_read_capacity_16(union ctl_io *io, uint8_t *data_ptr,
411                           uint32_t data_len, uint64_t addr, int reladr,
412                           int pmi, ctl_tag_type tag_type, uint8_t control)
413 {
414         struct scsi_read_capacity_16 *cdb;
415
416         ctl_scsi_zero_io(io);
417
418         io->io_hdr.io_type = CTL_IO_SCSI;
419         cdb = (struct scsi_read_capacity_16 *)io->scsiio.cdb;
420
421         cdb->opcode = SERVICE_ACTION_IN;
422         cdb->service_action = SRC16_SERVICE_ACTION;
423         if (reladr)
424                 cdb->reladr |= SRC16_RELADR;
425         if (pmi)
426                 cdb->reladr |= SRC16_PMI;
427         scsi_u64to8b(addr, cdb->addr);
428         scsi_ulto4b(data_len, cdb->alloc_len);
429         cdb->control = control;
430
431         io->io_hdr.io_type = CTL_IO_SCSI;
432         io->io_hdr.flags = CTL_FLAG_DATA_IN;
433         io->scsiio.tag_type = tag_type;
434         io->scsiio.ext_data_ptr = data_ptr;
435         io->scsiio.ext_data_len = data_len;
436         io->scsiio.ext_sg_entries = 0;
437         io->scsiio.ext_data_filled = 0;
438         io->scsiio.sense_len = SSD_FULL_SIZE;
439 }
440
441 void
442 ctl_scsi_mode_sense(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len, 
443                     int dbd, int llbaa, uint8_t page_code, uint8_t pc,
444                     uint8_t subpage, int minimum_cdb_size,
445                     ctl_tag_type tag_type, uint8_t control)
446 {
447         ctl_scsi_zero_io(io);
448
449         if ((minimum_cdb_size < 10)
450          && (llbaa == 0)
451          && (data_len < 256)) {
452                 struct scsi_mode_sense_6 *cdb;
453
454                 cdb = (struct scsi_mode_sense_6 *)io->scsiio.cdb;
455
456                 cdb->opcode = MODE_SENSE_6;
457                 if (dbd)
458                         cdb->byte2 |= SMS_DBD;
459                 cdb->page = page_code | pc;
460                 cdb->subpage = subpage;
461                 cdb->length = data_len;
462                 cdb->control = control;
463         } else {
464                 struct scsi_mode_sense_10 *cdb;
465
466                 cdb = (struct scsi_mode_sense_10 *)io->scsiio.cdb;
467
468                 cdb->opcode = MODE_SENSE_10;
469                 if (dbd)
470                         cdb->byte2 |= SMS_DBD;
471                 if (llbaa)
472                         cdb->byte2 |= SMS10_LLBAA;
473                 cdb->page = page_code | pc;
474                 cdb->subpage = subpage;
475                 scsi_ulto2b(data_len, cdb->length);
476                 cdb->control = control;
477         }
478
479         io->io_hdr.io_type = CTL_IO_SCSI;
480         io->io_hdr.flags = CTL_FLAG_DATA_IN;
481         io->scsiio.tag_type = tag_type;
482         io->scsiio.ext_data_ptr = data_ptr;
483         io->scsiio.ext_data_len = data_len;
484         io->scsiio.ext_sg_entries = 0;
485         io->scsiio.ext_data_filled = 0;
486         io->scsiio.sense_len = SSD_FULL_SIZE;
487 }
488
489 void
490 ctl_scsi_start_stop(union ctl_io *io, int start, int load_eject, int immediate,
491     int power_conditions, ctl_tag_type tag_type, uint8_t control)
492 {
493         struct scsi_start_stop_unit *cdb;
494
495         cdb = (struct scsi_start_stop_unit *)io->scsiio.cdb;
496
497         ctl_scsi_zero_io(io);
498
499         cdb->opcode = START_STOP_UNIT;
500         if (immediate)
501                 cdb->byte2 |= SSS_IMMED;
502         cdb->how = power_conditions;
503         if (load_eject)
504                 cdb->how |= SSS_LOEJ;
505         if (start)
506                 cdb->how |= SSS_START;
507         cdb->control = control;
508         io->io_hdr.io_type = CTL_IO_SCSI;
509         io->io_hdr.flags = CTL_FLAG_DATA_NONE;
510         io->scsiio.tag_type = tag_type;
511         io->scsiio.ext_data_ptr = NULL;
512         io->scsiio.ext_data_len = 0;
513         io->scsiio.ext_sg_entries = 0;
514         io->scsiio.ext_data_filled = 0;
515         io->scsiio.sense_len = SSD_FULL_SIZE;
516 }
517
518 void
519 ctl_scsi_sync_cache(union ctl_io *io, int immed, int reladr,
520                     int minimum_cdb_size, uint64_t starting_lba,
521                     uint32_t block_count, ctl_tag_type tag_type,
522                     uint8_t control)
523 {
524         ctl_scsi_zero_io(io);
525
526         if ((minimum_cdb_size < 16)
527          && ((block_count & 0xffff) == block_count)
528          && ((starting_lba & 0xffffffff) == starting_lba)) {
529                 struct scsi_sync_cache *cdb;
530
531                 cdb = (struct scsi_sync_cache *)io->scsiio.cdb;
532
533                 cdb->opcode = SYNCHRONIZE_CACHE;
534                 if (reladr)
535                         cdb->byte2 |= SSC_RELADR;
536
537                 if (immed)
538                         cdb->byte2 |= SSC_IMMED;
539
540                 scsi_ulto4b(starting_lba, cdb->begin_lba);
541                 scsi_ulto2b(block_count, cdb->lb_count);
542                 cdb->control = control;
543         } else {
544                 struct scsi_sync_cache_16 *cdb;
545
546                 cdb = (struct scsi_sync_cache_16 *)io->scsiio.cdb;
547
548                 cdb->opcode = SYNCHRONIZE_CACHE_16;
549                 if (reladr)
550                         cdb->byte2 |= SSC_RELADR;
551
552                 if (immed)
553                         cdb->byte2 |= SSC_IMMED;
554
555                 scsi_u64to8b(starting_lba, cdb->begin_lba);
556                 scsi_ulto4b(block_count, cdb->lb_count);
557                 cdb->control = control;
558         }
559         io->io_hdr.io_type = CTL_IO_SCSI;
560         io->io_hdr.flags = CTL_FLAG_DATA_NONE;
561         io->scsiio.tag_type = tag_type;
562         io->scsiio.ext_data_ptr = NULL;
563         io->scsiio.ext_data_len = 0;
564         io->scsiio.ext_sg_entries = 0;
565         io->scsiio.ext_data_filled = 0;
566         io->scsiio.sense_len = SSD_FULL_SIZE;
567 }
568
569 void
570 ctl_scsi_persistent_res_in(union ctl_io *io, uint8_t *data_ptr,
571                            uint32_t data_len, int action,
572                            ctl_tag_type tag_type, uint8_t control)
573 {
574
575         struct scsi_per_res_in *cdb;
576
577         ctl_scsi_zero_io(io);
578
579         cdb = (struct scsi_per_res_in *)io->scsiio.cdb;
580         cdb->opcode = PERSISTENT_RES_IN;
581         cdb->action = action;
582         scsi_ulto2b(data_len, cdb->length);
583         cdb->control = control;
584
585         io->io_hdr.io_type = CTL_IO_SCSI;
586         io->io_hdr.flags = CTL_FLAG_DATA_IN;
587         io->scsiio.tag_type = tag_type;
588         io->scsiio.ext_data_ptr = data_ptr;
589         io->scsiio.ext_data_len = data_len;
590         io->scsiio.ext_sg_entries = 0;
591         io->scsiio.ext_data_filled = 0;
592         io->scsiio.sense_len = SSD_FULL_SIZE;
593 }
594
595 void
596 ctl_scsi_persistent_res_out(union ctl_io *io, uint8_t *data_ptr,
597                             uint32_t data_len, int action, int type,
598                             uint64_t key, uint64_t sa_key,
599                             ctl_tag_type tag_type, uint8_t control)
600 {
601
602         struct scsi_per_res_out *cdb;
603         struct scsi_per_res_out_parms *params;
604
605         ctl_scsi_zero_io(io);
606
607         cdb = (struct scsi_per_res_out *)io->scsiio.cdb;
608         params = (struct scsi_per_res_out_parms *)data_ptr;
609
610         cdb->opcode = PERSISTENT_RES_OUT;
611         if (action == 5)
612             cdb->action = 6;
613         else
614             cdb->action = action;
615         switch(type)
616         {
617             case 0:
618                     cdb->scope_type = 1;
619                         break;
620             case 1:
621                     cdb->scope_type = 3;
622                         break;
623             case 2:
624                     cdb->scope_type = 5;
625                         break;
626             case 3:
627                     cdb->scope_type = 6;
628                         break;
629             case 4:
630                     cdb->scope_type = 7;
631                         break;
632             case 5:
633                     cdb->scope_type = 8;
634                         break;
635         }
636         scsi_ulto4b(data_len, cdb->length);
637         cdb->control = control;
638
639         scsi_u64to8b(key, params->res_key.key);
640         scsi_u64to8b(sa_key, params->serv_act_res_key);
641
642         io->io_hdr.io_type = CTL_IO_SCSI;
643         io->io_hdr.flags = CTL_FLAG_DATA_OUT;
644         io->scsiio.tag_type = tag_type;
645         io->scsiio.ext_data_ptr = data_ptr;
646         io->scsiio.ext_data_len = data_len;
647         io->scsiio.ext_sg_entries = 0;
648         io->scsiio.ext_data_filled = 0;
649         io->scsiio.sense_len = SSD_FULL_SIZE;
650
651 }
652
653 void
654 ctl_scsi_maintenance_in(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len, 
655                         uint8_t action, ctl_tag_type tag_type, uint8_t control)
656 {
657         struct scsi_maintenance_in *cdb;
658
659         ctl_scsi_zero_io(io);
660
661         cdb = (struct scsi_maintenance_in *)io->scsiio.cdb;
662         cdb->opcode = MAINTENANCE_IN;
663         cdb->byte2 = action;
664         scsi_ulto4b(data_len, cdb->length);
665         cdb->control = control;
666
667         io->io_hdr.io_type = CTL_IO_SCSI;
668         io->io_hdr.flags = CTL_FLAG_DATA_IN;
669         io->scsiio.tag_type = tag_type;
670         io->scsiio.ext_data_ptr = data_ptr;
671         io->scsiio.ext_data_len = data_len;
672         io->scsiio.ext_sg_entries = 0;
673         io->scsiio.ext_data_filled = 0;
674         io->scsiio.sense_len = SSD_FULL_SIZE;
675 }
676
677 #ifndef _KERNEL
678 union ctl_io *
679 ctl_scsi_alloc_io(uint32_t initid)
680 {
681         union ctl_io *io;
682
683         io = (union ctl_io *)malloc(sizeof(*io));
684         if (io == NULL)
685                 goto bailout;
686
687         io->io_hdr.nexus.initid = initid;
688
689 bailout:
690         return (io);
691 }
692
693 void
694 ctl_scsi_free_io(union ctl_io *io)
695 {
696         free(io);
697 }
698
699 void
700 ctl_scsi_zero_io(union ctl_io *io)
701 {
702         void *pool_ref;
703
704         if (io == NULL)
705                 return;
706
707         pool_ref = io->io_hdr.pool;
708         memset(io, 0, sizeof(*io));
709         io->io_hdr.pool = pool_ref;
710 }
711 #endif /* !_KERNEL */
712
713 const char *
714 ctl_scsi_task_string(struct ctl_taskio *taskio)
715 {
716         unsigned int i;
717
718         for (i = 0; i < (sizeof(ctl_task_table)/sizeof(ctl_task_table[0]));
719              i++) {
720                 if (taskio->task_action == ctl_task_table[i].task_action) {
721                         return (ctl_task_table[i].description);
722                 }
723         }
724
725         return (NULL);
726 }
727
728 void
729 ctl_io_sbuf(union ctl_io *io, struct sbuf *sb)
730 {
731         const char *task_desc;
732         char path_str[64];
733
734         ctl_scsi_path_string(io, path_str, sizeof(path_str));
735
736         switch (io->io_hdr.io_type) {
737         case CTL_IO_SCSI:
738                 sbuf_cat(sb, path_str);
739                 ctl_scsi_command_string(&io->scsiio, NULL, sb);
740                 sbuf_printf(sb, " Tag: %#jx/%d, Prio: %d\n",
741                             io->scsiio.tag_num, io->scsiio.tag_type,
742                             io->scsiio.priority);
743                 break;
744         case CTL_IO_TASK:
745                 sbuf_cat(sb, path_str);
746                 task_desc = ctl_scsi_task_string(&io->taskio);
747                 if (task_desc == NULL)
748                         sbuf_printf(sb, "Unknown Task Action %d (%#x)",
749                             io->taskio.task_action, io->taskio.task_action);
750                 else
751                         sbuf_printf(sb, "Task Action: %s", task_desc);
752                 switch (io->taskio.task_action) {
753                 case CTL_TASK_ABORT_TASK:
754                         sbuf_printf(sb, " Tag: %#jx/%d\n",
755                             io->taskio.tag_num, io->taskio.tag_type);
756                         break;
757                 default:
758                         sbuf_putc(sb, '\n');
759                         break;
760                 }
761                 break;
762         default:
763                 break;
764         }
765 }
766
767 void
768 ctl_io_error_sbuf(union ctl_io *io, struct scsi_inquiry_data *inq_data,
769                   struct sbuf *sb)
770 {
771         struct ctl_status_desc *status_desc;
772         char path_str[64];
773         unsigned int i;
774
775         ctl_io_sbuf(io, sb);
776
777         status_desc = NULL;
778         for (i = 0; i < (sizeof(ctl_status_table)/sizeof(ctl_status_table[0]));
779              i++) {
780                 if ((io->io_hdr.status & CTL_STATUS_MASK) ==
781                      ctl_status_table[i].status) {
782                         status_desc = &ctl_status_table[i];
783                         break;
784                 }
785         }
786
787         ctl_scsi_path_string(io, path_str, sizeof(path_str));
788
789         sbuf_cat(sb, path_str);
790         if (status_desc == NULL)
791                 sbuf_printf(sb, "CTL Status: Unknown status %#x\n",
792                             io->io_hdr.status);
793         else
794                 sbuf_printf(sb, "CTL Status: %s\n", status_desc->description);
795
796         if ((io->io_hdr.io_type == CTL_IO_SCSI)
797          && ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_SCSI_ERROR)) {
798                 sbuf_cat(sb, path_str);
799                 sbuf_printf(sb, "SCSI Status: %s\n",
800                             ctl_scsi_status_string(&io->scsiio));
801
802                 if (io->scsiio.scsi_status == SCSI_STATUS_CHECK_COND)
803                         ctl_scsi_sense_sbuf(&io->scsiio, inq_data,
804                                             sb, SSS_FLAG_NONE);
805         }
806 }
807
808 char *
809 ctl_io_string(union ctl_io *io, char *str, int str_len)
810 {
811         struct sbuf sb;
812
813         sbuf_new(&sb, str, str_len, SBUF_FIXEDLEN);
814         ctl_io_sbuf(io, &sb);
815         sbuf_finish(&sb);
816         return (sbuf_data(&sb));
817 }
818
819 char *
820 ctl_io_error_string(union ctl_io *io, struct scsi_inquiry_data *inq_data,
821                     char *str, int str_len)
822 {
823         struct sbuf sb;
824
825         sbuf_new(&sb, str, str_len, SBUF_FIXEDLEN);
826         ctl_io_error_sbuf(io, inq_data, &sb);
827         sbuf_finish(&sb);
828         return (sbuf_data(&sb));
829 }
830
831 #ifdef _KERNEL
832
833 void
834 ctl_io_print(union ctl_io *io)
835 {
836         char str[512];
837
838         printf("%s", ctl_io_string(io, str, sizeof(str)));
839 }
840
841 void
842 ctl_io_error_print(union ctl_io *io, struct scsi_inquiry_data *inq_data)
843 {
844         char str[512];
845
846         printf("%s", ctl_io_error_string(io, inq_data, str, sizeof(str)));
847
848 }
849
850 void
851 ctl_data_print(union ctl_io *io)
852 {
853         char str[128];
854         char path_str[64];
855         struct sbuf sb;
856         int i, j, len;
857
858         if (io->io_hdr.io_type != CTL_IO_SCSI)
859                 return;
860         if (io->io_hdr.flags & CTL_FLAG_BUS_ADDR)
861                 return;
862         if (io->scsiio.kern_sg_entries > 0)     /* XXX: Implement */
863                 return;
864         ctl_scsi_path_string(io, path_str, sizeof(path_str));
865         len = min(io->scsiio.kern_data_len, 4096);
866         for (i = 0; i < len; ) {
867                 sbuf_new(&sb, str, sizeof(str), SBUF_FIXEDLEN);
868                 sbuf_cat(&sb, path_str);
869                 sbuf_printf(&sb, " %#jx:%04x:", io->scsiio.tag_num, i);
870                 for (j = 0; j < 16 && i < len; i++, j++) {
871                         if (j == 8)
872                                 sbuf_cat(&sb, " ");
873                         sbuf_printf(&sb, " %02x", io->scsiio.kern_data_ptr[i]);
874                 }
875                 sbuf_cat(&sb, "\n");
876                 sbuf_finish(&sb);
877                 printf("%s", sbuf_data(&sb));
878         }
879 }
880
881 #else /* _KERNEL */
882
883 void
884 ctl_io_error_print(union ctl_io *io, struct scsi_inquiry_data *inq_data,
885                    FILE *ofile)
886 {
887         char str[512];
888
889         fprintf(ofile, "%s", ctl_io_error_string(io, inq_data, str,
890                 sizeof(str)));
891 }
892
893 #endif /* _KERNEL */
894
895 /*
896  * vim: ts=8
897  */