buslogic958.c

来自「这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统」· C语言 代码 · 共 1,558 行 · 第 1/5 页

C
1,558
字号
/*
 * vmscsi-- Miniport driver for the Buslogic BT 958 SCSI Controller 
 *          under Windows 2000/XP/Server 2003
 *
 *          Based in parts on the buslogic driver for the same device
 *          available with the GNU Linux Operating System.
 *          
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

//____________________________________________________________________________________
//
// File description :The driver for BusLogic-BT958 SCSI Host adapter card.
// This driver assumes that the host adapter(HA from now on) is a PCI device.
// This is an effort to build a driver for this card for the windows XP ennvironment
// since the native XP installation doesnt provide this driver.
//
// The technical refernece for this device is at :
//
// Author: Namita Lal, Sirish Raghuram Calsoft Pvt Ltd
// Date:   5th Feb 2003
// Status: Driver version 1.2.0.0
//         Performance tuned
//         Correctness tested for
//            1. Installation at OS install time
//            2. Installation in an installed OS
//            3. Installation by upgrading a previous version
//         on all flavours of WinXP and Win Server 2003
//         For Win2k however, please refer PR 22812
/*
Revision History: 
v1.0.0.4  // Pre final release to VMware in Sep 2001, without WMI
    |
    |
    v
v1.0.0.5  // Sep 2001 release to VMware, with WMI
    |
    |
    v
v1.0.0.6  // Fix for bug with Nero Burning ROM in XP
    |     // where SCSI_AUTO_SENSE is turned off at times
    |
    |
    |---------> v1.1.0.0    // Performance optimizations:
    |           |           // A. WMI disabled, B. Queueing depth increased
    |           |           // C. Control flow changed (bug)
    |           |
    |           v
    |       v1.1.0.1    // Fix for .NET restart freeze with 1.1.0.0
    |                   // Breaks on XP
    |
    v
v1.2.0.0  // A. WMI disabled, B. Queueing depth increased
    |
    |
    |
    v
v1.2.0.1  // Fix PR 40284, affects pure ACPI Win2k systems.
    |
    |
    |
    v
v1.2.0.2  // Fix PR 40284 correctly, disable interrupts in the initialization routine.
          // CURRENT VERSION
*/
//____________________________________________________________________________________

#include "BusLogic958.h"

ULONG
STDCALL
DriverEntry(IN PVOID DriverObject,
            IN PVOID Argument2
           )
//_________________________________________________________________________
// Routine Description:
//              Installable driver initialization entry point for system.
// Arguments:
//              Driver Object
// Return Value:
//              Status from ScsiPortInitialize()
//_________________________________________________________________________
{
    HW_INITIALIZATION_DATA hwInitializationData;
    ULONG Status;
    ULONG i;
    ULONG HwContext;
//    static int    cardNo = 0;

    UCHAR VendorId[4] = { '1', '0', '4', 'b'        };
    UCHAR DeviceId[4] = { '1', '0', '4', '0'        };

    DebugPrint((TRACE,"\n BusLogic -  Inside the DriverEntry function \n"));

    // Zero out structure. 
    for (i = 0; i < sizeof(HW_INITIALIZATION_DATA); i++) 
    {
        ((PUCHAR) & hwInitializationData)[i] = 0;
    }

    // Set size of hwInitializationData. 
    hwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);

    // Set entry points. 
    hwInitializationData.HwInitialize =     BT958HwInitialize;
    hwInitializationData.HwResetBus =       BT958HwResetBus;
    hwInitializationData.HwStartIo =        BT958HwStartIO;
    hwInitializationData.HwInterrupt =      BT958HwInterrupt;
    hwInitializationData.HwAdapterControl = BT958HwAdapterControl;
    hwInitializationData.HwFindAdapter =    BT958HwFindAdapter;

    // Inidicate no buffer mapping but will need physical addresses
    hwInitializationData.NeedPhysicalAddresses = TRUE;
    
    // Indicate Auto request sense is supported
    hwInitializationData.AutoRequestSense = TRUE;
    hwInitializationData.MultipleRequestPerLu = TRUE;

#if TAG_QUEUING
    hwInitializationData.TaggedQueuing = TRUE;
#else
    hwInitializationData.TaggedQueuing = FALSE;
#endif
        
    hwInitializationData.AdapterInterfaceType = PCIBus;

    // Fill in the vendor id and the device id
    hwInitializationData.VendorId = &VendorId;
    hwInitializationData.VendorIdLength = 4;
    hwInitializationData.DeviceId = &DeviceId;
    hwInitializationData.DeviceIdLength = 4;
    

    hwInitializationData.NumberOfAccessRanges = 2;


    // Specify size of extensions. 
    hwInitializationData.DeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION);

    // logical unit extension 
    hwInitializationData.SrbExtensionSize = sizeof(BusLogic_CCB_T);

    HwContext = 0;

    DebugPrint((TRACE,"\n BusLogic -  Calling the ScsiPortInitialize Routine\n"));

    Status = ScsiPortInitialize(DriverObject,
                                Argument2,
                                &hwInitializationData, 
                                &HwContext);

    DebugPrint((TRACE,"\n BusLogic -  Exiting the DriverEntry function \n"));
    DebugPrint((INFO,"\n BusLogic - Status = %ul \n", Status));
    return( Status );

} // end DriverEntry() 


ULONG
STDCALL
BT958HwFindAdapter(IN PVOID HwDeviceExtension,
                   IN PVOID Context,
                   IN PVOID BusInformation,
                   IN PCHAR ArgumentString,
                   IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
                   OUT PBOOLEAN  Again
                  )
//_________________________________________________________________________________________________
// Routine Description:
//              This function is called by the OS-specific port driver after the necessary storage 
//              has been allocated, to gather information about the adapter's configuration.
//
// Arguments:
//              HwDeviceExtension - HBA miniport driver's adapter data storage
//              Context - Register base address
//              ConfigInfo - Configuration information structure describing HBA
//              This structure is defined in PORT.H.
//
// Return Value:
//              HwScsiFindAdapter must return one of the following status values:
//              SP_RETURN_FOUND: Indicates a supported HBA was found and that the HBA-relevant 
//                               configuration information was successfully determined and set in 
//                               the PORT_CONFIGURATION_INFORMATION structure. 
//              SP_RETURN_ERROR: Indicates an HBA was found but there was error obtaining the 
//                               configuration information. If possible, such an error should be 
//                               logged with ScsiPortLogError. 
//              SP_RETURN_BAD_CONFIG: Indicates the supplied configuration information was invalid 
//                                    for the adapter. 
//              SP_RETURN_NOT_FOUND: Indicates no supported HBA was found for the supplied 
//                                   configuration information. 
//________________________________________________________________________________________________
{
    PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
    BusLogic_HostAdapter_T *hcsp = &(deviceExtension->hcs);
//    static UCHAR k = 0;
    PACCESS_RANGE   accessRange;
//    PCI_COMMON_CONFIG PCICommonConfig;
    PUCHAR   pciAddress, portFound;
    char    NumPort = 0;

    DebugPrint((TRACE,"\n BusLogic -  Inside the Find Adapter Routine\n"));

    *Again = FALSE;

    accessRange = &((*(ConfigInfo->AccessRanges))[0]);

    // Inform SCSIPORT that we are NOT a WMI data provider 
    // Sirish, 10th June 2002
    ConfigInfo->WmiDataProvider = FALSE;
    /*Sirish, 10th June 2002 BT958WmiInitialize(deviceExtension);*/

    // Check for configuration information passed in form the system
    if ((*ConfigInfo->AccessRanges)[0].RangeLength != 0) 
    {
        // check if the system supplied bus-relative address is valid and has not been
        // claimed by anyother device
        if ( ScsiPortValidateRange(deviceExtension,
                                   ConfigInfo->AdapterInterfaceType,
                                   ConfigInfo->SystemIoBusNumber,
                                   accessRange->RangeStart,
                                   accessRange->RangeLength,
                                   TRUE) )  // TRUE: iniospace  
        {
            DebugPrint((INFO,"\n BusLogic - Validate Range function succeeded \n"));

            // Map the Bus-relative range addresses to system-space logical range addresses
            // so that these mapped logical addresses can be called with SciPortRead/Writexxx 
            // to determine whether the adapter is an HBA that the driver supports

            pciAddress = (PUCHAR) ScsiPortGetDeviceBase(deviceExtension,
                                                       ConfigInfo->AdapterInterfaceType,
                                                       ConfigInfo->SystemIoBusNumber,
                                                       accessRange->RangeStart,
                                                       accessRange->RangeLength,
                                                       TRUE);  // TRUE: iniospace 

            if(pciAddress)
            {
                DebugPrint((INFO,"\n BusLogic -  Get Device Base  function succeeded \n"));

                memset(hcsp, 0, sizeof(BusLogic_HostAdapter_T));

                // points to structure of type BT958_HA which has device specific information. This needs
                // to be either changed or modified with our specific info.
                hcsp->IO_Address = pciAddress;
                hcsp->IRQ_Channel = (UCHAR)ConfigInfo->BusInterruptLevel;
                NumPort++;
            }
        }
    }

    if (NumPort == 0) 
    {
        return(SP_RETURN_NOT_FOUND);
    }

    //  Hardware found, let's find out hardware configuration
    //  and fill out ConfigInfo table for WinNT     
    ConfigInfo->NumberOfBuses = 1;
    ConfigInfo->MaximumTransferLength = MAX_TRANSFER_SIZE; 
    
#if SG_SUPPORT                                     
    ConfigInfo->ScatterGather = TRUE;
#else
    ConfigInfo->ScatterGather = FALSE;
#endif

    ConfigInfo->Master = TRUE;
    ConfigInfo->NeedPhysicalAddresses = TRUE;
    ConfigInfo->Dma32BitAddresses = TRUE;
    ConfigInfo->InterruptMode =  LevelSensitive;

#if TAG_QUEUING
    ConfigInfo->TaggedQueuing = TRUE;
#else
    ConfigInfo->TaggedQueuing = FALSE;
#endif

    // Should we change this to double-word aligned to increase performance
    ConfigInfo->AlignmentMask = 0x0;     
    
    portFound =     hcsp->IO_Address;

    if (!Buslogic_InitBT958(deviceExtension,ConfigInfo)) // harware specific initializations. Find what's for our card
    {
       ScsiPortLogError(deviceExtension,
                         NULL,
                         0,
                         0,
                         0,
                         SP_INTERNAL_ADAPTER_ERROR,
                         7 << 8);

       return(SP_RETURN_ERROR);
    }
    
    if (NumPort != 0)
        *Again = TRUE;

    return(SP_RETURN_FOUND);

⌨️ 快捷键说明

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