mirror of https://github.com/xemu-project/xemu.git
usb: add max_packet_size to USBEndpoint
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
5b6780d045
commit
f003397ce9
|
@ -248,6 +248,8 @@ static void usb_desc_ep_init(USBDevice *dev)
|
||||||
ep = iface->eps[e].bEndpointAddress & 0x0f;
|
ep = iface->eps[e].bEndpointAddress & 0x0f;
|
||||||
usb_ep_set_type(dev, pid, ep, iface->eps[e].bmAttributes & 0x03);
|
usb_ep_set_type(dev, pid, ep, iface->eps[e].bmAttributes & 0x03);
|
||||||
usb_ep_set_ifnum(dev, pid, ep, iface->bInterfaceNumber);
|
usb_ep_set_ifnum(dev, pid, ep, iface->bInterfaceNumber);
|
||||||
|
usb_ep_set_max_packet_size(dev, pid, ep,
|
||||||
|
iface->eps[e].wMaxPacketSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
37
hw/usb.c
37
hw/usb.c
|
@ -449,8 +449,9 @@ void usb_ep_dump(USBDevice *dev)
|
||||||
fprintf(stderr, " Interface %d, alternative %d\n",
|
fprintf(stderr, " Interface %d, alternative %d\n",
|
||||||
ifnum, dev->altsetting[ifnum]);
|
ifnum, dev->altsetting[ifnum]);
|
||||||
}
|
}
|
||||||
fprintf(stderr, " Endpoint %d, IN, %s\n", ep,
|
fprintf(stderr, " Endpoint %d, IN, %s, %d max\n", ep,
|
||||||
tname[dev->ep_in[ep].type]);
|
tname[dev->ep_in[ep].type],
|
||||||
|
dev->ep_in[ep].max_packet_size);
|
||||||
}
|
}
|
||||||
if (dev->ep_out[ep].type != USB_ENDPOINT_XFER_INVALID &&
|
if (dev->ep_out[ep].type != USB_ENDPOINT_XFER_INVALID &&
|
||||||
dev->ep_out[ep].ifnum == ifnum) {
|
dev->ep_out[ep].ifnum == ifnum) {
|
||||||
|
@ -459,8 +460,9 @@ void usb_ep_dump(USBDevice *dev)
|
||||||
fprintf(stderr, " Interface %d, alternative %d\n",
|
fprintf(stderr, " Interface %d, alternative %d\n",
|
||||||
ifnum, dev->altsetting[ifnum]);
|
ifnum, dev->altsetting[ifnum]);
|
||||||
}
|
}
|
||||||
fprintf(stderr, " Endpoint %d, OUT, %s\n", ep,
|
fprintf(stderr, " Endpoint %d, OUT, %s, %d max\n", ep,
|
||||||
tname[dev->ep_out[ep].type]);
|
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);
|
struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
|
||||||
uep->ifnum = ifnum;
|
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;
|
||||||
|
}
|
||||||
|
|
4
hw/usb.h
4
hw/usb.h
|
@ -176,6 +176,7 @@ struct USBDescString {
|
||||||
struct USBEndpoint {
|
struct USBEndpoint {
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
uint8_t ifnum;
|
uint8_t ifnum;
|
||||||
|
int max_packet_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* definition of a USB device */
|
/* 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);
|
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_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_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_attach(USBPort *port);
|
||||||
void usb_detach(USBPort *port);
|
void usb_detach(USBPort *port);
|
||||||
|
|
31
usb-linux.c
31
usb-linux.c
|
@ -83,7 +83,6 @@ struct endp_data {
|
||||||
AsyncURB *iso_urb;
|
AsyncURB *iso_urb;
|
||||||
int iso_urb_idx;
|
int iso_urb_idx;
|
||||||
int iso_buffer_used;
|
int iso_buffer_used;
|
||||||
int max_packet_size;
|
|
||||||
int inflight;
|
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;
|
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.
|
* Async URB state.
|
||||||
* We always allocate iso packet descriptors even for bulk transfers
|
* 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)
|
static AsyncURB *usb_host_alloc_iso(USBHostDevice *s, int pid, uint8_t ep)
|
||||||
{
|
{
|
||||||
AsyncURB *aurb;
|
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));
|
aurb = g_malloc0(s->iso_urb_count * sizeof(*aurb));
|
||||||
for (i = 0; i < s->iso_urb_count; i++) {
|
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;
|
int i, j, ret, max_packet_size, offset, len = 0;
|
||||||
uint8_t *buf;
|
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)
|
if (max_packet_size == 0)
|
||||||
return USB_RET_NAK;
|
return USB_RET_NAK;
|
||||||
|
|
||||||
|
@ -1133,6 +1112,7 @@ static int usb_linux_update_endp_table(USBHostDevice *s)
|
||||||
{
|
{
|
||||||
uint8_t *descriptors;
|
uint8_t *descriptors;
|
||||||
uint8_t devep, type, alt_interface;
|
uint8_t devep, type, alt_interface;
|
||||||
|
uint16_t raw;
|
||||||
int interface, length, i, ep, pid;
|
int interface, length, i, ep, pid;
|
||||||
struct endp_data *epd;
|
struct endp_data *epd;
|
||||||
|
|
||||||
|
@ -1200,9 +1180,8 @@ static int usb_linux_update_endp_table(USBHostDevice *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
type = descriptors[i + 3] & 0x3;
|
type = descriptors[i + 3] & 0x3;
|
||||||
if (type == USB_ENDPOINT_XFER_ISOC) {
|
raw = descriptors[i + 4] + (descriptors[i + 5] << 8);
|
||||||
set_max_packet_size(s, pid, ep, descriptors + i);
|
usb_ep_set_max_packet_size(&s->dev, pid, ep, raw);
|
||||||
};
|
|
||||||
assert(usb_ep_get_type(&s->dev, pid, ep) ==
|
assert(usb_ep_get_type(&s->dev, pid, ep) ==
|
||||||
USB_ENDPOINT_XFER_INVALID);
|
USB_ENDPOINT_XFER_INVALID);
|
||||||
usb_ep_set_type(&s->dev, pid, ep, type);
|
usb_ep_set_type(&s->dev, pid, ep, type);
|
||||||
|
|
Loading…
Reference in New Issue