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

📄 hwc_rw.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 4 页
字号:
		internal_print (				       DELAYED_WRITE,				       "*** " HWC_RW_PRINT_HEADER			 "page at 0x%x released, %i pages still in use ***\n",				       page, hwc_data.hwcb_count);#endif	}	return 0;}static int add_mto (		unsigned char *message,		unsigned short int count){	unsigned short int mto_size;	write_hwcb_t *hwcb;	mto_t *mto;	void *dest;	if (!BUF_HWCB)		return -ENOMEM;	if (BUF_HWCB == hwc_data.current_hwcb)		return -ENOMEM;	mto_size = sizeof (mto_t) + count;	hwcb = (write_hwcb_t *) BUF_HWCB;	if ((MAX_HWCB_ROOM - hwcb->length) < mto_size)		return -ENOMEM;	mto = (mto_t *) (((unsigned long) hwcb) + hwcb->length);	memcpy (mto, &mto_template, sizeof (mto_t));	dest = (void *) (((unsigned long) mto) + sizeof (mto_t));	memcpy (dest, message, count);	mto->length += count;	hwcb->length += mto_size;	hwcb->msgbuf.length += mto_size;	hwcb->msgbuf.mdb.length += mto_size;	BUF_HWCB_MTO++;	ALL_HWCB_MTO++;	BUF_HWCB_CHAR += count;	ALL_HWCB_CHAR += count;	return count;}static int write_event_data_1 (void);static void do_poll_hwc (unsigned long data){	unsigned long flags;	spin_lock_irqsave (&hwc_data.lock, flags);	write_event_data_1 ();	spin_unlock_irqrestore (&hwc_data.lock, flags);}void start_poll_hwc (void){	init_timer (&hwc_data.poll_timer);	hwc_data.poll_timer.function = do_poll_hwc;	hwc_data.poll_timer.data = (unsigned long) NULL;	hwc_data.poll_timer.expires = jiffies + 2 * HZ;	add_timer (&hwc_data.poll_timer);	hwc_data.flags |= HWC_PTIMER_RUNS;}static int write_event_data_1 (void){	unsigned short int condition_code;	int retval;	write_hwcb_t *hwcb = (write_hwcb_t *) OUT_HWCB;	if ((!hwc_data.write_prio) &&	    (!hwc_data.write_nonprio) &&	    hwc_data.read_statechange)		return -EOPNOTSUPP;	if (hwc_data.current_servc)		return -EBUSY;	retval = sane_write_hwcb ();	if (retval < 0)		return -EIO;	if (!OUT_HWCB_MTO)		return -ENODATA;	if (!hwc_data.write_nonprio && hwc_data.write_prio)		hwcb->msgbuf.type = ET_PMsgCmd;	else		hwcb->msgbuf.type = ET_Msg;	condition_code = service_call (HWC_CMDW_WRITEDATA, OUT_HWCB);#ifdef DUMP_HWC_WRITE_ERROR	if (condition_code != HWC_COMMAND_INITIATED)		__asm__ ("LHI 1,0xe20\n\t"			 "L 2,0(%0)\n\t"			 "LRA 3,0(%1)\n\t"			 "J .+0 \n\t"	      :	      :	 "a" (&condition_code), "a" (OUT_HWCB)	      :	 "1", "2", "3");#endif	switch (condition_code) {	case HWC_COMMAND_INITIATED:		hwc_data.current_servc = HWC_CMDW_WRITEDATA;		hwc_data.current_hwcb = OUT_HWCB;		retval = condition_code;		break;	case HWC_BUSY:		retval = -EBUSY;		break;	case HWC_NOT_OPERATIONAL:		start_poll_hwc ();	default:		retval = -EIO;	}	return retval;}static void flush_hwcbs (void){	while (hwc_data.hwcb_count > 1)		release_write_hwcb ();	release_write_hwcb ();	hwc_data.flags &= ~HWC_FLUSH;}static int write_event_data_2 (u32 ext_int_param){	write_hwcb_t *hwcb;	int retval = 0;#ifdef DUMP_HWC_WRITE_ERROR	if ((ext_int_param & HWC_EXT_INT_PARAM_ADDR)	    != (unsigned long) hwc_data.current_hwcb) {		internal_print (				       DELAYED_WRITE,				       HWC_RW_PRINT_HEADER				       "write_event_data_2 : "				       "HWCB address does not fit "				       "(expected: 0x%lx, got: 0x%lx).\n",				       (unsigned long) hwc_data.current_hwcb,				       ext_int_param);		return -EINVAL;	}#endif	hwcb = (write_hwcb_t *) OUT_HWCB;#ifdef DUMP_HWC_WRITE_LIST_ERROR	if (((unsigned char *) hwcb) != hwc_data.current_hwcb) {		__asm__ ("LHI 1,0xe22\n\t"			 "LRA 2,0(%0)\n\t"			 "LRA 3,0(%1)\n\t"			 "LRA 4,0(%2)\n\t"			 "LRA 5,0(%3)\n\t"			 "J .+0 \n\t"	      :	      :	 "a" (OUT_HWCB),			 "a" (hwc_data.current_hwcb),			 "a" (BUF_HWCB),			 "a" (hwcb)	      :	 "1", "2", "3", "4", "5");	}#endif#ifdef DUMP_HWC_WRITE_ERROR	if (hwcb->response_code != 0x0020) {		__asm__ ("LHI 1,0xe21\n\t"			 "LRA 2,0(%0)\n\t"			 "LRA 3,0(%1)\n\t"			 "LRA 4,0(%2)\n\t"			 "LH 5,0(%3)\n\t"			 "SRL 5,8\n\t"			 "J .+0 \n\t"	      :	      :	 "a" (OUT_HWCB), "a" (hwc_data.current_hwcb),			 "a" (BUF_HWCB),			 "a" (&(hwc_data.hwcb_count))	      :	 "1", "2", "3", "4", "5");	}#endif	switch (hwcb->response_code) {	case 0x0020:		retval = OUT_HWCB_CHAR;		release_write_hwcb ();		break;	case 0x0040:	case 0x0340:	case 0x40F0:		if (!hwc_data.read_statechange) {			hwcb->response_code = 0;			start_poll_hwc ();		}		retval = -EIO;		break;	default:		internal_print (				       DELAYED_WRITE,				       HWC_RW_PRINT_HEADER				       "write_event_data_2 : "				       "failed operation "				       "(response code: 0x%x "				       "HWCB address: 0x%x).\n",				       hwcb->response_code,				       hwcb);		retval = -EIO;	}	if (retval == -EIO) {		hwcb->control_mask[0] = 0;		hwcb->control_mask[1] = 0;		hwcb->control_mask[2] = 0;		hwcb->response_code = 0;	}	hwc_data.current_servc = 0;	hwc_data.current_hwcb = NULL;	if (hwc_data.flags & HWC_FLUSH)		flush_hwcbs ();	return retval;}static void do_put_line (		    unsigned char *message,		    unsigned short count){	if (add_mto (message, count) != count) {		if (allocate_write_hwcb () < 0)			reuse_write_hwcb ();#ifdef DUMP_HWC_WRITE_LIST_ERROR		if (add_mto (message, count) != count)			__asm__ ("LHI 1,0xe32\n\t"				 "LRA 2,0(%0)\n\t"				 "L 3,0(%1)\n\t"				 "LRA 4,0(%2)\n\t"				 "LRA 5,0(%3)\n\t"				 "J .+0 \n\t"		      :		      :	 "a" (message), "a" (&hwc_data.kmem_pages),				 "a" (BUF_HWCB), "a" (OUT_HWCB)		      :	 "1", "2", "3", "4", "5");#else		add_mto (message, count);#endif	}}static void put_line (		 unsigned char *message,		 unsigned short count){	if ((!hwc_data.obuf_start) && (hwc_data.flags & HWC_WTIMER_RUNS)) {		del_timer (&hwc_data.write_timer);		hwc_data.flags &= ~HWC_WTIMER_RUNS;	}	hwc_data.obuf_start += count;	do_put_line (message, count);	hwc_data.obuf_start -= count;}static void set_alarm (void){	write_hwcb_t *hwcb;	if ((!BUF_HWCB) || (BUF_HWCB == hwc_data.current_hwcb))		allocate_write_hwcb ();	hwcb = (write_hwcb_t *) BUF_HWCB;	hwcb->msgbuf.mdb.mdb_body.go.general_msg_flags |= GMF_SndAlrm;}static void hwc_write_timeout (unsigned long data){	unsigned long flags;	spin_lock_irqsave (&hwc_data.lock, flags);	hwc_data.obuf_start = hwc_data.obuf_count;	if (hwc_data.obuf_count)		put_line (hwc_data.obuf, hwc_data.obuf_count);	hwc_data.obuf_start = 0;	hwc_data.obuf_cursor = 0;	hwc_data.obuf_count = 0;	write_event_data_1 ();	spin_unlock_irqrestore (&hwc_data.lock, flags);}static int do_hwc_write (		     int from_user,		     unsigned char *msg,		     unsigned int count,		     unsigned char write_time){	unsigned int i_msg = 0;	unsigned short int spaces = 0;	unsigned int processed_characters = 0;	unsigned char ch;	unsigned short int obuf_count;	unsigned short int obuf_cursor;	unsigned short int obuf_columns;	if (hwc_data.obuf_start) {		obuf_cursor = 0;		obuf_count = 0;		obuf_columns = MIN (hwc_data.ioctls.columns,				    MAX_MESSAGE_SIZE - hwc_data.obuf_start);	} else {		obuf_cursor = hwc_data.obuf_cursor;		obuf_count = hwc_data.obuf_count;		obuf_columns = hwc_data.ioctls.columns;	}	for (i_msg = 0; i_msg < count; i_msg++) {		if (from_user)			get_user (ch, msg + i_msg);		else			ch = msg[i_msg];		processed_characters++;		if ((obuf_cursor == obuf_columns) &&		    (ch != '\n') &&		    (ch != '\t')) {			put_line (&hwc_data.obuf[hwc_data.obuf_start],				  obuf_columns);			obuf_cursor = 0;			obuf_count = 0;		}		switch (ch) {		case '\n':			put_line (&hwc_data.obuf[hwc_data.obuf_start],				  obuf_count);			obuf_cursor = 0;			obuf_count = 0;			break;		case '\a':			hwc_data.obuf_start += obuf_count;			set_alarm ();			hwc_data.obuf_start -= obuf_count;			break;		case '\t':			do {				if (obuf_cursor < obuf_columns) {					hwc_data.obuf[hwc_data.obuf_start +						      obuf_cursor]					    = HWC_ASCEBC (' ');					obuf_cursor++;				} else					break;			} while (obuf_cursor % hwc_data.ioctls.width_htab);			break;		case '\f':		case '\v':			spaces = obuf_cursor;			put_line (&hwc_data.obuf[hwc_data.obuf_start],				  obuf_count);			obuf_count = obuf_cursor;			while (spaces) {				hwc_data.obuf[hwc_data.obuf_start +					      obuf_cursor - spaces]				    = HWC_ASCEBC (' ');				spaces--;			}			break;		case '\b':			if (obuf_cursor)				obuf_cursor--;			break;		case '\r':			obuf_cursor = 0;			break;		case 0x00:			put_line (&hwc_data.obuf[hwc_data.obuf_start],				  obuf_count);			obuf_cursor = 0;			obuf_count = 0;			goto out;		default:			if (isprint (ch))				hwc_data.obuf[hwc_data.obuf_start +					      obuf_cursor++]				    = HWC_ASCEBC (ch);		}		if (obuf_cursor > obuf_count)			obuf_count = obuf_cursor;	}	if (obuf_cursor) {		if (hwc_data.obuf_start ||		    (hwc_data.ioctls.final_nl == 0)) {			put_line (&hwc_data.obuf[hwc_data.obuf_start],				  obuf_count);			obuf_cursor = 0;			obuf_count = 0;		} else {			if (hwc_data.ioctls.final_nl > 0) {				if (hwc_data.flags & HWC_WTIMER_RUNS) {					mod_timer (&hwc_data.write_timer,						   jiffies + hwc_data.ioctls.final_nl * HZ / 10);				} else {					init_timer (&hwc_data.write_timer);					hwc_data.write_timer.function =					    hwc_write_timeout;					hwc_data.write_timer.data =					    (unsigned long) NULL;					hwc_data.write_timer.expires =					    jiffies +					    hwc_data.ioctls.final_nl * HZ / 10;					add_timer (&hwc_data.write_timer);					hwc_data.flags |= HWC_WTIMER_RUNS;				}			} else;		}	} else;      out:	if (!hwc_data.obuf_start) {		hwc_data.obuf_cursor = obuf_cursor;		hwc_data.obuf_count = obuf_count;	}	if (write_time == IMMEDIATE_WRITE)		write_event_data_1 ();	return processed_characters;}signed int hwc_write (int from_user, const unsigned char *msg, unsigned int count){	unsigned long flags;	int retval;	spin_lock_irqsave (&hwc_data.lock, flags);	retval = do_hwc_write (from_user, (unsigned char *) msg,			       count, IMMEDIATE_WRITE);	spin_unlock_irqrestore (&hwc_data.lock, flags);	return retval;}unsigned int hwc_chars_in_buffer (unsigned char flag){	unsigned short int number = 0;	unsigned long flags;	spin_lock_irqsave (&hwc_data.lock, flags);	if (flag & IN_HWCB)		number += ALL_HWCB_CHAR;	if (flag & IN_WRITE_BUF)		number += hwc_data.obuf_cursor;	spin_unlock_irqrestore (&hwc_data.lock, flags);	return number;}static inline int nr_setbits (kmem_pages_t arg){	int i;	int nr = 0;	for (i = 0; i < (sizeof (arg) << 3); i++) {		if (arg & 1)			nr++;		arg >>= 1;	}	return nr;}unsigned int hwc_write_room (unsigned char flag){	unsigned int number = 0;	unsigned long flags;	write_hwcb_t *hwcb;	spin_lock_irqsave (&hwc_data.lock, flags);	if (flag & IN_HWCB) {		if (BUF_HWCB) {			hwcb = (write_hwcb_t *) BUF_HWCB;			number += MAX_HWCB_ROOM - hwcb->length;		}		number += (hwc_data.ioctls.kmem_hwcb -			   nr_setbits (hwc_data.kmem_pages)) *		    (MAX_HWCB_ROOM -		     (sizeof (write_hwcb_t) + sizeof (mto_t)));	}	if (flag & IN_WRITE_BUF)		number += MAX_HWCB_ROOM - hwc_data.obuf_cursor;	spin_unlock_irqrestore (&hwc_data.lock, flags);	return number;}void hwc_flush_buffer (unsigned char flag){	unsigned long flags;	spin_lock_irqsave (&hwc_data.lock, flags);	if (flag & IN_HWCB) {		if (hwc_data.current_servc != HWC_CMDW_WRITEDATA)			flush_hwcbs ();		else			hwc_data.flags |= HWC_FLUSH;	}	if (flag & IN_WRITE_BUF) {		hwc_data.obuf_cursor = 0;		hwc_data.obuf_count = 0;	}	spin_unlock_irqrestore (&hwc_data.lock, flags);}unsigned short int 

⌨️ 快捷键说明

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