in cistpl.c [215:277]
int pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
u_int len, void *ptr)
{
void __iomem *sys, *end;
unsigned char *buf = ptr;
dev_dbg(&s->dev,
"pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
if (attr & IS_INDIRECT) {
/* Indirect accesses use a bunch of special registers at fixed
locations in common memory */
u_char flags = ICTRL0_COMMON|ICTRL0_AUTOINC|ICTRL0_BYTEGRAN;
if (attr & IS_ATTR) {
addr *= 2;
flags = ICTRL0_AUTOINC;
}
sys = set_cis_map(s, 0, MAP_ACTIVE |
((cis_width) ? MAP_16BIT : 0));
if (!sys) {
dev_dbg(&s->dev, "could not map memory\n");
return -EINVAL;
}
writeb(flags, sys+CISREG_ICTRL0);
writeb(addr & 0xff, sys+CISREG_IADDR0);
writeb((addr>>8) & 0xff, sys+CISREG_IADDR1);
writeb((addr>>16) & 0xff, sys+CISREG_IADDR2);
writeb((addr>>24) & 0xff, sys+CISREG_IADDR3);
for ( ; len > 0; len--, buf++)
writeb(*buf, sys+CISREG_IDATA0);
} else {
u_int inc = 1, card_offset, flags;
flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0);
if (attr & IS_ATTR) {
flags |= MAP_ATTRIB;
inc++;
addr *= 2;
}
card_offset = addr & ~(s->map_size-1);
while (len) {
sys = set_cis_map(s, card_offset, flags);
if (!sys) {
dev_dbg(&s->dev, "could not map memory\n");
return -EINVAL;
}
end = sys + s->map_size;
sys = sys + (addr & (s->map_size-1));
for ( ; len > 0; len--, buf++, sys += inc) {
if (sys == end)
break;
writeb(*buf, sys);
}
card_offset += s->map_size;
addr = 0;
}
}
return 0;
}