goto err;
wait_for_completion(&socket->thread_done);
- BUG_ON(!socket->thread);
+ if(!socket->thread) {
+ printk(KERN_WARNING "PCMCIA: warning: socket thread for socket %p did not start\n", socket);
+ return -EIO;
+ }
pcmcia_parse_events(socket, SS_DETECT);
return 0;
int ret;
daemonize("pccardd");
- skt->thread = current;
- complete(&skt->thread_done);
+ skt->thread = current;
skt->socket = dead_socket;
skt->ops->init(skt);
skt->ops->set_socket(skt, &skt->socket);
if (ret) {
printk(KERN_WARNING "PCMCIA: unable to register socket 0x%p\n",
skt);
+ skt->thread = NULL;
+ complete_and_exit(&skt->thread_done, 0);
}
+ complete(&skt->thread_done);
add_wait_queue(&skt->thread_wait, &wait);
for (;;) {
if (w == MAX_WIN)
return CS_NO_MORE_ITEMS;
win = &s->win[w];
- req->Base = win->ctl.sys_start;
- req->Size = win->ctl.sys_stop - win->ctl.sys_start + 1;
+ req->Base = win->ctl.res->start;
+ req->Size = win->ctl.res->end - win->ctl.res->start + 1;
req->AccessSpeed = win->ctl.speed;
req->Attributes = 0;
if (win->ctl.flags & MAP_ATTRIB)
s->state &= ~SOCKET_WIN_REQ(win->index);
/* Release system memory */
- if(!(s->features & SS_CAP_STATIC_MAP))
- release_mem_region(win->base, win->size);
+ if (win->ctl.res) {
+ release_resource(win->ctl.res);
+ kfree(win->ctl.res);
+ win->ctl.res = NULL;
+ }
win->handle->state &= ~CLIENT_WIN_REQ(win->index);
win->magic = 0;
win->index = w;
win->handle = *handle;
win->sock = s;
- win->base = req->Base;
- win->size = req->Size;
- if (!(s->features & SS_CAP_STATIC_MAP) &&
- find_mem_region(&win->base, win->size, align,
- (req->Attributes & WIN_MAP_BELOW_1MB),
- (*handle)->dev_info, s))
- return CS_IN_USE;
+ if (!(s->features & SS_CAP_STATIC_MAP)) {
+ win->ctl.res = find_mem_region(req->Base, req->Size, align,
+ (req->Attributes & WIN_MAP_BELOW_1MB),
+ (*handle)->dev_info, s);
+ if (!win->ctl.res)
+ return CS_IN_USE;
+ win->ctl.sys_start = win->ctl.res->start;
+ win->ctl.sys_stop = win->ctl.res->end;
+ } else {
+ win->ctl.sys_start = req->Base;
+ win->ctl.sys_stop = req->Base + req->Size - 1;
+ }
(*handle)->state |= CLIENT_WIN_REQ(w);
/* Configure the socket controller */
win->ctl.flags |= MAP_16BIT;
if (req->Attributes & WIN_USE_WAIT)
win->ctl.flags |= MAP_USE_WAIT;
- win->ctl.sys_start = win->base;
- win->ctl.sys_stop = win->base + win->size-1;
win->ctl.card_start = 0;
if (s->ops->set_mem_map(s, &win->ctl) != 0)
return CS_BAD_ARGS;
down(&skt->skt_sem);
do {
if (!(skt->state & SOCKET_PRESENT)) {
- ret = CS_NO_CARD;
+ ret = -ENODEV;
break;
}
ret = send_event(skt, CS_EVENT_EJECTION_REQUEST, CS_EVENT_PRI_LOW);
- if (ret != 0)
+ if (ret != 0) {
+ ret = -EINVAL;
break;
+ }
socket_remove(skt);
- ret = CS_SUCCESS;
+ ret = 0;
} while (0);
up(&skt->skt_sem);
down(&skt->skt_sem);
do {
if (skt->state & SOCKET_PRESENT) {
- ret = CS_IN_USE;
+ ret = -EBUSY;
break;
}
if (socket_insert(skt) == CS_NO_CARD) {
- ret = CS_NO_CARD;
+ ret = -ENODEV;
break;
}
- ret = CS_SUCCESS;
+ ret = 0;
} while (0);
up(&skt->skt_sem);
static int __init init_pcmcia_cs(void)
{
- printk(KERN_INFO "%s\n", release);
- printk(KERN_INFO " %s\n", options);
+ int ret;
+ printk(KERN_INFO "%s\n", release);
+ printk(KERN_INFO " %s\n", options);
- return class_register(&pcmcia_socket_class);
+ ret = class_register(&pcmcia_socket_class);
+ if (ret)
+ return (ret);
+ return class_interface_register(&pccard_sysfs_interface);
}
static void __exit exit_pcmcia_cs(void)
{
printk(KERN_INFO "unloading Kernel Card Services\n");
release_resource_db();
+ class_interface_unregister(&pccard_sysfs_interface);
class_unregister(&pcmcia_socket_class);
}