mirror of
https://git.proxmox.com/git/qemu
synced 2025-08-15 13:51:24 +00:00
usb: move complete callback to port ops
This commit is contained in:
parent
5dc1672b27
commit
13a9a0d3e2
14
hw/usb-hub.c
14
hw/usb-hub.c
@ -256,6 +256,19 @@ static void usb_hub_wakeup(USBDevice *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void usb_hub_complete(USBDevice *dev, USBPacket *packet)
|
||||||
|
{
|
||||||
|
USBHubState *s = dev->port->opaque;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Just pass it along upstream for now.
|
||||||
|
*
|
||||||
|
* If we ever inplement usb 2.0 split transactions this will
|
||||||
|
* become a little more complicated ...
|
||||||
|
*/
|
||||||
|
usb_packet_complete(&s->dev, packet);
|
||||||
|
}
|
||||||
|
|
||||||
static void usb_hub_handle_attach(USBDevice *dev)
|
static void usb_hub_handle_attach(USBDevice *dev)
|
||||||
{
|
{
|
||||||
USBHubState *s = DO_UPCAST(USBHubState, dev, dev);
|
USBHubState *s = DO_UPCAST(USBHubState, dev, dev);
|
||||||
@ -524,6 +537,7 @@ static USBPortOps usb_hub_port_ops = {
|
|||||||
.attach = usb_hub_attach,
|
.attach = usb_hub_attach,
|
||||||
.detach = usb_hub_detach,
|
.detach = usb_hub_detach,
|
||||||
.wakeup = usb_hub_wakeup,
|
.wakeup = usb_hub_wakeup,
|
||||||
|
.complete = usb_hub_complete,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int usb_hub_initfn(USBDevice *dev)
|
static int usb_hub_initfn(USBDevice *dev)
|
||||||
|
@ -241,7 +241,7 @@ static void usb_msd_command_complete(SCSIBus *bus, int reason, uint32_t tag,
|
|||||||
s->mode = USB_MSDM_CSW;
|
s->mode = USB_MSDM_CSW;
|
||||||
}
|
}
|
||||||
s->packet = NULL;
|
s->packet = NULL;
|
||||||
usb_packet_complete(p);
|
usb_packet_complete(&s->dev, p);
|
||||||
} else if (s->data_len == 0) {
|
} else if (s->data_len == 0) {
|
||||||
s->mode = USB_MSDM_CSW;
|
s->mode = USB_MSDM_CSW;
|
||||||
}
|
}
|
||||||
@ -257,7 +257,7 @@ static void usb_msd_command_complete(SCSIBus *bus, int reason, uint32_t tag,
|
|||||||
usb_packet_complete returns. */
|
usb_packet_complete returns. */
|
||||||
DPRINTF("Packet complete %p\n", p);
|
DPRINTF("Packet complete %p\n", p);
|
||||||
s->packet = NULL;
|
s->packet = NULL;
|
||||||
usb_packet_complete(p);
|
usb_packet_complete(&s->dev, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -261,10 +261,12 @@
|
|||||||
|
|
||||||
static void musb_attach(USBPort *port);
|
static void musb_attach(USBPort *port);
|
||||||
static void musb_detach(USBPort *port);
|
static void musb_detach(USBPort *port);
|
||||||
|
static void musb_schedule_cb(USBDevice *dev, USBPacket *p);
|
||||||
|
|
||||||
static USBPortOps musb_port_ops = {
|
static USBPortOps musb_port_ops = {
|
||||||
.attach = musb_attach,
|
.attach = musb_attach,
|
||||||
.detach = musb_detach,
|
.detach = musb_detach,
|
||||||
|
.complete = musb_schedule_cb,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct MUSBPacket MUSBPacket;
|
typedef struct MUSBPacket MUSBPacket;
|
||||||
@ -511,9 +513,11 @@ static inline void musb_cb_tick1(void *opaque)
|
|||||||
|
|
||||||
#define musb_cb_tick (dir ? musb_cb_tick1 : musb_cb_tick0)
|
#define musb_cb_tick (dir ? musb_cb_tick1 : musb_cb_tick0)
|
||||||
|
|
||||||
static inline void musb_schedule_cb(USBPacket *packey, void *opaque, int dir)
|
static inline void musb_schedule_cb(USBDevice *dev, USBPacket *packey)
|
||||||
{
|
{
|
||||||
MUSBEndPoint *ep = (MUSBEndPoint *) opaque;
|
MUSBPacket *p = container_of(packey, MUSBPacket, p);
|
||||||
|
MUSBEndPoint *ep = p->ep;
|
||||||
|
int dir = p->dir;
|
||||||
int timeout = 0;
|
int timeout = 0;
|
||||||
|
|
||||||
if (ep->status[dir] == USB_RET_NAK)
|
if (ep->status[dir] == USB_RET_NAK)
|
||||||
@ -521,25 +525,15 @@ static inline void musb_schedule_cb(USBPacket *packey, void *opaque, int dir)
|
|||||||
else if (ep->interrupt[dir])
|
else if (ep->interrupt[dir])
|
||||||
timeout = 8;
|
timeout = 8;
|
||||||
else
|
else
|
||||||
return musb_cb_tick(opaque);
|
return musb_cb_tick(ep);
|
||||||
|
|
||||||
if (!ep->intv_timer[dir])
|
if (!ep->intv_timer[dir])
|
||||||
ep->intv_timer[dir] = qemu_new_timer_ns(vm_clock, musb_cb_tick, opaque);
|
ep->intv_timer[dir] = qemu_new_timer_ns(vm_clock, musb_cb_tick, ep);
|
||||||
|
|
||||||
qemu_mod_timer(ep->intv_timer[dir], qemu_get_clock_ns(vm_clock) +
|
qemu_mod_timer(ep->intv_timer[dir], qemu_get_clock_ns(vm_clock) +
|
||||||
muldiv64(timeout, get_ticks_per_sec(), 8000));
|
muldiv64(timeout, get_ticks_per_sec(), 8000));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void musb_schedule0_cb(USBPacket *packey, void *opaque)
|
|
||||||
{
|
|
||||||
return musb_schedule_cb(packey, opaque, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void musb_schedule1_cb(USBPacket *packey, void *opaque)
|
|
||||||
{
|
|
||||||
return musb_schedule_cb(packey, opaque, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int musb_timeout(int ttype, int speed, int val)
|
static int musb_timeout(int ttype, int speed, int val)
|
||||||
{
|
{
|
||||||
#if 1
|
#if 1
|
||||||
@ -596,7 +590,6 @@ static inline void musb_packet(MUSBState *s, MUSBEndPoint *ep,
|
|||||||
ep->type[idx] >> 6, ep->interval[idx]);
|
ep->type[idx] >> 6, ep->interval[idx]);
|
||||||
ep->interrupt[dir] = ttype == USB_ENDPOINT_XFER_INT;
|
ep->interrupt[dir] = ttype == USB_ENDPOINT_XFER_INT;
|
||||||
ep->delayed_cb[dir] = cb;
|
ep->delayed_cb[dir] = cb;
|
||||||
cb = dir ? musb_schedule1_cb : musb_schedule0_cb;
|
|
||||||
|
|
||||||
ep->packey[dir].p.pid = pid;
|
ep->packey[dir].p.pid = pid;
|
||||||
/* A wild guess on the FADDR semantics... */
|
/* A wild guess on the FADDR semantics... */
|
||||||
@ -604,8 +597,6 @@ static inline void musb_packet(MUSBState *s, MUSBEndPoint *ep,
|
|||||||
ep->packey[dir].p.devep = ep->type[idx] & 0xf;
|
ep->packey[dir].p.devep = ep->type[idx] & 0xf;
|
||||||
ep->packey[dir].p.data = (void *) ep->buf[idx];
|
ep->packey[dir].p.data = (void *) ep->buf[idx];
|
||||||
ep->packey[dir].p.len = len;
|
ep->packey[dir].p.len = len;
|
||||||
ep->packey[dir].p.complete_cb = cb;
|
|
||||||
ep->packey[dir].p.complete_opaque = ep;
|
|
||||||
ep->packey[dir].ep = ep;
|
ep->packey[dir].ep = ep;
|
||||||
ep->packey[dir].dir = dir;
|
ep->packey[dir].dir = dir;
|
||||||
|
|
||||||
@ -620,7 +611,7 @@ static inline void musb_packet(MUSBState *s, MUSBEndPoint *ep,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ep->status[dir] = ret;
|
ep->status[dir] = ret;
|
||||||
usb_packet_complete(&ep->packey[dir].p);
|
usb_packet_complete(s->port.dev, &ep->packey[dir].p);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void musb_tx_packet_complete(USBPacket *packey, void *opaque)
|
static void musb_tx_packet_complete(USBPacket *packey, void *opaque)
|
||||||
|
@ -575,7 +575,7 @@ static void ohci_copy_iso_td(OHCIState *ohci,
|
|||||||
|
|
||||||
static void ohci_process_lists(OHCIState *ohci, int completion);
|
static void ohci_process_lists(OHCIState *ohci, int completion);
|
||||||
|
|
||||||
static void ohci_async_complete_packet(USBPacket *packet, void *opaque)
|
static void ohci_async_complete_packet(USBDevice *dev, USBPacket *packet)
|
||||||
{
|
{
|
||||||
OHCIState *ohci = container_of(packet, OHCIState, usb_packet);
|
OHCIState *ohci = container_of(packet, OHCIState, usb_packet);
|
||||||
#ifdef DEBUG_PACKET
|
#ifdef DEBUG_PACKET
|
||||||
@ -748,8 +748,6 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
|
|||||||
ohci->usb_packet.devep = OHCI_BM(ed->flags, ED_EN);
|
ohci->usb_packet.devep = OHCI_BM(ed->flags, ED_EN);
|
||||||
ohci->usb_packet.data = ohci->usb_buf;
|
ohci->usb_packet.data = ohci->usb_buf;
|
||||||
ohci->usb_packet.len = len;
|
ohci->usb_packet.len = len;
|
||||||
ohci->usb_packet.complete_cb = ohci_async_complete_packet;
|
|
||||||
ohci->usb_packet.complete_opaque = ohci;
|
|
||||||
ret = dev->info->handle_packet(dev, &ohci->usb_packet);
|
ret = dev->info->handle_packet(dev, &ohci->usb_packet);
|
||||||
if (ret != USB_RET_NODEV)
|
if (ret != USB_RET_NODEV)
|
||||||
break;
|
break;
|
||||||
@ -946,8 +944,6 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
|
|||||||
ohci->usb_packet.devep = OHCI_BM(ed->flags, ED_EN);
|
ohci->usb_packet.devep = OHCI_BM(ed->flags, ED_EN);
|
||||||
ohci->usb_packet.data = ohci->usb_buf;
|
ohci->usb_packet.data = ohci->usb_buf;
|
||||||
ohci->usb_packet.len = len;
|
ohci->usb_packet.len = len;
|
||||||
ohci->usb_packet.complete_cb = ohci_async_complete_packet;
|
|
||||||
ohci->usb_packet.complete_opaque = ohci;
|
|
||||||
ret = dev->info->handle_packet(dev, &ohci->usb_packet);
|
ret = dev->info->handle_packet(dev, &ohci->usb_packet);
|
||||||
if (ret != USB_RET_NODEV)
|
if (ret != USB_RET_NODEV)
|
||||||
break;
|
break;
|
||||||
@ -1665,6 +1661,7 @@ static CPUWriteMemoryFunc * const ohci_writefn[3]={
|
|||||||
static USBPortOps ohci_port_ops = {
|
static USBPortOps ohci_port_ops = {
|
||||||
.attach = ohci_attach,
|
.attach = ohci_attach,
|
||||||
.detach = ohci_detach,
|
.detach = ohci_detach,
|
||||||
|
.complete = ohci_async_complete_packet,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void usb_ohci_init(OHCIState *ohci, DeviceState *dev,
|
static void usb_ohci_init(OHCIState *ohci, DeviceState *dev,
|
||||||
|
@ -642,7 +642,7 @@ static int uhci_broadcast_packet(UHCIState *s, USBPacket *p)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void uhci_async_complete(USBPacket * packet, void *opaque);
|
static void uhci_async_complete(USBDevice *dev, USBPacket *packet);
|
||||||
static void uhci_process_frame(UHCIState *s);
|
static void uhci_process_frame(UHCIState *s);
|
||||||
|
|
||||||
/* return -1 if fatal error (frame must be stopped)
|
/* return -1 if fatal error (frame must be stopped)
|
||||||
@ -795,8 +795,6 @@ static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *in
|
|||||||
async->packet.devep = (td->token >> 15) & 0xf;
|
async->packet.devep = (td->token >> 15) & 0xf;
|
||||||
async->packet.data = async->buffer;
|
async->packet.data = async->buffer;
|
||||||
async->packet.len = max_len;
|
async->packet.len = max_len;
|
||||||
async->packet.complete_cb = uhci_async_complete;
|
|
||||||
async->packet.complete_opaque = s;
|
|
||||||
|
|
||||||
switch(pid) {
|
switch(pid) {
|
||||||
case USB_TOKEN_OUT:
|
case USB_TOKEN_OUT:
|
||||||
@ -832,7 +830,7 @@ done:
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void uhci_async_complete(USBPacket *packet, void *opaque)
|
static void uhci_async_complete(USBDevice *dev, USBPacket *packet)
|
||||||
{
|
{
|
||||||
UHCIAsync *async = container_of(packet, UHCIAsync, packet);
|
UHCIAsync *async = container_of(packet, UHCIAsync, packet);
|
||||||
UHCIState *s = async->uhci;
|
UHCIState *s = async->uhci;
|
||||||
@ -1083,6 +1081,7 @@ static USBPortOps uhci_port_ops = {
|
|||||||
.attach = uhci_attach,
|
.attach = uhci_attach,
|
||||||
.detach = uhci_detach,
|
.detach = uhci_detach,
|
||||||
.wakeup = uhci_wakeup,
|
.wakeup = uhci_wakeup,
|
||||||
|
.complete = uhci_async_complete,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int usb_uhci_common_initfn(UHCIState *s)
|
static int usb_uhci_common_initfn(UHCIState *s)
|
||||||
|
7
hw/usb.h
7
hw/usb.h
@ -235,6 +235,7 @@ typedef struct USBPortOps {
|
|||||||
void (*attach)(USBPort *port);
|
void (*attach)(USBPort *port);
|
||||||
void (*detach)(USBPort *port);
|
void (*detach)(USBPort *port);
|
||||||
void (*wakeup)(USBDevice *dev);
|
void (*wakeup)(USBDevice *dev);
|
||||||
|
void (*complete)(USBDevice *dev, USBPacket *p);
|
||||||
} USBPortOps;
|
} USBPortOps;
|
||||||
|
|
||||||
/* USB port on which a device can be connected */
|
/* USB port on which a device can be connected */
|
||||||
@ -259,8 +260,6 @@ struct USBPacket {
|
|||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
int len;
|
int len;
|
||||||
/* Internal use by the USB layer. */
|
/* Internal use by the USB layer. */
|
||||||
USBCallback *complete_cb;
|
|
||||||
void *complete_opaque;
|
|
||||||
USBCallback *cancel_cb;
|
USBCallback *cancel_cb;
|
||||||
void *cancel_opaque;
|
void *cancel_opaque;
|
||||||
};
|
};
|
||||||
@ -278,9 +277,9 @@ static inline void usb_defer_packet(USBPacket *p, USBCallback *cancel,
|
|||||||
/* Notify the controller that an async packet is complete. This should only
|
/* Notify the controller that an async packet is complete. This should only
|
||||||
be called for packets previously deferred with usb_defer_packet, and
|
be called for packets previously deferred with usb_defer_packet, and
|
||||||
should never be called from within handle_packet. */
|
should never be called from within handle_packet. */
|
||||||
static inline void usb_packet_complete(USBPacket *p)
|
static inline void usb_packet_complete(USBDevice *dev, USBPacket *p)
|
||||||
{
|
{
|
||||||
p->complete_cb(p, p->complete_opaque);
|
dev->port->ops->complete(dev, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cancel an active packet. The packed must have been deferred with
|
/* Cancel an active packet. The packed must have been deferred with
|
||||||
|
@ -348,7 +348,7 @@ static void async_complete(void *opaque)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
usb_packet_complete(p);
|
usb_packet_complete(&s->dev, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
async_free(aurb);
|
async_free(aurb);
|
||||||
|
Loading…
Reference in New Issue
Block a user