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

📄 pcielink.c

📁 PCI-Express Lane Test Utility. Validates negotiated lane capability registers, returns error codes,
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
   PCIELINK.EXE  Written by: Jeff Fabrizio, QLogic Corporation 
                                                                  
   Examine PCI Bus for PCIexpress device Lane Validations
   Supports PCI Express 2.1 Register offsets for VendorId & DeviceID
                          
   Device number is a combination of Device+Function where:
    device number   = bits [7:4]
    function number = bits [3:0] 
                          
   Link Capability Register values are programmable via the CFG file with device data 
   formatted as follows in decimal values:

     VendorId;DeviceId;RegMLW;msb;lsb;RegNLW;msb;lsb;RegNLS;msb;lsb

     RegMLW = Register Maximum Link Width
     RegNLW = Register Negotiated Link Width
     RegNLS = Register Negotiated Link Speed
     msb    = most significant bit offset
     lsb    = least significant bit offset                                                             

   PCIe Link Status Register at offset 5E bits 4:9 can be read to determine PCIe Negotiated Lane Width. 
   Link Width         Link Capability       Link Speed
   000001b = X1       000001b = X1          0001 = 2.5Gb/s
   000010b = X2       000010b = X2          0010 = 5.0Gb/s
   000100b = X4       000100b = X4
   001000b = X8       001000b = X8
   001100b = X12      001100b = X12
   010000b = X16      010000b = X16
   100000b = X32      100000b = X32   
   
   Reference Documentation
   PCISIG - PCI BIOS SPECIFICATION V2.1
   QLOGIC - FW SPEC 2400 Series Rev: D
                                                          
   Last Update: 06/29/07 11:05 jf V1.0 Initial release   
   Last Update: 07/02/07 16:43 jf V1.1 chg to AutoDetect by default
                                       only echo fail msgs when using /V  
                                       add /I=integer display option 
   Last Update: 09/12/07 11:46 jf V1.2 add ISP7432, ISP8432, ISP2532                                       
   Last Update: 03/24/08 16:04 jf V1.3 add sub-system vendor id and vendor id args, 
                                       add ISP6220, ISP7220                                    
                                       add /M0 /N0 /L0 where 0=ignore_test
   Last Update: 02/27/09 13:13 jf V2.0 rewrite as PCIELINK using absolute register values
                                       
*/

#include <stdio.h>
#include <dos.h>
#include <stdlib.h> 
#include <string.h>
#include <math.h> 
#include <ctype.h>

typedef unsigned char byte;  /* 8-bits */
typedef unsigned short word; /* 16-bits */ 
typedef unsigned long dword; /* 32-bits */   
typedef unsigned int UWORD;  // Unsigned word 0 to 65535.
typedef unsigned long ULONG; // Unsigned word 0 to 4294967295.
 
union _REGS inregs;  
union _REGS outregs; 

#define PCI_FUNCTION_ID   0xB1
#define FIND_PCI_DEVICE   0x02
#define ADAPTER_COUNT     16
#define SUCCESSFUL        0x00
#define BAD_VENDOR_ID     0x83
#define DEVICE_NOT_FOUND  0x86 

struct device_info
{
 unsigned char Bus_Number;
 unsigned char Device_Number;
 unsigned int  BaseAddress;
 ULONG flag;
};

UWORD   adapter_count;
struct  device_info  Device_Info_Array[ADAPTER_COUNT];
           
unsigned int shift=0;  //shift bit-string count
unsigned int mask=0;   //mask bit-string count
char trimStr[255];
char trimmedStr[255];      
char *result;

//int readCfg(unsigned int, unsigned int);
//void makeCfg(void); 
void trimSpace(char *, char *, int);        
void makeTxt(void);           
           
//if user specifies /Bus or /Device, use that specifically
//else run autodetect for ISP2432 and only run /Device=0 of each /Bus

int main(int argc, char *argv[])
{ 
 int i=0,rtnVal=0,echo=0,userBD=0,acount=0,tcount=0,doTest=0;  
 char *test="0",*test1="0",*sarg="0";
 char argv10[20]="0",argv11[20]="0",argv12[20]="0",emsg[80]="0",argVal[6]="0";
 char version[10]="(V2.0)";
 unsigned int count=0;
 unsigned int argv0=0;     //verbose mode 
 unsigned int argv1=0;     //default pci bus number
 unsigned int argv2=0;     //default pci device number
 unsigned int argv3=4;     //default max link width
 unsigned int argv4=4;     //default negotiate link width
 unsigned int argv5=1;     //default link speed 
 unsigned int argv6=9266;  //default device id
 unsigned int argv7=2;     //default 2=binary display, 10=integer display  
 unsigned int argv8=4215;  //default vendor id as QLogic
 unsigned int argv9=4215;  //default subsystem vendor id as QLogic 
 unsigned int argv10_r=88; //default maximum link width register
 unsigned int argv10_m=9;  //default maximum link width register offset most significant bit
 unsigned int argv10_l=4;  //default maximum link width register offset least significant bit
 unsigned int argv11_r=94; //default negotiate link width register
 unsigned int argv11_m=9;  //default negotiate link width register offset most significant bit
 unsigned int argv11_l=4;  //default negotiate link width register offset least significant bit
 unsigned int argv12_r=94; //default negotiate link speed register
 unsigned int argv12_m=3;  //default negotiate link speed register offset most significant bit
 unsigned int argv12_l=0;  //default negotiate link speed register offset least significant bit
 unsigned int tmpVal=0;    //used to shift and mask 16bit word from &outregs 
 unsigned int lssVal=0;    //used to format link speed value
 unsigned int venId=0;     //vendor id
 unsigned int venIdS=0;    //subsystem vendor id
              
                
 //set default argval10,11,12 
 strcpy(argv10,"88;9;4");
 strcpy(argv11,"94;9;4");
 strcpy(argv12,"94;3;0");
                   
 //make PCIELINK.TXT sample file
 makeTxt();                  
                   
 //loop thru argv[x] and set variables for calling arguments
 for(i=1;i!=argc;i++)
 {
  sarg=strtok(argv[i],"/");
  if(i==1 && !strcmp(sarg,"?"))
  {
   printf("\n");
   printf("Verify PCIexpress Link Capability Registers %s\n",version);    
   printf("PCIELINK [options]\n");
   printf(" /I vendorId (0-65535)                            (default=4215)\n");
   printf(" /A deviceId (0-65535) ignored if using /B or /D  (default=9266)\n");
   printf(" /B PCI Bus Number (0-15)                         (default=AutoDetect)\n"); 
   printf(" /D PCI Device+Function Number (0-63)             (default=AutoDetect)\n"); 
   printf(" /E PCI Maximum Link Width Register;MSB;LSB       (default=88;9;4)\n");
   printf(" /F PCI Negotiated Link Width Register;MSB;LSB    (default=94;9;4)\n");
   printf(" /G PCI Negotiated Link Speed Register;MSB;LSB    (default=94;3;0)\n");      
   printf(" /M PCI Maximum Link Width   1,2,4,8,12,16,32     (default=4)\n");
   printf(" /N PCI Negotiate Link Width 1,2,4,8,12,16,32     (default=4)\n");
   printf(" /L PCI Link Speed Gb/s 0=Ignore 1=2.5, 2=5.0     (default=1)\n"); 
   printf(" /S Sub-system Vendor ID (0-65535)                (default=4215)\n");
   printf(" /H Display hexidecimal results (requires /V)     (default=binary)\n"); 
   printf(" /V Verbose display\n"); 
   printf(" /R Show Return Codes\n\n\n");
   printf("Uses 16bit Register /E /F /G, apply Register offset for MSB;LSB of 16-32\n");
   printf("AutoDetect mode of (/B and /D) will test for DEVICE=0 on all BUSSES\n\n");  
   return 1;                                   
  }
  if(i==1 && (!strcmp(sarg,"r") || !strcmp(sarg,"R")))
  { 
   printf("\n");
   printf("Verify PCIexpress Link Negotiation Parameters %s\n",version);    
   printf(" Return codes:\n");
   printf("  0 = Pass\n");
   printf("  1 = Fail, no adapter found at Bus\n");    
   printf("  2 = Fail, no adapter found at Device\n");
   printf("  3 = Fail, Maximum_Link_Width\n");  
   printf("  4 = Fail, Negotiate_Link_Width\n");  
   printf("  5 = Fail, Link_Speed\n");  
   printf("  6 = Fail, Invalid QLogic PCIexpress ASIC\n");  
   printf("  7 = Fail, Invalid Vendor ID\n");
   printf("  8 = Fail, Subsystem Vendor ID\n");
   printf("  9 = Fail, Invalid Maximum Link Width Register\n");
   printf(" 10 = Fail, Invalid Negotiate Link Width Register\n");
   printf(" 11 = Fail, Invalid Negotiate Link Speed Register\n");
   return 1;
  }
  //get bus number
  if(!strncmp(sarg,"B",1)|| !strncmp(sarg,"b",1))
  {  
   userBD=1; //set flag user forced bus           
   strncpy(argVal,sarg,1);   //get 1st char after /, dont know if lower or upper
   sarg=strtok(sarg,argVal); //split by first char and ignore char case
   argv1=atoi(sarg);
   if(argv1>=16) argv1=4;  //reset to default val if user selects invalid bus number  
   continue;
  }

  //get device number
  if(!strncmp(sarg,"D",1)||!strncmp(sarg,"d",1))
  {        
   userBD=2; //set flag user forced device
   strncpy(argVal,sarg,1);
   sarg=strtok(sarg,argVal);
   argv2=atoi(sarg);
   continue;
  }
 
  //get max link width
  if(!strncmp(sarg,"M",1)||!strncmp(sarg,"m",1))
  {  
   strncpy(argVal,sarg,1);
   sarg=strtok(sarg,argVal);
   argv3=atoi(sarg);
   continue;
  }
 
  //get negotiate link width
  if(!strncmp(sarg,"N",1)||!strncmp(sarg,"n",1))
  {  
   strncpy(argVal,sarg,1);
   sarg=strtok(sarg,argVal);
   argv4=atoi(sarg);
   continue;
  }

  //get bus link speed
  if(!strncmp(sarg,"L",1)||!strncmp(sarg,"l",1))
  {  
   strncpy(argVal,sarg,1);
   sarg=strtok(sarg,argVal);
   argv5=atoi(sarg);
   continue;
  }     

  //get device id number
  if(!strncmp(sarg,"A",1)||!strncmp(sarg,"a",1))
  {  
   strncpy(argVal,sarg,1);
   sarg=strtok(sarg,argVal);
   argv6=atoi(sarg);
   continue;
  }
  
  //get vendor ID number offset 00h
  if(!strncmp(sarg,"I",1)||!strncmp(sarg,"i",1))
  {  
   strncpy(argVal,sarg,1);
   sarg=strtok(sarg,argVal);
   argv8=atoi(sarg);
   continue;
  }

  //get subsystem vendor ID number offset 2Ch
  if(!strncmp(sarg,"S",1)||!strncmp(sarg,"s",1))
  {  
   strncpy(argVal,sarg,1);
   sarg=strtok(sarg,argVal);
   argv9=atoi(sarg);
   continue;
  }
     
  //verbose mode
  if(!strncmp(sarg,"V",1)||!strncmp(sarg,"v",1)) argv0=1;

  //display mode integer 
  if(!strncmp(sarg,"H",1)||!strncmp(sarg,"h",1)) argv7=10;
                                                           
  //get maximum link width register;msb;lsb
  if(!strncmp(sarg,"E",1)||!strncmp(sarg,"e",1)) 
  {
   strncpy(argVal,sarg,1);
   sarg=strtok(sarg,argVal);
   strcpy(argv10,sarg);
   continue;
  }                                                           

  //get negotiated link width register;msb;lsb
  if(!strncmp(sarg,"F",1)||!strncmp(sarg,"f",1)) 
  {
   strncpy(argVal,sarg,1);
   sarg=strtok(sarg,argVal);
   strcpy(argv11,sarg);
   continue;
  }                                                           

  //get negotiated link speed register;msb;lsb
  if(!strncmp(sarg,"G",1)||!strncmp(sarg,"g",1)) 
  {
   strncpy(argVal,sarg,1);
   sarg=strtok(sarg,argVal);
   strcpy(argv12,sarg);
   continue;
  }                                                           
 }
 
 //check verbose mode
 if(argv0) echo=1;
  
 //check Bus
 strcpy(emsg,"Invalid Bus Number!\n"); 
 switch (argv1) 
 {
  case 0: case 1: case 2: case 3: 
  case 4: case 5: case 6: case 7:
  case 8: case 9: case 10: case 11:
  case 12: case 13: case 14: case 15:
  case 16:
  break;
  default:
  if(echo) printf(emsg);
  rtnVal=1;                        
  break;
 }

 //check device + function
 strcpy(emsg,"Invalid Device Number!\n"); 
 if(argv2<0||argv2>63)
 {
  if(echo) printf(emsg);
  rtnVal=2;
 } 

 //check max_link_width
 strcpy(emsg,"Invalid Max Link Width!\n"); 
 switch (argv3) 
 {
  case 0: case 1: case 2: case 4: case 8:
  case 12: case 16: case 32: 
  break;
  default:
  if(echo) printf(emsg);
  rtnVal=3;
  break;
 } 

 //check negotiate_link_width
 strcpy(emsg,"Invalid Negotiate Link Width!\n"); 
 switch (argv4) 
 {
  case 0: case 1: case 2: case 4: case 8:
  case 12: case 16: case 32: 
  break;
  default:
  if(echo) printf(emsg);
  rtnVal=4;
  break;
 } 

 //check link_speed
 strcpy(emsg,"Invalid Link Speed!\n"); 
 switch (argv5) 
 {
  case 0: case 1: case 2:
  break;
  default:
  if(echo) printf(emsg);
  rtnVal=5;
  break;
 } 

 //check maximum link width register
 strcpy(emsg,"Invalid Maximum Link Width Register!\n");
 result=strtok(argv10,";");
 argv10_r=atoi(result);
 if(argv10_r<1||argv10_r>255)
 {
  if(echo) printf(emsg);
  rtnVal=9;
 }

 //check maximum link width register msb
 strcpy(emsg,"Invalid Maximum Link Width Register MSB!\n");
 result=strtok(NULL,";");
 argv10_m=atoi(result);
 if(argv10_m<0||argv10_m>32)
 {
  if(echo) printf(emsg);
  rtnVal=9;
 }

 //check maximum link width register lsb
 strcpy(emsg,"Invalid Maximum Link Width Register LSB!\n");
 result=strtok(NULL,";");
 argv10_l=atoi(result);
 if(argv10_l<0||argv10_l>32||argv10_l>=argv10_m)
 {
  if(echo) printf(emsg);
  rtnVal=9;
 }

 //check negotiate link width register
 strcpy(emsg,"Invalid Negotiate Link Width Register!\n");
 result=strtok(argv11,";");

⌨️ 快捷键说明

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