summaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r--drivers/usb/gadget/ether.c90
-rw-r--r--drivers/usb/gadget/file_storage.c2
-rw-r--r--drivers/usb/gadget/goku_udc.c11
-rw-r--r--drivers/usb/gadget/inode.c68
-rw-r--r--drivers/usb/gadget/net2280.c31
-rw-r--r--drivers/usb/gadget/pxa2xx_udc.c13
-rw-r--r--drivers/usb/gadget/rndis.c389
-rw-r--r--drivers/usb/gadget/rndis.h26
-rw-r--r--drivers/usb/gadget/serial.c105
9 files changed, 345 insertions, 390 deletions
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 9c4422ac9de4..078daa026718 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -49,7 +49,7 @@
#include <asm/unaligned.h>
#include <linux/usb_ch9.h>
-#include <linux/usb_cdc.h>
+#include <linux/usb/cdc.h>
#include <linux/usb_gadget.h>
#include <linux/random.h>
@@ -101,9 +101,9 @@ static const char driver_desc [] = DRIVER_DESC;
/* CDC and RNDIS support the same host-chosen outgoing packet filters. */
#define DEFAULT_FILTER (USB_CDC_PACKET_TYPE_BROADCAST \
- |USB_CDC_PACKET_TYPE_ALL_MULTICAST \
- |USB_CDC_PACKET_TYPE_PROMISCUOUS \
- |USB_CDC_PACKET_TYPE_DIRECTED)
+ |USB_CDC_PACKET_TYPE_ALL_MULTICAST \
+ |USB_CDC_PACKET_TYPE_PROMISCUOUS \
+ |USB_CDC_PACKET_TYPE_DIRECTED)
/*-------------------------------------------------------------------------*/
@@ -318,7 +318,7 @@ static inline int rndis_active(struct eth_dev *dev)
#define DEFAULT_QLEN 2 /* double buffering by default */
/* peak bulk transfer bits-per-second */
-#define HS_BPS (13 * 512 * 8 * 1000 * 8)
+#define HS_BPS (13 * 512 * 8 * 1000 * 8)
#define FS_BPS (19 * 64 * 1 * 1000 * 8)
#ifdef CONFIG_USB_GADGET_DUALSPEED
@@ -466,7 +466,7 @@ eth_config = {
};
#ifdef CONFIG_USB_ETH_RNDIS
-static struct usb_config_descriptor
+static struct usb_config_descriptor
rndis_config = {
.bLength = sizeof rndis_config,
.bDescriptorType = USB_DT_CONFIG,
@@ -511,7 +511,7 @@ static const struct usb_interface_descriptor
rndis_control_intf = {
.bLength = sizeof rndis_control_intf,
.bDescriptorType = USB_DT_INTERFACE,
-
+
.bInterfaceNumber = 0,
.bNumEndpoints = 1,
.bInterfaceClass = USB_CLASS_COMM,
@@ -545,20 +545,20 @@ static const struct usb_cdc_union_desc union_desc = {
#ifdef CONFIG_USB_ETH_RNDIS
static const struct usb_cdc_call_mgmt_descriptor call_mgmt_descriptor = {
- .bLength = sizeof call_mgmt_descriptor,
- .bDescriptorType = USB_DT_CS_INTERFACE,
- .bDescriptorSubType = USB_CDC_CALL_MANAGEMENT_TYPE,
+ .bLength = sizeof call_mgmt_descriptor,
+ .bDescriptorType = USB_DT_CS_INTERFACE,
+ .bDescriptorSubType = USB_CDC_CALL_MANAGEMENT_TYPE,
- .bmCapabilities = 0x00,
- .bDataInterface = 0x01,
+ .bmCapabilities = 0x00,
+ .bDataInterface = 0x01,
};
static const struct usb_cdc_acm_descriptor acm_descriptor = {
- .bLength = sizeof acm_descriptor,
- .bDescriptorType = USB_DT_CS_INTERFACE,
- .bDescriptorSubType = USB_CDC_ACM_TYPE,
+ .bLength = sizeof acm_descriptor,
+ .bDescriptorType = USB_DT_CS_INTERFACE,
+ .bDescriptorSubType = USB_CDC_ACM_TYPE,
- .bmCapabilities = 0x00,
+ .bmCapabilities = 0x00,
};
#endif
@@ -595,7 +595,7 @@ static const struct usb_cdc_ether_desc ether_desc = {
* RNDIS requires the status endpoint, since it uses that encapsulation
* mechanism for its funky RPC scheme.
*/
-
+
#define LOG2_STATUS_INTERVAL_MSEC 5 /* 1 << 5 == 32 msec */
#define STATUS_BYTECOUNT 16 /* 8 byte header + data */
@@ -978,7 +978,7 @@ set_ether_config (struct eth_dev *dev, gfp_t gfp_flags)
result = usb_ep_enable (dev->status_ep, dev->status);
if (result != 0) {
- DEBUG (dev, "enable %s --> %d\n",
+ DEBUG (dev, "enable %s --> %d\n",
dev->status_ep->name, result);
goto done;
}
@@ -1002,15 +1002,15 @@ set_ether_config (struct eth_dev *dev, gfp_t gfp_flags)
if (!cdc_active(dev)) {
result = usb_ep_enable (dev->in_ep, dev->in);
if (result != 0) {
- DEBUG(dev, "enable %s --> %d\n",
+ DEBUG(dev, "enable %s --> %d\n",
dev->in_ep->name, result);
goto done;
}
result = usb_ep_enable (dev->out_ep, dev->out);
if (result != 0) {
- DEBUG (dev, "enable %s --> %d\n",
- dev->in_ep->name, result);
+ DEBUG (dev, "enable %s --> %d\n",
+ dev->out_ep->name, result);
goto done;
}
}
@@ -1144,7 +1144,7 @@ eth_set_config (struct eth_dev *dev, unsigned number, gfp_t gfp_flags)
#ifdef CONFIG_USB_GADGET_DUALSPEED
case USB_SPEED_HIGH: speed = "high"; break;
#endif
- default: speed = "?"; break;
+ default: speed = "?"; break;
}
dev->config = number;
@@ -1206,7 +1206,7 @@ static void issue_start_status (struct eth_dev *dev)
struct usb_request *req = dev->stat_req;
struct usb_cdc_notification *event;
int value;
-
+
DEBUG (dev, "%s, flush old status first\n", __FUNCTION__);
/* flush old status
@@ -1268,7 +1268,7 @@ static void rndis_command_complete (struct usb_ep *ep, struct usb_request *req)
{
struct eth_dev *dev = ep->driver_data;
int status;
-
+
/* received RNDIS command from USB_CDC_SEND_ENCAPSULATED_COMMAND */
spin_lock(&dev->lock);
status = rndis_msg_parser (dev->rndis_config, (u8 *) req->buf);
@@ -1472,7 +1472,7 @@ done_set_intf:
#endif /* DEV_CONFIG_CDC */
-#ifdef CONFIG_USB_ETH_RNDIS
+#ifdef CONFIG_USB_ETH_RNDIS
/* RNDIS uses the CDC command encapsulation mechanism to implement
* an RPC scheme, with much getting/setting of attributes by OID.
*/
@@ -1489,7 +1489,7 @@ done_set_intf:
req->complete = rndis_command_complete;
/* later, rndis_control_ack () sends a notification */
break;
-
+
case USB_CDC_GET_ENCAPSULATED_RESPONSE:
if ((USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE)
== ctrl->bRequestType
@@ -1641,7 +1641,7 @@ rx_submit (struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags)
DEBUG (dev, "no rx skb\n");
goto enomem;
}
-
+
/* Some platforms perform better when IP packets are aligned,
* but on at least one, checksumming fails otherwise. Note:
* RNDIS headers involve variable numbers of LE32 values.
@@ -1720,7 +1720,7 @@ quiesce:
case -EOVERFLOW:
dev->stats.rx_over_errors++;
// FALLTHROUGH
-
+
default:
dev->stats.rx_errors++;
DEBUG (dev, "rx status %d\n", status);
@@ -1915,7 +1915,7 @@ static int eth_start_xmit (struct sk_buff *skb, struct net_device *net)
sizeof (struct rndis_packet_msg_type));
if (!skb_rndis)
goto drop;
-
+
dev_kfree_skb_any (skb);
skb = skb_rndis;
rndis_add_hdr (skb);
@@ -2001,7 +2001,7 @@ static int rndis_control_ack (struct net_device *net)
struct eth_dev *dev = netdev_priv(net);
u32 length;
struct usb_request *resp = dev->stat_req;
-
+
/* in case RNDIS calls this after disconnect */
if (!dev->status) {
DEBUG (dev, "status ENODEV\n");
@@ -2021,16 +2021,16 @@ static int rndis_control_ack (struct net_device *net)
resp->length = 8;
resp->complete = rndis_control_ack_complete;
resp->context = dev;
-
+
*((__le32 *) resp->buf) = __constant_cpu_to_le32 (1);
*((__le32 *) resp->buf + 1) = __constant_cpu_to_le32 (0);
-
+
length = usb_ep_queue (dev->status_ep, resp, GFP_ATOMIC);
if (length < 0) {
resp->status = 0;
rndis_control_ack_complete (dev->status_ep, resp);
}
-
+
return 0;
}
@@ -2047,7 +2047,7 @@ static void eth_start (struct eth_dev *dev, gfp_t gfp_flags)
/* fill the rx queue */
rx_fill (dev, gfp_flags);
- /* and open the tx floodgates */
+ /* and open the tx floodgates */
atomic_set (&dev->tx_qlen, 0);
netif_wake_queue (dev->net);
if (rndis_active(dev)) {
@@ -2076,7 +2076,7 @@ static int eth_stop (struct net_device *net)
netif_stop_queue (net);
DEBUG (dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld\n",
- dev->stats.rx_packets, dev->stats.tx_packets,
+ dev->stats.rx_packets, dev->stats.tx_packets,
dev->stats.rx_errors, dev->stats.tx_errors
);
@@ -2095,7 +2095,7 @@ static int eth_stop (struct net_device *net)
usb_ep_enable (dev->status_ep, dev->status);
}
}
-
+
if (rndis_active(dev)) {
rndis_set_param_medium (dev->rndis_config,
NDIS_MEDIUM_802_3, 0);
@@ -2301,7 +2301,7 @@ autoconf_fail:
return -ENODEV;
}
in_ep->driver_data = in_ep; /* claim */
-
+
out_ep = usb_ep_autoconfig (gadget, &fs_sink_desc);
if (!out_ep)
goto autoconf_fail;
@@ -2374,8 +2374,8 @@ autoconf_fail:
#endif
}
- net = alloc_etherdev (sizeof *dev);
- if (!net)
+ net = alloc_etherdev (sizeof *dev);
+ if (!net)
return status;
dev = netdev_priv(net);
spin_lock_init (&dev->lock);
@@ -2454,7 +2454,7 @@ autoconf_fail:
dev->gadget = gadget;
set_gadget_data (gadget, dev);
gadget->ep0->driver_data = dev;
-
+
/* two kinds of host-initiated state changes:
* - iff DATA transfer is active, carrier is "on"
* - tx queueing enabled if open *and* carrier is "on"
@@ -2462,8 +2462,8 @@ autoconf_fail:
netif_stop_queue (dev->net);
netif_carrier_off (dev->net);
- SET_NETDEV_DEV (dev->net, &gadget->dev);
- status = register_netdev (dev->net);
+ SET_NETDEV_DEV (dev->net, &gadget->dev);
+ status = register_netdev (dev->net);
if (status < 0)
goto fail1;
@@ -2488,7 +2488,7 @@ autoconf_fail:
u32 vendorID = 0;
/* FIXME RNDIS vendor id == "vendor NIC code" == ? */
-
+
dev->rndis_config = rndis_register (rndis_control_ack);
if (dev->rndis_config < 0) {
fail0:
@@ -2496,7 +2496,7 @@ fail0:
status = -ENODEV;
goto fail;
}
-
+
/* these set up a lot of the OIDs that RNDIS needs */
rndis_set_host_mac (dev->rndis_config, dev->host_mac);
if (rndis_set_param_dev (dev->rndis_config, dev->net,
@@ -2556,7 +2556,7 @@ static struct usb_gadget_driver eth_driver = {
.suspend = eth_suspend,
.resume = eth_resume,
- .driver = {
+ .driver = {
.name = (char *) shortname,
.owner = THIS_MODULE,
},
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index 6f887478b148..a43dc908ac59 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -1906,7 +1906,6 @@ static int fsync_sub(struct lun *curlun)
inode = filp->f_dentry->d_inode;
mutex_lock(&inode->i_mutex);
- current->flags |= PF_SYNCWRITE;
rc = filemap_fdatawrite(inode->i_mapping);
err = filp->f_op->fsync(filp, filp->f_dentry, 1);
if (!rc)
@@ -1914,7 +1913,6 @@ static int fsync_sub(struct lun *curlun)
err = filemap_fdatawait(inode->i_mapping);
if (!rc)
rc = err;
- current->flags &= ~PF_SYNCWRITE;
mutex_unlock(&inode->i_mutex);
VLDBG(curlun, "fdatasync -> %d\n", rc);
return rc;
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c
index 66b81bbf6bee..5378c1757292 100644
--- a/drivers/usb/gadget/goku_udc.c
+++ b/drivers/usb/gadget/goku_udc.c
@@ -1850,7 +1850,6 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id)
unsigned long resource, len;
void __iomem *base = NULL;
int retval;
- char buf [8], *bufp;
/* if you want to support more than one controller in a system,
* usb_gadget_driver_{register,unregister}() must change.
@@ -1913,20 +1912,14 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id)
pci_set_drvdata(pdev, dev);
INFO(dev, "%s\n", driver_desc);
INFO(dev, "version: " DRIVER_VERSION " %s\n", dmastr());
-#ifndef __sparc__
- scnprintf(buf, sizeof buf, "%d", pdev->irq);
- bufp = buf;
-#else
- bufp = __irq_itoa(pdev->irq);
-#endif
- INFO(dev, "irq %s, pci mem %p\n", bufp, base);
+ INFO(dev, "irq %d, pci mem %p\n", pdev->irq, base);
/* init to known state, then setup irqs */
udc_reset(dev);
udc_reinit (dev);
if (request_irq(pdev->irq, goku_irq, SA_SHIRQ/*|SA_SAMPLE_RANDOM*/,
driver_name, dev) != 0) {
- DBG(dev, "request interrupt %s failed\n", bufp);
+ DBG(dev, "request interrupt %d failed\n", pdev->irq);
retval = -EBUSY;
goto done;
}
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index 0eb010a3f5bc..3bdc5e3ba234 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -528,7 +528,7 @@ struct kiocb_priv {
struct usb_request *req;
struct ep_data *epdata;
void *buf;
- char __user *ubuf;
+ char __user *ubuf; /* NULL for writes */
unsigned actual;
};
@@ -566,7 +566,6 @@ static ssize_t ep_aio_read_retry(struct kiocb *iocb)
status = priv->actual;
kfree(priv->buf);
kfree(priv);
- aio_put_req(iocb);
return status;
}
@@ -580,8 +579,8 @@ static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req)
spin_lock(&epdata->dev->lock);
priv->req = NULL;
priv->epdata = NULL;
- if (NULL == iocb->ki_retry
- || unlikely(0 == req->actual)
+ if (priv->ubuf == NULL
+ || unlikely(req->actual == 0)
|| unlikely(kiocbIsCancelled(iocb))) {
kfree(req->buf);
kfree(priv);
@@ -618,7 +617,7 @@ ep_aio_rwtail(
char __user *ubuf
)
{
- struct kiocb_priv *priv = (void *) &iocb->private;
+ struct kiocb_priv *priv;
struct usb_request *req;
ssize_t value;
@@ -670,7 +669,7 @@ fail:
kfree(priv);
put_ep(epdata);
} else
- value = -EIOCBQUEUED;
+ value = (ubuf ? -EIOCBRETRY : -EIOCBQUEUED);
return value;
}
@@ -1039,7 +1038,7 @@ scan:
/* ep0 can't deliver events when STATE_SETUP */
for (i = 0; i < n; i++) {
if (dev->event [i].type == GADGETFS_SETUP) {
- len = n = i + 1;
+ len = i + 1;
len *= sizeof (struct usb_gadgetfs_event);
n = 0;
break;
@@ -1587,13 +1586,13 @@ gadgetfs_create_file (struct super_block *sb, char const *name,
static int activate_ep_files (struct dev_data *dev)
{
struct usb_ep *ep;
+ struct ep_data *data;
gadget_for_each_ep (ep, dev->gadget) {
- struct ep_data *data;
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (!data)
- goto enomem;
+ goto enomem0;
data->state = STATE_EP_DISABLED;
init_MUTEX (&data->lock);
init_waitqueue_head (&data->wait);
@@ -1608,21 +1607,23 @@ static int activate_ep_files (struct dev_data *dev)
data->req = usb_ep_alloc_request (ep, GFP_KERNEL);
if (!data->req)
- goto enomem;
+ goto enomem1;
data->inode = gadgetfs_create_file (dev->sb, data->name,
data, &ep_config_operations,
&data->dentry);
- if (!data->inode) {
- usb_ep_free_request(ep, data->req);
- kfree (data);
- goto enomem;
- }
+ if (!data->inode)
+ goto enomem2;
list_add_tail (&data->epfiles, &dev->epfiles);
}
return 0;
-enomem:
+enomem2:
+ usb_ep_free_request (ep, data->req);
+enomem1:
+ put_dev (dev);
+ kfree (data);
+enomem0:
DBG (dev, "%s enomem\n", __FUNCTION__);
destroy_ep_files (dev);
return -ENOMEM;
@@ -1793,7 +1794,7 @@ static struct usb_gadget_driver probe_driver = {
*
* After initialization, the device stays active for as long as that
* $CHIP file is open. Events may then be read from that descriptor,
- * such configuration notifications. More complex drivers will handle
+ * such as configuration notifications. More complex drivers will handle
* some control requests in user space.
*/
@@ -2033,12 +2034,10 @@ gadgetfs_fill_super (struct super_block *sb, void *opts, int silent)
NULL, &simple_dir_operations,
S_IFDIR | S_IRUGO | S_IXUGO);
if (!inode)
- return -ENOMEM;
+ goto enomem0;
inode->i_op = &simple_dir_inode_operations;
- if (!(d = d_alloc_root (inode))) {
- iput (inode);
- return -ENOMEM;
- }
+ if (!(d = d_alloc_root (inode)))
+ goto enomem1;
sb->s_root = d;
/* the ep0 file is named after the controller we expect;
@@ -2046,29 +2045,36 @@ gadgetfs_fill_super (struct super_block *sb, void *opts, int silent)
*/
dev = dev_new ();
if (!dev)
- return -ENOMEM;
+ goto enomem2;
dev->sb = sb;
- if (!(inode = gadgetfs_create_file (sb, CHIP,
+ if (!gadgetfs_create_file (sb, CHIP,
dev, &dev_init_operations,
- &dev->dentry))) {
- put_dev(dev);
- return -ENOMEM;
- }
+ &dev->dentry))
+ goto enomem3;
/* other endpoint files are available after hardware setup,
* from binding to a controller.
*/
the_device = dev;
return 0;
+
+enomem3:
+ put_dev (dev);
+enomem2:
+ dput (d);
+enomem1:
+ iput (inode);
+enomem0:
+ return -ENOMEM;
}
/* "mount -t gadgetfs path /dev/gadget" ends up here */
-static struct super_block *
+static int
gadgetfs_get_sb (struct file_system_type *t, int flags,
- const char *path, void *opts)
+ const char *path, void *opts, struct vfsmount *mnt)
{
- return get_sb_single (t, flags, opts, gadgetfs_fill_super);
+ return get_sb_single (t, flags, opts, gadgetfs_fill_super, mnt);
}
static void
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
index 0b9293493957..1facdea56a8a 100644
--- a/drivers/usb/gadget/net2280.c
+++ b/drivers/usb/gadget/net2280.c
@@ -2822,7 +2822,6 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id)
unsigned long resource, len;
void __iomem *base = NULL;
int retval, i;
- char buf [8], *bufp;
/* if you want to support more than one controller in a system,
* usb_gadget_driver_{register,unregister}() must change.
@@ -2896,15 +2895,10 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id)
retval = -ENODEV;
goto done;
}
-#ifndef __sparc__
- scnprintf (buf, sizeof buf, "%d", pdev->irq);
- bufp = buf;
-#else
- bufp = __irq_itoa(pdev->irq);
-#endif
+
if (request_irq (pdev->irq, net2280_irq, SA_SHIRQ, driver_name, dev)
!= 0) {
- ERROR (dev, "request interrupt %s failed\n", bufp);
+ ERROR (dev, "request interrupt %d failed\n", pdev->irq);
retval = -EBUSY;
goto done;
}
@@ -2953,8 +2947,8 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id)
/* done */
INFO (dev, "%s\n", driver_desc);
- INFO (dev, "irq %s, pci mem %p, chip rev %04x\n",
- bufp, base, dev->chiprev);
+ INFO (dev, "irq %d, pci mem %p, chip rev %04x\n",
+ pdev->irq, base, dev->chiprev);
INFO (dev, "version: " DRIVER_VERSION "; dma %s\n",
use_dma
? (use_dma_chaining ? "chaining" : "enabled")
@@ -2972,6 +2966,22 @@ done:
return retval;
}
+/* make sure the board is quiescent; otherwise it will continue
+ * generating IRQs across the upcoming reboot.
+ */
+
+static void net2280_shutdown (struct pci_dev *pdev)
+{
+ struct net2280 *dev = pci_get_drvdata (pdev);
+
+ /* disable IRQs */
+ writel (0, &dev->regs->pciirqenb0);
+ writel (0, &dev->regs->pciirqenb1);
+
+ /* disable the pullup so the host will think we're gone */
+ writel (0, &dev->usb->usbctl);
+}
+
/*-------------------------------------------------------------------------*/
@@ -3001,6 +3011,7 @@ static struct pci_driver net2280_pci_driver = {
.probe = net2280_probe,
.remove = net2280_remove,
+ .shutdown = net2280_shutdown,
/* FIXME add power management support */
};
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c
index 680f7fc5b171..269ce7f4ad66 100644
--- a/drivers/usb/gadget/pxa2xx_udc.c
+++ b/drivers/usb/gadget/pxa2xx_udc.c
@@ -53,12 +53,14 @@
#include <asm/mach-types.h>
#include <asm/unaligned.h>
#include <asm/hardware.h>
+#ifdef CONFIG_ARCH_PXA
#include <asm/arch/pxa-regs.h>
+#endif
#include <linux/usb_ch9.h>
#include <linux/usb_gadget.h>
-#include <asm/arch/udc.h>
+#include <asm/arch/hardware/intel_udc.h>
/*
@@ -545,6 +547,7 @@ write_ep0_fifo (struct pxa2xx_ep *ep, struct pxa2xx_request *req)
count = req->req.length;
done (ep, req, 0);
ep0_idle(ep->dev);
+#ifndef CONFIG_ARCH_IXP4XX
#if 1
/* This seems to get rid of lost status irqs in some cases:
* host responds quickly, or next request involves config
@@ -565,6 +568,7 @@ write_ep0_fifo (struct pxa2xx_ep *ep, struct pxa2xx_request *req)
} while (count);
}
#endif
+#endif
} else if (ep->dev->req_pending)
ep0start(ep->dev, 0, "IN");
return is_short;
@@ -1585,7 +1589,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
int retval;
if (!driver
- || driver->speed != USB_SPEED_FULL
+ || driver->speed < USB_SPEED_FULL
|| !driver->bind
|| !driver->unbind
|| !driver->disconnect
@@ -2427,6 +2431,7 @@ static struct pxa2xx_udc memory = {
#define PXA210_B1 0x00000123
#define PXA210_B0 0x00000122
#define IXP425_A0 0x000001c1
+#define IXP465_AD 0x00000200
/*
* probe - binds to the platform device
@@ -2463,6 +2468,8 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev)
break;
#elif defined(CONFIG_ARCH_IXP4XX)
case IXP425_A0:
+ case IXP465_AD:
+ dev->has_cfr = 1;
out_dma = 0;
break;
#endif
@@ -2575,10 +2582,12 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev)
free_irq(IRQ_USB, dev);
dev->got_irq = 0;
}
+#ifdef CONFIG_ARCH_LUBBOCK
if (machine_is_lubbock()) {
free_irq(LUBBOCK_USB_DISC_IRQ, dev);
free_irq(LUBBOCK_USB_IRQ, dev);
}
+#endif
platform_set_drvdata(pdev, NULL);
the_controller = NULL;
return 0;
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c
index 6d6eaad73968..3ff6db7828a0 100644
--- a/drivers/usb/gadget/rndis.c
+++ b/drivers/usb/gadget/rndis.c
@@ -1,23 +1,23 @@
-/*
+/*
* RNDIS MSG parser
- *
+ *
* Version: $Id: rndis.c,v 1.19 2004/03/25 21:33:46 robert Exp $
- *
+ *
* Authors: Benedikt Spranger, Pengutronix
- * Robert Schwebel, Pengutronix
- *
+ * Robert Schwebel, Pengutronix
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
- * version 2, as published by the Free Software Foundation.
- *
+ * version 2, as published by the Free Software Foundation.
+ *
* This software was originally developed in conformance with
* Microsoft's Remote NDIS Specification License Agreement.
- *
+ *
* 03/12/2004 Kai-Uwe Bloem <linux-development@auerswald.de>
* Fixed message length bug in init_response
- *
+ *
* 03/25/2004 Kai-Uwe Bloem <linux-development@auerswald.de>
- * Fixed rndis_rm_hdr length bug.
+ * Fixed rndis_rm_hdr length bug.
*
* Copyright (C) 2004 by David Brownell
* updates to merge with Linux 2.6, better match RNDIS spec
@@ -82,7 +82,7 @@ static rndis_resp_t *rndis_add_response (int configNr, u32 length);
/* supported OIDs */
-static const u32 oid_supported_list [] =
+static const u32 oid_supported_list [] =
{
/* the general stuff */
OID_GEN_SUPPORTED_LIST,
@@ -103,7 +103,7 @@ static const u32 oid_supported_list [] =
#if 0
OID_GEN_RNDIS_CONFIG_PARAMETER,
#endif
-
+
/* the statistical stuff */
OID_GEN_XMIT_OK,
OID_GEN_RCV_OK,
@@ -127,14 +127,14 @@ static const u32 oid_supported_list [] =
OID_GEN_TRANSMIT_QUEUE_LENGTH,
#endif /* RNDIS_OPTIONAL_STATS */
- /* mandatory 802.3 */
+ /* mandatory 802.3 */
/* the general stuff */
OID_802_3_PERMANENT_ADDRESS,
OID_802_3_CURRENT_ADDRESS,
OID_802_3_MULTICAST_LIST,
OID_802_3_MAC_OPTIONS,
OID_802_3_MAXIMUM_LIST_SIZE,
-
+
/* the statistical stuff */
OID_802_3_RCV_ERROR_ALIGNMENT,
OID_802_3_XMIT_ONE_COLLISION,
@@ -172,8 +172,8 @@ static int
gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
rndis_resp_t *r)
{
- int retval = -ENOTSUPP;
- u32 length = 4; /* usually */
+ int retval = -ENOTSUPP;
+ u32 length = 4; /* usually */
__le32 *outbuf;
int i, count;
rndis_query_cmplt_type *resp;
@@ -211,27 +211,27 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
outbuf[i] = cpu_to_le32 (oid_supported_list[i]);
retval = 0;
break;
-
+
/* mandatory */
case OID_GEN_HARDWARE_STATUS:
DEBUG("%s: OID_GEN_HARDWARE_STATUS\n", __FUNCTION__);
- /* Bogus question!
+ /* Bogus question!
* Hardware must be ready to receive high level protocols.
- * BTW:
+ * BTW:
* reddite ergo quae sunt Caesaris Caesari
* et quae sunt Dei Deo!
*/
*outbuf = __constant_cpu_to_le32 (0);
retval = 0;
break;
-
+
/* mandatory */
case OID_GEN_MEDIA_SUPPORTED:
DEBUG("%s: OID_GEN_MEDIA_SUPPORTED\n", __FUNCTION__);
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium);
retval = 0;
break;
-
+
/* mandatory */
case OID_GEN_MEDIA_IN_USE:
DEBUG("%s: OID_GEN_MEDIA_IN_USE\n", __FUNCTION__);
@@ -239,7 +239,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium);
retval = 0;
break;
-
+
/* mandatory */
case OID_GEN_MAXIMUM_FRAME_SIZE:
DEBUG("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __FUNCTION__);
@@ -249,7 +249,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
retval = 0;
}
break;
-
+
/* mandatory */
case OID_GEN_LINK_SPEED:
if (rndis_debug > 1)
@@ -272,7 +272,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
retval = 0;
}
break;
-
+
/* mandatory */
case OID_GEN_RECEIVE_BLOCK_SIZE:
DEBUG("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __FUNCTION__);
@@ -282,7 +282,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
retval = 0;
}
break;
-
+
/* mandatory */
case OID_GEN_VENDOR_ID:
DEBUG("%s: OID_GEN_VENDOR_ID\n", __FUNCTION__);
@@ -290,7 +290,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
rndis_per_dev_params [configNr].vendorID);
retval = 0;
break;
-
+
/* mandatory */
case OID_GEN_VENDOR_DESCRIPTION:
DEBUG("%s: OID_GEN_VENDOR_DESCRIPTION\n", __FUNCTION__);
@@ -356,7 +356,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
DEBUG("%s: OID_GEN_XMIT_OK\n", __FUNCTION__);
if (rndis_per_dev_params [configNr].stats) {
*outbuf = cpu_to_le32 (
- rndis_per_dev_params [configNr].stats->tx_packets -
+ rndis_per_dev_params [configNr].stats->tx_packets -
rndis_per_dev_params [configNr].stats->tx_errors -
rndis_per_dev_params [configNr].stats->tx_dropped);
retval = 0;
@@ -369,13 +369,13 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
DEBUG("%s: OID_GEN_RCV_OK\n", __FUNCTION__);
if (rndis_per_dev_params [configNr].stats) {
*outbuf = cpu_to_le32 (
- rndis_per_dev_params [configNr].stats->rx_packets -
+ rndis_per_dev_params [configNr].stats->rx_packets -
rndis_per_dev_params [configNr].stats->rx_errors -
rndis_per_dev_params [configNr].stats->rx_dropped);
retval = 0;
}
break;
-
+
/* mandatory */
case OID_GEN_XMIT_ERROR:
if (rndis_debug > 1)
@@ -386,7 +386,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
retval = 0;
}
break;
-
+
/* mandatory */
case OID_GEN_RCV_ERROR:
if (rndis_debug > 1)
@@ -397,7 +397,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
retval = 0;
}
break;
-
+
/* mandatory */
case OID_GEN_RCV_NO_BUFFER:
DEBUG("%s: OID_GEN_RCV_NO_BUFFER\n", __FUNCTION__);
@@ -411,7 +411,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
#ifdef RNDIS_OPTIONAL_STATS
case OID_GEN_DIRECTED_BYTES_XMIT:
DEBUG("%s: OID_GEN_DIRECTED_BYTES_XMIT\n", __FUNCTION__);
- /*
+ /*
* Aunt Tilly's size of shoes
* minus antarctica count of penguins
* divided by weight of Alpha Centauri
@@ -419,7 +419,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
if (rndis_per_dev_params [configNr].stats) {
*outbuf = cpu_to_le32 (
(rndis_per_dev_params [configNr]
- .stats->tx_packets -
+ .stats->tx_packets -
rndis_per_dev_params [configNr]
.stats->tx_errors -
rndis_per_dev_params [configNr]
@@ -428,14 +428,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
retval = 0;
}
break;
-
+
case OID_GEN_DIRECTED_FRAMES_XMIT:
DEBUG("%s: OID_GEN_DIRECTED_FRAMES_XMIT\n", __FUNCTION__);
/* dito */
if (rndis_per_dev_params [configNr].stats) {
*outbuf = cpu_to_le32 (
(rndis_per_dev_params [configNr]
- .stats->tx_packets -
+ .stats->tx_packets -
rndis_per_dev_params [configNr]
.stats->tx_errors -
rndis_per_dev_params [configNr]
@@ -444,7 +444,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
retval = 0;
}
break;
-
+
case OID_GEN_MULTICAST_BYTES_XMIT:
DEBUG("%s: OID_GEN_MULTICAST_BYTES_XMIT\n", __FUNCTION__);
if (rndis_per_dev_params [configNr].stats) {
@@ -453,7 +453,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
retval = 0;
}
break;
-
+
case OID_GEN_MULTICAST_FRAMES_XMIT:
DEBUG("%s: OID_GEN_MULTICAST_FRAMES_XMIT\n", __FUNCTION__);
if (rndis_per_dev_params [configNr].stats) {
@@ -462,7 +462,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
retval = 0;
}
break;
-
+
case OID_GEN_BROADCAST_BYTES_XMIT:
DEBUG("%s: OID_GEN_BROADCAST_BYTES_XMIT\n", __FUNCTION__);
if (rndis_per_dev_params [configNr].stats) {
@@ -471,7 +471,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
retval = 0;
}
break;
-
+
case OID_GEN_BROADCAST_FRAMES_XMIT:
DEBUG("%s: OID_GEN_BROADCAST_FRAMES_XMIT\n", __FUNCTION__);
if (rndis_per_dev_params [configNr].stats) {
@@ -480,19 +480,19 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
retval = 0;
}
break;
-
+
case OID_GEN_DIRECTED_BYTES_RCV:
DEBUG("%s: OID_GEN_DIRECTED_BYTES_RCV\n", __FUNCTION__);
*outbuf = __constant_cpu_to_le32 (0);
retval = 0;
break;
-
+
case OID_GEN_DIRECTED_FRAMES_RCV:
DEBUG("%s: OID_GEN_DIRECTED_FRAMES_RCV\n", __FUNCTION__);
*outbuf = __constant_cpu_to_le32 (0);
retval = 0;
break;
-
+
case OID_GEN_MULTICAST_BYTES_RCV:
DEBUG("%s: OID_GEN_MULTICAST_BYTES_RCV\n", __FUNCTION__);
if (rndis_per_dev_params [configNr].stats) {
@@ -501,7 +501,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
retval = 0;
}
break;
-
+
case OID_GEN_MULTICAST_FRAMES_RCV:
DEBUG("%s: OID_GEN_MULTICAST_FRAMES_RCV\n", __FUNCTION__);
if (rndis_per_dev_params [configNr].stats) {
@@ -510,7 +510,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
retval = 0;
}
break;
-
+
case OID_GEN_BROADCAST_BYTES_RCV:
DEBUG("%s: OID_GEN_BROADCAST_BYTES_RCV\n", __FUNCTION__);
if (rndis_per_dev_params [configNr].stats) {
@@ -519,7 +519,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
retval = 0;
}
break;
-
+
case OID_GEN_BROADCAST_FRAMES_RCV:
DEBUG("%s: OID_GEN_BROADCAST_FRAMES_RCV\n", __FUNCTION__);
if (rndis_per_dev_params [configNr].stats) {
@@ -528,7 +528,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
retval = 0;
}
break;
-
+
case OID_GEN_RCV_CRC_ERROR:
DEBUG("%s: OID_GEN_RCV_CRC_ERROR\n", __FUNCTION__);
if (rndis_per_dev_params [configNr].stats) {
@@ -537,7 +537,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
retval = 0;
}
break;
-
+
case OID_GEN_TRANSMIT_QUEUE_LENGTH:
DEBUG("%s: OID_GEN_TRANSMIT_QUEUE_LENGTH\n", __FUNCTION__);
*outbuf = __constant_cpu_to_le32 (0);
@@ -558,7 +558,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
retval = 0;
}
break;
-
+
/* mandatory */
case OID_802_3_CURRENT_ADDRESS:
DEBUG("%s: OID_802_3_CURRENT_ADDRESS\n", __FUNCTION__);
@@ -570,7 +570,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
retval = 0;
}
break;
-
+
/* mandatory */
case OID_802_3_MULTICAST_LIST:
DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__);
@@ -578,7 +578,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
*outbuf = __constant_cpu_to_le32 (0xE0000000);
retval = 0;
break;
-
+
/* mandatory */
case OID_802_3_MAXIMUM_LIST_SIZE:
DEBUG("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __FUNCTION__);
@@ -586,7 +586,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
*outbuf = __constant_cpu_to_le32 (1);
retval = 0;
break;
-
+
case OID_802_3_MAC_OPTIONS:
DEBUG("%s: OID_802_3_MAC_OPTIONS\n", __FUNCTION__);
break;
@@ -602,56 +602,56 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
retval = 0;
}
break;
-
+
/* mandatory */
case OID_802_3_XMIT_ONE_COLLISION:
DEBUG("%s: OID_802_3_XMIT_ONE_COLLISION\n", __FUNCTION__);
*outbuf = __constant_cpu_to_le32 (0);
retval = 0;
break;
-
+
/* mandatory */
case OID_802_3_XMIT_MORE_COLLISIONS:
DEBUG("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __FUNCTION__);
*outbuf = __constant_cpu_to_le32 (0);
retval = 0;
break;
-
+
#ifdef RNDIS_OPTIONAL_STATS
case OID_802_3_XMIT_DEFERRED:
DEBUG("%s: OID_802_3_XMIT_DEFERRED\n", __FUNCTION__);
/* TODO */
break;
-
+
case OID_802_3_XMIT_MAX_COLLISIONS:
DEBUG("%s: OID_802_3_XMIT_MAX_COLLISIONS\n", __FUNCTION__);
/* TODO */
break;
-
+
case OID_802_3_RCV_OVERRUN:
DEBUG("%s: OID_802_3_RCV_OVERRUN\n", __FUNCTION__);
/* TODO */
break;
-
+
case OID_802_3_XMIT_UNDERRUN:
DEBUG("%s: OID_802_3_XMIT_UNDERRUN\n", __FUNCTION__);
/* TODO */
break;
-
+
case OID_802_3_XMIT_HEARTBEAT_FAILURE:
DEBUG("%s: OID_802_3_XMIT_HEARTBEAT_FAILURE\n", __FUNCTION__);
/* TODO */
break;
-
+
case OID_802_3_XMIT_TIMES_CRS_LOST:
DEBUG("%s: OID_802_3_XMIT_TIMES_CRS_LOST\n", __FUNCTION__);
/* TODO */
break;
-
+
case OID_802_3_XMIT_LATE_COLLISIONS:
DEBUG("%s: OID_802_3_XMIT_LATE_COLLISIONS\n", __FUNCTION__);
/* TODO */
- break;
+ break;
#endif /* RNDIS_OPTIONAL_STATS */
#ifdef RNDIS_PM
@@ -676,23 +676,23 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
#endif
default:
- printk (KERN_WARNING "%s: query unknown OID 0x%08X\n",
+ printk (KERN_WARNING "%s: query unknown OID 0x%08X\n",
__FUNCTION__, OID);
}
if (retval < 0)
length = 0;
-
+
resp->InformationBufferLength = cpu_to_le32 (length);
r->length = length + sizeof *resp;
resp->MessageLength = cpu_to_le32 (r->length);
return retval;
}
-static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
- rndis_resp_t *r)
+static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
+ rndis_resp_t *r)
{
rndis_set_cmplt_type *resp;
- int i, retval = -ENOTSUPP;
+ int i, retval = -ENOTSUPP;
struct rndis_params *params;
if (!r)
@@ -745,9 +745,9 @@ update_linkstate:
netif_stop_queue (params->dev);
}
break;
-
+
case OID_802_3_MULTICAST_LIST:
- /* I think we can ignore this */
+ /* I think we can ignore this */
DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__);
retval = 0;
break;
@@ -796,29 +796,29 @@ update_linkstate:
#endif /* RNDIS_PM */
default:
- printk (KERN_WARNING "%s: set unknown OID 0x%08X, size %d\n",
+ printk (KERN_WARNING "%s: set unknown OID 0x%08X, size %d\n",
__FUNCTION__, OID, buf_len);
}
-
+
return retval;
}
-/*
- * Response Functions
+/*
+ * Response Functions
*/
static int rndis_init_response (int configNr, rndis_init_msg_type *buf)
{
- rndis_init_cmplt_type *resp;
+ rndis_init_cmplt_type *resp;
rndis_resp_t *r;
-
+
if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP;
-
+
r = rndis_add_response (configNr, sizeof (rndis_init_cmplt_type));
if (!r)
return -ENOMEM;
resp = (rndis_init_cmplt_type *) r->buf;
-
+
resp->MessageType = __constant_cpu_to_le32 (
REMOTE_NDIS_INITIALIZE_CMPLT);
resp->MessageLength = __constant_cpu_to_le32 (52);
@@ -837,11 +837,11 @@ static int rndis_init_response (int configNr, rndis_init_msg_type *buf)
resp->PacketAlignmentFactor = __constant_cpu_to_le32 (0);
resp->AFListOffset = __constant_cpu_to_le32 (0);
resp->AFListSize = __constant_cpu_to_le32 (0);
-
+
if (rndis_per_dev_params [configNr].ack)
- rndis_per_dev_params [configNr].ack (
- rndis_per_dev_params [configNr].dev);
-
+ rndis_per_dev_params [configNr].ack (
+ rndis_per_dev_params [configNr].dev);
+
return 0;
}
@@ -849,10 +849,10 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf)
{
rndis_query_cmplt_type *resp;
rndis_resp_t *r;
-
+
// DEBUG("%s: OID = %08X\n", __FUNCTION__, cpu_to_le32(buf->OID));
if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP;
-
+
/*
* we need more memory:
* gen_ndis_query_resp expects enough space for
@@ -864,10 +864,10 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf)
if (!r)
return -ENOMEM;
resp = (rndis_query_cmplt_type *) r->buf;
-
+
resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_QUERY_CMPLT);
resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
-
+
if (gen_ndis_query_resp (configNr, le32_to_cpu (buf->OID),
le32_to_cpu(buf->InformationBufferOffset)
+ 8 + (u8 *) buf,
@@ -881,10 +881,10 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf)
resp->InformationBufferOffset = __constant_cpu_to_le32 (0);
} else
resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
-
+
if (rndis_per_dev_params [configNr].ack)
- rndis_per_dev_params [configNr].ack (
- rndis_per_dev_params [configNr].dev);
+ rndis_per_dev_params [configNr].ack (
+ rndis_per_dev_params [configNr].dev);
return 0;
}
@@ -893,7 +893,7 @@ static int rndis_set_response (int configNr, rndis_set_msg_type *buf)
u32 BufLength, BufOffset;
rndis_set_cmplt_type *resp;
rndis_resp_t *r;
-
+
r = rndis_add_response (configNr, sizeof (rndis_set_cmplt_type));
if (!r)
return -ENOMEM;
@@ -906,26 +906,27 @@ static int rndis_set_response (int configNr, rndis_set_msg_type *buf)
DEBUG("%s: Length: %d\n", __FUNCTION__, BufLength);
DEBUG("%s: Offset: %d\n", __FUNCTION__, BufOffset);
DEBUG("%s: InfoBuffer: ", __FUNCTION__);
-
+
for (i = 0; i < BufLength; i++) {
DEBUG ("%02x ", *(((u8 *) buf) + i + 8 + BufOffset));
}
-
+
DEBUG ("\n");
#endif
-
+
resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_SET_CMPLT);
resp->MessageLength = __constant_cpu_to_le32 (16);
resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
- if (gen_ndis_set_resp (configNr, le32_to_cpu (buf->OID),
- ((u8 *) buf) + 8 + BufOffset, BufLength, r))
- resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_NOT_SUPPORTED);
- else resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
-
+ if (gen_ndis_set_resp (configNr, le32_to_cpu (buf->OID),
+ ((u8 *) buf) + 8 + BufOffset, BufLength, r))
+ resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_NOT_SUPPORTED);
+ else
+ resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
+
if (rndis_per_dev_params [configNr].ack)
- rndis_per_dev_params [configNr].ack (
- rndis_per_dev_params [configNr].dev);
-
+ rndis_per_dev_params [configNr].ack (
+ rndis_per_dev_params [configNr].dev);
+
return 0;
}
@@ -933,27 +934,27 @@ static int rndis_reset_response (int configNr, rndis_reset_msg_type *buf)
{
rndis_reset_cmplt_type *resp;
rndis_resp_t *r;
-
+
r = rndis_add_response (configNr, sizeof (rndis_reset_cmplt_type));
if (!r)
return -ENOMEM;
resp = (rndis_reset_cmplt_type *) r->buf;
-
+
resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_RESET_CMPLT);
resp->MessageLength = __constant_cpu_to_le32 (16);
resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
/* resent information */
resp->AddressingReset = __constant_cpu_to_le32 (1);
-
+
if (rndis_per_dev_params [configNr].ack)
- rndis_per_dev_params [configNr].ack (
- rndis_per_dev_params [configNr].dev);
+ rndis_per_dev_params [configNr].ack (
+ rndis_per_dev_params [configNr].dev);
return 0;
}
static int rndis_keepalive_response (int configNr,
- rndis_keepalive_msg_type *buf)
+ rndis_keepalive_msg_type *buf)
{
rndis_keepalive_cmplt_type *resp;
rndis_resp_t *r;
@@ -964,48 +965,48 @@ static int rndis_keepalive_response (int configNr,
if (!r)
return -ENOMEM;
resp = (rndis_keepalive_cmplt_type *) r->buf;
-
+
resp->MessageType = __constant_cpu_to_le32 (
REMOTE_NDIS_KEEPALIVE_CMPLT);
resp->MessageLength = __constant_cpu_to_le32 (16);
resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
-
+
if (rndis_per_dev_params [configNr].ack)
- rndis_per_dev_params [configNr].ack (
- rndis_per_dev_params [configNr].dev);
-
+ rndis_per_dev_params [configNr].ack (
+ rndis_per_dev_params [configNr].dev);
+
return 0;
}
-/*
- * Device to Host Comunication
+/*
+ * Device to Host Comunication
*/
static int rndis_indicate_status_msg (int configNr, u32 status)
{
- rndis_indicate_status_msg_type *resp;
+ rndis_indicate_status_msg_type *resp;
rndis_resp_t *r;
-
+
if (rndis_per_dev_params [configNr].state == RNDIS_UNINITIALIZED)
- return -ENOTSUPP;
-
- r = rndis_add_response (configNr,
+ return -ENOTSUPP;
+
+ r = rndis_add_response (configNr,
sizeof (rndis_indicate_status_msg_type));
if (!r)
return -ENOMEM;
resp = (rndis_indicate_status_msg_type *) r->buf;
-
+
resp->MessageType = __constant_cpu_to_le32 (
REMOTE_NDIS_INDICATE_STATUS_MSG);
resp->MessageLength = __constant_cpu_to_le32 (20);
resp->Status = cpu_to_le32 (status);
resp->StatusBufferLength = __constant_cpu_to_le32 (0);
resp->StatusBufferOffset = __constant_cpu_to_le32 (0);
-
- if (rndis_per_dev_params [configNr].ack)
- rndis_per_dev_params [configNr].ack (
- rndis_per_dev_params [configNr].dev);
+
+ if (rndis_per_dev_params [configNr].ack)
+ rndis_per_dev_params [configNr].ack (
+ rndis_per_dev_params [configNr].dev);
return 0;
}
@@ -1013,7 +1014,7 @@ int rndis_signal_connect (int configNr)
{
rndis_per_dev_params [configNr].media_state
= NDIS_MEDIA_STATE_CONNECTED;
- return rndis_indicate_status_msg (configNr,
+ return rndis_indicate_status_msg (configNr,
RNDIS_STATUS_MEDIA_CONNECT);
}
@@ -1045,26 +1046,26 @@ void rndis_set_host_mac (int configNr, const u8 *addr)
rndis_per_dev_params [configNr].host_mac = addr;
}
-/*
- * Message Parser
+/*
+ * Message Parser
*/
int rndis_msg_parser (u8 configNr, u8 *buf)
{
u32 MsgType, MsgLength;
__le32 *tmp;
struct rndis_params *params;
-
+
if (!buf)
return -ENOMEM;
-
- tmp = (__le32 *) buf;
+
+ tmp = (__le32 *) buf;
MsgType = le32_to_cpup(tmp++);
MsgLength = le32_to_cpup(tmp++);
-
+
if (configNr >= RNDIS_MAX_CONFIGS)
return -ENOTSUPP;
params = &rndis_per_dev_params [configNr];
-
+
/* NOTE: RNDIS is *EXTREMELY* chatty ... Windows constantly polls for
* rx/tx statistics and link status, in addition to KEEPALIVE traffic
* and normal HC level polling to see if there's any IN traffic.
@@ -1073,12 +1074,12 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
/* For USB: responses may take up to 10 seconds */
switch (MsgType) {
case REMOTE_NDIS_INITIALIZE_MSG:
- DEBUG("%s: REMOTE_NDIS_INITIALIZE_MSG\n",
+ DEBUG("%s: REMOTE_NDIS_INITIALIZE_MSG\n",
__FUNCTION__ );
params->state = RNDIS_INITIALIZED;
return rndis_init_response (configNr,
- (rndis_init_msg_type *) buf);
-
+ (rndis_init_msg_type *) buf);
+
case REMOTE_NDIS_HALT_MSG:
DEBUG("%s: REMOTE_NDIS_HALT_MSG\n",
__FUNCTION__ );
@@ -1088,37 +1089,37 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
netif_stop_queue (params->dev);
}
return 0;
-
+
case REMOTE_NDIS_QUERY_MSG:
- return rndis_query_response (configNr,
- (rndis_query_msg_type *) buf);
-
+ return rndis_query_response (configNr,
+ (rndis_query_msg_type *) buf);
+
case REMOTE_NDIS_SET_MSG:
- return rndis_set_response (configNr,
- (rndis_set_msg_type *) buf);
-
+ return rndis_set_response (configNr,
+ (rndis_set_msg_type *) buf);
+
case REMOTE_NDIS_RESET_MSG:
- DEBUG("%s: REMOTE_NDIS_RESET_MSG\n",
+ DEBUG("%s: REMOTE_NDIS_RESET_MSG\n",
__FUNCTION__ );
return rndis_reset_response (configNr,
- (rndis_reset_msg_type *) buf);
+ (rndis_reset_msg_type *) buf);
case REMOTE_NDIS_KEEPALIVE_MSG:
/* For USB: host does this every 5 seconds */
if (rndis_debug > 1)
- DEBUG("%s: REMOTE_NDIS_KEEPALIVE_MSG\n",
+ DEBUG("%s: REMOTE_NDIS_KEEPALIVE_MSG\n",
__FUNCTION__ );
return rndis_keepalive_response (configNr,
- (rndis_keepalive_msg_type *)
+ (rndis_keepalive_msg_type *)
buf);
-
- default:
+
+ default:
/* At least Windows XP emits some undefined RNDIS messages.
* In one case those messages seemed to relate to the host
* suspending itself.
*/
printk (KERN_WARNING
- "%s: unknown RNDIS message 0x%08X len %d\n",
+ "%s: unknown RNDIS message 0x%08X len %d\n",
__FUNCTION__ , MsgType, MsgLength);
{
unsigned i;
@@ -1142,14 +1143,14 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
}
break;
}
-
+
return -ENOTSUPP;
}
int rndis_register (int (* rndis_control_ack) (struct net_device *))
{
u8 i;
-
+
for (i = 0; i < RNDIS_MAX_CONFIGS; i++) {
if (!rndis_per_dev_params [i].used) {
rndis_per_dev_params [i].used = 1;
@@ -1159,32 +1160,32 @@ int rndis_register (int (* rndis_control_ack) (struct net_device *))
}
}
DEBUG("failed\n");
-
+
return -1;
}
void rndis_deregister (int configNr)
{
DEBUG("%s: \n", __FUNCTION__ );
-
+
if (configNr >= RNDIS_MAX_CONFIGS) return;
rndis_per_dev_params [configNr].used = 0;
-
+
return;
}
-int rndis_set_param_dev (u8 configNr, struct net_device *dev,
+int rndis_set_param_dev (u8 configNr, struct net_device *dev,
struct net_device_stats *stats,
u16 *cdc_filter)
{
DEBUG("%s:\n", __FUNCTION__ );
if (!dev || !stats) return -1;
if (configNr >= RNDIS_MAX_CONFIGS) return -1;
-
+
rndis_per_dev_params [configNr].dev = dev;
rndis_per_dev_params [configNr].stats = stats;
rndis_per_dev_params [configNr].filter = cdc_filter;
-
+
return 0;
}
@@ -1193,10 +1194,10 @@ int rndis_set_param_vendor (u8 configNr, u32 vendorID, const char *vendorDescr)
DEBUG("%s:\n", __FUNCTION__ );
if (!vendorDescr) return -1;
if (configNr >= RNDIS_MAX_CONFIGS) return -1;
-
+
rndis_per_dev_params [configNr].vendorID = vendorID;
rndis_per_dev_params [configNr].vendorDescr = vendorDescr;
-
+
return 0;
}
@@ -1204,10 +1205,10 @@ int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed)
{
DEBUG("%s: %u %u\n", __FUNCTION__, medium, speed);
if (configNr >= RNDIS_MAX_CONFIGS) return -1;
-
+
rndis_per_dev_params [configNr].medium = medium;
rndis_per_dev_params [configNr].speed = speed;
-
+
return 0;
}
@@ -1229,9 +1230,9 @@ void rndis_free_response (int configNr, u8 *buf)
{
rndis_resp_t *r;
struct list_head *act, *tmp;
-
- list_for_each_safe (act, tmp,
- &(rndis_per_dev_params [configNr].resp_queue))
+
+ list_for_each_safe (act, tmp,
+ &(rndis_per_dev_params [configNr].resp_queue))
{
r = list_entry (act, rndis_resp_t, list);
if (r && r->buf == buf) {
@@ -1244,12 +1245,12 @@ void rndis_free_response (int configNr, u8 *buf)
u8 *rndis_get_next_response (int configNr, u32 *length)
{
rndis_resp_t *r;
- struct list_head *act, *tmp;
-
+ struct list_head *act, *tmp;
+
if (!length) return NULL;
-
- list_for_each_safe (act, tmp,
- &(rndis_per_dev_params [configNr].resp_queue))
+
+ list_for_each_safe (act, tmp,
+ &(rndis_per_dev_params [configNr].resp_queue))
{
r = list_entry (act, rndis_resp_t, list);
if (!r->send) {
@@ -1258,24 +1259,24 @@ u8 *rndis_get_next_response (int configNr, u32 *length)
return r->buf;
}
}
-
+
return NULL;
}
static rndis_resp_t *rndis_add_response (int configNr, u32 length)
{
rndis_resp_t *r;
-
+
/* NOTE: this gets copied into ether.c USB_BUFSIZ bytes ... */
r = kmalloc (sizeof (rndis_resp_t) + length, GFP_ATOMIC);
if (!r) return NULL;
-
+
r->buf = (u8 *) (r + 1);
r->length = length;
r->send = 0;
-
- list_add_tail (&r->list,
- &(rndis_per_dev_params [configNr].resp_queue));
+
+ list_add_tail (&r->list,
+ &(rndis_per_dev_params [configNr].resp_queue));
return r;
}
@@ -1301,14 +1302,14 @@ int rndis_rm_hdr(struct sk_buff *skb)
#ifdef CONFIG_USB_GADGET_DEBUG_FILES
-static int rndis_proc_read (char *page, char **start, off_t off, int count, int *eof,
- void *data)
+static int rndis_proc_read (char *page, char **start, off_t off, int count, int *eof,
+ void *data)
{
char *out = page;
int len;
rndis_params *param = (rndis_params *) data;
-
- out += snprintf (out, count,
+
+ out += snprintf (out, count,
"Config Nr. %d\n"
"used : %s\n"
"state : %s\n"
@@ -1316,8 +1317,8 @@ static int rndis_proc_read (char *page, char **start, off_t off, int count, int
"speed : %d\n"
"cable : %s\n"
"vendor ID : 0x%08X\n"
- "vendor : %s\n",
- param->confignr, (param->used) ? "y" : "n",
+ "vendor : %s\n",
+ param->confignr, (param->used) ? "y" : "n",
({ char *s = "?";
switch (param->state) {
case RNDIS_UNINITIALIZED:
@@ -1327,32 +1328,32 @@ static int rndis_proc_read (char *page, char **start, off_t off, int count, int
case RNDIS_DATA_INITIALIZED:
s = "RNDIS_DATA_INITIALIZED"; break;
}; s; }),
- param->medium,
- (param->media_state) ? 0 : param->speed*100,
+ param->medium,
+ (param->media_state) ? 0 : param->speed*100,
(param->media_state) ? "disconnected" : "connected",
- param->vendorID, param->vendorDescr);
-
+ param->vendorID, param->vendorDescr);
+
len = out - page;
len -= off;
-
+
if (len < count) {
*eof = 1;
if (len <= 0)
return 0;
} else
len = count;
-
+
*start = page + off;
return len;
}
-static int rndis_proc_write (struct file *file, const char __user *buffer,
- unsigned long count, void *data)
+static int rndis_proc_write (struct file *file, const char __user *buffer,
+ unsigned long count, void *data)
{
rndis_params *p = data;
u32 speed = 0;
int i, fl_speed = 0;
-
+
for (i = 0; i < count; i++) {
char c;
if (get_user(c, buffer))
@@ -1379,15 +1380,15 @@ static int rndis_proc_write (struct file *file, const char __user *buffer,
case 'd':
rndis_signal_disconnect(p->confignr);
break;
- default:
+ default:
if (fl_speed) p->speed = speed;
else DEBUG ("%c is not valid\n", c);
break;
}
-
+
buffer++;
}
-
+
return count;
}
@@ -1408,7 +1409,7 @@ int __init rndis_init (void)
sprintf (name, NAME_TEMPLATE, i);
if (!(rndis_connect_state [i]
- = create_proc_entry (name, 0660, NULL)))
+ = create_proc_entry (name, 0660, NULL)))
{
DEBUG ("%s :remove entries", __FUNCTION__);
while (i) {
@@ -1432,7 +1433,7 @@ int __init rndis_init (void)
= NDIS_MEDIA_STATE_DISCONNECTED;
INIT_LIST_HEAD (&(rndis_per_dev_params [i].resp_queue));
}
-
+
return 0;
}
@@ -1441,7 +1442,7 @@ void rndis_exit (void)
#ifdef CONFIG_USB_GADGET_DEBUG_FILES
u8 i;
char name [20];
-
+
for (i = 0; i < RNDIS_MAX_CONFIGS; i++) {
sprintf (name, NAME_TEMPLATE, i);
remove_proc_entry (name, NULL);
diff --git a/drivers/usb/gadget/rndis.h b/drivers/usb/gadget/rndis.h
index 95b4c6326100..2956608be751 100644
--- a/drivers/usb/gadget/rndis.h
+++ b/drivers/usb/gadget/rndis.h
@@ -1,15 +1,15 @@
-/*
+/*
* RNDIS Definitions for Remote NDIS
- *
+ *
* Version: $Id: rndis.h,v 1.15 2004/03/25 21:33:46 robert Exp $
- *
+ *
* Authors: Benedikt Spranger, Pengutronix
- * Robert Schwebel, Pengutronix
- *
- * This program is free software; you can redistribute it and/or
+ * Robert Schwebel, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
- * version 2, as published by the Free Software Foundation.
- *
+ * version 2, as published by the Free Software Foundation.
+ *
* This software was originally developed in conformance with
* Microsoft's Remote NDIS Specification License Agreement.
*/
@@ -34,7 +34,7 @@
#define RNDIS_STATUS_MEDIA_CONNECT 0x4001000BU /* Device connected */
#define RNDIS_STATUS_MEDIA_DISCONNECT 0x4001000CU /* Device disconnected */
/* For all not specified status messages:
- * RNDIS_STATUS_Xxx -> NDIS_STATUS_Xxx
+ * RNDIS_STATUS_Xxx -> NDIS_STATUS_Xxx
*/
/* Message Set for Connectionless (802.3) Devices */
@@ -69,7 +69,7 @@
#define OID_PNP_ENABLE_WAKE_UP 0xFD010106
-typedef struct rndis_init_msg_type
+typedef struct rndis_init_msg_type
{
__le32 MessageType;
__le32 MessageLength;
@@ -234,12 +234,12 @@ typedef struct rndis_params
const u8 *host_mac;
u16 *filter;
- struct net_device *dev;
+ struct net_device *dev;
struct net_device_stats *stats;
u32 vendorID;
const char *vendorDescr;
- int (*ack) (struct net_device *);
+ int (*ack) (struct net_device *);
struct list_head resp_queue;
} rndis_params;
@@ -250,7 +250,7 @@ void rndis_deregister (int configNr);
int rndis_set_param_dev (u8 configNr, struct net_device *dev,
struct net_device_stats *stats,
u16 *cdc_filter);
-int rndis_set_param_vendor (u8 configNr, u32 vendorID,
+int rndis_set_param_vendor (u8 configNr, u32 vendorID,
const char *vendorDescr);
int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed);
void rndis_add_hdr (struct sk_buff *skb);
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index b992546c394d..9d6e1d295528 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -45,88 +45,16 @@
#include <asm/uaccess.h>
#include <linux/usb_ch9.h>
-#include <linux/usb_cdc.h>
+#include <linux/usb/cdc.h>
#include <linux/usb_gadget.h>
#include "gadget_chips.h"
-/* Wait Cond */
-
-#define __wait_cond_interruptible(wq, condition, lock, flags, ret) \
-do { \
- wait_queue_t __wait; \
- init_waitqueue_entry(&__wait, current); \
- \
- add_wait_queue(&wq, &__wait); \
- for (;;) { \
- set_current_state(TASK_INTERRUPTIBLE); \
- if (condition) \
- break; \
- if (!signal_pending(current)) { \
- spin_unlock_irqrestore(lock, flags); \
- schedule(); \
- spin_lock_irqsave(lock, flags); \
- continue; \
- } \
- ret = -ERESTARTSYS; \
- break; \
- } \
- current->state = TASK_RUNNING; \
- remove_wait_queue(&wq, &__wait); \
-} while (0)
-
-#define wait_cond_interruptible(wq, condition, lock, flags) \
-({ \
- int __ret = 0; \
- if (!(condition)) \
- __wait_cond_interruptible(wq, condition, lock, flags, \
- __ret); \
- __ret; \
-})
-
-#define __wait_cond_interruptible_timeout(wq, condition, lock, flags, \
- timeout, ret) \
-do { \
- signed long __timeout = timeout; \
- wait_queue_t __wait; \
- init_waitqueue_entry(&__wait, current); \
- \
- add_wait_queue(&wq, &__wait); \
- for (;;) { \
- set_current_state(TASK_INTERRUPTIBLE); \
- if (__timeout == 0) \
- break; \
- if (condition) \
- break; \
- if (!signal_pending(current)) { \
- spin_unlock_irqrestore(lock, flags); \
- __timeout = schedule_timeout(__timeout); \
- spin_lock_irqsave(lock, flags); \
- continue; \
- } \
- ret = -ERESTARTSYS; \
- break; \
- } \
- current->state = TASK_RUNNING; \
- remove_wait_queue(&wq, &__wait); \
-} while (0)
-
-#define wait_cond_interruptible_timeout(wq, condition, lock, flags, \
- timeout) \
-({ \
- int __ret = 0; \
- if (!(condition)) \
- __wait_cond_interruptible_timeout(wq, condition, lock, \
- flags, timeout, __ret); \
- __ret; \
-})
-
-
/* Defines */
-#define GS_VERSION_STR "v2.0"
-#define GS_VERSION_NUM 0x0200
+#define GS_VERSION_STR "v2.2"
+#define GS_VERSION_NUM 0x0202
#define GS_LONG_NAME "Gadget Serial"
#define GS_SHORT_NAME "g_serial"
@@ -843,9 +771,19 @@ exit_unlock_dev:
/*
* gs_close
*/
+
+#define GS_WRITE_FINISHED_EVENT_SAFELY(p) \
+({ \
+ int cond; \
+ \
+ spin_lock_irq(&(p)->port_lock); \
+ cond = !(p)->port_dev || !gs_buf_data_avail((p)->port_write_buf); \
+ spin_unlock_irq(&(p)->port_lock); \
+ cond; \
+})
+
static void gs_close(struct tty_struct *tty, struct file *file)
{
- unsigned long flags;
struct gs_port *port = tty->driver_data;
struct semaphore *sem;
@@ -859,7 +797,7 @@ static void gs_close(struct tty_struct *tty, struct file *file)
sem = &gs_open_close_sem[port->port_num];
down(sem);
- spin_lock_irqsave(&port->port_lock, flags);
+ spin_lock_irq(&port->port_lock);
if (port->port_open_count == 0) {
printk(KERN_ERR
@@ -887,12 +825,11 @@ static void gs_close(struct tty_struct *tty, struct file *file)
/* wait for write buffer to drain, or */
/* at most GS_CLOSE_TIMEOUT seconds */
if (gs_buf_data_avail(port->port_write_buf) > 0) {
- spin_unlock_irqrestore(&port->port_lock, flags);
- wait_cond_interruptible_timeout(port->port_write_wait,
- port->port_dev == NULL
- || gs_buf_data_avail(port->port_write_buf) == 0,
- &port->port_lock, flags, GS_CLOSE_TIMEOUT * HZ);
- spin_lock_irqsave(&port->port_lock, flags);
+ spin_unlock_irq(&port->port_lock);
+ wait_event_interruptible_timeout(port->port_write_wait,
+ GS_WRITE_FINISHED_EVENT_SAFELY(port),
+ GS_CLOSE_TIMEOUT * HZ);
+ spin_lock_irq(&port->port_lock);
}
/* free disconnected port on final close */
@@ -912,7 +849,7 @@ static void gs_close(struct tty_struct *tty, struct file *file)
port->port_num, tty, file);
exit:
- spin_unlock_irqrestore(&port->port_lock, flags);
+ spin_unlock_irq(&port->port_lock);
up(sem);
}