Re: howto access shared memory-address d0000 on alpha

Thomas Bogendoerfer (tsbogend@bigbug.franken.de)
Thu, 13 Jun 1996 07:22:24 +0200 (MET DST)


> you can wait a couple of days, Fritz or me will come up with a
> working ICN driver on the alpha (and probably on Linux/Mips:-)).

Ok, I fixed the ICN driver in 2.0.0. It's now working on my
Noname at least /dev/ttyI works. There are still some kernel
unaliagned accesses, which I will fix today. The patch below
will show up in one of the next kernels from Linus (at least the
ICN patch).

Thomas.

Index: linux/arch/alpha/config.in
===================================================================
RCS file: /usr/src/cvs/linux/arch/alpha/config.in,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 config.in
--- config.in 1996/06/04 20:51:35 1.1.1.2
+++ config.in 1996/06/07 10:04:52
@@ -123,6 +123,15 @@
fi

mainmenu_option next_comment
+comment 'ISDN subsystem'
+
+tristate 'ISDN support' CONFIG_ISDN
+if [ "$CONFIG_ISDN" != "n" ]; then
+ source drivers/isdn/Config.in
+fi
+endmenu
+
+mainmenu_option next_comment
comment 'CD-ROM drivers (not for SCSI or IDE/ATAPI drives)'

bool 'Support non-SCSI/IDE/ATAPI drives' CONFIG_CD_NO_IDESCSI
Index: linux/drivers/isdn/icn/icn.c
===================================================================
RCS file: /usr/src/cvs/linux/drivers/isdn/icn/icn.c,v
retrieving revision 1.1.1.3
diff -u -r1.1.1.3 icn.c
--- icn.c 1996/06/09 22:16:38 1.1.1.3
+++ icn.c 1996/06/11 22:40:41
@@ -112,6 +112,21 @@
#include "icn.h"

/*
+ * there is no memcpy_fromfs_toio, so we use a very generic
+ * version. It might be good to generate a much better optimized
+ * routine for each hardware architecture
+ */
+static inline void memcpy_fromfs_toio(unsigned long to, void * from, unsigned long count)
+{
+ while (count) {
+ count--;
+ writeb(get_user((char *)from), to);
+ ((char *) from)++;
+ to++;
+ }
+}
+
+/*
* Verbose bootcode- and protocol-downloading.
*/
#undef BOOT_DEBUG
@@ -315,7 +330,7 @@

if (icn_trymaplock_channel(card,mch)) {
while (rbavl) {
- cnt = rbuf_l;
+ cnt = readb(&rbuf_l);
if ((card->rcvidx[channel] + cnt) > 4000) {
printk(KERN_WARNING
"icn: (%s) bogus packet on ch%d, dropping.\n",
@@ -325,9 +340,9 @@
eflag = 0;
} else {
memcpy_fromio(&card->rcvbuf[channel][card->rcvidx[channel]],
- rbuf_d, cnt);
+ &rbuf_d, cnt);
card->rcvidx[channel] += cnt;
- eflag = rbuf_f;
+ eflag = readb(&rbuf_f);
}
rbnext;
icn_maprelease_channel(card, mch & 2);
@@ -381,10 +396,15 @@
}
skb->lock = 1;
restore_flags(flags);
- cnt =
- (sbuf_l =
- (skb->len > ICN_FRAGSIZE) ? ((sbuf_f = 0xff), ICN_FRAGSIZE) : ((sbuf_f = 0), skb->len));
- memcpy(sbuf_d, skb->data, cnt);
+ if (skb->len > ICN_FRAGSIZE) {
+ writeb (0xff, &sbuf_f);
+ cnt = ICN_FRAGSIZE;
+ } else {
+ writeb (0x0, &sbuf_f);
+ cnt = skb->len;
+ }
+ writeb (cnt, &sbuf_l);
+ memcpy_toio(&sbuf_d, skb->data, cnt);
skb_pull(skb, cnt);
card->sndcount[channel] -= cnt;
sbnext; /* switch to next buffer */
@@ -754,7 +774,6 @@
{
int ret;
ulong flags;
- unsigned char codebuf[ICN_CODE_STAGE1];

#ifdef BOOT_DEBUG
printk(KERN_DEBUG "icn_loadboot called, buffaddr=%08lx\n", (ulong) buffer);
@@ -807,8 +826,7 @@
icn_lock_channel(card,0); /* Lock Bank 0 */
restore_flags(flags);
SLEEP(1);
- memcpy_fromfs(codebuf, buffer, ICN_CODE_STAGE1); /* Copy code */
- memcpy_toio(dev.shmem, codebuf, ICN_CODE_STAGE1);
+ memcpy_fromfs_toio(dev.shmem, buffer, ICN_CODE_STAGE1); /* Copy code */
#ifdef BOOT_DEBUG
printk(KERN_DEBUG "Bootloader transfered\n");
#endif
@@ -824,8 +842,7 @@
icn_lock_channel(card,2); /* Lock Bank 8 */
restore_flags(flags);
SLEEP(1);
- memcpy_fromfs(codebuf, buffer, ICN_CODE_STAGE1); /* Copy code */
- memcpy_toio(dev.shmem, codebuf, ICN_CODE_STAGE1);
+ memcpy_fromfs_toio(dev.shmem, buffer, ICN_CODE_STAGE1); /* Copy code */
#ifdef BOOT_DEBUG
printk(KERN_DEBUG "Bootloader transfered\n");
#endif
@@ -877,7 +894,7 @@
while (left) {
if (sbfree) { /* If there is a free buffer... */
cnt = MIN(256, left);
- memcpy_fromfs(&sbuf_l, p, cnt); /* copy data */
+ memcpy_fromfs_toio(&sbuf_l, p, cnt); /* copy data */
sbnext; /* switch to next buffer */
p += cnt;
left -= cnt;
@@ -895,7 +912,7 @@
schedule();
}
}
- sbuf_n = 0x20;
+ writeb (0x20, &sbuf_n);
timer = 0;
while (1) {
if (readb(&cmd_o) || readb(&cmd_i)) {

-- 
That process _deserves_ to die ("My name is Linus Torvalds, prepare to 
die").                                [Linus Torvalds on linux-kernel]