X-Git-Url: https://vcs.maemo.org/git/?a=blobdiff_plain;f=usbhost%2Fusb%2Fstorage%2Fshuttle_usbat.c;fp=usbhost%2Fusb%2Fstorage%2Fshuttle_usbat.c;h=0000000000000000000000000000000000000000;hb=be5e0463be71f581804375736a417723dc9f46bb;hp=ae6d64810d2a9d4cc8fc9db09fd68047136df801;hpb=b9788a4ac72d4b9819a8ce3d8faf0ce3b049185a;p=kernel-power diff --git a/usbhost/usb/storage/shuttle_usbat.c b/usbhost/usb/storage/shuttle_usbat.c deleted file mode 100644 index ae6d648..0000000 --- a/usbhost/usb/storage/shuttle_usbat.c +++ /dev/null @@ -1,1720 +0,0 @@ -/* 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 - * - * Developed with the assistance of: - * (c) 2002 Alan Stern - * - * Flash support based on earlier work by: - * (c) 2002 Thomas Kreiling - * - * 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 -#include -#include - -#include -#include - -#include "usb.h" -#include "transport.h" -#include "protocol.h" -#include "debug.h" -#include "shuttle_usbat.h" - -#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); - -/* - * 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; - - US_DEBUGP("usbat_bulk_read: 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; - - US_DEBUGP("usbat_bulk_write: 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); - - US_DEBUGP("usbat_get_status: 0x%02X\n", (unsigned short) (*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 prepartion 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 */ - US_DEBUGP("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 */ - } - - US_DEBUGP("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; jsend_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; - - US_DEBUGP("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); - - } - - US_DEBUGP("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; iiobuf; - - 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); - - US_DEBUGP("usbat_read_user_io: UIO register reads %02X\n", (unsigned short) (*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(unsigned char *uio) -{ - if (*uio & USBAT_UIO_UI0) { - US_DEBUGP("usbat_flash_check_media_present: 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(unsigned char *uio) -{ - if (*uio & USBAT_UIO_0) { - US_DEBUGP("usbat_flash_check_media_changed: 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(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(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 */ - US_DEBUGP("usbat_identify_device: 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"); - 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) { - US_DEBUGP("usbat_flash_get_sector_count: 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; - - US_DEBUGP("usbat_flash_read_data: %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; - - US_DEBUGP("handle_read10: 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]; - US_DEBUGP("handle_read10: 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); - } - - /* - * 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; - US_DEBUGP("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) { - US_DEBUGP("init_usbat: Gah! Can't allocate storage for usbat info struct!\n"); - 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; - - US_DEBUGP("INIT 1\n"); - - msleep(2000); - - rc = usbat_read_user_io(us, status); - if (rc != USB_STOR_TRANSPORT_GOOD) - return rc; - - US_DEBUGP("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; - - US_DEBUGP("INIT 3\n"); - - rc = usbat_select_and_test_registers(us); - if (rc != USB_STOR_TRANSPORT_GOOD) - return rc; - - US_DEBUGP("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"); - - /* 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"); - - rc = usbat_read_user_io(us, status); - if (rc != USB_STOR_XFER_GOOD) - return USB_STOR_TRANSPORT_ERROR; - - US_DEBUGP("INIT 7\n"); - - msleep(1400); - - rc = usbat_read_user_io(us, status); - if (rc != USB_STOR_XFER_GOOD) - return USB_STOR_TRANSPORT_ERROR; - - US_DEBUGP("INIT 8\n"); - - rc = usbat_select_and_test_registers(us); - if (rc != USB_STOR_TRANSPORT_GOOD) - return rc; - - US_DEBUGP("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; - - US_DEBUGP("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; - - US_DEBUGP("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); - US_DEBUGP("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; - US_DEBUGP("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) { - US_DEBUGP("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) { - 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!!! - */ - - if ((result = usbat_write_block(us, - USBAT_ATA, srb->cmnd, 12, - (srb->cmnd[0]==GPCMD_BLANK ? 75 : 10), 0) != - 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) { - US_DEBUGP("usbat_flash_transport: 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; - US_DEBUGP("usbat_flash_transport: 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) { - US_DEBUGP("usbat_flash_transport: 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])); - - US_DEBUGP("usbat_flash_transport: 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])); - - US_DEBUGP("usbat_flash_transport: 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])); - - US_DEBUGP("usbat_flash_transport: 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])); - - US_DEBUGP("usbat_flash_transport: 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"); - - 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) { - US_DEBUGP("usbat_flash_transport: 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; - } - - US_DEBUGP("usbat_flash_transport: 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; -} - -int init_usbat_cd(struct us_data *us) -{ - return init_usbat(us, USBAT_DEV_HP8200); -} - - -int init_usbat_flash(struct us_data *us) -{ - return init_usbat(us, USBAT_DEV_FLASH); -} - -int init_usbat_probe(struct us_data *us) -{ - return init_usbat(us, 0); -} - -/* - * 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) -{ - struct usbat_info *info = (struct usbat_info*) (us->extra); - - if (usbat_set_transport(us, info, 0)) - return USB_STOR_TRANSPORT_ERROR; - - return us->transport(srb, us); -}