summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2013-10-24 07:38:32 +0000
committerhselasky <hselasky@FreeBSD.org>2013-10-24 07:38:32 +0000
commit110ec3f7e38eb87529f8a17b5e5a207378bce219 (patch)
treedde87ec7a20808212dcf43014af42946a6963e7e
parentbe939ca962d3012cea3d32385af7527e0ce5c525 (diff)
downloadFreeBSD-src-110ec3f7e38eb87529f8a17b5e5a207378bce219.zip
FreeBSD-src-110ec3f7e38eb87529f8a17b5e5a207378bce219.tar.gz
MFC r256548:
Correct programming of XXX_MAXP register. This register is 16-bit wide and not 8-bit. Fix support for isochronous transfers in USB host mode. Fix a whitespace while at it. PR: usb/181987 Approved by: re (Xin Li)
-rw-r--r--sys/dev/usb/controller/musb_otg.c53
-rw-r--r--sys/dev/usb/controller/musb_otg.h2
2 files changed, 38 insertions, 17 deletions
diff --git a/sys/dev/usb/controller/musb_otg.c b/sys/dev/usb/controller/musb_otg.c
index 9b2974f..6944a59 100644
--- a/sys/dev/usb/controller/musb_otg.c
+++ b/sys/dev/usb/controller/musb_otg.c
@@ -1661,7 +1661,7 @@ repeat:
}
/* Max packet size */
- MUSB2_WRITE_1(sc, MUSB2_REG_TXMAXP, td->max_packet);
+ MUSB2_WRITE_2(sc, MUSB2_REG_TXMAXP, td->reg_max_packet);
/* write command */
MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
@@ -1726,13 +1726,16 @@ repeat:
td->hport);
/* RX NAK timeout */
- MUSB2_WRITE_1(sc, MUSB2_REG_RXNAKLIMIT, MAX_NAK_TO);
+ if (td->transfer_type & MUSB2_MASK_TI_PROTO_ISOC)
+ MUSB2_WRITE_1(sc, MUSB2_REG_RXNAKLIMIT, 0);
+ else
+ MUSB2_WRITE_1(sc, MUSB2_REG_RXNAKLIMIT, MAX_NAK_TO);
/* Protocol, speed, device endpoint */
MUSB2_WRITE_1(sc, MUSB2_REG_RXTI, td->transfer_type);
/* Max packet size */
- MUSB2_WRITE_1(sc, MUSB2_REG_RXMAXP, td->max_packet);
+ MUSB2_WRITE_2(sc, MUSB2_REG_RXMAXP, td->reg_max_packet);
/* Data Toggle */
csrh = MUSB2_READ_1(sc, MUSB2_REG_RXCSRH);
@@ -1938,7 +1941,7 @@ musbotg_host_data_tx(struct musbotg_td *td)
return (0); /* complete */
}
- if (csr & MUSB2_MASK_CSRL_TXNAKTO ) {
+ if (csr & MUSB2_MASK_CSRL_TXNAKTO) {
/*
* Flush TX FIFO before clearing NAK TO
*/
@@ -2069,13 +2072,16 @@ musbotg_host_data_tx(struct musbotg_td *td)
td->hport);
/* TX NAK timeout */
- MUSB2_WRITE_1(sc, MUSB2_REG_TXNAKLIMIT, MAX_NAK_TO);
+ if (td->transfer_type & MUSB2_MASK_TI_PROTO_ISOC)
+ MUSB2_WRITE_1(sc, MUSB2_REG_TXNAKLIMIT, 0);
+ else
+ MUSB2_WRITE_1(sc, MUSB2_REG_TXNAKLIMIT, MAX_NAK_TO);
/* Protocol, speed, device endpoint */
MUSB2_WRITE_1(sc, MUSB2_REG_TXTI, td->transfer_type);
/* Max packet size */
- MUSB2_WRITE_1(sc, MUSB2_REG_TXMAXP, td->max_packet);
+ MUSB2_WRITE_2(sc, MUSB2_REG_TXMAXP, td->reg_max_packet);
if (!td->transaction_started) {
csrh = MUSB2_READ_1(sc, MUSB2_REG_TXCSRH);
@@ -2406,7 +2412,6 @@ musbotg_setup_standard_chain(struct usb_xfer *xfer)
if (xfer->flags_int.usb_mode == USB_MODE_HOST) {
speed = usbd_get_speed(xfer->xroot->udev);
- xfer_type = xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE;
switch (speed) {
case USB_SPEED_LOW:
@@ -2444,7 +2449,6 @@ musbotg_setup_standard_chain(struct usb_xfer *xfer)
}
temp.transfer_type |= ep_no;
- td->max_packet = xfer->max_packet_size;
td->toggle = xfer->endpoint->toggle_next;
}
@@ -2469,9 +2473,9 @@ musbotg_setup_standard_chain(struct usb_xfer *xfer)
x = 0;
}
- if (x != xfer->nframes) {
- tx = 0;
+ tx = 0;
+ if (x != xfer->nframes) {
if (xfer->endpointno & UE_DIR_IN)
tx = 1;
@@ -2532,9 +2536,14 @@ musbotg_setup_standard_chain(struct usb_xfer *xfer)
} else {
- /* regular data transfer */
-
- temp.short_pkt = (xfer->flags.force_short_xfer) ? 0 : 1;
+ if (xfer->flags_int.isochronous_xfr) {
+ /* isochronous data transfer */
+ /* don't force short */
+ temp.short_pkt = 1;
+ } else {
+ /* regular data transfer */
+ temp.short_pkt = (xfer->flags.force_short_xfer ? 0 : 1);
+ }
}
musbotg_setup_standard_chain_sub(&temp);
@@ -3158,7 +3167,12 @@ musbotg_init(struct musbotg_softc *sc)
if (dynfifo) {
if (frx && (temp <= nrx)) {
- if (temp < 8) {
+ if (temp == 1) {
+ frx = 12; /* 4K */
+ MUSB2_WRITE_1(sc, MUSB2_REG_RXFIFOSZ,
+ MUSB2_VAL_FIFOSZ_4096 |
+ MUSB2_MASK_FIFODB);
+ } else if (temp < 8) {
frx = 10; /* 1K */
MUSB2_WRITE_1(sc, MUSB2_REG_RXFIFOSZ,
MUSB2_VAL_FIFOSZ_512 |
@@ -3175,7 +3189,12 @@ musbotg_init(struct musbotg_softc *sc)
offset += (1 << frx);
}
if (ftx && (temp <= ntx)) {
- if (temp < 8) {
+ if (temp == 1) {
+ ftx = 12; /* 4K */
+ MUSB2_WRITE_1(sc, MUSB2_REG_TXFIFOSZ,
+ MUSB2_VAL_FIFOSZ_4096 |
+ MUSB2_MASK_FIFODB);
+ } else if (temp < 8) {
ftx = 10; /* 1K */
MUSB2_WRITE_1(sc, MUSB2_REG_TXFIFOSZ,
MUSB2_VAL_FIFOSZ_512 |
@@ -4042,7 +4061,7 @@ musbotg_xfer_setup(struct usb_setup_params *parm)
* reasonable dummies:
*/
parm->hc_max_packet_size = 0x400;
- parm->hc_max_frame_size = 0x400;
+ parm->hc_max_frame_size = 0xc00;
if ((parm->methods == &musbotg_device_isoc_methods) ||
(parm->methods == &musbotg_device_intr_methods))
@@ -4117,6 +4136,8 @@ musbotg_xfer_setup(struct usb_setup_params *parm)
/* init TD */
td->max_frame_size = xfer->max_frame_size;
+ td->reg_max_packet = xfer->max_packet_size |
+ ((xfer->max_packet_count - 1) << 11);
td->ep_no = ep_no;
td->obj_next = last_obj;
diff --git a/sys/dev/usb/controller/musb_otg.h b/sys/dev/usb/controller/musb_otg.h
index 649cab8..f8f3470 100644
--- a/sys/dev/usb/controller/musb_otg.h
+++ b/sys/dev/usb/controller/musb_otg.h
@@ -316,9 +316,9 @@ struct musbotg_td {
uint32_t offset;
uint32_t remainder;
uint16_t max_frame_size; /* packet_size * mult */
+ uint16_t reg_max_packet;
uint8_t ep_no;
uint8_t transfer_type;
- uint8_t max_packet;
uint8_t error:1;
uint8_t alt_next:1;
uint8_t short_pkt:1;
OpenPOWER on IntegriCloud