]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - sys/cam/ctl/ctl_util.c
MFC r356135:
[FreeBSD/stable/10.git] / sys / cam / ctl / ctl_util.c
1 /*-
2  * Copyright (c) 2003 Silicon Graphics International Corp.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions, and the following disclaimer,
10  *    without modification.
11  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12  *    substantially similar to the "NO WARRANTY" disclaimer below
13  *    ("Disclaimer") and any redistribution must be conditioned upon
14  *    including a substantially similar Disclaimer requirement for further
15  *    binary redistribution.
16  *
17  * NO WARRANTY
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
27  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGES.
29  *
30  * $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/ctl_util.c#2 $
31  */
32 /*
33  * CAM Target Layer SCSI library
34  *
35  * Author: Ken Merry <ken@FreeBSD.org>
36  */
37
38 #include <sys/cdefs.h>
39 __FBSDID("$FreeBSD$");
40
41 #ifdef _KERNEL
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/kernel.h>
45 #include <sys/types.h>
46 #include <sys/malloc.h>
47 #else /* __KERNEL__ */
48 #include <sys/types.h>
49 #include <sys/time.h>
50 #include <stdint.h>
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <string.h>
54 #endif /* __KERNEL__ */
55 #include <sys/sbuf.h>
56 #include <sys/queue.h>
57 #include <sys/callout.h>
58 #include <cam/scsi/scsi_all.h>
59 #include <cam/ctl/ctl_io.h>
60 #include <cam/ctl/ctl_scsi_all.h>
61 #include <cam/ctl/ctl_util.h>
62
63 struct ctl_status_desc {
64         ctl_io_status status;
65         const char *description;
66 };
67
68 struct ctl_task_desc {
69         ctl_task_type   task_action;
70         const char      *description;
71 };
72 static struct ctl_status_desc ctl_status_table[] = {
73         {CTL_STATUS_NONE, "No Status"},
74         {CTL_SUCCESS, "Command Completed Successfully"},
75         {CTL_CMD_TIMEOUT, "Command Timed Out"},
76         {CTL_SEL_TIMEOUT, "Selection Timeout"},
77         {CTL_ERROR, "Command Failed"},
78         {CTL_SCSI_ERROR, "SCSI Error"},
79         {CTL_CMD_ABORTED, "Command Aborted"},
80 };
81
82 static struct ctl_task_desc ctl_task_table[] = {
83         {CTL_TASK_ABORT_TASK, "Abort Task"},
84         {CTL_TASK_ABORT_TASK_SET, "Abort Task Set"},
85         {CTL_TASK_CLEAR_ACA, "Clear ACA"},
86         {CTL_TASK_CLEAR_TASK_SET, "Clear Task Set"},
87         {CTL_TASK_I_T_NEXUS_RESET, "I_T Nexus Reset"},
88         {CTL_TASK_LUN_RESET, "LUN Reset"},
89         {CTL_TASK_TARGET_RESET, "Target Reset"},
90         {CTL_TASK_BUS_RESET, "Bus Reset"},
91         {CTL_TASK_PORT_LOGIN, "Port Login"},
92         {CTL_TASK_PORT_LOGOUT, "Port Logout"},
93         {CTL_TASK_QUERY_TASK, "Query Task"},
94         {CTL_TASK_QUERY_TASK_SET, "Query Task Set"},
95         {CTL_TASK_QUERY_ASYNC_EVENT, "Query Async Event"}
96 };
97
98 void
99 ctl_scsi_tur(union ctl_io *io, ctl_tag_type tag_type, uint8_t control)
100 {
101         struct ctl_scsiio *ctsio;
102         struct scsi_test_unit_ready *cdb;
103
104         ctl_scsi_zero_io(io);
105
106         io->io_hdr.io_type = CTL_IO_SCSI;
107         ctsio = &io->scsiio;
108         cdb = (struct scsi_test_unit_ready *)ctsio->cdb;
109
110         cdb->opcode = TEST_UNIT_READY;
111         cdb->control = control;
112         io->io_hdr.flags = CTL_FLAG_DATA_NONE;
113         ctsio->tag_type = tag_type;
114         ctsio->cdb_len = sizeof(*cdb);
115         ctsio->ext_data_len = 0;
116         ctsio->ext_data_ptr = NULL;
117         ctsio->ext_sg_entries = 0;
118         ctsio->ext_data_filled = 0;
119         ctsio->sense_len = SSD_FULL_SIZE;
120 }
121
122 void
123 ctl_scsi_inquiry(union ctl_io *io, uint8_t *data_ptr, int32_t data_len,
124                  uint8_t byte2, uint8_t page_code, ctl_tag_type tag_type,
125                  uint8_t control)
126 {
127         struct ctl_scsiio *ctsio;
128         struct scsi_inquiry *cdb;
129
130         ctl_scsi_zero_io(io);
131
132         io->io_hdr.io_type = CTL_IO_SCSI;
133         ctsio = &io->scsiio;
134         cdb = (struct scsi_inquiry *)ctsio->cdb;
135
136         cdb->opcode = INQUIRY;
137         cdb->byte2 = byte2;
138         cdb->page_code = page_code;
139         cdb->control = control;
140         scsi_ulto2b(data_len, cdb->length);
141         io->io_hdr.io_type = CTL_IO_SCSI;
142         io->io_hdr.flags = CTL_FLAG_DATA_IN;
143         ctsio->tag_type = tag_type;
144         ctsio->cdb_len = sizeof(*cdb);
145         ctsio->ext_data_len = data_len;
146         ctsio->ext_data_ptr = data_ptr;
147         ctsio->ext_sg_entries = 0;
148         ctsio->ext_data_filled = 0;
149         ctsio->sense_len = SSD_FULL_SIZE;
150 }
151
152 void
153 ctl_scsi_request_sense(union ctl_io *io, uint8_t *data_ptr,
154                        int32_t data_len, uint8_t byte2, ctl_tag_type tag_type,
155                        uint8_t control)
156 {
157         struct ctl_scsiio *ctsio;
158         struct scsi_request_sense *cdb;
159
160         ctl_scsi_zero_io(io);
161
162         io->io_hdr.io_type = CTL_IO_SCSI;
163         ctsio = &io->scsiio;
164         cdb = (struct scsi_request_sense *)ctsio->cdb;
165
166         cdb->opcode = REQUEST_SENSE;
167         cdb->byte2 = byte2;
168         cdb->control = control;
169         cdb->length = data_len;
170         io->io_hdr.io_type = CTL_IO_SCSI;
171         io->io_hdr.flags = CTL_FLAG_DATA_IN;
172         ctsio->tag_type = tag_type;
173         ctsio->cdb_len = sizeof(*cdb);
174         ctsio->ext_data_ptr = data_ptr;
175         ctsio->ext_data_len = data_len;
176         ctsio->ext_sg_entries = 0;
177         ctsio->ext_data_filled = 0;
178         ctsio->sense_len = SSD_FULL_SIZE;
179 }
180
181 void
182 ctl_scsi_report_luns(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len,
183                      uint8_t select_report, ctl_tag_type tag_type,
184                      uint8_t control)
185 {
186         struct ctl_scsiio *ctsio;
187         struct scsi_report_luns *cdb;
188
189         ctl_scsi_zero_io(io);
190
191         io->io_hdr.io_type = CTL_IO_SCSI;
192         ctsio = &io->scsiio;
193         cdb = (struct scsi_report_luns *)ctsio->cdb;
194
195         cdb->opcode = REPORT_LUNS;
196         cdb->select_report = select_report;
197         scsi_ulto4b(data_len, cdb->length);
198         cdb->control = control;
199         io->io_hdr.io_type = CTL_IO_SCSI;
200         io->io_hdr.flags = CTL_FLAG_DATA_IN;
201         ctsio->tag_type = tag_type;
202         ctsio->cdb_len = sizeof(*cdb);
203         ctsio->ext_data_ptr = data_ptr;
204         ctsio->ext_data_len = data_len;
205         ctsio->ext_sg_entries = 0;
206         ctsio->ext_data_filled = 0;
207         ctsio->sense_len = SSD_FULL_SIZE;
208 }
209
210 void
211 ctl_scsi_read_write_buffer(union ctl_io *io, uint8_t *data_ptr,
212                            uint32_t data_len, int read_buffer, uint8_t mode,
213                            uint8_t buffer_id, uint32_t buffer_offset,
214                            ctl_tag_type tag_type, uint8_t control)
215 {
216         struct ctl_scsiio *ctsio;
217         struct scsi_write_buffer *cdb;
218
219         ctl_scsi_zero_io(io);
220
221         io->io_hdr.io_type = CTL_IO_SCSI;
222         ctsio = &io->scsiio;
223         cdb = (struct scsi_write_buffer *)ctsio->cdb;
224
225         if (read_buffer != 0)
226                 cdb->opcode = READ_BUFFER;
227         else
228                 cdb->opcode = WRITE_BUFFER;
229
230         cdb->byte2 = mode & RWB_MODE;
231         cdb->buffer_id = buffer_id;
232         scsi_ulto3b(buffer_offset, cdb->offset);
233         scsi_ulto3b(data_len, cdb->length);
234         cdb->control = control;
235         io->io_hdr.io_type = CTL_IO_SCSI;
236         if (read_buffer != 0)
237                 io->io_hdr.flags = CTL_FLAG_DATA_IN;
238         else
239                 io->io_hdr.flags = CTL_FLAG_DATA_OUT;
240         ctsio->tag_type = tag_type;
241         ctsio->cdb_len = sizeof(*cdb);
242         ctsio->ext_data_ptr = data_ptr;
243         ctsio->ext_data_len = data_len;
244         ctsio->ext_sg_entries = 0;
245         ctsio->ext_data_filled = 0;
246         ctsio->sense_len = SSD_FULL_SIZE;
247 }
248
249 void
250 ctl_scsi_read_write(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len,
251                     int read_op, uint8_t byte2, int minimum_cdb_size,
252                     uint64_t lba, uint32_t num_blocks, ctl_tag_type tag_type,
253                     uint8_t control)
254 {
255         struct ctl_scsiio *ctsio;
256
257         ctl_scsi_zero_io(io);
258
259         io->io_hdr.io_type = CTL_IO_SCSI;
260         ctsio = &io->scsiio;
261
262         /*
263          * Pick out the smallest CDB that will hold the user's request.
264          * minimum_cdb_size allows cranking the CDB size up, even for
265          * requests that would not normally need a large CDB.  This can be
266          * useful for testing (e.g. to make sure READ_16 support works without
267          * having an array larger than 2TB) and for compatibility -- e.g.
268          * if your device doesn't support READ_6.  (ATAPI drives don't.)
269          */
270         if ((minimum_cdb_size < 10)
271          && ((lba & 0x1fffff) == lba)
272          && ((num_blocks & 0xff) == num_blocks)
273          && (byte2 == 0)) {
274                 struct scsi_rw_6 *cdb;
275
276                 /*
277                  * Note that according to SBC-2, the target should return 256
278                  * blocks if the transfer length in a READ(6) or WRITE(6) CDB
279                  * is set to 0.  Since it's possible that some targets
280                  * won't do the right thing, we only send a READ(6) or
281                  * WRITE(6) for transfer sizes up to and including 255 blocks.
282                  */
283                 cdb = (struct scsi_rw_6 *)ctsio->cdb;
284
285                 cdb->opcode = (read_op) ? READ_6 : WRITE_6;
286                 scsi_ulto3b(lba, cdb->addr);
287                 cdb->length = num_blocks & 0xff;
288                 cdb->control = control;
289
290                 ctsio->cdb_len = sizeof(*cdb);
291
292         } else if ((minimum_cdb_size < 12)
293                 && ((num_blocks & 0xffff) == num_blocks)
294                 && ((lba & 0xffffffff) == lba)) {
295                 struct scsi_rw_10 *cdb;
296
297                 cdb = (struct scsi_rw_10 *)ctsio->cdb;
298
299                 cdb->opcode = (read_op) ? READ_10 : WRITE_10;
300                 cdb->byte2 = byte2;
301                 scsi_ulto4b(lba, cdb->addr);
302                 cdb->reserved = 0;
303                 scsi_ulto2b(num_blocks, cdb->length);
304                 cdb->control = control;
305
306                 ctsio->cdb_len = sizeof(*cdb);
307         } else if ((minimum_cdb_size < 16)
308                 && ((num_blocks & 0xffffffff) == num_blocks)
309                 && ((lba & 0xffffffff) == lba)) {
310                 struct scsi_rw_12 *cdb;
311
312                 cdb = (struct scsi_rw_12 *)ctsio->cdb;
313
314                 cdb->opcode = (read_op) ? READ_12 : WRITE_12;
315                 cdb->byte2 = byte2;
316                 scsi_ulto4b(lba, cdb->addr);
317                 scsi_ulto4b(num_blocks, cdb->length);
318                 cdb->reserved = 0;
319                 cdb->control = control;
320
321                 ctsio->cdb_len = sizeof(*cdb);
322         } else {
323                 struct scsi_rw_16 *cdb;
324
325                 cdb = (struct scsi_rw_16 *)ctsio->cdb;
326
327                 cdb->opcode = (read_op) ? READ_16 : WRITE_16;
328                 cdb->byte2 = byte2;
329                 scsi_u64to8b(lba, cdb->addr);
330                 scsi_ulto4b(num_blocks, cdb->length);
331                 cdb->reserved = 0;
332                 cdb->control = control;
333
334                 ctsio->cdb_len = sizeof(*cdb);
335         }
336
337         io->io_hdr.io_type = CTL_IO_SCSI;
338         if (read_op != 0)
339                 io->io_hdr.flags = CTL_FLAG_DATA_IN;
340         else
341                 io->io_hdr.flags = CTL_FLAG_DATA_OUT;
342         ctsio->tag_type = tag_type;
343         ctsio->ext_data_ptr = data_ptr;
344         ctsio->ext_data_len = data_len;
345         ctsio->ext_sg_entries = 0;
346         ctsio->ext_data_filled = 0;
347         ctsio->sense_len = SSD_FULL_SIZE;
348 }
349
350 void
351 ctl_scsi_write_same(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len,
352                     uint8_t byte2, uint64_t lba, uint32_t num_blocks,
353                     ctl_tag_type tag_type, uint8_t control)
354 {
355         struct ctl_scsiio *ctsio;
356         struct scsi_write_same_16 *cdb;
357
358         ctl_scsi_zero_io(io);
359
360         io->io_hdr.io_type = CTL_IO_SCSI;
361         ctsio = &io->scsiio;
362         ctsio->cdb_len = sizeof(*cdb);
363         cdb = (struct scsi_write_same_16 *)ctsio->cdb;
364         cdb->opcode = WRITE_SAME_16;
365         cdb->byte2 = byte2;
366         scsi_u64to8b(lba, cdb->addr);
367         scsi_ulto4b(num_blocks, cdb->length);
368         cdb->group = 0;
369         cdb->control = control;
370
371         io->io_hdr.io_type = CTL_IO_SCSI;
372         io->io_hdr.flags = CTL_FLAG_DATA_OUT;
373         ctsio->tag_type = tag_type;
374         ctsio->ext_data_ptr = data_ptr;
375         ctsio->ext_data_len = data_len;
376         ctsio->ext_sg_entries = 0;
377         ctsio->ext_data_filled = 0;
378         ctsio->sense_len = SSD_FULL_SIZE;
379 }
380
381 void
382 ctl_scsi_read_capacity(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len,
383                        uint32_t addr, int reladr, int pmi,
384                        ctl_tag_type tag_type, uint8_t control)
385 {
386         struct scsi_read_capacity *cdb;
387
388         ctl_scsi_zero_io(io);
389
390         io->io_hdr.io_type = CTL_IO_SCSI;
391         cdb = (struct scsi_read_capacity *)io->scsiio.cdb;
392
393         cdb->opcode = READ_CAPACITY;
394         if (reladr)
395                 cdb->byte2 = SRC_RELADR;
396         if (pmi)
397                 cdb->pmi = SRC_PMI;
398         scsi_ulto4b(addr, cdb->addr);
399         cdb->control = control;
400         io->io_hdr.io_type = CTL_IO_SCSI;
401         io->io_hdr.flags = CTL_FLAG_DATA_IN;
402         io->scsiio.tag_type = tag_type;
403         io->scsiio.ext_data_ptr = data_ptr;
404         io->scsiio.ext_data_len = data_len;
405         io->scsiio.ext_sg_entries = 0;
406         io->scsiio.ext_data_filled = 0;
407         io->scsiio.sense_len = SSD_FULL_SIZE;
408 }
409
410 void
411 ctl_scsi_read_capacity_16(union ctl_io *io, uint8_t *data_ptr,
412                           uint32_t data_len, uint64_t addr, int reladr,
413                           int pmi, ctl_tag_type tag_type, uint8_t control)
414 {
415         struct scsi_read_capacity_16 *cdb;
416
417         ctl_scsi_zero_io(io);
418
419         io->io_hdr.io_type = CTL_IO_SCSI;
420         cdb = (struct scsi_read_capacity_16 *)io->scsiio.cdb;
421
422         cdb->opcode = SERVICE_ACTION_IN;
423         cdb->service_action = SRC16_SERVICE_ACTION;
424         if (reladr)
425                 cdb->reladr |= SRC16_RELADR;
426         if (pmi)
427                 cdb->reladr |= SRC16_PMI;
428         scsi_u64to8b(addr, cdb->addr);
429         scsi_ulto4b(data_len, cdb->alloc_len);
430         cdb->control = control;
431
432         io->io_hdr.io_type = CTL_IO_SCSI;
433         io->io_hdr.flags = CTL_FLAG_DATA_IN;
434         io->scsiio.tag_type = tag_type;
435         io->scsiio.ext_data_ptr = data_ptr;
436         io->scsiio.ext_data_len = data_len;
437         io->scsiio.ext_sg_entries = 0;
438         io->scsiio.ext_data_filled = 0;
439         io->scsiio.sense_len = SSD_FULL_SIZE;
440 }
441
442 void
443 ctl_scsi_mode_sense(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len, 
444                     int dbd, int llbaa, uint8_t page_code, uint8_t pc,
445                     uint8_t subpage, int minimum_cdb_size,
446                     ctl_tag_type tag_type, uint8_t control)
447 {
448         ctl_scsi_zero_io(io);
449
450         if ((minimum_cdb_size < 10)
451          && (llbaa == 0)
452          && (data_len < 256)) {
453                 struct scsi_mode_sense_6 *cdb;
454
455                 cdb = (struct scsi_mode_sense_6 *)io->scsiio.cdb;
456
457                 cdb->opcode = MODE_SENSE_6;
458                 if (dbd)
459                         cdb->byte2 |= SMS_DBD;
460                 cdb->page = page_code | pc;
461                 cdb->subpage = subpage;
462                 cdb->length = data_len;
463                 cdb->control = control;
464         } else {
465                 struct scsi_mode_sense_10 *cdb;
466
467                 cdb = (struct scsi_mode_sense_10 *)io->scsiio.cdb;
468
469                 cdb->opcode = MODE_SENSE_10;
470                 if (dbd)
471                         cdb->byte2 |= SMS_DBD;
472                 if (llbaa)
473                         cdb->byte2 |= SMS10_LLBAA;
474                 cdb->page = page_code | pc;
475                 cdb->subpage = subpage;
476                 scsi_ulto2b(data_len, cdb->length);
477                 cdb->control = control;
478         }
479
480         io->io_hdr.io_type = CTL_IO_SCSI;
481         io->io_hdr.flags = CTL_FLAG_DATA_IN;
482         io->scsiio.tag_type = tag_type;
483         io->scsiio.ext_data_ptr = data_ptr;
484         io->scsiio.ext_data_len = data_len;
485         io->scsiio.ext_sg_entries = 0;
486         io->scsiio.ext_data_filled = 0;
487         io->scsiio.sense_len = SSD_FULL_SIZE;
488 }
489
490 void
491 ctl_scsi_start_stop(union ctl_io *io, int start, int load_eject, int immediate,
492     int power_conditions, ctl_tag_type tag_type, uint8_t control)
493 {
494         struct scsi_start_stop_unit *cdb;
495
496         cdb = (struct scsi_start_stop_unit *)io->scsiio.cdb;
497
498         ctl_scsi_zero_io(io);
499
500         cdb->opcode = START_STOP_UNIT;
501         if (immediate)
502                 cdb->byte2 |= SSS_IMMED;
503         cdb->how = power_conditions;
504         if (load_eject)
505                 cdb->how |= SSS_LOEJ;
506         if (start)
507                 cdb->how |= SSS_START;
508         cdb->control = control;
509         io->io_hdr.io_type = CTL_IO_SCSI;
510         io->io_hdr.flags = CTL_FLAG_DATA_NONE;
511         io->scsiio.tag_type = tag_type;
512         io->scsiio.ext_data_ptr = NULL;
513         io->scsiio.ext_data_len = 0;
514         io->scsiio.ext_sg_entries = 0;
515         io->scsiio.ext_data_filled = 0;
516         io->scsiio.sense_len = SSD_FULL_SIZE;
517 }
518
519 void
520 ctl_scsi_sync_cache(union ctl_io *io, int immed, int reladr,
521                     int minimum_cdb_size, uint64_t starting_lba,
522                     uint32_t block_count, ctl_tag_type tag_type,
523                     uint8_t control)
524 {
525         ctl_scsi_zero_io(io);
526
527         if ((minimum_cdb_size < 16)
528          && ((block_count & 0xffff) == block_count)
529          && ((starting_lba & 0xffffffff) == starting_lba)) {
530                 struct scsi_sync_cache *cdb;
531
532                 cdb = (struct scsi_sync_cache *)io->scsiio.cdb;
533
534                 cdb->opcode = SYNCHRONIZE_CACHE;
535                 if (reladr)
536                         cdb->byte2 |= SSC_RELADR;
537
538                 if (immed)
539                         cdb->byte2 |= SSC_IMMED;
540
541                 scsi_ulto4b(starting_lba, cdb->begin_lba);
542                 scsi_ulto2b(block_count, cdb->lb_count);
543                 cdb->control = control;
544         } else {
545                 struct scsi_sync_cache_16 *cdb;
546
547                 cdb = (struct scsi_sync_cache_16 *)io->scsiio.cdb;
548
549                 cdb->opcode = SYNCHRONIZE_CACHE_16;
550                 if (reladr)
551                         cdb->byte2 |= SSC_RELADR;
552
553                 if (immed)
554                         cdb->byte2 |= SSC_IMMED;
555
556                 scsi_u64to8b(starting_lba, cdb->begin_lba);
557                 scsi_ulto4b(block_count, cdb->lb_count);
558                 cdb->control = control;
559         }
560         io->io_hdr.io_type = CTL_IO_SCSI;
561         io->io_hdr.flags = CTL_FLAG_DATA_NONE;
562         io->scsiio.tag_type = tag_type;
563         io->scsiio.ext_data_ptr = NULL;
564         io->scsiio.ext_data_len = 0;
565         io->scsiio.ext_sg_entries = 0;
566         io->scsiio.ext_data_filled = 0;
567         io->scsiio.sense_len = SSD_FULL_SIZE;
568 }
569
570 void
571 ctl_scsi_persistent_res_in(union ctl_io *io, uint8_t *data_ptr,
572                            uint32_t data_len, int action,
573                            ctl_tag_type tag_type, uint8_t control)
574 {
575
576         struct scsi_per_res_in *cdb;
577
578         ctl_scsi_zero_io(io);
579
580         cdb = (struct scsi_per_res_in *)io->scsiio.cdb;
581         cdb->opcode = PERSISTENT_RES_IN;
582         cdb->action = action;
583         scsi_ulto2b(data_len, cdb->length);
584         cdb->control = control;
585
586         io->io_hdr.io_type = CTL_IO_SCSI;
587         io->io_hdr.flags = CTL_FLAG_DATA_IN;
588         io->scsiio.tag_type = tag_type;
589         io->scsiio.ext_data_ptr = data_ptr;
590         io->scsiio.ext_data_len = data_len;
591         io->scsiio.ext_sg_entries = 0;
592         io->scsiio.ext_data_filled = 0;
593         io->scsiio.sense_len = SSD_FULL_SIZE;
594 }
595
596 void
597 ctl_scsi_persistent_res_out(union ctl_io *io, uint8_t *data_ptr,
598                             uint32_t data_len, int action, int type,
599                             uint64_t key, uint64_t sa_key,
600                             ctl_tag_type tag_type, uint8_t control)
601 {
602
603         struct scsi_per_res_out *cdb;
604         struct scsi_per_res_out_parms *params;
605
606         ctl_scsi_zero_io(io);
607
608         cdb = (struct scsi_per_res_out *)io->scsiio.cdb;
609         params = (struct scsi_per_res_out_parms *)data_ptr;
610
611         cdb->opcode = PERSISTENT_RES_OUT;
612         if (action == 5)
613             cdb->action = 6;
614         else
615             cdb->action = action;
616         switch(type)
617         {
618             case 0:
619                     cdb->scope_type = 1;
620                         break;
621             case 1:
622                     cdb->scope_type = 3;
623                         break;
624             case 2:
625                     cdb->scope_type = 5;
626                         break;
627             case 3:
628                     cdb->scope_type = 6;
629                         break;
630             case 4:
631                     cdb->scope_type = 7;
632                         break;
633             case 5:
634                     cdb->scope_type = 8;
635                         break;
636         }
637         scsi_ulto4b(data_len, cdb->length);
638         cdb->control = control;
639
640         scsi_u64to8b(key, params->res_key.key);
641         scsi_u64to8b(sa_key, params->serv_act_res_key);
642
643         io->io_hdr.io_type = CTL_IO_SCSI;
644         io->io_hdr.flags = CTL_FLAG_DATA_OUT;
645         io->scsiio.tag_type = tag_type;
646         io->scsiio.ext_data_ptr = data_ptr;
647         io->scsiio.ext_data_len = data_len;
648         io->scsiio.ext_sg_entries = 0;
649         io->scsiio.ext_data_filled = 0;
650         io->scsiio.sense_len = SSD_FULL_SIZE;
651
652 }
653
654 void
655 ctl_scsi_maintenance_in(union ctl_io *io, uint8_t *data_ptr, uint32_t data_len, 
656                         uint8_t action, ctl_tag_type tag_type, uint8_t control)
657 {
658         struct scsi_maintenance_in *cdb;
659
660         ctl_scsi_zero_io(io);
661
662         cdb = (struct scsi_maintenance_in *)io->scsiio.cdb;
663         cdb->opcode = MAINTENANCE_IN;
664         cdb->byte2 = action;
665         scsi_ulto4b(data_len, cdb->length);
666         cdb->control = control;
667
668         io->io_hdr.io_type = CTL_IO_SCSI;
669         io->io_hdr.flags = CTL_FLAG_DATA_IN;
670         io->scsiio.tag_type = tag_type;
671         io->scsiio.ext_data_ptr = data_ptr;
672         io->scsiio.ext_data_len = data_len;
673         io->scsiio.ext_sg_entries = 0;
674         io->scsiio.ext_data_filled = 0;
675         io->scsiio.sense_len = SSD_FULL_SIZE;
676 }
677
678 #ifndef _KERNEL
679 union ctl_io *
680 ctl_scsi_alloc_io(uint32_t initid)
681 {
682         union ctl_io *io;
683
684         io = (union ctl_io *)malloc(sizeof(*io));
685         if (io == NULL)
686                 goto bailout;
687
688         io->io_hdr.nexus.initid = initid;
689
690 bailout:
691         return (io);
692 }
693
694 void
695 ctl_scsi_free_io(union ctl_io *io)
696 {
697         free(io);
698 }
699
700 void
701 ctl_scsi_zero_io(union ctl_io *io)
702 {
703         void *pool_ref;
704
705         if (io == NULL)
706                 return;
707
708         pool_ref = io->io_hdr.pool;
709         memset(io, 0, sizeof(*io));
710         io->io_hdr.pool = pool_ref;
711 }
712 #endif /* !_KERNEL */
713
714 const char *
715 ctl_scsi_task_string(struct ctl_taskio *taskio)
716 {
717         unsigned int i;
718
719         for (i = 0; i < (sizeof(ctl_task_table)/sizeof(ctl_task_table[0]));
720              i++) {
721                 if (taskio->task_action == ctl_task_table[i].task_action) {
722                         return (ctl_task_table[i].description);
723                 }
724         }
725
726         return (NULL);
727 }
728
729 void
730 ctl_io_sbuf(union ctl_io *io, struct sbuf *sb)
731 {
732         const char *task_desc;
733         char path_str[64];
734
735         ctl_scsi_path_string(io, path_str, sizeof(path_str));
736
737         switch (io->io_hdr.io_type) {
738         case CTL_IO_SCSI:
739                 sbuf_cat(sb, path_str);
740                 ctl_scsi_command_string(&io->scsiio, NULL, sb);
741                 sbuf_printf(sb, " Tag: %#x/%d\n",
742                             io->scsiio.tag_num, io->scsiio.tag_type);
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: %#x/%d\n",
755                             io->taskio.tag_num, io->taskio.tag_type);
756                         break;
757                 default:
758                         sbuf_printf(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.ext_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, " %#6x:%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  */