1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate /* 30*7c478bd9Sstevel@tonic-gate * This file contains the tuple handlers that are called by the CIS 31*7c478bd9Sstevel@tonic-gate * parser. 32*7c478bd9Sstevel@tonic-gate * 33*7c478bd9Sstevel@tonic-gate * XXX - how about a better explaination?? 34*7c478bd9Sstevel@tonic-gate */ 35*7c478bd9Sstevel@tonic-gate 36*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 37*7c478bd9Sstevel@tonic-gate #include <sys/systm.h> 38*7c478bd9Sstevel@tonic-gate #include <sys/user.h> 39*7c478bd9Sstevel@tonic-gate #include <sys/buf.h> 40*7c478bd9Sstevel@tonic-gate #include <sys/file.h> 41*7c478bd9Sstevel@tonic-gate #include <sys/uio.h> 42*7c478bd9Sstevel@tonic-gate #include <sys/conf.h> 43*7c478bd9Sstevel@tonic-gate #include <sys/stat.h> 44*7c478bd9Sstevel@tonic-gate #include <sys/autoconf.h> 45*7c478bd9Sstevel@tonic-gate #include <sys/vtoc.h> 46*7c478bd9Sstevel@tonic-gate #include <sys/dkio.h> 47*7c478bd9Sstevel@tonic-gate #include <sys/ddi.h> 48*7c478bd9Sstevel@tonic-gate #include <sys/sunddi.h> 49*7c478bd9Sstevel@tonic-gate #include <sys/debug.h> 50*7c478bd9Sstevel@tonic-gate #include <sys/ddi_impldefs.h> 51*7c478bd9Sstevel@tonic-gate #include <sys/kstat.h> 52*7c478bd9Sstevel@tonic-gate #include <sys/kmem.h> 53*7c478bd9Sstevel@tonic-gate #include <sys/modctl.h> 54*7c478bd9Sstevel@tonic-gate #include <sys/kobj.h> 55*7c478bd9Sstevel@tonic-gate #include <sys/callb.h> 56*7c478bd9Sstevel@tonic-gate 57*7c478bd9Sstevel@tonic-gate #include <sys/pctypes.h> 58*7c478bd9Sstevel@tonic-gate #include <pcmcia/sys/cs_types.h> 59*7c478bd9Sstevel@tonic-gate #include <pcmcia/sys/cis.h> 60*7c478bd9Sstevel@tonic-gate #include <pcmcia/sys/cis_handlers.h> 61*7c478bd9Sstevel@tonic-gate #include <pcmcia/sys/cs.h> 62*7c478bd9Sstevel@tonic-gate #include <pcmcia/sys/cs_priv.h> 63*7c478bd9Sstevel@tonic-gate #include <pcmcia/sys/cis_protos.h> 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate /* 66*7c478bd9Sstevel@tonic-gate * Function prototypes 67*7c478bd9Sstevel@tonic-gate */ 68*7c478bd9Sstevel@tonic-gate static void cistpl_pd_parse(cistpl_t *, cistpl_cftable_entry_pwr_t *); 69*7c478bd9Sstevel@tonic-gate static void cis_return_name(cistpl_callout_t *, cistpl_get_tuple_name_t *); 70*7c478bd9Sstevel@tonic-gate 71*7c478bd9Sstevel@tonic-gate /* 72*7c478bd9Sstevel@tonic-gate * cis_tuple_handler - call the handler for the tuple described by the 73*7c478bd9Sstevel@tonic-gate * tuple pointer 74*7c478bd9Sstevel@tonic-gate * 75*7c478bd9Sstevel@tonic-gate * cistpl_callout_t *co - pointer to callout structure 76*7c478bd9Sstevel@tonic-gate * array to use to find this tuple 77*7c478bd9Sstevel@tonic-gate * cistpl_t *tp - pointer to a tuple structure 78*7c478bd9Sstevel@tonic-gate * int flags - action for the handler to perform 79*7c478bd9Sstevel@tonic-gate * XXX - we need a description of the flags passed to the tuple handler 80*7c478bd9Sstevel@tonic-gate * void *arg - argument to pass on to tuple handler 81*7c478bd9Sstevel@tonic-gate * 82*7c478bd9Sstevel@tonic-gate * If the tuple is not recognized but is is a vendor-specific tuple, we 83*7c478bd9Sstevel@tonic-gate * set the CISTPLF_VENDOR_SPECIFIC flag in the tuple. 84*7c478bd9Sstevel@tonic-gate * 85*7c478bd9Sstevel@tonic-gate * We return CISTPLF_UNKNOWN if this is an unrecognized tuple as well as 86*7c478bd9Sstevel@tonic-gate * set the CISTPLF_UNKNOWN flag in the tuple list structure. Note 87*7c478bd9Sstevel@tonic-gate * that encountering an unknown tuple is not necessarily an error, 88*7c478bd9Sstevel@tonic-gate * so we don't set the HANDTPL_ERROR flag on the return code. It 89*7c478bd9Sstevel@tonic-gate * is up to the caller to determine what an unrecognized tuple means. 90*7c478bd9Sstevel@tonic-gate * 91*7c478bd9Sstevel@tonic-gate * If this is a recognized tuple, the apropriate tuple handler is called and 92*7c478bd9Sstevel@tonic-gate * the return value from the handler is returned directly to the caller. 93*7c478bd9Sstevel@tonic-gate * 94*7c478bd9Sstevel@tonic-gate * The void *arg is optional, and it's meaning is dependent on the 95*7c478bd9Sstevel@tonic-gate * particular tuple handler called and the flags parameter. 96*7c478bd9Sstevel@tonic-gate * 97*7c478bd9Sstevel@tonic-gate * For the special case of HANDTPL_RETURN_NAME, we don't bother calling the 98*7c478bd9Sstevel@tonic-gate * tuple handler and just return the tuple name to the caller. 99*7c478bd9Sstevel@tonic-gate */ 100*7c478bd9Sstevel@tonic-gate uint32_t 101*7c478bd9Sstevel@tonic-gate cis_tuple_handler(cistpl_callout_t *co, cistpl_t *tp, uint32_t flags, 102*7c478bd9Sstevel@tonic-gate void *arg, cisdata_t subtype) 103*7c478bd9Sstevel@tonic-gate { 104*7c478bd9Sstevel@tonic-gate /* 105*7c478bd9Sstevel@tonic-gate * Check to see if this is a vendor-specific tuple. 106*7c478bd9Sstevel@tonic-gate */ 107*7c478bd9Sstevel@tonic-gate if (CISTPL_IS_VENDOR_SPECIFIC(tp->type)) 108*7c478bd9Sstevel@tonic-gate tp->flags |= CISTPLF_VENDOR_SPECIFIC; 109*7c478bd9Sstevel@tonic-gate 110*7c478bd9Sstevel@tonic-gate /* 111*7c478bd9Sstevel@tonic-gate * Scan the callout list until we find the tuple passed to us, or we 112*7c478bd9Sstevel@tonic-gate * encounter a CISTPL_END in the callout list, which signals that 113*7c478bd9Sstevel@tonic-gate * there are no more tuples in the callout list. 114*7c478bd9Sstevel@tonic-gate */ 115*7c478bd9Sstevel@tonic-gate while (co->type != (cisdata_t)CISTPL_END) { 116*7c478bd9Sstevel@tonic-gate if (co->type == tp->type && 117*7c478bd9Sstevel@tonic-gate ((tp->type != CISTPL_FUNCE) || 118*7c478bd9Sstevel@tonic-gate (tp->type == CISTPL_FUNCE && co->subtype == subtype))) { 119*7c478bd9Sstevel@tonic-gate tp->flags &= ~CISTPLF_UNKNOWN; 120*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_RETURN_NAME) { 121*7c478bd9Sstevel@tonic-gate cis_return_name(co, (cistpl_get_tuple_name_t *)arg); 122*7c478bd9Sstevel@tonic-gate return (CISTPLF_NOERROR); 123*7c478bd9Sstevel@tonic-gate } else { 124*7c478bd9Sstevel@tonic-gate return ((*co->handler) (co, tp, flags, arg)); 125*7c478bd9Sstevel@tonic-gate } /* HANDTPL_RETURN_NAME */ 126*7c478bd9Sstevel@tonic-gate } /* if */ 127*7c478bd9Sstevel@tonic-gate co++; 128*7c478bd9Sstevel@tonic-gate } /* while */ 129*7c478bd9Sstevel@tonic-gate 130*7c478bd9Sstevel@tonic-gate /* 131*7c478bd9Sstevel@tonic-gate * If we didn't recognize the tuple and the caller wants the tuple 132*7c478bd9Sstevel@tonic-gate * name back, then return the "unknown tuple" string. At this 133*7c478bd9Sstevel@tonic-gate * point, "co" will be pointing to the last entry in the 134*7c478bd9Sstevel@tonic-gate * callout list. It's not an error to not recognize the tuple 135*7c478bd9Sstevel@tonic-gate * when the operation is HANDTPL_RETURN_NAME. 136*7c478bd9Sstevel@tonic-gate */ 137*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_RETURN_NAME) { 138*7c478bd9Sstevel@tonic-gate cis_return_name(co, (cistpl_get_tuple_name_t *)arg); 139*7c478bd9Sstevel@tonic-gate return (CISTPLF_NOERROR); 140*7c478bd9Sstevel@tonic-gate } 141*7c478bd9Sstevel@tonic-gate 142*7c478bd9Sstevel@tonic-gate tp->flags |= CISTPLF_UNKNOWN; 143*7c478bd9Sstevel@tonic-gate return (CISTPLF_UNKNOWN); 144*7c478bd9Sstevel@tonic-gate } 145*7c478bd9Sstevel@tonic-gate 146*7c478bd9Sstevel@tonic-gate /* 147*7c478bd9Sstevel@tonic-gate * cis_no_tuple_handler - this generic tuple handler is used if no special 148*7c478bd9Sstevel@tonic-gate * tuple processing is required for the passed 149*7c478bd9Sstevel@tonic-gate * tuple 150*7c478bd9Sstevel@tonic-gate * 151*7c478bd9Sstevel@tonic-gate * cistpl_callout_t *co - pointer to this tuple's entry in the 152*7c478bd9Sstevel@tonic-gate * tuple callout structure 153*7c478bd9Sstevel@tonic-gate * cistpl_t *tp - pointer to this tuple's entry in the local linked list 154*7c478bd9Sstevel@tonic-gate * int flags - action to perform 155*7c478bd9Sstevel@tonic-gate * 156*7c478bd9Sstevel@tonic-gate * This handler will set the CISTPLF_COPYOK flag if the tuple link is greater 157*7c478bd9Sstevel@tonic-gate * than zero, indicating that it's OK to copy the tuple data body. It 158*7c478bd9Sstevel@tonic-gate * will also set whatever flags are specified in the callout structure. 159*7c478bd9Sstevel@tonic-gate * 160*7c478bd9Sstevel@tonic-gate * We always set the CISTPLF_VALID when we're called with HANDTPL_COPY_DONE. 161*7c478bd9Sstevel@tonic-gate * 162*7c478bd9Sstevel@tonic-gate * We return CISTPLF_UNKNOWN if we're being called to parse the tuple. 163*7c478bd9Sstevel@tonic-gate * 164*7c478bd9Sstevel@tonic-gate * We return CISTPLF_NOERROR in every other case to indicate that this is a 165*7c478bd9Sstevel@tonic-gate * recognized tuple. 166*7c478bd9Sstevel@tonic-gate */ 167*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 168*7c478bd9Sstevel@tonic-gate uint32_t 169*7c478bd9Sstevel@tonic-gate cis_no_tuple_handler(cistpl_callout_t *co, cistpl_t *tp, 170*7c478bd9Sstevel@tonic-gate uint32_t flags, void *arg) 171*7c478bd9Sstevel@tonic-gate { 172*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_SET_FLAGS) { 173*7c478bd9Sstevel@tonic-gate tp->flags |= co->flags; /* XXX - is = the right thing here? */ 174*7c478bd9Sstevel@tonic-gate if (tp->len > 0) 175*7c478bd9Sstevel@tonic-gate tp->flags |= CISTPLF_COPYOK; 176*7c478bd9Sstevel@tonic-gate } 177*7c478bd9Sstevel@tonic-gate 178*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_COPY_DONE) 179*7c478bd9Sstevel@tonic-gate tp->flags |= CISTPLF_VALID; 180*7c478bd9Sstevel@tonic-gate 181*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_PARSE_LTUPLE) 182*7c478bd9Sstevel@tonic-gate return (CISTPLF_UNKNOWN); 183*7c478bd9Sstevel@tonic-gate 184*7c478bd9Sstevel@tonic-gate return (CISTPLF_NOERROR); 185*7c478bd9Sstevel@tonic-gate } 186*7c478bd9Sstevel@tonic-gate 187*7c478bd9Sstevel@tonic-gate /* 188*7c478bd9Sstevel@tonic-gate * cis_unknown_tuple_handler - this generic tuple handler is used if we don't 189*7c478bd9Sstevel@tonic-gate * understand this tuple 190*7c478bd9Sstevel@tonic-gate * 191*7c478bd9Sstevel@tonic-gate * cistpl_callout_t *co - pointer to this tuple's entry in the 192*7c478bd9Sstevel@tonic-gate * tuple callout structure 193*7c478bd9Sstevel@tonic-gate * cistpl_t *tp - pointer to this tuple's entry in the local linked list 194*7c478bd9Sstevel@tonic-gate * int flags - action to perform 195*7c478bd9Sstevel@tonic-gate * 196*7c478bd9Sstevel@tonic-gate * This handler will not set the CISTPLF_COPYOK flag since we don't know the 197*7c478bd9Sstevel@tonic-gate * contents of a vendor-specific tuple. 198*7c478bd9Sstevel@tonic-gate * 199*7c478bd9Sstevel@tonic-gate * We always set the CISTPLF_VALID when we're called with HANDTPL_COPY_DONE 200*7c478bd9Sstevel@tonic-gate * to specify that we understand this tuple's code, but not it's data 201*7c478bd9Sstevel@tonic-gate * body. 202*7c478bd9Sstevel@tonic-gate * 203*7c478bd9Sstevel@tonic-gate * We return CISTPLF_UNKNOWN if we're being called to parse the tuple or to 204*7c478bd9Sstevel@tonic-gate * perform any other operation. 205*7c478bd9Sstevel@tonic-gate */ 206*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 207*7c478bd9Sstevel@tonic-gate uint32_t 208*7c478bd9Sstevel@tonic-gate cis_unknown_tuple_handler(cistpl_callout_t *co, cistpl_t *tp, 209*7c478bd9Sstevel@tonic-gate uint32_t flags, void *arg) 210*7c478bd9Sstevel@tonic-gate { 211*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_SET_FLAGS) { 212*7c478bd9Sstevel@tonic-gate tp->flags |= co->flags; /* XXX - is = the right thing here? */ 213*7c478bd9Sstevel@tonic-gate return (CISTPLF_NOERROR); 214*7c478bd9Sstevel@tonic-gate } 215*7c478bd9Sstevel@tonic-gate 216*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_COPY_DONE) { 217*7c478bd9Sstevel@tonic-gate tp->flags |= CISTPLF_VALID; 218*7c478bd9Sstevel@tonic-gate return (CISTPLF_NOERROR); 219*7c478bd9Sstevel@tonic-gate } 220*7c478bd9Sstevel@tonic-gate 221*7c478bd9Sstevel@tonic-gate return (CISTPLF_UNKNOWN); 222*7c478bd9Sstevel@tonic-gate } 223*7c478bd9Sstevel@tonic-gate 224*7c478bd9Sstevel@tonic-gate /* 225*7c478bd9Sstevel@tonic-gate * cistpl_vers_1_handler - handler for the CISTPL_VERS_1 tuple 226*7c478bd9Sstevel@tonic-gate * 227*7c478bd9Sstevel@tonic-gate * void *arg - points to a cistpl_vers_1_t * where the 228*7c478bd9Sstevel@tonic-gate * information is stuffed into 229*7c478bd9Sstevel@tonic-gate */ 230*7c478bd9Sstevel@tonic-gate uint32_t 231*7c478bd9Sstevel@tonic-gate cistpl_vers_1_handler(cistpl_callout_t *co, cistpl_t *tp, 232*7c478bd9Sstevel@tonic-gate uint32_t flags, void *arg) 233*7c478bd9Sstevel@tonic-gate { 234*7c478bd9Sstevel@tonic-gate /* 235*7c478bd9Sstevel@tonic-gate * nothing special about our flags, so just call the 236*7c478bd9Sstevel@tonic-gate * generic handler for this 237*7c478bd9Sstevel@tonic-gate */ 238*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_SET_FLAGS) 239*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 240*7c478bd9Sstevel@tonic-gate 241*7c478bd9Sstevel@tonic-gate /* 242*7c478bd9Sstevel@tonic-gate * We don't currently validate this tuple. This call will 243*7c478bd9Sstevel@tonic-gate * always set tp->flags |= CISTPLF_VALID. 244*7c478bd9Sstevel@tonic-gate */ 245*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_COPY_DONE) 246*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 247*7c478bd9Sstevel@tonic-gate 248*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_PARSE_LTUPLE) { 249*7c478bd9Sstevel@tonic-gate cistpl_vers_1_t *cs = (cistpl_vers_1_t *)arg; 250*7c478bd9Sstevel@tonic-gate 251*7c478bd9Sstevel@tonic-gate 252*7c478bd9Sstevel@tonic-gate RESET_TP(tp); 253*7c478bd9Sstevel@tonic-gate 254*7c478bd9Sstevel@tonic-gate cs->major = GET_BYTE(tp); 255*7c478bd9Sstevel@tonic-gate cs->minor = GET_BYTE(tp); 256*7c478bd9Sstevel@tonic-gate for (cs->ns = 0; GET_LEN(tp) > 0 && 257*7c478bd9Sstevel@tonic-gate /* CSTYLED */ 258*7c478bd9Sstevel@tonic-gate cs->ns < CISTPL_VERS_1_MAX_PROD_STRINGS; ) { 259*7c478bd9Sstevel@tonic-gate (void) strcpy(cs->pi[cs->ns++], cis_getstr(tp)); 260*7c478bd9Sstevel@tonic-gate } /* for */ 261*7c478bd9Sstevel@tonic-gate } /* HANDTPL_PARSE_LTUPLE */ 262*7c478bd9Sstevel@tonic-gate 263*7c478bd9Sstevel@tonic-gate return (CISTPLF_NOERROR); 264*7c478bd9Sstevel@tonic-gate } 265*7c478bd9Sstevel@tonic-gate 266*7c478bd9Sstevel@tonic-gate /* 267*7c478bd9Sstevel@tonic-gate * cistpl_config_handler - handler for the CISTPL_CONFIG tuple 268*7c478bd9Sstevel@tonic-gate * 269*7c478bd9Sstevel@tonic-gate * void *arg - points to a XXX where the information is stuffed into 270*7c478bd9Sstevel@tonic-gate * 271*7c478bd9Sstevel@tonic-gate * For the first ten config registers we set the present flags in the 272*7c478bd9Sstevel@tonic-gate * cistpl_config_t if the register exists. The flags that we use 273*7c478bd9Sstevel@tonic-gate * for this are the same as the flags reguired for the Card Services 274*7c478bd9Sstevel@tonic-gate * RequestConfiguration function and they can be used by clients 275*7c478bd9Sstevel@tonic-gate * directly without requiring any remapping of values. 276*7c478bd9Sstevel@tonic-gate * 277*7c478bd9Sstevel@tonic-gate * XXX we don't handle TPCC_SBTPL subtuples yet 278*7c478bd9Sstevel@tonic-gate */ 279*7c478bd9Sstevel@tonic-gate 280*7c478bd9Sstevel@tonic-gate uint32_t config_regs_present_map[] = { 281*7c478bd9Sstevel@tonic-gate CONFIG_OPTION_REG_PRESENT, /* COR present */ 282*7c478bd9Sstevel@tonic-gate CONFIG_STATUS_REG_PRESENT, /* STAT reg present */ 283*7c478bd9Sstevel@tonic-gate CONFIG_PINREPL_REG_PRESENT, /* PRR present */ 284*7c478bd9Sstevel@tonic-gate CONFIG_COPY_REG_PRESENT, /* COPY reg present */ 285*7c478bd9Sstevel@tonic-gate CONFIG_EXSTAT_REG_PRESENT, /* EXSTAT reg present */ 286*7c478bd9Sstevel@tonic-gate CONFIG_IOBASE0_REG_PRESENT, /* IOBASE0 reg present */ 287*7c478bd9Sstevel@tonic-gate CONFIG_IOBASE1_REG_PRESENT, /* IOBASE1 reg present */ 288*7c478bd9Sstevel@tonic-gate CONFIG_IOBASE2_REG_PRESENT, /* IOBASE2 reg present */ 289*7c478bd9Sstevel@tonic-gate CONFIG_IOBASE3_REG_PRESENT, /* IOBASE3 reg present */ 290*7c478bd9Sstevel@tonic-gate CONFIG_IOLIMIT_REG_PRESENT, /* IOLIMIT reg present */ 291*7c478bd9Sstevel@tonic-gate }; 292*7c478bd9Sstevel@tonic-gate 293*7c478bd9Sstevel@tonic-gate uint32_t 294*7c478bd9Sstevel@tonic-gate cistpl_config_handler(cistpl_callout_t *co, cistpl_t *tp, 295*7c478bd9Sstevel@tonic-gate uint32_t flags, void *arg) 296*7c478bd9Sstevel@tonic-gate { 297*7c478bd9Sstevel@tonic-gate cisdata_t tpcc_sz; 298*7c478bd9Sstevel@tonic-gate int i, n, nrb, na, hr = 0; 299*7c478bd9Sstevel@tonic-gate 300*7c478bd9Sstevel@tonic-gate /* 301*7c478bd9Sstevel@tonic-gate * nothing special about our flags, so just call the 302*7c478bd9Sstevel@tonic-gate * generic handler for this 303*7c478bd9Sstevel@tonic-gate */ 304*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_SET_FLAGS) 305*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 306*7c478bd9Sstevel@tonic-gate 307*7c478bd9Sstevel@tonic-gate /* 308*7c478bd9Sstevel@tonic-gate * We don't currently validate this tuple. This call will 309*7c478bd9Sstevel@tonic-gate * always set tp->flags |= CISTPLF_VALID. 310*7c478bd9Sstevel@tonic-gate */ 311*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_COPY_DONE) 312*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 313*7c478bd9Sstevel@tonic-gate 314*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_PARSE_LTUPLE) { 315*7c478bd9Sstevel@tonic-gate cistpl_config_t *cr = (cistpl_config_t *)arg; 316*7c478bd9Sstevel@tonic-gate int crn = 0; 317*7c478bd9Sstevel@tonic-gate 318*7c478bd9Sstevel@tonic-gate RESET_TP(tp); 319*7c478bd9Sstevel@tonic-gate 320*7c478bd9Sstevel@tonic-gate tpcc_sz = GET_BYTE(tp); /* config regs size fields */ 321*7c478bd9Sstevel@tonic-gate cr->last = GET_BYTE(tp); /* last config index */ 322*7c478bd9Sstevel@tonic-gate 323*7c478bd9Sstevel@tonic-gate na = (tpcc_sz&3)+1; /* config regs address bytes */ 324*7c478bd9Sstevel@tonic-gate nrb = ((tpcc_sz>>2)&0x0f)+1; /* number of bytes in config */ 325*7c478bd9Sstevel@tonic-gate /* regs presence mask */ 326*7c478bd9Sstevel@tonic-gate 327*7c478bd9Sstevel@tonic-gate /* 328*7c478bd9Sstevel@tonic-gate * Construct the base offset address for the config registers. 329*7c478bd9Sstevel@tonic-gate * We jump through these hoops because the base address 330*7c478bd9Sstevel@tonic-gate * can be between one and four bytes in length. 331*7c478bd9Sstevel@tonic-gate */ 332*7c478bd9Sstevel@tonic-gate cr->base = 0; 333*7c478bd9Sstevel@tonic-gate n = na; 334*7c478bd9Sstevel@tonic-gate while (n--) 335*7c478bd9Sstevel@tonic-gate cr->base |= ((GET_BYTE(tp) & 0x0ff) << 336*7c478bd9Sstevel@tonic-gate (8 * (na - (n+1)))); 337*7c478bd9Sstevel@tonic-gate 338*7c478bd9Sstevel@tonic-gate /* 339*7c478bd9Sstevel@tonic-gate * Go through the config register presense mask bit by bit and 340*7c478bd9Sstevel@tonic-gate * figure out which config registers are present and which 341*7c478bd9Sstevel@tonic-gate * aren't. 342*7c478bd9Sstevel@tonic-gate * For the first ten config registers, set the appropriate 343*7c478bd9Sstevel@tonic-gate * bits in the cr->present member so that the caller 344*7c478bd9Sstevel@tonic-gate * doesn't have to do this. 345*7c478bd9Sstevel@tonic-gate */ 346*7c478bd9Sstevel@tonic-gate cr->nr = 0; 347*7c478bd9Sstevel@tonic-gate cr->present = 0; 348*7c478bd9Sstevel@tonic-gate n = nrb; 349*7c478bd9Sstevel@tonic-gate while (n--) { 350*7c478bd9Sstevel@tonic-gate for (i = 0; i < 8; i++, crn++) { 351*7c478bd9Sstevel@tonic-gate if (LOOK_BYTE(tp) & (1<<i)) { 352*7c478bd9Sstevel@tonic-gate if (crn < (sizeof (config_regs_present_map)/ 353*7c478bd9Sstevel@tonic-gate sizeof (uint32_t))) 354*7c478bd9Sstevel@tonic-gate cr->present |= 355*7c478bd9Sstevel@tonic-gate config_regs_present_map[crn]; 356*7c478bd9Sstevel@tonic-gate cr->nr++; 357*7c478bd9Sstevel@tonic-gate cr->hr = hr; 358*7c478bd9Sstevel@tonic-gate cr->regs[hr] = MAKE_CONFIG_REG_ADDR( 359*7c478bd9Sstevel@tonic-gate cr->base, hr); 360*7c478bd9Sstevel@tonic-gate } /* LOOK_BYTE */ 361*7c478bd9Sstevel@tonic-gate hr++; 362*7c478bd9Sstevel@tonic-gate } /* for */ 363*7c478bd9Sstevel@tonic-gate (void) GET_BYTE(tp); 364*7c478bd9Sstevel@tonic-gate } /* while */ 365*7c478bd9Sstevel@tonic-gate } 366*7c478bd9Sstevel@tonic-gate 367*7c478bd9Sstevel@tonic-gate return (CISTPLF_NOERROR); 368*7c478bd9Sstevel@tonic-gate } 369*7c478bd9Sstevel@tonic-gate 370*7c478bd9Sstevel@tonic-gate /* 371*7c478bd9Sstevel@tonic-gate * cistpl_device_handler - handler for the CISTPL_DEVICE, CISTPL_DEVICE_A, 372*7c478bd9Sstevel@tonic-gate * CISTPL_DEVICE_OC and CISTPL_DEVICE_OA tuples 373*7c478bd9Sstevel@tonic-gate * 374*7c478bd9Sstevel@tonic-gate * void *arg - points to a cistpl_device_t * where the 375*7c478bd9Sstevel@tonic-gate * information is stuffed into 376*7c478bd9Sstevel@tonic-gate * 377*7c478bd9Sstevel@tonic-gate * XXX - we only handle CISTPL_DEVICE_MAX_DEVICES device descriptions 378*7c478bd9Sstevel@tonic-gate * described in the tuple 379*7c478bd9Sstevel@tonic-gate */ 380*7c478bd9Sstevel@tonic-gate uint32_t 381*7c478bd9Sstevel@tonic-gate cistpl_device_handler(cistpl_callout_t *co, cistpl_t *tp, 382*7c478bd9Sstevel@tonic-gate uint32_t flags, void *arg) 383*7c478bd9Sstevel@tonic-gate { 384*7c478bd9Sstevel@tonic-gate cisdata_t dev_id; 385*7c478bd9Sstevel@tonic-gate 386*7c478bd9Sstevel@tonic-gate /* 387*7c478bd9Sstevel@tonic-gate * nothing special about our flags, so just call the 388*7c478bd9Sstevel@tonic-gate * generic handler for this 389*7c478bd9Sstevel@tonic-gate */ 390*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_SET_FLAGS) 391*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 392*7c478bd9Sstevel@tonic-gate 393*7c478bd9Sstevel@tonic-gate /* 394*7c478bd9Sstevel@tonic-gate * We don't currently validate this tuple. This call will 395*7c478bd9Sstevel@tonic-gate * always set tp->flags |= CISTPLF_VALID. 396*7c478bd9Sstevel@tonic-gate */ 397*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_COPY_DONE) 398*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 399*7c478bd9Sstevel@tonic-gate 400*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_PARSE_LTUPLE) { 401*7c478bd9Sstevel@tonic-gate convert_speed_t convert_speed; 402*7c478bd9Sstevel@tonic-gate cistpl_device_t *dt = (cistpl_device_t *)arg; 403*7c478bd9Sstevel@tonic-gate cistpl_device_node_t *cdn; 404*7c478bd9Sstevel@tonic-gate 405*7c478bd9Sstevel@tonic-gate /* 406*7c478bd9Sstevel@tonic-gate * XXX - fix this to look for more than one device definition 407*7c478bd9Sstevel@tonic-gate * XXX - fix this to handle the OC fields for 408*7c478bd9Sstevel@tonic-gate * CISTPL_DEVICE_OC and CISTPL_DEVICE_OA 409*7c478bd9Sstevel@tonic-gate */ 410*7c478bd9Sstevel@tonic-gate dt->num_devices = 1; 411*7c478bd9Sstevel@tonic-gate cdn = &dt->devnode[0]; 412*7c478bd9Sstevel@tonic-gate 413*7c478bd9Sstevel@tonic-gate cdn->flags = 0; 414*7c478bd9Sstevel@tonic-gate 415*7c478bd9Sstevel@tonic-gate RESET_TP(tp); 416*7c478bd9Sstevel@tonic-gate 417*7c478bd9Sstevel@tonic-gate dev_id = GET_BYTE(tp); 418*7c478bd9Sstevel@tonic-gate 419*7c478bd9Sstevel@tonic-gate /* 420*7c478bd9Sstevel@tonic-gate * Get the device speed code. If it's 7, then there is an 421*7c478bd9Sstevel@tonic-gate * extended speed code table in use, so parse that. 422*7c478bd9Sstevel@tonic-gate * If it's anything else, get the speed information 423*7c478bd9Sstevel@tonic-gate * directly from the device speed code. 424*7c478bd9Sstevel@tonic-gate */ 425*7c478bd9Sstevel@tonic-gate if ((dev_id & 7) == 7) { 426*7c478bd9Sstevel@tonic-gate cdn->nS_speed = cistpl_devspeed(tp, 0, CISTPL_DEVSPEED_EXT); 427*7c478bd9Sstevel@tonic-gate } else { 428*7c478bd9Sstevel@tonic-gate cdn->nS_speed = cistpl_devspeed(NULL, dev_id, 429*7c478bd9Sstevel@tonic-gate CISTPL_DEVSPEED_TABLE); 430*7c478bd9Sstevel@tonic-gate } 431*7c478bd9Sstevel@tonic-gate 432*7c478bd9Sstevel@tonic-gate /* 433*7c478bd9Sstevel@tonic-gate * Convert the speed in nS to a device speed code. 434*7c478bd9Sstevel@tonic-gate * XXX - should check return code from cis_convert_devspeed() 435*7c478bd9Sstevel@tonic-gate */ 436*7c478bd9Sstevel@tonic-gate convert_speed.Attributes = CONVERT_NS_TO_DEVSPEED; 437*7c478bd9Sstevel@tonic-gate convert_speed.nS = cdn->nS_speed; 438*7c478bd9Sstevel@tonic-gate (void) cis_convert_devspeed(&convert_speed); 439*7c478bd9Sstevel@tonic-gate cdn->speed = convert_speed.devspeed; 440*7c478bd9Sstevel@tonic-gate 441*7c478bd9Sstevel@tonic-gate if (dev_id & 8) 442*7c478bd9Sstevel@tonic-gate cdn->flags |= CISTPL_DEVICE_WPS; 443*7c478bd9Sstevel@tonic-gate 444*7c478bd9Sstevel@tonic-gate /* 445*7c478bd9Sstevel@tonic-gate * Set the device type. Note that we take the raw value 446*7c478bd9Sstevel@tonic-gate * from the tuple and pass it back to the caller. 447*7c478bd9Sstevel@tonic-gate * If the device type codes in the standard change, 448*7c478bd9Sstevel@tonic-gate * we will have to change our flags as well. 449*7c478bd9Sstevel@tonic-gate */ 450*7c478bd9Sstevel@tonic-gate cdn->type = (dev_id>>4) & 0x0f; 451*7c478bd9Sstevel@tonic-gate 452*7c478bd9Sstevel@tonic-gate /* 453*7c478bd9Sstevel@tonic-gate * XXX - what about the device_size byte? Is the spec wrong? 454*7c478bd9Sstevel@tonic-gate */ 455*7c478bd9Sstevel@tonic-gate cdn->size = GET_BYTE(tp); 456*7c478bd9Sstevel@tonic-gate /* check for end of list */ 457*7c478bd9Sstevel@tonic-gate if (cdn->size != 0x0ff) { 458*7c478bd9Sstevel@tonic-gate convert_size_t convert_size; 459*7c478bd9Sstevel@tonic-gate 460*7c478bd9Sstevel@tonic-gate convert_size.devsize = cdn->size; 461*7c478bd9Sstevel@tonic-gate convert_size.Attributes = CONVERT_DEVSIZE_TO_BYTES; 462*7c478bd9Sstevel@tonic-gate (void) cis_convert_devsize(&convert_size); 463*7c478bd9Sstevel@tonic-gate cdn->size_in_bytes = convert_size.bytes; 464*7c478bd9Sstevel@tonic-gate } 465*7c478bd9Sstevel@tonic-gate } 466*7c478bd9Sstevel@tonic-gate 467*7c478bd9Sstevel@tonic-gate return (CISTPLF_NOERROR); 468*7c478bd9Sstevel@tonic-gate } 469*7c478bd9Sstevel@tonic-gate 470*7c478bd9Sstevel@tonic-gate /* 471*7c478bd9Sstevel@tonic-gate * cistpl_cftable_handler - handler for the CISTPL_CFTABLE_ENTRY tuple 472*7c478bd9Sstevel@tonic-gate * 473*7c478bd9Sstevel@tonic-gate * void *arg - points to a XXX where the information is stuffed into 474*7c478bd9Sstevel@tonic-gate * 475*7c478bd9Sstevel@tonic-gate * Return: CISTPLF_NOERROR - if no error parsing tuple 476*7c478bd9Sstevel@tonic-gate * HANDTPL_ERROR - if error parsing tuple 477*7c478bd9Sstevel@tonic-gate */ 478*7c478bd9Sstevel@tonic-gate extern uint32_t cistpl_cftable_io_size_table[]; 479*7c478bd9Sstevel@tonic-gate extern uint32_t cistpl_cftable_shift_table[]; 480*7c478bd9Sstevel@tonic-gate 481*7c478bd9Sstevel@tonic-gate uint32_t 482*7c478bd9Sstevel@tonic-gate cistpl_cftable_handler(cistpl_callout_t *co, cistpl_t *tp, 483*7c478bd9Sstevel@tonic-gate uint32_t flags, void *arg) 484*7c478bd9Sstevel@tonic-gate { 485*7c478bd9Sstevel@tonic-gate cisdata_t tpce_indx, tpce_fs, tpce_td, sf, tpce_io, nr; 486*7c478bd9Sstevel@tonic-gate cisdata_t ior_desc, tpce_ir, tpce_msd; 487*7c478bd9Sstevel@tonic-gate int i, j; 488*7c478bd9Sstevel@tonic-gate 489*7c478bd9Sstevel@tonic-gate /* 490*7c478bd9Sstevel@tonic-gate * nothing special about our flags, so just call the 491*7c478bd9Sstevel@tonic-gate * generic handler for this 492*7c478bd9Sstevel@tonic-gate */ 493*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_SET_FLAGS) 494*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 495*7c478bd9Sstevel@tonic-gate 496*7c478bd9Sstevel@tonic-gate /* 497*7c478bd9Sstevel@tonic-gate * We don't currently validate this tuple. This call will 498*7c478bd9Sstevel@tonic-gate * always set tp->flags |= CISTPLF_VALID. 499*7c478bd9Sstevel@tonic-gate */ 500*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_COPY_DONE) 501*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 502*7c478bd9Sstevel@tonic-gate 503*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_PARSE_LTUPLE) { 504*7c478bd9Sstevel@tonic-gate cistpl_cftable_entry_t *ce = (cistpl_cftable_entry_t *)arg; 505*7c478bd9Sstevel@tonic-gate 506*7c478bd9Sstevel@tonic-gate RESET_TP(tp); 507*7c478bd9Sstevel@tonic-gate 508*7c478bd9Sstevel@tonic-gate /* 509*7c478bd9Sstevel@tonic-gate * Check to see if we have an interface description byte. If 510*7c478bd9Sstevel@tonic-gate * we do, grab it and give it directly to the caller, and 511*7c478bd9Sstevel@tonic-gate * set a flag so the caller knows that it's there. 512*7c478bd9Sstevel@tonic-gate * We also setup the appropriate values in the ce->pin member 513*7c478bd9Sstevel@tonic-gate * so that clients can feed this value directly to the 514*7c478bd9Sstevel@tonic-gate * Card Services RequestConfiguration call. 515*7c478bd9Sstevel@tonic-gate */ 516*7c478bd9Sstevel@tonic-gate if ((tpce_indx = GET_BYTE(tp)) & CISTPL_CFTABLE_TPCE_IFM) { 517*7c478bd9Sstevel@tonic-gate ce->ifc = GET_BYTE(tp); 518*7c478bd9Sstevel@tonic-gate 519*7c478bd9Sstevel@tonic-gate ce->pin = 0; 520*7c478bd9Sstevel@tonic-gate 521*7c478bd9Sstevel@tonic-gate if (ce->ifc & CISTPL_CFTABLE_TPCE_IF_BVD) 522*7c478bd9Sstevel@tonic-gate ce->pin |= (PRR_BVD1_STATUS | PRR_BVD2_STATUS | 523*7c478bd9Sstevel@tonic-gate PRR_BVD1_EVENT | PRR_BVD2_EVENT); 524*7c478bd9Sstevel@tonic-gate if (ce->ifc & CISTPL_CFTABLE_TPCE_IF_WP) 525*7c478bd9Sstevel@tonic-gate ce->pin |= (PRR_WP_STATUS | PRR_WP_EVENT); 526*7c478bd9Sstevel@tonic-gate if (ce->ifc & CISTPL_CFTABLE_TPCE_IF_RDY) 527*7c478bd9Sstevel@tonic-gate ce->pin |= (PRR_READY_STATUS | PRR_READY_EVENT); 528*7c478bd9Sstevel@tonic-gate 529*7c478bd9Sstevel@tonic-gate ce->flags |= CISTPL_CFTABLE_TPCE_IF; 530*7c478bd9Sstevel@tonic-gate } 531*7c478bd9Sstevel@tonic-gate 532*7c478bd9Sstevel@tonic-gate /* 533*7c478bd9Sstevel@tonic-gate * Return the configuration index to the caller, and set the 534*7c478bd9Sstevel@tonic-gate * default configuration flag if this is a default 535*7c478bd9Sstevel@tonic-gate * configuration. 536*7c478bd9Sstevel@tonic-gate */ 537*7c478bd9Sstevel@tonic-gate ce->index = tpce_indx & CISTPL_CFTABLE_TPCE_CFGENTRYM; 538*7c478bd9Sstevel@tonic-gate if (tpce_indx & CISTPL_CFTABLE_TPCE_DEFAULTM) 539*7c478bd9Sstevel@tonic-gate ce->flags |= CISTPL_CFTABLE_TPCE_DEFAULT; 540*7c478bd9Sstevel@tonic-gate 541*7c478bd9Sstevel@tonic-gate /* 542*7c478bd9Sstevel@tonic-gate * Feature selection flags. 543*7c478bd9Sstevel@tonic-gate */ 544*7c478bd9Sstevel@tonic-gate tpce_fs = GET_BYTE(tp); 545*7c478bd9Sstevel@tonic-gate 546*7c478bd9Sstevel@tonic-gate /* 547*7c478bd9Sstevel@tonic-gate * See what types of power information are available, 548*7c478bd9Sstevel@tonic-gate * and if there is any, set the global power 549*7c478bd9Sstevel@tonic-gate * information flag as well as a flag for each 550*7c478bd9Sstevel@tonic-gate * power description available. 551*7c478bd9Sstevel@tonic-gate */ 552*7c478bd9Sstevel@tonic-gate if (tpce_fs & CISTPL_CFTABLE_TPCE_FS_PWRM) { 553*7c478bd9Sstevel@tonic-gate cistpl_cftable_entry_pd_t *pd = &ce->pd; 554*7c478bd9Sstevel@tonic-gate 555*7c478bd9Sstevel@tonic-gate ce->flags |= CISTPL_CFTABLE_TPCE_FS_PWR; 556*7c478bd9Sstevel@tonic-gate 557*7c478bd9Sstevel@tonic-gate switch (tpce_fs & CISTPL_CFTABLE_TPCE_FS_PWRM) { 558*7c478bd9Sstevel@tonic-gate case CISTPL_CFTABLE_TPCE_FS_PWR_VPP2M: 559*7c478bd9Sstevel@tonic-gate pd->flags |= CISTPL_CFTABLE_TPCE_FS_PWR_VPP2; 560*7c478bd9Sstevel@tonic-gate /* FALLTHROUGH */ 561*7c478bd9Sstevel@tonic-gate case CISTPL_CFTABLE_TPCE_FS_PWR_VPP1M: 562*7c478bd9Sstevel@tonic-gate pd->flags |= CISTPL_CFTABLE_TPCE_FS_PWR_VPP1; 563*7c478bd9Sstevel@tonic-gate /* FALLTHROUGH */ 564*7c478bd9Sstevel@tonic-gate case CISTPL_CFTABLE_TPCE_FS_PWR_VCCM: 565*7c478bd9Sstevel@tonic-gate pd->flags |= CISTPL_CFTABLE_TPCE_FS_PWR_VCC; 566*7c478bd9Sstevel@tonic-gate } /* switch */ 567*7c478bd9Sstevel@tonic-gate } /* if (CISTPL_CFTABLE_TPCE_FS_PWRM) */ 568*7c478bd9Sstevel@tonic-gate 569*7c478bd9Sstevel@tonic-gate /* 570*7c478bd9Sstevel@tonic-gate * Set up the global memory information flag. 571*7c478bd9Sstevel@tonic-gate */ 572*7c478bd9Sstevel@tonic-gate if (tpce_fs & CISTPL_CFTABLE_TPCE_FS_MEMM) 573*7c478bd9Sstevel@tonic-gate ce->flags |= CISTPL_CFTABLE_TPCE_FS_MEM; 574*7c478bd9Sstevel@tonic-gate 575*7c478bd9Sstevel@tonic-gate /* 576*7c478bd9Sstevel@tonic-gate * Parse the various power description structures. 577*7c478bd9Sstevel@tonic-gate */ 578*7c478bd9Sstevel@tonic-gate if (ce->flags & CISTPL_CFTABLE_TPCE_FS_PWR) { 579*7c478bd9Sstevel@tonic-gate cistpl_cftable_entry_pd_t *pd = &ce->pd; 580*7c478bd9Sstevel@tonic-gate cistpl_cftable_entry_pwr_t *pwr; 581*7c478bd9Sstevel@tonic-gate /* 582*7c478bd9Sstevel@tonic-gate * Collect any Vcc information. 583*7c478bd9Sstevel@tonic-gate */ 584*7c478bd9Sstevel@tonic-gate if (pd->flags & CISTPL_CFTABLE_TPCE_FS_PWR_VCC) { 585*7c478bd9Sstevel@tonic-gate pwr = &pd->pd_vcc; 586*7c478bd9Sstevel@tonic-gate cistpl_pd_parse(tp, pwr); 587*7c478bd9Sstevel@tonic-gate } 588*7c478bd9Sstevel@tonic-gate /* 589*7c478bd9Sstevel@tonic-gate * Collect any Vpp1 information. 590*7c478bd9Sstevel@tonic-gate */ 591*7c478bd9Sstevel@tonic-gate if (pd->flags & CISTPL_CFTABLE_TPCE_FS_PWR_VPP1) { 592*7c478bd9Sstevel@tonic-gate pwr = &pd->pd_vpp1; 593*7c478bd9Sstevel@tonic-gate cistpl_pd_parse(tp, pwr); 594*7c478bd9Sstevel@tonic-gate } 595*7c478bd9Sstevel@tonic-gate /* 596*7c478bd9Sstevel@tonic-gate * Collect any Vpp2 information. 597*7c478bd9Sstevel@tonic-gate */ 598*7c478bd9Sstevel@tonic-gate if (pd->flags & CISTPL_CFTABLE_TPCE_FS_PWR_VPP2) { 599*7c478bd9Sstevel@tonic-gate pwr = &pd->pd_vpp2; 600*7c478bd9Sstevel@tonic-gate cistpl_pd_parse(tp, pwr); 601*7c478bd9Sstevel@tonic-gate } 602*7c478bd9Sstevel@tonic-gate } /* if (CISTPL_CFTABLE_TPCE_FS_PWR) */ 603*7c478bd9Sstevel@tonic-gate 604*7c478bd9Sstevel@tonic-gate /* 605*7c478bd9Sstevel@tonic-gate * Check to see if there's any timing information, and if 606*7c478bd9Sstevel@tonic-gate * so, parse the tuple data and store it in the 607*7c478bd9Sstevel@tonic-gate * caller's structure. Set a flag in the global 608*7c478bd9Sstevel@tonic-gate * flag field indicating that there is timing information. 609*7c478bd9Sstevel@tonic-gate */ 610*7c478bd9Sstevel@tonic-gate if (tpce_fs & CISTPL_CFTABLE_TPCE_FS_TDM) { 611*7c478bd9Sstevel@tonic-gate convert_speed_t convert_speed; 612*7c478bd9Sstevel@tonic-gate cistpl_cftable_entry_speed_t *sp = &ce->speed; 613*7c478bd9Sstevel@tonic-gate ce->flags |= CISTPL_CFTABLE_TPCE_FS_TD; 614*7c478bd9Sstevel@tonic-gate tpce_td = GET_BYTE(tp); 615*7c478bd9Sstevel@tonic-gate /* 616*7c478bd9Sstevel@tonic-gate * Parse TPCE_TD to get the various timing 617*7c478bd9Sstevel@tonic-gate * scale factors. Each scale factor has 618*7c478bd9Sstevel@tonic-gate * a value that indicates that the particular 619*7c478bd9Sstevel@tonic-gate * timing parameter doesn't exist. 620*7c478bd9Sstevel@tonic-gate */ 621*7c478bd9Sstevel@tonic-gate if ((sf = (tpce_td & 622*7c478bd9Sstevel@tonic-gate CISTPL_CFTABLE_TPCE_FS_TD_WAITM)) != 623*7c478bd9Sstevel@tonic-gate CISTPL_CFTABLE_TPCE_FS_TD_WAITM) { 624*7c478bd9Sstevel@tonic-gate sp->nS_wait = cistpl_devspeed(tp, 625*7c478bd9Sstevel@tonic-gate GET_TPCE_FS_TD_WAITS(sf), 626*7c478bd9Sstevel@tonic-gate CISTPL_DEVSPEED_EXT); 627*7c478bd9Sstevel@tonic-gate convert_speed.Attributes = 628*7c478bd9Sstevel@tonic-gate CONVERT_NS_TO_DEVSPEED; 629*7c478bd9Sstevel@tonic-gate convert_speed.nS = sp->nS_wait; 630*7c478bd9Sstevel@tonic-gate (void) cis_convert_devspeed(&convert_speed); 631*7c478bd9Sstevel@tonic-gate sp->wait = convert_speed.devspeed; 632*7c478bd9Sstevel@tonic-gate sp->flags |= CISTPL_CFTABLE_TPCE_FS_TD_WAIT; 633*7c478bd9Sstevel@tonic-gate } 634*7c478bd9Sstevel@tonic-gate 635*7c478bd9Sstevel@tonic-gate if ((sf = (tpce_td & CISTPL_CFTABLE_TPCE_FS_TD_RDYM)) != 636*7c478bd9Sstevel@tonic-gate CISTPL_CFTABLE_TPCE_FS_TD_RDYM) { 637*7c478bd9Sstevel@tonic-gate sp->nS_rdybsy = cistpl_devspeed(tp, 638*7c478bd9Sstevel@tonic-gate GET_TPCE_FS_TD_RDYS(sf), 639*7c478bd9Sstevel@tonic-gate CISTPL_DEVSPEED_EXT); 640*7c478bd9Sstevel@tonic-gate convert_speed.Attributes = 641*7c478bd9Sstevel@tonic-gate CONVERT_NS_TO_DEVSPEED; 642*7c478bd9Sstevel@tonic-gate convert_speed.nS = sp->nS_rdybsy; 643*7c478bd9Sstevel@tonic-gate (void) cis_convert_devspeed(&convert_speed); 644*7c478bd9Sstevel@tonic-gate sp->rdybsy = convert_speed.devspeed; 645*7c478bd9Sstevel@tonic-gate sp->flags |= CISTPL_CFTABLE_TPCE_FS_TD_RDY; 646*7c478bd9Sstevel@tonic-gate } 647*7c478bd9Sstevel@tonic-gate 648*7c478bd9Sstevel@tonic-gate if ((sf = (tpce_td & 649*7c478bd9Sstevel@tonic-gate CISTPL_CFTABLE_TPCE_FS_TD_RSVDM)) != 650*7c478bd9Sstevel@tonic-gate CISTPL_CFTABLE_TPCE_FS_TD_RSVDM) { 651*7c478bd9Sstevel@tonic-gate sp->nS_rsvd = cistpl_devspeed(tp, 652*7c478bd9Sstevel@tonic-gate GET_TPCE_FS_TD_RSVDS(sf), 653*7c478bd9Sstevel@tonic-gate CISTPL_DEVSPEED_EXT); 654*7c478bd9Sstevel@tonic-gate convert_speed.Attributes = 655*7c478bd9Sstevel@tonic-gate CONVERT_NS_TO_DEVSPEED; 656*7c478bd9Sstevel@tonic-gate convert_speed.nS = sp->nS_rsvd; 657*7c478bd9Sstevel@tonic-gate (void) cis_convert_devspeed(&convert_speed); 658*7c478bd9Sstevel@tonic-gate sp->rsvd = convert_speed.devspeed; 659*7c478bd9Sstevel@tonic-gate sp->flags |= CISTPL_CFTABLE_TPCE_FS_TD_RSVD; 660*7c478bd9Sstevel@tonic-gate } 661*7c478bd9Sstevel@tonic-gate } /* if (CISTPL_CFTABLE_TPCE_FS_TDM) */ 662*7c478bd9Sstevel@tonic-gate 663*7c478bd9Sstevel@tonic-gate 664*7c478bd9Sstevel@tonic-gate /* 665*7c478bd9Sstevel@tonic-gate * Parse any I/O address information. If there is I/O 666*7c478bd9Sstevel@tonic-gate * inforamtion, set a flag in the global flag field 667*7c478bd9Sstevel@tonic-gate * to let the caller know. 668*7c478bd9Sstevel@tonic-gate */ 669*7c478bd9Sstevel@tonic-gate if (tpce_fs & CISTPL_CFTABLE_TPCE_FS_IOM) { 670*7c478bd9Sstevel@tonic-gate cistpl_cftable_entry_io_t *io = &ce->io; 671*7c478bd9Sstevel@tonic-gate 672*7c478bd9Sstevel@tonic-gate ce->flags |= CISTPL_CFTABLE_TPCE_FS_IO; 673*7c478bd9Sstevel@tonic-gate tpce_io = GET_BYTE(tp); 674*7c478bd9Sstevel@tonic-gate /* 675*7c478bd9Sstevel@tonic-gate * Pass any I/O flags that are in the tuple directly 676*7c478bd9Sstevel@tonic-gate * to the caller. 677*7c478bd9Sstevel@tonic-gate */ 678*7c478bd9Sstevel@tonic-gate io->flags = tpce_io; 679*7c478bd9Sstevel@tonic-gate io->addr_lines = tpce_io & 680*7c478bd9Sstevel@tonic-gate CISTPL_CFTABLE_TPCE_FS_IO_ALM; 681*7c478bd9Sstevel@tonic-gate /* 682*7c478bd9Sstevel@tonic-gate * If there are any ranges, extract the number of 683*7c478bd9Sstevel@tonic-gate * ranges and the range descriptions. 684*7c478bd9Sstevel@tonic-gate */ 685*7c478bd9Sstevel@tonic-gate if (tpce_io & CISTPL_CFTABLE_TPCE_FS_IO_RANGEM) { 686*7c478bd9Sstevel@tonic-gate cistpl_cftable_entry_io_range_t *ior; 687*7c478bd9Sstevel@tonic-gate ior_desc = GET_BYTE(tp); 688*7c478bd9Sstevel@tonic-gate /* 689*7c478bd9Sstevel@tonic-gate * Number of I/O ranges is the value specified 690*7c478bd9Sstevel@tonic-gate * in the tuple plus one, so there's 691*7c478bd9Sstevel@tonic-gate * always at least one I/O range if the 692*7c478bd9Sstevel@tonic-gate * CISTPL_CFTABLE_TPCE_FS_IO_RANGEM bit 693*7c478bd9Sstevel@tonic-gate * in the I/O flags register is set. 694*7c478bd9Sstevel@tonic-gate */ 695*7c478bd9Sstevel@tonic-gate nr = (ior_desc & 0x0f) + 1; 696*7c478bd9Sstevel@tonic-gate io->ranges = nr; 697*7c478bd9Sstevel@tonic-gate /* 698*7c478bd9Sstevel@tonic-gate * Cycle through each I/O range. 699*7c478bd9Sstevel@tonic-gate */ 700*7c478bd9Sstevel@tonic-gate for (i = 0; i < (int)nr; i++) { 701*7c478bd9Sstevel@tonic-gate ior = &io->range[i]; 702*7c478bd9Sstevel@tonic-gate ior->addr = 0; 703*7c478bd9Sstevel@tonic-gate ior->length = 0; 704*7c478bd9Sstevel@tonic-gate /* 705*7c478bd9Sstevel@tonic-gate * Gather the address information. 706*7c478bd9Sstevel@tonic-gate * It's OK if there's no address 707*7c478bd9Sstevel@tonic-gate * information in which case this 708*7c478bd9Sstevel@tonic-gate * loop will never execute. 709*7c478bd9Sstevel@tonic-gate */ 710*7c478bd9Sstevel@tonic-gate for (j = 0; j < 711*7c478bd9Sstevel@tonic-gate cistpl_cftable_io_size_table[ 712*7c478bd9Sstevel@tonic-gate (ior_desc>>4)&3]; 713*7c478bd9Sstevel@tonic-gate j++) 714*7c478bd9Sstevel@tonic-gate ior->addr |= (GET_BYTE(tp) << 715*7c478bd9Sstevel@tonic-gate cistpl_cftable_shift_table[j]); 716*7c478bd9Sstevel@tonic-gate /* 717*7c478bd9Sstevel@tonic-gate * Gather the length information. 718*7c478bd9Sstevel@tonic-gate * It's OK if there's no length 719*7c478bd9Sstevel@tonic-gate * information in which case this 720*7c478bd9Sstevel@tonic-gate * loop will never execute. 721*7c478bd9Sstevel@tonic-gate */ 722*7c478bd9Sstevel@tonic-gate for (j = 0; j < 723*7c478bd9Sstevel@tonic-gate cistpl_cftable_io_size_table[ 724*7c478bd9Sstevel@tonic-gate (ior_desc>>6)&3]; 725*7c478bd9Sstevel@tonic-gate j++) 726*7c478bd9Sstevel@tonic-gate ior->length |= (GET_BYTE(tp) << 727*7c478bd9Sstevel@tonic-gate cistpl_cftable_shift_table[j]); 728*7c478bd9Sstevel@tonic-gate } /* for (nr) */ 729*7c478bd9Sstevel@tonic-gate } /* if (CISTPL_CFTABLE_TPCE_FS_IO_RANGEM) */ 730*7c478bd9Sstevel@tonic-gate } /* if (CISTPL_CFTABLE_TPCE_FS_IOM) */ 731*7c478bd9Sstevel@tonic-gate 732*7c478bd9Sstevel@tonic-gate /* 733*7c478bd9Sstevel@tonic-gate * Parse any IRQ information. If there is IRQ inforamtion, 734*7c478bd9Sstevel@tonic-gate * set a flag in the global flag field to let the 735*7c478bd9Sstevel@tonic-gate * caller know. 736*7c478bd9Sstevel@tonic-gate */ 737*7c478bd9Sstevel@tonic-gate if (tpce_fs & CISTPL_CFTABLE_TPCE_FS_IRQM) { 738*7c478bd9Sstevel@tonic-gate cistpl_cftable_entry_irq_t *irq = &ce->irq; 739*7c478bd9Sstevel@tonic-gate 740*7c478bd9Sstevel@tonic-gate ce->flags |= CISTPL_CFTABLE_TPCE_FS_IRQ; 741*7c478bd9Sstevel@tonic-gate tpce_ir = GET_BYTE(tp); 742*7c478bd9Sstevel@tonic-gate /* 743*7c478bd9Sstevel@tonic-gate * Pass any IRQ flags that are in the tuple directly 744*7c478bd9Sstevel@tonic-gate * to the caller. 745*7c478bd9Sstevel@tonic-gate */ 746*7c478bd9Sstevel@tonic-gate irq->flags = tpce_ir; 747*7c478bd9Sstevel@tonic-gate /* 748*7c478bd9Sstevel@tonic-gate * Check for and parse the extended IRQ bitmask 749*7c478bd9Sstevel@tonic-gate * if it exists. 750*7c478bd9Sstevel@tonic-gate */ 751*7c478bd9Sstevel@tonic-gate if (tpce_ir & CISTPL_CFTABLE_TPCE_FS_IRQ_MASKM) { 752*7c478bd9Sstevel@tonic-gate irq->irqs = GET_BYTE(tp) & 0x0ff; 753*7c478bd9Sstevel@tonic-gate irq->irqs |= (GET_BYTE(tp) << 8)&0x0ff00; 754*7c478bd9Sstevel@tonic-gate } else { 755*7c478bd9Sstevel@tonic-gate irq->irqs = (1<< (tpce_ir&0x0f)); 756*7c478bd9Sstevel@tonic-gate } 757*7c478bd9Sstevel@tonic-gate } /* if (CISTPL_CFTABLE_TPCE_FS_IRQM) */ 758*7c478bd9Sstevel@tonic-gate 759*7c478bd9Sstevel@tonic-gate /* 760*7c478bd9Sstevel@tonic-gate * Parse any memory information. 761*7c478bd9Sstevel@tonic-gate * 762*7c478bd9Sstevel@tonic-gate * XXX - should be a cleaner way to parse this information. 763*7c478bd9Sstevel@tonic-gate */ 764*7c478bd9Sstevel@tonic-gate if (ce->flags & CISTPL_CFTABLE_TPCE_FS_MEM) { 765*7c478bd9Sstevel@tonic-gate cistpl_cftable_entry_mem_t *mem = &ce->mem; 766*7c478bd9Sstevel@tonic-gate cistpl_cftable_entry_mem_window_t *win; 767*7c478bd9Sstevel@tonic-gate /* 768*7c478bd9Sstevel@tonic-gate * Switch on the type of memory description 769*7c478bd9Sstevel@tonic-gate * information that is available. 770*7c478bd9Sstevel@tonic-gate */ 771*7c478bd9Sstevel@tonic-gate switch (tpce_fs & CISTPL_CFTABLE_TPCE_FS_MEMM) { 772*7c478bd9Sstevel@tonic-gate /* 773*7c478bd9Sstevel@tonic-gate * variable length memory space description 774*7c478bd9Sstevel@tonic-gate */ 775*7c478bd9Sstevel@tonic-gate case CISTPL_CFTABLE_TPCE_FS_MEM3M: 776*7c478bd9Sstevel@tonic-gate mem->flags |= CISTPL_CFTABLE_TPCE_FS_MEM3; 777*7c478bd9Sstevel@tonic-gate /* memory space descriptor */ 778*7c478bd9Sstevel@tonic-gate tpce_msd = GET_BYTE(tp); 779*7c478bd9Sstevel@tonic-gate mem->windows = ((tpce_msd & 780*7c478bd9Sstevel@tonic-gate (CISTPL_CFTABLE_ENTRY_MAX_MEM_WINDOWS - 781*7c478bd9Sstevel@tonic-gate 1)) + 1); 782*7c478bd9Sstevel@tonic-gate /* 783*7c478bd9Sstevel@tonic-gate * If there's host address information, let 784*7c478bd9Sstevel@tonic-gate * the caller know. 785*7c478bd9Sstevel@tonic-gate */ 786*7c478bd9Sstevel@tonic-gate if (tpce_msd & CISTPL_CFTABLE_TPCE_FS_MEM_HOSTM) 787*7c478bd9Sstevel@tonic-gate mem->flags |= 788*7c478bd9Sstevel@tonic-gate CISTPL_CFTABLE_TPCE_FS_MEM_HOST; 789*7c478bd9Sstevel@tonic-gate /* 790*7c478bd9Sstevel@tonic-gate * Cycle through each window space description 791*7c478bd9Sstevel@tonic-gate * and collect all the interesting bits. 792*7c478bd9Sstevel@tonic-gate */ 793*7c478bd9Sstevel@tonic-gate for (i = 0; i < mem->windows; i++) { 794*7c478bd9Sstevel@tonic-gate win = &mem->window[i]; 795*7c478bd9Sstevel@tonic-gate win->length = 0; 796*7c478bd9Sstevel@tonic-gate win->card_addr = 0; 797*7c478bd9Sstevel@tonic-gate win->host_addr = 0; 798*7c478bd9Sstevel@tonic-gate /* 799*7c478bd9Sstevel@tonic-gate * Gather the length information. 800*7c478bd9Sstevel@tonic-gate * It's OK if there's no length 801*7c478bd9Sstevel@tonic-gate * information in which case this 802*7c478bd9Sstevel@tonic-gate * loop will never execute. 803*7c478bd9Sstevel@tonic-gate */ 804*7c478bd9Sstevel@tonic-gate for (j = 0; j < 805*7c478bd9Sstevel@tonic-gate (int)((tpce_msd>>3)&3); j++) 806*7c478bd9Sstevel@tonic-gate win->length |= (GET_BYTE(tp) << 807*7c478bd9Sstevel@tonic-gate cistpl_cftable_shift_table[j]); 808*7c478bd9Sstevel@tonic-gate /* 809*7c478bd9Sstevel@tonic-gate * Gather the card address information. 810*7c478bd9Sstevel@tonic-gate * It's OK if there's no card 811*7c478bd9Sstevel@tonic-gate * address information in which 812*7c478bd9Sstevel@tonic-gate * case this loop will never 813*7c478bd9Sstevel@tonic-gate * execute. 814*7c478bd9Sstevel@tonic-gate */ 815*7c478bd9Sstevel@tonic-gate for (j = 0; j < 816*7c478bd9Sstevel@tonic-gate (int)((tpce_msd>>5)&3); j++) 817*7c478bd9Sstevel@tonic-gate win->card_addr |= 818*7c478bd9Sstevel@tonic-gate (GET_BYTE(tp) << 819*7c478bd9Sstevel@tonic-gate cistpl_cftable_shift_table[j]); 820*7c478bd9Sstevel@tonic-gate /* 821*7c478bd9Sstevel@tonic-gate * If there's a host address 822*7c478bd9Sstevel@tonic-gate * description, grab that 823*7c478bd9Sstevel@tonic-gate * as well. 824*7c478bd9Sstevel@tonic-gate */ 825*7c478bd9Sstevel@tonic-gate if (mem->flags & 826*7c478bd9Sstevel@tonic-gate CISTPL_CFTABLE_TPCE_FS_MEM_HOST) { 827*7c478bd9Sstevel@tonic-gate /* 828*7c478bd9Sstevel@tonic-gate * Gather the host address 829*7c478bd9Sstevel@tonic-gate * information. It's OK 830*7c478bd9Sstevel@tonic-gate * if there's no host 831*7c478bd9Sstevel@tonic-gate * address information in 832*7c478bd9Sstevel@tonic-gate * which case this loop 833*7c478bd9Sstevel@tonic-gate * will never execute. 834*7c478bd9Sstevel@tonic-gate * Note that we use the card 835*7c478bd9Sstevel@tonic-gate * address size to 836*7c478bd9Sstevel@tonic-gate * determine how many 837*7c478bd9Sstevel@tonic-gate * bytes of host address 838*7c478bd9Sstevel@tonic-gate * are present. 839*7c478bd9Sstevel@tonic-gate */ 840*7c478bd9Sstevel@tonic-gate for (j = 0; j < 841*7c478bd9Sstevel@tonic-gate (int)((tpce_msd>>5)&3); 842*7c478bd9Sstevel@tonic-gate j++) 843*7c478bd9Sstevel@tonic-gate win->host_addr |= 844*7c478bd9Sstevel@tonic-gate (GET_BYTE(tp) << 845*7c478bd9Sstevel@tonic-gate cistpl_cftable_shift_table[j]); 846*7c478bd9Sstevel@tonic-gate } else { 847*7c478bd9Sstevel@tonic-gate /* 848*7c478bd9Sstevel@tonic-gate * No host address information, 849*7c478bd9Sstevel@tonic-gate * so the host address is 850*7c478bd9Sstevel@tonic-gate * equal to the card 851*7c478bd9Sstevel@tonic-gate * address. 852*7c478bd9Sstevel@tonic-gate */ 853*7c478bd9Sstevel@tonic-gate win->host_addr = win->card_addr; 854*7c478bd9Sstevel@tonic-gate } 855*7c478bd9Sstevel@tonic-gate } /* for (i<mem->windows) */ 856*7c478bd9Sstevel@tonic-gate break; 857*7c478bd9Sstevel@tonic-gate /* 858*7c478bd9Sstevel@tonic-gate * single length and card base address specified 859*7c478bd9Sstevel@tonic-gate */ 860*7c478bd9Sstevel@tonic-gate case CISTPL_CFTABLE_TPCE_FS_MEM2M: 861*7c478bd9Sstevel@tonic-gate mem->flags |= CISTPL_CFTABLE_TPCE_FS_MEM2; 862*7c478bd9Sstevel@tonic-gate win = &mem->window[0]; 863*7c478bd9Sstevel@tonic-gate mem->windows = 1; 864*7c478bd9Sstevel@tonic-gate /* 865*7c478bd9Sstevel@tonic-gate * Construct the size of the window. 866*7c478bd9Sstevel@tonic-gate */ 867*7c478bd9Sstevel@tonic-gate win->length = GET_BYTE(tp); 868*7c478bd9Sstevel@tonic-gate win->length |= (GET_BYTE(tp)<<8); 869*7c478bd9Sstevel@tonic-gate win->length *= 870*7c478bd9Sstevel@tonic-gate CISTPL_CFTABLE_TPCE_FS_MEM_PGSIZE; 871*7c478bd9Sstevel@tonic-gate 872*7c478bd9Sstevel@tonic-gate /* 873*7c478bd9Sstevel@tonic-gate * Construct the card base address. 874*7c478bd9Sstevel@tonic-gate */ 875*7c478bd9Sstevel@tonic-gate win->card_addr = GET_BYTE(tp); 876*7c478bd9Sstevel@tonic-gate win->card_addr |= (GET_BYTE(tp)<<8); 877*7c478bd9Sstevel@tonic-gate win->card_addr *= 878*7c478bd9Sstevel@tonic-gate CISTPL_CFTABLE_TPCE_FS_MEM_PGSIZE; 879*7c478bd9Sstevel@tonic-gate 880*7c478bd9Sstevel@tonic-gate /* 881*7c478bd9Sstevel@tonic-gate * In this mode, both the host base address 882*7c478bd9Sstevel@tonic-gate * and the card base address are equal. 883*7c478bd9Sstevel@tonic-gate */ 884*7c478bd9Sstevel@tonic-gate win->host_addr = win->card_addr; 885*7c478bd9Sstevel@tonic-gate break; 886*7c478bd9Sstevel@tonic-gate /* 887*7c478bd9Sstevel@tonic-gate * single length specified 888*7c478bd9Sstevel@tonic-gate */ 889*7c478bd9Sstevel@tonic-gate case CISTPL_CFTABLE_TPCE_FS_MEM1M: 890*7c478bd9Sstevel@tonic-gate mem->flags |= CISTPL_CFTABLE_TPCE_FS_MEM1; 891*7c478bd9Sstevel@tonic-gate win = &mem->window[0]; 892*7c478bd9Sstevel@tonic-gate mem->windows = 1; 893*7c478bd9Sstevel@tonic-gate win->card_addr = 0; 894*7c478bd9Sstevel@tonic-gate win->host_addr = 0; 895*7c478bd9Sstevel@tonic-gate /* 896*7c478bd9Sstevel@tonic-gate * Construct the size of the window. 897*7c478bd9Sstevel@tonic-gate */ 898*7c478bd9Sstevel@tonic-gate win->length = GET_BYTE(tp); 899*7c478bd9Sstevel@tonic-gate win->length |= (GET_BYTE(tp)<<8); 900*7c478bd9Sstevel@tonic-gate win->length *= 901*7c478bd9Sstevel@tonic-gate CISTPL_CFTABLE_TPCE_FS_MEM_PGSIZE; 902*7c478bd9Sstevel@tonic-gate break; 903*7c478bd9Sstevel@tonic-gate } /* switch (CISTPL_CFTABLE_TPCE_FS_MEMM) */ 904*7c478bd9Sstevel@tonic-gate } /* if (CISTPL_CFTABLE_TPCE_FS_MEM) */ 905*7c478bd9Sstevel@tonic-gate 906*7c478bd9Sstevel@tonic-gate /* 907*7c478bd9Sstevel@tonic-gate * Check for and parse any miscellaneous information. 908*7c478bd9Sstevel@tonic-gate * 909*7c478bd9Sstevel@tonic-gate * We only understand how to parse the first 910*7c478bd9Sstevel@tonic-gate * CISTPL_CFTABLE_TPCE_FS_MISC_MAX extension 911*7c478bd9Sstevel@tonic-gate * bytes specified in the PC Card 95 standard; 912*7c478bd9Sstevel@tonic-gate * we throw away any other extension bytes that 913*7c478bd9Sstevel@tonic-gate * are past these bytes. 914*7c478bd9Sstevel@tonic-gate * XXX Note that the assumption here is that the 915*7c478bd9Sstevel@tonic-gate * size of cistpl_cftable_entry_misc_t->flags 916*7c478bd9Sstevel@tonic-gate * is at least CISTPL_CFTABLE_TPCE_FS_MISC_MAX 917*7c478bd9Sstevel@tonic-gate * bytes in length. 918*7c478bd9Sstevel@tonic-gate */ 919*7c478bd9Sstevel@tonic-gate if (tpce_fs & CISTPL_CFTABLE_TPCE_FS_MISCM) { 920*7c478bd9Sstevel@tonic-gate cistpl_cftable_entry_misc_t *misc = &ce->misc; 921*7c478bd9Sstevel@tonic-gate int mb = CISTPL_CFTABLE_TPCE_FS_MISC_MAX; 922*7c478bd9Sstevel@tonic-gate 923*7c478bd9Sstevel@tonic-gate ce->flags |= CISTPL_CFTABLE_TPCE_FS_MISC; 924*7c478bd9Sstevel@tonic-gate misc->flags = 0; 925*7c478bd9Sstevel@tonic-gate 926*7c478bd9Sstevel@tonic-gate do { 927*7c478bd9Sstevel@tonic-gate if (mb) { 928*7c478bd9Sstevel@tonic-gate misc->flags = (misc->flags << 8) | LOOK_BYTE(tp); 929*7c478bd9Sstevel@tonic-gate mb--; 930*7c478bd9Sstevel@tonic-gate } 931*7c478bd9Sstevel@tonic-gate } while ((GET_BYTE(tp) & CISTPL_EXT_BIT) && 932*7c478bd9Sstevel@tonic-gate (!(tp->flags & CISTPLF_MEM_ERR))); 933*7c478bd9Sstevel@tonic-gate 934*7c478bd9Sstevel@tonic-gate /* 935*7c478bd9Sstevel@tonic-gate * Check to see if we tried to read past the 936*7c478bd9Sstevel@tonic-gate * end of the tuple data; if we have, 937*7c478bd9Sstevel@tonic-gate * there's no point in trying to parse 938*7c478bd9Sstevel@tonic-gate * any more of the tuple. 939*7c478bd9Sstevel@tonic-gate */ 940*7c478bd9Sstevel@tonic-gate if (tp->flags & CISTPLF_MEM_ERR) 941*7c478bd9Sstevel@tonic-gate return (HANDTPL_ERROR); 942*7c478bd9Sstevel@tonic-gate } /* if (CISTPL_CFTABLE_TPCE_FS_MISCM) */ 943*7c478bd9Sstevel@tonic-gate 944*7c478bd9Sstevel@tonic-gate /* 945*7c478bd9Sstevel@tonic-gate * Check for and parse any additional subtuple 946*7c478bd9Sstevel@tonic-gate * information. We know that there is 947*7c478bd9Sstevel@tonic-gate * additional information if we haven't 948*7c478bd9Sstevel@tonic-gate * reached the end of the tuple data area 949*7c478bd9Sstevel@tonic-gate * and if the additional information is 950*7c478bd9Sstevel@tonic-gate * in standard tuple format. 951*7c478bd9Sstevel@tonic-gate * If we don't recognize the additional info, 952*7c478bd9Sstevel@tonic-gate * then just silently ignore it, don't 953*7c478bd9Sstevel@tonic-gate * flag it as an error. 954*7c478bd9Sstevel@tonic-gate */ 955*7c478bd9Sstevel@tonic-gate #ifdef PARSE_STCE_TUPLES 956*7c478bd9Sstevel@tonic-gate if (GET_LEN(tp) > 0) { 957*7c478bd9Sstevel@tonic-gate 958*7c478bd9Sstevel@tonic-gate ce->flags |= CISTPL_CFTABLE_TPCE_FS_STCE_EV 959*7c478bd9Sstevel@tonic-gate ce->flags |= CISTPL_CFTABLE_TPCE_FS_STCE_PD 960*7c478bd9Sstevel@tonic-gate #endif 961*7c478bd9Sstevel@tonic-gate 962*7c478bd9Sstevel@tonic-gate } /* if (HANDTPL_PARSE_LTUPLE) */ 963*7c478bd9Sstevel@tonic-gate 964*7c478bd9Sstevel@tonic-gate return (CISTPLF_NOERROR); 965*7c478bd9Sstevel@tonic-gate } 966*7c478bd9Sstevel@tonic-gate 967*7c478bd9Sstevel@tonic-gate /* 968*7c478bd9Sstevel@tonic-gate * cistpl_pd_parse - read and parse a power description structure 969*7c478bd9Sstevel@tonic-gate * 970*7c478bd9Sstevel@tonic-gate * cisdata_t **ddp - pointer to pointer tuple data area 971*7c478bd9Sstevel@tonic-gate * cistpl_cftable_entry_pwr_t *pd - pointer to local power description 972*7c478bd9Sstevel@tonic-gate * structure 973*7c478bd9Sstevel@tonic-gate */ 974*7c478bd9Sstevel@tonic-gate static void 975*7c478bd9Sstevel@tonic-gate cistpl_pd_parse(cistpl_t *tp, cistpl_cftable_entry_pwr_t *pd) 976*7c478bd9Sstevel@tonic-gate { 977*7c478bd9Sstevel@tonic-gate cisdata_t pdesc; 978*7c478bd9Sstevel@tonic-gate 979*7c478bd9Sstevel@tonic-gate pdesc = GET_BYTE(tp); /* power description selector */ 980*7c478bd9Sstevel@tonic-gate 981*7c478bd9Sstevel@tonic-gate /* nominal supply voltage */ 982*7c478bd9Sstevel@tonic-gate if (pdesc & CISTPL_CFTABLE_PD_NOMV) { 983*7c478bd9Sstevel@tonic-gate pd->nomV = cistpl_expd_parse(tp, &pd->nomV_flags) / 100; 984*7c478bd9Sstevel@tonic-gate pd->nomV_flags |= (pdesc | CISTPL_CFTABLE_PD_EXISTS); 985*7c478bd9Sstevel@tonic-gate } 986*7c478bd9Sstevel@tonic-gate 987*7c478bd9Sstevel@tonic-gate /* minimum supply voltage */ 988*7c478bd9Sstevel@tonic-gate if (pdesc & CISTPL_CFTABLE_PD_MINV) { 989*7c478bd9Sstevel@tonic-gate pd->minV = cistpl_expd_parse(tp, &pd->minV_flags) / 100; 990*7c478bd9Sstevel@tonic-gate pd->minV_flags |= (pdesc | CISTPL_CFTABLE_PD_EXISTS); 991*7c478bd9Sstevel@tonic-gate } 992*7c478bd9Sstevel@tonic-gate 993*7c478bd9Sstevel@tonic-gate /* maximum supply voltage */ 994*7c478bd9Sstevel@tonic-gate if (pdesc & CISTPL_CFTABLE_PD_MAXV) { 995*7c478bd9Sstevel@tonic-gate pd->maxV = cistpl_expd_parse(tp, &pd->maxV_flags) / 100; 996*7c478bd9Sstevel@tonic-gate pd->maxV_flags |= (pdesc | CISTPL_CFTABLE_PD_EXISTS); 997*7c478bd9Sstevel@tonic-gate } 998*7c478bd9Sstevel@tonic-gate 999*7c478bd9Sstevel@tonic-gate /* continuous supply current */ 1000*7c478bd9Sstevel@tonic-gate if (pdesc & CISTPL_CFTABLE_PD_STATICI) { 1001*7c478bd9Sstevel@tonic-gate pd->staticI_flags |= CISTPL_CFTABLE_PD_MUL10; 1002*7c478bd9Sstevel@tonic-gate pd->staticI = cistpl_expd_parse(tp, &pd->staticI_flags); 1003*7c478bd9Sstevel@tonic-gate pd->staticI_flags |= (pdesc | CISTPL_CFTABLE_PD_EXISTS); 1004*7c478bd9Sstevel@tonic-gate } 1005*7c478bd9Sstevel@tonic-gate 1006*7c478bd9Sstevel@tonic-gate /* maximum current required averaged over 1 second */ 1007*7c478bd9Sstevel@tonic-gate if (pdesc & CISTPL_CFTABLE_PD_AVGI) { 1008*7c478bd9Sstevel@tonic-gate pd->avgI_flags |= CISTPL_CFTABLE_PD_MUL10; 1009*7c478bd9Sstevel@tonic-gate pd->avgI = cistpl_expd_parse(tp, &pd->avgI_flags); 1010*7c478bd9Sstevel@tonic-gate pd->avgI_flags |= (pdesc | CISTPL_CFTABLE_PD_EXISTS); 1011*7c478bd9Sstevel@tonic-gate } 1012*7c478bd9Sstevel@tonic-gate 1013*7c478bd9Sstevel@tonic-gate /* maximum current required averaged over 10mS */ 1014*7c478bd9Sstevel@tonic-gate if (pdesc & CISTPL_CFTABLE_PD_PEAKI) { 1015*7c478bd9Sstevel@tonic-gate pd->peakI_flags |= CISTPL_CFTABLE_PD_MUL10; 1016*7c478bd9Sstevel@tonic-gate pd->peakI = cistpl_expd_parse(tp, &pd->peakI_flags); 1017*7c478bd9Sstevel@tonic-gate pd->peakI_flags |= (pdesc | CISTPL_CFTABLE_PD_EXISTS); 1018*7c478bd9Sstevel@tonic-gate } 1019*7c478bd9Sstevel@tonic-gate 1020*7c478bd9Sstevel@tonic-gate /* power down supply curent required */ 1021*7c478bd9Sstevel@tonic-gate if (pdesc & CISTPL_CFTABLE_PD_PDOWNI) { 1022*7c478bd9Sstevel@tonic-gate pd->pdownI_flags |= CISTPL_CFTABLE_PD_MUL10; 1023*7c478bd9Sstevel@tonic-gate pd->pdownI = cistpl_expd_parse(tp, &pd->pdownI_flags); 1024*7c478bd9Sstevel@tonic-gate pd->pdownI_flags |= (pdesc | CISTPL_CFTABLE_PD_EXISTS); 1025*7c478bd9Sstevel@tonic-gate } 1026*7c478bd9Sstevel@tonic-gate } 1027*7c478bd9Sstevel@tonic-gate 1028*7c478bd9Sstevel@tonic-gate /* 1029*7c478bd9Sstevel@tonic-gate * cistpl_expd_parse - read and parse an extended power description structure 1030*7c478bd9Sstevel@tonic-gate * 1031*7c478bd9Sstevel@tonic-gate * cistpl_t *tp - pointer to pointer tuple data area 1032*7c478bd9Sstevel@tonic-gate * int *flags - flags that get for this parameter: 1033*7c478bd9Sstevel@tonic-gate * CISTPL_CFTABLE_PD_NC_SLEEP - no connection on 1034*7c478bd9Sstevel@tonic-gate * sleep/power down 1035*7c478bd9Sstevel@tonic-gate * CISTPL_CFTABLE_PD_ZERO - zero value required 1036*7c478bd9Sstevel@tonic-gate * CISTPL_CFTABLE_PD_NC - no connection ever 1037*7c478bd9Sstevel@tonic-gate * 1038*7c478bd9Sstevel@tonic-gate * The power consumption is returned in the following units: 1039*7c478bd9Sstevel@tonic-gate * 1040*7c478bd9Sstevel@tonic-gate * voltage - milliVOLTS 1041*7c478bd9Sstevel@tonic-gate * current - microAMPS 1042*7c478bd9Sstevel@tonic-gate */ 1043*7c478bd9Sstevel@tonic-gate extern cistpl_pd_struct_t cistpl_pd_struct; 1044*7c478bd9Sstevel@tonic-gate 1045*7c478bd9Sstevel@tonic-gate uint32_t 1046*7c478bd9Sstevel@tonic-gate cistpl_expd_parse(cistpl_t *tp, uint32_t *flags) 1047*7c478bd9Sstevel@tonic-gate { 1048*7c478bd9Sstevel@tonic-gate cisdata_t pdesc; 1049*7c478bd9Sstevel@tonic-gate uint32_t exponent, mantisa, val, digits = 0; 1050*7c478bd9Sstevel@tonic-gate 1051*7c478bd9Sstevel@tonic-gate /* 1052*7c478bd9Sstevel@tonic-gate * Get the power description parameter byte and break it up 1053*7c478bd9Sstevel@tonic-gate * into mantissa and exponent. 1054*7c478bd9Sstevel@tonic-gate */ 1055*7c478bd9Sstevel@tonic-gate pdesc = GET_BYTE(tp); 1056*7c478bd9Sstevel@tonic-gate exponent = pdesc&7; 1057*7c478bd9Sstevel@tonic-gate mantisa = (pdesc>>3)&0x0f; 1058*7c478bd9Sstevel@tonic-gate 1059*7c478bd9Sstevel@tonic-gate if (pdesc & CISTPL_EXT_BIT) { 1060*7c478bd9Sstevel@tonic-gate do { 1061*7c478bd9Sstevel@tonic-gate if (LOOK_BYTE(tp) <= 0x63) 1062*7c478bd9Sstevel@tonic-gate digits = LOOK_BYTE(tp); 1063*7c478bd9Sstevel@tonic-gate if (LOOK_BYTE(tp) == CISTPL_CFTABLE_PD_NC_SLEEPM) 1064*7c478bd9Sstevel@tonic-gate *flags |= CISTPL_CFTABLE_PD_NC_SLEEP; 1065*7c478bd9Sstevel@tonic-gate if (LOOK_BYTE(tp) == CISTPL_CFTABLE_PD_ZEROM) 1066*7c478bd9Sstevel@tonic-gate *flags |= CISTPL_CFTABLE_PD_ZERO; 1067*7c478bd9Sstevel@tonic-gate if (LOOK_BYTE(tp) == CISTPL_CFTABLE_PD_NCM) 1068*7c478bd9Sstevel@tonic-gate *flags |= CISTPL_CFTABLE_PD_NC; 1069*7c478bd9Sstevel@tonic-gate } while (GET_BYTE(tp) & CISTPL_EXT_BIT); 1070*7c478bd9Sstevel@tonic-gate } 1071*7c478bd9Sstevel@tonic-gate 1072*7c478bd9Sstevel@tonic-gate val = CISTPL_PD_MAN(mantisa) * CISTPL_PD_EXP(exponent); 1073*7c478bd9Sstevel@tonic-gate 1074*7c478bd9Sstevel@tonic-gate /* 1075*7c478bd9Sstevel@tonic-gate * If we have to multiply the power value by ten, then just 1076*7c478bd9Sstevel@tonic-gate * don't bother dividing. 1077*7c478bd9Sstevel@tonic-gate */ 1078*7c478bd9Sstevel@tonic-gate if (! (*flags & CISTPL_CFTABLE_PD_MUL10)) 1079*7c478bd9Sstevel@tonic-gate val = val/10; /* do this since our mantissa table is X 10 */ 1080*7c478bd9Sstevel@tonic-gate 1081*7c478bd9Sstevel@tonic-gate /* 1082*7c478bd9Sstevel@tonic-gate * If we need to add some digits to the right of the decimal, do 1083*7c478bd9Sstevel@tonic-gate * that here. 1084*7c478bd9Sstevel@tonic-gate */ 1085*7c478bd9Sstevel@tonic-gate if (exponent) 1086*7c478bd9Sstevel@tonic-gate val = val + (digits * CISTPL_PD_EXP(exponent-1)); 1087*7c478bd9Sstevel@tonic-gate 1088*7c478bd9Sstevel@tonic-gate val /= 1000; 1089*7c478bd9Sstevel@tonic-gate 1090*7c478bd9Sstevel@tonic-gate return (val); 1091*7c478bd9Sstevel@tonic-gate } 1092*7c478bd9Sstevel@tonic-gate 1093*7c478bd9Sstevel@tonic-gate /* 1094*7c478bd9Sstevel@tonic-gate * cistpl_devspeed - returns device speed in nS 1095*7c478bd9Sstevel@tonic-gate * 1096*7c478bd9Sstevel@tonic-gate * cistpl_t *tp - tuple pointer. 1097*7c478bd9Sstevel@tonic-gate * cisdata_t spindex - device speed table index 1098*7c478bd9Sstevel@tonic-gate * int flags - operation flags 1099*7c478bd9Sstevel@tonic-gate * CISTPL_DEVSPEED_TABLE: 1100*7c478bd9Sstevel@tonic-gate * Use the spindex argument as an index into a simple 1101*7c478bd9Sstevel@tonic-gate * device speed table. ref: PCMCIA Release 2.01 1102*7c478bd9Sstevel@tonic-gate * Card Metaformat pg. 5-14 table 5-12. 1103*7c478bd9Sstevel@tonic-gate * When this flag is set, the spindex argument is ignored. 1104*7c478bd9Sstevel@tonic-gate * CISTPL_DEVSPEED_EXT: 1105*7c478bd9Sstevel@tonic-gate * Use the tp argument to access the 1106*7c478bd9Sstevel@tonic-gate * tuple data area containing an extended speed 1107*7c478bd9Sstevel@tonic-gate * code table. ref: PCMCIA Release 2.01 Card 1108*7c478bd9Sstevel@tonic-gate * Metaformat pg. 5-15 table 5-13. 1109*7c478bd9Sstevel@tonic-gate * The tp->read argument must point to the first byte of 1110*7c478bd9Sstevel@tonic-gate * an extended speed code table. 1111*7c478bd9Sstevel@tonic-gate * When this flag is set, the spindex argument is 1112*7c478bd9Sstevel@tonic-gate * used as a power-of-10 scale factor. We only allow 1113*7c478bd9Sstevel@tonic-gate * a maximum scale factor of 10^16. 1114*7c478bd9Sstevel@tonic-gate * 1115*7c478bd9Sstevel@tonic-gate * The device speed is returned in nS for all combinations of flags and 1116*7c478bd9Sstevel@tonic-gate * speed table entries. 1117*7c478bd9Sstevel@tonic-gate * 1118*7c478bd9Sstevel@tonic-gate * Note if you pass the CISTPL_DEVSPEED_TABLE with a spindex index that 1119*7c478bd9Sstevel@tonic-gate * refers to an extended speed table, you will get back an undefined 1120*7c478bd9Sstevel@tonic-gate * speed value. 1121*7c478bd9Sstevel@tonic-gate */ 1122*7c478bd9Sstevel@tonic-gate extern cistpl_devspeed_struct_t cistpl_devspeed_struct; 1123*7c478bd9Sstevel@tonic-gate 1124*7c478bd9Sstevel@tonic-gate uint32_t 1125*7c478bd9Sstevel@tonic-gate cistpl_devspeed(cistpl_t *tp, cisdata_t spindex, uint32_t flags) 1126*7c478bd9Sstevel@tonic-gate { 1127*7c478bd9Sstevel@tonic-gate int scale = 1, first; 1128*7c478bd9Sstevel@tonic-gate cisdata_t exspeed; 1129*7c478bd9Sstevel@tonic-gate int exponent, mantisa; 1130*7c478bd9Sstevel@tonic-gate uint32_t speed; 1131*7c478bd9Sstevel@tonic-gate 1132*7c478bd9Sstevel@tonic-gate switch (flags) { 1133*7c478bd9Sstevel@tonic-gate case CISTPL_DEVSPEED_TABLE: 1134*7c478bd9Sstevel@tonic-gate speed = CISTPL_DEVSPEED_TBL(spindex); 1135*7c478bd9Sstevel@tonic-gate break; 1136*7c478bd9Sstevel@tonic-gate case CISTPL_DEVSPEED_EXT: 1137*7c478bd9Sstevel@tonic-gate do { 1138*7c478bd9Sstevel@tonic-gate exspeed = GET_BYTE(tp); 1139*7c478bd9Sstevel@tonic-gate first = 1; 1140*7c478bd9Sstevel@tonic-gate if (first) { 1141*7c478bd9Sstevel@tonic-gate /* 1142*7c478bd9Sstevel@tonic-gate * XXX - ugh! we don't understand additional 1143*7c478bd9Sstevel@tonic-gate * exspeed bytes 1144*7c478bd9Sstevel@tonic-gate */ 1145*7c478bd9Sstevel@tonic-gate first = 0; 1146*7c478bd9Sstevel@tonic-gate exponent = (exspeed & 0x07); 1147*7c478bd9Sstevel@tonic-gate mantisa = (exspeed >> 3) & 0x0f; 1148*7c478bd9Sstevel@tonic-gate spindex &= 0x0f; /* only allow 10^16 */ 1149*7c478bd9Sstevel@tonic-gate while (spindex--) 1150*7c478bd9Sstevel@tonic-gate scale *= 10; 1151*7c478bd9Sstevel@tonic-gate } /* if (first) */ 1152*7c478bd9Sstevel@tonic-gate } while (exspeed & CISTPL_EXT_BIT); 1153*7c478bd9Sstevel@tonic-gate speed = scale * CISTPL_DEVSPEED_MAN(mantisa) * 1154*7c478bd9Sstevel@tonic-gate CISTPL_DEVSPEED_EXP(exponent); 1155*7c478bd9Sstevel@tonic-gate speed = speed/10; /* XXX - mantissa table is all X 10 */ 1156*7c478bd9Sstevel@tonic-gate break; 1157*7c478bd9Sstevel@tonic-gate default: 1158*7c478bd9Sstevel@tonic-gate break; 1159*7c478bd9Sstevel@tonic-gate } 1160*7c478bd9Sstevel@tonic-gate 1161*7c478bd9Sstevel@tonic-gate return (speed); 1162*7c478bd9Sstevel@tonic-gate } 1163*7c478bd9Sstevel@tonic-gate 1164*7c478bd9Sstevel@tonic-gate /* 1165*7c478bd9Sstevel@tonic-gate * cistpl_vers_2_handler - handler for the CISTPL_VERS_2 tuple 1166*7c478bd9Sstevel@tonic-gate * 1167*7c478bd9Sstevel@tonic-gate * void *arg - points to a XXX where the information is stuffed into 1168*7c478bd9Sstevel@tonic-gate */ 1169*7c478bd9Sstevel@tonic-gate uint32_t 1170*7c478bd9Sstevel@tonic-gate cistpl_vers_2_handler(cistpl_callout_t *co, cistpl_t *tp, 1171*7c478bd9Sstevel@tonic-gate uint32_t flags, void *arg) 1172*7c478bd9Sstevel@tonic-gate { 1173*7c478bd9Sstevel@tonic-gate /* 1174*7c478bd9Sstevel@tonic-gate * nothing special about our flags, so just call the 1175*7c478bd9Sstevel@tonic-gate * generic handler for this 1176*7c478bd9Sstevel@tonic-gate */ 1177*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_SET_FLAGS) 1178*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 1179*7c478bd9Sstevel@tonic-gate 1180*7c478bd9Sstevel@tonic-gate /* 1181*7c478bd9Sstevel@tonic-gate * We don't currently validate this tuple. This call will 1182*7c478bd9Sstevel@tonic-gate * always set tp->flags |= CISTPLF_VALID. 1183*7c478bd9Sstevel@tonic-gate */ 1184*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_COPY_DONE) 1185*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 1186*7c478bd9Sstevel@tonic-gate 1187*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_PARSE_LTUPLE) { 1188*7c478bd9Sstevel@tonic-gate cistpl_vers_2_t *cs = (cistpl_vers_2_t *)arg; 1189*7c478bd9Sstevel@tonic-gate 1190*7c478bd9Sstevel@tonic-gate RESET_TP(tp); 1191*7c478bd9Sstevel@tonic-gate 1192*7c478bd9Sstevel@tonic-gate cs->vers = GET_BYTE(tp); 1193*7c478bd9Sstevel@tonic-gate cs->comply = GET_BYTE(tp); 1194*7c478bd9Sstevel@tonic-gate cs->dindex = GET_SHORT(tp); 1195*7c478bd9Sstevel@tonic-gate 1196*7c478bd9Sstevel@tonic-gate cs->reserved = GET_SHORT(tp); 1197*7c478bd9Sstevel@tonic-gate 1198*7c478bd9Sstevel@tonic-gate cs->vspec8 = GET_BYTE(tp); 1199*7c478bd9Sstevel@tonic-gate cs->vspec9 = GET_BYTE(tp); 1200*7c478bd9Sstevel@tonic-gate cs->nhdr = GET_BYTE(tp); 1201*7c478bd9Sstevel@tonic-gate 1202*7c478bd9Sstevel@tonic-gate (void) strcpy(cs->oem, cis_getstr(tp)); 1203*7c478bd9Sstevel@tonic-gate 1204*7c478bd9Sstevel@tonic-gate if (GET_LEN(tp) > 0) 1205*7c478bd9Sstevel@tonic-gate (void) strcpy(cs->info, cis_getstr(tp)); 1206*7c478bd9Sstevel@tonic-gate else 1207*7c478bd9Sstevel@tonic-gate (void) strcpy(cs->info, "(no info)"); 1208*7c478bd9Sstevel@tonic-gate } 1209*7c478bd9Sstevel@tonic-gate 1210*7c478bd9Sstevel@tonic-gate return (CISTPLF_NOERROR); 1211*7c478bd9Sstevel@tonic-gate } 1212*7c478bd9Sstevel@tonic-gate 1213*7c478bd9Sstevel@tonic-gate /* 1214*7c478bd9Sstevel@tonic-gate * cistpl_jedec_handler - handler for JEDEC C and JEDEC A tuples 1215*7c478bd9Sstevel@tonic-gate * 1216*7c478bd9Sstevel@tonic-gate * void *arg - points to a XXX where the information is stuffed into 1217*7c478bd9Sstevel@tonic-gate */ 1218*7c478bd9Sstevel@tonic-gate uint32_t 1219*7c478bd9Sstevel@tonic-gate cistpl_jedec_handler(cistpl_callout_t *co, cistpl_t *tp, 1220*7c478bd9Sstevel@tonic-gate uint32_t flags, void *arg) 1221*7c478bd9Sstevel@tonic-gate { 1222*7c478bd9Sstevel@tonic-gate /* 1223*7c478bd9Sstevel@tonic-gate * nothing special about our flags, so just call the 1224*7c478bd9Sstevel@tonic-gate * generic handler for this 1225*7c478bd9Sstevel@tonic-gate */ 1226*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_SET_FLAGS) 1227*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 1228*7c478bd9Sstevel@tonic-gate 1229*7c478bd9Sstevel@tonic-gate /* 1230*7c478bd9Sstevel@tonic-gate * We don't currently validate this tuple. This call will 1231*7c478bd9Sstevel@tonic-gate * always set tp->flags |= CISTPLF_VALID. 1232*7c478bd9Sstevel@tonic-gate */ 1233*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_COPY_DONE) 1234*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 1235*7c478bd9Sstevel@tonic-gate 1236*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_PARSE_LTUPLE) { 1237*7c478bd9Sstevel@tonic-gate int nid; 1238*7c478bd9Sstevel@tonic-gate cistpl_jedec_t *cs = (cistpl_jedec_t *)arg; 1239*7c478bd9Sstevel@tonic-gate 1240*7c478bd9Sstevel@tonic-gate RESET_TP(tp); 1241*7c478bd9Sstevel@tonic-gate 1242*7c478bd9Sstevel@tonic-gate for (nid = 0; GET_LEN(tp) > 0 && 1243*7c478bd9Sstevel@tonic-gate nid < CISTPL_JEDEC_MAX_IDENTIFIERS && 1244*7c478bd9Sstevel@tonic-gate LOOK_BYTE(tp) != 0xFF; nid++) { 1245*7c478bd9Sstevel@tonic-gate cs->jid[nid].id = GET_BYTE(tp); 1246*7c478bd9Sstevel@tonic-gate cs->jid[nid].info = GET_BYTE(tp); 1247*7c478bd9Sstevel@tonic-gate } 1248*7c478bd9Sstevel@tonic-gate cs->nid = nid; 1249*7c478bd9Sstevel@tonic-gate } 1250*7c478bd9Sstevel@tonic-gate 1251*7c478bd9Sstevel@tonic-gate return (CISTPLF_NOERROR); 1252*7c478bd9Sstevel@tonic-gate } 1253*7c478bd9Sstevel@tonic-gate 1254*7c478bd9Sstevel@tonic-gate /* 1255*7c478bd9Sstevel@tonic-gate * cistpl_format_handler - handler for the CISTPL_FORMAT and 1256*7c478bd9Sstevel@tonic-gate * CISTPL_FORMAT_A tuples 1257*7c478bd9Sstevel@tonic-gate */ 1258*7c478bd9Sstevel@tonic-gate uint32_t 1259*7c478bd9Sstevel@tonic-gate cistpl_format_handler(cistpl_callout_t *co, cistpl_t *tp, 1260*7c478bd9Sstevel@tonic-gate uint32_t flags, void *arg) 1261*7c478bd9Sstevel@tonic-gate { 1262*7c478bd9Sstevel@tonic-gate /* 1263*7c478bd9Sstevel@tonic-gate * nothing special about our flags, so just call the 1264*7c478bd9Sstevel@tonic-gate * generic handler for this 1265*7c478bd9Sstevel@tonic-gate */ 1266*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_SET_FLAGS) 1267*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 1268*7c478bd9Sstevel@tonic-gate 1269*7c478bd9Sstevel@tonic-gate /* 1270*7c478bd9Sstevel@tonic-gate * We don't currently validate this tuple. This call will 1271*7c478bd9Sstevel@tonic-gate * always set tp->flags |= CISTPLF_VALID. 1272*7c478bd9Sstevel@tonic-gate */ 1273*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_COPY_DONE) 1274*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 1275*7c478bd9Sstevel@tonic-gate 1276*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_PARSE_LTUPLE) { 1277*7c478bd9Sstevel@tonic-gate cistpl_format_t *cs = (cistpl_format_t *)arg; 1278*7c478bd9Sstevel@tonic-gate 1279*7c478bd9Sstevel@tonic-gate RESET_TP(tp); 1280*7c478bd9Sstevel@tonic-gate 1281*7c478bd9Sstevel@tonic-gate cs->type = GET_BYTE(tp); 1282*7c478bd9Sstevel@tonic-gate cs->edc_length = LOOK_BYTE(tp) & EDC_LENGTH_MASK; 1283*7c478bd9Sstevel@tonic-gate cs->edc_type = ((uint32_t)GET_BYTE(tp) >> EDC_TYPE_SHIFT) & 1284*7c478bd9Sstevel@tonic-gate EDC_TYPE_MASK; 1285*7c478bd9Sstevel@tonic-gate cs->offset = GET_LONG(tp); 1286*7c478bd9Sstevel@tonic-gate cs->nbytes = GET_LONG(tp); 1287*7c478bd9Sstevel@tonic-gate 1288*7c478bd9Sstevel@tonic-gate switch (cs->type) { 1289*7c478bd9Sstevel@tonic-gate case TPLFMTTYPE_DISK: 1290*7c478bd9Sstevel@tonic-gate cs->dev.disk.bksize = GET_SHORT(tp); 1291*7c478bd9Sstevel@tonic-gate cs->dev.disk.nblocks = GET_LONG(tp); 1292*7c478bd9Sstevel@tonic-gate cs->dev.disk.edcloc = GET_LONG(tp); 1293*7c478bd9Sstevel@tonic-gate break; 1294*7c478bd9Sstevel@tonic-gate 1295*7c478bd9Sstevel@tonic-gate case TPLFMTTYPE_MEM: 1296*7c478bd9Sstevel@tonic-gate cs->dev.mem.flags = GET_BYTE(tp); 1297*7c478bd9Sstevel@tonic-gate cs->dev.mem.reserved = GET_BYTE(tp); 1298*7c478bd9Sstevel@tonic-gate cs->dev.mem.address = (caddr_t)(uintptr_t)GET_LONG(tp); 1299*7c478bd9Sstevel@tonic-gate cs->dev.disk.edcloc = GET_LONG(tp); 1300*7c478bd9Sstevel@tonic-gate break; 1301*7c478bd9Sstevel@tonic-gate default: 1302*7c478bd9Sstevel@tonic-gate /* don't know about any other type */ 1303*7c478bd9Sstevel@tonic-gate break; 1304*7c478bd9Sstevel@tonic-gate } 1305*7c478bd9Sstevel@tonic-gate } 1306*7c478bd9Sstevel@tonic-gate 1307*7c478bd9Sstevel@tonic-gate return (CISTPLF_NOERROR); 1308*7c478bd9Sstevel@tonic-gate } 1309*7c478bd9Sstevel@tonic-gate 1310*7c478bd9Sstevel@tonic-gate /* 1311*7c478bd9Sstevel@tonic-gate * cistpl_geometry_handler - handler for the CISTPL_GEOMETRY tuple 1312*7c478bd9Sstevel@tonic-gate * 1313*7c478bd9Sstevel@tonic-gate * void *arg - points to a XXX where the information is stuffed into 1314*7c478bd9Sstevel@tonic-gate */ 1315*7c478bd9Sstevel@tonic-gate uint32_t 1316*7c478bd9Sstevel@tonic-gate cistpl_geometry_handler(cistpl_callout_t *co, cistpl_t *tp, uint32_t flags, 1317*7c478bd9Sstevel@tonic-gate void *arg) 1318*7c478bd9Sstevel@tonic-gate { 1319*7c478bd9Sstevel@tonic-gate /* 1320*7c478bd9Sstevel@tonic-gate * nothing special about our flags, so just call the 1321*7c478bd9Sstevel@tonic-gate * generic handler for this 1322*7c478bd9Sstevel@tonic-gate */ 1323*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_SET_FLAGS) 1324*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 1325*7c478bd9Sstevel@tonic-gate 1326*7c478bd9Sstevel@tonic-gate /* 1327*7c478bd9Sstevel@tonic-gate * We don't currently validate this tuple. This call will 1328*7c478bd9Sstevel@tonic-gate * always set tp->flags |= CISTPLF_VALID. 1329*7c478bd9Sstevel@tonic-gate */ 1330*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_COPY_DONE) 1331*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 1332*7c478bd9Sstevel@tonic-gate 1333*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_PARSE_LTUPLE) { 1334*7c478bd9Sstevel@tonic-gate cistpl_geometry_t *cs = (cistpl_geometry_t *)arg; 1335*7c478bd9Sstevel@tonic-gate 1336*7c478bd9Sstevel@tonic-gate RESET_TP(tp); 1337*7c478bd9Sstevel@tonic-gate cs->spt = GET_BYTE(tp); 1338*7c478bd9Sstevel@tonic-gate cs->tpc = GET_BYTE(tp); 1339*7c478bd9Sstevel@tonic-gate cs->ncyl = GET_SHORT(tp); 1340*7c478bd9Sstevel@tonic-gate } 1341*7c478bd9Sstevel@tonic-gate return (CISTPLF_NOERROR); 1342*7c478bd9Sstevel@tonic-gate } 1343*7c478bd9Sstevel@tonic-gate 1344*7c478bd9Sstevel@tonic-gate /* 1345*7c478bd9Sstevel@tonic-gate * cistpl_byteorder_handler - handler for the CISTPL_BYTEORDER tuple 1346*7c478bd9Sstevel@tonic-gate * 1347*7c478bd9Sstevel@tonic-gate * void *arg - points to a XXX where the information is stuffed into 1348*7c478bd9Sstevel@tonic-gate */ 1349*7c478bd9Sstevel@tonic-gate uint32_t 1350*7c478bd9Sstevel@tonic-gate cistpl_byteorder_handler(cistpl_callout_t *co, cistpl_t *tp, uint32_t flags, 1351*7c478bd9Sstevel@tonic-gate void *arg) 1352*7c478bd9Sstevel@tonic-gate { 1353*7c478bd9Sstevel@tonic-gate /* 1354*7c478bd9Sstevel@tonic-gate * nothing special about our flags, so just call the 1355*7c478bd9Sstevel@tonic-gate * generic handler for this 1356*7c478bd9Sstevel@tonic-gate */ 1357*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_SET_FLAGS) 1358*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 1359*7c478bd9Sstevel@tonic-gate 1360*7c478bd9Sstevel@tonic-gate /* 1361*7c478bd9Sstevel@tonic-gate * We don't currently validate this tuple. This call will 1362*7c478bd9Sstevel@tonic-gate * always set tp->flags |= CISTPLF_VALID. 1363*7c478bd9Sstevel@tonic-gate */ 1364*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_COPY_DONE) 1365*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 1366*7c478bd9Sstevel@tonic-gate 1367*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_PARSE_LTUPLE) { 1368*7c478bd9Sstevel@tonic-gate cistpl_byteorder_t *cs = (cistpl_byteorder_t *)arg; 1369*7c478bd9Sstevel@tonic-gate 1370*7c478bd9Sstevel@tonic-gate RESET_TP(tp); 1371*7c478bd9Sstevel@tonic-gate cs->order = GET_BYTE(tp); 1372*7c478bd9Sstevel@tonic-gate cs->map = GET_BYTE(tp); 1373*7c478bd9Sstevel@tonic-gate } 1374*7c478bd9Sstevel@tonic-gate return (CISTPLF_NOERROR); 1375*7c478bd9Sstevel@tonic-gate } 1376*7c478bd9Sstevel@tonic-gate 1377*7c478bd9Sstevel@tonic-gate /* 1378*7c478bd9Sstevel@tonic-gate * cistpl_date_handler - handler for CISTPL_DATE card format tuple 1379*7c478bd9Sstevel@tonic-gate * 1380*7c478bd9Sstevel@tonic-gate * void *arg - points to a cistpl_date_t * where the 1381*7c478bd9Sstevel@tonic-gate * information is stuffed into 1382*7c478bd9Sstevel@tonic-gate */ 1383*7c478bd9Sstevel@tonic-gate uint32_t 1384*7c478bd9Sstevel@tonic-gate cistpl_date_handler(cistpl_callout_t *co, cistpl_t *tp, 1385*7c478bd9Sstevel@tonic-gate uint32_t flags, void *arg) 1386*7c478bd9Sstevel@tonic-gate { 1387*7c478bd9Sstevel@tonic-gate /* 1388*7c478bd9Sstevel@tonic-gate * nothing special about our flags, so just call the 1389*7c478bd9Sstevel@tonic-gate * generic handler for this 1390*7c478bd9Sstevel@tonic-gate */ 1391*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_SET_FLAGS) 1392*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 1393*7c478bd9Sstevel@tonic-gate 1394*7c478bd9Sstevel@tonic-gate /* 1395*7c478bd9Sstevel@tonic-gate * We don't currently validate this tuple. This call will 1396*7c478bd9Sstevel@tonic-gate * always set tp->flags |= CISTPLF_VALID. 1397*7c478bd9Sstevel@tonic-gate */ 1398*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_COPY_DONE) 1399*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 1400*7c478bd9Sstevel@tonic-gate 1401*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_PARSE_LTUPLE) { 1402*7c478bd9Sstevel@tonic-gate cistpl_date_t *cs = (cistpl_date_t *)arg; 1403*7c478bd9Sstevel@tonic-gate 1404*7c478bd9Sstevel@tonic-gate RESET_TP(tp); 1405*7c478bd9Sstevel@tonic-gate cs->time = GET_SHORT(tp); 1406*7c478bd9Sstevel@tonic-gate cs->day = GET_SHORT(tp); 1407*7c478bd9Sstevel@tonic-gate } 1408*7c478bd9Sstevel@tonic-gate return (CISTPLF_NOERROR); 1409*7c478bd9Sstevel@tonic-gate } 1410*7c478bd9Sstevel@tonic-gate 1411*7c478bd9Sstevel@tonic-gate /* 1412*7c478bd9Sstevel@tonic-gate * cistpl_battery_handler - handler for CISTPL_BATTERY battery replacement 1413*7c478bd9Sstevel@tonic-gate * date tuple 1414*7c478bd9Sstevel@tonic-gate * 1415*7c478bd9Sstevel@tonic-gate * void *arg - points to a cistpl_battery_t * where the 1416*7c478bd9Sstevel@tonic-gate * information is stuffed into 1417*7c478bd9Sstevel@tonic-gate */ 1418*7c478bd9Sstevel@tonic-gate uint32_t 1419*7c478bd9Sstevel@tonic-gate cistpl_battery_handler(cistpl_callout_t *co, cistpl_t *tp, 1420*7c478bd9Sstevel@tonic-gate uint32_t flags, void *arg) 1421*7c478bd9Sstevel@tonic-gate { 1422*7c478bd9Sstevel@tonic-gate /* 1423*7c478bd9Sstevel@tonic-gate * nothing special about our flags, so just call the 1424*7c478bd9Sstevel@tonic-gate * generic handler for this 1425*7c478bd9Sstevel@tonic-gate */ 1426*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_SET_FLAGS) 1427*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 1428*7c478bd9Sstevel@tonic-gate 1429*7c478bd9Sstevel@tonic-gate /* 1430*7c478bd9Sstevel@tonic-gate * We don't currently validate this tuple. This call will 1431*7c478bd9Sstevel@tonic-gate * always set tp->flags |= CISTPLF_VALID. 1432*7c478bd9Sstevel@tonic-gate */ 1433*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_COPY_DONE) 1434*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 1435*7c478bd9Sstevel@tonic-gate 1436*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_PARSE_LTUPLE) { 1437*7c478bd9Sstevel@tonic-gate cistpl_battery_t *cs = (cistpl_battery_t *)arg; 1438*7c478bd9Sstevel@tonic-gate 1439*7c478bd9Sstevel@tonic-gate RESET_TP(tp); 1440*7c478bd9Sstevel@tonic-gate cs->rday = GET_SHORT(tp); 1441*7c478bd9Sstevel@tonic-gate cs->xday = GET_SHORT(tp); 1442*7c478bd9Sstevel@tonic-gate } 1443*7c478bd9Sstevel@tonic-gate return (CISTPLF_NOERROR); 1444*7c478bd9Sstevel@tonic-gate } 1445*7c478bd9Sstevel@tonic-gate 1446*7c478bd9Sstevel@tonic-gate /* 1447*7c478bd9Sstevel@tonic-gate * cistpl_org_handler - handler for CISTPL_ORG data organization tuple 1448*7c478bd9Sstevel@tonic-gate * 1449*7c478bd9Sstevel@tonic-gate * void *arg - points to a cistpl_org_t * where the 1450*7c478bd9Sstevel@tonic-gate * information is stuffed into 1451*7c478bd9Sstevel@tonic-gate */ 1452*7c478bd9Sstevel@tonic-gate uint32_t 1453*7c478bd9Sstevel@tonic-gate cistpl_org_handler(cistpl_callout_t *co, cistpl_t *tp, 1454*7c478bd9Sstevel@tonic-gate uint32_t flags, void *arg) 1455*7c478bd9Sstevel@tonic-gate { 1456*7c478bd9Sstevel@tonic-gate /* 1457*7c478bd9Sstevel@tonic-gate * nothing special about our flags, so just call the 1458*7c478bd9Sstevel@tonic-gate * generic handler for this 1459*7c478bd9Sstevel@tonic-gate */ 1460*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_SET_FLAGS) 1461*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 1462*7c478bd9Sstevel@tonic-gate 1463*7c478bd9Sstevel@tonic-gate /* 1464*7c478bd9Sstevel@tonic-gate * We don't currently validate this tuple. This call will 1465*7c478bd9Sstevel@tonic-gate * always set tp->flags |= CISTPLF_VALID. 1466*7c478bd9Sstevel@tonic-gate */ 1467*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_COPY_DONE) 1468*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 1469*7c478bd9Sstevel@tonic-gate 1470*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_PARSE_LTUPLE) { 1471*7c478bd9Sstevel@tonic-gate cistpl_org_t *cs = (cistpl_org_t *)arg; 1472*7c478bd9Sstevel@tonic-gate 1473*7c478bd9Sstevel@tonic-gate RESET_TP(tp); 1474*7c478bd9Sstevel@tonic-gate cs->type = GET_BYTE(tp); 1475*7c478bd9Sstevel@tonic-gate 1476*7c478bd9Sstevel@tonic-gate (void) strcpy(cs->desc, cis_getstr(tp)); 1477*7c478bd9Sstevel@tonic-gate } 1478*7c478bd9Sstevel@tonic-gate 1479*7c478bd9Sstevel@tonic-gate return (CISTPLF_NOERROR); 1480*7c478bd9Sstevel@tonic-gate } 1481*7c478bd9Sstevel@tonic-gate 1482*7c478bd9Sstevel@tonic-gate 1483*7c478bd9Sstevel@tonic-gate /* 1484*7c478bd9Sstevel@tonic-gate * cistpl_manfid_handler - handler for CISTPL_MANFID, the manufacturer ID tuple 1485*7c478bd9Sstevel@tonic-gate * 1486*7c478bd9Sstevel@tonic-gate * void *arg - points to a XXX where the information is stuffed into 1487*7c478bd9Sstevel@tonic-gate */ 1488*7c478bd9Sstevel@tonic-gate uint32_t 1489*7c478bd9Sstevel@tonic-gate cistpl_manfid_handler(cistpl_callout_t *co, cistpl_t *tp, 1490*7c478bd9Sstevel@tonic-gate uint32_t flags, void *arg) 1491*7c478bd9Sstevel@tonic-gate { 1492*7c478bd9Sstevel@tonic-gate /* 1493*7c478bd9Sstevel@tonic-gate * nothing special about our flags, so just call the 1494*7c478bd9Sstevel@tonic-gate * generic handler for this 1495*7c478bd9Sstevel@tonic-gate */ 1496*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_SET_FLAGS) 1497*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 1498*7c478bd9Sstevel@tonic-gate 1499*7c478bd9Sstevel@tonic-gate /* 1500*7c478bd9Sstevel@tonic-gate * We don't currently validate this tuple. This call will 1501*7c478bd9Sstevel@tonic-gate * always set tp->flags |= CISTPLF_VALID. 1502*7c478bd9Sstevel@tonic-gate */ 1503*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_COPY_DONE) 1504*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 1505*7c478bd9Sstevel@tonic-gate 1506*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_PARSE_LTUPLE) { 1507*7c478bd9Sstevel@tonic-gate cistpl_manfid_t *cs = (cistpl_manfid_t *)arg; 1508*7c478bd9Sstevel@tonic-gate 1509*7c478bd9Sstevel@tonic-gate RESET_TP(tp); 1510*7c478bd9Sstevel@tonic-gate cs->manf = GET_SHORT(tp); 1511*7c478bd9Sstevel@tonic-gate cs->card = GET_SHORT(tp); 1512*7c478bd9Sstevel@tonic-gate } 1513*7c478bd9Sstevel@tonic-gate return (CISTPLF_NOERROR); 1514*7c478bd9Sstevel@tonic-gate } 1515*7c478bd9Sstevel@tonic-gate 1516*7c478bd9Sstevel@tonic-gate /* 1517*7c478bd9Sstevel@tonic-gate * cistpl_funcid_handler - handler for CISTPL_FUNCID 1518*7c478bd9Sstevel@tonic-gate * 1519*7c478bd9Sstevel@tonic-gate * void *arg - points to a XXX where the information is stuffed into 1520*7c478bd9Sstevel@tonic-gate */ 1521*7c478bd9Sstevel@tonic-gate uint32_t 1522*7c478bd9Sstevel@tonic-gate cistpl_funcid_handler(cistpl_callout_t *co, cistpl_t *tp, 1523*7c478bd9Sstevel@tonic-gate uint32_t flags, void *arg) 1524*7c478bd9Sstevel@tonic-gate { 1525*7c478bd9Sstevel@tonic-gate /* 1526*7c478bd9Sstevel@tonic-gate * nothing special about our flags, so just call the 1527*7c478bd9Sstevel@tonic-gate * generic handler for this 1528*7c478bd9Sstevel@tonic-gate */ 1529*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_SET_FLAGS) 1530*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 1531*7c478bd9Sstevel@tonic-gate 1532*7c478bd9Sstevel@tonic-gate /* 1533*7c478bd9Sstevel@tonic-gate * We don't currently validate this tuple. This call will 1534*7c478bd9Sstevel@tonic-gate * always set tp->flags |= CISTPLF_VALID. 1535*7c478bd9Sstevel@tonic-gate */ 1536*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_COPY_DONE) 1537*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 1538*7c478bd9Sstevel@tonic-gate 1539*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_PARSE_LTUPLE) { 1540*7c478bd9Sstevel@tonic-gate cistpl_funcid_t *cs = (cistpl_funcid_t *)arg; 1541*7c478bd9Sstevel@tonic-gate 1542*7c478bd9Sstevel@tonic-gate RESET_TP(tp); 1543*7c478bd9Sstevel@tonic-gate 1544*7c478bd9Sstevel@tonic-gate cs->function = GET_BYTE(tp); 1545*7c478bd9Sstevel@tonic-gate cs->sysinit = GET_BYTE(tp); 1546*7c478bd9Sstevel@tonic-gate } 1547*7c478bd9Sstevel@tonic-gate return (CISTPLF_NOERROR); 1548*7c478bd9Sstevel@tonic-gate } 1549*7c478bd9Sstevel@tonic-gate 1550*7c478bd9Sstevel@tonic-gate 1551*7c478bd9Sstevel@tonic-gate /* 1552*7c478bd9Sstevel@tonic-gate * cistpl_funce_serial_handler - handler for the CISTPL_FUNCE/SERIAL tuple 1553*7c478bd9Sstevel@tonic-gate * 1554*7c478bd9Sstevel@tonic-gate * void *arg - points to a XXX where the information is stuffed into 1555*7c478bd9Sstevel@tonic-gate */ 1556*7c478bd9Sstevel@tonic-gate uint32_t 1557*7c478bd9Sstevel@tonic-gate cistpl_funce_serial_handler(cistpl_callout_t *co, cistpl_t *tp, 1558*7c478bd9Sstevel@tonic-gate uint32_t flags, void *arg) 1559*7c478bd9Sstevel@tonic-gate { 1560*7c478bd9Sstevel@tonic-gate int subfunction; 1561*7c478bd9Sstevel@tonic-gate 1562*7c478bd9Sstevel@tonic-gate /* 1563*7c478bd9Sstevel@tonic-gate * nothing special about our flags, so just call the 1564*7c478bd9Sstevel@tonic-gate * generic handler for this 1565*7c478bd9Sstevel@tonic-gate */ 1566*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_SET_FLAGS) 1567*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 1568*7c478bd9Sstevel@tonic-gate 1569*7c478bd9Sstevel@tonic-gate /* 1570*7c478bd9Sstevel@tonic-gate * We don't currently validate this tuple. This call will 1571*7c478bd9Sstevel@tonic-gate * always set tp->flags |= CISTPLF_VALID. 1572*7c478bd9Sstevel@tonic-gate */ 1573*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_COPY_DONE) 1574*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 1575*7c478bd9Sstevel@tonic-gate 1576*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_PARSE_LTUPLE) { 1577*7c478bd9Sstevel@tonic-gate cistpl_funce_t *cs = (cistpl_funce_t *)arg; 1578*7c478bd9Sstevel@tonic-gate 1579*7c478bd9Sstevel@tonic-gate RESET_TP(tp); 1580*7c478bd9Sstevel@tonic-gate 1581*7c478bd9Sstevel@tonic-gate cs->function = TPLFUNC_SERIAL; 1582*7c478bd9Sstevel@tonic-gate cs->subfunction = subfunction = GET_BYTE(tp); 1583*7c478bd9Sstevel@tonic-gate switch (subfunction & 0xF) { 1584*7c478bd9Sstevel@tonic-gate case TPLFE_SUB_SERIAL: 1585*7c478bd9Sstevel@tonic-gate case TPLFE_CAP_SERIAL_DATA: 1586*7c478bd9Sstevel@tonic-gate case TPLFE_CAP_SERIAL_FAX: 1587*7c478bd9Sstevel@tonic-gate case TPLFE_CAP_SERIAL_VOICE: 1588*7c478bd9Sstevel@tonic-gate cs->data.serial.ua = GET_BYTE(tp); 1589*7c478bd9Sstevel@tonic-gate cs->data.serial.uc = GET_SHORT(tp); 1590*7c478bd9Sstevel@tonic-gate break; 1591*7c478bd9Sstevel@tonic-gate case TPLFE_SUB_MODEM_COMMON: 1592*7c478bd9Sstevel@tonic-gate case TPLFE_CAP_MODEM_DATA: 1593*7c478bd9Sstevel@tonic-gate case TPLFE_CAP_MODEM_FAX: 1594*7c478bd9Sstevel@tonic-gate case TPLFE_CAP_MODEM_VOICE: 1595*7c478bd9Sstevel@tonic-gate cs->data.modem.fc = GET_BYTE(tp); 1596*7c478bd9Sstevel@tonic-gate cs->data.modem.cb = (GET_BYTE(tp) + 1) * 4; 1597*7c478bd9Sstevel@tonic-gate cs->data.modem.eb = GET_INT24(tp); 1598*7c478bd9Sstevel@tonic-gate cs->data.modem.tb = GET_INT24(tp); 1599*7c478bd9Sstevel@tonic-gate break; 1600*7c478bd9Sstevel@tonic-gate case TPLFE_SUB_MODEM_DATA: 1601*7c478bd9Sstevel@tonic-gate cs->data.data_modem.ud = GET_BE_SHORT(tp) * 75; 1602*7c478bd9Sstevel@tonic-gate cs->data.data_modem.ms = GET_SHORT(tp); 1603*7c478bd9Sstevel@tonic-gate cs->data.data_modem.em = GET_BYTE(tp); 1604*7c478bd9Sstevel@tonic-gate cs->data.data_modem.dc = GET_BYTE(tp); 1605*7c478bd9Sstevel@tonic-gate cs->data.data_modem.cm = GET_BYTE(tp); 1606*7c478bd9Sstevel@tonic-gate cs->data.data_modem.ex = GET_BYTE(tp); 1607*7c478bd9Sstevel@tonic-gate cs->data.data_modem.dy = GET_BYTE(tp); 1608*7c478bd9Sstevel@tonic-gate cs->data.data_modem.ef = GET_BYTE(tp); 1609*7c478bd9Sstevel@tonic-gate for (cs->data.data_modem.ncd = 0; 1610*7c478bd9Sstevel@tonic-gate GET_LEN(tp) > 0 && cs->data.data_modem.ncd < 16; 1611*7c478bd9Sstevel@tonic-gate cs->data.data_modem.ncd++) 1612*7c478bd9Sstevel@tonic-gate if (LOOK_BYTE(tp) != 255) { 1613*7c478bd9Sstevel@tonic-gate cs->data.data_modem.cd[ 1614*7c478bd9Sstevel@tonic-gate cs->data.data_modem.ncd] = 1615*7c478bd9Sstevel@tonic-gate GET_BYTE(tp); 1616*7c478bd9Sstevel@tonic-gate } else { 1617*7c478bd9Sstevel@tonic-gate GET_BYTE(tp); 1618*7c478bd9Sstevel@tonic-gate break; 1619*7c478bd9Sstevel@tonic-gate } 1620*7c478bd9Sstevel@tonic-gate break; 1621*7c478bd9Sstevel@tonic-gate case TPLFE_SUB_MODEM_FAX: 1622*7c478bd9Sstevel@tonic-gate cs->data.fax.uf = GET_BE_SHORT(tp) * 75; 1623*7c478bd9Sstevel@tonic-gate cs->data.fax.fm = GET_BYTE(tp); 1624*7c478bd9Sstevel@tonic-gate cs->data.fax.fy = GET_BYTE(tp); 1625*7c478bd9Sstevel@tonic-gate cs->data.fax.fs = GET_SHORT(tp); 1626*7c478bd9Sstevel@tonic-gate for (cs->data.fax.ncf = 0; 1627*7c478bd9Sstevel@tonic-gate GET_LEN(tp) > 0 && cs->data.fax.ncf < 16; 1628*7c478bd9Sstevel@tonic-gate cs->data.fax.ncf++) 1629*7c478bd9Sstevel@tonic-gate if (LOOK_BYTE(tp) != 255) { 1630*7c478bd9Sstevel@tonic-gate cs->data.fax.cf[cs->data.fax.ncf] = 1631*7c478bd9Sstevel@tonic-gate GET_BYTE(tp); 1632*7c478bd9Sstevel@tonic-gate } else { 1633*7c478bd9Sstevel@tonic-gate GET_BYTE(tp); 1634*7c478bd9Sstevel@tonic-gate break; 1635*7c478bd9Sstevel@tonic-gate } 1636*7c478bd9Sstevel@tonic-gate break; 1637*7c478bd9Sstevel@tonic-gate case TPLFE_SUB_VOICE: 1638*7c478bd9Sstevel@tonic-gate cs->data.voice.uv = GET_BE_SHORT(tp) * 75; 1639*7c478bd9Sstevel@tonic-gate for (cs->data.voice.nsr = 0; LOOK_BYTE(tp) != 0 && 1640*7c478bd9Sstevel@tonic-gate GET_LEN(tp) >= 2; 1641*7c478bd9Sstevel@tonic-gate cs->data.voice.nsr++) { 1642*7c478bd9Sstevel@tonic-gate cs->data.voice.sr[cs->data.voice.nsr] = 1643*7c478bd9Sstevel@tonic-gate GET_BYTE(tp) * 1000; 1644*7c478bd9Sstevel@tonic-gate cs->data.voice.sr[cs->data.voice.nsr] += 1645*7c478bd9Sstevel@tonic-gate GET_BYTE(tp) * 100; 1646*7c478bd9Sstevel@tonic-gate } 1647*7c478bd9Sstevel@tonic-gate for (cs->data.voice.nss = 0; LOOK_BYTE(tp) != 0 && 1648*7c478bd9Sstevel@tonic-gate GET_LEN(tp) >= 2; 1649*7c478bd9Sstevel@tonic-gate cs->data.voice.nss++) { 1650*7c478bd9Sstevel@tonic-gate cs->data.voice.ss[cs->data.voice.nss] = 1651*7c478bd9Sstevel@tonic-gate GET_BYTE(tp) * 10; 1652*7c478bd9Sstevel@tonic-gate cs->data.voice.ss[cs->data.voice.nss] += 1653*7c478bd9Sstevel@tonic-gate GET_BYTE(tp); 1654*7c478bd9Sstevel@tonic-gate } 1655*7c478bd9Sstevel@tonic-gate for (cs->data.voice.nsc = 0; LOOK_BYTE(tp) != 0 && 1656*7c478bd9Sstevel@tonic-gate GET_LEN(tp) >= 1; 1657*7c478bd9Sstevel@tonic-gate cs->data.voice.nsc++) { 1658*7c478bd9Sstevel@tonic-gate cs->data.voice.sc[cs->data.voice.nsc] = 1659*7c478bd9Sstevel@tonic-gate GET_BYTE(tp); 1660*7c478bd9Sstevel@tonic-gate } 1661*7c478bd9Sstevel@tonic-gate break; 1662*7c478bd9Sstevel@tonic-gate default: 1663*7c478bd9Sstevel@tonic-gate break; 1664*7c478bd9Sstevel@tonic-gate } 1665*7c478bd9Sstevel@tonic-gate } 1666*7c478bd9Sstevel@tonic-gate return (CISTPLF_NOERROR); 1667*7c478bd9Sstevel@tonic-gate } 1668*7c478bd9Sstevel@tonic-gate 1669*7c478bd9Sstevel@tonic-gate /* 1670*7c478bd9Sstevel@tonic-gate * cistpl_funce_lan_handler - handler for the CISTPL_FUNCE/LAN tuple 1671*7c478bd9Sstevel@tonic-gate * 1672*7c478bd9Sstevel@tonic-gate * void *arg - points to a XXX where the information is stuffed into 1673*7c478bd9Sstevel@tonic-gate */ 1674*7c478bd9Sstevel@tonic-gate uint32_t 1675*7c478bd9Sstevel@tonic-gate cistpl_funce_lan_handler(cistpl_callout_t *co, cistpl_t *tp, uint32_t flags, 1676*7c478bd9Sstevel@tonic-gate void *arg) 1677*7c478bd9Sstevel@tonic-gate { 1678*7c478bd9Sstevel@tonic-gate int subfunction; 1679*7c478bd9Sstevel@tonic-gate 1680*7c478bd9Sstevel@tonic-gate /* 1681*7c478bd9Sstevel@tonic-gate * nothing special about our flags, so just call the 1682*7c478bd9Sstevel@tonic-gate * generic handler for this 1683*7c478bd9Sstevel@tonic-gate */ 1684*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_SET_FLAGS) 1685*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 1686*7c478bd9Sstevel@tonic-gate 1687*7c478bd9Sstevel@tonic-gate /* 1688*7c478bd9Sstevel@tonic-gate * We don't currently validate this tuple. This call will 1689*7c478bd9Sstevel@tonic-gate * always set tp->flags |= CISTPLF_VALID. 1690*7c478bd9Sstevel@tonic-gate */ 1691*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_COPY_DONE) 1692*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 1693*7c478bd9Sstevel@tonic-gate 1694*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_PARSE_LTUPLE) { 1695*7c478bd9Sstevel@tonic-gate int i; 1696*7c478bd9Sstevel@tonic-gate cistpl_funce_t *cs = (cistpl_funce_t *)arg; 1697*7c478bd9Sstevel@tonic-gate 1698*7c478bd9Sstevel@tonic-gate RESET_TP(tp); 1699*7c478bd9Sstevel@tonic-gate 1700*7c478bd9Sstevel@tonic-gate cs->function = TPLFUNC_LAN; 1701*7c478bd9Sstevel@tonic-gate cs->subfunction = subfunction = GET_BYTE(tp); 1702*7c478bd9Sstevel@tonic-gate 1703*7c478bd9Sstevel@tonic-gate switch (subfunction) { 1704*7c478bd9Sstevel@tonic-gate case TPLFE_NETWORK_INFO: 1705*7c478bd9Sstevel@tonic-gate cs->data.lan.tech = GET_BYTE(tp); 1706*7c478bd9Sstevel@tonic-gate cs->data.lan.speed = GET_BYTE(tp); 1707*7c478bd9Sstevel@tonic-gate i = GET_BYTE(tp); 1708*7c478bd9Sstevel@tonic-gate if (i < 24) { 1709*7c478bd9Sstevel@tonic-gate cs->data.lan.speed <<= i; 1710*7c478bd9Sstevel@tonic-gate } else { 1711*7c478bd9Sstevel@tonic-gate /* 1712*7c478bd9Sstevel@tonic-gate * if speed is too large a value 1713*7c478bd9Sstevel@tonic-gate * to hold in a uint32 flag it and 1714*7c478bd9Sstevel@tonic-gate * store as [mantissa][exponent] 1715*7c478bd9Sstevel@tonic-gate * in least significant 16 bits 1716*7c478bd9Sstevel@tonic-gate */ 1717*7c478bd9Sstevel@tonic-gate cs->data.lan.speed = 0x80000000 | 1718*7c478bd9Sstevel@tonic-gate (cs->data.lan.speed << 8) | i; 1719*7c478bd9Sstevel@tonic-gate } 1720*7c478bd9Sstevel@tonic-gate cs->data.lan.media = GET_BYTE(tp); 1721*7c478bd9Sstevel@tonic-gate cs->data.lan.con = GET_BYTE(tp); 1722*7c478bd9Sstevel@tonic-gate cs->data.lan.id_sz = GET_BYTE(tp); 1723*7c478bd9Sstevel@tonic-gate if (cs->data.lan.id_sz <= 16) { 1724*7c478bd9Sstevel@tonic-gate for (i = 0; i < cs->data.lan.id_sz; i++) 1725*7c478bd9Sstevel@tonic-gate cs->data.lan.id[i] = GET_BYTE(tp); 1726*7c478bd9Sstevel@tonic-gate } 1727*7c478bd9Sstevel@tonic-gate break; 1728*7c478bd9Sstevel@tonic-gate default: 1729*7c478bd9Sstevel@tonic-gate /* unknown LAN tuple type */ 1730*7c478bd9Sstevel@tonic-gate return (CISTPLF_UNKNOWN); 1731*7c478bd9Sstevel@tonic-gate } 1732*7c478bd9Sstevel@tonic-gate } 1733*7c478bd9Sstevel@tonic-gate return (CISTPLF_NOERROR); 1734*7c478bd9Sstevel@tonic-gate } 1735*7c478bd9Sstevel@tonic-gate 1736*7c478bd9Sstevel@tonic-gate /* 1737*7c478bd9Sstevel@tonic-gate * cistpl_linktarget_handler - handler for CISTPL_LINKTARGET tuple 1738*7c478bd9Sstevel@tonic-gate * 1739*7c478bd9Sstevel@tonic-gate * void *arg - points to a cistpl_linktarget_t * where the 1740*7c478bd9Sstevel@tonic-gate * information is stuffed into 1741*7c478bd9Sstevel@tonic-gate * 1742*7c478bd9Sstevel@tonic-gate * If HANDTPL_COPY_DONE is set, we just validate the tuple but 1743*7c478bd9Sstevel@tonic-gate * do not return any values. 1744*7c478bd9Sstevel@tonic-gate * If HANDTPL_PARSE_LTUPLE is set, we validate the tuple and 1745*7c478bd9Sstevel@tonic-gate * return the parsed tuple data if the tuple is valid. 1746*7c478bd9Sstevel@tonic-gate * 1747*7c478bd9Sstevel@tonic-gate * If the tuple link field is invalid, the CISTPLF_LINK_INVALID flag 1748*7c478bd9Sstevel@tonic-gate * will be set in the tp->flags field and HANDTPL_ERROR 1749*7c478bd9Sstevel@tonic-gate * will be returned. 1750*7c478bd9Sstevel@tonic-gate * 1751*7c478bd9Sstevel@tonic-gate * If the tuple data body is invalid, the CISTPLF_PARAMS_INVALID flag 1752*7c478bd9Sstevel@tonic-gate * will be set in the tp->flags field and HANDTPL_ERROR 1753*7c478bd9Sstevel@tonic-gate * will be returned. 1754*7c478bd9Sstevel@tonic-gate * 1755*7c478bd9Sstevel@tonic-gate * The tuple is considered invalid if it's link field is less than 1756*7c478bd9Sstevel@tonic-gate * MIN_LINKTARGET_LENGTH or if the data body of the tuple 1757*7c478bd9Sstevel@tonic-gate * does not contain the pattern CISTPL_LINKTARGET_MAGIC. 1758*7c478bd9Sstevel@tonic-gate * 1759*7c478bd9Sstevel@tonic-gate * XXX At some point we should revisit this to see if we can call 1760*7c478bd9Sstevel@tonic-gate * cis_validate_longlink_acm instead of doing the validation 1761*7c478bd9Sstevel@tonic-gate * in both places. 1762*7c478bd9Sstevel@tonic-gate */ 1763*7c478bd9Sstevel@tonic-gate uint32_t 1764*7c478bd9Sstevel@tonic-gate cistpl_linktarget_handler(cistpl_callout_t *co, cistpl_t *tp, uint32_t flags, 1765*7c478bd9Sstevel@tonic-gate void *arg) 1766*7c478bd9Sstevel@tonic-gate { 1767*7c478bd9Sstevel@tonic-gate /* 1768*7c478bd9Sstevel@tonic-gate * nothing special about our flags, so just call the 1769*7c478bd9Sstevel@tonic-gate * generic handler for this 1770*7c478bd9Sstevel@tonic-gate */ 1771*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_SET_FLAGS) 1772*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 1773*7c478bd9Sstevel@tonic-gate 1774*7c478bd9Sstevel@tonic-gate /* 1775*7c478bd9Sstevel@tonic-gate * Validate the tuple for both the HANDTPL_COPY_DONE case and 1776*7c478bd9Sstevel@tonic-gate * the HANDTPL_PARSE_LTUPLE case. Only return data in 1777*7c478bd9Sstevel@tonic-gate * the HANDTPL_PARSE_LTUPLE case. 1778*7c478bd9Sstevel@tonic-gate */ 1779*7c478bd9Sstevel@tonic-gate if (flags & (HANDTPL_COPY_DONE | HANDTPL_PARSE_LTUPLE)) { 1780*7c478bd9Sstevel@tonic-gate uchar_t *cp; 1781*7c478bd9Sstevel@tonic-gate cisdata_t tl; 1782*7c478bd9Sstevel@tonic-gate 1783*7c478bd9Sstevel@tonic-gate if ((tl = tp->len) >= (cisdata_t)MIN_LINKTARGET_LENGTH) { 1784*7c478bd9Sstevel@tonic-gate cisdata_t *ltm = (cisdata_t *)CISTPL_LINKTARGET_MAGIC; 1785*7c478bd9Sstevel@tonic-gate int i; 1786*7c478bd9Sstevel@tonic-gate 1787*7c478bd9Sstevel@tonic-gate RESET_TP(tp); 1788*7c478bd9Sstevel@tonic-gate 1789*7c478bd9Sstevel@tonic-gate /* 1790*7c478bd9Sstevel@tonic-gate * Save the start address of this string in case 1791*7c478bd9Sstevel@tonic-gate * the tuple turns out to be OK since we 1792*7c478bd9Sstevel@tonic-gate * need to pass this address to the caller. 1793*7c478bd9Sstevel@tonic-gate */ 1794*7c478bd9Sstevel@tonic-gate cp = GET_BYTE_ADDR(tp); 1795*7c478bd9Sstevel@tonic-gate 1796*7c478bd9Sstevel@tonic-gate /* 1797*7c478bd9Sstevel@tonic-gate * Check each byte of the tuple body to see if it 1798*7c478bd9Sstevel@tonic-gate * matches what should be in a valid tuple. 1799*7c478bd9Sstevel@tonic-gate * Note that we can't assume that this magic 1800*7c478bd9Sstevel@tonic-gate * pattern is a string and we also only need 1801*7c478bd9Sstevel@tonic-gate * to be sure that MIN_LINKTARGET_LENGTH bytes 1802*7c478bd9Sstevel@tonic-gate * match; all bytes following this magic number 1803*7c478bd9Sstevel@tonic-gate * in this tuple are ignored. 1804*7c478bd9Sstevel@tonic-gate */ 1805*7c478bd9Sstevel@tonic-gate for (i = 0; i < MIN_LINKTARGET_LENGTH; i++) { 1806*7c478bd9Sstevel@tonic-gate if (GET_BYTE(tp) != *ltm++) { 1807*7c478bd9Sstevel@tonic-gate tp->flags |= CISTPLF_PARAMS_INVALID; 1808*7c478bd9Sstevel@tonic-gate return (HANDTPL_ERROR); 1809*7c478bd9Sstevel@tonic-gate } 1810*7c478bd9Sstevel@tonic-gate } /* MIN_LINKTARGET_LENGTH */ 1811*7c478bd9Sstevel@tonic-gate 1812*7c478bd9Sstevel@tonic-gate /* 1813*7c478bd9Sstevel@tonic-gate * This tuple is valid. 1814*7c478bd9Sstevel@tonic-gate */ 1815*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_COPY_DONE) 1816*7c478bd9Sstevel@tonic-gate tp->flags |= CISTPLF_VALID; 1817*7c478bd9Sstevel@tonic-gate 1818*7c478bd9Sstevel@tonic-gate /* 1819*7c478bd9Sstevel@tonic-gate * If we're also parsing this tuple, then 1820*7c478bd9Sstevel@tonic-gate * setup the return values. 1821*7c478bd9Sstevel@tonic-gate */ 1822*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_PARSE_LTUPLE) { 1823*7c478bd9Sstevel@tonic-gate cistpl_linktarget_t *cs = 1824*7c478bd9Sstevel@tonic-gate (cistpl_linktarget_t *)arg; 1825*7c478bd9Sstevel@tonic-gate 1826*7c478bd9Sstevel@tonic-gate cs->length = tl; 1827*7c478bd9Sstevel@tonic-gate (void) strncpy(cs->tpltg_tag, (char *)cp, 1828*7c478bd9Sstevel@tonic-gate cs->length); 1829*7c478bd9Sstevel@tonic-gate cs->tpltg_tag[cs->length] = NULL; 1830*7c478bd9Sstevel@tonic-gate 1831*7c478bd9Sstevel@tonic-gate } /* HANDTPL_PARSE_LTUPLE */ 1832*7c478bd9Sstevel@tonic-gate 1833*7c478bd9Sstevel@tonic-gate } else { 1834*7c478bd9Sstevel@tonic-gate 1835*7c478bd9Sstevel@tonic-gate tp->flags |= CISTPLF_LINK_INVALID; 1836*7c478bd9Sstevel@tonic-gate return (HANDTPL_ERROR); 1837*7c478bd9Sstevel@tonic-gate 1838*7c478bd9Sstevel@tonic-gate } /* CISTPL_LINKTARGET */ 1839*7c478bd9Sstevel@tonic-gate 1840*7c478bd9Sstevel@tonic-gate } /* (HANDTPL_COPY_DONE | HANDTPL_PARSE_LTUPLE) */ 1841*7c478bd9Sstevel@tonic-gate 1842*7c478bd9Sstevel@tonic-gate return (CISTPLF_NOERROR); 1843*7c478bd9Sstevel@tonic-gate } 1844*7c478bd9Sstevel@tonic-gate 1845*7c478bd9Sstevel@tonic-gate /* 1846*7c478bd9Sstevel@tonic-gate * cistpl_longlink_ac_handler - handler for CISTPL_LONGLINK_A and 1847*7c478bd9Sstevel@tonic-gate * CISTPL_LONGLINK_C tuples 1848*7c478bd9Sstevel@tonic-gate * 1849*7c478bd9Sstevel@tonic-gate * void *arg - points to a cistpl_longlink_ac_t * where the 1850*7c478bd9Sstevel@tonic-gate * information is stuffed into 1851*7c478bd9Sstevel@tonic-gate * 1852*7c478bd9Sstevel@tonic-gate * If the passed in tuple is CISTPL_LONGLINK_A the CISTPL_LONGLINK_AC_AM 1853*7c478bd9Sstevel@tonic-gate * flag in cistpl_longlink_ac_t->flags is set. 1854*7c478bd9Sstevel@tonic-gate * If the passed in tuple is CISTPL_LONGLINK_C the CISTPL_LONGLINK_AC_CM 1855*7c478bd9Sstevel@tonic-gate * flag in cistpl_longlink_ac_t->flags is set. 1856*7c478bd9Sstevel@tonic-gate * 1857*7c478bd9Sstevel@tonic-gate * If HANDTPL_COPY_DONE is set, we just validate the tuple but 1858*7c478bd9Sstevel@tonic-gate * do not return any values. 1859*7c478bd9Sstevel@tonic-gate * If HANDTPL_PARSE_LTUPLE is set, we validate the tuple and 1860*7c478bd9Sstevel@tonic-gate * return the parsed tuple data if the tuple is valid. 1861*7c478bd9Sstevel@tonic-gate * 1862*7c478bd9Sstevel@tonic-gate * If the tuple link field is invalid, the CISTPLF_LINK_INVALID flag 1863*7c478bd9Sstevel@tonic-gate * will be set in the tp->flags field and HANDTPL_ERROR 1864*7c478bd9Sstevel@tonic-gate * will be returned. 1865*7c478bd9Sstevel@tonic-gate * 1866*7c478bd9Sstevel@tonic-gate * The tuple is considered invalid if it's link field is less than 1867*7c478bd9Sstevel@tonic-gate * MIN_LONGLINK_AC_LENGTH. 1868*7c478bd9Sstevel@tonic-gate */ 1869*7c478bd9Sstevel@tonic-gate uint32_t 1870*7c478bd9Sstevel@tonic-gate cistpl_longlink_ac_handler(cistpl_callout_t *co, cistpl_t *tp, uint32_t flags, 1871*7c478bd9Sstevel@tonic-gate void *arg) 1872*7c478bd9Sstevel@tonic-gate { 1873*7c478bd9Sstevel@tonic-gate /* 1874*7c478bd9Sstevel@tonic-gate * nothing special about our flags, so just call the 1875*7c478bd9Sstevel@tonic-gate * generic handler for this 1876*7c478bd9Sstevel@tonic-gate */ 1877*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_SET_FLAGS) 1878*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 1879*7c478bd9Sstevel@tonic-gate 1880*7c478bd9Sstevel@tonic-gate /* 1881*7c478bd9Sstevel@tonic-gate * Validate the tuple for both the HANDTPL_COPY_DONE case and 1882*7c478bd9Sstevel@tonic-gate * the HANDTPL_PARSE_LTUPLE case. Only return data in 1883*7c478bd9Sstevel@tonic-gate * the HANDTPL_PARSE_LTUPLE case. 1884*7c478bd9Sstevel@tonic-gate */ 1885*7c478bd9Sstevel@tonic-gate if (flags & (HANDTPL_COPY_DONE | HANDTPL_PARSE_LTUPLE)) { 1886*7c478bd9Sstevel@tonic-gate 1887*7c478bd9Sstevel@tonic-gate if (tp->len >= (cisdata_t)MIN_LONGLINK_AC_LENGTH) { 1888*7c478bd9Sstevel@tonic-gate 1889*7c478bd9Sstevel@tonic-gate /* 1890*7c478bd9Sstevel@tonic-gate * This tuple is valid. 1891*7c478bd9Sstevel@tonic-gate */ 1892*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_COPY_DONE) 1893*7c478bd9Sstevel@tonic-gate tp->flags |= CISTPLF_VALID; 1894*7c478bd9Sstevel@tonic-gate 1895*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_PARSE_LTUPLE) { 1896*7c478bd9Sstevel@tonic-gate cistpl_longlink_ac_t *cs = 1897*7c478bd9Sstevel@tonic-gate (cistpl_longlink_ac_t *)arg; 1898*7c478bd9Sstevel@tonic-gate 1899*7c478bd9Sstevel@tonic-gate switch (tp->type) { 1900*7c478bd9Sstevel@tonic-gate case CISTPL_LONGLINK_A: 1901*7c478bd9Sstevel@tonic-gate cs->flags = CISTPL_LONGLINK_AC_AM; 1902*7c478bd9Sstevel@tonic-gate break; 1903*7c478bd9Sstevel@tonic-gate 1904*7c478bd9Sstevel@tonic-gate case CISTPL_LONGLINK_C: 1905*7c478bd9Sstevel@tonic-gate cs->flags = CISTPL_LONGLINK_AC_CM; 1906*7c478bd9Sstevel@tonic-gate break; 1907*7c478bd9Sstevel@tonic-gate default: 1908*7c478bd9Sstevel@tonic-gate break; 1909*7c478bd9Sstevel@tonic-gate } /* switch */ 1910*7c478bd9Sstevel@tonic-gate 1911*7c478bd9Sstevel@tonic-gate RESET_TP(tp); 1912*7c478bd9Sstevel@tonic-gate 1913*7c478bd9Sstevel@tonic-gate cs->tpll_addr = GET_LONG(tp); 1914*7c478bd9Sstevel@tonic-gate 1915*7c478bd9Sstevel@tonic-gate } /* HANDTPL_PARSE_LTUPLE */ 1916*7c478bd9Sstevel@tonic-gate 1917*7c478bd9Sstevel@tonic-gate } else { 1918*7c478bd9Sstevel@tonic-gate tp->flags |= CISTPLF_LINK_INVALID; 1919*7c478bd9Sstevel@tonic-gate return (HANDTPL_ERROR); 1920*7c478bd9Sstevel@tonic-gate } /* MIN_LONGLINK_AC_LENGTH */ 1921*7c478bd9Sstevel@tonic-gate 1922*7c478bd9Sstevel@tonic-gate } /* (HANDTPL_COPY_DONE | HANDTPL_PARSE_LTUPLE) */ 1923*7c478bd9Sstevel@tonic-gate 1924*7c478bd9Sstevel@tonic-gate return (CISTPLF_NOERROR); 1925*7c478bd9Sstevel@tonic-gate } 1926*7c478bd9Sstevel@tonic-gate 1927*7c478bd9Sstevel@tonic-gate /* 1928*7c478bd9Sstevel@tonic-gate * cistpl_longlink_mfc_handler - handler for CISTPL_LONGLINK_MFC tuples 1929*7c478bd9Sstevel@tonic-gate * 1930*7c478bd9Sstevel@tonic-gate * void *arg - points to a cistpl_longlink_mfc_t * where the 1931*7c478bd9Sstevel@tonic-gate * information is stuffed into 1932*7c478bd9Sstevel@tonic-gate * 1933*7c478bd9Sstevel@tonic-gate * If HANDTPL_COPY_DONE is set, we just validate the tuple but 1934*7c478bd9Sstevel@tonic-gate * do not return any values. 1935*7c478bd9Sstevel@tonic-gate * If HANDTPL_PARSE_LTUPLE is set, we validate the tuple and 1936*7c478bd9Sstevel@tonic-gate * return the parsed tuple data if the tuple is valid. 1937*7c478bd9Sstevel@tonic-gate * 1938*7c478bd9Sstevel@tonic-gate * If the tuple link field is invalid, the CISTPLF_LINK_INVALID flag 1939*7c478bd9Sstevel@tonic-gate * will be set in the tp->flags field and HANDTPL_ERROR 1940*7c478bd9Sstevel@tonic-gate * will be returned. 1941*7c478bd9Sstevel@tonic-gate * 1942*7c478bd9Sstevel@tonic-gate * If the number of register sets is invalid, the CISTPLF_PARAMS_INVALID 1943*7c478bd9Sstevel@tonic-gate * flag be set in the tp->flags field and HANDTPL_ERROR will be 1944*7c478bd9Sstevel@tonic-gate * returned. 1945*7c478bd9Sstevel@tonic-gate * 1946*7c478bd9Sstevel@tonic-gate * The tuple is considered invalid if it's link field is less than 1947*7c478bd9Sstevel@tonic-gate * MIN_LONGLINK_MFC_LENGTH or if the number of register sets 1948*7c478bd9Sstevel@tonic-gate * is not in the range [MIN_LONGLINK_MFC_NREGS..CIS_MAX_FUNCTIONS] 1949*7c478bd9Sstevel@tonic-gate */ 1950*7c478bd9Sstevel@tonic-gate uint32_t 1951*7c478bd9Sstevel@tonic-gate cistpl_longlink_mfc_handler(cistpl_callout_t *co, cistpl_t *tp, 1952*7c478bd9Sstevel@tonic-gate uint32_t flags, void *arg) 1953*7c478bd9Sstevel@tonic-gate { 1954*7c478bd9Sstevel@tonic-gate /* 1955*7c478bd9Sstevel@tonic-gate * nothing special about our flags, so just call the 1956*7c478bd9Sstevel@tonic-gate * generic handler for this 1957*7c478bd9Sstevel@tonic-gate */ 1958*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_SET_FLAGS) 1959*7c478bd9Sstevel@tonic-gate return (cis_no_tuple_handler(co, tp, flags, arg)); 1960*7c478bd9Sstevel@tonic-gate 1961*7c478bd9Sstevel@tonic-gate /* 1962*7c478bd9Sstevel@tonic-gate * Validate the tuple for both the HANDTPL_COPY_DONE case and 1963*7c478bd9Sstevel@tonic-gate * the HANDTPL_PARSE_LTUPLE case. Only return data in 1964*7c478bd9Sstevel@tonic-gate * the HANDTPL_PARSE_LTUPLE case. 1965*7c478bd9Sstevel@tonic-gate */ 1966*7c478bd9Sstevel@tonic-gate if (flags & (HANDTPL_COPY_DONE | HANDTPL_PARSE_LTUPLE)) { 1967*7c478bd9Sstevel@tonic-gate 1968*7c478bd9Sstevel@tonic-gate if (tp->len >= (cisdata_t)MIN_LONGLINK_MFC_LENGTH) { 1969*7c478bd9Sstevel@tonic-gate 1970*7c478bd9Sstevel@tonic-gate /* 1971*7c478bd9Sstevel@tonic-gate * This tuple is valid. 1972*7c478bd9Sstevel@tonic-gate */ 1973*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_COPY_DONE) 1974*7c478bd9Sstevel@tonic-gate tp->flags |= CISTPLF_VALID; 1975*7c478bd9Sstevel@tonic-gate 1976*7c478bd9Sstevel@tonic-gate if (flags & HANDTPL_PARSE_LTUPLE) { 1977*7c478bd9Sstevel@tonic-gate cistpl_longlink_mfc_t *cs = 1978*7c478bd9Sstevel@tonic-gate (cistpl_longlink_mfc_t *)arg; 1979*7c478bd9Sstevel@tonic-gate int fn; 1980*7c478bd9Sstevel@tonic-gate 1981*7c478bd9Sstevel@tonic-gate RESET_TP(tp); 1982*7c478bd9Sstevel@tonic-gate 1983*7c478bd9Sstevel@tonic-gate /* 1984*7c478bd9Sstevel@tonic-gate * Get the number of register sets described 1985*7c478bd9Sstevel@tonic-gate * by this tuple. The number of register 1986*7c478bd9Sstevel@tonic-gate * sets must be greter than or equal to 1987*7c478bd9Sstevel@tonic-gate * MIN_LONGLINK_MFC_NREGS and less than 1988*7c478bd9Sstevel@tonic-gate * CIS_MAX_FUNCTIONS. 1989*7c478bd9Sstevel@tonic-gate * Note that the number of functions is equal 1990*7c478bd9Sstevel@tonic-gate * to the number of register sets. 1991*7c478bd9Sstevel@tonic-gate */ 1992*7c478bd9Sstevel@tonic-gate cs->nregs = GET_BYTE(tp); 1993*7c478bd9Sstevel@tonic-gate cs->nfuncs = cs->nregs; 1994*7c478bd9Sstevel@tonic-gate 1995*7c478bd9Sstevel@tonic-gate if ((cs->nregs < MIN_LONGLINK_MFC_NREGS) || 1996*7c478bd9Sstevel@tonic-gate (cs->nregs > CIS_MAX_FUNCTIONS)) { 1997*7c478bd9Sstevel@tonic-gate tp->flags |= CISTPLF_PARAMS_INVALID; 1998*7c478bd9Sstevel@tonic-gate return (HANDTPL_ERROR); 1999*7c478bd9Sstevel@tonic-gate } 2000*7c478bd9Sstevel@tonic-gate 2001*7c478bd9Sstevel@tonic-gate /* 2002*7c478bd9Sstevel@tonic-gate * Cycle through each function and setup 2003*7c478bd9Sstevel@tonic-gate * the appropriate parameter values. 2004*7c478bd9Sstevel@tonic-gate */ 2005*7c478bd9Sstevel@tonic-gate for (fn = 0; fn < cs->nregs; fn++) { 2006*7c478bd9Sstevel@tonic-gate cs->function[fn].tas = GET_BYTE(tp); 2007*7c478bd9Sstevel@tonic-gate cs->function[fn].addr = GET_LONG(tp); 2008*7c478bd9Sstevel@tonic-gate } /* for (fn) */ 2009*7c478bd9Sstevel@tonic-gate 2010*7c478bd9Sstevel@tonic-gate } /* HANDTPL_PARSE_LTUPLE */ 2011*7c478bd9Sstevel@tonic-gate 2012*7c478bd9Sstevel@tonic-gate } else { 2013*7c478bd9Sstevel@tonic-gate tp->flags |= CISTPLF_LINK_INVALID; 2014*7c478bd9Sstevel@tonic-gate return (HANDTPL_ERROR); 2015*7c478bd9Sstevel@tonic-gate } /* MIN_LONGLINK_MFC_LENGTH */ 2016*7c478bd9Sstevel@tonic-gate 2017*7c478bd9Sstevel@tonic-gate } /* (HANDTPL_COPY_DONE | HANDTPL_PARSE_LTUPLE) */ 2018*7c478bd9Sstevel@tonic-gate 2019*7c478bd9Sstevel@tonic-gate return (CISTPLF_NOERROR); 2020*7c478bd9Sstevel@tonic-gate } 2021*7c478bd9Sstevel@tonic-gate 2022*7c478bd9Sstevel@tonic-gate /* 2023*7c478bd9Sstevel@tonic-gate * cis_validate_longlink_acm - Validates the secondary tuple chain pointed 2024*7c478bd9Sstevel@tonic-gate * to by cisptr and specified by a previous 2025*7c478bd9Sstevel@tonic-gate * CISTPL_LONGLINK_A, CISTPL_LONGLINK_C or 2026*7c478bd9Sstevel@tonic-gate * CISTPL_LONGLINK_MFC tuple. 2027*7c478bd9Sstevel@tonic-gate * 2028*7c478bd9Sstevel@tonic-gate * cisptr->offset must be the offset to the first byte in the secondary 2029*7c478bd9Sstevel@tonic-gate * tuple chain to validate 2030*7c478bd9Sstevel@tonic-gate * cisptr->flags must be setup to specify the correct address space 2031*7c478bd9Sstevel@tonic-gate * 2032*7c478bd9Sstevel@tonic-gate * The cisptr->offset member is not updated after this function returns. 2033*7c478bd9Sstevel@tonic-gate * 2034*7c478bd9Sstevel@tonic-gate * BAD_CIS_ADDR is returned is the raw CIS data cound not be read. 2035*7c478bd9Sstevel@tonic-gate * HANDTPL_ERROR is returned if the secondary tuple chain does not 2036*7c478bd9Sstevel@tonic-gate * contain a valid CISTPL_LINKTARGET tuple. 2037*7c478bd9Sstevel@tonic-gate */ 2038*7c478bd9Sstevel@tonic-gate uint32_t 2039*7c478bd9Sstevel@tonic-gate cis_validate_longlink_acm(cisptr_t *cisptr) 2040*7c478bd9Sstevel@tonic-gate { 2041*7c478bd9Sstevel@tonic-gate uchar_t cb[MIN_LINKTARGET_LENGTH + LINKTARGET_AC_HEADER_LENGTH]; 2042*7c478bd9Sstevel@tonic-gate cisptr_t t_cisptr, *cpt; 2043*7c478bd9Sstevel@tonic-gate int tl; 2044*7c478bd9Sstevel@tonic-gate 2045*7c478bd9Sstevel@tonic-gate /* 2046*7c478bd9Sstevel@tonic-gate * Since the NEXT_CIS_ADDR macro increments the cisptr_t->offset 2047*7c478bd9Sstevel@tonic-gate * member, make a local copy of the cisptr and use the local 2048*7c478bd9Sstevel@tonic-gate * copy to read data from the card. 2049*7c478bd9Sstevel@tonic-gate */ 2050*7c478bd9Sstevel@tonic-gate cpt = &t_cisptr; 2051*7c478bd9Sstevel@tonic-gate bcopy((caddr_t)cisptr, (caddr_t)cpt, sizeof (cisptr_t)); 2052*7c478bd9Sstevel@tonic-gate 2053*7c478bd9Sstevel@tonic-gate for (tl = 0; tl < MIN_LINKTARGET_LENGTH + 2054*7c478bd9Sstevel@tonic-gate LINKTARGET_AC_HEADER_LENGTH; tl++) { 2055*7c478bd9Sstevel@tonic-gate 2056*7c478bd9Sstevel@tonic-gate cb[tl] = GET_CIS_DATA(cpt); 2057*7c478bd9Sstevel@tonic-gate if (!NEXT_CIS_ADDR(cpt)) 2058*7c478bd9Sstevel@tonic-gate return ((uint32_t)BAD_CIS_ADDR); 2059*7c478bd9Sstevel@tonic-gate 2060*7c478bd9Sstevel@tonic-gate } /* for */ 2061*7c478bd9Sstevel@tonic-gate 2062*7c478bd9Sstevel@tonic-gate if ((cb[0] == CISTPL_LINKTARGET) && (cb[1] >= MIN_LINKTARGET_LENGTH)) { 2063*7c478bd9Sstevel@tonic-gate cisdata_t *ltm = (cisdata_t *)CISTPL_LINKTARGET_MAGIC; 2064*7c478bd9Sstevel@tonic-gate 2065*7c478bd9Sstevel@tonic-gate for (tl = 0; tl < MIN_LINKTARGET_LENGTH; tl++, ltm++) { 2066*7c478bd9Sstevel@tonic-gate if (cb[tl + LINKTARGET_AC_HEADER_LENGTH] != *ltm) 2067*7c478bd9Sstevel@tonic-gate return (HANDTPL_ERROR); 2068*7c478bd9Sstevel@tonic-gate } 2069*7c478bd9Sstevel@tonic-gate return (CISTPLF_NOERROR); 2070*7c478bd9Sstevel@tonic-gate 2071*7c478bd9Sstevel@tonic-gate } /* if */ 2072*7c478bd9Sstevel@tonic-gate 2073*7c478bd9Sstevel@tonic-gate return (HANDTPL_ERROR); 2074*7c478bd9Sstevel@tonic-gate } 2075*7c478bd9Sstevel@tonic-gate 2076*7c478bd9Sstevel@tonic-gate /* 2077*7c478bd9Sstevel@tonic-gate * cis_getstr (tp) 2078*7c478bd9Sstevel@tonic-gate * we want the address of the first character returned 2079*7c478bd9Sstevel@tonic-gate * but need to skip past the string in the cistpl_t structure 2080*7c478bd9Sstevel@tonic-gate */ 2081*7c478bd9Sstevel@tonic-gate char * 2082*7c478bd9Sstevel@tonic-gate cis_getstr(cistpl_t *tp) 2083*7c478bd9Sstevel@tonic-gate { 2084*7c478bd9Sstevel@tonic-gate uchar_t *cp, *cpp; 2085*7c478bd9Sstevel@tonic-gate uchar_t x; 2086*7c478bd9Sstevel@tonic-gate 2087*7c478bd9Sstevel@tonic-gate cp = tp->read.byte; 2088*7c478bd9Sstevel@tonic-gate cpp = cp; 2089*7c478bd9Sstevel@tonic-gate 2090*7c478bd9Sstevel@tonic-gate while ((x = LOOK_BYTE(tp)) != 0 && x != 0xff) { 2091*7c478bd9Sstevel@tonic-gate x = GET_BYTE(tp); 2092*7c478bd9Sstevel@tonic-gate } 2093*7c478bd9Sstevel@tonic-gate 2094*7c478bd9Sstevel@tonic-gate (void) GET_BYTE(tp); /* get past that last byte */ 2095*7c478bd9Sstevel@tonic-gate 2096*7c478bd9Sstevel@tonic-gate while ((*cpp != 0) && (*cpp != 0xff)) 2097*7c478bd9Sstevel@tonic-gate cpp++; 2098*7c478bd9Sstevel@tonic-gate 2099*7c478bd9Sstevel@tonic-gate *cpp = NULL; 2100*7c478bd9Sstevel@tonic-gate 2101*7c478bd9Sstevel@tonic-gate return ((char *)cp); 2102*7c478bd9Sstevel@tonic-gate } 2103*7c478bd9Sstevel@tonic-gate 2104*7c478bd9Sstevel@tonic-gate /* 2105*7c478bd9Sstevel@tonic-gate * cis_return_name - returns name of tuple 2106*7c478bd9Sstevel@tonic-gate * 2107*7c478bd9Sstevel@tonic-gate * calling: co - pointer to cistpl_callout_t entry that contains 2108*7c478bd9Sstevel@tonic-gate * tuple name to return 2109*7c478bd9Sstevel@tonic-gate * gtn - pointer to cistpl_get_tuple_name_t to return 2110*7c478bd9Sstevel@tonic-gate * name into 2111*7c478bd9Sstevel@tonic-gate */ 2112*7c478bd9Sstevel@tonic-gate static void 2113*7c478bd9Sstevel@tonic-gate cis_return_name(cistpl_callout_t *co, cistpl_get_tuple_name_t *gtn) 2114*7c478bd9Sstevel@tonic-gate { 2115*7c478bd9Sstevel@tonic-gate (void) strncpy(gtn->name, co->text, CIS_MAX_TUPLE_NAME_LEN); 2116*7c478bd9Sstevel@tonic-gate gtn->name[CIS_MAX_TUPLE_NAME_LEN - 1] = NULL; 2117*7c478bd9Sstevel@tonic-gate } 2118*7c478bd9Sstevel@tonic-gate 2119*7c478bd9Sstevel@tonic-gate /* 2120*7c478bd9Sstevel@tonic-gate * cis_malloc/cis_free 2121*7c478bd9Sstevel@tonic-gate * wrappers around kmem_alloc()/kmem_free() that 2122*7c478bd9Sstevel@tonic-gate * provide malloc/free style usage 2123*7c478bd9Sstevel@tonic-gate */ 2124*7c478bd9Sstevel@tonic-gate 2125*7c478bd9Sstevel@tonic-gate caddr_t 2126*7c478bd9Sstevel@tonic-gate cis_malloc(size_t len) 2127*7c478bd9Sstevel@tonic-gate { 2128*7c478bd9Sstevel@tonic-gate caddr_t addr; 2129*7c478bd9Sstevel@tonic-gate 2130*7c478bd9Sstevel@tonic-gate addr = kmem_zalloc(len + sizeof (size_t), KM_SLEEP); 2131*7c478bd9Sstevel@tonic-gate *(size_t *)addr = len + sizeof (size_t); 2132*7c478bd9Sstevel@tonic-gate addr += sizeof (size_t); 2133*7c478bd9Sstevel@tonic-gate return (addr); 2134*7c478bd9Sstevel@tonic-gate } 2135*7c478bd9Sstevel@tonic-gate 2136*7c478bd9Sstevel@tonic-gate void 2137*7c478bd9Sstevel@tonic-gate cis_free(caddr_t addr) 2138*7c478bd9Sstevel@tonic-gate { 2139*7c478bd9Sstevel@tonic-gate size_t len; 2140*7c478bd9Sstevel@tonic-gate addr -= sizeof (size_t); 2141*7c478bd9Sstevel@tonic-gate len = *(size_t *)addr; 2142*7c478bd9Sstevel@tonic-gate kmem_free(addr, len); 2143*7c478bd9Sstevel@tonic-gate } 2144