aboutsummaryrefslogtreecommitdiffstats
diff options
authorGreg Kroah-Hartman <gregkh@suse.de>2010-09-28 19:01:48 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2010-09-28 19:01:48 -0700
commit56df444494ad03afc57e2f2d917377a09c3ff89b (patch)
tree53218969c46c6e95482addf12b4ae64fd6611e7d
parentdcf49f00a8e3c08f6484ba259e8d524aaac97881 (diff)
downloadpatches-56df444494ad03afc57e2f2d917377a09c3ff89b.tar.gz
uas driver patch
-rw-r--r--series4
-rw-r--r--usb/usb-add-uas-driver.patch828
-rw-r--r--usb/usb-gadget-file_storage-reuse-definitions-from-a-header-file.patch196
-rw-r--r--usb/usb-move-usb-storage-definitions-to-their-own-header-file.patch117
4 files changed, 1144 insertions, 1 deletions
diff --git a/series b/series
index dbee192e14a0b6..52419d9c68ce04 100644
--- a/series
+++ b/series
@@ -149,10 +149,12 @@ usb/usb-serial-enable-usb-autosuspend-by-default-on-qcserial.patch
usb/usb-ftdi_sio-revert-usb-ftdi_sio-fix-dtr-rts-line-modes.patch
usb/usb-cdc.h-ncm-fix-one-more-typo.patch
usb/usb-qcserial-enable-diagnostics-monitor-and-gps-ports-on-gobi-2000.patch
+usb/usb-move-usb-storage-definitions-to-their-own-header-file.patch
+usb/usb-add-uas-driver.patch
+usb/usb-gadget-file_storage-reuse-definitions-from-a-header-file.patch
# staging stuff for next is now in the staging-next tree on git.kernel.org
-
diff --git a/usb/usb-add-uas-driver.patch b/usb/usb-add-uas-driver.patch
new file mode 100644
index 00000000000000..978327b2463586
--- /dev/null
+++ b/usb/usb-add-uas-driver.patch
@@ -0,0 +1,828 @@
+From willy@linux.intel.com Tue Sep 28 18:53:35 2010
+From: Matthew Wilcox <willy@linux.intel.com>
+Date: Tue, 28 Sep 2010 06:14:56 -0400
+Subject: USB: Add UAS driver
+To: greg@kroah.com, linux-usb@vger.kernel.org, linux-scsi@vger.kernel.org, sarah.a.sharp@linux.intel.com
+Cc: Matthew Wilcox <matthew.r.wilcox@intel.com>, Matthew Wilcox <willy@linux.intel.com>
+Message-ID: <1285668896-6356-2-git-send-email-willy@linux.intel.com>
+
+
+From: Matthew Wilcox <matthew.r.wilcox@intel.com>
+
+USB Attached SCSI is a new protocol specified jointly by the SCSI T10
+committee and the USB Implementors Forum.
+
+Signed-off-by: Matthew Wilcox <willy@linux.intel.com>
+Cc: Matthew Dharm <mdharm-usb@one-eyed-alien.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ MAINTAINERS | 8
+ drivers/usb/storage/Kconfig | 13
+ drivers/usb/storage/Makefile | 1
+ drivers/usb/storage/uas.c | 751 +++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 773 insertions(+)
+
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -5898,6 +5898,14 @@ S: Maintained
+ F: Documentation/usb/acm.txt
+ F: drivers/usb/class/cdc-acm.*
+
++USB ATTACHED SCSI
++M: Matthew Wilcox <willy@linux.intel.com>
++M: Sarah Sharp <sarah.a.sharp@linux.intel.com>
++L: linux-usb@vger.kernel.org
++L: linux-scsi@vger.kernel.org
++S: Supported
++F: drivers/usb/storage/uas.c
++
+ USB BLOCK DRIVER (UB ub)
+ M: Pete Zaitcev <zaitcev@redhat.com>
+ L: linux-usb@vger.kernel.org
+--- a/drivers/usb/storage/Kconfig
++++ b/drivers/usb/storage/Kconfig
+@@ -172,6 +172,19 @@ config USB_STORAGE_CYPRESS_ATACB
+
+ If this driver is compiled as a module, it will be named ums-cypress.
+
++config USB_UAS
++ tristate "USB Attached SCSI"
++ depends on USB && SCSI
++ help
++ The USB Attached SCSI protocol is supported by some USB
++ storage devices. It permits higher performance by supporting
++ multiple outstanding commands.
++
++ If you don't know whether you have a UAS device, it is safe to
++ say 'Y' or 'M' here and the kernel will use the right driver.
++
++ If you compile this driver as a module, it will be named uas.
++
+ config USB_LIBUSUAL
+ bool "The shared table of common (or usual) storage devices"
+ depends on USB
+--- a/drivers/usb/storage/Makefile
++++ b/drivers/usb/storage/Makefile
+@@ -7,6 +7,7 @@
+
+ EXTRA_CFLAGS := -Idrivers/scsi
+
++obj-$(CONFIG_USB_UAS) += uas.o
+ obj-$(CONFIG_USB_STORAGE) += usb-storage.o
+
+ usb-storage-obj-$(CONFIG_USB_STORAGE_DEBUG) += debug.o
+--- /dev/null
++++ b/drivers/usb/storage/uas.c
+@@ -0,0 +1,751 @@
++/*
++ * USB Attached SCSI
++ * Note that this is not the same as the USB Mass Storage driver
++ *
++ * Copyright Matthew Wilcox for Intel Corp, 2010
++ * Copyright Sarah Sharp for Intel Corp, 2010
++ *
++ * Distributed under the terms of the GNU GPL, version two.
++ */
++
++#include <linux/blkdev.h>
++#include <linux/slab.h>
++#include <linux/types.h>
++#include <linux/usb.h>
++#include <linux/usb/storage.h>
++
++#include <scsi/scsi.h>
++#include <scsi/scsi_dbg.h>
++#include <scsi/scsi_cmnd.h>
++#include <scsi/scsi_device.h>
++#include <scsi/scsi_host.h>
++#include <scsi/scsi_tcq.h>
++
++/* Common header for all IUs */
++struct iu {
++ __u8 iu_id;
++ __u8 rsvd1;
++ __be16 tag;
++};
++
++enum {
++ IU_ID_COMMAND = 0x01,
++ IU_ID_STATUS = 0x03,
++ IU_ID_RESPONSE = 0x04,
++ IU_ID_TASK_MGMT = 0x05,
++ IU_ID_READ_READY = 0x06,
++ IU_ID_WRITE_READY = 0x07,
++};
++
++struct command_iu {
++ __u8 iu_id;
++ __u8 rsvd1;
++ __be16 tag;
++ __u8 prio_attr;
++ __u8 rsvd5;
++ __u8 len;
++ __u8 rsvd7;
++ struct scsi_lun lun;
++ __u8 cdb[16]; /* XXX: Overflow-checking tools may misunderstand */
++};
++
++struct sense_iu {
++ __u8 iu_id;
++ __u8 rsvd1;
++ __be16 tag;
++ __be16 status_qual;
++ __u8 status;
++ __u8 service_response;
++ __u8 rsvd8[6];
++ __be16 len;
++ __u8 sense[SCSI_SENSE_BUFFERSIZE];
++};
++
++/*
++ * The r00-r01c specs define this version of the SENSE IU data structure.
++ * It's still in use by several different firmware releases.
++ */
++struct sense_iu_old {
++ __u8 iu_id;
++ __u8 rsvd1;
++ __be16 tag;
++ __be16 len;
++ __u8 status;
++ __u8 service_response;
++ __u8 sense[SCSI_SENSE_BUFFERSIZE];
++};
++
++enum {
++ CMD_PIPE_ID = 1,
++ STATUS_PIPE_ID = 2,
++ DATA_IN_PIPE_ID = 3,
++ DATA_OUT_PIPE_ID = 4,
++
++ UAS_SIMPLE_TAG = 0,
++ UAS_HEAD_TAG = 1,
++ UAS_ORDERED_TAG = 2,
++ UAS_ACA = 4,
++};
++
++struct uas_dev_info {
++ struct usb_interface *intf;
++ struct usb_device *udev;
++ int qdepth;
++ unsigned cmd_pipe, status_pipe, data_in_pipe, data_out_pipe;
++ unsigned use_streams:1;
++ unsigned uas_sense_old:1;
++};
++
++enum {
++ ALLOC_SENSE_URB = (1 << 0),
++ SUBMIT_SENSE_URB = (1 << 1),
++ ALLOC_DATA_IN_URB = (1 << 2),
++ SUBMIT_DATA_IN_URB = (1 << 3),
++ ALLOC_DATA_OUT_URB = (1 << 4),
++ SUBMIT_DATA_OUT_URB = (1 << 5),
++ ALLOC_CMD_URB = (1 << 6),
++ SUBMIT_CMD_URB = (1 << 7),
++};
++
++/* Overrides scsi_pointer */
++struct uas_cmd_info {
++ unsigned int state;
++ unsigned int stream;
++ struct urb *cmd_urb;
++ struct urb *sense_urb;
++ struct urb *data_in_urb;
++ struct urb *data_out_urb;
++ struct list_head list;
++};
++
++/* I hate forward declarations, but I actually have a loop */
++static int uas_submit_urbs(struct scsi_cmnd *cmnd,
++ struct uas_dev_info *devinfo, gfp_t gfp);
++
++static DEFINE_SPINLOCK(uas_work_lock);
++static LIST_HEAD(uas_work_list);
++
++static void uas_do_work(struct work_struct *work)
++{
++ struct uas_cmd_info *cmdinfo;
++ struct list_head list;
++
++ spin_lock_irq(&uas_work_lock);
++ list_replace_init(&uas_work_list, &list);
++ spin_unlock_irq(&uas_work_lock);
++
++ list_for_each_entry(cmdinfo, &list, list) {
++ struct scsi_pointer *scp = (void *)cmdinfo;
++ struct scsi_cmnd *cmnd = container_of(scp,
++ struct scsi_cmnd, SCp);
++ uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_KERNEL);
++ }
++}
++
++static DECLARE_WORK(uas_work, uas_do_work);
++
++static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd)
++{
++ struct sense_iu *sense_iu = urb->transfer_buffer;
++ struct scsi_device *sdev = cmnd->device;
++
++ if (urb->actual_length > 16) {
++ unsigned len = be16_to_cpup(&sense_iu->len);
++ if (len + 16 != urb->actual_length) {
++ int newlen = min(len + 16, urb->actual_length) - 16;
++ if (newlen < 0)
++ newlen = 0;
++ sdev_printk(KERN_INFO, sdev, "%s: urb length %d "
++ "disagrees with IU sense data length %d, "
++ "using %d bytes of sense data\n", __func__,
++ urb->actual_length, len, newlen);
++ len = newlen;
++ }
++ memcpy(cmnd->sense_buffer, sense_iu->sense, len);
++ }
++
++ cmnd->result = sense_iu->status;
++ if (sdev->current_cmnd)
++ sdev->current_cmnd = NULL;
++ cmnd->scsi_done(cmnd);
++ usb_free_urb(urb);
++}
++
++static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd)
++{
++ struct sense_iu_old *sense_iu = urb->transfer_buffer;
++ struct scsi_device *sdev = cmnd->device;
++
++ if (urb->actual_length > 8) {
++ unsigned len = be16_to_cpup(&sense_iu->len) - 2;
++ if (len + 8 != urb->actual_length) {
++ int newlen = min(len + 8, urb->actual_length) - 8;
++ if (newlen < 0)
++ newlen = 0;
++ sdev_printk(KERN_INFO, sdev, "%s: urb length %d "
++ "disagrees with IU sense data length %d, "
++ "using %d bytes of sense data\n", __func__,
++ urb->actual_length, len, newlen);
++ len = newlen;
++ }
++ memcpy(cmnd->sense_buffer, sense_iu->sense, len);
++ }
++
++ cmnd->result = sense_iu->status;
++ if (sdev->current_cmnd)
++ sdev->current_cmnd = NULL;
++ cmnd->scsi_done(cmnd);
++ usb_free_urb(urb);
++}
++
++static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd,
++ unsigned direction)
++{
++ struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
++ int err;
++
++ cmdinfo->state = direction | SUBMIT_SENSE_URB;
++ err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_ATOMIC);
++ if (err) {
++ spin_lock(&uas_work_lock);
++ list_add_tail(&cmdinfo->list, &uas_work_list);
++ spin_unlock(&uas_work_lock);
++ schedule_work(&uas_work);
++ }
++}
++
++static void uas_stat_cmplt(struct urb *urb)
++{
++ struct iu *iu = urb->transfer_buffer;
++ struct scsi_device *sdev = urb->context;
++ struct uas_dev_info *devinfo = sdev->hostdata;
++ struct scsi_cmnd *cmnd;
++ u16 tag;
++
++ if (urb->status) {
++ dev_err(&urb->dev->dev, "URB BAD STATUS %d\n", urb->status);
++ usb_free_urb(urb);
++ return;
++ }
++
++ tag = be16_to_cpup(&iu->tag) - 1;
++ if (sdev->current_cmnd)
++ cmnd = sdev->current_cmnd;
++ else
++ cmnd = scsi_find_tag(sdev, tag);
++ if (!cmnd)
++ return;
++
++ switch (iu->iu_id) {
++ case IU_ID_STATUS:
++ if (urb->actual_length < 16)
++ devinfo->uas_sense_old = 1;
++ if (devinfo->uas_sense_old)
++ uas_sense_old(urb, cmnd);
++ else
++ uas_sense(urb, cmnd);
++ break;
++ case IU_ID_READ_READY:
++ uas_xfer_data(urb, cmnd, SUBMIT_DATA_IN_URB);
++ break;
++ case IU_ID_WRITE_READY:
++ uas_xfer_data(urb, cmnd, SUBMIT_DATA_OUT_URB);
++ break;
++ default:
++ scmd_printk(KERN_ERR, cmnd,
++ "Bogus IU (%d) received on status pipe\n", iu->iu_id);
++ }
++}
++
++static void uas_data_cmplt(struct urb *urb)
++{
++ struct scsi_data_buffer *sdb = urb->context;
++ sdb->resid = sdb->length - urb->actual_length;
++ usb_free_urb(urb);
++}
++
++static struct urb *uas_alloc_data_urb(struct uas_dev_info *devinfo, gfp_t gfp,
++ unsigned int pipe, u16 stream_id,
++ struct scsi_data_buffer *sdb,
++ enum dma_data_direction dir)
++{
++ struct usb_device *udev = devinfo->udev;
++ struct urb *urb = usb_alloc_urb(0, gfp);
++
++ if (!urb)
++ goto out;
++ usb_fill_bulk_urb(urb, udev, pipe, NULL, sdb->length, uas_data_cmplt,
++ sdb);
++ if (devinfo->use_streams)
++ urb->stream_id = stream_id;
++ urb->num_sgs = udev->bus->sg_tablesize ? sdb->table.nents : 0;
++ urb->sg = sdb->table.sgl;
++ out:
++ return urb;
++}
++
++static struct urb *uas_alloc_sense_urb(struct uas_dev_info *devinfo, gfp_t gfp,
++ struct scsi_cmnd *cmnd, u16 stream_id)
++{
++ struct usb_device *udev = devinfo->udev;
++ struct urb *urb = usb_alloc_urb(0, gfp);
++ struct sense_iu *iu;
++
++ if (!urb)
++ goto out;
++
++ iu = kmalloc(sizeof(*iu), gfp);
++ if (!iu)
++ goto free;
++
++ usb_fill_bulk_urb(urb, udev, devinfo->status_pipe, iu, sizeof(*iu),
++ uas_stat_cmplt, cmnd->device);
++ urb->stream_id = stream_id;
++ urb->transfer_flags |= URB_FREE_BUFFER;
++ out:
++ return urb;
++ free:
++ usb_free_urb(urb);
++ return NULL;
++}
++
++static struct urb *uas_alloc_cmd_urb(struct uas_dev_info *devinfo, gfp_t gfp,
++ struct scsi_cmnd *cmnd, u16 stream_id)
++{
++ struct usb_device *udev = devinfo->udev;
++ struct scsi_device *sdev = cmnd->device;
++ struct urb *urb = usb_alloc_urb(0, gfp);
++ struct command_iu *iu;
++ int len;
++
++ if (!urb)
++ goto out;
++
++ len = cmnd->cmd_len - 16;
++ if (len < 0)
++ len = 0;
++ len = ALIGN(len, 4);
++ iu = kmalloc(sizeof(*iu) + len, gfp);
++ if (!iu)
++ goto free;
++
++ iu->iu_id = IU_ID_COMMAND;
++ iu->tag = cpu_to_be16(stream_id);
++ if (sdev->ordered_tags && (cmnd->request->cmd_flags & REQ_HARDBARRIER))
++ iu->prio_attr = UAS_ORDERED_TAG;
++ else
++ iu->prio_attr = UAS_SIMPLE_TAG;
++ iu->len = len;
++ int_to_scsilun(sdev->lun, &iu->lun);
++ memcpy(iu->cdb, cmnd->cmnd, cmnd->cmd_len);
++
++ usb_fill_bulk_urb(urb, udev, devinfo->cmd_pipe, iu, sizeof(*iu) + len,
++ usb_free_urb, NULL);
++ urb->transfer_flags |= URB_FREE_BUFFER;
++ out:
++ return urb;
++ free:
++ usb_free_urb(urb);
++ return NULL;
++}
++
++/*
++ * Why should I request the Status IU before sending the Command IU? Spec
++ * says to, but also says the device may receive them in any order. Seems
++ * daft to me.
++ */
++
++static int uas_submit_urbs(struct scsi_cmnd *cmnd,
++ struct uas_dev_info *devinfo, gfp_t gfp)
++{
++ struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
++
++ if (cmdinfo->state & ALLOC_SENSE_URB) {
++ cmdinfo->sense_urb = uas_alloc_sense_urb(devinfo, gfp, cmnd,
++ cmdinfo->stream);
++ if (!cmdinfo->sense_urb)
++ return SCSI_MLQUEUE_DEVICE_BUSY;
++ cmdinfo->state &= ~ALLOC_SENSE_URB;
++ }
++
++ if (cmdinfo->state & SUBMIT_SENSE_URB) {
++ if (usb_submit_urb(cmdinfo->sense_urb, gfp)) {
++ scmd_printk(KERN_INFO, cmnd,
++ "sense urb submission failure\n");
++ return SCSI_MLQUEUE_DEVICE_BUSY;
++ }
++ cmdinfo->state &= ~SUBMIT_SENSE_URB;
++ }
++
++ if (cmdinfo->state & ALLOC_DATA_IN_URB) {
++ cmdinfo->data_in_urb = uas_alloc_data_urb(devinfo, gfp,
++ devinfo->data_in_pipe, cmdinfo->stream,
++ scsi_in(cmnd), DMA_FROM_DEVICE);
++ if (!cmdinfo->data_in_urb)
++ return SCSI_MLQUEUE_DEVICE_BUSY;
++ cmdinfo->state &= ~ALLOC_DATA_IN_URB;
++ }
++
++ if (cmdinfo->state & SUBMIT_DATA_IN_URB) {
++ if (usb_submit_urb(cmdinfo->data_in_urb, gfp)) {
++ scmd_printk(KERN_INFO, cmnd,
++ "data in urb submission failure\n");
++ return SCSI_MLQUEUE_DEVICE_BUSY;
++ }
++ cmdinfo->state &= ~SUBMIT_DATA_IN_URB;
++ }
++
++ if (cmdinfo->state & ALLOC_DATA_OUT_URB) {
++ cmdinfo->data_out_urb = uas_alloc_data_urb(devinfo, gfp,
++ devinfo->data_out_pipe, cmdinfo->stream,
++ scsi_out(cmnd), DMA_TO_DEVICE);
++ if (!cmdinfo->data_out_urb)
++ return SCSI_MLQUEUE_DEVICE_BUSY;
++ cmdinfo->state &= ~ALLOC_DATA_OUT_URB;
++ }
++
++ if (cmdinfo->state & SUBMIT_DATA_OUT_URB) {
++ if (usb_submit_urb(cmdinfo->data_out_urb, gfp)) {
++ scmd_printk(KERN_INFO, cmnd,
++ "data out urb submission failure\n");
++ return SCSI_MLQUEUE_DEVICE_BUSY;
++ }
++ cmdinfo->state &= ~SUBMIT_DATA_OUT_URB;
++ }
++
++ if (cmdinfo->state & ALLOC_CMD_URB) {
++ cmdinfo->cmd_urb = uas_alloc_cmd_urb(devinfo, gfp, cmnd,
++ cmdinfo->stream);
++ if (!cmdinfo->cmd_urb)
++ return SCSI_MLQUEUE_DEVICE_BUSY;
++ cmdinfo->state &= ~ALLOC_CMD_URB;
++ }
++
++ if (cmdinfo->state & SUBMIT_CMD_URB) {
++ if (usb_submit_urb(cmdinfo->cmd_urb, gfp)) {
++ scmd_printk(KERN_INFO, cmnd,
++ "cmd urb submission failure\n");
++ return SCSI_MLQUEUE_DEVICE_BUSY;
++ }
++ cmdinfo->state &= ~SUBMIT_CMD_URB;
++ }
++
++ return 0;
++}
++
++static int uas_queuecommand(struct scsi_cmnd *cmnd,
++ void (*done)(struct scsi_cmnd *))
++{
++ struct scsi_device *sdev = cmnd->device;
++ struct uas_dev_info *devinfo = sdev->hostdata;
++ struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
++ int err;
++
++ BUILD_BUG_ON(sizeof(struct uas_cmd_info) > sizeof(struct scsi_pointer));
++
++ if (!cmdinfo->sense_urb && sdev->current_cmnd)
++ return SCSI_MLQUEUE_DEVICE_BUSY;
++
++ if (blk_rq_tagged(cmnd->request)) {
++ cmdinfo->stream = cmnd->request->tag + 1;
++ } else {
++ sdev->current_cmnd = cmnd;
++ cmdinfo->stream = 1;
++ }
++
++ cmnd->scsi_done = done;
++
++ cmdinfo->state = ALLOC_SENSE_URB | SUBMIT_SENSE_URB |
++ ALLOC_CMD_URB | SUBMIT_CMD_URB;
++
++ switch (cmnd->sc_data_direction) {
++ case DMA_FROM_DEVICE:
++ cmdinfo->state |= ALLOC_DATA_IN_URB | SUBMIT_DATA_IN_URB;
++ break;
++ case DMA_BIDIRECTIONAL:
++ cmdinfo->state |= ALLOC_DATA_IN_URB | SUBMIT_DATA_IN_URB;
++ case DMA_TO_DEVICE:
++ cmdinfo->state |= ALLOC_DATA_OUT_URB | SUBMIT_DATA_OUT_URB;
++ case DMA_NONE:
++ break;
++ }
++
++ if (!devinfo->use_streams) {
++ cmdinfo->state &= ~(SUBMIT_DATA_IN_URB | SUBMIT_DATA_OUT_URB);
++ cmdinfo->stream = 0;
++ }
++
++ err = uas_submit_urbs(cmnd, devinfo, GFP_ATOMIC);
++ if (err) {
++ /* If we did nothing, give up now */
++ if (cmdinfo->state & SUBMIT_SENSE_URB) {
++ usb_free_urb(cmdinfo->sense_urb);
++ return SCSI_MLQUEUE_DEVICE_BUSY;
++ }
++ spin_lock(&uas_work_lock);
++ list_add_tail(&cmdinfo->list, &uas_work_list);
++ spin_unlock(&uas_work_lock);
++ schedule_work(&uas_work);
++ }
++
++ return 0;
++}
++
++static int uas_eh_abort_handler(struct scsi_cmnd *cmnd)
++{
++ struct scsi_device *sdev = cmnd->device;
++ sdev_printk(KERN_INFO, sdev, "%s tag %d\n", __func__,
++ cmnd->request->tag);
++
++/* XXX: Send ABORT TASK Task Management command */
++ return FAILED;
++}
++
++static int uas_eh_device_reset_handler(struct scsi_cmnd *cmnd)
++{
++ struct scsi_device *sdev = cmnd->device;
++ sdev_printk(KERN_INFO, sdev, "%s tag %d\n", __func__,
++ cmnd->request->tag);
++
++/* XXX: Send LOGICAL UNIT RESET Task Management command */
++ return FAILED;
++}
++
++static int uas_eh_target_reset_handler(struct scsi_cmnd *cmnd)
++{
++ struct scsi_device *sdev = cmnd->device;
++ sdev_printk(KERN_INFO, sdev, "%s tag %d\n", __func__,
++ cmnd->request->tag);
++
++/* XXX: Can we reset just the one USB interface?
++ * Would calling usb_set_interface() have the right effect?
++ */
++ return FAILED;
++}
++
++static int uas_eh_bus_reset_handler(struct scsi_cmnd *cmnd)
++{
++ struct scsi_device *sdev = cmnd->device;
++ struct uas_dev_info *devinfo = sdev->hostdata;
++ struct usb_device *udev = devinfo->udev;
++
++ sdev_printk(KERN_INFO, sdev, "%s tag %d\n", __func__,
++ cmnd->request->tag);
++
++ if (usb_reset_device(udev))
++ return SUCCESS;
++
++ return FAILED;
++}
++
++static int uas_slave_alloc(struct scsi_device *sdev)
++{
++ sdev->hostdata = (void *)sdev->host->hostdata[0];
++ return 0;
++}
++
++static int uas_slave_configure(struct scsi_device *sdev)
++{
++ struct uas_dev_info *devinfo = sdev->hostdata;
++ scsi_set_tag_type(sdev, MSG_ORDERED_TAG);
++ scsi_activate_tcq(sdev, devinfo->qdepth - 1);
++ return 0;
++}
++
++static struct scsi_host_template uas_host_template = {
++ .module = THIS_MODULE,
++ .name = "uas",
++ .queuecommand = uas_queuecommand,
++ .slave_alloc = uas_slave_alloc,
++ .slave_configure = uas_slave_configure,
++ .eh_abort_handler = uas_eh_abort_handler,
++ .eh_device_reset_handler = uas_eh_device_reset_handler,
++ .eh_target_reset_handler = uas_eh_target_reset_handler,
++ .eh_bus_reset_handler = uas_eh_bus_reset_handler,
++ .can_queue = 65536, /* Is there a limit on the _host_ ? */
++ .this_id = -1,
++ .sg_tablesize = SG_NONE,
++ .cmd_per_lun = 1, /* until we override it */
++ .skip_settle_delay = 1,
++ .ordered_tag = 1,
++};
++
++static struct usb_device_id uas_usb_ids[] = {
++ { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_BULK) },
++ { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_UAS) },
++ /* 0xaa is a prototype device I happen to have access to */
++ { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, 0xaa) },
++ { }
++};
++MODULE_DEVICE_TABLE(usb, uas_usb_ids);
++
++static void uas_configure_endpoints(struct uas_dev_info *devinfo)
++{
++ struct usb_host_endpoint *eps[4] = { };
++ struct usb_interface *intf = devinfo->intf;
++ struct usb_device *udev = devinfo->udev;
++ struct usb_host_endpoint *endpoint = intf->cur_altsetting->endpoint;
++ unsigned i, n_endpoints = intf->cur_altsetting->desc.bNumEndpoints;
++
++ devinfo->uas_sense_old = 0;
++
++ for (i = 0; i < n_endpoints; i++) {
++ unsigned char *extra = endpoint[i].extra;
++ int len = endpoint[i].extralen;
++ while (len > 1) {
++ if (extra[1] == USB_DT_PIPE_USAGE) {
++ unsigned pipe_id = extra[2];
++ if (pipe_id > 0 && pipe_id < 5)
++ eps[pipe_id - 1] = &endpoint[i];
++ break;
++ }
++ len -= extra[0];
++ extra += extra[0];
++ }
++ }
++
++ /*
++ * Assume that if we didn't find a control pipe descriptor, we're
++ * using a device with old firmware that happens to be set up like
++ * this.
++ */
++ if (!eps[0]) {
++ devinfo->cmd_pipe = usb_sndbulkpipe(udev, 1);
++ devinfo->status_pipe = usb_rcvbulkpipe(udev, 1);
++ devinfo->data_in_pipe = usb_rcvbulkpipe(udev, 2);
++ devinfo->data_out_pipe = usb_sndbulkpipe(udev, 2);
++
++ eps[1] = usb_pipe_endpoint(udev, devinfo->status_pipe);
++ eps[2] = usb_pipe_endpoint(udev, devinfo->data_in_pipe);
++ eps[3] = usb_pipe_endpoint(udev, devinfo->data_out_pipe);
++ } else {
++ devinfo->cmd_pipe = usb_sndbulkpipe(udev,
++ eps[0]->desc.bEndpointAddress);
++ devinfo->status_pipe = usb_rcvbulkpipe(udev,
++ eps[1]->desc.bEndpointAddress);
++ devinfo->data_in_pipe = usb_rcvbulkpipe(udev,
++ eps[2]->desc.bEndpointAddress);
++ devinfo->data_out_pipe = usb_sndbulkpipe(udev,
++ eps[3]->desc.bEndpointAddress);
++ }
++
++ devinfo->qdepth = usb_alloc_streams(devinfo->intf, eps + 1, 3, 256,
++ GFP_KERNEL);
++ if (devinfo->qdepth < 0) {
++ devinfo->qdepth = 256;
++ devinfo->use_streams = 0;
++ } else {
++ devinfo->use_streams = 1;
++ }
++}
++
++/*
++ * XXX: What I'd like to do here is register a SCSI host for each USB host in
++ * the system. Follow usb-storage's design of registering a SCSI host for
++ * each USB device for the moment. Can implement this by walking up the
++ * USB hierarchy until we find a USB host.
++ */
++static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id)
++{
++ int result;
++ struct Scsi_Host *shost;
++ struct uas_dev_info *devinfo;
++ struct usb_device *udev = interface_to_usbdev(intf);
++
++ if (id->bInterfaceProtocol == 0x50) {
++ int ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
++/* XXX: Shouldn't assume that 1 is the alternative we want */
++ int ret = usb_set_interface(udev, ifnum, 1);
++ if (ret)
++ return -ENODEV;
++ }
++
++ devinfo = kmalloc(sizeof(struct uas_dev_info), GFP_KERNEL);
++ if (!devinfo)
++ return -ENOMEM;
++
++ result = -ENOMEM;
++ shost = scsi_host_alloc(&uas_host_template, sizeof(void *));
++ if (!shost)
++ goto free;
++
++ shost->max_cmd_len = 16 + 252;
++ shost->max_id = 1;
++ shost->sg_tablesize = udev->bus->sg_tablesize;
++
++ result = scsi_add_host(shost, &intf->dev);
++ if (result)
++ goto free;
++ shost->hostdata[0] = (unsigned long)devinfo;
++
++ devinfo->intf = intf;
++ devinfo->udev = udev;
++ uas_configure_endpoints(devinfo);
++
++ scsi_scan_host(shost);
++ usb_set_intfdata(intf, shost);
++ return result;
++ free:
++ kfree(devinfo);
++ if (shost)
++ scsi_host_put(shost);
++ return result;
++}
++
++static int uas_pre_reset(struct usb_interface *intf)
++{
++/* XXX: Need to return 1 if it's not our device in error handling */
++ return 0;
++}
++
++static int uas_post_reset(struct usb_interface *intf)
++{
++/* XXX: Need to return 1 if it's not our device in error handling */
++ return 0;
++}
++
++static void uas_disconnect(struct usb_interface *intf)
++{
++ struct usb_device *udev = interface_to_usbdev(intf);
++ struct usb_host_endpoint *eps[3];
++ struct Scsi_Host *shost = usb_get_intfdata(intf);
++ struct uas_dev_info *devinfo = (void *)shost->hostdata[0];
++
++ scsi_remove_host(shost);
++
++ eps[0] = usb_pipe_endpoint(udev, devinfo->status_pipe);
++ eps[1] = usb_pipe_endpoint(udev, devinfo->data_in_pipe);
++ eps[2] = usb_pipe_endpoint(udev, devinfo->data_out_pipe);
++ usb_free_streams(intf, eps, 3, GFP_KERNEL);
++
++ kfree(devinfo);
++}
++
++/*
++ * XXX: Should this plug into libusual so we can auto-upgrade devices from
++ * Bulk-Only to UAS?
++ */
++static struct usb_driver uas_driver = {
++ .name = "uas",
++ .probe = uas_probe,
++ .disconnect = uas_disconnect,
++ .pre_reset = uas_pre_reset,
++ .post_reset = uas_post_reset,
++ .id_table = uas_usb_ids,
++};
++
++static int uas_init(void)
++{
++ return usb_register(&uas_driver);
++}
++
++static void uas_exit(void)
++{
++ usb_deregister(&uas_driver);
++}
++
++module_init(uas_init);
++module_exit(uas_exit);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Matthew Wilcox and Sarah Sharp");
diff --git a/usb/usb-gadget-file_storage-reuse-definitions-from-a-header-file.patch b/usb/usb-gadget-file_storage-reuse-definitions-from-a-header-file.patch
new file mode 100644
index 00000000000000..641ffb338f96d5
--- /dev/null
+++ b/usb/usb-gadget-file_storage-reuse-definitions-from-a-header-file.patch
@@ -0,0 +1,196 @@
+From m.nazarewicz@samsung.com Tue Sep 28 18:56:38 2010
+From: Michal Nazarewicz <m.nazarewicz@samsung.com>
+Date: Tue, 28 Sep 2010 12:55:32 +0200
+Subject: USB: gadget: file_storage: reuse definitions from a header file
+To: Matthew Wilcox <willy@linux.intel.com>, greg@kroah.com
+Cc: sarah.a.sharp@linux.intel.com, Michal Nazarewicz <mina86@mina86.com>, Alan Stern <stern@rowland.harvard.edu>
+Message-ID: <5d4c116b32f9e6c45bb09eb6f28d5ef2e1b26c1f.1285670575.git.mina86@mina86.com>
+
+
+From: Michal Nazarewicz <mina86@mina86.com>
+
+This commit changes storage_common.c and file_storage.c to
+reuse definitions from linux/usb/storage.h header file.
+
+Signed-off-by: Michal Nazarewicz <mina86@mina86.com>
+Cc: Alan Stern <stern@rowland.harvard.edu>
+Cc: Matthew Wilcox <willy@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/file_storage.c | 50 ++++++++++++++++++------------------
+ drivers/usb/gadget/storage_common.c | 18 ++----------
+ 2 files changed, 28 insertions(+), 40 deletions(-)
+
+--- a/drivers/usb/gadget/file_storage.c
++++ b/drivers/usb/gadget/file_storage.c
+@@ -400,9 +400,9 @@ MODULE_PARM_DESC(buflen, "I/O buffer siz
+
+ #ifdef CONFIG_USB_FILE_STORAGE_TEST
+
+-#define transport_is_bbb() (mod_data.transport_type == USB_PR_BULK)
+-#define transport_is_cbi() (mod_data.transport_type == USB_PR_CBI)
+-#define protocol_is_scsi() (mod_data.protocol_type == USB_SC_SCSI)
++#define transport_is_bbb() (mod_data.transport_type == US_PR_BULK)
++#define transport_is_cbi() (mod_data.transport_type == US_PR_CBI)
++#define protocol_is_scsi() (mod_data.protocol_type == US_SC_SCSI)
+
+ #else
+
+@@ -2183,18 +2183,18 @@ static int send_status(struct fsg_dev *f
+ start_transfer(fsg, fsg->bulk_in, bh->inreq,
+ &bh->inreq_busy, &bh->state);
+
+- } else if (mod_data.transport_type == USB_PR_CB) {
++ } else if (mod_data.transport_type == US_PR_CB) {
+
+ /* Control-Bulk transport has no status phase! */
+ return 0;
+
+- } else { // USB_PR_CBI
++ } else { // US_PR_CBI
+ struct interrupt_data *buf = bh->buf;
+
+ /* Store and send the Interrupt data. UFI sends the ASC
+ * and ASCQ bytes. Everything else sends a Type (which
+ * is always 0) and the status Value. */
+- if (mod_data.protocol_type == USB_SC_UFI) {
++ if (mod_data.protocol_type == US_SC_UFI) {
+ buf->bType = ASC(sd);
+ buf->bValue = ASCQ(sd);
+ } else {
+@@ -2236,7 +2236,7 @@ static int check_command(struct fsg_dev
+
+ /* There's some disagreement as to whether RBC pads commands or not.
+ * We'll play it safe and accept either form. */
+- else if (mod_data.protocol_type == USB_SC_RBC) {
++ else if (mod_data.protocol_type == US_SC_RBC) {
+ if (fsg->cmnd_size == 12)
+ cmnd_size = 12;
+
+@@ -2707,7 +2707,7 @@ static int get_next_command(struct fsg_d
+ rc = received_cbw(fsg, bh);
+ bh->state = BUF_STATE_EMPTY;
+
+- } else { // USB_PR_CB or USB_PR_CBI
++ } else { // US_PR_CB or US_PR_CBI
+
+ /* Wait for the next command to arrive */
+ while (fsg->cbbuf_cmnd_size == 0) {
+@@ -3213,9 +3213,9 @@ static int __init check_parameters(struc
+ int gcnum;
+
+ /* Store the default values */
+- mod_data.transport_type = USB_PR_BULK;
++ mod_data.transport_type = US_PR_BULK;
+ mod_data.transport_name = "Bulk-only";
+- mod_data.protocol_type = USB_SC_SCSI;
++ mod_data.protocol_type = US_SC_SCSI;
+ mod_data.protocol_name = "Transparent SCSI";
+
+ /* Some peripheral controllers are known not to be able to
+@@ -3242,10 +3242,10 @@ static int __init check_parameters(struc
+ if (strnicmp(mod_data.transport_parm, "BBB", 10) == 0) {
+ ; // Use default setting
+ } else if (strnicmp(mod_data.transport_parm, "CB", 10) == 0) {
+- mod_data.transport_type = USB_PR_CB;
++ mod_data.transport_type = US_PR_CB;
+ mod_data.transport_name = "Control-Bulk";
+ } else if (strnicmp(mod_data.transport_parm, "CBI", 10) == 0) {
+- mod_data.transport_type = USB_PR_CBI;
++ mod_data.transport_type = US_PR_CBI;
+ mod_data.transport_name = "Control-Bulk-Interrupt";
+ } else {
+ ERROR(fsg, "invalid transport: %s\n", mod_data.transport_parm);
+@@ -3253,28 +3253,28 @@ static int __init check_parameters(struc
+ }
+
+ if (strnicmp(mod_data.protocol_parm, "SCSI", 10) == 0 ||
+- prot == USB_SC_SCSI) {
++ prot == US_SC_SCSI) {
+ ; // Use default setting
+ } else if (strnicmp(mod_data.protocol_parm, "RBC", 10) == 0 ||
+- prot == USB_SC_RBC) {
+- mod_data.protocol_type = USB_SC_RBC;
++ prot == US_SC_RBC) {
++ mod_data.protocol_type = US_SC_RBC;
+ mod_data.protocol_name = "RBC";
+ } else if (strnicmp(mod_data.protocol_parm, "8020", 4) == 0 ||
+ strnicmp(mod_data.protocol_parm, "ATAPI", 10) == 0 ||
+- prot == USB_SC_8020) {
+- mod_data.protocol_type = USB_SC_8020;
++ prot == US_SC_8020) {
++ mod_data.protocol_type = US_SC_8020;
+ mod_data.protocol_name = "8020i (ATAPI)";
+ } else if (strnicmp(mod_data.protocol_parm, "QIC", 3) == 0 ||
+- prot == USB_SC_QIC) {
+- mod_data.protocol_type = USB_SC_QIC;
++ prot == US_SC_QIC) {
++ mod_data.protocol_type = US_SC_QIC;
+ mod_data.protocol_name = "QIC-157";
+ } else if (strnicmp(mod_data.protocol_parm, "UFI", 10) == 0 ||
+- prot == USB_SC_UFI) {
+- mod_data.protocol_type = USB_SC_UFI;
++ prot == US_SC_UFI) {
++ mod_data.protocol_type = US_SC_UFI;
+ mod_data.protocol_name = "UFI";
+ } else if (strnicmp(mod_data.protocol_parm, "8070", 4) == 0 ||
+- prot == USB_SC_8070) {
+- mod_data.protocol_type = USB_SC_8070;
++ prot == US_SC_8070) {
++ mod_data.protocol_type = US_SC_8070;
+ mod_data.protocol_name = "8070i";
+ } else {
+ ERROR(fsg, "invalid protocol: %s\n", mod_data.protocol_parm);
+@@ -3312,8 +3312,8 @@ static int __init check_parameters(struc
+ }
+ }
+ if (len > 126 ||
+- (mod_data.transport_type == USB_PR_BULK && len < 12) ||
+- (mod_data.transport_type != USB_PR_BULK && len > 12)) {
++ (mod_data.transport_type == US_PR_BULK && len < 12) ||
++ (mod_data.transport_type != US_PR_BULK && len > 12)) {
+ WARNING(fsg, "Invalid serial string length!\n");
+ goto no_serial;
+ }
+--- a/drivers/usb/gadget/storage_common.c
++++ b/drivers/usb/gadget/storage_common.c
+@@ -54,6 +54,7 @@
+
+
+ #include <asm/unaligned.h>
++#include <linux/usb/storage.h>
+
+
+ /*
+@@ -156,19 +157,6 @@
+ #define TYPE_DISK 0x00
+ #define TYPE_CDROM 0x05
+
+-/* USB protocol value = the transport method */
+-#define USB_PR_CBI 0x00 /* Control/Bulk/Interrupt */
+-#define USB_PR_CB 0x01 /* Control/Bulk w/o interrupt */
+-#define USB_PR_BULK 0x50 /* Bulk-only */
+-
+-/* USB subclass value = the protocol encapsulation */
+-#define USB_SC_RBC 0x01 /* Reduced Block Commands (flash) */
+-#define USB_SC_8020 0x02 /* SFF-8020i, MMC-2, ATAPI (CD-ROM) */
+-#define USB_SC_QIC 0x03 /* QIC-157 (tape) */
+-#define USB_SC_UFI 0x04 /* UFI (floppy) */
+-#define USB_SC_8070 0x05 /* SFF-8070i (removable) */
+-#define USB_SC_SCSI 0x06 /* Transparent SCSI */
+-
+ /* Bulk-only data structures */
+
+ /* Command Block Wrapper */
+@@ -407,8 +395,8 @@ fsg_intf_desc = {
+
+ .bNumEndpoints = 2, /* Adjusted during fsg_bind() */
+ .bInterfaceClass = USB_CLASS_MASS_STORAGE,
+- .bInterfaceSubClass = USB_SC_SCSI, /* Adjusted during fsg_bind() */
+- .bInterfaceProtocol = USB_PR_BULK, /* Adjusted during fsg_bind() */
++ .bInterfaceSubClass = US_SC_SCSI, /* Adjusted during fsg_bind() */
++ .bInterfaceProtocol = US_PR_BULK, /* Adjusted during fsg_bind() */
+ .iInterface = FSG_STRING_INTERFACE,
+ };
+
diff --git a/usb/usb-move-usb-storage-definitions-to-their-own-header-file.patch b/usb/usb-move-usb-storage-definitions-to-their-own-header-file.patch
new file mode 100644
index 00000000000000..bb861ffaa4bd69
--- /dev/null
+++ b/usb/usb-move-usb-storage-definitions-to-their-own-header-file.patch
@@ -0,0 +1,117 @@
+From willy@linux.intel.com Tue Sep 28 18:52:20 2010
+From: Matthew Wilcox <willy@linux.intel.com>
+Date: Tue, 28 Sep 2010 06:14:55 -0400
+Subject: USB: Move USB Storage definitions to their own header file
+To: greg@kroah.com, linux-usb@vger.kernel.org, linux-scsi@vger.kernel.org, sarah.a.sharp@linux.intel.com
+Cc: Matthew Wilcox <matthew.r.wilcox@intel.com>, Matthew Wilcox <willy@linux.intel.com>
+Message-ID: <1285668896-6356-1-git-send-email-willy@linux.intel.com>
+
+
+From: Matthew Wilcox <matthew.r.wilcox@intel.com>
+
+The libusual header file is hard to use from code that isn't part
+of libusual. As the comment suggests, these definitions are moved to
+their own header file, paralleling other USB classes.
+
+Signed-off-by: Matthew Wilcox <willy@linux.intel.com>
+Cc: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/linux/usb/storage.h | 44 ++++++++++++++++++++++++++++++++++++++++++++
+ include/linux/usb_usual.h | 37 +------------------------------------
+ 2 files changed, 45 insertions(+), 36 deletions(-)
+
+--- /dev/null
++++ b/include/linux/usb/storage.h
+@@ -0,0 +1,44 @@
++/*
++ * linux/usb/storage.h
++ *
++ * Copyright Matthew Wilcox for Intel Corp, 2010
++ *
++ * This file contains definitions taken from the
++ * USB Mass Storage Class Specification Overview
++ *
++ * Distributed under the terms of the GNU GPL, version two.
++ */
++
++/* Storage subclass codes */
++
++#define US_SC_RBC 0x01 /* Typically, flash devices */
++#define US_SC_8020 0x02 /* CD-ROM */
++#define US_SC_QIC 0x03 /* QIC-157 Tapes */
++#define US_SC_UFI 0x04 /* Floppy */
++#define US_SC_8070 0x05 /* Removable media */
++#define US_SC_SCSI 0x06 /* Transparent */
++#define US_SC_LOCKABLE 0x07 /* Password-protected */
++
++#define US_SC_ISD200 0xf0 /* ISD200 ATA */
++#define US_SC_CYP_ATACB 0xf1 /* Cypress ATACB */
++#define US_SC_DEVICE 0xff /* Use device's value */
++
++/* Storage protocol codes */
++
++#define US_PR_CBI 0x00 /* Control/Bulk/Interrupt */
++#define US_PR_CB 0x01 /* Control/Bulk w/o interrupt */
++#define US_PR_BULK 0x50 /* bulk only */
++#define US_PR_UAS 0x62 /* USB Attached SCSI */
++
++#define US_PR_USBAT 0x80 /* SCM-ATAPI bridge */
++#define US_PR_EUSB_SDDR09 0x81 /* SCM-SCSI bridge for SDDR-09 */
++#define US_PR_SDDR55 0x82 /* SDDR-55 (made up) */
++#define US_PR_DPCM_USB 0xf0 /* Combination CB/SDDR09 */
++#define US_PR_FREECOM 0xf1 /* Freecom */
++#define US_PR_DATAFAB 0xf2 /* Datafab chipsets */
++#define US_PR_JUMPSHOT 0xf3 /* Lexar Jumpshot */
++#define US_PR_ALAUDA 0xf4 /* Alauda chipsets */
++#define US_PR_KARMA 0xf5 /* Rio Karma */
++
++#define US_PR_DEVICE 0xff /* Use device's value */
++
+--- a/include/linux/usb_usual.h
++++ b/include/linux/usb_usual.h
+@@ -74,42 +74,7 @@ enum { US_DO_ALL_FLAGS };
+ #define USB_US_TYPE(flags) (((flags) >> 24) & 0xFF)
+ #define USB_US_ORIG_FLAGS(flags) ((flags) & 0x00FFFFFF)
+
+-/*
+- * This is probably not the best place to keep these constants, conceptually.
+- * But it's the only header included into all places which need them.
+- */
+-
+-/* Sub Classes */
+-
+-#define US_SC_RBC 0x01 /* Typically, flash devices */
+-#define US_SC_8020 0x02 /* CD-ROM */
+-#define US_SC_QIC 0x03 /* QIC-157 Tapes */
+-#define US_SC_UFI 0x04 /* Floppy */
+-#define US_SC_8070 0x05 /* Removable media */
+-#define US_SC_SCSI 0x06 /* Transparent */
+-#define US_SC_LOCKABLE 0x07 /* Password-protected */
+-
+-#define US_SC_ISD200 0xf0 /* ISD200 ATA */
+-#define US_SC_CYP_ATACB 0xf1 /* Cypress ATACB */
+-#define US_SC_DEVICE 0xff /* Use device's value */
+-
+-/* Protocols */
+-
+-#define US_PR_CBI 0x00 /* Control/Bulk/Interrupt */
+-#define US_PR_CB 0x01 /* Control/Bulk w/o interrupt */
+-#define US_PR_BULK 0x50 /* bulk only */
+-
+-#define US_PR_USBAT 0x80 /* SCM-ATAPI bridge */
+-#define US_PR_EUSB_SDDR09 0x81 /* SCM-SCSI bridge for SDDR-09 */
+-#define US_PR_SDDR55 0x82 /* SDDR-55 (made up) */
+-#define US_PR_DPCM_USB 0xf0 /* Combination CB/SDDR09 */
+-#define US_PR_FREECOM 0xf1 /* Freecom */
+-#define US_PR_DATAFAB 0xf2 /* Datafab chipsets */
+-#define US_PR_JUMPSHOT 0xf3 /* Lexar Jumpshot */
+-#define US_PR_ALAUDA 0xf4 /* Alauda chipsets */
+-#define US_PR_KARMA 0xf5 /* Rio Karma */
+-
+-#define US_PR_DEVICE 0xff /* Use device's value */
++#include <linux/usb/storage.h>
+
+ /*
+ */