[linux-usb-devel] [PATCH 1/6] USB gadget driver
From: Ragner Magalhaes [EMAIL PROTECTED] Implements support for a gadget function with composite support to work as a single function. Signed-off-by: Ragner Magalhaes [EMAIL PROTECTED] --- drivers/usb/gadget/gadget.c | 283 +++ 1 files changed, 283 insertions(+), 0 deletions(-) diff --git a/drivers/usb/gadget/gadget.c b/drivers/usb/gadget/gadget.c new file mode 100644 index 000..9a4a0e0 --- /dev/null +++ b/drivers/usb/gadget/gadget.c @@ -0,0 +1,283 @@ +/* + * gadget.c -- USB gadget driver. + * + * Copyright (C) 2007 Instituto Nokia de Tecnologia - INdT + * Developed for INdT by Ragner Magalhaes + * Ragner Magalhaes [EMAIL PROTECTED] + * + * This software is distributed under the terms of the GNU General Public + * License (GPL) version 2, as published by the Free Software Foundation. + * + * Implements support for one gadget device with a single function. + */ + +#if 0 +#define DEBUG 1 +#define VERBOSE 1 +#endif + +#include linux/module.h +#include linux/kernel.h +#include linux/delay.h +#include linux/ioport.h +#include linux/sched.h +#include linux/slab.h +#include linux/smp_lock.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/device.h +#include linux/moduleparam.h + +#include asm/byteorder.h +#include asm/system.h +#include asm/unaligned.h + +#include linux/usb/ch9.h +#include linux/usb/cdc.h +#include linux/usb_gadget.h +#include linux/usb/composite.h + +#include gadget_chips.h + +/*-*/ + +#define xprintk(d,level,fmt,args...) \ + dev_printk(level , (d)-gadget-dev , fmt , ## args) + +#ifdef DEBUG +#define DBG(dev,fmt,args...) \ + xprintk(dev , KERN_DEBUG , fmt , ## args) +#else +#define DBG(dev,fmt,args...) \ + do { } while(0) +#endif /* DEBUG */ + +#ifdef VERBOSE +#define VDBG DBG +#else +#define VDBG(dev,fmt,args...) \ + do { } while(0) +#endif /* VERBOSE */ + +#define ERROR(dev,fmt,args...) \ + xprintk(dev , KERN_ERR , fmt , ## args) +#define WARN(dev,fmt,args...) \ + xprintk(dev , KERN_WARNING , fmt , ## args) +#define INFO(dev,fmt,args...) \ + xprintk(dev , KERN_INFO , fmt , ## args) + +/*-*/ + +/* big enough to hold our biggest descriptor */ +#define USB_BUFSIZ 256 + + +struct usb_function*func; + +/*-*/ + +/* An impossibly large value as file_storage */ +#define DELAYED_STATUS (USB_BUFSIZ + 999) + +void usb_func_ep_reset (struct usb_gadget *g, struct usb_function *f) +{ + struct usb_ep *ep; + + list_for_each_entry (ep, g-ep_list, ep_list) { + if (ep-driver_data == f-driver_data) { + usb_ep_disable (ep); + ep-driver_data = NULL; + } + } +} + +static void +free_ep_req(struct usb_ep *ep, struct usb_request *req) +{ + if (req-buf) + kfree (req-buf); + usb_ep_free_request(ep, req); +} + +/*-*/ + +static int +gadget_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) +{ + struct usb_gadget_dev *dev = get_gadget_data(gadget); + struct usb_request *req = dev-req; + int value = -EOPNOTSUPP; + u16 w_index = le16_to_cpu(ctrl-wIndex); + u16 w_value = le16_to_cpu(ctrl-wValue); + u16 w_length = le16_to_cpu(ctrl-wLength); + + req-zero = 0; + req-length = 0; + value = dev-func-setup (gadget, ctrl); + + /* respond with data transfer before status phase? */ + if (value = 0 value != DELAYED_STATUS) { + value = min((u16)value, w_length); + req-length = value; + req-zero = value w_length; + + value = usb_ep_queue(gadget-ep0, req, GFP_ATOMIC); + if (value != 0 value != -ESHUTDOWN) { + WARN(dev, error in submission: %s -- %d\n, + (ctrl-bRequestType USB_DIR_IN ? +ep0-in : ep0-out), value); + req-status = 0; + } + } else { + DBG(dev, setup req%02x.%02x v%04x i%04x l%d -- %d\n, + ctrl-bRequestType, ctrl-bRequest, + w_value, w_index, w_length, value); + /* to eliminate compile warnings */ + w_index = w_value = 0; + } + + /* device either stalls (value 0) or reports success */ + return value; +} + +static void +gadget_disconnect(struct usb_gadget
[linux-usb-devel] [PATCH 1/6] USB gadget driver
Implements support for a gadget function with composite support to work as a single function. Signed-off-by: Ragner Magalhaes [EMAIL PROTECTED] :00 100644 000... e6551d9... A drivers/usb/gadget/gadget.c diff --git a/drivers/usb/gadget/gadget.c b/drivers/usb/gadget/gadget.c new file mode 100644 index 000..e6551d9 --- /dev/null +++ b/drivers/usb/gadget/gadget.c @@ -0,0 +1,293 @@ +/* + * gadget.c -- USB gadget driver. + * + * Copyright (C) 2007 Instituto Nokia de Tecnologia - INdT + * Developed for INdT by Ragner Magalhaes + * Ragner Magalhaes [EMAIL PROTECTED] + * + * This software is distributed under the terms of the GNU General Public + * License (GPL) version 2, as published by the Free Software Foundation. + * + * Implements support for one gadget device with a single function. + */ + +#if 0 +#define DEBUG 1 +#define VERBOSE 1 +#endif + +#include linux/module.h +#include linux/kernel.h +#include linux/delay.h +#include linux/ioport.h +#include linux/sched.h +#include linux/slab.h +#include linux/smp_lock.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/device.h +#include linux/moduleparam.h + +#include asm/byteorder.h +#include asm/system.h +#include asm/unaligned.h + +#include linux/usb/ch9.h +#include linux/usb/cdc.h +#include linux/usb_gadget.h +#include linux/usb/composite.h + +#include gadget_chips.h + +/*-*/ + +#define xprintk(d,level,fmt,args...) \ + dev_printk(level , (d)-gadget-dev , fmt , ## args) + +#ifdef DEBUG +#define DBG(dev,fmt,args...) \ + xprintk(dev , KERN_DEBUG , fmt , ## args) +#else +#define DBG(dev,fmt,args...) \ + do { } while(0) +#endif /* DEBUG */ + +#ifdef VERBOSE +#define VDBG DBG +#else +#define VDBG(dev,fmt,args...) \ + do { } while(0) +#endif /* VERBOSE */ + +#define ERROR(dev,fmt,args...) \ + xprintk(dev , KERN_ERR , fmt , ## args) +#define WARN(dev,fmt,args...) \ + xprintk(dev , KERN_WARNING , fmt , ## args) +#define INFO(dev,fmt,args...) \ + xprintk(dev , KERN_INFO , fmt , ## args) + +/*-*/ + +/* big enough to hold our biggest descriptor */ +#define USB_BUFSIZ 256 + + +struct usb_function*func; + +/*-*/ + +/* An impossibly large value as file_storage */ +#define DELAYED_STATUS (USB_BUFSIZ + 999) + +void usb_func_ep_reset (struct usb_gadget *g, struct usb_function *f) +{ + struct usb_ep *ep; + + list_for_each_entry (ep, g-ep_list, ep_list) { + if (ep-driver_data == f-driver_data) { + usb_ep_disable (ep); + ep-driver_data = NULL; + } + } +} + +static void +free_ep_req(struct usb_ep *ep, struct usb_request *req) +{ + if (req-buf) + kfree (req-buf); + usb_ep_free_request(ep, req); +} + +/*-*/ + +static void +gadget_setup_complete(struct usb_ep *ep, struct usb_request *req) +{ + if (req-status || req-actual != req-length) + DBG((struct usb_gadget_dev *)ep-driver_data, + setup complete -- %d, %u/%u\n, + req-status, req-actual, req-length); +} + +static int +gadget_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) +{ + struct usb_gadget_dev *dev = get_gadget_data(gadget); + struct usb_request *req = dev-req; + int value = -EOPNOTSUPP; + u16 w_index = le16_to_cpu(ctrl-wIndex); + u16 w_value = le16_to_cpu(ctrl-wValue); + u16 w_length = le16_to_cpu(ctrl-wLength); + + req-complete = gadget_setup_complete; + req-zero = 0; + spin_lock(dev-lock); + value = dev-func-setup (gadget, ctrl); + spin_unlock(dev-lock); + + /* respond with data transfer before status phase? */ + if (value = 0 value != DELAYED_STATUS) { + req-length = value; + req-zero = value w_length; + value = usb_ep_queue(gadget-ep0, req, GFP_ATOMIC); + if (value 0) { + DBG(dev, ep_queue -- %d\n, value); + req-status = 0; + gadget_setup_complete(gadget-ep0, req); + } + } else { + DBG(dev, setup req%02x.%02x v%04x i%04x l%d -- %d\n, + ctrl-bRequestType, ctrl-bRequest, + w_value, w_index, w_length, value); + /* to eliminate compile warnings */ + w_index = w_value = 0; + } +
[linux-usb-devel] [PATCH 1/6] USB gadget driver
Implements support for a gadget function with composite support to work as a single function. Signed-off-by: Ragner Magalhaes [EMAIL PROTECTED] :00 100644 000... e6551d9... A drivers/usb/gadget/gadget.c diff --git a/drivers/usb/gadget/gadget.c b/drivers/usb/gadget/gadget.c new file mode 100644 index 000..e6551d9 --- /dev/null +++ b/drivers/usb/gadget/gadget.c @@ -0,0 +1,293 @@ +/* + * gadget.c -- USB gadget driver. + * + * Copyright (C) 2007 Instituto Nokia de Tecnologia - INdT + * Developed for INdT by Ragner Magalhaes + * Ragner Magalhaes [EMAIL PROTECTED] + * + * This software is distributed under the terms of the GNU General Public + * License (GPL) version 2, as published by the Free Software Foundation. + * + * Implements support for one gadget device with a single function. + */ + +#if 0 +#define DEBUG 1 +#define VERBOSE 1 +#endif + +#include linux/module.h +#include linux/kernel.h +#include linux/delay.h +#include linux/ioport.h +#include linux/sched.h +#include linux/slab.h +#include linux/smp_lock.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/device.h +#include linux/moduleparam.h + +#include asm/byteorder.h +#include asm/system.h +#include asm/unaligned.h + +#include linux/usb/ch9.h +#include linux/usb/cdc.h +#include linux/usb_gadget.h +#include linux/usb/composite.h + +#include gadget_chips.h + +/*-*/ + +#define xprintk(d,level,fmt,args...) \ + dev_printk(level , (d)-gadget-dev , fmt , ## args) + +#ifdef DEBUG +#define DBG(dev,fmt,args...) \ + xprintk(dev , KERN_DEBUG , fmt , ## args) +#else +#define DBG(dev,fmt,args...) \ + do { } while(0) +#endif /* DEBUG */ + +#ifdef VERBOSE +#define VDBG DBG +#else +#define VDBG(dev,fmt,args...) \ + do { } while(0) +#endif /* VERBOSE */ + +#define ERROR(dev,fmt,args...) \ + xprintk(dev , KERN_ERR , fmt , ## args) +#define WARN(dev,fmt,args...) \ + xprintk(dev , KERN_WARNING , fmt , ## args) +#define INFO(dev,fmt,args...) \ + xprintk(dev , KERN_INFO , fmt , ## args) + +/*-*/ + +/* big enough to hold our biggest descriptor */ +#define USB_BUFSIZ 256 + + +struct usb_function*func; + +/*-*/ + +/* An impossibly large value as file_storage */ +#define DELAYED_STATUS (USB_BUFSIZ + 999) + +void usb_func_ep_reset (struct usb_gadget *g, struct usb_function *f) +{ + struct usb_ep *ep; + + list_for_each_entry (ep, g-ep_list, ep_list) { + if (ep-driver_data == f-driver_data) { + usb_ep_disable (ep); + ep-driver_data = NULL; + } + } +} + +static void +free_ep_req(struct usb_ep *ep, struct usb_request *req) +{ + if (req-buf) + kfree (req-buf); + usb_ep_free_request(ep, req); +} + +/*-*/ + +static void +gadget_setup_complete(struct usb_ep *ep, struct usb_request *req) +{ + if (req-status || req-actual != req-length) + DBG((struct usb_gadget_dev *)ep-driver_data, + setup complete -- %d, %u/%u\n, + req-status, req-actual, req-length); +} + +static int +gadget_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) +{ + struct usb_gadget_dev *dev = get_gadget_data(gadget); + struct usb_request *req = dev-req; + int value = -EOPNOTSUPP; + u16 w_index = le16_to_cpu(ctrl-wIndex); + u16 w_value = le16_to_cpu(ctrl-wValue); + u16 w_length = le16_to_cpu(ctrl-wLength); + + req-complete = gadget_setup_complete; + req-zero = 0; + spin_lock(dev-lock); + value = dev-func-setup (gadget, ctrl); + spin_unlock(dev-lock); + + /* respond with data transfer before status phase? */ + if (value = 0 value != DELAYED_STATUS) { + req-length = value; + req-zero = value w_length; + value = usb_ep_queue(gadget-ep0, req, GFP_ATOMIC); + if (value 0) { + DBG(dev, ep_queue -- %d\n, value); + req-status = 0; + gadget_setup_complete(gadget-ep0, req); + } + } else { + DBG(dev, setup req%02x.%02x v%04x i%04x l%d -- %d\n, + ctrl-bRequestType, ctrl-bRequest, + w_value, w_index, w_length, value); + /* to eliminate compile warnings */ + w_index = w_value = 0; + } +
[linux-usb-devel] [PATCH 1/6] USB gadget driver
Implements support for a gadget function with composite support to work as a single function. Signed-off-by: Ragner Magalhaes [EMAIL PROTECTED] :00 100644 000... e6551d9... A drivers/usb/gadget/gadget.c diff --git a/drivers/usb/gadget/gadget.c b/drivers/usb/gadget/gadget.c new file mode 100644 index 000..e6551d9 --- /dev/null +++ b/drivers/usb/gadget/gadget.c @@ -0,0 +1,293 @@ +/* + * gadget.c -- USB gadget driver. + * + * Copyright (C) 2007 Instituto Nokia de Tecnologia - INdT + * Developed for INdT by Ragner Magalhaes + * Ragner Magalhaes [EMAIL PROTECTED] + * + * This software is distributed under the terms of the GNU General Public + * License (GPL) version 2, as published by the Free Software Foundation. + * + * Implements support for one gadget device with a single function. + */ + +#if 0 +#define DEBUG 1 +#define VERBOSE 1 +#endif + +#include linux/module.h +#include linux/kernel.h +#include linux/delay.h +#include linux/ioport.h +#include linux/sched.h +#include linux/slab.h +#include linux/smp_lock.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/device.h +#include linux/moduleparam.h + +#include asm/byteorder.h +#include asm/system.h +#include asm/unaligned.h + +#include linux/usb/ch9.h +#include linux/usb/cdc.h +#include linux/usb_gadget.h +#include linux/usb/composite.h + +#include gadget_chips.h + +/*-*/ + +#define xprintk(d,level,fmt,args...) \ + dev_printk(level , (d)-gadget-dev , fmt , ## args) + +#ifdef DEBUG +#define DBG(dev,fmt,args...) \ + xprintk(dev , KERN_DEBUG , fmt , ## args) +#else +#define DBG(dev,fmt,args...) \ + do { } while(0) +#endif /* DEBUG */ + +#ifdef VERBOSE +#define VDBG DBG +#else +#define VDBG(dev,fmt,args...) \ + do { } while(0) +#endif /* VERBOSE */ + +#define ERROR(dev,fmt,args...) \ + xprintk(dev , KERN_ERR , fmt , ## args) +#define WARN(dev,fmt,args...) \ + xprintk(dev , KERN_WARNING , fmt , ## args) +#define INFO(dev,fmt,args...) \ + xprintk(dev , KERN_INFO , fmt , ## args) + +/*-*/ + +/* big enough to hold our biggest descriptor */ +#define USB_BUFSIZ 256 + + +struct usb_function*func; + +/*-*/ + +/* An impossibly large value as file_storage */ +#define DELAYED_STATUS (USB_BUFSIZ + 999) + +void usb_func_ep_reset (struct usb_gadget *g, struct usb_function *f) +{ + struct usb_ep *ep; + + list_for_each_entry (ep, g-ep_list, ep_list) { + if (ep-driver_data == f-driver_data) { + usb_ep_disable (ep); + ep-driver_data = NULL; + } + } +} + +static void +free_ep_req(struct usb_ep *ep, struct usb_request *req) +{ + if (req-buf) + kfree (req-buf); + usb_ep_free_request(ep, req); +} + +/*-*/ + +static void +gadget_setup_complete(struct usb_ep *ep, struct usb_request *req) +{ + if (req-status || req-actual != req-length) + DBG((struct usb_gadget_dev *)ep-driver_data, + setup complete -- %d, %u/%u\n, + req-status, req-actual, req-length); +} + +static int +gadget_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) +{ + struct usb_gadget_dev *dev = get_gadget_data(gadget); + struct usb_request *req = dev-req; + int value = -EOPNOTSUPP; + u16 w_index = le16_to_cpu(ctrl-wIndex); + u16 w_value = le16_to_cpu(ctrl-wValue); + u16 w_length = le16_to_cpu(ctrl-wLength); + + req-complete = gadget_setup_complete; + req-zero = 0; + spin_lock(dev-lock); + value = dev-func-setup (gadget, ctrl); + spin_unlock(dev-lock); + + /* respond with data transfer before status phase? */ + if (value = 0 value != DELAYED_STATUS) { + req-length = value; + req-zero = value w_length; + value = usb_ep_queue(gadget-ep0, req, GFP_ATOMIC); + if (value 0) { + DBG(dev, ep_queue -- %d\n, value); + req-status = 0; + gadget_setup_complete(gadget-ep0, req); + } + } else { + DBG(dev, setup req%02x.%02x v%04x i%04x l%d -- %d\n, + ctrl-bRequestType, ctrl-bRequest, + w_value, w_index, w_length, value); + /* to eliminate compile warnings */ + w_index = w_value = 0; + } +
[linux-usb-devel] [PATCH 1/6] USB gadget driver
Implements support for a gadget function with composite support to work as a single function. Signed-off-by: Ragner Magalhaes [EMAIL PROTECTED] :00 100644 000... e6551d9... A drivers/usb/gadget/gadget.c diff --git a/drivers/usb/gadget/gadget.c b/drivers/usb/gadget/gadget.c new file mode 100644 index 000..e6551d9 --- /dev/null +++ b/drivers/usb/gadget/gadget.c @@ -0,0 +1,293 @@ +/* + * gadget.c -- USB gadget driver. + * + * Copyright (C) 2007 Instituto Nokia de Tecnologia - INdT + * Developed for INdT by Ragner Magalhaes + * Ragner Magalhaes [EMAIL PROTECTED] + * + * This software is distributed under the terms of the GNU General Public + * License (GPL) version 2, as published by the Free Software Foundation. + * + * Implements support for one gadget device with a single function. + */ + +#if 0 +#define DEBUG 1 +#define VERBOSE 1 +#endif + +#include linux/module.h +#include linux/kernel.h +#include linux/delay.h +#include linux/ioport.h +#include linux/sched.h +#include linux/slab.h +#include linux/smp_lock.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/device.h +#include linux/moduleparam.h + +#include asm/byteorder.h +#include asm/system.h +#include asm/unaligned.h + +#include linux/usb/ch9.h +#include linux/usb/cdc.h +#include linux/usb_gadget.h +#include linux/usb/composite.h + +#include gadget_chips.h + +/*-*/ + +#define xprintk(d,level,fmt,args...) \ + dev_printk(level , (d)-gadget-dev , fmt , ## args) + +#ifdef DEBUG +#define DBG(dev,fmt,args...) \ + xprintk(dev , KERN_DEBUG , fmt , ## args) +#else +#define DBG(dev,fmt,args...) \ + do { } while(0) +#endif /* DEBUG */ + +#ifdef VERBOSE +#define VDBG DBG +#else +#define VDBG(dev,fmt,args...) \ + do { } while(0) +#endif /* VERBOSE */ + +#define ERROR(dev,fmt,args...) \ + xprintk(dev , KERN_ERR , fmt , ## args) +#define WARN(dev,fmt,args...) \ + xprintk(dev , KERN_WARNING , fmt , ## args) +#define INFO(dev,fmt,args...) \ + xprintk(dev , KERN_INFO , fmt , ## args) + +/*-*/ + +/* big enough to hold our biggest descriptor */ +#define USB_BUFSIZ 256 + + +struct usb_function*func; + +/*-*/ + +/* An impossibly large value as file_storage */ +#define DELAYED_STATUS (USB_BUFSIZ + 999) + +void usb_func_ep_reset (struct usb_gadget *g, struct usb_function *f) +{ + struct usb_ep *ep; + + list_for_each_entry (ep, g-ep_list, ep_list) { + if (ep-driver_data == f-driver_data) { + usb_ep_disable (ep); + ep-driver_data = NULL; + } + } +} + +static void +free_ep_req(struct usb_ep *ep, struct usb_request *req) +{ + if (req-buf) + kfree (req-buf); + usb_ep_free_request(ep, req); +} + +/*-*/ + +static void +gadget_setup_complete(struct usb_ep *ep, struct usb_request *req) +{ + if (req-status || req-actual != req-length) + DBG((struct usb_gadget_dev *)ep-driver_data, + setup complete -- %d, %u/%u\n, + req-status, req-actual, req-length); +} + +static int +gadget_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) +{ + struct usb_gadget_dev *dev = get_gadget_data(gadget); + struct usb_request *req = dev-req; + int value = -EOPNOTSUPP; + u16 w_index = le16_to_cpu(ctrl-wIndex); + u16 w_value = le16_to_cpu(ctrl-wValue); + u16 w_length = le16_to_cpu(ctrl-wLength); + + req-complete = gadget_setup_complete; + req-zero = 0; + spin_lock(dev-lock); + value = dev-func-setup (gadget, ctrl); + spin_unlock(dev-lock); + + /* respond with data transfer before status phase? */ + if (value = 0 value != DELAYED_STATUS) { + req-length = value; + req-zero = value w_length; + value = usb_ep_queue(gadget-ep0, req, GFP_ATOMIC); + if (value 0) { + DBG(dev, ep_queue -- %d\n, value); + req-status = 0; + gadget_setup_complete(gadget-ep0, req); + } + } else { + DBG(dev, setup req%02x.%02x v%04x i%04x l%d -- %d\n, + ctrl-bRequestType, ctrl-bRequest, + w_value, w_index, w_length, value); + /* to eliminate compile warnings */ + w_index = w_value = 0; + } +
[linux-usb-devel] [PATCH 1/6] USB gadget driver
Implements support for a gadget function with composite support to work as a single function. Signed-off-by: Ragner Magalhaes [EMAIL PROTECTED] :00 100644 000... e6551d9... A drivers/usb/gadget/gadget.c diff --git a/drivers/usb/gadget/gadget.c b/drivers/usb/gadget/gadget.c new file mode 100644 index 000..e6551d9 --- /dev/null +++ b/drivers/usb/gadget/gadget.c @@ -0,0 +1,293 @@ +/* + * gadget.c -- USB gadget driver. + * + * Copyright (C) 2007 Instituto Nokia de Tecnologia - INdT + * Developed for INdT by Ragner Magalhaes + * Ragner Magalhaes [EMAIL PROTECTED] + * + * This software is distributed under the terms of the GNU General Public + * License (GPL) version 2, as published by the Free Software Foundation. + * + * Implements support for one gadget device with a single function. + */ + +#if 0 +#define DEBUG 1 +#define VERBOSE 1 +#endif + +#include linux/module.h +#include linux/kernel.h +#include linux/delay.h +#include linux/ioport.h +#include linux/sched.h +#include linux/slab.h +#include linux/smp_lock.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/device.h +#include linux/moduleparam.h + +#include asm/byteorder.h +#include asm/system.h +#include asm/unaligned.h + +#include linux/usb/ch9.h +#include linux/usb/cdc.h +#include linux/usb_gadget.h +#include linux/usb/composite.h + +#include gadget_chips.h + +/*-*/ + +#define xprintk(d,level,fmt,args...) \ + dev_printk(level , (d)-gadget-dev , fmt , ## args) + +#ifdef DEBUG +#define DBG(dev,fmt,args...) \ + xprintk(dev , KERN_DEBUG , fmt , ## args) +#else +#define DBG(dev,fmt,args...) \ + do { } while(0) +#endif /* DEBUG */ + +#ifdef VERBOSE +#define VDBG DBG +#else +#define VDBG(dev,fmt,args...) \ + do { } while(0) +#endif /* VERBOSE */ + +#define ERROR(dev,fmt,args...) \ + xprintk(dev , KERN_ERR , fmt , ## args) +#define WARN(dev,fmt,args...) \ + xprintk(dev , KERN_WARNING , fmt , ## args) +#define INFO(dev,fmt,args...) \ + xprintk(dev , KERN_INFO , fmt , ## args) + +/*-*/ + +/* big enough to hold our biggest descriptor */ +#define USB_BUFSIZ 256 + + +struct usb_function*func; + +/*-*/ + +/* An impossibly large value as file_storage */ +#define DELAYED_STATUS (USB_BUFSIZ + 999) + +void usb_func_ep_reset (struct usb_gadget *g, struct usb_function *f) +{ + struct usb_ep *ep; + + list_for_each_entry (ep, g-ep_list, ep_list) { + if (ep-driver_data == f-driver_data) { + usb_ep_disable (ep); + ep-driver_data = NULL; + } + } +} + +static void +free_ep_req(struct usb_ep *ep, struct usb_request *req) +{ + if (req-buf) + kfree (req-buf); + usb_ep_free_request(ep, req); +} + +/*-*/ + +static void +gadget_setup_complete(struct usb_ep *ep, struct usb_request *req) +{ + if (req-status || req-actual != req-length) + DBG((struct usb_gadget_dev *)ep-driver_data, + setup complete -- %d, %u/%u\n, + req-status, req-actual, req-length); +} + +static int +gadget_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) +{ + struct usb_gadget_dev *dev = get_gadget_data(gadget); + struct usb_request *req = dev-req; + int value = -EOPNOTSUPP; + u16 w_index = le16_to_cpu(ctrl-wIndex); + u16 w_value = le16_to_cpu(ctrl-wValue); + u16 w_length = le16_to_cpu(ctrl-wLength); + + req-complete = gadget_setup_complete; + req-zero = 0; + spin_lock(dev-lock); + value = dev-func-setup (gadget, ctrl); + spin_unlock(dev-lock); + + /* respond with data transfer before status phase? */ + if (value = 0 value != DELAYED_STATUS) { + req-length = value; + req-zero = value w_length; + value = usb_ep_queue(gadget-ep0, req, GFP_ATOMIC); + if (value 0) { + DBG(dev, ep_queue -- %d\n, value); + req-status = 0; + gadget_setup_complete(gadget-ep0, req); + } + } else { + DBG(dev, setup req%02x.%02x v%04x i%04x l%d -- %d\n, + ctrl-bRequestType, ctrl-bRequest, + w_value, w_index, w_length, value); + /* to eliminate compile warnings */ + w_index = w_value = 0; + } +
[linux-usb-devel] [PATCH 1/6] USB gadget driver
Implements support for a gadget function with composite support to work as a single function. Signed-off-by: Ragner Magalhaes [EMAIL PROTECTED] :00 100644 000... e6551d9... A drivers/usb/gadget/gadget.c diff --git a/drivers/usb/gadget/gadget.c b/drivers/usb/gadget/gadget.c new file mode 100644 index 000..e6551d9 --- /dev/null +++ b/drivers/usb/gadget/gadget.c @@ -0,0 +1,293 @@ +/* + * gadget.c -- USB gadget driver. + * + * Copyright (C) 2007 Instituto Nokia de Tecnologia - INdT + * Developed for INdT by Ragner Magalhaes + * Ragner Magalhaes [EMAIL PROTECTED] + * + * This software is distributed under the terms of the GNU General Public + * License (GPL) version 2, as published by the Free Software Foundation. + * + * Implements support for one gadget device with a single function. + */ + +#if 0 +#define DEBUG 1 +#define VERBOSE 1 +#endif + +#include linux/module.h +#include linux/kernel.h +#include linux/delay.h +#include linux/ioport.h +#include linux/sched.h +#include linux/slab.h +#include linux/smp_lock.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/device.h +#include linux/moduleparam.h + +#include asm/byteorder.h +#include asm/system.h +#include asm/unaligned.h + +#include linux/usb/ch9.h +#include linux/usb/cdc.h +#include linux/usb_gadget.h +#include linux/usb/composite.h + +#include gadget_chips.h + +/*-*/ + +#define xprintk(d,level,fmt,args...) \ + dev_printk(level , (d)-gadget-dev , fmt , ## args) + +#ifdef DEBUG +#define DBG(dev,fmt,args...) \ + xprintk(dev , KERN_DEBUG , fmt , ## args) +#else +#define DBG(dev,fmt,args...) \ + do { } while(0) +#endif /* DEBUG */ + +#ifdef VERBOSE +#define VDBG DBG +#else +#define VDBG(dev,fmt,args...) \ + do { } while(0) +#endif /* VERBOSE */ + +#define ERROR(dev,fmt,args...) \ + xprintk(dev , KERN_ERR , fmt , ## args) +#define WARN(dev,fmt,args...) \ + xprintk(dev , KERN_WARNING , fmt , ## args) +#define INFO(dev,fmt,args...) \ + xprintk(dev , KERN_INFO , fmt , ## args) + +/*-*/ + +/* big enough to hold our biggest descriptor */ +#define USB_BUFSIZ 256 + + +struct usb_function*func; + +/*-*/ + +/* An impossibly large value as file_storage */ +#define DELAYED_STATUS (USB_BUFSIZ + 999) + +void usb_func_ep_reset (struct usb_gadget *g, struct usb_function *f) +{ + struct usb_ep *ep; + + list_for_each_entry (ep, g-ep_list, ep_list) { + if (ep-driver_data == f-driver_data) { + usb_ep_disable (ep); + ep-driver_data = NULL; + } + } +} + +static void +free_ep_req(struct usb_ep *ep, struct usb_request *req) +{ + if (req-buf) + kfree (req-buf); + usb_ep_free_request(ep, req); +} + +/*-*/ + +static void +gadget_setup_complete(struct usb_ep *ep, struct usb_request *req) +{ + if (req-status || req-actual != req-length) + DBG((struct usb_gadget_dev *)ep-driver_data, + setup complete -- %d, %u/%u\n, + req-status, req-actual, req-length); +} + +static int +gadget_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) +{ + struct usb_gadget_dev *dev = get_gadget_data(gadget); + struct usb_request *req = dev-req; + int value = -EOPNOTSUPP; + u16 w_index = le16_to_cpu(ctrl-wIndex); + u16 w_value = le16_to_cpu(ctrl-wValue); + u16 w_length = le16_to_cpu(ctrl-wLength); + + req-complete = gadget_setup_complete; + req-zero = 0; + spin_lock(dev-lock); + value = dev-func-setup (gadget, ctrl); + spin_unlock(dev-lock); + + /* respond with data transfer before status phase? */ + if (value = 0 value != DELAYED_STATUS) { + req-length = value; + req-zero = value w_length; + value = usb_ep_queue(gadget-ep0, req, GFP_ATOMIC); + if (value 0) { + DBG(dev, ep_queue -- %d\n, value); + req-status = 0; + gadget_setup_complete(gadget-ep0, req); + } + } else { + DBG(dev, setup req%02x.%02x v%04x i%04x l%d -- %d\n, + ctrl-bRequestType, ctrl-bRequest, + w_value, w_index, w_length, value); + /* to eliminate compile warnings */ + w_index = w_value = 0; + } +
[linux-usb-devel] [PATCH 1/6] USB gadget driver
Implements support for a gadget function with composite support to work as a single function. Signed-off-by: Ragner Magalhaes [EMAIL PROTECTED] :00 100644 000... e6551d9... A drivers/usb/gadget/gadget.c diff --git a/drivers/usb/gadget/gadget.c b/drivers/usb/gadget/gadget.c new file mode 100644 index 000..e6551d9 --- /dev/null +++ b/drivers/usb/gadget/gadget.c @@ -0,0 +1,293 @@ +/* + * gadget.c -- USB gadget driver. + * + * Copyright (C) 2007 Instituto Nokia de Tecnologia - INdT + * Developed for INdT by Ragner Magalhaes + * Ragner Magalhaes [EMAIL PROTECTED] + * + * This software is distributed under the terms of the GNU General Public + * License (GPL) version 2, as published by the Free Software Foundation. + * + * Implements support for one gadget device with a single function. + */ + +#if 0 +#define DEBUG 1 +#define VERBOSE 1 +#endif + +#include linux/module.h +#include linux/kernel.h +#include linux/delay.h +#include linux/ioport.h +#include linux/sched.h +#include linux/slab.h +#include linux/smp_lock.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/device.h +#include linux/moduleparam.h + +#include asm/byteorder.h +#include asm/system.h +#include asm/unaligned.h + +#include linux/usb/ch9.h +#include linux/usb/cdc.h +#include linux/usb_gadget.h +#include linux/usb/composite.h + +#include gadget_chips.h + +/*-*/ + +#define xprintk(d,level,fmt,args...) \ + dev_printk(level , (d)-gadget-dev , fmt , ## args) + +#ifdef DEBUG +#define DBG(dev,fmt,args...) \ + xprintk(dev , KERN_DEBUG , fmt , ## args) +#else +#define DBG(dev,fmt,args...) \ + do { } while(0) +#endif /* DEBUG */ + +#ifdef VERBOSE +#define VDBG DBG +#else +#define VDBG(dev,fmt,args...) \ + do { } while(0) +#endif /* VERBOSE */ + +#define ERROR(dev,fmt,args...) \ + xprintk(dev , KERN_ERR , fmt , ## args) +#define WARN(dev,fmt,args...) \ + xprintk(dev , KERN_WARNING , fmt , ## args) +#define INFO(dev,fmt,args...) \ + xprintk(dev , KERN_INFO , fmt , ## args) + +/*-*/ + +/* big enough to hold our biggest descriptor */ +#define USB_BUFSIZ 256 + + +struct usb_function*func; + +/*-*/ + +/* An impossibly large value as file_storage */ +#define DELAYED_STATUS (USB_BUFSIZ + 999) + +void usb_func_ep_reset (struct usb_gadget *g, struct usb_function *f) +{ + struct usb_ep *ep; + + list_for_each_entry (ep, g-ep_list, ep_list) { + if (ep-driver_data == f-driver_data) { + usb_ep_disable (ep); + ep-driver_data = NULL; + } + } +} + +static void +free_ep_req(struct usb_ep *ep, struct usb_request *req) +{ + if (req-buf) + kfree (req-buf); + usb_ep_free_request(ep, req); +} + +/*-*/ + +static void +gadget_setup_complete(struct usb_ep *ep, struct usb_request *req) +{ + if (req-status || req-actual != req-length) + DBG((struct usb_gadget_dev *)ep-driver_data, + setup complete -- %d, %u/%u\n, + req-status, req-actual, req-length); +} + +static int +gadget_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) +{ + struct usb_gadget_dev *dev = get_gadget_data(gadget); + struct usb_request *req = dev-req; + int value = -EOPNOTSUPP; + u16 w_index = le16_to_cpu(ctrl-wIndex); + u16 w_value = le16_to_cpu(ctrl-wValue); + u16 w_length = le16_to_cpu(ctrl-wLength); + + req-complete = gadget_setup_complete; + req-zero = 0; + spin_lock(dev-lock); + value = dev-func-setup (gadget, ctrl); + spin_unlock(dev-lock); + + /* respond with data transfer before status phase? */ + if (value = 0 value != DELAYED_STATUS) { + req-length = value; + req-zero = value w_length; + value = usb_ep_queue(gadget-ep0, req, GFP_ATOMIC); + if (value 0) { + DBG(dev, ep_queue -- %d\n, value); + req-status = 0; + gadget_setup_complete(gadget-ep0, req); + } + } else { + DBG(dev, setup req%02x.%02x v%04x i%04x l%d -- %d\n, + ctrl-bRequestType, ctrl-bRequest, + w_value, w_index, w_length, value); + /* to eliminate compile warnings */ + w_index = w_value = 0; + } +
[linux-usb-devel] [PATCH 1/6] USB gadget driver
Implements support for a gadget function with composite support to work as a single function. Signed-off-by: Ragner Magalhaes [EMAIL PROTECTED] :00 100644 000... e6551d9... A drivers/usb/gadget/gadget.c diff --git a/drivers/usb/gadget/gadget.c b/drivers/usb/gadget/gadget.c new file mode 100644 index 000..e6551d9 --- /dev/null +++ b/drivers/usb/gadget/gadget.c @@ -0,0 +1,293 @@ +/* + * gadget.c -- USB gadget driver. + * + * Copyright (C) 2007 Instituto Nokia de Tecnologia - INdT + * Developed for INdT by Ragner Magalhaes + * Ragner Magalhaes [EMAIL PROTECTED] + * + * This software is distributed under the terms of the GNU General Public + * License (GPL) version 2, as published by the Free Software Foundation. + * + * Implements support for one gadget device with a single function. + */ + +#if 0 +#define DEBUG 1 +#define VERBOSE 1 +#endif + +#include linux/module.h +#include linux/kernel.h +#include linux/delay.h +#include linux/ioport.h +#include linux/sched.h +#include linux/slab.h +#include linux/smp_lock.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/device.h +#include linux/moduleparam.h + +#include asm/byteorder.h +#include asm/system.h +#include asm/unaligned.h + +#include linux/usb/ch9.h +#include linux/usb/cdc.h +#include linux/usb_gadget.h +#include linux/usb/composite.h + +#include gadget_chips.h + +/*-*/ + +#define xprintk(d,level,fmt,args...) \ + dev_printk(level , (d)-gadget-dev , fmt , ## args) + +#ifdef DEBUG +#define DBG(dev,fmt,args...) \ + xprintk(dev , KERN_DEBUG , fmt , ## args) +#else +#define DBG(dev,fmt,args...) \ + do { } while(0) +#endif /* DEBUG */ + +#ifdef VERBOSE +#define VDBG DBG +#else +#define VDBG(dev,fmt,args...) \ + do { } while(0) +#endif /* VERBOSE */ + +#define ERROR(dev,fmt,args...) \ + xprintk(dev , KERN_ERR , fmt , ## args) +#define WARN(dev,fmt,args...) \ + xprintk(dev , KERN_WARNING , fmt , ## args) +#define INFO(dev,fmt,args...) \ + xprintk(dev , KERN_INFO , fmt , ## args) + +/*-*/ + +/* big enough to hold our biggest descriptor */ +#define USB_BUFSIZ 256 + + +struct usb_function*func; + +/*-*/ + +/* An impossibly large value as file_storage */ +#define DELAYED_STATUS (USB_BUFSIZ + 999) + +void usb_func_ep_reset (struct usb_gadget *g, struct usb_function *f) +{ + struct usb_ep *ep; + + list_for_each_entry (ep, g-ep_list, ep_list) { + if (ep-driver_data == f-driver_data) { + usb_ep_disable (ep); + ep-driver_data = NULL; + } + } +} + +static void +free_ep_req(struct usb_ep *ep, struct usb_request *req) +{ + if (req-buf) + kfree (req-buf); + usb_ep_free_request(ep, req); +} + +/*-*/ + +static void +gadget_setup_complete(struct usb_ep *ep, struct usb_request *req) +{ + if (req-status || req-actual != req-length) + DBG((struct usb_gadget_dev *)ep-driver_data, + setup complete -- %d, %u/%u\n, + req-status, req-actual, req-length); +} + +static int +gadget_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) +{ + struct usb_gadget_dev *dev = get_gadget_data(gadget); + struct usb_request *req = dev-req; + int value = -EOPNOTSUPP; + u16 w_index = le16_to_cpu(ctrl-wIndex); + u16 w_value = le16_to_cpu(ctrl-wValue); + u16 w_length = le16_to_cpu(ctrl-wLength); + + req-complete = gadget_setup_complete; + req-zero = 0; + spin_lock(dev-lock); + value = dev-func-setup (gadget, ctrl); + spin_unlock(dev-lock); + + /* respond with data transfer before status phase? */ + if (value = 0 value != DELAYED_STATUS) { + req-length = value; + req-zero = value w_length; + value = usb_ep_queue(gadget-ep0, req, GFP_ATOMIC); + if (value 0) { + DBG(dev, ep_queue -- %d\n, value); + req-status = 0; + gadget_setup_complete(gadget-ep0, req); + } + } else { + DBG(dev, setup req%02x.%02x v%04x i%04x l%d -- %d\n, + ctrl-bRequestType, ctrl-bRequest, + w_value, w_index, w_length, value); + /* to eliminate compile warnings */ + w_index = w_value = 0; + } +
[linux-usb-devel] [PATCH 1/6] USB gadget driver
Implements support for a gadget function with composite support to work as a single function. Signed-off-by: Ragner Magalhaes [EMAIL PROTECTED] :00 100644 000... e6551d9... A drivers/usb/gadget/gadget.c diff --git a/drivers/usb/gadget/gadget.c b/drivers/usb/gadget/gadget.c new file mode 100644 index 000..e6551d9 --- /dev/null +++ b/drivers/usb/gadget/gadget.c @@ -0,0 +1,293 @@ +/* + * gadget.c -- USB gadget driver. + * + * Copyright (C) 2007 Instituto Nokia de Tecnologia - INdT + * Developed for INdT by Ragner Magalhaes + * Ragner Magalhaes [EMAIL PROTECTED] + * + * This software is distributed under the terms of the GNU General Public + * License (GPL) version 2, as published by the Free Software Foundation. + * + * Implements support for one gadget device with a single function. + */ + +#if 0 +#define DEBUG 1 +#define VERBOSE 1 +#endif + +#include linux/module.h +#include linux/kernel.h +#include linux/delay.h +#include linux/ioport.h +#include linux/sched.h +#include linux/slab.h +#include linux/smp_lock.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/device.h +#include linux/moduleparam.h + +#include asm/byteorder.h +#include asm/system.h +#include asm/unaligned.h + +#include linux/usb/ch9.h +#include linux/usb/cdc.h +#include linux/usb_gadget.h +#include linux/usb/composite.h + +#include gadget_chips.h + +/*-*/ + +#define xprintk(d,level,fmt,args...) \ + dev_printk(level , (d)-gadget-dev , fmt , ## args) + +#ifdef DEBUG +#define DBG(dev,fmt,args...) \ + xprintk(dev , KERN_DEBUG , fmt , ## args) +#else +#define DBG(dev,fmt,args...) \ + do { } while(0) +#endif /* DEBUG */ + +#ifdef VERBOSE +#define VDBG DBG +#else +#define VDBG(dev,fmt,args...) \ + do { } while(0) +#endif /* VERBOSE */ + +#define ERROR(dev,fmt,args...) \ + xprintk(dev , KERN_ERR , fmt , ## args) +#define WARN(dev,fmt,args...) \ + xprintk(dev , KERN_WARNING , fmt , ## args) +#define INFO(dev,fmt,args...) \ + xprintk(dev , KERN_INFO , fmt , ## args) + +/*-*/ + +/* big enough to hold our biggest descriptor */ +#define USB_BUFSIZ 256 + + +struct usb_function*func; + +/*-*/ + +/* An impossibly large value as file_storage */ +#define DELAYED_STATUS (USB_BUFSIZ + 999) + +void usb_func_ep_reset (struct usb_gadget *g, struct usb_function *f) +{ + struct usb_ep *ep; + + list_for_each_entry (ep, g-ep_list, ep_list) { + if (ep-driver_data == f-driver_data) { + usb_ep_disable (ep); + ep-driver_data = NULL; + } + } +} + +static void +free_ep_req(struct usb_ep *ep, struct usb_request *req) +{ + if (req-buf) + kfree (req-buf); + usb_ep_free_request(ep, req); +} + +/*-*/ + +static void +gadget_setup_complete(struct usb_ep *ep, struct usb_request *req) +{ + if (req-status || req-actual != req-length) + DBG((struct usb_gadget_dev *)ep-driver_data, + setup complete -- %d, %u/%u\n, + req-status, req-actual, req-length); +} + +static int +gadget_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) +{ + struct usb_gadget_dev *dev = get_gadget_data(gadget); + struct usb_request *req = dev-req; + int value = -EOPNOTSUPP; + u16 w_index = le16_to_cpu(ctrl-wIndex); + u16 w_value = le16_to_cpu(ctrl-wValue); + u16 w_length = le16_to_cpu(ctrl-wLength); + + req-complete = gadget_setup_complete; + req-zero = 0; + spin_lock(dev-lock); + value = dev-func-setup (gadget, ctrl); + spin_unlock(dev-lock); + + /* respond with data transfer before status phase? */ + if (value = 0 value != DELAYED_STATUS) { + req-length = value; + req-zero = value w_length; + value = usb_ep_queue(gadget-ep0, req, GFP_ATOMIC); + if (value 0) { + DBG(dev, ep_queue -- %d\n, value); + req-status = 0; + gadget_setup_complete(gadget-ep0, req); + } + } else { + DBG(dev, setup req%02x.%02x v%04x i%04x l%d -- %d\n, + ctrl-bRequestType, ctrl-bRequest, + w_value, w_index, w_length, value); + /* to eliminate compile warnings */ + w_index = w_value = 0; + } +