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
- Lines: 287
- Date:
2003-08-25 04:44:42.000000000 -0700
- Orig file:
linux-2.4.21/drivers/macintosh/via-cuda.c
- Orig date:
2002-11-28 15:53:13.000000000 -0800
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)