diff options
Diffstat (limited to 'arch/m68k/mac/iop.c')
-rw-r--r-- | arch/m68k/mac/iop.c | 60 |
1 files changed, 26 insertions, 34 deletions
diff --git a/arch/m68k/mac/iop.c b/arch/m68k/mac/iop.c index d3775afb0f07..c669a7644301 100644 --- a/arch/m68k/mac/iop.c +++ b/arch/m68k/mac/iop.c @@ -183,7 +183,7 @@ static __inline__ void iop_writeb(volatile struct mac_iop *iop, __u16 addr, __u8 static __inline__ void iop_stop(volatile struct mac_iop *iop) { - iop->status_ctrl &= ~IOP_RUN; + iop->status_ctrl = IOP_AUTOINC; } static __inline__ void iop_start(volatile struct mac_iop *iop) @@ -191,14 +191,9 @@ static __inline__ void iop_start(volatile struct mac_iop *iop) iop->status_ctrl = IOP_RUN | IOP_AUTOINC; } -static __inline__ void iop_bypass(volatile struct mac_iop *iop) -{ - iop->status_ctrl |= IOP_BYPASS; -} - static __inline__ void iop_interrupt(volatile struct mac_iop *iop) { - iop->status_ctrl |= IOP_IRQ; + iop->status_ctrl = IOP_IRQ | IOP_RUN | IOP_AUTOINC; } static int iop_alive(volatile struct mac_iop *iop) @@ -244,7 +239,6 @@ void __init iop_preinit(void) } else { iop_base[IOP_NUM_SCC] = (struct mac_iop *) SCC_IOP_BASE_QUADRA; } - iop_base[IOP_NUM_SCC]->status_ctrl = 0x87; iop_scc_present = 1; } else { iop_base[IOP_NUM_SCC] = NULL; @@ -256,7 +250,7 @@ void __init iop_preinit(void) } else { iop_base[IOP_NUM_ISM] = (struct mac_iop *) ISM_IOP_BASE_QUADRA; } - iop_base[IOP_NUM_ISM]->status_ctrl = 0; + iop_stop(iop_base[IOP_NUM_ISM]); iop_ism_present = 1; } else { iop_base[IOP_NUM_ISM] = NULL; @@ -353,8 +347,8 @@ void iop_complete_message(struct iop_msg *msg) int chan = msg->channel; int i,offset; - iop_pr_debug("msg %p iop_num %d channel %d\n", msg, msg->iop_num, - msg->channel); + iop_pr_debug("iop_num %d chan %d reply %*ph\n", + msg->iop_num, msg->channel, IOP_MSG_LEN, msg->reply); offset = IOP_ADDR_RECV_MSG + (msg->channel * IOP_MSG_LEN); @@ -378,6 +372,9 @@ static void iop_do_send(struct iop_msg *msg) volatile struct mac_iop *iop = iop_base[msg->iop_num]; int i,offset; + iop_pr_debug("iop_num %d chan %d message %*ph\n", + msg->iop_num, msg->channel, IOP_MSG_LEN, msg->message); + offset = IOP_ADDR_SEND_MSG + (msg->channel * IOP_MSG_LEN); for (i = 0 ; i < IOP_MSG_LEN ; i++, offset++) { @@ -400,8 +397,6 @@ static void iop_handle_send(uint iop_num, uint chan) struct iop_msg *msg; int i,offset; - iop_pr_debug("iop_num %d chan %d\n", iop_num, chan); - iop_writeb(iop, IOP_ADDR_SEND_STATE + chan, IOP_MSG_IDLE); if (!(msg = iop_send_queue[iop_num][chan])) return; @@ -411,11 +406,15 @@ static void iop_handle_send(uint iop_num, uint chan) for (i = 0 ; i < IOP_MSG_LEN ; i++, offset++) { msg->reply[i] = iop_readb(iop, offset); } + iop_pr_debug("iop_num %d chan %d reply %*ph\n", + iop_num, chan, IOP_MSG_LEN, msg->reply); + if (msg->handler) (*msg->handler)(msg); msg->status = IOP_MSGSTATUS_UNUSED; msg = msg->next; iop_send_queue[iop_num][chan] = msg; - if (msg) iop_do_send(msg); + if (msg && iop_readb(iop, IOP_ADDR_SEND_STATE + chan) == IOP_MSG_IDLE) + iop_do_send(msg); } /* @@ -429,8 +428,6 @@ static void iop_handle_recv(uint iop_num, uint chan) int i,offset; struct iop_msg *msg; - iop_pr_debug("iop_num %d chan %d\n", iop_num, chan); - msg = iop_get_unused_msg(); msg->iop_num = iop_num; msg->channel = chan; @@ -442,6 +439,8 @@ static void iop_handle_recv(uint iop_num, uint chan) for (i = 0 ; i < IOP_MSG_LEN ; i++, offset++) { msg->message[i] = iop_readb(iop, offset); } + iop_pr_debug("iop_num %d chan %d message %*ph\n", + iop_num, chan, IOP_MSG_LEN, msg->message); iop_writeb(iop, IOP_ADDR_RECV_STATE + chan, IOP_MSG_RCVD); @@ -451,9 +450,7 @@ static void iop_handle_recv(uint iop_num, uint chan) if (msg->handler) { (*msg->handler)(msg); } else { - iop_pr_debug("unclaimed message on iop_num %d chan %d\n", - iop_num, chan); - iop_pr_debug("%*ph\n", IOP_MSG_LEN, msg->message); + memset(msg->reply, 0, IOP_MSG_LEN); iop_complete_message(msg); } } @@ -489,16 +486,12 @@ int iop_send_message(uint iop_num, uint chan, void *privdata, if (!(q = iop_send_queue[iop_num][chan])) { iop_send_queue[iop_num][chan] = msg; + iop_do_send(msg); } else { while (q->next) q = q->next; q->next = msg; } - if (iop_readb(iop_base[iop_num], - IOP_ADDR_SEND_STATE + chan) == IOP_MSG_IDLE) { - iop_do_send(msg); - } - return 0; } @@ -567,35 +560,34 @@ irqreturn_t iop_ism_irq(int irq, void *dev_id) int i,state; u8 events = iop->status_ctrl & (IOP_INT0 | IOP_INT1); - iop_pr_debug("status %02X\n", iop->status_ctrl); - do { + iop_pr_debug("iop_num %d status %02X\n", iop_num, + iop->status_ctrl); + /* INT0 indicates state change on an outgoing message channel */ if (events & IOP_INT0) { iop->status_ctrl = IOP_INT0 | IOP_RUN | IOP_AUTOINC; - iop_pr_debug("new status %02X, send states", - iop->status_ctrl); for (i = 0; i < NUM_IOP_CHAN; i++) { state = iop_readb(iop, IOP_ADDR_SEND_STATE + i); - iop_pr_cont(" %02X", state); if (state == IOP_MSG_COMPLETE) iop_handle_send(iop_num, i); + else if (state != IOP_MSG_IDLE) + iop_pr_debug("chan %d send state %02X\n", + i, state); } - iop_pr_cont("\n"); } /* INT1 for incoming messages */ if (events & IOP_INT1) { iop->status_ctrl = IOP_INT1 | IOP_RUN | IOP_AUTOINC; - iop_pr_debug("new status %02X, recv states", - iop->status_ctrl); for (i = 0; i < NUM_IOP_CHAN; i++) { state = iop_readb(iop, IOP_ADDR_RECV_STATE + i); - iop_pr_cont(" %02X", state); if (state == IOP_MSG_NEW) iop_handle_recv(iop_num, i); + else if (state != IOP_MSG_IDLE) + iop_pr_debug("chan %d recv state %02X\n", + i, state); } - iop_pr_cont("\n"); } events = iop->status_ctrl & (IOP_INT0 | IOP_INT1); |