[Bug 4115] New: i82635_init hangs if first call to pcmcia_register_socket fails

bugme-daemon at osdl.org bugme-daemon at osdl.org
Thu Jan 27 16:45:34 EST 2005


http://bugme.osdl.org/show_bug.cgi?id=4115

           Summary: i82635_init hangs if first call to
                    pcmcia_register_socket fails
    Kernel Version: 2.6.7
            Status: NEW
          Severity: normal
             Owner: linux-pcmcia at lists.infradead.org
         Submitter: daveh at dmh2000.com


Distribution: NA
Hardware Environment: Diamond Systems Hercules CPU board (Via Eden)
Software Environment: 2.6.7 kernel, i82635.c driver
Problem Description:

in the function i82635.c::i82635_init, there is a loop that registers all the
PCMCIA sockets with the cs core. The loop has a condition where if a call to
pcmcia_register_socket fails, it tries to deregister all the sockets that were
already registered, and then exits the loop. However, because of the way the
loop and fail conditions are coded, if the FIRST call to pcmcia_register_socket
fails, then the loop will never terminate. This is because the first iteration
has a socket index 'i' equal to 0.


static int __init init_i82365(void)
{
    int i, ret;

...other stuff
    
    /* register sockets with the pcmcia core */
    for (i = 0; i < sockets; i++) {
	    socket[i].socket.dev.dev = &i82365_device.dev;
	    socket[i].socket.ops = &pcic_operations;
	    socket[i].socket.owner = THIS_MODULE;
	    socket[i].number = i;
	    ret = pcmcia_register_socket(&socket[i].socket);	    
========>   if (ret && i--) {
========> this condition fails if 'i' == 0 !!!
		    for (; i>= 0; i--)
			    pcmcia_unregister_socket(&socket[i].socket);
		    break;
	    }
#if 0 /* driver model ordering issue */
	   class_device_create_file(&socket[i].socket.dev,
			   	    &class_device_attr_info);
	   class_device_create_file(&socket[i].socket.dev,
			   	    &class_device_attr_exca);
#endif
    }
...other stuff
    
    return 0;
    
} /* init_i82365 */


ANALYSIS:

if (ret && i--) {

the problem is that when ret != 0 (register_socket failed) AND i == 0 (first
socket), the 'if' condition is false because i == 0, and so it doesn't go to the
deregister and break. however the postdecrement of 'i' still happens, so that i
is set to -1. This screws up the loop counter so that it repeats again with i ==
0, and it continues forevever.


Steps to reproduce:
build with pcmcia support, and the i82635 module.
set up some pcmcia hardware, modify pcmcia_register_socket to always return
nonzero (indicating it failed) and do "insmod i82635.ko". it will hang. put some
printk's in the loop and it will show that it is repeating.

FIX : restructure that loop and avoid the side effect on 'i'.

------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.



More information about the linux-pcmcia mailing list