|
@@ -154,6 +154,7 @@ static void do_token_setup(USBDevice *s, USBPacket *p)
|
|
index = (s->setup_buf[5] << 8) | s->setup_buf[4];
|
|
index = (s->setup_buf[5] << 8) | s->setup_buf[4];
|
|
|
|
|
|
if (s->setup_buf[0] & USB_DIR_IN) {
|
|
if (s->setup_buf[0] & USB_DIR_IN) {
|
|
|
|
+ usb_pcap_ctrl(p, true);
|
|
usb_device_handle_control(s, p, request, value, index,
|
|
usb_device_handle_control(s, p, request, value, index,
|
|
s->setup_len, s->data_buf);
|
|
s->setup_len, s->data_buf);
|
|
if (p->status == USB_RET_ASYNC) {
|
|
if (p->status == USB_RET_ASYNC) {
|
|
@@ -190,6 +191,7 @@ static void do_token_in(USBDevice *s, USBPacket *p)
|
|
switch(s->setup_state) {
|
|
switch(s->setup_state) {
|
|
case SETUP_STATE_ACK:
|
|
case SETUP_STATE_ACK:
|
|
if (!(s->setup_buf[0] & USB_DIR_IN)) {
|
|
if (!(s->setup_buf[0] & USB_DIR_IN)) {
|
|
|
|
+ usb_pcap_ctrl(p, true);
|
|
usb_device_handle_control(s, p, request, value, index,
|
|
usb_device_handle_control(s, p, request, value, index,
|
|
s->setup_len, s->data_buf);
|
|
s->setup_len, s->data_buf);
|
|
if (p->status == USB_RET_ASYNC) {
|
|
if (p->status == USB_RET_ASYNC) {
|
|
@@ -197,6 +199,7 @@ static void do_token_in(USBDevice *s, USBPacket *p)
|
|
}
|
|
}
|
|
s->setup_state = SETUP_STATE_IDLE;
|
|
s->setup_state = SETUP_STATE_IDLE;
|
|
p->actual_length = 0;
|
|
p->actual_length = 0;
|
|
|
|
+ usb_pcap_ctrl(p, false);
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
|
|
|
|
@@ -215,6 +218,7 @@ static void do_token_in(USBDevice *s, USBPacket *p)
|
|
}
|
|
}
|
|
s->setup_state = SETUP_STATE_IDLE;
|
|
s->setup_state = SETUP_STATE_IDLE;
|
|
p->status = USB_RET_STALL;
|
|
p->status = USB_RET_STALL;
|
|
|
|
+ usb_pcap_ctrl(p, false);
|
|
break;
|
|
break;
|
|
|
|
|
|
default:
|
|
default:
|
|
@@ -230,6 +234,7 @@ static void do_token_out(USBDevice *s, USBPacket *p)
|
|
case SETUP_STATE_ACK:
|
|
case SETUP_STATE_ACK:
|
|
if (s->setup_buf[0] & USB_DIR_IN) {
|
|
if (s->setup_buf[0] & USB_DIR_IN) {
|
|
s->setup_state = SETUP_STATE_IDLE;
|
|
s->setup_state = SETUP_STATE_IDLE;
|
|
|
|
+ usb_pcap_ctrl(p, false);
|
|
/* transfer OK */
|
|
/* transfer OK */
|
|
} else {
|
|
} else {
|
|
/* ignore additional output */
|
|
/* ignore additional output */
|
|
@@ -251,6 +256,7 @@ static void do_token_out(USBDevice *s, USBPacket *p)
|
|
}
|
|
}
|
|
s->setup_state = SETUP_STATE_IDLE;
|
|
s->setup_state = SETUP_STATE_IDLE;
|
|
p->status = USB_RET_STALL;
|
|
p->status = USB_RET_STALL;
|
|
|
|
+ usb_pcap_ctrl(p, false);
|
|
break;
|
|
break;
|
|
|
|
|
|
default:
|
|
default:
|
|
@@ -288,6 +294,7 @@ static void do_parameter(USBDevice *s, USBPacket *p)
|
|
usb_packet_copy(p, s->data_buf, s->setup_len);
|
|
usb_packet_copy(p, s->data_buf, s->setup_len);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ usb_pcap_ctrl(p, true);
|
|
usb_device_handle_control(s, p, request, value, index,
|
|
usb_device_handle_control(s, p, request, value, index,
|
|
s->setup_len, s->data_buf);
|
|
s->setup_len, s->data_buf);
|
|
if (p->status == USB_RET_ASYNC) {
|
|
if (p->status == USB_RET_ASYNC) {
|
|
@@ -301,6 +308,7 @@ static void do_parameter(USBDevice *s, USBPacket *p)
|
|
p->actual_length = 0;
|
|
p->actual_length = 0;
|
|
usb_packet_copy(p, s->data_buf, s->setup_len);
|
|
usb_packet_copy(p, s->data_buf, s->setup_len);
|
|
}
|
|
}
|
|
|
|
+ usb_pcap_ctrl(p, false);
|
|
}
|
|
}
|
|
|
|
|
|
/* ctrl complete function for devices which use usb_generic_handle_packet and
|
|
/* ctrl complete function for devices which use usb_generic_handle_packet and
|
|
@@ -311,6 +319,7 @@ void usb_generic_async_ctrl_complete(USBDevice *s, USBPacket *p)
|
|
{
|
|
{
|
|
if (p->status < 0) {
|
|
if (p->status < 0) {
|
|
s->setup_state = SETUP_STATE_IDLE;
|
|
s->setup_state = SETUP_STATE_IDLE;
|
|
|
|
+ usb_pcap_ctrl(p, false);
|
|
}
|
|
}
|
|
|
|
|
|
switch (s->setup_state) {
|
|
switch (s->setup_state) {
|
|
@@ -325,6 +334,7 @@ void usb_generic_async_ctrl_complete(USBDevice *s, USBPacket *p)
|
|
case SETUP_STATE_ACK:
|
|
case SETUP_STATE_ACK:
|
|
s->setup_state = SETUP_STATE_IDLE;
|
|
s->setup_state = SETUP_STATE_IDLE;
|
|
p->actual_length = 0;
|
|
p->actual_length = 0;
|
|
|
|
+ usb_pcap_ctrl(p, false);
|
|
break;
|
|
break;
|
|
|
|
|
|
case SETUP_STATE_PARAM:
|
|
case SETUP_STATE_PARAM:
|
|
@@ -359,12 +369,14 @@ USBDevice *usb_find_device(USBPort *port, uint8_t addr)
|
|
static void usb_process_one(USBPacket *p)
|
|
static void usb_process_one(USBPacket *p)
|
|
{
|
|
{
|
|
USBDevice *dev = p->ep->dev;
|
|
USBDevice *dev = p->ep->dev;
|
|
|
|
+ bool nak;
|
|
|
|
|
|
/*
|
|
/*
|
|
* Handlers expect status to be initialized to USB_RET_SUCCESS, but it
|
|
* Handlers expect status to be initialized to USB_RET_SUCCESS, but it
|
|
* can be USB_RET_NAK here from a previous usb_process_one() call,
|
|
* can be USB_RET_NAK here from a previous usb_process_one() call,
|
|
* or USB_RET_ASYNC from going through usb_queue_one().
|
|
* or USB_RET_ASYNC from going through usb_queue_one().
|
|
*/
|
|
*/
|
|
|
|
+ nak = (p->status == USB_RET_NAK);
|
|
p->status = USB_RET_SUCCESS;
|
|
p->status = USB_RET_SUCCESS;
|
|
|
|
|
|
if (p->ep->nr == 0) {
|
|
if (p->ep->nr == 0) {
|
|
@@ -388,6 +400,9 @@ static void usb_process_one(USBPacket *p)
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
/* data pipe */
|
|
/* data pipe */
|
|
|
|
+ if (!nak) {
|
|
|
|
+ usb_pcap_data(p, true);
|
|
|
|
+ }
|
|
usb_device_handle_data(dev, p);
|
|
usb_device_handle_data(dev, p);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -439,6 +454,7 @@ void usb_handle_packet(USBDevice *dev, USBPacket *p)
|
|
assert(p->stream || !p->ep->pipeline ||
|
|
assert(p->stream || !p->ep->pipeline ||
|
|
QTAILQ_EMPTY(&p->ep->queue));
|
|
QTAILQ_EMPTY(&p->ep->queue));
|
|
if (p->status != USB_RET_NAK) {
|
|
if (p->status != USB_RET_NAK) {
|
|
|
|
+ usb_pcap_data(p, false);
|
|
usb_packet_set_state(p, USB_PACKET_COMPLETE);
|
|
usb_packet_set_state(p, USB_PACKET_COMPLETE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -458,6 +474,7 @@ void usb_packet_complete_one(USBDevice *dev, USBPacket *p)
|
|
(p->short_not_ok && (p->actual_length < p->iov.size))) {
|
|
(p->short_not_ok && (p->actual_length < p->iov.size))) {
|
|
ep->halted = true;
|
|
ep->halted = true;
|
|
}
|
|
}
|
|
|
|
+ usb_pcap_data(p, false);
|
|
usb_packet_set_state(p, USB_PACKET_COMPLETE);
|
|
usb_packet_set_state(p, USB_PACKET_COMPLETE);
|
|
QTAILQ_REMOVE(&ep->queue, p, queue);
|
|
QTAILQ_REMOVE(&ep->queue, p, queue);
|
|
dev->port->ops->complete(dev->port, p);
|
|
dev->port->ops->complete(dev->port, p);
|