static void musb_attach(USBPort *port);
static void musb_detach(USBPort *port);
static void musb_schedule_cb(USBDevice *dev, USBPacket *p);
+static void musb_device_destroy(USBBus *bus, USBDevice *dev);
static USBPortOps musb_port_ops = {
.attach = musb_attach,
.complete = musb_schedule_cb,
};
+static USBBusOps musb_bus_ops = {
+ .device_destroy = musb_device_destroy,
+};
+
typedef struct MUSBPacket MUSBPacket;
typedef struct MUSBEndPoint MUSBEndPoint;
s->ep[i].epnum = i;
}
- usb_bus_new(&s->bus, NULL /* FIXME */);
+ usb_bus_new(&s->bus, &musb_bus_ops, NULL /* FIXME */);
usb_register_port(&s->bus, &s->port, s, 0, &musb_port_ops,
USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
usb_port_location(&s->port, NULL, 1);
musb_session_update(s, 1, s->session);
}
-static inline void musb_cb_tick0(void *opaque)
+static void musb_cb_tick0(void *opaque)
{
MUSBEndPoint *ep = (MUSBEndPoint *) opaque;
ep->delayed_cb[0](&ep->packey[0].p, opaque);
}
-static inline void musb_cb_tick1(void *opaque)
+static void musb_cb_tick1(void *opaque)
{
MUSBEndPoint *ep = (MUSBEndPoint *) opaque;
#define musb_cb_tick (dir ? musb_cb_tick1 : musb_cb_tick0)
-static inline void musb_schedule_cb(USBDevice *dev, USBPacket *packey)
+static void musb_schedule_cb(USBDevice *dev, USBPacket *packey)
{
MUSBPacket *p = container_of(packey, MUSBPacket, p);
MUSBEndPoint *ep = p->ep;
hw_error("bad interval\n");
}
-static inline void musb_packet(MUSBState *s, MUSBEndPoint *ep,
+static void musb_packet(MUSBState *s, MUSBEndPoint *ep,
int epnum, int pid, int len, USBCallback cb, int dir)
{
int ret;
ep->packey[dir].dir = dir;
if (s->port.dev)
- ret = s->port.dev->info->handle_packet(s->port.dev, &ep->packey[dir].p);
+ ret = usb_handle_packet(s->port.dev, &ep->packey[dir].p);
else
ret = USB_RET_NODEV;
musb_rx_intr_set(s, epnum, 1);
}
+static void musb_device_destroy(USBBus *bus, USBDevice *dev)
+{
+ MUSBState *s = container_of(bus, MUSBState, bus);
+ int ep, dir;
+
+ for (ep = 0; ep < 16; ep++) {
+ for (dir = 0; dir < 2; dir++) {
+ if (s->ep[ep].packey[dir].p.owner != dev) {
+ continue;
+ }
+ usb_cancel_packet(&s->ep[ep].packey[dir].p);
+ /* status updates needed here? */
+ }
+ }
+}
+
static void musb_tx_rdy(MUSBState *s, int epnum)
{
MUSBEndPoint *ep = s->ep + epnum;