OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [char/] [au1000_usbraw.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * BRIEF MODULE DESCRIPTION
3
 *      Au1x00 USB Device-Side Raw Block Driver (function layer)
4
 *
5
 * Copyright 2001-2002 MontaVista Software Inc.
6
 * Author: MontaVista Software, Inc.
7
 *              stevel@mvista.com or source@mvista.com
8
 *
9
 *  This program is free software; you can redistribute  it and/or modify it
10
 *  under  the terms of  the GNU General  Public License as published by the
11
 *  Free Software Foundation;  either version 2 of the  License, or (at your
12
 *  option) any later version.
13
 *
14
 *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
15
 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
16
 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
17
 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
18
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19
 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
20
 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
21
 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
22
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23
 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
 *
25
 *  You should have received a copy of the  GNU General Public License along
26
 *  with this program; if not, write  to the Free Software Foundation, Inc.,
27
 *  675 Mass Ave, Cambridge, MA 02139, USA.
28
 */
29
 
30
#include <linux/config.h>
31
#include <linux/kernel.h>
32
#include <linux/ioport.h>
33
#include <linux/sched.h>
34
#include <linux/signal.h>
35
#include <linux/errno.h>
36
#include <linux/poll.h>
37
#include <linux/init.h>
38
#include <linux/slab.h>
39
#include <linux/fcntl.h>
40
#include <linux/module.h>
41
#include <linux/spinlock.h>
42
#include <linux/list.h>
43
#include <linux/smp_lock.h>
44
#undef DEBUG
45
#include <linux/usb.h>
46
 
47
#include <asm/io.h>
48
#include <asm/uaccess.h>
49
#include <asm/irq.h>
50
#include <asm/au1000.h>
51
#include <asm/au1000_usbdev.h>
52
 
53
#define USBRAW_MAJOR 190 // FIXME: need a legal major
54
#define USBRAW_NAME "usbraw"
55
 
56
#define MAX_NUM_PORTS 2
57
 
58
#define IN_MAX_PACKET_SIZE  64
59
#define OUT_MAX_PACKET_SIZE 64
60
 
61
// FIXME: when Au1x00 endpoints 3 and 5 are fixed, make NUM_PORTS=2
62
#define NUM_PORTS 1
63
#define NUM_EP 2*NUM_PORTS
64
 
65
#define CONFIG_DESC_LEN \
66
 USB_DT_CONFIG_SIZE + USB_DT_INTERFACE_SIZE + NUM_EP*USB_DT_ENDPOINT_SIZE
67
 
68
/* must be power of two */
69
#define READ_BUF_SIZE (1<<12)
70
 
71
struct usb_raw_port {
72
        unsigned char number;
73
        spinlock_t port_lock;
74
 
75
        struct usb_endpoint_descriptor* out_desc;
76
        struct usb_endpoint_descriptor* in_desc;
77
 
78
        int out_ep_addr; /* endpoint address of OUT endpoint */
79
        int in_ep_addr;  /* endpoint address of IN endpoint */
80
 
81
        __u8 read_buf[READ_BUF_SIZE]; // FIXME: allocate with get_free_pages
82
        int read_nextin, read_nextout;
83
        int read_count;
84
 
85
        wait_queue_head_t wait;
86
        struct fasync_struct *fasync;     // asynch notification
87
 
88
        int active;     /* someone has this device open */
89
        int open_count; /* number of times this port has been opened */
90
};
91
 
92
static struct usb_serial {
93
        struct usb_device_descriptor* dev_desc;
94
        struct usb_config_descriptor* config_desc;
95
        struct usb_interface_descriptor* if_desc;
96
        struct usb_string_descriptor * str_desc[6];
97
        void* str_desc_buf;
98
 
99
        usbdev_state_t dev_state;
100
 
101
        struct usb_raw_port port[NUM_PORTS];
102
} usbraw;
103
 
104
static struct usb_device_descriptor dev_desc = {
105
        bLength:USB_DT_DEVICE_SIZE,
106
        bDescriptorType:USB_DT_DEVICE,
107
        bcdUSB:USBDEV_REV,              //usb rev
108
        bDeviceClass:USB_CLASS_PER_INTERFACE,   //class    (none)
109
        bDeviceSubClass:0x00,   //subclass (none)
110
        bDeviceProtocol:0x00,   //protocol (none)
111
        bMaxPacketSize0:USBDEV_EP0_MAX_PACKET_SIZE, //max packet size for ep0
112
        idVendor:0x6d04,        //vendor  id
113
        idProduct:0x0bc0,       //product id
114
        bcdDevice:0x0001,       //BCD rev 0.1
115
        iManufacturer:0x01,     //manufactuer string index
116
        iProduct:0x02,          //product string index
117
        iSerialNumber:0x03,     //serial# string index
118
        bNumConfigurations:0x01 //num configurations
119
};
120
 
121
static struct usb_endpoint_descriptor ep_desc[] = {
122
        {
123
                // Bulk IN for Port 0
124
                bLength:USB_DT_ENDPOINT_SIZE,
125
                bDescriptorType:USB_DT_ENDPOINT,
126
                bEndpointAddress:USB_DIR_IN,
127
                bmAttributes:USB_ENDPOINT_XFER_BULK,
128
                wMaxPacketSize:IN_MAX_PACKET_SIZE,
129
                bInterval:0x00  // ignored for bulk
130
        },
131
        {
132
                // Bulk OUT for Port 0
133
                bLength:USB_DT_ENDPOINT_SIZE,
134
                bDescriptorType:USB_DT_ENDPOINT,
135
                bEndpointAddress:USB_DIR_OUT,
136
                bmAttributes:USB_ENDPOINT_XFER_BULK,
137
                wMaxPacketSize:OUT_MAX_PACKET_SIZE,
138
                bInterval:0x00  // ignored for bulk
139
        },
140
        {
141
                // Bulk IN for Port 1
142
                bLength:USB_DT_ENDPOINT_SIZE,
143
                bDescriptorType:USB_DT_ENDPOINT,
144
                bEndpointAddress:USB_DIR_IN,
145
                bmAttributes:USB_ENDPOINT_XFER_BULK,
146
                wMaxPacketSize:IN_MAX_PACKET_SIZE,
147
                bInterval:0x00  // ignored for bulk
148
        },
149
        {
150
                // Bulk OUT for Port 1
151
                bLength:USB_DT_ENDPOINT_SIZE,
152
                bDescriptorType:USB_DT_ENDPOINT,
153
                bEndpointAddress:USB_DIR_OUT,
154
                bmAttributes:USB_ENDPOINT_XFER_BULK,
155
                wMaxPacketSize:OUT_MAX_PACKET_SIZE,
156
                bInterval:0x00  // ignored for bulk
157
        }
158
};
159
 
160
static struct usb_interface_descriptor if_desc = {
161
        bLength:USB_DT_INTERFACE_SIZE,
162
        bDescriptorType:USB_DT_INTERFACE,
163
        bInterfaceNumber:0x00,
164
        bAlternateSetting:0x00,
165
        bNumEndpoints:NUM_EP,
166
        bInterfaceClass:0xff,
167
        bInterfaceSubClass:0xab,
168
        bInterfaceProtocol:0x00,
169
        iInterface:0x05
170
};
171
 
172
static struct usb_config_descriptor config_desc = {
173
        bLength:USB_DT_CONFIG_SIZE,
174
        bDescriptorType:USB_DT_CONFIG,
175
        wTotalLength:CONFIG_DESC_LEN,
176
        bNumInterfaces:0x01,
177
        bConfigurationValue:0x01,
178
        iConfiguration:0x04,    // configuration string
179
        bmAttributes:0xc0,      // self-powered
180
        MaxPower:20             // 40 mA
181
};
182
 
183
// String[0] is a list of Language IDs supported by this device
184
static struct usb_string_descriptor string_desc0 = {
185
        bLength:4,
186
        bDescriptorType:USB_DT_STRING,
187
        wData:{0x0409} // English, US
188
};
189
 
190
// These strings will be converted to Unicode in string_desc[]
191
static char *strings[5] = {
192
        "Alchemy Semiconductor",  // iManufacturer
193
        "USB Raw Block Device",   // iProduct
194
        "0.1",                    // iSerialNumber
195
        "USB Raw Config",         // iConfiguration
196
        "USB Raw Interface"       // iInterface
197
};
198
 
199
 
200
static void
201
receive_callback(struct usb_raw_port *port)
202
{
203
        int i, pkt_size;
204
        usbdev_pkt_t* pkt;
205
 
206
        if ((pkt_size = usbdev_receive_packet(port->out_ep_addr,
207
                                              &pkt)) <= 0) {
208
                dbg(__FUNCTION__ ": usbdev_receive_packet returns %d",
209
                    pkt_size);
210
                return;
211
        }
212
 
213
        dbg(__FUNCTION__ ": ep%d, size=%d", port->out_ep_addr, pkt_size);
214
 
215
        spin_lock(&port->port_lock);
216
        for (i=0; i < pkt_size; i++) {
217
                port->read_buf[port->read_nextin++] = pkt->payload[i];
218
                port->read_nextin &= (READ_BUF_SIZE - 1);
219
                if (++port->read_count == READ_BUF_SIZE)
220
                        break;
221
        }
222
        spin_unlock(&port->port_lock);
223
 
224
        /* free the packet */
225
        kfree(pkt);
226
 
227
        // async notify
228
        if (port->fasync)
229
                kill_fasync(&port->fasync, SIGIO, POLL_IN);
230
        // wake up any read call
231
        if (waitqueue_active(&port->wait))
232
                wake_up_interruptible(&port->wait);
233
}
234
 
235
static void
236
transmit_callback(struct usb_raw_port *port, usbdev_pkt_t* pkt)
237
{
238
        dbg(__FUNCTION__ ": ep%d", port->in_ep_addr);
239
        /* just free the returned packet */
240
        kfree(pkt);
241
}
242
 
243
 
244
static void
245
usbraw_callback(usbdev_cb_type_t cb_type, unsigned long arg, void* data)
246
{
247
        usbdev_pkt_t* pkt;
248
        int i;
249
 
250
        switch (cb_type) {
251
        case CB_NEW_STATE:
252
                usbraw.dev_state = (usbdev_state_t)arg;
253
                break;
254
        case CB_PKT_COMPLETE:
255
                pkt = (usbdev_pkt_t*)arg;
256
                for (i=0; i<NUM_PORTS; i++) {
257
                        struct usb_raw_port *port = &usbraw.port[i];
258
                        if (pkt->ep_addr == port->in_ep_addr) {
259
                                transmit_callback(port, pkt);
260
                                break;
261
                        } else if (pkt->ep_addr == port->out_ep_addr) {
262
                                receive_callback(port);
263
                                break;
264
                        }
265
                }
266
                break;
267
        }
268
}
269
 
270
/*****************************************************************************
271
 * Here begins the driver interface functions
272
 *****************************************************************************/
273
 
274
static unsigned int usbraw_poll(struct file * filp, poll_table * wait)
275
{
276
        struct usb_raw_port *port = (struct usb_raw_port *)filp->private_data;
277
        unsigned long flags;
278
        int count;
279
 
280
        poll_wait(filp, &port->wait, wait);
281
 
282
        spin_lock_irqsave(&port->port_lock, flags);
283
        count = port->read_count;
284
        spin_unlock_irqrestore(&port->port_lock, flags);
285
 
286
        if (count > 0) {
287
                dbg(__FUNCTION__ ": count=%d", count);
288
                return POLLIN | POLLRDNORM;
289
        }
290
 
291
        return 0;
292
}
293
 
294
static int usbraw_fasync(int fd, struct file *filp, int mode)
295
{
296
        struct usb_raw_port *port = (struct usb_raw_port *)filp->private_data;
297
        return fasync_helper(fd, filp, mode, &port->fasync);
298
}
299
 
300
static int usbraw_open(struct inode * inode, struct file *filp)
301
{
302
        int portNumber;
303
        struct usb_raw_port *port;
304
        unsigned long flags;
305
 
306
        /*
307
         * the device-layer must be in the configured state before the
308
         * function layer can operate.
309
         */
310
        if (usbraw.dev_state != CONFIGURED)
311
                return -ENODEV;
312
 
313
        MOD_INC_USE_COUNT;
314
 
315
        /* set up our port structure making the tty driver remember
316
           our port object, and us it */
317
        portNumber = MINOR(inode->i_rdev);
318
        port = &usbraw.port[portNumber];
319
        filp->private_data = port;
320
 
321
        dbg(__FUNCTION__ ": port %d", port->number);
322
 
323
        spin_lock_irqsave(&port->port_lock, flags);
324
 
325
        ++port->open_count;
326
 
327
        if (!port->active) {
328
                port->active = 1;
329
        }
330
 
331
        /* flush read buffer */
332
        port->read_nextin = port->read_nextout = port->read_count = 0;
333
 
334
        spin_unlock_irqrestore(&port->port_lock, flags);
335
 
336
        return 0;
337
}
338
 
339
static int usbraw_release(struct inode * inode, struct file * filp)
340
{
341
        struct usb_raw_port *port = (struct usb_raw_port *)filp->private_data;
342
        unsigned long flags;
343
 
344
        dbg(__FUNCTION__ ": port %d", port->number);
345
 
346
        if (!port->active) {
347
                err(__FUNCTION__ ": port not opened");
348
                return -ENODEV;
349
        }
350
 
351
        usbraw_fasync(-1, filp, 0);
352
 
353
        spin_lock_irqsave(&port->port_lock, flags);
354
 
355
        --port->open_count;
356
 
357
        if (port->open_count <= 0) {
358
                port->active = 0;
359
                port->open_count = 0;
360
        }
361
 
362
        spin_unlock_irqrestore(&port->port_lock, flags);
363
        MOD_DEC_USE_COUNT;
364
        return 0;
365
}
366
 
367
 
368
static ssize_t usbraw_read(struct file * filp, char * buf,
369
                           size_t count, loff_t * l)
370
{
371
        struct usb_raw_port *port = (struct usb_raw_port *)filp->private_data;
372
        unsigned long flags;
373
        int i, cnt;
374
 
375
        /*
376
         * the device-layer must be in the configured state before the
377
         * function layer can operate.
378
         */
379
        if (usbraw.dev_state != CONFIGURED)
380
                return -ENODEV;
381
 
382
        do {
383
                spin_lock_irqsave(&port->port_lock, flags);
384
                cnt = port->read_count;
385
                spin_unlock_irqrestore(&port->port_lock, flags);
386
                if (cnt == 0) {
387
                        if (filp->f_flags & O_NONBLOCK)
388
                                return -EAGAIN;
389
                        interruptible_sleep_on(&port->wait);
390
                        if (signal_pending(current))
391
                                return -ERESTARTSYS;
392
                }
393
        } while (cnt == 0);
394
 
395
        count = (count > cnt) ? cnt : count;
396
 
397
        for (i=0; i<count; i++) {
398
                put_user(port->read_buf[port->read_nextout++], &buf[i]);
399
                port->read_nextout &= (READ_BUF_SIZE - 1);
400
                spin_lock_irqsave(&port->port_lock, flags);
401
                port->read_count--;
402
                spin_unlock_irqrestore(&port->port_lock, flags);
403
                if (port->read_count == 0)
404
                        break;
405
        }
406
 
407
        return i+1;
408
}
409
 
410
static ssize_t usbraw_write(struct file * filp, const char * buf,
411
                            size_t count, loff_t *ppos)
412
{
413
        struct usb_raw_port *port = (struct usb_raw_port *)filp->private_data;
414
        usbdev_pkt_t* pkt;
415
        int ret, max_pkt_sz;
416
 
417
        /*
418
         * the device-layer must be in the configured state before the
419
         * function layer can operate.
420
         */
421
        if (usbraw.dev_state != CONFIGURED)
422
                return -ENODEV;
423
 
424
        if (!port->active) {
425
                err(__FUNCTION__ ": port not opened");
426
                return -EINVAL;
427
        }
428
 
429
        if (count == 0) {
430
                dbg(__FUNCTION__ ": write request of 0 bytes");
431
                return (0);
432
        }
433
 
434
        max_pkt_sz = port->in_desc->wMaxPacketSize;
435
        count = (count > max_pkt_sz) ? max_pkt_sz : count;
436
 
437
        if ((ret = usbdev_alloc_packet(port->in_ep_addr, count, &pkt)) < 0)
438
                return ret;
439
 
440
        copy_from_user(pkt->payload, buf, count);
441
 
442
        return usbdev_send_packet(port->in_ep_addr, pkt);
443
}
444
 
445
static int usbraw_ioctl(struct inode *inode, struct file *filp,
446
                        unsigned int cmd, unsigned long arg)
447
{
448
        struct usb_raw_port *port = (struct usb_raw_port *)filp->private_data;
449
 
450
        if (!port->active) {
451
                err(__FUNCTION__ ": port not open");
452
                return -ENODEV;
453
        }
454
        // FIXME: need any IOCTLs?
455
 
456
        return -ENOIOCTLCMD;
457
}
458
 
459
 
460
static struct file_operations usbraw_fops = {
461
        owner:          THIS_MODULE,
462
        write:          usbraw_write,
463
        read:           usbraw_read,
464
        poll:           usbraw_poll,
465
        ioctl:          usbraw_ioctl,
466
        fasync:         usbraw_fasync,
467
        open:           usbraw_open,
468
        release:        usbraw_release,
469
};
470
 
471
void usbfn_raw_exit(void)
472
{
473
        /* kill the device layer */
474
        usbdev_exit();
475
 
476
        unregister_chrdev(USBRAW_MAJOR, USBRAW_NAME);
477
 
478
        if (usbraw.str_desc_buf)
479
                kfree(usbraw.str_desc_buf);
480
}
481
 
482
 
483
int usbfn_raw_init(void)
484
{
485
        int ret = 0, i, str_desc_len;
486
 
487
        /* register our character device */
488
        if ((ret = register_chrdev(USBRAW_MAJOR, USBRAW_NAME,
489
                                   &usbraw_fops)) < 0) {
490
                err("can't get major number");
491
                return ret;
492
        }
493
        info("registered");
494
 
495
        /*
496
         * initialize pointers to descriptors
497
         */
498
        usbraw.dev_desc = &dev_desc;
499
        usbraw.config_desc = &config_desc;
500
        usbraw.if_desc = &if_desc;
501
 
502
        /*
503
         * initialize the string descriptors
504
         */
505
 
506
        /* alloc buffer big enough for all string descriptors */
507
        str_desc_len = string_desc0.bLength;
508
        for (i = 0; i < 5; i++)
509
                str_desc_len += 2 + 2 * strlen(strings[i]);
510
        usbraw.str_desc_buf = (void *) kmalloc(str_desc_len, GFP_KERNEL);
511
        if (!usbraw.str_desc_buf) {
512
                err(__FUNCTION__ ": failed to alloc string descriptors");
513
                ret = -ENOMEM;
514
                goto out;
515
        }
516
 
517
        usbraw.str_desc[0] =
518
                (struct usb_string_descriptor *)usbraw.str_desc_buf;
519
        memcpy(usbraw.str_desc[0], &string_desc0, string_desc0.bLength);
520
        usbraw.str_desc[1] = (struct usb_string_descriptor *)
521
                (usbraw.str_desc_buf + string_desc0.bLength);
522
        for (i = 1; i < 6; i++) {
523
                struct usb_string_descriptor *desc = usbraw.str_desc[i];
524
                char *str = strings[i - 1];
525
                int j, str_len = strlen(str);
526
 
527
                desc->bLength = 2 + 2 * str_len;
528
                desc->bDescriptorType = USB_DT_STRING;
529
                for (j = 0; j < str_len; j++) {
530
                        desc->wData[j] = (u16) str[j];
531
                }
532
                if (i < 5)
533
                        usbraw.str_desc[i + 1] =
534
                                (struct usb_string_descriptor *)
535
                                ((u8 *) desc + desc->bLength);
536
        }
537
 
538
        /*
539
         * start the device layer. The device layer assigns us
540
         * our endpoint addresses
541
         */
542
        if ((ret = usbdev_init(&dev_desc, &config_desc, &if_desc, ep_desc,
543
                               usbraw.str_desc, usbraw_callback, NULL))) {
544
                err(__FUNCTION__ ": device-layer init failed");
545
                goto out;
546
        }
547
 
548
        /* initialize the devfs nodes for this device and let the user
549
           know what ports we are bound to */
550
        for (i = 0; i < NUM_PORTS; ++i) {
551
                struct usb_raw_port *port = &usbraw.port[i];
552
 
553
                port->number = i;
554
                port->in_desc = &ep_desc[NUM_PORTS*i];
555
                port->out_desc = &ep_desc[NUM_PORTS*i + 1];
556
                port->in_ep_addr = port->in_desc->bEndpointAddress & 0x0f;
557
                port->out_ep_addr = port->out_desc->bEndpointAddress & 0x0f;
558
                init_waitqueue_head(&port->wait);
559
                spin_lock_init(&port->port_lock);
560
        }
561
 
562
 out:
563
        if (ret)
564
                usbfn_raw_exit();
565
        return ret;
566
}
567
 
568
 
569
/* Module information */
570
MODULE_AUTHOR("Steve Longerbeam, stevel@mvista.com, www.mvista.com");
571
MODULE_DESCRIPTION("Au1x00 USB Device-Side Raw Block Driver");
572
MODULE_LICENSE("GPL");
573
 
574
module_init(usbfn_raw_init);
575
module_exit(usbfn_raw_exit);

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.