From owner-svn-src-all@FreeBSD.ORG Sat Apr 20 11:45:49 2013 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 75F08946 for ; Sat, 20 Apr 2013 11:45:49 +0000 (UTC) (envelope-from imp@bsdimp.com) Received: from mail-da0-x235.google.com (mail-da0-x235.google.com [IPv6:2607:f8b0:400e:c00::235]) by mx1.freebsd.org (Postfix) with ESMTP id 50C561865 for ; Sat, 20 Apr 2013 11:45:49 +0000 (UTC) Received: by mail-da0-f53.google.com with SMTP id n34so2340096dal.12 for ; Sat, 20 Apr 2013 04:45:49 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:sender:subject:mime-version:content-type:from :in-reply-to:date:cc:content-transfer-encoding:message-id:references :to:x-mailer:x-gm-message-state; bh=8TCNneII8gau7mY+pR0sfxLAP7xIiIAiO9t+eyQcQCc=; b=NcRSUFX5T3bCP+KytqTi92juCjmKSxNvUAqpuUBRyIq3407bdQU5EeYLMrax/4Wo4T KpP/Z7Waph6bmzbIRPCGrXce86OJAe2EB7lgaG9rpiSjic456JNx361mDzHP7EZfkR/C /ug7lowntknVCICToGgQzYittwAr+Vm4ZI+0JXQX3wDjpKBGzGKW1EDgDbT7UvG+jpnY QtLV4NoYwF1Zhc+WoMQAI9mom4TjJC8aeZhBm0U1lteyoZQe6icHxjRuRoGsGjgD9LFg ztprS4UbyZO7uLO7i3knVHaJartUmdTsPpFRqlF1kzllAUJ9XMZZgDjP/2lZ3VLgzQsB RXKw== X-Received: by 10.66.161.69 with SMTP id xq5mr20309658pab.136.1366458349037; Sat, 20 Apr 2013 04:45:49 -0700 (PDT) Received: from [10.0.0.53] (50-78-194-198-static.hfc.comcastbusiness.net. [50.78.194.198]) by mx.google.com with ESMTPS id wi6sm16960045pbc.22.2013.04.20.04.45.46 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sat, 20 Apr 2013 04:45:47 -0700 (PDT) Sender: Warner Losh Subject: Re: svn commit: r249658 - in head: bin/chio sys/cam/scsi sys/sys Mime-Version: 1.0 (Apple Message framework v1085) Content-Type: text/plain; charset=us-ascii From: Warner Losh In-Reply-To: <201304192003.r3JK3qFB013463@svn.freebsd.org> Date: Sat, 20 Apr 2013 05:45:43 -0600 Content-Transfer-Encoding: quoted-printable Message-Id: <82451AEC-79FD-448F-B180-C2CEC47EB18B@bsdimp.com> References: <201304192003.r3JK3qFB013463@svn.freebsd.org> To: Kenneth D. Merry X-Mailer: Apple Mail (2.1085) X-Gm-Message-State: ALoCoQlS1gZqsiqGNaYR6cR5Gs5xmyYTZoPU3OKfBQ/y+EIae5fPR+B3LNMB6mIg36wXUMtrWHlj Cc: svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 20 Apr 2013 11:45:49 -0000 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 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 > #include > #include > +#include > +#include >=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_ */