示例#1
0
STATUS ScsiMonitorIsm::SmTblReply1(void *pClientContext, STATUS status)
{
	SM_TBL_CONTEXT *pTC = (SM_TBL_CONTEXT *)pClientContext;

	TRACE_ENTRY(SmTblReply1);
	
	// if the table exist, do not load dummy values
	if (status != ercOK)
	{
		TRACE_STRING(TRACE_L8, "\n\rSM: DiskDesc table already defined");
	
		status = SmTblReply2(pTC, ercOK);
		return (status);
	}
	
	// Table did not exist, it does now, so load it with default data from
	// the BuildSys.cpp file

	TRACE_STRING(TRACE_L8, "\n\rSM: loading DiskDesc table");
	
	char* pcinewDiskDescRecord = (char*)new(tPCI) 
					char[sizeof(DiskDescriptor) * config.num_drives];

	// fill in the blanks to generate a default table
	DiskDescriptor *pDD = (DiskDescriptor *)pcinewDiskDescRecord;

	for (int i = 0; i < config.num_drives; i++, pDD++)
	{
		memset(pDD, 0, sizeof(DiskDescriptor));
		pDD->version = DISK_DESC_VERSION;
		pDD->size = sizeof(DiskDescriptor);
		pDD->SlotID = i;
		pDD->FCTargetID = config.xlate[i];
		pDD->CurrentStatus = DriveInvalid;
	}
	
	// Create a new InsertRow Object, Initialize it with our parameters
	// and send it off to the the table service.  This will insert
	// the new record initialized above into the DiskDescTable.
	m_pInsertRow = new(tUNCACHED) TSInsertRow;
	
	status = m_pInsertRow->Initialize(
		this,							// Ddm* ClientDdm
		DISK_DESC_TABLE,				// prgbTableName
		pcinewDiskDescRecord,			// prgbRowData
		sizeof(DiskDescriptor)*config.num_drives,		// cbRowData
		&m_RowID1,						// *pRowIDRet
		(pTSCallback_t)&SmTblReply2,	// pTSCallback_t pCallback,
		(void*)pTC						// pContext
	);
	
	if (status == ercOK)
		m_pInsertRow->Send();

	return status;
} // SmTblReply1
示例#2
0
void DdmSSAPIDriver::InitReplyHandler(U32 state, Message *msg) 
{
	
	TRACE_ENTRY(DdmSSAPIDriver::InitReplyHandler());
	static Message* initMsg;

	switch (state) {
	case ssapidriver_WAITING_FOR_INIT:
		TRACE_STRING(5, ("DdmSSAPIDriver::InitReplyHandler - WAITING_FOR_INIT\n")); 
		initMsg = msg;
		break;
	case ssapidriver_INITIALIZED:
		TRACE_STRING(5, ("DdmSSAPIDriver::InitReplyHandler - INITIALIZED\n")); 
		Reply(initMsg, OK);
		break;
	default:
		assert(0);
	}
}
示例#3
0
STATUS DriveMonitorIsm::DM_Create_InstBSAVD(void *pClientContext, STATUS status)
{
	DM_CR_CONTEXT*	pCC = (DM_CR_CONTEXT *)pClientContext;

	TRACE_ENTRY(DM_Create_InstBSAVD);

	if ((status != ercKeyNotFound) && (status != ercEOF) && (status != OK))
		return DM_Create_Bsa_End(pCC, status);
			
	TRACE_STRING(TRACE_L8, "\n\rDM_Create_InstBSAVD: Creating VDT entry");

	RqOsVirtualMasterLoadVirtualDevice *pCreateBsaVDMsg;
	
	// Our failover partner's slot number
	TySlot MyFOP;
	if(config.flags & DM_FLAGS_REDUNDANT)
		MyFOP =  Address::GetFopForIop(Address::iSlotMe);	// DID of secondary DDM.
	else
		MyFOP =  SLOTNULL;									// There is no DID of secondary DDM.
	

	// Alloocate and construct a VirtualMasterLoadVirtualDevice message.
	// Mark the VD with the rowID of the DiskDescriptor that is creating it.
	// TODO: try to find our failover partner's slot number
	pCreateBsaVDMsg = new RqOsVirtualMasterLoadVirtualDevice(
		"HDM_BSA", 									// Class Name of VD.
		Address::iSlotMe,							// Primary Slot.
		MyFOP,										// Secondary Slot
		false,										// fAutoStart
		RowId(m_BSAConfigRec.rid),					// rid of VD's Config Record
		RowId(pCC->pDMState->ridDD)					// Owner unique ID rid
	);

	// Check the pointer and...
	if (!pCreateBsaVDMsg)
		// Set an error if null.
		status = CTS_OUT_OF_MEMORY;
	else
		// Send the message off to the Virtual Master.
		status = Send(
			pCreateBsaVDMsg,
			pCC,										// void* pContext
			REPLYCALLBACK(DriveMonitorIsm, DM_Create_InstBSAVDReply)
		);
	
	// Cleanup in the event of any error.
	if (status != OK)
	{
		CheckFreeAndClear(pCreateBsaVDMsg);
		status = DM_Create_Bsa_End(pCC, status);			
	}
	
	return status;
} // DM_Create_InstBSAVD
示例#4
0
void DdmSSAPIDriver::cmdsenderEventHandler(STATUS eventCode,
										   void* pStatusData)
{

	TRACE_ENTRY(DdmSSAPIDriver::cmdsenderEventHandler());
	switch (eventCode) 
	{
	case AMSTR_EVT_ALARM_SUBMITTED:
		TRACE_STRING(5, ("DdmSSAPIDriver::cmdsenderEventHandler - ALARM SUBMITTED\n")); 
		break;
	case AMSTR_EVT_ALARM_REMITTED:
		TRACE_STRING(5, ("DdmSSAPIDriver::cmdsenderEventHandler - ALARM REMITTED\n")); 
		break;
	case AMSTR_EVT_ALARM_ACKNOWLEDGED:
		TRACE_STRING(5, ("DdmSSAPIDriver::cmdsenderEventHandler - ALARM ACKNOWLEDGED\n")); 
		break;
	case AMSTR_EVT_ALARM_UNACKNOWLEDGED:
		TRACE_STRING(5, ("DdmSSAPIDriver::cmdsenderEventHandler - ALARM UNACKNOWLEDGED\n")); 
		break;
	case AMSTR_EVT_ALARM_NOTIFIED:
		TRACE_STRING(5, ("DdmSSAPIDriver::cmdsenderEventHandler - ALARM NOTIFIED\n")); 
		break;
	case AMSTR_EVT_ALARM_KILLED:
		TRACE_STRING(5, ("DdmSSAPIDriver::cmdsenderEventHandler - ALARM KILLED\n")); 
		break;
	default:
		assert(0);
		break;
	}
}
示例#5
0
void LoopMonitorIsm::LM_Send_DM_SCAN(U32 chip )
{
	TRACE_ENTRY(LM_Send_DM_SCAN);
	
	Message	*pMsg = new Message(DM_SCAN);
	
	Send(LM_Loop_Desc[chip]->vdnDriveMonitor, pMsg, (void *) chip);

	TRACE_STRING(TRACE_L3, "\n\rLoopScan: DM_SCAN message sent");
	
	// this loop is waiting for the DM_SCAN reply now
 	LoopFlags[chip] = LM_STS_LOOP_DM_SCAN_REQ;
	
} // LM_Send_DM_SCAN
示例#6
0
/*! otg_task_exit
 * Terminate and wait for otg task.
 * @param task - otg_task instance pointer
 */
void otg_task_exit(struct otg_task *task)
{
        TRACE_STRING(task->tag, "EXIT: %s", task->name);
        if (task->debug)
                printk(KERN_INFO"%s: %s\n", __FUNCTION__, task->name);

        #if defined(OTG_TASK_WORK)
        while (!task->terminated) {
                otg_sleep( 1 );
        }
        #else /* defined(OTG_TASK_WORK) */
        /* signal termination */
        task->terminate = TRUE;
        otg_up_work(task);
        otg_down_admin(task);

        /* destroy workqueue */
        flush_workqueue(task->work_queue);
        destroy_workqueue(task->work_queue);
        #endif /* defined(OTG_TASK_WORK) */

        LKFREE(task);
}
示例#7
0
void LoopMonitorIsm::LM_Scan_Loops(Message *pMsg)
{
	U32				 loop;
	STATUS			 status;
	U16				 state, type;
	U8				 num_IDs;
	
	TRACE_ENTRY(LM_Scan_Loops);

	TRACE_STRING(TRACE_L2, "\n\rLM: Start Scan");

	// start with no good or bad loops
	
	for (loop = 0; loop < config.num_loops; loop++)
	{
	
		U32		FCinstance = config.FC_instance[loop];
		
		LM_Scan_A_Loop(FCinstance);
		
	}
	
} // LM_Scan_Loops
示例#8
0
STATUS EchoScsiIsm::DoWork(Message *pMsg) {

	TRACE_ENTRY(EchoScsiIsm::DoWork);
	
	STATUS status = Ddm::DoWork(pMsg);
	TRACE_ENTRY(EchoScsiIsm::DoWork Ddm::DoWork);
	
	if (status != OS_DETAIL_STATUS_INAPPROPRIATE_FUNCTION)
		return status;
		
    TRACE_DUMP_HEX(TRACE_L8, "\n\rEchoScsiIsm::DoWork Message",
    					(U8 *)pMsg, 128);

	// New service message
	switch(pMsg->reqCode) {

	case SCSI_SCB_EXEC:
	{
		// Handle the SCSI_SCB_EXECUTE_MESSAGE
		IDLUN				*p_idlun;
		SCB_PAYLOAD			*pP = (SCB_PAYLOAD *)pMsg->GetPPayload();
		
		TRACE_STRING(TRACE_L8, "\n\rEchoScsiIsm::DoWork I2O_SCSI_SCB_EXECUTE_MESSAGE");
		
		TRACE_HEX16(TRACE_L6, "\n\rES MyVd: ", myVd);
		
		// point ot the old LUN and Target Id
		p_idlun = (IDLUN *) &pP->IdLun;
		
		TRACE_HEX16(TRACE_L6, "\n\rES old Id: ", p_idlun->id);
		TRACE_HEX16(TRACE_L6, "\n\rES old LUN: ", p_idlun->LUN);
		
		TRACE_HEX16(TRACE_L6, "\n\rES ID: ", config.ID);
		TRACE_HEX16(TRACE_L6, "\n\rES LUN: ", config.LUN);
		
		// pass the new LUN and Target Id on to the Initiator
		p_idlun->id = config.ID;
		p_idlun->LUN = config.LUN;		// always zero here
		
		// clear the old SCSI-1/2 LUN field since some vendors (IBM)
		// require it to be zero
		pP->CDB[1] &= 0x1f;
		
		// forward on to the SCSI FCP Initiator
		status = Forward(pMsg, config.vdnNext);
		return status;
		
	}
		break;

	case SCSI_DEVICE_RESET:
	case SCSI_SCB_ABORT:
		// no work here for these guys, just forward
		TRACE_HEX16(TRACE_L8, "\n\rEchoScsiIsm::DoWork Other Message", (U16) pMsg->reqCode);
		
		Forward(pMsg, config.vdnNext);
		break;

	default:
		return OS_DETAIL_STATUS_INAPPROPRIATE_FUNCTION;
		}

	// Return success, we have already delivered the message.
	return OS_DETAIL_STATUS_SUCCESS;
	
} // DoWork
示例#9
0
void   task_0(void) {
	unsigned  key = 0;
	unsigned  i,s;
	U16 j; // Module Select Bits
	unsigned  cMsDelay=1;
	unsigned  idx;
	
	TRACE_ENTRY(task_0);
	
	// start on a fresh line
	printf("\n\r");
	
	DrawScreen();
	
	/* Task0 forever loop */
	while(1) {

		//cMsDelay=1;
		
        switch (key = getch()) {
        
        // The first set of commands are general purpose commands
        // for all projects
        case 'X':   /* X - cause address exception and return to boot code */
			printf("Exit with exception\r\n\r\n");
            unsigned long *d = ( unsigned long * ) 0x1;
            *d = 0xFFFF0000;
            break;

        case ' ':  /* SPACEBAR - redraw the screen */
			DrawScreen();
            break;

        case 0x08:  /* BACKSPACE */
        case 0x09:  /* TAB */
        case 0x1B:  /* ESC */
			printf(" \n\r");
        	//printf(" /008");
            break;
            
        case 0x0D:  /* ENTER */
        case 0x0A:  /*  or the real ENTER */
			printf("\n\r");
            break;

#if defined(HSCSI_DEBUG) && defined(_DEBUG)
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
			// Set the Global TraceLevel index to the number specified
			idx = key - 0x30;
debug_set:
			printf("\n\rTraceLevel[%d] = %d",
						index[idx], TraceLevel[index[idx]]);
			break;

        case '!':
			idx = 10;
			goto debug_set;

        case '@':
			idx = 11;
			goto debug_set;

        case '#':
			idx = 12;
			goto debug_set;

		case '+':
			// Increment the Global TraceLevel
			TraceLevel[index[idx]]++;
			printf("\n\rTraceLevel[%d] = %d",
						index[idx], TraceLevel[index[idx]]);
			break;

		case '-':
			// Increment the Global TraceLevel
			TraceLevel[index[idx]]--;
			printf("\n\rTraceLevel[%d] = %d",
						index[idx], TraceLevel[index[idx]]);
			break;
			
		case 'a':
			// Set the Global TraceLevel for all 15 to max
			for (idx = 0; idx < 15; idx++)
			{
				TraceLevel[index[idx]] = TRACE_ALL_LVL;
				printf("\n\rTraceLevel[%d] = %d",
							index[idx], TraceLevel[index[idx]]);
			}
			break;

		case 'm':
			// Set the Global TraceLevel for all 15 to min
			for (idx = 0; idx < 15; idx++)
			{
				TraceLevel[index[idx]] = TRACE_L2;
				printf("\n\rTraceLevel[%d] = %d",
							index[idx], TraceLevel[index[idx]]);
			}
			break;
#endif

		// Oos specific command extensions
        case 'i':
        	TRACE_STRING(TRACE_L2, "\n\rOs:Initialize called\n\r");
			Os::Initialize();
        	break;
        	
        case 'n':
			printf_at(7,0,"Interrupt counters\r\n");
			for (i=Interrupt::tyFirst; i < Interrupt::tyLast; i++) {
				printf("%04x", (int)Interrupt::aN[i]);
				printf(" ");
				}
			break;

        case 'b':
			printf_at(7,0,"Base registers\r\n");
		    Print_Dump((unsigned long*)GT_CPU_CONFIG_REG, 64);
            break;

		case 'd':
			printf_at(7,0,"I2O registers\r\n");
		   	Print_Dump((unsigned long*)(GT_I2O_BASE), 32);
		   	break;
		   	
		case 'D':
			printf_at(7,0,"DMA registers\r\n");
		   	Print_Dump((unsigned long*)(GT_DMA_CH0_COUNT_REG), 32);
		   	break;
		   
		case 'p':
			printf_at(7,0,"PCI registers\r\n");
		   	Print_Dump((unsigned long*)(GT_PCI_COMMAND_REG), 64);
		   	break;

		case 'u':
			printf_at(7,0,"PCI internal registers\r\n");
			for (i=0x80000000; i < 0x80000120; i+= 4) {
		    	if (i % 0x10 == 0) {
				    printf("\n\r");
				   	printf("%04x", i & 0xFF);
				   	}
				printf(" ");
				*(unsigned long*)(GT_PCI_CONFIG_ADDR_REG) = BYTE_SWAP32(i);
				printf("%08x", BYTE_SWAP32(*(unsigned long*)(GT_PCI_CONFIG_DATA_REG)));
			}
						
			break;
			
		case 'U':
			printf_at(7,0,"ISP1040/PCI internal registers\r\n");
			for (i=0x80004000; i < 0x80004100; i+= 4) { // slot 6 = 80003000
		    	if (i % 0x10 == 0) {
				    printf("\n\r");
				   	printf("%04x", i & 0xFF);
				   	}
				printf(" ");
				*(unsigned long*)(GT_PCI_CONFIG_ADDR_REG) = BYTE_SWAP32(i);
//				printf("%08x", BYTE_SWAP32(*(unsigned long*)(GT_PCI_CONFIG_DATA_REG)));
				printf("%04x%04x", (*(unsigned long*)(GT_PCI_CONFIG_DATA_REG)&0xffff),
					(*(unsigned long*)(GT_PCI_CONFIG_DATA_REG)>>16));
			}
			break;


		// FCP specific command extensions
        case 't':
        	extern void S_Test_Unit_Ready(U32 drive_no);
        	S_Test_Unit_Ready(0);
			break;

        case 'y':
        // spare
			break;

#if !defined(NIC_TEST_BUILD)
		case 'h':
			void S_Read_Test(U32 drive_no);
			
			S_Read_Test(0);		// drive 0

			break;

		case 'j':
			void S_Sts_Read_Test(U32 drive_no);
			
			S_Sts_Read_Test(TestVdn);		// Virtual Device 

			break;

        case 's':
        {
        	// defined in the DriveMonitor
			extern void S_Scan_For_Drives(Message *pMsg);
		
			S_Scan_For_Drives(NULL);
			s=1; // keep track of start/stop
		}
			break;
		
		case 'S':
			s=s^0x0001;
			extern void S_Stop_Drive(U32 drive_no, unsigned s);
			S_Stop_Drive(0,s);
			break;
#endif

		case 'r':
			printf_at(7,0,"ISP 1 PCI registers\r\n");
			for (i=0x80004800; i < 0x80004840; i+= 4) {
		    	if (i % 0x10 == 0) {
				    printf("\n\r");
				   	printf("%04x", i & 0xFF);
				   	}
				printf(" ");
				*(unsigned long*)(GT_PCI_CONFIG_ADDR_REG) = BYTE_SWAP32(i);
				printf("%08x", *(unsigned long*)(GT_PCI_CONFIG_DATA_REG));
			}
			break;

		case 'R':
			printf_at(7,0,"ISP 2 PCI registers\r\n");
			for (i=0x80003000; i < 0x80003040; i+= 4) {
		    	if (i % 0x10 == 0) {
				    printf("\n\r");
				   	printf("%04x", i & 0xFF);
				   	}
				printf(" ");
				*(unsigned long*)(GT_PCI_CONFIG_ADDR_REG) = BYTE_SWAP32(i);
				printf("%08x", *(unsigned long*)(GT_PCI_CONFIG_DATA_REG));
			}
			break;

		case 'z':
			printf_at(7,0,"ISP 1 registers\r\n");
			for (i=0; i < 0x100; i+= 2) {
		    	if (i % 0x10 == 0) {
				    printf("\n\r");
				   	printf("%04x", i & 0xFF);
				   	}
				printf(" ");
				printf("%04x", 
					BYTE_SWAP16(*((U16*)((UNSIGNED)(ISP_memory_base_address | 0xA0000000) + i))));
			}
		   	break;

		case 'Z':
			printf_at(7,0,"ISP 2 registers\r\n");
			for (i=0; i < 0x100; i+= 2) {
		    	if (i % 0x10 == 0) {
				    printf("\n\r");
				   	printf("%04x", i & 0xFF);
				   	}
				printf(" ");
				printf("%04x",
					BYTE_SWAP16(*((U16*)((UNSIGNED)(ISP_memory_base_address2 | 0xA0000000) + i))));
			}
		   	break;
		
		case 'H':
			printf_at(7,0,"ISP 3 registers\r\n");
			for (i=0;i<0x100;i+=2) {
				if (i%0x10==0) {
					printf("\n\r");
					printf("%04x",i&0xff);
				}
				printf(" ");
				printf("%04x",BYTE_SWAP16(*((U16*)((UNSIGNED)(ISP_memory_base_address3 | 0xa0000000)+i))));
			}
			break;

		case 'f':
			U16 *ispcs = (U16 *)((ISP_memory_base_address3 | K1BASE)+HSCSI_CONFIG_1);
			U16 *isphccr = (U16 *)((ISP_memory_base_address3 | K1BASE)+HSCSI_HCCR);
			// Clear RISC interrupt (FCP_Mailbox_Wait_Ready_Intr) if needed
			
			*isphccr=BYTE_SWAP16((UNSIGNED)HCCRPAUSERISC); // Pause RISC
			printf_at(7,0,"HSCSI PBIU/RISC registers\r\n");
			j = BYTE_SWAP16(*ispcs)&0x00f7;
										
			*ispcs=BYTE_SWAP16(j); // Set ISP Control/Status register
			for (i=0x00; i<0x100; i+=2) {
				if (!(i % 0x10)) {
					printf("\n\r");
					printf("%04x",i&0xff);
				}
				printf(" ");
				printf("%04x", BYTE_SWAP16(*((U16*)((UNSIGNED)(ISP_memory_base_address3 | K1BASE)+i))));
			}
			printf("\r\n");
			*isphccr=BYTE_SWAP16((UNSIGNED)HCCRRLSRISC); // Unpause RISC
			break;
		case 'F':
			U16 *ispcs2=(U16*)((ISP_memory_base_address3 | K1BASE)+HSCSI_CONFIG_1);
			U16 *isphccr2=(U16*)((ISP_memory_base_address3|K1BASE)+HSCSI_HCCR);
			U16 *sxp=(U16*)((ISP_memory_base_address3|K1BASE)+0xa4);
			
			*isphccr2=BYTE_SWAP16((UNSIGNED)HCCRPAUSERISC); // Pause RISC
			printf_at(7,0,"HSCSI PBIU/SXP registers\r\n");
			j = BYTE_SWAP16(*ispcs2)|0x0008; // SXP select
				
			*ispcs2=BYTE_SWAP16(j); // ISP Config 1 register
//			*sxp = BYTE_SWAP16(0x0c00); // SXP override
			for (i=0x00;i<0x100; i+=2) {
				if (!(i % 0x10)) {
					printf("\n\r");
					printf("%04x",i&0xff);
			    }
			    printf(" ");
			    printf("%04x",BYTE_SWAP16(*((U16*)((UNSIGNED)(ISP_memory_base_address3 | K1BASE)+i))));
			}
			printf("\r\n");
			
			j = j&0x00f7; // SXP select bit off
			*ispcs2=BYTE_SWAP16(j);
			*isphccr2=BYTE_SWAP16((UNSIGNED)HCCRRLSRISC); // Unpause RISC
			break;

        case 'x':
        	// x - cause address exception
        	// and return to boot code			
            unsigned long *g = ( unsigned long * ) 0x1;
            *g = 0xFFFF0000;
            break;

        case 'q':
        	// scan all PCI slots for devices
        	// print only the devices found
        	printf("PCI Devices:\n\r");
        	for (i = 0; i < 31; i++) {
        		U32		reg;
        		
        		reg =  GetPciReg(0, i, 0, 0);
        		if (reg == 0xffffffff)
        			continue;
        		printf("S:%02d = %08x\n\r", i, reg);
        	}
			break;

        default:
        	printf("%c", key);
            break;

         }  /* switch (key = Get_Char()) */

		NU_Sleep(cMsDelay);
		cMsDelay=5;
		}  /* while(1) */
	}
示例#10
0
CCompareTableDialog::CCompareTableDialog(Filename fnOriginal, Filename fnNew)
{
	fnOriginal.SetSuffix("");
	fnNew.SetSuffix("");

	String str;
	str = fnNew.GetString();
	fnNew = Filename(str.SubStr(0, str.GetLength() - 1));

	str = fnOriginal.GetString();
	fnOriginal = Filename(str.SubStr(0, str.GetLength() - 1));

	String strOriginalFileString = fnOriginal.GetFileString();
	String strNewFileString = fnNew.GetFileString();

	Filename fn;

	Bool bOriginalDiag = false, bNewDiag = false;

	fn = fnOriginal.GetDirectory(); // fn contains strings_* or dialogs
	if (fn.GetFileString().LexCompare("dialogs") == 0)
	{
		fn = fn.GetDirectory(); // now, we are in the strings_* path
		bOriginalDiag = true;
	}
	fn = fn.GetDirectory();
	fnOriginal = fn;

	fn = fnNew.GetDirectory(); // fn contains strings_* or dialogs
	if (fn.GetFileString().LexCompare("dialogs") == 0)
	{
		fn = fn.GetDirectory(); // now, we are in the strings_* path
		bNewDiag = true;
	}
	fn = fn.GetDirectory();
	fnNew = fn;

	TRACE_STRING(fnOriginal.GetString());
	TRACE_STRING(fnNew.GetString());

	m_OriginalDoc.LoadGlobalStringTable(fnOriginal, strOriginalFileString);
	m_NewDoc.LoadGlobalStringTable(fnNew, strNewFileString);

	TRACE_STRING(fnNew.GetDirectory().GetFileString());

	m_pOriginalTable = m_OriginalDoc.GetStringTable();
	m_pNewTable = m_NewDoc.GetStringTable();

	if (bOriginalDiag)
		m_fnOriginal = fnOriginal + String("strings_*") + String("dialogs") + (strOriginalFileString + ".str");
	else
		m_fnOriginal = fnOriginal + String("strings_*") + (strOriginalFileString + ".str");

	if (bNewDiag)
		m_fnNew = fnNew + String("strings_*") + String("dialogs") + (strNewFileString + ".str");
	else
		m_fnNew = fnNew + String("strings_*") + (strNewFileString + ".str");

	//TRACE_STRING(m_fnNew.GetString());
	//TRACE_STRING(m_fnOriginal.GetString());

	m_bIsCommandTable = (m_OriginalDoc.m_StringTableType == typeCommandStrings) &&
											(m_NewDoc.m_StringTableType == typeCommandStrings);
}
示例#11
0
STATUS SSD_Ddm::Process_PHS_Request(Message *pMsg)
{
	TRACE_ENTRY(SSD_Ddm::Process_PHS_Request);

	STATUS status;
	U32 cbData;
	U8	*pData;

	FF_STATISTICS flash_statistics;
	status = FF_Get_Statistics(m_flash_handle, &flash_statistics, sizeof(flash_statistics));

	// Check to be sure the flash file system is open.
	if (m_flash_file_system_open == 0)
	{
		Reply(pMsg, I2O_DETAIL_STATUS_DEVICE_NOT_AVAILABLE);
		return OK;
	}

	switch (pMsg->reqCode)
	{
	case PHS_RESET_STATUS:
		TRACE_STRING(TRACE_L8, "\n\rSSD::Process PHS_RESET_STATUS");
		// TODO: send a FF_Stats::Reset_Event_Data to FF_Stats class
		memset(&m_Status, 0, sizeof(SSD_STATUS));

		status = Reply(pMsg, OK);
		break;

	case PHS_RETURN_STATUS:
		TRACE_STRING(TRACE_L8, "\n\rSSD::Process PHS_RETURN_STATUS");

		// Update the Status record
		m_Status.NumReplacementPagesAvailable = flash_statistics.num_replacement_pages_available;
		//m_Status.PercentDirtyPage = CM_STATISTICS::num_pages_dirty;

		pMsg->GetSgl(DDM_REPLY_DATA_SGI, &pData, &cbData);

		memcpy(pData, &m_Status, sizeof(SSD_STATUS));

		status = Reply(pMsg, OK);
		break;

	case PHS_RESET_PERFORMANCE:
		TRACE_STRING(TRACE_L8, "\n\rSSD::Process PHS_RESET_PERFORMANCE");
		// TODO: send a FF_Stats::Reset_Event_Data to FF_Stats class
		memset(&m_Performance, 0, sizeof(SSD_PERFORMANCE));
		
		status = Reply(pMsg, OK);
		break;

	case PHS_RETURN_PERFORMANCE:
		TRACE_STRING(TRACE_L8, "\n\rSSD::Process PHS_RETURN_PERFORMANCE");

		// Update the performance record
		m_Performance.NumPagesRead = flash_statistics.num_page_reads;
		m_Performance.NumPagesReadCacheHit = flash_statistics.num_page_reads_cache_hit;
		m_Performance.NumPagesReadCacheMiss = flash_statistics.num_page_reads_cache_miss;

		m_Performance.NumPagesWrite = flash_statistics.num_page_writes;
		m_Performance.NumPagesWriteCacheHit = flash_statistics.num_page_writes_cache_hit;
		m_Performance.NumPagesWriteCacheMiss = flash_statistics.num_page_writes_cache_miss;

		m_Performance.NumReadBytesTotal = flash_statistics.num_read_bytes_total;
		m_Performance.NumWriteBytesTotal = flash_statistics.num_write_bytes_total;

		pMsg->GetSgl(DDM_REPLY_DATA_SGI, &pData, &cbData);

		memcpy(pData, &m_Status, sizeof(SSD_STATUS));

		status = Reply(pMsg, OK);
		break;

	case PHS_RETURN_RESET_PERFORMANCE:
		TRACE_STRING(TRACE_L8, "\n\rSSD::Process PHS_RETURN_RESET_PERFORMANCE");

		pMsg->GetSgl(DDM_REPLY_DATA_SGI, &pData, &cbData);

		memcpy(pData, &m_Status, sizeof(SSD_STATUS));

		status = Reply(pMsg, OK);

		// TODO: send a FF_Stats::Reset_Event_Data to FF_Stats class
		memset(&m_Performance, 0, sizeof(SSD_PERFORMANCE));
		break;
	} // switch (pMsg->reqCode)

	return status;

} // SSD_Ddm::Process_PHS_Request
示例#12
0
void DdmRAIDMstrTest
::rmstrEventHandler(
			STATUS			eventCode,
			void			*pStatusData)
{
	U32					i=0;
	rowID				dedicatedSpareId;
	rowID				addMemberId;

	TRACEF_NF(TRACE_RMSTR_1,("\nEnter: DdmRAIDMstrTest::rmstrEventHandler\n"));
	RMSTR_EVT_ARRAY_ADDED_STATUS		*pEvtArrayAdded = NULL;
	RMSTR_EVT_ARRAY_DELETED_STATUS		*pEvtArrayDeleted = NULL;
	RMSTR_EVT_SPARE_ADDED_STATUS		*pEvtSpareAdded = NULL;
	RMSTR_EVT_SPARE_DELETED_STATUS		*pEvtSpareDeleted = NULL;
	RMSTR_EVT_UTIL_STARTED_STATUS		*pEvtUtilStarted = NULL;
	RMSTR_EVT_UTIL_STOPPED_STATUS		*pEvtUtilStopped = NULL;
	RMSTR_PRIORITY_CHANGED_STATUS		*pEvtPriorityChanged = NULL;
	RMSTR_PERCENT_COMPLETE_STATUS		*pEvtPercentComplete = NULL;
	RMSTR_EVT_MEMBER_DOWN_STATUS		*pEvtMemberDown = NULL;
	RMSTR_EVT_MEMBER_ADDED_STATUS		*pEvtMemberAdded = NULL;
	RMSTR_EVT_SPARE_ACTIVATED_STATUS	*pEvtSpareActivated = NULL;
	RMSTR_EVT_ARRAY_CRITICAL_STATUS		*pEvtArrayCriticalStatus = NULL;
	RMSTR_EVT_ARRAY_OFFLINE_STATUS		*pEvtArrayOfflineStatus = NULL;
	RMSTR_EVT_PREFERRED_MEMBER_CHANGED_STATUS		*pEvtPreferredMemberChanged = NULL;
	RMSTR_EVT_SOURCE_MEMBER_CHANGED_STATUS			*pEvtSourceMemberChanged = NULL;
	RMSTR_EVT_ARRAY_FAULT_TOLERANT_STATUS			*pEvtArrayFaultTolerant = NULL;

	RAID_UTIL_POLICIES					utilPolicy;
	rowID								tempRowId = {9,0,1};

	UnicodeString				ucNewArrayName;
	StringClass					scNewArrayName;


	TRACE_STRING(TRACE_RMSTR_1, "\t<<<Event Received>>>:\n");
	TRACEF_NF(TRACE_RMSTR_1,("\t\tEvent=%s\n", 
				dispEventName[eventCode]));
	switch(eventCode){
	case RMSTR_EVT_ARRAY_ADDED:
		pEvtArrayAdded = (RMSTR_EVT_ARRAY_ADDED_STATUS *)pStatusData;
		PrintArrayData(&pEvtArrayAdded->arrayData);
		// Display the array name
		ucNewArrayName = UnicodeString(pEvtArrayAdded->arrayName);
		ucNewArrayName.GetAsciiString(scNewArrayName);
		TRACEF_NF(TRACE_RMSTR_1, ("\t\tArrayName=%s\n", scNewArrayName.CString()));
#if 0
		addMemberId.Table = pEvtArrayAdded->arrayData.SRCTRID.Table;
		addMemberId.HiPart = 0;
		addMemberId.LoPart = 4;		// 5 is still free

		// Add a member
		TestAddMember(
			&pEvtArrayAdded->arrayData.thisRID,
			&addMemberId);
#endif

#if 0
		TestChangePreferredMember(
				&pEvtArrayAdded->arrayData.thisRID,
				&pEvtArrayAdded->arrayData.members[1]);
#endif
#if 0
		TestChangeSourceMember(
				&pEvtArrayAdded->arrayData.thisRID,
				&pEvtArrayAdded->arrayData.members[1]);
#endif

#if 1
		// Add a Dedicated Spare
		dedicatedSpareId.Table = pEvtArrayAdded->SRCData.rid.Table;
		dedicatedSpareId.HiPart = 0;
		dedicatedSpareId.LoPart = 5;		// 5 is still free
		TestAddSpare(
			//RAID_HOST_POOL_SPARE,
			//RAID_GENERAL_POOL_SPARE,
			RAID_DEDICATED_SPARE,
			&dedicatedSpareId,
			//NULL,
			&pEvtArrayAdded->arrayData.thisRID,	// target rid
			NULL);
#endif
#if 0
		memset(&utilPolicy,0,sizeof(RAID_UTIL_POLICIES));
		// Start a verify on the Array
		utilPolicy.SilentMode = 1;
		utilPolicy.RunThruErrors = 1;
		utilPolicy.SpecifyMembersToRunOn = 0;
		TestStartUtility(
			&pEvtArrayAdded->arrayData.thisRID,	// target rid
			RAID_UTIL_VERIFY,
			PRIORITY_HIGH,
			utilPolicy,
			5);							// %complete update rate
#endif

#if 0
		// Down a member
		rowID		memberRowId = pEvtArrayAdded->arrayData.members[1];
		TestDownAMember(&pEvtArrayAdded->arrayData.thisRID,&memberRowId);
#endif
		break;

	case RMSTR_EVT_ARRAY_DELETED:
		pEvtArrayDeleted = (RMSTR_EVT_ARRAY_DELETED_STATUS *)pStatusData;
		PrintArrayData(&pEvtArrayDeleted->arrayData);
#if 0
		TestDeleteArray(&pEvtArrayDeleted->arrayData.thisRID);
#endif

		break;


	case RMSTR_EVT_PREFERRED_MEMBER_CHANGED:
		pEvtPreferredMemberChanged = (RMSTR_EVT_PREFERRED_MEMBER_CHANGED_STATUS *)pStatusData;
		PrintArrayData(&pEvtPreferredMemberChanged->arrayData);
		break;

	case RMSTR_EVT_SOURCE_MEMBER_CHANGED:
		pEvtSourceMemberChanged = (RMSTR_EVT_SOURCE_MEMBER_CHANGED_STATUS *)pStatusData;
		PrintArrayData(&pEvtSourceMemberChanged->arrayData);
		break;


	case RMSTR_EVT_UTIL_STARTED:
		pEvtUtilStarted = (RMSTR_EVT_UTIL_STARTED_STATUS *)pStatusData;
		TRACEF_NF(TRACE_RMSTR_1,("\t\tUtil=%s\n", 
				dispUtilityName[pEvtUtilStarted->utilityData.utilityCode]));
		PrintUtilityData(&pEvtUtilStarted->utilityData);

#if 0
		TestDeleteArray(&pEvtUtilStarted->utilityData.targetRID);
#endif

#if 1
		//TestChangePriority(&pEvtUtilStarted->utilityData.thisRID, PRIORITY_LOW);
		TestAbortUtility(&pEvtUtilStarted->utilityData.thisRID);
#endif
		break;

	case RMSTR_EVT_UTIL_STOPPED:
		pEvtUtilStopped = (RMSTR_EVT_UTIL_STOPPED_STATUS *)pStatusData;
		TRACEF_NF(TRACE_RMSTR_1,("\t\tUtil=%s\n", 
				dispUtilityName[pEvtUtilStopped->utilityData.utilityCode]));
		switch(pEvtUtilStopped->reason){
		case RAID_UTIL_ABORTED:
			TRACEF_NF(TRACE_RMSTR_1, ("\t\tUTIL ABORTED BY USER\n"));
			break;
		case RAID_UTIL_ABORTED_IOERROR:
			TRACEF_NF(TRACE_RMSTR_1, ("\t\tUTIL ABORTED IOERROR\n"));
			break;
		case RAID_UTIL_COMPLETE:
			TRACEF_NF(TRACE_RMSTR_1, ("\t\tUTIL COMPLETED\n"));
			break;
		}
		PrintUtilityData(&pEvtUtilStopped->utilityData);
		switch(pEvtUtilStopped->utilityData.utilityCode){
		case RAID_UTIL_VERIFY:
			TRACEF_NF(TRACE_RMSTR_1, ("\t\tUtil Miscompare cnt=%x\n", 
				pEvtUtilStopped->miscompareCount));

			break;
		}
		break;
	

	case RMSTR_EVT_UTIL_PRIORITY_CHANGED:
		pEvtPriorityChanged = (RMSTR_PRIORITY_CHANGED_STATUS *)pStatusData;
		PrintUtilityData(&pEvtPriorityChanged->utilityData);
		TRACEF_NF(TRACE_RMSTR_1, ("\t\tUtil Old priority=%x\n", 
			pEvtPriorityChanged->oldPriority));
		TRACEF_NF(TRACE_RMSTR_1, ("\t\tUtil New priority=%x\n", 
			pEvtPriorityChanged->utilityData.priority));
		break;

	case RMSTR_EVT_UTIL_PERCENT_COMPLETE:
		pEvtPercentComplete = (RMSTR_PERCENT_COMPLETE_STATUS *)pStatusData;
		PrintUtilityData(&pEvtPercentComplete->utilityData);
		TRACEF_NF(TRACE_RMSTR_1, ("\t\tUtil Percent Complete=%x\n", 
			pEvtPercentComplete->percentComplete));
		break;

	case RMSTR_EVT_ARRAY_FAULT_TOLERANT:
		pEvtArrayFaultTolerant = (RMSTR_EVT_ARRAY_FAULT_TOLERANT_STATUS *)pStatusData;
		PrintArrayData(&pEvtArrayFaultTolerant->arrayData);
		break;

	case RMSTR_EVT_SPARE_ADDED:
		pEvtSpareAdded = (RMSTR_EVT_SPARE_ADDED_STATUS *)pStatusData;
		PrintSpareData(&pEvtSpareAdded->spareData);
#if 1
		// Down a member
		rowID		memberRowId;
		memberRowId.Table = 0xe;
		memberRowId.HiPart = 0;
		memberRowId.LoPart = 1;
		TestDownAMember(&pEvtSpareAdded->spareData.arrayRID,&memberRowId);
#endif
#if 0
		addMemberId.Table = pEvtSpareAdded->spareData.SRCTRID.Table;
		addMemberId.HiPart = 0;
		addMemberId.LoPart = 4;		// 5 is still free

		// Add a member
		TestAddMember(
			&pEvtSpareAdded->spareData.arrayRID,
			&addMemberId);
#endif

#if 0
		TestDeleteSpare(&pEvtSpareAdded->spareData.thisRID);
#endif
		break;
	
	case RMSTR_EVT_MEMBER_DOWN:
		pEvtMemberDown = (RMSTR_EVT_MEMBER_DOWN_STATUS *)pStatusData;
		PrintMemberData(&pEvtMemberDown->memberData);
#if 0
		// Add a Dedicated Spare
		dedicatedSpareId.Table = pEvtMemberDown->memberData.memberRID.Table;
		dedicatedSpareId.HiPart = 0;
		dedicatedSpareId.LoPart = 5;		// 5 is still free
		TestAddSpare(
			//RAID_HOST_POOL_SPARE,
			RAID_GENERAL_POOL_SPARE,
			//RAID_DEDICATED_SPARE,
			&dedicatedSpareId,
			NULL,
			//&pEvtMemberDown->memberData.arrayRID,	// target rid
			NULL);
#endif

		break;

	case RMSTR_EVT_MEMBER_ADDED:
		pEvtMemberAdded = (RMSTR_EVT_MEMBER_ADDED_STATUS *)pStatusData;
		PrintMemberData(&pEvtMemberAdded->memberData);
		break;

	case RMSTR_EVT_SPARE_ACTIVATED:
		pEvtSpareActivated = (RMSTR_EVT_SPARE_ACTIVATED_STATUS *)pStatusData;
		PrintSpareData(&pEvtSpareActivated->spareData);
#if 0
		memset(&utilPolicy,0,sizeof(RAID_UTIL_POLICIES));
		// Start a regenerate on the Array
		utilPolicy.SilentMode = 1;
		utilPolicy.RunThruErrors = 1;
		utilPolicy.SpecifyMembersToRunOn = 0;
		TestStartUtility(
			&pEvtSpareActivated->spareData.arrayRID,	// target rid
			RAID_UTIL_REGENERATE,
			PRIORITY_HIGH,
			utilPolicy,
			15);				// %complete update rate
#endif
#if 0
		// Add a Dedicated Spare
		dedicatedSpareId.Table = pEvtSpareActivated->spareData.SRCTRID.Table;
		dedicatedSpareId.HiPart = 0;
		dedicatedSpareId.LoPart = 5;		// 5 is still free
		TestAddSpare(
			//RAID_HOST_POOL_SPARE,
			//RAID_GENERAL_POOL_SPARE,
			RAID_DEDICATED_SPARE,
			&dedicatedSpareId,
			//NULL,
			&pEvtSpareActivated->spareData.arrayRID,	// target rid
			NULL);
#endif
		break;

	case RMSTR_EVT_SPARE_DELETED:	
		pEvtSpareDeleted = (RMSTR_EVT_SPARE_DELETED_STATUS *)pStatusData;
		PrintSpareData(&pEvtSpareDeleted->spareData);
#if 0
		TestDeleteArray(&pEvtSpareDeleted->spareData.arrayRID);
#endif
#if 0
		TestDeleteSpare(&pEvtSpareDeleted->spareData.thisRID);
#endif
		break;

	case RMSTR_EVT_ARRAY_CRITICAL:
		pEvtArrayCriticalStatus = (RMSTR_EVT_ARRAY_CRITICAL_STATUS *)pStatusData;
		PrintArrayData(&pEvtArrayCriticalStatus->arrayData);
		break;

	case RMSTR_EVT_ARRAY_OFFLINE:
		pEvtArrayOfflineStatus = (RMSTR_EVT_ARRAY_OFFLINE_STATUS *)pStatusData;
		PrintArrayData(&pEvtArrayOfflineStatus->arrayData);
		break;
	}
}
示例#13
0
//**************************************************************************
//
//	Command Completion Reply
//
//**************************************************************************
void DdmRAIDMstrTest
::rmstrCommandCompletionReply(
			STATUS				completionCode,
			void				*pStatusData,
			void				*pCmdData,
			void				*pCmdContext)
{
	UnicodeString				ucNewArrayName;
	StringClass					scNewArrayName;

	TRACE_STRING(TRACE_RMSTR_1, "\nEnter: DdmRAIDMstrTest::rmstrCommandCompletionReply\n");
	RMSTR_CMND_INFO *pInfo = (RMSTR_CMND_INFO *)pCmdData;
	RMSTR_CMND_PARAMETERS *pParams = &pInfo->cmdParams;
	RMSTR_CREATE_ARRAY_DEFINITION *pArrayDef = 
			(RMSTR_CREATE_ARRAY_DEFINITION *)&pParams->createArrayDefinition;
	RMSTR_DELETE_ARRAY_INFO *pDeleteArrayInfo = 
			(RMSTR_DELETE_ARRAY_INFO *)&pParams->deleteArrayInfo;

	RMSTR_START_UTIL_INFO		*pStartUtilInfo =
			(RMSTR_START_UTIL_INFO *)&pParams->startUtilInfo;
	RMSTR_ABORT_UTIL_INFO		*pAbortUtilInfo =
			(RMSTR_ABORT_UTIL_INFO *)&pParams->abortUtilInfo;
	RMSTR_CHANGE_PRIORITY_INFO		*pChangePriorityInfo =
			(RMSTR_CHANGE_PRIORITY_INFO *)&pParams->changePriorityInfo;


	TRACE_STRING(TRACE_RMSTR_1, "\t***Cmd Submitted***:\n");
	TRACEF_NF(TRACE_RMSTR_1,("\t\tCmd=%s\n", 
				dispCommandName[pInfo->opcode]));

	CONTEXT	*pContext = (CONTEXT *)pCmdContext;
	U32		x;
	switch(completionCode){
	case RMSTR_SUCCESS:
		switch (pInfo->opcode){
		case RMSTR_CMND_CREATE_ARRAY:
#if 0
			ucNewArrayName = UnicodeString(pArrayDef->arrayName);
			ucNewArrayName.GetAsciiString(scNewArrayName);
			TRACEF_NF(TRACE_RMSTR_1, ("\t\tArrayName=%s\n", scNewArrayName.CString()));
#endif
			break;

		case RMSTR_CMND_DELETE_ARRAY:
			//TRACEF_NF(TRACE_RMSTR_1, ("\t\t", pDeleteArrayInfo->arrayRowId));
			break;


		case RMSTR_CMND_CREATE_SPARE:
			x = pContext->value;
			break;

		case RMSTR_CMND_DELETE_SPARE:
			break;

		case RMSTR_CMND_START_UTIL:
			TRACEF_NF(TRACE_RMSTR_1,("\t\tUtil=%s\n", 
				dispUtilityName[pStartUtilInfo->utilityName]));
			break;

		case RMSTR_CMND_ABORT_UTIL:
			TRACEF_NF(TRACE_RMSTR_1,("\t\tUtil Abort Cmd Reply\n"));
			break;

		case RMSTR_CMND_CHANGE_UTIL_PRIORITY:
			TRACEF_NF(TRACE_RMSTR_1,("\t\tChange Priority Cmd Reply\n"));
			break;

		case RMSTR_CMND_ADD_MEMBER:
			TRACEF_NF(TRACE_RMSTR_1,("\t\tAdd Members Cmd Reply\n"));
			break;

		case RMSTR_CMND_CHANGE_PREFERRED_MEMBER:
			TRACEF_NF(TRACE_RMSTR_1,("\t\tChange Preferred Member Cmd Reply\n"));
			break;

		case RMSTR_CMND_CHANGE_SOURCE_MEMBER:
			TRACEF_NF(TRACE_RMSTR_1,("\t\tChange Source Member Cmd Reply\n"));
			break;

		default:
			TRACEF_NF(TRACE_RMSTR_1,("\tERROR: Unknown Cmd: Opcode=0x%x\n", pInfo->opcode));
			break;
		}
		break;
	default:
		TRACEF_NF(TRACE_RMSTR_1,("\t\tErrorCode=%s\n", 
				dispErrorName[completionCode]));
		break;
	}
	if (pContext){
		delete pContext;
		pContext = NULL;
	}
}
示例#14
0
void ShaderGen2D_CreateShader2D(ShaderGen2D *gen, int index, DWORD id)
{
    STRING tmp;
    DWORD rop;
    tmp.ptr = NULL;
    BOOL intproc = FALSE;
    BOOL usedest = FALSE;
    gen->genshaders2D[index].shader.vsrc.ptr = NULL;
    gen->genshaders2D[index].shader.fsrc.ptr = NULL;
    char idstring[22];
    _snprintf(idstring, 21, "%0.8I32X\n", id);
    idstring[21] = 0;
    // Create vertex shader
    // Header
    STRING *vsrc = &gen->genshaders2D[index].shader.vsrc;
    String_Append(vsrc, revheader);
    if (id & DDBLT_ROP)
    {
        rop = UnpackROPBits(id);
        if (gen->ext->glver_major >= 3)
        {
            String_Append(vsrc, version_130);
            intproc = TRUE;
        }
        else if (gen->ext->GLEXT_EXT_gpu_shader4)
        {
            String_Append(vsrc, version_110);
            String_Append(vsrc, ext_shader4);
            intproc = TRUE;
        }
        else String_Append(vsrc, version_110);
    }
    else String_Append(vsrc, version_110);
    String_Append(vsrc, idheader);
    String_Append(vsrc, idstring);

    // Attributes
    String_Append(vsrc, attr_xy);
    if (!(id & DDBLT_COLORFILL)) String_Append(vsrc, attr_srcst);
    if (id & DDBLT_ROP)
    {
        if (rop_texture_usage[rop] & 2) usedest = TRUE;
    }
    if (id & DDBLT_KEYDEST) usedest = TRUE;
    if (usedest) String_Append(vsrc, attr_destst);
    if (id & 0x10000000) String_Append(vsrc, attr_stencilst);

    // Uniforms
    String_Append(vsrc, unif_view);

    // Main
    String_Append(vsrc, mainstart);
    String_Append(vsrc, op_vertex);
    if (!(id & DDBLT_COLORFILL)) String_Append(vsrc, op_texcoord0);
    if(usedest) String_Append(vsrc, op_texcoord1);
    if (id & 0x10000000) String_Append(vsrc, op_texcoord3);
    String_Append(vsrc, mainend);
#ifdef _DEBUG
    OutputDebugStringA("2D blitter vertex shader:\n");
    OutputDebugStringA(vsrc->ptr);
    OutputDebugStringA("\nCompiling 2D blitter vertex shader:\n");
    TRACE_STRING("2D blitter vertex shader:\n");
    TRACE_STRING(vsrc->ptr);
    TRACE_STRING("\nCompiling 2D blitter vertex shader:\n");
#endif
    gen->genshaders2D[index].shader.vs = gen->ext->glCreateShader(GL_VERTEX_SHADER);
    GLint srclen = strlen(vsrc->ptr);
    gen->ext->glShaderSource(gen->genshaders2D[index].shader.vs, 1, &vsrc->ptr, &srclen);
    gen->ext->glCompileShader(gen->genshaders2D[index].shader.vs);
    GLint result;
    char *infolog = NULL;
    gen->ext->glGetShaderiv(gen->genshaders2D[index].shader.vs, GL_COMPILE_STATUS, &result);
#ifdef _DEBUG
    GLint loglen;
    if (!result)
    {
        gen->ext->glGetShaderiv(gen->genshaders2D[index].shader.vs, GL_INFO_LOG_LENGTH, &loglen);
        infolog = (char*)malloc(loglen);
        gen->ext->glGetShaderInfoLog(gen->genshaders2D[index].shader.vs, loglen, &result, infolog);
        OutputDebugStringA("Compilation failed. Error messages:\n");
        OutputDebugStringA(infolog);
        TRACE_STRING("Compilation failed. Error messages:\n");
        TRACE_STRING(infolog);
        free(infolog);
    }
#endif
    usedest = FALSE;
    // Create fragment shader
    STRING *fsrc = &gen->genshaders2D[index].shader.fsrc;
    String_Append(fsrc, revheader);
    if (id & DDBLT_ROP)
    {
        if (gen->ext->glver_major >= 3)
        {
            String_Append(fsrc, version_130);
            intproc = true;
        }
        else if (gen->ext->GLEXT_EXT_gpu_shader4)
        {
            String_Append(fsrc, version_110);
            String_Append(fsrc, ext_shader4);
            intproc = true;
        }
        else String_Append(fsrc, version_110);
    }
    else String_Append(fsrc, version_110);
    String_Append(fsrc, idheader);
    String_Append(fsrc, idstring);

    // Uniforms
    if (id & DDBLT_COLORFILL) String_Append(fsrc, unif_fillcolor);
    else String_Append(fsrc, unif_srctex);
    if (id & DDBLT_KEYDEST) usedest = TRUE;
    if (id & DDBLT_ROP)
    {
        if (rop_texture_usage[rop] & 2) usedest = TRUE;
        if (rop_texture_usage[rop] & 4)
        {
            String_Append(fsrc, unif_patterntex);
            String_Append(fsrc, unif_patternsize);
        }
    }
    if (usedest) String_Append(fsrc, unif_desttex);
    if (id & 0x10000000) String_Append(fsrc, unif_stenciltex);
    if (id & DDBLT_KEYSRC)
    {
        String_Append(fsrc, unif_ckeysrc);
        if (id & 0x20000000) String_Append(fsrc, unif_ckeysrchigh);
        String_Append(fsrc, unif_colorsizesrc);
    }
    String_Append(fsrc, unif_colorsizedest);
    if (id & DDBLT_KEYDEST)
    {
        String_Append(fsrc, unif_ckeydest);
        if (id & 0x40000000) String_Append(fsrc, unif_ckeydesthigh);
    }

    // Variables
    String_Append(fsrc, var_pixel);
    if (id & DDBLT_KEYSRC) String_Append(fsrc, var_src);
    if (id & DDBLT_ROP)
    {
        if (rop_texture_usage[rop] & 4)
        {
            String_Append(fsrc, var_pattern);
            String_Append(fsrc, var_patternst);
        }
    }
    if (usedest) String_Append(fsrc, var_dest);

    // Main
    String_Append(fsrc, mainstart);
    if (id & 0x10000000) String_Append(fsrc, op_clip);
    if (id & DDBLT_COLORFILL) String_Append(fsrc, op_color);
    else String_Append(fsrc, op_pixel);
    if (id & DDBLT_KEYSRC) String_Append(fsrc, op_src);
    if (usedest) String_Append(fsrc, op_dest);
    if (id & DDBLT_KEYSRC)
    {
        if (id & 0x20000000) String_Append(fsrc, op_ckeysrcrange);
        else String_Append(fsrc, op_ckeysrc);
    }
    if (id & DDBLT_KEYDEST)
    {
        if (id & 0x40000000) String_Append(fsrc, op_ckeydestrange);
        else String_Append(fsrc, op_ckeydest);
    }
    if (id & DDBLT_ROP)
    {
        if (rop_texture_usage[rop] & 4) String_Append(fsrc, op_pattern);
        if (intproc) String_Append(fsrc, op_ROP[rop]);
        else String_Append(fsrc, op_ROP_float[rop]);
    }

    String_Append(fsrc, op_destout);
    String_Append(fsrc, mainend);
#ifdef _DEBUG
    OutputDebugStringA("2D blitter fragment shader:\n");
    OutputDebugStringA(fsrc->ptr);
    OutputDebugStringA("\nCompiling 2D blitter fragment shader:\n");
    TRACE_STRING("2D blitter fragment shader:\n");
    TRACE_STRING(fsrc->ptr);
    TRACE_STRING("\nCompiling 2D blitter fragment shader:\n");
#endif
    gen->genshaders2D[index].shader.fs = gen->ext->glCreateShader(GL_FRAGMENT_SHADER);
    srclen = strlen(fsrc->ptr);
    gen->ext->glShaderSource(gen->genshaders2D[index].shader.fs, 1, &fsrc->ptr, &srclen);
    gen->ext->glCompileShader(gen->genshaders2D[index].shader.fs);
    gen->ext->glGetShaderiv(gen->genshaders2D[index].shader.fs, GL_COMPILE_STATUS, &result);
#ifdef _DEBUG
    if (!result)
    {
        gen->ext->glGetShaderiv(gen->genshaders2D[index].shader.fs, GL_INFO_LOG_LENGTH, &loglen);
        infolog = (char*)malloc(loglen);
        gen->ext->glGetShaderInfoLog(gen->genshaders2D[index].shader.fs, loglen, &result, infolog);
        OutputDebugStringA("Compilation failed. Error messages:\n");
        OutputDebugStringA(infolog);
        TRACE_STRING("Compilation failed. Error messages:\n");
        TRACE_STRING(infolog);
        free(infolog);
    }
#endif
    gen->genshaders2D[index].shader.prog = gen->ext->glCreateProgram();
    gen->ext->glAttachShader(gen->genshaders2D[index].shader.prog, gen->genshaders2D[index].shader.vs);
    gen->ext->glAttachShader(gen->genshaders2D[index].shader.prog, gen->genshaders2D[index].shader.fs);
    gen->ext->glLinkProgram(gen->genshaders2D[index].shader.prog);
    gen->ext->glGetProgramiv(gen->genshaders2D[index].shader.prog, GL_LINK_STATUS, &result);
#ifdef _DEBUG
    if (!result)
    {
        gen->ext->glGetProgramiv(gen->genshaders2D[index].shader.prog, GL_INFO_LOG_LENGTH, &loglen);
        infolog = (char*)malloc(loglen);
        gen->ext->glGetProgramInfoLog(gen->genshaders2D[index].shader.prog, loglen, &result, infolog);
        OutputDebugStringA("Program link failed. Error messages:\n");
        OutputDebugStringA(infolog);
        TRACE_STRING("Program link failed. Error messages:\n");
        TRACE_STRING(infolog);
        free(infolog);
    }
#endif
    gen->genshaders2D[index].shader.attribs[0] = gen->ext->glGetAttribLocation(gen->genshaders2D[index].shader.prog, "xy");
    gen->genshaders2D[index].shader.attribs[1] = gen->ext->glGetAttribLocation(gen->genshaders2D[index].shader.prog, "rgb");
    gen->genshaders2D[index].shader.attribs[2] = gen->ext->glGetAttribLocation(gen->genshaders2D[index].shader.prog, "rgba");
    gen->genshaders2D[index].shader.attribs[3] = gen->ext->glGetAttribLocation(gen->genshaders2D[index].shader.prog, "srcst");
    gen->genshaders2D[index].shader.attribs[4] = gen->ext->glGetAttribLocation(gen->genshaders2D[index].shader.prog, "destst");
    gen->genshaders2D[index].shader.attribs[5] = gen->ext->glGetAttribLocation(gen->genshaders2D[index].shader.prog, "stencilst");
    gen->genshaders2D[index].shader.uniforms[0] = gen->ext->glGetUniformLocation(gen->genshaders2D[index].shader.prog, "view");
    gen->genshaders2D[index].shader.uniforms[1] = gen->ext->glGetUniformLocation(gen->genshaders2D[index].shader.prog, "srctex");
    gen->genshaders2D[index].shader.uniforms[2] = gen->ext->glGetUniformLocation(gen->genshaders2D[index].shader.prog, "desttex");
    gen->genshaders2D[index].shader.uniforms[3] = gen->ext->glGetUniformLocation(gen->genshaders2D[index].shader.prog, "patterntex");
    gen->genshaders2D[index].shader.uniforms[4] = gen->ext->glGetUniformLocation(gen->genshaders2D[index].shader.prog, "stenciltex");
    gen->genshaders2D[index].shader.uniforms[5] = gen->ext->glGetUniformLocation(gen->genshaders2D[index].shader.prog, "ckeysrc");
    gen->genshaders2D[index].shader.uniforms[6] = gen->ext->glGetUniformLocation(gen->genshaders2D[index].shader.prog, "ckeydest");
    gen->genshaders2D[index].shader.uniforms[7] = gen->ext->glGetUniformLocation(gen->genshaders2D[index].shader.prog, "ckeysrchigh");
    gen->genshaders2D[index].shader.uniforms[8] = gen->ext->glGetUniformLocation(gen->genshaders2D[index].shader.prog, "ckeydesthigh");
    gen->genshaders2D[index].shader.uniforms[9] = gen->ext->glGetUniformLocation(gen->genshaders2D[index].shader.prog, "patternsize");
    gen->genshaders2D[index].shader.uniforms[10] = gen->ext->glGetUniformLocation(gen->genshaders2D[index].shader.prog, "colorsizesrc");
    gen->genshaders2D[index].shader.uniforms[11] = gen->ext->glGetUniformLocation(gen->genshaders2D[index].shader.prog, "colorsizedest");
    gen->genshaders2D[index].shader.uniforms[12] = gen->ext->glGetUniformLocation(gen->genshaders2D[index].shader.prog, "fillcolor");

    gen->genshaders2D[index].id = id;
}