Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
846 giacomo 1
/*
2
 * USB Serial Converter Generic functions
3
 *
4
 * Copyright (C) 1999 - 2002 Greg Kroah-Hartman (greg@kroah.com)
5
 *
6
 *      This program is free software; you can redistribute it and/or
7
 *      modify it under the terms of the GNU General Public License version
8
 *      2 as published by the Free Software Foundation.
9
 *
10
 */
11
 
12
#include <linuxcomp.h>
13
 
14
#include <linux/config.h>
15
#include <linux/kernel.h>
16
#include <linux/errno.h>
17
#include <linux/slab.h>
18
#include <linux/tty.h>
19
#include <linux/tty_flip.h>
20
#include <linux/module.h>
21
#include <linux/usb.h>
22
#include <asm/uaccess.h>
23
 
24
#ifdef CONFIG_USB_SERIAL_DEBUG
25
        static int debug = 1;
26
#else
27
        static int debug;
28
#endif
29
 
30
#include "usb-serial.h"
31
 
32
 
33
#ifdef CONFIG_USB_SERIAL_GENERIC
34
static __u16 vendor  = 0x05f9;
35
static __u16 product = 0xffff;
36
 
37
MODULE_PARM(vendor, "h");
38
MODULE_PARM_DESC(vendor, "User specified USB idVendor");
39
 
40
MODULE_PARM(product, "h");
41
MODULE_PARM_DESC(product, "User specified USB idProduct");
42
 
43
static struct usb_device_id generic_device_ids[2]; /* Initially all zeroes. */
44
 
45
/* All of the device info needed for the Generic Serial Converter */
46
struct usb_serial_device_type usb_serial_generic_device = {
47
        .owner =                THIS_MODULE,
48
        .name =                 "Generic",
49
        .short_name =           "generic",
50
        .id_table =             generic_device_ids,
51
        .num_interrupt_in =     NUM_DONT_CARE,
52
        .num_bulk_in =          NUM_DONT_CARE,
53
        .num_bulk_out =         NUM_DONT_CARE,
54
        .num_ports =            1,
55
        .shutdown =             usb_serial_generic_shutdown,
56
};
57
#endif
58
 
59
int usb_serial_generic_register (int _debug)
60
{
61
        int retval = 0;
62
 
63
        debug = _debug;
64
#ifdef CONFIG_USB_SERIAL_GENERIC
65
        generic_device_ids[0].idVendor = vendor;
66
        generic_device_ids[0].idProduct = product;
67
        generic_device_ids[0].match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT;
68
 
69
        /* register our generic driver with ourselves */
70
        retval = usb_serial_register (&usb_serial_generic_device);
71
#endif
72
        return retval;
73
}
74
 
75
void usb_serial_generic_deregister (void)
76
{
77
#ifdef CONFIG_USB_SERIAL_GENERIC
78
        /* remove our generic driver */
79
        usb_serial_deregister (&usb_serial_generic_device);
80
#endif
81
}
82
 
83
int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp)
84
{
85
        struct usb_serial *serial = port->serial;
86
        int result = 0;
87
 
88
        if (port_paranoia_check (port, __FUNCTION__))
89
                return -ENODEV;
90
 
91
        dbg("%s - port %d", __FUNCTION__, port->number);
92
 
93
        /* force low_latency on so that our tty_push actually forces the data through,
94
           otherwise it is scheduled, and with high data rates (like with OHCI) data
95
           can get lost. */
96
        if (port->tty)
97
                port->tty->low_latency = 1;
98
 
99
        /* if we have a bulk interrupt, start reading from it */
100
        if (serial->num_bulk_in) {
101
                /* Start reading from the device */
102
                usb_fill_bulk_urb (port->read_urb, serial->dev,
103
                                   usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
104
                                   port->read_urb->transfer_buffer,
105
                                   port->read_urb->transfer_buffer_length,
106
                                   ((serial->type->read_bulk_callback) ?
107
                                     serial->type->read_bulk_callback :
108
                                     usb_serial_generic_read_bulk_callback),
109
                                   port);
110
                result = usb_submit_urb(port->read_urb, GFP_KERNEL);
111
                if (result)
112
                        dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result);
113
        }
114
 
115
        return result;
116
}
117
 
118
static void generic_cleanup (struct usb_serial_port *port)
119
{
120
        struct usb_serial *serial = port->serial;
121
 
122
        dbg("%s - port %d", __FUNCTION__, port->number);
123
 
124
        if (serial->dev) {
125
                /* shutdown any bulk reads that might be going on */
126
                if (serial->num_bulk_out)
127
                        usb_unlink_urb (port->write_urb);
128
                if (serial->num_bulk_in)
129
                        usb_unlink_urb (port->read_urb);
130
        }
131
}
132
 
133
void usb_serial_generic_close (struct usb_serial_port *port, struct file * filp)
134
{
135
        dbg("%s - port %d", __FUNCTION__, port->number);
136
        generic_cleanup (port);
137
}
138
 
139
int usb_serial_generic_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count)
140
{
141
        struct usb_serial *serial = port->serial;
142
        int result;
143
 
144
        dbg("%s - port %d", __FUNCTION__, port->number);
145
 
146
        if (count == 0) {
147
                dbg("%s - write request of 0 bytes", __FUNCTION__);
148
                return (0);
149
        }
150
 
151
        /* only do something if we have a bulk out endpoint */
152
        if (serial->num_bulk_out) {
153
                if (port->write_urb->status == -EINPROGRESS) {
154
                        dbg("%s - already writing", __FUNCTION__);
155
                        return (0);
156
                }
157
 
158
                count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
159
 
160
                if (from_user) {
161
                        if (copy_from_user(port->write_urb->transfer_buffer, buf, count))
162
                                return -EFAULT;
163
                }
164
                else {
165
                        memcpy (port->write_urb->transfer_buffer, buf, count);
166
                }
167
 
168
                usb_serial_debug_data (__FILE__, __FUNCTION__, count, port->write_urb->transfer_buffer);
169
 
170
                /* set up our urb */
171
                usb_fill_bulk_urb (port->write_urb, serial->dev,
172
                                   usb_sndbulkpipe (serial->dev,
173
                                                    port->bulk_out_endpointAddress),
174
                                   port->write_urb->transfer_buffer, count,
175
                                   ((serial->type->write_bulk_callback) ?
176
                                     serial->type->write_bulk_callback :
177
                                     usb_serial_generic_write_bulk_callback), port);
178
 
179
                /* send the data out the bulk port */
180
                result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
181
                if (result)
182
                        dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result);
183
                else
184
                        result = count;
185
 
186
                return result;
187
        }
188
 
189
        /* no bulk out, so return 0 bytes written */
190
        return (0);
191
}
192
 
193
int usb_serial_generic_write_room (struct usb_serial_port *port)
194
{
195
        struct usb_serial *serial = port->serial;
196
        int room = 0;
197
 
198
        dbg("%s - port %d", __FUNCTION__, port->number);
199
 
200
        if (serial->num_bulk_out) {
201
                if (port->write_urb->status != -EINPROGRESS)
202
                        room = port->bulk_out_size;
203
        }
204
 
205
        dbg("%s - returns %d", __FUNCTION__, room);
206
        return (room);
207
}
208
 
209
int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port)
210
{
211
        struct usb_serial *serial = port->serial;
212
        int chars = 0;
213
 
214
        dbg("%s - port %d", __FUNCTION__, port->number);
215
 
216
        if (serial->num_bulk_out) {
217
                if (port->write_urb->status == -EINPROGRESS)
218
                        chars = port->write_urb->transfer_buffer_length;
219
        }
220
 
221
        dbg("%s - returns %d", __FUNCTION__, chars);
222
        return (chars);
223
}
224
 
225
void usb_serial_generic_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
226
{
227
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
228
        struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
229
        struct tty_struct *tty;
230
        unsigned char *data = urb->transfer_buffer;
231
        int i;
232
        int result;
233
 
234
        dbg("%s - port %d", __FUNCTION__, port->number);
235
 
236
        if (!serial) {
237
                dbg("%s - bad serial pointer, exiting", __FUNCTION__);
238
                return;
239
        }
240
 
241
        if (urb->status) {
242
                dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);
243
                return;
244
        }
245
 
246
        usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
247
 
248
        tty = port->tty;
249
        if (tty && urb->actual_length) {
250
                for (i = 0; i < urb->actual_length ; ++i) {
251
                        /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */
252
                        if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
253
                                tty_flip_buffer_push(tty);
254
                        }
255
                        /* this doesn't actually push the data through unless tty->low_latency is set */
256
                        tty_insert_flip_char(tty, data[i], 0);
257
                }
258
                tty_flip_buffer_push(tty);
259
        }
260
 
261
        /* Continue trying to always read  */
262
        usb_fill_bulk_urb (port->read_urb, serial->dev,
263
                           usb_rcvbulkpipe (serial->dev,
264
                                            port->bulk_in_endpointAddress),
265
                           port->read_urb->transfer_buffer,
266
                           port->read_urb->transfer_buffer_length,
267
                           ((serial->type->read_bulk_callback) ?
268
                             serial->type->read_bulk_callback :
269
                             usb_serial_generic_read_bulk_callback), port);
270
        result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
271
        if (result)
272
                dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result);
273
}
274
 
275
void usb_serial_generic_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
276
{
277
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
278
        struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
279
 
280
        dbg("%s - port %d", __FUNCTION__, port->number);
281
 
282
        if (!serial) {
283
                dbg("%s - bad serial pointer, exiting", __FUNCTION__);
284
                return;
285
        }
286
 
287
        if (urb->status) {
288
                dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
289
                return;
290
        }
291
 
292
        usb_serial_port_softint((void *)port);
293
 
294
        schedule_work(&port->work);
295
}
296
 
297
void usb_serial_generic_shutdown (struct usb_serial *serial)
298
{
299
        int i;
300
 
301
        dbg("%s", __FUNCTION__);
302
 
303
        /* stop reads and writes on all ports */
304
        for (i=0; i < serial->num_ports; ++i) {
305
                generic_cleanup(serial->port[i]);
306
        }
307
}
308