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