u8 cf_read8(struct intf_hdl *pintfhdl, u32 addr) { _irqL irqL; uint res; u8 val; struct _SyncContext synccontext; struct intf_priv *pintfpriv = pintfhdl->pintfpriv; //u8 *rwmem = pintfpriv->io_rwmem; struct dvobj_priv * pcfiodev = (struct dvobj_priv * )(pintfpriv->intf_dev); u32 iobase_addr = pcfiodev->io_base_address; // Please remember, you just can't only use lock/unlock to // protect the rw functions... // since, i/o is quite common in call-back and isr routines... _func_enter_; _enter_hwio_critical(&pintfpriv->rwlock, &irqL); #ifdef PLATFORM_WINDOWS if( addr >= RTL8711_HCICTRL_ && addr <= (RTL8711_HCICTRL_+0x1FFFF) ) { //the address is in HCI local register addr = (addr&0x00003FFF); NdisRawReadPortUchar((u32)(iobase_addr+addr), (u8 *)&val); }else{ synccontext.pintfpriv = pintfpriv; synccontext.lbusaddr = addr; synccontext.bytecnt = 1; // 1-byte synccontext.pdata=(u8 *)&val; irqL = KeGetCurrentIrql(); if ( irqL <= DISPATCH_LEVEL ) res = NdisMSynchronizeWithInterrupt(&pcfiodev->interrupt, cfbus_read, (void *)&synccontext); else//IRQL > DISPATCH_LEVEL res = cfbus_read((void *)&synccontext); //NdisMoveMemory(&val, rwmem, 1); } #endif _exit_hwio_critical(&pintfpriv->rwlock, &irqL); _func_exit_; return val; }
/* ************************************************************************* * MiniportHandleInterrupt ************************************************************************* * * * This is the deferred interrupt processing routine (DPC) which is * optionally called following an interrupt serviced by MiniportISR. * */ VOID MiniportHandleInterrupt(NDIS_HANDLE MiniportAdapterContext) { IrDevice *thisDev = CONTEXT_TO_DEV(MiniportAdapterContext); DBGOUT(("==> MiniportHandleInterrupt(0x%x)", (UINT)MiniportAdapterContext)); /* * If we have just started receiving a packet, * indicate media-busy to the protocol. */ if (thisDev->mediaBusy && !thisDev->haveIndicatedMediaBusy){ NdisMIndicateStatus(thisDev->ndisAdapterHandle, NDIS_STATUS_MEDIA_BUSY, NULL, 0); NdisMIndicateStatusComplete(thisDev->ndisAdapterHandle); thisDev->haveIndicatedMediaBusy = TRUE; } /* * Deliver all undelivered receive packets to the protocol. */ DeliverFullBuffers(thisDev); /* * Update the rcv queue 'first' and 'last' pointers. * * We cannot use a spinlock to coordinate accesses to the rcv buffers * with the ISR, since ISR's are not allowed to acquire spinlocks. * So instead, we synchronize with the ISR using this special mechanism. * MiniportSyncHandleInterrupt will do our work for us with the IRQ * masked out in the PIC. */ NdisMSynchronizeWithInterrupt( &thisDev->interruptObj, MiniportSyncHandleInterrupt, (PVOID)MiniportAdapterContext); /* * Send any pending write packets if possible. */ if (IsCommReadyForTransmit(thisDev)){ PortReadyForWrite(thisDev, FALSE); } DBGOUT(("<== MiniportHandleInterrupt")); }
u32 cf_read32(struct intf_hdl *pintfhdl, u32 addr) { _irqL irqL; uint res; u32 val; struct _SyncContext synccontext; struct intf_priv *pintfpriv = pintfhdl->pintfpriv; struct dvobj_priv * pcfiodev = (struct dvobj_priv * )(pintfpriv->intf_dev); u32 iobase_addr = pcfiodev->io_base_address; _func_enter_; _enter_hwio_critical(&pintfpriv->rwlock, &irqL); #ifdef PLATFORM_WINDOWS if( addr >= RTL8711_HCICTRL_ && addr <= (RTL8711_HCICTRL_+0x1FFFF) ) { //the address is in HCI local register addr = (addr&0x00003FFF); NdisRawReadPortUlong((u32)(iobase_addr+addr), (u32 *)&val); }else{ synccontext.pintfpriv = pintfpriv; synccontext.lbusaddr = addr; synccontext.bytecnt = 4; // 4-byte synccontext.pdata=(u8 *)&val; irqL = KeGetCurrentIrql(); if ( irqL <= DISPATCH_LEVEL ) res = NdisMSynchronizeWithInterrupt(&pcfiodev->interrupt, cfbus_read, (void *)&synccontext); else//IRQL > DISPATCH_LEVEL res = cfbus_read((void *)&synccontext); } #endif _exit_hwio_critical(&pintfpriv->rwlock, &irqL); _func_exit_; return val; }
BOOLEAN shared_interrupt_synchronize(PNDIS_MINIPORT_INTERRUPT pintr, shared_info_t *sh, void (*SyncFunc)(void *), void *SyncCxt) { if (sh->BusType == NdisInterfacePci || sh->BusType == NdisInterfacePcMcia) { return NdisMSynchronizeWithInterrupt(pintr, (void*)SyncFunc, (void*)SyncCxt); } else if (sh->BusType == NdisInterfaceSDIO) { { BOOLEAN intr_on; /* disable intr and reenable after reset if intr was on */ intr_on = bcmsdh_intr_query(sh->sdh); if (intr_on) bcmsdh_intr_disable(sh->sdh); (SyncFunc)(SyncCxt); if (intr_on) bcmsdh_intr_enable(sh->sdh); } } return TRUE; }