⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 send.c

📁 HomePNA的Usb网卡驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
*         If the attempt to send the packet to the driver fails,
*         return ownership of the packet to the protocol and
*         try another packet (until one succeeds).
*
*
*****************************************************************************/

NTSTATUS
UsbIoCompleteWrite(
            IN PDEVICE_OBJECT pUsbDevObj,
            IN PIRP           pIrp,
            IN PVOID          Context
            )
{
    PUSB_DEVICE          device;
    PVOID               pThisContextPacket;
    NTSTATUS            status;
    BOOLEAN             found = FALSE;
    PUSB_CONTEXT        thisContext = ( PUSB_CONTEXT ) Context;
    PUSB_CONTEXT        pPrev, pCur, pNext;
    int                    len;
    CONTEXT_TYPE        ContextType;
    PIRP                ContextIrp;
    PURB                ContextUrb;
    ULONG                BufLen;

    //
    // The context given to IoSetCompletionRoutine is an USB_CONTEXT struct
    //
    ASSERT( NULL != thisContext );                // we better have a non NULL buffer

    device = thisContext->DeviceObject;


    ASSERT( NULL != device );    

    ContextType = thisContext->Type;
    ContextIrp = thisContext->Irp;
    ContextUrb = thisContext->Urb;
    BufLen = thisContext->BufLen;

    pThisContextPacket =  thisContext->Packet; //save ptr to packet to access after context freed

    //
    // Perform various IRP, URB, and buffer 'sanity checks'
    //

    ASSERT( ContextIrp ==  pIrp );                // check we're not a bogus IRP

    status = pIrp->IoStatus.Status;

    //we should have failed, succeeded, or cancelled, but NOT be pending

    ASSERT( STATUS_PENDING != status );
    //
    // IoCallDriver has been called on this Irp;
    // Set the length based on the TransferBufferLength
    // value in the URB
    //

    pIrp->IoStatus.Information =
        ContextUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;

    len = (int)pIrp->IoStatus.Information; // save for below need-termination test

    if (status == STATUS_SUCCESS)
    {
        InterlockedIncrement( (PLONG) &device->packetsSent );
    }
    else
    {
        InterlockedIncrement( (PLONG) &device->NumDataErrors);
        InterlockedIncrement( (PLONG) &device->packetsSentDropped);
    }

    //
    // Free the IRP  because we alloced it ourselves,
    //

    IoFreeIrp( pIrp );


    //
    // See if this was the last packet before we need to change
    // speed.
    //
    /*if ( pThisContextPacket == device->LastPacketAtOldSpeed){

        InterlockedExchangePointer( &device->LastPacketAtOldSpeed, NULL);
        InterlockedExchange( (PLONG) &device->fSetSpeedAfterCurrentSendPacket, TRUE);
    }*/

    InterlockedExchange( (PLONG) &thisContext->fInUse, FALSE );

    UsbDecIoCount( device ); // we will track count of pending irps

    /*if ( device->fSetSpeedAfterCurrentSendPacket) {

         InterlockedExchange( (PLONG) &device->fSetSpeedAfterCurrentSendPacket,  FALSE);

         ASSERT( NULL == device->LastPacketAtOldSpeed );

        // Signal SetspeedCallback it's OK to set speed now
        KeSetEvent(&device->EventSetSpeedNow, 0, FALSE );
    }*/


 /*   if ( CONTEXT_SETSPEED == ContextType ) {

        if ( STATUS_SUCCESS == status ) {
            InterlockedExchange( (PLONG) &device->currentSpeed,
                device->linkSpeedInfo->bitsPerSec);
        }
        NdisMSetInformationComplete( (NDIS_HANDLE) device->hNdisAdapter, (NDIS_STATUS) status );

        device->LastSetTime.QuadPart = 0;

        device->fSetpending = FALSE;

    } else  */
	if ( CONTEXT_NDIS_PACKET == ContextType ) 
	{
        //
        //
        // Indicate to the protocol the status of the sent packet and return
        // ownership of the packet.
        //

        NdisMSendComplete(
                    device->hNdisAdapter,
                    pThisContextPacket,
                    status );

    }

    if (( STATUS_SUCCESS != status )  && ( STATUS_CANCELLED != status )) 
	{
        InterlockedExchange( (PLONG) &device->fPendingWriteClearStall, TRUE );

        ScheduleWorkItem( device,
          ResetPipeCallback, device->BulkOutPipeHandle, 0);
    }
    return STATUS_MORE_PROCESSING_REQUIRED;
}


BOOLEAN
NdisToUsbPacket(
            PUSB_DEVICE   Device,
            PVOID        pPack,
            UCHAR        *usbPacketBuf,
            UINT         usbPacketBufLen
            )
{
    UINT i;
    UINT ndisPacketBytes;
    UINT totalBytes;
    UINT ndisPacketLen;
    UINT bufLen;
    UCHAR *bufData;
    UCHAR nextChar;

    PNDIS_BUFFER ndisBuf;
    PNDIS_PACKET    pPacket = (PNDIS_PACKET) pPack;


    DEBUGMSG(DBG_FUNC, ("+NdisToUsbPacket input packet:\n"));

    //
    // Initialize locals.
    //
     //Beginning of Frame
   // Device->OutBoundHeader  = 0;  // this translates to 'no change ' of either link speed or BOFS
    ndisPacketBytes = 0;
   
    totalBytes      = 0;

    //
    // Get the packet's entire length and its first NDIS buffer.
    //
    NdisQueryPacket(pPacket, NULL, NULL, &ndisBuf, &ndisPacketLen);

    // A zero-legth packet is OK; we may just get the one-byte inbound header
    //  to report media busy!
    if ( ndisPacketLen > 0 )
    {

    //
    // But if the packet is not 0-len, it must have at least Addr and Control fields
    // Make sure that the packet is big enough to be legal.
    // It consists of an A, C, and variable-length I field.
    //
        if (ndisPacketLen < 20 )//IP head length
        {
            DEBUGMSG(DBG_ERR, ("Packet too short in NdisToUsbPacket (%d bytes)\n",
                    ndisPacketLen));

            return FALSE;
        }
      
    }

    //
    // Make sure that we won't overwrite our contiguous buffer.
    // Make sure that the passed-in buffer can accomodate this packet's data
    //

    if (ndisPacketLen > MAX_PACKET_SIZE)
    {
        //
        // The packet is too large
        // Tell the caller to retry with a packet size large
        // enough to get past this stage next time.
        //

        DEBUGMSG(DBG_ERR, ("Packet too large in NdisToUsbPacket (%d=%xh bytes), \n"
                "usbPacketBufLen=%d.",
                 ndisPacketLen, ndisPacketLen, usbPacketBufLen));

        return FALSE;
    }

    if (!ndisBuf)
    {
        DEBUGMSG(DBG_ERR, ("No NDIS_BUFFER in NdisToUsbPacket\n"));
        return FALSE;
    }
    
    NdisQueryBuffer(ndisBuf, (PVOID *)&bufData, &bufLen);
 
    //
    // Now begin building the USB frame.
    //
    // This is the final format:
    //
    //     FIRST BYTE low byte ethernet packet length     (1)
    //     SECOND BYTE 
    //     NdisMedium packet (what we get from NDIS):
    //     Ethernet packet
    //         
    
    
    usbPacketBuf[0] =(UCHAR) ((ndisPacketLen) & 0x000000FF);
   // DEBUGMSG(DBG_ERR, ("usbPacketBuf[0]="d% bytes), \n",usbPacketBuf[0]);
	
    usbPacketBuf[1] =(UCHAR) (((ndisPacketLen) & 0x0000FF00)/0x100);
    //DEBUGMSG(DBG_ERR, ("usbPacketBuf[1]="d% bytes), \n",usbPacketBuf[1]);

	totalBytes = USB_PACKET_LENGTH;  // USB_HEADER_SIZE is just two byte

    for (i=0; i<ndisPacketLen; i++)
    {
        ASSERT(bufData);

        nextChar = *bufData++;

        usbPacketBuf[totalBytes++] = nextChar; 

        if (--bufLen==0)
        {
            NdisGetNextBuffer(ndisBuf, &ndisBuf);
            if (ndisBuf)
            {
                NdisQueryBuffer(ndisBuf, (PVOID *)&bufData, &bufLen);
            }
            else
            {
                bufData = NULL;
            }
        }

    }

    if ((bufData!=NULL) && ndisPacketLen )
    {
        /*
         *  Packet was corrupt -- it misreported its size.
         */
        DEBUGMSG(DBG_ERR, ("Packet corrupt in NdisToUsbPacket (buffer lengths don't add up to packet length)."));
        return FALSE;
    }


    DEBUGMSG(DBG_FUNC, ("-NdisToUsbPacket converted %d-byte ndis pkt to %d-byte irda pkt to send\n", ndisPacketLen, totalBytes));

    DEBUGMSG(DBG_BUF, ("SENDING:")); 
    USB_DUMP( DBG_BUF, (usbPacketBuf,   totalBytes ) );

    return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -