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