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

📄 os_freebsd.cpp

📁 硬盘各项性能的测试,如温度容量版本健康度型号
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    request.u.ata.count=select;    request.flags=ATA_CMD_CONTROL;    break;  case IMMEDIATE_OFFLINE:    request.u.ata.feature=ATA_SMART_IMMEDIATE_OFFLINE;    request.u.ata.lba = select|(0xc24f<<8); // put test in sector    request.flags=ATA_CMD_CONTROL;    break;  case STATUS_CHECK: // same command, no HDIO in FreeBSD  case STATUS:    // this command only says if SMART is working.  It could be    // replaced with STATUS_CHECK below.    request.u.ata.feature=ATA_SMART_STATUS;    request.u.ata.lba=0xc24f<<8;    request.flags=ATA_CMD_CONTROL;    break;  default:    pout("Unrecognized command %d in ata_command_interface()\n"         "Please contact " PACKAGE_BUGREPORT "\n", command);    errno=ENOSYS;    return -1;  }    if (command==STATUS_CHECK){    unsigned const char normal_lo=0x4f, normal_hi=0xc2;    unsigned const char failed_lo=0xf4, failed_hi=0x2c;    unsigned char low,high;    #ifdef IOCATAREQUEST    if ((retval=ioctl(con->device, IOCATAREQUEST, &request)) || request.error)#else    if ((retval=ioctl(con->atacommand, IOCATA, &iocmd)) || request.error)#endif      return -1;#if __FreeBSD_version < 502000    printwarning(NO_RETURN,NULL);#endif    high = (request.u.ata.lba >> 16) & 0xff;    low = (request.u.ata.lba >> 8) & 0xff;        // Cyl low and Cyl high unchanged means "Good SMART status"    if (low==normal_lo && high==normal_hi)      return 0;        // These values mean "Bad SMART status"    if (low==failed_lo && high==failed_hi)      return 1;        // We haven't gotten output that makes sense; print out some debugging info    char buf[512];    sprintf(buf,"CMD=0x%02x\nFR =0x%02x\nNS =0x%02x\nSC =0x%02x\nCL =0x%02x\nCH =0x%02x\nRETURN =0x%04x\n",            (int)request.u.ata.command,            (int)request.u.ata.feature,            (int)request.u.ata.count,            (int)((request.u.ata.lba) & 0xff),            (int)((request.u.ata.lba>>8) & 0xff),            (int)((request.u.ata.lba>>16) & 0xff),            (int)request.error);    printwarning(BAD_SMART,buf);    return 0;     }#ifdef IOCATAREQUEST  if ((retval=ioctl(con->device, IOCATAREQUEST, &request)) || request.error)#else  if ((retval=ioctl(con->atacommand, IOCATA, &iocmd)) || request.error)#endif  {    return -1;  }  //   if (copydata)    memcpy(data, buff, 512);    return 0;#endif}// Interface to SCSI devices.  See os_linux.cint do_normal_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report){  struct freebsd_dev_channel* con = NULL;  struct cam_device* cam_dev = NULL;  union ccb *ccb;        if (report > 0) {        unsigned int k;        const unsigned char * ucp = iop->cmnd;        const char * np;        np = scsi_get_opcode_name(ucp[0]);        pout(" [%s: ", np ? np : "<unknown opcode>");        for (k = 0; k < iop->cmnd_len; ++k)            pout("%02x ", ucp[k]);        if ((report > 1) &&             (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {            int trunc = (iop->dxfer_len > 256) ? 1 : 0;            pout("]\n  Outgoing data, len=%d%s:\n", (int)iop->dxfer_len,                 (trunc ? " [only first 256 bytes shown]" : ""));            dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);        }        else            pout("]");    }  // check that "file descriptor" is valid  if (isnotopen(&fd,&con))      return -ENOTTY;  if (!(cam_dev = cam_open_spec_device(con->devname,con->unitnum,O_RDWR,NULL))) {    warnx("%s",cam_errbuf);    return -1;  }  if (!(ccb = cam_getccb(cam_dev))) {    warnx("error allocating ccb");    return -ENOMEM;  }  // clear out structure, except for header that was filled in for us  bzero(&(&ccb->ccb_h)[1],        sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));  cam_fill_csio(&ccb->csio,                /*retrires*/ 1,                /*cbfcnp*/ NULL,                /* flags */ (iop->dxfer_dir == DXFER_NONE ? CAM_DIR_NONE :(iop->dxfer_dir == DXFER_FROM_DEVICE ? CAM_DIR_IN : CAM_DIR_OUT)),                /* tagaction */ MSG_SIMPLE_Q_TAG,                /* dataptr */ iop->dxferp,                /* datalen */ iop->dxfer_len,                /* senselen */ iop->max_sense_len,                /* cdblen */ iop->cmnd_len,                /* timout (converted to seconds) */ iop->timeout*1000);  memcpy(ccb->csio.cdb_io.cdb_bytes,iop->cmnd,iop->cmnd_len);  if (cam_send_ccb(cam_dev,ccb) < 0) {    warn("error sending SCSI ccb"); #if __FreeBSD_version > 500000    cam_error_print(cam_dev,ccb,CAM_ESF_ALL,CAM_EPF_ALL,stderr); #endif    cam_freeccb(ccb);    return -1;  }  if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { #if __FreeBSD_version > 500000    cam_error_print(cam_dev,ccb,CAM_ESF_ALL,CAM_EPF_ALL,stderr); #endif    cam_freeccb(ccb);    return -1;  }  if (iop->sensep) {    memcpy(iop->sensep,&(ccb->csio.sense_data),sizeof(struct scsi_sense_data));    iop->resp_sense_len = sizeof(struct scsi_sense_data);  }  iop->scsi_status = ccb->csio.scsi_status;  cam_freeccb(ccb);    if (cam_dev)    cam_close_device(cam_dev);  if (report > 0) {    int trunc;    pout("  status=0\n");    trunc = (iop->dxfer_len > 256) ? 1 : 0;        pout("  Incoming data, len=%d%s:\n", (int)iop->dxfer_len,         (trunc ? " [only first 256 bytes shown]" : ""));    dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);  }  return 0;}/* Check and call the right interface. Maybe when the do_generic_scsi_cmd_io interface is better   we can take off this crude way of calling the right interface */int do_scsi_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report){struct freebsd_dev_channel *fdchan;     switch(con->controller_type)     {         case CONTROLLER_CCISS:	     // check that "file descriptor" is valid	     if (isnotopen(&dev_fd,&fdchan))		  return -ENOTTY;#ifdef HAVE_DEV_CISS_CISSIO_H             return cciss_io_interface(fdchan->device, con->controller_port-1, iop, report);#else             {                 static int warned = 0;                 if (!warned) {                     pout("CCISS support is not available in this build of smartmontools,\n"                          "/usr/src/sys/dev/ciss/cissio.h was not available at build time.\n\n");                     warned = 1;                 }             }             errno = ENOSYS;             return -1;#endif             // not reached             break;         default:             return do_normal_scsi_cmnd_io(dev_fd, iop, report);             // not reached             break;     }}// Interface to ATA devices behind 3ware escalade RAID controller cards.  See os_linux.c#define BUFFER_LEN_678K_CHAR ( sizeof(struct twe_usercommand) ) // 520#define BUFFER_LEN_9000_CHAR ( sizeof(TW_OSLI_IOCTL_NO_DATA_BUF) + sizeof(TWE_Command) ) // 2048#define TW_IOCTL_BUFFER_SIZE ( MAX(BUFFER_LEN_678K_CHAR, BUFFER_LEN_9000_CHAR) )int escalade_command_interface(int fd, int disknum, int escalade_type, smart_command_set command, int select, char *data) {  // to hold true file descriptor  struct freebsd_dev_channel* con;  // return value and buffer for ioctl()  int  ioctlreturn, readdata=0;  struct twe_usercommand* cmd_twe = NULL;  TW_OSLI_IOCTL_NO_DATA_BUF* cmd_twa = NULL;  TWE_Command_ATA* ata = NULL;  // Used by both the SCSI and char interfaces  char ioctl_buffer[TW_IOCTL_BUFFER_SIZE];  if (disknum < 0) {    printwarning(NO_DISK_3WARE,NULL);    return -1;  }  // check that "file descriptor" is valid  if (isnotopen(&fd,&con))      return -1;  memset(ioctl_buffer, 0, TW_IOCTL_BUFFER_SIZE);  if (escalade_type==CONTROLLER_3WARE_9000_CHAR) {    cmd_twa = (TW_OSLI_IOCTL_NO_DATA_BUF*)ioctl_buffer;    cmd_twa->pdata = ((TW_OSLI_IOCTL_WITH_PAYLOAD*)cmd_twa)->payload.data_buf;    cmd_twa->driver_pkt.buffer_length = 512;    ata = (TWE_Command_ATA*)&cmd_twa->cmd_pkt.command.cmd_pkt_7k;  } else if (escalade_type==CONTROLLER_3WARE_678K_CHAR) {    cmd_twe = (struct twe_usercommand*)ioctl_buffer;    ata = &cmd_twe->tu_command.ata;  } else {    pout("Unrecognized escalade_type %d in freebsd_3ware_command_interface(disk %d)\n"         "Please contact " PACKAGE_BUGREPORT "\n", escalade_type, disknum);    errno=ENOSYS;    return -1;  }  ata->opcode = TWE_OP_ATA_PASSTHROUGH;  // Same for (almost) all commands - but some reset below  ata->request_id    = 0xFF;  ata->unit          = disknum;  ata->status        = 0;             ata->flags         = 0x1;  ata->drive_head    = 0x0;  ata->sector_num    = 0;  // All SMART commands use this CL/CH signature.  These are magic  // values from the ATA specifications.  ata->cylinder_lo   = 0x4F;  ata->cylinder_hi   = 0xC2;    // SMART ATA COMMAND REGISTER value  ata->command       = ATA_SMART_CMD;    // Is this a command that reads or returns 512 bytes?  // passthru->param values are:  // 0x0 - non data command without TFR write check,  // 0x8 - non data command with TFR write check,  // 0xD - data command that returns data to host from device  // 0xF - data command that writes data from host to device  // passthru->size values are 0x5 for non-data and 0x07 for data  if (command == READ_VALUES     ||      command == READ_THRESHOLDS ||      command == READ_LOG        ||      command == IDENTIFY        ||      command == WRITE_LOG ) {    readdata=1;    if (escalade_type==CONTROLLER_3WARE_678K_CHAR) {      cmd_twe->tu_data = data;      cmd_twe->tu_size = 512;    }    ata->sgl_offset = 0x5;    ata->size         = 0x5;    ata->param        = 0xD;    ata->sector_count = 0x1;    // For 64-bit to work correctly, up the size of the command packet    // in dwords by 1 to account for the 64-bit single sgl 'address'    // field. Note that this doesn't agree with the typedefs but it's    // right (agree with kernel driver behavior/typedefs).    //if (sizeof(long)==8)    //  ata->size++;  }  else {    // Non data command -- but doesn't use large sector     // count register values.      ata->sgl_offset = 0x0;    ata->size         = 0x5;    ata->param        = 0x8;    ata->sector_count = 0x0;  }    // Now set ATA registers depending upon command  switch (command){  case CHECK_POWER_MODE:    ata->command     = ATA_CHECK_POWER_MODE;    ata->features    = 0;    ata->cylinder_lo = 0;    ata->cylinder_hi = 0;    break;  case READ_VALUES:    ata->features = ATA_SMART_READ_VALUES;    break;  case READ_THRESHOLDS:    ata->features = ATA_SMART_READ_THRESHOLDS;    break;  case READ_LOG:    ata->features = ATA_SMART_READ_LOG_SECTOR;    // log number to return    ata->sector_num  = select;    break;  case WRITE_LOG:    readdata=0;    ata->features     = ATA_SMART_WRITE_LOG_SECTOR;    ata->sector_count = 1;    ata->sector_num   = select;    ata->param        = 0xF;  // PIO data write    break;  case IDENTIFY:    // ATA IDENTIFY DEVICE    ata->command     = ATA_IDENTIFY_DEVICE;    ata->features    = 0;    ata->cylinder_lo = 0;    ata->cylinder_hi = 0;    break;  case PIDENTIFY:    // 3WARE controller can NOT have packet device internally    pout("WARNING - NO DEVICE FOUND ON 3WARE CONTROLLER (disk %d)\n", disknum);    errno=ENODEV;    return -1;  case ENABLE:    ata->features = ATA_SMART_ENABLE;    break;  case DISABLE:    ata->features = ATA_SMART_DISABLE;    break;  case AUTO_OFFLINE:    ata->features     = ATA_SMART_AUTO_OFFLINE;    // Enable or disable?    ata->sector_count = select;    break;  case AUTOSAVE:    ata->features     = ATA_SMART_AUTOSAVE;    // Enable or disable?    ata->sector_count = select;    break;  case IMMEDIATE_OFFLINE:    ata->features    = ATA_SMART_IMMEDIATE_OFFLINE;    // What test type to run?    ata->sector_num  = select;    break;  case STATUS_CHECK:

⌨️ 快捷键说明

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