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 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 iop_handle_recv(uint iop_num, uint chan) { volatile struct mac_iop *iop = iop_base[iop_num]; int i,offset; struct iop_msg *msg; #ifdef DEBUG_IOP printk("iop_handle_recv: iop %d channel %d\n", iop_num, chan); #endif msg = iop_alloc_msg(); msg->iop_num = iop_num; msg->channel = chan; msg->status = IOP_MSGSTATUS_UNSOL; msg->handler = iop_listeners[iop_num][chan].handler; offset = IOP_ADDR_RECV_MSG + (chan * IOP_MSG_LEN); for (i = 0 ; i < IOP_MSG_LEN ; i++, offset++) { msg->message[i] = iop_readb(iop, offset); } iop_writeb(iop, IOP_ADDR_RECV_STATE + chan, IOP_MSG_RCVD); /* If there is a listener, call it now. Otherwise complete */ /* the message ourselves to avoid possible stalls. */ if (msg->handler) { (*msg->handler)(msg); } else { #ifdef DEBUG_IOP printk("iop_handle_recv: unclaimed message on iop %d channel %d\n", iop_num, chan); printk("iop_handle_recv:"); for (i = 0 ; i < IOP_MSG_LEN ; i++) { printk(" %02X", (uint) msg->message[i]); } printk("\n"); #endif iop_complete_message(msg); } }