Skip to content

Commit

Permalink
Merge pull request #28 from rossphilipson/error_count
Browse files Browse the repository at this point in the history
[vusb] Fix ISOCH segment lengths, return actual ISOCH error count from the back end & cleanup.
jean-edouard committed Nov 25, 2015

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
2 parents 8b0aed0 + 1ace80b commit ea39d97
Showing 2 changed files with 13 additions and 15 deletions.
8 changes: 4 additions & 4 deletions xc-vusb/include/xen/interface/io/usbif.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/******************************************************************************
* usbif.h
*
*
* Unified usb-device I/O interface for Xen guest OSes.
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
@@ -38,7 +38,7 @@
* notification can be made conditional on req_event (i.e., the generic
* hold-off mechanism provided by the ring macros). Backends must set
* req_event appropriately (e.g., using RING_FINAL_CHECK_FOR_REQUESTS()).
*
*
* Back->front notifications: When enqueuing a new response, sending a
* notification can be made conditional on rsp_event (i.e., the generic
* hold-off mechanism provided by the ring macros). Frontends must set
@@ -123,7 +123,7 @@ struct usbif_response {
usbif_request_len_t actual_length;
uint32_t data;
int16_t status; /* USBIF_RSP_??? */
uint32_t pad;
uint32_t error_count; /* total ISOCH error count */
};
typedef struct usbif_response usbif_response_t;

20 changes: 9 additions & 11 deletions xc-vusb/xc-vusb.c
Original file line number Diff line number Diff line change
@@ -1221,8 +1221,8 @@ vusb_allocate_indirect_grefs(struct vusb_device *vdev,
vdev->xendev->otherend_id, iso_mfn,
usb_urb_dir_out(shadow->urbp->urb)); /* OUT is write, so RO */

indirect_reqs[0].nr_segments++;
k++; /* Second gref slot in the first indirect reqs page */
indirect_reqs[0].nr_segments = 1;
k = 1; /* Second gref slot in the first indirect reqs page */
}

for ( ; i < nr_mfns; i++, va += PAGE_SIZE) {
@@ -1240,7 +1240,7 @@ vusb_allocate_indirect_grefs(struct vusb_device *vdev,

indirect_reqs[j].nr_segments++;
if (++k == USBIF_MAX_SEGMENTS_PER_IREQUEST) {
indirect_reqs[++j].nr_segments = 0;
j++;
k = 0;
}
}
@@ -1391,7 +1391,7 @@ vusb_put_urb(struct vusb_device *vdev, struct vusb_urbp *urbp)
nr_ind_pages = INDIRECT_PAGES_REQUIRED(nr_mfns);
shadow->indirect_reqs_size = nr_ind_pages*PAGE_SIZE;
shadow->indirect_reqs =
kzalloc(nr_ind_pages*PAGE_SIZE,
kzalloc(shadow->indirect_reqs_size,
GFP_ATOMIC);
if (unlikely(!shadow->indirect_reqs)) {
eprintk("%s out of memory\n", __FUNCTION__);
@@ -1458,7 +1458,6 @@ vusb_put_isochronous_urb(struct vusb_device *vdev, struct vusb_urbp *urbp)
struct urb *urb = urbp->urb;
usbif_iso_packet_info_t *iso_packets;
u32 nr_mfns = 0, nr_ind_pages;
u16 seg_length;
int ret = 0, i;

BUG_ON(!urb);
@@ -1486,10 +1485,9 @@ vusb_put_isochronous_urb(struct vusb_device *vdev, struct vusb_urbp *urbp)
goto err;
}

seg_length = (u16)urb->transfer_buffer_length/urb->number_of_packets;
for (i = 0; i < urb->number_of_packets; i++) {
iso_packets[i].offset = urb->iso_frame_desc[i].offset;
iso_packets[i].length = seg_length;
iso_packets[i].length = urb->iso_frame_desc[i].length;
}

shadow->iso_packet_info = iso_packets;
@@ -1513,7 +1511,7 @@ vusb_put_isochronous_urb(struct vusb_device *vdev, struct vusb_urbp *urbp)
nr_ind_pages = INDIRECT_PAGES_REQUIRED(nr_mfns + 1);
shadow->indirect_reqs_size = nr_ind_pages*PAGE_SIZE;
shadow->indirect_reqs =
kzalloc(nr_ind_pages*PAGE_SIZE,
kzalloc(shadow->indirect_reqs_size,
GFP_ATOMIC);
if (unlikely(!shadow->indirect_reqs)) {
eprintk("%s out of memory\n", __FUNCTION__);
@@ -1815,7 +1813,6 @@ vusb_urb_isochronous_finish(struct vusb_device *vdev, struct vusb_urbp *urbp,
iso_desc[i].actual_length = packet_length;
iso_desc[i].status =
vusb_status_to_errno(urbp->iso_packet_info[i].status);
iso_desc[i].offset = urbp->iso_packet_info[i].offset;

/* Do sanity check each time on effective data length */
if (unlikely((in) && (urb->transfer_buffer_length <
@@ -1827,15 +1824,16 @@ vusb_urb_isochronous_finish(struct vusb_device *vdev, struct vusb_urbp *urbp,
goto iso_io;
}

if (!iso_desc[i].status)
urb->error_count++;
total_length += packet_length;
}

/* Check for new start frame */
if (urb->transfer_flags & URB_ISO_ASAP)
urb->start_frame = urbp->rsp.data;

/* Get the ISOCH error counter */
urb->error_count = urbp->rsp.error_count;

urb->actual_length = total_length;
dprintk(D_URB2, "ISO response urbp: %p total: %u errors: %d\n",
urbp, total_length, urb->error_count);

0 comments on commit ea39d97

Please sign in to comment.