* [Qemu-devel] [PATCH v3 0/2] usb-mtp: Added support for sending files larger than 4gb
@ 2016-08-06 10:06 Isaac Lozano
2016-08-06 10:06 ` [Qemu-devel] [PATCH v3 2/2] usb-mtp: added object properties Isaac Lozano
0 siblings, 1 reply; 4+ messages in thread
From: Isaac Lozano @ 2016-08-06 10:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Isaac Lozano, bsd, kraxel
Added support for sending files larger than 4gb from the host
to the guest. The first patch adds support on Linux guests.
The second patch is to add support on Windows guests. Windows
requires object properties to read the file size from.
We have to implement a minimum set of commands and object properties
to support object properties, though. But most of the properties
are data that we already have access to.
Isaac Lozano (2):
usb-mtp: fix sending files larger than 4gb
usb-mtp: added object properties
hw/usb/dev-mtp.c | 197 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 192 insertions(+), 5 deletions(-)
--
2.9.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Qemu-devel] [PATCH v3 2/2] usb-mtp: added object properties
2016-08-06 10:06 [Qemu-devel] [PATCH v3 0/2] usb-mtp: Added support for sending files larger than 4gb Isaac Lozano
@ 2016-08-06 10:06 ` Isaac Lozano
2016-09-07 11:56 ` Gerd Hoffmann
0 siblings, 1 reply; 4+ messages in thread
From: Isaac Lozano @ 2016-08-06 10:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Isaac Lozano, bsd, kraxel
Windows uses object properties to determine the size of a file, so to
add object properties, we must also add a minimum set of new commands
and object properties. Most object properties are data that we already
have, except for the unique persistant object identifier. Windows
doesn't use this property, it seems, so we can cheat a bit and just use
the object handle for it.
Signed-off-by: Isaac Lozano <109lozanoi@gmail.com>
---
hw/usb/dev-mtp.c | 177 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 177 insertions(+)
diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c
index 869d244..58d95ff 100644
--- a/hw/usb/dev-mtp.c
+++ b/hw/usb/dev-mtp.c
@@ -48,6 +48,9 @@ enum mtp_code {
CMD_GET_OBJECT_INFO = 0x1008,
CMD_GET_OBJECT = 0x1009,
CMD_GET_PARTIAL_OBJECT = 0x101b,
+ CMD_GET_OBJECT_PROPS_SUPPORTED = 0x9801,
+ CMD_GET_OBJECT_PROP_DESC = 0x9802,
+ CMD_GET_OBJECT_PROP_VALUE = 0x9803,
/* response codes */
RES_OK = 0x2001,
@@ -59,10 +62,12 @@ enum mtp_code {
RES_INCOMPLETE_TRANSFER = 0x2007,
RES_INVALID_STORAGE_ID = 0x2008,
RES_INVALID_OBJECT_HANDLE = 0x2009,
+ RES_INVALID_OBJECT_FORMAT_CODE = 0x200b,
RES_SPEC_BY_FORMAT_UNSUPPORTED = 0x2014,
RES_INVALID_PARENT_OBJECT = 0x201a,
RES_INVALID_PARAMETER = 0x201d,
RES_SESSION_ALREADY_OPEN = 0x201e,
+ RES_INVALID_OBJECT_PROP_CODE = 0xA801,
/* format codes */
FMT_UNDEFINED_OBJECT = 0x3000,
@@ -72,6 +77,22 @@ enum mtp_code {
EVT_OBJ_ADDED = 0x4002,
EVT_OBJ_REMOVED = 0x4003,
EVT_OBJ_INFO_CHANGED = 0x4007,
+
+ /* object properties */
+ PROP_STORAGE_ID = 0xDC01,
+ PROP_OBJECT_FORMAT = 0xDC02,
+ PROP_OBJECT_COMPRESSED_SIZE = 0xDC04,
+ PROP_PARENT_OBJECT = 0xDC0B,
+ PROP_PERSISTENT_UNIQUE_OBJECT_IDENTIFIER = 0xDC41,
+ PROP_NAME = 0xDC44,
+};
+
+enum mtp_data_type {
+ DATA_TYPE_UINT16 = 0x0004,
+ DATA_TYPE_UINT32 = 0x0006,
+ DATA_TYPE_UINT64 = 0x0008,
+ DATA_TYPE_UINT128 = 0x000a,
+ DATA_TYPE_STRING = 0xffff,
};
typedef struct {
@@ -778,6 +799,9 @@ static MTPData *usb_mtp_get_device_info(MTPState *s, MTPControl *c)
CMD_GET_OBJECT_INFO,
CMD_GET_OBJECT,
CMD_GET_PARTIAL_OBJECT,
+ CMD_GET_OBJECT_PROPS_SUPPORTED,
+ CMD_GET_OBJECT_PROP_DESC,
+ CMD_GET_OBJECT_PROP_VALUE,
};
static const uint16_t fmt[] = {
FMT_UNDEFINED_OBJECT,
@@ -971,6 +995,122 @@ static MTPData *usb_mtp_get_partial_object(MTPState *s, MTPControl *c,
return d;
}
+static MTPData *usb_mtp_get_object_props_supported(MTPState *s, MTPControl *c)
+{
+ static const uint16_t props[] = {
+ PROP_STORAGE_ID,
+ PROP_OBJECT_FORMAT,
+ PROP_OBJECT_COMPRESSED_SIZE,
+ PROP_PARENT_OBJECT,
+ PROP_PERSISTENT_UNIQUE_OBJECT_IDENTIFIER,
+ PROP_NAME,
+ };
+ MTPData *d = usb_mtp_data_alloc(c);
+ usb_mtp_add_u16_array(d, ARRAY_SIZE(props), props);
+
+ return d;
+}
+
+static MTPData *usb_mtp_get_object_prop_desc(MTPState *s, MTPControl *c)
+{
+ MTPData *d = usb_mtp_data_alloc(c);
+ switch (c->argv[0]) {
+ case PROP_STORAGE_ID:
+ usb_mtp_add_u16(d, PROP_STORAGE_ID);
+ usb_mtp_add_u16(d, DATA_TYPE_UINT32);
+ usb_mtp_add_u8(d, 0x00);
+ usb_mtp_add_u32(d, 0x00000000);
+ usb_mtp_add_u32(d, 0x00000000);
+ usb_mtp_add_u8(d, 0x00);
+ break;
+ case PROP_OBJECT_FORMAT:
+ usb_mtp_add_u16(d, PROP_OBJECT_FORMAT);
+ usb_mtp_add_u16(d, DATA_TYPE_UINT16);
+ usb_mtp_add_u8(d, 0x00);
+ usb_mtp_add_u16(d, 0x0000);
+ usb_mtp_add_u32(d, 0x00000000);
+ usb_mtp_add_u8(d, 0x00);
+ break;
+ case PROP_OBJECT_COMPRESSED_SIZE:
+ usb_mtp_add_u16(d, PROP_OBJECT_COMPRESSED_SIZE);
+ usb_mtp_add_u16(d, DATA_TYPE_UINT64);
+ usb_mtp_add_u8(d, 0x00);
+ usb_mtp_add_u64(d, 0x0000000000000000);
+ usb_mtp_add_u32(d, 0x00000000);
+ usb_mtp_add_u8(d, 0x00);
+ break;
+ case PROP_PARENT_OBJECT:
+ usb_mtp_add_u16(d, PROP_PARENT_OBJECT);
+ usb_mtp_add_u16(d, DATA_TYPE_UINT32);
+ usb_mtp_add_u8(d, 0x00);
+ usb_mtp_add_u32(d, 0x00000000);
+ usb_mtp_add_u32(d, 0x00000000);
+ usb_mtp_add_u8(d, 0x00);
+ break;
+ case PROP_PERSISTENT_UNIQUE_OBJECT_IDENTIFIER:
+ usb_mtp_add_u16(d, PROP_PERSISTENT_UNIQUE_OBJECT_IDENTIFIER);
+ usb_mtp_add_u16(d, DATA_TYPE_UINT128);
+ usb_mtp_add_u8(d, 0x00);
+ usb_mtp_add_u64(d, 0x0000000000000000);
+ usb_mtp_add_u64(d, 0x0000000000000000);
+ usb_mtp_add_u32(d, 0x00000000);
+ usb_mtp_add_u8(d, 0x00);
+ break;
+ case PROP_NAME:
+ usb_mtp_add_u16(d, PROP_NAME);
+ usb_mtp_add_u16(d, DATA_TYPE_STRING);
+ usb_mtp_add_u8(d, 0x00);
+ usb_mtp_add_u8(d, 0x00);
+ usb_mtp_add_u32(d, 0x00000000);
+ usb_mtp_add_u8(d, 0x00);
+ break;
+ default:
+ usb_mtp_data_free(d);
+ return NULL;
+ }
+
+ return d;
+}
+
+static MTPData *usb_mtp_get_object_prop_value(MTPState *s, MTPControl *c,
+ MTPObject *o)
+{
+ MTPData *d = usb_mtp_data_alloc(c);
+ switch (c->argv[1]) {
+ case PROP_STORAGE_ID:
+ usb_mtp_add_u32(d, QEMU_STORAGE_ID);
+ break;
+ case PROP_OBJECT_FORMAT:
+ usb_mtp_add_u16(d, o->format);
+ break;
+ case PROP_OBJECT_COMPRESSED_SIZE:
+ usb_mtp_add_u64(d, o->stat.st_size);
+ break;
+ case PROP_PARENT_OBJECT:
+ if (o->parent == NULL) {
+ usb_mtp_add_u32(d, 0x00000000);
+ } else {
+ usb_mtp_add_u32(d, o->parent->handle);
+ }
+ break;
+ case PROP_PERSISTENT_UNIQUE_OBJECT_IDENTIFIER:
+ /* Should be persistant between sessions,
+ * but using our objedt ID is "good enough"
+ * for now */
+ usb_mtp_add_u64(d, 0x0000000000000000);
+ usb_mtp_add_u64(d, o->handle);
+ break;
+ case PROP_NAME:
+ usb_mtp_add_str(d, o->name);
+ break;
+ default:
+ usb_mtp_data_free(d);
+ return NULL;
+ }
+
+ return d;
+}
+
static void usb_mtp_command(MTPState *s, MTPControl *c)
{
MTPData *data_in = NULL;
@@ -1118,6 +1258,43 @@ static void usb_mtp_command(MTPState *s, MTPControl *c)
nres = 1;
res0 = data_in->length;
break;
+ case CMD_GET_OBJECT_PROPS_SUPPORTED:
+ if (c->argv[0] != FMT_UNDEFINED_OBJECT &&
+ c->argv[0] != FMT_ASSOCIATION) {
+ usb_mtp_queue_result(s, RES_INVALID_OBJECT_FORMAT_CODE,
+ c->trans, 0, 0, 0);
+ return;
+ }
+ data_in = usb_mtp_get_object_props_supported(s, c);
+ break;
+ case CMD_GET_OBJECT_PROP_DESC:
+ if (c->argv[1] != FMT_UNDEFINED_OBJECT &&
+ c->argv[1] != FMT_ASSOCIATION) {
+ usb_mtp_queue_result(s, RES_INVALID_OBJECT_FORMAT_CODE,
+ c->trans, 0, 0, 0);
+ return;
+ }
+ data_in = usb_mtp_get_object_prop_desc(s, c);
+ if (data_in == NULL) {
+ usb_mtp_queue_result(s, RES_INVALID_OBJECT_PROP_CODE,
+ c->trans, 0, 0, 0);
+ return;
+ }
+ break;
+ case CMD_GET_OBJECT_PROP_VALUE:
+ o = usb_mtp_object_lookup(s, c->argv[0]);
+ if (o == NULL) {
+ usb_mtp_queue_result(s, RES_INVALID_OBJECT_HANDLE,
+ c->trans, 0, 0, 0);
+ return;
+ }
+ data_in = usb_mtp_get_object_prop_value(s, c, o);
+ if (data_in == NULL) {
+ usb_mtp_queue_result(s, RES_INVALID_OBJECT_PROP_CODE,
+ c->trans, 0, 0, 0);
+ return;
+ }
+ break;
default:
trace_usb_mtp_op_unknown(s->dev.addr, c->code);
usb_mtp_queue_result(s, RES_OPERATION_NOT_SUPPORTED,
--
2.9.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH v3 2/2] usb-mtp: added object properties
2016-08-06 10:06 ` [Qemu-devel] [PATCH v3 2/2] usb-mtp: added object properties Isaac Lozano
@ 2016-09-07 11:56 ` Gerd Hoffmann
2016-11-15 21:55 ` Bandan Das
0 siblings, 1 reply; 4+ messages in thread
From: Gerd Hoffmann @ 2016-09-07 11:56 UTC (permalink / raw)
To: Isaac Lozano; +Cc: qemu-devel, bsd
Hi,
> and object properties. Most object properties are data that we already
> have, except for the unique persistant object identifier. Windows
> + case PROP_PERSISTENT_UNIQUE_OBJECT_IDENTIFIER:
> + /* Should be persistant between sessions,
> + * but using our objedt ID is "good enough"
> + * for now */
> + usb_mtp_add_u64(d, 0x0000000000000000);
> + usb_mtp_add_u64(d, o->handle);
> + break;
Didn't I mention for an older version already that the inode number
would be a better fit? The inode number is persistent and unique per
filesystem. While being at it we might also add the device id, to
handle the (unlikely) case that the mtp device spans multiple
filesystems.
We stat() the file already and cache the result, so this is as simple as
using o->stat.st_{dev,ino}. See "man 2 stat" for details.
Other than that the patch series looks fine.
Sorry for the delay. Now that vacation time, kvm forum and qemu 2.7
freeze are over things should go faster for v4.
cheers,
Gerd
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH v3 2/2] usb-mtp: added object properties
2016-09-07 11:56 ` Gerd Hoffmann
@ 2016-11-15 21:55 ` Bandan Das
0 siblings, 0 replies; 4+ messages in thread
From: Bandan Das @ 2016-11-15 21:55 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: Isaac Lozano, qemu-devel
Gerd Hoffmann <kraxel@redhat.com> writes:
> Hi,
>
>> and object properties. Most object properties are data that we already
>> have, except for the unique persistant object identifier. Windows
>
>> + case PROP_PERSISTENT_UNIQUE_OBJECT_IDENTIFIER:
>> + /* Should be persistant between sessions,
>> + * but using our objedt ID is "good enough"
>> + * for now */
>> + usb_mtp_add_u64(d, 0x0000000000000000);
>> + usb_mtp_add_u64(d, o->handle);
>> + break;
>
> Didn't I mention for an older version already that the inode number
> would be a better fit? The inode number is persistent and unique per
> filesystem. While being at it we might also add the device id, to
> handle the (unlikely) case that the mtp device spans multiple
> filesystems.
Seems Isaac is busy with school and stuff. I will pick these up and post
a follow up soon.
Bandan
> We stat() the file already and cache the result, so this is as simple as
> using o->stat.st_{dev,ino}. See "man 2 stat" for details.
>
> Other than that the patch series looks fine.
>
> Sorry for the delay. Now that vacation time, kvm forum and qemu 2.7
> freeze are over things should go faster for v4.
>
> cheers,
> Gerd
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2016-11-15 21:55 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-08-06 10:06 [Qemu-devel] [PATCH v3 0/2] usb-mtp: Added support for sending files larger than 4gb Isaac Lozano
2016-08-06 10:06 ` [Qemu-devel] [PATCH v3 2/2] usb-mtp: added object properties Isaac Lozano
2016-09-07 11:56 ` Gerd Hoffmann
2016-11-15 21:55 ` Bandan Das
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.