2 * Copyright (c) 1998,1999,2000
3 * Traakan, Inc., Los Altos, CA
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice unmodified, this list of conditions, and the following
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41 #define WITH(P,V,T) { T * V = (T *) P;
45 smc_parse_volume_tag (
46 struct smc_raw_volume_tag *raw,
47 struct smc_volume_tag *vtag)
51 bzero (vtag, sizeof *vtag);
53 for (i = 31; i >= 0 && raw->volume_id[i] == ' '; i--)
57 vtag->volume_id[i] = raw->volume_id[i];
59 vtag->volume_seq = SMC_GET2(raw->volume_seq);
67 smc_parse_element_status_data (
70 struct smc_element_descriptor elem_desc[],
71 unsigned max_elem_desc)
73 unsigned char * p = (unsigned char *)raw;
74 unsigned char * raw_end = p + raw_len;
75 unsigned int n_elem = 0;
77 bzero (elem_desc, sizeof elem_desc[0] * max_elem_desc);
79 WITH(p, esdh, struct smc_raw_element_status_data_header)
80 unsigned byte_count = SMC_GET3(esdh->byte_count);
82 if (raw_len > byte_count+8) {
83 /* probably an error, but press on */
84 raw_len = byte_count+8;
86 raw_end = p + raw_len;
91 while (p+8 < raw_end) { /* +8 for sizeof *esph */
92 WITH(p, esph, struct smc_raw_element_status_page_header)
93 unsigned desc_size = SMC_GET2(esph->elem_desc_len);
94 unsigned byte_count = SMC_GET3(esph->byte_count);
95 unsigned elem_type = esph->element_type;
96 unsigned char * pgend = p + byte_count + 8;
100 if (pgend > raw_end) {
101 /* malformed, really, but punt */
105 if (esph->flag1 & SMC_RAW_ESP_F1_PVolTag)
107 if (esph->flag1 & SMC_RAW_ESP_F1_AVolTag)
112 for (;p + desc_size <= pgend; p += desc_size) {
113 struct smc_element_descriptor *edp;
115 if (n_elem >= max_elem_desc) {
119 edp = &elem_desc[n_elem++];
120 WITH (p, red, struct smc_raw_element_descriptor)
123 edp->element_type_code = elem_type;
124 edp->element_address = SMC_GET2(red->element_address);
125 edp->PVolTag = PVolTag;
126 edp->AVolTag = AVolTag;
127 #define FLAG(RAWMEM,BIT,MEM) if (red->RAWMEM & BIT) edp->MEM = 1;
128 FLAG(flags2, SMC_RAW_ED_F2_Full, Full);
129 FLAG(flags2, SMC_RAW_ED_F2_ImpExp, ImpExp);
130 FLAG(flags2, SMC_RAW_ED_F2_Except, Except);
131 FLAG(flags2, SMC_RAW_ED_F2_Access, Access);
132 FLAG(flags2, SMC_RAW_ED_F2_ExEnab, ExEnab);
133 FLAG(flags2, SMC_RAW_ED_F2_InEnab, InEnab);
136 edp->ascq = red->ascq;
138 edp->scsi_lun = red->flags6 & 7;
139 FLAG(flags6, SMC_RAW_ED_F6_LU_valid, LU_valid);
140 FLAG(flags6, SMC_RAW_ED_F6_ID_valid, ID_valid);
141 FLAG(flags6, SMC_RAW_ED_F6_Not_bus, Not_bus);
143 edp->scsi_sid = red->scsi_sid;
145 FLAG(flags9, SMC_RAW_ED_F9_Invert, Invert);
146 FLAG(flags9, SMC_RAW_ED_F9_SValid, SValid);
149 edp->src_se_addr = SMC_GET2(red->src_se_addr);
151 p2 = (unsigned char *) &red->primary_vol_tag;
153 smc_parse_volume_tag ((void*)p2,
154 &edp->primary_vol_tag);
155 p2 += SMC_VOL_TAG_LEN;
158 smc_parse_volume_tag ((void*)p2,
159 &edp->alternate_vol_tag);
160 p2 += SMC_VOL_TAG_LEN;
162 p2 += 4; /* resv84 */
163 /* p2 ready for vendor_specific */
177 smc_parse_element_address_assignment (
178 struct smc_raw_element_address_assignment_page *raw,
179 struct smc_element_address_assignment *eaa)
181 eaa->mte_addr = SMC_GET2(raw->mte_addr);
182 eaa->mte_count = SMC_GET2(raw->mte_count);
183 eaa->se_addr = SMC_GET2(raw->se_addr);
184 eaa->se_count = SMC_GET2(raw->se_count);
185 eaa->iee_addr = SMC_GET2(raw->iee_addr);
186 eaa->iee_count = SMC_GET2(raw->iee_count);
187 eaa->dte_addr = SMC_GET2(raw->dte_addr);
188 eaa->dte_count = SMC_GET2(raw->dte_count);