Print this page
NEX-3705 Need to update libses with LID/USN code from sesctld
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Hans Rosenfeld <hans.rosenfeld@nexenta.com>


   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.

  24  */
  25 
  26 #include <scsi/libses.h>
  27 #include "ses_impl.h"
  28 
  29 #define NEXT_ED(eip)    \
  30         ((ses2_ed_impl_t *)((uint8_t *)(eip) +  \
  31             ((eip)->st_hdr.sehi_ed_len + sizeof (ses2_ed_hdr_impl_t))))
  32 
  33 static ses_node_t *
  34 ses_find_enclosure(ses_snap_t *sp, uint64_t number)
  35 {
  36         ses_node_t *np;
  37 
  38         for (np = sp->ss_root->sn_first_child; np != NULL;
  39             np = np->sn_next_sibling) {
  40                 ASSERT(np->sn_type == SES_NODE_ENCLOSURE);
  41                 if (np->sn_enc_num == number)
  42                         return ((ses_node_t *)np);
  43         }


 151         pip = (ses2_config_page_impl_t *)pp->ssp_page;
 152 
 153         if (pp->ssp_len < offsetof(ses2_config_page_impl_t, scpi_data))
 154                 return (ses_error(ESES_BAD_RESPONSE, "no enclosure "
 155                     "descriptors found"));
 156 
 157         /*
 158          * Start with the root of the tree, which is a target node, containing
 159          * just the SCSI inquiry properties.
 160          */
 161         if ((root = ses_node_alloc(sp, sp->ss_root)) == NULL)
 162                 return (-1);
 163 
 164         root->sn_type = SES_NODE_TARGET;
 165         SES_NV_ADD(string, err, root->sn_props, SCSI_PROP_VENDOR,
 166             libscsi_vendor(sp->ss_target->st_target));
 167         SES_NV_ADD(string, err, root->sn_props, SCSI_PROP_PRODUCT,
 168             libscsi_product(sp->ss_target->st_target));
 169         SES_NV_ADD(string, err, root->sn_props, SCSI_PROP_REVISION,
 170             libscsi_revision(sp->ss_target->st_target));






 171 
 172         for (eip = (ses2_ed_impl_t *)pip->scpi_data, i = 0;
 173             i < pip->scpi_n_subenclosures + 1;
 174             i++, eip = NEXT_ED(eip)) {
 175                 if (!SES_WITHIN_PAGE_STRUCT(eip, pp->ssp_page, pp->ssp_len))
 176                         break;
 177 
 178                 n_etds += eip->st_hdr.sehi_n_etd_hdrs;
 179         }
 180         ftip = (ses2_td_hdr_impl_t *)eip;
 181 
 182         /*
 183          * There should really be only one Enclosure element possible for a
 184          * give subenclosure ID.  The standard never comes out and says this,
 185          * but it does describe this element as "managing the enclosure itself"
 186          * which implies rather strongly that the subenclosure ID field is that
 187          * of, well, the enclosure itself.  Since an enclosure can't contain
 188          * itself, it follows logically that each subenclosure has at most one
 189          * Enclosure type descriptor elements matching its ID.  Of course, some
 190          * enclosure firmware is buggy, so this may not always work out; in


 193          */
 194         for (eip = (ses2_ed_impl_t *)pip->scpi_data, i = 0;
 195             i < pip->scpi_n_subenclosures + 1;
 196             i++, eip = NEXT_ED(eip)) {
 197                 if (!SES_WITHIN_PAGE_STRUCT(eip, pp->ssp_page, pp->ssp_len))
 198                         break;
 199 
 200                 if ((np = ses_node_alloc(sp, root)) == NULL)
 201                         return (-1);
 202 
 203                 np->sn_type = SES_NODE_ENCLOSURE;
 204                 np->sn_enc_num = eip->st_hdr.sehi_subenclosure_id;
 205 
 206                 if (!SES_WITHIN_PAGE(eip, eip->st_hdr.sehi_ed_len +
 207                     sizeof (ses2_ed_hdr_impl_t),
 208                     pp->ssp_page, pp->ssp_len))
 209                         break;
 210 
 211                 if (enc_parse_ed(eip, np->sn_props) != 0)
 212                         return (-1);








 213         }
 214 
 215         if (root->sn_first_child == NULL)
 216                 return (ses_error(ESES_BAD_RESPONSE, "no enclosure "
 217                     "descriptors found"));
 218 
 219         tp = (char *)(ftip + n_etds);
 220 
 221         for (i = 0, toff = 0, idx = eidx = 0; i < n_etds; i++) {
 222                 tip = ftip + i;
 223 
 224                 if (!SES_WITHIN_PAGE_STRUCT(tip, pp->ssp_page, pp->ssp_len))
 225                         break;
 226 
 227                 pnp = ses_find_enclosure(sp,
 228                     tip->sthi_subenclosure_id);
 229                 if (pnp == NULL) {
 230                         idx += tip->sthi_max_elements + 1;
 231                         eidx += tip->sthi_max_elements;
 232                         toff += tip->sthi_text_len;




   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  25  */
  26 
  27 #include <scsi/libses.h>
  28 #include "ses_impl.h"
  29 
  30 #define NEXT_ED(eip)    \
  31         ((ses2_ed_impl_t *)((uint8_t *)(eip) +  \
  32             ((eip)->st_hdr.sehi_ed_len + sizeof (ses2_ed_hdr_impl_t))))
  33 
  34 static ses_node_t *
  35 ses_find_enclosure(ses_snap_t *sp, uint64_t number)
  36 {
  37         ses_node_t *np;
  38 
  39         for (np = sp->ss_root->sn_first_child; np != NULL;
  40             np = np->sn_next_sibling) {
  41                 ASSERT(np->sn_type == SES_NODE_ENCLOSURE);
  42                 if (np->sn_enc_num == number)
  43                         return ((ses_node_t *)np);
  44         }


 152         pip = (ses2_config_page_impl_t *)pp->ssp_page;
 153 
 154         if (pp->ssp_len < offsetof(ses2_config_page_impl_t, scpi_data))
 155                 return (ses_error(ESES_BAD_RESPONSE, "no enclosure "
 156                     "descriptors found"));
 157 
 158         /*
 159          * Start with the root of the tree, which is a target node, containing
 160          * just the SCSI inquiry properties.
 161          */
 162         if ((root = ses_node_alloc(sp, sp->ss_root)) == NULL)
 163                 return (-1);
 164 
 165         root->sn_type = SES_NODE_TARGET;
 166         SES_NV_ADD(string, err, root->sn_props, SCSI_PROP_VENDOR,
 167             libscsi_vendor(sp->ss_target->st_target));
 168         SES_NV_ADD(string, err, root->sn_props, SCSI_PROP_PRODUCT,
 169             libscsi_product(sp->ss_target->st_target));
 170         SES_NV_ADD(string, err, root->sn_props, SCSI_PROP_REVISION,
 171             libscsi_revision(sp->ss_target->st_target));
 172         if (libscsi_usn(sp->ss_target->st_target) != NULL)
 173                 SES_NV_ADD(string, err, root->sn_props, SCSI_PROP_USN,
 174                     libscsi_usn(sp->ss_target->st_target));
 175         if (libscsi_lid(sp->ss_target->st_target) != NULL)
 176                 SES_NV_ADD(string, err, root->sn_props, SCSI_PROP_LID,
 177                     libscsi_lid(sp->ss_target->st_target));
 178 
 179         for (eip = (ses2_ed_impl_t *)pip->scpi_data, i = 0;
 180             i < pip->scpi_n_subenclosures + 1;
 181             i++, eip = NEXT_ED(eip)) {
 182                 if (!SES_WITHIN_PAGE_STRUCT(eip, pp->ssp_page, pp->ssp_len))
 183                         break;
 184 
 185                 n_etds += eip->st_hdr.sehi_n_etd_hdrs;
 186         }
 187         ftip = (ses2_td_hdr_impl_t *)eip;
 188 
 189         /*
 190          * There should really be only one Enclosure element possible for a
 191          * give subenclosure ID.  The standard never comes out and says this,
 192          * but it does describe this element as "managing the enclosure itself"
 193          * which implies rather strongly that the subenclosure ID field is that
 194          * of, well, the enclosure itself.  Since an enclosure can't contain
 195          * itself, it follows logically that each subenclosure has at most one
 196          * Enclosure type descriptor elements matching its ID.  Of course, some
 197          * enclosure firmware is buggy, so this may not always work out; in


 200          */
 201         for (eip = (ses2_ed_impl_t *)pip->scpi_data, i = 0;
 202             i < pip->scpi_n_subenclosures + 1;
 203             i++, eip = NEXT_ED(eip)) {
 204                 if (!SES_WITHIN_PAGE_STRUCT(eip, pp->ssp_page, pp->ssp_len))
 205                         break;
 206 
 207                 if ((np = ses_node_alloc(sp, root)) == NULL)
 208                         return (-1);
 209 
 210                 np->sn_type = SES_NODE_ENCLOSURE;
 211                 np->sn_enc_num = eip->st_hdr.sehi_subenclosure_id;
 212 
 213                 if (!SES_WITHIN_PAGE(eip, eip->st_hdr.sehi_ed_len +
 214                     sizeof (ses2_ed_hdr_impl_t),
 215                     pp->ssp_page, pp->ssp_len))
 216                         break;
 217 
 218                 if (enc_parse_ed(eip, np->sn_props) != 0)
 219                         return (-1);
 220 
 221                 if (libscsi_usn(sp->ss_target->st_target) != NULL)
 222                         SES_NV_ADD(string, err, np->sn_props, SCSI_PROP_USN,
 223                             libscsi_usn(sp->ss_target->st_target));
 224 
 225                 if (libscsi_lid(sp->ss_target->st_target) != NULL)
 226                         SES_NV_ADD(string, err, np->sn_props, SCSI_PROP_LID,
 227                             libscsi_lid(sp->ss_target->st_target));
 228         }
 229 
 230         if (root->sn_first_child == NULL)
 231                 return (ses_error(ESES_BAD_RESPONSE, "no enclosure "
 232                     "descriptors found"));
 233 
 234         tp = (char *)(ftip + n_etds);
 235 
 236         for (i = 0, toff = 0, idx = eidx = 0; i < n_etds; i++) {
 237                 tip = ftip + i;
 238 
 239                 if (!SES_WITHIN_PAGE_STRUCT(tip, pp->ssp_page, pp->ssp_len))
 240                         break;
 241 
 242                 pnp = ses_find_enclosure(sp,
 243                     tip->sthi_subenclosure_id);
 244                 if (pnp == NULL) {
 245                         idx += tip->sthi_max_elements + 1;
 246                         eidx += tip->sthi_max_elements;
 247                         toff += tip->sthi_text_len;