This source file includes following definitions.
- hp_plus_probe
- hpp_probe1
- hpp_open
- hpp_close
- hpp_reset_8390
- hpp_io_block_input
- hpp_mem_block_input
- hpp_io_block_output
- hpp_mem_block_output
- init_module
- cleanup_module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 static const char *version =
22 "hp-plus.c:v1.10 9/24/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
23
24 #ifdef MODULE
25 #include <linux/module.h>
26 #include <linux/version.h>
27 #endif
28
29 #include <linux/string.h>
30 #include <linux/kernel.h>
31 #include <linux/sched.h>
32 #include <linux/errno.h>
33 #include <linux/ioport.h>
34 #include <linux/netdevice.h>
35 #include <linux/etherdevice.h>
36
37 #include <asm/system.h>
38 #include <asm/io.h>
39
40
41 #include "8390.h"
42 extern struct device *init_etherdev(struct device *dev, int sizeof_private,
43 unsigned long *mem_startp);
44
45
46 static unsigned int hpplus_portlist[] =
47 {0x200, 0x240, 0x280, 0x2C0, 0x300, 0x320, 0x340, 0};
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74 #define HP_ID 0x00
75 #define HP_PAGING 0x02
76 #define HPP_OPTION 0x04
77 #define HPP_OUT_ADDR 0x08
78 #define HPP_IN_ADDR 0x0A
79 #define HP_DATAPORT 0x0c
80 #define NIC_OFFSET 0x10
81 #define HP_IO_EXTENT 32
82
83 #define HP_START_PG 0x00
84 #define HP_STOP_PG 0x80
85
86
87 enum PageName {
88 Perf_Page = 0,
89 MAC_Page = 1,
90 HW_Page = 2,
91 LAN_Page = 4,
92 ID_Page = 6 };
93
94
95 enum HP_Option {
96 NICReset = 1, ChipReset = 2,
97 EnableIRQ = 4, FakeIntr = 8, BootROMEnb = 0x10, IOEnb = 0x20,
98 MemEnable = 0x40, ZeroWait = 0x80, MemDisable = 0x1000, };
99
100 int hp_plus_probe(struct device *dev);
101 int hpp_probe1(struct device *dev, int ioaddr);
102
103 static void hpp_reset_8390(struct device *dev);
104 static int hpp_open(struct device *dev);
105 static int hpp_close(struct device *dev);
106 static int hpp_mem_block_input(struct device *dev, int count,
107 char *buf, int ring_offset);
108 static void hpp_mem_block_output(struct device *dev, int count,
109 const unsigned char *buf, const start_page);
110 static int hpp_io_block_input(struct device *dev, int count,
111 char *buf, int ring_offset);
112 static void hpp_io_block_output(struct device *dev, int count,
113 const unsigned char *buf, const start_page);
114
115
116
117
118 #ifdef HAVE_DEVLIST
119
120
121 struct netdev_entry hpplus_drv =
122 {"hpplus", hpp_probe1, HP_IO_EXTENT, hpplus_portlist};
123 #else
124
125 int hp_plus_probe(struct device *dev)
126 {
127 int i;
128 int base_addr = dev ? dev->base_addr : 0;
129
130 if (base_addr > 0x1ff)
131 return hpp_probe1(dev, base_addr);
132 else if (base_addr != 0)
133 return ENXIO;
134
135 for (i = 0; hpplus_portlist[i]; i++) {
136 int ioaddr = hpplus_portlist[i];
137 if (check_region(ioaddr, HP_IO_EXTENT))
138 continue;
139 if (hpp_probe1(dev, ioaddr) == 0)
140 return 0;
141 }
142
143 return ENODEV;
144 }
145 #endif
146
147
148 int hpp_probe1(struct device *dev, int ioaddr)
149 {
150 int i;
151 unsigned char checksum = 0;
152 const char *name = "HP-PC-LAN+";
153 int mem_start;
154
155
156 if (inw(ioaddr + HP_ID) != 0x4850
157 || (inw(ioaddr + HP_PAGING) & 0xfff0) != 0x5300)
158 return ENODEV;
159
160 if (dev == NULL)
161 dev = init_etherdev(0, sizeof(struct ei_device), 0);
162
163 printk("%s: %s at %#3x,", dev->name, name, ioaddr);
164
165
166 outw(MAC_Page, ioaddr + HP_PAGING);
167
168 for(i = 0; i < ETHER_ADDR_LEN; i++) {
169 unsigned char inval = inb(ioaddr + 8 + i);
170 dev->dev_addr[i] = inval;
171 checksum += inval;
172 printk(" %2.2x", inval);
173 }
174 checksum += inb(ioaddr + 14);
175
176 if (checksum != 0xff) {
177 printk(" bad checksum %2.2x.\n", checksum);
178 return ENODEV;
179 } else {
180
181 outw(ID_Page, ioaddr + HP_PAGING);
182 printk(" ID %4.4x", inw(ioaddr + 12));
183 }
184
185
186 request_region(ioaddr, HP_IO_EXTENT,"hp-plus");
187
188
189 outw(HW_Page, ioaddr + HP_PAGING);
190 {
191 int irq = inb(ioaddr + 13) & 0x0f;
192 int option = inw(ioaddr + HPP_OPTION);
193
194 dev->irq = irq;
195 if (option & MemEnable) {
196 mem_start = inw(ioaddr + 9) << 8;
197 printk(", IRQ %d, memory address %#x.\n", irq, mem_start);
198 } else {
199 mem_start = 0;
200 printk(", IRQ %d, programmed-I/O mode.\n", irq);
201 }
202 }
203
204 printk( "%s%s", KERN_INFO, version);
205
206
207 outw((HP_START_PG + TX_2X_PAGES) | ((HP_STOP_PG - 1) << 8), ioaddr + 14);
208
209
210 dev->base_addr = ioaddr + NIC_OFFSET;
211
212 ethdev_init(dev);
213
214 dev->open = &hpp_open;
215 dev->stop = &hpp_close;
216
217 ei_status.name = name;
218 ei_status.word16 = 0;
219 ei_status.tx_start_page = HP_START_PG;
220 ei_status.rx_start_page = HP_START_PG + TX_2X_PAGES;
221 ei_status.stop_page = HP_STOP_PG;
222
223 ei_status.reset_8390 = &hpp_reset_8390;
224 ei_status.block_input = &hpp_io_block_input;
225 ei_status.block_output = &hpp_io_block_output;
226
227
228 if (mem_start) {
229 ei_status.block_input = &hpp_mem_block_input;
230 ei_status.block_output = &hpp_mem_block_output;
231 dev->mem_start = mem_start;
232 dev->rmem_start = dev->mem_start + TX_2X_PAGES*256;
233 dev->mem_end = dev->rmem_end
234 = dev->mem_start + (HP_STOP_PG - HP_START_PG)*256;
235 }
236
237 outw(Perf_Page, ioaddr + HP_PAGING);
238 NS8390_init(dev, 0);
239
240 outw(inw(ioaddr + HPP_OPTION) & ~EnableIRQ, ioaddr + HPP_OPTION);
241
242 return 0;
243 }
244
245 static int
246 hpp_open(struct device *dev)
247 {
248 int ioaddr = dev->base_addr - NIC_OFFSET;
249 int option_reg;
250
251 if (request_irq(dev->irq, &ei_interrupt, 0, "hp-plus")) {
252 return -EAGAIN;
253 }
254
255
256 option_reg = inw(ioaddr + HPP_OPTION);
257 outw(option_reg & ~(NICReset + ChipReset), ioaddr + HPP_OPTION);
258 SLOW_DOWN_IO; SLOW_DOWN_IO;
259
260 outw(option_reg | (EnableIRQ + NICReset + ChipReset), ioaddr + HPP_OPTION);
261
262
263 outw(HW_Page, ioaddr + HP_PAGING);
264 outw((HP_START_PG + TX_2X_PAGES) | ((HP_STOP_PG - 1) << 8), ioaddr + 14);
265
266
267 outw(Perf_Page, ioaddr + HP_PAGING);
268
269 return ei_open(dev);
270 }
271
272 static int
273 hpp_close(struct device *dev)
274 {
275 int ioaddr = dev->base_addr - NIC_OFFSET;
276 int option_reg = inw(ioaddr + HPP_OPTION);
277
278 free_irq(dev->irq);
279 irq2dev_map[dev->irq] = NULL;
280 NS8390_init(dev, 0);
281 outw((option_reg & ~EnableIRQ) | MemDisable | NICReset | ChipReset,
282 ioaddr + HPP_OPTION);
283
284 return 0;
285 }
286
287 static void
288 hpp_reset_8390(struct device *dev)
289 {
290 int ioaddr = dev->base_addr - NIC_OFFSET;
291 int option_reg = inw(ioaddr + HPP_OPTION);
292
293 if (ei_debug > 1) printk("resetting the 8390 time=%ld...", jiffies);
294
295 outw(option_reg & ~(NICReset + ChipReset), ioaddr + HPP_OPTION);
296
297 SLOW_DOWN_IO;
298 SLOW_DOWN_IO;
299 ei_status.txing = 0;
300 outw(option_reg | (EnableIRQ + NICReset + ChipReset), ioaddr + HPP_OPTION);
301
302 SLOW_DOWN_IO; SLOW_DOWN_IO;
303
304
305 if ((inb_p(ioaddr+NIC_OFFSET+EN0_ISR) & ENISR_RESET) == 0)
306 printk("%s: hp_reset_8390() did not complete.\n", dev->name);
307
308 if (ei_debug > 1) printk("8390 reset done (%ld).", jiffies);
309 return;
310 }
311
312
313
314
315 static int
316 hpp_io_block_input(struct device *dev, int count, char *buf, int ring_offset)
317 {
318 int ioaddr = dev->base_addr - NIC_OFFSET;
319
320 outw(ring_offset, ioaddr + HPP_IN_ADDR);
321 insw(ioaddr + HP_DATAPORT, buf, count>>1);
322 if (count & 0x01)
323 buf[count-1] = inw(ioaddr + HP_DATAPORT);
324 return ring_offset + count;
325 }
326
327 static int
328 hpp_mem_block_input(struct device *dev, int count, char *buf, int ring_offset)
329 {
330 int ioaddr = dev->base_addr - NIC_OFFSET;
331 int option_reg = inw(ioaddr + HPP_OPTION);
332
333 outw(ring_offset, ioaddr + HPP_IN_ADDR);
334
335 outw(option_reg & ~(MemDisable + BootROMEnb), ioaddr + HPP_OPTION);
336
337 memcpy(buf, (char*)dev->mem_start, (count + 3) & ~3);
338 outw(option_reg, ioaddr + HPP_OPTION);
339
340 return ring_offset + count;
341 }
342
343
344
345 static void
346 hpp_io_block_output(struct device *dev, int count,
347 const unsigned char *buf, const start_page)
348 {
349 int ioaddr = dev->base_addr - NIC_OFFSET;
350 outw(start_page << 8, ioaddr + HPP_OUT_ADDR);
351 outsl(ioaddr + HP_DATAPORT, buf, (count+3)>>2);
352 return;
353 }
354
355 static void
356 hpp_mem_block_output(struct device *dev, int count,
357 const unsigned char *buf, const start_page)
358 {
359 int ioaddr = dev->base_addr - NIC_OFFSET;
360 int option_reg = inw(ioaddr + HPP_OPTION);
361
362 outw(start_page << 8, ioaddr + HPP_OUT_ADDR);
363 outw(option_reg & ~(MemDisable + BootROMEnb), ioaddr + HPP_OPTION);
364 memcpy((char *)dev->mem_start, buf, (count + 3) & ~3);
365 outw(option_reg, ioaddr + HPP_OPTION);
366
367 return;
368 }
369
370 #ifdef MODULE
371 char kernel_version[] = UTS_RELEASE;
372 static struct device dev_hp = {
373 " " , 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, hp_plus_probe };
374
375 int io = 0;
376 int irq = 0;
377
378 int init_module(void)
379 {
380 dev_hp.base_addr = io;
381 dev_hp.irq = irq;
382 if (register_netdev(&dev_hp) != 0) {
383 printk("hp: register_netdev() returned non-zero.\n");
384 return -EIO;
385 }
386 return 0;
387 }
388
389 void
390 cleanup_module(void)
391 {
392 if (MOD_IN_USE)
393 printk("hp: device busy, remove delayed\n");
394 else
395 {
396 unregister_netdev(&dev_hp);
397 }
398 }
399 #endif
400
401
402
403
404
405
406
407
408
409