1/* Intel PRO/1000 Family Driver
2 * Copyright (C) 2004 Marcus Overhagen <marcus@overhagen.de>. All rights reserved.
3 *
4 * Permission to use, copy, modify and distribute this software and its
5 * documentation for any purpose and without fee is hereby granted, provided
6 * that the above copyright notice appear in all copies, and that both the
7 * copyright notice and this permission notice appear in supporting documentation.
8 *
9 * Marcus Overhagen makes no representations about the suitability of this software
10 * for any purpose. It is provided "as is" without express or implied warranty.
11 *
12 * MARCUS OVERHAGEN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
13 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL MARCUS
14 * OVERHAGEN BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
15 * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
17 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19#include "if_em_osdep.h"
20#include "debug.h"
21#include "util.h"
22
23#undef malloc
24#undef free
25
26
27void *
28driver_malloc(int size, int p2, int p3)
29{
30	return malloc(size);
31}
32
33
34void
35driver_free(void *p, int p2)
36{
37	free(p);
38}
39
40
41void *
42contigmalloc(int size, int p1, int p2, int p3, int p4, int p5, int p6)
43{
44	void *adr;
45	if (create_area("contigmalloc", &adr, B_ANY_KERNEL_ADDRESS, size,
46			B_CONTIGUOUS, 0) < B_OK)
47		return NULL;
48	return adr;
49}
50
51
52void
53contigfree(void *p, int p1, int p2)
54{
55	delete_area(area_for(p));
56}
57
58
59void
60callout_handle_init(struct callout_handle *handle)
61{
62	handle->timer = -1;
63}
64
65
66struct callout_handle
67timeout(timer_function func, void *cookie, bigtime_t timeout)
68{
69	struct callout_handle handle;
70	handle.timer = create_timer(func, cookie, timeout, B_ONE_SHOT_RELATIVE_TIMER);
71	return handle;
72}
73
74
75void
76untimeout(timer_function func, void *cookie, struct callout_handle handle)
77{
78	delete_timer(handle.timer);
79}
80
81
82struct resource *
83bus_alloc_resource(device_t dev, int type, int *rid, int d, int e, int f, int g)
84{
85	switch (type) {
86		case SYS_RES_IOPORT:
87		{
88			uint32 v = pci_read_config(dev, *rid, 4) & PCI_address_io_mask;
89			INIT_DEBUGOUT2("bus_alloc_resource SYS_RES_IOPORT, reg 0x%x, adr %p\n", *rid, (void *)v);
90			return (struct resource *) v;
91		}
92
93		case SYS_RES_MEMORY:
94		{
95			uint32 v = pci_read_config(dev, *rid, 4) & PCI_address_memory_32_mask;
96			uint32 size = 128 * 1024; // XXX get size from BAR
97			void *virt;
98			INIT_DEBUGOUT2("bus_alloc_resource SYS_RES_MEMORY, reg 0x%x, adr %p\n", *rid, (void *)v);
99			if (map_mem(&virt, (void *)v, size, 0, "SYS_RES_MEMORY") < 0)
100				return 0;
101			return (struct resource *) virt;
102		}
103
104		case SYS_RES_IRQ:
105		{
106			uint8 v = pci_read_config(dev, PCI_interrupt_line, 1);
107			if (v == 0 || v == 0xff) {
108				ERROROUT("bus_alloc_resource SYS_RES_IRQ: no irq");
109				return 0;
110			}
111			return (struct resource *)(int)v;
112		}
113
114		default:
115			INIT_DEBUGOUT("bus_alloc_resource default!\n");
116			return 0;
117	}
118}
119
120
121void
122bus_release_resource(device_t dev, int type, int reg, struct resource *res)
123{
124	switch (type) {
125		case SYS_RES_IOPORT:
126		case SYS_RES_IRQ:
127			return;
128
129		case SYS_RES_MEMORY:
130			delete_area(area_for(res));
131			return;
132
133		default:
134			INIT_DEBUGOUT("bus_release_resource default!\n");
135			return;
136	}
137}
138
139
140uint32
141rman_get_start(struct resource *res)
142{
143	return (uint32)res;
144}
145
146
147struct int_tag {
148	interrupt_handler int_func;
149	void *cookie;
150	int irq;
151};
152
153
154int
155bus_setup_intr(device_t dev, struct resource *res, int p3, interrupt_handler int_func, void *cookie, void **tag)
156{
157	int irq = (int)res;
158
159	struct int_tag *int_tag = (struct int_tag *) malloc(sizeof(struct int_tag));
160	int_tag->int_func = int_func;
161	int_tag->cookie = cookie;
162	int_tag->irq = irq;
163	*tag = int_tag;
164
165	return install_io_interrupt_handler(irq, int_func, cookie, 0);
166}
167
168
169void
170bus_teardown_intr(device_t dev, struct resource *res, void *tag)
171{
172	struct int_tag *int_tag = (struct int_tag *) tag;
173	remove_io_interrupt_handler(int_tag->irq, int_tag->int_func, int_tag->cookie);
174	free(int_tag);
175}
176