svn commit: r249658 - in head: bin/chio sys/cam/scsi sys/sys
Warner Losh
imp at bsdimp.com
Sat Apr 20 11:45:49 UTC 2013
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_ */
More information about the svn-src-all
mailing list