diff options
Diffstat (limited to 'drivers/usb/image/microtek.c')
| -rw-r--r-- | drivers/usb/image/microtek.c | 187 |
1 files changed, 62 insertions, 125 deletions
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c index 28538db9eaf..37b44b04a70 100644 --- a/drivers/usb/image/microtek.c +++ b/drivers/usb/image/microtek.c @@ -69,7 +69,7 @@ * 20000513 added IDs for all products supported by Windows driver (john) * 20000514 Rewrote mts_scsi_queuecommand to use URBs (john) * 20000514 Version 0.0.8j - * 20000514 Fix reporting of non-existant devices to SCSI layer (john) + * 20000514 Fix reporting of non-existent devices to SCSI layer (john) * 20000514 Added MTS_DEBUG_INT (john) * 20000514 Changed "usb-microtek" to "microtek" for consistency (john) * 20000514 Stupid bug fixes (john) @@ -121,19 +121,16 @@ #include <linux/module.h> #include <linux/kernel.h> -#include <linux/sched.h> #include <linux/signal.h> #include <linux/errno.h> #include <linux/random.h> #include <linux/poll.h> -#include <linux/init.h> #include <linux/slab.h> #include <linux/spinlock.h> -#include <linux/smp_lock.h> #include <linux/usb.h> #include <linux/proc_fs.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <linux/blkdev.h> #include "../../scsi/scsi.h" #include <scsi/scsi_host.h> @@ -157,7 +154,7 @@ static int mts_usb_probe(struct usb_interface *intf, const struct usb_device_id *id); static void mts_usb_disconnect(struct usb_interface *intf); -static struct usb_device_id mts_usb_ids []; +static const struct usb_device_id mts_usb_ids[]; static struct usb_driver mts_usb_driver = { .name = "microtekX6", @@ -187,11 +184,11 @@ static struct usb_driver mts_usb_driver = { printk( KERN_DEBUG MTS_NAME x ) #define MTS_DEBUG_GOT_HERE() \ - MTS_DEBUG("got to %s:%d (%s)\n", __FILE__, (int)__LINE__, __PRETTY_FUNCTION__ ) + MTS_DEBUG("got to %s:%d (%s)\n", __FILE__, (int)__LINE__, __func__ ) #define MTS_DEBUG_INT() \ do { MTS_DEBUG_GOT_HERE(); \ MTS_DEBUG("transfer = 0x%x context = 0x%x\n",(int)transfer,(int)context ); \ - MTS_DEBUG("status = 0x%x data-length = 0x%x sent = 0x%x\n",(int)transfer->status,(int)context->data_length, (int)transfer->actual_length ); \ + MTS_DEBUG("status = 0x%x data-length = 0x%x sent = 0x%x\n",transfer->status,(int)context->data_length, (int)transfer->actual_length ); \ mts_debug_dump(context->instance);\ } while(0) #else @@ -225,7 +222,7 @@ static inline void mts_debug_dump(struct mts_desc* desc) { } -static inline void mts_show_command(Scsi_Cmnd *srb) +static inline void mts_show_command(struct scsi_cmnd *srb) { char *what = NULL; @@ -309,7 +306,7 @@ static inline void mts_show_command(Scsi_Cmnd *srb) #else -static inline void mts_show_command(Scsi_Cmnd * dummy) +static inline void mts_show_command(struct scsi_cmnd * dummy) { } @@ -338,7 +335,7 @@ static int mts_slave_configure (struct scsi_device *s) return 0; } -static int mts_scsi_abort (Scsi_Cmnd *srb) +static int mts_scsi_abort(struct scsi_cmnd *srb) { struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]); @@ -349,28 +346,27 @@ static int mts_scsi_abort (Scsi_Cmnd *srb) return FAILED; } -static int mts_scsi_host_reset (Scsi_Cmnd *srb) +static int mts_scsi_host_reset(struct scsi_cmnd *srb) { struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]); - int result, rc; + int result; MTS_DEBUG_GOT_HERE(); mts_debug_dump(desc); - rc = usb_lock_device_for_reset(desc->usb_dev, desc->usb_intf); - if (rc < 0) - return FAILED; - result = usb_reset_device(desc->usb_dev);; - if (rc) + result = usb_lock_device_for_reset(desc->usb_dev, desc->usb_intf); + if (result == 0) { + result = usb_reset_device(desc->usb_dev); usb_unlock_device(desc->usb_dev); + } return result ? FAILED : SUCCESS; } -static -int mts_scsi_queuecommand (Scsi_Cmnd *srb, mts_scsi_cmnd_callback callback ); +static int +mts_scsi_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *srb); static void mts_transfer_cleanup( struct urb *transfer ); -static void mts_do_sg(struct urb * transfer, struct pt_regs *regs); +static void mts_do_sg(struct urb * transfer); static inline void mts_int_submit_urb (struct urb* transfer, @@ -395,15 +391,12 @@ void mts_int_submit_urb (struct urb* transfer, context ); - transfer->status = 0; - res = usb_submit_urb( transfer, GFP_ATOMIC ); if ( unlikely(res) ) { MTS_INT_ERROR( "could not submit URB! Error was %d\n",(int)res ); context->srb->result = DID_ERROR << 16; mts_transfer_cleanup(transfer); } - return; } @@ -414,10 +407,9 @@ static void mts_transfer_cleanup( struct urb *transfer ) if ( likely(context->final_callback != NULL) ) context->final_callback(context->srb); - } -static void mts_transfer_done( struct urb *transfer, struct pt_regs *regs ) +static void mts_transfer_done( struct urb *transfer ) { MTS_INT_INIT(); @@ -425,8 +417,6 @@ static void mts_transfer_done( struct urb *transfer, struct pt_regs *regs ) context->srb->result |= (unsigned)(*context->scsi_status)<<1; mts_transfer_cleanup(transfer); - - return; } @@ -443,30 +433,31 @@ static void mts_get_status( struct urb *transfer ) mts_transfer_done ); } -static void mts_data_done( struct urb* transfer, struct pt_regs *regs ) +static void mts_data_done( struct urb* transfer ) /* Interrupt context! */ { + int status = transfer->status; MTS_INT_INIT(); if ( context->data_length != transfer->actual_length ) { - context->srb->resid = context->data_length - transfer->actual_length; - } else if ( unlikely(transfer->status) ) { - context->srb->result = (transfer->status == -ENOENT ? DID_ABORT : DID_ERROR)<<16; + scsi_set_resid(context->srb, context->data_length - + transfer->actual_length); + } else if ( unlikely(status) ) { + context->srb->result = (status == -ENOENT ? DID_ABORT : DID_ERROR)<<16; } mts_get_status(transfer); - - return; } -static void mts_command_done( struct urb *transfer, struct pt_regs *regs ) +static void mts_command_done( struct urb *transfer ) /* Interrupt context! */ { + int status = transfer->status; MTS_INT_INIT(); - if ( unlikely(transfer->status) ) { - if (transfer->status == -ENOENT) { + if ( unlikely(status) ) { + if (status == -ENOENT) { /* We are being killed */ MTS_DEBUG_GOT_HERE(); context->srb->result = DID_ABORT<<16; @@ -492,36 +483,36 @@ static void mts_command_done( struct urb *transfer, struct pt_regs *regs ) context->data_pipe, context->data, context->data_length, - context->srb->use_sg > 1 ? mts_do_sg : mts_data_done); + scsi_sg_count(context->srb) > 1 ? + mts_do_sg : mts_data_done); } else { mts_get_status(transfer); } } - - return; } -static void mts_do_sg (struct urb* transfer, struct pt_regs *regs) +static void mts_do_sg (struct urb* transfer) { struct scatterlist * sg; + int status = transfer->status; MTS_INT_INIT(); - MTS_DEBUG("Processing fragment %d of %d\n", context->fragment,context->srb->use_sg); + MTS_DEBUG("Processing fragment %d of %d\n", context->fragment, + scsi_sg_count(context->srb)); - if (unlikely(transfer->status)) { - context->srb->result = (transfer->status == -ENOENT ? DID_ABORT : DID_ERROR)<<16; + if (unlikely(status)) { + context->srb->result = (status == -ENOENT ? DID_ABORT : DID_ERROR)<<16; mts_transfer_cleanup(transfer); } - sg = context->srb->buffer; + sg = scsi_sglist(context->srb); context->fragment++; mts_int_submit_urb(transfer, context->data_pipe, - page_address(sg[context->fragment].page) + - sg[context->fragment].offset, + sg_virt(&sg[context->fragment]), sg[context->fragment].length, - context->fragment + 1 == context->srb->use_sg ? mts_data_done : mts_do_sg); - return; + context->fragment + 1 == scsi_sg_count(context->srb) ? + mts_data_done : mts_do_sg); } static const u8 mts_read_image_sig[] = { 0x28, 00, 00, 00 }; @@ -537,7 +528,7 @@ static const unsigned char mts_direction[256/8] = { #define MTS_DIRECTION_IS_IN(x) ((mts_direction[x>>3] >> (x & 7)) & 1) static void -mts_build_transfer_context( Scsi_Cmnd *srb, struct mts_desc* desc ) +mts_build_transfer_context(struct scsi_cmnd *srb, struct mts_desc* desc) { int pipe; struct scatterlist * sg; @@ -548,21 +539,13 @@ mts_build_transfer_context( Scsi_Cmnd *srb, struct mts_desc* desc ) desc->context.srb = srb; desc->context.fragment = 0; - if (!srb->use_sg) { - if ( !srb->bufflen ){ - desc->context.data = NULL; - desc->context.data_length = 0; - return; - } else { - desc->context.data = srb->buffer; - desc->context.data_length = srb->bufflen; - MTS_DEBUG("length = %d or %d\n", - srb->request_bufflen, srb->bufflen); - } + if (!scsi_bufflen(srb)) { + desc->context.data = NULL; + desc->context.data_length = 0; + return; } else { - MTS_DEBUG("Using scatter/gather\n"); - sg = srb->buffer; - desc->context.data = page_address(sg[0].page) + sg[0].offset; + sg = scsi_sglist(srb); + desc->context.data = sg_virt(&sg[0]); desc->context.data_length = sg[0].length; } @@ -573,14 +556,14 @@ mts_build_transfer_context( Scsi_Cmnd *srb, struct mts_desc* desc ) if ( !memcmp( srb->cmnd, mts_read_image_sig, mts_read_image_sig_len ) ) { pipe = usb_rcvbulkpipe(desc->usb_dev,desc->ep_image); - MTS_DEBUG( "transfering from desc->ep_image == %d\n", + MTS_DEBUG( "transferring from desc->ep_image == %d\n", (int)desc->ep_image ); } else if ( MTS_DIRECTION_IS_IN(srb->cmnd[0]) ) { pipe = usb_rcvbulkpipe(desc->usb_dev,desc->ep_response); - MTS_DEBUG( "transfering from desc->ep_response == %d\n", + MTS_DEBUG( "transferring from desc->ep_response == %d\n", (int)desc->ep_response); } else { - MTS_DEBUG("transfering to desc->ep_out == %d\n", + MTS_DEBUG("transferring to desc->ep_out == %d\n", (int)desc->ep_out); pipe = usb_sndbulkpipe(desc->usb_dev,desc->ep_out); } @@ -588,8 +571,8 @@ mts_build_transfer_context( Scsi_Cmnd *srb, struct mts_desc* desc ) } -static -int mts_scsi_queuecommand( Scsi_Cmnd *srb, mts_scsi_cmnd_callback callback ) +static int +mts_scsi_queuecommand_lck(struct scsi_cmnd *srb, mts_scsi_cmnd_callback callback) { struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]); int err = 0; @@ -642,6 +625,8 @@ out: return err; } +static DEF_SCSI_QCMD(mts_scsi_queuecommand) + static struct scsi_host_template mts_scsi_host_template = { .module = THIS_MODULE, .name = "microtekX6", @@ -660,37 +645,10 @@ static struct scsi_host_template mts_scsi_host_template = { .max_sectors= 256, /* 128 K */ }; -struct vendor_product -{ - char* name; - enum - { - mts_sup_unknown=0, - mts_sup_alpha, - mts_sup_full - } - support_status; -} ; - - -/* These are taken from the msmUSB.inf file on the Windows driver CD */ -static const struct vendor_product mts_supported_products[] = -{ - { "Phantom 336CX", mts_sup_unknown}, - { "Phantom 336CX", mts_sup_unknown}, - { "Scanmaker X6", mts_sup_alpha}, - { "Phantom C6", mts_sup_unknown}, - { "Phantom 336CX", mts_sup_unknown}, - { "ScanMaker V6USL", mts_sup_unknown}, - { "ScanMaker V6USL", mts_sup_unknown}, - { "Scanmaker V6UL", mts_sup_unknown}, - { "Scanmaker V6UPL", mts_sup_alpha}, -}; - /* The entries of microtek_table must correspond, line-by-line to the entries of mts_supported_products[]. */ -static struct usb_device_id mts_usb_ids [] = +static const struct usb_device_id mts_usb_ids[] = { { USB_DEVICE(0x4ce, 0x0300) }, { USB_DEVICE(0x5da, 0x0094) }, @@ -718,7 +676,6 @@ static int mts_usb_probe(struct usb_interface *intf, int err_retval = -ENOMEM; struct mts_desc * new_desc; - struct vendor_product const* p; struct usb_device *dev = interface_to_usbdev (intf); /* the current altsetting on the interface we're probing */ @@ -733,15 +690,6 @@ static int mts_usb_probe(struct usb_interface *intf, MTS_DEBUG_GOT_HERE(); - p = &mts_supported_products[id - mts_usb_ids]; - - MTS_DEBUG_GOT_HERE(); - - MTS_DEBUG( "found model %s\n", p->name ); - if ( p->support_status != mts_sup_full ) - MTS_MESSAGE( "model %s is not known to be fully supported, reports welcome!\n", - p->name ); - /* the current altsetting on the interface we're probing */ altsetting = intf->cur_altsetting; @@ -796,11 +744,10 @@ static int mts_usb_probe(struct usb_interface *intf, new_desc->context.scsi_status = kmalloc(1, GFP_KERNEL); if (!new_desc->context.scsi_status) - goto out_kfree2; + goto out_free_urb; new_desc->usb_dev = dev; new_desc->usb_intf = intf; - init_MUTEX(&new_desc->lock); /* endpoints */ new_desc->ep_out = ep_out; @@ -822,18 +769,20 @@ static int mts_usb_probe(struct usb_interface *intf, new_desc->host = scsi_host_alloc(&mts_scsi_host_template, sizeof(new_desc)); if (!new_desc->host) - goto out_free_urb; + goto out_kfree2; new_desc->host->hostdata[0] = (unsigned long)new_desc; - if (scsi_add_host(new_desc->host, NULL)) { + if (scsi_add_host(new_desc->host, &dev->dev)) { err_retval = -EIO; - goto out_free_urb; + goto out_host_put; } scsi_scan_host(new_desc->host); usb_set_intfdata(intf, new_desc); return 0; + out_host_put: + scsi_host_put(new_desc->host); out_kfree2: kfree(new_desc->context.scsi_status); out_free_urb: @@ -859,19 +808,7 @@ static void mts_usb_disconnect (struct usb_interface *intf) kfree(desc); } - -static int __init microtek_drv_init(void) -{ - return usb_register(&mts_usb_driver); -} - -static void __exit microtek_drv_exit(void) -{ - usb_deregister(&mts_usb_driver); -} - -module_init(microtek_drv_init); -module_exit(microtek_drv_exit); +module_usb_driver(mts_usb_driver); MODULE_AUTHOR( DRIVER_AUTHOR ); MODULE_DESCRIPTION( DRIVER_DESC ); |
