Subject: chio diff to display vendor specific data
To: None <current-users@netbsd.org>
From: Stoned Elipot <seb@ssr.univ-paris7.fr>
List: current-users
Date: 05/27/2004 19:22:31
--YD3LsXFS42OYHhNZ
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi,
I made a simple patch to chio(1) so it displays the vendor specific
data your SCSI changer device may report. This patch is attached here.

FYI I tested this on 1.6.2_STABLE but I've been told it runs
on 1.6Zsomething and the patch applies and builds on today's -current.

For me it reports:
:;./chio status
picker 0: <>
...
drive 0: <ACCESS,EXCEPT,FULL> (st0)
        From: slot 1
        Vendor-specific data size: 16
        Vendor-specific data: 0002692569\0\0\0\0\0\0

This data (vis(3) VIS_CSTYLE encoded) is the drive S/N... not really
interesting I guess. You might get something more interesting ;)

Cheers, Stoned.

--YD3LsXFS42OYHhNZ
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="chio.diffs"

? chio.diffs
Index: chio.c
===================================================================
RCS file: /cvsroot/src/bin/chio/chio.c,v
retrieving revision 1.18
diff -u -u -r1.18 chio.c
--- chio.c	2 May 2002 13:07:01 -0000	1.18
+++ chio.c	27 May 2004 16:19:40 -0000
@@ -63,6 +63,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <vis.h>
 
 #include "defs.h"
 #include "pathnames.h"
@@ -466,9 +467,11 @@
 	struct changer_element_status_request cmd;
 	struct changer_params data;
 	struct changer_element_status *ces;
-	int i, chet, count, echet, flags, have_ucount, have_unit;
+	int i, j, chet, count, echet, flags, have_ucount, have_unit;
 	int schet, ucount, unit;
-	size_t size;
+	void **vendor_data;
+	char *v_vdata;
+	size_t size, max_vendor_len;
 
 	flags = 0;
 	have_ucount = 0;
@@ -616,10 +619,6 @@
 		cmd.cesr_count = ucount;
 		cmd.cesr_flags = flags;
 		cmd.cesr_data = ces;
-
-		/*
-		 * Should we deal with this eventually?
-		 */
 		cmd.cesr_vendor_data = NULL;
 
 		if (ioctl(changer_fd, CHIOGSTATUS, &cmd)) {
@@ -627,6 +626,42 @@
 			err(1, "%s: CHIOGSTATUS", changer_name);
 		}
 
+		vendor_data = malloc(ucount * sizeof(void *));
+		if (vendor_data == NULL)
+			errx(1, "can't allocate vendor data storage");
+		max_vendor_len = 0;
+		for (i = 0; i < ucount; i++) {
+			if (ces[i].ces_vendor_len == 0) {
+				*(vendor_data + i) = NULL;
+				continue;
+			}
+			if (ces[i].ces_vendor_len > max_vendor_len)
+				max_vendor_len = ces[i].ces_vendor_len;
+			*(vendor_data + i) =
+				malloc(ces[i].ces_vendor_len * sizeof(uint8_t));
+			if (*(vendor_data + i) == NULL) {
+				for (j = 0; j < i; j++)
+					if (*(vendor_data + j) != NULL)
+						free(*(vendor_data + j));
+				free(vendor_data);
+				errx(1, "can't allocate vendor data storage");
+			}
+		}
+		cmd.cesr_vendor_data = vendor_data;
+		v_vdata = malloc((4 * max_vendor_len * sizeof(char)) + 1);
+		if (v_vdata == NULL) {
+			for (i = 0; i < ucount; i++)
+				if (*(vendor_data + i) != NULL)
+					free(*(vendor_data + i));
+			free(vendor_data);
+			errx(1, "can't allocate vendor data storage");
+		}
+
+		if (ioctl(changer_fd, CHIOGSTATUS, &cmd)) {
+			free(ces);
+			err(1, "%s: CHIOGSTATUS", changer_name);
+		}
+
 		/* Dump the status for each element of this type. */
 		for (i = 0; i < ucount; i++) {
 			(void)printf("%s %d: ", elements[chet].et_name,
@@ -654,10 +689,19 @@
 				(void)printf("\tFrom: %s %d\n",
 				    elements[ces[i].ces_from_type].et_name,
 				    ces[i].ces_from_unit);
-			if (ces[i].ces_vendor_len)
+			if (ces[i].ces_vendor_len) {
+				(void)strvisx(v_vdata,
+				    *(vendor_data + i),
+				    ces[i].ces_vendor_len, 
+				    VIS_CSTYLE|VIS_WHITE);
 				(void)printf("\tVendor-specific data size: "
 				    "%lu\n", (u_long)ces[i].ces_vendor_len);
+				(void)printf("\tVendor-specific data: "
+				    "%s\n", v_vdata);
+				free(*(vendor_data + i));
+			}
 		}
+		free(vendor_data);
 		free(ces);
 	}
 

--YD3LsXFS42OYHhNZ--