rsrc_mgr.c 3.03 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13
/*
 * rsrc_mgr.c -- Resource management routines
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * The initial developer of the original code is David A. Hinds
 * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
 * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
 *
 * (C) 1999		David A. Hinds
 */
Linus Torvalds's avatar
Linus Torvalds committed
14 15 16

#include <linux/config.h>
#include <linux/module.h>
17
#include <linux/moduleparam.h>
Linus Torvalds's avatar
Linus Torvalds committed
18
#include <linux/init.h>
19
#include <linux/interrupt.h>
Linus Torvalds's avatar
Linus Torvalds committed
20 21 22
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/types.h>
Linus Torvalds's avatar
Linus Torvalds committed
23
#include <linux/slab.h>
Linus Torvalds's avatar
Linus Torvalds committed
24 25
#include <linux/ioport.h>
#include <linux/timer.h>
26
#include <linux/pci.h>
Linus Torvalds's avatar
Linus Torvalds committed
27 28 29 30 31 32 33 34 35 36 37
#include <asm/irq.h>
#include <asm/io.h>

#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
#include <pcmcia/cs.h>
#include <pcmcia/bulkmem.h>
#include <pcmcia/cistpl.h>
#include "cs_internal.h"


38
#ifdef CONFIG_PCMCIA_PROBE
39

40 41 42 43 44 45 46 47 48 49 50 51 52 53
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;

54
	if (!(s->irq_mask & mask))
55 56 57 58 59
		return 0;

	s->irq_mask &= ~mask;

	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
60 61
}

62 63 64 65 66 67 68 69 70
#else

static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) {
	return CS_SUCCESS;
}

#endif


71
int pcmcia_adjust_resource_info(adjust_t *adj)
Linus Torvalds's avatar
Linus Torvalds committed
72
{
73 74 75 76 77
	struct pcmcia_socket *s;
	int ret = CS_UNSUPPORTED_FUNCTION;

	down_read(&pcmcia_socket_list_rwsem);
	list_for_each_entry(s, &pcmcia_socket_list, socket_list) {
78 79 80 81 82

		if (adj->Resource == RES_IRQ)
			ret = adjust_irq(s, adj);

		else if (s->resource_ops->adjust_resource)
83
			ret = s->resource_ops->adjust_resource(s, adj);
84 85 86 87
	}
	up_read(&pcmcia_socket_list_rwsem);

	return (ret);
Linus Torvalds's avatar
Linus Torvalds committed
88
}
89
EXPORT_SYMBOL(pcmcia_adjust_resource_info);
Linus Torvalds's avatar
Linus Torvalds committed
90

91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
void pcmcia_validate_mem(struct pcmcia_socket *s)
{
	if (s->resource_ops->validate_mem)
		s->resource_ops->validate_mem(s);
}
EXPORT_SYMBOL(pcmcia_validate_mem);

int adjust_io_region(struct resource *res, unsigned long r_start,
		     unsigned long r_end, struct pcmcia_socket *s)
{
	if (s->resource_ops->adjust_io_region)
		return s->resource_ops->adjust_io_region(res, r_start, r_end, s);
	return -ENOMEM;
}

struct resource *find_io_region(unsigned long base, int num,
		   unsigned long align, struct pcmcia_socket *s)
{
	if (s->resource_ops->find_io)
		return s->resource_ops->find_io(base, num, align, s);
	return NULL;
}

114 115 116 117 118 119 120 121
struct resource *find_mem_region(u_long base, u_long num, u_long align,
				 int low, struct pcmcia_socket *s)
{
	if (s->resource_ops->find_mem)
		return s->resource_ops->find_mem(base, num, align, low, s);
	return NULL;
}

122 123 124 125 126 127
void release_resource_db(struct pcmcia_socket *s)
{
	if (s->resource_ops->exit)
		s->resource_ops->exit(s);
}

128

129 130
struct pccard_resource_ops pccard_static_ops = {
	.validate_mem = NULL,
131
	.adjust_io_region = NULL,
132
	.find_io = NULL,
133
	.find_mem = NULL,
134 135
	.adjust_resource = NULL,
	.exit = NULL,
136
};
137
EXPORT_SYMBOL(pccard_static_ops);