mirror of
https://github.com/pvvx/RTL00MP3.git
synced 2025-07-31 12:41:06 +00:00
add and update
This commit is contained in:
parent
03ed2886cb
commit
bda4d33012
109 changed files with 73065 additions and 85 deletions
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef _ETH_DEBUG_H_
|
||||
#define _ETH_DEBUG_H_
|
||||
|
||||
#define ETH_DEBUG 0
|
||||
|
||||
#if ETH_DEBUG
|
||||
#define ETH_PRINT(fmt, args...) printf("\n\r[%s]%s: " fmt, __FUNCTION__, ## args)
|
||||
#define ETH_ERROR(fmt, args...) printf("\n\r[%s]%s: " fmt, __FUNCTION__, ## args)
|
||||
#define ETH_WARM(fmt, args...) printf("\n\r[%s]%s: " fmt, __FUNCTION__, ## args)
|
||||
#define FUN_ENTER printf("\n\r[%s ==>]\n", __func__)
|
||||
#define FUN_EXIT printf("\n\r[%s <==]\n", __func__)
|
||||
#define FUN_TRACE printf("\n\r[%s]:%d \n", __func__, __LINE__)
|
||||
#else
|
||||
#define ETH_PRINT(fmt, args...)
|
||||
#define ETH_ERROR(fmt, args...) printf("\n\r%s: " fmt,__FUNCTION__, ## args)
|
||||
#define ETH_WARM(fmt, args...)
|
||||
#define FUN_ENTER
|
||||
#define FUN_EXIT
|
||||
#define FUN_TRACE
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,358 @@
|
|||
/*
|
||||
* Ethernet gadget driver -- with CDC and non-CDC options
|
||||
* Builds on hardware support for a full duplex link.
|
||||
*
|
||||
* CDC Ethernet is the standard USB solution for sending Ethernet frames
|
||||
* using USB. Real hardware tends to use the same framing protocol but look
|
||||
* different for control features. This driver strongly prefers to use
|
||||
* this USB-IF standard as its open-systems interoperability solution;
|
||||
* most host side USB stacks (except from Microsoft) support it.
|
||||
*
|
||||
* There's some hardware that can't talk CDC. We make that hardware
|
||||
* implement a "minimalist" vendor-agnostic CDC core: same framing, but
|
||||
* link-level setup only requires activating the configuration.
|
||||
* Linux supports it, but other host operating systems may not.
|
||||
* (This is a subset of CDC Ethernet.)
|
||||
*
|
||||
* A third option is also in use. Rather than CDC Ethernet, or something
|
||||
* simpler, Microsoft pushes their own approach: RNDIS. The published
|
||||
* RNDIS specs are ambiguous and appear to be incomplete, and are also
|
||||
* needlessly complex.
|
||||
*/
|
||||
#ifndef __USB_ETHERNET_H
|
||||
#define __USB_ETHERNET_H
|
||||
|
||||
#include "usb.h"
|
||||
#include "usb_gadget.h"
|
||||
#include "core/inc/usb_composite.h"
|
||||
|
||||
//#define DRIVER_DESC "Ethernet Gadget"
|
||||
#define DRIVER_DESC "USB Network Interface"
|
||||
#define DRIVER_VERSION "May Day 2015"
|
||||
#define ETH_ADDR "00E04C8196C8"
|
||||
|
||||
static const char shortname [] = "ether";
|
||||
static const char driver_desc [] = DRIVER_DESC;
|
||||
|
||||
#define CONFIG_USB_ETH_RNDIS 1
|
||||
|
||||
|
||||
#define RNDIS_VENDOR_NUM ULINKER_ETHER_VID
|
||||
#define RNDIS_PRODUCT_NUM ULINKER_ETHER_PID
|
||||
|
||||
|
||||
/* Thanks to NetChip Technologies for donating this product ID.
|
||||
* It's for devices with only CDC Ethernet configurations.
|
||||
*/
|
||||
#define CDC_VENDOR_NUM 0x0525 /* NetChip */
|
||||
#define CDC_PRODUCT_NUM 0xa4a1 /* Linux-USB Ethernet Gadget */
|
||||
|
||||
/* USB DRIVER HOOKUP (to the hardware driver, below us), mostly
|
||||
* ep0 implementation: descriptors, config management, setup().
|
||||
* also optional class-specific notification interrupt transfer.
|
||||
*/
|
||||
|
||||
/*
|
||||
* DESCRIPTORS ... most are static, but strings and (full) configuration
|
||||
* descriptors are built on demand. For now we do either full CDC, or
|
||||
* our simple subset, with RNDIS as an optional second configuration.
|
||||
*
|
||||
* RNDIS includes some CDC ACM descriptors ... like CDC Ethernet. But
|
||||
* the class descriptors match a modem (they're ignored; it's really just
|
||||
* Ethernet functionality), they don't need the NOP altsetting, and the
|
||||
* status transfer endpoint isn't optional.
|
||||
*/
|
||||
|
||||
#define STRING_MANUFACTURER 1
|
||||
#define STRING_PRODUCT 2
|
||||
#define STRING_ETHADDR 3
|
||||
#define STRING_DATA 4
|
||||
#define STRING_CONTROL 5
|
||||
#define STRING_RNDIS_CONTROL 6
|
||||
#define STRING_CDC 7
|
||||
#define STRING_SUBSET 8
|
||||
#define STRING_RNDIS 9
|
||||
#define STRING_SERIALNUMBER 10
|
||||
|
||||
/* holds our biggest descriptor (or RNDIS response) */
|
||||
#define USB_BUFSIZ 256
|
||||
|
||||
#define BUFSIZ_IN 512
|
||||
#define BUFSIZ_OUT 512
|
||||
/*
|
||||
* This device advertises one configuration, eth_config, unless RNDIS
|
||||
* is enabled (rndis_config) on hardware supporting at least two configs.
|
||||
*
|
||||
* NOTE: Controllers like superh_udc should probably be able to use
|
||||
* an RNDIS-only configuration.
|
||||
*
|
||||
* FIXME define some higher-powered configurations to make it easier
|
||||
* to recharge batteries ...
|
||||
*/
|
||||
|
||||
//#define DEV_CONFIG_VALUE 1 /* cdc or subset */
|
||||
//#define DEV_RNDIS_CONFIG_VALUE 2 /* rndis; optional */
|
||||
#define DEV_CONFIG_VALUE 2 /* cdc or subset */
|
||||
#define DEV_RNDIS_CONFIG_VALUE 1 /* rndis; optional */
|
||||
|
||||
|
||||
#define DEVSPEED USB_SPEED_HIGH
|
||||
|
||||
|
||||
/* descriptors that are built on-demand */
|
||||
|
||||
static char manufacturer [50];
|
||||
static char product_desc [40] = DRIVER_DESC;
|
||||
static char serial_number [20];
|
||||
|
||||
|
||||
/* address that the host will use ... usually assigned at random */
|
||||
//ModifiedByJD static char ethaddr [2 * ETH_ALEN + 1];
|
||||
static char ethaddr [2 * 6 + 1] = ETH_ADDR;
|
||||
|
||||
/* static strings, in UTF-8 */
|
||||
static struct usb_string strings [] = {
|
||||
{ STRING_MANUFACTURER, manufacturer, },
|
||||
{ STRING_PRODUCT, product_desc, },
|
||||
{ STRING_SERIALNUMBER, serial_number, },
|
||||
{ STRING_DATA, "Ethernet Data", },
|
||||
#if 1//def DEV_CONFIG_CDC//ModifiedByJD
|
||||
{ STRING_CDC, "CDC Ethernet", },
|
||||
{ STRING_ETHADDR, ethaddr, },
|
||||
{ STRING_CONTROL, "CDC Communications Control", },
|
||||
#endif
|
||||
#if 1//def DEV_CONFIG_SUBSET//ModifiedByJD
|
||||
{ STRING_SUBSET, "CDC Ethernet Subset", },
|
||||
#endif
|
||||
#if 1//def CONFIG_USB_ETH_RNDIS//ModifiedByJD
|
||||
{ STRING_RNDIS, "RNDIS", },
|
||||
{ STRING_RNDIS_CONTROL, "RNDIS Communications Control", },
|
||||
#endif /* end of list */
|
||||
};
|
||||
|
||||
static struct usb_gadget_strings stringtab = {
|
||||
.language = 0x0409, /* en-us */
|
||||
.strings = strings,
|
||||
};
|
||||
|
||||
static struct usb_gadget_strings *dev_strings[] = {
|
||||
&stringtab,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct usb_device_descriptor
|
||||
device_desc = {
|
||||
.bLength = sizeof device_desc,
|
||||
.bDescriptorType = USB_DT_DEVICE,
|
||||
|
||||
.bcdUSB = (0x0200),
|
||||
|
||||
.bDeviceClass = USB_CLASS_COMM,
|
||||
.bDeviceSubClass = 0,
|
||||
.bDeviceProtocol = 0,
|
||||
|
||||
.idVendor = (CDC_VENDOR_NUM),
|
||||
.idProduct = (CDC_PRODUCT_NUM),
|
||||
.iManufacturer = STRING_MANUFACTURER,
|
||||
.iProduct = STRING_PRODUCT,
|
||||
.bNumConfigurations = 1,
|
||||
};
|
||||
|
||||
static struct usb_config_descriptor
|
||||
eth_config = {
|
||||
.bLength = sizeof eth_config,
|
||||
.bDescriptorType = USB_DT_CONFIG,
|
||||
|
||||
/* compute wTotalLength on the fly */
|
||||
.bNumInterfaces = 1,
|
||||
.bConfigurationValue = DEV_CONFIG_VALUE,
|
||||
.iConfiguration = STRING_CDC,
|
||||
.bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
|
||||
.bMaxPower = 50,
|
||||
};
|
||||
|
||||
static struct usb_otg_descriptor
|
||||
otg_descriptor = {
|
||||
.bLength = sizeof otg_descriptor,
|
||||
.bDescriptorType = USB_DT_OTG,
|
||||
|
||||
.bmAttributes = USB_OTG_SRP,
|
||||
};
|
||||
|
||||
|
||||
#ifdef CONFIG_USB_ETH_RNDIS
|
||||
|
||||
/* RNDIS doesn't activate by changing to the "real" altsetting */
|
||||
|
||||
static struct usb_interface_descriptor
|
||||
rndis_data_intf = {
|
||||
.bLength = sizeof rndis_data_intf,
|
||||
.bDescriptorType = USB_DT_INTERFACE,
|
||||
|
||||
.bInterfaceNumber = 0,
|
||||
.bAlternateSetting = 0,
|
||||
.bNumEndpoints = 2,
|
||||
.bInterfaceClass = USB_CLASS_CDC_DATA,
|
||||
.bInterfaceSubClass = 0,
|
||||
.bInterfaceProtocol = 0,
|
||||
.iInterface = STRING_DATA,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static struct usb_endpoint_descriptor
|
||||
hs_source_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = (512),//ModifiedByJD
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor
|
||||
hs_sink_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = (512),//ModifiedByJD
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor
|
||||
fs_source_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
.bEndpointAddress = USB_DIR_IN,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor
|
||||
fs_sink_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
.bEndpointAddress = USB_DIR_OUT,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
};
|
||||
|
||||
|
||||
static const struct usb_descriptor_header *fs_rndis_function [] = {
|
||||
(struct usb_descriptor_header *) &otg_descriptor,
|
||||
/* control interface matches ACM, not Ethernet */
|
||||
#if 0//ModifiedByJD
|
||||
(struct usb_descriptor_header *) &rndis_control_intf,
|
||||
(struct usb_descriptor_header *) &header_desc,
|
||||
(struct usb_descriptor_header *) &call_mgmt_descriptor,
|
||||
(struct usb_descriptor_header *) &acm_descriptor,
|
||||
(struct usb_descriptor_header *) &union_desc,
|
||||
(struct usb_descriptor_header *) &fs_status_desc,
|
||||
#endif
|
||||
/* data interface has no altsetting */
|
||||
(struct usb_descriptor_header *) &rndis_data_intf,
|
||||
(struct usb_descriptor_header *) &fs_source_desc,
|
||||
(struct usb_descriptor_header *) &fs_sink_desc,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
static const struct usb_descriptor_header *fs_eth_function [11] = {
|
||||
(struct usb_descriptor_header *) &otg_descriptor,
|
||||
#ifdef DEV_CONFIG_CDC
|
||||
/* "cdc" mode descriptors */
|
||||
(struct usb_descriptor_header *) &control_intf,
|
||||
(struct usb_descriptor_header *) &header_desc,
|
||||
(struct usb_descriptor_header *) &union_desc,
|
||||
(struct usb_descriptor_header *) ðer_desc,
|
||||
/* NOTE: status endpoint may need to be removed */
|
||||
(struct usb_descriptor_header *) &fs_status_desc,
|
||||
/* data interface, with altsetting */
|
||||
(struct usb_descriptor_header *) &data_nop_intf,
|
||||
(struct usb_descriptor_header *) &data_intf,
|
||||
(struct usb_descriptor_header *) &fs_source_desc,
|
||||
(struct usb_descriptor_header *) &fs_sink_desc,
|
||||
NULL,
|
||||
#endif /* DEV_CONFIG_CDC */
|
||||
};
|
||||
|
||||
#ifdef CONFIG_USB_ETH_RNDIS
|
||||
static const struct usb_descriptor_header *hs_rndis_function [] = {
|
||||
(struct usb_descriptor_header *) &otg_descriptor,
|
||||
/* control interface matches ACM, not Ethernet */
|
||||
#if 0//ModifiedByJD
|
||||
(struct usb_descriptor_header *) &rndis_control_intf,
|
||||
(struct usb_descriptor_header *) &header_desc,
|
||||
(struct usb_descriptor_header *) &call_mgmt_descriptor,
|
||||
(struct usb_descriptor_header *) &acm_descriptor,
|
||||
(struct usb_descriptor_header *) &union_desc,
|
||||
(struct usb_descriptor_header *) &hs_status_desc,
|
||||
#endif
|
||||
/* data interface has no altsetting */
|
||||
(struct usb_descriptor_header *) &rndis_data_intf,
|
||||
(struct usb_descriptor_header *) &hs_source_desc,
|
||||
(struct usb_descriptor_header *) &hs_sink_desc,
|
||||
NULL,
|
||||
};
|
||||
#endif
|
||||
|
||||
static struct usb_config_descriptor
|
||||
rndis_config = {
|
||||
.bLength = sizeof rndis_config,
|
||||
.bDescriptorType = USB_DT_CONFIG,
|
||||
|
||||
/* compute wTotalLength on the fly */
|
||||
.bNumInterfaces = 1,
|
||||
.bConfigurationValue = DEV_RNDIS_CONFIG_VALUE,
|
||||
.iConfiguration = STRING_RNDIS,
|
||||
.bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
|
||||
.bMaxPower = 50,
|
||||
};
|
||||
|
||||
static struct usb_configuration eth_configuration = {
|
||||
.label = "eth_configuration",
|
||||
.bConfigurationValue = DEV_CONFIG_VALUE,
|
||||
// .bConfigurationValue = 1,
|
||||
/* .iConfiguration = DYNAMIC */
|
||||
.bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
|
||||
};
|
||||
|
||||
|
||||
static struct eth_dev{
|
||||
struct usb_gadget *gadget;
|
||||
struct usb_request *req; /* for control responses */
|
||||
/* when configured, we have one of two configs:
|
||||
* - source data (in to host) and sink it (out from host)
|
||||
* - or loop it back (out from host back in to host)
|
||||
*/
|
||||
u8 config;
|
||||
struct usb_ep *in_ep;
|
||||
struct usb_ep *out_ep;
|
||||
const struct usb_endpoint_descriptor
|
||||
*in, *out, *status;
|
||||
// lock is held when accessing usb
|
||||
_Lock lock;
|
||||
|
||||
struct usb_function func;
|
||||
|
||||
|
||||
|
||||
/*send (depends on host)*/
|
||||
_Sema xmit_sema;
|
||||
xTaskHandle xmit_task;
|
||||
unsigned int qlen;
|
||||
_Mutex xmit_mutex;
|
||||
_LIST eth2wlan_list;
|
||||
/*receive (debuf_poolpends on host)*/
|
||||
_Sema recv_sema;
|
||||
xTaskHandle recv_task;
|
||||
_Mutex recv_mutex;
|
||||
_LIST wlan2eth_list;
|
||||
};
|
||||
|
||||
|
||||
extern int usb_eth_init(void);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
#ifndef USBD_MSC_H
|
||||
#define USBD_MSC_H
|
||||
|
||||
#include "usb.h"
|
||||
#include "usb_gadget.h"
|
||||
#include "core/inc/usb_composite.h"
|
||||
#include "msc/inc/usbd_msc_config.h"
|
||||
|
||||
/* config usb msc device debug inforation */
|
||||
#define USBD_MSC_DEBUG 0
|
||||
|
||||
#if USBD_MSC_DEBUG
|
||||
#define USBD_PRINTF(fmt, args...) DBG_8195A("\n\r%s: " fmt, __FUNCTION__, ## args)
|
||||
#define USBD_ERROR(fmt, args...) DBG_8195A("\n\r%s: " fmt, __FUNCTION__, ## args)
|
||||
#define USBD_WARN(fmt, args...) DBG_8195A("\n\r%s: " fmt, __FUNCTION__, ## args)
|
||||
#define FUN_ENTER DBG_8195A("\n\r%s ==>\n", __func__)
|
||||
#define FUN_EXIT DBG_8195A("\n\r%s <==\n", __func__)
|
||||
#define FUN_TRACE DBG_8195A("\n\r%s:%d \n", __func__, __LINE__)
|
||||
#else
|
||||
#define USBD_PRINTF(fmt, args...)
|
||||
#define USBD_ERROR(fmt, args...) DBG_8195A("\n\r%s: " fmt, __FUNCTION__, ## args)
|
||||
#define USBD_WARN(fmt, args...)
|
||||
#define FUN_ENTER
|
||||
#define FUN_EXIT
|
||||
#define FUN_TRACE
|
||||
#endif
|
||||
|
||||
/* MSC Request Codes */
|
||||
#define MSC_REQUEST_RESET 0xFF
|
||||
#define MSC_REQUEST_GET_MAX_LUN 0xFE
|
||||
|
||||
/* MSC LUN */
|
||||
#define MSC_MAX_LOGIC_UNIT_NUMBER 1
|
||||
|
||||
enum data_direction{
|
||||
DATA_DIR_UNKNOWN = 0,
|
||||
DATA_DIR_FROM_HOST,
|
||||
DATA_DIR_TO_HOST,
|
||||
DATA_DIR_NONE
|
||||
};
|
||||
|
||||
typedef enum _disk_type{
|
||||
DISK_SDCARD,
|
||||
DISK_FLASH
|
||||
}disk_type;
|
||||
|
||||
//structure predefine
|
||||
struct msc_dev;
|
||||
struct msc_bufhd;
|
||||
|
||||
struct msc_opts{
|
||||
int (*disk_init)(void);
|
||||
int (*disk_deinit)(void);
|
||||
int (*disk_getcapacity)(u32* sectors);
|
||||
int (*disk_read)(u32 sector,u8 *buffer,u32 count);
|
||||
int (*disk_write)(u32 sector,const u8 *buffer,u32 count);
|
||||
};
|
||||
|
||||
struct msc_lun {
|
||||
unsigned int initially_ro:1;
|
||||
unsigned int ro:1;
|
||||
unsigned int removable:1;
|
||||
unsigned int cdrom:1;
|
||||
unsigned int prevent_medium_removal:1;
|
||||
unsigned int registered:1;
|
||||
unsigned int info_valid:1;
|
||||
unsigned int nofua:1;
|
||||
|
||||
u32 sense_data;
|
||||
u32 sense_data_info;
|
||||
u32 unit_attention_data;
|
||||
|
||||
u64 file_length;
|
||||
unsigned int num_sectors; /* */
|
||||
unsigned int blkbits; /* Bits of logical block size
|
||||
of bound block device */
|
||||
unsigned int blksize; /* logical block size of bound block device */
|
||||
const char *name; /* "lun.name" */
|
||||
|
||||
unsigned int lba; // the current read and write logical block address
|
||||
u8 is_open;
|
||||
_mutex lun_mutex;
|
||||
struct msc_opts *lun_opts;
|
||||
};
|
||||
|
||||
|
||||
struct msc_common{
|
||||
struct msc_dev *mscdev;
|
||||
|
||||
struct msc_lun **luns;
|
||||
struct msc_lun *curlun;
|
||||
|
||||
struct usb_gadget *gadget;
|
||||
struct usb_ep *ep0;
|
||||
struct usb_request *req0; /* for control responses */
|
||||
|
||||
/* scsi cbw relevant */
|
||||
enum data_direction data_dir;
|
||||
u32 data_size;
|
||||
u32 data_size_from_cmnd;
|
||||
u32 tag;
|
||||
u32 residue;
|
||||
u32 usb_amount_left;
|
||||
u8 scsi_cmnd[16]; // max command
|
||||
u8 cmnd_size;
|
||||
|
||||
u8 lun; /* current lun*/
|
||||
u8 nluns;
|
||||
|
||||
u8 nbufhd;
|
||||
u8 nbufhd_a;
|
||||
_list bufhd_pool;
|
||||
_mutex bufhd_mutex;
|
||||
/* bulk out cmd*/
|
||||
_list boc_list;
|
||||
_mutex boc_mutex;
|
||||
|
||||
/* bolk out data*/
|
||||
_mutex bod_mutex;
|
||||
_list bod_list;
|
||||
/**/
|
||||
struct msc_bufhd* curbh; // current buffer header
|
||||
struct msc_bufhd* cbw_bh; // buffer header for CBW
|
||||
struct msc_bufhd* csw_bh; // buffer header for CSW
|
||||
|
||||
unsigned int can_stall:1;
|
||||
unsigned int phase_error:1;
|
||||
unsigned int short_packet_received:1;
|
||||
unsigned int bad_lun_okay:1;
|
||||
unsigned int running:1;
|
||||
};
|
||||
|
||||
typedef enum _bufhd_type{
|
||||
BUFHD_CBW = 0,
|
||||
BUFHD_CSW,
|
||||
BUFHD_DATA,
|
||||
}bufhd_type;
|
||||
|
||||
struct msc_bufhd{
|
||||
u8* buf;
|
||||
int buf_size;
|
||||
bufhd_type type;
|
||||
_list list;
|
||||
struct usb_request *reqin; /* for bulkin responses */
|
||||
struct usb_request *reqout;
|
||||
};
|
||||
|
||||
struct msc_dev{
|
||||
struct msc_common *common;
|
||||
|
||||
u16 interface_number;
|
||||
u8 config;
|
||||
|
||||
struct usb_ep *in_ep;
|
||||
struct usb_ep *out_ep;
|
||||
unsigned int bulk_in_enabled:1;
|
||||
unsigned int bulk_out_enabled:1;
|
||||
|
||||
const struct usb_endpoint_descriptor
|
||||
*in, *out, *status;
|
||||
// lock is held when accessing usb
|
||||
struct task_struct msc_outCmdTask;
|
||||
struct task_struct msc_outDataTask;
|
||||
struct usb_function func;
|
||||
};
|
||||
|
||||
u32 min(u32 value1,u32 value2);
|
||||
|
||||
int usbd_msc_halt_bulk_in_endpoint(struct msc_dev *mscdev);
|
||||
void usbd_msc_put_bufhd(struct msc_common *common, struct msc_bufhd* bufhd);
|
||||
struct msc_bufhd* usbd_msc_get_bufhd(struct msc_common *common);
|
||||
int usbd_msc_bulk_in_transfer(struct msc_dev *mscdev, struct usb_request *req);
|
||||
int usbd_msc_bulk_out_transfer(struct msc_dev *mscdev, struct usb_request *req);
|
||||
|
||||
/*
|
||||
* N_bh : number of buffer header
|
||||
* Size_bh: buffer size per buffer
|
||||
* type:msc physical disk type
|
||||
*/
|
||||
int usbd_msc_init(int N_bh, int Size_bh, disk_type type);
|
||||
void usbd_msc_deinit(void);
|
||||
|
||||
#endif
|
||||
|
|
@ -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
|
||||
|
|
@ -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,
|
||||
};
|
||||
|
|
@ -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
|
||||
Loading…
Add table
Add a link
Reference in a new issue