]> xenbits.xen.org Git - xenclient/ioemu-pq.git/commitdiff
Fix new-media bug and make logging runtime switchable
authorThomas Horsten <thomas.horsten@citrix.com>
Thu, 17 Sep 2009 12:09:21 +0000 (13:09 +0100)
committerThomas Horsten <thomas.horsten@citrix.com>
Thu, 17 Sep 2009 12:09:21 +0000 (13:09 +0100)
master/atapi-async-fix.patch

index 0d6298075eb53f8100a62b032eb8c1b479a1841f..7222a222eaf24567811cf1de60d430d82bbf4785 100644 (file)
@@ -1,23 +1,31 @@
 diff --git a/hw/atapi-pt.c b/hw/atapi-pt.c
-index 92f2934..343798d 100644
+index 92f2934..d38d536 100644
 --- a/hw/atapi-pt.c
 +++ b/hw/atapi-pt.c
-@@ -1,19 +1,23 @@
+@@ -1,19 +1,30 @@
 +#include <scsi/sg.h>
  #include <utime.h>
++#include <time.h>
++#include <sys/types.h>
  #include <sys/stat.h>
  #include <fcntl.h>
 +#include <pthread.h>
 +#include <sys/ioctl.h>
++#include <unistd.h>
++#include "xen.h"
  
- #undef DEBUG_IDE_ATAPI_PT
+-#undef DEBUG_IDE_ATAPI_PT
++/* Even when defined debugging is only enabled if /etc/debugcdrom exists */
++#define DEBUG_IDE_ATAPI_PT
  
  #define MSF_TO_FRAMES(M, S, F) (((M) * CD_SECS + (S)) * CD_FRAMES + (F))
 +static int log_fd=-1;
  
++static int debug_fd=-1;
++static int debug_enabled=-1;
  #ifdef DEBUG_IDE_ATAPI_PT
 -# define DEBUG_PRINTF(Args...) printf(Args)
-+# define DEBUG_PRINTF(Args...) do { char buf[1024]; int len; if (log_fd==-1) log_fd=open("/tmp/cdrom.log",O_WRONLY | O_CREAT | O_APPEND,0666);  len=sprintf(buf,Args); write(log_fd,buf,len); } while (1==0)
++# define DEBUG_PRINTF(Args...) atapi_dprintf(Args)
  # define CHECK_SAME_VALUE(Val1, Val2)                                   \
      do {                                                                \
 -        if ((Val1) != (Val2))                                           \
@@ -25,13 +33,66 @@ index 92f2934..343798d 100644
 -                   __PRETTY_FUNCTION__, __LINE__, #Val1, (Val1),        \
 -                   #Val2, (Val2));                                      \
 +    if ((Val1) != (Val2))                                           \
-+      printf("[\e[1;32m!VALUE\e[m] %s:%d, %s=%d %s=%d\n",         \
++      dprintf("[\e[1;32m!VALUE\e[m] %s:%d, %s=%d %s=%d\n",         \
 +          __PRETTY_FUNCTION__, __LINE__, #Val1, (Val1),        \
 +             #Val2, (Val2));                                      \
      } while (0)
  #else
  # define DEBUG_PRINTF(Args...)
-@@ -676,14 +680,58 @@ static void ide_atapi_pt_error(IDEState *s)
+@@ -21,9 +32,10 @@
+ #endif /* DEBUG_IDE_ATAPI_PT */
++#define IDE_ATAPI_PT_DEBUG_ENABLE_FILE   "/etc/debugcdrom"
+ #define IDE_ATAPI_PT_NEW_CD_FILE   "/var/lock/xen-cd-new"
+ #define IDE_ATAPI_PT_EJECT_CD_FILE "/var/lock/xen-cd-eject"
+-
++#define IDE_ATAPI_PT_DEBUG_FILE_TEMPLATE "/var/log/cdrom-%d.log"
+ /* 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)
+ }
++static void atapi_dprintf(const char *fmt, ...)
++{
++    struct stat st;
++    char debugbuf[2048];
++    time_t t = time(NULL);
++    struct tm *tmp = localtime(&t);
++    struct timeval tv;
++    va_list args;
++    int l;
++    if (debug_enabled == 0)
++      return;
++    if (debug_enabled < 0) {
++      if (stat(IDE_ATAPI_PT_DEBUG_ENABLE_FILE, &st) == 0)
++          debug_enabled = 1;
++      else {
++          debug_enabled = 0;
++          return;
++      }
++    }
++    if (debug_fd<0) {
++      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);
++    va_start(args, fmt);
++    vsnprintf(debugbuf+l, sizeof(debugbuf)-1-l, fmt, args);
++    va_end(args);
++    debugbuf[sizeof(debugbuf)-1] = '\0';
++    write(debug_fd, debugbuf, strlen(debugbuf));
++}
++
++
+ /* 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)
      ide_set_irq(s);
  }
  
@@ -95,14 +156,12 @@ index 92f2934..343798d 100644
      assert(cmd->din_xfer_len != (__u32)-1);
  
      s->atapi_pt.sense.error_code = 0;
-@@ -691,9 +739,27 @@ static void ide_atapi_pt_do_sg_io(IDEState *s)
+@@ -691,9 +781,27 @@ 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;
--    /* Send command and wait for reply, SG_IO ioctl*/
--    r = ioctl(raw_state->fd, 0x2285, cmd);
++
 +    /* 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);
@@ -119,13 +178,44 @@ index 92f2934..343798d 100644
 +
 +    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_GET_EVENT_STATUS_NOTIFICATION)
      {
-@@ -832,16 +898,17 @@ static void ide_atapi_pt_do_sg_io(IDEState *s)
+@@ -746,16 +854,18 @@ static void ide_atapi_pt_do_sg_io(IDEState *s)
+             if(stat(IDE_ATAPI_PT_NEW_CD_FILE, &file_stat) == 0)
+             {
+-                /* There's been a new media message that we haven't seen yet */
+-                DEBUG_PRINTF("[ATAPI] new media message spotted\n");
+-                s->atapi_pt.new_cd_time = file_stat.st_ctime;
+-
+-                s->io_buffer[2] = 4;
+-                s->io_buffer[4] = 2;
+-                s->io_buffer[5] = 2;
+-                s->io_buffer[6] = 0;
+-                s->io_buffer[7] = 0;
+-            }
++              if (s->atapi_pt.new_cd_time != file_stat.st_ctime) {
++              /* There's been a new media message that we haven't seen yet */
++                  s->atapi_pt.new_cd_time = file_stat.st_ctime;
++                  DEBUG_PRINTF("[ATAPI] new media message spotted\n");
++
++                  s->io_buffer[2] = 4;
++                  s->io_buffer[4] = 2;
++                  s->io_buffer[5] = 2;
++                  s->io_buffer[6] = 0;
++                  s->io_buffer[7] = 0;
++              }
++          }
+             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)
      if(din_desired == (__u32)-1)
          din_desired = cmd->din_xfer_len;
  
@@ -145,7 +235,7 @@ index 92f2934..343798d 100644
  static void ide_atapi_pt_dout_fetch_dma_done(void *opaque, int ret)
  {
      BMDMAState *bm = opaque;
-@@ -850,13 +917,15 @@ static void ide_atapi_pt_dout_fetch_dma_done(void *opaque, int ret)
+@@ -850,13 +961,15 @@ static void ide_atapi_pt_dout_fetch_dma_done(void *opaque, int ret)
  
      if (ret < 0) {
          ide_atapi_io_error(s, ret);
@@ -162,7 +252,7 @@ index 92f2934..343798d 100644
  static void ide_atapi_pt_wcmd(IDEState *s)
  {
      if (s->atapi_dma)
-@@ -1005,11 +1074,20 @@ static int ide_atapi_pt_read_cd_block_size(const uint8_t *io_buffer)
+@@ -1005,11 +1118,20 @@ static int ide_atapi_pt_read_cd_block_size(const uint8_t *io_buffer)
      return block_size;
  }
  
@@ -183,7 +273,7 @@ index 92f2934..343798d 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 +1099,7 @@ static void ide_atapi_pt_cmd(IDEState *s)
+@@ -1021,6 +1143,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
@@ -191,7 +281,7 @@ index 92f2934..343798d 100644
  
      s->status |= BUSY_STAT;
  
-@@ -1054,14 +1133,15 @@ static void ide_atapi_pt_cmd(IDEState *s)
+@@ -1054,14 +1177,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);
  
@@ -209,7 +299,7 @@ index 92f2934..343798d 100644
          break;
  
      case GPCMD_WRITE_BUFFER:
-@@ -1072,6 +1152,7 @@ static void ide_atapi_pt_cmd(IDEState *s)
+@@ -1072,6 +1196,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);
@@ -217,7 +307,7 @@ index 92f2934..343798d 100644
              return;
          }
  
-@@ -1091,6 +1172,7 @@ static void ide_atapi_pt_cmd(IDEState *s)
+@@ -1091,6 +1216,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);
@@ -225,7 +315,7 @@ index 92f2934..343798d 100644
          return;
      }
  
-@@ -1152,6 +1234,7 @@ static void ide_atapi_pt_cmd(IDEState *s)
+@@ -1152,6 +1278,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);
@@ -233,7 +323,7 @@ index 92f2934..343798d 100644
              return;
          }
          break;
-@@ -1169,5 +1252,5 @@ static void ide_atapi_pt_cmd(IDEState *s)
+@@ -1169,5 +1296,5 @@ static void ide_atapi_pt_cmd(IDEState *s)
          return;
      }