linux-old/drivers/usb/microtek.c
<<
>>
Prefs
   1/* Driver for Microtek Scanmaker X6 USB scanner, and possibly others.
   2 *
   3 * (C) Copyright 2000 John Fremlin <vii@penguinpowered.com>
   4 * (C) Copyright 2000 Oliver Neukum <Oliver.Neukum@lrz.uni-muenchen.de>
   5 *
   6 * Parts shamelessly stolen from usb-storage and copyright by their
   7 * authors. Thanks to Matt Dharm for giving us permission!
   8 *
   9 * This driver implements a SCSI host controller driver and a USB
  10 * device driver. To avoid confusion, all the USB related stuff is
  11 * prefixed by mts_usb_ and all the SCSI stuff by mts_scsi_.
  12 *
  13 * Microtek (www.microtek.com) did not release the specifications for
  14 * their USB protocol to us, so we had to reverse engineer them. We
  15 * don't know for which models they are valid.
  16 *
  17 * The X6 USB has three bulk endpoints, one output (0x1) down which
  18 * commands and outgoing data are sent, and two input: 0x82 from which
  19 * normal data is read from the scanner (in packets of maximum 32
  20 * bytes) and from which the status byte is read, and 0x83 from which
  21 * the results of a scan (or preview) are read in up to 64 * 1024 byte
  22 * chunks by the Windows driver. We don't know how much it is possible
  23 * to read at a time from 0x83.
  24 *
  25 * It seems possible to read (with URB transfers) everything from 0x82
  26 * in one go, without bothering to read in 32 byte chunks.
  27 *
  28 * There seems to be an optimisation of a further READ implicit if
  29 * you simply read from 0x83.
  30 *
  31 * Guessed protocol:
  32 *
  33 *      Send raw SCSI command to EP 0x1
  34 *
  35 *      If there is data to receive:
  36 *              If the command was READ datatype=image:
  37 *                      Read a lot of data from EP 0x83
  38 *              Else:
  39 *                      Read data from EP 0x82
  40 *      Else:
  41 *              If there is data to transmit:
  42 *                      Write it to EP 0x1
  43 *
  44 *      Read status byte from EP 0x82
  45 *
  46 * References:
  47 *
  48 * The SCSI command set for the scanner is available from
  49 *      ftp://ftp.microtek.com/microtek/devpack/
  50 *
  51 * Microtek NV sent us a more up to date version of the document. If
  52 * you want it, just send mail.
  53 *
  54 * Status:
  55 *
  56 *      Untested with multiple scanners.
  57 *      Untested on SMP.
  58 *      Untested on a bigendian machine.
  59 *
  60 * History:
  61 *
  62 *      20000417 starting history
  63 *      20000417 fixed load oops
  64 *      20000417 fixed unload oops
  65 *      20000419 fixed READ IMAGE detection
  66 *      20000424 started conversion to use URBs
  67 *      20000502 handled short transfers as errors
  68 *      20000513 rename and organisation of functions (john)
  69 *      20000513 added IDs for all products supported by Windows driver (john)
  70 *      20000514 Rewrote mts_scsi_queuecommand to use URBs (john)
  71 *      20000514 Version 0.0.8j
  72 *      20000514 Fix reporting of non-existant devices to SCSI layer (john)
  73 *      20000514 Added MTS_DEBUG_INT (john)
  74 *      20000514 Changed "usb-microtek" to "microtek" for consistency (john)
  75 *      20000514 Stupid bug fixes (john)
  76 *      20000514 Version 0.0.9j
  77 *      20000515 Put transfer context and URB in mts_desc (john)
  78 *      20000515 Added prelim turn off debugging support (john)
  79 *      20000515 Version 0.0.10j
  80 *      20000515 Fixed up URB allocation (clear URB on alloc) (john)
  81 *      20000515 Version 0.0.11j
  82 *      20000516 Removed unnecessary spinlock in mts_transfer_context (john)
  83 *      20000516 Removed unnecessary up on instance lock in mts_remove_nolock (john)
  84 *      20000516 Implemented (badly) scsi_abort (john)
  85 *      20000516 Version 0.0.12j
  86 *      20000517 Hopefully removed mts_remove_nolock quasideadlock (john)
  87 *      20000517 Added mts_debug_dump to print ll USB info (john)
  88 *      20000518 Tweaks and documentation updates (john)
  89 *      20000518 Version 0.0.13j
  90 *      20000518 Cleaned up abort handling (john)
  91 *      20000523 Removed scsi_command and various scsi_..._resets (john)
  92 *      20000523 Added unlink URB on scsi_abort, now OHCI supports it (john)
  93 *      20000523 Fixed last tiresome compile warning (john)
  94 *      20000523 Version 0.0.14j (though version 0.1 has come out?)
  95 *      20000602 Added primitive reset
  96 *      20000602 Version 0.2.0
  97 *      20000603 various cosmetic changes
  98 *      20000603 Version 0.2.1
  99 *      20000620 minor cosmetic changes
 100 *      20000620 Version 0.2.2
 101 *      20000822 Hopefully fixed deadlock in mts_remove_nolock()
 102 *      20000822 Fixed minor race in mts_transfer_cleanup()
 103 *      20000822 Fixed deadlock on submission error in queuecommand
 104 *      20000822 Version 0.2.3
 105 *      20000913 Reduced module size if debugging is off
 106 *      20000913 Version 0.2.4
 107 *      20010210 New abort logic
 108 *      20010210 Version 0.3.0
 109 *      20010217 Merged scatter/gather
 110 *      20010218 Version 0.4.0
 111 *      20010218 Cosmetic fixes
 112 *      20010218 Version 0.4.1
 113 *      20010306 Abort while using scatter/gather
 114 *      20010306 Version 0.4.2
 115 *      20010311 Remove all timeouts and tidy up generally (john)
 116 *      20010320 check return value of scsi_register()
 117 *      20010320 Version 0.4.3
 118 *      20010408 Identify version on module load.
 119 *      20011003 Fix multiple requests
 120 *      20020618 Version 0.4.4
 121 *      20020618 Confirm to utterly stupid rules about io_request_lock
 122 */
 123
 124#include <linux/module.h>
 125#include <linux/kernel.h>
 126#include <linux/sched.h>
 127#include <linux/signal.h>
 128#include <linux/errno.h>
 129#include <linux/random.h>
 130#include <linux/poll.h>
 131#include <linux/init.h>
 132#include <linux/slab.h>
 133#include <linux/spinlock.h>
 134#include <linux/smp_lock.h>
 135#include <linux/usb.h>
 136#include <linux/proc_fs.h>
 137
 138#include <asm/atomic.h>
 139#include <linux/blk.h>
 140#include "../scsi/scsi.h"
 141#include "../scsi/hosts.h"
 142#include "../scsi/sd.h"
 143
 144#include "microtek.h"
 145
 146/*
 147 * Version Information
 148 */
 149#define DRIVER_VERSION "v0.4.4"
 150#define DRIVER_AUTHOR "John Fremlin <vii@penguinpowered.com>, Oliver Neukum <Oliver.Neukum@lrz.uni-muenchen.de>"
 151#define DRIVER_DESC "Microtek Scanmaker X6 USB scanner driver"
 152
 153/* Should we do debugging? */
 154
 155//#define MTS_DO_DEBUG
 156
 157/* USB layer driver interface */
 158
 159static void *mts_usb_probe(struct usb_device *dev, unsigned int interface,
 160                         const struct usb_device_id *id);
 161static void mts_usb_disconnect(struct usb_device *dev, void *ptr);
 162
 163static struct usb_device_id mts_usb_ids [];
 164
 165static struct usb_driver mts_usb_driver = {
 166        name:           "microtekX6",
 167        probe:          mts_usb_probe,
 168        disconnect:     mts_usb_disconnect,
 169        id_table:       mts_usb_ids,
 170};
 171
 172
 173/* Internal driver stuff */
 174
 175#define MTS_VERSION     "0.4.3"
 176#define MTS_NAME        "microtek usb (rev " MTS_VERSION "): "
 177
 178#define MTS_WARNING(x...) \
 179        printk( KERN_WARNING MTS_NAME x )
 180#define MTS_ERROR(x...) \
 181        printk( KERN_ERR MTS_NAME x )
 182#define MTS_INT_ERROR(x...) \
 183        MTS_ERROR(x)
 184#define MTS_MESSAGE(x...) \
 185        printk( KERN_INFO MTS_NAME x )
 186
 187#if defined MTS_DO_DEBUG
 188
 189#define MTS_DEBUG(x...) \
 190        printk( KERN_DEBUG MTS_NAME x )
 191
 192#define MTS_DEBUG_GOT_HERE() \
 193        MTS_DEBUG("got to %s:%d (%s)\n", __FILE__, (int)__LINE__, __PRETTY_FUNCTION__ )
 194#define MTS_DEBUG_INT() \
 195        do { MTS_DEBUG_GOT_HERE(); \
 196             MTS_DEBUG("transfer = 0x%x context = 0x%x\n",(int)transfer,(int)context ); \
 197             MTS_DEBUG("status = 0x%x data-length = 0x%x sent = 0x%x\n",(int)transfer->status,(int)context->data_length, (int)transfer->actual_length ); \
 198             mts_debug_dump(context->instance);\
 199           } while(0)
 200#else
 201
 202#define MTS_NUL_STATEMENT do { } while(0)
 203
 204#define MTS_DEBUG(x...) MTS_NUL_STATEMENT
 205#define MTS_DEBUG_GOT_HERE() MTS_NUL_STATEMENT
 206#define MTS_DEBUG_INT() MTS_NUL_STATEMENT
 207
 208#endif
 209
 210
 211
 212#define MTS_INT_INIT()\
 213        struct mts_transfer_context* context = (struct mts_transfer_context*)transfer->context; \
 214        MTS_DEBUG_INT();\
 215
 216#ifdef MTS_DO_DEBUG
 217
 218static inline void mts_debug_dump(struct mts_desc* desc) {
 219        MTS_DEBUG("desc at 0x%x: halted = %02x%02x, toggle = %02x%02x\n",
 220                  (int)desc,(int)desc->usb_dev->halted[1],(int)desc->usb_dev->halted[0],
 221                  (int)desc->usb_dev->toggle[1],(int)desc->usb_dev->toggle[0]
 222                );
 223        MTS_DEBUG("ep_out=%x ep_response=%x ep_image=%x\n",
 224                  usb_sndbulkpipe(desc->usb_dev,desc->ep_out),
 225                  usb_rcvbulkpipe(desc->usb_dev,desc->ep_response),
 226                  usb_rcvbulkpipe(desc->usb_dev,desc->ep_image)
 227                );
 228}
 229
 230
 231static inline void mts_show_command(Scsi_Cmnd *srb)
 232{
 233        char *what = NULL;
 234
 235        switch (srb->cmnd[0]) {
 236        case TEST_UNIT_READY: what = "TEST_UNIT_READY"; break;
 237        case REZERO_UNIT: what = "REZERO_UNIT"; break;
 238        case REQUEST_SENSE: what = "REQUEST_SENSE"; break;
 239        case FORMAT_UNIT: what = "FORMAT_UNIT"; break;
 240        case READ_BLOCK_LIMITS: what = "READ_BLOCK_LIMITS"; break;
 241        case REASSIGN_BLOCKS: what = "REASSIGN_BLOCKS"; break;
 242        case READ_6: what = "READ_6"; break;
 243        case WRITE_6: what = "WRITE_6"; break;
 244        case SEEK_6: what = "SEEK_6"; break;
 245        case READ_REVERSE: what = "READ_REVERSE"; break;
 246        case WRITE_FILEMARKS: what = "WRITE_FILEMARKS"; break;
 247        case SPACE: what = "SPACE"; break;
 248        case INQUIRY: what = "INQUIRY"; break;
 249        case RECOVER_BUFFERED_DATA: what = "RECOVER_BUFFERED_DATA"; break;
 250        case MODE_SELECT: what = "MODE_SELECT"; break;
 251        case RESERVE: what = "RESERVE"; break;
 252        case RELEASE: what = "RELEASE"; break;
 253        case COPY: what = "COPY"; break;
 254        case ERASE: what = "ERASE"; break;
 255        case MODE_SENSE: what = "MODE_SENSE"; break;
 256        case START_STOP: what = "START_STOP"; break;
 257        case RECEIVE_DIAGNOSTIC: what = "RECEIVE_DIAGNOSTIC"; break;
 258        case SEND_DIAGNOSTIC: what = "SEND_DIAGNOSTIC"; break;
 259        case ALLOW_MEDIUM_REMOVAL: what = "ALLOW_MEDIUM_REMOVAL"; break;
 260        case SET_WINDOW: what = "SET_WINDOW"; break;
 261        case READ_CAPACITY: what = "READ_CAPACITY"; break;
 262        case READ_10: what = "READ_10"; break;
 263        case WRITE_10: what = "WRITE_10"; break;
 264        case SEEK_10: what = "SEEK_10"; break;
 265        case WRITE_VERIFY: what = "WRITE_VERIFY"; break;
 266        case VERIFY: what = "VERIFY"; break;
 267        case SEARCH_HIGH: what = "SEARCH_HIGH"; break;
 268        case SEARCH_EQUAL: what = "SEARCH_EQUAL"; break;
 269        case SEARCH_LOW: what = "SEARCH_LOW"; break;
 270        case SET_LIMITS: what = "SET_LIMITS"; break;
 271        case READ_POSITION: what = "READ_POSITION"; break;
 272        case SYNCHRONIZE_CACHE: what = "SYNCHRONIZE_CACHE"; break;
 273        case LOCK_UNLOCK_CACHE: what = "LOCK_UNLOCK_CACHE"; break;
 274        case READ_DEFECT_DATA: what = "READ_DEFECT_DATA"; break;
 275        case MEDIUM_SCAN: what = "MEDIUM_SCAN"; break;
 276        case COMPARE: what = "COMPARE"; break;
 277        case COPY_VERIFY: what = "COPY_VERIFY"; break;
 278        case WRITE_BUFFER: what = "WRITE_BUFFER"; break;
 279        case READ_BUFFER: what = "READ_BUFFER"; break;
 280        case UPDATE_BLOCK: what = "UPDATE_BLOCK"; break;
 281        case READ_LONG: what = "READ_LONG"; break;
 282        case WRITE_LONG: what = "WRITE_LONG"; break;
 283        case CHANGE_DEFINITION: what = "CHANGE_DEFINITION"; break;
 284        case WRITE_SAME: what = "WRITE_SAME"; break;
 285        case READ_TOC: what = "READ_TOC"; break;
 286        case LOG_SELECT: what = "LOG_SELECT"; break;
 287        case LOG_SENSE: what = "LOG_SENSE"; break;
 288        case MODE_SELECT_10: what = "MODE_SELECT_10"; break;
 289        case MODE_SENSE_10: what = "MODE_SENSE_10"; break;
 290        case MOVE_MEDIUM: what = "MOVE_MEDIUM"; break;
 291        case READ_12: what = "READ_12"; break;
 292        case WRITE_12: what = "WRITE_12"; break;
 293        case WRITE_VERIFY_12: what = "WRITE_VERIFY_12"; break;
 294        case SEARCH_HIGH_12: what = "SEARCH_HIGH_12"; break;
 295        case SEARCH_EQUAL_12: what = "SEARCH_EQUAL_12"; break;
 296        case SEARCH_LOW_12: what = "SEARCH_LOW_12"; break;
 297        case READ_ELEMENT_STATUS: what = "READ_ELEMENT_STATUS"; break;
 298        case SEND_VOLUME_TAG: what = "SEND_VOLUME_TAG"; break;
 299        case WRITE_LONG_2: what = "WRITE_LONG_2"; break;
 300        default:
 301                MTS_DEBUG("can't decode command\n");
 302                goto out;
 303                break;
 304        }
 305        MTS_DEBUG( "Command %s (%d bytes)\n", what, srb->cmd_len);
 306
 307 out:
 308        MTS_DEBUG( "  %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
 309               srb->cmnd[0], srb->cmnd[1], srb->cmnd[2], srb->cmnd[3], srb->cmnd[4], srb->cmnd[5],
 310               srb->cmnd[6], srb->cmnd[7], srb->cmnd[8], srb->cmnd[9]);
 311}
 312
 313#else
 314
 315static inline void mts_show_command(Scsi_Cmnd * dummy)
 316{
 317}
 318
 319static inline void mts_debug_dump(struct mts_desc* dummy)
 320{
 321}
 322
 323#endif
 324
 325
 326/* static inline int mts_is_aborting(struct mts_desc* desc) {
 327        return (atomic_read(&desc->context.do_abort));
 328}  */
 329
 330static inline void mts_urb_abort(struct mts_desc* desc) {
 331        spin_unlock_irq(&io_request_lock);
 332        MTS_DEBUG_GOT_HERE();
 333        mts_debug_dump(desc);
 334
 335        usb_unlink_urb( &desc->urb );
 336        spin_lock_irq(&io_request_lock);
 337}
 338
 339static struct mts_desc * mts_list; /* list of active scanners */
 340struct semaphore mts_list_semaphore;
 341
 342/* Internal list operations */
 343
 344static
 345void mts_remove_nolock( struct mts_desc* to_remove )
 346{
 347        MTS_DEBUG( "removing 0x%x from list\n",
 348                   (int)to_remove );
 349
 350        lock_kernel();
 351        mts_urb_abort(to_remove);
 352
 353        MTS_DEBUG_GOT_HERE();
 354
 355        if ( to_remove != mts_list ) {
 356                MTS_DEBUG_GOT_HERE();
 357                if (to_remove->prev && to_remove->next)
 358                        to_remove->prev->next = to_remove->next;
 359        } else {
 360                MTS_DEBUG_GOT_HERE();
 361                mts_list = to_remove->next;
 362                if (mts_list) {
 363                        MTS_DEBUG_GOT_HERE();
 364                        mts_list->prev = 0;
 365                }
 366        }
 367
 368        if ( to_remove->next ) {
 369                MTS_DEBUG_GOT_HERE();
 370                to_remove->next->prev = to_remove->prev;
 371        }
 372
 373        MTS_DEBUG_GOT_HERE();
 374        scsi_unregister_module(MODULE_SCSI_HA, &(to_remove->ctempl));
 375        unlock_kernel();
 376
 377        kfree( to_remove );
 378}
 379
 380static
 381void mts_add_nolock( struct mts_desc* to_add )
 382{
 383        MTS_DEBUG( "adding 0x%x to list\n", (int)to_add );
 384
 385        to_add->prev = 0;
 386        to_add->next = mts_list;
 387        if ( mts_list ) {
 388                mts_list->prev = to_add;
 389        }
 390
 391        mts_list = to_add;
 392}
 393
 394
 395
 396
 397/* SCSI driver interface */
 398
 399/* scsi related functions - dummies for now mostly */
 400
 401static int mts_scsi_release(struct Scsi_Host *psh)
 402{
 403        MTS_DEBUG_GOT_HERE();
 404
 405        return 0;
 406}
 407
 408static int mts_scsi_abort (Scsi_Cmnd *srb)
 409{
 410        struct mts_desc* desc = (struct mts_desc*)(srb->host->hostdata[0]);
 411
 412        MTS_DEBUG_GOT_HERE();
 413
 414        mts_urb_abort(desc);
 415
 416        return SCSI_ABORT_PENDING;
 417}
 418
 419static int mts_scsi_host_reset (Scsi_Cmnd *srb)
 420{
 421
 422        struct mts_desc* desc = (struct mts_desc*)(srb->host->hostdata[0]);
 423        spin_unlock_irq(&io_request_lock);
 424        MTS_DEBUG_GOT_HERE();
 425        mts_debug_dump(desc);
 426
 427        usb_reset_device(desc->usb_dev); /*FIXME: untested on new reset code */
 428        spin_lock_irq(&io_request_lock);
 429        return 0;  /* RANT why here 0 and not SUCCESS */
 430}
 431
 432/* the core of the scsi part */
 433
 434/* faking a detection - which can't fail :-) */
 435
 436static int mts_scsi_detect (struct SHT * sht)
 437{
 438        /* Whole function stolen from usb-storage */
 439
 440        struct mts_desc * desc = (struct mts_desc *)sht->proc_dir;
 441        /* What a hideous hack! */
 442
 443        char local_name[48];
 444        spin_unlock_irq(&io_request_lock);
 445
 446        MTS_DEBUG_GOT_HERE();
 447
 448        /* set up the name of our subdirectory under /proc/scsi/ */
 449        sprintf(local_name, "microtek-%d", desc->host_number);
 450        sht->proc_name = kmalloc (strlen(local_name) + 1, GFP_KERNEL);
 451        /* FIXME: where is this freed ? */
 452
 453        if (!sht->proc_name) {
 454                MTS_ERROR( "unable to allocate memory for proc interface!!\n" );
 455                spin_lock_irq(&io_request_lock);
 456                return 0;
 457        }
 458
 459        strcpy(sht->proc_name, local_name);
 460
 461        sht->proc_dir = NULL;
 462
 463        /* In host->hostdata we store a pointer to desc */
 464        desc->host = scsi_register(sht, sizeof(desc));
 465        if (desc->host == NULL) {
 466                MTS_ERROR("Cannot register due to low memory");
 467                kfree(sht->proc_name);
 468                spin_lock_irq(&io_request_lock);
 469                return 0;
 470        }
 471        desc->host->hostdata[0] = (unsigned long)desc;
 472/* FIXME: what if sizeof(void*) != sizeof(unsigned long)? */
 473        spin_lock_irq(&io_request_lock);
 474        return 1;
 475}
 476
 477
 478
 479/* Main entrypoint: SCSI commands are dispatched to here */
 480
 481
 482
 483static
 484int mts_scsi_queuecommand (Scsi_Cmnd *srb, mts_scsi_cmnd_callback callback );
 485
 486static void mts_transfer_cleanup( struct urb *transfer );
 487static void mts_do_sg(struct urb * transfer);
 488
 489
 490inline static
 491void mts_int_submit_urb (struct urb* transfer,
 492                        int pipe,
 493                        void* data,
 494                        unsigned length,
 495                        mts_usb_urb_callback callback )
 496/* Interrupt context! */
 497
 498/* Holding transfer->context->lock! */
 499{
 500        int res;
 501
 502        MTS_INT_INIT();
 503
 504        FILL_BULK_URB(transfer,
 505                      context->instance->usb_dev,
 506                      pipe,
 507                      data,
 508                      length,
 509                      callback,
 510                      context
 511                );
 512
 513        transfer->status = 0;
 514
 515        res = usb_submit_urb( transfer );
 516        if ( res ) {
 517                MTS_INT_ERROR( "could not submit URB! Error was %d\n",(int)res );
 518                context->srb->result = DID_ERROR << 16;
 519                mts_transfer_cleanup(transfer);
 520        }
 521        return;
 522}
 523
 524
 525static void mts_transfer_cleanup( struct urb *transfer )
 526/* Interrupt context! */
 527{
 528        MTS_INT_INIT();
 529
 530        if ( context->final_callback )
 531                context->final_callback(context->srb);
 532
 533}
 534
 535static void mts_transfer_done( struct urb *transfer )
 536{
 537        MTS_INT_INIT();
 538
 539        context->srb->result &= MTS_SCSI_ERR_MASK;
 540        context->srb->result |= (unsigned)context->status<<1;
 541
 542        mts_transfer_cleanup(transfer);
 543
 544        return;
 545}
 546
 547
 548static void mts_get_status( struct urb *transfer )
 549/* Interrupt context! */
 550{
 551        MTS_INT_INIT();
 552
 553        mts_int_submit_urb(transfer,
 554                           usb_rcvbulkpipe(context->instance->usb_dev,
 555                                           context->instance->ep_response),
 556                           &context->status,
 557                           1,
 558                           mts_transfer_done );
 559}
 560
 561static void mts_data_done( struct urb* transfer )
 562/* Interrupt context! */
 563{
 564        MTS_INT_INIT();
 565
 566        if ( context->data_length != transfer->actual_length ) {
 567                context->srb->resid = context->data_length - transfer->actual_length;
 568        } else if ( transfer->status ) {
 569                context->srb->result = (transfer->status == -ENOENT ? DID_ABORT : DID_ERROR)<<16;
 570        }
 571
 572        mts_get_status(transfer);
 573
 574        return;
 575}
 576
 577
 578static void mts_command_done( struct urb *transfer )
 579/* Interrupt context! */
 580{
 581        MTS_INT_INIT();
 582
 583        if ( transfer->status ) {
 584                if (transfer->status == -ENOENT) {
 585                        /* We are being killed */
 586                        MTS_DEBUG_GOT_HERE();
 587                        context->srb->result = DID_ABORT<<16;
 588                } else {
 589                        /* A genuine error has occured */
 590                        MTS_DEBUG_GOT_HERE();
 591
 592                        context->srb->result = DID_ERROR<<16;
 593                }
 594                mts_transfer_cleanup(transfer);
 595
 596                return;
 597        }
 598
 599        if ( context->data ) {
 600                mts_int_submit_urb(transfer,
 601                                   context->data_pipe,
 602                                   context->data,
 603                                   context->data_length,
 604                                   context->srb->use_sg ? mts_do_sg : mts_data_done);
 605        } else mts_get_status(transfer);
 606
 607        return;
 608}
 609
 610static void mts_do_sg (struct urb* transfer)
 611{
 612        struct scatterlist * sg;
 613        MTS_INT_INIT();
 614        
 615        MTS_DEBUG("Processing fragment %d of %d\n", context->fragment,context->srb->use_sg);
 616
 617        if (transfer->status) {
 618                context->srb->result = (transfer->status == -ENOENT ? DID_ABORT : DID_ERROR)<<16;
 619                mts_transfer_cleanup(transfer);
 620        }
 621
 622        sg = context->srb->buffer;
 623        context->fragment++;
 624        mts_int_submit_urb(transfer,
 625                        context->data_pipe,
 626                        sg[context->fragment].address,
 627                        sg[context->fragment].length,
 628                        context->fragment + 1 == context->srb->use_sg ? mts_data_done : mts_do_sg);
 629        return;
 630}
 631
 632static const u8 mts_read_image_sig[] = { 0x28, 00, 00, 00 };
 633static const u8 mts_read_image_sig_len = 4;
 634static const unsigned char mts_direction[256/8] = {
 635        0x28, 0x81, 0x14, 0x14, 0x20, 0x01, 0x90, 0x77,
 636        0x0C, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
 637        0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,
 638        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 639};
 640
 641
 642#define MTS_DIRECTION_IS_IN(x) ((mts_direction[x>>3] >> (x & 7)) & 1)
 643
 644static void
 645mts_build_transfer_context( Scsi_Cmnd *srb, struct mts_desc* desc )
 646{
 647        int pipe;
 648        struct scatterlist * sg;
 649        
 650        MTS_DEBUG_GOT_HERE();
 651
 652        desc->context.instance = desc;
 653        desc->context.srb = srb;
 654        desc->context.fragment = 0;
 655
 656        if (!srb->use_sg) {
 657                if ( !srb->bufflen ){
 658                        desc->context.data = 0;
 659                        desc->context.data_length = 0;
 660                        return;
 661                } else {
 662                        desc->context.data = srb->buffer;
 663                        desc->context.data_length = srb->bufflen;
 664                        MTS_DEBUG("length = %d or %d\n",
 665                                  srb->request_bufflen, srb->bufflen);
 666                }
 667        } else {
 668                MTS_DEBUG("Using scatter/gather\n");
 669                sg = srb->buffer;
 670                desc->context.data = sg[0].address;
 671                desc->context.data_length = sg[0].length;
 672        }
 673
 674
 675        /* can't rely on srb->sc_data_direction */
 676
 677        /* Brutally ripped from usb-storage */
 678
 679        if ( !memcmp( srb->cmnd, mts_read_image_sig, mts_read_image_sig_len )
 680) {             pipe = usb_rcvbulkpipe(desc->usb_dev,desc->ep_image);
 681                MTS_DEBUG( "transfering from desc->ep_image == %d\n",
 682                           (int)desc->ep_image );
 683        } else if ( MTS_DIRECTION_IS_IN(srb->cmnd[0]) ) {
 684                        pipe = usb_rcvbulkpipe(desc->usb_dev,desc->ep_response);
 685                        MTS_DEBUG( "transfering from desc->ep_response == %d\n",
 686                                   (int)desc->ep_response);
 687        } else {
 688                MTS_DEBUG("transfering to desc->ep_out == %d\n",
 689                          (int)desc->ep_out);
 690                pipe = usb_sndbulkpipe(desc->usb_dev,desc->ep_out);
 691        }
 692        desc->context.data_pipe = pipe;
 693}
 694
 695
 696static
 697int mts_scsi_queuecommand( Scsi_Cmnd *srb, mts_scsi_cmnd_callback callback )
 698{
 699        struct mts_desc* desc = (struct mts_desc*)(srb->host->hostdata[0]);
 700        int err = 0;
 701        int res;
 702
 703        MTS_DEBUG_GOT_HERE();
 704        mts_show_command(srb);
 705        mts_debug_dump(desc);
 706
 707        if ( srb->device->lun || srb->device->id || srb->device->channel ) {
 708
 709                MTS_DEBUG("Command to LUN=%d ID=%d CHANNEL=%d from SCSI layer\n",(int)srb->device->lun,(int)srb->device->id, (int)srb->device->channel );
 710
 711                MTS_DEBUG("this device doesn't exist\n");
 712
 713                srb->result = DID_BAD_TARGET << 16;
 714
 715                if(callback)
 716                        callback(srb);
 717
 718                goto out;
 719        }
 720
 721        
 722        FILL_BULK_URB(&desc->urb,
 723                      desc->usb_dev,
 724                      usb_sndbulkpipe(desc->usb_dev,desc->ep_out),
 725                      srb->cmnd,
 726                      srb->cmd_len,
 727                      mts_command_done,
 728                      &desc->context
 729                      );
 730
 731
 732        mts_build_transfer_context( srb, desc );
 733        desc->context.final_callback = callback;
 734        
 735        res=usb_submit_urb(&desc->urb);
 736
 737        if(res){
 738                MTS_ERROR("error %d submitting URB\n",(int)res);
 739                srb->result = DID_ERROR << 16;
 740
 741                if(callback)
 742                        callback(srb);
 743
 744        }
 745
 746out:
 747        return err;
 748}
 749/*
 750 * this defines our 'host'
 751 */
 752
 753/* NOTE: This is taken from usb-storage, should be right. */
 754
 755
 756static Scsi_Host_Template mts_scsi_host_template = {
 757        name:           "microtekX6",
 758        detect:         mts_scsi_detect,
 759        release:        mts_scsi_release,
 760        queuecommand:   mts_scsi_queuecommand,
 761
 762        eh_abort_handler:       mts_scsi_abort,
 763        eh_host_reset_handler:  mts_scsi_host_reset,
 764
 765        sg_tablesize:           SG_ALL,
 766        can_queue:              1,
 767        this_id:                -1,
 768        cmd_per_lun:            1,
 769        present:                0,
 770        unchecked_isa_dma:      FALSE,
 771        use_clustering:         TRUE,
 772        use_new_eh_code:        TRUE,
 773        emulated:               TRUE
 774};
 775
 776
 777/* USB layer driver interface implementation */
 778
 779static void mts_usb_disconnect (struct usb_device *dev, void *ptr)
 780{
 781        struct mts_desc* to_remove = (struct mts_desc*)ptr;
 782
 783        MTS_DEBUG_GOT_HERE();
 784
 785        /* leave the list - lock it */
 786        down(&mts_list_semaphore);
 787
 788        mts_remove_nolock(to_remove);
 789
 790        up(&mts_list_semaphore);
 791}
 792
 793struct vendor_product
 794{
 795        char* name;
 796        enum
 797        {
 798                mts_sup_unknown=0,
 799                mts_sup_alpha,
 800                mts_sup_full
 801        }
 802        support_status;
 803} ;
 804
 805
 806/* These are taken from the msmUSB.inf file on the Windows driver CD */
 807const static struct vendor_product mts_supported_products[] =
 808{
 809        { "Phantom 336CX",      mts_sup_unknown},
 810        { "Phantom 336CX",      mts_sup_unknown},
 811        { "Scanmaker X6",       mts_sup_alpha},
 812        { "Phantom C6",         mts_sup_unknown},
 813        { "Phantom 336CX",      mts_sup_unknown},
 814        { "ScanMaker V6USL",    mts_sup_unknown},
 815        { "ScanMaker V6USL",    mts_sup_unknown},
 816        { "Scanmaker V6UL",     mts_sup_unknown},
 817        { "Scanmaker V6UPL",    mts_sup_alpha},
 818};
 819
 820/* The entries of microtek_table must correspond, line-by-line to
 821   the entries of mts_supported_products[]. */
 822
 823static struct usb_device_id mts_usb_ids [] =
 824{
 825        { USB_DEVICE(0x4ce, 0x0300) },
 826        { USB_DEVICE(0x5da, 0x0094) },
 827        { USB_DEVICE(0x5da, 0x0099) },
 828        { USB_DEVICE(0x5da, 0x009a) },
 829        { USB_DEVICE(0x5da, 0x00a0) },
 830        { USB_DEVICE(0x5da, 0x00a3) },
 831        { USB_DEVICE(0x5da, 0x80a3) },
 832        { USB_DEVICE(0x5da, 0x80ac) },
 833        { USB_DEVICE(0x5da, 0x00b6) },
 834        { }                                             /* Terminating entry */
 835};
 836
 837MODULE_DEVICE_TABLE (usb, mts_usb_ids);
 838
 839
 840static void * mts_usb_probe (struct usb_device *dev, unsigned int interface,
 841                             const struct usb_device_id *id)
 842{
 843        int i;
 844        int result;
 845        int ep_out = -1;
 846        int ep_in_set[3]; /* this will break if we have more than three endpoints
 847                           which is why we check */
 848        int *ep_in_current = ep_in_set;
 849
 850        struct mts_desc * new_desc;
 851        struct vendor_product const* p;
 852
 853        /* the altsettting 0 on the interface we're probing */
 854        struct usb_interface_descriptor *altsetting;
 855
 856        MTS_DEBUG_GOT_HERE();
 857        MTS_DEBUG( "usb-device descriptor at %x\n", (int)dev );
 858
 859        MTS_DEBUG( "product id = 0x%x, vendor id = 0x%x\n",
 860                   (int)dev->descriptor.idProduct,
 861                   (int)dev->descriptor.idVendor );
 862
 863        MTS_DEBUG_GOT_HERE();
 864
 865        p = &mts_supported_products[id - mts_usb_ids];
 866
 867        MTS_DEBUG_GOT_HERE();
 868
 869        MTS_DEBUG( "found model %s\n", p->name );
 870        if ( p->support_status != mts_sup_full )
 871                MTS_MESSAGE( "model %s is not known to be fully supported, reports welcome!\n",
 872                             p->name );
 873
 874        /* the altsettting 0 on the interface we're probing */
 875        altsetting =
 876                &(dev->actconfig->interface[interface].altsetting[0]);
 877
 878
 879        /* Check if the config is sane */
 880
 881        if ( altsetting->bNumEndpoints != MTS_EP_TOTAL ) {
 882                MTS_WARNING( "expecting %d got %d endpoints! Bailing out.\n",
 883                             (int)MTS_EP_TOTAL, (int)altsetting->bNumEndpoints );
 884                return NULL;
 885        }
 886
 887        for( i = 0; i < altsetting->bNumEndpoints; i++ ) {
 888                if ((altsetting->endpoint[i].bmAttributes &
 889                     USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK) {
 890
 891                        MTS_WARNING( "can only deal with bulk endpoints; endpoint %d is not bulk.\n",
 892                             (int)altsetting->endpoint[i].bEndpointAddress );
 893                } else {
 894                        if (altsetting->endpoint[i].bEndpointAddress &
 895                            USB_DIR_IN)
 896                                *ep_in_current++
 897                                        = altsetting->endpoint[i].bEndpointAddress &
 898                                        USB_ENDPOINT_NUMBER_MASK;
 899                        else {
 900                                if ( ep_out != -1 ) {
 901                                        MTS_WARNING( "can only deal with one output endpoints. Bailing out." );
 902                                        return NULL;
 903                                }
 904
 905                                ep_out = altsetting->endpoint[i].bEndpointAddress &
 906                                        USB_ENDPOINT_NUMBER_MASK;
 907                        }
 908                }
 909
 910        }
 911
 912
 913        if ( ep_out == -1 ) {
 914                MTS_WARNING( "couldn't find an output bulk endpoint. Bailing out.\n" );
 915                return NULL;
 916        }
 917
 918
 919        /* I don't understand the following fully (it's from usb-storage) -- John */
 920
 921        /* set the interface -- STALL is an acceptable response here */
 922        result = usb_set_interface(dev, altsetting->bInterfaceNumber, 0);
 923
 924        MTS_DEBUG("usb_set_interface returned %d.\n",result);
 925        switch( result )
 926        {
 927        case 0: /* no error */
 928                break;
 929                
 930        case -EPIPE:
 931                usb_clear_halt(dev, usb_sndctrlpipe(dev, 0));
 932                MTS_DEBUG( "clearing clearing stall on control interface\n" );
 933                break;
 934                
 935        default:
 936                MTS_DEBUG( "unknown error %d from usb_set_interface\n",
 937                        (int)result );
 938                return NULL;
 939        }
 940        
 941        
 942        /* allocating a new descriptor */
 943        new_desc = (struct mts_desc *)kmalloc(sizeof(struct mts_desc), GFP_KERNEL);
 944        if (new_desc == NULL)
 945        {
 946                MTS_ERROR("couldn't allocate scanner desc, bailing out!\n");
 947                return NULL;
 948        }
 949
 950        /* As done by usb_alloc_urb */
 951        memset( new_desc, 0, sizeof(*new_desc) );
 952        spin_lock_init(&new_desc->urb.lock);
 953        
 954                
 955        /* initialising that descriptor */
 956        new_desc->usb_dev = dev;
 957        new_desc->interface = interface;
 958
 959        init_MUTEX(&new_desc->lock);
 960
 961        if(mts_list){
 962                new_desc->host_number = mts_list->host_number+1;
 963        } else {
 964                new_desc->host_number = 0;
 965        }
 966        
 967        /* endpoints */
 968        
 969        new_desc->ep_out = ep_out;
 970        new_desc->ep_response = ep_in_set[0];
 971        new_desc->ep_image = ep_in_set[1];
 972
 973
 974        if ( new_desc->ep_out != MTS_EP_OUT )
 975                MTS_WARNING( "will this work? Command EP is not usually %d\n",
 976                             (int)new_desc->ep_out );
 977
 978        if ( new_desc->ep_response != MTS_EP_RESPONSE )
 979                MTS_WARNING( "will this work? Response EP is not usually %d\n",
 980                             (int)new_desc->ep_response );
 981
 982        if ( new_desc->ep_image != MTS_EP_IMAGE )
 983                MTS_WARNING( "will this work? Image data EP is not usually %d\n",
 984                             (int)new_desc->ep_image );
 985
 986
 987        /* Initialize the host template based on the default one */
 988        memcpy(&(new_desc->ctempl), &mts_scsi_host_template, sizeof(mts_scsi_host_template));
 989        /* HACK from usb-storage - this is needed for scsi detection */
 990        new_desc->ctempl.proc_dir = (void *)new_desc; /* FIXME */
 991
 992        MTS_DEBUG("registering SCSI module\n");
 993
 994        new_desc->ctempl.module = THIS_MODULE;
 995        result = scsi_register_module(MODULE_SCSI_HA, &(new_desc->ctempl));
 996        /* Will get hit back in microtek_detect by this func */
 997        if ( result )
 998        {
 999                MTS_ERROR( "error %d from scsi_register_module! Help!\n",
1000                           (int)result );
1001
1002                /* FIXME: need more cleanup? */
1003                kfree( new_desc );
1004                return NULL;
1005        }
1006        MTS_DEBUG_GOT_HERE();
1007
1008        /* FIXME: the bomb is armed, must the host be registered under lock ? */
1009        /* join the list - lock it */
1010        down(&mts_list_semaphore);
1011
1012        mts_add_nolock( new_desc );
1013
1014        up(&mts_list_semaphore);
1015
1016
1017        MTS_DEBUG("completed probe and exiting happily\n");
1018
1019        return (void *)new_desc;
1020}
1021
1022
1023
1024/* get us noticed by the rest of the kernel */
1025
1026int __init microtek_drv_init(void)
1027{
1028        int result;
1029
1030        MTS_DEBUG_GOT_HERE();
1031        init_MUTEX(&mts_list_semaphore);
1032
1033        if ((result = usb_register(&mts_usb_driver)) < 0) {
1034                MTS_DEBUG("usb_register returned %d\n", result );
1035                return -1;
1036        } else {
1037                MTS_DEBUG("driver registered.\n");
1038        }
1039
1040        info(DRIVER_VERSION ":" DRIVER_DESC);
1041
1042        return 0;
1043}
1044
1045void __exit microtek_drv_exit(void)
1046{
1047        struct mts_desc* next;
1048
1049        MTS_DEBUG_GOT_HERE();
1050
1051        usb_deregister(&mts_usb_driver);
1052
1053        down(&mts_list_semaphore);
1054
1055        while (mts_list) {
1056                /* keep track of where the next one is */
1057                next = mts_list->next;
1058
1059                mts_remove_nolock( mts_list );
1060
1061                /* advance the list pointer */
1062                mts_list = next;
1063        }
1064
1065        up(&mts_list_semaphore);
1066}
1067
1068module_init(microtek_drv_init);
1069module_exit(microtek_drv_exit);
1070
1071MODULE_AUTHOR( DRIVER_AUTHOR );
1072MODULE_DESCRIPTION( DRIVER_DESC );
1073MODULE_LICENSE("GPL");
1074
1075
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.