📄 am930di.c
字号:
{ /* Build the mac object */ /* NOTE: am930mac_construct modifies instance->priv */ am930mac_construct(instance, instance->io.BasePort1, membase, instance->irq.AssignedIRQ); if ( instance->priv == NULL ) { WLAN_LOG_ERROR0("am930hw_construct failed!\n"); am930DI_deconfig(instance); instance->state &= ~DEV_CONFIG_PENDING; } } else { WLAN_LOG_ERROR0("am930DI_config failed!\n"); instance->state &= ~DEV_CONFIG_PENDING; } } break; case CS_EVENT_CARD_REMOVAL: WLAN_LOG_DEBUG1( 2, "CS_EVENT_CARD_REMOVAL event, instance %x\n", (UINT)instance); instance->state &= ~DEV_PRESENT; if (instance->state & DEV_CONFIG) { WLAN_LOG_DEBUG0(2,"Setting up timer destructor call.\n"); instance->release.expires = RUN_AT(HZ/20); add_timer(&instance->release); } break; case CS_EVENT_BATTERY_LOW: WLAN_LOG_DEBUG1(2, "CS_EVENT_BATTERY_LOW event, instance %x\n", (UINT)instance); break; case CS_EVENT_BATTERY_DEAD: WLAN_LOG_DEBUG1(2, "CS_EVENT_BATTERY_DEAD event, instance %x\n", (UINT)instance); break; case CS_EVENT_RESET_REQUEST: WLAN_LOG_DEBUG1(2, "CS_EVENT_RESET_REQUEST event, instance %x\n", (UINT)instance); break; case CS_EVENT_RESET_PHYSICAL: WLAN_LOG_DEBUG1(2, "CS_EVENT_RESET_PHYSICAL event, instance %x\n", (UINT)instance); break; case CS_EVENT_CARD_RESET: WLAN_LOG_DEBUG1(2, "CS_EVENT_CARD_RESET event, instance %x\n", (UINT)instance); break; case CS_EVENT_RESET_COMPLETE: WLAN_LOG_DEBUG1(2, "CS_EVENT_RESET_COMPLETE event, instance %x\n", (UINT)instance); break; case CS_EVENT_PM_SUSPEND: WLAN_LOG_DEBUG1(2, "CS_EVENT_PM_SUSPEND event, instance %x\n", (UINT)instance); break; case CS_EVENT_PM_RESUME: WLAN_LOG_DEBUG1(2, "CS_EVENT_PM_RESUME event, instance %x\n", (UINT)instance); break; default: WLAN_LOG_DEBUG1(2, "unknown event, instance %x\n", (UINT)instance); break; } DBFEXIT return 0;} /*----------------------------------------------------------------* am930DI_config** This function configures the PCMCIA socket, and allocates the* system resources for the card. Once this function is complete* we can treat the card like any other ISA and ignore the fact* that it's a PCMCIA.** returns: nothing----------------------------------------------------------------*/#define CS_CHECK( fn, args... ) while( ( last_ret = CardServices( last_fn = ( fn ), args ) ) != 0 ) goto cs_failed#define CFG_CHECK( fn, args... ) if( CardServices( fn, args ) != 0 ) goto next_entryint am930DI_config(dev_link_t *instance, UINT32 *pMemBase){ client_handle_t handle = instance->handle; tuple_t tuple; cisparse_t parse; int last_fn; int last_ret; cisdata_t buf[AM930DI_TPL_BUFSIZE]; win_req_t req; dev_node_t *pnode; cistpl_cftable_entry_t dflt = { 0 }; cistpl_cftable_entry_t *cfg = NULL; DBFENTER; /*--Allocate a node_t for the instance to point to, apparently --*/ /*-- driver services requires this ------*/ pnode = kmalloc(sizeof(dev_node_t), GFP_KERNEL); memset( pnode, 0, sizeof(dev_node_t)); instance->dev = pnode; /*-- set up the deconfig (release) function --*/ instance->release.function = (void (*)(u_long))&am930DI_destruct; instance->release.data = (u_long)instance; /* clear the membase */ *pMemBase = 0; /* Pick up the CONFIG tuple items */ tuple.DesiredTuple = CISTPL_CONFIG; tuple.Attributes = 0; tuple.TupleData = buf; tuple.TupleDataMax = sizeof( buf ); tuple.TupleOffset = 0; CS_CHECK( GetFirstTuple, handle, &tuple ); CS_CHECK( GetTupleData, handle, &tuple ); CS_CHECK( ParseTuple, handle, &tuple, &parse ); instance->conf.ConfigBase = parse.config.base; instance->conf.Present = parse.config.rmask[0]; instance->conf.IntType = INT_MEMORY_AND_IO; instance->state |= DEV_CONFIG; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; CS_CHECK( GetFirstTuple, handle, &tuple ); while( 1 ) { CFG_CHECK( GetTupleData, handle, &tuple ); CFG_CHECK( ParseTuple, handle, &tuple, &parse ); cfg = &(parse.cftable_entry); printk(KERN_DEBUG"Inspecting CFTABLE[%d]\n", cfg->index); if( cfg->flags & CISTPL_CFTABLE_DEFAULT ) { dflt = *cfg; } if( cfg->index == 0 || ((am930_use_mmio == 0) && (cfg->mem.nwin > 0)) ) { goto next_entry; } instance->conf.ConfigIndex = cfg->index; if( cfg->vcc.present & ( 1<<CISTPL_POWER_VNOM ) ) instance->conf.Vcc = cfg->vcc.param[CISTPL_POWER_VNOM] / 10000; else if( dflt.vcc.present & ( 1<<CISTPL_POWER_VNOM ) ) instance->conf.Vcc = dflt.vcc.param[CISTPL_POWER_VNOM] / 10000; if( cfg->vpp1.present & ( 1<<CISTPL_POWER_VNOM ) ) instance->conf.Vpp1 = instance->conf.Vpp2 = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; else if( dflt.vpp1.present & ( 1<<CISTPL_POWER_VNOM ) ) instance->conf.Vpp1 = instance->conf.Vpp2 = dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; if( cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1 ) { instance->conf.Attributes |= CONF_ENABLE_IRQ; instance->irq.Handler = am930DI_interrupt; instance->irq.Instance = instance; instance->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; instance->irq.IRQInfo1 = cfg->irq.IRQInfo1 ? cfg->irq.IRQInfo1 : dflt.irq.IRQInfo1; if( cfg->irq.IRQInfo2 || dflt.irq.IRQInfo2 ) { instance->irq.IRQInfo1 |= IRQ_INFO2_VALID; instance->irq.IRQInfo2 = cfg->irq.IRQInfo2 ? cfg->irq.IRQInfo2 : dflt.irq.IRQInfo2; } } instance->io.NumPorts1 = instance->io.NumPorts2 = 0; if( ( cfg->io.nwin > 0 ) || ( dflt.io.nwin > 0 ) ) { cistpl_io_t *io = ( cfg->io.nwin ) ? &cfg->io : &dflt.io; instance->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; if( !( io->flags & CISTPL_IO_8BIT ) ) instance->io.Attributes1 = IO_DATA_PATH_WIDTH_16; if( !( io->flags & CISTPL_IO_16BIT ) ) instance->io.Attributes1 = IO_DATA_PATH_WIDTH_8; instance->io.BasePort1 = io->win[0].base; instance->io.NumPorts1 = io->win[0].len; } CFG_CHECK( RequestIO, instance->handle, &instance->io ); if( ( cfg->mem.nwin > 0 ) || ( dflt.mem.nwin > 0 ) ) { cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &dflt.mem; req.Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM; req.Base = mem->win[0].host_addr; req.Size = mem->win[0].len; req.AccessSpeed = 0; instance->win = (window_handle_t)instance->handle; CFG_CHECK( RequestWindow, &instance->win, &req ); /*-- Save the mem base ----*/ *pMemBase = (UINT32)ioremap_nocache( req.Base, 0x8000 ); } break;next_entry: CS_CHECK( GetNextTuple, handle, &tuple ); } if( instance->conf.Attributes & CONF_ENABLE_IRQ ) { CS_CHECK( RequestIRQ, instance->handle, &instance->irq ); } CS_CHECK( RequestConfiguration, instance->handle, &instance->conf ); IRQ_MAP(instance->irq.AssignedIRQ, instance); printk(KERN_DEBUG"CFTABLE index 0x%02x: Vcc %d.%d irq %d\n", instance->conf.ConfigIndex, instance->conf.Vcc / 10, instance->conf.Vcc % 10, instance->irq.AssignedIRQ ); printk(KERN_DEBUG" io 0x%04x-0x%04x\n", instance->io.BasePort1, instance->io.BasePort1 + instance->io.NumPorts1 - 1 ); if( instance->win ) printk(KERN_DEBUG" mem 0x%06lx-0x%06lx\n", req.Base, req.Base + req.Size - 1 ); instance->state &= ~DEV_CONFIG_PENDING; DBFEXIT; return AM930DI_SUCCESS; cs_failed: am930_drvr_cs_error( handle, last_fn, last_ret ); am930DI_deconfig( instance ); return AM930DI_FAILURE;}/*----------------------------------------------------------------* am930DI_deconfig** This function releases all of the resources established for* the pcmcia card instance. It then marks the instance as NOT* configured.** returns: always returns success----------------------------------------------------------------*/int am930DI_deconfig(dev_link_t *instance){ int nResult = AM930DI_SUCCESS; DBFENTER; /*-------Clear the irq2dev_map entry -----*/ IRQ_MAP( instance->irq.AssignedIRQ, NULL ); /* Don't bother checking to see if these succeed or not */ if( instance->priv != NULL ) { am930mac_t * mac = (am930mac_t *) instance->priv; if( mac->hw != NULL ) { am930hw_t * hw = (am930hw_t *) mac->hw; if( hw->membase != 0 ) { iounmap( (void *) hw->membase ); } } } CardServices(ReleaseWindow, instance->win); CardServices(ReleaseConfiguration, instance->handle); CardServices(ReleaseIO, instance->handle, &instance->io); CardServices(ReleaseIRQ, instance->handle, &instance->irq); instance->state &= ~DEV_CONFIG; DBFEXIT; return nResult;}/*----------------------------------------------------------------* am930DI_interrupt** Wrapper interrupt handle. This function receives interrupts* logically from the PCMCIA hardware since it's the one mapping* card interrupts to a given host interrupt line.** This function checks to see if the DI object is referenced in* the irq entry in the irq2dev_map. If so, then we check to see* if an am930hw object is present in the given DI object. If so* we call the am930hw object's ISR method.** TODO: check that it's OK for a dev_link_t to be in irq2dev_map** returns: nothing----------------------------------------------------------------*/static void am930DI_interrupt IRQ(int irq, void * dev_id, struct pt_regs *regs ) { dev_link_t* instance = NULL; DBFENTER; if ( (instance = (dev_link_t*)DEV_ID) != NULL ) { if ( instance->priv != NULL ) { am930mac_ISR( (am930mac_t*)instance->priv ); } } else { WLAN_LOG_DEBUG0(2, "*** am930di_interrupt with unknown receiver!\n"); } DBFEXIT; return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -