--- old/usr/src/uts/common/pcmcia/cis/cis_handlers.c	2014-11-12 17:44:40.661240133 +0100
+++ /dev/null	2014-11-12 17:44:40.000000000 +0100
@@ -1,2194 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
-/*
- * This file contains the tuple handlers that are called by the CIS
- *	parser.
- *
- * XXX - how about a better explaination??
- */
-
-#include <sys/types.h>
-#include <sys/systm.h>
-#include <sys/user.h>
-#include <sys/buf.h>
-#include <sys/file.h>
-#include <sys/uio.h>
-#include <sys/conf.h>
-#include <sys/stat.h>
-#include <sys/autoconf.h>
-#include <sys/vtoc.h>
-#include <sys/dkio.h>
-#include <sys/ddi.h>
-#include <sys/sunddi.h>
-#include <sys/debug.h>
-#include <sys/ddi_impldefs.h>
-#include <sys/kstat.h>
-#include <sys/kmem.h>
-#include <sys/modctl.h>
-#include <sys/kobj.h>
-#include <sys/callb.h>
-
-#include <sys/pctypes.h>
-#include <pcmcia/sys/cs_types.h>
-#include <pcmcia/sys/cis.h>
-#include <pcmcia/sys/cis_handlers.h>
-#include <pcmcia/sys/cs.h>
-#include <pcmcia/sys/cs_priv.h>
-#include <pcmcia/sys/cis_protos.h>
-
-/*
- * Function prototypes
- */
-static void cistpl_pd_parse(cistpl_t *, cistpl_cftable_entry_pwr_t *);
-static void cis_return_name(cistpl_callout_t *, cistpl_get_tuple_name_t *);
-
-/*
- * Fetch data functions.
- */
-uint16_t
-cis_get_short(cistpl_t *tp)
-{
-	uint16_t result;
-
-	if (tp->flags & CISTPLF_AM_SPACE) {
-		result = GET_AM_BYTE(tp);
-		result |= GET_AM_BYTE(tp) << 8;
-	} else {
-		result = GET_CM_BYTE(tp);
-		result |= GET_CM_BYTE(tp) << 8;
-	}
-	return (result);
-}
-
-uint16_t
-cis_get_be_short(cistpl_t *tp)
-{
-	uint16_t result;
-
-	if (tp->flags & CISTPLF_AM_SPACE) {
-		result = GET_AM_BYTE(tp) << 8;
-		result |= GET_AM_BYTE(tp);
-	} else {
-		result = GET_CM_BYTE(tp) << 8;
-		result |= GET_CM_BYTE(tp);
-	}
-	return (result);
-}
-
-uint32_t
-cis_get_int24(cistpl_t *tp)
-{
-	uint32_t result = cis_get_short(tp);
-
-	result |= GET_BYTE(tp) << 16;
-	return (result);
-}
-
-uint32_t
-cis_get_long(cistpl_t *tp)
-{
-	uint32_t result = cis_get_short(tp);
-
-	result |= cis_get_short(tp) << 16;
-	return (result);
-}
-
-/*
- * cis_tuple_handler - call the handler for the tuple described by the
- *				tuple pointer
- *
- *	cistpl_callout_t *co - pointer to callout structure
- *				array to use to find this tuple
- *	cistpl_t *tp - pointer to a tuple structure
- *	int flags - action for the handler to perform
- * XXX - we need a description of the flags passed to the tuple handler
- *	void *arg - argument to pass on to tuple handler
- *
- * If the tuple is not recognized but is is a vendor-specific tuple, we
- *	set the CISTPLF_VENDOR_SPECIFIC flag in the tuple.
- *
- * We return CISTPLF_UNKNOWN if this is an unrecognized	tuple as well as
- *	set the CISTPLF_UNKNOWN flag in the tuple list structure.  Note
- *	that encountering an unknown tuple is not necessarily an error,
- *	so we don't set the HANDTPL_ERROR flag on the return code.  It
- *	is up to the caller to determine what an unrecognized tuple means.
- *
- * If this is a recognized tuple, the apropriate tuple handler is called and
- *	the return value from the handler is returned directly to the caller.
- *
- * The void *arg is optional, and it's meaning is dependent on the
- *	particular tuple handler called and the flags parameter.
- *
- * For the special case of HANDTPL_RETURN_NAME, we don't bother calling the
- *	tuple handler and just return the tuple name to the caller.
- */
-uint32_t
-cis_tuple_handler(cistpl_callout_t *co, cistpl_t *tp, uint32_t flags,
-					void *arg, cisdata_t subtype)
-{
-	/*
-	 * Check to see if this is a vendor-specific tuple.
-	 */
-	if (CISTPL_IS_VENDOR_SPECIFIC(tp->type))
-	    tp->flags |= CISTPLF_VENDOR_SPECIFIC;
-
-	/*
-	 * Scan the callout list until we find the tuple passed to us, or we
-	 *	encounter a CISTPL_END in the callout list, which signals that
-	 *	there are no more tuples in the callout list.
-	 */
-	while (co->type != (cisdata_t)CISTPL_END) {
-	    if (co->type == tp->type &&
-		((tp->type != CISTPL_FUNCE) ||
-		    (tp->type == CISTPL_FUNCE && co->subtype == subtype))) {
-			tp->flags &= ~CISTPLF_UNKNOWN;
-			if (flags & HANDTPL_RETURN_NAME) {
-			    cis_return_name(co, (cistpl_get_tuple_name_t *)arg);
-			    return (CISTPLF_NOERROR);
-			} else {
-			    return ((*co->handler) (co, tp, flags, arg));
-			} /* HANDTPL_RETURN_NAME */
-	    } /* if */
-	    co++;
-	} /* while */
-
-	/*
-	 * If we didn't recognize the tuple and the caller wants the tuple
-	 *	name back, then return the "unknown tuple" string. At this
-	 *	point, "co" will be pointing to the last entry in the
-	 *	callout list. It's not an error to not recognize the tuple
-	 *	when the operation is HANDTPL_RETURN_NAME.
-	 */
-	if (flags & HANDTPL_RETURN_NAME) {
-	    cis_return_name(co, (cistpl_get_tuple_name_t *)arg);
-	    return (CISTPLF_NOERROR);
-	}
-
-	tp->flags |= CISTPLF_UNKNOWN;
-	return (CISTPLF_UNKNOWN);
-}
-
-/*
- * cis_no_tuple_handler - this generic tuple handler is used if no special
- *				tuple processing is required for the passed
- *				tuple
- *
- *	cistpl_callout_t *co - pointer to this tuple's entry in the
- *				tuple callout structure
- *	cistpl_t *tp - pointer to this tuple's entry in the local linked list
- *	int flags - action to perform
- *
- * This handler will set the CISTPLF_COPYOK flag if the tuple link is greater
- *	than zero, indicating that it's OK to copy the tuple data body. It
- *	will also set whatever flags are specified in the callout structure.
- *
- * We always set the CISTPLF_VALID when we're called with HANDTPL_COPY_DONE.
- *
- * We return CISTPLF_UNKNOWN if we're being called to parse the tuple.
- *
- * We return CISTPLF_NOERROR in every other case to indicate that this is a
- *	recognized tuple.
- */
-/*ARGSUSED*/
-uint32_t
-cis_no_tuple_handler(cistpl_callout_t *co, cistpl_t *tp,
-					uint32_t flags, void *arg)
-{
-	if (flags & HANDTPL_SET_FLAGS) {
-		tp->flags |= co->flags;	/* XXX - is = the right thing here? */
-		if (tp->len > 0)
-			tp->flags |= CISTPLF_COPYOK;
-	}
-
-	if (flags & HANDTPL_COPY_DONE)
-		tp->flags |= CISTPLF_VALID;
-
-	if (flags & HANDTPL_PARSE_LTUPLE)
-	    return (CISTPLF_UNKNOWN);
-
-	return (CISTPLF_NOERROR);
-}
-
-/*
- * cis_unknown_tuple_handler - this generic tuple handler is used if we don't
- *				understand this tuple
- *
- *	cistpl_callout_t *co - pointer to this tuple's entry in the
- *				tuple callout structure
- *	cistpl_t *tp - pointer to this tuple's entry in the local linked list
- *	int flags - action to perform
- *
- * This handler will not set the CISTPLF_COPYOK flag since we don't know the
- *	contents of a vendor-specific tuple.
- *
- * We always set the CISTPLF_VALID when we're called with HANDTPL_COPY_DONE
- *	to specify that we understand this tuple's code, but not it's data
- *	body.
- *
- * We return CISTPLF_UNKNOWN if we're being called to parse the tuple or to
- *	perform any other operation.
- */
-/*ARGSUSED*/
-uint32_t
-cis_unknown_tuple_handler(cistpl_callout_t *co, cistpl_t *tp,
-					uint32_t flags, void *arg)
-{
-	if (flags & HANDTPL_SET_FLAGS) {
-		tp->flags |= co->flags;	/* XXX - is = the right thing here? */
-		return (CISTPLF_NOERROR);
-	}
-
-	if (flags & HANDTPL_COPY_DONE) {
-		tp->flags |= CISTPLF_VALID;
-		return (CISTPLF_NOERROR);
-	}
-
-	return (CISTPLF_UNKNOWN);
-}
-
-/*
- * cistpl_vers_1_handler - handler for the CISTPL_VERS_1 tuple
- *
- *	void *arg - points to a cistpl_vers_1_t * where the
- *			information is stuffed into
- */
-uint32_t
-cistpl_vers_1_handler(cistpl_callout_t *co, cistpl_t *tp,
-					uint32_t flags, void *arg)
-{
-	/*
-	 * nothing special about our flags, so just call the
-	 *	generic handler for this
-	 */
-	if (flags & HANDTPL_SET_FLAGS)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	/*
-	 * We don't currently validate this tuple. This call will
-	 *	always set tp->flags |= CISTPLF_VALID.
-	 */
-	if (flags & HANDTPL_COPY_DONE)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	if (flags & HANDTPL_PARSE_LTUPLE) {
-		cistpl_vers_1_t *cs = (cistpl_vers_1_t *)arg;
-
-
-		RESET_TP(tp);
-
-		cs->major = GET_BYTE(tp);
-		cs->minor = GET_BYTE(tp);
-		for (cs->ns = 0; GET_LEN(tp) > 0 &&
-				/* CSTYLED */
-				cs->ns < CISTPL_VERS_1_MAX_PROD_STRINGS; ) {
-			(void) strcpy(cs->pi[cs->ns++], cis_getstr(tp));
-		} /* for */
-	} /* HANDTPL_PARSE_LTUPLE */
-
-	return (CISTPLF_NOERROR);
-}
-
-/*
- * cistpl_config_handler - handler for the CISTPL_CONFIG tuple
- *
- *	void *arg - points to a XXX where the information is stuffed into
- *
- * For the first ten config registers we set the present flags in the
- *	cistpl_config_t if the register exists.  The flags that we use
- *	for this are the same as the flags reguired for the Card Services
- *	RequestConfiguration function and they can be used by clients
- *	directly without requiring any remapping of values.
- *
- * XXX we don't handle TPCC_SBTPL subtuples yet
- */
-
-uint32_t	config_regs_present_map[] = {
-	CONFIG_OPTION_REG_PRESENT,	/* COR present */
-	CONFIG_STATUS_REG_PRESENT,	/* STAT reg present */
-	CONFIG_PINREPL_REG_PRESENT,	/* PRR present */
-	CONFIG_COPY_REG_PRESENT,	/* COPY reg present */
-	CONFIG_EXSTAT_REG_PRESENT,	/* EXSTAT reg present */
-	CONFIG_IOBASE0_REG_PRESENT,	/* IOBASE0 reg present */
-	CONFIG_IOBASE1_REG_PRESENT,	/* IOBASE1 reg present */
-	CONFIG_IOBASE2_REG_PRESENT,	/* IOBASE2 reg present */
-	CONFIG_IOBASE3_REG_PRESENT,	/* IOBASE3 reg present */
-	CONFIG_IOLIMIT_REG_PRESENT,	/* IOLIMIT reg present */
-};
-
-uint32_t
-cistpl_config_handler(cistpl_callout_t *co, cistpl_t *tp,
-					uint32_t flags, void *arg)
-{
-	cisdata_t tpcc_sz;
-	int i, n, nrb, na, hr = 0;
-
-	/*
-	 * nothing special about our flags, so just call the
-	 *	generic handler for this
-	 */
-	if (flags & HANDTPL_SET_FLAGS)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	/*
-	 * We don't currently validate this tuple. This call will
-	 *	always set tp->flags |= CISTPLF_VALID.
-	 */
-	if (flags & HANDTPL_COPY_DONE)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	if (flags & HANDTPL_PARSE_LTUPLE) {
-		cistpl_config_t *cr = (cistpl_config_t *)arg;
-		int crn = 0;
-
-		RESET_TP(tp);
-
-		tpcc_sz = GET_BYTE(tp);		/* config regs size fields */
-		cr->last = GET_BYTE(tp);	/* last config index */
-
-		na = (tpcc_sz&3)+1;		/* config regs address bytes */
-		nrb = ((tpcc_sz>>2)&0x0f)+1;	/* number of bytes in config */
-						/*	regs presence mask */
-
-		/*
-		 * Construct the base offset address for the config registers.
-		 *	We jump through these hoops because the base address
-		 *	can be between one and four bytes in length.
-		 */
-		cr->base = 0;
-		n = na;
-		while (n--)
-			cr->base |= ((GET_BYTE(tp) & 0x0ff) <<
-							(8 * (na - (n+1))));
-
-		/*
-		 * Go through the config register presense mask bit by bit and
-		 *	figure out which config registers are present and which
-		 *	aren't.
-		 * For the first ten config registers, set the appropriate
-		 *	bits in the cr->present member so that the caller
-		 *	doesn't have to do this.
-		 */
-		cr->nr = 0;
-		cr->present = 0;
-		n = nrb;
-		while (n--) {
-			for (i = 0; i < 8; i++, crn++) {
-				if (LOOK_BYTE(tp) & (1<<i)) {
-				    if (crn < (sizeof (config_regs_present_map)/
-							sizeof (uint32_t)))
-					cr->present |=
-						config_regs_present_map[crn];
-				    cr->nr++;
-				    cr->hr = hr;
-				    cr->regs[hr] = MAKE_CONFIG_REG_ADDR(
-								cr->base, hr);
-				} /* LOOK_BYTE */
-				hr++;
-			} /* for */
-			(void) GET_BYTE(tp);
-		} /* while */
-	}
-
-	return (CISTPLF_NOERROR);
-}
-
-/*
- * cistpl_device_handler - handler for the CISTPL_DEVICE, CISTPL_DEVICE_A,
- *				CISTPL_DEVICE_OC and CISTPL_DEVICE_OA tuples
- *
- *	void *arg - points to a cistpl_device_t * where the
- *			information is stuffed into
- *
- * XXX - we only handle CISTPL_DEVICE_MAX_DEVICES device descriptions
- *		described in the tuple
- */
-uint32_t
-cistpl_device_handler(cistpl_callout_t *co, cistpl_t *tp,
-					uint32_t flags, void *arg)
-{
-	cisdata_t dev_id;
-
-	/*
-	 * nothing special about our flags, so just call the
-	 *	generic handler for this
-	 */
-	if (flags & HANDTPL_SET_FLAGS)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	/*
-	 * We don't currently validate this tuple. This call will
-	 *	always set tp->flags |= CISTPLF_VALID.
-	 */
-	if (flags & HANDTPL_COPY_DONE)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	if (flags & HANDTPL_PARSE_LTUPLE) {
-		convert_speed_t convert_speed;
-		cistpl_device_t *dt = (cistpl_device_t *)arg;
-		cistpl_device_node_t *cdn;
-
-		/*
-		 * XXX - fix this to look for more than one device definition
-		 * XXX - fix this to handle the OC fields for
-		 *	CISTPL_DEVICE_OC and CISTPL_DEVICE_OA
-		 */
-		dt->num_devices = 1;
-		cdn = &dt->devnode[0];
-
-		cdn->flags = 0;
-
-		RESET_TP(tp);
-
-		dev_id = GET_BYTE(tp);
-
-		/*
-		 * Get the device speed code.  If it's 7, then there is an
-		 *	extended speed code table in use, so parse that.
-		 *	If it's anything else, get the speed information
-		 *	directly from the device speed code.
-		 */
-		if ((dev_id & 7) == 7) {
-		    cdn->nS_speed = cistpl_devspeed(tp, 0, CISTPL_DEVSPEED_EXT);
-		} else {
-		    cdn->nS_speed = cistpl_devspeed(NULL, dev_id,
-							CISTPL_DEVSPEED_TABLE);
-		}
-
-		/*
-		 * Convert the speed in nS to a device speed code.
-		 * XXX -  should check return code from cis_convert_devspeed()
-		 */
-		convert_speed.Attributes = CONVERT_NS_TO_DEVSPEED;
-		convert_speed.nS = cdn->nS_speed;
-		(void) cis_convert_devspeed(&convert_speed);
-		cdn->speed = convert_speed.devspeed;
-
-		if (dev_id & 8)
-			cdn->flags |= CISTPL_DEVICE_WPS;
-
-		/*
-		 * Set the device type.  Note that we take the raw value
-		 *	from the tuple and pass it back to the caller.
-		 *	If the device type codes in the standard change,
-		 *	we will have to change our flags as well.
-		 */
-		cdn->type = (dev_id>>4) & 0x0f;
-
-		/*
-		 * XXX - what about the device_size byte?  Is the spec wrong?
-		 */
-		cdn->size = GET_BYTE(tp);
-		/* check for end of list */
-		if (cdn->size != 0x0ff) {
-		    convert_size_t convert_size;
-
-		    convert_size.devsize = cdn->size;
-		    convert_size.Attributes = CONVERT_DEVSIZE_TO_BYTES;
-		    (void) cis_convert_devsize(&convert_size);
-		    cdn->size_in_bytes = convert_size.bytes;
-		}
-	}
-
-	return (CISTPLF_NOERROR);
-}
-
-/*
- * cistpl_cftable_handler - handler for the CISTPL_CFTABLE_ENTRY tuple
- *
- *	void *arg - points to a XXX where the information is stuffed into
- *
- *    Return:	CISTPLF_NOERROR - if no error parsing tuple
- *		HANDTPL_ERROR - if error parsing tuple
- */
-extern uint32_t cistpl_cftable_io_size_table[];
-extern uint32_t cistpl_cftable_shift_table[];
-
-uint32_t
-cistpl_cftable_handler(cistpl_callout_t *co, cistpl_t *tp,
-					uint32_t flags, void *arg)
-{
-	cisdata_t tpce_indx, tpce_fs, tpce_td, sf, tpce_io, nr;
-	cisdata_t ior_desc, tpce_ir, tpce_msd;
-	int i, j;
-
-	/*
-	 * nothing special about our flags, so just call the
-	 *	generic handler for this
-	 */
-	if (flags & HANDTPL_SET_FLAGS)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	/*
-	 * We don't currently validate this tuple. This call will
-	 *	always set tp->flags |= CISTPLF_VALID.
-	 */
-	if (flags & HANDTPL_COPY_DONE)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	if (flags & HANDTPL_PARSE_LTUPLE) {
-		cistpl_cftable_entry_t *ce = (cistpl_cftable_entry_t *)arg;
-
-		RESET_TP(tp);
-
-		/*
-		 * Check to see if we have an interface description byte.  If
-		 *	we do, grab it and give it directly to the caller, and
-		 *	set a flag so the caller knows that it's there.
-		 * We also setup the appropriate values in the ce->pin member
-		 *	so that clients can feed this value directly to the
-		 *	Card Services RequestConfiguration call.
-		 */
-		if ((tpce_indx = GET_BYTE(tp)) & CISTPL_CFTABLE_TPCE_IFM) {
-			ce->ifc = GET_BYTE(tp);
-
-			ce->pin = 0;
-
-			if (ce->ifc & CISTPL_CFTABLE_TPCE_IF_BVD)
-			    ce->pin |= (PRR_BVD1_STATUS | PRR_BVD2_STATUS |
-					PRR_BVD1_EVENT | PRR_BVD2_EVENT);
-			if (ce->ifc & CISTPL_CFTABLE_TPCE_IF_WP)
-			    ce->pin |= (PRR_WP_STATUS | PRR_WP_EVENT);
-			if (ce->ifc & CISTPL_CFTABLE_TPCE_IF_RDY)
-			    ce->pin |= (PRR_READY_STATUS | PRR_READY_EVENT);
-
-			ce->flags |= CISTPL_CFTABLE_TPCE_IF;
-		}
-
-		/*
-		 * Return the configuration index to the caller, and set the
-		 *	default configuration flag if this is a default
-		 *	configuration.
-		 */
-		ce->index = tpce_indx & CISTPL_CFTABLE_TPCE_CFGENTRYM;
-		if (tpce_indx & CISTPL_CFTABLE_TPCE_DEFAULTM)
-			ce->flags |= CISTPL_CFTABLE_TPCE_DEFAULT;
-
-		/*
-		 * Feature selection flags.
-		 */
-		tpce_fs = GET_BYTE(tp);
-
-		/*
-		 * See what types of power information are available,
-		 *	and if there is any, set the global power
-		 *	information flag as well as a flag for each
-		 *	power description available.
-		 */
-		if (tpce_fs & CISTPL_CFTABLE_TPCE_FS_PWRM) {
-		    cistpl_cftable_entry_pd_t *pd = &ce->pd;
-
-		    ce->flags |= CISTPL_CFTABLE_TPCE_FS_PWR;
-
-		    switch (tpce_fs & CISTPL_CFTABLE_TPCE_FS_PWRM) {
-			case CISTPL_CFTABLE_TPCE_FS_PWR_VPP2M:
-				pd->flags |= CISTPL_CFTABLE_TPCE_FS_PWR_VPP2;
-				/* FALLTHROUGH */
-			case CISTPL_CFTABLE_TPCE_FS_PWR_VPP1M:
-				pd->flags |= CISTPL_CFTABLE_TPCE_FS_PWR_VPP1;
-				/* FALLTHROUGH */
-			case CISTPL_CFTABLE_TPCE_FS_PWR_VCCM:
-				pd->flags |= CISTPL_CFTABLE_TPCE_FS_PWR_VCC;
-		    } /* switch */
-		} /* if (CISTPL_CFTABLE_TPCE_FS_PWRM) */
-
-		/*
-		 * Set up the global memory information flag.
-		 */
-		if (tpce_fs & CISTPL_CFTABLE_TPCE_FS_MEMM)
-			ce->flags |= CISTPL_CFTABLE_TPCE_FS_MEM;
-
-		/*
-		 * Parse the various power description structures.
-		 */
-		if (ce->flags & CISTPL_CFTABLE_TPCE_FS_PWR) {
-			cistpl_cftable_entry_pd_t *pd = &ce->pd;
-			cistpl_cftable_entry_pwr_t *pwr;
-			/*
-			 * Collect any Vcc information.
-			 */
-			if (pd->flags & CISTPL_CFTABLE_TPCE_FS_PWR_VCC) {
-				pwr = &pd->pd_vcc;
-				cistpl_pd_parse(tp, pwr);
-			}
-			/*
-			 * Collect any Vpp1 information.
-			 */
-			if (pd->flags & CISTPL_CFTABLE_TPCE_FS_PWR_VPP1) {
-				pwr = &pd->pd_vpp1;
-				cistpl_pd_parse(tp, pwr);
-			}
-			/*
-			 * Collect any Vpp2 information.
-			 */
-			if (pd->flags & CISTPL_CFTABLE_TPCE_FS_PWR_VPP2) {
-				pwr = &pd->pd_vpp2;
-				cistpl_pd_parse(tp, pwr);
-			}
-		} /* if (CISTPL_CFTABLE_TPCE_FS_PWR) */
-
-		/*
-		 * Check to see if there's any timing information, and if
-		 *	so, parse the tuple data and store it in the
-		 *	caller's structure.  Set a flag in the global
-		 *	flag field indicating that there is timing information.
-		 */
-		if (tpce_fs & CISTPL_CFTABLE_TPCE_FS_TDM) {
-			convert_speed_t convert_speed;
-			cistpl_cftable_entry_speed_t *sp = &ce->speed;
-			ce->flags |= CISTPL_CFTABLE_TPCE_FS_TD;
-			tpce_td = GET_BYTE(tp);
-			/*
-			 * Parse TPCE_TD to get the various timing
-			 *	scale factors. Each scale factor has
-			 *	a value that indicates that the particular
-			 *	timing parameter doesn't exist.
-			 */
-			if ((sf = (tpce_td &
-					CISTPL_CFTABLE_TPCE_FS_TD_WAITM)) !=
-			    CISTPL_CFTABLE_TPCE_FS_TD_WAITM) {
-				sp->nS_wait = cistpl_devspeed(tp,
-						GET_TPCE_FS_TD_WAITS(sf),
-						CISTPL_DEVSPEED_EXT);
-				convert_speed.Attributes =
-							CONVERT_NS_TO_DEVSPEED;
-				convert_speed.nS = sp->nS_wait;
-				(void) cis_convert_devspeed(&convert_speed);
-				sp->wait = convert_speed.devspeed;
-				sp->flags |= CISTPL_CFTABLE_TPCE_FS_TD_WAIT;
-			}
-
-			if ((sf = (tpce_td & CISTPL_CFTABLE_TPCE_FS_TD_RDYM)) !=
-			    CISTPL_CFTABLE_TPCE_FS_TD_RDYM) {
-				sp->nS_rdybsy = cistpl_devspeed(tp,
-						GET_TPCE_FS_TD_RDYS(sf),
-						CISTPL_DEVSPEED_EXT);
-				convert_speed.Attributes =
-							CONVERT_NS_TO_DEVSPEED;
-				convert_speed.nS = sp->nS_rdybsy;
-				(void) cis_convert_devspeed(&convert_speed);
-				sp->rdybsy = convert_speed.devspeed;
-				sp->flags |= CISTPL_CFTABLE_TPCE_FS_TD_RDY;
-			}
-
-			if ((sf = (tpce_td &
-					CISTPL_CFTABLE_TPCE_FS_TD_RSVDM)) !=
-			    CISTPL_CFTABLE_TPCE_FS_TD_RSVDM) {
-				sp->nS_rsvd = cistpl_devspeed(tp,
-						GET_TPCE_FS_TD_RSVDS(sf),
-						CISTPL_DEVSPEED_EXT);
-				convert_speed.Attributes =
-							CONVERT_NS_TO_DEVSPEED;
-				convert_speed.nS = sp->nS_rsvd;
-				(void) cis_convert_devspeed(&convert_speed);
-				sp->rsvd = convert_speed.devspeed;
-				sp->flags |= CISTPL_CFTABLE_TPCE_FS_TD_RSVD;
-			}
-		} /* if (CISTPL_CFTABLE_TPCE_FS_TDM) */
-
-
-		/*
-		 * Parse any I/O address information.  If there is I/O
-		 *	inforamtion, set a flag in the global flag field
-		 *	to let the caller know.
-		 */
-		if (tpce_fs & CISTPL_CFTABLE_TPCE_FS_IOM) {
-			cistpl_cftable_entry_io_t *io = &ce->io;
-
-			ce->flags |= CISTPL_CFTABLE_TPCE_FS_IO;
-			tpce_io = GET_BYTE(tp);
-			/*
-			 * Pass any I/O flags that are in the tuple directly
-			 *	to the caller.
-			 */
-			io->flags = tpce_io;
-			io->addr_lines = tpce_io &
-						CISTPL_CFTABLE_TPCE_FS_IO_ALM;
-			/*
-			 * If there are any ranges, extract the number of
-			 *	ranges and the range descriptions.
-			 */
-			if (tpce_io & CISTPL_CFTABLE_TPCE_FS_IO_RANGEM) {
-				cistpl_cftable_entry_io_range_t *ior;
-				ior_desc = GET_BYTE(tp);
-				/*
-				 * Number of I/O ranges is the value specified
-				 *	in the tuple plus one, so there's
-				 *	always at least one I/O range if the
-				 *	CISTPL_CFTABLE_TPCE_FS_IO_RANGEM bit
-				 *	in the I/O flags register is set.
-				 */
-				nr = (ior_desc & 0x0f) + 1;
-				io->ranges = nr;
-				/*
-				 * Cycle through each I/O range.
-				 */
-				for (i = 0; i < (int)nr; i++) {
-					ior = &io->range[i];
-					ior->addr = 0;
-					ior->length = 0;
-					/*
-					 * Gather the address information.
-					 *	It's OK if there's no address
-					 *	information in which case this
-					 *	loop will never execute.
-					 */
-					for (j = 0; j <
-						cistpl_cftable_io_size_table[
-							(ior_desc>>4)&3];
-									j++)
-						ior->addr |= (GET_BYTE(tp) <<
-						cistpl_cftable_shift_table[j]);
-					/*
-					 * Gather the length information.
-					 *	It's OK if there's no length
-					 *	information in which case this
-					 *	loop will never execute.
-					 */
-					for (j = 0; j <
-						cistpl_cftable_io_size_table[
-							(ior_desc>>6)&3];
-									j++)
-						ior->length |= (GET_BYTE(tp) <<
-						cistpl_cftable_shift_table[j]);
-				} /* for (nr) */
-			} /* if (CISTPL_CFTABLE_TPCE_FS_IO_RANGEM) */
-		} /* if (CISTPL_CFTABLE_TPCE_FS_IOM) */
-
-		/*
-		 * Parse any IRQ information.  If there is IRQ inforamtion,
-		 *	set a flag in the global flag field to let the
-		 *	caller know.
-		 */
-		if (tpce_fs & CISTPL_CFTABLE_TPCE_FS_IRQM) {
-			cistpl_cftable_entry_irq_t *irq = &ce->irq;
-
-			ce->flags |= CISTPL_CFTABLE_TPCE_FS_IRQ;
-			tpce_ir = GET_BYTE(tp);
-			/*
-			 * Pass any IRQ flags that are in the tuple directly
-			 *	to the caller.
-			 */
-			irq->flags = tpce_ir;
-			/*
-			 * Check for and parse the extended IRQ bitmask
-			 *	if it exists.
-			 */
-			if (tpce_ir & CISTPL_CFTABLE_TPCE_FS_IRQ_MASKM) {
-				irq->irqs = GET_BYTE(tp) & 0x0ff;
-				irq->irqs |= (GET_BYTE(tp) << 8)&0x0ff00;
-			} else {
-				irq->irqs = (1<< (tpce_ir&0x0f));
-			}
-		} /* if (CISTPL_CFTABLE_TPCE_FS_IRQM) */
-
-		/*
-		 * Parse any memory information.
-		 *
-		 * XXX - should be a cleaner way to parse this information.
-		 */
-		if (ce->flags & CISTPL_CFTABLE_TPCE_FS_MEM) {
-			cistpl_cftable_entry_mem_t *mem = &ce->mem;
-			cistpl_cftable_entry_mem_window_t *win;
-			/*
-			 * Switch on the type of memory description
-			 *	information that is available.
-			 */
-			switch (tpce_fs & CISTPL_CFTABLE_TPCE_FS_MEMM) {
-				/*
-				 * variable length memory space description
-				 */
-			case CISTPL_CFTABLE_TPCE_FS_MEM3M:
-				mem->flags |= CISTPL_CFTABLE_TPCE_FS_MEM3;
-				/* memory space descriptor */
-				tpce_msd = GET_BYTE(tp);
-				mem->windows = ((tpce_msd &
-					(CISTPL_CFTABLE_ENTRY_MAX_MEM_WINDOWS -
-								1)) + 1);
-				/*
-				 * If there's host address information, let
-				 *	the caller know.
-				 */
-				if (tpce_msd & CISTPL_CFTABLE_TPCE_FS_MEM_HOSTM)
-					mem->flags |=
-						CISTPL_CFTABLE_TPCE_FS_MEM_HOST;
-				/*
-				 * Cycle through each window space description
-				 *	and collect all the interesting bits.
-				 */
-				for (i = 0; i < mem->windows; i++) {
-					win = &mem->window[i];
-					win->length = 0;
-					win->card_addr = 0;
-					win->host_addr = 0;
-					/*
-					 * Gather the length information.
-					 *	It's OK if there's no length
-					 *	information in which case this
-					 *	loop will never execute.
-					 */
-					for (j = 0; j <
-						(int)((tpce_msd>>3)&3); j++)
-						win->length |= (GET_BYTE(tp) <<
-						cistpl_cftable_shift_table[j]);
-					/*
-					 * Gather the card address information.
-					 *	It's OK if there's no card
-					 *	address information in which
-					 *	case this loop will never
-					 *	execute.
-					 */
-					for (j = 0; j <
-						(int)((tpce_msd>>5)&3); j++)
-						win->card_addr |=
-							(GET_BYTE(tp) <<
-						cistpl_cftable_shift_table[j]);
-					/*
-					 * If there's a host address
-					 *	description, grab that
-					 *	as well.
-					 */
-					if (mem->flags &
-					    CISTPL_CFTABLE_TPCE_FS_MEM_HOST) {
-						/*
-						 * Gather the host address
-						 *	information.  It's OK
-						 *	if there's no host
-						 *	address information in
-						 *	which case this loop
-						 *	will never execute.
-						 * Note that we use the card
-						 *	address size to
-						 *	determine how many
-						 *	bytes of host address
-						 *	are present.
-						 */
-						for (j = 0; j <
-							(int)((tpce_msd>>5)&3);
-									j++)
-							win->host_addr |=
-							(GET_BYTE(tp) <<
-						cistpl_cftable_shift_table[j]);
-					} else {
-						/*
-						 * No host address information,
-						 *	so the host address is
-						 *	equal to the card
-						 *	address.
-						 */
-						win->host_addr = win->card_addr;
-					}
-				} /* for (i<mem->windows) */
-				break;
-				/*
-				 * single length and card base address specified
-				 */
-			case CISTPL_CFTABLE_TPCE_FS_MEM2M:
-				mem->flags |= CISTPL_CFTABLE_TPCE_FS_MEM2;
-				win = &mem->window[0];
-				mem->windows = 1;
-				/*
-				 * Construct the size of the window.
-				 */
-				win->length = GET_BYTE(tp);
-				win->length |= (GET_BYTE(tp)<<8);
-				win->length *=
-					CISTPL_CFTABLE_TPCE_FS_MEM_PGSIZE;
-
-				/*
-				 * Construct the card base address.
-				 */
-				win->card_addr = GET_BYTE(tp);
-				win->card_addr |= (GET_BYTE(tp)<<8);
-				win->card_addr *=
-					CISTPL_CFTABLE_TPCE_FS_MEM_PGSIZE;
-
-				/*
-				 * In this mode, both the host base address
-				 *	and the card base address are equal.
-				 */
-				win->host_addr = win->card_addr;
-				break;
-				/*
-				 * single length specified
-				 */
-			case CISTPL_CFTABLE_TPCE_FS_MEM1M:
-				mem->flags |= CISTPL_CFTABLE_TPCE_FS_MEM1;
-				win = &mem->window[0];
-				mem->windows = 1;
-				win->card_addr = 0;
-				win->host_addr = 0;
-				/*
-				 * Construct the size of the window.
-				 */
-				win->length = GET_BYTE(tp);
-				win->length |= (GET_BYTE(tp)<<8);
-				win->length *=
-					CISTPL_CFTABLE_TPCE_FS_MEM_PGSIZE;
-				break;
-			} /* switch (CISTPL_CFTABLE_TPCE_FS_MEMM) */
-		} /* if (CISTPL_CFTABLE_TPCE_FS_MEM) */
-
-		/*
-		 * Check for and parse any miscellaneous information.
-		 *
-		 * We only understand how to parse the first
-		 *	CISTPL_CFTABLE_TPCE_FS_MISC_MAX extension
-		 *	bytes specified in the PC Card 95 standard;
-		 *	we throw away any other extension bytes that
-		 *	are past these bytes.
-		 * XXX Note that the assumption here is that the
-		 *	size of cistpl_cftable_entry_misc_t->flags
-		 *	is at least CISTPL_CFTABLE_TPCE_FS_MISC_MAX
-		 *	bytes in length.
-		 */
-		if (tpce_fs & CISTPL_CFTABLE_TPCE_FS_MISCM) {
-		    cistpl_cftable_entry_misc_t *misc = &ce->misc;
-		    int mb = CISTPL_CFTABLE_TPCE_FS_MISC_MAX;
-
-		    ce->flags |= CISTPL_CFTABLE_TPCE_FS_MISC;
-		    misc->flags = 0;
-
-		    do {
-			if (mb) {
-			    misc->flags = (misc->flags << 8) | LOOK_BYTE(tp);
-			    mb--;
-			}
-		    } while ((GET_BYTE(tp) & CISTPL_EXT_BIT) &&
-				(!(tp->flags & CISTPLF_MEM_ERR)));
-
-			/*
-			 * Check to see if we tried to read past the
-			 *	end of the tuple data; if we have,
-			 *	there's no point in trying to parse
-			 *	any more of the tuple.
-			 */
-		    if (tp->flags & CISTPLF_MEM_ERR)
-			return (HANDTPL_ERROR);
-		} /* if (CISTPL_CFTABLE_TPCE_FS_MISCM) */
-
-		/*
-		 * Check for and parse any additional subtuple
-		 *	information. We know that there is
-		 *	additional information if we haven't
-		 *	reached the end of the tuple data area
-		 *	and if the additional information is
-		 *	in standard tuple format.
-		 * If we don't recognize the additional info,
-		 *	then just silently ignore it, don't
-		 *	flag it as an error.
-		 */
-#ifdef	PARSE_STCE_TUPLES
-		if (GET_LEN(tp) > 0) {
-
-		ce->flags |= CISTPL_CFTABLE_TPCE_FS_STCE_EV
-		ce->flags |= CISTPL_CFTABLE_TPCE_FS_STCE_PD
-#endif
-
-	} /* if (HANDTPL_PARSE_LTUPLE) */
-
-	return (CISTPLF_NOERROR);
-}
-
-/*
- * cistpl_pd_parse - read and parse a power description structure
- *
- *	cisdata_t **ddp - pointer to pointer tuple data area
- *	cistpl_cftable_entry_pwr_t *pd - pointer to local power description
- *					structure
- */
-static void
-cistpl_pd_parse(cistpl_t *tp, cistpl_cftable_entry_pwr_t *pd)
-{
-	cisdata_t pdesc;
-
-	pdesc = GET_BYTE(tp);	/* power description selector */
-
-	/* nominal supply voltage */
-	if (pdesc & CISTPL_CFTABLE_PD_NOMV) {
-		pd->nomV = cistpl_expd_parse(tp, &pd->nomV_flags) / 100;
-		pd->nomV_flags |= (pdesc | CISTPL_CFTABLE_PD_EXISTS);
-	}
-
-	/* minimum supply voltage */
-	if (pdesc & CISTPL_CFTABLE_PD_MINV) {
-		pd->minV = cistpl_expd_parse(tp, &pd->minV_flags) / 100;
-		pd->minV_flags |= (pdesc | CISTPL_CFTABLE_PD_EXISTS);
-	}
-
-	/* maximum supply voltage */
-	if (pdesc & CISTPL_CFTABLE_PD_MAXV) {
-		pd->maxV = cistpl_expd_parse(tp, &pd->maxV_flags) / 100;
-		pd->maxV_flags |= (pdesc | CISTPL_CFTABLE_PD_EXISTS);
-	}
-
-	/* continuous supply current */
-	if (pdesc & CISTPL_CFTABLE_PD_STATICI) {
-		pd->staticI_flags |= CISTPL_CFTABLE_PD_MUL10;
-		pd->staticI = cistpl_expd_parse(tp, &pd->staticI_flags);
-		pd->staticI_flags |= (pdesc | CISTPL_CFTABLE_PD_EXISTS);
-	}
-
-	/* maximum current required averaged over 1 second */
-	if (pdesc & CISTPL_CFTABLE_PD_AVGI) {
-		pd->avgI_flags |= CISTPL_CFTABLE_PD_MUL10;
-		pd->avgI = cistpl_expd_parse(tp, &pd->avgI_flags);
-		pd->avgI_flags |= (pdesc | CISTPL_CFTABLE_PD_EXISTS);
-	}
-
-	/* maximum current required averaged over 10mS */
-	if (pdesc & CISTPL_CFTABLE_PD_PEAKI) {
-		pd->peakI_flags |= CISTPL_CFTABLE_PD_MUL10;
-		pd->peakI = cistpl_expd_parse(tp, &pd->peakI_flags);
-		pd->peakI_flags |= (pdesc | CISTPL_CFTABLE_PD_EXISTS);
-	}
-
-	/* power down supply curent required */
-	if (pdesc & CISTPL_CFTABLE_PD_PDOWNI) {
-		pd->pdownI_flags |= CISTPL_CFTABLE_PD_MUL10;
-		pd->pdownI = cistpl_expd_parse(tp, &pd->pdownI_flags);
-		pd->pdownI_flags |= (pdesc | CISTPL_CFTABLE_PD_EXISTS);
-	}
-}
-
-/*
- * cistpl_expd_parse - read and parse an extended power description structure
- *
- *	cistpl_t *tp - pointer to pointer tuple data area
- *	int *flags - flags that get for this parameter:
- *			CISTPL_CFTABLE_PD_NC_SLEEP - no connection on
- *							sleep/power down
- *			CISTPL_CFTABLE_PD_ZERO - zero value required
- *			CISTPL_CFTABLE_PD_NC - no connection ever
- *
- * The power consumption is returned in the following units:
- *
- *				voltage - milliVOLTS
- *				current - microAMPS
- */
-extern cistpl_pd_struct_t cistpl_pd_struct;
-
-uint32_t
-cistpl_expd_parse(cistpl_t *tp, uint32_t *flags)
-{
-	cisdata_t pdesc;
-	uint32_t exponent, mantisa, val, digits = 0;
-
-	/*
-	 * Get the power description parameter byte and break it up
-	 *	into mantissa and exponent.
-	 */
-	pdesc = GET_BYTE(tp);
-	exponent = pdesc&7;
-	mantisa = (pdesc>>3)&0x0f;
-
-	if (pdesc & CISTPL_EXT_BIT) {
-		do {
-			if (LOOK_BYTE(tp) <= 0x63)
-				digits = LOOK_BYTE(tp);
-			if (LOOK_BYTE(tp) == CISTPL_CFTABLE_PD_NC_SLEEPM)
-				*flags |= CISTPL_CFTABLE_PD_NC_SLEEP;
-			if (LOOK_BYTE(tp) == CISTPL_CFTABLE_PD_ZEROM)
-				*flags |= CISTPL_CFTABLE_PD_ZERO;
-			if (LOOK_BYTE(tp) == CISTPL_CFTABLE_PD_NCM)
-				*flags |= CISTPL_CFTABLE_PD_NC;
-		} while (GET_BYTE(tp) & CISTPL_EXT_BIT);
-	}
-
-	val = CISTPL_PD_MAN(mantisa) * CISTPL_PD_EXP(exponent);
-
-	/*
-	 * If we have to multiply the power value by ten, then just
-	 *	don't bother dividing.
-	 */
-	if (! (*flags & CISTPL_CFTABLE_PD_MUL10))
-		val = val/10;	/* do this since our mantissa table is X 10 */
-
-	/*
-	 * If we need to add some digits to the right of the decimal, do
-	 *	that here.
-	 */
-	if (exponent)
-		val = val + (digits * CISTPL_PD_EXP(exponent-1));
-
-	val /= 1000;
-
-	return (val);
-}
-
-/*
- * cistpl_devspeed - returns device speed in nS
- *
- *	cistpl_t *tp - tuple pointer.
- *	cisdata_t spindex - device speed table index
- *	int flags - operation flags
- *		CISTPL_DEVSPEED_TABLE:
- *		    Use the spindex argument as an index into a simple
- *			device speed table. ref: PCMCIA Release 2.01
- *			Card Metaformat pg. 5-14 table 5-12.
- *		    When this flag is set, the spindex argument is ignored.
- *		CISTPL_DEVSPEED_EXT:
- *		    Use the tp argument to access the
- *			tuple data area containing an extended speed
- *			code table.  ref: PCMCIA Release 2.01 Card
- *			Metaformat pg. 5-15 table 5-13.
- *		    The tp->read argument must point to the first byte of
- *			an extended speed code table.
- *		    When this flag is set, the spindex argument is
- *			used as a power-of-10 scale factor.  We only allow
- *			a maximum scale factor of 10^16.
- *
- * The device speed is returned in nS for all combinations of flags and
- *	speed table entries.
- *
- * Note if you pass the CISTPL_DEVSPEED_TABLE with a spindex index that
- *	refers to an extended speed table, you will get back an undefined
- *	speed value.
- */
-extern cistpl_devspeed_struct_t cistpl_devspeed_struct;
-
-uint32_t
-cistpl_devspeed(cistpl_t *tp, cisdata_t spindex, uint32_t flags)
-{
-	int scale = 1, first;
-	cisdata_t exspeed;
-	int exponent, mantisa;
-	uint32_t speed;
-
-	switch (flags) {
-	case CISTPL_DEVSPEED_TABLE:
-		speed = CISTPL_DEVSPEED_TBL(spindex);
-		break;
-	case CISTPL_DEVSPEED_EXT:
-		do {
-			exspeed = GET_BYTE(tp);
-			first = 1;
-			if (first) {
-				/*
-				 * XXX - ugh! we don't understand additional
-				 *	exspeed bytes
-				 */
-				first = 0;
-				exponent = (exspeed & 0x07);
-				mantisa = (exspeed >> 3) & 0x0f;
-				spindex &= 0x0f;	/* only allow 10^16 */
-				while (spindex--)
-					scale *= 10;
-			} /* if (first) */
-		} while (exspeed & CISTPL_EXT_BIT);
-		speed = scale * CISTPL_DEVSPEED_MAN(mantisa) *
-						CISTPL_DEVSPEED_EXP(exponent);
-		speed = speed/10;	/* XXX - mantissa table is all X 10 */
-		break;
-	default:
-		break;
-	}
-
-	return (speed);
-}
-
-/*
- * cistpl_vers_2_handler - handler for the CISTPL_VERS_2 tuple
- *
- *	void *arg - points to a XXX where the information is stuffed into
- */
-uint32_t
-cistpl_vers_2_handler(cistpl_callout_t *co, cistpl_t *tp,
-					uint32_t flags, void *arg)
-{
-	/*
-	 * nothing special about our flags, so just call the
-	 *	generic handler for this
-	 */
-	if (flags & HANDTPL_SET_FLAGS)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	/*
-	 * We don't currently validate this tuple. This call will
-	 *	always set tp->flags |= CISTPLF_VALID.
-	 */
-	if (flags & HANDTPL_COPY_DONE)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	if (flags & HANDTPL_PARSE_LTUPLE) {
-		cistpl_vers_2_t *cs = (cistpl_vers_2_t *)arg;
-
-		RESET_TP(tp);
-
-		cs->vers = GET_BYTE(tp);
-		cs->comply = GET_BYTE(tp);
-		cs->dindex = GET_SHORT(tp);
-
-		cs->reserved = GET_SHORT(tp);
-
-		cs->vspec8 = GET_BYTE(tp);
-		cs->vspec9 = GET_BYTE(tp);
-		cs->nhdr = GET_BYTE(tp);
-
-		(void) strcpy(cs->oem, cis_getstr(tp));
-
-		if (GET_LEN(tp) > 0)
-		    (void) strcpy(cs->info, cis_getstr(tp));
-		else
-		    (void) strcpy(cs->info, "(no info)");
-	}
-
-	return (CISTPLF_NOERROR);
-}
-
-/*
- * cistpl_jedec_handler - handler for JEDEC C and JEDEC A tuples
- *
- *	void *arg - points to a XXX where the information is stuffed into
- */
-uint32_t
-cistpl_jedec_handler(cistpl_callout_t *co, cistpl_t *tp,
-					uint32_t flags, void *arg)
-{
-	/*
-	 * nothing special about our flags, so just call the
-	 *	generic handler for this
-	 */
-	if (flags & HANDTPL_SET_FLAGS)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	/*
-	 * We don't currently validate this tuple. This call will
-	 *	always set tp->flags |= CISTPLF_VALID.
-	 */
-	if (flags & HANDTPL_COPY_DONE)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	if (flags & HANDTPL_PARSE_LTUPLE) {
-		int nid;
-		cistpl_jedec_t *cs = (cistpl_jedec_t *)arg;
-
-		RESET_TP(tp);
-
-		for (nid = 0; GET_LEN(tp) > 0 &&
-					nid < CISTPL_JEDEC_MAX_IDENTIFIERS &&
-					LOOK_BYTE(tp) != 0xFF; nid++) {
-			cs->jid[nid].id = GET_BYTE(tp);
-			cs->jid[nid].info = GET_BYTE(tp);
-		}
-		cs->nid = nid;
-	}
-
-	return (CISTPLF_NOERROR);
-}
-
-/*
- * cistpl_format_handler - handler for the CISTPL_FORMAT and
- *				CISTPL_FORMAT_A tuples
- */
-uint32_t
-cistpl_format_handler(cistpl_callout_t *co, cistpl_t *tp,
-					uint32_t flags, void *arg)
-{
-	/*
-	 * nothing special about our flags, so just call the
-	 *	generic handler for this
-	 */
-	if (flags & HANDTPL_SET_FLAGS)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	/*
-	 * We don't currently validate this tuple. This call will
-	 *	always set tp->flags |= CISTPLF_VALID.
-	 */
-	if (flags & HANDTPL_COPY_DONE)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	if (flags & HANDTPL_PARSE_LTUPLE) {
-		cistpl_format_t *cs = (cistpl_format_t *)arg;
-
-		RESET_TP(tp);
-
-		cs->type = GET_BYTE(tp);
-		cs->edc_length = LOOK_BYTE(tp) & EDC_LENGTH_MASK;
-		cs->edc_type = ((uint32_t)GET_BYTE(tp) >> EDC_TYPE_SHIFT) &
-								EDC_TYPE_MASK;
-		cs->offset = GET_LONG(tp);
-		cs->nbytes = GET_LONG(tp);
-
-		switch (cs->type) {
-		case TPLFMTTYPE_DISK:
-			cs->dev.disk.bksize = GET_SHORT(tp);
-			cs->dev.disk.nblocks = GET_LONG(tp);
-			cs->dev.disk.edcloc = GET_LONG(tp);
-			break;
-
-		case TPLFMTTYPE_MEM:
-			cs->dev.mem.flags = GET_BYTE(tp);
-			cs->dev.mem.reserved = GET_BYTE(tp);
-			cs->dev.mem.address = (caddr_t)(uintptr_t)GET_LONG(tp);
-			cs->dev.disk.edcloc = GET_LONG(tp);
-			break;
-		default:
-			/* don't know about any other type */
-			break;
-		}
-	}
-
-	return (CISTPLF_NOERROR);
-}
-
-/*
- * cistpl_geometry_handler - handler for the CISTPL_GEOMETRY tuple
- *
- *	void *arg - points to a XXX where the information is stuffed into
- */
-uint32_t
-cistpl_geometry_handler(cistpl_callout_t *co, cistpl_t *tp, uint32_t flags,
-								void *arg)
-{
-	/*
-	 * nothing special about our flags, so just call the
-	 *	generic handler for this
-	 */
-	if (flags & HANDTPL_SET_FLAGS)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	/*
-	 * We don't currently validate this tuple. This call will
-	 *	always set tp->flags |= CISTPLF_VALID.
-	 */
-	if (flags & HANDTPL_COPY_DONE)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	if (flags & HANDTPL_PARSE_LTUPLE) {
-		cistpl_geometry_t *cs = (cistpl_geometry_t *)arg;
-
-		RESET_TP(tp);
-		cs->spt = GET_BYTE(tp);
-		cs->tpc = GET_BYTE(tp);
-		cs->ncyl = GET_SHORT(tp);
-	}
-	return (CISTPLF_NOERROR);
-}
-
-/*
- * cistpl_byteorder_handler - handler for the CISTPL_BYTEORDER tuple
- *
- *	void *arg - points to a XXX where the information is stuffed into
- */
-uint32_t
-cistpl_byteorder_handler(cistpl_callout_t *co, cistpl_t *tp, uint32_t flags,
-								void *arg)
-{
-	/*
-	 * nothing special about our flags, so just call the
-	 *	generic handler for this
-	 */
-	if (flags & HANDTPL_SET_FLAGS)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	/*
-	 * We don't currently validate this tuple. This call will
-	 *	always set tp->flags |= CISTPLF_VALID.
-	 */
-	if (flags & HANDTPL_COPY_DONE)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	if (flags & HANDTPL_PARSE_LTUPLE) {
-		cistpl_byteorder_t *cs = (cistpl_byteorder_t *)arg;
-
-		RESET_TP(tp);
-		cs->order = GET_BYTE(tp);
-		cs->map = GET_BYTE(tp);
-	}
-	return (CISTPLF_NOERROR);
-}
-
-/*
- * cistpl_date_handler - handler for CISTPL_DATE card format tuple
- *
- *	void *arg - points to a cistpl_date_t * where the
- *			information is stuffed into
- */
-uint32_t
-cistpl_date_handler(cistpl_callout_t *co, cistpl_t *tp,
-					uint32_t flags, void *arg)
-{
-	/*
-	 * nothing special about our flags, so just call the
-	 *	generic handler for this
-	 */
-	if (flags & HANDTPL_SET_FLAGS)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	/*
-	 * We don't currently validate this tuple. This call will
-	 *	always set tp->flags |= CISTPLF_VALID.
-	 */
-	if (flags & HANDTPL_COPY_DONE)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	if (flags & HANDTPL_PARSE_LTUPLE) {
-		cistpl_date_t *cs = (cistpl_date_t *)arg;
-
-		RESET_TP(tp);
-		cs->time = GET_SHORT(tp);
-		cs->day = GET_SHORT(tp);
-	}
-	return (CISTPLF_NOERROR);
-}
-
-/*
- * cistpl_battery_handler - handler for CISTPL_BATTERY battery replacement
- *				date tuple
- *
- *	void *arg - points to a cistpl_battery_t * where the
- *			information is stuffed into
- */
-uint32_t
-cistpl_battery_handler(cistpl_callout_t *co, cistpl_t *tp,
-					uint32_t flags, void *arg)
-{
-	/*
-	 * nothing special about our flags, so just call the
-	 *	generic handler for this
-	 */
-	if (flags & HANDTPL_SET_FLAGS)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	/*
-	 * We don't currently validate this tuple. This call will
-	 *	always set tp->flags |= CISTPLF_VALID.
-	 */
-	if (flags & HANDTPL_COPY_DONE)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	if (flags & HANDTPL_PARSE_LTUPLE) {
-		cistpl_battery_t *cs = (cistpl_battery_t *)arg;
-
-		RESET_TP(tp);
-		cs->rday = GET_SHORT(tp);
-		cs->xday = GET_SHORT(tp);
-	}
-	return (CISTPLF_NOERROR);
-}
-
-/*
- * cistpl_org_handler - handler for CISTPL_ORG data organization tuple
- *
- *	void *arg - points to a cistpl_org_t * where the
- *			information is stuffed into
- */
-uint32_t
-cistpl_org_handler(cistpl_callout_t *co, cistpl_t *tp,
-					uint32_t flags, void *arg)
-{
-	/*
-	 * nothing special about our flags, so just call the
-	 *	generic handler for this
-	 */
-	if (flags & HANDTPL_SET_FLAGS)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	/*
-	 * We don't currently validate this tuple. This call will
-	 *	always set tp->flags |= CISTPLF_VALID.
-	 */
-	if (flags & HANDTPL_COPY_DONE)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	if (flags & HANDTPL_PARSE_LTUPLE) {
-		cistpl_org_t *cs = (cistpl_org_t *)arg;
-
-		RESET_TP(tp);
-		cs->type = GET_BYTE(tp);
-
-		(void) strcpy(cs->desc, cis_getstr(tp));
-	}
-
-	return (CISTPLF_NOERROR);
-}
-
-
-/*
- * cistpl_manfid_handler - handler for CISTPL_MANFID, the manufacturer ID tuple
- *
- *	void *arg - points to a XXX where the information is stuffed into
- */
-uint32_t
-cistpl_manfid_handler(cistpl_callout_t *co, cistpl_t *tp,
-					uint32_t flags, void *arg)
-{
-	/*
-	 * nothing special about our flags, so just call the
-	 *	generic handler for this
-	 */
-	if (flags & HANDTPL_SET_FLAGS)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	/*
-	 * We don't currently validate this tuple. This call will
-	 *	always set tp->flags |= CISTPLF_VALID.
-	 */
-	if (flags & HANDTPL_COPY_DONE)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	if (flags & HANDTPL_PARSE_LTUPLE) {
-		cistpl_manfid_t *cs = (cistpl_manfid_t *)arg;
-
-		RESET_TP(tp);
-		cs->manf = GET_SHORT(tp);
-		cs->card = GET_SHORT(tp);
-	}
-	return (CISTPLF_NOERROR);
-}
-
-/*
- * cistpl_funcid_handler - handler for CISTPL_FUNCID
- *
- *	void *arg - points to a XXX where the information is stuffed into
- */
-uint32_t
-cistpl_funcid_handler(cistpl_callout_t *co, cistpl_t *tp,
-					uint32_t flags, void *arg)
-{
-	/*
-	 * nothing special about our flags, so just call the
-	 *	generic handler for this
-	 */
-	if (flags & HANDTPL_SET_FLAGS)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	/*
-	 * We don't currently validate this tuple. This call will
-	 *	always set tp->flags |= CISTPLF_VALID.
-	 */
-	if (flags & HANDTPL_COPY_DONE)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	if (flags & HANDTPL_PARSE_LTUPLE) {
-		cistpl_funcid_t *cs = (cistpl_funcid_t *)arg;
-
-		RESET_TP(tp);
-
-		cs->function = GET_BYTE(tp);
-		cs->sysinit = GET_BYTE(tp);
-	}
-	return (CISTPLF_NOERROR);
-}
-
-
-/*
- * cistpl_funce_serial_handler - handler for the CISTPL_FUNCE/SERIAL tuple
- *
- *	void *arg - points to a XXX where the information is stuffed into
- */
-uint32_t
-cistpl_funce_serial_handler(cistpl_callout_t *co, cistpl_t *tp,
-						uint32_t flags, void *arg)
-{
-	int subfunction;
-
-	/*
-	 * nothing special about our flags, so just call the
-	 *	generic handler for this
-	 */
-	if (flags & HANDTPL_SET_FLAGS)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	/*
-	 * We don't currently validate this tuple. This call will
-	 *	always set tp->flags |= CISTPLF_VALID.
-	 */
-	if (flags & HANDTPL_COPY_DONE)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	if (flags & HANDTPL_PARSE_LTUPLE) {
-		cistpl_funce_t *cs = (cistpl_funce_t *)arg;
-
-		RESET_TP(tp);
-
-		cs->function = TPLFUNC_SERIAL;
-		cs->subfunction = subfunction = GET_BYTE(tp);
-		switch (subfunction & 0xF) {
-		case TPLFE_SUB_SERIAL:
-		case TPLFE_CAP_SERIAL_DATA:
-		case TPLFE_CAP_SERIAL_FAX:
-		case TPLFE_CAP_SERIAL_VOICE:
-			cs->data.serial.ua = GET_BYTE(tp);
-			cs->data.serial.uc = GET_SHORT(tp);
-			break;
-		case TPLFE_SUB_MODEM_COMMON:
-		case TPLFE_CAP_MODEM_DATA:
-		case TPLFE_CAP_MODEM_FAX:
-		case TPLFE_CAP_MODEM_VOICE:
-			cs->data.modem.fc = GET_BYTE(tp);
-			cs->data.modem.cb = (GET_BYTE(tp) + 1) * 4;
-			cs->data.modem.eb = GET_INT24(tp);
-			cs->data.modem.tb = GET_INT24(tp);
-			break;
-		case TPLFE_SUB_MODEM_DATA:
-			cs->data.data_modem.ud = GET_BE_SHORT(tp) * 75;
-			cs->data.data_modem.ms = GET_SHORT(tp);
-			cs->data.data_modem.em = GET_BYTE(tp);
-			cs->data.data_modem.dc = GET_BYTE(tp);
-			cs->data.data_modem.cm = GET_BYTE(tp);
-			cs->data.data_modem.ex = GET_BYTE(tp);
-			cs->data.data_modem.dy = GET_BYTE(tp);
-			cs->data.data_modem.ef = GET_BYTE(tp);
-			for (cs->data.data_modem.ncd = 0;
-				GET_LEN(tp) > 0 && cs->data.data_modem.ncd < 16;
-						cs->data.data_modem.ncd++)
-				if (LOOK_BYTE(tp) != 255) {
-					cs->data.data_modem.cd[
-						cs->data.data_modem.ncd] =
-								GET_BYTE(tp);
-				} else {
-					GET_BYTE(tp);
-					break;
-				}
-			break;
-		case TPLFE_SUB_MODEM_FAX:
-			cs->data.fax.uf = GET_BE_SHORT(tp) * 75;
-			cs->data.fax.fm = GET_BYTE(tp);
-			cs->data.fax.fy = GET_BYTE(tp);
-			cs->data.fax.fs = GET_SHORT(tp);
-			for (cs->data.fax.ncf = 0;
-				GET_LEN(tp) > 0 && cs->data.fax.ncf < 16;
-							cs->data.fax.ncf++)
-				if (LOOK_BYTE(tp) != 255) {
-					cs->data.fax.cf[cs->data.fax.ncf] =
-								GET_BYTE(tp);
-				} else {
-					GET_BYTE(tp);
-					break;
-				}
-			break;
-		case TPLFE_SUB_VOICE:
-			cs->data.voice.uv = GET_BE_SHORT(tp) * 75;
-			for (cs->data.voice.nsr = 0; LOOK_BYTE(tp) != 0 &&
-				GET_LEN(tp) >= 2;
-						cs->data.voice.nsr++) {
-				cs->data.voice.sr[cs->data.voice.nsr] =
-					GET_BYTE(tp) * 1000;
-				cs->data.voice.sr[cs->data.voice.nsr] +=
-					GET_BYTE(tp) * 100;
-			}
-			for (cs->data.voice.nss = 0; LOOK_BYTE(tp) != 0 &&
-				GET_LEN(tp) >= 2;
-						cs->data.voice.nss++) {
-				cs->data.voice.ss[cs->data.voice.nss] =
-					GET_BYTE(tp) * 10;
-				cs->data.voice.ss[cs->data.voice.nss] +=
-								GET_BYTE(tp);
-			}
-			for (cs->data.voice.nsc = 0; LOOK_BYTE(tp) != 0 &&
-				GET_LEN(tp) >= 1;
-						cs->data.voice.nsc++) {
-				cs->data.voice.sc[cs->data.voice.nsc] =
-								GET_BYTE(tp);
-			}
-			break;
-		default:
-			break;
-		}
-	}
-	return (CISTPLF_NOERROR);
-}
-
-/*
- * cistpl_funce_lan_handler - handler for the CISTPL_FUNCE/LAN tuple
- *
- *	void *arg - points to a XXX where the information is stuffed into
- */
-uint32_t
-cistpl_funce_lan_handler(cistpl_callout_t *co, cistpl_t *tp, uint32_t flags,
-								void *arg)
-{
-	int subfunction;
-
-	/*
-	 * nothing special about our flags, so just call the
-	 *	generic handler for this
-	 */
-	if (flags & HANDTPL_SET_FLAGS)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	/*
-	 * We don't currently validate this tuple. This call will
-	 *	always set tp->flags |= CISTPLF_VALID.
-	 */
-	if (flags & HANDTPL_COPY_DONE)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	if (flags & HANDTPL_PARSE_LTUPLE) {
-		int i;
-		cistpl_funce_t *cs = (cistpl_funce_t *)arg;
-
-		RESET_TP(tp);
-
-		cs->function = TPLFUNC_LAN;
-		cs->subfunction = subfunction = GET_BYTE(tp);
-
-		switch (subfunction) {
-		case TPLFE_NETWORK_INFO:
-			cs->data.lan.tech = GET_BYTE(tp);
-			cs->data.lan.speed = GET_BYTE(tp);
-			i = GET_BYTE(tp);
-			if (i < 24) {
-				cs->data.lan.speed <<= i;
-			} else {
-				/*
-				 * if speed is too large a value
-				 * to hold in a uint32 flag it and
-				 * store as [mantissa][exponent]
-				 * in least significant 16 bits
-				 */
-				cs->data.lan.speed = 0x80000000 |
-					(cs->data.lan.speed << 8) | i;
-			}
-			cs->data.lan.media = GET_BYTE(tp);
-			cs->data.lan.con = GET_BYTE(tp);
-			cs->data.lan.id_sz = GET_BYTE(tp);
-			if (cs->data.lan.id_sz <= 16) {
-				for (i = 0; i < cs->data.lan.id_sz; i++)
-					cs->data.lan.id[i] = GET_BYTE(tp);
-			}
-			break;
-		default:
-				/* unknown LAN tuple type */
-			return (CISTPLF_UNKNOWN);
-		}
-	}
-	return (CISTPLF_NOERROR);
-}
-
-/*
- * cistpl_linktarget_handler - handler for CISTPL_LINKTARGET tuple
- *
- *	void *arg - points to a cistpl_linktarget_t * where the
- *			information is stuffed into
- *
- *	If HANDTPL_COPY_DONE is set, we just validate the tuple but
- *		do not return any values.
- *	If HANDTPL_PARSE_LTUPLE is set, we validate the tuple and
- *		return the parsed tuple data if the tuple is valid.
- *
- *	If the tuple link field is invalid, the CISTPLF_LINK_INVALID flag
- *		will be set in the tp->flags field and HANDTPL_ERROR
- *		will be returned.
- *
- *	If the tuple data body is invalid, the CISTPLF_PARAMS_INVALID flag
- *		will be set in the tp->flags field and HANDTPL_ERROR
- *		will be returned.
- *
- *	The tuple is considered invalid if it's link field is less than
- *		MIN_LINKTARGET_LENGTH or if the data body of the tuple
- *		does not contain the pattern CISTPL_LINKTARGET_MAGIC.
- *
- * XXX At some point we should revisit this to see if we can call
- *	cis_validate_longlink_acm instead of doing the validation
- *	in both places.
- */
-uint32_t
-cistpl_linktarget_handler(cistpl_callout_t *co, cistpl_t *tp, uint32_t flags,
-								void *arg)
-{
-	/*
-	 * nothing special about our flags, so just call the
-	 *	generic handler for this
-	 */
-	if (flags & HANDTPL_SET_FLAGS)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	/*
-	 * Validate the tuple for both the HANDTPL_COPY_DONE case and
-	 *	the HANDTPL_PARSE_LTUPLE case. Only return data in
-	 *	the HANDTPL_PARSE_LTUPLE case.
-	 */
-	if (flags & (HANDTPL_COPY_DONE | HANDTPL_PARSE_LTUPLE)) {
-		uchar_t *cp;
-		cisdata_t tl;
-
-		if ((tl = tp->len) >= (cisdata_t)MIN_LINKTARGET_LENGTH) {
-			cisdata_t *ltm = (cisdata_t *)CISTPL_LINKTARGET_MAGIC;
-			int i;
-
-			RESET_TP(tp);
-
-			/*
-			 * Save the start address of this string in case
-			 *	the tuple turns out to be OK since we
-			 *	need to pass this address to the caller.
-			 */
-			cp = GET_BYTE_ADDR(tp);
-
-			/*
-			 * Check each byte of the tuple body to see if it
-			 *	matches what should be in a valid tuple.
-			 *	Note that we can't assume that this magic
-			 *	pattern is a string and we also only need
-			 *	to be sure that MIN_LINKTARGET_LENGTH bytes
-			 *	match; all bytes following this magic number
-			 *	in this tuple are ignored.
-			 */
-			for (i = 0; i < MIN_LINKTARGET_LENGTH; i++) {
-				if (GET_BYTE(tp) != *ltm++) {
-					tp->flags |= CISTPLF_PARAMS_INVALID;
-					return (HANDTPL_ERROR);
-				}
-			} /* MIN_LINKTARGET_LENGTH */
-
-			/*
-			 * This tuple is valid.
-			 */
-			if (flags & HANDTPL_COPY_DONE)
-				tp->flags |= CISTPLF_VALID;
-
-			/*
-			 * If we're also parsing this tuple, then
-			 *	setup the return values.
-			 */
-			if (flags & HANDTPL_PARSE_LTUPLE) {
-				cistpl_linktarget_t *cs =
-						(cistpl_linktarget_t *)arg;
-
-				cs->length = tl;
-				(void) strncpy(cs->tpltg_tag, (char *)cp,
-								cs->length);
-				cs->tpltg_tag[cs->length] = NULL;
-
-			} /* HANDTPL_PARSE_LTUPLE */
-
-		} else {
-
-			tp->flags |= CISTPLF_LINK_INVALID;
-			return (HANDTPL_ERROR);
-
-		} /* CISTPL_LINKTARGET */
-
-	} /* (HANDTPL_COPY_DONE | HANDTPL_PARSE_LTUPLE) */
-
-	return (CISTPLF_NOERROR);
-}
-
-/*
- * cistpl_longlink_ac_handler - handler for CISTPL_LONGLINK_A and
- *				CISTPL_LONGLINK_C tuples
- *
- *	void *arg - points to a cistpl_longlink_ac_t * where the
- *			information is stuffed into
- *
- *	If the passed in tuple is CISTPL_LONGLINK_A the CISTPL_LONGLINK_AC_AM
- *		flag in cistpl_longlink_ac_t->flags is set.
- *	If the passed in tuple is CISTPL_LONGLINK_C the CISTPL_LONGLINK_AC_CM
- *		flag in cistpl_longlink_ac_t->flags is set.
- *
- *	If HANDTPL_COPY_DONE is set, we just validate the tuple but
- *		do not return any values.
- *	If HANDTPL_PARSE_LTUPLE is set, we validate the tuple and
- *		return the parsed tuple data if the tuple is valid.
- *
- *	If the tuple link field is invalid, the CISTPLF_LINK_INVALID flag
- *		will be set in the tp->flags field and HANDTPL_ERROR
- *		will be returned.
- *
- *	The tuple is considered invalid if it's link field is less than
- *		MIN_LONGLINK_AC_LENGTH.
- */
-uint32_t
-cistpl_longlink_ac_handler(cistpl_callout_t *co, cistpl_t *tp, uint32_t flags,
-								void *arg)
-{
-	/*
-	 * nothing special about our flags, so just call the
-	 *	generic handler for this
-	 */
-	if (flags & HANDTPL_SET_FLAGS)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	/*
-	 * Validate the tuple for both the HANDTPL_COPY_DONE case and
-	 *	the HANDTPL_PARSE_LTUPLE case. Only return data in
-	 *	the HANDTPL_PARSE_LTUPLE case.
-	 */
-	if (flags & (HANDTPL_COPY_DONE | HANDTPL_PARSE_LTUPLE)) {
-
-		if (tp->len >= (cisdata_t)MIN_LONGLINK_AC_LENGTH) {
-
-			/*
-			 * This tuple is valid.
-			 */
-			if (flags & HANDTPL_COPY_DONE)
-				tp->flags |= CISTPLF_VALID;
-
-			if (flags & HANDTPL_PARSE_LTUPLE) {
-				cistpl_longlink_ac_t *cs =
-						(cistpl_longlink_ac_t *)arg;
-
-				switch (tp->type) {
-				    case CISTPL_LONGLINK_A:
-					cs->flags = CISTPL_LONGLINK_AC_AM;
-					break;
-
-				    case CISTPL_LONGLINK_C:
-					cs->flags = CISTPL_LONGLINK_AC_CM;
-					break;
-				    default:
-					break;
-				} /* switch */
-
-				RESET_TP(tp);
-
-				cs->tpll_addr = GET_LONG(tp);
-
-			} /* HANDTPL_PARSE_LTUPLE */
-
-		} else {
-			tp->flags |= CISTPLF_LINK_INVALID;
-			return (HANDTPL_ERROR);
-		} /* MIN_LONGLINK_AC_LENGTH */
-
-	} /* (HANDTPL_COPY_DONE | HANDTPL_PARSE_LTUPLE) */
-
-	return (CISTPLF_NOERROR);
-}
-
-/*
- * cistpl_longlink_mfc_handler - handler for CISTPL_LONGLINK_MFC tuples
- *
- *	void *arg - points to a cistpl_longlink_mfc_t * where the
- *			information is stuffed into
- *
- *	If HANDTPL_COPY_DONE is set, we just validate the tuple but
- *		do not return any values.
- *	If HANDTPL_PARSE_LTUPLE is set, we validate the tuple and
- *		return the parsed tuple data if the tuple is valid.
- *
- *	If the tuple link field is invalid, the CISTPLF_LINK_INVALID flag
- *		will be set in the tp->flags field and HANDTPL_ERROR
- *		will be returned.
- *
- *	If the number of register sets is invalid, the CISTPLF_PARAMS_INVALID
- *		flag be set in the tp->flags field and HANDTPL_ERROR will be
- *		returned.
- *
- *	The tuple is considered invalid if it's link field is less than
- *		MIN_LONGLINK_MFC_LENGTH or if the number of register sets
- *		is not in the range [MIN_LONGLINK_MFC_NREGS..CIS_MAX_FUNCTIONS]
- */
-uint32_t
-cistpl_longlink_mfc_handler(cistpl_callout_t *co, cistpl_t *tp,
-					uint32_t flags, void *arg)
-{
-	/*
-	 * nothing special about our flags, so just call the
-	 *	generic handler for this
-	 */
-	if (flags & HANDTPL_SET_FLAGS)
-		return (cis_no_tuple_handler(co, tp, flags, arg));
-
-	/*
-	 * Validate the tuple for both the HANDTPL_COPY_DONE case and
-	 *	the HANDTPL_PARSE_LTUPLE case. Only return data in
-	 *	the HANDTPL_PARSE_LTUPLE case.
-	 */
-	if (flags & (HANDTPL_COPY_DONE | HANDTPL_PARSE_LTUPLE)) {
-
-		if (tp->len >= (cisdata_t)MIN_LONGLINK_MFC_LENGTH) {
-
-			/*
-			 * This tuple is valid.
-			 */
-			if (flags & HANDTPL_COPY_DONE)
-				tp->flags |= CISTPLF_VALID;
-
-			if (flags & HANDTPL_PARSE_LTUPLE) {
-				cistpl_longlink_mfc_t *cs =
-						(cistpl_longlink_mfc_t *)arg;
-				int fn;
-
-				RESET_TP(tp);
-
-				/*
-				 * Get the number of register sets described
-				 *	by this tuple. The number of register
-				 *	sets must be greter than or equal to
-				 *	MIN_LONGLINK_MFC_NREGS and less than
-				 *	CIS_MAX_FUNCTIONS.
-				 * Note that the number of functions is equal
-				 *	to the number of register sets.
-				 */
-				cs->nregs = GET_BYTE(tp);
-				cs->nfuncs = cs->nregs;
-
-				if ((cs->nregs < MIN_LONGLINK_MFC_NREGS) ||
-					(cs->nregs > CIS_MAX_FUNCTIONS)) {
-				    tp->flags |= CISTPLF_PARAMS_INVALID;
-				    return (HANDTPL_ERROR);
-				}
-
-				/*
-				 * Cycle through each function and setup
-				 *	the appropriate parameter values.
-				 */
-				for (fn = 0; fn < cs->nregs; fn++) {
-				    cs->function[fn].tas = GET_BYTE(tp);
-				    cs->function[fn].addr = GET_LONG(tp);
-				} /* for (fn) */
-
-			} /* HANDTPL_PARSE_LTUPLE */
-
-		} else {
-			tp->flags |= CISTPLF_LINK_INVALID;
-			return (HANDTPL_ERROR);
-		} /* MIN_LONGLINK_MFC_LENGTH */
-
-	} /* (HANDTPL_COPY_DONE | HANDTPL_PARSE_LTUPLE) */
-
-	return (CISTPLF_NOERROR);
-}
-
-/*
- * cis_validate_longlink_acm - Validates the secondary tuple chain pointed
- *				to by cisptr and specified by a previous
- *				CISTPL_LONGLINK_A, CISTPL_LONGLINK_C or
- *				CISTPL_LONGLINK_MFC tuple.
- *
- *	cisptr->offset must be the offset to the first byte in the secondary
- *		tuple chain to validate
- *	cisptr->flags must be setup to specify the correct address space
- *
- * The cisptr->offset member is not updated after this function returns.
- *
- *	BAD_CIS_ADDR is returned is the raw CIS data cound not be read.
- *	HANDTPL_ERROR is returned if the secondary tuple chain does not
- *		contain a valid CISTPL_LINKTARGET tuple.
- */
-uint32_t
-cis_validate_longlink_acm(cisptr_t *cisptr)
-{
-	uchar_t cb[MIN_LINKTARGET_LENGTH + LINKTARGET_AC_HEADER_LENGTH];
-	cisptr_t t_cisptr, *cpt;
-	int tl;
-
-	/*
-	 * Since the NEXT_CIS_ADDR macro increments the cisptr_t->offset
-	 *	member, make a local copy of the cisptr and use the local
-	 *	copy to read data from the card.
-	 */
-	cpt = &t_cisptr;
-	bcopy((caddr_t)cisptr, (caddr_t)cpt, sizeof (cisptr_t));
-
-	for (tl = 0; tl < MIN_LINKTARGET_LENGTH +
-					LINKTARGET_AC_HEADER_LENGTH; tl++) {
-
-		cb[tl] = GET_CIS_DATA(cpt);
-		if (!NEXT_CIS_ADDR(cpt))
-			return ((uint32_t)BAD_CIS_ADDR);
-
-	} /* for */
-
-	if ((cb[0] == CISTPL_LINKTARGET) && (cb[1] >= MIN_LINKTARGET_LENGTH)) {
-		cisdata_t *ltm = (cisdata_t *)CISTPL_LINKTARGET_MAGIC;
-
-		for (tl = 0; tl < MIN_LINKTARGET_LENGTH; tl++, ltm++) {
-			if (cb[tl + LINKTARGET_AC_HEADER_LENGTH] != *ltm)
-				return (HANDTPL_ERROR);
-		}
-		return (CISTPLF_NOERROR);
-
-	} /* if */
-
-	return (HANDTPL_ERROR);
-}
-
-/*
- * cis_getstr (tp)
- *	we want the address of the first character returned
- *	but need to skip past the string in the cistpl_t structure
- */
-char *
-cis_getstr(cistpl_t *tp)
-{
-	uchar_t *cp, *cpp;
-	uchar_t x;
-
-	cp = tp->read.byte;
-	cpp = cp;
-
-	while ((x = LOOK_BYTE(tp)) != 0 && x != 0xff) {
-		x = GET_BYTE(tp);
-	}
-
-	(void) GET_BYTE(tp);	/* get past that last byte */
-
-	while ((*cpp != 0) && (*cpp != 0xff))
-	    cpp++;
-
-	*cpp = NULL;
-
-	return ((char *)cp);
-}
-
-/*
- * cis_return_name - returns name of tuple
- *
- *    calling:	co - pointer to cistpl_callout_t entry that contains
- *			tuple name to return
- *		gtn - pointer to cistpl_get_tuple_name_t to return
- *			name into
- */
-static void
-cis_return_name(cistpl_callout_t *co, cistpl_get_tuple_name_t *gtn)
-{
-	(void) strncpy(gtn->name, co->text, CIS_MAX_TUPLE_NAME_LEN);
-	gtn->name[CIS_MAX_TUPLE_NAME_LEN - 1] = NULL;
-}
-
-/*
- * cis_malloc/cis_free
- *	wrappers around kmem_alloc()/kmem_free() that
- *	provide malloc/free style usage
- */
-
-caddr_t
-cis_malloc(size_t len)
-{
-	caddr_t addr;
-
-	addr = kmem_zalloc(len + sizeof (size_t), KM_SLEEP);
-	*(size_t *)addr = len + sizeof (size_t);
-	addr += sizeof (size_t);
-	return (addr);
-}
-
-void
-cis_free(caddr_t addr)
-{
-	size_t len;
-	addr -= sizeof (size_t);
-	len = *(size_t *)addr;
-	kmem_free(addr, len);
-}
