Date: Tue, 20 Jul 1999 22:31:50 +0900 (JST) From: hosokawa@itc.keio.ac.jp (HOSOKAWA Tatsumi) To: mobile@FreeBSD.org Cc: hosokawa@itc.keio.ac.jp Subject: usr.sbin/pccard/pccardd change for "cardio" and "cardmem" Message-ID: <199907201331.WAA22907@afs.ntc.mita.keio.ac.jp>
next in thread | raw e-mail | index | archive | help
Following patch (derived from PAO3) adds two keywords ("cardio" and "cardmem") to pccard.conf. "cardio" and "cardmem" specifies I/O address and memory address regardles of CIS tupple (so-called "builtin point enabler"). These keywords are needed for broken CIS cards and hardwired driver code, etc. This patch is needed by flash ATA support (Mr. Losh is working on kernel side of flash ATA support). If there's no objection, I'll commit it soon. -- HOSOKAWA, Tatsumi Assistant Manager Information Technology Center, Keio University <hosokawa@itc.keio.ac.jp> Index: cardd.c =================================================================== RCS file: /home/ncvs/src/usr.sbin/pccard/pccardd/cardd.c,v retrieving revision 1.34 diff -u -r1.34 cardd.c --- cardd.c 1999/02/05 16:00:17 1.34 +++ cardd.c 1999/07/20 13:14:38 @@ -179,6 +179,9 @@ sp->config = 0; /* release io */ bit_nset(io_avail, sp->io.addr, sp->io.addr + sp->io.size - 1); + /* release irq */ + if (sp->irq) + pool_irq[sp->irq] = 1; } /* @@ -383,15 +386,47 @@ sp->mem.addr, sp->mem.size, sp->mem.cardaddr); #endif } + if (sp->config->card_mem) { + struct card_mem *cm; + struct allocblk *m, *n; + for (m = sp->mem.next; m;) { + n = m->next; + free(m); + m = n; + } + sp->mem.next = 0; + sp->mem.addr = sp->config->card_mem->addr; + sp->mem.cardaddr = sp->config->card_mem->cardaddr; + sp->mem.size = sp->config->card_mem->size; + sp->mem.flags = sp->config->card_mem->flags; +#ifdef DEBUG + printf("addr=%x cardaddr=%x size=%x\n", + sp->mem.addr, sp->mem.cardaddr, sp->mem.size); +#endif + n = &sp->mem; + for (cm = sp->config->card_mem->next; cm; cm = cm->next) { + m = xmalloc(sizeof(*m)); + m->addr = cm->addr; + m->cardaddr = cm->cardaddr; + m->size = cm->size; + m->flags = cm->flags; + m->next = 0; + n->next = m; + n = m; + } + } /* Now look at I/O. */ bzero(&sp->io, sizeof(sp->io)); - if (cisconf->iospace || (defconf && defconf->iospace)) { + if (cisconf->iospace || (defconf && defconf->iospace) + || sp->config->card_io) { struct cis_config *cp; + struct card_io *cdio; cp = cisconf; if (!cisconf->iospace) cp = defconf; + cdio = sp->config->card_io; /* * If # of I/O lines decoded == 10, then card does its * own decoding. @@ -400,16 +435,20 @@ * If no address (but a length) is available, allocate * from the pool. */ - if (cp->io) { + if (cdio) { + sp->io.addr = cdio->addr; + sp->io.size = cdio->size; + } + else if (cp->io) { sp->io.addr = cp->io->addr; sp->io.size = cp->io->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); @@ -419,6 +458,7 @@ } bit_nclear(io_avail, sp->io.addr, sp->io.addr + sp->io.size - 1); + sp->flags |= IO_ASSIGNED; /* Set up the size to take into account the decode lines. */ sp->io.cardaddr = cp->io_addr; @@ -441,6 +481,7 @@ #endif } sp->irq = sp->config->irq; + sp->flags |= IRQ_ASSIGNED; return (0); } @@ -495,20 +536,31 @@ lseek(sp->fd, offs + 2, SEEK_SET); write(sp->fd, &c, sizeof(c)); } - mem.window = 0; - if (sp->mem.addr) { + if (sp->flags & MEM_ASSIGNED) { mem.window = 0; - mem.flags = sp->mem.flags | MDF_ACTIVE | MDF_16BITS; - mem.start = (caddr_t) sp->mem.addr; - mem.card = sp->mem.cardaddr; - mem.size = sp->mem.size; - if (ioctl(sp->fd, PIOCSMEM, &mem)) { - logerr("ioctl (PIOCSMEM)"); - return (0); + + /* + * This allows cardmem directives in /etc/pccard.conf + * with addr = 0x0 for cards which can tolerate arbitrary + * mappings + */ + if (!sp->mem.addr) + sp->mem.addr = alloc_memory(sp->mem.size); + + if (sp->mem.addr) { + mem.window = 0; + mem.flags = sp->mem.flags | MDF_ACTIVE | MDF_16BITS; + mem.start = (caddr_t) sp->mem.addr; + mem.card = sp->mem.cardaddr; + mem.size = sp->mem.size; + if (ioctl(sp->fd, PIOCSMEM, &mem)) { + logerr("ioctl (PIOCSMEM)"); + return (0); + } } } io.window = 0; - if (sp->io.size) { + if (sp->flags & IO_ASSIGNED) { io.flags = sp->io.flags; io.start = sp->io.addr; io.size = sp->io.size; @@ -534,14 +586,14 @@ drv.unit = drvp->unit; drv.irqmask = 1 << sp->irq; drv.flags = 0x80; - if (sp->mem.size) { + if (sp->flags & MEM_ASSIGNED) { drv.mem = sp->mem.addr; drv.memsize = sp->mem.size; } else { drv.mem = 0; drv.memsize = 0; } - if (sp->io.size) + if (sp->flags & IO_ASSIGNED) drv.iobase = sp->io.addr; else drv.iobase = 0; Index: cardd.h =================================================================== RCS file: /home/ncvs/src/usr.sbin/pccard/pccardd/cardd.h,v retrieving revision 1.12 diff -u -r1.12 cardd.h --- cardd.h 1998/03/09 05:18:55 1.12 +++ cardd.h 1999/07/20 13:14:40 @@ -44,10 +44,26 @@ int macro; /* Contains macros */ }; +struct card_io { + struct card_io *next; + int addr; + int size; +}; + +struct card_mem { + struct card_mem *next; + int addr; + int cardaddr; + int size; + int flags; +}; + struct card_config { struct card_config *next; unsigned char index; struct driver *driver; + struct card_io *card_io; + struct card_mem *card_mem; int irq; int flags; char inuse; @@ -109,9 +125,20 @@ struct allocblk io; /* I/O block spec */ struct allocblk mem; /* Memory block spec */ int irq; /* Irq value */ + int flags; /* Resource assignment flags */ }; + +/* + * Slot resource assignment/configuration flags + */ +#define IO_ASSIGNED 0x1 +#define MEM_ASSIGNED 0x2 +#define IRQ_ASSIGNED 0x4 +#define EADDR_CONFIGED 0x8 +#define WL_CONFIGED 0x10 +#define AFLAGS (IO_ASSIGNED | MEM_ASSIGNED | IRQ_ASSIGNED) +#define CFLAGS (EADDR_CONFIGED | WL_CONFIGED) -EXTERN struct allocblk *pool_ioblks; /* I/O blocks in the pool */ EXTERN struct allocblk *pool_mem; /* Memory in the pool */ EXTERN int pool_irq[16]; /* IRQ allocations */ EXTERN struct driver *drivers; /* List of drivers */ Index: file.c =================================================================== RCS file: /home/ncvs/src/usr.sbin/pccard/pccardd/file.c,v retrieving revision 1.18 diff -u -r1.18 file.c --- file.c 1999/07/15 03:04:31 1.18 +++ file.c 1999/07/20 13:14:43 @@ -52,6 +52,9 @@ "ether", /* 9 */ "insert", /* 10 */ "remove", /* 11 */ + "function", /* 12 (currrently, not works) */ + "cardio", /* 13 */ + "cardmem", /* 14 */ 0 }; @@ -66,6 +69,9 @@ #define KWD_ETHER 9 #define KWD_INSERT 10 #define KWD_REMOVE 11 +#define KWD_FUNCTION 12 +#define KWD_CARDIO 13 +#define KWD_CARDMEM 14 struct flags { char *name; @@ -82,6 +88,8 @@ static struct allocblk *ioblk_tok(int); static struct allocblk *memblk_tok(int); static struct driver *new_driver(char *); +static struct card_io *cardio_tok(void); +static struct card_mem *cardmem_tok(void); static void addcmd(struct cmd **); static void parse_card(void); @@ -183,7 +191,10 @@ struct card *cp; int i; struct card_config *confp, *lastp; + struct card_io *card_io, **ci; + struct card_mem *card_mem, **cm; + confp = 0; man = newstr(next_tok()); vers = newstr(next_tok()); cp = xmalloc(sizeof(*cp)); @@ -256,6 +267,38 @@ /* remove */ addcmd(&cp->remove); break; + case KWD_CARDIO: + /* cardio */ + card_io = cardio_tok(); + if (!card_io) { + error("Illegal cardio arguments"); + break; + } + if (!confp) { + error("No valid config index for cardio"); + free(card_io); + break; + } + for (ci = &confp->card_io; *ci; ci = &((*ci)->next)) + ; + *ci = card_io; + break; + case KWD_CARDMEM: + /* cardmem */ + card_mem = cardmem_tok(); + if (!card_mem) { + error("Illegal cardmem arguments"); + break; + } + if (!confp) { + error("No valid config index for cardmem"); + free(card_mem); + break; + } + for (cm = &confp->card_mem; *cm; cm = &((*cm)->next)) + ; + *cm = card_mem; + break; default: pusht = 1; return; @@ -378,6 +421,70 @@ error("illegal IRQ value"); return (-1); } + +/* + * Cardio token + * cardio {<addr>|auto} <size> + */ +static struct card_io * +cardio_tok(void) +{ + struct card_io * card_io = xmalloc(sizeof(*card_io)); + if (strcmp("auto", next_tok()) == 0) + card_io->addr = -1; /* wildcard */ + else { + pusht = 1; + card_io->addr = num_tok(); + if (card_io->addr == -1) + goto err; + } + card_io->size = num_tok(); + if (card_io->size == -1) + goto err; +#ifdef DEBUG + if (verbose) + printf("cardio:addr=%x size=%x\n", + card_io->addr, card_io->size); +#endif + return card_io; +err: /* parse error */ + free(card_io); + return NULL; +} + + +/* + * Cardmem token + * cardmem <addr> <cardaddr> <size> [<flags>] + */ +static struct card_mem * +cardmem_tok(void) +{ + struct card_mem * card_mem = xmalloc(sizeof(*card_mem)); + if ((card_mem->addr = num_tok()) == -1) + goto err; + if ((card_mem->cardaddr = num_tok()) == -1) + goto err; + if ((card_mem->size = num_tok()) == -1) + goto err; + /* scan mem flags; use defaults if none exist */ + card_mem->flags = num_tok(); + if (card_mem->flags == -1) { + pusht = 1; + card_mem->flags = MDF_ACTIVE | MDF_16BITS; + } +#ifdef DEBUG + if (verbose) + printf("cardmem:addr=%x cardaddr=%x size=%x\n", + card_mem->addr, card_mem->cardaddr, + card_mem->size); +#endif + return card_mem; +err: /* parse error */ + free(card_mem); + return NULL; +} + /* * search the table for a match. -- HOSOKAWA, Tatsumi Assistant Manager Information Technology Center, Keio University <hosokawa@itc.keio.ac.jp> To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-mobile" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199907201331.WAA22907>