Introduce pet-projects dir
[lcapit-junk-code.git] / linux-kernel / PATCHES / serial-core-port-V0 / 0007-usbserial-pl2303-Initial-Serial-Core-port.patch
blob854f6eb5edcd0be31a95a0b03e5468cab225851b
1 From deaddbb51bc79f2a2af1a2dda868c7738ae44d94 Mon Sep 17 00:00:00 2001
2 From: Luiz Fernando N. Capitulino <lcapitulino@mandriva.com.br>
3 Date: Thu, 1 Jun 2006 19:12:41 -0300
4 Subject: [PATCH 7/11] usbserial: pl2303: Initial Serial Core port.
6 This patch ports the pl2303 USB-Serial's attach() and shutdown() methods to
7 the Serial Core version of the USB-Serial's core.
9 Also note that they have been renamed to avoid name collision in the next
10 patches:
12 pl2303_startup() -> pl2303_attach()
13 pl2303_shutdown() -> pl2303_usb_shutdown()
15 Additionally, this patch also adds refcouting to the struct pl2303_private
16 structure.
18 This is needed because the p2l303 Serial Core version cannot free its
19 dynamic allocated struct pl2303_private in pl2303_usb_shutdown() anymore,
20 because we can get a NULL pointer in the other methods (eg. pl2303_shutdown()).
22 Signed-off-by: Luiz Fernando N. Capitulino <lcapitulino@mandriva.com.br>
23 ---
24 drivers/usb/serial/pl2303.c | 50 +++++++++++++++++++++++++------------------
25 1 files changed, 29 insertions(+), 21 deletions(-)
27 diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
28 index f9300b8..0b60c04 100644
29 --- a/drivers/usb/serial/pl2303.c
30 +++ b/drivers/usb/serial/pl2303.c
31 @@ -20,12 +20,12 @@ #include <linux/errno.h>
32 #include <linux/init.h>
33 #include <linux/slab.h>
34 #include <linux/tty.h>
35 -#include <linux/tty_driver.h>
36 #include <linux/tty_flip.h>
37 #include <linux/serial.h>
38 #include <linux/module.h>
39 #include <linux/moduleparam.h>
40 #include <linux/spinlock.h>
41 +#include <linux/kref.h>
42 #include <asm/uaccess.h>
43 #include <linux/usb.h>
44 #include "usb-serial.h"
45 @@ -145,8 +145,8 @@ static void pl2303_break_ctl(struct usb_
46 static int pl2303_tiocmget (struct usb_serial_port *port, struct file *file);
47 static int pl2303_tiocmset (struct usb_serial_port *port, struct file *file,
48 unsigned int set, unsigned int clear);
49 -static int pl2303_startup (struct usb_serial *serial);
50 -static void pl2303_shutdown (struct usb_serial *serial);
51 +static int pl2303_attach(struct usb_serial *serial);
52 +static void pl2303_usb_shutdown(struct usb_serial *serial);
53 static struct pl2303_buf *pl2303_buf_alloc(unsigned int size);
54 static void pl2303_buf_free(struct pl2303_buf *pb);
55 static void pl2303_buf_clear(struct pl2303_buf *pb);
56 @@ -182,8 +182,8 @@ static struct usb_serial_driver pl2303_d
57 .write_bulk_callback = pl2303_write_bulk_callback,
58 .write_room = pl2303_write_room,
59 .chars_in_buffer = pl2303_chars_in_buffer,
60 - .attach = pl2303_startup,
61 - .shutdown = pl2303_shutdown,
62 + .attach = pl2303_attach,
63 + .shutdown = pl2303_usb_shutdown,
66 enum pl2303_type {
67 @@ -201,10 +201,20 @@ struct pl2303_private {
68 u8 line_status;
69 u8 termios_initialized;
70 enum pl2303_type type;
71 + struct kref kref;
73 +#define to_pl2303_private(p) container_of(p, struct pl2303_private, kref)
75 +static void destroy_priv(struct kref *kref)
77 + struct pl2303_private *priv;
79 + priv = to_pl2303_private(kref);
80 + pl2303_buf_free(priv->buf);
81 + kfree(priv);
84 -static int pl2303_startup (struct usb_serial *serial)
85 +static int pl2303_attach(struct usb_serial *serial)
87 struct pl2303_private *priv;
88 enum pl2303_type type = type_0;
89 @@ -222,15 +232,18 @@ static int pl2303_startup (struct usb_se
91 for (i = 0; i < serial->num_ports; ++i) {
92 priv = kzalloc(sizeof(struct pl2303_private), GFP_KERNEL);
93 - if (!priv)
94 + if (!priv) {
95 + err("Couldn't allocate memory");
96 goto cleanup;
97 + }
98 + kref_init(&priv->kref);
99 spin_lock_init(&priv->lock);
100 priv->buf = pl2303_buf_alloc(PL2303_BUF_SIZE);
101 - if (priv->buf == NULL) {
102 - kfree(priv);
103 + if (!priv->buf) {
104 + err("Couldn't allocate memory");
105 + kref_put(&priv->kref, destroy_priv);
106 goto cleanup;
108 - init_waitqueue_head(&priv->delta_msr_wait);
109 priv->type = type;
110 usb_set_serial_port_data(serial->port[i], priv);
112 @@ -239,8 +252,7 @@ static int pl2303_startup (struct usb_se
113 cleanup:
114 for (--i; i>=0; --i) {
115 priv = usb_get_serial_port_data(serial->port[i]);
116 - pl2303_buf_free(priv->buf);
117 - kfree(priv);
118 + kref_put(&priv->kref, destroy_priv);
119 usb_set_serial_port_data(serial->port[i], NULL);
121 return -ENOMEM;
122 @@ -786,22 +798,18 @@ static void pl2303_break_ctl (struct usb
123 dbg("error sending break = %d", result);
127 -static void pl2303_shutdown (struct usb_serial *serial)
128 +static void pl2303_usb_shutdown(struct usb_serial *serial)
130 int i;
131 struct pl2303_private *priv;
133 - dbg("");
134 + dbg("%s", serial->type->description);
136 for (i = 0; i < serial->num_ports; ++i) {
137 priv = usb_get_serial_port_data(serial->port[i]);
138 - if (priv) {
139 - pl2303_buf_free(priv->buf);
140 - kfree(priv);
141 - usb_set_serial_port_data(serial->port[i], NULL);
143 - }
144 + if (priv)
145 + kref_put(&priv->kref, destroy_priv);
149 static void pl2303_update_line_status(struct usb_serial_port *port,
151 1.3.3.g0825d