BPicture: Fix archive constructor.
[haiku.git] / src / add-ons / kernel / drivers / network / ipro1000 / driver.c
blob028e0ca73e0a411cd8f6e8388268c18012080d60
1 /* Intel PRO/1000 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 #include "debug.h"
26 #include "timer.h"
27 #include "device.h"
28 #include "driver.h"
29 #include "mempool.h"
31 int32 api_version = B_CUR_DRIVER_API_VERSION;
33 pci_module_info *gPci;
35 char* gDevNameList[MAX_CARDS + 1];
36 pci_info *gDevList[MAX_CARDS];
38 static const char *
39 identify_device(const pci_info *info)
41 if (info->vendor_id != 0x8086)
42 return 0;
43 switch (info->device_id) {
44 case 0x1000: return "82542";
45 case 0x1001: return "82543GC FIBER";
46 case 0x1004: return "82543GC COPPER";
47 case 0x1008: return "82544EI COPPER";
48 case 0x1009: return "82544EI FIBER";
49 case 0x100C: return "82544GC COPPER";
50 case 0x100D: return "82544GC LOM";
51 case 0x100E: return "82540EM";
52 case 0x100F: return "82545EM COPPER";
53 case 0x1010: return "82546EB COPPER";
54 case 0x1011: return "82545EM FIBER";
55 case 0x1012: return "82546EB FIBER";
56 case 0x1013: return "82541EI";
57 case 0x1014: return "unknown 1014";
58 case 0x1015: return "82540EM LOM";
59 case 0x1016: return "82540EP LOM";
60 case 0x1017: return "82540EP";
61 case 0x1018: return "82541EI MOBILE";
62 case 0x1019: return "82547EI";
63 case 0x101A: return "unknown 101A";
64 case 0x101D: return "82546EB QUAD COPPER";
65 case 0x101E: return "82540EP LP";
66 case 0x1026: return "82545GM COPPER";
67 case 0x1027: return "82545GM FIBER";
68 case 0x1028: return "82545GM SERDES";
69 case 0x1075: return "82547GI";
70 case 0x1076: return "82541GI";
71 case 0x1077: return "82541GI MOBILE";
72 case 0x1078: return "82541ER";
73 case 0x1079: return "82546GB COPPER";
74 case 0x107A: return "82546GB FIBER";
75 case 0x107B: return "82546GB SERDES";
76 case 0x107C: return "82541PI";
77 default: return 0;
81 status_t
82 init_hardware(void)
84 pci_module_info *pci;
85 pci_info info;
86 status_t res;
87 int i;
89 INIT_DEBUGOUT("init_hardware()");
91 if (get_module(B_PCI_MODULE_NAME, (module_info **)&pci) < B_OK)
92 return B_ERROR;
93 for (res = B_ERROR, i = 0; pci->get_nth_pci_info(i, &info) == B_OK; i++) {
94 if (identify_device(&info)) {
95 res = B_OK;
96 break;
99 put_module(B_PCI_MODULE_NAME);
101 return res;
105 status_t
106 init_driver(void)
108 struct pci_info *item;
109 int index;
110 int cards;
112 #ifdef DEBUG
113 set_dprintf_enabled(true);
114 load_driver_symbols("ipro1000");
115 #endif
117 dprintf("ipro1000: " INFO "\n");
119 item = (pci_info *)malloc(sizeof(pci_info));
120 if (!item)
121 return B_NO_MEMORY;
123 if (get_module(B_PCI_MODULE_NAME, (module_info **)&gPci) < B_OK) {
124 free(item);
125 return B_ERROR;
128 for (cards = 0, index = 0; gPci->get_nth_pci_info(index++, item) == B_OK; ) {
129 const char *info = identify_device(item);
130 if (info) {
131 char name[64];
132 sprintf(name, "net/ipro1000/%d", cards);
133 dprintf("ipro1000: /dev/%s is a %s\n", name, info);
134 gDevList[cards] = item;
135 gDevNameList[cards] = strdup(name);
136 gDevNameList[cards + 1] = NULL;
137 cards++;
138 item = (pci_info *)malloc(sizeof(pci_info));
139 if (!item)
140 goto err_outofmem;
141 if (cards == MAX_CARDS)
142 break;
146 free(item);
148 if (!cards)
149 goto err_cards;
151 if (initialize_timer() != B_OK) {
152 ERROROUT("timer init failed");
153 goto err_timer;
156 if (mempool_init(cards * 768) != B_OK) {
157 ERROROUT("mempool init failed");
158 goto err_mempool;
161 return B_OK;
163 err_mempool:
164 terminate_timer();
165 err_timer:
166 err_cards:
167 err_outofmem:
168 for (index = 0; index < cards; index++) {
169 free(gDevList[index]);
170 free(gDevNameList[index]);
172 put_module(B_PCI_MODULE_NAME);
173 return B_ERROR;
177 void
178 uninit_driver(void)
180 int32 i;
182 INIT_DEBUGOUT("uninit_driver()");
184 terminate_timer();
186 mempool_exit();
188 for (i = 0; gDevNameList[i] != NULL; i++) {
189 free(gDevList[i]);
190 free(gDevNameList[i]);
193 put_module(B_PCI_MODULE_NAME);
197 device_hooks
198 gDeviceHooks = {
199 ipro1000_open,
200 ipro1000_close,
201 ipro1000_free,
202 ipro1000_control,
203 ipro1000_read,
204 ipro1000_write,
208 const char**
209 publish_devices()
211 return (const char**)gDevNameList;
215 device_hooks*
216 find_device(const char* name)
218 return &gDeviceHooks;