?? usbhost.c
字號:
/*
* Start of Zoran Standard Header
* Copyright (c) 2003 - 2004 Zoran Corporation.
*
*
* All rights reserved. Proprietary and confidential.
*
* DESCRIPTION for usbhost.c
* USB Host
*
* NEW HISTORY COMMENT (description must be followed by a blank line)
* <Enter change description here>
* ===== HISTORY of changes in //depot/misc/projects/tps/usb/usbhost.c
*
* 1/Jul/04 #49 lee I forgot to run stdhdr; sorry.
* 1/Jul/04 #48 lee Fixed window in power-on sequence where PictBridge could
* grab the job lock before a maintenance task had a change to run.
* 30/Jun/04 #47 ebradsha Reinstated changes from #45. But make sure we set *retCount in early
* return in PTP_USB_Read_Timed and _Write_Timed.
* 30/Jun/04 #46 ebradsha Back out change #45. May be related to recent hangs.
* 30/Jun/04 #45 lee Make interrupt polling timing more accurate; fix bug.
* 28/Jun/04 #44 lee Added 8-second delay before camera enumeration
* after printer is first powered on.
* 23/Jun/04 #43 lee Fix for tracking transfer counts properly.
* 18/Jun/04 #42 lee Fix issues with PB camera connected during printer power-on.
* 10/Jun/04 #41 lee If printer is powered off, stop USB host communication.
* 10/Jun/04 #40 lee Toggle DATAx after sending OUT null packet.
* 9/Jun/04 #39 lee Return correct byte count for PTP_USB_Write_Timed()
* on incomplete transfer due to PTP_USB_NAK return; also, add zero-length
* packet if write size is integral multiple of packet size.
* 28/May/04 #38 ebradsha Fix unsigned math error in PTP_USB_Write_Timed().
* 28/May/04 #37 ebradsha Fix return math in PTP_USB_Write_Timed() for full packet.
* 27/May/04 #36 bhebeise Return bytes actually sent by PTP_USB_Write_Timed(), commented-out PTP_USB_Write()
* 19/May/04 #35 lee Fix return count for doGetEvent & doGetDeviceStatus
* 19/May/04 #34 lee Fix doSICD_Class() so it will return command data.
* 13/May/04 #33 lee PictBridge has to read device status before STALL is cleared.
* 13/May/04 #32 lee Fix USB STALL code.
* 13/May/04 #31 ebradsha PTP_SND_RCV_DBG for interrupt packet data.
* 26/Apr/04 #30 lee Added versions of PTP read and write routines
* that return after a requested time, even if I/O doesn't take place.
* 21/Apr/04 #29 lee Fix enumeration retry bug; reduce read failure timeout.
* 21/Apr/04 #28 lee Fix NAKlimit setting for interrupt endpoint.
* 21/Apr/04 #27 lee Fix MSCLASS_HOST_PASSTHROUGH array argument errors.
* 13/Apr/04 #26 mrhines Fixed compiler errors when building with -DMSCLASS_HOST_PASSTHROUGH
* 10/Apr/04 #25 ebradsha Retry after failing to enumerate (helps Canon Rebel).
* 10/Apr/04 #24 ebradsha Slow down interrupt polling. (Based on testing with Sanyo, Fuji cameras.)
* 10/Apr/04 #23 ebradsha Now aborts PTP I/O if interrupt endpoint packet received.
* 6/Apr/04 #22 lee Add interrupt poll to PTP reads/writes for Fuji
* 30/Mar/04 #21 lee Added WriteProtected arg to CAMERA_GetMemoryCardStatus(),
* fixed SetInterface[] value.
* 26/Mar/04 #20 ebradsha Change PTP_USB_ReadInterrupt() to indicate NAK, separate from 0 length data.
* 10/Mar/04 #19 lee Fix permissions (remove execute permission)
* 10/Mar/04 #18 lee Fix compiler warnings: ptr argument agreement.
* 23/Feb/04 #17 lee Add support for non-PictBridge device reporting.
* 12/Feb/04 #16 lee Update Passthrough code for
* new ...GetMemoryCardStatus() routines.
* 11/Feb/04 #15 lee Force DMA buffers into non-cachable memory address space.
* 27/Jan/04 #14 lee Move immediately from LISR to HISR; add volatile
* to variables shared between ISR and task levels.
* 26/Jan/04 #13 lee Detected unrecoverable NAK errors; fix reentrancy
* problem in MSCLASS_HOST_PASSTHROUGH mode.
* 23/Jan/04 #12 lee Remove unused MEMORY_CARD_READER reference
* 23/Jan/04 #11 lee Fix EOF errors by increasing SOF_THRESHOLD and
* ignoring EOF errors if they do occur.
* 22/Jan/04 #10 dmerritt New build path. Assume we're doing PictBridge.
* 20/Jan/04 #9 lee Fix MSCLASS_HOST_PASSTHROUGH regression.
* 22/Dec/03 #8 lee PictBridge fix.
* 19/Dec/03 #7 dmerritt Local copy of mydoPictbridge should be static.
* 19/Dec/03 #6 dmerritt Make builds work from the zipped archive.
* 12/Dec/03 #5 lee Fixes for PictBridge
* 11/Dec/03 #4 lee Handle USB errors properly.
* 5/Dec/03 #3 emiller Allow external tuning of task stack sizes and priorities
* 1/Dec/03 #2 lee Moved misplaced endif.
* 26/Nov/03 #1 lee Created.
*
* End of Zoran Standard Header
*/
#ifndef BOOTCODE
#include "univ.gh"
#include "arch.h"
#include "util.h"
#include "pile.h"
#include "dbg.h"
#include "ts.h"
#include "bios.h"
#include "nucleus.h"
#include "oti4100.h"
#include "lstring.h"
#include "propman.h"
#include "usbhost.h"
#include "usb.h"
#include "usbh.h"
#include "usbmass.h"
#ifndef USBH_VERBOSE
#define USBH_VERBOSE 1
#endif
#if USBH_VERBOSE
#define VPRINT PSPRINTF
#else
#define VPRINT if(0)PSPRINTF
#endif
#define _CODE(_rs) ((_rs >> 24) & 255)
#define _ISTATUS(_rs) ((_rs >> 16) & 255)
#define _ERROR(_rs) ((_rs >> 8) & 255)
#define _STATUS(_rs) (_rs & 255)
#ifndef USB_HOST_DEBUG_LOG
#define DEBUG_LOG(_a, _s)
#define DEBUG_DUMP(_a)
#define DUMP_CODE(_a)
#define DBPRINT if(0)PSPRINTF
#else
/******************************************************************************/
/* DEBUG CODE TO LOG INTERRUPTS - not required for normal operation */
#define DBPRINT if(1)PSPRINTF
#define DCODE_CNT 250
Uint32 usb_debug_status[DCODE_CNT];
int usb_debuginx = 0, usb_debugoutx = 0;
static struct {
char *name;
} cn[13] = {
"NCODE ", /* USBH_NOCODE 0 */
"ERROR ", /* USBH_ERROR 1 */
"RESET ", /* USBH_RESET 2 */
"ATTCH ", /* USBH_ATTACH 3 */
"STALL ", /* USBH_STALL 4 */
"INTNAK", /* USBH_INTNAK 5 */
"DONE ", /* USBH_DONE 6 */
"HCAN ", /* USBH_HCAN 7 */
"NAK ", /* USBH_NAK 8 */
"OUT ", /* USBH_OUT 9 */
"IN ", /* USBH_IN 10 */
"OUT0 ", /* USBH_OUT0 11 */
"IN0 " /* USBH_IN0 12 */
};
static void DUMP_CODE(Uint32 rstatus)
{
if (_CODE(rstatus) > 12) {
PSPRINTF("*** %02x %02x %02x %02x\n", _CODE(rstatus),
_ISTATUS(rstatus), _ERROR(rstatus), _STATUS(rstatus));
}
else {
PSPRINTF("%s", cn[_CODE(rstatus)].name);
if (_ISTATUS(rstatus)) {
PSPRINTF(", ISTAT %02x:", _ISTATUS(rstatus));
if (_ISTATUS(rstatus) & 0x01) PSPRINTF(" RST");
if (_ISTATUS(rstatus) & 0x02) PSPRINTF(" ERR");
if (_ISTATUS(rstatus) & 0x04) PSPRINTF(" SOF");
if (_ISTATUS(rstatus) & 0x08) PSPRINTF(" TDN");
if (_ISTATUS(rstatus) & 0x10) PSPRINTF(" SLP");
if (_ISTATUS(rstatus) & 0x40) PSPRINTF(" ATT");
if (_ISTATUS(rstatus) & 0x80) PSPRINTF(" STL");
}
if (_ERROR(rstatus)) {
PSPRINTF(", ERROR %02x:", _ERROR(rstatus));
if (_ERROR(rstatus) & 0x01) PSPRINTF(" PID ERR");
if (_ERROR(rstatus) & 0x02) PSPRINTF(" EOF ERR");
if (_ERROR(rstatus) & 0x04) PSPRINTF(" CRC ERR");
if (_ERROR(rstatus) & 0x08) PSPRINTF(" ALG ERR");
if (_ERROR(rstatus) & 0x10) PSPRINTF(" BUSTURN");
if (_ERROR(rstatus) & 0x20) PSPRINTF(" DMA");
if (_ERROR(rstatus) & 0x40) PSPRINTF(" OWN");
if (_ERROR(rstatus) & 0x80) PSPRINTF(" STUFF");
}
PSPRINTF(" - EP%d %s %s\n", (_STATUS(rstatus) >> 4),
((_STATUS(rstatus) & 8) ? "IN ":"OUT"),
((_STATUS(rstatus) & 4) ? "ODD":"EVN"));
}
}
#define DEBUG_LOG(_a, _s) \
usb_debug_status[usb_debuginx] = (_a << 24) | _s; \
if (++usb_debuginx == DCODE_CNT) \
usb_debuginx = 0; \
if (usb_debuginx == usb_debugoutx) { \
if (--usb_debuginx < 0) \
usb_debuginx = DCODE_CNT - 1; \
}
static void DUMP_CODE_I(Uint32 rstatus)
{
if (_CODE(rstatus) > 12) {
PSPRINTF("*** %02x %02x %02x %02x\n", _CODE(rstatus),
_ISTATUS(rstatus), _ERROR(rstatus), _STATUS(rstatus));
}
else {
PSPRINTF("%s", cn[_CODE(rstatus)].name);
if (_ISTATUS(rstatus)) {
PSPRINTF(", ISTAT %02x:", _ISTATUS(rstatus));
if (_ISTATUS(rstatus) & 0x01) PSPRINTF(" RST");
if (_ISTATUS(rstatus) & 0x02) PSPRINTF(" ERR");
if (_ISTATUS(rstatus) & 0x04) PSPRINTF(" SOF");
if (_ISTATUS(rstatus) & 0x08) PSPRINTF(" TDN");
if (_ISTATUS(rstatus) & 0x10) PSPRINTF(" SLP");
if (_ISTATUS(rstatus) & 0x40) PSPRINTF(" ATT");
if (_ISTATUS(rstatus) & 0x80) PSPRINTF(" STL");
}
if (_ERROR(rstatus)) {
PSPRINTF(", ERROR %02x:", _ERROR(rstatus));
if (_ERROR(rstatus) & 0x01) PSPRINTF(" PID ERR");
if (_ERROR(rstatus) & 0x02) PSPRINTF(" EOF ERR");
if (_ERROR(rstatus) & 0x04) PSPRINTF(" CRC ERR");
if (_ERROR(rstatus) & 0x08) PSPRINTF(" ALG ERR");
if (_ERROR(rstatus) & 0x10) PSPRINTF(" BUSTURN");
if (_ERROR(rstatus) & 0x20) PSPRINTF(" DMA");
if (_ERROR(rstatus) & 0x40) PSPRINTF(" OWN");
if (_ERROR(rstatus) & 0x80) PSPRINTF(" STUFF");
}
PSPRINTF(" - EP%d %s %s\n", (_STATUS(rstatus) >> 4),
((_STATUS(rstatus) & 8) ? "IN ":"OUT"),
((_STATUS(rstatus) & 4) ? "ODD":"EVN"));
}
}
static void DEBUG_DUMP(void)
{
Uint32 rstatus;
while (usb_debugoutx != usb_debuginx) {
rstatus = usb_debug_status[usb_debugoutx];
if (++usb_debugoutx == DCODE_CNT)
usb_debugoutx = 0;
DUMP_CODE_I(rstatus);
}
}
#endif
/* end of debug code */
/******************************************************************************/
/* front-panel flag to tell if power is on or off */
extern int g_powerOn;
extern int g_powerWasOff;
/* Prototype for interrupts off/on functions */
void armIntsOff(void);
void armIntsOn(void);
/* Just turn off ARM chip interrupts for brief protection. */
#define ARM_INTS_OFF armIntsOff();
#define ARM_INTS_ON armIntsOn();
/* For protection over longer periods, only disable the USB interrupt. */
#define USBH_INTS_OFF {armIntsOff();*(unsigned long *)EXMSK1A &=~1;armIntsOn();}
#define USBH_INTS_ON {armIntsOff();*(unsigned long *)EXMSK1A |= 1;armIntsOn();}
#define FS_CTRL_PKCT_SIZE 64
#define FS_BULK_PKCT_SIZE 64
/*
* Start-of-Frame byte-count-times threshold for starting a worst-case
* transfer followed by ACK or NAK without colliding with next SOF.
*/
#define SOF_THRESHOLD 100
#define PIPECNT 4
#define BUFCOUNT (PIPECNT+1) /* 1 buffer for each pipe + 1 control setup */
#define USB_BDT_PAGE ( (Uint32) USB10BDT0REG0 )
#define MEM32_ALIGN(n) (((Uint32)(n)) + (-((Uint32)(n)) & 31))
/* Insertion delay - 100ms. min USB spec.: 9.1.2, #3, pg. 243 */
#define USB_DEBOUNCE_DELAY (105*1000)
static TimeVal debounce_delay = {0, USB_DEBOUNCE_DELAY};
/* Reset delay (TDRSTR) - 50ms. min, USB spec.: 7.1.7.5, pg. 153 */
#define USB_RESET_DELAY (55*1000)
static TimeVal reset_delay = {0, USB_RESET_DELAY};
/* Reset recovery time (TRSTRCY) - 10ms. min, USB spec.: 7.1.7.5, pg. 153 */
#define USB_RESET_RECOVERY_DELAY (15*1000)
static TimeVal recover_delay = {0, USB_RESET_RECOVERY_DELAY};
/* usb_host.state values: */
#define CNTRL_SETUP 1
#define PROCESS_IN 2
#define PROCESS_OUT 3
#define PROCESS_NUL 4
#define CNTRL_LAST 5
#define NO_REQUEST 6
/* usb_host.code values: */
#define USBH_NOCODE 0
#define USBH_ERROR 1
#define USBH_RESET 2
#define USBH_ATTACH 3
#define USBH_STALL 4
#define USBH_INTNAK 5
#define USBH_DONE 6
#define USBH_HCAN 7
#define USBH_NAK 8
#define USBH_OUT 9
#define USBH_IN 10
#define USBH_OUT0 11
#define USBH_IN0 12
#define USBH_INTR 13
/* VUSB Buffer Descriptor Format */
typedef struct {
Uint8 PID; /* 7:own 6:data0/1 5-2:pid 1-0:bch bits */
Uint8 BC; /* Byte Count Low bits */
Uint8 ADDRL;
Uint8 ADDRH;
} BDT_STRUCT;
typedef struct {
Uint8 pipe_type;
Uint8 EP;
Uint8 pksize;
Uint8 type;
Uint8 pid_ep;
Uint8 DATAx;
Uint8 *setup_bf;
Uint8 *pipe_bf;
Uint8 *io_bf;
Uint32 length;
Uint32 count;
Uint32 NAKtime;
Uint32 NAKstart;
BDT_STRUCT *bdt;
} PIPE_STRUCT;
static PIPE_STRUCT pipe[PIPECNT];
#define PIPE_CTL 0
#define PIPE_IN 1
#define PIPE_OUT 2
#define PIPE_INT 3
static Uint32 ipoll_lasttime = 0;
static Uint32 usbhost_poll_msec = 50;
static Uint8 dev_request_buffer[256];
#define BFSIZE_ALLOC (2*(BUFCOUNT+1)*FS_BULK_PKCT_SIZE)
#define BFSIZE (BUFCOUNT*FS_BULK_PKCT_SIZE)
static Uint32 abuffers[(BFSIZE_ALLOC+3)/4];
#define CODE_CNT 4
typedef struct {
volatile PIPE_STRUCT *cur_pipe;
volatile Boolean even_odd_OUT;
volatile Boolean even_odd_IN;
volatile Uint32 state;
volatile Boolean reset_required;
volatile Uint32 USB_addr;
volatile BDT_STRUCT nxt_bdt;
volatile Uint32 code_status_error[CODE_CNT];
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -