#include "gadget_chips.h"
-/* Wait Cond */
-
-#define __wait_cond_interruptible(wq, condition, lock, flags, ret) \
-do { \
- wait_queue_t __wait; \
- init_waitqueue_entry(&__wait, current); \
- \
- add_wait_queue(&wq, &__wait); \
- for (;;) { \
- set_current_state(TASK_INTERRUPTIBLE); \
- if (condition) \
- break; \
- if (!signal_pending(current)) { \
- spin_unlock_irqrestore(lock, flags); \
- schedule(); \
- spin_lock_irqsave(lock, flags); \
- continue; \
- } \
- ret = -ERESTARTSYS; \
- break; \
- } \
- current->state = TASK_RUNNING; \
- remove_wait_queue(&wq, &__wait); \
-} while (0)
-
-#define wait_cond_interruptible(wq, condition, lock, flags) \
-({ \
- int __ret = 0; \
- if (!(condition)) \
- __wait_cond_interruptible(wq, condition, lock, flags, \
- __ret); \
- __ret; \
-})
-
-#define __wait_cond_interruptible_timeout(wq, condition, lock, flags, \
- timeout, ret) \
-do { \
- signed long __timeout = timeout; \
- wait_queue_t __wait; \
- init_waitqueue_entry(&__wait, current); \
- \
- add_wait_queue(&wq, &__wait); \
- for (;;) { \
- set_current_state(TASK_INTERRUPTIBLE); \
- if (__timeout == 0) \
- break; \
- if (condition) \
- break; \
- if (!signal_pending(current)) { \
- spin_unlock_irqrestore(lock, flags); \
- __timeout = schedule_timeout(__timeout); \
- spin_lock_irqsave(lock, flags); \
- continue; \
- } \
- ret = -ERESTARTSYS; \
- break; \
- } \
- current->state = TASK_RUNNING; \
- remove_wait_queue(&wq, &__wait); \
-} while (0)
-
-#define wait_cond_interruptible_timeout(wq, condition, lock, flags, \
- timeout) \
-({ \
- int __ret = 0; \
- if (!(condition)) \
- __wait_cond_interruptible_timeout(wq, condition, lock, \
- flags, timeout, __ret); \
- __ret; \
-})
-
-
/* Defines */
-#define GS_VERSION_STR "v2.0"
-#define GS_VERSION_NUM 0x0200
+#define GS_VERSION_STR "v2.1"
+#define GS_VERSION_NUM 0x0201
#define GS_LONG_NAME "Gadget Serial"
#define GS_SHORT_NAME "g_serial"
u8 type, unsigned int index, int is_otg);
static struct usb_request *gs_alloc_req(struct usb_ep *ep, unsigned int len,
- unsigned kmalloc_flags);
+ gfp_t kmalloc_flags);
static void gs_free_req(struct usb_ep *ep, struct usb_request *req);
static struct gs_req_entry *gs_alloc_req_entry(struct usb_ep *ep, unsigned len,
- unsigned kmalloc_flags);
+ gfp_t kmalloc_flags);
static void gs_free_req_entry(struct usb_ep *ep, struct gs_req_entry *req);
-static int gs_alloc_ports(struct gs_dev *dev, unsigned kmalloc_flags);
+static int gs_alloc_ports(struct gs_dev *dev, gfp_t kmalloc_flags);
static void gs_free_ports(struct gs_dev *dev);
/* circular buffer */
-static struct gs_buf *gs_buf_alloc(unsigned int size, unsigned kmalloc_flags);
+static struct gs_buf *gs_buf_alloc(unsigned int size, gfp_t kmalloc_flags);
static void gs_buf_free(struct gs_buf *gb);
static void gs_buf_clear(struct gs_buf *gb);
static unsigned int gs_buf_data_avail(struct gs_buf *gb);
#endif /* CONFIG_USB_GADGET_DUALSPEED */
.function = GS_LONG_NAME,
.bind = gs_bind,
- .unbind = gs_unbind,
+ .unbind = __exit_p(gs_unbind),
.setup = gs_setup,
.disconnect = gs_disconnect,
.driver = {
.name = GS_SHORT_NAME,
- /* .shutdown = ... */
- /* .suspend = ... */
- /* .resume = ... */
},
};
/*
* gs_close
*/
+
+#define GS_WRITE_FINISHED_EVENT_SAFELY(p) \
+({ \
+ unsigned long flags; \
+ int cond; \
+ \
+ spin_lock_irqsave(&(p)->port_lock, flags); \
+ cond = !(p)->port_dev || !gs_buf_data_avail((p)->port_write_buf); \
+ spin_unlock_irqrestore(&(p)->port_lock, flags); \
+ cond; \
+})
+
static void gs_close(struct tty_struct *tty, struct file *file)
{
unsigned long flags;
/* wait for write buffer to drain, or */
/* at most GS_CLOSE_TIMEOUT seconds */
if (gs_buf_data_avail(port->port_write_buf) > 0) {
- wait_cond_interruptible_timeout(port->port_write_wait,
- port->port_dev == NULL
- || gs_buf_data_avail(port->port_write_buf) == 0,
- &port->port_lock, flags, GS_CLOSE_TIMEOUT * HZ);
+ spin_unlock_irqrestore(&port->port_lock, flags);
+ wait_event_interruptible_timeout(port->port_write_wait,
+ GS_WRITE_FINISHED_EVENT_SAFELY(port),
+ GS_CLOSE_TIMEOUT * HZ);
+ spin_lock_irqsave(&port->port_lock, flags);
}
/* free disconnected port on final close */
unsigned int len;
struct gs_port *port;
int ret;
+ struct tty_struct *tty;
/* TEMPORARY -- only port 0 is supported right now */
port = dev->dev_port[0];
goto exit;
}
- if (port->port_tty == NULL) {
+
+ tty = port->port_tty;
+
+ if (tty == NULL) {
printk(KERN_ERR "gs_recv_packet: port=%d, NULL tty pointer\n",
port->port_num);
ret = -EIO;
goto exit;
}
- len = (unsigned int)(TTY_FLIPBUF_SIZE - port->port_tty->flip.count);
- if (len < size)
- size = len;
-
- if (size > 0) {
- memcpy(port->port_tty->flip.char_buf_ptr, packet, size);
- port->port_tty->flip.char_buf_ptr += size;
- port->port_tty->flip.count += size;
+ len = tty_buffer_request_room(tty, size);
+ if (len > 0) {
+ tty_insert_flip_string(tty, packet, len);
tty_flip_buffer_push(port->port_tty);
wake_up_interruptible(&port->port_tty->read_wait);
}
-
ret = 0;
-
exit:
spin_unlock(&port->port_lock);
return ret;
* Called on module load. Allocates and initializes the device
* structure and a control request.
*/
-static int gs_bind(struct usb_gadget *gadget)
+static int __init gs_bind(struct usb_gadget *gadget)
{
int ret;
struct usb_ep *ep;
* Called on module unload. Frees the control request and device
* structure.
*/
-static void gs_unbind(struct usb_gadget *gadget)
+static void __exit gs_unbind(struct usb_gadget *gadget)
{
struct gs_dev *dev = get_gadget_data(gadget);
* usb_request or NULL if there is an error.
*/
static struct usb_request *
-gs_alloc_req(struct usb_ep *ep, unsigned int len, unsigned kmalloc_flags)
+gs_alloc_req(struct usb_ep *ep, unsigned int len, gfp_t kmalloc_flags)
{
struct usb_request *req;
* endpoint, buffer len, and kmalloc flags.
*/
static struct gs_req_entry *
-gs_alloc_req_entry(struct usb_ep *ep, unsigned len, unsigned kmalloc_flags)
+gs_alloc_req_entry(struct usb_ep *ep, unsigned len, gfp_t kmalloc_flags)
{
struct gs_req_entry *req;
*
* The device lock is normally held when calling this function.
*/
-static int gs_alloc_ports(struct gs_dev *dev, unsigned kmalloc_flags)
+static int gs_alloc_ports(struct gs_dev *dev, gfp_t kmalloc_flags)
{
int i;
struct gs_port *port;
return -EIO;
for (i=0; i<GS_NUM_PORTS; i++) {
- if ((port=(struct gs_port *)kmalloc(sizeof(struct gs_port), kmalloc_flags)) == NULL)
+ if ((port=kzalloc(sizeof(struct gs_port), kmalloc_flags)) == NULL)
return -ENOMEM;
- memset(port, 0, sizeof(struct gs_port));
port->port_dev = dev;
port->port_num = i;
port->port_line_coding.dwDTERate = cpu_to_le32(GS_DEFAULT_DTE_RATE);
*
* Allocate a circular buffer and all associated memory.
*/
-static struct gs_buf *gs_buf_alloc(unsigned int size, unsigned kmalloc_flags)
+static struct gs_buf *gs_buf_alloc(unsigned int size, gfp_t kmalloc_flags)
{
struct gs_buf *gb;