This commit is contained in:
parent
47490e3dd4
commit
9116357c8b
20
qemu-cvs-cache-info.patch
Normal file
20
qemu-cvs-cache-info.patch
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
Index: target-i386/helper.c
|
||||||
|
===================================================================
|
||||||
|
RCS file: /sources/qemu/qemu/target-i386/helper.c,v
|
||||||
|
retrieving revision 1.84
|
||||||
|
diff -u -r1.84 helper.c
|
||||||
|
--- target-i386/helper.c 26 Jun 2007 08:35:18 -0000 1.84
|
||||||
|
+++ target-i386/helper.c 8 Sep 2007 16:07:23 -0000
|
||||||
|
@@ -1657,10 +1657,10 @@
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
/* cache info: needed for Pentium Pro compatibility */
|
||||||
|
- EAX = 0x410601;
|
||||||
|
+ EAX = 1;
|
||||||
|
EBX = 0;
|
||||||
|
ECX = 0;
|
||||||
|
- EDX = 0;
|
||||||
|
+ EDX = 0x2c307d;
|
||||||
|
break;
|
||||||
|
case 0x80000000:
|
||||||
|
EAX = env->cpuid_xlevel;
|
26
qemu-cvs-eepro100-flow-control.patch
Normal file
26
qemu-cvs-eepro100-flow-control.patch
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
Index: eepro100.c
|
||||||
|
===================================================================
|
||||||
|
RCS file: /sources/qemu/qemu/hw/eepro100.c,v
|
||||||
|
retrieving revision 1.3
|
||||||
|
diff -u -r1.3 eepro100.c
|
||||||
|
--- hw/eepro100.c 2 Jul 2007 13:38:46 -0000 1.3
|
||||||
|
+++ hw/eepro100.c 10 Sep 2007 08:38:51 -0000
|
||||||
|
@@ -140,6 +140,7 @@
|
||||||
|
SCBflash = 12, SCBeeprom = 14, /* EEPROM and flash memory control. */
|
||||||
|
SCBCtrlMDI = 16, /* MDI interface control. */
|
||||||
|
SCBEarlyRx = 20, /* Early receive byte count. */
|
||||||
|
+ SCBFlow = 24
|
||||||
|
};
|
||||||
|
|
||||||
|
/* A speedo3 transmit buffer descriptor with two buffers... */
|
||||||
|
@@ -1256,6 +1257,10 @@
|
||||||
|
eepro100_interrupt(s, 0);
|
||||||
|
break;
|
||||||
|
case SCBPort + 3:
|
||||||
|
+ case SCBFlow:
|
||||||
|
+ case SCBFlow + 1:
|
||||||
|
+ case SCBFlow + 2:
|
||||||
|
+ case SCBFlow + 3:
|
||||||
|
logout("addr=%s val=0x%02x\n", regname(addr), val);
|
||||||
|
break;
|
||||||
|
case SCBeeprom:
|
16
qemu-cvs-fdc.patch
Normal file
16
qemu-cvs-fdc.patch
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
--- qemu-orig/hw/fdc.c Mon Aug 20 19:51:42 2007
|
||||||
|
+++ qemu/hw/fdc.c Tue Aug 28 15:46:31 2007
|
||||||
|
@@ -1843,5 +1843,13 @@
|
||||||
|
static void fdctrl_result_timer(void *opaque)
|
||||||
|
{
|
||||||
|
fdctrl_t *fdctrl = opaque;
|
||||||
|
+ fdrive_t *cur_drv = get_cur_drv(fdctrl);
|
||||||
|
+ /* Pretend we are spinning.
|
||||||
|
+ * This is needed for Coherent, which uses READ ID to check for
|
||||||
|
+ * sector interleaving.
|
||||||
|
+ */
|
||||||
|
+ if (cur_drv->last_sect != 0) {
|
||||||
|
+ cur_drv->sect = (cur_drv->sect % cur_drv->last_sect) + 1;
|
||||||
|
+ }
|
||||||
|
fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
|
||||||
|
}
|
29
qemu-cvs-ide-allow-more-powermgmt.patch
Normal file
29
qemu-cvs-ide-allow-more-powermgmt.patch
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
diff -r 106bc46793ca hw/ide.c
|
||||||
|
--- a/hw/ide.c Mon Aug 27 16:20:33 2007 -0400
|
||||||
|
+++ b/hw/ide.c Mon Aug 27 16:27:28 2007 -0400
|
||||||
|
@@ -1914,6 +1914,8 @@ static void ide_ioport_write(void *opaqu
|
||||||
|
case 0x67: /* NOP */
|
||||||
|
case 0x96: /* NOP */
|
||||||
|
case 0x9a: /* NOP */
|
||||||
|
+ case 0x42: /* enable Automatic Acoustic Mode */
|
||||||
|
+ case 0xc2: /* disable Automatic Acoustic Mode */
|
||||||
|
s->status = READY_STAT | SEEK_STAT;
|
||||||
|
ide_set_irq(s);
|
||||||
|
break;
|
||||||
|
@@ -1952,12 +1954,16 @@ static void ide_ioport_write(void *opaqu
|
||||||
|
s->status = READY_STAT;
|
||||||
|
ide_set_irq(s);
|
||||||
|
break;
|
||||||
|
+ case WIN_STANDBY:
|
||||||
|
+ case WIN_STANDBY2:
|
||||||
|
case WIN_STANDBYNOW1:
|
||||||
|
case WIN_STANDBYNOW2:
|
||||||
|
case WIN_IDLEIMMEDIATE:
|
||||||
|
case CFA_IDLEIMMEDIATE:
|
||||||
|
case WIN_SETIDLE1:
|
||||||
|
case WIN_SETIDLE2:
|
||||||
|
+ case WIN_SLEEPNOW1:
|
||||||
|
+ case WIN_SLEEPNOW2:
|
||||||
|
s->status = READY_STAT;
|
||||||
|
ide_set_irq(s);
|
||||||
|
break;
|
121
qemu-cvs-ide-dvd.patch
Normal file
121
qemu-cvs-ide-dvd.patch
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
Index: hw/ide.c
|
||||||
|
===================================================================
|
||||||
|
RCS file: /sources/qemu/qemu/hw/ide.c,v
|
||||||
|
retrieving revision 1.65
|
||||||
|
diff -u -r1.65 ide.c
|
||||||
|
--- hw/ide.c 26 Aug 2007 17:42:20 -0000 1.65
|
||||||
|
+++ hw/ide.c 8 Sep 2007 16:05:27 -0000
|
||||||
|
@@ -261,6 +261,7 @@
|
||||||
|
* older drives only.
|
||||||
|
*/
|
||||||
|
#define GPCMD_GET_MEDIA_STATUS 0xda
|
||||||
|
+#define GPCMD_MODE_SENSE_6 0x1a
|
||||||
|
|
||||||
|
/* Mode page codes for mode sense/set */
|
||||||
|
#define GPMODE_R_W_ERROR_PAGE 0x01
|
||||||
|
@@ -1329,10 +1330,14 @@
|
||||||
|
ASC_MEDIUM_NOT_PRESENT);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
+ case GPCMD_MODE_SENSE_6:
|
||||||
|
case GPCMD_MODE_SENSE_10:
|
||||||
|
{
|
||||||
|
int action, code;
|
||||||
|
- max_len = ube16_to_cpu(packet + 7);
|
||||||
|
+ if (packet[0] == GPCMD_MODE_SENSE_10)
|
||||||
|
+ max_len = ube16_to_cpu(packet + 7);
|
||||||
|
+ else
|
||||||
|
+ max_len = packet[4];
|
||||||
|
action = packet[2] >> 6;
|
||||||
|
code = packet[2] & 0x3f;
|
||||||
|
switch(action) {
|
||||||
|
@@ -1368,7 +1373,7 @@
|
||||||
|
|
||||||
|
buf[8] = 0x2a;
|
||||||
|
buf[9] = 0x12;
|
||||||
|
- buf[10] = 0x00;
|
||||||
|
+ buf[10] = 0x08;
|
||||||
|
buf[11] = 0x00;
|
||||||
|
|
||||||
|
buf[12] = 0x70;
|
||||||
|
@@ -1582,6 +1587,50 @@
|
||||||
|
ide_atapi_cmd_reply(s, 8, 8);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
+ case GPCMD_READ_DVD_STRUCTURE:
|
||||||
|
+ {
|
||||||
|
+ int media = packet[1];
|
||||||
|
+ int layer = packet[6];
|
||||||
|
+ int format = packet[2];
|
||||||
|
+ int64_t total_sectors;
|
||||||
|
+
|
||||||
|
+ if (media != 0 || layer != 0)
|
||||||
|
+ {
|
||||||
|
+ ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
|
||||||
|
+ ASC_INV_FIELD_IN_CMD_PACKET);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ switch (format) {
|
||||||
|
+ case 0:
|
||||||
|
+ bdrv_get_geometry(s->bs, &total_sectors);
|
||||||
|
+ total_sectors >>= 2;
|
||||||
|
+
|
||||||
|
+ memset(buf, 0, 2052);
|
||||||
|
+
|
||||||
|
+ buf[4] = 1; // DVD-ROM, part version 1
|
||||||
|
+ buf[5] = 0xf; // 120mm disc, maximum rate unspecified
|
||||||
|
+ buf[6] = 0; // one layer, embossed data
|
||||||
|
+ buf[7] = 0;
|
||||||
|
+
|
||||||
|
+ cpu_to_ube32(buf + 8, 0);
|
||||||
|
+ cpu_to_ube32(buf + 12, total_sectors - 1);
|
||||||
|
+ cpu_to_ube32(buf + 16, total_sectors - 1);
|
||||||
|
+
|
||||||
|
+ cpu_to_be16wu((uint16_t *)buf, 2048 + 4);
|
||||||
|
+
|
||||||
|
+ ide_atapi_cmd_reply(s, 2048 + 3, 2048 + 4);
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ default:
|
||||||
|
+ ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
|
||||||
|
+ ASC_INV_FIELD_IN_CMD_PACKET);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ case GPCMD_SET_SPEED:
|
||||||
|
+ ide_atapi_cmd_ok(s);
|
||||||
|
+ break;
|
||||||
|
case GPCMD_INQUIRY:
|
||||||
|
max_len = packet[4];
|
||||||
|
buf[0] = 0x05; /* CD-ROM */
|
||||||
|
@@ -1597,6 +1646,29 @@
|
||||||
|
padstr8(buf + 32, 4, QEMU_VERSION);
|
||||||
|
ide_atapi_cmd_reply(s, 36, max_len);
|
||||||
|
break;
|
||||||
|
+ case GPCMD_GET_CONFIGURATION:
|
||||||
|
+ {
|
||||||
|
+ int64_t total_sectors;
|
||||||
|
+
|
||||||
|
+ /* only feature 0 is supported */
|
||||||
|
+ if (packet[2] != 0 || packet[3] != 0) {
|
||||||
|
+ ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
|
||||||
|
+ ASC_INV_FIELD_IN_CMD_PACKET);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ memset(buf, 0, 32);
|
||||||
|
+ bdrv_get_geometry(s->bs, &total_sectors);
|
||||||
|
+ buf[3] = 16;
|
||||||
|
+ buf[7] = total_sectors <= 1433600 ? 0x08 : 0x10; /* current profile */
|
||||||
|
+ buf[10] = 0x10 | 0x1;
|
||||||
|
+ buf[11] = 0x08; /* size of profile list */
|
||||||
|
+ buf[13] = 0x10; /* DVD-ROM profile */
|
||||||
|
+ buf[14] = buf[7] == 0x10; /* (in)active */
|
||||||
|
+ buf[17] = 0x08; /* CD-ROM profile */
|
||||||
|
+ buf[18] = buf[7] == 0x08; /* (in)active */
|
||||||
|
+ ide_atapi_cmd_reply(s, 32, 32);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
default:
|
||||||
|
ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
|
||||||
|
ASC_ILLEGAL_OPCODE);
|
134
qemu-cvs-raw-io-reliability.patch
Normal file
134
qemu-cvs-raw-io-reliability.patch
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
diff -r 808c4b54209f block-raw.c
|
||||||
|
--- a/block-raw.c Fri Aug 10 16:30:38 2007 -0400
|
||||||
|
+++ b/block-raw.c Fri Aug 10 16:30:38 2007 -0400
|
||||||
|
@@ -59,6 +59,13 @@
|
||||||
|
|
||||||
|
//#define DEBUG_FLOPPY
|
||||||
|
|
||||||
|
+#define DEBUG_BLOCK
|
||||||
|
+#ifdef DEBUG_BLOCK
|
||||||
|
+#define DEBUG_BLOCK_PRINT( formatCstr, args... ) fprintf( logfile, formatCstr, ##args ); fflush( logfile )
|
||||||
|
+#else
|
||||||
|
+#define DEBUG_BLOCK_PRINT( formatCstr, args... )
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#define FTYPE_FILE 0
|
||||||
|
#define FTYPE_CD 1
|
||||||
|
#define FTYPE_FD 2
|
||||||
|
@@ -70,6 +77,7 @@ typedef struct BDRVRawState {
|
||||||
|
typedef struct BDRVRawState {
|
||||||
|
int fd;
|
||||||
|
int type;
|
||||||
|
+ unsigned int lseek_err_cnt;
|
||||||
|
#if defined(__linux__)
|
||||||
|
/* linux floppy specific */
|
||||||
|
int fd_open_flags;
|
||||||
|
@@ -87,6 +95,8 @@ static int raw_open(BlockDriverState *bs
|
||||||
|
BDRVRawState *s = bs->opaque;
|
||||||
|
int fd, open_flags, ret;
|
||||||
|
|
||||||
|
+ s->lseek_err_cnt = 0;
|
||||||
|
+
|
||||||
|
open_flags = O_BINARY;
|
||||||
|
if ((flags & BDRV_O_ACCESS) == O_RDWR) {
|
||||||
|
open_flags |= O_RDWR;
|
||||||
|
@@ -137,8 +147,58 @@ static int raw_pread(BlockDriverState *b
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
- lseek(s->fd, offset, SEEK_SET);
|
||||||
|
+ if (lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
|
||||||
|
+ ++(s->lseek_err_cnt);
|
||||||
|
+ if(s->lseek_err_cnt <= 10) {
|
||||||
|
+ DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %ld, %p, %d) [%ld] lseek failed : %d = %s\n",
|
||||||
|
+ s->fd,
|
||||||
|
+ bs->filename,
|
||||||
|
+ offset,
|
||||||
|
+ buf,
|
||||||
|
+ count,
|
||||||
|
+ bs->total_sectors, errno, strerror(errno) );
|
||||||
|
+ }
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ s->lseek_err_cnt=0;
|
||||||
|
+
|
||||||
|
ret = read(s->fd, buf, count);
|
||||||
|
+ if (ret == count)
|
||||||
|
+ goto label__raw_read__success;
|
||||||
|
+
|
||||||
|
+ DEBUG_BLOCK_PRINT("raw_read(%d:%s, %ld, %p, %d) [%ld] read failed %d : %d = %s\n",
|
||||||
|
+ s->fd,
|
||||||
|
+ bs->filename,
|
||||||
|
+ offset,
|
||||||
|
+ buf,
|
||||||
|
+ count,
|
||||||
|
+ bs->total_sectors,
|
||||||
|
+ ret, errno, strerror(errno) );
|
||||||
|
+
|
||||||
|
+ if (bs->type == BDRV_TYPE_CDROM) { // Try harder for CDrom
|
||||||
|
+ lseek(s->fd, offset, SEEK_SET);
|
||||||
|
+ ret = read(s->fd, buf, count);
|
||||||
|
+ if (ret == count)
|
||||||
|
+ goto label__raw_read__success;
|
||||||
|
+ lseek(s->fd, offset, SEEK_SET);
|
||||||
|
+ ret = read(s->fd, buf, count);
|
||||||
|
+ if (ret == count)
|
||||||
|
+ goto label__raw_read__success;
|
||||||
|
+
|
||||||
|
+ DEBUG_BLOCK_PRINT("raw_read(%d:%s, %ld, %p, %d) [%ld] retry read failed %d : %d = %s\n",
|
||||||
|
+ s->fd,
|
||||||
|
+ bs->filename,
|
||||||
|
+ offset,
|
||||||
|
+ buf,
|
||||||
|
+ count,
|
||||||
|
+ bs->total_sectors,
|
||||||
|
+ ret, errno, strerror(errno) );
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return -1;
|
||||||
|
+
|
||||||
|
+label__raw_read__success:
|
||||||
|
+
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -152,8 +212,38 @@ static int raw_pwrite(BlockDriverState *
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
- lseek(s->fd, offset, SEEK_SET);
|
||||||
|
+ if (lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
|
||||||
|
+ ++(s->lseek_err_cnt);
|
||||||
|
+ if(s->lseek_err_cnt) {
|
||||||
|
+ DEBUG_BLOCK_PRINT("raw_write(%d:%s, %ld, %p, %d) [%ld] lseek failed : %d = %s\n",
|
||||||
|
+ s->fd,
|
||||||
|
+ bs->filename,
|
||||||
|
+ offset,
|
||||||
|
+ buf,
|
||||||
|
+ count,
|
||||||
|
+ bs->total_sectors, errno, strerror(errno) );
|
||||||
|
+ }
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ s->lseek_err_cnt = 0;
|
||||||
|
+
|
||||||
|
ret = write(s->fd, buf, count);
|
||||||
|
+ if (ret == count)
|
||||||
|
+ goto label__raw_write__success;
|
||||||
|
+
|
||||||
|
+ DEBUG_BLOCK_PRINT("raw_write(%d:%s, %ld, %p, %d) [%ld] write failed %d : %d = %s\n",
|
||||||
|
+ s->fd,
|
||||||
|
+ bs->filename,
|
||||||
|
+ offset,
|
||||||
|
+ buf,
|
||||||
|
+ count,
|
||||||
|
+ bs->total_sectors,
|
||||||
|
+ ret, errno, strerror(errno) );
|
||||||
|
+
|
||||||
|
+ return -1;
|
||||||
|
+
|
||||||
|
+label__raw_write__success:
|
||||||
|
+
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
1812
qemu-cvs-svm.patch
Normal file
1812
qemu-cvs-svm.patch
Normal file
File diff suppressed because it is too large
Load Diff
71
qemu-cvs-svm2.patch
Normal file
71
qemu-cvs-svm2.patch
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
Index: qemu/cpu-exec.c
|
||||||
|
===================================================================
|
||||||
|
--- qemu.orig/cpu-exec.c
|
||||||
|
+++ qemu/cpu-exec.c
|
||||||
|
@@ -408,7 +408,7 @@ int cpu_exec(CPUState *env1)
|
||||||
|
!(env->hflags & HF_INHIBIT_IRQ_MASK)) {
|
||||||
|
int intno;
|
||||||
|
svm_check_intercept(SVM_EXIT_INTR);
|
||||||
|
- env->interrupt_request &= ~CPU_INTERRUPT_HARD;
|
||||||
|
+ env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ);
|
||||||
|
intno = cpu_get_pic_interrupt(env);
|
||||||
|
if (loglevel & CPU_LOG_TB_IN_ASM) {
|
||||||
|
fprintf(logfile, "Servicing hardware INT=0x%02x\n", intno);
|
||||||
|
@@ -427,12 +427,13 @@ int cpu_exec(CPUState *env1)
|
||||||
|
int intno;
|
||||||
|
/* FIXME: this should respect TPR */
|
||||||
|
env->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
|
||||||
|
- stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl),
|
||||||
|
- ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl)) & ~V_IRQ_MASK);
|
||||||
|
+ svm_check_intercept(SVM_EXIT_VINTR);
|
||||||
|
intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector));
|
||||||
|
if (loglevel & CPU_LOG_TB_IN_ASM)
|
||||||
|
fprintf(logfile, "Servicing virtual hardware INT=0x%02x\n", intno);
|
||||||
|
do_interrupt(intno, 0, 0, -1, 1);
|
||||||
|
+ stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl),
|
||||||
|
+ ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl)) & ~V_IRQ_MASK);
|
||||||
|
#if defined(__sparc__) && !defined(HOST_SOLARIS)
|
||||||
|
tmp_T0 = 0;
|
||||||
|
#else
|
||||||
|
Index: qemu/target-i386/helper.c
|
||||||
|
===================================================================
|
||||||
|
--- qemu.orig/target-i386/helper.c
|
||||||
|
+++ qemu/target-i386/helper.c
|
||||||
|
@@ -4120,8 +4122,9 @@ void helper_vmrun(target_ulong addr)
|
||||||
|
if (loglevel & CPU_LOG_TB_IN_ASM)
|
||||||
|
fprintf(logfile, " %#x %#x\n", env->exception_index, env->error_code);
|
||||||
|
}
|
||||||
|
- if (int_ctl & V_IRQ_MASK)
|
||||||
|
+ if ((int_ctl & V_IRQ_MASK) || (env->intercept & INTERCEPT_VINTR)) {
|
||||||
|
env->interrupt_request |= CPU_INTERRUPT_VIRQ;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
cpu_loop_exit();
|
||||||
|
}
|
||||||
|
@@ -4283,6 +4291,13 @@ void vmexit(uint64_t exit_code, uint64_t
|
||||||
|
ldq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2)),
|
||||||
|
EIP);
|
||||||
|
|
||||||
|
+ if(env->hflags & HF_INHIBIT_IRQ_MASK) {
|
||||||
|
+ stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_state), SVM_INTERRUPT_SHADOW_MASK);
|
||||||
|
+ env->hflags &= ~HF_INHIBIT_IRQ_MASK;
|
||||||
|
+ } else {
|
||||||
|
+ stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_state), 0);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* Save the VM state in the vmcb */
|
||||||
|
SVM_SAVE_SEG(env->vm_vmcb, segs[R_ES], es);
|
||||||
|
SVM_SAVE_SEG(env->vm_vmcb, segs[R_CS], cs);
|
||||||
|
Index: qemu/target-i386/translate.c
|
||||||
|
===================================================================
|
||||||
|
--- qemu.orig/target-i386/translate.c
|
||||||
|
+++ qemu/target-i386/translate.c
|
||||||
|
@@ -5551,8 +5551,6 @@ static target_ulong disas_insn(DisasCont
|
||||||
|
gen_op_set_inhibit_irq();
|
||||||
|
/* give a chance to handle pending irqs */
|
||||||
|
gen_jmp_im(s->pc - s->cs_base);
|
||||||
|
- if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_VINTR))
|
||||||
|
- break;
|
||||||
|
gen_eob(s);
|
||||||
|
} else {
|
||||||
|
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
|
660
qemu-cvs-usb-isoch.patch
Normal file
660
qemu-cvs-usb-isoch.patch
Normal file
@ -0,0 +1,660 @@
|
|||||||
|
diff --git a/qemu/usb-linux.c b/qemu/usb-linux.c
|
||||||
|
old mode 100644
|
||||||
|
new mode 100755
|
||||||
|
index 50386ea..e790f00
|
||||||
|
--- a/qemu/usb-linux.c
|
||||||
|
+++ b/qemu/usb-linux.c
|
||||||
|
@@ -28,6 +28,7 @@
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <linux/usbdevice_fs.h>
|
||||||
|
#include <linux/version.h>
|
||||||
|
+#include <signal.h>
|
||||||
|
|
||||||
|
/* We redefine it to avoid version problems */
|
||||||
|
struct usb_ctrltransfer {
|
||||||
|
@@ -48,15 +49,152 @@ static int usb_host_find_device(int *pbus_num, int *paddr,
|
||||||
|
const char *devname);
|
||||||
|
|
||||||
|
//#define DEBUG
|
||||||
|
+//#define DEBUG_ISOCH
|
||||||
|
+//#define USE_ASYNCIO
|
||||||
|
|
||||||
|
#define USBDEVFS_PATH "/dev/bus/usb"
|
||||||
|
#define PRODUCT_NAME_SZ 32
|
||||||
|
+#define SIG_ISOCOMPLETE (SIGRTMIN+7)
|
||||||
|
+#define MAX_ENDPOINTS 16
|
||||||
|
+
|
||||||
|
+struct sigaction sigact;
|
||||||
|
+
|
||||||
|
+// endpoint association data
|
||||||
|
+struct endp_data {
|
||||||
|
+ uint8_t type;
|
||||||
|
+};
|
||||||
|
|
||||||
|
typedef struct USBHostDevice {
|
||||||
|
USBDevice dev;
|
||||||
|
int fd;
|
||||||
|
+ struct usbdevfs_urb *urb;
|
||||||
|
+ USBPacket *packet;
|
||||||
|
+ QEMUBH *bh;
|
||||||
|
+ int status;
|
||||||
|
+ struct endp_data endp_table[MAX_ENDPOINTS];
|
||||||
|
+ int configuration;
|
||||||
|
+ uint8_t descr[1024];
|
||||||
|
+ int descr_len;
|
||||||
|
} USBHostDevice;
|
||||||
|
|
||||||
|
+typedef struct PendingURB {
|
||||||
|
+ struct usbdevfs_urb *urb;
|
||||||
|
+ struct PendingURB *next;
|
||||||
|
+} PendingURB;
|
||||||
|
+
|
||||||
|
+PendingURB *pending_urbs = NULL;
|
||||||
|
+
|
||||||
|
+int add_pending_urb(struct usbdevfs_urb *urb)
|
||||||
|
+{
|
||||||
|
+ PendingURB *purb = qemu_mallocz(sizeof(PendingURB));
|
||||||
|
+ if (purb) {
|
||||||
|
+ purb->urb = urb;
|
||||||
|
+ purb->next = pending_urbs;
|
||||||
|
+ pending_urbs = purb;
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int del_pending_urb(struct usbdevfs_urb *urb)
|
||||||
|
+{
|
||||||
|
+ PendingURB *purb = pending_urbs;
|
||||||
|
+ PendingURB *prev = NULL;
|
||||||
|
+
|
||||||
|
+ while (purb && purb->urb != urb) {
|
||||||
|
+ prev = purb;
|
||||||
|
+ purb = purb->next;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (purb && purb->urb == urb) {
|
||||||
|
+ if (prev) {
|
||||||
|
+ prev->next = purb->next;
|
||||||
|
+ } else {
|
||||||
|
+ pending_urbs = purb->next;
|
||||||
|
+ }
|
||||||
|
+ qemu_free(purb);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int usb_host_update_interfaces(USBHostDevice *dev, int configuration)
|
||||||
|
+{
|
||||||
|
+ int dev_descr_len, config_descr_len;
|
||||||
|
+ int interface, nb_interfaces, nb_configurations;
|
||||||
|
+ int ret, i;
|
||||||
|
+
|
||||||
|
+ if (configuration == 0) // address state - ignore
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ i = 0;
|
||||||
|
+ dev_descr_len = dev->descr[0];
|
||||||
|
+ if (dev_descr_len > dev->descr_len)
|
||||||
|
+ goto fail;
|
||||||
|
+ nb_configurations = dev->descr[17];
|
||||||
|
+
|
||||||
|
+ i += dev_descr_len;
|
||||||
|
+ while (i < dev->descr_len) {
|
||||||
|
+#ifdef DEBUG
|
||||||
|
+ printf("i is %d, descr_len is %d, dl %d, dt %d\n", i, dev->descr_len,
|
||||||
|
+ dev->descr[i], dev->descr[i+1]);
|
||||||
|
+#endif
|
||||||
|
+ if (dev->descr[i+1] != USB_DT_CONFIG) {
|
||||||
|
+ i += dev->descr[i];
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ config_descr_len = dev->descr[i];
|
||||||
|
+
|
||||||
|
+ if (configuration == dev->descr[i + 5])
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ i += config_descr_len;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (i >= dev->descr_len) {
|
||||||
|
+ printf("usb_host: error - device has no matching configuration\n");
|
||||||
|
+ goto fail;
|
||||||
|
+ }
|
||||||
|
+ nb_interfaces = dev->descr[i + 4];
|
||||||
|
+
|
||||||
|
+#ifdef USBDEVFS_DISCONNECT
|
||||||
|
+ /* earlier Linux 2.4 do not support that */
|
||||||
|
+ {
|
||||||
|
+ struct usbdevfs_ioctl ctrl;
|
||||||
|
+ for (interface = 0; interface < nb_interfaces; interface++) {
|
||||||
|
+ ctrl.ioctl_code = USBDEVFS_DISCONNECT;
|
||||||
|
+ ctrl.ifno = interface;
|
||||||
|
+ ret = ioctl(dev->fd, USBDEVFS_IOCTL, &ctrl);
|
||||||
|
+ if (ret < 0 && errno != ENODATA) {
|
||||||
|
+ perror("USBDEVFS_DISCONNECT");
|
||||||
|
+ goto fail;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ /* XXX: only grab if all interfaces are free */
|
||||||
|
+ for (interface = 0; interface < nb_interfaces; interface++) {
|
||||||
|
+ ret = ioctl(dev->fd, USBDEVFS_CLAIMINTERFACE, &interface);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ if (errno == EBUSY) {
|
||||||
|
+ fprintf(stderr, "usb_host: warning - device already grabbed\n");
|
||||||
|
+ } else {
|
||||||
|
+ perror("USBDEVFS_CLAIMINTERFACE");
|
||||||
|
+ }
|
||||||
|
+ fail:
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+#ifdef DEBUG
|
||||||
|
+ printf("usb_host: %d interfaces claimed for configuration %d\n", nb_interfaces,
|
||||||
|
+ configuration);
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void usb_host_handle_reset(USBDevice *dev)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
@@ -76,6 +214,8 @@ static void usb_host_handle_destroy(USBDevice *dev)
|
||||||
|
qemu_free(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int usb_linux_update_endp_table(USBHostDevice *s);
|
||||||
|
+
|
||||||
|
static int usb_host_handle_control(USBDevice *dev,
|
||||||
|
int request,
|
||||||
|
int value,
|
||||||
|
@@ -85,13 +225,32 @@ static int usb_host_handle_control(USBDevice *dev,
|
||||||
|
{
|
||||||
|
USBHostDevice *s = (USBHostDevice *)dev;
|
||||||
|
struct usb_ctrltransfer ct;
|
||||||
|
+ struct usbdevfs_setinterface si;
|
||||||
|
+ int intf_update_required = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (request == (DeviceOutRequest | USB_REQ_SET_ADDRESS)) {
|
||||||
|
/* specific SET_ADDRESS support */
|
||||||
|
dev->addr = value;
|
||||||
|
return 0;
|
||||||
|
+ } else if (request == ((USB_RECIP_INTERFACE << 8) | USB_REQ_SET_INTERFACE)) {
|
||||||
|
+ /* set alternate setting for the interface */
|
||||||
|
+ si.interface = index;
|
||||||
|
+ si.altsetting = value;
|
||||||
|
+ ret = ioctl(s->fd, USBDEVFS_SETINTERFACE, &si);
|
||||||
|
+ usb_linux_update_endp_table(dev);
|
||||||
|
+ } else if (request == (DeviceOutRequest | USB_REQ_SET_CONFIGURATION)) {
|
||||||
|
+#ifdef DEBUG
|
||||||
|
+ printf("usb_host_handle_control: SET_CONFIGURATION request - config %d\n",
|
||||||
|
+ value & 0xff);
|
||||||
|
+#endif
|
||||||
|
+ if (s->configuration != (value & 0xff)) {
|
||||||
|
+ s->configuration = (value & 0xff);
|
||||||
|
+ intf_update_required = 1;
|
||||||
|
+ }
|
||||||
|
+ goto do_request;
|
||||||
|
} else {
|
||||||
|
+ do_request:
|
||||||
|
ct.bRequestType = request >> 8;
|
||||||
|
ct.bRequest = request;
|
||||||
|
ct.wValue = value;
|
||||||
|
@@ -100,19 +259,28 @@ static int usb_host_handle_control(USBDevice *dev,
|
||||||
|
ct.timeout = 50;
|
||||||
|
ct.data = data;
|
||||||
|
ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
|
||||||
|
- if (ret < 0) {
|
||||||
|
- switch(errno) {
|
||||||
|
- case ETIMEDOUT:
|
||||||
|
- return USB_RET_NAK;
|
||||||
|
- default:
|
||||||
|
- return USB_RET_STALL;
|
||||||
|
- }
|
||||||
|
- } else {
|
||||||
|
- return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ switch(errno) {
|
||||||
|
+ case ETIMEDOUT:
|
||||||
|
+ return USB_RET_NAK;
|
||||||
|
+ default:
|
||||||
|
+ return USB_RET_STALL;
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ if (intf_update_required) {
|
||||||
|
+#ifdef DEBUG
|
||||||
|
+ printf("usb_host_handle_control: updating interfaces\n");
|
||||||
|
+#endif
|
||||||
|
+ usb_host_update_interfaces(s, value & 0xff);
|
||||||
|
}
|
||||||
|
- }
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int usb_host_handle_isoch(USBDevice *dev, USBPacket *p);
|
||||||
|
+
|
||||||
|
static int usb_host_handle_data(USBDevice *dev, USBPacket *p)
|
||||||
|
{
|
||||||
|
USBHostDevice *s = (USBHostDevice *)dev;
|
||||||
|
@@ -120,6 +288,10 @@ static int usb_host_handle_data(USBDevice *dev, USBPacket *p)
|
||||||
|
int ret;
|
||||||
|
uint8_t devep = p->devep;
|
||||||
|
|
||||||
|
+ if (s->endp_table[p->devep - 1].type == USBDEVFS_URB_TYPE_ISO) {
|
||||||
|
+ return usb_host_handle_isoch(dev, p);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* XXX: optimize and handle all data types by looking at the
|
||||||
|
config descriptor */
|
||||||
|
if (p->pid == USB_TOKEN_IN)
|
||||||
|
@@ -145,18 +317,268 @@ static int usb_host_handle_data(USBDevice *dev, USBPacket *p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+void isoch_done(int signum, siginfo_t *info, void *context) {
|
||||||
|
+ struct usbdevfs_urb *urb = (struct usbdevfs_urb *)info->si_addr;
|
||||||
|
+ USBHostDevice *s = (USBHostDevice *)urb->usercontext;
|
||||||
|
+
|
||||||
|
+ if (info->si_code != SI_ASYNCIO ||
|
||||||
|
+ info->si_signo != SIG_ISOCOMPLETE) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ s->status = info->si_errno;
|
||||||
|
+ qemu_bh_schedule(s->bh);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int usb_host_handle_isoch(USBDevice *dev, USBPacket *p)
|
||||||
|
+{
|
||||||
|
+ USBHostDevice *s = (USBHostDevice *)dev;
|
||||||
|
+ struct usbdevfs_urb *urb, *purb = NULL;
|
||||||
|
+ int ret;
|
||||||
|
+ uint8_t devep = p->devep;
|
||||||
|
+
|
||||||
|
+ if (p->pid == USB_TOKEN_IN)
|
||||||
|
+ devep |= 0x80;
|
||||||
|
+
|
||||||
|
+ urb = qemu_mallocz(sizeof(struct usbdevfs_urb) +
|
||||||
|
+ sizeof(struct usbdevfs_iso_packet_desc));
|
||||||
|
+ if (!urb) {
|
||||||
|
+ printf("usb_host_handle_isoch: malloc failed\n");
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ urb->type = USBDEVFS_URB_TYPE_ISO;
|
||||||
|
+ urb->endpoint = devep;
|
||||||
|
+ urb->status = 0;
|
||||||
|
+ urb->flags = USBDEVFS_URB_ISO_ASAP;
|
||||||
|
+ urb->buffer = p->data;
|
||||||
|
+ urb->buffer_length = p->len;
|
||||||
|
+ urb->actual_length = 0;
|
||||||
|
+ urb->start_frame = 0;
|
||||||
|
+ urb->error_count = 0;
|
||||||
|
+#ifdef USE_ASYNCIO
|
||||||
|
+ urb->signr = SIG_ISOCOMPLETE;
|
||||||
|
+#else
|
||||||
|
+ urb->signr = 0;
|
||||||
|
+#endif
|
||||||
|
+ urb->usercontext = s;
|
||||||
|
+ urb->number_of_packets = 1;
|
||||||
|
+ urb->iso_frame_desc[0].length = p->len;
|
||||||
|
+ urb->iso_frame_desc[0].actual_length = 0;
|
||||||
|
+ urb->iso_frame_desc[0].status = 0;
|
||||||
|
+ ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);
|
||||||
|
+ if (ret == 0) {
|
||||||
|
+ if (!add_pending_urb(urb)) {
|
||||||
|
+ printf("usb_host_handle_isoch: add_pending_urb failed %p\n", urb);
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ printf("usb_host_handle_isoch: SUBMITURB ioctl=%d errno=%d\n", ret, errno);
|
||||||
|
+ qemu_free(urb);
|
||||||
|
+ switch(errno) {
|
||||||
|
+ case ETIMEDOUT:
|
||||||
|
+ return USB_RET_NAK;
|
||||||
|
+ case EPIPE:
|
||||||
|
+ default:
|
||||||
|
+ return USB_RET_STALL;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+#ifdef USE_ASYNCIO
|
||||||
|
+ s->urb = urb;
|
||||||
|
+ s->packet = p;
|
||||||
|
+ return USB_RET_ASYNC;
|
||||||
|
+#else
|
||||||
|
+ ret = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &purb);
|
||||||
|
+ if (ret == 0) {
|
||||||
|
+ if (del_pending_urb(purb)) {
|
||||||
|
+ ret = purb->actual_length;
|
||||||
|
+ qemu_free(purb);
|
||||||
|
+ } else {
|
||||||
|
+ printf("usb_host_handle_isoch: del_pending_urb failed %p\n", purb);
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+#ifdef DEBUG_ISOCH
|
||||||
|
+ printf("usb_host_handle_isoch: REAPURBNDELAY ioctl=%d errno=%d\n", ret, errno);
|
||||||
|
+#endif
|
||||||
|
+ }
|
||||||
|
+ return ret;
|
||||||
|
+#endif
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void usb_linux_bh_cb(void *opaque)
|
||||||
|
+{
|
||||||
|
+ USBHostDevice *s = (USBHostDevice *)opaque;
|
||||||
|
+ struct usbdevfs_urb *purb = NULL;
|
||||||
|
+ USBPacket *p = s->packet;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ if (!s || !p)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+#ifdef DEBUG_ISOCH
|
||||||
|
+ printf("completion: devaddr %d - devep 0x%02x\n", p->devaddr, p->devep);
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ ret = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &purb);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ perror("USBDEVFS_REAPURBNDELAY");
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* FIXME: handle s->status */
|
||||||
|
+ if (del_pending_urb(purb)) {
|
||||||
|
+ p->len = purb->actual_length;
|
||||||
|
+ qemu_free(purb);
|
||||||
|
+ s->packet = NULL;
|
||||||
|
+ usb_packet_complete(p);
|
||||||
|
+ } else {
|
||||||
|
+ printf("usb_linux_bh_cb: purb NOT found %p\n", purb);
|
||||||
|
+ qemu_free(purb);
|
||||||
|
+ s->packet = NULL;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// returns 1 on problem encountered or 0 for success
|
||||||
|
+static int usb_linux_update_endp_table(USBHostDevice *s)
|
||||||
|
+{
|
||||||
|
+ uint8_t descriptors[1024];
|
||||||
|
+ uint8_t data, devep, type;
|
||||||
|
+ struct usb_ctrltransfer ct;
|
||||||
|
+ int configuration, interface, alt_interface;
|
||||||
|
+ int ret, length, i;
|
||||||
|
+
|
||||||
|
+ ct.bRequestType = USB_DIR_IN;
|
||||||
|
+ ct.bRequest = USB_REQ_GET_CONFIGURATION;
|
||||||
|
+ ct.wValue = 0;
|
||||||
|
+ ct.wIndex = 0;
|
||||||
|
+ ct.wLength = 1;
|
||||||
|
+ ct.data = &data;
|
||||||
|
+ ct.timeout = 50;
|
||||||
|
+
|
||||||
|
+ ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ perror("usb_linux_update_endp_table");
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ configuration = data;
|
||||||
|
+
|
||||||
|
+ // in address state
|
||||||
|
+ if (configuration == 0)
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ /* get the desired configuration, interface, and endpoint
|
||||||
|
+ * descriptors in one shot - could also re-read all data from
|
||||||
|
+ * open file descriptor, go through sysfs entries, etc.
|
||||||
|
+ */
|
||||||
|
+ ct.bRequestType = USB_DIR_IN;
|
||||||
|
+ ct.bRequest = USB_REQ_GET_DESCRIPTOR;
|
||||||
|
+ ct.wValue = (USB_DT_CONFIG << 8) | (configuration - 1);
|
||||||
|
+ ct.wIndex = 0;
|
||||||
|
+ ct.wLength = 1024;
|
||||||
|
+ ct.data = descriptors;
|
||||||
|
+ ct.timeout = 50;
|
||||||
|
+
|
||||||
|
+ ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ perror("usb_linux_update_endp_table");
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ length = ret;
|
||||||
|
+ i = 0;
|
||||||
|
+
|
||||||
|
+ if (descriptors[i + 1] != USB_DT_CONFIG ||
|
||||||
|
+ descriptors[i + 5] != configuration) {
|
||||||
|
+ printf("invalid descriptor data - configuration\n");
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ i += descriptors[i];
|
||||||
|
+
|
||||||
|
+ while (i < length) {
|
||||||
|
+ if (descriptors[i + 1] != USB_DT_INTERFACE ||
|
||||||
|
+ (descriptors[i + 1] == USB_DT_INTERFACE &&
|
||||||
|
+ descriptors[i + 4] == 0)) {
|
||||||
|
+ i += descriptors[i];
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ interface = descriptors[i + 2];
|
||||||
|
+
|
||||||
|
+ ct.bRequestType = USB_DIR_IN | USB_RECIP_INTERFACE;
|
||||||
|
+ ct.bRequest = USB_REQ_GET_INTERFACE;
|
||||||
|
+ ct.wValue = 0;
|
||||||
|
+ ct.wIndex = interface;
|
||||||
|
+ ct.wLength = 1;
|
||||||
|
+ ct.data = &data;
|
||||||
|
+ ct.timeout = 50;
|
||||||
|
+
|
||||||
|
+ ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ perror("usb_linux_update_endp_table");
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ alt_interface = data;
|
||||||
|
+
|
||||||
|
+ // the current interface descriptor is the active interface
|
||||||
|
+ // and has endpoints
|
||||||
|
+ if (descriptors[i + 3] != alt_interface) {
|
||||||
|
+ i += descriptors[i];
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // advance to the endpoints
|
||||||
|
+ while (i < length && descriptors[i +1] != USB_DT_ENDPOINT)
|
||||||
|
+ i += descriptors[i];
|
||||||
|
+
|
||||||
|
+ if (i >= length)
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ while (i < length) {
|
||||||
|
+ if (descriptors[i + 1] != USB_DT_ENDPOINT)
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ devep = descriptors[i + 2];
|
||||||
|
+ switch (descriptors[i + 3] & 0x3) {
|
||||||
|
+ case 0x00:
|
||||||
|
+ type = USBDEVFS_URB_TYPE_CONTROL;
|
||||||
|
+ break;
|
||||||
|
+ case 0x01:
|
||||||
|
+ type = USBDEVFS_URB_TYPE_ISO;
|
||||||
|
+ break;
|
||||||
|
+ case 0x02:
|
||||||
|
+ type = USBDEVFS_URB_TYPE_BULK;
|
||||||
|
+ break;
|
||||||
|
+ case 0x03:
|
||||||
|
+ type = USBDEVFS_URB_TYPE_INTERRUPT;
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ printf("usb_host: malformed endpoint type\n");
|
||||||
|
+ type = USBDEVFS_URB_TYPE_BULK;
|
||||||
|
+ }
|
||||||
|
+ s->endp_table[(devep & 0xf) - 1].type = type;
|
||||||
|
+
|
||||||
|
+ i += descriptors[i];
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* XXX: exclude high speed devices or implement EHCI */
|
||||||
|
USBDevice *usb_host_device_open(const char *devname)
|
||||||
|
{
|
||||||
|
- int fd, interface, ret, i;
|
||||||
|
- USBHostDevice *dev;
|
||||||
|
+ int fd = -1, ret;
|
||||||
|
+ USBHostDevice *dev = NULL;
|
||||||
|
struct usbdevfs_connectinfo ci;
|
||||||
|
- uint8_t descr[1024];
|
||||||
|
char buf[1024];
|
||||||
|
- int descr_len, dev_descr_len, config_descr_len, nb_interfaces;
|
||||||
|
int bus_num, addr;
|
||||||
|
char product_name[PRODUCT_NAME_SZ];
|
||||||
|
|
||||||
|
+ dev = qemu_mallocz(sizeof(USBHostDevice));
|
||||||
|
+ if (!dev)
|
||||||
|
+ goto fail;
|
||||||
|
+
|
||||||
|
+#ifdef DEBUG_ISOCH
|
||||||
|
+ printf("usb_host_device_open %s\n", devname);
|
||||||
|
+#endif
|
||||||
|
if (usb_host_find_device(&bus_num, &addr,
|
||||||
|
product_name, sizeof(product_name),
|
||||||
|
devname) < 0)
|
||||||
|
@@ -164,61 +586,35 @@ USBDevice *usb_host_device_open(const char *devname)
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), USBDEVFS_PATH "/%03d/%03d",
|
||||||
|
bus_num, addr);
|
||||||
|
- fd = open(buf, O_RDWR);
|
||||||
|
+ fd = open(buf, O_RDWR | O_NONBLOCK);
|
||||||
|
if (fd < 0) {
|
||||||
|
perror(buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* read the config description */
|
||||||
|
- descr_len = read(fd, descr, sizeof(descr));
|
||||||
|
- if (descr_len <= 0) {
|
||||||
|
- perror("read descr");
|
||||||
|
- goto fail;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- i = 0;
|
||||||
|
- dev_descr_len = descr[0];
|
||||||
|
- if (dev_descr_len > descr_len)
|
||||||
|
- goto fail;
|
||||||
|
- i += dev_descr_len;
|
||||||
|
- config_descr_len = descr[i];
|
||||||
|
- if (i + config_descr_len > descr_len)
|
||||||
|
- goto fail;
|
||||||
|
- nb_interfaces = descr[i + 4];
|
||||||
|
- if (nb_interfaces != 1) {
|
||||||
|
- /* NOTE: currently we grab only one interface */
|
||||||
|
- fprintf(stderr, "usb_host: only one interface supported\n");
|
||||||
|
+ /* read the device description */
|
||||||
|
+ dev->descr_len = read(fd, dev->descr, sizeof(dev->descr));
|
||||||
|
+ if (dev->descr_len <= 0) {
|
||||||
|
+ perror("usb_host_update_interfaces: reading device data failed");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
-#ifdef USBDEVFS_DISCONNECT
|
||||||
|
- /* earlier Linux 2.4 do not support that */
|
||||||
|
+#ifdef DEBUG
|
||||||
|
{
|
||||||
|
- struct usbdevfs_ioctl ctrl;
|
||||||
|
- ctrl.ioctl_code = USBDEVFS_DISCONNECT;
|
||||||
|
- ctrl.ifno = 0;
|
||||||
|
- ret = ioctl(fd, USBDEVFS_IOCTL, &ctrl);
|
||||||
|
- if (ret < 0 && errno != ENODATA) {
|
||||||
|
- perror("USBDEVFS_DISCONNECT");
|
||||||
|
- goto fail;
|
||||||
|
- }
|
||||||
|
+ int x;
|
||||||
|
+ printf("=== begin dumping device descriptor data ===\n");
|
||||||
|
+ for (x = 0; x < dev->descr_len; x++)
|
||||||
|
+ printf("%02x ", dev->descr[x]);
|
||||||
|
+ printf("\n=== end dumping device descriptor data ===\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
- /* XXX: only grab if all interfaces are free */
|
||||||
|
- interface = 0;
|
||||||
|
- ret = ioctl(fd, USBDEVFS_CLAIMINTERFACE, &interface);
|
||||||
|
- if (ret < 0) {
|
||||||
|
- if (errno == EBUSY) {
|
||||||
|
- fprintf(stderr, "usb_host: device already grabbed\n");
|
||||||
|
- } else {
|
||||||
|
- perror("USBDEVFS_CLAIMINTERFACE");
|
||||||
|
- }
|
||||||
|
- fail:
|
||||||
|
- close(fd);
|
||||||
|
- return NULL;
|
||||||
|
- }
|
||||||
|
+ dev->fd = fd;
|
||||||
|
+ dev->configuration = 1;
|
||||||
|
+
|
||||||
|
+ // XXX - do something about initial configuration
|
||||||
|
+ if (!usb_host_update_interfaces(dev, 1))
|
||||||
|
+ goto fail;
|
||||||
|
|
||||||
|
ret = ioctl(fd, USBDEVFS_CONNECTINFO, &ci);
|
||||||
|
if (ret < 0) {
|
||||||
|
@@ -230,10 +626,20 @@ USBDevice *usb_host_device_open(const char *devname)
|
||||||
|
printf("host USB device %d.%d grabbed\n", bus_num, addr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
- dev = qemu_mallocz(sizeof(USBHostDevice));
|
||||||
|
- if (!dev)
|
||||||
|
+ ret = usb_linux_update_endp_table(dev);
|
||||||
|
+ if (ret) {
|
||||||
|
+ qemu_free(dev);
|
||||||
|
goto fail;
|
||||||
|
- dev->fd = fd;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+#ifdef USE_ASYNCIO
|
||||||
|
+ dev->bh = qemu_bh_new(usb_linux_bh_cb, dev);
|
||||||
|
+ if (!dev->bh) {
|
||||||
|
+ qemu_free(dev);
|
||||||
|
+ goto fail;
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
if (ci.slow)
|
||||||
|
dev->dev.speed = USB_SPEED_LOW;
|
||||||
|
else
|
||||||
|
@@ -252,7 +658,24 @@ USBDevice *usb_host_device_open(const char *devname)
|
||||||
|
pstrcpy(dev->dev.devname, sizeof(dev->dev.devname),
|
||||||
|
product_name);
|
||||||
|
|
||||||
|
+#ifdef USE_ASYNCIO
|
||||||
|
+ /* set up the signal handlers */
|
||||||
|
+ sigemptyset(&sigact.sa_mask);
|
||||||
|
+ sigact.sa_sigaction = isoch_done;
|
||||||
|
+ sigact.sa_flags = SA_SIGINFO;
|
||||||
|
+ sigact.sa_restorer = 0;
|
||||||
|
+ ret = sigaction(SIG_ISOCOMPLETE, &sigact, NULL);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ printf("sigaction SIG_ISOCOMPLETE=%d errno=%d\n", ret, errno);
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
return (USBDevice *)dev;
|
||||||
|
+fail:
|
||||||
|
+ if (dev)
|
||||||
|
+ qemu_free(dev);
|
||||||
|
+ close(fd);
|
||||||
|
+ return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_tag_value(char *buf, int buf_size,
|
@ -71,6 +71,19 @@
|
|||||||
#elif defined(__alpha__)
|
#elif defined(__alpha__)
|
||||||
#define EXIT_TB() asm volatile ("ret")
|
#define EXIT_TB() asm volatile ("ret")
|
||||||
#elif defined(__ia64__)
|
#elif defined(__ia64__)
|
||||||
|
--- qemu-0.9.0.cvs/dyngen.c
|
||||||
|
+++ qemu-0.9.0.cvs/dyngen.c
|
||||||
|
@@ -1495,8 +1495,8 @@
|
||||||
|
p = (void *)(p_end - 2);
|
||||||
|
if (p == p_start)
|
||||||
|
error("empty code for %s", name);
|
||||||
|
- if (get16((uint16_t *)p) != 0x07fe && get16((uint16_t *)p) != 0x07f4)
|
||||||
|
- error("br %%r14 expected at the end of %s", name);
|
||||||
|
+ if ((get16((uint16_t *)p) & 0xfff0) != 0x07f0)
|
||||||
|
+ error("br %%rX expected at the end of %s", name);
|
||||||
|
copy_size = p - p_start;
|
||||||
|
}
|
||||||
|
#elif defined(HOST_ALPHA)
|
||||||
--- qemu-0.9.0.cvs/exec-all.h
|
--- qemu-0.9.0.cvs/exec-all.h
|
||||||
+++ qemu-0.9.0.cvs/exec-all.h
|
+++ qemu-0.9.0.cvs/exec-all.h
|
||||||
@@ -340,6 +340,24 @@
|
@@ -340,6 +340,24 @@
|
||||||
|
15
qemu.changes
15
qemu.changes
@ -1,3 +1,18 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Thu Sep 28 14:45:41 CEST 2007 - agraf@suse.de
|
||||||
|
|
||||||
|
- fix SVM support (Alexander Graf)
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Thu Sep 13 13:37:41 CEST 2007 - agraf@suse.de
|
||||||
|
|
||||||
|
- add SVM emulation support (Alexander Graf)
|
||||||
|
- fix a misassumption in the s390 fix (uli)
|
||||||
|
- allow more IDE power management (Ben Guthro)
|
||||||
|
- log any I/O error and perform automatic read retry for CDrom (Ben Guthro)
|
||||||
|
- fix Coherent guest support (Jan Jezabek)
|
||||||
|
- fix several Darwin guest issues (Filip Navara)
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Mon Aug 20 11:05:39 CEST 2007 - agraf@suse.de
|
Mon Aug 20 11:05:39 CEST 2007 - agraf@suse.de
|
||||||
|
|
||||||
|
36
qemu.spec
36
qemu.spec
@ -12,12 +12,12 @@
|
|||||||
|
|
||||||
Name: qemu
|
Name: qemu
|
||||||
BuildRequires: SDL-devel bison e2fsprogs-devel
|
BuildRequires: SDL-devel bison e2fsprogs-devel
|
||||||
URL: http://fabrice.bellard.free.fr/qemu/
|
Url: http://fabrice.bellard.free.fr/qemu/
|
||||||
License: BSD 3-Clause, GPL v2 or later
|
License: BSD 3-Clause; GPL v2 or later; LGPL v2 or later; X11/MIT
|
||||||
Group: System/Emulators/PC
|
Group: System/Emulators/PC
|
||||||
Summary: Universal CPU emulator
|
Summary: Universal CPU emulator
|
||||||
Version: 0.9.0.cvs
|
Version: 0.9.0.cvs
|
||||||
Release: 21
|
Release: 36
|
||||||
Source: %name-%version.tar.bz2
|
Source: %name-%version.tar.bz2
|
||||||
#Patch400: qemu-0.7.0-gcc4-dot-syms.patch
|
#Patch400: qemu-0.7.0-gcc4-dot-syms.patch
|
||||||
#Patch401: qemu-0.8.0-gcc4-hacks.patch
|
#Patch401: qemu-0.8.0-gcc4-hacks.patch
|
||||||
@ -59,6 +59,15 @@ Patch69: qemu-cvs-ia64.patch
|
|||||||
Patch70: qemu-m68k.diff
|
Patch70: qemu-m68k.diff
|
||||||
Patch71: qemu-s390.patch
|
Patch71: qemu-s390.patch
|
||||||
Patch72: qemu-cvs-atapi.patch
|
Patch72: qemu-cvs-atapi.patch
|
||||||
|
Patch73: qemu-cvs-svm.patch
|
||||||
|
Patch74: qemu-cvs-cache-info.patch
|
||||||
|
Patch76: qemu-cvs-eepro100-flow-control.patch
|
||||||
|
Patch77: qemu-cvs-fdc.patch
|
||||||
|
Patch78: qemu-cvs-ide-allow-more-powermgmt.patch
|
||||||
|
Patch79: qemu-cvs-ide-dvd.patch
|
||||||
|
Patch80: qemu-cvs-raw-io-reliability.patch
|
||||||
|
Patch81: qemu-cvs-usb-isoch.patch
|
||||||
|
Patch82: qemu-cvs-svm2.patch
|
||||||
Source200: kvm_bios.bin
|
Source200: kvm_bios.bin
|
||||||
Source201: zx-rom.bin
|
Source201: zx-rom.bin
|
||||||
Source202: COPYING.zx-rom
|
Source202: COPYING.zx-rom
|
||||||
@ -103,7 +112,7 @@ Patch701: gcc-3.3.5.dif
|
|||||||
# this is to make lint happy
|
# this is to make lint happy
|
||||||
Source300: rpmlintrc
|
Source300: rpmlintrc
|
||||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||||
ExclusiveArch: %ix86 ppc sparc x86_64 ia64 s390
|
ExclusiveArch: %ix86 ppc sparc x86_64 ia64 s390
|
||||||
|
|
||||||
%description
|
%description
|
||||||
QEMU is an extremely well-performing CPU emulator that allows you to
|
QEMU is an extremely well-performing CPU emulator that allows you to
|
||||||
@ -159,6 +168,15 @@ Authors:
|
|||||||
%patch70
|
%patch70
|
||||||
%patch71 -p1
|
%patch71 -p1
|
||||||
%patch72 -p1
|
%patch72 -p1
|
||||||
|
%patch73 -p1
|
||||||
|
%patch74
|
||||||
|
%patch76
|
||||||
|
# needs fixing
|
||||||
|
%patch77 -p1
|
||||||
|
%patch78 -p1
|
||||||
|
%patch79
|
||||||
|
%patch80 -p1
|
||||||
|
%patch81 -p2
|
||||||
%ifarch ia64 ppc64
|
%ifarch ia64 ppc64
|
||||||
#this is the dyngen for gcc4 patch (does not work on x86)
|
#this is the dyngen for gcc4 patch (does not work on x86)
|
||||||
%patch68 -p1
|
%patch68 -p1
|
||||||
@ -309,8 +327,16 @@ rm -rf %{gcc33tmp}
|
|||||||
%ifnarch %ix86 x86_64 ia64
|
%ifnarch %ix86 x86_64 ia64
|
||||||
%dir /emul/ia32-linux
|
%dir /emul/ia32-linux
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Fri Sep 28 2007 - agraf@suse.de
|
||||||
|
- fix SVM support (Alexander Graf)
|
||||||
|
* Thu Sep 13 2007 - agraf@suse.de
|
||||||
|
- add SVM emulation support (Alexander Graf)
|
||||||
|
- fix a misassumption in the s390 fix (uli)
|
||||||
|
- allow more IDE power management (Ben Guthro)
|
||||||
|
- log any I/O error and perform automatic read retry for CDrom (Ben Guthro)
|
||||||
|
- fix Coherent guest support (Jan Jezabek)
|
||||||
|
- fix several Darwin guest issues (Filip Navara)
|
||||||
* Mon Aug 20 2007 - agraf@suse.de
|
* Mon Aug 20 2007 - agraf@suse.de
|
||||||
- fix ATAPI bug when using libata (Brandon Philips) (#291775)
|
- fix ATAPI bug when using libata (Brandon Philips) (#291775)
|
||||||
* Sat Aug 11 2007 - olh@suse.de
|
* Sat Aug 11 2007 - olh@suse.de
|
||||||
|
Loading…
Reference in New Issue
Block a user