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