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 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_cmnd *srb, mts_scsi_cmnd_callback callback);
 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        return;
 402}
 403
 404
 405static void mts_transfer_cleanup( struct urb *transfer )
 406/* Interrupt context! */
 407{
 408        MTS_INT_INIT();
 409
 410        if ( likely(context->final_callback != NULL) )
 411                context->final_callback(context->srb);
 412
 413}
 414
 415static void mts_transfer_done( struct urb *transfer )
 416{
 417        MTS_INT_INIT();
 418
 419        context->srb->result &= MTS_SCSI_ERR_MASK;
 420        context->srb->result |= (unsigned)(*context->scsi_status)<<1;
 421
 422        mts_transfer_cleanup(transfer);
 423
 424        return;
 425}
 426
 427
 428static void mts_get_status( struct urb *transfer )
 429/* Interrupt context! */
 430{
 431        MTS_INT_INIT();
 432
 433        mts_int_submit_urb(transfer,
 434                           usb_rcvbulkpipe(context->instance->usb_dev,
 435                                           context->instance->ep_response),
 436                           context->scsi_status,
 437                           1,
 438                           mts_transfer_done );
 439}
 440
 441static void mts_data_done( struct urb* transfer )
 442/* Interrupt context! */
 443{
 444        int status = transfer->status;
 445        MTS_INT_INIT();
 446
 447        if ( context->data_length != transfer->actual_length ) {
 448                scsi_set_resid(context->srb, context->data_length -
 449                               transfer->actual_length);
 450        } else if ( unlikely(status) ) {
 451                context->srb->result = (status == -ENOENT ? DID_ABORT : DID_ERROR)<<16;
 452        }
 453
 454        mts_get_status(transfer);
 455
 456        return;
 457}
 458
 459
 460static void mts_command_done( struct urb *transfer )
 461/* Interrupt context! */
 462{
 463        int status = transfer->status;
 464        MTS_INT_INIT();
 465
 466        if ( unlikely(status) ) {
 467                if (status == -ENOENT) {
 468                        /* We are being killed */
 469                        MTS_DEBUG_GOT_HERE();
 470                        context->srb->result = DID_ABORT<<16;
 471                } else {
 472                        /* A genuine error has occurred */
 473                        MTS_DEBUG_GOT_HERE();
 474
 475                        context->srb->result = DID_ERROR<<16;
 476                }
 477                mts_transfer_cleanup(transfer);
 478
 479                return;
 480        }
 481
 482        if (context->srb->cmnd[0] == REQUEST_SENSE) {
 483                mts_int_submit_urb(transfer,
 484                                   context->data_pipe,
 485                                   context->srb->sense_buffer,
 486                                   context->data_length,
 487                                   mts_data_done);
 488        } else { if ( context->data ) {
 489                        mts_int_submit_urb(transfer,
 490                                           context->data_pipe,
 491                                           context->data,
 492                                           context->data_length,
 493                                           scsi_sg_count(context->srb) > 1 ?
 494                                                   mts_do_sg : mts_data_done);
 495                } else {
 496                        mts_get_status(transfer);
 497                }
 498        }
 499
 500        return;
 501}
 502
 503static void mts_do_sg (struct urb* transfer)
 504{
 505        struct scatterlist * sg;
 506        int status = transfer->status;
 507        MTS_INT_INIT();
 508
 509        MTS_DEBUG("Processing fragment %d of %d\n", context->fragment,
 510                                                  scsi_sg_count(context->srb));
 511
 512        if (unlikely(status)) {
 513                context->srb->result = (status == -ENOENT ? DID_ABORT : DID_ERROR)<<16;
 514                mts_transfer_cleanup(transfer);
 515        }
 516
 517        sg = scsi_sglist(context->srb);
 518        context->fragment++;
 519        mts_int_submit_urb(transfer,
 520                           context->data_pipe,
 521                           sg_virt(&sg[context->fragment]),
 522                           sg[context->fragment].length,
 523                           context->fragment + 1 == scsi_sg_count(context->srb) ?
 524                           mts_data_done : mts_do_sg);
 525        return;
 526}
 527
 528static const u8 mts_read_image_sig[] = { 0x28, 00, 00, 00 };
 529static const u8 mts_read_image_sig_len = 4;
 530static const unsigned char mts_direction[256/8] = {
 531        0x28, 0x81, 0x14, 0x14, 0x20, 0x01, 0x90, 0x77,
 532        0x0C, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
 533        0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,
 534        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 535};
 536
 537
 538#define MTS_DIRECTION_IS_IN(x) ((mts_direction[x>>3] >> (x & 7)) & 1)
 539
 540static void
 541mts_build_transfer_context(struct scsi_cmnd *srb, struct mts_desc* desc)
 542{
 543        int pipe;
 544        struct scatterlist * sg;
 545        
 546        MTS_DEBUG_GOT_HERE();
 547
 548        desc->context.instance = desc;
 549        desc->context.srb = srb;
 550        desc->context.fragment = 0;
 551
 552        if (!scsi_bufflen(srb)) {
 553                desc->context.data = NULL;
 554                desc->context.data_length = 0;
 555                return;
 556        } else {
 557                sg = scsi_sglist(srb);
 558                desc->context.data = sg_virt(&sg[0]);
 559                desc->context.data_length = sg[0].length;
 560        }
 561
 562
 563        /* can't rely on srb->sc_data_direction */
 564
 565        /* Brutally ripped from usb-storage */
 566
 567        if ( !memcmp( srb->cmnd, mts_read_image_sig, mts_read_image_sig_len )
 568) {             pipe = usb_rcvbulkpipe(desc->usb_dev,desc->ep_image);
 569                MTS_DEBUG( "transfering from desc->ep_image == %d\n",
 570                           (int)desc->ep_image );
 571        } else if ( MTS_DIRECTION_IS_IN(srb->cmnd[0]) ) {
 572                        pipe = usb_rcvbulkpipe(desc->usb_dev,desc->ep_response);
 573                        MTS_DEBUG( "transfering from desc->ep_response == %d\n",
 574                                   (int)desc->ep_response);
 575        } else {
 576                MTS_DEBUG("transfering to desc->ep_out == %d\n",
 577                          (int)desc->ep_out);
 578                pipe = usb_sndbulkpipe(desc->usb_dev,desc->ep_out);
 579        }
 580        desc->context.data_pipe = pipe;
 581}
 582
 583
 584static int
 585mts_scsi_queuecommand(struct scsi_cmnd *srb, mts_scsi_cmnd_callback callback)
 586{
 587        struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]);
 588        int err = 0;
 589        int res;
 590
 591        MTS_DEBUG_GOT_HERE();
 592        mts_show_command(srb);
 593        mts_debug_dump(desc);
 594
 595        if ( srb->device->lun || srb->device->id || srb->device->channel ) {
 596
 597                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 );
 598
 599                MTS_DEBUG("this device doesn't exist\n");
 600
 601                srb->result = DID_BAD_TARGET << 16;
 602
 603                if(likely(callback != NULL))
 604                        callback(srb);
 605
 606                goto out;
 607        }
 608
 609        
 610        usb_fill_bulk_urb(desc->urb,
 611                      desc->usb_dev,
 612                      usb_sndbulkpipe(desc->usb_dev,desc->ep_out),
 613                      srb->cmnd,
 614                      srb->cmd_len,
 615                      mts_command_done,
 616                      &desc->context
 617                      );
 618
 619
 620        mts_build_transfer_context( srb, desc );
 621        desc->context.final_callback = callback;
 622        
 623        /* here we need ATOMIC as we are called with the iolock */
 624        res=usb_submit_urb(desc->urb, GFP_ATOMIC);
 625
 626        if(unlikely(res)){
 627                MTS_ERROR("error %d submitting URB\n",(int)res);
 628                srb->result = DID_ERROR << 16;
 629
 630                if(likely(callback != NULL))
 631                        callback(srb);
 632
 633        }
 634out:
 635        return err;
 636}
 637
 638static struct scsi_host_template mts_scsi_host_template = {
 639        .module                 = THIS_MODULE,
 640        .name                   = "microtekX6",
 641        .proc_name              = "microtekX6",
 642        .queuecommand           = mts_scsi_queuecommand,
 643        .eh_abort_handler       = mts_scsi_abort,
 644        .eh_host_reset_handler  = mts_scsi_host_reset,
 645        .sg_tablesize =         SG_ALL,
 646        .can_queue =            1,
 647        .this_id =              -1,
 648        .cmd_per_lun =          1,
 649        .use_clustering =       1,
 650        .emulated =             1,
 651        .slave_alloc =          mts_slave_alloc,
 652        .slave_configure =      mts_slave_configure,
 653        .max_sectors=           256, /* 128 K */
 654};
 655
 656/* The entries of microtek_table must correspond, line-by-line to
 657   the entries of mts_supported_products[]. */
 658
 659static struct usb_device_id mts_usb_ids [] =
 660{
 661        { USB_DEVICE(0x4ce, 0x0300) },
 662        { USB_DEVICE(0x5da, 0x0094) },
 663        { USB_DEVICE(0x5da, 0x0099) },
 664        { USB_DEVICE(0x5da, 0x009a) },
 665        { USB_DEVICE(0x5da, 0x00a0) },
 666        { USB_DEVICE(0x5da, 0x00a3) },
 667        { USB_DEVICE(0x5da, 0x80a3) },
 668        { USB_DEVICE(0x5da, 0x80ac) },
 669        { USB_DEVICE(0x5da, 0x00b6) },
 670        { }                                             /* Terminating entry */
 671};
 672
 673MODULE_DEVICE_TABLE (usb, mts_usb_ids);
 674
 675
 676static int mts_usb_probe(struct usb_interface *intf,
 677                         const struct usb_device_id *id)
 678{
 679        int i;
 680        int ep_out = -1;
 681        int ep_in_set[3]; /* this will break if we have more than three endpoints
 682                           which is why we check */
 683        int *ep_in_current = ep_in_set;
 684        int err_retval = -ENOMEM;
 685
 686        struct mts_desc * new_desc;
 687        struct usb_device *dev = interface_to_usbdev (intf);
 688
 689        /* the current altsetting on the interface we're probing */
 690        struct usb_host_interface *altsetting;
 691
 692        MTS_DEBUG_GOT_HERE();
 693        MTS_DEBUG( "usb-device descriptor at %x\n", (int)dev );
 694
 695        MTS_DEBUG( "product id = 0x%x, vendor id = 0x%x\n",
 696                   le16_to_cpu(dev->descriptor.idProduct),
 697                   le16_to_cpu(dev->descriptor.idVendor) );
 698
 699        MTS_DEBUG_GOT_HERE();
 700
 701        /* the current altsetting on the interface we're probing */
 702        altsetting = intf->cur_altsetting;
 703
 704
 705        /* Check if the config is sane */
 706
 707        if ( altsetting->desc.bNumEndpoints != MTS_EP_TOTAL ) {
 708                MTS_WARNING( "expecting %d got %d endpoints! Bailing out.\n",
 709                             (int)MTS_EP_TOTAL, (int)altsetting->desc.bNumEndpoints );
 710                return -ENODEV;
 711        }
 712
 713        for( i = 0; i < altsetting->desc.bNumEndpoints; i++ ) {
 714                if ((altsetting->endpoint[i].desc.bmAttributes &
 715                     USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK) {
 716
 717                        MTS_WARNING( "can only deal with bulk endpoints; endpoint %d is not bulk.\n",
 718                             (int)altsetting->endpoint[i].desc.bEndpointAddress );
 719                } else {
 720                        if (altsetting->endpoint[i].desc.bEndpointAddress &
 721                            USB_DIR_IN)
 722                                *ep_in_current++
 723                                        = altsetting->endpoint[i].desc.bEndpointAddress &
 724                                        USB_ENDPOINT_NUMBER_MASK;
 725                        else {
 726                                if ( ep_out != -1 ) {
 727                                        MTS_WARNING( "can only deal with one output endpoints. Bailing out." );
 728                                        return -ENODEV;
 729                                }
 730
 731                                ep_out = altsetting->endpoint[i].desc.bEndpointAddress &
 732                                        USB_ENDPOINT_NUMBER_MASK;
 733                        }
 734                }
 735
 736        }
 737
 738
 739        if ( ep_out == -1 ) {
 740                MTS_WARNING( "couldn't find an output bulk endpoint. Bailing out.\n" );
 741                return -ENODEV;
 742        }
 743
 744
 745        new_desc = kzalloc(sizeof(struct mts_desc), GFP_KERNEL);
 746        if (!new_desc)
 747                goto out;
 748
 749        new_desc->urb = usb_alloc_urb(0, GFP_KERNEL);
 750        if (!new_desc->urb)
 751                goto out_kfree;
 752
 753        new_desc->context.scsi_status = kmalloc(1, GFP_KERNEL);
 754        if (!new_desc->context.scsi_status)
 755                goto out_free_urb;
 756
 757        new_desc->usb_dev = dev;
 758        new_desc->usb_intf = intf;
 759
 760        /* endpoints */
 761        new_desc->ep_out = ep_out;
 762        new_desc->ep_response = ep_in_set[0];
 763        new_desc->ep_image = ep_in_set[1];
 764
 765        if ( new_desc->ep_out != MTS_EP_OUT )
 766                MTS_WARNING( "will this work? Command EP is not usually %d\n",
 767                             (int)new_desc->ep_out );
 768
 769        if ( new_desc->ep_response != MTS_EP_RESPONSE )
 770                MTS_WARNING( "will this work? Response EP is not usually %d\n",
 771                             (int)new_desc->ep_response );
 772
 773        if ( new_desc->ep_image != MTS_EP_IMAGE )
 774                MTS_WARNING( "will this work? Image data EP is not usually %d\n",
 775                             (int)new_desc->ep_image );
 776
 777        new_desc->host = scsi_host_alloc(&mts_scsi_host_template,
 778                        sizeof(new_desc));
 779        if (!new_desc->host)
 780                goto out_kfree2;
 781
 782        new_desc->host->hostdata[0] = (unsigned long)new_desc;
 783        if (scsi_add_host(new_desc->host, &dev->dev)) {
 784                err_retval = -EIO;
 785                goto out_host_put;
 786        }
 787        scsi_scan_host(new_desc->host);
 788
 789        usb_set_intfdata(intf, new_desc);
 790        return 0;
 791
 792 out_host_put:
 793        scsi_host_put(new_desc->host);
 794 out_kfree2:
 795        kfree(new_desc->context.scsi_status);
 796 out_free_urb:
 797        usb_free_urb(new_desc->urb);
 798 out_kfree:
 799        kfree(new_desc);
 800 out:
 801        return err_retval;
 802}
 803
 804static void mts_usb_disconnect (struct usb_interface *intf)
 805{
 806        struct mts_desc *desc = usb_get_intfdata(intf);
 807
 808        usb_set_intfdata(intf, NULL);
 809
 810        usb_kill_urb(desc->urb);
 811        scsi_remove_host(desc->host);
 812
 813        scsi_host_put(desc->host);
 814        usb_free_urb(desc->urb);
 815        kfree(desc->context.scsi_status);
 816        kfree(desc);
 817}
 818
 819
 820static int __init microtek_drv_init(void)
 821{
 822        return usb_register(&mts_usb_driver);
 823}
 824
 825static void __exit microtek_drv_exit(void)
 826{
 827        usb_deregister(&mts_usb_driver);
 828}
 829
 830module_init(microtek_drv_init);
 831module_exit(microtek_drv_exit);
 832
 833MODULE_AUTHOR( DRIVER_AUTHOR );
 834MODULE_DESCRIPTION( DRIVER_DESC );
 835MODULE_LICENSE("GPL");
 836