Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6 into avr32-arch
此提交包含在:
@@ -191,6 +191,7 @@ config USB_GADGET_OMAP
|
||||
boolean "OMAP USB Device Controller"
|
||||
depends on ARCH_OMAP
|
||||
select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_H4_OTG
|
||||
select USB_OTG_UTILS if ARCH_OMAP
|
||||
help
|
||||
Many Texas Instruments OMAP processors have flexible full
|
||||
speed USB device controllers, with support for up to 30
|
||||
@@ -253,6 +254,7 @@ config USB_PXA25X_SMALL
|
||||
config USB_GADGET_PXA27X
|
||||
boolean "PXA 27x"
|
||||
depends on ARCH_PXA && PXA27x
|
||||
select USB_OTG_UTILS
|
||||
help
|
||||
Intel's PXA 27x series XScale ARM v5TE processors include
|
||||
an integrated full speed USB 1.1 device controller.
|
||||
|
@@ -551,7 +551,7 @@ udc_alloc_request(struct usb_ep *usbep, gfp_t gfp)
|
||||
dma_desc->status = AMD_ADDBITS(dma_desc->status,
|
||||
UDC_DMA_STP_STS_BS_HOST_BUSY,
|
||||
UDC_DMA_STP_STS_BS);
|
||||
dma_desc->bufptr = __constant_cpu_to_le32(DMA_DONT_USE);
|
||||
dma_desc->bufptr = cpu_to_le32(DMA_DONT_USE);
|
||||
req->td_data = dma_desc;
|
||||
req->td_data_last = NULL;
|
||||
req->chain_len = 1;
|
||||
|
@@ -1017,7 +1017,7 @@ static struct usb_endpoint_descriptor usba_ep0_desc = {
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = 0,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_CONTROL,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(64),
|
||||
.wMaxPacketSize = cpu_to_le16(64),
|
||||
/* FIXME: I have no idea what to put here */
|
||||
.bInterval = 1,
|
||||
};
|
||||
@@ -1207,21 +1207,21 @@ static int do_test_mode(struct usba_udc *udc)
|
||||
/* Avoid overly long expressions */
|
||||
static inline bool feature_is_dev_remote_wakeup(struct usb_ctrlrequest *crq)
|
||||
{
|
||||
if (crq->wValue == __constant_cpu_to_le16(USB_DEVICE_REMOTE_WAKEUP))
|
||||
if (crq->wValue == cpu_to_le16(USB_DEVICE_REMOTE_WAKEUP))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool feature_is_dev_test_mode(struct usb_ctrlrequest *crq)
|
||||
{
|
||||
if (crq->wValue == __constant_cpu_to_le16(USB_DEVICE_TEST_MODE))
|
||||
if (crq->wValue == cpu_to_le16(USB_DEVICE_TEST_MODE))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool feature_is_ep_halt(struct usb_ctrlrequest *crq)
|
||||
{
|
||||
if (crq->wValue == __constant_cpu_to_le16(USB_ENDPOINT_HALT))
|
||||
if (crq->wValue == cpu_to_le16(USB_ENDPOINT_HALT))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -1239,7 +1239,7 @@ static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep,
|
||||
status = cpu_to_le16(udc->devstatus);
|
||||
} else if (crq->bRequestType
|
||||
== (USB_DIR_IN | USB_RECIP_INTERFACE)) {
|
||||
status = __constant_cpu_to_le16(0);
|
||||
status = cpu_to_le16(0);
|
||||
} else if (crq->bRequestType
|
||||
== (USB_DIR_IN | USB_RECIP_ENDPOINT)) {
|
||||
struct usba_ep *target;
|
||||
@@ -1250,12 +1250,12 @@ static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep,
|
||||
|
||||
status = 0;
|
||||
if (is_stalled(udc, target))
|
||||
status |= __constant_cpu_to_le16(1);
|
||||
status |= cpu_to_le16(1);
|
||||
} else
|
||||
goto delegate;
|
||||
|
||||
/* Write directly to the FIFO. No queueing is done. */
|
||||
if (crq->wLength != __constant_cpu_to_le16(sizeof(status)))
|
||||
if (crq->wLength != cpu_to_le16(sizeof(status)))
|
||||
goto stall;
|
||||
ep->state = DATA_STAGE_IN;
|
||||
__raw_writew(status, ep->fifo);
|
||||
@@ -1274,7 +1274,7 @@ static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep,
|
||||
} else if (crq->bRequestType == USB_RECIP_ENDPOINT) {
|
||||
struct usba_ep *target;
|
||||
|
||||
if (crq->wLength != __constant_cpu_to_le16(0)
|
||||
if (crq->wLength != cpu_to_le16(0)
|
||||
|| !feature_is_ep_halt(crq))
|
||||
goto stall;
|
||||
target = get_ep_by_addr(udc, le16_to_cpu(crq->wIndex));
|
||||
@@ -1308,7 +1308,7 @@ static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep,
|
||||
} else if (crq->bRequestType == USB_RECIP_ENDPOINT) {
|
||||
struct usba_ep *target;
|
||||
|
||||
if (crq->wLength != __constant_cpu_to_le16(0)
|
||||
if (crq->wLength != cpu_to_le16(0)
|
||||
|| !feature_is_ep_halt(crq))
|
||||
goto stall;
|
||||
|
||||
@@ -1514,7 +1514,7 @@ restart:
|
||||
*/
|
||||
ep->state = DATA_STAGE_IN;
|
||||
} else {
|
||||
if (crq.crq.wLength != __constant_cpu_to_le16(0))
|
||||
if (crq.crq.wLength != cpu_to_le16(0))
|
||||
ep->state = DATA_STAGE_OUT;
|
||||
else
|
||||
ep->state = STATUS_STAGE_IN;
|
||||
|
@@ -66,7 +66,7 @@ static struct usb_device_descriptor device_desc = {
|
||||
.bLength = sizeof device_desc,
|
||||
.bDescriptorType = USB_DT_DEVICE,
|
||||
|
||||
.bcdUSB = __constant_cpu_to_le16(0x0200),
|
||||
.bcdUSB = cpu_to_le16(0x0200),
|
||||
|
||||
.bDeviceClass = USB_CLASS_COMM,
|
||||
.bDeviceSubClass = 0,
|
||||
@@ -74,8 +74,8 @@ static struct usb_device_descriptor device_desc = {
|
||||
/* .bMaxPacketSize0 = f(hardware) */
|
||||
|
||||
/* Vendor and product id can be overridden by module parameters. */
|
||||
.idVendor = __constant_cpu_to_le16(CDC_VENDOR_NUM),
|
||||
.idProduct = __constant_cpu_to_le16(CDC_PRODUCT_NUM),
|
||||
.idVendor = cpu_to_le16(CDC_VENDOR_NUM),
|
||||
.idProduct = cpu_to_le16(CDC_PRODUCT_NUM),
|
||||
/* .bcdDevice = f(hardware) */
|
||||
/* .iManufacturer = DYNAMIC */
|
||||
/* .iProduct = DYNAMIC */
|
||||
@@ -193,7 +193,7 @@ static int __init cdc_bind(struct usb_composite_dev *cdev)
|
||||
gadget->name,
|
||||
cdc_config_driver.label);
|
||||
device_desc.bcdDevice =
|
||||
__constant_cpu_to_le16(0x0300 | 0x0099);
|
||||
cpu_to_le16(0x0300 | 0x0099);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -56,7 +56,6 @@
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/kernel.h>
|
||||
@@ -2626,7 +2625,7 @@ static int udc_probe(struct device *dev, void __iomem *regs, const char *name)
|
||||
INIT_LIST_HEAD(&udc->gadget.ep_list);
|
||||
udc->gadget.ep0 = NULL;
|
||||
|
||||
strcpy(udc->gadget.dev.bus_id, "gadget");
|
||||
dev_set_name(&udc->gadget.dev, "gadget");
|
||||
udc->gadget.dev.dma_mask = dev->dma_mask;
|
||||
udc->gadget.dev.parent = dev;
|
||||
udc->gadget.dev.release = udc_release;
|
||||
|
@@ -149,16 +149,17 @@ done:
|
||||
int usb_function_deactivate(struct usb_function *function)
|
||||
{
|
||||
struct usb_composite_dev *cdev = function->config->cdev;
|
||||
unsigned long flags;
|
||||
int status = 0;
|
||||
|
||||
spin_lock(&cdev->lock);
|
||||
spin_lock_irqsave(&cdev->lock, flags);
|
||||
|
||||
if (cdev->deactivations == 0)
|
||||
status = usb_gadget_disconnect(cdev->gadget);
|
||||
if (status == 0)
|
||||
cdev->deactivations++;
|
||||
|
||||
spin_unlock(&cdev->lock);
|
||||
spin_unlock_irqrestore(&cdev->lock, flags);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -683,6 +684,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
|
||||
struct usb_request *req = cdev->req;
|
||||
int value = -EOPNOTSUPP;
|
||||
u16 w_index = le16_to_cpu(ctrl->wIndex);
|
||||
u8 intf = w_index & 0xFF;
|
||||
u16 w_value = le16_to_cpu(ctrl->wValue);
|
||||
u16 w_length = le16_to_cpu(ctrl->wLength);
|
||||
struct usb_function *f = NULL;
|
||||
@@ -769,10 +771,10 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
|
||||
goto unknown;
|
||||
if (!cdev->config || w_index >= MAX_CONFIG_INTERFACES)
|
||||
break;
|
||||
f = cdev->config->interface[w_index];
|
||||
f = cdev->config->interface[intf];
|
||||
if (!f)
|
||||
break;
|
||||
if (w_value && !f->get_alt)
|
||||
if (w_value && !f->set_alt)
|
||||
break;
|
||||
value = f->set_alt(f, w_index, w_value);
|
||||
break;
|
||||
@@ -781,7 +783,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
|
||||
goto unknown;
|
||||
if (!cdev->config || w_index >= MAX_CONFIG_INTERFACES)
|
||||
break;
|
||||
f = cdev->config->interface[w_index];
|
||||
f = cdev->config->interface[intf];
|
||||
if (!f)
|
||||
break;
|
||||
/* lots of interfaces only need altsetting zero... */
|
||||
@@ -808,7 +810,7 @@ unknown:
|
||||
*/
|
||||
if ((ctrl->bRequestType & USB_RECIP_MASK)
|
||||
== USB_RECIP_INTERFACE) {
|
||||
f = cdev->config->interface[w_index];
|
||||
f = cdev->config->interface[intf];
|
||||
if (f && f->setup)
|
||||
value = f->setup(f, ctrl);
|
||||
else
|
||||
@@ -1012,7 +1014,7 @@ composite_suspend(struct usb_gadget *gadget)
|
||||
struct usb_composite_dev *cdev = get_gadget_data(gadget);
|
||||
struct usb_function *f;
|
||||
|
||||
/* REVISIT: should we have config and device level
|
||||
/* REVISIT: should we have config level
|
||||
* suspend/resume callbacks?
|
||||
*/
|
||||
DBG(cdev, "suspend\n");
|
||||
@@ -1022,6 +1024,8 @@ composite_suspend(struct usb_gadget *gadget)
|
||||
f->suspend(f);
|
||||
}
|
||||
}
|
||||
if (composite->suspend)
|
||||
composite->suspend(cdev);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1030,10 +1034,12 @@ composite_resume(struct usb_gadget *gadget)
|
||||
struct usb_composite_dev *cdev = get_gadget_data(gadget);
|
||||
struct usb_function *f;
|
||||
|
||||
/* REVISIT: should we have config and device level
|
||||
/* REVISIT: should we have config level
|
||||
* suspend/resume callbacks?
|
||||
*/
|
||||
DBG(cdev, "resume\n");
|
||||
if (composite->resume)
|
||||
composite->resume(cdev);
|
||||
if (cdev->config) {
|
||||
list_for_each_entry(f, &cdev->config->functions, list) {
|
||||
if (f->resume)
|
||||
|
@@ -1437,7 +1437,7 @@ restart:
|
||||
}
|
||||
if (urb->transfer_buffer_length > 1)
|
||||
buf [1] = 0;
|
||||
urb->actual_length = min (2,
|
||||
urb->actual_length = min_t(u32, 2,
|
||||
urb->transfer_buffer_length);
|
||||
value = 0;
|
||||
status = 0;
|
||||
@@ -1626,7 +1626,7 @@ static int dummy_hub_control (
|
||||
hub_descriptor ((struct usb_hub_descriptor *) buf);
|
||||
break;
|
||||
case GetHubStatus:
|
||||
*(__le32 *) buf = __constant_cpu_to_le32 (0);
|
||||
*(__le32 *) buf = cpu_to_le32 (0);
|
||||
break;
|
||||
case GetPortStatus:
|
||||
if (wIndex != 1)
|
||||
|
@@ -148,7 +148,7 @@ ep_matches (
|
||||
return 0;
|
||||
|
||||
/* BOTH: "high bandwidth" works only at high speed */
|
||||
if ((desc->wMaxPacketSize & __constant_cpu_to_le16(3<<11))) {
|
||||
if ((desc->wMaxPacketSize & cpu_to_le16(3<<11))) {
|
||||
if (!gadget->is_dualspeed)
|
||||
return 0;
|
||||
/* configure your hardware with enough buffering!! */
|
||||
|
@@ -156,7 +156,7 @@ static struct usb_device_descriptor device_desc = {
|
||||
.bLength = sizeof device_desc,
|
||||
.bDescriptorType = USB_DT_DEVICE,
|
||||
|
||||
.bcdUSB = __constant_cpu_to_le16 (0x0200),
|
||||
.bcdUSB = cpu_to_le16 (0x0200),
|
||||
|
||||
.bDeviceClass = USB_CLASS_COMM,
|
||||
.bDeviceSubClass = 0,
|
||||
@@ -167,8 +167,8 @@ static struct usb_device_descriptor device_desc = {
|
||||
* we support. (As does bNumConfigurations.) These values can
|
||||
* also be overridden by module parameters.
|
||||
*/
|
||||
.idVendor = __constant_cpu_to_le16 (CDC_VENDOR_NUM),
|
||||
.idProduct = __constant_cpu_to_le16 (CDC_PRODUCT_NUM),
|
||||
.idVendor = cpu_to_le16 (CDC_VENDOR_NUM),
|
||||
.idProduct = cpu_to_le16 (CDC_PRODUCT_NUM),
|
||||
/* .bcdDevice = f(hardware) */
|
||||
/* .iManufacturer = DYNAMIC */
|
||||
/* .iProduct = DYNAMIC */
|
||||
@@ -318,7 +318,7 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
|
||||
gadget->name,
|
||||
eth_config_driver.label);
|
||||
device_desc.bcdDevice =
|
||||
__constant_cpu_to_le16(0x0300 | 0x0099);
|
||||
cpu_to_le16(0x0300 | 0x0099);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -125,7 +125,7 @@ static struct usb_cdc_header_desc acm_header_desc __initdata = {
|
||||
.bLength = sizeof(acm_header_desc),
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
.bDescriptorSubType = USB_CDC_HEADER_TYPE,
|
||||
.bcdCDC = __constant_cpu_to_le16(0x0110),
|
||||
.bcdCDC = cpu_to_le16(0x0110),
|
||||
};
|
||||
|
||||
static struct usb_cdc_call_mgmt_descriptor
|
||||
@@ -159,7 +159,7 @@ static struct usb_endpoint_descriptor acm_fs_notify_desc __initdata = {
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = USB_DIR_IN,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_INT,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(GS_NOTIFY_MAXPACKET),
|
||||
.wMaxPacketSize = cpu_to_le16(GS_NOTIFY_MAXPACKET),
|
||||
.bInterval = 1 << GS_LOG2_NOTIFY_INTERVAL,
|
||||
};
|
||||
|
||||
@@ -197,7 +197,7 @@ static struct usb_endpoint_descriptor acm_hs_notify_desc __initdata = {
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = USB_DIR_IN,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_INT,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(GS_NOTIFY_MAXPACKET),
|
||||
.wMaxPacketSize = cpu_to_le16(GS_NOTIFY_MAXPACKET),
|
||||
.bInterval = GS_LOG2_NOTIFY_INTERVAL+4,
|
||||
};
|
||||
|
||||
@@ -205,14 +205,14 @@ static struct usb_endpoint_descriptor acm_hs_in_desc __initdata = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(512),
|
||||
.wMaxPacketSize = cpu_to_le16(512),
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor acm_hs_out_desc __initdata = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(512),
|
||||
.wMaxPacketSize = cpu_to_le16(512),
|
||||
};
|
||||
|
||||
static struct usb_descriptor_header *acm_hs_function[] __initdata = {
|
||||
|
@@ -130,7 +130,7 @@ static struct usb_cdc_header_desc ecm_header_desc __initdata = {
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
.bDescriptorSubType = USB_CDC_HEADER_TYPE,
|
||||
|
||||
.bcdCDC = __constant_cpu_to_le16(0x0110),
|
||||
.bcdCDC = cpu_to_le16(0x0110),
|
||||
};
|
||||
|
||||
static struct usb_cdc_union_desc ecm_union_desc __initdata = {
|
||||
@@ -148,9 +148,9 @@ static struct usb_cdc_ether_desc ecm_desc __initdata = {
|
||||
|
||||
/* this descriptor actually adds value, surprise! */
|
||||
/* .iMACAddress = DYNAMIC */
|
||||
.bmEthernetStatistics = __constant_cpu_to_le32(0), /* no statistics */
|
||||
.wMaxSegmentSize = __constant_cpu_to_le16(ETH_FRAME_LEN),
|
||||
.wNumberMCFilters = __constant_cpu_to_le16(0),
|
||||
.bmEthernetStatistics = cpu_to_le32(0), /* no statistics */
|
||||
.wMaxSegmentSize = cpu_to_le16(ETH_FRAME_LEN),
|
||||
.wNumberMCFilters = cpu_to_le16(0),
|
||||
.bNumberPowerFilters = 0,
|
||||
};
|
||||
|
||||
@@ -192,7 +192,7 @@ static struct usb_endpoint_descriptor fs_ecm_notify_desc __initdata = {
|
||||
|
||||
.bEndpointAddress = USB_DIR_IN,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_INT,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(ECM_STATUS_BYTECOUNT),
|
||||
.wMaxPacketSize = cpu_to_le16(ECM_STATUS_BYTECOUNT),
|
||||
.bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC,
|
||||
};
|
||||
|
||||
@@ -236,7 +236,7 @@ static struct usb_endpoint_descriptor hs_ecm_notify_desc __initdata = {
|
||||
|
||||
.bEndpointAddress = USB_DIR_IN,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_INT,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(ECM_STATUS_BYTECOUNT),
|
||||
.wMaxPacketSize = cpu_to_le16(ECM_STATUS_BYTECOUNT),
|
||||
.bInterval = LOG2_STATUS_INTERVAL_MSEC + 4,
|
||||
};
|
||||
static struct usb_endpoint_descriptor hs_ecm_in_desc __initdata = {
|
||||
@@ -245,7 +245,7 @@ static struct usb_endpoint_descriptor hs_ecm_in_desc __initdata = {
|
||||
|
||||
.bEndpointAddress = USB_DIR_IN,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(512),
|
||||
.wMaxPacketSize = cpu_to_le16(512),
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor hs_ecm_out_desc __initdata = {
|
||||
@@ -254,7 +254,7 @@ static struct usb_endpoint_descriptor hs_ecm_out_desc __initdata = {
|
||||
|
||||
.bEndpointAddress = USB_DIR_OUT,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(512),
|
||||
.wMaxPacketSize = cpu_to_le16(512),
|
||||
};
|
||||
|
||||
static struct usb_descriptor_header *ecm_hs_function[] __initdata = {
|
||||
|
@@ -100,7 +100,7 @@ static struct usb_endpoint_descriptor hs_loop_source_desc = {
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(512),
|
||||
.wMaxPacketSize = cpu_to_le16(512),
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor hs_loop_sink_desc = {
|
||||
@@ -108,7 +108,7 @@ static struct usb_endpoint_descriptor hs_loop_sink_desc = {
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(512),
|
||||
.wMaxPacketSize = cpu_to_le16(512),
|
||||
};
|
||||
|
||||
static struct usb_descriptor_header *hs_loopback_descs[] = {
|
||||
@@ -359,7 +359,7 @@ static struct usb_configuration loopback_driver = {
|
||||
* loopback_add - add a loopback testing configuration to a device
|
||||
* @cdev: the device to support the loopback configuration
|
||||
*/
|
||||
int __init loopback_add(struct usb_composite_dev *cdev)
|
||||
int __init loopback_add(struct usb_composite_dev *cdev, bool autoresume)
|
||||
{
|
||||
int id;
|
||||
|
||||
@@ -372,6 +372,10 @@ int __init loopback_add(struct usb_composite_dev *cdev)
|
||||
loopback_intf.iInterface = id;
|
||||
loopback_driver.iConfiguration = id;
|
||||
|
||||
/* support autoresume for remote wakeup testing */
|
||||
if (autoresume)
|
||||
sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
|
||||
|
||||
/* support OTG systems */
|
||||
if (gadget_is_otg(cdev->gadget)) {
|
||||
loopback_driver.descriptors = otg_desc;
|
||||
|
@@ -123,7 +123,7 @@ static struct usb_cdc_header_desc obex_cdc_header_desc __initdata = {
|
||||
.bLength = sizeof(obex_cdc_header_desc),
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
.bDescriptorSubType = USB_CDC_HEADER_TYPE,
|
||||
.bcdCDC = __constant_cpu_to_le16(0x0120),
|
||||
.bcdCDC = cpu_to_le16(0x0120),
|
||||
};
|
||||
|
||||
static struct usb_cdc_union_desc obex_cdc_union_desc __initdata = {
|
||||
@@ -138,7 +138,7 @@ static struct usb_cdc_obex_desc obex_desc __initdata = {
|
||||
.bLength = sizeof(obex_desc),
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
.bDescriptorSubType = USB_CDC_OBEX_TYPE,
|
||||
.bcdVersion = __constant_cpu_to_le16(0x0100),
|
||||
.bcdVersion = cpu_to_le16(0x0100),
|
||||
};
|
||||
|
||||
/* High-Speed Support */
|
||||
@@ -149,7 +149,7 @@ static struct usb_endpoint_descriptor obex_hs_ep_out_desc __initdata = {
|
||||
|
||||
.bEndpointAddress = USB_DIR_OUT,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(512),
|
||||
.wMaxPacketSize = cpu_to_le16(512),
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor obex_hs_ep_in_desc __initdata = {
|
||||
@@ -158,7 +158,7 @@ static struct usb_endpoint_descriptor obex_hs_ep_in_desc __initdata = {
|
||||
|
||||
.bEndpointAddress = USB_DIR_IN,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(512),
|
||||
.wMaxPacketSize = cpu_to_le16(512),
|
||||
};
|
||||
|
||||
static struct usb_descriptor_header *hs_function[] __initdata = {
|
||||
@@ -366,9 +366,9 @@ obex_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
f->hs_descriptors = usb_copy_descriptors(hs_function);
|
||||
|
||||
obex->hs.obex_in = usb_find_endpoint(hs_function,
|
||||
f->descriptors, &obex_hs_ep_in_desc);
|
||||
f->hs_descriptors, &obex_hs_ep_in_desc);
|
||||
obex->hs.obex_out = usb_find_endpoint(hs_function,
|
||||
f->descriptors, &obex_hs_ep_out_desc);
|
||||
f->hs_descriptors, &obex_hs_ep_out_desc);
|
||||
}
|
||||
|
||||
/* Avoid letting this gadget enumerate until the userspace
|
||||
|
@@ -79,7 +79,7 @@ pn_header_desc = {
|
||||
.bLength = sizeof pn_header_desc,
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
.bDescriptorSubType = USB_CDC_HEADER_TYPE,
|
||||
.bcdCDC = __constant_cpu_to_le16(0x0110),
|
||||
.bcdCDC = cpu_to_le16(0x0110),
|
||||
};
|
||||
|
||||
static const struct usb_cdc_header_desc
|
||||
@@ -87,7 +87,7 @@ pn_phonet_desc = {
|
||||
.bLength = sizeof pn_phonet_desc,
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
.bDescriptorSubType = USB_CDC_PHONET_TYPE,
|
||||
.bcdCDC = __constant_cpu_to_le16(0x1505), /* ??? */
|
||||
.bcdCDC = cpu_to_le16(0x1505), /* ??? */
|
||||
};
|
||||
|
||||
static struct usb_cdc_union_desc
|
||||
@@ -138,7 +138,7 @@ pn_hs_sink_desc = {
|
||||
|
||||
.bEndpointAddress = USB_DIR_OUT,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(512),
|
||||
.wMaxPacketSize = cpu_to_le16(512),
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor
|
||||
@@ -157,7 +157,7 @@ pn_hs_source_desc = {
|
||||
|
||||
.bEndpointAddress = USB_DIR_IN,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(512),
|
||||
.wMaxPacketSize = cpu_to_le16(512),
|
||||
};
|
||||
|
||||
static struct usb_descriptor_header *fs_pn_function[] = {
|
||||
|
@@ -137,7 +137,7 @@ static struct usb_cdc_header_desc header_desc __initdata = {
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
.bDescriptorSubType = USB_CDC_HEADER_TYPE,
|
||||
|
||||
.bcdCDC = __constant_cpu_to_le16(0x0110),
|
||||
.bcdCDC = cpu_to_le16(0x0110),
|
||||
};
|
||||
|
||||
static struct usb_cdc_call_mgmt_descriptor call_mgmt_descriptor __initdata = {
|
||||
@@ -187,7 +187,7 @@ static struct usb_endpoint_descriptor fs_notify_desc __initdata = {
|
||||
|
||||
.bEndpointAddress = USB_DIR_IN,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_INT,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(STATUS_BYTECOUNT),
|
||||
.wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT),
|
||||
.bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC,
|
||||
};
|
||||
|
||||
@@ -230,7 +230,7 @@ static struct usb_endpoint_descriptor hs_notify_desc __initdata = {
|
||||
|
||||
.bEndpointAddress = USB_DIR_IN,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_INT,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(STATUS_BYTECOUNT),
|
||||
.wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT),
|
||||
.bInterval = LOG2_STATUS_INTERVAL_MSEC + 4,
|
||||
};
|
||||
static struct usb_endpoint_descriptor hs_in_desc __initdata = {
|
||||
@@ -239,7 +239,7 @@ static struct usb_endpoint_descriptor hs_in_desc __initdata = {
|
||||
|
||||
.bEndpointAddress = USB_DIR_IN,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(512),
|
||||
.wMaxPacketSize = cpu_to_le16(512),
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor hs_out_desc __initdata = {
|
||||
@@ -248,7 +248,7 @@ static struct usb_endpoint_descriptor hs_out_desc __initdata = {
|
||||
|
||||
.bEndpointAddress = USB_DIR_OUT,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(512),
|
||||
.wMaxPacketSize = cpu_to_le16(512),
|
||||
};
|
||||
|
||||
static struct usb_descriptor_header *eth_hs_function[] __initdata = {
|
||||
@@ -437,7 +437,7 @@ invalid:
|
||||
DBG(cdev, "rndis req%02x.%02x v%04x i%04x l%d\n",
|
||||
ctrl->bRequestType, ctrl->bRequest,
|
||||
w_value, w_index, w_length);
|
||||
req->zero = 0;
|
||||
req->zero = (value < w_length);
|
||||
req->length = value;
|
||||
value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC);
|
||||
if (value < 0)
|
||||
|
@@ -89,14 +89,14 @@ static struct usb_endpoint_descriptor gser_hs_in_desc __initdata = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(512),
|
||||
.wMaxPacketSize = cpu_to_le16(512),
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor gser_hs_out_desc __initdata = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(512),
|
||||
.wMaxPacketSize = cpu_to_le16(512),
|
||||
};
|
||||
|
||||
static struct usb_descriptor_header *gser_hs_function[] __initdata = {
|
||||
|
@@ -59,7 +59,6 @@ struct f_sourcesink {
|
||||
|
||||
struct usb_ep *in_ep;
|
||||
struct usb_ep *out_ep;
|
||||
struct timer_list resume;
|
||||
};
|
||||
|
||||
static inline struct f_sourcesink *func_to_ss(struct usb_function *f)
|
||||
@@ -67,10 +66,6 @@ static inline struct f_sourcesink *func_to_ss(struct usb_function *f)
|
||||
return container_of(f, struct f_sourcesink, function);
|
||||
}
|
||||
|
||||
static unsigned autoresume;
|
||||
module_param(autoresume, uint, 0);
|
||||
MODULE_PARM_DESC(autoresume, "zero, or seconds before remote wakeup");
|
||||
|
||||
static unsigned pattern;
|
||||
module_param(pattern, uint, 0);
|
||||
MODULE_PARM_DESC(pattern, "0 = all zeroes, 1 = mod63 ");
|
||||
@@ -118,7 +113,7 @@ static struct usb_endpoint_descriptor hs_source_desc = {
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(512),
|
||||
.wMaxPacketSize = cpu_to_le16(512),
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor hs_sink_desc = {
|
||||
@@ -126,7 +121,7 @@ static struct usb_endpoint_descriptor hs_sink_desc = {
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(512),
|
||||
.wMaxPacketSize = cpu_to_le16(512),
|
||||
};
|
||||
|
||||
static struct usb_descriptor_header *hs_source_sink_descs[] = {
|
||||
@@ -155,21 +150,6 @@ static struct usb_gadget_strings *sourcesink_strings[] = {
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static void sourcesink_autoresume(unsigned long _c)
|
||||
{
|
||||
struct usb_composite_dev *cdev = (void *)_c;
|
||||
struct usb_gadget *g = cdev->gadget;
|
||||
|
||||
/* Normally the host would be woken up for something
|
||||
* more significant than just a timer firing; likely
|
||||
* because of some direct user request.
|
||||
*/
|
||||
if (g->speed != USB_SPEED_UNKNOWN) {
|
||||
int status = usb_gadget_wakeup(g);
|
||||
DBG(cdev, "%s --> %d\n", __func__, status);
|
||||
}
|
||||
}
|
||||
|
||||
static int __init
|
||||
sourcesink_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
{
|
||||
@@ -198,9 +178,6 @@ autoconf_fail:
|
||||
goto autoconf_fail;
|
||||
ss->out_ep->driver_data = cdev; /* claim */
|
||||
|
||||
setup_timer(&ss->resume, sourcesink_autoresume,
|
||||
(unsigned long) c->cdev);
|
||||
|
||||
/* support high speed hardware */
|
||||
if (gadget_is_dualspeed(c->cdev->gadget)) {
|
||||
hs_source_desc.bEndpointAddress =
|
||||
@@ -359,7 +336,6 @@ static void disable_source_sink(struct f_sourcesink *ss)
|
||||
|
||||
cdev = ss->function.config->cdev;
|
||||
disable_endpoints(cdev, ss->in_ep, ss->out_ep);
|
||||
del_timer(&ss->resume);
|
||||
VDBG(cdev, "%s disabled\n", ss->function.name);
|
||||
}
|
||||
|
||||
@@ -426,30 +402,6 @@ static void sourcesink_disable(struct usb_function *f)
|
||||
disable_source_sink(ss);
|
||||
}
|
||||
|
||||
static void sourcesink_suspend(struct usb_function *f)
|
||||
{
|
||||
struct f_sourcesink *ss = func_to_ss(f);
|
||||
struct usb_composite_dev *cdev = f->config->cdev;
|
||||
|
||||
if (cdev->gadget->speed == USB_SPEED_UNKNOWN)
|
||||
return;
|
||||
|
||||
if (autoresume) {
|
||||
mod_timer(&ss->resume, jiffies + (HZ * autoresume));
|
||||
DBG(cdev, "suspend, wakeup in %d seconds\n", autoresume);
|
||||
} else
|
||||
DBG(cdev, "%s\n", __func__);
|
||||
}
|
||||
|
||||
static void sourcesink_resume(struct usb_function *f)
|
||||
{
|
||||
struct f_sourcesink *ss = func_to_ss(f);
|
||||
struct usb_composite_dev *cdev = f->config->cdev;
|
||||
|
||||
DBG(cdev, "%s\n", __func__);
|
||||
del_timer(&ss->resume);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static int __init sourcesink_bind_config(struct usb_configuration *c)
|
||||
@@ -467,8 +419,6 @@ static int __init sourcesink_bind_config(struct usb_configuration *c)
|
||||
ss->function.unbind = sourcesink_unbind;
|
||||
ss->function.set_alt = sourcesink_set_alt;
|
||||
ss->function.disable = sourcesink_disable;
|
||||
ss->function.suspend = sourcesink_suspend;
|
||||
ss->function.resume = sourcesink_resume;
|
||||
|
||||
status = usb_add_function(c, &ss->function);
|
||||
if (status)
|
||||
@@ -559,7 +509,7 @@ static struct usb_configuration sourcesink_driver = {
|
||||
* sourcesink_add - add a source/sink testing configuration to a device
|
||||
* @cdev: the device to support the configuration
|
||||
*/
|
||||
int __init sourcesink_add(struct usb_composite_dev *cdev)
|
||||
int __init sourcesink_add(struct usb_composite_dev *cdev, bool autoresume)
|
||||
{
|
||||
int id;
|
||||
|
||||
|
@@ -108,7 +108,7 @@ static struct usb_cdc_header_desc mdlm_header_desc __initdata = {
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
.bDescriptorSubType = USB_CDC_HEADER_TYPE,
|
||||
|
||||
.bcdCDC = __constant_cpu_to_le16(0x0110),
|
||||
.bcdCDC = cpu_to_le16(0x0110),
|
||||
};
|
||||
|
||||
static struct usb_cdc_mdlm_desc mdlm_desc __initdata = {
|
||||
@@ -116,7 +116,7 @@ static struct usb_cdc_mdlm_desc mdlm_desc __initdata = {
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
.bDescriptorSubType = USB_CDC_MDLM_TYPE,
|
||||
|
||||
.bcdVersion = __constant_cpu_to_le16(0x0100),
|
||||
.bcdVersion = cpu_to_le16(0x0100),
|
||||
.bGUID = {
|
||||
0x5d, 0x34, 0xcf, 0x66, 0x11, 0x18, 0x11, 0xd6,
|
||||
0xa2, 0x1a, 0x00, 0x01, 0x02, 0xca, 0x9a, 0x7f,
|
||||
@@ -144,9 +144,9 @@ static struct usb_cdc_ether_desc ether_desc __initdata = {
|
||||
|
||||
/* this descriptor actually adds value, surprise! */
|
||||
/* .iMACAddress = DYNAMIC */
|
||||
.bmEthernetStatistics = __constant_cpu_to_le32(0), /* no statistics */
|
||||
.wMaxSegmentSize = __constant_cpu_to_le16(ETH_FRAME_LEN),
|
||||
.wNumberMCFilters = __constant_cpu_to_le16(0),
|
||||
.bmEthernetStatistics = cpu_to_le32(0), /* no statistics */
|
||||
.wMaxSegmentSize = cpu_to_le16(ETH_FRAME_LEN),
|
||||
.wNumberMCFilters = cpu_to_le16(0),
|
||||
.bNumberPowerFilters = 0,
|
||||
};
|
||||
|
||||
@@ -186,7 +186,7 @@ static struct usb_endpoint_descriptor hs_subset_in_desc __initdata = {
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(512),
|
||||
.wMaxPacketSize = cpu_to_le16(512),
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor hs_subset_out_desc __initdata = {
|
||||
@@ -194,7 +194,7 @@ static struct usb_endpoint_descriptor hs_subset_out_desc __initdata = {
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(512),
|
||||
.wMaxPacketSize = cpu_to_le16(512),
|
||||
};
|
||||
|
||||
static struct usb_descriptor_header *hs_eth_function[] __initdata = {
|
||||
|
@@ -847,13 +847,13 @@ device_desc = {
|
||||
.bLength = sizeof device_desc,
|
||||
.bDescriptorType = USB_DT_DEVICE,
|
||||
|
||||
.bcdUSB = __constant_cpu_to_le16(0x0200),
|
||||
.bcdUSB = cpu_to_le16(0x0200),
|
||||
.bDeviceClass = USB_CLASS_PER_INTERFACE,
|
||||
|
||||
/* The next three values can be overridden by module parameters */
|
||||
.idVendor = __constant_cpu_to_le16(DRIVER_VENDOR_ID),
|
||||
.idProduct = __constant_cpu_to_le16(DRIVER_PRODUCT_ID),
|
||||
.bcdDevice = __constant_cpu_to_le16(0xffff),
|
||||
.idVendor = cpu_to_le16(DRIVER_VENDOR_ID),
|
||||
.idProduct = cpu_to_le16(DRIVER_PRODUCT_ID),
|
||||
.bcdDevice = cpu_to_le16(0xffff),
|
||||
|
||||
.iManufacturer = STRING_MANUFACTURER,
|
||||
.iProduct = STRING_PRODUCT,
|
||||
@@ -926,7 +926,7 @@ fs_intr_in_desc = {
|
||||
|
||||
.bEndpointAddress = USB_DIR_IN,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_INT,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(2),
|
||||
.wMaxPacketSize = cpu_to_le16(2),
|
||||
.bInterval = 32, // frames -> 32 ms
|
||||
};
|
||||
|
||||
@@ -954,7 +954,7 @@ dev_qualifier = {
|
||||
.bLength = sizeof dev_qualifier,
|
||||
.bDescriptorType = USB_DT_DEVICE_QUALIFIER,
|
||||
|
||||
.bcdUSB = __constant_cpu_to_le16(0x0200),
|
||||
.bcdUSB = cpu_to_le16(0x0200),
|
||||
.bDeviceClass = USB_CLASS_PER_INTERFACE,
|
||||
|
||||
.bNumConfigurations = 1,
|
||||
@@ -967,7 +967,7 @@ hs_bulk_in_desc = {
|
||||
|
||||
/* bEndpointAddress copied from fs_bulk_in_desc during fsg_bind() */
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(512),
|
||||
.wMaxPacketSize = cpu_to_le16(512),
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor
|
||||
@@ -977,7 +977,7 @@ hs_bulk_out_desc = {
|
||||
|
||||
/* bEndpointAddress copied from fs_bulk_out_desc during fsg_bind() */
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(512),
|
||||
.wMaxPacketSize = cpu_to_le16(512),
|
||||
.bInterval = 1, // NAK every 1 uframe
|
||||
};
|
||||
|
||||
@@ -988,7 +988,7 @@ hs_intr_in_desc = {
|
||||
|
||||
/* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */
|
||||
.bmAttributes = USB_ENDPOINT_XFER_INT,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(2),
|
||||
.wMaxPacketSize = cpu_to_le16(2),
|
||||
.bInterval = 9, // 2**(9-1) = 256 uframes -> 32 ms
|
||||
};
|
||||
|
||||
@@ -1711,7 +1711,9 @@ static int do_write(struct fsg_dev *fsg)
|
||||
curlun->sense_data = SS_WRITE_PROTECTED;
|
||||
return -EINVAL;
|
||||
}
|
||||
spin_lock(&curlun->filp->f_lock);
|
||||
curlun->filp->f_flags &= ~O_SYNC; // Default is not to wait
|
||||
spin_unlock(&curlun->filp->f_lock);
|
||||
|
||||
/* Get the starting Logical Block Address and check that it's
|
||||
* not too big */
|
||||
@@ -1728,8 +1730,11 @@ static int do_write(struct fsg_dev *fsg)
|
||||
curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
|
||||
return -EINVAL;
|
||||
}
|
||||
if (fsg->cmnd[1] & 0x08) // FUA
|
||||
if (fsg->cmnd[1] & 0x08) { // FUA
|
||||
spin_lock(&curlun->filp->f_lock);
|
||||
curlun->filp->f_flags |= O_SYNC;
|
||||
spin_unlock(&curlun->filp->f_lock);
|
||||
}
|
||||
}
|
||||
if (lba >= curlun->num_sectors) {
|
||||
curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
|
||||
@@ -2646,7 +2651,7 @@ static int send_status(struct fsg_dev *fsg)
|
||||
struct bulk_cs_wrap *csw = bh->buf;
|
||||
|
||||
/* Store and send the Bulk-only CSW */
|
||||
csw->Signature = __constant_cpu_to_le32(USB_BULK_CS_SIG);
|
||||
csw->Signature = cpu_to_le32(USB_BULK_CS_SIG);
|
||||
csw->Tag = fsg->tag;
|
||||
csw->Residue = cpu_to_le32(fsg->residue);
|
||||
csw->Status = status;
|
||||
@@ -3089,7 +3094,7 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
|
||||
|
||||
/* Is the CBW valid? */
|
||||
if (req->actual != USB_BULK_CB_WRAP_LEN ||
|
||||
cbw->Signature != __constant_cpu_to_le32(
|
||||
cbw->Signature != cpu_to_le32(
|
||||
USB_BULK_CB_SIG)) {
|
||||
DBG(fsg, "invalid CBW: len %u sig 0x%x\n",
|
||||
req->actual,
|
||||
@@ -3879,7 +3884,11 @@ static int __init check_parameters(struct fsg_dev *fsg)
|
||||
mod_data.protocol_type = USB_SC_SCSI;
|
||||
mod_data.protocol_name = "Transparent SCSI";
|
||||
|
||||
if (gadget_is_sh(fsg->gadget))
|
||||
/* Some peripheral controllers are known not to be able to
|
||||
* halt bulk endpoints correctly. If one of them is present,
|
||||
* disable stalls.
|
||||
*/
|
||||
if (gadget_is_sh(fsg->gadget) || gadget_is_at91(fsg->gadget))
|
||||
mod_data.can_stall = 0;
|
||||
|
||||
if (mod_data.release == 0xffff) { // Parameter wasn't set
|
||||
|
@@ -1622,6 +1622,8 @@ static int qe_ep_disable(struct usb_ep *_ep)
|
||||
nuke(ep, -ESHUTDOWN);
|
||||
ep->desc = NULL;
|
||||
ep->stopped = 1;
|
||||
ep->tx_req = NULL;
|
||||
qe_ep_reset(udc, ep->epnum);
|
||||
spin_unlock_irqrestore(&udc->lock, flags);
|
||||
|
||||
cpm_muram_free(cpm_muram_offset(ep->rxbase));
|
||||
@@ -1681,14 +1683,11 @@ static void qe_free_request(struct usb_ep *_ep, struct usb_request *_req)
|
||||
kfree(req);
|
||||
}
|
||||
|
||||
/* queues (submits) an I/O request to an endpoint */
|
||||
static int qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
|
||||
gfp_t gfp_flags)
|
||||
static int __qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req)
|
||||
{
|
||||
struct qe_ep *ep = container_of(_ep, struct qe_ep, ep);
|
||||
struct qe_req *req = container_of(_req, struct qe_req, req);
|
||||
struct qe_udc *udc;
|
||||
unsigned long flags;
|
||||
int reval;
|
||||
|
||||
udc = ep->udc;
|
||||
@@ -1732,7 +1731,7 @@ static int qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
|
||||
list_add_tail(&req->queue, &ep->queue);
|
||||
dev_vdbg(udc->dev, "gadget have request in %s! %d\n",
|
||||
ep->name, req->req.length);
|
||||
spin_lock_irqsave(&udc->lock, flags);
|
||||
|
||||
/* push the request to device */
|
||||
if (ep_is_in(ep))
|
||||
reval = ep_req_send(ep, req);
|
||||
@@ -1748,11 +1747,24 @@ static int qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
|
||||
if (ep->dir == USB_DIR_OUT)
|
||||
reval = ep_req_receive(ep, req);
|
||||
|
||||
spin_unlock_irqrestore(&udc->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* queues (submits) an I/O request to an endpoint */
|
||||
static int qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
|
||||
gfp_t gfp_flags)
|
||||
{
|
||||
struct qe_ep *ep = container_of(_ep, struct qe_ep, ep);
|
||||
struct qe_udc *udc = ep->udc;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
spin_lock_irqsave(&udc->lock, flags);
|
||||
ret = __qe_ep_queue(_ep, _req);
|
||||
spin_unlock_irqrestore(&udc->lock, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* dequeues (cancels, unlinks) an I/O request from an endpoint */
|
||||
static int qe_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
|
||||
{
|
||||
@@ -2008,7 +2020,7 @@ static void ch9getstatus(struct qe_udc *udc, u8 request_type, u16 value,
|
||||
udc->ep0_dir = USB_DIR_IN;
|
||||
|
||||
/* data phase */
|
||||
status = qe_ep_queue(&ep->ep, &req->req, GFP_ATOMIC);
|
||||
status = __qe_ep_queue(&ep->ep, &req->req);
|
||||
|
||||
if (status == 0)
|
||||
return;
|
||||
@@ -2151,6 +2163,9 @@ static int reset_irq(struct qe_udc *udc)
|
||||
{
|
||||
unsigned char i;
|
||||
|
||||
if (udc->usb_state == USB_STATE_DEFAULT)
|
||||
return 0;
|
||||
|
||||
qe_usb_disable();
|
||||
out_8(&udc->usb_regs->usb_usadr, 0);
|
||||
|
||||
@@ -2442,8 +2457,12 @@ static int __devinit qe_udc_reg_init(struct qe_udc *udc)
|
||||
struct usb_ctlr __iomem *qe_usbregs;
|
||||
qe_usbregs = udc->usb_regs;
|
||||
|
||||
/* Init the usb register */
|
||||
/* Spec says that we must enable the USB controller to change mode. */
|
||||
out_8(&qe_usbregs->usb_usmod, 0x01);
|
||||
/* Mode changed, now disable it, since muram isn't initialized yet. */
|
||||
out_8(&qe_usbregs->usb_usmod, 0x00);
|
||||
|
||||
/* Initialize the rest. */
|
||||
out_be16(&qe_usbregs->usb_usbmr, 0);
|
||||
out_8(&qe_usbregs->usb_uscom, 0);
|
||||
out_be16(&qe_usbregs->usb_usber, USBER_ALL_CLEAR);
|
||||
@@ -2604,6 +2623,10 @@ static int __devinit qe_udc_probe(struct of_device *ofdev,
|
||||
(unsigned long)udc_controller);
|
||||
/* request irq and disable DR */
|
||||
udc_controller->usb_irq = irq_of_parse_and_map(np, 0);
|
||||
if (!udc_controller->usb_irq) {
|
||||
ret = -EINVAL;
|
||||
goto err_noirq;
|
||||
}
|
||||
|
||||
ret = request_irq(udc_controller->usb_irq, qe_udc_irq, 0,
|
||||
driver_name, udc_controller);
|
||||
@@ -2625,6 +2648,8 @@ static int __devinit qe_udc_probe(struct of_device *ofdev,
|
||||
err6:
|
||||
free_irq(udc_controller->usb_irq, udc_controller);
|
||||
err5:
|
||||
irq_dispose_mapping(udc_controller->usb_irq);
|
||||
err_noirq:
|
||||
if (udc_controller->nullmap) {
|
||||
dma_unmap_single(udc_controller->gadget.dev.parent,
|
||||
udc_controller->nullp, 256,
|
||||
@@ -2648,7 +2673,7 @@ err2:
|
||||
iounmap(udc_controller->usb_regs);
|
||||
err1:
|
||||
kfree(udc_controller);
|
||||
|
||||
udc_controller = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2710,6 +2735,7 @@ static int __devexit qe_udc_remove(struct of_device *ofdev)
|
||||
kfree(ep->txframe);
|
||||
|
||||
free_irq(udc_controller->usb_irq, udc_controller);
|
||||
irq_dispose_mapping(udc_controller->usb_irq);
|
||||
|
||||
tasklet_kill(&udc_controller->rx_tasklet);
|
||||
|
||||
|
@@ -404,7 +404,10 @@ static void struct_ep_qh_setup(struct fsl_udc *udc, unsigned char ep_num,
|
||||
}
|
||||
if (zlt)
|
||||
tmp |= EP_QUEUE_HEAD_ZLT_SEL;
|
||||
|
||||
p_QH->max_pkt_length = cpu_to_le32(tmp);
|
||||
p_QH->next_dtd_ptr = 1;
|
||||
p_QH->size_ioc_int_sts = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1799,7 +1802,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
|
||||
|
||||
out:
|
||||
if (retval)
|
||||
printk("gadget driver register failed %d\n", retval);
|
||||
printk(KERN_WARNING "gadget driver register failed %d\n",
|
||||
retval);
|
||||
return retval;
|
||||
}
|
||||
EXPORT_SYMBOL(usb_gadget_register_driver);
|
||||
@@ -1844,7 +1848,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
|
||||
udc_controller->gadget.dev.driver = NULL;
|
||||
udc_controller->driver = NULL;
|
||||
|
||||
printk("unregistered gadget driver '%s'\n", driver->driver.name);
|
||||
printk(KERN_WARNING "unregistered gadget driver '%s'\n",
|
||||
driver->driver.name);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(usb_gadget_unregister_driver);
|
||||
@@ -2452,7 +2457,7 @@ module_init(udc_init);
|
||||
static void __exit udc_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&udc_driver);
|
||||
printk("%s unregistered\n", driver_desc);
|
||||
printk(KERN_WARNING "%s unregistered\n", driver_desc);
|
||||
}
|
||||
|
||||
module_exit(udc_exit);
|
||||
|
@@ -19,7 +19,7 @@ void disable_endpoints(struct usb_composite_dev *cdev,
|
||||
struct usb_ep *in, struct usb_ep *out);
|
||||
|
||||
/* configuration-specific linkup */
|
||||
int sourcesink_add(struct usb_composite_dev *cdev);
|
||||
int loopback_add(struct usb_composite_dev *cdev);
|
||||
int sourcesink_add(struct usb_composite_dev *cdev, bool autoresume);
|
||||
int loopback_add(struct usb_composite_dev *cdev, bool autoresume);
|
||||
|
||||
#endif /* __G_ZERO_H */
|
||||
|
@@ -199,10 +199,10 @@ DECLARE_USB_MS_ENDPOINT_DESCRIPTOR(1);
|
||||
static struct usb_device_descriptor device_desc = {
|
||||
.bLength = USB_DT_DEVICE_SIZE,
|
||||
.bDescriptorType = USB_DT_DEVICE,
|
||||
.bcdUSB = __constant_cpu_to_le16(0x0200),
|
||||
.bcdUSB = cpu_to_le16(0x0200),
|
||||
.bDeviceClass = USB_CLASS_PER_INTERFACE,
|
||||
.idVendor = __constant_cpu_to_le16(DRIVER_VENDOR_NUM),
|
||||
.idProduct = __constant_cpu_to_le16(DRIVER_PRODUCT_NUM),
|
||||
.idVendor = cpu_to_le16(DRIVER_VENDOR_NUM),
|
||||
.idProduct = cpu_to_le16(DRIVER_PRODUCT_NUM),
|
||||
.iManufacturer = STRING_MANUFACTURER,
|
||||
.iProduct = STRING_PRODUCT,
|
||||
.bNumConfigurations = 1,
|
||||
@@ -241,8 +241,8 @@ static const struct usb_ac_header_descriptor_1 ac_header_desc = {
|
||||
.bLength = USB_DT_AC_HEADER_SIZE(1),
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
.bDescriptorSubtype = USB_MS_HEADER,
|
||||
.bcdADC = __constant_cpu_to_le16(0x0100),
|
||||
.wTotalLength = __constant_cpu_to_le16(USB_DT_AC_HEADER_SIZE(1)),
|
||||
.bcdADC = cpu_to_le16(0x0100),
|
||||
.wTotalLength = cpu_to_le16(USB_DT_AC_HEADER_SIZE(1)),
|
||||
.bInCollection = 1,
|
||||
.baInterfaceNr = {
|
||||
[0] = GMIDI_MS_INTERFACE,
|
||||
@@ -265,8 +265,8 @@ static const struct usb_ms_header_descriptor ms_header_desc = {
|
||||
.bLength = USB_DT_MS_HEADER_SIZE,
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
.bDescriptorSubtype = USB_MS_HEADER,
|
||||
.bcdMSC = __constant_cpu_to_le16(0x0100),
|
||||
.wTotalLength = __constant_cpu_to_le16(USB_DT_MS_HEADER_SIZE
|
||||
.bcdMSC = cpu_to_le16(0x0100),
|
||||
.wTotalLength = cpu_to_le16(USB_DT_MS_HEADER_SIZE
|
||||
+ 2*USB_DT_MIDI_IN_SIZE
|
||||
+ 2*USB_DT_MIDI_OUT_SIZE(1)),
|
||||
};
|
||||
@@ -1099,10 +1099,9 @@ static int gmidi_register_card(struct gmidi_device *dev)
|
||||
.dev_free = gmidi_snd_free,
|
||||
};
|
||||
|
||||
card = snd_card_new(index, id, THIS_MODULE, 0);
|
||||
if (!card) {
|
||||
ERROR(dev, "snd_card_new failed\n");
|
||||
err = -ENOMEM;
|
||||
err = snd_card_create(index, id, THIS_MODULE, 0, &card);
|
||||
if (err < 0) {
|
||||
ERROR(dev, "snd_card_create failed\n");
|
||||
goto fail;
|
||||
}
|
||||
dev->card = card;
|
||||
@@ -1227,7 +1226,7 @@ autoconf_fail:
|
||||
*/
|
||||
pr_warning("%s: controller '%s' not recognized\n",
|
||||
shortname, gadget->name);
|
||||
device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);
|
||||
device_desc.bcdDevice = cpu_to_le16(0x9999);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1472,7 +1472,7 @@ static void ep0_setup(struct goku_udc *dev)
|
||||
/* active endpoint */
|
||||
if (tmp > 3 || (!dev->ep[tmp].desc && tmp != 0))
|
||||
goto stall;
|
||||
if (ctrl.wIndex & __constant_cpu_to_le16(
|
||||
if (ctrl.wIndex & cpu_to_le16(
|
||||
USB_DIR_IN)) {
|
||||
if (!dev->ep[tmp].is_in)
|
||||
goto stall;
|
||||
@@ -1480,7 +1480,7 @@ static void ep0_setup(struct goku_udc *dev)
|
||||
if (dev->ep[tmp].is_in)
|
||||
goto stall;
|
||||
}
|
||||
if (ctrl.wValue != __constant_cpu_to_le16(
|
||||
if (ctrl.wValue != cpu_to_le16(
|
||||
USB_ENDPOINT_HALT))
|
||||
goto stall;
|
||||
if (tmp)
|
||||
@@ -1493,7 +1493,7 @@ succeed:
|
||||
return;
|
||||
case USB_RECIP_DEVICE:
|
||||
/* device remote wakeup: always clear */
|
||||
if (ctrl.wValue != __constant_cpu_to_le16(1))
|
||||
if (ctrl.wValue != cpu_to_le16(1))
|
||||
goto stall;
|
||||
VDBG(dev, "clear dev remote wakeup\n");
|
||||
goto succeed;
|
||||
@@ -1519,7 +1519,7 @@ succeed:
|
||||
dev->req_config = (ctrl.bRequest == USB_REQ_SET_CONFIGURATION
|
||||
&& ctrl.bRequestType == USB_RECIP_DEVICE);
|
||||
if (unlikely(dev->req_config))
|
||||
dev->configured = (ctrl.wValue != __constant_cpu_to_le16(0));
|
||||
dev->configured = (ctrl.wValue != cpu_to_le16(0));
|
||||
|
||||
/* delegate everything to the gadget driver.
|
||||
* it may respond after this irq handler returns.
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* driver/usb/gadget/imx_udc.c
|
||||
*
|
||||
* Copyright (C) 2005 Mike Lee(eemike@gmail.com)
|
||||
* Copyright (C) 2005 Mike Lee <eemike@gmail.com>
|
||||
* Copyright (C) 2008 Darius Augulis <augulis.darius@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/timer.h>
|
||||
|
||||
#include <linux/usb/ch9.h>
|
||||
#include <linux/usb/gadget.h>
|
||||
@@ -51,7 +52,8 @@ void ep0_chg_stat(const char *label, struct imx_udc_struct *imx_usb,
|
||||
void imx_udc_enable(struct imx_udc_struct *imx_usb)
|
||||
{
|
||||
int temp = __raw_readl(imx_usb->base + USB_CTRL);
|
||||
__raw_writel(temp | CTRL_FE_ENA | CTRL_AFE_ENA, imx_usb->base + USB_CTRL);
|
||||
__raw_writel(temp | CTRL_FE_ENA | CTRL_AFE_ENA,
|
||||
imx_usb->base + USB_CTRL);
|
||||
imx_usb->gadget.speed = USB_SPEED_FULL;
|
||||
}
|
||||
|
||||
@@ -126,7 +128,8 @@ void imx_udc_config(struct imx_udc_struct *imx_usb)
|
||||
for (j = 0; j < 5; j++) {
|
||||
__raw_writeb(ep_conf[j],
|
||||
imx_usb->base + USB_DDAT);
|
||||
do {} while (__raw_readl(imx_usb->base + USB_DADR)
|
||||
do {} while (__raw_readl(imx_usb->base
|
||||
+ USB_DADR)
|
||||
& DADR_BSY);
|
||||
}
|
||||
}
|
||||
@@ -183,7 +186,8 @@ void imx_udc_init_ep(struct imx_udc_struct *imx_usb)
|
||||
temp = (EP_DIR(imx_ep) << 7) | (max << 5)
|
||||
| (imx_ep->bmAttributes << 3);
|
||||
__raw_writel(temp, imx_usb->base + USB_EP_STAT(i));
|
||||
__raw_writel(temp | EPSTAT_FLUSH, imx_usb->base + USB_EP_STAT(i));
|
||||
__raw_writel(temp | EPSTAT_FLUSH,
|
||||
imx_usb->base + USB_EP_STAT(i));
|
||||
D_INI(imx_usb->dev, "<%s> ep%d_stat %08x\n", __func__, i,
|
||||
__raw_readl(imx_usb->base + USB_EP_STAT(i)));
|
||||
}
|
||||
@@ -278,15 +282,18 @@ void imx_ep_stall(struct imx_ep_struct *imx_ep)
|
||||
struct imx_udc_struct *imx_usb = imx_ep->imx_usb;
|
||||
int temp, i;
|
||||
|
||||
D_ERR(imx_usb->dev, "<%s> Forced stall on %s\n", __func__, imx_ep->ep.name);
|
||||
D_ERR(imx_usb->dev,
|
||||
"<%s> Forced stall on %s\n", __func__, imx_ep->ep.name);
|
||||
|
||||
imx_flush(imx_ep);
|
||||
|
||||
/* Special care for ep0 */
|
||||
if (EP_NO(imx_ep)) {
|
||||
if (!EP_NO(imx_ep)) {
|
||||
temp = __raw_readl(imx_usb->base + USB_CTRL);
|
||||
__raw_writel(temp | CTRL_CMDOVER | CTRL_CMDERROR, imx_usb->base + USB_CTRL);
|
||||
do { } while (__raw_readl(imx_usb->base + USB_CTRL) & CTRL_CMDOVER);
|
||||
__raw_writel(temp | CTRL_CMDOVER | CTRL_CMDERROR,
|
||||
imx_usb->base + USB_CTRL);
|
||||
do { } while (__raw_readl(imx_usb->base + USB_CTRL)
|
||||
& CTRL_CMDOVER);
|
||||
temp = __raw_readl(imx_usb->base + USB_CTRL);
|
||||
__raw_writel(temp & ~CTRL_CMDERROR, imx_usb->base + USB_CTRL);
|
||||
}
|
||||
@@ -296,12 +303,13 @@ void imx_ep_stall(struct imx_ep_struct *imx_ep)
|
||||
imx_usb->base + USB_EP_STAT(EP_NO(imx_ep)));
|
||||
|
||||
for (i = 0; i < 100; i ++) {
|
||||
temp = __raw_readl(imx_usb->base + USB_EP_STAT(EP_NO(imx_ep)));
|
||||
if (!temp & EPSTAT_STALL)
|
||||
temp = __raw_readl(imx_usb->base
|
||||
+ USB_EP_STAT(EP_NO(imx_ep)));
|
||||
if (!(temp & EPSTAT_STALL))
|
||||
break;
|
||||
udelay(20);
|
||||
}
|
||||
if (i == 50)
|
||||
if (i == 100)
|
||||
D_ERR(imx_usb->dev, "<%s> Non finished stall on %s\n",
|
||||
__func__, imx_ep->ep.name);
|
||||
}
|
||||
@@ -325,7 +333,8 @@ static int imx_udc_wakeup(struct usb_gadget *_gadget)
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
static void ep_add_request(struct imx_ep_struct *imx_ep, struct imx_request *req)
|
||||
static void ep_add_request(struct imx_ep_struct *imx_ep,
|
||||
struct imx_request *req)
|
||||
{
|
||||
if (unlikely(!req))
|
||||
return;
|
||||
@@ -334,7 +343,8 @@ static void ep_add_request(struct imx_ep_struct *imx_ep, struct imx_request *req
|
||||
list_add_tail(&req->queue, &imx_ep->queue);
|
||||
}
|
||||
|
||||
static void ep_del_request(struct imx_ep_struct *imx_ep, struct imx_request *req)
|
||||
static void ep_del_request(struct imx_ep_struct *imx_ep,
|
||||
struct imx_request *req)
|
||||
{
|
||||
if (unlikely(!req))
|
||||
return;
|
||||
@@ -343,7 +353,8 @@ static void ep_del_request(struct imx_ep_struct *imx_ep, struct imx_request *req
|
||||
req->in_use = 0;
|
||||
}
|
||||
|
||||
static void done(struct imx_ep_struct *imx_ep, struct imx_request *req, int status)
|
||||
static void done(struct imx_ep_struct *imx_ep,
|
||||
struct imx_request *req, int status)
|
||||
{
|
||||
ep_del_request(imx_ep, req);
|
||||
|
||||
@@ -494,7 +505,8 @@ static int write_fifo(struct imx_ep_struct *imx_ep, struct imx_request *req)
|
||||
__func__, imx_ep->ep.name, req,
|
||||
completed ? "completed" : "not completed");
|
||||
if (!EP_NO(imx_ep))
|
||||
ep0_chg_stat(__func__, imx_ep->imx_usb, EP0_IDLE);
|
||||
ep0_chg_stat(__func__,
|
||||
imx_ep->imx_usb, EP0_IDLE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -539,10 +551,9 @@ static int handle_ep0(struct imx_ep_struct *imx_ep)
|
||||
struct imx_request *req = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if (!list_empty(&imx_ep->queue))
|
||||
if (!list_empty(&imx_ep->queue)) {
|
||||
req = list_entry(imx_ep->queue.next, struct imx_request, queue);
|
||||
|
||||
if (req) {
|
||||
switch (imx_ep->imx_usb->ep0state) {
|
||||
|
||||
case EP0_IN_DATA_PHASE: /* GET_DESCRIPTOR */
|
||||
@@ -561,6 +572,10 @@ static int handle_ep0(struct imx_ep_struct *imx_ep)
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
D_ERR(imx_ep->imx_usb->dev, "<%s> no request on %s\n",
|
||||
__func__, imx_ep->ep.name);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -583,7 +598,8 @@ static void handle_ep0_devreq(struct imx_udc_struct *imx_usb)
|
||||
"<%s> no setup packet received\n", __func__);
|
||||
goto stall;
|
||||
}
|
||||
u.word[i] = __raw_readl(imx_usb->base + USB_EP_FDAT(EP_NO(imx_ep)));
|
||||
u.word[i] = __raw_readl(imx_usb->base
|
||||
+ USB_EP_FDAT(EP_NO(imx_ep)));
|
||||
}
|
||||
|
||||
temp = imx_ep_empty(imx_ep);
|
||||
@@ -759,7 +775,7 @@ static int imx_ep_queue
|
||||
*/
|
||||
if (imx_usb->set_config && !EP_NO(imx_ep)) {
|
||||
imx_usb->set_config = 0;
|
||||
D_EPX(imx_usb->dev,
|
||||
D_ERR(imx_usb->dev,
|
||||
"<%s> gadget reply set config\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
@@ -779,28 +795,29 @@ static int imx_ep_queue
|
||||
return -ESHUTDOWN;
|
||||
}
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
/* Debug */
|
||||
D_REQ(imx_usb->dev, "<%s> ep%d %s request for [%d] bytes\n",
|
||||
__func__, EP_NO(imx_ep),
|
||||
((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state == EP0_IN_DATA_PHASE)
|
||||
|| (EP_NO(imx_ep) && EP_DIR(imx_ep))) ? "IN" : "OUT", usb_req->length);
|
||||
((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state
|
||||
== EP0_IN_DATA_PHASE)
|
||||
|| (EP_NO(imx_ep) && EP_DIR(imx_ep)))
|
||||
? "IN" : "OUT", usb_req->length);
|
||||
dump_req(__func__, imx_ep, usb_req);
|
||||
|
||||
if (imx_ep->stopped) {
|
||||
usb_req->status = -ESHUTDOWN;
|
||||
ret = -ESHUTDOWN;
|
||||
goto out;
|
||||
return -ESHUTDOWN;
|
||||
}
|
||||
|
||||
if (req->in_use) {
|
||||
D_ERR(imx_usb->dev,
|
||||
"<%s> refusing to queue req %p (already queued)\n",
|
||||
__func__, req);
|
||||
goto out;
|
||||
return 0;
|
||||
}
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
usb_req->status = -EINPROGRESS;
|
||||
usb_req->actual = 0;
|
||||
|
||||
@@ -810,7 +827,7 @@ static int imx_ep_queue
|
||||
ret = handle_ep0(imx_ep);
|
||||
else
|
||||
ret = handle_ep(imx_ep);
|
||||
out:
|
||||
|
||||
local_irq_restore(flags);
|
||||
return ret;
|
||||
}
|
||||
@@ -997,71 +1014,32 @@ static void udc_stop_activity(struct imx_udc_struct *imx_usb,
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
static irqreturn_t imx_udc_irq(int irq, void *dev)
|
||||
/*
|
||||
* Called when timer expires.
|
||||
* Timer is started when CFG_CHG is received.
|
||||
*/
|
||||
static void handle_config(unsigned long data)
|
||||
{
|
||||
struct imx_udc_struct *imx_usb = dev;
|
||||
struct imx_udc_struct *imx_usb = (void *)data;
|
||||
struct usb_ctrlrequest u;
|
||||
int temp, cfg, intf, alt;
|
||||
int intr = __raw_readl(imx_usb->base + USB_INTR);
|
||||
|
||||
if (intr & (INTR_WAKEUP | INTR_SUSPEND | INTR_RESUME | INTR_RESET_START
|
||||
| INTR_RESET_STOP | INTR_CFG_CHG)) {
|
||||
dump_intr(__func__, intr, imx_usb->dev);
|
||||
dump_usb_stat(__func__, imx_usb);
|
||||
}
|
||||
local_irq_disable();
|
||||
|
||||
if (!imx_usb->driver) {
|
||||
/*imx_udc_disable(imx_usb);*/
|
||||
goto end_irq;
|
||||
}
|
||||
temp = __raw_readl(imx_usb->base + USB_STAT);
|
||||
cfg = (temp & STAT_CFG) >> 5;
|
||||
intf = (temp & STAT_INTF) >> 3;
|
||||
alt = temp & STAT_ALTSET;
|
||||
|
||||
if (intr & INTR_WAKEUP) {
|
||||
if (imx_usb->gadget.speed == USB_SPEED_UNKNOWN
|
||||
&& imx_usb->driver && imx_usb->driver->resume)
|
||||
imx_usb->driver->resume(&imx_usb->gadget);
|
||||
imx_usb->set_config = 0;
|
||||
imx_usb->gadget.speed = USB_SPEED_FULL;
|
||||
}
|
||||
D_REQ(imx_usb->dev,
|
||||
"<%s> orig config C=%d, I=%d, A=%d / "
|
||||
"req config C=%d, I=%d, A=%d\n",
|
||||
__func__, imx_usb->cfg, imx_usb->intf, imx_usb->alt,
|
||||
cfg, intf, alt);
|
||||
|
||||
if (intr & INTR_SUSPEND) {
|
||||
if (imx_usb->gadget.speed != USB_SPEED_UNKNOWN
|
||||
&& imx_usb->driver && imx_usb->driver->suspend)
|
||||
imx_usb->driver->suspend(&imx_usb->gadget);
|
||||
imx_usb->set_config = 0;
|
||||
imx_usb->gadget.speed = USB_SPEED_UNKNOWN;
|
||||
}
|
||||
if (cfg == 1 || cfg == 2) {
|
||||
|
||||
if (intr & INTR_RESET_START) {
|
||||
__raw_writel(intr, imx_usb->base + USB_INTR);
|
||||
udc_stop_activity(imx_usb, imx_usb->driver);
|
||||
imx_usb->set_config = 0;
|
||||
imx_usb->gadget.speed = USB_SPEED_UNKNOWN;
|
||||
}
|
||||
|
||||
if (intr & INTR_RESET_STOP)
|
||||
imx_usb->gadget.speed = USB_SPEED_FULL;
|
||||
|
||||
if (intr & INTR_CFG_CHG) {
|
||||
__raw_writel(INTR_CFG_CHG, imx_usb->base + USB_INTR);
|
||||
temp = __raw_readl(imx_usb->base + USB_STAT);
|
||||
cfg = (temp & STAT_CFG) >> 5;
|
||||
intf = (temp & STAT_INTF) >> 3;
|
||||
alt = temp & STAT_ALTSET;
|
||||
|
||||
D_REQ(imx_usb->dev,
|
||||
"<%s> orig config C=%d, I=%d, A=%d / "
|
||||
"req config C=%d, I=%d, A=%d\n",
|
||||
__func__, imx_usb->cfg, imx_usb->intf, imx_usb->alt,
|
||||
cfg, intf, alt);
|
||||
|
||||
if (cfg != 1 && cfg != 2)
|
||||
goto end_irq;
|
||||
|
||||
imx_usb->set_config = 0;
|
||||
|
||||
/* Config setup */
|
||||
if (imx_usb->cfg != cfg) {
|
||||
D_REQ(imx_usb->dev, "<%s> Change config start\n",__func__);
|
||||
u.bRequest = USB_REQ_SET_CONFIGURATION;
|
||||
u.bRequestType = USB_DIR_OUT |
|
||||
USB_TYPE_STANDARD |
|
||||
@@ -1070,14 +1048,10 @@ static irqreturn_t imx_udc_irq(int irq, void *dev)
|
||||
u.wIndex = 0;
|
||||
u.wLength = 0;
|
||||
imx_usb->cfg = cfg;
|
||||
imx_usb->set_config = 1;
|
||||
imx_usb->driver->setup(&imx_usb->gadget, &u);
|
||||
imx_usb->set_config = 0;
|
||||
D_REQ(imx_usb->dev, "<%s> Change config done\n",__func__);
|
||||
|
||||
}
|
||||
if (imx_usb->intf != intf || imx_usb->alt != alt) {
|
||||
D_REQ(imx_usb->dev, "<%s> Change interface start\n",__func__);
|
||||
u.bRequest = USB_REQ_SET_INTERFACE;
|
||||
u.bRequestType = USB_DIR_OUT |
|
||||
USB_TYPE_STANDARD |
|
||||
@@ -1087,20 +1061,92 @@ static irqreturn_t imx_udc_irq(int irq, void *dev)
|
||||
u.wLength = 0;
|
||||
imx_usb->intf = intf;
|
||||
imx_usb->alt = alt;
|
||||
imx_usb->set_config = 1;
|
||||
imx_usb->driver->setup(&imx_usb->gadget, &u);
|
||||
imx_usb->set_config = 0;
|
||||
D_REQ(imx_usb->dev, "<%s> Change interface done\n",__func__);
|
||||
}
|
||||
}
|
||||
|
||||
imx_usb->set_config = 0;
|
||||
|
||||
local_irq_enable();
|
||||
}
|
||||
|
||||
static irqreturn_t imx_udc_irq(int irq, void *dev)
|
||||
{
|
||||
struct imx_udc_struct *imx_usb = dev;
|
||||
int intr = __raw_readl(imx_usb->base + USB_INTR);
|
||||
int temp;
|
||||
|
||||
if (intr & (INTR_WAKEUP | INTR_SUSPEND | INTR_RESUME | INTR_RESET_START
|
||||
| INTR_RESET_STOP | INTR_CFG_CHG)) {
|
||||
dump_intr(__func__, intr, imx_usb->dev);
|
||||
dump_usb_stat(__func__, imx_usb);
|
||||
}
|
||||
|
||||
if (!imx_usb->driver)
|
||||
goto end_irq;
|
||||
|
||||
if (intr & INTR_SOF) {
|
||||
/* Copy from Freescale BSP.
|
||||
We must enable SOF intr and set CMDOVER.
|
||||
Datasheet don't specifiy this action, but it
|
||||
is done in Freescale BSP, so just copy it.
|
||||
*/
|
||||
if (imx_usb->ep0state == EP0_IDLE) {
|
||||
temp = __raw_readl(imx_usb->base + USB_CTRL);
|
||||
__raw_writel(temp | CTRL_CMDOVER, imx_usb->base + USB_CTRL);
|
||||
__raw_writel(temp | CTRL_CMDOVER,
|
||||
imx_usb->base + USB_CTRL);
|
||||
}
|
||||
}
|
||||
|
||||
if (intr & INTR_CFG_CHG) {
|
||||
/* A workaround of serious IMX UDC bug.
|
||||
Handling of CFG_CHG should be delayed for some time, because
|
||||
IMX does not NACK the host when CFG_CHG interrupt is pending.
|
||||
There is no time to handle current CFG_CHG
|
||||
if next CFG_CHG or SETUP packed is send immediately.
|
||||
We have to clear CFG_CHG, start the timer and
|
||||
NACK the host by setting CTRL_CMDOVER
|
||||
if it sends any SETUP packet.
|
||||
When timer expires, handler is called to handle configuration
|
||||
changes. While CFG_CHG is not handled (set_config=1),
|
||||
we must NACK the host to every SETUP packed.
|
||||
This delay prevents from going out of sync with host.
|
||||
*/
|
||||
__raw_writel(INTR_CFG_CHG, imx_usb->base + USB_INTR);
|
||||
imx_usb->set_config = 1;
|
||||
mod_timer(&imx_usb->timer, jiffies + 5);
|
||||
goto end_irq;
|
||||
}
|
||||
|
||||
if (intr & INTR_WAKEUP) {
|
||||
if (imx_usb->gadget.speed == USB_SPEED_UNKNOWN
|
||||
&& imx_usb->driver && imx_usb->driver->resume)
|
||||
imx_usb->driver->resume(&imx_usb->gadget);
|
||||
imx_usb->set_config = 0;
|
||||
del_timer(&imx_usb->timer);
|
||||
imx_usb->gadget.speed = USB_SPEED_FULL;
|
||||
}
|
||||
|
||||
if (intr & INTR_SUSPEND) {
|
||||
if (imx_usb->gadget.speed != USB_SPEED_UNKNOWN
|
||||
&& imx_usb->driver && imx_usb->driver->suspend)
|
||||
imx_usb->driver->suspend(&imx_usb->gadget);
|
||||
imx_usb->set_config = 0;
|
||||
del_timer(&imx_usb->timer);
|
||||
imx_usb->gadget.speed = USB_SPEED_UNKNOWN;
|
||||
}
|
||||
|
||||
if (intr & INTR_RESET_START) {
|
||||
__raw_writel(intr, imx_usb->base + USB_INTR);
|
||||
udc_stop_activity(imx_usb, imx_usb->driver);
|
||||
imx_usb->set_config = 0;
|
||||
del_timer(&imx_usb->timer);
|
||||
imx_usb->gadget.speed = USB_SPEED_UNKNOWN;
|
||||
}
|
||||
|
||||
if (intr & INTR_RESET_STOP)
|
||||
imx_usb->gadget.speed = USB_SPEED_FULL;
|
||||
|
||||
end_irq:
|
||||
__raw_writel(intr, imx_usb->base + USB_INTR);
|
||||
return IRQ_HANDLED;
|
||||
@@ -1109,6 +1155,7 @@ end_irq:
|
||||
static irqreturn_t imx_udc_ctrl_irq(int irq, void *dev)
|
||||
{
|
||||
struct imx_udc_struct *imx_usb = dev;
|
||||
struct imx_ep_struct *imx_ep = &imx_usb->imx_ep[0];
|
||||
int intr = __raw_readl(imx_usb->base + USB_EP_INTR(0));
|
||||
|
||||
dump_ep_intr(__func__, 0, intr, imx_usb->dev);
|
||||
@@ -1118,16 +1165,15 @@ static irqreturn_t imx_udc_ctrl_irq(int irq, void *dev)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/* DEVREQ IRQ has highest priority */
|
||||
/* DEVREQ has highest priority */
|
||||
if (intr & (EPINTR_DEVREQ | EPINTR_MDEVREQ))
|
||||
handle_ep0_devreq(imx_usb);
|
||||
/* Seem i.MX is missing EOF interrupt sometimes.
|
||||
* Therefore we monitor both EOF and FIFO_EMPTY interrups
|
||||
* when transmiting, and both EOF and FIFO_FULL when
|
||||
* receiving data.
|
||||
* Therefore we don't monitor EOF.
|
||||
* We call handle_ep0() only if a request is queued for ep0.
|
||||
*/
|
||||
else if (intr & (EPINTR_EOF | EPINTR_FIFO_EMPTY | EPINTR_FIFO_FULL))
|
||||
handle_ep0(&imx_usb->imx_ep[0]);
|
||||
else if (!list_empty(&imx_ep->queue))
|
||||
handle_ep0(imx_ep);
|
||||
|
||||
__raw_writel(intr, imx_usb->base + USB_EP_INTR(0));
|
||||
|
||||
@@ -1186,8 +1232,8 @@ static struct imx_udc_struct controller = {
|
||||
.ep0 = &controller.imx_ep[0].ep,
|
||||
.name = driver_name,
|
||||
.dev = {
|
||||
.bus_id = "gadget",
|
||||
},
|
||||
.init_name = "gadget",
|
||||
},
|
||||
},
|
||||
|
||||
.imx_ep[0] = {
|
||||
@@ -1318,6 +1364,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
|
||||
|
||||
udc_stop_activity(imx_usb, driver);
|
||||
imx_udc_disable(imx_usb);
|
||||
del_timer(&imx_usb->timer);
|
||||
|
||||
driver->unbind(&imx_usb->gadget);
|
||||
imx_usb->gadget.dev.driver = NULL;
|
||||
@@ -1435,6 +1482,10 @@ static int __init imx_udc_probe(struct platform_device *pdev)
|
||||
usb_init_data(imx_usb);
|
||||
imx_udc_init(imx_usb);
|
||||
|
||||
init_timer(&imx_usb->timer);
|
||||
imx_usb->timer.function = handle_config;
|
||||
imx_usb->timer.data = (unsigned long)imx_usb;
|
||||
|
||||
return 0;
|
||||
|
||||
fail3:
|
||||
@@ -1457,6 +1508,7 @@ static int __exit imx_udc_remove(struct platform_device *pdev)
|
||||
int i;
|
||||
|
||||
imx_udc_disable(imx_usb);
|
||||
del_timer(&imx_usb->timer);
|
||||
|
||||
for (i = 0; i < IMX_USB_NB_EP + 1; i++)
|
||||
free_irq(imx_usb->usbd_int[i], imx_usb);
|
||||
|
@@ -23,7 +23,8 @@
|
||||
/* Helper macros */
|
||||
#define EP_NO(ep) ((ep->bEndpointAddress) & ~USB_DIR_IN) /* IN:1, OUT:0 */
|
||||
#define EP_DIR(ep) ((ep->bEndpointAddress) & USB_DIR_IN ? 1 : 0)
|
||||
#define irq_to_ep(irq) (((irq) >= USBD_INT0) || ((irq) <= USBD_INT6) ? ((irq) - USBD_INT0) : (USBD_INT6)) /*should not happen*/
|
||||
#define irq_to_ep(irq) (((irq) >= USBD_INT0) || ((irq) <= USBD_INT6) \
|
||||
? ((irq) - USBD_INT0) : (USBD_INT6)) /*should not happen*/
|
||||
#define ep_to_irq(ep) (EP_NO((ep)) + USBD_INT0)
|
||||
#define IMX_USB_NB_EP 6
|
||||
|
||||
@@ -58,6 +59,7 @@ struct imx_udc_struct {
|
||||
struct device *dev;
|
||||
struct imx_ep_struct imx_ep[IMX_USB_NB_EP];
|
||||
struct clk *clk;
|
||||
struct timer_list timer;
|
||||
enum ep0_state ep0state;
|
||||
struct resource *res;
|
||||
void __iomem *base;
|
||||
@@ -88,8 +90,8 @@ struct imx_udc_struct {
|
||||
#define USB_EP_FDAT3(x) (0x3F + (x*0x30)) /* USB FIFO data */
|
||||
#define USB_EP_FSTAT(x) (0x40 + (x*0x30)) /* USB FIFO status */
|
||||
#define USB_EP_FCTRL(x) (0x44 + (x*0x30)) /* USB FIFO control */
|
||||
#define USB_EP_LRFP(x) (0x48 + (x*0x30)) /* USB last read frame pointer */
|
||||
#define USB_EP_LWFP(x) (0x4C + (x*0x30)) /* USB last write frame pointer */
|
||||
#define USB_EP_LRFP(x) (0x48 + (x*0x30)) /* USB last rd f. pointer */
|
||||
#define USB_EP_LWFP(x) (0x4C + (x*0x30)) /* USB last wr f. pointer */
|
||||
#define USB_EP_FALRM(x) (0x50 + (x*0x30)) /* USB FIFO alarm */
|
||||
#define USB_EP_FRDP(x) (0x54 + (x*0x30)) /* USB FIFO read pointer */
|
||||
#define USB_EP_FWRP(x) (0x58 + (x*0x30)) /* USB FIFO write pointer */
|
||||
@@ -170,7 +172,7 @@ struct imx_udc_struct {
|
||||
/* #define DEBUG_IRQ */
|
||||
/* #define DEBUG_EPIRQ */
|
||||
/* #define DEBUG_DUMP */
|
||||
#define DEBUG_ERR
|
||||
/* #define DEBUG_ERR */
|
||||
|
||||
#ifdef DEBUG_REQ
|
||||
#define D_REQ(dev, args...) dev_dbg(dev, ## args)
|
||||
@@ -228,7 +230,8 @@ struct imx_udc_struct {
|
||||
#endif /* DEBUG_IRQ */
|
||||
|
||||
#ifdef DEBUG_EPIRQ
|
||||
static void dump_ep_intr(const char *label, int nr, int irqreg, struct device *dev)
|
||||
static void dump_ep_intr(const char *label, int nr, int irqreg,
|
||||
struct device *dev)
|
||||
{
|
||||
dev_dbg(dev, "<%s> EP%d_INTR=[%s%s%s%s%s%s%s%s%s]\n", label, nr,
|
||||
(irqreg & EPINTR_FIFO_FULL) ? " full" : "",
|
||||
@@ -246,7 +249,8 @@ struct imx_udc_struct {
|
||||
#endif /* DEBUG_IRQ */
|
||||
|
||||
#ifdef DEBUG_DUMP
|
||||
static void dump_usb_stat(const char *label, struct imx_udc_struct *imx_usb)
|
||||
static void dump_usb_stat(const char *label,
|
||||
struct imx_udc_struct *imx_usb)
|
||||
{
|
||||
int temp = __raw_readl(imx_usb->base + USB_STAT);
|
||||
|
||||
@@ -259,12 +263,15 @@ struct imx_udc_struct {
|
||||
(temp & STAT_ALTSET));
|
||||
}
|
||||
|
||||
static void dump_ep_stat(const char *label, struct imx_ep_struct *imx_ep)
|
||||
static void dump_ep_stat(const char *label,
|
||||
struct imx_ep_struct *imx_ep)
|
||||
{
|
||||
int temp = __raw_readl(imx_ep->imx_usb->base + USB_EP_INTR(EP_NO(imx_ep)));
|
||||
int temp = __raw_readl(imx_ep->imx_usb->base
|
||||
+ USB_EP_INTR(EP_NO(imx_ep)));
|
||||
|
||||
dev_dbg(imx_ep->imx_usb->dev,
|
||||
"<%s> EP%d_INTR=[%s%s%s%s%s%s%s%s%s]\n", label, EP_NO(imx_ep),
|
||||
"<%s> EP%d_INTR=[%s%s%s%s%s%s%s%s%s]\n",
|
||||
label, EP_NO(imx_ep),
|
||||
(temp & EPINTR_FIFO_FULL) ? " full" : "",
|
||||
(temp & EPINTR_FIFO_EMPTY) ? " fempty" : "",
|
||||
(temp & EPINTR_FIFO_ERROR) ? " ferr" : "",
|
||||
@@ -275,18 +282,22 @@ struct imx_udc_struct {
|
||||
(temp & EPINTR_DEVREQ) ? " devreq" : "",
|
||||
(temp & EPINTR_EOT) ? " eot" : "");
|
||||
|
||||
temp = __raw_readl(imx_ep->imx_usb->base + USB_EP_STAT(EP_NO(imx_ep)));
|
||||
temp = __raw_readl(imx_ep->imx_usb->base
|
||||
+ USB_EP_STAT(EP_NO(imx_ep)));
|
||||
|
||||
dev_dbg(imx_ep->imx_usb->dev,
|
||||
"<%s> EP%d_STAT=[%s%s bcount=%d]\n", label, EP_NO(imx_ep),
|
||||
"<%s> EP%d_STAT=[%s%s bcount=%d]\n",
|
||||
label, EP_NO(imx_ep),
|
||||
(temp & EPSTAT_SIP) ? " sip" : "",
|
||||
(temp & EPSTAT_STALL) ? " stall" : "",
|
||||
(temp & EPSTAT_BCOUNT) >> 16);
|
||||
|
||||
temp = __raw_readl(imx_ep->imx_usb->base + USB_EP_FSTAT(EP_NO(imx_ep)));
|
||||
temp = __raw_readl(imx_ep->imx_usb->base
|
||||
+ USB_EP_FSTAT(EP_NO(imx_ep)));
|
||||
|
||||
dev_dbg(imx_ep->imx_usb->dev,
|
||||
"<%s> EP%d_FSTAT=[%s%s%s%s%s%s%s]\n", label, EP_NO(imx_ep),
|
||||
"<%s> EP%d_FSTAT=[%s%s%s%s%s%s%s]\n",
|
||||
label, EP_NO(imx_ep),
|
||||
(temp & FSTAT_ERR) ? " ferr" : "",
|
||||
(temp & FSTAT_UF) ? " funder" : "",
|
||||
(temp & FSTAT_OF) ? " fover" : "",
|
||||
@@ -296,19 +307,23 @@ struct imx_udc_struct {
|
||||
(temp & FSTAT_EMPTY) ? " fempty" : "");
|
||||
}
|
||||
|
||||
static void dump_req(const char *label, struct imx_ep_struct *imx_ep, struct usb_request *req)
|
||||
static void dump_req(const char *label, struct imx_ep_struct *imx_ep,
|
||||
struct usb_request *req)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!req || !req->buf) {
|
||||
dev_dbg(imx_ep->imx_usb->dev, "<%s> req or req buf is free\n", label);
|
||||
dev_dbg(imx_ep->imx_usb->dev,
|
||||
"<%s> req or req buf is free\n", label);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state == EP0_IN_DATA_PHASE)
|
||||
if ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state
|
||||
== EP0_IN_DATA_PHASE)
|
||||
|| (EP_NO(imx_ep) && EP_DIR(imx_ep))) {
|
||||
|
||||
dev_dbg(imx_ep->imx_usb->dev, "<%s> request dump <", label);
|
||||
dev_dbg(imx_ep->imx_usb->dev,
|
||||
"<%s> request dump <", label);
|
||||
for (i = 0; i < req->length; i++)
|
||||
printk("%02x-", *((u8 *)req->buf + i));
|
||||
printk(">\n");
|
||||
|
@@ -1334,7 +1334,7 @@ static void make_qualifier (struct dev_data *dev)
|
||||
|
||||
qual.bLength = sizeof qual;
|
||||
qual.bDescriptorType = USB_DT_DEVICE_QUALIFIER;
|
||||
qual.bcdUSB = __constant_cpu_to_le16 (0x0200);
|
||||
qual.bcdUSB = cpu_to_le16 (0x0200);
|
||||
|
||||
desc = dev->dev;
|
||||
qual.bDeviceClass = desc->bDeviceClass;
|
||||
@@ -1908,7 +1908,7 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
|
||||
|| dev->dev->bNumConfigurations != 1)
|
||||
goto fail;
|
||||
dev->dev->bNumConfigurations = 1;
|
||||
dev->dev->bcdUSB = __constant_cpu_to_le16 (0x0200);
|
||||
dev->dev->bcdUSB = cpu_to_le16 (0x0200);
|
||||
|
||||
/* triggers gadgetfs_bind(); then we can enumerate. */
|
||||
spin_unlock_irq (&dev->lock);
|
||||
|
@@ -432,8 +432,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
|
||||
device_add(&dev->gadget.dev);
|
||||
retval = driver->bind(&dev->gadget);
|
||||
if (retval) {
|
||||
printk("%s: bind to driver %s --> error %d\n", dev->gadget.name,
|
||||
driver->driver.name, retval);
|
||||
printk(KERN_WARNING "%s: bind to driver %s --> error %d\n",
|
||||
dev->gadget.name, driver->driver.name, retval);
|
||||
device_del(&dev->gadget.dev);
|
||||
|
||||
dev->driver = 0;
|
||||
@@ -445,8 +445,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
|
||||
* for set_configuration as well as eventual disconnect.
|
||||
* NOTE: this shouldn't power up until later.
|
||||
*/
|
||||
printk("%s: registered gadget driver '%s'\n", dev->gadget.name,
|
||||
driver->driver.name);
|
||||
printk(KERN_WARNING "%s: registered gadget driver '%s'\n",
|
||||
dev->gadget.name, driver->driver.name);
|
||||
|
||||
udc_enable(dev);
|
||||
|
||||
@@ -581,7 +581,8 @@ static int read_fifo(struct lh7a40x_ep *ep, struct lh7a40x_request *req)
|
||||
* discard the extra data.
|
||||
*/
|
||||
if (req->req.status != -EOVERFLOW)
|
||||
printk("%s overflow %d\n", ep->ep.name, count);
|
||||
printk(KERN_WARNING "%s overflow %d\n",
|
||||
ep->ep.name, count);
|
||||
req->req.status = -EOVERFLOW;
|
||||
} else {
|
||||
*buf++ = byte;
|
||||
@@ -831,7 +832,8 @@ static void lh7a40x_out_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr)
|
||||
queue);
|
||||
|
||||
if (!req) {
|
||||
printk("%s: NULL REQ %d\n",
|
||||
printk(KERN_WARNING
|
||||
"%s: NULL REQ %d\n",
|
||||
__func__, ep_idx);
|
||||
flush(ep);
|
||||
break;
|
||||
@@ -844,7 +846,7 @@ static void lh7a40x_out_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr)
|
||||
|
||||
} else {
|
||||
/* Throw packet away.. */
|
||||
printk("%s: No descriptor?!?\n", __func__);
|
||||
printk(KERN_WARNING "%s: No descriptor?!?\n", __func__);
|
||||
flush(ep);
|
||||
}
|
||||
}
|
||||
|
@@ -142,8 +142,8 @@ static char *type_string (u8 bmAttributes)
|
||||
|
||||
#include "net2280.h"
|
||||
|
||||
#define valid_bit __constant_cpu_to_le32 (1 << VALID_BIT)
|
||||
#define dma_done_ie __constant_cpu_to_le32 (1 << DMA_DONE_INTERRUPT_ENABLE)
|
||||
#define valid_bit cpu_to_le32 (1 << VALID_BIT)
|
||||
#define dma_done_ie cpu_to_le32 (1 << DMA_DONE_INTERRUPT_ENABLE)
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
@@ -425,7 +425,7 @@ net2280_alloc_request (struct usb_ep *_ep, gfp_t gfp_flags)
|
||||
return NULL;
|
||||
}
|
||||
td->dmacount = 0; /* not VALID */
|
||||
td->dmaaddr = __constant_cpu_to_le32 (DMA_ADDR_INVALID);
|
||||
td->dmaaddr = cpu_to_le32 (DMA_ADDR_INVALID);
|
||||
td->dmadesc = td->dmaaddr;
|
||||
req->td = td;
|
||||
}
|
||||
@@ -775,7 +775,7 @@ static void start_dma (struct net2280_ep *ep, struct net2280_request *req)
|
||||
fill_dma_desc (ep, req, 1);
|
||||
|
||||
if (!use_dma_chaining)
|
||||
req->td->dmacount |= __constant_cpu_to_le32 (1 << END_OF_CHAIN);
|
||||
req->td->dmacount |= cpu_to_le32 (1 << END_OF_CHAIN);
|
||||
|
||||
start_queue (ep, tmp, req->td_dma);
|
||||
}
|
||||
@@ -2407,9 +2407,9 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat)
|
||||
|
||||
if (readl (&e->regs->ep_rsp)
|
||||
& (1 << SET_ENDPOINT_HALT))
|
||||
status = __constant_cpu_to_le32 (1);
|
||||
status = cpu_to_le32 (1);
|
||||
else
|
||||
status = __constant_cpu_to_le32 (0);
|
||||
status = cpu_to_le32 (0);
|
||||
|
||||
/* don't bother with a request object! */
|
||||
writel (0, &dev->epregs [0].ep_irqenb);
|
||||
@@ -2667,7 +2667,7 @@ static void handle_stat1_irqs (struct net2280 *dev, u32 stat)
|
||||
req = list_entry (ep->queue.next,
|
||||
struct net2280_request, queue);
|
||||
dmacount = req->td->dmacount;
|
||||
dmacount &= __constant_cpu_to_le32 (
|
||||
dmacount &= cpu_to_le32 (
|
||||
(1 << VALID_BIT)
|
||||
| DMA_BYTE_COUNT_MASK);
|
||||
if (dmacount && (dmacount & valid_bit) == 0)
|
||||
@@ -2881,7 +2881,7 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
goto done;
|
||||
}
|
||||
td->dmacount = 0; /* not VALID */
|
||||
td->dmaaddr = __constant_cpu_to_le32 (DMA_ADDR_INVALID);
|
||||
td->dmaaddr = cpu_to_le32 (DMA_ADDR_INVALID);
|
||||
td->dmadesc = td->dmaaddr;
|
||||
dev->ep [i].dummy = td;
|
||||
}
|
||||
|
@@ -225,12 +225,12 @@ module_param(qlen, uint, S_IRUGO|S_IWUSR);
|
||||
static struct usb_device_descriptor device_desc = {
|
||||
.bLength = sizeof device_desc,
|
||||
.bDescriptorType = USB_DT_DEVICE,
|
||||
.bcdUSB = __constant_cpu_to_le16(0x0200),
|
||||
.bcdUSB = cpu_to_le16(0x0200),
|
||||
.bDeviceClass = USB_CLASS_PER_INTERFACE,
|
||||
.bDeviceSubClass = 0,
|
||||
.bDeviceProtocol = 0,
|
||||
.idVendor = __constant_cpu_to_le16(PRINTER_VENDOR_NUM),
|
||||
.idProduct = __constant_cpu_to_le16(PRINTER_PRODUCT_NUM),
|
||||
.idVendor = cpu_to_le16(PRINTER_VENDOR_NUM),
|
||||
.idProduct = cpu_to_le16(PRINTER_PRODUCT_NUM),
|
||||
.iManufacturer = STRING_MANUFACTURER,
|
||||
.iProduct = STRING_PRODUCT,
|
||||
.iSerialNumber = STRING_SERIALNUM,
|
||||
@@ -299,20 +299,20 @@ static struct usb_endpoint_descriptor hs_ep_in_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(512)
|
||||
.wMaxPacketSize = cpu_to_le16(512)
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor hs_ep_out_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(512)
|
||||
.wMaxPacketSize = cpu_to_le16(512)
|
||||
};
|
||||
|
||||
static struct usb_qualifier_descriptor dev_qualifier = {
|
||||
.bLength = sizeof dev_qualifier,
|
||||
.bDescriptorType = USB_DT_DEVICE_QUALIFIER,
|
||||
.bcdUSB = __constant_cpu_to_le16(0x0200),
|
||||
.bcdUSB = cpu_to_le16(0x0200),
|
||||
.bDeviceClass = USB_CLASS_PRINTER,
|
||||
.bNumConfigurations = 1
|
||||
};
|
||||
@@ -1406,16 +1406,16 @@ printer_bind(struct usb_gadget *gadget)
|
||||
gadget->name);
|
||||
/* unrecognized, but safe unless bulk is REALLY quirky */
|
||||
device_desc.bcdDevice =
|
||||
__constant_cpu_to_le16(0xFFFF);
|
||||
cpu_to_le16(0xFFFF);
|
||||
}
|
||||
snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s",
|
||||
init_utsname()->sysname, init_utsname()->release,
|
||||
gadget->name);
|
||||
|
||||
device_desc.idVendor =
|
||||
__constant_cpu_to_le16(PRINTER_VENDOR_NUM);
|
||||
cpu_to_le16(PRINTER_VENDOR_NUM);
|
||||
device_desc.idProduct =
|
||||
__constant_cpu_to_le16(PRINTER_PRODUCT_NUM);
|
||||
cpu_to_le16(PRINTER_PRODUCT_NUM);
|
||||
|
||||
/* support optional vendor/distro customization */
|
||||
if (idVendor) {
|
||||
|
@@ -904,8 +904,8 @@ static void pxa25x_ep_fifo_flush(struct usb_ep *_ep)
|
||||
|
||||
/* most IN status is the same, but ISO can't stall */
|
||||
*ep->reg_udccs = UDCCS_BI_TPC|UDCCS_BI_FTF|UDCCS_BI_TUR
|
||||
| (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC)
|
||||
? 0 : UDCCS_BI_SST;
|
||||
| (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC
|
||||
? 0 : UDCCS_BI_SST);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -30,6 +30,7 @@
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#include <asm/byteorder.h>
|
||||
#include <mach/hardware.h>
|
||||
@@ -278,7 +279,7 @@ static void pxa_init_debugfs(struct pxa_udc *udc)
|
||||
goto err_queues;
|
||||
eps = debugfs_create_file("epstate", 0400, root, udc,
|
||||
&eps_dbg_fops);
|
||||
if (!queues)
|
||||
if (!eps)
|
||||
goto err_eps;
|
||||
|
||||
udc->debugfs_root = root;
|
||||
@@ -747,13 +748,13 @@ static void req_done(struct pxa_ep *ep, struct pxa27x_request *req, int status)
|
||||
}
|
||||
|
||||
/**
|
||||
* ep_end_out_req - Ends control endpoint in request
|
||||
* ep_end_out_req - Ends endpoint OUT request
|
||||
* @ep: physical endpoint
|
||||
* @req: pxa request
|
||||
*
|
||||
* Context: ep->lock held
|
||||
*
|
||||
* Ends endpoint in request (completes usb request).
|
||||
* Ends endpoint OUT request (completes usb request).
|
||||
*/
|
||||
static void ep_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req)
|
||||
{
|
||||
@@ -762,13 +763,13 @@ static void ep_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req)
|
||||
}
|
||||
|
||||
/**
|
||||
* ep0_end_out_req - Ends control endpoint in request (ends data stage)
|
||||
* ep0_end_out_req - Ends control endpoint OUT request (ends data stage)
|
||||
* @ep: physical endpoint
|
||||
* @req: pxa request
|
||||
*
|
||||
* Context: ep->lock held
|
||||
*
|
||||
* Ends control endpoint in request (completes usb request), and puts
|
||||
* Ends control endpoint OUT request (completes usb request), and puts
|
||||
* control endpoint into idle state
|
||||
*/
|
||||
static void ep0_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req)
|
||||
@@ -779,13 +780,13 @@ static void ep0_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req)
|
||||
}
|
||||
|
||||
/**
|
||||
* ep_end_in_req - Ends endpoint out request
|
||||
* ep_end_in_req - Ends endpoint IN request
|
||||
* @ep: physical endpoint
|
||||
* @req: pxa request
|
||||
*
|
||||
* Context: ep->lock held
|
||||
*
|
||||
* Ends endpoint out request (completes usb request).
|
||||
* Ends endpoint IN request (completes usb request).
|
||||
*/
|
||||
static void ep_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req)
|
||||
{
|
||||
@@ -794,20 +795,18 @@ static void ep_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req)
|
||||
}
|
||||
|
||||
/**
|
||||
* ep0_end_in_req - Ends control endpoint out request (ends data stage)
|
||||
* ep0_end_in_req - Ends control endpoint IN request (ends data stage)
|
||||
* @ep: physical endpoint
|
||||
* @req: pxa request
|
||||
*
|
||||
* Context: ep->lock held
|
||||
*
|
||||
* Ends control endpoint out request (completes usb request), and puts
|
||||
* Ends control endpoint IN request (completes usb request), and puts
|
||||
* control endpoint into status state
|
||||
*/
|
||||
static void ep0_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req)
|
||||
{
|
||||
struct pxa_udc *udc = ep->dev;
|
||||
|
||||
set_ep0state(udc, IN_STATUS_STAGE);
|
||||
set_ep0state(ep->dev, IN_STATUS_STAGE);
|
||||
ep_end_in_req(ep, req);
|
||||
}
|
||||
|
||||
@@ -1167,7 +1166,7 @@ static int pxa_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
|
||||
ep_end_in_req(ep, req);
|
||||
} else {
|
||||
ep_err(ep, "got a request of %d bytes while"
|
||||
"in state WATI_ACK_SET_CONF_INTERF\n",
|
||||
"in state WAIT_ACK_SET_CONF_INTERF\n",
|
||||
length);
|
||||
ep_del_request(ep, req);
|
||||
rc = -EL2HLT;
|
||||
@@ -1213,30 +1212,26 @@ static int pxa_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
|
||||
struct udc_usb_ep *udc_usb_ep;
|
||||
struct pxa27x_request *req;
|
||||
unsigned long flags;
|
||||
int rc;
|
||||
int rc = -EINVAL;
|
||||
|
||||
if (!_ep)
|
||||
return -EINVAL;
|
||||
return rc;
|
||||
udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep);
|
||||
ep = udc_usb_ep->pxa_ep;
|
||||
if (!ep || is_ep0(ep))
|
||||
return -EINVAL;
|
||||
return rc;
|
||||
|
||||
spin_lock_irqsave(&ep->lock, flags);
|
||||
|
||||
/* make sure it's actually queued on this endpoint */
|
||||
list_for_each_entry(req, &ep->queue, queue) {
|
||||
if (&req->req == _req)
|
||||
if (&req->req == _req) {
|
||||
req_done(ep, req, -ECONNRESET);
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rc = -EINVAL;
|
||||
if (&req->req != _req)
|
||||
goto out;
|
||||
|
||||
rc = 0;
|
||||
req_done(ep, req, -ECONNRESET);
|
||||
out:
|
||||
spin_unlock_irqrestore(&ep->lock, flags);
|
||||
return rc;
|
||||
}
|
||||
@@ -1471,6 +1466,32 @@ static struct usb_ep_ops pxa_ep_ops = {
|
||||
.fifo_flush = pxa_ep_fifo_flush,
|
||||
};
|
||||
|
||||
/**
|
||||
* dplus_pullup - Connect or disconnect pullup resistor to D+ pin
|
||||
* @udc: udc device
|
||||
* @on: 0 if disconnect pullup resistor, 1 otherwise
|
||||
* Context: any
|
||||
*
|
||||
* Handle D+ pullup resistor, make the device visible to the usb bus, and
|
||||
* declare it as a full speed usb device
|
||||
*/
|
||||
static void dplus_pullup(struct pxa_udc *udc, int on)
|
||||
{
|
||||
if (on) {
|
||||
if (gpio_is_valid(udc->mach->gpio_pullup))
|
||||
gpio_set_value(udc->mach->gpio_pullup,
|
||||
!udc->mach->gpio_pullup_inverted);
|
||||
if (udc->mach->udc_command)
|
||||
udc->mach->udc_command(PXA2XX_UDC_CMD_CONNECT);
|
||||
} else {
|
||||
if (gpio_is_valid(udc->mach->gpio_pullup))
|
||||
gpio_set_value(udc->mach->gpio_pullup,
|
||||
udc->mach->gpio_pullup_inverted);
|
||||
if (udc->mach->udc_command)
|
||||
udc->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT);
|
||||
}
|
||||
udc->pullup_on = on;
|
||||
}
|
||||
|
||||
/**
|
||||
* pxa_udc_get_frame - Returns usb frame number
|
||||
@@ -1500,21 +1521,145 @@ static int pxa_udc_wakeup(struct usb_gadget *_gadget)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void udc_enable(struct pxa_udc *udc);
|
||||
static void udc_disable(struct pxa_udc *udc);
|
||||
|
||||
/**
|
||||
* should_enable_udc - Tells if UDC should be enabled
|
||||
* @udc: udc device
|
||||
* Context: any
|
||||
*
|
||||
* The UDC should be enabled if :
|
||||
|
||||
* - the pullup resistor is connected
|
||||
* - and a gadget driver is bound
|
||||
* - and vbus is sensed (or no vbus sense is available)
|
||||
*
|
||||
* Returns 1 if UDC should be enabled, 0 otherwise
|
||||
*/
|
||||
static int should_enable_udc(struct pxa_udc *udc)
|
||||
{
|
||||
int put_on;
|
||||
|
||||
put_on = ((udc->pullup_on) && (udc->driver));
|
||||
put_on &= ((udc->vbus_sensed) || (!udc->transceiver));
|
||||
return put_on;
|
||||
}
|
||||
|
||||
/**
|
||||
* should_disable_udc - Tells if UDC should be disabled
|
||||
* @udc: udc device
|
||||
* Context: any
|
||||
*
|
||||
* The UDC should be disabled if :
|
||||
* - the pullup resistor is not connected
|
||||
* - or no gadget driver is bound
|
||||
* - or no vbus is sensed (when vbus sesing is available)
|
||||
*
|
||||
* Returns 1 if UDC should be disabled
|
||||
*/
|
||||
static int should_disable_udc(struct pxa_udc *udc)
|
||||
{
|
||||
int put_off;
|
||||
|
||||
put_off = ((!udc->pullup_on) || (!udc->driver));
|
||||
put_off |= ((!udc->vbus_sensed) && (udc->transceiver));
|
||||
return put_off;
|
||||
}
|
||||
|
||||
/**
|
||||
* pxa_udc_pullup - Offer manual D+ pullup control
|
||||
* @_gadget: usb gadget using the control
|
||||
* @is_active: 0 if disconnect, else connect D+ pullup resistor
|
||||
* Context: !in_interrupt()
|
||||
*
|
||||
* Returns 0 if OK, -EOPNOTSUPP if udc driver doesn't handle D+ pullup
|
||||
*/
|
||||
static int pxa_udc_pullup(struct usb_gadget *_gadget, int is_active)
|
||||
{
|
||||
struct pxa_udc *udc = to_gadget_udc(_gadget);
|
||||
|
||||
if (!gpio_is_valid(udc->mach->gpio_pullup) && !udc->mach->udc_command)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
dplus_pullup(udc, is_active);
|
||||
|
||||
if (should_enable_udc(udc))
|
||||
udc_enable(udc);
|
||||
if (should_disable_udc(udc))
|
||||
udc_disable(udc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void udc_enable(struct pxa_udc *udc);
|
||||
static void udc_disable(struct pxa_udc *udc);
|
||||
|
||||
/**
|
||||
* pxa_udc_vbus_session - Called by external transceiver to enable/disable udc
|
||||
* @_gadget: usb gadget
|
||||
* @is_active: 0 if should disable the udc, 1 if should enable
|
||||
*
|
||||
* Enables the udc, and optionnaly activates D+ pullup resistor. Or disables the
|
||||
* udc, and deactivates D+ pullup resistor.
|
||||
*
|
||||
* Returns 0
|
||||
*/
|
||||
static int pxa_udc_vbus_session(struct usb_gadget *_gadget, int is_active)
|
||||
{
|
||||
struct pxa_udc *udc = to_gadget_udc(_gadget);
|
||||
|
||||
udc->vbus_sensed = is_active;
|
||||
if (should_enable_udc(udc))
|
||||
udc_enable(udc);
|
||||
if (should_disable_udc(udc))
|
||||
udc_disable(udc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* pxa_udc_vbus_draw - Called by gadget driver after SET_CONFIGURATION completed
|
||||
* @_gadget: usb gadget
|
||||
* @mA: current drawn
|
||||
*
|
||||
* Context: !in_interrupt()
|
||||
*
|
||||
* Called after a configuration was chosen by a USB host, to inform how much
|
||||
* current can be drawn by the device from VBus line.
|
||||
*
|
||||
* Returns 0 or -EOPNOTSUPP if no transceiver is handling the udc
|
||||
*/
|
||||
static int pxa_udc_vbus_draw(struct usb_gadget *_gadget, unsigned mA)
|
||||
{
|
||||
struct pxa_udc *udc;
|
||||
|
||||
udc = to_gadget_udc(_gadget);
|
||||
if (udc->transceiver)
|
||||
return otg_set_power(udc->transceiver, mA);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static const struct usb_gadget_ops pxa_udc_ops = {
|
||||
.get_frame = pxa_udc_get_frame,
|
||||
.wakeup = pxa_udc_wakeup,
|
||||
/* current versions must always be self-powered */
|
||||
.pullup = pxa_udc_pullup,
|
||||
.vbus_session = pxa_udc_vbus_session,
|
||||
.vbus_draw = pxa_udc_vbus_draw,
|
||||
};
|
||||
|
||||
/**
|
||||
* udc_disable - disable udc device controller
|
||||
* @udc: udc device
|
||||
* Context: any
|
||||
*
|
||||
* Disables the udc device : disables clocks, udc interrupts, control endpoint
|
||||
* interrupts.
|
||||
*/
|
||||
static void udc_disable(struct pxa_udc *udc)
|
||||
{
|
||||
if (!udc->enabled)
|
||||
return;
|
||||
|
||||
udc_writel(udc, UDCICR0, 0);
|
||||
udc_writel(udc, UDCICR1, 0);
|
||||
|
||||
@@ -1523,8 +1668,8 @@ static void udc_disable(struct pxa_udc *udc)
|
||||
|
||||
ep0_idle(udc);
|
||||
udc->gadget.speed = USB_SPEED_UNKNOWN;
|
||||
if (udc->mach->udc_command)
|
||||
udc->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT);
|
||||
|
||||
udc->enabled = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1555,10 +1700,9 @@ static __init void udc_init_data(struct pxa_udc *dev)
|
||||
}
|
||||
|
||||
/* USB endpoints init */
|
||||
for (i = 0; i < NR_USB_ENDPOINTS; i++)
|
||||
if (i != 0)
|
||||
list_add_tail(&dev->udc_usb_ep[i].usb_ep.ep_list,
|
||||
&dev->gadget.ep_list);
|
||||
for (i = 1; i < NR_USB_ENDPOINTS; i++)
|
||||
list_add_tail(&dev->udc_usb_ep[i].usb_ep.ep_list,
|
||||
&dev->gadget.ep_list);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1570,6 +1714,9 @@ static __init void udc_init_data(struct pxa_udc *dev)
|
||||
*/
|
||||
static void udc_enable(struct pxa_udc *udc)
|
||||
{
|
||||
if (udc->enabled)
|
||||
return;
|
||||
|
||||
udc_writel(udc, UDCICR0, 0);
|
||||
udc_writel(udc, UDCICR1, 0);
|
||||
udc_clear_mask_UDCCR(udc, UDCCR_UDE);
|
||||
@@ -1598,9 +1745,7 @@ static void udc_enable(struct pxa_udc *udc)
|
||||
/* enable ep0 irqs */
|
||||
pio_irq_enable(&udc->pxa_ep[0]);
|
||||
|
||||
dev_info(udc->dev, "UDC connecting\n");
|
||||
if (udc->mach->udc_command)
|
||||
udc->mach->udc_command(PXA2XX_UDC_CMD_CONNECT);
|
||||
udc->enabled = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1612,6 +1757,9 @@ static void udc_enable(struct pxa_udc *udc)
|
||||
* usb traffic follows until a disconnect is reported. Then a host may connect
|
||||
* again, or the driver might get unbound.
|
||||
*
|
||||
* Note that the udc is not automatically enabled. Check function
|
||||
* should_enable_udc().
|
||||
*
|
||||
* Returns 0 if no error, -EINVAL, -ENODEV, -EBUSY otherwise
|
||||
*/
|
||||
int usb_gadget_register_driver(struct usb_gadget_driver *driver)
|
||||
@@ -1630,6 +1778,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
|
||||
/* first hook up the driver ... */
|
||||
udc->driver = driver;
|
||||
udc->gadget.dev.driver = &driver->driver;
|
||||
dplus_pullup(udc, 1);
|
||||
|
||||
retval = device_add(&udc->gadget.dev);
|
||||
if (retval) {
|
||||
@@ -1645,9 +1794,21 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
|
||||
dev_dbg(udc->dev, "registered gadget driver '%s'\n",
|
||||
driver->driver.name);
|
||||
|
||||
udc_enable(udc);
|
||||
if (udc->transceiver) {
|
||||
retval = otg_set_peripheral(udc->transceiver, &udc->gadget);
|
||||
if (retval) {
|
||||
dev_err(udc->dev, "can't bind to transceiver\n");
|
||||
goto transceiver_fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (should_enable_udc(udc))
|
||||
udc_enable(udc);
|
||||
return 0;
|
||||
|
||||
transceiver_fail:
|
||||
if (driver->unbind)
|
||||
driver->unbind(&udc->gadget);
|
||||
bind_fail:
|
||||
device_del(&udc->gadget.dev);
|
||||
add_fail:
|
||||
@@ -1699,14 +1860,17 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
|
||||
|
||||
stop_activity(udc, driver);
|
||||
udc_disable(udc);
|
||||
dplus_pullup(udc, 0);
|
||||
|
||||
driver->unbind(&udc->gadget);
|
||||
udc->driver = NULL;
|
||||
|
||||
device_del(&udc->gadget.dev);
|
||||
|
||||
dev_info(udc->dev, "unregistered gadget driver '%s'\n",
|
||||
driver->driver.name);
|
||||
|
||||
if (udc->transceiver)
|
||||
return otg_set_peripheral(udc->transceiver, NULL);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(usb_gadget_unregister_driver);
|
||||
@@ -1823,14 +1987,14 @@ static void handle_ep0(struct pxa_udc *udc, int fifo_irq, int opc_irq)
|
||||
struct pxa27x_request *req = NULL;
|
||||
int completed = 0;
|
||||
|
||||
if (!list_empty(&ep->queue))
|
||||
req = list_entry(ep->queue.next, struct pxa27x_request, queue);
|
||||
|
||||
udccsr0 = udc_ep_readl(ep, UDCCSR);
|
||||
ep_dbg(ep, "state=%s, req=%p, udccsr0=0x%03x, udcbcr=%d, irq_msk=%x\n",
|
||||
EP0_STNAME(udc), req, udccsr0, udc_ep_readl(ep, UDCBCR),
|
||||
(fifo_irq << 1 | opc_irq));
|
||||
|
||||
if (!list_empty(&ep->queue))
|
||||
req = list_entry(ep->queue.next, struct pxa27x_request, queue);
|
||||
|
||||
if (udccsr0 & UDCCSR0_SST) {
|
||||
ep_dbg(ep, "clearing stall status\n");
|
||||
nuke(ep, -EPIPE);
|
||||
@@ -2212,7 +2376,7 @@ static int __init pxa_udc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *regs;
|
||||
struct pxa_udc *udc = &memory;
|
||||
int retval;
|
||||
int retval = 0, gpio;
|
||||
|
||||
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!regs)
|
||||
@@ -2223,6 +2387,20 @@ static int __init pxa_udc_probe(struct platform_device *pdev)
|
||||
|
||||
udc->dev = &pdev->dev;
|
||||
udc->mach = pdev->dev.platform_data;
|
||||
udc->transceiver = otg_get_transceiver();
|
||||
|
||||
gpio = udc->mach->gpio_pullup;
|
||||
if (gpio_is_valid(gpio)) {
|
||||
retval = gpio_request(gpio, "USB D+ pullup");
|
||||
if (retval == 0)
|
||||
gpio_direction_output(gpio,
|
||||
udc->mach->gpio_pullup_inverted);
|
||||
}
|
||||
if (retval) {
|
||||
dev_err(&pdev->dev, "Couldn't request gpio %d : %d\n",
|
||||
gpio, retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
udc->clk = clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(udc->clk)) {
|
||||
@@ -2240,6 +2418,7 @@ static int __init pxa_udc_probe(struct platform_device *pdev)
|
||||
device_initialize(&udc->gadget.dev);
|
||||
udc->gadget.dev.parent = &pdev->dev;
|
||||
udc->gadget.dev.dma_mask = NULL;
|
||||
udc->vbus_sensed = 0;
|
||||
|
||||
the_controller = udc;
|
||||
platform_set_drvdata(pdev, udc);
|
||||
@@ -2273,14 +2452,21 @@ err_clk:
|
||||
static int __exit pxa_udc_remove(struct platform_device *_dev)
|
||||
{
|
||||
struct pxa_udc *udc = platform_get_drvdata(_dev);
|
||||
int gpio = udc->mach->gpio_pullup;
|
||||
|
||||
usb_gadget_unregister_driver(udc->driver);
|
||||
free_irq(udc->irq, udc);
|
||||
pxa_cleanup_debugfs(udc);
|
||||
if (gpio_is_valid(gpio))
|
||||
gpio_free(gpio);
|
||||
|
||||
otg_put_transceiver(udc->transceiver);
|
||||
|
||||
udc->transceiver = NULL;
|
||||
platform_set_drvdata(_dev, NULL);
|
||||
the_controller = NULL;
|
||||
clk_put(udc->clk);
|
||||
iounmap(udc->regs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2319,6 +2505,8 @@ static int pxa_udc_suspend(struct platform_device *_dev, pm_message_t state)
|
||||
}
|
||||
|
||||
udc_disable(udc);
|
||||
udc->pullup_resume = udc->pullup_on;
|
||||
dplus_pullup(udc, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2346,7 +2534,9 @@ static int pxa_udc_resume(struct platform_device *_dev)
|
||||
ep->udccsr_value, ep->udccr_value);
|
||||
}
|
||||
|
||||
udc_enable(udc);
|
||||
dplus_pullup(udc, udc->pullup_resume);
|
||||
if (should_enable_udc(udc))
|
||||
udc_enable(udc);
|
||||
/*
|
||||
* We do not handle OTG yet.
|
||||
*
|
||||
|
@@ -26,6 +26,7 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/usb/otg.h>
|
||||
|
||||
/*
|
||||
* Register definitions
|
||||
@@ -421,10 +422,14 @@ struct udc_stats {
|
||||
* @driver: bound gadget (zero, g_ether, g_file_storage, ...)
|
||||
* @dev: device
|
||||
* @mach: machine info, used to activate specific GPIO
|
||||
* @transceiver: external transceiver to handle vbus sense and D+ pullup
|
||||
* @ep0state: control endpoint state machine state
|
||||
* @stats: statistics on udc usage
|
||||
* @udc_usb_ep: array of usb endpoints offered by the gadget
|
||||
* @pxa_ep: array of pxa available endpoints
|
||||
* @enabled: UDC was enabled by a previous udc_enable()
|
||||
* @pullup_on: if pullup resistor connected to D+ pin
|
||||
* @pullup_resume: if pullup resistor should be connected to D+ pin on resume
|
||||
* @config: UDC active configuration
|
||||
* @last_interface: UDC interface of the last SET_INTERFACE host request
|
||||
* @last_alternate: UDC altsetting of the last SET_INTERFACE host request
|
||||
@@ -443,6 +448,7 @@ struct pxa_udc {
|
||||
struct usb_gadget_driver *driver;
|
||||
struct device *dev;
|
||||
struct pxa2xx_udc_mach_info *mach;
|
||||
struct otg_transceiver *transceiver;
|
||||
|
||||
enum ep0_state ep0state;
|
||||
struct udc_stats stats;
|
||||
@@ -450,6 +456,10 @@ struct pxa_udc {
|
||||
struct udc_usb_ep udc_usb_ep[NR_USB_ENDPOINTS];
|
||||
struct pxa_ep pxa_ep[NR_PXA_ENDPOINTS];
|
||||
|
||||
unsigned enabled:1;
|
||||
unsigned pullup_on:1;
|
||||
unsigned pullup_resume:1;
|
||||
unsigned vbus_sensed:1;
|
||||
unsigned config:2;
|
||||
unsigned last_interface:3;
|
||||
unsigned last_alternate:3;
|
||||
|
@@ -63,7 +63,7 @@ MODULE_PARM_DESC (rndis_debug, "enable debugging");
|
||||
static rndis_params rndis_per_dev_params [RNDIS_MAX_CONFIGS];
|
||||
|
||||
/* Driver Version */
|
||||
static const __le32 rndis_driver_version = __constant_cpu_to_le32 (1);
|
||||
static const __le32 rndis_driver_version = cpu_to_le32 (1);
|
||||
|
||||
/* Function Prototypes */
|
||||
static rndis_resp_t *rndis_add_response (int configNr, u32 length);
|
||||
@@ -170,7 +170,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
||||
int i, count;
|
||||
rndis_query_cmplt_type *resp;
|
||||
struct net_device *net;
|
||||
struct net_device_stats *stats;
|
||||
const struct net_device_stats *stats;
|
||||
|
||||
if (!r) return -ENOMEM;
|
||||
resp = (rndis_query_cmplt_type *) r->buf;
|
||||
@@ -190,13 +190,10 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
||||
|
||||
/* response goes here, right after the header */
|
||||
outbuf = (__le32 *) &resp[1];
|
||||
resp->InformationBufferOffset = __constant_cpu_to_le32 (16);
|
||||
resp->InformationBufferOffset = cpu_to_le32 (16);
|
||||
|
||||
net = rndis_per_dev_params[configNr].dev;
|
||||
if (net->get_stats)
|
||||
stats = net->get_stats(net);
|
||||
else
|
||||
stats = NULL;
|
||||
stats = dev_get_stats(net);
|
||||
|
||||
switch (OID) {
|
||||
|
||||
@@ -221,7 +218,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
||||
* reddite ergo quae sunt Caesaris Caesari
|
||||
* et quae sunt Dei Deo!
|
||||
*/
|
||||
*outbuf = __constant_cpu_to_le32 (0);
|
||||
*outbuf = cpu_to_le32 (0);
|
||||
retval = 0;
|
||||
break;
|
||||
|
||||
@@ -256,7 +253,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
||||
pr_debug("%s: OID_GEN_LINK_SPEED\n", __func__);
|
||||
if (rndis_per_dev_params [configNr].media_state
|
||||
== NDIS_MEDIA_STATE_DISCONNECTED)
|
||||
*outbuf = __constant_cpu_to_le32 (0);
|
||||
*outbuf = cpu_to_le32 (0);
|
||||
else
|
||||
*outbuf = cpu_to_le32 (
|
||||
rndis_per_dev_params [configNr].speed);
|
||||
@@ -317,7 +314,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
||||
/* mandatory */
|
||||
case OID_GEN_MAXIMUM_TOTAL_SIZE:
|
||||
pr_debug("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __func__);
|
||||
*outbuf = __constant_cpu_to_le32(RNDIS_MAX_TOTAL_SIZE);
|
||||
*outbuf = cpu_to_le32(RNDIS_MAX_TOTAL_SIZE);
|
||||
retval = 0;
|
||||
break;
|
||||
|
||||
@@ -332,7 +329,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
||||
|
||||
case OID_GEN_PHYSICAL_MEDIUM:
|
||||
pr_debug("%s: OID_GEN_PHYSICAL_MEDIUM\n", __func__);
|
||||
*outbuf = __constant_cpu_to_le32 (0);
|
||||
*outbuf = cpu_to_le32 (0);
|
||||
retval = 0;
|
||||
break;
|
||||
|
||||
@@ -342,7 +339,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
||||
*/
|
||||
case OID_GEN_MAC_OPTIONS: /* from WinME */
|
||||
pr_debug("%s: OID_GEN_MAC_OPTIONS\n", __func__);
|
||||
*outbuf = __constant_cpu_to_le32(
|
||||
*outbuf = cpu_to_le32(
|
||||
NDIS_MAC_OPTION_RECEIVE_SERIALIZED
|
||||
| NDIS_MAC_OPTION_FULL_DUPLEX);
|
||||
retval = 0;
|
||||
@@ -431,7 +428,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
||||
case OID_802_3_MULTICAST_LIST:
|
||||
pr_debug("%s: OID_802_3_MULTICAST_LIST\n", __func__);
|
||||
/* Multicast base address only */
|
||||
*outbuf = __constant_cpu_to_le32 (0xE0000000);
|
||||
*outbuf = cpu_to_le32 (0xE0000000);
|
||||
retval = 0;
|
||||
break;
|
||||
|
||||
@@ -439,7 +436,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
||||
case OID_802_3_MAXIMUM_LIST_SIZE:
|
||||
pr_debug("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __func__);
|
||||
/* Multicast base address only */
|
||||
*outbuf = __constant_cpu_to_le32 (1);
|
||||
*outbuf = cpu_to_le32 (1);
|
||||
retval = 0;
|
||||
break;
|
||||
|
||||
@@ -461,14 +458,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
||||
/* mandatory */
|
||||
case OID_802_3_XMIT_ONE_COLLISION:
|
||||
pr_debug("%s: OID_802_3_XMIT_ONE_COLLISION\n", __func__);
|
||||
*outbuf = __constant_cpu_to_le32 (0);
|
||||
*outbuf = cpu_to_le32 (0);
|
||||
retval = 0;
|
||||
break;
|
||||
|
||||
/* mandatory */
|
||||
case OID_802_3_XMIT_MORE_COLLISIONS:
|
||||
pr_debug("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __func__);
|
||||
*outbuf = __constant_cpu_to_le32 (0);
|
||||
*outbuf = cpu_to_le32 (0);
|
||||
retval = 0;
|
||||
break;
|
||||
|
||||
@@ -572,24 +569,24 @@ static int rndis_init_response (int configNr, rndis_init_msg_type *buf)
|
||||
return -ENOMEM;
|
||||
resp = (rndis_init_cmplt_type *) r->buf;
|
||||
|
||||
resp->MessageType = __constant_cpu_to_le32 (
|
||||
resp->MessageType = cpu_to_le32 (
|
||||
REMOTE_NDIS_INITIALIZE_CMPLT);
|
||||
resp->MessageLength = __constant_cpu_to_le32 (52);
|
||||
resp->MessageLength = cpu_to_le32 (52);
|
||||
resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
|
||||
resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
|
||||
resp->MajorVersion = __constant_cpu_to_le32 (RNDIS_MAJOR_VERSION);
|
||||
resp->MinorVersion = __constant_cpu_to_le32 (RNDIS_MINOR_VERSION);
|
||||
resp->DeviceFlags = __constant_cpu_to_le32 (RNDIS_DF_CONNECTIONLESS);
|
||||
resp->Medium = __constant_cpu_to_le32 (RNDIS_MEDIUM_802_3);
|
||||
resp->MaxPacketsPerTransfer = __constant_cpu_to_le32 (1);
|
||||
resp->Status = cpu_to_le32 (RNDIS_STATUS_SUCCESS);
|
||||
resp->MajorVersion = cpu_to_le32 (RNDIS_MAJOR_VERSION);
|
||||
resp->MinorVersion = cpu_to_le32 (RNDIS_MINOR_VERSION);
|
||||
resp->DeviceFlags = cpu_to_le32 (RNDIS_DF_CONNECTIONLESS);
|
||||
resp->Medium = cpu_to_le32 (RNDIS_MEDIUM_802_3);
|
||||
resp->MaxPacketsPerTransfer = cpu_to_le32 (1);
|
||||
resp->MaxTransferSize = cpu_to_le32 (
|
||||
params->dev->mtu
|
||||
+ sizeof (struct ethhdr)
|
||||
+ sizeof (struct rndis_packet_msg_type)
|
||||
+ 22);
|
||||
resp->PacketAlignmentFactor = __constant_cpu_to_le32 (0);
|
||||
resp->AFListOffset = __constant_cpu_to_le32 (0);
|
||||
resp->AFListSize = __constant_cpu_to_le32 (0);
|
||||
resp->PacketAlignmentFactor = cpu_to_le32 (0);
|
||||
resp->AFListOffset = cpu_to_le32 (0);
|
||||
resp->AFListSize = cpu_to_le32 (0);
|
||||
|
||||
params->resp_avail(params->v);
|
||||
return 0;
|
||||
@@ -617,7 +614,7 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf)
|
||||
return -ENOMEM;
|
||||
resp = (rndis_query_cmplt_type *) r->buf;
|
||||
|
||||
resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_QUERY_CMPLT);
|
||||
resp->MessageType = 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),
|
||||
@@ -626,13 +623,13 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf)
|
||||
le32_to_cpu(buf->InformationBufferLength),
|
||||
r)) {
|
||||
/* OID not supported */
|
||||
resp->Status = __constant_cpu_to_le32 (
|
||||
resp->Status = cpu_to_le32 (
|
||||
RNDIS_STATUS_NOT_SUPPORTED);
|
||||
resp->MessageLength = __constant_cpu_to_le32 (sizeof *resp);
|
||||
resp->InformationBufferLength = __constant_cpu_to_le32 (0);
|
||||
resp->InformationBufferOffset = __constant_cpu_to_le32 (0);
|
||||
resp->MessageLength = cpu_to_le32 (sizeof *resp);
|
||||
resp->InformationBufferLength = cpu_to_le32 (0);
|
||||
resp->InformationBufferOffset = cpu_to_le32 (0);
|
||||
} else
|
||||
resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
|
||||
resp->Status = cpu_to_le32 (RNDIS_STATUS_SUCCESS);
|
||||
|
||||
params->resp_avail(params->v);
|
||||
return 0;
|
||||
@@ -665,14 +662,14 @@ static int rndis_set_response (int configNr, rndis_set_msg_type *buf)
|
||||
pr_debug("\n");
|
||||
#endif
|
||||
|
||||
resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_SET_CMPLT);
|
||||
resp->MessageLength = __constant_cpu_to_le32 (16);
|
||||
resp->MessageType = cpu_to_le32 (REMOTE_NDIS_SET_CMPLT);
|
||||
resp->MessageLength = 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);
|
||||
resp->Status = cpu_to_le32 (RNDIS_STATUS_NOT_SUPPORTED);
|
||||
else
|
||||
resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
|
||||
resp->Status = cpu_to_le32 (RNDIS_STATUS_SUCCESS);
|
||||
|
||||
params->resp_avail(params->v);
|
||||
return 0;
|
||||
@@ -689,11 +686,11 @@ static int rndis_reset_response (int configNr, rndis_reset_msg_type *buf)
|
||||
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);
|
||||
resp->MessageType = cpu_to_le32 (REMOTE_NDIS_RESET_CMPLT);
|
||||
resp->MessageLength = cpu_to_le32 (16);
|
||||
resp->Status = cpu_to_le32 (RNDIS_STATUS_SUCCESS);
|
||||
/* resent information */
|
||||
resp->AddressingReset = __constant_cpu_to_le32 (1);
|
||||
resp->AddressingReset = cpu_to_le32 (1);
|
||||
|
||||
params->resp_avail(params->v);
|
||||
return 0;
|
||||
@@ -713,11 +710,11 @@ static int rndis_keepalive_response (int configNr,
|
||||
return -ENOMEM;
|
||||
resp = (rndis_keepalive_cmplt_type *) r->buf;
|
||||
|
||||
resp->MessageType = __constant_cpu_to_le32 (
|
||||
resp->MessageType = cpu_to_le32 (
|
||||
REMOTE_NDIS_KEEPALIVE_CMPLT);
|
||||
resp->MessageLength = __constant_cpu_to_le32 (16);
|
||||
resp->MessageLength = cpu_to_le32 (16);
|
||||
resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
|
||||
resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
|
||||
resp->Status = cpu_to_le32 (RNDIS_STATUS_SUCCESS);
|
||||
|
||||
params->resp_avail(params->v);
|
||||
return 0;
|
||||
@@ -742,12 +739,12 @@ static int rndis_indicate_status_msg (int configNr, u32 status)
|
||||
return -ENOMEM;
|
||||
resp = (rndis_indicate_status_msg_type *) r->buf;
|
||||
|
||||
resp->MessageType = __constant_cpu_to_le32 (
|
||||
resp->MessageType = cpu_to_le32 (
|
||||
REMOTE_NDIS_INDICATE_STATUS_MSG);
|
||||
resp->MessageLength = __constant_cpu_to_le32 (20);
|
||||
resp->MessageLength = cpu_to_le32 (20);
|
||||
resp->Status = cpu_to_le32 (status);
|
||||
resp->StatusBufferLength = __constant_cpu_to_le32 (0);
|
||||
resp->StatusBufferOffset = __constant_cpu_to_le32 (0);
|
||||
resp->StatusBufferLength = cpu_to_le32 (0);
|
||||
resp->StatusBufferOffset = cpu_to_le32 (0);
|
||||
|
||||
params->resp_avail(params->v);
|
||||
return 0;
|
||||
@@ -963,9 +960,9 @@ void rndis_add_hdr (struct sk_buff *skb)
|
||||
return;
|
||||
header = (void *) skb_push (skb, sizeof *header);
|
||||
memset (header, 0, sizeof *header);
|
||||
header->MessageType = __constant_cpu_to_le32(REMOTE_NDIS_PACKET_MSG);
|
||||
header->MessageType = cpu_to_le32(REMOTE_NDIS_PACKET_MSG);
|
||||
header->MessageLength = cpu_to_le32(skb->len);
|
||||
header->DataOffset = __constant_cpu_to_le32 (36);
|
||||
header->DataOffset = cpu_to_le32 (36);
|
||||
header->DataLength = cpu_to_le32(skb->len - sizeof *header);
|
||||
}
|
||||
|
||||
@@ -1029,7 +1026,7 @@ int rndis_rm_hdr(struct sk_buff *skb)
|
||||
__le32 *tmp = (void *) skb->data;
|
||||
|
||||
/* MessageType, MessageLength */
|
||||
if (__constant_cpu_to_le32(REMOTE_NDIS_PACKET_MSG)
|
||||
if (cpu_to_le32(REMOTE_NDIS_PACKET_MSG)
|
||||
!= get_unaligned(tmp++))
|
||||
return -EINVAL;
|
||||
tmp++;
|
||||
|
@@ -87,12 +87,12 @@ static struct usb_gadget_strings *dev_strings[] = {
|
||||
static struct usb_device_descriptor device_desc = {
|
||||
.bLength = USB_DT_DEVICE_SIZE,
|
||||
.bDescriptorType = USB_DT_DEVICE,
|
||||
.bcdUSB = __constant_cpu_to_le16(0x0200),
|
||||
.bcdUSB = cpu_to_le16(0x0200),
|
||||
/* .bDeviceClass = f(use_acm) */
|
||||
.bDeviceSubClass = 0,
|
||||
.bDeviceProtocol = 0,
|
||||
/* .bMaxPacketSize0 = f(hardware) */
|
||||
.idVendor = __constant_cpu_to_le16(GS_VENDOR_ID),
|
||||
.idVendor = cpu_to_le16(GS_VENDOR_ID),
|
||||
/* .idProduct = f(use_acm) */
|
||||
/* .bcdDevice = f(hardware) */
|
||||
/* .iManufacturer = DYNAMIC */
|
||||
@@ -216,7 +216,7 @@ static int __init gs_bind(struct usb_composite_dev *cdev)
|
||||
pr_warning("gs_bind: controller '%s' not recognized\n",
|
||||
gadget->name);
|
||||
device_desc.bcdDevice =
|
||||
__constant_cpu_to_le16(GS_VERSION_NUM | 0x0099);
|
||||
cpu_to_le16(GS_VERSION_NUM | 0x0099);
|
||||
}
|
||||
|
||||
if (gadget_is_otg(cdev->gadget)) {
|
||||
@@ -255,19 +255,19 @@ static int __init init(void)
|
||||
serial_config_driver.bConfigurationValue = 2;
|
||||
device_desc.bDeviceClass = USB_CLASS_COMM;
|
||||
device_desc.idProduct =
|
||||
__constant_cpu_to_le16(GS_CDC_PRODUCT_ID);
|
||||
cpu_to_le16(GS_CDC_PRODUCT_ID);
|
||||
} else if (use_obex) {
|
||||
serial_config_driver.label = "CDC OBEX config";
|
||||
serial_config_driver.bConfigurationValue = 3;
|
||||
device_desc.bDeviceClass = USB_CLASS_COMM;
|
||||
device_desc.idProduct =
|
||||
__constant_cpu_to_le16(GS_CDC_OBEX_PRODUCT_ID);
|
||||
cpu_to_le16(GS_CDC_OBEX_PRODUCT_ID);
|
||||
} else {
|
||||
serial_config_driver.label = "Generic Serial config";
|
||||
serial_config_driver.bConfigurationValue = 1;
|
||||
device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC;
|
||||
device_desc.idProduct =
|
||||
__constant_cpu_to_le16(GS_PRODUCT_ID);
|
||||
cpu_to_le16(GS_PRODUCT_ID);
|
||||
}
|
||||
strings_dev[STRING_DESCRIPTION_IDX].s = serial_config_driver.label;
|
||||
|
||||
|
@@ -1092,7 +1092,7 @@ int __init gserial_setup(struct usb_gadget *g, unsigned count)
|
||||
gs_tty_driver->init_termios.c_ispeed = 9600;
|
||||
gs_tty_driver->init_termios.c_ospeed = 9600;
|
||||
|
||||
coding.dwDTERate = __constant_cpu_to_le32(9600);
|
||||
coding.dwDTERate = cpu_to_le32(9600);
|
||||
coding.bCharFormat = 8;
|
||||
coding.bParityType = USB_CDC_NO_PARITY;
|
||||
coding.bDataBits = USB_CDC_1_STOP_BITS;
|
||||
|
@@ -102,22 +102,32 @@ module_param(loopdefault, bool, S_IRUGO|S_IWUSR);
|
||||
#ifndef CONFIG_USB_ZERO_HNPTEST
|
||||
#define DRIVER_VENDOR_NUM 0x0525 /* NetChip */
|
||||
#define DRIVER_PRODUCT_NUM 0xa4a0 /* Linux-USB "Gadget Zero" */
|
||||
#define DEFAULT_AUTORESUME 0
|
||||
#else
|
||||
#define DRIVER_VENDOR_NUM 0x1a0a /* OTG test device IDs */
|
||||
#define DRIVER_PRODUCT_NUM 0xbadd
|
||||
#define DEFAULT_AUTORESUME 5
|
||||
#endif
|
||||
|
||||
/* If the optional "autoresume" mode is enabled, it provides good
|
||||
* functional coverage for the "USBCV" test harness from USB-IF.
|
||||
* It's always set if OTG mode is enabled.
|
||||
*/
|
||||
unsigned autoresume = DEFAULT_AUTORESUME;
|
||||
module_param(autoresume, uint, S_IRUGO);
|
||||
MODULE_PARM_DESC(autoresume, "zero, or seconds before remote wakeup");
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static struct usb_device_descriptor device_desc = {
|
||||
.bLength = sizeof device_desc,
|
||||
.bDescriptorType = USB_DT_DEVICE,
|
||||
|
||||
.bcdUSB = __constant_cpu_to_le16(0x0200),
|
||||
.bcdUSB = cpu_to_le16(0x0200),
|
||||
.bDeviceClass = USB_CLASS_VENDOR_SPEC,
|
||||
|
||||
.idVendor = __constant_cpu_to_le16(DRIVER_VENDOR_NUM),
|
||||
.idProduct = __constant_cpu_to_le16(DRIVER_PRODUCT_NUM),
|
||||
.idVendor = cpu_to_le16(DRIVER_VENDOR_NUM),
|
||||
.idProduct = cpu_to_le16(DRIVER_PRODUCT_NUM),
|
||||
.bNumConfigurations = 2,
|
||||
};
|
||||
|
||||
@@ -212,6 +222,47 @@ void disable_endpoints(struct usb_composite_dev *cdev,
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static struct timer_list autoresume_timer;
|
||||
|
||||
static void zero_autoresume(unsigned long _c)
|
||||
{
|
||||
struct usb_composite_dev *cdev = (void *)_c;
|
||||
struct usb_gadget *g = cdev->gadget;
|
||||
|
||||
/* unconfigured devices can't issue wakeups */
|
||||
if (!cdev->config)
|
||||
return;
|
||||
|
||||
/* Normally the host would be woken up for something
|
||||
* more significant than just a timer firing; likely
|
||||
* because of some direct user request.
|
||||
*/
|
||||
if (g->speed != USB_SPEED_UNKNOWN) {
|
||||
int status = usb_gadget_wakeup(g);
|
||||
INFO(cdev, "%s --> %d\n", __func__, status);
|
||||
}
|
||||
}
|
||||
|
||||
static void zero_suspend(struct usb_composite_dev *cdev)
|
||||
{
|
||||
if (cdev->gadget->speed == USB_SPEED_UNKNOWN)
|
||||
return;
|
||||
|
||||
if (autoresume) {
|
||||
mod_timer(&autoresume_timer, jiffies + (HZ * autoresume));
|
||||
DBG(cdev, "suspend, wakeup in %d seconds\n", autoresume);
|
||||
} else
|
||||
DBG(cdev, "%s\n", __func__);
|
||||
}
|
||||
|
||||
static void zero_resume(struct usb_composite_dev *cdev)
|
||||
{
|
||||
DBG(cdev, "%s\n", __func__);
|
||||
del_timer(&autoresume_timer);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static int __init zero_bind(struct usb_composite_dev *cdev)
|
||||
{
|
||||
int gcnum;
|
||||
@@ -239,17 +290,19 @@ static int __init zero_bind(struct usb_composite_dev *cdev)
|
||||
strings_dev[STRING_SERIAL_IDX].id = id;
|
||||
device_desc.iSerialNumber = id;
|
||||
|
||||
setup_timer(&autoresume_timer, zero_autoresume, (unsigned long) cdev);
|
||||
|
||||
/* Register primary, then secondary configuration. Note that
|
||||
* SH3 only allows one config...
|
||||
*/
|
||||
if (loopdefault) {
|
||||
loopback_add(cdev);
|
||||
loopback_add(cdev, autoresume != 0);
|
||||
if (!gadget_is_sh(gadget))
|
||||
sourcesink_add(cdev);
|
||||
sourcesink_add(cdev, autoresume != 0);
|
||||
} else {
|
||||
sourcesink_add(cdev);
|
||||
sourcesink_add(cdev, autoresume != 0);
|
||||
if (!gadget_is_sh(gadget))
|
||||
loopback_add(cdev);
|
||||
loopback_add(cdev, autoresume != 0);
|
||||
}
|
||||
|
||||
gcnum = usb_gadget_controller_number(gadget);
|
||||
@@ -265,7 +318,7 @@ static int __init zero_bind(struct usb_composite_dev *cdev)
|
||||
*/
|
||||
pr_warning("%s: controller '%s' not recognized\n",
|
||||
longname, gadget->name);
|
||||
device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);
|
||||
device_desc.bcdDevice = cpu_to_le16(0x9999);
|
||||
}
|
||||
|
||||
|
||||
@@ -278,11 +331,20 @@ static int __init zero_bind(struct usb_composite_dev *cdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int zero_unbind(struct usb_composite_dev *cdev)
|
||||
{
|
||||
del_timer_sync(&autoresume_timer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct usb_composite_driver zero_driver = {
|
||||
.name = "zero",
|
||||
.dev = &device_desc,
|
||||
.strings = dev_strings,
|
||||
.bind = zero_bind,
|
||||
.unbind = zero_unbind,
|
||||
.suspend = zero_suspend,
|
||||
.resume = zero_resume,
|
||||
};
|
||||
|
||||
MODULE_AUTHOR("David Brownell");
|
||||
|
新增問題並參考
封鎖使用者