diff options
-rw-r--r-- | bin/chio/chio.c | 70 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_ch.c | 203 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_ch.h | 97 | ||||
-rw-r--r-- | sys/sys/chio.h | 83 |
4 files changed, 379 insertions, 74 deletions
diff --git a/bin/chio/chio.c b/bin/chio/chio.c index 9bb11d7..5a2a7ba 100644 --- a/bin/chio/chio.c +++ b/bin/chio/chio.c @@ -54,6 +54,8 @@ __FBSDID("$FreeBSD$"); #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <langinfo.h> +#include <locale.h> #include "defs.h" #include "pathnames.h" @@ -81,6 +83,7 @@ static int do_status(const char *, int, char **); static int do_ielem(const char *, int, char **); static int do_return(const char *, int, char **); static int do_voltag(const char *, int, char **); +static void print_designator(const char *, u_int8_t, u_int8_t); #ifndef CHET_VT #define CHET_VT 10 /* Completely Arbitrary */ @@ -723,6 +726,10 @@ do_status(const char *cname, int argc, char **argv) putchar('?'); putchar('>'); } + if (ces->ces_designator_length > 0) + print_designator(ces->ces_designator, + ces->ces_code_set, + ces->ces_designator_length); putchar('\n'); } @@ -1177,3 +1184,66 @@ usage(void) "arg1 arg2 [arg3 [...]]\n", getprogname()); exit(1); } + +#define UTF8CODESET "UTF-8" + +static void +print_designator(const char *designator, u_int8_t code_set, + u_int8_t designator_length) +{ + printf(" serial number: <"); + switch (code_set) { + case CES_CODE_SET_ASCII: { + /* + * The driver insures that the string is always NUL terminated. + */ + printf("%s", designator); + break; + } + case CES_CODE_SET_UTF_8: { + char *cs_native; + + setlocale(LC_ALL, ""); + cs_native = nl_langinfo(CODESET); + + /* See if we can natively print UTF-8 */ + if (strcmp(cs_native, UTF8CODESET) == 0) + cs_native = NULL; + + if (cs_native == NULL) { + /* We can natively print UTF-8, so use printf. */ + printf("%s", designator); + } else { + int i; + + /* + * We can't natively print UTF-8. We should + * convert it to the terminal's codeset, but that + * requires iconv(3) and FreeBSD doesn't have + * iconv(3) in the base system yet. So we use %XX + * notation for non US-ASCII characters instead. + */ + for (i = 0; i < designator_length && + designator[i] != '\0'; i++) { + if ((unsigned char)designator[i] < 0x80) + printf("%c", designator[i]); + else + printf("%%%02x", + (unsigned char)designator[i]); + } + } + break; + } + case CES_CODE_SET_BINARY: { + int i; + + for (i = 0; i < designator_length; i++) + printf("%02X%s", designator[i], + (i == designator_length - 1) ? "" : " "); + break; + } + default: + break; + } + printf(">"); +} diff --git a/sys/cam/scsi/scsi_ch.c b/sys/cam/scsi/scsi_ch.c index 38dcd48..03dd5cd 100644 --- a/sys/cam/scsi/scsi_ch.c +++ b/sys/cam/scsi/scsi_ch.c @@ -194,12 +194,14 @@ static int chexchange(struct cam_periph *periph, static int chposition(struct cam_periph *periph, struct changer_position *cp); static int chgetelemstatus(struct cam_periph *periph, + int scsi_version, u_long cmd, struct changer_element_status_request *csr); static int chsetvoltag(struct cam_periph *periph, struct changer_set_voltag_request *csvr); static int chielem(struct cam_periph *periph, unsigned int timeout); static int chgetparams(struct cam_periph *periph); +static int chscsiversion(struct cam_periph *periph); static struct periph_driver chdriver = { @@ -474,6 +476,7 @@ chopen(struct cdev *dev, int flags, int fmt, struct thread *td) * Load information about this changer device into the softc. */ if ((error = chgetparams(periph)) != 0) { + cam_periph_unhold(periph); cam_periph_release_locked(periph); cam_periph_unlock(periph); return(error); @@ -772,6 +775,7 @@ chioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td) switch (cmd) { case CHIOGPICKER: case CHIOGPARAMS: + case OCHIOGSTATUS: case CHIOGSTATUS: break; @@ -824,10 +828,26 @@ chioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td) error = chielem(periph, *(unsigned int *)addr); break; + case OCHIOGSTATUS: + { + error = chgetelemstatus(periph, SCSI_REV_2, cmd, + (struct changer_element_status_request *)addr); + break; + } + case CHIOGSTATUS: { - error = chgetelemstatus(periph, - (struct changer_element_status_request *) addr); + int scsi_version; + + scsi_version = chscsiversion(periph); + if (scsi_version >= SCSI_REV_0) { + error = chgetelemstatus(periph, scsi_version, cmd, + (struct changer_element_status_request *)addr); + } + else { /* unable to determine the SCSI version */ + cam_periph_unlock(periph); + return (ENXIO); + } break; } @@ -1034,18 +1054,20 @@ copy_voltag(struct changer_voltag *uvoltag, struct volume_tag *voltag) } /* - * Copy an an element status descriptor to a user-mode + * Copy an element status descriptor to a user-mode * changer_element_status structure. */ - -static void +static void copy_element_status(struct ch_softc *softc, u_int16_t flags, struct read_element_status_descriptor *desc, - struct changer_element_status *ces) + struct changer_element_status *ces, + int scsi_version) { u_int16_t eaddr = scsi_2btoul(desc->eaddr); u_int16_t et; + struct volume_tag *pvol_tag = NULL, *avol_tag = NULL; + struct read_element_status_device_id *devid = NULL; ces->ces_int_addr = eaddr; /* set up logical address in element status */ @@ -1076,7 +1098,7 @@ copy_element_status(struct ch_softc *softc, if ((softc->sc_firsts[et] <= eaddr) && ((softc->sc_firsts[et] + softc->sc_counts[et]) > eaddr)) { - ces->ces_source_addr = + ces->ces_source_addr = eaddr - softc->sc_firsts[et]; ces->ces_source_type = et; ces->ces_flags |= CES_SOURCE_VALID; @@ -1089,27 +1111,92 @@ copy_element_status(struct ch_softc *softc, "address %ud to a valid element type\n", eaddr); } - + /* + * pvoltag and avoltag are common between SCSI-2 and later versions + */ if (flags & READ_ELEMENT_STATUS_PVOLTAG) - copy_voltag(&(ces->ces_pvoltag), &(desc->pvoltag)); + pvol_tag = &desc->voltag_devid.pvoltag; if (flags & READ_ELEMENT_STATUS_AVOLTAG) - copy_voltag(&(ces->ces_avoltag), &(desc->avoltag)); + avol_tag = (flags & READ_ELEMENT_STATUS_PVOLTAG) ? + &desc->voltag_devid.voltag[1] :&desc->voltag_devid.pvoltag; + /* + * For SCSI-3 and later, element status can carry designator and + * other information. + */ + if (scsi_version >= SCSI_REV_SPC) { + if ((flags & READ_ELEMENT_STATUS_PVOLTAG) ^ + (flags & READ_ELEMENT_STATUS_AVOLTAG)) + devid = &desc->voltag_devid.pvol_and_devid.devid; + else if (!(flags & READ_ELEMENT_STATUS_PVOLTAG) && + !(flags & READ_ELEMENT_STATUS_AVOLTAG)) + devid = &desc->voltag_devid.devid; + else /* Have both PVOLTAG and AVOLTAG */ + devid = &desc->voltag_devid.vol_tags_and_devid.devid; + } - if (desc->dt_scsi_flags & READ_ELEMENT_STATUS_DT_IDVALID) { - ces->ces_flags |= CES_SCSIID_VALID; - ces->ces_scsi_id = desc->dt_scsi_addr; + if (pvol_tag) + copy_voltag(&(ces->ces_pvoltag), pvol_tag); + if (avol_tag) + copy_voltag(&(ces->ces_pvoltag), avol_tag); + if (devid != NULL) { + if (devid->designator_length > 0) { + bcopy((void *)devid->designator, + (void *)ces->ces_designator, + devid->designator_length); + ces->ces_designator_length = devid->designator_length; + /* + * Make sure we are always NUL terminated. The + * buffer should be sized for the maximum + * designator length plus 1, but this will make sure + * there is always a NUL at the end. This won't + * matter for the binary code set, since the user + * will only pay attention to the length field. + */ + ces->ces_designator[ + MIN(sizeof(ces->ces_designator) - 1, + devid->designator_length)]= '\0'; + } + if (devid->piv_assoc_designator_type & + READ_ELEMENT_STATUS_PIV_SET) { + ces->ces_flags |= CES_PIV; + ces->ces_protocol_id = + READ_ELEMENT_STATUS_PROTOCOL_ID( + devid->prot_code_set); + } + ces->ces_code_set = + READ_ELEMENT_STATUS_CODE_SET(devid->prot_code_set); + ces->ces_assoc = READ_ELEMENT_STATUS_ASSOCIATION( + devid->piv_assoc_designator_type); + ces->ces_designator_type = READ_ELEMENT_STATUS_DESIGNATOR_TYPE( + devid->piv_assoc_designator_type); + } else if (scsi_version > SCSI_REV_2) { + /* SCSI-SPC and No devid, no designator */ + ces->ces_designator_length = 0; + ces->ces_designator[0] = '\0'; + ces->ces_protocol_id = CES_PROTOCOL_ID_FCP_4; } - if (desc->dt_scsi_addr & READ_ELEMENT_STATUS_DT_LUVALID) { - ces->ces_flags |= CES_LUN_VALID; - ces->ces_scsi_lun = - desc->dt_scsi_flags & READ_ELEMENT_STATUS_DT_LUNMASK; + if (scsi_version <= SCSI_REV_2) { + if (desc->dt_or_obsolete.scsi_2.dt_scsi_flags & + READ_ELEMENT_STATUS_DT_IDVALID) { + ces->ces_flags |= CES_SCSIID_VALID; + ces->ces_scsi_id = + desc->dt_or_obsolete.scsi_2.dt_scsi_addr; + } + + if (desc->dt_or_obsolete.scsi_2.dt_scsi_addr & + READ_ELEMENT_STATUS_DT_LUVALID) { + ces->ces_flags |= CES_LUN_VALID; + ces->ces_scsi_lun = + desc->dt_or_obsolete.scsi_2.dt_scsi_flags & + READ_ELEMENT_STATUS_DT_LUNMASK; + } } } static int -chgetelemstatus(struct cam_periph *periph, +chgetelemstatus(struct cam_periph *periph, int scsi_version, u_long cmd, struct changer_element_status_request *cesr) { struct read_element_status_header *st_hdr; @@ -1155,6 +1242,8 @@ chgetelemstatus(struct cam_periph *periph, /* tag_action */ MSG_SIMPLE_Q_TAG, /* voltag */ want_voltags, /* sea */ softc->sc_firsts[chet], + /* dvcid */ 1, + /* curdata */ 1, /* count */ 1, /* data_ptr */ data, /* dxfer_len */ 1024, @@ -1177,7 +1266,6 @@ chgetelemstatus(struct cam_periph *periph, size = sizeof(struct read_element_status_header) + sizeof(struct read_element_status_page_header) + (desclen * cesr->cesr_element_count); - /* * Reallocate storage for descriptors and get them from the * device. @@ -1193,12 +1281,14 @@ chgetelemstatus(struct cam_periph *periph, /* voltag */ want_voltags, /* sea */ softc->sc_firsts[chet] + cesr->cesr_element_base, + /* dvcid */ 1, + /* curdata */ 1, /* count */ cesr->cesr_element_count, /* data_ptr */ data, /* dxfer_len */ size, /* sense_len */ SSD_FULL_SIZE, /* timeout */ CH_TIMEOUT_READ_ELEMENT_STATUS); - + error = cam_periph_runccb(ccb, cherror, /*cam_flags*/ CAM_RETRY_SELTO, /*sense_flags*/ SF_RETRY_UA, softc->device_stats); @@ -1231,18 +1321,41 @@ chgetelemstatus(struct cam_periph *periph, * Set up the individual element status structures */ for (i = 0; i < avail; ++i) { - struct changer_element_status *ces = &(user_data[i]); + struct changer_element_status *ces; - copy_element_status(softc, pg_hdr->flags, desc, ces); + /* + * In the changer_element_status structure, fields from + * the beginning to the field of ces_scsi_lun are common + * between SCSI-2 and SCSI-3, while all the rest are new + * from SCSI-3. In order to maintain backward compatibility + * of the chio command, the ces pointer, below, is computed + * such that it lines up with the structure boundary + * corresponding to the SCSI version. + */ + ces = cmd == OCHIOGSTATUS ? + (struct changer_element_status *) + ((unsigned char *)user_data + i * + (offsetof(struct changer_element_status,ces_scsi_lun)+1)): + &user_data[i]; + + copy_element_status(softc, pg_hdr->flags, desc, + ces, scsi_version); desc = (struct read_element_status_descriptor *) - ((uintptr_t)desc + desclen); + ((unsigned char *)desc + desclen); } /* Copy element status structures out to userspace. */ - error = copyout(user_data, - cesr->cesr_element_status, - avail * sizeof(struct changer_element_status)); + if (cmd == OCHIOGSTATUS) + error = copyout(user_data, + cesr->cesr_element_status, + avail* (offsetof(struct changer_element_status, + ces_scsi_lun) + 1)); + else + error = copyout(user_data, + cesr->cesr_element_status, + avail * sizeof(struct changer_element_status)); + cam_periph_lock(periph); done: @@ -1549,6 +1662,39 @@ chgetparams(struct cam_periph *periph) return(error); } +static int +chscsiversion(struct cam_periph *periph) +{ + struct scsi_inquiry_data *inq_data; + struct ccb_getdev *cgd; + int dev_scsi_version; + struct cam_sim *sim; + + sim = xpt_path_sim(periph->path); + mtx_assert(sim->mtx, MA_OWNED); + if ((cgd = (struct ccb_getdev *)xpt_alloc_ccb_nowait()) == NULL) + return (-1); + /* + * Get the device information. + */ + xpt_setup_ccb(&cgd->ccb_h, + periph->path, + CAM_PRIORITY_NORMAL); + cgd->ccb_h.func_code = XPT_GDEV_TYPE; + xpt_action((union ccb *)cgd); + + if (cgd->ccb_h.status != CAM_REQ_CMP) { + xpt_free_ccb((union ccb *)cgd); + return -1; + } + + inq_data = &cgd->inq_data; + dev_scsi_version = inq_data->version; + xpt_free_ccb((union ccb *)cgd); + + return dev_scsi_version; +} + void scsi_move_medium(struct ccb_scsiio *csio, u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *), @@ -1654,6 +1800,7 @@ 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) @@ -1668,6 +1815,10 @@ scsi_read_element_status(struct ccb_scsiio *csio, u_int32_t retries, scsi_ulto2b(sea, scsi_cmd->sea); scsi_ulto2b(count, scsi_cmd->count); scsi_ulto3b(dxfer_len, scsi_cmd->len); + if (dvcid) + scsi_cmd->flags |= READ_ELEMENT_STATUS_DVCID; + if (curdata) + scsi_cmd->flags |= READ_ELEMENT_STATUS_CURDATA; if (voltag) scsi_cmd->byte2 |= READ_ELEMENT_STATUS_VOLTAG; diff --git a/sys/cam/scsi/scsi_ch.h b/sys/cam/scsi/scsi_ch.h index 5ee2244..fd317d2 100644 --- a/sys/cam/scsi/scsi_ch.h +++ b/sys/cam/scsi/scsi_ch.h @@ -136,11 +136,14 @@ struct scsi_position_to_element { struct scsi_read_element_status { u_int8_t opcode; u_int8_t byte2; -#define READ_ELEMENT_STATUS_VOLTAG 0x10 /* report volume tag info */ +#define READ_ELEMENT_STATUS_VOLTAG 0x10 /* report volume tag info */ /* ...next 4 bits are an element type code... */ u_int8_t sea[2]; /* starting element address */ u_int8_t count[2]; /* number of elements */ - u_int8_t reserved0; + u_int8_t flags; +#define READ_ELEMENT_STATUS_DVCID 0x01 /* report device serial number */ +#define READ_ELEMENT_STATUS_CURDATA 0x02 /* allow motion during command */ + u_int8_t len[3]; /* length of data buffer */ u_int8_t reserved1; u_int8_t control; @@ -149,7 +152,7 @@ struct scsi_read_element_status { struct scsi_request_volume_element_address { u_int8_t opcode; u_int8_t byte2; -#define REQUEST_VOLUME_ELEMENT_ADDRESS_VOLTAG 0x10 +#define REQUEST_VOLUME_ELEMENT_ADDRESS_VOLTAG 0x10 /* ...next 4 bits are an element type code... */ u_int8_t eaddr[2]; /* element address */ u_int8_t count[2]; /* number of elements */ @@ -182,8 +185,8 @@ struct read_element_status_header { struct read_element_status_page_header { u_int8_t type; /* element type code; see type codes below */ u_int8_t flags; -#define READ_ELEMENT_STATUS_AVOLTAG 0x40 -#define READ_ELEMENT_STATUS_PVOLTAG 0x80 +#define READ_ELEMENT_STATUS_AVOLTAG 0x40 +#define READ_ELEMENT_STATUS_PVOLTAG 0x80 u_int8_t edl[2]; /* element descriptor length */ u_int8_t reserved; u_int8_t nbytes[3]; /* byte count of all descriptors */ @@ -199,50 +202,79 @@ struct volume_tag { u_int8_t vsn[2]; /* volume sequence number */ }; +struct read_element_status_device_id { + u_int8_t prot_code_set; +#define READ_ELEMENT_STATUS_CODE_SET(p) ((p) & 0x0F) +#define READ_ELEMENT_STATUS_PROTOCOL_ID(p) ((p) >> 4) + + u_int8_t piv_assoc_designator_type; +#define READ_ELEMENT_STATUS_PIV_SET 0x80 +#define READ_ELEMENT_STATUS_ASSOCIATION(p) ((p) >> 4) +#define READ_ELEMENT_STATUS_DESIGNATOR_TYPE(p) ((p) & 0x0F) + + u_int8_t reserved2; + u_int8_t designator_length; + u_int8_t designator[256]; /* Allocate max length */ +}; + struct read_element_status_descriptor { u_int8_t eaddr[2]; /* element address */ u_int8_t flags1; -#define READ_ELEMENT_STATUS_FULL 0x01 -#define READ_ELEMENT_STATUS_IMPEXP 0x02 -#define READ_ELEMENT_STATUS_EXCEPT 0x04 -#define READ_ELEMENT_STATUS_ACCESS 0x08 -#define READ_ELEMENT_STATUS_EXENAB 0x10 -#define READ_ELEMENT_STATUS_INENAB 0x20 +#define READ_ELEMENT_STATUS_FULL 0x01 +#define READ_ELEMENT_STATUS_IMPEXP 0x02 +#define READ_ELEMENT_STATUS_EXCEPT 0x04 +#define READ_ELEMENT_STATUS_ACCESS 0x08 +#define READ_ELEMENT_STATUS_EXENAB 0x10 +#define READ_ELEMENT_STATUS_INENAB 0x20 -#define READ_ELEMENT_STATUS_MT_MASK1 0x05 -#define READ_ELEMENT_STATUS_ST_MASK1 0x0c -#define READ_ELEMENT_STATUS_IE_MASK1 0x3f -#define READ_ELEMENT_STATUS_DT_MASK1 0x0c +#define READ_ELEMENT_STATUS_MT_MASK1 0x05 +#define READ_ELEMENT_STATUS_ST_MASK1 0x0c +#define READ_ELEMENT_STATUS_IE_MASK1 0x3f +#define READ_ELEMENT_STATUS_DT_MASK1 0x0c u_int8_t reserved0; u_int8_t sense_code; u_int8_t sense_qual; - /* - * dt_scsi_flags and dt_scsi_addr are valid only on data transport - * elements. These bytes are undefined for all other element types. - */ - u_int8_t dt_scsi_flags; + union { + struct { + u_int8_t dt_scsi_flags; -#define READ_ELEMENT_STATUS_DT_LUNMASK 0x07 -#define READ_ELEMENT_STATUS_DT_LUVALID 0x10 -#define READ_ELEMENT_STATUS_DT_IDVALID 0x20 -#define READ_ELEMENT_STATUS_DT_NOTBUS 0x80 +#define READ_ELEMENT_STATUS_DT_LUNMASK 0x07 +#define READ_ELEMENT_STATUS_DT_LUVALID 0x10 +#define READ_ELEMENT_STATUS_DT_IDVALID 0x20 +#define READ_ELEMENT_STATUS_DT_NOTBUS 0x80 - u_int8_t dt_scsi_addr; + u_int8_t dt_scsi_addr; + u_int8_t reserved1; + } scsi_2; - u_int8_t reserved1; + /* reserved and obsolete (as of SCSI-3) fields */ + u_int8_t reserved_or_obsolete[3]; + } dt_or_obsolete; u_int8_t flags2; -#define READ_ELEMENT_STATUS_INVERT 0x40 -#define READ_ELEMENT_STATUS_SVALID 0x80 - u_int8_t ssea[2]; /* source storage element address */ +#define READ_ELEMENT_STATUS_INVERT 0x40 +#define READ_ELEMENT_STATUS_SVALID 0x80 +#define READ_ELEMENT_STATUS_ED 0x80 +#define READ_ELEMENT_STATUS_MEDIA_TYPE_MASK 0x07 - struct volume_tag pvoltag; /* omitted if PVOLTAG == 0 */ - struct volume_tag avoltag; /* omitted if AVOLTAG == 0 */ + u_int8_t ssea[2]; /* source storage element address */ - /* Other data may follow */ + union { + struct volume_tag pvoltag; + struct volume_tag voltag[2]; + struct read_element_status_device_id devid; + struct { + struct volume_tag pvoltag; + struct read_element_status_device_id devid; + } pvol_and_devid; + struct { + struct volume_tag voltag[2]; + struct read_element_status_device_id devid; + } vol_tags_and_devid; + } voltag_devid; }; /* XXX add data returned by REQUEST VOLUME ELEMENT ADDRESS */ @@ -457,6 +489,7 @@ void scsi_position_to_element(struct ccb_scsiio *csio, u_int32_t retries, 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); diff --git a/sys/sys/chio.h b/sys/sys/chio.h index aa55f7c..edf1ab7 100644 --- a/sys/sys/chio.h +++ b/sys/sys/chio.h @@ -152,7 +152,8 @@ typedef enum { CES_INVERT = 0x040, /* invert bit */ CES_SOURCE_VALID = 0x080, /* source address (ces_source) valid */ CES_SCSIID_VALID = 0x100, /* ces_scsi_id is valid */ - CES_LUN_VALID = 0x200 /* ces_scsi_lun is valid */ + CES_LUN_VALID = 0x200, /* ces_scsi_lun is valid */ + CES_PIV = 0x400 /* ces_protocol_id is valid */ } ces_status_flags; struct changer_element_status { @@ -181,6 +182,55 @@ struct changer_element_status { changer_voltag_t ces_avoltag; /* alternate volume tag */ u_int8_t ces_scsi_id; /* SCSI id of element */ u_int8_t ces_scsi_lun; /* SCSI lun of element */ + + /* + * Data members for SMC3 and later versions + */ + u_int8_t ces_medium_type; +#define CES_MEDIUM_TYPE_UNKNOWN 0 /* Medium type unspecified */ +#define CES_MEDIUM_TYPE_DATA 1 /* Data medium */ +#define CES_MEDIUM_TYPE_CLEANING 2 /* Cleaning medium */ +#define CES_MEDIUM_TYPE_DIAGNOSTIC 3 /* Diagnostic medium */ +#define CES_MEDIUM_TYPE_WORM 4 /* WORM medium */ +#define CES_MEDIUM_TYPE_MICROCODE 5 /* Microcode image medium */ + + u_int8_t ces_protocol_id; +#define CES_PROTOCOL_ID_FCP_4 0 /* Fiber channel */ +#define CES_PROTOCOL_ID_SPI_5 1 /* Parallel SCSI */ +#define CES_PROTOCOL_ID_SSA_S3P 2 /* SSA */ +#define CES_PROTOCOL_ID_SBP_3 3 /* IEEE 1394 */ +#define CES_PROTOCOL_ID_SRP 4 /* SCSI Remote DMA */ +#define CES_PROTOCOL_ID_ISCSI 5 /* iSCSI */ +#define CES_PROTOCOL_ID_SPL 6 /* SAS */ +#define CES_PROTOCOL_ID_ADT_2 7 /* Automation/Drive Interface */ +#define CES_PROTOCOL_ID_ACS_2 8 /* ATA */ + + u_int8_t ces_assoc; +#define CES_ASSOC_LOGICAL_UNIT 0 +#define CES_ASSOC_TARGET_PORT 1 +#define CES_ASSOC_TARGET_DEVICE 2 + + u_int8_t ces_designator_type; +#define CES_DESIGNATOR_TYPE_VENDOR_SPECIFIC 0 +#define CES_DESIGNATOR_TYPE_T10_VENDOR_ID 1 +#define CES_DESIGNATOR_TYPE_EUI_64 2 +#define CES_DESIGNATOR_TYPE_NAA 3 +#define CES_DESIGNATOR_TYPE_TARGET_PORT_ID 4 +#define CES_DESIGNATOR_TYPE_TARGET_PORT_GRP 5 +#define CES_DESIGNATOR_TYPE_LOGICAL_UNIT_GRP 6 +#define CES_DESIGNATOR_TYPE_MD5_LOGICAL_UNIT_ID 7 +#define CES_DESIGNATOR_TYPE_SCSI_NAME_STRING 8 + + u_int8_t ces_code_set; +#define CES_CODE_SET_RESERVED 0 +#define CES_CODE_SET_BINARY 1 +#define CES_CODE_SET_ASCII 2 +#define CES_CODE_SET_UTF_8 3 + + u_int8_t ces_designator_length; + +#define CES_MAX_DESIGNATOR_LENGTH (1 << 8) + u_int8_t ces_designator[CES_MAX_DESIGNATOR_LENGTH + 1]; }; struct changer_element_status_request { @@ -189,7 +239,7 @@ struct changer_element_status_request { u_int16_t cesr_element_count; u_int16_t cesr_flags; -#define CESR_VOLTAGS 0x01 +#define CESR_VOLTAGS 0x01 struct changer_element_status *cesr_element_status; }; @@ -200,28 +250,29 @@ struct changer_set_voltag_request { u_int16_t csvr_addr; u_int16_t csvr_flags; -#define CSVR_MODE_MASK 0x0f /* mode mask, acceptable modes below: */ +#define CSVR_MODE_MASK 0x0f /* mode mask, acceptable modes below: */ #define CSVR_MODE_SET 0x00 /* set volume tag if not set */ -#define CSVR_MODE_REPLACE 0x01 /* unconditionally replace volume tag */ -#define CSVR_MODE_CLEAR 0x02 /* clear volume tag */ +#define CSVR_MODE_REPLACE 0x01 /* unconditionally replace volume tag */ +#define CSVR_MODE_CLEAR 0x02 /* clear volume tag */ -#define CSVR_ALTERNATE 0x10 /* set to work with alternate voltag */ +#define CSVR_ALTERNATE 0x10 /* set to work with alternate voltag */ changer_voltag_t csvr_voltag; }; -#define CESTATUS_BITS \ +#define CESTATUS_BITS \ "\20\6INEAB\5EXENAB\4ACCESS\3EXCEPT\2IMPEXP\1FULL" -#define CHIOMOVE _IOW('c', 0x01, struct changer_move) -#define CHIOEXCHANGE _IOW('c', 0x02, struct changer_exchange) -#define CHIOPOSITION _IOW('c', 0x03, struct changer_position) -#define CHIOGPICKER _IOR('c', 0x04, int) -#define CHIOSPICKER _IOW('c', 0x05, int) -#define CHIOGPARAMS _IOR('c', 0x06, struct changer_params) -#define CHIOIELEM _IOW('c', 0x07, u_int32_t) -#define CHIOGSTATUS _IOW('c', 0x08, struct changer_element_status_request) -#define CHIOSETVOLTAG _IOW('c', 0x09, struct changer_set_voltag_request) +#define CHIOMOVE _IOW('c', 0x01, struct changer_move) +#define CHIOEXCHANGE _IOW('c', 0x02, struct changer_exchange) +#define CHIOPOSITION _IOW('c', 0x03, struct changer_position) +#define CHIOGPICKER _IOR('c', 0x04, int) +#define CHIOSPICKER _IOW('c', 0x05, int) +#define CHIOGPARAMS _IOR('c', 0x06, struct changer_params) +#define CHIOIELEM _IOW('c', 0x07, u_int32_t) +#define OCHIOGSTATUS _IOW('c', 0x08, struct changer_element_status_request) +#define CHIOSETVOLTAG _IOW('c', 0x09, struct changer_set_voltag_request) +#define CHIOGSTATUS _IOW('c', 0x0A, struct changer_element_status_request) #endif /* !_SYS_CHIO_H_ */ |