📄 smc37c669.c
字号:
** configuration register. This function assumes that the** device is already in configuration mode.**** FORMAL PARAMETERS:**** index:** Index of configuration register to write** ** data:** Data to be written**** RETURN VALUE:**** None**** SIDE EFFECTS:**** None****--*/static void __init SMC37c669_write_config( unsigned char index, unsigned char data ){ wb( &SMC37c669->index_port, index ); wb( &SMC37c669->data_port, data );}/***++** FUNCTIONAL DESCRIPTION:**** This function initializes the local device** configuration storage. This function assumes** that the device is already in configuration** mode.**** FORMAL PARAMETERS:**** None**** RETURN VALUE:**** None**** SIDE EFFECTS:**** Local storage for device configuration information** is initialized.****--*/static void __init SMC37c669_init_local_config ( void ){ SMC37c669_SERIAL_BASE_ADDRESS_REGISTER uart_base; SMC37c669_SERIAL_IRQ_REGISTER uart_irqs; SMC37c669_PARALLEL_BASE_ADDRESS_REGISTER ppt_base; SMC37c669_PARALLEL_FDC_IRQ_REGISTER ppt_fdc_irqs; SMC37c669_PARALLEL_FDC_DRQ_REGISTER ppt_fdc_drqs; SMC37c669_FDC_BASE_ADDRESS_REGISTER fdc_base; SMC37c669_IDE_ADDRESS_REGISTER ide_base; SMC37c669_IDE_ADDRESS_REGISTER ide_alt;/*** Get serial port 1 base address */ uart_base.as_uchar = SMC37c669_read_config( SMC37c669_SERIAL0_BASE_ADDRESS_INDEX );/*** Get IRQs for serial ports 1 & 2*/ uart_irqs.as_uchar = SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );/*** Store local configuration information for serial port 1*/ local_config[SERIAL_0].port1 = uart_base.by_field.addr9_3 << 3; local_config[SERIAL_0].irq = SMC37c669_xlate_irq( SMC37c669_DEVICE_IRQ( uart_irqs.by_field.uart1_irq ) );/*** Get serial port 2 base address*/ uart_base.as_uchar = SMC37c669_read_config( SMC37c669_SERIAL1_BASE_ADDRESS_INDEX );/*** Store local configuration information for serial port 2*/ local_config[SERIAL_1].port1 = uart_base.by_field.addr9_3 << 3; local_config[SERIAL_1].irq = SMC37c669_xlate_irq( SMC37c669_DEVICE_IRQ( uart_irqs.by_field.uart2_irq ) );/*** Get parallel port base address*/ ppt_base.as_uchar = SMC37c669_read_config( SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX );/*** Get IRQs for parallel port and floppy controller*/ ppt_fdc_irqs.as_uchar = SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );/*** Get DRQs for parallel port and floppy controller*/ ppt_fdc_drqs.as_uchar = SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );/*** Store local configuration information for parallel port*/ local_config[PARALLEL_0].port1 = ppt_base.by_field.addr9_2 << 2; local_config[PARALLEL_0].irq = SMC37c669_xlate_irq( SMC37c669_DEVICE_IRQ( ppt_fdc_irqs.by_field.ppt_irq ) ); local_config[PARALLEL_0].drq = SMC37c669_xlate_drq( SMC37c669_DEVICE_DRQ( ppt_fdc_drqs.by_field.ppt_drq ) );/*** Get floppy controller base address*/ fdc_base.as_uchar = SMC37c669_read_config( SMC37c669_FDC_BASE_ADDRESS_INDEX );/*** Store local configuration information for floppy controller*/ local_config[FLOPPY_0].port1 = fdc_base.by_field.addr9_4 << 4; local_config[FLOPPY_0].irq = SMC37c669_xlate_irq( SMC37c669_DEVICE_IRQ( ppt_fdc_irqs.by_field.fdc_irq ) ); local_config[FLOPPY_0].drq = SMC37c669_xlate_drq( SMC37c669_DEVICE_DRQ( ppt_fdc_drqs.by_field.fdc_drq ) );/*** Get IDE controller base address*/ ide_base.as_uchar = SMC37c669_read_config( SMC37c669_IDE_BASE_ADDRESS_INDEX );/*** Get IDE alternate status base address*/ ide_alt.as_uchar = SMC37c669_read_config( SMC37c669_IDE_ALTERNATE_ADDRESS_INDEX );/*** Store local configuration information for IDE controller*/ local_config[IDE_0].port1 = ide_base.by_field.addr9_4 << 4; local_config[IDE_0].port2 = ide_alt.by_field.addr9_4 << 4; local_config[IDE_0].irq = 14;}/***++** FUNCTIONAL DESCRIPTION:**** This function returns a pointer to the local shadow** configuration of the requested device function.**** FORMAL PARAMETERS:**** func:** Which device function**** RETURN VALUE:**** Returns a pointer to the DEVICE_CONFIG structure for the** requested function, otherwise, NULL.**** SIDE EFFECTS:**** {@description or none@}****--*/static struct DEVICE_CONFIG * __init SMC37c669_get_config( unsigned int func ){ struct DEVICE_CONFIG *cp = NULL; switch ( func ) { case SERIAL_0: cp = &local_config[ SERIAL_0 ]; break; case SERIAL_1: cp = &local_config[ SERIAL_1 ]; break; case PARALLEL_0: cp = &local_config[ PARALLEL_0 ]; break; case FLOPPY_0: cp = &local_config[ FLOPPY_0 ]; break; case IDE_0: cp = &local_config[ IDE_0 ]; break; } return cp;}/***++** FUNCTIONAL DESCRIPTION:**** This function translates IRQs back and forth between ISA** IRQs and SMC37c669 device IRQs.**** FORMAL PARAMETERS:**** irq:** The IRQ to translate**** RETURN VALUE:**** Returns the translated IRQ, otherwise, returns -1.**** SIDE EFFECTS:**** {@description or none@}****--*/static int __init SMC37c669_xlate_irq ( unsigned int irq ){ int i, translated_irq = -1; if ( SMC37c669_IS_DEVICE_IRQ( irq ) ) {/*** We are translating a device IRQ to an ISA IRQ*/ for ( i = 0; ( SMC37c669_irq_table[i].device_irq != -1 ) || ( SMC37c669_irq_table[i].isa_irq != -1 ); i++ ) { if ( irq == SMC37c669_irq_table[i].device_irq ) { translated_irq = SMC37c669_irq_table[i].isa_irq; break; } } } else {/*** We are translating an ISA IRQ to a device IRQ*/ for ( i = 0; ( SMC37c669_irq_table[i].isa_irq != -1 ) || ( SMC37c669_irq_table[i].device_irq != -1 ); i++ ) { if ( irq == SMC37c669_irq_table[i].isa_irq ) { translated_irq = SMC37c669_irq_table[i].device_irq; break; } } } return translated_irq;}/***++** FUNCTIONAL DESCRIPTION:**** This function translates DMA channels back and forth between** ISA DMA channels and SMC37c669 device DMA channels.**** FORMAL PARAMETERS:**** drq:** The DMA channel to translate**** RETURN VALUE:**** Returns the translated DMA channel, otherwise, returns -1**** SIDE EFFECTS:**** {@description or none@}****--*/static int __init SMC37c669_xlate_drq ( unsigned int drq ){ int i, translated_drq = -1; if ( SMC37c669_IS_DEVICE_DRQ( drq ) ) {/*** We are translating a device DMA channel to an ISA DMA channel*/ for ( i = 0; ( SMC37c669_drq_table[i].device_drq != -1 ) || ( SMC37c669_drq_table[i].isa_drq != -1 ); i++ ) { if ( drq == SMC37c669_drq_table[i].device_drq ) { translated_drq = SMC37c669_drq_table[i].isa_drq; break; } } } else {/*** We are translating an ISA DMA channel to a device DMA channel*/ for ( i = 0; ( SMC37c669_drq_table[i].isa_drq != -1 ) || ( SMC37c669_drq_table[i].device_drq != -1 ); i++ ) { if ( drq == SMC37c669_drq_table[i].isa_drq ) { translated_drq = SMC37c669_drq_table[i].device_drq; break; } } } return translated_drq;}#if 0int __init smcc669_init ( void ){ struct INODE *ip; allocinode( smc_ddb.name, 1, &ip ); ip->dva = &smc_ddb; ip->attr = ATTR$M_WRITE | ATTR$M_READ; ip->len[0] = 0x30; ip->misc = 0; INODE_UNLOCK( ip ); return msg_success;}int __init smcc669_open( struct FILE *fp, char *info, char *next, char *mode ){ struct INODE *ip;/*** Allow multiple readers but only one writer. ip->misc keeps track** of the number of writers*/ ip = fp->ip; INODE_LOCK( ip ); if ( fp->mode & ATTR$M_WRITE ) { if ( ip->misc ) { INODE_UNLOCK( ip ); return msg_failure; /* too many writers */ } ip->misc++; }/*** Treat the information field as a byte offset*/ *fp->offset = xtoi( info ); INODE_UNLOCK( ip ); return msg_success;}int __init smcc669_close( struct FILE *fp ){ struct INODE *ip; ip = fp->ip; if ( fp->mode & ATTR$M_WRITE ) { INODE_LOCK( ip ); ip->misc--; INODE_UNLOCK( ip ); } return msg_success;}int __init smcc669_read( struct FILE *fp, int size, int number, unsigned char *buf ){ int i; int length; int nbytes; struct INODE *ip;/*** Always access a byte at a time*/ ip = fp->ip; length = size * number; nbytes = 0; SMC37c669_config_mode( TRUE ); for ( i = 0; i < length; i++ ) { if ( !inrange( *fp->offset, 0, ip->len[0] ) ) break; *buf++ = SMC37c669_read_config( *fp->offset ); *fp->offset += 1; nbytes++; } SMC37c669_config_mode( FALSE ); return nbytes;}int __init smcc669_write( struct FILE *fp, int size, int number, unsigned char *buf ){ int i; int length; int nbytes; struct INODE *ip;/*** Always access a byte at a time*/ ip = fp->ip; length = size * number; nbytes = 0; SMC37c669_config_mode( TRUE ); for ( i = 0; i < length; i++ ) { if ( !inrange( *fp->offset, 0, ip->len[0] ) ) break; SMC37c669_write_config( *fp->offset, *buf ); *fp->offset += 1; buf++; nbytes++; } SMC37c669_config_mode( FALSE ); return nbytes;}#endifvoid __initSMC37c669_dump_registers(void){ int i; for (i = 0; i <= 0x29; i++) printk("-- CR%02x : %02x\n", i, SMC37c669_read_config(i));}/*+ * ============================================================================ * = SMC_init - SMC37c669 Super I/O controller initialization = * ============================================================================ * * OVERVIEW: * * This routine configures and enables device functions on the * SMC37c669 Super I/O controller. * * FORM OF CALL: * * SMC_init( ); * * RETURNS: * * 1 if the chip found, 0 otherwise * * ARGUMENTS: * * None * * SIDE EFFECTS: * * None * */int __init SMC669_Init ( int index ){ SMC37c669_CONFIG_REGS *SMC_base; unsigned long flags; __save_and_cli(flags); if ( ( SMC_base = SMC37c669_detect( index ) ) != NULL ) {#if SMC_DEBUG SMC37c669_config_mode( TRUE ); SMC37c669_dump_registers( ); SMC37c669_config_mode( FALSE ); SMC37c669_display_device_info( );#endif SMC37c669_disable_device( SERIAL_0 ); SMC37c669_configure_device( SERIAL_0, COM1_BASE, COM1_IRQ, -1 ); SMC37c669_enable_device( SERIAL_0 ); SMC37c669_disable_device( SERIAL_1 ); SMC37c669_configure_device( SERIAL_1, COM2_BASE, COM2_IRQ, -1 ); SMC37c669_enable_device( SERIAL_1 ); SMC37c669_disable_device( PARALLEL_0 ); SMC37c669_configure_device( PARALLEL_0, PARP_BASE, PARP_IRQ, PARP_DRQ ); SMC37c669_enable_device( PARALLEL_0 ); SMC37c669_disable_device( FLOPPY_0 ); SMC37c669_configure_device( FLOPPY_0, FDC_BASE, FDC_IRQ, FDC_DRQ ); SMC37c669_enable_device( FLOPPY_0 ); /* Wake up sometimes forgotten floppy, especially on DP264. */ outb(0xc, 0x3f2); SMC37c669_disable_device( IDE_0 );#if SMC_DEBUG SMC37c669_config_mode( TRUE ); SMC37c669_dump_registers( ); SMC37c669_config_mode( FALSE ); SMC37c669_display_device_info( );#endif __restore_flags(flags); printk( "SMC37c669 Super I/O Controller found @ 0x%lx\n", (unsigned long) SMC_base ); return 1; } else { __restore_flags(flags);#if SMC_DEBUG printk( "No SMC37c669 Super I/O Controller found\n" );#endif return 0; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -