📄 usbmass.c
字号:
/*
* Start of Zoran Standard Header
* Copyright (c) 2003 - 2004 Zoran Corporation.
*
*
* All rights reserved. Proprietary and confidential.
*
* DESCRIPTION for usbmass.c
* Support for USB Mass Storage Class device (flash memory cards)
*
* NEW HISTORY COMMENT (description must be followed by a blank line)
* <Enter change description here>
* ===== HISTORY of changes in //depot/misc/projects/tps/usb/usbmass.c
*
* 1/Jul/04 #42 lee Changed "occasional sleep" to be 0.5 seconds ever 8 seconds.
* 30/Jun/04 #41 lee Fix bug 41116 by occasionally sleeping USBMassStorage()
* thread if running in USB 2.0 and host is intensively
* reading flash memory. Can be reverted back by
* "-DUSB_MASS_OCCASIONAL_HS_SLEEP=0" for testing.
* 15/Jun/04 #40 lee Make STALL_CARD_ENDPOINT dependent on MEM_EP.
* 10/Jun/04 #39 imgeng Disable reads in DoVerify() unless #define REALLY_VERIFY_DATA is set
* 2/Jun/04 #38 lee Only set LED-blink flag if card present and being accessed.
* 1/Jun/04 #37 lee Pick up manufacturer from NVRAM in case personality changes.
* 1/Jun/04 #36 lee Change manufacturer character string to report "Dell"
* for CH*, else "Lexmark".
* 28/May/04 #36 lee Added code for debugging.
* 28/May/04 #35 lee Changes for USB 2.0 scan-to-host speed-up; USBWriteCard
* now blocking so I/O no longer double buffered.
* 21/May/04 #34 emiller Fix boot build error
* 21/May/04 #33 lee Fix READ12 & WRITE12 operations.
* 21/May/04 #32 lee Fix linker error if MEMORY_CARD_READER not defined.
* 12/May/04 #31 lee No memory card reported to PC if printer powered off.
* 10/May/04 #30 lee Remove RAM_FLASH debug code.
* 27/Apr/04 #29 lee Fix Request Sense for Win98.
* 26/Apr/04 #28 lee STALL if error during SCSI command (works with MAC).
* 26/Apr/04 #27 lee Stop Card Reader LED blinking if USB cable removed.
* 20/Apr/04 #26 lee Let Host O/S know medium changed.
* 15/Apr/04 #25 pshread PreventRemoval is no longer static so that mem-car mngr can track when host is done writing to card
* 7/Apr/04 #24 lee Fix undefined references if NO_MEMORY_CARD_READER
* build flag is used.
* 1/Apr/04 #23 lee Small fix to blinking LED code.
* 30/Mar/04 #22 lee Make "DoNotRemoveFlashMemory" volatile.
* 30/Mar/04 #21 lee Added support for WriteProtected flash; set
* DoNotRemoveFlashMemory whenever host is accessing flash,
* not just for Prevent Media Removal command.
* 26/Mar/04 #20 pshread Reverted DISABLE_FLASH_WRITE: Writing to memory card is enabled by default. Use DISABLE_FLASH_WRITE to disable
* 19/Mar/04 #19 mrhines Now use DISABLE_FLASH_WRITE=0 to enable card writing.
* 18/Mar/04 #18 pshread Writing to memory card is enabled by default. Use DISABLE_FLASH_WRITE to disable
* 15/Mar/04 #17 lee Broke Windows version - now fixed (needs clean-up)
* 15/Mar/04 #16 lee Changes to get MACs to work.
* 10/Mar/04 #15 lee Moved USB data buffers to non-cachable memory.
* 3/Mar/04 #14 lee Added Funai modifications for Memory Card Check Tool.
* 12/Feb/04 #13 lee GetMemoryCardInfo() now GetMemoryCardStatus()
* with added argument indicating if flash memory card was removed
* and another inserted. Also fixed bug in DoWrite that caused hang
* and windows error if USB packets for a flash sector data wrapped
* the USB ring buffer.
* 5/Feb/04 #12 lee Fix for Win2K: Sometimes couldn't see
* compact flash was mounted. Expand diagnostic printouts.
* 26/Nov/03 #11 lee Support Mass Storage Class devices on host USB port
* (pass-through mode); don't allow writes to flash memory
* unless overridden by "-DALLOW_FLASH_WRITE" until
* sector 0 bug fixed.
* 30/Oct/03 #10 lee Removed "MC_DBPRINT" undefine so it can be overridden
* by compiler "-D" option; made printout less noisy. Added
* "DoNotRemoveFlashMemory" flag.
* 14/Oct/03 #9 lee Now manifest for RAM Flash Card (debug) is RAM_FLASH.
* 14/Oct/03 #8 lee Don't allow MEMORY_CARD_READER for boot builds.
* 14/Oct/03 #7 pshread Debug printing disabled my default. Too much spitting out serial port otherwise.
* 7/Oct/03 #6 lee Continued development.
* 6/Oct/03 #5 lee More fixes; changed iface routines to use sector address,
* sector count rather than byte address, byte count.
* 2/Oct/03 #4 lee Life goes on.
* 29/Sep/03 #3 lee More work/bug fixes for Mass Memory Class.
* 26/Sep/03 #2 lee Work in progress.
* 19/Sep/03 #1 lee Created (work in progress).
*
* End of Zoran Standard Header
*/
#ifdef BOOTCODE
/* Boot build default: memory card reader off */
#ifdef MEMORY_CARD_READER
#undef MEMORY_CARD_READER
#endif
#endif
#include "univ.gh"
#include "arch.h"
#ifndef BOOTCODE
#include "pile.h"
#include "util.h"
#include "dbg.h"
#include "ts.h"
#include "propman.h"
#include "bios.h"
#include "usb.h"
#include "usbpriv.h"
#include "usbmass.h"
#ifdef DISABLE_FLASH_WRITE
#define WRITE_PROTECT_FLASH 1
#else
#define WRITE_PROTECT_FLASH 0
#endif
#ifdef MSCLASS_HOST_PASSTHROUGH
#undef WRITE_PROTECT_FLASH
#define WRITE_PROTECT_FLASH 0
#ifndef MEMORY_CARD_READER
#define MEMORY_CARD_READER
#endif
#endif
#endif
volatile Boolean DoNotRemoveFlashMemory = FALSE;
Boolean PreventRemoval = FALSE;
#ifdef MEMORY_CARD_READER
#ifdef FUNAI_MODIFY_022704
/* for Memory Card Check Tool */
#include "MemCardTest.h"
#endif /* FUNAI_MODIFY_022704 */
#define PRODUCT_ID_16 "USB Mass Storage"
#define PRODUCT_REV_4 "1.00"
#ifdef MC_DBPRINT
#define DBPRINT if(1)PSPRINTF
#else
#define DBPRINT if(0)PSPRINTF
#endif
#ifndef USB_MASS_OCCASIONAL_HS_SLEEP
#define USB_MASS_OCCASIONAL_HS_SLEEP 1
#endif
#define STALL TRUE
#define NO_STALL FALSE
typedef struct {
Uint8 *cmd;
Uint8 cmd_length;
Uint8 INflag;
Uint32 data_length;
Uint32 cmdtag;
Uint32 LastSector;
Uint32 SectorSize;
MEM_STATUS CardStatus;
Boolean WriteProtected;
} COMMAND;
static void DoSCSICommand(COMMAND *c);
static void DoInquiry(COMMAND *c);
static void DoModeSense(COMMAND *c);
static void DoRead(COMMAND *c);
static void DoReadCapacity(COMMAND *c);
static void DoReadFormatCapacities(COMMAND *c);
static void DoRequestSense(COMMAND *c);
static void DoVerify(COMMAND *c);
static void DoWrite(COMMAND *c, Boolean *CardChangeFlag);
#ifdef FUNAI_MODIFY_022704
/* for Memory Card Check Tool */
static void DoMediaCheck(COMMAND *c);
#endif /* FUNAI_MODIFY_022704 */
static void SendStatus(Uint8 status, Boolean stall, Uint32 tag, Uint32 residue);
static Boolean SectorCheck(COMMAND *c, Boolean FieldFlag, Uint32 *sector,
Uint32 *count);
/* Flag maintained in fp/fp.c showing if nominal "power" is on or off */
extern int g_powerOn; /* power is on or off */
#if USB_MASS_OCCASIONAL_HS_SLEEP
extern Boolean USB20_HighSpeed;
#endif
#ifdef MSCLASS_HOST_PASSTHROUGH
MEM_STATUS CAMERA_GetMemoryCardStatus(Uint32 *LastSect, Uint32 *SectSize,
Boolean *NewFlash, Boolean *WriteProtected);
MEM_STATUS CAMERA_WriteMemoryCard(Uint32 sector, Uint32 count, Uint8 *data);
MEM_STATUS CAMERA_ReadMemoryCard(Uint8 *buff, Uint32 sector, Uint32 count);
#define GET_MEMORYCARD_STAT CAMERA_GetMemoryCardStatus
#define MEMORYCARD_WRITE CAMERA_WriteMemoryCard
#define MEMORYCARD_READ CAMERA_ReadMemoryCard
#else
/* Use the real routines */
#define GET_MEMORYCARD_STAT GetMemoryCardStatus
#define MEMORYCARD_WRITE WriteMemoryCard
#define MEMORYCARD_READ ReadMemoryCard
#endif
/* Just turn off ARM chip interrupts for brief protection. */
void armIntsOff(void);
void armIntsOn(void);
#define ARM_INTS_OFF armIntsOff();
#define ARM_INTS_ON armIntsOn();
#define STALL_CARD_ENDPOINT USB_ISR_set_endpoint_status(0x80+MEM_EP, 1)
#define NON_CACHABLE_MEMORY(v) ((Uint32)(v) | 0x20000000)
static Uint32 sense_data = NO_SENSE;
/* One-sector buffer for Write and Verify commands */
static Uint8 sectbuff[MAX_SECTOR_SIZE];
void USBMassStorage(void)
{
int i;
Uint8 *ptr1, *ptr2;
Uint32 cnt1, cnt2;
Uint8 cmd[31];
COMMAND c;
while (1) {
/* Check if USB Mass Storage Class interface disconnected */
if (!USBConfigured()) {
DoNotRemoveFlashMemory = FALSE;
PreventRemoval = FALSE;
return;
}
/* Read next Command Block Wrapper */
USBReadCard(&ptr1, &cnt1, &ptr2, &cnt2);
if (cnt1 + cnt2 < 31) {
DoNotRemoveFlashMemory = PreventRemoval;
return;
}
for (i = 0; i < 31; i++)
cmd[i] = (i < cnt1) ? ptr1[i] : ptr2[i - cnt1];
USBConsumeCard(31);
if (cmd[0] == 0x55 &&
cmd[1] == 0x53 &&
cmd[2] == 0x42 &&
cmd[3] == 0x43)
{
c.cmdtag = (cmd[4] << 0) |
(cmd[5] << 8) |
(cmd[6] << 16) |
(cmd[7] << 24);
c.INflag = cmd[12];
c.cmd_length = cmd[14];
if (cmd[13] || c.cmd_length > 16 || (c.INflag & 0x3f)) {
SendStatus(PHASE_ERROR, STALL, c.cmdtag, 0);
DBPRINT("Phase: cmd[13] %02x l %d INflag %02x\n",
cmd[13], c.cmd_length, (c.INflag & 0x3f));
USBReadCard(&ptr1, &cnt1, &ptr2, &cnt2);
USBConsumeCard(cnt1 + cnt2);
}
else {
c.data_length = (cmd[ 8] << 0) | (cmd[ 9] << 8) |
(cmd[10] << 16) | (cmd[11] << 24);
c.cmd = &cmd[15];
DoSCSICommand(&c);
}
}
else {
SendStatus(PHASE_ERROR, STALL, c.cmdtag, 0);
DBPRINT("Phase error: header %02 %02 %02 %02 %02 %02 %02 %02x\n",
cmd[0], cmd[1], cmd[2], cmd[3],
cmd[4], cmd[5], cmd[6], cmd[7]);
USBReadCard(&ptr1, &cnt1, &ptr2, &cnt2);
USBConsumeCard(cnt1 + cnt2);
}
}
}
static void DoSCSICommand(COMMAND *c)
{
static Boolean CardChangeFlag = FALSE;
Boolean NewFlash;
if (c->cmd[0] != TEST_UNIT_READY) {
DBPRINT("<%02x> ", c->cmd[0]);
}
if (!g_powerOn)
c->CardStatus = NOT_PRESENT;
else
c->CardStatus = GET_MEMORYCARD_STAT(&c->LastSector, &c->SectorSize,
&NewFlash, &c->WriteProtected);
if (c->CardStatus == NOT_PRESENT || NewFlash) {
CardChangeFlag = TRUE;
if (c->cmd[0] == TEST_UNIT_READY ||
c->cmd[0] == PREVENT_ALLOW_MEDIUM_REMOVAL)
{
sense_data = SENSE_MEDIUM_NOT_PRESENT;
SendStatus(COMMAND_FAILED, NO_STALL, c->cmdtag, c->data_length);
DBPRINT("CardNotPresent\n");
PreventRemoval = FALSE;
return;
}
}
else if (CardChangeFlag) {
c->CardStatus = NOT_PRESENT;
DBPRINT("Flash memory card was changed\n");
sense_data = SENSE_UNIT_ATTN_MEDIA_CHNGD;
}
switch (c->cmd[0]) {
case INQUIRY:
DoInquiry(c);
break;
case MODE_SENSE6:
case MODE_SENSE10:
DoModeSense(c);
break;
case PREVENT_ALLOW_MEDIUM_REMOVAL:
if (c->cmd[4]) {
DBPRINT("DO NOT REMOVE FLASH MEMORY\n");
PreventRemoval = TRUE;
}
else {
DBPRINT("OK to remove flash memory\n");
PreventRemoval = FALSE;
}
if (c->CardStatus == NOT_PRESENT) {
sense_data = SENSE_MEDIUM_NOT_PRESENT;
SendStatus(COMMAND_FAILED, NO_STALL, c->cmdtag, c->data_length);
}
else {
CardChangeFlag = FALSE;
sense_data = NO_SENSE;
SendStatus(COMMAND_PASSED, NO_STALL, c->cmdtag, c->data_length);
}
break;
case READ10:
case READ12:
CardChangeFlag = FALSE;
DoRead(c);
break;
case READ_CAPACITY:
DoReadCapacity(c);
break;
case READ_FORMAT_CAPACITIES:
DoReadFormatCapacities(c);
break;
case REQUEST_SENSE:
/* If we are telling O/S that medium changed, clear flag */
if (sense_data == SENSE_UNIT_ATTN_MEDIA_CHNGD)
CardChangeFlag = FALSE;
DoRequestSense(c);
break;
case SEND_DIAGNOSTIC:
DBPRINT("SendDiag\n");
sense_data = NO_SENSE;
SendStatus(COMMAND_PASSED, NO_STALL, c->cmdtag, c->data_length);
break;
case TEST_UNIT_READY:
sense_data = NO_SENSE;
SendStatus(COMMAND_PASSED, NO_STALL, c->cmdtag, c->data_length);
break;
case VERIFY:
DoVerify(c);
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -