added pack_cis from pcmcia-cs-3.2.8, untested
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14740 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -4,4 +4,12 @@ StdBinCommands
|
||||
cardctl.c
|
||||
dump_cis.c
|
||||
dump_cisreg.c
|
||||
: libroot.so ;
|
||||
: root ;
|
||||
|
||||
BinCommand pack_cis :
|
||||
pack_cis.c
|
||||
lex_cis.l
|
||||
yacc_cis.y
|
||||
;
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,234 @@
|
||||
/* Special state for handling include files */
|
||||
%x src
|
||||
|
||||
%{
|
||||
/*
|
||||
* lex_cis.l 1.15 2001/08/24 12:21:41
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License
|
||||
* at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* The initial developer of the original code is David A. Hinds
|
||||
* <[email protected]>. Portions created by David A. Hinds
|
||||
* are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License version 2 (the "GPL"), in
|
||||
* which case the provisions of the GPL are applicable instead of the
|
||||
* above. If you wish to allow the use of your version of this file
|
||||
* only under the terms of the GPL and not to allow others to use
|
||||
* your version of this file under the MPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice and
|
||||
* other provisions required by the GPL. If you do not delete the
|
||||
* provisions above, a recipient may use your version of this file
|
||||
* under either the MPL or the GPL.
|
||||
*/
|
||||
|
||||
#undef src
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#define src 1
|
||||
|
||||
#include <pcmcia/cs_types.h>
|
||||
#include <pcmcia/cistpl.h>
|
||||
|
||||
#include "pack_cis.h"
|
||||
#include "yacc_cis.h"
|
||||
|
||||
/* For assembling nice error messages */
|
||||
int current_lineno;
|
||||
|
||||
static int lex_number(char *);
|
||||
static int lex_units(char *, int, int);
|
||||
static int lex_float(char *);
|
||||
static int lex_string(char *);
|
||||
|
||||
%}
|
||||
|
||||
int [0-9]+
|
||||
hex 0x[0-9a-fA-F]+
|
||||
flt [0-9]+\.[0-9]*
|
||||
str \"([^"]|\\.)*\"
|
||||
|
||||
%%
|
||||
|
||||
\n current_lineno++;
|
||||
[ \t]* /* skip */ ;
|
||||
[ ]*[#;].* /* skip */ ;
|
||||
|
||||
funcid return FUNCID;
|
||||
mfc return MFC;
|
||||
manfid return MANFID;
|
||||
vers_1 return VERS_1;
|
||||
checksum return CHECKSUM;
|
||||
|
||||
common_jedec return CJEDEC;
|
||||
attr_jedec return AJEDEC;
|
||||
|
||||
dev_info return DEV_INFO;
|
||||
attr_dev_info return ATTR_DEV_INFO;
|
||||
no_info return NO_INFO;
|
||||
NULL return lex_number("0");
|
||||
ROM return lex_number("1");
|
||||
EPROM return lex_number("3");
|
||||
EEPROM return lex_number("4");
|
||||
FLASH return lex_number("5");
|
||||
SRAM return lex_number("6");
|
||||
DRAM return lex_number("7");
|
||||
fn_specific return lex_number("13");
|
||||
|
||||
config return CONFIG;
|
||||
base return BASE;
|
||||
mask return MASK;
|
||||
last_index return LAST_INDEX;
|
||||
\[post\] return POST;
|
||||
\[rom\] return ROM;
|
||||
|
||||
cftable_entry return CFTABLE;
|
||||
\[default\] return DEFAULT;
|
||||
\[bvd\] return BVD;
|
||||
\[wp\] return WP;
|
||||
\[rdybsy\] return RDYBSY;
|
||||
\[mwait\] return MWAIT;
|
||||
\[audio\] return AUDIO;
|
||||
\[readonly\] return READONLY;
|
||||
\[pwrdown\] return PWRDOWN;
|
||||
|
||||
Vcc return VCC;
|
||||
Vpp1 return VPP1;
|
||||
Vpp2 return VPP2;
|
||||
Vnom return VNOM;
|
||||
Vmin return VMIN;
|
||||
Vmax return VMAX;
|
||||
Istatic return ISTATIC;
|
||||
Iavg return IAVG;
|
||||
Ipeak return IPEAK;
|
||||
Idown return IDOWN;
|
||||
|
||||
io return IO;
|
||||
memory return MEM;
|
||||
\[8bit\] return BIT8;
|
||||
\[16bit\] return BIT16;
|
||||
\[lines return LINES;
|
||||
\[range\] return RANGE;
|
||||
|
||||
irq return IRQ_NO;
|
||||
\[level\] return LEVEL;
|
||||
\[pulse\] return PULSE;
|
||||
\[shared\] return SHARED;
|
||||
|
||||
timing return TIMING;
|
||||
wait return WAIT;
|
||||
ready return READY;
|
||||
reserved return RESERVED;
|
||||
|
||||
multi_function return lex_number("0");
|
||||
memory_card return lex_number("1");
|
||||
serial_port return lex_number("2");
|
||||
parallel_port return lex_number("3");
|
||||
fixed_disk return lex_number("4");
|
||||
video_adapter return lex_number("5");
|
||||
network_adapter return lex_number("6");
|
||||
aims_card return lex_number("7");
|
||||
scsi_adapter return lex_number("8");
|
||||
|
||||
{int} return lex_number(yytext);
|
||||
{hex} return lex_number(yytext);
|
||||
|
||||
{int}b return lex_units(yytext, 1, SIZE);
|
||||
{int}kb return lex_units(yytext, 1024, SIZE);
|
||||
{int}mb return lex_units(yytext, 1024*1024, SIZE);
|
||||
|
||||
{flt}s return lex_units(yytext, 1000000000, TIME);
|
||||
{flt}ms return lex_units(yytext, 1000000, TIME);
|
||||
{flt}us return lex_units(yytext, 1000, TIME);
|
||||
{flt}ns return lex_units(yytext, 1, TIME);
|
||||
{int}s return lex_units(yytext, 1000000000, TIME);
|
||||
{int}ms return lex_units(yytext, 1000000, TIME);
|
||||
{int}us return lex_units(yytext, 1000, TIME);
|
||||
{int}ns return lex_units(yytext, 1, TIME);
|
||||
|
||||
{flt}V return lex_units(yytext, 100000, VOLTAGE);
|
||||
{flt}mV return lex_units(yytext, 100, VOLTAGE);
|
||||
{flt}uV return lex_units(yytext, 0.1, VOLTAGE);
|
||||
{int}V return lex_units(yytext, 100000, VOLTAGE);
|
||||
{int}mV return lex_units(yytext, 100, VOLTAGE);
|
||||
{int}uV return lex_units(yytext, 0.1, VOLTAGE);
|
||||
|
||||
{flt}A return lex_units(yytext, 10000000, CURRENT);
|
||||
{flt}mA return lex_units(yytext, 10000, CURRENT);
|
||||
{flt}uA return lex_units(yytext, 10, CURRENT);
|
||||
{int}A return lex_units(yytext, 10000000, CURRENT);
|
||||
{int}mA return lex_units(yytext, 10000, CURRENT);
|
||||
{int}uA return lex_units(yytext, 10, CURRENT);
|
||||
|
||||
{flt} return lex_float(yytext);
|
||||
|
||||
{str} return lex_string(yytext);
|
||||
|
||||
. return yytext[0];
|
||||
|
||||
%%
|
||||
|
||||
#ifndef yywrap
|
||||
int yywrap() { return 1; }
|
||||
#endif
|
||||
|
||||
/*======================================================================
|
||||
|
||||
Stuff to parse basic data types
|
||||
|
||||
======================================================================*/
|
||||
|
||||
static int lex_number(char *s)
|
||||
{
|
||||
yylval.num = strtoul(s, NULL, 0);
|
||||
return NUMBER;
|
||||
}
|
||||
|
||||
static int lex_float(char *s)
|
||||
{
|
||||
yylval.flt = strtod(s, NULL);
|
||||
return FLOAT;
|
||||
}
|
||||
|
||||
static int lex_units(char *s, int scale, int token)
|
||||
{
|
||||
float f;
|
||||
sscanf(s, "%f", &f);
|
||||
yylval.num = scale*f + 0.5;
|
||||
return token;
|
||||
}
|
||||
|
||||
static int lex_string(char *s)
|
||||
{
|
||||
int n = strlen(s);
|
||||
yylval.str = malloc(n-1);
|
||||
strncpy(yylval.str, s+1, n-2);
|
||||
yylval.str[n-2] = '\0';
|
||||
return STRING;
|
||||
}
|
||||
|
||||
/*======================================================================
|
||||
|
||||
The main parser entry point
|
||||
|
||||
======================================================================*/
|
||||
|
||||
void parse_cis(FILE *f)
|
||||
{
|
||||
current_lineno = 1;
|
||||
yyrestart(f);
|
||||
yyparse();
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
.\" Copyright (C) 1998 David A. Hinds -- [email protected]
|
||||
.\" pack_cis.8 1.5 2000/06/12 21:24:49
|
||||
.\"
|
||||
.TH PACK_CIS 8 "2000/06/12 21:24:49" "pcmcia-cs"
|
||||
.SH NAME
|
||||
pack_cis \- compile PCMCIA Card Information Structures
|
||||
.SH SYNOPSIS
|
||||
.B pack_cis
|
||||
.RB [ "\-o\ "\c
|
||||
.I outfile\c
|
||||
]
|
||||
.I infile
|
||||
.SH DESCRIPTION
|
||||
.B Pack_cis
|
||||
is used to convert a text description of a PCMCIA Card
|
||||
Information Structure (CIS) to its packed binary representation. It
|
||||
can parse a reasonably useful subset of the possible output of the
|
||||
.B dump_cis
|
||||
utility. The primary use of
|
||||
.B pack_cis
|
||||
is to construct replacement CIS files
|
||||
for cards that have incomplete, inaccurate, or damaged CIS
|
||||
structures. Thus, the supported tuple types are mostly limited to
|
||||
things that are important for correctly configuring typical IO cards.
|
||||
.PP
|
||||
By default, the packed data is written to standard output.
|
||||
.SH FORMAT
|
||||
The best way to get started writing CIS descriptions will be to use
|
||||
.B dump_cis
|
||||
to extract the CIS data from a card, and to examine the CIS files
|
||||
distributed with the PCMCIA source tree in
|
||||
.IR etc/cis/ .
|
||||
.PP
|
||||
The basic structure of a CIS is a list of tuple descriptions.
|
||||
Anything following a hash mark (``#'') is treated as a comment.
|
||||
A multifunction CIS can be described with the notation:
|
||||
.sp
|
||||
.RS
|
||||
.nf
|
||||
[common tuple list]
|
||||
mfc {
|
||||
[tuple list for function 0]
|
||||
}, {
|
||||
[tuple list for function 1]
|
||||
}
|
||||
.RE
|
||||
.fi
|
||||
.sp
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BI "\-o " outfile
|
||||
Write the packed tuple data to the specified file.
|
||||
.SH FILES
|
||||
.PD 0
|
||||
.TP \w'/etc/pcmcia/cis\ \ \ \|\|'u
|
||||
/etc/pcmcia/cis
|
||||
Standard location for packed CIS files
|
||||
.SH AUTHOR
|
||||
David Hinds \- [email protected]
|
||||
.SH "SEE ALSO"
|
||||
dump_cis(8), cardmgr(8), pcmcia(5).
|
||||
@@ -0,0 +1,447 @@
|
||||
/*======================================================================
|
||||
|
||||
A utility to convert a plain text description of a Card
|
||||
Information Structure into its packed binary representation.
|
||||
|
||||
pack_cis.c 1.20 2002/10/16 16:38:18
|
||||
|
||||
The contents of this file are subject to the Mozilla Public
|
||||
License Version 1.1 (the "License"); you may not use this file
|
||||
except in compliance with the License. You may obtain a copy of
|
||||
the License at http://www.mozilla.org/MPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS
|
||||
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
implied. See the License for the specific language governing
|
||||
rights and limitations under the License.
|
||||
|
||||
The initial developer of the original code is David A. Hinds
|
||||
<[email protected]>. Portions created by David A. Hinds
|
||||
are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
|
||||
|
||||
Alternatively, the contents of this file may be used under the
|
||||
terms of the GNU General Public License version 2 (the "GPL"), in
|
||||
which case the provisions of the GPL are applicable instead of the
|
||||
above. If you wish to allow the use of your version of this file
|
||||
only under the terms of the GPL and not to allow others to use
|
||||
your version of this file under the MPL, indicate your decision
|
||||
by deleting the provisions above and replace them with the notice
|
||||
and other provisions required by the GPL. If you do not delete
|
||||
the provisions above, a recipient may use your version of this
|
||||
file under either the MPL or the GPL.
|
||||
|
||||
Usage:
|
||||
|
||||
pack_cis [-o outfile] [infile]
|
||||
|
||||
[infile] defaults to stdin, and [outfile] defaults to stdout.
|
||||
|
||||
======================================================================*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <pcmcia/cs_types.h>
|
||||
#include <pcmcia/cs.h>
|
||||
#include <pcmcia/cistpl.h>
|
||||
|
||||
#include "pack_cis.h"
|
||||
|
||||
tuple_info_t *cis_root = NULL, *mfc[8] = { NULL };
|
||||
int nf = 0;
|
||||
|
||||
/*======================================================================
|
||||
|
||||
Support routines for packing parts of configuration table entries
|
||||
|
||||
======================================================================*/
|
||||
|
||||
static u_int mantissa[] = {
|
||||
10, 12, 13, 15, 20, 25, 30, 35,
|
||||
40, 45, 50, 55, 60, 70, 80, 90
|
||||
};
|
||||
static int pack_power(cistpl_power_t *pwr, u_char *b)
|
||||
{
|
||||
u_int tmp, i;
|
||||
u_char m, e, x, *c = b;
|
||||
*c = pwr->present; c++;
|
||||
for (i = 0; i < 7; i++) {
|
||||
if (!(pwr->present & (1<<i)))
|
||||
continue;
|
||||
tmp = pwr->param[i];
|
||||
for (e = 1; ((tmp % 10) == 0) || (tmp > 999); e++)
|
||||
tmp /= 10;
|
||||
x = m = 0;
|
||||
if (tmp < 100) {
|
||||
if (tmp < 10) { tmp *= 10; e--; }
|
||||
for (m = 0; m < 16; m++)
|
||||
if (mantissa[m] == tmp) break;
|
||||
if (m == 16) { tmp *= 10; e--; }
|
||||
}
|
||||
if (tmp >= 100) {
|
||||
e++;
|
||||
x = (tmp/10) - ((tmp/10) % 10);
|
||||
for (m = 0; m < 16; m++)
|
||||
if (mantissa[m] == x) break;
|
||||
x = (u_char)(tmp - 10*(u_int)x);
|
||||
}
|
||||
*c = (m<<3) | e | (x ? 0x80 : 0); c++;
|
||||
if (x) { *c = x; c++; }
|
||||
}
|
||||
return c-b;
|
||||
}
|
||||
|
||||
static int pack_io(cistpl_io_t *p, u_char *b)
|
||||
{
|
||||
u_char *c = b;
|
||||
u_int i, j, ml, ma;
|
||||
*c = p->flags & (CISTPL_IO_8BIT|CISTPL_IO_16BIT);
|
||||
if ((p->nwin == 1) && (p->win[0].base == 0)) {
|
||||
for (i = 1, j = 0; i < p->win[0].len; i *= 2, j++) ;
|
||||
*c |= j; c++;
|
||||
} else {
|
||||
for (i = ma = ml = 0; i < p->nwin; i++) {
|
||||
ma |= p->win[i].base;
|
||||
ml |= p->win[i].len-1;
|
||||
}
|
||||
ma = (ma > 0xffff) ? 3 : ((ma > 0xff) ? 2 : 1);
|
||||
ml = (ml > 0xffff) ? 3 : ((ml > 0xff) ? 2 : 1);
|
||||
*c |= 0x80 | (p->flags & CISTPL_IO_LINES_MASK); c++;
|
||||
*c = (p->nwin-1) | (ma<<4) | (ml<<6); c++;
|
||||
if (ma == 3) ma++; if (ml == 3) ml++;
|
||||
for (i = 0; i < p->nwin; i++) {
|
||||
for (j = 0; j < ma; j++) {
|
||||
*c = (p->win[i].base >> (8*j)) & 0xff; c++;
|
||||
}
|
||||
for (j = 0; j < ml; j++) {
|
||||
*c = ((p->win[i].len-1) >> (8*j)) & 0xff; c++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return c-b;
|
||||
}
|
||||
|
||||
static int pack_mem(cistpl_mem_t *p, u_char *b)
|
||||
{
|
||||
u_char *c = b;
|
||||
u_int i, j, ml, ma, ha;
|
||||
for (i = ma = ml = ha = 0; i < p->nwin; i++) {
|
||||
ma |= p->win[i].card_addr;
|
||||
ml |= p->win[i].len;
|
||||
ha |= p->win[i].host_addr;
|
||||
}
|
||||
ma = (ma|ha) >> 8; ml >>= 8;
|
||||
ma = (ma > 0xffff) ? 3 : ((ma > 0xff) ? 2 : 1);
|
||||
ml = (ml > 0xffff) ? 3 : ((ml > 0xff) ? 2 : 1);
|
||||
*c = (p->nwin-1) | (ma<<5) | (ml<<3) | (ha ? 0x80 : 0); c++;
|
||||
for (i = 0; i < p->nwin; i++) {
|
||||
for (j = 1; j <= ml; j++) {
|
||||
*c = (p->win[i].len >> (8*j)) & 0xff; c++;
|
||||
}
|
||||
for (j = 1; j <= ma; j++) {
|
||||
*c = (p->win[i].card_addr >> (8*j)) & 0xff; c++;
|
||||
}
|
||||
if (ha)
|
||||
for (j = 1; j <= ma; j++) {
|
||||
*c = (p->win[i].host_addr >> (8*j)) & 0xff; c++;
|
||||
}
|
||||
}
|
||||
return c-b;
|
||||
}
|
||||
|
||||
static int pack_irq(cistpl_irq_t *p, u_char *b)
|
||||
{
|
||||
b[0] = p->IRQInfo1;
|
||||
if (p->IRQInfo1 & IRQ_INFO2_VALID) {
|
||||
b[1] = p->IRQInfo2 & 0xff;
|
||||
b[2] = (p->IRQInfo2 >> 8) & 0xff;
|
||||
return 3;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void pack_cftable(cistpl_cftable_entry_t *p, u_char *b)
|
||||
{
|
||||
u_char *c;
|
||||
b[2] = p->index | 0x80;
|
||||
if (p->flags & CISTPL_CFTABLE_DEFAULT)
|
||||
b[2] |= 0x40;
|
||||
b[3] = 0x01;
|
||||
b[3] |= (p->flags & CISTPL_CFTABLE_BVDS) ? 0x10 : 0;
|
||||
b[3] |= (p->flags & CISTPL_CFTABLE_WP) ? 0x20 : 0;
|
||||
b[3] |= (p->flags & CISTPL_CFTABLE_RDYBSY) ? 0x40 : 0;
|
||||
b[3] |= (p->flags & CISTPL_CFTABLE_MWAIT) ? 0x80 : 0;
|
||||
b[4] = 0;
|
||||
c = b+5;
|
||||
if (p->vcc.present) {
|
||||
b[4]++; c += pack_power(&p->vcc, c);
|
||||
if (p->vpp1.present) {
|
||||
b[4]++; c += pack_power(&p->vpp1, c);
|
||||
if (p->vpp2.present) {
|
||||
b[4]++; c += pack_power(&p->vpp2, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (p->io.nwin > 0) {
|
||||
b[4] |= 0x08;
|
||||
c += pack_io(&p->io, c);
|
||||
}
|
||||
if (p->irq.IRQInfo1 > 0) {
|
||||
b[4] |= 0x10;
|
||||
c += pack_irq(&p->irq, c);
|
||||
}
|
||||
if (p->mem.nwin > 0) {
|
||||
b[4] |= 0x60;
|
||||
c += pack_mem(&p->mem, c);
|
||||
}
|
||||
if (p->flags >> 8) {
|
||||
b[4] |= 0x80;
|
||||
*c++ = p->flags >> 8;
|
||||
}
|
||||
b[1] = c-b-2;
|
||||
}
|
||||
|
||||
/*======================================================================
|
||||
|
||||
Routines for packing device info tuples
|
||||
|
||||
======================================================================*/
|
||||
|
||||
static int pack_speed(u_int speed, u_char *b)
|
||||
{
|
||||
u_char e, m, *c = b;
|
||||
switch (speed) {
|
||||
case 0: *c |= 0; c++; break;
|
||||
case 250: *c |= 1; c++; break;
|
||||
case 200: *c |= 2; c++; break;
|
||||
case 150: *c |= 3; c++; break;
|
||||
case 100: *c |= 4; c++; break;
|
||||
default:
|
||||
*c |= 7; c++;
|
||||
for (e = 1; speed > 80; e++)
|
||||
speed /= 10;
|
||||
for (m = 0; m < 15; m++)
|
||||
if (mantissa[m] >= speed) break;
|
||||
*c = ((m+1)<<3) | e; c++;
|
||||
}
|
||||
return c-b;
|
||||
}
|
||||
|
||||
static void pack_device(cistpl_device_t *d, u_char *b)
|
||||
{
|
||||
u_int i, sz;
|
||||
u_char e, *c = b+2;
|
||||
for (i = 0; i < d->ndev; i++) {
|
||||
*c = (d->dev[i].type<<4);
|
||||
c += pack_speed(d->dev[i].speed, c);
|
||||
sz = d->dev[i].size/512;
|
||||
for (e = 0; sz > 32; e++)
|
||||
sz /= 4;
|
||||
*c = (e & 7) | ((sz-1) << 3); c++;
|
||||
}
|
||||
*c = 0xff; c++;
|
||||
b[1] = c-b-2;
|
||||
}
|
||||
|
||||
/*======================================================================
|
||||
|
||||
For now, I only implement a subset of tuples types, intended to be
|
||||
enough to handle most IO-oriented cards.
|
||||
|
||||
======================================================================*/
|
||||
|
||||
static int pack_tuple(tuple_info_t *t, u_char *b)
|
||||
{
|
||||
cisparse_t *p = t->parse;
|
||||
u_int i, m;
|
||||
u_char *c;
|
||||
|
||||
*b = t->type;
|
||||
switch (t->type) {
|
||||
case CISTPL_DEVICE:
|
||||
case CISTPL_DEVICE_A:
|
||||
if (p) {
|
||||
pack_device(&p->device, b);
|
||||
} else {
|
||||
/* Fake null device tuple */
|
||||
b[1] = 3; b[2] = 0; b[3] = 0; b[4] = 0xff;
|
||||
}
|
||||
break;
|
||||
case CISTPL_MANFID:
|
||||
b[1] = 4;
|
||||
b[2] = p->manfid.manf & 0xff;
|
||||
b[3] = p->manfid.manf >> 8;
|
||||
b[4] = p->manfid.card & 0xff;
|
||||
b[5] = p->manfid.card >> 8;
|
||||
break;
|
||||
case CISTPL_FUNCID:
|
||||
b[1] = 2;
|
||||
b[2] = p->funcid.func;
|
||||
b[3] = p->funcid.sysinit;
|
||||
break;
|
||||
case CISTPL_JEDEC_C:
|
||||
case CISTPL_JEDEC_A:
|
||||
b[1] = 2*p->jedec.nid;
|
||||
for (i = 0; i < p->jedec.nid; i++) {
|
||||
b[2*i+1] = p->jedec.id[i].mfr;
|
||||
b[2*i+2] = p->jedec.id[i].info;
|
||||
}
|
||||
break;
|
||||
case CISTPL_CONFIG:
|
||||
b[3] = p->config.last_idx;
|
||||
i = p->config.base;
|
||||
for (c = b+4, m = 0; (i > 0) || !m; i >>= 8, m++) {
|
||||
c[m] = i & 0xff;
|
||||
}
|
||||
b[2] = m-1;
|
||||
i = p->config.rmask[0];
|
||||
for (c = c+m, m = 0; (i > 0) || !m; i >>= 8, m++) {
|
||||
c[m] = i & 0xff;
|
||||
}
|
||||
b[2] |= ((m-1) << 2);
|
||||
b[1] = c+m-b-2;
|
||||
break;
|
||||
case CISTPL_VERS_1:
|
||||
b[2] = p->version_1.major;
|
||||
b[3] = p->version_1.minor;
|
||||
c = b+4;
|
||||
for (i = 0; i < p->version_1.ns; i++) {
|
||||
strcpy((char *)c, p->version_1.str+p->version_1.ofs[i]);
|
||||
c += strlen((char *)c) + 1;
|
||||
}
|
||||
for (; i < 4; i++) { *c = 0; c++; }
|
||||
*c = 0xff; c++;
|
||||
b[1] = c-b-2;
|
||||
break;
|
||||
case CISTPL_CFTABLE_ENTRY:
|
||||
pack_cftable(&p->cftable_entry, b);
|
||||
break;
|
||||
case CISTPL_LINKTARGET:
|
||||
b[1] = 3; b[2] = 'C'; b[3] = 'I'; b[4] = 'S';
|
||||
break;
|
||||
case CISTPL_NO_LINK:
|
||||
case CISTPL_END:
|
||||
b[1] = 0;
|
||||
break;
|
||||
}
|
||||
return b[1]+2;
|
||||
}
|
||||
|
||||
/*======================================================================
|
||||
|
||||
The following routines handle parsing of aggregates of tuples.
|
||||
pack_chain() is the simplest: just return a string of tuples and
|
||||
terminate with an END tuple. pack_mfc() is used to tie the
|
||||
function-specific tuple chains for a multifunction card together
|
||||
using a LONGLINK_MFC tuple. And pack_cis() handles a complete
|
||||
CIS, whether it is multifunction or not.
|
||||
|
||||
======================================================================*/
|
||||
|
||||
static int pack_chain(tuple_info_t *t, u_char *b)
|
||||
{
|
||||
int n = 0;
|
||||
tuple_info_t end = { CISTPL_END, NULL, NULL };
|
||||
while (t) {
|
||||
n += pack_tuple(t, b+n);
|
||||
t = t->next;
|
||||
}
|
||||
n += pack_tuple(&end, b+n);
|
||||
return n;
|
||||
}
|
||||
|
||||
static int pack_mfc(u_int ofs, u_char *b)
|
||||
{
|
||||
u_int i, j, pos;
|
||||
tuple_info_t target = { CISTPL_LINKTARGET, NULL, NULL };
|
||||
|
||||
b[0] = CISTPL_LONGLINK_MFC;
|
||||
b[1] = 5*nf + 1;
|
||||
b[2] = nf;
|
||||
b[5*nf+3] = CISTPL_END;
|
||||
b[5*nf+4] = 0;
|
||||
/* Leave space for this tuple and the CISTPL_END tuple */
|
||||
pos = 5*nf+5;
|
||||
for (i = 0; i < nf; i++) {
|
||||
b[3+i*5] = 0;
|
||||
for (j = 0; j < 4; j++)
|
||||
b[4+i*5+j] = ((ofs+pos) >> (8*j)) & 0xff;
|
||||
pos += pack_tuple(&target, b+pos);
|
||||
pos += pack_chain(mfc[i], b+pos);
|
||||
}
|
||||
return ofs+pos;
|
||||
}
|
||||
|
||||
static int pack_cis(tuple_info_t *t, u_char *b)
|
||||
{
|
||||
int n = 0;
|
||||
tuple_info_t device = { CISTPL_DEVICE, NULL, NULL };
|
||||
tuple_info_t nolink = { CISTPL_NO_LINK, NULL, NULL };
|
||||
tuple_info_t end = { CISTPL_END, NULL, NULL };
|
||||
if (t->type != CISTPL_DEVICE)
|
||||
n = pack_tuple(&device, b);
|
||||
while (t) {
|
||||
n += pack_tuple(t, b+n);
|
||||
t = t->next;
|
||||
}
|
||||
if (nf > 0) {
|
||||
n = pack_mfc(n, b+n);
|
||||
} else {
|
||||
n += pack_tuple(&nolink, b+n);
|
||||
n += pack_tuple(&end, b+n);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/*====================================================================*/
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int optch, errflg = 0;
|
||||
char *out = NULL;
|
||||
u_char buf[1024];
|
||||
int n;
|
||||
FILE *f;
|
||||
|
||||
while ((optch = getopt(argc, argv, "o:")) != -1) {
|
||||
switch (optch) {
|
||||
case 'o':
|
||||
out = strdup(optarg); break;
|
||||
default:
|
||||
errflg = 1; break;
|
||||
}
|
||||
}
|
||||
if (errflg || (optind < argc-1)) {
|
||||
fprintf(stderr, "usage: %s [-o outfile] [infile]\n",
|
||||
argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (optind < argc) {
|
||||
f = fopen(argv[optind], "r");
|
||||
if (!f) {
|
||||
fprintf(stderr, "could not open '%s': %s\n", argv[optind],
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
} else
|
||||
f = stdin;
|
||||
parse_cis(f);
|
||||
fclose(f);
|
||||
n = pack_cis(cis_root, buf);
|
||||
if (out) {
|
||||
f = fopen(out, "w");
|
||||
if (!f) {
|
||||
fprintf(stderr, "could not open '%s': %s\n", out,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
} else f = stdout;
|
||||
fwrite(buf, n, 1, f);
|
||||
fclose(f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* pack_cis.h 1.7 2001/08/24 12:16:45
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License
|
||||
* at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* The initial developer of the original code is David A. Hinds
|
||||
* <[email protected]>. Portions created by David A. Hinds
|
||||
* are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License version 2 (the "GPL"), in
|
||||
* which case the provisions of the GPL are applicable instead of the
|
||||
* above. If you wish to allow the use of your version of this file
|
||||
* only under the terms of the GPL and not to allow others to use
|
||||
* your version of this file under the MPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice and
|
||||
* other provisions required by the GPL. If you do not delete the
|
||||
* provisions above, a recipient may use your version of this file
|
||||
* under either the MPL or the GPL.
|
||||
*/
|
||||
typedef struct tuple_info_t {
|
||||
u_char type;
|
||||
cisparse_t *parse;
|
||||
struct tuple_info_t *next;
|
||||
} tuple_info_t;
|
||||
|
||||
extern tuple_info_t *cis_root, *mfc[8];
|
||||
extern int nf;
|
||||
|
||||
void parse_cis(FILE *f);
|
||||
@@ -0,0 +1,418 @@
|
||||
%{
|
||||
/*
|
||||
* yacc_cis.y 1.13 2001/08/24 12:21:41
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License
|
||||
* at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* The initial developer of the original code is David A. Hinds
|
||||
* <[email protected]>. Portions created by David A. Hinds
|
||||
* are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License version 2 (the "GPL"), in
|
||||
* which case the provisions of the GPL are applicable instead of the
|
||||
* above. If you wish to allow the use of your version of this file
|
||||
* only under the terms of the GPL and not to allow others to use
|
||||
* your version of this file under the MPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice and
|
||||
* other provisions required by the GPL. If you do not delete the
|
||||
* provisions above, a recipient may use your version of this file
|
||||
* under either the MPL or the GPL.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <pcmcia/cs_types.h>
|
||||
#include <pcmcia/cs.h>
|
||||
#include <pcmcia/cistpl.h>
|
||||
|
||||
#include "pack_cis.h"
|
||||
|
||||
/* If bison: generate nicer error messages */
|
||||
#define YYERROR_VERBOSE 1
|
||||
|
||||
extern int current_lineno;
|
||||
|
||||
void yyerror(char *msg, ...);
|
||||
static tuple_info_t *new_tuple(u_char type, cisparse_t *parse);
|
||||
|
||||
%}
|
||||
|
||||
%token STRING NUMBER FLOAT VOLTAGE CURRENT SIZE
|
||||
%token VERS_1 MANFID FUNCID CONFIG CFTABLE MFC CHECKSUM
|
||||
%token POST ROM BASE LAST_INDEX CJEDEC AJEDEC
|
||||
%token DEV_INFO ATTR_DEV_INFO NO_INFO
|
||||
%token TIME TIMING WAIT READY RESERVED
|
||||
%token VNOM VMIN VMAX ISTATIC IAVG IPEAK IDOWN
|
||||
%token VCC VPP1 VPP2 IO MEM
|
||||
%token DEFAULT BVD WP RDYBSY MWAIT AUDIO READONLY PWRDOWN
|
||||
%token BIT8 BIT16 LINES RANGE
|
||||
%token IRQ_NO MASK LEVEL PULSE SHARED
|
||||
|
||||
%union {
|
||||
char *str;
|
||||
u_long num;
|
||||
float flt;
|
||||
cistpl_power_t pwr;
|
||||
cisparse_t *parse;
|
||||
tuple_info_t *tuple;
|
||||
}
|
||||
|
||||
%type <str> STRING
|
||||
%type <num> NUMBER SIZE VOLTAGE CURRENT TIME
|
||||
%type <flt> FLOAT
|
||||
%type <pwr> pwr pwrlist
|
||||
%type <parse> vers_1 manfid funcid config cftab io mem irq timing
|
||||
%type <parse> dev_info attr_dev_info checksum cjedec ajedec
|
||||
%type <tuple> tuple chain cis;
|
||||
%%
|
||||
|
||||
cis: chain
|
||||
{ cis_root = $1; }
|
||||
| chain mfc
|
||||
{ cis_root = $1; }
|
||||
;
|
||||
|
||||
chain: /* nothing */
|
||||
{ $$ = NULL; }
|
||||
| chain tuple
|
||||
{
|
||||
if ($1 == NULL) {
|
||||
$$ = $2;
|
||||
} else if ($2 == NULL) {
|
||||
$$ = $1;
|
||||
} else {
|
||||
tuple_info_t *tail = $1;
|
||||
while (tail->next != NULL) tail = tail->next;
|
||||
tail->next = $2;
|
||||
$$ = $1;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
mfc: MFC '{' chain '}'
|
||||
{ mfc[nf++] = $3; }
|
||||
| mfc ',' '{' chain '}'
|
||||
{ mfc[nf++] = $4; }
|
||||
;
|
||||
|
||||
tuple: dev_info
|
||||
{ $$ = new_tuple(CISTPL_DEVICE, $1); }
|
||||
| attr_dev_info
|
||||
{ $$ = new_tuple(CISTPL_DEVICE_A, $1); }
|
||||
| vers_1
|
||||
{ $$ = new_tuple(CISTPL_VERS_1, $1); }
|
||||
| manfid
|
||||
{ $$ = new_tuple(CISTPL_MANFID, $1); }
|
||||
| funcid
|
||||
{ $$ = new_tuple(CISTPL_FUNCID, $1); }
|
||||
| config
|
||||
{ $$ = new_tuple(CISTPL_CONFIG, $1); }
|
||||
| cftab
|
||||
{ $$ = new_tuple(CISTPL_CFTABLE_ENTRY, $1); }
|
||||
| checksum
|
||||
{ $$ = NULL; }
|
||||
| error
|
||||
{ $$ = NULL; }
|
||||
| cjedec
|
||||
{ $$ = new_tuple(CISTPL_JEDEC_C, $1); }
|
||||
| ajedec
|
||||
{ $$ = new_tuple(CISTPL_JEDEC_A, $1); }
|
||||
;
|
||||
|
||||
dev_info: DEV_INFO
|
||||
{ $$ = calloc(1, sizeof(cisparse_t)); }
|
||||
| dev_info NUMBER TIME ',' SIZE
|
||||
{
|
||||
$$->device.dev[$$->device.ndev].type = $2;
|
||||
$$->device.dev[$$->device.ndev].speed = $3;
|
||||
$$->device.dev[$$->device.ndev].size = $5;
|
||||
$$->device.ndev++;
|
||||
}
|
||||
| dev_info NO_INFO
|
||||
;
|
||||
|
||||
attr_dev_info: ATTR_DEV_INFO
|
||||
{ $$ = calloc(1, sizeof(cisparse_t)); }
|
||||
| attr_dev_info NUMBER TIME ',' SIZE
|
||||
{
|
||||
$$->device.dev[$$->device.ndev].type = $2;
|
||||
$$->device.dev[$$->device.ndev].speed = $3;
|
||||
$$->device.dev[$$->device.ndev].size = $5;
|
||||
$$->device.ndev++;
|
||||
}
|
||||
| attr_dev_info NO_INFO
|
||||
;
|
||||
|
||||
vers_1: VERS_1 FLOAT
|
||||
{
|
||||
$$ = calloc(1, sizeof(cisparse_t));
|
||||
$$->version_1.major = $2;
|
||||
$2 -= floor($2+0.01);
|
||||
while (fabs($2 - floor($2+0.5)) > 0.01) {
|
||||
$2 *= 10;
|
||||
}
|
||||
$$->version_1.minor = $2+0.01;
|
||||
}
|
||||
| vers_1 ',' STRING
|
||||
{
|
||||
cistpl_vers_1_t *v = &$$->version_1;
|
||||
u_int pos = 0;
|
||||
if (v->ns) {
|
||||
pos = v->ofs[v->ns-1];
|
||||
pos += strlen(v->str+pos)+1;
|
||||
}
|
||||
v->ofs[v->ns] = pos;
|
||||
strcpy(v->str+pos, $3);
|
||||
v->ns++;
|
||||
}
|
||||
;
|
||||
|
||||
manfid: MANFID NUMBER ',' NUMBER
|
||||
{
|
||||
$$ = calloc(1, sizeof(cisparse_t));
|
||||
$$->manfid.manf = $2;
|
||||
$$->manfid.card = $4;
|
||||
}
|
||||
;
|
||||
|
||||
funcid: FUNCID NUMBER
|
||||
{
|
||||
$$ = calloc(1, sizeof(cisparse_t));
|
||||
$$->funcid.func = $2;
|
||||
}
|
||||
| funcid POST
|
||||
{ $$->funcid.sysinit |= CISTPL_SYSINIT_POST; }
|
||||
| funcid ROM
|
||||
{ $$->funcid.sysinit |= CISTPL_SYSINIT_ROM; }
|
||||
;
|
||||
|
||||
cjedec: CJEDEC NUMBER NUMBER
|
||||
{
|
||||
$$ = calloc(1, sizeof(cisparse_t));
|
||||
$$->jedec.id[0].mfr = $2;
|
||||
$$->jedec.id[0].info = $3;
|
||||
$$->jedec.nid = 1;
|
||||
}
|
||||
| cjedec ',' NUMBER NUMBER
|
||||
{
|
||||
$$->jedec.id[$$->jedec.nid].mfr = $3;
|
||||
$$->jedec.id[$$->jedec.nid++].info = $4;
|
||||
}
|
||||
;
|
||||
|
||||
ajedec: AJEDEC NUMBER NUMBER
|
||||
{
|
||||
$$ = calloc(1, sizeof(cisparse_t));
|
||||
$$->jedec.id[0].mfr = $2;
|
||||
$$->jedec.id[0].info = $3;
|
||||
$$->jedec.nid = 1;
|
||||
}
|
||||
| ajedec ',' NUMBER NUMBER
|
||||
{
|
||||
$$->jedec.id[$$->jedec.nid].mfr = $3;
|
||||
$$->jedec.id[$$->jedec.nid++].info = $4;
|
||||
}
|
||||
;
|
||||
|
||||
config: CONFIG BASE NUMBER MASK NUMBER LAST_INDEX NUMBER
|
||||
{
|
||||
$$ = calloc(1, sizeof(cisparse_t));
|
||||
$$->config.base = $3;
|
||||
$$->config.rmask[0] = $5;
|
||||
$$->config.last_idx = $7;
|
||||
}
|
||||
;
|
||||
|
||||
pwr: VNOM VOLTAGE
|
||||
{
|
||||
$$.present = CISTPL_POWER_VNOM;
|
||||
$$.param[0] = $2;
|
||||
}
|
||||
| VMIN VOLTAGE
|
||||
{
|
||||
$$.present = CISTPL_POWER_VMIN;
|
||||
$$.param[0] = $2;
|
||||
}
|
||||
| VMAX VOLTAGE
|
||||
{
|
||||
$$.present = CISTPL_POWER_VMAX;
|
||||
$$.param[0] = $2;
|
||||
}
|
||||
| ISTATIC CURRENT
|
||||
{
|
||||
$$.present = CISTPL_POWER_ISTATIC;
|
||||
$$.param[0] = $2;
|
||||
}
|
||||
| IAVG CURRENT
|
||||
{
|
||||
$$.present = CISTPL_POWER_IAVG;
|
||||
$$.param[0] = $2;
|
||||
}
|
||||
| IPEAK CURRENT
|
||||
{
|
||||
$$.present = CISTPL_POWER_IPEAK;
|
||||
$$.param[0] = $2;
|
||||
}
|
||||
| IDOWN CURRENT
|
||||
{
|
||||
$$.present = CISTPL_POWER_IDOWN;
|
||||
$$.param[0] = $2;
|
||||
}
|
||||
;
|
||||
|
||||
pwrlist: /* nothing */
|
||||
{
|
||||
$$.present = 0;
|
||||
}
|
||||
| pwrlist pwr
|
||||
{
|
||||
$$.present |= 1<<($2.present);
|
||||
$$.param[$2.present] = $2.param[0];
|
||||
}
|
||||
;
|
||||
|
||||
timing: cftab TIMING
|
||||
| timing WAIT TIME
|
||||
| timing READY TIME
|
||||
| timing RESERVED TIME
|
||||
;
|
||||
|
||||
io: cftab IO NUMBER '-' NUMBER
|
||||
{
|
||||
int n = $$->cftable_entry.io.nwin;
|
||||
$$->cftable_entry.io.win[n].base = $3;
|
||||
$$->cftable_entry.io.win[n].len = $5-$3+1;
|
||||
$$->cftable_entry.io.nwin++;
|
||||
}
|
||||
| io ',' NUMBER '-' NUMBER
|
||||
{
|
||||
int n = $$->cftable_entry.io.nwin;
|
||||
$$->cftable_entry.io.win[n].base = $3;
|
||||
$$->cftable_entry.io.win[n].len = $5-$3+1;
|
||||
$$->cftable_entry.io.nwin++;
|
||||
}
|
||||
| io BIT8
|
||||
{ $$->cftable_entry.io.flags |= CISTPL_IO_8BIT; }
|
||||
| io BIT16
|
||||
{ $$->cftable_entry.io.flags |= CISTPL_IO_16BIT; }
|
||||
| io LINES '=' NUMBER ']'
|
||||
{ $$->cftable_entry.io.flags |= $4; }
|
||||
| io RANGE
|
||||
;
|
||||
|
||||
mem: cftab MEM NUMBER '-' NUMBER '@' NUMBER
|
||||
{
|
||||
int n = $$->cftable_entry.mem.nwin;
|
||||
$$->cftable_entry.mem.win[n].card_addr = $3;
|
||||
$$->cftable_entry.mem.win[n].host_addr = $7;
|
||||
$$->cftable_entry.mem.win[n].len = $5-$3+1;
|
||||
$$->cftable_entry.mem.nwin++;
|
||||
}
|
||||
| mem ',' NUMBER '-' NUMBER '@' NUMBER
|
||||
{
|
||||
int n = $$->cftable_entry.mem.nwin;
|
||||
$$->cftable_entry.mem.win[n].card_addr = $3;
|
||||
$$->cftable_entry.mem.win[n].host_addr = $7;
|
||||
$$->cftable_entry.mem.win[n].len = $5-$3+1;
|
||||
$$->cftable_entry.mem.nwin++;
|
||||
}
|
||||
| mem BIT8
|
||||
{ $$->cftable_entry.io.flags |= CISTPL_IO_8BIT; }
|
||||
| mem BIT16
|
||||
{ $$->cftable_entry.io.flags |= CISTPL_IO_16BIT; }
|
||||
;
|
||||
|
||||
irq: cftab IRQ_NO NUMBER
|
||||
{ $$->cftable_entry.irq.IRQInfo1 = ($3 & 0x0f); }
|
||||
| cftab IRQ_NO MASK NUMBER
|
||||
{
|
||||
$$->cftable_entry.irq.IRQInfo1 = IRQ_INFO2_VALID;
|
||||
$$->cftable_entry.irq.IRQInfo2 = $4;
|
||||
}
|
||||
| irq PULSE
|
||||
{ $$->cftable_entry.irq.IRQInfo1 |= IRQ_PULSE_ID; }
|
||||
| irq LEVEL
|
||||
{ $$->cftable_entry.irq.IRQInfo1 |= IRQ_LEVEL_ID; }
|
||||
| irq SHARED
|
||||
{ $$->cftable_entry.irq.IRQInfo1 |= IRQ_SHARE_ID; }
|
||||
;
|
||||
|
||||
cftab: CFTABLE NUMBER
|
||||
{
|
||||
$$ = calloc(1, sizeof(cisparse_t));
|
||||
$$->cftable_entry.index = $2;
|
||||
}
|
||||
| cftab DEFAULT
|
||||
{ $$->cftable_entry.flags |= CISTPL_CFTABLE_DEFAULT; }
|
||||
| cftab BVD
|
||||
{ $$->cftable_entry.flags |= CISTPL_CFTABLE_BVDS; }
|
||||
| cftab WP
|
||||
{ $$->cftable_entry.flags |= CISTPL_CFTABLE_WP; }
|
||||
| cftab RDYBSY
|
||||
{ $$->cftable_entry.flags |= CISTPL_CFTABLE_RDYBSY; }
|
||||
| cftab MWAIT
|
||||
{ $$->cftable_entry.flags |= CISTPL_CFTABLE_MWAIT; }
|
||||
| cftab AUDIO
|
||||
{ $$->cftable_entry.flags |= CISTPL_CFTABLE_AUDIO; }
|
||||
| cftab READONLY
|
||||
{ $$->cftable_entry.flags |= CISTPL_CFTABLE_READONLY; }
|
||||
| cftab PWRDOWN
|
||||
{ $$->cftable_entry.flags |= CISTPL_CFTABLE_PWRDOWN; }
|
||||
| cftab VCC pwrlist
|
||||
{ $$->cftable_entry.vcc = $3; }
|
||||
| cftab VPP1 pwrlist
|
||||
{ $$->cftable_entry.vpp1 = $3; }
|
||||
| cftab VPP2 pwrlist
|
||||
{ $$->cftable_entry.vpp2 = $3; }
|
||||
| io
|
||||
| mem
|
||||
| irq
|
||||
| timing
|
||||
;
|
||||
|
||||
checksum: CHECKSUM NUMBER '-' NUMBER '=' NUMBER
|
||||
{ $$ = NULL; }
|
||||
|
||||
%%
|
||||
|
||||
static tuple_info_t *new_tuple(u_char type, cisparse_t *parse)
|
||||
{
|
||||
tuple_info_t *t = calloc(1, sizeof(tuple_info_t));
|
||||
t->type = type;
|
||||
t->parse = parse;
|
||||
t->next = NULL;
|
||||
}
|
||||
|
||||
void yyerror(char *msg, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char str[256];
|
||||
|
||||
va_start(ap, msg);
|
||||
sprintf(str, "error at line %d: ", current_lineno);
|
||||
vsprintf(str+strlen(str), msg, ap);
|
||||
fprintf(stderr, "%s\n", str);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void main(int argc, char *argv[])
|
||||
{
|
||||
if (argc > 1)
|
||||
parse_cis(argv[1]);
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user