1 /*
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
receive_callback(struct usb_raw_port * port)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
transmit_callback(struct usb_raw_port * port,usbdev_pkt_t * pkt)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
usbraw_callback(usbdev_cb_type_t cb_type,unsigned long arg,void * data)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
usbraw_poll(struct file * filp,poll_table * wait)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
usbraw_fasync(int fd,struct file * filp,int mode)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
usbraw_open(struct inode * inode,struct file * filp)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
usbraw_release(struct inode * inode,struct file * filp)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
usbraw_read(struct file * filp,char * buf,size_t count,loff_t * l)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
usbraw_write(struct file * filp,const char * buf,size_t count,loff_t * ppos)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
usbraw_ioctl(struct inode * inode,struct file * filp,unsigned int cmd,unsigned long arg)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
usbfn_raw_exit(void)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
usbfn_raw_init(void)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);
576