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

📄 mf.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (ev == NULL) {		rc = -ENOMEM;	} else {		union safe_cast mine;		mine.ptr = userToken;		ev->event.hp_lp_event.xSubtype = 4;		ev->event.hp_lp_event.xCorrelationToken = mine.ptr_as_u64;		ev->event.hp_lp_event.x.xSubtypeData =			subtype_data('M', 'F', 'M', 'A');		ev->event.data.alloc.target_lp = targetLp;		ev->event.data.alloc.type = type;		ev->event.data.alloc.size = size;		ev->event.data.alloc.count = count;		ev->hdlr = hdlr;		rc = signal_event(ev);	}	if ((rc != 0) && (hdlr != NULL))		(*hdlr)(userToken, rc);}EXPORT_SYMBOL(mf_allocateLpEvents);/* * Global kernel interface to unseed and deallocate events already in * Hypervisor. */void mf_deallocateLpEvents(HvLpIndex targetLp, HvLpEvent_Type type,		unsigned count, MFCompleteHandler hdlr, void *userToken){	struct pending_event *ev = new_pending_event();	int rc;	if (ev == NULL)		rc = -ENOMEM;	else {		union safe_cast mine;		mine.ptr = userToken;		ev->event.hp_lp_event.xSubtype = 5;		ev->event.hp_lp_event.xCorrelationToken = mine.ptr_as_u64;		ev->event.hp_lp_event.x.xSubtypeData =			subtype_data('M', 'F', 'M', 'D');		ev->event.data.alloc.target_lp = targetLp;		ev->event.data.alloc.type = type;		ev->event.data.alloc.count = count;		ev->hdlr = hdlr;		rc = signal_event(ev);	}	if ((rc != 0) && (hdlr != NULL))		(*hdlr)(userToken, rc);}EXPORT_SYMBOL(mf_deallocateLpEvents);/* * Global kernel interface to tell the VSP object in the primary * partition to power this partition off. */void mf_powerOff(void){	printk(KERN_INFO "mf.c: Down it goes...\n");	signal_ce_msg("\x00\x00\x00\x4D\x00\x00\x00\x00\x00\x00\x00\x00", NULL);	for (;;);}/* * Global kernel interface to tell the VSP object in the primary * partition to reboot this partition. */void mf_reboot(void){	printk(KERN_INFO "mf.c: Preparing to bounce...\n");	signal_ce_msg("\x00\x00\x00\x4E\x00\x00\x00\x00\x00\x00\x00\x00", NULL);	for (;;);}/* * Display a single word SRC onto the VSP control panel. */void mf_displaySrc(u32 word){	u8 ce[12];	memcpy(ce, "\x00\x00\x00\x4A\x00\x00\x00\x01\x00\x00\x00\x00", 12);	ce[8] = word >> 24;	ce[9] = word >> 16;	ce[10] = word >> 8;	ce[11] = word;	signal_ce_msg(ce, NULL);}/* * Display a single word SRC of the form "PROGXXXX" on the VSP control panel. */void mf_displayProgress(u16 value){	u8 ce[12];	u8 src[72];	memcpy(ce, "\x00\x00\x04\x4A\x00\x00\x00\x48\x00\x00\x00\x00", 12);	memcpy(src, "\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"		"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"		"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"		"\x00\x00\x00\x00PROGxxxx                        ",		72);	src[6] = value >> 8;	src[7] = value & 255;	src[44] = "0123456789ABCDEF"[(value >> 12) & 15];	src[45] = "0123456789ABCDEF"[(value >> 8) & 15];	src[46] = "0123456789ABCDEF"[(value >> 4) & 15];	src[47] = "0123456789ABCDEF"[value & 15];	dma_and_signal_ce_msg(ce, NULL, src, sizeof(src), 9 * 64 * 1024);}/* * Clear the VSP control panel.  Used to "erase" an SRC that was * previously displayed. */void mf_clearSrc(void){	signal_ce_msg("\x00\x00\x00\x4B\x00\x00\x00\x00\x00\x00\x00\x00", NULL);}/* * Initialization code here. */void mf_init(void){	int i;	/* initialize */	spin_lock_init(&pending_event_spinlock);	for (i = 0;	     i < sizeof(pending_event_prealloc) / sizeof(*pending_event_prealloc);	     ++i)		free_pending_event(&pending_event_prealloc[i]);	HvLpEvent_registerHandler(HvLpEvent_Type_MachineFac, &hvHandler);	/* virtual continue ack */	signal_ce_msg("\x00\x00\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00", NULL);	/* initialization complete */	printk(KERN_NOTICE "mf.c: iSeries Linux LPAR Machine Facilities initialized\n");}void mf_setSide(char side){	u64 newSide;	struct VspCmdData myVspCmd;	memset(&myVspCmd, 0, sizeof(myVspCmd));	switch (side) {	case 'A':	newSide = 0;			break;	case 'B':	newSide = 1;			break;	case 'C':	newSide = 2; 			break;	default:	newSide = 3;			break;	}	myVspCmd.sub_data.ipl_type = newSide;	myVspCmd.cmd = 10;	(void)signal_vsp_instruction(&myVspCmd);}char mf_getSide(void){	char returnValue = ' ';	int rc = 0;	struct VspCmdData myVspCmd;	memset(&myVspCmd, 0, sizeof(myVspCmd));	myVspCmd.cmd = 2;	myVspCmd.sub_data.ipl_type = 0;	mb();	rc = signal_vsp_instruction(&myVspCmd);	if (rc != 0)		return returnValue;	if (myVspCmd.result_code == 0) {		switch (myVspCmd.sub_data.ipl_type) {		case 0:	returnValue = 'A';			break;		case 1:	returnValue = 'B';			break;		case 2:	returnValue = 'C';			break;		default:	returnValue = 'D';			break;		}	}	return returnValue;}void mf_getSrcHistory(char *buffer, int size){#if 0	struct IplTypeReturnStuff returnStuff;	struct pending_event *ev = new_pending_event();	int rc = 0;	char *pages[4];	pages[0] = kmalloc(4096, GFP_ATOMIC);	pages[1] = kmalloc(4096, GFP_ATOMIC);	pages[2] = kmalloc(4096, GFP_ATOMIC);	pages[3] = kmalloc(4096, GFP_ATOMIC);	if ((ev == NULL) || (pages[0] == NULL) || (pages[1] == NULL)			 || (pages[2] == NULL) || (pages[3] == NULL))		return -ENOMEM;	returnStuff.xType = 0;	returnStuff.xRc = 0;	returnStuff.xDone = 0;	ev->event.hp_lp_event.xSubtype = 6;	ev->event.hp_lp_event.x.xSubtypeData =		subtype_data('M', 'F', 'V', 'I');	ev->event.data.vsp_cmd.xEvent = &returnStuff;	ev->event.data.vsp_cmd.cmd = 4;	ev->event.data.vsp_cmd.lp_index = HvLpConfig_getLpIndex();	ev->event.data.vsp_cmd.result_code = 0xFF;	ev->event.data.vsp_cmd.reserved = 0;	ev->event.data.vsp_cmd.sub_data.page[0] = ISERIES_HV_ADDR(pages[0]);	ev->event.data.vsp_cmd.sub_data.page[1] = ISERIES_HV_ADDR(pages[1]);	ev->event.data.vsp_cmd.sub_data.page[2] = ISERIES_HV_ADDR(pages[2]);	ev->event.data.vsp_cmd.sub_data.page[3] = ISERIES_HV_ADDR(pages[3]);	mb();	if (signal_event(ev) != 0)		return; 	while (returnStuff.xDone != 1) 		udelay(10); 	if (returnStuff.xRc == 0) 		memcpy(buffer, pages[0], size);	kfree(pages[0]);	kfree(pages[1]);	kfree(pages[2]);	kfree(pages[3]);#endif}void mf_setCmdLine(const char *cmdline, int size, u64 side){	struct VspCmdData myVspCmd;	dma_addr_t dma_addr = 0;	char *page = dma_alloc_coherent(iSeries_vio_dev, size, &dma_addr,			GFP_ATOMIC);	if (page == NULL) {		printk(KERN_ERR "mf.c: couldn't allocate memory to set command line\n");		return;	}	copy_from_user(page, cmdline, size);	memset(&myVspCmd, 0, sizeof(myVspCmd));	myVspCmd.cmd = 31;	myVspCmd.sub_data.kern.token = dma_addr;	myVspCmd.sub_data.kern.address_type = HvLpDma_AddressType_TceIndex;	myVspCmd.sub_data.kern.side = side;	myVspCmd.sub_data.kern.length = size;	mb();	(void)signal_vsp_instruction(&myVspCmd);	dma_free_coherent(iSeries_vio_dev, size, page, dma_addr);}int mf_getCmdLine(char *cmdline, int *size, u64 side){	struct VspCmdData myVspCmd;	int rc;	int len = *size;	dma_addr_t dma_addr;	dma_addr = dma_map_single(iSeries_vio_dev, cmdline, len,			DMA_FROM_DEVICE);	memset(cmdline, 0, len);	memset(&myVspCmd, 0, sizeof(myVspCmd));	myVspCmd.cmd = 33;	myVspCmd.sub_data.kern.token = dma_addr;	myVspCmd.sub_data.kern.address_type = HvLpDma_AddressType_TceIndex;	myVspCmd.sub_data.kern.side = side;	myVspCmd.sub_data.kern.length = len;	mb();	rc = signal_vsp_instruction(&myVspCmd);	if (rc == 0) {		if (myVspCmd.result_code == 0)			len = myVspCmd.sub_data.length_out;#if 0		else			memcpy(cmdline, "Bad cmdline", 11);#endif	}	dma_unmap_single(iSeries_vio_dev, dma_addr, *size, DMA_FROM_DEVICE);	return len;}int mf_setVmlinuxChunk(const char *buffer, int size, int offset, u64 side){	struct VspCmdData myVspCmd;	int rc;	dma_addr_t dma_addr = 0;	char *page = dma_alloc_coherent(iSeries_vio_dev, size, &dma_addr,			GFP_ATOMIC);	if (page == NULL) {		printk(KERN_ERR "mf.c: couldn't allocate memory to set vmlinux chunk\n");		return -ENOMEM;	}	copy_from_user(page, buffer, size);	memset(&myVspCmd, 0, sizeof(myVspCmd));	myVspCmd.cmd = 30;	myVspCmd.sub_data.kern.token = dma_addr;	myVspCmd.sub_data.kern.address_type = HvLpDma_AddressType_TceIndex;	myVspCmd.sub_data.kern.side = side;	myVspCmd.sub_data.kern.offset = offset;	myVspCmd.sub_data.kern.length = size;	mb();	rc = signal_vsp_instruction(&myVspCmd);	if (rc == 0) {		if (myVspCmd.result_code == 0)			rc = 0;		else			rc = -ENOMEM;	}	dma_free_coherent(iSeries_vio_dev, size, page, dma_addr);	return rc;}int mf_getVmlinuxChunk(char *buffer, int *size, int offset, u64 side){	struct VspCmdData myVspCmd;	int rc;	int len = *size;	dma_addr_t dma_addr;	dma_addr = dma_map_single(iSeries_vio_dev, buffer, len,			DMA_FROM_DEVICE);	memset(buffer, 0, len);	memset(&myVspCmd, 0, sizeof(myVspCmd));	myVspCmd.cmd = 32;	myVspCmd.sub_data.kern.token = dma_addr;	myVspCmd.sub_data.kern.address_type = HvLpDma_AddressType_TceIndex;	myVspCmd.sub_data.kern.side = side;	myVspCmd.sub_data.kern.offset = offset;	myVspCmd.sub_data.kern.length = len;	mb();	rc = signal_vsp_instruction(&myVspCmd);	if (rc == 0) {		if (myVspCmd.result_code == 0)			*size = myVspCmd.sub_data.length_out;		else			rc = -ENOMEM;	}	dma_unmap_single(iSeries_vio_dev, dma_addr, len, DMA_FROM_DEVICE);	return rc;}int mf_setRtcTime(unsigned long time){	struct rtc_time tm;	to_tm(time, &tm);	return mf_setRtc(&tm);}struct RtcTimeData {	struct completion com;	struct CeMsgData xCeMsg;	int xRc;};void getRtcTimeComplete(void * token, struct CeMsgData *ceMsg){	struct RtcTimeData *rtc = (struct RtcTimeData *)token;	memcpy(&(rtc->xCeMsg), ceMsg, sizeof(rtc->xCeMsg));	rtc->xRc = 0;	complete(&rtc->com);}static unsigned long lastsec = 1;int mf_getRtcTime(unsigned long *time){	u32 dataWord1 = *((u32 *)(&xSpCommArea.xBcdTimeAtIplStart));	u32 dataWord2 = *(((u32 *)&(xSpCommArea.xBcdTimeAtIplStart)) + 1);	int year = 1970;	int year1 = (dataWord1 >> 24) & 0x000000FF;	int year2 = (dataWord1 >> 16) & 0x000000FF;	int sec = (dataWord1 >> 8) & 0x000000FF;	int min = dataWord1 & 0x000000FF;	int hour = (dataWord2 >> 24) & 0x000000FF;	int day = (dataWord2 >> 8) & 0x000000FF;	int mon = dataWord2 & 0x000000FF;	BCD_TO_BIN(sec);	BCD_TO_BIN(min);	BCD_TO_BIN(hour);	BCD_TO_BIN(day);	BCD_TO_BIN(mon);	BCD_TO_BIN(year1);	BCD_TO_BIN(year2);	year = year1 * 100 + year2;	*time = mktime(year, mon, day, hour, min, sec);	*time += (jiffies / HZ);    	/*	 * Now THIS is a nasty hack!	 * It ensures that the first two calls to mf_getRtcTime get different	 * answers.  That way the loop in init_time (time.c) will not think	 * the clock is stuck.	 */	if (lastsec) {		*time -= lastsec;		--lastsec;	}	return 0;}int mf_getRtc(struct rtc_time *tm){	struct CeMsgCompleteData ceComplete;	struct RtcTimeData rtcData;	int rc;	memset(&ceComplete, 0, sizeof(ceComplete));	memset(&rtcData, 0, sizeof(rtcData));	init_completion(&rtcData.com);	ceComplete.handler = &getRtcTimeComplete;	ceComplete.token = (void *)&rtcData;	rc = signal_ce_msg("\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00",			&ceComplete);	if (rc == 0) {		wait_for_completion(&rtcData.com);		if (rtcData.xRc == 0) {			if ((rtcData.xCeMsg.ce_msg[2] == 0xa9) ||			    (rtcData.xCeMsg.ce_msg[2] == 0xaf)) {				/* TOD clock is not set */				tm->tm_sec = 1;				tm->tm_min = 1;				tm->tm_hour = 1;				tm->tm_mday = 10;				tm->tm_mon = 8;				tm->tm_year = 71;				mf_setRtc(tm);			}			{				u32 dataWord1 = *((u32 *)(rtcData.xCeMsg.ce_msg+4));				u32 dataWord2 = *((u32 *)(rtcData.xCeMsg.ce_msg+8));				u8 year = (dataWord1 >> 16) & 0x000000FF;				u8 sec = (dataWord1 >> 8) & 0x000000FF;				u8 min = dataWord1 & 0x000000FF;				u8 hour = (dataWord2 >> 24) & 0x000000FF;				u8 day = (dataWord2 >> 8) & 0x000000FF;				u8 mon = dataWord2 & 0x000000FF;				BCD_TO_BIN(sec);				BCD_TO_BIN(min);				BCD_TO_BIN(hour);				BCD_TO_BIN(day);				BCD_TO_BIN(mon);				BCD_TO_BIN(year);				if (year <= 69)					year += 100;	    				tm->tm_sec = sec;				tm->tm_min = min;				tm->tm_hour = hour;				tm->tm_mday = day;				tm->tm_mon = mon;				tm->tm_year = year;			}		} else {			rc = rtcData.xRc;			tm->tm_sec = 0;			tm->tm_min = 0;			tm->tm_hour = 0;			tm->tm_mday = 15;			tm->tm_mon = 5;			tm->tm_year = 52;		}		tm->tm_wday = 0;		tm->tm_yday = 0;		tm->tm_isdst = 0;	}	return rc;}int mf_setRtc(struct rtc_time * tm){	char ceTime[12] = "\x00\x00\x00\x41\x00\x00\x00\x00\x00\x00\x00\x00";	u8 day, mon, hour, min, sec, y1, y2;	unsigned year;    	year = 1900 + tm->tm_year;	y1 = year / 100;	y2 = year % 100;    	sec = tm->tm_sec;	min = tm->tm_min;	hour = tm->tm_hour;	day = tm->tm_mday;	mon = tm->tm_mon + 1;	    	BIN_TO_BCD(sec);	BIN_TO_BCD(min);	BIN_TO_BCD(hour);	BIN_TO_BCD(mon);	BIN_TO_BCD(day);	BIN_TO_BCD(y1);	BIN_TO_BCD(y2);	ceTime[4] = y1;	ceTime[5] = y2;	ceTime[6] = sec;	ceTime[7] = min;	ceTime[8] = hour;	ceTime[10] = day;	ceTime[11] = mon;   	return signal_ce_msg(ceTime, NULL);}

⌨️ 快捷键说明

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