static void cuda_input(unsigned char *buf, int nb) { int i; switch (buf[0]) { case ADB_PACKET: #ifdef CONFIG_XMON if (nb == 5 && buf[2] == 0x2c) { extern int xmon_wants_key, xmon_adb_keycode; if (xmon_wants_key) { xmon_adb_keycode = buf[3]; return; } } #endif /* CONFIG_XMON */ #ifdef CONFIG_ADB adb_input(buf+2, nb-2, buf[1] & 0x40); #endif /* CONFIG_ADB */ break; default: printk("data from cuda (%d bytes):", nb); for (i = 0; i < nb; ++i) printk(" %.2x", buf[i]); printk("\n"); } }
static void adb_iop_listen(struct iop_msg *msg) { struct adb_iopmsg *amsg = (struct adb_iopmsg *) msg->message; struct adb_request *req; unsigned long flags; #ifdef DEBUG_ADB_IOP int i; #endif local_irq_save(flags); req = current_req; #ifdef DEBUG_ADB_IOP printk("adb_iop_listen %p: rcvd packet, %d bytes: %02X %02X", req, (uint) amsg->count + 2, (uint) amsg->flags, (uint) amsg->cmd); for (i = 0; i < amsg->count; i++) printk(" %02X", (uint) amsg->data[i]); printk("\n"); #endif if (amsg->flags & ADB_IOP_TIMEOUT) { msg->reply[0] = ADB_IOP_TIMEOUT | ADB_IOP_AUTOPOLL; msg->reply[1] = 0; msg->reply[2] = 0; if (req && (adb_iop_state != idle)) { adb_iop_end_req(req, idle); } } else { if ((adb_iop_state == awaiting_reply) && (amsg->flags & ADB_IOP_EXPLICIT)) { req->reply_len = amsg->count + 1; memcpy(req->reply, &amsg->cmd, req->reply_len); } else { adb_input(&amsg->cmd, amsg->count + 1, amsg->flags & ADB_IOP_AUTOPOLL); } memcpy(msg->reply, msg->message, IOP_MSG_LEN); } iop_complete_message(msg); local_irq_restore(flags); }
static void adb_iop_listen(struct iop_msg *msg, struct pt_regs *regs) { struct adb_iopmsg *amsg = (struct adb_iopmsg *) msg->message; struct adb_request *req; uint flags; #ifdef DEBUG_ADB_IOP int i; #endif local_irq_save(flags); req = current_req; #ifdef DEBUG_ADB_IOP printk("adb_iop_listen %p: rcvd packet, %d bytes: %02X %02X", req, (uint) amsg->count + 2, (uint) amsg->flags, (uint) amsg->cmd); for (i = 0; i < amsg->count; i++) printk(" %02X", (uint) amsg->data[i]); printk("\n"); #endif /* Handle a timeout. Timeout packets seem to occur even after */ /* we've gotten a valid reply to a TALK, so I'm assuming that */ /* a "timeout" is actually more like an "end-of-data" signal. */ /* We need to send back a timeout packet to the IOP to shut */ /* it up, plus complete the current request, if any. */ if (amsg->flags & ADB_IOP_TIMEOUT) { msg->reply[0] = ADB_IOP_TIMEOUT | ADB_IOP_AUTOPOLL; msg->reply[1] = 0; msg->reply[2] = 0; if (req && (adb_iop_state != idle)) { adb_iop_end_req(req, idle); } } else { /* TODO: is it possible for more than one chunk of data */ /* to arrive before the timeout? If so we need to */ /* use reply_ptr here like the other drivers do. */ if ((adb_iop_state == awaiting_reply) && (amsg->flags & ADB_IOP_EXPLICIT)) { req->reply_len = amsg->count + 1; memcpy(req->reply, &amsg->cmd, req->reply_len); } else { adb_input(&amsg->cmd, amsg->count + 1, regs, amsg->flags & ADB_IOP_AUTOPOLL); } memcpy(msg->reply, msg->message, IOP_MSG_LEN); } iop_complete_message(msg); local_irq_restore(flags); }
static void maciisi_input(unsigned char *buf, int nb, struct pt_regs *regs) { int i; switch (buf[0]) { case ADB_PACKET: adb_input(buf+2, nb-2, regs, buf[1] & 0x40); break; default: printk(KERN_DEBUG "data from IIsi ADB (%d bytes):", nb); for (i = 0; i < nb; ++i) printk(" %.2x", buf[i]); printk("\n"); } }
static void maciisi_input(unsigned char *buf, int nb) { #ifdef DEBUG_MACIISI_ADB int i; #endif switch (buf[0]) { case ADB_PACKET: adb_input(buf+2, nb-2, buf[1] & 0x40); break; default: #ifdef DEBUG_MACIISI_ADB printk(KERN_DEBUG "data from IIsi ADB (%d bytes):", nb); for (i = 0; i < nb; ++i) printk(" %.2x", buf[i]); printk("\n"); #endif break; } }
static void macio_adb_interrupt(int irq, void *arg, struct pt_regs *regs) { int i, n, err; struct adb_request *req; unsigned char ibuf[16]; int ibuf_len = 0; int complete = 0; int autopoll = 0; spin_lock(&macio_lock); if (in_8(&adb->intr.r) & TAG) { if ((req = current_req) != 0) { /* put the current request in */ for (i = 0; i < req->nbytes; ++i) out_8(&adb->data[i].r, req->data[i]); out_8(&adb->dcount.r, req->nbytes & HMB); req->sent = 1; if (req->reply_expected) { out_8(&adb->ctrl.r, DTB + CRE); } else { out_8(&adb->ctrl.r, DTB); req->complete = 1; current_req = req->next; complete = 1; if (current_req) out_8(&adb->ctrl.r, in_8(&adb->ctrl.r) | TAR); } } out_8(&adb->intr.r, 0); } if (in_8(&adb->intr.r) & DFB) { err = in_8(&adb->error.r); if (current_req && current_req->sent) { /* this is the response to a command */ req = current_req; if (err == 0) { req->reply_len = in_8(&adb->dcount.r) & HMB; for (i = 0; i < req->reply_len; ++i) req->reply[i] = in_8(&adb->data[i].r); } req->complete = 1; current_req = req->next; complete = 1; if (current_req) out_8(&adb->ctrl.r, in_8(&adb->ctrl.r) | TAR); } else if (err == 0) { /* autopoll data */ n = in_8(&adb->dcount.r) & HMB; for (i = 0; i < n; ++i) ibuf[i] = in_8(&adb->data[i].r); ibuf_len = n; autopoll = (in_8(&adb->dcount.r) & APD) != 0; } out_8(&adb->error.r, 0); out_8(&adb->intr.r, 0); } spin_unlock(&macio_lock); if (complete && req && req->done) (*req->done)(req); if (ibuf_len) adb_input(ibuf, ibuf_len, regs, autopoll); }
/* * The notorious ADB interrupt handler - does all of the protocol handling, * except for starting new send operations. Relies heavily on the ADB * controller sending and receiving data, thereby generating SR interrupts * for us. This means there has to be always activity on the ADB bus, otherwise * the whole process dies and has to be re-kicked by sending TALK requests ... * CUDA-based Macs seem to solve this with the autopoll option, for MacII-type * ADB the problem isn't solved yet (retransmit of the latest active TALK seems * a good choice; either on timeout or on a timer interrupt). * * The basic ADB state machine was left unchanged from the original MacII code * by Alan Cox, which was based on the CUDA driver for PowerMac. * The syntax of the ADB status lines seems to be totally different on MacII, * though. MacII uses the states Command -> Even -> Odd -> Even ->...-> Idle for * sending, and Idle -> Even -> Odd -> Even ->...-> Idle for receiving. Start * and end of a receive packet are signaled by asserting /IRQ on the interrupt * line. Timeouts are signaled by a sequence of 4 0xFF, with /IRQ asserted on * every other byte. SRQ is probably signaled by 3 or more 0xFF tacked on the * end of a packet. (Thanks to Guido Koerber for eavesdropping on the ADB * protocol with a logic analyzer!!) * * Note: As of 21/10/97, the MacII ADB part works including timeout detection * and retransmit (Talk to the last active device). */ void macii_interrupt(int irq, void *arg, struct pt_regs *regs) { int x, adbdir; unsigned long flags; struct adb_request *req; last_status = status; /* prevent races due to SCSI enabling ints */ save_flags(flags); cli(); if (driver_running) { restore_flags(flags); return; } driver_running = 1; status = via[B] & (ST_MASK|TREQ); adbdir = via[ACR] & SR_OUT; switch (macii_state) { case idle: x = via[SR]; first_byte = x; /* set ADB state = even for first data byte */ via[B] = (via[B] & ~ST_MASK) | ST_EVEN; reply_buf[0] = first_byte; /* was command_byte?? */ reply_ptr = reply_buf + 1; reply_len = 1; prefix_len = 1; reading_reply = 0; macii_state = reading; break; case awaiting_reply: /* handshake etc. for II ?? */ x = via[SR]; first_byte = x; /* set ADB state = even for first data byte */ via[B] = (via[B] & ~ST_MASK) | ST_EVEN; current_req->reply[0] = first_byte; reply_ptr = current_req->reply + 1; reply_len = 1; prefix_len = 1; reading_reply = 1; macii_state = reading; break; case sending: req = current_req; if (data_index >= req->nbytes) { /* print an error message if a listen command has no data */ if (((command_byte & 0x0C) == 0x08) /* && (console_loglevel == 10) */ && (data_index == 2)) printk("MacII ADB: listen command with no data: %x!\n", command_byte); /* reset to shift in */ via[ACR] &= ~SR_OUT; x = via[SR]; /* set ADB state idle - might get SRQ */ via[B] = (via[B] & ~ST_MASK) | ST_IDLE; req->sent = 1; if (req->reply_expected) { macii_state = awaiting_reply; } else { req->complete = 1; current_req = req->next; if (req->done) (*req->done)(req); macii_state = idle; if (current_req || retry_req) macii_start(); else macii_retransmit((command_byte & 0xF0) >> 4); } } else { via[SR] = req->data[data_index++]; if ( (via[B] & ST_MASK) == ST_CMD ) { /* just sent the command byte, set to EVEN */ via[B] = (via[B] & ~ST_MASK) | ST_EVEN; } else { /* invert state bits, toggle ODD/EVEN */ via[B] ^= ST_MASK; } } break; case reading: /* timeout / SRQ handling for II hw */ if( (first_byte == 0xFF && (reply_len-prefix_len)==2 && memcmp(reply_ptr-2,"\xFF\xFF",2)==0) || ((reply_len-prefix_len)==3 && memcmp(reply_ptr-3,"\xFF\xFF\xFF",3)==0)) { /* * possible timeout (in fact, most probably a * timeout, since SRQ can't be signaled without * transfer on the bus). * The last three bytes seen were FF, together * with the starting byte (in case we started * on 'idle' or 'awaiting_reply') this probably * makes four. So this is mostl likely #5! * The timeout signal is a pattern 1 0 1 0 0.. * on /INT, meaning we missed it :-( */ x = via[SR]; if (x != 0xFF) printk("MacII ADB: mistaken timeout/SRQ!\n"); if ((status & TREQ) == (last_status & TREQ)) { /* Not a timeout. Unsolicited SRQ? weird. */ /* Terminate the SRQ packet and poll */ need_poll = 1; } /* There's no packet to get, so reply is blank */ via[B] ^= ST_MASK; reply_ptr -= (reply_len-prefix_len); reply_len = prefix_len; macii_state = read_done; break; } /* end timeout / SRQ handling for II hw. */ if((reply_len-prefix_len)>3 && memcmp(reply_ptr-3,"\xFF\xFF\xFF",3)==0) { /* SRQ tacked on data packet */ /* Terminate the packet (SRQ never ends) */ x = via[SR]; macii_state = read_done; reply_len -= 3; reply_ptr -= 3; need_poll = 1; /* need to continue; next byte not seen else */ } else { /* Sanity check */ if (reply_len > 15) reply_len = 0; /* read byte */ x = via[SR]; *reply_ptr = x; reply_ptr++; reply_len++; } /* The usual handshake ... */ /* * NetBSD hints that the next to last byte * is sent with IRQ !! * Guido found out it's the last one (0x0), * but IRQ should be asserted already. * Problem with timeout detection: First * transition to /IRQ might be second * byte of timeout packet! * Timeouts are signaled by 4x FF. */ if (((status & TREQ) == 0) && (x == 0x00)) { /* != 0xFF */ /* invert state bits, toggle ODD/EVEN */ via[B] ^= ST_MASK; /* adjust packet length */ reply_len--; reply_ptr--; macii_state = read_done; } else { /* not caught: ST_CMD */ /* required for re-entry 'reading'! */ if ((status & ST_MASK) == ST_IDLE) { /* (in)sanity check - set even */ via[B] = (via[B] & ~ST_MASK) | ST_EVEN; } else { /* invert state bits */ via[B] ^= ST_MASK; } } break; case read_done: x = via[SR]; if (reading_reply) { req = current_req; req->reply_len = reply_ptr - req->reply; req->complete = 1; current_req = req->next; if (req->done) (*req->done)(req); } else { adb_input(reply_buf, reply_ptr - reply_buf, regs, 0); } /* * remember this device ID; it's the latest we got a * reply from! */ last_reply = command_byte; last_active = (command_byte & 0xF0) >> 4; /* SRQ seen before, initiate poll now */ if (need_poll) { macii_state = idle; macii_queue_poll(); need_poll = 0; break; } /* set ADB state to idle */ via[B] = (via[B] & ~ST_MASK) | ST_IDLE; /* /IRQ seen, so the ADB controller has data for us */ if ((via[B] & TREQ) != 0) { macii_state = reading; reply_buf[0] = command_byte; reply_ptr = reply_buf + 1; reply_len = 1; prefix_len = 1; reading_reply = 0; } else { /* no IRQ, send next packet or wait */ macii_state = idle; if (current_req) macii_start(); else macii_retransmit(last_active); } break; default: break; }
static irqreturn_t macio_adb_interrupt(int irq, void *arg) { int i, n, err; struct adb_request *req = NULL; unsigned char ibuf[16]; int ibuf_len = 0; int complete = 0; int autopoll = 0; int handled = 0; spin_lock(&macio_lock); if (in_8(&adb->intr.r) & TAG) { handled = 1; if ((req = current_req) != 0) { /* put the current request in */ for (i = 0; i < req->nbytes; ++i) out_8(&adb->data[i].r, req->data[i]); out_8(&adb->dcount.r, req->nbytes & HMB); req->sent = 1; if (req->reply_expected) { out_8(&adb->ctrl.r, DTB + CRE); } else { out_8(&adb->ctrl.r, DTB); current_req = req->next; complete = 1; if (current_req) out_8(&adb->ctrl.r, in_8(&adb->ctrl.r) | TAR); } } out_8(&adb->intr.r, 0); } if (in_8(&adb->intr.r) & DFB) { handled = 1; err = in_8(&adb->error.r); if (current_req && current_req->sent) { /* this is the response to a command */ req = current_req; if (err == 0) { req->reply_len = in_8(&adb->dcount.r) & HMB; for (i = 0; i < req->reply_len; ++i) req->reply[i] = in_8(&adb->data[i].r); } current_req = req->next; complete = 1; if (current_req) out_8(&adb->ctrl.r, in_8(&adb->ctrl.r) | TAR); } else if (err == 0) { /* autopoll data */ n = in_8(&adb->dcount.r) & HMB; for (i = 0; i < n; ++i) ibuf[i] = in_8(&adb->data[i].r); ibuf_len = n; autopoll = (in_8(&adb->dcount.r) & APD) != 0; } out_8(&adb->error.r, 0); out_8(&adb->intr.r, 0); } spin_unlock(&macio_lock); 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) adb_input(ibuf, ibuf_len, autopoll); return IRQ_RETVAL(handled); }