]> xenbits.xen.org Git - xenclient/ioemu-pq.git/commitdiff
Enable writing on atapi pt:wq
authorJames Mckenzie <jamesmck@bob.uk.xensource.com>
Fri, 4 Sep 2009 01:22:12 +0000 (02:22 +0100)
committerJames Mckenzie <jamesmck@bob.uk.xensource.com>
Fri, 4 Sep 2009 01:22:12 +0000 (02:22 +0100)
master/atapi-pt-write [new file with mode: 0644]
master/series

diff --git a/master/atapi-pt-write b/master/atapi-pt-write
new file mode 100644 (file)
index 0000000..c300040
--- /dev/null
@@ -0,0 +1,467 @@
+diff --git a/hw/atapi-pt.c b/hw/atapi-pt.c
+index 413cc47..2441096 100644
+--- a/hw/atapi-pt.c
++++ b/hw/atapi-pt.c
+@@ -497,18 +497,157 @@ static void ide_atapi_pt_error(IDEState *s)
+     ide_set_irq(s);
+ }
+-#if 0
+-static int cmd_count = 0;
+-static int finish_count = 0;
+-static int no_finish_count = 0;
+-
+-static void ide_atapi_pt_sg_io_finished(IDEState *s)
++static void ide_atapi_pt_sg_io_finish(IDEState *s)
+ {
++    struct sg_io_v4 *cmd = &s->atapi_pt.cmd;
++    BDRVRawState *raw_state = s->bs->opaque;
++    int r;
++
++    s->atapi_pt.sense.error_code = 0;
++    s->atapi_pt.sense.sense_key = 0;
++    s->atapi_pt.sense.asc = 0;
++    s->atapi_pt.sense.ascq = 0;
++
++    if(cmd->dout_xfer_len > 0)
++    {
++        int max, i;
++
++        max = cmd->dout_xfer_len;
++        if(max > 0x100)
++            max = 0x100;
++
++        DEBUG_PRINTF("Dout: 0x");
++        for(i = 0; i < max; ++i)
++            DEBUG_PRINTF("%02x ", ((char *)cmd->dout_xferp)[i]);
++        DEBUG_PRINTF("\n");
++    }
++
++
++    /* Send command and wait for reply, SG_IO ioctl*/
++    r = ioctl(raw_state->fd, 0x2285, cmd);
++
++    if(s->atapi_pt.request[0] == GPCMD_MODE_SENSE_10)
++    {
++        DEBUG_PRINTF("Mode sense 10, %d bytes\n", cmd->din_xfer_len);
++        {
++            int i;
++            DEBUG_PRINTF("0x");
++            for(i = 0; i < cmd->din_xfer_len; ++i)
++                DEBUG_PRINTF("%02x ", s->io_buffer[i]);
++            DEBUG_PRINTF("\n");
++        }
++    }
++
++
++    if(s->atapi_pt.request[0] == GPCMD_GET_EVENT_STATUS_NOTIFICATION)
++    {
++        struct stat file_stat;
++
++        if(s->io_buffer[2] == 4 && s->io_buffer[4] == 2)
++        {
++            /* This is a "new media" message, tell any other VMs */
++            DEBUG_PRINTF("[ATAPI] new media\n");
++            system("touch " IDE_ATAPI_PT_NEW_CD_FILE);
++
++            if(stat(IDE_ATAPI_PT_NEW_CD_FILE, &file_stat) != 0)
++                DEBUG_PRINTF("Error writing to new CD file\n");
++            else
++                s->atapi_pt.new_cd_time = file_stat.st_ctime;
++        }
++
++        if(s->io_buffer[2] == 4 && s->io_buffer[4] == 3)
++        {
++            /* This is a "media removed" message, tell any other VMs */
++            DEBUG_PRINTF("[ATAPI] media removed\n");
++            system("touch " IDE_ATAPI_PT_EJECT_CD_FILE);
++
++            if(stat(IDE_ATAPI_PT_EJECT_CD_FILE, &file_stat) != 0)
++                DEBUG_PRINTF("Error writing to eject CD file\n");
++            else
++                s->atapi_pt.eject_time = file_stat.st_ctime;
++        }
++
++        if((s->io_buffer[2] == 4 && s->io_buffer[4] == 0 && s->io_buffer[5] == 2) ||
++           (s->io_buffer[4] == 0 && s->io_buffer[5] == 0 &&
++            s->io_buffer[6] == 0 && s->io_buffer[7] == 0))
++        {
++            /* This is a no activity message we can hijack if we need to */
++
++            if((stat(IDE_ATAPI_PT_NEW_CD_FILE, &file_stat) == 0 &&
++               s->atapi_pt.new_cd_time < file_stat.st_ctime) ||
++               s->atapi_pt.aardvark == 1)
++            {
++                /* 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->atapi_pt.aardvark = 0;
++
++                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)
++            {
++                /* There's been an eject message that we haven't seen yet */
++                DEBUG_PRINTF("[ATAPI] media removed message spotted\n");
++                s->atapi_pt.eject_time = file_stat.st_ctime;
++
++                s->io_buffer[2] = 4;
++                s->io_buffer[4] = 3;
++                s->io_buffer[5] = 1;
++                s->io_buffer[6] = 0;
++                s->io_buffer[7] = 0;
++            }
++        }
++    }
++
++    if(r || cmd->driver_status || cmd->transport_status ||
++       cmd->device_status) {
++        /*
++        DEBUG_PRINTF("[\e[1;31mERROR\e[m]\n"
++                     "\tcommand 0x%02x (%s)\n"
++                     "\terrno: %d (%s)\n"
++                     "\tsense: 0x%02x,%02x,%02x (%s)\n"
++                     "\tdriver: %d, transport: %d, device: %d\n",
++                     command, atapi_cmd_to_str(command),
++                     errno,
++                     strerror(errno) ? : "(null)",
++                     s->atapi_pt.sense.sense_key,
++                     s->atapi_pt.sense.asc,
++                     s->atapi_pt.sense.ascq,
++                     atapi_sense_to_str(s->atapi_pt.sense.sense_key,
++                                        s->atapi_pt.sense.asc,
++                                        s->atapi_pt.sense.ascq),
++                     cmd->driver_status,
++                     cmd->transport_status,
++                     cmd->device_status);
++        */
++        DEBUG_PRINTF("[\e[1;31mERROR\e[m] (%s)  sense: 0x%02x,%02x,%02x (%s)\n",
++                     atapi_cmd_to_str(s->atapi_pt.request[0]),
++                     s->atapi_pt.sense.sense_key,
++                     s->atapi_pt.sense.asc,
++                     s->atapi_pt.sense.ascq,
++                     atapi_sense_to_str(s->atapi_pt.sense.sense_key,
++                                        s->atapi_pt.sense.asc,
++                                        s->atapi_pt.sense.ascq));
++        ide_atapi_pt_error(s);
++        return;
++    }
++
++    s->atapi_pt.cmd_sent(s);
++}
++
++
++
++
++#if 0
+     BDRVRawState *raw_state = s->bs->opaque;
+     int read_bytes;
+     int i;
+-    ++finish_count;
+     DEBUG_PRINTF("****  finish   (%p, u=%p, raw=%p, fd=%d, %d-%d(%d))\n",
+                  s, s->atapi_pt.cmd.usr_ptr,
+                  raw_state, raw_state->fd, cmd_count,
+@@ -607,11 +746,12 @@ static void ide_atapi_pt_read_finish(IDEState *s)
+     s->atapi_pt.cmd_sent = ide_atapi_cmd_ok;
+     ATAPI_PT_SEND_PACKET;
+ }
++#endif
+ static void ide_atapi_pt_read_pio_end(IDEState *s)
+ {
+     ide_transfer_stop(s);
+-    ide_atapi_pt_read_finish(s);
++    ide_atapi_pt_sg_io_finish(s);
+ }
+ static void ide_atapi_pt_read_dma_cb(void *opaque, int ret)
+@@ -626,11 +766,9 @@ static void ide_atapi_pt_read_dma_cb(void *opaque, int ret)
+     }
+     i = dma_buf_rw(bm, 0);
+-    ide_atapi_pt_read_finish(s);
++    ide_atapi_pt_sg_io_finish(s);
+ }
+-#endif
+-#if 0
+ static void ide_atapi_pt_wcmd(IDEState *s)
+ {
+     if (s->atapi_dma)
+@@ -657,7 +795,6 @@ static void ide_atapi_pt_wcmd(IDEState *s)
+     ide_set_irq(s);
+     return;
+ }
+-#endif
+ static void ide_atapi_pt_read_format_capacities_sent(IDEState *s)
+ {
+@@ -817,9 +954,14 @@ static int ide_atapi_pt_read_cd_block_size(const uint8_t *io_buffer)
+ static void ide_atapi_pt_cmd(IDEState *s)
+ {
+     struct sg_io_v4 *cmd = &s->atapi_pt.cmd;
+-    int r;
+-    int command;
+-    BDRVRawState *raw_state = s->bs->opaque;
++
++    {
++        static int foo = 0;
++
++        if(foo == 0)
++            printf("Welcome to pt 2.1\n");
++        foo = 1;
++    }
+     memset(cmd, 0, sizeof (*cmd));
+     memcpy(s->atapi_pt.request, s->io_buffer, ATAPI_PACKET_SIZE);
+@@ -838,11 +980,13 @@ static void ide_atapi_pt_cmd(IDEState *s)
+     s->atapi_pt.reply_size_len    = 0;
+     cmd->din_xferp = (__u64)s->io_buffer;
+-    cmd->dout_xferp = (__u64)(s->io_buffer + ATAPI_PACKET_SIZE);
++    cmd->dout_xferp = (__u64)s->io_buffer;
+     s->atapi_pt.cmd_sent = ide_atapi_cmd_ok;
+-    command = s->io_buffer[0];
+-    switch (s->io_buffer[0])
++    DEBUG_PRINTF("[ATAPI] sending command: 0x%02x (\e[0;32m%s\e[m)\n",
++                 s->atapi_pt.request[0], atapi_cmd_to_str(s->atapi_pt.request[0]));
++
++    switch (s->atapi_pt.request[0])
+     {
+         /*******************/
+         /* SIMPLE COMMANDS */
+@@ -881,24 +1025,24 @@ static void ide_atapi_pt_cmd(IDEState *s)
+     case GPCMD_WRITE_AND_VERIFY_10:
+         cmd->dout_xfer_len = ube16_to_cpu(s->io_buffer + 7) * CD_FRAMESIZE;
+-        DEBUG_PRINTF("Write (%s) %d bytes\n", atapi_cmd_to_str(command),
++        DEBUG_PRINTF("Write (%s) %d bytes\n", atapi_cmd_to_str(s->atapi_pt.request[0]),
+                      cmd->dout_xfer_len);
+         if (cmd->dout_xfer_len == 0)
+             goto simple_cmd;
+-        break;
++        ide_atapi_pt_wcmd(s);
++        return;
+     case GPCMD_WRITE_12:
+         cmd->dout_xfer_len = ube32_to_cpu(s->io_buffer + 6);
+-        DEBUG_PRINTF("Write (%s) %d bytes\n", atapi_cmd_to_str(command),
++        DEBUG_PRINTF("Write (%s) %d bytes\n", atapi_cmd_to_str(s->atapi_pt.request[0]),
+                      cmd->dout_xfer_len);
+         if (cmd->dout_xfer_len == 0)
+             goto simple_cmd;
+-        //        ide_atapi_pt_wcmd(s);
+-        //        return;
+-        break;
++        ide_atapi_pt_wcmd(s);
++        return;
+     case GPCMD_WRITE_BUFFER:
+     {
+@@ -926,25 +1070,23 @@ static void ide_atapi_pt_cmd(IDEState *s)
+         }
+-        DEBUG_PRINTF("Write (%s) %d bytes\n", atapi_cmd_to_str(command),
++        DEBUG_PRINTF("Write (%s) %d bytes\n", atapi_cmd_to_str(s->atapi_pt.request[0]),
+                      cmd->dout_xfer_len);
+-        //        ide_atapi_pt_wcmd(s);
+-        //        return;
+-        break;
++        ide_atapi_pt_wcmd(s);
++        return;
+     }
+     case GPCMD_SEND_CUE_SHEET:
+         cmd->dout_xfer_len = ube24_to_cpu(s->io_buffer + 6);
+-        DEBUG_PRINTF("Write (%s) %d bytes\n", atapi_cmd_to_str(command),
++        DEBUG_PRINTF("Write (%s) %d bytes\n", atapi_cmd_to_str(s->atapi_pt.request[0]),
+                      cmd->dout_xfer_len);
+         if (cmd->dout_xfer_len == 0)
+             goto simple_cmd;
+-        //        ide_atapi_pt_wcmd(s);
+-        //        return;
+-        break;
++        ide_atapi_pt_wcmd(s);
++        return;
+     case GPCMD_MODE_SELECT_10:
+         cmd->dout_xfer_len = ube16_to_cpu(s->io_buffer + 7);
+@@ -956,65 +1098,63 @@ static void ide_atapi_pt_cmd(IDEState *s)
+             DEBUG_PRINTF("0x");
+             for(i = 0; i < 12; ++i)
+                 DEBUG_PRINTF("%02x ", s->io_buffer[i]);
+-            DEBUG_PRINTF("\n0x");
++            DEBUG_PRINTF("\n+12   0x");
+             for(i = 0; i < cmd->dout_xfer_len; ++i)
+                 DEBUG_PRINTF("%02x ", s->io_buffer[i + 12]);
++            DEBUG_PRINTF("\n+512  0x");
++            for(i = 0; i < cmd->dout_xfer_len; ++i)
++                DEBUG_PRINTF("%02x ", s->io_buffer[i + 512]);
+             DEBUG_PRINTF("\n");
+         }
+         if (cmd->dout_xfer_len == 0)
+             goto simple_cmd;
+-        //        ide_atapi_pt_wcmd(s);
+-        //        return;
+-        break;
++        ide_atapi_pt_wcmd(s);
++        return;
+     case GPCMD_SEND_KEY:
+     case GPCMD_SEND_EVENT:
+         cmd->dout_xfer_len = ube16_to_cpu(s->io_buffer + 8);
+-        DEBUG_PRINTF("Write (%s) %d bytes\n", atapi_cmd_to_str(command),
++        DEBUG_PRINTF("Write (%s) %d bytes\n", atapi_cmd_to_str(s->atapi_pt.request[0]),
+                      cmd->dout_xfer_len);
+         if (cmd->dout_xfer_len == 0)
+             goto simple_cmd;
+-        //        ide_atapi_pt_wcmd(s);
+-        //        return;
+-        break;
++        ide_atapi_pt_wcmd(s);
++        return;
+     case GPCMD_SEND_OPC:
+         cmd->dout_xfer_len = ube16_to_cpu(s->io_buffer + 7) << 3;
+         CHECK_SAME_VALUE(s->lcyl | (s->hcyl << 8), cmd->dout_xfer_len);
+-        DEBUG_PRINTF("Write (%s) %d bytes\n", atapi_cmd_to_str(command),
++        DEBUG_PRINTF("Write (%s) %d bytes\n", atapi_cmd_to_str(s->atapi_pt.request[0]),
+                      cmd->dout_xfer_len);
+         if (cmd->dout_xfer_len == 0)
+             goto simple_cmd;
+-        //        ide_atapi_pt_wcmd(s);
+-        //        return;
+-        break;
++        ide_atapi_pt_wcmd(s);
++        return;
+     case GPCMD_SET_STREAMING:
+         cmd->dout_xfer_len = ube16_to_cpu(s->io_buffer + 9);
+-        DEBUG_PRINTF("Write (%s) %d bytes\n", atapi_cmd_to_str(command),
++        DEBUG_PRINTF("Write (%s) %d bytes\n", atapi_cmd_to_str(s->atapi_pt.request[0]),
+                      cmd->dout_xfer_len);
+         if (cmd->dout_xfer_len == 0)
+             goto simple_cmd;
+-        //        ide_atapi_pt_wcmd(s);
+-        //        return;
+-        break;
++        ide_atapi_pt_wcmd(s);
++        return;
+     case GPCMD_FORMAT_UNIT:
+         cmd->dout_xfer_len = 12;
+-        DEBUG_PRINTF("Write (%s) %d bytes\n", atapi_cmd_to_str(command),
++        DEBUG_PRINTF("Write (%s) %d bytes\n", atapi_cmd_to_str(s->atapi_pt.request[0]),
+                      cmd->dout_xfer_len);
+-        //        ide_atapi_pt_wcmd(s);
+-        //        return;
+-        break;
++        ide_atapi_pt_wcmd(s);
++        return;
+         /*****************/
+         /* READ COMMANDS */
+@@ -1047,6 +1187,13 @@ static void ide_atapi_pt_cmd(IDEState *s)
+         //               max_size, s->atapi_pt.sense.add_sense_len,
+         //             sizeof (s->atapi_pt.sense));
+         memcpy(s->io_buffer, &s->atapi_pt.sense, sizeof (s->atapi_pt.sense));
++        {
++            int i;
++            DEBUG_PRINTF("Sense data: 0x");
++            for(i = 0; i < sizeof(s->atapi_pt.sense); ++i)
++                DEBUG_PRINTF("%02x ", s->io_buffer[i]);
++            DEBUG_PRINTF("\n");
++        }
+         ide_atapi_cmd_reply(s, size, max_size);
+         return;
+     }
+@@ -1181,6 +1328,13 @@ static void ide_atapi_pt_cmd(IDEState *s)
+         //s->atapi_pt.reply_size_init = cmd->din_xfer_len;
+         //        ATAPI_PT_SEND_PACKET;
+         //        return;
++        {
++            int i;
++            DEBUG_PRINTF("Cmd: 0x");
++            for(i = 0; i < ATAPI_PACKET_SIZE; ++i)
++                DEBUG_PRINTF("%02x ", s->io_buffer[i]);
++            DEBUG_PRINTF("\n");
++        }
+         break;
+     case GPCMD_GET_EVENT_STATUS_NOTIFICATION:
+@@ -1318,7 +1472,9 @@ static void ide_atapi_pt_cmd(IDEState *s)
+         return;
+     }
++    ide_atapi_pt_sg_io_finish(s);
++#if 0
+     s->atapi_pt.sense.error_code = 0;
+     s->atapi_pt.sense.sense_key = 0;
+     s->atapi_pt.sense.asc = 0;
+@@ -1327,6 +1483,19 @@ static void ide_atapi_pt_cmd(IDEState *s)
+     /* Send command and wait for reply, SG_IO ioctl*/
+     r = ioctl(raw_state->fd, 0x2285, cmd);
++    if(command == GPCMD_MODE_SENSE_10)
++    {
++        DEBUG_PRINTF("Mode sense 10, %d bytes\n", cmd->din_xfer_len);
++        {
++            int i;
++            DEBUG_PRINTF("0x");
++            for(i = 0; i < cmd->din_xfer_len; ++i)
++                DEBUG_PRINTF("%02x ", s->io_buffer[i]);
++            DEBUG_PRINTF("\n");
++        }
++    }
++
++
+     if(command == GPCMD_GET_EVENT_STATUS_NOTIFICATION)
+     {
+         struct stat file_stat;
+@@ -1361,12 +1530,14 @@ static void ide_atapi_pt_cmd(IDEState *s)
+         {
+             /* This is a no activity message we can hijack if we need to */
+-            if(stat(IDE_ATAPI_PT_NEW_CD_FILE, &file_stat) == 0 &&
+-               s->atapi_pt.new_cd_time < file_stat.st_ctime)
++            if((stat(IDE_ATAPI_PT_NEW_CD_FILE, &file_stat) == 0 &&
++               s->atapi_pt.new_cd_time < file_stat.st_ctime) ||
++               s->atapi_pt.aardvark == 1)
+             {
+                 /* 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->atapi_pt.aardvark = 0;
+                 s->io_buffer[2] = 4;
+                 s->io_buffer[4] = 2;
+@@ -1424,4 +1595,5 @@ static void ide_atapi_pt_cmd(IDEState *s)
+     }
+     s->atapi_pt.cmd_sent(s);
++#endif
+ }
index 9a556512b6272509ba14c8aa3cafca81b45fd827..2b162e928ce0580f9dfda852e7138d69862bfa4f 100644 (file)
@@ -30,3 +30,4 @@ new-input-code
 atapi-pass-through
 pv_driver_throttling_disabled
 move-iso-cdrom
+atapi-pt-write