PERFORCE change 182111 for review
Hans Petter Selasky
hselasky at skunkworks.freebsd.org
Wed Aug 11 18:25:54 UTC 2010
http://p4web.freebsd.org/@@182111?ac=10
Change 182111 by hselasky at hselasky_laptop001 on 2010/08/08 22:08:28
USB controller (XHCI):
- more bugfixes.
- take into account that SuperSpeed devices can
burst upto 1024 * 32 bytes. Increase TD size.
- fix wrong endpoint direction.
- at this point a SuperSpeed hardisk is enumerating
and is usable.
Affected files ...
.. //depot/projects/usb/src/sys/dev/usb/controller/xhci.c#21 edit
.. //depot/projects/usb/src/sys/dev/usb/controller/xhci.h#19 edit
Differences ...
==== //depot/projects/usb/src/sys/dev/usb/controller/xhci.c#21 (text+ko) ====
@@ -122,7 +122,7 @@
static struct xhci_endpoint_ext *xhci_get_endpoint_ext(struct usb_device *, struct usb_endpoint_descriptor *);
static usb_proc_callback_t xhci_configure_msg;
static usb_error_t xhci_configure_device(struct usb_device *);
-static usb_error_t xhci_configure_endpoint(struct usb_device *, struct usb_endpoint_descriptor *, uint64_t, uint16_t, uint8_t, uint16_t, uint16_t);
+static usb_error_t xhci_configure_endpoint(struct usb_device *, struct usb_endpoint_descriptor *, uint64_t, uint16_t, uint8_t, uint8_t, uint16_t, uint16_t);
static usb_error_t xhci_configure_mask(struct usb_device *, uint32_t, uint8_t);
static usb_error_t xhci_cmd_evaluate_ctx(struct xhci_softc *, uint64_t, uint8_t);
static usb_error_t xhci_cmd_reset_dev(struct xhci_softc *, uint8_t);
@@ -1124,7 +1124,7 @@
&udev->ctrl_ep_desc);
err = xhci_configure_endpoint(udev,
&udev->ctrl_ep_desc, pepext->physaddr,
- 0, 1, mps, mps);
+ 0, 1, 1, mps, mps);
if (err != 0) {
DPRINTF("Could not configure default endpoint\n");
@@ -1910,7 +1910,7 @@
static usb_error_t
xhci_configure_endpoint(struct usb_device *udev,
struct usb_endpoint_descriptor *edesc, uint64_t ring_addr,
- uint16_t interval, uint8_t max_packet_count,
+ uint16_t interval, uint8_t max_packet_count, uint8_t mult,
uint16_t max_packet_size, uint16_t max_frame_size)
{
struct usb_page_search buf_inp;
@@ -1940,7 +1940,12 @@
if (max_packet_count == 0)
return (USB_ERR_BAD_BUFSIZE);
- max_packet_count --;
+ max_packet_count--;
+
+ if (mult == 0)
+ return (USB_ERR_BAD_BUFSIZE);
+
+ mult--;
temp = XHCI_EPCTX_0_EPSTATE_SET(0) |
XHCI_EPCTX_0_MAXP_STREAMS_SET(0) |
@@ -1952,8 +1957,10 @@
temp |= XHCI_EPCTX_0_IVAL_SET(k);
break;
case UE_ISOCHRONOUS:
- if (udev->speed == USB_SPEED_SUPER)
- temp |= XHCI_EPCTX_0_MULT_SET(max_packet_count);
+ if (udev->speed == USB_SPEED_SUPER) {
+ temp |= XHCI_EPCTX_0_MULT_SET(mult);
+ max_packet_count /= mult;
+ }
break;
default:
break;
@@ -1966,8 +1973,10 @@
XHCI_EPCTX_1_MAXB_SET(max_packet_count) |
XHCI_EPCTX_1_MAXP_SIZE_SET(max_packet_size);
- if ((udev->parent_hs_hub != NULL) || (udev->address != 0))
- temp |= XHCI_EPCTX_1_CERR_SET(3);
+ if ((udev->parent_hs_hub != NULL) || (udev->address != 0)) {
+ if ((edesc->bmAttributes & UE_XFERTYPE) != UE_ISOCHRONOUS)
+ temp |= XHCI_EPCTX_1_CERR_SET(3);
+ }
switch (edesc->bmAttributes & UE_XFERTYPE) {
case UE_CONTROL:
@@ -1984,7 +1993,7 @@
break;
}
- if (edesc->bmAttributes & UE_DIR_IN)
+ if (edesc->bEndpointAddress & UE_DIR_IN)
temp |= XHCI_EPCTX_1_EPTYPE_SET(4);
pinp->ctx_ep[epno - 1].dwEpCtx1 = htole32(temp);
@@ -1993,8 +2002,21 @@
pinp->ctx_ep[epno - 1].qwEpCtx2 = htole64(ring_addr);
- temp = XHCI_EPCTX_4_AVG_TRB_LEN_SET(max_frame_size) |
- XHCI_EPCTX_4_MAX_ESIT_PAYLOAD_SET(max_frame_size);
+ temp = 0;
+
+ switch (edesc->bmAttributes & UE_XFERTYPE) {
+ case UE_INTERRUPT:
+ case UE_ISOCHRONOUS:
+ temp |= XHCI_EPCTX_4_MAX_ESIT_PAYLOAD_SET(max_frame_size);
+ temp |= XHCI_EPCTX_4_AVG_TRB_LEN_SET(XHCI_TD_PAYLOAD_MAX);
+ break;
+ case UE_CONTROL:
+ temp |= XHCI_EPCTX_4_AVG_TRB_LEN_SET(8);
+ break;
+ default:
+ temp |= XHCI_EPCTX_4_AVG_TRB_LEN_SET(XHCI_TD_PAYLOAD_MAX);
+ break;
+ }
pinp->ctx_ep[epno - 1].dwEpCtx4 = htole32(temp);
@@ -2010,16 +2032,20 @@
xhci_configure_endpoint_by_xfer(struct usb_xfer *xfer)
{
struct xhci_endpoint_ext *pepext;
+ struct usb_endpoint_ss_comp_descriptor *ecomp;
pepext = xhci_get_endpoint_ext(xfer->xroot->udev,
xfer->endpoint->edesc);
+ ecomp = xfer->endpoint->ecomp;
+
pepext->trb[0].dwTrb3 = 0; /* halt any transfers */
usb_pc_cpu_flush(pepext->page_cache);
return (xhci_configure_endpoint(xfer->xroot->udev,
xfer->endpoint->edesc, pepext->physaddr,
xfer->interval, xfer->max_packet_count,
+ (ecomp != NULL) ? (ecomp->bmAttributes & 3) + 1 : 1,
xfer->max_packet_size, xfer->max_frame_size));
}
@@ -2122,12 +2148,19 @@
temp |= XHCI_SCTX_1_NUM_PORTS_SET(udev->hub->nports);
switch (udev->speed) {
- case USB_SPEED_LOW:
- case USB_SPEED_HIGH:
- case USB_SPEED_FULL:
+ case USB_SPEED_SUPER:
+ switch (sc->sc_hw.devs[index].state) {
+ case XHCI_ST_ADDRESSED:
+ case XHCI_ST_CONFIGURED:
+ /* enable power save */
+ temp |= XHCI_SCTX_1_MAX_EL_SET(sc->sc_exit_lat_max);
+ break;
+ default:
+ /* disable power save */
+ break;
+ }
break;
default:
- temp |= XHCI_SCTX_1_MAX_EL_SET(sc->sc_exit_lat_max);
break;
}
@@ -3116,7 +3149,7 @@
* maximum data payload.
*/
parm->hc_max_packet_size = 0x400;
- parm->hc_max_packet_count = 15;
+ parm->hc_max_packet_count = 16 * 3;
parm->hc_max_frame_size = XHCI_TD_PAYLOAD_MAX;
xfer->flags_int.bdma_enable = 1;
==== //depot/projects/usb/src/sys/dev/usb/controller/xhci.h#19 (text+ko) ====
@@ -46,7 +46,6 @@
#define XHCI_SCRATCH_BUF_ARRAY_ALIGN 64 /* bytes */
#define XHCI_SCRATCH_BUFFER_ALIGN USB_PAGE_SIZE
#define XHCI_TRB_ALIGN 16 /* bytes */
-#define XHCI_QH_ALIGN 16 /* bytes */
#define XHCI_TD_ALIGN 64 /* bytes */
#define XHCI_PAGE_SIZE 4096 /* bytes */
@@ -304,7 +303,7 @@
struct xhci_trb trb[XHCI_MAX_ENDPOINTS][XHCI_MAX_TRANSFERS];
};
-#define XHCI_TD_PAGE_NBUF 5 /* units */
+#define XHCI_TD_PAGE_NBUF 13 /* units */
#define XHCI_TD_PAGE_SIZE 4096 /* bytes */
#define XHCI_TD_PAYLOAD_MAX (XHCI_TD_PAGE_SIZE * (XHCI_TD_PAGE_NBUF - 1))
More information about the p4-projects
mailing list