plan 9 kernel history: overview | file list | diff list

1991/0423/port/devscsi.c (diff list | history)

1991/0110/sys/src/9/port/devscsi.c:318,3241991/0112/sys/src/9/port/devscsi.c:318,324 (short | long)
1991/0110    
#define	DEV	((Scsictl *)&PORT[Scsiaddr]) 
 
static long	poot; 
#define	WAIT	(poot=0, (poot==0?0:poot)) 
1991/0112    
#define	WAIT	(poot=0, poot==0?0:poot) 
1991/0110    
 
#define	PUT(a,d)	(DEV->asr=(a), WAIT, DEV->data=(d)) 
#define	GET(a)		(DEV->asr=(a), WAIT, DEV->data) 
1991/0110/sys/src/9/port/devscsi.c:470,4761991/0112/sys/src/9/port/devscsi.c:470,476
1991/0110    
void 
scsidmaintr(void) 
{ 
	uchar *p=0; 
1991/0112    
		uchar *p = 0; 
1991/0110    
/* 
 *	if (scsirflag) { 
 *		unsigned char *p; 
1991/0112/sys/src/9/port/devscsi.c:7,151991/0115/sys/src/9/port/devscsi.c:7,12 (short | long)
1991/0110    
#include	"devtab.h" 
#include	"io.h" 
 
#include	"port.h" 
#include	"scsi.h" 
                 
int	scsiintr(void); 
 
#define	DPRINT	if(debug)kprint 
1991/0115/sys/src/9/port/devscsi.c:152,1581991/0318/sys/src/9/port/devscsi.c:152,158 (short | long)
1991/0110    
		cmd->save = cmd->data.base; 
		scsiexec(cmd, 1); 
		n = cmd->data.ptr - cmd->data.base; 
		memcpy(a, cmd->data.base, n); 
1991/0318    
		memmove(a, cmd->data.base, n); 
1991/0110    
		break; 
	case Qdebug: 
		if (c->offset == 0) { 
1991/0115/sys/src/9/port/devscsi.c:184,1901991/0318/sys/src/9/port/devscsi.c:184,190
1991/0110    
			error(Ebadarg); 
		/*qlock(cmd);*/ 
		cmd->cmd.base = cmd->cmdblk; 
		memcpy(cmd->cmd.base, a, n); 
1991/0318    
		memmove(cmd->cmd.base, a, n); 
1991/0110    
		cmd->cmd.lim = cmd->cmd.base + n; 
		cmd->cmd.ptr = cmd->cmd.base; 
		cmd->target = (c->qid.path>>4)&7; 
1991/0115/sys/src/9/port/devscsi.c:199,2051991/0318/sys/src/9/port/devscsi.c:199,205
1991/0110    
		cmd->data.lim = cmd->data.base + n; 
		cmd->data.ptr = cmd->data.base; 
		cmd->save = cmd->data.base; 
		memcpy(cmd->data.base, a, n); 
1991/0318    
		memmove(cmd->data.base, a, n); 
1991/0110    
		scsiexec(cmd, 0); 
		n = cmd->data.ptr - cmd->data.base; 
		break; 
1991/0115/sys/src/9/port/devscsi.c:282,2881991/0318/sys/src/9/port/devscsi.c:282,288
1991/0110    
	int status; 
	scsicmd(&cmd, dev, 0x03, buf, sizeof buf); 
	status = scsiexec(&cmd, 1); 
	memcpy(p, buf, sizeof buf); 
1991/0318    
	memmove(p, buf, sizeof buf); 
1991/0110    
	qunlock(&cmd); 
	if ((status&0xff00) != 0x6000) 
		error(Eio); 
1991/0115/sys/src/9/port/devscsi.c:297,3031991/0318/sys/src/9/port/devscsi.c:297,303
1991/0110    
	int status; 
	scsicmd(&cmd, dev, 0x25, buf, sizeof buf); 
	status = scsiexec(&cmd, 1); 
	memcpy(p, buf, sizeof buf); 
1991/0318    
	memmove(p, buf, sizeof buf); 
1991/0110    
	qunlock(&cmd); 
	if ((status&0xff00) != 0x6000) 
		error(Eio); 
1991/0318/sys/src/9/port/devscsi.c:117,1231991/0411/sys/src/9/port/devscsi.c:117,123 (short | long)
1991/0110    
{} 
 
long 
scsiread(Chan *c, char *a, long n) 
1991/0411    
scsiread(Chan *c, char *a, long n, ulong offset) 
1991/0110    
{ 
	Scsi *cmd = &staticcmd; 
	if (n == 0) 
1991/0318/sys/src/9/port/devscsi.c:125,1311991/0411/sys/src/9/port/devscsi.c:125,131
1991/0110    
	if(c->qid.path & CHDIR) 
		return devdirread(c, a, n, 0, 0, scsigen); 
	if(c->qid.path==1){ 
		if(c->offset == 0){ 
1991/0411    
		if(offset == 0){ 
1991/0110    
			*a = ownid; 
			n = 1; 
		}else 
1991/0318/sys/src/9/port/devscsi.c:155,1611991/0411/sys/src/9/port/devscsi.c:155,161
1991/0318    
		memmove(a, cmd->data.base, n); 
1991/0110    
		break; 
	case Qdebug: 
		if (c->offset == 0) { 
1991/0411    
		if (offset == 0) { 
1991/0110    
			n=1; 
			*a="01"[debugs[(c->qid.path>>4)&7]!=0]; 
		} else 
1991/0318/sys/src/9/port/devscsi.c:168,1781991/0411/sys/src/9/port/devscsi.c:168,178
1991/0110    
} 
 
long 
scsiwrite(Chan *c, char *a, long n) 
1991/0411    
scsiwrite(Chan *c, char *a, long n, ulong offset) 
1991/0110    
{ 
	Scsi *cmd = &staticcmd; 
	if(c->qid.path==1 && n>0){ 
		if(c->offset == 0){ 
1991/0411    
		if(offset == 0){ 
1991/0110    
			n = 1; 
			ownid=*a; 
			scsiinit(); 
1991/0318/sys/src/9/port/devscsi.c:204,2101991/0411/sys/src/9/port/devscsi.c:204,210
1991/0110    
		n = cmd->data.ptr - cmd->data.base; 
		break; 
	case Qdebug: 
		if (c->offset == 0) { 
1991/0411    
		if (offset == 0) { 
1991/0110    
			debugs[(c->qid.path>>4)&7] = (*a=='1'); 
			n = 1; 
		} else 
1991/0411/sys/src/9/port/devscsi.c:94,991991/0419/sys/src/9/port/devscsi.c:94,105 (short | long)
1991/0110    
	return devwalk(c, name, 0, 0, scsigen); 
} 
 
1991/0419    
Chan* 
scsiclwalk(Chan *c, char *name) 
{ 
	return devclwalk(c, name); 
} 
 
1991/0110    
void 
scsistat(Chan *c, char *db) 
{ 
1991/0419/sys/src/9/port/devscsi.c:24,301991/0423/sys/src/9/port/devscsi.c:24,31 (short | long)
1991/0110    
#define	NSCSI	(sizeof scsidir/sizeof(Dirtab)) 
 
static Scsi	staticcmd;	/* BUG */ 
static uchar	datablk[8192];	/* BUG */ 
1991/0423    
#define	DATASIZE	(8*1024) 
static uchar	datablk[DATASIZE];	/* BUG */ 
1991/0110    
 
static int	debugs[8]; 
static int	isscsi; 
1991/0419/sys/src/9/port/devscsi.c:120,1261991/0423/sys/src/9/port/devscsi.c:121,138
1991/0110    
 
void 
scsiclose(Chan *c) 
{} 
1991/0423    
{ 
	Scsi *cmd = &staticcmd; 
	 
	if((c->qid.path & CHDIR) || c->qid.path==1) 
		return; 
	if((c->qid.path & 0xf) == Qcmd){ 
		if(canqlock(cmd) || cmd->pid == u->p->pid){ 
			cmd->pid = 0; 
			qunlock(cmd); 
		} 
	} 
} 
1991/0110    
 
long 
1991/0411    
scsiread(Chan *c, char *a, long n, ulong offset) 
1991/0419/sys/src/9/port/devscsi.c:132,1371991/0423/sys/src/9/port/devscsi.c:144,150
1991/0110    
		return devdirread(c, a, n, 0, 0, scsigen); 
	if(c->qid.path==1){ 
1991/0411    
		if(offset == 0){ 
1991/0423    
			/*void scsidump(void); scsidump();*/ 
1991/0110    
			*a = ownid; 
			n = 1; 
		}else 
1991/0419/sys/src/9/port/devscsi.c:140,1561991/0423/sys/src/9/port/devscsi.c:153,178
1991/0110    
	case Qcmd: 
		if (n < 4) 
			error(Ebadarg); 
		/*if(canqlock(cmd)){ 
1991/0423    
		if(canqlock(cmd)){ 
1991/0110    
			qunlock(cmd); 
			error(Egreg); 
		}*/ 
1991/0423    
		} 
		if(cmd->pid != u->p->pid) 
			error(Egreg); 
1991/0110    
		n = 4; 
		*a++ = cmd->state>>8; *a++ = cmd->state; 
1991/0423    
		*a++ = 0; *a++ = 0; 
1991/0110    
		*a++ = cmd->status>>8; *a = cmd->status; 
		/*qunlock(cmd);*/ 
1991/0423    
		cmd->pid = 0; 
		qunlock(cmd); 
1991/0110    
		break; 
	case Qdata: 
		if (n > sizeof datablk) 
1991/0423    
		if(canqlock(cmd)){ 
			qunlock(cmd); 
			error(Egreg); 
		} 
		if(cmd->pid != u->p->pid) 
			error(Egreg); 
		if (n > DATASIZE) 
1991/0110    
			error(Ebadarg); 
		cmd->data.base = datablk; 
		cmd->data.lim = cmd->data.base + n; 
1991/0419/sys/src/9/port/devscsi.c:181,1871991/0423/sys/src/9/port/devscsi.c:203,209
1991/0411    
		if(offset == 0){ 
1991/0110    
			n = 1; 
			ownid=*a; 
			scsiinit(); 
1991/0423    
			scsireset(); 
1991/0110    
		}else 
			n = 0; 
	}else switch ((int)c->qid.path & 0xf){ 
1991/0419/sys/src/9/port/devscsi.c:188,1941991/0423/sys/src/9/port/devscsi.c:210,217
1991/0110    
	case Qcmd: 
		if (n < 6 || n > sizeof cmd->cmdblk) 
			error(Ebadarg); 
		/*qlock(cmd);*/ 
1991/0423    
		qlock(cmd); 
		cmd->pid = u->p->pid; 
1991/0110    
		cmd->cmd.base = cmd->cmdblk; 
1991/0318    
		memmove(cmd->cmd.base, a, n); 
1991/0110    
		cmd->cmd.lim = cmd->cmd.base + n; 
1991/0419/sys/src/9/port/devscsi.c:195,2051991/0423/sys/src/9/port/devscsi.c:218,233
1991/0110    
		cmd->cmd.ptr = cmd->cmd.base; 
		cmd->target = (c->qid.path>>4)&7; 
		cmd->lun = (a[1]>>5)&7; 
		cmd->state = 0; 
		cmd->status = 0xFFFF; 
		break; 
	case Qdata: 
		if (n > sizeof datablk) 
1991/0423    
		if(canqlock(cmd)){ 
			qunlock(cmd); 
			error(Egreg); 
		} 
		if(cmd->pid != u->p->pid) 
			error(Egreg); 
		if (n > DATASIZE) 
1991/0110    
			error(Ebadarg); 
		cmd->data.base = datablk; 
		cmd->data.lim = cmd->data.base + n; 
1991/0419/sys/src/9/port/devscsi.c:234,2511991/0423/sys/src/9/port/devscsi.c:262,282
1991/0110    
	error(Eperm); 
} 
 
void 
scsicmd(Scsi *cmd, int dev, int cmdbyte, uchar *buf, long size) 
1991/0423    
Scsi * 
scsicmd(int dev, int cmdbyte, long size) 
1991/0110    
{ 
1991/0423    
	Scsi *cmd = &staticcmd; 
 
	if(size > DATASIZE) 
		panic("scsicmd %d", size); 
1991/0110    
	qlock(cmd); 
	cmd->target = dev>>3; 
	cmd->lun = dev&7; 
	cmd->cmd.base = cmd->cmdblk; 
	cmd->data.base = buf; 
	cmd->cmd.ptr = cmd->cmd.base; 
	memset(cmd->cmdblk, 0, sizeof cmd->cmdblk); 
	cmd->cmdblk[0] = cmdbyte; 
	switch (cmdbyte>>5) { 
1991/0423    
	switch(cmdbyte>>5){ 
1991/0110    
	case 0: 
		cmd->cmd.lim = &cmd->cmdblk[6]; break; 
	case 1: 
1991/0419/sys/src/9/port/devscsi.c:253,2591991/0423/sys/src/9/port/devscsi.c:284,290
1991/0110    
	default: 
		cmd->cmd.lim = &cmd->cmdblk[12]; break; 
	} 
	switch (cmdbyte) { 
1991/0423    
	switch(cmdbyte){ 
1991/0110    
	case 0x00:	/* test unit ready */ 
		break; 
	case 0x03:	/* read sense data */ 
1991/0419/sys/src/9/port/devscsi.c:262,2801991/0423/sys/src/9/port/devscsi.c:293,313
1991/0110    
	case 0x25:	/* read capacity */ 
		break; 
	} 
1991/0423    
	cmd->data.base = datablk; 
1991/0110    
	cmd->data.lim = cmd->data.base + size; 
	cmd->data.ptr = cmd->data.base; 
	cmd->save = cmd->data.base; 
1991/0423    
	return cmd; 
1991/0110    
} 
 
int 
scsiready(int dev) 
{ 
	static Scsi cmd; 
1991/0423    
	Scsi *cmd = scsicmd(dev, 0x00, 0); 
1991/0110    
	int status; 
	scsicmd(&cmd, dev, 0x00, 0, 0); 
	status = scsiexec(&cmd, 0); 
	qunlock(&cmd); 
1991/0423    
 
	status = scsiexec(cmd, 0); 
	qunlock(cmd); 
1991/0110    
	if ((status&0xff00) != 0x6000) 
		error(Eio); 
	return status&0xff; 
1991/0419/sys/src/9/port/devscsi.c:281,2951991/0423/sys/src/9/port/devscsi.c:314,327
1991/0110    
} 
 
int 
scsisense(int dev, uchar *p) 
1991/0423    
scsisense(int dev, void *p) 
1991/0110    
{ 
	static Scsi cmd; 
	static uchar buf[18]; 
1991/0423    
	Scsi *cmd = scsicmd(dev, 0x03, 18); 
1991/0110    
	int status; 
	scsicmd(&cmd, dev, 0x03, buf, sizeof buf); 
	status = scsiexec(&cmd, 1); 
1991/0318    
	memmove(p, buf, sizeof buf); 
1991/0110    
	qunlock(&cmd); 
1991/0423    
 
	status = scsiexec(cmd, 1); 
	memmove(p, cmd->data.base, 18); 
	qunlock(cmd); 
1991/0110    
	if ((status&0xff00) != 0x6000) 
		error(Eio); 
	return status&0xff; 
1991/0419/sys/src/9/port/devscsi.c:296,3101991/0423/sys/src/9/port/devscsi.c:328,341
1991/0110    
} 
 
int 
scsicap(int dev, uchar *p) 
1991/0423    
scsicap(int dev, void *p) 
1991/0110    
{ 
	static Scsi cmd; 
	static uchar buf[8]; 
1991/0423    
	Scsi *cmd = scsicmd(dev, 0x25, 8); 
1991/0110    
	int status; 
	scsicmd(&cmd, dev, 0x25, buf, sizeof buf); 
	status = scsiexec(&cmd, 1); 
1991/0318    
	memmove(p, buf, sizeof buf); 
1991/0110    
	qunlock(&cmd); 
1991/0423    
 
	status = scsiexec(cmd, 1); 
	memmove(p, cmd->data.base, 8); 
	qunlock(cmd); 
1991/0110    
	if ((status&0xff00) != 0x6000) 
		error(Eio); 
	return status&0xff; 
1991/0419/sys/src/9/port/devscsi.c:381,3861991/0423/sys/src/9/port/devscsi.c:412,418
1991/0110    
		nexterror(); 
	} 
	scsirflag = rflag; 
1991/0423    
	p->rflag = rflag; 
1991/0110    
	datap = p->data.base; 
	if ((ownid & 0x08) && rflag) 
		PUT(Dest_id, 0x40|p->target); 
1991/0423/sys/src/9/port/devscsi.c:95,1061991/0427/sys/src/9/port/devscsi.c:95,100 (short | long)
1991/0110    
	return devwalk(c, name, 0, 0, scsigen); 
} 
 
1991/0419    
Chan* 
scsiclwalk(Chan *c, char *name) 
{ 
	return devclwalk(c, name); 
} 
                 
1991/0110    
void 
scsistat(Chan *c, char *db) 
{ 
1991/0427/sys/src/9/port/devscsi.c:31,361991/0514/sys/src/9/port/devscsi.c:31,42 (short | long)
1991/0110    
static int	isscsi; 
static int	ownid = 0x08|7; /* enable advanced features */ 
 
1991/0514    
void * 
dmaalloc(ulong n) 
{ 
	return ialloc(n, 0); 
} 
 
1991/0110    
static int 
scsigen1(Chan *c, long qid, Dir *dp) 
{ 
1991/0514/sys/src/9/port/devscsi.c:104,1101991/0627/sys/src/9/port/devscsi.c:104,110 (short | long)
1991/0110    
void 
scsistat(Chan *c, char *db) 
{ 
	devstat(c, db, 0, 0, scsigen); 
1991/0627    
	devstat(c, db, 0, 0, scsigeno); 
1991/0110    
} 
 
Chan * 
1991/0514/sys/src/9/port/devscsi.c:579,5831991/0627/sys/src/9/port/devscsi.c:579,587
1991/0110    
		default: 
			panic("scsi status 0x%2.2ux", status); 
		} 
1991/0627    
		kprint("resetting..."); 
		PUT(Own_id, ownid); 
		PUT(Cmd, Reset); 
		break; 
1991/0110    
	} 
} 
1991/0627/sys/src/9/port/devscsi.c:104,1101991/0705/sys/src/9/port/devscsi.c:104,110 (short | long)
1991/0110    
void 
scsistat(Chan *c, char *db) 
{ 
1991/0627    
	devstat(c, db, 0, 0, scsigeno); 
1991/0705    
	devstat(c, db, 0, 0, scsigen); 
1991/0110    
} 
 
Chan * 
1991/0627/sys/src/9/port/devscsi.c:579,5871991/0705/sys/src/9/port/devscsi.c:579,583
1991/0110    
		default: 
			panic("scsi status 0x%2.2ux", status); 
		} 
1991/0627    
		kprint("resetting..."); 
		PUT(Own_id, ownid); 
		PUT(Cmd, Reset); 
		break; 
1991/0110    
	} 
} 
1991/0705/sys/src/9/port/devscsi.c:104,1101991/0706/sys/src/9/port/devscsi.c:104,110 (short | long)
1991/0110    
void 
scsistat(Chan *c, char *db) 
{ 
1991/0705    
	devstat(c, db, 0, 0, scsigen); 
1991/0706    
	devstat(c, db, 0, 0, scsigeno); 
1991/0110    
} 
 
Chan * 
1991/0705/sys/src/9/port/devscsi.c:579,5831991/0706/sys/src/9/port/devscsi.c:579,587
1991/0110    
		default: 
			panic("scsi status 0x%2.2ux", status); 
		} 
1991/0706    
		kprint("resetting..."); 
		PUT(Own_id, ownid); 
		PUT(Cmd, Reset); 
		break; 
1991/0110    
	} 
} 
1991/0706/sys/src/9/port/devscsi.c:7,411991/0927/sys/src/9/port/devscsi.c:7,83 (short | long)
1991/0110    
#include	"devtab.h" 
#include	"io.h" 
 
int	scsiintr(void); 
                 
#define	DPRINT	if(debug)kprint 
 
enum { 
	Qdir, Qcmd, Qdata, Qdebug, 
1991/0927    
typedef struct Scsi	Scsi; 
typedef struct Scsidata	Scsidata; 
 
#define Nbuf	4 
#define DATASIZE (8*1024) 
enum 
{ 
	ScsiTestunit	= 0x00, 
	ScsiExtsens	= 0x03, 
	ScsiGetcap	= 0x25, 
	ScsiRead	= 0x08, 
	ScsiWrite	= 0x0a, 
 
	/* 
	 * data direction 
	 */ 
	ScsiIn		= 1, 
	ScsiOut		= 0, 
1991/0110    
}; 
 
1991/0927    
struct Scsidata 
{ 
	uchar	*base; 
	uchar	*lim; 
	uchar	*ptr; 
}; 
 
struct Scsi 
{ 
	QLock; 
	ulong	pid; 
	ushort	target; 
	ushort	lun; 
	ushort	rflag; 
	ushort	status; 
	Scsidata cmd; 
	Scsidata data; 
	Scsibuf	*b; 
	uchar	*save; 
	uchar	cmdblk[16]; 
}; 
 
struct{ 
	Lock; 
	Scsibuf	*free; 
}scsibufalloc; 
 
static Scsi	staticcmd;	/* BUG: should be one per scsi device */ 
 
enum 
{ 
	Qdir, 
	Qcmd, 
	Qdata, 
	Qdebug, 
}; 
 
1991/0110    
static Dirtab scsidir[]={ 
	"cmd",		{Qcmd},		0,	0600, 
	"data",		{Qdata},	0,	0600, 
	"debug",	{Qdebug},	1,	0600, 
}; 
                 
#define	NSCSI	(sizeof scsidir/sizeof(Dirtab)) 
 
static Scsi	staticcmd;	/* BUG */ 
1991/0423    
#define	DATASIZE	(8*1024) 
static uchar	datablk[DATASIZE];	/* BUG */ 
1991/0110    
                 
static int	debugs[8]; 
static int	isscsi; 
static int	ownid = 0x08|7; /* enable advanced features */ 
 
1991/0514    
void * 
dmaalloc(ulong n) 
{ 
	return ialloc(n, 0); 
} 
1991/0927    
int	scsiexec(Scsi*, int); 
int	scsiintr(void); 
1991/0514    
 
1991/0110    
static int 
scsigen1(Chan *c, long qid, Dir *dp) 
1991/0706/sys/src/9/port/devscsi.c:77,881991/0927/sys/src/9/port/devscsi.c:119,124
1991/0110    
	return scsigen1(c, (c->qid.path&~CHDIR)+s+1, dp); 
} 
 
void 
scsireset(void) 
{ 
	addportintr(scsiintr); 
} 
                 
Chan * 
scsiattach(char *param) 
{ 
1991/0706/sys/src/9/port/devscsi.c:138,1441991/0927/sys/src/9/port/devscsi.c:174,181
1991/0411    
scsiread(Chan *c, char *a, long n, ulong offset) 
1991/0110    
{ 
	Scsi *cmd = &staticcmd; 
	if (n == 0) 
1991/0927    
 
	if(n == 0) 
1991/0110    
		return 0; 
	if(c->qid.path & CHDIR) 
		return devdirread(c, a, n, 0, 0, scsigen); 
1991/0706/sys/src/9/port/devscsi.c:149,1571991/0927/sys/src/9/port/devscsi.c:186,194
1991/0110    
			n = 1; 
		}else 
			n = 0; 
	}else switch((int)(c->qid.path & 0xf)){ 
1991/0927    
	}else switch(c->qid.path & 0xf){ 
1991/0110    
	case Qcmd: 
		if (n < 4) 
1991/0927    
		if(n < 4) 
1991/0110    
			error(Ebadarg); 
1991/0423    
		if(canqlock(cmd)){ 
1991/0110    
			qunlock(cmd); 
1991/0706/sys/src/9/port/devscsi.c:160,1671991/0927/sys/src/9/port/devscsi.c:197,206
1991/0423    
		if(cmd->pid != u->p->pid) 
			error(Egreg); 
1991/0110    
		n = 4; 
1991/0423    
		*a++ = 0; *a++ = 0; 
1991/0110    
		*a++ = cmd->status>>8; *a = cmd->status; 
1991/0927    
		*a++ = 0; 
		*a++ = 0; 
		*a++ = cmd->status >> 8; 
		*a = cmd->status; 
1991/0423    
		cmd->pid = 0; 
		qunlock(cmd); 
1991/0110    
		break; 
1991/0706/sys/src/9/port/devscsi.c:174,1921991/0927/sys/src/9/port/devscsi.c:213,238
1991/0423    
			error(Egreg); 
		if (n > DATASIZE) 
1991/0110    
			error(Ebadarg); 
		cmd->data.base = datablk; 
1991/0927    
		cmd->b = scsibuf(); 
		cmd->data.base = cmd->b->virt; 
		if(waserror()){ 
			scsifree(cmd->b); 
			nexterror(); 
		} 
1991/0110    
		cmd->data.lim = cmd->data.base + n; 
		cmd->data.ptr = cmd->data.base; 
		cmd->save = cmd->data.base; 
		scsiexec(cmd, 1); 
1991/0927    
		scsiexec(cmd, ScsiIn); 
1991/0110    
		n = cmd->data.ptr - cmd->data.base; 
1991/0318    
		memmove(a, cmd->data.base, n); 
1991/0927    
		poperror(); 
		scsifree(cmd->b); 
1991/0110    
		break; 
	case Qdebug: 
1991/0411    
		if (offset == 0) { 
1991/0927    
		if(offset == 0){ 
1991/0110    
			n=1; 
			*a="01"[debugs[(c->qid.path>>4)&7]!=0]; 
		} else 
1991/0927    
		}else 
1991/0110    
			n = 0; 
		break; 
	default: 
1991/0706/sys/src/9/port/devscsi.c:199,2041991/0927/sys/src/9/port/devscsi.c:245,251
1991/0411    
scsiwrite(Chan *c, char *a, long n, ulong offset) 
1991/0110    
{ 
	Scsi *cmd = &staticcmd; 
1991/0927    
 
1991/0110    
	if(c->qid.path==1 && n>0){ 
1991/0411    
		if(offset == 0){ 
1991/0110    
			n = 1; 
1991/0706/sys/src/9/port/devscsi.c:206,2141991/0927/sys/src/9/port/devscsi.c:253,261
1991/0423    
			scsireset(); 
1991/0110    
		}else 
			n = 0; 
	}else switch ((int)c->qid.path & 0xf){ 
1991/0927    
	}else switch(c->qid.path & 0xf){ 
1991/0110    
	case Qcmd: 
		if (n < 6 || n > sizeof cmd->cmdblk) 
1991/0927    
		if(n < 6 || n > sizeof cmd->cmdblk) 
1991/0110    
			error(Ebadarg); 
1991/0423    
		qlock(cmd); 
		cmd->pid = u->p->pid; 
1991/0706/sys/src/9/port/devscsi.c:229,2471991/0927/sys/src/9/port/devscsi.c:276,301
1991/0423    
			error(Egreg); 
		if (n > DATASIZE) 
1991/0110    
			error(Ebadarg); 
		cmd->data.base = datablk; 
1991/0927    
		cmd->b = scsibuf(); 
		cmd->data.base = cmd->b->virt; 
		if(waserror()){ 
			scsifree(cmd->b); 
			nexterror(); 
		} 
1991/0110    
		cmd->data.lim = cmd->data.base + n; 
		cmd->data.ptr = cmd->data.base; 
		cmd->save = cmd->data.base; 
1991/0318    
		memmove(cmd->data.base, a, n); 
1991/0110    
		scsiexec(cmd, 0); 
1991/0927    
		scsiexec(cmd, ScsiOut); 
1991/0110    
		n = cmd->data.ptr - cmd->data.base; 
1991/0927    
		poperror(); 
		scsifree(cmd->b); 
1991/0110    
		break; 
	case Qdebug: 
1991/0411    
		if (offset == 0) { 
1991/0927    
		if(offset == 0){ 
1991/0110    
			debugs[(c->qid.path>>4)&7] = (*a=='1'); 
			n = 1; 
		} else 
1991/0927    
		}else 
1991/0110    
			n = 0; 
		break; 
	default: 
1991/0706/sys/src/9/port/devscsi.c:263,2991991/0927/sys/src/9/port/devscsi.c:317,355
1991/0110    
} 
 
1991/0423    
Scsi * 
scsicmd(int dev, int cmdbyte, long size) 
1991/0927    
scsicmd(int dev, int cmdbyte, Scsibuf *b, long size) 
1991/0110    
{ 
1991/0423    
	Scsi *cmd = &staticcmd; 
 
	if(size > DATASIZE) 
		panic("scsicmd %d", size); 
1991/0110    
	qlock(cmd); 
	cmd->target = dev>>3; 
	cmd->lun = dev&7; 
1991/0927    
	cmd->target = dev >> 3; 
	cmd->lun = dev & 7; 
1991/0110    
	cmd->cmd.base = cmd->cmdblk; 
	cmd->cmd.ptr = cmd->cmd.base; 
	memset(cmd->cmdblk, 0, sizeof cmd->cmdblk); 
	cmd->cmdblk[0] = cmdbyte; 
1991/0423    
	switch(cmdbyte>>5){ 
1991/0927    
	switch(cmdbyte >> 5){ 
1991/0110    
	case 0: 
		cmd->cmd.lim = &cmd->cmdblk[6]; break; 
1991/0927    
		cmd->cmd.lim = &cmd->cmdblk[6]; 
		break; 
1991/0110    
	case 1: 
		cmd->cmd.lim = &cmd->cmdblk[10]; break; 
1991/0927    
		cmd->cmd.lim = &cmd->cmdblk[10]; 
		break; 
1991/0110    
	default: 
		cmd->cmd.lim = &cmd->cmdblk[12]; break; 
1991/0927    
		cmd->cmd.lim = &cmd->cmdblk[12]; 
		break; 
1991/0110    
	} 
1991/0423    
	switch(cmdbyte){ 
1991/0110    
	case 0x00:	/* test unit ready */ 
1991/0927    
	case ScsiTestunit: 
1991/0110    
		break; 
	case 0x03:	/* read sense data */ 
1991/0927    
	case ScsiExtsens: 
1991/0110    
		cmd->cmdblk[4] = size; 
		break; 
	case 0x25:	/* read capacity */ 
1991/0927    
	case ScsiGetcap: 
1991/0110    
		break; 
	} 
1991/0423    
	cmd->data.base = datablk; 
1991/0927    
	cmd->b = b; 
	cmd->data.base = b->virt; 
1991/0110    
	cmd->data.lim = cmd->data.base + size; 
	cmd->data.ptr = cmd->data.base; 
	cmd->save = cmd->data.base; 
1991/0706/sys/src/9/port/devscsi.c:303,3141991/0927/sys/src/9/port/devscsi.c:359,378
1991/0110    
int 
scsiready(int dev) 
{ 
1991/0423    
	Scsi *cmd = scsicmd(dev, 0x00, 0); 
1991/0927    
	Scsi *cmd; 
1991/0110    
	int status; 
1991/0423    
 
	status = scsiexec(cmd, 0); 
1991/0927    
	cmd = scsicmd(dev, ScsiTestunit, scsibuf(), 0); 
	if(waserror()){ 
		scsifree(cmd->b); 
		qunlock(cmd); 
		nexterror(); 
	} 
	status = scsiexec(cmd, ScsiOut); 
	poperror(); 
	scsifree(cmd->b); 
1991/0423    
	qunlock(cmd); 
1991/0110    
	if ((status&0xff00) != 0x6000) 
1991/0927    
	if((status&0xff00) != 0x6000) 
1991/0110    
		error(Eio); 
	return status&0xff; 
} 
1991/0706/sys/src/9/port/devscsi.c:316,3281991/0927/sys/src/9/port/devscsi.c:380,400
1991/0110    
int 
1991/0423    
scsisense(int dev, void *p) 
1991/0110    
{ 
1991/0423    
	Scsi *cmd = scsicmd(dev, 0x03, 18); 
1991/0927    
	Scsi *cmd; 
1991/0110    
	int status; 
1991/0423    
 
	status = scsiexec(cmd, 1); 
1991/0927    
	cmd = scsicmd(dev, ScsiExtsens, scsibuf(), 18); 
	if(waserror()){ 
		scsifree(cmd->b); 
		qunlock(cmd); 
		nexterror(); 
	} 
	status = scsiexec(cmd, ScsiIn); 
1991/0423    
	memmove(p, cmd->data.base, 18); 
1991/0927    
	poperror(); 
	scsifree(cmd->b); 
1991/0423    
	qunlock(cmd); 
1991/0110    
	if ((status&0xff00) != 0x6000) 
1991/0927    
	if((status&0xff00) != 0x6000) 
1991/0110    
		error(Eio); 
	return status&0xff; 
} 
1991/0706/sys/src/9/port/devscsi.c:330,3461991/0927/sys/src/9/port/devscsi.c:402,514
1991/0110    
int 
1991/0423    
scsicap(int dev, void *p) 
1991/0110    
{ 
1991/0423    
	Scsi *cmd = scsicmd(dev, 0x25, 8); 
1991/0927    
	Scsi *cmd; 
1991/0110    
	int status; 
1991/0423    
 
	status = scsiexec(cmd, 1); 
1991/0927    
	cmd = scsicmd(dev, ScsiGetcap, scsibuf(), 8); 
	if(waserror()){ 
		scsifree(cmd->b); 
		qunlock(cmd); 
		nexterror(); 
	} 
	status = scsiexec(cmd, ScsiIn); 
1991/0423    
	memmove(p, cmd->data.base, 8); 
1991/0927    
	poperror(); 
	scsifree(cmd->b); 
1991/0423    
	qunlock(cmd); 
1991/0110    
	if ((status&0xff00) != 0x6000) 
1991/0927    
	if((status&0xff00) != 0x6000) 
1991/0110    
		error(Eio); 
	return status&0xff; 
} 
 
1991/0927    
int 
scsibread(int dev, Scsibuf *b, long n, long blocksize, long blockno) 
{ 
	Scsi *cmd; 
 
	cmd = scsicmd(dev, ScsiRead, b, n*blocksize); 
	if(waserror()){ 
		qunlock(cmd); 
		nexterror(); 
	} 
	cmd->cmdblk[1] = blockno >> 16; 
	cmd->cmdblk[2] = blockno >> 8; 
	cmd->cmdblk[3] = blockno; 
	cmd->cmdblk[4] = n; 
	scsiexec(cmd, ScsiIn); 
	n = cmd->data.ptr - cmd->data.base; 
	poperror(); 
	qunlock(cmd); 
	return n; 
} 
 
int 
scsibwrite(int dev, Scsibuf *b, long n, long blocksize, long blockno) 
{ 
	Scsi *cmd; 
 
	cmd = scsicmd(dev, ScsiWrite, b, n*blocksize); 
	if(waserror()){ 
		qunlock(cmd); 
		nexterror(); 
	} 
	cmd->cmdblk[1] = blockno >> 16; 
	cmd->cmdblk[2] = blockno >> 8; 
	cmd->cmdblk[3] = blockno; 
	cmd->cmdblk[4] = n; 
	scsiexec(cmd, ScsiOut); 
	n = cmd->data.ptr - cmd->data.base; 
	poperror(); 
	qunlock(cmd); 
	return n; 
} 
 
/* 
 * allocate a scsi buf of any length 
 * must be called at ialloc time and never freed 
 */ 
Scsibuf * 
scsialloc(ulong n) 
{ 
	Scsibuf *b; 
	uchar *x; 
	long m; 
 
	b = ialloc(sizeof *b, 0); 
	b->virt = b->phys = ialloc(n, 0); 
	return b; 
} 
 
/* 
 * get a scsi io buffer of DATASIZE size 
 */ 
Scsibuf * 
scsibuf(void) 
{ 
	Scsibuf *b; 
 
	for(;;) { 
		lock(&scsibufalloc); 
		if(b = scsibufalloc.free) { 
			scsibufalloc.free = b->next; 
			unlock(&scsibufalloc); 
			return b; 
		} 
 
		unlock(&scsibufalloc); 
		resrcwait("no scsi buffers"); 
	} 
} 
 
void 
scsifree(Scsibuf *b) 
{ 
	lock(&scsibufalloc); 
	b->next = scsibufalloc.free; 
	scsibufalloc.free = b; 
	unlock(&scsibufalloc); 
} 
 
1991/0110    
typedef struct Scsictl { 
	uchar	asr; 
	uchar	data; 
1991/0706/sys/src/9/port/devscsi.c:385,3901991/0927/sys/src/9/port/devscsi.c:553,559
1991/0110    
	PE=0x02, DBR=0x01, 
}; 
 
1991/0927    
static int	isscsi; 
1991/0110    
static QLock	scsilock; 
static Rendez	scsirendez; 
static uchar	*datap; 
1991/0706/sys/src/9/port/devscsi.c:394,3991991/0927/sys/src/9/port/devscsi.c:563,599
1991/0110    
nop(void) 
{} 
 
1991/0927    
void 
scsireset(void) 
{ 
	static int alloced = 0; 
	int i; 
 
	addportintr(scsiintr); 
	if(!alloced){ 
		for(i = 0; i < Nbuf; i++) 
			scsifree(scsialloc(DATASIZE)); 
		alloced = 1; 
	} 
} 
 
void 
scsiinit(void) 
{ 
	isscsi = portprobe("scsi", -1, Scsiaddr, -1, 0L); 
	if (isscsi >= 0) { 
		DEV->stat = Scsirst; 
		WAIT; nop(); WAIT; 
		DEV->stat = Inten; 
		while (DEV->stat & (INTRQ|DMA)) 
			nop(); 
		ownid &= 0x0f; /* possibly advanced features */ 
		ownid |= 0x80; /* 16MHz */ 
		PUT(Own_id, ownid); 
		PUT(Cmd, Reset); 
	} 
} 
 
1991/0110    
static int 
scsidone(void *arg) 
{ 
1991/0706/sys/src/9/port/devscsi.c:450,4721991/0927/sys/src/9/port/devscsi.c:650,655
1991/0110    
{ 
	wakeup(&scsirendez); 
	scsibusy = 0; 
} 
                 
void 
scsiinit(void) 
{ 
	isscsi = portprobe("scsi", -1, Scsiaddr, -1, 0L); 
	if (isscsi >= 0) { 
		DEV->stat = Scsirst; 
		WAIT; nop(); WAIT; 
		DEV->stat = Inten; 
		while (DEV->stat & (INTRQ|DMA)) 
			nop(); 
		ownid &= 0x0f; /* possibly advanced features */ 
		ownid |= 0x80; /* 16MHz */ 
		PUT(Own_id, ownid); 
		PUT(Cmd, Reset); 
	} 
} 
 
void 
1991/0927/sys/src/9/port/devscsi.c:67,751991/1112/sys/src/9/port/devscsi.c:67,75 (short | long)
1991/0927    
}; 
 
1991/0110    
static Dirtab scsidir[]={ 
	"cmd",		{Qcmd},		0,	0600, 
	"data",		{Qdata},	0,	0600, 
	"debug",	{Qdebug},	1,	0600, 
1991/1112    
	"cmd",		{Qcmd},		0,	0666, 
	"data",		{Qdata},	0,	0666, 
	"debug",	{Qdebug},	1,	0666, 
1991/0110    
}; 
#define	NSCSI	(sizeof scsidir/sizeof(Dirtab)) 
 
1991/0927/sys/src/9/port/devscsi.c:83,981991/1112/sys/src/9/port/devscsi.c:83,98
1991/0110    
scsigen1(Chan *c, long qid, Dir *dp) 
{ 
	if (qid == CHDIR) 
		devdir(c, (Qid){qid,0}, ".", 0, 0500, dp); 
1991/1112    
		devdir(c, (Qid){qid,0}, ".", 0, eve, 0555, dp); 
1991/0110    
	else if (qid == 1) 
		devdir(c, (Qid){qid,0}, "id", 1, 0600, dp); 
1991/1112    
		devdir(c, (Qid){qid,0}, "id", 1, eve, 0666, dp); 
1991/0110    
	else if (qid&CHDIR) { 
		char name[2]; 
		name[0] = '0'+((qid>>4)&7), name[1] = 0; 
		devdir(c, (Qid){qid,0}, name, 0, 0500, dp); 
1991/1112    
		devdir(c, (Qid){qid,0}, name, 0, eve, 0555, dp); 
1991/0110    
	} else { 
		Dirtab *tab = &scsidir[(qid&7)-1]; 
		devdir(c, (Qid){qid,0}, tab->name, tab->length, tab->perm, dp); 
1991/1112    
		devdir(c, (Qid){qid,0}, tab->name, tab->length, eve, tab->perm, dp); 
1991/0110    
	} 
	return 1; 
} 
1991/1112/sys/src/9/port/devscsi.c:78,831991/1220/sys/src/9/port/devscsi.c:78,84 (short | long)
1991/0110    
 
1991/0927    
int	scsiexec(Scsi*, int); 
int	scsiintr(void); 
1991/1220    
void	scsireset(void); 
1991/0514    
 
1991/0110    
static int 
scsigen1(Chan *c, long qid, Dir *dp) 
1991/1220/sys/src/9/port/devscsi.c:3,91992/0111/sys/src/9/port/devscsi.c:3,9 (short | long)
1991/0110    
#include	"mem.h" 
#include	"dat.h" 
#include	"fns.h" 
#include	"errno.h" 
1992/0111    
#include	"../port/error.h" 
1991/0110    
#include	"devtab.h" 
#include	"io.h" 
 
1992/0111/sys/src/9/port/devscsi.c:1,51992/0321/sys/src/9/port/devscsi.c:1,5 (short | long)
1991/0110    
#include	"u.h" 
#include	"lib.h" 
1992/0321    
#include	"../port/lib.h" 
1991/0110    
#include	"mem.h" 
#include	"dat.h" 
#include	"fns.h" 
1992/0321/sys/src/9/port/devscsi.c:51,611992/0625/sys/src/9/port/devscsi.c:51,56 (short | long)
1991/0927    
	uchar	cmdblk[16]; 
}; 
 
struct{ 
	Lock; 
	Scsibuf	*free; 
}scsibufalloc; 
                 
static Scsi	staticcmd;	/* BUG: should be one per scsi device */ 
 
enum 
1992/0321/sys/src/9/port/devscsi.c:465,4861992/0625/sys/src/9/port/devscsi.c:460,465
1991/0927    
} 
 
/* 
 * allocate a scsi buf of any length 
 * must be called at ialloc time and never freed 
 */ 
Scsibuf * 
scsialloc(ulong n) 
{ 
	Scsibuf *b; 
	uchar *x; 
	long m; 
                 
	b = ialloc(sizeof *b, 0); 
	b->virt = b->phys = ialloc(n, 0); 
	return b; 
} 
                 
/* 
 * get a scsi io buffer of DATASIZE size 
 */ 
Scsibuf * 
1992/0321/sys/src/9/port/devscsi.c:488,5131992/0625/sys/src/9/port/devscsi.c:467,482
1991/0927    
{ 
	Scsibuf *b; 
 
	for(;;) { 
		lock(&scsibufalloc); 
		if(b = scsibufalloc.free) { 
			scsibufalloc.free = b->next; 
			unlock(&scsibufalloc); 
			return b; 
		} 
                 
		unlock(&scsibufalloc); 
		resrcwait("no scsi buffers"); 
	} 
1992/0625    
	b = smalloc(sizeof(Scsibuf)+DATASIZE); 
	b->phys = (void*)(b + 1); 
	b->virt = b->phys; 
	return b; 
1991/0927    
} 
 
void 
scsifree(Scsibuf *b) 
{ 
	lock(&scsibufalloc); 
	b->next = scsibufalloc.free; 
	scsibufalloc.free = b; 
	unlock(&scsibufalloc); 
1992/0625    
	free(b); 
1991/0927    
} 
 
1991/0110    
typedef struct Scsictl { 
1992/0321/sys/src/9/port/devscsi.c:567,5811992/0625/sys/src/9/port/devscsi.c:536,542
1991/0927    
void 
scsireset(void) 
{ 
	static int alloced = 0; 
	int i; 
                 
	addportintr(scsiintr); 
	if(!alloced){ 
		for(i = 0; i < Nbuf; i++) 
			scsifree(scsialloc(DATASIZE)); 
		alloced = 1; 
	} 
} 
 
void 
1992/0625/sys/src/9/port/devscsi.c:96,1011992/0711/sys/src/9/port/devscsi.c:96,102 (short | long)
1991/0110    
static int 
scsigeno(Chan *c, Dirtab *tab, long ntab, long s, Dir *dp) 
{ 
1992/0711    
	USED(tab, ntab, s); 
1991/0110    
	return scsigen1(c, c->qid.path, dp); 
} 
 
1992/0625/sys/src/9/port/devscsi.c:102,1071992/0711/sys/src/9/port/devscsi.c:103,109
1991/0110    
static int 
scsigen(Chan *c, Dirtab *tab, long ntab, long s, Dir *dp) 
{ 
1992/0711    
	USED(tab, ntab); 
1991/0110    
	if (c->qid.path == CHDIR) { 
		if (0<=s && s<=7) 
			return scsigen1(c, CHDIR|0x100|(s<<4), dp); 
1992/0625/sys/src/9/port/devscsi.c:148,1531992/0711/sys/src/9/port/devscsi.c:150,156
1991/0110    
void 
scsicreate(Chan *c, char *name, int omode, ulong perm) 
{ 
1992/0711    
	USED(c, name, omode, perm); 
1991/0110    
	error(Eperm); 
} 
 
1992/0625/sys/src/9/port/devscsi.c:303,3081992/0711/sys/src/9/port/devscsi.c:306,312
1991/0110    
void 
scsiremove(Chan *c) 
{ 
1992/0711    
	USED(c); 
1991/0110    
	error(Eperm); 
} 
 
1992/0625/sys/src/9/port/devscsi.c:309,3141992/0711/sys/src/9/port/devscsi.c:313,319
1991/0110    
void 
scsiwstat(Chan *c, char *dp) 
{ 
1992/0711    
	USED(c, dp); 
1991/0110    
	error(Eperm); 
} 
 
1992/0625/sys/src/9/port/devscsi.c:559,5641992/0711/sys/src/9/port/devscsi.c:564,570
1991/0110    
static int 
scsidone(void *arg) 
{ 
1992/0711    
	USED(arg); 
1991/0110    
	return (scsibusy == 0); 
} 
 
1992/0711/sys/src/9/port/devscsi.c:5,561992/0808/sys/src/9/port/devscsi.c:5,21 (short | long)
Created.
rsc Fri Mar 4 12:44:25 2005
1991/0110    
#include	"fns.h" 
1992/0111    
#include	"../port/error.h" 
1991/0110    
#include	"devtab.h" 
#include	"io.h" 
 
#define	DPRINT	if(debug)kprint 
 
1991/0927    
typedef struct Scsi	Scsi; 
typedef struct Scsidata	Scsidata; 
1992/0808    
#define Nbuf	2 
#define DATASIZE	(32*512) 
1991/0927    
 
#define Nbuf	4 
#define DATASIZE (8*1024) 
enum 
{ 
	ScsiTestunit	= 0x00, 
	ScsiExtsens	= 0x03, 
	ScsiGetcap	= 0x25, 
	ScsiRead	= 0x08, 
	ScsiWrite	= 0x0a, 
1992/0808    
struct{ 
	Lock; 
	Scsibuf	*free; 
}scsibufalloc; 
1991/0927    
 
	/* 
	 * data direction 
	 */ 
	ScsiIn		= 1, 
	ScsiOut		= 0, 
1991/0110    
}; 
                 
1991/0927    
struct Scsidata 
{ 
	uchar	*base; 
	uchar	*lim; 
	uchar	*ptr; 
}; 
                 
struct Scsi 
{ 
	QLock; 
	ulong	pid; 
	ushort	target; 
	ushort	lun; 
	ushort	rflag; 
	ushort	status; 
	Scsidata cmd; 
	Scsidata data; 
	Scsibuf	*b; 
	uchar	*save; 
	uchar	cmdblk[16]; 
}; 
                 
static Scsi	staticcmd;	/* BUG: should be one per scsi device */ 
 
enum 
1992/0711/sys/src/9/port/devscsi.c:68,801992/0808/sys/src/9/port/devscsi.c:33,41
1991/0110    
}; 
#define	NSCSI	(sizeof scsidir/sizeof(Dirtab)) 
 
static int	debugs[8]; 
static int	ownid = 0x08|7; /* enable advanced features */ 
1992/0808    
extern int	scsidebugs[]; 
extern int	scsiownid; 
1991/0110    
 
1991/0927    
int	scsiexec(Scsi*, int); 
int	scsiintr(void); 
1991/1220    
void	scsireset(void); 
1991/0514    
                 
1991/0110    
static int 
scsigen1(Chan *c, long qid, Dir *dp) 
{ 
1992/0711/sys/src/9/port/devscsi.c:117,1221992/0808/sys/src/9/port/devscsi.c:78,101
1991/0110    
	return scsigen1(c, (c->qid.path&~CHDIR)+s+1, dp); 
} 
 
1992/0808    
void 
scsireset(void) 
{ 
	int i; 
 
	for(i = 0; i < Nbuf; i++) 
		scsifree(scsialloc(DATASIZE)); 
	lock(&scsibufalloc); 
	unlock(&scsibufalloc); 
	resetscsi(); 
} 
 
void 
scsiinit(void) 
{ 
	initscsi(); 
} 
 
1991/0110    
Chan * 
scsiattach(char *param) 
{ 
1992/0711/sys/src/9/port/devscsi.c:181,1871992/0808/sys/src/9/port/devscsi.c:160,166
1991/0110    
	if(c->qid.path==1){ 
1991/0411    
		if(offset == 0){ 
1991/0423    
			/*void scsidump(void); scsidump();*/ 
1991/0110    
			*a = ownid; 
1992/0808    
			*a = scsiownid; 
1991/0110    
			n = 1; 
		}else 
			n = 0; 
1992/0711/sys/src/9/port/devscsi.c:230,2361992/0808/sys/src/9/port/devscsi.c:209,215
1991/0110    
	case Qdebug: 
1991/0927    
		if(offset == 0){ 
1991/0110    
			n=1; 
			*a="01"[debugs[(c->qid.path>>4)&7]!=0]; 
1992/0808    
			*a="01"[scsidebugs[(c->qid.path>>4)&7]!=0]; 
1991/0927    
		}else 
1991/0110    
			n = 0; 
		break; 
1992/0711/sys/src/9/port/devscsi.c:248,2541992/0808/sys/src/9/port/devscsi.c:227,233
1991/0110    
	if(c->qid.path==1 && n>0){ 
1991/0411    
		if(offset == 0){ 
1991/0110    
			n = 1; 
			ownid=*a; 
1992/0808    
			scsiownid=*a; 
1991/0423    
			scsireset(); 
1991/0110    
		}else 
			n = 0; 
1992/0711/sys/src/9/port/devscsi.c:292,2981992/0808/sys/src/9/port/devscsi.c:271,277
1991/0110    
		break; 
	case Qdebug: 
1991/0927    
		if(offset == 0){ 
1991/0110    
			debugs[(c->qid.path>>4)&7] = (*a=='1'); 
1992/0808    
			scsidebugs[(c->qid.path>>4)&7] = (*a=='1'); 
1991/0110    
			n = 1; 
1991/0927    
		}else 
1991/0110    
			n = 0; 
1992/0711/sys/src/9/port/devscsi.c:343,3481992/0808/sys/src/9/port/devscsi.c:322,330
1991/0423    
	switch(cmdbyte){ 
1991/0927    
	case ScsiTestunit: 
1991/0110    
		break; 
1992/0808    
	case ScsiModesense: 
		cmd->cmdblk[2] = 1; 
		/* fall through */ 
1991/0927    
	case ScsiExtsens: 
1991/0110    
		cmd->cmdblk[4] = size; 
		break; 
1992/0711/sys/src/9/port/devscsi.c:419,4281992/0808/sys/src/9/port/devscsi.c:401,434
1991/0423    
	qunlock(cmd); 
1991/0927    
	if((status&0xff00) != 0x6000) 
1991/0110    
		error(Eio); 
1992/0808    
	if(status & 0xFF) 
		scsisense(dev, p); 
1991/0110    
	return status&0xff; 
} 
 
1991/0927    
int 
1992/0808    
scsiwp(int dev) 
{ 
	Scsi *cmd; 
	int r, status; 
 
	cmd = scsicmd(dev, ScsiModesense, scsibuf(), 12); 
	if(waserror()){ 
		scsifree(cmd->b); 
		qunlock(cmd); 
		nexterror(); 
	} 
	status = scsiexec(cmd, ScsiIn); 
	r = cmd->data.base[2] & 0x80; 
	poperror(); 
	scsifree(cmd->b); 
	qunlock(cmd); 
	if ((status&0xffff) != 0x6000) 
		error(Eio); 
	return r; 
} 
 
int 
1991/0927    
scsibread(int dev, Scsibuf *b, long n, long blocksize, long blockno) 
{ 
	Scsi *cmd; 
1992/0711/sys/src/9/port/devscsi.c:472,7381992/0808/sys/src/9/port/devscsi.c:478,502
1991/0927    
{ 
	Scsibuf *b; 
 
1992/0625    
	b = smalloc(sizeof(Scsibuf)+DATASIZE); 
	b->phys = (void*)(b + 1); 
	b->virt = b->phys; 
	return b; 
1991/0927    
} 
1992/0808    
	for(;;) { 
		lock(&scsibufalloc); 
		if(b = scsibufalloc.free) { 
			scsibufalloc.free = b->next; 
			unlock(&scsibufalloc); 
			return b; 
		} 
1991/0927    
 
void 
scsifree(Scsibuf *b) 
{ 
1992/0625    
	free(b); 
1991/0927    
} 
                 
1991/0110    
typedef struct Scsictl { 
	uchar	asr; 
	uchar	data; 
	uchar	stat; 
	uchar	dma; 
} Scsictl; 
                 
#define	Scsiaddr	48 
#define	DEV	((Scsictl *)&PORT[Scsiaddr]) 
                 
static long	poot; 
1991/0112    
#define	WAIT	(poot=0, poot==0?0:poot) 
1991/0110    
                 
#define	PUT(a,d)	(DEV->asr=(a), WAIT, DEV->data=(d)) 
#define	GET(a)		(DEV->asr=(a), WAIT, DEV->data) 
                 
enum Int_status { 
	Inten = 0x01, Scsirst = 0x02, 
	INTRQ = 0x01, DMA = 0x02, 
}; 
                 
enum SBIC_regs { 
	Own_id=0x00, Control=0x01, CDB=0x03, Target_LUN=0x0f, 
	Cmd_phase=0x10, Tc_hi=0x12, 
	Dest_id=0x15, Src_id=0x16, SCSI_Status=0x17, 
	Cmd=0x18, Data=0x19, 
}; 
                 
enum Commands { 
	Reset = 0x00, 
	Assert_ATN = 0x02, 
	Negate_ACK = 0x03, 
	Select_with_ATN = 0x06, 
	Select_with_ATN_and_Xfr = 0x08, 
	Select_and_Xfr = 0x09, 
	Transfer_Info = 0x20, 
	SBT = 0x80,		/* modifier for single-byte transfer */ 
}; 
                 
enum Aux_status { 
	INT=0x80, LCI=0x40, BSY=0x20, CIP=0x10, 
	PE=0x02, DBR=0x01, 
}; 
                 
1991/0927    
static int	isscsi; 
1991/0110    
static QLock	scsilock; 
static Rendez	scsirendez; 
static uchar	*datap; 
static long	debug, scsirflag, scsibusy, scsiinservice; 
                 
static void 
nop(void) 
{} 
                 
1991/0927    
void 
scsireset(void) 
{ 
	addportintr(scsiintr); 
} 
                 
void 
scsiinit(void) 
{ 
	isscsi = portprobe("scsi", -1, Scsiaddr, -1, 0L); 
	if (isscsi >= 0) { 
		DEV->stat = Scsirst; 
		WAIT; nop(); WAIT; 
		DEV->stat = Inten; 
		while (DEV->stat & (INTRQ|DMA)) 
			nop(); 
		ownid &= 0x0f; /* possibly advanced features */ 
		ownid |= 0x80; /* 16MHz */ 
		PUT(Own_id, ownid); 
		PUT(Cmd, Reset); 
1992/0808    
		unlock(&scsibufalloc); 
		resrcwait("no scsi buffers"); 
1991/0927    
	} 
1992/0808    
	return 0;		/* not reached */ 
1991/0927    
} 
 
1991/0110    
static int 
scsidone(void *arg) 
{ 
1992/0711    
	USED(arg); 
1991/0110    
	return (scsibusy == 0); 
} 
                 
int 
scsiexec(Scsi *p, int rflag) 
{ 
	long n; 
	debug = debugs[p->target&7]; 
	DPRINT("scsi %d.%d ", p->target, p->lun); 
	qlock(&scsilock); 
	if(waserror()){ 
		qunlock(&scsilock); 
		nexterror(); 
	} 
	scsirflag = rflag; 
1991/0423    
	p->rflag = rflag; 
1991/0110    
	datap = p->data.base; 
	if ((ownid & 0x08) && rflag) 
		PUT(Dest_id, 0x40|p->target); 
	else 
		PUT(Dest_id, p->target); 
	PUT(Target_LUN, p->lun); 
	n = p->data.lim - p->data.base; 
	PUT(Tc_hi, n>>16); 
	DEV->data = n>>8; 
	DEV->data = n; 
	if (ownid & 0x08) { 
		n = p->cmd.lim - p->cmd.ptr; 
		DPRINT("len=%d ", n); 
		PUT(Own_id, n); 
	} 
	PUT(CDB, *(p->cmd.ptr)++); 
	while (p->cmd.ptr < p->cmd.lim) 
		DEV->data = *(p->cmd.ptr)++; 
	scsibusy = 1; 
	PUT(Cmd, Select_and_Xfr); 
	DPRINT("S<"); 
	sleep(&scsirendez, scsidone, 0); 
	DPRINT(">"); 
	p->data.ptr = datap; 
	p->status = GET(Target_LUN); 
	p->status |= DEV->data<<8; 
	poperror(); 
	qunlock(&scsilock); 
	debug = 0; 
	return p->status; 
} 
                 
void 
scsirun(void) 
1992/0808    
scsifree(Scsibuf *b) 
1991/0110    
{ 
	wakeup(&scsirendez); 
	scsibusy = 0; 
} 
                 
void 
scsireset0(void) 
{ 
	PUT(Control, 0x29);	/* burst DMA, halt on parity error */ 
	PUT(Control+1, 0xff);	/* timeout */ 
	PUT(Src_id, 0x80);	/* enable reselection */ 
	scsirun(); 
	/*qunlock(&scsilock);*/ 
} 
                 
int 
scsiintr(void) 
{ 
	int status, s; 
	if (isscsi < 0 || scsiinservice 
		|| !((status = DEV->stat) & (DMA|INTRQ))) 
			return 0; 
	DEV->stat = 0; 
	scsiinservice = 1; 
	s = spl1(); 
	DPRINT("i%x ", status); 
	do { 
		if (status & DMA) 
			scsidmaintr(); 
		if (status & INTRQ) 
			scsictrlintr(); 
	} while ((status = DEV->stat) & (DMA|INTRQ)); 
	splx(s); 
	scsiinservice = 0; 
	DEV->stat = Inten; 
	return 1; 
} 
                 
void 
scsidmaintr(void) 
{ 
1991/0112    
		uchar *p = 0; 
1991/0110    
/* 
 *	if (scsirflag) { 
 *		unsigned char *p; 
 *		DPRINT("R", p=datap); 
 *		do 
 *			*datap++ = DEV->dma; 
 *		while (DEV->stat & DMA); 
 *		DPRINT("%d ", datap-p); 
 *	} else { 
 *		unsigned char *p; 
 *		DPRINT("W", p=datap); 
 *		do 
 *			DEV->dma = *datap++; 
 *		while (DEV->stat & DMA); 
 *		DPRINT("%d ", datap-p); 
 *	} 
 */ 
	if (scsirflag) { 
		DPRINT("R", p=datap); 
		datap = scsirecv(datap); 
		DPRINT("%d ", datap-p); 
	} else { 
		DPRINT("X", p=datap); 
		datap = scsixmit(datap); 
		DPRINT("%d ", datap-p); 
	} 
} 
                 
void 
scsictrlintr(void) 
{ 
	int status; 
	status = GET(SCSI_Status); 
	DPRINT("I%2.2x ", status); 
	switch(status){ 
	case 0x00:			/* reset by command or power-up */ 
	case 0x01:			/* reset by command or power-up */ 
		scsireset0(); 
		break; 
	case 0x21:			/* Save Data Pointers message received */ 
		break; 
	case 0x16:			/* select-and-transfer completed */ 
	case 0x42:			/* timeout during select */ 
		scsirun(); 
		break; 
	case 0x4b:			/* unexpected status phase */ 
		PUT(Tc_hi, 0); 
		DEV->data = 0; 
		DEV->data = 0; 
		PUT(Cmd_phase, 0x46); 
		PUT(Cmd, Select_and_Xfr); 
		break; 
	default: 
		kprint("scsintr 0x%ux\n", status); 
		DEV->asr = Target_LUN; 
		kprint("lun/status 0x%ux\n", DEV->data); 
		kprint("phase 0x%ux\n", DEV->data); 
		switch (status&0xf0) { 
		case 0x00: 
		case 0x10: 
		case 0x20: 
		case 0x40: 
		case 0x80: 
			if (status & 0x08) { 
				kprint("count 0x%ux", GET(Tc_hi)); 
				kprint(" 0x%ux", DEV->data); 
				kprint(" 0x%ux\n", DEV->data); 
			} 
			scsirun(); 
			break; 
		default: 
			panic("scsi status 0x%2.2ux", status); 
		} 
1991/0706    
		kprint("resetting..."); 
		PUT(Own_id, ownid); 
		PUT(Cmd, Reset); 
		break; 
1991/0110    
	} 
1992/0808    
	lock(&scsibufalloc); 
	b->next = scsibufalloc.free; 
	scsibufalloc.free = b; 
	unlock(&scsibufalloc); 
1991/0110    
} 
1992/0808/sys/src/9/port/devscsi.c:326,3311992/0825/sys/src/9/port/devscsi.c:326,332 (short | long)
1992/0808    
		cmd->cmdblk[2] = 1; 
		/* fall through */ 
1991/0927    
	case ScsiExtsens: 
1992/0825    
	case ScsiInquiry: 
1991/0110    
		cmd->cmdblk[4] = size; 
		break; 
1991/0927    
	case ScsiGetcap: 
1992/0808/sys/src/9/port/devscsi.c:407,4121992/0825/sys/src/9/port/devscsi.c:408,437
1991/0110    
} 
 
1991/0927    
int 
1992/0825    
scsiinquiry(int dev, void *p, int size) 
{ 
	Scsi *cmd; 
	int status; 
 
	cmd = scsicmd(dev, ScsiInquiry, scsibuf(), size); 
	if(waserror()){ 
		scsifree(cmd->b); 
		qunlock(cmd); 
		nexterror(); 
	} 
	status = scsiexec(cmd, ScsiIn); 
	memmove(p, cmd->data.base, size); 
	poperror(); 
	scsifree(cmd->b); 
	qunlock(cmd); 
	if((status&0xff00) != 0x6000) 
		error(Eio); 
	if(status & 0xFF) 
		scsisense(dev, p); 
	return status&0xff; 
} 
 
int 
1992/0808    
scsiwp(int dev) 
{ 
	Scsi *cmd; 
1992/0808/sys/src/9/port/devscsi.c:426,4311992/0825/sys/src/9/port/devscsi.c:451,479
1992/0808    
	if ((status&0xffff) != 0x6000) 
		error(Eio); 
	return r; 
1992/0825    
} 
 
int 
scsimodesense(int dev, int page, void *p, int size) 
{ 
	Scsi *cmd; 
	int status; 
 
	cmd = scsicmd(dev, ScsiModesense, scsibuf(), size); 
	cmd->cmdblk[2] = page; 
	if(waserror()){ 
		scsifree(cmd->b); 
		qunlock(cmd); 
		nexterror(); 
	} 
	status = scsiexec(cmd, ScsiIn); 
	memmove(p, cmd->data.base, size); 
	poperror(); 
	scsifree(cmd->b); 
	qunlock(cmd); 
	if ((status&0xffff) != 0x6000) 
		error(Eio); 
	return status&0xff; 
1992/0808    
} 
 
int 
1992/0825/sys/src/9/port/devscsi.c:10,151992/0829/sys/src/9/port/devscsi.c:10,17 (short | long)
1991/0110    
 
1992/0808    
#define Nbuf	2 
#define DATASIZE	(32*512) 
1992/0829    
#undef DATASIZE 
#define	DATASIZE	(64*1024) 
1991/0927    
 
1992/0808    
struct{ 
	Lock; 
1992/0829/sys/src/9/port/devscsi.c:530,5431992/0921/sys/src/9/port/devscsi.c:530,543 (short | long)
1991/0927    
 
1992/0808    
	for(;;) { 
		lock(&scsibufalloc); 
		if(b = scsibufalloc.free) { 
1992/0921    
		b = scsibufalloc.free; 
		if(b != 0) { 
1992/0808    
			scsibufalloc.free = b->next; 
			unlock(&scsibufalloc); 
			return b; 
		} 
1991/0927    
                 
1992/0808    
		unlock(&scsibufalloc); 
		resrcwait("no scsi buffers"); 
1992/0921    
		resrcwait(0); 
1991/0927    
	} 
1992/0808    
	return 0;		/* not reached */ 
1991/0927    
} 
1992/0921/sys/src/9/port/devscsi.c:324,3291992/1009/sys/src/9/port/devscsi.c:324,332 (short | long)
1991/0423    
	switch(cmdbyte){ 
1991/0927    
	case ScsiTestunit: 
1991/0110    
		break; 
1992/1009    
	case ScsiStartunit: 
		cmd->cmdblk[4] = 1; 
		break; 
1992/0808    
	case ScsiModesense: 
		cmd->cmdblk[2] = 1; 
		/* fall through */ 
1992/0921/sys/src/9/port/devscsi.c:349,3541992/1009/sys/src/9/port/devscsi.c:352,378
1991/0110    
	int status; 
1991/0423    
 
1991/0927    
	cmd = scsicmd(dev, ScsiTestunit, scsibuf(), 0); 
1992/1009    
	if(waserror()){ 
		scsifree(cmd->b); 
		qunlock(cmd); 
		nexterror(); 
	} 
	status = scsiexec(cmd, ScsiOut); 
	poperror(); 
	scsifree(cmd->b); 
	qunlock(cmd); 
	if((status&0xff00) != 0x6000) 
		error(Eio); 
	return status&0xff; 
} 
 
int 
scsistartstop(int dev, int cmdbyte) 
{ 
	Scsi *cmd; 
	int status; 
 
	cmd = scsicmd(dev, cmdbyte, scsibuf(), 0); 
1991/0927    
	if(waserror()){ 
		scsifree(cmd->b); 
		qunlock(cmd); 
1992/1009/sys/src/9/port/devscsi.c:8,221992/1029/sys/src/9/port/devscsi.c:8,17 (short | long)
1991/0110    
 
#define	DPRINT	if(debug)kprint 
 
1992/0808    
#define Nbuf	2 
#define DATASIZE	(32*512) 
1992/0829    
#undef DATASIZE 
#define	DATASIZE	(64*1024) 
1991/0927    
 
1992/0808    
struct{ 
	Lock; 
	Scsibuf	*free; 
}scsibufalloc; 
1991/0927    
 
static Scsi	staticcmd;	/* BUG: should be one per scsi device */ 
 
1992/1009/sys/src/9/port/devscsi.c:83,941992/1029/sys/src/9/port/devscsi.c:78,84
1992/0808    
void 
scsireset(void) 
{ 
	int i; 
                 
	for(i = 0; i < Nbuf; i++) 
		scsifree(scsialloc(DATASIZE)); 
	lock(&scsibufalloc); 
	unlock(&scsibufalloc); 
1992/1029    
	scsibufreset(DATASIZE); 
1992/0808    
	resetscsi(); 
} 
 
1992/1009/sys/src/9/port/devscsi.c:542,5761992/1029/sys/src/9/port/devscsi.c:532,535
1991/0927    
	poperror(); 
	qunlock(cmd); 
	return n; 
} 
                 
/* 
 * get a scsi io buffer of DATASIZE size 
 */ 
Scsibuf * 
scsibuf(void) 
{ 
	Scsibuf *b; 
                 
1992/0808    
	for(;;) { 
		lock(&scsibufalloc); 
1992/0921    
		b = scsibufalloc.free; 
		if(b != 0) { 
1992/0808    
			scsibufalloc.free = b->next; 
			unlock(&scsibufalloc); 
			return b; 
		} 
		unlock(&scsibufalloc); 
1992/0921    
		resrcwait(0); 
1991/0927    
	} 
1992/0808    
	return 0;		/* not reached */ 
1991/0927    
} 
                 
1991/0110    
void 
1992/0808    
scsifree(Scsibuf *b) 
1991/0110    
{ 
1992/0808    
	lock(&scsibufalloc); 
	b->next = scsibufalloc.free; 
	scsibufalloc.free = b; 
	unlock(&scsibufalloc); 
1991/0110    
} 
1992/1029/sys/src/9/port/devscsi.c:9,181992/1209/sys/src/9/port/devscsi.c:9,15 (short | long)
1991/0110    
#define	DPRINT	if(debug)kprint 
 
1992/0808    
#define DATASIZE	(32*512) 
1992/0829    
#undef DATASIZE 
#define	DATASIZE	(64*1024) 
1991/0927    
 
                 
static Scsi	staticcmd;	/* BUG: should be one per scsi device */ 
 
enum 
1992/1029/sys/src/9/port/devscsi.c:450,4551992/1209/sys/src/9/port/devscsi.c:447,453
1992/0825    
int 
1992/0808    
scsiwp(int dev) 
{ 
1992/1209    
/* Device specific 
1992/0808    
	Scsi *cmd; 
	int r, status; 
 
1992/1029/sys/src/9/port/devscsi.c:467,4721992/1209/sys/src/9/port/devscsi.c:465,473
1992/0808    
	if ((status&0xffff) != 0x6000) 
		error(Eio); 
	return r; 
1992/1209    
*/ 
	USED(dev); 
	return 0; 
1992/0825    
} 
 
int 
Too many diffs (26 > 25). Stopping.


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)