Lines Matching +full:usb +full:- +full:version

1 // SPDX-License-Identifier: GPL-2.0
2 /* Driver for Microtek Scanmaker X6 USB scanner, and possibly others.
5 * (C) Copyright 2000 Oliver Neukum <Oliver.Neukum@lrz.uni-muenchen.de>
7 * Parts shamelessly stolen from usb-storage and copyright by their
10 * This driver implements a SCSI host controller driver and a USB
11 * device driver. To avoid confusion, all the USB related stuff is
15 * their USB protocol to us, so we had to reverse engineer them. We
18 * The X6 USB has three bulk endpoints, one output (0x1) down which
52 * Microtek NV sent us a more up to date version of the document. If
72 * 20000514 Version 0.0.8j
73 * 20000514 Fix reporting of non-existent devices to SCSI layer (john)
75 * 20000514 Changed "usb-microtek" to "microtek" for consistency (john)
77 * 20000514 Version 0.0.9j
80 * 20000515 Version 0.0.10j
82 * 20000515 Version 0.0.11j
86 * 20000516 Version 0.0.12j
88 * 20000517 Added mts_debug_dump to print ll USB info (john)
90 * 20000518 Version 0.0.13j
95 * 20000523 Version 0.0.14j (though version 0.1 has come out?)
97 * 20000602 Version 0.2.0
99 * 20000603 Version 0.2.1
101 * 20000620 Version 0.2.2
105 * 20000822 Version 0.2.3
107 * 20000913 Version 0.2.4
109 * 20010210 Version 0.3.0
111 * 20010218 Version 0.4.0
113 * 20010218 Version 0.4.1
115 * 20010306 Version 0.4.2
118 * 20010320 Version 0.4.3
119 * 20010408 Identify version on module load.
131 #include <linux/usb.h>
145 #define DRIVER_AUTHOR "John Fremlin <vii@penguinpowered.com>, Oliver Neukum <Oliver.Neukum@lrz.uni-
146 #define DRIVER_DESC "Microtek Scanmaker X6 USB scanner driver"
152 /* USB layer driver interface */
171 #define MTS_NAME "microtek usb (rev " MTS_VERSION "): "
192 …MTS_DEBUG("status = 0x%x data-length = 0x%x sent = 0x%x\n",transfer->status,(int)context->data_len…
193 mts_debug_dump(context->instance);\
208 struct mts_transfer_context* context = (struct mts_transfer_context*)transfer->context; \
216 (int)desc->usb_dev->toggle[1],(int)desc->usb_dev->toggle[0] in mts_debug_dump()
219 usb_sndbulkpipe(desc->usb_dev,desc->ep_out), in mts_debug_dump()
220 usb_rcvbulkpipe(desc->usb_dev,desc->ep_response), in mts_debug_dump()
221 usb_rcvbulkpipe(desc->usb_dev,desc->ep_image) in mts_debug_dump()
230 switch (srb->cmnd[0]) { in mts_show_command()
300 MTS_DEBUG( "Command %s (%d bytes)\n", what, srb->cmd_len); in mts_show_command()
303 MTS_DEBUG( " %10ph\n", srb->cmnd); in mts_show_command()
322 usb_kill_urb( desc->urb ); in mts_urb_abort()
327 s->inquiry_len = 0x24; in mts_slave_alloc()
333 struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]); in mts_scsi_abort()
344 struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]); in mts_scsi_host_reset()
350 result = usb_lock_device_for_reset(desc->usb_dev, desc->usb_intf); in mts_scsi_host_reset()
352 result = usb_reset_device(desc->usb_dev); in mts_scsi_host_reset()
353 usb_unlock_device(desc->usb_dev); in mts_scsi_host_reset()
372 /* Holding transfer->context->lock! */ in mts_int_submit_urb()
379 context->instance->usb_dev, in mts_int_submit_urb()
390 set_host_byte(context->srb, DID_ERROR); in mts_int_submit_urb()
401 if ( likely(context->final_callback != NULL) ) in mts_transfer_cleanup()
402 context->final_callback(context->srb); in mts_transfer_cleanup()
409 context->srb->result &= MTS_SCSI_ERR_MASK; in mts_transfer_done()
410 context->srb->result |= (unsigned)(*context->scsi_status)<<1; in mts_transfer_done()
422 usb_rcvbulkpipe(context->instance->usb_dev, in mts_get_status()
423 context->instance->ep_response), in mts_get_status()
424 context->scsi_status, in mts_get_status()
432 int status = transfer->status; in mts_data_done()
435 if ( context->data_length != transfer->actual_length ) { in mts_data_done()
436 scsi_set_resid(context->srb, context->data_length - in mts_data_done()
437 transfer->actual_length); in mts_data_done()
439 set_host_byte(context->srb, (status == -ENOENT ? DID_ABORT : DID_ERROR)); in mts_data_done()
449 int status = transfer->status; in mts_command_done()
453 if (status == -ENOENT) { in mts_command_done()
456 set_host_byte(context->srb, DID_ABORT); in mts_command_done()
461 set_host_byte(context->srb, DID_ERROR); in mts_command_done()
468 if (context->srb->cmnd[0] == REQUEST_SENSE) { in mts_command_done()
470 context->data_pipe, in mts_command_done()
471 context->srb->sense_buffer, in mts_command_done()
472 context->data_length, in mts_command_done()
474 } else { if ( context->data ) { in mts_command_done()
476 context->data_pipe, in mts_command_done()
477 context->data, in mts_command_done()
478 context->data_length, in mts_command_done()
479 scsi_sg_count(context->srb) > 1 ? in mts_command_done()
489 int status = transfer->status; in mts_do_sg()
492 MTS_DEBUG("Processing fragment %d of %d\n", context->fragment, in mts_do_sg()
493 scsi_sg_count(context->srb)); in mts_do_sg()
496 set_host_byte(context->srb, (status == -ENOENT ? DID_ABORT : DID_ERROR)); in mts_do_sg()
500 context->curr_sg = sg_next(context->curr_sg); in mts_do_sg()
502 context->data_pipe, in mts_do_sg()
503 sg_virt(context->curr_sg), in mts_do_sg()
504 context->curr_sg->length, in mts_do_sg()
505 sg_is_last(context->curr_sg) ? in mts_do_sg()
528 desc->context.instance = desc; in mts_build_transfer_context()
529 desc->context.srb = srb; in mts_build_transfer_context()
532 desc->context.data = NULL; in mts_build_transfer_context()
533 desc->context.data_length = 0; in mts_build_transfer_context()
536 desc->context.curr_sg = scsi_sglist(srb); in mts_build_transfer_context()
537 desc->context.data = sg_virt(desc->context.curr_sg); in mts_build_transfer_context()
538 desc->context.data_length = desc->context.curr_sg->length; in mts_build_transfer_context()
542 /* can't rely on srb->sc_data_direction */ in mts_build_transfer_context()
544 /* Brutally ripped from usb-storage */ in mts_build_transfer_context()
546 if ( !memcmp( srb->cmnd, mts_read_image_sig, mts_read_image_sig_len ) in mts_build_transfer_context()
547 ) { pipe = usb_rcvbulkpipe(desc->usb_dev,desc->ep_image); in mts_build_transfer_context()
548 MTS_DEBUG( "transferring from desc->ep_image == %d\n", in mts_build_transfer_context()
549 (int)desc->ep_image ); in mts_build_transfer_context()
550 } else if ( MTS_DIRECTION_IS_IN(srb->cmnd[0]) ) { in mts_build_transfer_context()
551 pipe = usb_rcvbulkpipe(desc->usb_dev,desc->ep_response); in mts_build_transfer_context()
552 MTS_DEBUG( "transferring from desc->ep_response == %d\n", in mts_build_transfer_context()
553 (int)desc->ep_response); in mts_build_transfer_context()
555 MTS_DEBUG("transferring to desc->ep_out == %d\n", in mts_build_transfer_context()
556 (int)desc->ep_out); in mts_build_transfer_context()
557 pipe = usb_sndbulkpipe(desc->usb_dev,desc->ep_out); in mts_build_transfer_context()
559 desc->context.data_pipe = pipe; in mts_build_transfer_context()
565 struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]); in mts_scsi_queuecommand_lck()
572 if ( srb->device->lun || srb->device->id || srb->device->channel ) { in mts_scsi_queuecommand_lck()
574 …UN=%d ID=%d CHANNEL=%d from SCSI layer\n",(int)srb->device->lun,(int)srb->device->id, (int)srb->de… in mts_scsi_queuecommand_lck()
587 usb_fill_bulk_urb(desc->urb, in mts_scsi_queuecommand_lck()
588 desc->usb_dev, in mts_scsi_queuecommand_lck()
589 usb_sndbulkpipe(desc->usb_dev,desc->ep_out), in mts_scsi_queuecommand_lck()
590 srb->cmnd, in mts_scsi_queuecommand_lck()
591 srb->cmd_len, in mts_scsi_queuecommand_lck()
593 &desc->context in mts_scsi_queuecommand_lck()
598 desc->context.final_callback = callback; in mts_scsi_queuecommand_lck()
601 res=usb_submit_urb(desc->urb, GFP_ATOMIC); in mts_scsi_queuecommand_lck()
626 .this_id = -1,
633 /* The entries of microtek_table must correspond, line-by-line to
650 MODULE_DEVICE_TABLE (usb, mts_usb_ids);
657 int ep_out = -1; in mts_usb_probe()
661 int err_retval = -ENOMEM; in mts_usb_probe()
670 MTS_DEBUG( "usb-device descriptor at %x\n", (int)dev ); in mts_usb_probe()
673 le16_to_cpu(dev->descriptor.idProduct), in mts_usb_probe()
674 le16_to_cpu(dev->descriptor.idVendor) ); in mts_usb_probe()
679 altsetting = intf->cur_altsetting; in mts_usb_probe()
684 if ( altsetting->desc.bNumEndpoints != MTS_EP_TOTAL ) { in mts_usb_probe()
686 (int)MTS_EP_TOTAL, (int)altsetting->desc.bNumEndpoints ); in mts_usb_probe()
687 return -ENODEV; in mts_usb_probe()
690 for( i = 0; i < altsetting->desc.bNumEndpoints; i++ ) { in mts_usb_probe()
691 if ((altsetting->endpoint[i].desc.bmAttributes & in mts_usb_probe()
695 (int)altsetting->endpoint[i].desc.bEndpointAddress ); in mts_usb_probe()
697 if (altsetting->endpoint[i].desc.bEndpointAddress & in mts_usb_probe()
700 = altsetting->endpoint[i].desc.bEndpointAddress & in mts_usb_probe()
703 if ( ep_out != -1 ) { in mts_usb_probe()
705 return -ENODEV; in mts_usb_probe()
708 ep_out = altsetting->endpoint[i].desc.bEndpointAddress & in mts_usb_probe()
717 return -ENODEV; in mts_usb_probe()
720 if ( ep_out == -1 ) { in mts_usb_probe()
722 return -ENODEV; in mts_usb_probe()
730 new_desc->urb = usb_alloc_urb(0, GFP_KERNEL); in mts_usb_probe()
731 if (!new_desc->urb) in mts_usb_probe()
734 new_desc->context.scsi_status = kmalloc(1, GFP_KERNEL); in mts_usb_probe()
735 if (!new_desc->context.scsi_status) in mts_usb_probe()
738 new_desc->usb_dev = dev; in mts_usb_probe()
739 new_desc->usb_intf = intf; in mts_usb_probe()
742 new_desc->ep_out = ep_out; in mts_usb_probe()
743 new_desc->ep_response = ep_in_set[0]; in mts_usb_probe()
744 new_desc->ep_image = ep_in_set[1]; in mts_usb_probe()
746 if ( new_desc->ep_out != MTS_EP_OUT ) in mts_usb_probe()
748 (int)new_desc->ep_out ); in mts_usb_probe()
750 if ( new_desc->ep_response != MTS_EP_RESPONSE ) in mts_usb_probe()
752 (int)new_desc->ep_response ); in mts_usb_probe()
754 if ( new_desc->ep_image != MTS_EP_IMAGE ) in mts_usb_probe()
756 (int)new_desc->ep_image ); in mts_usb_probe()
758 new_desc->host = scsi_host_alloc(&mts_scsi_host_template, in mts_usb_probe()
760 if (!new_desc->host) in mts_usb_probe()
763 new_desc->host->hostdata[0] = (unsigned long)new_desc; in mts_usb_probe()
764 if (scsi_add_host(new_desc->host, &dev->dev)) { in mts_usb_probe()
765 err_retval = -EIO; in mts_usb_probe()
768 scsi_scan_host(new_desc->host); in mts_usb_probe()
774 scsi_host_put(new_desc->host); in mts_usb_probe()
776 kfree(new_desc->context.scsi_status); in mts_usb_probe()
778 usb_free_urb(new_desc->urb); in mts_usb_probe()
791 usb_kill_urb(desc->urb); in mts_usb_disconnect()
792 scsi_remove_host(desc->host); in mts_usb_disconnect()
794 scsi_host_put(desc->host); in mts_usb_disconnect()
795 usb_free_urb(desc->urb); in mts_usb_disconnect()
796 kfree(desc->context.scsi_status); in mts_usb_disconnect()