1/* Kernel driver for SiS 900 networking
2 *
3 * Copyright © 2001-2005 pinc Software. All Rights Reserved.
4 * Distributed under the terms of the MIT license.
5 */
6
7
8#include <OS.h>
9#include <KernelExport.h>
10#include <SupportDefs.h>
11#include <PCI.h>
12
13#include <stdlib.h>
14#include <stdio.h>
15#include <string.h>
16#include <malloc.h>
17
18#include "ether_driver.h"
19#include "driver.h"
20#include "device.h"
21#include "sis900.h"
22
23#define MAX_CARDS 4
24
25int32 api_version = B_CUR_DRIVER_API_VERSION;
26
27char *gDeviceNames[MAX_CARDS + 1];
28pci_info *pciInfo[MAX_CARDS];
29pci_module_info	*pci;
30
31extern status_t init_hardware(void);
32extern status_t init_driver(void);
33extern void uninit_driver(void);
34extern const char **publish_devices(void);
35extern device_hooks *find_device(const char *name);
36
37
38const char **
39publish_devices(void)
40{
41	TRACE((DEVICE_NAME ": publish_devices()\n"));
42	return (const char **)gDeviceNames;
43}
44
45
46status_t
47init_hardware(void)
48{
49	TRACE((DEVICE_NAME ": init_hardware()\n"));
50	return B_NO_ERROR;
51}
52
53
54status_t
55init_driver(void)
56{
57	status_t status;
58	pci_info *info;
59	int i, found;
60
61	TRACE((DEVICE_NAME ": init_driver()\n"));
62
63	if ((status = get_module(B_PCI_MODULE_NAME,(module_info **)&pci)) != B_OK)
64	{
65		TRACE((DEVICE_NAME ": pci module unavailable\n"));
66		return status;
67	}
68
69	// find devices
70	info = malloc(sizeof(pci_info));
71	for (i = found = 0; (status = pci->get_nth_pci_info(i, info)) == B_OK; i++) {
72		if (info->vendor_id == VENDOR_ID_SiS && info->device_id == DEVICE_ID_SiS900) {
73			// enable bus mastering for device
74			pci->write_pci_config(info->bus, info->device, info->function,
75				PCI_command, 2,
76				PCI_command_master | pci->read_pci_config(
77					info->bus, info->device, info->function,
78					PCI_command, 2));
79
80			pciInfo[found++] = info;
81			dprintf(DEVICE_NAME ": revision = %x\n", info->revision);
82
83			info = malloc(sizeof(pci_info));
84		}
85	}
86	free(info);
87
88	if (found == 0) {
89		put_module(B_PCI_MODULE_NAME);
90		return ENODEV;
91	}
92
93	// create device name list
94	{
95		char name[32];
96
97		for (i = 0; i < found; i++) {
98			sprintf(name, DEVICE_DRIVERNAME "/%d", i);
99			gDeviceNames[i] = strdup(name);
100		}
101		gDeviceNames[i] = NULL;
102	}
103	return B_OK;
104}
105
106
107void
108uninit_driver(void)
109{
110	void *item;
111	int index;
112
113	TRACE((DEVICE_NAME ": uninit_driver()\n"));
114
115	// free device names & pci info
116	for (index = 0; (item = gDeviceNames[index]) != NULL; index++) {
117		free(item);
118		free(pciInfo[index]);
119	}
120
121	put_module(B_PCI_MODULE_NAME);
122}
123
124
125device_hooks *
126find_device(const char *name)
127{
128	int index;
129
130	TRACE((DEVICE_NAME ": find_device()\n"));
131
132	for (index = 0; gDeviceNames[index] != NULL; index++) {
133		if (!strcmp(name, gDeviceNames[index]))
134			return &gDeviceHooks;
135	}
136
137	return NULL;
138}
139
140/*
141void
142wake_driver(void)
143{
144	// for compatibility with Dano, only
145}
146
147
148void
149suspend_driver(void)
150{
151	// for compatibility with Dano, only
152}
153*/
154