PERFORCE change 113031 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Tue Jan 16 23:33:11 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=113031
Change 113031 by hselasky at hselasky_mini_itx on 2007/01/16 23:32:59
Implement proper support for high speed isochronous and
interrupt transfer multiplier, bits 11..12 of wMaxPacketSize.
Affected files ...
.. //depot/projects/usb/src/sys/dev/usb/ehci.c#15 edit
.. //depot/projects/usb/src/sys/dev/usb/ohci.c#13 edit
.. //depot/projects/usb/src/sys/dev/usb/ugen.c#10 edit
.. //depot/projects/usb/src/sys/dev/usb/uhci.c#14 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_subr.c#23 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_subr.h#27 edit
Differences ...
==== //depot/projects/usb/src/sys/dev/usb/ehci.c#15 (text+ko) ====
@@ -1672,7 +1672,7 @@
}
qh->qh_endphub = htole32
- (EHCI_QH_SET_MULT(1)|
+ (EHCI_QH_SET_MULT(xfer->max_packet_count & 3)|
EHCI_QH_SET_CMASK(0xf0));
if(xfer->udev->myhsport)
@@ -2519,7 +2519,7 @@
}
/* set transfer multiplier */
- td->itd_bp[2] = htole32(1);
+ td->itd_bp[2] = htole32(xfer->max_packet_count & 3);
}
return;
}
@@ -3545,8 +3545,11 @@
(xfer->pipe->methods == &ehci_device_bulk_methods) ||
(xfer->pipe->methods == &ehci_device_intr_methods))
{
- usbd_std_transfer_setup(xfer, setup, 0x400, 0x400);
-
+ if ((xfer->pipe->methods == &ehci_device_intr_methods) &&
+ (udev->speed == USB_SPEED_HIGH))
+ usbd_std_transfer_setup(xfer, setup, 0x400, 0xC00, 3);
+ else
+ usbd_std_transfer_setup(xfer, setup, 0x400, 0x400, 1);
nqh = 1;
nqtd = (1+ /* SETUP */ 1+ /* STATUS */
1 /* SHORTPKT */) +
@@ -3554,7 +3557,7 @@
}
else if(xfer->pipe->methods == &ehci_device_isoc_fs_methods)
{
- usbd_std_transfer_setup(xfer, setup, 188, 188);
+ usbd_std_transfer_setup(xfer, setup, 188, 188, 1);
if(xfer->nframes == 0)
{
@@ -3578,7 +3581,7 @@
}
else if(xfer->pipe->methods == &ehci_device_isoc_hs_methods)
{
- usbd_std_transfer_setup(xfer, setup, 0x400, 0xC00);
+ usbd_std_transfer_setup(xfer, setup, 0x400, 0xC00, 3);
if(xfer->nframes == 0)
{
@@ -3602,7 +3605,7 @@
}
else
{
- usbd_std_transfer_setup(xfer, setup, 0x400, 0x400);
+ usbd_std_transfer_setup(xfer, setup, 0x400, 0x400, 1);
}
}
==== //depot/projects/usb/src/sys/dev/usb/ohci.c#13 (text+ko) ====
@@ -2614,7 +2614,7 @@
}
else
{
- usbd_std_transfer_setup(xfer, setup, 0x500, 0x500);
+ usbd_std_transfer_setup(xfer, setup, 0x500, 0x500, 1);
/*
* calculate ntd and nqh
==== //depot/projects/usb/src/sys/dev/usb/ugen.c#10 (text+ko) ====
@@ -642,9 +642,9 @@
break;
case UE_ISOCHRONOUS:
- isize = UGETW(ed->wMaxPacketSize);
+ isize = usbd_get_max_frame_size(ed);
- /* wMaxPacketSize is validated
+ /* the maximum frame size is validated
* by "usbd_fill_iface_data()"
*/
@@ -736,14 +736,15 @@
switch(ed->bmAttributes & UE_XFERTYPE)
{
case UE_INTERRUPT:
+ isize = usbd_get_max_frame_size(ed);
usbd_config[0].flags = USBD_SHORT_XFER_OK;
usbd_config[0].callback = ugen_interrupt_callback;
- usbd_config[0].bufsize = UGETW(ed->wMaxPacketSize);
+ usbd_config[0].bufsize = isize;
usbd_config[0].interval = USBD_DEFAULT_INTERVAL;
if(ugen_allocate_blocks
(sc, sce, UGEN_RD_CFG,
- &sce->in_queue, 1, UGETW(ed->wMaxPacketSize)) == 0)
+ &sce->in_queue, 1, isize) == 0)
{
return ENOMEM;
}
@@ -786,9 +787,11 @@
case UE_ISOCHRONOUS:
- isize = UGETW(ed->wMaxPacketSize);
+ isize = usbd_get_max_frame_size(ed);
- /* wMaxPacketSize is validated by "usbd_fill_iface_data()" */
+ /* the maximum frame size is validated
+ * by "usbd_fill_iface_data()"
+ */
if(usbd_get_speed(sc->sc_udev) == USB_SPEED_HIGH)
{
@@ -1385,7 +1388,7 @@
plen1 = xfer->frlengths;
ptr1 = xfer->buffer;
- isize = UGETW(sce->pipe_in->edesc->wMaxPacketSize);
+ isize = usbd_get_max_frame_size(sce->pipe_in->edesc);
n = sce->in_frames;
while(n--)
{
@@ -1423,7 +1426,7 @@
tr_setup:
tr_error:
- isize = UGETW(sce->pipe_in->edesc->wMaxPacketSize);
+ isize = usbd_get_max_frame_size(sce->pipe_in->edesc);
for(n = 0; n < sce->in_frames; n++)
{
/* setup size for next transfer */
@@ -1454,7 +1457,7 @@
plen1 = xfer->frlengths;
ptr1 = xfer->buffer;
- isize = UGETW(sce->pipe_out->edesc->wMaxPacketSize);
+ isize = usbd_get_max_frame_size(sce->pipe_out->edesc);
n = sce->out_frames;
while(n--)
{
@@ -1663,7 +1666,7 @@
case USB_GET_FRAME_SIZE:
if(sce->pipe_in)
{
- *(int *)addr = UGETW(sce->pipe_in->edesc->wMaxPacketSize);
+ *(int *)addr = usbd_get_max_frame_size(sce->pipe_in->edesc);
}
else
{
==== //depot/projects/usb/src/sys/dev/usb/uhci.c#14 (text+ko) ====
@@ -2873,7 +2873,7 @@
}
else
{
- usbd_std_transfer_setup(xfer, setup, 0x500, 0x500);
+ usbd_std_transfer_setup(xfer, setup, 0x500, 0x500, 1);
/*
* compute ntd and nqh
==== //depot/projects/usb/src/sys/dev/usb/usb_subr.c#23 (text+ko) ====
@@ -512,38 +512,27 @@
if(udev->speed == USB_SPEED_HIGH)
{
- u_int16_t mps;
- /* control and bulk endpoints have max packet limits */
+ /* control and bulk endpoints have fixed max packet sizes */
switch (UE_GET_XFERTYPE(ed->bmAttributes)) {
case UE_CONTROL:
- mps = USB_2_MAX_CTRL_PACKET;
- goto check;
+ USETW(ed->wMaxPacketSize, USB_2_MAX_CTRL_PACKET);
+ break;
case UE_BULK:
- mps = USB_2_MAX_BULK_PACKET;
- check:
- if(UGETW(ed->wMaxPacketSize) != mps)
- {
- USETW(ed->wMaxPacketSize, mps);
-#ifdef DIAGNOSTIC
- printf("%s: bad wMaxPacketSize, addr=%d!\n",
- __FUNCTION__, udev->address);
-#endif
- }
- break;
- default:
+ USETW(ed->wMaxPacketSize, USB_2_MAX_BULK_PACKET);
break;
}
}
- if(UGETW(ed->wMaxPacketSize) == 0)
- {
+
+ if (usbd_get_max_frame_size(ed) == 0) {
#ifdef USB_DEBUG
- printf("%s: invalid wMaxPacketSize, addr=%d!\n",
- __FUNCTION__, udev->address);
+ printf("%s: invalid wMaxPacketSize=0x%04x, addr=%d!\n",
+ __FUNCTION__, UGETW(ed->wMaxPacketSize),
+ udev->address);
#endif
- /* avoid division by zero
- * (in EHCI/UHCI/OHCI drivers)
- */
- USETW(ed->wMaxPacketSize, USB_MAX_IPACKET);
+ /* avoid division by zero
+ * (in EHCI/UHCI/OHCI drivers)
+ */
+ usbd_set_max_packet_size_count(ed, USB_MAX_IPACKET, 1);
}
/* find a free pipe */
@@ -1293,20 +1282,13 @@
if(speed == USB_SPEED_HIGH)
{
/* max packet size must be 64 (sec 5.5.3) */
- if(udev->ddesc.bMaxPacketSize != USB_2_MAX_CTRL_PACKET)
- {
-#ifdef DIAGNOSTIC
- printf("%s: addr=%d bad max packet size\n",
- __FUNCTION__, udev->address);
-#endif
- udev->ddesc.bMaxPacketSize = USB_2_MAX_CTRL_PACKET;
- }
+ udev->ddesc.bMaxPacketSize = USB_2_MAX_CTRL_PACKET;
}
if(udev->ddesc.bMaxPacketSize == 0)
{
#ifdef USB_DEBUG
- printf("%s: addr=%d invalid bMaxPacketSize!\n",
+ printf("%s: addr=%d invalid bMaxPacketSize=0x00!\n",
__FUNCTION__, udev->address);
#endif
/* avoid division by zero */
@@ -2212,7 +2194,8 @@
void
usbd_std_transfer_setup(struct usbd_xfer *xfer,
const struct usbd_config *setup,
- u_int16_t max_packet_size, u_int16_t max_frame_size)
+ u_int16_t max_packet_size, u_int16_t max_frame_size,
+ uint8_t max_packet_count)
{
__callout_init_mtx(&xfer->timeout_handle, xfer->usb_mtx,
CALLOUT_RETURNUNLOCKED);
@@ -2223,16 +2206,18 @@
xfer->callback = setup->callback;
xfer->interval = setup->interval;
xfer->endpoint = xfer->pipe->edesc->bEndpointAddress;
- xfer->max_packet_size = UGETW(xfer->pipe->edesc->wMaxPacketSize);
+ xfer->max_packet_size = usbd_get_max_packet_size(xfer->pipe->edesc);
+ xfer->max_packet_count = usbd_get_max_packet_count(xfer->pipe->edesc);
+ xfer->max_frame_size = usbd_get_max_frame_size(xfer->pipe->edesc);
xfer->length = setup->bufsize;
- if(xfer->interval == 0)
- {
+ /* check interrupt interval */
+
+ if (xfer->interval == 0) {
xfer->interval = xfer->pipe->edesc->bInterval;
}
- if(xfer->interval == 0)
- {
+ if (xfer->interval == 0) {
/* one is the smallest interval */
xfer->interval = 1;
}
@@ -2247,18 +2232,27 @@
xfer->max_packet_size = max_packet_size;
}
- /* frame_size: isochronous frames only */
+ /* check the maximum packet count */
+
+ if (xfer->max_packet_count == 0) {
+ xfer->max_packet_count = 1;
+ }
+
+ if (xfer->max_packet_count > max_packet_count) {
+ xfer->max_packet_count = max_packet_count;
+ }
+
+ /* check the maximum frame size */
- xfer->max_frame_size = max_frame_size;
+ if (xfer->max_frame_size > max_frame_size) {
+ xfer->max_frame_size = max_frame_size;
+ }
if (xfer->length == 0) {
- xfer->length = xfer->max_packet_size;
+ xfer->length = xfer->max_frame_size;
if (xfer->nframes) {
xfer->length *= xfer->nframes;
}
- if (setup->sub_frames) {
- xfer->length *= setup->sub_frames;
- }
}
return;
}
@@ -2677,3 +2671,45 @@
}
return error;
}
+
+/*---------------------------------------------------------------------------*
+ * usbd_get_max_packet_size - get maximum packet size
+ *---------------------------------------------------------------------------*/
+uint16_t
+usbd_get_max_packet_size(usb_endpoint_descriptor_t *edesc)
+{
+ return (UGETW(edesc->wMaxPacketSize) & 0x7FF);
+}
+
+/*---------------------------------------------------------------------------*
+ * usbd_get_max_packet_count - get maximum packet count
+ *---------------------------------------------------------------------------*/
+uint16_t
+usbd_get_max_packet_count(usb_endpoint_descriptor_t *edesc)
+{
+ return (1 + ((UGETW(edesc->wMaxPacketSize) >> 11) & 3));
+}
+
+/*---------------------------------------------------------------------------*
+ * usbd_get_max_frame_size - get maximum frame size
+ *---------------------------------------------------------------------------*/
+uint16_t
+usbd_get_max_frame_size(usb_endpoint_descriptor_t *edesc)
+{
+ uint16_t n;
+ n = UGETW(edesc->wMaxPacketSize);
+ return (n & 0x7FF) * (1 + ((n >> 11) & 3));
+}
+
+/*---------------------------------------------------------------------------*
+ * usbd_set_max_packet_size_count - set maximum packet size and count
+ *---------------------------------------------------------------------------*/
+void
+usbd_set_max_packet_size_count(usb_endpoint_descriptor_t *edesc,
+ uint16_t size, uint16_t count)
+{
+ uint16_t n;
+ n = (size & 0x7FF)|(((count-1) & 3) << 11);
+ USETW(edesc->wMaxPacketSize, n);
+ return;
+}
==== //depot/projects/usb/src/sys/dev/usb/usb_subr.h#27 (text+ko) ====
@@ -279,11 +279,6 @@
* used in isochronous
* mode
*/
- u_int8_t sub_frames; /* number of sub-frames
- * contained within each
- * frame. Used in High-Speed
- * isochronous mode.
- */
u_int8_t index; /* pipe index to use, if more
* than one descriptor matches
* type, address, direction ...
@@ -376,6 +371,7 @@
u_int8_t address;
u_int8_t endpoint;
u_int8_t interval; /* milliseconds */
+ uint8_t max_packet_count;
u_int16_t max_packet_size;
u_int16_t max_frame_size;
@@ -702,9 +698,8 @@
#endif
#endif
-void
-usbd_std_transfer_setup(struct usbd_xfer *xfer, const struct usbd_config *setup,
- u_int16_t max_packet_size, u_int16_t max_frame_size);
+void usbd_std_transfer_setup(struct usbd_xfer *xfer, const struct usbd_config *setup, u_int16_t max_packet_size, u_int16_t max_frame_size, uint8_t max_packet_count);
+
u_int8_t
usbd_make_str_desc(void *ptr, u_int16_t max_len, const char *s);
@@ -741,6 +736,12 @@
int32_t device_delete_all_children(device_t dev);
+uint16_t usbd_get_max_packet_size(usb_endpoint_descriptor_t *edesc);
+uint16_t usbd_get_max_packet_count(usb_endpoint_descriptor_t *edesc);
+uint16_t usbd_get_max_frame_size(usb_endpoint_descriptor_t *edesc);
+
+void usbd_set_max_packet_size_count(usb_endpoint_descriptor_t *edesc, uint16_t size, uint16_t count);
+
/* routines from usb.c */
#if 0
More information about the p4-projects
mailing list