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

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

[PATCH] pcmcia: validate_mem shouldn't be void



Add a return value to pcmcia_validate_mem.  Only if we have enough memory
available to map the CIS, we should proceed in trying to determine information
about the device.

Signed-off-by: default avatarDominik Brodowski <linux@dominikbrodowski.net>
parent 9da4bc6d
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -117,7 +117,7 @@ int verify_cis_cache(struct pcmcia_socket *s);
int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t code, void *parse);

/* In rsrc_mgr */
void pcmcia_validate_mem(struct pcmcia_socket *s);
int pcmcia_validate_mem(struct pcmcia_socket *s);
struct resource *pcmcia_find_io_region(unsigned long base, int num, unsigned long align,
		   struct pcmcia_socket *s);
int pcmcia_adjust_io_region(struct resource *res, unsigned long r_start,
+3 −1
Original line number Diff line number Diff line
@@ -583,7 +583,9 @@ static int pcmcia_card_add(struct pcmcia_socket *s)
	if (!(s->resource_setup_done))
		return -EAGAIN; /* try again, but later... */

	pcmcia_validate_mem(s);
	if (pcmcia_validate_mem(s))
		return -EAGAIN; /* try again, but later... */

	ret = pccard_validate_cis(s, BIND_FN_ALL, &cisinfo);
	if (ret || !cisinfo.Chains) {
		ds_dbg(0, "invalid CIS or invalid resources\n");
+4 −2
Original line number Diff line number Diff line
@@ -98,10 +98,12 @@ int pcmcia_adjust_resource_info(adjust_t *adj)
}
EXPORT_SYMBOL(pcmcia_adjust_resource_info);

void pcmcia_validate_mem(struct pcmcia_socket *s)
int pcmcia_validate_mem(struct pcmcia_socket *s)
{
	if (s->resource_ops->validate_mem)
		s->resource_ops->validate_mem(s);
		return s->resource_ops->validate_mem(s);
	/* if there is no callback, we can assume that everything is OK */
	return 0;
}
EXPORT_SYMBOL(pcmcia_validate_mem);

+66 −57
Original line number Diff line number Diff line
@@ -422,26 +422,27 @@ static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s)
	return do_mem_probe(m->base, m->num, s);
}

static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
{
	struct resource_map *m, mm;
    static u_char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
    u_long b, i, ok = 0;
	static unsigned char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
	unsigned long b, i, ok = 0;
	struct socket_data *s_data = s->resource_data;

	/* We do up to four passes through the list */
	if (probe_mask & MEM_PROBE_HIGH) {
		if (inv_probe(s_data->mem_db.next, s) > 0)
	    return;
			return 0;
		printk(KERN_NOTICE "cs: warning: no high memory space "
		       "available!\n");
		return -ENODEV;
	}
    if ((probe_mask & MEM_PROBE_LOW) == 0)
	return;

	for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
		mm = *m;
		/* Only probe < 1 MB */
	if (mm.base >= 0x100000) continue;
		if (mm.base >= 0x100000)
			continue;
		if ((mm.base | mm.num) & 0xffff) {
			ok += do_mem_probe(mm.base, mm.num, s);
			continue;
@@ -457,6 +458,11 @@ static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
			}
		}
	}

	if (ok > 0)
		return 0;

	return -ENODEV;
}

#else /* CONFIG_PCMCIA_PROBE */
@@ -478,27 +484,30 @@ static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
/*
 * Locking note: Must be called with skt_sem held!
 */
static void pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
{
	struct socket_data *s_data = s->resource_data;
	if (probe_mem) {
		unsigned int probe_mask;
	unsigned int probe_mask = MEM_PROBE_LOW;
	int ret = 0;

	if (!probe_mem)
		return 0;

	down(&rsrc_sem);

		probe_mask = MEM_PROBE_LOW;
	if (s->features & SS_CAP_PAGE_REGS)
		probe_mask = MEM_PROBE_HIGH;

	if (probe_mask & ~s_data->rsrc_mem_probe) {
			s_data->rsrc_mem_probe |= probe_mask;

		if (s->state & SOCKET_PRESENT)
				validate_mem(s, probe_mask);
			ret = validate_mem(s, probe_mask);
		if (!ret)
			s_data->rsrc_mem_probe |= probe_mask;
	}

	up(&rsrc_sem);
	}

	return ret;
}

struct pcmcia_align_data {
+1 −1
Original line number Diff line number Diff line
@@ -125,7 +125,7 @@ struct pccard_operations {
};

struct pccard_resource_ops {
	void	(*validate_mem)		(struct pcmcia_socket *s);
	int	(*validate_mem)		(struct pcmcia_socket *s);
	int	(*adjust_io_region)	(struct resource *res,
					 unsigned long r_start,
					 unsigned long r_end,