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