74#include <sys/kernel.h>
76#include <sys/malloc.h>
81#include <sys/devicestat.h>
126#define CH_Q_BIT_STRING \
131#define ccb_state ppriv_field0
132#define ccb_bp ppriv_ptr1
186static void chasync(
void *callback_arg, u_int32_t code,
189 union ccb *done_ccb);
191 u_int32_t sense_flags);
193 struct changer_move *cm);
195 struct changer_exchange *ce);
197 struct changer_position *cp);
199 int scsi_version, u_long cmd,
200 struct changer_element_status_request *csr);
202 struct changer_set_voltag_request *csvr);
204 unsigned int timeout);
211 TAILQ_HEAD_INITIALIZER(
chdriver.units), 0
217 .d_version = D_VERSION,
218 .d_flags = D_TRACKCLOSE,
239 printf(
"ch: Failed to attach master async callback "
240 "due to status 0x%x!\n", status);
257 KASSERT(softc->
open_count >= 0, (
"Negative open count %d",
315 free(softc, M_DEVBUF);
354 printf(
"chasync: Unable to probe new device "
355 "due to status 0x%x\n", status);
371 struct make_dev_args args;
376 printf(
"chregister: no getdev CCB, can't register device\n");
380 softc = (
struct ch_softc *)malloc(
sizeof(*softc),M_DEVBUF,M_NOWAIT);
383 printf(
"chregister: Unable to probe new device. "
384 "Unable to allocate softc\n");
388 bzero(softc,
sizeof(*softc));
390 periph->
softc = softc;
410 DEVSTAT_NO_BLOCKSIZE | DEVSTAT_NO_ORDERED_TAGS,
413 DEVSTAT_PRIORITY_OTHER);
422 "registration!\n", __func__);
428 make_dev_args_init(&args);
431 args.mda_uid = UID_ROOT;
432 args.mda_gid = GID_OPERATOR;
433 args.mda_mode = 0600;
434 args.mda_si_drv1 = periph;
435 error = make_dev_s(&args, &softc->
dev,
"%s%d", periph->
periph_name,
506chclose(
struct cdev *
dev,
int flag,
int fmt,
struct thread *td)
545 switch (softc->
state) {
564 mode_buffer = malloc(mode_buffer_len, M_SCSICH, M_NOWAIT);
566 if (mode_buffer == NULL) {
567 printf(
"chstart: couldn't malloc mode sense data\n");
570 bzero(mode_buffer, mode_buffer_len);
583 (u_int8_t *)mode_buffer,
588 start_ccb->
ccb_h.ccb_bp = NULL;
603 csio = &done_ccb->
csio;
605 switch(done_ccb->
ccb_h.ccb_state) {
610 char announce_buf[80];
629#define PLURAL(c) (c) == 1 ? "" : "s"
630 snprintf(announce_buf,
sizeof(announce_buf),
631 "%d slot%s, %d drive%s, "
632 "%d picker%s, %d portal%s",
642 if (announce_buf[0] !=
'\0') {
656 if (error == ERESTART) {
662 }
else if (error != 0) {
664 int frozen, retry_scheduled;
682 sms->
byte2 &= ~SMS_DBD;
705 "got CAM status %#x\n",
709 "to attach to device\n");
715 free(mode_header, M_SCSICH);
742chioctl(
struct cdev *dev, u_long cmd, caddr_t addr,
int flag,
struct thread *td)
757 (
"trying to do ioctl %#lx\n", cmd));
771 if ((flag & FWRITE) == 0) {
779 error =
chmove(periph, (
struct changer_move *)addr);
783 error =
chexchange(periph, (
struct changer_exchange *)addr);
787 error =
chposition(periph, (
struct changer_position *)addr);
796 int new_picker = *(
int *)addr;
798 if (new_picker > (softc->
sc_counts[CHET_MT] - 1)) {
807 struct changer_params *cp = (
struct changer_params *)addr;
809 cp->cp_npickers = softc->
sc_counts[CHET_MT];
810 cp->cp_nslots = softc->
sc_counts[CHET_ST];
811 cp->cp_nportals = softc->
sc_counts[CHET_IE];
812 cp->cp_ndrives = softc->
sc_counts[CHET_DT];
816 error =
chielem(periph, *(
unsigned int *)addr);
822 (
struct changer_element_status_request *)addr);
833 (
struct changer_element_status_request *)addr);
845 (
struct changer_set_voltag_request *) addr);
864 u_int16_t fromelem, toelem;
874 if ((cm->cm_fromtype > CHET_DT) || (cm->cm_totype > CHET_DT))
876 if ((cm->cm_fromunit > (softc->
sc_counts[cm->cm_fromtype] - 1)) ||
877 (cm->cm_tounit > (softc->
sc_counts[cm->cm_totype] - 1)))
883 if ((softc->
sc_movemask[cm->cm_fromtype] & (1 << cm->cm_totype)) == 0)
889 fromelem = softc->
sc_firsts[cm->cm_fromtype] + cm->cm_fromunit;
890 toelem = softc->
sc_firsts[cm->cm_totype] + cm->cm_tounit;
901 (cm->cm_flags & CM_INVERT) ? TRUE : FALSE,
918 u_int16_t src, dst1, dst2;
927 if ((ce->ce_srctype > CHET_DT) || (ce->ce_fdsttype > CHET_DT) ||
928 (ce->ce_sdsttype > CHET_DT))
930 if ((ce->ce_srcunit > (softc->
sc_counts[ce->ce_srctype] - 1)) ||
931 (ce->ce_fdstunit > (softc->
sc_counts[ce->ce_fdsttype] - 1)) ||
932 (ce->ce_sdstunit > (softc->
sc_counts[ce->ce_sdsttype] - 1)))
939 (1 << ce->ce_fdsttype)) == 0) ||
941 (1 << ce->ce_sdsttype)) == 0))
947 src = softc->
sc_firsts[ce->ce_srctype] + ce->ce_srcunit;
948 dst1 = softc->
sc_firsts[ce->ce_fdsttype] + ce->ce_fdstunit;
949 dst2 = softc->
sc_firsts[ce->ce_sdsttype] + ce->ce_sdstunit;
961 (ce->ce_flags & CE_INVERT1) ?
963 (ce->ce_flags & CE_INVERT2) ?
991 if (cp->cp_type > CHET_DT)
993 if (cp->cp_unit > (softc->
sc_counts[cp->cp_type] - 1))
999 dst = softc->
sc_firsts[cp->cp_type] + cp->cp_unit;
1009 (cp->cp_flags & CP_INVERT) ?
1034 for (i=0; i<CH_VOLTAG_MAXLEN; i++) {
1035 char c = voltag->
vif[i];
1037 uvoltag->cv_volid[i] = c;
1052 struct changer_element_status *ces,
1057 struct volume_tag *pvol_tag = NULL, *avol_tag = NULL;
1060 ces->ces_int_addr = eaddr;
1062 for (et = CHET_MT; et <= CHET_DT; et++) {
1066 ces->ces_addr = eaddr - softc->
sc_firsts[et];
1072 ces->ces_flags = desc->
flags1;
1078 ces->ces_flags |= CES_INVERT;
1084 for (et = CHET_MT; et <= CHET_DT; et++) {
1088 ces->ces_source_addr =
1090 ces->ces_source_type = et;
1091 ces->ces_flags |= CES_SOURCE_VALID;
1096 if (!(ces->ces_flags & CES_SOURCE_VALID))
1097 printf(
"ch: warning: could not map element source "
1098 "address %ud to a valid element type\n",
1129 if (devid != NULL) {
1132 (
void *)ces->ces_designator,
1145 ces->ces_flags |= CES_PIV;
1146 ces->ces_protocol_id =
1158 ces->ces_designator_length = 0;
1159 ces->ces_designator[0] =
'\0';
1160 ces->ces_protocol_id = CES_PROTOCOL_ID_FCP_4;
1166 ces->ces_flags |= CES_SCSIID_VALID;
1173 ces->ces_flags |= CES_LUN_VALID;
1183 struct changer_element_status_request *cesr)
1188 caddr_t data = NULL;
1189 size_t size, desclen;
1191 int curdata, dvcid, sense_flags;
1192 int try_no_dvcid = 0;
1193 struct changer_element_status *user_data = NULL;
1196 int chet = cesr->cesr_element_type;
1198 int want_voltags = (cesr->cesr_flags & CESR_VOLTAGS) ? 1 : 0;
1208 if ((softc->
sc_counts[chet] - cesr->cesr_element_base) <= 0
1209 || (cesr->cesr_element_base + cesr->cesr_element_count)
1220 data = (caddr_t)malloc(1024, M_DEVBUF, M_WAITOK);
1266 if ((error == EINVAL)
1267 && (dvcid || curdata)) {
1272 sense_flags &= ~SF_QUIET_IR;
1285 if ((try_no_dvcid != 0)
1300 (desclen * cesr->cesr_element_count);
1305 free(data, M_DEVBUF);
1306 data = (caddr_t)malloc(size, M_DEVBUF, M_WAITOK);
1315 + cesr->cesr_element_base,
1318 cesr->cesr_element_count,
1340 if (avail != cesr->cesr_element_count) {
1342 "warning, READ ELEMENT STATUS avail != count\n");
1345 user_data = (
struct changer_element_status *)
1346 malloc(avail *
sizeof(
struct changer_element_status),
1347 M_DEVBUF, M_WAITOK | M_ZERO);
1355 for (i = 0; i < avail; ++i) {
1356 struct changer_element_status *ces;
1367 ces = cmd == OCHIOGSTATUS ?
1368 (
struct changer_element_status *)
1369 ((
unsigned char *)user_data + i *
1370 (offsetof(
struct changer_element_status,ces_scsi_lun)+1)):
1377 ((
unsigned char *)desc + desclen);
1381 if (cmd == OCHIOGSTATUS)
1382 error = copyout(user_data,
1383 cesr->cesr_element_status,
1384 avail* (offsetof(
struct changer_element_status,
1385 ces_scsi_lun) + 1));
1387 error = copyout(user_data,
1388 cesr->cesr_element_status,
1389 avail *
sizeof(
struct changer_element_status));
1397 free(data, M_DEVBUF);
1398 if (user_data != NULL)
1399 free(user_data, M_DEVBUF);
1406 unsigned int timeout)
1441 struct changer_set_voltag_request *csvr)
1454 bzero(&ssvtp,
sizeof(ssvtp));
1455 for (i=0; i<
sizeof(ssvtp.
vitf); i++) {
1456 ssvtp.
vitf[i] =
' ';
1462 if (csvr->csvr_type > CHET_DT)
1464 if (csvr->csvr_addr > (softc->
sc_counts[csvr->csvr_type] - 1))
1467 ea = softc->
sc_firsts[csvr->csvr_type] + csvr->csvr_addr;
1469 if (csvr->csvr_flags & CSVR_ALTERNATE) {
1470 switch (csvr->csvr_flags & CSVR_MODE_MASK) {
1474 case CSVR_MODE_REPLACE:
1477 case CSVR_MODE_CLEAR:
1485 switch (csvr->csvr_flags & CSVR_MODE_MASK) {
1489 case CSVR_MODE_REPLACE:
1492 case CSVR_MODE_CLEAR:
1501 memcpy(ssvtp.
vitf, csvr->csvr_voltag.cv_volid,
1502 min(strlen(csvr->csvr_voltag.cv_volid),
sizeof(ssvtp.
vitf)));
1533 int mode_buffer_len;
1536 int error, from, dbd;
1537 u_int8_t *moves, *exchanges;
1552 mode_buffer = malloc(mode_buffer_len, M_SCSICH, M_NOWAIT);
1554 if (mode_buffer == NULL) {
1555 printf(
"chgetparams: couldn't malloc mode sense data\n");
1560 bzero(mode_buffer, mode_buffer_len);
1577 (u_int8_t *)mode_buffer,
1608 "chgetparams: error getting element "
1611 free(mode_buffer, M_SCSICH);
1628 bzero(mode_buffer, mode_buffer_len);
1640 (u_int8_t *)mode_buffer,
1671 "chgetparams: error getting device "
1672 "capabilities page\n");
1674 free(mode_buffer, M_SCSICH);
1688 for (from = CHET_MT; from <= CHET_MAX; ++from) {
1693 free(mode_buffer, M_SCSICH);
1703 int dev_scsi_version;
1726 return dev_scsi_version;
1732 u_int8_t tag_action, u_int32_t tea, u_int32_t src,
1733 u_int32_t dst,
int invert, u_int8_t sense_len,
1739 bzero(scsi_cmd,
sizeof(*scsi_cmd));
1765 u_int8_t tag_action, u_int32_t
tea, u_int32_t
src,
1766 u_int32_t dst1, u_int32_t dst2,
int invert1,
1767 int invert2, u_int8_t sense_len, u_int32_t timeout)
1772 bzero(scsi_cmd,
sizeof(*scsi_cmd));
1802 u_int8_t tag_action, u_int32_t
tea, u_int32_t dst,
1803 int invert, u_int8_t sense_len, u_int32_t timeout)
1808 bzero(scsi_cmd,
sizeof(*scsi_cmd));
1833 u_int8_t tag_action,
int voltag, u_int32_t sea,
1834 int curdata,
int dvcid,
1835 u_int32_t count, u_int8_t *data_ptr,
1836 u_int32_t dxfer_len, u_int8_t sense_len,
1842 bzero(scsi_cmd,
sizeof(*scsi_cmd));
1872 u_int8_t tag_action, u_int8_t sense_len,
1879 bzero(scsi_cmd,
sizeof(*scsi_cmd));
1898 u_int8_t tag_action,
1899 u_int16_t element_address,
1900 u_int8_t send_action_code,
1902 u_int8_t sense_len, u_int32_t timeout)
1907 bzero(scsi_cmd,
sizeof(*scsi_cmd));
1911 scsi_cmd->
sac = send_action_code;
1919 (u_int8_t *) parameters,
1920 sizeof(*parameters),
#define CAM_PRIORITY_NORMAL
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)
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)
void cam_periph_invalidate(struct cam_periph *periph)
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_assert(periph, what)
#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)
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_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)
union ccb * xpt_alloc_ccb_nowait(void)
void xpt_release_ccb(union ccb *free_ccb)
void xpt_announce_quirks(struct cam_periph *periph, int quirks, char *bit_string)
void xpt_free_ccb(union ccb *free_ccb)
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_sense_print(struct ccb_scsiio *csio)
#define POSITION_TO_ELEMENT
static __inline uint32_t scsi_2btoul(const uint8_t *bytes)
static __inline void scsi_ulto2b(u_int32_t val, u_int8_t *bytes)
#define SID_QUAL_LU_CONNECTED
#define SMS_PAGE_CTRL_CURRENT
#define READ_ELEMENT_STATUS
#define SID_TYPE(inq_data)
static __inline void * find_mode_page_6(struct scsi_mode_header_6 *mode_header)
#define SID_QUAL(inq_data)
static __inline void scsi_ulto3b(u_int32_t val, u_int8_t *bytes)
static const u_int32_t CH_TIMEOUT_POSITION_TO_ELEMENT
static const u_int32_t CH_TIMEOUT_READ_ELEMENT_STATUS
static const u_int32_t CH_TIMEOUT_MOVE_MEDIUM
static int chsetvoltag(struct cam_periph *periph, struct changer_set_voltag_request *csvr)
static int cherror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags)
static periph_ctor_t chregister
static struct periph_driver chdriver
static int chexchange(struct cam_periph *periph, struct changer_exchange *ce)
static periph_dtor_t chcleanup
static int chielem(struct cam_periph *periph, unsigned int timeout)
static periph_start_t chstart
static periph_oninv_t choninvalidate
static const u_int32_t CH_TIMEOUT_MODE_SENSE
static void chdone(struct cam_periph *periph, union ccb *done_ccb)
static const u_int32_t CH_TIMEOUT_EXCHANGE_MEDIUM
static void copy_voltag(struct changer_voltag *uvoltag, struct volume_tag *voltag)
static void chasync(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg)
static void copy_element_status(struct ch_softc *softc, u_int16_t flags, struct read_element_status_descriptor *desc, struct changer_element_status *ces, int scsi_version)
void scsi_read_element_status(struct ccb_scsiio *csio, u_int32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), u_int8_t tag_action, int voltag, u_int32_t sea, int curdata, int dvcid, u_int32_t count, u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len, u_int32_t timeout)
static const u_int32_t CH_TIMEOUT_SEND_VOLTAG
void scsi_send_volume_tag(struct ccb_scsiio *csio, u_int32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), u_int8_t tag_action, u_int16_t element_address, u_int8_t send_action_code, struct scsi_send_volume_tag_parameters *parameters, u_int8_t sense_len, u_int32_t timeout)
void scsi_move_medium(struct ccb_scsiio *csio, u_int32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), u_int8_t tag_action, u_int32_t tea, u_int32_t src, u_int32_t dst, int invert, u_int8_t sense_len, u_int32_t timeout)
void scsi_position_to_element(struct ccb_scsiio *csio, u_int32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), u_int8_t tag_action, u_int32_t tea, u_int32_t dst, int invert, u_int8_t sense_len, u_int32_t timeout)
static int chposition(struct cam_periph *periph, struct changer_position *cp)
static periph_init_t chinit
void scsi_initialize_element_status(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)
static void chdevgonecb(void *arg)
void scsi_exchange_medium(struct ccb_scsiio *csio, u_int32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), u_int8_t tag_action, u_int32_t tea, u_int32_t src, u_int32_t dst1, u_int32_t dst2, int invert1, int invert2, u_int8_t sense_len, u_int32_t timeout)
PERIPHDRIVER_DECLARE(ch, chdriver)
static int chscsiversion(struct cam_periph *periph)
static MALLOC_DEFINE(M_SCSICH, "scsi_ch", "scsi_ch buffers")
static const u_int32_t CH_TIMEOUT_INITIALIZE_ELEMENT_STATUS
static int chgetelemstatus(struct cam_periph *periph, int scsi_version, u_long cmd, struct changer_element_status_request *csr)
static int chmove(struct cam_periph *periph, struct changer_move *cm)
static struct cdevsw ch_cdevsw
static int chgetparams(struct cam_periph *periph)
#define READ_ELEMENT_STATUS_DT_LUVALID
#define CH_DEVICE_CAP_PAGE
#define READ_ELEMENT_STATUS_DESIGNATOR_TYPE(p)
#define READ_ELEMENT_STATUS_PROTOCOL_ID(p)
#define READ_ELEMENT_STATUS_PIV_SET
#define READ_ELEMENT_STATUS_SVALID
#define READ_ELEMENT_STATUS_AVOLTAG
#define CH_ELEMENT_ADDR_ASSIGN_PAGE
#define READ_ELEMENT_STATUS_INVERT
#define READ_ELEMENT_STATUS_DT_LUNMASK
#define READ_ELEMENT_STATUS_CODE_SET(p)
#define READ_ELEMENT_STATUS_CURDATA
#define READ_ELEMENT_STATUS_DVCID
#define SEND_VOLUME_TAG_UNDEFINED_ALTERNATE
#define READ_ELEMENT_STATUS_DT_IDVALID
#define INITIALIZE_ELEMENT_STATUS
#define EXCHANGE_MEDIUM_INV2
#define SEND_VOLUME_TAG_UNDEFINED_PRIMARY
#define MOVE_MEDIUM_INVERT
#define EXCHANGE_MEDIUM_INV1
#define SEND_VOLUME_TAG_REPLACE_ALTERNATE
#define SEND_VOLUME_TAG_ASSERT_ALTERNATE
#define READ_ELEMENT_STATUS_VOLTAG
#define READ_ELEMENT_STATUS_PVOLTAG
#define READ_ELEMENT_STATUS_ASSOCIATION(p)
#define POSITION_TO_ELEMENT_INVERT
#define SEND_VOLUME_TAG_REPLACE_PRIMARY
#define SEND_VOLUME_TAG_ASSERT_PRIMARY
struct scsi_inquiry_data inq_data
int sc_counts[CHET_MAX+1]
u_int8_t sc_exchangemask[CHET_MAX+1]
u_int8_t sc_movemask[CHET_MAX+1]
int sc_firsts[CHET_MAX+1]
struct devstat * device_stats
u_int8_t move_from[CHET_MAX+1]
u_int8_t exchange_with[CHET_MAX+1]
union read_element_status_descriptor::@16 dt_or_obsolete
struct volume_tag pvoltag
struct volume_tag voltag[2]
struct read_element_status_descriptor::@16::@18 scsi_2
struct read_element_status_device_id devid
union read_element_status_descriptor::@17 voltag_devid
struct read_element_status_descriptor::@17::@19 pvol_and_devid
struct read_element_status_descriptor::@17::@20 vol_tags_and_devid
u_int8_t piv_assoc_designator_type
u_int8_t designator_length
struct page_device_capabilities cap
struct page_element_address_assignment ea
union scsi_mode_sense_data::@15 pages
struct scsi_mode_header_6 header
struct scsi_mode_blk_desc blk_desc
struct page_transport_geometry_parameters tg
u_int8_t cdb_bytes[IOCDBLEN]