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

📄 vxpci.cpp

📁 devloped under vxwork, support ess sound card. driver library, include datasheet.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	{
		if(	vx_pci_probe_devices( pci_DrvTable, pDev ) < 0 )
		{
			PCI_DEBUG_PRINT( "Error probing pci device\n");
			return ERR0R_GEN_FAIL_vx;
		}
	
		pDev = (pci_dev *)pDev->global_list.next;
	}

	return SUCCESS_vx;

}

/* -------------------------------------------------------
	Function : 	 vx_pci_scan_bus

	Scans the PCI bus to find devices.
	Allocates a pci_dev structure for each device found and
	places in the linked list	
*/
int vx_pci_scan_bus( void )
{
	int deviceNo;
	int devices;
	ushort_t vendorId;
	ushort_t deviceId;
	union
	{
	    int classCode;
    	unsigned char array[4];
	} u;
	int busNo = 0;
	pci_dev *pDev;

	if (pciConfigLibInit (PCI_MECHANISM_1, 0xCF8, 0xCFC, 0) != OK)
	{
    	PCI_DEBUG_PRINT("PCI lib config error\n");
		return (ERR0R_GEN_FAIL_vx);
	}
  
	devices = 0x1f;
    
	PCI_DEBUG_PRINT("Bus #, Device#, vendorID, deviceID, u.classCode\n");
 
	for (deviceNo=0; deviceNo < devices; deviceNo++)
	{
	    pciConfigInWord (busNo, deviceNo, 0, PCI_CFG_VENDOR_ID, &vendorId);
    	pciConfigInWord (busNo, deviceNo, 0, PCI_CFG_DEVICE_ID, &deviceId);
	    pciConfigInByte (busNo, deviceNo, 0, PCI_CFG_PROGRAMMING_IF,
    	         &u.array[3]);
	    pciConfigInByte (busNo, deviceNo, 0, PCI_CFG_SUBCLASS, &u.array[2]);
    	pciConfigInByte (busNo, deviceNo, 0, PCI_CFG_CLASS, &u.array[1]);
	    u.array[0] = 0;
	
    	if (vendorId != 0xffff)
		{	 
			PCI_DEBUG_PRINT ("%.8x  %.8x  %.8x  %.8x  %.8x  %.8x\n",
	                busNo, deviceNo, 0, vendorId, deviceId, u.classCode);
		
			if( ( pDev = vx_pci_find_pci_dev( busNo, deviceNo, 0 ) ) != NULL )
			{
				PCI_DEBUG_PRINT( "device already found on this bus, device #\n" );
			}
			else
			{     		
				if( (pDev = vx_pci_alloc_new_pci_dev( busNo )) == NULL )
				{
					return ERR0R_GEN_FAIL_vx;
				}
			}


			pDev->bus = (pci_bus *) &pci_Bus0Struct;
			pDev->device = deviceId;
			pDev->devfn = PCI_DEVFN( deviceNo, 0 );
			pDev->vendor = vendorId;

		}
		/* fill in the PCI dev structure with the values found on the bus */

	}


	return (SUCCESS_vx);
}


/* -------------------------------------------------------
	Function : 	 vx_pci_probe_id_table_match

	Looks for a match in the pci_device_id null termated table
	specified by a driver funtion.  If a match is found, returns a pointer
	to the table ID entry.
*/
pci_device_id *vx_pci_probe_id_table_match(const pci_device_id *pTableStart, pci_dev *pci )
{
	pci_device_id *pTableEntry;

	pTableEntry = (pci_device_id *)pTableStart;

	while( pTableEntry->device )	/* look for null-terminated end of table */
	{
		if( pTableEntry->device == pci->device &&
			pTableEntry->vendor == pci->vendor )
		{
			return pTableEntry;
		}

		pTableEntry++;	/* go to the next table entry */
	}

	/* no match found in the table */
	return NULL;

}		 

/* -------------------------------------------------------
	Function : 	 vx_pci_probe_devices

	Attempts to match a pci_dev structure with and entry in the 
	passed driver table.  If a match is found, resources are allocated,
	the probe function and driver functions are called.    
*/
static int vx_pci_probe_devices( const pci_driver *pPCIDrvTable[], pci_dev *pci )
{
	pci_driver *pDriverTable;
	pci_device_id *pIDTableEntry;
	int err;
	int index=0;

	pDriverTable = (pci_driver *)pPCIDrvTable[index];	/* get the address of the first table */

	while( pDriverTable )
	{	
		if( ( pIDTableEntry = vx_pci_probe_id_table_match( pDriverTable->id_table, pci ) ) != 0 )
		{
			PCI_DEBUG_PRINT( "Found Matching PCI ID Device %s:\n", pDriverTable->name );

			strcpy( pci->pretty_name, pDriverTable->name );

			if( ( err = pci_enable_device_bars_vx( pci ) < 0 ) ) /* enable bar's for this device */
			{
				PCI_DEBUG_PRINT( "Error %d when configuring pci BAR\n", err );
				return ERR0R_GEN_FAIL_vx;
			}
							
			if( ( err = ( *pDriverTable->probe )( pci, pIDTableEntry ) ) < 0 )
			{
				PCI_DEBUG_PRINT( "Error: probe failed for device with error %d\n", err );
				return ERR0R_GEN_FAIL_vx;

			}
			if ( ( err = ( ( *pDriverTable->vx_start_driver ) ( pci ) )) < 0 )
			{
				PCI_DEBUG_PRINT( "Error: driver start failed for device with error %d\n", err );
				return ERR0R_GEN_FAIL_vx;
			}			  
		}
		pDriverTable =  (pci_driver *)pPCIDrvTable[++index];	// set the next probe table entry
	}

	return SUCCESS_vx;
}
				

/* -------------------------------------------------------
	Function : 	 vx_pci_start

	A command-line function which can be used to start all PCI drivers
*/
			
int vx_pci_start( void )
{
	int err;

	if( ( err = vx_pci_scan_bus() ) < 0 )
	{
		return err;
	}

	return	vx_pci_probe_all_recognized_devices();
}


/* -------------------------------------------------------
	Function : 	 vx_pci_stop

	A command-line function which can be used to stop all PCI drivers
*/

void vx_pci_stop( void )
{
	pci_dev *pDev;
	int	count = 0;		   

	/* re-start the memory allocation from the start of alloc space */
	pci_memAllocRegionStart = PCI_SYSTEM_START_MEM_ALLOC_SPACE;
 	pci_IOAllocRegionStart = PCI_SYSTEM_START_IO_ALLOC_SPACE;

	pDev = pci_pListHeadDev;

	while( pDev )
	{
		vx_pci_remove_pci_dev( pDev );
		pDev = pci_pListHeadDev;
		count++;
	};

	PCI_DEBUG_PRINT( "vx_pci_remove_all_devices: %d devices removed\n",count );
}


/* -------------------------------------------------------
	Function : 	 vx_pci_free_irq

	A function to disconnect the PCI IRQ number passed.  Used
	for un-installing drivers
*/
int vx_pci_free_irq( int irqnum, VOIDFUNCPTR funcptr )
{
	printf("Freeing IRQ %d",irqnum );
	sysIntDisablePIC( irqnum );
	pciIntDisconnect( ( INUM_TO_IVEC ( irqnum+INT_NUM_IRQ0 ) ), funcptr );
	return 0;
}

/* -------------------------------------------------------
	Function : 	 vx_pci_request_irq

	A function to request a PCI IRQ based on the number passed and
	connect it to the passed function.  The param value will be passed
	to the function when the interrupt is serviced.

	Call vx_pci_free_irq to free this IRQ when no longer in use
*/
int vx_pci_request_irq( int irqnum, VOIDFUNCPTR funcptr,  int param )
{
	printf( "Hooking interrupt %d with param 0x%x\n",irqnum,param );

	if( pciIntConnect(( INUM_TO_IVEC ( irqnum+INT_NUM_IRQ0 ) ), funcptr, param ) == OK )	
	{
		printf( "Enabling interrupt %d\n",irqnum );
		if( sysIntEnablePIC(irqnum) == OK )
		{
			return 0;
		}
	}
	return -1;
}
		
/* -------------------------------------------------------
	Function : 	 vx_pci_get_next_dma_mem_space_align

	Allocates a memory space (aligned buffer) of the passed size
	for PCI DMA purposes.  
	
	Free this buffer with free() when no longer in use
*/
void *vx_pci_get_next_dma_mem_space_align( uint32 size )
{
	return valloc( size ); 
}

/* -------------------------------------------------------
	Function : 	 d_vxpci_display

	A debug function which prints out data describing which devices were
	found on the bus
*/
void d_vxpci_display( void )
{
	pci_dev *pDev;
	int device=0;

	pDev = pci_pListHeadDev;
	
	printf("PCI Device List\n#\tName\n");

	while( pDev )
	{
		printf( "%d:", device );

		if( strlen(pDev->pretty_name) )
		{
			printf( " %s\n", pDev->pretty_name );
		}
		else
		{
			printf( " Unknown \n" );
		}

		pDev = (pci_dev *)pDev->global_list.next;
		device++;

	}

	if( device == 0 )
	{
		printf("No devices found\n");
	}

}


/* -------------------------------------------------------
	Function : 	 d_vxpci_set

	A function to set PCI registers for a specific device.  The req_device
	value may be found by calling d_vxpci_display.

*/
int d_vxpci_set( int req_device, int reg, uint32 val, unsigned char numbytes)
{
	int device=0;
	unsigned char byte;
	pci_dev *pDev;
			
	pDev = pci_pListHeadDev;

	while( pDev )
	{
		if( device == req_device )
		{
			break;
		}
		pDev = (pci_dev *)pDev->global_list.next;
		device++;
	}

	if( pDev )
	{
		switch(numbytes)
		{
			case 4:
			pci_write_config_dword( pDev, reg, val );
			break;

			case 2:
			pci_write_config_word( pDev, reg, (uint16)val );
			break;

			default:
			pci_write_config_byte( pDev, reg, (uint8)val );
			break;
		}

		pci_write_config_byte( pDev, reg, val );
		printf("Device %s\n Set Reg: 0x%x = 0x%x\n",pDev->pretty_name, reg, val );
		d_vxpci_get( req_device, reg, numbytes );  
	}
	else
	{
		printf("Error: Unknown device\n");
		printf("Device list:\n");
		d_vxpci_display();
	}

	return 0;
}
	 
/* -------------------------------------------------------
	Function : 	 d_vxpci_get

	A debug function to do a PCI register read for the reqested
	number of bytes.  Returns the register value and prints on the 
	shell.
	For req_device values, use d_vxpci_display
*/
int d_vxpci_get( int req_device, int reg,  unsigned char numbytes )
{
	int device=0;
	uint32	dword;
	uint16	word;
	uint8	byte;
	pci_dev *pDev;
			
	pDev = pci_pListHeadDev;

	while( pDev )
	{
		if( device == req_device )
		{
			break;
		}
		pDev = (pci_dev *)pDev->global_list.next;
		device++;
	}

	if( pDev )
	{
		switch(numbytes)
		{
			case 4:
			pci_read_config_dword( pDev, reg, &dword );
			break;

			case 2:
			pci_read_config_word( pDev, reg, &word );
			dword = word;
			break;

			default:
			pci_read_config_byte( pDev, reg, &byte );
			dword = byte;
			break;
		}

		printf("Device %s\n Read Reg: 0x%x = 0x%x\n",pDev->pretty_name, reg, dword );
	}
	else
	{
		printf("Error: Unknown device\n");
		printf("Device list:\n");
		d_vxpci_display();
	}

	return dword;
}

	

⌨️ 快捷键说明

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