Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c5023801 authored by Dominik Brodowski's avatar Dominik Brodowski
Browse files

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: default avatarDominik Brodowski <linux@dominikbrodowski.net>
parent 635416ef
Loading
Loading
Loading
Loading
+88 −2
Original line number Diff line number Diff line
@@ -138,6 +138,94 @@ static int proc_read_drivers(char *buf, char **start, off_t pos,
}
#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
@@ -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,
		    u_int cmd, u_long arg)
{
+4 −82
Original line number Diff line number Diff line
@@ -21,86 +21,6 @@
#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)
{
	if (s->resource_ops->validate_mem)
@@ -164,7 +84,8 @@ struct pccard_resource_ops pccard_static_ops = {
	.adjust_io_region = NULL,
	.find_io = NULL,
	.find_mem = NULL,
	.adjust_resource = NULL,
	.add_io = NULL,
	.add_mem = NULL,
	.init = static_init,
	.exit = NULL,
};
@@ -264,7 +185,8 @@ struct pccard_resource_ops pccard_iodyn_ops = {
	.adjust_io_region = iodyn_adjust_io_region,
	.find_io = iodyn_find_io_region,
	.find_mem = NULL,
	.adjust_resource = NULL,
	.add_io = NULL,
	.add_mem = NULL,
	.init = static_init,
	.exit = NULL,
};
+2 −16
Original line number Diff line number Diff line
@@ -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
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,
	.find_io = nonstatic_find_io_region,
	.find_mem = nonstatic_find_mem_region,
	.adjust_resource = nonstatic_adjust_resource_info,
	.add_io = adjust_io,
	.add_mem = adjust_memory,
	.init = nonstatic_init,
	.exit = nonstatic_release_resource_db,
};
+8 −2
Original line number Diff line number Diff line
@@ -136,8 +136,14 @@ struct pccard_resource_ops {
	struct resource* (*find_mem)	(unsigned long base, unsigned long num,
					 unsigned long align, int low,
					 struct pcmcia_socket *s);
	int	(*adjust_resource)	(struct pcmcia_socket *s,
					 adjust_t *adj);
	int	(*add_io)		(struct pcmcia_socket *s,
					 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);
	void	(*exit)			(struct pcmcia_socket *s);
};