From 0acbfb9719c96e97c4095c04a3a23b3c66394bc4 Mon Sep 17 00:00:00 2001 From: Thomas Horsten Date: Fri, 18 Sep 2009 10:03:02 +0100 Subject: [PATCH] [atapi-pt] Don't bail out on unknown command, improve trace --- master/atapi-async-fix.patch | 116 +++++++++++++++++++++++++++-------- 1 file changed, 92 insertions(+), 24 deletions(-) diff --git a/master/atapi-async-fix.patch b/master/atapi-async-fix.patch index 7222a22..558a3ee 100644 --- a/master/atapi-async-fix.patch +++ b/master/atapi-async-fix.patch @@ -1,8 +1,8 @@ diff --git a/hw/atapi-pt.c b/hw/atapi-pt.c -index 92f2934..d38d536 100644 +index 92f2934..6a7fab1 100644 --- a/hw/atapi-pt.c +++ b/hw/atapi-pt.c -@@ -1,19 +1,30 @@ +@@ -1,29 +1,43 @@ +#include #include +#include @@ -26,6 +26,7 @@ index 92f2934..d38d536 100644 #ifdef DEBUG_IDE_ATAPI_PT -# define DEBUG_PRINTF(Args...) printf(Args) +# define DEBUG_PRINTF(Args...) atapi_dprintf(Args) ++# define DEBUG_HEXDUMP(addr, count) atapi_dhexdump(addr, count) # define CHECK_SAME_VALUE(Val1, Val2) \ do { \ - if ((Val1) != (Val2)) \ @@ -39,7 +40,8 @@ index 92f2934..d38d536 100644 } while (0) #else # define DEBUG_PRINTF(Args...) -@@ -21,9 +32,10 @@ ++# define DEBUG_HEXDUMP(addr, count) + # define CHECK_SAME_VALUE(Val1, Val2) #endif /* DEBUG_IDE_ATAPI_PT */ @@ -51,7 +53,7 @@ index 92f2934..d38d536 100644 /* The generic packet command opcodes for CD/DVD Logical Units, * From Table 57 of the SFF8090 Ver. 3 (Mt. Fuji) draft standard. */ -@@ -482,6 +494,40 @@ static const char *atapi_sense_to_str(int key, int asc, int ascq) +@@ -482,6 +496,66 @@ static const char *atapi_sense_to_str(int key, int asc, int ascq) } @@ -64,6 +66,7 @@ index 92f2934..d38d536 100644 + struct timeval tv; + va_list args; + int l; ++ static int sol = 1; + if (debug_enabled == 0) + return; + if (debug_enabled < 0) { @@ -78,21 +81,46 @@ index 92f2934..d38d536 100644 + sprintf(debugbuf, IDE_ATAPI_PT_DEBUG_FILE_TEMPLATE, domid); + debug_fd=open(debugbuf, O_WRONLY | O_CREAT | O_APPEND, 0666); + } -+ gettimeofday(&tv, NULL); -+ l = snprintf(debugbuf, sizeof(debugbuf)-1, "[%02d:%02d:%02d.%03ld] ", -+ tmp->tm_hour, tmp->tm_min, tmp->tm_sec, tv.tv_usec/1000); ++ l = 0; ++ if (sol) { ++ gettimeofday(&tv, NULL); ++ l = snprintf(debugbuf, sizeof(debugbuf)-1, "[%02d:%02d:%02d.%03ld] ", ++ tmp->tm_hour, tmp->tm_min, tmp->tm_sec, tv.tv_usec/1000); ++ } + va_start(args, fmt); -+ vsnprintf(debugbuf+l, sizeof(debugbuf)-1-l, fmt, args); ++ l += vsnprintf(debugbuf+l, sizeof(debugbuf)-1-l, fmt, args); + va_end(args); ++ if ((l>0) && debugbuf[l-1] == '\n') { ++ sol = 1; ++ } else { ++ sol = 0; ++ } + debugbuf[sizeof(debugbuf)-1] = '\0'; + write(debug_fd, debugbuf, strlen(debugbuf)); +} + ++static void atapi_dhexdump(const void* address, uint32_t len) ++{ ++ const unsigned char* p = address; ++ int i, j; ++ ++ for (i = 0; i < len; i += 16) { ++ for (j = 0; j < 16 && i + j < len; j++) ++ atapi_dprintf("%02x ", p[i + j]); ++ for (; j < 16; j++) ++ atapi_dprintf(" "); ++ atapi_dprintf(" "); ++ for (j = 0; j < 16 && i + j < len; j++) ++ atapi_dprintf("%c", (p[i + j] < ' ' || p[i + j] > 0x7f) ? '.' : p[i + j]); ++ atapi_dprintf("\n"); ++ } ++} ++ + /* For each SCSI command we need to know up to 3 data sizes. These are: * 1. The amount of data to send to the LU. * 2. The size of the buffer provided for data sent back from the LU. -@@ -676,14 +722,58 @@ static void ide_atapi_pt_error(IDEState *s) +@@ -676,14 +750,58 @@ static void ide_atapi_pt_error(IDEState *s) ide_set_irq(s); } @@ -134,7 +162,7 @@ index 92f2934..d38d536 100644 +{ + int fds[2]; + -+ DEBUG_PRINTF("%s\n", __FUNCTION__); ++ //DEBUG_PRINTF("%s\n", __FUNCTION__); + if (pipe(fds) < 0) { + fprintf(stderr, "atapi-pt failed to create pipe: %m\n"); + exit(1); @@ -151,17 +179,24 @@ index 92f2934..d38d536 100644 +/* Call with ide_atapi_sgio_mutex held */ +static void ide_atapi_pt_do_sg_io(IDEState *s, int timeout) +{ -+ DEBUG_PRINTF("%s\n", __FUNCTION__); ++ //DEBUG_PRINTF("%s\n", __FUNCTION__); + struct sg_io_v4 *cmd = &s->atapi_pt.cmd; assert(cmd->din_xfer_len != (__u32)-1); s->atapi_pt.sense.error_code = 0; -@@ -691,9 +781,27 @@ static void ide_atapi_pt_do_sg_io(IDEState *s) +@@ -691,9 +809,41 @@ static void ide_atapi_pt_do_sg_io(IDEState *s) s->atapi_pt.sense.asc = 0; s->atapi_pt.sense.ascq = 0; + cmd->timeout = timeout ? timeout : 15000; + ++ if ((s->atapi_pt.request[0] == GPCMD_REPORT_KEY) || (s->atapi_pt.request[0] == GPCMD_SEND_KEY)) { ++ if (cmd->dout_xfer_len > 0) { ++ DEBUG_PRINTF("write:\n"); ++ DEBUG_HEXDUMP(cmd->dout_xferp, cmd->dout_xfer_len); ++ } ++ } ++ + /* Poke worker thread to send command using SG_IO ioctl */ + pthread_cond_signal(&s->atapi_pt.sgio_cv); + pthread_mutex_unlock(&s->atapi_pt.sgio_mutex); @@ -176,17 +211,24 @@ index 92f2934..d38d536 100644 + uint8_t cmd_code = s->atapi_pt.request[0]; + uint32_t din_desired; + -+ DEBUG_PRINTF("%s\n", __FUNCTION__); ++ //DEBUG_PRINTF("%s\n", __FUNCTION__); + assert(s); - /* Send command and wait for reply, SG_IO ioctl*/ - r = ioctl(raw_state->fd, 0x2285, cmd); + /* Get return code of ioctl from worker thread's fd */ + read(s->atapi_pt.sgio_rfd, &r, sizeof(int)); ++ ++ if ((s->atapi_pt.request[0] == GPCMD_REPORT_KEY) || (s->atapi_pt.request[0] == GPCMD_SEND_KEY)) { ++ if (cmd->din_xfer_len > 0) { ++ DEBUG_PRINTF("read:\n"); ++ DEBUG_HEXDUMP(cmd->din_xferp, cmd->din_xfer_len); ++ } ++ } if(s->atapi_pt.request[0] == GPCMD_GET_EVENT_STATUS_NOTIFICATION) { -@@ -746,16 +854,18 @@ static void ide_atapi_pt_do_sg_io(IDEState *s) +@@ -746,16 +896,18 @@ static void ide_atapi_pt_do_sg_io(IDEState *s) if(stat(IDE_ATAPI_PT_NEW_CD_FILE, &file_stat) == 0) { @@ -215,7 +257,7 @@ index 92f2934..d38d536 100644 else if(stat(IDE_ATAPI_PT_EJECT_CD_FILE, &file_stat) == 0 && s->atapi_pt.eject_time < file_stat.st_ctime) { -@@ -832,16 +942,17 @@ static void ide_atapi_pt_do_sg_io(IDEState *s) +@@ -832,16 +984,17 @@ static void ide_atapi_pt_do_sg_io(IDEState *s) if(din_desired == (__u32)-1) din_desired = cmd->din_xfer_len; @@ -235,7 +277,7 @@ index 92f2934..d38d536 100644 static void ide_atapi_pt_dout_fetch_dma_done(void *opaque, int ret) { BMDMAState *bm = opaque; -@@ -850,13 +961,15 @@ static void ide_atapi_pt_dout_fetch_dma_done(void *opaque, int ret) +@@ -850,13 +1003,15 @@ static void ide_atapi_pt_dout_fetch_dma_done(void *opaque, int ret) if (ret < 0) { ide_atapi_io_error(s, ret); @@ -252,7 +294,7 @@ index 92f2934..d38d536 100644 static void ide_atapi_pt_wcmd(IDEState *s) { if (s->atapi_dma) -@@ -1005,11 +1118,20 @@ static int ide_atapi_pt_read_cd_block_size(const uint8_t *io_buffer) +@@ -1005,11 +1160,20 @@ static int ide_atapi_pt_read_cd_block_size(const uint8_t *io_buffer) return block_size; } @@ -264,7 +306,7 @@ index 92f2934..d38d536 100644 uint8_t cmd_code; + -+ DEBUG_PRINTF("%s (before mutex)\n", __FUNCTION__); ++ //DEBUG_PRINTF("%s (before mutex)\n", __FUNCTION__); + if (pthread_mutex_trylock(&s->atapi_pt.sgio_mutex)) { + fprintf(stderr, "ide_atapi_pt_cmd() called with existing request processing - ignored!\n"); + return; @@ -273,7 +315,7 @@ index 92f2934..d38d536 100644 memset(cmd, 0, sizeof(*cmd)); memcpy(s->atapi_pt.request, s->io_buffer, ATAPI_PACKET_SIZE); cmd_code = s->atapi_pt.request[0]; -@@ -1021,6 +1143,7 @@ static void ide_atapi_pt_cmd(IDEState *s) +@@ -1021,6 +1185,7 @@ static void ide_atapi_pt_cmd(IDEState *s) cmd->response = (__u64)&s->atapi_pt.sense; cmd->max_response_len = sizeof(s->atapi_pt.sense); cmd->timeout = 15000; // 15 seconds @@ -281,7 +323,21 @@ index 92f2934..d38d536 100644 s->status |= BUSY_STAT; -@@ -1054,14 +1177,15 @@ static void ide_atapi_pt_cmd(IDEState *s) +@@ -1043,6 +1208,13 @@ static void ide_atapi_pt_cmd(IDEState *s) + atapi_data_sizes[cmd_code].alloc_block_size); + + ++ if ((cmd_code == GPCMD_REPORT_KEY) || (cmd_code == GPCMD_SEND_KEY)) { ++ DEBUG_PRINTF("Command dump:\n"); ++ DEBUG_HEXDUMP(s->atapi_pt.request, 11); ++ DEBUG_PRINTF("dout_xfer_len: %d din_xfer_len: %d\n", ++ cmd->dout_xfer_len, cmd->din_xfer_len); ++ } ++ + /* A few commands need special attention */ + switch(cmd_code) + { +@@ -1054,14 +1226,15 @@ static void ide_atapi_pt_cmd(IDEState *s) ide_atapi_pt_set_error(s, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET, 0x70); @@ -299,7 +355,7 @@ index 92f2934..d38d536 100644 break; case GPCMD_WRITE_BUFFER: -@@ -1072,6 +1196,7 @@ static void ide_atapi_pt_cmd(IDEState *s) +@@ -1072,6 +1245,7 @@ static void ide_atapi_pt_cmd(IDEState *s) s->io_buffer[1] & 7); ide_atapi_pt_set_error(s, SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE, 0x70); @@ -307,7 +363,7 @@ index 92f2934..d38d536 100644 return; } -@@ -1091,6 +1216,7 @@ static void ide_atapi_pt_cmd(IDEState *s) +@@ -1091,6 +1265,7 @@ static void ide_atapi_pt_cmd(IDEState *s) int size = 8 + s->atapi_pt.sense.add_sense_len; memcpy(s->io_buffer, &s->atapi_pt.sense, sizeof (s->atapi_pt.sense)); ide_atapi_cmd_reply(s, size, max_size); @@ -315,7 +371,7 @@ index 92f2934..d38d536 100644 return; } -@@ -1152,6 +1278,7 @@ static void ide_atapi_pt_cmd(IDEState *s) +@@ -1152,6 +1327,7 @@ static void ide_atapi_pt_cmd(IDEState *s) s->io_buffer[10]); ide_atapi_pt_set_error(s, SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE, 0x70); @@ -323,7 +379,19 @@ index 92f2934..d38d536 100644 return; } break; -@@ -1169,5 +1296,5 @@ static void ide_atapi_pt_cmd(IDEState *s) +@@ -1160,7 +1336,10 @@ static void ide_atapi_pt_cmd(IDEState *s) + if(cmd->dout_xfer_len == (__u32)-1) + { + DEBUG_PRINTF("[UNHANDLED SCSI COMMAND] 0x%02x\n", cmd_code); +- exit(1); ++ ide_atapi_pt_set_error(s, SENSE_ILLEGAL_REQUEST, ++ ASC_ILLEGAL_OPCODE, 0x70); ++ pthread_mutex_unlock(&s->atapi_pt.sgio_mutex); ++ return; + } + + if(cmd->dout_xfer_len > 0) +@@ -1169,5 +1348,5 @@ static void ide_atapi_pt_cmd(IDEState *s) return; } -- 2.39.5