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

📄 os_freebsd.cpp

📁 硬盘各项性能的测试,如温度容量版本健康度型号
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    ata->features = ATA_SMART_STATUS;    break;  case STATUS:    // This is JUST to see if SMART is enabled, by giving SMART status    // command. But it doesn't say if status was good, or failing.    // See below for the difference.    ata->features = ATA_SMART_STATUS;    break;  default:    pout("Unrecognized command %d in freebsd_3ware_command_interface(disk %d)\n"         "Please contact " PACKAGE_BUGREPORT "\n", command, disknum);    errno=ENOSYS;    return -1;  }  // Now send the command down through an ioctl()  if (escalade_type==CONTROLLER_3WARE_9000_CHAR) {#ifdef IOCATAREQUEST    ioctlreturn=ioctl(con->device,TW_OSL_IOCTL_FIRMWARE_PASS_THROUGH,cmd_twa);#else    ioctlreturn=ioctl(con->atacommand,TW_OSL_IOCTL_FIRMWARE_PASS_THROUGH,cmd_twa);#endif  } else {#ifdef IOCATAREQUEST    ioctlreturn=ioctl(con->device,TWEIO_COMMAND,cmd_twe);#else    ioctlreturn=ioctl(con->atacommand,TWEIO_COMMAND,cmd_twe);#endif  }  // Deal with the different error cases  if (ioctlreturn) {    if (!errno)      errno=EIO;    return -1;  }    // See if the ATA command failed.  Now that we have returned from  // the ioctl() call, if passthru is valid, then:  // - ata->status contains the 3ware controller STATUS  // - ata->command contains the ATA STATUS register  // - ata->features contains the ATA ERROR register  //  // Check bits 0 (error bit) and 5 (device fault) of the ATA STATUS  // If bit 0 (error bit) is set, then ATA ERROR register is valid.  // While we *might* decode the ATA ERROR register, at the moment it  // doesn't make much sense: we don't care in detail why the error  // happened.    if (ata->status || (ata->command & 0x21)) {    pout("Command failed, ata.status=(0x%2.2x), ata.command=(0x%2.2x), ata.flags=(0x%2.2x)\n",ata->status,ata->command,ata->flags);    errno=EIO;    return -1;  }    // If this is a read data command, copy data to output buffer  if (readdata) {    if (escalade_type==CONTROLLER_3WARE_9000_CHAR)      memcpy(data, cmd_twa->pdata, 512);  }  // For STATUS_CHECK, we need to check register values  if (command==STATUS_CHECK) {        // To find out if the SMART RETURN STATUS is good or failing, we    // need to examine the values of the Cylinder Low and Cylinder    // High Registers.        unsigned short cyl_lo=ata->cylinder_lo;    unsigned short cyl_hi=ata->cylinder_hi;        // If values in Cyl-LO and Cyl-HI are unchanged, SMART status is good.    if (cyl_lo==0x4F && cyl_hi==0xC2)      return 0;        // If values in Cyl-LO and Cyl-HI are as follows, SMART status is FAIL    if (cyl_lo==0xF4 && cyl_hi==0x2C)      return 1;          errno=EIO;      return -1;  }    // copy sector count register (one byte!) to return data  if (command==CHECK_POWER_MODE)    *data=*(char *)&(ata->sector_count);    // look for nonexistent devices/ports  if (command==IDENTIFY && !nonempty((unsigned char *)data, 512)) {    errno=ENODEV;    return -1;  }    return 0;}static int get_tw_channel_unit (const char* name, int* unit, int* dev) {  const char *p;  /* device node sanity check */  for (p = name + 3; *p; p++)    if (*p < '0' || *p > '9')      return -1;  if (strlen(name) > 4 && *(name + 3) == '0')    return -1;  if (dev != NULL)    *dev=atoi(name + 3);  /* no need for unit number */  if (unit != NULL)    *unit=0;  return 0;}#ifndef IOCATAREQUESTstatic int get_ata_channel_unit ( const char* name, int* unit, int* dev) {#ifndef ATAREQUEST  *dev=0;  *unit=0;return 0;#else  // there is no direct correlation between name 'ad0, ad1, ...' and  // channel/unit number.  So we need to iterate through the possible  // channels and check each unit to see if we match names  struct ata_cmd iocmd;  int fd,maxunit;    bzero(&iocmd, sizeof(struct ata_cmd));  if ((fd = open("/dev/ata", O_RDWR)) < 0)    return -errno;    iocmd.cmd = ATAGMAXCHANNEL;  if (ioctl(fd, IOCATA, &iocmd) < 0) {    return -errno;    close(fd);  }  maxunit = iocmd.u.maxchan;  for (*unit = 0; *unit < maxunit; (*unit)++) {    iocmd.channel = *unit;    iocmd.device = -1;    iocmd.cmd = ATAGPARM;    if (ioctl(fd, IOCATA, &iocmd) < 0) {      close(fd);      return -errno;    }    if (iocmd.u.param.type[0] && !strcmp(name,iocmd.u.param.name[0])) {      *dev = 0;      break;    }    if (iocmd.u.param.type[1] && !strcmp(name,iocmd.u.param.name[1])) {      *dev = 1;      break;    }  }  close(fd);  if (*unit == maxunit)    return -1;  else    return 0;#endif}#endif// Guess device type (ata or scsi) based on device name (FreeBSD// specific) SCSI device name in FreeBSD can be sd, sr, scd, st, nst,// osst, nosst and sg.static const char * fbsd_dev_prefix = "/dev/";static const char * fbsd_dev_ata_disk_prefix = "ad";static const char * fbsd_dev_scsi_disk_plus = "da";static const char * fbsd_dev_scsi_tape1 = "sa";static const char * fbsd_dev_scsi_tape2 = "nsa";static const char * fbsd_dev_scsi_tape3 = "esa";static const char * fbsd_dev_twe_ctrl = "twe";static const char * fbsd_dev_twa_ctrl = "twa";static const char * fbsd_dev_cciss = "ciss";static int parse_ata_chan_dev(const char * dev_name, struct freebsd_dev_channel *chan) {  int len;  int dev_prefix_len = strlen(fbsd_dev_prefix);    // if dev_name null, or string length zero  if (!dev_name || !(len = strlen(dev_name)))    return CONTROLLER_UNKNOWN;    // Remove the leading /dev/... if it's there  if (!strncmp(fbsd_dev_prefix, dev_name, dev_prefix_len)) {    if (len <= dev_prefix_len)       // if nothing else in the string, unrecognized      return CONTROLLER_UNKNOWN;    // else advance pointer to following characters    dev_name += dev_prefix_len;  }  // form /dev/ad* or ad*  if (!strncmp(fbsd_dev_ata_disk_prefix, dev_name,               strlen(fbsd_dev_ata_disk_prefix))) {#ifndef IOCATAREQUEST    if (chan != NULL) {      if (get_ata_channel_unit(dev_name,&(chan->channel),&(chan->device))<0) {        return CONTROLLER_UNKNOWN;      }    }#endif    return CONTROLLER_ATA;  }    // form /dev/da* or da*  if (!strncmp(fbsd_dev_scsi_disk_plus, dev_name,               strlen(fbsd_dev_scsi_disk_plus)))    goto handlescsi;  // form /dev/sa* or sa*  if (!strncmp(fbsd_dev_scsi_tape1, dev_name,              strlen(fbsd_dev_scsi_tape1)))    goto handlescsi;  // form /dev/nsa* or nsa*  if (!strncmp(fbsd_dev_scsi_tape2, dev_name,              strlen(fbsd_dev_scsi_tape2)))    goto handlescsi;  // form /dev/esa* or esa*  if (!strncmp(fbsd_dev_scsi_tape3, dev_name,              strlen(fbsd_dev_scsi_tape3)))    goto handlescsi;    if (!strncmp(fbsd_dev_twa_ctrl,dev_name,	       strlen(fbsd_dev_twa_ctrl))) {    if (chan != NULL) {      if (get_tw_channel_unit(dev_name,&(chan->channel),&(chan->device))<0) {	return CONTROLLER_UNKNOWN;      }    }    else if (get_tw_channel_unit(dev_name,NULL,NULL)<0) {	return CONTROLLER_UNKNOWN;    }    return CONTROLLER_3WARE_9000_CHAR;  }  if (!strncmp(fbsd_dev_twe_ctrl,dev_name,	       strlen(fbsd_dev_twe_ctrl))) {    if (chan != NULL) {      if (get_tw_channel_unit(dev_name,&(chan->channel),&(chan->device))<0) {	return CONTROLLER_UNKNOWN;      }    }    else if (get_tw_channel_unit(dev_name,NULL,NULL)<0) {	return CONTROLLER_UNKNOWN;    }    return CONTROLLER_3WARE_678K_CHAR;  }  // form /dev/ciss*  if (!strncmp(fbsd_dev_cciss, dev_name,               strlen(fbsd_dev_cciss)))    return CONTROLLER_CCISS;  // we failed to recognize any of the forms  return CONTROLLER_UNKNOWN; handlescsi:  if (chan != NULL) {    if (!(chan->devname = (char *)calloc(1,DEV_IDLEN+1)))      return CONTROLLER_UNKNOWN;        if (cam_get_device(dev_name,chan->devname,DEV_IDLEN,&(chan->unitnum)) == -1)      return CONTROLLER_UNKNOWN;  }  return CONTROLLER_SCSI;  }int guess_device_type (const char* dev_name) {  return parse_ata_chan_dev(dev_name,NULL);}// global variable holding byte count of allocated memoryextern long long bytes;// we are going to take advantage of the fact that FreeBSD's devfs will only// have device entries for devices that exist.  So if we get the equivilent of// ls /dev/ad?, we have all the ATA devices on the system//// If any errors occur, leave errno set as it was returned by the// system call, and return <0.// Return values:// -1 out of memory// -2 to -5 errors in globint get_dev_names(char*** names, const char* prefix) {  int n = 0;  char** mp;  int retglob,lim;  glob_t globbuf;  int i;  char pattern1[128],pattern2[128];  bzero(&globbuf,sizeof(globbuf));  // in case of non-clean exit  *names=NULL;  // handle 0-99 possible devices, will still be limited by MAX_NUM_DEV  sprintf(pattern1,"/dev/%s[0-9]",prefix);  sprintf(pattern2,"/dev/%s[0-9][0-9]",prefix);    // Use glob to look for any directory entries matching the patterns  // first call inits with first pattern match, second call appends  // to first list. GLOB_NOCHECK results in no error if no more matches   // found, however it does append the actual pattern to the list of   // paths....  if ((retglob=glob(pattern1, GLOB_ERR|GLOB_NOCHECK, NULL, &globbuf)) ||      (retglob=glob(pattern2, GLOB_ERR|GLOB_APPEND|GLOB_NOCHECK,NULL,&globbuf))) {     int retval = -1;    // glob failed    if (retglob==GLOB_NOSPACE)      pout("glob(3) ran out of memory matching patterns (%s),(%s)\n",           pattern1, pattern2);    else if (retglob==GLOB_ABORTED)      pout("glob(3) aborted matching patterns (%s),(%s)\n",           pattern1, pattern2);    else if (retglob==GLOB_NOMATCH) {      pout("glob(3) found no matches for patterns (%s),(%s)\n",           pattern1, pattern2);      retval = 0;    }    else if (retglob)      pout("Unexplained error in glob(3) of patterns (%s),(%s)\n",           pattern1, pattern2);        //  Free memory and return    globfree(&globbuf);    return retval;  }  // did we find too many paths?  lim = globbuf.gl_pathc < MAX_NUM_DEV ? globbuf.gl_pathc : MAX_NUM_DEV;  if (lim < globbuf.gl_pathc)    pout("glob(3) found %d > MAX=%d devices matching patterns (%s),(%s): ignoring %d paths\n",          globbuf.gl_pathc, MAX_NUM_DEV, pattern1,pattern2,         globbuf.gl_pathc-MAX_NUM_DEV);    // allocate space for up to lim number of ATA devices  if (!(mp =  (char **)calloc(lim, sizeof(char*)))){    pout("Out of memory constructing scan device list\n");    return -1;  }  // now step through the list returned by glob.  No link checking needed  // in FreeBSD  for (i=0; i<globbuf.gl_pathc; i++){    // because of the NO_CHECK in calls to glob,    // the pattern itself will be added to path list..    // so ignore any paths that have the ']' from pattern    if (strchr(globbuf.gl_pathv[i],']') == NULL)      mp[n++] = CustomStrDup(globbuf.gl_pathv[i], 1, __LINE__, filenameandversion);  }  globfree(&globbuf);  mp = (char **)realloc(mp,n*(sizeof(char*))); // shrink to correct size  bytes += (n)*(sizeof(char*)); // and set allocated byte count  *names=mp;  return n;}int make_device_names (char*** devlist, const char* name) {  if (!strcmp(name,"SCSI"))    return get_dev_names(devlist,"da");  else if (!strcmp(name,"ATA"))    return get_dev_names(devlist,"ad");  else    return 0;}

⌨️ 快捷键说明

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