U32 C_DM9000::DeviceReadDataWithoutIncrement(void) { U32 value,tmp; ENTER_CRITICAL_SECTION VALIDATE_ADDR_PORT(DM9_MRCMDX); switch (m_nIoMode) { case BYTE_MODE: NdisRawReadPortUchar( m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9000_DATA_OFFSET, (PU8)&tmp); NdisRawReadPortUchar( m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9000_DATA_OFFSET, (PU8)&value); value = (value&0x000000FF); break; case WORD_MODE: NdisRawReadPortUshort( m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9000_DATA_OFFSET, (PU16)&tmp); NdisRawReadPortUshort( m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9000_DATA_OFFSET, (PU16)&value); value = (value&0x0000FFFF); break; case DWORD_MODE: NdisRawReadPortUlong( m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9000_DATA_OFFSET, (PU32)&tmp); NdisRawReadPortUlong( m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9000_DATA_OFFSET, (PU32)&value); break; default: break; } // of switch LEAVE_CRITICAL_SECTION return value; }
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // // Routine Name: NetFlexISR // // Description: // This routine is the ISR for this Netflx mac driver. // This routine determines if the interrupt is for it // and if so, it clears the system interrupt bit of // the sifint register. // // Input: // Context - Our Driver Context for this adapter or head. // // Output: // Returns TRUE if the interrupt belongs to the // adapter and returns FALSE if it does not // belong to the adapter. // // Called By: // Miniport Wrapper // //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ VOID NetFlexISR( OUT PBOOLEAN InterruptRecognized, OUT PBOOLEAN QueueDpc, IN PVOID Context ) { PACB acb; USHORT sifint_reg; USHORT actl_reg; acb = (PACB) Context; // // Read the Sifint register. // NdisRawReadPortUshort( acb->SifIntPort, &sifint_reg); // // See if the System Interrupt bit is set. If it is, this is an // interrupt for us. // if (sifint_reg & SIFINT_SYSINT) { // // Acknowledge and Clear Int // if (!acb->InterruptsDisabled) { actl_reg = acb->actl_reg & ~ACTL_SINTEN; NdisRawWritePortUshort(acb->SifActlPort, actl_reg); DebugPrint(3,("NF(%d)(D)\n",acb->anum)); acb->InterruptsDisabled = TRUE; // // Return that we recognize it // *InterruptRecognized = TRUE; *QueueDpc = TRUE; } else { // // It appears that a second head is generating // the interrupt, and we have a DPC queued to // process our int, return that we don't recognize it // so that the oterh head's isr gets called... // *InterruptRecognized = FALSE; *QueueDpc = FALSE; } } else { // Return that we don't recognize it // *InterruptRecognized = FALSE; *QueueDpc = FALSE; } }
u16 cf_read16(struct intf_hdl *pintfhdl, u32 addr) { _irqL irqL; uint res; u16 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); NdisRawReadPortUshort((u32)(iobase_addr+addr), (u16 *)&val); // 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... }else{ synccontext.pintfpriv = pintfpriv; synccontext.lbusaddr = addr; synccontext.bytecnt = 2; // 2-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; }
static uint cfbus_read(void *context) { #ifdef PLATFORM_WINDOWS u32 iobase_addr, len, addr, HAARValue, Read_Data; u8 *pdata; USHORT readCF_HAAR; u32 counter=0; struct _SyncContext *psynccontext = (struct _SyncContext *)context; struct intf_priv *pintfpriv = (struct intf_priv *)psynccontext->pintfpriv; struct dvobj_priv * pcfiodev = (struct dvobj_priv *)pintfpriv->intf_dev; //u8 *rwmem = (u8 *)pintfpriv->rw_mem; iobase_addr = pcfiodev->io_base_address; len = psynccontext ->bytecnt; addr = psynccontext->lbusaddr; pdata = psynccontext->pdata; _func_enter_; //if the address is in HCI local register, to skip it if( addr >= RTL8711_HCICTRL_ && addr <= (RTL8711_HCICTRL_+0x1FFFF) ) { _func_exit_; return _FAIL; } HAARValue = HAARSetting(len, IO_READ, addr); // 1.Write HAAR NdisRawWritePortUlong( (ULONG)(iobase_addr+HAAR), HAARValue); // 2.Polling HAAR Ready do { if(counter > HAAR_POLLING_CNT){ //RT_TRACE(COMP_DBG, DBG_LOUD, ("\n\nCFIOReadReg: Poll HAAR Ready too long, LBus = 0x%X checkRegRWCnt(1) = %d currentIRQL = %x, read HAAR=%x, HAARValue=%x.\n\n",c->LexraBusAddr, checkRegRWCnt, currentIRQL, test32, HAARValue )); _func_exit_; return _FAIL; } if(addr == CR9346) NdisStallExecution(50); //Considering CFIO default mode is 16-bit mode, we use 16-bit reading NdisRawReadPortUshort( (ULONG)(iobase_addr+HAAR+0x0002), &readCF_HAAR); counter++; }while(((readCF_HAAR >> 14) & 0x3) != 0x3); //while READY has not been set // 3.Read HRADR NdisRawReadPortUlong( (ULONG)(iobase_addr+HRADR), (ULONG *)&Read_Data); NdisMoveMemory(pdata , (u8 *)&Read_Data, len); #endif _func_exit_; return _SUCCESS; }
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // // Routine Name: NetFlexHandleInterrupt // // Description: // This routine is the deferred processing // routine for all adapter interrupts. // // Input: // acb - Our Driver Context for this adapter or head. // // Output: // None // // Called By: // Miniport Wrapper // //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ VOID NetFlexHandleInterrupt( IN NDIS_HANDLE MiniportAdapterContext ) { USHORT sifint_reg; USHORT tmp_reg; USHORT ReceivesProcessed = 0; PACB acb = (PACB) MiniportAdapterContext; // // Read the SifInt // NdisRawReadPortUshort( acb->SifIntPort, &sifint_reg); while (sifint_reg & SIFINT_SYSINT) { // // Ack the interrupt // sifint_reg &= ~SIFINT_SYSINT; NdisRawWritePortUshort( acb->SifIntPort, sifint_reg); // // mask off the int code // sifint_reg &= INT_CODES; // // See if there are any recieves to do... // if (acb->acb_rcv_head->RCV_CSTAT & RCSTAT_COMPLETE) { // // Increment the interrupt count. // acb->acb_int_count++; // // yes, do them... // acb->handled_interrupts++; ReceivesProcessed += acb->ProcessReceiveHandler(acb); } // // See if there are any transmits to do... // NetFlexProcessXmit(acb); switch (sifint_reg) { case INT_SCBCLEAR: acb->acb_scbclearout = FALSE; // // Is the SCB really clear? // // If the SCB is clear, send a SCB command off now. // Otherwise, if we are not currently waiting for an SCB clear // interrupt, signal the adapter to send us a SCB clear interrupt // when it is done with the SCB. // if (acb->acb_scb_virtptr->SCB_Cmd == 0) { NetFlexSendNextSCB(acb); } else if ((acb->acb_xmit_whead) || (acb->acb_rcv_whead) || (acb->acb_scbreq_next)) { acb->acb_scbclearout = TRUE; NdisRawWritePortUshort( acb->SifIntPort, (USHORT)SIFINT_SCBREQST); } break; case INT_COMMAND: NetFlexCommand(acb); // // Do we have any commands to complete? // if (acb->acb_confirm_qhead != NULL) { NetFlexProcessMacReq(acb); } break; case INT_ADPCHECK: // // Read the Adapter Check Status @ 1.05e0 // NdisRawWritePortUshort(acb->SifAddrxPort, (USHORT) 1); NdisRawWritePortUshort(acb->SifAddrPort, (USHORT) 0x5e0); NdisRawReadPortUshort( acb->SifDIncPort, &tmp_reg); DebugPrint(1,("NF(%d): Adapter Check - 0x%x\n",acb->anum,tmp_reg)); // // Reset has failed, errorlog an entry. // NdisWriteErrorLogEntry( acb->acb_handle, EVENT_NDIS_ADAPTER_CHECK_ERROR, 2, NETFLEX_ADAPTERCHECK_ERROR_CODE, tmp_reg ); // // Set the variables up showing that the hardware has an unrecoverable // error. // acb->acb_state = AS_HARDERROR; break; case INT_RINGSTAT: NetFlexRingStatus(acb); break; case INT_RECEIVE: break; case INT_TRANSMIT: // // If we reached the end of the xmit lists, // then the xmit status will indicate COMMAND_COMPLETE. // The transmiter will be stalled until another transmit // command is issued with a valid list. // if (acb->acb_ssb_virtptr->SSB_Status & XSTAT_LERROR) { // // We have a list error... // NetFlexTransmitStatus(acb); } default: break; } // // Issue a ssb clear. After this we may see SIFCMD interrupts. // NdisRawWritePortUshort(acb->SifIntPort, SIFINT_SSBCLEAR); // // Read the SifInt // NdisRawReadPortUshort(acb->SifIntPort, &sifint_reg); } // // Processed any receives which need IndicateReceiveComplete? // if (ReceivesProcessed) { if (acb->acb_gen_objs.media_type_in_use == NdisMedium802_5) { // Token Ring // NdisMTrIndicateReceiveComplete(acb->acb_handle); } else { // Ethernet // NdisMEthIndicateReceiveComplete(acb->acb_handle); } } }