/*
* 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
* 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/autoconf.h>
#include <sys/ddi_impldefs.h>
/*
* Function prototypes
*/
/*
* Fetch data functions.
*/
{
} else {
}
return (result);
}
{
} else {
}
return (result);
}
{
return (result);
}
{
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.
*/
{
/*
* Check to see if this is a vendor-specific tuple.
*/
/*
* 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.
*/
if (flags & HANDTPL_RETURN_NAME) {
return (CISTPLF_NOERROR);
} else {
} /* 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) {
return (CISTPLF_NOERROR);
}
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*/
{
if (flags & HANDTPL_SET_FLAGS) {
}
if (flags & HANDTPL_COPY_DONE)
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*/
{
if (flags & HANDTPL_SET_FLAGS) {
return (CISTPLF_NOERROR);
}
if (flags & HANDTPL_COPY_DONE) {
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
*/
{
/*
* nothing special about our flags, so just call the
* generic handler for this
*/
if (flags & HANDTPL_SET_FLAGS)
/*
* We don't currently validate this tuple. This call will
* always set tp->flags |= CISTPLF_VALID.
*/
if (flags & HANDTPL_COPY_DONE)
if (flags & HANDTPL_PARSE_LTUPLE) {
/* CSTYLED */
} /* 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
*/
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 */
};
{
/*
* nothing special about our flags, so just call the
* generic handler for this
*/
if (flags & HANDTPL_SET_FLAGS)
/*
* We don't currently validate this tuple. This call will
* always set tp->flags |= CISTPLF_VALID.
*/
if (flags & HANDTPL_COPY_DONE)
if (flags & HANDTPL_PARSE_LTUPLE) {
int crn = 0;
/* 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.
*/
n = na;
while (n--)
/*
* 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.
*/
n = nrb;
while (n--) {
for (i = 0; i < 8; i++, crn++) {
if (crn < (sizeof (config_regs_present_map)/
sizeof (uint32_t)))
} /* LOOK_BYTE */
hr++;
} /* for */
} /* 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
*/
{
/*
* nothing special about our flags, so just call the
* generic handler for this
*/
if (flags & HANDTPL_SET_FLAGS)
/*
* We don't currently validate this tuple. This call will
* always set tp->flags |= CISTPLF_VALID.
*/
if (flags & HANDTPL_COPY_DONE)
if (flags & HANDTPL_PARSE_LTUPLE) {
/*
* 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
*/
/*
* 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.
*/
} else {
}
/*
* Convert the speed in nS to a device speed code.
* XXX - should check return code from cis_convert_devspeed()
*/
(void) cis_convert_devspeed(&convert_speed);
if (dev_id & 8)
/*
* 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.
*/
/*
* XXX - what about the device_size byte? Is the spec wrong?
*/
/* check for end of list */
(void) cis_convert_devsize(&convert_size);
}
}
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[];
{
int i, j;
/*
* nothing special about our flags, so just call the
* generic handler for this
*/
if (flags & HANDTPL_SET_FLAGS)
/*
* We don't currently validate this tuple. This call will
* always set tp->flags |= CISTPLF_VALID.
*/
if (flags & HANDTPL_COPY_DONE)
if (flags & HANDTPL_PARSE_LTUPLE) {
/*
* 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.
*/
}
/*
* Return the configuration index to the caller, and set the
* default configuration flag if this is a default
* configuration.
*/
/*
* Feature selection flags.
*/
/*
* 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) {
switch (tpce_fs & CISTPL_CFTABLE_TPCE_FS_PWRM) {
/* FALLTHROUGH */
/* FALLTHROUGH */
} /* switch */
} /* if (CISTPL_CFTABLE_TPCE_FS_PWRM) */
/*
* Set up the global memory information flag.
*/
/*
* Parse the various power description structures.
*/
/*
* Collect any Vcc information.
*/
}
/*
* Collect any Vpp1 information.
*/
}
/*
* Collect any Vpp2 information.
*/
}
} /* 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) {
/*
* 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.
*/
(void) cis_convert_devspeed(&convert_speed);
}
(void) cis_convert_devspeed(&convert_speed);
}
(void) cis_convert_devspeed(&convert_speed);
}
} /* 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) {
/*
* Pass any I/O flags that are in the tuple directly
* to the caller.
*/
/*
* If there are any ranges, extract the number of
* ranges and the range descriptions.
*/
if (tpce_io & CISTPL_CFTABLE_TPCE_FS_IO_RANGEM) {
/*
* 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.
*/
/*
* Cycle through each I/O range.
*/
for (i = 0; i < (int)nr; i++) {
/*
* 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 <
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 <
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) {
/*
* Pass any IRQ flags that are in the tuple directly
* to the caller.
*/
/*
* Check for and parse the extended IRQ bitmask
* if it exists.
*/
if (tpce_ir & CISTPL_CFTABLE_TPCE_FS_IRQ_MASKM) {
} else {
}
} /* if (CISTPL_CFTABLE_TPCE_FS_IRQM) */
/*
* Parse any memory information.
*
* XXX - should be a cleaner way to parse this information.
*/
/*
* Switch on the type of memory description
* information that is available.
*/
switch (tpce_fs & CISTPL_CFTABLE_TPCE_FS_MEMM) {
/*
* variable length memory space description
*/
/* memory space descriptor */
1)) + 1);
/*
* If there's host address information, let
* the caller know.
*/
/*
* Cycle through each window space description
* and collect all the interesting bits.
*/
/*
* 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 <
/*
* 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 <
/*
* If there's a host address
* description, grab that
* as well.
*/
/*
* 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 <
j++)
} else {
/*
* No host address information,
* so the host address is
* equal to the card
* address.
*/
}
} /* for (i<mem->windows) */
break;
/*
* single length and card base address specified
*/
/*
* Construct the size of the window.
*/
/*
* Construct the card base address.
*/
/*
* In this mode, both the host base address
* and the card base address are equal.
*/
break;
/*
* single length specified
*/
/*
* Construct the size of the window.
*/
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) {
do {
if (mb) {
mb--;
}
/*
* 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.
*/
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
#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
{
/* nominal supply voltage */
if (pdesc & CISTPL_CFTABLE_PD_NOMV) {
}
/* minimum supply voltage */
if (pdesc & CISTPL_CFTABLE_PD_MINV) {
}
/* maximum supply voltage */
if (pdesc & CISTPL_CFTABLE_PD_MAXV) {
}
/* continuous supply current */
if (pdesc & CISTPL_CFTABLE_PD_STATICI) {
}
/* maximum current required averaged over 1 second */
if (pdesc & CISTPL_CFTABLE_PD_AVGI) {
}
/* maximum current required averaged over 10mS */
if (pdesc & CISTPL_CFTABLE_PD_PEAKI) {
}
/* power down supply curent required */
if (pdesc & CISTPL_CFTABLE_PD_PDOWNI) {
}
}
/*
* 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
* 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;
{
/*
* Get the power description parameter byte and break it up
* into mantissa and exponent.
*/
if (pdesc & CISTPL_EXT_BIT) {
do {
}
/*
* If we have to multiply the power value by ten, then just
* don't bother dividing.
*/
if (! (*flags & CISTPL_CFTABLE_PD_MUL10))
/*
* If we need to add some digits to the right of the decimal, do
* that here.
*/
if (exponent)
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.
*/
{
switch (flags) {
case CISTPL_DEVSPEED_TABLE:
break;
case CISTPL_DEVSPEED_EXT:
do {
first = 1;
if (first) {
/*
* XXX - ugh! we don't understand additional
* exspeed bytes
*/
first = 0;
while (spindex--)
scale *= 10;
} /* if (first) */
} while (exspeed & CISTPL_EXT_BIT);
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
*/
{
/*
* nothing special about our flags, so just call the
* generic handler for this
*/
if (flags & HANDTPL_SET_FLAGS)
/*
* We don't currently validate this tuple. This call will
* always set tp->flags |= CISTPLF_VALID.
*/
if (flags & HANDTPL_COPY_DONE)
if (flags & HANDTPL_PARSE_LTUPLE) {
else
}
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
*/
{
/*
* nothing special about our flags, so just call the
* generic handler for this
*/
if (flags & HANDTPL_SET_FLAGS)
/*
* We don't currently validate this tuple. This call will
* always set tp->flags |= CISTPLF_VALID.
*/
if (flags & HANDTPL_COPY_DONE)
if (flags & HANDTPL_PARSE_LTUPLE) {
int nid;
}
}
return (CISTPLF_NOERROR);
}
/*
* cistpl_format_handler - handler for the CISTPL_FORMAT and
* CISTPL_FORMAT_A tuples
*/
{
/*
* nothing special about our flags, so just call the
* generic handler for this
*/
if (flags & HANDTPL_SET_FLAGS)
/*
* We don't currently validate this tuple. This call will
* always set tp->flags |= CISTPLF_VALID.
*/
if (flags & HANDTPL_COPY_DONE)
if (flags & HANDTPL_PARSE_LTUPLE) {
case TPLFMTTYPE_DISK:
break;
case TPLFMTTYPE_MEM:
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
*/
void *arg)
{
/*
* nothing special about our flags, so just call the
* generic handler for this
*/
if (flags & HANDTPL_SET_FLAGS)
/*
* We don't currently validate this tuple. This call will
* always set tp->flags |= CISTPLF_VALID.
*/
if (flags & HANDTPL_COPY_DONE)
if (flags & HANDTPL_PARSE_LTUPLE) {
}
return (CISTPLF_NOERROR);
}
/*
* cistpl_byteorder_handler - handler for the CISTPL_BYTEORDER tuple
*
* void *arg - points to a XXX where the information is stuffed into
*/
void *arg)
{
/*
* nothing special about our flags, so just call the
* generic handler for this
*/
if (flags & HANDTPL_SET_FLAGS)
/*
* We don't currently validate this tuple. This call will
* always set tp->flags |= CISTPLF_VALID.
*/
if (flags & HANDTPL_COPY_DONE)
if (flags & HANDTPL_PARSE_LTUPLE) {
}
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
*/
{
/*
* nothing special about our flags, so just call the
* generic handler for this
*/
if (flags & HANDTPL_SET_FLAGS)
/*
* We don't currently validate this tuple. This call will
* always set tp->flags |= CISTPLF_VALID.
*/
if (flags & HANDTPL_COPY_DONE)
if (flags & HANDTPL_PARSE_LTUPLE) {
}
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
*/
{
/*
* nothing special about our flags, so just call the
* generic handler for this
*/
if (flags & HANDTPL_SET_FLAGS)
/*
* We don't currently validate this tuple. This call will
* always set tp->flags |= CISTPLF_VALID.
*/
if (flags & HANDTPL_COPY_DONE)
if (flags & HANDTPL_PARSE_LTUPLE) {
}
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
*/
{
/*
* nothing special about our flags, so just call the
* generic handler for this
*/
if (flags & HANDTPL_SET_FLAGS)
/*
* We don't currently validate this tuple. This call will
* always set tp->flags |= CISTPLF_VALID.
*/
if (flags & HANDTPL_COPY_DONE)
if (flags & HANDTPL_PARSE_LTUPLE) {
}
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
*/
{
/*
* nothing special about our flags, so just call the
* generic handler for this
*/
if (flags & HANDTPL_SET_FLAGS)
/*
* We don't currently validate this tuple. This call will
* always set tp->flags |= CISTPLF_VALID.
*/
if (flags & HANDTPL_COPY_DONE)
if (flags & HANDTPL_PARSE_LTUPLE) {
}
return (CISTPLF_NOERROR);
}
/*
* cistpl_funcid_handler - handler for CISTPL_FUNCID
*
* void *arg - points to a XXX where the information is stuffed into
*/
{
/*
* nothing special about our flags, so just call the
* generic handler for this
*/
if (flags & HANDTPL_SET_FLAGS)
/*
* We don't currently validate this tuple. This call will
* always set tp->flags |= CISTPLF_VALID.
*/
if (flags & HANDTPL_COPY_DONE)
if (flags & HANDTPL_PARSE_LTUPLE) {
}
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
*/
{
int subfunction;
/*
* nothing special about our flags, so just call the
* generic handler for this
*/
if (flags & HANDTPL_SET_FLAGS)
/*
* We don't currently validate this tuple. This call will
* always set tp->flags |= CISTPLF_VALID.
*/
if (flags & HANDTPL_COPY_DONE)
if (flags & HANDTPL_PARSE_LTUPLE) {
switch (subfunction & 0xF) {
case TPLFE_SUB_SERIAL:
case TPLFE_CAP_SERIAL_DATA:
case TPLFE_CAP_SERIAL_FAX:
case TPLFE_CAP_SERIAL_VOICE:
break;
case TPLFE_SUB_MODEM_COMMON:
case TPLFE_CAP_MODEM_DATA:
case TPLFE_CAP_MODEM_FAX:
case TPLFE_CAP_MODEM_VOICE:
break;
case TPLFE_SUB_MODEM_DATA:
} else {
break;
}
break;
case TPLFE_SUB_MODEM_FAX:
} else {
break;
}
break;
case TPLFE_SUB_VOICE:
}
}
}
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
*/
void *arg)
{
int subfunction;
/*
* nothing special about our flags, so just call the
* generic handler for this
*/
if (flags & HANDTPL_SET_FLAGS)
/*
* We don't currently validate this tuple. This call will
* always set tp->flags |= CISTPLF_VALID.
*/
if (flags & HANDTPL_COPY_DONE)
if (flags & HANDTPL_PARSE_LTUPLE) {
int i;
switch (subfunction) {
case TPLFE_NETWORK_INFO:
if (i < 24) {
} 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
*/
}
}
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.
*/
void *arg)
{
/*
* nothing special about our flags, so just call the
* generic handler for this
*/
if (flags & HANDTPL_SET_FLAGS)
/*
* 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.
*/
int i;
/*
* 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.
*/
/*
* 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++) {
return (HANDTPL_ERROR);
}
} /* MIN_LINKTARGET_LENGTH */
/*
* This tuple is valid.
*/
if (flags & HANDTPL_COPY_DONE)
/*
* If we're also parsing this tuple, then
* setup the return values.
*/
if (flags & HANDTPL_PARSE_LTUPLE) {
} /* HANDTPL_PARSE_LTUPLE */
} else {
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.
*/
void *arg)
{
/*
* nothing special about our flags, so just call the
* generic handler for this
*/
if (flags & HANDTPL_SET_FLAGS)
/*
* 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.
*/
/*
* This tuple is valid.
*/
if (flags & HANDTPL_COPY_DONE)
if (flags & HANDTPL_PARSE_LTUPLE) {
case CISTPL_LONGLINK_A:
break;
case CISTPL_LONGLINK_C:
break;
default:
break;
} /* switch */
} /* HANDTPL_PARSE_LTUPLE */
} else {
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]
*/
{
/*
* nothing special about our flags, so just call the
* generic handler for this
*/
if (flags & HANDTPL_SET_FLAGS)
/*
* 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.
*/
/*
* This tuple is valid.
*/
if (flags & HANDTPL_COPY_DONE)
if (flags & HANDTPL_PARSE_LTUPLE) {
int fn;
/*
* 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.
*/
return (HANDTPL_ERROR);
}
/*
* Cycle through each function and setup
* the appropriate parameter values.
*/
} /* for (fn) */
} /* HANDTPL_PARSE_LTUPLE */
} else {
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.
*/
{
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.
*/
if (!NEXT_CIS_ADDR(cpt))
return ((uint32_t)BAD_CIS_ADDR);
} /* for */
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 *
{
uchar_t x;
}
cpp++;
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
{
}
/*
* wrappers around kmem_alloc()/kmem_free() that
*/
{
return (addr);
}
void
{
}