⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbmass.c

📁 printer usb
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 *  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 + -