📄 smc37c669.c
字号:
SMC37c669_write_config( SMC37c669_SERIAL_IRQ_INDEX, irq.as_uchar );/*** Disable the serial 2 port base address mapping*/ base_addr.as_uchar = 0; 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;/*** Disable the parallel port DMA channel mapping*/ drq.as_uchar = SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX ); drq.by_field.ppt_drq = 0; SMC37c669_write_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX, drq.as_uchar );/*** Disable the parallel port IRQ mapping*/ irq.as_uchar = SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX ); irq.by_field.ppt_irq = 0; SMC37c669_write_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX, irq.as_uchar );/*** Disable the parallel port base address mapping*/ base_addr.as_uchar = 0; 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;/*** Disable the floppy controller DMA channel mapping*/ drq.as_uchar = SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX ); drq.by_field.fdc_drq = 0; SMC37c669_write_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX, drq.as_uchar );/*** Disable the floppy controller IRQ mapping*/ irq.as_uchar = SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX ); irq.by_field.fdc_irq = 0; SMC37c669_write_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX, irq.as_uchar );/*** Disable the floppy controller base address mapping*/ base_addr.as_uchar = 0; 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;/*** Disable the IDE alternate status base address mapping*/ ide_addr.as_uchar = 0; SMC37c669_write_config( SMC37c669_IDE_ALTERNATE_ADDRESS_INDEX, ide_addr.as_uchar );/*** Disable the IDE controller base address mapping*/ ide_addr.as_uchar = 0; 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 configures a device function within the ** SMC37c669 Super I/O controller.**** FORMAL PARAMETERS:**** func:** Which device function** ** port:** I/O port for the function to use** ** irq:** IRQ for the device function to use** ** drq:** DMA channel for the device function to use**** RETURN VALUE:**** Returns TRUE if the device function was configured, ** otherwise, FALSE.**** SIDE EFFECTS:**** {@description or none@}**** DESIGN:**** If this function returns TRUE, the local shadow copy of** the configuration is also updated. If the device function** is currently disabled, only the local shadow copy is ** updated and the actual device function will be updated** if/when it is enabled.****--*/unsigned int __init SMC37c669_configure_device ( unsigned int func, int port, int irq, int drq ){ struct DEVICE_CONFIG *cp;/*** Check for a valid configuration*/ if ( ( cp = SMC37c669_get_config ( func ) ) != NULL ) {/*** Configuration is valid, update the local shadow copy*/ if ( ( drq & ~0xFF ) == 0 ) { cp->drq = drq; } if ( ( irq & ~0xFF ) == 0 ) { cp->irq = irq; } if ( ( port & ~0xFFFF ) == 0 ) { cp->port1 = port; }/*** If the device function is enabled, update the actual** device configuration.*/ if ( SMC37c669_is_device_enabled( func ) ) { SMC37c669_enable_device( func ); } return TRUE; } return FALSE;}/***++** FUNCTIONAL DESCRIPTION:**** This function determines whether a device function** within the SMC37c669 controller is enabled.**** FORMAL PARAMETERS:**** func:** Which device function**** RETURN VALUE:**** Returns TRUE if the device function is enabled, otherwise, FALSE**** SIDE EFFECTS:**** {@description or none@}**** DESIGN:**** To check whether a device is enabled we will only look at ** the port base address mapping. According to the SMC37c669** specification, all of the port base address mappings are** disabled if the addr<9:8> (bits <7:6> of the register) are** zero.****--*/static unsigned int __init SMC37c669_is_device_enabled ( unsigned int func ){ unsigned char base_addr = 0; unsigned int dev_ok = FALSE; unsigned int ret_val = FALSE;/*** Enter configuration mode*/ SMC37c669_config_mode( TRUE ); switch ( func ) { case SERIAL_0: base_addr = SMC37c669_read_config( SMC37c669_SERIAL0_BASE_ADDRESS_INDEX ); dev_ok = TRUE; break; case SERIAL_1: base_addr = SMC37c669_read_config( SMC37c669_SERIAL1_BASE_ADDRESS_INDEX ); dev_ok = TRUE; break; case PARALLEL_0: base_addr = SMC37c669_read_config( SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX ); dev_ok = TRUE; break; case FLOPPY_0: base_addr = SMC37c669_read_config( SMC37c669_FDC_BASE_ADDRESS_INDEX ); dev_ok = TRUE; break; case IDE_0: base_addr = SMC37c669_read_config( SMC37c669_IDE_BASE_ADDRESS_INDEX ); dev_ok = TRUE; break; }/*** If we have a valid device, check base_addr<7:6> to see if the** device is enabled (mapped).*/ if ( ( dev_ok ) && ( ( base_addr & 0xC0 ) != 0 ) ) {/*** The mapping is not disabled, so assume that the function is ** enabled.*/ ret_val = TRUE; }/*** Exit configuration mode */ SMC37c669_config_mode( FALSE ); return ret_val;}#if 0/***++** FUNCTIONAL DESCRIPTION:**** This function retrieves the configuration information of a ** device function within the SMC37c699 Super I/O controller.**** FORMAL PARAMETERS:**** func:** Which device function** ** port:** I/O port returned** ** irq:** IRQ returned** ** drq:** DMA channel returned**** RETURN VALUE:**** Returns TRUE if the device configuration was successfully** retrieved, otherwise, FALSE.**** SIDE EFFECTS:**** The data pointed to by the port, irq, and drq parameters** my be modified even if the configuration is not successfully** retrieved.**** DESIGN:**** The device configuration is fetched from the local shadow** copy. Any unused parameters will be set to -1. Any** parameter which is not desired can specify the NULL** pointer.****--*/static unsigned int __init SMC37c669_get_device_config ( unsigned int func, int *port, int *irq, int *drq ){ struct DEVICE_CONFIG *cp; unsigned int ret_val = FALSE;/*** Check for a valid device configuration*/ if ( ( cp = SMC37c669_get_config( func ) ) != NULL ) { if ( drq != NULL ) { *drq = cp->drq; ret_val = TRUE; } if ( irq != NULL ) { *irq = cp->irq; ret_val = TRUE; } if ( port != NULL ) { *port = cp->port1; ret_val = TRUE; } } return ret_val;}#endif/***++** FUNCTIONAL DESCRIPTION:**** This function displays the current state of the SMC37c699** Super I/O controller's device functions.**** FORMAL PARAMETERS:**** None**** RETURN VALUE:**** None**** SIDE EFFECTS:**** None****--*/void __init SMC37c669_display_device_info ( void ){ if ( SMC37c669_is_device_enabled( SERIAL_0 ) ) { printk( " Serial 0: Enabled [ Port 0x%x, IRQ %d ]\n", local_config[ SERIAL_0 ].port1, local_config[ SERIAL_0 ].irq ); } else { printk( " Serial 0: Disabled\n" ); } if ( SMC37c669_is_device_enabled( SERIAL_1 ) ) { printk( " Serial 1: Enabled [ Port 0x%x, IRQ %d ]\n", local_config[ SERIAL_1 ].port1, local_config[ SERIAL_1 ].irq ); } else { printk( " Serial 1: Disabled\n" ); } if ( SMC37c669_is_device_enabled( PARALLEL_0 ) ) { printk( " Parallel: Enabled [ Port 0x%x, IRQ %d/%d ]\n", local_config[ PARALLEL_0 ].port1, local_config[ PARALLEL_0 ].irq, local_config[ PARALLEL_0 ].drq ); } else { printk( " Parallel: Disabled\n" ); } if ( SMC37c669_is_device_enabled( FLOPPY_0 ) ) { printk( " Floppy Ctrl: Enabled [ Port 0x%x, IRQ %d/%d ]\n", local_config[ FLOPPY_0 ].port1, local_config[ FLOPPY_0 ].irq, local_config[ FLOPPY_0 ].drq ); } else { printk( " Floppy Ctrl: Disabled\n" ); } if ( SMC37c669_is_device_enabled( IDE_0 ) ) { printk( " IDE 0: Enabled [ Port 0x%x, IRQ %d ]\n", local_config[ IDE_0 ].port1, local_config[ IDE_0 ].irq ); } else { printk( " IDE 0: Disabled\n" ); }}/***++** FUNCTIONAL DESCRIPTION:**** This function puts the SMC37c669 Super I/O controller into,** and takes it out of, configuration mode.**** FORMAL PARAMETERS:**** enable:** TRUE to enter configuration mode, FALSE to exit.**** RETURN VALUE:**** None**** SIDE EFFECTS:**** The SMC37c669 controller may be left in configuration mode.****--*/static void __init SMC37c669_config_mode( unsigned int enable ){ if ( enable ) {/*** To enter configuration mode, two writes in succession to the index** port are required. If a write to another address or port occurs** between these two writes, the chip does not enter configuration** mode. Therefore, a spinlock is placed around the two writes to ** guarantee that they complete uninterrupted.*/ spinlock( &spl_atomic ); wb( &SMC37c669->index_port, SMC37c669_CONFIG_ON_KEY ); wb( &SMC37c669->index_port, SMC37c669_CONFIG_ON_KEY ); spinunlock( &spl_atomic ); } else { wb( &SMC37c669->index_port, SMC37c669_CONFIG_OFF_KEY ); }}/***++** FUNCTIONAL DESCRIPTION:**** This function reads an SMC37c669 Super I/O controller** configuration register. This function assumes that the** device is already in configuration mode.**** FORMAL PARAMETERS:**** index:** Index value of configuration register to read**** RETURN VALUE:**** Data read from configuration register**** SIDE EFFECTS:**** None****--*/static unsigned char __init SMC37c669_read_config( unsigned char index ){ unsigned char data; wb( &SMC37c669->index_port, index ); data = rb( &SMC37c669->data_port ); return data;}/***++** FUNCTIONAL DESCRIPTION:**** This function writes an SMC37c669 Super I/O controller
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -