ameba micropython sdk first commit

This commit is contained in:
xidameng 2020-07-31 22:16:12 +08:00
commit 8508ee6139
5619 changed files with 1874619 additions and 0 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...) DBG_8195A("\n\r[%s]%s: " fmt, __FUNCTION__, ## args)
#define ETH_ERROR(fmt, args...) DBG_8195A("\n\r[%s]%s: " fmt, __FUNCTION__, ## args)
#define ETH_WARM(fmt, args...) DBG_8195A("\n\r[%s]%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 ETH_PRINT(fmt, args...)
#define ETH_ERROR(fmt, args...) DBG_8195A("\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,30 @@
#ifndef _USB_ETH_OPTS_H
#define _USB_ETH_OPTS_H
#define CONFIG_WLAN2ETH_THREAD 0
#define CONFIG_ETH2WLAN_THREAD 0
#define CONFIG_RX_AGGREGATION
#define CONFIG_TX_AGGREGATION
// RX aggregation
#ifdef CONFIG_RX_AGGREGATION
#define NR_RX_SKB_PERBUF 3
#define CONFIG_RX_TIMER 1
#define CONFIG_USE_GDMA 0 // use multi-block gdma to do aggregation
#if CONFIG_RX_TIMER
#define CONFIG_RX_SW_TIMER 0
#define CONFIG_RX_HW_TIMER 1
#endif
#else
#define NR_RX_SKB_PERBUF 1
#endif
// TX aggregation
#ifdef CONFIG_TX_AGGREGATION
#define NR_TX_SKB_PERBUF 3
#else
#define NR_TX_SKB_PERBUF 1
#endif
#endif //_USB_ETH_OPTS_H

View file

@ -0,0 +1,453 @@
/*
* 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"
#include "usb_eth_opts.h"
//#define DRIVER_DESC "Ethernet Gadget"
#define DRIVER_DESC "USB Network Interface"
#define DRIVER_VERSION "May Day 2015"
#define ETH_ADDR "00E04C8196C8"
#define ETH_FRAME_LEN 0x5EA
#if 0
OTG_ROM_DATA_SECTION
static const char shortname [] = "ether";
OTG_ROM_DATA_SECTION
static const char driver_desc [] = DRIVER_DESC;
#endif
#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 */
#if 0
START_OTG_RAM_DATA_SECTION
static char manufacturer [50];
START_OTG_RAM_DATA_SECTION
static char product_desc [40] = DRIVER_DESC;
START_OTG_RAM_DATA_SECTION
static char serial_number [20];
#endif
/* address that the host will use ... usually assigned at random */
//ModifiedByJD static char ethaddr [2 * ETH_ALEN + 1];
#if 0
START_OTG_RAM_DATA_SECTION
static char ethaddr [2 * 6 + 1] = ETH_ADDR;
#endif
/* static strings, in UTF-8 */
#if 0
START_OTG_RAM_DATA_SECTION
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 */
};
#endif
#if 0
static struct usb_gadget_strings stringtab = {
.language = 0x0409, /* en-us */
.strings = strings,
};
static struct usb_gadget_strings *dev_strings[] = {
&stringtab,
NULL,
};
START_OTG_RAM_DATA_SECTION
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,
};
START_OTG_RAM_DATA_SECTION
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,
};
START_OTG_RAM_DATA_SECTION
static struct usb_otg_descriptor
otg_descriptor = {
.bLength = sizeof otg_descriptor,
.bDescriptorType = USB_DT_OTG,
.bmAttributes = USB_OTG_SRP,
};
#endif
#if 0
#ifdef CONFIG_USB_ETH_RNDIS
/* RNDIS doesn't activate by changing to the "real" altsetting */
START_OTG_RAM_DATA_SECTION
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
START_OTG_RAM_DATA_SECTION
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
};
START_OTG_RAM_DATA_SECTION
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
};
START_OTG_RAM_DATA_SECTION
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,
};
START_OTG_RAM_DATA_SECTION
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,
};
OTG_ROM_DATA_SECTION
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,
};
OTG_ROM_DATA_SECTION
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
OTG_ROM_DATA_SECTION
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
START_OTG_RAM_DATA_SECTION
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,
};
#endif
struct rx_frame{
dwc_list_link_t list;
struct sk_buff* skb;
u8 cmd;
u16 pkt_len;
u8* buf_addr;
u8* pbuf;
u8* priv;
u8 status;
};
struct tx_frame{
dwc_list_link_t list;
struct usb_request *req;
u16 pkt_len;
u8* priv;
u8 status;
};
// indicate packages type
enum{
PKTS_CMD = 0,
PKTS_DATA
};
// inidicate frame status
enum{
FRAME_INITED = 0,
FRAME_QUEUED,
FRAME_DONE,
FRAME_FAIL
};
struct usb_queue{
_Mutex mutex;
dwc_list_link_t list;
};
#define MAX_PKT_LEN 1538 //
#define USB_DMA_ALIGN_4 4
#define BO_BUFF_SZ NR_TX_SKB_PERBUF*MAX_PKT_LEN
#define BI_BUFF_SZ NR_RX_SKB_PERBUF*MAX_PKT_LEN
#define VENDOR_WRITEN 0x00 //vendor memory wirte
#define VENDOR_READN 0x01 //vendor memory read
#define VENDOR_DEV_ISREADY 0x02 // device is ready or not
enum {
FW_READY_NOT = 0,
FW_READY_YES = 1
};
#include "timer_api.h"
#include "dma_api.h"
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
_Mutex eth_mutex;
struct usb_function func;
u8 usb_cmd; // this for usb common command
/*send (depends on host)*/
_Sema xmit_sema;
xTaskHandle xmit_task;
u8 tx_qlen;
_Mutex xmit_mutex;
dwc_list_link_t tx_reqs;
dwc_list_link_t tx_act_reqs;
u32 tx_dropped;
struct usb_queue tx_frame_pending_que;
/*receive (debuf_poolpends on host)*/
_Sema recv_sema;
xTaskHandle recv_task;
_Mutex recv_mutex;
dwc_list_link_t rx_reqs;
dwc_list_link_t rx_act_reqs;
u32 rx_dropped;
u8 rx_qlen;
struct usb_queue rx_frame_pending_que;
#ifdef CONFIG_RX_AGGREGATION
#if CONFIG_RX_TIMER
#if CONFIG_RX_HW_TIMER
gtimer_t rx_agg_timer;
#elif CONFIG_RX_SW_TIMER
PRTL_TIMER rx_agg_timer;
#endif
u8 timer_scheduled;
xTaskHandle timer_task;
_Sema timer_sema;
#endif
#if CONFIG_USE_GDMA
gdma_t gdma;
#endif
#endif
// define fucntion point to remove resource in ram code
void (*remove_all)(void);
};
extern _LONG_CALL_ int usb_eth_init(void);
extern _LONG_CALL_ int usb_eth_deinit(void);
void _LONG_CALL_ usb_eth_rx(void *pPackage, u16 pPktsize, u8 CmdType);
#endif

View file

@ -0,0 +1,136 @@
#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 defined(CONFIG_PLATFORM_8195BHP)
#if USBD_MSC_DEBUG
#define USBD_PRINTF(fmt, args...) DBG_8195BL("\n\r%s: " fmt, __FUNCTION__, ## args)
#define USBD_ERROR(fmt, args...) DBG_8195BL("\n\r%s: " fmt, __FUNCTION__, ## args)
#define USBD_WARN(fmt, args...) DBG_8195BL("\n\r%s: " fmt, __FUNCTION__, ## args)
#define FUN_ENTER DBG_8195BL("\n\r%s ==>\n", __func__)
#define FUN_EXIT DBG_8195BL("\n\r%s <==\n", __func__)
#define FUN_TRACE DBG_8195BL("\n\r%s:%d \n", __func__, __LINE__)
#else
#define USBD_PRINTF(fmt, args...)
#define USBD_ERROR(fmt, args...) DBG_8195BL("\n\r%s: " fmt, __FUNCTION__, ## args)
#define USBD_WARN(fmt, args...)
#define FUN_ENTER
#define FUN_EXIT
#define FUN_TRACE
#endif
#else
#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
#endif
/* MSC Request Codes */
#define MSC_REQUEST_RESET 0xFF
#define MSC_REQUEST_GET_MAX_LUN 0xFE
struct blank_common{
struct blank_dev *blankdev;
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 */
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;
/**/
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 blank_dev{
struct blank_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;
struct usb_function func;
};
static u32 min(u32 value1,u32 value2);
/*
* N_bh : number of buffer header
* Size_bh: buffer size per buffer
* type:msc physical disk type
*/
int usbd_blank_init(void);
void usbd_blank_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,183 @@
#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_blank_strings [] = {
{ STRING_MANUFACTURER, string_manufacturer, },
{ STRING_PRODUCT, string_product, },
{ STRING_SERIALNUMBER, string_serial, },
{ STRING_INTERFACE, "USB BLANK Interface", },
{ STRING_MSC, "USB BLANK", },
};
struct usb_gadget_strings blank_stringtab = {
.language = 0x0409, /* en-us */
.strings = usbd_blank_strings,
};
struct usb_gadget_strings *dev_blank_strings[] = {
&blank_stringtab,
NULL,
};
static struct usb_device_descriptor
usbd_blank_device_desc = {
.bLength = sizeof usbd_blank_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 USBD_HS_ENABLE
/* USB Device Qualifier Descriptor (for Full Speed) */
static struct usb_qualifier_descriptor
usbd_blank_qualifier_desc_FS = {
.bLength = sizeof usbd_blank_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_blank_qualifier_desc_HS = {
.bLength = sizeof usbd_blank_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_blank_qualifier_desc_FS = { 0 };
/* USB Device Qualifier Descriptor for High Speed */
static struct usb_qualifier_descriptor
usbd_blank_qualifier_desc_HS = { 0 };
#endif
/* MSC Interface, Alternate Setting 0*/
struct usb_interface_descriptor
usbd_blank_intf_desc = {
.bLength = sizeof usbd_blank_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_blank_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_blank_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_blank_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_blank_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_blank_descriptors_FS [] = {
/* data interface has no altsetting */
(struct usb_descriptor_header *) &usbd_blank_intf_desc,
(struct usb_descriptor_header *) &usbd_blank_source_desc_FS,
(struct usb_descriptor_header *) &usbd_blank_sink_desc_FS,
NULL,
};
struct usb_descriptor_header *usbd_blank_descriptors_HS [] = {
/* data interface has no altsetting */
(struct usb_descriptor_header *) &usbd_blank_intf_desc,
(struct usb_descriptor_header *) &usbd_blank_source_desc_HS,
(struct usb_descriptor_header *) &usbd_blank_sink_desc_HS,
NULL,
};

View file

@ -0,0 +1,211 @@
#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 1
#if defined(CONFIG_PLATFORM_8195BHP)
#if USBD_MSC_DEBUG
#define USBD_PRINTF(fmt, args...) DBG_8195BL("\n\r%s: " fmt, __FUNCTION__, ## args)
#define USBD_ERROR(fmt, args...) DBG_8195BL("\n\r%s: " fmt, __FUNCTION__, ## args)
#define USBD_WARN(fmt, args...) DBG_8195BL("\n\r%s: " fmt, __FUNCTION__, ## args)
#define FUN_ENTER DBG_8195BL("\n\r%s ==>\n", __func__)
#define FUN_EXIT DBG_8195BL("\n\r%s <==\n", __func__)
#define FUN_TRACE DBG_8195BL("\n\r%s:%d \n", __func__, __LINE__)
#else
#define USBD_PRINTF(fmt, args...)
#define USBD_ERROR(fmt, args...) DBG_8195BL("\n\r%s: " fmt, __FUNCTION__, ## args)
#define USBD_WARN(fmt, args...)
#define FUN_ENTER
#define FUN_EXIT
#define FUN_TRACE
#endif
#else
#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
#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;
#if (defined(CONFIG_PLATFORM_8195BHP) || defined (CONFIG_PLATFORM_8721D))
#include "sd.h"
struct msc_opts{
SD_RESULT (*disk_init)(void);
SD_RESULT (*disk_deinit)(void);
SD_RESULT (*disk_getcapacity)(u32* sectors);
SD_RESULT (*disk_read)(u32 sector,u8 *buffer,u32 count);
SD_RESULT (*disk_write)(u32 sector,const u8 *buffer,u32 count);
};
#else
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);
};
#endif
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* prebuf;
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

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,73 @@
#ifndef USBD_MSC_H
#define USBD_MSC_H
#include "usb.h"
#include "usb_gadget.h"
#include "core/inc/usb_composite.h"
#if defined (CONFIG_PLATFORM_8721D)
#include "ameba_otg.h"
#else
#include "rtl8195a_otg.h"
#endif
/* config usb msc device debug inforation */
#define USBD_VENDOR_DEBUG 1
#if USBD_VENDOR_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
struct vend_common;
struct vend_dev;
#define VEN_NUM_REQUESTS 2
struct ven_common{
struct ven_dev *vendev;
struct usb_gadget *gadget;
struct usb_ep *ep0;
struct usb_request *req0; /* for control responses */
unsigned int running;
};
struct ven_dev {
struct ven_common *common;
struct usb_function func;
struct usb_ep *in_ep;
struct usb_ep *out_ep;
struct usb_ep *iso_in_ep;
struct usb_ep *iso_out_ep;
/* Requests */
unsigned int req_size;
struct usb_iso_request *req;
unsigned char *req_buffer[VEN_NUM_REQUESTS];
struct usb_iso_request *req_in;
unsigned char *req_buffer_in[VEN_NUM_REQUESTS];
};
/*
* N_bh : number of buffer header
* Size_bh: buffer size per buffer
* type:msc physical disk type
*/
int usbd_vendor_init(int N_bh, int Size_bh, int type);
void usbd_vendor_deinit(void);
#endif

View file

@ -0,0 +1,258 @@
#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_VENDOR 5
#define DEV_CONFIG_VALUE 1
#define DRIVER_DESC "USB Vendor"
#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_vendor_strings [] = {
{ STRING_MANUFACTURER, string_manufacturer, },
{ STRING_PRODUCT, string_product, },
{ STRING_SERIALNUMBER, string_serial, },
{ STRING_INTERFACE, "USB VENDOR Interface", },
{ STRING_VENDOR, "USB VENDOR", },
};
struct usb_gadget_strings vendor_stringtab = {
.language = 0x0409, /* en-us */
.strings = usbd_vendor_strings,
};
struct usb_gadget_strings *dev_vendor_strings[] = {
&vendor_stringtab,
NULL,
};
static struct usb_device_descriptor
usbd_vendor_device_desc = {
.bLength = sizeof usbd_vendor_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 = 0x0525,
.idProduct = 0xa4a0,
// .bcdDevice = ,
.iManufacturer = STRING_MANUFACTURER,
.iProduct = STRING_PRODUCT,
.iSerialNumber = STRING_SERIALNUMBER,
.bNumConfigurations=0x01,
};
#if USBD_HS_ENABLE
/* USB Device Qualifier Descriptor (for Full Speed) */
static struct usb_qualifier_descriptor
usbd_vendor_qualifier_desc_FS = {
.bLength = sizeof usbd_vendor_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_vendor_qualifier_desc_HS = {
.bLength = sizeof usbd_vendor_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_vendor_qualifier_desc_FS = { 0 };
/* USB Device Qualifier Descriptor for High Speed */
static struct usb_qualifier_descriptor
usbd_vendor_qualifier_desc_HS = { 0 };
#endif
/* MSC Interface, Alternate Setting 0*/
struct usb_interface_descriptor
usbd_vendor_intf0_desc = {
.bLength = sizeof usbd_vendor_intf0_desc,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = 0x00, // this will be assign automatically
.bAlternateSetting =0x00,
.bNumEndpoints = 0x04,
.bInterfaceClass = USB_CLASS_VENDOR_SPEC,
.bInterfaceSubClass = 0,
.bInterfaceProtocol = 0,
.iInterface = STRING_INTERFACE,
};
struct usb_interface_descriptor
usbd_vendor_intf1_desc = {
.bLength = sizeof usbd_vendor_intf1_desc,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = 0x00, // this will be assign automatically
.bAlternateSetting =0x01,
.bNumEndpoints = 0x02,
.bInterfaceClass = USB_CLASS_VENDOR_SPEC,
.bInterfaceSubClass = 0,
.bInterfaceProtocol = 0,
.iInterface = STRING_INTERFACE,
};
/* MSC Endpoints for Low-speed/Full-speed */
/* Endpoint, EP Bulk IN */
struct usb_endpoint_descriptor
usbd_vendor_bulk_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_vendor_bulk_sink_desc_FS = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_OUT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
.wMaxPacketSize = (512),
.bInterval = 0x00,
};
/* MSC Endpoints for High-speed */
/* Endpoint, EP Bulk IN */
struct usb_endpoint_descriptor
usbd_vendor_bulk_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_vendor_bulk_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,
};
/* MSC Endpoints for Low-speed/Full-speed */
/* Endpoint, EP Bulk IN */
struct usb_endpoint_descriptor
usbd_vendor_iso_source_desc_FS = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = 0X05,
.wMaxPacketSize = (128),
.bInterval = 0x01,
};
/* Endpoint, EP Bulk OUT */
struct usb_endpoint_descriptor
usbd_vendor_iso_sink_desc_FS = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_OUT,
.bmAttributes = 0X05,
.wMaxPacketSize = (512),
.bInterval = 0x01,
};
/* MSC Endpoints for High-speed */
/* Endpoint, EP Bulk IN */
struct usb_endpoint_descriptor
usbd_vendor_iso_source_desc_HS = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = 0X05,
.wMaxPacketSize = (512),
.bInterval = 0x02,
};
/* Endpoint, EP Bulk OUT */
struct usb_endpoint_descriptor
usbd_vendor_iso_sink_desc_HS = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_OUT,
.bmAttributes = 0X05,
.wMaxPacketSize = (512),
.bInterval = 0x02,
};
struct usb_descriptor_header *usbd_vendor_descriptors_FS [] = {
/* data interface has no altsetting */
(struct usb_descriptor_header *) &usbd_vendor_intf0_desc,
(struct usb_descriptor_header *) &usbd_vendor_bulk_source_desc_FS,
(struct usb_descriptor_header *) &usbd_vendor_bulk_sink_desc_FS,
(struct usb_descriptor_header *) &usbd_vendor_iso_source_desc_FS,
(struct usb_descriptor_header *) &usbd_vendor_iso_sink_desc_FS,
(struct usb_descriptor_header *) &usbd_vendor_intf1_desc,
(struct usb_descriptor_header *) &usbd_vendor_bulk_source_desc_FS,
(struct usb_descriptor_header *) &usbd_vendor_bulk_sink_desc_FS,
NULL,
};
struct usb_descriptor_header *usbd_vendor_descriptors_HS [] = {
/* data interface has no altsetting */
(struct usb_descriptor_header *) &usbd_vendor_intf0_desc,
(struct usb_descriptor_header *) &usbd_vendor_bulk_source_desc_HS,
(struct usb_descriptor_header *) &usbd_vendor_bulk_sink_desc_HS,
(struct usb_descriptor_header *) &usbd_vendor_iso_source_desc_HS,
(struct usb_descriptor_header *) &usbd_vendor_iso_sink_desc_HS,
(struct usb_descriptor_header *) &usbd_vendor_intf1_desc,
(struct usb_descriptor_header *) &usbd_vendor_bulk_source_desc_HS,
(struct usb_descriptor_header *) &usbd_vendor_bulk_sink_desc_HS,
NULL,
};

View file

@ -0,0 +1,19 @@
#ifndef ISOOUT_TEST_H
#define ISOOUT_TEST_H
/******************************************************/
/* Control define */
/******************************************************/
#define USBH_ENABLE_ISOIN
#define USBH_ENABLE_ISOOUT
//--
#define USBD_ENABE_ISOIN_USB_REQ_ISO_ASAP
//#define USBD_ENABE_ISOOUT_USB_REQ_ISO_ASAP
/******************************************************/
/* Parameter define */
/******************************************************/
#define USB_ISOOUT_TRANSFER_CNT 100
#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,402 @@
#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 */
#ifndef TYPE_LOCK
#define TYPE_LOCK
typedef u32 _Lock;
#endif
/* 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,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,319 @@
/*
* 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"
#if !defined (CONFIG_PLATFORM_8721D)
#include "osdep_api.h"
#endif
#define GFP_KERNEL 1
#define GFP_ATOMIC 1
#if defined (CONFIG_PLATFORM_8721D)
#define RestoreFlags() portEXIT_CRITICAL()
#define SaveAndCli() portENTER_CRITICAL()
#endif
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,71 @@
#ifndef __LINUX_UVCVIDEO_H_
#define __LINUX_UVCVIDEO_H_
#if 0
#include <linux/ioctl.h>
#include <linux/types.h>
#endif
#include "uvc_os_wrap_via_osdep_api.h"
/*
* Dynamic controls
*/
/* Data types for UVC control data */
#define UVC_CTRL_DATA_TYPE_RAW 0
#define UVC_CTRL_DATA_TYPE_SIGNED 1
#define UVC_CTRL_DATA_TYPE_UNSIGNED 2
#define UVC_CTRL_DATA_TYPE_BOOLEAN 3
#define UVC_CTRL_DATA_TYPE_ENUM 4
#define UVC_CTRL_DATA_TYPE_BITMASK 5
/* Control flags */
#define UVC_CTRL_FLAG_SET_CUR (1 << 0)
#define UVC_CTRL_FLAG_GET_CUR (1 << 1)
#define UVC_CTRL_FLAG_GET_MIN (1 << 2)
#define UVC_CTRL_FLAG_GET_MAX (1 << 3)
#define UVC_CTRL_FLAG_GET_RES (1 << 4)
#define UVC_CTRL_FLAG_GET_DEF (1 << 5)
/* Control should be saved at suspend and restored at resume. */
#define UVC_CTRL_FLAG_RESTORE (1 << 6)
/* Control can be updated by the camera. */
#define UVC_CTRL_FLAG_AUTO_UPDATE (1 << 7)
#define UVC_CTRL_FLAG_GET_RANGE \
(UVC_CTRL_FLAG_GET_CUR | UVC_CTRL_FLAG_GET_MIN | \
UVC_CTRL_FLAG_GET_MAX | UVC_CTRL_FLAG_GET_RES | \
UVC_CTRL_FLAG_GET_DEF)
struct uvc_menu_info {
__u32 value;
__u8 name[32];
};
struct uvc_xu_control_mapping {
__u32 id;
__u8 name[32];
__u8 entity[16];
__u8 selector;
__u8 size;
__u8 offset;
__u32 v4l2_type;
__u32 data_type;
struct uvc_menu_info __user *menu_info;
__u32 menu_count;
__u32 reserved[4];
};
struct uvc_xu_control_query {
__u8 unit;
__u8 selector;
__u8 query; /* Video Class-Specific Request Code, */
/* defined in linux/usb/video.h A.8. */
__u16 size;
__u8 __user *data;
};
#define UVCIOC_CTRL_MAP _IOWR('u', 0x20, struct uvc_xu_control_mapping)
#define UVCIOC_CTRL_QUERY _IOWR('u', 0x21, struct uvc_xu_control_query)
#endif

View file

@ -0,0 +1,78 @@
#ifndef _UVC_INTF_H_
#define _UVC_INTF_H_
enum uvc_format_type{
UVC_FORMAT_MJPEG = 1,
UVC_FORMAT_H264 = 2,
UVC_FORMAT_UNKNOWN = -1,
};
typedef enum uvc_format_type uvc_fmt_t;
struct uvc_context
{
uvc_fmt_t fmt_type; //video format type
int width;//video frame width
int height;//video frame height
int frame_rate;//video frame rate
int compression_ratio;//compression format video compression ratio
};
#define USER_CTRL_BRIGHTNESS 0
#define USER_CTRL_CONTRAST 1
#define USER_CTRL_SATURATION 2
#define USER_CTRL_HUE 3
#define USER_CTRL_AUTO_WHITE_BALANCE 12
#define USER_CTRL_DO_WHITE_BALANCE 13
#define USER_CTRL_RED_BALANCE 14
#define USER_CTRL_BLUE_BALANCE 15
#define USER_CTRL_GAMMA 16
#define USER_CTRL_EXPOSURE 17
#define USER_CTRL_AUTOGAIN 18
#define USER_CTRL_GAIN 19
#define USER_CTRL_HFLIP 20
#define USER_CTRL_VFLIP 21
#define USER_CTRL_POWER_LINE_FREQUENCY 24
#define USER_CTRL_HUE_AUTO 25
#define USER_CTRL_WHITE_BALANCE_TEMPERATURE 26
#define USER_CTRL_SHARPNESS 27
#define USER_CTRL_BACKLIGHT_COMPENSATION 28
struct uvc_user_ctrl
{
u32 ctrl_id;
s32 ctrl_value;
};
struct uvc_buf_context
{
int index; //index of internal uvc buffer
unsigned char *data; //address of uvc data
int len; //length of uvc data
u32 timestamp; //timestamp
};
#if UVC_BUF_DYNAMIC
int uvc_stream_init(int buf_num, int buf_size);
#else
int uvc_stream_init(void); //entry function to start uvc
#endif
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.
int uvc_get_user_ctrl(struct uvc_user_ctrl *user_ctrl);
int uvc_set_user_ctrl(struct uvc_user_ctrl *user_ctrl);
int uvc_buf_check(struct uvc_buf_context *b); //check if uvc_buf_context is legal (return 0 is legal otherwise -1)
int uvc_dqbuf(struct uvc_buf_context *b); //dequeue internal buffer & get internal buffer info
int uvc_qbuf(struct uvc_buf_context *b); //queue internal buffer
int is_pure_thru_on(void); //return 1 if pure throughput test mode is on otherwise return 0
void uvc_pure_thru_on(void); //turn on pure uvc throughput test mode (i.e. no decoding is involved)
void uvc_dec_thru_on(void); //turn on uvc throughput test mode with uvc payload decoding
void uvc_thru_off(void); //turn off uvc throughput log service
#endif

View file

@ -0,0 +1,574 @@
#ifndef _UVC_OSDEP_WRAP_H_
#define _UVC_OSDEP_WRAP_H_
//#include "rtl_utility.h"
#include "platform/platform_stdlib.h"
#include "basic_types.h"
#include "osdep_api.h"
#include "usb_defs.h"
#include "usb_errno.h"
#include "dlist.h"
#define UVC_LAYER_DEBUG 0
#if UVC_LAYER_DEBUG
#define UVC_PRINTF(fmt, args...) printf("\n\r%s: " fmt, __FUNCTION__, ## args)
#define UVC_ERROR(fmt, args...) printf("\n\r%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 UVC_PRINTF(fmt, args...)
#define UVC_ERROR(fmt, args...) printf("\n\r%s: " fmt, __FUNCTION__, ## args)
#define FUN_ENTER
#define FUN_EXIT
#define FUN_TRACE
#endif
/* add by Ian -- define uvc task priority */
#define UVC_TASK_PRIORITY 2
#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
#ifndef gfp_t
#define gfp_t u32
#endif
#define ALIGN(x, a, type_of_x) (((x) + ((type_of_x)(a) - 1)) & ~((type_of_x)(a) - 1))
#ifndef IS_ALIGNED
#define IS_ALIGNED(x, a, type_of_x) (((x) & ((type_of_x)(a) - 1)) == 0)
#endif
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#endif
#ifndef BITS_PER_LONG
#define BITS_PER_LONG (32)
#endif
#ifndef BITS_PER_LONG_LONG
#define BITS_PER_LONG_LONG (32)
#endif
/* Atomic integer operations */
#ifndef atomic_set
#define atomic_set(v, i) RTL_ATOMIC_SET((v), (i))
#endif
#ifndef atomic_read
#define atomic_read(v) RTL_ATOMIC_READ((v))
#endif
#ifndef atomic_add
#define atomic_add(v, i) RTL_ATOMIC_ADD((v), (i))
#endif
#ifndef atomic_sub
#define atomic_sub(v, i) RTL_ATOMIC_SUB((v), (i))
#endif
#ifndef atomic_inc
#define atomic_inc(v) RTL_ATOMIC_INC((v))
#endif
#ifndef atomic_dec
#define atomic_dec(v) RTL_ATOMIC_DEC((v))
#endif
#ifndef MEDIA_PAD_FL_SINK
#define MEDIA_PAD_FL_SINK (1 << 0)
#endif
#ifndef MEDIA_PAD_FL_SOURCE
#define MEDIA_PAD_FL_SOURCE (1 << 1)
#endif
#ifndef MEDIA_PAD_FL_MUST_CONNECT
#define MEDIA_PAD_FL_MUST_CONNECT (1 << 2)
#endif
static inline u16 __get_unaligned_le16(const u8 *p)
{
return p[0] | p[1] << 8;
}
static inline u32 __get_unaligned_le32(const u8 *p)
{
return p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24;
}
static inline u64 __get_unaligned_le64(const u8 *p)
{
return (u64)__get_unaligned_le32(p + 4) << 32 |
__get_unaligned_le32(p);
}
static inline void __put_unaligned_le16(u16 val, u8 *p)
{
*p++ = val;
*p++ = val >> 8;
}
static inline void __put_unaligned_le32(u32 val, u8 *p)
{
__put_unaligned_le16(val >> 16, p + 2);
__put_unaligned_le16(val, p);
}
static inline void __put_unaligned_le64(u64 val, u8 *p)
{
__put_unaligned_le32(val >> 32, p + 4);
__put_unaligned_le32(val, p);
}
static inline u16 get_unaligned_le16(const void *p)
{
return __get_unaligned_le16((const u8 *)p);
}
static inline u32 get_unaligned_le32(const void *p)
{
return __get_unaligned_le32((const u8 *)p);
}
static inline u64 get_unaligned_le64(const void *p)
{
return __get_unaligned_le64((const u8 *)p);
}
static inline void put_unaligned_le16(u16 val, void *p)
{
__put_unaligned_le16(val, p);
}
static inline void put_unaligned_le32(u32 val, void *p)
{
__put_unaligned_le32(val, p);
}
static inline void put_unaligned_le64(u64 val, void *p)
{
__put_unaligned_le64(val, p);
}
/**
* kmemdup - duplicate region of memory
*
* @src: memory region to duplicate
* @len: memory region length
* @gfp: GFP mask to use
*/
static inline void *kmemdup(const void *src, size_t len, gfp_t gfp)
{
void *p;
//p = kmalloc_track_caller(len, gfp);
//p = kmalloc(len, gfp);
p = malloc(len);
if (p)
memcpy(p, src, len);
return p;
}
#ifndef __force
#define __force __attribute__((force))
#endif
#if 0
typedef __u16 __bitwise __le16;
typedef __u16 __bitwise __be16;
typedef __u32 __bitwise __le32;
typedef __u32 __bitwise __be32;
typedef __u64 __bitwise __le64;
typedef __u64 __bitwise __be64;
typedef __u16 __bitwise __sum16;
typedef __u32 __bitwise __wsum;
#endif
//edit by Ian -- remove duplicated definitions
#if 0
typedef __u16 __le16;
typedef __u16 __be16;
typedef __u32 __le32;
typedef __u32 __be32;
typedef __u64 __le64;
typedef __u64 __be64;
typedef __u16 __sum16;
typedef __u32 __wsum;
#endif
#ifndef __le16
#define __le16 __u16
#endif
#ifndef __be16
#define __be16 __u16
#endif
#ifndef __le32
#define __le32 __u32
#endif
#ifndef __be32
#define __be32 __u32
#endif
static inline __u32 le32_to_cpup(const __le32 *p)
{
//return (__force __u32)*p;
return (__u32)*p;
}
static inline __u16 le16_to_cpup(const __le16 *p)
{
//return (__force __u16)*p;
return (__u16)*p;
}
/* Endian macros */
#ifndef htonl
#define htonl(x) rtk_cpu_to_be32(x)
#endif
#ifndef ntohl
#define ntohl(x) rtk_be32_to_cpu(x)
#endif
#ifndef htons
#define htons(x) rtk_cpu_to_be16(x)
#endif
#ifndef ntohs
#define ntohs(x) rtk_be16_to_cpu(x)
#endif
#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
/* Parameters used to convert the timespec values: */
#ifndef MSEC_PER_SEC
#define MSEC_PER_SEC 1000L
#endif
#ifndef USEC_PER_MSEC
#define USEC_PER_MSEC 1000L
#endif
#ifndef NSEC_PER_USEC
#define NSEC_PER_USEC 1000L
#endif
#ifndef NSEC_PER_MSEC
#define NSEC_PER_MSEC 1000000L
#endif
#ifndef USEC_PER_SEC
#define USEC_PER_SEC 1000000L
#endif
#ifndef NSEC_PER_SEC
#define NSEC_PER_SEC 1000000000L
#endif
#ifndef FSEC_PER_SEC
#define FSEC_PER_SEC 1000000000000000LL
#endif
#ifndef TIME_T_MAX
#define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1)
#endif
#ifndef __GFP_WAIT
#define __GFP_WAIT (0x10u)
#endif
#ifndef __GFP_HIGH
#define __GFP_HIGH (0x20u)
#endif
#ifndef __GFP_IO
#define __GFP_IO (0x40u)
#endif
#ifndef __GFP_FS
#define __GFP_FS (0x80u)
#endif
#ifndef GFP_NOIO
#define GFP_NOIO (0x10u)
#endif
#ifndef __GFP_NOWARN
#define __GFP_NOWARN (0x200u)
#endif
#ifndef GFP_KERNEL
#define GFP_KERNEL (__GFP_WAIT | __GFP_IO | __GFP_FS)
#endif
#ifndef copy_from_user
#define copy_from_user(to, from, sz) RtlMemcpy((to), (from), (sz))
#endif
#ifndef copy_to_user
#define copy_to_user(to, from, sz) RtlMemcpy((to), (from), (sz))
#endif
typedef u32 compat_caddr_t; //used for compatibility in uvc_v4l2.c
/**
* strlcpy - Copy a %NUL terminated string into a sized buffer
* @dest: Where to copy the string to
* @src: Where to copy the string from
* @size: size of destination buffer
*
* Compatible with *BSD: the result is always a valid
* NUL-terminated string that fits in the buffer (unless,
* of course, the buffer size is zero). It does not pad
* out the result like strncpy() does.
*/
#ifndef __GNUC__
extern SIZE_T _strlen(const char *s);
static inline size_t strlcpy(char *dest, const char *src, size_t size)
{
size_t ret = _strlen(src);
if (size) {
size_t len = (ret >= size) ? size - 1 : ret;
memcpy(dest, src, len);
dest[len] = '\0';
}
return ret;
}
#endif
/**
* clamp - return a value clamped to a given range with strict typechecking
* @val: current value
* @min: minimum allowable value
* @max: maximum allowable value
*
* This macro does strict typechecking of min/max to make sure they are of the
* same type as val. See the unnecessary pointer comparisons.
*/
#ifndef clamp
#define clamp(new_val, val, min, max, type) do{ \
type __val = (val); \
type __min = (min); \
type __max = (max); \
(void) (&__val == &__min); \
(void) (&__val == &__max); \
__val = (__val < __min) ? __min: __val; \
new_val = (__val > __max) ? __max: __val; }while(0)
#endif
/*
* Compile time versions of __arch_hweightN()
*/
#ifndef __const_hweight8
#define __const_hweight8(w) \
( (!!((w) & (1ULL << 0))) + \
(!!((w) & (1ULL << 1))) + \
(!!((w) & (1ULL << 2))) + \
(!!((w) & (1ULL << 3))) + \
(!!((w) & (1ULL << 4))) + \
(!!((w) & (1ULL << 5))) + \
(!!((w) & (1ULL << 6))) + \
(!!((w) & (1ULL << 7))) )
#endif
#ifndef hweight8
#define hweight8(w) __const_hweight8(w)
#endif
#ifndef BITMAP_LAST_WORD_MASK
#define BITMAP_LAST_WORD_MASK(nbits) \
( \
((nbits) % BITS_PER_LONG) ? \
(1UL<<((nbits) % BITS_PER_LONG))-1 : ~0UL \
)
#endif
/**
* hweightN - returns the hamming weight of a N-bit word
* @x: the word to weigh
*
* The Hamming Weight of a number is the total number of bits set in it.
*/
static inline unsigned int hweight32(unsigned int w)
{
unsigned int res = w - ((w >> 1) & 0x55555555);
res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
res = (res + (res >> 4)) & 0x0F0F0F0F;
res = res + (res >> 8);
return (res + (res >> 16)) & 0x000000FF;
}
static inline unsigned long hweight64(__u64 w)
{
#if BITS_PER_LONG == 32
return hweight32((unsigned int)(w >> 32)) + hweight32((unsigned int)w);
#elif BITS_PER_LONG == 64
__u64 res = w - ((w >> 1) & 0x5555555555555555ul);
res = (res & 0x3333333333333333ul) + ((res >> 2) & 0x3333333333333333ul);
res = (res + (res >> 4)) & 0x0F0F0F0F0F0F0F0Ful;
res = res + (res >> 8);
res = res + (res >> 16);
return (res + (res >> 32)) & 0x00000000000000FFul;
#endif
}
static inline unsigned long hweight_long(unsigned long w)
{
return sizeof(w) == 4 ? hweight32(w) : hweight64(w);
}
static inline int __bitmap_weight(const unsigned long *bitmap, int bits)
{
int k, w = 0, lim = bits/BITS_PER_LONG;
for (k = 0; k < lim; k++)
w += hweight_long(bitmap[k]);
if (bits % BITS_PER_LONG)
w += hweight_long(bitmap[k] & BITMAP_LAST_WORD_MASK(bits));
return w;
}
static inline int bitmap_weight(const unsigned long *src, int nbits)
{
// if (small_const_nbits(nbits))
// return hweight_long(*src & BITMAP_LAST_WORD_MASK(nbits));
return __bitmap_weight(src, nbits);
}
/**
* memweight - count the total number of bits set in memory area
* @ptr: pointer to the start of the area
* @bytes: the size of the area
*/
static inline size_t memweight(const void *ptr, size_t bytes)
{
size_t ret = 0;
size_t longs;
const unsigned char *bitmap = ptr;
for (; bytes > 0 && ((unsigned long)bitmap) % sizeof(long);
bytes--, bitmap++)
ret += hweight8(*bitmap);
longs = bytes / sizeof(long);
if (longs) {
//BUG_ON(longs >= INT_MAX / BITS_PER_LONG);
ret += bitmap_weight((unsigned long *)bitmap, longs * BITS_PER_LONG);
bytes -= longs * sizeof(long);
bitmap += longs * sizeof(long);
}
/*
* The reason that this last loop is distinct from the preceding
* bitmap_weight() call is to compute 1-bits in the last region smaller
* than sizeof(long) properly on big-endian systems.
*/
for (; bytes > 0; bytes--, bitmap++)
ret += hweight8(*bitmap);
return ret;
}
/**
* strlcat - Append a length-limited, %NUL-terminated string to another
* @dest: The string to be appended to
* @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);
size_t len = _strlen(src);
size_t res = dsize + len;
/* This would be a bug */
//BUG_ON(dsize >= count);
dest += dsize;
count -= dsize;
if (len >= count)
len = count-1;
memcpy(dest, src, len);
dest[len] = 0;
return res;
}
#endif
/**
* atomic_dec_and_test - decrement and test
* @v: pointer of type atomic_t
*
* Atomically decrements @v by 1 and
* returns true if the result is 0, or false for all other
* cases.
*/
static inline int atomic_dec_and_test(atomic_t *v)
{
atomic_dec(v);
if (v->counter == 0)
return TRUE;
else
return FALSE;
}
/**
* kcalloc - allocate memory for an array. The memory is set to zero.
* @n: number of elements.
* @size: element size.
* @flags: the type of memory to allocate (see kmalloc).
*/
static inline void *kcalloc(size_t n, size_t size, gfp_t flags)
{
return RtlZmalloc(((n) * (size)));
}
#ifndef GFP_ATOMIC
#define GFP_ATOMIC GFP_KERNEL
#endif
#ifndef offsetof
#define offsetof(s,m) (size_t)&(((s *)0)->m)
#endif
//enum linux kernel version
#ifndef KERNEL_VERSION
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
#endif
#ifndef LINUX_VERSION_CODE
#define LINUX_VERSION_CODE KERNEL_VERSION(3, 12, 0)
#endif
#endif //_UVC_OSDEP_WRAP_H_

View file

@ -0,0 +1,588 @@
#ifndef _UVC_OSDEP_WRAP_H_
#define _UVC_OSDEP_WRAP_H_
//#include "rtl_utility.h"
#include "platform/platform_stdlib.h"
#include "basic_types.h"
#include "osdep_api.h"
#include "usb_defs.h"
#include "errno.h"
#include "dlist.h"
#define UVC_LAYER_DEBUG 0
#if UVC_LAYER_DEBUG
#define UVC_PRINTF(fmt, args...) printf("\n\r%s: " fmt, __FUNCTION__, ## args)
#define UVC_ERROR(fmt, args...) printf("\n\r%s: " fmt, __FUNCTION__, ## args)
#define UVC_WARN(fmt, args...) printf("\n\r%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 UVC_PRINTF(fmt, args...)
#define UVC_ERROR(fmt, args...) printf("\n\r%s: " fmt, __FUNCTION__, ## args)
#define UVC_WARN(fmt, args...) printf("\n\r%s: " fmt, __FUNCTION__, ## args)
#define FUN_ENTER
#define FUN_EXIT
#define FUN_TRACE
#endif
/* add by Ian -- define uvc task priority */
#define UVC_TASK_PRIORITY 2
#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
#ifndef gfp_t
#define gfp_t u32
#endif
#define ALIGN(x, a, type_of_x) (((x) + ((type_of_x)(a) - 1)) & ~((type_of_x)(a) - 1))
#ifndef IS_ALIGNED
#define IS_ALIGNED(x, a, type_of_x) (((x) & ((type_of_x)(a) - 1)) == 0)
#endif
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#endif
#ifndef BITS_PER_LONG
#define BITS_PER_LONG (32)
#endif
#ifndef BITS_PER_LONG_LONG
#define BITS_PER_LONG_LONG (32)
#endif
/* Atomic integer operations */
#ifndef atomic_set
#define atomic_set(v, i) RTL_ATOMIC_SET((v), (i))
#endif
#ifndef atomic_read
#define atomic_read(v) RTL_ATOMIC_READ((v))
#endif
#ifndef atomic_add
#define atomic_add(v, i) RTL_ATOMIC_ADD((v), (i))
#endif
#ifndef atomic_sub
#define atomic_sub(v, i) RTL_ATOMIC_SUB((v), (i))
#endif
#ifndef atomic_inc
#define atomic_inc(v) RTL_ATOMIC_INC((v))
#endif
#ifndef atomic_dec
#define atomic_dec(v) RTL_ATOMIC_DEC((v))
#endif
#ifndef MEDIA_PAD_FL_SINK
#define MEDIA_PAD_FL_SINK (1 << 0)
#endif
#ifndef MEDIA_PAD_FL_SOURCE
#define MEDIA_PAD_FL_SOURCE (1 << 1)
#endif
#ifndef MEDIA_PAD_FL_MUST_CONNECT
#define MEDIA_PAD_FL_MUST_CONNECT (1 << 2)
#endif
static inline u16 __get_unaligned_le16(const u8 *p)
{
return p[0] | p[1] << 8;
}
static inline u32 __get_unaligned_le32(const u8 *p)
{
return p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24;
}
static inline u64 __get_unaligned_le64(const u8 *p)
{
return (u64)__get_unaligned_le32(p + 4) << 32 |
__get_unaligned_le32(p);
}
static inline void __put_unaligned_le16(u16 val, u8 *p)
{
*p++ = val;
*p++ = val >> 8;
}
static inline void __put_unaligned_le32(u32 val, u8 *p)
{
__put_unaligned_le16(val >> 16, p + 2);
__put_unaligned_le16(val, p);
}
static inline void __put_unaligned_le64(u64 val, u8 *p)
{
__put_unaligned_le32(val >> 32, p + 4);
__put_unaligned_le32(val, p);
}
static inline u16 get_unaligned_le16(const void *p)
{
return __get_unaligned_le16((const u8 *)p);
}
static inline u32 get_unaligned_le32(const void *p)
{
return __get_unaligned_le32((const u8 *)p);
}
static inline u64 get_unaligned_le64(const void *p)
{
return __get_unaligned_le64((const u8 *)p);
}
static inline void put_unaligned_le16(u16 val, void *p)
{
__put_unaligned_le16(val, p);
}
static inline void put_unaligned_le32(u32 val, void *p)
{
__put_unaligned_le32(val, p);
}
static inline void put_unaligned_le64(u64 val, void *p)
{
__put_unaligned_le64(val, p);
}
/**
* kmemdup - duplicate region of memory
*
* @src: memory region to duplicate
* @len: memory region length
* @gfp: GFP mask to use
*/
static inline void *kmemdup(const void *src, size_t len, gfp_t gfp)
{
void *p;
//p = kmalloc_track_caller(len, gfp);
//p = kmalloc(len, gfp);
p = rtw_malloc(len);
if (p)
memcpy(p, src, len);
return p;
}
#ifndef __force
#define __force __attribute__((force))
#endif
#if 0
typedef __u16 __bitwise __le16;
typedef __u16 __bitwise __be16;
typedef __u32 __bitwise __le32;
typedef __u32 __bitwise __be32;
typedef __u64 __bitwise __le64;
typedef __u64 __bitwise __be64;
typedef __u16 __bitwise __sum16;
typedef __u32 __bitwise __wsum;
#endif
//edit by Ian -- remove duplicated definitions
#if 0
typedef __u16 __le16;
typedef __u16 __be16;
typedef __u32 __le32;
typedef __u32 __be32;
typedef __u64 __le64;
typedef __u64 __be64;
typedef __u16 __sum16;
typedef __u32 __wsum;
#endif
#ifndef __le16
#define __le16 __u16
#endif
#ifndef __be16
#define __be16 __u16
#endif
#ifndef __le32
#define __le32 __u32
#endif
#ifndef __be32
#define __be32 __u32
#endif
static inline __u32 le32_to_cpup(const __le32 *p)
{
//return (__force __u32)*p;
return (__u32)*p;
}
static inline __u16 le16_to_cpup(const __le16 *p)
{
//return (__force __u16)*p;
return (__u16)*p;
}
/* Endian macros */
#ifndef htonl
#define htonl(x) rtk_cpu_to_be32(x)
#endif
#ifndef ntohl
#define ntohl(x) rtk_be32_to_cpu(x)
#endif
#ifndef htons
#define htons(x) rtk_cpu_to_be16(x)
#endif
#ifndef ntohs
#define ntohs(x) rtk_be16_to_cpu(x)
#endif
#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
/* Parameters used to convert the timespec values: */
#ifndef MSEC_PER_SEC
#define MSEC_PER_SEC 1000L
#endif
#ifndef USEC_PER_MSEC
#define USEC_PER_MSEC 1000L
#endif
#ifndef NSEC_PER_USEC
#define NSEC_PER_USEC 1000L
#endif
#ifndef NSEC_PER_MSEC
#define NSEC_PER_MSEC 1000000L
#endif
#ifndef USEC_PER_SEC
#define USEC_PER_SEC 1000000L
#endif
#ifndef NSEC_PER_SEC
#define NSEC_PER_SEC 1000000000L
#endif
#ifndef FSEC_PER_SEC
#define FSEC_PER_SEC 1000000000000000LL
#endif
#ifndef TIME_T_MAX
#define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1)
#endif
#ifndef __GFP_WAIT
#define __GFP_WAIT (0x10u)
#endif
#ifndef __GFP_HIGH
#define __GFP_HIGH (0x20u)
#endif
#ifndef __GFP_IO
#define __GFP_IO (0x40u)
#endif
#ifndef __GFP_FS
#define __GFP_FS (0x80u)
#endif
#ifndef GFP_NOIO
#define GFP_NOIO (0x10u)
#endif
#ifndef __GFP_NOWARN
#define __GFP_NOWARN (0x200u)
#endif
#ifndef GFP_KERNEL
#define GFP_KERNEL (__GFP_WAIT | __GFP_IO | __GFP_FS)
#endif
#if 0
#ifndef copy_from_user
#define copy_from_user(to, from, sz) rtw_memcpy((to), (from), (sz))
#endif
#ifndef copy_to_user
#define copy_to_user(to, from, sz) rtw_memcpy((to), (from), (sz))
#endif
#endif
int inline copy_from_user(void* to, void* from, u32 sz)
{
memcpy(to, from, sz);
return TRUE;
}
int inline copy_to_user(void* to, void* from, u32 sz)
{
memcpy(to, from, sz);
return TRUE;
}
typedef u32 compat_caddr_t; //used for compatibility in uvc_v4l2.c
/**
* strlcpy - Copy a %NUL terminated string into a sized buffer
* @dest: Where to copy the string to
* @src: Where to copy the string from
* @size: size of destination buffer
*
* Compatible with *BSD: the result is always a valid
* NUL-terminated string that fits in the buffer (unless,
* of course, the buffer size is zero). It does not pad
* out the result like strncpy() does.
*/
static inline size_t strlcpy(char *dest, const char *src, size_t size)
{
size_t ret = _strlen(src);
if (size) {
size_t len = (ret >= size) ? size - 1 : ret;
memcpy(dest, src, len);
dest[len] = '\0';
}
return ret;
}
/**
* clamp - return a value clamped to a given range with strict typechecking
* @val: current value
* @min: minimum allowable value
* @max: maximum allowable value
*
* This macro does strict typechecking of min/max to make sure they are of the
* same type as val. See the unnecessary pointer comparisons.
*/
#ifndef clamp
#define clamp(new_val, val, min, max, type) do{ \
type __val = (val); \
type __min = (min); \
type __max = (max); \
(void) (&__val == &__min); \
(void) (&__val == &__max); \
__val = (__val < __min) ? __min: __val; \
new_val = (__val > __max) ? __max: __val; }while(0)
#endif
/*
* Compile time versions of __arch_hweightN()
*/
#ifndef __const_hweight8
#define __const_hweight8(w) \
( (!!((w) & (1ULL << 0))) + \
(!!((w) & (1ULL << 1))) + \
(!!((w) & (1ULL << 2))) + \
(!!((w) & (1ULL << 3))) + \
(!!((w) & (1ULL << 4))) + \
(!!((w) & (1ULL << 5))) + \
(!!((w) & (1ULL << 6))) + \
(!!((w) & (1ULL << 7))) )
#endif
#ifndef hweight8
#define hweight8(w) __const_hweight8(w)
#endif
#ifndef BITMAP_LAST_WORD_MASK
#define BITMAP_LAST_WORD_MASK(nbits) \
( \
((nbits) % BITS_PER_LONG) ? \
(1UL<<((nbits) % BITS_PER_LONG))-1 : ~0UL \
)
#endif
/**
* hweightN - returns the hamming weight of a N-bit word
* @x: the word to weigh
*
* The Hamming Weight of a number is the total number of bits set in it.
*/
static inline unsigned int hweight32(unsigned int w)
{
unsigned int res = w - ((w >> 1) & 0x55555555);
res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
res = (res + (res >> 4)) & 0x0F0F0F0F;
res = res + (res >> 8);
return (res + (res >> 16)) & 0x000000FF;
}
static inline unsigned long hweight64(__u64 w)
{
#if BITS_PER_LONG == 32
return hweight32((unsigned int)(w >> 32)) + hweight32((unsigned int)w);
#elif BITS_PER_LONG == 64
__u64 res = w - ((w >> 1) & 0x5555555555555555ul);
res = (res & 0x3333333333333333ul) + ((res >> 2) & 0x3333333333333333ul);
res = (res + (res >> 4)) & 0x0F0F0F0F0F0F0F0Ful;
res = res + (res >> 8);
res = res + (res >> 16);
return (res + (res >> 32)) & 0x00000000000000FFul;
#endif
}
static inline unsigned long hweight_long(unsigned long w)
{
return sizeof(w) == 4 ? hweight32(w) : hweight64(w);
}
static inline int __bitmap_weight(const unsigned long *bitmap, int bits)
{
int k, w = 0, lim = bits/BITS_PER_LONG;
for (k = 0; k < lim; k++)
w += hweight_long(bitmap[k]);
if (bits % BITS_PER_LONG)
w += hweight_long(bitmap[k] & BITMAP_LAST_WORD_MASK(bits));
return w;
}
static inline int bitmap_weight(const unsigned long *src, int nbits)
{
// if (small_const_nbits(nbits))
// return hweight_long(*src & BITMAP_LAST_WORD_MASK(nbits));
return __bitmap_weight(src, nbits);
}
/**
* memweight - count the total number of bits set in memory area
* @ptr: pointer to the start of the area
* @bytes: the size of the area
*/
static inline size_t memweight(const void *ptr, size_t bytes)
{
size_t ret = 0;
size_t longs;
const unsigned char *bitmap = ptr;
for (; bytes > 0 && ((unsigned long)bitmap) % sizeof(long);
bytes--, bitmap++)
ret += hweight8(*bitmap);
longs = bytes / sizeof(long);
if (longs) {
//BUG_ON(longs >= INT_MAX / BITS_PER_LONG);
ret += bitmap_weight((unsigned long *)bitmap, longs * BITS_PER_LONG);
bytes -= longs * sizeof(long);
bitmap += longs * sizeof(long);
}
/*
* The reason that this last loop is distinct from the preceding
* bitmap_weight() call is to compute 1-bits in the last region smaller
* than sizeof(long) properly on big-endian systems.
*/
for (; bytes > 0; bytes--, bitmap++)
ret += hweight8(*bitmap);
return ret;
}
/**
* strlcat - Append a length-limited, %NUL-terminated string to another
* @dest: The string to be appended to
* @src: The string to append to it
* @count: The size of the destination buffer.
*/
static inline size_t strlcat(char *dest, const char *src, size_t count)
{
size_t dsize = _strlen(dest);
size_t len = _strlen(src);
size_t res = dsize + len;
/* This would be a bug */
//BUG_ON(dsize >= count);
dest += dsize;
count -= dsize;
if (len >= count)
len = count-1;
memcpy(dest, src, len);
dest[len] = 0;
return res;
}
/**
* atomic_dec_and_test - decrement and test
* @v: pointer of type atomic_t
*
* Atomically decrements @v by 1 and
* returns true if the result is 0, or false for all other
* cases.
*/
static inline int atomic_dec_and_test(atomic_t *v)
{
atomic_dec(v);
if (v->counter == 0)
return TRUE;
else
return FALSE;
}
/**
* kcalloc - allocate memory for an array. The memory is set to zero.
* @n: number of elements.
* @size: element size.
* @flags: the type of memory to allocate (see kmalloc).
*/
static inline void *kcalloc(size_t n, size_t size, gfp_t flags)
{
//return RtlZmalloc(((n) * (size)));
return rtw_zmalloc(((n) * (size)));
}
#ifndef GFP_ATOMIC
#define GFP_ATOMIC GFP_KERNEL
#endif
#ifndef offsetof
#define offsetof(s,m) (size_t)&(((s *)0)->m)
#endif
//enum linux kernel version
#ifndef KERNEL_VERSION
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
#endif
#ifndef LINUX_VERSION_CODE
#define LINUX_VERSION_CODE KERNEL_VERSION(3, 12, 0)
#endif
#endif //_UVC_OSDEP_WRAP_H_

View file

@ -0,0 +1,776 @@
#ifndef _USB_VIDEO_H_
#define _USB_VIDEO_H_
#if 0
#ifndef __KERNEL__
#error "The uvcvideo.h header is deprecated, use linux/uvcvideo.h instead."
#endif /* __KERNEL__ */
#include <linux/kernel.h>
#include <linux/poll.h>
#endif
#include "usb.h"
#include "video.h"
#include "uvcvideo.h"
#include "videodev2.h"
#include "media-device.h"
#include "v4l2-device.h"
#include "v4l2-event.h"
#include "v4l2-fh.h"
#include "videobuf2-core.h"
/* --------------------------------------------------------------------------
* UVC constants
*/
#define UVC_TERM_INPUT 0x0000
#define UVC_TERM_OUTPUT 0x8000
#define UVC_TERM_DIRECTION(term) ((term)->type & 0x8000)
#define UVC_ENTITY_TYPE(entity) ((entity)->type & 0x7fff)
#define UVC_ENTITY_IS_UNIT(entity) (((entity)->type & 0xff00) == 0)
#define UVC_ENTITY_IS_TERM(entity) (((entity)->type & 0xff00) != 0)
#define UVC_ENTITY_IS_ITERM(entity) \
(UVC_ENTITY_IS_TERM(entity) && \
((entity)->type & 0x8000) == UVC_TERM_INPUT)
#define UVC_ENTITY_IS_OTERM(entity) \
(UVC_ENTITY_IS_TERM(entity) && \
((entity)->type & 0x8000) == UVC_TERM_OUTPUT)
/* ------------------------------------------------------------------------
* GUIDs
*/
#define UVC_GUID_UVC_CAMERA \
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}
#define UVC_GUID_UVC_OUTPUT \
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}
#define UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT \
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
#define UVC_GUID_UVC_PROCESSING \
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01}
#define UVC_GUID_UVC_SELECTOR \
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02}
#define UVC_GUID_FORMAT_MJPEG \
{ 'M', 'J', 'P', 'G', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_YUY2 \
{ 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_YUY2_ISIGHT \
{ 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0x00, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_NV12 \
{ 'N', 'V', '1', '2', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_YV12 \
{ 'Y', 'V', '1', '2', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_I420 \
{ 'I', '4', '2', '0', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_UYVY \
{ 'U', 'Y', 'V', 'Y', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_Y800 \
{ 'Y', '8', '0', '0', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_Y8 \
{ 'Y', '8', ' ', ' ', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_Y10 \
{ 'Y', '1', '0', ' ', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_Y12 \
{ 'Y', '1', '2', ' ', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_Y16 \
{ 'Y', '1', '6', ' ', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_BY8 \
{ 'B', 'Y', '8', ' ', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_RGBP \
{ 'R', 'G', 'B', 'P', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_M420 \
{ 'M', '4', '2', '0', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_H264 \
{ 'H', '2', '6', '4', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
/* edit by Ian -- patch for GEO add two new guids*/
#define UVC_GUID_FORMAT_MPEG \
{ 'M', 'P', 'E', 'G', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_MUX \
{ 'M', 'U', 'X', 0x00, 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
/* ------------------------------------------------------------------------
* Driver specific constants.
*/
#define DRIVER_VERSION "1.1.1"
/* Number of isochronous URBs. */
#define UVC_URBS 4
/* Maximum number of packets per URB. */
#define UVC_MAX_PACKETS 32
/* Maximum number of video buffers. */
#define UVC_MAX_VIDEO_BUFFERS 8
/* Maximum status buffer size in bytes of interrupt URB. */
#define UVC_MAX_STATUS_SIZE 16
//modified by Ian
#define UVC_REQBUF_SIZE (150000)
#define UVC_BUF_DYNAMIC 0
#define UVC_USE_DMA 0
#define UVC_CTRL_CONTROL_TIMEOUT 300
#define UVC_CTRL_STREAMING_TIMEOUT 5000
/* Maximum allowed number of control mappings per device */
#define UVC_MAX_CONTROL_MAPPINGS 1024
#define UVC_MAX_CONTROL_MENU_ENTRIES 32
/* Devices quirks */
#define UVC_QUIRK_STATUS_INTERVAL 0x00000001
#define UVC_QUIRK_PROBE_MINMAX 0x00000002
#define UVC_QUIRK_PROBE_EXTRAFIELDS 0x00000004
#define UVC_QUIRK_BUILTIN_ISIGHT 0x00000008
#define UVC_QUIRK_STREAM_NO_FID 0x00000010
#define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020
#define UVC_QUIRK_FIX_BANDWIDTH 0x00000080
#define UVC_QUIRK_PROBE_DEF 0x00000100
#define UVC_QUIRK_RESTRICT_FRAME_RATE 0x00000200
/* Format flags */
#define UVC_FMT_FLAG_COMPRESSED 0x00000001
#define UVC_FMT_FLAG_STREAM 0x00000002
/* ------------------------------------------------------------------------
* Structures.
*/
struct uvc_device;
/* TODO: Put the most frequently accessed fields at the beginning of
* structures to maximize cache efficiency.
*/
struct uvc_control_info {
struct list_head mappings;
__u8 entity[16];
__u8 index; /* Bit index in bmControls */
__u8 selector;
__u16 size;
__u32 flags;
};
struct uvc_control_mapping {
struct list_head list;
struct list_head ev_subs;
__u32 id;
__u8 name[32];
__u8 entity[16];
__u8 selector;
__u8 size;
__u8 offset;
enum v4l2_ctrl_type v4l2_type;
__u32 data_type;
struct uvc_menu_info *menu_info;
__u32 menu_count;
__u32 master_id;
__s32 master_manual;
__u32 slave_ids[2];
__s32 (*get) (struct uvc_control_mapping *mapping, __u8 query,
const __u8 *data);
void (*set) (struct uvc_control_mapping *mapping, __s32 value,
__u8 *data);
};
struct uvc_control {
struct uvc_entity *entity;
struct uvc_control_info info;
__u8 index; /* Used to match the uvc_control entry with a
uvc_control_info. */
__u8 dirty:1,
loaded:1,
modified:1,
cached:1,
initialized:1;
__u8 *uvc_data;
};
struct uvc_format_desc {
char *name;
__u8 guid[16];
__u32 fcc;
};
/* The term 'entity' refers to both UVC units and UVC terminals.
*
* The type field is either the terminal type (wTerminalType in the terminal
* descriptor), or the unit type (bDescriptorSubtype in the unit descriptor).
* As the bDescriptorSubtype field is one byte long, the type value will
* always have a null MSB for units. All terminal types defined by the UVC
* specification have a non-null MSB, so it is safe to use the MSB to
* differentiate between units and terminals as long as the descriptor parsing
* code makes sure terminal types have a non-null MSB.
*
* For terminals, the type's most significant bit stores the terminal
* direction (either UVC_TERM_INPUT or UVC_TERM_OUTPUT). The type field should
* always be accessed with the UVC_ENTITY_* macros and never directly.
*/
#define UVC_ENTITY_FLAG_DEFAULT (1 << 0)
struct uvc_entity {
struct list_head list; /* Entity as part of a UVC device. */
struct list_head chain; /* Entity as part of a video device
* chain. */
unsigned int flags;
__u8 id;
__u16 type;
char name[64];
/* Media controller-related fields. */
struct video_device *vdev;
struct v4l2_subdev subdev;
unsigned int num_pads;
unsigned int num_links;
struct media_pad *pads;
union {
struct {
__u16 wObjectiveFocalLengthMin;
__u16 wObjectiveFocalLengthMax;
__u16 wOcularFocalLength;
__u8 bControlSize;
__u8 *bmControls;
} camera;
struct {
__u8 bControlSize;
__u8 *bmControls;
__u8 bTransportModeSize;
__u8 *bmTransportModes;
} media;
#if 0
struct {
} output;
#endif
struct {
__u16 wMaxMultiplier;
__u8 bControlSize;
__u8 *bmControls;
__u8 bmVideoStandards;
} processing;
#if 0
struct {
} selector;
#endif
struct {
__u8 guidExtensionCode[16];
__u8 bNumControls;
__u8 bControlSize;
__u8 *bmControls;
__u8 *bmControlsType;
} extension;
};
__u8 bNrInPins;
__u8 *baSourceID;
unsigned int ncontrols;
struct uvc_control *controls;
};
// total (27)-> 28 Bytes
struct uvc_frame {
__u8 bFrameIndex;
__u8 bmCapabilities;
__u16 wWidth;
__u16 wHeight;
__u32 dwMinBitRate;
__u32 dwMaxBitRate;
__u32 dwMaxVideoFrameBufferSize;
__u8 bFrameIntervalType;
__u32 dwDefaultFrameInterval;
__u32 *dwFrameInterval;
};
// total 52 Bytes
struct uvc_format {
__u8 type;
__u8 index;
__u8 bpp;
__u8 colorspace;
__u32 fcc;
__u32 flags;
char name[32];
unsigned int nframes;
struct uvc_frame *frame;
};
struct uvc_streaming_header {
__u8 bNumFormats;
__u8 bEndpointAddress;
__u8 bTerminalLink;
__u8 bControlSize;
__u8 *bmaControls;
/* The following fields are used by input headers only. */
__u8 bmInfo;
__u8 bStillCaptureMethod;
__u8 bTriggerSupport;
__u8 bTriggerUsage;
};
enum uvc_buffer_state {
UVC_BUF_STATE_IDLE = 0,
UVC_BUF_STATE_QUEUED = 1,
UVC_BUF_STATE_ACTIVE = 2,
UVC_BUF_STATE_READY = 3,
UVC_BUF_STATE_DONE = 4,
UVC_BUF_STATE_ERROR = 5,
};
struct uvc_buffer {
struct vb2_buffer buf;
struct list_head queue;
_Mutex mutex;
enum uvc_buffer_state state;
unsigned int error;
void *mem;
unsigned int length;
unsigned int bytesused;
u32 pts;
};
#define UVC_QUEUE_DISCONNECTED (1 << 0)
#define UVC_QUEUE_DROP_CORRUPTED (1 << 1)
struct uvc_video_queue {
struct vb2_queue queue;
//struct mutex mutex; /* Protects queue */
_Mutex mutex;
unsigned int flags;
unsigned int buf_used;
//spinlock_t irqlock; /* Protects irqqueue */
//_LOCK_T irqlock;
_Mutex irqlock;
struct list_head irqqueue;
};
struct uvc_video_chain {
struct uvc_device *dev;
struct list_head list;
struct list_head entities; /* All entities */
struct uvc_entity *processing; /* Processing unit */
struct uvc_entity *selector; /* Selector unit */
//struct mutex ctrl_mutex; /* Protects ctrl.info */
_Mutex ctrl_mutex;
struct v4l2_prio_state prio; /* V4L2 priority state */
u32 caps; /* V4L2 chain-wide caps */
};
struct uvc_stats_frame {
unsigned int size; /* Number of bytes captured */
unsigned int first_data; /* Index of the first non-empty packet */
unsigned int nb_packets; /* Number of packets */
unsigned int nb_empty; /* Number of empty packets */
unsigned int nb_invalid; /* Number of packets with an invalid header */
unsigned int nb_errors; /* Number of packets with the error bit set */
unsigned int nb_pts; /* Number of packets with a PTS timestamp */
unsigned int nb_pts_diffs; /* Number of PTS differences inside a frame */
unsigned int last_pts_diff; /* Index of the last PTS difference */
bool has_initial_pts; /* Whether the first non-empty packet has a PTS */
bool has_early_pts; /* Whether a PTS is present before the first non-empty packet */
u32 pts; /* PTS of the last packet */
unsigned int nb_scr; /* Number of packets with a SCR timestamp */
unsigned int nb_scr_diffs; /* Number of SCR.STC differences inside a frame */
u16 scr_sof; /* SCR.SOF of the last packet */
u32 scr_stc; /* SCR.STC of the last packet */
};
struct uvc_stats_stream {
//struct timespec start_ts; /* Stream start timestamp */
//struct timespec stop_ts; /* Stream stop timestamp */
u32 start_ts;
u32 stop_ts;
unsigned int nb_frames; /* Number of frames */
unsigned int nb_packets; /* Number of packets */
unsigned int nb_empty; /* Number of empty packets */
unsigned int nb_invalid; /* Number of packets with an invalid header */
unsigned int nb_errors; /* Number of packets with the error bit set */
unsigned int nb_pts_constant; /* Number of frames with constant PTS */
unsigned int nb_pts_early; /* Number of frames with early PTS */
unsigned int nb_pts_initial; /* Number of frames with initial PTS */
unsigned int nb_scr_count_ok; /* Number of frames with at least one SCR per non empty packet */
unsigned int nb_scr_diffs_ok; /* Number of frames with varying SCR.STC */
unsigned int scr_sof_count; /* STC.SOF counter accumulated since stream start */
unsigned int scr_sof; /* STC.SOF of the last packet */
unsigned int min_sof; /* Minimum STC.SOF value */
unsigned int max_sof; /* Maximum STC.SOF value */
};
struct uvc_streaming {
struct list_head list;
struct uvc_device *dev;
struct video_device *vdev;
struct uvc_video_chain *chain;
atomic_t active;
struct usb_interface *intf;
int intfnum;
__u16 maxpsize;
struct uvc_streaming_header header;
enum v4l2_buf_type type;
unsigned int nformats;
struct uvc_format *format;
struct uvc_streaming_control ctrl;
struct uvc_format *def_format;
struct uvc_format *cur_format;
struct uvc_frame *cur_frame;
/* Protect access to ctrl, cur_format, cur_frame and hardware video
* probe control.
*/
//struct mutex mutex;
_Mutex mutex;
/* Buffers queue. */
unsigned int frozen : 1;
struct uvc_video_queue queue;
void (*decode) (struct urb *urb, struct uvc_streaming *video,
struct uvc_buffer *buf);
/* Context data used by the bulk completion handler. */
struct {
__u8 header[256];
unsigned int header_size;
int skip_payload;
__u32 payload_size;
__u32 max_payload_size;
} bulk;
struct urb *urb[UVC_URBS];
char *urb_buffer[UVC_URBS];
dma_addr_t urb_dma[UVC_URBS];
unsigned int urb_size;
__u32 sequence;
__u8 last_fid;
/* debugfs */
//struct dentry *debugfs_dir;
struct {
struct uvc_stats_frame frame;
struct uvc_stats_stream stream;
} stats;
/* Timestamps support. */
struct uvc_clock {
struct uvc_clock_sample {
u32 dev_stc;
u16 dev_sof;
//struct timespec host_ts;
u32 host_ts; //change to tick
u16 host_sof;
} *samples;
unsigned int head;
unsigned int count;
unsigned int size;
u16 last_sof;
u16 sof_offset;
//spinlock_t lock;
_Lock lock;
} clock;
};
enum uvc_device_state {
UVC_DEV_DISCONNECTED = 1,
};
struct uvc_device {
struct usb_device *udev;
struct usb_interface *intf;
unsigned long warnings;
__u32 quirks;
int intfnum;
char name[32];
enum uvc_device_state state;
//struct mutex lock; /* Protects users */
_Mutex lock;
unsigned int users;
atomic_t nmappings;
/* Video control interface */
#ifdef CONFIG_MEDIA_CONTROLLER
struct media_device mdev;
#endif
struct v4l2_device vdev;
__u16 uvc_version;
__u32 clock_frequency;
struct list_head entities; // VC_EXTENSION_UNIT ->VC_INPUT_TERMINAL ->VC_PROCESSING_UNIT ->VC_OUTPUT_TERMINAL
struct list_head chains;
/* Video Streaming interfaces */
struct list_head streams;
atomic_t nstreams;
/* Status Interrupt Endpoint */
struct usb_host_endpoint *int_ep;
struct urb *int_urb;
__u8 *status;
//struct input_dev *input;
char input_phys[64];
};
enum uvc_handle_state {
UVC_HANDLE_PASSIVE = 0,
UVC_HANDLE_ACTIVE = 1,
};
/* uvc file handle */
struct uvc_fh {
struct v4l2_fh vfh;
struct uvc_video_chain *chain;
struct uvc_streaming *stream;
enum uvc_handle_state state;
};
#if 0
/* uvc_driver = usb_driver for interface
* - identifies USB interface driver to usbcore
*/
struct uvc_driver {
struct usb_driver driver;
};
#endif
/* ------------------------------------------------------------------------
* Debugging, printing and logging
*/
#define UVC_TRACE_PROBE (1 << 0)
#define UVC_TRACE_DESCR (1 << 1)
#define UVC_TRACE_CONTROL (1 << 2)
#define UVC_TRACE_FORMAT (1 << 3)
#define UVC_TRACE_CAPTURE (1 << 4)
#define UVC_TRACE_CALLS (1 << 5)
#define UVC_TRACE_IOCTL (1 << 6)
#define UVC_TRACE_FRAME (1 << 7)
#define UVC_TRACE_SUSPEND (1 << 8)
#define UVC_TRACE_STATUS (1 << 9)
#define UVC_TRACE_VIDEO (1 << 10)
#define UVC_TRACE_STATS (1 << 11)
#define UVC_TRACE_CLOCK (1 << 12)
#define UVC_WARN_MINMAX 0
#define UVC_WARN_PROBE_DEF 1
#define UVC_WARN_XU_GET_RES 2
extern unsigned int uvc_clock_param;
extern unsigned int uvc_no_drop_param;
extern unsigned int uvc_trace_param;
extern unsigned int uvc_timeout_param;
#if 0
#define uvc_trace(flag, msg...) \
do { \
if (uvc_trace_param & flag) \
printk(KERN_DEBUG "uvcvideo: " msg); \
} while (0)
#define uvc_warn_once(dev, warn, msg...) \
do { \
if (!test_and_set_bit(warn, &dev->warnings)) \
printk(KERN_INFO "uvcvideo: " msg); \
} while (0)
#define uvc_printk(level, msg...) \
printk(level "uvcvideo: " msg)
#endif
/* --------------------------------------------------------------------------
* Internal functions.
*/
/* Core driver */
extern struct uvc_driver uvc_driver;
extern struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id);
/* Video buffers queue management. */
extern int uvc_queue_init(struct uvc_video_queue *queue,
enum v4l2_buf_type type, int drop_corrupted);
extern int uvc_alloc_buffers(struct uvc_video_queue *queue,
struct v4l2_requestbuffers *rb);
extern void uvc_free_buffers(struct uvc_video_queue *queue);
extern int uvc_query_buffer(struct uvc_video_queue *queue,
struct v4l2_buffer *v4l2_buf);
extern int uvc_queue_buffer(struct uvc_video_queue *queue,
struct v4l2_buffer *v4l2_buf);
extern int uvc_dequeue_buffer(struct uvc_video_queue *queue,
struct v4l2_buffer *v4l2_buf, int nonblocking);
extern int uvc_queue_enable(struct uvc_video_queue *queue, int enable);
extern void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect);
extern struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
struct uvc_buffer *buf);
extern int uvc_queue_mmap(struct uvc_video_queue *queue);
#if 0
extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue,
struct file *file, poll_table *wait);
#endif
#ifndef CONFIG_MMU
extern unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue,
unsigned long pgoff);
#endif
extern int uvc_queue_allocated(struct uvc_video_queue *queue);
static inline int uvc_queue_streaming(struct uvc_video_queue *queue)
{
return vb2_is_streaming(&queue->queue);
}
/* V4L2 interface */
extern const struct v4l2_file_operations uvc_fops;
/* Media controller */
extern int uvc_mc_register_entities(struct uvc_video_chain *chain);
extern void uvc_mc_cleanup_entity(struct uvc_entity *entity);
/* Video */
extern int uvc_video_init(struct uvc_streaming *stream);
extern int uvc_video_suspend(struct uvc_streaming *stream);
extern int uvc_video_resume(struct uvc_streaming *stream, int reset);
extern int uvc_video_enable(struct uvc_streaming *stream, int enable);
extern int uvc_probe_video(struct uvc_streaming *stream,
struct uvc_streaming_control *probe);
/* edit by Ian -- patch for GEO */
extern int uvc_commit_video(struct uvc_streaming *stream,
struct uvc_streaming_control *probe);
extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
__u8 intfnum, __u8 cs, void *data, __u16 size);
/* edit by Ian -- disable uvc clock api*/
#if 0
void uvc_video_clock_update(struct uvc_streaming *stream,
struct v4l2_buffer *v4l2_buf,
struct uvc_buffer *buf);
#endif
/* Status */
//#define UVC_STATUS_EN
#ifdef UVC_STATUS_EN
extern int uvc_status_init(struct uvc_device *dev);
extern void uvc_status_cleanup(struct uvc_device *dev);
extern int uvc_status_start(struct uvc_device *dev, gfp_t flags);
extern void uvc_status_stop(struct uvc_device *dev);
#endif
/* Controls */
extern const struct v4l2_subscribed_event_ops uvc_ctrl_sub_ev_ops;
extern int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
struct v4l2_queryctrl *v4l2_ctrl);
extern int uvc_query_v4l2_menu(struct uvc_video_chain *chain,
struct v4l2_querymenu *query_menu);
extern int uvc_ctrl_add_mapping(struct uvc_video_chain *chain,
const struct uvc_control_mapping *mapping);
extern int uvc_ctrl_init_device(struct uvc_device *dev);
extern void uvc_ctrl_cleanup_device(struct uvc_device *dev);
extern int uvc_ctrl_resume_device(struct uvc_device *dev);
extern int uvc_ctrl_begin(struct uvc_video_chain *chain);
extern int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback,
const struct v4l2_ext_control *xctrls,
unsigned int xctrls_count);
static inline int uvc_ctrl_commit(struct uvc_fh *handle,
const struct v4l2_ext_control *xctrls,
unsigned int xctrls_count)
{
return __uvc_ctrl_commit(handle, 0, xctrls, xctrls_count);
}
static inline int uvc_ctrl_rollback(struct uvc_fh *handle)
{
return __uvc_ctrl_commit(handle, 1, NULL, 0);
}
extern int uvc_ctrl_get(struct uvc_video_chain *chain,
struct v4l2_ext_control *xctrl);
extern int uvc_ctrl_set(struct uvc_video_chain *chain,
struct v4l2_ext_control *xctrl);
//edit by Ian -- remove uvc_xu_ctrl_query declaration
//extern int uvc_xu_ctrl_query(struct uvc_video_chain *chain, struct uvc_xu_control_query *xqry);
/* Utility functions */
extern void uvc_simplify_fraction(uint32_t *numerator, uint32_t *denominator,
unsigned int n_terms, unsigned int threshold);
extern uint32_t uvc_fraction_to_interval(uint32_t numerator,
uint32_t denominator);
extern struct usb_host_endpoint *uvc_find_endpoint(
struct usb_host_interface *alts, __u8 epaddr);
/* Quirks support */
void uvc_video_decode_isight(struct urb *urb, struct uvc_streaming *stream,
struct uvc_buffer *buf);
/* debugfs and statistics */
#if 0
int uvc_debugfs_init(void);
void uvc_debugfs_cleanup(void);
int uvc_debugfs_init_stream(struct uvc_streaming *stream);
void uvc_debugfs_cleanup_stream(struct uvc_streaming *stream);
size_t uvc_video_stats_dump(struct uvc_streaming *stream, char *buf,
size_t size);
#endif
#endif

View file

@ -0,0 +1,766 @@
/*
* USB Video Class definitions.
*
* Copyright (C) 2009 Laurent Pinchart <laurent.pinchart@skynet.be>
*
* This file holds USB constants and structures defined by the USB Device
* Class Definition for Video Devices. Unless otherwise stated, comments
* below reference relevant sections of the USB Video Class 1.1 specification
* available at
*
* http://www.usb.org/developers/devclass_docs/USB_Video_Class_1_1.zip
*/
#ifndef __LINUX_USB_VIDEO_H
#define __LINUX_USB_VIDEO_H
#if 0
#include <linux/types.h>
#endif
/* --------------------------------------------------------------------------
* UVC constants
*/
/* A.2. Video Interface Subclass Codes */
#define UVC_SC_UNDEFINED 0x00
#define UVC_SC_VIDEOCONTROL 0x01
#define UVC_SC_VIDEOSTREAMING 0x02
#define UVC_SC_VIDEO_INTERFACE_COLLECTION 0x03
/* A.3. Video Interface Protocol Codes */
#define UVC_PC_PROTOCOL_UNDEFINED 0x00
/* A.5. Video Class-Specific VC Interface Descriptor Subtypes */
#define UVC_VC_DESCRIPTOR_UNDEFINED 0x00
#define UVC_VC_HEADER 0x01
#define UVC_VC_INPUT_TERMINAL 0x02
#define UVC_VC_OUTPUT_TERMINAL 0x03
#define UVC_VC_SELECTOR_UNIT 0x04
#define UVC_VC_PROCESSING_UNIT 0x05
#define UVC_VC_EXTENSION_UNIT 0x06
/* A.6. Video Class-Specific VS Interface Descriptor Subtypes */
#define UVC_VS_UNDEFINED 0x00
#define UVC_VS_INPUT_HEADER 0x01
#define UVC_VS_OUTPUT_HEADER 0x02
#define UVC_VS_STILL_IMAGE_FRAME 0x03
#define UVC_VS_FORMAT_UNCOMPRESSED 0x04
#define UVC_VS_FRAME_UNCOMPRESSED 0x05
#define UVC_VS_FORMAT_MJPEG 0x06
#define UVC_VS_FRAME_MJPEG 0x07
#define UVC_VS_FORMAT_MPEG2TS 0x0a
#define UVC_VS_FORMAT_DV 0x0c
#define UVC_VS_COLORFORMAT 0x0d
#define UVC_VS_FORMAT_FRAME_BASED 0x10
#define UVC_VS_FRAME_FRAME_BASED 0x11
#define UVC_VS_FORMAT_STREAM_BASED 0x12
/* A.7. Video Class-Specific Endpoint Descriptor Subtypes */
#define UVC_EP_UNDEFINED 0x00
#define UVC_EP_GENERAL 0x01
#define UVC_EP_ENDPOINT 0x02
#define UVC_EP_INTERRUPT 0x03
/* A.8. Video Class-Specific Request Codes */
#define UVC_RC_UNDEFINED 0x00
#define UVC_SET_CUR 0x01
#define UVC_GET_CUR 0x81
#define UVC_GET_MIN 0x82
#define UVC_GET_MAX 0x83
#define UVC_GET_RES 0x84
#define UVC_GET_LEN 0x85
#define UVC_GET_INFO 0x86
#define UVC_GET_DEF 0x87
/* A.9.1. VideoControl Interface Control Selectors */
#define UVC_VC_CONTROL_UNDEFINED 0x00
#define UVC_VC_VIDEO_POWER_MODE_CONTROL 0x01
#define UVC_VC_REQUEST_ERROR_CODE_CONTROL 0x02
/* A.9.2. Terminal Control Selectors */
#define UVC_TE_CONTROL_UNDEFINED 0x00
/* A.9.3. Selector Unit Control Selectors */
#define UVC_SU_CONTROL_UNDEFINED 0x00
#define UVC_SU_INPUT_SELECT_CONTROL 0x01
/* A.9.4. Camera Terminal Control Selectors */
#define UVC_CT_CONTROL_UNDEFINED 0x00
#define UVC_CT_SCANNING_MODE_CONTROL 0x01
#define UVC_CT_AE_MODE_CONTROL 0x02
#define UVC_CT_AE_PRIORITY_CONTROL 0x03
#define UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x04
#define UVC_CT_EXPOSURE_TIME_RELATIVE_CONTROL 0x05
#define UVC_CT_FOCUS_ABSOLUTE_CONTROL 0x06
#define UVC_CT_FOCUS_RELATIVE_CONTROL 0x07
#define UVC_CT_FOCUS_AUTO_CONTROL 0x08
#define UVC_CT_IRIS_ABSOLUTE_CONTROL 0x09
#define UVC_CT_IRIS_RELATIVE_CONTROL 0x0a
#define UVC_CT_ZOOM_ABSOLUTE_CONTROL 0x0b
#define UVC_CT_ZOOM_RELATIVE_CONTROL 0x0c
#define UVC_CT_PANTILT_ABSOLUTE_CONTROL 0x0d
#define UVC_CT_PANTILT_RELATIVE_CONTROL 0x0e
#define UVC_CT_ROLL_ABSOLUTE_CONTROL 0x0f
#define UVC_CT_ROLL_RELATIVE_CONTROL 0x10
#define UVC_CT_PRIVACY_CONTROL 0x11
/* A.9.5. Processing Unit Control Selectors */
#define UVC_PU_CONTROL_UNDEFINED 0x00
#define UVC_PU_BACKLIGHT_COMPENSATION_CONTROL 0x01
#define UVC_PU_BRIGHTNESS_CONTROL 0x02
#define UVC_PU_CONTRAST_CONTROL 0x03
#define UVC_PU_GAIN_CONTROL 0x04
#define UVC_PU_POWER_LINE_FREQUENCY_CONTROL 0x05
#define UVC_PU_HUE_CONTROL 0x06
#define UVC_PU_SATURATION_CONTROL 0x07
#define UVC_PU_SHARPNESS_CONTROL 0x08
#define UVC_PU_GAMMA_CONTROL 0x09
#define UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x0a
#define UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL 0x0b
#define UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL 0x0c
#define UVC_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL 0x0d
#define UVC_PU_DIGITAL_MULTIPLIER_CONTROL 0x0e
#define UVC_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x0f
#define UVC_PU_HUE_AUTO_CONTROL 0x10
#define UVC_PU_ANALOG_VIDEO_STANDARD_CONTROL 0x11
#define UVC_PU_ANALOG_LOCK_STATUS_CONTROL 0x12
/* A.9.7. VideoStreaming Interface Control Selectors */
#define UVC_VS_CONTROL_UNDEFINED 0x00
#define UVC_VS_PROBE_CONTROL 0x01
#define UVC_VS_COMMIT_CONTROL 0x02
#define UVC_VS_STILL_PROBE_CONTROL 0x03
#define UVC_VS_STILL_COMMIT_CONTROL 0x04
#define UVC_VS_STILL_IMAGE_TRIGGER_CONTROL 0x05
#define UVC_VS_STREAM_ERROR_CODE_CONTROL 0x06
#define UVC_VS_GENERATE_KEY_FRAME_CONTROL 0x07
#define UVC_VS_UPDATE_FRAME_SEGMENT_CONTROL 0x08
#define UVC_VS_SYNC_DELAY_CONTROL 0x09
/* B.1. USB Terminal Types */
#define UVC_TT_VENDOR_SPECIFIC 0x0100
#define UVC_TT_STREAMING 0x0101
/* B.2. Input Terminal Types */
#define UVC_ITT_VENDOR_SPECIFIC 0x0200
#define UVC_ITT_CAMERA 0x0201
#define UVC_ITT_MEDIA_TRANSPORT_INPUT 0x0202
/* B.3. Output Terminal Types */
#define UVC_OTT_VENDOR_SPECIFIC 0x0300
#define UVC_OTT_DISPLAY 0x0301
#define UVC_OTT_MEDIA_TRANSPORT_OUTPUT 0x0302
/* B.4. External Terminal Types */
#define UVC_EXTERNAL_VENDOR_SPECIFIC 0x0400
#define UVC_COMPOSITE_CONNECTOR 0x0401
#define UVC_SVIDEO_CONNECTOR 0x0402
#define UVC_COMPONENT_CONNECTOR 0x0403
/* 2.4.2.2. Status Packet Type */
#define UVC_STATUS_TYPE_CONTROL 1
#define UVC_STATUS_TYPE_STREAMING 2
/* 2.4.3.3. Payload Header Information */
#define UVC_STREAM_EOH (1 << 7)
#define UVC_STREAM_ERR (1 << 6)
#define UVC_STREAM_STI (1 << 5)
#define UVC_STREAM_RES (1 << 4)
#define UVC_STREAM_SCR (1 << 3)
#define UVC_STREAM_PTS (1 << 2)
#define UVC_STREAM_EOF (1 << 1)
#define UVC_STREAM_FID (1 << 0)
/* 4.1.2. Control Capabilities */
#define UVC_CONTROL_CAP_GET (1 << 0)
#define UVC_CONTROL_CAP_SET (1 << 1)
#define UVC_CONTROL_CAP_DISABLED (1 << 2)
#define UVC_CONTROL_CAP_AUTOUPDATE (1 << 3)
#define UVC_CONTROL_CAP_ASYNCHRONOUS (1 << 4)
/* ------------------------------------------------------------------------
* UVC structures
*/
/* All UVC descriptors have these 3 fields at the beginning */
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_begin.h"
#endif
RTW_PACK_STRUCT_BEGIN
struct uvc_descriptor_header {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubType;
} //__attribute__((packed));
RTW_PACK_STRUCT_STRUCT;
RTW_PACK_STRUCT_END
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_end.h"
#endif
/* 3.7.2. Video Control Interface Header Descriptor */
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_begin.h"
#endif
RTW_PACK_STRUCT_BEGIN
struct uvc_header_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubType;
__u16 bcdUVC;
__u16 wTotalLength;
__u32 dwClockFrequency;
__u8 bInCollection;
__u8 baInterfaceNr[];
} //__attribute__((__packed__));
RTW_PACK_STRUCT_STRUCT;
RTW_PACK_STRUCT_END
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_end.h"
#endif
#define UVC_DT_HEADER_SIZE(n) (12+(n))
#define UVC_HEADER_DESCRIPTOR(n) \
uvc_header_descriptor_##n
#define DECLARE_UVC_HEADER_DESCRIPTOR(n) \
struct UVC_HEADER_DESCRIPTOR(n) { \
__u8 bLength; \
__u8 bDescriptorType; \
__u8 bDescriptorSubType; \
__u16 bcdUVC; \
__u16 wTotalLength; \
__u32 dwClockFrequency; \
__u8 bInCollection; \
__u8 baInterfaceNr[n]; \
} __attribute__ ((packed))
/* 3.7.2.1. Input Terminal Descriptor */
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_begin.h"
#endif
RTW_PACK_STRUCT_BEGIN
struct uvc_input_terminal_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubType;
__u8 bTerminalID;
__u16 wTerminalType;
__u8 bAssocTerminal;
__u8 iTerminal;
} //__attribute__((__packed__));
RTW_PACK_STRUCT_STRUCT;
RTW_PACK_STRUCT_END
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_end.h"
#endif
#define UVC_DT_INPUT_TERMINAL_SIZE 8
/* 3.7.2.2. Output Terminal Descriptor */
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_begin.h"
#endif
RTW_PACK_STRUCT_BEGIN
struct uvc_output_terminal_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubType;
__u8 bTerminalID;
__u16 wTerminalType;
__u8 bAssocTerminal;
__u8 bSourceID;
__u8 iTerminal;
} //__attribute__((__packed__));
RTW_PACK_STRUCT_STRUCT;
RTW_PACK_STRUCT_END
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_end.h"
#endif
#define UVC_DT_OUTPUT_TERMINAL_SIZE 9
/* 3.7.2.3. Camera Terminal Descriptor */
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_begin.h"
#endif
RTW_PACK_STRUCT_BEGIN
struct uvc_camera_terminal_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubType;
__u8 bTerminalID;
__u16 wTerminalType;
__u8 bAssocTerminal;
__u8 iTerminal;
__u16 wObjectiveFocalLengthMin;
__u16 wObjectiveFocalLengthMax;
__u16 wOcularFocalLength;
__u8 bControlSize;
__u8 bmControls[3];
} //__attribute__((__packed__));
RTW_PACK_STRUCT_STRUCT;
RTW_PACK_STRUCT_END
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_end.h"
#endif
#define UVC_DT_CAMERA_TERMINAL_SIZE(n) (15+(n))
/* 3.7.2.4. Selector Unit Descriptor */
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_begin.h"
#endif
RTW_PACK_STRUCT_BEGIN
struct uvc_selector_unit_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubType;
__u8 bUnitID;
__u8 bNrInPins;
// __u8 baSourceID[0];
__u8 * baSourceID;
__u8 iSelector;
} //__attribute__((__packed__));
RTW_PACK_STRUCT_STRUCT;
RTW_PACK_STRUCT_END
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_end.h"
#endif
#define UVC_DT_SELECTOR_UNIT_SIZE(n) (6+(n))
#define UVC_SELECTOR_UNIT_DESCRIPTOR(n) \
uvc_selector_unit_descriptor_##n
#define DECLARE_UVC_SELECTOR_UNIT_DESCRIPTOR(n) \
struct UVC_SELECTOR_UNIT_DESCRIPTOR(n) { \
__u8 bLength; \
__u8 bDescriptorType; \
__u8 bDescriptorSubType; \
__u8 bUnitID; \
__u8 bNrInPins; \
__u8 baSourceID[n]; \
__u8 iSelector; \
} __attribute__ ((packed))
/* 3.7.2.5. Processing Unit Descriptor */
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_begin.h"
#endif
RTW_PACK_STRUCT_BEGIN
struct uvc_processing_unit_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubType;
__u8 bUnitID;
__u8 bSourceID;
__u16 wMaxMultiplier;
__u8 bControlSize;
__u8 bmControls[2];
__u8 iProcessing;
} //__attribute__((__packed__));
RTW_PACK_STRUCT_STRUCT;
RTW_PACK_STRUCT_END
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_end.h"
#endif
#define UVC_DT_PROCESSING_UNIT_SIZE(n) (9+(n))
/* 3.7.2.6. Extension Unit Descriptor */
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_begin.h"
#endif
RTW_PACK_STRUCT_BEGIN
struct uvc_extension_unit_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubType;
__u8 bUnitID;
__u8 guidExtensionCode[16];
__u8 bNumControls;
__u8 bNrInPins;
// __u8 baSourceID[0];
__u8 * baSourceID;
__u8 bControlSize;
// __u8 bmControls[0];
__u8 * bmControls;
__u8 iExtension;
} //__attribute__((__packed__));
RTW_PACK_STRUCT_STRUCT;
RTW_PACK_STRUCT_END
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_end.h"
#endif
#define UVC_DT_EXTENSION_UNIT_SIZE(p, n) (24+(p)+(n))
#define UVC_EXTENSION_UNIT_DESCRIPTOR(p, n) \
uvc_extension_unit_descriptor_##p_##n
#define DECLARE_UVC_EXTENSION_UNIT_DESCRIPTOR(p, n) \
struct UVC_EXTENSION_UNIT_DESCRIPTOR(p, n) { \
__u8 bLength; \
__u8 bDescriptorType; \
__u8 bDescriptorSubType; \
__u8 bUnitID; \
__u8 guidExtensionCode[16]; \
__u8 bNumControls; \
__u8 bNrInPins; \
__u8 baSourceID[p]; \
__u8 bControlSize; \
__u8 bmControls[n]; \
__u8 iExtension; \
} __attribute__ ((packed))
/* 3.8.2.2. Video Control Interrupt Endpoint Descriptor */
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_begin.h"
#endif
RTW_PACK_STRUCT_BEGIN
struct uvc_control_endpoint_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubType;
__u16 wMaxTransferSize;
} //__attribute__((__packed__));
RTW_PACK_STRUCT_STRUCT;
RTW_PACK_STRUCT_END
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_end.h"
#endif
#define UVC_DT_CONTROL_ENDPOINT_SIZE 5
/* 3.9.2.1. Input Header Descriptor */
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_begin.h"
#endif
RTW_PACK_STRUCT_BEGIN
struct uvc_input_header_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubType;
__u8 bNumFormats;
__u16 wTotalLength;
__u8 bEndpointAddress;
__u8 bmInfo;
__u8 bTerminalLink;
__u8 bStillCaptureMethod;
__u8 bTriggerSupport;
__u8 bTriggerUsage;
__u8 bControlSize;
__u8 bmaControls[];
} //__attribute__((__packed__));
RTW_PACK_STRUCT_STRUCT;
RTW_PACK_STRUCT_END
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_end.h"
#endif
#define UVC_DT_INPUT_HEADER_SIZE(n, p) (13+(n*p))
#define UVC_INPUT_HEADER_DESCRIPTOR(n, p) \
uvc_input_header_descriptor_##n_##p
#define DECLARE_UVC_INPUT_HEADER_DESCRIPTOR(n, p) \
struct UVC_INPUT_HEADER_DESCRIPTOR(n, p) { \
__u8 bLength; \
__u8 bDescriptorType; \
__u8 bDescriptorSubType; \
__u8 bNumFormats; \
__u16 wTotalLength; \
__u8 bEndpointAddress; \
__u8 bmInfo; \
__u8 bTerminalLink; \
__u8 bStillCaptureMethod; \
__u8 bTriggerSupport; \
__u8 bTriggerUsage; \
__u8 bControlSize; \
__u8 bmaControls[p][n]; \
} __attribute__ ((packed))
/* 3.9.2.2. Output Header Descriptor */
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_begin.h"
#endif
RTW_PACK_STRUCT_BEGIN
struct uvc_output_header_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubType;
__u8 bNumFormats;
__u16 wTotalLength;
__u8 bEndpointAddress;
__u8 bTerminalLink;
__u8 bControlSize;
__u8 bmaControls[];
} //__attribute__((__packed__));
RTW_PACK_STRUCT_STRUCT;
RTW_PACK_STRUCT_END
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_end.h"
#endif
#define UVC_DT_OUTPUT_HEADER_SIZE(n, p) (9+(n*p))
#define UVC_OUTPUT_HEADER_DESCRIPTOR(n, p) \
uvc_output_header_descriptor_##n_##p
#define DECLARE_UVC_OUTPUT_HEADER_DESCRIPTOR(n, p) \
struct UVC_OUTPUT_HEADER_DESCRIPTOR(n, p) { \
__u8 bLength; \
__u8 bDescriptorType; \
__u8 bDescriptorSubType; \
__u8 bNumFormats; \
__u16 wTotalLength; \
__u8 bEndpointAddress; \
__u8 bTerminalLink; \
__u8 bControlSize; \
__u8 bmaControls[p][n]; \
} __attribute__ ((packed))
/* 3.9.2.6. Color matching descriptor */
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_begin.h"
#endif
RTW_PACK_STRUCT_BEGIN
struct uvc_color_matching_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubType;
__u8 bColorPrimaries;
__u8 bTransferCharacteristics;
__u8 bMatrixCoefficients;
} //__attribute__((__packed__));
RTW_PACK_STRUCT_STRUCT;
RTW_PACK_STRUCT_END
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_end.h"
#endif
#define UVC_DT_COLOR_MATCHING_SIZE 6
/* 4.3.1.1. Video Probe and Commit Controls */
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_begin.h"
#endif
RTW_PACK_STRUCT_BEGIN
struct uvc_streaming_control {
__u16 bmHint;
__u8 bFormatIndex;
__u8 bFrameIndex;
__u32 dwFrameInterval;
__u16 wKeyFrameRate;
__u16 wPFrameRate;
__u16 wCompQuality;
__u16 wCompWindowSize;
__u16 wDelay;
__u32 dwMaxVideoFrameSize;
__u32 dwMaxPayloadTransferSize;
__u32 dwClockFrequency;
__u8 bmFramingInfo;
__u8 bPreferedVersion;
__u8 bMinVersion;
__u8 bMaxVersion;
} //__attribute__((__packed__));
RTW_PACK_STRUCT_STRUCT;
RTW_PACK_STRUCT_END
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_end.h"
#endif
/* Uncompressed Payload - 3.1.1. Uncompressed Video Format Descriptor */
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_begin.h"
#endif
RTW_PACK_STRUCT_BEGIN
struct uvc_format_uncompressed {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubType;
__u8 bFormatIndex;
__u8 bNumFrameDescriptors;
__u8 guidFormat[16];
__u8 bBitsPerPixel;
__u8 bDefaultFrameIndex;
__u8 bAspectRatioX;
__u8 bAspectRatioY;
__u8 bmInterfaceFlags;
__u8 bCopyProtect;
} //__attribute__((__packed__));
RTW_PACK_STRUCT_STRUCT;
RTW_PACK_STRUCT_END
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_end.h"
#endif
#define UVC_DT_FORMAT_UNCOMPRESSED_SIZE 27
/* Uncompressed Payload - 3.1.2. Uncompressed Video Frame Descriptor */
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_begin.h"
#endif
RTW_PACK_STRUCT_BEGIN
struct uvc_frame_uncompressed {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubType;
__u8 bFrameIndex;
__u8 bmCapabilities;
__u16 wWidth;
__u16 wHeight;
__u32 dwMinBitRate;
__u32 dwMaxBitRate;
__u32 dwMaxVideoFrameBufferSize;
__u32 dwDefaultFrameInterval;
__u8 bFrameIntervalType;
__u32 dwFrameInterval[];
} //__attribute__((__packed__));
RTW_PACK_STRUCT_STRUCT;
RTW_PACK_STRUCT_END
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_end.h"
#endif
#define UVC_DT_FRAME_UNCOMPRESSED_SIZE(n) (26+4*(n))
#define UVC_FRAME_UNCOMPRESSED(n) \
uvc_frame_uncompressed_##n
#define DECLARE_UVC_FRAME_UNCOMPRESSED(n) \
struct UVC_FRAME_UNCOMPRESSED(n) { \
__u8 bLength; \
__u8 bDescriptorType; \
__u8 bDescriptorSubType; \
__u8 bFrameIndex; \
__u8 bmCapabilities; \
__u16 wWidth; \
__u16 wHeight; \
__u32 dwMinBitRate; \
__u32 dwMaxBitRate; \
__u32 dwMaxVideoFrameBufferSize; \
__u32 dwDefaultFrameInterval; \
__u8 bFrameIntervalType; \
__u32 dwFrameInterval[n]; \
} __attribute__ ((packed))
/* MJPEG Payload - 3.1.1. MJPEG Video Format Descriptor */
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_begin.h"
#endif
RTW_PACK_STRUCT_BEGIN
struct uvc_format_mjpeg {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubType;
__u8 bFormatIndex;
__u8 bNumFrameDescriptors;
__u8 bmFlags;
__u8 bDefaultFrameIndex;
__u8 bAspectRatioX;
__u8 bAspectRatioY;
__u8 bmInterfaceFlags;
__u8 bCopyProtect;
} //__attribute__((__packed__));
RTW_PACK_STRUCT_STRUCT;
RTW_PACK_STRUCT_END
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_end.h"
#endif
#define UVC_DT_FORMAT_MJPEG_SIZE 11
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_begin.h"
#endif
RTW_PACK_STRUCT_BEGIN
/* MJPEG Payload - 3.1.2. MJPEG Video Frame Descriptor */
struct uvc_frame_mjpeg {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubType;
__u8 bFrameIndex;
__u8 bmCapabilities;
__u16 wWidth;
__u16 wHeight;
__u32 dwMinBitRate;
__u32 dwMaxBitRate;
__u32 dwMaxVideoFrameBufferSize;
__u32 dwDefaultFrameInterval;
__u8 bFrameIntervalType;
__u32 dwFrameInterval[];
} //__attribute__((__packed__));
RTW_PACK_STRUCT_STRUCT;
RTW_PACK_STRUCT_END
#ifdef RTW_PACK_STRUCT_USE_INCLUDES
# include "pack_end.h"
#endif
#define UVC_DT_FRAME_MJPEG_SIZE(n) (26+4*(n))
#define UVC_FRAME_MJPEG(n) \
uvc_frame_mjpeg_##n
#define DECLARE_UVC_FRAME_MJPEG(n) \
struct UVC_FRAME_MJPEG(n) { \
__u8 bLength; \
__u8 bDescriptorType; \
__u8 bDescriptorSubType; \
__u8 bFrameIndex; \
__u8 bmCapabilities; \
__u16 wWidth; \
__u16 wHeight; \
__u32 dwMinBitRate; \
__u32 dwMaxBitRate; \
__u32 dwMaxVideoFrameBufferSize; \
__u32 dwDefaultFrameInterval; \
__u8 bFrameIntervalType; \
__u32 dwFrameInterval[n]; \
} __attribute__ ((packed))
/* Framebased Payload - 3.1.2. Framebased Video Frame Descriptor */
#define UVC_DT_FRAME_FRAMEBASED_SIZE(n) (26+4*(n))
#define UVC_FRAME_FRAMEBASED(n) \
uvc_frame_framebased_##n
#define DECLARE_UVC_FRAME_FRAMEBASED(n) \
struct UVC_FRAME_FRAMEBASED(n) { \
__u8 bLength; \
__u8 bDescriptorType; \
__u8 bDescriptorSubType; \
__u8 bFrameIndex; \
__u8 bmCapabilities; \
__u16 wWidth; \
__u16 wHeight; \
__u32 dwMinBitRate; \
__u32 dwMaxBitRate; \
__u32 dwDefaultFrameInterval; \
__u8 bFrameIntervalType; \
__u32 dwBytesPerLine; \
__u32 dwFrameInterval[n]; \
} __attribute__ ((packed))
#define UVC_DT_FORMAT_FRAMEBASED_SIZE 28
struct uvc_format_framebased {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubType;
__u8 bFormatIndex;
__u8 bNumFrameDescriptors;
__u8 guidFormat[16];
__u8 bBitsPerPixel;
__u8 bDefaultFrameIndex;
__u8 bAspectRatioX;
__u8 bAspectRatioY;
__u8 bmInterfaceFlags;
__u8 bCopyProtect;
__u8 bVariableSize;
} __attribute__((__packed__));
#endif /* __LINUX_USB_VIDEO_H */

View file

@ -0,0 +1,19 @@
#ifndef ISOOUT_TEST_H
#define ISOOUT_TEST_H
/******************************************************/
/* Control define */
/******************************************************/
#define USBH_ENABLE_ISOIN
#define USBH_ENABLE_ISOOUT
//--
#define USBD_ENABE_ISOIN_USB_REQ_ISO_ASAP
//#define USBD_ENABE_ISOOUT_USB_REQ_ISO_ASAP
/******************************************************/
/* Parameter define */
/******************************************************/
#define USB_ISOOUT_TRANSFER_CNT 100
#endif

View file

@ -0,0 +1,18 @@
/*
header file for vendor spec driver
*/
//#define ctrl_test
//#define bulk_test
#define iso_test_in
#define iso_test_out
#define IN_STORAGE_SIZE 512
#define IN_BUFFER_SIZE 128
#define OUT_BUFFER_SIZE 128
#define USB_IN_CNT 100
//#define ctrl_test
int vs_init(void); //entry function to start vs
void vs_free(void);