⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iop.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 2 页
字号:
 * into the buffer, setting the channel state to MSG_COMPLETE and * notifying the IOP. */void iop_complete_message(struct iop_msg *msg){	int iop_num = msg->iop_num;	int chan = msg->channel;	int i,offset;#ifdef DEBUG_IOP	printk("iop_complete(%p): iop %d chan %d\n", msg, msg->iop_num, msg->channel);#endif	offset = IOP_ADDR_RECV_MSG + (msg->channel * IOP_MSG_LEN);	for (i = 0 ; i < IOP_MSG_LEN ; i++, offset++) {		iop_writeb(iop_base[iop_num], offset, msg->reply[i]);	}	iop_writeb(iop_base[iop_num],		   IOP_ADDR_RECV_STATE + chan, IOP_MSG_COMPLETE);	iop_interrupt(iop_base[msg->iop_num]);	iop_free_msg(msg);}/* * Actually put a message into a send channel buffer */static void iop_do_send(struct iop_msg *msg){	volatile struct mac_iop *iop = iop_base[msg->iop_num];	int i,offset;	offset = IOP_ADDR_SEND_MSG + (msg->channel * IOP_MSG_LEN);	for (i = 0 ; i < IOP_MSG_LEN ; i++, offset++) {		iop_writeb(iop, offset, msg->message[i]);	}	iop_writeb(iop, IOP_ADDR_SEND_STATE + msg->channel, IOP_MSG_NEW);	iop_interrupt(iop);}/* * Handle sending a message on a channel that * has gone into the IOP_MSG_COMPLETE state. */static void iop_handle_send(uint iop_num, uint chan, struct pt_regs *regs){	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, regs);	msg2 = msg;	msg = msg->next;	iop_free_msg(msg2);	iop_send_queue[iop_num][chan] = msg;	if (msg) iop_do_send(msg);}/* * Handle reception of a message on a channel that has * gone into the IOP_MSG_NEW state. */static void iop_handle_recv(uint iop_num, uint chan, struct pt_regs *regs){	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, regs);	} 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);	}}/* * Send a message *  * The message is placed at the end of the send queue. Afterwards if the * channel is idle we force an immediate send of the next message in the * queue. */int iop_send_message(uint iop_num, uint chan, void *privdata,		      uint msg_len, __u8 *msg_data,		      void (*handler)(struct iop_msg *, struct pt_regs *)){	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;}/* * Upload code to the shared RAM of an IOP. */void iop_upload_code(uint iop_num, __u8 *code_start,		     uint code_len, __u16 shared_ram_start){	if ((iop_num >= NUM_IOPS) || !iop_base[iop_num]) return;	iop_loadaddr(iop_base[iop_num], shared_ram_start);		while (code_len--) {		iop_base[iop_num]->ram_data = *code_start++;	}}/* * Download code from the shared RAM of an IOP. */void iop_download_code(uint iop_num, __u8 *code_start,		       uint code_len, __u16 shared_ram_start){	if ((iop_num >= NUM_IOPS) || !iop_base[iop_num]) return;	iop_loadaddr(iop_base[iop_num], shared_ram_start);		while (code_len--) {		*code_start++ = iop_base[iop_num]->ram_data;	}}/* * Compare the code in the shared RAM of an IOP with a copy in system memory * and return 0 on match or the first nonmatching system memory address on * failure. */__u8 *iop_compare_code(uint iop_num, __u8 *code_start,		       uint code_len, __u16 shared_ram_start){	if ((iop_num >= NUM_IOPS) || !iop_base[iop_num]) return code_start;	iop_loadaddr(iop_base[iop_num], shared_ram_start);		while (code_len--) {		if (*code_start != iop_base[iop_num]->ram_data) {			return code_start;		}		code_start++;	}	return (__u8 *) 0;}/* * Handle an ISM IOP interrupt */void iop_ism_irq(int irq, void *dev_id, struct pt_regs *regs){	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, regs);			}		}#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, regs);			}		}#ifdef DEBUG_IOP		printk("\n");#endif	}}#ifdef CONFIG_PROC_FSchar *iop_chan_state(int state){	switch(state) {		case IOP_MSG_IDLE	: return "idle      ";		case IOP_MSG_NEW	: return "new       ";		case IOP_MSG_RCVD	: return "received  ";		case IOP_MSG_COMPLETE	: return "completed ";		default			: return "unknown   ";	}}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;} static int iop_get_proc_info(char *buf, char **start, off_t pos, int count){	int len, cnt;	cnt = 0;	len =  sprintf(buf, "IOPs detected:\n\n");	if (iop_scc_present) {		len += sprintf(buf+len, "SCC IOP (%p): status %02X\n",				iop_base[IOP_NUM_SCC],				(uint) iop_base[IOP_NUM_SCC]->status_ctrl);	}	if (iop_ism_present) {		len += sprintf(buf+len, "ISM IOP (%p): status %02X\n\n",				iop_base[IOP_NUM_ISM],				(uint) iop_base[IOP_NUM_ISM]->status_ctrl);	}	if (iop_scc_present) {		len += iop_dump_one_iop(buf+len, IOP_NUM_SCC, "SCC");	}	if (iop_ism_present) {		len += iop_dump_one_iop(buf+len, IOP_NUM_ISM, "ISM");	}	if (len >= pos) {		if (!*start) {			*start = buf + pos;			cnt = len - pos;		} else {			cnt += len;		}	}	return (count > cnt) ? cnt : count;}#endif /* CONFIG_PROC_FS */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -