Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Driver for Microtek Scanmaker X6 USB scanner, and possibly others.
0003  *
0004  * (C) Copyright 2000 John Fremlin <vii@penguinpowered.com>
0005  * (C) Copyright 2000 Oliver Neukum <Oliver.Neukum@lrz.uni-muenchen.de>
0006  *
0007  * Parts shamelessly stolen from usb-storage and copyright by their
0008  * authors. Thanks to Matt Dharm for giving us permission!
0009  *
0010  * This driver implements a SCSI host controller driver and a USB
0011  * device driver. To avoid confusion, all the USB related stuff is
0012  * prefixed by mts_usb_ and all the SCSI stuff by mts_scsi_.
0013  *
0014  * Microtek (www.microtek.com) did not release the specifications for
0015  * their USB protocol to us, so we had to reverse engineer them. We
0016  * don't know for which models they are valid.
0017  *
0018  * The X6 USB has three bulk endpoints, one output (0x1) down which
0019  * commands and outgoing data are sent, and two input: 0x82 from which
0020  * normal data is read from the scanner (in packets of maximum 32
0021  * bytes) and from which the status byte is read, and 0x83 from which
0022  * the results of a scan (or preview) are read in up to 64 * 1024 byte
0023  * chunks by the Windows driver. We don't know how much it is possible
0024  * to read at a time from 0x83.
0025  *
0026  * It seems possible to read (with URB transfers) everything from 0x82
0027  * in one go, without bothering to read in 32 byte chunks.
0028  *
0029  * There seems to be an optimisation of a further READ implicit if
0030  * you simply read from 0x83.
0031  *
0032  * Guessed protocol:
0033  *
0034  *  Send raw SCSI command to EP 0x1
0035  *
0036  *  If there is data to receive:
0037  *      If the command was READ datatype=image:
0038  *          Read a lot of data from EP 0x83
0039  *      Else:
0040  *          Read data from EP 0x82
0041  *  Else:
0042  *      If there is data to transmit:
0043  *          Write it to EP 0x1
0044  *
0045  *  Read status byte from EP 0x82
0046  *
0047  * References:
0048  *
0049  * The SCSI command set for the scanner is available from
0050  *  ftp://ftp.microtek.com/microtek/devpack/
0051  *
0052  * Microtek NV sent us a more up to date version of the document. If
0053  * you want it, just send mail.
0054  *
0055  * Status:
0056  *
0057  *  Untested with multiple scanners.
0058  *  Untested on SMP.
0059  *  Untested on a bigendian machine.
0060  *
0061  * History:
0062  *
0063  *  20000417 starting history
0064  *  20000417 fixed load oops
0065  *  20000417 fixed unload oops
0066  *  20000419 fixed READ IMAGE detection
0067  *  20000424 started conversion to use URBs
0068  *  20000502 handled short transfers as errors
0069  *  20000513 rename and organisation of functions (john)
0070  *  20000513 added IDs for all products supported by Windows driver (john)
0071  *  20000514 Rewrote mts_scsi_queuecommand to use URBs (john)
0072  *  20000514 Version 0.0.8j
0073  *      20000514 Fix reporting of non-existent devices to SCSI layer (john)
0074  *  20000514 Added MTS_DEBUG_INT (john)
0075  *  20000514 Changed "usb-microtek" to "microtek" for consistency (john)
0076  *  20000514 Stupid bug fixes (john)
0077  *  20000514 Version 0.0.9j
0078  *  20000515 Put transfer context and URB in mts_desc (john)
0079  *  20000515 Added prelim turn off debugging support (john)
0080  *  20000515 Version 0.0.10j
0081  *      20000515 Fixed up URB allocation (clear URB on alloc) (john)
0082  *      20000515 Version 0.0.11j
0083  *  20000516 Removed unnecessary spinlock in mts_transfer_context (john)
0084  *  20000516 Removed unnecessary up on instance lock in mts_remove_nolock (john)
0085  *  20000516 Implemented (badly) scsi_abort (john)
0086  *  20000516 Version 0.0.12j
0087  *      20000517 Hopefully removed mts_remove_nolock quasideadlock (john)
0088  *      20000517 Added mts_debug_dump to print ll USB info (john)
0089  *  20000518 Tweaks and documentation updates (john)
0090  *  20000518 Version 0.0.13j
0091  *  20000518 Cleaned up abort handling (john)
0092  *  20000523 Removed scsi_command and various scsi_..._resets (john)
0093  *  20000523 Added unlink URB on scsi_abort, now OHCI supports it (john)
0094  *  20000523 Fixed last tiresome compile warning (john)
0095  *  20000523 Version 0.0.14j (though version 0.1 has come out?)
0096  *  20000602 Added primitive reset
0097  *  20000602 Version 0.2.0
0098  *  20000603 various cosmetic changes
0099  *  20000603 Version 0.2.1
0100  *  20000620 minor cosmetic changes
0101  *  20000620 Version 0.2.2
0102  *  20000822 Hopefully fixed deadlock in mts_remove_nolock()
0103  *  20000822 Fixed minor race in mts_transfer_cleanup()
0104  *  20000822 Fixed deadlock on submission error in queuecommand
0105  *  20000822 Version 0.2.3
0106  *  20000913 Reduced module size if debugging is off
0107  *  20000913 Version 0.2.4
0108  *      20010210 New abort logic
0109  *      20010210 Version 0.3.0
0110  *  20010217 Merged scatter/gather
0111  *  20010218 Version 0.4.0
0112  *  20010218 Cosmetic fixes
0113  *  20010218 Version 0.4.1
0114  *      20010306 Abort while using scatter/gather
0115  *      20010306 Version 0.4.2
0116  *      20010311 Remove all timeouts and tidy up generally (john)
0117  *  20010320 check return value of scsi_register()
0118  *  20010320 Version 0.4.3
0119  *  20010408 Identify version on module load.
0120  *  20011003 Fix multiple requests
0121  */
0122 
0123 #include <linux/module.h>
0124 #include <linux/kernel.h>
0125 #include <linux/signal.h>
0126 #include <linux/errno.h>
0127 #include <linux/random.h>
0128 #include <linux/poll.h>
0129 #include <linux/slab.h>
0130 #include <linux/spinlock.h>
0131 #include <linux/usb.h>
0132 #include <linux/proc_fs.h>
0133 #include <linux/atomic.h>
0134 #include <linux/blkdev.h>
0135 
0136 #include <scsi/scsi.h>
0137 #include <scsi/scsi_cmnd.h>
0138 #include <scsi/scsi_device.h>
0139 #include <scsi/scsi_eh.h>
0140 #include <scsi/scsi_host.h>
0141 #include <scsi/scsi_tcq.h>
0142 
0143 #include "microtek.h"
0144 
0145 #define DRIVER_AUTHOR "John Fremlin <vii@penguinpowered.com>, Oliver Neukum <Oliver.Neukum@lrz.uni-muenchen.de>"
0146 #define DRIVER_DESC "Microtek Scanmaker X6 USB scanner driver"
0147 
0148 /* Should we do debugging? */
0149 
0150 //#define MTS_DO_DEBUG
0151 
0152 /* USB layer driver interface */
0153 
0154 static int mts_usb_probe(struct usb_interface *intf,
0155              const struct usb_device_id *id);
0156 static void mts_usb_disconnect(struct usb_interface *intf);
0157 
0158 static const struct usb_device_id mts_usb_ids[];
0159 
0160 static struct usb_driver mts_usb_driver = {
0161     .name =     "microtekX6",
0162     .probe =    mts_usb_probe,
0163     .disconnect =   mts_usb_disconnect,
0164     .id_table = mts_usb_ids,
0165 };
0166 
0167 
0168 /* Internal driver stuff */
0169 
0170 #define MTS_VERSION "0.4.3"
0171 #define MTS_NAME    "microtek usb (rev " MTS_VERSION "): "
0172 
0173 #define MTS_WARNING(x...) \
0174     printk( KERN_WARNING MTS_NAME x )
0175 #define MTS_ERROR(x...) \
0176     printk( KERN_ERR MTS_NAME x )
0177 #define MTS_INT_ERROR(x...) \
0178     MTS_ERROR(x)
0179 #define MTS_MESSAGE(x...) \
0180     printk( KERN_INFO MTS_NAME x )
0181 
0182 #if defined MTS_DO_DEBUG
0183 
0184 #define MTS_DEBUG(x...) \
0185     printk( KERN_DEBUG MTS_NAME x )
0186 
0187 #define MTS_DEBUG_GOT_HERE() \
0188     MTS_DEBUG("got to %s:%d (%s)\n", __FILE__, (int)__LINE__, __func__ )
0189 #define MTS_DEBUG_INT() \
0190     do { MTS_DEBUG_GOT_HERE(); \
0191          MTS_DEBUG("transfer = 0x%x context = 0x%x\n",(int)transfer,(int)context ); \
0192          MTS_DEBUG("status = 0x%x data-length = 0x%x sent = 0x%x\n",transfer->status,(int)context->data_length, (int)transfer->actual_length ); \
0193              mts_debug_dump(context->instance);\
0194        } while(0)
0195 #else
0196 
0197 #define MTS_NUL_STATEMENT do { } while(0)
0198 
0199 #define MTS_DEBUG(x...) MTS_NUL_STATEMENT
0200 #define MTS_DEBUG_GOT_HERE() MTS_NUL_STATEMENT
0201 #define MTS_DEBUG_INT() MTS_NUL_STATEMENT
0202 
0203 #endif
0204 
0205 
0206 
0207 #define MTS_INT_INIT()\
0208     struct mts_transfer_context* context = (struct mts_transfer_context*)transfer->context; \
0209     MTS_DEBUG_INT();\
0210 
0211 #ifdef MTS_DO_DEBUG
0212 
0213 static inline void mts_debug_dump(struct mts_desc* desc) {
0214     MTS_DEBUG("desc at 0x%x: toggle = %02x%02x\n",
0215           (int)desc,
0216           (int)desc->usb_dev->toggle[1],(int)desc->usb_dev->toggle[0]
0217         );
0218     MTS_DEBUG("ep_out=%x ep_response=%x ep_image=%x\n",
0219           usb_sndbulkpipe(desc->usb_dev,desc->ep_out),
0220           usb_rcvbulkpipe(desc->usb_dev,desc->ep_response),
0221           usb_rcvbulkpipe(desc->usb_dev,desc->ep_image)
0222         );
0223 }
0224 
0225 
0226 static inline void mts_show_command(struct scsi_cmnd *srb)
0227 {
0228     char *what = NULL;
0229 
0230     switch (srb->cmnd[0]) {
0231     case TEST_UNIT_READY: what = "TEST_UNIT_READY"; break;
0232     case REZERO_UNIT: what = "REZERO_UNIT"; break;
0233     case REQUEST_SENSE: what = "REQUEST_SENSE"; break;
0234     case FORMAT_UNIT: what = "FORMAT_UNIT"; break;
0235     case READ_BLOCK_LIMITS: what = "READ_BLOCK_LIMITS"; break;
0236     case REASSIGN_BLOCKS: what = "REASSIGN_BLOCKS"; break;
0237     case READ_6: what = "READ_6"; break;
0238     case WRITE_6: what = "WRITE_6"; break;
0239     case SEEK_6: what = "SEEK_6"; break;
0240     case READ_REVERSE: what = "READ_REVERSE"; break;
0241     case WRITE_FILEMARKS: what = "WRITE_FILEMARKS"; break;
0242     case SPACE: what = "SPACE"; break;
0243     case INQUIRY: what = "INQUIRY"; break;
0244     case RECOVER_BUFFERED_DATA: what = "RECOVER_BUFFERED_DATA"; break;
0245     case MODE_SELECT: what = "MODE_SELECT"; break;
0246     case RESERVE: what = "RESERVE"; break;
0247     case RELEASE: what = "RELEASE"; break;
0248     case COPY: what = "COPY"; break;
0249     case ERASE: what = "ERASE"; break;
0250     case MODE_SENSE: what = "MODE_SENSE"; break;
0251     case START_STOP: what = "START_STOP"; break;
0252     case RECEIVE_DIAGNOSTIC: what = "RECEIVE_DIAGNOSTIC"; break;
0253     case SEND_DIAGNOSTIC: what = "SEND_DIAGNOSTIC"; break;
0254     case ALLOW_MEDIUM_REMOVAL: what = "ALLOW_MEDIUM_REMOVAL"; break;
0255     case SET_WINDOW: what = "SET_WINDOW"; break;
0256     case READ_CAPACITY: what = "READ_CAPACITY"; break;
0257     case READ_10: what = "READ_10"; break;
0258     case WRITE_10: what = "WRITE_10"; break;
0259     case SEEK_10: what = "SEEK_10"; break;
0260     case WRITE_VERIFY: what = "WRITE_VERIFY"; break;
0261     case VERIFY: what = "VERIFY"; break;
0262     case SEARCH_HIGH: what = "SEARCH_HIGH"; break;
0263     case SEARCH_EQUAL: what = "SEARCH_EQUAL"; break;
0264     case SEARCH_LOW: what = "SEARCH_LOW"; break;
0265     case SET_LIMITS: what = "SET_LIMITS"; break;
0266     case READ_POSITION: what = "READ_POSITION"; break;
0267     case SYNCHRONIZE_CACHE: what = "SYNCHRONIZE_CACHE"; break;
0268     case LOCK_UNLOCK_CACHE: what = "LOCK_UNLOCK_CACHE"; break;
0269     case READ_DEFECT_DATA: what = "READ_DEFECT_DATA"; break;
0270     case MEDIUM_SCAN: what = "MEDIUM_SCAN"; break;
0271     case COMPARE: what = "COMPARE"; break;
0272     case COPY_VERIFY: what = "COPY_VERIFY"; break;
0273     case WRITE_BUFFER: what = "WRITE_BUFFER"; break;
0274     case READ_BUFFER: what = "READ_BUFFER"; break;
0275     case UPDATE_BLOCK: what = "UPDATE_BLOCK"; break;
0276     case READ_LONG: what = "READ_LONG"; break;
0277     case WRITE_LONG: what = "WRITE_LONG"; break;
0278     case CHANGE_DEFINITION: what = "CHANGE_DEFINITION"; break;
0279     case WRITE_SAME: what = "WRITE_SAME"; break;
0280     case READ_TOC: what = "READ_TOC"; break;
0281     case LOG_SELECT: what = "LOG_SELECT"; break;
0282     case LOG_SENSE: what = "LOG_SENSE"; break;
0283     case MODE_SELECT_10: what = "MODE_SELECT_10"; break;
0284     case MODE_SENSE_10: what = "MODE_SENSE_10"; break;
0285     case MOVE_MEDIUM: what = "MOVE_MEDIUM"; break;
0286     case READ_12: what = "READ_12"; break;
0287     case WRITE_12: what = "WRITE_12"; break;
0288     case WRITE_VERIFY_12: what = "WRITE_VERIFY_12"; break;
0289     case SEARCH_HIGH_12: what = "SEARCH_HIGH_12"; break;
0290     case SEARCH_EQUAL_12: what = "SEARCH_EQUAL_12"; break;
0291     case SEARCH_LOW_12: what = "SEARCH_LOW_12"; break;
0292     case READ_ELEMENT_STATUS: what = "READ_ELEMENT_STATUS"; break;
0293     case SEND_VOLUME_TAG: what = "SEND_VOLUME_TAG"; break;
0294     case WRITE_LONG_2: what = "WRITE_LONG_2"; break;
0295     default:
0296         MTS_DEBUG("can't decode command\n");
0297         goto out;
0298         break;
0299     }
0300     MTS_DEBUG( "Command %s (%d bytes)\n", what, srb->cmd_len);
0301 
0302  out:
0303     MTS_DEBUG( "  %10ph\n", srb->cmnd);
0304 }
0305 
0306 #else
0307 
0308 static inline void mts_show_command(struct scsi_cmnd * dummy)
0309 {
0310 }
0311 
0312 static inline void mts_debug_dump(struct mts_desc* dummy)
0313 {
0314 }
0315 
0316 #endif
0317 
0318 static inline void mts_urb_abort(struct mts_desc* desc) {
0319     MTS_DEBUG_GOT_HERE();
0320     mts_debug_dump(desc);
0321 
0322     usb_kill_urb( desc->urb );
0323 }
0324 
0325 static int mts_slave_alloc (struct scsi_device *s)
0326 {
0327     s->inquiry_len = 0x24;
0328     return 0;
0329 }
0330 
0331 static int mts_slave_configure (struct scsi_device *s)
0332 {
0333     blk_queue_dma_alignment(s->request_queue, (512 - 1));
0334     return 0;
0335 }
0336 
0337 static int mts_scsi_abort(struct scsi_cmnd *srb)
0338 {
0339     struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]);
0340 
0341     MTS_DEBUG_GOT_HERE();
0342 
0343     mts_urb_abort(desc);
0344 
0345     return FAILED;
0346 }
0347 
0348 static int mts_scsi_host_reset(struct scsi_cmnd *srb)
0349 {
0350     struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]);
0351     int result;
0352 
0353     MTS_DEBUG_GOT_HERE();
0354     mts_debug_dump(desc);
0355 
0356     result = usb_lock_device_for_reset(desc->usb_dev, desc->usb_intf);
0357     if (result == 0) {
0358         result = usb_reset_device(desc->usb_dev);
0359         usb_unlock_device(desc->usb_dev);
0360     }
0361     return result ? FAILED : SUCCESS;
0362 }
0363 
0364 static int
0365 mts_scsi_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *srb);
0366 
0367 static void mts_transfer_cleanup( struct urb *transfer );
0368 static void mts_do_sg(struct urb * transfer);
0369 
0370 static inline
0371 void mts_int_submit_urb (struct urb* transfer,
0372             int pipe,
0373             void* data,
0374             unsigned length,
0375             usb_complete_t callback )
0376 /* Interrupt context! */
0377 
0378 /* Holding transfer->context->lock! */
0379 {
0380     int res;
0381 
0382     MTS_INT_INIT();
0383 
0384     usb_fill_bulk_urb(transfer,
0385               context->instance->usb_dev,
0386               pipe,
0387               data,
0388               length,
0389               callback,
0390               context
0391         );
0392 
0393     res = usb_submit_urb( transfer, GFP_ATOMIC );
0394     if ( unlikely(res) ) {
0395         MTS_INT_ERROR( "could not submit URB! Error was %d\n",(int)res );
0396         set_host_byte(context->srb, DID_ERROR);
0397         mts_transfer_cleanup(transfer);
0398     }
0399 }
0400 
0401 
0402 static void mts_transfer_cleanup( struct urb *transfer )
0403 /* Interrupt context! */
0404 {
0405     MTS_INT_INIT();
0406 
0407     if ( likely(context->final_callback != NULL) )
0408         context->final_callback(context->srb);
0409 }
0410 
0411 static void mts_transfer_done( struct urb *transfer )
0412 {
0413     MTS_INT_INIT();
0414 
0415     context->srb->result &= MTS_SCSI_ERR_MASK;
0416     context->srb->result |= (unsigned)(*context->scsi_status)<<1;
0417 
0418     mts_transfer_cleanup(transfer);
0419 }
0420 
0421 
0422 static void mts_get_status( struct urb *transfer )
0423 /* Interrupt context! */
0424 {
0425     MTS_INT_INIT();
0426 
0427     mts_int_submit_urb(transfer,
0428                usb_rcvbulkpipe(context->instance->usb_dev,
0429                        context->instance->ep_response),
0430                context->scsi_status,
0431                1,
0432                mts_transfer_done );
0433 }
0434 
0435 static void mts_data_done( struct urb* transfer )
0436 /* Interrupt context! */
0437 {
0438     int status = transfer->status;
0439     MTS_INT_INIT();
0440 
0441     if ( context->data_length != transfer->actual_length ) {
0442         scsi_set_resid(context->srb, context->data_length -
0443                    transfer->actual_length);
0444     } else if ( unlikely(status) ) {
0445         set_host_byte(context->srb, (status == -ENOENT ? DID_ABORT : DID_ERROR));
0446     }
0447 
0448     mts_get_status(transfer);
0449 }
0450 
0451 
0452 static void mts_command_done( struct urb *transfer )
0453 /* Interrupt context! */
0454 {
0455     int status = transfer->status;
0456     MTS_INT_INIT();
0457 
0458     if ( unlikely(status) ) {
0459             if (status == -ENOENT) {
0460                 /* We are being killed */
0461             MTS_DEBUG_GOT_HERE();
0462             set_host_byte(context->srb, DID_ABORT);
0463                 } else {
0464                 /* A genuine error has occurred */
0465             MTS_DEBUG_GOT_HERE();
0466 
0467                 set_host_byte(context->srb, DID_ERROR);
0468                 }
0469         mts_transfer_cleanup(transfer);
0470 
0471         return;
0472     }
0473 
0474     if (context->srb->cmnd[0] == REQUEST_SENSE) {
0475         mts_int_submit_urb(transfer,
0476                    context->data_pipe,
0477                    context->srb->sense_buffer,
0478                    context->data_length,
0479                    mts_data_done);
0480     } else { if ( context->data ) {
0481             mts_int_submit_urb(transfer,
0482                        context->data_pipe,
0483                        context->data,
0484                        context->data_length,
0485                        scsi_sg_count(context->srb) > 1 ?
0486                                mts_do_sg : mts_data_done);
0487         } else {
0488             mts_get_status(transfer);
0489         }
0490     }
0491 }
0492 
0493 static void mts_do_sg (struct urb* transfer)
0494 {
0495     int status = transfer->status;
0496     MTS_INT_INIT();
0497 
0498     MTS_DEBUG("Processing fragment %d of %d\n", context->fragment,
0499                                               scsi_sg_count(context->srb));
0500 
0501     if (unlikely(status)) {
0502                 set_host_byte(context->srb, (status == -ENOENT ? DID_ABORT : DID_ERROR));
0503         mts_transfer_cleanup(transfer);
0504         }
0505 
0506     context->curr_sg = sg_next(context->curr_sg);
0507     mts_int_submit_urb(transfer,
0508                context->data_pipe,
0509                sg_virt(context->curr_sg),
0510                context->curr_sg->length,
0511                sg_is_last(context->curr_sg) ?
0512                mts_data_done : mts_do_sg);
0513 }
0514 
0515 static const u8 mts_read_image_sig[] = { 0x28, 00, 00, 00 };
0516 static const u8 mts_read_image_sig_len = 4;
0517 static const unsigned char mts_direction[256/8] = {
0518     0x28, 0x81, 0x14, 0x14, 0x20, 0x01, 0x90, 0x77,
0519     0x0C, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
0520     0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,
0521     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
0522 };
0523 
0524 
0525 #define MTS_DIRECTION_IS_IN(x) ((mts_direction[x>>3] >> (x & 7)) & 1)
0526 
0527 static void
0528 mts_build_transfer_context(struct scsi_cmnd *srb, struct mts_desc* desc)
0529 {
0530     int pipe;
0531 
0532     MTS_DEBUG_GOT_HERE();
0533 
0534     desc->context.instance = desc;
0535     desc->context.srb = srb;
0536 
0537     if (!scsi_bufflen(srb)) {
0538         desc->context.data = NULL;
0539         desc->context.data_length = 0;
0540         return;
0541     } else {
0542         desc->context.curr_sg = scsi_sglist(srb);
0543         desc->context.data = sg_virt(desc->context.curr_sg);
0544         desc->context.data_length = desc->context.curr_sg->length;
0545     }
0546 
0547 
0548     /* can't rely on srb->sc_data_direction */
0549 
0550     /* Brutally ripped from usb-storage */
0551 
0552     if ( !memcmp( srb->cmnd, mts_read_image_sig, mts_read_image_sig_len )
0553 ) {         pipe = usb_rcvbulkpipe(desc->usb_dev,desc->ep_image);
0554         MTS_DEBUG( "transferring from desc->ep_image == %d\n",
0555                (int)desc->ep_image );
0556     } else if ( MTS_DIRECTION_IS_IN(srb->cmnd[0]) ) {
0557             pipe = usb_rcvbulkpipe(desc->usb_dev,desc->ep_response);
0558             MTS_DEBUG( "transferring from desc->ep_response == %d\n",
0559                    (int)desc->ep_response);
0560     } else {
0561         MTS_DEBUG("transferring to desc->ep_out == %d\n",
0562               (int)desc->ep_out);
0563         pipe = usb_sndbulkpipe(desc->usb_dev,desc->ep_out);
0564     }
0565     desc->context.data_pipe = pipe;
0566 }
0567 
0568 static int mts_scsi_queuecommand_lck(struct scsi_cmnd *srb)
0569 {
0570     mts_scsi_cmnd_callback callback = scsi_done;
0571     struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]);
0572     int res;
0573 
0574     MTS_DEBUG_GOT_HERE();
0575     mts_show_command(srb);
0576     mts_debug_dump(desc);
0577 
0578     if ( srb->device->lun || srb->device->id || srb->device->channel ) {
0579 
0580         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 );
0581 
0582         MTS_DEBUG("this device doesn't exist\n");
0583 
0584         set_host_byte(srb, DID_BAD_TARGET);
0585 
0586         if(likely(callback != NULL))
0587             callback(srb);
0588 
0589         goto out;
0590     }
0591 
0592     
0593     usb_fill_bulk_urb(desc->urb,
0594               desc->usb_dev,
0595               usb_sndbulkpipe(desc->usb_dev,desc->ep_out),
0596               srb->cmnd,
0597               srb->cmd_len,
0598               mts_command_done,
0599               &desc->context
0600               );
0601 
0602 
0603     mts_build_transfer_context( srb, desc );
0604     desc->context.final_callback = callback;
0605     
0606     /* here we need ATOMIC as we are called with the iolock */
0607     res=usb_submit_urb(desc->urb, GFP_ATOMIC);
0608 
0609     if(unlikely(res)){
0610         MTS_ERROR("error %d submitting URB\n",(int)res);
0611         set_host_byte(srb, DID_ERROR);
0612 
0613         if(likely(callback != NULL))
0614             callback(srb);
0615 
0616     }
0617 out:
0618     return 0;
0619 }
0620 
0621 static DEF_SCSI_QCMD(mts_scsi_queuecommand)
0622 
0623 static struct scsi_host_template mts_scsi_host_template = {
0624     .module         = THIS_MODULE,
0625     .name           = "microtekX6",
0626     .proc_name      = "microtekX6",
0627     .queuecommand       = mts_scsi_queuecommand,
0628     .eh_abort_handler   = mts_scsi_abort,
0629     .eh_host_reset_handler  = mts_scsi_host_reset,
0630     .sg_tablesize =     SG_ALL,
0631     .can_queue =        1,
0632     .this_id =      -1,
0633     .emulated =     1,
0634     .slave_alloc =      mts_slave_alloc,
0635     .slave_configure =  mts_slave_configure,
0636     .max_sectors=       256, /* 128 K */
0637 };
0638 
0639 /* The entries of microtek_table must correspond, line-by-line to
0640    the entries of mts_supported_products[]. */
0641 
0642 static const struct usb_device_id mts_usb_ids[] =
0643 {
0644     { USB_DEVICE(0x4ce, 0x0300) },
0645     { USB_DEVICE(0x5da, 0x0094) },
0646     { USB_DEVICE(0x5da, 0x0099) },
0647     { USB_DEVICE(0x5da, 0x009a) },
0648     { USB_DEVICE(0x5da, 0x00a0) },
0649     { USB_DEVICE(0x5da, 0x00a3) },
0650     { USB_DEVICE(0x5da, 0x80a3) },
0651     { USB_DEVICE(0x5da, 0x80ac) },
0652     { USB_DEVICE(0x5da, 0x00b6) },
0653     { }                     /* Terminating entry */
0654 };
0655 
0656 MODULE_DEVICE_TABLE (usb, mts_usb_ids);
0657 
0658 
0659 static int mts_usb_probe(struct usb_interface *intf,
0660              const struct usb_device_id *id)
0661 {
0662     int i;
0663     int ep_out = -1;
0664     int ep_in_set[3]; /* this will break if we have more than three endpoints
0665                which is why we check */
0666     int *ep_in_current = ep_in_set;
0667     int err_retval = -ENOMEM;
0668 
0669     struct mts_desc * new_desc;
0670     struct usb_device *dev = interface_to_usbdev (intf);
0671 
0672     /* the current altsetting on the interface we're probing */
0673     struct usb_host_interface *altsetting;
0674 
0675     MTS_DEBUG_GOT_HERE();
0676     MTS_DEBUG( "usb-device descriptor at %x\n", (int)dev );
0677 
0678     MTS_DEBUG( "product id = 0x%x, vendor id = 0x%x\n",
0679            le16_to_cpu(dev->descriptor.idProduct),
0680            le16_to_cpu(dev->descriptor.idVendor) );
0681 
0682     MTS_DEBUG_GOT_HERE();
0683 
0684     /* the current altsetting on the interface we're probing */
0685     altsetting = intf->cur_altsetting;
0686 
0687 
0688     /* Check if the config is sane */
0689 
0690     if ( altsetting->desc.bNumEndpoints != MTS_EP_TOTAL ) {
0691         MTS_WARNING( "expecting %d got %d endpoints! Bailing out.\n",
0692                  (int)MTS_EP_TOTAL, (int)altsetting->desc.bNumEndpoints );
0693         return -ENODEV;
0694     }
0695 
0696     for( i = 0; i < altsetting->desc.bNumEndpoints; i++ ) {
0697         if ((altsetting->endpoint[i].desc.bmAttributes &
0698              USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK) {
0699 
0700             MTS_WARNING( "can only deal with bulk endpoints; endpoint %d is not bulk.\n",
0701                  (int)altsetting->endpoint[i].desc.bEndpointAddress );
0702         } else {
0703             if (altsetting->endpoint[i].desc.bEndpointAddress &
0704                 USB_DIR_IN)
0705                 *ep_in_current++
0706                     = altsetting->endpoint[i].desc.bEndpointAddress &
0707                     USB_ENDPOINT_NUMBER_MASK;
0708             else {
0709                 if ( ep_out != -1 ) {
0710                     MTS_WARNING( "can only deal with one output endpoints. Bailing out." );
0711                     return -ENODEV;
0712                 }
0713 
0714                 ep_out = altsetting->endpoint[i].desc.bEndpointAddress &
0715                     USB_ENDPOINT_NUMBER_MASK;
0716             }
0717         }
0718 
0719     }
0720 
0721     if (ep_in_current != &ep_in_set[2]) {
0722         MTS_WARNING("couldn't find two input bulk endpoints. Bailing out.\n");
0723         return -ENODEV;
0724     }
0725 
0726     if ( ep_out == -1 ) {
0727         MTS_WARNING( "couldn't find an output bulk endpoint. Bailing out.\n" );
0728         return -ENODEV;
0729     }
0730 
0731 
0732     new_desc = kzalloc(sizeof(struct mts_desc), GFP_KERNEL);
0733     if (!new_desc)
0734         goto out;
0735 
0736     new_desc->urb = usb_alloc_urb(0, GFP_KERNEL);
0737     if (!new_desc->urb)
0738         goto out_kfree;
0739 
0740     new_desc->context.scsi_status = kmalloc(1, GFP_KERNEL);
0741     if (!new_desc->context.scsi_status)
0742         goto out_free_urb;
0743 
0744     new_desc->usb_dev = dev;
0745     new_desc->usb_intf = intf;
0746 
0747     /* endpoints */
0748     new_desc->ep_out = ep_out;
0749     new_desc->ep_response = ep_in_set[0];
0750     new_desc->ep_image = ep_in_set[1];
0751 
0752     if ( new_desc->ep_out != MTS_EP_OUT )
0753         MTS_WARNING( "will this work? Command EP is not usually %d\n",
0754                  (int)new_desc->ep_out );
0755 
0756     if ( new_desc->ep_response != MTS_EP_RESPONSE )
0757         MTS_WARNING( "will this work? Response EP is not usually %d\n",
0758                  (int)new_desc->ep_response );
0759 
0760     if ( new_desc->ep_image != MTS_EP_IMAGE )
0761         MTS_WARNING( "will this work? Image data EP is not usually %d\n",
0762                  (int)new_desc->ep_image );
0763 
0764     new_desc->host = scsi_host_alloc(&mts_scsi_host_template,
0765             sizeof(new_desc));
0766     if (!new_desc->host)
0767         goto out_kfree2;
0768 
0769     new_desc->host->hostdata[0] = (unsigned long)new_desc;
0770     if (scsi_add_host(new_desc->host, &dev->dev)) {
0771         err_retval = -EIO;
0772         goto out_host_put;
0773     }
0774     scsi_scan_host(new_desc->host);
0775 
0776     usb_set_intfdata(intf, new_desc);
0777     return 0;
0778 
0779  out_host_put:
0780     scsi_host_put(new_desc->host);
0781  out_kfree2:
0782     kfree(new_desc->context.scsi_status);
0783  out_free_urb:
0784     usb_free_urb(new_desc->urb);
0785  out_kfree:
0786     kfree(new_desc);
0787  out:
0788     return err_retval;
0789 }
0790 
0791 static void mts_usb_disconnect (struct usb_interface *intf)
0792 {
0793     struct mts_desc *desc = usb_get_intfdata(intf);
0794 
0795     usb_set_intfdata(intf, NULL);
0796 
0797     usb_kill_urb(desc->urb);
0798     scsi_remove_host(desc->host);
0799 
0800     scsi_host_put(desc->host);
0801     usb_free_urb(desc->urb);
0802     kfree(desc->context.scsi_status);
0803     kfree(desc);
0804 }
0805 
0806 module_usb_driver(mts_usb_driver);
0807 
0808 MODULE_AUTHOR( DRIVER_AUTHOR );
0809 MODULE_DESCRIPTION( DRIVER_DESC );
0810 MODULE_LICENSE("GPL");