From: Jean Guyader Date: Tue, 27 Oct 2009 15:54:08 +0000 (+0000) Subject: Merge all the atapi patches. X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=b0c083ca2998272f62b2bcfd0076fb003d36dc55;p=xenclient%2Fioemu-pq.git Merge all the atapi patches. --- diff --git a/master/atapi-async-fix.patch b/master/atapi-async-fix.patch deleted file mode 100644 index 4c6690b..0000000 --- a/master/atapi-async-fix.patch +++ /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 - #include -+#include -+#include - #include - #include -+#include -+#include -+#include -+#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; diff --git a/master/atapi-pass-through b/master/atapi-pass-through index 6416230..fa009a8 100644 --- a/master/atapi-pass-through +++ b/master/atapi-pass-through @@ -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 +#include ++#include ++#include +#include +#include ++#include ++#include ++#include ++#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 index dd0064e..0000000 --- a/master/move-iso-cdrom +++ /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" diff --git a/master/series b/master/series index 167ffe8..c2a280c 100644 --- a/master/series +++ b/master/series @@ -31,5 +31,3 @@ fix-imobile-mouse new-input-code atapi-pass-through pv_driver_throttling_disabled -move-iso-cdrom -atapi-async-fix.patch