From: James Mckenzie Date: Fri, 4 Sep 2009 01:22:12 +0000 (+0100) Subject: Enable writing on atapi pt:wq X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=5f63e795a6a4618d0e6602c9810989367b69d29a;p=xenclient%2Fioemu-pq.git Enable writing on atapi pt:wq --- diff --git a/master/atapi-pt-write b/master/atapi-pt-write new file mode 100644 index 0000000..c300040 --- /dev/null +++ b/master/atapi-pt-write @@ -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 + } diff --git a/master/series b/master/series index 9a55651..2b162e9 100644 --- a/master/series +++ b/master/series @@ -30,3 +30,4 @@ new-input-code atapi-pass-through pv_driver_throttling_disabled move-iso-cdrom +atapi-pt-write