Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/cam/ctl/ctl_util.c
39483 views
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 <[email protected]>
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_nvme_all.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->io_hdr, 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: %#jx/%d, Prio: %d\n",
742
io->scsiio.tag_num, io->scsiio.tag_type,
743
io->scsiio.priority);
744
break;
745
case CTL_IO_TASK:
746
sbuf_cat(sb, path_str);
747
task_desc = ctl_scsi_task_string(&io->taskio);
748
if (task_desc == NULL)
749
sbuf_printf(sb, "Unknown Task Action %d (%#x)",
750
io->taskio.task_action, io->taskio.task_action);
751
else
752
sbuf_printf(sb, "Task Action: %s", task_desc);
753
switch (io->taskio.task_action) {
754
case CTL_TASK_ABORT_TASK:
755
sbuf_printf(sb, " Tag: %#jx/%d\n",
756
io->taskio.tag_num, io->taskio.tag_type);
757
break;
758
default:
759
sbuf_putc(sb, '\n');
760
break;
761
}
762
break;
763
case CTL_IO_NVME:
764
case CTL_IO_NVME_ADMIN:
765
sbuf_cat(sb, path_str);
766
ctl_nvme_command_string(&io->nvmeio, sb);
767
sbuf_printf(sb, " CID: 0x%x\n", le16toh(io->nvmeio.cmd.cid));
768
break;
769
default:
770
break;
771
}
772
}
773
774
void
775
ctl_io_error_sbuf(union ctl_io *io, struct scsi_inquiry_data *inq_data,
776
struct sbuf *sb)
777
{
778
struct ctl_status_desc *status_desc;
779
char path_str[64];
780
unsigned int i;
781
782
ctl_io_sbuf(io, sb);
783
784
status_desc = NULL;
785
for (i = 0; i < (sizeof(ctl_status_table)/sizeof(ctl_status_table[0]));
786
i++) {
787
if ((io->io_hdr.status & CTL_STATUS_MASK) ==
788
ctl_status_table[i].status) {
789
status_desc = &ctl_status_table[i];
790
break;
791
}
792
}
793
794
ctl_scsi_path_string(&io->io_hdr, path_str, sizeof(path_str));
795
796
sbuf_cat(sb, path_str);
797
if (status_desc == NULL)
798
sbuf_printf(sb, "CTL Status: Unknown status %#x\n",
799
io->io_hdr.status);
800
else
801
sbuf_printf(sb, "CTL Status: %s\n", status_desc->description);
802
803
switch (io->io_hdr.io_type) {
804
case CTL_IO_SCSI:
805
if ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_SCSI_ERROR) {
806
sbuf_cat(sb, path_str);
807
sbuf_printf(sb, "SCSI Status: %s\n",
808
ctl_scsi_status_string(&io->scsiio));
809
810
if (io->scsiio.scsi_status == SCSI_STATUS_CHECK_COND)
811
ctl_scsi_sense_sbuf(&io->scsiio, inq_data,
812
sb, SSS_FLAG_NONE);
813
}
814
break;
815
case CTL_IO_NVME:
816
case CTL_IO_NVME_ADMIN:
817
if ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_NVME_ERROR) {
818
sbuf_cat(sb, path_str);
819
sbuf_printf(sb, "NVMe Status: ");
820
ctl_nvme_status_string(&io->nvmeio, sb);
821
sbuf_printf(sb, "\n");
822
}
823
break;
824
default:
825
break;
826
}
827
}
828
829
char *
830
ctl_io_string(union ctl_io *io, char *str, int str_len)
831
{
832
struct sbuf sb;
833
834
sbuf_new(&sb, str, str_len, SBUF_FIXEDLEN);
835
ctl_io_sbuf(io, &sb);
836
sbuf_finish(&sb);
837
return (sbuf_data(&sb));
838
}
839
840
char *
841
ctl_io_error_string(union ctl_io *io, struct scsi_inquiry_data *inq_data,
842
char *str, int str_len)
843
{
844
struct sbuf sb;
845
846
sbuf_new(&sb, str, str_len, SBUF_FIXEDLEN);
847
ctl_io_error_sbuf(io, inq_data, &sb);
848
sbuf_finish(&sb);
849
return (sbuf_data(&sb));
850
}
851
852
#ifdef _KERNEL
853
854
void
855
ctl_io_print(union ctl_io *io)
856
{
857
char str[512];
858
859
printf("%s", ctl_io_string(io, str, sizeof(str)));
860
}
861
862
void
863
ctl_io_error_print(union ctl_io *io, struct scsi_inquiry_data *inq_data)
864
{
865
char str[512];
866
867
printf("%s", ctl_io_error_string(io, inq_data, str, sizeof(str)));
868
869
}
870
871
void
872
ctl_data_print(union ctl_io *io)
873
{
874
char str[128];
875
char path_str[64];
876
struct sbuf sb;
877
uintmax_t tag_num;
878
int i, j, len;
879
880
switch (io->io_hdr.io_type) {
881
case CTL_IO_SCSI:
882
tag_num = io->scsiio.tag_num;
883
break;
884
case CTL_IO_NVME:
885
case CTL_IO_NVME_ADMIN:
886
tag_num = le16toh(io->nvmeio.cmd.cid);
887
break;
888
default:
889
return;
890
}
891
if (io->io_hdr.flags & CTL_FLAG_BUS_ADDR)
892
return;
893
if (ctl_kern_sg_entries(io) > 0) /* XXX: Implement */
894
return;
895
ctl_scsi_path_string(&io->io_hdr, path_str, sizeof(path_str));
896
len = min(ctl_kern_data_len(io), 4096);
897
for (i = 0; i < len; ) {
898
sbuf_new(&sb, str, sizeof(str), SBUF_FIXEDLEN);
899
sbuf_cat(&sb, path_str);
900
sbuf_printf(&sb, " %#jx:%04x:", tag_num, i);
901
for (j = 0; j < 16 && i < len; i++, j++) {
902
if (j == 8)
903
sbuf_cat(&sb, " ");
904
sbuf_printf(&sb, " %02x", ctl_kern_data_ptr(io)[i]);
905
}
906
sbuf_cat(&sb, "\n");
907
sbuf_finish(&sb);
908
printf("%s", sbuf_data(&sb));
909
}
910
}
911
912
#else /* _KERNEL */
913
914
void
915
ctl_io_error_print(union ctl_io *io, struct scsi_inquiry_data *inq_data,
916
FILE *ofile)
917
{
918
char str[512];
919
920
fprintf(ofile, "%s", ctl_io_error_string(io, inq_data, str,
921
sizeof(str)));
922
}
923
924
#endif /* _KERNEL */
925
926
/*
927
* vim: ts=8
928
*/
929
930