1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29#define DRIVER_VERSION "v0.8"
30#define DATE "April 2002"
31#define DRIVER_AUTHOR \
32 "Stephane Dalton <sdalton@videotron.ca> " \
33 "and Stéphane Doyon <s.doyon@videotron.ca>"
34#define DRIVER_DESC "Tieman Voyager braille display USB driver for Linux 2.4"
35#define DRIVER_SHORTDESC "Voyager"
36
37#define BANNER \
38 KERN_INFO DRIVER_SHORTDESC " " DRIVER_VERSION " (" DATE ")\n" \
39 KERN_INFO " by " DRIVER_AUTHOR "\n"
40
41static const char longbanner[] = {
42 DRIVER_DESC ", " DRIVER_VERSION " (" DATE "), by " DRIVER_AUTHOR
43};
44
45#include <linux/module.h>
46#include <linux/usb.h>
47#include <linux/init.h>
48#include <linux/slab.h>
49#include <linux/sched.h>
50#include <asm/uaccess.h>
51#include <asm/atomic.h>
52#include <linux/poll.h>
53#include <linux/devfs_fs_kernel.h>
54#include <linux/brlvger.h>
55
56MODULE_AUTHOR( DRIVER_AUTHOR );
57MODULE_DESCRIPTION( DRIVER_DESC );
58MODULE_LICENSE("GPL");
59
60
61
62static int debug = 1;
63MODULE_PARM(debug, "i");
64MODULE_PARM_DESC(debug, "Debug level, 0-3");
65
66static int write_repeats = 2;
67MODULE_PARM(write_repeats, "i");
68MODULE_PARM_DESC(write_repeats, "Hack: repetitions for command to "
69 "display braille pattern");
70
71
72
73static int stall_tries = 3;
74MODULE_PARM(stall_tries, "i");
75MODULE_PARM_DESC(stall_tries, "Hack: retransmits of stalled USB "
76 "control messages");
77
78
79#define BRLVGER_RAW_VOLTAGE 89
80
81
82static int raw_voltage = BRLVGER_RAW_VOLTAGE;
83MODULE_PARM(raw_voltage, "i");
84MODULE_PARM_DESC(raw_voltage, "Parameter for the call to SET_DISPLAY_VOLTAGE");
85
86
87
88#define MAX_BRLVGER_CELLS 72
89#define MAX_INTERRUPT_DATA 8
90
91#define BRLVGER_READ_REQ 0xC2
92#define BRLVGER_WRITE_REQ 0x42
93
94#define BRLVGER_SET_DISPLAY_ON 0
95#define BRLVGER_SET_DISPLAY_VOLTAGE 1
96#define BRLVGER_GET_SERIAL 3
97#define BRLVGER_GET_HWVERSION 4
98#define BRLVGER_GET_FWVERSION 5
99#define BRLVGER_GET_LENGTH 6
100#define BRLVGER_SEND_BRAILLE 7
101#define BRLVGER_BEEP 9
102#if 0
103#define BRLVGER_GET_DISPLAY_VOLTAGE 2
104#define BRLVGER_GET_CURRENT 8
105#endif
106
107
108static void *brlvger_probe (struct usb_device *dev, unsigned ifnum,
109 const struct usb_device_id *id);
110static void brlvger_disconnect(struct usb_device *dev, void *ptr);
111static int brlvger_open(struct inode *inode, struct file *file);
112static int brlvger_release(struct inode *inode, struct file *file);
113static ssize_t brlvger_write(struct file *file, const char *buffer,
114 size_t count, loff_t *pos);
115static ssize_t brlvger_read(struct file *file, char *buffer,
116 size_t count, loff_t *unused_pos);
117static int brlvger_ioctl(struct inode *inode, struct file *file,
118 unsigned cmd, unsigned long arg);
119static unsigned brlvger_poll(struct file *file, poll_table *wait);
120static loff_t brlvger_llseek(struct file * file, loff_t offset, int orig);
121static void intr_callback(struct urb *urb);
122struct brlvger_priv;
123static int brlvger_get_hw_version(struct brlvger_priv *priv,
124 unsigned char *verbuf);
125static int brlvger_get_fw_version(struct brlvger_priv *priv,
126 unsigned char *buf);
127static int brlvger_get_serial(struct brlvger_priv *priv,
128 unsigned char *buf);
129static int brlvger_get_display_length(struct brlvger_priv *priv);
130static int brlvger_set_display_on_off(struct brlvger_priv *priv, __u16 on);
131static int brlvger_beep(struct brlvger_priv *priv, __u16 duration);
132static int brlvger_set_display_voltage(struct brlvger_priv *priv,
133 __u16 voltage);
134static int mycontrolmsg(const char *funcname,
135 struct brlvger_priv *priv, unsigned pipe_dir,
136 __u8 request, __u8 requesttype, __u16 value,
137 __u16 index, void *data, __u16 size);
138
139#define controlmsg(priv,pipe_dir,a,b,c,d,e,f) \
140 mycontrolmsg(__FUNCTION__, priv, pipe_dir, \
141 a,b,c,d,e,f)
142#define sndcontrolmsg(priv,a,b,c,d,e,f) \
143 controlmsg(priv, 0, a,b,c,d,e,f)
144#define rcvcontrolmsg(priv,a,b,c,d,e,f) \
145 controlmsg(priv, USB_DIR_IN, a,b,c,d,e,f)
146
147extern devfs_handle_t usb_devfs_handle;
148
149
150
151
152
153
154#define MAX_INTERRUPT_BUFFER 10
155
156
157struct brlvger_priv {
158 struct usb_device *dev;
159 struct usb_endpoint_descriptor *in_interrupt;
160 struct urb *intr_urb;
161 devfs_handle_t devfs;
162
163 int subminor;
164
165 unsigned char hwver[BRLVGER_HWVER_SIZE];
166 unsigned char fwver[BRLVGER_FWVER_SIZE];
167 unsigned char serialnum[BRLVGER_SERIAL_SIZE];
168
169 int llength;
170 int plength;
171
172 __u8 obuf[MAX_BRLVGER_CELLS];
173 __u8 intr_buff[MAX_INTERRUPT_DATA];
174 __u8 event_queue[MAX_INTERRUPT_BUFFER][MAX_INTERRUPT_DATA];
175 atomic_t intr_idx, read_idx;
176 spinlock_t intr_idx_lock;
177 wait_queue_head_t read_wait;
178
179 int opened;
180 struct semaphore open_sem;
181 struct semaphore dev_sem;
182};
183
184
185
186
187static struct brlvger_priv *display_table[ MAX_NR_BRLVGER_DEVS ];
188
189
190static DECLARE_MUTEX(disconnect_sem);
191
192
193static DECLARE_WAIT_QUEUE_HEAD(open_wait);
194
195
196#ifdef dbg
197#undef dbg
198#endif
199#ifdef info
200#undef info
201#endif
202#ifdef err
203#undef err
204#endif
205#define info(args...) \
206 ({ printk(KERN_INFO "Voyager: " args); \
207 printk("\n"); })
208#define err(args...) \
209 ({ printk(KERN_ERR "Voyager: " args); \
210 printk("\n"); })
211#define dbgprint(fmt, args...) \
212 ({ printk(KERN_DEBUG "Voyager: %s: " fmt, __FUNCTION__ , ##args); \
213 printk("\n"); })
214#define dbg(args...) \
215 ({ if(debug >= 1) dbgprint(args); })
216#define dbg2(args...) \
217 ({ if(debug >= 2) dbgprint(args); })
218#define dbg3(args...) \
219 ({ if(debug >= 3) dbgprint(args); })
220
221
222
223
224
225static struct usb_device_id brlvger_ids [] = {
226 { USB_DEVICE(0x0798, 0x0001) },
227 { }
228};
229MODULE_DEVICE_TABLE (usb, brlvger_ids);
230
231static struct file_operations brlvger_fops =
232{
233 owner: THIS_MODULE,
234 llseek: brlvger_llseek,
235 read: brlvger_read,
236 write: brlvger_write,
237 ioctl: brlvger_ioctl,
238 open: brlvger_open,
239 release: brlvger_release,
240 poll: brlvger_poll,
241};
242
243static struct usb_driver brlvger_driver =
244{
245 name: "brlvger",
246 probe: brlvger_probe,
247 disconnect: brlvger_disconnect,
248 fops: &brlvger_fops,
249 minor: BRLVGER_MINOR,
250 id_table: brlvger_ids,
251};
252
253static int
254__init brlvger_init (void)
255{
256 printk(BANNER);
257
258 if(stall_tries < 1 || write_repeats < 1)
259 return -EINVAL;
260
261 memset(display_table, 0, sizeof(display_table));
262
263 if (usb_register(&brlvger_driver)) {
264 err("USB registration failed");
265 return -ENOSYS;
266 }
267
268 return 0;
269}
270
271static void
272__exit brlvger_cleanup (void)
273{
274 usb_deregister (&brlvger_driver);
275 dbg("Driver unregistered");
276}
277
278module_init (brlvger_init);
279module_exit (brlvger_cleanup);
280
281
282
283
284
285static void *
286brlvger_probe (struct usb_device *dev, unsigned ifnum,
287 const struct usb_device_id *id)
288{
289 struct brlvger_priv *priv = NULL;
290 int i;
291 struct usb_endpoint_descriptor *endpoint;
292 struct usb_interface_descriptor *actifsettings;
293
294
295 static DECLARE_MUTEX(reserve_sem);
296 char devfs_name[16];
297
298 actifsettings = dev->actconfig->interface->altsetting;
299
300 if( dev->descriptor.bNumConfigurations != 1
301 || dev->config->bNumInterfaces != 1
302 || actifsettings->bNumEndpoints != 1 ) {
303 err ("Bogus braille display config info");
304 return NULL;
305 }
306
307 endpoint = actifsettings->endpoint;
308 if (!(endpoint->bEndpointAddress & 0x80) ||
309 ((endpoint->bmAttributes & 3) != 0x03)) {
310 err ("Bogus braille display config info, wrong endpoints");
311 return NULL;
312 }
313
314 down(&reserve_sem);
315
316 for( i = 0; i < MAX_NR_BRLVGER_DEVS; i++ )
317 if( display_table[i] == NULL )
318 break;
319
320 if( i == MAX_NR_BRLVGER_DEVS ) {
321 err( "This driver cannot handle more than %d "
322 "braille displays", MAX_NR_BRLVGER_DEVS);
323 goto error;
324 }
325
326 if( !(priv = kmalloc (sizeof *priv, GFP_KERNEL)) ){
327 err("No more memory");
328 goto error;
329 }
330
331 memset(priv, 0, sizeof(*priv));
332 atomic_set(&priv->intr_idx, 0);
333 atomic_set(&priv->read_idx, MAX_INTERRUPT_BUFFER-1);
334 spin_lock_init(&priv->intr_idx_lock);
335 init_waitqueue_head(&priv->read_wait);
336
337 init_MUTEX(&priv->open_sem);
338 init_MUTEX(&priv->dev_sem);
339
340 priv->subminor = i;
341
342
343 priv->in_interrupt = endpoint;
344
345 priv->dev = dev;
346
347 if(brlvger_get_hw_version(priv, priv->hwver) <0) {
348 err("Unable to get hardware version");
349 goto error;
350 }
351 dbg("Hw ver %d.%d", priv->hwver[0], priv->hwver[1]);
352 if(brlvger_get_fw_version(priv, priv->fwver) <0) {
353 err("Unable to get firmware version");
354 goto error;
355 }
356 dbg("Fw ver: %s", priv->fwver);
357
358 if(brlvger_get_serial(priv, priv->serialnum) <0) {
359 err("Unable to get serial number");
360 goto error;
361 }
362 dbg("Serial number: %s", priv->serialnum);
363
364 if( (priv->llength = brlvger_get_display_length(priv)) <0 ){
365 err("Unable to get display length");
366 goto error;
367 }
368 switch(priv->llength) {
369 case 48:
370 priv->plength = 44;
371 break;
372 case 72:
373 priv->plength = 70;
374 break;
375 default:
376 err("Unsupported display length: %d", priv->llength);
377 goto error;
378 };
379 dbg("Display length: %d", priv->plength);
380
381 sprintf(devfs_name, "brlvger%d", priv->subminor);
382 priv->devfs = devfs_register(usb_devfs_handle, devfs_name,
383 DEVFS_FL_DEFAULT, USB_MAJOR,
384 BRLVGER_MINOR+priv->subminor,
385 S_IFCHR |S_IRUSR|S_IWUSR |S_IRGRP|S_IWGRP,
386 &brlvger_fops, NULL);
387 if (!priv->devfs) {
388#ifdef CONFIG_DEVFS_FS
389 err("devfs node registration failed");
390#endif
391 }
392
393 display_table[i] = priv;
394
395 info( "Braille display %d is device major %d minor %d",
396 i, USB_MAJOR, BRLVGER_MINOR + i);
397
398
399 wake_up_interruptible(&open_wait);
400
401 goto out;
402
403 error:
404 if(priv) {
405 kfree( priv );
406 priv = NULL;
407 }
408
409 out:
410 up(&reserve_sem);
411 return priv;
412}
413
414static void
415brlvger_disconnect(struct usb_device *dev, void *ptr)
416{
417 struct brlvger_priv *priv = (struct brlvger_priv *)ptr;
418 int r;
419
420 if(priv){
421 info("Display %d disconnecting", priv->subminor);
422
423 devfs_unregister(priv->devfs);
424
425 down(&disconnect_sem);
426 display_table[priv->subminor] = NULL;
427 up(&disconnect_sem);
428
429 down(&priv->open_sem);
430 down(&priv->dev_sem);
431 if(priv->opened) {
432
433 if((r = usb_unlink_urb(priv->intr_urb)) <0)
434 err("usb_unlink_urb returns %d", r);
435 usb_free_urb(priv->intr_urb);
436
437
438 priv->dev = NULL;
439
440
441 wake_up_interruptible(&priv->read_wait);
442 up(&priv->dev_sem);
443 up(&priv->open_sem);
444 }else
445
446 kfree(priv);
447 }
448}
449
450
451
452
453
454static int
455brlvger_open(struct inode *inode, struct file *file)
456{
457 int devnum = MINOR (inode->i_rdev);
458 struct brlvger_priv *priv;
459 int n, ret;
460
461 if (devnum < BRLVGER_MINOR
462 || devnum >= (BRLVGER_MINOR + MAX_NR_BRLVGER_DEVS))
463 return -ENXIO;
464
465 n = devnum - BRLVGER_MINOR;
466
467 MOD_INC_USE_COUNT;
468
469 do {
470 down(&disconnect_sem);
471 priv = display_table[n];
472
473 if(!priv) {
474 up(&disconnect_sem);
475 if (file->f_flags & O_NONBLOCK) {
476 dbg3("Failing non-blocking open: "
477 "device %d not connected", n);
478 MOD_DEC_USE_COUNT;
479 return -EAGAIN;
480 }
481
482
483
484 dbg2("Waiting for device %d to be connected", n);
485 ret = wait_event_interruptible(open_wait,
486 display_table[n]
487 != NULL);
488 if(ret) {
489 dbg2("Interrupted wait for device %d", n);
490 MOD_DEC_USE_COUNT;
491 return ret;
492 }
493 }
494 } while(!priv);
495
496
497 if(down_interruptible(&priv->open_sem))
498 return -ERESTARTSYS;
499 up(&disconnect_sem);
500
501
502 ret = -EBUSY;
503 if(priv->opened)
504 goto error;
505
506 dbg("Opening display %d", priv->subminor);
507
508
509 priv->intr_urb = usb_alloc_urb(0);
510 if(!priv->intr_urb) {
511 err("Unable to allocate URB");
512 goto error;
513 }
514 FILL_INT_URB( priv->intr_urb, priv->dev,
515 usb_rcvintpipe(priv->dev,
516 priv->in_interrupt->bEndpointAddress),
517 priv->intr_buff, sizeof(priv->intr_buff),
518 intr_callback, priv, priv->in_interrupt->bInterval);
519 if((ret = usb_submit_urb(priv->intr_urb)) <0){
520 err("Error %d while submitting URB", ret);
521 goto error;
522 }
523
524
525 if(brlvger_set_display_voltage(priv, raw_voltage) <0) {
526 err("Unable to set voltage");
527 goto error;
528 }
529
530
531 if((ret = brlvger_set_display_on_off(priv, 1)) <0) {
532 err("Error %d while turning display on", ret);
533 goto error;
534 }
535
536
537 priv->opened = 1;
538
539 file->private_data = priv;
540
541 ret = 0;
542 goto out;
543
544 error:
545 MOD_DEC_USE_COUNT;
546 out:
547 up(&priv->open_sem);
548 return ret;
549}
550
551static int
552brlvger_release(struct inode *inode, struct file *file)
553{
554 struct brlvger_priv *priv = file->private_data;
555 int r;
556
557
558 brlvger_set_display_on_off(priv, 0);
559
560
561 down(&priv->open_sem);
562
563 if(!priv->dev) {
564 dbg("Releasing disconnected device %d", priv->subminor);
565
566 kfree(priv);
567 }else{
568 dbg("Closing display %d", priv->subminor);
569
570 if((r = usb_unlink_urb(priv->intr_urb)) <0)
571 err("usb_unlink_urb returns %d", r);
572 usb_free_urb(priv->intr_urb);
573 priv->opened = 0;
574 up(&priv->open_sem);
575 }
576
577 MOD_DEC_USE_COUNT;
578
579 return 0;
580}
581
582static ssize_t
583brlvger_write(struct file *file, const char *buffer,
584 size_t count, loff_t *pos)
585{
586 struct brlvger_priv *priv = file->private_data;
587 char buf[MAX_BRLVGER_CELLS];
588 int ret;
589 size_t rs;
590 loff_t off;
591
592 __u16 written;
593
594 if(!priv->dev)
595 return -ENOLINK;
596
597 off = *pos;
598
599 if (off < 0)
600 return -EINVAL;
601
602 if(off > priv->plength)
603 return -ESPIPE;;
604
605 rs = priv->plength - off;
606
607 if(count > rs)
608 count = rs;
609 written = count;
610
611 if (copy_from_user (buf, buffer, count ) )
612 return -EFAULT;
613
614 memset(priv->obuf, 0xaa, sizeof(priv->obuf));
615
616
617
618
619 if( priv->plength == 44 ) {
620
621
622 if(off > 5) {
623 off +=4;
624 memcpy(priv->obuf, buf, count);
625 }else{
626 int firstpart = 6 - off;
627
628#ifdef WRITE_DEBUG
629 dbg3("off: %lld, rs: %d, count: %d, firstpart: %d",
630 off, rs, count, firstpart);
631#endif
632
633 firstpart = (firstpart < count) ? firstpart : count;
634
635#ifdef WRITE_DEBUG
636 dbg3("off: %lld", off);
637 dbg3("firstpart: %d", firstpart);
638#endif
639
640 memcpy(priv->obuf, buf, firstpart);
641
642 if(firstpart != count) {
643 int secondpart = count - firstpart;
644#ifdef WRITE_DEBUG
645 dbg3("secondpart: %d", secondpart);
646#endif
647
648 memcpy(priv->obuf+(firstpart+2),
649 buf+firstpart, secondpart);
650 written +=2;
651 }
652
653 off +=2;
654
655#ifdef WRITE_DEBUG
656 dbg3("off: %lld, rs: %d, count: %d, firstpart: %d, "
657 "written: %d", off, rs, count, firstpart, written);
658#endif
659 }
660 }else{
661
662 memcpy(priv->obuf, buf, count);
663 off += 2;
664 }
665
666 {
667 int repeat = write_repeats;
668
669
670 while(repeat--) {
671 ret = sndcontrolmsg(priv,
672 BRLVGER_SEND_BRAILLE, BRLVGER_WRITE_REQ, 0,
673 off, priv->obuf, written);
674 if(ret <0)
675 return ret;
676 }
677 }
678
679 return count;
680}
681
682static int
683read_index(struct brlvger_priv *priv)
684{
685 int intr_idx, read_idx;
686
687 read_idx = atomic_read(&priv->read_idx);
688 read_idx = ++read_idx == MAX_INTERRUPT_BUFFER ? 0 : read_idx;
689
690 intr_idx = atomic_read(&priv->intr_idx);
691
692 return(read_idx == intr_idx ? -1 : read_idx);
693}
694
695static ssize_t
696brlvger_read(struct file *file, char *buffer,
697 size_t count, loff_t *unused_pos)
698{
699 struct brlvger_priv *priv = file->private_data;
700 int read_idx;
701
702 if(count != MAX_INTERRUPT_DATA)
703 return -EINVAL;
704
705 if(!priv->dev)
706 return -ENOLINK;
707
708 if((read_idx = read_index(priv)) == -1) {
709
710 if (file->f_flags & O_NONBLOCK)
711 return -EAGAIN;
712 else{
713 int r = wait_event_interruptible(priv->read_wait,
714 (!priv->dev || (read_idx = read_index(priv)) != -1));
715 if(!priv->dev)
716 return -ENOLINK;
717 if(r)
718 return r;
719 if(read_idx == -1)
720
721 return 0;
722 }
723 }
724
725 if (copy_to_user (buffer, priv->event_queue[read_idx], count) )
726 return( -EFAULT);
727
728 atomic_set(&priv->read_idx, read_idx);
729
730
731
732
733 return MAX_INTERRUPT_DATA;
734}
735
736static int
737brlvger_ioctl(struct inode *inode, struct file *file,
738 unsigned cmd, unsigned long arg)
739{
740 struct brlvger_priv *priv = file->private_data;
741
742 if(!priv->dev)
743 return -ENOLINK;
744
745 switch(cmd) {
746 case BRLVGER_GET_INFO: {
747 struct brlvger_info vi;
748
749 memset(&vi, 0, sizeof(vi));
750 strncpy(vi.driver_version, DRIVER_VERSION,
751 sizeof(vi.driver_version));
752 vi.driver_version[sizeof(vi.driver_version)-1] = 0;
753 strncpy(vi.driver_banner, longbanner,
754 sizeof(vi.driver_banner));
755 vi.driver_banner[sizeof(vi.driver_banner)-1] = 0;
756
757 vi.display_length = priv->plength;
758
759 memcpy(&vi.hwver, priv->hwver, BRLVGER_HWVER_SIZE);
760 memcpy(&vi.fwver, priv->fwver, BRLVGER_FWVER_SIZE);
761 memcpy(&vi.serialnum, priv->serialnum, BRLVGER_SERIAL_SIZE);
762
763 if(copy_to_user((void *)arg, &vi, sizeof(vi)))
764 return -EFAULT;
765 return 0;
766 }
767 case BRLVGER_DISPLAY_ON:
768 return brlvger_set_display_on_off(priv, 1);
769 case BRLVGER_DISPLAY_OFF:
770 return brlvger_set_display_on_off(priv, 0);
771 case BRLVGER_BUZZ: {
772 __u16 duration;
773 if(get_user(duration, (__u16 *)arg))
774 return -EFAULT;
775 return brlvger_beep(priv, duration);
776 }
777
778#if 0
779
780 case BRLVGER_SET_VOLTAGE: {
781 __u16 voltage;
782 if(get_user(voltage, (__u16 *)arg))
783 return -EFAULT;
784 return brlvger_set_display_voltage(priv, voltage);
785 }
786 case BRLVGER_GET_VOLTAGE: {
787 __u8 voltage;
788 int r = brlvger_get_display_voltage(priv);
789 if(r <0)
790 return r;
791 voltage = r;
792 if(put_user(voltage, (__u8 *)arg))
793 return -EFAULT;
794 return 0;
795 }
796#endif
797 default:
798 return -EINVAL;
799 };
800}
801
802static loff_t
803brlvger_llseek(struct file *file, loff_t offset, int orig)
804{
805 struct brlvger_priv *priv = file->private_data;
806
807 if(!priv->dev)
808 return -ENOLINK;
809
810 switch (orig) {
811 case 0:
812
813 break;
814 case 1:
815 offset +=file->f_pos;
816 break;
817 case 2:
818 offset += priv->plength;
819 default:
820 return -EINVAL;
821 }
822
823 if((offset >= priv->plength) || (offset < 0))
824 return -EINVAL;
825
826 return (file->f_pos = offset);
827}
828
829static unsigned
830brlvger_poll(struct file *file, poll_table *wait)
831{
832 struct brlvger_priv *priv = file->private_data;
833
834 if(!priv->dev)
835 return POLLERR | POLLHUP;
836
837 poll_wait(file, &priv->read_wait, wait);
838
839 if(!priv->dev)
840 return POLLERR | POLLHUP;
841 if(read_index(priv) != -1)
842 return POLLIN | POLLRDNORM;
843
844 return 0;
845}
846
847static void
848intr_callback(struct urb *urb)
849{
850 struct brlvger_priv *priv = urb->context;
851 int intr_idx, read_idx;
852
853 if( urb->status ) {
854 if(urb->status == -ETIMEDOUT)
855 dbg2("Status -ETIMEDOUT, "
856 "probably disconnected");
857 else if(urb->status != -ENOENT)
858 err("Status: %d", urb->status);
859 return;
860 }
861
862 read_idx = atomic_read(&priv->read_idx);
863 spin_lock(&priv->intr_idx_lock);
864 intr_idx = atomic_read(&priv->intr_idx);
865 if(read_idx == intr_idx) {
866 dbg2("Queue full, dropping braille display input");
867 spin_unlock(&priv->intr_idx_lock);
868 return;
869 }
870
871 memcpy(priv->event_queue[intr_idx], urb->transfer_buffer,
872 MAX_INTERRUPT_DATA);
873
874 intr_idx = (++intr_idx == MAX_INTERRUPT_BUFFER)? 0 : intr_idx;
875 atomic_set(&priv->intr_idx, intr_idx);
876 spin_unlock(&priv->intr_idx_lock);
877
878 wake_up_interruptible(&priv->read_wait);
879}
880
881
882
883
884
885static int
886mycontrolmsg(const char *funcname,
887 struct brlvger_priv *priv, unsigned pipe_dir,
888 __u8 request, __u8 requesttype, __u16 value,
889 __u16 index, void *data, __u16 size)
890{
891 int ret=0, tries = stall_tries;
892
893
894 if(down_interruptible(&priv->dev_sem))
895 return -ERESTARTSYS;
896 if(!priv->dev) {
897 up(&priv->dev_sem);
898 return -ENOLINK;
899 }
900
901
902
903 while(tries--) {
904 ret = usb_control_msg(priv->dev,
905 usb_sndctrlpipe(priv->dev,0) |pipe_dir,
906 request, requesttype, value,
907 index, data, size,
908 HZ);
909 if(ret != -EPIPE)
910 break;
911 dbg2("Stalled, remaining %d tries", tries);
912 }
913 up(&priv->dev_sem);
914 if(ret <0) {
915 err("%s: usb_control_msg returns %d",
916 funcname, ret);
917 return -EIO;
918 }
919 return 0;
920}
921
922static int
923brlvger_get_hw_version(struct brlvger_priv *priv, unsigned char *verbuf)
924{
925 return rcvcontrolmsg(priv,
926 BRLVGER_GET_HWVERSION, BRLVGER_READ_REQ, 0,
927 0, verbuf, BRLVGER_HWVER_SIZE);
928
929}
930
931static int
932brlvger_get_fw_version(struct brlvger_priv *priv, unsigned char *buf)
933{
934 unsigned char rawbuf[(BRLVGER_FWVER_SIZE-1)*2+2];
935 int i, len;
936 int r = rcvcontrolmsg(priv,
937 BRLVGER_GET_FWVERSION, BRLVGER_READ_REQ, 0,
938 0, rawbuf, sizeof(rawbuf));
939 if(r<0)
940 return r;
941
942
943
944
945
946 len = rawbuf[0]-2;
947 if(len<0)
948 len = 0;
949 else if(len+1 > BRLVGER_FWVER_SIZE)
950 len = BRLVGER_FWVER_SIZE-1;
951 for(i=0; i<len; i++)
952 buf[i] = rawbuf[2+2*i];
953 buf[i] = 0;
954 return 0;
955}
956
957static int
958brlvger_get_serial(struct brlvger_priv *priv, unsigned char *buf)
959{
960 unsigned char rawserial[BRLVGER_SERIAL_BIN_SIZE];
961 int i;
962 int r = rcvcontrolmsg(priv,
963 BRLVGER_GET_SERIAL, BRLVGER_READ_REQ, 0,
964 0, rawserial, sizeof(rawserial));
965 if(r<0)
966 return r;
967
968 for(i=0; i<BRLVGER_SERIAL_BIN_SIZE; i++) {
969#define NUM_TO_HEX(n) (((n)>9) ? (n)+'A' : (n)+'0')
970 buf[2*i] = NUM_TO_HEX(rawserial[i] >>4);
971 buf[2*i+1] = NUM_TO_HEX(rawserial[i] &0xf);
972 }
973 buf[2*i] = 0;
974 return 0;
975}
976
977static int
978brlvger_get_display_length(struct brlvger_priv *priv)
979{
980 unsigned char data[2];
981 int ret = rcvcontrolmsg(priv,
982 BRLVGER_GET_LENGTH, BRLVGER_READ_REQ, 0,
983 0, data, 2);
984 if(ret<0)
985 return ret;
986 return data[1];
987}
988
989static int
990brlvger_beep(struct brlvger_priv *priv, __u16 duration)
991{
992 return sndcontrolmsg(priv,
993 BRLVGER_BEEP, BRLVGER_WRITE_REQ, duration,
994 0, NULL, 0);
995}
996
997static int
998brlvger_set_display_on_off(struct brlvger_priv *priv, __u16 on)
999{
1000 dbg2("Turning display %s", ((on) ? "on" : "off"));
1001 return sndcontrolmsg(priv,
1002 BRLVGER_SET_DISPLAY_ON, BRLVGER_WRITE_REQ, on,
1003 0, NULL, 0);
1004}
1005
1006static int
1007brlvger_set_display_voltage(struct brlvger_priv *priv, __u16 voltage)
1008{
1009 dbg("SET_DISPLAY_VOLTAGE to %u", voltage);
1010 return sndcontrolmsg(priv,
1011 BRLVGER_SET_DISPLAY_VOLTAGE, BRLVGER_WRITE_REQ, voltage,
1012 0, NULL, 0);
1013}
1014
1015#if 0
1016
1017static int
1018brlvger_get_display_voltage(struct brlvger_priv *priv)
1019{
1020 __u8 voltage = 0;
1021 int ret = rcvcontrolmsg(priv,
1022 BRLVGER_GET_DISPLAY_VOLTAGE, BRLVGER_READ_REQ, 0,
1023 0, &voltage, 1);
1024 if(ret<0)
1025 return ret;
1026 return voltage;
1027}
1028
1029static int
1030brlvger_get_current(struct brlvger_priv *priv)
1031{
1032 unsigned char data;
1033 int ret = rcvcontrolmsg(priv,
1034 BRLVGER_GET_CURRENT, BRLVGER_READ_REQ, 0,
1035 0, &data, 1);
1036 if(ret<0)
1037 return ret;
1038 return data;
1039}
1040#endif
1041