in cs.c [103:198]
int pcmcia_register_socket(struct pcmcia_socket *socket)
{
struct task_struct *tsk;
int ret;
if (!socket || !socket->ops || !socket->dev.parent || !socket->resource_ops)
return -EINVAL;
dev_dbg(&socket->dev, "pcmcia_register_socket(0x%p)\n", socket->ops);
/* try to obtain a socket number [yes, it gets ugly if we
* register more than 2^sizeof(unsigned int) pcmcia
* sockets... but the socket number is deprecated
* anyways, so I don't care] */
down_write(&pcmcia_socket_list_rwsem);
if (list_empty(&pcmcia_socket_list))
socket->sock = 0;
else {
unsigned int found, i = 1;
struct pcmcia_socket *tmp;
do {
found = 1;
list_for_each_entry(tmp, &pcmcia_socket_list, socket_list) {
if (tmp->sock == i)
found = 0;
}
i++;
} while (!found);
socket->sock = i - 1;
}
list_add_tail(&socket->socket_list, &pcmcia_socket_list);
up_write(&pcmcia_socket_list_rwsem);
#ifndef CONFIG_CARDBUS
/*
* If we do not support Cardbus, ensure that
* the Cardbus socket capability is disabled.
*/
socket->features &= ~SS_CAP_CARDBUS;
#endif
/* set proper values in socket->dev */
dev_set_drvdata(&socket->dev, socket);
socket->dev.class = &pcmcia_socket_class;
dev_set_name(&socket->dev, "pcmcia_socket%u", socket->sock);
/* base address = 0, map = 0 */
socket->cis_mem.flags = 0;
socket->cis_mem.speed = cis_speed;
INIT_LIST_HEAD(&socket->cis_cache);
init_completion(&socket->socket_released);
init_completion(&socket->thread_done);
mutex_init(&socket->skt_mutex);
mutex_init(&socket->ops_mutex);
spin_lock_init(&socket->thread_lock);
if (socket->resource_ops->init) {
mutex_lock(&socket->ops_mutex);
ret = socket->resource_ops->init(socket);
mutex_unlock(&socket->ops_mutex);
if (ret)
goto err;
}
tsk = kthread_run(pccardd, socket, "pccardd");
if (IS_ERR(tsk)) {
ret = PTR_ERR(tsk);
goto err;
}
wait_for_completion(&socket->thread_done);
if (!socket->thread) {
dev_warn(&socket->dev,
"PCMCIA: warning: socket thread did not start\n");
return -EIO;
}
pcmcia_parse_events(socket, SS_DETECT);
/*
* Let's try to get the PCMCIA module for 16-bit PCMCIA support.
* If it fails, it doesn't matter -- we still have 32-bit CardBus
* support to offer, so this is not a failure mode.
*/
request_module_nowait("pcmcia");
return 0;
err:
down_write(&pcmcia_socket_list_rwsem);
list_del(&socket->socket_list);
up_write(&pcmcia_socket_list_rwsem);
return ret;
} /* pcmcia_register_socket */