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

📄 hwc_rw.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 3 页
字号:
	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;	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 &= ~FLUSH_HWCBS;}static int write_event_data_2 (void){	write_hwcb_t *hwcb;	int retval;	unsigned char *param;	param = ext_int_param ();	if (param != hwc_data.current_hwcb)		return -EINVAL;	hwcb = (write_hwcb_t *) OUT_HWCB;#ifdef DUMP_HWC_WRITE_ERROR#if 0	if (((unsigned char *) hwcb) != param)		__asm__ ("LHI 1,0xe22\n\t"			 "LRA 2,0(0,%0)\n\t"			 "LRA 3,0(0,%1)\n\t"			 "LRA 4,0(0,%2)\n\t"			 "LRA 5,0(0,%3)\n\t"			 "J .+0 \n\t"	      :	      :	 "a" (OUT_HWCB),			 "a" (hwc_data.current_hwcb),			 "a" (BUF_HWCB),			 "a" (param)	      :	 "1", "2", "3", "4", "5");#endif	if (hwcb->response_code != 0x0020)#if 0		internal_print (DELAYED_WRITE, HWC_RW_PRINT_HEADER		  "\n************************ error in write_event_data_2()\n"				"OUT_HWCB:                    0x%x\n"				"BUF_HWCB:                    0x%x\n"				"response_code:               0x%x\n"				"hwc_data.hwcb_count:        %d\n"				"hwc_data.kmem_pages:        0x%x\n"				"hwc_data.ioctls.kmem_hwcb:   %d\n"				"hwc_data.ioctls.max_hwcb:    %d\n"				"hwc_data.kmem_start:        0x%x\n"				"hwc_data.kmem_end:          0x%x\n"		    "*****************************************************\n",				OUT_HWCB,				BUF_HWCB,				hwcb->response_code,				hwc_data.hwcb_count,				hwc_data.kmem_pages,				hwc_data.ioctls.kmem_hwcb,				hwc_data.ioctls.max_hwcb,				hwc_data.kmem_start,				hwc_data.kmem_end);#endif	__asm__ ("LHI 1,0xe21\n\t"		 "LRA 2,0(0,%0)\n\t"		 "LRA 3,0(0,%1)\n\t"		 "LRA 4,0(0,%2)\n\t"		 "LH 5,0(0,%3)\n\t"		 "SRL 5,8(0)\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	if (hwcb->response_code == 0x0020) {		retval = OUT_HWCB_CHAR;		release_write_hwcb ();	} else		retval = -EIO;	hwc_data.current_servc = 0;	hwc_data.current_hwcb = NULL;	if (hwc_data.flags & FLUSH_HWCBS)		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,%0)\n\t"				 "L 3,0(0,%1)\n\t"				 "LRA 4,0(0,%2)\n\t"				 "LRA 5,0(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_TIMER_RUNS)) {		del_timer (&hwc_data.write_timer);		hwc_data.flags &= ~HWC_TIMER_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 code,		     unsigned char write_time){	unsigned int i_msg = 0;	unsigned short int spaces = 0;	unsigned int processed_characters = 0;	unsigned char ch, orig_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 (orig_ch, msg + i_msg);		else			orig_ch = msg[i_msg];		if (code == CODE_EBCDIC)			ch = _ebcasc[orig_ch];		else			ch = orig_ch;		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]					    = 0x20;					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]				    = 0x20;				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++]				    = (code == CODE_ASCII) ?				    _ascebc[orig_ch] : orig_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_TIMER_RUNS) {					hwc_data.write_timer.expires =					    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_TIMER_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, msg, count, hwc_data.ioctls.code,			       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 |= FLUSH_HWCBS;	}	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 seperate_cases (unsigned char *buf, unsigned short int count){	unsigned short int i_in;	unsigned short int i_out = 0;	unsigned char _case = 0;	for (i_in = 0; i_in < count; i_in++) {		if (buf[i_in] == hwc_data.ioctls.delim) {			if ((i_in + 1 < count) &&			    (buf[i_in + 1] == hwc_data.ioctls.delim)) {				buf[i_out] = hwc_data.ioctls.delim;				i_out++;				i_in++;			} else				_case = ~_case;		} else {			if (_case) {				if (hwc_data.ioctls.tolower)					buf[i_out] = _ebc_toupper[buf[i_in]];				else					buf[i_out] = _ebc_tolower[buf[i_in]];			} else				buf[i_out] = buf[i_in];			i_out++;		}	}	return i_out;}#ifdef DUMP_HWCB_INPUTstatic int gds_vector_name (u16 id, unsigned char name[]){	int retval = 0;	switch (id) {	case GDS_ID_MDSMU:		name = "Multiple Domain Support Message Unit";		break;	case GDS_ID_MDSRouteInfo:		name = "MDS Routing Information";		break;	case GDS_ID_AgUnWrkCorr:		name = "Agent Unit of Work Correlator";		break;	case GDS_ID_SNACondReport:		name = "SNA Condition Report";		break;	case GDS_ID_CPMSU:		name = "CP Management Services Unit";		break;	case GDS_ID_RoutTargInstr:		name = "Routing and Targeting Instructions";		break;	case GDS_ID_OpReq:		name = "Operate Request";		break;	case GDS_ID_TextCmd:		name = "Text Command";		break;	default:		name = "unknown GDS variable";		retval = -EINVAL;	}	return retval;}#endifinline static gds_vector_t *find_gds_vector (			gds_vector_t * start, void *end, u16 id){	gds_vector_t *vec;	gds_vector_t *retval = NULL;	vec = start;	while (((void *) vec) < end) {		if (vec->gds_id == id) {#ifdef DUMP_HWCB_INPUT			int retval_name;			unsigned char name[64];			retval_name = gds_vector_name (id, name);			internal_print (					       DELAYED_WRITE,					       HWC_RW_PRINT_HEADER					  "%s at 0x%x up to 0x%x, length: %d",					       name,					       (unsigned long) vec,				      ((unsigned long) vec) + vec->length - 1,					       vec->length);			if (retval_name < 0)				internal_print (						       IMMEDIATE_WRITE,						       ", id: 0x%x\n",						       vec->gds_id);			else				internal_print (						       IMMEDIATE_WRITE,						       "\n");#endif			retval = vec;			break;		}		vec = (gds_vector_t *) (((unsigned long) vec) + vec->length);	}	return retval;}inline static gds_subvector_t *find_gds_subvector (			   gds_subvector_t * start, void *end, u8 key){	gds_subvector_t *subvec;	gds_subvector_t *retval = NULL;	subvec = start;	while (((void *) subvec) < end) {		if (subvec->key == key) {			retval = subvec;			break;		}		subvec = (gds_subvector_t *)		    (((unsigned long) subvec) + subvec->length);	}	return retval;}inline static int get_input (void *start, void *end){	int count;	count = ((unsigned long) end) - ((unsigned long) start);	if (hwc_data.ioctls.tolower)		EBC_TOLOWER (start, count);	if (hwc_data.ioctls.delim)		count = seperate_cases (start, count);	if (hwc_data.ioctls.echo)		do_hwc_write (0, start, count, CODE_EBCDIC, IMMEDIATE_WRITE);	if (hwc_data.ioctls.code == CODE_ASCII)		EBCASC (start, count);	store_hwc_input (start, count);	return count;}inline static int eval_selfdeftextmsg (gds_subvector_t * start, void *end){	gds_subvector_t *subvec;	void *subvec_data;	void *subvec_end;	int retval = 0;	subvec = start;	while (((void *) subvec) < end) {		subvec = find_gds_subvector (subvec, end, 0x30);		if (!subvec)			break;		subvec_data = (void *)		    (((unsigned long) subvec) +		     sizeof (gds_subvector_t));		subvec_end = (void *)		    (((unsigned long) subvec) + subvec->length);		retval += get_input (subvec_data, subvec_end);		subvec = (gds_subvector_t *) subvec_end;	}	return retval;}inline static int eval_textcmd (gds_subvector_t * start, void *end){	gds_subvector_t *subvec;	gds_subvector_t *subvec_data;	void *subvec_end;

⌨️ 快捷键说明

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