9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
* Re: [9fans] smc 91cxx driver
@ 2000-10-20 17:43 jmk
  2000-10-22 17:33 ` Latchesar Ionkov
  0 siblings, 1 reply; 4+ messages in thread
From: jmk @ 2000-10-20 17:43 UTC (permalink / raw)
  To: 9fans

Since we are always short of PCMCIA cards I looked into buying one of these
but they seem to have been replaced by the 'EZ PC Card 10' which is claimed
to be NE2000 compatible.

--jim



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [9fans] smc 91cxx driver
  2000-10-20 17:43 [9fans] smc 91cxx driver jmk
@ 2000-10-22 17:33 ` Latchesar Ionkov
  0 siblings, 0 replies; 4+ messages in thread
From: Latchesar Ionkov @ 2000-10-22 17:33 UTC (permalink / raw)
  To: 9fans

On Fri, Oct 20, 2000 at 01:43:23PM -0400, jmk@plan9.bell-labs.com said:
> Since we are always short of PCMCIA cards I looked into buying one of these
> but they seem to have been replaced by the 'EZ PC Card 10' which is claimed
> to be NE2000 compatible.

I am not sure that smc91cXX driver should be included in kernel. Especially
if the hardware is obsolete and I am the only person that uses it. It would
be great to have the change in devi82365.c though.

Thanks,
	Lucho



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [9fans] smc 91cxx driver
@ 2000-10-20 15:20 jmk
  0 siblings, 0 replies; 4+ messages in thread
From: jmk @ 2000-10-20 15:20 UTC (permalink / raw)
  To: 9fans

Thanks!

I've added it to our source tree so it will appear in
future updates.

--jim



^ permalink raw reply	[flat|nested] 4+ messages in thread

* [9fans] smc 91cxx driver
@ 2000-10-19 15:20 Latchesar Ionkov
  0 siblings, 0 replies; 4+ messages in thread
From: Latchesar Ionkov @ 2000-10-19 15:20 UTC (permalink / raw)
  To: 9fans

[-- Attachment #1: Type: text/plain, Size: 158 bytes --]

Hi,

Here is a driver for SMC EtherEZ PCMCIA card. It should be easily enhanced
to support all network cards that use SMC 91cXX chips.

Thanks,
	Lucho

[-- Attachment #2: ethersmc.c --]
[-- Type: text/plain, Size: 15868 bytes --]

/*
 * SMC EtherEZ (SMC91cXX chip) PCMCIA card support.
 */

#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
#include "../port/error.h"
#include "../port/netif.h"
#include "etherif.h"

enum {
	IoSize		= 0x10,		/* port pool size */
	TxTimeout	= 150,
};

enum {	/* PCMCIA related */
	TupleFunce	= 0x22,
	TfNodeId	= 0x04,
};

enum {	/* bank 0 registers */
	Tcr			= 0x0000,	/* transmit control */
	Eph			= 0x0002,	/* ethernet protocol handler */
	Rcr			= 0x0004,	/* receiver control */
	Counter		= 0x0006,	/* statistics counter */
	MemInfo		= 0x0008,
	MemCfg		= 0x000A,
};

enum {	/* bank 1 registers */
	Config		= 0x0000,
	BaseAddr		= 0x0002,
	Addr0		= 0x0004,	/* ethernet address */
	Addr1		= 0x0006,
	Addr2		= 0x0008,
	General		= 0x000A,
	Control		= 0x000C,
};

enum {	/* bank 2 registers */
	MmuCmd		= 0x0000,
	PktNo		= 0x0002,
	AllocRes		= 0x0003,
	FifoPorts		= 0x0004,
	Pointer		= 0x0006,
	Data1		= 0x0008,
	Interrupt		= 0x000C,
	IntrMask		= 0x000D,
};

enum {	/* bank 3 registers */
	Mcast0		= 0x0000,
	Mcast2		= 0x0002,
	Mcast4		= 0x0004,
	Mcast6		= 0x0006,
	Revision		= 0x000A,
};

enum {
	BankSelect	= 0x000E	/* bank select register */
};

enum {
	BsrMask		= 0xFF00,	/* mask for chip identification */
	BsrId		= 0x3300,
};


enum {	/* Tcr values */
	TcrClear		= 0x0000,
	TcrEnable		= 0x0001,	/* enable transmit */
	TcrLoop		= 0x0002,	/* enable internal analogue loopback */
	TcrForceCol	= 0x0004,	/* force collision on next tx */
	TcrPadEn		= 0x0080,	/* pad short packets to 64 bytes */
	TcrNoCrc		= 0x0100,	/* do not append CRC */
	TcrMonCns	= 0x0400,	/* monitor carrier status */
	TcrFduplx		= 0x0800,
	TcrStpSqet	= 0x1000,
	TcrEphLoop	= 0x2000,
	TcrNormal	= TcrEnable,
};

enum {	/* Eph values */
	EphTxOk		= 0x0001,
	Eph1Col		= 0x0002,	/* single collision */
	EphMCol		= 0x0004,	/* multiple collisions */
	EphTxMcast	= 0x0008,	/* multicast transmit */
	Eph16Col		= 0x0010,	/* 16 collisions, tx disabled */
	EphSqet		= 0x0020,	/* SQE test failed, tx disabled */
	EphTxBcast	= 0x0040,	/* broadcast tx */
	EphDefr		= 0x0080,	/* deffered tx */
	EphLatCol		= 0x0200,	/* late collision, tx disabled */
	EphLostCarr	= 0x0400,	/* lost carrier, tx disabled */
	EphExcDefr	= 0x0800,	/* excessive defferals */
	EphCntRol	= 0x1000,	/* ECR counter(s) rolled over */
	EphRxOvrn	= 0x2000,	/* receiver overrun, packets dropped */
	EphLinkOk	= 0x4000,
	EphTxUnrn	= 0x8000,	/* tx underrun */
};

enum {	/* Rcr values */
	RcrClear		= 0x0000,
	RcrPromisc	= 0x0002,
	RcrAllMcast	= 0x0004,
	RcrEnable		= 0x0100,
	RcrStripCrc	= 0x0200,
	RcrSoftReset	= 0x8000,
	RcrNormal	= RcrStripCrc | RcrEnable,
};

enum { /* Counter value masks */
	CntColMask	= 0x000F,	/* collisions */
	CntMColMask	= 0x00F0,	/* multiple collisions */
	CntDtxMask	= 0x0F00,	/* deferred transmits */
	CntExDtxMask	= 0xF000,	/* excessively deferred transmits */

	CntColShr		= 1,
	CntMColShr	= 4,
	CntDtxShr	= 8,
};

enum { /* MemInfo value masks */
	MirTotalMask	= 0x00FF,
	MirFreeMask	= 0xFF00,
};

enum {	/* Config values */
	CfgIrqSel0	= 0x0002,
	CfgIrqSel1	= 0x0004,
	CfgDisLink	= 0x0040,	/* disable 10BaseT link test */
	Cfg16Bit		= 0x0080,
	CfgAuiSelect	= 0x0100,
	CfgSetSqlch	= 0x0200,
	CfgFullStep	= 0x0400,
	CfgNoWait	= 0x1000,
	CfgMiiSelect	= 0x8000,
};

enum {	/* Control values */
	CtlStore		= 0x0001,	/* store to EEPROM */
	CtlReload		= 0x0002,	/* reload EEPROM into registers */
	CtlEeSelect	= 0x0004,	/* select registers for reload/store */
	CtlTeEnable	= 0x0020,	/* tx error detection via eph irq */
	CtlCrEnable	= 0x0040,	/* counter rollover via eph irq */
	CtlLeEnable	= 0x0080,	/* link error detection via eph irq*/
	CtlAutoRls	= 0x0800,	/* auto release mode */
	CtlPowerDn	= 0x2000,
};

enum {	/* MmuCmd values */
	McBusy		= 0x0001,
	McAlloc		= 0x0020,	/* | with number of 256 byte packets - 1 */
	McReset		= 0x0040,
	McRelease	= 0x0080,	/* dequeue (but not free) current rx packet */
	McFreePkt	= 0x00A0,	/* dequeue and free current rx packet */
	McEnqueue	= 0x00C0,	/* enqueue the packet for tx */
	McTxReset	= 0x00E0,	/* reset transmit queues */
};

enum { /* AllocRes values */
	ArFailed		= 0x80,
};

enum {	/* FifoPorts values */
	FpTxEmpty	= 0x0080,
	FpRxEmpty	= 0x8000,
	FpTxMask		= 0x007F,
	FpRxMask		= 0x7F00,
};

enum {	/* Pointer values */
	PtrRead		= 0x2000,
	PtrAutoInc	= 0x4000,
	PtrRcv		= 0x8000,
};

enum {	/* Interrupt values */
	IntRcv		= 0x0001,
	IntTxError	= 0x0002,
	IntTxEmpty	= 0x0004,
	IntAlloc		= 0x0008,
	IntRxOvrn		= 0x0010,
	IntEph		= 0x0020,
};

enum { /* transmit status bits */
	TsSuccess		= 0x0001,
	Ts16Col		= 0x00A0,
	TsLatCol		= 0x0200,
	TsLostCar		= 0x0400,
};

enum { /* receive status bits */
	RsMcast		= 0x0001,
	RsTooShort	= 0x0400,
	RsTooLong	= 0x0800,
	RsOddFrame	= 0x1000,
	RsBadCrc		= 0x2000,
	RsAlgnErr		= 0x8000,
	RsError		= RsAlgnErr | RsBadCrc | RsTooLong | RsTooShort,
};

enum {
	RxLenMask	= 0x07FF,		/* significant rx len bits */
	HdrSize		= 6,			/* packet header length */
	PageSize		= 256,		/* page length */
};

typedef struct {
	Lock;
	ushort rev;
	int attached;
	Block *txbp;
	ulong txtime;

	ulong rovrn;
	ulong lcar;
	ulong col;
	ulong scol;
	ulong mcol;
	ulong lcol;
	ulong dfr;
} Smc91xx;

#define SELECT_BANK(x) outs(port + BankSelect, x)

static int
readnodeid(int slot, Ether* ether)
{
	uchar data[Eaddrlen + 1];
	int len;

	len = sizeof(data);
	if (pcmcistuple(slot, TupleFunce, TfNodeId, data, len) != len)
		return -1;

	if (data[0] != Eaddrlen)
		return -1;

	memmove(ether->ea, &data[1], Eaddrlen);
	return 0;
}

static void
chipreset(Ether* ether)
{
	int port;
	int i;

	port = ether->port;

	/* reset the chip */
	SELECT_BANK(0);
	outs(port + Rcr, RcrSoftReset);
	delay(1);
	outs(port + Rcr, RcrClear);
	outs(port + Tcr, TcrClear);
	SELECT_BANK(1);
	outs(port + Control, CtlAutoRls | CtlTeEnable |
		CtlCrEnable);

	for(i = 0; i < 6; i++) {
		outb(port + Addr0 +  i, ether->ea[i]);
	}

	SELECT_BANK(2);
	outs(port + MmuCmd, McReset);
}

static void
chipenable(Ether* ether)
{
	int port;

	port = ether->port;
	SELECT_BANK(0);
	outs(port + Tcr, TcrNormal);
	outs(port + Rcr, RcrNormal);
	SELECT_BANK(2);
	outb(port + IntrMask, IntEph | IntRxOvrn | IntRcv);
}

static void
attach(Ether *ether)
{
	Smc91xx* ctlr;

	ctlr = ether->ctlr;
	ilock(ctlr);

	if (ctlr->attached) {
		iunlock(ctlr);
		return;
	}

	chipenable(ether);
	ctlr->attached = 1;
	iunlock(ctlr);
}

static void
txstart(Ether* ether)
{
	int port;
	Smc91xx* ctlr;
	Block* bp;
	int len, npages;
	int pno;

	/* assumes ctlr is locked and bank 2 is selected */
	/* leaves bank 2 selected on return */
	port = ether->port;
	ctlr = ether->ctlr;

	if (ctlr->txbp) {
		bp = ctlr->txbp;
		ctlr->txbp = 0;
	} else {
		bp = qget(ether->oq);
		if (bp == 0)
			return;

		len = BLEN(bp);
		npages = (len + HdrSize) / PageSize;
		outs(port + MmuCmd, McAlloc | npages);
	}

	pno = inb(port + AllocRes);
	if (pno & ArFailed) {
		outb(port + IntrMask, inb(port + IntrMask) | IntAlloc);
		ctlr->txbp = bp;
		ctlr->txtime = MACHP(0)->ticks;
		return;
	}

	outb(port + PktNo, pno);
	outs(port + Pointer, PtrAutoInc);

	len = BLEN(bp);
	outs(port + Data1, 0);
	outb(port + Data1, (len + HdrSize) & 0xFF);
	outb(port + Data1, (len + HdrSize) >> 8);
	outss(port + Data1, bp->rp, len / 2);
	if ((len & 1) == 0) {
		outs(port + Data1, 0);
	} else {
		outb(port + Data1, bp->rp[len - 1]);
		outb(port + Data1, 0x20);	/* no info what 0x20 means */
	}

	outb(port + IntrMask, inb(port + IntrMask) |
			IntTxError | IntTxEmpty);

	outs(port + MmuCmd, McEnqueue);
	freeb(bp);
}

static void
receive(Ether* ether)
{
	int port;
	Block* bp;
	int pktno, status, len;

	/* assumes ctlr is locked and bank 2 is selected */
	/* leaves bank 2 selected on return */
	port = ether->port;

	pktno = ins(port + FifoPorts);
	if (pktno & FpRxEmpty) {
		return;
	}

	outs(port + Pointer, PtrRead | PtrRcv | PtrAutoInc);
	status = ins(port + Data1);
	len = ins(port + Data1) & RxLenMask - HdrSize;

	if (status & RsOddFrame)
		len++;

	if ((status & RsError) || (bp = iallocb(len)) == 0) {

		if (status & RsAlgnErr)
			ether->frames++;
		if (status & (RsTooShort | RsTooLong))
			ether->buffs++;
		if (status & RsBadCrc)
			ether->crcs++;

		outs(port + MmuCmd, McRelease);
		return;
	}

	/* packet length is padded to word */
	inss(port + Data1, bp->rp, len / 2);
	bp->wp = bp->rp + (len & ~1);

	if (len & 1) {
		*bp->wp = inb(port + Data1);
		bp->wp++;
	}

	etheriq(ether, bp, 1);
	ether->inpackets++;
	outs(port + MmuCmd, McRelease);
}

static void
txerror(Ether* ether)
{
	int port;
	Smc91xx* ctlr;
	int save_pkt;
	int pktno, status;

	/* assumes ctlr is locked and bank 2 is selected */
	/* leaves bank 2 selected on return */
	port = ether->port;
	ctlr = ether->ctlr;

	save_pkt = inb(port + PktNo);

	pktno = ins(port + FifoPorts) & FpTxMask;
	outb(port + PktNo, pktno);
	outs(port + Pointer, PtrAutoInc | PtrRead);
	status = ins(port + Data1);

	if (status & TsLostCar)
		ctlr->lcar++;

	if (status & TsLatCol)
		ctlr->lcol++;

	if (status & Ts16Col)
		ctlr->scol++;

	ether->oerrs++;

	SELECT_BANK(0);
	outs(port + Tcr, ins(port + Tcr) | TcrEnable);

	SELECT_BANK(2);
	outs(port + MmuCmd, McFreePkt);

	outb(port + PktNo, save_pkt);
}

static void
eph_irq(Ether* ether)
{
	int port;
	Smc91xx* ctlr;
	ushort status;
	int n;

	/* assumes ctlr is locked and bank 2 is selected */
	/* leaves bank 2 selected on return */
	port = ether->port;
	ctlr = ether->ctlr;

	SELECT_BANK(0);
	status = ins(port + Eph);

	if (status & EphCntRol) {
		/* read the counter register even if we don't need it */
		/* otherwise we will keep getting this interrupt */
		n = ins(port + Counter);
		ctlr->col += (n & CntColMask) >> CntColShr;
		ctlr->mcol += (n & CntMColMask) >> CntMColShr;
		ctlr->dfr += (n & CntDtxMask) >> CntDtxShr;
	}

	/* if there was a transmit error, Tcr is disabled */
	outs(port + Tcr, ins(port + Tcr) | TcrEnable);

	/* clear a link error interrupt */
	SELECT_BANK(1);
	outs(port + Control, CtlAutoRls);
	outs(port + Control, CtlAutoRls | CtlTeEnable | CtlCrEnable);

	SELECT_BANK(2);
}

static void
transmit(Ether* ether)
{
	Smc91xx* ctlr;
	int port, n;

	ctlr = ether->ctlr;
	port = ether->port;
	ilock(ctlr);

	if (ctlr->txbp) {
		n = TK2MS(MACHP(0)->ticks - ctlr->txtime);
		if (n > TxTimeout) {
			chipreset(ether);
			chipenable(ether);
			freeb(ctlr->txbp);
			ctlr->txbp = 0;
		}
		iunlock(ctlr);
		return;
	}

	SELECT_BANK(2);
	txstart(ether);
	iunlock(ctlr);
}

static void
interrupt(Ureg*, void *arg)
{
	int port;
	Smc91xx* ctlr;
	Ether* ether;
	int save_bank;
	int save_pointer;
	int mask, status;

	ether = arg;
	port = ether->port;
	ctlr = ether->ctlr;

	ilock(ctlr);
	save_bank = ins(port + BankSelect);
	SELECT_BANK(2);
	save_pointer = ins(port + Pointer);

	mask = inb(port + IntrMask);
	outb(port + IntrMask, 0);

	while ((status = inb(port + Interrupt) & mask) != 0) {
		if (status & IntRcv) {
			receive(ether);
		}

		if (status & IntTxError) {
			txerror(ether);
		}

		if (status & IntTxEmpty) {
			outb(port + Interrupt, IntTxEmpty);
			outb(port + IntrMask, mask & ~IntTxEmpty);
			txstart(ether);
			mask = inb(port + IntrMask);
		}

		if (status & IntAlloc) {
			outb(port + IntrMask, mask & ~IntAlloc);
			txstart(ether);;
			mask = inb(port + IntrMask);
		}

		if (status & IntRxOvrn) {
			ctlr->rovrn++;
			ether->misses++;
			outb(port + Interrupt,IntRxOvrn);
		}

		if (status & IntEph)
			eph_irq(ether);
	}

	outb(port + IntrMask, mask);
	outs(port + Pointer, save_pointer);
	outs(port + BankSelect, save_bank);
	iunlock(ctlr);
}

static void
promiscuous(void* arg, int on)
{
	int port;
	Smc91xx *ctlr;
	Ether* ether;
	ushort x;

	ether = arg;
	port = ether->port;
	ctlr = ether->ctlr;

	ilock(ctlr);
	SELECT_BANK(0);
	x = ins(port + Rcr);
	if (on)
		x |= RcrPromisc;
	else
		x &= ~RcrPromisc;

	outs(port + Rcr, x);
	iunlock(ctlr);
}

static void
multicast(void* arg, uchar *addr, int on)
{
	int port;
	Smc91xx*ctlr;
	Ether *ether;
	ushort x;

	USED(addr, on);

	ether = arg;
	port = ether->port;
	ctlr = ether->ctlr;
	ilock(ctlr);

	SELECT_BANK(0);
	x = ins(port + Rcr);

	if (ether->nmaddr)
		x |= RcrAllMcast;
	else
		x &= ~RcrAllMcast;

	outs(port + Rcr, x);
	iunlock(ctlr);
}

static long
ifstat(Ether* ether, void* a, long n, ulong offset)
{
	static char *chiprev[] = {
		[3] 	"92",
		[5]	"95",
		[7]	"100",
		[8]	"100-FD",
		[9]	"110",
	};

	Smc91xx* ctlr;
	char* p;
	int r, len;
	char* s;

	if (n == 0)
		return 0;

	ctlr = ether->ctlr;
	p = malloc(READSTR);

	s = 0;
	if (ctlr->rev > 0) {
		r = ctlr->rev >> 4;
		if (r < nelem(chiprev))
			s = chiprev[r];

		if (r == 4) {
			if ((ctlr->rev & 0x0F) >= 6)
				s = "96";
			else
				s = "94";
		}
	}

	len = snprint(p, READSTR, "rev: 91c%s\n", (s) ? s : "???");
	len += snprint(p + len, READSTR - len, "rxovrn: %uld\n", ctlr->rovrn);
	len += snprint(p + len, READSTR - len, "lcar: %uld\n", ctlr->lcar);
	len += snprint(p + len, READSTR - len, "col: %uld\n", ctlr->col);
	len += snprint(p + len, READSTR - len, "16col: %uld\n", ctlr->scol);
	len += snprint(p + len, READSTR - len, "mcol: %uld\n", ctlr->mcol);
	len += snprint(p + len, READSTR - len, "lcol: %uld\n", ctlr->lcol);
	len += snprint(p + len, READSTR - len, "dfr: %uld\n", ctlr->dfr);
	USED(len);

	n = readstr(offset, a, n, p);
	free(p);

	return n;
}

static int
reset(Ether* ether)
{
	int port;
	int i, x;
	char* type;
	Smc91xx* ctlr;
	int slot;
	uchar ea[Eaddrlen];

	if (ether->irq == 0)
		ether->irq = 9;

	if (ether->port == 0)
		ether->port = 0x100;

	type = "8020";
	for(i = 0; i < ether->nopt; i++) {
		if (cistrncmp(ether->opt[i], "id=", 3))
			continue;
		type = &ether->opt[i][3];
		break;
	}

	if ((slot = pcmspecial(type, ether)) < 0)
		return -1;

	if (ioalloc(ether->port, IoSize, 0, "smc91cXX") < 0) {
		pcmspecialclose(slot);
		return -1;
	}

	ether->ctlr = malloc(sizeof(Smc91xx));
	ctlr = ether->ctlr;
	if (ctlr == 0) {
		iofree(ether->port);
		pcmspecialclose(slot);
	}

	ilock(ctlr);
	ctlr->rev = 0;
	ctlr->txbp = nil;
	ctlr->attached = 0;
	ctlr->rovrn = 0;
	ctlr->lcar = 0;
	ctlr->col = 0;
	ctlr->scol = 0;
	ctlr->mcol = 0;
	ctlr->lcol = 0;
	ctlr->dfr = 0;

	port = ether->port;

	SELECT_BANK(1);
	if ((ins(port + BankSelect) & BsrMask) != BsrId) {
		outs(port + Control, 0);	/* try powering up the chip */
		delay(55);
	}

	outs(port + Config, ins(port + Config) | Cfg16Bit);
	x = ins(port + BaseAddr);

	if (((ins(port + BankSelect) & BsrMask) != BsrId) ||
		((x >> 8) == (x & 0xFF))) {
		iunlock(ctlr);
		iofree(port);
		pcmspecialclose(slot);
		return -1;
	}

	SELECT_BANK(3);
	ctlr->rev = ins(port + Revision) & 0xFF;

	memset(ea, 0, Eaddrlen);
	if (memcmp(ea, ether->ea, Eaddrlen) == 0) {
		if (readnodeid(slot, ether) < 0) {
			print("Smc91cXX: cannot find ethernet address\n");
			iunlock(ctlr);
			iofree(port);
			pcmspecialclose(slot);
			return -1;
		}
	}

	chipreset(ether);

	ether->attach = attach;
	ether->transmit = transmit;
	ether->interrupt = interrupt;
	ether->ifstat = ifstat;
	ether->promiscuous = promiscuous;
	ether->multicast = multicast;
	ether->arg = ether;
	iunlock(ctlr);
	return 0;
}

void
ethersmclink(void)
{
	addethercard("smc91cXX", reset);
}

[-- Attachment #3: fns.h.diff --]
[-- Type: text/plain, Size: 101 bytes --]

98c98
< int	pcmcistuple(int, int, void*, int);
---
> int	pcmcistuple(int, int, int, void*, int);

[-- Attachment #4: devi82365.c.diff --]
[-- Type: text/plain, Size: 1178 bytes --]

1096c1096
< xcistuple(int slotno, int tuple, void *v, int nv, int attr)
---
> xcistuple(int slotno, int tuple, int subtuple, void *v, int nv, int attr)
1102,1103c1102,1103
< 	uchar type, link;
< 	int this;
---
> 	uchar type, link, n, c;
> 	int this, subtype;
1125c1125,1135
< 		if(type == tuple) {
---
>
> 		n = link;
> 		if (link > 1 && subtuple != -1) {
> 			if (readc(&cis, &c) != 1)
> 				break;
> 			subtype = c;
> 			n--;
> 		} else
> 			subtype = -1;
>
> 		if(type == tuple && subtype == subtuple) {
1127c1137
< 			for(l=0; l<nv && l<link; l++)
---
> 			for(l=0; l<nv && l<n; l++)
1140c1150
< pcmcistuple(int slotno, int tuple, void *v, int nv)
---
> pcmcistuple(int slotno, int tuple, int subtuple, void *v, int nv)
1145c1155
< 	if((n = xcistuple(slotno, tuple, v, nv, 1)) >= 0)
---
> 	if((n = xcistuple(slotno, tuple, subtuple, v, nv, 1)) >= 0)
1147c1157
< 	return xcistuple(slotno, tuple, v, nv, 0);
---
> 	return xcistuple(slotno, tuple, subtuple, v, nv, 0);
1164c1174
< 		if((nv = pcmcistuple(pp->slotno, cistab[i].n, v, sizeof(v))) >= 0) {
---
> 		if((nv = pcmcistuple(pp->slotno, cistab[i].n, -1, v, sizeof(v))) >= 0) {

[-- Attachment #5: ether589.c.diff --]
[-- Type: text/plain, Size: 112 bytes --]

155c155
< 		if(pcmcistuple(slot, 0x88, ea, 6) == 6) {
---
> 		if(pcmcistuple(slot, 0x88, -1, ea, 6) == 6) {

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2000-10-22 17:33 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-10-20 17:43 [9fans] smc 91cxx driver jmk
2000-10-22 17:33 ` Latchesar Ionkov
  -- strict thread matches above, loose matches on Subject: below --
2000-10-20 15:20 jmk
2000-10-19 15:20 Latchesar Ionkov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).