39#include <sys/kernel.h>
44#include <sys/limits.h>
45#include <sys/malloc.h>
50#include <sys/sysctl.h>
51#include <sys/taskqueue.h>
54#include <sys/devicestat.h>
76#define SA_IO_TIMEOUT 32
78#ifndef SA_SPACE_TIMEOUT
79#define SA_SPACE_TIMEOUT 1 * 60
81#ifndef SA_REWIND_TIMEOUT
82#define SA_REWIND_TIMEOUT 2 * 60
84#ifndef SA_ERASE_TIMEOUT
85#define SA_ERASE_TIMEOUT 4 * 60
87#ifndef SA_REP_DENSITY_TIMEOUT
88#define SA_REP_DENSITY_TIMEOUT 1
91#define SCSIOP_TIMEOUT (60 * 1000)
93#define IO_TIMEOUT (SA_IO_TIMEOUT * 60 * 1000)
94#define REWIND_TIMEOUT (SA_REWIND_TIMEOUT * 60 * 1000)
95#define ERASE_TIMEOUT (SA_ERASE_TIMEOUT * 60 * 1000)
96#define SPACE_TIMEOUT (SA_SPACE_TIMEOUT * 60 * 1000)
97#define REP_DENSITY_TIMEOUT (SA_REP_DENSITY_TIMEOUT * 60 * 1000)
103#ifndef UNUSED_PARAMETER
104#define UNUSED_PARAMETER(x) x = x
108 if (((ccb)->ccb_h.status & CAM_DEV_QFRZN) != 0) \
109 cam_release_devq((ccb)->ccb_h.path, 0, 0, 0, FALSE)
121#define ccb_pflags ppriv_field0
122#define ccb_bp ppriv_ptr1
125#define SA_POSITION_UPDATED 0x1
243#define SA_QUIRK_BIT_STRING \
255#define SAMODE(z) (dev2unit(z) & 0x3)
256#define SA_IS_CTRL(z) (dev2unit(z) & (1 << 4))
258#define SA_NOT_CTLDEV 0
264#define SA_NUM_ATYPES 3
266#define SAMINOR(ctl, access) \
267 ((ctl << 4) | (access & 0x3))
276#define SASBADDBASE(sb, indent, data, xfmt, name, type, xsize, desc) \
277 sbuf_printf(sb, "%*s<%s type=\"%s\" size=\"%zd\" " \
278 "fmt=\"%s\" desc=\"%s\">" #xfmt "</%s>\n", indent, "", \
279 #name, #type, xsize, #xfmt, desc ? desc : "", data, #name);
281#define SASBADDINT(sb, indent, data, fmt, name) \
282 SASBADDBASE(sb, indent, data, fmt, name, int, sizeof(data), \
285#define SASBADDINTDESC(sb, indent, data, fmt, name, desc) \
286 SASBADDBASE(sb, indent, data, fmt, name, int, sizeof(data), \
289#define SASBADDUINT(sb, indent, data, fmt, name) \
290 SASBADDBASE(sb, indent, data, fmt, name, uint, sizeof(data), \
293#define SASBADDUINTDESC(sb, indent, data, fmt, name, desc) \
294 SASBADDBASE(sb, indent, data, fmt, name, uint, sizeof(data), \
297#define SASBADDFIXEDSTR(sb, indent, data, fmt, name) \
298 SASBADDBASE(sb, indent, data, fmt, name, str, sizeof(data), \
301#define SASBADDFIXEDSTRDESC(sb, indent, data, fmt, name, desc) \
302 SASBADDBASE(sb, indent, data, fmt, name, str, sizeof(data), \
305#define SASBADDVARSTR(sb, indent, data, fmt, name, maxlen) \
306 SASBADDBASE(sb, indent, data, fmt, name, str, maxlen, NULL)
308#define SASBADDVARSTRDESC(sb, indent, data, fmt, name, maxlen, desc) \
309 SASBADDBASE(sb, indent, data, fmt, name, str, maxlen, desc)
311#define SASBADDNODE(sb, indent, name) { \
312 sbuf_printf(sb, "%*s<%s type=\"%s\">\n", indent, "", #name, \
317#define SASBADDNODENUM(sb, indent, name, num) { \
318 sbuf_printf(sb, "%*s<%s type=\"%s\" num=\"%d\">\n", indent, "", \
319 #name, "node", num); \
323#define SASBENDNODE(sb, indent, name) { \
325 sbuf_printf(sb, "%*s</%s>\n", indent, "", #name); \
328#define SA_DENSITY_TYPES 4
355 {
"prot_method", MT_PARAM_SET_UNSIGNED,
358 {
"pi_length", MT_PARAM_SET_UNSIGNED,
361 {
"lbp_w", MT_PARAM_SET_UNSIGNED,
364 {
"lbp_r", MT_PARAM_SET_UNSIGNED,
367 {
"rbdp", MT_PARAM_SET_UNSIGNED,
372#define SA_NUM_PROT_ENTS nitems(sa_prot_table)
374#define SA_PROT_ENABLED(softc) ((softc->flags & SA_FLAG_PROTECT_SUPP) \
375 && (softc->prot_info.cur_prot_state.initialized != 0) \
376 && (softc->prot_info.cur_prot_state.prot_method != 0))
378#define SA_PROT_LEN(softc) softc->prot_info.cur_prot_state.pi_length
457#define last_io_sense errinfo._last_io_sense
458#define last_io_resid errinfo._last_io_resid
459#define last_io_cdb errinfo._last_io_cdb
460#define last_ctl_sense errinfo._last_ctl_sense
461#define last_ctl_resid errinfo._last_ctl_resid
462#define last_ctl_cdb errinfo._last_ctl_cdb
511 "VIPER 2525 25462",
"-011"},
599static void saasync(
void *callback_arg, u_int32_t code,
602 union ccb *start_ccb);
604 u_int32_t sense_flags);
609 u_int32_t *blocksize, u_int8_t *density,
610 u_int32_t *numblocks,
int *buff_mode,
611 u_int8_t *write_protect, u_int8_t *speed,
612 int *comp_supported,
int *comp_enabled,
613 u_int32_t *comp_algorithm,
616 *prot_page,
int dp_size,
617 int prot_changeable);
622 u_int32_t blocksize, u_int8_t density,
623 u_int32_t comp_algorithm,
624 u_int32_t sense_flags);
626 struct mtparamset *ps,
int num_params);
628 struct mtparamset *ps,
int num_params);
637 struct mtparamset *ps,
int num_params);
640 struct mtsetlist *list,
int need_copy);
642 struct sbuf *sb,
struct mtextget *g);
659 int nmarks,
int setmarks,
int immed);
665 uint8_t *buf,
int buf_len,
671#ifndef SA_DEFAULT_IO_SPLIT
672#define SA_DEFAULT_IO_SPLIT 0
683static SYSCTL_NODE(_kern_cam, OID_AUTO, sa, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
684 "CAM Sequential Access Tape Driver");
685SYSCTL_INT(_kern_cam_sa, OID_AUTO, allow_io_split, CTLFLAG_RDTUN,
691 TAILQ_HEAD_INITIALIZER(
sadriver.units), 0
702 .d_version = D_VERSION,
706 .d_write = physwrite,
710 .d_flags =
D_TAPE | D_TRACKCLOSE,
714saopen(
struct cdev *dev,
int flags,
int fmt,
struct thread *td)
730 (
"saopen(%s): softc=0x%x\n", devtoname(dev), softc->
flags));
763 if (error && (
flags & O_NONBLOCK)) {
790saclose(
struct cdev *dev,
int flag,
int fmt,
struct thread *td)
794 int mode, error, writing, tmp, i;
804 (
"saclose(%s): softc=0x%x\n", devtoname(dev), softc->
flags));
816 softc->
flags &= ~SA_FLAG_OPEN;
842 "failed to write terminating filemark(s)\n");
856 }
else switch (mode) {
898 "over one of double filemarks at end of "
901 "this device needs a SA_QUIRK_1FM quirk set"
917 softc->
flags &= ~SA_FLAG_TAPE_WRITTEN;
922 softc->
flags &= ~closedbits;
939 "REWIND or MTEOM command to clear this state.\n");
964 bp->bio_resid = bp->bio_bcount;
966 biofinish(bp, NULL, EINVAL);
976 biofinish(bp, NULL, ENXIO);
982 biofinish(bp, NULL, EPERM);
991 if (bp->bio_cmd == BIO_WRITE && softc->
open_rdonly) {
993 biofinish(bp, NULL, EBADF);
1001 biofinish(bp, NULL, ENXIO);
1011 if (bp->bio_bcount == 0) {
1024 ((bp->bio_bcount & softc->
blk_mask) != 0)) ||
1026 ((bp->bio_bcount % softc->
min_blk) != 0))) {
1028 "device requests must be a multiple of %d bytes\n",
1031 biofinish(bp, NULL, EINVAL);
1034 }
else if ((bp->bio_bcount > softc->
max_blk) ||
1035 (bp->bio_bcount < softc->
min_blk) ||
1036 (bp->bio_bcount & softc->
blk_mask) != 0) {
1038 printf(
"Invalid request. Variable block "
1039 "device requests must be ");
1041 printf(
"a multiple of %d ", (0x1 << softc->
blk_gran));
1043 printf(
"between %d and %d bytes\n", softc->
min_blk,
1046 biofinish(bp, NULL, EINVAL);
1053 bioq_insert_tail(&softc->
bio_queue, bp);
1057 (
"sastrategy: queuing a %ld %s byte %s\n", bp->bio_bcount,
1059 (bp->bio_cmd == BIO_READ)?
"read" :
"write"));
1063 (
"sastrategy: queue count now %d\n", softc->
queue_count));
1078 uint32_t sili_blocksize;
1085 if (ps->value_type != MT_PARAM_SET_SIGNED) {
1086 snprintf(ps->error_str,
sizeof(ps->error_str),
1087 "sili is a signed parameter");
1090 if ((ps->value.value_signed < 0)
1091 || (ps->value.value_signed > 1)) {
1092 snprintf(ps->error_str,
sizeof(ps->error_str),
1093 "invalid sili value %jd", (intmax_t)ps->value.value_signed);
1102 snprintf(ps->error_str,
sizeof(ps->error_str),
1103 "can't set sili bit in fixed block mode");
1106 if (softc->
sili == ps->value.value_signed)
1109 if (ps->value.value_signed == 1)
1117 snprintf(ps->error_str,
sizeof(ps->error_str),
1118 "sasetparams() returned error %d", error);
1122 softc->
sili = ps->value.value_signed;
1125 ps->status = MT_PARAM_STATUS_OK;
1129 ps->status = MT_PARAM_STATUS_ERROR;
1145 if (ps->value_type != MT_PARAM_SET_SIGNED) {
1146 snprintf(ps->error_str,
sizeof(ps->error_str),
1147 "eot_warn is a signed parameter");
1148 ps->status = MT_PARAM_STATUS_ERROR;
1151 if ((ps->value.value_signed < 0)
1152 || (ps->value.value_signed > 1)) {
1153 snprintf(ps->error_str,
sizeof(ps->error_str),
1154 "invalid eot_warn value %jd\n",
1155 (intmax_t)ps->value.value_signed);
1156 ps->status = MT_PARAM_STATUS_ERROR;
1159 softc->
eot_warn = ps->value.value_signed;
1160 ps->status = MT_PARAM_STATUS_OK;
1162 if (ps->status != MT_PARAM_STATUS_OK)
1179 "Set to 1 if protection information is supported");
1190 pi_length,
"Length of Protection Information");
1192 lbp_w,
"Check Protection on Writes");
1194 lbp_r,
"Check and Include Protection on Reads");
1196 rbdp,
"Transfer Protection Information for RECOVER "
1197 "BUFFERED DATA command");
1208 bcopy(
sa_prot_table, new_table, min(table_ents *
sizeof(*new_table),
1213 for (i = 0; i < table_ents; i++)
1214 new_table[i].value = (uint32_t *)((uint8_t *)cur_state +
1215 new_table[i].offset);
1223 char *prot_name =
"protection.";
1226 prot_len = strlen(prot_name);
1231 if (strncmp(
name, prot_name, prot_len) != 0)
1234 for (i = 0; i < table_ents; i++) {
1235 if (strcmp(&
name[prot_len], table[i].
name) != 0)
1260 snprintf(ps[0].error_str,
sizeof(ps[0].error_str),
1261 "Protection information is not supported for this device");
1262 ps[0].status = MT_PARAM_STATUS_ERROR;
1272 if ((softc->
si_flags & SI_NOSPLIT) == 0) {
1273 snprintf(ps[0].error_str,
sizeof(ps[0].error_str),
1274 "Protection information cannot be enabled with I/O "
1276 ps[0].status = MT_PARAM_STATUS_ERROR;
1296 for (i = 0; i < num_params; i++) {
1302 ps[i].status = MT_PARAM_STATUS_ERROR;
1303 snprintf(ps[i].error_str,
sizeof(ps[i].error_str),
1304 "Invalid protection entry name %s",
1310 ps[i].status = MT_PARAM_STATUS_ERROR;
1311 snprintf(ps[i].error_str,
sizeof(ps[i].error_str),
1312 "Supplied type %d does not match actual type %d",
1318 || (ps[i].value.value_unsigned > ent->
max_val)) {
1319 ps[i].status = MT_PARAM_STATUS_ERROR;
1320 snprintf(ps[i].error_str,
sizeof(ps[i].error_str),
1321 "Value %ju is outside valid range %u - %u",
1335 for (i = 0; i < num_params; i++) {
1336 ps[i].status = MT_PARAM_STATUS_ERROR;
1337 snprintf(ps[i].error_str,
sizeof(ps[i].error_str),
1338 "Unable to set parameter, see dmesg(8)");
1346 for (i = 0; i < num_params; i++)
1347 ps[i].status = MT_PARAM_STATUS_OK;
1407 struct mtparamset *params, *first;
1413 if (list->num_params == 0)
1420 if ((list->num_params *
sizeof(
struct mtparamset)) !=
1423 "sizeof(struct mtparamset) %zd * num_params %d\n",
1424 __func__, list->param_len,
sizeof(
struct mtparamset),
1430 if (need_copy != 0) {
1435 params = malloc(list->param_len, M_SCSISA, M_WAITOK | M_ZERO);
1436 error = copyin(list->params, params, list->param_len);
1442 params = list->params;
1448 for (i = 0; i < list->num_params; i++) {
1453 snprintf(params[i].error_str,
1454 sizeof(params[i].error_str),
1455 "%s: cannot find parameter %s", __func__,
1456 params[i].value_name);
1457 params[i].status = MT_PARAM_STATUS_ERROR;
1461 if (first != NULL) {
1462 if (first_ent == ent) {
1471 error = first_ent->
set_func(periph, first,
1487 error = ent->
set_func(periph, ¶ms[i], 1);
1495 first_ent->
set_func(periph, first, contig_ents);
1498 if (need_copy != 0) {
1499 if (error != EFAULT) {
1501 copyout(params, list->params, list->param_len);
1504 free(params, M_SCSISA);
1513 u_int8_t write_protect;
1514 int comp_enabled, comp_supported, error;
1527 &write_protect, &softc->
speed, &comp_supported, &comp_enabled,
1534 softc->
flags &= ~SA_FLAG_TAPE_WP;
1535 softc->
flags &= ~SA_FLAG_COMPRESSION;
1536 if (comp_supported) {
1549#define PENDING_MOUNT_CHECK(softc, periph, dev) \
1550 if (softc->open_pending_mount) { \
1551 error = samount(periph, 0, dev); \
1555 saprevent(periph, PR_PREVENT); \
1556 softc->open_pending_mount = 0; \
1560saioctl(
struct cdev *dev, u_long cmd, caddr_t arg,
int flag,
struct thread *td)
1565 int didlockperiph = 0;
1587 case MTIOCGETEOTMODEL:
1615 struct mtop *mt = (
struct mtop *) arg;
1621 switch (mt->mt_op) {
1635 case MTIOCSETEOTMODEL:
1661 struct mtget *g = (
struct mtget *)arg;
1666 bzero(g,
sizeof(
struct mtget));
1667 g->mt_type = MT_ISAR;
1669 g->mt_comp = MT_COMP_UNSUPP;
1670 g->mt_comp0 = MT_COMP_UNSUPP;
1671 g->mt_comp1 = MT_COMP_UNSUPP;
1672 g->mt_comp2 = MT_COMP_UNSUPP;
1673 g->mt_comp3 = MT_COMP_UNSUPP;
1676 g->mt_comp = MT_COMP_DISABLED;
1695 g->mt_fileno = softc->
fileno;
1696 g->mt_blkno = softc->
blkno;
1697 g->mt_dsreg = (short) softc->
dsreg;
1702 if ((g->mt_resid = (
short) softc->last_io_resid) != 0) {
1704 softc->last_io_resid = 0;
1708 if ((g->mt_resid = (
short)softc->last_ctl_resid) != 0) {
1710 softc->last_ctl_resid = 0;
1720 struct mtextget *g = (
struct mtextget *)arg;
1732 sb = sbuf_new(NULL, NULL, g->alloc_len, SBUF_FIXEDLEN);
1734 g->status = MT_EXT_GET_ERROR;
1735 snprintf(g->error_str,
sizeof(g->error_str),
1736 "Unable to allocate %d bytes for status info",
1739 goto extget_bailout;
1743 if (cmd == MTIOCEXTGET)
1744 error =
saextget(dev, periph, sb, g);
1749 goto extget_bailout;
1751 error = sbuf_finish(sb);
1752 if (error == ENOMEM) {
1753 g->status = MT_EXT_GET_NEED_MORE_SPACE;
1755 }
else if (error != 0) {
1756 g->status = MT_EXT_GET_ERROR;
1757 snprintf(g->error_str,
sizeof(g->error_str),
1758 "Error %d returned from sbuf_finish()", error);
1760 g->status = MT_EXT_GET_OK;
1763 tmpstr2 = sbuf_data(sb);
1764 g->fill_len = strlen(tmpstr2) + 1;
1767 error = copyout(tmpstr2, g->status_xml, g->fill_len);
1777 struct mtsetlist list;
1778 struct mtparamset *ps = (
struct mtparamset *)arg;
1780 bzero(&list,
sizeof(list));
1781 list.num_params = 1;
1782 list.param_len =
sizeof(*ps);
1790 struct mtsetlist *list = (
struct mtsetlist *)arg;
1797 struct scsi_tape_errors *sep =
1798 &((
union mterrstat *)arg)->scsi_errstat;
1801 (
"saioctl: MTIOCERRSTAT\n"));
1803 bzero(sep,
sizeof(*sep));
1804 sep->io_resid = softc->last_io_resid;
1805 bcopy((caddr_t) &softc->last_io_sense, sep->io_sense,
1806 sizeof (sep->io_sense));
1807 bcopy((caddr_t) &softc->last_io_cdb, sep->io_cdb,
1808 sizeof (sep->io_cdb));
1809 sep->ctl_resid = softc->last_ctl_resid;
1810 bcopy((caddr_t) &softc->last_ctl_sense, sep->ctl_sense,
1811 sizeof (sep->ctl_sense));
1812 bcopy((caddr_t) &softc->last_ctl_cdb, sep->ctl_cdb,
1813 sizeof (sep->ctl_cdb));
1817 bzero((caddr_t) &softc->
errinfo,
1829 mt = (
struct mtop *)arg;
1832 (
"saioctl: op=0x%x count=0x%x\n",
1833 mt->mt_op, mt->mt_count));
1835 count = mt->mt_count;
1836 switch (mt->mt_op) {
1868 "EOD check prior to spacing failed\n");
1911 error =
saspace(periph, count - nmarks, spaceop);
1933 softc->
flags &= ~SA_FLAG_ERR_PENDING;
1938 error =
saerase(periph, count);
1941 softc->
flags &= ~SA_FLAG_ERR_PENDING;
1948 softc->
flags &= ~SA_FLAG_ERR_PENDING;
1956 softc->
flags &= ~SA_FLAG_TAPE_WRITTEN;
1961 softc->
flags &= ~SA_FLAG_TAPE_FROZEN;
1971 softc->
flags &= ~SA_FLAG_TAPE_MOUNTED;
1989 if ((softc->
sili != 0)
1992 "block mode with SILI enabled\n");
2004 if (powerof2(count)) {
2015 softc->
quirks &= ~SA_QUIRK_VARIABLE;
2018 softc->
flags &= ~SA_FLAG_FIXED;
2033 softc->
quirks &= ~SA_QUIRK_FIXED;
2040 if (count > UCHAR_MAX) {
2074 error =
sardpos(periph, 0, (u_int32_t *) arg);
2078 error =
sardpos(periph, 1, (u_int32_t *) arg);
2081 case MTIOCHLOCATE: {
2082 struct mtlocate locate_info;
2085 bzero(&locate_info,
sizeof(locate_info));
2086 locate_info.logical_id = *((uint32_t *)arg);
2087 if (cmd == MTIOCSLOCATE)
2094 error =
sasetpos(periph, hard, &locate_info);
2097 case MTIOCEXTLOCATE:
2099 error =
sasetpos(periph, 0, (
struct mtlocate *)arg);
2102 softc->
flags &= ~SA_FLAG_ERR_PENDING;
2105 case MTIOCGETEOTMODEL:
2111 *((u_int32_t *) arg) = mode;
2113 case MTIOCSETEOTMODEL:
2115 switch (*((u_int32_t *) arg)) {
2117 softc->
quirks &= ~SA_QUIRK_2FM;
2121 softc->
quirks &= ~SA_QUIRK_1FM;
2130 struct mtrblim *rblim;
2132 rblim = (
struct mtrblim *)arg;
2134 rblim->granularity = softc->
blk_gran;
2135 rblim->min_block_length = softc->
min_blk;
2136 rblim->max_block_length = softc->
max_blk;
2156 softc->
fileno = (daddr_t) -1;
2157 softc->
blkno = (daddr_t) -1;
2161 softc->
flags &= ~SA_FLAG_TAPE_FROZEN;
2163 "tape state now unfrozen.\n");
2169 if (didlockperiph) {
2187 printf(
"sa: Failed to attach master async callback "
2188 "due to status 0x%x!\n", status);
2256 bioq_flush(&softc->
bio_queue, NULL, ENXIO);
2281 || sysctl_ctx_free(&softc->
sysctl_ctx) != 0))
2288 free(softc, M_SCSISA);
2327 printf(
"saasync: Unable to probe new device "
2328 "due to status 0x%x\n", status);
2341 dev->si_iosize_max = softc->
maxio;
2348 if ((dev->si_flags & SI_ALIAS) == 0)
2368 snprintf(tmpstr,
sizeof(tmpstr),
"kern.cam.sa.timeout.%s",
2370 retval = TUNABLE_INT_FETCH(tmpstr, &tmpval);
2378 snprintf(tmpstr,
sizeof(tmpstr),
"kern.cam.sa.%u.timeout.%s",
2380 retval = TUNABLE_INT_FETCH(tmpstr, &tmpval);
2391 char tmpstr[64], tmpstr2[16];
2409 SYSCTL_STATIC_CHILDREN(_kern_cam_sa), OID_AUTO, tmpstr2,
2410 CTLFLAG_RD | CTLFLAG_MPSAFE, 0, tmpstr,
"device_index");
2415 OID_AUTO,
"allow_io_split", CTLFLAG_RDTUN | CTLFLAG_NOFETCH,
2418 OID_AUTO,
"maxio", CTLFLAG_RD,
2419 &softc->
maxio, 0,
"Maximum I/O size");
2421 OID_AUTO,
"cpi_maxio", CTLFLAG_RD,
2422 &softc->
cpi_maxio, 0,
"Maximum Controller I/O size");
2424 OID_AUTO,
"inject_eom", CTLFLAG_RW,
2425 &softc->
inject_eom, 0,
"Queue EOM for the next write/read");
2429 SYSCTL_CHILDREN(softc->
sysctl_tree), OID_AUTO,
"timeout",
2430 CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
"Timeouts");
2435 snprintf(tmpstr,
sizeof(tmpstr),
"%s timeout",
2466 struct make_dev_args args;
2474 printf(
"saregister: no getdev CCB, can't register device\n");
2479 malloc(
sizeof (*softc), M_SCSISA, M_NOWAIT | M_ZERO);
2480 if (softc == NULL) {
2481 printf(
"saregister: Unable to probe new device. "
2482 "Unable to allocate softc\n");
2487 softc->
fileno = (daddr_t) -1;
2488 softc->
blkno = (daddr_t) -1;
2508 if (match != NULL) {
2554 bzero(&ext_inq,
sizeof(ext_inq));
2556 memset(&cdai, 0,
sizeof(cdai));
2562 cdai.
bufsiz =
sizeof(ext_inq);
2563 cdai.
buf = (uint8_t *)&ext_inq;
2595 snprintf(tmpstr,
sizeof(tmpstr),
"kern.cam.sa.%u.allow_io_split",
2604 softc->
maxio = DFLTPHYS;
2605 else if (cpi.
maxio > maxphys)
2606 softc->
maxio = maxphys;
2643 "registration!\n", __func__);
2648 make_dev_args_init(&args);
2650 args.mda_si_drv1 = softc->
periph;
2651 args.mda_uid = UID_ROOT;
2652 args.mda_gid = GID_OPERATOR;
2653 args.mda_mode = 0660;
2656 error = make_dev_s(&args, &softc->
devs.
ctl_dev,
"%s%d.ctl",
2665 error = make_dev_s(&args, &softc->
devs.
r_dev,
"%s%d",
2674 error = make_dev_s(&args, &softc->
devs.
nr_dev,
"n%s%d",
2683 error = make_dev_s(&args, &softc->
devs.
er_dev,
"e%s%d",
2704 taskqueue_enqueue(taskqueue_thread, &softc->
sysctl_task);
2760 switch (softc->
state) {
2774 struct bio *done_bp;
2788 if (bp->bio_cmd == BIO_WRITE)
2796 bp->bio_resid = bp->bio_bcount;
2823 bp->bio_flags |= BIO_ERROR;
2824 bp->bio_error = ENOSPC;
2835 if (bioq_first(&softc->
bio_queue) != NULL) {
2840 bp->bio_error = EIO;
2841 bp->bio_flags |= BIO_ERROR;
2849 softc->
flags &= ~SA_FLAG_ERR_PENDING;
2851 (
"sastart- ERR_PENDING now 0x%x, bp is %sNULL, "
2852 "%d more buffers queued up\n",
2863 if ((bp->bio_cmd != BIO_READ) &&
2864 (bp->bio_cmd != BIO_WRITE)) {
2865 biofinish(bp, NULL, EOPNOTSUPP);
2869 length = bp->bio_bcount;
2877 bp->bio_error = EIO;
2879 " for FIXED length writes?\n");
2885 (
"issuing a %d fixed record %s\n",
2886 length, (bp->bio_cmd == BIO_READ)?
"read" :
2892 (
"issuing a %d variable byte %s\n",
2893 length, (bp->bio_cmd == BIO_READ)?
"read" :
2897 devstat_start_transaction_bio(softc->
device_stats, bp);
2931 softc->
dsreg = (bp->bio_cmd == BIO_READ)?
2932 MTIO_DSREG_RD : MTIO_DSREG_WR;
2936 ((bp->bio_flags & BIO_UNMAPPED) != 0 ?
2939 (bp->bio_flags & BIO_UNMAPPED) != 0 ? (
void *)bp :
2941 (bp->bio_cmd == BIO_READ) ?
2944 start_ccb->
ccb_h.ccb_pflags &= ~SA_POSITION_UPDATED;
2945 start_ccb->
ccb_h.ccb_bp = bp;
2972 alloc_len = num_opcodes *
2976 params = malloc(alloc_len, M_SCSISA, M_NOWAIT| M_ZERO);
2977 if (params == NULL) {
3011 panic(
"state 0x%x in sastart", softc->
state);
3025 csio = &done_ccb->
csio;
3029 softc->
dsreg = MTIO_DSREG_REST;
3030 bp = (
struct bio *)done_ccb->
ccb_h.ccb_bp;
3033 if ((error =
saerror(done_ccb, 0, 0)) == ERESTART) {
3058 }
else if (error != 0) {
3098 panic(
"state 0x%x in sadone", softc->
state);
3114 bioq_flush(&softc->
bio_queue, NULL, EIO);
3117 bp->bio_resid = bp->bio_bcount;
3118 bp->bio_error = error;
3119 bp->bio_flags |= BIO_ERROR;
3124 bp->bio_resid = csio->
resid;
3126 if (csio->
resid != 0) {
3127 bp->bio_flags |= BIO_ERROR;
3129 if (bp->bio_cmd == BIO_WRITE) {
3134 (softc->
blkno != (daddr_t) -1)) {
3138 l = bp->bio_bcount >>
3141 l = bp->bio_bcount /
3144 softc->
blkno += (daddr_t) l;
3156 if (error || bp->bio_resid) {
3158 (
"error %d resid %ld count %ld\n", error,
3159 bp->bio_resid, bp->bio_bcount));
3200 if (error == ENXIO) {
3201 softc->
flags &= ~SA_FLAG_TAPE_MOUNTED;
3212 softc->
flags &= ~SA_FLAG_TAPE_MOUNTED;
3215 "error %d on TUR in samount\n", error);
3233 int comp_enabled, comp_supported;
3234 u_int8_t write_protect, guessing = 0;
3275 malloc(8192, M_SCSISA, M_NOWAIT);
3276 if (rblim == NULL) {
3298 "unable to rewind after test read\n");
3349 &softc->
speed, &comp_supported,
3379 static u_int8_t ctry[] = {
3397 for (i = 0; ctry[i]; i++) {
3416 softc->
quirks &= ~SA_QUIRK_2FM;
3422 softc->
quirks &= ~SA_QUIRK_2FM;
3446 softc->
quirks &= ~SA_QUIRK_1FM;
3461 "BLOCK LIMITS (%d..%d) could not match current "
3462 "block settings (%d)- adjusting\n", softc->
min_blk,
3496 "unable to set fixed blocksize to %d\n",
3516 softc->
quirks &= ~SA_QUIRK_VARIABLE;
3523 "unable to set variable blocksize\n");
3563 if (comp_supported) {
3581 "unable to set buffered mode\n");
3591 free(rblim, M_SCSISA);
3594 softc->
dsreg = MTIO_DSREG_NIL;
3599 softc->
dsreg = MTIO_DSREG_REST;
3621 softc->last_io_resid = 0;
3622 softc->last_ctl_resid = 0;
3646 return (markswanted);
3657 if (markswanted > 0) {
3668 static const char *toobig =
3669 "%d-byte tape record bigger than supplied buffer\n";
3677 int error_code, sense_key, asc, ascq, error, aqvalid, stream_valid;
3679 uint8_t stream_bits;
3688 if (asc != -1 && ascq != -1)
3720 bcopy((caddr_t) sense, (caddr_t) &softc->last_io_sense,
3724 softc->last_io_resid = resid;
3727 bcopy((caddr_t) sense, (caddr_t) &softc->last_ctl_sense,
3731 softc->last_ctl_resid = resid;
3735 "ASC/ASCQ 0x%x/0x%x CAM STATUS 0x%x flags 0x%x resid %jd "
3737 sense_key, asc, ascq, status,
3738 (stream_valid) ? stream_bits : 0, (intmax_t)resid,
3742 (
"Cam Status 0x%x\n", status));
3761 if ((aqvalid && asc == 0 && ((ascq > 0 && ascq <= 5)
3764 csio->
resid = resid;
3795 csio->
resid = resid;
3797 }
else if ((stream_valid != 0) && (stream_bits &
SSD_EOM)) {
3808 csio->
resid = resid;
3816 }
else if ((stream_valid != 0) && (stream_bits &
SSD_FILEMARK)){
3825 if (softc->
fileno != (daddr_t) -1) {
3836 if (error == 0 && (stream_valid != 0) && (stream_bits &
SSD_ILI)) {
3843 csio->
resid = resid;
3851 if ((stream_valid == 0) ||
3853 if (softc->
blkno != (daddr_t) -1) {
3855 csio->
ccb_h.ccb_pflags |=
3876 u_int32_t *blocksize, u_int8_t *density, u_int32_t *numblocks,
3877 int *buff_mode, u_int8_t *write_protect, u_int8_t *
speed,
3878 int *comp_supported,
int *comp_enabled, u_int32_t *
comp_algorithm,
3880 int dp_size,
int prot_changeable)
3886 int mode_buffer_len;
3900 mode_buffer_len =
sizeof(*mode_hdr) +
sizeof(*mode_blk);
3904 *comp_supported = FALSE;
3905 params_to_get &= ~SA_PARAM_COMPRESSION;
3911 mode_buffer = malloc(mode_buffer_len, M_SCSISA, M_NOWAIT | M_ZERO);
3912 if (mode_buffer == NULL) {
3943 free(mode_buffer, M_SCSISA);
3948 goto sagetparamsexit;
3974 bcopy(&mode_hdr[0], &mode_hdr[1],
sizeof (
sa_comp_t));
3975 bzero(&mode_hdr[0],
sizeof (mode_hdr[0]));
3991 goto sagetparamsexit;
4028 *comp_supported = TRUE;
4090 int dp_len, returned_len;
4093 dp_size =
sizeof(*dp_page);
4095 dp_len =
sizeof(*mode10_hdr) + dp_size;
4096 mode10_hdr = malloc(dp_len, M_SCSISA, M_NOWAIT | M_ZERO);
4097 if (mode10_hdr == NULL) {
4099 goto sagetparamsexit;
4107 (prot_changeable == 0) ?
4111 (uint8_t *)mode10_hdr,
4127 free(mode10_hdr, M_SCSISA);
4128 goto sagetparamsexit;
4134 free(mode10_hdr, M_SCSISA);
4135 goto sagetparamsexit;
4143 if (returned_len <
sizeof(mode10_hdr->
data_length)) {
4145 free(mode10_hdr, M_SCSISA);
4146 goto sagetparamsexit;
4149 returned_len = min(returned_len,
4160 if (returned_len < (
sizeof(*mode10_hdr) +
4164 free(mode10_hdr, M_SCSISA);
4165 goto sagetparamsexit;
4177 if (prot_page != NULL)
4178 bcopy(dp_page, prot_page, min(
sizeof(*prot_page),
4181 free(mode10_hdr, M_SCSISA);
4186 char *xyz = mode_buffer;
4188 printf(
"Mode Sense Data=");
4189 for (idx = 0; idx < mode_buffer_len; idx++)
4190 printf(
" 0x%02x", xyz[idx] & 0xff);
4197 free(mode_buffer, M_SCSISA);
4212 uint8_t current_speed;
4213 size_t dp_size, dp_page_length;
4214 int dp_len, buff_mode;
4219 mode10_changeable = NULL;
4226 dp_size =
sizeof(*dp_changeable);
4227 dp_page_length = dp_size -
4232 dp_len =
sizeof(*mode10_changeable) + dp_size;
4233 mode10_changeable = malloc(dp_len, M_SCSISA, M_NOWAIT | M_ZERO);
4234 if (mode10_changeable == NULL) {
4255 NULL, NULL, NULL, &buff_mode, NULL, ¤t_speed, NULL, NULL,
4256 NULL, NULL, dp_changeable, dp_size, 1);
4262 dp_size = dp_page_length +
4265 free(mode10_changeable, M_SCSISA);
4266 mode10_changeable = NULL;
4270 mode10_hdr = malloc(dp_len, M_SCSISA, M_NOWAIT | M_ZERO);
4271 if (mode10_hdr == NULL) {
4282 NULL, NULL, NULL, &buff_mode, NULL, ¤t_speed, NULL, NULL,
4283 NULL, NULL, dp_page, dp_size, 0);
4293 mode10_hdr->
dev_spec = current_speed;
4307 dp_page->
pi_length &= ~SA_CTRL_DP_PI_LENGTH_MASK;
4312 if (new_prot->
lbp_w)
4315 dp_page->
prot_bits &= ~SA_CTRL_DP_LBP_W;
4319 if (new_prot->
lbp_r)
4322 dp_page->
prot_bits &= ~SA_CTRL_DP_LBP_R;
4340 (uint8_t *)mode10_hdr,
4362 NULL, NULL, NULL, &buff_mode, NULL, ¤t_speed, NULL, NULL,
4363 NULL, NULL, dp_page, dp_size, 0);
4368 free(mode10_hdr, M_SCSISA);
4369 free(mode10_changeable, M_SCSISA);
4391 u_int32_t blocksize, u_int8_t density, u_int32_t calg,
4392 u_int32_t sense_flags)
4395 u_int32_t current_blocksize;
4396 u_int32_t current_calg;
4397 u_int8_t current_density;
4398 u_int8_t current_speed;
4399 int comp_enabled, comp_supported;
4401 int mode_buffer_len;
4411 ccomp = malloc(
sizeof (
sa_comp_t), M_SCSISA, M_NOWAIT);
4423 ¤t_blocksize, ¤t_density, NULL, &buff_mode, NULL,
4424 ¤t_speed, &comp_supported, &comp_enabled,
4425 ¤t_calg, ccomp, NULL, 0, 0);
4428 free(ccomp, M_SCSISA);
4432 mode_buffer_len =
sizeof(*mode_hdr) +
sizeof(*mode_blk);
4436 mode_buffer = malloc(mode_buffer_len, M_SCSISA, M_NOWAIT | M_ZERO);
4437 if (mode_buffer == NULL) {
4438 free(ccomp, M_SCSISA);
4455 bcopy(ccomp, cpage,
sizeof (
sa_comp_t));
4492 mode_hdr->
dev_spec = current_speed;
4530 if (calg != MT_COMP_ENABLE) {
4561 if (calg != MT_COMP_ENABLE) {
4588 params_to_set &= ~SA_PARAM_COMPRESSION;
4590 "device does not seem to support compression\n");
4598 free(mode_buffer, M_SCSISA);
4623 char *xyz = mode_buffer;
4625 printf(
"Err%d, Mode Select Data=", error);
4626 for (idx = 0; idx < mode_buffer_len; idx++)
4627 printf(
" 0x%02x", xyz[idx] & 0xff);
4636 if ((params_to_set &
4659 mode_blk->
density = current_density;
4667 bcopy(ccomp, cpage,
sizeof (
sa_comp_t));
4681 free(ccomp, M_SCSISA);
4685 softc->
flags &= ~SA_FLAG_COMP_ENABLED;
4700 free(mode_buffer, M_SCSISA);
4721 goto extget_bailout;
4733 memset(&cgd, 0,
sizeof(cgd));
4740 g->status = MT_EXT_GET_ERROR;
4741 snprintf(g->error_str,
sizeof(g->error_str),
4742 "Error %#x returned for XPT_GDEV_TYPE CCB",
4744 goto extget_bailout;
4772 tmpstr2 = malloc(ts2_len, M_SCSISA, M_NOWAIT | M_ZERO);
4780 if (tmpstr2 == NULL) {
4782 goto extget_bailout;
4785 ts2_len =
sizeof(tmpstr);
4795 if (ts2_malloc != 0)
4796 free(tmpstr2, M_SCSISA);
4804 (ssize_t)0,
"Serial Number");
4808 "Maximum I/O size allowed by driver and controller");
4811 "Maximum I/O size reported by controller");
4814 "Maximum block size supported by tape drive and media");
4817 "Minimum block size supported by tape drive and media");
4820 "Block granularity supported by tape drive and media");
4825 "Maximum possible I/O size");
4828 fixed_mode,
"Set to 1 for fixed block mode, 0 for variable block");
4838 "Set to 1 if compression is supported, 0 if not");
4844 "Set to 1 if compression is enabled, 0 if not");
4846 compression_algorithm,
"Numeric compression algorithm");
4851 media_blocksize,
"Block size reported by drive or set by user");
4853 calculated_fileno,
"Calculated file number, -1 if unknown");
4855 calculated_rel_blkno,
"Calculated block number relative to file, "
4856 "set to -1 if unknown");
4858 reported_fileno,
"File number reported by drive, -1 if unknown");
4860 reported_blkno,
"Block number relative to BOP/BOT reported by "
4861 "drive, -1 if unknown");
4863 partition,
"Current partition number, 0 is the default");
4865 "Set to 1 if drive is at the beginning of partition/tape, 0 if "
4866 "not, -1 if unknown");
4868 "Set to 1 if drive is past early warning, 0 if not, -1 if unknown");
4870 "Set to 1 if drive is past programmable early warning, 0 if not, "
4873 residual,
"Residual for the last I/O");
4879 "Current state of the driver");
4898 "Suppress an error on underlength variable reads");
4900 "Return an error to warn that end of tape is approaching");
4938 softc->
flags &= ~SA_FLAG_TAPE_LOCKED;
4961 softc->
dsreg = MTIO_DSREG_REW;
4963 softc->
dsreg = MTIO_DSREG_REST;
4996 softc->last_ctl_resid = 0;
4998 softc->
dsreg = (count < 0)? MTIO_DSREG_REV : MTIO_DSREG_FWD;
5000 softc->
dsreg = MTIO_DSREG_REST;
5030 softc->
fileno += (count - softc->last_ctl_resid);
5035 softc->
blkno += (count - softc->last_ctl_resid);
5037 if (softc->last_ctl_resid || softc->
blkno < 0) {
5038 if (softc->
fileno == 0) {
5041 softc->
blkno = (daddr_t) -1;
5067 softc->last_ctl_resid = 0;
5069 softc->
dsreg = MTIO_DSREG_FMK;
5074 softc->
dsreg = MTIO_DSREG_REST;
5078 if (error == 0 && nmarks) {
5080 nwm = nmarks - softc->last_ctl_resid;
5091 }
else if (softc->
fileno != (daddr_t) -1) {
5126 return (EOPNOTSUPP);
5129 bzero(&long_pos,
sizeof(long_pos));
5137 (uint8_t *)&long_pos,
5143 softc->
dsreg = MTIO_DSREG_RBSY;
5146 softc->
dsreg = MTIO_DSREG_REST;
5155 softc->
fileno = (daddr_t) -1;
5169 softc->
blkno = (daddr_t) -1;
5192 }
else if (error == EINVAL) {
5231 if (error && error != EACCES)
5239 softc->
dsreg = MTIO_DSREG_RBSY;
5241 softc->
dsreg = MTIO_DSREG_REST;
5275 cp = locate_info->flags & MT_LOCATE_FLAG_CHANGE_PART ? 1 : 0;
5276 immed = locate_info->flags & MT_LOCATE_FLAG_IMMED ? 1 : 0;
5287 else if ((locate_info->dest_type != MT_LOCATE_DEST_OBJECT)
5288 || (locate_info->block_address_mode != MT_LOCATE_BAM_IMPLICIT)
5294 if (locate16 != 0) {
5301 locate_info->dest_type,
5302 locate_info->block_address_mode,
5303 locate_info->partition,
5304 locate_info->logical_id,
5316 locate_info->partition,
5317 locate_info->logical_id,
5323 softc->
dsreg = MTIO_DSREG_POS;
5325 softc->
dsreg = MTIO_DSREG_REST;
5340 softc->
partition = locate_info->partition;
5345 switch (locate_info->dest_type) {
5346 case MT_LOCATE_DEST_FILE:
5351 softc->
fileno = locate_info->logical_id;
5354 case MT_LOCATE_DEST_OBJECT:
5355 case MT_LOCATE_DEST_SET:
5356 case MT_LOCATE_DEST_EOD:
5386 softc->
dsreg = MTIO_DSREG_TEN;
5388 softc->
dsreg = MTIO_DSREG_REST;
5413 softc->
dsreg = MTIO_DSREG_RBSY;
5416 softc->
dsreg = MTIO_DSREG_REST;
5423 if (error == EINVAL) {
5446 softc->
dsreg = (load)? MTIO_DSREG_LD : MTIO_DSREG_UNL;
5448 softc->
dsreg = MTIO_DSREG_REST;
5451 if (error || load == 0) {
5454 }
else if (error == 0) {
5478 softc->
dsreg = MTIO_DSREG_ZER;
5480 softc->
dsreg = MTIO_DSREG_REST;
5497#define SAFILLDENSSB(dens_data, sb, indent, field, desc_remain, \
5498 len_to_go, cur_offset, desc){ \
5499 size_t cur_field_len; \
5501 cur_field_len = sizeof(dens_data->field); \
5502 if (desc_remain < cur_field_len) { \
5503 len_to_go -= desc_remain; \
5504 cur_offset += desc_remain; \
5507 len_to_go -= cur_field_len; \
5508 cur_offset += cur_field_len; \
5509 desc_remain -= cur_field_len; \
5511 switch (sizeof(dens_data->field)) { \
5513 KASSERT(1 == 0, ("Programmer error, invalid 1 byte " \
5514 "field width for SAFILLDENSFIELD")); \
5517 SASBADDUINTDESC(sb, indent, \
5518 scsi_2btoul(dens_data->field), %u, field, desc); \
5521 SASBADDUINTDESC(sb, indent, \
5522 scsi_3btoul(dens_data->field), %u, field, desc); \
5525 SASBADDUINTDESC(sb, indent, \
5526 scsi_4btoul(dens_data->field), %u, field, desc); \
5529 SASBADDUINTDESC(sb, indent, \
5530 (uintmax_t)scsi_8btou64(dens_data->field), %ju, \
5541#define SAFILLDENSSBSTR(dens_data, sb, indent, field, desc_remain, \
5542 len_to_go, cur_offset, desc){ \
5543 size_t cur_field_len; \
5546 cur_field_len = sizeof(dens_data->field); \
5547 if (desc_remain < cur_field_len) { \
5548 len_to_go -= desc_remain; \
5549 cur_offset += desc_remain; \
5552 len_to_go -= cur_field_len; \
5553 cur_offset += cur_field_len; \
5554 desc_remain -= cur_field_len; \
5556 cam_strvis(tmpstr, dens_data->field, \
5557 sizeof(dens_data->field), sizeof(tmpstr)); \
5558 SASBADDVARSTRDESC(sb, indent, tmpstr, %s, field, \
5559 strlen(tmpstr) + 1, desc); \
5571 int len_to_go, cur_offset;
5573 int num_reports, need_close;
5579 if (buf_len <
sizeof(*hdr))
5584 len_to_go = min(buf_len -
sizeof(*hdr), hdr_len);
5592 cur_offset =
sizeof(*hdr);
5597 while (len_to_go > length_offset) {
5601 size_t cur_field_len;
5619 len_to_go -= length_offset;
5620 desc_remain = min(desc_remain, len_to_go);
5621 cur_offset += length_offset;
5623 if (need_close != 0) {
5634 primary_density_code,
"Primary Density Code");
5637 secondary_density_code,
"Secondary Density Code");
5643 desc_remain, len_to_go, cur_offset,
"Bits per mm");
5645 desc_remain, len_to_go, cur_offset,
"Media width");
5647 desc_remain, len_to_go, cur_offset,
5648 "Number of Tracks");
5650 desc_remain, len_to_go, cur_offset,
"Capacity");
5653 desc_remain, len_to_go, cur_offset,
5654 "Assigning Organization");
5657 desc_remain, len_to_go, cur_offset,
"Density Name");
5660 desc_remain, len_to_go, cur_offset,
"Description");
5673 if (desc_remain < cur_field_len) {
5674 len_to_go -= desc_remain;
5675 cur_offset += desc_remain;
5678 len_to_go -= cur_field_len;
5679 cur_offset += cur_field_len;
5680 desc_remain -= cur_field_len;
5690 density_code,
"Density Code");
5695 desc_remain, len_to_go, cur_offset,
5698 desc_remain, len_to_go, cur_offset,
5704 cur_field_len =
sizeof(type_data->
reserved2);
5705 if (desc_remain < cur_field_len) {
5706 len_to_go -= desc_remain;
5707 cur_offset += desc_remain;
5710 len_to_go -= cur_field_len;
5711 cur_offset += cur_field_len;
5712 desc_remain -= cur_field_len;
5715 desc_remain, len_to_go, cur_offset,
5716 "Assigning Organization");
5719 cur_offset,
"Medium type name");
5721 desc_remain, len_to_go, cur_offset,
"Description");
5724 if (need_close != 0) {
5742 "Current Medium Density");
5759 "Medium type report");
5783 uint32_t valid_len, avail_len = 0, used_len = 0;
5791 if (valid_len <
sizeof(*hdr))
5795 if ((avail_len != 0)
5796 && (avail_len > valid_len)) {
5798 "descriptor len %zu > valid len %u\n", avail_len,valid_len);
5801 used_len =
sizeof(hdr->
length);
5802 avail_len = MIN(avail_len, valid_len -
sizeof(*hdr));
5804 while ((avail_len - used_len) >
sizeof(*desc)) {
5810 cur_ptr = &buf[used_len];
5813 used_len +=
sizeof(*desc);
5822 if ((avail_len - used_len) <
sizeof(*td)) {
5823 used_len = avail_len;
5827 cur_ptr = &buf[used_len];
5830 td_len +=
sizeof(td->
length);
5833 if (td_len <
sizeof(*td))
5936 u_int8_t tag_action,
5938 u_int8_t sense_len, u_int32_t timeout)
5943 (u_int8_t *)rlimit_buf,
sizeof(*rlimit_buf), sense_len,
5944 sizeof(*scsi_cmd), timeout);
5947 bzero(scsi_cmd,
sizeof(*scsi_cmd));
5954 u_int8_t tag_action,
int readop,
int sli,
5955 int fixed, u_int32_t length, u_int8_t *data_ptr,
5956 u_int32_t dxfer_len, u_int8_t sense_len, u_int32_t timeout)
5975 tag_action, data_ptr, dxfer_len, sense_len,
5976 sizeof(*scsi_cmd), timeout);
5982 u_int8_t tag_action,
int immediate,
int eot,
5983 int reten,
int load, u_int8_t sense_len,
5989 bzero(scsi_cmd,
sizeof(*scsi_cmd));
6001 NULL, 0, sense_len,
sizeof(*scsi_cmd), timeout);
6007 u_int8_t tag_action,
int immediate, u_int8_t sense_len,
6013 bzero(scsi_cmd,
sizeof(*scsi_cmd));
6019 0, sense_len,
sizeof(*scsi_cmd), timeout);
6026 u_int32_t count, u_int8_t sense_len, u_int32_t timeout)
6037 0, sense_len,
sizeof(*scsi_cmd), timeout);
6043 u_int8_t tag_action,
int immediate,
int setmark,
6044 u_int32_t num_marks, u_int8_t sense_len,
6050 bzero(scsi_cmd,
sizeof(*scsi_cmd));
6060 0, sense_len,
sizeof(*scsi_cmd), timeout);
6069 u_int8_t tag_action,
int third_party,
6070 int third_party_id, u_int8_t sense_len,
6071 u_int32_t timeout,
int reserve)
6076 bzero(scsi_cmd,
sizeof(*scsi_cmd));
6090 0, sense_len,
sizeof(*scsi_cmd), timeout);
6096 u_int8_t tag_action,
int immediate,
int long_erase,
6097 u_int8_t sense_len, u_int32_t timeout)
6102 bzero(scsi_cmd,
sizeof(*scsi_cmd));
6113 0, sense_len,
sizeof(*scsi_cmd), timeout);
6122 u_int8_t tag_action,
int hardsoft,
6124 u_int8_t sense_len, u_int32_t timeout)
6129 (u_int8_t *)sbp,
sizeof (*sbp), sense_len,
sizeof(*scmd), timeout);
6131 bzero(scmd,
sizeof(*scmd));
6133 scmd->
byte1 = hardsoft;
6142 u_int8_t tag_action,
int service_action,
6143 u_int8_t *data_ptr, u_int32_t
length,
6144 u_int32_t sense_len, u_int32_t timeout)
6160 bzero(scmd,
sizeof(*scmd));
6162 scmd->
byte1 = service_action;
6177 u_int8_t tag_action,
int hardsoft, u_int32_t blkno,
6178 u_int8_t sense_len, u_int32_t timeout)
6183 (u_int8_t *)NULL, 0, sense_len,
sizeof(*scmd), timeout);
6185 bzero(scmd,
sizeof(*scmd));
6198 u_int8_t tag_action,
int immed,
int cp,
int hard,
6199 int64_t
partition, u_int32_t block_address,
6200 int sense_len, u_int32_t timeout)
6215 bzero(scmd,
sizeof(*scmd));
6230 u_int8_t tag_action,
int immed,
int cp, u_int8_t dest_type,
6231 int bam, int64_t
partition, u_int64_t logical_id,
6232 int sense_len, u_int32_t timeout)
6249 bzero(scsi_cmd,
sizeof(*scsi_cmd));
6257 scsi_cmd->
byte2 |= bam;
6265 u_int8_t tag_action,
int media,
int medium_type,
6266 u_int8_t *data_ptr, u_int32_t length,
6267 u_int32_t sense_len, u_int32_t timeout)
6272 bzero(scsi_cmd,
sizeof(*scsi_cmd));
6277 if (medium_type != 0)
6297 u_int8_t tag_action,
int byte1, u_int32_t proportion,
6298 u_int32_t sense_len, u_int32_t timeout)
6303 bzero(scsi_cmd,
sizeof(*scsi_cmd));
6325 u_int8_t tag_action,
int byte1,
int byte2,
6326 u_int8_t *data_ptr, u_int32_t dxfer_len,
6327 u_int32_t sense_len, u_int32_t timeout)
6332 bzero(scsi_cmd,
sizeof(*scsi_cmd));
6356 u_int8_t tag_action,
int allow_overwrite,
int partition,
6357 u_int64_t logical_id, u_int32_t sense_len, u_int32_t timeout)
6362 bzero(scsi_cmd,
sizeof(*scsi_cmd));
caddr_t cam_quirkmatch(caddr_t target, caddr_t quirk_table, int num_entries, int entry_size, cam_quirkmatch_t *comp_func)
void cam_strvis(u_int8_t *dst, const u_int8_t *src, int srclen, int dstlen)
#define CAM_PRIORITY_NORMAL
#define CDAI_TYPE_EXT_INQ
static __BEGIN_DECLS __inline void cam_fill_csio(struct ccb_scsiio *csio, u_int32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), u_int32_t flags, u_int8_t tag_action, u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len, u_int8_t cdb_len, u_int32_t timeout)
#define XPORT_DEVSTAT_TYPE(t)
#define CAM_DEBUG(path, flag, printfargs)
#define CAM_DEBUGGED(path, flag)
void cam_periph_release_locked(struct cam_periph *periph)
u_int32_t cam_release_devq(struct cam_path *path, u_int32_t relsim_flags, u_int32_t openings, u_int32_t arg, int getcount_only)
int cam_periph_acquire(struct cam_periph *periph)
void cam_periph_async(struct cam_periph *periph, u_int32_t code, struct cam_path *path, void *arg)
void cam_periph_release(struct cam_periph *periph)
void cam_periph_unhold(struct cam_periph *periph)
int cam_periph_hold(struct cam_periph *periph, int priority)
int cam_periph_runccb(union ccb *ccb, int(*error_routine)(union ccb *ccb, cam_flags camflags, u_int32_t sense_flags), cam_flags camflags, u_int32_t sense_flags, struct devstat *ds)
int cam_periph_error(union ccb *ccb, cam_flags camflags, u_int32_t sense_flags)
int cam_periph_ioctl(struct cam_periph *periph, u_long cmd, caddr_t addr, int(*error_routine)(union ccb *ccb, cam_flags camflags, u_int32_t sense_flags))
cam_status cam_periph_alloc(periph_ctor_t *periph_ctor, periph_oninv_t *periph_oninvalidate, periph_dtor_t *periph_dtor, periph_start_t *periph_start, char *name, cam_periph_type type, struct cam_path *path, ac_callback_t *ac_callback, ac_code code, void *arg)
cam_status periph_ctor_t(struct cam_periph *periph, void *arg)
#define CAM_PERIPH_INVALID
void periph_oninv_t(struct cam_periph *periph)
#define cam_periph_lock(periph)
union ccb * cam_periph_getccb(struct cam_periph *periph, u_int32_t priority)
#define cam_periph_unlock(periph)
static __inline struct mtx * cam_periph_mtx(struct cam_periph *periph)
#define CAM_PERIPH_LOCKED
void periph_dtor_t(struct cam_periph *periph)
void periph_start_t(struct cam_periph *periph, union ccb *start_ccb)
void() periph_init_t(void)
void xpt_print_path(struct cam_path *path)
void xpt_schedule(struct cam_periph *periph, u_int32_t new_priority)
void xpt_print(struct cam_path *path, const char *fmt,...)
void xpt_announce_periph(struct cam_periph *periph, char *announce_string)
void xpt_setup_ccb(struct ccb_hdr *ccb_h, struct cam_path *path, u_int32_t priority)
void xpt_action(union ccb *start_ccb)
cam_status xpt_register_async(int event, ac_callback_t *cbfunc, void *cbarg, struct cam_path *path)
struct cam_periph * xpt_path_periph(struct cam_path *path)
void xpt_release_ccb(union ccb *free_ccb)
void xpt_announce_quirks(struct cam_periph *periph, int quirks, char *bit_string)
static void xpt_path_inq(struct ccb_pathinq *cpi, struct cam_path *path)
void scsi_mode_sense(struct ccb_scsiio *csio, uint32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), uint8_t tag_action, int dbd, uint8_t pc, uint8_t page, uint8_t *param_buf, uint32_t param_len, uint8_t sense_len, uint32_t timeout)
void scsi_report_supported_opcodes(struct ccb_scsiio *csio, uint32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), uint8_t tag_action, int options, int req_opcode, int req_service_action, uint8_t *data_ptr, uint32_t dxfer_len, int sense_len, int timeout)
void scsi_mode_select_len(struct ccb_scsiio *csio, u_int32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), u_int8_t tag_action, int scsi_page_fmt, int save_pages, u_int8_t *param_buf, u_int32_t param_len, int minimum_cmd_size, u_int8_t sense_len, u_int32_t timeout)
void scsi_sense_print(struct ccb_scsiio *csio)
void scsi_mode_select(struct ccb_scsiio *csio, u_int32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), u_int8_t tag_action, int scsi_page_fmt, int save_pages, u_int8_t *param_buf, u_int32_t param_len, u_int8_t sense_len, u_int32_t timeout)
void scsi_prevent(struct ccb_scsiio *csio, u_int32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), u_int8_t tag_action, u_int8_t action, u_int8_t sense_len, u_int32_t timeout)
int scsi_inquiry_match(caddr_t inqbuffer, caddr_t table_entry)
void scsi_extract_sense_len(struct scsi_sense_data *sense_data, u_int sense_len, int *error_code, int *sense_key, int *asc, int *ascq, int show_errors)
void scsi_mode_sense_len(struct ccb_scsiio *csio, uint32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), uint8_t tag_action, int dbd, uint8_t pc, uint8_t page, uint8_t *param_buf, uint32_t param_len, int minimum_cmd_size, uint8_t sense_len, uint32_t timeout)
int scsi_get_sense_info(struct scsi_sense_data *sense_data, u_int sense_len, uint8_t info_type, uint64_t *info, int64_t *signed_info)
void scsi_test_unit_ready(struct ccb_scsiio *csio, u_int32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), u_int8_t tag_action, u_int8_t sense_len, u_int32_t timeout)
int scsi_get_stream_info(struct scsi_sense_data *sense_data, u_int sense_len, struct scsi_inquiry_data *inq_data, uint8_t *stream_bits)
#define SSD_KEY_BLANK_CHECK
static __inline uint32_t scsi_3btoul(const uint8_t *bytes)
static __inline uint64_t scsi_8btou64(const uint8_t *bytes)
static __inline uint32_t scsi_2btoul(const uint8_t *bytes)
#define SIP_MEDIA_REMOVABLE
#define SMS_PAGE_CTRL_CHANGEABLE
#define SVPD_EID_SA_SPT_LBP
static __inline void scsi_ulto2b(u_int32_t val, u_int8_t *bytes)
static __inline uint32_t scsi_4btoul(const uint8_t *bytes)
#define SSD_KEY_VOLUME_OVERFLOW
#define SID_QUAL_LU_CONNECTED
#define SMS_PAGE_CTRL_CURRENT
#define SCSI_DEFAULT_DENSITY
#define SMS_CONTROL_MODE_PAGE
#define SMS_VENDOR_SPECIFIC_PAGE
static __inline void scsi_ulto4b(u_int32_t val, u_int8_t *bytes)
static __inline void scsi_u64to8b(u_int64_t val, u_int8_t *bytes)
#define SID_TYPE(inq_data)
#define SID_ANSI_REV(inq_data)
#define SID_QUAL(inq_data)
static __inline void scsi_ulto3b(u_int32_t val, u_int8_t *bytes)
#define SCSI_SAME_DENSITY
void scsi_read_position(struct ccb_scsiio *csio, u_int32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), u_int8_t tag_action, int hardsoft, struct scsi_tape_position_data *sbp, u_int8_t sense_len, u_int32_t timeout)
static int saerase(struct cam_periph *periph, int longerase)
static MALLOC_DEFINE(M_SCSISA, "SCSI sa", "SCSI sequential access buffers")
static int sasetparams(struct cam_periph *periph, sa_params params_to_set, u_int32_t blocksize, u_int8_t density, u_int32_t comp_algorithm, u_int32_t sense_flags)
static struct sa_quirk_entry sa_quirk_table[]
static void saloadtotunables(struct sa_softc *softc)
static int sacheckeod(struct cam_periph *periph)
static d_strategy_t sastrategy
#define SASBADDVARSTRDESC(sb, indent, data, fmt, name, maxlen, desc)
void scsi_allow_overwrite(struct ccb_scsiio *csio, u_int32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), u_int8_t tag_action, int allow_overwrite, int partition, u_int64_t logical_id, u_int32_t sense_len, u_int32_t timeout)
static int saparamget(struct sa_softc *softc, struct sbuf *sb)
static int sawritefilemarks(struct cam_periph *periph, int nmarks, int setmarks, int immed)
static SYSCTL_NODE(_kern_cam, OID_AUTO, sa, CTLFLAG_RD|CTLFLAG_MPSAFE, 0, "CAM Sequential Access Tape Driver")
#define SASBENDNODE(sb, indent, name)
static int sasetpos(struct cam_periph *periph, int, struct mtlocate *)
static void safilldenstypesb(struct sbuf *sb, int *indent, uint8_t *buf, int buf_len, int is_density)
struct sa_param_ent sa_param_table[]
static int sasetprotents(struct cam_periph *periph, struct mtparamset *ps, int num_params)
void scsi_read_block_limits(struct ccb_scsiio *csio, u_int32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), u_int8_t tag_action, struct scsi_read_block_limits_data *rlimit_buf, u_int8_t sense_len, u_int32_t timeout)
void scsi_space(struct ccb_scsiio *csio, u_int32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), u_int8_t tag_action, scsi_space_code code, u_int32_t count, u_int8_t sense_len, u_int32_t timeout)
static int saretension(struct cam_periph *periph)
#define REP_DENSITY_TIMEOUT
#define UNUSED_PARAMETER(x)
void scsi_rewind(struct ccb_scsiio *csio, u_int32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), u_int8_t tag_action, int immediate, u_int8_t sense_len, u_int32_t timeout)
static void saasync(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg)
@ SA_TIMEOUT_READ_BLOCK_LIMITS
@ SA_TIMEOUT_READ_POSITION
@ SA_TIMEOUT_WRITE_FILEMARKS
#define SAFILLDENSSBSTR(dens_data, sb, indent, field, desc_remain, len_to_go, cur_offset, desc)
static void saloadtimeouts(struct sa_softc *softc, union ccb *ccb)
static periph_init_t sainit
static int sa_allow_io_split
static int sarewind(struct cam_periph *periph)
static void sadone(struct cam_periph *periph, union ccb *start_ccb)
void scsi_read_position_10(struct ccb_scsiio *csio, u_int32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), u_int8_t tag_action, int service_action, u_int8_t *data_ptr, u_int32_t length, u_int32_t sense_len, u_int32_t timeout)
#define SASBADDNODENUM(sb, indent, name, num)
static int sasetsili(struct cam_periph *periph, struct mtparamset *ps, int num_params)
#define SAMINOR(ctl, access)
#define SA_DEFAULT_IO_SPLIT
void scsi_write_filemarks(struct ccb_scsiio *csio, u_int32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), u_int8_t tag_action, int immediate, int setmark, u_int32_t num_marks, u_int8_t sense_len, u_int32_t timeout)
static int saextget(struct cdev *dev, struct cam_periph *periph, struct sbuf *sb, struct mtextget *g)
SYSCTL_INT(_kern_cam_sa, OID_AUTO, allow_io_split, CTLFLAG_RDTUN, &sa_allow_io_split, 0, "Default I/O split value")
void scsi_locate_16(struct ccb_scsiio *csio, u_int32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), u_int8_t tag_action, int immed, int cp, u_int8_t dest_type, int bam, int64_t partition, u_int64_t logical_id, int sense_len, u_int32_t timeout)
void scsi_set_capacity(struct ccb_scsiio *csio, u_int32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), u_int8_t tag_action, int byte1, u_int32_t proportion, u_int32_t sense_len, u_int32_t timeout)
void scsi_set_position(struct ccb_scsiio *csio, u_int32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), u_int8_t tag_action, int hardsoft, u_int32_t blkno, u_int8_t sense_len, u_int32_t timeout)
static int sagetparams_common(struct cdev *dev, struct cam_periph *periph)
void scsi_load_unload(struct ccb_scsiio *csio, u_int32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), u_int8_t tag_action, int immediate, int eot, int reten, int load, u_int8_t sense_len, u_int32_t timeout)
void scsi_report_density_support(struct ccb_scsiio *csio, u_int32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), u_int8_t tag_action, int media, int medium_type, u_int8_t *data_ptr, u_int32_t length, u_int32_t sense_len, u_int32_t timeout)
static int sasetprot(struct cam_periph *periph, struct sa_prot_state *new_prot)
struct sa_prot_map sa_prot_table[]
#define PENDING_MOUNT_CHECK(softc, periph, dev)
static struct sa_prot_map * safindprotent(char *name, struct sa_prot_map *table, int table_ents)
static int sagetparams(struct cam_periph *periph, sa_params params_to_get, u_int32_t *blocksize, u_int8_t *density, u_int32_t *numblocks, int *buff_mode, u_int8_t *write_protect, u_int8_t *speed, int *comp_supported, int *comp_enabled, u_int32_t *comp_algorithm, sa_comp_t *comp_page, struct scsi_control_data_prot_subpage *prot_page, int dp_size, int prot_changeable)
void scsi_format_medium(struct ccb_scsiio *csio, u_int32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), u_int8_t tag_action, int byte1, int byte2, u_int8_t *data_ptr, u_int32_t dxfer_len, u_int32_t sense_len, u_int32_t timeout)
static struct sa_timeout_desc sa_default_timeouts[SA_TIMEOUT_TYPE_MAX]
#define SASBADDUINTDESC(sb, indent, data, fmt, name, desc)
void scsi_reserve_release_unit(struct ccb_scsiio *csio, u_int32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), u_int8_t tag_action, int third_party, int third_party_id, u_int8_t sense_len, u_int32_t timeout, int reserve)
#define SASBADDVARSTR(sb, indent, data, fmt, name, maxlen)
static void sasetupdev(struct sa_softc *softc, struct cdev *dev)
static int sardpos(struct cam_periph *periph, int, u_int32_t *)
static void safilldensitysb(struct sa_softc *softc, int *indent, struct sbuf *sb)
static periph_oninv_t saoninvalidate
static int saseteotwarn(struct cam_periph *periph, struct mtparamset *ps, int num_params)
static struct sa_param_ent * safindparament(struct mtparamset *ps)
static void sadevgonecb(void *arg)
static void safillprot(struct sa_softc *softc, int *indent, struct sbuf *sb)
static void saprevent(struct cam_periph *periph, int action)
static int saparamsetlist(struct cam_periph *periph, struct mtsetlist *list, int need_copy)
PERIPHDRIVER_DECLARE(sa, sadriver)
#define SASBADDUINT(sb, indent, data, fmt, name)
static int sagetpos(struct cam_periph *periph)
static void sasysctlinit(void *context, int pending)
static int saloadunload(struct cam_periph *periph, int load)
void scsi_erase(struct ccb_scsiio *csio, u_int32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), u_int8_t tag_action, int immediate, int long_erase, u_int8_t sense_len, u_int32_t timeout)
static periph_ctor_t saregister
static void sapopulateprots(struct sa_prot_state *cur_state, struct sa_prot_map *new_table, int table_ents)
void scsi_locate_10(struct ccb_scsiio *csio, u_int32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), u_int8_t tag_action, int immed, int cp, int hard, int64_t partition, u_int32_t block_address, int sense_len, u_int32_t timeout)
#define SASBADDNODE(sb, indent, name)
#define SA_POSITION_UPDATED
static periph_start_t sastart
static struct cdevsw sa_cdevsw
static int saspace(struct cam_periph *periph, int count, scsi_space_code code)
void scsi_sa_read_write(struct ccb_scsiio *csio, u_int32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), u_int8_t tag_action, int readop, int sli, int fixed, u_int32_t length, u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len, u_int32_t timeout)
#define SASBADDINTDESC(sb, indent, data, fmt, name, desc)
#define SA_QUIRK_BIT_STRING
static int samount(struct cam_periph *, int, struct cdev *)
static periph_dtor_t sacleanup
#define SAFILLDENSSB(dens_data, sb, indent, field, desc_remain, len_to_go, cur_offset, desc)
static struct periph_driver sadriver
static int sareservereleaseunit(struct cam_periph *periph, int reserve)
static int saerror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags)
static int samarkswanted(struct cam_periph *)
#define READ_BLOCK_LIMITS
#define SMH_SA_BUF_MODE_SIBUF
#define SCSI_DENSITY_HALFINCH_PE
#define SCSI_DENSITY_QIC_24
#define SCSI_DENSITY_HALFINCH_800
#define SCSI_DENSITY_QIC_3080
#define SA_CTRL_DP_PI_LENGTH_MASK
#define SCSI_DENSITY_QIC_2GB
#define SCSI_DENSITY_QIC_525_320
#define SMH_SA_BUF_MODE_NOBUF
#define SMH_SA_BUF_MODE_MASK
#define SA_RPOS_LONG_FORM
#define SCSI_DENSITY_QIC_120
#define SCSI_DENSITY_HALFINCH_1600
#define SA_LC_DEST_TYPE_SHIFT
#define SCSI_DENSITY_QIC_150
#define SCSI_DENSITY_QIC_4GB
#define SA_DATA_COMPRESSION_PAGE
#define SCSI_DENSITY_QIC_11_4TRK
#define SA_RPOS_UNCERTAIN
#define SCSI_DENSITY_HALFINCH_6250
#define SA_RPOS_LONG_LONU
#define SCSI_DENSITY_HALFINCH_6250C
#define SDD_DEFAULT_LENGTH
#define SMH_SA_SPEED_MASK
#define SCSI_DENSITY_QIC_11_9TRK
#define SCSI_DENSITY_QIC_1320
#define SA_DEVICE_CONFIGURATION_PAGE
#define REPORT_DENSITY_SUPPORT
#define SA_RPOS_EXTENDED_FORM
#define SA_RPOS_LONG_BPEW
#define SA_CTRL_DP_SUBPAGE_CODE
struct scsi_inquiry_data inq_data
struct scsi_sense_data sense_data
int(* set_func)(struct cam_periph *periph, struct mtparamset *ps, int num_params)
struct sa_prot_state pending_prot_state
struct sa_prot_state cur_prot_state
mt_param_set_type param_type
struct scsi_inquiry_pattern inq_pat
struct scsi_sense_data _last_ctl_sense
struct sa_softc::@25 errinfo
u_int32_t saved_comp_algorithm
uint8_t density_info[SA_DENSITY_TYPES][SRDS_MAX_LENGTH]
struct sysctl_oid * sysctl_tree
struct cam_periph * periph
struct sa_prot_info prot_info
u_int64_t _last_ctl_resid
int timeout_info[SA_TIMEOUT_TYPE_MAX]
u_int8_t _last_ctl_cdb[CAM_MAX_CDBLEN]
u_int32_t open_pending_mount
struct sysctl_oid * sysctl_timeout_tree
uint8_t density_type_bits[SA_DENSITY_TYPES]
struct sysctl_ctx_list sysctl_ctx
struct sysctl_ctx_list sysctl_timeout_ctx
u_int8_t _last_io_cdb[CAM_MAX_CDBLEN]
struct devstat * device_stats
u_int32_t last_media_blksize
int density_info_valid[SA_DENSITY_TYPES]
struct bio_queue_head bio_queue
struct scsi_sense_data _last_io_sense
u_int8_t comp_algorithm[4]
u_int8_t decomp_algorithm[4]
u_int8_t primary_density_code
u_int8_t secondary_density_code
char vendor[SID_VENDOR_SIZE]
char product[SID_PRODUCT_SIZE]
char revision[SID_REVISION_SIZE]
u_int8_t medium_length[2]
u_int8_t medium_type_name[8]
u_int8_t assigning_org[8]
u_int8_t num_density_codes
u_int8_t primary_density_codes[9]
uint8_t recommended_time[4]
u_int8_t cap_proportion[2]
u_int8_t logical_file_num[8]
u_int8_t logical_object_num[8]
u_int8_t cdb_bytes[IOCDBLEN]
struct sa_comp_t::@26 hdr
struct scsi_dev_conf_page dconf
struct scsi_data_compression_page dcomp