MFPAO3. Add support multi io window. This code support following cards;

Accton UE2212
	PLANET-SMART-COM-CREDITCARD-2000
	Melco LPC-T
	ME-3000II
	Laneed LD-CDY
	Melco LPC3-TX

Submitted by:	MIHIRA Sanpei Yoshiro <sanpei@sanpei.org>
Obtained from:	PAO3
This commit is contained in:
Mitsuru IWASAKI 2000-04-26 15:11:17 +00:00
parent 92c4078faf
commit b254720a71
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=59655
3 changed files with 96 additions and 58 deletions

View File

@ -494,7 +494,9 @@ assign_io(struct slot *sp)
* Found a matching configuration. Now look at the I/O, memory and IRQ * Found a matching configuration. Now look at the I/O, memory and IRQ
* to create the desired parameters. Look at memory first. * to create the desired parameters. Look at memory first.
*/ */
if (cisconf->memspace || (defconf && defconf->memspace)) { if (!(strncmp(sp->config->driver->name, "ed", 2) == 0
&& (sp->config->flags & 0x10))
&& (cisconf->memspace || (defconf && defconf->memspace))) {
struct cis_memblk *mp; struct cis_memblk *mp;
mp = cisconf->mem; mp = cisconf->mem;
@ -527,6 +529,9 @@ assign_io(struct slot *sp)
if (cisconf->iospace || (defconf && defconf->iospace) if (cisconf->iospace || (defconf && defconf->iospace)
|| sp->card->iosize) { || sp->card->iosize) {
struct cis_config *cp; struct cis_config *cp;
struct cis_ioblk *cio;
struct allocblk *sio;
int x, xmax;
int iosize; int iosize;
cp = cisconf; cp = cisconf;
@ -550,49 +555,61 @@ assign_io(struct slot *sp)
* If no address (but a length) is available, allocate * If no address (but a length) is available, allocate
* from the pool. * from the pool.
*/ */
if (iosize) { cio = cp->io;
sp->io.addr = 0; sio = &(sp->io);
sp->io.size = iosize; xmax = 1;
} if (cio)
else if (cp->io) { xmax = cisconf->io_blks;
sp->io.addr = cp->io->addr; for (x = 0; x < xmax; x++) {
sp->io.size = cp->io->size; if (iosize) {
} else { sio->addr = 0;
/* sio->size = iosize;
* No I/O block, assume the address lines } else if (cio) {
* decode gives the size. sio->addr = cio->addr;
*/ sio->size = cio->size;
sp->io.size = 1 << cp->io_addr; } else {
} /*
if (sp->io.addr == 0) { * No I/O block, assume the address lines
int i = bit_fns(io_avail, IOPORTS, sp->io.size); * decode gives the size.
*/
sio->size = 1 << cp->io_addr;
}
if (sio->addr == 0) {
int i = bit_fns(io_avail, IOPORTS,
sio->size, sio->size);
if (i < 0) {
return (-1);
}
sio->addr = i;
}
bit_nclear(io_avail, sio->addr,
sio->addr + sio->size - 1);
sp->flags |= IO_ASSIGNED;
if (i < 0) /* Set up the size to take into account the decode lines. */
return (-1); sio->cardaddr = cp->io_addr;
sp->io.addr = i; switch (cp->io_bus) {
} case 0:
bit_nclear(io_avail, sp->io.addr, break;
sp->io.addr + sp->io.size - 1); case 1:
sp->flags |= IO_ASSIGNED; sio->flags = IODF_WS;
break;
/* Set up the size to take into account the decode lines. */ case 2:
sp->io.cardaddr = cp->io_addr; sio->flags = IODF_WS | IODF_CS16;
switch (cp->io_bus) { break;
case 0: case 3:
break; sio->flags = IODF_WS | IODF_CS16 | IODF_16BIT;
case 1: break;
sp->io.flags = IODF_WS; }
break; if (debug_level > 0) {
case 2: logmsg("Using I/O addr 0x%x, size %d\n",
sp->io.flags = IODF_WS | IODF_CS16; sio->addr, sio->size);
break; }
case 3: if (cio && cio->next) {
sp->io.flags = IODF_WS | IODF_CS16 | IODF_16BIT; sio->next = xmalloc(sizeof(*sio));
break; sio = sio->next;
} cio = cio->next;
if (debug_level > 0) { }
logmsg("Using I/O addr 0x%x, size %d\n",
sp->io.addr, sp->io.size);
} }
} }
sp->irq = sp->config->irq; sp->irq = sp->config->irq;
@ -611,10 +628,12 @@ setup_slot(struct slot *sp)
struct io_desc io; struct io_desc io;
struct dev_desc drv; struct dev_desc drv;
struct driver *drvp = sp->config->driver; struct driver *drvp = sp->config->driver;
struct allocblk *sio;
char *p; char *p;
char c; char c;
off_t offs; off_t offs;
int rw_flags; int rw_flags;
int iowin;
memset(&io, 0, sizeof io); memset(&io, 0, sizeof io);
memset(&drv, 0, sizeof drv); memset(&drv, 0, sizeof drv);
@ -664,11 +683,14 @@ setup_slot(struct slot *sp)
return (0); return (0);
} }
} }
io.window = 0;
if (sp->flags & IO_ASSIGNED) { if (sp->flags & IO_ASSIGNED) {
io.flags = sp->io.flags; for (iowin = 0, sio = &(sp->io); iowin <= 1; iowin++) {
io.start = sp->io.addr; io.window = iowin;
io.size = sp->io.size; if (sio->size) {
io.flags = sio->flags;
io.start = sio->addr;
io.size = sio->size;
}
#if 0 #if 0
io.start = sp->io.addr & ~((1 << sp->io.cardaddr) - 1); io.start = sp->io.addr & ~((1 << sp->io.cardaddr) - 1);
io.size = 1 << sp->io.cardaddr; io.size = 1 << sp->io.cardaddr;
@ -687,6 +709,21 @@ setup_slot(struct slot *sp)
logerr("ioctl (PIOCSIO)"); logerr("ioctl (PIOCSIO)");
return (0); return (0);
} }
if (ioctl(sp->fd, PIOCGIO, &io))
{
logerr("ioctl (PIOCGIO)");
return(0);
}
if (io.start != sio->addr){
logmsg("I/O base address changed from 0x%x to 0x%x\n",
sio->addr, io.start);
sio->addr = io.start;
}
if (sio->next)
sio = sio->next;
else
break;
}
} }
strcpy(drv.name, drvp->kernel); strcpy(drv.name, drvp->kernel);
drv.unit = drvp->unit; drv.unit = drvp->unit;

View File

@ -157,7 +157,7 @@ void slot_change(struct slot *);
/* util.c functions */ /* util.c functions */
unsigned long alloc_memory(int); unsigned long alloc_memory(int);
int bit_fns(bitstr_t *, int, int); int bit_fns(bitstr_t *, int, int, int);
void die(char *); void die(char *);
void execute(struct cmd *, struct slot *); void execute(struct cmd *, struct slot *);
void logmsg(const char *, ...); void logmsg(const char *, ...);

View File

@ -150,17 +150,18 @@ newstr(char *p)
* least count number. * least count number.
*/ */
int int
bit_fns(bitstr_t *nm, int nbits, int count) bit_fns(bitstr_t *nm, int nbits, int count, int step)
{ {
int i; int i, j;
int found = 0; int found = 0;
for (i = 0; i < nbits; i++) for (i = 0; i < nbits; i += step)
if (bit_test(nm, i)) { for (j = i, found = 0; j < nbits; j++)
if (++found == count) if (bit_test(nm, j)) {
return (i - count + 1); if (++found == count)
} else return i;
found = 0; } else
break;
return (-1); return (-1);
} }
@ -172,10 +173,10 @@ alloc_memory(int size)
{ {
int i; int i;
i = bit_fns(mem_avail, MEMBLKS, size / MEMUNIT); i = bit_fns(mem_avail, MEMBLKS, size / MEMUNIT + (size % MEMUNIT != 0), 1);
if (i < 0) if (i < 0)
return (0); return (0);
bit_nclear(mem_avail, i, size / MEMUNIT); bit_nclear(mem_avail, i, i + size / MEMUNIT + (size % MEMUNIT != 0) - 1);
return (BIT2MEM(i)); return (BIT2MEM(i));
} }