Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 20 Apr 2013 05:45:43 -0600
From:      Warner Losh <imp@bsdimp.com>
To:        Kenneth D. Merry <ken@freebsd.org>
Cc:        svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org
Subject:   Re: svn commit: r249658 - in head: bin/chio sys/cam/scsi sys/sys
Message-ID:  <82451AEC-79FD-448F-B180-C2CEC47EB18B@bsdimp.com>
In-Reply-To: <201304192003.r3JK3qFB013463@svn.freebsd.org>
References:  <201304192003.r3JK3qFB013463@svn.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
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
>=20
> Log:
>  Update chio(1) and ch(4) to support reporting element designators.
>=20
>  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.
>=20
>  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.
>=20
>  chio.h:		Modify the changer_element_status structure to =
add new
>  		fields and definitions from the SMC3r16 spec.
>=20
>  		Rename the original CHIOGSTATUS ioctl to OCHIOGTATUS and
>  		define a new CHIOGSTATUS ioctl.
>=20
>  		Clean up some tab/space issues.
>=20
>  chio.c: 	For the 'status' subcommand, print the designator field
>  		if it is supplied by a device.
>=20
>  scsi_ch.h:	Add new flags for DVCID and CURDATA to the READ
>  		ELEMENT STATUS command structure.
>=20
>  		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.
>=20
>  scsi_ch.c:	Implement support for fetching device IDs with READ
>  		ELEMENT STATUS data.
>=20
>  		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.
>=20
>  		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.
>=20
>  		Fix a bug in chopen() that would result in the =
peripheral
>  		never getting unheld if chgetparams() failed.
>=20
>  Sponsored by:	Spectra Logic
>  Submitted by:	Po-Li Soong
>  MFC After:	1 week
>=20
> 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
>=20
> Modified: head/bin/chio/chio.c
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- 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>
>=20
> #include "defs.h"
> #include "pathnames.h"
> @@ -81,6 +83,7 @@ static	int do_status(const char *, int,=20
> 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);
>=20
> #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');
> 		}
>=20
> @@ -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 =3D nl_langinfo(CODESET);
> +
> +		/* See if we can natively print UTF-8 */
> +		if (strcmp(cs_native, UTF8CODESET) =3D=3D 0)
> +			cs_native =3D NULL;
> +
> +		if (cs_native =3D=3D 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 =3D 0; i < designator_length &&
> +			    designator[i] !=3D '\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 =3D 0; i < designator_length; i++)
> +			printf("%02X%s", designator[i],
> +			    (i =3D=3D designator_length - 1) ? "" : " =
");
> +		break;
> +	}
> +	default:
> +		break;
> +	}
> +	printf(">");
> +}
>=20
> Modified: head/sys/cam/scsi/scsi_ch.c
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- 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,=20
> 				unsigned int timeout);
> static	int		chgetparams(struct cam_periph *periph);
> +static	int		chscsiversion(struct cam_periph =
*periph);
>=20
> static struct periph_driver chdriver =3D
> {
> @@ -474,6 +476,7 @@ chopen(struct cdev *dev, int flags, int=20
> 	 * Load information about this changer device into the softc.
> 	 */
> 	if ((error =3D chgetparams(periph)) !=3D 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;
>=20
> @@ -824,10 +828,26 @@ chioctl(struct cdev *dev, u_long cmd, ca
> 		error =3D chielem(periph, *(unsigned int *)addr);
> 		break;
>=20
> +	case OCHIOGSTATUS:
> +	{
> +		error =3D chgetelemstatus(periph, SCSI_REV_2, cmd,
> +		    (struct changer_element_status_request *)addr);
> +		break;
> +	}
> +
> 	case CHIOGSTATUS:
> 	{
> -		error =3D chgetelemstatus(periph,
> -			       (struct changer_element_status_request *) =
addr);
> +		int scsi_version;
> +
> +		scsi_version =3D chscsiversion(periph);
> +		if (scsi_version >=3D SCSI_REV_0) {
> +			error =3D 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;
> 	}
>=20
> @@ -1034,18 +1054,20 @@ copy_voltag(struct changer_voltag *uvolt
> }
>=20
> /*
> - * 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 =3D scsi_2btoul(desc->eaddr);
> 	u_int16_t et;
> +	struct volume_tag *pvol_tag =3D NULL, *avol_tag =3D NULL;
> +	struct read_element_status_device_id *devid =3D NULL;
>=20
> 	ces->ces_int_addr =3D eaddr;
> 	/* set up logical address in element status */
> @@ -1076,7 +1098,7 @@ copy_element_status(struct ch_softc *sof
> 			if ((softc->sc_firsts[et] <=3D eaddr)
> 			    && ((softc->sc_firsts[et] + =
softc->sc_counts[et])
> 				> eaddr)) {
> -				ces->ces_source_addr =3D=20
> +				ces->ces_source_addr =3D
> 					eaddr - softc->sc_firsts[et];
> 				ces->ces_source_type =3D et;
> 				ces->ces_flags |=3D CES_SOURCE_VALID;
> @@ -1089,27 +1111,92 @@ copy_element_status(struct ch_softc *sof
> 			       "address %ud to a valid element type\n",
> 			       eaddr);
> 	}
> -		=09
>=20
> +	/*
> +	 * 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 =3D &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 |=3D CES_SCSIID_VALID;
> -		ces->ces_scsi_id =3D desc->dt_scsi_addr;
> -	}
> +		avol_tag =3D (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 >=3D SCSI_REV_SPC) {
> +		if ((flags & READ_ELEMENT_STATUS_PVOLTAG) ^
> +		    (flags & READ_ELEMENT_STATUS_AVOLTAG))
> +			devid =3D =
&desc->voltag_devid.pvol_and_devid.devid;
> +		else if (!(flags & READ_ELEMENT_STATUS_PVOLTAG) &&
> +			 !(flags & READ_ELEMENT_STATUS_AVOLTAG))
> +			devid =3D &desc->voltag_devid.devid;
> +		else /* Have both PVOLTAG and AVOLTAG */
> +			devid =3D =
&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 !=3D NULL) {
> +		if (devid->designator_length > 0) {
> +			bcopy((void *)devid->designator,
> +			      (void *)ces->ces_designator,
> +			      devid->designator_length);
> +			ces->ces_designator_length =3D =
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)]=3D '\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 |=3D CES_PIV;
> +			ces->ces_protocol_id =3D
> +			    READ_ELEMENT_STATUS_PROTOCOL_ID(
> +			    devid->prot_code_set);
> +		}
> +		ces->ces_code_set =3D
> +		    READ_ELEMENT_STATUS_CODE_SET(devid->prot_code_set);
> +		ces->ces_assoc =3D READ_ELEMENT_STATUS_ASSOCIATION(
> +		    devid->piv_assoc_designator_type);
> +		ces->ces_designator_type =3D =
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 =3D 0;
> +		ces->ces_designator[0] =3D '\0';
> +		ces->ces_protocol_id =3D CES_PROTOCOL_ID_FCP_4;
> +	}
> +
> +	if (scsi_version <=3D SCSI_REV_2) {
> +		if (desc->dt_or_obsolete.scsi_2.dt_scsi_flags &
> +		    READ_ELEMENT_STATUS_DT_IDVALID) {
> +			ces->ces_flags |=3D CES_SCSIID_VALID;
> +			ces->ces_scsi_id =3D
> +			    desc->dt_or_obsolete.scsi_2.dt_scsi_addr;
> +		}
>=20
> -	if (desc->dt_scsi_addr & READ_ELEMENT_STATUS_DT_LUVALID) {
> -		ces->ces_flags |=3D CES_LUN_VALID;
> -		ces->ces_scsi_lun =3D=20
> -			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 |=3D CES_LUN_VALID;
> +			ces->ces_scsi_lun =3D
> +			    desc->dt_or_obsolete.scsi_2.dt_scsi_flags &
> +			    READ_ELEMENT_STATUS_DT_LUNMASK;
> +		}
> 	}
> }
>=20
> static int
> -chgetelemstatus(struct cam_periph *periph,=20
> +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 =3D 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);
> -=09
> +
> 	error =3D 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 =3D 0; i < avail; ++i) {
> -		struct changer_element_status *ces =3D &(user_data[i]);
> +		struct changer_element_status *ces;
>=20
> -		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 =3D cmd =3D=3D 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);
>=20
> 		desc =3D (struct read_element_status_descriptor *)
> -		       ((uintptr_t)desc + desclen);
> +		       ((unsigned char *)desc + desclen);
> 	}
>=20
> 	/* Copy element status structures out to userspace. */
> -	error =3D copyout(user_data,
> -			cesr->cesr_element_status,
> -			avail * sizeof(struct changer_element_status));
> +	if (cmd =3D=3D OCHIOGSTATUS)
> +		error =3D copyout(user_data,
> +				cesr->cesr_element_status,
> +				avail* (offsetof(struct =
changer_element_status,
> +				ces_scsi_lun) + 1));
> +	else
> +		error =3D copyout(user_data,
> +				cesr->cesr_element_status,
> +				avail * sizeof(struct =
changer_element_status));
> +
> 	cam_periph_lock(periph);
>=20
>  done:
> @@ -1549,6 +1662,39 @@ chgetparams(struct cam_periph *periph)
> 	return(error);
> }
>=20
> +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 =3D xpt_path_sim(periph->path);
> +	mtx_assert(sim->mtx, MA_OWNED);
> +	if ((cgd =3D (struct ccb_getdev *)xpt_alloc_ccb_nowait()) =3D=3D =
NULL)
> +		return (-1);
> +	/*
> +	 * Get the device information.
> +	 */
> +	xpt_setup_ccb(&cgd->ccb_h,
> +		      periph->path,
> +		      CAM_PRIORITY_NORMAL);
> +	cgd->ccb_h.func_code =3D XPT_GDEV_TYPE;
> +	xpt_action((union ccb *)cgd);
> +
> +	if (cgd->ccb_h.status !=3D CAM_REQ_CMP) {
> +		xpt_free_ccb((union ccb *)cgd);
> +		return -1;
> +	}
> +
> +	inq_data =3D &cgd->inq_data;
> +	dev_scsi_version =3D 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 |=3D READ_ELEMENT_STATUS_DVCID;
> +	if (curdata)
> +		scsi_cmd->flags |=3D READ_ELEMENT_STATUS_CURDATA;
>=20
> 	if (voltag)
> 		scsi_cmd->byte2 |=3D READ_ELEMENT_STATUS_VOLTAG;
>=20
> Modified: head/sys/cam/scsi/scsi_ch.h
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- 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 */
> };
>=20
> +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;
>=20
> -#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
>=20
> 	u_int8_t	reserved0;
> 	u_int8_t	sense_code;
> 	u_int8_t	sense_qual;
>=20
> -	/*
> -	 * 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;
>=20
> 	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
>=20
> -	struct volume_tag pvoltag;	/* omitted if PVOLTAG =3D=3D 0 =
*/
> -	struct volume_tag avoltag;	/* omitted if AVOLTAG =3D=3D 0 =
*/
> +	u_int8_t	ssea[2];	/* source storage element =
address */
>=20
> -	/* 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;
> };
>=20
> /* 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);
>=20
> Modified: head/sys/sys/chio.h
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- 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	  =3D 0x040,	/* invert bit */
> 	CES_SOURCE_VALID  =3D 0x080,	/* source address (ces_source) =
valid */
> 	CES_SCSIID_VALID  =3D 0x100,	/* ces_scsi_id is valid */
> -	CES_LUN_VALID	  =3D 0x200	/* ces_scsi_lun is valid */
> +	CES_LUN_VALID	  =3D 0x200,	/* ces_scsi_lun is valid */
> +	CES_PIV		  =3D 0x400	/* ces_protocol_id is valid */
> } ces_status_flags;
>=20
> 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];
> };
>=20
> struct changer_element_status_request {
> @@ -189,7 +239,7 @@ struct changer_element_status_request {
> 	u_int16_t			cesr_element_count;
>=20
> 	u_int16_t			cesr_flags;
> -#define CESR_VOLTAGS	0x01
> +#define	CESR_VOLTAGS	0x01
>=20
> 	struct changer_element_status	*cesr_element_status;
> };
> @@ -200,28 +250,29 @@ struct changer_set_voltag_request {
> 	u_int16_t		csvr_addr;
>=20
> 	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 */
>=20
> -#define CSVR_ALTERNATE		0x10	/* set to work with =
alternate voltag */
> +#define	CSVR_ALTERNATE		0x10	/* set to work with =
alternate voltag */
>=20
> 	changer_voltag_t     	csvr_voltag;
> };
>=20
>=20
> -#define CESTATUS_BITS	\
> +#define	CESTATUS_BITS	\
> 	"\20\6INEAB\5EXENAB\4ACCESS\3EXCEPT\2IMPEXP\1FULL"
>=20
> -#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)
>=20
> #endif /* !_SYS_CHIO_H_ */




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?82451AEC-79FD-448F-B180-C2CEC47EB18B>