X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fusb%2Fimage%2Fmicrotek.c;h=8ccddf74534a8e35db419c35030a58524385b7b9;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=230efaf7bfe3484009cd9d80d016bd07e0800d97;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c index 230efaf7b..8ccddf745 100644 --- a/drivers/usb/image/microtek.c +++ b/drivers/usb/image/microtek.c @@ -160,7 +160,6 @@ static void mts_usb_disconnect(struct usb_interface *intf); static struct usb_device_id mts_usb_ids []; static struct usb_driver mts_usb_driver = { - .owner = THIS_MODULE, .name = "microtekX6", .probe = mts_usb_probe, .disconnect = mts_usb_disconnect, @@ -214,8 +213,8 @@ static struct usb_driver mts_usb_driver = { #ifdef MTS_DO_DEBUG static inline void mts_debug_dump(struct mts_desc* desc) { - MTS_DEBUG("desc at 0x%x: halted = %02x%02x, toggle = %02x%02x\n", - (int)desc,(int)desc->usb_dev->halted[1],(int)desc->usb_dev->halted[0], + MTS_DEBUG("desc at 0x%x: toggle = %02x%02x\n", + (int)desc, (int)desc->usb_dev->toggle[1],(int)desc->usb_dev->toggle[0] ); MTS_DEBUG("ep_out=%x ep_response=%x ep_image=%x\n", @@ -226,7 +225,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; @@ -310,7 +309,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) { } @@ -324,10 +323,22 @@ static inline void mts_urb_abort(struct mts_desc* desc) { MTS_DEBUG_GOT_HERE(); mts_debug_dump(desc); - usb_unlink_urb( desc->urb ); + usb_kill_urb( desc->urb ); } -static int mts_scsi_abort (Scsi_Cmnd *srb) +static int mts_slave_alloc (struct scsi_device *s) +{ + s->inquiry_len = 0x24; + return 0; +} + +static int mts_slave_configure (struct scsi_device *s) +{ + blk_queue_dma_alignment(s->request_queue, (512 - 1)); + return 0; +} + +static int mts_scsi_abort(struct scsi_cmnd *srb) { struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]); @@ -335,28 +346,33 @@ static int mts_scsi_abort (Scsi_Cmnd *srb) mts_urb_abort(desc); - return SCSI_ABORT_PENDING; + 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; MTS_DEBUG_GOT_HERE(); mts_debug_dump(desc); - usb_reset_device(desc->usb_dev); /*FIXME: untested on new reset code */ - return 0; /* RANT why here 0 and not SUCCESS */ + 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) + 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_cmnd *srb, mts_scsi_cmnd_callback callback); 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); -inline static +static inline void mts_int_submit_urb (struct urb* transfer, int pipe, void* data, @@ -401,12 +417,12 @@ static void mts_transfer_cleanup( struct urb *transfer ) } -static void mts_transfer_done( struct urb *transfer, struct pt_regs *regs ) +static void mts_transfer_done( struct urb *transfer ) { MTS_INT_INIT(); context->srb->result &= MTS_SCSI_ERR_MASK; - context->srb->result |= (unsigned)context->status<<1; + context->srb->result |= (unsigned)(*context->scsi_status)<<1; mts_transfer_cleanup(transfer); @@ -422,12 +438,12 @@ static void mts_get_status( struct urb *transfer ) mts_int_submit_urb(transfer, usb_rcvbulkpipe(context->instance->usb_dev, context->instance->ep_response), - &context->status, + context->scsi_status, 1, 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! */ { MTS_INT_INIT(); @@ -444,7 +460,7 @@ static void mts_data_done( struct urb* transfer, struct pt_regs *regs ) } -static void mts_command_done( struct urb *transfer, struct pt_regs *regs ) +static void mts_command_done( struct urb *transfer ) /* Interrupt context! */ { MTS_INT_INIT(); @@ -476,7 +492,7 @@ static void mts_command_done( struct urb *transfer, struct pt_regs *regs ) context->data_pipe, context->data, context->data_length, - context->srb->use_sg ? mts_do_sg : mts_data_done); + context->srb->use_sg > 1 ? mts_do_sg : mts_data_done); } else { mts_get_status(transfer); } @@ -485,7 +501,7 @@ static void mts_command_done( struct urb *transfer, struct pt_regs *regs ) return; } -static void mts_do_sg (struct urb* transfer, struct pt_regs *regs) +static void mts_do_sg (struct urb* transfer) { struct scatterlist * sg; MTS_INT_INIT(); @@ -497,7 +513,7 @@ static void mts_do_sg (struct urb* transfer, struct pt_regs *regs) mts_transfer_cleanup(transfer); } - sg = context->srb->buffer; + sg = context->srb->request_buffer; context->fragment++; mts_int_submit_urb(transfer, context->data_pipe, @@ -521,7 +537,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; @@ -533,19 +549,19 @@ mts_build_transfer_context( Scsi_Cmnd *srb, struct mts_desc* desc ) desc->context.fragment = 0; if (!srb->use_sg) { - if ( !srb->bufflen ){ + if ( !srb->request_bufflen ){ desc->context.data = NULL; desc->context.data_length = 0; return; } else { - desc->context.data = srb->buffer; - desc->context.data_length = srb->bufflen; + desc->context.data = srb->request_buffer; + desc->context.data_length = srb->request_bufflen; MTS_DEBUG("length = %d or %d\n", srb->request_bufflen, srb->bufflen); } } else { MTS_DEBUG("Using scatter/gather\n"); - sg = srb->buffer; + sg = srb->request_buffer; desc->context.data = page_address(sg[0].page) + sg[0].offset; desc->context.data_length = sg[0].length; } @@ -572,8 +588,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(struct scsi_cmnd *srb, mts_scsi_cmnd_callback callback) { struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]); int err = 0; @@ -622,12 +638,11 @@ int mts_scsi_queuecommand( Scsi_Cmnd *srb, mts_scsi_cmnd_callback callback ) callback(srb); } - out: return err; } -static Scsi_Host_Template mts_scsi_host_template = { +static struct scsi_host_template mts_scsi_host_template = { .module = THIS_MODULE, .name = "microtekX6", .proc_name = "microtekX6", @@ -640,6 +655,9 @@ static Scsi_Host_Template mts_scsi_host_template = { .cmd_per_lun = 1, .use_clustering = 1, .emulated = 1, + .slave_alloc = mts_slave_alloc, + .slave_configure = mts_slave_configure, + .max_sectors= 256, /* 128 K */ }; struct vendor_product @@ -656,7 +674,7 @@ struct vendor_product /* These are taken from the msmUSB.inf file on the Windows driver CD */ -const static struct vendor_product mts_supported_products[] = +static const struct vendor_product mts_supported_products[] = { { "Phantom 336CX", mts_sup_unknown}, { "Phantom 336CX", mts_sup_unknown}, @@ -697,6 +715,7 @@ static int mts_usb_probe(struct usb_interface *intf, int ep_in_set[3]; /* this will break if we have more than three endpoints which is why we check */ int *ep_in_current = ep_in_set; + int err_retval = -ENOMEM; struct mts_desc * new_desc; struct vendor_product const* p; @@ -709,8 +728,8 @@ static int mts_usb_probe(struct usb_interface *intf, MTS_DEBUG( "usb-device descriptor at %x\n", (int)dev ); MTS_DEBUG( "product id = 0x%x, vendor id = 0x%x\n", - (int)dev->descriptor.idProduct, - (int)dev->descriptor.idVendor ); + le16_to_cpu(dev->descriptor.idProduct), + le16_to_cpu(dev->descriptor.idVendor) ); MTS_DEBUG_GOT_HERE(); @@ -765,18 +784,22 @@ static int mts_usb_probe(struct usb_interface *intf, MTS_WARNING( "couldn't find an output bulk endpoint. Bailing out.\n" ); return -ENODEV; } - - - new_desc = kmalloc(sizeof(struct mts_desc), GFP_KERNEL); + + + new_desc = kzalloc(sizeof(struct mts_desc), GFP_KERNEL); if (!new_desc) goto out; - memset(new_desc, 0, sizeof(*new_desc)); new_desc->urb = usb_alloc_urb(0, GFP_KERNEL); if (!new_desc->urb) goto out_kfree; + new_desc->context.scsi_status = kmalloc(1, GFP_KERNEL); + if (!new_desc->context.scsi_status) + goto out_free_urb; + new_desc->usb_dev = dev; + new_desc->usb_intf = intf; init_MUTEX(&new_desc->lock); /* endpoints */ @@ -799,21 +822,28 @@ 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; - scsi_add_host(new_desc->host, NULL); /* XXX handle failure */ + if (scsi_add_host(new_desc->host, NULL)) { + err_retval = -EIO; + 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: usb_free_urb(new_desc->urb); out_kfree: kfree(new_desc); out: - return -ENOMEM; + return err_retval; } static void mts_usb_disconnect (struct usb_interface *intf) @@ -822,11 +852,12 @@ static void mts_usb_disconnect (struct usb_interface *intf) usb_set_intfdata(intf, NULL); + usb_kill_urb(desc->urb); scsi_remove_host(desc->host); - usb_unlink_urb(desc->urb); - scsi_host_put(desc->host); + scsi_host_put(desc->host); usb_free_urb(desc->urb); + kfree(desc->context.scsi_status); kfree(desc); } @@ -847,5 +878,3 @@ module_exit(microtek_drv_exit); MODULE_AUTHOR( DRIVER_AUTHOR ); MODULE_DESCRIPTION( DRIVER_DESC ); MODULE_LICENSE("GPL"); - -