Hey Ken, this change doesn't compile for me. See below
Warner On Apr 19, 2013, at 2:03 PM, Kenneth D. Merry wrote: > Author: ken > Date: Fri Apr 19 20:03:51 2013 > New Revision: 249658 > URL: http://svnweb.freebsd.org/changeset/base/249658 > > Log: > Update chio(1) and ch(4) to support reporting element designators. > > This allows mapping a tape drive in a changer (as reported by > 'chio status') to a sa(4) driver instance by comparing the > serial numbers. > > The designators can be ASCII (which is printed out directly), binary > (which is printed in hex format) or UTF-8, which is printed in either > native UTF-8 format if the terminal can support it, or in %XX notation > for non-ASCII characters. Thanks to Hiroki Sato <hrs@> for the > explaining UTF-8 printing and example UTF-8 printing code. > > chio.h: Modify the changer_element_status structure to add new > fields and definitions from the SMC3r16 spec. > > Rename the original CHIOGSTATUS ioctl to OCHIOGTATUS and > define a new CHIOGSTATUS ioctl. > > Clean up some tab/space issues. > > chio.c: For the 'status' subcommand, print the designator field > if it is supplied by a device. > > scsi_ch.h: Add new flags for DVCID and CURDATA to the READ > ELEMENT STATUS command structure. > > Add a read_element_status_device_id structure > for the data fields in the new standard. Add new > unions, dt_or_obsolete and voltage_devid, to hold > and address data from either SCSI-2 or newer devices. > > scsi_ch.c: Implement support for fetching device IDs with READ > ELEMENT STATUS data. > > Add new arguments to scsi_read_element_status() to > allow the user to request the DVCID and CURDATA bits. > This isn't compiled into libcam (it's only an internal > kernel interface), so we don't need any special > handling for the API change. > > If the user issues the new CHIOGSTATUS ioctl, copy all of > the available element status data out. If he issues the > OCHIOGSTATUS ioctl, we don't copy the new fields in the > structure. > > Fix a bug in chopen() that would result in the peripheral > never getting unheld if chgetparams() failed. > > Sponsored by: Spectra Logic > Submitted by: Po-Li Soong > MFC After: 1 week > > Modified: > head/bin/chio/chio.c > head/sys/cam/scsi/scsi_ch.c > head/sys/cam/scsi/scsi_ch.h > head/sys/sys/chio.h > > Modified: head/bin/chio/chio.c > ============================================================================== > --- head/bin/chio/chio.c Fri Apr 19 19:45:00 2013 (r249657) > +++ head/bin/chio/chio.c Fri Apr 19 20:03:51 2013 (r249658) > @@ -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, > 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, c > 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(">"); > +} > > Modified: head/sys/cam/scsi/scsi_ch.c > ============================================================================== > --- head/sys/cam/scsi/scsi_ch.c Fri Apr 19 19:45:00 2013 > (r249657) > +++ head/sys/cam/scsi/scsi_ch.c Fri Apr 19 20:03:51 2013 > (r249658) > @@ -194,12 +194,14 @@ static int chexchange(struct cam_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 > * 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, ca > switch (cmd) { > case CHIOGPICKER: > case CHIOGPARAMS: > + case OCHIOGSTATUS: > case CHIOGSTATUS: > break; > > @@ -824,10 +828,26 @@ chioctl(struct cdev *dev, u_long cmd, ca > 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 *uvolt > } > > /* > - * 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 *sof > 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 *sof > "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)); > - > - if (desc->dt_scsi_flags & READ_ELEMENT_STATUS_DT_IDVALID) { > - ces->ces_flags |= CES_SCSIID_VALID; > - ces->ces_scsi_id = desc->dt_scsi_addr; > - } > + 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 (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'; compiler complains here that this comparison is always false due to data ranges. I hacked it in my copy by always using devid->designator_length, but I know that's a lame fix. Can you look into it? Also, just got tinderbox mail. Warner > + } > + 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 (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_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 (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 *perip > /* 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 *perip > 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 *perip > /* 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 *perip > * 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_scsi > 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; > > Modified: head/sys/cam/scsi/scsi_ch.h > ============================================================================== > --- head/sys/cam/scsi/scsi_ch.h Fri Apr 19 19:45:00 2013 > (r249657) > +++ head/sys/cam/scsi/scsi_ch.h Fri Apr 19 20:03:51 2013 > (r249658) > @@ -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_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_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 > > 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; > - > -#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 reserved1; > + 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 > + > + u_int8_t dt_scsi_addr; > + u_int8_t reserved1; > + } scsi_2; > + > + /* 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 > 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); > > Modified: head/sys/sys/chio.h > ============================================================================== > --- head/sys/sys/chio.h Fri Apr 19 19:45:00 2013 (r249657) > +++ head/sys/sys/chio.h Fri Apr 19 20:03:51 2013 (r249658) > @@ -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_ */ _______________________________________________ svn-src-head@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"