Beispiel #1
0
irqreturn_t iop_ism_irq(int irq, void *dev_id)
{
	uint iop_num = (uint) dev_id;
	volatile struct mac_iop *iop = iop_base[iop_num];
	int i,state;

#ifdef DEBUG_IOP
	printk("iop_ism_irq: status = %02X\n", (uint) iop->status_ctrl);
#endif

	/* INT0 indicates a state change on an outgoing message channel */

	if (iop->status_ctrl & IOP_INT0) {
		iop->status_ctrl = IOP_INT0 | IOP_RUN | IOP_AUTOINC;
#ifdef DEBUG_IOP
		printk("iop_ism_irq: new status = %02X, send states",
			(uint) iop->status_ctrl);
#endif
		for (i = 0 ; i < NUM_IOP_CHAN  ; i++) {
			state = iop_readb(iop, IOP_ADDR_SEND_STATE + i);
#ifdef DEBUG_IOP
			printk(" %02X", state);
#endif
			if (state == IOP_MSG_COMPLETE) {
				iop_handle_send(iop_num, i);
			}
		}
#ifdef DEBUG_IOP
		printk("\n");
#endif
	}

	if (iop->status_ctrl & IOP_INT1) {	/* INT1 for incoming msgs */
		iop->status_ctrl = IOP_INT1 | IOP_RUN | IOP_AUTOINC;
#ifdef DEBUG_IOP
		printk("iop_ism_irq: new status = %02X, recv states",
			(uint) iop->status_ctrl);
#endif
		for (i = 0 ; i < NUM_IOP_CHAN ; i++) {
			state = iop_readb(iop, IOP_ADDR_RECV_STATE + i);
#ifdef DEBUG_IOP
			printk(" %02X", state);
#endif
			if (state == IOP_MSG_NEW) {
				iop_handle_recv(iop_num, i);
			}
		}
#ifdef DEBUG_IOP
		printk("\n");
#endif
	}
	return IRQ_HANDLED;
}
Beispiel #2
0
int iop_send_message(uint iop_num, uint chan, void *privdata,
		      uint msg_len, __u8 *msg_data,
		      void (*handler)(struct iop_msg *))
{
	struct iop_msg *msg, *q;

	if ((iop_num >= NUM_IOPS) || !iop_base[iop_num]) return -EINVAL;
	if (chan >= NUM_IOP_CHAN) return -EINVAL;
	if (msg_len > IOP_MSG_LEN) return -EINVAL;

	msg = iop_alloc_msg();
	if (!msg) return -ENOMEM;

	msg->next = NULL;
	msg->status = IOP_MSGSTATUS_WAITING;
	msg->iop_num = iop_num;
	msg->channel = chan;
	msg->caller_priv = privdata;
	memcpy(msg->message, msg_data, msg_len);
	msg->handler = handler;

	if (!(q = iop_send_queue[iop_num][chan])) {
		iop_send_queue[iop_num][chan] = 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;
}
Beispiel #3
0
static void iop_handle_send(uint iop_num, uint chan)
{
	volatile struct mac_iop *iop = iop_base[iop_num];
	struct iop_msg *msg,*msg2;
	int i,offset;

#ifdef DEBUG_IOP
	printk("iop_handle_send: iop %d channel %d\n", iop_num, chan);
#endif

	iop_writeb(iop, IOP_ADDR_SEND_STATE + chan, IOP_MSG_IDLE);

	if (!(msg = iop_send_queue[iop_num][chan])) return;

	msg->status = IOP_MSGSTATUS_COMPLETE;
	offset = IOP_ADDR_SEND_MSG + (chan * IOP_MSG_LEN);
	for (i = 0 ; i < IOP_MSG_LEN ; i++, offset++) {
		msg->reply[i] = iop_readb(iop, offset);
	}
	if (msg->handler) (*msg->handler)(msg);
	msg2 = msg;
	msg = msg->next;
	iop_free_msg(msg2);

	iop_send_queue[iop_num][chan] = msg;
	if (msg) iop_do_send(msg);
}
Beispiel #4
0
static int iop_alive(volatile struct mac_iop *iop)
{
	int retval;

	retval = (iop_readb(iop, IOP_ADDR_ALIVE) == 0xFF);
	iop_writeb(iop, IOP_ADDR_ALIVE, 0);
	return retval;
}
Beispiel #5
0
int iop_dump_one_iop(char *buf, int iop_num, char *iop_name)
{
	int i,len = 0;
	volatile struct mac_iop *iop = iop_base[iop_num];

	len += sprintf(buf+len, "%s IOP channel states:\n\n", iop_name);
	len += sprintf(buf+len, "##  send_state  recv_state  device\n");
	len += sprintf(buf+len, "------------------------------------------------\n");
	for (i = 0 ; i < NUM_IOP_CHAN ; i++) {
		len += sprintf(buf+len, "%2d  %10s  %10s  %s\n", i,
			iop_chan_state(iop_readb(iop, IOP_ADDR_SEND_STATE+i)),
			iop_chan_state(iop_readb(iop, IOP_ADDR_RECV_STATE+i)),
			iop_listeners[iop_num][i].handler?
				      iop_listeners[iop_num][i].devname : "");
			
	}
	len += sprintf(buf+len, "\n");
	return len;
}
Beispiel #6
0
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);
	}
}