~kris/9p

9hist

684b0400aefc0efee89a6a7d74af95ca20760ea3 — David du Colombier 24 years ago 78a0392
Plan 9 from Bell Labs 2002-04-14
M boot/local.c => boot/local.c +0 -5
@@ 96,11 96,6 @@ connectlocal(void)
			*argp++ = bargv[i];
		*argp = 0;

		print("kfs");
		for(argp=arg; *argp; argp++)
			print(" %s", *argp);
		print("\n");

		dup(p[0], 0);
		dup(p[1], 1);
		close(p[0]);

M pc/devi82365.c => pc/devi82365.c +7 -3
@@ 584,9 584,6 @@ devi82365link(void)
	if(_pcmspecial)
		return;
	
	_pcmspecial = pcmcia_pcmspecial;
	_pcmspecialclose = pcmcia_pcmspecialclose;

	/* look for controllers if the ports aren't already taken */
	if(ioalloc(0x3E0, 2, 0, "i82365.0") >= 0){
		i82365probe(0x3E0, 0x3E1, 0);


@@ 601,6 598,13 @@ devi82365link(void)
		if(ncontroller == i)
			iofree(0x3E2);
	}

	if(ncontroller == 0)
		return;

	_pcmspecial = pcmcia_pcmspecial;
	_pcmspecialclose = pcmcia_pcmspecialclose;

	for(i = 0; i < ncontroller; i++)
		nslot += controller[i]->nslot;
	slot = xalloc(nslot * sizeof(PCMslot));

M pc/devpccard.c => pc/devpccard.c +179 -171
@@ 201,34 201,36 @@ typedef struct Cisdat {
} Cisdat;

typedef struct {
	char			pi_verstr[512];		/* Version string */
	PCMmap		pi_mmap[4];		/* maps, last is always for the kernel */
	ulong		pi_conf_addr;		/* Config address */
	uchar		pi_conf_present;	/* Config register present */
	int			pi_nctab;			/* In use configuration tables */
	PCMconftab	pi_ctab[8];		/* Configuration tables */
	PCMconftab	*pi_defctab;		/* Default conftab */

	int			pi_port;			/* Actual port usage */
	int			pi_irq;			/* Actual IRQ usage */
	char			verstr[512];		/* Version string */
	PCMmap		mmap[4];		/* maps, last is always for the kernel */
	ulong		conf_addr;		/* Config address */
	uchar		conf_present;	/* Config register present */
	int			nctab;			/* In use configuration tables */
	PCMconftab	ctab[8];		/* Configuration tables */
	PCMconftab	*defctab;		/* Default conftab */

	int			port;			/* Actual port usage */
	int			irq;			/* Actual IRQ usage */
} Pcminfo;

typedef struct {
	QLock;
	Variant		*cb_variant;		/* Which CardBus chipset */
	Pcidev		*cb_pci;			/* The bridge itself */
	ulong		*cb_regs;			/* Cardbus registers */
	int			cb_ltype;			/* Legacy type */
	int			cb_lindex;		/* Legacy port index address */
	int			cb_ldata;			/* Legacy port data address */
	int			cb_lbase;			/* Base register for this socket */

	int			cb_state;			/* Current state of card */
	int			cb_type;			/* Type of card */
	Pcminfo		cb_linfo;			/* PCMCIA slot info */

	int			cb_refs;			/* Number of refs to slot */
	QLock		cb_refslock;		/* inc/dev ref lock */
	Variant		*variant;		/* Which CardBus chipset */
	Pcidev		*pci;			/* The bridge itself */
	ulong		*regs;			/* Cardbus registers */
	int			ltype;			/* Legacy type */
	int			lindex;		/* Legacy port index address */
	int			ldata;			/* Legacy port data address */
	int			lbase;			/* Base register for this socket */

	int			state;			/* Current state of card */
	int			type;			/* Type of card */
	Pcminfo		linfo;			/* PCMCIA slot info */

	int			special;		/* card is allocated to a driver */

	int			refs;			/* Number of refs to slot */
	QLock		refslock;		/* inc/dev ref lock */
} Cardbus;

static int managerstarted;


@@ 324,13 326,13 @@ static void
engine(Cardbus *cb, int message)
{
	// print("engine(%d): %s(%s)\n", 
	//	 (int)(cb - cbslots), states[cb->cb_state], messages[message]);
	switch (cb->cb_state) {
	//	 (int)(cb - cbslots), states[cb->state], messages[message]);
	switch (cb->state) {
	case SlotEmpty:

		switch (message) {
		case CardDetected:
			cb->cb_state = SlotFull;
			cb->state = SlotFull;
			powerup(cb);
			break;
		case CardEjected:


@@ 346,11 348,11 @@ engine(Cardbus *cb, int message)

		switch (message) {
		case CardPowered:
			cb->cb_state = SlotPowered;
			cb->state = SlotPowered;
			configure(cb);
			break;
		case CardEjected:
			cb->cb_state = SlotEmpty;
			cb->state = SlotEmpty;
			powerdown(cb);
			break;
		default:


@@ 364,10 366,10 @@ engine(Cardbus *cb, int message)

		switch (message) {
		case CardConfigured:
			cb->cb_state = SlotConfigured;
			cb->state = SlotConfigured;
			break;
		case CardEjected:
			cb->cb_state = SlotEmpty;
			cb->state = SlotEmpty;
			unconfigure(cb);
			powerdown(cb);
			break;


@@ 382,7 384,7 @@ engine(Cardbus *cb, int message)

		switch (message) {
		case CardEjected:
			cb->cb_state = SlotEmpty;
			cb->state = SlotEmpty;
			unconfigure(cb);
			powerdown(cb);
			break;


@@ 469,17 471,17 @@ cbinterrupt(Ureg *, void *)
		Cardbus *cb = &cbslots[i];
		ulong event, state;

		event= cb->cb_regs[SocketEvent];
		state = cb->cb_regs[SocketState];
		event= cb->regs[SocketEvent];
		state = cb->regs[SocketState];
		rdreg(cb, Rcsc);	/* Ack the interrupt */

		// print("interrupt: slot %d, event %.8lX, state %.8lX, (%s)\n", 
		//		(int)(cb - cbslots), event, state, states[cb->cb_state]);
		//		(int)(cb - cbslots), event, state, states[cb->state]);

		if (event & SE_CCD) {
			cb->cb_regs[SocketEvent] |= SE_CCD;	/* Ack interrupt */
			cb->regs[SocketEvent] |= SE_CCD;	/* Ack interrupt */
			if (state & SE_CCD) {
				if (cb->cb_state != SlotEmpty) {
				if (cb->state != SlotEmpty) {
					print("#Y: take cardejected interrupt\n");
					iengine(cb, CardEjected);
				}


@@ 489,7 491,7 @@ cbinterrupt(Ureg *, void *)
		}

		if (event & SE_POWER) {
			cb->cb_regs[SocketEvent] |= SE_POWER;	/* Ack interrupt */
			cb->regs[SocketEvent] |= SE_POWER;	/* Ack interrupt */
			iengine(cb, CardPowered);
		}
	}


@@ 533,8 535,8 @@ devpccardlink(void)
		slot = nslots++;
		cb = &cbslots[slot];

		cb->cb_pci = pci;
		cb->cb_variant = &variant[i];
		cb->pci = pci;
		cb->variant = &variant[i];
		
		if (pci->vid != TI_vid) {
			// Gross hack, needs a fix.  Inherit the mappings from 9load


@@ 599,16 601,16 @@ devpccardlink(void)
			intrenable(pci->intl, cbinterrupt, cb, pci->tbdf, "cardbus");
		intl = pci->intl;

		if ((baddr = pcicfgr32(cb->cb_pci, PciBAR0)) == 0) {
		if ((baddr = pcicfgr32(cb->pci, PciBAR0)) == 0) {
			int align = (pci->did == Ricoh_478_did)? 0x10000: 0x1000;

			baddr = upamalloc(baddr, align, align);
			pcicfgw32(cb->cb_pci, PciBAR0, baddr);
			cb->cb_regs = (ulong *)KADDR(baddr);
			pcicfgw32(cb->pci, PciBAR0, baddr);
			cb->regs = (ulong *)KADDR(baddr);
		}
		else
			cb->cb_regs = (ulong *)KADDR(upamalloc(baddr, 4096, 0));
		cb->cb_state = SlotEmpty;
			cb->regs = (ulong *)KADDR(upamalloc(baddr, 4096, 0));
		cb->state = SlotEmpty;

		/* Don't really know what to do with this... */
		i82365probe(cb, LegacyAddr, LegacyAddr + 1);


@@ 617,8 619,10 @@ devpccardlink(void)
			 variant[i].r_name, baddr, pci->intl);
	}

	if (nslots == 0)
	if (nslots == 0){
		iofree(LegacyAddr);
		return;
	}

	_pcmspecial = pccard_pcmspecial;
	_pcmspecialclose = pccard_pcmspecialclose;


@@ 626,7 630,7 @@ devpccardlink(void)
	for (i = 0; i != nslots; i++) {
		Cardbus *cb = &cbslots[i];

		if ((cb->cb_regs[SocketState] & SE_CCD) == 0)
		if ((cb->regs[SocketState] & SE_CCD) == 0)
			engine(cb, CardDetected);
	}



@@ 635,12 639,12 @@ devpccardlink(void)
	for (i = 0; i != nslots; i++) {
		Cardbus *cb = &cbslots[i];

		if (cb->cb_regs[SocketState] & SE_POWER)
		if (cb->regs[SocketState] & SE_POWER)
			engine(cb, CardPowered);

		/* Ack and enable interrupts on all events */
		// cb->cb_regs[SocketEvent] = cb->cb_regs[SocketEvent];
		cb->cb_regs[SocketMask] |= 0xF;	
		// cb->regs[SocketEvent] = cb->regs[SocketEvent];
		cb->regs[SocketMask] |= 0xF;	
		wrreg(cb, Rcscic, 0xC);
	}
}


@@ 651,11 655,11 @@ powerup(Cardbus *cb)
	ulong state;
	ushort bcr;

	if ((state = cb->cb_regs[SocketState]) & SS_PC16) {
	if ((state = cb->regs[SocketState]) & SS_PC16) {
	
		// print("#Y%ld: Probed a PC16 card, powering up card\n", cb - cbslots);
		cb->cb_type = PC16;
		memset(&cb->cb_linfo, 0, sizeof(Pcminfo));
		cb->type = PC16;
		memset(&cb->linfo, 0, sizeof(Pcminfo));

		/* power up and unreset, wait's are empirical (???) */
		wrreg(cb, Rpc, Fautopower|Foutena|Fcardena);


@@ 678,7 682,7 @@ powerup(Cardbus *cb)
	if ((state & SS_3V) == 0 && (state & SS_5V) == 0) {
		print("#Y%ld: Unsupported voltage, powering down card!\n", 
			cb - cbslots);
		cb->cb_regs[SocketControl] = 0;
		cb->regs[SocketControl] = 0;
		return 0;
	}



@@ 689,14 693,14 @@ powerup(Cardbus *cb)
	/* Power up the card
	 * and make sure the secondary bus is not in reset.
	 */
	cb->cb_regs[SocketControl] = (state & SS_5V)? SC_5V: SC_3V;
	cb->regs[SocketControl] = (state & SS_5V)? SC_5V: SC_3V;
	delay(50);
	bcr = pcicfgr16(cb->cb_pci, PciBCR);
	bcr = pcicfgr16(cb->pci, PciBCR);
	bcr &= ~0x40;
	pcicfgw16(cb->cb_pci, PciBCR, bcr);
	pcicfgw16(cb->pci, PciBCR, bcr);
	delay(100);

	cb->cb_type = PC32;
	cb->type = PC32;
	return 1;
}



@@ 705,20 709,20 @@ powerdown(Cardbus *cb)
{
	ushort bcr;

	if (cb->cb_type == PC16) {
	if (cb->type == PC16) {

		wrreg(cb, Rpc, 0);	/* turn off card power */
		wrreg(cb, Rwe, 0);	/* no windows */

		cb->cb_type = -1;
		cb->type = -1;
		return;
	}

	bcr = pcicfgr16(cb->cb_pci, PciBCR);
	bcr = pcicfgr16(cb->pci, PciBCR);
	bcr |= 0x40;
	pcicfgw16(cb->cb_pci, PciBCR, bcr);
	cb->cb_regs[SocketControl] = 0;
	cb->cb_type = -1;
	pcicfgw16(cb->pci, PciBCR, bcr);
	cb->regs[SocketControl] = 0;
	cb->type = -1;
}

static void


@@ 727,21 731,21 @@ configure(Cardbus *cb)
	int i;
	Pcidev *pci;

	//print("configuring slot %d (%s)\n", (int)(cb - cbslots), states[cb->cb_state]);
	if (cb->cb_state == SlotConfigured)
	//print("configuring slot %d (%s)\n", (int)(cb - cbslots), states[cb->state]);
	if (cb->state == SlotConfigured)
		return;
	engine(cb, CardConfigured);

	delay(50);					/* Emperically established */

	if (cb->cb_type == PC16) {
	if (cb->type == PC16) {
		i82365configure(cb);
		return;
	}

	/* Scan the CardBus for new PCI devices */
	pciscan(pcicfgr8(cb->cb_pci, PciSBN), &cb->cb_pci->bridge);
	pci = cb->cb_pci->bridge;
	pciscan(pcicfgr8(cb->pci, PciSBN), &cb->pci->bridge);
	pci = cb->pci->bridge;
	while (pci) {
		ulong size, bar;
		int memindex, ioindex;


@@ 768,8 772,8 @@ configure(Cardbus *cb)
				pci->mem[i].bar = bar | 1;
				pcicfgw32(pci, PciBAR0 + i * sizeof(ulong), 
					          pci->mem[i].bar);
				pcicfgw16(cb->cb_pci, PciCBIBR0 + ioindex * 8, bar);
				pcicfgw16(cb->cb_pci, PciCBILR0 + ioindex * 8, 
				pcicfgw16(cb->pci, PciCBIBR0 + ioindex * 8, bar);
				pcicfgw16(cb->pci, PciCBILR0 + ioindex * 8, 
						 bar + pci->mem[i].size - 1);
				//print("ioindex[%d] %.8uX (%d)\n", 
				//	ioindex, bar, pci->mem[i].size);


@@ 786,14 790,14 @@ configure(Cardbus *cb)
			bar = upamalloc(0, pci->mem[i].size, BY2PG);
			pci->mem[i].bar = bar | (pci->mem[i].bar & 0x80);
			pcicfgw32(pci, PciBAR0 + i * sizeof(ulong), pci->mem[i].bar);
			pcicfgw32(cb->cb_pci, PciCBMBR0 + memindex * 8, bar);
			pcicfgw32(cb->cb_pci, PciCBMLR0 + memindex * 8, 
			pcicfgw32(cb->pci, PciCBMBR0 + memindex * 8, bar);
			pcicfgw32(cb->pci, PciCBMLR0 + memindex * 8, 
					  bar + pci->mem[i].size - 1);

			if (pci->mem[i].bar & 0x80)
				/* Enable prefetch */
				pcicfgw16(cb->cb_pci, PciBCR, 
						 pcicfgr16(cb->cb_pci, PciBCR) | 
				pcicfgw16(cb->pci, PciBCR, 
						 pcicfgr16(cb->pci, PciBCR) | 
							          (1 << (8 + memindex)));

			//print("memindex[%d] %.8uX (%d)\n", 


@@ 811,9 815,9 @@ configure(Cardbus *cb)
				pci->rom.size = size;

				pcicfgw32(pci, PciEBAR0, pci->rom.bar);
				pcicfgw32(cb->cb_pci, PciCBMBR0 + memindex * 8,
				pcicfgw32(cb->pci, PciCBMBR0 + memindex * 8,
						 pci->rom.bar);
				pcicfgw32(cb->cb_pci, PciCBMLR0 + memindex * 8, 
				pcicfgw32(cb->pci, PciCBMLR0 + memindex * 8, 
						 pci->rom.bar + pci->rom.size - 1);
			}
		}


@@ 826,12 830,12 @@ configure(Cardbus *cb)
		pcicfgw8(pci, PciLTR, 64);

		if (pcicfgr8(pci, PciINTP)) {
			pci->intl = pcicfgr8(cb->cb_pci, PciINTL);
			pci->intl = pcicfgr8(cb->pci, PciINTL);
			pcicfgw8(pci, PciINTL, pci->intl);

			/* Route interrupts to INTA#/B# */
			pcicfgw16(cb->cb_pci, PciBCR, 
					  pcicfgr16(cb->cb_pci, PciBCR) & ~(1 << 7));
			pcicfgw16(cb->pci, PciBCR, 
					  pcicfgr16(cb->pci, PciBCR) & ~(1 << 7));
		}
			
		pci = pci->list;


@@ 844,18 848,18 @@ unconfigure(Cardbus *cb)
	Pcidev *pci;
	int i, ioindex, memindex;

	if (cb->cb_type == PC16) {
	if (cb->type == PC16) {
		print("#Y%d: Don't know how to unconfigure a PC16 card\n",
			 (int)(cb - cbslots));

		memset(&cb->cb_linfo, 0, sizeof(Pcminfo));
		memset(&cb->linfo, 0, sizeof(Pcminfo));
		return;
	}

	pci = cb->cb_pci->bridge;
	pci = cb->pci->bridge;
	if (pci == nil) 
		return;		/* Not configured */
	cb->cb_pci->bridge = nil;		
	cb->pci->bridge = nil;		

	memindex = ioindex = 0;
	while (pci) {


@@ 865,28 869,28 @@ unconfigure(Cardbus *cb)
			if (pci->mem[i].size == 0) continue;
			if (pci->mem[i].bar & 1) {
				iofree(pci->mem[i].bar & ~1);
				pcicfgw16(cb->cb_pci, PciCBIBR0 + ioindex * 8, 
				pcicfgw16(cb->pci, PciCBIBR0 + ioindex * 8, 
						 (ushort)-1);
				pcicfgw16(cb->cb_pci, PciCBILR0 + ioindex * 8, 0);
				pcicfgw16(cb->pci, PciCBILR0 + ioindex * 8, 0);
				ioindex++;
				continue;
			}

			upafree(pci->mem[i].bar & ~0xF, pci->mem[i].size);
			pcicfgw32(cb->cb_pci, PciCBMBR0 + memindex * 8, 
			pcicfgw32(cb->pci, PciCBMBR0 + memindex * 8, 
				          (ulong)-1);
			pcicfgw32(cb->cb_pci, PciCBMLR0 + memindex * 8, 0);
			pcicfgw16(cb->cb_pci, PciBCR, 
					 pcicfgr16(cb->cb_pci, PciBCR) & 
			pcicfgw32(cb->pci, PciCBMLR0 + memindex * 8, 0);
			pcicfgw16(cb->pci, PciBCR, 
					 pcicfgr16(cb->pci, PciBCR) & 
							       ~(1 << (8 + memindex)));
			memindex++;
		}

		if (pci->rom.bar && memindex < 2) {
			upafree(pci->rom.bar & ~0xF, pci->rom.size);
			pcicfgw32(cb->cb_pci, PciCBMBR0 + memindex * 8, 
			pcicfgw32(cb->pci, PciCBMBR0 + memindex * 8, 
					  (ulong)-1);
			pcicfgw32(cb->cb_pci, PciCBMLR0 + memindex * 8, 0);
			pcicfgw32(cb->pci, PciCBMLR0 + memindex * 8, 0);
			memindex++;
		}



@@ 964,9 968,10 @@ pccard_pcmspecial(char *idstr, ISAConf *isa)
		cb = &cbslots[i];

		qlock(cb);
		if (cb->cb_state == SlotConfigured &&
		    cb->cb_type == PC16 && 
		    strstr(cb->cb_linfo.pi_verstr, idstr)) 
		if (cb->state == SlotConfigured &&
		    cb->type == PC16 && 
		    !cb->special &&
		    strstr(cb->linfo.verstr, idstr)) 
			break;
		qunlock(cb);
	}


@@ 976,7 981,7 @@ pccard_pcmspecial(char *idstr, ISAConf *isa)
		return -1;
	}

	pi = &cb->cb_linfo;
	pi = &cb->linfo;

	/*
 	  *  configure the PCMslot for IO.  We assume very heavily that we can read


@@ 986,7 991,7 @@ pccard_pcmspecial(char *idstr, ISAConf *isa)
	if(irq == 2)
		irq = 9;

	et = &pi->pi_ctab[pi->pi_nctab];
	et = &pi->ctab[pi->nctab];
	ct = nil;
	for(i = 0; i < isa->nopt; i++){
		int index;


@@ 995,28 1000,28 @@ pccard_pcmspecial(char *idstr, ISAConf *isa)
		if(strncmp(isa->opt[i], "index=", 6))
			continue;
		index = strtol(&isa->opt[i][6], &cp, 0);
		if(cp == &isa->opt[i][6] || index >= pi->pi_nctab) {
		if(cp == &isa->opt[i][6] || index >= pi->nctab) {
			qunlock(cb);
			print("#Y%d: Cannot find index %d in conf table\n", 
				 (int)(cb - cbslots), index);
			return -1;
		}
		ct = &pi->pi_ctab[index];
		ct = &pi->ctab[index];
	}

	if(ct == nil){
		PCMconftab *t;

		/* assume default is right */
		if(pi->pi_defctab)
			ct = pi->pi_defctab;
		if(pi->defctab)
			ct = pi->defctab;
		else
			ct = pi->pi_ctab;
			ct = pi->ctab;
	
		/* try for best match */
		if(ct->nio == 0
		|| ct->io[0].start != isa->port || ((1<<irq) & ct->irqs) == 0){
			for(t = pi->pi_ctab; t < et; t++)
			for(t = pi->ctab; t < et; t++)
				if(t->nio
				&& t->io[0].start == isa->port
				&& ((1<<irq) & t->irqs)){


@@ 1025,14 1030,14 @@ pccard_pcmspecial(char *idstr, ISAConf *isa)
				}
		}
		if(ct->nio == 0 || ((1<<irq) & ct->irqs) == 0){
			for(t = pi->pi_ctab; t < et; t++)
			for(t = pi->ctab; t < et; t++)
				if(t->nio && ((1<<irq) & t->irqs)){
					ct = t;
					break;
				}
		}
		if(ct->nio == 0){
			for(t = pi->pi_ctab; t < et; t++)
			for(t = pi->ctab; t < et; t++)
				if(t->nio){
					ct = t;
					break;


@@ 1051,6 1056,8 @@ pccard_pcmspecial(char *idstr, ISAConf *isa)
		return -1;
	}

	cb->special = 1;	/* taken */

	/* route interrupts */
	isa->irq = irq;
	wrreg(cb, Rigc, irq | Fnotreset | Fiocard);


@@ 1092,12 1099,12 @@ pccard_pcmspecial(char *idstr, ISAConf *isa)
	wrreg(cb, Rwe, we);

	/* only touch Rconfig if it is present */
	if(pi->pi_conf_present & (1<<Rconfig)){
	if(pi->conf_present & (1<<Rconfig)){
		PCMmap *m;

		/*  Reset adapter */
		m = isamap(cb, pi->pi_conf_addr + Rconfig, 1, 1);
		p = KADDR(m->isa + pi->pi_conf_addr + Rconfig - m->ca);
		m = isamap(cb, pi->conf_addr + Rconfig, 1, 1);
		p = KADDR(m->isa + pi->conf_addr + Rconfig - m->ca);

		/* set configuration and interrupt type */
		x = ct->index;


@@ 1109,11 1116,11 @@ pccard_pcmspecial(char *idstr, ISAConf *isa)
		isaunmap(m);
	}

	pi->pi_port = isa->port;
	pi->pi_irq = isa->irq;
	pi->port = isa->port;
	pi->irq = isa->irq;
	qunlock(cb);

	print("#Y%d: %s irq %ld, port %lX\n", (int)(cb - cbslots), pi->pi_verstr, isa->irq, isa->port);
	print("#Y%d: %s irq %ld, port %lX\n", (int)(cb - cbslots), pi->verstr, isa->irq, isa->port);
	return (int)(cb - cbslots);
}



@@ 1123,6 1130,7 @@ pccard_pcmspecialclose(int slotno)
	Cardbus *cb = &cbslots[slotno];

	wrreg(cb, Rwe, 0);	/* no windows */
	cb->special = 0;
}

static int


@@ 1249,17 1257,17 @@ pccardstat(Chan *c, uchar *db, int n)
static void
increfp(Cardbus *cb)
{
	qlock(&cb->cb_refslock);
	cb->cb_refs++;
	qunlock(&cb->cb_refslock);
	qlock(&cb->refslock);
	cb->refs++;
	qunlock(&cb->refslock);
}

static void
decrefp(Cardbus *cb)
{
	qlock(&cb->cb_refslock);
	cb->cb_refs--;
	qunlock(&cb->cb_refslock);
	qlock(&cb->refslock);
	cb->refs--;
	qunlock(&cb->refslock);
}

static Chan*


@@ 1301,16 1309,16 @@ pccardread(Chan *c, void *a, long n, vlong offset)
	
		cb = &cbslots[SLOTNO(c)];
		qlock(cb);
		p = seprint(p, e, "slot %ld: %s; ", cb - cbslots, states[cb->cb_state]);
		p = seprint(p, e, "slot %ld: %s; ", cb - cbslots, states[cb->state]);

		switch (cb->cb_type) {
		switch (cb->type) {
		case -1:
			seprint(p, e, "\n");
			break;

		case PC32:
			if (cb->cb_pci->bridge) {
				Pcidev *pci = cb->cb_pci->bridge;
			if (cb->pci->bridge) {
				Pcidev *pci = cb->pci->bridge;
				int i;

				while (pci) {


@@ 1331,21 1339,21 @@ pccardread(Chan *c, void *a, long n, vlong offset)
			break;

		case PC16:
			if (cb->cb_state == SlotConfigured) {
				Pcminfo *pi = &cb->cb_linfo;
			if (cb->state == SlotConfigured) {
				Pcminfo *pi = &cb->linfo;

				p = seprint(p, e, "%s port %X; irq %d;\n",
						  pi->pi_verstr, pi->pi_port,
						  pi->pi_irq);
				for (n = 0; n != pi->pi_nctab; n++) {
						  pi->verstr, pi->port,
						  pi->irq);
				for (n = 0; n != pi->nctab; n++) {
					PCMconftab *ct;
					int i;

					ct = &pi->pi_ctab[n];
					ct = &pi->ctab[n];
					p = seprint(p, e, 
						"\tconfiguration[%ld] irqs %.4uX; vpp %d, %d; %s\n",
							  n, ct->irqs, ct->vpp1, ct->vpp2,
							  (ct == pi->pi_defctab)? "(default);": "");
							  (ct == pi->defctab)? "(default);": "");
					for (i = 0; i != ct->nio; i++)
						if (ct->io[i].len > 0)
							p = seprint(p, e, "\t\tio[%d] %.8ulX %uld\n",


@@ 1393,7 1401,7 @@ pccardwrite(Chan *c, void *v, long n, vlong)
			qengine(cb, CardEjected);
			break;
		case CMpower:
			if ((cb->cb_regs[SocketState] & SS_CCD) == 0)
			if ((cb->regs[SocketState] & SS_CCD) == 0)
				qengine(cb, CardDetected);
			break;
		}


@@ 1434,7 1442,7 @@ isamap(Cardbus *cb, ulong offset, int len, int attr)
	int i;
	ulong e;

	pi = &cb->cb_linfo;
	pi = &cb->linfo;

	/* convert offset to granularity */
	if(len <= 0)


@@ 1447,7 1455,7 @@ isamap(Cardbus *cb, ulong offset, int len, int attr)
	we = rdreg(cb, Rwe);
	bit = 1;
	nm = 0;
	for(m = pi->pi_mmap; m < &pi->pi_mmap[nelem(pi->pi_mmap)]; m++){
	for(m = pi->mmap; m < &pi->mmap[nelem(pi->mmap)]; m++){
		if((we & bit))
		if(m->attr == attr)
		if(offset >= m->ca && e <= m->cea){


@@ 1481,7 1489,7 @@ isamap(Cardbus *cb, ulong offset, int len, int attr)
	m->ca = offset;
	m->cea = m->ca + m->len;
	m->attr = attr;
	i = m - pi->pi_mmap;
	i = m - pi->mmap;
	bit = 1<<i;
	wrreg(cb, Rwe, we & ~bit);		/* disable map before changing it */
	wrreg(cb, MAP(i, Mbtmlo), m->isa>>Mshift);


@@ 1511,15 1519,15 @@ isaunmap(PCMmap* m)
static uchar
rdreg(Cardbus *cb, int index)
{
	outb(cb->cb_lindex, cb->cb_lbase + index);
	return inb(cb->cb_ldata);
	outb(cb->lindex, cb->lbase + index);
	return inb(cb->ldata);
}

static void
wrreg(Cardbus *cb, int index, uchar val)
{
	outb(cb->cb_lindex, cb->cb_lbase + index);
	outb(cb->cb_ldata, val);
	outb(cb->lindex, cb->lbase + index);
	outb(cb->ldata, val);
}

static int


@@ 1562,9 1570,9 @@ tcfig(Cardbus *cb, Cisdat *cis, int )
	if(readc(cis, &last) != 1)
		return;

	pi = &cb->cb_linfo;
	pi->pi_conf_addr = getlong(cis, rasize);
	pi->pi_conf_present = getlong(cis, rmsize);
	pi = &cb->linfo;
	pi->conf_addr = getlong(cis, rasize);
	pi->conf_present = getlong(cis, rmsize);
}

static void


@@ 1574,13 1582,13 @@ tvers1(Cardbus *cb, Cisdat *cis, int )
	int  i;
	Pcminfo *pi;

	pi = &cb->cb_linfo;
	pi = &cb->linfo;
	if(readc(cis, &major) != 1)
		return;
	if(readc(cis, &minor) != 1)
		return;
	last = 0;
	for(i = 0; i < sizeof(pi->pi_verstr) - 1; i++){
	for(i = 0; i < sizeof(pi->verstr) - 1; i++){
		if(readc(cis, &c) != 1)
			return;
		if(c == 0)


@@ 1591,10 1599,10 @@ tvers1(Cardbus *cb, Cisdat *cis, int )
			break;
		if(c == ';' && last == ';')
			continue;
		pi->pi_verstr[i] = c;
		pi->verstr[i] = c;
		last = c;
	}
	pi->pi_verstr[i] = 0;
	pi->verstr[i] = 0;
}

static ulong


@@ 1774,22 1782,22 @@ tentry(Cardbus *cb, Cisdat *cis, int )
	PCMconftab *ct;
	Pcminfo *pi;

	pi = &cb->cb_linfo;
	if(pi->pi_nctab >= nelem(pi->pi_ctab))
	pi = &cb->linfo;
	if(pi->nctab >= nelem(pi->ctab))
		return;
	if(readc(cis, &c) != 1)
		return;
	ct = &pi->pi_ctab[pi->pi_nctab++];
	ct = &pi->ctab[pi->nctab++];

	/* copy from last default config */
	if(pi->pi_defctab)
		*ct = *pi->pi_defctab;
	if(pi->defctab)
		*ct = *pi->defctab;

	ct->index = c & 0x3f;

	/* is this the new default? */
	if(c & 0x40)
		pi->pi_defctab = ct;
		pi->defctab = ct;

	/* memory wait specified? */
	if(c & 0x80){


@@ 1853,51 1861,51 @@ i82365probe(Cardbus *cb, int lindex, int ldata)
	if((id & 0x0f) == 0x00)
		return;		/* no revision number, not possible */

	cb->cb_lindex = lindex;
	cb->cb_ldata = ldata;
	cb->cb_ltype = Ti82365;
	cb->cb_lbase = (int)(cb - cbslots) * 0x40;
	cb->lindex = lindex;
	cb->ldata = ldata;
	cb->ltype = Ti82365;
	cb->lbase = (int)(cb - cbslots) * 0x40;

	switch(id){
	case 0x82:
	case 0x83:
	case 0x84:
		/* could be a cirrus */
		outb(cb->cb_lindex, Rchipinfo + (dev<<7));
		outb(cb->cb_ldata, 0);
		c = inb(cb->cb_ldata);
		outb(cb->lindex, Rchipinfo + (dev<<7));
		outb(cb->ldata, 0);
		c = inb(cb->ldata);
		if((c & 0xc0) != 0xc0)
			break;
		c = inb(cb->cb_ldata);
		c = inb(cb->ldata);
		if((c & 0xc0) != 0x00)
			break;
		if(c & 0x20){
			cb->cb_ltype = Tpd6720;
			cb->ltype = Tpd6720;
		} else {
			cb->cb_ltype = Tpd6710;
			cb->ltype = Tpd6710;
		}
		break;
	}

	/* if it's not a Cirrus, it could be a Vadem... */
	if(cb->cb_ltype == Ti82365){
	if(cb->ltype == Ti82365){
		/* unlock the Vadem extended regs */
		outb(cb->cb_lindex, 0x0E + (dev<<7));
		outb(cb->cb_lindex, 0x37 + (dev<<7));
		outb(cb->lindex, 0x0E + (dev<<7));
		outb(cb->lindex, 0x37 + (dev<<7));

		/* make the id register show the Vadem id */
		outb(cb->cb_lindex, 0x3A + (dev<<7));
		c = inb(cb->cb_ldata);
		outb(cb->cb_ldata, c|0xC0);
		outb(cb->cb_lindex, Rid + (dev<<7));
		c = inb(cb->cb_ldata);
		outb(cb->lindex, 0x3A + (dev<<7));
		c = inb(cb->ldata);
		outb(cb->ldata, c|0xC0);
		outb(cb->lindex, Rid + (dev<<7));
		c = inb(cb->ldata);
		if(c & 0x08)
			cb->cb_ltype = Tvg46x;
			cb->ltype = Tvg46x;

		/* go back to Intel compatible id */
		outb(cb->cb_lindex, 0x3A + (dev<<7));
		c = inb(cb->cb_ldata);
		outb(cb->cb_ldata, c & ~0xC0);
		outb(cb->lindex, 0x3A + (dev<<7));
		c = inb(cb->ldata);
		outb(cb->ldata, c & ~0xC0);
	}
}


M pc/etherelnk3.c => pc/etherelnk3.c +2 -0
@@ 777,6 777,7 @@ txstart905(Ether* ether)

		coherence();
		ctlr->dnhead->np = PADDR(&pd->np);
		coherence();
		ctlr->dnhead->control &= ~dnIndicate;
		ctlr->dnhead = pd;
		if(ctlr->dnq == 0)


@@ 850,6 851,7 @@ receive905(Ether* ether)
			pd->bp->wp = pd->bp->rp+len;
			etheriq(ether, pd->bp, 1);
			pd->bp = bp;
			coherence();
			pd->addr = PADDR(bp->rp);
			coherence();
		}

M port/devaudio.c => port/devaudio.c +2 -2
@@ 747,12 747,12 @@ audioinit(void)
	}

	if(ioalloc(sbconf.port, 0x10, 0, "audio") < 0){
		print("#A: cannot ioalloc range %x+0x10\n", sbconf.port);
		print("#A: cannot ioalloc range %lux+0x10\n", sbconf.port);
		return;
	}
	if(ioalloc(sbconf.port+0x100, 1, 0, "audio.mpu401") < 0){
		iofree(sbconf.port);
		print("#A: cannot ioalloc range %x+0x01\n", sbconf.port+0x100);
		print("#A: cannot ioalloc range %lux+0x01\n", sbconf.port+0x100);
		return;
	}


M port/devpnp.c => port/devpnp.c +32 -6
@@ 485,10 485,12 @@ pnpclose(Chan*)
static long
pnpread(Chan *c, void *va, long n, vlong offset)
{
	ulong x;
	Card *cp;
	Pcidev *p;
	int csn, i, tbdf;
	char buf[256], *ebuf, *w;
	char *a = va;
	int csn, i, tbdf, r;

	switch(TYPE(c->qid)){
	case Qtopdir:


@@ 511,9 513,9 @@ pnpread(Chan *c, void *va, long n, vlong offset)
		qlock(&pnp);
		initiation();
		cmd(0x03, csn);				/* Wake up the card */
		for (i = 0; i < offset+9; i++)		/* 9 == skip serial + csum */
		for(i = 0; i < offset+9; i++)		/* 9 == skip serial + csum */
			getresbyte(pnp.rddata);
		for (i = 0; i < n; i++)
		for(i = 0; i < n; i++)
			a[i] = getresbyte(pnp.rddata);
		cmd(0x03, 0);					/* Wake all cards with a CSN of 0, putting this card to sleep */
		cmd(0x02, 0x02);				/* return cards to Wait for Key state */


@@ 531,15 533,39 @@ pnpread(Chan *c, void *va, long n, vlong offset)
		p = pcimatchtbdf(tbdf);
		if(p == nil)
			error(Egreg);
		sprint(up->genbuf, "class %.2x subclass %.2x piclass %.2x vid %.4x did %.4x intl %d\n",
		ebuf = buf+sizeof buf-1;	/* -1 for newline */
		w = seprint(buf, ebuf, "%.2x.%.2x.%.2x %.4x/%.4x %3d",
			p->ccrb, p->ccru, p->ccrp, p->vid, p->did, p->intl);
		return readstr(offset, a, n, up->genbuf);
		for(i=0; i<nelem(p->mem); i++){
			if(p->mem[i].size == 0)
				continue;
			w = seprint(w, ebuf, " %d:%.8lux %d", i, p->mem[i].bar, p->mem[i].size);
		}
		*w++ = '\n';
		*w = '\0';
		return readstr(offset, a, n, buf);
	case Qpciraw:
		tbdf = MKBUS(BusPCI, 0, 0, 0)|BUSBDF((ulong)c->qid.path);
		p = pcimatchtbdf(tbdf);
		if(p == nil)
			error(Egreg);
		break;
		if(offset > 128)
			return 0;
		if(n+offset > 128)
			n = 128-offset;
		if(offset%4)
			error(Ebadarg);
		r = offset;
		for(i = 0; i+4 <= n; i+=4) {
			x = pcicfgr32(p, r);
			a[0] = x;
			a[1] = (x>>8);
			a[2] = (x>>16);
			a[3] = (x>>24);
			a += 4;
			r += 4;
		}
		return i;
	default:
		error(Egreg);
	}

M port/portclock.c => port/portclock.c +0 -2
@@ 174,8 174,6 @@ timerintr(Ureg *u, uvlong)
		ilock(tt);
		if(t->period){
			t->when += t->period;
			if (t->when <= now)
				t->when = now + t->period;
			tadd(tt, t);
		}
	}

M port/proc.c => port/proc.c +0 -1
@@ 89,7 89,6 @@ sched(void)
{
	if(up){
		if(up->state == Running && up->nlocks){
			up->delaysched++;
			delayedscheds++;
			return;
		}

M port/taslock.c => port/taslock.c +2 -12
@@ 152,7 152,6 @@ canlock(Lock *l)
	return 1;
}

int buggeredsched;
void
unlock(Lock *l)
{


@@ 165,17 164,8 @@ unlock(Lock *l)
	l->key = 0;
	coherence();

	/* give up the processor if ... */
	if(up && --up->nlocks == 0	/* we've closed the last nested lock */
	&& up->delaysched		/* we delayed scheduling because of the lock */
	&& up->state == Running){		/* we're in running state */
		if(!islo())
			buggeredsched++;
		else{
			up->delaysched = 0;
			sched();
		}
	}
	if(up)
		--up->nlocks;
}

void