summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2011-08-31 16:09:27 +0200
committerGerd Hoffmann <kraxel@redhat.com>2012-01-17 09:44:50 +0100
commitf003397ce95441cd8de01a728affb3de7accd1dd (patch)
treea5ec4b86fffd6c90770ff1fe0d88e435ebe7298a
parent5b6780d045720848c57a7cf461b49befcd24c691 (diff)
downloadqemu-f003397ce95441cd8de01a728affb3de7accd1dd.zip
usb: add max_packet_size to USBEndpoint
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
-rw-r--r--hw/usb-desc.c2
-rw-r--r--hw/usb.c37
-rw-r--r--hw/usb.h4
-rw-r--r--usb-linux.c31
4 files changed, 44 insertions, 30 deletions
diff --git a/hw/usb-desc.c b/hw/usb-desc.c
index 0768334b8c..b3eb97bc6b 100644
--- a/hw/usb-desc.c
+++ b/hw/usb-desc.c
@@ -248,6 +248,8 @@ static void usb_desc_ep_init(USBDevice *dev)
ep = iface->eps[e].bEndpointAddress & 0x0f;
usb_ep_set_type(dev, pid, ep, iface->eps[e].bmAttributes & 0x03);
usb_ep_set_ifnum(dev, pid, ep, iface->bInterfaceNumber);
+ usb_ep_set_max_packet_size(dev, pid, ep,
+ iface->eps[e].wMaxPacketSize);
}
}
}
diff --git a/hw/usb.c b/hw/usb.c
index f07cb9d58c..0f163b45ff 100644
--- a/hw/usb.c
+++ b/hw/usb.c
@@ -449,8 +449,9 @@ void usb_ep_dump(USBDevice *dev)
fprintf(stderr, " Interface %d, alternative %d\n",
ifnum, dev->altsetting[ifnum]);
}
- fprintf(stderr, " Endpoint %d, IN, %s\n", ep,
- tname[dev->ep_in[ep].type]);
+ fprintf(stderr, " Endpoint %d, IN, %s, %d max\n", ep,
+ tname[dev->ep_in[ep].type],
+ dev->ep_in[ep].max_packet_size);
}
if (dev->ep_out[ep].type != USB_ENDPOINT_XFER_INVALID &&
dev->ep_out[ep].ifnum == ifnum) {
@@ -459,8 +460,9 @@ void usb_ep_dump(USBDevice *dev)
fprintf(stderr, " Interface %d, alternative %d\n",
ifnum, dev->altsetting[ifnum]);
}
- fprintf(stderr, " Endpoint %d, OUT, %s\n", ep,
- tname[dev->ep_out[ep].type]);
+ fprintf(stderr, " Endpoint %d, OUT, %s, %d max\n", ep,
+ tname[dev->ep_out[ep].type],
+ dev->ep_out[ep].max_packet_size);
}
}
}
@@ -498,3 +500,30 @@ void usb_ep_set_ifnum(USBDevice *dev, int pid, int ep, uint8_t ifnum)
struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
uep->ifnum = ifnum;
}
+
+void usb_ep_set_max_packet_size(USBDevice *dev, int pid, int ep,
+ uint16_t raw)
+{
+ struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
+ int size, microframes;
+
+ size = raw & 0x7ff;
+ switch ((raw >> 11) & 3) {
+ case 1:
+ microframes = 2;
+ break;
+ case 2:
+ microframes = 3;
+ break;
+ default:
+ microframes = 1;
+ break;
+ }
+ uep->max_packet_size = size * microframes;
+}
+
+int usb_ep_get_max_packet_size(USBDevice *dev, int pid, int ep)
+{
+ struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
+ return uep->max_packet_size;
+}
diff --git a/hw/usb.h b/hw/usb.h
index c35ff7437b..5ea984cfdd 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -176,6 +176,7 @@ struct USBDescString {
struct USBEndpoint {
uint8_t type;
uint8_t ifnum;
+ int max_packet_size;
};
/* definition of a USB device */
@@ -339,6 +340,9 @@ uint8_t usb_ep_get_type(USBDevice *dev, int pid, int ep);
uint8_t usb_ep_get_ifnum(USBDevice *dev, int pid, int ep);
void usb_ep_set_type(USBDevice *dev, int pid, int ep, uint8_t type);
void usb_ep_set_ifnum(USBDevice *dev, int pid, int ep, uint8_t ifnum);
+void usb_ep_set_max_packet_size(USBDevice *dev, int pid, int ep,
+ uint16_t raw);
+int usb_ep_get_max_packet_size(USBDevice *dev, int pid, int ep);
void usb_attach(USBPort *port);
void usb_detach(USBPort *port);
diff --git a/usb-linux.c b/usb-linux.c
index 2a7b748ee6..56898dd4cd 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -83,7 +83,6 @@ struct endp_data {
AsyncURB *iso_urb;
int iso_urb_idx;
int iso_buffer_used;
- int max_packet_size;
int inflight;
};
@@ -259,26 +258,6 @@ static int get_iso_buffer_used(USBHostDevice *s, int pid, int ep)
return get_endp(s, pid, ep)->iso_buffer_used;
}
-static void set_max_packet_size(USBHostDevice *s, int pid, int ep,
- uint8_t *descriptor)
-{
- int raw = descriptor[4] + (descriptor[5] << 8);
- int size, microframes;
-
- size = raw & 0x7ff;
- switch ((raw >> 11) & 3) {
- case 1: microframes = 2; break;
- case 2: microframes = 3; break;
- default: microframes = 1; break;
- }
- get_endp(s, pid, ep)->max_packet_size = size * microframes;
-}
-
-static int get_max_packet_size(USBHostDevice *s, int pid, int ep)
-{
- return get_endp(s, pid, ep)->max_packet_size;
-}
-
/*
* Async URB state.
* We always allocate iso packet descriptors even for bulk transfers
@@ -674,7 +653,7 @@ static void usb_host_handle_destroy(USBDevice *dev)
static AsyncURB *usb_host_alloc_iso(USBHostDevice *s, int pid, uint8_t ep)
{
AsyncURB *aurb;
- int i, j, len = get_max_packet_size(s, pid, ep);
+ int i, j, len = usb_ep_get_max_packet_size(&s->dev, pid, ep);
aurb = g_malloc0(s->iso_urb_count * sizeof(*aurb));
for (i = 0; i < s->iso_urb_count; i++) {
@@ -754,7 +733,7 @@ static int usb_host_handle_iso_data(USBHostDevice *s, USBPacket *p, int in)
int i, j, ret, max_packet_size, offset, len = 0;
uint8_t *buf;
- max_packet_size = get_max_packet_size(s, p->pid, p->devep);
+ max_packet_size = usb_ep_get_max_packet_size(&s->dev, p->pid, p->devep);
if (max_packet_size == 0)
return USB_RET_NAK;
@@ -1133,6 +1112,7 @@ static int usb_linux_update_endp_table(USBHostDevice *s)
{
uint8_t *descriptors;
uint8_t devep, type, alt_interface;
+ uint16_t raw;
int interface, length, i, ep, pid;
struct endp_data *epd;
@@ -1200,9 +1180,8 @@ static int usb_linux_update_endp_table(USBHostDevice *s)
}
type = descriptors[i + 3] & 0x3;
- if (type == USB_ENDPOINT_XFER_ISOC) {
- set_max_packet_size(s, pid, ep, descriptors + i);
- };
+ raw = descriptors[i + 4] + (descriptors[i + 5] << 8);
+ usb_ep_set_max_packet_size(&s->dev, pid, ep, raw);
assert(usb_ep_get_type(&s->dev, pid, ep) ==
USB_ENDPOINT_XFER_INVALID);
usb_ep_set_type(&s->dev, pid, ep, type);