Commit 2328fb17 authored by David Brownell's avatar David Brownell Committed by Greg Kroah-Hartman

[PATCH] USB gadget: dualspeed {run,compile}-time flags

This is the first several autoconfig patches; please merge.
This particular one abstracts dual-speed (high and full)
support.


Support some more autoconfiguration for gadget drivers.

    Run-time:
	* Add gadget->is_dualspeed flag for controllers to set.
	* Tested by "ethernet" gadget, to decide whether certain
	  operations are errors or not.
	* Turned on by net2280.

    Compile-time
	* Generic CONFIG_USB_GADGET_DUALSPEED, not net2280-specific.
	* Used by "ethernet" gadget, to decide whether to
	  include extra code and data for dual-speed support.
	* Turned on by net2280.

The basic idea behind this, and other autoconfig patches yet to come,
is minimizing the controller-specific compile-time configuration
needed by gadget drivers.
parent e2d38bf3
...@@ -52,6 +52,7 @@ choice ...@@ -52,6 +52,7 @@ choice
config USB_GADGET_NET2280 config USB_GADGET_NET2280
boolean "NetChip 2280" boolean "NetChip 2280"
depends on PCI depends on PCI
select USB_GADGET_DUALSPEED
help help
NetChip 2280 is a PCI based USB peripheral controller which NetChip 2280 is a PCI based USB peripheral controller which
supports both full and high speed USB 2.0 data transfers. supports both full and high speed USB 2.0 data transfers.
...@@ -135,6 +136,13 @@ config USB_SA1100 ...@@ -135,6 +136,13 @@ config USB_SA1100
endchoice endchoice
config USB_GADGET_DUALSPEED
bool
depends on USB_GADGET
default n
help
Means that gadget drivers should include extra descriptors
and code to handle dual-speed controllers.
# #
# USB Gadget Drivers # USB Gadget Drivers
......
...@@ -124,7 +124,6 @@ struct eth_dev { ...@@ -124,7 +124,6 @@ struct eth_dev {
* DRIVER_VERSION_NUM ... alerts the host side driver to differences * DRIVER_VERSION_NUM ... alerts the host side driver to differences
* EP_*_NAME ... which endpoints do we use for which purpose? * EP_*_NAME ... which endpoints do we use for which purpose?
* EP_*_NUM ... numbers for them (often limited by hardware) * EP_*_NUM ... numbers for them (often limited by hardware)
* HIGHSPEED ... define if ep0 and descriptors need high speed support
* WAKEUP ... if hardware supports remote wakeup AND we will issue the * WAKEUP ... if hardware supports remote wakeup AND we will issue the
* usb_gadget_wakeup() call to initiate it, USB_CONFIG_ATT_WAKEUP * usb_gadget_wakeup() call to initiate it, USB_CONFIG_ATT_WAKEUP
* *
...@@ -162,7 +161,6 @@ static const char EP_IN_NAME [] = "ep-b"; ...@@ -162,7 +161,6 @@ static const char EP_IN_NAME [] = "ep-b";
#define EP_IN_NUM 2 #define EP_IN_NUM 2
static const char EP_STATUS_NAME [] = "ep-f"; static const char EP_STATUS_NAME [] = "ep-f";
#define EP_STATUS_NUM 3 #define EP_STATUS_NUM 3
#define HIGHSPEED
/* supports remote wakeup, but this driver doesn't */ /* supports remote wakeup, but this driver doesn't */
extern int net2280_set_fifo_mode (struct usb_gadget *gadget, int mode); extern int net2280_set_fifo_mode (struct usb_gadget *gadget, int mode);
...@@ -311,7 +309,7 @@ static const char EP_IN_NAME[] = "ep2in-bulk"; ...@@ -311,7 +309,7 @@ static const char EP_IN_NAME[] = "ep2in-bulk";
#define DEFAULT_QLEN 2 /* double buffering by default */ #define DEFAULT_QLEN 2 /* double buffering by default */
#endif #endif
#ifdef HIGHSPEED #ifdef CONFIG_USB_GADGET_DUALSPEED
static unsigned qmult = 5; static unsigned qmult = 5;
module_param (qmult, uint, S_IRUGO|S_IWUSR); module_param (qmult, uint, S_IRUGO|S_IWUSR);
...@@ -324,7 +322,7 @@ module_param (qmult, uint, S_IRUGO|S_IWUSR); ...@@ -324,7 +322,7 @@ module_param (qmult, uint, S_IRUGO|S_IWUSR);
/* also defer IRQs on highspeed TX */ /* also defer IRQs on highspeed TX */
#define TX_DELAY DEFAULT_QLEN #define TX_DELAY DEFAULT_QLEN
#else /* !HIGHSPEED ... full speed: */ #else /* full speed (low speed doesn't do bulk) */
#define qlen(gadget) DEFAULT_QLEN #define qlen(gadget) DEFAULT_QLEN
#endif #endif
...@@ -626,7 +624,7 @@ static const struct usb_descriptor_header *fs_function [] = { ...@@ -626,7 +624,7 @@ static const struct usb_descriptor_header *fs_function [] = {
0, 0,
}; };
#ifdef HIGHSPEED #ifdef CONFIG_USB_GADGET_DUALSPEED
/* /*
* usb 2.0 devices need to expose both high speed and full speed * usb 2.0 devices need to expose both high speed and full speed
...@@ -707,7 +705,7 @@ static const struct usb_descriptor_header *hs_function [] = { ...@@ -707,7 +705,7 @@ static const struct usb_descriptor_header *hs_function [] = {
/* if there's no high speed support, maxpacket doesn't change. */ /* if there's no high speed support, maxpacket doesn't change. */
#define ep_desc(g,hs,fs) fs #define ep_desc(g,hs,fs) fs
#endif /* !HIGHSPEED */ #endif /* !CONFIG_USB_GADGET_DUALSPEED */
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
...@@ -744,7 +742,7 @@ config_buf (enum usb_device_speed speed, u8 *buf, u8 type, unsigned index) ...@@ -744,7 +742,7 @@ config_buf (enum usb_device_speed speed, u8 *buf, u8 type, unsigned index)
{ {
int len; int len;
const struct usb_descriptor_header **function = fs_function; const struct usb_descriptor_header **function = fs_function;
#ifdef HIGHSPEED #ifdef CONFIG_USB_GADGET_DUALSPEED
int hs = (speed == USB_SPEED_HIGH); int hs = (speed == USB_SPEED_HIGH);
if (type == USB_DT_OTHER_SPEED_CONFIG) if (type == USB_DT_OTHER_SPEED_CONFIG)
...@@ -969,7 +967,7 @@ eth_set_config (struct eth_dev *dev, unsigned number, int gfp_flags) ...@@ -969,7 +967,7 @@ eth_set_config (struct eth_dev *dev, unsigned number, int gfp_flags)
switch (gadget->speed) { switch (gadget->speed) {
case USB_SPEED_FULL: speed = "full"; break; case USB_SPEED_FULL: speed = "full"; break;
#ifdef HIGHSPEED #ifdef CONFIG_USB_GADGET_DUALSPEED
case USB_SPEED_HIGH: speed = "high"; break; case USB_SPEED_HIGH: speed = "high"; break;
#endif #endif
default: speed = "?"; break; default: speed = "?"; break;
...@@ -1140,15 +1138,19 @@ eth_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) ...@@ -1140,15 +1138,19 @@ eth_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
value = min (ctrl->wLength, (u16) sizeof device_desc); value = min (ctrl->wLength, (u16) sizeof device_desc);
memcpy (req->buf, &device_desc, value); memcpy (req->buf, &device_desc, value);
break; break;
#ifdef HIGHSPEED #ifdef CONFIG_USB_GADGET_DUALSPEED
case USB_DT_DEVICE_QUALIFIER: case USB_DT_DEVICE_QUALIFIER:
if (!gadget->is_dualspeed)
break;
value = min (ctrl->wLength, (u16) sizeof dev_qualifier); value = min (ctrl->wLength, (u16) sizeof dev_qualifier);
memcpy (req->buf, &dev_qualifier, value); memcpy (req->buf, &dev_qualifier, value);
break; break;
case USB_DT_OTHER_SPEED_CONFIG: case USB_DT_OTHER_SPEED_CONFIG:
if (!gadget->is_dualspeed)
break;
// FALLTHROUGH // FALLTHROUGH
#endif /* HIGHSPEED */ #endif /* CONFIG_USB_GADGET_DUALSPEED */
case USB_DT_CONFIG: case USB_DT_CONFIG:
value = config_buf (gadget->speed, req->buf, value = config_buf (gadget->speed, req->buf,
ctrl->wValue >> 8, ctrl->wValue >> 8,
...@@ -1652,7 +1654,7 @@ static int eth_start_xmit (struct sk_buff *skb, struct net_device *net) ...@@ -1652,7 +1654,7 @@ static int eth_start_xmit (struct sk_buff *skb, struct net_device *net)
#endif #endif
req->length = length; req->length = length;
#ifdef HIGHSPEED #ifdef CONFIG_USB_GADGET_DUALSPEED
/* throttle highspeed IRQ rate back slightly */ /* throttle highspeed IRQ rate back slightly */
req->no_interrupt = (dev->gadget->speed == USB_SPEED_HIGH) req->no_interrupt = (dev->gadget->speed == USB_SPEED_HIGH)
? ((atomic_read (&dev->tx_qlen) % TX_DELAY) != 0) ? ((atomic_read (&dev->tx_qlen) % TX_DELAY) != 0)
...@@ -1775,7 +1777,7 @@ eth_bind (struct usb_gadget *gadget) ...@@ -1775,7 +1777,7 @@ eth_bind (struct usb_gadget *gadget)
#endif #endif
device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
#ifdef HIGHSPEED #ifdef CONFIG_USB_GADGET_DUALSPEED
/* assumes ep0 uses the same value for both speeds ... */ /* assumes ep0 uses the same value for both speeds ... */
dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0; dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0;
#endif #endif
...@@ -1871,7 +1873,7 @@ eth_bind (struct usb_gadget *gadget) ...@@ -1871,7 +1873,7 @@ eth_bind (struct usb_gadget *gadget)
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
static struct usb_gadget_driver eth_driver = { static struct usb_gadget_driver eth_driver = {
#ifdef HIGHSPEED #ifdef CONFIG_USB_GADGET_DUALSPEED
.speed = USB_SPEED_HIGH, .speed = USB_SPEED_HIGH,
#else #else
.speed = USB_SPEED_FULL, .speed = USB_SPEED_FULL,
......
...@@ -2736,6 +2736,7 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -2736,6 +2736,7 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id)
spin_lock_init (&dev->lock); spin_lock_init (&dev->lock);
dev->pdev = pdev; dev->pdev = pdev;
dev->gadget.ops = &net2280_ops; dev->gadget.ops = &net2280_ops;
dev->gadget.is_dualspeed = 1;
/* the "gadget" abstracts/virtualizes the controller */ /* the "gadget" abstracts/virtualizes the controller */
strcpy (dev->gadget.dev.bus_id, "gadget"); strcpy (dev->gadget.dev.bus_id, "gadget");
......
...@@ -465,6 +465,8 @@ struct usb_gadget_ops { ...@@ -465,6 +465,8 @@ struct usb_gadget_ops {
* driver setup() requests * driver setup() requests
* @ep_list: List of other endpoints supported by the device. * @ep_list: List of other endpoints supported by the device.
* @speed: Speed of current connection to USB host. * @speed: Speed of current connection to USB host.
* @is_dualspeed: True if the controller supports both high and full speed
* operation. If it does, the gadget driver must also support both.
* @name: Identifies the controller hardware type. Used in diagnostics * @name: Identifies the controller hardware type. Used in diagnostics
* and sometimes configuration. * and sometimes configuration.
* @dev: Driver model state for this abstract device. * @dev: Driver model state for this abstract device.
...@@ -488,6 +490,7 @@ struct usb_gadget { ...@@ -488,6 +490,7 @@ struct usb_gadget {
struct usb_ep *ep0; struct usb_ep *ep0;
struct list_head ep_list; /* of usb_ep */ struct list_head ep_list; /* of usb_ep */
enum usb_device_speed speed; enum usb_device_speed speed;
unsigned is_dualspeed:1;
const char *name; const char *name;
struct device dev; struct device dev;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment