usb: mtp fixes, guest-reset switch for usb-host.
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABAgAGBQJcgOozAAoJEEy22O7T6HE4EzEP/3oPKSSMhxdk8gy///7aoF8V grBlDQPca+RBUnJyqPg7iBFO0uO+uxNVd5JYUnNuMYfTBgzJXNtLmWIZY0uHHT/u 8oYju5ayYK+n4nwcmDDYO5gfNq6zIVqfn/Ur6GurdDlrJQQ0ERU7e4M2WUpB2lgo 2Gar52fSovjV37ql5gBYeLlxADKNOxQqGeUS7k6fkxktu/hPrnmjBzzdLbntHP7B lzytUcEPej76Pm1SVQZgUewSnjpjVUAFNmWH79NpSk23VD8Q2ANE2SJFF43lxA/S vm7iklbpjrJVHOCNSQGmGKfXnO+39UMfzVmJwOmX1DMuO8zb4K6bSxUX578P6BPa Jm3qA3zE26ZkB2PlcA/XNkw2YoCBX6v+U8M7sjfRqfFLDLgvI54ZreGovM4Ai/65 H0KENMRvn+5Kb4p5wQ/z57aSbdXrXFCJIiKoPr6JrOOMpq7t3sSUY6Am418NilJE 9g+ahZrdF4NlQIQE4EnLw9vuMUvYspsYvs6qHkUe0dDPLh0elcplCVQgprsTncA1 YFLCwZMR7c1W/OzETSFcx9ph9n0UejXwGXDKR7/DoLXJsX/gqaPDExfBbMO6wYBN oXXV5/jiLPrsKREP1xm2nIREZrxmwlpg55jmtaYJ1FSa1I7hzFl7e9/bccGFWPah BN4CB8cPdGNkyDNktMfK =UGuj -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/kraxel/tags/usb-20190307-pull-request' into staging usb: mtp fixes, guest-reset switch for usb-host. # gpg: Signature made Thu 07 Mar 2019 09:53:55 GMT # gpg: using RSA key 4CB6D8EED3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [full] # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" [full] # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [full] # Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138 * remotes/kraxel/tags/usb-20190307-pull-request: Introduce new "no_guest_reset" parameter for usb-host device usb-mtp: prevent null dereference while deleting objects usb-mtp: fix some usb_mtp_write_data return paths usb-mtp: return incomplete transfer on a lstat failure Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
3a75ef6a0f
|
@ -1177,9 +1177,7 @@ static int usb_mtp_deletefn(MTPState *s, MTPObject *o, uint32_t trans)
|
|||
usb_mtp_object_free_one(s, o);
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (o->format == FMT_ASSOCIATION) {
|
||||
} else if (o->format == FMT_ASSOCIATION) {
|
||||
if (rmdir(o->path)) {
|
||||
partial_delete = true;
|
||||
} else {
|
||||
|
@ -1591,17 +1589,21 @@ done:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void usb_mtp_update_object(MTPObject *parent, char *name)
|
||||
static int usb_mtp_update_object(MTPObject *parent, char *name)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
MTPObject *o =
|
||||
usb_mtp_object_lookup_name(parent, name, strlen(name));
|
||||
|
||||
if (o) {
|
||||
lstat(o->path, &o->stat);
|
||||
ret = lstat(o->path, &o->stat);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void usb_mtp_write_data(MTPState *s)
|
||||
static int usb_mtp_write_data(MTPState *s)
|
||||
{
|
||||
MTPData *d = s->data_out;
|
||||
MTPObject *parent =
|
||||
|
@ -1609,6 +1611,7 @@ static void usb_mtp_write_data(MTPState *s)
|
|||
char *path = NULL;
|
||||
uint64_t rc;
|
||||
mode_t mask = 0644;
|
||||
int ret = 0;
|
||||
|
||||
assert(d != NULL);
|
||||
|
||||
|
@ -1617,13 +1620,13 @@ static void usb_mtp_write_data(MTPState *s)
|
|||
if (!parent || !s->write_pending) {
|
||||
usb_mtp_queue_result(s, RES_INVALID_OBJECTINFO, d->trans,
|
||||
0, 0, 0, 0);
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (s->dataset.filename) {
|
||||
path = g_strdup_printf("%s/%s", parent->path, s->dataset.filename);
|
||||
if (s->dataset.format == FMT_ASSOCIATION) {
|
||||
d->fd = mkdir(path, mask);
|
||||
ret = mkdir(path, mask);
|
||||
goto free;
|
||||
}
|
||||
d->fd = open(path, O_CREAT | O_WRONLY |
|
||||
|
@ -1653,15 +1656,21 @@ static void usb_mtp_write_data(MTPState *s)
|
|||
goto done;
|
||||
}
|
||||
if (d->write_status != WRITE_END) {
|
||||
return;
|
||||
g_free(path);
|
||||
return ret;
|
||||
} else {
|
||||
/* Only for < 4G file sizes */
|
||||
if (s->dataset.size != 0xFFFFFFFF && d->offset != s->dataset.size) {
|
||||
/*
|
||||
* Return an incomplete transfer if file size doesn't match
|
||||
* for < 4G file or if lstat fails which will result in an incorrect
|
||||
* file size
|
||||
*/
|
||||
if ((s->dataset.size != 0xFFFFFFFF &&
|
||||
d->offset != s->dataset.size) ||
|
||||
usb_mtp_update_object(parent, s->dataset.filename)) {
|
||||
usb_mtp_queue_result(s, RES_INCOMPLETE_TRANSFER, d->trans,
|
||||
0, 0, 0, 0);
|
||||
goto done;
|
||||
}
|
||||
usb_mtp_update_object(parent, s->dataset.filename);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1676,12 +1685,14 @@ done:
|
|||
*/
|
||||
if (d->fd != -1) {
|
||||
close(d->fd);
|
||||
d->fd = -1;
|
||||
}
|
||||
free:
|
||||
g_free(s->dataset.filename);
|
||||
s->dataset.size = 0;
|
||||
g_free(path);
|
||||
s->write_pending = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void usb_mtp_write_metadata(MTPState *s, uint64_t dlen)
|
||||
|
@ -1718,14 +1729,12 @@ static void usb_mtp_write_metadata(MTPState *s, uint64_t dlen)
|
|||
s->write_pending = true;
|
||||
|
||||
if (s->dataset.format == FMT_ASSOCIATION) {
|
||||
usb_mtp_write_data(s);
|
||||
/* next_handle will be allocated to the newly created dir */
|
||||
if (d->fd == -1) {
|
||||
if (usb_mtp_write_data(s)) {
|
||||
/* next_handle will be allocated to the newly created dir */
|
||||
usb_mtp_queue_result(s, RES_STORE_FULL, d->trans,
|
||||
0, 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
d->fd = -1;
|
||||
}
|
||||
|
||||
usb_mtp_queue_result(s, RES_OK, d->trans, 3, QEMU_STORAGE_ID,
|
||||
|
|
|
@ -82,7 +82,7 @@ struct USBHostDevice {
|
|||
uint32_t options;
|
||||
uint32_t loglevel;
|
||||
bool needs_autoscan;
|
||||
|
||||
bool allow_guest_reset;
|
||||
/* state */
|
||||
QTAILQ_ENTRY(USBHostDevice) next;
|
||||
int seen, errcount;
|
||||
|
@ -1456,6 +1456,10 @@ static void usb_host_handle_reset(USBDevice *udev)
|
|||
USBHostDevice *s = USB_HOST_DEVICE(udev);
|
||||
int rc;
|
||||
|
||||
if (!s->allow_guest_reset) {
|
||||
return;
|
||||
}
|
||||
|
||||
trace_usb_host_reset(s->bus_num, s->addr);
|
||||
|
||||
rc = libusb_reset_device(s->dh);
|
||||
|
@ -1573,6 +1577,7 @@ static Property usb_host_dev_properties[] = {
|
|||
DEFINE_PROP_UINT32("productid", USBHostDevice, match.product_id, 0),
|
||||
DEFINE_PROP_UINT32("isobufs", USBHostDevice, iso_urb_count, 4),
|
||||
DEFINE_PROP_UINT32("isobsize", USBHostDevice, iso_urb_frames, 32),
|
||||
DEFINE_PROP_BOOL("guest-reset", USBHostDevice, allow_guest_reset, true),
|
||||
DEFINE_PROP_UINT32("loglevel", USBHostDevice, loglevel,
|
||||
LIBUSB_LOG_LEVEL_WARNING),
|
||||
DEFINE_PROP_BIT("pipeline", USBHostDevice, options,
|
||||
|
|
Loading…
Reference in a new issue