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

📄 usbaer.c

📁 usb驱动源代码。98的
💻 C
字号:
/*++

Copyright (c) 1999 Microsoft Corporation

Module Name:

    Usbaer.c 

Abstract:

    IOS port driver for USB LS-120 drive
    Async Event Handler module

Environment:

    kernel mode only

Notes:

  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  PURPOSE.

  Copyright (c) 1999 Microsoft Corporation.  All Rights Reserved.


Revision History:

    03/19/99: MRB  Original

--*/

#define WANTVXDWRAPS

#include <basedef.h>
#include <vmm.h>
#include <debug.h>
#include <vxdwraps.h>
#include <winerror.h>
#include <aep.h>
#include <drp.h>
#include <isp.h>
#include <ior.h>
#include <iop.h>
#include <dcb.h>
#include <ilb.h>
#include <configmg.h>
#include <ntkern.h>
#include "usbstor.h"
#include "usbdebug.h"

#pragma VxD_LOCKED_CODE_SEG
#pragma VxD_LOCKED_DATA_SEG

BYTE DcbCount=0;

void
USBSTOR_AER (
    PAEP Aep
    )
{
/*++

Routine Description:

    Asychronous event handler.

Arguments:

    Aep - Asychronous Event Packet.  Structure varies depending
          on AER type.

Return Value:

    Status returned in Aep->AEP_result

--*/

    USBSTOR_DebugPrintf(DBG_MAX, ("Enter USBSTOR_AER\n\r"));

    // presume success
    Aep->AEP_result = AEP_SUCCESS;

    switch (Aep->AEP_func)
    {
    case AEP_INITIALIZE:
        USBSTOR_DebugPrintf(DBG_MAX, ("AEP_INITIALIZE\n\r"));
	
        Aep->AEP_result = USBSTOR_AEP_Init((PAEP_bi_init)Aep);
        break;
		
    case AEP_UNINITIALIZE:
        USBSTOR_DebugPrintf(DBG_MAX, ("AEP_UNINITIALIZE\n\r"));
        break;

    case AEP_DEVICE_INQUIRY:
        USBSTOR_DebugPrintf(DBG_MAX, ("AEP_DEVICE_INQUIRY\n\r"));

        Aep->AEP_result = USBSTOR_Device_Inquiry((PAEP_inquiry_device)Aep);

        // Make sure we didn't record the inquiry DCB in our DDB.  If we did, 
        // erase it and decrement our DCB count.
        if (((PAEP_inquiry_device)Aep)->AEP_i_d_dcb == ((PUSBDDB)Aep->AEP_ddb)->Dcb1)
        {
                ((PUSBDDB)Aep->AEP_ddb)->Dcb1 = NULL;
                DcbCount--;
        }
        else if (((PAEP_inquiry_device)Aep)->AEP_i_d_dcb == ((PUSBDDB)Aep->AEP_ddb)->Dcb2)
        {
                ((PUSBDDB)Aep->AEP_ddb)->Dcb2 = NULL;
                DcbCount--;
        }
        break;

    case AEP_CONFIG_DCB:
        USBSTOR_DebugPrintf(DBG_MAX, ("AEP_CONFIG_DCB\n\r"));

        Aep->AEP_result = USBSTOR_Config_DCB((PAEP_dcb_config)Aep);

        if (AEP_SUCCESS == Aep->AEP_result)
        {
            // Store the DCB in our DDB
            if (((PUSBDDB)Aep->AEP_ddb)->Dcb1 == NULL)
            {
                ((PUSBDDB)Aep->AEP_ddb)->Dcb1 = ((PAEP_dcb_config)Aep)->AEP_d_c_dcb;
                DcbCount++;
            }
            else if (((PUSBDDB)Aep->AEP_ddb)->Dcb2 == NULL)
            {
                ((PUSBDDB)Aep->AEP_ddb)->Dcb2 = ((PAEP_dcb_config)Aep)->AEP_d_c_dcb;
                DcbCount++;
            }
            else
            {
                USBSTOR_DebugPrintf(DBG_MIN, ("ERROR! - Configured more DCBs than we expected\n\r"));
                USBSTOR_DebugPrintf(DBG_MIN, ("         This should not happen!\n\r"));
            }
        }
        break;

    case AEP_UNCONFIG_DCB:
        USBSTOR_DebugPrintf(DBG_MAX, ("AEP_UNCONFIG_DCB\n\r"));
    {
        DWORD pdcb = ((PAEP_dcb_unconfig)Aep)->AEP_d_u_dcb;
        PUSBDDB UsbDdb = (PUSBDDB)Aep->AEP_ddb;

        // Make sure it's our DCB
        if (UsbDdb->Dcb1 == pdcb)
        {
            //Zero out Dcb field
            UsbDdb->Dcb1 = NULL;
            DcbCount--;
        }
        else if (UsbDdb->Dcb2 == pdcb)
        {
            //Zero out Dcb field
            UsbDdb->Dcb2 = NULL;
            DcbCount--;
        }

    }
        break;

    case AEP_IOP_TIMEOUT:
        USBSTOR_DebugPrintf(DBG_MAX, ("AEP_IOP_TIMEOUT\n\r"));
        break;

    case AEP_1_SEC:
        USBSTOR_DebugPrintf(DBG_MAX, ("AEP_1_SEC\n\r"));
        break;

#ifdef DEBUG
    case AEP_DBG_DOT_CMD:
        USBSTOR_DebugPrintf(DBG_MAX, ("AEP_DBG_DOT_CMD\n\r"));
        break;
#endif

    case AEP_BOOT_COMPLETE:
        USBSTOR_DebugPrintf(DBG_MAX, ("AEP_BOOT_COMPLETE\n\r"));
        if (0 == DcbCount)
            Aep->AEP_result = AEP_FAILURE;
        break;

    default:
        USBSTOR_DebugPrintf(DBG_DEFAULT, ("Unhandled AEP - %x\n\r",Aep->AEP_func));
        Aep->AEP_result = AEP_FAILURE;
        break;

    } // end switch on AEP function

    return;

}


USHORT
USBSTOR_AEP_Init(
    PAEP_bi_init Aep
    )
{
/*++

Routine Description:

    Initialization routine.

Arguments:

    Aep - AEP_bi_init structure.  

Return Value:

    AEP_SUCCESS if successful,
    AEP_FAILURE otherwise

--*/


    DWORD          Pdo, Fdo=0;
    DEVNODE        ParentDevNode;
    ISP_ddb_create Isp;
    PUSBDDB        UsbDdb;

    // We need to find the FDO created by USBLS120.SYS for the USB storage
    // device.  This will be passed as a parameter to USBLS120.SYS when we
    // do I/O calls so it knows which device to talk to.

    // To identify the correct FDO, we call an exported function in 
    // USBLS120.SYS that enumerates each PDO/FDO pair attached to USBLS120.SYS.
    // We can then use an exported service from NTKERN.VXD to translate
    // the PDO to a DevNode handle, and compare it to our parent's DevNode
    // handle (we are loaded via a psuedo-child device created by USBLS120.SYS,
    // so our parent is the real USB device).
        		

    // First, get our parent's DevNode handle
    if (CM_Get_Parent(&ParentDevNode, (DEVNODE)Aep->AEP_bi_i_hdevnode, 0) != CR_SUCCESS)
    {
        USBSTOR_DebugPrintf(DBG_MIN, ("Can't find our parent DevNode!\n\r"));
        return AEP_FAILURE;
    }
		

    //Loop thru all the PDO/FDO pairs looking for a match to our parent DevNode
    while ((Pdo = pfnGetNextPdo(&Fdo)) && (_NtKernPhysicalDeviceObjectToDevNode(Pdo) != ParentDevNode));
    if (!Pdo)
    {
        USBSTOR_DebugPrintf(DBG_MIN, ("Can't PDO for our parent DevNode!\n\r"));
        return AEP_FAILURE;
    }


    // Found our PDO, so allocate our DDB
    Isp.ISP_ddb_hdr.ISP_func = ISP_CREATE_DDB;
    Isp.ISP_ddb_size = sizeof(USBDDB);
    Isp.ISP_ddb_flags = 0;

    ILBService(&Isp);

    if (Isp.ISP_ddb_hdr.ISP_result)
    {
        USBSTOR_DebugPrintf(DBG_MIN, ("Can't allocate DDB!\n\r"));
        return AEP_FAILURE;
    }

    UsbDdb = (PUSBDDB)(Isp.ISP_ddb_ptr);

    // Store pertinent information in our DDB.
    UsbDdb->Ddb.DDB_number_buses = 1;
    UsbDdb->Ddb.DDB_devnode_ptr = Aep->AEP_bi_i_hdevnode;
    UsbDdb->Fdo = Fdo;
    UsbDdb->Flags = 0;

    // Register our I/O completion handler with USBLS120.SYS
    pfnRegisterCompletionHandler(Fdo, USBSTOR_CompleteRequest);

    return AEP_SUCCESS;
}



USHORT
USBSTOR_Config_DCB(
    PAEP_dcb_config Aep
    )
{
/*++

Routine Description:

    Configuration handler for new DCBs.

Arguments:

    Aep - AEP_dcb_config structure.  

Return Value:

    Aep->AEP_result = AEP_SUCCESS if successful,
    Aep->AEP_result = AEP_FAILURE otherwise

--*/

    PDCB Dcb;
    ISP_calldown_insert Isp;


    Dcb = (PDCB)Aep->AEP_d_c_dcb;

    //Set maximum scatter gather elements to 17
    Dcb->DCB_max_sg_elements = 17;

    //Set max transfer size to 64k
    Dcb->DCB_max_xfer_len = 0x10000;

    // DCB_DEV2_IDE_FLOPTICAL is set specifically if we are a
    // LS-120 device.  This flag tells DISKVSD.VXD to special
    // handle this drive.  It causes the device type to change
    // from a hard-disk to a floppy.

    // This flag should only be set for LS-120 devices, as it
    // relies on capacity information being returned in the
    // vendor specific INQUIRY data, and assumes SFF-8070i
    // compatibility.   Devices that wish to appear as normal
    // hard-drives should *not* set the DCB_DEV2_IDE_FLOPTICAL
    // flag.

    Dcb->DCB_cmn.DCB_device_flags2 |= DCB_DEV2_ATAPI_DEVICE |
                                      DCB_DEV2_IDE_FLOPTICAL;

    // Insert ourselves into the calldown stack for this device
    Isp.ISP_i_cd_hdr.ISP_func = ISP_INSERT_CALLDOWN;
    Isp.ISP_i_cd_dcb = (ULONG)Dcb;         
    Isp.ISP_i_cd_req = USBSTOR_Request;     
    Isp.ISP_i_cd_expan_len = 0;             
    Isp.ISP_i_cd_lgn = Aep->AEP_d_c_hdr.AEP_lgn;      
    Isp.ISP_i_cd_ddb = (ULONG)Aep->AEP_d_c_hdr.AEP_ddb;        
    //BUGBUG - what are the correct flags for this device?
    Isp.ISP_i_cd_flags = DCB_dmd_srb_cdb |
                         DCB_dmd_pageability;

    // Call IOS
    ILBService(&Isp);

    return AEP_SUCCESS;
}

⌨️ 快捷键说明

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