add and update

This commit is contained in:
pvvx 2016-11-22 07:48:09 +03:00
parent 03ed2886cb
commit bda4d33012
109 changed files with 73065 additions and 85 deletions

View file

@ -0,0 +1,22 @@
#ifndef _ETH_DEBUG_H_
#define _ETH_DEBUG_H_
#define ETH_DEBUG 0
#if ETH_DEBUG
#define ETH_PRINT(fmt, args...) printf("\n\r[%s]%s: " fmt, __FUNCTION__, ## args)
#define ETH_ERROR(fmt, args...) printf("\n\r[%s]%s: " fmt, __FUNCTION__, ## args)
#define ETH_WARM(fmt, args...) printf("\n\r[%s]%s: " fmt, __FUNCTION__, ## args)
#define FUN_ENTER printf("\n\r[%s ==>]\n", __func__)
#define FUN_EXIT printf("\n\r[%s <==]\n", __func__)
#define FUN_TRACE printf("\n\r[%s]:%d \n", __func__, __LINE__)
#else
#define ETH_PRINT(fmt, args...)
#define ETH_ERROR(fmt, args...) printf("\n\r%s: " fmt,__FUNCTION__, ## args)
#define ETH_WARM(fmt, args...)
#define FUN_ENTER
#define FUN_EXIT
#define FUN_TRACE
#endif
#endif

View file

@ -0,0 +1,358 @@
/*
* Ethernet gadget driver -- with CDC and non-CDC options
* Builds on hardware support for a full duplex link.
*
* CDC Ethernet is the standard USB solution for sending Ethernet frames
* using USB. Real hardware tends to use the same framing protocol but look
* different for control features. This driver strongly prefers to use
* this USB-IF standard as its open-systems interoperability solution;
* most host side USB stacks (except from Microsoft) support it.
*
* There's some hardware that can't talk CDC. We make that hardware
* implement a "minimalist" vendor-agnostic CDC core: same framing, but
* link-level setup only requires activating the configuration.
* Linux supports it, but other host operating systems may not.
* (This is a subset of CDC Ethernet.)
*
* A third option is also in use. Rather than CDC Ethernet, or something
* simpler, Microsoft pushes their own approach: RNDIS. The published
* RNDIS specs are ambiguous and appear to be incomplete, and are also
* needlessly complex.
*/
#ifndef __USB_ETHERNET_H
#define __USB_ETHERNET_H
#include "usb.h"
#include "usb_gadget.h"
#include "core/inc/usb_composite.h"
//#define DRIVER_DESC "Ethernet Gadget"
#define DRIVER_DESC "USB Network Interface"
#define DRIVER_VERSION "May Day 2015"
#define ETH_ADDR "00E04C8196C8"
static const char shortname [] = "ether";
static const char driver_desc [] = DRIVER_DESC;
#define CONFIG_USB_ETH_RNDIS 1
#define RNDIS_VENDOR_NUM ULINKER_ETHER_VID
#define RNDIS_PRODUCT_NUM ULINKER_ETHER_PID
/* Thanks to NetChip Technologies for donating this product ID.
* It's for devices with only CDC Ethernet configurations.
*/
#define CDC_VENDOR_NUM 0x0525 /* NetChip */
#define CDC_PRODUCT_NUM 0xa4a1 /* Linux-USB Ethernet Gadget */
/* USB DRIVER HOOKUP (to the hardware driver, below us), mostly
* ep0 implementation: descriptors, config management, setup().
* also optional class-specific notification interrupt transfer.
*/
/*
* DESCRIPTORS ... most are static, but strings and (full) configuration
* descriptors are built on demand. For now we do either full CDC, or
* our simple subset, with RNDIS as an optional second configuration.
*
* RNDIS includes some CDC ACM descriptors ... like CDC Ethernet. But
* the class descriptors match a modem (they're ignored; it's really just
* Ethernet functionality), they don't need the NOP altsetting, and the
* status transfer endpoint isn't optional.
*/
#define STRING_MANUFACTURER 1
#define STRING_PRODUCT 2
#define STRING_ETHADDR 3
#define STRING_DATA 4
#define STRING_CONTROL 5
#define STRING_RNDIS_CONTROL 6
#define STRING_CDC 7
#define STRING_SUBSET 8
#define STRING_RNDIS 9
#define STRING_SERIALNUMBER 10
/* holds our biggest descriptor (or RNDIS response) */
#define USB_BUFSIZ 256
#define BUFSIZ_IN 512
#define BUFSIZ_OUT 512
/*
* This device advertises one configuration, eth_config, unless RNDIS
* is enabled (rndis_config) on hardware supporting at least two configs.
*
* NOTE: Controllers like superh_udc should probably be able to use
* an RNDIS-only configuration.
*
* FIXME define some higher-powered configurations to make it easier
* to recharge batteries ...
*/
//#define DEV_CONFIG_VALUE 1 /* cdc or subset */
//#define DEV_RNDIS_CONFIG_VALUE 2 /* rndis; optional */
#define DEV_CONFIG_VALUE 2 /* cdc or subset */
#define DEV_RNDIS_CONFIG_VALUE 1 /* rndis; optional */
#define DEVSPEED USB_SPEED_HIGH
/* descriptors that are built on-demand */
static char manufacturer [50];
static char product_desc [40] = DRIVER_DESC;
static char serial_number [20];
/* address that the host will use ... usually assigned at random */
//ModifiedByJD static char ethaddr [2 * ETH_ALEN + 1];
static char ethaddr [2 * 6 + 1] = ETH_ADDR;
/* static strings, in UTF-8 */
static struct usb_string strings [] = {
{ STRING_MANUFACTURER, manufacturer, },
{ STRING_PRODUCT, product_desc, },
{ STRING_SERIALNUMBER, serial_number, },
{ STRING_DATA, "Ethernet Data", },
#if 1//def DEV_CONFIG_CDC//ModifiedByJD
{ STRING_CDC, "CDC Ethernet", },
{ STRING_ETHADDR, ethaddr, },
{ STRING_CONTROL, "CDC Communications Control", },
#endif
#if 1//def DEV_CONFIG_SUBSET//ModifiedByJD
{ STRING_SUBSET, "CDC Ethernet Subset", },
#endif
#if 1//def CONFIG_USB_ETH_RNDIS//ModifiedByJD
{ STRING_RNDIS, "RNDIS", },
{ STRING_RNDIS_CONTROL, "RNDIS Communications Control", },
#endif /* end of list */
};
static struct usb_gadget_strings stringtab = {
.language = 0x0409, /* en-us */
.strings = strings,
};
static struct usb_gadget_strings *dev_strings[] = {
&stringtab,
NULL,
};
static struct usb_device_descriptor
device_desc = {
.bLength = sizeof device_desc,
.bDescriptorType = USB_DT_DEVICE,
.bcdUSB = (0x0200),
.bDeviceClass = USB_CLASS_COMM,
.bDeviceSubClass = 0,
.bDeviceProtocol = 0,
.idVendor = (CDC_VENDOR_NUM),
.idProduct = (CDC_PRODUCT_NUM),
.iManufacturer = STRING_MANUFACTURER,
.iProduct = STRING_PRODUCT,
.bNumConfigurations = 1,
};
static struct usb_config_descriptor
eth_config = {
.bLength = sizeof eth_config,
.bDescriptorType = USB_DT_CONFIG,
/* compute wTotalLength on the fly */
.bNumInterfaces = 1,
.bConfigurationValue = DEV_CONFIG_VALUE,
.iConfiguration = STRING_CDC,
.bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
.bMaxPower = 50,
};
static struct usb_otg_descriptor
otg_descriptor = {
.bLength = sizeof otg_descriptor,
.bDescriptorType = USB_DT_OTG,
.bmAttributes = USB_OTG_SRP,
};
#ifdef CONFIG_USB_ETH_RNDIS
/* RNDIS doesn't activate by changing to the "real" altsetting */
static struct usb_interface_descriptor
rndis_data_intf = {
.bLength = sizeof rndis_data_intf,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = 0,
.bAlternateSetting = 0,
.bNumEndpoints = 2,
.bInterfaceClass = USB_CLASS_CDC_DATA,
.bInterfaceSubClass = 0,
.bInterfaceProtocol = 0,
.iInterface = STRING_DATA,
};
#endif
static struct usb_endpoint_descriptor
hs_source_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
.wMaxPacketSize = (512),//ModifiedByJD
};
static struct usb_endpoint_descriptor
hs_sink_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
.wMaxPacketSize = (512),//ModifiedByJD
};
static struct usb_endpoint_descriptor
fs_source_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
};
static struct usb_endpoint_descriptor
fs_sink_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_OUT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
};
static const struct usb_descriptor_header *fs_rndis_function [] = {
(struct usb_descriptor_header *) &otg_descriptor,
/* control interface matches ACM, not Ethernet */
#if 0//ModifiedByJD
(struct usb_descriptor_header *) &rndis_control_intf,
(struct usb_descriptor_header *) &header_desc,
(struct usb_descriptor_header *) &call_mgmt_descriptor,
(struct usb_descriptor_header *) &acm_descriptor,
(struct usb_descriptor_header *) &union_desc,
(struct usb_descriptor_header *) &fs_status_desc,
#endif
/* data interface has no altsetting */
(struct usb_descriptor_header *) &rndis_data_intf,
(struct usb_descriptor_header *) &fs_source_desc,
(struct usb_descriptor_header *) &fs_sink_desc,
NULL,
};
static const struct usb_descriptor_header *fs_eth_function [11] = {
(struct usb_descriptor_header *) &otg_descriptor,
#ifdef DEV_CONFIG_CDC
/* "cdc" mode descriptors */
(struct usb_descriptor_header *) &control_intf,
(struct usb_descriptor_header *) &header_desc,
(struct usb_descriptor_header *) &union_desc,
(struct usb_descriptor_header *) &ether_desc,
/* NOTE: status endpoint may need to be removed */
(struct usb_descriptor_header *) &fs_status_desc,
/* data interface, with altsetting */
(struct usb_descriptor_header *) &data_nop_intf,
(struct usb_descriptor_header *) &data_intf,
(struct usb_descriptor_header *) &fs_source_desc,
(struct usb_descriptor_header *) &fs_sink_desc,
NULL,
#endif /* DEV_CONFIG_CDC */
};
#ifdef CONFIG_USB_ETH_RNDIS
static const struct usb_descriptor_header *hs_rndis_function [] = {
(struct usb_descriptor_header *) &otg_descriptor,
/* control interface matches ACM, not Ethernet */
#if 0//ModifiedByJD
(struct usb_descriptor_header *) &rndis_control_intf,
(struct usb_descriptor_header *) &header_desc,
(struct usb_descriptor_header *) &call_mgmt_descriptor,
(struct usb_descriptor_header *) &acm_descriptor,
(struct usb_descriptor_header *) &union_desc,
(struct usb_descriptor_header *) &hs_status_desc,
#endif
/* data interface has no altsetting */
(struct usb_descriptor_header *) &rndis_data_intf,
(struct usb_descriptor_header *) &hs_source_desc,
(struct usb_descriptor_header *) &hs_sink_desc,
NULL,
};
#endif
static struct usb_config_descriptor
rndis_config = {
.bLength = sizeof rndis_config,
.bDescriptorType = USB_DT_CONFIG,
/* compute wTotalLength on the fly */
.bNumInterfaces = 1,
.bConfigurationValue = DEV_RNDIS_CONFIG_VALUE,
.iConfiguration = STRING_RNDIS,
.bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
.bMaxPower = 50,
};
static struct usb_configuration eth_configuration = {
.label = "eth_configuration",
.bConfigurationValue = DEV_CONFIG_VALUE,
// .bConfigurationValue = 1,
/* .iConfiguration = DYNAMIC */
.bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
};
static struct eth_dev{
struct usb_gadget *gadget;
struct usb_request *req; /* for control responses */
/* when configured, we have one of two configs:
* - source data (in to host) and sink it (out from host)
* - or loop it back (out from host back in to host)
*/
u8 config;
struct usb_ep *in_ep;
struct usb_ep *out_ep;
const struct usb_endpoint_descriptor
*in, *out, *status;
// lock is held when accessing usb
_Lock lock;
struct usb_function func;
/*send (depends on host)*/
_Sema xmit_sema;
xTaskHandle xmit_task;
unsigned int qlen;
_Mutex xmit_mutex;
_LIST eth2wlan_list;
/*receive (debuf_poolpends on host)*/
_Sema recv_sema;
xTaskHandle recv_task;
_Mutex recv_mutex;
_LIST wlan2eth_list;
};
extern int usb_eth_init(void);
#endif

View file

@ -0,0 +1,183 @@
#ifndef USBD_MSC_H
#define USBD_MSC_H
#include "usb.h"
#include "usb_gadget.h"
#include "core/inc/usb_composite.h"
#include "msc/inc/usbd_msc_config.h"
/* config usb msc device debug inforation */
#define USBD_MSC_DEBUG 0
#if USBD_MSC_DEBUG
#define USBD_PRINTF(fmt, args...) DBG_8195A("\n\r%s: " fmt, __FUNCTION__, ## args)
#define USBD_ERROR(fmt, args...) DBG_8195A("\n\r%s: " fmt, __FUNCTION__, ## args)
#define USBD_WARN(fmt, args...) DBG_8195A("\n\r%s: " fmt, __FUNCTION__, ## args)
#define FUN_ENTER DBG_8195A("\n\r%s ==>\n", __func__)
#define FUN_EXIT DBG_8195A("\n\r%s <==\n", __func__)
#define FUN_TRACE DBG_8195A("\n\r%s:%d \n", __func__, __LINE__)
#else
#define USBD_PRINTF(fmt, args...)
#define USBD_ERROR(fmt, args...) DBG_8195A("\n\r%s: " fmt, __FUNCTION__, ## args)
#define USBD_WARN(fmt, args...)
#define FUN_ENTER
#define FUN_EXIT
#define FUN_TRACE
#endif
/* MSC Request Codes */
#define MSC_REQUEST_RESET 0xFF
#define MSC_REQUEST_GET_MAX_LUN 0xFE
/* MSC LUN */
#define MSC_MAX_LOGIC_UNIT_NUMBER 1
enum data_direction{
DATA_DIR_UNKNOWN = 0,
DATA_DIR_FROM_HOST,
DATA_DIR_TO_HOST,
DATA_DIR_NONE
};
typedef enum _disk_type{
DISK_SDCARD,
DISK_FLASH
}disk_type;
//structure predefine
struct msc_dev;
struct msc_bufhd;
struct msc_opts{
int (*disk_init)(void);
int (*disk_deinit)(void);
int (*disk_getcapacity)(u32* sectors);
int (*disk_read)(u32 sector,u8 *buffer,u32 count);
int (*disk_write)(u32 sector,const u8 *buffer,u32 count);
};
struct msc_lun {
unsigned int initially_ro:1;
unsigned int ro:1;
unsigned int removable:1;
unsigned int cdrom:1;
unsigned int prevent_medium_removal:1;
unsigned int registered:1;
unsigned int info_valid:1;
unsigned int nofua:1;
u32 sense_data;
u32 sense_data_info;
u32 unit_attention_data;
u64 file_length;
unsigned int num_sectors; /* */
unsigned int blkbits; /* Bits of logical block size
of bound block device */
unsigned int blksize; /* logical block size of bound block device */
const char *name; /* "lun.name" */
unsigned int lba; // the current read and write logical block address
u8 is_open;
_mutex lun_mutex;
struct msc_opts *lun_opts;
};
struct msc_common{
struct msc_dev *mscdev;
struct msc_lun **luns;
struct msc_lun *curlun;
struct usb_gadget *gadget;
struct usb_ep *ep0;
struct usb_request *req0; /* for control responses */
/* scsi cbw relevant */
enum data_direction data_dir;
u32 data_size;
u32 data_size_from_cmnd;
u32 tag;
u32 residue;
u32 usb_amount_left;
u8 scsi_cmnd[16]; // max command
u8 cmnd_size;
u8 lun; /* current lun*/
u8 nluns;
u8 nbufhd;
u8 nbufhd_a;
_list bufhd_pool;
_mutex bufhd_mutex;
/* bulk out cmd*/
_list boc_list;
_mutex boc_mutex;
/* bolk out data*/
_mutex bod_mutex;
_list bod_list;
/**/
struct msc_bufhd* curbh; // current buffer header
struct msc_bufhd* cbw_bh; // buffer header for CBW
struct msc_bufhd* csw_bh; // buffer header for CSW
unsigned int can_stall:1;
unsigned int phase_error:1;
unsigned int short_packet_received:1;
unsigned int bad_lun_okay:1;
unsigned int running:1;
};
typedef enum _bufhd_type{
BUFHD_CBW = 0,
BUFHD_CSW,
BUFHD_DATA,
}bufhd_type;
struct msc_bufhd{
u8* buf;
int buf_size;
bufhd_type type;
_list list;
struct usb_request *reqin; /* for bulkin responses */
struct usb_request *reqout;
};
struct msc_dev{
struct msc_common *common;
u16 interface_number;
u8 config;
struct usb_ep *in_ep;
struct usb_ep *out_ep;
unsigned int bulk_in_enabled:1;
unsigned int bulk_out_enabled:1;
const struct usb_endpoint_descriptor
*in, *out, *status;
// lock is held when accessing usb
struct task_struct msc_outCmdTask;
struct task_struct msc_outDataTask;
struct usb_function func;
};
u32 min(u32 value1,u32 value2);
int usbd_msc_halt_bulk_in_endpoint(struct msc_dev *mscdev);
void usbd_msc_put_bufhd(struct msc_common *common, struct msc_bufhd* bufhd);
struct msc_bufhd* usbd_msc_get_bufhd(struct msc_common *common);
int usbd_msc_bulk_in_transfer(struct msc_dev *mscdev, struct usb_request *req);
int usbd_msc_bulk_out_transfer(struct msc_dev *mscdev, struct usb_request *req);
/*
* N_bh : number of buffer header
* Size_bh: buffer size per buffer
* type:msc physical disk type
*/
int usbd_msc_init(int N_bh, int Size_bh, disk_type type);
void usbd_msc_deinit(void);
#endif

View file

@ -0,0 +1,8 @@
#ifndef _USBD_MSC_CONFIG_H
#define _USBD_MSC_CONFIG_H
/* config usb MSC device buffer resource */
#define MSC_NBR_BUFHD 2 /* number of buffer header for bulk in/out data*/
#define MSC_BUFLEN (20*512)/* Default size of buffer length. Minmun of 512 byte*/
#endif

View file

@ -0,0 +1,196 @@
#include "usb_ch9.h"
#include "usb_defs.h"
#include "usb_gadget.h"
// <i> Enable high-speed functionality (if device supports it)
#define USBD_HS_ENABLE 1
// define string index
#define STRING_MANUFACTURER 1
#define STRING_PRODUCT 2
#define STRING_SERIALNUMBER 3
#define STRING_INTERFACE 4
#define STRING_MSC 5
#define DEV_CONFIG_VALUE 1
#define DRIVER_DESC "USB Mass Storage"
#define DRIVER_VERSION "Feb 2016"
#define MANUFACTURER "Realtek Singapore Semiconductor"
static char string_manufacturer [50] = MANUFACTURER;
static char string_product [40] = DRIVER_DESC;
static char string_serial [20] = "0123456789";
struct usb_string
usbd_msc_strings [] = {
{ STRING_MANUFACTURER, string_manufacturer, },
{ STRING_PRODUCT, string_product, },
{ STRING_SERIALNUMBER, string_serial, },
{ STRING_INTERFACE, "USB MSC Interface", },
{ STRING_MSC, "USB MSC", },
};
struct usb_gadget_strings msc_stringtab = {
.language = 0x0409, /* en-us */
.strings = usbd_msc_strings,
};
struct usb_gadget_strings *dev_msc_strings[] = {
&msc_stringtab,
NULL,
};
static struct usb_device_descriptor
usbd_msc_device_desc = {
.bLength = sizeof usbd_msc_device_desc,
.bDescriptorType = USB_DT_DEVICE,
.bcdUSB = (0x0200),
.bDeviceClass = 0x00,// define in interface descriptor
.bDeviceSubClass = 0x00,
.bDeviceProtocol = 0x00,
.bMaxPacketSize0 = 64, // this will be set automatically depends on ep0 setting
.idVendor = 0x0BDA,
.idProduct = 0x8195,
// .bcdDevice = ,
.iManufacturer = STRING_MANUFACTURER,
.iProduct = STRING_PRODUCT,
.iSerialNumber = STRING_SERIALNUMBER,
.bNumConfigurations=0x01,
};
#if 0
struct usb_config_descriptor
usbd_msc_config_desc = {
.bLength = sizeof usbd_msc_config_desc,
.bDescriptorType = USB_DT_CONFIG,
/* compute wTotalLength on the fly */
.bNumInterfaces = 1,
.bConfigurationValue = DEV_CONFIG_VALUE,
.iConfiguration = STRING_MSC,
.bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
.bMaxPower = 0x32,
};
#endif
#if USBD_HS_ENABLE
/* USB Device Qualifier Descriptor (for Full Speed) */
static struct usb_qualifier_descriptor
usbd_msc_qualifier_desc_FS = {
.bLength = sizeof usbd_msc_qualifier_desc_FS,
.bDescriptorType = USB_DT_DEVICE_QUALIFIER,
.bcdUSB = 0x0200,
.bDeviceClass = 0x00,
.bDeviceSubClass = 0x00,
.bDeviceProtocol = 0x00,
.bMaxPacketSize0 = 64,
.bNumConfigurations = 0x01,
.bRESERVED = 0x00,
};
/* USB Device Qualifier Descriptor for High Speed */
static struct usb_qualifier_descriptor
usbd_msc_qualifier_desc_HS = {
.bLength = sizeof usbd_msc_qualifier_desc_HS,
.bDescriptorType = USB_DT_DEVICE_QUALIFIER,
.bcdUSB = 0x0200,
.bDeviceClass = 0x00,
.bDeviceSubClass = 0x00,
.bDeviceProtocol = 0x00,
.bMaxPacketSize0 = 64,
.bNumConfigurations = 0x01,
.bRESERVED = 0x00,
};
#else
/* USB Device Qualifier Descriptor (for Full Speed) */
static struct usb_qualifier_descriptor
usbd_msc_qualifier_desc_FS = { 0 };
/* USB Device Qualifier Descriptor for High Speed */
static struct usb_qualifier_descriptor
usbd_msc_qualifier_desc_HS = { 0 };
#endif
/* MSC Interface, Alternate Setting 0*/
struct usb_interface_descriptor
usbd_msc_intf_desc = {
.bLength = sizeof usbd_msc_intf_desc,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = 0x00, // this will be assign automatically
.bAlternateSetting =0x00,
.bNumEndpoints = 0x02,
.bInterfaceClass = USB_CLASS_MASS_STORAGE,
.bInterfaceSubClass = US_SC_SCSI,
.bInterfaceProtocol = US_PR_BULK,
.iInterface = STRING_INTERFACE,
};
/* MSC Endpoints for Low-speed/Full-speed */
/* Endpoint, EP Bulk IN */
struct usb_endpoint_descriptor
usbd_msc_source_desc_FS = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
.wMaxPacketSize = (64),
.bInterval = 0x00,
};
/* Endpoint, EP Bulk OUT */
struct usb_endpoint_descriptor
usbd_msc_sink_desc_FS = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_OUT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
.wMaxPacketSize = (64),
.bInterval = 0x00,
};
/* MSC Endpoints for High-speed */
/* Endpoint, EP Bulk IN */
struct usb_endpoint_descriptor
usbd_msc_source_desc_HS = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
.wMaxPacketSize = (512),
.bInterval = 0x00,
};
/* Endpoint, EP Bulk OUT */
struct usb_endpoint_descriptor
usbd_msc_sink_desc_HS = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_OUT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
.wMaxPacketSize = (512),
.bInterval = 0x00,
};
struct usb_descriptor_header *usbd_msc_descriptors_FS [] = {
/* data interface has no altsetting */
(struct usb_descriptor_header *) &usbd_msc_intf_desc,
(struct usb_descriptor_header *) &usbd_msc_source_desc_FS,
(struct usb_descriptor_header *) &usbd_msc_sink_desc_FS,
NULL,
};
struct usb_descriptor_header *usbd_msc_descriptors_HS [] = {
/* data interface has no altsetting */
(struct usb_descriptor_header *) &usbd_msc_intf_desc,
(struct usb_descriptor_header *) &usbd_msc_source_desc_HS,
(struct usb_descriptor_header *) &usbd_msc_sink_desc_HS,
NULL,
};

View file

@ -0,0 +1,110 @@
#ifndef USBD_SCSI_H
#define USBD_SCSI_H
#include "basic_types.h"
#include "msc/inc/usbd_msc.h"
#define MAX_COMMAND_SIZE 16
#define MSC_MAX_LUNS 8
/* SCSI Commands */
#define SCSI_FORMAT_UNIT 0x04
#define SCSI_INQUIRY 0x12
#define SCSI_MODE_SELECT6 0x15
#define SCSI_MODE_SELECT10 0x55
#define SCSI_MODE_SENSE6 0x1A
#define SCSI_MODE_SENSE10 0x5A
#define SCSI_ALLOW_MEDIUM_REMOVAL 0x1E
#define SCSI_READ6 0x08
#define SCSI_READ10 0x28
#define SCSI_READ12 0xA8
#define SCSI_READ16 0x88
#define SCSI_READ_CAPACITY10 0x25
#define SCSI_READ_CAPACITY16 0x9E
#define SCSI_SYNCHRONIZE_CACHE 0x35
#define SCSI_REQUEST_SENSE 0x03
#define SCSI_START_STOP_UNIT 0x1B
#define SCSI_TEST_UNIT_READY 0x00
#define SCSI_WRITE6 0x0A
#define SCSI_WRITE10 0x2A
#define SCSI_WRITE12 0xAA
#define SCSI_WRITE16 0x8A
#define SCSI_VERIFY10 0x2F
#define SCSI_VERIFY12 0xAF
#define SCSI_VERIFY16 0x8F
#define SCSI_SEND_DIAGNOSTIC 0x1D
#define SCSI_READ_FORMAT_CAPACITIES 0x23
#define READ_FORMAT_CAPACITY_DATA_LEN 0x0C
#define READ_CAPACITY10_DATA_LEN 0x08
#define MODE_SENSE10_DATA_LEN 0x08
#define MODE_SENSE6_DATA_LEN 0x04
#define REQUEST_SENSE_DATA_LEN 0x12
#define STANDARD_INQUIRY_DATA_LEN 0x24
/* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */
#define SS_NO_SENSE 0
#define SS_COMMUNICATION_FAILURE 0x040800
#define SS_INVALID_COMMAND 0x052000
#define SS_INVALID_FIELD_IN_CDB 0x052400
#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x052100
#define SS_LOGICAL_UNIT_NOT_SUPPORTED 0x052500
#define SS_MEDIUM_NOT_PRESENT 0x023a00
#define SS_MEDIUM_REMOVAL_PREVENTED 0x055302
#define SS_NOT_READY_TO_READY_TRANSITION 0x062800
#define SS_RESET_OCCURRED 0x062900
#define SS_SAVING_PARAMETERS_NOT_SUPPORTED 0x053900
#define SS_UNRECOVERED_READ_ERROR 0x031100
#define SS_WRITE_ERROR 0x030c02
#define SS_WRITE_PROTECTED 0x072700
#define SK(x) ((u8) ((x) >> 16)) /* Sense Key byte, etc. */
#define ASC(x) ((u8) ((x) >> 8))
#define ASCQ(x) ((u8) (x))
/*
* Bulk only data structures
*/
/* command block wrapper */
struct bulk_cb_wrap {
unsigned int Signature; /* contains 'USBC', denote bulk_cb_wrap */
unsigned int Tag; /* unique per command id */
unsigned int DataTransferLength; /* size of data for transfer */
unsigned char Flags; /* data transfer direction */
unsigned char Lun; /* LUN normally 0, (which command block is sent) */
unsigned char Length; /* length of the CDB */
unsigned char CDB[16]; /* max command */
};
#define US_BULK_CB_WRAP_LEN 31
#define US_BULK_CB_SIGN 0x43425355 /*spells out USBC */
#define US_BULK_FLAG_IN (1 << 7)
#define US_BULK_FLAG_OUT 0
/* command status wrapper */
struct bulk_cs_wrap {
unsigned int Signature; /* should = 'USBS' */
unsigned int Tag; /* same as original command, echoed by the device as received */
unsigned int Residue; /* amount not transferred */
unsigned char Status; /* execute command status */
};
#define US_BULK_CS_WRAP_LEN 13
#define US_BULK_CS_SIGN 0x53425355 /* spells out 'USBS' */
// execute command status
#define US_BULK_STAT_OK 0
#define US_BULK_STAT_FAIL 1
#define US_BULK_STAT_PHASE 2
/* bulk-only class specific requests */
#define US_BULK_RESET_REQUEST 0xff
#define US_BULK_GET_MAX_LUN 0xfe
extern int usbd_msc_receive_cbw(struct msc_dev *mscdev, struct usb_request *req);
#endif

View file

@ -0,0 +1,24 @@
#ifndef _GADEGT_DEBUG_H_
#define _GADGET_DEBUG_H_
#include "diag.h"
#define GADGET_DEBUG 0
#if GADGET_DEBUG
#define GADGET_PRINT(fmt, args...) DBG_8195A("\n\r[%s]: " fmt, __FUNCTION__, ## args)
#define GADGET_ERROR(fmt, args...) DBG_8195A("\n\r[%s]: " fmt, __FUNCTION__, ## args)
#define GADGET_WARN(fmt, args...) DBG_8195A("\n\r[%s]: " fmt, __FUNCTION__, ## args)
#define FUN_ENTER DBG_8195A("\n\r[%s ==>]\n", __func__)
#define FUN_EXIT DBG_8195A("\n\r[%s <==]\n", __func__)
#define FUN_TRACE DBG_8195A("\n\r[%s]:%d \n", __func__, __LINE__)
#else
#define GADGET_PRINT(fmt, args...)
#define GADGET_ERROR(fmt, args...) DBG_8195A("\n\r[%s]: " fmt, __FUNCTION__, ## args)
#define GADGET_WARN(fmt, args...)
#define FUN_ENTER
#define FUN_EXIT
#define FUN_TRACE
#endif
#endif

View file

@ -0,0 +1,30 @@
#ifndef _OS_WRAPPER_H_
#define _OS_WRAPPER_H_
#include "osdep_api.h"
#ifndef spinlock_t
#define spinlock_t _Lock
#endif
#ifndef _atomic_spin_lock_irqsave
#define _atomic_spin_lock_irqsave(p, flags) SaveAndCli()
#endif
#ifndef _atomic_spin_unlock_irqrestore
#define _atomic_spin_unlock_irqrestore(p, flags) RestoreFlags()
#endif
/* spin lock */
#ifndef spin_lock_init
#define spin_lock_init(plock) RtlSpinlockInit((plock))
#endif
#ifndef spin_lock_free
#define spin_lock_free(plock) RtlSpinlockFree((plock))
#endif
#ifndef spin_lock
#define spin_lock(plock) RtlSpinlock((plock))
#endif
#ifndef spin_unlock
#define spin_unlock(plock) RtlSpinunlock((plock))
#endif
#endif

View file

@ -0,0 +1,398 @@
#ifndef _USB_COMPOSITE_H_
#define _USB_COMPOSITE_H_
#include "usb_gadget.h"
#include "usb.h"
/*
* USB function drivers should return USB_GADGET_DELAYED_STATUS if they
* wish to delay the data/status stages of the control transfer till they
* are ready. The control transfer will then be kept from completing till
* all the function drivers that requested for USB_GADGET_DELAYED_STAUS
* invoke usb_composite_setup_continue().
*/
#define USB_GADGET_DELAYED_STATUS 0x7fff /* Impossibly large value */
/* big enough to hold our biggest descriptor */
#define USB_COMP_EP0_BUFSIZ 1024+24
#define MAX_CONFIG_INTERFACES 16 /* arbitrary; max 255 */
// predefine structure
struct usb_composite_dev;
struct usb_composite_driver;
enum control_request_return_codes {
USBD_REQ_NOTSUPP = 0,
USBD_REQ_HANDLED = 1,
USBD_REQ_NEXT_CALLBACK = 2,
};
/**
* struct usb_composite_driver - groups configurations into a gadget
* @name: For diagnostics, identifies the driver.
* @dev: Template descriptor for the device, including default device
* identifiers.
* @strings: tables of strings, keyed by identifiers assigned during @bind
* and language IDs provided in control requests. Note: The first entries
* are predefined. The first entry that may be used is
* USB_GADGET_FIRST_AVAIL_IDX
* @max_speed: Highest speed the driver supports.
* @needs_serial: set to 1 if the gadget needs userspace to provide
* a serial number. If one is not provided, warning will be printed.
* @bind: (REQUIRED) Used to allocate resources that are shared across the
* whole device, such as string IDs, and add its configurations using
* @usb_add_config(). This may fail by returning a negative errno
* value; it should return zero on successful initialization.
* @unbind: Reverses @bind; called as a side effect of unregistering
* this driver.
* @disconnect: optional driver disconnect method
* @suspend: Notifies when the host stops sending USB traffic,
* after function notifications
* @resume: Notifies configuration when the host restarts USB traffic,
* before function notifications
* @gadget_driver: Gadget driver controlling this driver
*
* Devices default to reporting self powered operation. Devices which rely
* on bus powered operation should report this in their @bind method.
*
* Before returning from @bind, various fields in the template descriptor
* may be overridden. These include the idVendor/idProduct/bcdDevice values
* normally to bind the appropriate host side driver, and the three strings
* (iManufacturer, iProduct, iSerialNumber) normally used to provide user
* meaningful device identifiers. (The strings will not be defined unless
* they are defined in @dev and @strings.) The correct ep0 maxpacket size
* is also reported, as defined by the underlying controller driver.
*/
struct usb_composite_driver {
const char *name;
const struct usb_device_descriptor *dev;
struct usb_gadget_strings **strings;
enum usb_device_speed max_speed;
unsigned needs_serial:1;
int (*bind)(struct usb_composite_dev *cdev);
int (*unbind)(struct usb_composite_dev *);
void (*disconnect)(struct usb_composite_dev *);
/* global suspend hooks */
void (*suspend)(struct usb_composite_dev *);
void (*resume)(struct usb_composite_dev *);
struct usb_gadget_driver gadget_driver;
};
/**
* struct usb_composite_device - represents one composite usb gadget
* @gadget: read-only, abstracts the gadget's usb peripheral controller
* @req: used for control responses; buffer is pre-allocated
* @os_desc_req: used for OS descriptors responses; buffer is pre-allocated
* @config: the currently active configuration
* @qw_sign: qwSignature part of the OS string
* @b_vendor_code: bMS_VendorCode part of the OS string
* @use_os_string: false by default, interested gadgets set it
* @os_desc_config: the configuration to be used with OS descriptors
*
* One of these devices is allocated and initialized before the
* associated device driver's bind() is called.
*
* OPEN ISSUE: it appears that some WUSB devices will need to be
* built by combining a normal (wired) gadget with a wireless one.
* This revision of the gadget framework should probably try to make
* sure doing that won't hurt too much.
*
* One notion for how to handle Wireless USB devices involves:
* (a) a second gadget here, discovery mechanism TBD, but likely
* needing separate "register/unregister WUSB gadget" calls;
* (b) updates to usb_gadget to include flags "is it wireless",
* "is it wired", plus (presumably in a wrapper structure)
* bandgroup and PHY info;
* (c) presumably a wireless_ep wrapping a usb_ep, and reporting
* wireless-specific parameters like maxburst and maxsequence;
* (d) configurations that are specific to wireless links;
* (e) function drivers that understand wireless configs and will
* support wireless for (additional) function instances;
* (f) a function to support association setup (like CBAF), not
* necessarily requiring a wireless adapter;
* (g) composite device setup that can create one or more wireless
* configs, including appropriate association setup support;
* (h) more, TBD.
*/
#define MAX_USER_CONTROL_CALLBACK 2
typedef int (*user_control_callback)(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl);
struct usb_composite_dev {
struct usb_gadget *gadget;
struct usb_request *req;
struct usb_request *os_desc_req;
struct usb_configuration *config;
//
// /* OS String is a custom (yet popular) extension to the USB standard. */
// u8 qw_sign[OS_STRING_QW_SIGN_LEN];
// u8 b_vendor_code;
// struct usb_configuration *os_desc_config;
// unsigned int use_os_string:1;
//
// /* private: */
// /* internals */
unsigned int suspended:1;
struct usb_device_descriptor desc;
//_LIST config_list;
dwc_list_link_t config_list; // by jimmy
//_LIST gstring_list;
dwc_list_link_t gstring_list;// by jimmy
struct usb_composite_driver *driver;
// u8 next_string_id;
// char *def_manufacturer;
//
// /* the gadget driver won't enable the data pullup
// * while the deactivation count is nonzero.
// */
// unsigned deactivations;
//
// /* the composite driver won't complete the control transfer's
// * data/status stages till delayed_status is zero.
// */
// int delayed_status;
//
// /* protects deactivations and delayed_status counts*/
_Lock lock;
/* for unstandard control request handler */
user_control_callback control_cb[MAX_USER_CONTROL_CALLBACK];
};
#if 0
#define container_of(p,t,n) (t*)((p)-&(((t*)0)->n))
static inline struct usb_composite_driver *to_cdriver(
struct usb_gadget_driver *gdrv)
{
return container_of(gdrv, struct usb_composite_driver, gadget_driver);
}
#endif
#if 1
/**
* struct usb_configuration - represents one gadget configuration
* @label: For diagnostics, describes the configuration.
* @strings: Tables of strings, keyed by identifiers assigned during @bind()
* and by language IDs provided in control requests.
* @descriptors: Table of descriptors preceding all function descriptors.
* Examples include OTG and vendor-specific descriptors.
* @unbind: Reverses @bind; called as a side effect of unregistering the
* driver which added this configuration.
* @setup: Used to delegate control requests that aren't handled by standard
* device infrastructure or directed at a specific interface.
* @bConfigurationValue: Copied into configuration descriptor.
* @iConfiguration: Copied into configuration descriptor.
* @bmAttributes: Copied into configuration descriptor.
* @MaxPower: Power consumtion in mA. Used to compute bMaxPower in the
* configuration descriptor after considering the bus speed.
* @cdev: assigned by @usb_add_config() before calling @bind(); this is
* the device associated with this configuration.
*
* Configurations are building blocks for gadget drivers structured around
* function drivers. Simple USB gadgets require only one function and one
* configuration, and handle dual-speed hardware by always providing the same
* functionality. Slightly more complex gadgets may have more than one
* single-function configuration at a given speed; or have configurations
* that only work at one speed.
*
* Composite devices are, by definition, ones with configurations which
* include more than one function.
*
* The lifecycle of a usb_configuration includes allocation, initialization
* of the fields described above, and calling @usb_add_config() to set up
* internal data and bind it to a specific device. The configuration's
* @bind() method is then used to initialize all the functions and then
* call @usb_add_function() for them.
*
* Those functions would normally be independent of each other, but that's
* not mandatory. CDC WMC devices are an example where functions often
* depend on other functions, with some functions subsidiary to others.
* Such interdependency may be managed in any way, so long as all of the
* descriptors complete by the time the composite driver returns from
* its bind() routine.
*/
struct usb_configuration {
const char *label;
struct usb_gadget_strings **strings;
const struct usb_descriptor_header **descriptors;
/* REVISIT: bind() functions can be marked __init, which
* makes trouble for section mismatch analysis. See if
* we can't restructure things to avoid mismatching...
*/
/* configuration management: unbind/setup */
void (*unbind)(struct usb_configuration *);
int (*setup)(struct usb_configuration *,
const struct usb_ctrlrequest *);
/* fields in the config descriptor */
u8 bConfigurationValue;
u8 iConfiguration;
u8 bmAttributes;
u16 MaxPower;
struct usb_composite_dev *cdev;
/* private: */
/* internals */
//_LIST list;
//_LIST function_lists;
dwc_list_link_t list;
dwc_list_link_t function_lists; // by jimmy
u8 next_interface_id;
unsigned superspeed:1;
unsigned highspeed:1;
unsigned fullspeed:1;
struct usb_function *interface[MAX_CONFIG_INTERFACES];
};
_LONG_CALL_ int usb_interface_id(struct usb_configuration *config,
struct usb_function *function);
_LONG_CALL_ int usb_add_config(struct usb_composite_dev *,
struct usb_configuration *,
int (*)(struct usb_configuration *));
_LONG_CALL_ void usb_remove_config(struct usb_composite_dev *,
struct usb_configuration *);
/**
* struct usb_function - describes one function of a configuration
* @name: For diagnostics, identifies the function.
* @strings: tables of strings, keyed by identifiers assigned during bind()
* and by language IDs provided in control requests
* @fs_descriptors: Table of full (or low) speed descriptors, using interface and
* string identifiers assigned during @bind(). If this pointer is null,
* the function will not be available at full speed (or at low speed).
* @hs_descriptors: Table of high speed descriptors, using interface and
* string identifiers assigned during @bind(). If this pointer is null,
* the function will not be available at high speed.
* @ss_descriptors: Table of super speed descriptors, using interface and
* string identifiers assigned during @bind(). If this
* pointer is null after initiation, the function will not
* be available at super speed.
* @config: assigned when @usb_add_function() is called; this is the
* configuration with which this function is associated.
* @os_desc_table: Table of (interface id, os descriptors) pairs. The function
* can expose more than one interface. If an interface is a member of
* an IAD, only the first interface of IAD has its entry in the table.
* @os_desc_n: Number of entries in os_desc_table
* @bind: Before the gadget can register, all of its functions bind() to the
* available resources including string and interface identifiers used
* in interface or class descriptors; endpoints; I/O buffers; and so on.
* @unbind: Reverses @bind; called as a side effect of unregistering the
* driver which added this function.
* @free_func: free the struct usb_function.
* @mod: (internal) points to the module that created this structure.
* @set_alt: (REQUIRED) Reconfigures altsettings; function drivers may
* initialize usb_ep.driver data at this time (when it is used).
* Note that setting an interface to its current altsetting resets
* interface state, and that all interfaces have a disabled state.
* @get_alt: Returns the active altsetting. If this is not provided,
* then only altsetting zero is supported.
* @disable: (REQUIRED) Indicates the function should be disabled. Reasons
* include host resetting or reconfiguring the gadget, and disconnection.
* @setup: Used for interface-specific control requests.
* @suspend: Notifies functions when the host stops sending USB traffic.
* @resume: Notifies functions when the host restarts USB traffic.
* @get_status: Returns function status as a reply to
* GetStatus() request when the recipient is Interface.
* @func_suspend: callback to be called when
* SetFeature(FUNCTION_SUSPEND) is reseived
*
* A single USB function uses one or more interfaces, and should in most
* cases support operation at both full and high speeds. Each function is
* associated by @usb_add_function() with a one configuration; that function
* causes @bind() to be called so resources can be allocated as part of
* setting up a gadget driver. Those resources include endpoints, which
* should be allocated using @usb_ep_autoconfig().
*
* To support dual speed operation, a function driver provides descriptors
* for both high and full speed operation. Except in rare cases that don't
* involve bulk endpoints, each speed needs different endpoint descriptors.
*
* Function drivers choose their own strategies for managing instance data.
* The simplest strategy just declares it "static', which means the function
* can only be activated once. If the function needs to be exposed in more
* than one configuration at a given speed, it needs to support multiple
* usb_function structures (one for each configuration).
*
* A more complex strategy might encapsulate a @usb_function structure inside
* a driver-specific instance structure to allows multiple activations. An
* example of multiple activations might be a CDC ACM function that supports
* two or more distinct instances within the same configuration, providing
* several independent logical data links to a USB host.
*/
struct usb_function {
const char *name;
struct usb_gadget_strings **strings;
struct usb_descriptor_header **fs_descriptors;
struct usb_descriptor_header **hs_descriptors;
// struct usb_descriptor_header **ss_descriptors;
struct usb_configuration *config;
// struct usb_os_desc_table *os_desc_table;
// unsigned os_desc_n;
/* REVISIT: bind() functions can be marked __init, which
* makes trouble for section mismatch analysis. See if
* we can't restructure things to avoid mismatching.
* Related: unbind() may kfree() but bind() won't...
*/
/* configuration management: bind/unbind */
int (*bind)(struct usb_configuration *,
struct usb_function *);
void (*unbind)(struct usb_configuration *,
struct usb_function *);
void (*free_func)(struct usb_function *f);
struct module *mod;
/* runtime state management */
int (*set_alt)(struct usb_function *,
unsigned interface, unsigned alt);
int (*get_alt)(struct usb_function *,
unsigned interface);
void (*disable)(struct usb_function *);
int (*setup)(struct usb_function *,
const struct usb_ctrlrequest *);
void (*suspend)(struct usb_function *);
void (*resume)(struct usb_function *);
/* USB 3.0 additions */
int (*get_status)(struct usb_function *);
int (*func_suspend)(struct usb_function *,
u8 suspend_opt);
/* private: */
/* internals */
//_LIST list;
dwc_list_link_t list; // by jimmy
// DECLARE_BITMAP(endpoints, 32);
// const struct usb_function_instance *fi;
};
#endif
extern _LONG_CALL_ int usb_add_function(struct usb_configuration *, struct usb_function *);
extern _LONG_CALL_ void usb_remove_function(struct usb_configuration *, struct usb_function *);
extern _LONG_CALL_ void usb_put_function(struct usb_function *);
extern _LONG_CALL_ int usb_function_deactivate(struct usb_function *);
extern _LONG_CALL_ int usb_function_activate(struct usb_function *);
extern _LONG_CALL_ int usb_interface_id(struct usb_configuration *, struct usb_function *);
extern _LONG_CALL_ int usb_composite_probe(struct usb_composite_driver *driver);
extern _LONG_CALL_ int register_class_vendor_control_request_cb(struct usb_composite_dev *cdev, user_control_callback cb);
extern _LONG_CALL_ void usb_composite_unregister(struct usb_composite_driver *driver);
#endif

View file

@ -0,0 +1,12 @@
#ifndef _USB_CONFIG_H_
#define _USB_CONFIG_H_
#include "core/inc/usb_composite.h"
extern _LONG_CALL_ int usb_assign_descriptors(struct usb_function *f,
struct usb_descriptor_header **fs,
struct usb_descriptor_header **hs,
struct usb_descriptor_header **ss);
extern _LONG_CALL_ void usb_free_all_descriptors(struct usb_function *f);
#endif

View file

@ -0,0 +1,5 @@
#ifndef _USB_BOT_H
#define _USB_BOT_H
#include "basic_types.h"
#endif

View file

@ -0,0 +1,34 @@
/*
* This file holds the definitions of quirks found in USB devices.
* Only quirks that affect the whole device, not an interface,
* belong here.
*/
#ifndef __QUIRKS_H
#define __QUIRKS_H
/* string descriptors must not be fetched using a 255-byte read */
#define USB_QUIRK_STRING_FETCH_255 0x00000001
/* device can't resume correctly so reset it instead */
#define USB_QUIRK_RESET_RESUME 0x00000002
/* device can't handle Set-Interface requests */
#define USB_QUIRK_NO_SET_INTF 0x00000004
/* device can't handle its Configuration or Interface strings */
#define USB_QUIRK_CONFIG_INTF_STRINGS 0x00000008
/* device can't be reset(e.g morph devices), don't use reset */
#define USB_QUIRK_RESET 0x00000010
/* device has more interface descriptions than the bNumInterfaces count,
and can't handle talking to these interfaces */
#define USB_QUIRK_HONOR_BNUMINTERFACES 0x00000020
/* device needs a pause during initialization, after we read the device
descriptor */
#define USB_QUIRK_DELAY_INIT 0x00000040
#endif /* __QUIRKS_H */

View file

@ -0,0 +1,20 @@
#ifndef _SCATTERLIST_H
#define _SCATTERLIST_H
struct scatterlist {
unsigned long sg_magic;
unsigned long page_link;
unsigned int offset;
unsigned int length;
dma_addr_t dma_address;
__u32 dma_length;
};
struct sg_table {
struct scatterlist *sgl; /* the list */
unsigned int nents; /* number of mapped entries */
unsigned int orig_nents; /* original size of list */
};
#endif

View file

@ -0,0 +1,12 @@
#ifndef _DMA_DIRECTION_H
#define _DMA_DIRECTION_H
enum dma_data_direction {
DMA_BIDIRECTIONAL = 0,
DMA_TO_DEVICE = 1,
DMA_FROM_DEVICE = 2,
DMA_NONE = 3,
};
#endif

View file

@ -0,0 +1,585 @@
/*
* This header file contains public constants and structures used by
* the scsi code for linux.
*
* For documentation on the OPCODES, MESSAGES, and SENSE values,
* please consult the SCSI standard.
*/
#ifndef _SCSI_SCSI_H
#define _SCSI_SCSI_H
#include "us_os_wrap_via_osdep_api.h"
#define HZ 1024
struct scsi_cmnd;
enum scsi_timeouts {
SCSI_DEFAULT_EH_TIMEOUT = 10 * HZ,
};
/*
* The maximum number of SG segments that we will put inside a
* scatterlist (unless chaining is used). Should ideally fit inside a
* single page, to avoid a higher order allocation. We could define this
* to SG_MAX_SINGLE_ALLOC to pack correctly at the highest order. The
* minimum value is 32
*/
#define SCSI_MAX_SG_SEGMENTS 128
/*
* Like SCSI_MAX_SG_SEGMENTS, but for archs that have sg chaining. This limit
* is totally arbitrary, a setting of 2048 will get you at least 8mb ios.
*/
#ifdef ARCH_HAS_SG_CHAIN
#define SCSI_MAX_SG_CHAIN_SEGMENTS 2048
#else
#define SCSI_MAX_SG_CHAIN_SEGMENTS SCSI_MAX_SG_SEGMENTS
#endif
/*
* DIX-capable adapters effectively support infinite chaining for the
* protection information scatterlist
*/
#define SCSI_MAX_PROT_SG_SEGMENTS 0xFFFF
/*
* Special value for scanning to specify scanning or rescanning of all
* possible channels, (target) ids, or luns on a given shost.
*/
#define SCAN_WILD_CARD ~0
/*
* SCSI opcodes
*/
#define TEST_UNIT_READY 0x00
#define REZERO_UNIT 0x01
#define REQUEST_SENSE 0x03
#define FORMAT_UNIT 0x04
#define READ_BLOCK_LIMITS 0x05
#define REASSIGN_BLOCKS 0x07
#define INITIALIZE_ELEMENT_STATUS 0x07
#define READ_6 0x08
#define WRITE_6 0x0a
#define SEEK_6 0x0b
#define READ_REVERSE 0x0f
#define WRITE_FILEMARKS 0x10
#define SPACE 0x11
#define INQUIRY 0x12
#define RECOVER_BUFFERED_DATA 0x14
#define MODE_SELECT 0x15
#define RESERVE 0x16
#define RELEASE 0x17
#define COPY 0x18
#define ERASE 0x19
#define MODE_SENSE 0x1a
#define START_STOP 0x1b
#define RECEIVE_DIAGNOSTIC 0x1c
#define SEND_DIAGNOSTIC 0x1d
#define ALLOW_MEDIUM_REMOVAL 0x1e
#define READ_FORMAT_CAPACITIES 0x23
#define SET_WINDOW 0x24
#define READ_CAPACITY 0x25
#define READ_10 0x28
#define WRITE_10 0x2a
#define SEEK_10 0x2b
#define POSITION_TO_ELEMENT 0x2b
#define WRITE_VERIFY 0x2e
#define VERIFY 0x2f
#define SEARCH_HIGH 0x30
#define SEARCH_EQUAL 0x31
#define SEARCH_LOW 0x32
#define SET_LIMITS 0x33
#define PRE_FETCH 0x34
#define READ_POSITION 0x34
#define SYNCHRONIZE_CACHE 0x35
#define LOCK_UNLOCK_CACHE 0x36
#define READ_DEFECT_DATA 0x37
#define MEDIUM_SCAN 0x38
#define COMPARE 0x39
#define COPY_VERIFY 0x3a
#define WRITE_BUFFER 0x3b
#define READ_BUFFER 0x3c
#define UPDATE_BLOCK 0x3d
#define READ_LONG 0x3e
#define WRITE_LONG 0x3f
#define CHANGE_DEFINITION 0x40
#define WRITE_SAME 0x41
#define UNMAP 0x42
#define READ_TOC 0x43
#define READ_HEADER 0x44
#define GET_EVENT_STATUS_NOTIFICATION 0x4a
#define LOG_SELECT 0x4c
#define LOG_SENSE 0x4d
#define XDWRITEREAD_10 0x53
#define MODE_SELECT_10 0x55
#define RESERVE_10 0x56
#define RELEASE_10 0x57
#define MODE_SENSE_10 0x5a
#define PERSISTENT_RESERVE_IN 0x5e
#define PERSISTENT_RESERVE_OUT 0x5f
#define VARIABLE_LENGTH_CMD 0x7f
#define REPORT_LUNS 0xa0
#define SECURITY_PROTOCOL_IN 0xa2
#define MAINTENANCE_IN 0xa3
#define MAINTENANCE_OUT 0xa4
#define MOVE_MEDIUM 0xa5
#define EXCHANGE_MEDIUM 0xa6
#define READ_12 0xa8
#define WRITE_12 0xaa
#define READ_MEDIA_SERIAL_NUMBER 0xab
#define WRITE_VERIFY_12 0xae
#define VERIFY_12 0xaf
#define SEARCH_HIGH_12 0xb0
#define SEARCH_EQUAL_12 0xb1
#define SEARCH_LOW_12 0xb2
#define SECURITY_PROTOCOL_OUT 0xb5
#define READ_ELEMENT_STATUS 0xb8
#define SEND_VOLUME_TAG 0xb6
#define WRITE_LONG_2 0xea
#define EXTENDED_COPY 0x83
#define RECEIVE_COPY_RESULTS 0x84
#define ACCESS_CONTROL_IN 0x86
#define ACCESS_CONTROL_OUT 0x87
#define READ_16 0x88
#define COMPARE_AND_WRITE 0x89
#define WRITE_16 0x8a
#define READ_ATTRIBUTE 0x8c
#define WRITE_ATTRIBUTE 0x8d
#define VERIFY_16 0x8f
#define SYNCHRONIZE_CACHE_16 0x91
#define WRITE_SAME_16 0x93
#define SERVICE_ACTION_IN 0x9e
/* values for service action in */
#define SAI_READ_CAPACITY_16 0x10
#define SAI_GET_LBA_STATUS 0x12
#define SAI_REPORT_REFERRALS 0x13
/* values for VARIABLE_LENGTH_CMD service action codes
* see spc4r17 Section D.3.5, table D.7 and D.8 */
#define VLC_SA_RECEIVE_CREDENTIAL 0x1800
/* values for maintenance in */
#define MI_REPORT_IDENTIFYING_INFORMATION 0x05
#define MI_REPORT_TARGET_PGS 0x0a
#define MI_REPORT_ALIASES 0x0b
#define MI_REPORT_SUPPORTED_OPERATION_CODES 0x0c
#define MI_REPORT_SUPPORTED_TASK_MANAGEMENT_FUNCTIONS 0x0d
#define MI_REPORT_PRIORITY 0x0e
#define MI_REPORT_TIMESTAMP 0x0f
#define MI_MANAGEMENT_PROTOCOL_IN 0x10
/* value for MI_REPORT_TARGET_PGS ext header */
#define MI_EXT_HDR_PARAM_FMT 0x20
/* values for maintenance out */
#define MO_SET_IDENTIFYING_INFORMATION 0x06
#define MO_SET_TARGET_PGS 0x0a
#define MO_CHANGE_ALIASES 0x0b
#define MO_SET_PRIORITY 0x0e
#define MO_SET_TIMESTAMP 0x0f
#define MO_MANAGEMENT_PROTOCOL_OUT 0x10
/* values for variable length command */
#define XDREAD_32 0x03
#define XDWRITE_32 0x04
#define XPWRITE_32 0x06
#define XDWRITEREAD_32 0x07
#define READ_32 0x09
#define VERIFY_32 0x0a
#define WRITE_32 0x0b
#define WRITE_SAME_32 0x0d
/* Values for T10/04-262r7 */
#define ATA_16 0x85 /* 16-byte pass-thru */
#define ATA_12 0xa1 /* 12-byte pass-thru */
/*
* SCSI command lengths
*/
#define SCSI_MAX_VARLEN_CDB_SIZE 260
/* defined in T10 SCSI Primary Commands-2 (SPC2) */
struct scsi_varlen_cdb_hdr {
__u8 opcode; /* opcode always == VARIABLE_LENGTH_CMD */
__u8 control;
__u8 misc[5];
__u8 additional_cdb_length; /* total cdb length - 8 */
__be16 service_action;
/* service specific data follows */
};
static inline unsigned
scsi_varlen_cdb_length(const void *hdr)
{
return ((struct scsi_varlen_cdb_hdr *)hdr)->additional_cdb_length + 8;
}
extern const unsigned char scsi_command_size_tbl[8];
#define COMMAND_SIZE(opcode) scsi_command_size_tbl[((opcode) >> 5) & 7]
static inline unsigned
scsi_command_size(const unsigned char *cmnd)
{
return (cmnd[0] == VARIABLE_LENGTH_CMD) ?
scsi_varlen_cdb_length(cmnd) : COMMAND_SIZE(cmnd[0]);
}
#ifdef CONFIG_ACPI
struct acpi_bus_type;
extern int
scsi_register_acpi_bus_type(struct acpi_bus_type *bus);
extern void
scsi_unregister_acpi_bus_type(struct acpi_bus_type *bus);
#endif
/*
* SCSI Architecture Model (SAM) Status codes. Taken from SAM-3 draft
* T10/1561-D Revision 4 Draft dated 7th November 2002.
*/
#define SAM_STAT_GOOD 0x00
#define SAM_STAT_CHECK_CONDITION 0x02
#define SAM_STAT_CONDITION_MET 0x04
#define SAM_STAT_BUSY 0x08
#define SAM_STAT_INTERMEDIATE 0x10
#define SAM_STAT_INTERMEDIATE_CONDITION_MET 0x14
#define SAM_STAT_RESERVATION_CONFLICT 0x18
#define SAM_STAT_COMMAND_TERMINATED 0x22 /* obsolete in SAM-3 */
#define SAM_STAT_TASK_SET_FULL 0x28
#define SAM_STAT_ACA_ACTIVE 0x30
#define SAM_STAT_TASK_ABORTED 0x40
/** scsi_status_is_good - check the status return.
*
* @status: the status passed up from the driver (including host and
* driver components)
*
* This returns true for known good conditions that may be treated as
* command completed normally
*/
static inline int scsi_status_is_good(int status)
{
/*
* FIXME: bit0 is listed as reserved in SCSI-2, but is
* significant in SCSI-3. For now, we follow the SCSI-2
* behaviour and ignore reserved bits.
*/
status &= 0xfe;
return ((status == SAM_STAT_GOOD) ||
(status == SAM_STAT_INTERMEDIATE) ||
(status == SAM_STAT_INTERMEDIATE_CONDITION_MET) ||
/* FIXME: this is obsolete in SAM-3 */
(status == SAM_STAT_COMMAND_TERMINATED));
}
/*
* Status codes. These are deprecated as they are shifted 1 bit right
* from those found in the SCSI standards. This causes confusion for
* applications that are ported to several OSes. Prefer SAM Status codes
* above.
*/
#define GOOD 0x00
#define CHECK_CONDITION 0x01
#define CONDITION_GOOD 0x02
#define BUSY 0x04
#define INTERMEDIATE_GOOD 0x08
#define INTERMEDIATE_C_GOOD 0x0a
#define RESERVATION_CONFLICT 0x0c
#define COMMAND_TERMINATED 0x11
#define QUEUE_FULL 0x14
#define ACA_ACTIVE 0x18
#define TASK_ABORTED 0x20
#define STATUS_MASK 0xfe
/*
* SENSE KEYS
*/
#define NO_SENSE 0x00
#define RECOVERED_ERROR 0x01
#define NOT_READY 0x02
#define MEDIUM_ERROR 0x03
#define HARDWARE_ERROR 0x04
#define ILLEGAL_REQUEST 0x05
#define UNIT_ATTENTION 0x06
#define DATA_PROTECT 0x07
#define BLANK_CHECK 0x08
#define COPY_ABORTED 0x0a
#define ABORTED_COMMAND 0x0b
#define VOLUME_OVERFLOW 0x0d
#define MISCOMPARE 0x0e
/*
* DEVICE TYPES
* Please keep them in 0x%02x format for $MODALIAS to work
*/
#define TYPE_DISK 0x00
#define TYPE_TAPE 0x01
#define TYPE_PRINTER 0x02
#define TYPE_PROCESSOR 0x03 /* HP scanners use this */
#define TYPE_WORM 0x04 /* Treated as ROM by our system */
#define TYPE_ROM 0x05
#define TYPE_SCANNER 0x06
#define TYPE_MOD 0x07 /* Magneto-optical disk -
* - treated as TYPE_DISK */
#define TYPE_MEDIUM_CHANGER 0x08
#define TYPE_COMM 0x09 /* Communications device */
#define TYPE_RAID 0x0c
#define TYPE_ENCLOSURE 0x0d /* Enclosure Services Device */
#define TYPE_RBC 0x0e
#define TYPE_OSD 0x11
#define TYPE_NO_LUN 0x7f
/* SCSI protocols; these are taken from SPC-3 section 7.5 */
enum scsi_protocol {
SCSI_PROTOCOL_FCP = 0, /* Fibre Channel */
SCSI_PROTOCOL_SPI = 1, /* parallel SCSI */
SCSI_PROTOCOL_SSA = 2, /* Serial Storage Architecture - Obsolete */
SCSI_PROTOCOL_SBP = 3, /* firewire */
SCSI_PROTOCOL_SRP = 4, /* Infiniband RDMA */
SCSI_PROTOCOL_ISCSI = 5,
SCSI_PROTOCOL_SAS = 6,
SCSI_PROTOCOL_ADT = 7, /* Media Changers */
SCSI_PROTOCOL_ATA = 8,
SCSI_PROTOCOL_UNSPEC = 0xf, /* No specific protocol */
};
/* Returns a human-readable name for the device */
extern const char * scsi_device_type(unsigned type);
/*
* standard mode-select header prepended to all mode-select commands
*/
struct ccs_modesel_head {
__u8 _r1; /* reserved */
__u8 medium; /* device-specific medium type */
__u8 _r2; /* reserved */
__u8 block_desc_length; /* block descriptor length */
__u8 density; /* device-specific density code */
__u8 number_blocks_hi; /* number of blocks in this block desc */
__u8 number_blocks_med;
__u8 number_blocks_lo;
__u8 _r3;
__u8 block_length_hi; /* block length for blocks in this desc */
__u8 block_length_med;
__u8 block_length_lo;
};
/*
* ScsiLun: 8 byte LUN.
*/
struct scsi_lun {
__u8 scsi_lun[8];
};
/*
* The Well Known LUNS (SAM-3) in our int representation of a LUN
*/
#define SCSI_W_LUN_BASE 0xc100
#define SCSI_W_LUN_REPORT_LUNS (SCSI_W_LUN_BASE + 1)
#define SCSI_W_LUN_ACCESS_CONTROL (SCSI_W_LUN_BASE + 2)
#define SCSI_W_LUN_TARGET_LOG_PAGE (SCSI_W_LUN_BASE + 3)
static inline int scsi_is_wlun(unsigned int lun)
{
return (lun & 0xff00) == SCSI_W_LUN_BASE;
}
/*
* MESSAGE CODES
*/
#define COMMAND_COMPLETE 0x00
#define EXTENDED_MESSAGE 0x01
#define EXTENDED_MODIFY_DATA_POINTER 0x00
#define EXTENDED_SDTR 0x01
#define EXTENDED_EXTENDED_IDENTIFY 0x02 /* SCSI-I only */
#define EXTENDED_WDTR 0x03
#define EXTENDED_PPR 0x04
#define EXTENDED_MODIFY_BIDI_DATA_PTR 0x05
#define SAVE_POINTERS 0x02
#define RESTORE_POINTERS 0x03
#define DISCONNECT 0x04
#define INITIATOR_ERROR 0x05
#define ABORT_TASK_SET 0x06
#define MESSAGE_REJECT 0x07
#define NOP 0x08
#define MSG_PARITY_ERROR 0x09
#define LINKED_CMD_COMPLETE 0x0a
#define LINKED_FLG_CMD_COMPLETE 0x0b
#define TARGET_RESET 0x0c
#define ABORT_TASK 0x0d
#define CLEAR_TASK_SET 0x0e
#define INITIATE_RECOVERY 0x0f /* SCSI-II only */
#define RELEASE_RECOVERY 0x10 /* SCSI-II only */
#define CLEAR_ACA 0x16
#define LOGICAL_UNIT_RESET 0x17
#define SIMPLE_QUEUE_TAG 0x20
#define HEAD_OF_QUEUE_TAG 0x21
#define ORDERED_QUEUE_TAG 0x22
#define IGNORE_WIDE_RESIDUE 0x23
#define ACA 0x24
#define QAS_REQUEST 0x55
/* Old SCSI2 names, don't use in new code */
#define BUS_DEVICE_RESET TARGET_RESET
#define ABORT ABORT_TASK_SET
/*
* Host byte codes
*/
#define DID_OK 0x00 /* NO error */
#define DID_NO_CONNECT 0x01 /* Couldn't connect before timeout period */
#define DID_BUS_BUSY 0x02 /* BUS stayed busy through time out period */
#define DID_TIME_OUT 0x03 /* TIMED OUT for other reason */
#define DID_BAD_TARGET 0x04 /* BAD target. */
#define DID_ABORT 0x05 /* Told to abort for some other reason */
#define DID_PARITY 0x06 /* Parity error */
#define DID_ERROR 0x07 /* Internal error */
#define DID_RESET 0x08 /* Reset by somebody. */
#define DID_BAD_INTR 0x09 /* Got an interrupt we weren't expecting. */
#define DID_PASSTHROUGH 0x0a /* Force command past mid-layer */
#define DID_SOFT_ERROR 0x0b /* The low level driver just wish a retry */
#define DID_IMM_RETRY 0x0c /* Retry without decrementing retry count */
#define DID_REQUEUE 0x0d /* Requeue command (no immediate retry) also
* without decrementing the retry count */
#define DID_TRANSPORT_DISRUPTED 0x0e /* Transport error disrupted execution
* and the driver blocked the port to
* recover the link. Transport class will
* retry or fail IO */
#define DID_TRANSPORT_FAILFAST 0x0f /* Transport class fastfailed the io */
#define DID_TARGET_FAILURE 0x10 /* Permanent target failure, do not retry on
* other paths */
#define DID_NEXUS_FAILURE 0x11 /* Permanent nexus failure, retry on other
* paths might yield different results */
#define DID_ALLOC_FAILURE 0x12 /* Space allocation on the device failed */
#define DID_MEDIUM_ERROR 0x13 /* Medium error */
#define DRIVER_OK 0x00 /* Driver status */
/*
* These indicate the error that occurred, and what is available.
*/
#define DRIVER_BUSY 0x01
#define DRIVER_SOFT 0x02
#define DRIVER_MEDIA 0x03
#define DRIVER_ERROR 0x04
#define DRIVER_INVALID 0x05
#define DRIVER_TIMEOUT 0x06
#define DRIVER_HARD 0x07
#define DRIVER_SENSE 0x08
/*
* Internal return values.
*/
#define NEEDS_RETRY 0x2001
#define SUCCESS 0x2002
#define FAILED 0x2003
#define QUEUED 0x2004
#define SOFT_ERROR 0x2005
#define ADD_TO_MLQUEUE 0x2006
#define TIMEOUT_ERROR 0x2007
#define SCSI_RETURN_NOT_HANDLED 0x2008
#define FAST_IO_FAIL 0x2009
/*
* Midlevel queue return values.
*/
#define SCSI_MLQUEUE_HOST_BUSY 0x1055
#define SCSI_MLQUEUE_DEVICE_BUSY 0x1056
#define SCSI_MLQUEUE_EH_RETRY 0x1057
#define SCSI_MLQUEUE_TARGET_BUSY 0x1058
/*
* Use these to separate status msg and our bytes
*
* These are set by:
*
* status byte = set from target device
* msg_byte = return status from host adapter itself.
* host_byte = set by low-level driver to indicate status.
* driver_byte = set by mid-level.
*/
#define status_byte(result) (((result) >> 1) & 0x7f)
#define msg_byte(result) (((result) >> 8) & 0xff)
#define host_byte(result) (((result) >> 16) & 0xff)
#define driver_byte(result) (((result) >> 24) & 0xff)
#define sense_class(sense) (((sense) >> 4) & 0x7)
#define sense_error(sense) ((sense) & 0xf)
#define sense_valid(sense) ((sense) & 0x80)
/*
* default timeouts
*/
#define FORMAT_UNIT_TIMEOUT (2 * 60 * 60 * HZ)
#define START_STOP_TIMEOUT (60 * HZ)
#define MOVE_MEDIUM_TIMEOUT (5 * 60 * HZ)
#define READ_ELEMENT_STATUS_TIMEOUT (5 * 60 * HZ)
#define READ_DEFECT_DATA_TIMEOUT (60 * HZ )
#define IDENTIFY_BASE 0x80
#define IDENTIFY(can_disconnect, lun) (IDENTIFY_BASE |\
((can_disconnect) ? 0x40 : 0) |\
((lun) & 0x07))
/*
* struct scsi_device::scsi_level values. For SCSI devices other than those
* prior to SCSI-2 (i.e. over 12 years old) this value is (resp[2] + 1)
* where "resp" is a byte array of the response to an INQUIRY. The scsi_level
* variable is visible to the user via sysfs.
*/
#define SCSI_UNKNOWN 0
#define SCSI_1 1
#define SCSI_1_CCS 2
#define SCSI_2 3
#define SCSI_3 4 /* SPC */
#define SCSI_SPC_2 5
#define SCSI_SPC_3 6
/*
* INQ PERIPHERAL QUALIFIERS
*/
#define SCSI_INQ_PQ_CON 0x00
#define SCSI_INQ_PQ_NOT_CON 0x01
#define SCSI_INQ_PQ_NOT_CAP 0x03
/*
* Here are some scsi specific ioctl commands which are sometimes useful.
*
* Note that include/linux/cdrom.h also defines IOCTL 0x5300 - 0x5395
*/
/* Used to obtain PUN and LUN info. Conflicts with CDROMAUDIOBUFSIZ */
#define SCSI_IOCTL_GET_IDLUN 0x5382
/* 0x5383 and 0x5384 were used for SCSI_IOCTL_TAGGED_{ENABLE,DISABLE} */
/* Used to obtain the host number of a device. */
#define SCSI_IOCTL_PROBE_HOST 0x5385
/* Used to obtain the bus number for a device */
#define SCSI_IOCTL_GET_BUS_NUMBER 0x5386
/* Used to obtain the PCI location of a device */
#define SCSI_IOCTL_GET_PCI 0x5387
/* Pull a u32 out of a SCSI message (using BE SCSI conventions) */
static inline __u32 scsi_to_u32(__u8 *ptr)
{
return (ptr[0]<<24) + (ptr[1]<<16) + (ptr[2]<<8) + ptr[3];
}
#endif /* _SCSI_SCSI_H */

View file

@ -0,0 +1,84 @@
#ifndef __SCSI_CMND_H_
#define __SCSI_CMND_H_
#include "us_usb.h"
#include "us_os_wrap_via_osdep_api.h"
#include <scsi/scsi.h>
#include <scsi/dma_direction.h>
#include <scatterlist/scatterlist.h>
/**
* define flash block size
*/
#define BLOCK_SIZE 512
struct scsi_data_buffer {
struct sg_table table;
unsigned char *data_buffer; /* Data buffer to store read data */
unsigned length;
int resid;
};
struct scsi_cmnd{
int result; /* Status code from lower level driver */
unsigned int channel,id,lun;
enum dma_data_direction sc_data_direction;
unsigned short cmd_len;
unsigned length;
_Sema cmnd_done;
int eh_eflags; /* Used by error handlr */
struct scsi_data_buffer sdb;
unsigned long sector;/* Sector address in LBA */
unsigned int count;/* Number of sectors to read */
void *request_buffer;
/* These elements define the operation we are about to perform */
#define MAX_COMMAND_SIZE 16
unsigned char cmnd[MAX_COMMAND_SIZE];
#define SCSI_SENSE_BUFFERSIZE 96
unsigned char *sense_buffer; /* obtained by REQUEST SENSE
* when CHECK CONDITION is
* received on original command
* (auto-sense) */
/* Low-level done function - can be used by low-level driver to point
* to completion function. Not used by mid/upper level code. */
void (*scsi_done) (struct scsi_cmnd *);
unsigned underflow; /* Return error if less than
this amount is transferred */
};
static inline unsigned scsi_sg_count(struct scsi_cmnd *cmd)
{
return cmd->sdb.table.nents;
}
static inline struct scatterlist *scsi_sglist(struct scsi_cmnd *cmd)
{
return cmd->sdb.table.sgl;
}
static inline void scsi_set_resid(struct scsi_cmnd *cmd, int resid)
{
cmd->sdb.resid = resid;
}
//
static inline int scsi_get_resid(struct scsi_cmnd *cmd)
{
return cmd->sdb.resid;
}
static inline unsigned scsi_bufflen(struct scsi_cmnd *cmd)
{
return cmd->sdb.length;
}
extern int scsi_cmnd_execute(char cmnd, unsigned char * _buff,
unsigned long _sector, unsigned int _count);
#endif

View file

@ -0,0 +1,52 @@
#ifndef _SCSI_EH_H_
#define _SCSI_EH_H_
#include "scsi/scsi_cmnd.h"
#include "dma_direction.h"
#define BLK_MAX_CDB 16
/*
* This is a slightly modified SCSI sense "descriptor" format header.
* The addition is to allow the 0x70 and 0x71 response codes. The idea
* is to place the salient data from either "fixed" or "descriptor" sense
* format into one structure to ease application processing.
*
* The original sense buffer should be kept around for those cases
* in which more information is required (e.g. the LBA of a MEDIUM ERROR).
*/
struct scsi_sense_hdr { /* See SPC-3 section 4.5 */
u8 response_code; /* permit: 0x0, 0x70, 0x71, 0x72, 0x73 */
u8 sense_key;
u8 asc;
u8 ascq;
u8 byte4;
u8 byte5;
u8 byte6;
u8 additional_length; /* always 0 for fixed sense format */
};
static inline int scsi_sense_valid(struct scsi_sense_hdr *sshdr)
{
if (!sshdr)
return 0;
return (sshdr->response_code & 0x70) == 0x70;
}
struct scsi_eh_save {
/* saved state */
int result;
enum dma_data_direction data_direction;
unsigned underflow;
unsigned char cmd_len;
// unsigned char prot_op;
unsigned char cmnd[BLK_MAX_CDB];
struct scsi_data_buffer sdb;
// struct request *next_rq;
/* new command support */
unsigned char eh_cmnd[BLK_MAX_CDB];
// struct scatterlist sense_sgl;
};
const u8 * scsi_sense_desc_find(const u8 * sense_buffer, int sb_len,
int desc_type);
#endif

View file

@ -0,0 +1,78 @@
#ifndef __STORAGE_H
#define __STORAGE_H
#include "us_os_wrap_via_osdep_api.h"
/* Storage subclass codes */
#define USB_SC_RBC 0x01 /* Typically, flash devices */
#define USB_SC_8020 0x02 /* CD-ROM */
#define USB_SC_QIC 0x03 /* QIC-157 Tapes */
#define USB_SC_UFI 0x04 /* Floppy */
#define USB_SC_8070 0x05 /* Removable media */
#define USB_SC_SCSI 0x06 /* Transparent */
#define USB_SC_LOCKABLE 0x07 /* Password-protected */
#define USB_SC_ISD200 0xf0 /* ISD200 ATA */
#define USB_SC_CYP_ATACB 0xf1 /* Cypress ATACB */
#define USB_SC_DEVICE 0xff /* Use device's value */
/* Storage protocol codes */
#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 */
#define USB_PR_UAS 0x62 /* USB Attached SCSI */
#define USB_PR_USBAT 0x80 /* SCM-ATAPI bridge */
#define USB_PR_EUSB_SDDR09 0x81 /* SCM-SCSI bridge for SDDR-09 */
#define USB_PR_SDDR55 0x82 /* SDDR-55 (made up) */
#define USB_PR_DPCM_USB 0xf0 /* Combination CB/SDDR09 */
#define USB_PR_FREECOM 0xf1 /* Freecom */
#define USB_PR_DATAFAB 0xf2 /* Datafab chipsets */
#define USB_PR_JUMPSHOT 0xf3 /* Lexar Jumpshot */
#define USB_PR_ALAUDA 0xf4 /* Alauda chipsets */
#define USB_PR_KARMA 0xf5 /* Rio Karma */
#define USB_PR_DEVICE 0xff /* Use device's value */
/*
* Bulk only data structures
*/
/* command block wrapper */
struct bulk_cb_wrap {
__le32 Signature; /* contains 'USBC', denote bulk_cb_wrap */
__u32 Tag; /* unique per command id */
__le32 DataTransferLength; /* size of data for transfer */
__u8 Flags; /* data transfer direction */
__u8 Lun; /* LUN normally 0, (which command block is sent) */
__u8 Length; /* length of the CDB */
__u8 CDB[16]; /* max command */
};
#define US_BULK_CB_WRAP_LEN 31
#define US_BULK_CB_SIGN 0x43425355 /*spells out USBC */
#define US_BULK_FLAG_IN (1 << 7)
#define US_BULK_FLAG_OUT 0
/* command status wrapper */
struct bulk_cs_wrap {
__le32 Signature; /* should = 'USBS' */
__u32 Tag; /* same as original command, echoed by the device as received */
__le32 Residue; /* amount not transferred */
__u8 Status; /* execute command status */
};
#define US_BULK_CS_WRAP_LEN 13
#define US_BULK_CS_SIGN 0x53425355 /* spells out 'USBS' */
// execute command status
#define US_BULK_STAT_OK 0
#define US_BULK_STAT_FAIL 1
#define US_BULK_STAT_PHASE 2
/* bulk-only class specific requests */
#define US_BULK_RESET_REQUEST 0xff
#define US_BULK_GET_MAX_LUN 0xfe
#endif

View file

@ -0,0 +1,102 @@
/* Driver for USB Mass Storage compliant devices
* Transport Functions Header File
*
* Current development and maintenance by:
* (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
*
* This driver is based on the 'USB Mass Storage Class' document. This
* describes in detail the protocol used to communicate with such
* devices. Clearly, the designers had SCSI and ATAPI commands in
* mind when they created this document. The commands are all very
* similar to commands in the SCSI-II and ATAPI specifications.
*
* It is important to note that in a number of cases this class
* exhibits class-specific exemptions from the USB specification.
* Notably the usage of NAK, STALL and ACK differs from the norm, in
* that they are used to communicate wait, failed and OK on commands.
*
* Also, for certain devices, the interrupt endpoint is used to convey
* status of a command.
*
* Please see http://www.one-eyed-alien.net/~mdharm/linux-usb for more
* information about 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.
*/
#ifndef _US_TRANSPORT_H_
#define _US_TRANSPORT_H_
#if 0
#include <linux/blkdev.h>
#endif
/*
* usb_stor_bulk_transfer_xxx() return codes, in order of severity
*/
#define USB_STOR_XFER_GOOD 0 /* good transfer */
#define USB_STOR_XFER_SHORT 1 /* transferred less than expected */
#define USB_STOR_XFER_STALLED 2 /* endpoint stalled */
#define USB_STOR_XFER_LONG 3 /* device tried to send too much */
#define USB_STOR_XFER_ERROR 4 /* transfer died in the middle */
/*
* Transport return codes
*/
#define USB_STOR_TRANSPORT_GOOD 0 /* Transport good, command good */
#define USB_STOR_TRANSPORT_FAILED 1 /* Transport good, command failed */
#define USB_STOR_TRANSPORT_NO_SENSE 2 /* Command failed, no auto-sense */
#define USB_STOR_TRANSPORT_ERROR 3 /* Transport bad (i.e. device dead) */
/*
* We used to have USB_STOR_XFER_ABORTED and USB_STOR_TRANSPORT_ABORTED
* return codes. But now the transport and low-level transfer routines
* treat an abort as just another error (-ENOENT for a cancelled URB).
* It is up to the invoke_transport() function to test for aborts and
* distinguish them from genuine communication errors.
*/
/*
* CBI accept device specific command
*/
#define US_CBI_ADSC 0
//extern int usb_stor_CB_transport(struct scsi_cmnd *, struct us_data*);
//extern int usb_stor_CB_reset(struct us_data*);
//
//extern int usb_stor_Bulk_transport(struct scsi_cmnd *, struct us_data*);
//extern int usb_stor_Bulk_max_lun(struct us_data*);
//extern int usb_stor_Bulk_reset(struct us_data*);
//
//extern void usb_stor_invoke_transport(struct scsi_cmnd *, struct us_data*);
//extern void usb_stor_stop_transport(struct us_data*);
//extern int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
// u8 request, u8 requesttype, u16 value, u16 index,
// void *data, u16 size, int timeout);
//extern int usb_stor_clear_halt(struct us_data *us, unsigned int pipe);
//
//extern int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe,
// u8 request, u8 requesttype, u16 value, u16 index,
// void *data, u16 size);
//extern int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe,
// void *buf, unsigned int length, unsigned int *act_len);
//extern int usb_stor_bulk_transfer_sg(struct us_data *us, unsigned int pipe,
// void *buf, unsigned int length, int use_sg, int *residual);
//extern int usb_stor_bulk_srb(struct us_data* us, unsigned int pipe,
// struct scsi_cmnd* srb);
//
//extern int usb_stor_port_reset(struct us_data *us);
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,32 @@
#ifndef __UNUSUAL_USBAT_H
#define __UNUSUAL_USBAT_H
#if defined(CONFIG_USB_STORAGE_USBAT) || \
defined(CONFIG_USB_STORAGE_USBAT_MODULE)
UNUSUAL_DEV( 0x03f0, 0x0207, 0x0001, 0x0001,
"HP",
"CD-Writer+ 8200e",
USB_SC_8070, USB_PR_USBAT, init_usbat_cd, 0),
UNUSUAL_DEV( 0x03f0, 0x0307, 0x0001, 0x0001,
"HP",
"CD-Writer+ CD-4e",
USB_SC_8070, USB_PR_USBAT, init_usbat_cd, 0),
UNUSUAL_DEV( 0x04e6, 0x1010, 0x0000, 0x9999,
"Shuttle/SCM",
"USBAT-02",
USB_SC_SCSI, USB_PR_USBAT, init_usbat_flash,
US_FL_SINGLE_LUN),
UNUSUAL_DEV( 0x0781, 0x0005, 0x0005, 0x0005,
"Sandisk",
"ImageMate SDDR-05b",
USB_SC_SCSI, USB_PR_USBAT, init_usbat_flash,
US_FL_SINGLE_LUN),
#endif /* defined(CONFIG_USB_STORAGE_USBAT) || ... */
#endif

View file

@ -0,0 +1,26 @@
#ifndef _US_DEBUG_H_
#define _US_DEBUG_H_
#include "diag.h"
#define US_DEBUG 0
#define US_DRIVER "US_DRIVER"
#if US_DEBUG
#define US_INFO(fmt, args...) DBG_8195A("\n\r[%s]%s: " fmt, US_DRIVER, __FUNCTION__, ## args)
#define US_ERR(fmt, args...) DBG_8195A("\n\r[%s]%s: " fmt, US_DRIVER,__FUNCTION__, ## args)
#define US_WARN(fmt, args...) DBG_8195A("\n\r[%s]%s: " fmt, US_DRIVER,__FUNCTION__, ## args)
#define FUN_ENTER DBG_8195A("\n\r[%s]%s ==>\n", US_DRIVER,__FUNCTION__)
#define FUN_EXIT DBG_8195A("\n\r[%s]%s <==\n", US_DRIVER,__FUNCTION__)
#define FUN_TRACE DBG_8195A("\n\r[%s]%s:%d \n", US_DRIVER,__FUNCTION__, __LINE__)
#else
#define US_INFO(fmt, args...)
#define US_ERR(fmt, args...) DBG_8195A("\n\r[%s]%s: " fmt, US_DRIVER,__FUNCTION__, ## args)
#define US_WARN(fmt, args...)
#define FUN_ENTER
#define FUN_EXIT
#define FUN_TRACE
#endif
#endif /* _US_DEBUG_H_ */

View file

@ -0,0 +1,14 @@
#include "usb.h"
#include "transport.h"
/* This places the Shuttle/SCM USB<->SCSI bridge devices in multi-target
* mode */
int usb_stor_euscsi_init(struct us_data *us);
/* This function is required to activate all four slots on the UCR-61S2B
* flash reader */
int usb_stor_ucr61s2b_init(struct us_data *us);
/* This places the HUAWEI E220 devices in multi-port mode */
int usb_stor_huawei_e220_init(struct us_data *us);

View file

@ -0,0 +1,34 @@
#ifndef __US_INTF_H_
#define __US_INTF_H_
#include "basic_types.h"
typedef enum
{
MSC_OK = 0,
MSC_NOT_READY,
MSC_W_PROTECT,
MSC_ERROR,
}MSC_RESULT;
extern MSC_RESULT us_init(void);
extern MSC_RESULT us_isready (void);
extern MSC_RESULT us_getStatus(void);
extern MSC_RESULT us_getmaxlun (u8* lun_num);
extern MSC_RESULT us_unitisready (u8 lun);
extern MSC_RESULT us_inquiry (u8 *pbuf);
extern MSC_RESULT us_getcap(u32 *last_blk_addr, u32 *block_size);
extern MSC_RESULT us_read_blocks( u8 *pbuf, u32 sector, u32 count);
extern MSC_RESULT us_write_blocks( const u8 *pbuf, u32 sector, u32 count);
// indicate usb storage driver status
extern bool USB_STORAGE_READY;
#endif

View file

@ -0,0 +1,313 @@
/*
* umsc_os_wrap_via_osdep_api.h
*
* Created on: Sep 5, 2014
* Author: jimmysqf
*/
#ifndef US_OS_WRAP_VIA_OSDEP_API_H_
#define US_OS_WRAP_VIA_OSDEP_API_H_
#include "basic_types.h"
#include "osdep_api.h"
#define GFP_KERNEL 1
#define GFP_ATOMIC 1
typedef unsigned int gfp_t;
/* misc items */
#ifndef ssize_t
#define ssize_t SSIZE_T
#endif
#ifndef size_t
#define size_t SIZE_T
#endif
#ifndef __user
#define __user
#endif
#ifndef loff_t
#define loff_t long
#endif
#ifndef __u8
#define __u8 u8
#endif
#ifndef __u16
#define __u16 u16
#endif
#ifndef __u32
#define __u32 u32
#endif
#ifndef __u64
#define __u64 u64
#endif
#ifndef __s8
#define __s8 s8
#endif
#ifndef __s16
#define __s16 s16
#endif
#ifndef __s32
#define __s32 s32
#endif
#ifndef __s64
#define __s64 s64
#endif
typedef __u16 __le16;
typedef __u16 __be16;
typedef __u32 __le32;
typedef __u32 __be32;
typedef __u64 __le64;
typedef __u64 __be64;
typedef __u16 __sum16;
typedef __u32 __wsum;
#ifndef cpu_to_le32
#define cpu_to_le32(x) rtk_cpu_to_le32(x)
#endif
#ifndef le32_to_cpu
#define le32_to_cpu(x) rtk_le32_to_cpu(x)
#endif
#ifndef cpu_to_le16
#define cpu_to_le16(x) rtk_cpu_to_le16(x)
#endif
#ifndef le16_to_cpu
#define le16_to_cpu(x) rtk_le16_to_cpu(x)
#endif
#ifndef cpu_to_be32
#define cpu_to_be32(x) rtk_cpu_to_be32(x)
#endif
#ifndef be32_to_cpu
#define be32_to_cpu(x) rtk_be32_to_cpu(x)
#endif
#ifndef cpu_to_be16
#define cpu_to_be16(x) rtk_cpu_to_be16(x)
#endif
#ifndef be16_to_cpu
#define be16_to_cpu(x) rtk_be16_to_cpu(x)
#endif
#ifndef DIV_ROUND_UP
#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
#endif
#ifndef BITS_PER_LONG
#define BITS_PER_LONG (32)
#endif
#ifndef BITS_PER_LONG_LONG
#define BITS_PER_LONG_LONG (32)
#endif
#ifndef BIT
#define BIT(nr) (1UL << (nr))
#endif
#ifndef BIT_ULL
#define BIT_ULL(nr) (1ULL << (nr))
#endif
#ifndef BIT_MASK
#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
#endif
#ifndef BIT_WORD
#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
#endif
#ifndef BIT_ULL_MASK
#define BIT_ULL_MASK(nr) (1ULL << ((nr) % BITS_PER_LONG_LONG))
#endif
#ifndef BIT_ULL_WORD
#define BIT_ULL_WORD(nr) ((nr) / BITS_PER_LONG_LONG)
#endif
#ifndef BITS_PER_BYTE
#define BITS_PER_BYTE (8)
#endif
#ifndef BITS_TO_LONGS
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
#endif
#ifndef min
#define min(x, y) ((x) < (y) ? (x) : (y))
#endif
#ifndef max
#define max(x, y) ((x) > (y) ? (x) : (y))
#endif
#ifndef min_t
#define min_t(type, x, y) ({ \
type __min1 = (x); \
type __min2 = (y); \
__min1 < __min2 ? __min1 : __min2; })
#endif
#ifndef max_t
#define max_t(type, x, y) ({ \
type __max1 = (x); \
type __max2 = (y); \
__max1 > __max2 ? __max1 : __max2; })
#endif
/**
* container_of - cast a member of a structure out to the containing structure
* @p(ptr): the pointer to the member.
* @t(type): the type of the container struct this is embedded in.
* @m(member): the name of the member within the struct.
*
*/
#ifndef container_of
#define container_of(ptr, type, member) \
((type *)((char *)(ptr)-(SIZE_T)(&((type *)0)->member)))
#endif
/**
* test_bit - Determine whether a bit is set
* @nr: bit number to test
* @addr: Address to start counting from
*/
static inline int test_bit(int nr, const volatile unsigned long *addr)
{
return ((1UL << (nr & 31)) & (addr[nr >> 5])) != 0;
}
/**
* set_bit - Atomically set a bit in memory
* @nr: the bit to set
* @addr: the address to start counting from
*
* This function is atomic and may not be reordered. See __set_bit()
* if you do not require the atomic guarantees.
*
* Note: there are no guarantees that this function will not be reordered
* on non x86 architectures, so if you are writing portable code,
* make sure not to rely on its reordering guarantees.
*
* Note that @nr may be almost arbitrarily large; this function is not
* restricted to acting on a single-word quantity.
*/
static inline void set_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
SaveAndCli();
*p |= mask;
RestoreFlags();
}
/**
* clear_bit - Clears a bit in memory
* @nr: Bit to clear
* @addr: Address to start counting from
*
* clear_bit() is atomic and may not be reordered. However, it does
* not contain a memory barrier, so if it is used for locking purposes,
* you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
* in order to ensure changes are visible on other processors.
*/
static inline void clear_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
SaveAndCli();
*p &= ~mask;
RestoreFlags();
}
/**
* change_bit - Toggle a bit in memory
* @nr: Bit to change
* @addr: Address to start counting from
*
* change_bit() is atomic and may not be reordered. It may be
* reordered on other architectures than x86.
* Note that @nr may be almost arbitrarily large; this function is not
* restricted to acting on a single-word quantity.
*/
static inline void change_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
SaveAndCli();
*p ^= mask;
RestoreFlags();
}
/**
* test_and_set_bit - Set a bit and return its old value
* @nr: Bit to set
* @addr: Address to count from
*
* This operation is atomic and cannot be reordered.
* It may be reordered on other architectures than x86.
* It also implies a memory barrier.
*/
static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
unsigned long old;
SaveAndCli();
old = *p;
*p = old | mask;
RestoreFlags();
return (old & mask) != 0;
}
/**
* test_and_clear_bit - Clear a bit and return its old value
* @nr: Bit to clear
* @addr: Address to count from
*
* This operation is atomic and cannot be reordered.
* It can be reorderdered on other architectures other than x86.
* It also implies a memory barrier.
*/
static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
unsigned long old;
SaveAndCli();
old = *p;
*p = old & ~mask;
RestoreFlags();
return (old & mask) != 0;
}
/**
* test_and_change_bit - Change a bit and return its old value
* @nr: Bit to change
* @addr: Address to count from
*
* This operation is atomic and cannot be reordered.
* It also implies a memory barrier.
*/
static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
unsigned long old;
SaveAndCli();
old = *p;
*p = old ^ mask;
RestoreFlags();
return (old & mask) != 0;
}
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#endif
#endif /* US_OS_WRAP_VIA_OSDEP_API_H_ */

View file

@ -0,0 +1,19 @@
#ifndef _US_SCSI_H
#define _US_SCSI_H
/**
* define transfer length
*/
#define TRANS_LEN_READ_10 512
#define TRANS_LEN_WRITE_10 512
#define TRANS_LEN_INQUIRY 36
#define TRANS_LEN_TEST_UNIT_READY 0
#define TRANS_LEN_READ_CAPACITY_10 8
#define TRANS_LEN_READ_CAPACITY_16 12
#define TRANS_LEN_REQUEST_SENSE 18
#define TRANS_LEN_MODE_SENSE 192
extern int scsi_cmnd_execute(char cmnd, unsigned char * _buff,
unsigned long _sector, unsigned int _count);
#endif

View file

@ -0,0 +1,28 @@
#ifndef _US_STRINGS_H
#define _US_STRINGS_H
/* description of the sense key values */
static const char * const snstext[] = {
"No Sense", /* 0: There is no sense information */
"Recovered Error", /* 1: The last command completed successfully
but used error correction */
"Not Ready", /* 2: The addressed target is not ready */
"Medium Error", /* 3: Data error detected on the medium */
"Hardware Error", /* 4: Controller or device failure */
"Illegal Request", /* 5: Error in request */
"Unit Attention", /* 6: Removable medium was changed, or
the target has been reset, or ... */
"Data Protect", /* 7: Access to the data is blocked */
"Blank Check", /* 8: Reached unexpected written or unwritten
region of the medium */
"Vendor Specific(9)",
"Copy Aborted", /* A: COPY or COMPARE was aborted */
"Aborted Command", /* B: The target aborted the command */
"Equal", /* C: A SEARCH DATA command found data equal,
reserved in SPC-4 rev 36 */
"Volume Overflow", /* D: Medium full with still data to be written */
"Miscompare", /* E: Source data and data on the medium
do not agree */
"Completed", /* F: command completed sense data reported,
may occur for successful command */
};
#endif

View file

@ -0,0 +1,67 @@
/* Driver for USB Mass Storage compliant devices
* Transport Functions Header File
*/
#ifndef _US_TRANSPORT_H_
#define _US_TRANSPORT_H_
/*
* usb_stor_bulk_transfer_xxx() return codes, in order of severity
*/
#define USB_STOR_XFER_GOOD 0 /* good transfer */
#define USB_STOR_XFER_SHORT 1 /* transferred less than expected */
#define USB_STOR_XFER_STALLED 2 /* endpoint stalled */
#define USB_STOR_XFER_LONG 3 /* device tried to send too much */
#define USB_STOR_XFER_ERROR 4 /* transfer died in the middle */
/*
* Transport return codes
*/
#define USB_STOR_TRANSPORT_GOOD 0 /* Transport good, command good */
#define USB_STOR_TRANSPORT_FAILED 1 /* Transport good, command failed */
#define USB_STOR_TRANSPORT_NO_SENSE 2 /* Command failed, no auto-sense */
#define USB_STOR_TRANSPORT_ERROR 3 /* Transport bad (i.e. device dead) */
/*
* We used to have USB_STOR_XFER_ABORTED and USB_STOR_TRANSPORT_ABORTED
* return codes. But now the transport and low-level transfer routines
* treat an abort as just another error (-ENOENT for a cancelled URB).
* It is up to the invoke_transport() function to test for aborts and
* distinguish them from genuine communication errors.
*/
/*
* CBI accept device specific command
*/
#define US_CBI_ADSC 0
//extern int usb_stor_CB_transport(struct scsi_cmnd *, struct us_data*);
//extern int usb_stor_CB_reset(struct us_data*);
//
//extern int usb_stor_Bulk_transport(struct scsi_cmnd *, struct us_data*);
//extern int usb_stor_Bulk_max_lun(struct us_data*);
//extern int usb_stor_Bulk_reset(struct us_data*);
//
//extern void usb_stor_invoke_transport(struct scsi_cmnd *, struct us_data*);
//extern void usb_stor_stop_transport(struct us_data*);
//extern int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
// u8 request, u8 requesttype, u16 value, u16 index,
// void *data, u16 size, int timeout);
//extern int usb_stor_clear_halt(struct us_data *us, unsigned int pipe);
//
//extern int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe,
// u8 request, u8 requesttype, u16 value, u16 index,
// void *data, u16 size);
//extern int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe,
// void *buf, unsigned int length, unsigned int *act_len);
//extern int usb_stor_bulk_transfer_sg(struct us_data *us, unsigned int pipe,
// void *buf, unsigned int length, int use_sg, int *residual);
//extern int usb_stor_bulk_srb(struct us_data* us, unsigned int pipe,
// struct scsi_cmnd* srb);
//
//extern int usb_stor_port_reset(struct us_data *us);
#endif

View file

@ -0,0 +1,245 @@
#ifndef _US_USB_H_
#define _US_USB_H_
#include "usb.h"
#include "us_os_wrap_via_osdep_api.h"
#include "us_debug.h"
//#include "sg.h"
struct us_data;
struct scsi_cmnd;
#define CONFIG_SG 0
#define CONFIG_DMA 0
/*
* Unusual device list definitions
*/
struct us_unusual_dev {
const char* vendorName;
const char* productName;
__u8 useProtocol;
__u8 useTransport;
int (*initFunction)(struct us_data *);
};
/* Flag definitions: these entries are static */
#define US_FL_SINGLE_LUN 0x00000001 /* allow access to only LUN 0 */
//#define US_FL_MODE_XLATE 0 /* [no longer used] */
#define US_FL_NEED_OVERRIDE 0x00000004 /* unusual_devs entry is necessary */
//#define US_FL_IGNORE_SER 0 /* [no longer used] */
#define US_FL_SCM_MULT_TARG 0x00000020 /* supports multiple targets */
#define US_FL_FIX_INQUIRY 0x00000040 /* INQUIRY response needs faking */
#define US_FL_FIX_CAPACITY 0x00000080 /* READ CAPACITY response too big */
#define US_FL_IGNORE_RESIDUE 0x00000100 /* reported residue is wrong */
#define US_FL_BULK32 0x00000200 /* Uses 32-byte CBW length */
/* Dynamic bitflag definitions (us->dflags): used in set_bit() etc. */
#define US_FLIDX_URB_ACTIVE 0 /* current_urb is in use */
#define US_FLIDX_SG_ACTIVE 1 /* current_sg is in use */
#define US_FLIDX_ABORTING 2 /* abort is in progress */
#define US_FLIDX_DISCONNECTING 3 /* disconnect in progress */
#define US_FLIDX_RESETTING 4 /* device reset in progress */
#define US_FLIDX_TIMED_OUT 5 /* SCSI midlayer timed out */
#define US_FLIDX_SCAN_PENDING 6 /* scanning not yet done */
#define US_FLIDX_REDO_READ10 7 /* redo READ(10) command */
#define US_FLIDX_READ10_WORKED 8 /* previous READ(10) succeeded */
#define USB_STOR_STRING_LEN 32
/*
* We provide a DMA-mapped I/O buffer for use with small USB transfers.
* It turns out that CB[I] needs a 12-byte buffer and Bulk-only needs a
* 31-byte buffer. But Freecom needs a 64-byte buffer, so that's the
* size we'll allocate.
*/
#define US_IOBUF_SIZE 64 /* Size of the DMA-mapped I/O buffer */
#define US_SENSE_SIZE 18 /* Size of the autosense data buffer */
typedef int (*trans_cmnd)(struct scsi_cmnd *, struct us_data*);
typedef int (*trans_reset)(struct us_data*);
typedef void (*proto_cmnd)(struct scsi_cmnd*, struct us_data*);
typedef void (*extra_data_destructor)(void *); /* extra data destructor */
typedef void (*pm_hook)(struct us_data *, int); /* power management hook */
#define US_SUSPEND 0
#define US_RESUME 1
/* we allocate one of these for every device that we remember */
struct us_data {
/* The device we're working with
* It's important to note:
* (o) you must hold dev_mutex to change pusb_dev
*/
_Mutex dev_mutex;
struct usb_device *pusb_dev; /* this usb_device */
struct usb_interface *pusb_intf; /* this interface */
struct us_unusual_dev *unusual_dev; /* device-filter entry */
unsigned long fflags; /* fixed flags from filter */
unsigned long dflags; /* dynamic atomic bitflags */
unsigned int send_bulk_pipe; /* cached pipe values */
unsigned int recv_bulk_pipe;
unsigned int send_ctrl_pipe;
unsigned int recv_ctrl_pipe;
unsigned int recv_intr_pipe;
/* information about the device */
char *transport_name;
char *protocol_name;
__le32 bcs_signature;
u8 subclass;
u8 protocol;
u8 max_lun; // max number of logical unit (0,1,2,3...)
u8 ifnum; /* interface number */
u8 ep_bInterval; /* interrupt interval */
/* function pointers for this device */
trans_cmnd transport; /* transport function */
trans_reset transport_reset; /* transport device reset */
proto_cmnd proto_handler; /* protocol handler */
/* SCSI interfaces */
struct scsi_cmnd *srb; /* current srb */
unsigned int tag; /* current dCBWTag */
/* control and bulk communications data */
struct urb *current_urb; /* USB requests */
struct usb_ctrlrequest *cr; /* control requests */
// struct usb_sg_request current_sg; /* scatter-gather req. */
unsigned char *iobuf; /* I/O buffer */
dma_addr_t iobuf_dma; /* buffer DMA addresses */
xTaskHandle ctl_task; /*the control task handle*/
/* mutual exclusion and synchronization structures */
_Sema cmnd_ready; /* to sleep thread on */
_Mutex notify; /* thread begin/end */
unsigned no_sg_constraint:1; /* no sg constraint */
unsigned sg_tablesize; /* 0 or largest number of sg list entries */
/* subdriver information */
void *extra; /* Any extra data */
};
/* Convert between us_data and the corresponding Scsi_Host */
//static inline struct Scsi_Host *us_to_host(struct us_data *us) {
// return container_of((void *) us, struct Scsi_Host, hostdata);
//}
//static inline struct us_data *host_to_us(struct Scsi_Host *host) {
// return (struct us_data *) host->hostdata;
//}
/* Function to fill an inquiry response. See usb.c for details */
extern void fill_inquiry_response(struct us_data *us,
unsigned char *data, unsigned int data_len);
/* The scsi_lock() and scsi_unlock() macros protect the sm_state and the
* single queue element srb for write access */
//#define scsi_unlock(host) spin_unlock_irq(host->host_lock)
//#define scsi_lock(host) spin_lock_irq(host->host_lock)
#define scsi_unlock(host) spin_unlock(host->host_lock)
#define scsi_lock(host) spin_lock(host->host_lock)
/* General routines provided by the usb-storage standard core */
#ifdef CONFIG_PM
extern int usb_stor_suspend(struct usb_interface *iface, pm_message_t message);
extern int usb_stor_resume(struct usb_interface *iface);
extern int usb_stor_reset_resume(struct usb_interface *iface);
#else
#define usb_stor_suspend NULL
#define usb_stor_resume NULL
#define usb_stor_reset_resume NULL
#endif
extern int usb_stor_pre_reset(struct usb_interface *iface);
extern int usb_stor_post_reset(struct usb_interface *iface);
extern int usb_stor_probe1(struct us_data *us,
struct usb_interface *intf,
const struct usb_device_id *id,
struct us_unusual_dev *unusual_dev);
extern int usb_stor_probe2(struct us_data *us);
extern void usb_stor_disconnect(struct usb_interface *intf);
extern void usb_stor_adjust_quirks(struct usb_device *dev,
unsigned long *fflags);
// the follow definition should be prot to usb.h for other usb device
/* USB autosuspend and autoresume */
#ifdef CONFIG_PM_RUNTIME
extern void usb_enable_autosuspend(struct usb_device *udev);
extern void usb_disable_autosuspend(struct usb_device *udev);
extern int usb_autopm_get_interface(struct usb_interface *intf);
extern void usb_autopm_put_interface(struct usb_interface *intf);
extern int usb_autopm_get_interface_async(struct usb_interface *intf);
extern void usb_autopm_put_interface_async(struct usb_interface *intf);
extern void usb_autopm_get_interface_no_resume(struct usb_interface *intf);
extern void usb_autopm_put_interface_no_suspend(struct usb_interface *intf);
static inline void usb_mark_last_busy(struct usb_device *udev)
{
pm_runtime_mark_last_busy(&udev->dev);
}
#else
static inline int usb_enable_autosuspend(struct usb_device *udev)
{ return 0; }
static inline int usb_disable_autosuspend(struct usb_device *udev)
{ return 0; }
static inline int usb_autopm_get_interface(struct usb_interface *intf)
{ return 0; }
static inline int usb_autopm_get_interface_async(struct usb_interface *intf)
{ return 0; }
static inline void usb_autopm_put_interface(struct usb_interface *intf)
{ }
static inline void usb_autopm_put_interface_async(struct usb_interface *intf)
{ }
static inline void usb_autopm_get_interface_no_resume(
struct usb_interface *intf)
{ }
static inline void usb_autopm_put_interface_no_suspend(
struct usb_interface *intf)
{ }
static inline void usb_mark_last_busy(struct usb_device *udev)
{ }
#endif
/* USB port reset for device reinitialization */
extern int usb_reset_device(struct usb_device *dev);
extern void usb_queue_reset_device(struct usb_interface *dev);
extern void *usb_alloc_coherent(struct usb_device *dev, size_t size,
gfp_t mem_flags, dma_addr_t *dma);
extern void usb_free_coherent(struct usb_device *dev, size_t size,
void *addr, dma_addr_t dma);
// copy from transport.h
extern int usb_stor_CB_transport(struct scsi_cmnd *, struct us_data*);
extern int usb_stor_CB_reset(struct us_data*);
extern int usb_stor_Bulk_transport(struct scsi_cmnd *, struct us_data*);
extern int usb_stor_Bulk_max_lun(struct us_data*);
extern int usb_stor_Bulk_reset(struct us_data*);
extern void usb_stor_invoke_transport(struct scsi_cmnd *, struct us_data*);
extern void usb_stor_stop_transport(struct us_data*);
// copy form protocol.h
extern void usb_stor_transparent_scsi_command(struct scsi_cmnd* srb, struct us_data* );
extern unsigned char usb_stor_sense_invalidCDB[18];
#endif

View file

@ -0,0 +1,37 @@
#ifndef __US_USUAL_H
#define __US_USUAL_H
#include "usb.h"
#include "storage.h"
#define US_FL_SINGLE_LUN 0x00000001/* allow access to only LUN 0 */
//#define US_FL_NEED_OVERRIDE 0x00000002/* unusual_devs entry is necessary */
//#define US_FL_SCM_MULT_TARG 0x00000004/* supports multiple targets */
//#define US_FL_FIX_INQUIRY 0x00000008/* INQUIRY response needs faking */
//#define US_FL_FIX_CAPACITY 0x00000010/* READ CAPACITY response too big */
//#define US_FL_IGNORE_RESIDUE 0x00000020/* reported residue is wrong */
//#define US_FL_BULK32 0x00000040/* Uses 32-byte CBW length */
#define US_FL_NOT_LOCKABLE 0x00000080/* PREVENT/ALLOW not supported */
#define US_FL_GO_SLOW 0x00000100/* Need delay after Command phase */
#define US_FL_NO_WP_DETECT 0x00000200/* Don't check for write-protect */
#define US_FL_MAX_SECTORS_64 0x00000400/* Sets max_sectors to 64 */
#define US_FL_IGNORE_DEVICE 0x00000800/* Don't claim device */
#define US_FL_CAPACITY_HEURISTICS 0x00001000/* sometimes sizes is too big */
#define US_FL_MAX_SECTORS_MIN 0x00002000/* Sets max_sectors to arch min */
#define US_FL_BULK_IGNORE_TAG 0x00004000/* Ignore tag mismatch in bulk operations */
#define US_FL_SANE_SENSE 0x00008000/* Sane Sense (> 18 bytes) */
#define US_FL_CAPACITY_OK 0x00010000/* READ CAPACITY response is correct */
#define US_FL_BAD_SENSE 0x00020000/* Bad Sense (never more than 18 bytes) */
#define US_FL_NO_READ_DISC_INFO 0x00040000/* cannot handle READ_DISC_INFO */
#define US_FL_NO_READ_CAPACITY_16 0x00080000/* cannot handle READ_CAPACITY_16*/
#define US_FL_INITIAL_READ10 0x00100000/* Initial READ(10) (and others) must be retried */
#define US_FL_WRITE_CACHE 0x00200000/* Write Cache status is not available */
#define US_FL_NEEDS_CAP16 0x00400000/* cannot handle READ_CAPACITY_10 */
#define US_FL_IGNORE_UAS 0x00800000/* Device advertises UAS but it is broken */
#define US_FL_BROKEN_FUA 0x01000000/* Cannot handle FUA in WRITE or READ CDBs */
extern int usb_usual_ignore_device(struct usb_interface *intf);
extern struct usb_device_id usb_storage_usb_ids[];
#endif /* __US_USUAL_H */

View file

@ -0,0 +1,41 @@
#ifndef _MJPEG_API_H
#define _MJPEG_API_H
/* memory disk type */
typedef enum _medium_type{
medium_SD,
medium_USB,
medium_FLASH,
medium_CACHE
}medium_type;
/* time unit*/
typedef enum _time_unit{
unit_HR, // hour
unit_MIN, // minute
unit_SEC, //second
}time_unit;
typedef struct _mjpeg_cache{
unsigned char* addr;
int size;
}mjpeg_cache;
struct mjpeg_context{
/* mjpeg size*/
int width;//frame width
int height;//frame height
/* */
medium_type disktype;
time_unit timeunit;
int interval;
unsigned char* name;
unsigned char is_periodic;
/* store mjpeg in a RAM cache */
mjpeg_cache cache;
};
int mjpeg_get(struct mjpeg_context *context);
#endif

View file

@ -38,6 +38,7 @@ int uvc_stream_init(void); //entry function to start uvc
void uvc_stream_free(void); // free streaming resources
int uvc_is_stream_ready(void); // return true if uvc device is initialized successfully
int uvc_is_stream_on(void); //return true if uvc device is streaming now
int uvc_is_stream_off(void); //return true if uvc device is free already
int uvc_stream_on(void); //enable camera streaming
void uvc_stream_off(void); //disable camera streaming
int uvc_set_param(uvc_fmt_t fmt_type, int *width, int *height, int *frame_rate, int *compression_ratio);//set camera streaming video parameters:video format, resolution and frame rate.

View file

@ -335,10 +335,10 @@ static inline __u16 le16_to_cpup(const __le16 *p)
#endif
#ifndef copy_from_user
#define copy_from_user(to, from, sz) RtlMemcpy((to), (from), (sz))
#define copy_from_user(to, from, sz) _memcpy((to), (from), (sz))
#endif
#ifndef copy_to_user
#define copy_to_user(to, from, sz) RtlMemcpy((to), (from), (sz))
#define copy_to_user(to, from, sz) _memcpy((to), (from), (sz))
#endif
typedef u32 compat_caddr_t; //used for compatibility in uvc_v4l2.c
@ -354,6 +354,7 @@ typedef u32 compat_caddr_t; //used for compatibility in uvc_v4l2.c
* of course, the buffer size is zero). It does not pad
* out the result like strncpy() does.
*/
#ifndef __GNUC__
static inline size_t strlcpy(char *dest, const char *src, size_t size)
{
size_t ret = _strlen(src);
@ -365,6 +366,7 @@ static inline size_t strlcpy(char *dest, const char *src, size_t size)
}
return ret;
}
#endif
/**
* clamp - return a value clamped to a given range with strict typechecking
@ -505,6 +507,7 @@ static inline size_t memweight(const void *ptr, size_t bytes)
* @src: The string to append to it
* @count: The size of the destination buffer.
*/
#ifndef __GNUC__
static inline size_t strlcat(char *dest, const char *src, size_t count)
{
size_t dsize = _strlen(dest);
@ -522,7 +525,7 @@ static inline size_t strlcat(char *dest, const char *src, size_t count)
dest[len] = 0;
return res;
}
#endif
/**
* atomic_dec_and_test - decrement and test