From 6c9b5a441966211c2639e27e27e08fec71de51f3 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Thu, 10 Nov 2011 15:37:32 +0000 Subject: [PATCH] Logging of early SCSI commands of Linux system adapter to stderr --- cdrskin/cdrskin_timestamp.h | 2 +- libburn/sg-linux.c | 55 ++++++++++++++- libburn/spc.c | 135 ++++++++++++++++++++++++++---------- libburn/spc.h | 23 ++++-- 4 files changed, 171 insertions(+), 44 deletions(-) diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index dd1d7d4..ff8beee 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2011.11.10.134432" +#define Cdrskin_timestamP "2011.11.10.153659" diff --git a/libburn/sg-linux.c b/libburn/sg-linux.c index 26d4b4f..f1c2a88 100644 --- a/libburn/sg-linux.c +++ b/libburn/sg-linux.c @@ -376,10 +376,48 @@ static int sg_exchange_scd_for_sr(char *fname, int flag) } +/* ts B11110 */ +/* This is an early stage version of scsi_log_cmd. + >>> It will become obsolete when the /tmp file handler is moved into + >>> scsi_log_command(). +*/ +static int sgio_log_cmd(unsigned char *cmd, int cmd_len, FILE *fp_in, int flag) +{ + FILE *fp = fp_in; + int ret; + + /* >>> ts B11110 : move this into scsi_log_command() */ + if (fp == NULL && (burn_sg_log_scsi & 1)) { + fp= fopen("/tmp/libburn_sg_command_log", "a"); + fprintf(fp, "\n=========================================\n"); + } + + ret = scsi_log_command(cmd, cmd_len, NO_TRANSFER, NULL, 0, fp, flag); + if (fp_in == NULL && fp != NULL) + fclose(fp); + return ret; +} + + +/* ts B11110 */ +static int sgio_log_reply(unsigned char *opcode, int data_dir, + unsigned char *data, int dxfer_len, + void *fp_in, unsigned char sense[18], + int sense_len, int duration, int flag) +{ + int ret; + + ret = scsi_log_reply(opcode, data_dir, data, dxfer_len, fp_in, + sense, sense_len, duration, flag); + return 1; +} + + static int sgio_test(int fd) { unsigned char test_ops[] = { 0, 0, 0, 0, 0, 0 }; sg_io_hdr_t s; + int ret; memset(&s, 0, sizeof(sg_io_hdr_t)); s.interface_id = 'S'; @@ -387,7 +425,14 @@ static int sgio_test(int fd) s.cmd_len = 6; s.cmdp = test_ops; s.timeout = 12345; - return ioctl(fd, SG_IO, &s); + + sgio_log_cmd(s.cmdp, s.cmd_len, NULL, 0); + + ret= ioctl(fd, SG_IO, &s); + + sgio_log_reply(s.cmdp, NO_TRANSFER, NULL, 0, + NULL, s.sbp, s.sb_len_wr, s.duration, 0); + return ret; } @@ -416,6 +461,8 @@ static int sgio_inquiry_cd_drive(int fd, char *fname) s.dxfer_len = 36; s.usr_ptr = NULL; + sgio_log_cmd(s.cmdp, s.cmd_len, NULL, 0); + ret = ioctl(fd, SG_IO, &s); if (ret == -1) { sprintf(msg, @@ -426,6 +473,10 @@ static int sgio_inquiry_cd_drive(int fd, char *fname) msg, 0, 0); goto ex; } + + sgio_log_reply(s.cmdp, FROM_DRIVE, buf->data, s.dxfer_len, + NULL, s.sbp, s.sb_len_wr, s.duration, 0); + if (s.sb_len_wr > 0 || s.host_status != Libburn_sg_host_oK || s.driver_status != Libburn_sg_driver_oK) { sprintf(msg, "INQUIRY failed on '%s' : host_status= %hd , driver_status= %hd", fname, s.host_status, s.driver_status); @@ -1830,6 +1881,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c) d->fd, d->released); mmc_function_spy(NULL, msg); + /* >>> ts B11110 : move this into scsi_log_cmd() together with the + static fp */ /* ts A61030 */ if (burn_sg_log_scsi & 1) { if (fp == NULL) { diff --git a/libburn/spc.c b/libburn/spc.c index 5caaf95..fb74bb4 100644 --- a/libburn/spc.c +++ b/libburn/spc.c @@ -1408,7 +1408,7 @@ static char *scsi_command_name(unsigned int c, int flag) case 0xbe: return "READ CD"; } - return "(NOT IN COMMAND LIST)"; + return "(NOT IN LIBBURN COMMAND LIST)"; } @@ -1456,38 +1456,39 @@ ex:; } -/* ts A91106 */ +/* ts B11110 */ /* @param flag bit0= do not show eventual data payload sent to the drive (never with WRITE commands) - bit1= show write length and target LBA in decimal */ -int scsi_show_cmd_text(struct command *c, void *fp_in, int flag) +int scsi_show_command(unsigned char *opcode, int oplen, int dir, + unsigned char *data, int bytes, + void *fp_in, int flag) { int i; FILE *fp = fp_in; fprintf(fp, "\n%s\n", - scsi_command_name((unsigned int) c->opcode[0], 0)); - for(i = 0; i < 16 && i < c->oplen; i++) - fprintf(fp, "%2.2x ", c->opcode[i]); + scsi_command_name((unsigned int) opcode[0], 0)); + for(i = 0; i < 16 && i < oplen; i++) + fprintf(fp, "%2.2x ", opcode[i]); if (i > 0) fprintf(fp, "\n"); if (flag & 1) return 1; - if (c->opcode[0] == 0x2A) { /* WRITE 10 */ + if (opcode[0] == 0x2A) { /* WRITE 10 */ if (flag & 2) fprintf(fp, "%d -> %d\n", - (c->opcode[7] << 8) | c->opcode[8], - mmc_four_char_to_int(c->opcode + 2)); - } else if (c->opcode[0] == 0xAA) { /* WRITE 12 */ + (opcode[7] << 8) | opcode[8], + mmc_four_char_to_int(opcode + 2)); + } else if (opcode[0] == 0xAA) { /* WRITE 12 */ if (flag & 2) fprintf(fp, "%d -> %d\n", - mmc_four_char_to_int(c->opcode + 6), - mmc_four_char_to_int(c->opcode + 2)); - } else if (c->dir == TO_DRIVE) { - fprintf(fp, "To drive: %db\n", c->page->bytes); - for (i = 0; i < c->page->bytes; i++) - fprintf(fp, "%2.2x%c", c->page->data[i], + mmc_four_char_to_int(opcode + 6), + mmc_four_char_to_int(opcode + 2)); + } else if (dir == TO_DRIVE && !(flag & 1)) { + fprintf(fp, "To drive: %db\n", bytes); + for (i = 0; i < bytes; i++) + fprintf(fp, "%2.2x%c", data[i], ((i % 20) == 19 ? '\n' : ' ')); if (i % 20) fprintf(fp, "\n"); @@ -1495,24 +1496,39 @@ int scsi_show_cmd_text(struct command *c, void *fp_in, int flag) return 1; } + + /* ts A91106 */ -int scsi_show_cmd_reply(struct command *c, void *fp_in, int flag) +/* @param flag bit0= do not show eventual data payload sent to the drive + (never with WRITE commands) +*/ +int scsi_show_cmd_text(struct command *c, void *fp_in, int flag) +{ + return scsi_show_command(c->opcode, c->oplen, c->dir, c->page->data, + c->page->bytes, fp_in, flag); +} + + +/* ts A91106 */ /* ts B11110 */ +int scsi_show_command_reply(unsigned char *opcode, int data_dir, + unsigned char *data, int dxfer_len, + void *fp_in, int flag) { int i; FILE *fp = fp_in; - if (c->dir != FROM_DRIVE) + if (data_dir != FROM_DRIVE) return 2; - if (c->opcode[0] == 0x28 || c->opcode[0] == 0x3C || - c->opcode[0] == 0xA8 || c->opcode[0] == 0xBE) { + if (opcode[0] == 0x28 || opcode[0] == 0x3C || + opcode[0] == 0xA8 || opcode[0] == 0xBE) { /* READ commands */ /* >>> report amount of data */; return 2; } - fprintf(fp, "From drive: %db\n", c->dxfer_len); - for (i = 0; i < c->dxfer_len; i++) - fprintf(fp, "%2.2x%c", c->page->data[i], + fprintf(fp, "From drive: %db\n", dxfer_len); + for (i = 0; i < dxfer_len; i++) + fprintf(fp, "%2.2x%c", data[i], ((i % 20) == 19 ? '\n' : ' ')); if (i % 20) fprintf(fp, "\n"); @@ -1520,31 +1536,51 @@ int scsi_show_cmd_reply(struct command *c, void *fp_in, int flag) } +/* ts B11110 */ +/** Logs command (before execution) */ +int scsi_log_command(unsigned char *opcode, int oplen, int data_dir, + unsigned char *data, int bytes, + void *fp_in, int flag) +{ + FILE *fp = fp_in; + + if (fp != NULL && (fp == stderr || (burn_sg_log_scsi & 1))) { + scsi_show_command(opcode, oplen, data_dir, data, bytes, fp, 0); + if (burn_sg_log_scsi & 4) + fflush(fp); + } + if (fp == stderr || !(burn_sg_log_scsi & 2)) + return 1; + scsi_log_command(opcode, oplen, data_dir, data, bytes, stderr, 0); + return 1; +} + + /* ts A91218 (former sg_log_cmd ts A70518) */ /** Logs command (before execution) */ int scsi_log_cmd(struct command *c, void *fp_in, int flag) { - FILE *fp = fp_in; + int ret, bytes = 0; + unsigned char *data = NULL; - if (fp != NULL && (fp == stderr || (burn_sg_log_scsi & 1))) { - scsi_show_cmd_text(c, fp, 0); - if (burn_sg_log_scsi & 4) - fflush(fp); + if (c->page != NULL) { + data = c->page->data; + bytes = c->page->bytes; } - if (fp == stderr || !(burn_sg_log_scsi & 2)) - return 1; - scsi_log_cmd(c, stderr, flag); - return 1; + ret = scsi_log_command(c->opcode, c->oplen, c->dir, data, bytes, + fp_in, flag); + return ret; } -/* ts A91221 (former sg_log_err ts A91108) */ +/* ts B11110 */ /** Logs outcome of a sg command. @param flag bit0 causes an error message bit1 do not print duration */ -int scsi_log_err(struct command *c, void *fp_in, unsigned char sense[18], - int sense_len, int duration, int flag) +int scsi_log_reply(unsigned char *opcode, int data_dir, unsigned char *data, + int dxfer_len, void *fp_in, unsigned char sense[18], + int sense_len, int duration, int flag) { char durtxt[20]; FILE *fp = fp_in; @@ -1570,7 +1606,9 @@ int scsi_log_err(struct command *c, void *fp_in, unsigned char sense[18], (unsigned int) key, (unsigned int) asc, (unsigned int) ascq, durtxt); } else { - scsi_show_cmd_reply(c, fp, 0); + scsi_show_command_reply(opcode, data_dir, data, + dxfer_len, fp, 0); + if (!(flag & 2)) fprintf(fp,"%6d ms\n", duration); } @@ -1579,11 +1617,32 @@ int scsi_log_err(struct command *c, void *fp_in, unsigned char sense[18], } if (fp == stderr || !(burn_sg_log_scsi & 2)) return 1; - scsi_log_err(c, stderr, sense, sense_len, duration, flag); + scsi_log_reply(opcode, data_dir, data, dxfer_len, + stderr, sense, sense_len, duration, flag); + return 1; } +/* ts A91221 (former sg_log_err ts A91108) */ +/** Legacy frontend to scsi_log_reply(). + @param flag bit0 causes an error message + bit1 do not print duration +*/ +int scsi_log_err(struct command *c, void *fp_in, unsigned char sense[18], + int sense_len, int duration, int flag) +{ + int ret; + unsigned char *data = NULL; + + if (c->page != NULL) + data = c->page->data; + ret= scsi_log_reply(c->opcode, c->dir, data, c->dxfer_len , + fp_in, sense, sense_len, duration, flag); + return ret; +} + + /* ts B00808 */ /* @param flag bit0 = do not retry diff --git a/libburn/spc.h b/libburn/spc.h index 423b7fb..63fbdd1 100644 --- a/libburn/spc.h +++ b/libburn/spc.h @@ -68,15 +68,30 @@ int scsi_init_command(struct command *c, unsigned char *opcode, int oplen); /* ts A91106 */ int scsi_show_cmd_text(struct command *c, void *fp, int flag); -/* ts A91106 */ -int scsi_show_cmd_reply(struct command *c, void *fp, int flag); +/* ts B11110 */ +/** Logs command (before execution). */ +int scsi_log_command(unsigned char *opcode, int oplen, int data_dir, + unsigned char *data, int bytes, + void *fp_in, int flag); /* ts A91218 (former sg_log_cmd ts A70518) */ -/** Logs command (before execution) */ +/** Legacy frontend to scsi_log_command() */ int scsi_log_cmd(struct command *c, void *fp, int flag); +/* ts B11110 */ +/** Logs outcome of a sg command. + @param flag bit0 causes an error message + bit1 do not print duration +*/ +int scsi_log_reply(unsigned char *opcode, int data_dir, unsigned char *data, + int dxfer_len, void *fp_in, unsigned char sense[18], + int sense_len, int duration, int flag); + /* ts A91221 (former sg_log_err ts A91108) */ -/** Logs outcome of a sg command. */ +/** Legacy frontend to scsi_log_reply(). + @param flag bit0 causes an error message + bit1 do not print duration +*/ int scsi_log_err(struct command *c, void *fp, unsigned char sense[18], int sense_len, int duration, int flag);