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,14 @@
#ifndef __MII_ETHERNETIF_H__
#define __MII_ETHERNETIF_H__
#include "lwip_netconf.h"
#define MII_TX_DESC_CNT 4
#define MII_RX_DESC_CNT 10
#define ETHERNET_IDX (NET_IF_NUM - 1)
#define WLAN_IDX 0
typedef void (*link_up_down_callback)(int blinkup);
#endif // __MII_ETHERNETIF_H__

View file

@ -0,0 +1,15 @@
#ifndef __STM32_FLASH_H__
#define __STM32_FLASH_H__
#include <stdint.h>
uint32_t flash_SectorAddress(uint16_t sector_nb);
#if defined STM32F2XX || STM32F4XX
int flash_EraseSector(uint16_t sector_nb);
#elif defined STM32f1xx
int flash_EraseSector(uint32_t Page_Address);
#endif
int flash_Wrtie(uint32_t address, char* buf, uint32_t len);
int flash_Read(uint32_t address, char* buf, uint32_t len);
#endif // __STM32_FLASH_H__

View file

@ -0,0 +1,62 @@
#ifndef _STM32_I2C_H_
#define _STM32_I2C_H_
#include <stdint.h>
#define I2C_MASTER
// I2C mode supported
#define I2C_OP_MODE_POLLING 0x01
#define I2C_OP_MODE_INTERRUPT 0x02
#define I2C_OP_MODE_DMA_POLLING 0x04
#define I2C_OP_MODE_DMA_INTERRUPT 0x08
// Define I2C Speed --------------------------------------------------------
#ifdef FAST_I2C_MODE
#define I2C_SPEED 340000
#define I2C_DUTYCYCLE I2C_DutyCycle_16_9
#else // STANDARD_I2C_MODE
#define I2C_SPEED 100000
#define I2C_DUTYCYCLE I2C_DutyCycle_2
#endif // FAST_I2C_MODE
// Define I2C operation mode
#ifndef I2C_OP_MODE
#define I2C_OP_MODE I2C_OP_MODE_INTERRUPT
#endif
// I2Cx Communication boards Interface
#define I2Cx_NUM I2C1
#define I2Cx_CLK RCC_APB1Periph_I2C1
#define I2Cx_EV_IRQn I2C1_EV_IRQn
#define I2Cx_ER_IRQn I2C1_ER_IRQn
#define I2Cx_EV_IRQHANDLER I2C1_EV_IRQHandler
#define I2Cx_ER_IRQHANDLER I2C1_ER_IRQHandler
#define I2Cx_SDA_GPIO_CLK RCC_AHB1Periph_GPIOB
#define I2Cx_SDA_PIN GPIO_Pin_9
#define I2Cx_SDA_GPIO_PORT GPIOB
#define I2Cx_SDA_SOURCE GPIO_PinSource9
#define I2Cx_SDA_AF GPIO_AF_I2C1
#define I2Cx_SCL_GPIO_CLK RCC_AHB1Periph_GPIOB
#define I2Cx_SCL_PIN GPIO_Pin_8
#define I2Cx_SCL_GPIO_PORT GPIOB
#define I2Cx_SCL_SOURCE GPIO_PinSource8
#define I2Cx_SCL_AF GPIO_AF_I2C1
#if (I2C_OP_MODE == I2C_OP_MODE_INTERRUPT)
#define stm32_i2c_tx stm32_i2c_tx_int
#define stm32_i2c_rx stm32_i2c_rx_int
#else
#error
#endif
void stm32_i2c_ev_isr(void);
void stm32_i2c_err_isr(void);
uint32_t stm32_i2c_tx(uint16_t device_address, uint8_t send_start, const uint8_t *tx_data, uint32_t count, uint8_t send_stop);
uint32_t stm32_i2c_rx(uint16_t device_address, uint8_t send_start, uint8_t *rx_data, uint32_t count, uint8_t send_nak, uint8_t send_stop);
int stm32_i2c_init(void);
void stm32_i2c_deinit(void);
#endif //_STM32_I2C_H_

View file

@ -0,0 +1,9 @@
#ifndef _ALC5616_H_
#define _ALC5616_H_
void alc5616_reg_dump(void);
void alc5616_index_dump(void);
void alc5616_init(void);
void alc5616_set_word_len(int len_idx);
void alc5616_init_interface1(void);
void alc5616_init_interface2(void);
#endif

View file

@ -0,0 +1,10 @@
#ifndef _ALC5640_H_
#define _ALC5640_H_
void alc5640_reg_dump(void);
void alc5640_index_dump(void);
void alc5640_init(void);
void alc5640_set_word_len(int len_idx);
void alc5640_init_interface1(void);
void alc5640_init_interface1_pcm(void);
void alc5640_init_interface2(void);
#endif

View file

@ -0,0 +1,9 @@
#ifndef _ALC5651_H_
#define _ALC5651_H_
void alc5651_reg_dump(void);
void alc5651_index_dump(void);
void alc5651_init(void);
void alc5651_set_word_len(int len_idx);
void alc5651_init_interface1(void);
void alc5651_init_interface2(void);
#endif

View file

@ -0,0 +1,9 @@
#ifndef _ALC5660_H_
#define _ALC5660_H_
void alc5660_reg_dump(void);
void alc5660_index_dump(void);
void alc5660_init(void);
void alc5660_set_word_len(int len_idx);
void alc5660_init_interface1(void);
void alc5660_init_interface2(void);
#endif

View file

@ -0,0 +1,13 @@
#ifndef _ALC5679_H_
#define _ALC5679_H_
#define RT5679_DEVICE_ID 0x6385
#define RT5679_VENDOR_ID2 0x00ff
/////////////////////////////////////////////////////
void rt5679_i2c_init(void);
int check_id();
void rt5679_linein_to_i2s(void);
void rt5679_i2s_to_hp(void);
void rt5679_mic_to_i2s(void);
#endif

View file

@ -0,0 +1,22 @@
#ifndef _ALC5680_H_
#define _ALC5680_H_
#define RT5680_DEVICE_ID 0x6385
void alc5680_status();
void alc5680_write_data_to_flash(const unsigned char *data_value,unsigned int len,unsigned int addr);
void alc5680_erase();
void alc5680_i2c_init(void);
u8 alc5680_reg_read_16(u32 reg, u16* val);
u8 alc5680_reg_read_32(u32 reg, u32* val);
u8 alc5680_reg_write_32(u32 reg, u32 val);
u8 alc5680_reg_write_16b(u32 reg, u16 val);
void alc5680_get_info(unsigned char *buffer);
void alc5680_handler_function(unsigned char *buffer,int len,unsigned int index);
void alc5680_check_sum();
int alc5680_get_version();
void set_alc5680_volume(unsigned char left,unsigned char right);
void get_alc5680_volume(unsigned short *value);//high byte is left and low byte is high
#endif

View file

@ -0,0 +1,517 @@
/* Audio Library for Teensy 3.X
* Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com
*
* Development of this audio library was funded by PJRC.COM, LLC by sales of
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
* open source software by purchasing Teensy or other PJRC products.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice, development funding notice, and this permission
* notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* 20170309 refined by RTK
*/
#ifndef _SGTL5000_H_
#define _SGTL5000_H_
#include <inttypes.h>
#define CHIP_ID 0x0000
// 15:8 PARTID 0xA0 - 8 bit identifier for SGTL5000
// 7:0 REVID 0x00 - revision number for SGTL5000.
#define CHIP_DIG_POWER 0x0002
// 6 ADC_POWERUP 1=Enable, 0=disable the ADC block, both digital & analog,
// 5 DAC_POWERUP 1=Enable, 0=disable the DAC block, both analog and digital
// 4 DAP_POWERUP 1=Enable, 0=disable the DAP block
// 1 I2S_OUT_POWERUP 1=Enable, 0=disable the I2S data output
// 0 I2S_IN_POWERUP 1=Enable, 0=disable the I2S data input
#define CHIP_CLK_CTRL 0x0004
// 5:4 RATE_MODE Sets the sample rate mode. MCLK_FREQ is still specified
// relative to the rate in SYS_FS
// 0x0 = SYS_FS specifies the rate
// 0x1 = Rate is 1/2 of the SYS_FS rate
// 0x2 = Rate is 1/4 of the SYS_FS rate
// 0x3 = Rate is 1/6 of the SYS_FS rate
// 3:2 SYS_FS Sets the internal system sample rate (default=2)
// 0x0 = 32 kHz
// 0x1 = 44.1 kHz
// 0x2 = 48 kHz
// 0x3 = 96 kHz
// 1:0 MCLK_FREQ Identifies incoming SYS_MCLK frequency and if the PLL should be used
// 0x0 = 256*Fs
// 0x1 = 384*Fs
// 0x2 = 512*Fs
// 0x3 = Use PLL
// The 0x3 (Use PLL) setting must be used if the SYS_MCLK is not
// a standard multiple of Fs (256, 384, or 512). This setting can
// also be used if SYS_MCLK is a standard multiple of Fs.
// Before this field is set to 0x3 (Use PLL), the PLL must be
// powered up by setting CHIP_ANA_POWER->PLL_POWERUP and
// CHIP_ANA_POWER->VCOAMP_POWERUP. Also, the PLL dividers must
// be calculated based on the external MCLK rate and
// CHIP_PLL_CTRL register must be set (see CHIP_PLL_CTRL register
// description details on how to calculate the divisors).
#define CHIP_I2S_CTRL 0x0006
// 8 SCLKFREQ Sets frequency of I2S_SCLK when in master mode (MS=1). When in slave
// mode (MS=0), this field must be set appropriately to match SCLK input
// rate.
// 0x0 = 64Fs
// 0x1 = 32Fs - Not supported for RJ mode (I2S_MODE = 1)
// 7 MS Configures master or slave of I2S_LRCLK and I2S_SCLK.
// 0x0 = Slave: I2S_LRCLK an I2S_SCLK are inputs
// 0x1 = Master: I2S_LRCLK and I2S_SCLK are outputs
// NOTE: If the PLL is used (CHIP_CLK_CTRL->MCLK_FREQ==0x3),
// the SGTL5000 must be a master of the I2S port (MS==1)
// 6 SCLK_INV Sets the edge that data (input and output) is clocked in on for I2S_SCLK
// 0x0 = data is valid on rising edge of I2S_SCLK
// 0x1 = data is valid on falling edge of I2S_SCLK
// 5:4 DLEN I2S data length (default=1)
// 0x0 = 32 bits (only valid when SCLKFREQ=0),
// not valid for Right Justified Mode
// 0x1 = 24 bits (only valid when SCLKFREQ=0)
// 0x2 = 20 bits
// 0x3 = 16 bits
// 3:2 I2S_MODE Sets the mode for the I2S port
// 0x0 = I2S mode or Left Justified (Use LRALIGN to select)
// 0x1 = Right Justified Mode
// 0x2 = PCM Format A/B
// 0x3 = RESERVED
// 1 LRALIGN I2S_LRCLK Alignment to data word. Not used for Right Justified mode
// 0x0 = Data word starts 1 I2S_SCLK delay after I2S_LRCLK
// transition (I2S format, PCM format A)
// 0x1 = Data word starts after I2S_LRCLK transition (left
// justified format, PCM format B)
// 0 LRPOL I2S_LRCLK Polarity when data is presented.
// 0x0 = I2S_LRCLK = 0 - Left, 1 - Right
// 1x0 = I2S_LRCLK = 0 - Right, 1 - Left
// The left subframe should be presented first regardless of
// the setting of LRPOL.
#define CHIP_SSS_CTRL 0x000A
// 14 DAP_MIX_LRSWAP DAP Mixer Input Swap
// 0x0 = Normal Operation
// 0x1 = Left and Right channels for the DAP MIXER Input are swapped.
// 13 DAP_LRSWAP DAP Mixer Input Swap
// 0x0 = Normal Operation
// 0x1 = Left and Right channels for the DAP Input are swapped
// 12 DAC_LRSWAP DAC Input Swap
// 0x0 = Normal Operation
// 0x1 = Left and Right channels for the DAC are swapped
// 10 I2S_LRSWAP I2S_DOUT Swap
// 0x0 = Normal Operation
// 0x1 = Left and Right channels for the I2S_DOUT are swapped
// 9:8 DAP_MIX_SELECT Select data source for DAP mixer
// 0x0 = ADC
// 0x1 = I2S_IN
// 0x2 = Reserved
// 0x3 = Reserved
// 7:6 DAP_SELECT Select data source for DAP
// 0x0 = ADC
// 0x1 = I2S_IN
// 0x2 = Reserved
// 0x3 = Reserved
// 5:4 DAC_SELECT Select data source for DAC (default=1)
// 0x0 = ADC
// 0x1 = I2S_IN
// 0x2 = Reserved
// 0x3 = DAP
// 1:0 I2S_SELECT Select data source for I2S_DOUT
// 0x0 = ADC
// 0x1 = I2S_IN
// 0x2 = Reserved
// 0x3 = DAP
#define CHIP_ADCDAC_CTRL 0x000E
// 13 VOL_BUSY_DAC_RIGHT Volume Busy DAC Right
// 0x0 = Ready
// 0x1 = Busy - This indicates the channel has not reached its
// programmed volume/mute level
// 12 VOL_BUSY_DAC_LEFT Volume Busy DAC Left
// 0x0 = Ready
// 0x1 = Busy - This indicates the channel has not reached its
// programmed volume/mute level
// 9 VOL_RAMP_EN Volume Ramp Enable (default=1)
// 0x0 = Disables volume ramp. New volume settings take immediate
// effect without a ramp
// 0x1 = Enables volume ramp
// This field affects DAC_VOL. The volume ramp effects both
// volume settings and mute When set to 1 a soft mute is enabled.
// 8 VOL_EXPO_RAMP Exponential Volume Ramp Enable
// 0x0 = Linear ramp over top 4 volume octaves
// 0x1 = Exponential ramp over full volume range
// This bit only takes effect if VOL_RAMP_EN is 1.
// 3 DAC_MUTE_RIGHT DAC Right Mute (default=1)
// 0x0 = Unmute
// 0x1 = Muted
// If VOL_RAMP_EN = 1, this is a soft mute.
// 2 DAC_MUTE_LEFT DAC Left Mute (default=1)
// 0x0 = Unmute
// 0x1 = Muted
// If VOL_RAMP_EN = 1, this is a soft mute.
// 1 ADC_HPF_FREEZE ADC High Pass Filter Freeze
// 0x0 = Normal operation
// 0x1 = Freeze the ADC high-pass filter offset register. The
// offset continues to be subtracted from the ADC data stream.
// 0 ADC_HPF_BYPASS ADC High Pass Filter Bypass
// 0x0 = Normal operation
// 0x1 = Bypassed and offset not updated
#define CHIP_DAC_VOL 0x0010
// 15:8 DAC_VOL_RIGHT DAC Right Channel Volume. Set the Right channel DAC volume
// with 0.5017 dB steps from 0 to -90 dB
// 0x3B and less = Reserved
// 0x3C = 0 dB
// 0x3D = -0.5 dB
// 0xF0 = -90 dB
// 0xFC and greater = Muted
// If VOL_RAMP_EN = 1, there is an automatic ramp to the
// new volume setting.
// 7:0 DAC_VOL_LEFT DAC Left Channel Volume. Set the Left channel DAC volume
// with 0.5017 dB steps from 0 to -90 dB
// 0x3B and less = Reserved
// 0x3C = 0 dB
// 0x3D = -0.5 dB
// 0xF0 = -90 dB
// 0xFC and greater = Muted
// If VOL_RAMP_EN = 1, there is an automatic ramp to the
// new volume setting.
#define CHIP_PAD_STRENGTH 0x0014
// 9:8 I2S_LRCLK I2S LRCLK Pad Drive Strength (default=1)
// Sets drive strength for output pads per the table below.
// VDDIO 1.8 V 2.5 V 3.3 V
// 0x0 = Disable
// 0x1 = 1.66 mA 2.87 mA 4.02 mA
// 0x2 = 3.33 mA 5.74 mA 8.03 mA
// 0x3 = 4.99 mA 8.61 mA 12.05 mA
// 7:6 I2S_SCLK I2S SCLK Pad Drive Strength (default=1)
// 5:4 I2S_DOUT I2S DOUT Pad Drive Strength (default=1)
// 3:2 CTRL_DATA I2C DATA Pad Drive Strength (default=3)
// 1:0 CTRL_CLK I2C CLK Pad Drive Strength (default=3)
// (all use same table as I2S_LRCLK)
#define CHIP_ANA_ADC_CTRL 0x0020
// 8 ADC_VOL_M6DB ADC Volume Range Reduction
// This bit shifts both right and left analog ADC volume
// range down by 6.0 dB.
// 0x0 = No change in ADC range
// 0x1 = ADC range reduced by 6.0 dB
// 7:4 ADC_VOL_RIGHT ADC Right Channel Volume
// Right channel analog ADC volume control in 1.5 dB steps.
// 0x0 = 0 dB
// 0x1 = +1.5 dB
// ...
// 0xF = +22.5 dB
// This range is -6.0 dB to +16.5 dB if ADC_VOL_M6DB is set to 1.
// 3:0 ADC_VOL_LEFT ADC Left Channel Volume
// (same scale as ADC_VOL_RIGHT)
#define CHIP_ANA_HP_CTRL 0x0022
// 14:8 HP_VOL_RIGHT Headphone Right Channel Volume (default 0x18)
// Right channel headphone volume control with 0.5 dB steps.
// 0x00 = +12 dB
// 0x01 = +11.5 dB
// 0x18 = 0 dB
// ...
// 0x7F = -51.5 dB
// 6:0 HP_VOL_LEFT Headphone Left Channel Volume (default 0x18)
// (same scale as HP_VOL_RIGHT)
#define CHIP_ANA_CTRL 0x0024
// 8 MUTE_LO LINEOUT Mute, 0 = Unmute, 1 = Mute (default 1)
// 6 SELECT_HP Select the headphone input, 0 = DAC, 1 = LINEIN
// 5 EN_ZCD_HP Enable the headphone zero cross detector (ZCD)
// 0x0 = HP ZCD disabled
// 0x1 = HP ZCD enabled
// 4 MUTE_HP Mute the headphone outputs, 0 = Unmute, 1 = Mute (default)
// 2 SELECT_ADC Select the ADC input, 0 = Microphone, 1 = LINEIN
// 1 EN_ZCD_ADC Enable the ADC analog zero cross detector (ZCD)
// 0x0 = ADC ZCD disabled
// 0x1 = ADC ZCD enabled
// 0 MUTE_ADC Mute the ADC analog volume, 0 = Unmute, 1 = Mute (default)
#define CHIP_LINREG_CTRL 0x0026
// 6 VDDC_MAN_ASSN Determines chargepump source when VDDC_ASSN_OVRD is set.
// 0x0 = VDDA
// 0x1 = VDDIO
// 5 VDDC_ASSN_OVRD Charge pump Source Assignment Override
// 0x0 = Charge pump source is automatically assigned based
// on higher of VDDA and VDDIO
// 0x1 = the source of charge pump is manually assigned by
// VDDC_MAN_ASSN If VDDIO and VDDA are both the same
// and greater than 3.1 V, VDDC_ASSN_OVRD and
// VDDC_MAN_ASSN should be used to manually assign
// VDDIO as the source for charge pump.
// 3:0 D_PROGRAMMING Sets the VDDD linear regulator output voltage in 50 mV steps.
// Must clear the LINREG_SIMPLE_POWERUP and STARTUP_POWERUP bits
// in the 0x0030 (CHIP_ANA_POWER) register after power-up, for
// this setting to produce the proper VDDD voltage.
// 0x0 = 1.60
// 0xF = 0.85
#define CHIP_REF_CTRL 0x0028 // bandgap reference bias voltage and currents
// 8:4 VAG_VAL Analog Ground Voltage Control
// These bits control the analog ground voltage in 25 mV steps.
// This should usually be set to VDDA/2 or lower for best
// performance (maximum output swing at minimum THD). This VAG
// reference is also used for the DAC and ADC voltage reference.
// So changing this voltage scales the output swing of the DAC
// and the output signal of the ADC.
// 0x00 = 0.800 V
// 0x1F = 1.575 V
// 3:1 BIAS_CTRL Bias control
// These bits adjust the bias currents for all of the analog
// blocks. By lowering the bias current a lower quiescent power
// is achieved. It should be noted that this mode can affect
// performance by 3-4 dB.
// 0x0 = Nominal
// 0x1-0x3=+12.5%
// 0x4=-12.5%
// 0x5=-25%
// 0x6=-37.5%
// 0x7=-50%
// 0 SMALL_POP VAG Ramp Control
// Setting this bit slows down the VAG ramp from ~200 to ~400 ms
// to reduce the startup pop, but increases the turn on/off time.
// 0x0 = Normal VAG ramp
// 0x1 = Slow down VAG ramp
#define CHIP_MIC_CTRL 0x002A // microphone gain & internal microphone bias
// 9:8 BIAS_RESISTOR MIC Bias Output Impedance Adjustment
// Controls an adjustable output impedance for the microphone bias.
// If this is set to zero the micbias block is powered off and
// the output is highZ.
// 0x0 = Powered off
// 0x1 = 2.0 kohm
// 0x2 = 4.0 kohm
// 0x3 = 8.0 kohm
// 6:4 BIAS_VOLT MIC Bias Voltage Adjustment
// Controls an adjustable bias voltage for the microphone bias
// amp in 250 mV steps. This bias voltage setting should be no
// more than VDDA-200 mV for adequate power supply rejection.
// 0x0 = 1.25 V
// ...
// 0x7 = 3.00 V
// 1:0 GAIN MIC Amplifier Gain
// Sets the microphone amplifier gain. At 0 dB setting the THD
// can be slightly higher than other paths- typically around
// ~65 dB. At other gain settings the THD are better.
// 0x0 = 0 dB
// 0x1 = +20 dB
// 0x2 = +30 dB
// 0x3 = +40 dB
#define CHIP_LINE_OUT_CTRL 0x002C
// 11:8 OUT_CURRENT Controls the output bias current for the LINEOUT amplifiers. The
// nominal recommended setting for a 10 kohm load with 1.0 nF load cap
// is 0x3. There are only 5 valid settings.
// 0x0=0.18 mA
// 0x1=0.27 mA
// 0x3=0.36 mA
// 0x7=0.45 mA
// 0xF=0.54 mA
// 5:0 LO_VAGCNTRL LINEOUT Amplifier Analog Ground Voltage
// Controls the analog ground voltage for the LINEOUT amplifiers
// in 25 mV steps. This should usually be set to VDDIO/2.
// 0x00 = 0.800 V
// ...
// 0x1F = 1.575 V
// ...
// 0x23 = 1.675 V
// 0x24-0x3F are invalid
#define CHIP_LINE_OUT_VOL 0x002E
// 12:8 LO_VOL_RIGHT LINEOUT Right Channel Volume (default=4)
// Controls the right channel LINEOUT volume in 0.5 dB steps.
// Higher codes have more attenuation.
// 4:0 LO_VOL_LEFT LINEOUT Left Channel Output Level (default=4)
// Used to normalize the output level of the left line output
// to full scale based on the values used to set
// LINE_OUT_CTRL->LO_VAGCNTRL and CHIP_REF_CTRL->VAG_VAL.
// In general this field should be set to:
// 40*log((VAG_VAL)/(LO_VAGCNTRL)) + 15
// Suggested values based on typical VDDIO and VDDA voltages.
// VDDA VAG_VAL VDDIO LO_VAGCNTRL LO_VOL_*
// 1.8 V 0.9 3.3 V 1.55 0x06
// 1.8 V 0.9 1.8 V 0.9 0x0F
// 3.3 V 1.55 1.8 V 0.9 0x19
// 3.3 V 1.55 3.3 V 1.55 0x0F
// After setting to the nominal voltage, this field can be used
// to adjust the output level in +/-0.5 dB increments by using
// values higher or lower than the nominal setting.
#define CHIP_ANA_POWER 0x0030 // power down controls for the analog blocks.
// The only other power-down controls are BIAS_RESISTOR in the MIC_CTRL register
// and the EN_ZCD control bits in ANA_CTRL.
// 14 DAC_MONO While DAC_POWERUP is set, this allows the DAC to be put into left only
// mono operation for power savings. 0=mono, 1=stereo (default)
// 13 LINREG_SIMPLE_POWERUP Power up the simple (low power) digital supply regulator.
// After reset, this bit can be cleared IF VDDD is driven
// externally OR the primary digital linreg is enabled with
// LINREG_D_POWERUP
// 12 STARTUP_POWERUP Power up the circuitry needed during the power up ramp and reset.
// After reset this bit can be cleared if VDDD is coming from
// an external source.
// 11 VDDC_CHRGPMP_POWERUP Power up the VDDC charge pump block. If neither VDDA or VDDIO
// is 3.0 V or larger this bit should be cleared before analog
// blocks are powered up.
// 10 PLL_POWERUP PLL Power Up, 0 = Power down, 1 = Power up
// When cleared, the PLL is turned off. This must be set before
// CHIP_CLK_CTRL->MCLK_FREQ is programmed to 0x3. The
// CHIP_PLL_CTRL register must be configured correctly before
// setting this bit.
// 9 LINREG_D_POWERUP Power up the primary VDDD linear regulator, 0 = Power down, 1 = Power up
// 8 VCOAMP_POWERUP Power up the PLL VCO amplifier, 0 = Power down, 1 = Power up
// 7 VAG_POWERUP Power up the VAG reference buffer.
// Setting this bit starts the power up ramp for the headphone
// and LINEOUT. The headphone (and/or LINEOUT) powerup should
// be set BEFORE clearing this bit. When this bit is cleared
// the power-down ramp is started. The headphone (and/or LINEOUT)
// powerup should stay set until the VAG is fully ramped down
// (200 to 400 ms after clearing this bit).
// 0x0 = Power down, 0x1 = Power up
// 6 ADC_MONO While ADC_POWERUP is set, this allows the ADC to be put into left only
// mono operation for power savings. This mode is useful when
// only using the microphone input.
// 0x0 = Mono (left only), 0x1 = Stereo
// 5 REFTOP_POWERUP Power up the reference bias currents
// 0x0 = Power down, 0x1 = Power up
// This bit can be cleared when the part is a sleep state
// to minimize analog power.
// 4 HEADPHONE_POWERUP Power up the headphone amplifiers
// 0x0 = Power down, 0x1 = Power up
// 3 DAC_POWERUP Power up the DACs
// 0x0 = Power down, 0x1 = Power up
// 2 CAPLESS_HEADPHONE_POWERUP Power up the capless headphone mode
// 0x0 = Power down, 0x1 = Power up
// 1 ADC_POWERUP Power up the ADCs
// 0x0 = Power down, 0x1 = Power up
// 0 LINEOUT_POWERUP Power up the LINEOUT amplifiers
// 0x0 = Power down, 0x1 = Power up
#define CHIP_PLL_CTRL 0x0032
// 15:11 INT_DIVISOR
// 10:0 FRAC_DIVISOR
#define CHIP_CLK_TOP_CTRL 0x0034
// 11 ENABLE_INT_OSC Setting this bit enables an internal oscillator to be used for the
// zero cross detectors, the short detect recovery, and the
// charge pump. This allows the I2S clock to be shut off while
// still operating an analog signal path. This bit can be kept
// on when the I2S clock is enabled, but the I2S clock is more
// accurate so it is preferred to clear this bit when I2S is present.
// 3 INPUT_FREQ_DIV2 SYS_MCLK divider before PLL input
// 0x0 = pass through
// 0x1 = SYS_MCLK is divided by 2 before entering PLL
// This must be set when the input clock is above 17 Mhz. This
// has no effect when the PLL is powered down.
#define CHIP_ANA_STATUS 0x0036
// 9 LRSHORT_STS This bit is high whenever a short is detected on the left or right
// channel headphone drivers.
// 8 CSHORT_STS This bit is high whenever a short is detected on the capless headphone
// common/center channel driver.
// 4 PLL_IS_LOCKED This bit goes high after the PLL is locked.
#define CHIP_ANA_TEST1 0x0038 // intended only for debug.
#define CHIP_ANA_TEST2 0x003A // intended only for debug.
#define CHIP_SHORT_CTRL 0x003C
// 14:12 LVLADJR Right channel headphone short detector in 25 mA steps.
// 0x3=25 mA
// 0x2=50 mA
// 0x1=75 mA
// 0x0=100 mA
// 0x4=125 mA
// 0x5=150 mA
// 0x6=175 mA
// 0x7=200 mA
// This trip point can vary by ~30% over process so leave plenty
// of guard band to avoid false trips. This short detect trip
// point is also effected by the bias current adjustments made
// by CHIP_REF_CTRL->BIAS_CTRL and by CHIP_ANA_TEST1->HP_IALL_ADJ.
// 10:8 LVLADJL Left channel headphone short detector in 25 mA steps.
// (same scale as LVLADJR)
// 6:4 LVLADJC Capless headphone center channel short detector in 50 mA steps.
// 0x3=50 mA
// 0x2=100 mA
// 0x1=150 mA
// 0x0=200 mA
// 0x4=250 mA
// 0x5=300 mA
// 0x6=350 mA
// 0x7=400 mA
// 3:2 MODE_LR Behavior of left/right short detection
// 0x0 = Disable short detector, reset short detect latch,
// software view non-latched short signal
// 0x1 = Enable short detector and reset the latch at timeout
// (every ~50 ms)
// 0x2 = This mode is not used/invalid
// 0x3 = Enable short detector with only manual reset (have
// to return to 0x0 to reset the latch)
// 1:0 MODE_CM Behavior of capless headphone central short detection
// (same settings as MODE_LR)
#define DAP_CONTROL 0x0100
#define DAP_PEQ 0x0102
#define DAP_BASS_ENHANCE 0x0104
#define DAP_BASS_ENHANCE_CTRL 0x0106
#define DAP_AUDIO_EQ 0x0108
#define DAP_SGTL_SURROUND 0x010A
#define DAP_FILTER_COEF_ACCESS 0x010C
#define DAP_COEF_WR_B0_MSB 0x010E
#define DAP_COEF_WR_B0_LSB 0x0110
#define DAP_AUDIO_EQ_BASS_BAND0 0x0116 // 115 Hz
#define DAP_AUDIO_EQ_BAND1 0x0118 // 330 Hz
#define DAP_AUDIO_EQ_BAND2 0x011A // 990 Hz
#define DAP_AUDIO_EQ_BAND3 0x011C // 3000 Hz
#define DAP_AUDIO_EQ_TREBLE_BAND4 0x011E // 9900 Hz
#define DAP_MAIN_CHAN 0x0120
#define DAP_MIX_CHAN 0x0122
#define DAP_AVC_CTRL 0x0124
#define DAP_AVC_THRESHOLD 0x0126
#define DAP_AVC_ATTACK 0x0128
#define DAP_AVC_DECAY 0x012A
#define DAP_COEF_WR_B1_MSB 0x012C
#define DAP_COEF_WR_B1_LSB 0x012E
#define DAP_COEF_WR_B2_MSB 0x0130
#define DAP_COEF_WR_B2_LSB 0x0132
#define DAP_COEF_WR_A1_MSB 0x0134
#define DAP_COEF_WR_A1_LSB 0x0136
#define DAP_COEF_WR_A2_MSB 0x0138
#define DAP_COEF_WR_A2_LSB 0x013A
#define SGTL5000_I2C_ADDR_CS_LOW 0x0A // CTRL_ADR0_CS pin low (normal configuration)
#define SGTL5000_I2C_ADDR_CS_HIGH 0x2A // CTRL_ADR0_CS pin high
#define SGTL5000_AUDIO_INPUT_LINEIN 0
#define SGTL5000_AUDIO_INPUT_MIC 1
uint8_t sgtl5000_enable(void);
uint8_t sgtl5000_muteHeadphone(void);
uint8_t sgtl5000_unmuteHeadphone(void);
uint8_t sgtl5000_muteLineout(void);
uint8_t sgtl5000_unmuteLineout(void);
uint8_t sgtl5000_inputSelect(uint8_t n);
uint8_t sgtl5000_setVolume(float val);
uint8_t sgtl5000_micGain(uint16_t dB);
#endif

View file

@ -0,0 +1,67 @@
#ifndef __INIC_ETHERNETIF_H__
#define __INIC_ETHERNETIF_H__
#define INIC_BIT(n) (1<<n)
#define INIC_FLAG INIC_BIT(0)
#define INIC_FLAG_SDIO INIC_BIT(1)
#define INIC_FLAG_USB INIC_BIT(2)
#define INIC_FLAG_SPI INIC_BIT(3)
enum{
INIC_DBG_OFF = 0,
INIC_DBG_ALWAYS,
INIC_DBG_ERROR,
INIC_DBG_WARNING,
INIC_DBG_INFO
};
#define INIC_DBG
#ifdef INIC_DBG
static unsigned char gINICDbgLevel = INIC_DBG_ERROR;
static unsigned int gINICDbgFlag = 0xFFFFFFFF;
#define INIC_PRINTK(fmt, args...) printf(fmt"\r\n",## args)
#define _INIC_PRINTK(fmt, args...) printf(fmt,## args)
#define INIC_DBG_MSG(flag, level, fmt, args...) \
do{ \
if(((flag) & gINICDbgFlag) && (level <= gINICDbgLevel)){ \
INIC_PRINTK(fmt,## args); \
} \
}while(0)
extern _LONG_CALL_ void __rtl_memDump_v1_00(const u8 *start, u32 size, char * strHeader);
#define INIC_DUMP(pData, Len) __rtl_memDump_v1_00(pData, Len, NULL)
#else
#define INIC_PRINTK(fmt, args...)
#define INIC_DBG_MSG(flag, level, fmt, args...)
#define INIC_DUMP(pData, Len)
#endif
#ifndef inic_memcpy
#define inic_memcpy(d, s, n) rtw_memcpy((void*)(d), ((void*)(s)), (n))
#endif
#ifndef inic_malloc
#define inic_malloc(sz) rtw_malloc(sz)
#endif
#ifndef inic_zmalloc
#define inic_zmalloc(sz) rtw_zmalloc(sz)
#endif
#ifndef inic_memset
#define inic_memset(pbuf, c, sz) rtw_memset(pbuf, c, sz)
#endif
#ifndef inic_mfree
#define inic_mfree(p, sz) rtw_mfree(((u8*)(p)), (sz))
#endif
#ifndef inic_memcmp
#define inic_memcmp(s1, s2, n) rtw_memcmp(((void*)(s1)), ((void*)(s2)), (n))
#endif
#ifndef inic_mdelay_os
#define inic_mdelay_os(ms) rtw_mdelay_os(ms)
#endif
#endif//__INIC_ETHERNETIF_H__

View file

@ -0,0 +1,37 @@
#ifndef __INIC_ETHERNETIF_H__
#define __INIC_ETHERNETIF_H__
#define INIC_BIT(n) (1<<n)
#define INIC_FLAG INIC_BIT(0)
#define INIC_FLAG_SDIO INIC_BIT(1)
#define INIC_FLAG_USB INIC_BIT(2)
#define INIC_FLAG_SPI INIC_BIT(3)
enum{
INIC_DBG_OFF = 0,
INIC_DBG_ALWAYS,
INIC_DBG_ERROR,
INIC_DBG_WARNING,
INIC_DBG_INFO
};
#define INIC_DBG
#ifdef INIC_DBG
static unsigned char gDbgLevel = INIC_DBG_ERROR;
static unsigned int gDbgFlag = 0xFFFFFFFF;
#define INIC_PRINTK(fmt, args...) printf(fmt"\r\n",## args)
#define _INIC_PRINTK(fmt, args...) printf(fmt,## args)
#define INIC_DBG_MSG(flag, level, fmt, args...) \
do{ \
if(((flag) & gDbgFlag) && (level <= gDbgLevel)){ \
INIC_PRINTK(fmt,## args); \
} \
}while(0)
#else
#define INIC_PRINTK(fmt, args...)
#define INIC_DBG_MSG(flag, level, fmt, args...)
#endif
#endif//__INIC_ETHERNETIF_H__

View file

@ -0,0 +1,185 @@
/*
* Routines to access hardware
*
* Copyright (c) 2013 Realtek Semiconductor Corp.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*/
#ifndef _INIC_SDIO_H_
#define _INIC_SDIO_H_
#include "rtl8710b_sdio.h"
#include "osdep_service.h"
#include "rtl8710b_inic.h"
#include <FreeRTOS.h>
#include "timers.h"
#include "semphr.h"
#if defined(__IAR_SYSTEMS_ICC__) //for IAR SDK
#include "platform_opts.h"
#endif
#define PURE_SDIO_INIC 0 // is a pure SDIO iNIC device or a SDIO iNIC + peripheral device
#ifndef PRIORITIE_OFFSET //PRIORITIE_OFFSET in FreeRTOSConfig.h
#define PRIORITIE_OFFSET 0
#endif
#define SDIO_RX_PKT_SIZE_OVER_16K 0 /* is support SDIO RX packet size > 16K. if true,
a big packet will be transmited via multiple RX_BD */
#define SDIO_MAILBOX_SIZE 10 // the maximum number of message block can be stored in this mailbox
#define SDIO_PERIODICAL_TIMER_INTERVAL 2000 // in ms, the interval of SDIO periodical timer
#define SDIO_AVG_TP_WIN_SIZE 20 // the number of entry to log the byte count for every periodical timer statistic, to calculate throughput
//TX BD setting
#define SDIO_TX_BD_BUF_SIZE 1540 //1514+24 //(2048+32) // the size of a TX BD pointed buffer, WLan header = 26 bytes
#define SDIO_TX_BD_NUM 20 // Number of TX BD
//RX BD setting
#define SDIO_RX_BD_BUF_SIZE 1540 //1514+24 //2048
#define SDIO_RX_BD_NUM 32 // Number of RX BD, to make 32K of bus aggregation, it needs 22 RX_BD at least
#define RX_BD_FREE_TH 5 // trigger the interrupt when free RX BD over this threshold
#define MAX_RX_BD_BUF_SIZE 16380 // the Maximum size for a RX_BD point to, make it 4-bytes aligned
#define SDIO_RX_PKT_NUM 128 // Number of RX packet handler
#define MIN_RX_BD_SEND_PKT 2 /* the minum needed RX_BD to send a Packet to Host, we need 2: one for RX_Desc, the other for payload */
#define SDIO_IRQ_PRIORITY 10
#define SDIO_TASK_PRIORITY 1 // it can be 0(lowest) ~ configMAX_PRIORITIES-1(highest)
#define SDIO_MP_TASK_PRIORITY 2 // it can be 0(lowest) ~ configMAX_PRIORITIES-1(highest)
//#if SDIO_TASK_PRIORITY > (configMAX_PRIORITIES - 1)
#if SDIO_TASK_PRIORITY > (4 - 1)
#error "SDIO Task Priority Should be 0~(configMAX_PRIORITIES-1)"
#endif
typedef struct {
u32 Address; /* The TX buffer physical address, it must be 4-bytes aligned */
}SDIO_TX_BD;
#define TX_BD_STRUCTURE_SIZE (sizeof(SDIO_TX_BD))
/* The RX Buffer Descriptor format */
typedef struct {
u32 BuffSize:14; /* bit[13:0], RX Buffer Size, Maximum 16384-1 */
u32 LS:1; /* bit[14], is the Last Segment ? */
u32 FS:1; /* bit[15], is the First Segment ? */
u32 Seq:16; /* bit[31:16], The sequence number, it's no use for now */
u32 PhyAddr; /* The RX buffer physical address, it must be 4-bytes aligned */
} SDIO_RX_BD;
#define RX_BD_STRUCTURE_SIZE (sizeof(SDIO_RX_BD))
// define the TX BD buffer size with unite of 64 byets
// Be carefull!! the setting of hardware's TX BD buffer size may exceed the real size of
// the TX BD buffer size, and then it may cause the hardware DMA write the buffer overflow
#define SDIO_TX_BUF_SZ_UNIT 64
#define SDIO_TX_BD_BUF_USIZE ((((SDIO_TX_BD_BUF_SIZE+sizeof(INIC_TX_DESC)-1)/SDIO_TX_BUF_SZ_UNIT)+1)&0xff)
typedef struct {
INIC_TX_DESC TX_Desc;
u8 TX_Buffer[SDIO_TX_BD_BUF_SIZE];
}SDIO_TX_BD_BUFFER;
typedef struct {
INIC_RX_DESC RxDesc; // The RX Descriptor for this packet, to be send to Host ahead this packet
#if CONFIG_INIC_EN
struct sk_buff *skb; //sdk->data will set to pData
#endif
u8 *pData; // point to the head of payload of this packet
u16 Offset; // the offset from the pData to the payload buffer
_list list; // the link list to chain packets
u8 isDyna; // is Dynamic allocated
} SDIO_RX_PACKET;
/* the data structer to bind a TX_BD with a TX Packet */
typedef struct {
#if CONFIG_INIC_EN
struct sk_buff *skb;
#endif
u8 isFree; // is this TX BD free
} SDIO_TX_BD_HANDLE;
/* the data structer to bind a RX_BD with a RX Packet */
typedef struct {
SDIO_RX_BD *pRXBD; // Point to the RX_BD buffer
SDIO_RX_PACKET *pPkt; // point to the Rx Packet
u8 isPktEnd; // For a packet over 1 BD , this flag to indicate is this BD contains a packet end
u8 isFree; // is this RX BD free (DMA done and its RX packet has been freed)
} SDIO_RX_BD_HANDLE;
typedef struct _HAL_SDIO_ADAPTER_ {
SDIO_TX_BD_HANDLE* pTXBDHdl; /* point to the allocated memory for TX_BD Handle array */
u16 TXBDWPtr; /* The SDIO TX(Host->Device) BD local write index, different with HW maintained write Index. */
u16 TXBDRPtr; /* The SDIO TX(Host->Device) BD read index */
u16 TXBDRPtrReg; /* The SDIO TX(Host->Device) BD read index has been write to HW register */
u8 TxOverFlow;
SDIO_RX_BD_HANDLE* pRXBDHdl; /* point to the allocated memory for RX_BD Handle array */
u16 RXBDWPtr; /* The SDIO RX(Device->Host) BD write index */
u16 RXBDRPtr; /* The SDIO RX(Device->Host) BD local read index, different with HW maintained Read Index. */
u32 Events; /* The Event to the SDIO Task */
u8 CCPWM; /* the value write to register CCPWM, which will sync to Host HCPWM */
u8 reserve1;
u16 CCPWM2; /* the value write to register CCPWM2, which will sync to Host HCPWM2 */
u8 CRPWM; /* sync from Host HRPWM */
u8 reserve2;
u16 CRPWM2; /* sync from Host HRPWM2 */
_sema TxSema; /* Semaphore for SDIO TX, use to wakeup the SDIO TX task */
_sema RxSema; /* Semaphore for SDIO RX, use to wakeup the SDIO RX task */
_sema IrqSema; /* Semaphore for SDIO RX, use to wakeup the SDIO RX task */
xTaskHandle xSDIOTxTaskHandle; /* The handle of the SDIO Task for TX, can be used to delte the task */
xTaskHandle xSDIORxTaskHandle; /* The handle of the SDIO Task speical for RX, can be used to delte the task */
xTaskHandle xSDIOIrqTaskHandle; /* The handle of the SDIO Task speical for RX, can be used to delte the task */
s8 (*Tx_Callback)(VOID *pAdapter, u8 *pPkt, u16 Offset, u16 PktSize, u8 type); /* to hook the WLan driver TX callback function to handle a Packet TX */
VOID *pTxCb_Adapter; /* a pointer will be used to call the TX Callback function,
which is from the TX CallBack function register */
s8 (*pTxCallback_Backup)(VOID *pAdapter, u8 *pPkt, u16 Offset, u16 PktSize, u8 type); // Use to back up the registered TX Callback function, for MP/Normal mode switch
VOID *pTxCb_Adapter_Backup; // Backup the pTxCb_Adapter, for MP/Normal mode switch
_list RxPktList; /* The list to queue RX packets */
_list FreeRxPktList; /* The list to queue free Rx packets handler */
_mutex RxMutex; /* The Mutex to protect RxPktList */
u32 RxInQCnt; /* The packet count for Rx In Queue */
} HAL_SDIO_ADAPTER, *PHAL_SDIO_ADAPTER;
// function not extern
VOID SDIO_TxTask(IN VOID *pData);
VOID SDIO_RxTask(IN VOID *pData);
VOID SDIO_IRQ_Handler_BH(VOID *pData);
u8 SDIO_Process_RPWM( IN PHAL_SDIO_ADAPTER pSDIODev);
u8 SDIO_Process_RPWM2(IN PHAL_SDIO_ADAPTER pSDIODev);
VOID SDIO_Reset_Cmd(IN PHAL_SDIO_ADAPTER pSDIODev);
VOID SDIO_Return_Rx_Data(IN PHAL_SDIO_ADAPTER pSDIODev);
VOID SDIO_Process_H2C_IOMsg(IN PHAL_SDIO_ADAPTER pSDIODev);
VOID SDIO_TX_FIFO_DataReady(IN PHAL_SDIO_ADAPTER pSDIODev);
VOID SDIO_Recycle_Rx_BD (IN PHAL_SDIO_ADAPTER pSDIODev);
VOID SDIO_IRQ_Handler(VOID *pData);
//function extern
extern BOOL SDIO_Device_Init(VOID);
extern VOID SDIO_Device_DeInit(VOID);
extern VOID SDIO_Send_C2H_IOMsg(IN PHAL_SDIO_ADAPTER pSDIODev, IN u32 *C2HMsg);
extern u8 SDIO_Send_C2H_PktMsg(IN PHAL_SDIO_ADAPTER pSDIODev, IN u8 *C2HMsg, IN u16 MsgLen);
extern VOID SDIO_Register_Tx_Callback(
IN PHAL_SDIO_ADAPTER pSDIODev,
IN s8 (*Tx_Callback)(VOID *pAdapter, u8 *pPkt, u16 Offset, u16 PktSize, u8 Type),
IN VOID *pAdapter
);
extern s8 SDIO_Rx_Callback(
IN PHAL_SDIO_ADAPTER pSDIODev,
IN VOID *pData,
IN u16 Offset,
IN u16 Length,
IN u8 CmdType
);
extern void SDIO_INTClear(void);
extern PHAL_SDIO_ADAPTER pgSDIODev;
#define HalSdioInit SDIO_Device_Init
#define HalSdioDeInit SDIO_Device_DeInit
#endif // #ifndef _INIC_SDIO_H_

View file

@ -0,0 +1,37 @@
#ifndef __INIC_ETHERNETIF_H__
#define __INIC_ETHERNETIF_H__
#define INIC_BIT(n) (1<<n)
#define INIC_FLAG INIC_BIT(0)
#define INIC_FLAG_SDIO INIC_BIT(1)
#define INIC_FLAG_USB INIC_BIT(2)
#define INIC_FLAG_SPI INIC_BIT(3)
enum{
INIC_DBG_OFF = 0,
INIC_DBG_ALWAYS,
INIC_DBG_ERROR,
INIC_DBG_WARNING,
INIC_DBG_INFO
};
#define INIC_DBG
#ifdef INIC_DBG
static unsigned char gDbgLevel = INIC_DBG_ERROR;
static unsigned int gDbgFlag = 0xFFFFFFFF;
#define INIC_PRINTK(fmt, args...) printf(fmt"\r\n",## args)
#define _INIC_PRINTK(fmt, args...) printf(fmt,## args)
#define INIC_DBG_MSG(flag, level, fmt, args...) \
do{ \
if(((flag) & gDbgFlag) && (level <= gDbgLevel)){ \
INIC_PRINTK(fmt,## args); \
} \
}while(0)
#else
#define INIC_PRINTK(fmt, args...)
#define INIC_DBG_MSG(flag, level, fmt, args...)
#endif
#endif//__INIC_ETHERNETIF_H__

View file

@ -0,0 +1,185 @@
/*
* Routines to access hardware
*
* Copyright (c) 2013 Realtek Semiconductor Corp.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*/
#ifndef _INIC_SDIO_H_
#define _INIC_SDIO_H_
#include "rtl8721d_sdio.h"
#include "osdep_service.h"
#include "rtl8721d_inic.h"
#include <FreeRTOS.h>
#include "timers.h"
#include "semphr.h"
#if defined(__IAR_SYSTEMS_ICC__) //for IAR SDK
#include "platform_opts.h"
#endif
#define PURE_SDIO_INIC 0 // is a pure SDIO iNIC device or a SDIO iNIC + peripheral device
#ifndef PRIORITIE_OFFSET //PRIORITIE_OFFSET in FreeRTOSConfig.h
#define PRIORITIE_OFFSET 0
#endif
#define SDIO_RX_PKT_SIZE_OVER_16K 0 /* is support SDIO RX packet size > 16K. if true,
a big packet will be transmited via multiple RX_BD */
#define SDIO_MAILBOX_SIZE 10 // the maximum number of message block can be stored in this mailbox
#define SDIO_PERIODICAL_TIMER_INTERVAL 2000 // in ms, the interval of SDIO periodical timer
#define SDIO_AVG_TP_WIN_SIZE 20 // the number of entry to log the byte count for every periodical timer statistic, to calculate throughput
//TX BD setting
#define SDIO_TX_BD_BUF_SIZE 1540 //1514+24 //(2048+32) // the size of a TX BD pointed buffer, WLan header = 26 bytes
#define SDIO_TX_BD_NUM 20 // Number of TX BD
//RX BD setting
#define SDIO_RX_BD_BUF_SIZE 1540 //1514+24 //2048
#define SDIO_RX_BD_NUM 32 // Number of RX BD, to make 32K of bus aggregation, it needs 22 RX_BD at least
#define RX_BD_FREE_TH 5 // trigger the interrupt when free RX BD over this threshold
#define MAX_RX_BD_BUF_SIZE 16380 // the Maximum size for a RX_BD point to, make it 4-bytes aligned
#define SDIO_RX_PKT_NUM 128 // Number of RX packet handler
#define MIN_RX_BD_SEND_PKT 2 /* the minum needed RX_BD to send a Packet to Host, we need 2: one for RX_Desc, the other for payload */
#define SDIO_IRQ_PRIORITY 10
#define SDIO_TASK_PRIORITY 1 // it can be 0(lowest) ~ configMAX_PRIORITIES-1(highest)
#define SDIO_MP_TASK_PRIORITY 2 // it can be 0(lowest) ~ configMAX_PRIORITIES-1(highest)
//#if SDIO_TASK_PRIORITY > (configMAX_PRIORITIES - 1)
#if SDIO_TASK_PRIORITY > (4 - 1)
#error "SDIO Task Priority Should be 0~(configMAX_PRIORITIES-1)"
#endif
typedef struct {
u32 Address; /* The TX buffer physical address, it must be 4-bytes aligned */
}SDIO_TX_BD;
#define TX_BD_STRUCTURE_SIZE (sizeof(SDIO_TX_BD))
/* The RX Buffer Descriptor format */
typedef struct {
u32 BuffSize:14; /* bit[13:0], RX Buffer Size, Maximum 16384-1 */
u32 LS:1; /* bit[14], is the Last Segment ? */
u32 FS:1; /* bit[15], is the First Segment ? */
u32 Seq:16; /* bit[31:16], The sequence number, it's no use for now */
u32 PhyAddr; /* The RX buffer physical address, it must be 4-bytes aligned */
} SDIO_RX_BD;
#define RX_BD_STRUCTURE_SIZE (sizeof(SDIO_RX_BD))
// define the TX BD buffer size with unite of 64 byets
// Be carefull!! the setting of hardware's TX BD buffer size may exceed the real size of
// the TX BD buffer size, and then it may cause the hardware DMA write the buffer overflow
#define SDIO_TX_BUF_SZ_UNIT 64
#define SDIO_TX_BD_BUF_USIZE ((((SDIO_TX_BD_BUF_SIZE+sizeof(INIC_TX_DESC)-1)/SDIO_TX_BUF_SZ_UNIT)+1)&0xff)
typedef struct {
INIC_TX_DESC TX_Desc;
u8 TX_Buffer[SDIO_TX_BD_BUF_SIZE];
}SDIO_TX_BD_BUFFER;
typedef struct {
INIC_RX_DESC RxDesc; // The RX Descriptor for this packet, to be send to Host ahead this packet
#if CONFIG_INIC_EN
struct sk_buff *skb; //sdk->data will set to pData
#endif
u8 *pData; // point to the head of payload of this packet
u16 Offset; // the offset from the pData to the payload buffer
_list list; // the link list to chain packets
u8 isDyna; // is Dynamic allocated
} SDIO_RX_PACKET;
/* the data structer to bind a TX_BD with a TX Packet */
typedef struct {
#if CONFIG_INIC_EN
struct sk_buff *skb;
#endif
u8 isFree; // is this TX BD free
} SDIO_TX_BD_HANDLE;
/* the data structer to bind a RX_BD with a RX Packet */
typedef struct {
SDIO_RX_BD *pRXBD; // Point to the RX_BD buffer
SDIO_RX_PACKET *pPkt; // point to the Rx Packet
u8 isPktEnd; // For a packet over 1 BD , this flag to indicate is this BD contains a packet end
u8 isFree; // is this RX BD free (DMA done and its RX packet has been freed)
} SDIO_RX_BD_HANDLE;
typedef struct _HAL_SDIO_ADAPTER_ {
SDIO_TX_BD_HANDLE* pTXBDHdl; /* point to the allocated memory for TX_BD Handle array */
u16 TXBDWPtr; /* The SDIO TX(Host->Device) BD local write index, different with HW maintained write Index. */
u16 TXBDRPtr; /* The SDIO TX(Host->Device) BD read index */
u16 TXBDRPtrReg; /* The SDIO TX(Host->Device) BD read index has been write to HW register */
u8 TxOverFlow;
SDIO_RX_BD_HANDLE* pRXBDHdl; /* point to the allocated memory for RX_BD Handle array */
u16 RXBDWPtr; /* The SDIO RX(Device->Host) BD write index */
u16 RXBDRPtr; /* The SDIO RX(Device->Host) BD local read index, different with HW maintained Read Index. */
u32 Events; /* The Event to the SDIO Task */
u8 CCPWM; /* the value write to register CCPWM, which will sync to Host HCPWM */
u8 reserve1;
u16 CCPWM2; /* the value write to register CCPWM2, which will sync to Host HCPWM2 */
u8 CRPWM; /* sync from Host HRPWM */
u8 reserve2;
u16 CRPWM2; /* sync from Host HRPWM2 */
_sema TxSema; /* Semaphore for SDIO TX, use to wakeup the SDIO TX task */
_sema RxSema; /* Semaphore for SDIO RX, use to wakeup the SDIO RX task */
_sema IrqSema; /* Semaphore for SDIO RX, use to wakeup the SDIO RX task */
xTaskHandle xSDIOTxTaskHandle; /* The handle of the SDIO Task for TX, can be used to delte the task */
xTaskHandle xSDIORxTaskHandle; /* The handle of the SDIO Task speical for RX, can be used to delte the task */
xTaskHandle xSDIOIrqTaskHandle; /* The handle of the SDIO Task speical for RX, can be used to delte the task */
s8 (*Tx_Callback)(VOID *pAdapter, u8 *pPkt, u16 Offset, u16 PktSize, u8 type); /* to hook the WLan driver TX callback function to handle a Packet TX */
VOID *pTxCb_Adapter; /* a pointer will be used to call the TX Callback function,
which is from the TX CallBack function register */
s8 (*pTxCallback_Backup)(VOID *pAdapter, u8 *pPkt, u16 Offset, u16 PktSize, u8 type); // Use to back up the registered TX Callback function, for MP/Normal mode switch
VOID *pTxCb_Adapter_Backup; // Backup the pTxCb_Adapter, for MP/Normal mode switch
_list RxPktList; /* The list to queue RX packets */
_list FreeRxPktList; /* The list to queue free Rx packets handler */
_mutex RxMutex; /* The Mutex to protect RxPktList */
u32 RxInQCnt; /* The packet count for Rx In Queue */
} HAL_SDIO_ADAPTER, *PHAL_SDIO_ADAPTER;
// function not extern
VOID SDIO_TxTask(IN VOID *pData);
VOID SDIO_RxTask(IN VOID *pData);
VOID SDIO_IRQ_Handler_BH(VOID *pData);
u8 SDIO_Process_RPWM( IN PHAL_SDIO_ADAPTER pSDIODev);
u8 SDIO_Process_RPWM2(IN PHAL_SDIO_ADAPTER pSDIODev);
VOID SDIO_Reset_Cmd(IN PHAL_SDIO_ADAPTER pSDIODev);
VOID SDIO_Return_Rx_Data(IN PHAL_SDIO_ADAPTER pSDIODev);
VOID SDIO_Process_H2C_IOMsg(IN PHAL_SDIO_ADAPTER pSDIODev);
VOID SDIO_TX_FIFO_DataReady(IN PHAL_SDIO_ADAPTER pSDIODev);
VOID SDIO_Recycle_Rx_BD (IN PHAL_SDIO_ADAPTER pSDIODev);
VOID SDIO_IRQ_Handler(VOID *pData);
//function extern
extern BOOL SDIO_Device_Init(VOID);
extern VOID SDIO_Device_DeInit(VOID);
extern VOID SDIO_Send_C2H_IOMsg(IN PHAL_SDIO_ADAPTER pSDIODev, IN u32 *C2HMsg);
extern u8 SDIO_Send_C2H_PktMsg(IN PHAL_SDIO_ADAPTER pSDIODev, IN u8 *C2HMsg, IN u16 MsgLen);
extern VOID SDIO_Register_Tx_Callback(
IN PHAL_SDIO_ADAPTER pSDIODev,
IN s8 (*Tx_Callback)(VOID *pAdapter, u8 *pPkt, u16 Offset, u16 PktSize, u8 Type),
IN VOID *pAdapter
);
extern s8 SDIO_Rx_Callback(
IN PHAL_SDIO_ADAPTER pSDIODev,
IN VOID *pData,
IN u16 Offset,
IN u16 Length,
IN u8 CmdType
);
extern void SDIO_INTClear(void);
extern PHAL_SDIO_ADAPTER pgSDIODev;
#define HalSdioInit SDIO_Device_Init
#define HalSdioDeInit SDIO_Device_DeInit
#endif // #ifndef _INIC_SDIO_H_

View file

@ -0,0 +1,96 @@
/**
*********************************************************************************************************
* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
*********************************************************************************************************
* @file ir_led.h
* @brief This file provides driver of led encoding.
* @details
* @author elliot chen
* @date 2016-12-08
* @version v1.0
* *********************************************************************************************************
*/
#ifndef __IR_LED_H
#define __IR_LED_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Defines ------------------------------------------------------------------*/
typedef uint32_t IR_DataType;
/* Carrier waveform data type bit select */
#define PACK_TYPE ((uint32_t)31)
/* Carrier waveform data type select */
#define PULSE_HIGH ((uint32_t)0x80000000)
/* No carrier waveform data type select */
#define PULSE_LOW 0x0
/* IR data mask */
#define IR_DATA_MSK 0x7fffffffUL
/*when receiving waveform is inverse, we should define INVERSE_DATA*/
//#define INVERSE_DATA
/* Configure data code Width */
#define DATA_CODE_WIDTH 8
/* Configure maxium length of data code */
#define MAX_CODE_SIZE 3
/* Configure maxium length of data sent by IR peripheral */
#define MAX_IR_BUF_SIZE 51
/* Configure maxium data length of logical 0 or logical 1 */
#define MAX_LOG_WAVFORM_SIZE 2
/**
* @brief IR data structure definition
*/
typedef struct
{
/* Unit of carrierFreq is Hz */
uint32_t carrierFreq;
uint8_t code[MAX_CODE_SIZE];
uint8_t codeLen;
IR_DataType irBuf[MAX_IR_BUF_SIZE];
uint16_t bufLen;
} IR_DataTypeDef;
/**
* @brief IR protocol structure definition
*/
typedef struct
{
uint16_t carrierFreq;
IR_DataType log0Buf[MAX_LOG_WAVFORM_SIZE];
IR_DataType log1Buf[MAX_LOG_WAVFORM_SIZE];
uint32_t stopBuf;
uint32_t tolerancePrecent;
} LED_ProtocolTypeDef;
/**
* @brief IR return type of encoding function
*/
typedef enum
{
IR_SUCCEED = 0,
IR_FREQENCY_ERROR = 1,
IR_HEARDE_TYPE_ERROR = 2,
IR_HEADER_DATA_ERROR = 3,
IR_DATA_TYPE_ERROR = 4,
IR_DATA_ERROR = 5
} IR_RETURN_Type;
IR_RETURN_Type IR_LEDEncode(uint32_t freqency, uint8_t *data, IR_DataTypeDef *IR_DataStruct, int flag);
#ifdef __cplusplus
}
#endif
#endif /*__IR_LED_H*/
/******************* (C) COPYRIGHT 2016 Realtek Semiconductor Corporation *****END OF FILE****/

View file

@ -0,0 +1,117 @@
/**
*********************************************************************************************************
* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
*********************************************************************************************************
* @file ir_nec_protocol.h
* @brief This file provides driver of nec protocol encoding.
* @details
* @author elliot chen
* @date 2016-12-08
* @version v1.0
* *********************************************************************************************************
*/
#ifndef __IR_RCA_PROTOCOL_H
#define __IR_RCA_PROTOCOL_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Defines ------------------------------------------------------------------*/
typedef uint32_t IR_DataType;
/* Carrier waveform data type bit select */
#define PACK_TYPE ((uint32_t)31)
/* Carrier waveform data type select */
#define PULSE_HIGH ((uint32_t)0x80000000)
/* No carrier waveform data type select */
#define PULSE_LOW 0x0
/* IR data mask */
#define IR_DATA_MSK 0x7fffffffUL
/*when receiving waveform is inverse, we should define INVERSE_DATA*/
//#define INVERSE_DATA
/* Configure user code Width */
#define USER_CODE_WDTH 8
/* Configure data code Width */
#define DATA_CODE_WDTH 8
/* Configure maxium length of user code and data code */
#define MAX_CODE_SIZE 4
/* Configure maxium length of data sent by IR peripheral */
#define MAX_IR_BUF_SIZE 75
/* Configure maxium length of header of IR protocol */
#define MAX_HEADDER_LEN 2
/* Configure maxium data length of logical 0 or logical 1 */
#define MAX_LOG_WAVFORM_SIZE 2
/**
* @brief IR data structure definition
*/
typedef struct
{
/* Unit of carrierFreq is Hz */
uint32_t carrierFreq;
uint8_t code[MAX_CODE_SIZE];
uint8_t codeLen;
IR_DataType irBuf[MAX_IR_BUF_SIZE];
uint16_t bufLen;
} IR_DataTypeDef;
/**
* @brief IR protocol structure definition
*/
typedef struct
{
uint16_t carrierFreq;
uint8_t headerLen;
uint32_t headerBuf[MAX_HEADDER_LEN];
IR_DataType log0Buf[MAX_LOG_WAVFORM_SIZE];
IR_DataType log1Buf[MAX_LOG_WAVFORM_SIZE];
uint32_t stopBuf;
uint32_t tolerancePrecent;
} IR_ProtocolTypeDef;
/**
* @brief IR return type of encoding function
*/
typedef enum
{
IR_SUCCEED = 0,
IR_FREQENCY_ERROR = 1,
IR_HEARDE_TYPE_ERROR = 2,
IR_HEADER_DATA_ERROR = 3,
IR_DATA_TYPE_ERROR = 4,
IR_DATA_ERROR = 5
} IR_RETURN_Type;
/**
* @brief IR data length. This value depends on IR protocol.
*
*/
typedef enum
{
RCA_LENGTH = 52, /**< RCA data length */
NEC_LENGTH = 68, /**< NEC data length */
RC5_LENGTH = 80, /**< RC5 data length */
RC6_LENGTH = 70, /**< RC6 data length */
SONY_LENGTH = 90, /**< SONY data length */
} IR_Mode_Length;
IR_RETURN_Type IR_NECEncode(uint32_t freqency, uint8_t *data, IR_DataTypeDef *IR_DataStruct);
IR_RETURN_Type IR_NECDecode(uint32_t freqency, uint8_t *pdata, IR_DataTypeDef *IR_DataStruct);
#ifdef __cplusplus
}
#endif
#endif /*__IR_RCA_PROTOCOL_H*/
/******************* (C) COPYRIGHT 2016 Realtek Semiconductor Corporation *****END OF FILE****/

View file

@ -0,0 +1,2 @@
in ir_led document, ir is used to generate specific WS2812C-2020 waveforms needed by LED.
in led application, carrier frequency should be set more than 10MHz

View file

@ -0,0 +1,41 @@
//==========================================================================
//
// tmp75.h
//
// tmp75/175 temperature sensor driver using i2c for STM32 CortexM processors
//
//==========================================================================
// #####DESCRIPTIONBEGIN####
//
// Author(s): Cloud Tseng
// Contributors:
// Date: 2013-11-07
// Description: Temperature sensor driver using i2c for STM32 CortexM processors
//
// ####DESCRIPTIONEND####
//
//==========================================================================
#ifndef __MFI_I2C_H__
#define __MFI_I2C_H__
#include <stdint.h>
#define kMFiAuthReg_ProtocolMajorVersion 0x02
#define kMFiAuthReg_ErrorCode 0x05
#define kMFiAuthReg_AuthControlStatus 0x10
#define kMFiAuthErr_Flag 0x80
#define kMFiAuthControl_GenerateSignature 0x01
#define kMFiAuthReg_SignatureSize 0x11
#define kMFiAuthReg_SignatureData 0x12
#define kMFiAuthReg_ChallengeSize 0x20
#define kMFiAuthReg_ChallengeData 0x21
#define kMFiAuthReg_DeviceCertificateSize 0x30
#define kMFiAuthReg_DeviceCertificateData1 0x31 // Note: auto-increments so next read is Data2, Data3, etc.
uint16_t MFi_i2c_tx(uint8_t reg, const uint8_t* buf, uint16_t count, uint8_t retry);
uint16_t MFi_i2c_rx(uint8_t reg, uint8_t* buf, uint16_t count, uint8_t retry);
int MFi_auth_io(uint8_t reg, const uint8_t *write_buf, uint16_t write_count, uint8_t *read_buf, uint16_t read_count, uint8_t retry_count);
void MFi_auth_init(void);
void MFi_auth_deinit(void);
#endif //__MFI_I2C_H__

View file

@ -0,0 +1,18 @@
#ifndef __PIR_H__
#define __PIR_H__
#define PIR_IRQHandler EXTI1_IRQHandler
#define PIR_INT_GPIO_CLK RCC_AHB1Periph_GPIOB
#define PIR_INT_PIN GPIO_Pin_1
#define PIR_INT_GPIO_PORT GPIOB
#define PIR_INT_EXT_PORT_SRC EXTI_PortSourceGPIOB
#define PIR_INT_EXT_PIN_SRC EXTI_PinSource1
#define PIR_INT_EXT_LINE EXTI_Line1
#define PIR_INT_EXT_IRQ EXTI1_IRQn
void pir_isr(void);
int pir_init_flag(int *state);
int pir_init_callback(void (* pir_callback)(void));
void pir_exit(void);
#endif // __PIR_H__

View file

@ -0,0 +1,37 @@
#ifndef __RGB_LED_H__
#define __RGB_LED_H__
#include <stdint.h>
// R: PA6(TIM3_CH1) , G: PA7(TIM3_CH2) , B: PB0(TIM3_CH3)
#define TIMER TIM3
#define R_PIN GPIO_Pin_6
#define R_PORT GPIOA
#define R_CLK RCC_AHB1Periph_GPIOA
#define R_TCLK RCC_APB1Periph_TIM3
#define R_AF GPIO_AF_TIM3
#define R_AF_P GPIO_PinSource6
#define G_PIN GPIO_Pin_7
#define G_PORT GPIOA
#define G_CLK RCC_AHB1Periph_GPIOA
#define G_TCLK RCC_APB1Periph_TIM3
#define G_AF GPIO_AF_TIM3
#define G_AF_P GPIO_PinSource7
#define B_PIN GPIO_Pin_0
#define B_PORT GPIOB
#define B_CLK RCC_AHB1Periph_GPIOB
#define B_TCLK RCC_APB1Periph_TIM3
#define B_AF GPIO_AF_TIM3
#define B_AF_P GPIO_PinSource0
void led_init(void);
void led_set_color(uint8_t r, uint8_t g, uint8_t b);
void led_gradient_mode_thread(void *param);
void led_pinky_mode_thread(void *param);
void led_christmas_mode_thread(void *param);
void led_warning_mode_thread(void *param);
#endif // __RGB_LED_H__

View file

@ -0,0 +1,49 @@
//==========================================================================
//
// tmp75.h
//
// tmp75/175 temperature sensor driver using i2c for STM32 CortexM processors
//
//==========================================================================
// #####DESCRIPTIONBEGIN####
//
// Author(s): Cloud Tseng
// Contributors:
// Date: 2013-11-07
// Description: Temperature sensor driver using i2c for STM32 CortexM processors
//
// ####DESCRIPTIONEND####
//
//==========================================================================
#ifndef __TMP75_H__
#define __TMP75_H__
#include <stdint.h>
#define SHUTDOWN_MODE_OFF 0x00
#define SHUTDOWN_MODE_ON 0x01
#define COMPARATOR_MODE 0x00
#define INTERRUPT_MODE 0x02
#define POLARITY_0 0x00
#define POLARITY_1 0x04
#define FAULT_QUEUE_1 0x00
#define FAULT_QUEUE_2 0x08
#define FAULT_QUEUE_4 0x10
#define FAULT_QUEUE_6 0x18
#define RESOLUTION_9 0x00
#define RESOLUTION_10 0x20
#define RESOLUTION_11 0x40
#define RESOLUTION_12 0x60
#define ONE_SHOT 0x80
void tmp75_set_temperature_low(float value);
float tmp75_get_temperature_low(void);
void tmp75_set_temperature_high(float value);
float tmp75_get_temperature_high(void);
float tmp75_get_temperature(void);
void tmp75_set_config(uint8_t config);
uint8_t tmp75_get_config(void);
void tmp75_start_single_conversion(void);
void tmp75_init(void);
#endif //__TMP75_H__

View file

@ -0,0 +1,686 @@
#ifndef _SDIO_HEADER_8195B
#define _SDIO_HEADER_8195B
#if defined(CONFIG_PLATFORM_8195A)
typedef void (*sdioh_card_detect)(void *para);
typedef void (*sdioh_task_yield)(void);
typedef uint8_t sdioh_pin_sel_t;
typedef uint32_t hal_status_t;
#ifdef __cplusplus
#define __I volatile /*!< Defines 'read only' permissions */
#else
#define __I volatile const /*!< Defines 'read only' permissions */
#endif
#define __O volatile /*!< Defines 'write only' permissions */
#define __IO volatile /*!< Defines 'read / write' permissions */
#ifndef __IM /*!< Fallback for older CMSIS versions */
#define __IM __I
#endif
#ifndef __OM /*!< Fallback for older CMSIS versions */
#define __OM __O
#endif
#ifndef __IOM /*!< Fallback for older CMSIS versions */
#define __IOM __IO
#endif
#define __IM __I
#ifndef SDIO_HOST_Type
typedef struct { /*!< (@ 0x40058000) SDIO_HOST Structure */
__IM uint32_t RESERVED[256];
union {
__IOM uint32_t sram_ctl; /*!< (@ 0x00000400) SRAM Control Register */
struct {
__IOM uint32_t mem_region : 4; /*!< [3..0] Set this bit to enable buffer SRAM direct access mode. */
__IOM uint32_t access_en : 1; /*!< [4..4] Set this bit to enable buffer SRAM direct access mode. */
__IOM uint32_t map_sel : 1; /*!< [5..5] 0: R-Bus = x01020304 => to flash 01, 02, 03, 04; 1: R-Bus
= x01020304 => to flash 04, 03, 02, 01 */
__IOM uint32_t lx_burst_size : 2; /*!< [7..6] Set the Lexra burst size. 0: 64 Bytes; 1: 128 Bytes;
2: 256 Bytes; 3: 128 Bytes */
} sram_ctl_b;
} ;
union {
__IOM uint32_t dma_ctl1; /*!< (@ 0x00000404) DMA Control Register 1 */
struct {
__IOM uint32_t dram_sa : 28; /*!< [27..0] Dram start address for DMA transfer. This information
will be map to addcmd. (8 Bytes Unit, 1 means 8B) */
} dma_ctl1_b;
} ;
union {
__IOM uint32_t dma_ctl2; /*!< (@ 0x00000408) DMA Control Register 2 */
struct {
__IOM uint32_t dma_len : 16; /*!< [15..0] Transfer length for DMA transfer between DMA buffer
and DDR. (512B Unit, 1 means 512B) */
} dma_ctl2_b;
} ;
union {
__IOM uint32_t dma_ctl3; /*!< (@ 0x0000040C) DMA Control Register 3 */
struct {
__IOM uint32_t dma_xfer : 1; /*!< [0..0] Set this bit to transfer data between DRAM and DMA buffer.
Direction must be set at next bit. The transfer length
is reference to DMA_CTL2[15:0]. This bit will be auto clear
when transfer done. */
__IOM uint32_t ddr_wr : 1; /*!< [1..1] 1: Move data from DMA buffer to DDR; 0: Move data from
DDR to DMA Buffer. */
__IM uint32_t : 2;
__IOM uint32_t rsp17_sel : 1; /*!< [4..4] For response is R2 case, reponse will transfer by dma
and not store in register. 1: dma count to 16byte and send
sb1_req; 0: normal case. */
__IOM uint32_t dat64_sel : 1; /*!< [5..5] For CMD6 case, read data length is 64byte (less than
256 byte) 1: dma count to 64byte and send sb1_req; 0: normal
case. */
} dma_ctl3_b;
} ;
union {
__IOM uint32_t sys_low_pwr; /*!< (@ 0x00000410) Low Power Control Register */
struct {
__IOM uint32_t dma_sram_rdy_num : 4; /*!< [3..0] DMA SRAM ready cycle (leave sleep mode) (N+1) * clk_sys
period */
__IOM uint32_t dma_sram_lp_ena : 1; /*!< [4..4] DMA SRAM low power enable */
__IM uint32_t : 1;
__IOM uint32_t sys_clk_gate_ena : 1; /*!< [6..6] DMA clk_sys gating enable */
} sys_low_pwr_b;
} ;
__IM uint32_t RESERVED1[4];
union {
__IOM uint32_t sd_isr; /*!< (@ 0x00000424) SD Interrupt Status Register */
struct {
__IOM uint32_t write_data : 1; /*!< [0..0] 1 to set, 0 to clear bit with 1. */
__IOM uint32_t int1 : 1; /*!< [1..1] SD Int1. Card End. */
__IOM uint32_t int2 : 1; /*!< [2..2] SD Int2. Card Error. */
__IM uint32_t : 1;
__IOM uint32_t int4 : 1; /*!< [4..4] SD Int4. DMA transfer done INT. */
} sd_isr_b;
} ;
union {
__IOM uint32_t sd_isren; /*!< (@ 0x00000428) SD Interrupt Enable Register */
struct {
__IOM uint32_t write_data : 1; /*!< [0..0] 1 to set, 0 to clear bit with 1. */
__IOM uint32_t int1en : 1; /*!< [1..1] SD Int1 Enable Card End INT Enable. */
__IOM uint32_t int2en : 1; /*!< [2..2] SD Int2 Enable Card Error INT Enable. */
__IM uint32_t : 1;
__IOM uint32_t int4en : 1; /*!< [4..4] SD Int4 Enable dma_clr INT Enable. */
} sd_isren_b;
} ;
__IM uint32_t RESERVED2[18];
union {
__IOM uint32_t pad_ctl; /*!< (@ 0x00000474) Pad Control Register */
struct {
__IOM uint32_t tune3318 : 1; /*!< [0..0] Pad select 3.3v or 1.8v. 1: 3.3v; 0: 1.8v */
} pad_ctl_b;
} ;
union {
__IOM uint32_t ckgen_ctl; /*!< (@ 0x00000478) Clock Generation Control Register */
struct {
__IOM uint32_t clk_div : 3; /*!< [2..0] 000: div1; 001: div2; 010: div4; 011: div8 */
__IM uint32_t : 1;
__IOM uint32_t crc_clk_src : 2; /*!< [5..4] 00: ssc_clk; 01: ssc_clk_vp0; 10: ssc_clk_vp1 */
__IM uint32_t : 2;
__IOM uint32_t sd30_push_clk_src : 2; /*!< [9..8] 00: ssc_clk; 01: ssc_clk_vp0; 10: ssc_clk_vp1 */
__IM uint32_t : 2;
__IOM uint32_t sd30_sample_clk_src : 2; /*!< [13..12] 00: ssc_clk; 01: ssc_clk_vp0; 10: ssc_clk_vp1 */
__IM uint32_t : 2;
__IOM uint32_t crc_clk_change : 1; /*!< [16..16] 0: from crc_clk_src; 1: clk4M */
__IOM uint32_t sd30_push_change : 1; /*!< [17..17] 0: from sd30_push_clk_src; 1: clk4M */
__IOM uint32_t sd30_sample_change : 1; /*!< [18..18] 0: from sd30_sample_clk_src; 1: clk4M */
} ckgen_ctl_b;
} ;
__IM uint32_t RESERVED3[33];
__IM uint16_t RESERVED4;
union {
__IOM uint8_t card_drive_sel; /*!< (@ 0x00000502) Card Driving Selection Register */
struct {
__IOM uint8_t cf_drive : 2; /*!< [1..0] CF Interface Drive. 00: 4mA; 01: 8mA; 10: 12mA; 11: 12mA */
__IOM uint8_t xd_drive : 2; /*!< [3..2] XD Interface Drive. 00: 4mA; 01: 8mA; 10: 12mA; 11: 12mA */
__IOM uint8_t sd_drive : 2; /*!< [5..4] SD DAT7~4 Interface Drive. 00: 4mA; 01: 8mA; 10: 12mA;
11: 12mA */
__IOM uint8_t ms_drive : 2; /*!< [7..6] MS Interface Drive. 00: 4mA; 01: 8mA; 10: 12mA; 11: 12mA */
} card_drive_sel_b;
} ;
union {
__IOM uint8_t card_stop; /*!< (@ 0x00000503) Stop Transfer Register */
struct {
__IOM uint8_t cf_module : 1; /*!< [0..0] Target module is CF/MD card module. If set this bit the
transfer will be stop and the state machine of transfer
will return idle state. */
__IOM uint8_t sm_module : 1; /*!< [1..1] Target module is SM/XD card module. If set this bit the
transfer will be stop and the state machine of transfer
will return idle state. */
__IOM uint8_t sd_module : 1; /*!< [2..2] Target module is SD/MMC card module (SD). If set this
bit the transfer will be stop and the state machine of
transfer will return idle state. */
__IOM uint8_t ms_module : 1; /*!< [3..3] Target module is MS/MS-Pro/HG card module (MS). If set
this bit the transfer will be stop and the state machine
of transfer will return idle state. */
__IOM uint8_t sd2_module : 1; /*!< [4..4] Target module is SD/MMC card module (SD2). If set this
bit the transfer will be stop and the state machine of
transfer will return idle state. */
__IOM uint8_t ms2_module : 1; /*!< [5..5] Target module is MS/MS-Pro/HG card module (MS2). If set
this bit the transfer will be stop and the state machine
of transfer will return idle state. */
} card_stop_b;
} ;
__IM uint32_t RESERVED5[2];
__IM uint16_t RESERVED6;
union {
__IOM uint8_t card_select; /*!< (@ 0x0000050E) Card Type Select Register */
struct {
__IOM uint8_t card_sel : 3; /*!< [2..0] Card Select. Specify the current active card module.
000: CF module 001: XD module 010: SD module 011: MS module
100: I2C module 101: Reserved 110: SD2 module 111: MS2
module */
} card_select_b;
} ;
__IOM uint8_t dummy1; /*!< (@ 0x0000050F) Dummy Register 1 */
__IM uint32_t RESERVED7[3];
__IM uint16_t RESERVED8;
__IM uint8_t RESERVED9;
union {
__IOM uint8_t card_exist; /*!< (@ 0x0000051F) Card Detection Register */
struct {
__IOM uint8_t cf_exist : 1; /*!< [0..0] CF Existence. If this bit is set it means CF/MD card
is in its socket. */
__IOM uint8_t sm_exist : 1; /*!< [1..1] SM Existence. If this bit is set it means SM card is
in its socket. */
__IOM uint8_t sd_exist : 1; /*!< [2..2] SD Existence. If this bit is set it means SD/MMC card
is in its socket. */
__IOM uint8_t ms_exist : 1; /*!< [3..3] MS Existence. If this bit is set it means MS/MS-pro card
is in its socket. */
__IOM uint8_t xd_exist : 1; /*!< [4..4] XD Existence. If this bit is set it means XD card is
in its socket. */
__IOM uint8_t sd_wp : 1; /*!< [5..5] SD Write Protect. If this bit is set it means SD card
is mechanical write protected. */
__IOM uint8_t xd_wp : 1; /*!< [6..6] XD_WP Input. If the XD_WP pin is configure as input,
this bit reflect the level of XD_WP signal directly. */
} card_exist_b;
} ;
union {
__IOM uint8_t card_int_en; /*!< (@ 0x00000520) Card Interrupt Enable Register */
struct {
__IOM uint8_t cf_int_en : 1; /*!< [0..0] CF Card Interrupt Enable. If this bit is set it enables
the interrupt of CF card */
__IOM uint8_t sm_int_en : 1; /*!< [1..1] SM Card Interrupt Enable. If this bit is set it enables
the interrupt of SM card */
__IOM uint8_t sd_int_en : 1; /*!< [2..2] SD/MMC Interrupt Enable. If this bit is set it enables
the interrupt of SD/MMC card */
__IOM uint8_t ms_int_en : 1; /*!< [3..3] MS/MS-pro/HG card Interrupt Enable. If this bit is set
it enables the interrupt of MS/MS-pro card */
__IOM uint8_t xd_int_en : 1; /*!< [4..4] XD Card Interrupt Enable. If this bit is set it enables
the interrupt of XD card */
__IOM uint8_t sd2_int_en : 1; /*!< [5..5] SD/MMC (SD2) Interrupt Enable. If this bit is set it
enables the interrupt of SD/MMC card */
__IOM uint8_t ms2_int_en : 1; /*!< [6..6] MS/MS-pro/HG (MS2) card Interrupt Enable. If this bit
is set it enables the interrupt of MS/MS-pro card */
__IOM uint8_t gpio_int_en : 1; /*!< [7..7] GPIO[0] Interrupt Enable. If this bit is set it enables
the interrupt of GPIO0 */
} card_int_en_b;
} ;
union {
__IOM uint8_t card_int_pend; /*!< (@ 0x00000521) Card Interrupt Status Register */
struct {
__IOM uint8_t cf_int_pend : 1; /*!< [0..0] CF Card Interrupt Pending. If this bit is set it means
the interrupt of CF card is pending and write '1' to this
bit to clear the interrupt flag to '0' */
__IOM uint8_t sm_int_pend : 1; /*!< [1..1] SM Card Interrupt Pending. If this bit is set it means
the interrupt of SM card is pending and write '1' to this
bit to clear the interrupt flag to '0' */
__IOM uint8_t sd_int_pend : 1; /*!< [2..2] SD/MMC Interrupt Pending. If this bit is set it means
the interrupt of SD/MMC card is pending and write '1' to
this bit to clear the interrupt flag to '0' */
__IOM uint8_t ms_int_pend : 1; /*!< [3..3] MS/MS-pro/HG card Interrupt Pending. If this bit is set
it means the interrupt of MS/MS-pro card is pending and
write '1' to this bit to clear the interrupt flag to '0' */
__IOM uint8_t xd_int_pend : 1; /*!< [4..4] XD Card Interrupt Pending. If this bit is set it means
the interrupt of XD card is pending and write '1' to this
bit to clear the interrupt flag to '0' */
__IOM uint8_t sd2_int_pend : 1; /*!< [5..5] SD/MMC (SD2) Interrupt Pending. If this bit is set it
means the interrupt of SD/MMC card is pending and write
'1' to this bit to clear the interrupt flag to '0' */
__IOM uint8_t ms2_int_pend : 1; /*!< [6..6] MS/MS-pro/HG (MS2) card Interrupt Pending. If this bit
is set it means the interrupt of MS/MS-pro card is pending
and write '1' to this bit to clear the interrupt flag to
'0' */
__IOM uint8_t gpio_int_pend : 1; /*!< [7..7] GPIO[0] Interrupt Pending. If this bit is set it means
the interrupt of GPIO0 is pending and write '1' to this
bit to clear the interrupt flag to '0' */
} card_int_pend_b;
} ;
__IM uint16_t RESERVED10;
__IM uint32_t RESERVED11;
__IM uint8_t RESERVED12;
union {
__IOM uint8_t card_clk_en_ctl; /*!< (@ 0x00000529) Card Clock Enable Control Register */
struct {
__IOM uint8_t cf_clk_en : 1; /*!< [0..0] CF Card Module Clock Enable Control. Disable clock can
save power. 0: Disable; 1: Enable */
__IOM uint8_t xd_clk_en : 1; /*!< [1..1] XD Card Module Clock Enable Control. Disable clock can
save power. 0: Disable; 1: Enable */
__IOM uint8_t sd_clk_en : 1; /*!< [2..2] SD Card Module Clock Enable Control. Disable clock can
save power. 0: Disable; 1: Enable */
__IOM uint8_t ms_clk_en : 1; /*!< [3..3] MS Card Module Clock Enable Control. Disable clock can
save power. 0: Disable; 1: Enable */
__IOM uint8_t sd2_clk_en : 1; /*!< [4..4] SD2 Card Module Clock Enable Control. Disable clock can
save power. 0: Disable; 1: Enable */
__IOM uint8_t ms2_clk_en : 1; /*!< [5..5] MS2 Card Module Clock Enable Control. Disable clock can
save power. 0: Disable; 1: Enable */
__IOM uint8_t sw_clk_mode : 1; /*!< [6..6] Switch Clock Mode. Clk_en use FW configuration of HW
setting. 0: Clk_en use FW configure 1: Clk_en use HW setting */
__IOM uint8_t auto_cbw : 1; /*!< [7..7] Auto CBW Mode. Used for card select option. 0: Card select
is configured by FW. 1: Card select is configured by HW. */
} card_clk_en_ctl_b;
} ;
__IM uint16_t RESERVED13;
__IM uint32_t RESERVED14;
union {
__IOM uint8_t clk_pad_drive; /*!< (@ 0x00000530) Clock Pad Driving Register */
struct {
__IOM uint8_t nmos_drive : 3; /*!< [2..0] SD_CLK PAD NMOS drive select 3V3: 1V8: 000: x 10.1 x
1.93 001: x 13.5 x 3.85 010,100: x 16.9 x 5.78 011,101:
x 20.2 x 7.73 110: x 23.5 x 9.65 111: x 26.8 x 11.5 */
__IOM uint8_t pmos_drive : 3; /*!< [5..3] SD_CLK PAD PMOS drive select 3V3: 1V8: 000: x 7,07 x
2.27 001: x 14.2 x 4.61 010,100: x 21 x 6.68 011,101: x
27.9 x 9.14 110: x 34.9 x 11.5 111: x 42.4 x 13.8 */
} clk_pad_drive_b;
} ;
union {
__IOM uint8_t cmd_pad_drive; /*!< (@ 0x00000531) Command Pad Driving Register */
struct {
__IOM uint8_t nmos_drive : 3; /*!< [2..0] SD_CMD PAD NMOS drive select 3V3: 1V8: 000: x 10.1 x
1.93 001: x 13.5 x 3.85 010,100: x 16.9 x 5.78 011,101:
x 20.2 x 7.73 110: x 23.5 x 9.65 111: x 26.8 x 11.5 */
__IOM uint8_t pmos_drive : 3; /*!< [5..3] SD_CMD PAD PMOS drive select 3V3: 1V8: 000: x 7,07 x
2.27 001: x 14.2 x 4.61 010,100: x 21 x 6.68 011,101: x
27.9 x 9.14 110: x 34.9 x 11.5 111: x 42.4 x 13.8 */
} cmd_pad_drive_b;
} ;
union {
__IOM uint8_t dat_pad_drive; /*!< (@ 0x00000532) Data Pad Driving Register */
struct {
__IOM uint8_t nmos_drive : 3; /*!< [2..0] SD_DAT[3:0] PAD NMOS drive select 3V3: 1V8: 000: x 10.1
x 1.93 001: x 13.5 x 3.85 010,100: x 16.9 x 5.78 011,101:
x 20.2 x 7.73 110: x 23.5 x 9.65 111: x 26.8 x 11.5 */
__IOM uint8_t pmos_drive : 3; /*!< [5..3] SD_DAT[3:0] PAD PMOS drive select 3V3: 1V8: 000: x 7,07
x 2.27 001: x 14.2 x 4.61 010,100: x 21 x 6.68 011,101:
x 27.9 x 9.14 110: x 34.9 x 11.5 111: x 42.4 x 13.8 */
} dat_pad_drive_b;
} ;
__IM uint8_t RESERVED15;
__IM uint32_t RESERVED16[19];
union {
__IOM uint8_t sd_config1; /*!< (@ 0x00000580) SD Configuration Register 1 */
struct {
__IOM uint8_t bus_width : 2; /*!< [1..0] 00: 1-bit bus 01: 4-bit bus 10: 8-bit bus 11: Reserved */
__IOM uint8_t mode_sel : 2; /*!< [3..2] 00: SD20 mode (single data rate; internal clock frequency
is 2 times as SD_CLK) 01: DDR mode (double data rate; internal
clock frequency is 2 times as SD_CLK) 10: SD30 mode (single
data rate; internal clock frequency is the same as SD_CLK;
sampling point turning can only be used in this mode) 11:
Reserved Note: When access SDR Card that needs to do sampling
turning, we must select SD30_mode; when access SDR Card
that needn't sampling turning, both SD20_mode and SD30_mode
is available. */
__IOM uint8_t sd30_async_fifo_rst : 1; /*!< [4..4] When SD30_mode is asserted, the input CMD/DAT will be
latched by an asynchronous FIFO. The write clock of FIFO
is sample clock; the read clock of FIFO is internal clock.
Write this bit to 1'b0 to reset write/read pointer of FIFO
after the frequency/phase of sample clock or internal clock
is changed. */
__IM uint8_t : 1;
__IOM uint8_t clk_div : 1; /*!< [6..6] Clock Divider (only available when initial mode is set)
0: SDCLK is divided by 128 1: SDCLK is divided by 256 */
__IOM uint8_t initial_mode : 1; /*!< [7..7] Initial Mode (can not be used in SD30 mode) This bit
is used to control whether the SD clock will be divided
by clock divider 0: The SD clock can not be divided 1:
The SD clock will de divided by the value of Clock Divider */
} sd_config1_b;
} ;
union {
__IOM uint8_t sd_config2; /*!< (@ 0x00000581) SD Configuration Register 2 */
struct {
__IOM uint8_t rsp_type : 2; /*!< [1..0] Response Type Configure. 00: No response 01: 6-byte response
10: 17-byte response 11: Reserved */
__IOM uint8_t crc7_chk : 1; /*!< [2..2] CRC7 Check Enable. 0: Check CRC7 1: Not check CRC7 */
__IOM uint8_t wait_busy_end : 1; /*!< [3..3] Wait busy End Enable If this bit is set, hardware will
wait (with SD_CLK continually toggling) till SD card is
ready (SD_DAT0 is 1). This bit is only available when HW
executes SEND_CMD_GET_RSP command code 0: .Not wait busy
end; HW will stop toggle SD clock after the command/response
transfer is completed, not concern about whether the SD_DAT0
is 1b or not 1: Wait busy end; HW will continue to toggle
SD clock if SD_DAT0 is 0b */
__IOM uint8_t ignore_crc_sts_err : 1; /*!< [4..4] Ignore Write CRC Error Enable. Set this bit to ignore
the write error. 0: Check whether CRC status returned by
card is correct 1: Not check whether CRC status returned
by card is correct */
__IOM uint8_t wait_crc_sts_timeout : 1; /*!< [5..5] Wait Write CRC Status Time Out Enable If this bit is
set, HW will check whether the write CRC status is sent
by card in time.(In SD3.0 spec, card should send the CRC
status within 8 clocks, HW will wait 16 clocks actually)
0: HW will Check whether the write CRC status is time-out
1: HW will Not Check whether the write CRC status is time-out */
__IOM uint8_t crc16_chk : 1; /*!< [6..6] CRC16 Check Enable. 0: Check CRC16 1: Not check CRC16 */
__IOM uint8_t crc7_cal : 1; /*!< [7..7] CRC7 Calculation Enable. 0: Calculate CRC7 1: No calculation */
} sd_config2_b;
} ;
union {
__IOM uint8_t sd_config3; /*!< (@ 0x00000582) SD Configuration Register 3 */
struct {
__IOM uint8_t rsp_timeout_en : 1; /*!< [0..0] SD CMD Response Time Out Enable. If this bit is set,
HW will not check whether card's response to command is
time-out. It is considered to time-out if there is no SD
command response within 80 periods of SD_CLK after the
end bit of command is on the bus. 0: Not check whether
the response to command is time-out 1: Check whether the
response to command is time-out */
__IOM uint8_t addr_mode : 1; /*!< [1..1] Address mode. 0: sector address mode SD start data address
set in SD read/write command argument(CMD18/CMD25) equal
to (the start sector address) which is set in SCSI command
read10/write10; 1: byte mode SD start data address set
in SD read/write command argument(CMD18/CMD25) equal to
(the start sector address <<9) */
__IOM uint8_t rsp_chk : 1; /*!< [2..2] SD CMD Response Check Enable When in Random auto mode,
If this bit is set, HW will check whether card's response
is received correctly or not. When not in random auto mode,
this bit is useless. 0: No check whether the response of
command is correct 1: Check whether the response to command
is correct */
__IOM uint8_t sd20_clk_stop : 1; /*!< [3..3] SD20 Clock Stop After Data Transfer Over Enable. (Default
Disable) In order to conform to eMMC spec(NAC minimum value
is 2 SD Clock cycle), when this bit is 1'b1 and data transfer
is over(Sector Count is 0), SD clock(SD20 mode) is stopped
immediately. 0: Disable 1: Enable */
__IOM uint8_t sd30_clk_stop : 1; /*!< [4..4] SD30 Clock Stop After Data Transfer Over Enable. (Default
Disable) In order to conform to eMMC spec(NAC minimum value
is 2 SD Clock cycle), when this bit is 1'b1 and data transfer
is over(Sector Count is 0), SD clock(SD30 SDR and DDR mode)
is stopped immediately. 0: Disable 1: Enable */
__IOM uint8_t wait_card_idle : 1; /*!< [5..5] Data Phase Wait Card busy Enable. When this bit is set
, wait until SD card not busy, then set sd_end. 0: No wait
SD card not busy, set sd_end immediately when data transfer
is over 1: Wait until SD card is not busy, then set sd_end */
__IOM uint8_t cmd_start_wait_card_idle : 1;/*!< [6..6] CMD Start Wait No Card busy. When this bit is set , no
wait card busy and send command immediately. 0: Wait until
card is not busy, then send the pending command 1: No wait
card busy and send command immediately */
__IOM uint8_t stop_cmd_start_wait_card_idle : 1;/*!< [7..7] STOP CMD Start No Wait Card busy. This bit is only valid
when the SD card controller is auto in random auto mode.
In random auto mode, SD card controller will auto send
stop cmd(CMD12) after read/write cmd(cmd18/cmd25), this
bit control whether HW wait busy end before send CMD12
When this bit is set , no wait card busy and send stop
command (CMD12) immediately. 0: Wait until card is not
busy, then send the stop command (CMD12) 1: No wait card
busy and send stop command immediately */
} sd_config3_b;
} ;
union {
__IOM uint8_t sd_status1; /*!< (@ 0x00000583) SD Status Register 1 */
struct {
__IOM uint8_t tune_patrn_err : 1; /*!< [0..0] SD Tuning Pattern Compare Error. This bit will be set
to 1'b1, if the tuning data sampled by HW is not correct. */
__IOM uint8_t crc_sts_timeout_err : 1; /*!< [1..1] Get Write CRC Status Time-out Error This bit will be
set to 1'b1, if SD card doesn't return write CRC status
bits to host within 8 SD_CLK cycles after the end bit of
data packet is on the bus (actually, HW will wait 16 clocks). */
__IOM uint8_t crc_sts_val : 3; /*!< [4..2] Status Of Write CRC Status. This field reflects write
error bits returned from SD card. When card check CRC error,
it sends back CRC status (101); when card check CRC no
error, it sends back CRC status (010); when flash programming
error, CRC status read (111). */
__IOM uint8_t crc_sts_err : 1; /*!< [5..5] Write CRC Error. This bit will be set to 1'b1, if the
write CRC status bits are not equal to 3'b010. (this means
Card detected CRC16 error in the data it received from
host). */
__IOM uint8_t crc16_err : 1; /*!< [6..6] CRC16 Error. This bit will be set to 1'b1, if there is
CRC16 check error in the data from SD card. */
__IOM uint8_t crc7_err : 1; /*!< [7..7] CRC7 Error. This bit will be set to 1'b1, if there is
CRC7 check error in the response from SD card. */
} sd_status1_b;
} ;
union {
__IOM uint8_t sd_status2; /*!< (@ 0x00000584) SD Status Register 2 */
struct {
__IOM uint8_t rsp_timeout_err : 1; /*!< [0..0] SD CMD Response Timeout Error. This bit will be set to
1'b1, if there is no response within 80 periods of SD_CLK
after the end bit of command is on the bus. */
__IOM uint8_t rsp_invalid : 1; /*!< [1..1] SD CMD Response Invalid. If SD_CONFIGURE3 bit[2] is set,
this bit will reflect when the response is correct or not.
If this bit is set, sd_end and sd_error (SD_TRANSFER bit[6]
and bit[4]) will also be set 0: The response of command
is correct 1: The response to command is not correct */
__IOM uint8_t cbw_state : 4; /*!< [5..2] CBW State Machine. */
} sd_status2_b;
} ;
union {
__IOM uint8_t sd_bus_status; /*!< (@ 0x00000585) SD Bus Status Register */
struct {
__IOM uint8_t cmd : 1; /*!< [0..0] This bit reflect the level of pin SD_CMD. */
__IOM uint8_t dat3_0 : 4; /*!< [4..1] This bit reflect the level of pin SD_DAT3~SD_DAT0. */
__IM uint8_t : 1;
__IOM uint8_t stop_sdclk_when_no_xfer : 1;/*!< [6..6] Stop SD_CLK toggling when no cmd/data transfer (ignore
the level of SDDAT0) */
__IOM uint8_t sdclk_toggle : 1; /*!< [7..7] SD_CLK Toggle Enable. If this bit is set, host will generate
SDCLK toggle signal even when there is no signal transaction
on the CMD/DAT bus */
} sd_bus_status_b;
} ;
__IM uint16_t RESERVED17;
__IM uint8_t RESERVED18;
union {
__IOM uint8_t sd_cmd0; /*!< (@ 0x00000589) SD Command Register 0 */
struct {
__IOM uint8_t cmd : 8; /*!< [7..0] Command[47:40] or Response Data[47:40]. */
} sd_cmd0_b;
} ;
union {
__IOM uint8_t sd_cmd1; /*!< (@ 0x0000058A) SD Command Register 1 */
struct {
__IOM uint8_t cmd : 8; /*!< [7..0] Command[39:32] or Response Data[39:32]. */
} sd_cmd1_b;
} ;
union {
__IOM uint8_t sd_cmd2; /*!< (@ 0x0000058B) SD Command Register 2 */
struct {
__IOM uint8_t cmd : 8; /*!< [7..0] Command[31:24] or Response Data[31:24]. */
} sd_cmd2_b;
} ;
union {
__IOM uint8_t sd_cmd3; /*!< (@ 0x0000058C) SD Command Register 3 */
struct {
__IOM uint8_t cmd : 8; /*!< [7..0] Command[23:16] or Response Data[23:16]. */
} sd_cmd3_b;
} ;
union {
__IOM uint8_t sd_cmd4; /*!< (@ 0x0000058D) SD Command Register 4 */
struct {
__IOM uint8_t cmd : 8; /*!< [7..0] Command[15:8] or Response Data[15:8]. */
} sd_cmd4_b;
} ;
union {
__IOM uint8_t sd_cmd5; /*!< (@ 0x0000058E) SD Command Register 5 */
struct {
__IOM uint8_t cmd : 8; /*!< [7..0] Command[7:0] or Response Data[7:0]. */
} sd_cmd5_b;
} ;
union {
__IOM uint8_t sd_byte_cnt_l; /*!< (@ 0x0000058F) Byte Count Register (Low Byte) */
struct {
__IOM uint8_t byte_cnt_l : 8; /*!< [7..0] Byte Count[7:0]. Byte count in one block transferred
from/to SD card. */
} sd_byte_cnt_l_b;
} ;
union {
__IOM uint8_t sd_byte_cnt_h; /*!< (@ 0x00000590) Byte Count Register (High Byte) */
struct {
__IOM uint8_t byte_cnt_h : 3; /*!< [2..0] Byte Count[10:8]. Byte count in one block transferred
from/to SD card. */
} sd_byte_cnt_h_b;
} ;
union {
__IOM uint8_t sd_blk_cnt_l; /*!< (@ 0x00000591) Block Count Register (Low Byte) */
struct {
__IOM uint8_t blk_cnt_l : 8; /*!< [7..0] Block Count[7:0]. Block count transferred from/to SD
card. */
} sd_blk_cnt_l_b;
} ;
union {
__IOM uint8_t sd_blk_cnt_h; /*!< (@ 0x00000592) Block Count Register (High Byte) */
struct {
__IOM uint8_t blk_cnt_h : 7; /*!< [6..0] Block Count[14:8]. Byte count transferred from/to SD
card. */
} sd_blk_cnt_h_b;
} ;
union {
__IOM uint8_t sd_xfer; /*!< (@ 0x00000593) SD Transfer Control Register */
struct {
__IOM uint8_t cmd_code : 4; /*!< [3..0] Command Code. These bits encoded each working mode of
SD card control module. 0000(NORMAL_WRITE): Write 1 or
2 bytes to SD card and the content are put into SD_CMD2
& SD_CMD3 in advance. Hardware ignores write error returned
from SD card in this case. 0001(AUTO_WRITE3): Hardware
writes data from Ring buffer to SD card and the data length
is (SD_BYTE_CNT * SD_BLOCK_CNT). Hardware can only write
even bytes (2, 4, 6, ..., 512) data from SRAM2 buffer to
SD card if data source is consigned to SRAM2 buffer in
th */
__IOM uint8_t err : 1; /*!< [4..4] If this bit is set which means some error occurs detailed
error information is in register SD_STAT. */
__IOM uint8_t idle_ste : 1; /*!< [5..5] Status of SD card module state machine When this bit
is set 1, it means that the SD card module state machine
is in idle state. */
__IOM uint8_t end : 1; /*!< [6..6] If transfer starts this bit will be clear automatically
by hardware. And if transfer completes this bit will be
set and keep 1 until the next Start is set. */
__IOM uint8_t start : 1; /*!< [7..7] The transfer is launch if set this bit. */
} sd_xfer_b;
} ;
__IM uint8_t RESERVED19;
union {
__IOM uint8_t sd_cmd_ste; /*!< (@ 0x00000595) SD Command State Register */
struct {
__IOM uint8_t cmd_ste : 4; /*!< [3..0] CMD State Machine */
__IM uint8_t : 3;
__IOM uint8_t cmd_ste_is_idle : 1; /*!< [7..7] CMD State Machine is idle When this bit is 1'b1, it indicates
IDLE state of CMD State Machine */
} sd_cmd_ste_b;
} ;
union {
__IOM uint8_t sd_data_ste; /*!< (@ 0x00000596) SD Data State Register */
struct {
__IOM uint8_t data_ste : 5; /*!< [4..0] DATA State Machine */
__IM uint8_t : 2;
__IOM uint8_t data_ste_is_idle : 1; /*!< [7..7] DATA State Machine is idle When this bit is 1'b1, it
indicates IDLE state of DATA State Machine */
} sd_data_ste_b;
} ;
} SDIO_HOST_Type;
#endif
typedef struct hal_sdio_host_adapter_s {
SDIO_HOST_Type *base_addr;
u32 xfer_int_sts;
u8 csd[16];
u16 rca;
volatile u8 is_card_inserted;
volatile u8 is_wp;
u8 curr_sig_level;
u8 is_sdhc_sdxc;
u8 card_curr_ste;
u8 sd_spec_ver;
u8 curr_bus_spd;
u8 pin_mux_sel;
u8 card_support_spd_mdoe;
u8 is_s18a;
u8 voltage_mismatch;
u8 rsvd[3];
sdioh_card_detect card_insert_cb;
sdioh_card_detect card_remove_cb;
void *card_insert_cb_para;
void *card_remove_cb_para;
sdioh_task_yield task_yield;
void (*dcache_invalidate_by_addr)(uint32_t *addr, int32_t dsize); /*! callback function to do the D-cache invalidate */
void (*dcache_clean_by_addr) (uint32_t *addr, int32_t dsize); /*! callback function to do the D-cache clean */
} hal_sdio_host_adapter_t, *phal_sdio_host_adapter_t;
#endif
#endif

View file

@ -0,0 +1,49 @@
#ifndef _SD_DRIVER_H
#define _SD_DRIVER_H
#include "basic_types.h"
#include "cmsis.h"
#ifdef CONFIG_PLATFORM_8721D
#include "rtl8721dhp_sd.h"
#else
#define CONFIG_SD_SDIO 1
#define CONFIG_SD_SPI 0
typedef enum
{
SD_OK = 0,
SD_NODISK,
SD_INSERT,
SD_INITERR,
SD_PROTECTED,
SD_ERROR,
}SD_RESULT;
typedef enum{
SD_CLK_LOW,
SD_CLK_MID,
SD_CLK_HIGH,
SD_CLK_RSV,
}SD_CLK;
SD_RESULT SD_WaitReady(void);
SD_RESULT SD_Init(void);
SD_RESULT SD_DeInit(void);
#if defined(CONFIG_PLATFORM_8195A)
SD_RESULT SD_SetCLK(SD_CLK CLK);
#endif
SD_RESULT SD_Status(void);
SD_RESULT SD_GetCID(u8 *cid_data); // read sd card CID
SD_RESULT SD_GetCSD(u8 *csd_data); // read sd card CSD
SD_RESULT SD_GetCapacity(u32* sector_count); // read sd card Capacity
SD_RESULT SD_ReadBlocks(u32 sector,u8 *data,u32 count); //read multi sector
SD_RESULT SD_WriteBlocks(u32 sector,const u8 *data,u32 count); //write multi sector
#endif
#endif

View file

@ -0,0 +1,224 @@
/**
* @file sd_spi.h
* @author Lvehe
* @version V1.0
* @date 2015-10-08
* @brief This file contains all the functions prototypes for the sd_spi.c
* firmware driver.
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef SD_SPI_H
#define SD_SPI_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "diskio.h"
#include "hal_platform.h"
//根据SPI时钟频率作相应修改
#define INIT_RETRY_MAX 400000
#define READ_BLOCK_MAX 200000 //200ms
#define WAIT_READY_MAX 500000 //500ms
/* ---------------------------------------------------------------------------*/
typedef enum
{
SD_TYPE_UNKNOW,
SD_TYPE_MMC3,
SD_TYPE_SDV1,
SD_TYPE_SDV2,
SD_TYPE_SDHC,
} SD_Type;
typedef enum
{
/**
* @brief SD reponses and error flags
*/
SD_RESPONSE_NO_ERROR = (0x00),
SD_IN_IDLE_STATE = (0x01),
SD_ERASE_RESET = (0x02),
SD_ILLEGAL_COMMAND = (0x04),
SD_COM_CRC_ERROR = (0x08),
SD_ERASE_SEQUENCE_ERROR = (0x10),
SD_ADDRESS_ERROR = (0x20),
SD_PARAMETER_ERROR = (0x40),
SD_RESPONSE_FAILURE = (0xFF),
/**
* @brief Data response error
*/
SD_DATA_OK = (0x05),
SD_DATA_CRC_ERROR = (0x0B),
SD_DATA_WRITE_ERROR = (0x0D),
SD_DATA_OTHER_ERROR = (0xFF)
} SD_Error;
/**
* @brief Card Specific Data: CSD Register
*/
typedef struct
{
__IO uint8_t CSDStruct; /*!< CSD structure */
__IO uint8_t SysSpecVersion; /*!< System specification version */
__IO uint8_t Reserved1; /*!< Reserved */
__IO uint8_t TAAC; /*!< Data read access-time 1 */
__IO uint8_t NSAC; /*!< Data read access-time 2 in CLK cycles */
__IO uint8_t MaxBusClkFrec; /*!< Max. bus clock frequency */
__IO uint16_t CardComdClasses; /*!< Card command classes */
__IO uint8_t RdBlockLen; /*!< Max. read data block length */
__IO uint8_t PartBlockRead; /*!< Partial blocks for read allowed */
__IO uint8_t WrBlockMisalign; /*!< Write block misalignment */
__IO uint8_t RdBlockMisalign; /*!< Read block misalignment */
__IO uint8_t DSRImpl; /*!< DSR implemented */
__IO uint8_t Reserved2; /*!< Reserved */
__IO uint32_t DeviceSize; /*!< Device Size */
__IO uint8_t MaxRdCurrentVDDMin; /*!< Max. read current @ VDD min */
__IO uint8_t MaxRdCurrentVDDMax; /*!< Max. read current @ VDD max */
__IO uint8_t MaxWrCurrentVDDMin; /*!< Max. write current @ VDD min */
__IO uint8_t MaxWrCurrentVDDMax; /*!< Max. write current @ VDD max */
__IO uint8_t DeviceSizeMul; /*!< Device size multiplier */
__IO uint8_t EraseGrSize; /*!< Erase group size */
__IO uint8_t EraseGrMul; /*!< Erase group size multiplier */
__IO uint8_t WrProtectGrSize; /*!< Write protect group size */
__IO uint8_t WrProtectGrEnable; /*!< Write protect group enable */
__IO uint8_t ManDeflECC; /*!< Manufacturer default ECC */
__IO uint8_t WrSpeedFact; /*!< Write speed factor */
__IO uint8_t MaxWrBlockLen; /*!< Max. write data block length */
__IO uint8_t WriteBlockPaPartial; /*!< Partial blocks for write allowed */
__IO uint8_t Reserved3; /*!< Reserded */
__IO uint8_t ContentProtectAppli; /*!< Content protection application */
__IO uint8_t FileFormatGroup; /*!< File format group */
__IO uint8_t CopyFlag; /*!< Copy flag (OTP) */
__IO uint8_t PermWrProtect; /*!< Permanent write protection */
__IO uint8_t TempWrProtect; /*!< Temporary write protection */
__IO uint8_t FileFormat; /*!< File Format */
__IO uint8_t ECC; /*!< ECC code */
__IO uint8_t CSD_CRC; /*!< CSD CRC */
__IO uint8_t Reserved4; /*!< always 1*/
} SD_CSD;
/**
* @brief Card Identification Data: CID Register
*/
typedef struct
{
__IO uint8_t ManufacturerID; /*!< ManufacturerID */
__IO uint16_t OEM_AppliID; /*!< OEM/Application ID */
__IO uint32_t ProdName1; /*!< Product Name part1 */
__IO uint8_t ProdName2; /*!< Product Name part2*/
__IO uint8_t ProdRev; /*!< Product Revision */
__IO uint32_t ProdSN; /*!< Product Serial Number */
__IO uint8_t Reserved1; /*!< Reserved1 */
__IO uint16_t ManufactDate; /*!< Manufacturing Date */
__IO uint8_t CID_CRC; /*!< CID CRC */
__IO uint8_t Reserved2; /*!< always 1 */
} SD_CID;
/**
* @brief SD Card information
*/
typedef struct
{
SD_CSD CSD;
SD_CID CID;
uint64_t Capacity;
uint32_t BlockSize;
SD_Type Type;
DSTATUS Status;
} SD_CARDINFO;
/**
* @brief Block Size
*/
#define SD_BLOCK_SIZE 0x200
/**
* @brief Dummy byte
*/
#define SD_DUMMY_BYTE ((uint8_t)0xFF)
/**
* @brief Start Data tokens:
* Tokens (necessary because at nop/idle (and CS active) only 0xff is
* on the data/command line)
*/
#define SD_START_DATA_SINGLE_BLOCK_READ 0xFE /*!< Data token start byte, Start Single Block Read */
#define SD_START_DATA_MULTIPLE_BLOCK_READ 0xFE /*!< Data token start byte, Start Multiple Block Read */
#define SD_START_DATA_SINGLE_BLOCK_WRITE 0xFE /*!< Data token start byte, Start Single Block Write */
#define SD_START_DATA_MULTIPLE_BLOCK_WRITE 0xFC /*!< Data token start byte, Start Multiple Block Write */
#define SD_STOP_DATA_MULTIPLE_BLOCK_WRITE 0xFD /*!< Data toke stop byte, Stop Multiple Block Write */
/**
* @brief SD detection on its memory slot
*/
#define SD_PRESENT ((uint8_t)0x01)
#define SD_NOT_PRESENT ((uint8_t)0x00)
/**
* @brief Commands: CMDxx = CMD-number | 0x40
*/
#define SD_CMD_GO_IDLE_STATE 0 /*!< CMD0 = 0x40 */
#define SD_CMD_SEND_OP_COND 1 /*!< CMD1 = 0x41 */
#define SD_CMD_IF_COND 8 /*!< CMD8 = 0x48 */
#define SD_CMD_SEND_CSD 9 /*!< CMD9 = 0x49 */
#define SD_CMD_SEND_CID 10 /*!< CMD10 = 0x4A */
#define SD_CMD_STOP_TRANSMISSION 12 /*!< CMD12 = 0x4C */
#define SD_CMD_SEND_STATUS 13 /*!< CMD13 = 0x4D */
#define SD_CMD_SET_BLOCKLEN 16 /*!< CMD16 = 0x50 */
#define SD_CMD_READ_SINGLE_BLOCK 17 /*!< CMD17 = 0x51 */
#define SD_CMD_READ_MULTIPLE_BLOCK 18 /*!< CMD18 = 0x52 */
#define SD_CMD_SEND_NUM_WR_BLOCKS 22 /*!< CMD22 = 0x56 */
#define SD_CMD_SET_BLOCK_COUNT 23 /*!< CMD23 = 0x57 */
#define SD_CMD_WRITE_SINGLE_BLOCK 24 /*!< CMD24 = 0x58 */
#define SD_CMD_WRITE_MULTIPLE_BLOCK 25 /*!< CMD25 = 0x59 */
#define SD_CMD_PROG_CSD 27 /*!< CMD27 = 0x5B */
#define SD_CMD_SET_WRITE_PROT 28 /*!< CMD28 = 0x5C */
#define SD_CMD_CLR_WRITE_PROT 29 /*!< CMD29 = 0x5D */
#define SD_CMD_SEND_WRITE_PROT 30 /*!< CMD30 = 0x5E */
#define SD_CMD_SD_ERASE_GRP_START 32 /*!< CMD32 = 0x60 */
#define SD_CMD_SD_ERASE_GRP_END 33 /*!< CMD33 = 0x61 */
#define SD_CMD_UNTAG_SECTOR 34 /*!< CMD34 = 0x62 */
#define SD_CMD_ERASE_GRP_START 35 /*!< CMD35 = 0x63 */
#define SD_CMD_ERASE_GRP_END 36 /*!< CMD36 = 0x64 */
#define SD_CMD_UNTAG_ERASE_GROUP 37 /*!< CMD37 = 0x65 */
#define SD_CMD_ERASE 38 /*!< CMD38 = 0x66 */
//------------------------------------------------------------
#define SD_CMD_SET_CLR_CARD_DETECT 42 /*!< ACMD42= 0x6A */
#define SD_CMD_APP_CMD 55 /*!< CMD55 = 0x77 */
#define SD_CMD_READ_OCR 58 /*!< CMD58 = 0x7A */
#define SD_CMD_CRC_ON_OFF 59 /*!< CMD59 = 0x7B */
extern SD_CARDINFO SD_CardInfo;
void SPI_SD_PowerOn(void);
void SPI_SD_PowerOff(void);
void SPI_SD_Detect_Init(void);
void SPI_SD_SpeedSet(uint32_t speed);
uint8_t SPI_SD_Detect(void);
void SPI_SD_DeInit(void);
SD_Error SPI_SD_Init(void);
SD_Error SPI_SD_GetCardInfo(SD_CARDINFO *CardInfo);
SD_Error SPI_SD_ReadBlock(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t BlockSize);
SD_Error SPI_SD_ReadMultiBlocks(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t BlockSize, uint32_t NumberOfBlocks);
SD_Error SPI_SD_WriteBlock(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t BlockSize);
SD_Error SPI_SD_WriteMultiBlocks(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t BlockSize, uint32_t NumberOfBlocks);
SD_Error SPI_SD_GetCSDRegister(SD_CSD* sd_csd);
SD_Error SPI_SD_GetCIDRegister(SD_CID* sd_cid);
uint16_t SPI_SD_GetStatus(void);
#ifdef __cplusplus
}
#endif
#endif /* SD_SPI_H */

View file

@ -0,0 +1,35 @@
#ifndef _SDIO_COMMON_DRIVER
#define _SDIO_COMMON_DRIVER
#include "cmsis.h"
#include "hal_sdio_host.h"
#include "header8195b.h"
typedef uint32_t (*sdio_sd_init_combine_type)(hal_sdio_host_adapter_t *psdioh_adapter, sdioh_pin_sel_t pin_sel);
typedef uint32_t (*sdio_sd_read_combine_type)(hal_sdio_host_adapter_t *psdioh_adapter, u64 start_addr, u16 blk_cnt, u8 *rbuf_32align);//
#if defined(CONFIG_PLATFORM_8195BHP)
typedef uint32_t (*sdio_sd_write_combine_type)(hal_sdio_host_adapter_t *psdioh_adapter, u64 start_addr, u16 blk_cnt,u8 *rbuf_32align);
#else
typedef uint32_t (*sdio_sd_write_combine_type)(hal_sdio_host_adapter_t *psdioh_adapter, u64 start_addr, u16 blk_cnt,const u8 *rbuf_32align);
#endif
typedef void (*deinit_combine_type)(hal_sdio_host_adapter_t *psdioh_adapter);
typedef uint32_t (*sdio_sd_card_combine_type)(hal_sdio_host_adapter_t *psdioh_adapter);
typedef uint32_t (*hal_sdioh_speed_type) (hal_sdio_host_adapter_t *psdioh_adapter, u8 speed);
typedef uint32_t (*hal_sdioh_get_card_status_type) (hal_sdio_host_adapter_t *psdioh_adapter);
extern sdio_sd_init_combine_type sdio_sd_host_init_combine;
extern sdio_sd_read_combine_type sdio_sd_read_combine;
extern sdio_sd_write_combine_type sdio_sd_write_combine;
extern deinit_combine_type deinit_combine;
extern sdio_sd_card_combine_type sdio_sd_card_combine;
extern hal_sdioh_speed_type hal_sdioh_speed_combine;
extern hal_sdioh_get_card_status_type hal_sdioh_get_card_status_combine;
void sdio_driver_init(void);
#endif

View file

@ -0,0 +1,47 @@
#ifndef _SDIO_HOST_H
#define _SDIO_HOST_H
#include "basic_types.h"
#if defined(CONFIG_PLATFORM_8195A)
#include "rtl8195a_sdio_host.h"
#include "header8195b.h"
#endif
#if defined(CONFIG_PLATFORM_8195BHP)
#include "rtl8195bhp.h"
#include "rtl8195bhp_sdio_host.h"
#endif
typedef enum{
SDIO_INIT_NONE = -1,
SDIO_INIT_FAIL = 0,
SDIO_INIT_OK = 1,
SDIO_SD_NONE = 2,
SDIO_SD_INSERT = 3,
SDIO_SD_OK = 4,
}_sdio_init_s;
uint32_t sdio_init_host(hal_sdio_host_adapter_t *psdioh_adapter, sdioh_pin_sel_t pin_sel); // init sdio host interface
void sdio_deinit_host(hal_sdio_host_adapter_t *psdioh_adapter);
uint32_t sdio_sd_init(hal_sdio_host_adapter_t *psdioh_adapter); // init sd card through sdio
void sdio_sd_deinit(void); //de-init sd card through sdio
uint32_t sdio_sd_status(hal_sdio_host_adapter_t *psdioh_adapter);
u32 sdio_sd_getCapacity(void);
s8 sdio_sd_getProtection(void);
s8 sdio_sd_setProtection(bool protection);
s8 sdio_sd_getCSD(u8* CSD);
s8 sdio_sd_isReady();
#if defined(CONFIG_PLATFORM_8195A)
s8 sdio_sd_setClock(SD_CLK_FREQUENCY SDCLK);
u8 card_insert_status(void);
#endif
uint32_t sdio_read_blocks(hal_sdio_host_adapter_t *psdioh_adapter,u64 sector, u16 count, u8 *buffer);
uint32_t sdio_write_blocks(hal_sdio_host_adapter_t *psdioh_adapter,u64 sector, u16 count, const u8 *buffer);
#endif

View file

@ -0,0 +1,231 @@
/**
******************************************************************************
* @file rl6548.h
* @author
* @version V1.0.0
* @date 2018-12-12
* @brief This file contains all the functions prototypes for the audio codec firmware
* library.
******************************************************************************
* @attention
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*
* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
******************************************************************************
*/
#ifndef __RL6548_H__
#define __RL6548_H__
/** @addtogroup AmebaD_Periph_Driver
* @{
*/
/** @defgroup audio
* @brief audio driver modules
* @{
*/
/** @addtogroup audio
* @verbatim
*****************************************************************************************
* Introduction
*****************************************************************************************
* codec:
* - Support anti-pop function to reduce audible pop
* - Support AMIC-in, DMIC-in, Line-in and Line-out
* - Sample rate: 8/16/32/44.1/48/96 KHz
* - Sample bit: 16 bit, 24 bit, 8bit
* - Channel number: mono or stereo
* - Data format: I2S, Left justified, PCM mode A, PCM mode B, PCM mode A-N, PCM mode B-N
* - Gain Control in ADC and DAC Path
*
* audio SI:
* - Base Address: AUDIO_SI_DEV
* - can use to configure codec register
*
*****************************************************************************************
* How to use audio SI & codec API
*****************************************************************************************
* To use audio codec si, the following steps are mandatory:
*
* 1. Open audio codec clock and function using
* PLLx_Set(0, ENABLE); (x is 0 or 1)
* RCC_PeriphClockCmd(APBPeriph_AUDIOC, APBPeriph_AUDIOC_CLOCK, ENABLE);
* RCC_PeriphClockCmd(APBPeriph_SPORT, APBPeriph_SPORT_CLOCK, ENABLE);
*
* 2. AUDIO SI enable:
* AUDIO_SI_Cmd(ENABLE).
*
* 3. Write AUDIO Codec registers using:
* AUDIO_SI_WriteReg(address, data);
*
* 4. Read AUDIO Codec registers using:
* AUDIO_SI_ReadReg(address);
*
* @note Turn on AUDIO Codec register bank clock using:
* AUDIO_SI_ClkCmd(ENABLE);
*
* @note Turn off AUDIO Codec register bank clock using:
* AUDIO_SI_ClkCmd(DISABLE);
*
* To use audio codec si, the following steps are mandatory:
*
* 1. Codec initialize using
* CODEC_Init(sample_rate, word_len, mono_stereo, application);
*
* 2. Codec set volume using
* CODEC_SetVolume(vol_lch, vol_rch);
*
* 3. Codec get volume using
* CODEC_GetVolume(*vol);
*
* 4. Set codec ADC and DAC sample rate using
* CODEC_SetSr(sample_rate);
*
* 5. Set codec ADC gain using
* CODEC_SetAdcGain(ad_gain_left, ad_gain_right);
*
* 6. Set codec MIC_BIAS output voltage
* CODEC_SetMicBias(mic_bias);
*
* 7. Codec de-initialize using
* CODEC_DeInit(application);
*
* @note All other functions can be used separately to modify, if needed,
* a specific feature of the AUDIO
*****************************************************************************************
* @endverbatim
*/
/* Exported constants --------------------------------------------------------*/
/** @defgroup AUDIO_Exported_Constants AUDIO Exported Constants
* @{
*/
/** @defgroup CODEC_sample_rate AUDIO Codec Sample Rate
* @{
*/
#define SR_48K ((u32)0x00000000)
#define SR_96K ((u32)0x00000001)
#define SR_32K ((u32)0x00000003)
#define SR_16K ((u32)0x00000005)
#define SR_8K ((u32)0x00000007)
#define SR_44P1K ((u32)0x00000008)
#define SR_88P2K ((u32)0x00000009)
/**
* @}
*/
/** @defgroup CODEC_word_len AUDIO Codec Word Len
* @{
*/
#define WL_16 ((u32)0x00000000)
#define WL_24 ((u32)0x00000002)
#define WL_8 ((u32)0x00000003)
/**
* @}
*/
/** @defgroup CODEC_channel_mode AUDIO Codec Channel Mode
* @{
*/
#define CH_STEREO ((u32)0x00000000)
#define CH_MONO ((u32)0x00000001)
/**
* @}
*/
/** @defgroup CODEC_application_mode AUDIO CODEC Application Mode
* @{
*/
#define APP_AMIC_IN ((u32)0x00000001)
#define APP_DMIC_IN ((u32)0x00000002)
#define APP_LINE_IN ((u32)0x00000004)
#define APP_LINE_OUT ((u32)0x00000008)
#define APP_DAAD_LPBK ((u32)0x00000010)
/**
* @}
*/
/** @defgroup CODEC_mute_action AUDIO CODEC mute action per channel
* @{
*/
#define MUTE_DISABLE ((u32)0x00000000)
#define MUTE_ENABLE ((u32)0x00000001)
#define MUTE_NO_ACT ((u32)0x00000002)
/**
* @}
*/
/** @defgroup Codec_rx_channel_selection AUDIO CODEC Rx Channel Selection
* @{
*/
#define RX_CH_LR ((u32)0x00000000)
#define RX_CH_RL ((u32)0x00000001)
#define RX_CH_LL ((u32)0x00000002)
#define RX_CH_RR ((u32)0x00000003)
/**
* @}
*/
/**
* @}
*/
/** @defgroup AUDIO_Exported_Functions AUDIO Exported Functions
* @{
*/
/** @defgroup AUDIO_SI_functions
* @{
*/
void AUDIO_SI_Cmd(u8 new_state);
void AUDIO_SI_WriteReg(u32 address, u32 data);
u16 AUDIO_SI_ReadReg(u32 address);
void AUDIO_SI_ClkCmd(u8 new_state);
/**
* @}
*/
/** @defgroup AUDIO_codec_functions
* @{
*/
void CODEC_Init(u32 sample_rate, u32 word_len, u32 mono_stereo, u32 application);
void CODEC_SetVolume(u8 vol_lch, u8 vol_rch);
void CODEC_GetVolume(u16 *vol);
void CODEC_SetSr(u32 sample_rate);
void CODEC_SetAdcGain(u32 ad_gain_left, u32 ad_gain_right);
void CODEC_SetAmicBst(u32 amic_bst_left, u32 amic_bst_right);
void CODEC_SetDmicBst(u32 dmic_bst_left, u32 dmic_bst_right);
void CODEC_SetMicBias(u8 mic_bias);
void CODEC_MuteRecord(u32 mute_lch, u32 mute_rch);
void CODEC_MutePlay(u32 mute_lch, u32 mute_rch);
void CODEC_DeInit(u32 application);
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#endif
/******************* (C) COPYRIGHT 2018 Realtek Semiconductor *****END OF FILE****/

View file

@ -0,0 +1,64 @@
#ifndef _BT8761_H_
#define _BT8761_H_
#include <inttypes.h>
#define BT_EV_LE_AUTHEN_COMPLETE (1)
#define BT_EV_LINK_KEY_REQ (2)
#define BT_EV_APP_DATA (3)
#define BT_EV_APP_READ_IND (4)
typedef struct _bt_status_t {
uint8_t gap_init_state;
uint8_t gap_adv_sub_state;
uint8_t gap_adv_state;
uint8_t gap_conn_state;
uint8_t gap_scan_state;
uint8_t radio_state;
uint8_t spp_state;
} bt_status_t;
typedef struct _bt_addr_t {
uint8_t addr_type;
uint8_t bd_addr[6];
} bt_addr_t;
typedef struct _bt_link_key_req_t {
uint8_t bd_addr[6];
uint8_t remote_addr_type;
uint8_t key_type;
} bt_link_key_req_t;
typedef struct _bt_link_key_t {
uint8_t key_type;
uint8_t link_key[28];
} bt_link_key_t;
typedef struct _bt_link_info_t {
uint8_t valid;
uint8_t bd_addr[6];
uint8_t remote_addr_type;
bt_link_key_t ltk;
bt_link_key_t irk;
} bt_link_info_t;
#define BT8761_MAX_LINK_INFO_SIZE (4)
typedef struct _bt_link_table_t {
uint8_t tblname[10];
bt_link_info_t link_info[BT8761_MAX_LINK_INFO_SIZE];
} bt_link_table_t;
int bt8761_init(bt_link_table_t *tbl);
int bt8761_dl_patchcfg(uint8_t *patch, uint32_t patch_len);
int bt8761_read_bt_status(bt_status_t *bs);
int bt8761_ble_read_addr(bt_addr_t *addr);
int bt8761_set_adv_mode(uint8_t mode);
int bt8761_ble_adv_enable(uint8_t enable);
int bt8761_ble_set_name(char *name);
int bt8761_set_adv_data(uint8_t *data, uint8_t len);
int bt8761_hci_le_cmd_all_paired_device_info(bt_link_key_req_t *req);
int bt8761_hci_send_raw(uint16_t cmd, uint8_t *data, uint32_t len);
void bt8761_reg_event_listener( void (*callback)(uint32_t type, void *data, uint32_t len) );
#endif

View file

@ -0,0 +1,402 @@
#ifndef __USB_AUDIO_H
#define __USB_AUDIO_H
#include <platform_opts.h>
#ifdef CONFIG_USBD_AUDIO
#include "usb.h"
#include "usb_composite.h"
#include "usb_audio_8763.h"
#include "ameba_otg.h"
#define USBD_AUDIO_DEBUG 0
#if USBD_AUDIO_DEBUG
#define USBD_AUDIO_INFO(fmt, args...) printf("\n\r[ADC]%s: " fmt, __FUNCTION__, ## args)
#define USBD_AUDIO_WARN(fmt, args...) printf("\n\r[ADC]%s: " fmt, __FUNCTION__, ## args)
#define USBD_AUDIO_ERROR(fmt, args...) printf("\n\r[ADC]%s: " fmt, __FUNCTION__, ## args)
#define USBD_AUDIO_ENTER printf("\n\r[ADC]%s: =>", __FUNCTION__)
#define USBD_AUDIO_EXIT printf("\n\r[ADC]%s: <=", __FUNCTION__)
#define USBD_AUDIO_EXIT_ERR printf("\n\r[ADC]%s: ERR <=", __FUNCTION__)
#else
#define USBD_AUDIO_INFO(fmt, args...)
#define USBD_AUDIO_WARN(fmt, args...)
#define USBD_AUDIO_ERROR(fmt, args...)
#define USBD_AUDIO_ENTER
#define USBD_AUDIO_EXIT
#define USBD_AUDIO_EXIT_ERR
#endif
#define USB_ISO_OUT_ENDPOINT_ADDRESS 0x02
#define USB_ISO_IN_ENDPOINT_ADDRESS 0x81
struct usb_audio_control {
dwc_list_link_t list;
const char *name;
uint8_t type;
int data[5];
int (*set)(struct usb_audio_control *con, uint8_t cmd, int value);
int (*get)(struct usb_audio_control *con, uint8_t cmd);
};
struct usb_audio_control_selector {
dwc_list_link_t list;
dwc_list_link_t control;
uint8_t id;
const char *name;
uint8_t type;
struct usb_descriptor_header *desc;
};
#define UAC_VERSION_1 0x00
#define UAC_VERSION_2 0x20
/* A.2 Audio Interface Subclass Codes */
#define USB_SUBCLASS_AUDIOCONTROL 0x01
#define USB_SUBCLASS_AUDIOSTREAMING 0x02
#define USB_SUBCLASS_MIDISTREAMING 0x03
#define F_AUDIO_NUM_INTERFACES 2
/* A.5 Audio Class-Specific AC Interface Descriptor Subtypes */
#define UAC_HEADER 0x01
#define UAC_INPUT_TERMINAL 0x02
#define UAC_OUTPUT_TERMINAL 0x03
#define UAC_MIXER_UNIT 0x04
#define UAC_SELECTOR_UNIT 0x05
#define UAC_FEATURE_UNIT 0x06
#define UAC1_PROCESSING_UNIT 0x07
#define UAC1_EXTENSION_UNIT 0x08
/* A.6 Audio Class-Specific AS Interface Descriptor Subtypes */
#define UAC_AS_GENERAL 0x01
#define UAC_FORMAT_TYPE 0x02
#define UAC_FORMAT_SPECIFIC 0x03
/* A.7 Processing Unit Process Types */
#define UAC_PROCESS_UNDEFINED 0x00
#define UAC_PROCESS_UP_DOWNMIX 0x01
#define UAC_PROCESS_DOLBY_PROLOGIC 0x02
#define UAC_PROCESS_STEREO_EXTENDER 0x03
#define UAC_PROCESS_REVERB 0x04
#define UAC_PROCESS_CHORUS 0x05
#define UAC_PROCESS_DYN_RANGE_COMP 0x06
/* A.8 Audio Class-Specific Endpoint Descriptor Subtypes */
#define UAC_EP_GENERAL 0x01
/* A.9 Audio Class-Specific Request Codes */
#define UAC_SET_ 0x00
#define UAC_GET_ 0x80
#define UAC__CUR 0x1
#define UAC__MIN 0x2
#define UAC__MAX 0x3
#define UAC__RES 0x4
#define UAC__MEM 0x5
#define UAC_SET_CUR (UAC_SET_ | UAC__CUR)
#define UAC_GET_CUR (UAC_GET_ | UAC__CUR)
#define UAC_SET_MIN (UAC_SET_ | UAC__MIN)
#define UAC_GET_MIN (UAC_GET_ | UAC__MIN)
#define UAC_SET_MAX (UAC_SET_ | UAC__MAX)
#define UAC_GET_MAX (UAC_GET_ | UAC__MAX)
#define UAC_SET_RES (UAC_SET_ | UAC__RES)
#define UAC_GET_RES (UAC_GET_ | UAC__RES)
#define UAC_SET_MEM (UAC_SET_ | UAC__MEM)
#define UAC_GET_MEM (UAC_GET_ | UAC__MEM)
#define UAC_GET_STAT 0xff
/* A.10 Control Selector Codes */
/* A.10.1 Terminal Control Selectors */
#define UAC_TERM_COPY_PROTECT 0x01
/* A.10.2 Feature Unit Control Selectors */
#define UAC_FU_MUTE 0x01
#define UAC_FU_VOLUME 0x02
#define UAC_FU_BASS 0x03
#define UAC_FU_MID 0x04
#define UAC_FU_TREBLE 0x05
#define UAC_FU_GRAPHIC_EQUALIZER 0x06
#define UAC_FU_AUTOMATIC_GAIN 0x07
#define UAC_FU_DELAY 0x08
#define UAC_FU_BASS_BOOST 0x09
#define UAC_FU_LOUDNESS 0x0a
#define UAC_CONTROL_BIT(CS) (1 << ((CS) - 1))
/* A.10.3.1 Up/Down-mix Processing Unit Controls Selectors */
#define UAC_UD_ENABLE 0x01
#define UAC_UD_MODE_SELECT 0x02
/* A.10.3.2 Dolby Prologic (tm) Processing Unit Controls Selectors */
#define UAC_DP_ENABLE 0x01
#define UAC_DP_MODE_SELECT 0x02
/* A.10.3.3 3D Stereo Extender Processing Unit Control Selectors */
#define UAC_3D_ENABLE 0x01
#define UAC_3D_SPACE 0x02
/* A.10.3.4 Reverberation Processing Unit Control Selectors */
#define UAC_REVERB_ENABLE 0x01
#define UAC_REVERB_LEVEL 0x02
#define UAC_REVERB_TIME 0x03
#define UAC_REVERB_FEEDBACK 0x04
/* A.10.3.5 Chorus Processing Unit Control Selectors */
#define UAC_CHORUS_ENABLE 0x01
#define UAC_CHORUS_LEVEL 0x02
#define UAC_CHORUS_RATE 0x03
#define UAC_CHORUS_DEPTH 0x04
/* A.10.3.6 Dynamic Range Compressor Unit Control Selectors */
#define UAC_DCR_ENABLE 0x01
#define UAC_DCR_RATE 0x02
#define UAC_DCR_MAXAMPL 0x03
#define UAC_DCR_THRESHOLD 0x04
#define UAC_DCR_ATTACK_TIME 0x05
#define UAC_DCR_RELEASE_TIME 0x06
/* A.10.4 Extension Unit Control Selectors */
#define UAC_XU_ENABLE 0x01
/* MIDI - A.1 MS Class-Specific Interface Descriptor Subtypes */
#define UAC_MS_HEADER 0x01
#define UAC_MIDI_IN_JACK 0x02
#define UAC_MIDI_OUT_JACK 0x03
/* MIDI - A.1 MS Class-Specific Endpoint Descriptor Subtypes */
#define UAC_MS_GENERAL 0x01
/* Terminals - 2.1 USB Terminal Types */
#define UAC_TERMINAL_UNDEFINED 0x100
#define UAC_TERMINAL_STREAMING 0x101
#define UAC_TERMINAL_VENDOR_SPEC 0x1FF
#pragma pack(push)
#pragma pack(1)
/* Terminal Control Selectors */
/* 4.3.2 Class-Specific AC Interface Descriptor */
struct uac1_ac_header_descriptor {
uint8_t bLength; /* 8 + n */
uint8_t bDescriptorType; /* USB_DT_CS_INTERFACE */
uint8_t bDescriptorSubtype; /* UAC_MS_HEADER */
uint16_t bcdADC; /* 0x0100 */
uint16_t wTotalLength; /* includes Unit and Terminal desc. */
uint8_t bInCollection; /* n */
uint8_t baInterfaceNr[F_AUDIO_NUM_INTERFACES]; /* [n] */
} __attribute__((packed));
//#define AC_HEADER_COUNT 2
#define UAC_DT_AC_HEADER_SIZE(n) (8 + (n))
/* 4.3.2.1 Input Terminal Descriptor */
struct uac_input_terminal_descriptor {
uint8_t bLength; /* in bytes: 12 */
uint8_t bDescriptorType; /* CS_INTERFACE descriptor type */
uint8_t bDescriptorSubtype; /* INPUT_TERMINAL descriptor subtype */
uint8_t bTerminalID; /* Constant uniquely terminal ID */
uint16_t wTerminalType; /* USB Audio Terminal Types */
uint8_t bAssocTerminal; /* ID of the Output Terminal associated */
uint8_t bNrChannels; /* Number of logical output channels */
uint16_t wChannelConfig;
uint8_t iChannelNames;
uint8_t iTerminal;
} __attribute__((packed));
#define UAC_DT_INPUT_TERMINAL_SIZE 12
/* Terminals - 2.2 Input Terminal Types */
#define UAC_INPUT_TERMINAL_UNDEFINED 0x200
#define UAC_INPUT_TERMINAL_MICROPHONE 0x201
#define UAC_INPUT_TERMINAL_DESKTOP_MICROPHONE 0x202
#define UAC_INPUT_TERMINAL_PERSONAL_MICROPHONE 0x203
#define UAC_INPUT_TERMINAL_OMNI_DIR_MICROPHONE 0x204
#define UAC_INPUT_TERMINAL_MICROPHONE_ARRAY 0x205
#define UAC_INPUT_TERMINAL_PROC_MICROPHONE_ARRAY 0x206
/* Terminals - control selectors */
#define UAC_TERMINAL_CS_COPY_PROTECT_CONTROL 0x01
/* 4.3.2.2 Output Terminal Descriptor */
struct uac1_output_terminal_descriptor {
uint8_t bLength; /* in bytes: 9 */
uint8_t bDescriptorType; /* CS_INTERFACE descriptor type */
uint8_t bDescriptorSubtype; /* OUTPUT_TERMINAL descriptor subtype */
uint8_t bTerminalID; /* Constant uniquely terminal ID */
uint16_t wTerminalType; /* USB Audio Terminal Types */
uint8_t bAssocTerminal; /* ID of the Input Terminal associated */
uint8_t bSourceID; /* ID of the connected Unit or Terminal*/
uint8_t iTerminal;
} __attribute__((packed));
#define UAC_DT_OUTPUT_TERMINAL_SIZE 9
/* Terminals - 2.3 Output Terminal Types */
#define UAC_OUTPUT_TERMINAL_UNDEFINED 0x300
#define UAC_OUTPUT_TERMINAL_SPEAKER 0x301
#define UAC_OUTPUT_TERMINAL_HEADPHONES 0x302
#define UAC_OUTPUT_TERMINAL_HEAD_MOUNTED_DISPLAY_AUDIO 0x303
#define UAC_OUTPUT_TERMINAL_DESKTOP_SPEAKER 0x304
#define UAC_OUTPUT_TERMINAL_ROOM_SPEAKER 0x305
#define UAC_OUTPUT_TERMINAL_COMMUNICATION_SPEAKER 0x306
#define UAC_OUTPUT_TERMINAL_LOW_FREQ_EFFECTS_SPEAKER 0x307
/* Set bControlSize = 2 as default setting */
#define UAC_DT_FEATURE_UNIT_SIZE(ch) (7 + ((ch) + 1) * 2)
/* As above, but more useful for defining your own descriptors: */
//#define DECLARE_UAC_FEATURE_UNIT_DESCRIPTOR(ch)
#define DECLARE_UAC_FEATURE_UNIT_DESCRIPTOR 2
#define DECLARE_FEATURE_UNIY_CONTROL_SIZE 1
#define CHANNEL_CNT 2
struct uac_feature_unit_descriptor_2 {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bUnitID;
uint8_t bSourceID;
uint8_t bControlSize;//DECLARE_FEATURE_UNIY_CONTROL_SIZE
//uint16_t bmaControls[DECLARE_UAC_FEATURE_UNIT_DESCRIPTOR + 1];
uint8_t bmaControls[((DECLARE_FEATURE_UNIY_CONTROL_SIZE) * (2)) + 1];
uint8_t iFeature;
} __attribute__((packed));
struct uac_feature_unit_descriptor_1 {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bUnitID;
uint8_t bSourceID;
uint8_t bControlSize;//DECLARE_FEATURE_UNIY_CONTROL_SIZE
//uint16_t bmaControls[DECLARE_UAC_FEATURE_UNIT_DESCRIPTOR + 1];
uint8_t bmaControls[((DECLARE_FEATURE_UNIY_CONTROL_SIZE) * (1)) + 1];
uint8_t iFeature;
} __attribute__((packed));
struct uac_feature_unit_descriptor_0 {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bUnitID;
uint8_t bSourceID;
uint8_t bControlSize;//DECLARE_FEATURE_UNIY_CONTROL_SIZE
//uint16_t bmaControls[DECLARE_UAC_FEATURE_UNIT_DESCRIPTOR + 1];
uint8_t bmaControls[((DECLARE_FEATURE_UNIY_CONTROL_SIZE) * (0)) + 1];
uint8_t iFeature;
} __attribute__((packed));
/* 4.3.2.3 Mixer Unit Descriptor */
// fongpin modify
#define MIXER_UNIT_CONNECTED 2 // BBRRO DEFINE
struct uac_mixer_unit_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bUnitID;
uint8_t bNrInPins;
uint8_t baSourceID[MIXER_UNIT_CONNECTED];// modify
uint8_t bNrChannels;// add
uint16_t bmChannelConfig;//add
uint8_t iChannelNames;//add
uint8_t bmControls;// add
uint8_t iMixer;//add
} __attribute__((packed));
/* 4.3.2.4 Selector Unit Descriptor */
// fongpin modify
struct uac_selector_unit_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bUintID;
uint8_t bNrInPins;
uint8_t baSourceID;
uint8_t iSelector;
} __attribute__((packed));
/* 4.5.2 Class-Specific AS Interface Descriptor */
struct uac1_as_header_descriptor {
uint8_t bLength; /* in bytes: 7 */
uint8_t bDescriptorType; /* USB_DT_CS_INTERFACE */
uint8_t bDescriptorSubtype; /* AS_GENERAL */
uint8_t bTerminalLink; /* Terminal ID of connected Terminal */
uint8_t bDelay; /* Delay introduced by the data path */
uint16_t wFormatTag; /* The Audio Data Format */
} __attribute__((packed));
#define UAC_DT_AS_HEADER_SIZE 7
/* Formats - A.1.1 Audio Data Format Type I Codes */
#define UAC_FORMAT_TYPE_I_UNDEFINED 0x0
#define UAC_FORMAT_TYPE_I_PCM 0x1
#define UAC_FORMAT_TYPE_I_PCM8 0x2
#define UAC_FORMAT_TYPE_I_IEEE_FLOAT 0x3
#define UAC_FORMAT_TYPE_I_ALAW 0x4
#define UAC_FORMAT_TYPE_I_MULAW 0x5
struct uac_format_type_i_discrete_descriptor {
uint8_t bLength; /* in bytes: 8 + (ns * 3) */
uint8_t bDescriptorType; /* USB_DT_CS_INTERFACE */
uint8_t bDescriptorSubtype; /* FORMAT_TYPE */
uint8_t bFormatType; /* FORMAT_TYPE_1 */
uint8_t bNrChannels; /* physical channels in the stream */
uint8_t bSubframeSize; /* */
uint8_t bBitResolution;
uint8_t bSamFreqType;
uint8_t tSamFreq[3][3];
} __attribute__((packed));
/* Formats - A.2 Format Type Codes */
#define UAC_FORMAT_TYPE_UNDEFINED 0x0
#define UAC_FORMAT_TYPE_I 0x1
#define UAC_FORMAT_TYPE_II 0x2
#define UAC_FORMAT_TYPE_III 0x3
#define UAC_EXT_FORMAT_TYPE_I 0x81
#define UAC_EXT_FORMAT_TYPE_II 0x82
#define UAC_EXT_FORMAT_TYPE_III 0x83
struct uac_iso_endpoint_descriptor {
uint8_t bLength; /* in bytes: 7 */
uint8_t bDescriptorType; /* USB_DT_CS_ENDPOINT */
uint8_t bDescriptorSubtype; /* EP_GENERAL */
uint8_t bmAttributes;
uint8_t bLockDelayUnits;
uint16_t wLockDelay;
} __attribute__((packed));
#define UAC_ISO_ENDPOINT_DESC_SIZE 7
#define UAC_EP_CS_ATTR_SAMPLE_RATE 0x01
#define UAC_EP_CS_ATTR_PITCH_CONTROL 0x02
#define UAC_EP_CS_ATTR_FILL_MAX 0x80
/* status word format (3.7.1.1) */
#define UAC1_STATUS_TYPE_ORIG_MASK 0x0f
#define UAC1_STATUS_TYPE_ORIG_AUDIO_CONTROL_IF 0x0
#define UAC1_STATUS_TYPE_ORIG_AUDIO_STREAM_IF 0x1
#define UAC1_STATUS_TYPE_ORIG_AUDIO_STREAM_EP 0x2
#define UAC1_STATUS_TYPE_IRQ_PENDING (1 << 7)
#define UAC1_STATUS_TYPE_MEM_CHANGED (1 << 6)
struct uac1_status_word {
uint8_t bStatusType;
uint8_t bOriginator;
} __attribute__((packed));
#pragma pack(pop)
#endif // CONFIG_USBD_AUDIO
#endif // __USB_AUDIO_H

View file

@ -0,0 +1,60 @@
#ifndef __USB_AUDIO_8763_H
#define __USB_AUDIO_8763_H
#include <platform_opts.h>
#ifdef CONFIG_USBD_AUDIO
#define INPUT_TERMINAL_2CH_ID 0x01
#define INPUT_TERMINAL_MIC_ID 0x02
#define OUTPUT_TERMINAL_SPEAKER_ID 0x06
#define OUTPUT_TERMINAL_USB_ID 0x07
#define SELECTOR_UNIT_ID 0x08
#define FEATURE_UNIT_0_ID 0x09
#define FEATURE_UNIT_1_ID 0x0A
#define FEATURE_UNIT_2_ID 0x0D
#define MIXER_UNIT_2_ID 0x0F
#define AUDIO_CONTROL_INTF_NUM 0
#define AUDIO_STREAM_OUT_INTF_NUM 1
#define AUDIO_STREAM_IN_INTF_NUM 2
// 8763 PCM setting
#define BIT_RES_16 16
#define BIT_RES_24 24
#define DEFAULT_BIT_RES BIT_RES_16
#define ICODEC_SR_8K 0
#define ICODEC_SR_16K 1
#define ICODEC_SR_32K 2
#define ICODEC_SR_44K 3
#define ICODEC_SR_48K 4
#define ICODEC_SR_88K 5
#define ICODEC_SR_96K 6
#define ICODEC_SR_192K 7
#define DEFAULT_SR ICODEC_SR_48K
#define CHANNEL_MODE_1CH 0x01
#define CHANNEL_MODE_2CH 0x02
#define DEFAULT_PLAY_CH CHANNEL_MODE_2CH
#define DEFAULT_RECORD_CH CHANNEL_MODE_2CH //CHANNEL_MODE_1CH
typedef struct USB_DSP_STATE_ {
uint8_t usb_ad_state;
uint8_t usb_da_state;
} USB_DSP_STATE;
enum { DSP_STOP, DSP_START};
typedef struct USB_ISOEP_STATE_ {
uint8_t usb_OUTEP_state;
uint8_t usb_INEP_state;
} USB_ISOEP_STATE;
enum {ISOEP_DISABLE, ISOEP_ENABLE};
enum {IDX_DA = 1, IDX_AD = 2};
enum {L_GAIN = 1, R_GAIN = 2};
#endif // CONFIG_USBD_AUDIO
#endif // __USB_AUDIO_8763_H

View file

@ -0,0 +1,27 @@
#ifndef __USB_AUDIO_IF_H
#define __USB_AUDIO_IF_H
#include <platform_opts.h>
#ifdef CONFIG_USBD_AUDIO
#include <stdint.h>
#include <stdbool.h>
typedef struct {
void (* plug)(uint8_t audio_path, uint8_t bit_res, uint8_t sf, uint8_t chann_mode);
void (* unplug)(uint8_t audio_path);
bool (* put_data)(uint8_t *p_data, uint16_t len);
void (* set_gain)(uint8_t lr_chann, uint8_t gain);
bool (* pull_data)(uint8_t *p_data, uint16_t len);
int (* init)(void);
void (* deinit)(void);
} usbd_audio_usr_cb_t;
int usbd_audio_init(usbd_audio_usr_cb_t *cb);
void usbd_audio_deinit(void);
void usbd_audio_stop(void);
#endif // CONFIG_USBD_AUDIO
#endif // __USB_AUDIO_IF_H

View file

@ -0,0 +1,85 @@
/*
* u_uac1.h -- interface to USB gadget "ALSA AUDIO" utilities
*
* Copyright (C) 2008 Bryan Wu <cooloney@kernel.org>
* Copyright (C) 2008 Analog Devices, Inc
*
* Enter bugs at http://blackfin.uclinux.org/
*
* Licensed under the GPL-2 or later.
*/
#ifndef __U_AUDIO_H
#define __U_AUDIO_H
#include <platform_opts.h>
#ifdef CONFIG_USBD_AUDIO
#include "usb_composite.h"
#include "usb_audio_if.h"
#include "usb_audio.h"
#include "ameba_otg.h"
#define UAC1_OUT_EP_MAX_PACKET_SIZE 512
#define UAC1_REQ_COUNT 1
#define UAC1_AUDIO_BUF_SIZE 1024
#define SUPPORT_ISO_MAX_PACKET_SIZE 512 // for 19k2 *2 channel*16 bit
#define UAC1_ISO_OUT_EP_MAX_PACKET_SIZE 576 // must be 576 for 96K + 24-bit, ??? what about P & R ???
#define UAC1_ISO_IN_EP_MAX_PACKET_SIZE 288 // 492, Max Packet, or Play and Record Fail in Win7
#define UAC1_ISO_OUT_EP_MAX_BUFFER_SIZE 576 // 24 -> 32 ( 576 -> 768 )
#define UAC1_ISO_IN_EP_MAX_BUFFER_SIZE 288 // 32 -> 24 ( 384 -> 288 )
/*
* This represents the USB side of an audio card device, managed by a USB
* function which provides control and stream interfaces.
*/
struct gaudio_snd_dev {
struct gaudio *card;
//struct file *filp;
//struct snd_pcm_substream *substream;
int access;
int format;// bbpro: 0: 16bit, 1 : 24bit
int channels;// bbpro:
int rate;// ex 44100
int sample_freq_idx;// bbpro, map to rate
};
struct gaudio {
//struct usb_function func;
struct usb_gadget *gadget;
/* ALSA sound device interfaces */
struct gaudio_snd_dev control;
struct gaudio_snd_dev playback;
struct gaudio_snd_dev capture;
};
struct f_audio {
struct gaudio card;
//bbpro
uint8_t ac_intf;
uint8_t ac_alt;
uint8_t as_out_intf;
uint8_t as_out_alt;
uint8_t as_in_intf;
uint8_t as_in_alt;
/* endpoints handle full and/or high speeds */
struct usb_ep *out_ep;
struct usb_ep *in_ep;
dwc_list_link_t cs;
uint8_t set_cmd;
struct usb_audio_control *set_con;
//bbpro
struct usb_gadget *gadget;
};
#endif // CONFIG_USBD_AUDIO
#endif // __U_AUDIO_H

View file

@ -0,0 +1,228 @@
#ifndef _USBD_CDC_ACM_H_
#define _USBD_CDC_ACM_H_
#include <platform_opts.h>
#ifdef CONFIG_USBD_CDC_ACM
#include <platform/platform_stdlib.h>
#include "usb.h"
#include "usb_gadget.h"
#include "usb_composite.h"
#include "osdep_service.h"
#include "usbd_cdc_acm_if.h"
// Use INT in endpoint
#define USBD_CDC_ACM_USE_INT_IN_ENDPOINT 1
// Use thread for bulk in transfer, turn it on when using usbd_cdc_acm_async_transmit_data API to transfer large data,
// which can not be transfered via single bulk in transfer, i.e. the transfer size is larger than bulk_in_buf_size.
#define USBD_CDC_ACM_USE_BULK_IN_THREAD 1
// Allocate async bulk in buffer, turn it on to release bulk in transfer buffer in user application ASAP.
#define USBD_CDC_ACM_ALLOC_ASYNC_BULK_IN_BUF 0
// Bulk in request number
#define USBD_CDC_ACM_BULK_IN_REQ_NUM 2
// Bulk out request number
#define USBD_CDC_ACM_BULK_OUT_REQ_NUM 1
// Bulk transfer configurations
#define USBD_CDC_ACM_HS_BULK_MAX_PACKET_SIZE 512
#define USBD_CDC_ACM_FS_BULK_MAX_PACKET_SIZE 64
#define USBD_CDC_ACM_HS_BULK_IN_PACKET_SIZE (USBD_CDC_ACM_HS_BULK_MAX_PACKET_SIZE)
#define USBD_CDC_ACM_HS_BULK_OUT_PACKET_SIZE (USBD_CDC_ACM_HS_BULK_MAX_PACKET_SIZE)
#define USBD_CDC_ACM_FS_BULK_IN_PACKET_SIZE (USBD_CDC_ACM_FS_BULK_MAX_PACKET_SIZE)
#define USBD_CDC_ACM_FS_BULK_OUT_PACKET_SIZE (USBD_CDC_ACM_FS_BULK_MAX_PACKET_SIZE)
#define USBD_CDC_ACM_MAX_BULK_IN_XFER_SIZE 65535
#define USBD_CDC_ACM_DEFAULT_BULK_IN_XFER_SIZE 1024 // Shall be <= USBD_CDC_ACM_MAX_BULK_IN_XFER_SIZE, restrict it to save memory
#define USBD_CDC_ACM_DEFAULT_BULK_OUT_XFER_SIZE 1024 // Shall be <= USBD_CDC_ACM_MAX_BULK_IN_XFER_SIZE, restrict it to save memory
// Bulk in task configurations
#define USBD_CDC_ACM_BULK_IN_TASK_PRIORITY (tskIDLE_PRIORITY + 2) // Should be lower than USBD_IRQ_THREAD_PRIORITY
#define USBD_CDC_ACM_BULK_IN_TASK_STACK_SIZE 512
// Endpoint address
#define USBD_CDC_ACM_BULK_IN_EP_ADDRESS 0x81
#define USBD_CDC_ACM_BULK_OUT_EP_ADDRESS 0x02
#define USBD_CDC_ACM_INT_IN_EP_ADDRESS 0x83
// CDC descriptor types
#define USBD_CDC_HEADER_TYPE 0x00
#define USBD_CDC_CALL_MANAGEMENT_TYPE 0x01
#define USBD_CDC_ACM_TYPE 0x02
#define USBD_CDC_UNION_TYPE 0x06
#define USBD_CDC_COUNTRY_TYPE 0x07
#define USBD_CDC_NETWORK_TERMINAL_TYPE 0x0A
#define USBD_CDC_ETHERNET_TYPE 0x0F
#define USBD_CDC_WHCM_TYPE 0x11
#define USBD_CDC_MDLM_TYPE 0x12
#define USBD_CDC_MDLM_DETAIL_TYPE 0x13
#define USBD_CDC_DMM_TYPE 0x14
#define USBD_CDC_OBEX_TYPE 0x15
// CDC subclass
#define USBD_CDC_SUBCLASS_ACM 0x02
#define USBD_CDC_SUBCLASS_ETHERNET 0x06
#define USBD_CDC_SUBCLASS_WHCM 0x08
#define USBD_CDC_SUBCLASS_DMM 0x09
#define USBD_CDC_SUBCLASS_MDLM 0x0A
#define USBD_CDC_SUBCLASS_OBEX 0x0B
// CDC ACM protocol
#define USBD_CDC_ACM_PROTO_NONE 0x00
#define USBD_CDC_ACM_PROTO_AT 0x01
#define USBD_CDC_ACM_PROTO_VENDOR 0xFF
// CDC ACM requests
#define USBD_CDC_SEND_ENCAPSULATED_COMMAND 0x00U
#define USBD_CDC_GET_ENCAPSULATED_RESPONSE 0x01U
#define USBD_CDC_SET_COMM_FEATURE 0x02U
#define USBD_CDC_GET_COMM_FEATURE 0x03U
#define USBD_CDC_CLEAR_COMM_FEATURE 0x04U
#define USBD_CDC_SET_LINE_CODING 0x20U
#define USBD_CDC_GET_LINE_CODING 0x21U
#define USBD_CDC_SET_CONTROL_LINE_STATE 0x22U
#define USBD_CDC_SEND_BREAK 0x23U
// CDC ACM debug options
#define USBD_CDC_ACM_DEBUG 0
#if USBD_CDC_ACM_DEBUG
#define USBD_CDC_INFO(fmt, args...) printf("\n\r[CDC]%s: " fmt, __FUNCTION__, ## args)
#define USBD_CDC_WARN(fmt, args...) printf("\n\r[CDC]%s: " fmt, __FUNCTION__, ## args)
#define USBD_CDC_ERROR(fmt, args...) printf("\n\r[CDC]%s: " fmt, __FUNCTION__, ## args)
#define USBD_CDC_ENTER printf("\n\r[CDC]%s: =>", __FUNCTION__)
#define USBD_CDC_EXIT printf("\n\r[CDC]%s: <=", __FUNCTION__)
#define USBD_CDC_EXIT_ERR printf("\n\r[CDC]%s: ERR <=", __FUNCTION__)
#else
#define USBD_CDC_INFO(fmt, args...)
#define USBD_CDC_WARN(fmt, args...)
#define USBD_CDC_ERROR(fmt, args...) printf("\n\r[CDC]%s: " fmt, __FUNCTION__, ## args)
#define USBD_CDC_ENTER
#define USBD_CDC_EXIT
#define USBD_CDC_EXIT_ERR
#endif
#pragma pack(push)
#pragma pack(1)
// Header Functional Descriptor
struct usb_cdc_header_desc {
u8 bLength;
u8 bDescriptorType;
u8 bDescriptorSubType;
u16 bcdCDC;
} __attribute__((packed));
#define USBD_CDC_DT_HEADER_SIZE 5
// Call Management Descriptor
struct usb_cdc_call_mgmt_descriptor {
u8 bLength;
u8 bDescriptorType;
u8 bDescriptorSubType;
u8 bmCapabilities;
#define USB_CDC_CALL_MGMT_CAP_CALL_MGMT 0x01
#define USB_CDC_CALL_MGMT_CAP_DATA_INTF 0x02
u8 bDataInterface;
} __attribute__((packed));
#define USBD_CDC_DT_CALL_MGMT_SIZE 5
// Abstract Control Management Descriptor
struct usb_cdc_acm_descriptor {
u8 bLength;
u8 bDescriptorType;
u8 bDescriptorSubType;
u8 bmCapabilities;
} __attribute__((packed));
#define USBD_CDC_DT_ACM_SIZE 4
// Union Functional Descriptor
struct usb_cdc_union_desc {
u8 bLength;
u8 bDescriptorType;
u8 bDescriptorSubType;
u8 bControlInterface;
u8 bSubordinateInterface0;
} __attribute__((packed));
#define USBD_CDC_DT_UNION_SIZE 5
typedef struct {
u32 dwDTERate;
u8 bCharFormat;
u8 bParityType;
u8 bDataBits;
} __attribute__((packed)) usbd_cdc_acm_line_coding_t;
#define USBD_CDC_ACM_LINE_CODING_SIZE 7
#define USBD_CDC_ACM_CHAR_FORMAT_STOP_1 0
#define USBD_CDC_ACM_CHAR_FORMAT_STOP_1_5 1
#define USBD_CDC_ACM_CHAR_FORMAT_STOP_2 2
#define USBD_CDC_ACM_PARITY_TYPE_NONE 0
#define USBD_CDC_ACM_PARITY_TYPE_ODD 1
#define USBD_CDC_ACM_PARITY_TYPE_EVEN 2
#define USBD_CDC_ACM_PARITY_TYPE_MARK 3
#define USBD_CDC_ACM_PARITY_TYPE_SPACE 4
#define USBD_CDC_ACM_DATA_BIT_5 5
#define USBD_CDC_ACM_DATA_BIT_6 6
#define USBD_CDC_ACM_DATA_BIT_7 7
#define USBD_CDC_ACM_DATA_BIT_8 8
#define USBD_CDC_ACM_DATA_BIT_16 16
typedef union {
u16 d16;
struct {
unsigned present:1;
unsigned activate:1;
unsigned reserved_2_15:14;
} b;
} __attribute__((packed)) usbd_cdc_acm_ctrl_line_state_t;
#pragma pack(pop)
struct usb_cdc_dev_t {
u8 interface_number;
struct usb_gadget *gadget;
struct usb_ep *bulk_out_ep;
_list bulk_out_req_list;
u16 bulk_out_req_num;
volatile u16 bulk_out_req_act_num;
u16 bulk_out_buf_size;
_mutex bulk_out_mutex;
struct usb_ep *bulk_in_ep;
_list bulk_in_req_list;
u16 bulk_in_req_num;
volatile u16 bulk_in_req_act_num;
u16 bulk_in_buf_size;
_mutex bulk_in_mutex;
volatile int bulk_in_busy;
#if USBD_CDC_ACM_USE_BULK_IN_THREAD
struct task_struct bulk_in_task;
#endif
usbd_cdc_acm_usr_cb_t *cb;
};
#endif // CONFIG_USBD_CDC_ACM
#endif // _USBD_CDC_ACM_H_

View file

@ -0,0 +1,24 @@
#ifndef _USBD_CDC_ACM_IF_H_
#define _USBD_CDC_ACM_IF_H_
#include <platform_opts.h>
#ifdef CONFIG_USBD_CDC_ACM
typedef struct {
int(* init)(void);
int(* deinit)(void);
int(* receive)(void *buf, u16 length);
void(*transmit_complete)(int status);
} usbd_cdc_acm_usr_cb_t;
int usbd_cdc_acm_sync_transmit_data(void *buf, u16 length);
int usbd_cdc_acm_async_transmit_data(void *buf, u32 length);
int usbd_cdc_acm_init(u16 bulk_in_buf_size, u16 bulk_out_buf_size, usbd_cdc_acm_usr_cb_t *cb);
void usbd_cdc_acm_deinit(void);
#endif // CONFIG_USBD_CDC_ACM
#endif // _USBD_CDC_ACM_IF_H_

View file

@ -0,0 +1,208 @@
#ifndef USBD_MSC_H
#define USBD_MSC_H
#include <platform_opts.h>
#ifdef CONFIG_USBD_MSC
#include <platform/platform_stdlib.h>
#include "usb.h"
#include "usb_composite.h"
#include "osdep_service.h"
#include "sd.h"
/* MSC configurations */
#define USBD_MSC_RAM_DISK 0 /* Use RAM as storage media, for test purpose only */
/* MSC Request Codes */
#define USBD_MSC_REQUEST_RESET 0xFF
#define USBD_MSC_REQUEST_GET_MAX_LUN 0xFE
#define USBD_MSC_MAX_LUN 1
#define USBD_MSC_MAX_SCSI_CMD_SIZE 16
#define USBD_MSC_BLK_BITS 9
#define USBD_MSC_BLK_SIZE (1 << USBD_MSC_BLK_BITS)
/* MSC Sub Classes */
#define USBD_MSC_SC_RBC 1 /* Typically, flash devices */
#define USBD_MSC_SC_8020 2 /* CD-ROM */
#define USBD_MSC_SC_QIC 3 /* QIC-157 Tapes */
#define USBD_MSC_SC_UFI 4 /* Floppy */
#define USBD_MSC_SC_8070 5 /* Removable media */
#define USBD_MSC_SC_SCSI 6 /* Transparent */
/* MSC Protocols */
#define USBD_MSC_PR_CB 1 /* Control/Bulk w/o interrupt */
#define USBD_MSC_PR_CBI 0 /* Control/Bulk/Interrupt */
#define USBD_MSC_PR_BULK 0x50 /* bulk only */
#define USBD_MSC_BULK_OUT_EP_ADDRESS 0x02
#define USBD_MSC_BULK_IN_EP_ADDRESS 0x81
/* MSC thread priority*/
#define USBD_MSC_BULK_CMD_THREAD_PRIORITY (tskIDLE_PRIORITY + 3) // Should be lower than USBD_IRQ_THREAD_PRIORITY
/* MSC device buffer configuration */
#define USBD_MSC_NBR_BUFHD 2 /* Number of buffer header for bulk in/out data */
#define USBD_MSC_BUFLEN (32*512) /* Default size of buffer length */
/* MSC tasks stack size */
#define USBD_MSC_BULK_CMD_TASK_STACK_SIZE 512
#define USBD_MSC_BULK_DATA_TASK_STACK_SIZE 512
#define USBD_MSC_HALT_ERROR_TOLERANCE 20
/* RAM disk configurations */
#if USBD_MSC_RAM_DISK
#define USBD_MSC_RAM_DISK_SIZE (USBD_MSC_BUFLEN * 2) // Should be >= 32KB
#define USBD_MSC_RAM_DISK_SECTORS (USBD_MSC_RAM_DISK_SIZE >> USBD_MSC_BLK_BITS)
#endif
/* Debug options */
#define USBD_MSC_DEBUG 0
#if USBD_MSC_DEBUG
#define USBD_MSC_INFO(fmt, args...) printf("\n\r[MSC]%s: " fmt, __FUNCTION__, ## args)
#define USBD_MSC_WARN(fmt, args...) printf("\n\r[MSC]%s: " fmt, __FUNCTION__, ## args)
#define USBD_MSC_ERROR(fmt, args...) printf("\n\r[MSC]%s: " fmt, __FUNCTION__, ## args)
#define USBD_MSC_ENTER printf("\n\r[MSC]%s: =>", __FUNCTION__)
#define USBD_MSC_EXIT printf("\n\r[MSC]%s: <=", __FUNCTION__)
#define USBD_MSC_EXIT_ERR printf("\n\r[MSC]%s: ERR <=", __FUNCTION__)
#else
#define USBD_MSC_INFO(fmt, args...)
#define USBD_MSC_WARN(fmt, args...)
#define USBD_MSC_ERROR(fmt, args...)
#define USBD_MSC_ENTER
#define USBD_MSC_EXIT
#define USBD_MSC_EXIT_ERR
#endif
enum data_direction {
DATA_DIR_UNKNOWN = 0,
DATA_DIR_FROM_HOST,
DATA_DIR_TO_HOST,
DATA_DIR_NONE
};
//structure predefine
struct usb_msc_dev_t;
struct usb_msc_bufhd_t;
struct usb_msc_opts_t {
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);
};
struct usb_msc_lun_t {
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;
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;
unsigned int lba; /* current read and write logical block address */
u8 is_open;
_mutex lun_mutex;
struct usb_msc_opts_t *lun_opts;
};
struct usb_msc_common_t {
struct usb_msc_dev_t *mscdev;
struct usb_msc_lun_t **luns;
struct usb_msc_lun_t *curlun;
struct usb_gadget *gadget;
/* scsi cbw relevant */
enum data_direction data_dir;
u32 data_size;
u32 data_size_from_cmnd;
u32 tag;
u32 residue;
u8 scsi_cmnd[USBD_MSC_MAX_SCSI_CMD_SIZE];
u8 cmnd_size;
u8 lun; /* current lun*/
u8 nluns;
u8 nbufhd; /* number of buffer header */
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 usb_msc_bufhd_t *curbh; // current buffer header
struct usb_msc_bufhd_t *cbw_bh; // buffer header for CBW
struct usb_msc_bufhd_t *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,
} usb_msc_bufhd_type;
struct usb_msc_bufhd_t {
u8 *prebuf;
u8 *buf;
int buf_size;
usb_msc_bufhd_type type;
_list list;
struct usb_request *reqin; /* for bulkin responses */
struct usb_request *reqout;
};
struct usb_msc_dev_t {
struct usb_msc_common_t *common;
u16 interface_number;
struct usb_ep *in_ep;
struct usb_ep *out_ep;
unsigned int bulk_in_enabled: 1;
unsigned int bulk_out_enabled: 1;
struct task_struct bulk_out_cmd_task;
};
int usbd_msc_lun_read(struct usb_msc_lun_t *curlun, u32 sector, u8 *buffer, u32 count);
int usbd_msc_lun_write(struct usb_msc_lun_t *curlun, u32 sector, const u8 *buffer, u32 count);
int usbd_msc_halt_bulk_in_endpoint(struct usb_msc_dev_t *mscdev);
void usbd_msc_put_bufhd(struct usb_msc_common_t *common, struct usb_msc_bufhd_t *bufhd);
struct usb_msc_bufhd_t *usbd_msc_get_bufhd(struct usb_msc_common_t *common);
int usbd_msc_bulk_in_transfer(struct usb_msc_dev_t *mscdev, struct usb_request *req);
int usbd_msc_bulk_out_transfer(struct usb_msc_dev_t *mscdev, struct usb_request *req);
#endif // CONFIG_USBD_MSC
#endif // USBD_MSC_H

View file

@ -0,0 +1,16 @@
#ifndef USBD_MSC_IF_H
#define USBD_MSC_IF_H
#include <platform_opts.h>
#ifdef CONFIG_USBD_MSC
#include <stdint.h>
//int usbd_msc_register(void);
int usbd_msc_init(void);
void usbd_msc_deinit(void);
#endif // CONFIG_USBD_MSC
#endif // USBD_MSC_H

View file

@ -0,0 +1,110 @@
#ifndef USBD_SCSI_H
#define USBD_SCSI_H
#include <platform_opts.h>
#ifdef CONFIG_USBD_MSC
#include "basic_types.h"
#include "usbd_msc.h"
/* 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[USBD_MSC_MAX_SCSI_CMD_SIZE]; /* 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
int usbd_msc_receive_cbw(struct usb_msc_dev_t *mscdev, struct usb_request *req);
#endif // CONFIG_USBD_MSC
#endif // USBD_SCSI_H

View file

@ -0,0 +1,91 @@
#ifndef USBD_VENDOR_H
#define USBD_VENDOR_H
#include <platform_opts.h>
#ifdef CONFIG_USBD_VENDOR
#include "usb.h"
#include "usb_composite.h"
// Test options
#define CONFIG_USBD_VENDOR_ISO_IN_TEST 1
#define CONFIG_USBD_VENDOR_ISO_OUT_TEST 1
#define CONFIG_USBD_VENDOR_ISO_INOUT_TEST 0
#define CONFIG_USBD_VENDOR_BULK_INOUT_TEST 0
#define CONFIG_USBD_VENDOR_ISO_IN_REQ_ASAP 1
#define CONFIG_USBD_VENDOR_ISO_OUT_REQ_ASAP 0
#define CONFIG_USBD_VENDOR_ISO_DBG_TIMER 1
#define CONFIG_USBD_VENDOR_ISO_DBG_GPIO 0
#define USBD_VENDOR_ISO_REQ_NUM 2
#define USBD_VENDOR_ISO_OUT_XFER_CNT 100
#define USBD_VENDOR_ISO_IN_CNT 512
/* Debug options */
#define USBD_VENDOR_DEBUG 0
#define USBD_VENDOR_STR "VS"
#if USBD_VENDOR_DEBUG
#define USBD_VENDOR_INFO(fmt, args...) printf("\n\r[%s]%s: " fmt, USBD_VENDOR_STR, __FUNCTION__, ## args)
#define USBD_VENDOR_WARN(fmt, args...) printf("\n\r[%s]%s: " fmt, USBD_VENDOR_STR, __FUNCTION__, ## args)
#define USBD_VENDOR_ERROR(fmt, args...) printf("\n\r[%s]%s: " fmt, USBD_VENDOR_STR, __FUNCTION__, ## args)
#define USBD_VENDOR_ENTER printf("\n\r[%s]%s: =>", USBD_VENDOR_STR, __FUNCTION__)
#define USBD_VENDOR_EXIT printf("\n\r[%s]%s: <=", USBD_VENDOR_STR, __FUNCTION__)
#define USBD_VENDOR_EXIT_ERR printf("\n\r[%s]%s: ERR <=", USBD_VENDOR_STR, __FUNCTION__)
#else
#define USBD_VENDOR_INFO(fmt, args...)
#define USBD_VENDOR_WARN(fmt, args...)
#define USBD_VENDOR_ERROR(fmt, args...) printf("\n\r[%s]%s: " fmt, USBD_VENDOR_STR, __FUNCTION__, ## args)
#define USBD_VENDOR_ENTER
#define USBD_VENDOR_EXIT
#define USBD_VENDOR_EXIT_ERR
#endif
struct usb_vendor_common_t;
struct usb_vendor_device_t;
struct usb_vendor_common_t {
struct usb_vendor_device_t *vendev;
struct usb_gadget *gadget;
struct usb_ep *ep0;
struct usb_request *req0;
};
struct usb_vendor_device_t {
struct usb_vendor_common_t *common;
struct usb_function func;
struct usb_ep *bulk_in_ep;
struct usb_ep *bulk_out_ep;
struct usb_ep *iso_in_ep;
struct usb_ep *iso_out_ep;
struct usb_iso_request *iso_out_req;
u8 *iso_out_req_buf[USBD_VENDOR_ISO_REQ_NUM];
struct usb_iso_request *iso_in_req;
u8 *iso_in_req_buf[USBD_VENDOR_ISO_REQ_NUM];
};
typedef struct {
u8 pos;
u8 data;
} usb_vendor_iso_out_record_t;
extern struct usb_gadget_strings *vendor_gadget_strings[];
extern struct usb_device_descriptor vendor_device_desc;
extern struct usb_config_descriptor vendor_config_desc;
extern struct usb_interface_descriptor vendor_intf0_desc;
extern struct usb_interface_descriptor vendor_intf1_desc;
extern struct usb_endpoint_descriptor vendor_bulk_source_desc_FS;
extern struct usb_endpoint_descriptor vendor_bulk_sink_desc_FS;
extern struct usb_endpoint_descriptor vendor_bulk_source_desc_HS;
extern struct usb_endpoint_descriptor vendor_bulk_sink_desc_HS;
extern struct usb_endpoint_descriptor vendor_iso_source_desc_FS;
extern struct usb_endpoint_descriptor vendor_iso_sink_desc_FS;
extern struct usb_endpoint_descriptor vendor_iso_source_desc_HS;
extern struct usb_endpoint_descriptor vendor_iso_sink_desc_HS;
extern struct usb_descriptor_header *vendor_descriptors_FS[];
extern struct usb_descriptor_header *vendor_descriptors_HS[];
#endif // CONFIG_USBD_VENDOR
#endif // USBD_VENDOR_H

View file

@ -0,0 +1,14 @@
#ifndef USBD_VENDOR_IF_H
#define USBD_VENDOR_IF_H
#include <platform_opts.h>
#ifdef CONFIG_USBD_VENDOR
#include "usb.h"
int usbd_vendor_init(void);
void usbd_vendor_deinit(void);
#endif // CONFIG_USBD_VENDOR
#endif // USBD_VENDOR_IF_H

View file

@ -0,0 +1,40 @@
/*
* 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
#include <platform_opts.h>
#ifdef CONFIG_USBH_MSC
/* 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 // CONFIG_USBH_MSC
#endif // __QUIRKS_H

View file

@ -0,0 +1,28 @@
#ifndef _SCATTERLIST_H
#define _SCATTERLIST_H
#include <platform_opts.h>
#ifdef CONFIG_USBH_MSC
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 // CONFIG_USBH_MSC
#endif // _SCATTERLIST_H

View file

@ -0,0 +1,18 @@
#ifndef _DMA_DIRECTION_H
#define _DMA_DIRECTION_H
#include <platform_opts.h>
#ifdef CONFIG_USBH_MSC
enum dma_data_direction {
DMA_BIDIRECTIONAL = 0,
DMA_TO_DEVICE = 1,
DMA_FROM_DEVICE = 2,
DMA_NONE = 3,
};
#endif // CONFIG_USBH_MSC
#endif // _DMA_DIRECTION_H

View file

@ -0,0 +1,578 @@
/*
* 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 <platform_opts.h>
#ifdef CONFIG_USBH_MSC
#include "us_os_wrap_via_osdep_api.h"
#define SCSI_HZ 1024
struct scsi_cmnd;
enum scsi_timeouts {
SCSI_DEFAULT_EH_TIMEOUT = 10 * SCSI_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
/*
* 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 * SCSI_HZ)
#define START_STOP_TIMEOUT (60 * SCSI_HZ)
#define MOVE_MEDIUM_TIMEOUT (5 * 60 * SCSI_HZ)
#define READ_ELEMENT_STATUS_TIMEOUT (5 * 60 * SCSI_HZ)
#define READ_DEFECT_DATA_TIMEOUT (60 * SCSI_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 // CONFIG_USBH_MSC
#endif // _SCSI_SCSI_H

View file

@ -0,0 +1,90 @@
#ifndef __SCSI_CMND_H_
#define __SCSI_CMND_H_
#include <platform_opts.h>
#ifdef CONFIG_USBH_MSC
#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 // CONFIG_USBH_MSC
#endif // __SCSI_CMND_H_

View file

@ -0,0 +1,64 @@
#ifndef _SCSI_EH_H_
#define _SCSI_EH_H_
#include <platform_opts.h>
#ifdef CONFIG_USBH_MSC
#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);
void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses,
unsigned char *cmnd, int cmnd_size, unsigned sense_bytes);
void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, struct scsi_eh_save *ses);
int scsi_normalize_sense(const u8 *sense_buffer, int sb_len,
struct scsi_sense_hdr *sshdr);
#endif // CONFIG_USBH_MSC
#endif // _SCSI_EH_H_

View file

@ -0,0 +1,89 @@
#ifndef __STORAGE_H
#define __STORAGE_H
#include <platform_opts.h>
#ifdef CONFIG_USBH_MSC
#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
*/
#pragma pack(push)
#pragma pack(1)
/* 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 */
} __attribute__((packed));
#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 */
} __attribute__((packed));
#pragma pack(pop)
#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 // CONFIG_USBH_MSC
#endif // __STORAGE_H

View file

@ -0,0 +1,109 @@
/* 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_
#include <platform_opts.h>
#ifdef CONFIG_USBH_MSC
/*
* 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 // CONFIG_USBH_MSC
#endif // _US_TRANSPORT_H_

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,38 @@
#ifndef __UNUSUAL_USBAT_H
#define __UNUSUAL_USBAT_H
#include <platform_opts.h>
#ifdef CONFIG_USBH_MSC
#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 // CONFIG_USBH_MSC
#endif // __UNUSUAL_USBAT_H

View file

@ -0,0 +1,30 @@
#ifndef _US_DEBUG_H_
#define _US_DEBUG_H_
#include <platform_opts.h>
#ifdef CONFIG_USBH_MSC
#include "diag.h"
#include "scsi/scsi_cmnd.h"
#define US_DEBUG 0
#define US_DRIVER "MSC"
#if US_DEBUG
#define US_INFO(fmt, args...) printf("\n\r[%s]%s: " fmt, US_DRIVER, __FUNCTION__, ## args)
#define US_ERR(fmt, args...) printf("\n\r[%s]%s: " fmt, US_DRIVER,__FUNCTION__, ## args)
#define US_WARN(fmt, args...) printf("\n\r[%s]%s: " fmt, US_DRIVER,__FUNCTION__, ## args)
#define US_ENTER printf("\n\r[%s]%s ==>\n", US_DRIVER,__FUNCTION__)
#define US_EXIT printf("\n\r[%s]%s <==\n", US_DRIVER,__FUNCTION__)
#else
#define US_INFO(fmt, args...)
#define US_ERR(fmt, args...) printf("\n\r[%s]%s: " fmt, US_DRIVER,__FUNCTION__, ## args)
#define US_WARN(fmt, args...)
#define US_ENTER
#define US_EXIT
#endif
#endif // CONFIG_USBH_MSC
#endif // _US_DEBUG_H_

View file

@ -0,0 +1,25 @@
#ifndef US_INITIALIZERS_H
#define US_INITIALIZERS_H
#include <platform_opts.h>
#ifdef CONFIG_USBH_MSC
#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);
#endif // CONFIG_USBH_MSC
#endif // US_INITIALIZERS_H

View file

@ -0,0 +1,34 @@
#ifndef __US_INTF_H_
#define __US_INTF_H_
#include <platform_opts.h>
#ifdef CONFIG_USBH_MSC
#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_deinit(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 // CONFIG_USBH_MSC
#endif // __US_INTF_H_

View file

@ -0,0 +1,326 @@
/*
* 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 <platform_opts.h>
#ifdef CONFIG_USBH_MSC
#include "basic_types.h"
#include "osdep_service.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 // CONFIG_USBH_MSC
#endif // US_OS_WRAP_VIA_OSDEP_API_H_

View file

@ -0,0 +1,26 @@
#ifndef _US_SCSI_H
#define _US_SCSI_H
#include <platform_opts.h>
#ifdef CONFIG_USBH_MSC
/**
* 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 // CONFIG_USBH_MSC
#endif // _US_SCSI_H

View file

@ -0,0 +1,37 @@
#ifndef _US_STRINGS_H
#define _US_STRINGS_H
#include <platform_opts.h>
#ifdef CONFIG_USBH_MSC
/* 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 // CONFIG_USBH_MSC
#endif // _US_STRINGS_H

View file

@ -0,0 +1,76 @@
/* Driver for USB Mass Storage compliant devices
* Transport Functions Header File
*/
#ifndef _US_TRANSPORT_H_
#define _US_TRANSPORT_H_
#include <platform_opts.h>
#ifdef CONFIG_USBH_MSC
#include "us_usb.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 // CONFIG_USBH_MSC
#endif // _US_TRANSPORT_H_

View file

@ -0,0 +1,202 @@
#ifndef _US_USB_H_
#define _US_USB_H_
#include <platform_opts.h>
#ifdef CONFIG_USBH_MSC
#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_USBH_MSC_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);
/* 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_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 // CONFIG_USBH_MSC
#endif // _US_USB_H_

View file

@ -0,0 +1,43 @@
#ifndef __US_USUAL_H
#define __US_USUAL_H
#include <platform_opts.h>
#ifdef CONFIG_USBH_MSC
#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 // CONFIG_USBH_MSC
#endif // __US_USUAL_H

View file

@ -0,0 +1,72 @@
#ifndef USBH_VENDOR_H
#define USBH_VENDOR_H
#include <platform_opts.h>
#ifdef CONFIG_USBH_VENDOR
#include "usb.h"
//#define CONFIG_USBH_VENDOR_CTRL_TEST
//#define CONFIG_USBH_VENDOR_BULK_TEST
#define CONFIG_USBH_VENDOR_ISO_IN_TEST
#define CONFIG_USBH_VENDOR_ISO_OUT_TEST
#define USBH_VENDOR_ISO_IN_BUF_SIZE 128
#define USBH_VENDOR_ISO_OUT_BUF_SIZE 128
#define USBH_VENDOR_ISO_IN_CNT 100
#define USBH_VENDOR_TASK_PRIORITY 2
/* Debug options */
#define USBH_VENDOR_DEBUG 0
#define USBH_VENDOR_STR "VS"
#if USBH_VENDOR_DEBUG
#define USBH_VENDOR_INFO(fmt, args...) printf("\n\r[%s]%s: " fmt, USBH_VENDOR_STR, __FUNCTION__, ## args)
#define USBH_VENDOR_WARN(fmt, args...) printf("\n\r[%s]%s: " fmt, USBH_VENDOR_STR, __FUNCTION__, ## args)
#define USBH_VENDOR_ERROR(fmt, args...) printf("\n\r[%s]%s: " fmt, USBH_VENDOR_STR, __FUNCTION__, ## args)
#define USBH_VENDOR_ENTER printf("\n\r[%s]%s: =>", USBH_VENDOR_STR, __FUNCTION__)
#define USBH_VENDOR_EXIT printf("\n\r[%s]%s: <=", USBH_VENDOR_STR, __FUNCTION__)
#define USBH_VENDOR_EXIT_ERR printf("\n\r[%s]%s: ERR <=", USBH_VENDOR_STR, __FUNCTION__)
#else
#define USBH_VENDOR_INFO(fmt, args...)
#define USBH_VENDOR_WARN(fmt, args...)
#define USBH_VENDOR_ERROR(fmt, args...) printf("\n\r[%s]%s: " fmt, USBH_VENDOR_STR, __FUNCTION__, ## args)
#define USBH_VENDOR_ENTER
#define USBH_VENDOR_EXIT
#define USBH_VENDOR_EXIT_ERR
#endif
struct usbtest_info {
const char *name;
u8 ep_in; /* bulk/intr source */
u8 ep_out; /* bulk/intr sink */
unsigned autoconf: 1;
unsigned ctrl_out: 1;
unsigned iso: 1; /* try iso in/out */
unsigned intr: 1; /* try interrupt in/out */
int alt;
};
struct usbtest_dev {
struct usb_interface *intf;
struct usbtest_info *info;
int in_pipe;
int out_pipe;
int in_pipe_addr;
int out_pipe_addr;
int in_iso_pipe;
int out_iso_pipe;
int in_iso_addr;
int out_iso_addr;
int in_int_pipe;
int out_int_pipe;
struct usb_endpoint_descriptor *iso_in, *iso_out;
struct usb_endpoint_descriptor *int_in, *int_out;
u8 *buf;
};
#endif // CONFIG_USBH_VENDOR
#endif // USBH_VENDOR_H

View file

@ -0,0 +1,14 @@
#ifndef USBH_VENDOR_IF_H
#define USBH_VENDOR_IF_H
#include <platform_opts.h>
#ifdef CONFIG_USBH_VENDOR
int usbh_vendor_init(void);
void usbh_vendor_deinit(void);
#endif // CONFIG_USBH_VENDOR
#endif // USBH_VENDOR_IF_H

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_

Some files were not shown because too many files have changed in this diff Show more