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