cpqfctsinit.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 2,099 行 · 第 1/5 页

C
2,099
字号
  static char buf[300];  CPQFCHBA *cpqfcHBA;  int BusSpeed, BusWidth;    // get the pointer to our Scsi layer HBA buffer    cpqfcHBA = (CPQFCHBA *)HostAdapter->hostdata;  BusWidth = (cpqfcHBA->fcChip.Registers.PCIMCTR &0x4) > 0 ?               64 : 32;  if( cpqfcHBA->fcChip.Registers.TYconfig.value & 0x80000000)    BusSpeed = 66;  else    BusSpeed = 33;  sprintf(buf, "%s: WWN %08X%08X\n on PCI bus %d device 0x%02x irq %d IObaseL 0x%x, MEMBASE 0x%x\nPCI bus width %d bits, bus speed %d MHz\nFCP-SCSI Driver v%d.%d.%d",      cpqfcHBA->fcChip.Name,       cpqfcHBA->fcChip.Registers.wwn_hi,      cpqfcHBA->fcChip.Registers.wwn_lo,      cpqfcHBA->PciDev->bus->number,      cpqfcHBA->PciDev->device,        HostAdapter->irq,      cpqfcHBA->fcChip.Registers.IOBaseL,      cpqfcHBA->fcChip.Registers.MemBase,      BusWidth,      BusSpeed,      VER_MAJOR, VER_MINOR, VER_SUBMINOR);    cpqfcTSDecodeGBICtype( &cpqfcHBA->fcChip, &buf[ strlen(buf)]);  cpqfcTSGetLPSM( &cpqfcHBA->fcChip, &buf[ strlen(buf)]);  return buf;}//// /proc/scsi support. The following routines allow us to do 'normal'// sprintf like calls to return the currently requested piece (buflenght// chars, starting at bufoffset) of the file. Although procfs allows for// a 1 Kb bytes overflow after te supplied buffer, I consider it bad // programming to use it to make programming a little simpler. This piece// of coding is borrowed from ncr53c8xx.c with some modifications //struct info_str{        char *buffer;			// Pointer to output buffer        int buflength;			// It's length        int bufoffset;			// File offset corresponding with buf[0]	int buffillen;			// Current filled length         int filpos;			// Current file offset};static void copy_mem_info(struct info_str *info, char *data, int datalen){  if (info->filpos < info->bufoffset) {	// Current offset before buffer offset    if (info->filpos + datalen <= info->bufoffset) {      info->filpos += datalen; 		// Discard if completely before buffer      return;    } else {				// Partial copy, set to begin      data += (info->bufoffset - info->filpos);      datalen  -= (info->bufoffset - info->filpos);      info->filpos = info->bufoffset;    }  }  info->filpos += datalen;		// Update current offset  if (info->buffillen == info->buflength) // Buffer full, discard    return;  if (info->buflength - info->buffillen < datalen)  // Overflows buffer ?    datalen = info->buflength - info->buffillen;  memcpy(info->buffer + info->buffillen, data, datalen);  info->buffillen += datalen;}static int copy_info(struct info_str *info, char *fmt, ...){        va_list args;        char buf[400];        int len;        va_start(args, fmt);        len = vsprintf(buf, fmt, args);        va_end(args);        copy_mem_info(info, buf, len);        return len;}// Routine to get data for /proc RAM filesystem//int cpqfcTS_proc_info (struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, 		       int inout){  struct scsi_cmnd *DumCmnd;  struct scsi_device *ScsiDev;  int Chan, Targ, i;  struct info_str info;  CPQFCHBA *cpqfcHBA;  PTACHYON fcChip;  PFC_LOGGEDIN_PORT pLoggedInPort;  char buf[81];  if (inout) return -EINVAL;  // get the pointer to our Scsi layer HBA buffer    cpqfcHBA = (CPQFCHBA *)host->hostdata;  fcChip = &cpqfcHBA->fcChip;    *start 	  = buffer;  info.buffer     = buffer;  info.buflength  = length;  info.bufoffset  = offset;  info.filpos     = 0;  info.buffillen  = 0;  copy_info(&info, "Driver version = %d.%d.%d", VER_MAJOR, VER_MINOR, VER_SUBMINOR);   cpqfcTSDecodeGBICtype( &cpqfcHBA->fcChip, &buf[0]);  cpqfcTSGetLPSM( &cpqfcHBA->fcChip, &buf[ strlen(buf)]);  copy_info(&info, "%s\n", buf); #define DISPLAY_WWN_INFO#ifdef DISPLAY_WWN_INFO  ScsiDev = scsi_get_host_dev (host);  if (!ScsiDev)     return -ENOMEM;  DumCmnd = scsi_get_command (ScsiDev, GFP_KERNEL);  if (!DumCmnd) {    scsi_free_host_dev (ScsiDev);    return -ENOMEM;  }  copy_info(&info, "WWN database: (\"port_id: 000000\" means disconnected)\n");  for ( Chan=0; Chan <= host->max_channel; Chan++) {    DumCmnd->device->channel = Chan;    for (Targ=0; Targ <= host->max_id; Targ++) {      DumCmnd->device->id = Targ;      if ((pLoggedInPort = fcFindLoggedInPort( fcChip,	    			DumCmnd,  // search Scsi Nexus    				0,        // DON'T search list for FC port id    				NULL,     // DON'T search list for FC WWN    				NULL))){   // DON'T care about end of list	copy_info(&info, "Host: scsi%d Channel: %02d TargetId: %02d -> WWN: ",			   host->host_no, Chan, Targ);        for( i=3; i>=0; i--)        // copy the LOGIN port's WWN          copy_info(&info, "%02X", pLoggedInPort->u.ucWWN[i]);        for( i=7; i>3; i--)             // copy the LOGIN port's WWN          copy_info(&info, "%02X", pLoggedInPort->u.ucWWN[i]);	copy_info(&info, " port_id: %06X\n", pLoggedInPort->port_id);       }    }  }  scsi_put_command (DumCmnd);  scsi_free_host_dev (ScsiDev);#endif    // Unfortunately, the proc_info buffer isn't big enough// for everything we would like...// For FC stats, compile this and turn off WWN stuff above  //#define DISPLAY_FC_STATS#ifdef DISPLAY_FC_STATS// get the Fibre Channel statistics  {    int DeltaSecs = (jiffies - cpqfcHBA->fcStatsTime) / HZ;    int days,hours,minutes,secs;        days = DeltaSecs / (3600*24); // days    hours = (DeltaSecs% (3600*24)) / 3600; // hours    minutes = (DeltaSecs%3600 /60); // minutes    secs =  DeltaSecs%60;  // secscopy_info( &info, "Fibre Channel Stats (time dd:hh:mm:ss %02u:%02u:%02u:%02u\n",      days, hours, minutes, secs);  }      cpqfcHBA->fcStatsTime = jiffies;  // (for next delta)  copy_info( &info, "  LinkUp           %9u     LinkDown      %u\n",        fcChip->fcStats.linkUp, fcChip->fcStats.linkDown);          copy_info( &info, "  Loss of Signal   %9u     Loss of Sync  %u\n",    fcChip->fcStats.LossofSignal, fcChip->fcStats.LossofSync);		    copy_info( &info, "  Discarded Frames %9u     Bad CRC Frame %u\n",    fcChip->fcStats.Dis_Frm, fcChip->fcStats.Bad_CRC);  copy_info( &info, "  TACH LinkFailTX  %9u     TACH LinkFailRX     %u\n",    fcChip->fcStats.linkFailTX, fcChip->fcStats.linkFailRX);    copy_info( &info, "  TACH RxEOFa      %9u     TACH Elastic Store  %u\n",    fcChip->fcStats.Rx_EOFa, fcChip->fcStats.e_stores);  copy_info( &info, "  BufferCreditWait %9uus   TACH FM Inits %u\n",    fcChip->fcStats.BB0_Timer*10, fcChip->fcStats.FMinits );	  copy_info( &info, "  FC-2 Timeouts    %9u     FC-2 Logouts  %u\n",    fcChip->fcStats.timeouts, fcChip->fcStats.logouts);           copy_info( &info, "  FC-2 Aborts      %9u     FC-4 Aborts   %u\n",    fcChip->fcStats.FC2aborted, fcChip->fcStats.FC4aborted);     // clear the counters  cpqfcTSClearLinkStatusCounters( fcChip);#endif	  return info.buffillen;}#if DEBUG_CMNDUCHAR *ScsiToAscii( UCHAR ScsiCommand){/*++Routine Description:   Converts a SCSI command to a text string for debugging purposes.Arguments:   ScsiCommand -- hex value SCSI CommandReturn Value:   An ASCII, null-terminated string if found, else returns NULL.Original code from M. McGowen, Compaq--*/   switch (ScsiCommand)   {      case 0x00:         return( "Test Unit Ready" );      case 0x01:         return( "Rezero Unit or Rewind" );      case 0x02:         return( "Request Block Address" );      case 0x03:         return( "Requese Sense" );      case 0x04:         return( "Format Unit" );      case 0x05:         return( "Read Block Limits" );      case 0x07:         return( "Reassign Blocks" );      case 0x08:         return( "Read (6)" );      case 0x0a:         return( "Write (6)" );      case 0x0b:         return( "Seek (6)" );      case 0x12:         return( "Inquiry" );      case 0x15:         return( "Mode Select (6)" );      case 0x16:         return( "Reserve" );      case 0x17:         return( "Release" );      case 0x1a:         return( "ModeSen(6)" );      case 0x1b:         return( "Start/Stop Unit" );      case 0x1c:         return( "Receive Diagnostic Results" );      case 0x1d:         return( "Send Diagnostic" );      case 0x25:         return( "Read Capacity" );      case 0x28:         return( "Read (10)" );      case 0x2a:         return( "Write (10)" );      case 0x2b:         return( "Seek (10)" );      case 0x2e:         return( "Write and Verify" );      case 0x2f:         return( "Verify" );      case 0x34:         return( "Pre-Fetch" );      case 0x35:         return( "Synchronize Cache" );      case 0x37:         return( "Read Defect Data (10)" );      case 0x3b:         return( "Write Buffer" );      case 0x3c:         return( "Read Buffer" );      case 0x3e:         return( "Read Long" );      case 0x3f:         return( "Write Long" );      case 0x41:         return( "Write Same" );      case 0x4c:         return( "Log Select" );      case 0x4d:         return( "Log Sense" );      case 0x56:         return( "Reserve (10)" );      case 0x57:         return( "Release (10)" );      case 0xa0:         return( "ReportLuns" );      case 0xb7:         return( "Read Defect Data (12)" );      case 0xca:         return( "Peripheral Device Addressing SCSI Passthrough" );      case 0xcb:         return( "Compaq Array Firmware Passthrough" );      default:         return( NULL );   }} // end ScsiToAscii()void cpqfcTS_print_scsi_cmd(Scsi_Cmnd * cmd){printk("cpqfcTS: (%s) chnl 0x%02x, trgt = 0x%02x, lun = 0x%02x, cmd_len = 0x%02x\n",     ScsiToAscii( cmd->cmnd[0]), cmd->channel, cmd->target, cmd->lun, cmd->cmd_len);if( cmd->cmnd[0] == 0)   // Test Unit Ready?{  int i;  printk("Cmnd->request_bufflen = 0x%X, ->use_sg = %d, ->bufflen = %d\n",    cmd->request_bufflen, cmd->use_sg, cmd->bufflen);  printk("Cmnd->request_buffer = %p, ->sglist_len = %d, ->buffer = %p\n",    cmd->request_buffer, cmd->sglist_len, cmd->buffer);  for (i = 0; i < cmd->cmd_len; i++)    printk("0x%02x ", cmd->cmnd[i]);  printk("\n");}}#endif				/* DEBUG_CMND */static void QueCmndOnBoardLock( CPQFCHBA *cpqfcHBAdata, Scsi_Cmnd *Cmnd){  int i;  for( i=0; i< CPQFCTS_REQ_QUEUE_LEN; i++)  {    // find spare slot    if( cpqfcHBAdata->BoardLockCmnd[i] == NULL )    {      cpqfcHBAdata->BoardLockCmnd[i] = Cmnd;//      printk(" BoardLockCmnd[%d] %p Queued, chnl/target/lun %d/%d/%d\n",//        i,Cmnd, Cmnd->channel, Cmnd->target, Cmnd->lun);      break;    }  }  if( i >= CPQFCTS_REQ_QUEUE_LEN)  {    printk(" cpqfcTS WARNING: Lost Cmnd %p on BoardLock Q full!", Cmnd);  }}static void QueLinkDownCmnd( CPQFCHBA *cpqfcHBAdata, Scsi_Cmnd *Cmnd){

⌨️ 快捷键说明

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