?? mass_storage.c
字號(hào):
/********************** BEGIN LICENSE BLOCK ************************************ * * JZ4740 mobile_tv Project V1.0.0 * INGENIC CONFIDENTIAL--NOT FOR DISTRIBUTION IN SOURCE CODE FORM * Copyright (c) Ingenic Semiconductor Co. Ltd 2005. All rights reserved. * * This file, and the files included with this file, is distributed and made * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * * http://www.ingenic.cn * ********************** END LICENSE BLOCK ************************************** * * Author: <dsqiu@ingenic.cn> <jgao@ingenic.cn> * * Create: 2008-06-26, by dsqiu * * Maintain: 2008-06-26, by jgao * * ******************************************************************************* */ #include <ucos_ii.h>#include "threadprio.h"#include "usb.h"#include "udcbus.h"#include "udc.h"#include "mass_storage.h"#include "function.h"#if 0#define dprintf printf#else#define dprintf(x...)#endif#ifndef NULL#define NULL#endif#define RECEIVE_CBW 0#define RECEIVE_DATA 1#define SENDING_CSW 2#define SEND_DATA 3#define RECEIVE_SERIES_DATA 4#define SEND_SERIES_DATA 5#define SENDED_CSW 6//#define MUTI_THREAD#ifdef MUTI_THREADvolatile static u32 ssector;volatile static u32 nsector;#define MASS_TASK_PRIO MASS_STORAGE_THREAD_PRIO //8#define MASS_TASK_STK_SIZE 1024OS_STK MassTaskStack[MASS_TASK_STK_SIZE];u8 err;#endifunsigned char mass_state = RECEIVE_CBW;//unsigned char send_state = RECEIVE_CBW;#define MAX_LUN_COUNT 4PUDC_LUN pDev[MAX_LUN_COUNT] = { 0, 0, 0, 0};unsigned char curLunCount = 0;PIPE pipe[3] = { {0,ENDPOINT_TYPE_CONTROL,8}, {0x81,ENDPOINT_TYPE_BULK,64}, {0x2,ENDPOINT_TYPE_BULK,64} };unsigned int register_dev(PUDC_LUN pdev){ if(pdev) { if(curLunCount > MAX_LUN_COUNT) { printf("warning:Max Logical Unit number is %d\r\n",MAX_LUN_COUNT); return -1; } pDev[curLunCount++] = pdev; } return 0;} /* * USB mass storage class subclasses */enum UMASS_SUBCLASS{ MASS_SUBCLASS_RBC = 1, // Flash MASS_SUBCLASS_8020, // CD-ROM MASS_SUBCLASS_QIC, // Tape MASS_SUBCLASS_UFI, // Floppy disk device MASS_SUBCLASS_8070, // Floppy disk device MASS_SUBCLASS_SCSI // Any device with a SCSI-defined command set};/* * USB mass storage class protocols */enum UMASS_PROTOCOL{ MASS_PROTOCOL_CBI, // Command/Bulk/Interrupt MASS_PROTOCOL_CBI_CCI, // Command/Bulk/Interrupt MASS_PROTOCOL_BULK = 0x50 // Bulk-Only transport};static u32 epout, epin;static USB_DeviceDescriptor devDesc = { sizeof(USB_DeviceDescriptor), DEVICE_DESCRIPTOR, //1 0x0200, //Version 2.0// 0x08,// 0x01,// 0x50, 0x00, 0x00, 0x00, 64, /* Ep0 FIFO size */ 0x0525, 0xa4a5, 0x0320, 0x01, //iManufacturer; 0x02, //iProduct; 0x03, 0x01};#define CONFIG_DESCRIPTOR_LEN (sizeof(USB_ConfigDescriptor) + \ sizeof(USB_InterfaceDescriptor) + \ sizeof(USB_EndPointDescriptor) * 2)static struct { USB_ConfigDescriptor configuration_descriptor; USB_InterfaceDescriptor interface_descritor; USB_EndPointDescriptor endpoint_descriptor[2];} __attribute__ ((packed)) confDesc = { { sizeof(USB_ConfigDescriptor), CONFIGURATION_DESCRIPTOR, CONFIG_DESCRIPTOR_LEN, 0x01, 0x01, 0x04, 0x80, // Self Powered, no remote wakeup 0xfa // Maximum power consumption 200 mA //0x00 }, { sizeof(USB_InterfaceDescriptor), INTERFACE_DESCRIPTOR, 0x00, 0x00, 0x02, /* ep number */ CLASS_MASS_STORAGE, MASS_SUBCLASS_SCSI, MASS_PROTOCOL_BULK, 0x05 }, { { sizeof(USB_EndPointDescriptor), ENDPOINT_DESCRIPTOR, (1 << 7) | 1,// endpoint 2 is IN endpoint 2, /* bulk */ /* Transfer Type: Bulk; * Synchronization Type: No Synchronization; * Usage Type: Data endpoint */ //512, /* IN EP FIFO size */ 512, 0 }, { sizeof(USB_EndPointDescriptor), ENDPOINT_DESCRIPTOR, (0 << 7) | 1,// endpoint 5 is OUT endpoint 2, /* bulk */ /* Transfer Type: Bulk; * Synchronization Type: No Synchronization; * Usage Type: Data endpoint */ 512, /* OUT EP FIFO size */ 0 } }};static USB_DeviceQualifierDescriptor devQualifyDesc ={ sizeof(USB_DeviceQualifierDescriptor), 0x06, 0x0200, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00};/*void send_dev_desc_string(int size){ u16 str_ret[13] = { 0x031a,//0x1a=26 byte 0x0041, 0x0030, 0x0030, 0x0041, 0x0030, 0x0030, 0x0041, 0x0030, 0x0030, 0x0041, 0x0030, 0x0030 }; dprintf("send_dev_desc_string size = %d\r\n",size); if(size >= 26) size = 26; str_ret[0] = (0x0300 | size); HW_SendPKT(0, str_ret,size); }*//* * Command Block Wrapper (CBW) */#define CBWSIGNATURE 0x43425355 // "CBSU"#define CBWFLAGS_OUT 0x00 // HOST-to-DEVICE#define CBWFLAGS_IN 0x80 // DEVICE-to-HOST#define CBWCDBLENGTH 16typedef struct{ u32 dCBWSignature; u32 dCBWTag; s32 dCBWDataXferLength; u8 bmCBWFlags; /* The bits of this field are defined as follows: * Bit 7 Direction - the device shall ignore this bit if the * dCBWDataTransferLength zero, otherwise: * 0 = Data-Out from host to the device, * 1 = Data-In from the device to the host. * Bit 6 Obsolete. The host shall set this bit to zero. * Bits 5..0 Reserved - the host shall set these bits to zero. */ u8 bCBWLUN : 4, reserved0 : 4; u8 bCBWCBLength : 5, reserved1 : 3; u8 CBWCB[CBWCDBLENGTH];} __attribute__ ((packed)) CBW;/* * Command Status Wrapper (CSW) */#define CSWSIGNATURE 0x53425355 // "SBSU"#define CSWSIGNATURE_IMAGINATION_DBX1 0x43425355 // "CBSU"#define CSWSIGNATURE_OLYMPUS_C1 0x55425355 // "UBSU"#define CSWSTATUS_GOOD 0x0#define CSWSTATUS_FAILED 0x1#define CSWSTATUS_PHASE_ERR 0x2typedef struct{ u32 dCSWSignature; u32 dCSWTag; u32 dCSWDataResidue; u8 bCSWStatus; /* 00h Command Passed ("good status") * 01h Command Failed * 02h Phase Error * 03h and 04h Reserved (Obsolete) * 05h to FFh Reserved */} __attribute__ ((packed)) CSW;/* * Required UFI Commands */#define UFI_FORMAT_UNIT 0x04 // output#define UFI_INQUIRY 0x12 // input#define UFI_MODE_SELECT 0x55 // output#define UFI_MODE_SENSE_6 0x1A // input#define UFI_MODE_SENSE_10 0x5A // input#define UFI_PREVENT_MEDIUM_REMOVAL 0x1E#define UFI_READ_10 0x28 // input#define UFI_READ_12 0xA8 // input#define UFI_READ_CAPACITY 0x25 // input#define UFI_READ_FORMAT_CAPACITY 0x23 // input#define UFI_REQUEST_SENSE 0x03 // input#define UFI_REZERO_UNIT 0x01#define UFI_SEEK_10 0x2B#define UFI_SEND_DIAGNOSTIC 0x1D#define UFI_START_UNIT 0x1B#define UFI_TEST_UNIT_READY 0x00#define UFI_VERIFY 0x2F#define UFI_WRITE_10 0x2A // output#define UFI_WRITE_12 0xAA // output#define UFI_WRITE_AND_VERIFY 0x2E // output#define UFI_ALLOW_MEDIUM_REMOVAL UFI_PREVENT_MEDIUM_REMOVAL#define UFI_STOP_UNIT UFI_START_UNITstatic u32 mass_get_state = 0;#undef memalign#undef free#define memalign(x,y) alignAlloc(x,y) #define free(x) deAlloc(x)#ifdef MUTI_THREAD#define UDC_FRAME_SIZE ( 512 *0x100 )//static u32 massBuf0[UDC_FRAME_SIZE / 4] __attribute__ ((aligned (32)));//static u32 massBuf1[UDC_FRAME_SIZE / 4] __attribute__ ((aligned (32)));static u32 *massBuf0 = NULL;static u32 *massBuf1 = NULL;#define udc_mass_alloc() \do { \ if(massBuf0 == NULL) \ massBuf0 = (u32 *)memalign(32,UDC_FRAME_SIZE); \ if(massBuf1 == NULL) \ massBuf1 = (u32 *)memalign(32,UDC_FRAME_SIZE); \ }while(0)#define udc_mass_free() \do{ \ if(massBuf0){ \ free(massBuf0); \ massBuf0 = NULL; \ } \ if(massBuf1){ \ free(massBuf1); \ massBuf1 = NULL; \ } \}while(0)unsigned char *massbuf = 0;volatile u8 udc_trigger = 1 , mass_trigger = 1; //first buffer 0 !OS_EVENT *sem_buf0 = NULL, *sem_buf1 = NULL, *sem_mass = NULL, *sem_device = NULL ;#else#define UDC_FRAME_SIZE ( 1024 * 64 )static u32 *massBuf_ptr = 0;#define udc_mass_alloc() \do { \ if(massBuf_ptr == NULL) \ massBuf_ptr = (u32 *)memalign(32,UDC_FRAME_SIZE); \ }while(0)#define udc_mass_free() \do{ \ if(massBuf_ptr){ \ free(massBuf_ptr); \ massBuf_ptr = NULL; \ } \}while(0)static unsigned char *massbuf_ptr = 0;#endifstatic CSW csw = {0};static CBW cbw = {0};unsigned int g_start_sector = 0;unsigned short g_nr_sectors = 0;unsigned int g_sector_size = 0;static u8 iscardin;static u32 swap32(u32 n){ return (((n & 0x000000ff) >> 0) << 24) | (((n & 0x0000ff00) >> 8) << 16) | (((n & 0x00ff0000) >> 16) << 8) | (((n & 0xff000000) >> 24) << 0);}typedef struct _CAPACITY_DATA { u32 Blocks; u32 BlockLen; }CAPACITY_DATA;typedef struct _READ_FORMAT_CAPACITY_DATA { u8 Reserve1[3]; u8 CapacityListLen; CAPACITY_DATA CurMaxCapacity; CAPACITY_DATA CapacityData[30]; }READ_FORMAT_CAPACITY_DATA;/*Interface */unsigned short udc_device_state = 0;#define UDC_HW_CONNECT 1#define UDC_SW_CONNECT 0x10#define WAIT_RECEIVECBW_FINISH 0#define WAIT_SENDCSW_FINISH 1#define WAIT_RECEIVE_FINISH 2#define WAIT_SEND_FINISH 3static void deinit_thread();static void init_thread();static inline unsigned int Handle_UFI_INQUIRY(unsigned handle){ PUDC_BUS pBus = (PUDC_BUS)handle; static const unsigned char inquiry[] = { 0x00, // Direct-access device (floppy) 0x80, // 0x80 // Removable Media 0x00, 0x00, // UFI device 0x29, 0x00, 0x00, 0x00, 'I', 'n', 'g', 'e', 'n', 'i', 'c', ' ', 'J', 'z', 'S', 'O', 'C', ' ', 'U', 'S', 'B', '-', 'D', 'I', 'S', 'K', ' ', ' ', '0', '1', '0', '0' }; u32 size = sizeof(inquiry); if(cbw.dCBWDataXferLength < sizeof(inquiry)) size = cbw.dCBWDataXferLength; pBus->StartTransfer(handle,pipe[1].ep,(unsigned char *)inquiry, size); return 1; }static inline unsigned int Handle_UFI_REQUEST_SENSE(unsigned handle){ PUDC_BUS pBus = (PUDC_BUS)handle; static unsigned char sense[] = { 0x70, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00 }; PUDC_LUN pdev = pDev[cbw.bCBWLUN]; if ( !(pdev->CheckDevState(handle)) ) {
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -