Source Code (Use browser search to find items of interest.)

Class Index

ksysctrl'SCSIScanner (./kdeadmin/ksysctrl/ksysctrl/scsiscanner.h:30)

class SCSIScanner : public DeviceScanner
{
  public:
  
    SCSIScanner(bool rescan);
    ~SCSIScanner();
    
    virtual Device  *firstDevice();
    virtual Device  *nextDevice();
    
  private:
  
    FILE        *_scsifhd;
    int         _diskcount, _cdromcount;
    
    SCSIDevice  *device();
    void        rescanBus();
};


ksysctrl'SCSIScanner::SCSIScanner() (./kdeadmin/ksysctrl/ksysctrl/scsiscanner.cpp:33)

SCSIScanner::SCSIScanner(bool rescan)
{
  if (rescan && !getuid()) rescanBus();
  
  _scsifhd = fopen("/proc/scsi/scsi", "r");
  
  if (!_scsifhd) cerr << "No SCSI driver present" << endl;
}



ksysctrl'SCSIScanner::~SCSIScanner() (./kdeadmin/ksysctrl/ksysctrl/scsiscanner.cpp:43)

SCSIScanner::~SCSIScanner()
{
  if (_scsifhd) fclose(_scsifhd);
}


/*
 * Public methods
 *****************/
 

ksysctrl'SCSIScanner::firstDevice() (./kdeadmin/ksysctrl/ksysctrl/scsiscanner.cpp:53)

Device  *SCSIScanner::firstDevice()
{
  if (_scsifhd)
  {
    _diskcount = _cdromcount = 0;
  
    fseek(_scsifhd, 0, SEEK_SET);       
    return device();
  }
  
  return 0L;
}



ksysctrl'SCSIScanner::nextDevice() (./kdeadmin/ksysctrl/ksysctrl/scsiscanner.cpp:67)

Device  *SCSIScanner::nextDevice()
{
  if (_scsifhd) return device();
  
  return 0L;
}


/*
 * Private methods
 ******************/


ksysctrl'SCSIScanner::device() (./kdeadmin/ksysctrl/ksysctrl/scsiscanner.cpp:79)

SCSIDevice  *SCSIScanner::device()
{
  QString               scsiline, vendorname, modelname;
  QString               typestr, devstr;
  char                  buffer[256];
  uint                  pos;
  uint                  channel, id, lun, firm;
  DriveInfo::drivetype  drvtype;
  
  while (fgets(buffer, sizeof(buffer), _scsifhd))
  {
    scsiline = QString(buffer).simplifyWhiteSpace();
    
    if (scsiline.left(5) == "Host:")
    {
      pos = scsiline.find("Channel:");
      
      if (pos >= 0)
      {
        scsiline = scsiline.right(scsiline.length()-pos).simplifyWhiteSpace();	
	sscanf(scsiline.data(), "Channel: %02i Id: %02i Lun: %02i", &channel, &id, &lun);
      }
    }
    else if (scsiline.left(7) == "Vendor:")
    {
      scsiline = scsiline.right(scsiline.length()-7).simplifyWhiteSpace();
      pos      = scsiline.find("Model:");
      
      if (pos >= 0)
      {
        vendorname = scsiline.left(pos-1).simplifyWhiteSpace();
	scsiline   = scsiline.right(scsiline.length()-pos-7).simplifyWhiteSpace();
	pos        = scsiline.find("Rev:");
	
	if (pos >= 0)
	{
	  modelname = scsiline.left(pos-1).simplifyWhiteSpace();
	  scsiline  = scsiline.right(scsiline.length()-pos-5).simplifyWhiteSpace();
	  sscanf(scsiline.data(), "%i", &firm);
	}
      }      
    }
    else if (scsiline.left(4) == "Type")
    {
      scsiline = scsiline.right(scsiline.length()-5);
      pos      = scsiline.find("ANSI SCSI revision:");
      
      if (pos >= 0)
      {
        typestr = scsiline.left(pos-1).simplifyWhiteSpace();
	
        if      (typestr == "Direct-Access") { drvtype = DriveInfo::DriveHD;    devstr.sprintf("sd%c",  'a'+_diskcount++);  }
        else if (typestr == "CD-ROM")        { drvtype = DriveInfo::DriveCDROM; devstr.sprintf("scd%c", '0'+_cdromcount++); }
        
        if (!devstr.isEmpty()) return new SCSIDrive(vendorname,  modelname, typestr, channel, id, lun, firm, new DriveInfo(devstr, drvtype));
        else                   return new SCSIDevice(vendorname, modelname, typestr, channel, id, lun, firm);
      }
    }
  }
  
  return 0L;
}



ksysctrl'SCSIScanner::rescanBus() (./kdeadmin/ksysctrl/ksysctrl/scsiscanner.cpp:143)

void  SCSIScanner::rescanBus()
{
  uint  numhosts = 0;	
  uint  numchs   = 1;			// Assume the simpliest setup for now!
  uint  numids   = 8;
  uint  numluns  = 1;
  uint  host, lun, ch, id;
  char  command[64];
  FILE  *scsifhd;  
  QDir  scsidir("/proc/scsi");
  
  if (!getuid())			// Must be root to do this
  {
    if (scsidir.exists())
    {
      scsidir.setFilter(QDir::Dirs);      
      numhosts = scsidir.count()-2;	// . and .. do not count
 
      if (numhosts >= 1)
      {
        cout << "Found " << numhosts << " host adapter(s)" << endl;
      
    	QProgressDialog  scsiprogdlg(i18n("Rescanning SCSI bus..."), i18n("Abort scan"),
    				     numhosts*numchs*numids*numluns, 0L,
    				     "scsiprogdlg", true);
 
    	scsiprogdlg.setCaption(i18n("SCSI bus rescan"));
    	scsiprogdlg.setMinimumDuration(0);
    	scsiprogdlg.setProgress(0);
 
    	for (host = 0; host < numhosts; host++)
    	{
    	  for (lun = 0; lun < numluns; lun++)
    	  {
    	    for (ch = 0; ch < numchs; ch++)
    	    {
    	      for (id = 0; id < numids; id++)
    	      {
    		scsiprogdlg.setProgress( host*numchs*numids*numluns
    					+lun *numids*numluns
    					+ch  *numluns
    					+id );
 
    		sprintf(command, "scsi remove-single-device %u %u %u %u", host, ch, id, lun);
 
    		if ((scsifhd = fopen("/proc/scsi/scsi", "w")))
    		{
    		  fwrite(command, sizeof(char), strlen(command)+1, scsifhd);
    		  fclose(scsifhd);
    		}
 
    		sprintf(command, "scsi add-single-device %u %u %u %u", host, ch, id, lun);
 
    		if ((scsifhd = fopen("/proc/scsi/scsi", "w")))
    		{
    		  fwrite(command, sizeof(char), strlen(command)+1, scsifhd);
    		  fclose(scsifhd);
    		}
 
    		if (scsiprogdlg.wasCancelled()) return;
    	      }
    	    }
    	  }
    	}
 
    	scsiprogdlg.setProgress(numhosts*numchs*numids*numluns);
      }
    }
  }
}