Emulex Logo
OneCoreā„¢ Storage SDK Release 11.2
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ocs_vpd.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2015, Emulex
3  * All rights reserved.
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  */
32 
33 /**
34  * @file
35  * OCS VPD parser
36  */
37 
38 #if !defined(__OCS_VPD_H__)
39 #define __OCS_VPD_H__
40 
41 /**
42  * @brief VPD buffer structure
43  */
44 
45 typedef struct {
46  uint8_t *buffer;
47  uint32_t length;
48  uint32_t offset;
49  uint8_t checksum;
50  } vpdbuf_t;
51 
52 /**
53  * @brief return next VPD byte
54  *
55  * Returns next VPD byte and updates accumulated checksum
56  *
57  * @param vpd pointer to vpd buffer
58  *
59  * @return returns next byte for success, or a negative error code value for failure.
60  *
61  */
62 
63 static inline int
65 {
66  int rc = -1;
67  if (vpd->offset < vpd->length) {
68  rc = vpd->buffer[vpd->offset++];
69  vpd->checksum += rc;
70  }
71  return rc;
72 }
73 
74 /**
75  * @brief return true if no more vpd buffer data
76  *
77  * return true if the vpd buffer data has been completely consumed
78  *
79  * @param vpd pointer to vpd buffer
80  *
81  * @return returns true if no more data
82  *
83  */
84 static inline int
86 {
87  return vpd->offset >= vpd->length;
88 }
89 /**
90  * @brief return pointer to current VPD data location
91  *
92  * Returns a pointer to the current location in the VPD data
93  *
94  * @param vpd pointer to vpd buffer
95  *
96  * @return pointer to current VPD data location
97  */
98 
99 static inline uint8_t *
101 {
102  return &vpd->buffer[vpd->offset];
103 }
104 
105 #define VPD_LARGE_RESOURCE_TYPE_ID_STRING_TAG 0x82
106 #define VPD_LARGE_RESOURCE_TYPE_R_TAG 0x90
107 #define VPD_LARGE_RESOURCE_TYPE_W_TAG 0x91
108 #define VPD_SMALL_RESOURCE_TYPE_END_TAG 0x78
109 
110 /**
111  * @brief find a VPD entry
112  *
113  * Finds a VPD entry given the two character code
114  *
115  * @param vpddata pointer to raw vpd data buffer
116  * @param vpddata_length length of vpddata buffer in bytes
117  * @param key key to look up
118 
119  * @return returns a pointer to the key location or NULL if not found or checksum error
120  */
121 
122 static inline uint8_t *
123 ocs_find_vpd(uint8_t *vpddata, uint32_t vpddata_length, const char *key)
124 {
125  vpdbuf_t vpdbuf;
126  uint8_t *pret = NULL;
127  uint8_t c0 = key[0];
128  uint8_t c1 = key[1];
129 
130  vpdbuf.buffer = (uint8_t*) vpddata;
131  vpdbuf.length = vpddata_length;
132  vpdbuf.offset = 0;
133  vpdbuf.checksum = 0;
134 
135  while (!vpddone(&vpdbuf)) {
136  int type = vpdnext(&vpdbuf);
137  int len_lo;
138  int len_hi;
139  int len;
140  int i;
141 
142  if (type == VPD_SMALL_RESOURCE_TYPE_END_TAG) {
143  break;
144  }
145 
146  len_lo = vpdnext(&vpdbuf);
147  len_hi = vpdnext(&vpdbuf);
148  len = len_lo + (len_hi << 8);
149 
151  while (len > 0) {
152  int rc0;
153  int rc1;
154  int sublen;
155  uint8_t *pstart;
156 
157  rc0 = vpdnext(&vpdbuf);
158  rc1 = vpdnext(&vpdbuf);
159 
160  /* Mark this location */
161  pstart = vpdref(&vpdbuf);
162 
163  sublen = vpdnext(&vpdbuf);
164 
165  /* Adjust remaining len */
166  len -= (sublen + 3);
167 
168  /* check for match with request */
169  if ((c0 == rc0) && (c1 == rc1)) {
170  pret = pstart;
171  for (i = 0; i < sublen; i++) {
172  vpdnext(&vpdbuf);
173  }
174  /* check for "RV" end */
175  } else if ('R' == rc0 && 'V' == rc1) {
176 
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 // __OCS_VPD_H__
#define VPD_SMALL_RESOURCE_TYPE_END_TAG
Definition: ocs_vpd.h:108
uint32_t offset
Definition: ocs_vpd.h:48
static int vpdnext(vpdbuf_t *vpd)
return next VPD byte
Definition: ocs_vpd.h:64
VPD buffer structure.
Definition: ocs_vpd.h:45
static uint8_t * ocs_find_vpd(uint8_t *vpddata, uint32_t vpddata_length, const char *key)
find a VPD entry
Definition: ocs_vpd.h:123
static int vpddone(vpdbuf_t *vpd)
return true if no more vpd buffer data
Definition: ocs_vpd.h:85
#define VPD_LARGE_RESOURCE_TYPE_R_TAG
Definition: ocs_vpd.h:106
uint32_t length
Definition: ocs_vpd.h:47
uint8_t * buffer
Definition: ocs_vpd.h:46
#define VPD_LARGE_RESOURCE_TYPE_W_TAG
Definition: ocs_vpd.h:107
uint8_t checksum
Definition: ocs_vpd.h:49
static uint8_t * vpdref(vpdbuf_t *vpd)
return pointer to current VPD data location
Definition: ocs_vpd.h:100