diff options
Diffstat (limited to 'drivers/usb/storage/shuttle_usbat.c')
| -rw-r--r-- | drivers/usb/storage/shuttle_usbat.c | 491 |
1 files changed, 324 insertions, 167 deletions
diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c index 33c55a6261b..008d805c3d2 100644 --- a/drivers/usb/storage/shuttle_usbat.c +++ b/drivers/usb/storage/shuttle_usbat.c @@ -1,7 +1,5 @@ /* Driver for SCM Microsystems (a.k.a. Shuttle) USB-ATAPI cable * - * $Id: shuttle_usbat.c,v 1.17 2002/04/22 03:39:43 mdharm Exp $ - * * Current development and maintenance by: * (c) 2000, 2001 Robert Baruch (autophile@starband.net) * (c) 2004, 2005 Daniel Drake <dsd@gentoo.org> @@ -43,8 +41,8 @@ * 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <linux/sched.h> #include <linux/errno.h> +#include <linux/module.h> #include <linux/slab.h> #include <linux/cdrom.h> @@ -55,7 +53,100 @@ #include "transport.h" #include "protocol.h" #include "debug.h" -#include "shuttle_usbat.h" + +MODULE_DESCRIPTION("Driver for SCM Microsystems (a.k.a. Shuttle) USB-ATAPI cable"); +MODULE_AUTHOR("Daniel Drake <dsd@gentoo.org>, Robert Baruch <autophile@starband.net>"); +MODULE_LICENSE("GPL"); + +/* Supported device types */ +#define USBAT_DEV_HP8200 0x01 +#define USBAT_DEV_FLASH 0x02 + +#define USBAT_EPP_PORT 0x10 +#define USBAT_EPP_REGISTER 0x30 +#define USBAT_ATA 0x40 +#define USBAT_ISA 0x50 + +/* Commands (need to be logically OR'd with an access type */ +#define USBAT_CMD_READ_REG 0x00 +#define USBAT_CMD_WRITE_REG 0x01 +#define USBAT_CMD_READ_BLOCK 0x02 +#define USBAT_CMD_WRITE_BLOCK 0x03 +#define USBAT_CMD_COND_READ_BLOCK 0x04 +#define USBAT_CMD_COND_WRITE_BLOCK 0x05 +#define USBAT_CMD_WRITE_REGS 0x07 + +/* Commands (these don't need an access type) */ +#define USBAT_CMD_EXEC_CMD 0x80 +#define USBAT_CMD_SET_FEAT 0x81 +#define USBAT_CMD_UIO 0x82 + +/* Methods of accessing UIO register */ +#define USBAT_UIO_READ 1 +#define USBAT_UIO_WRITE 0 + +/* Qualifier bits */ +#define USBAT_QUAL_FCQ 0x20 /* full compare */ +#define USBAT_QUAL_ALQ 0x10 /* auto load subcount */ + +/* USBAT Flash Media status types */ +#define USBAT_FLASH_MEDIA_NONE 0 +#define USBAT_FLASH_MEDIA_CF 1 + +/* USBAT Flash Media change types */ +#define USBAT_FLASH_MEDIA_SAME 0 +#define USBAT_FLASH_MEDIA_CHANGED 1 + +/* USBAT ATA registers */ +#define USBAT_ATA_DATA 0x10 /* read/write data (R/W) */ +#define USBAT_ATA_FEATURES 0x11 /* set features (W) */ +#define USBAT_ATA_ERROR 0x11 /* error (R) */ +#define USBAT_ATA_SECCNT 0x12 /* sector count (R/W) */ +#define USBAT_ATA_SECNUM 0x13 /* sector number (R/W) */ +#define USBAT_ATA_LBA_ME 0x14 /* cylinder low (R/W) */ +#define USBAT_ATA_LBA_HI 0x15 /* cylinder high (R/W) */ +#define USBAT_ATA_DEVICE 0x16 /* head/device selection (R/W) */ +#define USBAT_ATA_STATUS 0x17 /* device status (R) */ +#define USBAT_ATA_CMD 0x17 /* device command (W) */ +#define USBAT_ATA_ALTSTATUS 0x0E /* status (no clear IRQ) (R) */ + +/* USBAT User I/O Data registers */ +#define USBAT_UIO_EPAD 0x80 /* Enable Peripheral Control Signals */ +#define USBAT_UIO_CDT 0x40 /* Card Detect (Read Only) */ + /* CDT = ACKD & !UI1 & !UI0 */ +#define USBAT_UIO_1 0x20 /* I/O 1 */ +#define USBAT_UIO_0 0x10 /* I/O 0 */ +#define USBAT_UIO_EPP_ATA 0x08 /* 1=EPP mode, 0=ATA mode */ +#define USBAT_UIO_UI1 0x04 /* Input 1 */ +#define USBAT_UIO_UI0 0x02 /* Input 0 */ +#define USBAT_UIO_INTR_ACK 0x01 /* Interrupt (ATA/ISA)/Acknowledge (EPP) */ + +/* USBAT User I/O Enable registers */ +#define USBAT_UIO_DRVRST 0x80 /* Reset Peripheral */ +#define USBAT_UIO_ACKD 0x40 /* Enable Card Detect */ +#define USBAT_UIO_OE1 0x20 /* I/O 1 set=output/clr=input */ + /* If ACKD=1, set OE1 to 1 also. */ +#define USBAT_UIO_OE0 0x10 /* I/O 0 set=output/clr=input */ +#define USBAT_UIO_ADPRST 0x01 /* Reset SCM chip */ + +/* USBAT Features */ +#define USBAT_FEAT_ETEN 0x80 /* External trigger enable */ +#define USBAT_FEAT_U1 0x08 +#define USBAT_FEAT_U0 0x04 +#define USBAT_FEAT_ET1 0x02 +#define USBAT_FEAT_ET2 0x01 + +struct usbat_info { + int devicetype; + + /* Used for Flash readers only */ + unsigned long sectors; /* total sector count */ + unsigned long ssize; /* sector size in bytes */ + + unsigned char sense_key; + unsigned long sense_asc; /* additional sense code */ + unsigned long sense_ascq; /* additional sense code qualifier */ +}; #define short_pack(LSB,MSB) ( ((u16)(LSB)) | ( ((u16)(MSB))<<8 ) ) #define LSB_of(s) ((s)&0xFF) @@ -66,6 +157,48 @@ static int transferred = 0; static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us); static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us); +static int init_usbat_cd(struct us_data *us); +static int init_usbat_flash(struct us_data *us); + + +/* + * 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 usbat_usb_ids[] = { +# include "unusual_usbat.h" + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(usb, usbat_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 usbat_unusual_dev_list[] = { +# include "unusual_usbat.h" + { } /* Terminating entry */ +}; + +#undef UNUSUAL_DEV + /* * Convenience function to produce an ATA read/write sectors command * Use cmd=0x20 for read, cmd=0x30 for write @@ -131,28 +264,30 @@ static int usbat_write(struct us_data *us, * Convenience function to perform a bulk read */ static int usbat_bulk_read(struct us_data *us, - unsigned char *data, - unsigned int len) + void* buf, + unsigned int len, + int use_sg) { if (len == 0) return USB_STOR_XFER_GOOD; - US_DEBUGP("usbat_bulk_read: len = %d\n", len); - return usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, data, len, NULL); + usb_stor_dbg(us, "len = %d\n", len); + return usb_stor_bulk_transfer_sg(us, us->recv_bulk_pipe, buf, len, use_sg, NULL); } /* * Convenience function to perform a bulk write */ static int usbat_bulk_write(struct us_data *us, - unsigned char *data, - unsigned int len) + void* buf, + unsigned int len, + int use_sg) { if (len == 0) return USB_STOR_XFER_GOOD; - US_DEBUGP("usbat_bulk_write: len = %d\n", len); - return usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, data, len, NULL); + usb_stor_dbg(us, "len = %d\n", len); + return usb_stor_bulk_transfer_sg(us, us->send_bulk_pipe, buf, len, use_sg, NULL); } /* @@ -177,7 +312,7 @@ static int usbat_get_status(struct us_data *us, unsigned char *status) int rc; rc = usbat_read(us, USBAT_ATA, USBAT_ATA_STATUS, status); - US_DEBUGP("usbat_get_status: 0x%02X\n", (unsigned short) (*status)); + usb_stor_dbg(us, "0x%02X\n", *status); return rc; } @@ -189,9 +324,6 @@ static int usbat_check_status(struct us_data *us) unsigned char *reply = us->iobuf; int rc; - if (!us) - return USB_STOR_TRANSPORT_ERROR; - rc = usbat_get_status(us, reply); if (rc != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_FAILED; @@ -208,7 +340,7 @@ static int usbat_check_status(struct us_data *us) } /* - * Stores critical information in internal registers in prepartion for the execution + * Stores critical information in internal registers in preparation for the execution * of a conditional usbat_read_blocks or usbat_write_blocks call. */ static int usbat_set_shuttle_features(struct us_data *us, @@ -293,7 +425,7 @@ static int usbat_wait_not_busy(struct us_data *us, int minutes) return USB_STOR_TRANSPORT_FAILED; if ((*status & 0x80)==0x00) { /* not busy */ - US_DEBUGP("Waited not busy for %d steps\n", i); + usb_stor_dbg(us, "Waited not busy for %d steps\n", i); return USB_STOR_TRANSPORT_GOOD; } @@ -307,8 +439,8 @@ static int usbat_wait_not_busy(struct us_data *us, int minutes) msleep(1000); /* X minutes */ } - US_DEBUGP("Waited not busy for %d minutes, timing out.\n", - minutes); + usb_stor_dbg(us, "Waited not busy for %d minutes, timing out\n", + minutes); return USB_STOR_TRANSPORT_FAILED; } @@ -316,8 +448,9 @@ static int usbat_wait_not_busy(struct us_data *us, int minutes) * Read block data from the data register */ static int usbat_read_block(struct us_data *us, - unsigned char *content, - unsigned short len) + void* buf, + unsigned short len, + int use_sg) { int result; unsigned char *command = us->iobuf; @@ -338,7 +471,7 @@ static int usbat_read_block(struct us_data *us, if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - result = usbat_bulk_read(us, content, len); + result = usbat_bulk_read(us, buf, len, use_sg); return (result == USB_STOR_XFER_GOOD ? USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_ERROR); } @@ -348,9 +481,10 @@ static int usbat_read_block(struct us_data *us, */ static int usbat_write_block(struct us_data *us, unsigned char access, - unsigned char *content, + void* buf, unsigned short len, - int minutes) + int minutes, + int use_sg) { int result; unsigned char *command = us->iobuf; @@ -372,7 +506,7 @@ static int usbat_write_block(struct us_data *us, if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - result = usbat_bulk_write(us, content, len); + result = usbat_bulk_write(us, buf, len, use_sg); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; @@ -392,7 +526,7 @@ static int usbat_hp8200e_rw_block_test(struct us_data *us, unsigned char timeout, unsigned char qualifier, int direction, - unsigned char *content, + void *buf, unsigned short len, int use_sg, int minutes) @@ -465,14 +599,14 @@ static int usbat_hp8200e_rw_block_test(struct us_data *us, data[1+(j<<1)] = data_out[j]; } - result = usbat_bulk_write(us, data, num_registers*2); + result = usbat_bulk_write(us, data, num_registers*2, 0); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; } result = usb_stor_bulk_transfer_sg(us, - pipe, content, len, use_sg, NULL); + pipe, buf, len, use_sg, NULL); /* * If we get a stall on the bulk download, we'll retry @@ -523,8 +657,9 @@ static int usbat_hp8200e_rw_block_test(struct us_data *us, if (*status & 0x20) /* device fault */ return USB_STOR_TRANSPORT_FAILED; - US_DEBUGP("Redoing %s\n", - direction==DMA_TO_DEVICE ? "write" : "read"); + usb_stor_dbg(us, "Redoing %s\n", + direction == DMA_TO_DEVICE + ? "write" : "read"); } else if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; @@ -533,8 +668,8 @@ static int usbat_hp8200e_rw_block_test(struct us_data *us, } - US_DEBUGP("Bummer! %s bulk data 20 times failed.\n", - direction==DMA_TO_DEVICE ? "Writing" : "Reading"); + usb_stor_dbg(us, "Bummer! %s bulk data 20 times failed\n", + direction == DMA_TO_DEVICE ? "Writing" : "Reading"); return USB_STOR_TRANSPORT_FAILED; } @@ -583,7 +718,7 @@ static int usbat_multiple_write(struct us_data *us, } /* Send the data */ - result = usbat_bulk_write(us, data, num_registers*2); + result = usbat_bulk_write(us, data, num_registers*2, 0); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; @@ -606,8 +741,9 @@ static int usbat_multiple_write(struct us_data *us, * other related details) are defined beforehand with _set_shuttle_features(). */ static int usbat_read_blocks(struct us_data *us, - unsigned char *buffer, - int len) + void* buffer, + int len, + int use_sg) { int result; unsigned char *command = us->iobuf; @@ -627,7 +763,7 @@ static int usbat_read_blocks(struct us_data *us, return USB_STOR_TRANSPORT_FAILED; /* Read the blocks we just asked for */ - result = usbat_bulk_read(us, buffer, len); + result = usbat_bulk_read(us, buffer, len, use_sg); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_FAILED; @@ -647,8 +783,9 @@ static int usbat_read_blocks(struct us_data *us, * other related details) are defined beforehand with _set_shuttle_features(). */ static int usbat_write_blocks(struct us_data *us, - unsigned char *buffer, - int len) + void* buffer, + int len, + int use_sg) { int result; unsigned char *command = us->iobuf; @@ -668,7 +805,7 @@ static int usbat_write_blocks(struct us_data *us, return USB_STOR_TRANSPORT_FAILED; /* Write the data */ - result = usbat_bulk_write(us, buffer, len); + result = usbat_bulk_write(us, buffer, len, use_sg); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_FAILED; @@ -691,7 +828,7 @@ static int usbat_read_user_io(struct us_data *us, unsigned char *data_flags) data_flags, USBAT_UIO_READ); - US_DEBUGP("usbat_read_user_io: UIO register reads %02X\n", (unsigned short) (*data_flags)); + usb_stor_dbg(us, "UIO register reads %02X\n", *data_flags); return result; } @@ -764,10 +901,11 @@ static int usbat_device_enable_cdt(struct us_data *us) /* * Determine if media is present. */ -static int usbat_flash_check_media_present(unsigned char *uio) +static int usbat_flash_check_media_present(struct us_data *us, + unsigned char *uio) { if (*uio & USBAT_UIO_UI0) { - US_DEBUGP("usbat_flash_check_media_present: no media detected\n"); + usb_stor_dbg(us, "no media detected\n"); return USBAT_FLASH_MEDIA_NONE; } @@ -777,10 +915,11 @@ static int usbat_flash_check_media_present(unsigned char *uio) /* * Determine if media has changed since last operation */ -static int usbat_flash_check_media_changed(unsigned char *uio) +static int usbat_flash_check_media_changed(struct us_data *us, + unsigned char *uio) { if (*uio & USBAT_UIO_0) { - US_DEBUGP("usbat_flash_check_media_changed: media change detected\n"); + usb_stor_dbg(us, "media change detected\n"); return USBAT_FLASH_MEDIA_CHANGED; } @@ -801,7 +940,7 @@ static int usbat_flash_check_media(struct us_data *us, return USB_STOR_TRANSPORT_ERROR; /* Check for media existence */ - rc = usbat_flash_check_media_present(uio); + rc = usbat_flash_check_media_present(us, uio); if (rc == USBAT_FLASH_MEDIA_NONE) { info->sense_key = 0x02; info->sense_asc = 0x3A; @@ -810,7 +949,7 @@ static int usbat_flash_check_media(struct us_data *us, } /* Check for media change */ - rc = usbat_flash_check_media_changed(uio); + rc = usbat_flash_check_media_changed(us, uio); if (rc == USBAT_FLASH_MEDIA_CHANGED) { /* Reset and re-enable card detect */ @@ -853,7 +992,7 @@ static int usbat_identify_device(struct us_data *us, rc = usbat_device_reset(us); if (rc != USB_STOR_TRANSPORT_GOOD) return rc; - msleep(25); + msleep(500); /* * In attempt to distinguish between HP CDRW's and Flash readers, we now @@ -872,11 +1011,11 @@ static int usbat_identify_device(struct us_data *us, /* Check for error bit, or if the command 'fell through' */ if (status == 0xA1 || !(status & 0x01)) { /* Device is HP 8200 */ - US_DEBUGP("usbat_identify_device: Detected HP8200 CDRW\n"); + usb_stor_dbg(us, "Detected HP8200 CDRW\n"); info->devicetype = USBAT_DEV_HP8200; } else { /* Device is a CompactFlash reader/writer */ - US_DEBUGP("usbat_identify_device: Detected Flash reader/writer\n"); + usb_stor_dbg(us, "Detected Flash reader/writer\n"); info->devicetype = USBAT_DEV_FLASH; } @@ -887,22 +1026,28 @@ static int usbat_identify_device(struct us_data *us, * Set the transport function based on the device type */ static int usbat_set_transport(struct us_data *us, - struct usbat_info *info) + struct usbat_info *info, + int devicetype) { - int rc; - if (!info->devicetype) { - rc = usbat_identify_device(us, info); - if (rc != USB_STOR_TRANSPORT_GOOD) { - US_DEBUGP("usbat_set_transport: Could not identify device\n"); - return 1; - } - } + if (!info->devicetype) + info->devicetype = devicetype; - if (usbat_get_device_type(us) == USBAT_DEV_HP8200) + if (!info->devicetype) + usbat_identify_device(us, info); + + switch (info->devicetype) { + default: + return USB_STOR_TRANSPORT_ERROR; + + case USBAT_DEV_HP8200: us->transport = usbat_hp8200e_transport; - else if (usbat_get_device_type(us) == USBAT_DEV_FLASH) + break; + + case USBAT_DEV_FLASH: us->transport = usbat_flash_transport; + break; + } return 0; } @@ -933,7 +1078,7 @@ static int usbat_flash_get_sector_count(struct us_data *us, /* ATA command : IDENTIFY DEVICE */ rc = usbat_multiple_write(us, registers, command, 3); if (rc != USB_STOR_XFER_GOOD) { - US_DEBUGP("usbat_flash_get_sector_count: Gah! identify_device failed\n"); + usb_stor_dbg(us, "Gah! identify_device failed\n"); rc = USB_STOR_TRANSPORT_ERROR; goto leave; } @@ -947,7 +1092,7 @@ static int usbat_flash_get_sector_count(struct us_data *us, msleep(100); /* Read the device identification data */ - rc = usbat_read_block(us, reply, 512); + rc = usbat_read_block(us, reply, 512, 0); if (rc != USB_STOR_TRANSPORT_GOOD) goto leave; @@ -985,7 +1130,8 @@ static int usbat_flash_read_data(struct us_data *us, unsigned char thistime; unsigned int totallen, alloclen; int len, result; - unsigned int sg_idx = 0, sg_offset = 0; + unsigned int sg_offset = 0; + struct scatterlist *sg = NULL; result = usbat_flash_check_media(us, info); if (result != USB_STOR_TRANSPORT_GOOD) @@ -1031,15 +1177,15 @@ static int usbat_flash_read_data(struct us_data *us, goto leave; /* Read the data we just requested */ - result = usbat_read_blocks(us, buffer, len); + result = usbat_read_blocks(us, buffer, len, 0); if (result != USB_STOR_TRANSPORT_GOOD) goto leave; - US_DEBUGP("usbat_flash_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, - &sg_idx, &sg_offset, TO_XFER_BUF); + &sg, &sg_offset, TO_XFER_BUF); sector += thistime; totallen -= len; @@ -1075,7 +1221,8 @@ static int usbat_flash_write_data(struct us_data *us, unsigned char thistime; unsigned int totallen, alloclen; int len, result; - unsigned int sg_idx = 0, sg_offset = 0; + unsigned int sg_offset = 0; + struct scatterlist *sg = NULL; result = usbat_flash_check_media(us, info); if (result != USB_STOR_TRANSPORT_GOOD) @@ -1114,7 +1261,7 @@ static int usbat_flash_write_data(struct us_data *us, /* Get the data from the transfer buffer */ usb_stor_access_xfer_buf(buffer, len, us->srb, - &sg_idx, &sg_offset, FROM_XFER_BUF); + &sg, &sg_offset, FROM_XFER_BUF); /* ATA command 0x30 (WRITE SECTORS) */ usbat_pack_ata_sector_cmd(command, thistime, sector, 0x30); @@ -1125,7 +1272,7 @@ static int usbat_flash_write_data(struct us_data *us, goto leave; /* Write the data */ - result = usbat_write_blocks(us, buffer, len); + result = usbat_write_blocks(us, buffer, len, 0); if (result != USB_STOR_TRANSPORT_GOOD) goto leave; @@ -1154,21 +1301,20 @@ static int usbat_hp8200e_handle_read10(struct us_data *us, unsigned char *buffer; unsigned int len; unsigned int sector; - unsigned int sg_segment = 0; unsigned int sg_offset = 0; + struct scatterlist *sg = NULL; - US_DEBUGP("handle_read10: transfersize %d\n", - srb->transfersize); + usb_stor_dbg(us, "transfersize %d\n", srb->transfersize); - if (srb->request_bufflen < 0x10000) { + if (scsi_bufflen(srb) < 0x10000) { result = usbat_hp8200e_rw_block_test(us, USBAT_ATA, registers, data, 19, USBAT_ATA_DATA, USBAT_ATA_STATUS, 0xFD, (USBAT_QUAL_FCQ | USBAT_QUAL_ALQ), DMA_FROM_DEVICE, - srb->request_buffer, - srb->request_bufflen, srb->use_sg, 1); + scsi_sglist(srb), + scsi_bufflen(srb), scsi_sg_count(srb), 1); return result; } @@ -1185,14 +1331,14 @@ static int usbat_hp8200e_handle_read10(struct us_data *us, len = short_pack(data[7+9], data[7+8]); len <<= 16; len |= data[7+7]; - US_DEBUGP("handle_read10: GPCMD_READ_CD: len %d\n", len); - srb->transfersize = srb->request_bufflen/len; + usb_stor_dbg(us, "GPCMD_READ_CD: len %d\n", len); + srb->transfersize = scsi_bufflen(srb)/len; } if (!srb->transfersize) { srb->transfersize = 2048; /* A guess */ - US_DEBUGP("handle_read10: transfersize 0, forcing %d\n", - srb->transfersize); + usb_stor_dbg(us, "transfersize 0, forcing %d\n", + srb->transfersize); } /* @@ -1202,8 +1348,8 @@ static int usbat_hp8200e_handle_read10(struct us_data *us, */ len = (65535/srb->transfersize) * srb->transfersize; - US_DEBUGP("Max read is %d bytes\n", len); - len = min(len, srb->request_bufflen); + usb_stor_dbg(us, "Max read is %d bytes\n", len); + len = min(len, scsi_bufflen(srb)); buffer = kmalloc(len, GFP_NOIO); if (buffer == NULL) /* bloody hell! */ return USB_STOR_TRANSPORT_FAILED; @@ -1212,13 +1358,10 @@ static int usbat_hp8200e_handle_read10(struct us_data *us, sector |= short_pack(data[7+5], data[7+4]); transferred = 0; - sg_segment = 0; /* for keeping track of where we are in */ - sg_offset = 0; /* the scatter/gather list */ + while (transferred != scsi_bufflen(srb)) { - while (transferred != srb->request_bufflen) { - - if (len > srb->request_bufflen - transferred) - len = srb->request_bufflen - transferred; + if (len > scsi_bufflen(srb) - transferred) + len = scsi_bufflen(srb) - transferred; data[3] = len&0xFF; /* (cylL) = expected length (L) */ data[4] = (len>>8)&0xFF; /* (cylH) = expected length (H) */ @@ -1247,14 +1390,14 @@ static int usbat_hp8200e_handle_read10(struct us_data *us, /* Store the data in the transfer buffer */ usb_stor_access_xfer_buf(buffer, len, srb, - &sg_segment, &sg_offset, TO_XFER_BUF); + &sg, &sg_offset, TO_XFER_BUF); /* Update the amount transferred and the sector number */ transferred += len; sector += len / srb->transfersize; - } /* while transferred != srb->request_bufflen */ + } /* while transferred != scsi_bufflen(srb) */ kfree(buffer); return result; @@ -1310,7 +1453,7 @@ static int usbat_select_and_test_registers(struct us_data *us) /* * Initialize the USBAT processor and the storage device */ -int init_usbat(struct us_data *us) +static int init_usbat(struct us_data *us, int devicetype) { int rc; struct usbat_info *info; @@ -1318,12 +1461,10 @@ int init_usbat(struct us_data *us) unsigned char subcountL = USBAT_ATA_LBA_ME; unsigned char *status = us->iobuf; - us->extra = kmalloc(sizeof(struct usbat_info), GFP_NOIO); - if (!us->extra) { - US_DEBUGP("init_usbat: Gah! Can't allocate storage for usbat info struct!\n"); + us->extra = kzalloc(sizeof(struct usbat_info), GFP_NOIO); + if (!us->extra) return 1; - } - memset(us->extra, 0, sizeof(struct usbat_info)); + info = (struct usbat_info *) (us->extra); /* Enable peripheral control signals */ @@ -1333,7 +1474,7 @@ int init_usbat(struct us_data *us) if (rc != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - US_DEBUGP("INIT 1\n"); + usb_stor_dbg(us, "INIT 1\n"); msleep(2000); @@ -1341,7 +1482,7 @@ int init_usbat(struct us_data *us) if (rc != USB_STOR_TRANSPORT_GOOD) return rc; - US_DEBUGP("INIT 2\n"); + usb_stor_dbg(us, "INIT 2\n"); rc = usbat_read_user_io(us, status); if (rc != USB_STOR_XFER_GOOD) @@ -1351,32 +1492,32 @@ int init_usbat(struct us_data *us) if (rc != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - US_DEBUGP("INIT 3\n"); + usb_stor_dbg(us, "INIT 3\n"); rc = usbat_select_and_test_registers(us); if (rc != USB_STOR_TRANSPORT_GOOD) return rc; - US_DEBUGP("INIT 4\n"); + usb_stor_dbg(us, "INIT 4\n"); rc = usbat_read_user_io(us, status); if (rc != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - US_DEBUGP("INIT 5\n"); + usb_stor_dbg(us, "INIT 5\n"); /* Enable peripheral control signals and card detect */ rc = usbat_device_enable_cdt(us); if (rc != USB_STOR_TRANSPORT_GOOD) return rc; - US_DEBUGP("INIT 6\n"); + usb_stor_dbg(us, "INIT 6\n"); rc = usbat_read_user_io(us, status); if (rc != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - US_DEBUGP("INIT 7\n"); + usb_stor_dbg(us, "INIT 7\n"); msleep(1400); @@ -1384,19 +1525,19 @@ int init_usbat(struct us_data *us) if (rc != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - US_DEBUGP("INIT 8\n"); + usb_stor_dbg(us, "INIT 8\n"); rc = usbat_select_and_test_registers(us); if (rc != USB_STOR_TRANSPORT_GOOD) return rc; - US_DEBUGP("INIT 9\n"); + usb_stor_dbg(us, "INIT 9\n"); /* At this point, we need to detect which device we are using */ - if (usbat_set_transport(us, info)) + if (usbat_set_transport(us, info, devicetype)) return USB_STOR_TRANSPORT_ERROR; - US_DEBUGP("INIT 10\n"); + usb_stor_dbg(us, "INIT 10\n"); if (usbat_get_device_type(us) == USBAT_DEV_FLASH) { subcountH = 0x02; @@ -1407,7 +1548,7 @@ int init_usbat(struct us_data *us) if (rc != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - US_DEBUGP("INIT 11\n"); + usb_stor_dbg(us, "INIT 11\n"); return USB_STOR_TRANSPORT_GOOD; } @@ -1423,9 +1564,8 @@ static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us) unsigned char data[32]; unsigned int len; int i; - char string[64]; - len = srb->request_bufflen; + len = scsi_bufflen(srb); /* Send A0 (ATA PACKET COMMAND). Note: I guess we're never going to get any of the ATA @@ -1453,7 +1593,7 @@ static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us) } result = usbat_get_status(us, status); - US_DEBUGP("Status = %02X\n", *status); + usb_stor_dbg(us, "Status = %02X\n", *status); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; if (srb->cmnd[0] == TEST_UNIT_READY) @@ -1466,12 +1606,12 @@ static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us) USBAT_ATA_DATA, USBAT_ATA_STATUS, 0xFD, (USBAT_QUAL_FCQ | USBAT_QUAL_ALQ), DMA_TO_DEVICE, - srb->request_buffer, - len, srb->use_sg, 10); + scsi_sglist(srb), + len, scsi_sg_count(srb), 10); if (result == USB_STOR_TRANSPORT_GOOD) { transferred += len; - US_DEBUGP("Wrote %08X bytes\n", transferred); + usb_stor_dbg(us, "Wrote %08X bytes\n", transferred); } return result; @@ -1484,15 +1624,15 @@ static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us) } if (len > 0xFFFF) { - US_DEBUGP("Error: len = %08X... what do I do now?\n", - len); + usb_stor_dbg(us, "Error: len = %08X... what do I do now?\n", + len); return USB_STOR_TRANSPORT_ERROR; } - if ( (result = usbat_multiple_write(us, - registers, data, 7)) != USB_STOR_TRANSPORT_GOOD) { + result = usbat_multiple_write(us, registers, data, 7); + + if (result != USB_STOR_TRANSPORT_GOOD) return result; - } /* * Write the 12-byte command header. @@ -1504,12 +1644,11 @@ static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us) * AT SPEED 4 IS UNRELIABLE!!! */ - if ( (result = usbat_write_block(us, - USBAT_ATA, srb->cmnd, 12, - srb->cmnd[0]==GPCMD_BLANK ? 75 : 10)) != - USB_STOR_TRANSPORT_GOOD) { + result = usbat_write_block(us, USBAT_ATA, srb->cmnd, 12, + srb->cmnd[0] == GPCMD_BLANK ? 75 : 10, 0); + + if (result != USB_STOR_TRANSPORT_GOOD) return result; - } /* If there is response data to be read in then do it here. */ @@ -1534,23 +1673,8 @@ static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us) len = *status; - result = usbat_read_block(us, srb->request_buffer, len); - - /* Debug-print the first 32 bytes of the transfer */ - - if (!srb->use_sg) { - string[0] = 0; - for (i=0; i<len && i<32; i++) { - sprintf(string+strlen(string), "%02X ", - ((unsigned char *)srb->request_buffer)[i]); - if ((i%16)==15) { - US_DEBUGP("%s\n", string); - string[0] = 0; - } - } - if (string[0]!=0) - US_DEBUGP("%s\n", string); - } + result = usbat_read_block(us, scsi_sglist(srb), len, + scsi_sg_count(srb)); } return result; @@ -1570,7 +1694,7 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us) }; if (srb->cmnd[0] == INQUIRY) { - US_DEBUGP("usbat_flash_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; @@ -1587,8 +1711,8 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us) /* hard coded 512 byte sectors as per ATA spec */ info->ssize = 0x200; - US_DEBUGP("usbat_flash_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 @@ -1603,7 +1727,7 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us) } if (srb->cmnd[0] == MODE_SELECT_10) { - US_DEBUGP("usbat_flash_transport: Gah! MODE_SELECT_10.\n"); + usb_stor_dbg(us, "Gah! MODE_SELECT_10\n"); return USB_STOR_TRANSPORT_ERROR; } @@ -1613,7 +1737,8 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us) blocks = ((u32)(srb->cmnd[7]) << 8) | ((u32)(srb->cmnd[8])); - US_DEBUGP("usbat_flash_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 usbat_flash_read_data(us, info, block, blocks); } @@ -1627,7 +1752,8 @@ static int usbat_flash_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("usbat_flash_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 usbat_flash_read_data(us, info, block, blocks); } @@ -1637,7 +1763,8 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us) blocks = ((u32)(srb->cmnd[7]) << 8) | ((u32)(srb->cmnd[8])); - US_DEBUGP("usbat_flash_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 usbat_flash_write_data(us, info, block, blocks); } @@ -1651,13 +1778,14 @@ static int usbat_flash_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("usbat_flash_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 usbat_flash_write_data(us, info, block, blocks); } if (srb->cmnd[0] == TEST_UNIT_READY) { - US_DEBUGP("usbat_flash_transport: TEST_UNIT_READY.\n"); + usb_stor_dbg(us, "TEST_UNIT_READY\n"); rc = usbat_flash_check_media(us, info); if (rc != USB_STOR_TRANSPORT_GOOD) @@ -1667,7 +1795,7 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us) } if (srb->cmnd[0] == REQUEST_SENSE) { - US_DEBUGP("usbat_flash_transport: REQUEST_SENSE.\n"); + usb_stor_dbg(us, "REQUEST_SENSE\n"); memset(ptr, 0, 18); ptr[0] = 0xF0; @@ -1688,30 +1816,59 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us) return USB_STOR_TRANSPORT_GOOD; } - US_DEBUGP("usbat_flash_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; } -/* - * Default transport function. Attempts to detect which transport function - * should be called, makes it the new default, and calls it. - * - * This function should never be called. Our usbat_init() function detects the - * device type and changes the us->transport ptr to the transport function - * relevant to the device. - * However, we'll support this impossible(?) case anyway. - */ -int usbat_transport(struct scsi_cmnd *srb, struct us_data *us) +static int init_usbat_cd(struct us_data *us) { - struct usbat_info *info = (struct usbat_info*) (us->extra); + return init_usbat(us, USBAT_DEV_HP8200); +} - if (usbat_set_transport(us, info)) - return USB_STOR_TRANSPORT_ERROR; +static int init_usbat_flash(struct us_data *us) +{ + return init_usbat(us, USBAT_DEV_FLASH); +} + +static int usbat_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 - usbat_usb_ids) + usbat_unusual_dev_list); + if (result) + return result; - return us->transport(srb, us); + /* The actual transport will be determined later by the + * initialization routine; this is just a placeholder. + */ + us->transport_name = "Shuttle USBAT"; + us->transport = usbat_flash_transport; + us->transport_reset = usb_stor_CB_reset; + us->max_lun = 0; + + result = usb_stor_probe2(us); + return result; } +static struct usb_driver usbat_driver = { + .name = "ums-usbat", + .probe = usbat_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 = usbat_usb_ids, + .soft_unbind = 1, + .no_dynamic_id = 1, +}; + +module_usb_driver(usbat_driver); |
