1/*
2 * Copyright 2011, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Author(s):
6 *		Axel D��rfler <axeld@pinc-software.de>
7 *		Siarzhuk Zharski <imker@gmx.li>
8 */
9
10
11#include <sys/bus.h>
12#include <sys/mutex.h>
13#include <sys/systm.h>
14#include <machine/bus.h>
15#include <shared.h>
16
17#include "if_dcreg.h"
18
19
20HAIKU_FBSD_DRIVERS_GLUE(dec21xxx);
21HAIKU_DRIVER_REQUIREMENTS(0);
22
23
24int check_disable_interrupts_dc(device_t dev);
25void reenable_interrupts_dc(device_t dev);
26
27extern int check_disable_interrupts_de(device_t dev);
28extern void reenable_interrupts_de(device_t dev);
29
30
31extern driver_t *DRIVER_MODULE_NAME(dc, pci);
32extern driver_t *DRIVER_MODULE_NAME(de, pci);
33
34status_t
35__haiku_handle_fbsd_drivers_list(status_t (*handler)(driver_t *[], driver_t *[]))
36{
37	driver_t *drivers[] = {
38		DRIVER_MODULE_NAME(dc, pci),
39		DRIVER_MODULE_NAME(de, pci),
40		NULL
41	};
42	return (*handler)(drivers, NULL);
43}
44
45
46extern driver_t *DRIVER_MODULE_NAME(acphy, miibus);
47extern driver_t *DRIVER_MODULE_NAME(amphy, miibus);
48extern driver_t *DRIVER_MODULE_NAME(dcphy, miibus);
49extern driver_t *DRIVER_MODULE_NAME(pnphy, miibus);
50extern driver_t *DRIVER_MODULE_NAME(ukphy, miibus);
51
52driver_t *
53__haiku_select_miibus_driver(device_t dev)
54{
55	driver_t *drivers[] = {
56		DRIVER_MODULE_NAME(acphy, miibus),
57		DRIVER_MODULE_NAME(amphy, miibus),
58		DRIVER_MODULE_NAME(dcphy, miibus),
59		DRIVER_MODULE_NAME(pnphy, miibus),
60		DRIVER_MODULE_NAME(ukphy, miibus),
61		NULL
62	};
63
64	return __haiku_probe_miibus(dev, drivers);
65}
66
67
68int
69HAIKU_CHECK_DISABLE_INTERRUPTS(device_t dev)
70{
71	uint16 name = *(uint16*)dev->device_name;
72	switch (name) {
73		case 'cd':
74			return check_disable_interrupts_dc(dev);
75		case 'ed':
76			return check_disable_interrupts_de(dev);
77		default:
78			break;
79	}
80
81	panic("Unsupported device: %#x (%s)!", name, dev->device_name);
82	return 0;
83}
84
85
86void
87HAIKU_REENABLE_INTERRUPTS(device_t dev)
88{
89	uint16 name = *(uint16*)dev->device_name;
90	switch (name) {
91		case 'cd':
92			reenable_interrupts_dc(dev);
93			break;
94		case 'ed':
95			reenable_interrupts_de(dev);
96			break;
97		default:
98			panic("Unsupported device: %#x (%s)!", name, dev->device_name);
99			break;
100	}
101}
102
103
104int
105check_disable_interrupts_dc(device_t dev)
106{
107	struct dc_softc *sc = device_get_softc(dev);
108	uint16_t status;
109	HAIKU_INTR_REGISTER_STATE;
110
111	HAIKU_INTR_REGISTER_ENTER();
112
113	status = CSR_READ_4(sc, DC_ISR);
114	if (status == 0xffff) {
115		HAIKU_INTR_REGISTER_LEAVE();
116		return 0;
117	}
118
119	if (status != 0 && (status & DC_INTRS) == 0) {
120		CSR_WRITE_4(sc, DC_ISR, status);
121		HAIKU_INTR_REGISTER_LEAVE();
122		return 0;
123	}
124
125	if ((status & DC_INTRS) == 0) {
126		HAIKU_INTR_REGISTER_LEAVE();
127		return 0;
128	}
129
130	CSR_WRITE_4(sc, DC_IMR, 0);
131
132	HAIKU_INTR_REGISTER_LEAVE();
133
134	return 1;
135}
136
137
138void
139reenable_interrupts_dc(device_t dev)
140{
141	struct dc_softc *sc = device_get_softc(dev);
142	DC_LOCK(sc);
143	CSR_WRITE_4(sc, DC_IMR, DC_INTRS);
144	DC_UNLOCK(sc);
145}
146
147