master_ops.c revision aa2aa9a662539940ddbc8610da5a3a874ebd7503
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (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 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <sys/kobj_lex.h>
#define masterfile "/boot/solaris/devicedb/master"
/*
* Internal definitions
*/
typedef enum {
MF_UNEXPECTED = -1,
} mftoken_t;
typedef enum {
} mfparse_t;
{
}
void
{
kmem_free(d, sizeof (device_id_t));
}
static property_t *
{
}
static void
{
kmem_free(p, sizeof (property_t));
}
static master_rec_t *
{
}
static void
{
device_id_t *d;
property_t *p;
if (m->description != NULL)
strfree(m->description);
d = m->device_ids;
while (d != NULL) {
d = next;
}
p = m->properties;
while (p != NULL) {
mf_free_property(p);
p = next;
}
kmem_free(m, sizeof (master_rec_t));
}
void
{
master_rec_t *m;
m = master_list;
while (m != NULL) {
m = next;
}
master_list = NULL;
}
/*
* Unfortunately, kobj_lex() is too sophisticated for our needs
*/
static mftoken_t
{
char *cp;
if (size < 2)
return (token); /* MF_UNEXPECTED */
/* skip leading whitespace */
;
/* strip comments */
if (ch == '#') {
ch != -1)
;
}
switch (ch) {
case -1:
break;
case '\n':
case '\r':
token = MF_NEWLINE;
break;
case '=':
break;
case '|':
break;
case '"':
remain++;
cp--;
badquote = 0;
switch (ch) {
case '\n':
case -1:
*cp++ = '\n';
badquote = 1;
(void) kobj_ungetc(file);
break;
default:
if (--remain == 0) {
goto out;
}
break;
}
}
break;
default:
do {
if (--remain == 0) {
break;
}
/* if terminating character, break out */
(ch == '|')) {
(void) kobj_ungetc(file);
remain++;
cp--;
break;
}
} while (token != MF_UNEXPECTED);
break;
}
out:
*cp = '\0';
return (token);
}
static master_rec_t *
{
master_rec_t *m = NULL;
device_id_t *d = NULL;
property_t *p = NULL;
char tokval[MAXPATHLEN];
switch (parse_state) {
case MF_INIT:
m = mf_alloc_master_rec();
/*FALLTHROUGH*/
case MF_DEVID:
d = mf_alloc_device_id();
d->next = m->device_ids;
m->device_ids = d;
} else if (token != MF_NEWLINE)
break;
case MF_NAME:
} else
break;
case MF_DEVTYPE:
/* device_type not used */
} else if (token == MF_NEWLINE) {
/* version line ignored */
} else
break;
case MF_BUSTYPE:
/* bus_type ignored */
} else
break;
case MF_BEFNAME:
/* realmode driver name ignored */
} else
break;
case MF_DESCRIPTION:
} else
break;
case MF_PROPNAME:
p = mf_alloc_property();
} else if (token == MF_NEWLINE) {
} else
break;
case MF_PROPASSIGN:
} else
break;
case MF_PROPVAL:
p->next = m->properties;
/* delete properties which begin with '$' */
if (*p->name == '$') {
mf_free_property(p);
} else
m->properties = p;
p = NULL;
} else
break;
case MF_VERSION_DONE:
case MF_VALID_DONE:
case MF_ERROR_DONE:
/* terminating states handled outside switch() */
break;
}
if (parse_state == MF_VERSION_DONE) {
/* ignore version line */
} else if (parse_state == MF_VALID_DONE) {
/* valid line */
break;
} else if (parse_state == MF_ERROR_DONE) {
if (p != NULL)
mf_free_property(p);
/*
* Error in master file. Should never happen
* since master file is not user-edited. Eat rest
* of line to attempt error recovery
*/
continue;
}
}
return (m);
}
void
{
master_rec_t *m;
return;
}
m->next = master_list;
master_list = m;
}
}
/*
* Return the first master file record found matching pnpid list
*/
const master_rec_t *
{
master_rec_t *m;
device_id_t *d;
m = master_list;
while (m != NULL) {
d = m->device_ids;
while (d != NULL) {
return (m);
d = d->next;
}
m = m->next;
}
}
return (NULL);
}