📄 smc37c669.c
字号:
static SMC37c669_DRQ_TRANSLATION_ENTRY *SMC37c669_drq_table __initdata = 0;/*** The following definition is the default DRQ** translation table.*/static SMC37c669_DRQ_TRANSLATION_ENTRY SMC37c669_default_drq_table[]__initdata = { { SMC37c669_DEVICE_DRQ_A, 2 }, { SMC37c669_DEVICE_DRQ_B, 3 }, { SMC37c669_DEVICE_DRQ_C, -1 }, { -1, -1 } /* End of table */ };/*** Local Function Prototype Declarations*/static unsigned int SMC37c669_is_device_enabled( unsigned int func );#if 0static unsigned int SMC37c669_get_device_config( unsigned int func, int *port, int *irq, int *drq );#endifstatic void SMC37c669_config_mode( unsigned int enable );static unsigned char SMC37c669_read_config( unsigned char index );static void SMC37c669_write_config( unsigned char index, unsigned char data );static void SMC37c669_init_local_config( void );static struct DEVICE_CONFIG *SMC37c669_get_config( unsigned int func);static int SMC37c669_xlate_irq( unsigned int irq );static int SMC37c669_xlate_drq( unsigned int drq );#if 0/*** External Data Declarations*/extern struct LOCK spl_atomic;/*** External Function Prototype Declarations*//* From kernel_alpha.mar */extern spinlock( struct LOCK *spl );extern spinunlock( struct LOCK *spl );/* From filesys.c */int allocinode( char *name, int can_create, struct INODE **ipp);extern int null_procedure( void );int smcc669_init( void );int smcc669_open( struct FILE *fp, char *info, char *next, char *mode );int smcc669_read( struct FILE *fp, int size, int number, unsigned char *buf );int smcc669_write( struct FILE *fp, int size, int number, unsigned char *buf );int smcc669_close( struct FILE *fp );struct DDB smc_ddb = { "smc", /* how this routine wants to be called */ smcc669_read, /* read routine */ smcc669_write, /* write routine */ smcc669_open, /* open routine */ smcc669_close, /* close routine */ null_procedure, /* name expansion routine */ null_procedure, /* delete routine */ null_procedure, /* create routine */ null_procedure, /* setmode */ null_procedure, /* validation routine */ 0, /* class specific use */ 1, /* allows information */ 0, /* must be stacked */ 0, /* is a flash update driver */ 0, /* is a block device */ 0, /* not seekable */ 0, /* is an Ethernet device */ 0, /* is a filesystem driver */};#endif#define spinlock(x)#define spinunlock(x)/***++** FUNCTIONAL DESCRIPTION:**** This function detects the presence of an SMC37c669 Super I/O** controller.**** FORMAL PARAMETERS:**** None**** RETURN VALUE:**** Returns a pointer to the device if found, otherwise,** the NULL pointer is returned.**** SIDE EFFECTS:**** None****--*/SMC37c669_CONFIG_REGS * __init SMC37c669_detect( int index ){ int i; SMC37c669_DEVICE_ID_REGISTER id; for ( i = 0; SMC37c669_Addresses[i] != 0; i++ ) {/*** Initialize the device pointer even though we don't yet know if** the controller is at this address. The support functions access** the controller through this device pointer so we need to set it** even when we are looking ...*/ SMC37c669 = ( SMC37c669_CONFIG_REGS * )SMC37c669_Addresses[i];/*** Enter configuration mode*/ SMC37c669_config_mode( TRUE );/*** Read the device id*/ id.as_uchar = SMC37c669_read_config( SMC37c669_DEVICE_ID_INDEX );/*** Exit configuration mode*/ SMC37c669_config_mode( FALSE );/*** Does the device id match? If so, assume we have found an** SMC37c669 controller at this address.*/ if ( id.by_field.device_id == SMC37c669_DEVICE_ID ) {/*** Initialize the IRQ and DRQ translation tables.*/ SMC37c669_irq_table = SMC37c669_irq_tables[ index ]; SMC37c669_drq_table = SMC37c669_default_drq_table;/*** erfix**** If the platform can't use the IRQ and DRQ defaults set up in this ** file, it should call a platform-specific external routine at this ** point to reset the IRQ and DRQ translation table pointers to point ** at the appropriate tables for the platform. If the defaults are ** acceptable, then the external routine should do nothing.*//*** Put the chip back into configuration mode*/ SMC37c669_config_mode( TRUE );/*** Initialize local storage for configuration information*/ SMC37c669_init_local_config( );/*** Exit configuration mode*/ SMC37c669_config_mode( FALSE );/*** SMC37c669 controller found, break out of search loop*/ break; } else {/*** Otherwise, we did not find an SMC37c669 controller at this** address so set the device pointer to NULL.*/ SMC37c669 = NULL; } } return SMC37c669;}/***++** FUNCTIONAL DESCRIPTION:**** This function enables an SMC37c669 device function.**** FORMAL PARAMETERS:**** func:** Which device function to enable**** RETURN VALUE:**** Returns TRUE is the device function was enabled, otherwise, FALSE**** SIDE EFFECTS:**** {@description or none@}**** DESIGN:**** Enabling a device function in the SMC37c669 controller involves** setting all of its mappings (port, irq, drq ...). A local ** "shadow" copy of the device configuration is kept so we can** just set each mapping to what the local copy says.**** This function ALWAYS updates the local shadow configuration of** the device function being enabled, even if the device is always** enabled. To avoid replication of code, functions such as** configure_device set up the local copy and then call this ** function to the update the real device.****--*/unsigned int __init SMC37c669_enable_device ( unsigned int func ){ unsigned int ret_val = FALSE;/*** Put the device into configuration mode*/ SMC37c669_config_mode( TRUE ); switch ( func ) { case SERIAL_0: { SMC37c669_SERIAL_BASE_ADDRESS_REGISTER base_addr; SMC37c669_SERIAL_IRQ_REGISTER irq;/*** Enable the serial 1 IRQ mapping*/ irq.as_uchar = SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX ); irq.by_field.uart1_irq = SMC37c669_RAW_DEVICE_IRQ( SMC37c669_xlate_irq( local_config[ func ].irq ) ); SMC37c669_write_config( SMC37c669_SERIAL_IRQ_INDEX, irq.as_uchar );/*** Enable the serial 1 port base address mapping*/ base_addr.as_uchar = 0; base_addr.by_field.addr9_3 = local_config[ func ].port1 >> 3; SMC37c669_write_config( SMC37c669_SERIAL0_BASE_ADDRESS_INDEX, base_addr.as_uchar ); ret_val = TRUE; break; } case SERIAL_1: { SMC37c669_SERIAL_BASE_ADDRESS_REGISTER base_addr; SMC37c669_SERIAL_IRQ_REGISTER irq;/*** Enable the serial 2 IRQ mapping*/ irq.as_uchar = SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX ); irq.by_field.uart2_irq = SMC37c669_RAW_DEVICE_IRQ( SMC37c669_xlate_irq( local_config[ func ].irq ) ); SMC37c669_write_config( SMC37c669_SERIAL_IRQ_INDEX, irq.as_uchar );/*** Enable the serial 2 port base address mapping*/ base_addr.as_uchar = 0; base_addr.by_field.addr9_3 = local_config[ func ].port1 >> 3; SMC37c669_write_config( SMC37c669_SERIAL1_BASE_ADDRESS_INDEX, base_addr.as_uchar ); ret_val = TRUE; break; } case PARALLEL_0: { SMC37c669_PARALLEL_BASE_ADDRESS_REGISTER base_addr; SMC37c669_PARALLEL_FDC_IRQ_REGISTER irq; SMC37c669_PARALLEL_FDC_DRQ_REGISTER drq;/*** Enable the parallel port DMA channel mapping*/ drq.as_uchar = SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX ); drq.by_field.ppt_drq = SMC37c669_RAW_DEVICE_DRQ( SMC37c669_xlate_drq( local_config[ func ].drq ) ); SMC37c669_write_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX, drq.as_uchar );/*** Enable the parallel port IRQ mapping*/ irq.as_uchar = SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX ); irq.by_field.ppt_irq = SMC37c669_RAW_DEVICE_IRQ( SMC37c669_xlate_irq( local_config[ func ].irq ) ); SMC37c669_write_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX, irq.as_uchar );/*** Enable the parallel port base address mapping*/ base_addr.as_uchar = 0; base_addr.by_field.addr9_2 = local_config[ func ].port1 >> 2; SMC37c669_write_config( SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX, base_addr.as_uchar ); ret_val = TRUE; break; } case FLOPPY_0: { SMC37c669_FDC_BASE_ADDRESS_REGISTER base_addr; SMC37c669_PARALLEL_FDC_IRQ_REGISTER irq; SMC37c669_PARALLEL_FDC_DRQ_REGISTER drq;/*** Enable the floppy controller DMA channel mapping*/ drq.as_uchar = SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX ); drq.by_field.fdc_drq = SMC37c669_RAW_DEVICE_DRQ( SMC37c669_xlate_drq( local_config[ func ].drq ) ); SMC37c669_write_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX, drq.as_uchar );/*** Enable the floppy controller IRQ mapping*/ irq.as_uchar = SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX ); irq.by_field.fdc_irq = SMC37c669_RAW_DEVICE_IRQ( SMC37c669_xlate_irq( local_config[ func ].irq ) ); SMC37c669_write_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX, irq.as_uchar );/*** Enable the floppy controller base address mapping*/ base_addr.as_uchar = 0; base_addr.by_field.addr9_4 = local_config[ func ].port1 >> 4; SMC37c669_write_config( SMC37c669_FDC_BASE_ADDRESS_INDEX, base_addr.as_uchar ); ret_val = TRUE; break; } case IDE_0: { SMC37c669_IDE_ADDRESS_REGISTER ide_addr;/*** Enable the IDE alternate status base address mapping*/ ide_addr.as_uchar = 0; ide_addr.by_field.addr9_4 = local_config[ func ].port2 >> 4; SMC37c669_write_config( SMC37c669_IDE_ALTERNATE_ADDRESS_INDEX, ide_addr.as_uchar );/*** Enable the IDE controller base address mapping*/ ide_addr.as_uchar = 0; ide_addr.by_field.addr9_4 = local_config[ func ].port1 >> 4; SMC37c669_write_config( SMC37c669_IDE_BASE_ADDRESS_INDEX, ide_addr.as_uchar ); ret_val = TRUE; break; } }/*** Exit configuration mode and return*/ SMC37c669_config_mode( FALSE ); return ret_val;}/***++** FUNCTIONAL DESCRIPTION:**** This function disables a device function within the** SMC37c669 Super I/O controller.**** FORMAL PARAMETERS:**** func:** Which function to disable**** RETURN VALUE:**** Return TRUE if the device function was disabled, otherwise, FALSE**** SIDE EFFECTS:**** {@description or none@}**** DESIGN:**** Disabling a function in the SMC37c669 device involves** disabling all the function's mappings (port, irq, drq ...).** A shadow copy of the device configuration is maintained** in local storage so we won't worry aboving saving the** current configuration information.****--*/unsigned int __init SMC37c669_disable_device ( unsigned int func ){ unsigned int ret_val = FALSE;/*** Put the device into configuration mode*/ SMC37c669_config_mode( TRUE ); switch ( func ) { case SERIAL_0: { SMC37c669_SERIAL_BASE_ADDRESS_REGISTER base_addr; SMC37c669_SERIAL_IRQ_REGISTER irq;/*** Disable the serial 1 IRQ mapping*/ irq.as_uchar = SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX ); irq.by_field.uart1_irq = 0; SMC37c669_write_config( SMC37c669_SERIAL_IRQ_INDEX, irq.as_uchar );/*** Disable the serial 1 port base address mapping*/ base_addr.as_uchar = 0; SMC37c669_write_config( SMC37c669_SERIAL0_BASE_ADDRESS_INDEX, base_addr.as_uchar ); ret_val = TRUE; break; } case SERIAL_1: { SMC37c669_SERIAL_BASE_ADDRESS_REGISTER base_addr; SMC37c669_SERIAL_IRQ_REGISTER irq;/*** Disable the serial 2 IRQ mapping*/ irq.as_uchar = SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX ); irq.by_field.uart2_irq = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -