linux/drivers/usb/image/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 */
 121
 122#include <linux/module.h>
 123#include <linux/kernel.h>
 124#include <linux/signal.h>
 125#include <linux/errno.h>
 126#include <linux/random.h>
 127#include <linux/poll.h>
 128#include <linux/init.h>
 129#include <linux/slab.h>
 130#include <linux/spinlock.h>
 131#include <linux/usb.h>
 132#include <linux/proc_fs.h>
 133
 134#include <asm/atomic.h>
 135#include <linux/blkdev.h>
 136#include "../../scsi/scsi.h"
 137#include <scsi/scsi_host.h>
 138
 139#include "microtek.h"
 140
 141/*
 142 * Version Information
 143 */
 144#define DRIVER_VERSION "v0.4.3"
 145#define DRIVER_AUTHOR "John Fremlin <vii@penguinpowered.com>, Oliver Neukum <Oliver.Neukum@lrz.uni-muenchen.de>"
 146#define DRIVER_DESC "Microtek Scanmaker X6 USB scanner driver"
 147
 148/* Should we do debugging? */
 149
 150//#define MTS_DO_DEBUG
 151
 152/* USB layer driver interface */
 153
 154static int mts_usb_probe(struct usb_interface *intf,
 155                         const struct usb_device_id *id);
 156static void mts_usb_disconnect(struct usb_interface *intf);
 157
 158static const struct usb_device_id mts_usb_ids[];
 159
 160static struct usb_driver mts_usb_driver = {
 161        .name =         "microtekX6",
 162        .probe =        mts_usb_probe,
 163        .disconnect =   mts_usb_disconnect,
 164        .id_table =     mts_usb_ids,
 165};
 166
 167
 168/* Internal driver stuff */
 169
 170#define MTS_VERSION     "0.4.3"
 171#define MTS_NAME        "microtek usb (rev " MTS_VERSION "): "
 172
 173#define MTS_WARNING(x...) \
 174        printk( KERN_WARNING MTS_NAME x )
 175#define MTS_ERROR(x...) \
 176        printk( KERN_ERR MTS_NAME x )
 177#define MTS_INT_ERROR(x...) \
 178        MTS_ERROR(x)
 179#define MTS_MESSAGE(x...) \
 180        printk( KERN_INFO MTS_NAME x )
 181
 182#if defined MTS_DO_DEBUG
 183
 184#define MTS_DEBUG(x...) \
 185        printk( KERN_DEBUG MTS_NAME x )
 186
 187#define MTS_DEBUG_GOT_HERE() \
 188        MTS_DEBUG("got to %s:%d (%s)\n", __FILE__, (int)__LINE__, __func__ )
 189#define MTS_DEBUG_INT() \
 190        do { MTS_DEBUG_GOT_HERE(); \
 191             MTS_DEBUG("transfer = 0x%x context = 0x%x\n",(int)transfer,(int)context ); \
 192             MTS_DEBUG("status = 0x%x data-length = 0x%x sent = 0x%x\n",transfer->status,(int)context->data_length, (int)transfer->actual_length ); \
 193             mts_debug_dump(context->instance);\
 194           } while(0)
 195#else
 196
 197#define MTS_NUL_STATEMENT do { } while(0)
 198
 199#define MTS_DEBUG(x...) MTS_NUL_STATEMENT
 200#define MTS_DEBUG_GOT_HERE() MTS_NUL_STATEMENT
 201#define MTS_DEBUG_INT() MTS_NUL_STATEMENT
 202
 203#endif
 204
 205
 206
 207#define MTS_INT_INIT()\
 208        struct mts_transfer_context* context = (struct mts_transfer_context*)transfer->context; \
 209        MTS_DEBUG_INT();\
 210
 211#ifdef MTS_DO_DEBUG
 212
 213static inline void mts_debug_dump(struct mts_desc* desc) {
 214        MTS_DEBUG("desc at 0x%x: toggle = %02x%02x\n",
 215                  (int)desc,
 216                  (int)desc->usb_dev->toggle[1],(int)desc->usb_dev->toggle[0]
 217                );
 218        MTS_DEBUG("ep_out=%x ep_response=%x ep_image=%x\n",
 219                  usb_sndbulkpipe(desc->usb_dev,desc->ep_out),
 220                  usb_rcvbulkpipe(desc->usb_dev,desc->ep_response),
 221                  usb_rcvbulkpipe(desc->usb_dev,desc->ep_image)
 222                );
 223}
 224
 225
 226static inline void mts_show_command(struct scsi_cmnd *srb)
 227{
 228        char *what = NULL;
 229
 230        switch (srb->cmnd[0]) {
 231        case TEST_UNIT_READY: what = "TEST_UNIT_READY"; break;
 232        case REZERO_UNIT: what = "REZERO_UNIT"; break;
 233        case REQUEST_SENSE: what = "REQUEST_SENSE"; break;
 234        case FORMAT_UNIT: what = "FORMAT_UNIT"; break;
 235        case READ_BLOCK_LIMITS: what = "READ_BLOCK_LIMITS"; break;
 236        case REASSIGN_BLOCKS: what = "REASSIGN_BLOCKS"; break;
 237        case READ_6: what = "READ_6"; break;
 238        case WRITE_6: what = "WRITE_6"; break;
 239        case SEEK_6: what = "SEEK_6"; break;
 240        case READ_REVERSE: what = "READ_REVERSE"; break;
 241        case WRITE_FILEMARKS: what = "WRITE_FILEMARKS"; break;
 242        case SPACE: what = "SPACE"; break;
 243        case INQUIRY: what = "INQUIRY"; break;
 244        case RECOVER_BUFFERED_DATA: what = "RECOVER_BUFFERED_DATA"; break;
 245        case MODE_SELECT: what = "MODE_SELECT"; break;
 246        case RESERVE: what = "RESERVE"; break;
 247        case RELEASE: what = "RELEASE"; break;
 248        case COPY: what = "COPY"; break;
 249        case ERASE: what = "ERASE"; break;
 250        case MODE_SENSE: what = "MODE_SENSE"; break;
 251        case START_STOP: what = "START_STOP"; break;
 252        case RECEIVE_DIAGNOSTIC: what = "RECEIVE_DIAGNOSTIC"; break;
 253        case SEND_DIAGNOSTIC: what = "SEND_DIAGNOSTIC"; break;
 254        case ALLOW_MEDIUM_REMOVAL: what = "ALLOW_MEDIUM_REMOVAL"; break;
 255        case SET_WINDOW: what = "SET_WINDOW"; break;
 256        case READ_CAPACITY: what = "READ_CAPACITY"; break;
 257        case READ_10: what = "READ_10"; break;
 258        case WRITE_10: what = "WRITE_10"; break;
 259        case SEEK_10: what = "SEEK_10"; break;
 260        case WRITE_VERIFY: what = "WRITE_VERIFY"; break;
 261        case VERIFY: what = "VERIFY"; break;
 262        case SEARCH_HIGH: what = "SEARCH_HIGH"; break;
 263        case SEARCH_EQUAL: what = "SEARCH_EQUAL"; break;
 264        case SEARCH_LOW: what = "SEARCH_LOW"; break;
 265        case SET_LIMITS: what = "SET_LIMITS"; break;
 266        case READ_POSITION: what = "READ_POSITION"; break;
 267        case SYNCHRONIZE_CACHE: what = "SYNCHRONIZE_CACHE"; break;
 268        case LOCK_UNLOCK_CACHE: what = "LOCK_UNLOCK_CACHE"; break;
 269        case READ_DEFECT_DATA: what = "READ_DEFECT_DATA"; break;
 270        case MEDIUM_SCAN: what = "MEDIUM_SCAN"; break;
 271        case COMPARE: what = "COMPARE"; break;
 272        case COPY_VERIFY: what = "COPY_VERIFY"; break;
 273        case WRITE_BUFFER: what = "WRITE_BUFFER"; break;
 274        case READ_BUFFER: what = "READ_BUFFER"; break;
 275        case UPDATE_BLOCK: what = "UPDATE_BLOCK"; break;
 276        case READ_LONG: what = "READ_LONG"; break;
 277        case WRITE_LONG: what = "WRITE_LONG"; break;
 278        case CHANGE_DEFINITION: what = "CHANGE_DEFINITION"; break;
 279        case WRITE_SAME: what = "WRITE_SAME"; break;
 280        case READ_TOC: what = "READ_TOC"; break;
 281        case LOG_SELECT: what = "LOG_SELECT"; break;
 282        case LOG_SENSE: what = "LOG_SENSE"; break;
 283        case MODE_SELECT_10: what = "MODE_SELECT_10"; break;
 284        case MODE_SENSE_10: what = "MODE_SENSE_10"; break;
 285        case MOVE_MEDIUM: what = "MOVE_MEDIUM"; break;
 286        case READ_12: what = "READ_12"; break;
 287        case WRITE_12: what = "WRITE_12"; break;
 288        case WRITE_VERIFY_12: what = "WRITE_VERIFY_12"; break;
 289        case SEARCH_HIGH_12: what = "SEARCH_HIGH_12"; break;
 290        case SEARCH_EQUAL_12: what = "SEARCH_EQUAL_12"; break;
 291        case SEARCH_LOW_12: what = "SEARCH_LOW_12"; break;
 292        case READ_ELEMENT_STATUS: what = "READ_ELEMENT_STATUS"; break;
 293        case SEND_VOLUME_TAG: what = "SEND_VOLUME_TAG"; break;
 294        case WRITE_LONG_2: what = "WRITE_LONG_2"; break;
 295        default:
 296                MTS_DEBUG("can't decode command\n");
 297                goto out;
 298                break;
 299        }
 300        MTS_DEBUG( "Command %s (%d bytes)\n", what, srb->cmd_len);
 301
 302 out:
 303        MTS_DEBUG( "  %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
 304               srb->cmnd[0], srb->cmnd[1], srb->cmnd[2], srb->cmnd[3], srb->cmnd[4], srb->cmnd[5],
 305               srb->cmnd[6], srb->cmnd[7], srb->cmnd[8], srb->cmnd[9]);
 306}
 307
 308#else
 309
 310static inline void mts_show_command(struct scsi_cmnd * dummy)
 311{
 312}
 313
 314static inline void mts_debug_dump(struct mts_desc* dummy)
 315{
 316}
 317
 318#endif
 319
 320static inline void mts_urb_abort(struct mts_desc* desc) {
 321        MTS_DEBUG_GOT_HERE();
 322        mts_debug_dump(desc);
 323
 324        usb_kill_urb( desc->urb );
 325}
 326
 327static int mts_slave_alloc (struct scsi_device *s)
 328{
 329        s->inquiry_len = 0x24;
 330        return 0;
 331}
 332
 333static int mts_slave_configure (struct scsi_device *s)
 334{
 335        blk_queue_dma_alignment(s->request_queue, (512 - 1));
 336        return 0;
 337}
 338
 339static int mts_scsi_abort(struct scsi_cmnd *srb)
 340{
 341        struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]);
 342
 343        MTS_DEBUG_GOT_HERE();
 344
 345        mts_urb_abort(desc);
 346
 347        return FAILED;
 348}
 349
 350static int mts_scsi_host_reset(struct scsi_cmnd *srb)
 351{
 352        struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]);
 353        int result;
 354
 355        MTS_DEBUG_GOT_HERE();
 356        mts_debug_dump(desc);
 357
 358        result = usb_lock_device_for_reset(desc->usb_dev, desc->usb_intf);
 359        if (result == 0) {
 360                result = usb_reset_device(desc->usb_dev);
 361                usb_unlock_device(desc->usb_dev);
 362        }
 363        return result ? FAILED : SUCCESS;
 364}
 365
 366static int
 367mts_scsi_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *srb);
 368
 369static void mts_transfer_cleanup( struct urb *transfer );
 370static void mts_do_sg(struct urb * transfer);
 371
 372static inline
 373void mts_int_submit_urb (struct urb* transfer,
 374                        int pipe,
 375                        void* data,
 376                        unsigned length,
 377                        usb_complete_t callback )
 378/* Interrupt context! */
 379
 380/* Holding transfer->context->lock! */
 381{
 382        int res;
 383
 384        MTS_INT_INIT();
 385
 386        usb_fill_bulk_urb(transfer,
 387                      context->instance->usb_dev,
 388                      pipe,
 389                      data,
 390                      length,
 391                      callback,
 392                      context
 393                );
 394
 395        res = usb_submit_urb( transfer, GFP_ATOMIC );
 396        if ( unlikely(res) ) {
 397                MTS_INT_ERROR( "could not submit URB! Error was %d\n",(int)res );
 398                context->srb->result = DID_ERROR << 16;
 399                mts_transfer_cleanup(transfer);
 400        }
 401}
 402
 403
 404static void mts_transfer_cleanup( struct urb *transfer )
 405/* Interrupt context! */
 406{
 407        MTS_INT_INIT();
 408
 409        if ( likely(context->final_callback != NULL) )
 410                context->final_callback(context->srb);
 411}
 412
 413static void mts_transfer_done( struct urb *transfer )
 414{
 415        MTS_INT_INIT();
 416
 417        context->srb->result &= MTS_SCSI_ERR_MASK;
 418        context->srb->result |= (unsigned)(*context->scsi_status)<<1;
 419
 420        mts_transfer_cleanup(transfer);
 421}
 422
 423
 424static void mts_get_status( struct urb *transfer )
 425/* Interrupt context! */
 426{
 427        MTS_INT_INIT();
 428
 429        mts_int_submit_urb(transfer,
 430                           usb_rcvbulkpipe(context->instance->usb_dev,
 431                                           context->instance->ep_response),
 432                           context->scsi_status,
 433                           1,
 434                           mts_transfer_done );
 435}
 436
 437static void mts_data_done( struct urb* transfer )
 438/* Interrupt context! */
 439{
 440        int status = transfer->status;
 441        MTS_INT_INIT();
 442
 443        if ( context->data_length != transfer->actual_length ) {
 444                scsi_set_resid(context->srb, context->data_length -
 445                               transfer->actual_length);
 446        } else if ( unlikely(status) ) {
 447                context->srb->result = (status == -ENOENT ? DID_ABORT : DID_ERROR)<<16;
 448        }
 449
 450        mts_get_status(transfer);
 451}
 452
 453
 454static void mts_command_done( struct urb *transfer )
 455/* Interrupt context! */
 456{
 457        int status = transfer->status;
 458        MTS_INT_INIT();
 459
 460        if ( unlikely(status) ) {
 461                if (status == -ENOENT) {
 462                        /* We are being killed */
 463                        MTS_DEBUG_GOT_HERE();
 464                        context->srb->result = DID_ABORT<<16;
 465                } else {
 466                        /* A genuine error has occurred */
 467                        MTS_DEBUG_GOT_HERE();
 468
 469                        context->srb->result = DID_ERROR<<16;
 470                }
 471                mts_transfer_cleanup(transfer);
 472
 473                return;
 474        }
 475
 476        if (context->srb->cmnd[0] == REQUEST_SENSE) {
 477                mts_int_submit_urb(transfer,
 478                                   context->data_pipe,
 479                                   context->srb->sense_buffer,
 480                                   context->data_length,
 481                                   mts_data_done);
 482        } else { if ( context->data ) {
 483                        mts_int_submit_urb(transfer,
 484                                           context->data_pipe,
 485                                           context->data,
 486                                           context->data_length,
 487                                           scsi_sg_count(context->srb) > 1 ?
 488                                                   mts_do_sg : mts_data_done);
 489                } else {
 490                        mts_get_status(transfer);
 491                }
 492        }
 493}
 494
 495static void mts_do_sg (struct urb* transfer)
 496{
 497        struct scatterlist * sg;
 498        int status = transfer->status;
 499        MTS_INT_INIT();
 500
 501        MTS_DEBUG("Processing fragment %d of %d\n", context->fragment,
 502                                                  scsi_sg_count(context->srb));
 503
 504        if (unlikely(status)) {
 505                context->srb->result = (status == -ENOENT ? DID_ABORT : DID_ERROR)<<16;
 506                mts_transfer_cleanup(transfer);
 507        }
 508
 509        sg = scsi_sglist(context->srb);
 510        context->fragment++;
 511        mts_int_submit_urb(transfer,
 512                           context->data_pipe,
 513                           sg_virt(&sg[context->fragment]),
 514                           sg[context->fragment].length,
 515                           context->fragment + 1 == scsi_sg_count(context->srb) ?
 516                           mts_data_done : mts_do_sg);
 517}
 518
 519static const u8 mts_read_image_sig[] = { 0x28, 00, 00, 00 };
 520static const u8 mts_read_image_sig_len = 4;
 521static const unsigned char mts_direction[256/8] = {
 522        0x28, 0x81, 0x14, 0x14, 0x20, 0x01, 0x90, 0x77,
 523        0x0C, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
 524        0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,
 525        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 526};
 527
 528
 529#define MTS_DIRECTION_IS_IN(x) ((mts_direction[x>>3] >> (x & 7)) & 1)
 530
 531static void
 532mts_build_transfer_context(struct scsi_cmnd *srb, struct mts_desc* desc)
 533{
 534        int pipe;
 535        struct scatterlist * sg;
 536        
 537        MTS_DEBUG_GOT_HERE();
 538
 539        desc->context.instance = desc;
 540        desc->context.srb = srb;
 541        desc->context.fragment = 0;
 542
 543        if (!scsi_bufflen(srb)) {
 544                desc->context.data = NULL;
 545                desc->context.data_length = 0;
 546                return;
 547        } else {
 548                sg = scsi_sglist(srb);
 549                desc->context.data = sg_virt(&sg[0]);
 550                desc->context.data_length = sg[0].length;
 551        }
 552
 553
 554        /* can't rely on srb->sc_data_direction */
 555
 556        /* Brutally ripped from usb-storage */
 557
 558        if ( !memcmp( srb->cmnd, mts_read_image_sig, mts_read_image_sig_len )
 559) {             pipe = usb_rcvbulkpipe(desc->usb_dev,desc->ep_image);
 560                MTS_DEBUG( "transfering from desc->ep_image == %d\n",
 561                           (int)desc->ep_image );
 562        } else if ( MTS_DIRECTION_IS_IN(srb->cmnd[0]) ) {
 563                        pipe = usb_rcvbulkpipe(desc->usb_dev,desc->ep_response);
 564                        MTS_DEBUG( "transfering from desc->ep_response == %d\n",
 565                                   (int)desc->ep_response);
 566        } else {
 567                MTS_DEBUG("transfering to desc->ep_out == %d\n",
 568                          (int)desc->ep_out);
 569                pipe = usb_sndbulkpipe(desc->usb_dev,desc->ep_out);
 570        }
 571        desc->context.data_pipe = pipe;
 572}
 573
 574
 575static int
 576mts_scsi_queuecommand_lck(struct scsi_cmnd *srb, mts_scsi_cmnd_callback callback)
 577{
 578        struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]);
 579        int err = 0;
 580        int res;
 581
 582        MTS_DEBUG_GOT_HERE();
 583        mts_show_command(srb);
 584        mts_debug_dump(desc);
 585
 586        if ( srb->device->lun || srb->device->id || srb->device->channel ) {
 587
 588                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 );
 589
 590                MTS_DEBUG("this device doesn't exist\n");
 591
 592                srb->result = DID_BAD_TARGET << 16;
 593
 594                if(likely(callback != NULL))
 595                        callback(srb);
 596
 597                goto out;
 598        }
 599
 600        
 601        usb_fill_bulk_urb(desc->urb,
 602                      desc->usb_dev,
 603                      usb_sndbulkpipe(desc->usb_dev,desc->ep_out),
 604                      srb->cmnd,
 605                      srb->cmd_len,
 606                      mts_command_done,
 607                      &desc->context
 608                      );
 609
 610
 611        mts_build_transfer_context( srb, desc );
 612        desc->context.final_callback = callback;
 613        
 614        /* here we need ATOMIC as we are called with the iolock */
 615        res=usb_submit_urb(desc->urb, GFP_ATOMIC);
 616
 617        if(unlikely(res)){
 618                MTS_ERROR("error %d submitting URB\n",(int)res);
 619                srb->result = DID_ERROR << 16;
 620
 621                if(likely(callback != NULL))
 622                        callback(srb);
 623
 624        }
 625out:
 626        return err;
 627}
 628
 629static DEF_SCSI_QCMD(mts_scsi_queuecommand)
 630
 631static struct scsi_host_template mts_scsi_host_template = {
 632        .module                 = THIS_MODULE,
 633        .name                   = "microtekX6",
 634        .proc_name              = "microtekX6",
 635        .queuecommand           = mts_scsi_queuecommand,
 636        .eh_abort_handler       = mts_scsi_abort,
 637        .eh_host_reset_handler  = mts_scsi_host_reset,
 638        .sg_tablesize =         SG_ALL,
 639        .can_queue =            1,
 640        .this_id =              -1,
 641        .cmd_per_lun =          1,
 642        .use_clustering =       1,
 643        .emulated =             1,
 644        .slave_alloc =          mts_slave_alloc,
 645        .slave_configure =      mts_slave_configure,
 646        .max_sectors=           256, /* 128 K */
 647};
 648
 649/* The entries of microtek_table must correspond, line-by-line to
 650   the entries of mts_supported_products[]. */
 651
 652static const struct usb_device_id mts_usb_ids[] =
 653{
 654        { USB_DEVICE(0x4ce, 0x0300) },
 655        { USB_DEVICE(0x5da, 0x0094) },
 656        { USB_DEVICE(0x5da, 0x0099) },
 657        { USB_DEVICE(0x5da, 0x009a) },
 658        { USB_DEVICE(0x5da, 0x00a0) },
 659        { USB_DEVICE(0x5da, 0x00a3) },
 660        { USB_DEVICE(0x5da, 0x80a3) },
 661        { USB_DEVICE(0x5da, 0x80ac) },
 662        { USB_DEVICE(0x5da, 0x00b6) },
 663        { }                                             /* Terminating entry */
 664};
 665
 666MODULE_DEVICE_TABLE (usb, mts_usb_ids);
 667
 668
 669static int mts_usb_probe(struct usb_interface *intf,
 670                         const struct usb_device_id *id)
 671{
 672        int i;
 673        int ep_out = -1;
 674        int ep_in_set[3]; /* this will break if we have more than three endpoints
 675                           which is why we check */
 676        int *ep_in_current = ep_in_set;
 677        int err_retval = -ENOMEM;
 678
 679        struct mts_desc * new_desc;
 680        struct usb_device *dev = interface_to_usbdev (intf);
 681
 682        /* the current altsetting on the interface we're probing */
 683        struct usb_host_interface *altsetting;
 684
 685        MTS_DEBUG_GOT_HERE();
 686        MTS_DEBUG( "usb-device descriptor at %x\n", (int)dev );
 687
 688        MTS_DEBUG( "product id = 0x%x, vendor id = 0x%x\n",
 689                   le16_to_cpu(dev->descriptor.idProduct),
 690                   le16_to_cpu(dev->descriptor.idVendor) );
 691
 692        MTS_DEBUG_GOT_HERE();
 693
 694        /* the current altsetting on the interface we're probing */
 695        altsetting = intf->cur_altsetting;
 696
 697
 698        /* Check if the config is sane */
 699
 700        if ( altsetting->desc.bNumEndpoints != MTS_EP_TOTAL ) {
 701                MTS_WARNING( "expecting %d got %d endpoints! Bailing out.\n",
 702                             (int)MTS_EP_TOTAL, (int)altsetting->desc.bNumEndpoints );
 703                return -ENODEV;
 704        }
 705
 706        for( i = 0; i < altsetting->desc.bNumEndpoints; i++ ) {
 707                if ((altsetting->endpoint[i].desc.bmAttributes &
 708                     USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK) {
 709
 710                        MTS_WARNING( "can only deal with bulk endpoints; endpoint %d is not bulk.\n",
 711                             (int)altsetting->endpoint[i].desc.bEndpointAddress );
 712                } else {
 713                        if (altsetting->endpoint[i].desc.bEndpointAddress &
 714                            USB_DIR_IN)
 715                                *ep_in_current++
 716                                        = altsetting->endpoint[i].desc.bEndpointAddress &
 717                                        USB_ENDPOINT_NUMBER_MASK;
 718                        else {
 719                                if ( ep_out != -1 ) {
 720                                        MTS_WARNING( "can only deal with one output endpoints. Bailing out." );
 721                                        return -ENODEV;
 722                                }
 723
 724                                ep_out = altsetting->endpoint[i].desc.bEndpointAddress &
 725                                        USB_ENDPOINT_NUMBER_MASK;
 726                        }
 727                }
 728
 729        }
 730
 731
 732        if ( ep_out == -1 ) {
 733                MTS_WARNING( "couldn't find an output bulk endpoint. Bailing out.\n" );
 734                return -ENODEV;
 735        }
 736
 737
 738        new_desc = kzalloc(sizeof(struct mts_desc), GFP_KERNEL);
 739        if (!new_desc)
 740                goto out;
 741
 742        new_desc->urb = usb_alloc_urb(0, GFP_KERNEL);
 743        if (!new_desc->urb)
 744                goto out_kfree;
 745
 746        new_desc->context.scsi_status = kmalloc(1, GFP_KERNEL);
 747        if (!new_desc->context.scsi_status)
 748                goto out_free_urb;
 749
 750        new_desc->usb_dev = dev;
 751        new_desc->usb_intf = intf;
 752
 753        /* endpoints */
 754        new_desc->ep_out = ep_out;
 755        new_desc->ep_response = ep_in_set[0];
 756        new_desc->ep_image = ep_in_set[1];
 757
 758        if ( new_desc->ep_out != MTS_EP_OUT )
 759                MTS_WARNING( "will this work? Command EP is not usually %d\n",
 760                             (int)new_desc->ep_out );
 761
 762        if ( new_desc->ep_response != MTS_EP_RESPONSE )
 763                MTS_WARNING( "will this work? Response EP is not usually %d\n",
 764                             (int)new_desc->ep_response );
 765
 766        if ( new_desc->ep_image != MTS_EP_IMAGE )
 767                MTS_WARNING( "will this work? Image data EP is not usually %d\n",
 768                             (int)new_desc->ep_image );
 769
 770        new_desc->host = scsi_host_alloc(&mts_scsi_host_template,
 771                        sizeof(new_desc));
 772        if (!new_desc->host)
 773                goto out_kfree2;
 774
 775        new_desc->host->hostdata[0] = (unsigned long)new_desc;
 776        if (scsi_add_host(new_desc->host, &dev->dev)) {
 777                err_retval = -EIO;
 778                goto out_host_put;
 779        }
 780        scsi_scan_host(new_desc->host);
 781
 782        usb_set_intfdata(intf, new_desc);
 783        return 0;
 784
 785 out_host_put:
 786        scsi_host_put(new_desc->host);
 787 out_kfree2:
 788        kfree(new_desc->context.scsi_status);
 789 out_free_urb:
 790        usb_free_urb(new_desc->urb);
 791 out_kfree:
 792        kfree(new_desc);
 793 out:
 794        return err_retval;
 795}
 796
 797static void mts_usb_disconnect (struct usb_interface *intf)
 798{
 799        struct mts_desc *desc = usb_get_intfdata(intf);
 800
 801        usb_set_intfdata(intf, NULL);
 802
 803        usb_kill_urb(desc->urb);
 804        scsi_remove_host(desc->host);
 805
 806        scsi_host_put(desc->host);
 807        usb_free_urb(desc->urb);
 808        kfree(desc->context.scsi_status);
 809        kfree(desc);
 810}
 811
 812
 813static int __init microtek_drv_init(void)
 814{
 815        return usb_register(&mts_usb_driver);
 816}
 817
 818static void __exit microtek_drv_exit(void)
 819{
 820        usb_deregister(&mts_usb_driver);
 821}
 822
 823module_init(microtek_drv_init);
 824module_exit(microtek_drv_exit);
 825
 826MODULE_AUTHOR( DRIVER_AUTHOR );
 827MODULE_DESCRIPTION( DRIVER_DESC );
 828MODULE_LICENSE("GPL");
 829