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__)
|
||||
#define EXIT_TB() asm volatile ("ret")
|
||||
#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
|
||||
@@ -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
|
||||
|
||||
|
36
qemu.spec
36
qemu.spec
@ -12,12 +12,12 @@
|
||||
|
||||
Name: qemu
|
||||
BuildRequires: SDL-devel bison e2fsprogs-devel
|
||||
URL: http://fabrice.bellard.free.fr/qemu/
|
||||
License: BSD 3-Clause, GPL v2 or later
|
||||
Url: http://fabrice.bellard.free.fr/qemu/
|
||||
License: BSD 3-Clause; GPL v2 or later; LGPL v2 or later; X11/MIT
|
||||
Group: System/Emulators/PC
|
||||
Summary: Universal CPU emulator
|
||||
Version: 0.9.0.cvs
|
||||
Release: 21
|
||||
Release: 36
|
||||
Source: %name-%version.tar.bz2
|
||||
#Patch400: qemu-0.7.0-gcc4-dot-syms.patch
|
||||
#Patch401: qemu-0.8.0-gcc4-hacks.patch
|
||||
@ -59,6 +59,15 @@ Patch69: qemu-cvs-ia64.patch
|
||||
Patch70: qemu-m68k.diff
|
||||
Patch71: qemu-s390.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
|
||||
Source201: zx-rom.bin
|
||||
Source202: COPYING.zx-rom
|
||||
@ -103,7 +112,7 @@ Patch701: gcc-3.3.5.dif
|
||||
# this is to make lint happy
|
||||
Source300: rpmlintrc
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
ExclusiveArch: %ix86 ppc sparc x86_64 ia64 s390
|
||||
ExclusiveArch: %ix86 ppc sparc x86_64 ia64 s390
|
||||
|
||||
%description
|
||||
QEMU is an extremely well-performing CPU emulator that allows you to
|
||||
@ -159,6 +168,15 @@ Authors:
|
||||
%patch70
|
||||
%patch71 -p1
|
||||
%patch72 -p1
|
||||
%patch73 -p1
|
||||
%patch74
|
||||
%patch76
|
||||
# needs fixing
|
||||
%patch77 -p1
|
||||
%patch78 -p1
|
||||
%patch79
|
||||
%patch80 -p1
|
||||
%patch81 -p2
|
||||
%ifarch ia64 ppc64
|
||||
#this is the dyngen for gcc4 patch (does not work on x86)
|
||||
%patch68 -p1
|
||||
@ -309,8 +327,16 @@ rm -rf %{gcc33tmp}
|
||||
%ifnarch %ix86 x86_64 ia64
|
||||
%dir /emul/ia32-linux
|
||||
%endif
|
||||
|
||||
%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
|
||||
- fix ATAPI bug when using libata (Brandon Philips) (#291775)
|
||||
* Sat Aug 11 2007 - olh@suse.de
|
||||
|
Loading…
Reference in New Issue
Block a user