*
*/
-#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/timer.h>
-#include <linux/list.h>
-#include <linux/interrupt.h>
#include <linux/utsname.h>
-#include <linux/wait.h>
-#include <linux/proc_fs.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
-#include <linux/mutex.h>
-
-#include <asm/byteorder.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/system.h>
-#include <asm/unaligned.h>
-#include <asm/uaccess.h>
#include <linux/usb/ch9.h>
#include <linux/usb/cdc.h>
-#include <linux/usb_gadget.h>
+#include <linux/usb/gadget.h>
#include "gadget_chips.h"
#define GS_DEFAULT_PARITY USB_CDC_NO_PARITY
#define GS_DEFAULT_CHAR_FORMAT USB_CDC_1_STOP_BITS
-/* select highspeed/fullspeed, hiding highspeed if not configured */
-#ifdef CONFIG_USB_GADGET_DUALSPEED
-#define GS_SPEED_SELECT(is_hs,hs,fs) ((is_hs) ? (hs) : (fs))
-#else
-#define GS_SPEED_SELECT(is_hs,hs,fs) (fs)
-#endif /* CONFIG_USB_GADGET_DUALSPEED */
+/* maxpacket and other transfer characteristics vary by speed. */
+static inline struct usb_endpoint_descriptor *
+choose_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *hs,
+ struct usb_endpoint_descriptor *fs)
+{
+ if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
+ return hs;
+ return fs;
+}
+
/* debug settings */
-#ifdef GS_DEBUG
+#ifdef DEBUG
static int debug = 1;
-
-#define gs_debug(format, arg...) \
- do { if (debug) printk(KERN_DEBUG format, ## arg); } while(0)
-#define gs_debug_level(level, format, arg...) \
- do { if (debug>=level) printk(KERN_DEBUG format, ## arg); } while(0)
-
#else
+#define debug 0
+#endif
#define gs_debug(format, arg...) \
- do { } while(0)
+ do { if (debug) pr_debug(format, ## arg); } while (0)
#define gs_debug_level(level, format, arg...) \
- do { } while(0)
+ do { if (debug >= level) pr_debug(format, ## arg); } while (0)
-#endif /* GS_DEBUG */
/* Thanks to NetChip Technologies for donating this product ID.
*
/* the port structure holds info for each port, one for each minor number */
struct gs_port {
- struct gs_dev *port_dev; /* pointer to device struct */
+ struct gs_dev *port_dev; /* pointer to device struct */
struct tty_struct *port_tty; /* pointer to tty struct */
spinlock_t port_lock;
- int port_num;
+ int port_num;
int port_open_count;
int port_in_use; /* open/close in progress */
wait_queue_head_t port_write_wait;/* waiting to write */
/* tty driver */
static int gs_open(struct tty_struct *tty, struct file *file);
static void gs_close(struct tty_struct *tty, struct file *file);
-static int gs_write(struct tty_struct *tty,
+static int gs_write(struct tty_struct *tty,
const unsigned char *buf, int count);
static void gs_put_char(struct tty_struct *tty, unsigned char ch);
static void gs_flush_chars(struct tty_struct *tty);
static void gs_disconnect(struct usb_gadget *gadget);
static int gs_set_config(struct gs_dev *dev, unsigned config);
static void gs_reset_config(struct gs_dev *dev);
-static int gs_build_config_buf(u8 *buf, enum usb_device_speed speed,
+static int gs_build_config_buf(u8 *buf, struct usb_gadget *g,
u8 type, unsigned int index, int is_otg);
static struct usb_request *gs_alloc_req(struct usb_ep *ep, unsigned int len,
};
static const struct usb_cdc_call_mgmt_descriptor gs_call_mgmt_descriptor = {
- .bLength = sizeof(gs_call_mgmt_descriptor),
- .bDescriptorType = USB_DT_CS_INTERFACE,
- .bDescriptorSubType = USB_CDC_CALL_MANAGEMENT_TYPE,
- .bmCapabilities = 0,
- .bDataInterface = 1, /* index of data interface */
+ .bLength = sizeof(gs_call_mgmt_descriptor),
+ .bDescriptorType = USB_DT_CS_INTERFACE,
+ .bDescriptorSubType = USB_CDC_CALL_MANAGEMENT_TYPE,
+ .bmCapabilities = 0,
+ .bDataInterface = 1, /* index of data interface */
};
static struct usb_cdc_acm_descriptor gs_acm_descriptor = {
- .bLength = sizeof(gs_acm_descriptor),
- .bDescriptorType = USB_DT_CS_INTERFACE,
- .bDescriptorSubType = USB_CDC_ACM_TYPE,
- .bmCapabilities = 0,
+ .bLength = sizeof(gs_acm_descriptor),
+ .bDescriptorType = USB_DT_CS_INTERFACE,
+ .bDescriptorSubType = USB_CDC_ACM_TYPE,
+ .bmCapabilities = 0,
};
static const struct usb_cdc_union_desc gs_union_desc = {
.bMasterInterface0 = 0, /* index of control interface */
.bSlaveInterface0 = 1, /* index of data interface */
};
-
+
static struct usb_endpoint_descriptor gs_fullspeed_notify_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
NULL,
};
-#ifdef CONFIG_USB_GADGET_DUALSPEED
static struct usb_endpoint_descriptor gs_highspeed_notify_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
NULL,
};
-#endif /* CONFIG_USB_GADGET_DUALSPEED */
-
/* Module */
MODULE_DESCRIPTION(GS_LONG_NAME);
MODULE_AUTHOR("Al Borchers");
MODULE_LICENSE("GPL");
-#ifdef GS_DEBUG
+#ifdef DEBUG
module_param(debug, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(debug, "Enable debugging, 0=off, 1=on");
#endif
retval = usb_gadget_register_driver(&gs_gadget_driver);
if (retval) {
- printk(KERN_ERR "gs_module_init: cannot register gadget driver, ret=%d\n", retval);
+ pr_err("gs_module_init: cannot register gadget driver, "
+ "ret=%d\n", retval);
return retval;
}
if (retval) {
usb_gadget_unregister_driver(&gs_gadget_driver);
put_tty_driver(gs_tty_driver);
- printk(KERN_ERR "gs_module_init: cannot register tty driver, ret=%d\n", retval);
+ pr_err("gs_module_init: cannot register tty driver, "
+ "ret=%d\n", retval);
return retval;
}
- printk(KERN_INFO "gs_module_init: %s %s loaded\n", GS_LONG_NAME, GS_VERSION_STR);
+ pr_info("gs_module_init: %s %s loaded\n",
+ GS_LONG_NAME, GS_VERSION_STR);
return 0;
}
put_tty_driver(gs_tty_driver);
usb_gadget_unregister_driver(&gs_gadget_driver);
- printk(KERN_INFO "gs_module_exit: %s %s unloaded\n", GS_LONG_NAME, GS_VERSION_STR);
+ pr_info("gs_module_exit: %s %s unloaded\n",
+ GS_LONG_NAME, GS_VERSION_STR);
}
/* TTY Driver */
gs_debug("gs_open: (%d,%p,%p)\n", port_num, tty, file);
if (port_num < 0 || port_num >= GS_NUM_PORTS) {
- printk(KERN_ERR "gs_open: (%d,%p,%p) invalid port number\n",
+ pr_err("gs_open: (%d,%p,%p) invalid port number\n",
port_num, tty, file);
return -ENODEV;
}
dev = gs_device;
if (dev == NULL) {
- printk(KERN_ERR "gs_open: (%d,%p,%p) NULL device pointer\n",
+ pr_err("gs_open: (%d,%p,%p) NULL device pointer\n",
port_num, tty, file);
return -ENODEV;
}
mtx = &gs_open_close_lock[port_num];
if (mutex_lock_interruptible(mtx)) {
- printk(KERN_ERR
- "gs_open: (%d,%p,%p) interrupted waiting for mutex\n",
+ pr_err("gs_open: (%d,%p,%p) interrupted waiting for mutex\n",
port_num, tty, file);
return -ERESTARTSYS;
}
spin_lock_irqsave(&dev->dev_lock, flags);
if (dev->dev_config == GS_NO_CONFIG_ID) {
- printk(KERN_ERR
- "gs_open: (%d,%p,%p) device is not connected\n",
+ pr_err("gs_open: (%d,%p,%p) device is not connected\n",
port_num, tty, file);
ret = -ENODEV;
goto exit_unlock_dev;
port = dev->dev_port[port_num];
if (port == NULL) {
- printk(KERN_ERR "gs_open: (%d,%p,%p) NULL port pointer\n",
+ pr_err("gs_open: (%d,%p,%p) NULL port pointer\n",
port_num, tty, file);
ret = -ENODEV;
goto exit_unlock_dev;
spin_unlock(&dev->dev_lock);
if (port->port_dev == NULL) {
- printk(KERN_ERR "gs_open: (%d,%p,%p) port disconnected (1)\n",
+ pr_err("gs_open: (%d,%p,%p) port disconnected (1)\n",
port_num, tty, file);
ret = -EIO;
goto exit_unlock_port;
/* might have been disconnected while asleep, check */
if (port->port_dev == NULL) {
- printk(KERN_ERR
- "gs_open: (%d,%p,%p) port disconnected (2)\n",
+ pr_err("gs_open: (%d,%p,%p) port disconnected (2)\n",
port_num, tty, file);
port->port_in_use = 0;
ret = -EIO;
}
if ((port->port_write_buf=buf) == NULL) {
- printk(KERN_ERR "gs_open: (%d,%p,%p) cannot allocate port write buffer\n",
+ pr_err("gs_open: (%d,%p,%p) cannot allocate "
+ "port write buffer\n",
port_num, tty, file);
port->port_in_use = 0;
ret = -ENOMEM;
/* might have been disconnected while asleep, check */
if (port->port_dev == NULL) {
- printk(KERN_ERR "gs_open: (%d,%p,%p) port disconnected (3)\n",
+ pr_err("gs_open: (%d,%p,%p) port disconnected (3)\n",
port_num, tty, file);
port->port_in_use = 0;
ret = -EIO;
struct mutex *mtx;
if (port == NULL) {
- printk(KERN_ERR "gs_close: NULL port pointer\n");
+ pr_err("gs_close: NULL port pointer\n");
return;
}
spin_lock_irq(&port->port_lock);
if (port->port_open_count == 0) {
- printk(KERN_ERR
- "gs_close: (%d,%p,%p) port is already closed\n",
+ pr_err("gs_close: (%d,%p,%p) port is already closed\n",
port->port_num, tty, file);
goto exit;
}
int ret;
if (port == NULL) {
- printk(KERN_ERR "gs_write: NULL port pointer\n");
+ pr_err("gs_write: NULL port pointer\n");
return -EIO;
}
spin_lock_irqsave(&port->port_lock, flags);
if (port->port_dev == NULL) {
- printk(KERN_ERR "gs_write: (%d,%p) port is not connected\n",
+ pr_err("gs_write: (%d,%p) port is not connected\n",
port->port_num, tty);
ret = -EIO;
goto exit;
}
if (port->port_open_count == 0) {
- printk(KERN_ERR "gs_write: (%d,%p) port is closed\n",
+ pr_err("gs_write: (%d,%p) port is closed\n",
port->port_num, tty);
ret = -EBADF;
goto exit;
struct gs_port *port = tty->driver_data;
if (port == NULL) {
- printk(KERN_ERR "gs_put_char: NULL port pointer\n");
+ pr_err("gs_put_char: NULL port pointer\n");
return;
}
- gs_debug("gs_put_char: (%d,%p) char=0x%x, called from %p, %p, %p\n", port->port_num, tty, ch, __builtin_return_address(0), __builtin_return_address(1), __builtin_return_address(2));
+ gs_debug("gs_put_char: (%d,%p) char=0x%x, called from %p\n",
+ port->port_num, tty, ch, __builtin_return_address(0));
spin_lock_irqsave(&port->port_lock, flags);
if (port->port_dev == NULL) {
- printk(KERN_ERR "gs_put_char: (%d,%p) port is not connected\n",
+ pr_err("gs_put_char: (%d,%p) port is not connected\n",
port->port_num, tty);
goto exit;
}
if (port->port_open_count == 0) {
- printk(KERN_ERR "gs_put_char: (%d,%p) port is closed\n",
+ pr_err("gs_put_char: (%d,%p) port is closed\n",
port->port_num, tty);
goto exit;
}
struct gs_port *port = tty->driver_data;
if (port == NULL) {
- printk(KERN_ERR "gs_flush_chars: NULL port pointer\n");
+ pr_err("gs_flush_chars: NULL port pointer\n");
return;
}
spin_lock_irqsave(&port->port_lock, flags);
if (port->port_dev == NULL) {
- printk(KERN_ERR
- "gs_flush_chars: (%d,%p) port is not connected\n",
+ pr_err("gs_flush_chars: (%d,%p) port is not connected\n",
port->port_num, tty);
goto exit;
}
if (port->port_open_count == 0) {
- printk(KERN_ERR "gs_flush_chars: (%d,%p) port is closed\n",
+ pr_err("gs_flush_chars: (%d,%p) port is closed\n",
port->port_num, tty);
goto exit;
}
struct gs_port *port = tty->driver_data;
if (port == NULL) {
- printk(KERN_ERR "gs_ioctl: NULL port pointer\n");
+ pr_err("gs_ioctl: NULL port pointer\n");
return -EIO;
}
struct gs_req_entry *req_entry;
if (dev == NULL) {
- printk(KERN_ERR "gs_send: NULL device pointer\n");
+ pr_err("gs_send: NULL device pointer\n");
return -ENODEV;
}
len = gs_send_packet(dev, req->buf, ep->maxpacket);
if (len > 0) {
-gs_debug_level(3, "gs_send: len=%d, 0x%2.2x 0x%2.2x 0x%2.2x ...\n", len, *((unsigned char *)req->buf), *((unsigned char *)req->buf+1), *((unsigned char *)req->buf+2));
+ gs_debug_level(3, "gs_send: len=%d, 0x%2.2x "
+ "0x%2.2x 0x%2.2x ...\n", len,
+ *((unsigned char *)req->buf),
+ *((unsigned char *)req->buf+1),
+ *((unsigned char *)req->buf+2));
list_del(&req_entry->re_entry);
req->length = len;
spin_unlock_irqrestore(&dev->dev_lock, flags);
if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) {
- printk(KERN_ERR
+ pr_err(
"gs_send: cannot queue read request, ret=%d\n",
ret);
spin_lock_irqsave(&dev->dev_lock, flags);
port = dev->dev_port[0];
if (port == NULL) {
- printk(KERN_ERR
- "gs_send_packet: port=%d, NULL port pointer\n",
- 0);
+ pr_err("gs_send_packet: port=%d, NULL port pointer\n", 0);
return -EIO;
}
port = dev->dev_port[0];
if (port == NULL) {
- printk(KERN_ERR "gs_recv_packet: port=%d, NULL port pointer\n",
+ pr_err("gs_recv_packet: port=%d, NULL port pointer\n",
port->port_num);
return -EIO;
}
spin_lock(&port->port_lock);
if (port->port_open_count == 0) {
- printk(KERN_ERR "gs_recv_packet: port=%d, port is closed\n",
+ pr_err("gs_recv_packet: port=%d, port is closed\n",
port->port_num);
ret = -EIO;
goto exit;
tty = port->port_tty;
if (tty == NULL) {
- printk(KERN_ERR "gs_recv_packet: port=%d, NULL tty pointer\n",
+ pr_err("gs_recv_packet: port=%d, NULL tty pointer\n",
port->port_num);
ret = -EIO;
goto exit;
}
if (port->port_tty->magic != TTY_MAGIC) {
- printk(KERN_ERR "gs_recv_packet: port=%d, bad tty magic\n",
+ pr_err("gs_recv_packet: port=%d, bad tty magic\n",
port->port_num);
ret = -EIO;
goto exit;
struct gs_dev *dev = ep->driver_data;
if (dev == NULL) {
- printk(KERN_ERR "gs_read_complete: NULL device pointer\n");
+ pr_err("gs_read_complete: NULL device pointer\n");
return;
}
switch(req->status) {
case 0:
- /* normal completion */
+ /* normal completion */
gs_recv_packet(dev, req->buf, req->actual);
requeue:
req->length = ep->maxpacket;
if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) {
- printk(KERN_ERR
+ pr_err(
"gs_read_complete: cannot queue read request, ret=%d\n",
ret);
}
default:
/* unexpected */
- printk(KERN_ERR
+ pr_err(
"gs_read_complete: unexpected status error, status=%d\n",
req->status);
goto requeue;
struct gs_req_entry *gs_req = req->context;
if (dev == NULL) {
- printk(KERN_ERR "gs_write_complete: NULL device pointer\n");
+ pr_err("gs_write_complete: NULL device pointer\n");
return;
}
/* normal completion */
requeue:
if (gs_req == NULL) {
- printk(KERN_ERR
- "gs_write_complete: NULL request pointer\n");
+ pr_err("gs_write_complete: NULL request pointer\n");
return;
}
break;
default:
- printk(KERN_ERR
+ pr_err(
"gs_write_complete: unexpected status error, status=%d\n",
req->status);
goto requeue;
gs_device_desc.bcdDevice =
cpu_to_le16(GS_VERSION_NUM | gcnum);
else {
- printk(KERN_WARNING "gs_bind: controller '%s' not recognized\n",
+ pr_warning("gs_bind: controller '%s' not recognized\n",
gadget->name);
/* unrecognized, but safe unless bulk is REALLY quirky */
gs_device_desc.bcdDevice =
if (use_acm) {
ep = usb_ep_autoconfig(gadget, &gs_fullspeed_notify_desc);
if (!ep) {
- printk(KERN_ERR "gs_bind: cannot run ACM on %s\n", gadget->name);
+ pr_err("gs_bind: cannot run ACM on %s\n", gadget->name);
goto autoconf_fail;
}
gs_device_desc.idProduct = __constant_cpu_to_le16(
? USB_CLASS_COMM : USB_CLASS_VENDOR_SPEC;
gs_device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
-#ifdef CONFIG_USB_GADGET_DUALSPEED
- gs_qualifier_desc.bDeviceClass = use_acm
- ? USB_CLASS_COMM : USB_CLASS_VENDOR_SPEC;
- /* assume ep0 uses the same packet size for both speeds */
- gs_qualifier_desc.bMaxPacketSize0 = gs_device_desc.bMaxPacketSize0;
- /* assume endpoints are dual-speed */
- gs_highspeed_notify_desc.bEndpointAddress =
- gs_fullspeed_notify_desc.bEndpointAddress;
- gs_highspeed_in_desc.bEndpointAddress =
- gs_fullspeed_in_desc.bEndpointAddress;
- gs_highspeed_out_desc.bEndpointAddress =
- gs_fullspeed_out_desc.bEndpointAddress;
-#endif /* CONFIG_USB_GADGET_DUALSPEED */
+ if (gadget_is_dualspeed(gadget)) {
+ gs_qualifier_desc.bDeviceClass = use_acm
+ ? USB_CLASS_COMM : USB_CLASS_VENDOR_SPEC;
+ /* assume ep0 uses the same packet size for both speeds */
+ gs_qualifier_desc.bMaxPacketSize0 =
+ gs_device_desc.bMaxPacketSize0;
+ /* assume endpoints are dual-speed */
+ gs_highspeed_notify_desc.bEndpointAddress =
+ gs_fullspeed_notify_desc.bEndpointAddress;
+ gs_highspeed_in_desc.bEndpointAddress =
+ gs_fullspeed_in_desc.bEndpointAddress;
+ gs_highspeed_out_desc.bEndpointAddress =
+ gs_fullspeed_out_desc.bEndpointAddress;
+ }
usb_gadget_set_selfpowered(gadget);
- if (gadget->is_otg) {
+ if (gadget_is_otg(gadget)) {
gs_otg_descriptor.bmAttributes |= USB_OTG_HNP,
gs_bulk_config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
gs_acm_config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
set_gadget_data(gadget, dev);
if ((ret=gs_alloc_ports(dev, GFP_KERNEL)) != 0) {
- printk(KERN_ERR "gs_bind: cannot allocate ports\n");
+ pr_err("gs_bind: cannot allocate ports\n");
gs_unbind(gadget);
return ret;
}
gadget->ep0->driver_data = dev;
- printk(KERN_INFO "gs_bind: %s %s bound\n",
+ pr_info("gs_bind: %s %s bound\n",
GS_LONG_NAME, GS_VERSION_STR);
return 0;
autoconf_fail:
- printk(KERN_ERR "gs_bind: cannot autoconfigure on %s\n", gadget->name);
+ pr_err("gs_bind: cannot autoconfigure on %s\n", gadget->name);
return -ENODEV;
}
dev->dev_ctrl_req = NULL;
}
gs_free_ports(dev);
+ if (dev->dev_notify_ep)
+ usb_ep_disable(dev->dev_notify_ep);
+ if (dev->dev_in_ep)
+ usb_ep_disable(dev->dev_in_ep);
+ if (dev->dev_out_ep)
+ usb_ep_disable(dev->dev_out_ep);
kfree(dev);
set_gadget_data(gadget, NULL);
}
- printk(KERN_INFO "gs_unbind: %s %s unbound\n", GS_LONG_NAME,
+ pr_info("gs_unbind: %s %s unbound\n", GS_LONG_NAME,
GS_VERSION_STR);
}
break;
default:
- printk(KERN_ERR "gs_setup: unknown request, type=%02x, request=%02x, value=%04x, index=%04x, length=%d\n",
+ pr_err("gs_setup: unknown request, type=%02x, request=%02x, "
+ "value=%04x, index=%04x, length=%d\n",
ctrl->bRequestType, ctrl->bRequest,
wValue, wIndex, wLength);
break;
&& (ret % gadget->ep0->maxpacket) == 0;
ret = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC);
if (ret < 0) {
- printk(KERN_ERR "gs_setup: cannot queue response, ret=%d\n",
+ pr_err("gs_setup: cannot queue response, ret=%d\n",
ret);
req->status = 0;
gs_setup_complete(gadget->ep0, req);
memcpy(req->buf, &gs_device_desc, ret);
break;
-#ifdef CONFIG_USB_GADGET_DUALSPEED
case USB_DT_DEVICE_QUALIFIER:
- if (!gadget->is_dualspeed)
+ if (!gadget_is_dualspeed(gadget))
break;
ret = min(wLength,
(u16)sizeof(struct usb_qualifier_descriptor));
break;
case USB_DT_OTHER_SPEED_CONFIG:
- if (!gadget->is_dualspeed)
+ if (!gadget_is_dualspeed(gadget))
break;
/* fall through */
-#endif /* CONFIG_USB_GADGET_DUALSPEED */
case USB_DT_CONFIG:
- ret = gs_build_config_buf(req->buf, gadget->speed,
+ ret = gs_build_config_buf(req->buf, gadget,
wValue >> 8, wValue & 0xff,
- gadget->is_otg);
+ gadget_is_otg(gadget));
if (ret >= 0)
ret = min(wLength, (u16)ret);
break;
break;
default:
- printk(KERN_ERR "gs_setup: unknown standard request, type=%02x, request=%02x, value=%04x, index=%04x, length=%d\n",
+ pr_err("gs_setup: unknown standard request, type=%02x, "
+ "request=%02x, value=%04x, index=%04x, length=%d\n",
ctrl->bRequestType, ctrl->bRequest,
wValue, wIndex, wLength);
break;
switch (ctrl->bRequest) {
case USB_CDC_REQ_SET_LINE_CODING:
- ret = min(wLength,
- (u16)sizeof(struct usb_cdc_line_coding));
- if (port) {
- spin_lock(&port->port_lock);
- memcpy(&port->port_line_coding, req->buf, ret);
- spin_unlock(&port->port_lock);
- }
- ret = 0;
+ /* FIXME Submit req to read the data; have its completion
+ * handler copy that data to port->port_line_coding (iff
+ * it's valid) and maybe pass it on. Until then, fail.
+ */
+ pr_warning("gs_setup: set_line_coding "
+ "unuspported\n");
break;
case USB_CDC_REQ_GET_LINE_CODING:
break;
case USB_CDC_REQ_SET_CONTROL_LINE_STATE:
- ret = 0;
+ /* FIXME Submit req to read the data; have its completion
+ * handler use that to set the state (iff it's valid) and
+ * maybe pass it on. Until then, fail.
+ */
+ pr_warning("gs_setup: set_control_line_state "
+ "unuspported\n");
break;
default:
- printk(KERN_ERR "gs_setup: unknown class request, type=%02x, request=%02x, value=%04x, index=%04x, length=%d\n",
+ pr_err("gs_setup: unknown class request, "
+ "type=%02x, request=%02x, value=%04x, "
+ "index=%04x, length=%d\n",
ctrl->bRequestType, ctrl->bRequest,
wValue, wIndex, wLength);
break;
static void gs_setup_complete(struct usb_ep *ep, struct usb_request *req)
{
if (req->status || req->actual != req->length) {
- printk(KERN_ERR "gs_setup_complete: status error, status=%d, actual=%d, length=%d\n",
+ pr_err("gs_setup_complete: status error, status=%d, "
+ "actual=%d, length=%d\n",
req->status, req->actual, req->length);
}
}
/* re-allocate ports for the next connection */
if (gs_alloc_ports(dev, GFP_ATOMIC) != 0)
- printk(KERN_ERR "gs_disconnect: cannot re-allocate ports\n");
+ pr_err("gs_disconnect: cannot re-allocate ports\n");
spin_unlock_irqrestore(&dev->dev_lock, flags);
- printk(KERN_INFO "gs_disconnect: %s disconnected\n", GS_LONG_NAME);
+ pr_info("gs_disconnect: %s disconnected\n", GS_LONG_NAME);
}
/*
struct gs_req_entry *req_entry;
if (dev == NULL) {
- printk(KERN_ERR "gs_set_config: NULL device pointer\n");
+ pr_err("gs_set_config: NULL device pointer\n");
return 0;
}
if (EP_NOTIFY_NAME
&& strcmp(ep->name, EP_NOTIFY_NAME) == 0) {
- ep_desc = GS_SPEED_SELECT(
- gadget->speed == USB_SPEED_HIGH,
+ ep_desc = choose_ep_desc(gadget,
&gs_highspeed_notify_desc,
&gs_fullspeed_notify_desc);
ret = usb_ep_enable(ep,ep_desc);
dev->dev_notify_ep = ep;
dev->dev_notify_ep_desc = ep_desc;
} else {
- printk(KERN_ERR "gs_set_config: cannot enable notify endpoint %s, ret=%d\n",
+ pr_err("gs_set_config: cannot enable NOTIFY "
+ "endpoint %s, ret=%d\n",
ep->name, ret);
goto exit_reset_config;
}
}
else if (strcmp(ep->name, EP_IN_NAME) == 0) {
- ep_desc = GS_SPEED_SELECT(
- gadget->speed == USB_SPEED_HIGH,
- &gs_highspeed_in_desc,
+ ep_desc = choose_ep_desc(gadget,
+ &gs_highspeed_in_desc,
&gs_fullspeed_in_desc);
ret = usb_ep_enable(ep,ep_desc);
if (ret == 0) {
dev->dev_in_ep = ep;
dev->dev_in_ep_desc = ep_desc;
} else {
- printk(KERN_ERR "gs_set_config: cannot enable in endpoint %s, ret=%d\n",
+ pr_err("gs_set_config: cannot enable IN "
+ "endpoint %s, ret=%d\n",
ep->name, ret);
goto exit_reset_config;
}
}
else if (strcmp(ep->name, EP_OUT_NAME) == 0) {
- ep_desc = GS_SPEED_SELECT(
- gadget->speed == USB_SPEED_HIGH,
+ ep_desc = choose_ep_desc(gadget,
&gs_highspeed_out_desc,
&gs_fullspeed_out_desc);
ret = usb_ep_enable(ep,ep_desc);
dev->dev_out_ep = ep;
dev->dev_out_ep_desc = ep_desc;
} else {
- printk(KERN_ERR "gs_set_config: cannot enable out endpoint %s, ret=%d\n",
+ pr_err("gs_set_config: cannot enable OUT "
+ "endpoint %s, ret=%d\n",
ep->name, ret);
goto exit_reset_config;
}
if (dev->dev_in_ep == NULL || dev->dev_out_ep == NULL
|| (config != GS_BULK_CONFIG_ID && dev->dev_notify_ep == NULL)) {
- printk(KERN_ERR "gs_set_config: cannot find endpoints\n");
+ pr_err("gs_set_config: cannot find endpoints\n");
ret = -ENODEV;
goto exit_reset_config;
}
if ((req=gs_alloc_req(ep, ep->maxpacket, GFP_ATOMIC))) {
req->complete = gs_read_complete;
if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) {
- printk(KERN_ERR "gs_set_config: cannot queue read request, ret=%d\n",
- ret);
+ pr_err("gs_set_config: cannot queue read "
+ "request, ret=%d\n", ret);
}
} else {
- printk(KERN_ERR "gs_set_config: cannot allocate read requests\n");
+ pr_err("gs_set_config: cannot allocate "
+ "read requests\n");
ret = -ENOMEM;
goto exit_reset_config;
}
req_entry->re_req->complete = gs_write_complete;
list_add(&req_entry->re_entry, &dev->dev_req_list);
} else {
- printk(KERN_ERR "gs_set_config: cannot allocate write requests\n");
+ pr_err("gs_set_config: cannot allocate "
+ "write requests\n");
ret = -ENOMEM;
goto exit_reset_config;
}
}
- printk(KERN_INFO "gs_set_config: %s configured, %s speed %s config\n",
+ pr_info("gs_set_config: %s configured, %s speed %s config\n",
GS_LONG_NAME,
gadget->speed == USB_SPEED_HIGH ? "high" : "full",
config == GS_BULK_CONFIG_ID ? "BULK" : "CDC-ACM");
struct gs_req_entry *req_entry;
if (dev == NULL) {
- printk(KERN_ERR "gs_reset_config: NULL device pointer\n");
+ pr_err("gs_reset_config: NULL device pointer\n");
return;
}
* Builds the config descriptors in the given buffer and returns the
* length, or a negative error number.
*/
-static int gs_build_config_buf(u8 *buf, enum usb_device_speed speed,
+static int gs_build_config_buf(u8 *buf, struct usb_gadget *g,
u8 type, unsigned int index, int is_otg)
{
int len;
- int high_speed;
+ int high_speed = 0;
const struct usb_config_descriptor *config_desc;
const struct usb_descriptor_header **function;
return -EINVAL;
/* other speed switches high and full speed */
- high_speed = (speed == USB_SPEED_HIGH);
- if (type == USB_DT_OTHER_SPEED_CONFIG)
- high_speed = !high_speed;
+ if (gadget_is_dualspeed(g)) {
+ high_speed = (g->speed == USB_SPEED_HIGH);
+ if (type == USB_DT_OTHER_SPEED_CONFIG)
+ high_speed = !high_speed;
+ }
if (use_acm) {
config_desc = &gs_acm_config_desc;
- function = GS_SPEED_SELECT(high_speed,
- gs_acm_highspeed_function,
- gs_acm_fullspeed_function);
+ function = high_speed
+ ? gs_acm_highspeed_function
+ : gs_acm_fullspeed_function;
} else {
config_desc = &gs_bulk_config_desc;
- function = GS_SPEED_SELECT(high_speed,
- gs_bulk_highspeed_function,
- gs_bulk_fullspeed_function);
+ function = high_speed
+ ? gs_bulk_highspeed_function
+ : gs_bulk_fullspeed_function;
}
/* for now, don't advertise srp-only devices */