Incorrect card recognition
Larry W. Finger
Larry.Finger at lwfinger.net
Fri Oct 3 16:19:39 BST 2003
I have a problem with my Adaptec APA1460B SlimSCSI card. When I start
cardmgr and plug the card in, the system fails to read the CIS and tries to
load memory_cs. If I issue a kill -HUP to cardmgr and replug the card, it
is properly recognized. I have traced the program flow to the point where
the two code streams diverge, but I don't understand what I found and hope
you experts can help. BTW: serial, batch-like debugging is the pits!
First some pertinent details:
Computer: HP ze1115 notebook
Kernel 2.6.0-test6 with Dominic's patches of 9/30
Cardmgr 3.2.4
gcc 3.3.1
PCMCIA configuration section as follows:
#
# PCMCIA/CardBus support
#
CONFIG_PCMCIA=y
CONFIG_YENTA=y
CONFIG_CARDBUS=y
# CONFIG_I82092 is not set
# CONFIG_I82365 is not set
# CONFIG_TCIC is not set
CONFIG_PCMCIA_PROBE=y
I have defined PCMCIA_DEBUG to be 3 in cs, cistpl and ds. The program flow
after plugging the card is as follows:
cs: send_event(sock 0, event 4, pri 0)
ds: ds_event(0x000004, 0, 0xce3ffef8)
ds_poll(socket 0)
ds_read(socket 0)
ds_ioctl(socket 0, 0x8004640b, 0xbfffeab0): cmd = DS_VALIDATE_CIS
pcmcia_validate_cis calls pcmcia_get_first_tuple
pcmcia_get_first_tuple calls read_cis_cache
read_cis_cache calls validate_mem
This is where the two diverge. At the printk statement below, the incorrect
case has force_low, hi and lo all equal to zero, inv_probe is called and
the system does a memory probe from 0xa0000000 to 0xa0ffffff. The correct
case has hi == 1, thus the second part of the if is bypassed and inv_probe
is not called. Here is where I get lost. Why is it necessary to preserve
the values of hi and lo across calls? If hi and lo are not declared static,
the code never works. Is this the case of two wrongs making a right? Please
let me know if you need more information.
Larry
Code fragment follows:
void validate_mem(struct pcmcia_socket *s)
{
resource_map_t *m, mm;
static u_char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
static int hi = 0, lo = 0;
u_long b, i, ok = 0;
int force_low = !(s->features & SS_CAP_PAGE_REGS);
if (!probe_mem)
return;
down(&rsrc_sem);
/* We do up to four passes through the list */
printk(KERN_DEBUG "validate_mem: force_low = %d, hi = %d, lo =
%d\n",force_low,hi,lo);
if (!force_low) {
if (hi++ || (inv_probe(mem_db.next, s) > 0))
goto out;
printk(KERN_NOTICE "cs: warning: no high memory space "
"available!\n");
}
More information about the linux-pcmcia
mailing list