drivers: usb: gadget: update some usb drivers for USB Tethering.

This commit is contained in:
tytung 2012-05-19 19:33:14 +08:00 committed by milaq
parent 9bb78d2a7f
commit 560a956cd5
9 changed files with 1144 additions and 406 deletions

View File

@ -129,6 +129,45 @@ static inline void dma_free_noncoherent(struct device *dev, size_t size,
{
}
/*
* dma_coherent_pre_ops - barrier functions for coherent memory before DMA.
* A barrier is required to ensure memory operations are complete before the
* initiation of a DMA xfer.
* If the coherent memory is Strongly Ordered
* - pre ARMv7 and 8x50 guarantees ordering wrt other mem accesses
* - ARMv7 guarantees ordering only within a 1KB block, so we need a barrier
* If coherent memory is normal then we need a barrier to prevent
* reordering
*/
static inline void dma_coherent_pre_ops(void)
{
#if (__LINUX_ARM_ARCH__ >= 7)
dmb();
#else
if (arch_is_coherent())
dmb();
else
barrier();
#endif
}
/*
* dma_post_coherent_ops - barrier functions for coherent memory after DMA.
* If the coherent memory is Strongly Ordered we dont need a barrier since
* there are no speculative fetches to Strongly Ordered memory.
* If coherent memory is normal then we need a barrier to prevent reordering
*/
static inline void dma_coherent_post_ops(void)
{
#if (__LINUX_ARM_ARCH__ >= 7)
dmb();
#else
if (arch_is_coherent())
dmb();
else
barrier();
#endif
}
/**
* dma_alloc_coherent - allocate consistent memory for DMA
* @dev: valid struct device pointer, or NULL for ISA and EISA-like devices

View File

@ -179,6 +179,16 @@ enum {
};
void msm_hsusb_set_vbus_state(int online);
enum usb_connect_type {
CONNECT_TYPE_CLEAR = -2,
CONNECT_TYPE_UNKNOWN = -1,
CONNECT_TYPE_NONE = 0,
CONNECT_TYPE_USB,
CONNECT_TYPE_AC,
CONNECT_TYPE_9V_AC,
CONNECT_TYPE_WIRELESS,
CONNECT_TYPE_INTERNAL,
};
#define MSM_MAX_DEC_CNT 14
/* 7k target ADSP information */

View File

@ -47,8 +47,18 @@ struct msm_hsusb_platform_data {
/* 1 : uart, 0 : usb */
void (*usb_uart_switch)(int);
void (*config_usb_id_gpios)(bool enable);
/* val, reg pairs terminated by -1 */
int *phy_init_seq;
void (*usb_hub_enable)(bool);
void (*serial_debug_gpios)(int);
int (*china_ac_detect)(void);
void (*disable_usb_charger)(void);
/* val, reg pairs terminated by -1 */
int *phy_init_seq;
void (*change_phy_voltage)(int);
int (*ldo_init) (int init);
int (*ldo_enable) (int enable);
int (*rpc_connect)(int);
/* 1 : mhl, 0 : usb */
void (*usb_mhl_switch)(bool);
#ifdef CONFIG_USB_FUNCTION
/* USB device descriptor fields */
@ -74,10 +84,15 @@ struct msm_hsusb_platform_data {
int num_products;
struct msm_hsusb_product *products;
#endif
char *serial_number;
int usb_id_pin_gpio;
bool enable_car_kit_detect;
__u8 accessory_detect;
char *serial_number;
int usb_id_pin_gpio;
int dock_pin_gpio;
int id_pin_irq;
bool enable_car_kit_detect;
__u8 accessory_detect;
bool dock_detect;
int ac_9v_gpio;
};
int usb_get_connect_type(void);

View File

@ -37,11 +37,30 @@
do { } while (0)
#endif /* VERBOSE */
#ifndef __LINUX_USB_COMPOSITE_H
#define ERROR(fmt,args...) \
xprintk(KERN_ERR , fmt , ## args)
#define INFO(fmt,args...) \
xprintk(KERN_INFO , fmt , ## args)
#endif
#define USB_ERR(fmt, args...) \
printk(KERN_ERR "[USB:ERR] " fmt, ## args)
#define USB_WARNING(fmt, args...) \
printk(KERN_WARNING "[USB] " fmt, ## args)
#define USB_INFO(fmt, args...) \
printk(KERN_INFO "[USB] " fmt, ## args)
#define USB_DEBUG(fmt, args...) \
printk(KERN_DEBUG "[USB] " fmt, ## args)
#define USBH_ERR(fmt, args...) \
printk(KERN_ERR "[USBH:ERR] " fmt, ## args)
#define USBH_WARNING(fmt, args...) \
printk(KERN_WARNING "[USBH] " fmt, ## args)
#define USBH_INFO(fmt, args...) \
printk(KERN_INFO "[USBH] " fmt, ## args)
#define USBH_DEBUG(fmt, args...) \
printk(KERN_DEBUG "[USBH] " fmt, ## args)
/*-------------------------------------------------------------------------*/
@ -51,9 +70,12 @@
#define USB_HWDEVICE (MSM_USB_BASE + 0x000C)
#define USB_HWTXBUF (MSM_USB_BASE + 0x0010)
#define USB_HWRXBUF (MSM_USB_BASE + 0x0014)
#define USB_AHBBURST (MSM_USB_BASE + 0x0090)
#define USB_AHBMODE (MSM_USB_BASE + 0x0098)
#define USB_AHB_BURST (MSM_USB_BASE + 0x0090)
#define USB_AHB_MODE (MSM_USB_BASE + 0x0098)
#define USB_AHBBURST (USB_AHB_BURST)
#define USB_AHBMODE (USB_AHB_MODE)
#define USB_SBUSCFG (MSM_USB_BASE + 0x0090)
#define USB_ROC_AHB_MODE (MSM_USB_BASE + 0x0090)
#define USB_CAPLENGTH (MSM_USB_BASE + 0x0100) /* 8 bit */
#define USB_HCIVERSION (MSM_USB_BASE + 0x0102) /* 16 bit */
@ -82,12 +104,26 @@
#define USB_ENDPTCTRL(n) (MSM_USB_BASE + 0x01C0 + (4 * (n)))
#define USBCMD_RESET 2
#define USBCMD_ATTACH 1
#define USBCMD_ATDTW (1 << 14)
#define USBCMD_RESET 2
#define USBCMD_ATTACH 1
#define USBCMD_RS (1 << 0) /* run/stop bit */
#define USBCMD_ATDTW (1 << 14)
#define ASYNC_INTR_CTRL (1 << 29)
#define ULPI_STP_CTRL (1 << 30)
#define USBCMD_ITC(n) (n << 16)
#define USBCMD_ITC_MASK (0xFF << 16)
#define USBMODE_DEVICE 2
#define USBMODE_HOST 3
/* Redefining SDIS bit as it defined incorrectly in ehci.h. */
#ifdef USBMODE_SDIS
#undef USBMODE_SDIS
#endif
#define USBMODE_SDIS (1 << 4) /* stream disable */
#define USBMODE_VBUS (1 << 5) /* vbus power select */
struct ept_queue_head {
unsigned config;
@ -138,7 +174,7 @@ struct ept_queue_item {
#define STS_NAKI (1 << 16) /* */
#define STS_SLI (1 << 8) /* R/WC - suspend state entered */
#define STS_SRI (1 << 7) /* R/WC - SOF recv'd */
#define STS_URI (1 << 6) /* R/WC - RESET recv'd - write to clear */
#define STS_URI (1 << 6) /* R/WC - RESET recv'd */
#define STS_FRI (1 << 3) /* R/WC - Frame List Rollover */
#define STS_PCI (1 << 2) /* R/WC - Port Change Detect */
#define STS_UEI (1 << 1) /* R/WC - USB Error */
@ -175,6 +211,38 @@ struct ept_queue_item {
#define CTRL_RXT_INT (3 << 2)
#define CTRL_RXT_EP_TYPE_SHIFT 2
#if defined(CONFIG_ARCH_MSM7X30) || defined(CONFIG_ARCH_MSM8X60)
#define ULPI_DIGOUT_CTRL 0X36
#define ULPI_CDR_AUTORESET (1 << 1)
#else
#define ULPI_DIGOUT_CTRL 0X31
#define ULPI_CDR_AUTORESET (1 << 5)
#endif
#define ULPI_FUNC_CTRL_CLR (0x06)
#define ULPI_IFC_CTRL_CLR (0x09)
#define ULPI_AMPLITUDE_MAX (0x0C)
#define ULPI_OTG_CTRL (0x0B)
#define ULPI_OTG_CTRL_CLR (0x0C)
#define ULPI_INT_RISE_CLR (0x0F)
#define ULPI_INT_FALL_CLR (0x12)
#define ULPI_DEBUG_REG (0x15)
#define ULPI_SCRATCH_REG (0x16)
#define ULPI_CONFIG_REG1 (0x30)
#define ULPI_CONFIG_REG2 (0X31)
#define ULPI_CONFIG_REG (0x31)
#define ULPI_CONFIG_REG3 (0X32)
#define ULPI_CHG_DETECT_REG (0x34)
#define ULPI_PRE_EMPHASIS_MASK (3 << 4)
#define ULPI_DRV_AMPL_MASK (3 << 2)
#define ULPI_ONCLOCK (1 << 6)
#define ULPI_FUNC_SUSPENDM (1 << 6)
#define ULPI_IDPU (1 << 0)
#define ULPI_HOST_DISCONNECT (1 << 0)
#define ULPI_VBUS_VALID (1 << 1)
#define ULPI_SE1_GATE (1 << 2)
#define ULPI_SESS_END (1 << 3)
#define ULPI_ID_GND (1 << 4)
#define ULPI_WAKEUP (1 << 31)
#define ULPI_RUN (1 << 30)
#define ULPI_WRITE (1 << 29)
@ -184,12 +252,17 @@ struct ept_queue_item {
#define ULPI_DATA(n) ((n) & 255)
#define ULPI_DATA_READ(n) (((n) >> 8) & 255)
#define ULPI_DEBUG_REG (0x15)
#define ULPI_SCRATCH_REG (0x16)
/* control charger detection by ULPI or externally */
#define ULPI_EXTCHGCTRL_65NM (1 << 2)
#define ULPI_EXTCHGCTRL_180NM (1 << 3)
#define ULPI_FUNC_CTRL_CLR (0x06)
#define ULPI_FUNC_SUSPENDM (1 << 6)
/* charger detection power on control */
#define ULPI_CHGDETON (1 << 1)
/* enable charger detection */
#define ULPI_CHGDETEN (1 << 0)
#define ULPI_CHGTYPE_65NM (1 << 3)
#define ULPI_CHGTYPE_180NM (1 << 4)
/* USB_PORTSC bits for determining port speed */
#define PORTSC_PSPD_FS (0 << 26)
@ -218,6 +291,30 @@ struct ept_queue_item {
#define PORTSC_FPR (1 << 6) /* R/W - State normal => suspend */
#define PORTSC_SUSP (1 << 7) /* Read - Port in suspend state */
#define PORTSC_LS (3 << 10) /* Read - Port's Line status */
#define PORTSC_PHCD (1 << 23) /* phy suspend mode */
#define PORTSC_CCS (1 << 0) /* current connect status */
#define PORTSC_PTS (3 << 30)
#define PORTSC_PTS_ULPI (2 << 30)
#define PORTSC_PTS_SERIAL (3 << 30)
#define PORTSC_PORT_SPEED_FULL 0x00000000
#define PORTSC_PORT_SPEED_LOW 0x04000000
#define PORTSC_PORT_SPEED_HIGH 0x08000000
#define PORTSC_PORT_SPEED_MASK 0x0c000000
#define SBUSCFG_AHBBRST_INCR4 0x01
#define ULPI_USBINTR_ENABLE_FALLING_S 0x11
#define ULPI_USBINTR_ENABLE_FALLING_C 0x12
#define ULPI_USBINTR_STATUS 0x13
#define ULPI_USBINTR_ENABLE_RASING_S 0x0E
#define ULPI_USBINTR_ENABLE_RASING_C 0x0F
#define ULPI_SESSION_END_RAISE (1 << 3)
#define ULPI_SESSION_END_FALL (1 << 3)
#define ULPI_SESSION_VALID_RAISE (1 << 2)
#define ULPI_SESSION_VALID_FALL (1 << 2)
#define ULPI_VBUS_VALID_RAISE (1 << 1)
#define ULPI_VBUS_VALID_FALL (1 << 1)
#define PORTSC_PHCD (1 << 23) /* phy suspend mode */
#define PORTSC_CCS (1 << 0) /* current connect status */
#define PORTSC_PTS (3 << 30)
@ -238,6 +335,9 @@ struct ept_queue_item {
#define PORTSC_PTC_SE0_NAK (0x03 << 16)
#define PORTSC_PTC_TST_PKT (0x04 << 16)
#define USBH (1 << 15)
#define USB_PHY (1 << 18)
#define PORTSC_PTS_MASK (3 << 30)
#define PORTSC_PTS_ULPI (2 << 30)
#define PORTSC_PTS_SERIAL (3 << 30)
@ -250,5 +350,9 @@ struct ept_queue_item {
#define PORTSC_PHCD (1 << 23) /* phy suspend mode */
#define ULPI_DEBUG 0x15
#define ULPI_CLOCK_SUSPENDM (1 << 3)
#define ULPI_SUSPENDM (1 << 6)
#endif /* _USB_FUNCTION_MSM_HSUSB_HW_H */
#define ULPI_CALIB_STS (1 << 7)
#define ULPI_CALIB_VAL(x) (x & 0x7C)
#endif /* __LINUX_USB_GADGET_MSM72K_UDC_H__ */

View File

@ -21,11 +21,11 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/utsname.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/usb/android_composite.h>
#include <linux/usb/ch9.h>
@ -33,6 +33,8 @@
#include <linux/usb/gadget.h>
#include "gadget_chips.h"
#include <linux/wakelock.h>
#include <mach/perflock.h>
/*
* Kbuild is not very cooperative with respect to linking separately
@ -52,6 +54,8 @@ MODULE_LICENSE("GPL");
MODULE_VERSION("1.0");
static const char longname[] = "Gadget Android";
static struct wake_lock usb_rndis_idle_wake_lock;
static struct perf_lock usb_rndis_perf_lock;
enum {
USB_FUNCTION_UMS = 0,
@ -478,11 +482,14 @@ int android_switch_function(unsigned func)
dev->cdev->desc.bDeviceClass = USB_CLASS_PER_INTERFACE;
#ifdef CONFIG_USB_GADGET_MSM_72K
/* avoid sending a disconnect switch event until after we disconnect */
msm_hsusb_request_reset();
#else
/* force reenumeration */
if (dev->cdev && dev->cdev->gadget &&
dev->cdev->gadget->speed != USB_SPEED_UNKNOWN) {
/* avoid sending a disconnect switch event until after we disconnect */
usb_gadget_disconnect(dev->cdev->gadget);
msleep(10);
usb_gadget_connect(dev->cdev->gadget);
@ -500,6 +507,7 @@ void android_enable_function(struct usb_function *f, int enable)
if (!!f->hidden != disable) {
f->hidden = disable;
#ifdef CONFIG_USB_ANDROID_RNDIS
if (!strcmp(f->name, "rndis")) {
struct usb_function *func;
@ -565,6 +573,9 @@ static int __init android_probe(struct platform_device *pdev)
printk(KERN_INFO "android_probe pdata: %p\n", pdata);
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
if (pdata) {
dev->products = pdata->products;
dev->num_products = pdata->num_products;
@ -593,8 +604,26 @@ static int __init android_probe(struct platform_device *pdev)
return usb_composite_register(&android_usb_driver);
}
static int andr_runtime_suspend(struct device *dev)
{
dev_dbg(dev, "pm_runtime: suspending...\n");
return 0;
}
static int andr_runtime_resume(struct device *dev)
{
dev_dbg(dev, "pm_runtime: resuming...\n");
return 0;
}
static struct dev_pm_ops andr_dev_pm_ops = {
.runtime_suspend = andr_runtime_suspend,
.runtime_resume = andr_runtime_resume,
};
static struct platform_driver android_platform_driver = {
.driver = { .name = "android_usb", },
.driver = {
.name = "android_usb",
.pm = &andr_dev_pm_ops},
.probe = android_probe,
};
@ -612,6 +641,8 @@ static int __init init(void)
dev->product_id = PRODUCT_ID;
_android_dev = dev;
wake_lock_init(&usb_rndis_idle_wake_lock, WAKE_LOCK_IDLE, "rndis_idle_lock");
perf_lock_init(&usb_rndis_perf_lock, PERF_LOCK_HIGHEST, "rndis");
return platform_driver_register(&android_platform_driver);
}
module_init(init);

View File

@ -31,13 +31,11 @@
#include <linux/miscdevice.h>
#include <linux/usb/android_composite.h>
#include <mach/board.h>
#define BULK_BUFFER_SIZE 4096
/* number of tx requests to allocate */
#define TX_REQ_MAX 4
#define RX_REQ_MAX 32
static const char shortname[] = "android_adb";
@ -57,18 +55,11 @@ struct adb_dev {
atomic_t open_excl;
struct list_head tx_idle;
struct list_head rx_idle;
struct list_head rx_done;
wait_queue_head_t read_wq;
wait_queue_head_t write_wq;
/* the request we're currently reading from */
struct usb_request *read_req;
unsigned char *read_buf;
unsigned read_count;
int maxsize;
struct usb_request *rx_req;
int rx_done;
};
static struct usb_interface_descriptor adb_interface_desc = {
@ -125,22 +116,6 @@ static struct usb_descriptor_header *hs_adb_descs[] = {
NULL,
};
/* string descriptors: */
static struct usb_string adb_string_defs[] = {
[0].s = "ADB",
{ } /* end of list */
};
static struct usb_gadget_strings adb_string_table = {
.language = 0x0409, /* en-us */
.strings = adb_string_defs,
};
static struct usb_gadget_strings *adb_strings[] = {
&adb_string_table,
NULL,
};
/* temporary variable used between adb_open() and adb_gadget_bind() */
static struct adb_dev *_adb_dev;
@ -179,12 +154,16 @@ static void adb_request_free(struct usb_request *req, struct usb_ep *ep)
static inline int _lock(atomic_t *excl)
{
int ret = -1;
preempt_disable();
if (atomic_inc_return(excl) == 1) {
return 0;
} else {
ret = 0;
} else
atomic_dec(excl);
return -1;
}
preempt_enable();
return ret;
}
static inline void _unlock(atomic_t *excl)
@ -236,11 +215,9 @@ static void adb_complete_out(struct usb_ep *ep, struct usb_request *req)
{
struct adb_dev *dev = _adb_dev;
if (req->status != 0) {
dev->rx_done = 1;
if (req->status != 0)
dev->error = 1;
req_put(dev, &dev->rx_idle, req);
} else
req_put(dev, &dev->rx_done, req);
wake_up(&dev->read_wq);
}
@ -275,13 +252,11 @@ static int __init create_bulk_endpoints(struct adb_dev *dev,
dev->ep_out = ep;
/* now allocate requests for our endpoints */
for (i = 0; i < RX_REQ_MAX; i++) {
req = adb_request_new(dev->ep_out, 512);
if (!req)
goto fail;
req->complete = adb_complete_out;
req_put(dev, &dev->rx_idle, req);
}
req = adb_request_new(dev->ep_out, BULK_BUFFER_SIZE);
if (!req)
goto fail;
req->complete = adb_complete_out;
dev->rx_req = req;
for (i = 0; i < TX_REQ_MAX; i++) {
req = adb_request_new(dev->ep_in, BULK_BUFFER_SIZE);
@ -329,71 +304,41 @@ static ssize_t adb_read(struct file *fp, char __user *buf,
r = -EIO;
goto done;
}
while (count > 0) {
if (dev->error) {
r = -EIO;
break;
}
/* if we have idle read requests, get them queued */
while ((req = req_get(dev, &dev->rx_idle))) {
requeue_req:
req->length = dev->maxsize?dev->maxsize:512;
ret = usb_ep_queue(dev->ep_out, req, GFP_ATOMIC);
if (ret < 0) {
printk(KERN_INFO "adb_read: failed to queue req (%d)\n", ret);
r = -EIO;
dev->error = 1;
req_put(dev, &dev->rx_idle, req);
goto done;
}
}
/* if we have data pending, give it to userspace */
if (dev->read_count > 0) {
xfer = (dev->read_count < count) ? dev->read_count : count;
if (copy_to_user(buf, dev->read_buf, xfer)) {
r = -EFAULT;
break;
}
dev->read_buf += xfer;
dev->read_count -= xfer;
buf += xfer;
count -= xfer;
/* if we've emptied the buffer, release the request */
if (dev->read_count == 0) {
req_put(dev, &dev->rx_idle, dev->read_req);
dev->read_req = 0;
}
continue;
}
/* wait for a request to complete */
req = 0;
ret = wait_event_interruptible(dev->read_wq,
((req = req_get(dev, &dev->rx_done)) || dev->error));
if (req != 0) {
/* if we got a 0-len one we need to put it back into
** service. if we made it the current read req we'd
** be stuck forever
*/
if (req->actual == 0)
goto requeue_req;
dev->read_req = req;
dev->read_count = req->actual;
dev->read_buf = req->buf;
}
if (ret < 0) {
r = ret;
break;
}
/* queue a request */
req = dev->rx_req;
req->length = count;
dev->rx_done = 0;
ret = usb_ep_queue(dev->ep_out, req, GFP_ATOMIC);
if (ret < 0) {
DBG(cdev, "adb_read: failed to queue req %p (%d)\n", req, ret);
r = -EIO;
dev->error = 1;
goto done;
} else {
DBG(cdev, "rx %p queue\n", req);
}
/* wait for a request to complete */
ret = wait_event_interruptible(dev->read_wq, dev->rx_done);
if (ret < 0) {
dev->error = 1;
r = ret;
goto done;
}
if (!dev->error) {
/* If we got a 0-len packet, throw it back and try again. */
if (req->actual == 0)
goto requeue_req;
DBG(cdev, "rx %p %d\n", req, req->actual);
xfer = (req->actual < count) ? req->actual : count;
if (copy_to_user(buf, req->buf, xfer))
r = -EFAULT;
} else
r = -EIO;
done:
_unlock(&dev->read_excl);
DBG(cdev, "adb_read returning %d\n", r);
@ -468,9 +413,25 @@ static ssize_t adb_write(struct file *fp, const char __user *buf,
static int adb_open(struct inode *ip, struct file *fp)
{
printk(KERN_INFO "adb_open\n");
if (_lock(&_adb_dev->open_excl))
static unsigned long last_print;
static unsigned long count = 0;
if (++count == 1)
last_print = jiffies;
else {
if (!time_before(jiffies, last_print + HZ/2))
count = 0;
last_print = jiffies;
}
if (_lock(&_adb_dev->open_excl)) {
cpu_relax();
return -EBUSY;
}
if (count < 5)
printk(KERN_INFO "adb_open(%s)\n", current->comm);
fp->private_data = _adb_dev;
@ -482,7 +443,19 @@ static int adb_open(struct inode *ip, struct file *fp)
static int adb_release(struct inode *ip, struct file *fp)
{
printk(KERN_INFO "adb_release\n");
static unsigned long last_print;
static unsigned long count = 0;
if (++count == 1)
last_print = jiffies;
else {
if (!time_before(jiffies, last_print + HZ/2))
count = 0;
last_print = jiffies;
}
if (count < 5)
printk(KERN_INFO "adb_release\n");
_unlock(&_adb_dev->open_excl);
return 0;
}
@ -580,10 +553,7 @@ adb_function_unbind(struct usb_configuration *c, struct usb_function *f)
spin_lock_irq(&dev->lock);
while ((req = req_get(dev, &dev->rx_done)))
adb_request_free(req, dev->ep_out);
while ((req = req_get(dev, &dev->rx_idle)))
adb_request_free(req, dev->ep_out);
adb_request_free(dev->rx_req, dev->ep_out);
while ((req = req_get(dev, &dev->tx_idle)))
adb_request_free(req, dev->ep_in);
@ -603,7 +573,6 @@ static int adb_function_set_alt(struct usb_function *f,
struct adb_dev *dev = func_to_dev(f);
struct usb_composite_dev *cdev = f->config->cdev;
int ret;
struct usb_request *req;
DBG(cdev, "adb_function_set_alt intf: %d alt: %d\n", intf, alt);
ret = usb_ep_enable(dev->ep_in,
@ -620,17 +589,7 @@ static int adb_function_set_alt(struct usb_function *f,
usb_ep_disable(dev->ep_in);
return ret;
}
if (cdev->gadget->speed == USB_SPEED_FULL)
dev->maxsize = 64;
else
dev->maxsize = 512;
printk(KERN_INFO "%s: maxsize = %d\n", __func__, dev->maxsize);
/* retire any completed rx requests from previous session */
while ((req = req_get(dev, &dev->rx_done)))
req_put(dev, &dev->rx_idle, req);
dev->online = !dev->function.hidden;
dev->online = 1;
/* readers may be blocked waiting for us to go online */
wake_up(&dev->read_wq);
@ -645,7 +604,6 @@ static void adb_function_disable(struct usb_function *f)
DBG(cdev, "adb_function_disable\n");
dev->online = 0;
dev->error = 1;
dev->maxsize = 0;
usb_ep_disable(dev->ep_in);
usb_ep_disable(dev->ep_out);
@ -676,27 +634,18 @@ static int adb_bind_config(struct usb_configuration *c)
atomic_set(&dev->write_excl, 0);
INIT_LIST_HEAD(&dev->tx_idle);
INIT_LIST_HEAD(&dev->rx_idle);
INIT_LIST_HEAD(&dev->rx_done);
ret = usb_string_id(c->cdev);
if (ret < 0)
return ret;
adb_string_defs[0].id = ret;
adb_interface_desc.iInterface = ret;
dev->cdev = c->cdev;
dev->function.name = "adb";
dev->function.strings = adb_strings;
dev->function.descriptors = fs_adb_descs;
dev->function.hs_descriptors = hs_adb_descs;
dev->function.bind = adb_function_bind;
dev->function.unbind = adb_function_unbind;
dev->function.set_alt = adb_function_set_alt;
dev->function.disable = adb_function_disable;
dev->maxsize = 512;
if (board_mfg_mode() != 2)
dev->function.hidden = 1;
/* start disabled */
// dev->function.disabled = 1;
/* _adb_dev must be set before calling usb_gadget_register_driver */
_adb_dev = dev;

View File

@ -4,6 +4,8 @@
* Copyright (C) 2003-2005,2008 David Brownell
* Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger
* Copyright (C) 2008 Nokia Corporation
* Copyright (C) 2009 Samsung Electronics
* Author: Michal Nazarewicz (m.nazarewicz@samsung.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -22,6 +24,7 @@
/* #define VERBOSE_DEBUG */
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/etherdevice.h>
@ -84,6 +87,8 @@ struct f_rndis {
struct gether port;
u8 ctrl_id, data_id;
u8 ethaddr[ETH_ALEN];
u32 vendorID;
const char *manufacturer;
int config;
struct rndis_ep_descs fs;
@ -95,6 +100,8 @@ struct f_rndis {
atomic_t notify_count;
};
static char manufacturer [10] = "HTC";
static u32 vendorID = 0x0bb4;
static inline struct f_rndis *func_to_rndis(struct usb_function *f)
{
return container_of(f, struct f_rndis, port.func);
@ -412,8 +419,7 @@ rndis_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
*/
case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
| USB_CDC_SEND_ENCAPSULATED_COMMAND:
if (w_length > req->length || w_value
|| w_index != rndis->ctrl_id)
if (w_value || w_index != rndis->ctrl_id)
goto invalid;
/* read the request; process it later */
value = w_length;
@ -820,6 +826,8 @@ int __init rndis_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
goto fail;
memcpy(rndis->ethaddr, ethaddr, ETH_ALEN);
rndis->vendorID = vendorID;
rndis->manufacturer = manufacturer;
/* RNDIS activates when the host changes this filter */
rndis->port.cdc_filter = 0;

File diff suppressed because it is too large Load Diff

View File

@ -291,9 +291,13 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_VENDOR_DESCRIPTION:
pr_debug("%s: OID_GEN_VENDOR_DESCRIPTION\n", __func__);
length = strlen (rndis_per_dev_params [configNr].vendorDescr);
memcpy (outbuf,
rndis_per_dev_params [configNr].vendorDescr, length);
if ( rndis_per_dev_params [configNr].vendorDescr ) {
length = strlen (rndis_per_dev_params [configNr].vendorDescr);
memcpy (outbuf,
rndis_per_dev_params [configNr].vendorDescr, length);
} else {
outbuf[0] = 0;
}
retval = 0;
break;