The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ocs_fc/ocs_vpd.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2017 Broadcom. All rights reserved.
    3  * The term "Broadcom" refers to Broadcom Limited and/or its subsidiaries.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions are met:
    7  *
    8  * 1. Redistributions of source code must retain the above copyright notice,
    9  *    this list of conditions and the following disclaimer.
   10  *
   11  * 2. Redistributions in binary form must reproduce the above copyright notice,
   12  *    this list of conditions and the following disclaimer in the documentation
   13  *    and/or other materials provided with the distribution.
   14  *
   15  * 3. Neither the name of the copyright holder nor the names of its contributors
   16  *    may be used to endorse or promote products derived from this software
   17  *    without specific prior written permission.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
   23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   29  * POSSIBILITY OF SUCH DAMAGE.
   30  *
   31  * $FreeBSD$
   32  */
   33 
   34 /**
   35  * @file
   36  * OCS VPD parser
   37  */
   38 
   39 #if !defined(__OCS_VPD_H__)
   40 #define __OCS_VPD_H__
   41 
   42 /**
   43  * @brief VPD buffer structure
   44  */
   45 
   46 typedef struct {
   47         uint8_t *buffer;
   48         uint32_t length;
   49         uint32_t offset;
   50         uint8_t checksum;
   51         } vpdbuf_t;
   52 
   53 /**
   54  * @brief return next VPD byte
   55  *
   56  * Returns next VPD byte and updates accumulated checksum
   57  *
   58  * @param vpd pointer to vpd buffer
   59  *
   60  * @return returns next byte for success, or a negative error code value for failure.
   61  *
   62  */
   63 
   64 static inline int
   65 vpdnext(vpdbuf_t *vpd)
   66 {
   67         int rc = -1;
   68         if (vpd->offset < vpd->length) {
   69                 rc = vpd->buffer[vpd->offset++];
   70                 vpd->checksum += rc;
   71         }
   72         return rc;
   73 }
   74 
   75 /**
   76  * @brief return true if no more vpd buffer data
   77  *
   78  * return true if the vpd buffer data has been completely consumed
   79  *
   80  * @param vpd pointer to vpd buffer
   81  *
   82  * @return returns true if no more data
   83  *
   84  */
   85 static inline int
   86 vpddone(vpdbuf_t *vpd)
   87 {
   88         return vpd->offset >= vpd->length;
   89 }
   90 /**
   91  * @brief return pointer to current VPD data location
   92  *
   93  * Returns a pointer to the current location in the VPD data
   94  *
   95  * @param vpd pointer to vpd buffer
   96  *
   97  * @return pointer to current VPD data location
   98  */
   99 
  100 static inline uint8_t *
  101 vpdref(vpdbuf_t *vpd)
  102 {
  103         return &vpd->buffer[vpd->offset];
  104 }
  105 
  106 #define VPD_LARGE_RESOURCE_TYPE_ID_STRING_TAG   0x82
  107 #define VPD_LARGE_RESOURCE_TYPE_R_TAG           0x90
  108 #define VPD_LARGE_RESOURCE_TYPE_W_TAG           0x91
  109 #define VPD_SMALL_RESOURCE_TYPE_END_TAG         0x78
  110 
  111 /**
  112  * @brief find a VPD entry
  113  *
  114  * Finds a VPD entry given the two character code
  115  *
  116  * @param vpddata pointer to raw vpd data buffer
  117  * @param vpddata_length length of vpddata buffer in bytes
  118  * @param key key to look up
  119 
  120  * @return returns a pointer to the key location or NULL if not found or checksum error
  121  */
  122 
  123 static inline uint8_t *
  124 ocs_find_vpd(uint8_t *vpddata, uint32_t vpddata_length, const char *key)
  125 {
  126         vpdbuf_t vpdbuf;
  127         uint8_t *pret = NULL;
  128         uint8_t c0 = key[0];
  129         uint8_t c1 = key[1];
  130 
  131         vpdbuf.buffer = (uint8_t*) vpddata;
  132         vpdbuf.length = vpddata_length;
  133         vpdbuf.offset = 0;
  134         vpdbuf.checksum = 0;
  135 
  136         while (!vpddone(&vpdbuf)) {
  137                 int type = vpdnext(&vpdbuf);
  138                 int len_lo;
  139                 int len_hi;
  140                 int len;
  141                 int i;
  142 
  143                 if (type == VPD_SMALL_RESOURCE_TYPE_END_TAG) {
  144                         break;
  145                 }
  146 
  147                 len_lo = vpdnext(&vpdbuf);
  148                 len_hi = vpdnext(&vpdbuf);
  149                 len = len_lo + (len_hi << 8);
  150 
  151                 if ((type == VPD_LARGE_RESOURCE_TYPE_R_TAG) || (type == VPD_LARGE_RESOURCE_TYPE_W_TAG)) {
  152                         while (len > 0) {
  153                                 int rc0;
  154                                 int rc1;
  155                                 int sublen;
  156                                 uint8_t *pstart;
  157 
  158                                 rc0 = vpdnext(&vpdbuf);
  159                                 rc1 = vpdnext(&vpdbuf);
  160 
  161                                 /* Mark this location */
  162                                 pstart = vpdref(&vpdbuf);
  163 
  164                                 sublen = vpdnext(&vpdbuf);
  165 
  166                                 /* Adjust remaining len */
  167                                 len -= (sublen + 3);
  168 
  169                                 /* check for match with request */
  170                                 if ((c0 == rc0) && (c1 == rc1)) {
  171                                         pret = pstart;
  172                                         for (i = 0; i < sublen; i++) {
  173                                                 vpdnext(&vpdbuf);
  174                                         }
  175                                 /* check for "RV" end */
  176                                 } else if ('R' == rc0 && 'V' == rc1) {
  177                                         /* Read the checksum */
  178                                         for (i = 0; i < sublen; i++) {
  179                                                 vpdnext(&vpdbuf);
  180                                         }
  181 
  182                                         /* The accumulated checksum should be zero here */
  183                                         if (vpdbuf.checksum != 0) {
  184                                                 ocs_log_test(NULL, "checksum error\n");
  185                                                 return NULL;
  186                                         }
  187                                 }
  188                                 else
  189                                         for (i = 0; i < sublen; i++) {
  190                                                 vpdnext(&vpdbuf);
  191                                         }
  192                         }
  193                 }
  194 
  195                 for (i = 0; i < len; i++) {
  196                         vpdnext(&vpdbuf);
  197                 }
  198         }
  199 
  200         return pret;
  201 }
  202 #endif 

Cache object: 3dfdb71eff8caf9cd044c3f58ad62ac8


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.