Beispiel #1
0
void
ata_print_ident(struct ata_params *ident_data)
{
	char product[48], revision[16];

	cam_strvis(product, ident_data->model, sizeof(ident_data->model),
		   sizeof(product));
	cam_strvis(revision, ident_data->revision, sizeof(ident_data->revision),
		   sizeof(revision));
	printf("<%s %s> %s-%d",
	    product, revision,
	    (ident_data->config == ATA_PROTO_CFA) ? "CFA" :
	    (ident_data->config & ATA_PROTO_ATAPI) ? "ATAPI" : "ATA",
	    ata_version(ident_data->version_major));
	if (ident_data->satacapabilities && ident_data->satacapabilities != 0xffff) {
		if (ident_data->satacapabilities & ATA_SATA_GEN3)
			printf(" SATA 3.x");
		else if (ident_data->satacapabilities & ATA_SATA_GEN2)
			printf(" SATA 2.x");
		else if (ident_data->satacapabilities & ATA_SATA_GEN1)
			printf(" SATA 1.x");
		else
			printf(" SATA");
	}
	printf(" device\n");
}
Beispiel #2
0
void
semb_print_ident_short(struct sep_identify_data *ident_data)
{
	char vendor[9], product[17], revision[5], fw[5];

	cam_strvis(vendor, ident_data->vendor_id, 8, sizeof(vendor));
	cam_strvis(product, ident_data->product_id, 16, sizeof(product));
	cam_strvis(revision, ident_data->product_rev, 4, sizeof(revision));
	cam_strvis(fw, ident_data->firmware_rev, 4, sizeof(fw));
	printf("<%s %s %s %s>", vendor, product, revision, fw);
}
Beispiel #3
0
void
ata_print_ident_short(struct ata_params *ident_data)
{
	char product[48], revision[16];

	cam_strvis(product, ident_data->model, sizeof(ident_data->model),
		   sizeof(product));
	cam_strvis(revision, ident_data->revision, sizeof(ident_data->revision),
		   sizeof(revision));
	printf("<%s %s>", product, revision);
}
Beispiel #4
0
void
ata_print_ident(struct ata_params *ident_data)
{
	const char *proto;
	char product[48], revision[16], ata[12], sata[12];

	cam_strvis(product, ident_data->model, sizeof(ident_data->model),
		   sizeof(product));
	cam_strvis(revision, ident_data->revision, sizeof(ident_data->revision),
		   sizeof(revision));
	proto = (ident_data->config == ATA_PROTO_CFA) ? "CFA" :
		(ident_data->config & ATA_PROTO_ATAPI) ? "ATAPI" : "ATA";
	if (ata_version(ident_data->version_major) == 0) {
		snprintf(ata, sizeof(ata), "%s", proto);
	} else if (ata_version(ident_data->version_major) <= 7) {
		snprintf(ata, sizeof(ata), "%s-%d", proto,
		    ata_version(ident_data->version_major));
	} else if (ata_version(ident_data->version_major) == 8) {
		snprintf(ata, sizeof(ata), "%s8-ACS", proto);
	} else {
		snprintf(ata, sizeof(ata), "ACS-%d %s",
		    ata_version(ident_data->version_major) - 7, proto);
	}
	if (ident_data->satacapabilities && ident_data->satacapabilities != 0xffff) {
		if (ident_data->satacapabilities & ATA_SATA_GEN3)
			snprintf(sata, sizeof(sata), " SATA 3.x");
		else if (ident_data->satacapabilities & ATA_SATA_GEN2)
			snprintf(sata, sizeof(sata), " SATA 2.x");
		else if (ident_data->satacapabilities & ATA_SATA_GEN1)
			snprintf(sata, sizeof(sata), " SATA 1.x");
		else
			snprintf(sata, sizeof(sata), " SATA");
	} else
		sata[0] = 0;
	printf("<%s %s> %s%s device\n", product, revision, ata, sata);
}
Beispiel #5
0
/* Borrowed heavily from scsi_all.c:scsi_print_inquiry(). */
const char *
mpt_pd_inq_string(CONFIG_PAGE_RAID_PHYS_DISK_0 *pd_info)
{
	RAID_PHYS_DISK0_INQUIRY_DATA *inq_data;
	u_char vendor[9], product[17], revision[5];
	static char inq_string[64];

	inq_data = &pd_info->InquiryData;
	cam_strvis(vendor, inq_data->VendorID, sizeof(inq_data->VendorID),
	    sizeof(vendor));
	cam_strvis(product, inq_data->ProductID, sizeof(inq_data->ProductID),
	    sizeof(product));
	cam_strvis(revision, inq_data->ProductRevLevel,
	    sizeof(inq_data->ProductRevLevel), sizeof(revision));

	/* Total hack. */
	if (strcmp(vendor, "ATA") == 0)
		snprintf(inq_string, sizeof(inq_string), "<%s %s> SATA",
		    product, revision);
	else
		snprintf(inq_string, sizeof(inq_string), "<%s %s %s> SAS",
		    vendor, product, revision);
	return (inq_string);
}
Beispiel #6
0
/*
 * Find entry in vendors list that belongs to
 * the vendor of given cam device.
 */
static const struct fw_vendor *
fw_get_vendor(struct cam_device *cam_dev)
{
	char vendor[SID_VENDOR_SIZE + 1];
	const struct fw_vendor *vp;

	if (cam_dev == NULL)
		return (NULL);
	cam_strvis((u_char *)vendor, (u_char *)cam_dev->inq_data.vendor,
	    sizeof(cam_dev->inq_data.vendor), sizeof(vendor));
	for (vp = vendors_list; vp->pattern != NULL; vp++) {
		if (!cam_strmatch((const u_char *)vendor,
		    (const u_char *)vp->pattern, strlen(vendor)))
			break;
	}
	return (vp);
}
Beispiel #7
0
void
semb_print_ident(struct sep_identify_data *ident_data)
{
	char vendor[9], product[17], revision[5], fw[5], in[7], ins[5];

	cam_strvis(vendor, ident_data->vendor_id, 8, sizeof(vendor));
	cam_strvis(product, ident_data->product_id, 16, sizeof(product));
	cam_strvis(revision, ident_data->product_rev, 4, sizeof(revision));
	cam_strvis(fw, ident_data->firmware_rev, 4, sizeof(fw));
	cam_strvis(in, ident_data->interface_id, 6, sizeof(in));
	cam_strvis(ins, ident_data->interface_rev, 4, sizeof(ins));
	printf("<%s %s %s %s> SEMB %s %s device\n",
	    vendor, product, revision, fw, in, ins);
}
Beispiel #8
0
/*
 * Decode the SMP REPORT MANUFACTURER INFORMATION response.  The format is
 * current as of SPL Revision 7, but the parsing should be backward
 * compatible for older versions of the spec.
 */
void
smp_report_manuf_info_sbuf(struct smp_report_manuf_info_response *response,
			   int response_len, struct sbuf *sb)
{
	char vendor[16], product[48], revision[16];
	char comp_vendor[16];

	sbuf_printf(sb, "Report Manufacturer Information\n");
	sbuf_printf(sb, "Expander Change count: %d\n",
		    scsi_2btoul(response->expander_change_count));
	sbuf_printf(sb, "SAS 1.1 Format: %s\n",
		    smp_yesno(response->sas_11_format & SMP_RMI_SAS11_FORMAT));
	cam_strvis(vendor, response->vendor, sizeof(response->vendor),
		   sizeof(vendor));
	cam_strvis(product, response->product, sizeof(response->product),
		   sizeof(product));
	cam_strvis(revision, response->revision, sizeof(response->revision),
		   sizeof(revision));
	sbuf_printf(sb, "<%s %s %s>\n", vendor, product, revision);

	if ((response->sas_11_format & SMP_RMI_SAS11_FORMAT) == 0) {
		uint8_t *curbyte;
		int line_start, line_cursor;

		sbuf_printf(sb, "Vendor Specific Data:\n");

		/*
		 * Print out the bytes roughly in the style of hd(1), but
		 * without the extra ASCII decoding.  Hexadecimal line
		 * numbers on the left, and 16 bytes per line, with an
		 * extra space after the first 8 bytes.
		 *
		 * It would be nice if this sort of thing were available
		 * in a library routine.
		 */
		for (curbyte = (uint8_t *)&response->comp_vendor, line_start= 1,
		     line_cursor = 0; curbyte < (uint8_t *)&response->crc;
		     curbyte++, line_cursor++) {
			if (line_start != 0) {
				sbuf_printf(sb, "%08lx  ",
					    (unsigned long)(curbyte -
					    (uint8_t *)response));
				line_start = 0;
				line_cursor = 0;
			}
			sbuf_printf(sb, "%02x", *curbyte);

			if (line_cursor == 15) {
				sbuf_printf(sb, "\n");
				line_start = 1;
			} else
				sbuf_printf(sb, " %s", (line_cursor == 7) ?
					    " " : "");
		}
		if (line_cursor != 16)
			sbuf_printf(sb, "\n");
		return;
	}

	cam_strvis(comp_vendor, response->comp_vendor,
		   sizeof(response->comp_vendor), sizeof(comp_vendor));
	sbuf_printf(sb, "Component Vendor: %s\n", comp_vendor);
	sbuf_printf(sb, "Component ID: %#x\n", scsi_2btoul(response->comp_id));
	sbuf_printf(sb, "Component Revision: %#x\n", response->comp_revision);
	sbuf_printf(sb, "Vendor Specific: 0x%016jx\n",
		    (uintmax_t)scsi_8btou64(response->vendor_specific));
}
Beispiel #9
0
/*****************************************************************************
 * Processes HDD and SMART commands.
 *****************************************************************************/
void stat_hdd() {
	time_t tm;
	int channels_n, channel, device, i;
	int f_ata_request_supported, f_smart_supported, f_smart_enabled;
	struct ata_device dev[2];
	u_llong sectors;
	struct dev_match_result matches[100];
	union ccb ccb;

	msg_debug(1, "Processing of HDD/HDD_LIST/SMART command started");

	/* check byte order */
#if BYTE_ORDER != LITTLE_ENDIAN
	msg_err(0, "%s: ussd supports only LITTLE_ENDIAN byte order", __FUNCTION__);
	stat_hdd_finish();
	return;
#endif

	/* get statistics of all devices from devstat library */
	if ((f_stat_hdd_command_hdd || f_stat_hdd_command_hdd_list) && !stat_hdd_get_devstat()) {
		stat_hdd_finish();
		return;
	}

	/* check if [IOC]ATAREQUEST ioctl request supported by system */
	f_ata_request_supported = stat_hdd_is_ata_request_supported();
	if (f_stat_hdd_command_hdd || f_stat_hdd_command_smart) {
		tm = get_remote_tm();
		printf("%lu ata_request_supported %d\n", (u_long)tm, f_ata_request_supported);
	}

	/* determine number of ATA channels */
	if (stat_hdd_get_ata_channels_n(&channels_n)) {

		/* process all channels */
			for (channel = 0; channels_n < 0 || channel < channels_n; channel++) {
			msg_debug(2, "%s: Processing ATA channel %d", __FUNCTION__, channel);

			/* get channel devices */
			bzero(dev, sizeof(dev));
			if (!stat_hdd_get_ata_channel_devices(channel, dev)) {
				if (channels_n < 0)
					break;
				else
					continue;
			}
	
			/* check if channel has at least one device */
			if (!*dev[0].name && !*dev[1].name) {
				msg_debug(2, "%s: No devices found", __FUNCTION__);
				continue;
			}

			/* Process all devices within channel */
			for (device = 0; device < 2; device++) {
				/* skip if there is no device */
				if (!*dev[device].name)
					continue;
				msg_debug(2, "%s: Found device %s", __FUNCTION__, dev[device].name);
	
				if (!stat_hdd_is_device_ata(&dev[device])) {
					msg_debug(2, "%s: Device is not ATA device", __FUNCTION__);
					continue;
				}

				/* process HDD_LIST command */
				if (f_stat_hdd_command_hdd_list) {
					tm = get_remote_tm();
					printf("%lu hdd_exists:%s 1\n", (u_long)tm, dev[device].name);
				}
	
				/* go to the next device if no HDD or SMART command given */
				if (!f_stat_hdd_command_hdd && !f_stat_hdd_command_smart) {
					stat_hdd_fake_devstat(dev[device].name);
					continue;
				}
	
				/* refresh device parameters because they can be
				   cached by system */
				stat_hdd_refresh_ata_device_params(&dev[device]);
	
				/* process HDD command */
				if (f_stat_hdd_command_hdd) {
					/* get device size */
					sectors = stat_hdd_get_device_size(&dev[device]);
	
					tm = get_remote_tm();
					printf("%lu hdd_model:%s %s\n",
					    (u_long)tm, dev[device].name, dev[device].model);
					printf("%lu hdd_serno:%s %s\n",
					    (u_long)tm, dev[device].name, dev[device].serial);
					printf("%lu hdd_revision:%s %s\n",
					    (u_long)tm, dev[device].name, dev[device].revision);
					printf("%lu hdd_size_sectors:%s %llu\n",
					    (u_long)tm, dev[device].name, sectors);
					printf("%lu hdd_size_mbytes:%s %llu\n",
					    (u_long)tm, dev[device].name, sectors >> 11);
	
					/* print devstat statistics of device */
					stat_hdd_print_devstat(dev[device].name);
				}
				stat_hdd_fake_devstat(dev[device].name);
	
				/* process SMART command in remaining code */
				if (!f_stat_hdd_command_smart)
					continue;
	
				/* check if SMART supported by device */
				f_smart_supported = stat_hdd_is_smart_supported(&dev[device]);
	
				/* check if SMART enabled on device */
				f_smart_enabled = stat_hdd_is_smart_enabled(&dev[device]);
	
				/* enable SMART if requested */
				if (conf.f_enable_smart && f_ata_request_supported &&
				    f_smart_supported && !f_smart_enabled &&
				    stat_hdd_ata_command_interface(&dev[device],
				    SMART_ENABLE_OPERATIONS, NULL)) {
					f_smart_enabled = 1;
					msg_notice("SMART has been successfully enabled "
					    "on device %s", dev[device].name);
				}
	
				tm = get_remote_tm();
				printf("%lu smart_supported:%s %d\n",
				    (u_long)tm, dev[device].name, f_smart_supported);
				printf("%lu smart_enabled:%s %d\n",
				    (u_long)tm, dev[device].name, f_smart_enabled);
	
				/* don't try to get SMART if no attributes requested */
				if (!f_stat_hdd_smart_attrs_requested) {
					msg_debug(2, "%s: No SMART attributes requested",
					    __FUNCTION__);
					continue;
				}
	
				/* don't try to get SMART if system doesn't support
				   [IOC]ATAREQUEST ioctl request */
				if (!f_ata_request_supported) {
					msg_debug(2, "%s: Can't get SMART because system doesn't "
					    "support [IOC]ATAREQUEST ioctl request", __FUNCTION__);
					continue;
				}
	
				/* don't try to get SMART if it is not supported by device */
				if (!f_smart_supported) {
					msg_debug(2, "%s: SMART is not supported by device",
					    __FUNCTION__);
					continue;
				}
	
				/* don't try to get SMART if it is not enabled on device */
				if (!f_smart_enabled) {
					msg_debug(2, "%s: SMART is not enabled on device",
					    __FUNCTION__);
					continue;
				}
	
				/* get SMART values */
				if (!stat_hdd_ata_command_interface(&dev[device],
				    SMART_READ_VALUES, (char *)&dev[device].smart_values))
					continue;
				msg_debug(2, "%s: Got SMART values", __FUNCTION__);
	
				/* get SMART thresholds */
				if (!stat_hdd_ata_command_interface(&dev[device],
				    SMART_READ_THRESHOLDS, (char *)&dev[device].smart_thresholds))
					continue;
				msg_debug(2, "%s: Got SMART thresholds", __FUNCTION__);
	
				/* process SMART attributes */
				stat_hdd_process_smart_attributes(&dev[device]);
			}
		}
	
		msg_debug(2, "%s: All ATA channels processed", __FUNCTION__);
	}

	/* processing SCSI bus
	 * now we're not support SMART on SCSI, sad but true */

	msg_debug(2, "%s: Processing SCSI bus", __FUNCTION__);
	if ((channel = open(XPT_DEVICE, O_RDWR)) == -1) {
		msg_debug(1, "%s: open(%s) error %d (%s)", __FUNCTION__, XPT_DEVICE, errno, strerror(errno));
		stat_hdd_finish();
		return;
	}
	bzero(&ccb, sizeof(ccb));
	ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
	ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
	ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
	ccb.ccb_h.func_code = XPT_DEV_MATCH;
	ccb.cdm.match_buf_len = sizeof(matches);
	ccb.cdm.matches = &matches[0];
	if (ioctl(channel, CAMIOCOMMAND, &ccb) == -1) {
		msg_debug(1, "%s: ioctl(CAMIOCOMMAND) error %d (%s)", __FUNCTION__, errno, strerror(errno));
		stat_hdd_finish();
		return;
	}
	if ((ccb.ccb_h.status != CAM_REQ_CMP)
		|| ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
		&& (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
		msg_debug(1, "%s: CAM return error %#x, CDM error %d\n",
			__FUNCTION__, ccb.ccb_h.status, ccb.cdm.status);
		stat_hdd_finish();
		return;
	}

	/* walking CAM hierarchy */
	for(device = 0; (unsigned) device < ccb.cdm.num_matches; device++) {
		if (ccb.cdm.matches[device].type == DEV_MATCH_DEVICE) {
			if (ccb.cdm.matches[device].result.device_result.flags
				& DEV_RESULT_UNCONFIGURED)
				continue;
#if __FreeBSD_version > 800100
			/* new atacam devices - see ada(4) */
			if (ccb.cdm.matches[device].result.device_result.protocol == PROTO_ATA) {
				cam_strvis((void *) dev[0].model,
					ccb.cdm.matches[device].result.device_result.ident_data.model,
					sizeof(ccb.cdm.matches[device].result.device_result.ident_data.model),
					sizeof(dev[0].model));
				cam_strvis((void *) dev[0].serial,
					ccb.cdm.matches[device].result.device_result.ident_data.serial,
					sizeof(ccb.cdm.matches[device].result.device_result.ident_data.serial),
					sizeof(dev[0].serial));
				cam_strvis((void *) dev[0].revision,
					ccb.cdm.matches[device].result.device_result.ident_data.revision,
					sizeof(ccb.cdm.matches[device].result.device_result.ident_data.revision),
					sizeof(dev[0].revision));
				memcpy(&dev[0].params,
					&ccb.cdm.matches[device].result.device_result.ident_data,
					sizeof(dev[0].params));
				/* fake 3'rd device on IDE channel is atacam */
				dev[0].device = 2;
			}
			else if (ccb.cdm.matches[device].result.device_result.protocol == PROTO_SCSI) {
#endif
				cam_strvis((u_int8_t *) dev[0].model,
					(u_int8_t *) ccb.cdm.matches[device].result.device_result.inq_data.vendor,
					sizeof(ccb.cdm.matches[device].result.device_result.inq_data.vendor),
					sizeof(dev[0].model));
				if (strlen(dev[0].model) < sizeof(dev[0].model)+2)
					strlcat(dev[0].model, " ", sizeof(dev[0].model));
				cam_strvis((u_int8_t *) dev[0].model+strlen(dev[0].model),
					(u_int8_t *) ccb.cdm.matches[device].result.device_result.inq_data.product,
					sizeof(ccb.cdm.matches[device].result.device_result.inq_data.product),
					sizeof(dev[0].model)-strlen(dev[0].model));
				cam_strvis((u_int8_t *) dev[0].revision,
					(u_int8_t *) ccb.cdm.matches[device].result.device_result.inq_data.revision,
					sizeof(ccb.cdm.matches[device].result.device_result.inq_data.revision),
					sizeof(dev[0].revision));
				/* fake 4'th device on IDE channel is SCSI disk */
				dev[0].device = 3;
				msg_debug(2, "%s: found SCSI device, model is %s",
					__FUNCTION__, dev[0].model);
#if __FreeBSD_version > 800100
			}
#endif
		}
		if (ccb.cdm.matches[device].type == DEV_MATCH_PERIPH) {
			for (i=0; i < dinfo.numdevs; i++) {
				if (((dinfo.devices[i].device_type & DEVSTAT_TYPE_MASK) != DEVSTAT_TYPE_DIRECT)
					|| (dinfo.devices[i].device_type & DEVSTAT_TYPE_PASS))
					continue;
				if (!strcmp(dinfo.devices[i].device_name,
					ccb.cdm.matches[device].result.periph_result.periph_name)
					&& (unsigned) dinfo.devices[i].unit_number == ccb.cdm.matches[device].result.periph_result.unit_number) {
					snprintf(dev[0].name, sizeof(dev[0].name),
						"%s%d",
						ccb.cdm.matches[device].result.periph_result.periph_name,
						ccb.cdm.matches[device].result.periph_result.unit_number);
					msg_debug(2, "%s: periph %s have stat", __FUNCTION__, dev[0].name);
					if (dev[0].device == 2)
						stat_hdd_refresh_ata_device_params(&dev[0]);
					if (dev[0].device == 3)
						stat_hdd_refresh_cam_device_params(&dev[0]);

					if (f_stat_hdd_command_hdd_list) {
						tm = get_remote_tm();
						printf("%lu hdd_exists:%s 1\n",
							(u_long)tm, dev[0].name);
					}
					if (f_stat_hdd_command_hdd) {
						sectors = stat_hdd_get_device_size(&dev[0]);
						tm = get_remote_tm();
						printf("%lu hdd_model:%s %s\n",
							(u_long)tm, dev[0].name, dev[0].model);
						printf("%lu hdd_serno:%s %s\n",
							(u_long)tm, dev[0].name, dev[0].serial);
						printf("%lu hdd_revision:%s %s\n",
							(u_long)tm, dev[0].name, dev[0].revision);
						printf("%lu hdd_size_sectors:%s %llu\n",
							(u_long)tm, dev[0].name, sectors);
						printf("%lu hdd_size_mbytes:%s %llu\n",
							(u_long)tm, dev[0].name, sectors >> 11);
						stat_hdd_print_devstat(dev[0].name);
					}
					stat_hdd_fake_devstat(dev[0].name);
					if (!f_stat_hdd_command_smart)
						break;
					/* Now i don't know how to read SMART from SCSI */
					if (dev[0].device == 3) {
						break;
					}
			
					f_smart_supported = stat_hdd_is_smart_supported(&dev[0]);
					f_smart_enabled = stat_hdd_is_smart_enabled(&dev[0]);
					if (conf.f_enable_smart
						&& f_ata_request_supported
						&& f_smart_supported
						&& !f_smart_enabled
						&& stat_hdd_ata_command_interface(&dev[0], SMART_ENABLE_OPERATIONS, NULL)) {
						f_smart_enabled = 1;
						msg_notice("SMART has been successfully enabled on device %s", dev[0].name);
					}
					tm = get_remote_tm();
					printf("%lu smart_supported:%s %d\n", (u_long)tm, dev[0].name, f_smart_supported);
					printf("%lu smart_enabled:%s %d\n", (u_long)tm, dev[0].name, f_smart_enabled);
					if (!f_stat_hdd_smart_attrs_requested) {
						msg_debug(2, "%s: No SMART attributes requested", __FUNCTION__);
						break;
					}
					if (!f_smart_supported) {
						msg_debug(2, "%s: SMART is not supported by device", __FUNCTION__);
						break;
					}
					if (!f_smart_enabled) {
						msg_debug(2, "%s: SMART is not enabled on device", __FUNCTION__);
						break;
					}
					if (!stat_hdd_ata_command_interface(&dev[0], SMART_READ_VALUES, (char *)&dev[0].smart_values))
						break;
					msg_debug(2, "%s: Got SMART values", __FUNCTION__);
					if (!stat_hdd_ata_command_interface(&dev[0], SMART_READ_THRESHOLDS, (char *)&dev[0].smart_thresholds))
						break;
					msg_debug(2, "%s: Got SMART thresholds", __FUNCTION__);
					stat_hdd_process_smart_attributes(&dev[0]);

					break;
				}
			}
		}
	}