]> xenbits.xen.org Git - xenclient/ioemu-pq.git/commitdiff
Merge all the atapi patches.
authorJean Guyader <jean.guyader@eu.citrix.com>
Tue, 27 Oct 2009 15:54:08 +0000 (15:54 +0000)
committerJean Guyader <jean.guyader@eu.citrix.com>
Tue, 27 Oct 2009 15:54:08 +0000 (15:54 +0000)
master/atapi-async-fix.patch [deleted file]
master/atapi-pass-through
master/move-iso-cdrom [deleted file]
master/series

diff --git a/master/atapi-async-fix.patch b/master/atapi-async-fix.patch
deleted file mode 100644 (file)
index 4c6690b..0000000
+++ /dev/null
@@ -1,446 +0,0 @@
-diff --git a/hw/atapi-pt.c b/hw/atapi-pt.c
-index 92f2934..4373a2c 100644
---- a/hw/atapi-pt.c
-+++ b/hw/atapi-pt.c
-@@ -1,29 +1,43 @@
-+#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
-+/* 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...) atapi_dprintf(Args)
-+# define DEBUG_HEXDUMP(addr, count) atapi_dhexdump(addr, count)
- # define CHECK_SAME_VALUE(Val1, Val2)                                   \
-     do {                                                                \
--        if ((Val1) != (Val2))                                           \
--            printf("[\e[1;32m!VALUE\e[m] %s:%d, %s=%d %s=%d\n",         \
--                   __PRETTY_FUNCTION__, __LINE__, #Val1, (Val1),        \
--                   #Val2, (Val2));                                      \
-+    if ((Val1) != (Val2))                                           \
-+      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...)
-+# define DEBUG_HEXDUMP(addr, count)
- # define CHECK_SAME_VALUE(Val1, Val2)
- #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 +496,66 @@ 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;
-+    static int sol = 1;
-+    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);
-+    }
-+    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);
-+    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 +750,63 @@ static void ide_atapi_pt_error(IDEState *s)
-     ide_set_irq(s);
- }
--static void ide_atapi_pt_do_sg_io(IDEState *s)
-+static void *ide_atapi_pt_sgio_worker_thread(void *arg)
- {
--    struct sg_io_v4 *cmd = &s->atapi_pt.cmd;
--    BDRVRawState *raw_state = s->bs->opaque;
-     int r;
--    uint8_t cmd_code = s->atapi_pt.request[0];
--    uint32_t din_desired;
-+    volatile struct sg_io_v4 *cmd;
-+    BDRVRawState *raw_state;
-+    volatile IDEState *s = (volatile IDEState *)arg;
-+
-+    for(;;) {
-+        pthread_mutex_lock(&s->atapi_pt.sgio_mutex);
-+        pthread_cond_wait(&s->atapi_pt.sgio_cv, &s->atapi_pt.sgio_mutex);
-+
-+        /* Send command and wait for reply, SG_IO ioctl*/
-+        cmd = &s->atapi_pt.cmd;
-+        raw_state = s->bs->opaque;
-+        r = ioctl(raw_state->fd, SG_IO, cmd);
-+
-+        /* Unlock _before_ signalling parent */
-+        pthread_mutex_unlock(&s->atapi_pt.sgio_mutex);
-+        write(s->atapi_pt.sgio_wfd, &r, sizeof(int));
-+    }
-+}
-+
-+static int ide_atapi_pt_aio_flush(void *unused)
-+{
-+    return 0;
-+}
-+
-+static void ide_atapi_pt_do_sg_io_complete(void *unused);
-+
-+static void ide_atapi_pt_setup_sgio_thread(IDEState *s)
-+{
-+    int fds[2];
-+
-+    //DEBUG_PRINTF("%s\n", __FUNCTION__);
-+    if (pipe(fds) < 0) {
-+      fprintf(stderr, "atapi-pt failed to create pipe: %m\n");
-+        exit(1);
-+    }
-+    s->atapi_pt.sgio_rfd = fds[0];
-+    s->atapi_pt.sgio_wfd = fds[1];
-+
-+    pthread_mutex_init(&s->atapi_pt.sgio_mutex, NULL);
-+    pthread_cond_init (&s->atapi_pt.sgio_cv, NULL);
-+    if (pthread_create(&s->atapi_pt.sgio_thread, NULL, ide_atapi_pt_sgio_worker_thread, (void *)s))
-+    {
-+      DEBUG_PRINTF("Create CD-ROM worker thread failed\n");
-+      fprintf(stderr, "Create CD-ROM worker thread failed\n");
-+      exit(1);
-+    }
-+    qemu_aio_set_fd_handler(s->atapi_pt.sgio_rfd, ide_atapi_pt_do_sg_io_complete, NULL, ide_atapi_pt_aio_flush, (void *)s);
-+}
-+/* Call with ide_atapi_sgio_mutex held */
-+static void ide_atapi_pt_do_sg_io(IDEState *s, int timeout)
-+{
-+    //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 +814,45 @@ 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);
-+    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);
-+}
-+
-+static void ide_atapi_pt_do_sg_io_complete(void *arg)
-+{
-+    IDEState *s = (IDEState *)arg;
-+    struct sg_io_v4 *cmd = &s->atapi_pt.cmd;
-+    BDRVRawState *raw_state = s->bs->opaque;
-+    int r;
-+    uint8_t cmd_code = s->atapi_pt.request[0];
-+    uint32_t din_desired;
-+
-+    //DEBUG_PRINTF("%s\n", __FUNCTION__);
-+    assert(s);
-+
-+    /* Get return code of ioctl from worker thread's fd */
-+    read(s->atapi_pt.sgio_rfd, &r, sizeof(int));
-+
-+    if (r) {
-+      DEBUG_PRINTF("[ATAPI] SG_IO is a very naughty boy: %d\n", r);
-+    }
-+
-+    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 +905,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 +993,17 @@ static void ide_atapi_pt_do_sg_io(IDEState *s)
-     if(din_desired == (__u32)-1)
-         din_desired = cmd->din_xfer_len;
--    DEBUG_PRINTF("Reply, %d in %d\n", din_desired, cmd->din_xfer_len);
-     ide_atapi_cmd_reply(s, din_desired, cmd->din_xfer_len);
- }
-+/* Call with ide_atapi_sgio_mutex held */
- static void ide_atapi_pt_dout_fetch_pio_done(IDEState *s)
- {
-     ide_transfer_stop(s);
--    ide_atapi_pt_do_sg_io(s);
-+    ide_atapi_pt_do_sg_io(s, 0);
- }
-+/* Call with ide_atapi_sgio_mutex held */
- static void ide_atapi_pt_dout_fetch_dma_done(void *opaque, int ret)
- {
-     BMDMAState *bm = opaque;
-@@ -850,13 +1012,15 @@ static void ide_atapi_pt_dout_fetch_dma_done(void *opaque, int ret)
-     if (ret < 0) {
-         ide_atapi_io_error(s, ret);
-+        pthread_mutex_unlock(&s->atapi_pt.sgio_mutex);
-         return;
-     }
-     i = dma_buf_rw(bm, 0);
--    ide_atapi_pt_do_sg_io(s);
-+    ide_atapi_pt_do_sg_io(s, 0);
- }
-+/* Call with ide_atapi_sgio_mutex held */
- static void ide_atapi_pt_wcmd(IDEState *s)
- {
-     if (s->atapi_dma)
-@@ -1005,11 +1169,20 @@ static int ide_atapi_pt_read_cd_block_size(const uint8_t *io_buffer)
-     return block_size;
- }
-+
- static void ide_atapi_pt_cmd(IDEState *s)
- {
-+    int timeout;
-     struct sg_io_v4 *cmd = &s->atapi_pt.cmd;
-     uint8_t cmd_code;
-+
-+    //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;
-+    }
-+
-     memset(cmd, 0, sizeof(*cmd));
-     memcpy(s->atapi_pt.request, s->io_buffer, ATAPI_PACKET_SIZE);
-     cmd_code = s->atapi_pt.request[0];
-@@ -1021,15 +1194,13 @@ 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
-+    timeout = 0;
-     s->status |= BUSY_STAT;
-     cmd->din_xferp = (__u64)s->io_buffer;
-     cmd->dout_xferp = (__u64)s->io_buffer;
--    DEBUG_PRINTF("[ATAPI] sending command: 0x%02x (\e[0;32m%s\e[m)\n",
--                 cmd_code, atapi_cmd_to_str(cmd_code));
--
-     cmd->dout_xfer_len = atapi_data_sizes[cmd_code].dout_len_const +
-         (ide_atapi_pt_read_field_at_offset(s->atapi_pt.request,
-                                            atapi_data_sizes[cmd_code].dout_len_offset,
-@@ -1043,6 +1214,16 @@ static void ide_atapi_pt_cmd(IDEState *s)
-          atapi_data_sizes[cmd_code].alloc_block_size);
-+    DEBUG_PRINTF("[ATAPI] sending command: 0x%02x (\e[0;32m%s\e[m, in %d out %d)\n",
-+                 cmd_code, atapi_cmd_to_str(cmd_code), cmd->din_xfer_len, cmd->dout_xfer_len);
-+
-+    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 +1235,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);
-+        pthread_mutex_unlock(&s->atapi_pt.sgio_mutex);
-         return;
-     case GPCMD_BLANK: // bigger timeout while blanking
--        cmd->timeout = 1000 * 60 * 80; // 80 mins
-+        timeout = 1000 * 60 * 80; // 80 mins
-         break;
-     case GPCMD_CLOSE_TRACK:
--        cmd->timeout = 1000 * 60 * 5; // 5 mins
-+        timeout = 1000 * 60 * 5; // 5 mins
-         break;
-     case GPCMD_WRITE_BUFFER:
-@@ -1072,6 +1254,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);
-+            pthread_mutex_unlock(&s->atapi_pt.sgio_mutex);
-             return;
-         }
-@@ -1091,6 +1274,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);
-+      pthread_mutex_unlock(&s->atapi_pt.sgio_mutex);
-         return;
-     }
-@@ -1152,6 +1336,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);
-+            pthread_mutex_unlock(&s->atapi_pt.sgio_mutex);
-             return;
-         }
-         break;
-@@ -1160,7 +1345,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 +1357,5 @@ static void ide_atapi_pt_cmd(IDEState *s)
-         return;
-     }
--    ide_atapi_pt_do_sg_io(s);
-+    ide_atapi_pt_do_sg_io(s, timeout);
- }
-diff --git a/hw/ide.c b/hw/ide.c
-index 6c1d60a..2b58728 100644
---- a/hw/ide.c
-+++ b/hw/ide.c
-@@ -435,6 +435,12 @@ typedef struct ATAPIPassThroughState
-     time_t               new_cd_time;
-     time_t               eject_time;
-+
-+    pthread_t            sgio_thread;
-+    pthread_mutex_t      sgio_mutex;
-+    pthread_cond_t       sgio_cv;
-+    int                  sgio_rfd;
-+    int                  sgio_wfd;
- } ATAPIPassThroughState;
- #endif /* __linux__ */
-@@ -3220,6 +3226,7 @@ static void ide_init2(IDEState *ide_state,
-             }
- #ifdef __linux__
-             else if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM_PT) {
-+              ide_atapi_pt_setup_sgio_thread(s);
-                 //              BDRVRawState *raw_state = s->bs->opaque;
-                 s->is_cdrom = 1;
-                 s->atapi_cmd = ide_atapi_pt_cmd;
index 64162309fb222dbdfbee4a1b07bee3fdbe218a00..fa009a85c4bc6471b9a6295c75afddb69d604616 100644 (file)
@@ -105,36 +105,50 @@ index 0000000..f9bdee9
 +#endif /* !BLOCK_RAW_POSIX_H */
 diff --git a/hw/atapi-pt.c b/hw/atapi-pt.c
 new file mode 100644
-index 0000000..92f2934
+index 0000000..4373a2c
 --- /dev/null
 +++ b/hw/atapi-pt.c
-@@ -0,0 +1,1173 @@
+@@ -0,0 +1,1361 @@
++#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
++/* 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...) atapi_dprintf(Args)
++# define DEBUG_HEXDUMP(addr, count) atapi_dhexdump(addr, count)
 +# define CHECK_SAME_VALUE(Val1, Val2)                                   \
 +    do {                                                                \
-+        if ((Val1) != (Val2))                                           \
-+            printf("[\e[1;32m!VALUE\e[m] %s:%d, %s=%d %s=%d\n",         \
-+                   __PRETTY_FUNCTION__, __LINE__, #Val1, (Val1),        \
-+                   #Val2, (Val2));                                      \
++    if ((Val1) != (Val2))                                           \
++      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...)
++# define DEBUG_HEXDUMP(addr, count)
 +# define CHECK_SAME_VALUE(Val1, Val2)
 +#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. */
@@ -593,6 +607,66 @@ index 0000000..92f2934
 +}
 +
 +
++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;
++    static int sol = 1;
++    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);
++    }
++    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);
++    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.
@@ -787,14 +861,63 @@ index 0000000..92f2934
 +    ide_set_irq(s);
 +}
 +
-+static void ide_atapi_pt_do_sg_io(IDEState *s)
++static void *ide_atapi_pt_sgio_worker_thread(void *arg)
 +{
-+    struct sg_io_v4 *cmd = &s->atapi_pt.cmd;
-+    BDRVRawState *raw_state = s->bs->opaque;
 +    int r;
-+    uint8_t cmd_code = s->atapi_pt.request[0];
-+    uint32_t din_desired;
++    volatile struct sg_io_v4 *cmd;
++    BDRVRawState *raw_state;
++    volatile IDEState *s = (volatile IDEState *)arg;
++
++    for(;;) {
++        pthread_mutex_lock(&s->atapi_pt.sgio_mutex);
++        pthread_cond_wait(&s->atapi_pt.sgio_cv, &s->atapi_pt.sgio_mutex);
++
++        /* Send command and wait for reply, SG_IO ioctl*/
++        cmd = &s->atapi_pt.cmd;
++        raw_state = s->bs->opaque;
++        r = ioctl(raw_state->fd, SG_IO, cmd);
++
++        /* Unlock _before_ signalling parent */
++        pthread_mutex_unlock(&s->atapi_pt.sgio_mutex);
++        write(s->atapi_pt.sgio_wfd, &r, sizeof(int));
++    }
++}
++
++static int ide_atapi_pt_aio_flush(void *unused)
++{
++    return 0;
++}
++
++static void ide_atapi_pt_do_sg_io_complete(void *unused);
++
++static void ide_atapi_pt_setup_sgio_thread(IDEState *s)
++{
++    int fds[2];
++
++    //DEBUG_PRINTF("%s\n", __FUNCTION__);
++    if (pipe(fds) < 0) {
++      fprintf(stderr, "atapi-pt failed to create pipe: %m\n");
++        exit(1);
++    }
++    s->atapi_pt.sgio_rfd = fds[0];
++    s->atapi_pt.sgio_wfd = fds[1];
++
++    pthread_mutex_init(&s->atapi_pt.sgio_mutex, NULL);
++    pthread_cond_init (&s->atapi_pt.sgio_cv, NULL);
++    if (pthread_create(&s->atapi_pt.sgio_thread, NULL, ide_atapi_pt_sgio_worker_thread, (void *)s))
++    {
++      DEBUG_PRINTF("Create CD-ROM worker thread failed\n");
++      fprintf(stderr, "Create CD-ROM worker thread failed\n");
++      exit(1);
++    }
++    qemu_aio_set_fd_handler(s->atapi_pt.sgio_rfd, ide_atapi_pt_do_sg_io_complete, NULL, ide_atapi_pt_aio_flush, (void *)s);
++}
 +
++/* Call with ide_atapi_sgio_mutex held */
++static void ide_atapi_pt_do_sg_io(IDEState *s, int timeout)
++{
++    //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;
@@ -802,9 +925,45 @@ index 0000000..92f2934
 +    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);
++}
++
++static void ide_atapi_pt_do_sg_io_complete(void *arg)
++{
++    IDEState *s = (IDEState *)arg;
++    struct sg_io_v4 *cmd = &s->atapi_pt.cmd;
++    BDRVRawState *raw_state = s->bs->opaque;
++    int r;
++    uint8_t cmd_code = s->atapi_pt.request[0];
++    uint32_t din_desired;
++
++    //DEBUG_PRINTF("%s\n", __FUNCTION__);
++    assert(s);
++
++    /* Get return code of ioctl from worker thread's fd */
++    read(s->atapi_pt.sgio_rfd, &r, sizeof(int));
++
++    if (r) {
++      DEBUG_PRINTF("[ATAPI] SG_IO is a very naughty boy: %d\n", r);
++    }
 +
-+    /* Send command and wait for reply, SG_IO ioctl*/
-+    r = ioctl(raw_state->fd, 0x2285, cmd);
++    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)
 +    {
@@ -857,16 +1016,18 @@ index 0000000..92f2934
 +
 +            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)
 +            {
@@ -943,16 +1104,17 @@ index 0000000..92f2934
 +    if(din_desired == (__u32)-1)
 +        din_desired = cmd->din_xfer_len;
 +
-+    DEBUG_PRINTF("Reply, %d in %d\n", din_desired, cmd->din_xfer_len);
 +    ide_atapi_cmd_reply(s, din_desired, cmd->din_xfer_len);
 +}
 +
++/* Call with ide_atapi_sgio_mutex held */
 +static void ide_atapi_pt_dout_fetch_pio_done(IDEState *s)
 +{
 +    ide_transfer_stop(s);
-+    ide_atapi_pt_do_sg_io(s);
++    ide_atapi_pt_do_sg_io(s, 0);
 +}
 +
++/* Call with ide_atapi_sgio_mutex held */
 +static void ide_atapi_pt_dout_fetch_dma_done(void *opaque, int ret)
 +{
 +    BMDMAState *bm = opaque;
@@ -961,13 +1123,15 @@ index 0000000..92f2934
 +
 +    if (ret < 0) {
 +        ide_atapi_io_error(s, ret);
++        pthread_mutex_unlock(&s->atapi_pt.sgio_mutex);
 +        return;
 +    }
 +
 +    i = dma_buf_rw(bm, 0);
-+    ide_atapi_pt_do_sg_io(s);
++    ide_atapi_pt_do_sg_io(s, 0);
 +}
 +
++/* Call with ide_atapi_sgio_mutex held */
 +static void ide_atapi_pt_wcmd(IDEState *s)
 +{
 +    if (s->atapi_dma)
@@ -1116,11 +1280,20 @@ index 0000000..92f2934
 +    return block_size;
 +}
 +
++
 +static void ide_atapi_pt_cmd(IDEState *s)
 +{
++    int timeout;
 +    struct sg_io_v4 *cmd = &s->atapi_pt.cmd;
 +    uint8_t cmd_code;
 +
++
++    //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;
++    }
++
 +    memset(cmd, 0, sizeof(*cmd));
 +    memcpy(s->atapi_pt.request, s->io_buffer, ATAPI_PACKET_SIZE);
 +    cmd_code = s->atapi_pt.request[0];
@@ -1132,15 +1305,13 @@ index 0000000..92f2934
 +    cmd->response         = (__u64)&s->atapi_pt.sense;
 +    cmd->max_response_len = sizeof(s->atapi_pt.sense);
 +    cmd->timeout          = 15000; // 15 seconds
++    timeout = 0;
 +
 +    s->status |= BUSY_STAT;
 +
 +    cmd->din_xferp = (__u64)s->io_buffer;
 +    cmd->dout_xferp = (__u64)s->io_buffer;
 +
-+    DEBUG_PRINTF("[ATAPI] sending command: 0x%02x (\e[0;32m%s\e[m)\n",
-+                 cmd_code, atapi_cmd_to_str(cmd_code));
-+
 +    cmd->dout_xfer_len = atapi_data_sizes[cmd_code].dout_len_const +
 +        (ide_atapi_pt_read_field_at_offset(s->atapi_pt.request,
 +                                           atapi_data_sizes[cmd_code].dout_len_offset,
@@ -1154,6 +1325,16 @@ index 0000000..92f2934
 +         atapi_data_sizes[cmd_code].alloc_block_size);
 +
 +
++    DEBUG_PRINTF("[ATAPI] sending command: 0x%02x (\e[0;32m%s\e[m, in %d out %d)\n",
++                 cmd_code, atapi_cmd_to_str(cmd_code), cmd->din_xfer_len, cmd->dout_xfer_len);
++
++    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)
 +    {
@@ -1165,14 +1346,15 @@ index 0000000..92f2934
 +            ide_atapi_pt_set_error(s, SENSE_ILLEGAL_REQUEST,
 +                                   ASC_INV_FIELD_IN_CMD_PACKET, 0x70);
 +
++        pthread_mutex_unlock(&s->atapi_pt.sgio_mutex);
 +        return;
 +
 +    case GPCMD_BLANK: // bigger timeout while blanking
-+        cmd->timeout = 1000 * 60 * 80; // 80 mins
++        timeout = 1000 * 60 * 80; // 80 mins
 +        break;
 +
 +    case GPCMD_CLOSE_TRACK:
-+        cmd->timeout = 1000 * 60 * 5; // 5 mins
++        timeout = 1000 * 60 * 5; // 5 mins
 +        break;
 +
 +    case GPCMD_WRITE_BUFFER:
@@ -1183,6 +1365,7 @@ index 0000000..92f2934
 +                         s->io_buffer[1] & 7);
 +            ide_atapi_pt_set_error(s, SENSE_ILLEGAL_REQUEST,
 +                                   ASC_ILLEGAL_OPCODE, 0x70);
++            pthread_mutex_unlock(&s->atapi_pt.sgio_mutex);
 +            return;
 +        }
 +
@@ -1202,6 +1385,7 @@ index 0000000..92f2934
 +        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);
++      pthread_mutex_unlock(&s->atapi_pt.sgio_mutex);
 +        return;
 +    }
 +
@@ -1263,6 +1447,7 @@ index 0000000..92f2934
 +                         s->io_buffer[10]);
 +            ide_atapi_pt_set_error(s, SENSE_ILLEGAL_REQUEST,
 +                                   ASC_ILLEGAL_OPCODE, 0x70);
++            pthread_mutex_unlock(&s->atapi_pt.sgio_mutex);
 +            return;
 +        }
 +        break;
@@ -1271,7 +1456,10 @@ index 0000000..92f2934
 +    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)
@@ -1280,10 +1468,10 @@ index 0000000..92f2934
 +        return;
 +    }
 +
-+    ide_atapi_pt_do_sg_io(s);
++    ide_atapi_pt_do_sg_io(s, timeout);
 +}
 diff --git a/hw/ide.c b/hw/ide.c
-index e8d676e..6c1d60a 100644
+index e8d676e..2b58728 100644
 --- a/hw/ide.c
 +++ b/hw/ide.c
 @@ -22,6 +22,7 @@
@@ -1504,7 +1692,7 @@ index e8d676e..6c1d60a 100644
  #define ASC_ILLEGAL_OPCODE                   0x20
  #define ASC_LOGICAL_BLOCK_OOR                0x21
  #define ASC_INV_FIELD_IN_CMD_PACKET          0x24
-@@ -371,15 +399,45 @@
+@@ -371,15 +399,51 @@
  #define CFA_INVALID_ADDRESS     0x21
  #define CFA_ADDRESS_OVERFLOW    0x2f
  
@@ -1548,13 +1736,19 @@ index e8d676e..6c1d60a 100644
 +
 +    time_t               new_cd_time;
 +    time_t               eject_time;
++
++    pthread_t            sgio_thread;
++    pthread_mutex_t      sgio_mutex;
++    pthread_cond_t       sgio_cv;
++    int                  sgio_rfd;
++    int                  sgio_wfd;
 +} ATAPIPassThroughState;
 +#endif /* __linux__ */
 +
  /* NOTE: IDEState represents in fact one drive */
  typedef struct IDEState {
      /* ide config */
-@@ -429,6 +487,10 @@ typedef struct IDEState {
+@@ -429,6 +493,10 @@ typedef struct IDEState {
      int lba;
      int cd_sector_size;
      int atapi_dma; /* true if dma is requested for the packet cmd */
@@ -1565,7 +1759,7 @@ index e8d676e..6c1d60a 100644
      /* ATA DMA state */
      int io_buffer_size;
      QEMUSGList sg;
-@@ -940,6 +1002,8 @@ static inline void ide_set_irq(IDEState *s)
+@@ -940,6 +1008,8 @@ static inline void ide_set_irq(IDEState *s)
          if (bm) {
              bm->status |= BM_STATUS_INT;
          }
@@ -1574,7 +1768,7 @@ index e8d676e..6c1d60a 100644
          qemu_irq_raise(s->irq);
      }
  }
-@@ -1321,9 +1385,9 @@ static void ide_sector_write(IDEState *s)
+@@ -1321,9 +1391,9 @@ static void ide_sector_write(IDEState *s)
             that at the expense of slower write performances. Use this
             option _only_ to install Windows 2000. You must disable it
             for normal use. */
@@ -1586,7 +1780,7 @@ index e8d676e..6c1d60a 100644
  #endif
      {
          ide_set_irq(s);
-@@ -1499,6 +1563,13 @@ static inline int ube16_to_cpu(const uint8_t *buf)
+@@ -1499,6 +1569,13 @@ static inline int ube16_to_cpu(const uint8_t *buf)
      return (buf[0] << 8) | buf[1];
  }
  
@@ -1600,7 +1794,7 @@ index e8d676e..6c1d60a 100644
  static inline int ube32_to_cpu(const uint8_t *buf)
  {
      return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
-@@ -1567,12 +1638,14 @@ static void ide_atapi_io_error(IDEState *s, int ret)
+@@ -1567,12 +1644,14 @@ static void ide_atapi_io_error(IDEState *s, int ret)
  static void ide_atapi_cmd_reply_end(IDEState *s)
  {
      int byte_count_limit, size, ret;
@@ -1615,7 +1809,7 @@ index e8d676e..6c1d60a 100644
      if (s->packet_transfer_size <= 0) {
          /* end of transfer */
          ide_transfer_stop(s);
-@@ -1582,63 +1655,65 @@ static void ide_atapi_cmd_reply_end(IDEState *s)
+@@ -1582,63 +1661,65 @@ static void ide_atapi_cmd_reply_end(IDEState *s)
  #ifdef DEBUG_IDE_ATAPI
          printf("status=0x%x\n", s->status);
  #endif
@@ -1732,7 +1926,7 @@ index e8d676e..6c1d60a 100644
      }
  }
  
-@@ -1882,6 +1957,10 @@ static int ide_dvd_read_structure(IDEState *s, int format,
+@@ -1882,6 +1963,10 @@ static int ide_dvd_read_structure(IDEState *s, int format,
      }
  }
  
@@ -1743,7 +1937,7 @@ index e8d676e..6c1d60a 100644
  static void ide_atapi_cmd(IDEState *s)
  {
      const uint8_t *packet;
-@@ -1922,7 +2001,6 @@ static void ide_atapi_cmd(IDEState *s)
+@@ -1922,7 +2007,6 @@ static void ide_atapi_cmd(IDEState *s)
                                  ASC_MEDIUM_NOT_PRESENT);
          }
          break;
@@ -1751,7 +1945,7 @@ index e8d676e..6c1d60a 100644
      case GPCMD_MODE_SENSE_10:
          {
              int action, code;
-@@ -1935,9 +2013,9 @@ static void ide_atapi_cmd(IDEState *s)
+@@ -1935,9 +2019,9 @@ static void ide_atapi_cmd(IDEState *s)
              switch(action) {
              case 0: /* current values */
                  switch(code) {
@@ -1763,7 +1957,7 @@ index e8d676e..6c1d60a 100644
                      buf[3] = 0;
                      buf[4] = 0;
                      buf[5] = 0;
-@@ -1954,17 +2032,17 @@ static void ide_atapi_cmd(IDEState *s)
+@@ -1954,17 +2038,17 @@ static void ide_atapi_cmd(IDEState *s)
                      buf[15] = 0x00;
                      ide_atapi_cmd_reply(s, 16, max_len);
                      break;
@@ -1785,7 +1979,7 @@ index e8d676e..6c1d60a 100644
                      buf[10] = 0x00;
                      buf[11] = 0x00;
  
-@@ -1987,6 +2065,7 @@ static void ide_atapi_cmd(IDEState *s)
+@@ -1987,6 +2071,7 @@ static void ide_atapi_cmd(IDEState *s)
                      buf[27] = 0;
                      ide_atapi_cmd_reply(s, 28, max_len);
                      break;
@@ -1793,7 +1987,7 @@ index e8d676e..6c1d60a 100644
                  default:
                      goto error_cmd;
                  }
-@@ -2110,7 +2189,7 @@ static void ide_atapi_cmd(IDEState *s)
+@@ -2110,7 +2195,7 @@ static void ide_atapi_cmd(IDEState *s)
          break;
      case GPCMD_MECHANISM_STATUS:
          {
@@ -1802,7 +1996,7 @@ index e8d676e..6c1d60a 100644
              cpu_to_ube16(buf, 0);
              /* no current LBA */
              buf[2] = 0;
-@@ -2125,7 +2204,6 @@ static void ide_atapi_cmd(IDEState *s)
+@@ -2125,7 +2210,6 @@ static void ide_atapi_cmd(IDEState *s)
          {
              int format, msf, start_track, len;
              uint64_t total_sectors;
@@ -1810,7 +2004,7 @@ index e8d676e..6c1d60a 100644
              bdrv_get_geometry(s->bs, &total_sectors);
              total_sectors >>= 2;
              if (total_sectors == 0) {
-@@ -2279,7 +2357,7 @@ static void ide_atapi_cmd(IDEState *s)
+@@ -2279,7 +2363,7 @@ static void ide_atapi_cmd(IDEState *s)
                  max_len = 512;
  
              memset(buf, 0, max_len);
@@ -1819,7 +2013,7 @@ index e8d676e..6c1d60a 100644
               * the number of sectors from the media tells us which profile
               * to use as current.  0 means there is no media
               */
-@@ -2484,7 +2562,11 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+@@ -2484,7 +2568,11 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
  
          /* Only DEVICE RESET is allowed while BSY or/and DRQ are set */
          if ((s->status & (BUSY_STAT|DRQ_STAT)) && val != WIN_DEVICE_RESET)
@@ -1831,7 +2025,7 @@ index e8d676e..6c1d60a 100644
  
          switch(val) {
          case WIN_IDENTIFY:
-@@ -2727,7 +2809,7 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+@@ -2727,7 +2815,7 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
              else
                  s->status = READY_STAT | SEEK_STAT;
              s->error = 0x01; /* Device 0 passed, Device 1 passed or not
@@ -1840,7 +2034,7 @@ index e8d676e..6c1d60a 100644
                                */
              ide_set_irq(s);
              break;
-@@ -2748,7 +2830,7 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+@@ -2748,7 +2836,7 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
              s->atapi_dma = s->feature & 1;
              s->nsector = 1;
              ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE,
@@ -1849,7 +2043,7 @@ index e8d676e..6c1d60a 100644
              break;
          /* CF-ATA commands */
          case CFA_REQ_EXT_ERROR_CODE:
-@@ -3133,8 +3215,20 @@ static void ide_init2(IDEState *ide_state,
+@@ -3133,8 +3221,21 @@ static void ide_init2(IDEState *ide_state,
  
              if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) {
                  s->is_cdrom = 1;
@@ -1858,6 +2052,7 @@ index e8d676e..6c1d60a 100644
              }
 +#ifdef __linux__
 +            else if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM_PT) {
++              ide_atapi_pt_setup_sgio_thread(s);
 +                //              BDRVRawState *raw_state = s->bs->opaque;
 +                s->is_cdrom = 1;
 +                s->atapi_cmd = ide_atapi_pt_cmd;
@@ -1871,7 +2066,7 @@ index e8d676e..6c1d60a 100644
          s->drive_serial = drive_serial++;
          strncpy(s->drive_serial_str, drive_get_serial(s->bs),
 diff --git a/vl.c b/vl.c
-index f3b0dae..ae461c8 100644
+index f3b0dae..c9c7c7f 100644
 --- a/vl.c
 +++ b/vl.c
 @@ -2192,8 +2192,10 @@ static int bt_parse(const char *opt)
@@ -1881,7 +2076,7 @@ index f3b0dae..ae461c8 100644
 +#define CDROM_PT_ALIAS "index=1,media=cdrompt"
  #else
  #define CDROM_ALIAS "index=2,media=cdrom"
-+#define CDROM_PT_ALIAS "index=2,media=cdrompt"
++#define CDROM_PT_ALIAS "index=3,media=cdrompt"
  #endif
  #define FD_ALIAS "index=%d,if=floppy"
  #define PFLASH_ALIAS "if=pflash"
diff --git a/master/move-iso-cdrom b/master/move-iso-cdrom
deleted file mode 100644 (file)
index dd0064e..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-diff --git a/vl.c b/vl.c
-index ae461c8..c9c7c7f 100644
---- a/vl.c
-+++ b/vl.c
-@@ -2195,7 +2195,7 @@ static int bt_parse(const char *opt)
- #define CDROM_PT_ALIAS "index=1,media=cdrompt"
- #else
- #define CDROM_ALIAS "index=2,media=cdrom"
--#define CDROM_PT_ALIAS "index=2,media=cdrompt"
-+#define CDROM_PT_ALIAS "index=3,media=cdrompt"
- #endif
- #define FD_ALIAS "index=%d,if=floppy"
- #define PFLASH_ALIAS "if=pflash"
index 167ffe8466ffafb1dcad744b3e0f7948604b350c..c2a280cfbf924e4dc98d3516adc3e021ffa566b6 100644 (file)
@@ -31,5 +31,3 @@ fix-imobile-mouse
 new-input-code
 atapi-pass-through
 pv_driver_throttling_disabled
-move-iso-cdrom
-atapi-async-fix.patch