Run indent on all these files to make them more readable. (I also went
through by hand and cleaned up some indent bogons.)
This commit is contained in:
parent
9082b1de9d
commit
7f78c5620d
@ -14,19 +14,18 @@
|
||||
#include <varargs.h>
|
||||
#include "cardd.h"
|
||||
|
||||
|
||||
char *config_file = "/etc/pccard.conf";
|
||||
char *config_file = "/etc/pccard.conf";
|
||||
|
||||
struct card_config *assign_driver(struct card *);
|
||||
int setup_slot(struct slot *);
|
||||
void read_ether(struct slot *);
|
||||
void dump_config_file();
|
||||
void pr_cmd(struct cmd *);
|
||||
void readslots();
|
||||
void slot_change(struct slot *);
|
||||
void card_removed(struct slot *);
|
||||
void card_inserted(struct slot *);
|
||||
int assign_io(struct slot *sp);
|
||||
int setup_slot(struct slot *);
|
||||
void read_ether(struct slot *);
|
||||
void dump_config_file(void);
|
||||
void pr_cmd(struct cmd *);
|
||||
void readslots(void);
|
||||
void slot_change(struct slot *);
|
||||
void card_removed(struct slot *);
|
||||
void card_inserted(struct slot *);
|
||||
int assign_io(struct slot *);
|
||||
|
||||
/*
|
||||
* mainline code for cardd
|
||||
@ -34,17 +33,17 @@ int assign_io(struct slot *sp);
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct slot *sp;
|
||||
int count, debug = 0;
|
||||
int verbose = 0;
|
||||
extern char *optarg;
|
||||
extern int optind, optopt;
|
||||
struct slot *sp;
|
||||
int count, debug = 0;
|
||||
int verbose = 0;
|
||||
extern char *optarg;
|
||||
extern int optind, optopt;
|
||||
|
||||
while ((count = getopt(argc, argv, ":dvf:")) != -1) {
|
||||
switch(count) {
|
||||
switch (count) {
|
||||
case 'd':
|
||||
setbuf(stdout,0);
|
||||
setbuf(stderr,0);
|
||||
setbuf(stdout, 0);
|
||||
setbuf(stderr, 0);
|
||||
debug = 1;
|
||||
break;
|
||||
case 'v':
|
||||
@ -65,145 +64,134 @@ extern int optind, optopt;
|
||||
debug = 1;
|
||||
#endif
|
||||
io_avail = bit_alloc(IOPORTS); /* Only supports ISA ports */
|
||||
/*
|
||||
* Mem allocation done in MEMUNIT units.
|
||||
*/
|
||||
|
||||
/* Mem allocation done in MEMUNIT units. */
|
||||
mem_avail = bit_alloc(MEMBLKS);
|
||||
readfile(config_file);
|
||||
if (verbose)
|
||||
dump_config_file();
|
||||
if (!debug)
|
||||
{
|
||||
if (!debug) {
|
||||
if (daemon(0, 0))
|
||||
die("fork failed");
|
||||
openlog("cardd", LOG_PID, LOG_DAEMON);
|
||||
do_log = 1;
|
||||
}
|
||||
}
|
||||
printf("Before readslots\n");
|
||||
readslots();
|
||||
printf("After readslots\n");
|
||||
if (slots == 0)
|
||||
die("No PC-CARD slots");
|
||||
for (;;)
|
||||
{
|
||||
fd_set mask;
|
||||
for (;;) {
|
||||
fd_set mask;
|
||||
FD_ZERO(&mask);
|
||||
for (sp = slots; sp; sp = sp->next)
|
||||
FD_SET(sp->fd,&mask);
|
||||
printf("Doing select\n");
|
||||
FD_SET(sp->fd, &mask);
|
||||
printf("Doing select\n");
|
||||
count = select(32, 0, 0, &mask, 0);
|
||||
printf("select=%d\n",count);
|
||||
if (count == -1)
|
||||
{
|
||||
printf("select=%d\n", count);
|
||||
if (count == -1) {
|
||||
perror("Select");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (count)
|
||||
for (sp = slots; sp; sp = sp->next)
|
||||
if (FD_ISSET(sp->fd,&mask))
|
||||
slot_change(sp);
|
||||
}
|
||||
if (FD_ISSET(sp->fd, &mask))
|
||||
slot_change(sp);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Dump configuration file data.
|
||||
*/
|
||||
void
|
||||
dump_config_file()
|
||||
dump_config_file(void)
|
||||
{
|
||||
struct card *cp;
|
||||
struct card_config *confp;
|
||||
struct card *cp;
|
||||
struct card_config *confp;
|
||||
|
||||
for (cp = cards; cp; cp = cp->next)
|
||||
{
|
||||
for (cp = cards; cp; cp = cp->next) {
|
||||
printf("Card manuf %s, vers %s\n", cp->manuf, cp->version);
|
||||
printf("Configuration entries:\n");
|
||||
for (confp = cp->config; confp; confp = confp->next)
|
||||
printf("\tIndex code = 0x%x, driver name = %s\n",
|
||||
confp->index, confp->driver->name);
|
||||
if (cp->insert)
|
||||
{
|
||||
confp->index, confp->driver->name);
|
||||
if (cp->insert) {
|
||||
printf("Insert commands are:\n");
|
||||
pr_cmd(cp->insert);
|
||||
}
|
||||
if (cp->remove)
|
||||
{
|
||||
}
|
||||
if (cp->remove) {
|
||||
printf("Remove commands are:\n");
|
||||
pr_cmd(cp->remove);
|
||||
}
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
for (devp = devlist; devp; devp = devp->next)
|
||||
{
|
||||
if (devp->insert)
|
||||
{
|
||||
for (devp = devlist; devp; devp = devp->next) {
|
||||
if (devp->insert) {
|
||||
printf("Insert commands are:\n");
|
||||
pr_cmd(devp->insert);
|
||||
}
|
||||
if (devp->remove)
|
||||
{
|
||||
}
|
||||
if (devp->remove) {
|
||||
printf("Remove commands are:\n");
|
||||
pr_cmd(devp->remove);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
pr_cmd(struct cmd *cp)
|
||||
pr_cmd(struct cmd * cp)
|
||||
{
|
||||
while (cp)
|
||||
{
|
||||
while (cp) {
|
||||
printf("\t%s\n", cp->line);
|
||||
cp = cp->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* readslots - read all the PCMCIA slots, and build
|
||||
* a list of the slots.
|
||||
*/
|
||||
void
|
||||
readslots()
|
||||
readslots(void)
|
||||
{
|
||||
char name[128];
|
||||
int i, fd;
|
||||
struct slot *sp;
|
||||
char name[128];
|
||||
int i, fd;
|
||||
struct slot *sp;
|
||||
|
||||
for (i = 0; i < MAXSLOT; i++)
|
||||
{
|
||||
for (i = 0; i < MAXSLOT; i++) {
|
||||
sprintf(name, CARD_DEVICE, i);
|
||||
fd = open(name, 2);
|
||||
if (fd < 0)
|
||||
continue;
|
||||
printf("opened %s\n",name);
|
||||
printf("opened %s\n", name);
|
||||
sp = xmalloc(sizeof(*sp));
|
||||
sp->fd = fd;
|
||||
sp->name = newstr(name);
|
||||
sp->slot = i;
|
||||
sp->state = empty;
|
||||
/*
|
||||
* Check to see if the controller memory has been set up.
|
||||
*/
|
||||
if (slots == 0)
|
||||
{
|
||||
|
||||
/* Check to see if the controller memory has been set up. */
|
||||
if (slots == 0) {
|
||||
unsigned long mem = 0;
|
||||
|
||||
if (ioctl(fd, PIOCRWMEM, &mem))
|
||||
perror("ioctl (PIOCRWMEM)");
|
||||
printf("mem=%x\n",mem);
|
||||
if (mem == 0)
|
||||
{
|
||||
mem = alloc_memory(4*1024);
|
||||
printf("mem=%x\n", mem);
|
||||
if (mem == 0) {
|
||||
mem = alloc_memory(4 * 1024);
|
||||
if (mem == 0)
|
||||
die("Can't allocate memory for controller access");
|
||||
die("Can't allocate memory for controller access");
|
||||
if (ioctl(fd, PIOCRWMEM, &mem))
|
||||
perror("ioctl (PIOCRWMEM)");
|
||||
}
|
||||
}
|
||||
printf("%p %p\n",sp,&sp->next);
|
||||
}
|
||||
printf("%p %p\n", sp, &sp->next);
|
||||
sp->next = slots;
|
||||
slots = sp;
|
||||
slot_change(sp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* slot_change - Card status has changed.
|
||||
* read new state and process.
|
||||
@ -214,17 +202,15 @@ slot_change(struct slot *sp)
|
||||
struct slotstate state;
|
||||
|
||||
current_slot = sp;
|
||||
if (ioctl(sp->fd, PIOCGSTATE, &state))
|
||||
{
|
||||
if (ioctl(sp->fd, PIOCGSTATE, &state)) {
|
||||
perror("ioctl (PIOCGSTATE)");
|
||||
return;
|
||||
}
|
||||
printf("%p %p %d %d\n",sp,&sp->state,state.state,sp->state);
|
||||
}
|
||||
printf("%p %p %d %d\n", sp, &sp->state, state.state, sp->state);
|
||||
if (state.state == sp->state)
|
||||
return;
|
||||
sp->state = state.state;
|
||||
switch (sp->state)
|
||||
{
|
||||
switch (sp->state) {
|
||||
case empty:
|
||||
case noslot:
|
||||
card_removed(sp);
|
||||
@ -232,8 +218,9 @@ slot_change(struct slot *sp)
|
||||
case filled:
|
||||
card_inserted(sp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* card_removed - card has been removed from slot.
|
||||
* Execute the remove commands, and clear the slot's state.
|
||||
@ -244,20 +231,20 @@ slot_change(struct slot *sp)
|
||||
void
|
||||
card_removed(struct slot *sp)
|
||||
{
|
||||
struct card *cp;
|
||||
struct card *cp;
|
||||
|
||||
if (sp->cis)
|
||||
freecis(sp->cis);
|
||||
if (sp->config)
|
||||
{
|
||||
if (sp->config) {
|
||||
sp->config->inuse = 0;
|
||||
sp->config->driver->inuse = 0;
|
||||
}
|
||||
}
|
||||
if ((cp = sp->card) != 0)
|
||||
execute(cp->remove);
|
||||
sp->cis = 0;
|
||||
sp->config = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* card_inserted - Card has been inserted;
|
||||
* - Read the CIS
|
||||
@ -273,49 +260,46 @@ struct card *cp;
|
||||
void
|
||||
card_inserted(struct slot *sp)
|
||||
{
|
||||
struct card *cp;
|
||||
struct card *cp;
|
||||
|
||||
sleep(5);
|
||||
sp->cis = readcis(sp->fd);
|
||||
if (sp->cis == 0)
|
||||
{
|
||||
if (sp->cis == 0) {
|
||||
log_1s("Error reading CIS on %s\n", sp->name);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
}
|
||||
#if 0
|
||||
dumpcis(sp->cis);
|
||||
*/
|
||||
#endif
|
||||
for (cp = cards; cp; cp = cp->next)
|
||||
if (strcmp(cp->manuf, sp->cis->manuf) == 0 &&
|
||||
strcmp(cp->version, sp->cis->vers) == 0)
|
||||
strcmp(cp->version, sp->cis->vers) == 0)
|
||||
break;
|
||||
sp->card = cp;
|
||||
/*
|
||||
#if 0
|
||||
reset_slot(sp);
|
||||
*/
|
||||
if (cp == 0)
|
||||
{
|
||||
#endif
|
||||
if (cp == 0) {
|
||||
log_1s("No card in database for \"%s\"", sp->cis->manuf);
|
||||
log_1s("vers: \"%s\"", sp->cis->vers);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (cp->ether)
|
||||
read_ether(sp);
|
||||
sp->config = assign_driver(cp);
|
||||
if (sp->config == 0)
|
||||
{
|
||||
if (sp->config == 0) {
|
||||
execute(cp->insert);
|
||||
return;
|
||||
}
|
||||
if (assign_io(sp))
|
||||
{
|
||||
}
|
||||
if (assign_io(sp)) {
|
||||
log_1s("Resource allocation failure for %s", sp->cis->manuf);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Once assigned, then set up the I/O & mem contexts, and
|
||||
* set up the windows, and then attach the driver.
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
* Once assigned, then set up the I/O & mem contexts, and
|
||||
* set up the windows, and then attach the driver.
|
||||
*/
|
||||
if (setup_slot(sp))
|
||||
execute(cp->insert);
|
||||
#if 0
|
||||
@ -323,6 +307,7 @@ struct card *cp;
|
||||
reset_slot(sp);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* read_ether - read ethernet address from card. Offset is
|
||||
* the offset into the attribute memory of the card.
|
||||
@ -330,14 +315,13 @@ struct card *cp;
|
||||
void
|
||||
read_ether(struct slot *sp)
|
||||
{
|
||||
unsigned char net_addr[12];
|
||||
unsigned char net_addr[12];
|
||||
|
||||
lseek(sp->fd, (off_t)sp->card->ether, SEEK_SET);
|
||||
if (read(sp->fd, net_addr, sizeof(net_addr)) != sizeof(net_addr))
|
||||
{
|
||||
if (read(sp->fd, net_addr, sizeof(net_addr)) != sizeof(net_addr)) {
|
||||
logerr("read err on net addr");
|
||||
return;
|
||||
}
|
||||
}
|
||||
sp->eaddr[0] = net_addr[0];
|
||||
sp->eaddr[1] = net_addr[2];
|
||||
sp->eaddr[2] = net_addr[4];
|
||||
@ -345,9 +329,10 @@ unsigned char net_addr[12];
|
||||
sp->eaddr[4] = net_addr[8];
|
||||
sp->eaddr[5] = net_addr[10];
|
||||
printf("Ether=%02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
sp->eaddr[0], sp->eaddr[1], sp->eaddr[2],
|
||||
sp->eaddr[3], sp->eaddr[4], sp->eaddr[5]);
|
||||
sp->eaddr[0], sp->eaddr[1], sp->eaddr[2],
|
||||
sp->eaddr[3], sp->eaddr[4], sp->eaddr[5]);
|
||||
}
|
||||
|
||||
/*
|
||||
* assign_driver - Assign driver to card.
|
||||
* First, see if an existing driver is already setup.
|
||||
@ -355,101 +340,87 @@ unsigned char net_addr[12];
|
||||
struct card_config *
|
||||
assign_driver(struct card *cp)
|
||||
{
|
||||
struct driver *drvp;
|
||||
struct card_config *conf;
|
||||
struct driver *drvp;
|
||||
struct card_config *conf;
|
||||
|
||||
for (conf = cp->config; conf; conf = conf->next)
|
||||
if (conf->inuse == 0 && conf->driver->card == cp &&
|
||||
conf->driver->config == conf)
|
||||
{
|
||||
conf->driver->config == conf) {
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Found existing driver (%s) for %s\n",
|
||||
conf->driver->name, cp->manuf);
|
||||
#endif /* DEBUG */
|
||||
return(conf);
|
||||
}
|
||||
/*
|
||||
* New driver must be allocated. Find one that matches the
|
||||
* any configurations not in use.
|
||||
*/
|
||||
conf->driver->name, cp->manuf);
|
||||
#endif
|
||||
return (conf);
|
||||
}
|
||||
/*
|
||||
* New driver must be allocated. Find one that matches the
|
||||
* any configurations not in use.
|
||||
*/
|
||||
for (conf = cp->config; conf; conf = conf->next)
|
||||
if (conf->inuse == 0 && conf->driver->card == 0)
|
||||
break;
|
||||
if (conf == 0)
|
||||
{
|
||||
if (conf == 0) {
|
||||
log_1s("No free configuration for card %s", cp->manuf);
|
||||
return(0);
|
||||
}
|
||||
/*
|
||||
* Now we have a free driver and a matching configuration.
|
||||
* Before assigning and allocating everything, check to
|
||||
* see if a device class can be allocated to this.
|
||||
*/
|
||||
return (0);
|
||||
}
|
||||
/*
|
||||
* Now we have a free driver and a matching configuration.
|
||||
* Before assigning and allocating everything, check to
|
||||
* see if a device class can be allocated to this.
|
||||
*/
|
||||
drvp = conf->driver;
|
||||
/*
|
||||
* If none available, then we can't use this card.
|
||||
*/
|
||||
if (drvp->inuse)
|
||||
{
|
||||
|
||||
/* If none available, then we can't use this card. */
|
||||
if (drvp->inuse) {
|
||||
log_1s("Driver already being used for %s", cp->manuf);
|
||||
return(0);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#if 0
|
||||
/*
|
||||
* Allocate I/O, memory and IRQ resources.
|
||||
*/
|
||||
for (ap = drvp->io; ap; ap = ap->next)
|
||||
{
|
||||
if (ap->addr == 0 && ap->size)
|
||||
{
|
||||
int i = bit_fns(io_avail, IOPORTS, ap->size);
|
||||
|
||||
if (i < 0)
|
||||
{
|
||||
/* Allocate I/O, memory and IRQ resources. */
|
||||
for (ap = drvp->io; ap; ap = ap->next) {
|
||||
if (ap->addr == 0 && ap->size) {
|
||||
int i = bit_fns(io_avail, IOPORTS, ap->size);
|
||||
|
||||
if (i < 0) {
|
||||
log_1s("Failed to allocate I/O ports for %s\n",
|
||||
cp->manuf);
|
||||
return(0);
|
||||
}
|
||||
cp->manuf);
|
||||
return (0);
|
||||
}
|
||||
ap->addr = i;
|
||||
bit_nclear(io_avail, i, ap->size);
|
||||
}
|
||||
}
|
||||
if (drvp->irq == 0)
|
||||
{
|
||||
int i;
|
||||
}
|
||||
if (drvp->irq == 0) {
|
||||
int i;
|
||||
for (i = 1; i < 16; i++)
|
||||
if (pool_irq[i])
|
||||
{
|
||||
if (pool_irq[i]) {
|
||||
drvp->irq = i;
|
||||
pool_irq[i] = 0;
|
||||
break;
|
||||
}
|
||||
if (drvp->irq == 0)
|
||||
{
|
||||
}
|
||||
if (drvp->irq == 0) {
|
||||
log_1s("Failed to allocate IRQ for %s\n", cp->manuf);
|
||||
return(0);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
for (ap = drvp->mem; ap; ap = ap->next)
|
||||
{
|
||||
if (ap->addr == 0 && ap->size)
|
||||
{
|
||||
}
|
||||
for (ap = drvp->mem; ap; ap = ap->next) {
|
||||
if (ap->addr == 0 && ap->size) {
|
||||
ap->addr = alloc_memory(ap->size);
|
||||
if (ap->addr == 0)
|
||||
{
|
||||
if (ap->addr == 0) {
|
||||
log_1s("Failed to allocate memory for %s\n",
|
||||
cp->manuf);
|
||||
return(0);
|
||||
}
|
||||
cp->manuf);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
#endif /* 0 */
|
||||
}
|
||||
#endif /* 0 */
|
||||
drvp->card = cp;
|
||||
drvp->config = conf;
|
||||
drvp->inuse = 1;
|
||||
conf->inuse = 1;
|
||||
return(conf);
|
||||
return (conf);
|
||||
}
|
||||
|
||||
/*
|
||||
* assign_io - Allocate resources to slot matching the
|
||||
* configuration index selected.
|
||||
@ -457,8 +428,8 @@ struct card_config *conf;
|
||||
int
|
||||
assign_io(struct slot *sp)
|
||||
{
|
||||
struct cis *cis;
|
||||
struct cis_config *cisconf, *defconf;
|
||||
struct cis *cis;
|
||||
struct cis_config *cisconf, *defconf;
|
||||
|
||||
cis = sp->cis;
|
||||
defconf = cis->def_config;
|
||||
@ -466,14 +437,14 @@ struct cis_config *cisconf, *defconf;
|
||||
if (cisconf->id == sp->config->index)
|
||||
break;
|
||||
if (cisconf == 0)
|
||||
return(-1);
|
||||
return (-1);
|
||||
sp->card_config = cisconf;
|
||||
/*
|
||||
* Found a matching configuration. Now look at the I/O, memory and IRQ
|
||||
* to create the desired parameters. Look at memory first.
|
||||
*/
|
||||
if (cisconf->memspace || (defconf && defconf->memspace))
|
||||
{
|
||||
|
||||
/*
|
||||
* Found a matching configuration. Now look at the I/O, memory and IRQ
|
||||
* to create the desired parameters. Look at memory first.
|
||||
*/
|
||||
if (cisconf->memspace || (defconf && defconf->memspace)) {
|
||||
struct cis_memblk *mp;
|
||||
|
||||
mp = cisconf->mem;
|
||||
@ -481,91 +452,83 @@ struct cis_config *cisconf, *defconf;
|
||||
mp = defconf->mem;
|
||||
sp->mem.size = mp->length;
|
||||
sp->mem.cardaddr = mp->address;
|
||||
/*
|
||||
* For now, we allocate our own memory from the pool.
|
||||
*/
|
||||
|
||||
/* For now, we allocate our own memory from the pool. */
|
||||
sp->mem.addr = sp->config->driver->mem;
|
||||
/*
|
||||
* Host memory address is required. Allocate one
|
||||
* from our pool.
|
||||
*/
|
||||
if (sp->mem.size && sp->mem.addr == 0)
|
||||
{
|
||||
/*
|
||||
* Host memory address is required. Allocate one
|
||||
* from our pool.
|
||||
*/
|
||||
if (sp->mem.size && sp->mem.addr == 0) {
|
||||
sp->mem.addr = alloc_memory(mp->length);
|
||||
if (sp->mem.addr == 0)
|
||||
return(-1);
|
||||
return (-1);
|
||||
sp->config->driver->mem = sp->mem.addr;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Using mem addr 0x%x, size %d, card addr 0x%x\n",
|
||||
sp->mem.addr, sp->mem.cardaddr, sp->mem.size);
|
||||
sp->mem.addr, sp->mem.cardaddr, sp->mem.size);
|
||||
sp->mem.cardaddr = 0x4000;
|
||||
#endif /* DEBUG */
|
||||
}
|
||||
/*
|
||||
* Now look at I/O.
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Now look at I/O. */
|
||||
bzero(&sp->io, sizeof(sp->io));
|
||||
if (cisconf->iospace || (defconf && defconf->iospace))
|
||||
{
|
||||
if (cisconf->iospace || (defconf && defconf->iospace)) {
|
||||
struct cis_config *cp;
|
||||
|
||||
cp = cisconf;
|
||||
if (!cisconf->iospace)
|
||||
cp = defconf;
|
||||
/*
|
||||
* If # of I/O lines decoded == 10, then card does its
|
||||
* own decoding.
|
||||
*/
|
||||
/*
|
||||
* If an I/O block exists, then use it.
|
||||
* If no address (but a length) is available, allocate
|
||||
* from the pool.
|
||||
*/
|
||||
if (cp->io)
|
||||
{
|
||||
/*
|
||||
* If # of I/O lines decoded == 10, then card does its
|
||||
* own decoding.
|
||||
*
|
||||
* If an I/O block exists, then use it.
|
||||
* If no address (but a length) is available, allocate
|
||||
* from the pool.
|
||||
*/
|
||||
if (cp->io) {
|
||||
sp->io.addr = cp->io->addr;
|
||||
sp->io.size = cp->io->size;
|
||||
}
|
||||
/*
|
||||
* No I/O block, assume the address lines decode gives the size.
|
||||
*/
|
||||
else
|
||||
} else
|
||||
/*
|
||||
* No I/O block, assume the address lines
|
||||
* decode gives the size.
|
||||
*/
|
||||
sp->io.size = 1 << cp->io_addr;
|
||||
if (sp->io.addr == 0)
|
||||
{
|
||||
int i = bit_fns(io_avail, IOPORTS, sp->io.size);
|
||||
|
||||
|
||||
if (sp->io.addr == 0) {
|
||||
int i = bit_fns(io_avail, IOPORTS, sp->io.size);
|
||||
|
||||
if (i < 0)
|
||||
return(-1);
|
||||
return (-1);
|
||||
sp->io.addr = i;
|
||||
}
|
||||
}
|
||||
bit_nclear(io_avail, sp->io.addr, sp->io.size);
|
||||
/*
|
||||
* Set up the size to take into account the decode lines.
|
||||
*/
|
||||
|
||||
/* Set up the size to take into account the decode lines. */
|
||||
sp->io.cardaddr = cp->io_addr;
|
||||
switch(cp->io_bus)
|
||||
{
|
||||
switch (cp->io_bus) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
sp->io.flags = IODF_WS;
|
||||
break;
|
||||
case 2:
|
||||
sp->io.flags = IODF_WS|IODF_CS16;
|
||||
sp->io.flags = IODF_WS | IODF_CS16;
|
||||
break;
|
||||
case 3:
|
||||
sp->io.flags = IODF_WS|IODF_CS16|IODF_16BIT;
|
||||
sp->io.flags = IODF_WS | IODF_CS16 | IODF_16BIT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Using I/O addr 0x%x, size %d\n",
|
||||
sp->io.addr, sp->io.size);
|
||||
#endif /* DEBUG */
|
||||
}
|
||||
sp->io.addr, sp->io.size);
|
||||
#endif
|
||||
}
|
||||
sp->irq = sp->config->irq;
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
/*
|
||||
* setup_slot - Allocate the I/O and memory contexts
|
||||
@ -574,132 +537,123 @@ struct cis_config *cisconf, *defconf;
|
||||
int
|
||||
setup_slot(struct slot *sp)
|
||||
{
|
||||
struct mem_desc mem;
|
||||
struct io_desc io;
|
||||
struct drv_desc drv;
|
||||
struct driver *drvp = sp->config->driver;
|
||||
char c;
|
||||
off_t offs;
|
||||
int rw_flags;
|
||||
struct mem_desc mem;
|
||||
struct io_desc io;
|
||||
struct drv_desc drv;
|
||||
struct driver *drvp = sp->config->driver;
|
||||
char c;
|
||||
off_t offs;
|
||||
int rw_flags;
|
||||
|
||||
memset(&io,0,sizeof io);
|
||||
memset(&drv,0,sizeof drv);
|
||||
memset(&io, 0, sizeof io);
|
||||
memset(&drv, 0, sizeof drv);
|
||||
offs = sp->cis->reg_addr;
|
||||
rw_flags = MDF_ATTR;
|
||||
ioctl(sp->fd, PIOCRWFLAG, &rw_flags);
|
||||
lseek(sp->fd, offs, SEEK_SET);
|
||||
c = 0x80;
|
||||
write(sp->fd, &c, sizeof(c));
|
||||
usleep(sp->card->reset_time*1000);
|
||||
usleep(sp->card->reset_time * 1000);
|
||||
lseek(sp->fd, offs, SEEK_SET);
|
||||
c = 0x00;
|
||||
write(sp->fd, &c, sizeof(c));
|
||||
usleep(sp->card->reset_time*1000);
|
||||
usleep(sp->card->reset_time * 1000);
|
||||
lseek(sp->fd, offs, SEEK_SET);
|
||||
c = sp->config->index;
|
||||
c |= 0x40;
|
||||
c |= 0x40;
|
||||
write(sp->fd, &c, sizeof(c));
|
||||
#ifdef DEBUG
|
||||
printf("Setting config reg at offs 0x%x", offs);
|
||||
printf(" to 0x%x\n",c);
|
||||
printf(" to 0x%x\n", c);
|
||||
printf("Reset time = %d ms\n", sp->card->reset_time);
|
||||
#endif
|
||||
sleep(5);
|
||||
usleep(sp->card->reset_time*1000);
|
||||
/*
|
||||
* If other config registers exist, set them up.
|
||||
*/
|
||||
if (sp->cis->ccrs & 2) /* CCSR */
|
||||
{
|
||||
usleep(sp->card->reset_time * 1000);
|
||||
|
||||
/* If other config registers exist, set them up. */
|
||||
if (sp->cis->ccrs & 2) {
|
||||
/* CCSR */
|
||||
c = 0;
|
||||
if (sp->cis->def_config && sp->cis->def_config->misc_valid &&
|
||||
(sp->cis->def_config->misc & 0x8))
|
||||
c |= 0x08;
|
||||
if (sp->card_config->io_bus == 1)
|
||||
c |= 0x20;
|
||||
lseek(sp->fd, offs+2, SEEK_SET);
|
||||
lseek(sp->fd, offs + 2, SEEK_SET);
|
||||
write(sp->fd, &c, sizeof(c));
|
||||
#ifdef DEBUG
|
||||
printf("Setting CCSR reg to 0x%x\n", c);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
mem.window = 0;
|
||||
#ifdef DEBUG
|
||||
printf("Mem@ %x %d %x\n",sp->mem.addr, sp->mem.size, sp->mem.cardaddr);
|
||||
printf("Mem@ %x %d %x\n", sp->mem.addr, sp->mem.size, sp->mem.cardaddr);
|
||||
#endif
|
||||
if (sp->mem.addr)
|
||||
{
|
||||
if (sp->mem.addr) {
|
||||
mem.window = 0;
|
||||
mem.flags = sp->mem.flags | MDF_ACTIVE | MDF_16BITS;
|
||||
mem.start = (caddr_t)sp->mem.addr;
|
||||
mem.start = (caddr_t) sp->mem.addr;
|
||||
mem.card = sp->mem.cardaddr;
|
||||
mem.size = sp->mem.size;
|
||||
if (ioctl(sp->fd, PIOCSMEM, &mem))
|
||||
{
|
||||
if (ioctl(sp->fd, PIOCSMEM, &mem)) {
|
||||
logerr("ioctl (PIOCSMEM)");
|
||||
return(0);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
io.window = 0;
|
||||
if (sp->io.size)
|
||||
{
|
||||
if (sp->io.size) {
|
||||
io.flags = sp->io.flags;
|
||||
io.start = sp->io.addr;
|
||||
io.size = sp->io.size;
|
||||
/*
|
||||
io.start = sp->io.addr & ~((1 << sp->io.cardaddr)-1);
|
||||
#if 0
|
||||
io.start = sp->io.addr & ~((1 << sp->io.cardaddr) - 1);
|
||||
io.size = 1 << sp->io.cardaddr;
|
||||
if (io.start < 0x100)
|
||||
{
|
||||
if (io.start < 0x100) {
|
||||
io.start = 0x100;
|
||||
io.size = 0x300;
|
||||
}
|
||||
*/
|
||||
}
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
printf("Assigning I/O window 0, start 0x%x, size 0x%x flags 0x%x\n",
|
||||
io.start, io.size,io.flags);
|
||||
io.start, io.size, io.flags);
|
||||
#endif
|
||||
io.flags |= IODF_ACTIVE;
|
||||
if (ioctl(sp->fd, PIOCSIO, &io))
|
||||
{
|
||||
if (ioctl(sp->fd, PIOCSIO, &io)) {
|
||||
logerr("ioctl (PIOCSIO)");
|
||||
return(0);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
strcpy(drv.name, drvp->kernel);
|
||||
drv.unit = drvp->unit;
|
||||
drv.irqmask = 1 << sp->irq;
|
||||
drv.flags = 0x80;
|
||||
if (sp->mem.size)
|
||||
{
|
||||
if (sp->mem.size) {
|
||||
drv.mem = sp->mem.addr;
|
||||
drv.memsize = sp->mem.size;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
drv.mem = 0;
|
||||
drv.memsize = 0;
|
||||
}
|
||||
}
|
||||
if (sp->io.size)
|
||||
drv.iobase = sp->io.addr;
|
||||
else
|
||||
drv.iobase = 0;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Assign %s%d, io 0x%x, mem 0x%x, %d bytes, irq %x, flags %x\n",
|
||||
drv.name, drv.unit, drv.iobase, drv.mem, drv.memsize, drv.irqmask, drv.flags);
|
||||
#endif /* DEBUG */
|
||||
/*
|
||||
* If the driver fails to be connected to the device,
|
||||
* then it may mean that the driver did not recognise it.
|
||||
*/
|
||||
memcpy(drv.misc,sp->eaddr,6);
|
||||
if (ioctl(sp->fd, PIOCSDRV, &drv))
|
||||
{
|
||||
drv.name, drv.unit, drv.iobase, drv.mem, drv.memsize, drv.irqmask, drv.flags);
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* If the driver fails to be connected to the device,
|
||||
* then it may mean that the driver did not recognise it.
|
||||
*/
|
||||
memcpy(drv.misc, sp->eaddr, 6);
|
||||
if (ioctl(sp->fd, PIOCSDRV, &drv)) {
|
||||
#ifdef DEBUG
|
||||
perror(sp->card->manuf);
|
||||
#endif
|
||||
log_1s("driver allocation failed for %s", sp->card->manuf);
|
||||
return(0);
|
||||
}
|
||||
return(1);
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
@ -9,118 +9,116 @@
|
||||
|
||||
#include "readcis.h"
|
||||
|
||||
struct cmd
|
||||
{
|
||||
struct cmd {
|
||||
struct cmd *next;
|
||||
char *line; /* Command line */
|
||||
int macro; /* Contains macros */
|
||||
};
|
||||
char *line; /* Command line */
|
||||
int macro; /* Contains macros */
|
||||
};
|
||||
|
||||
struct card_config
|
||||
{
|
||||
struct card_config {
|
||||
struct card_config *next;
|
||||
unsigned char index;
|
||||
struct driver *driver;
|
||||
int irq;
|
||||
int flags;
|
||||
char inuse;
|
||||
};
|
||||
int irq;
|
||||
int flags;
|
||||
char inuse;
|
||||
};
|
||||
|
||||
struct card
|
||||
{
|
||||
struct card {
|
||||
struct card *next;
|
||||
char *manuf;
|
||||
char *version;
|
||||
int ether; /* For net cards, ether at offset */
|
||||
int reset_time; /* Reset time */
|
||||
char *manuf;
|
||||
char *version;
|
||||
int ether; /* For net cards, ether at offset */
|
||||
int reset_time; /* Reset time */
|
||||
struct card_config *config; /* List of configs */
|
||||
struct cmd *insert; /* Insert commands */
|
||||
struct cmd *remove; /* Remove commands */
|
||||
};
|
||||
};
|
||||
|
||||
struct driver
|
||||
{
|
||||
struct driver {
|
||||
struct driver *next;
|
||||
char *name;
|
||||
char *kernel; /* Kernel driver base name */
|
||||
int unit; /* Unit of driver */
|
||||
/*
|
||||
* The rest of the structure is allocated dynamically.
|
||||
* Once allocated, it stays allocated.
|
||||
*/
|
||||
char *name;
|
||||
char *kernel; /* Kernel driver base name */
|
||||
int unit; /* Unit of driver */
|
||||
/*
|
||||
* The rest of the structure is allocated dynamically.
|
||||
* Once allocated, it stays allocated.
|
||||
*/
|
||||
struct card *card; /* Current card, if any */
|
||||
struct card_config *config; /* Config back ptr */
|
||||
/* struct device *device;*/ /* System device info */
|
||||
unsigned int mem; /* Allocated host address (if any) */
|
||||
int inuse;
|
||||
};
|
||||
#if 0
|
||||
struct device
|
||||
{
|
||||
struct device *device; /* System device info */
|
||||
#endif
|
||||
unsigned int mem; /* Allocated host address (if any) */
|
||||
int inuse;
|
||||
};
|
||||
|
||||
#if 0
|
||||
struct device {
|
||||
struct device *next; /* List of devices */
|
||||
int inuse; /* Driver being used */
|
||||
int inuse; /* Driver being used */
|
||||
struct cmd *insert; /* Insert commands */
|
||||
struct cmd *remove; /* Remove commands */
|
||||
};
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Defines one allocation block i.e a starting address
|
||||
* and size. Used for either memory or I/O ports
|
||||
*/
|
||||
struct allocblk
|
||||
{
|
||||
struct allocblk {
|
||||
struct allocblk *next;
|
||||
int addr; /* Address */
|
||||
int size; /* Size */
|
||||
int flags; /* Flags for block */
|
||||
int cardaddr; /* Card address */
|
||||
};
|
||||
int addr; /* Address */
|
||||
int size; /* Size */
|
||||
int flags; /* Flags for block */
|
||||
int cardaddr; /* Card address */
|
||||
};
|
||||
/*
|
||||
* Slot structure - data held for each slot.
|
||||
*/
|
||||
struct slot
|
||||
{
|
||||
struct slot {
|
||||
struct slot *next;
|
||||
int fd;
|
||||
int mask;
|
||||
int slot;
|
||||
char *name;
|
||||
int fd;
|
||||
int mask;
|
||||
int slot;
|
||||
char *name;
|
||||
enum cardstate state;
|
||||
struct cis *cis;
|
||||
struct card *card; /* Current card */
|
||||
struct card_config *config; /* Current configuration */
|
||||
struct cis_config *card_config;
|
||||
char devname[16];
|
||||
char devname[16];
|
||||
unsigned char eaddr[6]; /* If any */
|
||||
struct allocblk io; /* I/O block spec */
|
||||
struct allocblk mem; /* Memory block spec */
|
||||
int irq; /* Irq value */
|
||||
};
|
||||
int irq; /* Irq value */
|
||||
};
|
||||
|
||||
struct slot *slots, *current_slot;
|
||||
|
||||
struct allocblk *pool_ioblks; /* I/O blocks in the pool */
|
||||
struct allocblk *pool_mem; /* Memory in the pool */
|
||||
int pool_irq[16]; /* IRQ allocations */
|
||||
struct driver *drivers; /* List of drivers */
|
||||
struct allocblk *pool_ioblks; /* I/O blocks in the pool */
|
||||
struct allocblk *pool_mem; /* Memory in the pool */
|
||||
int pool_irq[16]; /* IRQ allocations */
|
||||
struct driver *drivers; /* List of drivers */
|
||||
struct card *cards;
|
||||
/*struct device *devlist; */
|
||||
#if 0
|
||||
struct device *devlist;
|
||||
#endif
|
||||
bitstr_t *mem_avail;
|
||||
bitstr_t *io_avail;
|
||||
|
||||
int verbose, do_log;
|
||||
int verbose, do_log;
|
||||
|
||||
char *newstr();
|
||||
void die(char *);
|
||||
void *xmalloc(int);
|
||||
void log_1s(char *, char *);
|
||||
void logerr(char *);
|
||||
void reset_slot(struct slot *);
|
||||
void execute(struct cmd *);
|
||||
char *newstr();
|
||||
void die(char *);
|
||||
void *xmalloc(int);
|
||||
void log_1s(char *, char *);
|
||||
void logerr(char *);
|
||||
void reset_slot(struct slot *);
|
||||
void execute(struct cmd *);
|
||||
unsigned long alloc_memory(int size);
|
||||
int bit_fns(bitstr_t *nm, int nbits, int count);
|
||||
void readfile(char *name);
|
||||
int bit_fns(bitstr_t * nm, int nbits, int count);
|
||||
void readfile(char *name);
|
||||
|
||||
#define IOPORTS 0x400
|
||||
#define MEMUNIT 0x1000
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
/* set tab=4
|
||||
/*
|
||||
* Read/dump CIS tuples.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
@ -14,46 +14,45 @@
|
||||
|
||||
static int read_attr(int fd, char *bp, int len);
|
||||
struct tuple_list *read_one_tuplelist(int, int, off_t);
|
||||
int ck_linktarget(int, off_t, int);
|
||||
void cis_info(struct cis *cp, unsigned char *p, int len);
|
||||
void device_desc(unsigned char *p, int len, struct dev_mem *dp);
|
||||
void config_map(struct cis *cp, unsigned char *p, int len);
|
||||
void cis_config(struct cis *cp, unsigned char *p, int len);
|
||||
int ck_linktarget(int, off_t, int);
|
||||
void cis_info(struct cis *cp, unsigned char *p, int len);
|
||||
void device_desc(unsigned char *p, int len, struct dev_mem *dp);
|
||||
void config_map(struct cis *cp, unsigned char *p, int len);
|
||||
void cis_config(struct cis *cp, unsigned char *p, int len);
|
||||
|
||||
struct tuple_info tuple_info[] =
|
||||
{
|
||||
{ "Null tuple", 0x00, 0 },
|
||||
{ "Common memory descriptor", 0x01, 255 },
|
||||
{ "Checksum", 0x10, 5 },
|
||||
{ "Long link to attribute memory", 0x11, 4 },
|
||||
{ "Long link to common memory", 0x12, 4 },
|
||||
{ "Link target", 0x13, 3 },
|
||||
{ "No link", 0x14, 0 },
|
||||
{ "Version 1 info", 0x15, 255 },
|
||||
{ "Alternate language string", 0x16, 255 },
|
||||
{ "Attribute memory descriptor", 0x17, 255 },
|
||||
{ "JEDEC descr for common memory", 0x18, 255 },
|
||||
{ "JEDEC descr for attribute memory", 0x19, 255 },
|
||||
{ "Configuration map", 0x1A, 255 },
|
||||
{ "Configuration entry", 0x1B, 255 },
|
||||
{ "Other conditions for common memory", 0x1C, 255 },
|
||||
{ "Other conditions for attribute memory", 0x1D, 255 },
|
||||
{ "Geometry info for common memory", 0x1E, 255 },
|
||||
{ "Geometry info for attribute memory", 0x1F, 255 },
|
||||
{ "Manufacturer ID", 0x20, 4 },
|
||||
{ "Functional ID", 0x21, 255 },
|
||||
{ "Functional EXT", 0x22, 255 },
|
||||
{ "Software interleave", 0x23, 2 },
|
||||
{ "Version 2 Info", 0x40, 255 },
|
||||
{ "Data format", 0x41, 255 },
|
||||
{ "Geometry", 0x42, 4 },
|
||||
{ "Byte order", 0x43, 2 },
|
||||
{ "Card init date", 0x44, 4 },
|
||||
{ "Battery replacement", 0x45, 4 },
|
||||
{ "Organisation", 0x46, 255 },
|
||||
{ "Terminator", 0xFF, 255 },
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
struct tuple_info tuple_info[] = {
|
||||
{"Null tuple", 0x00, 0},
|
||||
{"Common memory descriptor", 0x01, 255},
|
||||
{"Checksum", 0x10, 5},
|
||||
{"Long link to attribute memory", 0x11, 4},
|
||||
{"Long link to common memory", 0x12, 4},
|
||||
{"Link target", 0x13, 3},
|
||||
{"No link", 0x14, 0},
|
||||
{"Version 1 info", 0x15, 255},
|
||||
{"Alternate language string", 0x16, 255},
|
||||
{"Attribute memory descriptor", 0x17, 255},
|
||||
{"JEDEC descr for common memory", 0x18, 255},
|
||||
{"JEDEC descr for attribute memory", 0x19, 255},
|
||||
{"Configuration map", 0x1A, 255},
|
||||
{"Configuration entry", 0x1B, 255},
|
||||
{"Other conditions for common memory", 0x1C, 255},
|
||||
{"Other conditions for attribute memory", 0x1D, 255},
|
||||
{"Geometry info for common memory", 0x1E, 255},
|
||||
{"Geometry info for attribute memory", 0x1F, 255},
|
||||
{"Manufacturer ID", 0x20, 4},
|
||||
{"Functional ID", 0x21, 255},
|
||||
{"Functional EXT", 0x22, 255},
|
||||
{"Software interleave", 0x23, 2},
|
||||
{"Version 2 Info", 0x40, 255},
|
||||
{"Data format", 0x41, 255},
|
||||
{"Geometry", 0x42, 4},
|
||||
{"Byte order", 0x43, 2},
|
||||
{"Card init date", 0x44, 4},
|
||||
{"Battery replacement", 0x45, 4},
|
||||
{"Organisation", 0x46, 255},
|
||||
{"Terminator", 0xFF, 255},
|
||||
{0, 0, 0}
|
||||
};
|
||||
|
||||
/*
|
||||
* After reading the tuples, decode the relevant ones.
|
||||
@ -61,83 +60,78 @@ struct tuple_info tuple_info[] =
|
||||
struct cis *
|
||||
readcis(int fd)
|
||||
{
|
||||
struct tuple_list *tl;
|
||||
struct tuple *tp;
|
||||
struct cis *cp;
|
||||
struct tuple_list *tl;
|
||||
struct tuple *tp;
|
||||
struct cis *cp;
|
||||
|
||||
cp = xmalloc(sizeof(*cp));
|
||||
cp->tlist = read_tuples(fd);
|
||||
if (cp->tlist == 0)
|
||||
return(NULL);
|
||||
return (NULL);
|
||||
|
||||
for (tl = cp->tlist; tl; tl = tl->next)
|
||||
for (tp = tl->tuples; tp; tp = tp->next)
|
||||
{
|
||||
for (tp = tl->tuples; tp; tp = tp->next) {
|
||||
#if 0
|
||||
printf("tuple code = 0x%02x, data is\n", tp->code);
|
||||
dump(tp->data, tp->length);
|
||||
printf("tuple code = 0x%02x, data is\n", tp->code);
|
||||
dump(tp->data, tp->length);
|
||||
#endif
|
||||
switch(tp->code)
|
||||
{
|
||||
case CIS_MEM_COMMON: /* 0x01 */
|
||||
device_desc(tp->data, tp->length, &cp->common_mem);
|
||||
break;
|
||||
case CIS_INFO_V1: /* 0x15 */
|
||||
cis_info(cp, tp->data, tp->length);
|
||||
break;
|
||||
case CIS_MEM_ATTR: /* 0x17 */
|
||||
device_desc(tp->data, tp->length, &cp->attr_mem);
|
||||
break;
|
||||
case CIS_CONF_MAP: /* 0x1A */
|
||||
config_map(cp, tp->data, tp->length);
|
||||
break;
|
||||
case CIS_CONFIG: /* 0x1B */
|
||||
cis_config(cp, tp->data, tp->length);
|
||||
break;
|
||||
switch (tp->code) {
|
||||
case CIS_MEM_COMMON: /* 0x01 */
|
||||
device_desc(tp->data, tp->length, &cp->common_mem);
|
||||
break;
|
||||
case CIS_INFO_V1: /* 0x15 */
|
||||
cis_info(cp, tp->data, tp->length);
|
||||
break;
|
||||
case CIS_MEM_ATTR: /* 0x17 */
|
||||
device_desc(tp->data, tp->length, &cp->attr_mem);
|
||||
break;
|
||||
case CIS_CONF_MAP: /* 0x1A */
|
||||
config_map(cp, tp->data, tp->length);
|
||||
break;
|
||||
case CIS_CONFIG: /* 0x1B */
|
||||
cis_config(cp, tp->data, tp->length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return(cp);
|
||||
return (cp);
|
||||
}
|
||||
|
||||
/*
|
||||
* free_cis - delete cis entry.
|
||||
*/
|
||||
void
|
||||
freecis(struct cis *cp)
|
||||
{
|
||||
struct cis_ioblk *io;
|
||||
struct cis_memblk *mem;
|
||||
struct cis_config *conf;
|
||||
struct tuple *tp;
|
||||
struct tuple_list *tl;
|
||||
struct cis_ioblk *io;
|
||||
struct cis_memblk *mem;
|
||||
struct cis_config *conf;
|
||||
struct tuple *tp;
|
||||
struct tuple_list *tl;
|
||||
|
||||
while ((tl = cp->tlist) != 0)
|
||||
{
|
||||
while ((tl = cp->tlist) != 0) {
|
||||
cp->tlist = tl->next;
|
||||
while ((tp = tl->tuples) != 0)
|
||||
{
|
||||
while ((tp = tl->tuples) != 0) {
|
||||
tl->tuples = tp->next;
|
||||
if (tp->data)
|
||||
free(tp->data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while ((conf = cp->conf) != 0)
|
||||
{
|
||||
while ((conf = cp->conf) != 0) {
|
||||
cp->conf = conf->next;
|
||||
while ((io = conf->io) != 0)
|
||||
{
|
||||
while ((io = conf->io) != 0) {
|
||||
conf->io = io->next;
|
||||
free(io);
|
||||
}
|
||||
while ((mem = conf->mem) != 0)
|
||||
{
|
||||
}
|
||||
while ((mem = conf->mem) != 0) {
|
||||
conf->mem = mem->next;
|
||||
free(mem);
|
||||
}
|
||||
free(conf);
|
||||
}
|
||||
free(conf);
|
||||
}
|
||||
free(cp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fills in CIS version data.
|
||||
*/
|
||||
@ -146,85 +140,81 @@ cis_info(struct cis *cp, unsigned char *p, int len)
|
||||
{
|
||||
cp->maj_v = *p++;
|
||||
cp->min_v = *p++;
|
||||
strncpy(cp->manuf, p, MAXSTR-1);
|
||||
while (*p++)
|
||||
;
|
||||
strncpy(cp->vers, p, MAXSTR-1);
|
||||
while (*p++)
|
||||
;
|
||||
strncpy(cp->add_info1, p, MAXSTR-1);
|
||||
while (*p++)
|
||||
;
|
||||
strncpy(cp->add_info2, p, MAXSTR-1);
|
||||
strncpy(cp->manuf, p, MAXSTR - 1);
|
||||
while (*p++);
|
||||
strncpy(cp->vers, p, MAXSTR - 1);
|
||||
while (*p++);
|
||||
strncpy(cp->add_info1, p, MAXSTR - 1);
|
||||
while (*p++);
|
||||
strncpy(cp->add_info2, p, MAXSTR - 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* device_desc - decode device descriptor.
|
||||
*/
|
||||
void
|
||||
device_desc(unsigned char *p, int len, struct dev_mem *dp)
|
||||
{
|
||||
while (len > 0 && *p != 0xFF)
|
||||
{
|
||||
while (len > 0 && *p != 0xFF) {
|
||||
dp->valid = 1;
|
||||
dp->type = (*p & 0xF0) >> 4;
|
||||
dp->wps = !!(*p & 0x8);
|
||||
dp->speed = *p & 7;
|
||||
p++;
|
||||
if (*p != 0xFF)
|
||||
{
|
||||
if (*p != 0xFF) {
|
||||
dp->addr = *p >> 3;
|
||||
dp->units = *p & 7;
|
||||
}
|
||||
}
|
||||
p++;
|
||||
len -= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* configuration map of card control register.
|
||||
*/
|
||||
void
|
||||
config_map(struct cis *cp, unsigned char *p, int len)
|
||||
{
|
||||
unsigned char *p1;
|
||||
int i;
|
||||
union {
|
||||
unsigned long l;
|
||||
unsigned char b[4];
|
||||
}u;
|
||||
unsigned char *p1;
|
||||
int i;
|
||||
union {
|
||||
unsigned long l;
|
||||
unsigned char b[4];
|
||||
} u;
|
||||
|
||||
p1 = p + 1;
|
||||
cp->last_config = *p1++ & 0x3F;
|
||||
u.l = 0;
|
||||
for (i = 0 ; i <= (*p & 3); i++)
|
||||
for (i = 0; i <= (*p & 3); i++)
|
||||
u.b[i] = *p1++;
|
||||
cp->reg_addr = u.l;
|
||||
cp->ccrs = *p1;
|
||||
}
|
||||
|
||||
/*
|
||||
* CIS config entry - Decode and build configuration entry.
|
||||
*/
|
||||
void
|
||||
cis_config(struct cis *cp, unsigned char *p, int len)
|
||||
{
|
||||
int x;
|
||||
int i, j;
|
||||
union {
|
||||
unsigned long l;
|
||||
unsigned char b[4];
|
||||
}u;
|
||||
struct cis_config *conf, *last;
|
||||
struct cis_memblk *mem;
|
||||
unsigned char feat;
|
||||
struct cis_memblk *lastmem = 0;
|
||||
int x;
|
||||
int i, j;
|
||||
union {
|
||||
unsigned long l;
|
||||
unsigned char b[4];
|
||||
} u;
|
||||
struct cis_config *conf, *last;
|
||||
struct cis_memblk *mem;
|
||||
unsigned char feat;
|
||||
struct cis_memblk *lastmem = 0;
|
||||
|
||||
conf = xmalloc(sizeof(*conf));
|
||||
if ((last = cp->conf) !=0)
|
||||
{
|
||||
if ((last = cp->conf) != 0) {
|
||||
while (last->next)
|
||||
last = last->next;
|
||||
last->next = conf;
|
||||
}
|
||||
else
|
||||
} else
|
||||
cp->conf = conf;
|
||||
conf->id = *p & 0x3F;
|
||||
if (*p & 0x40)
|
||||
@ -232,18 +222,15 @@ struct cis_memblk *lastmem = 0;
|
||||
if (*p++ & 0x80)
|
||||
p++;
|
||||
feat = *p++;
|
||||
for (i = 0; i < CIS_FEAT_POWER(feat); i++)
|
||||
{
|
||||
for (i = 0; i < CIS_FEAT_POWER(feat); i++) {
|
||||
unsigned char parms = *p++;
|
||||
|
||||
conf->pwr = 1;
|
||||
for (j = 0; j < 8; j++)
|
||||
if (parms & (1 << j))
|
||||
while (*p++ & 0x80)
|
||||
;
|
||||
}
|
||||
if (feat & CIS_FEAT_TIMING)
|
||||
{
|
||||
while (*p++ & 0x80);
|
||||
}
|
||||
if (feat & CIS_FEAT_TIMING) {
|
||||
conf->timing = 1;
|
||||
i = *p++;
|
||||
if (CIS_WAIT_SCALE(i) != 3)
|
||||
@ -252,21 +239,18 @@ struct cis_memblk *lastmem = 0;
|
||||
p++;
|
||||
if (CIS_RESERVED_SCALE(i) != 7)
|
||||
p++;
|
||||
}
|
||||
if (feat & CIS_FEAT_I_O)
|
||||
{
|
||||
}
|
||||
if (feat & CIS_FEAT_I_O) {
|
||||
conf->iospace = 1;
|
||||
if (CIS_IO_RANGE & *p)
|
||||
conf->io_blks = CIS_IO_BLKS(p[1])+1;
|
||||
conf->io_blks = CIS_IO_BLKS(p[1]) + 1;
|
||||
conf->io_addr = CIS_IO_ADDR(*p);
|
||||
conf->io_bus = (*p >> 5) & 3;
|
||||
if (*p++ & CIS_IO_RANGE)
|
||||
{
|
||||
if (*p++ & CIS_IO_RANGE) {
|
||||
struct cis_ioblk *io, *last = 0;
|
||||
i = CIS_IO_ADSZ(*p);
|
||||
j = CIS_IO_BLKSZ(*p++);
|
||||
for (x = 0; x < conf->io_blks; x++)
|
||||
{
|
||||
for (x = 0; x < conf->io_blks; x++) {
|
||||
io = xmalloc(sizeof(*io));
|
||||
if (last)
|
||||
last->next = io;
|
||||
@ -274,8 +258,7 @@ struct cis_memblk *lastmem = 0;
|
||||
conf->io = io;
|
||||
last = io;
|
||||
u.l = 0;
|
||||
switch(i)
|
||||
{
|
||||
switch (i) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
@ -291,11 +274,10 @@ struct cis_memblk *lastmem = 0;
|
||||
u.b[2] = *p++;
|
||||
u.b[3] = *p++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
io->addr = u.l;
|
||||
u.l = 0;
|
||||
switch(j)
|
||||
{
|
||||
switch (j) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
@ -314,30 +296,27 @@ struct cis_memblk *lastmem = 0;
|
||||
u.b[3] = *p++;
|
||||
u.l++;
|
||||
break;
|
||||
}
|
||||
io->size = u.l;
|
||||
}
|
||||
io->size = u.l;
|
||||
}
|
||||
}
|
||||
if (feat & CIS_FEAT_IRQ)
|
||||
{
|
||||
}
|
||||
if (feat & CIS_FEAT_IRQ) {
|
||||
conf->irq = 1;
|
||||
conf->irqlevel = *p & 0xF;
|
||||
conf->irq_flags = *p & 0xF0;
|
||||
if (*p++ & CIS_IRQ_MASK)
|
||||
{
|
||||
if (*p++ & CIS_IRQ_MASK) {
|
||||
conf->irq_mask = (p[1] << 8) | p[0];
|
||||
p += 2;
|
||||
}
|
||||
}
|
||||
switch(CIS_FEAT_MEMORY(feat))
|
||||
{
|
||||
}
|
||||
switch (CIS_FEAT_MEMORY(feat)) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
conf->memspace = 1;
|
||||
conf->mem = xmalloc(sizeof(*conf->mem));
|
||||
conf->mem->length = ((p[1] << 8) | p[0])<<8;
|
||||
conf->mem->length = ((p[1] << 8) | p[0]) << 8;
|
||||
break;
|
||||
case 2:
|
||||
conf->memspace = 1;
|
||||
@ -349,8 +328,7 @@ struct cis_memblk *lastmem = 0;
|
||||
conf->memspace = 1;
|
||||
x = *p++;
|
||||
conf->memwins = CIS_MEM_WINS(x);
|
||||
for (i = 0; i < conf->memwins; i++)
|
||||
{
|
||||
for (i = 0; i < conf->memwins; i++) {
|
||||
mem = xmalloc(sizeof(*mem));
|
||||
if (i == 0)
|
||||
conf->mem = mem;
|
||||
@ -358,29 +336,28 @@ struct cis_memblk *lastmem = 0;
|
||||
lastmem->next = mem;
|
||||
lastmem = mem;
|
||||
u.l = 0;
|
||||
for (j = 0 ; j < CIS_MEM_LENSZ(x); j++)
|
||||
for (j = 0; j < CIS_MEM_LENSZ(x); j++)
|
||||
u.b[j] = *p++;
|
||||
mem->length = u.l << 8;
|
||||
u.l = 0;
|
||||
for (j = 0 ; j < CIS_MEM_ADDRSZ(x); j++)
|
||||
for (j = 0; j < CIS_MEM_ADDRSZ(x); j++)
|
||||
u.b[j] = *p++;
|
||||
mem->address = u.l << 8;
|
||||
if (x & CIS_MEM_HOST)
|
||||
{
|
||||
if (x & CIS_MEM_HOST) {
|
||||
u.l = 0;
|
||||
for (j = 0 ; j < CIS_MEM_ADDRSZ(x); j++)
|
||||
for (j = 0; j < CIS_MEM_ADDRSZ(x); j++)
|
||||
u.b[j] = *p++;
|
||||
mem->host_address = u.l << 8;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (feat & 0x80)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (feat & 0x80) {
|
||||
conf->misc_valid = 1;
|
||||
conf->misc = *p++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the tuples from the card.
|
||||
* The processing of tuples is as follows:
|
||||
@ -402,173 +379,163 @@ static struct tuple_list *tlist;
|
||||
struct tuple_list *
|
||||
read_tuples(int fd)
|
||||
{
|
||||
struct tuple_list *tl = 0, *last_tl;
|
||||
struct tuple *tp;
|
||||
int flag;
|
||||
off_t offs;
|
||||
struct tuple_list *tl = 0, *last_tl;
|
||||
struct tuple *tp;
|
||||
int flag;
|
||||
off_t offs;
|
||||
|
||||
tlist = 0;
|
||||
last_tl = tlist = read_one_tuplelist(fd, MDF_ATTR, (off_t)0);
|
||||
/*
|
||||
* Now start processing the links (if any).
|
||||
*/
|
||||
do
|
||||
{
|
||||
last_tl = tlist = read_one_tuplelist(fd, MDF_ATTR, (off_t) 0);
|
||||
|
||||
/* Now start processing the links (if any). */
|
||||
do {
|
||||
flag = MDF_ATTR;
|
||||
tp = find_tuple_in_list(last_tl, CIS_LONGLINK_A);
|
||||
if (tp == 0)
|
||||
{
|
||||
if (tp == 0) {
|
||||
flag = 0;
|
||||
tp = find_tuple_in_list(last_tl, CIS_LONGLINK_C);
|
||||
}
|
||||
if (tp && tp->length == 4)
|
||||
{
|
||||
}
|
||||
if (tp && tp->length == 4) {
|
||||
offs = tp->data[0] |
|
||||
(tp->data[1] << 8) |
|
||||
(tp->data[2] << 16) |
|
||||
(tp->data[3] << 24);
|
||||
(tp->data[1] << 8) |
|
||||
(tp->data[2] << 16) |
|
||||
(tp->data[3] << 24);
|
||||
#ifdef DEBUG
|
||||
printf("Checking long link at %ld (%s memory)\n",
|
||||
offs, flag ? "Attribute" : "Common");
|
||||
offs, flag ? "Attribute" : "Common");
|
||||
#endif
|
||||
if (ck_linktarget(fd, offs, flag))
|
||||
{
|
||||
/*
|
||||
* If a link was found, then read the tuple list from it.
|
||||
*/
|
||||
/* If a link was found, read the tuple list from it. */
|
||||
if (ck_linktarget(fd, offs, flag)) {
|
||||
tl = read_one_tuplelist(fd, flag, offs);
|
||||
last_tl->next = tl;
|
||||
last_tl = tl;
|
||||
}
|
||||
}
|
||||
} while (tl);
|
||||
/*
|
||||
* If the primary list had no NOLINK tuple, and no LINKTARGET,
|
||||
* then try to read a tuple list at common memory (offset 0).
|
||||
*/
|
||||
if (find_tuple_in_list(tlist, CIS_NOLINK)==0 && tlist->next == 0 &&
|
||||
ck_linktarget(fd, (off_t)0, 0))
|
||||
{
|
||||
}
|
||||
} while (tl);
|
||||
|
||||
/*
|
||||
* If the primary list had no NOLINK tuple, and no LINKTARGET,
|
||||
* then try to read a tuple list at common memory (offset 0).
|
||||
*/
|
||||
if (find_tuple_in_list(tlist, CIS_NOLINK) == 0 && tlist->next == 0 &&
|
||||
ck_linktarget(fd, (off_t) 0, 0)) {
|
||||
#ifdef DEBUG
|
||||
printf("Reading long link at %ld (%s memory)\n",
|
||||
offs, flag ? "Attribute" : "Common");
|
||||
offs, flag ? "Attribute" : "Common");
|
||||
#endif
|
||||
tlist->next = read_one_tuplelist(fd, 0, (off_t)0);
|
||||
}
|
||||
return(tlist);
|
||||
tlist->next = read_one_tuplelist(fd, 0, (off_t) 0);
|
||||
}
|
||||
return (tlist);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read one tuple list from the card.
|
||||
*/
|
||||
struct tuple_list *
|
||||
read_one_tuplelist(int fd, int flags, off_t offs)
|
||||
{
|
||||
struct tuple *tp, *last_tp = 0;
|
||||
struct tuple_list *tl;
|
||||
struct tuple_info *tinfo;
|
||||
int total = 0;
|
||||
unsigned char code, length;
|
||||
struct tuple *tp, *last_tp = 0;
|
||||
struct tuple_list *tl;
|
||||
struct tuple_info *tinfo;
|
||||
int total = 0;
|
||||
unsigned char code, length;
|
||||
|
||||
/*
|
||||
* Check to see if this memory has already been scanned.
|
||||
*/
|
||||
/* Check to see if this memory has already been scanned. */
|
||||
for (tl = tlist; tl; tl = tl->next)
|
||||
if (tl->offs == offs && tl->flags == (flags & MDF_ATTR))
|
||||
return(0);
|
||||
return (0);
|
||||
tl = xmalloc(sizeof(*tl));
|
||||
tl->offs = offs;
|
||||
tl->flags = flags & MDF_ATTR;
|
||||
ioctl(fd, PIOCRWFLAG, &flags);
|
||||
lseek(fd, offs, SEEK_SET);
|
||||
do {
|
||||
if (read_attr(fd, &code, 1) != 1)
|
||||
{
|
||||
do {
|
||||
if (read_attr(fd, &code, 1) != 1) {
|
||||
perror("CIS code read");
|
||||
break;
|
||||
}
|
||||
}
|
||||
total++;
|
||||
if (code == CIS_NULL)
|
||||
continue;
|
||||
tp = xmalloc(sizeof(*tp));
|
||||
tp->code = code;
|
||||
if (read_attr(fd, &length, 1) != 1)
|
||||
{
|
||||
if (read_attr(fd, &length, 1) != 1) {
|
||||
perror("CIS len read");
|
||||
break;
|
||||
}
|
||||
}
|
||||
total++;
|
||||
tp->length = length;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Tuple code = 0x%x, len = %d\n",
|
||||
code, length);
|
||||
code, length);
|
||||
#endif
|
||||
if (length == 0xFF)
|
||||
{
|
||||
if (length == 0xFF) {
|
||||
length = tp->length = 0;
|
||||
code = CIS_END;
|
||||
}
|
||||
if (length != 0)
|
||||
{
|
||||
}
|
||||
if (length != 0) {
|
||||
total += length;
|
||||
tp->data = xmalloc(length);
|
||||
if (read_attr(fd, tp->data, length) != length)
|
||||
{
|
||||
if (read_attr(fd, tp->data, length) != length) {
|
||||
perror("CIS read");
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Check the tuple, and ignore it if it isn't in the table
|
||||
* or the length is illegal.
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the tuple, and ignore it if it isn't in the table
|
||||
* or the length is illegal.
|
||||
*/
|
||||
tinfo = get_tuple_info(code);
|
||||
if (tinfo == 0 || (tinfo->length != 255 && tinfo->length != length))
|
||||
{
|
||||
if (tinfo == 0 || (tinfo->length != 255 && tinfo->length != length)) {
|
||||
printf("code %s ignored\n", tuple_name(code));
|
||||
tp->code = CIS_NULL;
|
||||
}
|
||||
if (tl->tuples==0)
|
||||
}
|
||||
if (tl->tuples == 0)
|
||||
tl->tuples = tp;
|
||||
else
|
||||
last_tp->next = tp;
|
||||
last_tp = tp;
|
||||
} while (code != CIS_END && total < 1024);
|
||||
return(tl);
|
||||
} while (code != CIS_END && total < 1024);
|
||||
return (tl);
|
||||
}
|
||||
|
||||
/*
|
||||
* return true if the offset points to a LINKTARGET tuple.
|
||||
*/
|
||||
int
|
||||
ck_linktarget(int fd, off_t offs, int flag)
|
||||
{
|
||||
char blk[5];
|
||||
char blk[5];
|
||||
|
||||
ioctl(fd, PIOCRWFLAG, &flag);
|
||||
lseek(fd, offs, SEEK_SET);
|
||||
if (read_attr(fd, blk, 5) != 5)
|
||||
return(0);
|
||||
return (0);
|
||||
if (blk[0] == 0x13 &&
|
||||
blk[1] == 0x3 &&
|
||||
blk[2] == 'C' &&
|
||||
blk[3] == 'I' &&
|
||||
blk[4] == 'S')
|
||||
return(1);
|
||||
return(0);
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* find_tuple - find the indicated tuple in the CIS
|
||||
*/
|
||||
struct tuple *
|
||||
find_tuple(struct cis *sp, unsigned char code)
|
||||
{
|
||||
struct tuple_list *tl;
|
||||
struct tuple *tp;
|
||||
struct tuple_list *tl;
|
||||
struct tuple *tp;
|
||||
|
||||
for (tl = sp->tlist; tl; tl = tl->next)
|
||||
if ((tp = find_tuple_in_list(tl, code)) != 0)
|
||||
return(tp);
|
||||
return(0);
|
||||
return (tp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* find_tuple_in_list - find a tuple within a
|
||||
* single tuple list.
|
||||
@ -576,56 +543,57 @@ struct tuple *tp;
|
||||
struct tuple *
|
||||
find_tuple_in_list(struct tuple_list *tl, unsigned char code)
|
||||
{
|
||||
struct tuple *tp;
|
||||
struct tuple *tp;
|
||||
|
||||
for (tp = tl->tuples; tp; tp = tp->next)
|
||||
if (tp->code == code)
|
||||
break;
|
||||
return(tp);
|
||||
return (tp);
|
||||
}
|
||||
|
||||
static int
|
||||
read_attr(int fd, char *bp, int len)
|
||||
{
|
||||
char blk[1024], *p = blk;
|
||||
int i,l;
|
||||
char blk[1024], *p = blk;
|
||||
int i, l;
|
||||
|
||||
if (len > sizeof(blk)/2)
|
||||
len = sizeof(blk)/2;
|
||||
l = i = read(fd, blk, len*2);
|
||||
if (i <= 0)
|
||||
{
|
||||
printf("Read return %d bytes (expected %d)\n", i, len*2);
|
||||
return(i);
|
||||
}
|
||||
while (i > 0)
|
||||
{
|
||||
if (len > sizeof(blk) / 2)
|
||||
len = sizeof(blk) / 2;
|
||||
l = i = read(fd, blk, len * 2);
|
||||
if (i <= 0) {
|
||||
printf("Read return %d bytes (expected %d)\n", i, len * 2);
|
||||
return (i);
|
||||
}
|
||||
while (i > 0) {
|
||||
*bp++ = *p++;
|
||||
p++;
|
||||
i -= 2;
|
||||
}
|
||||
return(l/2);
|
||||
}
|
||||
return (l / 2);
|
||||
}
|
||||
|
||||
/*
|
||||
* return table entry for code.
|
||||
*/
|
||||
struct tuple_info *
|
||||
get_tuple_info(unsigned char code)
|
||||
{
|
||||
struct tuple_info *tp;
|
||||
struct tuple_info *tp;
|
||||
|
||||
for (tp = tuple_info; tp->name; tp++)
|
||||
if (tp->code == code)
|
||||
return(tp);
|
||||
return (tp);
|
||||
printf("Code %d not found\n", code);
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
char *
|
||||
|
||||
char *
|
||||
tuple_name(unsigned char code)
|
||||
{
|
||||
struct tuple_info *tp;
|
||||
struct tuple_info *tp;
|
||||
|
||||
tp = get_tuple_info(code);
|
||||
if (tp)
|
||||
return(tp->name);
|
||||
return("Unknown");
|
||||
return (tp->name);
|
||||
return ("Unknown");
|
||||
}
|
||||
|
@ -1,67 +1,63 @@
|
||||
|
||||
#define MAXSTR 20
|
||||
/*
|
||||
* Storage of one tuple.
|
||||
*/
|
||||
struct tuple
|
||||
{
|
||||
struct tuple {
|
||||
struct tuple *next;
|
||||
unsigned char code;
|
||||
int length;
|
||||
int length;
|
||||
unsigned char *data;
|
||||
};
|
||||
};
|
||||
|
||||
struct tuple_list
|
||||
{
|
||||
struct tuple_list {
|
||||
struct tuple_list *next;
|
||||
struct tuple *tuples;
|
||||
off_t offs;
|
||||
int flags;
|
||||
};
|
||||
off_t offs;
|
||||
int flags;
|
||||
};
|
||||
|
||||
struct tuple_info
|
||||
{
|
||||
char *name;
|
||||
struct tuple_info {
|
||||
char *name;
|
||||
unsigned char code;
|
||||
unsigned char length; /* 255 means variable length */
|
||||
};
|
||||
unsigned char length; /* 255 means variable length */
|
||||
};
|
||||
|
||||
/*
|
||||
* Memory device descriptor.
|
||||
*/
|
||||
struct dev_mem
|
||||
{
|
||||
struct dev_mem {
|
||||
unsigned char valid;
|
||||
unsigned char type;
|
||||
unsigned char speed;
|
||||
unsigned char wps;
|
||||
unsigned char addr;
|
||||
unsigned char units;
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* One I/O structure describing a possible I/O map
|
||||
* of the card.
|
||||
*/
|
||||
struct cis_ioblk
|
||||
{
|
||||
struct cis_ioblk {
|
||||
struct cis_ioblk *next;
|
||||
unsigned int addr;
|
||||
unsigned int size;
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* A structure storing a memory map for the card.
|
||||
*/
|
||||
struct cis_memblk
|
||||
{
|
||||
struct cis_memblk {
|
||||
struct cis_memblk *next;
|
||||
unsigned int address;
|
||||
unsigned int length;
|
||||
unsigned int host_address;
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* One configuration entry for the card.
|
||||
*/
|
||||
struct cis_config
|
||||
{
|
||||
struct cis_config {
|
||||
struct cis_config *next;
|
||||
unsigned int pwr:1; /* Which values are defined. */
|
||||
unsigned int timing:1;
|
||||
@ -80,20 +76,20 @@ struct cis_config
|
||||
unsigned char memwins;
|
||||
struct cis_memblk *mem;
|
||||
unsigned char misc;
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure holding all data retrieved from the
|
||||
* CIS block on the card.
|
||||
* The default configuration contains interface defaults
|
||||
* not listed in each separate configuration.
|
||||
*/
|
||||
struct cis
|
||||
{
|
||||
struct cis {
|
||||
struct tuple_list *tlist;
|
||||
char manuf[MAXSTR];
|
||||
char vers[MAXSTR];
|
||||
char add_info1[MAXSTR];
|
||||
char add_info2[MAXSTR];
|
||||
char manuf[MAXSTR];
|
||||
char vers[MAXSTR];
|
||||
char add_info1[MAXSTR];
|
||||
char add_info2[MAXSTR];
|
||||
unsigned char maj_v, min_v;
|
||||
unsigned char last_config;
|
||||
unsigned char ccrs;
|
||||
@ -102,15 +98,15 @@ struct cis
|
||||
struct dev_mem common_mem;
|
||||
struct cis_config *def_config;
|
||||
struct cis_config *conf;
|
||||
};
|
||||
};
|
||||
|
||||
void *xmalloc(int);
|
||||
void *xmalloc(int);
|
||||
struct cis *readcis(int);
|
||||
void dumpcis(struct cis *);
|
||||
void freecis(struct cis *);
|
||||
void dumpcis(struct cis *);
|
||||
void freecis(struct cis *);
|
||||
struct tuple_list *read_tuples(int);
|
||||
struct tuple *find_tuple(struct cis *, unsigned char);
|
||||
struct tuple *find_tuple_in_list(struct tuple_list *, unsigned char);
|
||||
|
||||
struct tuple_info *get_tuple_info(unsigned char);
|
||||
char *tuple_name(unsigned char);
|
||||
char *tuple_name(unsigned char);
|
||||
|
@ -18,13 +18,13 @@ log_1s(char *msg, char *arg)
|
||||
{
|
||||
if (do_log)
|
||||
syslog(LOG_ERR, msg, arg);
|
||||
else
|
||||
{
|
||||
else {
|
||||
fprintf(stderr, "cardd: ");
|
||||
fprintf(stderr, msg, arg);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
logerr(char *msg)
|
||||
{
|
||||
@ -33,6 +33,7 @@ logerr(char *msg)
|
||||
else
|
||||
perror(msg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Deliver last will and testament, and die.
|
||||
*/
|
||||
@ -47,29 +48,30 @@ die(char *msg)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void *
|
||||
void *
|
||||
xmalloc(int sz)
|
||||
{
|
||||
void *p;
|
||||
void *p;
|
||||
|
||||
p = malloc(sz);
|
||||
if (p)
|
||||
bzero(p, sz);
|
||||
else
|
||||
die("malloc failed");
|
||||
return(p);
|
||||
return (p);
|
||||
}
|
||||
|
||||
char *
|
||||
char *
|
||||
newstr(char *p)
|
||||
{
|
||||
char *s;
|
||||
char *s;
|
||||
|
||||
s = strdup(p);
|
||||
if (s == 0)
|
||||
die("strdup failed");
|
||||
return(s);
|
||||
return (s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find contiguous bit string (all set) of at
|
||||
* least count number.
|
||||
@ -77,33 +79,33 @@ char *s;
|
||||
int
|
||||
bit_fns(bitstr_t *nm, int nbits, int count)
|
||||
{
|
||||
int i;
|
||||
int found = 0;
|
||||
int i;
|
||||
int found = 0;
|
||||
|
||||
for (i = 0; i < nbits; i++)
|
||||
if (bit_test(nm, i))
|
||||
{
|
||||
if (bit_test(nm, i)) {
|
||||
if (++found == count)
|
||||
return(i - count + 1);
|
||||
}
|
||||
else
|
||||
return (i - count + 1);
|
||||
} else
|
||||
found = 0;
|
||||
return(-1);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a block of memory and return the address.
|
||||
*/
|
||||
unsigned long
|
||||
alloc_memory(int size)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
i = bit_fns(mem_avail, MEMBLKS, size/MEMUNIT);
|
||||
i = bit_fns(mem_avail, MEMBLKS, size / MEMUNIT);
|
||||
if (i < 0)
|
||||
return(0);
|
||||
bit_nclear(mem_avail, i, size/MEMUNIT);
|
||||
return(BIT2MEM(i));
|
||||
return (0);
|
||||
bit_nclear(mem_avail, i, size / MEMUNIT);
|
||||
return (BIT2MEM(i));
|
||||
}
|
||||
|
||||
/*
|
||||
* reset_slot - Power has been applied to the card.
|
||||
* Now reset the card.
|
||||
@ -111,36 +113,36 @@ int i;
|
||||
void
|
||||
reset_slot(struct slot *sp)
|
||||
{
|
||||
char c;
|
||||
off_t offs;
|
||||
struct mem_desc mem;
|
||||
struct io_desc io;
|
||||
int rw_flags;
|
||||
char c;
|
||||
off_t offs;
|
||||
struct mem_desc mem;
|
||||
struct io_desc io;
|
||||
int rw_flags;
|
||||
|
||||
rw_flags = MDF_ATTR;
|
||||
ioctl(sp->fd, PIOCRWFLAG, &rw_flags);
|
||||
#ifdef DEBUG
|
||||
printf("Resetting card, writing 0x80 to offs 0x%x\n",
|
||||
sp->cis->reg_addr);
|
||||
sp->cis->reg_addr);
|
||||
#endif
|
||||
offs = sp->cis->reg_addr;
|
||||
lseek(sp->fd, offs, SEEK_SET);
|
||||
c = 0x80;
|
||||
write(sp->fd, &c, sizeof(c));
|
||||
usleep(10*1000);
|
||||
usleep(10 * 1000);
|
||||
c = 0;
|
||||
lseek(sp->fd, offs, SEEK_SET);
|
||||
write(sp->fd, &c, sizeof(c));
|
||||
/*
|
||||
* Reset all the memory and I/O windows.
|
||||
*/
|
||||
bzero((caddr_t)&mem, sizeof(mem));
|
||||
bzero((caddr_t)&io, sizeof(io));
|
||||
|
||||
/* Reset all the memory and I/O windows. */
|
||||
bzero((caddr_t) & mem, sizeof(mem));
|
||||
bzero((caddr_t) & io, sizeof(io));
|
||||
for (mem.window = 0; mem.window < NUM_MEM_WINDOWS; mem.window++)
|
||||
ioctl(sp->fd, PIOCSMEM, &mem);
|
||||
for (io.window = 0; io.window < NUM_IO_WINDOWS; io.window++)
|
||||
ioctl(sp->fd, PIOCSIO, &io);
|
||||
}
|
||||
|
||||
/*
|
||||
* execute - Execute the command strings.
|
||||
* For the current slot (if any) perform macro
|
||||
@ -149,64 +151,49 @@ int rw_flags;
|
||||
void
|
||||
execute(struct cmd *cmdp)
|
||||
{
|
||||
char cmd[1024];
|
||||
char *p, *cp, *lp;
|
||||
char cmd[1024];
|
||||
char *p, *cp, *lp;
|
||||
|
||||
for (;cmdp; cmdp = cmdp->next)
|
||||
{
|
||||
for (; cmdp; cmdp = cmdp->next) {
|
||||
cp = cmd;
|
||||
lp = cmdp->line;
|
||||
if (*lp == 0)
|
||||
continue;
|
||||
while ((p = strchr(lp, '$')) != 0)
|
||||
{
|
||||
/*
|
||||
* copy over preceding string.
|
||||
*/
|
||||
while ((p = strchr(lp, '$')) != 0) {
|
||||
/* copy over preceding string. */
|
||||
while (lp != p)
|
||||
*cp++ = *lp++;
|
||||
/*
|
||||
* stringify ethernet address and place here.
|
||||
*/
|
||||
if (strncmp(p, "$ether", 6)==0)
|
||||
{
|
||||
/* stringify ethernet address and place here. */
|
||||
if (strncmp(p, "$ether", 6) == 0) {
|
||||
sprintf(cp, "%x:%x:%x:%x:%x:%x",
|
||||
current_slot->eaddr[0],
|
||||
current_slot->eaddr[1],
|
||||
current_slot->eaddr[2],
|
||||
current_slot->eaddr[3],
|
||||
current_slot->eaddr[4],
|
||||
current_slot->eaddr[5]);
|
||||
current_slot->eaddr[0],
|
||||
current_slot->eaddr[1],
|
||||
current_slot->eaddr[2],
|
||||
current_slot->eaddr[3],
|
||||
current_slot->eaddr[4],
|
||||
current_slot->eaddr[5]);
|
||||
while (*++cp)
|
||||
;
|
||||
continue;
|
||||
lp += 6;
|
||||
}
|
||||
/*
|
||||
* replace device name
|
||||
*/
|
||||
else if (strncmp(p, "$device", 7)==0)
|
||||
{
|
||||
sprintf(cp, "%s%d",
|
||||
current_slot->config->driver->kernel,
|
||||
current_slot->config->driver->unit);
|
||||
while (*cp)
|
||||
cp++;
|
||||
lp += 7;
|
||||
}
|
||||
/*
|
||||
* Copy the `$' and rescan.
|
||||
*/
|
||||
else
|
||||
*cp++ = *lp++;
|
||||
}
|
||||
/*
|
||||
* No more replacements. Copy rest of string.
|
||||
*/
|
||||
} else
|
||||
/* replace device name */
|
||||
if (strncmp(p, "$device", 7) == 0) {
|
||||
sprintf(cp, "%s%d",
|
||||
current_slot->config->driver->kernel,
|
||||
current_slot->config->driver->unit);
|
||||
while (*cp)
|
||||
cp++;
|
||||
lp += 7;
|
||||
} else
|
||||
/* Copy the `$' and rescan. */
|
||||
*cp++ = *lp++;
|
||||
}
|
||||
/* No more replacements. Copy rest of string. */
|
||||
while ((*cp++ = *lp++) != 0)
|
||||
;
|
||||
continue;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Executing [%s]\n", cmd);
|
||||
#endif /* DEBUG */
|
||||
#endif /* DEBUG */
|
||||
system(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user