mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
MFp4: //depot/projects/usb@155957
Make code more compliant with SuperSpeed USB and Wireless USB. Submitted by: Hans Petter Selasky
This commit is contained in:
parent
1697b02185
commit
0239859bda
6 changed files with 92 additions and 54 deletions
|
|
@ -393,8 +393,14 @@ usb_linux_shutdown(device_t dev)
|
|||
static uint16_t
|
||||
usb_max_isoc_frames(struct usb_device *dev)
|
||||
{
|
||||
return ((usb2_get_speed(dev->bsd_udev) == USB_SPEED_HIGH) ?
|
||||
USB_MAX_HIGH_SPEED_ISOC_FRAMES : USB_MAX_FULL_SPEED_ISOC_FRAMES);
|
||||
; /* indent fix */
|
||||
switch (usb2_get_speed(dev->bsd_udev)) {
|
||||
case USB_SPEED_LOW:
|
||||
case USB_SPEED_FULL:
|
||||
return (USB_MAX_FULL_SPEED_ISOC_FRAMES);
|
||||
default:
|
||||
return (USB_MAX_HIGH_SPEED_ISOC_FRAMES);
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
|
|
|
|||
|
|
@ -75,18 +75,6 @@ static usb2_error_t usb2_fill_iface_data(struct usb2_device *, uint8_t,
|
|||
static void usb2_notify_addq(const char *type, struct usb2_device *);
|
||||
static void usb2_fifo_free_wrap(struct usb2_device *, uint8_t, uint8_t);
|
||||
|
||||
/* static structures */
|
||||
|
||||
static const uint8_t usb2_hub_speed_combs[USB_SPEED_MAX][USB_SPEED_MAX] = {
|
||||
/* HUB *//* subdevice */
|
||||
[USB_SPEED_HIGH][USB_SPEED_HIGH] = 1,
|
||||
[USB_SPEED_HIGH][USB_SPEED_FULL] = 1,
|
||||
[USB_SPEED_HIGH][USB_SPEED_LOW] = 1,
|
||||
[USB_SPEED_FULL][USB_SPEED_FULL] = 1,
|
||||
[USB_SPEED_FULL][USB_SPEED_LOW] = 1,
|
||||
[USB_SPEED_LOW][USB_SPEED_LOW] = 1,
|
||||
};
|
||||
|
||||
/* This variable is global to allow easy access to it: */
|
||||
|
||||
int usb2_template = 0;
|
||||
|
|
@ -1364,21 +1352,10 @@ usb2_alloc_device(device_t parent_dev, struct usb2_bus *bus,
|
|||
udev->speed = speed;
|
||||
udev->flags.usb2_mode = usb2_mode;
|
||||
|
||||
/* check speed combination */
|
||||
/* speed combination should be checked by the parent HUB */
|
||||
|
||||
hub = udev->parent_hub;
|
||||
if (hub) {
|
||||
if (usb2_hub_speed_combs[hub->speed][speed] == 0) {
|
||||
#if USB_DEBUG
|
||||
printf("%s: the selected subdevice and HUB speed "
|
||||
"combination is not supported %d/%d.\n",
|
||||
__FUNCTION__, speed, hub->speed);
|
||||
#endif
|
||||
/* reject this combination */
|
||||
err = USB_ERR_INVAL;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* search for our High Speed USB HUB, if any */
|
||||
|
||||
adev = udev;
|
||||
|
|
|
|||
|
|
@ -157,12 +157,16 @@ ugen_open(struct usb2_fifo *f, int fflags, struct thread *td)
|
|||
DPRINTFN(6, "flag=0x%x\n", fflags);
|
||||
|
||||
mtx_lock(f->priv_mtx);
|
||||
if (usb2_get_speed(f->udev) == USB_SPEED_HIGH) {
|
||||
f->nframes = UGEN_HW_FRAMES * 8;
|
||||
f->bufsize = UGEN_BULK_HS_BUFFER_SIZE;
|
||||
} else {
|
||||
switch (usb2_get_speed(f->udev)) {
|
||||
case USB_SPEED_LOW:
|
||||
case USB_SPEED_FULL:
|
||||
f->nframes = UGEN_HW_FRAMES;
|
||||
f->bufsize = UGEN_BULK_FS_BUFFER_SIZE;
|
||||
break;
|
||||
default:
|
||||
f->nframes = UGEN_HW_FRAMES * 8;
|
||||
f->bufsize = UGEN_BULK_HS_BUFFER_SIZE;
|
||||
break;
|
||||
}
|
||||
|
||||
type = ed->bmAttributes & UE_XFERTYPE;
|
||||
|
|
|
|||
|
|
@ -372,18 +372,38 @@ repeat:
|
|||
/*
|
||||
* Figure out the device speed
|
||||
*/
|
||||
speed =
|
||||
(sc->sc_st.port_status & UPS_HIGH_SPEED) ? USB_SPEED_HIGH :
|
||||
(sc->sc_st.port_status & UPS_LOW_SPEED) ? USB_SPEED_LOW : USB_SPEED_FULL;
|
||||
|
||||
switch (udev->speed) {
|
||||
case USB_SPEED_HIGH:
|
||||
if (sc->sc_st.port_status & UPS_HIGH_SPEED)
|
||||
speed = USB_SPEED_HIGH;
|
||||
else if (sc->sc_st.port_status & UPS_LOW_SPEED)
|
||||
speed = USB_SPEED_LOW;
|
||||
else
|
||||
speed = USB_SPEED_FULL;
|
||||
break;
|
||||
case USB_SPEED_FULL:
|
||||
if (sc->sc_st.port_status & UPS_LOW_SPEED)
|
||||
speed = USB_SPEED_LOW;
|
||||
else
|
||||
speed = USB_SPEED_FULL;
|
||||
break;
|
||||
case USB_SPEED_LOW:
|
||||
speed = USB_SPEED_LOW;
|
||||
break;
|
||||
default:
|
||||
/* same speed like parent */
|
||||
speed = udev->speed;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Figure out the device mode
|
||||
*
|
||||
* NOTE: This part is currently FreeBSD specific.
|
||||
*/
|
||||
usb2_mode =
|
||||
(sc->sc_st.port_status & UPS_PORT_MODE_DEVICE) ?
|
||||
USB_MODE_DEVICE : USB_MODE_HOST;
|
||||
if (sc->sc_st.port_status & UPS_PORT_MODE_DEVICE)
|
||||
usb2_mode = USB_MODE_DEVICE;
|
||||
else
|
||||
usb2_mode = USB_MODE_HOST;
|
||||
|
||||
/* need to create a new child */
|
||||
|
||||
|
|
@ -1049,17 +1069,16 @@ usb2_intr_schedule_adjust(struct usb2_device *udev, int16_t len, uint8_t slot)
|
|||
{
|
||||
struct usb2_bus *bus = udev->bus;
|
||||
struct usb2_hub *hub;
|
||||
uint8_t speed;
|
||||
|
||||
USB_BUS_LOCK_ASSERT(bus, MA_OWNED);
|
||||
|
||||
if (usb2_get_speed(udev) == USB_SPEED_HIGH) {
|
||||
if (slot >= USB_HS_MICRO_FRAMES_MAX) {
|
||||
slot = usb2_intr_find_best_slot(bus->uframe_usage, 0,
|
||||
USB_HS_MICRO_FRAMES_MAX);
|
||||
}
|
||||
bus->uframe_usage[slot] += len;
|
||||
} else {
|
||||
if (usb2_get_speed(udev) == USB_SPEED_LOW) {
|
||||
speed = usb2_get_speed(udev);
|
||||
|
||||
switch (speed) {
|
||||
case USB_SPEED_LOW:
|
||||
case USB_SPEED_FULL:
|
||||
if (speed == USB_SPEED_LOW) {
|
||||
len *= 8;
|
||||
}
|
||||
/*
|
||||
|
|
@ -1076,6 +1095,14 @@ usb2_intr_schedule_adjust(struct usb2_device *udev, int16_t len, uint8_t slot)
|
|||
}
|
||||
hub->uframe_usage[slot] += len;
|
||||
bus->uframe_usage[slot] += len;
|
||||
break;
|
||||
default:
|
||||
if (slot >= USB_HS_MICRO_FRAMES_MAX) {
|
||||
slot = usb2_intr_find_best_slot(bus->uframe_usage, 0,
|
||||
USB_HS_MICRO_FRAMES_MAX);
|
||||
}
|
||||
bus->uframe_usage[slot] += len;
|
||||
break;
|
||||
}
|
||||
return (slot);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ static const struct usb2_std_packet_size
|
|||
[USB_SPEED_FULL] = {.range = {0, 64}},
|
||||
[USB_SPEED_HIGH] = {.range = {0, 1024}},
|
||||
[USB_SPEED_VARIABLE] = {.range = {0, 1024}},
|
||||
[USB_SPEED_SUPER] = {.range = {0, 1024}},
|
||||
},
|
||||
|
||||
[UE_CONTROL] = {
|
||||
|
|
@ -70,6 +71,7 @@ static const struct usb2_std_packet_size
|
|||
[USB_SPEED_FULL] = {.fixed = {8, 16, 32, 64}},
|
||||
[USB_SPEED_HIGH] = {.fixed = {64, 64, 64, 64}},
|
||||
[USB_SPEED_VARIABLE] = {.fixed = {512, 512, 512, 512}},
|
||||
[USB_SPEED_SUPER] = {.fixed = {512, 512, 512, 512}},
|
||||
},
|
||||
|
||||
[UE_BULK] = {
|
||||
|
|
@ -77,6 +79,7 @@ static const struct usb2_std_packet_size
|
|||
[USB_SPEED_FULL] = {.fixed = {8, 16, 32, 64}},
|
||||
[USB_SPEED_HIGH] = {.fixed = {512, 512, 512, 512}},
|
||||
[USB_SPEED_VARIABLE] = {.fixed = {512, 512, 1024, 1536}},
|
||||
[USB_SPEED_SUPER] = {.fixed = {1024, 1024, 1024, 1024}},
|
||||
},
|
||||
|
||||
[UE_ISOCHRONOUS] = {
|
||||
|
|
@ -84,6 +87,7 @@ static const struct usb2_std_packet_size
|
|||
[USB_SPEED_FULL] = {.range = {0, 1023}},
|
||||
[USB_SPEED_HIGH] = {.range = {0, 1024}},
|
||||
[USB_SPEED_VARIABLE] = {.range = {0, 3584}},
|
||||
[USB_SPEED_SUPER] = {.range = {0, 1024}},
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -413,10 +417,14 @@ usb2_transfer_setup_sub(struct usb2_setup_params *parm)
|
|||
*/
|
||||
xfer->timeout = 1000 / 4;
|
||||
}
|
||||
if (parm->speed == USB_SPEED_HIGH) {
|
||||
frame_limit = USB_MAX_HS_ISOC_FRAMES_PER_XFER;
|
||||
} else {
|
||||
switch (parm->speed) {
|
||||
case USB_SPEED_LOW:
|
||||
case USB_SPEED_FULL:
|
||||
frame_limit = USB_MAX_FS_ISOC_FRAMES_PER_XFER;
|
||||
break;
|
||||
default:
|
||||
frame_limit = USB_MAX_HS_ISOC_FRAMES_PER_XFER;
|
||||
break;
|
||||
}
|
||||
|
||||
if (xfer->nframes > frame_limit) {
|
||||
|
|
@ -446,13 +454,29 @@ usb2_transfer_setup_sub(struct usb2_setup_params *parm)
|
|||
|
||||
xfer->interval = edesc->bInterval;
|
||||
|
||||
if (parm->speed == USB_SPEED_HIGH) {
|
||||
xfer->interval /= 8; /* 125us -> 1ms */
|
||||
switch (parm->speed) {
|
||||
case USB_SPEED_SUPER:
|
||||
case USB_SPEED_VARIABLE:
|
||||
/* 125us -> 1ms */
|
||||
if (xfer->interval < 4)
|
||||
xfer->interval = 1;
|
||||
else if (xfer->interval > 16)
|
||||
xfer->interval = (1<<(16-4));
|
||||
else
|
||||
xfer->interval =
|
||||
(1 << (xfer->interval-4));
|
||||
break;
|
||||
case USB_SPEED_HIGH:
|
||||
/* 125us -> 1ms */
|
||||
xfer->interval /= 8;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (xfer->interval == 0) {
|
||||
/*
|
||||
* one millisecond is the smallest
|
||||
* interval
|
||||
* One millisecond is the smallest
|
||||
* interval we support:
|
||||
*/
|
||||
xfer->interval = 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -602,12 +602,12 @@ struct usb2_port_status {
|
|||
#define UPS_SUSPEND 0x0004
|
||||
#define UPS_OVERCURRENT_INDICATOR 0x0008
|
||||
#define UPS_RESET 0x0010
|
||||
#define UPS_PORT_MODE_DEVICE 0x0020 /* currently FreeBSD specific */
|
||||
#define UPS_PORT_POWER 0x0100
|
||||
#define UPS_LOW_SPEED 0x0200
|
||||
#define UPS_HIGH_SPEED 0x0400
|
||||
#define UPS_PORT_TEST 0x0800
|
||||
#define UPS_PORT_INDICATOR 0x1000
|
||||
#define UPS_PORT_MODE_DEVICE 0x8000 /* currently FreeBSD specific */
|
||||
uWord wPortChange;
|
||||
#define UPS_C_CONNECT_STATUS 0x0001
|
||||
#define UPS_C_PORT_ENABLED 0x0002
|
||||
|
|
|
|||
Loading…
Reference in a new issue