]> CyberLeo.Net >> Repos - FreeBSD/releng/10.3.git/blob - sys/cam/ctl/ctl_util.c
- Copy stable/10@296371 to releng/10.3 in preparation for 10.3-RC1
[FreeBSD/releng/10.3.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 #endif /* !_KERNEL */
701 void
702 ctl_scsi_zero_io(union ctl_io *io)
703 {
704         void *pool_ref;
705
706         if (io == NULL)
707                 return;
708
709         pool_ref = io->io_hdr.pool;
710
711         memset(io, 0, sizeof(*io));
712
713         io->io_hdr.pool = pool_ref;
714 }
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\n",
744                             io->scsiio.tag_num, io->scsiio.tag_type);
745                 break;
746         case CTL_IO_TASK:
747                 sbuf_cat(sb, path_str);
748                 task_desc = ctl_scsi_task_string(&io->taskio);
749                 if (task_desc == NULL)
750                         sbuf_printf(sb, "Unknown Task Action %d (%#x)",
751                             io->taskio.task_action, io->taskio.task_action);
752                 else
753                         sbuf_printf(sb, "Task Action: %s", task_desc);
754                 switch (io->taskio.task_action) {
755                 case CTL_TASK_ABORT_TASK:
756                         sbuf_printf(sb, " Tag: %#x/%d\n",
757                             io->taskio.tag_num, io->taskio.tag_type);
758                         break;
759                 default:
760                         sbuf_printf(sb, "\n");
761                         break;
762                 }
763                 break;
764         default:
765                 break;
766         }
767 }
768
769 void
770 ctl_io_error_sbuf(union ctl_io *io, struct scsi_inquiry_data *inq_data,
771                   struct sbuf *sb)
772 {
773         struct ctl_status_desc *status_desc;
774         char path_str[64];
775         unsigned int i;
776
777         ctl_io_sbuf(io, sb);
778
779         status_desc = NULL;
780         for (i = 0; i < (sizeof(ctl_status_table)/sizeof(ctl_status_table[0]));
781              i++) {
782                 if ((io->io_hdr.status & CTL_STATUS_MASK) ==
783                      ctl_status_table[i].status) {
784                         status_desc = &ctl_status_table[i];
785                         break;
786                 }
787         }
788
789         ctl_scsi_path_string(io, path_str, sizeof(path_str));
790
791         sbuf_cat(sb, path_str);
792         if (status_desc == NULL)
793                 sbuf_printf(sb, "CTL Status: Unknown status %#x\n",
794                             io->io_hdr.status);
795         else
796                 sbuf_printf(sb, "CTL Status: %s\n", status_desc->description);
797
798         if ((io->io_hdr.io_type == CTL_IO_SCSI)
799          && ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_SCSI_ERROR)) {
800                 sbuf_cat(sb, path_str);
801                 sbuf_printf(sb, "SCSI Status: %s\n",
802                             ctl_scsi_status_string(&io->scsiio));
803
804                 if (io->scsiio.scsi_status == SCSI_STATUS_CHECK_COND)
805                         ctl_scsi_sense_sbuf(&io->scsiio, inq_data,
806                                             sb, SSS_FLAG_NONE);
807         }
808 }
809
810 char *
811 ctl_io_string(union ctl_io *io, char *str, int str_len)
812 {
813         struct sbuf sb;
814
815         sbuf_new(&sb, str, str_len, SBUF_FIXEDLEN);
816         ctl_io_sbuf(io, &sb);
817         sbuf_finish(&sb);
818         return (sbuf_data(&sb));
819 }
820
821 char *
822 ctl_io_error_string(union ctl_io *io, struct scsi_inquiry_data *inq_data,
823                     char *str, int str_len)
824 {
825         struct sbuf sb;
826
827         sbuf_new(&sb, str, str_len, SBUF_FIXEDLEN);
828         ctl_io_error_sbuf(io, inq_data, &sb);
829         sbuf_finish(&sb);
830         return (sbuf_data(&sb));
831 }
832
833 #ifdef _KERNEL
834
835 void
836 ctl_io_print(union ctl_io *io)
837 {
838         char str[512];
839
840         printf("%s", ctl_io_string(io, str, sizeof(str)));
841 }
842
843 void
844 ctl_io_error_print(union ctl_io *io, struct scsi_inquiry_data *inq_data)
845 {
846         char str[512];
847
848         printf("%s", ctl_io_error_string(io, inq_data, str, sizeof(str)));
849
850 }
851
852 void
853 ctl_data_print(union ctl_io *io)
854 {
855         char str[128];
856         char path_str[64];
857         struct sbuf sb;
858         int i, j, len;
859
860         if (io->io_hdr.io_type != CTL_IO_SCSI)
861                 return;
862         if (io->io_hdr.flags & CTL_FLAG_BUS_ADDR)
863                 return;
864         if (io->scsiio.ext_sg_entries > 0)      /* XXX: Implement */
865                 return;
866         ctl_scsi_path_string(io, path_str, sizeof(path_str));
867         len = min(io->scsiio.kern_data_len, 4096);
868         for (i = 0; i < len; ) {
869                 sbuf_new(&sb, str, sizeof(str), SBUF_FIXEDLEN);
870                 sbuf_cat(&sb, path_str);
871                 sbuf_printf(&sb, " %#6x:%04x:", io->scsiio.tag_num, i);
872                 for (j = 0; j < 16 && i < len; i++, j++) {
873                         if (j == 8)
874                                 sbuf_cat(&sb, " ");
875                         sbuf_printf(&sb, " %02x", io->scsiio.kern_data_ptr[i]);
876                 }
877                 sbuf_cat(&sb, "\n");
878                 sbuf_finish(&sb);
879                 printf("%s", sbuf_data(&sb));
880         }
881 }
882
883 #else /* _KERNEL */
884
885 void
886 ctl_io_error_print(union ctl_io *io, struct scsi_inquiry_data *inq_data,
887                    FILE *ofile)
888 {
889         char str[512];
890
891         fprintf(ofile, "%s", ctl_io_error_string(io, inq_data, str,
892                 sizeof(str)));
893 }
894
895 #endif /* _KERNEL */
896
897 /*
898  * vim: ts=8
899  */