vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / kernel / drivers / network / rtl8169 / driver.c
blobf5befe7e33605b696591e28201f4b9bfb8bcfe67
1 /* Realtek RTL8169 Family Driver
2 * Copyright (C) 2004 Marcus Overhagen <marcus@overhagen.de>. All rights reserved.
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.
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.
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.
19 #include <KernelExport.h>
20 #include <Errors.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
25 //#define DEBUG
27 #include "debug.h"
28 #include "device.h"
29 #include "driver.h"
30 #include "setup.h"
31 #include "timer.h"
34 #define VENDOR_ID_REALTEK 0x10ec
37 static const uint32 kSupportedDevices[] = {
38 0x8167,
39 0x8168,
40 0x8169,
43 int32 api_version = B_CUR_DRIVER_API_VERSION;
45 char* gDevNameList[MAX_CARDS + 1];
46 pci_info *gDevList[MAX_CARDS];
47 pci_module_info *gPci;
49 static device_hooks sDeviceHooks = {
50 rtl8169_open,
51 rtl8169_close,
52 rtl8169_free,
53 rtl8169_control,
54 rtl8169_read,
55 rtl8169_write,
59 static status_t
60 get_next_supported_pci_info(int32 *_cookie, pci_info *info)
62 int32 index = *_cookie;
63 uint32 i;
65 // find devices
67 for (; gPci->get_nth_pci_info(index, info) == B_OK; index++) {
68 // check vendor
69 if (info->vendor_id != VENDOR_ID_REALTEK)
70 continue;
72 // check device
73 for (i = 0; i < sizeof(kSupportedDevices)
74 / sizeof(kSupportedDevices[0]); i++) {
75 if (info->device_id == kSupportedDevices[i]) {
76 *_cookie = index + 1;
77 return B_OK;
82 return B_ENTRY_NOT_FOUND;
86 // #pragma mark -
89 status_t
90 init_hardware(void)
92 uint32 cookie = 0;
93 status_t result;
94 pci_info info;
96 TRACE("init_hardware()\n");
98 if (get_module(B_PCI_MODULE_NAME, (module_info **)&gPci) < B_OK)
99 return B_ERROR;
101 result = get_next_supported_pci_info(&cookie, &info);
102 put_module(B_PCI_MODULE_NAME);
104 return result;
108 status_t
109 init_driver(void)
111 struct pci_info *item;
112 uint32 index = 0;
113 int cards = 0;
115 #ifdef DEBUG
116 set_dprintf_enabled(true);
117 load_driver_symbols("rtl8169");
118 #endif
120 dprintf(INFO1"\n");
121 dprintf(INFO2"\n");
123 item = (pci_info *)malloc(sizeof(pci_info));
124 if (!item)
125 return B_NO_MEMORY;
127 if (get_module(B_PCI_MODULE_NAME, (module_info **)&gPci) < B_OK) {
128 free(item);
129 return B_ERROR;
132 while (get_next_supported_pci_info(&index, item) == B_OK) {
133 char name[64];
134 sprintf(name, "net/rtl8169/%d", cards);
135 gDevList[cards] = item;
136 gDevNameList[cards] = strdup(name);
137 gDevNameList[cards + 1] = NULL;
138 cards++;
140 item = (pci_info *)malloc(sizeof(pci_info));
141 if (!item)
142 goto err_outofmem;
144 if (cards == MAX_CARDS)
145 break;
148 TRACE("found %d cards\n", cards);
150 free(item);
152 if (!cards)
153 goto err_cards;
155 if (initialize_timer() != B_OK) {
156 ERROR("timer init failed\n");
157 goto err_timer;
160 return B_OK;
162 err_timer:
163 err_cards:
164 err_outofmem:
165 for (index = 0; index < cards; index++) {
166 free(gDevList[index]);
167 free(gDevNameList[index]);
169 put_module(B_PCI_MODULE_NAME);
170 return B_ERROR;
174 void
175 uninit_driver(void)
177 int32 i;
179 TRACE("uninit_driver()\n");
181 terminate_timer();
183 for (i = 0; gDevNameList[i] != NULL; i++) {
184 free(gDevList[i]);
185 free(gDevNameList[i]);
188 put_module(B_PCI_MODULE_NAME);
192 const char**
193 publish_devices()
195 return (const char**)gDevNameList;
199 device_hooks*
200 find_device(const char* name)
202 return &sDeviceHooks;