[PATCH] pcmcia: use mutexes instead of semaphores
Use mutexes in the PCMICA core, as they suffice for what needs to be done. Includes a bugfix from and Signed-off-by Andrew Morton. Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
This commit is contained in:
parent
cbbddd1046
commit
7fe908dd11
@ -111,9 +111,9 @@ int pcmcia_socket_dev_suspend(struct device *dev, pm_message_t state)
|
|||||||
list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
|
list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
|
||||||
if (socket->dev.dev != dev)
|
if (socket->dev.dev != dev)
|
||||||
continue;
|
continue;
|
||||||
down(&socket->skt_sem);
|
mutex_lock(&socket->skt_mutex);
|
||||||
socket_suspend(socket);
|
socket_suspend(socket);
|
||||||
up(&socket->skt_sem);
|
mutex_unlock(&socket->skt_mutex);
|
||||||
}
|
}
|
||||||
up_read(&pcmcia_socket_list_rwsem);
|
up_read(&pcmcia_socket_list_rwsem);
|
||||||
|
|
||||||
@ -129,9 +129,9 @@ int pcmcia_socket_dev_resume(struct device *dev)
|
|||||||
list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
|
list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
|
||||||
if (socket->dev.dev != dev)
|
if (socket->dev.dev != dev)
|
||||||
continue;
|
continue;
|
||||||
down(&socket->skt_sem);
|
mutex_lock(&socket->skt_mutex);
|
||||||
socket_resume(socket);
|
socket_resume(socket);
|
||||||
up(&socket->skt_sem);
|
mutex_unlock(&socket->skt_mutex);
|
||||||
}
|
}
|
||||||
up_read(&pcmcia_socket_list_rwsem);
|
up_read(&pcmcia_socket_list_rwsem);
|
||||||
|
|
||||||
@ -237,7 +237,7 @@ int pcmcia_register_socket(struct pcmcia_socket *socket)
|
|||||||
init_completion(&socket->socket_released);
|
init_completion(&socket->socket_released);
|
||||||
init_completion(&socket->thread_done);
|
init_completion(&socket->thread_done);
|
||||||
init_waitqueue_head(&socket->thread_wait);
|
init_waitqueue_head(&socket->thread_wait);
|
||||||
init_MUTEX(&socket->skt_sem);
|
mutex_init(&socket->skt_mutex);
|
||||||
spin_lock_init(&socket->thread_lock);
|
spin_lock_init(&socket->thread_lock);
|
||||||
|
|
||||||
ret = kernel_thread(pccardd, socket, CLONE_KERNEL);
|
ret = kernel_thread(pccardd, socket, CLONE_KERNEL);
|
||||||
@ -662,7 +662,7 @@ static int pccardd(void *__skt)
|
|||||||
spin_unlock_irqrestore(&skt->thread_lock, flags);
|
spin_unlock_irqrestore(&skt->thread_lock, flags);
|
||||||
|
|
||||||
if (events) {
|
if (events) {
|
||||||
down(&skt->skt_sem);
|
mutex_lock(&skt->skt_mutex);
|
||||||
if (events & SS_DETECT)
|
if (events & SS_DETECT)
|
||||||
socket_detect_change(skt);
|
socket_detect_change(skt);
|
||||||
if (events & SS_BATDEAD)
|
if (events & SS_BATDEAD)
|
||||||
@ -671,7 +671,7 @@ static int pccardd(void *__skt)
|
|||||||
send_event(skt, CS_EVENT_BATTERY_LOW, CS_EVENT_PRI_LOW);
|
send_event(skt, CS_EVENT_BATTERY_LOW, CS_EVENT_PRI_LOW);
|
||||||
if (events & SS_READY)
|
if (events & SS_READY)
|
||||||
send_event(skt, CS_EVENT_READY_CHANGE, CS_EVENT_PRI_LOW);
|
send_event(skt, CS_EVENT_READY_CHANGE, CS_EVENT_PRI_LOW);
|
||||||
up(&skt->skt_sem);
|
mutex_unlock(&skt->skt_mutex);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -715,8 +715,8 @@ int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c)
|
|||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
/* s->skt_sem also protects s->callback */
|
/* s->skt_mutex also protects s->callback */
|
||||||
down(&s->skt_sem);
|
mutex_lock(&s->skt_mutex);
|
||||||
|
|
||||||
if (c) {
|
if (c) {
|
||||||
/* registration */
|
/* registration */
|
||||||
@ -732,7 +732,7 @@ int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c)
|
|||||||
} else
|
} else
|
||||||
s->callback = NULL;
|
s->callback = NULL;
|
||||||
err:
|
err:
|
||||||
up(&s->skt_sem);
|
mutex_unlock(&s->skt_mutex);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -750,7 +750,7 @@ int pccard_reset_card(struct pcmcia_socket *skt)
|
|||||||
|
|
||||||
cs_dbg(skt, 1, "resetting socket\n");
|
cs_dbg(skt, 1, "resetting socket\n");
|
||||||
|
|
||||||
down(&skt->skt_sem);
|
mutex_lock(&skt->skt_mutex);
|
||||||
do {
|
do {
|
||||||
if (!(skt->state & SOCKET_PRESENT)) {
|
if (!(skt->state & SOCKET_PRESENT)) {
|
||||||
ret = CS_NO_CARD;
|
ret = CS_NO_CARD;
|
||||||
@ -779,7 +779,7 @@ int pccard_reset_card(struct pcmcia_socket *skt)
|
|||||||
|
|
||||||
ret = CS_SUCCESS;
|
ret = CS_SUCCESS;
|
||||||
} while (0);
|
} while (0);
|
||||||
up(&skt->skt_sem);
|
mutex_unlock(&skt->skt_mutex);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
} /* reset_card */
|
} /* reset_card */
|
||||||
@ -795,7 +795,7 @@ int pcmcia_suspend_card(struct pcmcia_socket *skt)
|
|||||||
|
|
||||||
cs_dbg(skt, 1, "suspending socket\n");
|
cs_dbg(skt, 1, "suspending socket\n");
|
||||||
|
|
||||||
down(&skt->skt_sem);
|
mutex_lock(&skt->skt_mutex);
|
||||||
do {
|
do {
|
||||||
if (!(skt->state & SOCKET_PRESENT)) {
|
if (!(skt->state & SOCKET_PRESENT)) {
|
||||||
ret = CS_NO_CARD;
|
ret = CS_NO_CARD;
|
||||||
@ -812,7 +812,7 @@ int pcmcia_suspend_card(struct pcmcia_socket *skt)
|
|||||||
}
|
}
|
||||||
ret = socket_suspend(skt);
|
ret = socket_suspend(skt);
|
||||||
} while (0);
|
} while (0);
|
||||||
up(&skt->skt_sem);
|
mutex_unlock(&skt->skt_mutex);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
} /* suspend_card */
|
} /* suspend_card */
|
||||||
@ -825,7 +825,7 @@ int pcmcia_resume_card(struct pcmcia_socket *skt)
|
|||||||
|
|
||||||
cs_dbg(skt, 1, "waking up socket\n");
|
cs_dbg(skt, 1, "waking up socket\n");
|
||||||
|
|
||||||
down(&skt->skt_sem);
|
mutex_lock(&skt->skt_mutex);
|
||||||
do {
|
do {
|
||||||
if (!(skt->state & SOCKET_PRESENT)) {
|
if (!(skt->state & SOCKET_PRESENT)) {
|
||||||
ret = CS_NO_CARD;
|
ret = CS_NO_CARD;
|
||||||
@ -839,7 +839,7 @@ int pcmcia_resume_card(struct pcmcia_socket *skt)
|
|||||||
if (!ret && skt->callback)
|
if (!ret && skt->callback)
|
||||||
skt->callback->resume(skt);
|
skt->callback->resume(skt);
|
||||||
} while (0);
|
} while (0);
|
||||||
up(&skt->skt_sem);
|
mutex_unlock(&skt->skt_mutex);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
} /* resume_card */
|
} /* resume_card */
|
||||||
@ -853,7 +853,7 @@ int pcmcia_eject_card(struct pcmcia_socket *skt)
|
|||||||
|
|
||||||
cs_dbg(skt, 1, "user eject request\n");
|
cs_dbg(skt, 1, "user eject request\n");
|
||||||
|
|
||||||
down(&skt->skt_sem);
|
mutex_lock(&skt->skt_mutex);
|
||||||
do {
|
do {
|
||||||
if (!(skt->state & SOCKET_PRESENT)) {
|
if (!(skt->state & SOCKET_PRESENT)) {
|
||||||
ret = -ENODEV;
|
ret = -ENODEV;
|
||||||
@ -869,7 +869,7 @@ int pcmcia_eject_card(struct pcmcia_socket *skt)
|
|||||||
socket_remove(skt);
|
socket_remove(skt);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
} while (0);
|
} while (0);
|
||||||
up(&skt->skt_sem);
|
mutex_unlock(&skt->skt_mutex);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
} /* eject_card */
|
} /* eject_card */
|
||||||
@ -882,7 +882,7 @@ int pcmcia_insert_card(struct pcmcia_socket *skt)
|
|||||||
|
|
||||||
cs_dbg(skt, 1, "user insert request\n");
|
cs_dbg(skt, 1, "user insert request\n");
|
||||||
|
|
||||||
down(&skt->skt_sem);
|
mutex_lock(&skt->skt_mutex);
|
||||||
do {
|
do {
|
||||||
if (skt->state & SOCKET_PRESENT) {
|
if (skt->state & SOCKET_PRESENT) {
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
@ -894,7 +894,7 @@ int pcmcia_insert_card(struct pcmcia_socket *skt)
|
|||||||
}
|
}
|
||||||
ret = 0;
|
ret = 0;
|
||||||
} while (0);
|
} while (0);
|
||||||
up(&skt->skt_sem);
|
mutex_unlock(&skt->skt_mutex);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
} /* insert_card */
|
} /* insert_card */
|
||||||
|
@ -564,7 +564,7 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev)
|
|||||||
* won't work, this doesn't matter much at the moment: the driver core doesn't
|
* won't work, this doesn't matter much at the moment: the driver core doesn't
|
||||||
* support it either.
|
* support it either.
|
||||||
*/
|
*/
|
||||||
static DECLARE_MUTEX(device_add_lock);
|
static DEFINE_MUTEX(device_add_lock);
|
||||||
|
|
||||||
struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int function)
|
struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int function)
|
||||||
{
|
{
|
||||||
@ -576,7 +576,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
|
|||||||
if (!s)
|
if (!s)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
down(&device_add_lock);
|
mutex_lock(&device_add_lock);
|
||||||
|
|
||||||
/* max of 2 devices per card */
|
/* max of 2 devices per card */
|
||||||
if (s->device_count == 2)
|
if (s->device_count == 2)
|
||||||
@ -640,7 +640,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
|
|||||||
if (device_register(&p_dev->dev))
|
if (device_register(&p_dev->dev))
|
||||||
goto err_unreg;
|
goto err_unreg;
|
||||||
|
|
||||||
up(&device_add_lock);
|
mutex_unlock(&device_add_lock);
|
||||||
|
|
||||||
return p_dev;
|
return p_dev;
|
||||||
|
|
||||||
@ -654,7 +654,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
|
|||||||
kfree(p_dev);
|
kfree(p_dev);
|
||||||
s->device_count--;
|
s->device_count--;
|
||||||
err_put:
|
err_put:
|
||||||
up(&device_add_lock);
|
mutex_unlock(&device_add_lock);
|
||||||
pcmcia_put_socket(s);
|
pcmcia_put_socket(s);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -713,7 +713,7 @@ static void pcmcia_bus_rescan(struct pcmcia_socket *skt)
|
|||||||
int no_devices=0;
|
int no_devices=0;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
/* must be called with skt_sem held */
|
/* must be called with skt_mutex held */
|
||||||
spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
|
spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
|
||||||
if (list_empty(&skt->devices_list))
|
if (list_empty(&skt->devices_list))
|
||||||
no_devices=1;
|
no_devices=1;
|
||||||
@ -999,9 +999,9 @@ static ssize_t pcmcia_store_allow_func_id_match(struct device *dev,
|
|||||||
if (!count)
|
if (!count)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
down(&p_dev->socket->skt_sem);
|
mutex_lock(&p_dev->socket->skt_mutex);
|
||||||
p_dev->allow_func_id_match = 1;
|
p_dev->allow_func_id_match = 1;
|
||||||
up(&p_dev->socket->skt_sem);
|
mutex_unlock(&p_dev->socket->skt_mutex);
|
||||||
|
|
||||||
bus_rescan_devices(&pcmcia_bus_type);
|
bus_rescan_devices(&pcmcia_bus_type);
|
||||||
|
|
||||||
|
@ -269,9 +269,9 @@ rescan:
|
|||||||
/*
|
/*
|
||||||
* Prevent this racing with a card insertion.
|
* Prevent this racing with a card insertion.
|
||||||
*/
|
*/
|
||||||
down(&s->skt_sem);
|
mutex_lock(&s->skt_mutex);
|
||||||
bus_rescan_devices(&pcmcia_bus_type);
|
bus_rescan_devices(&pcmcia_bus_type);
|
||||||
up(&s->skt_sem);
|
mutex_unlock(&s->skt_mutex);
|
||||||
|
|
||||||
/* check whether the driver indeed matched. I don't care if this
|
/* check whether the driver indeed matched. I don't care if this
|
||||||
* is racy or not, because it can only happen on cardmgr access
|
* is racy or not, because it can only happen on cardmgr access
|
||||||
@ -606,9 +606,9 @@ static int ds_ioctl(struct inode * inode, struct file * file,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DS_GET_FIRST_TUPLE:
|
case DS_GET_FIRST_TUPLE:
|
||||||
down(&s->skt_sem);
|
mutex_lock(&s->skt_mutex);
|
||||||
pcmcia_validate_mem(s);
|
pcmcia_validate_mem(s);
|
||||||
up(&s->skt_sem);
|
mutex_unlock(&s->skt_mutex);
|
||||||
ret = pccard_get_first_tuple(s, BIND_FN_ALL, &buf->tuple);
|
ret = pccard_get_first_tuple(s, BIND_FN_ALL, &buf->tuple);
|
||||||
break;
|
break;
|
||||||
case DS_GET_NEXT_TUPLE:
|
case DS_GET_NEXT_TUPLE:
|
||||||
@ -637,9 +637,9 @@ static int ds_ioctl(struct inode * inode, struct file * file,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DS_VALIDATE_CIS:
|
case DS_VALIDATE_CIS:
|
||||||
down(&s->skt_sem);
|
mutex_lock(&s->skt_mutex);
|
||||||
pcmcia_validate_mem(s);
|
pcmcia_validate_mem(s);
|
||||||
up(&s->skt_sem);
|
mutex_unlock(&s->skt_mutex);
|
||||||
ret = pccard_validate_cis(s, BIND_FN_ALL, &buf->cisinfo);
|
ret = pccard_validate_cis(s, BIND_FN_ALL, &buf->cisinfo);
|
||||||
break;
|
break;
|
||||||
case DS_SUSPEND_CARD:
|
case DS_SUSPEND_CARD:
|
||||||
|
@ -61,7 +61,7 @@ struct socket_data {
|
|||||||
unsigned int rsrc_mem_probe;
|
unsigned int rsrc_mem_probe;
|
||||||
};
|
};
|
||||||
|
|
||||||
static DECLARE_MUTEX(rsrc_sem);
|
static DEFINE_MUTEX(rsrc_mutex);
|
||||||
#define MEM_PROBE_LOW (1 << 0)
|
#define MEM_PROBE_LOW (1 << 0)
|
||||||
#define MEM_PROBE_HIGH (1 << 1)
|
#define MEM_PROBE_HIGH (1 << 1)
|
||||||
|
|
||||||
@ -484,7 +484,7 @@ static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Locking note: Must be called with skt_sem held!
|
* Locking note: Must be called with skt_mutex held!
|
||||||
*/
|
*/
|
||||||
static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
|
static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
|
||||||
{
|
{
|
||||||
@ -495,7 +495,7 @@ static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
|
|||||||
if (!probe_mem)
|
if (!probe_mem)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
down(&rsrc_sem);
|
mutex_lock(&rsrc_mutex);
|
||||||
|
|
||||||
if (s->features & SS_CAP_PAGE_REGS)
|
if (s->features & SS_CAP_PAGE_REGS)
|
||||||
probe_mask = MEM_PROBE_HIGH;
|
probe_mask = MEM_PROBE_HIGH;
|
||||||
@ -507,7 +507,7 @@ static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
|
|||||||
s_data->rsrc_mem_probe |= probe_mask;
|
s_data->rsrc_mem_probe |= probe_mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
up(&rsrc_sem);
|
mutex_unlock(&rsrc_mutex);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -585,7 +585,7 @@ static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_star
|
|||||||
struct socket_data *s_data = s->resource_data;
|
struct socket_data *s_data = s->resource_data;
|
||||||
int ret = -ENOMEM;
|
int ret = -ENOMEM;
|
||||||
|
|
||||||
down(&rsrc_sem);
|
mutex_lock(&rsrc_mutex);
|
||||||
for (m = s_data->io_db.next; m != &s_data->io_db; m = m->next) {
|
for (m = s_data->io_db.next; m != &s_data->io_db; m = m->next) {
|
||||||
unsigned long start = m->base;
|
unsigned long start = m->base;
|
||||||
unsigned long end = m->base + m->num - 1;
|
unsigned long end = m->base + m->num - 1;
|
||||||
@ -596,7 +596,7 @@ static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_star
|
|||||||
ret = adjust_resource(res, r_start, r_end - r_start + 1);
|
ret = adjust_resource(res, r_start, r_end - r_start + 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
up(&rsrc_sem);
|
mutex_unlock(&rsrc_mutex);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -630,7 +630,7 @@ static struct resource *nonstatic_find_io_region(unsigned long base, int num,
|
|||||||
data.offset = base & data.mask;
|
data.offset = base & data.mask;
|
||||||
data.map = &s_data->io_db;
|
data.map = &s_data->io_db;
|
||||||
|
|
||||||
down(&rsrc_sem);
|
mutex_lock(&rsrc_mutex);
|
||||||
#ifdef CONFIG_PCI
|
#ifdef CONFIG_PCI
|
||||||
if (s->cb_dev) {
|
if (s->cb_dev) {
|
||||||
ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
|
ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
|
||||||
@ -639,7 +639,7 @@ static struct resource *nonstatic_find_io_region(unsigned long base, int num,
|
|||||||
#endif
|
#endif
|
||||||
ret = allocate_resource(&ioport_resource, res, num, min, ~0UL,
|
ret = allocate_resource(&ioport_resource, res, num, min, ~0UL,
|
||||||
1, pcmcia_align, &data);
|
1, pcmcia_align, &data);
|
||||||
up(&rsrc_sem);
|
mutex_unlock(&rsrc_mutex);
|
||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
kfree(res);
|
kfree(res);
|
||||||
@ -672,7 +672,7 @@ static struct resource * nonstatic_find_mem_region(u_long base, u_long num,
|
|||||||
min = 0x100000UL + base;
|
min = 0x100000UL + base;
|
||||||
}
|
}
|
||||||
|
|
||||||
down(&rsrc_sem);
|
mutex_lock(&rsrc_mutex);
|
||||||
#ifdef CONFIG_PCI
|
#ifdef CONFIG_PCI
|
||||||
if (s->cb_dev) {
|
if (s->cb_dev) {
|
||||||
ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num,
|
ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num,
|
||||||
@ -682,7 +682,7 @@ static struct resource * nonstatic_find_mem_region(u_long base, u_long num,
|
|||||||
#endif
|
#endif
|
||||||
ret = allocate_resource(&iomem_resource, res, num, min,
|
ret = allocate_resource(&iomem_resource, res, num, min,
|
||||||
max, 1, pcmcia_align, &data);
|
max, 1, pcmcia_align, &data);
|
||||||
up(&rsrc_sem);
|
mutex_unlock(&rsrc_mutex);
|
||||||
if (ret == 0 || low)
|
if (ret == 0 || low)
|
||||||
break;
|
break;
|
||||||
low = 1;
|
low = 1;
|
||||||
@ -705,7 +705,7 @@ static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned
|
|||||||
if (end < start)
|
if (end < start)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
down(&rsrc_sem);
|
mutex_lock(&rsrc_mutex);
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case ADD_MANAGED_RESOURCE:
|
case ADD_MANAGED_RESOURCE:
|
||||||
ret = add_interval(&data->mem_db, start, size);
|
ret = add_interval(&data->mem_db, start, size);
|
||||||
@ -723,7 +723,7 @@ static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned
|
|||||||
default:
|
default:
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
}
|
}
|
||||||
up(&rsrc_sem);
|
mutex_unlock(&rsrc_mutex);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -741,7 +741,7 @@ static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long
|
|||||||
if (end > IO_SPACE_LIMIT)
|
if (end > IO_SPACE_LIMIT)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
down(&rsrc_sem);
|
mutex_lock(&rsrc_mutex);
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case ADD_MANAGED_RESOURCE:
|
case ADD_MANAGED_RESOURCE:
|
||||||
if (add_interval(&data->io_db, start, size) != 0) {
|
if (add_interval(&data->io_db, start, size) != 0) {
|
||||||
@ -760,7 +760,7 @@ static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long
|
|||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
up(&rsrc_sem);
|
mutex_unlock(&rsrc_mutex);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -867,7 +867,7 @@ static void nonstatic_release_resource_db(struct pcmcia_socket *s)
|
|||||||
struct socket_data *data = s->resource_data;
|
struct socket_data *data = s->resource_data;
|
||||||
struct resource_map *p, *q;
|
struct resource_map *p, *q;
|
||||||
|
|
||||||
down(&rsrc_sem);
|
mutex_lock(&rsrc_mutex);
|
||||||
for (p = data->mem_db.next; p != &data->mem_db; p = q) {
|
for (p = data->mem_db.next; p != &data->mem_db; p = q) {
|
||||||
q = p->next;
|
q = p->next;
|
||||||
kfree(p);
|
kfree(p);
|
||||||
@ -876,7 +876,7 @@ static void nonstatic_release_resource_db(struct pcmcia_socket *s)
|
|||||||
q = p->next;
|
q = p->next;
|
||||||
kfree(p);
|
kfree(p);
|
||||||
}
|
}
|
||||||
up(&rsrc_sem);
|
mutex_unlock(&rsrc_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -901,7 +901,7 @@ static ssize_t show_io_db(struct class_device *class_dev, char *buf)
|
|||||||
struct resource_map *p;
|
struct resource_map *p;
|
||||||
ssize_t ret = 0;
|
ssize_t ret = 0;
|
||||||
|
|
||||||
down(&rsrc_sem);
|
mutex_lock(&rsrc_mutex);
|
||||||
data = s->resource_data;
|
data = s->resource_data;
|
||||||
|
|
||||||
for (p = data->io_db.next; p != &data->io_db; p = p->next) {
|
for (p = data->io_db.next; p != &data->io_db; p = p->next) {
|
||||||
@ -913,7 +913,7 @@ static ssize_t show_io_db(struct class_device *class_dev, char *buf)
|
|||||||
((unsigned long) p->base + p->num - 1));
|
((unsigned long) p->base + p->num - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
up(&rsrc_sem);
|
mutex_unlock(&rsrc_mutex);
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -953,7 +953,7 @@ static ssize_t show_mem_db(struct class_device *class_dev, char *buf)
|
|||||||
struct resource_map *p;
|
struct resource_map *p;
|
||||||
ssize_t ret = 0;
|
ssize_t ret = 0;
|
||||||
|
|
||||||
down(&rsrc_sem);
|
mutex_lock(&rsrc_mutex);
|
||||||
data = s->resource_data;
|
data = s->resource_data;
|
||||||
|
|
||||||
for (p = data->mem_db.next; p != &data->mem_db; p = p->next) {
|
for (p = data->mem_db.next; p != &data->mem_db; p = p->next) {
|
||||||
@ -965,7 +965,7 @@ static ssize_t show_mem_db(struct class_device *class_dev, char *buf)
|
|||||||
((unsigned long) p->base + p->num - 1));
|
((unsigned long) p->base + p->num - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
up(&rsrc_sem);
|
mutex_unlock(&rsrc_mutex);
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include <linux/pm.h>
|
#include <linux/pm.h>
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
|
|
||||||
@ -183,7 +184,7 @@ static ssize_t pccard_store_resource(struct class_device *dev, const char *buf,
|
|||||||
s->resource_setup_done = 1;
|
s->resource_setup_done = 1;
|
||||||
spin_unlock_irqrestore(&s->lock, flags);
|
spin_unlock_irqrestore(&s->lock, flags);
|
||||||
|
|
||||||
down(&s->skt_sem);
|
mutex_lock(&s->skt_mutex);
|
||||||
if ((s->callback) &&
|
if ((s->callback) &&
|
||||||
(s->state & SOCKET_PRESENT) &&
|
(s->state & SOCKET_PRESENT) &&
|
||||||
!(s->state & SOCKET_CARDBUS)) {
|
!(s->state & SOCKET_CARDBUS)) {
|
||||||
@ -192,7 +193,7 @@ static ssize_t pccard_store_resource(struct class_device *dev, const char *buf,
|
|||||||
module_put(s->callback->owner);
|
module_put(s->callback->owner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
up(&s->skt_sem);
|
mutex_unlock(&s->skt_mutex);
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
@ -322,7 +323,7 @@ static ssize_t pccard_store_cis(struct kobject *kobj, char *buf, loff_t off, siz
|
|||||||
kfree(cis);
|
kfree(cis);
|
||||||
|
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
down(&s->skt_sem);
|
mutex_lock(&s->skt_mutex);
|
||||||
if ((s->callback) && (s->state & SOCKET_PRESENT) &&
|
if ((s->callback) && (s->state & SOCKET_PRESENT) &&
|
||||||
!(s->state & SOCKET_CARDBUS)) {
|
!(s->state & SOCKET_CARDBUS)) {
|
||||||
if (try_module_get(s->callback->owner)) {
|
if (try_module_get(s->callback->owner)) {
|
||||||
@ -330,7 +331,7 @@ static ssize_t pccard_store_cis(struct kobject *kobj, char *buf, loff_t off, siz
|
|||||||
module_put(s->callback->owner);
|
module_put(s->callback->owner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
up(&s->skt_sem);
|
mutex_unlock(&s->skt_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include <linux/config.h>
|
#include <linux/config.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/sched.h> /* task_struct, completion */
|
#include <linux/sched.h> /* task_struct, completion */
|
||||||
|
#include <linux/mutex.h>
|
||||||
|
|
||||||
#include <pcmcia/cs_types.h>
|
#include <pcmcia/cs_types.h>
|
||||||
#include <pcmcia/cs.h>
|
#include <pcmcia/cs.h>
|
||||||
@ -240,7 +241,7 @@ struct pcmcia_socket {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* state thread */
|
/* state thread */
|
||||||
struct semaphore skt_sem; /* protects socket h/w state */
|
struct mutex skt_mutex; /* protects socket h/w state */
|
||||||
|
|
||||||
struct task_struct *thread;
|
struct task_struct *thread;
|
||||||
struct completion thread_done;
|
struct completion thread_done;
|
||||||
|
Loading…
Reference in New Issue
Block a user