diff options
Diffstat (limited to 'drivers/usb/storage/jumpshot.c')
| -rw-r--r-- | drivers/usb/storage/jumpshot.c | 166 |
1 files changed, 127 insertions, 39 deletions
diff --git a/drivers/usb/storage/jumpshot.c b/drivers/usb/storage/jumpshot.c index 61097cbb158..563078be654 100644 --- a/drivers/usb/storage/jumpshot.c +++ b/drivers/usb/storage/jumpshot.c @@ -1,7 +1,5 @@ /* Driver for Lexar "Jumpshot" Compact Flash reader * - * $Id: jumpshot.c,v 1.7 2002/02/25 00:40:13 mdharm Exp $ - * * jumpshot driver v0.1: * * First release @@ -48,6 +46,7 @@ */ #include <linux/errno.h> +#include <linux/module.h> #include <linux/slab.h> #include <scsi/scsi.h> @@ -57,9 +56,61 @@ #include "transport.h" #include "protocol.h" #include "debug.h" -#include "jumpshot.h" +MODULE_DESCRIPTION("Driver for Lexar \"Jumpshot\" Compact Flash reader"); +MODULE_AUTHOR("Jimmie Mayfield <mayfield+usb@sackheads.org>"); +MODULE_LICENSE("GPL"); + +/* + * The table of devices + */ +#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ + vendorName, productName, useProtocol, useTransport, \ + initFunction, flags) \ +{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ + .driver_info = (flags) } + +static struct usb_device_id jumpshot_usb_ids[] = { +# include "unusual_jumpshot.h" + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(usb, jumpshot_usb_ids); + +#undef UNUSUAL_DEV + +/* + * The flags table + */ +#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ + vendor_name, product_name, use_protocol, use_transport, \ + init_function, Flags) \ +{ \ + .vendorName = vendor_name, \ + .productName = product_name, \ + .useProtocol = use_protocol, \ + .useTransport = use_transport, \ + .initFunction = init_function, \ +} + +static struct us_unusual_dev jumpshot_unusual_dev_list[] = { +# include "unusual_jumpshot.h" + { } /* Terminating entry */ +}; + +#undef UNUSUAL_DEV + + +struct jumpshot_info { + unsigned long sectors; /* total sector count */ + unsigned long ssize; /* sector size in bytes */ + + /* the following aren't used yet */ + unsigned char sense_key; + unsigned long sense_asc; /* additional sense code */ + unsigned long sense_ascq; /* additional sense code qualifier */ +}; + static inline int jumpshot_bulk_read(struct us_data *us, unsigned char *data, unsigned int len) @@ -67,7 +118,7 @@ static inline int jumpshot_bulk_read(struct us_data *us, if (len == 0) return USB_STOR_XFER_GOOD; - US_DEBUGP("jumpshot_bulk_read: len = %d\n", len); + usb_stor_dbg(us, "len = %d\n", len); return usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, data, len, NULL); } @@ -80,7 +131,7 @@ static inline int jumpshot_bulk_write(struct us_data *us, if (len == 0) return USB_STOR_XFER_GOOD; - US_DEBUGP("jumpshot_bulk_write: len = %d\n", len); + usb_stor_dbg(us, "len = %d\n", len); return usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, data, len, NULL); } @@ -101,8 +152,7 @@ static int jumpshot_get_status(struct us_data *us) return USB_STOR_TRANSPORT_ERROR; if (us->iobuf[0] != 0x50) { - US_DEBUGP("jumpshot_get_status: 0x%2x\n", - us->iobuf[0]); + usb_stor_dbg(us, "0x%2x\n", us->iobuf[0]); return USB_STOR_TRANSPORT_ERROR; } @@ -167,7 +217,7 @@ static int jumpshot_read_data(struct us_data *us, if (result != USB_STOR_XFER_GOOD) goto leave; - US_DEBUGP("jumpshot_read_data: %d bytes\n", len); + usb_stor_dbg(us, "%d bytes\n", len); // Store the data in the transfer buffer usb_stor_access_xfer_buf(buffer, len, us->srb, @@ -263,7 +313,7 @@ static int jumpshot_write_data(struct us_data *us, } while ((result != USB_STOR_TRANSPORT_GOOD) && (waitcount < 10)); if (result != USB_STOR_TRANSPORT_GOOD) - US_DEBUGP("jumpshot_write_data: Gah! Waitcount = 10. Bad write!?\n"); + usb_stor_dbg(us, "Gah! Waitcount = 10. Bad write!?\n"); sector += thistime; totallen -= len; @@ -284,7 +334,7 @@ static int jumpshot_id_device(struct us_data *us, unsigned char *reply; int rc; - if (!us || !info) + if (!info) return USB_STOR_TRANSPORT_ERROR; command[0] = 0xE0; @@ -298,8 +348,7 @@ static int jumpshot_id_device(struct us_data *us, 0, 0x20, 0, 6, command, 2); if (rc != USB_STOR_XFER_GOOD) { - US_DEBUGP("jumpshot_id_device: Gah! " - "send_control for read_capacity failed\n"); + usb_stor_dbg(us, "Gah! send_control for read_capacity failed\n"); rc = USB_STOR_TRANSPORT_ERROR; goto leave; } @@ -349,17 +398,17 @@ static int jumpshot_handle_mode_sense(struct us_data *us, switch (pc) { case 0x0: - US_DEBUGP("jumpshot_handle_mode_sense: Current values\n"); - break; + usb_stor_dbg(us, "Current values\n"); + break; case 0x1: - US_DEBUGP("jumpshot_handle_mode_sense: Changeable values\n"); - break; + usb_stor_dbg(us, "Changeable values\n"); + break; case 0x2: - US_DEBUGP("jumpshot_handle_mode_sense: Default values\n"); - break; + usb_stor_dbg(us, "Default values\n"); + break; case 0x3: - US_DEBUGP("jumpshot_handle_mode_sense: Saves values\n"); - break; + usb_stor_dbg(us, "Saves values\n"); + break; } memset(ptr, 0, 8); @@ -431,7 +480,7 @@ static void jumpshot_info_destructor(void *extra) // Transport for the Lexar 'Jumpshot' // -int jumpshot_transport(struct scsi_cmnd * srb, struct us_data *us) +static int jumpshot_transport(struct scsi_cmnd *srb, struct us_data *us) { struct jumpshot_info *info; int rc; @@ -443,17 +492,16 @@ int jumpshot_transport(struct scsi_cmnd * srb, struct us_data *us) if (!us->extra) { us->extra = kzalloc(sizeof(struct jumpshot_info), GFP_NOIO); - if (!us->extra) { - US_DEBUGP("jumpshot_transport: Gah! Can't allocate storage for jumpshot info struct!\n"); + if (!us->extra) return USB_STOR_TRANSPORT_ERROR; - } + us->extra_destructor = jumpshot_info_destructor; } info = (struct jumpshot_info *) (us->extra); if (srb->cmnd[0] == INQUIRY) { - US_DEBUGP("jumpshot_transport: INQUIRY. Returning bogus response.\n"); + usb_stor_dbg(us, "INQUIRY - Returning bogus response\n"); memcpy(ptr, inquiry_response, sizeof(inquiry_response)); fill_inquiry_response(us, ptr, 36); return USB_STOR_TRANSPORT_GOOD; @@ -470,8 +518,8 @@ int jumpshot_transport(struct scsi_cmnd * srb, struct us_data *us) if (rc != USB_STOR_TRANSPORT_GOOD) return rc; - US_DEBUGP("jumpshot_transport: READ_CAPACITY: %ld sectors, %ld bytes per sector\n", - info->sectors, info->ssize); + usb_stor_dbg(us, "READ_CAPACITY: %ld sectors, %ld bytes per sector\n", + info->sectors, info->ssize); // build the reply // @@ -483,7 +531,7 @@ int jumpshot_transport(struct scsi_cmnd * srb, struct us_data *us) } if (srb->cmnd[0] == MODE_SELECT_10) { - US_DEBUGP("jumpshot_transport: Gah! MODE_SELECT_10.\n"); + usb_stor_dbg(us, "Gah! MODE_SELECT_10\n"); return USB_STOR_TRANSPORT_ERROR; } @@ -493,7 +541,8 @@ int jumpshot_transport(struct scsi_cmnd * srb, struct us_data *us) blocks = ((u32)(srb->cmnd[7]) << 8) | ((u32)(srb->cmnd[8])); - US_DEBUGP("jumpshot_transport: READ_10: read block 0x%04lx count %ld\n", block, blocks); + usb_stor_dbg(us, "READ_10: read block 0x%04lx count %ld\n", + block, blocks); return jumpshot_read_data(us, info, block, blocks); } @@ -506,7 +555,8 @@ int jumpshot_transport(struct scsi_cmnd * srb, struct us_data *us) blocks = ((u32)(srb->cmnd[6]) << 24) | ((u32)(srb->cmnd[7]) << 16) | ((u32)(srb->cmnd[8]) << 8) | ((u32)(srb->cmnd[9])); - US_DEBUGP("jumpshot_transport: READ_12: read block 0x%04lx count %ld\n", block, blocks); + usb_stor_dbg(us, "READ_12: read block 0x%04lx count %ld\n", + block, blocks); return jumpshot_read_data(us, info, block, blocks); } @@ -516,7 +566,8 @@ int jumpshot_transport(struct scsi_cmnd * srb, struct us_data *us) blocks = ((u32)(srb->cmnd[7]) << 8) | ((u32)(srb->cmnd[8])); - US_DEBUGP("jumpshot_transport: WRITE_10: write block 0x%04lx count %ld\n", block, blocks); + usb_stor_dbg(us, "WRITE_10: write block 0x%04lx count %ld\n", + block, blocks); return jumpshot_write_data(us, info, block, blocks); } @@ -529,18 +580,19 @@ int jumpshot_transport(struct scsi_cmnd * srb, struct us_data *us) blocks = ((u32)(srb->cmnd[6]) << 24) | ((u32)(srb->cmnd[7]) << 16) | ((u32)(srb->cmnd[8]) << 8) | ((u32)(srb->cmnd[9])); - US_DEBUGP("jumpshot_transport: WRITE_12: write block 0x%04lx count %ld\n", block, blocks); + usb_stor_dbg(us, "WRITE_12: write block 0x%04lx count %ld\n", + block, blocks); return jumpshot_write_data(us, info, block, blocks); } if (srb->cmnd[0] == TEST_UNIT_READY) { - US_DEBUGP("jumpshot_transport: TEST_UNIT_READY.\n"); + usb_stor_dbg(us, "TEST_UNIT_READY\n"); return jumpshot_get_status(us); } if (srb->cmnd[0] == REQUEST_SENSE) { - US_DEBUGP("jumpshot_transport: REQUEST_SENSE.\n"); + usb_stor_dbg(us, "REQUEST_SENSE\n"); memset(ptr, 0, 18); ptr[0] = 0xF0; @@ -554,12 +606,12 @@ int jumpshot_transport(struct scsi_cmnd * srb, struct us_data *us) } if (srb->cmnd[0] == MODE_SENSE) { - US_DEBUGP("jumpshot_transport: MODE_SENSE_6 detected\n"); + usb_stor_dbg(us, "MODE_SENSE_6 detected\n"); return jumpshot_handle_mode_sense(us, srb, 1); } if (srb->cmnd[0] == MODE_SENSE_10) { - US_DEBUGP("jumpshot_transport: MODE_SENSE_10 detected\n"); + usb_stor_dbg(us, "MODE_SENSE_10 detected\n"); return jumpshot_handle_mode_sense(us, srb, 0); } @@ -573,7 +625,7 @@ int jumpshot_transport(struct scsi_cmnd * srb, struct us_data *us) if (srb->cmnd[0] == START_STOP) { /* this is used by sd.c'check_scsidisk_media_change to detect media change */ - US_DEBUGP("jumpshot_transport: START_STOP.\n"); + usb_stor_dbg(us, "START_STOP\n"); /* the first jumpshot_id_device after a media change returns an error (determined experimentally) */ rc = jumpshot_id_device(us, info); @@ -587,10 +639,46 @@ int jumpshot_transport(struct scsi_cmnd * srb, struct us_data *us) return rc; } - US_DEBUGP("jumpshot_transport: Gah! Unknown command: %d (0x%x)\n", - srb->cmnd[0], srb->cmnd[0]); + usb_stor_dbg(us, "Gah! Unknown command: %d (0x%x)\n", + srb->cmnd[0], srb->cmnd[0]); info->sense_key = 0x05; info->sense_asc = 0x20; info->sense_ascq = 0x00; return USB_STOR_TRANSPORT_FAILED; } + +static int jumpshot_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct us_data *us; + int result; + + result = usb_stor_probe1(&us, intf, id, + (id - jumpshot_usb_ids) + jumpshot_unusual_dev_list); + if (result) + return result; + + us->transport_name = "Lexar Jumpshot Control/Bulk"; + us->transport = jumpshot_transport; + us->transport_reset = usb_stor_Bulk_reset; + us->max_lun = 1; + + result = usb_stor_probe2(us); + return result; +} + +static struct usb_driver jumpshot_driver = { + .name = "ums-jumpshot", + .probe = jumpshot_probe, + .disconnect = usb_stor_disconnect, + .suspend = usb_stor_suspend, + .resume = usb_stor_resume, + .reset_resume = usb_stor_reset_resume, + .pre_reset = usb_stor_pre_reset, + .post_reset = usb_stor_post_reset, + .id_table = jumpshot_usb_ids, + .soft_unbind = 1, + .no_dynamic_id = 1, +}; + +module_usb_driver(jumpshot_driver); |
