xref: /illumos-gate/usr/src/cmd/sasinfo/printAttrs.c (revision 21f023df5de311466c7fef39e70e23b3551a16d5)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include <ctype.h>
27 #include <printAttrs.h>
28 
29 static SAS_STATE hbastatus_string[] = {
30 	HBA_STATUS_OK,				"Okay",
31 	HBA_STATUS_ERROR,			"Error",
32 	HBA_STATUS_ERROR_NOT_SUPPORTED,		"Not Supported",
33 	HBA_STATUS_ERROR_INVALID_HANDLE,	"Invalid Handle",
34 	HBA_STATUS_ERROR_ARG,			"Argument Error",
35 	HBA_STATUS_ERROR_ILLEGAL_WWN,		"Illegal WWN",
36 	HBA_STATUS_ERROR_ILLEGAL_INDEX,		"Illegal Index",
37 	HBA_STATUS_ERROR_MORE_DATA,		"Not Enough Buffer for Data",
38 	HBA_STATUS_ERROR_STALE_DATA,		"Stale Data",
39 	HBA_STATUS_SCSI_CHECK_CONDITION,	"SCSI Check Condition",
40 	HBA_STATUS_ERROR_BUSY,			"Busy",
41 	HBA_STATUS_ERROR_TRY_AGAIN,		"Try Again",
42 	HBA_STATUS_ERROR_UNAVAILABLE,		"Unavailable",
43 	HBA_STATUS_ERROR_ELS_REJECT,		"ELS Reject",
44 	HBA_STATUS_ERROR_INVALID_LUN,		"Invalid LUN",
45 	HBA_STATUS_ERROR_INCOMPATIBLE,		"Request Incompatible",
46 	HBA_STATUS_ERROR_AMBIGUOUS_WWN,		"Ambiguous WWN",
47 	HBA_STATUS_ERROR_LOCAL_BUS,		"Local Bus Error",
48 	HBA_STATUS_ERROR_LOCAL_TARGET,		"Local Target Error",
49 	HBA_STATUS_ERROR_LOCAL_LUN,		"Local LUN Error",
50 	HBA_STATUS_ERROR_LOCAL_SCSIID_BOUND,	"Local SCSIID Bound",
51 	HBA_STATUS_ERROR_TARGET_FCID,		"Target FCID Error",
52 	HBA_STATUS_ERROR_TARGET_NODE_WWN,	"Target Node WWN Error",
53 	HBA_STATUS_ERROR_TARGET_PORT_WWN,	"Target Port WWN Error",
54 	HBA_STATUS_ERROR_TARGET_LUN,		"Target LUN Error",
55 	HBA_STATUS_ERROR_TARGET_LUID,		"Target LUID Error",
56 	HBA_STATUS_ERROR_NO_SUCH_BINDING,	"No Such Binding",
57 	HBA_STATUS_ERROR_NOT_A_TARGET,		"Not a Target",
58 	HBA_STATUS_ERROR_UNSUPPORTED_FC4,	"Unsupported FC4",
59 	HBA_STATUS_ERROR_INCAPABLE,		"Incapable",
60 	HBA_STATUS_ERROR_TARGET_BUSY,		"Target Busy",
61 	HBA_STATUS_ERROR_NOT_LOADED,		"Not Loaded",
62 	HBA_STATUS_ERROR_ALREADY_LOADED,	"Alreday Loaded",
63 	HBA_STATUS_ERROR_ILLEGAL_FCID,		"Illegal FCID",
64 	HBA_STATUS_ERROR_NOT_ASCSIDEVICE,	"Not a SCSI Device",
65 	HBA_STATUS_ERROR_INVALID_PROTOCOL_TYPE,	"Invalid Protocol Type",
66 	HBA_STATUS_ERROR_BAD_EVENT_TYPE,	"Bad Event Type",
67 	-1,					NULL
68 };
69 
70 SAS_STATE porttype_string[] = {
71 	HBA_PORTTYPE_UNKNOWN,		"UNKNOWN",
72 	HBA_PORTTYPE_OTHER,		"OTHER",
73 	HBA_PORTTYPE_NOTPRESENT,	"NOT Present",
74 	HBA_PORTTYPE_SASDEVICE,		"SAS Device",
75 	HBA_PORTTYPE_SATADEVICE,	"SATA Device",
76 	HBA_PORTTYPE_SASEXPANDER, 	"SAS Expander",
77 	-1,				NULL,
78 };
79 
80 SAS_STATE portstate_string[] = {
81 	HBA_PORTSTATE_UNKNOWN,		"unknown",
82 	HBA_PORTSTATE_ONLINE,		"online",
83 	HBA_PORTSTATE_OFFLINE,		"offline",
84 	HBA_PORTSTATE_BYPASSED,		"bypassed",
85 	HBA_PORTSTATE_DIAGNOSTICS,	"diagnostics",
86 	HBA_PORTSTATE_LINKDOWN,		"link Down",
87 	HBA_PORTSTATE_ERROR,		"port Error",
88 	HBA_PORTSTATE_LOOPBACK,		"loopback",
89 	HBA_PORTSTATE_DEGRADED,		"degraded",
90 	-1,				NULL,
91 };
92 
93 static SAS_STATE phystate_string[] = {
94 	HBA_SASSTATE_UNKNOWN,		"unknown",
95 	HBA_SASSTATE_DISABLED,		"disabled",
96 	HBA_SASSTATE_FAILED,		"failed",
97 	HBA_SASSTATE_SATASPINUP,	"sata-spinup",
98 	HBA_SASSTATE_SATAPORTSEL,	"sata-portselector",
99 	HBA_SASSPEED_1_5GBIT,		"1.5Gbit",
100 	HBA_SASSPEED_3GBIT,		"3Gbit",
101 	HBA_SASSPEED_6GBIT,		"6Gbit",
102 	HBA_SASSPEED_12GBIT,		"12Gbit",
103 	-1,				NULL,
104 };
105 
106 static SAS_STATE dtype_string[] = {
107 	DTYPE_DIRECT,			"Disk Device",
108 	DTYPE_SEQUENTIAL,		"Tape Device",
109 	DTYPE_PRINTER,			"Printer Device",
110 	DTYPE_PROCESSOR,		"Processor Device",
111 	DTYPE_WORM,			"WORM Device",
112 	DTYPE_RODIRECT,			"CD/DVD Device",
113 	DTYPE_SCANNER,			"Scanner Device",
114 	DTYPE_OPTICAL,			"Optical Memory Device",
115 	DTYPE_CHANGER,			"Medium Changer Device",
116 	DTYPE_COMM,			"Communications Device",
117 	DTYPE_ARRAY_CTRL,		"Storage Array Controller Device",
118 	DTYPE_ESI,			"Enclosure Services Device",
119 	DTYPE_RBC,			"Simplified Direct-access Device",
120 	DTYPE_OCRW,			"Optical Card Reader/Writer Device",
121 	DTYPE_BCC,			"Bridge Controller Commands",
122 	DTYPE_OSD,			"Object-based Storage Device",
123 	DTYPE_ADC,			"Automation/Drive Interface",
124 	DTYPE_WELLKNOWN,		"Well Known Logical Unit",
125 	DTYPE_UNKNOWN,			"Unknown Device",
126 	-1,				NULL
127 };
128 
129 static char *getPhyStateString(HBA_UINT32 key, phystat_type phyt);
130 
131 char *
132 getIndentSpaces(int number)
133 {
134 	int 		i = 0;
135 	/* the maximum indent with terminator '\0' */
136 	static char	ret[MAXINDENT+1];
137 
138 	if (number > MAXINDENT)
139 		number = MAXINDENT;
140 
141 	for (i = 0; i < number; i++) {
142 		ret[i] = ' ';
143 	}
144 	ret[i] = '\0';
145 	return (ret);
146 }
147 
148 char *
149 getStateString(HBA_UINT32 key, SAS_STATE *stat_string)
150 {
151 	static char ret[64];
152 	while (stat_string->key != -1) {
153 		if (stat_string->key == key) {
154 			return ((char *)stat_string->value);
155 		}
156 		stat_string++;
157 	}
158 	(void *) sprintf(ret, "Undefined value (%d)", key);
159 	return (ret);
160 }
161 
162 static char *
163 getPhyStateString(HBA_UINT32 key, phystat_type phyt)
164 {
165 	int i = 0, len = 0, match = 0;
166 	HBA_UINT32 physpeed[] = {
167 		HBA_SASSPEED_1_5GBIT,
168 		HBA_SASSPEED_3GBIT,
169 		HBA_SASSPEED_6GBIT,
170 		HBA_SASSPEED_12GBIT
171 	};
172 
173 	len = sizeof (physpeed) / sizeof (HBA_UINT32);
174 	for (i = 0; i < len; i++) {
175 		if (key == physpeed[i]) {
176 			match = 1;
177 			break;
178 		}
179 	}
180 
181 	if (match == 1) {
182 		if (phyt == PHY_STATE)
183 			return ("enabled");
184 		else
185 			return (getStateString(key, phystate_string));
186 	} else {
187 		if (phyt == PHY_STATE)
188 			return (getStateString(key, phystate_string));
189 		else
190 			return ("not available");
191 	}
192 }
193 
194 char *
195 getHBAStatus(HBA_STATUS key)
196 {
197 	return (getStateString(key, hbastatus_string));
198 }
199 
200 /*
201  * return device type description
202  *
203  * Arguments:
204  *	dType - Device type returned from Standard INQUIRY
205  * Returns:
206  *	char string description for device type
207  */
208 char *
209 getDTypeString(uchar_t dType)
210 {
211 	return (getStateString((dType & DTYPE_MASK), dtype_string));
212 }
213 
214 uint64_t
215 wwnConversion(uchar_t *wwn)
216 {
217 	uint64_t tmp;
218 	(void *) memcpy(&tmp, wwn, sizeof (uint64_t));
219 	return (ntohll(tmp));
220 }
221 
222 /*
223  * prints out HBA information
224  */
225 void
226 printHBAInfo(SMHBA_ADAPTERATTRIBUTES *attrs, int pflag, int numberOfPorts,
227     const char *adapterName)
228 {
229 
230 	(void *) fprintf(stdout, "%s %s\n", "HBA Name:", adapterName);
231 
232 	if (pflag & PRINT_VERBOSE) {
233 		(void *) fprintf(stdout, "%s%s %s\n",
234 		    getIndentSpaces(4), "Manufacturer:",
235 		    attrs->Manufacturer[0] == 0?
236 		    "not available":attrs->Manufacturer);
237 		(void *) fprintf(stdout, "%s%s %s\n",
238 		    getIndentSpaces(4), "Model: ",
239 		    attrs->Model[0] == 0? "not available":attrs->Model);
240 		(void *) fprintf(stdout, "%s%s %s\n",
241 		    getIndentSpaces(4),
242 		    "Firmware Version:",
243 		    attrs->FirmwareVersion[0] == 0? "not available":
244 		    attrs->FirmwareVersion);
245 		(void *) fprintf(stdout, "%s%s %s\n",
246 		    getIndentSpaces(4),
247 		    "FCode/BIOS Version:",
248 		    attrs->OptionROMVersion[0] == 0? "not available":
249 		    attrs->OptionROMVersion);
250 		(void *) fprintf(stdout, "%s%s %s\n",
251 		    getIndentSpaces(4),
252 		    "Serial Number:",
253 		    attrs->SerialNumber[0] == 0? "not available":
254 		    attrs->SerialNumber);
255 		(void *) fprintf(stdout, "%s%s %s\n",
256 		    getIndentSpaces(4),
257 		    "Driver Name:",
258 		    attrs->DriverName[0] == 0? "not available":
259 		    attrs->DriverName);
260 		(void *) fprintf(stdout, "%s%s %s\n",
261 		    getIndentSpaces(4),
262 		    "Driver Version:",
263 		    attrs->DriverVersion[0] == 0? "not available":
264 		    attrs->DriverVersion);
265 		(void *) fprintf(stdout, "%s%s %d\n",
266 		    getIndentSpaces(4),
267 		    "Number of HBA Ports:",
268 		    numberOfPorts);
269 	}
270 }
271 
272 /*
273  * prints out all the HBA port information
274  */
275 void
276 printHBAPortInfo(SMHBA_PORTATTRIBUTES *port,
277     SMHBA_ADAPTERATTRIBUTES *attrs, int pflag) {
278 
279 	if ((port == NULL) || (attrs == NULL)) {
280 		return;
281 	}
282 
283 	(void *) fprintf(stdout, "%s%s %s\n",
284 	    getIndentSpaces(2),
285 	    "HBA Port Name:",
286 	    port->OSDeviceName);
287 
288 	if (!(pflag & PRINT_VERBOSE)) {
289 		return;
290 	}
291 
292 	if (port->PortType != HBA_PORTTYPE_SASDEVICE)
293 		return;
294 
295 	(void *) fprintf(stdout, "%s%s %s\n",
296 	    getIndentSpaces(4),
297 	    "Type:",
298 	    getStateString(port->PortType, porttype_string));
299 	(void *) fprintf(stdout, "%s%s %s\n",
300 	    getIndentSpaces(4),
301 	    "State:",
302 	    getStateString(port->PortState, portstate_string));
303 
304 	(void *) fprintf(stdout, "%s%s %016llx\n",
305 	    getIndentSpaces(4),
306 	    "Local SAS Address:",
307 	    wwnConversion(port->PortSpecificAttribute.SASPort->\
308 	    LocalSASAddress.wwn));
309 
310 	(void *) fprintf(stdout, "%s%s %016llx\n",
311 	    getIndentSpaces(4),
312 	    "Attached SAS Address:",
313 	    wwnConversion(port->PortSpecificAttribute.SASPort->\
314 	    AttachedSASAddress.wwn));
315 
316 	(void *) fprintf(stdout, "%s%s %d\n",
317 	    getIndentSpaces(4),
318 	    "Number of Phys:",
319 	    port->PortSpecificAttribute.SASPort->NumberofPhys);
320 }
321 
322 void
323 printHBAPortPhyInfo(SMHBA_SAS_PHY *phyinfo)
324 {
325 	if (phyinfo == NULL)
326 		return;
327 
328 	(void *) fprintf(stdout, "%s%s %u\n",
329 	    getIndentSpaces(6),
330 	    "Identifier:",
331 	    phyinfo->PhyIdentifier);
332 
333 	(void *) fprintf(stdout, "%s%s %s\n",
334 	    getIndentSpaces(8),
335 	    "State: ",
336 	    getPhyStateString(phyinfo->NegotiatedLinkRate, PHY_STATE));
337 	(void *) fprintf(stdout, "%s%s %s/%s\n",
338 	    getIndentSpaces(8),
339 	    "HardwareLinkRate(Min/Max):",
340 	    getPhyStateString(phyinfo->HardwareMinLinkRate, PHY_SPEED),
341 	    getPhyStateString(phyinfo->HardwareMaxLinkRate, PHY_SPEED));
342 	(void *) fprintf(stdout, "%s%s %s/%s\n",
343 	    getIndentSpaces(8),
344 	    "ProgrammedLinkRate(Min/Max):",
345 	    getPhyStateString(phyinfo->ProgrammedMinLinkRate, PHY_SPEED),
346 	    getPhyStateString(phyinfo->ProgrammedMaxLinkRate, PHY_SPEED));
347 	(void *) fprintf(stdout, "%s%s %s\n",
348 	    getIndentSpaces(8),
349 	    "NegotiatedLinkRate:",
350 	    getPhyStateString(phyinfo->NegotiatedLinkRate, PHY_SPEED));
351 }
352 
353 void
354 printHBAPortPhyStatistics(SMHBA_SASPHYSTATISTICS *phystat)
355 {
356 	if (phystat == NULL)
357 		return;
358 
359 	(void *) fprintf(stdout, "%s%s\n",
360 	    getIndentSpaces(8),
361 	    "Link Error Statistics:");
362 	(void *) fprintf(stdout, "%s%s %llu\n",
363 	    getIndentSpaces(12),
364 	    "Invalid Dword:",
365 	    phystat->InvalidDwordCount);
366 	(void *) fprintf(stdout, "%s%s %llu\n",
367 	    getIndentSpaces(12),
368 	    "Running Disparity Error:",
369 	    phystat->RunningDisparityErrorCount);
370 	(void *) fprintf(stdout, "%s%s %llu\n",
371 	    getIndentSpaces(12),
372 	    "Loss of Dword Sync:",
373 	    phystat->LossofDwordSyncCount);
374 	(void *) fprintf(stdout, "%s%s %llu\n",
375 	    getIndentSpaces(12),
376 	    "Reset Problem:",
377 	    phystat->PhyResetProblemCount);
378 }
379 
380 /*
381  * print the OS device name for the logical-unit object
382  *
383  * Arguments:
384  *	devListWalk - OS device path info
385  *	verbose - boolean indicating whether to display additional info
386  *
387  * returns:
388  * 	0 - we're good.
389  * 	>0 - we met issues.
390  */
391 int
392 printTargetPortInfo(targetPortList_t *TPListWalk, int pflag)
393 {
394 	targetPortConfig_t	*configList;
395 	targetPortMappingData_t	*mapList;
396 	int			count, i;
397 	int			ret = 0;
398 
399 	(void *) fprintf(stdout, "Target Port SAS Address: %016llx\n",
400 	    wwnConversion(TPListWalk->sasattr.LocalSASAddress.wwn));
401 	if ((pflag & PRINT_VERBOSE) || (pflag & PRINT_TARGET_SCSI)) {
402 		(void *) fprintf(stdout, "%sType: %s\n", getIndentSpaces(4),
403 		    getStateString(TPListWalk->targetattr.PortType,
404 		    porttype_string));
405 		for (configList = TPListWalk->configEntry;
406 		    configList != NULL; configList = configList->next) {
407 			(void *) fprintf(stdout, "%sHBA Port Name: %s\n",
408 			    getIndentSpaces(4), configList->hbaPortName);
409 			if (wwnConversion(configList->expanderSASAddr.wwn) !=
410 			    0) {
411 				if (configList->expanderValid) {
412 					(void *) fprintf(stdout,
413 					    "%sExpander Device SAS Address:"
414 					    " %016llx",
415 					    getIndentSpaces(8),
416 					    wwnConversion(configList->
417 					    expanderSASAddr.wwn));
418 				} else {
419 					(void *) fprintf(stdout,
420 					    "%sExpander Device SAS Address:"
421 					    " %016llx (Failed to Validate"
422 					    " Attached Port.)",
423 					    getIndentSpaces(8),
424 					    wwnConversion(configList->
425 					    expanderSASAddr.wwn));
426 					ret++;
427 				}
428 			} else {
429 				if (configList->expanderValid) {
430 					(void *) fprintf(stdout,
431 					    "%sExpander Device SAS Address: %s",
432 					    getIndentSpaces(8),
433 					    "None (direct attached)");
434 				} else {
435 					(void *) fprintf(stdout,
436 					    "%sExpander Device SAS Address: %s",
437 					    getIndentSpaces(8),
438 					    "None (Failed to Get"
439 					    " Attached Port)");
440 				}
441 			}
442 			(void *) fprintf(stdout, "\n");
443 			if (pflag & PRINT_TARGET_SCSI) {
444 
445 				if (configList->reportLUNsFailed) {
446 					(void *) fprintf(stdout,
447 					    "%s %016llx\n",
448 					    gettext("Error: Failed to get "
449 					    "ReportLun Data on"),
450 					    wwnConversion(TPListWalk->
451 					    sasattr.LocalSASAddress.wwn));
452 					ret++;
453 					continue;
454 				}
455 
456 				for (mapList = configList->map;
457 				    mapList != NULL; mapList = mapList->next) {
458 					(void *) fprintf(stdout, "%sLUN : %d\n",
459 					    getIndentSpaces(12),
460 					    mapList->osLUN);
461 					if (mapList->mappingExist) {
462 						(void *) fprintf(stdout,
463 						    "%sOS Device Name : %s\n",
464 						    getIndentSpaces(14),
465 						    (mapList->osDeviceName[0] ==
466 						    '\0') ?  "Not avaialble" :
467 						    mapList->osDeviceName);
468 					} else {
469 						(void *) fprintf(stdout,
470 						    "%sOS Device Name : %s\n",
471 						    getIndentSpaces(14), "No "
472 						    "matching OS Device "
473 						    "found.");
474 						ret++;
475 					}
476 		/* indentation changed here */
477 		if (mapList->inquiryFailed) {
478 			(void *) fprintf(stdout, "%s %s LUN %d\n",
479 			    gettext("Error: Failed to get Inquiry Data on"),
480 			    mapList->osDeviceName, mapList->osLUN);
481 			ret++;
482 		} else {
483 			(void *) fprintf(stdout, "%sVendor: ",
484 			    getIndentSpaces(14));
485 			for (count = sizeof (mapList->inq_vid), i = 0;
486 			    i < count; i++) {
487 				if (isprint(mapList->inq_vid[i]))
488 					(void *) fprintf(stdout, "%c",
489 					    mapList->inq_vid[i]);
490 			}
491 
492 			(void *) fprintf(stdout, "\n%sProduct: ",
493 			    getIndentSpaces(14));
494 			for (count = sizeof (mapList->inq_pid), i = 0;
495 			    i < count; i++) {
496 				if (isprint(mapList->inq_pid[i]))
497 					(void *) fprintf(stdout, "%c",
498 					    mapList->inq_pid[i]);
499 			}
500 
501 			(void *) fprintf(stdout, "\n%sDevice Type: %s\n",
502 			    getIndentSpaces(14),
503 			    getDTypeString(mapList->inq_dtype));
504 		}
505 		/* indentation changed back */
506 				}
507 			}
508 		}
509 	}
510 	return (ret);
511 }
512 
513 /*
514  * print the OS device name for the logical-unit object
515  *
516  * Arguments:
517  *	devListWalk - OS device path info
518  *	verbose - boolean indicating whether to display additional info
519  *
520  * returns:
521  * 	0 - we're good.
522  * 	>0 - we met issues.
523  */
524 int
525 printOSDeviceNameInfo(discoveredDevice *devListWalk, boolean_t verbose)
526 {
527 	portList		*portElem;
528 	tgtPortWWNList		*tgtWWNList;
529 	int			i, count;
530 	int			ret = 0;
531 
532 	(void *) fprintf(stdout, "OS Device Name: %s\n",
533 	    devListWalk->OSDeviceName);
534 	if (verbose == B_TRUE) {
535 		for (portElem = devListWalk->HBAPortList;
536 		    portElem != NULL; portElem = portElem->next) {
537 			(void *) fprintf(stdout, "%sHBA Port Name: ",
538 			    getIndentSpaces(4));
539 			(void *) fprintf(stdout, "%s", portElem->portName);
540 			for (tgtWWNList = portElem->tgtPortWWN;
541 			    tgtWWNList != NULL; tgtWWNList = tgtWWNList->next) {
542 				(void *) fprintf(stdout,
543 				    "\n%sTarget Port SAS Address: ",
544 				    getIndentSpaces(8));
545 				(void *) fprintf(stdout, "%016llx",
546 				    wwnConversion(tgtWWNList->portWWN.wwn));
547 				(void *) fprintf(stdout, "\n%sLUN: %u",
548 				    getIndentSpaces(12),
549 				    tgtWWNList->scsiOSLun);
550 			}
551 			(void *) fprintf(stdout, "\n");
552 		}
553 
554 		if (devListWalk->inquiryFailed) {
555 			(void *) fprintf(stdout, "%s %s\n",
556 			    gettext("Error: Failed to get Inquiry data "
557 			    "on device"), devListWalk->OSDeviceName);
558 			ret++;
559 		} else {
560 			(void *) fprintf(stdout, "%sVendor: ",
561 			    getIndentSpaces(4));
562 			for (count = sizeof (devListWalk->VID), i = 0;
563 			    i < count; i++) {
564 				if (isprint(devListWalk->VID[i]))
565 					(void *) fprintf(stdout, "%c",
566 					    devListWalk->VID[i]);
567 			}
568 
569 			(void *) fprintf(stdout, "\n%sProduct: ",
570 			    getIndentSpaces(4));
571 			for (count = sizeof (devListWalk->PID), i = 0;
572 			    i < count; i++) {
573 				if (isprint(devListWalk->PID[i]))
574 					(void *) fprintf(stdout, "%c",
575 					    devListWalk->PID[i]);
576 			}
577 
578 			(void *) fprintf(stdout, "\n%sDevice Type: %s\n",
579 			    getIndentSpaces(4),
580 			    getDTypeString(devListWalk->dType));
581 		}
582 	}
583 	return (ret);
584 }
585