source: src/linux/universal/linux-3.18/drivers/usb/misc/uss720.c @ 31869

Last change on this file since 31869 was 31869, checked in by brainslayer, 5 weeks ago

update

File size: 22.9 KB
Line 
1/*****************************************************************************/
2
3/*
4 *      uss720.c  --  USS720 USB Parport Cable.
5 *
6 *      Copyright (C) 1999, 2005, 2010
7 *          Thomas Sailer (t.sailer@alumni.ethz.ch)
8 *
9 *      This program is free software; you can redistribute it and/or modify
10 *      it under the terms of the GNU General Public License as published by
11 *      the Free Software Foundation; either version 2 of the License, or
12 *      (at your option) any later version.
13 *
14 *      This program is distributed in the hope that it will be useful,
15 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *      GNU General Public License for more details.
18 *
19 *      You should have received a copy of the GNU General Public License
20 *      along with this program; if not, write to the Free Software
21 *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 *  Based on parport_pc.c
24 *
25 *  History:
26 *   0.1  04.08.1999  Created
27 *   0.2  07.08.1999  Some fixes mainly suggested by Tim Waugh
28 *                    Interrupt handling currently disabled because
29 *                    usb_request_irq crashes somewhere within ohci.c
30 *                    for no apparent reason (that is for me, anyway)
31 *                    ECP currently untested
32 *   0.3  10.08.1999  fixing merge errors
33 *   0.4  13.08.1999  Added Vendor/Product ID of Brad Hard's cable
34 *   0.5  20.09.1999  usb_control_msg wrapper used
35 *        Nov01.2000  usb_device_table support by Adam J. Richter
36 *        08.04.2001  Identify version on module load.  gb
37 *   0.6  02.09.2005  Fix "scheduling in interrupt" problem by making save/restore
38 *                    context asynchronous
39 *
40 */
41
42/*****************************************************************************/
43
44#include <linux/module.h>
45#include <linux/socket.h>
46#include <linux/parport.h>
47#include <linux/init.h>
48#include <linux/usb.h>
49#include <linux/delay.h>
50#include <linux/completion.h>
51#include <linux/kref.h>
52#include <linux/slab.h>
53
54/*
55 * Version Information
56 */
57#define DRIVER_VERSION "v0.6"
58#define DRIVER_AUTHOR "Thomas M. Sailer, t.sailer@alumni.ethz.ch"
59#define DRIVER_DESC "USB Parport Cable driver for Cables using the Lucent Technologies USS720 Chip"
60
61/* --------------------------------------------------------------------- */
62
63struct parport_uss720_private {
64        struct usb_device *usbdev;
65        struct parport *pp;
66        struct kref ref_count;
67        __u8 reg[7];  /* USB registers */
68        struct list_head asynclist;
69        spinlock_t asynclock;
70};
71
72struct uss720_async_request {
73        struct parport_uss720_private *priv;
74        struct kref ref_count;
75        struct list_head asynclist;
76        struct completion compl;
77        struct urb *urb;
78        struct usb_ctrlrequest *dr;
79        __u8 reg[7];
80};
81
82/* --------------------------------------------------------------------- */
83
84static void destroy_priv(struct kref *kref)
85{
86        struct parport_uss720_private *priv = container_of(kref, struct parport_uss720_private, ref_count);
87
88        dev_dbg(&priv->usbdev->dev, "destroying priv datastructure\n");
89        usb_put_dev(priv->usbdev);
90        kfree(priv);
91}
92
93static void destroy_async(struct kref *kref)
94{
95        struct uss720_async_request *rq = container_of(kref, struct uss720_async_request, ref_count);
96        struct parport_uss720_private *priv = rq->priv;
97        unsigned long flags;
98
99        if (likely(rq->urb))
100                usb_free_urb(rq->urb);
101        kfree(rq->dr);
102        spin_lock_irqsave(&priv->asynclock, flags);
103        list_del_init(&rq->asynclist);
104        spin_unlock_irqrestore(&priv->asynclock, flags);
105        kfree(rq);
106        kref_put(&priv->ref_count, destroy_priv);
107}
108
109/* --------------------------------------------------------------------- */
110
111static void async_complete(struct urb *urb)
112{
113        struct uss720_async_request *rq;
114        struct parport *pp;
115        struct parport_uss720_private *priv;
116        int status = urb->status;
117
118        rq = urb->context;
119        priv = rq->priv;
120        pp = priv->pp;
121        if (status) {
122                dev_err(&urb->dev->dev, "async_complete: urb error %d\n",
123                        status);
124        } else if (rq->dr->bRequest == 3) {
125                memcpy(priv->reg, rq->reg, sizeof(priv->reg));
126#if 0
127                dev_dbg(&priv->usbdev->dev,
128                        "async_complete regs %02x %02x %02x %02x %02x %02x %02x\n",
129                        (unsigned int)priv->reg[0], (unsigned int)priv->reg[1],
130                        (unsigned int)priv->reg[2], (unsigned int)priv->reg[3],
131                        (unsigned int)priv->reg[4], (unsigned int)priv->reg[5],
132                        (unsigned int)priv->reg[6]);
133#endif
134                /* if nAck interrupts are enabled and we have an interrupt, call the interrupt procedure */
135                if (rq->reg[2] & rq->reg[1] & 0x10 && pp)
136                        parport_generic_irq(pp);
137        }
138        complete(&rq->compl);
139        kref_put(&rq->ref_count, destroy_async);
140}
141
142static struct uss720_async_request *submit_async_request(struct parport_uss720_private *priv,
143                                                         __u8 request, __u8 requesttype, __u16 value, __u16 index,
144                                                         gfp_t mem_flags)
145{
146        struct usb_device *usbdev;
147        struct uss720_async_request *rq;
148        unsigned long flags;
149        int ret;
150
151        if (!priv)
152                return NULL;
153        usbdev = priv->usbdev;
154        if (!usbdev)
155                return NULL;
156        rq = kzalloc(sizeof(struct uss720_async_request), mem_flags);
157        if (!rq) {
158                dev_err(&usbdev->dev, "submit_async_request out of memory\n");
159                return NULL;
160        }
161        kref_init(&rq->ref_count);
162        INIT_LIST_HEAD(&rq->asynclist);
163        init_completion(&rq->compl);
164        kref_get(&priv->ref_count);
165        rq->priv = priv;
166        rq->urb = usb_alloc_urb(0, mem_flags);
167        if (!rq->urb) {
168                kref_put(&rq->ref_count, destroy_async);
169                dev_err(&usbdev->dev, "submit_async_request out of memory\n");
170                return NULL;
171        }
172        rq->dr = kmalloc(sizeof(*rq->dr), mem_flags);
173        if (!rq->dr) {
174                kref_put(&rq->ref_count, destroy_async);
175                return NULL;
176        }
177        rq->dr->bRequestType = requesttype;
178        rq->dr->bRequest = request;
179        rq->dr->wValue = cpu_to_le16(value);
180        rq->dr->wIndex = cpu_to_le16(index);
181        rq->dr->wLength = cpu_to_le16((request == 3) ? sizeof(rq->reg) : 0);
182        usb_fill_control_urb(rq->urb, usbdev, (requesttype & 0x80) ? usb_rcvctrlpipe(usbdev, 0) : usb_sndctrlpipe(usbdev, 0),
183                             (unsigned char *)rq->dr,
184                             (request == 3) ? rq->reg : NULL, (request == 3) ? sizeof(rq->reg) : 0, async_complete, rq);
185        /* rq->urb->transfer_flags |= URB_ASYNC_UNLINK; */
186        spin_lock_irqsave(&priv->asynclock, flags);
187        list_add_tail(&rq->asynclist, &priv->asynclist);
188        spin_unlock_irqrestore(&priv->asynclock, flags);
189        kref_get(&rq->ref_count);
190        ret = usb_submit_urb(rq->urb, mem_flags);
191        if (!ret)
192                return rq;
193        destroy_async(&rq->ref_count);
194        dev_err(&usbdev->dev, "submit_async_request submit_urb failed with %d\n", ret);
195        return NULL;
196}
197
198static unsigned int kill_all_async_requests_priv(struct parport_uss720_private *priv)
199{
200        struct uss720_async_request *rq;
201        unsigned long flags;
202        unsigned int ret = 0;
203
204        spin_lock_irqsave(&priv->asynclock, flags);
205        list_for_each_entry(rq, &priv->asynclist, asynclist) {
206                usb_unlink_urb(rq->urb);
207                ret++;
208        }
209        spin_unlock_irqrestore(&priv->asynclock, flags);
210        return ret;
211}
212
213/* --------------------------------------------------------------------- */
214
215static int get_1284_register(struct parport *pp, unsigned char reg, unsigned char *val, gfp_t mem_flags)
216{
217        struct parport_uss720_private *priv;
218        struct uss720_async_request *rq;
219        static const unsigned char regindex[9] = {
220                4, 0, 1, 5, 5, 0, 2, 3, 6
221        };
222        int ret;
223
224        if (!pp)
225                return -EIO;
226        priv = pp->private_data;
227        rq = submit_async_request(priv, 3, 0xc0, ((unsigned int)reg) << 8, 0, mem_flags);
228        if (!rq) {
229                dev_err(&priv->usbdev->dev, "get_1284_register(%u) failed",
230                        (unsigned int)reg);
231                return -EIO;
232        }
233        if (!val) {
234                kref_put(&rq->ref_count, destroy_async);
235                return 0;
236        }
237        if (wait_for_completion_timeout(&rq->compl, HZ)) {
238                ret = rq->urb->status;
239                *val = priv->reg[(reg >= 9) ? 0 : regindex[reg]];
240                if (ret)
241                        printk(KERN_WARNING "get_1284_register: "
242                               "usb error %d\n", ret);
243                kref_put(&rq->ref_count, destroy_async);
244                return ret;
245        }
246        printk(KERN_WARNING "get_1284_register timeout\n");
247        kill_all_async_requests_priv(priv);
248        return -EIO;
249}
250
251static int set_1284_register(struct parport *pp, unsigned char reg, unsigned char val, gfp_t mem_flags)
252{
253        struct parport_uss720_private *priv;
254        struct uss720_async_request *rq;
255
256        if (!pp)
257                return -EIO;
258        priv = pp->private_data;
259        rq = submit_async_request(priv, 4, 0x40, (((unsigned int)reg) << 8) | val, 0, mem_flags);
260        if (!rq) {
261                dev_err(&priv->usbdev->dev, "set_1284_register(%u,%u) failed",
262                        (unsigned int)reg, (unsigned int)val);
263                return -EIO;
264        }
265        kref_put(&rq->ref_count, destroy_async);
266        return 0;
267}
268
269/* --------------------------------------------------------------------- */
270
271/* ECR modes */
272#define ECR_SPP 00
273#define ECR_PS2 01
274#define ECR_PPF 02
275#define ECR_ECP 03
276#define ECR_EPP 04
277
278/* Safely change the mode bits in the ECR */
279static int change_mode(struct parport *pp, int m)
280{
281        struct parport_uss720_private *priv = pp->private_data;
282        int mode;
283        __u8 reg;
284
285        if (get_1284_register(pp, 6, &reg, GFP_KERNEL))
286                return -EIO;
287        /* Bits <7:5> contain the mode. */
288        mode = (priv->reg[2] >> 5) & 0x7;
289        if (mode == m)
290                return 0;
291        /* We have to go through mode 000 or 001 */
292        if (mode > ECR_PS2 && m > ECR_PS2)
293                if (change_mode(pp, ECR_PS2))
294                        return -EIO;
295
296        if (m <= ECR_PS2 && !(priv->reg[1] & 0x20)) {
297                /* This mode resets the FIFO, so we may
298                 * have to wait for it to drain first. */
299                unsigned long expire = jiffies + pp->physport->cad->timeout;
300                switch (mode) {
301                case ECR_PPF: /* Parallel Port FIFO mode */
302                case ECR_ECP: /* ECP Parallel Port mode */
303                        /* Poll slowly. */
304                        for (;;) {
305                                if (get_1284_register(pp, 6, &reg, GFP_KERNEL))
306                                        return -EIO;
307                                if (priv->reg[2] & 0x01)
308                                        break;
309                                if (time_after_eq (jiffies, expire))
310                                        /* The FIFO is stuck. */
311                                        return -EBUSY;
312                                msleep_interruptible(10);
313                                if (signal_pending (current))
314                                        break;
315                        }
316                }
317        }
318        /* Set the mode. */
319        if (set_1284_register(pp, 6, m << 5, GFP_KERNEL))
320                return -EIO;
321        if (get_1284_register(pp, 6, &reg, GFP_KERNEL))
322                return -EIO;
323        return 0;
324}
325
326/*
327 * Clear TIMEOUT BIT in EPP MODE
328 */
329static int clear_epp_timeout(struct parport *pp)
330{
331        unsigned char stat;
332
333        if (get_1284_register(pp, 1, &stat, GFP_KERNEL))
334                return 1;
335        return stat & 1;
336}
337
338/*
339 * Access functions.
340 */
341#if 0
342static int uss720_irq(int usbstatus, void *buffer, int len, void *dev_id)
343{
344        struct parport *pp = (struct parport *)dev_id;
345        struct parport_uss720_private *priv = pp->private_data;
346
347        if (usbstatus != 0 || len < 4 || !buffer)
348                return 1;
349        memcpy(priv->reg, buffer, 4);
350        /* if nAck interrupts are enabled and we have an interrupt, call the interrupt procedure */
351        if (priv->reg[2] & priv->reg[1] & 0x10)
352                parport_generic_irq(pp);
353        return 1;
354}
355#endif
356
357static void parport_uss720_write_data(struct parport *pp, unsigned char d)
358{
359        set_1284_register(pp, 0, d, GFP_KERNEL);
360}
361
362static unsigned char parport_uss720_read_data(struct parport *pp)
363{
364        unsigned char ret;
365
366        if (get_1284_register(pp, 0, &ret, GFP_KERNEL))
367                return 0;
368        return ret;
369}
370
371static void parport_uss720_write_control(struct parport *pp, unsigned char d)
372{
373        struct parport_uss720_private *priv = pp->private_data;
374
375        d = (d & 0xf) | (priv->reg[1] & 0xf0);
376        if (set_1284_register(pp, 2, d, GFP_KERNEL))
377                return;
378        priv->reg[1] = d;
379}
380
381static unsigned char parport_uss720_read_control(struct parport *pp)
382{
383        struct parport_uss720_private *priv = pp->private_data;
384        return priv->reg[1] & 0xf; /* Use soft copy */
385}
386
387static unsigned char parport_uss720_frob_control(struct parport *pp, unsigned char mask, unsigned char val)
388{
389        struct parport_uss720_private *priv = pp->private_data;
390        unsigned char d;
391
392        mask &= 0x0f;
393        val &= 0x0f;
394        d = (priv->reg[1] & (~mask)) ^ val;
395        if (set_1284_register(pp, 2, d, GFP_KERNEL))
396                return 0;
397        priv->reg[1] = d;
398        return d & 0xf;
399}
400
401static unsigned char parport_uss720_read_status(struct parport *pp)
402{
403        unsigned char ret;
404
405        if (get_1284_register(pp, 1, &ret, GFP_KERNEL))
406                return 0;
407        return ret & 0xf8;
408}
409
410static void parport_uss720_disable_irq(struct parport *pp)
411{
412        struct parport_uss720_private *priv = pp->private_data;
413        unsigned char d;
414
415        d = priv->reg[1] & ~0x10;
416        if (set_1284_register(pp, 2, d, GFP_KERNEL))
417                return;
418        priv->reg[1] = d;
419}
420
421static void parport_uss720_enable_irq(struct parport *pp)
422{
423        struct parport_uss720_private *priv = pp->private_data;
424        unsigned char d;
425
426        d = priv->reg[1] | 0x10;
427        if (set_1284_register(pp, 2, d, GFP_KERNEL))
428                return;
429        priv->reg[1] = d;
430}
431
432static void parport_uss720_data_forward (struct parport *pp)
433{
434        struct parport_uss720_private *priv = pp->private_data;
435        unsigned char d;
436
437        d = priv->reg[1] & ~0x20;
438        if (set_1284_register(pp, 2, d, GFP_KERNEL))
439                return;
440        priv->reg[1] = d;
441}
442
443static void parport_uss720_data_reverse (struct parport *pp)
444{
445        struct parport_uss720_private *priv = pp->private_data;
446        unsigned char d;
447
448        d = priv->reg[1] | 0x20;
449        if (set_1284_register(pp, 2, d, GFP_KERNEL))
450                return;
451        priv->reg[1] = d;
452}
453
454static void parport_uss720_init_state(struct pardevice *dev, struct parport_state *s)
455{
456        s->u.pc.ctr = 0xc | (dev->irq_func ? 0x10 : 0x0);
457        s->u.pc.ecr = 0x24;
458}
459
460static void parport_uss720_save_state(struct parport *pp, struct parport_state *s)
461{
462        struct parport_uss720_private *priv = pp->private_data;
463
464#if 0
465        if (get_1284_register(pp, 2, NULL, GFP_ATOMIC))
466                return;
467#endif
468        s->u.pc.ctr = priv->reg[1];
469        s->u.pc.ecr = priv->reg[2];
470}
471
472static void parport_uss720_restore_state(struct parport *pp, struct parport_state *s)
473{
474        struct parport_uss720_private *priv = pp->private_data;
475
476        set_1284_register(pp, 2, s->u.pc.ctr, GFP_ATOMIC);
477        set_1284_register(pp, 6, s->u.pc.ecr, GFP_ATOMIC);
478        get_1284_register(pp, 2, NULL, GFP_ATOMIC);
479        priv->reg[1] = s->u.pc.ctr;
480        priv->reg[2] = s->u.pc.ecr;
481}
482
483static size_t parport_uss720_epp_read_data(struct parport *pp, void *buf, size_t length, int flags)
484{
485        struct parport_uss720_private *priv = pp->private_data;
486        size_t got = 0;
487
488        if (change_mode(pp, ECR_EPP))
489                return 0;
490        for (; got < length; got++) {
491                if (get_1284_register(pp, 4, (char *)buf, GFP_KERNEL))
492                        break;
493                buf++;
494                if (priv->reg[0] & 0x01) {
495                        clear_epp_timeout(pp);
496                        break;
497                }
498        }
499        change_mode(pp, ECR_PS2);
500        return got;
501}
502
503static size_t parport_uss720_epp_write_data(struct parport *pp, const void *buf, size_t length, int flags)
504{
505#if 0
506        struct parport_uss720_private *priv = pp->private_data;
507        size_t written = 0;
508
509        if (change_mode(pp, ECR_EPP))
510                return 0;
511        for (; written < length; written++) {
512                if (set_1284_register(pp, 4, (char *)buf, GFP_KERNEL))
513                        break;
514                ((char*)buf)++;
515                if (get_1284_register(pp, 1, NULL, GFP_KERNEL))
516                        break;
517                if (priv->reg[0] & 0x01) {
518                        clear_epp_timeout(pp);
519                        break;
520                }
521        }
522        change_mode(pp, ECR_PS2);
523        return written;
524#else
525        struct parport_uss720_private *priv = pp->private_data;
526        struct usb_device *usbdev = priv->usbdev;
527        int rlen;
528        int i;
529
530        if (!usbdev)
531                return 0;
532        if (change_mode(pp, ECR_EPP))
533                return 0;
534        i = usb_bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), (void *)buf, length, &rlen, 20000);
535        if (i)
536                printk(KERN_ERR "uss720: sendbulk ep 1 buf %p len %Zu rlen %u\n", buf, length, rlen);
537        change_mode(pp, ECR_PS2);
538        return rlen;
539#endif
540}
541
542static size_t parport_uss720_epp_read_addr(struct parport *pp, void *buf, size_t length, int flags)
543{
544        struct parport_uss720_private *priv = pp->private_data;
545        size_t got = 0;
546
547        if (change_mode(pp, ECR_EPP))
548                return 0;
549        for (; got < length; got++) {
550                if (get_1284_register(pp, 3, (char *)buf, GFP_KERNEL))
551                        break;
552                buf++;
553                if (priv->reg[0] & 0x01) {
554                        clear_epp_timeout(pp);
555                        break;
556                }
557        }
558        change_mode(pp, ECR_PS2);
559        return got;
560}
561
562static size_t parport_uss720_epp_write_addr(struct parport *pp, const void *buf, size_t length, int flags)
563{
564        struct parport_uss720_private *priv = pp->private_data;
565        size_t written = 0;
566
567        if (change_mode(pp, ECR_EPP))
568                return 0;
569        for (; written < length; written++) {
570                if (set_1284_register(pp, 3, *(char *)buf, GFP_KERNEL))
571                        break;
572                buf++;
573                if (get_1284_register(pp, 1, NULL, GFP_KERNEL))
574                        break;
575                if (priv->reg[0] & 0x01) {
576                        clear_epp_timeout(pp);
577                        break;
578                }
579        }
580        change_mode(pp, ECR_PS2);
581        return written;
582}
583
584static size_t parport_uss720_ecp_write_data(struct parport *pp, const void *buffer, size_t len, int flags)
585{
586        struct parport_uss720_private *priv = pp->private_data;
587        struct usb_device *usbdev = priv->usbdev;
588        int rlen;
589        int i;
590
591        if (!usbdev)
592                return 0;
593        if (change_mode(pp, ECR_ECP))
594                return 0;
595        i = usb_bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), (void *)buffer, len, &rlen, 20000);
596        if (i)
597                printk(KERN_ERR "uss720: sendbulk ep 1 buf %p len %Zu rlen %u\n", buffer, len, rlen);
598        change_mode(pp, ECR_PS2);
599        return rlen;
600}
601
602static size_t parport_uss720_ecp_read_data(struct parport *pp, void *buffer, size_t len, int flags)
603{
604        struct parport_uss720_private *priv = pp->private_data;
605        struct usb_device *usbdev = priv->usbdev;
606        int rlen;
607        int i;
608
609        if (!usbdev)
610                return 0;
611        if (change_mode(pp, ECR_ECP))
612                return 0;
613        i = usb_bulk_msg(usbdev, usb_rcvbulkpipe(usbdev, 2), buffer, len, &rlen, 20000);
614        if (i)
615                printk(KERN_ERR "uss720: recvbulk ep 2 buf %p len %Zu rlen %u\n", buffer, len, rlen);
616        change_mode(pp, ECR_PS2);
617        return rlen;
618}
619
620static size_t parport_uss720_ecp_write_addr(struct parport *pp, const void *buffer, size_t len, int flags)
621{
622        size_t written = 0;
623
624        if (change_mode(pp, ECR_ECP))
625                return 0;
626        for (; written < len; written++) {
627                if (set_1284_register(pp, 5, *(char *)buffer, GFP_KERNEL))
628                        break;
629                buffer++;
630        }
631        change_mode(pp, ECR_PS2);
632        return written;
633}
634
635static size_t parport_uss720_write_compat(struct parport *pp, const void *buffer, size_t len, int flags)
636{
637        struct parport_uss720_private *priv = pp->private_data;
638        struct usb_device *usbdev = priv->usbdev;
639        int rlen;
640        int i;
641
642        if (!usbdev)
643                return 0;
644        if (change_mode(pp, ECR_PPF))
645                return 0;
646        i = usb_bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), (void *)buffer, len, &rlen, 20000);
647        if (i)
648                printk(KERN_ERR "uss720: sendbulk ep 1 buf %p len %Zu rlen %u\n", buffer, len, rlen);
649        change_mode(pp, ECR_PS2);
650        return rlen;
651}
652
653/* --------------------------------------------------------------------- */
654
655static struct parport_operations parport_uss720_ops =
656{
657        .owner =                THIS_MODULE,
658        .write_data =           parport_uss720_write_data,
659        .read_data =            parport_uss720_read_data,
660
661        .write_control =        parport_uss720_write_control,
662        .read_control =         parport_uss720_read_control,
663        .frob_control =         parport_uss720_frob_control,
664
665        .read_status =          parport_uss720_read_status,
666
667        .enable_irq =           parport_uss720_enable_irq,
668        .disable_irq =          parport_uss720_disable_irq,
669
670        .data_forward =         parport_uss720_data_forward,
671        .data_reverse =         parport_uss720_data_reverse,
672
673        .init_state =           parport_uss720_init_state,
674        .save_state =           parport_uss720_save_state,
675        .restore_state =        parport_uss720_restore_state,
676
677        .epp_write_data =       parport_uss720_epp_write_data,
678        .epp_read_data =        parport_uss720_epp_read_data,
679        .epp_write_addr =       parport_uss720_epp_write_addr,
680        .epp_read_addr =        parport_uss720_epp_read_addr,
681
682        .ecp_write_data =       parport_uss720_ecp_write_data,
683        .ecp_read_data =        parport_uss720_ecp_read_data,
684        .ecp_write_addr =       parport_uss720_ecp_write_addr,
685
686        .compat_write_data =    parport_uss720_write_compat,
687        .nibble_read_data =     parport_ieee1284_read_nibble,
688        .byte_read_data =       parport_ieee1284_read_byte,
689};
690
691/* --------------------------------------------------------------------- */
692
693static int uss720_probe(struct usb_interface *intf,
694                        const struct usb_device_id *id)
695{
696        struct usb_device *usbdev = usb_get_dev(interface_to_usbdev(intf));
697        struct usb_host_interface *interface;
698        struct usb_host_endpoint *endpoint;
699        struct parport_uss720_private *priv;
700        struct parport *pp;
701        unsigned char reg;
702        int i;
703
704        dev_dbg(&intf->dev, "probe: vendor id 0x%x, device id 0x%x\n",
705                le16_to_cpu(usbdev->descriptor.idVendor),
706                le16_to_cpu(usbdev->descriptor.idProduct));
707
708        /* our known interfaces have 3 alternate settings */
709        if (intf->num_altsetting != 3) {
710                usb_put_dev(usbdev);
711                return -ENODEV;
712        }
713        i = usb_set_interface(usbdev, intf->altsetting->desc.bInterfaceNumber, 2);
714        dev_dbg(&intf->dev, "set interface result %d\n", i);
715
716        interface = intf->cur_altsetting;
717
718        if (interface->desc.bNumEndpoints < 3) {
719                usb_put_dev(usbdev);
720                return -ENODEV;
721        }
722
723        /*
724         * Allocate parport interface
725         */
726        if (!(priv = kzalloc(sizeof(struct parport_uss720_private), GFP_KERNEL))) {
727                usb_put_dev(usbdev);
728                return -ENOMEM;
729        }
730        priv->pp = NULL;
731        priv->usbdev = usbdev;
732        kref_init(&priv->ref_count);
733        spin_lock_init(&priv->asynclock);
734        INIT_LIST_HEAD(&priv->asynclist);
735        if (!(pp = parport_register_port(0, PARPORT_IRQ_NONE, PARPORT_DMA_NONE, &parport_uss720_ops))) {
736                printk(KERN_WARNING "uss720: could not register parport\n");
737                goto probe_abort;
738        }
739
740        priv->pp = pp;
741        pp->private_data = priv;
742        pp->modes = PARPORT_MODE_PCSPP | PARPORT_MODE_TRISTATE | PARPORT_MODE_EPP | PARPORT_MODE_ECP | PARPORT_MODE_COMPAT;
743
744        /* set the USS720 control register to manual mode, no ECP compression, enable all ints */
745        set_1284_register(pp, 7, 0x00, GFP_KERNEL);
746        set_1284_register(pp, 6, 0x30, GFP_KERNEL);  /* PS/2 mode */
747        set_1284_register(pp, 2, 0x0c, GFP_KERNEL);
748        /* debugging */
749        get_1284_register(pp, 0, &reg, GFP_KERNEL);
750        dev_dbg(&intf->dev, "reg: %02x %02x %02x %02x %02x %02x %02x\n",
751                priv->reg[0], priv->reg[1], priv->reg[2], priv->reg[3],
752                priv->reg[4], priv->reg[5], priv->reg[6]);
753
754        endpoint = &interface->endpoint[2];
755        dev_dbg(&intf->dev, "epaddr %d interval %d\n",
756                endpoint->desc.bEndpointAddress, endpoint->desc.bInterval);
757        parport_announce_port(pp);
758
759        usb_set_intfdata(intf, pp);
760        return 0;
761
762probe_abort:
763        kill_all_async_requests_priv(priv);
764        kref_put(&priv->ref_count, destroy_priv);
765        return -ENODEV;
766}
767
768static void uss720_disconnect(struct usb_interface *intf)
769{
770        struct parport *pp = usb_get_intfdata(intf);
771        struct parport_uss720_private *priv;
772        struct usb_device *usbdev;
773
774        dev_dbg(&intf->dev, "disconnect\n");
775        usb_set_intfdata(intf, NULL);
776        if (pp) {
777                priv = pp->private_data;
778                usbdev = priv->usbdev;
779                priv->usbdev = NULL;
780                priv->pp = NULL;
781                dev_dbg(&intf->dev, "parport_remove_port\n");
782                parport_remove_port(pp);
783                parport_put_port(pp);
784                kill_all_async_requests_priv(priv);
785                kref_put(&priv->ref_count, destroy_priv);
786        }
787        dev_dbg(&intf->dev, "disconnect done\n");
788}
789
790/* table of cables that work through this driver */
791static const struct usb_device_id uss720_table[] = {
792        { USB_DEVICE(0x047e, 0x1001) },
793        { USB_DEVICE(0x0557, 0x2001) },
794        { USB_DEVICE(0x0729, 0x1284) },
795        { USB_DEVICE(0x1293, 0x0002) },
796        { USB_DEVICE(0x050d, 0x0002) },
797        { }                                             /* Terminating entry */
798};
799
800MODULE_DEVICE_TABLE (usb, uss720_table);
801
802
803static struct usb_driver uss720_driver = {
804        .name =         "uss720",
805        .probe =        uss720_probe,
806        .disconnect =   uss720_disconnect,
807        .id_table =     uss720_table,
808};
809
810/* --------------------------------------------------------------------- */
811
812MODULE_AUTHOR(DRIVER_AUTHOR);
813MODULE_DESCRIPTION(DRIVER_DESC);
814MODULE_LICENSE("GPL");
815
816static int __init uss720_init(void)
817{
818        int retval;
819        retval = usb_register(&uss720_driver);
820        if (retval)
821                goto out;
822
823        printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
824               DRIVER_DESC "\n");
825        printk(KERN_INFO KBUILD_MODNAME ": NOTE: this is a special purpose "
826               "driver to allow nonstandard\n");
827        printk(KERN_INFO KBUILD_MODNAME ": protocols (eg. bitbang) over "
828               "USS720 usb to parallel cables\n");
829        printk(KERN_INFO KBUILD_MODNAME ": If you just want to connect to a "
830               "printer, use usblp instead\n");
831out:
832        return retval;
833}
834
835static void __exit uss720_cleanup(void)
836{
837        usb_deregister(&uss720_driver);
838}
839
840module_init(uss720_init);
841module_exit(uss720_cleanup);
842
843/* --------------------------------------------------------------------- */
Note: See TracBrowser for help on using the repository browser.