1/*
2 * Copyright 2008, Axel D��rfler, axeld@pinc-software.de. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include "bus.h"
8
9#include <KernelExport.h>
10#include <PCI.h>
11
12
13void
14bus_trigger_device_removed(device_node* node)
15{
16	// the network device
17	device_attr attrs[] = {
18		{B_DEVICE_VENDOR_ID, B_UINT16_TYPE, {ui16: 0x1001}},
19		{B_DEVICE_ID, B_UINT16_TYPE, {ui16: 0x0001}},
20		{NULL}
21	};
22
23	device_node* child = NULL;
24	while (gDeviceManager->get_next_child_node(node, attrs, &child) == B_OK) {
25		gDeviceManager->unregister_node(child);
26	}
27}
28
29
30void
31bus_trigger_device_added(device_node* node)
32{
33}
34
35
36//	#pragma mark - bus
37
38
39static float
40supports_device(device_node* parent)
41{
42	const char* bus;
43	if (gDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false)
44			!= B_OK)
45		return -1;
46
47	if (bus != NULL && !strcmp(bus, "root"))
48		return 1.0;
49
50	return -1;
51}
52
53
54static status_t
55register_device(device_node* parent)
56{
57	device_attr attrs[] = {
58		{B_DEVICE_PRETTY_NAME,	B_STRING_TYPE,	{string: "My Bus"}},
59		{B_DEVICE_BUS,			B_STRING_TYPE,	{string: BUS_NAME}},
60		{NULL}
61	};
62
63	return gDeviceManager->register_node(parent, BUS_MODULE_NAME, attrs, NULL,
64		NULL);
65}
66
67
68static status_t
69init_driver(device_node* node, void** _cookie)
70{
71	*_cookie = node;
72	return B_OK;
73}
74
75
76static void
77uninit_driver(void* cookie)
78{
79}
80
81
82static status_t
83register_child_devices(void* cookie)
84{
85	device_node* node = (device_node*)cookie;
86
87	const struct device_info {
88		uint16		vendor;
89		uint16		device;
90		uint16		type;
91		uint16		sub_type;
92		uint16		interface;
93	} kDevices[] = {
94		{0x1000, 0x0001, PCI_mass_storage, PCI_sata, PCI_sata_ahci},
95		{0x1001, 0x0001, PCI_network, PCI_ethernet, 0},
96		{0x1001, 0x0002, PCI_display, 0, 0},
97		{0x1002, 0x0001, PCI_multimedia, PCI_audio, 0},
98		{0x1002, 0x0002, PCI_serial_bus, PCI_usb, PCI_usb_ehci},
99	};
100	const size_t kNumDevices = sizeof(kDevices) / sizeof(kDevices[0]);
101
102	for (uint32 i = 0; i < kNumDevices; i++) {
103		device_attr attrs[] = {
104			// info about the device
105			{B_DEVICE_VENDOR_ID, B_UINT16_TYPE, {ui16: kDevices[i].vendor}},
106			{B_DEVICE_ID, B_UINT16_TYPE, {ui16: kDevices[i].device}},
107
108			{B_DEVICE_BUS, B_STRING_TYPE, {string: BUS_NAME}},
109			{B_DEVICE_TYPE, B_UINT16_TYPE, {ui16: kDevices[i].type}},
110			{B_DEVICE_SUB_TYPE, B_UINT16_TYPE,
111				{ui16: kDevices[i].sub_type}},
112			{B_DEVICE_INTERFACE, B_UINT16_TYPE,
113				{ui16: kDevices[i].interface}},
114
115			{B_DEVICE_FLAGS, B_UINT32_TYPE, {ui32: B_FIND_CHILD_ON_DEMAND}},
116			{NULL}
117		};
118
119		gDeviceManager->register_node(node, BUS_FOR_DRIVER_NAME, attrs, NULL,
120			NULL);
121	}
122
123	device_attr attrs[] = {
124		{B_DEVICE_FIXED_CHILD, B_STRING_TYPE,
125			{string: "non_existing/driver_v1"}},
126		{NULL}
127	};
128
129#if 1
130	// this is supposed to fail
131	dprintf("non-existing child: %ld\n", gDeviceManager->register_node(node,
132		BUS_FOR_DRIVER_NAME, attrs, NULL, NULL));
133#endif
134	return B_OK;
135}
136
137
138static status_t
139rescan_child_devices(void* cookie)
140{
141	return B_ERROR;
142}
143
144
145static void
146device_removed(void* cookie)
147{
148}
149
150
151//	#pragma mark - for driver
152
153
154static status_t
155get_bus_info(void* cookie, bus_info* info)
156{
157	gDeviceManager->get_attr_uint16((device_node*)cookie, B_DEVICE_VENDOR_ID,
158		&info->vendor_id, false);
159	gDeviceManager->get_attr_uint16((device_node*)cookie, B_DEVICE_ID,
160		&info->device_id, false);
161	return B_OK;
162}
163
164
165//	#pragma mark -
166
167
168struct driver_module_info gBusModuleInfo = {
169	{
170		BUS_MODULE_NAME,
171		0,
172		NULL,
173	},
174
175	supports_device,
176	register_device,
177
178	init_driver,
179	uninit_driver,
180	register_child_devices,
181	rescan_child_devices,
182	device_removed,
183};
184
185struct bus_for_driver_module_info gBusDriverModuleInfo = {
186	{
187		{
188			BUS_FOR_DRIVER_NAME,
189			0,
190			NULL,
191		},
192
193		NULL,
194		NULL,
195
196		init_driver,
197	},
198	get_bus_info
199};
200
201