diff options
Diffstat (limited to 'drivers/usb/storage')
-rw-r--r-- | drivers/usb/storage/Kconfig | 39 | ||||
-rw-r--r-- | drivers/usb/storage/Makefile | 1 | ||||
-rw-r--r-- | drivers/usb/storage/cypress_atacb.c | 200 | ||||
-rw-r--r-- | drivers/usb/storage/cypress_atacb.h | 25 | ||||
-rw-r--r-- | drivers/usb/storage/libusual.c | 14 | ||||
-rw-r--r-- | drivers/usb/storage/scsiglue.c | 26 | ||||
-rw-r--r-- | drivers/usb/storage/transport.c | 23 | ||||
-rw-r--r-- | drivers/usb/storage/unusual_devs.h | 8 | ||||
-rw-r--r-- | drivers/usb/storage/usb.c | 26 |
9 files changed, 309 insertions, 53 deletions
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index 7e53333be01..0f6d234d699 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig @@ -32,8 +32,8 @@ config USB_STORAGE_DEBUG verbose debugging messages. config USB_STORAGE_DATAFAB - bool "Datafab Compact Flash Reader support (EXPERIMENTAL)" - depends on USB_STORAGE && EXPERIMENTAL + bool "Datafab Compact Flash Reader support" + depends on USB_STORAGE help Support for certain Datafab CompactFlash readers. Datafab has a web page at <http://www.datafabusa.com/>. @@ -69,8 +69,8 @@ config USB_STORAGE_DPCM There is a web page at <http://www.ziocorp.com/products/>. config USB_STORAGE_USBAT - bool "USBAT/USBAT02-based storage support (EXPERIMENTAL)" - depends on USB_STORAGE && EXPERIMENTAL + bool "USBAT/USBAT02-based storage support" + depends on USB_STORAGE help Say Y here to include additional code to support storage devices based on the SCM/Shuttle USBAT/USBAT02 processors. @@ -90,30 +90,30 @@ config USB_STORAGE_USBAT - Sandisk ImageMate SDDR-05b config USB_STORAGE_SDDR09 - bool "SanDisk SDDR-09 (and other SmartMedia) support (EXPERIMENTAL)" - depends on USB_STORAGE && EXPERIMENTAL + bool "SanDisk SDDR-09 (and other SmartMedia) support" + depends on USB_STORAGE help Say Y here to include additional code to support the Sandisk SDDR-09 SmartMedia reader in the USB Mass Storage driver. Also works for the Microtech Zio! SmartMedia reader. config USB_STORAGE_SDDR55 - bool "SanDisk SDDR-55 SmartMedia support (EXPERIMENTAL)" - depends on USB_STORAGE && EXPERIMENTAL + bool "SanDisk SDDR-55 SmartMedia support" + depends on USB_STORAGE help Say Y here to include additional code to support the Sandisk SDDR-55 SmartMedia reader in the USB Mass Storage driver. config USB_STORAGE_JUMPSHOT - bool "Lexar Jumpshot Compact Flash Reader (EXPERIMENTAL)" - depends on USB_STORAGE && EXPERIMENTAL + bool "Lexar Jumpshot Compact Flash Reader" + depends on USB_STORAGE help Say Y here to include additional code to support the Lexar Jumpshot USB CompactFlash reader. config USB_STORAGE_ALAUDA - bool "Olympus MAUSB-10/Fuji DPC-R1 support (EXPERIMENTAL)" - depends on USB_STORAGE && EXPERIMENTAL + bool "Olympus MAUSB-10/Fuji DPC-R1 support" + depends on USB_STORAGE help Say Y here to include additional code to support the Olympus MAUSB-10 and Fujifilm DPC-R1 USB Card reader/writer devices. @@ -122,8 +122,8 @@ config USB_STORAGE_ALAUDA XD and SmartMedia cards. config USB_STORAGE_ONETOUCH - bool "Support OneTouch Button on Maxtor Hard Drives (EXPERIMENTAL)" - depends on USB_STORAGE && INPUT_EVDEV && EXPERIMENTAL && !PM + bool "Support OneTouch Button on Maxtor Hard Drives" + depends on USB_STORAGE && INPUT_EVDEV help Say Y here to include additional code to support the Maxtor OneTouch USB hard drive's onetouch button. @@ -145,6 +145,17 @@ config USB_STORAGE_KARMA on the resulting scsi device node returns the Karma to normal operation. +config USB_STORAGE_CYPRESS_ATACB + bool "SAT emulation on Cypress USB/ATA Bridge with ATACB" + depends on USB_STORAGE + ---help--- + Say Y here if you want to use SAT (ata pass through) on devices based + on the Cypress USB/ATA bridge supporting ATACB. This will allow you + to use tools to tune and monitor your drive (like hdparm or smartctl). + + If you say no here your device will still work with the standard usb + mass storage class. + config USB_LIBUSUAL bool "The shared table of common (or usual) storage devices" depends on USB diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile index 023969b4385..4c596c766c5 100644 --- a/drivers/usb/storage/Makefile +++ b/drivers/usb/storage/Makefile @@ -21,6 +21,7 @@ usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += jumpshot.o usb-storage-obj-$(CONFIG_USB_STORAGE_ALAUDA) += alauda.o usb-storage-obj-$(CONFIG_USB_STORAGE_ONETOUCH) += onetouch.o usb-storage-obj-$(CONFIG_USB_STORAGE_KARMA) += karma.o +usb-storage-obj-$(CONFIG_USB_STORAGE_CYPRESS_ATACB) += cypress_atacb.o usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \ initializers.o $(usb-storage-obj-y) diff --git a/drivers/usb/storage/cypress_atacb.c b/drivers/usb/storage/cypress_atacb.c new file mode 100644 index 00000000000..d88824b3511 --- /dev/null +++ b/drivers/usb/storage/cypress_atacb.c @@ -0,0 +1,200 @@ +/* + * Support for emulating SAT (ata pass through) on devices based + * on the Cypress USB/ATA bridge supporting ATACB. + * + * Copyright (c) 2008 Matthieu Castet (castet.matthieu@free.fr) + * + * 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 <scsi/scsi.h> +#include <scsi/scsi_cmnd.h> +#include <scsi/scsi_eh.h> +#include <linux/ata.h> + +#include "usb.h" +#include "protocol.h" +#include "scsiglue.h" +#include "debug.h" + +/* + * ATACB is a protocol used on cypress usb<->ata bridge to + * send raw ATA command over mass storage + * There is a ATACB2 protocol that support LBA48 on newer chip. + * More info that be found on cy7c68310_8.pdf and cy7c68300c_8.pdf + * datasheet from cypress.com. + */ +void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us) +{ + unsigned char save_cmnd[MAX_COMMAND_SIZE]; + + if (likely(srb->cmnd[0] != ATA_16 && srb->cmnd[0] != ATA_12)) { + usb_stor_transparent_scsi_command(srb, us); + return; + } + + memcpy(save_cmnd, srb->cmnd, sizeof(save_cmnd)); + memset(srb->cmnd, 0, sizeof(srb->cmnd)); + + /* check if we support the command */ + if (save_cmnd[1] >> 5) /* MULTIPLE_COUNT */ + goto invalid_fld; + /* check protocol */ + switch((save_cmnd[1] >> 1) & 0xf) { + case 3: /*no DATA */ + case 4: /* PIO in */ + case 5: /* PIO out */ + break; + default: + goto invalid_fld; + } + + /* first build the ATACB command */ + srb->cmd_len = 16; + + srb->cmnd[0] = 0x24; /* bVSCBSignature : vendor-specific command + this value can change, but most(all ?) manufacturers + keep the cypress default : 0x24 */ + srb->cmnd[1] = 0x24; /* bVSCBSubCommand : 0x24 for ATACB */ + + srb->cmnd[3] = 0xff - 1; /* features, sector count, lba low, lba med + lba high, device, command are valid */ + srb->cmnd[4] = 1; /* TransferBlockCount : 512 */ + + if (save_cmnd[0] == ATA_16) { + srb->cmnd[ 6] = save_cmnd[ 4]; /* features */ + srb->cmnd[ 7] = save_cmnd[ 6]; /* sector count */ + srb->cmnd[ 8] = save_cmnd[ 8]; /* lba low */ + srb->cmnd[ 9] = save_cmnd[10]; /* lba med */ + srb->cmnd[10] = save_cmnd[12]; /* lba high */ + srb->cmnd[11] = save_cmnd[13]; /* device */ + srb->cmnd[12] = save_cmnd[14]; /* command */ + + if (save_cmnd[1] & 0x01) {/* extended bit set for LBA48 */ + /* this could be supported by atacb2 */ + if (save_cmnd[3] || save_cmnd[5] || save_cmnd[7] || save_cmnd[9] + || save_cmnd[11]) + goto invalid_fld; + } + } + else { /* ATA12 */ + srb->cmnd[ 6] = save_cmnd[3]; /* features */ + srb->cmnd[ 7] = save_cmnd[4]; /* sector count */ + srb->cmnd[ 8] = save_cmnd[5]; /* lba low */ + srb->cmnd[ 9] = save_cmnd[6]; /* lba med */ + srb->cmnd[10] = save_cmnd[7]; /* lba high */ + srb->cmnd[11] = save_cmnd[8]; /* device */ + srb->cmnd[12] = save_cmnd[9]; /* command */ + + } + /* Filter SET_FEATURES - XFER MODE command */ + if ((srb->cmnd[12] == ATA_CMD_SET_FEATURES) + && (srb->cmnd[6] == SETFEATURES_XFER)) + goto invalid_fld; + + if (srb->cmnd[12] == ATA_CMD_ID_ATA || srb->cmnd[12] == ATA_CMD_ID_ATAPI) + srb->cmnd[2] |= (1<<7); /* set IdentifyPacketDevice for these cmds */ + + + usb_stor_transparent_scsi_command(srb, us); + + /* if the device doesn't support ATACB + */ + if (srb->result == SAM_STAT_CHECK_CONDITION && + memcmp(srb->sense_buffer, usb_stor_sense_invalidCDB, + sizeof(usb_stor_sense_invalidCDB)) == 0) { + US_DEBUGP("cypress atacb not supported ???\n"); + goto end; + } + + /* if ck_cond flags is set, and there wasn't critical error, + * build the special sense + */ + if ((srb->result != (DID_ERROR << 16) && + srb->result != (DID_ABORT << 16)) && + save_cmnd[2] & 0x20) { + struct scsi_eh_save ses; + unsigned char regs[8]; + unsigned char *sb = srb->sense_buffer; + unsigned char *desc = sb + 8; + int tmp_result; + + /* build the command for + * reading the ATA registers */ + scsi_eh_prep_cmnd(srb, &ses, NULL, 0, 0); + srb->sdb.length = sizeof(regs); + sg_init_one(&ses.sense_sgl, regs, srb->sdb.length); + srb->sdb.table.sgl = &ses.sense_sgl; + srb->sc_data_direction = DMA_FROM_DEVICE; + srb->sdb.table.nents = 1; + /* we use the same command as before, but we set + * the read taskfile bit, for not executing atacb command, + * but reading register selected in srb->cmnd[4] + */ + srb->cmnd[2] = 1; + + usb_stor_transparent_scsi_command(srb, us); + tmp_result = srb->result; + scsi_eh_restore_cmnd(srb, &ses); + /* we fail to get registers, report invalid command */ + if (tmp_result != SAM_STAT_GOOD) + goto invalid_fld; + + /* build the sense */ + memset(sb, 0, SCSI_SENSE_BUFFERSIZE); + + /* set sk, asc for a good command */ + sb[1] = RECOVERED_ERROR; + sb[2] = 0; /* ATA PASS THROUGH INFORMATION AVAILABLE */ + sb[3] = 0x1D; + + /* XXX we should generate sk, asc, ascq from status and error + * regs + * (see 11.1 Error translation ATA device error to SCSI error map) + * and ata_to_sense_error from libata. + */ + + /* Sense data is current and format is descriptor. */ + sb[0] = 0x72; + desc[0] = 0x09; /* ATA_RETURN_DESCRIPTOR */ + + /* set length of additional sense data */ + sb[7] = 14; + desc[1] = 12; + + /* Copy registers into sense buffer. */ + desc[ 2] = 0x00; + desc[ 3] = regs[1]; /* features */ + desc[ 5] = regs[2]; /* sector count */ + desc[ 7] = regs[3]; /* lba low */ + desc[ 9] = regs[4]; /* lba med */ + desc[11] = regs[5]; /* lba high */ + desc[12] = regs[6]; /* device */ + desc[13] = regs[7]; /* command */ + + srb->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; + } + goto end; +invalid_fld: + srb->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; + + memcpy(srb->sense_buffer, + usb_stor_sense_invalidCDB, + sizeof(usb_stor_sense_invalidCDB)); +end: + memcpy(srb->cmnd, save_cmnd, sizeof(save_cmnd)); + if (srb->cmnd[0] == ATA_12) + srb->cmd_len = 12; +} diff --git a/drivers/usb/storage/cypress_atacb.h b/drivers/usb/storage/cypress_atacb.h new file mode 100644 index 00000000000..fbada898d56 --- /dev/null +++ b/drivers/usb/storage/cypress_atacb.h @@ -0,0 +1,25 @@ +/* + * Support for emulating SAT (ata pass through) on devices based + * on the Cypress USB/ATA bridge supporting ATACB. + * + * Copyright (c) 2008 Matthieu Castet (castet.matthieu@free.fr) + * + * 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. + */ + +#ifndef _CYPRESS_ATACB_H_ +#define _CYPRESS_ATACB_H_ +extern void cypress_atacb_passthrough(struct scsi_cmnd*, struct us_data*); +#endif diff --git a/drivers/usb/storage/libusual.c b/drivers/usb/storage/libusual.c index 55b952084f0..a28d49122e7 100644 --- a/drivers/usb/storage/libusual.c +++ b/drivers/usb/storage/libusual.c @@ -9,6 +9,7 @@ #include <linux/usb_usual.h> #include <linux/vmalloc.h> #include <linux/kthread.h> +#include <linux/mutex.h> /* */ @@ -30,7 +31,7 @@ static atomic_t usu_bias = ATOMIC_INIT(USB_US_DEFAULT_BIAS); #define BIAS_NAME_SIZE (sizeof("usb-storage")) static const char *bias_names[3] = { "none", "usb-storage", "ub" }; -static struct semaphore usu_init_notify; +static DEFINE_MUTEX(usu_probe_mutex); static DECLARE_COMPLETION(usu_end_notify); static atomic_t total_threads = ATOMIC_INIT(0); @@ -178,10 +179,7 @@ static int usu_probe_thread(void *arg) int rc; unsigned long flags; - /* A completion does not work here because it's counted. */ - down(&usu_init_notify); - up(&usu_init_notify); - + mutex_lock(&usu_probe_mutex); rc = request_module(bias_names[type]); spin_lock_irqsave(&usu_lock, flags); if (rc == 0 && (st->fls & USU_MOD_FL_PRESENT) == 0) { @@ -194,6 +192,7 @@ static int usu_probe_thread(void *arg) } st->fls &= ~USU_MOD_FL_THREAD; spin_unlock_irqrestore(&usu_lock, flags); + mutex_unlock(&usu_probe_mutex); complete_and_exit(&usu_end_notify, 0); } @@ -204,10 +203,9 @@ static int __init usb_usual_init(void) { int rc; - sema_init(&usu_init_notify, 0); - + mutex_lock(&usu_probe_mutex); rc = usb_register(&usu_driver); - up(&usu_init_notify); + mutex_unlock(&usu_probe_mutex); return rc; } diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 8c1e2954f3b..3fcde9f0fa5 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -73,6 +73,7 @@ static const char* host_info(struct Scsi_Host *host) static int slave_alloc (struct scsi_device *sdev) { struct us_data *us = host_to_us(sdev->host); + struct usb_host_endpoint *bulk_in_ep; /* * Set the INQUIRY transfer length to 36. We don't use any of @@ -84,12 +85,13 @@ static int slave_alloc (struct scsi_device *sdev) /* Scatter-gather buffers (all but the last) must have a length * divisible by the bulk maxpacket size. Otherwise a data packet * would end up being short, causing a premature end to the data - * transfer. Since high-speed bulk pipes have a maxpacket size - * of 512, we'll use that as the scsi device queue's DMA alignment - * mask. Guaranteeing proper alignment of the first buffer will - * have the desired effect because, except at the beginning and - * the end, scatter-gather buffers follow page boundaries. */ - blk_queue_update_dma_alignment(sdev->request_queue, (512 - 1)); + * transfer. We'll use the maxpacket value of the bulk-IN pipe + * to set the SCSI device queue's DMA alignment mask. + */ + bulk_in_ep = us->pusb_dev->ep_in[usb_pipeendpoint(us->recv_bulk_pipe)]; + blk_queue_update_dma_alignment(sdev->request_queue, + le16_to_cpu(bulk_in_ep->desc.wMaxPacketSize) - 1); + /* wMaxPacketSize must be a power of 2 */ /* * The UFI spec treates the Peripheral Qualifier bits in an @@ -132,7 +134,7 @@ static int slave_configure(struct scsi_device *sdev) /* Disk-type devices use MODE SENSE(6) if the protocol * (SubClass) is Transparent SCSI, otherwise they use * MODE SENSE(10). */ - if (us->subclass != US_SC_SCSI) + if (us->subclass != US_SC_SCSI && us->subclass != US_SC_CYP_ATACB) sdev->use_10_for_ms = 1; /* Many disks only accept MODE SENSE transfer lengths of @@ -226,12 +228,12 @@ static int queuecommand(struct scsi_cmnd *srb, { struct us_data *us = host_to_us(srb->device->host); - US_DEBUGP("%s called\n", __FUNCTION__); + US_DEBUGP("%s called\n", __func__); /* check for state-transition errors */ if (us->srb != NULL) { printk(KERN_ERR USB_STORAGE "Error in %s: us->srb = %p\n", - __FUNCTION__, us->srb); + __func__, us->srb); return SCSI_MLQUEUE_HOST_BUSY; } @@ -260,7 +262,7 @@ static int command_abort(struct scsi_cmnd *srb) { struct us_data *us = host_to_us(srb->device->host); - US_DEBUGP("%s called\n", __FUNCTION__); + US_DEBUGP("%s called\n", __func__); /* us->srb together with the TIMED_OUT, RESETTING, and ABORTING * bits are protected by the host lock. */ @@ -297,7 +299,7 @@ static int device_reset(struct scsi_cmnd *srb) struct us_data *us = host_to_us(srb->device->host); int result; - US_DEBUGP("%s called\n", __FUNCTION__); + US_DEBUGP("%s called\n", __func__); /* lock the device pointers and do the reset */ mutex_lock(&(us->dev_mutex)); @@ -313,7 +315,7 @@ static int bus_reset(struct scsi_cmnd *srb) struct us_data *us = host_to_us(srb->device->host); int result; - US_DEBUGP("%s called\n", __FUNCTION__); + US_DEBUGP("%s called\n", __func__); result = usb_stor_port_reset(us); return result < 0 ? FAILED : SUCCESS; } diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index bdd4334bed5..6610d2dd1e7 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -110,7 +110,7 @@ */ static void usb_stor_blocking_completion(struct urb *urb) { - struct completion *urb_done_ptr = (struct completion *)urb->context; + struct completion *urb_done_ptr = urb->context; complete(urb_done_ptr); } @@ -198,7 +198,7 @@ int usb_stor_control_msg(struct us_data *us, unsigned int pipe, int status; US_DEBUGP("%s: rq=%02x rqtype=%02x value=%04x index=%02x len=%u\n", - __FUNCTION__, request, requesttype, + __func__, request, requesttype, value, index, size); /* fill in the devrequest structure */ @@ -250,7 +250,7 @@ int usb_stor_clear_halt(struct us_data *us, unsigned int pipe) usb_settoggle(us->pusb_dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 0); - US_DEBUGP("%s: result = %d\n", __FUNCTION__, result); + US_DEBUGP("%s: result = %d\n", __func__, result); return result; } @@ -332,7 +332,7 @@ int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe, int result; US_DEBUGP("%s: rq=%02x rqtype=%02x value=%04x index=%02x len=%u\n", - __FUNCTION__, request, requesttype, + __func__, request, requesttype, value, index, size); /* fill in the devrequest structure */ @@ -366,7 +366,7 @@ static int usb_stor_intr_transfer(struct us_data *us, void *buf, unsigned int pipe = us->recv_intr_pipe; unsigned int maxp; - US_DEBUGP("%s: xfer %u bytes\n", __FUNCTION__, length); + US_DEBUGP("%s: xfer %u bytes\n", __func__, length); /* calculate the max packet size */ maxp = usb_maxpacket(us->pusb_dev, pipe, usb_pipeout(pipe)); @@ -393,7 +393,7 @@ int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe, { int result; - US_DEBUGP("%s: xfer %u bytes\n", __FUNCTION__, length); + US_DEBUGP("%s: xfer %u bytes\n", __func__, length); /* fill and submit the URB */ usb_fill_bulk_urb(us->current_urb, us->pusb_dev, pipe, buf, length, @@ -424,7 +424,7 @@ static int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe, return USB_STOR_XFER_ERROR; /* initialize the scatter-gather request block */ - US_DEBUGP("%s: xfer %u bytes, %d entries\n", __FUNCTION__, + US_DEBUGP("%s: xfer %u bytes, %d entries\n", __func__, length, num_sg); result = usb_sg_init(&us->current_sg, us->pusb_dev, pipe, 0, sg, num_sg, length, GFP_NOIO); @@ -603,7 +603,8 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) scsi_eh_prep_cmnd(srb, &ses, NULL, 0, US_SENSE_SIZE); /* FIXME: we must do the protocol translation here */ - if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI) + if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI || + us->subclass == US_SC_CYP_ATACB) srb->cmd_len = 6; else srb->cmd_len = 12; @@ -700,7 +701,7 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) /* Stop the current URB transfer */ void usb_stor_stop_transport(struct us_data *us) { - US_DEBUGP("%s called\n", __FUNCTION__); + US_DEBUGP("%s called\n", __func__); /* If the state machine is blocked waiting for an URB, * let's wake it up. The test_and_clear_bit() call @@ -1134,7 +1135,7 @@ static int usb_stor_reset_common(struct us_data *us, int usb_stor_CB_reset(struct us_data *us) { - US_DEBUGP("%s called\n", __FUNCTION__); + US_DEBUGP("%s called\n", __func__); memset(us->iobuf, 0xFF, CB_RESET_CMD_SIZE); us->iobuf[0] = SEND_DIAGNOSTIC; @@ -1149,7 +1150,7 @@ int usb_stor_CB_reset(struct us_data *us) */ int usb_stor_Bulk_reset(struct us_data *us) { - US_DEBUGP("%s called\n", __FUNCTION__); + US_DEBUGP("%s called\n", __func__); return usb_stor_reset_common(us, US_BULK_RESET_REQUEST, USB_TYPE_CLASS | USB_RECIP_INTERFACE, diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 91252075e6e..732bf52a775 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1719,6 +1719,14 @@ UNUSUAL_DEV( 0xed06, 0x4500, 0x0001, 0x0001, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_CAPACITY_HEURISTICS), +#ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB +UNUSUAL_DEV( 0x04b4, 0x6830, 0x0000, 0x9999, + "Cypress", + "Cypress AT2LP", + US_SC_CYP_ATACB, US_PR_BULK, NULL, + 0), +#endif + /* Control/Bulk transport for all SubClass values */ USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR), USUAL_DEV(US_SC_8020, US_PR_CB, USB_US_TYPE_STOR), diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index ac6114eea0c..a856effad3b 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -101,6 +101,9 @@ #ifdef CONFIG_USB_STORAGE_KARMA #include "karma.h" #endif +#ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB +#include "cypress_atacb.h" +#endif /* Some informational data */ MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>"); @@ -187,7 +190,7 @@ static int storage_suspend(struct usb_interface *iface, pm_message_t message) /* Wait until no command is running */ mutex_lock(&us->dev_mutex); - US_DEBUGP("%s\n", __FUNCTION__); + US_DEBUGP("%s\n", __func__); if (us->suspend_resume_hook) (us->suspend_resume_hook)(us, US_SUSPEND); @@ -204,7 +207,7 @@ static int storage_resume(struct usb_interface *iface) mutex_lock(&us->dev_mutex); - US_DEBUGP("%s\n", __FUNCTION__); + US_DEBUGP("%s\n", __func__); if (us->suspend_resume_hook) (us->suspend_resume_hook)(us, US_RESUME); @@ -216,7 +219,7 @@ static int storage_reset_resume(struct usb_interface *iface) { struct us_data *us = usb_get_intfdata(iface); - US_DEBUGP("%s\n", __FUNCTION__); + US_DEBUGP("%s\n", __func__); /* Report the reset to the SCSI core */ usb_stor_report_bus_reset(us); @@ -237,7 +240,7 @@ static int storage_pre_reset(struct usb_interface *iface) { struct us_data *us = usb_get_intfdata(iface); - US_DEBUGP("%s\n", __FUNCTION__); + US_DEBUGP("%s\n", __func__); /* Make sure no command runs during the reset */ mutex_lock(&us->dev_mutex); @@ -248,7 +251,7 @@ static int storage_post_reset(struct usb_interface *iface) { struct us_data *us = usb_get_intfdata(iface); - US_DEBUGP("%s\n", __FUNCTION__); + US_DEBUGP("%s\n", __func__); /* Report the reset to the SCSI core */ usb_stor_report_bus_reset(us); @@ -434,7 +437,7 @@ SkipForAbort: /* Associate our private data with the USB device */ static int associate_dev(struct us_data *us, struct usb_interface *intf) { - US_DEBUGP("-- %s\n", __FUNCTION__); + US_DEBUGP("-- %s\n", __func__); /* Fill in the device-related fields */ us->pusb_dev = interface_to_usbdev(intf); @@ -708,6 +711,13 @@ static int get_protocol(struct us_data *us) break; #endif +#ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB + case US_SC_CYP_ATACB: + us->protocol_name = "Transparent SCSI with Cypress ATACB"; + us->proto_handler = cypress_atacb_passthrough; + break; +#endif + default: return -EIO; } @@ -806,7 +816,7 @@ static int usb_stor_acquire_resources(struct us_data *us) /* Release all our dynamic resources */ static void usb_stor_release_resources(struct us_data *us) { - US_DEBUGP("-- %s\n", __FUNCTION__); + US_DEBUGP("-- %s\n", __func__); /* Tell the control thread to exit. The SCSI host must * already have been removed so it won't try to queue @@ -832,7 +842,7 @@ static void usb_stor_release_resources(struct us_data *us) /* Dissociate from the USB device */ static void dissociate_dev(struct us_data *us) { - US_DEBUGP("-- %s\n", __FUNCTION__); + US_DEBUGP("-- %s\n", __func__); kfree(us->sensebuf); |