forked from Minki/linux
pcmcia: carve out ioctl adjust function to pcmcia_ioctl
Let pcmcia_ioctl interact with rsrc_nonstatic using functions which rsrc_nonstatic.c has to use anyway. Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
This commit is contained in:
parent
635416ef39
commit
c502380170
@ -138,6 +138,94 @@ static int proc_read_drivers(char *buf, char **start, off_t pos,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_PCMCIA_PROBE
|
||||||
|
|
||||||
|
static int adjust_irq(struct pcmcia_socket *s, adjust_t *adj)
|
||||||
|
{
|
||||||
|
int irq;
|
||||||
|
u32 mask;
|
||||||
|
|
||||||
|
irq = adj->resource.irq.IRQ;
|
||||||
|
if ((irq < 0) || (irq > 15))
|
||||||
|
return CS_BAD_IRQ;
|
||||||
|
|
||||||
|
if (adj->Action != REMOVE_MANAGED_RESOURCE)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
mask = 1 << irq;
|
||||||
|
|
||||||
|
if (!(s->irq_mask & mask))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
s->irq_mask &= ~mask;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) {
|
||||||
|
return CS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int pcmcia_adjust_resource_info(adjust_t *adj)
|
||||||
|
{
|
||||||
|
struct pcmcia_socket *s;
|
||||||
|
int ret = CS_UNSUPPORTED_FUNCTION;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
down_read(&pcmcia_socket_list_rwsem);
|
||||||
|
list_for_each_entry(s, &pcmcia_socket_list, socket_list) {
|
||||||
|
|
||||||
|
if (adj->Resource == RES_IRQ)
|
||||||
|
ret = adjust_irq(s, adj);
|
||||||
|
|
||||||
|
else if (s->resource_ops->add_io) {
|
||||||
|
unsigned long begin, end;
|
||||||
|
|
||||||
|
/* you can't use the old interface if the new
|
||||||
|
* one was used before */
|
||||||
|
spin_lock_irqsave(&s->lock, flags);
|
||||||
|
if ((s->resource_setup_new) &&
|
||||||
|
!(s->resource_setup_old)) {
|
||||||
|
spin_unlock_irqrestore(&s->lock, flags);
|
||||||
|
continue;
|
||||||
|
} else if (!(s->resource_setup_old))
|
||||||
|
s->resource_setup_old = 1;
|
||||||
|
spin_unlock_irqrestore(&s->lock, flags);
|
||||||
|
|
||||||
|
switch (adj->Resource) {
|
||||||
|
case RES_MEMORY_RANGE:
|
||||||
|
begin = adj->resource.memory.Base;
|
||||||
|
end = adj->resource.memory.Base + adj->resource.memory.Size - 1;
|
||||||
|
if (s->resource_ops->add_mem)
|
||||||
|
ret =s->resource_ops->add_mem(s, adj->Action, begin, end);
|
||||||
|
case RES_IO_RANGE:
|
||||||
|
begin = adj->resource.io.BasePort;
|
||||||
|
end = adj->resource.io.BasePort + adj->resource.io.NumPorts - 1;
|
||||||
|
if (s->resource_ops->add_io)
|
||||||
|
ret = s->resource_ops->add_io(s, adj->Action, begin, end);
|
||||||
|
}
|
||||||
|
if (!ret) {
|
||||||
|
/* as there's no way we know this is the
|
||||||
|
* last call to adjust_resource_info, we
|
||||||
|
* always need to assume this is the latest
|
||||||
|
* one... */
|
||||||
|
spin_lock_irqsave(&s->lock, flags);
|
||||||
|
s->resource_setup_done = 1;
|
||||||
|
spin_unlock_irqrestore(&s->lock, flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
up_read(&pcmcia_socket_list_rwsem);
|
||||||
|
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*======================================================================
|
/*======================================================================
|
||||||
|
|
||||||
These manage a ring buffer of events pending for one user process
|
These manage a ring buffer of events pending for one user process
|
||||||
@ -546,8 +634,6 @@ static u_int ds_poll(struct file *file, poll_table *wait)
|
|||||||
|
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
|
|
||||||
extern int pcmcia_adjust_resource_info(adjust_t *adj);
|
|
||||||
|
|
||||||
static int ds_ioctl(struct inode * inode, struct file * file,
|
static int ds_ioctl(struct inode * inode, struct file * file,
|
||||||
u_int cmd, u_long arg)
|
u_int cmd, u_long arg)
|
||||||
{
|
{
|
||||||
|
@ -21,86 +21,6 @@
|
|||||||
#include "cs_internal.h"
|
#include "cs_internal.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_PCMCIA_IOCTL
|
|
||||||
|
|
||||||
#ifdef CONFIG_PCMCIA_PROBE
|
|
||||||
|
|
||||||
static int adjust_irq(struct pcmcia_socket *s, adjust_t *adj)
|
|
||||||
{
|
|
||||||
int irq;
|
|
||||||
u32 mask;
|
|
||||||
|
|
||||||
irq = adj->resource.irq.IRQ;
|
|
||||||
if ((irq < 0) || (irq > 15))
|
|
||||||
return CS_BAD_IRQ;
|
|
||||||
|
|
||||||
if (adj->Action != REMOVE_MANAGED_RESOURCE)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
mask = 1 << irq;
|
|
||||||
|
|
||||||
if (!(s->irq_mask & mask))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
s->irq_mask &= ~mask;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) {
|
|
||||||
return CS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
int pcmcia_adjust_resource_info(adjust_t *adj)
|
|
||||||
{
|
|
||||||
struct pcmcia_socket *s;
|
|
||||||
int ret = CS_UNSUPPORTED_FUNCTION;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
down_read(&pcmcia_socket_list_rwsem);
|
|
||||||
list_for_each_entry(s, &pcmcia_socket_list, socket_list) {
|
|
||||||
|
|
||||||
if (adj->Resource == RES_IRQ)
|
|
||||||
ret = adjust_irq(s, adj);
|
|
||||||
|
|
||||||
else if (s->resource_ops->adjust_resource) {
|
|
||||||
|
|
||||||
/* you can't use the old interface if the new
|
|
||||||
* one was used before */
|
|
||||||
spin_lock_irqsave(&s->lock, flags);
|
|
||||||
if ((s->resource_setup_new) &&
|
|
||||||
!(s->resource_setup_old)) {
|
|
||||||
spin_unlock_irqrestore(&s->lock, flags);
|
|
||||||
continue;
|
|
||||||
} else if (!(s->resource_setup_old))
|
|
||||||
s->resource_setup_old = 1;
|
|
||||||
spin_unlock_irqrestore(&s->lock, flags);
|
|
||||||
|
|
||||||
ret = s->resource_ops->adjust_resource(s, adj);
|
|
||||||
if (!ret) {
|
|
||||||
/* as there's no way we know this is the
|
|
||||||
* last call to adjust_resource_info, we
|
|
||||||
* always need to assume this is the latest
|
|
||||||
* one... */
|
|
||||||
spin_lock_irqsave(&s->lock, flags);
|
|
||||||
s->resource_setup_done = 1;
|
|
||||||
spin_unlock_irqrestore(&s->lock, flags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
up_read(&pcmcia_socket_list_rwsem);
|
|
||||||
|
|
||||||
return (ret);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(pcmcia_adjust_resource_info);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int pcmcia_validate_mem(struct pcmcia_socket *s)
|
int pcmcia_validate_mem(struct pcmcia_socket *s)
|
||||||
{
|
{
|
||||||
if (s->resource_ops->validate_mem)
|
if (s->resource_ops->validate_mem)
|
||||||
@ -164,7 +84,8 @@ struct pccard_resource_ops pccard_static_ops = {
|
|||||||
.adjust_io_region = NULL,
|
.adjust_io_region = NULL,
|
||||||
.find_io = NULL,
|
.find_io = NULL,
|
||||||
.find_mem = NULL,
|
.find_mem = NULL,
|
||||||
.adjust_resource = NULL,
|
.add_io = NULL,
|
||||||
|
.add_mem = NULL,
|
||||||
.init = static_init,
|
.init = static_init,
|
||||||
.exit = NULL,
|
.exit = NULL,
|
||||||
};
|
};
|
||||||
@ -264,7 +185,8 @@ struct pccard_resource_ops pccard_iodyn_ops = {
|
|||||||
.adjust_io_region = iodyn_adjust_io_region,
|
.adjust_io_region = iodyn_adjust_io_region,
|
||||||
.find_io = iodyn_find_io_region,
|
.find_io = iodyn_find_io_region,
|
||||||
.find_mem = NULL,
|
.find_mem = NULL,
|
||||||
.adjust_resource = NULL,
|
.add_io = NULL,
|
||||||
|
.add_mem = NULL,
|
||||||
.init = static_init,
|
.init = static_init,
|
||||||
.exit = NULL,
|
.exit = NULL,
|
||||||
};
|
};
|
||||||
|
@ -766,21 +766,6 @@ static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int nonstatic_adjust_resource_info(struct pcmcia_socket *s, adjust_t *adj)
|
|
||||||
{
|
|
||||||
unsigned long end;
|
|
||||||
|
|
||||||
switch (adj->Resource) {
|
|
||||||
case RES_MEMORY_RANGE:
|
|
||||||
end = adj->resource.memory.Base + adj->resource.memory.Size - 1;
|
|
||||||
return adjust_memory(s, adj->Action, adj->resource.memory.Base, end);
|
|
||||||
case RES_IO_RANGE:
|
|
||||||
end = adj->resource.io.BasePort + adj->resource.io.NumPorts - 1;
|
|
||||||
return adjust_io(s, adj->Action, adj->resource.io.BasePort, end);
|
|
||||||
}
|
|
||||||
return CS_UNSUPPORTED_FUNCTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_PCI
|
#ifdef CONFIG_PCI
|
||||||
static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
|
static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
|
||||||
{
|
{
|
||||||
@ -889,7 +874,8 @@ struct pccard_resource_ops pccard_nonstatic_ops = {
|
|||||||
.adjust_io_region = nonstatic_adjust_io_region,
|
.adjust_io_region = nonstatic_adjust_io_region,
|
||||||
.find_io = nonstatic_find_io_region,
|
.find_io = nonstatic_find_io_region,
|
||||||
.find_mem = nonstatic_find_mem_region,
|
.find_mem = nonstatic_find_mem_region,
|
||||||
.adjust_resource = nonstatic_adjust_resource_info,
|
.add_io = adjust_io,
|
||||||
|
.add_mem = adjust_memory,
|
||||||
.init = nonstatic_init,
|
.init = nonstatic_init,
|
||||||
.exit = nonstatic_release_resource_db,
|
.exit = nonstatic_release_resource_db,
|
||||||
};
|
};
|
||||||
|
@ -136,8 +136,14 @@ struct pccard_resource_ops {
|
|||||||
struct resource* (*find_mem) (unsigned long base, unsigned long num,
|
struct resource* (*find_mem) (unsigned long base, unsigned long num,
|
||||||
unsigned long align, int low,
|
unsigned long align, int low,
|
||||||
struct pcmcia_socket *s);
|
struct pcmcia_socket *s);
|
||||||
int (*adjust_resource) (struct pcmcia_socket *s,
|
int (*add_io) (struct pcmcia_socket *s,
|
||||||
adjust_t *adj);
|
unsigned int action,
|
||||||
|
unsigned long r_start,
|
||||||
|
unsigned long r_end);
|
||||||
|
int (*add_mem) (struct pcmcia_socket *s,
|
||||||
|
unsigned int action,
|
||||||
|
unsigned long r_start,
|
||||||
|
unsigned long r_end);
|
||||||
int (*init) (struct pcmcia_socket *s);
|
int (*init) (struct pcmcia_socket *s);
|
||||||
void (*exit) (struct pcmcia_socket *s);
|
void (*exit) (struct pcmcia_socket *s);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user