📄 iusbprocesscommand.c
字号:
/* * 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 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Copyright (C) 2002 Motorola Semiconductors HK Ltd * */// This routine is called by the interrupt handler (triggered by the IN endpoint).// It handles commands from the USB host#include "prototype.h"#include "define.h"#include "variable.h"#include "mx1.h"P_U8 _gpUsbBufPtr; // pointer to buffer dataU32 _gUsbNumSector; // number of sector to read/writeU32 _gUsbCurSector; // current sector being read/writeU32 _gUsbPacketCount; // USB packet countU8 _gCBW[31]; // command block wrappervoid _iUsbProcessCommand(void){ U8 i; for (i=0; i<31; i++) _gCBW[i] = *((volatile U8 *)((U32)&_reg_USBD_EP2_FDAT+3)); switch(_gCBW[15]) { case 0x12: // inquiry//DPRINTK("Inquiry\n");// _reg_USBD_EP1_FDAT = 0x00800202; _reg_USBD_EP1_FDAT = 0x00800001; _reg_USBD_EP1_FDAT = 0x5B000000; // vendor identification (8 bytes) _reg_USBD_EP1_FDAT = 0x4D4F544F; // "MOTO" _reg_USBD_EP1_FDAT = 0x524F4C41; // "ROLA" // product identification (16 bytes) _reg_USBD_EP1_FDAT = 0x41445320; // "ADS " _reg_USBD_EP1_FDAT = 0x302E3120; // "0.1 " _reg_USBD_EP1_FDAT = 0x20202020; // " " _reg_USBD_EP1_FCTRL |= 0x20000000; // next is last word in packet _reg_USBD_EP1_FDAT = 0x20202020; // " " // product revision level (4 bytes) *((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = 0x30; *((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = 0x31; *((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = 0x30; _reg_USBD_EP1_FCTRL |= 0x20000000; // next is last word in packet *((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = 0x30; // now the CSW _reg_USBD_EP1_FDAT = 0x55534253; // signature in BIG endian for (i=0; i<4; i++) *((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = _gCBW[4+i]; // CSWtag _reg_USBD_EP1_FDAT = 0; // data residue _reg_USBD_EP1_FCTRL |= 0x20000000; // next is last word in packet *((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = 0; // status: passed break; case 0x23: // READ FORMAT CAPACITIES, not supported, return STALL case 0x1A: // MODE SENSE, not supported, return STALL case 0x5A: // MODE SENSE, not supported, return STALL _reg_USBD_EP1_STAT |= FORCE_STALL_MASK; // now the CSW _reg_USBD_EP1_FDAT = 0x55534253; // signature in BIG endian for (i=0; i<8; i++) *((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = _gCBW[4+i]; // CSWtag _reg_USBD_EP1_FCTRL |= 0x20000000; // next is last word in packet *((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = 0x01; // status: failed break; case 0x03: // REQUEST SENSE, return error _reg_USBD_EP1_FDAT = 0x70000500; _reg_USBD_EP1_FDAT = 0x0000000C; _reg_USBD_EP1_FDAT = 0x00000000; _reg_USBD_EP1_FDAT = 0x20000000; *((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = 0x00; _reg_USBD_EP1_FCTRL |= 0x20000000; // next is last word in packet *((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = 0x00; // now the CSW _reg_USBD_EP1_FDAT = 0x55534253; // signature in BIG endian for (i=0; i<4; i++) *((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = _gCBW[4+i]; // CSWtag _reg_USBD_EP1_FDAT = 0; // data residue _reg_USBD_EP1_FCTRL |= 0x20000000; // next is last word in packet *((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = 0; // status: passed break; case 0x25: // READ CAPACITY// _reg_USBD_EP1_FDAT = 0x00007FFF; // last block _reg_USBD_EP1_FDAT = 0x00006FFF; // last block of 14M disk _reg_USBD_EP1_FCTRL |= 0x20000000; // next is last word in packet _reg_USBD_EP1_FDAT = 0x00000200; // block size // now the CSW _reg_USBD_EP1_FDAT = 0x55534253; // signature in BIG endian for (i=0; i<4; i++) *((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = _gCBW[4+i]; // CSWtag _reg_USBD_EP1_FDAT = 0; // data residue _reg_USBD_EP1_FCTRL |= 0x20000000; // next is last word in packet *((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = 0; // status: passed break; case 0x28: // READ // extract start sector _gUsbCurSector = 0; for (i=0; i<4; i++) _gUsbCurSector = (_gUsbCurSector << 8) | (U32)_gCBW[17+i]; // extract number of sectors _gUsbNumSector = (((U32)_gCBW[22]) << 8) | ((U32)_gCBW[23]);//DPRINTK("Read from sector 0x%08x for 0x%04x sectors\n", _gUsbCurSector, _gUsbNumSector); _gUsbPacketCount = _gUsbNumSector * 16; _gpUsbBufPtr = (P_U8)(USB_DISK_START + _gUsbCurSector * 512); // fill up the 1st packet for (i=0; i<31; i++) *((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = *(_gpUsbBufPtr++); _reg_USBD_EP1_FCTRL |= 0x20000000; // next is last word in packet *((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = *(_gpUsbBufPtr++); // enable EOF interrupt _reg_USBD_EP1_INTR_MASK &= ~EOF_MASK; break; case 0x00: // NULL COMMAND, return CSW with pass case 0x1E: // PREVENT-ALLOW MEDIUM REMOVAL, return CSW with pass case 0x2F: // VERIFY // now the CSW _reg_USBD_EP1_FDAT = 0x55534253; // signature in BIG endian for (i=0; i<4; i++) *((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = _gCBW[4+i]; // CSWtag _reg_USBD_EP1_FDAT = 0; // data residue _reg_USBD_EP1_FCTRL |= 0x20000000; // next is last word in packet *((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = 0; // status: passed break; case 0x1B: // START-STOP UNIT (when host EJECT) printk("\nEJECT from host detected.\n"); // now the CSW _reg_USBD_EP1_FDAT = 0x55534253; // signature in BIG endian for (i=0; i<4; i++) *((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = _gCBW[4+i]; // CSWtag _reg_USBD_EP1_FDAT = 0; // data residue _reg_USBD_EP1_FCTRL |= 0x20000000; // next is last word in packet *((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = 0; // status: passed break; case 0x2A: // WRITE // extract start sector _gUsbCurSector = 0; for (i=0; i<4; i++) _gUsbCurSector = (_gUsbCurSector << 8) | (U32)_gCBW[17+i]; // extract number of sectors _gUsbNumSector = (((U32)_gCBW[22]) << 8) | ((U32)_gCBW[23]);//DPRINTK("Write to sector 0x%08x for 0x%04x sectors\n", _gUsbCurSector, _gUsbNumSector); _gUsbPacketCount = _gUsbNumSector * 16; _gpUsbBufPtr = (P_U8)(USB_DISK_START + _gUsbCurSector * 512); // enable EOF interrupt _reg_USBD_EP2_INTR_MASK &= ~EOF_MASK; break; default: printk("Unknown command !\n"); DPRINTK("dCBWSignature: 0x%02x 0x%02x 0x%02x 0x%02x \n", _gCBW[0], _gCBW[1], _gCBW[2], _gCBW[3]); DPRINTK("dCBWTag: 0x%02x 0x%02x 0x%02x 0x%02x \n", _gCBW[4], _gCBW[5], _gCBW[6], _gCBW[7]); DPRINTK("dCBWDataTransferLength: 0x%08x\n", (int)((U32)_gCBW[8] | ((U32)_gCBW[9]<<8) | ((U32)_gCBW[10]<<16) | ((U32)_gCBW[11]<<24))); DPRINTK("bmCBWFlags: 0x%02x\n", _gCBW[12]); DPRINTK("bCBWLUN: 0x%02x\n", _gCBW[13]); DPRINTK("bCBWLength: 0x%02x\n", _gCBW[14]); DPRINTK("CBWCB: "); for (i=0; i<_gCBW[14]; i++) DPRINTK("0x%02x ", _gCBW[15+i]); DPRINTK("\n"); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -