📄 os_linux.cpp
字号:
return 1; // We haven't gotten output that makes sense; print out some debugging info syserror("Error SMART Status command failed"); pout("Please get assistance from %s\n",PACKAGE_BUGREPORT); pout("Register values returned from SMART Status command are:\n"); pout("CMD =0x%02x\n",(int)buff[0]); pout("FR =0x%02x\n",(int)buff[1]); pout("NS =0x%02x\n",(int)buff[2]); pout("SC =0x%02x\n",(int)buff[3]); pout("CL =0x%02x\n",(int)buff[4]); pout("CH =0x%02x\n",(int)buff[5]); pout("SEL=0x%02x\n",(int)buff[6]); return -1; } if (copydata) memcpy(data, buff, 512); return 0;}// this implementation is derived from ata_command_interface with a header// packing for highpoint linux driver ioctl interface//// ioctl(fd,HPTIO_CTL,buff)// ^^^^^^^^^//// structure of hpt_buff// +----+----+----+----+--------------------.....---------------------+// | 1 | 2 | 3 | 4 | 5 |// +----+----+----+----+--------------------.....---------------------+//// 1: The target controller [ int ( 4 Bytes ) ]// 2: The channel of the target controllee [ int ( 4 Bytes ) ]// 3: HDIO_ ioctl call [ int ( 4 Bytes ) ]// available from ${LINUX_KERNEL_SOURCE}/Documentation/ioctl/hdio// 4: the pmport that disk attached, [ int ( 4 Bytes ) ]// if no pmport device, set to 1 or leave blank// 5: data [ void * ( var leangth ) ]//#define STRANGE_BUFFER_LENGTH (4+512*0xf8)int highpoint_command_interface(int device, smart_command_set command, int select, char *data){ unsigned char hpt_buff[4*sizeof(int) + STRANGE_BUFFER_LENGTH]; unsigned int *hpt = (unsigned int *)hpt_buff; unsigned char *buff = &hpt_buff[4*sizeof(int)]; int copydata = 0; const int HDIO_DRIVE_CMD_OFFSET = 4; memset(hpt_buff, 0, 4*sizeof(int) + STRANGE_BUFFER_LENGTH); hpt[0] = con->hpt_data[0]; // controller id hpt[1] = con->hpt_data[1]; // channel number hpt[3] = con->hpt_data[2]; // pmport number buff[0]=ATA_SMART_CMD; switch (command){ case CHECK_POWER_MODE: buff[0]=ATA_CHECK_POWER_MODE; copydata=1; break; case READ_VALUES: buff[2]=ATA_SMART_READ_VALUES; buff[3]=1; copydata=512; break; case READ_THRESHOLDS: buff[2]=ATA_SMART_READ_THRESHOLDS; buff[1]=buff[3]=1; copydata=512; break; case READ_LOG: buff[2]=ATA_SMART_READ_LOG_SECTOR; buff[1]=select; buff[3]=1; copydata=512; break; case WRITE_LOG: break; case IDENTIFY: buff[0]=ATA_IDENTIFY_DEVICE; buff[3]=1; copydata=512; break; case PIDENTIFY: buff[0]=ATA_IDENTIFY_PACKET_DEVICE; buff[3]=1; copydata=512; break; case ENABLE: buff[2]=ATA_SMART_ENABLE; buff[1]=1; break; case DISABLE: buff[2]=ATA_SMART_DISABLE; buff[1]=1; break; case STATUS: buff[2]=ATA_SMART_STATUS; break; case AUTO_OFFLINE: buff[2]=ATA_SMART_AUTO_OFFLINE; buff[3]=select; break; case AUTOSAVE: buff[2]=ATA_SMART_AUTOSAVE; buff[3]=select; break; case IMMEDIATE_OFFLINE: buff[2]=ATA_SMART_IMMEDIATE_OFFLINE; buff[1]=select; break; case STATUS_CHECK: buff[1]=ATA_SMART_STATUS; break; default: pout("Unrecognized command %d in linux_highpoint_command_interface()\n" "Please contact " PACKAGE_BUGREPORT "\n", command); errno=ENOSYS; return -1; } if (command==WRITE_LOG) { unsigned char task[4*sizeof(int)+sizeof(ide_task_request_t)+512]; unsigned int *hpt = (unsigned int *)task; ide_task_request_t *reqtask = (ide_task_request_t *)(&task[4*sizeof(int)]); task_struct_t *taskfile = (task_struct_t *)reqtask->io_ports; int retval; memset(task, 0, sizeof(task)); hpt[0] = con->hpt_data[0]; // controller id hpt[1] = con->hpt_data[1]; // channel number hpt[3] = con->hpt_data[2]; // pmport number hpt[2] = HDIO_DRIVE_TASKFILE; // real hd ioctl taskfile->data = 0; taskfile->feature = ATA_SMART_WRITE_LOG_SECTOR; taskfile->sector_count = 1; taskfile->sector_number = select; taskfile->low_cylinder = 0x4f; taskfile->high_cylinder = 0xc2; taskfile->device_head = 0; taskfile->command = ATA_SMART_CMD; reqtask->data_phase = TASKFILE_OUT; reqtask->req_cmd = IDE_DRIVE_TASK_OUT; reqtask->out_size = 512; reqtask->in_size = 0; memcpy(task+sizeof(ide_task_request_t)+4*sizeof(int), data, 512); if ((retval=ioctl(device, HPTIO_CTL, task))) { if (retval==-EINVAL) pout("Kernel lacks HDIO_DRIVE_TASKFILE support; compile kernel with CONFIG_IDE_TASKFILE_IO set\n"); return -1; } return 0; } if (command==STATUS_CHECK){ int retval; unsigned const char normal_lo=0x4f, normal_hi=0xc2; unsigned const char failed_lo=0xf4, failed_hi=0x2c; buff[4]=normal_lo; buff[5]=normal_hi; hpt[2] = HDIO_DRIVE_TASK; if ((retval=ioctl(device, HPTIO_CTL, hpt_buff))) { if (retval==-EINVAL) { pout("Error SMART Status command via HDIO_DRIVE_TASK failed"); pout("Rebuild older linux 2.2 kernels with HDIO_DRIVE_TASK support added\n"); } else syserror("Error SMART Status command failed"); return -1; } if (buff[4]==normal_lo && buff[5]==normal_hi) return 0; if (buff[4]==failed_lo && buff[5]==failed_hi) return 1; syserror("Error SMART Status command failed"); pout("Please get assistance from " PACKAGE_HOMEPAGE "\n"); pout("Register values returned from SMART Status command are:\n"); pout("CMD=0x%02x\n",(int)buff[0]); pout("FR =0x%02x\n",(int)buff[1]); pout("NS =0x%02x\n",(int)buff[2]); pout("SC =0x%02x\n",(int)buff[3]); pout("CL =0x%02x\n",(int)buff[4]); pout("CH =0x%02x\n",(int)buff[5]); pout("SEL=0x%02x\n",(int)buff[6]); return -1; }#if 1 if (command==IDENTIFY || command==PIDENTIFY) { unsigned char deviceid[4*sizeof(int)+512*sizeof(char)]; unsigned int *hpt = (unsigned int *)deviceid; hpt[0] = con->hpt_data[0]; // controller id hpt[1] = con->hpt_data[1]; // channel number hpt[3] = con->hpt_data[2]; // pmport number hpt[2] = HDIO_GET_IDENTITY; if (!ioctl(device, HPTIO_CTL, deviceid) && (deviceid[4*sizeof(int)] & 0x8000)) buff[0]=(command==IDENTIFY)?ATA_IDENTIFY_PACKET_DEVICE:ATA_IDENTIFY_DEVICE; }#endif hpt[2] = HDIO_DRIVE_CMD; if ((ioctl(device, HPTIO_CTL, hpt_buff))) return -1; if (command==CHECK_POWER_MODE) buff[HDIO_DRIVE_CMD_OFFSET]=buff[2]; if (copydata) memcpy(data, buff+HDIO_DRIVE_CMD_OFFSET, copydata); return 0;}// Utility function for printing warningsvoid printwarning(smart_command_set command){ static int printed[4]={0,0,0,0}; const char* message= "can not be passed through the 3ware 3w-xxxx driver. This can be fixed by\n" "applying a simple 3w-xxxx driver patch that can be found here:\n" PACKAGE_HOMEPAGE "\n" "Alternatively, upgrade your 3w-xxxx driver to version 1.02.00.037 or greater.\n\n"; if (command==AUTO_OFFLINE && !printed[0]) { printed[0]=1; pout("The SMART AUTO-OFFLINE ENABLE command (smartmontools -o on option/Directive)\n%s", message); } else if (command==AUTOSAVE && !printed[1]) { printed[1]=1; pout("The SMART AUTOSAVE ENABLE command (smartmontools -S on option/Directive)\n%s", message); } else if (command==STATUS_CHECK && !printed[2]) { printed[2]=1; pout("The SMART RETURN STATUS return value (smartmontools -H option/Directive)\n%s", message); } else if (command==WRITE_LOG && !printed[3]) { printed[3]=1; pout("The SMART WRITE LOG command (smartmontools -t selective) only supported via char /dev/tw[ae] interface\n"); } return;}// Guess device type (ata or scsi) based on device name (Linux// specific) SCSI device name in linux can be sd, sr, scd, st, nst,// osst, nosst and sg.static const char * lin_dev_prefix = "/dev/";static const char * lin_dev_ata_disk_plus = "h";static const char * lin_dev_ata_devfs_disk_plus = "ide/";static const char * lin_dev_scsi_devfs_disk_plus = "scsi/";static const char * lin_dev_scsi_disk_plus = "s";static const char * lin_dev_scsi_tape1 = "ns";static const char * lin_dev_scsi_tape2 = "os";static const char * lin_dev_scsi_tape3 = "nos";static const char * lin_dev_3ware_9000_char = "twa";static const char * lin_dev_3ware_678k_char = "twe";static const char * lin_dev_cciss_dir = "cciss/";int guess_device_type(const char * dev_name) { int len; int dev_prefix_len = strlen(lin_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(lin_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/h* or h* if (!strncmp(lin_dev_ata_disk_plus, dev_name, strlen(lin_dev_ata_disk_plus))) return CONTROLLER_ATA; // form /dev/ide/* or ide/* if (!strncmp(lin_dev_ata_devfs_disk_plus, dev_name, strlen(lin_dev_ata_devfs_disk_plus))) return CONTROLLER_ATA; // form /dev/s* or s* if (!strncmp(lin_dev_scsi_disk_plus, dev_name, strlen(lin_dev_scsi_disk_plus))) return CONTROLLER_SCSI; // form /dev/scsi/* or scsi/* if (!strncmp(lin_dev_scsi_devfs_disk_plus, dev_name, strlen(lin_dev_scsi_devfs_disk_plus))) return CONTROLLER_SCSI; // form /dev/ns* or ns* if (!strncmp(lin_dev_scsi_tape1, dev_name, strlen(lin_dev_scsi_tape1))) return CONTROLLER_SCSI; // form /dev/os* or os* if (!strncmp(lin_dev_scsi_tape2, dev_name, strlen(lin_dev_scsi_tape2))) return CONTROLLER_SCSI; // form /dev/nos* or nos* if (!strncmp(lin_dev_scsi_tape3, dev_name, strlen(lin_dev_scsi_tape3))) return CONTROLLER_SCSI; // form /dev/twa* if (!strncmp(lin_dev_3ware_9000_char, dev_name, strlen(lin_dev_3ware_9000_char))) return CONTROLLER_3WARE_9000_CHAR; // form /dev/twe* if (!strncmp(lin_dev_3ware_678k_char, dev_name, strlen(lin_dev_3ware_678k_char))) return CONTROLLER_3WARE_678K_CHAR; // form /dev/cciss* if (!strncmp(lin_dev_cciss_dir, dev_name, strlen(lin_dev_cciss_dir))) return CONTROLLER_CCISS; // we failed to recognize any of the forms return CONTROLLER_UNKNOWN;}#if 0[ed@firestorm ed]$ ls -l /dev/discstotal 0lr-xr-xr-x 1 root root 30 Dec 31 1969 disc0 -> ../ide/host2/bus0/target0/lun0/lr-xr-xr-x 1 root root 30 Dec 31 1969 disc1 -> ../ide/host2/bus1/target0/lun0/[ed@firestorm ed]$ ls -l dev/ide/host*/bus*/target*/lun*/discls: dev/ide/host*/bus*/target*/lun*/disc: No such file or directory[ed@firestorm ed]$ ls -l /dev/ide/host*/bus*/target*/lun*/discbrw------- 1 root root 33, 0 Dec 31 1969 /dev/ide/host2/bus0/target0/lun0/discbrw------- 1 root root 34, 0 Dec 31 1969 /dev/ide/host2/bus1/target0/lun0/disc[ed@firestorm ed]$ ls -l /dev/ide/c*b*t*u*ls: /dev/ide/c*b*t*u*: No such file or directory[ed@firestorm ed]$Script done on Fri Nov 7 13:46:28 2003#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -