diff --git a/hw/atapi-pt.c b/hw/atapi-pt.c
-index 92f2934..6633994 100644
+index 92f2934..4373a2c 100644
--- a/hw/atapi-pt.c
+++ b/hw/atapi-pt.c
@@ -1,29 +1,43 @@
/* 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,58 @@ static void ide_atapi_pt_error(IDEState *s)
+@@ -676,14 +750,63 @@ static void ide_atapi_pt_error(IDEState *s)
ide_set_irq(s);
}
+ /* Send command and wait for reply, SG_IO ioctl*/
+ cmd = &s->atapi_pt.cmd;
+ raw_state = s->bs->opaque;
-+ r = ioctl(raw_state->fd, 0x2285, cmd);
++ r = ioctl(raw_state->fd, SG_IO, cmd);
+
+ /* Unlock _before_ signalling parent */
+ pthread_mutex_unlock(&s->atapi_pt.sgio_mutex);
+
+ pthread_mutex_init(&s->atapi_pt.sgio_mutex, NULL);
+ pthread_cond_init (&s->atapi_pt.sgio_cv, NULL);
-+ pthread_create(&s->atapi_pt.sgio_thread, NULL, ide_atapi_pt_sgio_worker_thread, (void *)s);
++ 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);
+}
assert(cmd->din_xfer_len != (__u32)-1);
s->atapi_pt.sense.error_code = 0;
-@@ -691,9 +809,41 @@ static void ide_atapi_pt_do_sg_io(IDEState *s)
+@@ -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_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 (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");
if(s->atapi_pt.request[0] == GPCMD_GET_EVENT_STATUS_NOTIFICATION)
{
-@@ -746,16 +896,18 @@ static void ide_atapi_pt_do_sg_io(IDEState *s)
+@@ -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)
{
else if(stat(IDE_ATAPI_PT_EJECT_CD_FILE, &file_stat) == 0 &&
s->atapi_pt.eject_time < file_stat.st_ctime)
{
-@@ -832,16 +984,17 @@ static void ide_atapi_pt_do_sg_io(IDEState *s)
+@@ -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;
static void ide_atapi_pt_dout_fetch_dma_done(void *opaque, int ret)
{
BMDMAState *bm = opaque;
-@@ -850,13 +1003,15 @@ static void ide_atapi_pt_dout_fetch_dma_done(void *opaque, int ret)
+@@ -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);
static void ide_atapi_pt_wcmd(IDEState *s)
{
if (s->atapi_dma)
-@@ -1005,11 +1160,20 @@ static int ide_atapi_pt_read_cd_block_size(const uint8_t *io_buffer)
+@@ -1005,11 +1169,20 @@ static int ide_atapi_pt_read_cd_block_size(const uint8_t *io_buffer)
return block_size;
}
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 +1185,13 @@ static void ide_atapi_pt_cmd(IDEState *s)
+@@ -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
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 +1205,16 @@ static void ide_atapi_pt_cmd(IDEState *s)
+@@ -1043,6 +1214,16 @@ static void ide_atapi_pt_cmd(IDEState *s)
atapi_data_sizes[cmd_code].alloc_block_size);
/* A few commands need special attention */
switch(cmd_code)
{
-@@ -1054,14 +1226,15 @@ static void ide_atapi_pt_cmd(IDEState *s)
+@@ -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);
break;
case GPCMD_WRITE_BUFFER:
-@@ -1072,6 +1245,7 @@ static void ide_atapi_pt_cmd(IDEState *s)
+@@ -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);
return;
}
-@@ -1091,6 +1265,7 @@ static void ide_atapi_pt_cmd(IDEState *s)
+@@ -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);
return;
}
-@@ -1152,6 +1327,7 @@ static void ide_atapi_pt_cmd(IDEState *s)
+@@ -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);
return;
}
break;
-@@ -1160,7 +1336,10 @@ static void ide_atapi_pt_cmd(IDEState *s)
+@@ -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);
}
if(cmd->dout_xfer_len > 0)
-@@ -1169,5 +1348,5 @@ static void ide_atapi_pt_cmd(IDEState *s)
+@@ -1169,5 +1357,5 @@ static void ide_atapi_pt_cmd(IDEState *s)
return;
}