|  | /* Driver for SCM Microsystems (a.k.a. Shuttle) USB-ATAPI cable | 
|  | * | 
|  | * Current development and maintenance by: | 
|  | *   (c) 2000, 2001 Robert Baruch (autophile@starband.net) | 
|  | *   (c) 2004, 2005 Daniel Drake <dsd@gentoo.org> | 
|  | * | 
|  | * Developed with the assistance of: | 
|  | *   (c) 2002 Alan Stern <stern@rowland.org> | 
|  | * | 
|  | * Flash support based on earlier work by: | 
|  | *   (c) 2002 Thomas Kreiling <usbdev@sm04.de> | 
|  | * | 
|  | * Many originally ATAPI devices were slightly modified to meet the USB | 
|  | * market by using some kind of translation from ATAPI to USB on the host, | 
|  | * and the peripheral would translate from USB back to ATAPI. | 
|  | * | 
|  | * SCM Microsystems (www.scmmicro.com) makes a device, sold to OEM's only, | 
|  | * which does the USB-to-ATAPI conversion.  By obtaining the data sheet on | 
|  | * their device under nondisclosure agreement, I have been able to write | 
|  | * this driver for Linux. | 
|  | * | 
|  | * The chip used in the device can also be used for EPP and ISA translation | 
|  | * as well. This driver is only guaranteed to work with the ATAPI | 
|  | * translation. | 
|  | * | 
|  | * See the Kconfig help text for a list of devices known to be supported by | 
|  | * this driver. | 
|  | * | 
|  | * This program is free software; you can redistribute it and/or modify it | 
|  | * under the terms of the GNU General Public License as published by the | 
|  | * Free Software Foundation; either version 2, or (at your option) any | 
|  | * later version. | 
|  | * | 
|  | * This program is distributed in the hope that it will be useful, but | 
|  | * WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
|  | * General Public License for more details. | 
|  | * | 
|  | * You should have received a copy of the GNU General Public License along | 
|  | * with this program; if not, write to the Free Software Foundation, Inc., | 
|  | * 675 Mass Ave, Cambridge, MA 02139, USA. | 
|  | */ | 
|  |  | 
|  | #include <linux/errno.h> | 
|  | #include <linux/module.h> | 
|  | #include <linux/slab.h> | 
|  | #include <linux/cdrom.h> | 
|  |  | 
|  | #include <scsi/scsi.h> | 
|  | #include <scsi/scsi_cmnd.h> | 
|  |  | 
|  | #include "usb.h" | 
|  | #include "transport.h" | 
|  | #include "protocol.h" | 
|  | #include "debug.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) | 
|  | #define MSB_of(s) ((s)>>8) | 
|  |  | 
|  | 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 | 
|  | */ | 
|  | static void usbat_pack_ata_sector_cmd(unsigned char *buf, | 
|  | unsigned char thistime, | 
|  | u32 sector, unsigned char cmd) | 
|  | { | 
|  | buf[0] = 0; | 
|  | buf[1] = thistime; | 
|  | buf[2] = sector & 0xFF; | 
|  | buf[3] = (sector >>  8) & 0xFF; | 
|  | buf[4] = (sector >> 16) & 0xFF; | 
|  | buf[5] = 0xE0 | ((sector >> 24) & 0x0F); | 
|  | buf[6] = cmd; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Convenience function to get the device type (flash or hp8200) | 
|  | */ | 
|  | static int usbat_get_device_type(struct us_data *us) | 
|  | { | 
|  | return ((struct usbat_info*)us->extra)->devicetype; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Read a register from the device | 
|  | */ | 
|  | static int usbat_read(struct us_data *us, | 
|  | unsigned char access, | 
|  | unsigned char reg, | 
|  | unsigned char *content) | 
|  | { | 
|  | return usb_stor_ctrl_transfer(us, | 
|  | us->recv_ctrl_pipe, | 
|  | access | USBAT_CMD_READ_REG, | 
|  | 0xC0, | 
|  | (u16)reg, | 
|  | 0, | 
|  | content, | 
|  | 1); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Write to a register on the device | 
|  | */ | 
|  | static int usbat_write(struct us_data *us, | 
|  | unsigned char access, | 
|  | unsigned char reg, | 
|  | unsigned char content) | 
|  | { | 
|  | return usb_stor_ctrl_transfer(us, | 
|  | us->send_ctrl_pipe, | 
|  | access | USBAT_CMD_WRITE_REG, | 
|  | 0x40, | 
|  | short_pack(reg, content), | 
|  | 0, | 
|  | NULL, | 
|  | 0); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Convenience function to perform a bulk read | 
|  | */ | 
|  | static int usbat_bulk_read(struct us_data *us, | 
|  | void* buf, | 
|  | unsigned int len, | 
|  | int use_sg) | 
|  | { | 
|  | if (len == 0) | 
|  | return USB_STOR_XFER_GOOD; | 
|  |  | 
|  | 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, | 
|  | void* buf, | 
|  | unsigned int len, | 
|  | int use_sg) | 
|  | { | 
|  | if (len == 0) | 
|  | return USB_STOR_XFER_GOOD; | 
|  |  | 
|  | usb_stor_dbg(us, "len = %d\n", len); | 
|  | return usb_stor_bulk_transfer_sg(us, us->send_bulk_pipe, buf, len, use_sg, NULL); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Some USBAT-specific commands can only be executed over a command transport | 
|  | * This transport allows one (len=8) or two (len=16) vendor-specific commands | 
|  | * to be executed. | 
|  | */ | 
|  | static int usbat_execute_command(struct us_data *us, | 
|  | unsigned char *commands, | 
|  | unsigned int len) | 
|  | { | 
|  | return usb_stor_ctrl_transfer(us, us->send_ctrl_pipe, | 
|  | USBAT_CMD_EXEC_CMD, 0x40, 0, 0, | 
|  | commands, len); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Read the status register | 
|  | */ | 
|  | static int usbat_get_status(struct us_data *us, unsigned char *status) | 
|  | { | 
|  | int rc; | 
|  | rc = usbat_read(us, USBAT_ATA, USBAT_ATA_STATUS, status); | 
|  |  | 
|  | usb_stor_dbg(us, "0x%02X\n", *status); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Check the device status | 
|  | */ | 
|  | static int usbat_check_status(struct us_data *us) | 
|  | { | 
|  | unsigned char *reply = us->iobuf; | 
|  | int rc; | 
|  |  | 
|  | rc = usbat_get_status(us, reply); | 
|  | if (rc != USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_FAILED; | 
|  |  | 
|  | /* error/check condition (0x51 is ok) */ | 
|  | if (*reply & 0x01 && *reply != 0x51) | 
|  | return USB_STOR_TRANSPORT_FAILED; | 
|  |  | 
|  | /* device fault */ | 
|  | if (*reply & 0x20) | 
|  | return USB_STOR_TRANSPORT_FAILED; | 
|  |  | 
|  | return USB_STOR_TRANSPORT_GOOD; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * 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, | 
|  | unsigned char external_trigger, | 
|  | unsigned char epp_control, | 
|  | unsigned char mask_byte, | 
|  | unsigned char test_pattern, | 
|  | unsigned char subcountH, | 
|  | unsigned char subcountL) | 
|  | { | 
|  | unsigned char *command = us->iobuf; | 
|  |  | 
|  | command[0] = 0x40; | 
|  | command[1] = USBAT_CMD_SET_FEAT; | 
|  |  | 
|  | /* | 
|  | * The only bit relevant to ATA access is bit 6 | 
|  | * which defines 8 bit data access (set) or 16 bit (unset) | 
|  | */ | 
|  | command[2] = epp_control; | 
|  |  | 
|  | /* | 
|  | * If FCQ is set in the qualifier (defined in R/W cmd), then bits U0, U1, | 
|  | * ET1 and ET2 define an external event to be checked for on event of a | 
|  | * _read_blocks or _write_blocks operation. The read/write will not take | 
|  | * place unless the defined trigger signal is active. | 
|  | */ | 
|  | command[3] = external_trigger; | 
|  |  | 
|  | /* | 
|  | * The resultant byte of the mask operation (see mask_byte) is compared for | 
|  | * equivalence with this test pattern. If equal, the read/write will take | 
|  | * place. | 
|  | */ | 
|  | command[4] = test_pattern; | 
|  |  | 
|  | /* | 
|  | * This value is logically ANDed with the status register field specified | 
|  | * in the read/write command. | 
|  | */ | 
|  | command[5] = mask_byte; | 
|  |  | 
|  | /* | 
|  | * If ALQ is set in the qualifier, this field contains the address of the | 
|  | * registers where the byte count should be read for transferring the data. | 
|  | * If ALQ is not set, then this field contains the number of bytes to be | 
|  | * transferred. | 
|  | */ | 
|  | command[6] = subcountL; | 
|  | command[7] = subcountH; | 
|  |  | 
|  | return usbat_execute_command(us, command, 8); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Block, waiting for an ATA device to become not busy or to report | 
|  | * an error condition. | 
|  | */ | 
|  | static int usbat_wait_not_busy(struct us_data *us, int minutes) | 
|  | { | 
|  | int i; | 
|  | int result; | 
|  | unsigned char *status = us->iobuf; | 
|  |  | 
|  | /* Synchronizing cache on a CDR could take a heck of a long time, | 
|  | * but probably not more than 10 minutes or so. On the other hand, | 
|  | * doing a full blank on a CDRW at speed 1 will take about 75 | 
|  | * minutes! | 
|  | */ | 
|  |  | 
|  | for (i=0; i<1200+minutes*60; i++) { | 
|  |  | 
|  | result = usbat_get_status(us, status); | 
|  |  | 
|  | if (result!=USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  | if (*status & 0x01) { /* check condition */ | 
|  | result = usbat_read(us, USBAT_ATA, 0x10, status); | 
|  | return USB_STOR_TRANSPORT_FAILED; | 
|  | } | 
|  | if (*status & 0x20) /* device fault */ | 
|  | return USB_STOR_TRANSPORT_FAILED; | 
|  |  | 
|  | if ((*status & 0x80)==0x00) { /* not busy */ | 
|  | usb_stor_dbg(us, "Waited not busy for %d steps\n", i); | 
|  | return USB_STOR_TRANSPORT_GOOD; | 
|  | } | 
|  |  | 
|  | if (i<500) | 
|  | msleep(10); /* 5 seconds */ | 
|  | else if (i<700) | 
|  | msleep(50); /* 10 seconds */ | 
|  | else if (i<1200) | 
|  | msleep(100); /* 50 seconds */ | 
|  | else | 
|  | msleep(1000); /* X minutes */ | 
|  | } | 
|  |  | 
|  | usb_stor_dbg(us, "Waited not busy for %d minutes, timing out\n", | 
|  | minutes); | 
|  | return USB_STOR_TRANSPORT_FAILED; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Read block data from the data register | 
|  | */ | 
|  | static int usbat_read_block(struct us_data *us, | 
|  | void* buf, | 
|  | unsigned short len, | 
|  | int use_sg) | 
|  | { | 
|  | int result; | 
|  | unsigned char *command = us->iobuf; | 
|  |  | 
|  | if (!len) | 
|  | return USB_STOR_TRANSPORT_GOOD; | 
|  |  | 
|  | command[0] = 0xC0; | 
|  | command[1] = USBAT_ATA | USBAT_CMD_READ_BLOCK; | 
|  | command[2] = USBAT_ATA_DATA; | 
|  | command[3] = 0; | 
|  | command[4] = 0; | 
|  | command[5] = 0; | 
|  | command[6] = LSB_of(len); | 
|  | command[7] = MSB_of(len); | 
|  |  | 
|  | result = usbat_execute_command(us, command, 8); | 
|  | if (result != USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | result = usbat_bulk_read(us, buf, len, use_sg); | 
|  | return (result == USB_STOR_XFER_GOOD ? | 
|  | USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_ERROR); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Write block data via the data register | 
|  | */ | 
|  | static int usbat_write_block(struct us_data *us, | 
|  | unsigned char access, | 
|  | void* buf, | 
|  | unsigned short len, | 
|  | int minutes, | 
|  | int use_sg) | 
|  | { | 
|  | int result; | 
|  | unsigned char *command = us->iobuf; | 
|  |  | 
|  | if (!len) | 
|  | return USB_STOR_TRANSPORT_GOOD; | 
|  |  | 
|  | command[0] = 0x40; | 
|  | command[1] = access | USBAT_CMD_WRITE_BLOCK; | 
|  | command[2] = USBAT_ATA_DATA; | 
|  | command[3] = 0; | 
|  | command[4] = 0; | 
|  | command[5] = 0; | 
|  | command[6] = LSB_of(len); | 
|  | command[7] = MSB_of(len); | 
|  |  | 
|  | result = usbat_execute_command(us, command, 8); | 
|  |  | 
|  | if (result != USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | result = usbat_bulk_write(us, buf, len, use_sg); | 
|  | if (result != USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | return usbat_wait_not_busy(us, minutes); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Process read and write requests | 
|  | */ | 
|  | static int usbat_hp8200e_rw_block_test(struct us_data *us, | 
|  | unsigned char access, | 
|  | unsigned char *registers, | 
|  | unsigned char *data_out, | 
|  | unsigned short num_registers, | 
|  | unsigned char data_reg, | 
|  | unsigned char status_reg, | 
|  | unsigned char timeout, | 
|  | unsigned char qualifier, | 
|  | int direction, | 
|  | void *buf, | 
|  | unsigned short len, | 
|  | int use_sg, | 
|  | int minutes) | 
|  | { | 
|  | int result; | 
|  | unsigned int pipe = (direction == DMA_FROM_DEVICE) ? | 
|  | us->recv_bulk_pipe : us->send_bulk_pipe; | 
|  |  | 
|  | unsigned char *command = us->iobuf; | 
|  | int i, j; | 
|  | int cmdlen; | 
|  | unsigned char *data = us->iobuf; | 
|  | unsigned char *status = us->iobuf; | 
|  |  | 
|  | BUG_ON(num_registers > US_IOBUF_SIZE/2); | 
|  |  | 
|  | for (i=0; i<20; i++) { | 
|  |  | 
|  | /* | 
|  | * The first time we send the full command, which consists | 
|  | * of downloading the SCSI command followed by downloading | 
|  | * the data via a write-and-test.  Any other time we only | 
|  | * send the command to download the data -- the SCSI command | 
|  | * is still 'active' in some sense in the device. | 
|  | * | 
|  | * We're only going to try sending the data 10 times. After | 
|  | * that, we just return a failure. | 
|  | */ | 
|  |  | 
|  | if (i==0) { | 
|  | cmdlen = 16; | 
|  | /* | 
|  | * Write to multiple registers | 
|  | * Not really sure the 0x07, 0x17, 0xfc, 0xe7 is | 
|  | * necessary here, but that's what came out of the | 
|  | * trace every single time. | 
|  | */ | 
|  | command[0] = 0x40; | 
|  | command[1] = access | USBAT_CMD_WRITE_REGS; | 
|  | command[2] = 0x07; | 
|  | command[3] = 0x17; | 
|  | command[4] = 0xFC; | 
|  | command[5] = 0xE7; | 
|  | command[6] = LSB_of(num_registers*2); | 
|  | command[7] = MSB_of(num_registers*2); | 
|  | } else | 
|  | cmdlen = 8; | 
|  |  | 
|  | /* Conditionally read or write blocks */ | 
|  | command[cmdlen-8] = (direction==DMA_TO_DEVICE ? 0x40 : 0xC0); | 
|  | command[cmdlen-7] = access | | 
|  | (direction==DMA_TO_DEVICE ? | 
|  | USBAT_CMD_COND_WRITE_BLOCK : USBAT_CMD_COND_READ_BLOCK); | 
|  | command[cmdlen-6] = data_reg; | 
|  | command[cmdlen-5] = status_reg; | 
|  | command[cmdlen-4] = timeout; | 
|  | command[cmdlen-3] = qualifier; | 
|  | command[cmdlen-2] = LSB_of(len); | 
|  | command[cmdlen-1] = MSB_of(len); | 
|  |  | 
|  | result = usbat_execute_command(us, command, cmdlen); | 
|  |  | 
|  | if (result != USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | if (i==0) { | 
|  |  | 
|  | for (j=0; j<num_registers; j++) { | 
|  | data[j<<1] = registers[j]; | 
|  | data[1+(j<<1)] = data_out[j]; | 
|  | } | 
|  |  | 
|  | 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, buf, len, use_sg, NULL); | 
|  |  | 
|  | /* | 
|  | * If we get a stall on the bulk download, we'll retry | 
|  | * the bulk download -- but not the SCSI command because | 
|  | * in some sense the SCSI command is still 'active' and | 
|  | * waiting for the data. Don't ask me why this should be; | 
|  | * I'm only following what the Windoze driver did. | 
|  | * | 
|  | * Note that a stall for the test-and-read/write command means | 
|  | * that the test failed. In this case we're testing to make | 
|  | * sure that the device is error-free | 
|  | * (i.e. bit 0 -- CHK -- of status is 0). The most likely | 
|  | * hypothesis is that the USBAT chip somehow knows what | 
|  | * the device will accept, but doesn't give the device any | 
|  | * data until all data is received. Thus, the device would | 
|  | * still be waiting for the first byte of data if a stall | 
|  | * occurs, even if the stall implies that some data was | 
|  | * transferred. | 
|  | */ | 
|  |  | 
|  | if (result == USB_STOR_XFER_SHORT || | 
|  | result == USB_STOR_XFER_STALLED) { | 
|  |  | 
|  | /* | 
|  | * If we're reading and we stalled, then clear | 
|  | * the bulk output pipe only the first time. | 
|  | */ | 
|  |  | 
|  | if (direction==DMA_FROM_DEVICE && i==0) { | 
|  | if (usb_stor_clear_halt(us, | 
|  | us->send_bulk_pipe) < 0) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Read status: is the device angry, or just busy? | 
|  | */ | 
|  |  | 
|  | result = usbat_read(us, USBAT_ATA, | 
|  | direction==DMA_TO_DEVICE ? | 
|  | USBAT_ATA_STATUS : USBAT_ATA_ALTSTATUS, | 
|  | status); | 
|  |  | 
|  | if (result!=USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  | if (*status & 0x01) /* check condition */ | 
|  | return USB_STOR_TRANSPORT_FAILED; | 
|  | if (*status & 0x20) /* device fault */ | 
|  | return USB_STOR_TRANSPORT_FAILED; | 
|  |  | 
|  | 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; | 
|  | else | 
|  | return usbat_wait_not_busy(us, minutes); | 
|  |  | 
|  | } | 
|  |  | 
|  | usb_stor_dbg(us, "Bummer! %s bulk data 20 times failed\n", | 
|  | direction == DMA_TO_DEVICE ? "Writing" : "Reading"); | 
|  |  | 
|  | return USB_STOR_TRANSPORT_FAILED; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Write to multiple registers: | 
|  | * Allows us to write specific data to any registers. The data to be written | 
|  | * gets packed in this sequence: reg0, data0, reg1, data1, ..., regN, dataN | 
|  | * which gets sent through bulk out. | 
|  | * Not designed for large transfers of data! | 
|  | */ | 
|  | static int usbat_multiple_write(struct us_data *us, | 
|  | unsigned char *registers, | 
|  | unsigned char *data_out, | 
|  | unsigned short num_registers) | 
|  | { | 
|  | int i, result; | 
|  | unsigned char *data = us->iobuf; | 
|  | unsigned char *command = us->iobuf; | 
|  |  | 
|  | BUG_ON(num_registers > US_IOBUF_SIZE/2); | 
|  |  | 
|  | /* Write to multiple registers, ATA access */ | 
|  | command[0] = 0x40; | 
|  | command[1] = USBAT_ATA | USBAT_CMD_WRITE_REGS; | 
|  |  | 
|  | /* No relevance */ | 
|  | command[2] = 0; | 
|  | command[3] = 0; | 
|  | command[4] = 0; | 
|  | command[5] = 0; | 
|  |  | 
|  | /* Number of bytes to be transferred (incl. addresses and data) */ | 
|  | command[6] = LSB_of(num_registers*2); | 
|  | command[7] = MSB_of(num_registers*2); | 
|  |  | 
|  | /* The setup command */ | 
|  | result = usbat_execute_command(us, command, 8); | 
|  | if (result != USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | /* Create the reg/data, reg/data sequence */ | 
|  | for (i=0; i<num_registers; i++) { | 
|  | data[i<<1] = registers[i]; | 
|  | data[1+(i<<1)] = data_out[i]; | 
|  | } | 
|  |  | 
|  | /* Send the data */ | 
|  | result = usbat_bulk_write(us, data, num_registers*2, 0); | 
|  | if (result != USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | if (usbat_get_device_type(us) == USBAT_DEV_HP8200) | 
|  | return usbat_wait_not_busy(us, 0); | 
|  | else | 
|  | return USB_STOR_TRANSPORT_GOOD; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Conditionally read blocks from device: | 
|  | * Allows us to read blocks from a specific data register, based upon the | 
|  | * condition that a status register can be successfully masked with a status | 
|  | * qualifier. If this condition is not initially met, the read will wait | 
|  | * up until a maximum amount of time has elapsed, as specified by timeout. | 
|  | * The read will start when the condition is met, otherwise the command aborts. | 
|  | * | 
|  | * The qualifier defined here is not the value that is masked, it defines | 
|  | * conditions for the write to take place. The actual masked qualifier (and | 
|  | * other related details) are defined beforehand with _set_shuttle_features(). | 
|  | */ | 
|  | static int usbat_read_blocks(struct us_data *us, | 
|  | void* buffer, | 
|  | int len, | 
|  | int use_sg) | 
|  | { | 
|  | int result; | 
|  | unsigned char *command = us->iobuf; | 
|  |  | 
|  | command[0] = 0xC0; | 
|  | command[1] = USBAT_ATA | USBAT_CMD_COND_READ_BLOCK; | 
|  | command[2] = USBAT_ATA_DATA; | 
|  | command[3] = USBAT_ATA_STATUS; | 
|  | command[4] = 0xFD; /* Timeout (ms); */ | 
|  | command[5] = USBAT_QUAL_FCQ; | 
|  | command[6] = LSB_of(len); | 
|  | command[7] = MSB_of(len); | 
|  |  | 
|  | /* Multiple block read setup command */ | 
|  | result = usbat_execute_command(us, command, 8); | 
|  | if (result != USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_FAILED; | 
|  |  | 
|  | /* Read the blocks we just asked for */ | 
|  | result = usbat_bulk_read(us, buffer, len, use_sg); | 
|  | if (result != USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_FAILED; | 
|  |  | 
|  | return USB_STOR_TRANSPORT_GOOD; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Conditionally write blocks to device: | 
|  | * Allows us to write blocks to a specific data register, based upon the | 
|  | * condition that a status register can be successfully masked with a status | 
|  | * qualifier. If this condition is not initially met, the write will wait | 
|  | * up until a maximum amount of time has elapsed, as specified by timeout. | 
|  | * The read will start when the condition is met, otherwise the command aborts. | 
|  | * | 
|  | * The qualifier defined here is not the value that is masked, it defines | 
|  | * conditions for the write to take place. The actual masked qualifier (and | 
|  | * other related details) are defined beforehand with _set_shuttle_features(). | 
|  | */ | 
|  | static int usbat_write_blocks(struct us_data *us, | 
|  | void* buffer, | 
|  | int len, | 
|  | int use_sg) | 
|  | { | 
|  | int result; | 
|  | unsigned char *command = us->iobuf; | 
|  |  | 
|  | command[0] = 0x40; | 
|  | command[1] = USBAT_ATA | USBAT_CMD_COND_WRITE_BLOCK; | 
|  | command[2] = USBAT_ATA_DATA; | 
|  | command[3] = USBAT_ATA_STATUS; | 
|  | command[4] = 0xFD; /* Timeout (ms) */ | 
|  | command[5] = USBAT_QUAL_FCQ; | 
|  | command[6] = LSB_of(len); | 
|  | command[7] = MSB_of(len); | 
|  |  | 
|  | /* Multiple block write setup command */ | 
|  | result = usbat_execute_command(us, command, 8); | 
|  | if (result != USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_FAILED; | 
|  |  | 
|  | /* Write the data */ | 
|  | result = usbat_bulk_write(us, buffer, len, use_sg); | 
|  | if (result != USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_FAILED; | 
|  |  | 
|  | return USB_STOR_TRANSPORT_GOOD; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Read the User IO register | 
|  | */ | 
|  | static int usbat_read_user_io(struct us_data *us, unsigned char *data_flags) | 
|  | { | 
|  | int result; | 
|  |  | 
|  | result = usb_stor_ctrl_transfer(us, | 
|  | us->recv_ctrl_pipe, | 
|  | USBAT_CMD_UIO, | 
|  | 0xC0, | 
|  | 0, | 
|  | 0, | 
|  | data_flags, | 
|  | USBAT_UIO_READ); | 
|  |  | 
|  | usb_stor_dbg(us, "UIO register reads %02X\n", *data_flags); | 
|  |  | 
|  | return result; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Write to the User IO register | 
|  | */ | 
|  | static int usbat_write_user_io(struct us_data *us, | 
|  | unsigned char enable_flags, | 
|  | unsigned char data_flags) | 
|  | { | 
|  | return usb_stor_ctrl_transfer(us, | 
|  | us->send_ctrl_pipe, | 
|  | USBAT_CMD_UIO, | 
|  | 0x40, | 
|  | short_pack(enable_flags, data_flags), | 
|  | 0, | 
|  | NULL, | 
|  | USBAT_UIO_WRITE); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Reset the device | 
|  | * Often needed on media change. | 
|  | */ | 
|  | static int usbat_device_reset(struct us_data *us) | 
|  | { | 
|  | int rc; | 
|  |  | 
|  | /* | 
|  | * Reset peripheral, enable peripheral control signals | 
|  | * (bring reset signal up) | 
|  | */ | 
|  | rc = usbat_write_user_io(us, | 
|  | USBAT_UIO_DRVRST | USBAT_UIO_OE1 | USBAT_UIO_OE0, | 
|  | USBAT_UIO_EPAD | USBAT_UIO_1); | 
|  | if (rc != USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | /* | 
|  | * Enable peripheral control signals | 
|  | * (bring reset signal down) | 
|  | */ | 
|  | rc = usbat_write_user_io(us, | 
|  | USBAT_UIO_OE1  | USBAT_UIO_OE0, | 
|  | USBAT_UIO_EPAD | USBAT_UIO_1); | 
|  | if (rc != USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | return USB_STOR_TRANSPORT_GOOD; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Enable card detect | 
|  | */ | 
|  | static int usbat_device_enable_cdt(struct us_data *us) | 
|  | { | 
|  | int rc; | 
|  |  | 
|  | /* Enable peripheral control signals and card detect */ | 
|  | rc = usbat_write_user_io(us, | 
|  | USBAT_UIO_ACKD | USBAT_UIO_OE1  | USBAT_UIO_OE0, | 
|  | USBAT_UIO_EPAD | USBAT_UIO_1); | 
|  | if (rc != USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | return USB_STOR_TRANSPORT_GOOD; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Determine if media is present. | 
|  | */ | 
|  | static int usbat_flash_check_media_present(struct us_data *us, | 
|  | unsigned char *uio) | 
|  | { | 
|  | if (*uio & USBAT_UIO_UI0) { | 
|  | usb_stor_dbg(us, "no media detected\n"); | 
|  | return USBAT_FLASH_MEDIA_NONE; | 
|  | } | 
|  |  | 
|  | return USBAT_FLASH_MEDIA_CF; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Determine if media has changed since last operation | 
|  | */ | 
|  | static int usbat_flash_check_media_changed(struct us_data *us, | 
|  | unsigned char *uio) | 
|  | { | 
|  | if (*uio & USBAT_UIO_0) { | 
|  | usb_stor_dbg(us, "media change detected\n"); | 
|  | return USBAT_FLASH_MEDIA_CHANGED; | 
|  | } | 
|  |  | 
|  | return USBAT_FLASH_MEDIA_SAME; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Check for media change / no media and handle the situation appropriately | 
|  | */ | 
|  | static int usbat_flash_check_media(struct us_data *us, | 
|  | struct usbat_info *info) | 
|  | { | 
|  | int rc; | 
|  | unsigned char *uio = us->iobuf; | 
|  |  | 
|  | rc = usbat_read_user_io(us, uio); | 
|  | if (rc != USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | /* Check for media existence */ | 
|  | rc = usbat_flash_check_media_present(us, uio); | 
|  | if (rc == USBAT_FLASH_MEDIA_NONE) { | 
|  | info->sense_key = 0x02; | 
|  | info->sense_asc = 0x3A; | 
|  | info->sense_ascq = 0x00; | 
|  | return USB_STOR_TRANSPORT_FAILED; | 
|  | } | 
|  |  | 
|  | /* Check for media change */ | 
|  | rc = usbat_flash_check_media_changed(us, uio); | 
|  | if (rc == USBAT_FLASH_MEDIA_CHANGED) { | 
|  |  | 
|  | /* Reset and re-enable card detect */ | 
|  | rc = usbat_device_reset(us); | 
|  | if (rc != USB_STOR_TRANSPORT_GOOD) | 
|  | return rc; | 
|  | rc = usbat_device_enable_cdt(us); | 
|  | if (rc != USB_STOR_TRANSPORT_GOOD) | 
|  | return rc; | 
|  |  | 
|  | msleep(50); | 
|  |  | 
|  | rc = usbat_read_user_io(us, uio); | 
|  | if (rc != USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | info->sense_key = UNIT_ATTENTION; | 
|  | info->sense_asc = 0x28; | 
|  | info->sense_ascq = 0x00; | 
|  | return USB_STOR_TRANSPORT_FAILED; | 
|  | } | 
|  |  | 
|  | return USB_STOR_TRANSPORT_GOOD; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Determine whether we are controlling a flash-based reader/writer, | 
|  | * or a HP8200-based CD drive. | 
|  | * Sets transport functions as appropriate. | 
|  | */ | 
|  | static int usbat_identify_device(struct us_data *us, | 
|  | struct usbat_info *info) | 
|  | { | 
|  | int rc; | 
|  | unsigned char status; | 
|  |  | 
|  | if (!us || !info) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | rc = usbat_device_reset(us); | 
|  | if (rc != USB_STOR_TRANSPORT_GOOD) | 
|  | return rc; | 
|  | msleep(500); | 
|  |  | 
|  | /* | 
|  | * In attempt to distinguish between HP CDRW's and Flash readers, we now | 
|  | * execute the IDENTIFY PACKET DEVICE command. On ATA devices (i.e. flash | 
|  | * readers), this command should fail with error. On ATAPI devices (i.e. | 
|  | * CDROM drives), it should succeed. | 
|  | */ | 
|  | rc = usbat_write(us, USBAT_ATA, USBAT_ATA_CMD, 0xA1); | 
|  | if (rc != USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | rc = usbat_get_status(us, &status); | 
|  | if (rc != USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | /* Check for error bit, or if the command 'fell through' */ | 
|  | if (status == 0xA1 || !(status & 0x01)) { | 
|  | /* Device is HP 8200 */ | 
|  | usb_stor_dbg(us, "Detected HP8200 CDRW\n"); | 
|  | info->devicetype = USBAT_DEV_HP8200; | 
|  | } else { | 
|  | /* Device is a CompactFlash reader/writer */ | 
|  | usb_stor_dbg(us, "Detected Flash reader/writer\n"); | 
|  | info->devicetype = USBAT_DEV_FLASH; | 
|  | } | 
|  |  | 
|  | return USB_STOR_TRANSPORT_GOOD; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Set the transport function based on the device type | 
|  | */ | 
|  | static int usbat_set_transport(struct us_data *us, | 
|  | struct usbat_info *info, | 
|  | int devicetype) | 
|  | { | 
|  |  | 
|  | if (!info->devicetype) | 
|  | info->devicetype = devicetype; | 
|  |  | 
|  | 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; | 
|  | break; | 
|  |  | 
|  | case USBAT_DEV_FLASH: | 
|  | us->transport = usbat_flash_transport; | 
|  | break; | 
|  | } | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Read the media capacity | 
|  | */ | 
|  | static int usbat_flash_get_sector_count(struct us_data *us, | 
|  | struct usbat_info *info) | 
|  | { | 
|  | unsigned char registers[3] = { | 
|  | USBAT_ATA_SECCNT, | 
|  | USBAT_ATA_DEVICE, | 
|  | USBAT_ATA_CMD, | 
|  | }; | 
|  | unsigned char  command[3] = { 0x01, 0xA0, 0xEC }; | 
|  | unsigned char *reply; | 
|  | unsigned char status; | 
|  | int rc; | 
|  |  | 
|  | if (!us || !info) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | reply = kmalloc(512, GFP_NOIO); | 
|  | if (!reply) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | /* ATA command : IDENTIFY DEVICE */ | 
|  | rc = usbat_multiple_write(us, registers, command, 3); | 
|  | if (rc != USB_STOR_XFER_GOOD) { | 
|  | usb_stor_dbg(us, "Gah! identify_device failed\n"); | 
|  | rc = USB_STOR_TRANSPORT_ERROR; | 
|  | goto leave; | 
|  | } | 
|  |  | 
|  | /* Read device status */ | 
|  | if (usbat_get_status(us, &status) != USB_STOR_XFER_GOOD) { | 
|  | rc = USB_STOR_TRANSPORT_ERROR; | 
|  | goto leave; | 
|  | } | 
|  |  | 
|  | msleep(100); | 
|  |  | 
|  | /* Read the device identification data */ | 
|  | rc = usbat_read_block(us, reply, 512, 0); | 
|  | if (rc != USB_STOR_TRANSPORT_GOOD) | 
|  | goto leave; | 
|  |  | 
|  | info->sectors = ((u32)(reply[117]) << 24) | | 
|  | ((u32)(reply[116]) << 16) | | 
|  | ((u32)(reply[115]) <<  8) | | 
|  | ((u32)(reply[114])      ); | 
|  |  | 
|  | rc = USB_STOR_TRANSPORT_GOOD; | 
|  |  | 
|  | leave: | 
|  | kfree(reply); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Read data from device | 
|  | */ | 
|  | static int usbat_flash_read_data(struct us_data *us, | 
|  | struct usbat_info *info, | 
|  | u32 sector, | 
|  | u32 sectors) | 
|  | { | 
|  | unsigned char registers[7] = { | 
|  | USBAT_ATA_FEATURES, | 
|  | USBAT_ATA_SECCNT, | 
|  | USBAT_ATA_SECNUM, | 
|  | USBAT_ATA_LBA_ME, | 
|  | USBAT_ATA_LBA_HI, | 
|  | USBAT_ATA_DEVICE, | 
|  | USBAT_ATA_STATUS, | 
|  | }; | 
|  | unsigned char command[7]; | 
|  | unsigned char *buffer; | 
|  | unsigned char  thistime; | 
|  | unsigned int totallen, alloclen; | 
|  | int len, result; | 
|  | unsigned int sg_offset = 0; | 
|  | struct scatterlist *sg = NULL; | 
|  |  | 
|  | result = usbat_flash_check_media(us, info); | 
|  | if (result != USB_STOR_TRANSPORT_GOOD) | 
|  | return result; | 
|  |  | 
|  | /* | 
|  | * we're working in LBA mode.  according to the ATA spec, | 
|  | * we can support up to 28-bit addressing.  I don't know if Jumpshot | 
|  | * supports beyond 24-bit addressing.  It's kind of hard to test | 
|  | * since it requires > 8GB CF card. | 
|  | */ | 
|  |  | 
|  | if (sector > 0x0FFFFFFF) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | totallen = sectors * info->ssize; | 
|  |  | 
|  | /* | 
|  | * Since we don't read more than 64 KB at a time, we have to create | 
|  | * a bounce buffer and move the data a piece at a time between the | 
|  | * bounce buffer and the actual transfer buffer. | 
|  | */ | 
|  |  | 
|  | alloclen = min(totallen, 65536u); | 
|  | buffer = kmalloc(alloclen, GFP_NOIO); | 
|  | if (buffer == NULL) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | do { | 
|  | /* | 
|  | * loop, never allocate or transfer more than 64k at once | 
|  | * (min(128k, 255*info->ssize) is the real limit) | 
|  | */ | 
|  | len = min(totallen, alloclen); | 
|  | thistime = (len / info->ssize) & 0xff; | 
|  |  | 
|  | /* ATA command 0x20 (READ SECTORS) */ | 
|  | usbat_pack_ata_sector_cmd(command, thistime, sector, 0x20); | 
|  |  | 
|  | /* Write/execute ATA read command */ | 
|  | result = usbat_multiple_write(us, registers, command, 7); | 
|  | if (result != USB_STOR_TRANSPORT_GOOD) | 
|  | goto leave; | 
|  |  | 
|  | /* Read the data we just requested */ | 
|  | result = usbat_read_blocks(us, buffer, len, 0); | 
|  | if (result != USB_STOR_TRANSPORT_GOOD) | 
|  | goto leave; | 
|  |  | 
|  | 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, &sg_offset, TO_XFER_BUF); | 
|  |  | 
|  | sector += thistime; | 
|  | totallen -= len; | 
|  | } while (totallen > 0); | 
|  |  | 
|  | kfree(buffer); | 
|  | return USB_STOR_TRANSPORT_GOOD; | 
|  |  | 
|  | leave: | 
|  | kfree(buffer); | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Write data to device | 
|  | */ | 
|  | static int usbat_flash_write_data(struct us_data *us, | 
|  | struct usbat_info *info, | 
|  | u32 sector, | 
|  | u32 sectors) | 
|  | { | 
|  | unsigned char registers[7] = { | 
|  | USBAT_ATA_FEATURES, | 
|  | USBAT_ATA_SECCNT, | 
|  | USBAT_ATA_SECNUM, | 
|  | USBAT_ATA_LBA_ME, | 
|  | USBAT_ATA_LBA_HI, | 
|  | USBAT_ATA_DEVICE, | 
|  | USBAT_ATA_STATUS, | 
|  | }; | 
|  | unsigned char command[7]; | 
|  | unsigned char *buffer; | 
|  | unsigned char  thistime; | 
|  | unsigned int totallen, alloclen; | 
|  | int len, result; | 
|  | unsigned int sg_offset = 0; | 
|  | struct scatterlist *sg = NULL; | 
|  |  | 
|  | result = usbat_flash_check_media(us, info); | 
|  | if (result != USB_STOR_TRANSPORT_GOOD) | 
|  | return result; | 
|  |  | 
|  | /* | 
|  | * we're working in LBA mode.  according to the ATA spec, | 
|  | * we can support up to 28-bit addressing.  I don't know if the device | 
|  | * supports beyond 24-bit addressing.  It's kind of hard to test | 
|  | * since it requires > 8GB media. | 
|  | */ | 
|  |  | 
|  | if (sector > 0x0FFFFFFF) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | totallen = sectors * info->ssize; | 
|  |  | 
|  | /* | 
|  | * Since we don't write more than 64 KB at a time, we have to create | 
|  | * a bounce buffer and move the data a piece at a time between the | 
|  | * bounce buffer and the actual transfer buffer. | 
|  | */ | 
|  |  | 
|  | alloclen = min(totallen, 65536u); | 
|  | buffer = kmalloc(alloclen, GFP_NOIO); | 
|  | if (buffer == NULL) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | do { | 
|  | /* | 
|  | * loop, never allocate or transfer more than 64k at once | 
|  | * (min(128k, 255*info->ssize) is the real limit) | 
|  | */ | 
|  | len = min(totallen, alloclen); | 
|  | thistime = (len / info->ssize) & 0xff; | 
|  |  | 
|  | /* Get the data from the transfer buffer */ | 
|  | usb_stor_access_xfer_buf(buffer, len, us->srb, | 
|  | &sg, &sg_offset, FROM_XFER_BUF); | 
|  |  | 
|  | /* ATA command 0x30 (WRITE SECTORS) */ | 
|  | usbat_pack_ata_sector_cmd(command, thistime, sector, 0x30); | 
|  |  | 
|  | /* Write/execute ATA write command */ | 
|  | result = usbat_multiple_write(us, registers, command, 7); | 
|  | if (result != USB_STOR_TRANSPORT_GOOD) | 
|  | goto leave; | 
|  |  | 
|  | /* Write the data */ | 
|  | result = usbat_write_blocks(us, buffer, len, 0); | 
|  | if (result != USB_STOR_TRANSPORT_GOOD) | 
|  | goto leave; | 
|  |  | 
|  | sector += thistime; | 
|  | totallen -= len; | 
|  | } while (totallen > 0); | 
|  |  | 
|  | kfree(buffer); | 
|  | return result; | 
|  |  | 
|  | leave: | 
|  | kfree(buffer); | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Squeeze a potentially huge (> 65535 byte) read10 command into | 
|  | * a little ( <= 65535 byte) ATAPI pipe | 
|  | */ | 
|  | static int usbat_hp8200e_handle_read10(struct us_data *us, | 
|  | unsigned char *registers, | 
|  | unsigned char *data, | 
|  | struct scsi_cmnd *srb) | 
|  | { | 
|  | int result = USB_STOR_TRANSPORT_GOOD; | 
|  | unsigned char *buffer; | 
|  | unsigned int len; | 
|  | unsigned int sector; | 
|  | unsigned int sg_offset = 0; | 
|  | struct scatterlist *sg = NULL; | 
|  |  | 
|  | usb_stor_dbg(us, "transfersize %d\n", srb->transfersize); | 
|  |  | 
|  | 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, | 
|  | scsi_sglist(srb), | 
|  | scsi_bufflen(srb), scsi_sg_count(srb), 1); | 
|  |  | 
|  | return result; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Since we're requesting more data than we can handle in | 
|  | * a single read command (max is 64k-1), we will perform | 
|  | * multiple reads, but each read must be in multiples of | 
|  | * a sector.  Luckily the sector size is in srb->transfersize | 
|  | * (see linux/drivers/scsi/sr.c). | 
|  | */ | 
|  |  | 
|  | if (data[7+0] == GPCMD_READ_CD) { | 
|  | len = short_pack(data[7+9], data[7+8]); | 
|  | len <<= 16; | 
|  | len |= data[7+7]; | 
|  | 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 */ | 
|  | usb_stor_dbg(us, "transfersize 0, forcing %d\n", | 
|  | srb->transfersize); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Since we only read in one block at a time, we have to create | 
|  | * a bounce buffer and move the data a piece at a time between the | 
|  | * bounce buffer and the actual transfer buffer. | 
|  | */ | 
|  |  | 
|  | len = (65535/srb->transfersize) * srb->transfersize; | 
|  | 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; | 
|  | sector = short_pack(data[7+3], data[7+2]); | 
|  | sector <<= 16; | 
|  | sector |= short_pack(data[7+5], data[7+4]); | 
|  | transferred = 0; | 
|  |  | 
|  | while (transferred != scsi_bufflen(srb)) { | 
|  |  | 
|  | 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) */ | 
|  |  | 
|  | /* Fix up the SCSI command sector and num sectors */ | 
|  |  | 
|  | data[7+2] = MSB_of(sector>>16); /* SCSI command sector */ | 
|  | data[7+3] = LSB_of(sector>>16); | 
|  | data[7+4] = MSB_of(sector&0xFFFF); | 
|  | data[7+5] = LSB_of(sector&0xFFFF); | 
|  | if (data[7+0] == GPCMD_READ_CD) | 
|  | data[7+6] = 0; | 
|  | data[7+7] = MSB_of(len / srb->transfersize); /* SCSI command */ | 
|  | data[7+8] = LSB_of(len / srb->transfersize); /* num sectors */ | 
|  |  | 
|  | 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, | 
|  | buffer, | 
|  | len, 0, 1); | 
|  |  | 
|  | if (result != USB_STOR_TRANSPORT_GOOD) | 
|  | break; | 
|  |  | 
|  | /* Store the data in the transfer buffer */ | 
|  | usb_stor_access_xfer_buf(buffer, len, srb, | 
|  | &sg, &sg_offset, TO_XFER_BUF); | 
|  |  | 
|  | /* Update the amount transferred and the sector number */ | 
|  |  | 
|  | transferred += len; | 
|  | sector += len / srb->transfersize; | 
|  |  | 
|  | } /* while transferred != scsi_bufflen(srb) */ | 
|  |  | 
|  | kfree(buffer); | 
|  | return result; | 
|  | } | 
|  |  | 
|  | static int usbat_select_and_test_registers(struct us_data *us) | 
|  | { | 
|  | int selector; | 
|  | unsigned char *status = us->iobuf; | 
|  |  | 
|  | /* try device = master, then device = slave. */ | 
|  | for (selector = 0xA0; selector <= 0xB0; selector += 0x10) { | 
|  | if (usbat_write(us, USBAT_ATA, USBAT_ATA_DEVICE, selector) != | 
|  | USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | if (usbat_read(us, USBAT_ATA, USBAT_ATA_STATUS, status) != | 
|  | USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | if (usbat_read(us, USBAT_ATA, USBAT_ATA_DEVICE, status) != | 
|  | USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | if (usbat_read(us, USBAT_ATA, USBAT_ATA_LBA_ME, status) != | 
|  | USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | if (usbat_read(us, USBAT_ATA, USBAT_ATA_LBA_HI, status) != | 
|  | USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | if (usbat_write(us, USBAT_ATA, USBAT_ATA_LBA_ME, 0x55) != | 
|  | USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | if (usbat_write(us, USBAT_ATA, USBAT_ATA_LBA_HI, 0xAA) != | 
|  | USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | if (usbat_read(us, USBAT_ATA, USBAT_ATA_LBA_ME, status) != | 
|  | USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | if (usbat_read(us, USBAT_ATA, USBAT_ATA_LBA_ME, status) != | 
|  | USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  | } | 
|  |  | 
|  | return USB_STOR_TRANSPORT_GOOD; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Initialize the USBAT processor and the storage device | 
|  | */ | 
|  | static int init_usbat(struct us_data *us, int devicetype) | 
|  | { | 
|  | int rc; | 
|  | struct usbat_info *info; | 
|  | unsigned char subcountH = USBAT_ATA_LBA_HI; | 
|  | unsigned char subcountL = USBAT_ATA_LBA_ME; | 
|  | unsigned char *status = us->iobuf; | 
|  |  | 
|  | us->extra = kzalloc(sizeof(struct usbat_info), GFP_NOIO); | 
|  | if (!us->extra) | 
|  | return 1; | 
|  |  | 
|  | info = (struct usbat_info *) (us->extra); | 
|  |  | 
|  | /* Enable peripheral control signals */ | 
|  | rc = usbat_write_user_io(us, | 
|  | USBAT_UIO_OE1 | USBAT_UIO_OE0, | 
|  | USBAT_UIO_EPAD | USBAT_UIO_1); | 
|  | if (rc != USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | usb_stor_dbg(us, "INIT 1\n"); | 
|  |  | 
|  | msleep(2000); | 
|  |  | 
|  | rc = usbat_read_user_io(us, status); | 
|  | if (rc != USB_STOR_TRANSPORT_GOOD) | 
|  | return rc; | 
|  |  | 
|  | usb_stor_dbg(us, "INIT 2\n"); | 
|  |  | 
|  | rc = usbat_read_user_io(us, status); | 
|  | if (rc != USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | rc = usbat_read_user_io(us, status); | 
|  | if (rc != USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | usb_stor_dbg(us, "INIT 3\n"); | 
|  |  | 
|  | rc = usbat_select_and_test_registers(us); | 
|  | if (rc != USB_STOR_TRANSPORT_GOOD) | 
|  | return rc; | 
|  |  | 
|  | 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; | 
|  |  | 
|  | 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; | 
|  |  | 
|  | 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; | 
|  |  | 
|  | usb_stor_dbg(us, "INIT 7\n"); | 
|  |  | 
|  | msleep(1400); | 
|  |  | 
|  | rc = usbat_read_user_io(us, status); | 
|  | if (rc != USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | usb_stor_dbg(us, "INIT 8\n"); | 
|  |  | 
|  | rc = usbat_select_and_test_registers(us); | 
|  | if (rc != USB_STOR_TRANSPORT_GOOD) | 
|  | return rc; | 
|  |  | 
|  | 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, devicetype)) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | usb_stor_dbg(us, "INIT 10\n"); | 
|  |  | 
|  | if (usbat_get_device_type(us) == USBAT_DEV_FLASH) { | 
|  | subcountH = 0x02; | 
|  | subcountL = 0x00; | 
|  | } | 
|  | rc = usbat_set_shuttle_features(us, (USBAT_FEAT_ETEN | USBAT_FEAT_ET2 | USBAT_FEAT_ET1), | 
|  | 0x00, 0x88, 0x08, subcountH, subcountL); | 
|  | if (rc != USB_STOR_XFER_GOOD) | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  |  | 
|  | usb_stor_dbg(us, "INIT 11\n"); | 
|  |  | 
|  | return USB_STOR_TRANSPORT_GOOD; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Transport for the HP 8200e | 
|  | */ | 
|  | static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us) | 
|  | { | 
|  | int result; | 
|  | unsigned char *status = us->iobuf; | 
|  | unsigned char registers[32]; | 
|  | unsigned char data[32]; | 
|  | unsigned int len; | 
|  | int i; | 
|  |  | 
|  | len = scsi_bufflen(srb); | 
|  |  | 
|  | /* Send A0 (ATA PACKET COMMAND). | 
|  | Note: I guess we're never going to get any of the ATA | 
|  | commands... just ATA Packet Commands. | 
|  | */ | 
|  |  | 
|  | registers[0] = USBAT_ATA_FEATURES; | 
|  | registers[1] = USBAT_ATA_SECCNT; | 
|  | registers[2] = USBAT_ATA_SECNUM; | 
|  | registers[3] = USBAT_ATA_LBA_ME; | 
|  | registers[4] = USBAT_ATA_LBA_HI; | 
|  | registers[5] = USBAT_ATA_DEVICE; | 
|  | registers[6] = USBAT_ATA_CMD; | 
|  | data[0] = 0x00; | 
|  | data[1] = 0x00; | 
|  | data[2] = 0x00; | 
|  | data[3] = len&0xFF; 		/* (cylL) = expected length (L) */ | 
|  | data[4] = (len>>8)&0xFF; 	/* (cylH) = expected length (H) */ | 
|  | data[5] = 0xB0; 		/* (device sel) = slave */ | 
|  | data[6] = 0xA0; 		/* (command) = ATA PACKET COMMAND */ | 
|  |  | 
|  | for (i=7; i<19; i++) { | 
|  | registers[i] = 0x10; | 
|  | data[i] = (i-7 >= srb->cmd_len) ? 0 : srb->cmnd[i-7]; | 
|  | } | 
|  |  | 
|  | result = usbat_get_status(us, 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) | 
|  | transferred = 0; | 
|  |  | 
|  | if (srb->sc_data_direction == DMA_TO_DEVICE) { | 
|  |  | 
|  | 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_TO_DEVICE, | 
|  | scsi_sglist(srb), | 
|  | len, scsi_sg_count(srb), 10); | 
|  |  | 
|  | if (result == USB_STOR_TRANSPORT_GOOD) { | 
|  | transferred += len; | 
|  | usb_stor_dbg(us, "Wrote %08X bytes\n", transferred); | 
|  | } | 
|  |  | 
|  | return result; | 
|  |  | 
|  | } else if (srb->cmnd[0] == READ_10 || | 
|  | srb->cmnd[0] == GPCMD_READ_CD) { | 
|  |  | 
|  | return usbat_hp8200e_handle_read10(us, registers, data, srb); | 
|  |  | 
|  | } | 
|  |  | 
|  | if (len > 0xFFFF) { | 
|  | usb_stor_dbg(us, "Error: len = %08X... what do I do now?\n", | 
|  | len); | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  | } | 
|  |  | 
|  | result = usbat_multiple_write(us, registers, data, 7); | 
|  |  | 
|  | if (result != USB_STOR_TRANSPORT_GOOD) | 
|  | return result; | 
|  |  | 
|  | /* | 
|  | * Write the 12-byte command header. | 
|  | * | 
|  | * If the command is BLANK then set the timer for 75 minutes. | 
|  | * Otherwise set it for 10 minutes. | 
|  | * | 
|  | * NOTE: THE 8200 DOCUMENTATION STATES THAT BLANKING A CDRW | 
|  | * AT SPEED 4 IS UNRELIABLE!!! | 
|  | */ | 
|  |  | 
|  | 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. */ | 
|  |  | 
|  | if (len != 0 && (srb->sc_data_direction == DMA_FROM_DEVICE)) { | 
|  |  | 
|  | /* How many bytes to read in? Check cylL register */ | 
|  |  | 
|  | if (usbat_read(us, USBAT_ATA, USBAT_ATA_LBA_ME, status) != | 
|  | USB_STOR_XFER_GOOD) { | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  | } | 
|  |  | 
|  | if (len > 0xFF) { /* need to read cylH also */ | 
|  | len = *status; | 
|  | if (usbat_read(us, USBAT_ATA, USBAT_ATA_LBA_HI, status) != | 
|  | USB_STOR_XFER_GOOD) { | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  | } | 
|  | len += ((unsigned int) *status)<<8; | 
|  | } | 
|  | else | 
|  | len = *status; | 
|  |  | 
|  |  | 
|  | result = usbat_read_block(us, scsi_sglist(srb), len, | 
|  | scsi_sg_count(srb)); | 
|  | } | 
|  |  | 
|  | return result; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Transport for USBAT02-based CompactFlash and similar storage devices | 
|  | */ | 
|  | static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us) | 
|  | { | 
|  | int rc; | 
|  | struct usbat_info *info = (struct usbat_info *) (us->extra); | 
|  | unsigned long block, blocks; | 
|  | unsigned char *ptr = us->iobuf; | 
|  | static unsigned char inquiry_response[36] = { | 
|  | 0x00, 0x80, 0x00, 0x01, 0x1F, 0x00, 0x00, 0x00 | 
|  | }; | 
|  |  | 
|  | if (srb->cmnd[0] == INQUIRY) { | 
|  | 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; | 
|  | } | 
|  |  | 
|  | if (srb->cmnd[0] == READ_CAPACITY) { | 
|  | rc = usbat_flash_check_media(us, info); | 
|  | if (rc != USB_STOR_TRANSPORT_GOOD) | 
|  | return rc; | 
|  |  | 
|  | rc = usbat_flash_get_sector_count(us, info); | 
|  | if (rc != USB_STOR_TRANSPORT_GOOD) | 
|  | return rc; | 
|  |  | 
|  | /* hard coded 512 byte sectors as per ATA spec */ | 
|  | info->ssize = 0x200; | 
|  | usb_stor_dbg(us, "READ_CAPACITY: %ld sectors, %ld bytes per sector\n", | 
|  | info->sectors, info->ssize); | 
|  |  | 
|  | /* | 
|  | * build the reply | 
|  | * note: must return the sector number of the last sector, | 
|  | * *not* the total number of sectors | 
|  | */ | 
|  | ((__be32 *) ptr)[0] = cpu_to_be32(info->sectors - 1); | 
|  | ((__be32 *) ptr)[1] = cpu_to_be32(info->ssize); | 
|  | usb_stor_set_xfer_buf(ptr, 8, srb); | 
|  |  | 
|  | return USB_STOR_TRANSPORT_GOOD; | 
|  | } | 
|  |  | 
|  | if (srb->cmnd[0] == MODE_SELECT_10) { | 
|  | usb_stor_dbg(us, "Gah! MODE_SELECT_10\n"); | 
|  | return USB_STOR_TRANSPORT_ERROR; | 
|  | } | 
|  |  | 
|  | if (srb->cmnd[0] == READ_10) { | 
|  | block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) | | 
|  | ((u32)(srb->cmnd[4]) <<  8) | ((u32)(srb->cmnd[5])); | 
|  |  | 
|  | blocks = ((u32)(srb->cmnd[7]) << 8) | ((u32)(srb->cmnd[8])); | 
|  |  | 
|  | usb_stor_dbg(us, "READ_10: read block 0x%04lx  count %ld\n", | 
|  | block, blocks); | 
|  | return usbat_flash_read_data(us, info, block, blocks); | 
|  | } | 
|  |  | 
|  | if (srb->cmnd[0] == READ_12) { | 
|  | /* | 
|  | * I don't think we'll ever see a READ_12 but support it anyway | 
|  | */ | 
|  | block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) | | 
|  | ((u32)(srb->cmnd[4]) <<  8) | ((u32)(srb->cmnd[5])); | 
|  |  | 
|  | blocks = ((u32)(srb->cmnd[6]) << 24) | ((u32)(srb->cmnd[7]) << 16) | | 
|  | ((u32)(srb->cmnd[8]) <<  8) | ((u32)(srb->cmnd[9])); | 
|  |  | 
|  | usb_stor_dbg(us, "READ_12: read block 0x%04lx  count %ld\n", | 
|  | block, blocks); | 
|  | return usbat_flash_read_data(us, info, block, blocks); | 
|  | } | 
|  |  | 
|  | if (srb->cmnd[0] == WRITE_10) { | 
|  | block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) | | 
|  | ((u32)(srb->cmnd[4]) <<  8) | ((u32)(srb->cmnd[5])); | 
|  |  | 
|  | blocks = ((u32)(srb->cmnd[7]) << 8) | ((u32)(srb->cmnd[8])); | 
|  |  | 
|  | usb_stor_dbg(us, "WRITE_10: write block 0x%04lx  count %ld\n", | 
|  | block, blocks); | 
|  | return usbat_flash_write_data(us, info, block, blocks); | 
|  | } | 
|  |  | 
|  | if (srb->cmnd[0] == WRITE_12) { | 
|  | /* | 
|  | * I don't think we'll ever see a WRITE_12 but support it anyway | 
|  | */ | 
|  | block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) | | 
|  | ((u32)(srb->cmnd[4]) <<  8) | ((u32)(srb->cmnd[5])); | 
|  |  | 
|  | blocks = ((u32)(srb->cmnd[6]) << 24) | ((u32)(srb->cmnd[7]) << 16) | | 
|  | ((u32)(srb->cmnd[8]) <<  8) | ((u32)(srb->cmnd[9])); | 
|  |  | 
|  | 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) { | 
|  | usb_stor_dbg(us, "TEST_UNIT_READY\n"); | 
|  |  | 
|  | rc = usbat_flash_check_media(us, info); | 
|  | if (rc != USB_STOR_TRANSPORT_GOOD) | 
|  | return rc; | 
|  |  | 
|  | return usbat_check_status(us); | 
|  | } | 
|  |  | 
|  | if (srb->cmnd[0] == REQUEST_SENSE) { | 
|  | usb_stor_dbg(us, "REQUEST_SENSE\n"); | 
|  |  | 
|  | memset(ptr, 0, 18); | 
|  | ptr[0] = 0xF0; | 
|  | ptr[2] = info->sense_key; | 
|  | ptr[7] = 11; | 
|  | ptr[12] = info->sense_asc; | 
|  | ptr[13] = info->sense_ascq; | 
|  | usb_stor_set_xfer_buf(ptr, 18, srb); | 
|  |  | 
|  | return USB_STOR_TRANSPORT_GOOD; | 
|  | } | 
|  |  | 
|  | if (srb->cmnd[0] == ALLOW_MEDIUM_REMOVAL) { | 
|  | /* | 
|  | * sure.  whatever.  not like we can stop the user from popping | 
|  | * the media out of the device (no locking doors, etc) | 
|  | */ | 
|  | return USB_STOR_TRANSPORT_GOOD; | 
|  | } | 
|  |  | 
|  | 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 init_usbat_cd(struct us_data *us) | 
|  | { | 
|  | return init_usbat(us, USBAT_DEV_HP8200); | 
|  | } | 
|  |  | 
|  | 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; | 
|  |  | 
|  | /* 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); |