void insw()

in lib/io.c [167:229]


void insw (unsigned long port, void *dst, unsigned long count)
{
	unsigned int l = 0, l2;
	unsigned char *p;

	p = (unsigned char *)dst;
	
	if (!count)
		return;
	
	switch (((unsigned long)p) & 0x3)
	{
	 case 0x00:			/* Buffer 32-bit aligned */
		while (count>=2) {
			
			count -= 2;
			l = cpu_to_le16(inw(port)) << 16;
			l |= cpu_to_le16(inw(port));
			*(unsigned int *)p = l;
			p += 4;
		}
		if (count) {
			*(unsigned short *)p = cpu_to_le16(inw(port));
		}
		break;
	
	 case 0x02:			/* Buffer 16-bit aligned */
		*(unsigned short *)p = cpu_to_le16(inw(port));
		p += 2;
		count--;
		while (count>=2) {
			
			count -= 2;
			l = cpu_to_le16(inw(port)) << 16;
			l |= cpu_to_le16(inw(port));
			*(unsigned int *)p = l;
			p += 4;
		}
		if (count) {
			*(unsigned short *)p = cpu_to_le16(inw(port));
		}
		break;
		
	 case 0x01:			/* Buffer 8-bit aligned */
	 case 0x03:
		/* I don't bother with 32bit transfers
		 * in this case, 16bit will have to do -- DE */
		--count;
		
		l = cpu_to_le16(inw(port));
		*p = l >> 8;
		p++;
		while (count--)
		{
			l2 = cpu_to_le16(inw(port));
			*(unsigned short *)p = (l & 0xff) << 8 | (l2 >> 8);
			p += 2;
			l = l2;
		}
		*p = l & 0xff;
		break;
	}
}