[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Code for SCSI transaction log in dvd+rw-tools



Hi,
 
attached is a patch to let dvd+rw-tools report its SCSI transactions
on stderr.
 
The patch is based on growisofs-7.1.tar.gz of march 2008.
At least one of the changes is already addressed by Debian's dvd+rw-tools:
 
  +/* To compensate bit rot: "INT_MAX was not declared in this scope"
  +*/
  +#include <limits.h>
  +
 
Another noteworthy aspect is that the log cannot be enabled or disabled
at run time, but only at compile time. A new private variable of
class Scsi_Command and a setter method for it would be an improvement.
 
Have a nice day :)
 
Thomas
 
--- dvd+rw-tools-7.1.orig/transport.hxx	2008-03-01 11:34:43.000000000 +0100
+++ dvd+rw-tools-7.1.scsi_log/transport.hxx	2018-03-23 09:03:00.466581766 +0100
@@ -6,6 +6,12 @@
 // For further details see http://fy.chalmers.se/~appro/linux/DVD+RW/
 //

+
+/* If this is defined, then the SCSI transactions are logged to stderr.
+*/
+#define Libburnish_scsi_log_to_stderR 1
+
+
 #if defined(__unix) || defined(__unix__)
 #include <stdio.h>
 #include <stdlib.h>
@@ -17,6 +23,10 @@
 #include <poll.h>
 #include <sys/time.h>

+/* To compensate bit rot: "INT_MAX was not declared in this scope"
+*/
+#include <limits.h>
+
 inline long getmsecs()
 { struct timeval tv;
     gettimeofday (&tv,NULL);
@@ -281,8 +291,17 @@ public:
 	{   sg_io.dxferp		= buf;
 	    sg_io.dxfer_len		= sz;
 	    sg_io.dxfer_direction	= use_sg_io[dir];
+
+#ifdef Libburnish_scsi_log_to_stderR
+            show_cmd_text(&sg_io, stderr, 0);
+#endif /* Libburnish_scsi_log_to_stderR */
+
 	    if (ioctl (fd,SG_IO,&sg_io)) return -1;

+#ifdef Libburnish_scsi_log_to_stderR
+            show_cmd_reply(&sg_io, stderr, 0);
+#endif /* Libburnish_scsi_log_to_stderR */
+
 #if !KERNEL_BROKEN
 	    if ((sg_io.info&SG_INFO_OK_MASK) != SG_INFO_OK)
 #else
@@ -312,6 +331,136 @@ public:
 	}
 	return ret;
     }
+
+#ifdef Libburnish_scsi_log_to_stderR
+#ifdef SG_IO
+    /* This is my own code from libburn adapted to Linux SG_IO rather than
+       the generic command structure of libburn.
+       Permission is granted to use it in any way.
+       Thomas Schmitt, scdbackup@gmx.net, 2009
+    */
+    char *scsi_command_name(unsigned int c, int flag)
+    {
+	switch (c) {
+        case 0x00:
+		return (char *) "TEST UNIT READY";
+        case 0x03:
+		return (char *) "REQUEST SENSE";
+        case 0x04:
+		return (char *) "FORMAT UNIT";
+        case 0x1b:
+		return (char *) "START/STOP UNIT";
+	case 0x12:
+		return (char *) "INQUIRY";
+	case 0x1e:
+		return (char *) "PREVENT/ALLOW MEDIA REMOVAL";
+        case 0x23:
+		return (char *) "READ FORMAT CAPACITIES";
+        case 0x25:
+		return (char *) "READ CAPACITY";
+        case 0x28:
+		return (char *) "READ(10)";
+        case 0x2a:
+		return (char *) "WRITE(10)";
+        case 0x35:
+		return (char *) "SYNCHRONIZE CACHE";
+        case 0x43:
+		return (char *) "READ TOC/PMA/ATIP";
+        case 0x46:
+		return (char *) "GET CONFIGURATION";
+        case 0x4a:
+		return (char *) "GET EVENT STATUS NOTIFICATION";
+        case 0x51:
+		return (char *) "READ DISC INFORMATION";
+        case 0x52:
+		return (char *) "READ TRACK INFORMATION";
+        case 0x53:
+		return (char *) "RESERVE TRACK";
+        case 0x54:
+		return (char *) "SEND OPC INFORMATION";
+        case 0x55:
+		return (char *) "MODE SELECT";
+	case 0x5a:
+		return (char *) "MODE SENSE";
+        case 0x5b:
+		return (char *) "CLOSE TRACK/SESSION";
+        case 0x5c:
+		return (char *) "READ BUFFER CAPACITY";
+        case 0x5d:
+		return (char *) "SEND CUE SHEET";
+        case 0xa1:
+		return (char *) "BLANK";
+        case 0xaa:
+		return (char *) "WRITE(12)";
+        case 0xac:
+		return (char *) "GET PERFORMANCE";
+        case 0xad:
+		return (char *) "READ DISC STRUCTURE";
+        case 0xb6:
+		return (char *) "SET STREAMING";
+        case 0xbb:
+		return (char *) "SET CD SPEED";
+        case 0xbe:
+		return (char *) "READ CD";
+	}
+	return (char *) "(NOT IN COMMAND LIST)";
+    }
+    int show_cmd_text(sg_io_hdr_t *s, FILE *fp, int flag)
+    {
+	int i;
+
+	fprintf(fp, "\n%s\n",
+		 scsi_command_name((unsigned int) s->cmdp[0], 0));
+	for(i = 0; i < 16 && i < s->cmd_len; i++)
+		fprintf(fp, "%2.2x ", s->cmdp[i]);
+	if (i > 0)
+		fprintf(fp, "\n");
+	if (flag & 1)
+		return 1;
+	if (s->cmdp[0] == 0x2A) { /* WRITE 10 */
+		;
+	} else if (s->cmdp[0] == 0xAA) { /* WRITE 12 */
+		;
+	} else if (s->dxfer_direction == SG_DXFER_TO_DEV) {
+		fprintf(fp, "To drive: %db\n", s->dxfer_len);
+		for (i = 0; i < s->dxfer_len; i++)
+			fprintf(fp, "%2.2x%c", ((unsigned char *) s->dxferp)[i],
+				((i % 20) == 19 ? '\n' : ' '));
+		if (i % 20)
+			fprintf(fp, "\n");
+	}
+	return 1;
+    }
+    int show_cmd_reply(sg_io_hdr_t *s, FILE *fp, int flag)
+    {
+	int i;
+	if (s->sb_len_wr) {
+		fprintf(fp,
+			"+++ key=%X  asc=%2.2Xh  ascq=%2.2Xh   (%6d ms)\n",
+			((unsigned char *) s->sbp)[2],
+			((unsigned char *) s->sbp)[12],
+			((unsigned char *) s->sbp)[13], s->duration);
+		return 0;
+	}
+	if (s->dxfer_direction != SG_DXFER_FROM_DEV) {
+		/* No reply expected */;
+	} else if (s->cmdp[0] == 0x28 || s->cmdp[0] == 0x3C ||
+		    s->cmdp[0] == 0xA8 || s->cmdp[0] == 0xBE) {
+		/* READ commands */;
+	} else {
+		fprintf(fp, "From drive: %db\n", s->dxfer_len);
+		for (i = 0; i < s->dxfer_len; i++)
+			fprintf(fp, "%2.2x%c", ((unsigned char *) s->dxferp)[i],
+						((i % 20) == 19 ? '\n' : ' '));
+		if (i % 20)
+			fprintf(fp, "\n");
+	}
+	fprintf(fp,"%6d ms\n", s->duration);
+	return 1;
+    }
+#endif /* SG_IO */
+#endif /* Libburnish_scsi_log_to_stderR */
+
     int umount(int f=-1)
     { struct stat    fsb,msb;
       struct mntent *mb;

Reply to: