usb-gadget: Initial merge of target module for UASP + BOT
This fabric uses the target framework to provide a usb gadget device. This gadget supports the USB Attached SCSI Protocol (UASP) and Bulk Only Transfers (BOT or BBB). BOT is the primary interface, UAS is the alternative interface. It has been tested with dummy_hcd on HS and SS. On SS USB3 are supported. I also took my omap device and tried it there against WindowsXP. UAS implements basic command passing (i.e. read/write requests) and TASK MANAGEMENT functions are missing. I had to add a little of error recovery to BOT because Windows was issuing some strange commands and it does not complain after the gadget responded with CSW.status=1. (nab: Move to drivers/usb/gadget as per Sebastian to address legacy limitations for built-in gadget code) Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Acked-by: Felipe Balbi <balbi@ti.com> Cc: Alan Stern <stern@rowland.harvard.edu> Cc: Christoph Hellwig <hch@lst.de> Cc: Greg KH <gregkh@linuxfoundation.org> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
This commit is contained in:
parent
d5dc28eb92
commit
c52661d60f
|
@ -798,6 +798,16 @@ config USB_MASS_STORAGE
|
|||
Say "y" to link the driver statically, or "m" to build
|
||||
a dynamically linked module called "g_mass_storage".
|
||||
|
||||
config USB_GADGET_TARGET
|
||||
tristate "USB Gadget Target Fabric Module"
|
||||
depends on TARGET_CORE
|
||||
help
|
||||
This fabric is an USB gadget. Two USB protocols are supported that is
|
||||
BBB or BOT (Bulk Only Transport) and UAS (USB Attached SCSI). BOT is
|
||||
advertised on alternative interface 0 (primary) and UAS is on
|
||||
alternative interface 1. Both protocols can work on USB2.0 and USB3.0.
|
||||
UAS utilizes the USB 3.0 feature called streams support.
|
||||
|
||||
config USB_G_SERIAL
|
||||
tristate "Serial Gadget (with CDC ACM and CDC OBEX support)"
|
||||
help
|
||||
|
|
|
@ -52,6 +52,7 @@ g_nokia-y := nokia.o
|
|||
g_webcam-y := webcam.o
|
||||
g_ncm-y := ncm.o
|
||||
g_acm_ms-y := acm_ms.o
|
||||
g_tcm_usb_gadget-y := tcm_usb_gadget.o
|
||||
|
||||
obj-$(CONFIG_USB_ZERO) += g_zero.o
|
||||
obj-$(CONFIG_USB_AUDIO) += g_audio.o
|
||||
|
@ -71,3 +72,4 @@ obj-$(CONFIG_USB_G_NOKIA) += g_nokia.o
|
|||
obj-$(CONFIG_USB_G_WEBCAM) += g_webcam.o
|
||||
obj-$(CONFIG_USB_G_NCM) += g_ncm.o
|
||||
obj-$(CONFIG_USB_G_ACM_MS) += g_acm_ms.o
|
||||
obj-$(CONFIG_USB_GADGET_TARGET) += tcm_usb_gadget.o
|
||||
|
|
2480
drivers/usb/gadget/tcm_usb_gadget.c
Normal file
2480
drivers/usb/gadget/tcm_usb_gadget.c
Normal file
File diff suppressed because it is too large
Load diff
146
drivers/usb/gadget/tcm_usb_gadget.h
Normal file
146
drivers/usb/gadget/tcm_usb_gadget.h
Normal file
|
@ -0,0 +1,146 @@
|
|||
#ifndef __TARGET_USB_GADGET_H__
|
||||
#define __TARGET_USB_GADGET_H__
|
||||
|
||||
#include <linux/kref.h>
|
||||
/* #include <linux/usb/uas.h> */
|
||||
#include <linux/usb/composite.h>
|
||||
#include <linux/usb/uas.h>
|
||||
#include <linux/usb/storage.h>
|
||||
#include <scsi/scsi.h>
|
||||
#include <target/target_core_base.h>
|
||||
#include <target/target_core_fabric.h>
|
||||
|
||||
#define USBG_NAMELEN 32
|
||||
|
||||
#define fuas_to_gadget(f) (f->function.config->cdev->gadget)
|
||||
#define UASP_SS_EP_COMP_LOG_STREAMS 4
|
||||
#define UASP_SS_EP_COMP_NUM_STREAMS (1 << UASP_SS_EP_COMP_LOG_STREAMS)
|
||||
|
||||
#define USB_G_STR_MANUFACTOR 1
|
||||
#define USB_G_STR_PRODUCT 2
|
||||
#define USB_G_STR_SERIAL 3
|
||||
#define USB_G_STR_CONFIG 4
|
||||
#define USB_G_STR_INT_UAS 5
|
||||
#define USB_G_STR_INT_BBB 6
|
||||
|
||||
#define USB_G_ALT_INT_BBB 0
|
||||
#define USB_G_ALT_INT_UAS 1
|
||||
|
||||
struct usbg_nacl {
|
||||
/* Binary World Wide unique Port Name for SAS Initiator port */
|
||||
u64 iport_wwpn;
|
||||
/* ASCII formatted WWPN for Sas Initiator port */
|
||||
char iport_name[USBG_NAMELEN];
|
||||
/* Returned by usbg_make_nodeacl() */
|
||||
struct se_node_acl se_node_acl;
|
||||
};
|
||||
|
||||
struct tcm_usbg_nexus {
|
||||
struct se_session *tvn_se_sess;
|
||||
};
|
||||
|
||||
struct usbg_tpg {
|
||||
struct mutex tpg_mutex;
|
||||
/* SAS port target portal group tag for TCM */
|
||||
u16 tport_tpgt;
|
||||
/* Pointer back to usbg_tport */
|
||||
struct usbg_tport *tport;
|
||||
struct workqueue_struct *workqueue;
|
||||
/* Returned by usbg_make_tpg() */
|
||||
struct se_portal_group se_tpg;
|
||||
u32 gadget_connect;
|
||||
struct tcm_usbg_nexus *tpg_nexus;
|
||||
atomic_t tpg_port_count;
|
||||
};
|
||||
|
||||
struct usbg_tport {
|
||||
/* SCSI protocol the tport is providing */
|
||||
u8 tport_proto_id;
|
||||
/* Binary World Wide unique Port Name for SAS Target port */
|
||||
u64 tport_wwpn;
|
||||
/* ASCII formatted WWPN for SAS Target port */
|
||||
char tport_name[USBG_NAMELEN];
|
||||
/* Returned by usbg_make_tport() */
|
||||
struct se_wwn tport_wwn;
|
||||
};
|
||||
|
||||
enum uas_state {
|
||||
UASP_SEND_DATA,
|
||||
UASP_RECEIVE_DATA,
|
||||
UASP_SEND_STATUS,
|
||||
UASP_QUEUE_COMMAND,
|
||||
};
|
||||
|
||||
#define USBG_MAX_CMD 64
|
||||
struct usbg_cmd {
|
||||
/* common */
|
||||
u8 cmd_buf[USBG_MAX_CMD];
|
||||
u32 data_len;
|
||||
struct work_struct work;
|
||||
int unpacked_lun;
|
||||
struct se_cmd se_cmd;
|
||||
void *data_buf; /* used if no sg support available */
|
||||
struct f_uas *fu;
|
||||
struct completion write_complete;
|
||||
struct kref ref;
|
||||
|
||||
/* UAS only */
|
||||
u16 tag;
|
||||
u16 prio_attr;
|
||||
struct sense_iu sense_iu;
|
||||
enum uas_state state;
|
||||
struct uas_stream *stream;
|
||||
|
||||
/* BOT only */
|
||||
__le32 bot_tag;
|
||||
unsigned int csw_code;
|
||||
unsigned is_read:1;
|
||||
|
||||
};
|
||||
|
||||
struct uas_stream {
|
||||
struct usb_request *req_in;
|
||||
struct usb_request *req_out;
|
||||
struct usb_request *req_status;
|
||||
};
|
||||
|
||||
struct usbg_cdb {
|
||||
struct usb_request *req;
|
||||
void *buf;
|
||||
};
|
||||
|
||||
struct bot_status {
|
||||
struct usb_request *req;
|
||||
struct bulk_cs_wrap csw;
|
||||
};
|
||||
|
||||
struct f_uas {
|
||||
struct usbg_tpg *tpg;
|
||||
struct usb_function function;
|
||||
u16 iface;
|
||||
|
||||
u32 flags;
|
||||
#define USBG_ENABLED (1 << 0)
|
||||
#define USBG_IS_UAS (1 << 1)
|
||||
#define USBG_USE_STREAMS (1 << 2)
|
||||
#define USBG_IS_BOT (1 << 3)
|
||||
#define USBG_BOT_CMD_PEND (1 << 4)
|
||||
|
||||
struct usbg_cdb cmd;
|
||||
struct usb_ep *ep_in;
|
||||
struct usb_ep *ep_out;
|
||||
|
||||
/* UAS */
|
||||
struct usb_ep *ep_status;
|
||||
struct usb_ep *ep_cmd;
|
||||
struct uas_stream stream[UASP_SS_EP_COMP_NUM_STREAMS];
|
||||
|
||||
/* BOT */
|
||||
struct bot_status bot_status;
|
||||
struct usb_request *bot_req_in;
|
||||
struct usb_request *bot_req_out;
|
||||
};
|
||||
|
||||
extern struct usbg_tpg *the_only_tpg_I_currently_have;
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue