patch-1.3.5 linux/arch/alpha/lib/io.c
Next file: linux/arch/i386/Makefile
Previous file: linux/arch/alpha/kernel/head.S
Back to the patch index
Back to the overall index
- Lines: 215
- Date:
Wed Jun 28 14:02:43 1995
- Orig file:
v1.3.4/linux/arch/alpha/lib/io.c
- Orig date:
Fri Jun 16 22:02:54 1995
diff -u --recursive --new-file v1.3.4/linux/arch/alpha/lib/io.c linux/arch/alpha/lib/io.c
@@ -100,6 +100,40 @@
}
/*
+ * Read COUNT 8-bit bytes from port PORT into memory starting at
+ * SRC.
+ */
+#undef insb
+void insb (unsigned long port, void *dst, unsigned long count)
+{
+ while (((unsigned long)dst) & 0x3) {
+ if (!count)
+ return;
+ count--;
+ *(unsigned char *) dst = inb(port);
+ ((unsigned char *) dst)++;
+ }
+
+ while (count >= 4) {
+ unsigned int w;
+ count -= 4;
+ w = inb(port);
+ w |= inb(port) << 8;
+ w |= inb(port) << 16;
+ w |= inb(port) << 24;
+ *(unsigned int *) dst = w;
+ ((unsigned int *) dst)++;
+ }
+
+ while (count) {
+ --count;
+ *(unsigned char *) dst = inb(port);
+ ((unsigned char *) dst)++;
+ }
+}
+
+
+/*
* Read COUNT 16-bit words from port PORT into memory starting at
* SRC. SRC must be at least short aligned. This is used by the
* IDE driver to read disk sectors. Performance is important, but
@@ -109,28 +143,28 @@
#undef insw
void insw (unsigned long port, void *dst, unsigned long count)
{
- unsigned int *ip, w;
-
if (((unsigned long)dst) & 0x3) {
if (((unsigned long)dst) & 0x1) {
panic("insw: memory not short aligned");
}
- *(unsigned short*)dst = inw(port);
- dst += 2;
- --count;
+ if (!count)
+ return;
+ count--;
+ *(unsigned short* ) dst = inw(port);
+ ((unsigned short *) dst)++;
}
- ip = dst;
while (count >= 2) {
- w = inw(port);
- w |= inw(port) << 16;
+ unsigned int w;
count -= 2;
- *ip++ = w;
+ w = inw(port);
+ w |= inw(port) << 16;
+ *(unsigned int *) dst = w;
+ ((unsigned int *) dst)++;
}
if (count) {
- w = inw(port);
- *(unsigned short*)ip = w;
+ *(unsigned short*) dst = inw(port);
}
}
@@ -145,20 +179,32 @@
#undef insl
void insl (unsigned long port, void *dst, unsigned long count)
{
- unsigned int *ip, w;
-
if (((unsigned long)dst) & 0x3) {
panic("insl: memory not aligned");
}
- ip = dst;
- while (count > 0) {
- w = inw(port);
+ while (count) {
--count;
- *ip++ = w;
+ *(unsigned int *) dst = inl(port);
+ ((unsigned int *) dst)++;
}
}
+/*
+ * Like insb but in the opposite direction.
+ * Don't worry as much about doing aligned memory transfers:
+ * doing byte reads the "slow" way isn't nearly as slow as
+ * doing byte writes the slow way (no r-m-w cycle).
+ */
+#undef outsb
+void outsb(unsigned long port, void * src, unsigned long count)
+{
+ while (count) {
+ count--;
+ outb(*(char *)src, port);
+ ((char *) src)++;
+ }
+}
/*
* Like insw but in the opposite direction. This is used by the IDE
@@ -169,27 +215,26 @@
#undef outsw
void outsw (unsigned long port, void *src, unsigned long count)
{
- unsigned int *ip, w;
-
if (((unsigned long)src) & 0x3) {
if (((unsigned long)src) & 0x1) {
panic("outsw: memory not short aligned");
}
outw(*(unsigned short*)src, port);
- src += 2;
+ ((unsigned short *) src)++;
--count;
}
- ip = src;
while (count >= 2) {
- w = *ip++;
+ unsigned int w;
count -= 2;
+ w = *(unsigned int *) src;
+ ((unsigned int *) src)++;
outw(w >> 0, port);
outw(w >> 16, port);
}
if (count) {
- outw(*(unsigned short*)ip, port);
+ outw(*(unsigned short *) src, port);
}
}
@@ -203,16 +248,55 @@
#undef outsw
void outsl (unsigned long port, void *src, unsigned long count)
{
- unsigned int *ip, w;
-
if (((unsigned long)src) & 0x3) {
panic("outsw: memory not aligned");
}
- ip = src;
- while (count > 0) {
- w = *ip++;
+ while (count) {
--count;
- outw(w, port);
+ outl(*(unsigned int *) src, port);
+ ((unsigned int *) src)++;
+ }
+}
+
+
+/*
+ * Copy data from IO memory space to "real" memory space.
+ * This needs to be optimized.
+ */
+void memcpy_fromio(void * to, unsigned long from, unsigned long count)
+{
+ while (count) {
+ count--;
+ *(char *) to = readb(from);
+ ((char *) to)++;
+ from++;
+ }
+}
+
+/*
+ * Copy data from "real" memory space to IO memory space.
+ * This needs to be optimized.
+ */
+void memcpy_toio(unsigned long to, void * from, unsigned long count)
+{
+ while (count) {
+ count--;
+ writeb(*(char *) from, to);
+ ((char *) from)++;
+ to++;
+ }
+}
+
+/*
+ * "memset" on IO memory space.
+ * This needs to be optimized.
+ */
+void memset_io(unsigned long dst, int c, unsigned long count)
+{
+ while (count) {
+ count--;
+ writeb(c, dst);
+ dst++;
}
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this