全部博文(58)
分类: LINUX
2009-06-01 12:35:11
e100_eeprom.c 里面的一个函数:
//------------------------------------------------------------------------------------
----
// Procedure: e100_eeprom_size
//
// Description: This routine determines the size of the EEPROM. This value should be
// checked for validity - ie. is it too big or too small. The size
returned
// is then passed to the read/write functions.
//
// Returns:
// Size of the eeprom, or zero if an error occurred
//------------------------------------------------------------------------------------
----
u16
e100_eeprom_size(struct e100_private *adapter)
{
u16 x, size = 1; // must be one to accumulate a product
// if we've already stored this data, read from memory
if (adapter->eeprom_size) {
return adapter->eeprom_size;
}
// otherwise, read from the eeprom
// Set EEPROM semaphore.
if (adapter->rev_id >= D102_REV_ID) {
if (!eeprom_set_semaphore(adapter))
return 0;
}
// enable the eeprom by setting EECS.
x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
x &= ~(EEDI | EEDO | EESK);
x |= EECS;
writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
// write the read opcode
shift_out_bits(adapter, EEPROM_READ_OPCODE, 3);
// experiment to discover the size of the eeprom. request register zero
// and wait for the eeprom to tell us it has accepted the entire address.
x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
do {
size *= 2; // each bit of address doubles eeprom size
x |= EEDO; // set bit to detect "dummy zero"
x &= ~EEDI; // address consists of all zeros
writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
readw(&(adapter->scb->scb_status));
udelay(EEPROM_STALL_TIME);//udaly (4)
raise_clock(adapter, &x);
lower_clock(adapter, &x);
// check for "dummy zero"
x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
if (size > EEPROM_MAX_WORD_SIZE) {
size = 0;
break;
}
} while (x & EEDO);
// read in the value requested
(void) shift_in_bits(adapter);
e100_eeprom_cleanup(adapter);
// Clear EEPROM Semaphore.
if (adapter->rev_id >= D102_REV_ID) {
eeprom_reset_semaphore(adapter);
}
return size;
}
23 22 21 20 19 18 17 16
X X X X EEDO EEDI EECS EESK
当我们在学习 别人的driver的时候, 发现 在定义寄存器地址的时候都是这样定义的:
比如:
#define EN_TRNF 0x10 /* Enable turnoff */
#define EEDO 0x08 /* EEPROM data out */
#define EEDI 0x04 /* EEPROM data in (set for writing data) */
#define EECS 0x02 /* EEPROM chip select (1=hi, 0=lo) */
#define EESK 0x01 /* EEPROM shift clock (1=hi, 0=lo) */
我们看出来 , 如果从0开始排 , EEDO EEDI EECS EESK
0x08 0x04 0x02 0x01
所以就对应上了 。
// enable the eeprom by setting EECS. 把EECS 置为1
x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
x &= ~(EEDI | EEDO | EESK); //把这三位都置为 0 ,EECS不动 ,
//0x8 | 0x4 | 0x1 , 1101 ,
x |= EECS; // 把EECS的位置为 1
writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
when copy the file into USB Harddisk , some error messages will pop up ,
ehci_hcd 00:01.2: fatal error
Unable to handle kernel NULL pointer dereference at virtual address 00000000
it is printed by a sheet of code
/* unrequested/ignored: Port Change Detect, Frame List Rollover */
dbg_status (ehci, "irq", status); // print the status of USBSTS Register
....................................
/* PCI errors [4.15.2.4] */
if (unlikely ((status & STS_FATAL) != 0)) { //STS_FATAL : 1<<4
ehci_err (ehci, "fatal error
"); //will print "ehci_hcd 00:01.2: fatal error"
...........................................
// ----------------------------------STS_FATAL Define
-----------------------------------
/* USBSTS: offset 0x04 */
u32 status;
#define STS_ASS (1<<15) /* Async Schedule Status */
#define STS_PSS (1<<14) /* Periodic Schedule Status */
#define STS_RECL (1<<13) /* Reclamation */
#define STS_HALT (1<<12) /* Not running (any reason) */
/* some bits reserved */
/* these STS_* flags are also intr_enable bits (USBINTR) */
#define STS_IAA (1<<5) /* Interrupted on async advance */
#define STS_FATAL (1<<4) /* such as some PCI access errors */
#define STS_FLR (1<<3) /* frame list rolled over */
#define STS_PCD (1<<2) /* port change detect */
#define STS_ERR (1<<1) /* "error" completion (overflow, ...) */
#define STS_INT (1<<0) /* "normal" completion (short, ...) */
//
--------------------------------------------------------------------------------------
I find EHCI 1.0 datasheet(VT6212L declare that he is compliant with Enhanced Host
Controller Interface Specification Revision 1.0)
there is some info about STS_FATAL in 2.3.2 USBSTS USB Status Register of Page 31
bit 4
Host System Error . R/WC. The Host Controller sets this bit to 1 when a serious
error
occurs during a host system access involving the Host Controller module. In a PCI
system, conditions that set this bit to 1 include PCI Parity error, PCI Master Abort,
and
PCI Target Abort. When this error occurs, the Host Controller clears the Run/Stop bit
in
the Command register to prevent further execution of the scheduled TDs.
这样的话, 我们基本可以定位问题, 知道问题出在了哪里 。、