patch-2.4.22 linux-2.4.22/drivers/macintosh/via-cuda.c

Next file: linux-2.4.22/drivers/macintosh/via-pmu.c
Previous file: linux-2.4.22/drivers/macintosh/mediabay.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.21/drivers/macintosh/via-cuda.c linux-2.4.22/drivers/macintosh/via-cuda.c
@@ -37,7 +37,6 @@
 #ifdef CONFIG_MAC
 #define CUDA_IRQ IRQ_MAC_ADB
 #define __openfirmware
-#define eieio()
 #else
 #define CUDA_IRQ vias->intrs[0].line
 #endif
@@ -175,8 +174,8 @@
     /* for us by the main VIA driver in arch/m68k/mac/via.c        */
 
 #ifndef CONFIG_MAC
-    via[IFR] = 0x7f; eieio();	/* clear interrupts by writing 1s */
-    via[IER] = IER_SET|SR_INT; eieio();	/* enable interrupt from SR */
+    out_8(&via[IFR], 0x7f);	/* clear interrupts by writing 1s */
+    out_8(&via[IER], IER_SET|SR_INT); /* enable interrupt from SR */
 #endif
 
     /* enable autopoll */
@@ -244,7 +243,8 @@
 #endif /* CONFIG_ADB */
 
 #define WAIT_FOR(cond, what)					\
-    do {							\
+    do {                                                        \
+    	int x;							\
 	for (x = 1000; !(cond); --x) {				\
 	    if (x == 0) {					\
 		printk("Timeout waiting for " what "\n");	\
@@ -257,40 +257,40 @@
 static int
 cuda_init_via()
 {
-    int x;
-
-    via[DIRB] = (via[DIRB] | TACK | TIP) & ~TREQ;	/* TACK & TIP out */
-    via[B] |= TACK | TIP;				/* negate them */
-    via[ACR] = (via[ACR] & ~SR_CTRL) | SR_EXT;		/* SR data in */
-    eieio();
-    x = via[SR]; eieio();	/* clear any left-over data */
+    out_8(&via[DIRB], (in_8(&via[DIRB]) | TACK | TIP) & ~TREQ);	/* TACK & TIP out */
+    out_8(&via[B], in_8(&via[B]) | TACK | TIP);			/* negate them */
+    out_8(&via[ACR] ,(in_8(&via[ACR]) & ~SR_CTRL) | SR_EXT);	/* SR data in */
+    (void)in_8(&via[SR]);						/* clear any left-over data */
 #ifndef CONFIG_MAC
-    via[IER] = 0x7f; eieio();	/* disable interrupts from VIA */
+    out_8(&via[IER], 0x7f);					/* disable interrupts from VIA */
+    (void)in_8(&via[IER]);
 #endif
-    eieio();
 
     /* delay 4ms and then clear any pending interrupt */
     mdelay(4);
-    x = via[SR]; eieio();
+    (void)in_8(&via[SR]);
+    out_8(&via[IFR], in_8(&via[IFR]) & 0x7f);
 
     /* sync with the CUDA - assert TACK without TIP */
-    via[B] &= ~TACK; eieio();
+    out_8(&via[B], in_8(&via[B]) & ~TACK);
 
     /* wait for the CUDA to assert TREQ in response */
-    WAIT_FOR((via[B] & TREQ) == 0, "CUDA response to sync");
+    WAIT_FOR((in_8(&via[B]) & TREQ) == 0, "CUDA response to sync");
 
     /* wait for the interrupt and then clear it */
-    WAIT_FOR(via[IFR] & SR_INT, "CUDA response to sync (2)");
-    x = via[SR]; eieio();
+    WAIT_FOR(in_8(&via[IFR]) & SR_INT, "CUDA response to sync (2)");
+    (void)in_8(&via[SR]);
+    out_8(&via[IFR], in_8(&via[IFR]) & 0x7f);
 
     /* finish the sync by negating TACK */
-    via[B] |= TACK; eieio();
+    out_8(&via[B], in_8(&via[B]) | TACK);
 
     /* wait for the CUDA to negate TREQ and the corresponding interrupt */
-    WAIT_FOR(via[B] & TREQ, "CUDA response to sync (3)");
-    WAIT_FOR(via[IFR] & SR_INT, "CUDA response to sync (4)");
-    x = via[SR]; eieio();
-    via[B] |= TIP; eieio();	/* should be unnecessary */
+    WAIT_FOR(in_8(&via[B]) & TREQ, "CUDA response to sync (3)");
+    WAIT_FOR(in_8(&via[IFR]) & SR_INT, "CUDA response to sync (4)");
+    (void)in_8(&via[SR]);
+    out_8(&via[IFR], in_8(&via[IFR]) & 0x7f);
+    out_8(&via[B], in_8(&via[B]) | TIP);	/* should be unnecessary */
 
     return 0;
 }
@@ -413,55 +413,59 @@
     req = current_req;
     if (req == 0)
 	return;
-    if ((via[B] & TREQ) == 0)
+    if ((in_8(&via[B]) & TREQ) == 0)
 	return;			/* a byte is coming in from the CUDA */
 
     /* set the shift register to shift out and send a byte */
-    via[ACR] |= SR_OUT; eieio();
-    via[SR] = req->data[0]; eieio();
-    via[B] &= ~TIP;
+    out_8(&via[ACR], in_8(&via[ACR]) | SR_OUT);
+    out_8(&via[SR], req->data[0]);
+    out_8(&via[B], in_8(&via[B]) & ~TIP);
     cuda_state = sent_first_byte;
 }
 
 void
 cuda_poll()
 {
-    if (via[IFR] & SR_INT) {
-	unsigned long flags;
+    unsigned long flags;
 
-	/* cuda_interrupt only takes a normal lock, we disable
-	 * interrupts here to avoid re-entering and thus deadlocking.
-	 * An option would be to disable only the IRQ source with
-	 * disable_irq(), would that work on m68k ? --BenH
-	 */
-	local_irq_save(flags);
-	cuda_interrupt(0, 0, 0);
-	local_irq_restore(flags);
-    }
+    /* cuda_interrupt only takes a normal lock, we disable
+     * interrupts here to avoid re-entering and thus deadlocking.
+     * An option would be to disable only the IRQ source with
+     * disable_irq(), would that work on m68k ? --BenH
+     */
+    local_irq_save(flags);
+    cuda_interrupt(0, 0, 0);
+    local_irq_restore(flags);
 }
 
 static void
 cuda_interrupt(int irq, void *arg, struct pt_regs *regs)
 {
-    int x, status;
+    int status;
     struct adb_request *req = NULL;
     unsigned char ibuf[16];
     int ibuf_len = 0;
     int complete = 0;
+    unsigned char virq;
     
-    if ((via[IFR] & SR_INT) == 0)
-	return;
-
     spin_lock(&cuda_lock);
-    status = (~via[B] & (TIP|TREQ)) | (via[ACR] & SR_OUT); eieio();
+
+    virq = in_8(&via[IFR]) & 0x7f;
+    out_8(&via[IFR], virq);   
+    if ((virq & SR_INT) == 0) {
+        spin_unlock(&cuda_lock);
+	return;
+    }
+    
+    status = (~in_8(&via[B]) & (TIP|TREQ)) | (in_8(&via[ACR]) & SR_OUT);
     /* printk("cuda_interrupt: state=%d status=%x\n", cuda_state, status); */
     switch (cuda_state) {
     case idle:
 	/* CUDA has sent us the first byte of data - unsolicited */
 	if (status != TREQ)
 	    printk("cuda: state=idle, status=%x\n", status);
-	x = via[SR]; eieio();
-	via[B] &= ~TIP; eieio();
+	(void)in_8(&via[SR]);
+	out_8(&via[B], in_8(&via[B]) & ~TIP);
 	cuda_state = reading;
 	reply_ptr = cuda_rbuf;
 	reading_reply = 0;
@@ -471,8 +475,8 @@
 	/* CUDA has sent us the first byte of data of a reply */
 	if (status != TREQ)
 	    printk("cuda: state=awaiting_reply, status=%x\n", status);
-	x = via[SR]; eieio();
-	via[B] &= ~TIP; eieio();
+	(void)in_8(&via[SR]);
+	out_8(&via[B], in_8(&via[B]) & ~TIP);
 	cuda_state = reading;
 	reply_ptr = current_req->reply;
 	reading_reply = 1;
@@ -481,16 +485,16 @@
     case sent_first_byte:
 	if (status == TREQ + TIP + SR_OUT) {
 	    /* collision */
-	    via[ACR] &= ~SR_OUT; eieio();
-	    x = via[SR]; eieio();
-	    via[B] |= TIP | TACK; eieio();
+	    out_8(&via[ACR], in_8(&via[ACR]) & ~SR_OUT);
+	    (void)in_8(&via[SR]);
+	    out_8(&via[B], in_8(&via[B]) | TIP | TACK);
 	    cuda_state = idle;
 	} else {
 	    /* assert status == TIP + SR_OUT */
 	    if (status != TIP + SR_OUT)
 		printk("cuda: state=sent_first_byte status=%x\n", status);
-	    via[SR] = current_req->data[1]; eieio();
-	    via[B] ^= TACK; eieio();
+	    out_8(&via[SR], current_req->data[1]);
+	    out_8(&via[B], in_8(&via[B]) ^ TACK);
 	    data_index = 2;
 	    cuda_state = sending;
 	}
@@ -499,9 +503,9 @@
     case sending:
 	req = current_req;
 	if (data_index >= req->nbytes) {
-	    via[ACR] &= ~SR_OUT; eieio();
-	    x = via[SR]; eieio();
-	    via[B] |= TACK | TIP; eieio();
+	    out_8(&via[ACR], in_8(&via[ACR]) & ~SR_OUT);
+	    (void)in_8(&via[SR]);
+	    out_8(&via[B], in_8(&via[B]) | TACK | TIP);
 	    req->sent = 1;
 	    if (req->reply_expected) {
 		cuda_state = awaiting_reply;
@@ -513,27 +517,27 @@
 		cuda_start();
 	    }
 	} else {
-	    via[SR] = req->data[data_index++]; eieio();
-	    via[B] ^= TACK; eieio();
+	    out_8(&via[SR], req->data[data_index++]);
+	    out_8(&via[B], in_8(&via[B]) ^ TACK);
 	}
 	break;
 
     case reading:
-	*reply_ptr++ = via[SR]; eieio();
+	*reply_ptr++ = in_8(&via[SR]);
 	if (status == TIP) {
 	    /* that's all folks */
-	    via[B] |= TACK | TIP; eieio();
+	    out_8(&via[B], in_8(&via[B]) | TACK | TIP);
 	    cuda_state = read_done;
 	} else {
 	    /* assert status == TIP | TREQ */
 	    if (status != TIP + TREQ)
 		printk("cuda: state=reading status=%x\n", status);
-	    via[B] ^= TACK; eieio();
+	    out_8(&via[B], in_8(&via[B]) ^ TACK);
 	}
 	break;
 
     case read_done:
-	x = via[SR]; eieio();
+	(void)in_8(&via[SR]);
 	if (reading_reply) {
 	    req = current_req;
 	    req->reply_len = reply_ptr - req->reply;
@@ -548,7 +552,6 @@
 		    memmove(req->reply, req->reply + 2, req->reply_len);
 		}
 	    }
-	    req->complete = 1;
 	    current_req = req->next;
 	    complete = 1;
 	} else {
@@ -563,7 +566,7 @@
 	    memcpy(ibuf, cuda_rbuf, ibuf_len);
 	}
 	if (status == TREQ) {
-	    via[B] &= ~TIP; eieio();
+	    out_8(&via[B], in_8(&via[B]) & ~TIP);
 	    cuda_state = reading;
 	    reply_ptr = cuda_rbuf;
 	    reading_reply = 0;
@@ -577,8 +580,16 @@
 	printk("cuda_interrupt: unknown cuda_state %d?\n", cuda_state);
     }
     spin_unlock(&cuda_lock);
-    if (complete && req && req->done)
-	(*req->done)(req);
+    if (complete && req) {
+    	void (*done)(struct adb_request *) = req->done;
+    	mb();
+    	req->complete = 1;
+    	/* Here, we assume that if the request has a done member, the
+    	 * struct request will survive to setting req->complete to 1
+    	 */
+    	if (done)
+		(*done)(req);
+    }
     if (ibuf_len)
 	cuda_input(ibuf, ibuf_len, regs);
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)