PU8 C_DM9000::DeviceReadString( PU8 ptrBuffer, int nLength) { int count; count = (nLength + m_nIoMaxPad) / m_nIoMode; // select port to be read from ENTER_CRITICAL_SECTION VALIDATE_ADDR_PORT(DM9_MRCMD); switch (m_nIoMode) { case BYTE_MODE: NdisRawReadPortBufferUchar( m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9000_DATA_OFFSET, ptrBuffer,count); break; case WORD_MODE: NdisRawReadPortBufferUshort( m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9000_DATA_OFFSET, (PU16)ptrBuffer,count); break; case DWORD_MODE: NdisRawReadPortBufferUlong( m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9000_DATA_OFFSET, (PU32)ptrBuffer,count); break; default: break; } // of switch LEAVE_CRITICAL_SECTION return ptrBuffer; }
BOOLEAN LtFirmInitialize( IN PLT_ADAPTER Adapter, IN UCHAR SuggestedNodeId ) /*++ Routine Description: This routine initializes the card, downloads the firmware to it. Arguments: Adapter : Pointer to the adapter structure. Return Value: TRUE : If successful, false otherwise --*/ { PUCHAR Firmware; UINT FirmwareLen; UINT RetryCount; UCHAR Data; BOOLEAN Result = FALSE; // Clear the request Latch NdisRawReadPortUchar(XFER_PORT, &Data); // Clear the TX_READY FLOP NdisRawWritePortUchar(XFER_PORT, (UCHAR)0); // Reset the card. NdisRawWritePortUchar(RESET_PORT, (UCHAR)0); NdisStallExecution(LT_FIRM_INIT_STALL_TIME*5); for (RetryCount = 0; RetryCount < MAX_READ_RETRY_COUNT; RetryCount++) { // Get Card Status. NdisRawReadPortUchar(SC_PORT, &Data); if (Data & TX_READY) { break; } else DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_WARN, ("LtFirmInitialize: Waiting for card ready SC_PORT %x\n", Data)); NdisStallExecution(LT_FIRM_INIT_STALL_TIME); } // BUGBUG: // !!!!!! // For DAYNA, it will not be ready at this point. DCH is going to // send information to fix this. do { if (RetryCount == MAX_READ_RETRY_COUNT) { LOGERROR( Adapter->NdisAdapterHandle, NDIS_ERROR_CODE_HARDWARE_FAILURE); DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_FATAL, ("LtFirmInitialize: Card Not Ready after Reset\n")); break; } // Copy the firmware to the card. Firmware = LtMicroCode; FirmwareLen = sizeof(LtMicroCode); DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO, ("LtFirmInitialize: DownLoad %d bytes of firmware\n", FirmwareLen)); // Well... the card is alive and well and in a reset state. // Next we need to output the first byte of the firmware and // check for TX_READY. NdisRawWritePortUchar(XFER_PORT, *Firmware); DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO, ("LtFirmInitialize: First byte of Firmware on card\n")); NdisRawReadPortUchar(SC_PORT, &Data); if (Data & TX_READY) { DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_FATAL, ("LtFirmInitialize: Card Not Ready During Download\n")); LOGERROR( Adapter->NdisAdapterHandle, NDIS_ERROR_CODE_HARDWARE_FAILURE); break; } // Skip over the first byte because it already out there. Firmware ++; FirmwareLen --; NdisRawWritePortBufferUchar(XFER_PORT, Firmware, FirmwareLen); // Tell the card to start NdisRawReadPortUchar(XFER_PORT, &Data); // Wait for the card to start for (RetryCount = 0; RetryCount < MAX_START_RETRY_COUNT; RetryCount++) { NdisStallExecution(LT_FIRM_INIT_STALL_TIME); // Get Status NdisRawReadPortUchar(SC_PORT, &Data); DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_WARN, ("LtFirmInitialize: Waiting for start - SC_PORT Data %x\n", (UCHAR)Data)); if (Data & RX_READY) { break; } } // !!! This seems to be the only way the MCA card works according to // !!! Dave Hornbaker. It seems that the MCA card doesnt get ready at // !!! this point, but works later on. if (RetryCount == MAX_START_RETRY_COUNT) { ASSERT(Adapter->BusType != NdisInterfaceMca); DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_FATAL, ("LtFirmInitialize: Card Not Ready, could not get status\n")); LOGERROR( Adapter->NdisAdapterHandle, NDIS_ERROR_CODE_INVALID_VALUE_FROM_ADAPTER); break; } // Clear the initial ready signal. NdisRawReadPortUchar(XFER_PORT, &Data); // Now loop here for a finite time till the card acquires a node id. // If it fails to do so in the specified time, fail the load. if (!LtInitGetAddressSetPoll(Adapter, SuggestedNodeId)) { break; } // We need to catch the card fast after it acquire the node id and before it // receives any packets. If it does receive any packets, then ask it acquire // the node id again. The stall happens ONLY IF A PACKET IS RECVD. for (RetryCount = 0; RetryCount < MAX_START_RETRY_COUNT*200; RetryCount++) { USHORT ResponseLength; UCHAR ResponseType; LT_INIT_RESPONSE InitPacket; // Check for receive data NdisRawReadPortUchar(SC_PORT, &Data); if (Data & RX_READY) { // Get the length of the response on the card NdisRawReadPortUchar(XFER_PORT, &Data); ResponseLength = (USHORT)(Data & 0xFF); NdisRawReadPortUchar(XFER_PORT, &Data); ResponseLength |= (Data << 8); // Now get the IO code. NdisRawReadPortUchar(XFER_PORT, &ResponseType); DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO, ("LtFirmInitialize: RespType = %x, RespLength = %d\n", ResponseType, ResponseLength)); if ((ResponseType == LT_RSP_LAP_INIT) && (ResponseLength == sizeof(LT_INIT_RESPONSE))) { NdisRawReadPortBufferUchar(XFER_PORT, (PUCHAR)&InitPacket, ResponseLength); Adapter->NodeId = InitPacket.NodeId; Adapter->Flags |= ADAPTER_NODE_ID_VALID; // This should start off a worker thread to write the // node id into the pram. // BUGBUG: Implement using worker threads. // LtRegWritePramNodeId(Adapter); DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO, ("LtFirmInitailize: Node id acquired %x\n", InitPacket.NodeId)); break; } DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_WARN, ("LtFirmInitailize: Node id not valid yet !!\n")); // Suck in the packet and throw it away while (ResponseLength-- > 0) { NdisRawReadPortUchar(XFER_PORT, &Data); } // The response was probably over-written by incoming packet. // Try again. NdisStallExecution(LT_FIRM_INIT_STALL_TIME); DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_WARN, ("LtFirmInitailize: Re-acquire node after packet recv\n")); if (!LtInitGetAddressSetPoll(Adapter, SuggestedNodeId)) { break; } } else { DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_WARN, ("LtFirmInitialize: Waiting for node - SC_PORT Data %x\n", (UCHAR)Data)); } NdisStallExecution(500); // 500us } Result = ((Adapter->Flags & ADAPTER_NODE_ID_VALID) != 0); } while (FALSE); return(Result); }