| 
					
				 | 
			
			
				@@ -0,0 +1,536 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+diff -uprN vblade-15/aoe.c vblade-15-aio/aoe.c 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+--- vblade-15/aoe.c	2008-03-07 20:22:16.000000000 +0000 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++++ vblade-15-aio/aoe.c	2008-04-19 22:31:21.000000000 +0100 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -8,6 +8,9 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ #include <sys/stat.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ #include <fcntl.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ #include <netinet/in.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <errno.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <aio.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <poll.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ #include "dat.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ #include "fns.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -22,6 +25,11 @@ char config[Nconfig]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ int nconfig = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ int maxscnt = 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ char *ifname; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int queuepipe[2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int pktlen[Nplaces], pending[Nplaces]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++Ata *pkt[Nplaces]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++Ataregs regs[Nplaces]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++struct aiocb aiocb[Nplaces]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ void 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ aoead(int fd)			// advertise the virtual blade 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -78,32 +86,52 @@ getlba(uchar *p) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ int 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-aoeata(Ata *p, int pktlen)	// do ATA reqeust 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++aoeata(int place)	// do ATA reqeust 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	Ataregs r; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	int len = 60; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	int n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int len = 60; // minimum ethernet packet size 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	r.lba = getlba(p->lba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	r.sectors = p->sectors; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	r.feature = p->err; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	r.cmd = p->cmd; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	if (atacmd(&r, (uchar *)(p+1), maxscnt*512, pktlen - sizeof(*p)) < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-		p->h.flags |= Error; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-		p->h.error = BadArg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	regs[place].lba = getlba(pkt[place]->lba); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	regs[place].sectors = pkt[place]->sectors; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	regs[place].feature = pkt[place]->err; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	regs[place].cmd = pkt[place]->cmd; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	n = atacmd(regs + place, (uchar *)(pkt[place] + 1), maxscnt*512, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				pktlen[place] - sizeof(Ata), aiocb + place); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (n < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pkt[place]->h.flags |= Error; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pkt[place]->h.error = BadArg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		return len; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} else if (n > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pending[place] = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (!(pkt[place]->aflag & Write) && (n = pkt[place]->sectors)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		n -= regs[place].sectors; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		len = sizeof (Ata) + (n*512); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	if (!(p->aflag & Write)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	if ((n = p->sectors)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-		n -= r.sectors; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pkt[place]->sectors = regs[place].sectors; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pkt[place]->err = regs[place].err; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pkt[place]->cmd = regs[place].status; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return len; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int aoeatacomplete(int place, int pktlen) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int len = 60; // minimum ethernet packet size 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	atacmdcomplete(regs + place, aiocb + place); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (!(pkt[place]->aflag & Write) && (n = pkt[place]->sectors)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		n -= regs[place].sectors; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		len = sizeof (Ata) + (n*512); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	p->sectors = r.sectors; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	p->err = r.err; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	p->cmd = r.status; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pkt[place]->sectors = regs[place].sectors; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pkt[place]->err = regs[place].err; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pkt[place]->cmd = regs[place].status; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pending[place] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	return len; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ #define QCMD(x) ((x)->vercmd & 0xf) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ // yes, this makes unnecessary copies. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -156,8 +184,9 @@ confcmd(Conf *p, int payload)	// process 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ void 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-doaoe(Aoehdr *p, int n) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++doaoe(int place) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	Aoehdr *p = (Aoehdr *) pkt[place]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	int len; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	enum {	// config query header size 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		CHDR_SIZ = sizeof(Conf) - sizeof(((Conf *)0)->data), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -165,14 +194,16 @@ doaoe(Aoehdr *p, int n) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	switch (p->cmd) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	case ATAcmd: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-		if (n < sizeof(Ata)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if (pktlen[place] < sizeof(Ata)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		len = aoeata(place); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if (len == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 			return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-		len = aoeata((Ata*)p, n); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	case Config: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-		if (n < CHDR_SIZ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if (pktlen[place] < CHDR_SIZ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 			return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-		len = confcmd((Conf *)p, n - CHDR_SIZ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		len = confcmd((Conf *)p, pktlen[place] - CHDR_SIZ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		if (len == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 			return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -193,25 +224,129 @@ doaoe(Aoehdr *p, int n) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ void 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++doaoecomplete(int place) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	Aoehdr *p = (Aoehdr *) pkt[place]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int len = aoeatacomplete(place, pktlen[place]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	memmove(p->dst, p->src, 6); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	memmove(p->src, mac, 6); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	p->maj = htons(shelf); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	p->min = slot; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	p->flags |= Resp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (putpkt(sfd, (uchar *) p, len) == -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		perror("write to network"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		exit(1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++// allocate the buffer so that the ata data area 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++// is page aligned for o_direct on linux 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++bufalloc(void **buf, long len) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	long psize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	psize = sysconf(_SC_PAGESIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (psize == -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		perror("sysconf"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		exit(EXIT_FAILURE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	n = len/psize + 3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	*buf = malloc(psize * n); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (!*buf) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		perror("malloc"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		exit(EXIT_FAILURE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	n = (unsigned long) *buf; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	n += psize * 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	n &= ~(psize - 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return (void *) (n - sizeof (Ata)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++sigio(int signo)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	const char dummy = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	write(queuepipe[1], &dummy, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ aoe(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	Aoehdr *p; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	uchar *buf; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	int n, sh; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	char dummy; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int n, place, sh; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	enum { bufsz = 1<<16, }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	buf = malloc(bufsz); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	sigset_t mask, oldmask; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	struct sigaction sigact; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	struct pollfd pollfds[2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	void *freeme[Nplaces]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	for (n = 0; n < Nplaces; n++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pkt[n] = bufalloc(freeme + n, bufsz); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pending[n] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	aoead(sfd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pipe(queuepipe); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	fcntl(queuepipe[0], F_SETFL, O_NONBLOCK); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	fcntl(queuepipe[1], F_SETFL, O_NONBLOCK); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	sigemptyset(&sigact.sa_mask); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	sigact.sa_flags = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	sigact.sa_sigaction = (void *) sigio; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	sigaction(SIGIO, &sigact, NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	sigemptyset(&mask); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	sigaddset(&mask, SIGIO); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	sigprocmask(SIG_BLOCK, &mask, &oldmask); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pollfds[0].fd = queuepipe[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pollfds[1].fd = sfd; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pollfds[0].events = pollfds[1].events = POLLIN; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	for (;;) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-		n = getpkt(sfd, buf, bufsz); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-		if (n < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		sigprocmask(SIG_SETMASK, &oldmask, NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		n = poll(pollfds, 2, 1000); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		sigprocmask(SIG_BLOCK, &mask, NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if (n < 0 && errno != EINTR) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			perror("poll"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} else if (n == 0 || pollfds[0].revents & POLLIN) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			while(read(queuepipe[0], &dummy, 1) > 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			for (place = 0; place < Nplaces; place++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				if (!pending[place]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				if (aio_error(aiocb + place) == EINPROGRESS) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				doaoecomplete(place); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				pollfds[1].events = POLLIN; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if ((pollfds[1].revents & POLLIN) == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		for (place = 0; pending[place] && place < Nplaces; place++); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if (place >= Nplaces) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			pollfds[1].events = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pktlen[place] = getpkt(sfd, (uchar *) pkt[place], bufsz); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if (pktlen[place] < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			if (errno == EINTR) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 			perror("read network"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 			exit(1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-		if (n < sizeof(Aoehdr)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if (pktlen[place] < sizeof(Aoehdr)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 			continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-		p = (Aoehdr *) buf; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		p = (Aoehdr *) pkt[place]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		if (ntohs(p->type) != 0x88a2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 			continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		if (p->flags & Resp) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -223,9 +358,10 @@ aoe(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 			continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		if (nmasks && !maskok(p->src)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 			continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-		doaoe(p, n); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		doaoe(place); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	free(buf); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	for (place = 0; place < Nplaces; place++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		free(freeme[place]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ void 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -317,7 +453,7 @@ main(int argc, char **argv) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	if (s.st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		omode = O_RDWR; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	bfd = open(argv[3], omode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	bfd = opendisk(argv[3], omode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	if (bfd == -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		perror("open"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		exit(1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+diff -uprN vblade-15/ata.c vblade-15-aio/ata.c 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+--- vblade-15/ata.c	2008-03-07 20:22:16.000000000 +0000 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++++ vblade-15-aio/ata.c	2008-04-19 22:12:32.000000000 +0100 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -3,6 +3,8 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ #include <string.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ #include <stdio.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ #include <sys/types.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <errno.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <aio.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ #include "dat.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ #include "fns.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -98,7 +100,7 @@ atainit(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  * check for that. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ int 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-atacmd(Ataregs *p, uchar *dp, int ndp, int payload) // do the ata cmd 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++atacmd(Ataregs *p, uchar *dp, int ndp, int payload, struct aiocb *aiocb) // do the ata cmd 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	vlong lba; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	ushort *ip; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -155,14 +157,29 @@ atacmd(Ataregs *p, uchar *dp, int ndp, i 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	if (p->cmd == 0x20 || p->cmd == 0x24) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-		n = getsec(bfd, dp, lba, p->sectors); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		n = getsec(bfd, dp, lba, p->sectors, aiocb); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		// packet should be big enough to contain the data 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		if (payload < 512 * p->sectors) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 			return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-		n = putsec(bfd, dp, lba, p->sectors); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		n = putsec(bfd, dp, lba, p->sectors, aiocb); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	n /= 512; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (n < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		p->err = ABRT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		p->status = ERR|DRDY; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		p->lba += n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		p->sectors -= n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 1; // callback expected 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++atacmdcomplete(Ataregs *p, struct aiocb *aiocb) // complete the ata cmd 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	n = aio_return(aiocb) / 512; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	if (n != p->sectors) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		p->err = ABRT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		p->status = ERR; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -173,4 +190,3 @@ atacmd(Ataregs *p, uchar *dp, int ndp, i 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	p->sectors -= n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+diff -uprN vblade-15/dat.h vblade-15-aio/dat.h 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+--- vblade-15/dat.h	2008-03-07 20:22:16.000000000 +0000 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++++ vblade-15-aio/dat.h	2008-04-19 16:34:35.000000000 +0100 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -111,6 +111,8 @@ enum { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	Nconfig = 1024, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	Bufcount = 16, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	Nplaces = 32, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ int	shelf, slot; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+diff -uprN vblade-15/fns.h vblade-15-aio/fns.h 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+--- vblade-15/fns.h	2008-03-07 20:22:16.000000000 +0000 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++++ vblade-15-aio/fns.h	2008-04-17 00:11:36.000000000 +0100 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -15,14 +15,16 @@ int	maskok(uchar *); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ // ata.c 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ void	atainit(void); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-int	atacmd(Ataregs *, uchar *, int, int); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int	atacmd(Ataregs *, uchar *, int, int, struct aiocb *); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int	atacmdcomplete(Ataregs *, struct aiocb *); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ // os specific 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ int	dial(char *); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ int	getea(int, char *, uchar *); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-int	putsec(int, uchar *, vlong, int); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-int	getsec(int, uchar *, vlong, int); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int	opendisk(const char *, int); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int	putsec(int, uchar *, vlong, int, struct aiocb *); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int	getsec(int, uchar *, vlong, int, struct aiocb *); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ int	putpkt(int, uchar *, int); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ int	getpkt(int, uchar *, int); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ vlong	getsize(int); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+diff -uprN vblade-15/freebsd.c vblade-15-aio/freebsd.c 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+--- vblade-15/freebsd.c	2008-03-07 20:22:16.000000000 +0000 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++++ vblade-15-aio/freebsd.c	2008-04-19 22:24:57.000000000 +0100 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -241,19 +241,40 @@ getea(int s, char *eth, uchar *ea) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	return(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ int 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-getsec(int fd, uchar *place, vlong lba, int nsec) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++opendisk(const char *disk, int omode) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	return pread(fd, place, nsec * 512, lba * 512); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return open(disk, omode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ int 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-putsec(int fd, uchar *place, vlong lba, int nsec) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	return pwrite(fd, place, nsec * 512, lba * 512); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++getsec(int fd, uchar *place, vlong lba, int nsec, struct aiocb *aiocb) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{        
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        bzero((char *) aiocb, sizeof(struct aiocb)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        aiocb->aio_fildes = fd; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        aiocb->aio_buf = place; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        aiocb->aio_nbytes = nsec * 512; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        aiocb->aio_offset = lba * 512; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        aiocb->aio_sigevent.sigev_notify = SIGEV_SIGNAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        aiocb->aio_sigevent.sigev_signo = SIGIO; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        aiocb->aio_sigevent.sigev_value.sival_ptr = aiocb; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        return aio_read(aiocb); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++putsec(int fd, uchar *place, vlong lba, int nsec, struct aiocb *aiocb) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{        
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        bzero((char *) aiocb, sizeof(struct aiocb)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        aiocb->aio_fildes = fd; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        aiocb->aio_buf = place; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        aiocb->aio_nbytes = nsec * 512; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        aiocb->aio_offset = lba * 512; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        aiocb->aio_sigevent.sigev_notify = SIGEV_SIGNAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        aiocb->aio_sigevent.sigev_signo = SIGIO; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        aiocb->aio_sigevent.sigev_value.sival_ptr = aiocb; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        return aio_write(aiocb); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++}        
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ static int pktn = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ static uchar *pktbp = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+diff -uprN vblade-15/linux.c vblade-15-aio/linux.c 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+--- vblade-15/linux.c	2008-03-07 20:22:16.000000000 +0000 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++++ vblade-15-aio/linux.c	2008-04-19 22:23:51.000000000 +0100 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -1,5 +1,6 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ // linux.c: low level access routines for Linux 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ #include "config.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define _GNU_SOURCE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ #include <sys/socket.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ #include <stdio.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ #include <string.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -22,6 +23,9 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ #include <netinet/in.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ #include <linux/fs.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ #include <sys/stat.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <fcntl.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <errno.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <aio.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ #include "dat.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ #include "fns.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -29,8 +33,6 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ int	getindx(int, char *); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ int	getea(int, char *, uchar *); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ int 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ dial(char *eth)		// get us a raw connection to an interface 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -76,7 +78,7 @@ getea(int s, char *name, uchar *ea) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	struct ifreq xx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	int n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-        strcpy(xx.ifr_name, name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	strcpy(xx.ifr_name, name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	n = ioctl(s, SIOCGIFHWADDR, &xx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	if (n == -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		perror("Can't get hw addr"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -102,17 +104,37 @@ getmtu(int s, char *name) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ int 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-getsec(int fd, uchar *place, vlong lba, int nsec) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++opendisk(const char *disk, int omode) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return open(disk, omode|O_DIRECT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++getsec(int fd, uchar *place, vlong lba, int nsec, struct aiocb *aiocb) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	lseek(fd, lba * 512, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	return read(fd, place, nsec * 512); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	bzero((char *) aiocb, sizeof(struct aiocb)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	aiocb->aio_fildes = fd; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	aiocb->aio_buf = place; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	aiocb->aio_nbytes = nsec * 512; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	aiocb->aio_offset = lba * 512; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	aiocb->aio_sigevent.sigev_notify = SIGEV_SIGNAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	aiocb->aio_sigevent.sigev_signo = SIGIO; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	aiocb->aio_sigevent.sigev_value.sival_ptr = aiocb; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return aio_read(aiocb); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ int 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-putsec(int fd, uchar *place, vlong lba, int nsec) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++putsec(int fd, uchar *place, vlong lba, int nsec, struct aiocb *aiocb) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	lseek(fd, lba * 512, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	return write(fd, place, nsec * 512); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	bzero((char *) aiocb, sizeof(struct aiocb)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	aiocb->aio_fildes = fd; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	aiocb->aio_buf = place; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	aiocb->aio_nbytes = nsec * 512; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	aiocb->aio_offset = lba * 512; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	aiocb->aio_sigevent.sigev_notify = SIGEV_SIGNAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	aiocb->aio_sigevent.sigev_signo = SIGIO; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	aiocb->aio_sigevent.sigev_value.sival_ptr = aiocb; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return aio_write(aiocb); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ int 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+diff -uprN vblade-15/linux.h vblade-15-aio/linux.h 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+--- vblade-15/linux.h	2008-03-07 20:22:16.000000000 +0000 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++++ vblade-15-aio/linux.h	2008-04-16 23:03:07.000000000 +0100 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -6,6 +6,6 @@ typedef long long vlong; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ int	dial(char *); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ int	getindx(int, char *); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ int	getea(int, char *, uchar *); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-int	getsec(int, uchar *, vlong, int); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-int	putsec(int, uchar *, vlong, int); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int	getsec(int, uchar *, vlong, int, struct aiocb *); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int	putsec(int, uchar *, vlong, int, struct aiocb *); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ vlong	getsize(int); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+diff -uprN vblade-15/makefile vblade-15-aio/makefile 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+--- vblade-15/makefile	2008-03-07 20:22:16.000000000 +0000 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++++ vblade-15-aio/makefile	2008-04-16 19:09:46.000000000 +0100 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -13,7 +13,7 @@ CFLAGS += -Wall -g -O2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ CC = gcc 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ vblade: $O 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	${CC} -o vblade $O 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	${CC} -lrt -o vblade $O 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ aoe.o : aoe.c config.h dat.h fns.h makefile 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	${CC} ${CFLAGS} -c $< 
			 |