Tue Mar 17 18:19:15 2009 UTC ()
Add some 'int' into function definitions where the K&R one didn't
specify a type.


(dsl)
diff -r1.22 -r1.23 src/sys/arch/alpha/a12/if_xb.c
diff -r1.6 -r1.7 src/sys/arch/vax/boot/boot/ctu.c
diff -r1.8 -r1.9 src/sys/arch/vax/boot/boot/mfm.c
diff -r1.7 -r1.8 src/sys/arch/vax/boot/boot/tmscp.c
diff -r1.47 -r1.48 src/sys/dev/isa/if_hp.c

cvs diff -r1.22 -r1.23 src/sys/arch/alpha/a12/Attic/if_xb.c (switch to unified diff)

--- src/sys/arch/alpha/a12/Attic/if_xb.c 2009/03/14 21:04:01 1.22
+++ src/sys/arch/alpha/a12/Attic/if_xb.c 2009/03/17 18:19:15 1.23
@@ -1,752 +1,752 @@ @@ -1,752 +1,752 @@
1/* $NetBSD: if_xb.c,v 1.22 2009/03/14 21:04:01 dsl Exp $ */ 1/* $NetBSD: if_xb.c,v 1.23 2009/03/17 18:19:15 dsl Exp $ */
2 2
3/* [Notice revision 2.2] 3/* [Notice revision 2.2]
4 * Copyright (c) 1997, 1998 Avalon Computer Systems, Inc. 4 * Copyright (c) 1997, 1998 Avalon Computer Systems, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Author: Ross Harvey 7 * Author: Ross Harvey
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright and 12 * 1. Redistributions of source code must retain the above copyright and
13 * author notice, this list of conditions, and the following disclaimer. 13 * author notice, this list of conditions, and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of Avalon Computer Systems, Inc. nor the names of 17 * 3. Neither the name of Avalon Computer Systems, Inc. nor the names of
18 * its contributors may be used to endorse or promote products derived 18 * its contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission. 19 * from this software without specific prior written permission.
20 * 4. This copyright will be assigned to The NetBSD Foundation on 20 * 4. This copyright will be assigned to The NetBSD Foundation on
21 * 1/1/2000 unless these terms (including possibly the assignment 21 * 1/1/2000 unless these terms (including possibly the assignment
22 * date) are updated in writing by Avalon prior to the latest specified 22 * date) are updated in writing by Avalon prior to the latest specified
23 * assignment date. 23 * assignment date.
24 * 24 *
25 * THIS SOFTWARE IS PROVIDED BY AVALON COMPUTER SYSTEMS, INC. AND CONTRIBUTORS 25 * THIS SOFTWARE IS PROVIDED BY AVALON COMPUTER SYSTEMS, INC. AND CONTRIBUTORS
26 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 26 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AVALON OR THE CONTRIBUTORS 28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AVALON OR THE CONTRIBUTORS
29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE. 35 * POSSIBILITY OF SUCH DAMAGE.
36 */ 36 */
37 37
38/*  38/*
39 * Notes. 39 * Notes.
40 *  40 *
41 * Since the NetBSD build rules force the use of function prototypes, even on 41 * Since the NetBSD build rules force the use of function prototypes, even on
42 * functions that are defined before they are called, I've taken advantage of 42 * functions that are defined before they are called, I've taken advantage of
43 * the opportunity and organized this module in top down fashion, with 43 * the opportunity and organized this module in top down fashion, with
44 * functions generally calling down the page rather than up. It's different. 44 * functions generally calling down the page rather than up. It's different.
45 * I think I'm getting to like it this way. 45 * I think I'm getting to like it this way.
46 *  46 *
47 * The crossbar interface is not exactly a peripheral device, and it cannot 47 * The crossbar interface is not exactly a peripheral device, and it cannot
48 * appear on anything other than an alpha-based Avalon A12. The crossbar 48 * appear on anything other than an alpha-based Avalon A12. The crossbar
49 * controller is built into the core logic. 49 * controller is built into the core logic.
50 *  50 *
51 * If this version of the driver supports MPS transport, it may have some 51 * If this version of the driver supports MPS transport, it may have some
52 * large static data declarations. Don't worry about it, as Avalon a12 52 * large static data declarations. Don't worry about it, as Avalon a12
53 * support should not appear in a GENERIC or INSTALL kernel. 53 * support should not appear in a GENERIC or INSTALL kernel.
54 *  54 *
55 * (Every A12 ever shipped had 512 MB per CPU except one site, which had 256 55 * (Every A12 ever shipped had 512 MB per CPU except one site, which had 256
56 * MB. Partly has a result of this, it is unlikely that a kernel configured 56 * MB. Partly has a result of this, it is unlikely that a kernel configured
57 * for an A12 would be exactly the thing to use on most workstations, so we 57 * for an A12 would be exactly the thing to use on most workstations, so we
58 * don't really need to worry that we might be configured in a generic or 58 * don't really need to worry that we might be configured in a generic or
59 * site-wide kernel image.) 59 * site-wide kernel image.)
60 *  60 *
61 * This preliminary crossbar driver supports IP transport using PIO. Although 61 * This preliminary crossbar driver supports IP transport using PIO. Although
62 * it would be nice to have a DMA driver, do note that the crossbar register 62 * it would be nice to have a DMA driver, do note that the crossbar register
63 * port is 128 bits wide, so we have 128-bit PIO. (The 21164 write buffer 63 * port is 128 bits wide, so we have 128-bit PIO. (The 21164 write buffer
64 * will combine two 64-bit stores before they get off-chip.) Also, the rtmon 64 * will combine two 64-bit stores before they get off-chip.) Also, the rtmon
65 * driver wasn't DMA either, so at least the NetBSD driver is as good as any 65 * driver wasn't DMA either, so at least the NetBSD driver is as good as any
66 * other that exists now. 66 * other that exists now.
67 *  67 *
68 * We'll do DMA and specialized transport ops later. Given the high speed of 68 * We'll do DMA and specialized transport ops later. Given the high speed of
69 * the PIO mode, no current applications require DMA bandwidth, but everyone 69 * the PIO mode, no current applications require DMA bandwidth, but everyone
70 * benefits from low latency. The PIO mode is actually lower in latency 70 * benefits from low latency. The PIO mode is actually lower in latency
71 * anyway. 71 * anyway.
72 */ 72 */
73 73
74#include "opt_avalon_a12.h" /* Config options headers */ 74#include "opt_avalon_a12.h" /* Config options headers */
75#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 75#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
76 76
77__KERNEL_RCSID(0, "$NetBSD: if_xb.c,v 1.22 2009/03/14 21:04:01 dsl Exp $"); 77__KERNEL_RCSID(0, "$NetBSD: if_xb.c,v 1.23 2009/03/17 18:19:15 dsl Exp $");
78 78
79#include <sys/param.h> 79#include <sys/param.h>
80#include <sys/systm.h> 80#include <sys/systm.h>
81#include <sys/kernel.h> 81#include <sys/kernel.h>
82#include <sys/malloc.h> 82#include <sys/malloc.h>
83#include <sys/device.h> 83#include <sys/device.h>
84#include <sys/socket.h> 84#include <sys/socket.h>
85#include <sys/mbuf.h> 85#include <sys/mbuf.h>
86#include <sys/sockio.h> 86#include <sys/sockio.h>
87 87
88#include <uvm/uvm_extern.h> 88#include <uvm/uvm_extern.h>
89 89
90#include <net/if.h> 90#include <net/if.h>
91#include <net/if_dl.h> 91#include <net/if_dl.h>
92#include <net/if_types.h> 92#include <net/if_types.h>
93#include <net/route.h> 93#include <net/route.h>
94#include <netinet/in.h> 94#include <netinet/in.h>
95#include <netinet/in_var.h> 95#include <netinet/in_var.h>
96 96
97#include <machine/autoconf.h> 97#include <machine/autoconf.h>
98#include <machine/rpb.h> 98#include <machine/rpb.h>
99 99
100#include <dev/isa/isareg.h> 100#include <dev/isa/isareg.h>
101#include <dev/isa/isavar.h> 101#include <dev/isa/isavar.h>
102 102
103#include <dev/pci/pcireg.h> 103#include <dev/pci/pcireg.h>
104#include <dev/pci/pcivar.h> 104#include <dev/pci/pcivar.h>
105 105
106#include <alpha/pci/a12creg.h> 106#include <alpha/pci/a12creg.h>
107#include <alpha/pci/a12cvar.h> 107#include <alpha/pci/a12cvar.h>
108#include <alpha/pci/pci_a12.h> 108#include <alpha/pci/pci_a12.h>
109 109
110#if 1 110#if 1
111#define XB_DEBUG xb_debug 111#define XB_DEBUG xb_debug
112#else 112#else
113#define XB_DEBUG 0 113#define XB_DEBUG 0
114#endif 114#endif
115 115
116#undef Static 116#undef Static
117#if 1 117#if 1
118#define Static 118#define Static
119#else 119#else
120#define Static static 120#define Static static
121#endif 121#endif
122 122
123#define IF_XB() /* Generate ctags(1) key */ 123#define IF_XB() /* Generate ctags(1) key */
124 124
125#define XBAR_MTU (9*1024) /* Quite an arbitrary number */ 125#define XBAR_MTU (9*1024) /* Quite an arbitrary number */
126#define XBAR_MAXFRAMEHDR 48 /* Used to compute if_mtu */ 126#define XBAR_MAXFRAMEHDR 48 /* Used to compute if_mtu */
127 127
128#define XB_DEFAULT_MTU() (XBAR_MTU - XBAR_MAXFRAMEHDR) 128#define XB_DEFAULT_MTU() (XBAR_MTU - XBAR_MAXFRAMEHDR)
129 129
130#define FIFO_WORDCOUNT 60 130#define FIFO_WORDCOUNT 60
131 131
132static int xb_put_blk(struct mbuf *); 132static int xb_put_blk(struct mbuf *);
133static int xb_put(struct mbuf *); 133static int xb_put(struct mbuf *);
134static long xb_fifo_empty(void); 134static long xb_fifo_empty(void);
135 135
136int xbmatch(struct device *, struct cfdata *, void *); 136int xbmatch(struct device *, struct cfdata *, void *);
137void xbattach(struct device *, struct device *, void *); 137void xbattach(struct device *, struct device *, void *);
138 138
139struct xb_softc { 139struct xb_softc {
140 struct device d; 140 struct device d;
141} xb_softc; 141} xb_softc;
142 142
143CFATTACH_DECL(xb, sizeof(struct xb_softc), 143CFATTACH_DECL(xb, sizeof(struct xb_softc),
144 xbmatch, xbattach, NULL, NULL); 144 xbmatch, xbattach, NULL, NULL);
145 145
146extern struct cfdriver xb_cd; 146extern struct cfdriver xb_cd;
147 147
148long *xb_incoming; 148long *xb_incoming;
149int xb_incoming_max = XBAR_MTU; 149int xb_incoming_max = XBAR_MTU;
150 150
151typedef struct ccode_struct { 151typedef struct ccode_struct {
152 int64_t lo64, /* magic channel address s-word, high part*/ 152 int64_t lo64, /* magic channel address s-word, high part*/
153 hi64; /* magic channel address s-word, low part */ 153 hi64; /* magic channel address s-word, low part */
154} ccode_type; 154} ccode_type;
155/* 155/*
156 * Switch channel codes. Prepending one of these words will get you through 156 * Switch channel codes. Prepending one of these words will get you through
157 * the switch, which will eat the word, open the addressed channel, and 157 * the switch, which will eat the word, open the addressed channel, and
158 * forward the rest of the switch frame. Obviously, this helps if the second 158 * forward the rest of the switch frame. Obviously, this helps if the second
159 * switch word in the frame is the address word for a cascaded switch. (This 159 * switch word in the frame is the address word for a cascaded switch. (This
160 * can be repeated for an arbitrary depth of MSN.) The words aren't quite as 160 * can be repeated for an arbitrary depth of MSN.) The words aren't quite as
161 * weird as they look: the switch is really lots of narrow switches in an 161 * weird as they look: the switch is really lots of narrow switches in an
162 * array, and they don't switch an even number of hex digits. Also, there is 162 * array, and they don't switch an even number of hex digits. Also, there is
163 * a parity bit on most of the subunits. 163 * a parity bit on most of the subunits.
164 */ 164 */
165ccode_type channel[]={ 165ccode_type channel[]={
166 { 0x0000000000000000, 0x0000000000000000 }, 166 { 0x0000000000000000, 0x0000000000000000 },
167 { 0x8882108421084210, 0x1104210842108421 }, 167 { 0x8882108421084210, 0x1104210842108421 },
168 { 0x4441084210842108, 0x2208421084210842 }, 168 { 0x4441084210842108, 0x2208421084210842 },
169 { 0xccc318c6318c6318, 0x330c6318c6318c63 }, 169 { 0xccc318c6318c6318, 0x330c6318c6318c63 },
170 { 0x2220842108421084, 0x4410842108421084 }, 170 { 0x2220842108421084, 0x4410842108421084 },
171 { 0xaaa294a5294a5294, 0x5514a5294a5294a5 }, 171 { 0xaaa294a5294a5294, 0x5514a5294a5294a5 },
172 { 0x66618c6318c6318c, 0x6618c6318c6318c6 }, 172 { 0x66618c6318c6318c, 0x6618c6318c6318c6 },
173 { 0xeee39ce739ce739c, 0x771ce739ce739ce7 }, 173 { 0xeee39ce739ce739c, 0x771ce739ce739ce7 },
174 { 0x1110421084210842, 0x8821084210842108 }, 174 { 0x1110421084210842, 0x8821084210842108 },
175 { 0x99925294a5294a52, 0x9925294a5294a529 }, 175 { 0x99925294a5294a52, 0x9925294a5294a529 },
176 { 0x55514a5294a5294a, 0xaa294a5294a5294a }, 176 { 0x55514a5294a5294a, 0xaa294a5294a5294a },
177 { 0xddd35ad6b5ad6b5a, 0xbb2d6b5ad6b5ad6b }, 177 { 0xddd35ad6b5ad6b5a, 0xbb2d6b5ad6b5ad6b },
178 { 0x3330c6318c6318c6, 0xcc318c6318c6318c }, 178 { 0x3330c6318c6318c6, 0xcc318c6318c6318c },
179 { 0xbbb2d6b5ad6b5ad6, 0xdd35ad6b5ad6b5ad } 179 { 0xbbb2d6b5ad6b5ad6, 0xdd35ad6b5ad6b5ad }
180}; 180};
181 181
182Static enum xb_intr_rcv_state_t { 182Static enum xb_intr_rcv_state_t {
183 XBIR_PKTHDR = 0, XBIR_TRANS 183 XBIR_PKTHDR = 0, XBIR_TRANS
184} xb_intr_rcv_state; 184} xb_intr_rcv_state;
185 185
186struct xb_config { int am_i_used; } xb_configuration; 186struct xb_config { int am_i_used; } xb_configuration;
187 187
188Static struct ifnet xbi; 188Static struct ifnet xbi;
189 189
190Static int frame_len; 190Static int frame_len;
191static int xb_debug; 191static int xb_debug;
192 192
193Static void xb_start(struct ifnet *); 193Static void xb_start(struct ifnet *);
194Static void xb_mcrp_write(long *, int, int); 194Static void xb_mcrp_write(long *, int, int);
195static inline void xb_onefree(void); 195static inline void xb_onefree(void);
196static long set_interrupt_on_fifo_empty(void); 196static long set_interrupt_on_fifo_empty(void);
197static void xb_init(struct ifnet *); 197static void xb_init(struct ifnet *);
198static int xb_intr(void *); 198static int xb_intr(void *);
199static void xb_intr_rcv(void); 199static void xb_intr_rcv(void);
200Static void quickload(volatile long *, long *); 200Static void quickload(volatile long *, long *);
201static void xb_init_config(struct xb_config *, int); 201static void xb_init_config(struct xb_config *, int);
202static int xb_output(struct ifnet *, struct mbuf *, 202static int xb_output(struct ifnet *, struct mbuf *,
203 const struct sockaddr *, struct rtentry *); 203 const struct sockaddr *, struct rtentry *);
204static int xb_ioctl(struct ifnet *, u_long, void *); 204static int xb_ioctl(struct ifnet *, u_long, void *);
205static void xb_stop(void); 205static void xb_stop(void);
206static void a12_xbar_setup(void); 206static void a12_xbar_setup(void);
207 207
208/* There Can Be Only One */ 208/* There Can Be Only One */
209 209
210int xbfound; 210int xbfound;
211 211
212int 212int
213xbmatch(struct device *parent, struct cfdata *match, void *aux) 213xbmatch(struct device *parent, struct cfdata *match, void *aux)
214{ 214{
215 215
216 return cputype == ST_AVALON_A12 216 return cputype == ST_AVALON_A12
217 && !xbfound; 217 && !xbfound;
218} 218}
219 219
220void 220void
221xbattach(struct device *parent, struct device *self, void *aux) 221xbattach(struct device *parent, struct device *self, void *aux)
222{ 222{
223 struct xb_config *ccp; 223 struct xb_config *ccp;
224 224
225 strcpy(xbi.if_xname, self->dv_xname); 225 strcpy(xbi.if_xname, self->dv_xname);
226 xbfound = 1; 226 xbfound = 1;
227 ccp = &xb_configuration; 227 ccp = &xb_configuration;
228 xb_init_config(ccp, 1); 228 xb_init_config(ccp, 1);
229 printf(": driver %s mtu %lu\n", "$Revision: 1.22 $", xbi.if_mtu); 229 printf(": driver %s mtu %lu\n", "$Revision: 1.23 $", xbi.if_mtu);
230} 230}
231 231
232static void 232static void
233xb_init_config(struct xb_config *ccp, int mallocsafe) 233xb_init_config(struct xb_config *ccp, int mallocsafe)
234{ 234{
235 /*  235 /*
236 * The driver actually only needs about 64 bytes of buffer but with a 236 * The driver actually only needs about 64 bytes of buffer but with a
237 * nice contiguous frame we can call m_devget() 237 * nice contiguous frame we can call m_devget()
238 */ 238 */
239 if (mallocsafe && xb_incoming == NULL) { 239 if (mallocsafe && xb_incoming == NULL) {
240 xb_incoming = malloc(xb_incoming_max, M_DEVBUF, M_NOWAIT); 240 xb_incoming = malloc(xb_incoming_max, M_DEVBUF, M_NOWAIT);
241 if (xb_incoming == NULL) 241 if (xb_incoming == NULL)
242 DIE(); 242 DIE();
243 } 243 }
244 a12_xbar_setup(); 244 a12_xbar_setup();
245 a12_intr_register_xb(xb_intr); 245 a12_intr_register_xb(xb_intr);
246} 246}
247 247
248/* 248/*
249 * From The A12 Theory of Operation. Used with permission. 249 * From The A12 Theory of Operation. Used with permission.
250 * --- --- ------ -- --------- 250 * --- --- ------ -- ---------
251 * 251 *
252 * Message Channel Status Register 252 * Message Channel Status Register
253 * 253 *
254 * 31 0 254 * 31 0
255 * | | 255 * | |
256 * 10987654 32109876 54321098 76543210  256 * 10987654 32109876 54321098 76543210
257 * 257 *
258 * ........ ........ 0oiefaAr TR...... MCSR 258 * ........ ........ 0oiefaAr TR...... MCSR
259 * 259 *
260 * Field Type Name Function 260 * Field Type Name Function
261 * 261 *
262 * R R,W1C RBC Receive Block Complete 262 * R R,W1C RBC Receive Block Complete
263 * T R,W1C TBC Transmit Block Complete 263 * T R,W1C TBC Transmit Block Complete
264 * r R IMP Incoming message pending 264 * r R IMP Incoming message pending
265 * A R IMFAE Incoming message fifo almost empty 265 * A R IMFAE Incoming message fifo almost empty
266 * a R OMFAF Outgoing message fifo almost full 266 * a R OMFAF Outgoing message fifo almost full
267 * f R OMFF Outgoing message fifo full 267 * f R OMFF Outgoing message fifo full
268 * e R OMFE Outgoing message fifo empty 268 * e R OMFE Outgoing message fifo empty
269 * i R DMAin Incoming DMA channel armed 269 * i R DMAin Incoming DMA channel armed
270 * o R DMAout Outgoing DMA channel armed 270 * o R DMAout Outgoing DMA channel armed
271 *  271 *
272 * Interrupts Generated from MCSR 272 * Interrupts Generated from MCSR
273 * 273 *
274 * IMChInt <= (RBC or IMP) and not DMAin 274 * IMChInt <= (RBC or IMP) and not DMAin
275 * OMChInt <= ((TBC and not OMFAF) or (OMFE and OMR.E(6)) 275 * OMChInt <= ((TBC and not OMFAF) or (OMFE and OMR.E(6))
276 * ) and not DMAout 276 * ) and not DMAout
277 * 277 *
278 */ 278 */
279static int 279static int
280xb_intr(void *p) 280xb_intr(void *p)
281{ 281{
282 int n; 282 int n;
283 long mcsrval; 283 long mcsrval;
284 /*  284 /*
285 * The actual conditions under which this interrupt is generated are 285 * The actual conditions under which this interrupt is generated are
286 * a bit complicated, and no status flag is available that reads out 286 * a bit complicated, and no status flag is available that reads out
287 * the final values of the interrupt inputs. But, it doesn't really 287 * the final values of the interrupt inputs. But, it doesn't really
288 * matter. Simply check for receive data and transmitter IFF_OACTIVE. 288 * matter. Simply check for receive data and transmitter IFF_OACTIVE.
289 */ 289 */
290 while ((mcsrval = REGVAL(A12_MCSR)) & A12_MCSR_IMP) 290 while ((mcsrval = REGVAL(A12_MCSR)) & A12_MCSR_IMP)
291 for(n = mcsrval & A12_MCSR_IMFAE ? 1 : 5; n; --n) 291 for(n = mcsrval & A12_MCSR_IMFAE ? 1 : 5; n; --n)
292 xb_intr_rcv(); 292 xb_intr_rcv();
293 293
294 if (xbi.if_flags & IFF_OACTIVE 294 if (xbi.if_flags & IFF_OACTIVE
295 && mcsrval & A12_MCSR_OMFE) { 295 && mcsrval & A12_MCSR_OMFE) {
296 xbi.if_flags &= ~IFF_OACTIVE; 296 xbi.if_flags &= ~IFF_OACTIVE;
297 REGVAL(A12_OMR) &= ~A12_OMR_OMF_ENABLE; 297 REGVAL(A12_OMR) &= ~A12_OMR_OMF_ENABLE;
298 alpha_wmb(); 298 alpha_wmb();
299 xb_start(&xbi); 299 xb_start(&xbi);
300 } 300 }
301 return 0; 301 return 0;
302} 302}
303/*  303/*
304 * The interface logic will shoot us down with MCE (Missing Close Error) or 304 * The interface logic will shoot us down with MCE (Missing Close Error) or
305 * ECE (Embedded Close Error) if we aren't in sync with the hardware w.r.t. 305 * ECE (Embedded Close Error) if we aren't in sync with the hardware w.r.t.
306 * frame boundaries. As those are panic-level errors: Don't Get Them. 306 * frame boundaries. As those are panic-level errors: Don't Get Them.
307 */ 307 */
308static void 308static void
309xb_intr_rcv() 309xb_intr_rcv()
310{ 310{
311struct mbuf *m; 311struct mbuf *m;
312long frameword[2]; 312long frameword[2];
313static long *xb_ibp; 313static long *xb_ibp;
314int s = 0; /* XXX gcc */ 314int s = 0; /* XXX gcc */
315 315
316 switch (xb_intr_rcv_state) { 316 switch (xb_intr_rcv_state) {
317 case XBIR_PKTHDR: 317 case XBIR_PKTHDR:
318 xb_ibp = xb_incoming; 318 xb_ibp = xb_incoming;
319 quickload(REGADDR(A12_FIFO), frameword); /* frame_len >= 16 */ 319 quickload(REGADDR(A12_FIFO), frameword); /* frame_len >= 16 */
320 frame_len = frameword[0]; 320 frame_len = frameword[0];
321 if (!(20 <= frame_len && frame_len+16 <= xb_incoming_max)) 321 if (!(20 <= frame_len && frame_len+16 <= xb_incoming_max))
322 DIE(); 322 DIE();
323 /* 323 /*
324 * The extra word when frames are of an aligned size is due 324 * The extra word when frames are of an aligned size is due
325 * to the way the output routines work. After the mbuf is 325 * to the way the output routines work. After the mbuf is
326 * sent xb_put_blk(NULL) is called. If there is a leftover 326 * sent xb_put_blk(NULL) is called. If there is a leftover
327 * 127-bit-or-less fragment then the close word rides on it, 327 * 127-bit-or-less fragment then the close word rides on it,
328 * otherwise it gets an entire 128 bits of zeroes. 328 * otherwise it gets an entire 128 bits of zeroes.
329 */ 329 */
330 if (frame_len & 0xf) 330 if (frame_len & 0xf)
331 frame_len = (frame_len + 0xf) >> 4; 331 frame_len = (frame_len + 0xf) >> 4;
332 else frame_len = (frame_len >> 4) + 1; 332 else frame_len = (frame_len >> 4) + 1;
333 --frame_len; /* we read the frame len + the first packet int64 */ 333 --frame_len; /* we read the frame len + the first packet int64 */
334 *xb_ibp++ = frameword[1]; 334 *xb_ibp++ = frameword[1];
335 xb_intr_rcv_state = XBIR_TRANS; 335 xb_intr_rcv_state = XBIR_TRANS;
336 break; 336 break;
337 case XBIR_TRANS: 337 case XBIR_TRANS:
338 if (frame_len > 1) 338 if (frame_len > 1)
339 quickload(REGADDR(A12_FIFO), frameword); 339 quickload(REGADDR(A12_FIFO), frameword);
340 else if (frame_len == 1) { 340 else if (frame_len == 1) {
341 quickload(REGADDR(A12_FIFO_LWE), frameword); 341 quickload(REGADDR(A12_FIFO_LWE), frameword);
342 xb_intr_rcv_state = XBIR_PKTHDR; 342 xb_intr_rcv_state = XBIR_PKTHDR;
343 } else if (XB_DEBUG) 343 } else if (XB_DEBUG)
344 DIE(); 344 DIE();
345 --frame_len; 345 --frame_len;
346 xb_ibp[0] = frameword[0]; 346 xb_ibp[0] = frameword[0];
347 xb_ibp[1] = frameword[1]; 347 xb_ibp[1] = frameword[1];
348 xb_ibp += 2; 348 xb_ibp += 2;
349 if (xb_intr_rcv_state == XBIR_PKTHDR) { 349 if (xb_intr_rcv_state == XBIR_PKTHDR) {
350 if (XB_DEBUG) { 350 if (XB_DEBUG) {
351 s = splnet(); 351 s = splnet();
352 if (s != splnet()) 352 if (s != splnet())
353 DIE(); 353 DIE();
354 } 354 }
355 ++xbi.if_ipackets; 355 ++xbi.if_ipackets;
356 if (IF_QFULL(&ipintrq)) { 356 if (IF_QFULL(&ipintrq)) {
357 IF_DROP(&ipintrq); 357 IF_DROP(&ipintrq);
358 ++xbi.if_iqdrops; 358 ++xbi.if_iqdrops;
359 } else { 359 } else {
360 m = m_devget((void *)xb_incoming, 360 m = m_devget((void *)xb_incoming,
361 (char *)xb_ibp - (char *)xb_incoming, 361 (char *)xb_ibp - (char *)xb_incoming,
362 0, &xbi, 0L); 362 0, &xbi, 0L);
363 if (m) { 363 if (m) {
364 xbi.if_ibytes += m->m_pkthdr.len; 364 xbi.if_ibytes += m->m_pkthdr.len;
365 IF_ENQUEUE(&ipintrq, m); 365 IF_ENQUEUE(&ipintrq, m);
366 } else 366 } else
367 ++xbi.if_ierrors; 367 ++xbi.if_ierrors;
368 } 368 }
369 if (XB_DEBUG) 369 if (XB_DEBUG)
370 splx(s); 370 splx(s);
371 } 371 }
372 break; 372 break;
373 default: 373 default:
374 DIE(); 374 DIE();
375 } 375 }
376} 376}
377/* 377/*
378 * Make it easy for gcc to load a[0..1] without interlocking between 378 * Make it easy for gcc to load a[0..1] without interlocking between
379 * a[0] and a[1]. (If it did, that would be two external bus cycles.) 379 * a[0] and a[1]. (If it did, that would be two external bus cycles.)
380 */ 380 */
381Static void 381Static void
382quickload(volatile long *a, long *b) 382quickload(volatile long *a, long *b)
383{ 383{
384long t1,t2; 384long t1,t2;
385 385
386 t1 = a[0]; 386 t1 = a[0];
387 t2 = a[1]; 387 t2 = a[1];
388 b[0] = t1; 388 b[0] = t1;
389 b[1] = t2; 389 b[1] = t2;
390} 390}
391/* 391/*
392 * Verify during debugging that we have not overflowed the FIFO  392 * Verify during debugging that we have not overflowed the FIFO
393 */ 393 */
394static inline void 394static inline void
395xb_onefree() 395xb_onefree()
396{ 396{
397 if (XB_DEBUG && REGVAL(A12_MCSR) & A12_MCSR_OMFF) 397 if (XB_DEBUG && REGVAL(A12_MCSR) & A12_MCSR_OMFF)
398 DIE(); 398 DIE();
399} 399}
400 400
401static void 401static void
402xb_init(struct ifnet *ifp) 402xb_init(struct ifnet *ifp)
403{ 403{
404 ifp->if_flags |= IFF_RUNNING; 404 ifp->if_flags |= IFF_RUNNING;
405} 405}
406 406
407static void 407static void
408xb_stop() 408xb_stop()
409{ 409{
410} 410}
411 411
412static int 412static int
413xb_ioctl(struct ifnet *ifp, unsigned long cmd, void *data) 413xb_ioctl(struct ifnet *ifp, unsigned long cmd, void *data)
414{ 414{
415 struct ifaddr *ifa = (struct ifaddr *)data; 415 struct ifaddr *ifa = (struct ifaddr *)data;
416 int s, error = 0; 416 int s, error = 0;
417 417
418 s = splnet(); 418 s = splnet();
419 switch (cmd) { 419 switch (cmd) {
420 case SIOCINITIFADDR: 420 case SIOCINITIFADDR:
421 xbi.if_flags |= IFF_UP; 421 xbi.if_flags |= IFF_UP;
422 xb_init(ifp); 422 xb_init(ifp);
423 break; 423 break;
424 case SIOCSIFFLAGS: 424 case SIOCSIFFLAGS:
425 if ((error = ifioctl_common(ifp, cmd, data)) != 0) 425 if ((error = ifioctl_common(ifp, cmd, data)) != 0)
426 break; 426 break;
427 if ((ifp->if_flags & IFF_UP) == 0 && 427 if ((ifp->if_flags & IFF_UP) == 0 &&
428 (ifp->if_flags & IFF_RUNNING) != 0) { 428 (ifp->if_flags & IFF_RUNNING) != 0) {
429 xb_stop(); 429 xb_stop();
430 ifp->if_flags &= ~IFF_RUNNING; 430 ifp->if_flags &= ~IFF_RUNNING;
431 } else if ((ifp->if_flags & IFF_UP) != 0 && 431 } else if ((ifp->if_flags & IFF_UP) != 0 &&
432 (ifp->if_flags & IFF_RUNNING) == 0) { 432 (ifp->if_flags & IFF_RUNNING) == 0) {
433 xb_start(ifp); 433 xb_start(ifp);
434 } else 434 } else
435 xb_init(ifp); 435 xb_init(ifp);
436 if (ifp->if_flags & IFF_DEBUG) 436 if (ifp->if_flags & IFF_DEBUG)
437 xb_debug = 1; 437 xb_debug = 1;
438 break; 438 break;
439 default: 439 default:
440 error = ifioctl_common(ifp, cmd, data); 440 error = ifioctl_common(ifp, cmd, data);
441 break; 441 break;
442 } 442 }
443 splx(s); 443 splx(s);
444 return error; 444 return error;
445} 445}
446/* 446/*
447 * XXX - someday, keep a software copy of A12_OMR. We can execute up to 447 * XXX - someday, keep a software copy of A12_OMR. We can execute up to
448 * 200 or 300 instructions in the time it takes to do the read part of an 448 * 200 or 300 instructions in the time it takes to do the read part of an
449 * external bus cycle RMW op. (Or 10 - 20 cache cycles.) 449 * external bus cycle RMW op. (Or 10 - 20 cache cycles.)
450 */ 450 */
451static inline long 451static inline long
452xb_fifo_empty(void) 452xb_fifo_empty(void)
453{ 453{
454 return REGVAL(A12_MCSR) & A12_MCSR_OMFE; 454 return REGVAL(A12_MCSR) & A12_MCSR_OMFE;
455} 455}
456/* 456/*
457 * rtmon frames 457 * rtmon frames
458 * 458 *
459 * [ (... data) : commid : sourcepid : dstpid : ktype : length : frametype ] 459 * [ (... data) : commid : sourcepid : dstpid : ktype : length : frametype ]
460 * 460 *
461 * At the moment, NetBSD ip frames are not compatible with rtmon frames: 461 * At the moment, NetBSD ip frames are not compatible with rtmon frames:
462 * 462 *
463 * [ ... data : length ] 463 * [ ... data : length ]
464 */ 464 */
465static int 465static int
466xb_output(struct ifnet *ifp, struct mbuf *m0, const struct sockaddr *dst, struct rtentry *rt0) 466xb_output(struct ifnet *ifp, struct mbuf *m0, const struct sockaddr *dst, struct rtentry *rt0)
467{ 467{
468 int i,s; 468 int i,s;
469 struct mbuf *m = m0; 469 struct mbuf *m = m0;
470 const char *lladdr; 470 const char *lladdr;
471 char *xbh; 471 char *xbh;
472 long xbo_framesize; 472 long xbo_framesize;
473 const struct sockaddr_dl *llsa; 473 const struct sockaddr_dl *llsa;
474 int xbaddr; 474 int xbaddr;
475 475
476#ifdef DIAGNOSTIC 476#ifdef DIAGNOSTIC
477 if (ifp != &xbi) 477 if (ifp != &xbi)
478 DIE(); 478 DIE();
479#endif 479#endif
480 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) { 480 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) {
481 m_freem(m); 481 m_freem(m);
482 return ENETDOWN; 482 return ENETDOWN;
483 } 483 }
484 /* 484 /*
485 * We want an IP packet with a link level route, on a silver platter. 485 * We want an IP packet with a link level route, on a silver platter.
486 */ 486 */
487 if (rt0 == NULL 487 if (rt0 == NULL
488 || (rt0->rt_flags & (RTF_GATEWAY | RTF_LLINFO)) 488 || (rt0->rt_flags & (RTF_GATEWAY | RTF_LLINFO))
489 || (llsa = satocsdl(rt0->rt_gateway)) == NULL 489 || (llsa = satocsdl(rt0->rt_gateway)) == NULL
490 || llsa->sdl_family != AF_LINK 490 || llsa->sdl_family != AF_LINK
491 || llsa->sdl_slen != 0) { 491 || llsa->sdl_slen != 0) {
492 ++ifp->if_oerrors; 492 ++ifp->if_oerrors;
493 m_freem(m); 493 m_freem(m);
494 return EHOSTUNREACH; 494 return EHOSTUNREACH;
495 } 495 }
496 if (dst == NULL 496 if (dst == NULL
497 || dst->sa_family != AF_INET) { 497 || dst->sa_family != AF_INET) {
498 /* 498 /*
499 * This is because we give all received packets to ipintrq 499 * This is because we give all received packets to ipintrq
500 * right now. 500 * right now.
501 */ 501 */
502 What(); 502 What();
503 m_freem(m); 503 m_freem(m);
504 ++ifp->if_noproto; 504 ++ifp->if_noproto;
505 return EAFNOSUPPORT; 505 return EAFNOSUPPORT;
506 } 506 }
507 /*  507 /*
508 * The a12MppSwitch is a wormhole routed MSN consisting of a number 508 * The a12MppSwitch is a wormhole routed MSN consisting of a number
509 * (usually n==1) of 14 channel crossbar switches. Each route through 509 * (usually n==1) of 14 channel crossbar switches. Each route through
510 * a switch requires a 128 bit address word that specifies the channel 510 * a switch requires a 128 bit address word that specifies the channel
511 * to emerge on. The address word is eaten by the switch and the 511 * to emerge on. The address word is eaten by the switch and the
512 * rest of the packet is routed through. 512 * rest of the packet is routed through.
513 */ 513 */
514 lladdr = CLLADDR(llsa); 514 lladdr = CLLADDR(llsa);
515 if (llsa->sdl_alen != 1) /* XXX */ 515 if (llsa->sdl_alen != 1) /* XXX */
516 DIE(); /* OK someday, but totally unexpected right now */ 516 DIE(); /* OK someday, but totally unexpected right now */
517 /* 517 /*
518 * Alternatively, we could lookup the address word and output 518 * Alternatively, we could lookup the address word and output
519 * it with PIO when the mbuf is dequeued 519 * it with PIO when the mbuf is dequeued
520 */ 520 */
521 xbo_framesize = m->m_pkthdr.len + 8; 521 xbo_framesize = m->m_pkthdr.len + 8;
522 M_PREPEND(m, 16 * llsa->sdl_alen + 8, M_DONTWAIT); 522 M_PREPEND(m, 16 * llsa->sdl_alen + 8, M_DONTWAIT);
523 if (m == NULL) 523 if (m == NULL)
524 return ENOBUFS; 524 return ENOBUFS;
525 xbh = mtod(m, char *); 525 xbh = mtod(m, char *);
526 for (i=0; i<llsa->sdl_alen; ++i) { 526 for (i=0; i<llsa->sdl_alen; ++i) {
527 xbaddr = (lladdr[i] & 0xff) - 1; 527 xbaddr = (lladdr[i] & 0xff) - 1;
528 if (!(0 <= xbaddr && xbaddr <= 11)) /* XXX */ 528 if (!(0 <= xbaddr && xbaddr <= 11)) /* XXX */
529 DIE(); /* 12 or 13 will be OK later */ 529 DIE(); /* 12 or 13 will be OK later */
530 memcpy(xbh, &channel[xbaddr].lo64, 16); 530 memcpy(xbh, &channel[xbaddr].lo64, 16);
531 xbh += 16; 531 xbh += 16;
532 } 532 }
533 memcpy(xbh, &xbo_framesize, 8); 533 memcpy(xbh, &xbo_framesize, 8);
534 s = splnet(); 534 s = splnet();
535 if (IF_QFULL(&ifp->if_snd)) { 535 if (IF_QFULL(&ifp->if_snd)) {
536 IF_DROP(&ifp->if_snd); 536 IF_DROP(&ifp->if_snd);
537 ++ifp->if_oerrors; 537 ++ifp->if_oerrors;
538 splx(s); 538 splx(s);
539 m_freem(m); 539 m_freem(m);
540 return ENOBUFS; 540 return ENOBUFS;
541 } 541 }
542 ifp->if_obytes += m->m_pkthdr.len; 542 ifp->if_obytes += m->m_pkthdr.len;
543 ++ifp->if_opackets; 543 ++ifp->if_opackets;
544 IF_ENQUEUE(&ifp->if_snd, m); 544 IF_ENQUEUE(&ifp->if_snd, m);
545 if ((ifp->if_flags & IFF_OACTIVE) == 0) 545 if ((ifp->if_flags & IFF_OACTIVE) == 0)
546 xb_start(ifp); 546 xb_start(ifp);
547 splx(s); 547 splx(s);
548 if (m->m_flags & M_MCAST) 548 if (m->m_flags & M_MCAST)
549 ifp->if_omcasts++; 549 ifp->if_omcasts++;
550 return 0; 550 return 0;
551} 551}
552 552
553void 553void
554xb_start(struct ifnet *ifp) 554xb_start(struct ifnet *ifp)
555{ 555{
556 struct mbuf *m; 556 struct mbuf *m;
557 557
558 if ((xbi.if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 558 if ((xbi.if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
559 return; 559 return;
560 for (;;) { 560 for (;;) {
561 IF_DEQUEUE(&xbi.if_snd, m); 561 IF_DEQUEUE(&xbi.if_snd, m);
562 if (m == 0) 562 if (m == 0)
563 return; 563 return;
564 /* 564 /*
565 * XXX The variable-length switch address words cause problems 565 * XXX The variable-length switch address words cause problems
566 * for bpf, for now, leave it out. XXX It's not too hard to 566 * for bpf, for now, leave it out. XXX It's not too hard to
567 * fix, though, as there are lots of techniques that will 567 * fix, though, as there are lots of techniques that will
568 * identify the number of switch address words. 568 * identify the number of switch address words.
569 */ 569 */
570 if (!xb_put(m)) { 570 if (!xb_put(m)) {
571 xbi.if_flags |= IFF_OACTIVE; 571 xbi.if_flags |= IFF_OACTIVE;
572 return; 572 return;
573 } 573 }
574 } 574 }
575} 575}
576 576
577static int 577static int
578xb_put(struct mbuf *m) 578xb_put(struct mbuf *m)
579{ 579{
580 struct mbuf *n; 580 struct mbuf *n;
581 int len; 581 int len;
582 582
583 if (XB_DEBUG && (alpha_pal_rdps() & 7) < 3) 583 if (XB_DEBUG && (alpha_pal_rdps() & 7) < 3)
584 DIE(); /* this "cannot happen", of course */ 584 DIE(); /* this "cannot happen", of course */
585 for (; m; m = n) { 585 for (; m; m = n) {
586 len = m->m_len; 586 len = m->m_len;
587 if (len == 0 || xb_put_blk(m)) 587 if (len == 0 || xb_put_blk(m))
588 MFREE(m, n); 588 MFREE(m, n);
589 else return 0; 589 else return 0;
590 } 590 }
591 xb_put_blk(NULL); 591 xb_put_blk(NULL);
592 return 1; 592 return 1;
593} 593}
594/* 594/*
595 * Write a single mbuf to the transmit channel fifo. We can only write 128-bit 595 * Write a single mbuf to the transmit channel fifo. We can only write 128-bit
596 * words. Right now, we pad at the end. It is possible to pad at the 596 * words. Right now, we pad at the end. It is possible to pad at the
597 * beginning, especially since lots of games can be played at the receiver 597 * beginning, especially since lots of games can be played at the receiver
598 * with the mbuf data pointer. Padding at the beginning requires a pad-count 598 * with the mbuf data pointer. Padding at the beginning requires a pad-count
599 * field in a header, but it means you can always DMA the data, regardless of 599 * field in a header, but it means you can always DMA the data, regardless of
600 * alignment. Of course, we don't DMA at all, right now. 600 * alignment. Of course, we don't DMA at all, right now.
601 */ 601 */
602static int 602static int
603xb_put_blk(struct mbuf *m) 603xb_put_blk(struct mbuf *m)
604{ 604{
605 static long leftover[2]; /* 0-15 bytes from last xb_put_blk() */ 605 static long leftover[2]; /* 0-15 bytes from last xb_put_blk() */
606 static int leftover_len; /* non-aligned amount from last call */ 606 static int leftover_len; /* non-aligned amount from last call */
607 long xfertmp[8]; /* aligned switch word buffer */ 607 long xfertmp[8]; /* aligned switch word buffer */
608 int frag_len, /* fifo stream unit */ 608 int frag_len, /* fifo stream unit */
609 fifo_len, /* space left in fifo */ 609 fifo_len, /* space left in fifo */
610 fillin, /* amount needed to complete a switch word */ 610 fillin, /* amount needed to complete a switch word */
611 full, /* remember to restart on fifo full */ 611 full, /* remember to restart on fifo full */
612 len; /* amount of mbuf left to do */ 612 len; /* amount of mbuf left to do */
613 char *blk; /* location we are at in mbuf */ 613 char *blk; /* location we are at in mbuf */
614 static int fifo_free; /* current # of switch words free in fifo */ 614 static int fifo_free; /* current # of switch words free in fifo */
615 615
616#define XFERADJ() ((char *)xfertmp + leftover_len) 616#define XFERADJ() ((char *)xfertmp + leftover_len)
617 617
618 /* There is always room for the close word */ 618 /* There is always room for the close word */
619 619
620 if (m == NULL) { 620 if (m == NULL) {
621 if (leftover_len) 621 if (leftover_len)
622 leftover_len = 0; 622 leftover_len = 0;
623 else leftover[0] = leftover[1] = 0; 623 else leftover[0] = leftover[1] = 0;
624 xb_mcrp_write(leftover, 1, 1); 624 xb_mcrp_write(leftover, 1, 1);
625 --fifo_free; 625 --fifo_free;
626 return 1; 626 return 1;
627 } 627 }
628 628
629restart: 629restart:
630 if (fifo_free < 2) { 630 if (fifo_free < 2) {
631 if (!xb_fifo_empty()) { 631 if (!xb_fifo_empty()) {
632 if(!set_interrupt_on_fifo_empty()) { 632 if(!set_interrupt_on_fifo_empty()) {
633 /* still empty */ 633 /* still empty */
634 xbi.if_flags |= IFF_OACTIVE; 634 xbi.if_flags |= IFF_OACTIVE;
635 IF_PREPEND(&xbi.if_snd, m); 635 IF_PREPEND(&xbi.if_snd, m);
636 return 0; 636 return 0;
637 } 637 }
638 } 638 }
639 fifo_free = FIFO_WORDCOUNT; 639 fifo_free = FIFO_WORDCOUNT;
640 } 640 }
641 len = m->m_len; 641 len = m->m_len;
642 if (len == 0) 642 if (len == 0)
643 return 1; /* clean finish, nothing left over */ 643 return 1; /* clean finish, nothing left over */
644 blk = mtod(m, char *); 644 blk = mtod(m, char *);
645 if (leftover_len) { 645 if (leftover_len) {
646 /* See function intro comment regarding padding */ 646 /* See function intro comment regarding padding */
647 if (leftover_len + len < sizeof leftover) { 647 if (leftover_len + len < sizeof leftover) {
648 /* Heh, not even enough to write out */ 648 /* Heh, not even enough to write out */
649 memcpy(XFERADJ(), blk, len); 649 memcpy(XFERADJ(), blk, len);
650 leftover_len += len; 650 leftover_len += len;
651 return 1; 651 return 1;
652 } 652 }
653 xfertmp[0] = leftover[0]; 653 xfertmp[0] = leftover[0];
654 xfertmp[1] = leftover[1]; 654 xfertmp[1] = leftover[1];
655 fillin = sizeof leftover - leftover_len; 655 fillin = sizeof leftover - leftover_len;
656 memcpy(XFERADJ(), blk, fillin); 656 memcpy(XFERADJ(), blk, fillin);
657 blk += fillin; 657 blk += fillin;
658 len -= fillin; 658 len -= fillin;
659 xb_mcrp_write(xfertmp, 1, 0); 659 xb_mcrp_write(xfertmp, 1, 0);
660 leftover_len = 0; 660 leftover_len = 0;
661 --fifo_free; 661 --fifo_free;
662 } 662 }
663 /* fifo_free is known to be >= 1 at this point */ 663 /* fifo_free is known to be >= 1 at this point */
664 while (len >= 16) { 664 while (len >= 16) {
665 full = 0; 665 full = 0;
666 frag_len = sizeof xfertmp; 666 frag_len = sizeof xfertmp;
667 if (frag_len > len) 667 if (frag_len > len)
668 frag_len = len; 668 frag_len = len;
669 fifo_len = fifo_free * 16; 669 fifo_len = fifo_free * 16;
670 if (frag_len > fifo_len) { 670 if (frag_len > fifo_len) {
671 frag_len = fifo_len; 671 frag_len = fifo_len;
672 full = 1; 672 full = 1;
673 } 673 }
674 frag_len &= ~0xf; 674 frag_len &= ~0xf;
675 memcpy(xfertmp, blk, frag_len); 675 memcpy(xfertmp, blk, frag_len);
676 frag_len >>= 4; /* Round down to switch word size */ 676 frag_len >>= 4; /* Round down to switch word size */
677 xb_mcrp_write(xfertmp, frag_len, 0); 677 xb_mcrp_write(xfertmp, frag_len, 0);
678 fifo_free -= frag_len; 678 fifo_free -= frag_len;
679 frag_len <<= 4; 679 frag_len <<= 4;
680 len -= frag_len; 680 len -= frag_len;
681 blk += frag_len; 681 blk += frag_len;
682 if (full) { 682 if (full) {
683 m_adj(m, blk - mtod(m, char *)); 683 m_adj(m, blk - mtod(m, char *));
684 goto restart; 684 goto restart;
685 } 685 }
686 } 686 }
687 memcpy(leftover, blk, len); 687 memcpy(leftover, blk, len);
688 leftover_len = len; 688 leftover_len = len;
689 return 1; 689 return 1;
690} 690}
691 691
692static long 692static long
693set_interrupt_on_fifo_empty(void) 693set_interrupt_on_fifo_empty(void)
694{ 694{
695 REGVAL(A12_OMR) |= A12_OMR_OMF_ENABLE; 695 REGVAL(A12_OMR) |= A12_OMR_OMF_ENABLE;
696 alpha_mb(); 696 alpha_mb();
697 if(xb_fifo_empty()) { 697 if(xb_fifo_empty()) {
698 REGVAL(A12_OMR) &= ~A12_OMR_OMF_ENABLE; 698 REGVAL(A12_OMR) &= ~A12_OMR_OMF_ENABLE;
699 alpha_mb(); 699 alpha_mb();
700 return 1; 700 return 1;
701 } 701 }
702 return 0; 702 return 0;
703} 703}
704/* 704/*
705 * Write an aligned block of switch words to the FIFO 705 * Write an aligned block of switch words to the FIFO
706 */ 706 */
707Static void 707Static void
708xb_mcrp_write(long *d, n, islast) 708xb_mcrp_write(long *d, int n, int islast)
709{ 709{
710 volatile long *xb_fifo = islast ? REGADDR(A12_FIFO_LWE)  710 volatile long *xb_fifo = islast ? REGADDR(A12_FIFO_LWE)
711 : REGADDR(A12_FIFO); 711 : REGADDR(A12_FIFO);
712 int i; 712 int i;
713 713
714 if (XB_DEBUG && islast && n != 1) 714 if (XB_DEBUG && islast && n != 1)
715 DIE(); 715 DIE();
716 n <<= 1; 716 n <<= 1;
717 for (i = 0; i < n; i += 2) { 717 for (i = 0; i < n; i += 2) {
718 xb_onefree(); 718 xb_onefree();
719 xb_fifo[0] = d[i]; 719 xb_fifo[0] = d[i];
720 xb_fifo[1] = d[i+1]; 720 xb_fifo[1] = d[i+1];
721 alpha_wmb(); 721 alpha_wmb();
722 } 722 }
723} 723}
724 724
725/* 725/*
726const 726const
727int32_t xbar_bc_addr = XBAR_BROADCAST; 727int32_t xbar_bc_addr = XBAR_BROADCAST;
728 */ 728 */
729 729
730static void 730static void
731a12_xbar_setup() 731a12_xbar_setup()
732{ 732{
733 xbi.if_softc = &xb_softc; 733 xbi.if_softc = &xb_softc;
734 xbi.if_start = xb_start; 734 xbi.if_start = xb_start;
735 xbi.if_ioctl = xb_ioctl; 735 xbi.if_ioctl = xb_ioctl;
736 xbi.if_flags = IFF_BROADCAST /* ha ha */ 736 xbi.if_flags = IFF_BROADCAST /* ha ha */
737 | IFF_SIMPLEX; 737 | IFF_SIMPLEX;
738 738
739 xbi.if_type = IFT_A12MPPSWITCH; 739 xbi.if_type = IFT_A12MPPSWITCH;
740 xbi.if_addrlen = 32; 740 xbi.if_addrlen = 32;
741 xbi.if_hdrlen = 32; 741 xbi.if_hdrlen = 32;
742 xbi.if_mtu = XB_DEFAULT_MTU(); 742 xbi.if_mtu = XB_DEFAULT_MTU();
743 xbi.if_output = xb_output; 743 xbi.if_output = xb_output;
744 /* xbi.if_broadcastaddr = (u_int8_t)&xbar_bc_addr; */ 744 /* xbi.if_broadcastaddr = (u_int8_t)&xbar_bc_addr; */
745 745
746 if_attach(&xbi); 746 if_attach(&xbi);
747 if_alloc_sadl(&xbi); 747 if_alloc_sadl(&xbi);
748 748
749#if NBPFILTER > 0 749#if NBPFILTER > 0
750 bpfattach(&xbi, DLT_NULL, 0); 750 bpfattach(&xbi, DLT_NULL, 0);
751#endif 751#endif
752} 752}

cvs diff -r1.6 -r1.7 src/sys/arch/vax/boot/boot/ctu.c (switch to unified diff)

--- src/sys/arch/vax/boot/boot/ctu.c 2009/03/14 21:04:16 1.6
+++ src/sys/arch/vax/boot/boot/ctu.c 2009/03/17 18:19:15 1.7
@@ -1,178 +1,178 @@ @@ -1,178 +1,178 @@
1/* $NetBSD: ctu.c,v 1.6 2009/03/14 21:04:16 dsl Exp $ */ 1/* $NetBSD: ctu.c,v 1.7 2009/03/17 18:19:15 dsl Exp $ */
2/* 2/*
3 * Copyright (c) 1996 Ludd, University of Lule}, Sweden. 3 * Copyright (c) 1996 Ludd, University of Lule}, Sweden.
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software 14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement: 15 * must display the following acknowledgement:
16 * This product includes software developed at Ludd, University of  16 * This product includes software developed at Ludd, University of
17 * Lule}, Sweden and its contributors. 17 * Lule}, Sweden and its contributors.
18 * 4. The name of the author may not be used to endorse or promote products 18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission 19 * derived from this software without specific prior written permission
20 * 20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33/* 33/*
34 * Standalone device driver for 11/750 Console TU58. 34 * Standalone device driver for 11/750 Console TU58.
35 * It can only handle reads, and doesn't calculate checksum. 35 * It can only handle reads, and doesn't calculate checksum.
36 */ 36 */
37 37
38#include <sys/param.h> 38#include <sys/param.h>
39 39
40#include <lib/libsa/stand.h> 40#include <lib/libsa/stand.h>
41 41
42#include <machine/mtpr.h> 42#include <machine/mtpr.h>
43#include <machine/rsp.h> 43#include <machine/rsp.h>
44 44
45#include "vaxstand.h" 45#include "vaxstand.h"
46 46
47static short ctu_cksum(unsigned short *, int); 47static short ctu_cksum(unsigned short *, int);
48 48
49enum tu_state { 49enum tu_state {
50 SC_INIT, 50 SC_INIT,
51 SC_READY, 51 SC_READY,
52 SC_SEND_CMD, 52 SC_SEND_CMD,
53 SC_GET_RESP, 53 SC_GET_RESP,
54}; 54};
55 55
56volatile struct tu_softc { 56volatile struct tu_softc {
57 enum tu_state sc_state; 57 enum tu_state sc_state;
58 char sc_rsp[15]; /* Should be struct rsb; but don't work */ 58 char sc_rsp[15]; /* Should be struct rsb; but don't work */
59 u_char *sc_xfptr; /* Current char to xfer */ 59 u_char *sc_xfptr; /* Current char to xfer */
60 int sc_nbytes; /* Number of bytes to xfer */ 60 int sc_nbytes; /* Number of bytes to xfer */
61 int sc_xbytes; /* Number of xfer'd bytes */ 61 int sc_xbytes; /* Number of xfer'd bytes */
62 int sc_bbytes; /* Number of xfer'd bytes this block */ 62 int sc_bbytes; /* Number of xfer'd bytes this block */
63} tu_sc; 63} tu_sc;
64 64
65void ctutintr(void); 65void ctutintr(void);
66void cturintr(void); 66void cturintr(void);
67 67
68int 68int
69ctuopen(struct open_file *f, adapt, int ctlr, int unit, int part) 69ctuopen(struct open_file *f, int adapt, int ctlr, int unit, int part)
70{ 70{
71 71
72 tu_sc.sc_state = SC_INIT; 72 tu_sc.sc_state = SC_INIT;
73 73
74 mtpr(RSP_TYP_INIT, PR_CSTD); 74 mtpr(RSP_TYP_INIT, PR_CSTD);
75 cturintr(); 75 cturintr();
76 tu_sc.sc_state = SC_READY; 76 tu_sc.sc_state = SC_READY;
77 return 0; 77 return 0;
78 78
79} 79}
80 80
81int 81int
82ctustrategy(void *f, int func, daddr_t dblk, size_t size, void *buf, size_t *rsize) 82ctustrategy(void *f, int func, daddr_t dblk, size_t size, void *buf, size_t *rsize)
83{ 83{
84 struct rsp *rsp = (struct rsp *)tu_sc.sc_rsp; 84 struct rsp *rsp = (struct rsp *)tu_sc.sc_rsp;
85 85
86 tu_sc.sc_xfptr = buf; 86 tu_sc.sc_xfptr = buf;
87 tu_sc.sc_nbytes = size; 87 tu_sc.sc_nbytes = size;
88 tu_sc.sc_xbytes = tu_sc.sc_bbytes = 0; 88 tu_sc.sc_xbytes = tu_sc.sc_bbytes = 0;
89 89
90 rsp->rsp_typ = RSP_TYP_COMMAND; 90 rsp->rsp_typ = RSP_TYP_COMMAND;
91 rsp->rsp_sz = 012; 91 rsp->rsp_sz = 012;
92 rsp->rsp_op = RSP_OP_READ; 92 rsp->rsp_op = RSP_OP_READ;
93 rsp->rsp_mod = 0; 93 rsp->rsp_mod = 0;
94 rsp->rsp_drv = 0; 94 rsp->rsp_drv = 0;
95 rsp->rsp_sw = rsp->rsp_xx1 = rsp->rsp_xx2 = 0; 95 rsp->rsp_sw = rsp->rsp_xx1 = rsp->rsp_xx2 = 0;
96 rsp->rsp_cnt = tu_sc.sc_nbytes; 96 rsp->rsp_cnt = tu_sc.sc_nbytes;
97 rsp->rsp_blk = dblk; 97 rsp->rsp_blk = dblk;
98 rsp->rsp_sum = ctu_cksum((u_short *)rsp, 6); 98 rsp->rsp_sum = ctu_cksum((u_short *)rsp, 6);
99 tu_sc.sc_state = SC_SEND_CMD; 99 tu_sc.sc_state = SC_SEND_CMD;
100 while (tu_sc.sc_state != SC_GET_RESP) 100 while (tu_sc.sc_state != SC_GET_RESP)
101 ctutintr(); 101 ctutintr();
102 while (tu_sc.sc_state != SC_READY) 102 while (tu_sc.sc_state != SC_READY)
103 cturintr(); 103 cturintr();
104 *rsize = size; 104 *rsize = size;
105 return 0; 105 return 0;
106} 106}
107 107
108void 108void
109cturintr() 109cturintr()
110{ 110{
111 int status; 111 int status;
112 112
113 while ((mfpr(PR_CSRS) & 0x80) == 0) 113 while ((mfpr(PR_CSRS) & 0x80) == 0)
114 ; 114 ;
115 115
116 status = mfpr(PR_CSRD); 116 status = mfpr(PR_CSRD);
117 117
118 switch (tu_sc.sc_state) { 118 switch (tu_sc.sc_state) {
119 119
120 case SC_INIT: 120 case SC_INIT:
121 break; 121 break;
122 122
123 case SC_GET_RESP: 123 case SC_GET_RESP:
124 if (tu_sc.sc_xbytes == tu_sc.sc_nbytes) { 124 if (tu_sc.sc_xbytes == tu_sc.sc_nbytes) {
125 tu_sc.sc_bbytes++; 125 tu_sc.sc_bbytes++;
126 if (tu_sc.sc_bbytes == 146) 126 if (tu_sc.sc_bbytes == 146)
127 tu_sc.sc_state = SC_READY; 127 tu_sc.sc_state = SC_READY;
128 break; 128 break;
129 } 129 }
130 tu_sc.sc_bbytes++; 130 tu_sc.sc_bbytes++;
131 if (tu_sc.sc_bbytes < 3) /* Data header */ 131 if (tu_sc.sc_bbytes < 3) /* Data header */
132 break; 132 break;
133 if (tu_sc.sc_bbytes == 132) { /* Finished */ 133 if (tu_sc.sc_bbytes == 132) { /* Finished */
134 tu_sc.sc_bbytes = 0; 134 tu_sc.sc_bbytes = 0;
135 break; 135 break;
136 } 136 }
137 if (tu_sc.sc_bbytes == 131) /* First checksum */ 137 if (tu_sc.sc_bbytes == 131) /* First checksum */
138 break; 138 break;
139 tu_sc.sc_xfptr[tu_sc.sc_xbytes++] = status; 139 tu_sc.sc_xfptr[tu_sc.sc_xbytes++] = status;
140 break; 140 break;
141 141
142 case SC_READY: 142 case SC_READY:
143 case SC_SEND_CMD: 143 case SC_SEND_CMD:
144 break; 144 break;
145 } 145 }
146 146
147} 147}
148 148
149void 149void
150ctutintr() 150ctutintr()
151{ 151{
152 int c; 152 int c;
153 153
154 while ((mfpr(PR_CSTS) & 0x80) == 0) 154 while ((mfpr(PR_CSTS) & 0x80) == 0)
155 ; 155 ;
156 156
157 c = tu_sc.sc_rsp[tu_sc.sc_xbytes++] & 0xff; 157 c = tu_sc.sc_rsp[tu_sc.sc_xbytes++] & 0xff;
158 mtpr(c, PR_CSTD); 158 mtpr(c, PR_CSTD);
159 if (tu_sc.sc_xbytes > 13) { 159 if (tu_sc.sc_xbytes > 13) {
160 tu_sc.sc_state = SC_GET_RESP; 160 tu_sc.sc_state = SC_GET_RESP;
161 tu_sc.sc_xbytes = 0; 161 tu_sc.sc_xbytes = 0;
162 } 162 }
163} 163}
164 164
165short 165short
166ctu_cksum(unsigned short *buf, int words) 166ctu_cksum(unsigned short *buf, int words)
167{ 167{
168 int i, cksum; 168 int i, cksum;
169 169
170 for (i = cksum = 0; i < words; i++) 170 for (i = cksum = 0; i < words; i++)
171 cksum += buf[i]; 171 cksum += buf[i];
172 172
173hej: if (cksum > 65535) { 173hej: if (cksum > 65535) {
174 cksum = (cksum & 65535) + (cksum >> 16); 174 cksum = (cksum & 65535) + (cksum >> 16);
175 goto hej; 175 goto hej;
176 } 176 }
177 return cksum; 177 return cksum;
178} 178}

cvs diff -r1.8 -r1.9 src/sys/arch/vax/boot/boot/mfm.c (switch to unified diff)

--- src/sys/arch/vax/boot/boot/mfm.c 2009/03/14 21:04:16 1.8
+++ src/sys/arch/vax/boot/boot/mfm.c 2009/03/17 18:19:15 1.9
@@ -1,655 +1,655 @@ @@ -1,655 +1,655 @@
1/* $NetBSD: mfm.c,v 1.8 2009/03/14 21:04:16 dsl Exp $ */ 1/* $NetBSD: mfm.c,v 1.9 2009/03/17 18:19:15 dsl Exp $ */
2/* 2/*
3 * Copyright (c) 1996 Ludd, University of Lule}, Sweden. 3 * Copyright (c) 1996 Ludd, University of Lule}, Sweden.
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * This code is derived from software contributed to Ludd by 6 * This code is derived from software contributed to Ludd by
7 * Bertram Barth. 7 * Bertram Barth.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software 17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement: 18 * must display the following acknowledgement:
19 * This product includes software developed at Ludd, University of 19 * This product includes software developed at Ludd, University of
20 * Lule}, Sweden and its contributors. 20 * Lule}, Sweden and its contributors.
21 * 4. The name of the author may not be used to endorse or promote products 21 * 4. The name of the author may not be used to endorse or promote products
22 * derived from this software without specific prior written permission 22 * derived from this software without specific prior written permission
23 * 23 *
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 27 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */ 34 */
35 35
36/* 36/*
37 * ToDo: 37 * ToDo:
38 * 38 *
39 * - insert appropriate delays for diskette-drive where needed 39 * - insert appropriate delays for diskette-drive where needed
40 * - allow more than one sector per diskette-read 40 * - allow more than one sector per diskette-read
41 * - check for and handle bad sectors 41 * - check for and handle bad sectors
42 * - ??? 42 * - ???
43 */ 43 */
44 44
45#include <sys/param.h> 45#include <sys/param.h>
46#include <sys/reboot.h> 46#include <sys/reboot.h>
47#include <sys/disklabel.h> 47#include <sys/disklabel.h>
48 48
49#include <lib/libsa/stand.h> 49#include <lib/libsa/stand.h>
50#include <lib/libsa/ufs.h> 50#include <lib/libsa/ufs.h>
51 51
52#include <lib/libkern/libkern.h> 52#include <lib/libkern/libkern.h>
53 53
54#include "../include/pte.h" 54#include "../include/pte.h"
55#include "../include/sid.h" 55#include "../include/sid.h"
56#include "../include/mtpr.h" 56#include "../include/mtpr.h"
57#include "../include/reg.h" 57#include "../include/reg.h"
58#include "../include/rpb.h" 58#include "../include/rpb.h"
59 59
60#include "ka410.h" 60#include "ka410.h"
61#include "../vsa/hdc9224.h" 61#include "../vsa/hdc9224.h"
62 62
63#include "data.h" 63#include "data.h"
64#include "vaxstand.h" 64#include "vaxstand.h"
65 65
66#define MAX_WAIT (1000*1000) /* # of loop-instructions in seconds */ 66#define MAX_WAIT (1000*1000) /* # of loop-instructions in seconds */
67 67
68struct mfm_softc { 68struct mfm_softc {
69 int part; 69 int part;
70 int unit; 70 int unit;
71}; 71};
72 72
73static struct disklabel mfmlabel; 73static struct disklabel mfmlabel;
74static struct mfm_softc mfm_softc; 74static struct mfm_softc mfm_softc;
75static char io_buf[DEV_BSIZE]; 75static char io_buf[DEV_BSIZE];
76 76
77/* 77/*
78 * These should probably be somewhere else, but ka410 is the only 78 * These should probably be somewhere else, but ka410 is the only
79 * one with mfm disks anyway... 79 * one with mfm disks anyway...
80 */ 80 */
81volatile unsigned char *ka410_intreq = (void*)0x2008000f; 81volatile unsigned char *ka410_intreq = (void*)0x2008000f;
82volatile unsigned char *ka410_intclr = (void*)0x2008000f; 82volatile unsigned char *ka410_intclr = (void*)0x2008000f;
83volatile unsigned char *ka410_intmsk = (void*)0x2008000c; 83volatile unsigned char *ka410_intmsk = (void*)0x2008000c;
84 84
85static volatile struct hdc9224_DKCreg *dkc = (void *) 0x200c0000; 85static volatile struct hdc9224_DKCreg *dkc = (void *) 0x200c0000;
86static volatile struct hdc9224_UDCreg sreg; /* input */ 86static volatile struct hdc9224_UDCreg sreg; /* input */
87static volatile struct hdc9224_UDCreg creg; /* output */ 87static volatile struct hdc9224_UDCreg creg; /* output */
88 88
89static void sreg_read(void); 89static void sreg_read(void);
90static void creg_write(void); 90static void creg_write(void);
91static int mfm_rxprepare(void); 91static int mfm_rxprepare(void);
92static int mfm_command(int cmd); 92static int mfm_command(int cmd);
93static int mfm_rxselect(int unit); 93static int mfm_rxselect(int unit);
94static int mfm_rdselect(int unit); 94static int mfm_rdselect(int unit);
95static int mfm_rxstrategy(void *f, int func, daddr_t dblk, size_t size, void *buf, size_t *rsize); 95static int mfm_rxstrategy(void *f, int func, daddr_t dblk, size_t size, void *buf, size_t *rsize);
96static int mfm_rdstrategy(void *f, int func, daddr_t dblk, size_t size, void *buf, size_t *rsize); 96static int mfm_rdstrategy(void *f, int func, daddr_t dblk, size_t size, void *buf, size_t *rsize);
97/* 97/*
98 * we have to wait 0.7 usec between two accesses to any of the 98 * we have to wait 0.7 usec between two accesses to any of the
99 * dkc-registers, on a VS2000 with 1 MIPS, this is roughly one 99 * dkc-registers, on a VS2000 with 1 MIPS, this is roughly one
100 * instruction. Thus the loop-overhead will be enough... 100 * instruction. Thus the loop-overhead will be enough...
101 */ 101 */
102static void 102static void
103sreg_read() 103sreg_read()
104{ 104{
105 int i; 105 int i;
106 char *p; 106 char *p;
107 107
108 dkc->dkc_cmd = 0x40; /* set internal counter to zero */ 108 dkc->dkc_cmd = 0x40; /* set internal counter to zero */
109 p = (void *) &sreg; 109 p = (void *) &sreg;
110 for (i = 0; i < 10; i++) 110 for (i = 0; i < 10; i++)
111 *p++ = dkc->dkc_reg; /* dkc_reg auto-increments */ 111 *p++ = dkc->dkc_reg; /* dkc_reg auto-increments */
112} 112}
113 113
114static void 114static void
115creg_write() 115creg_write()
116{ 116{
117 int i; 117 int i;
118 char *p; 118 char *p;
119 119
120 dkc->dkc_cmd = 0x40; /* set internal counter to zero */ 120 dkc->dkc_cmd = 0x40; /* set internal counter to zero */
121 p = (void *) &creg; 121 p = (void *) &creg;
122 for (i = 0; i < 10; i++) 122 for (i = 0; i < 10; i++)
123 dkc->dkc_reg = *p++; /* dkc_reg auto-increments */ 123 dkc->dkc_reg = *p++; /* dkc_reg auto-increments */
124} 124}
125 125
126/* 126/*
127 * floppies are handled in a quite strange way by this controller... 127 * floppies are handled in a quite strange way by this controller...
128 * 128 *
129 * before reading/writing a sector from/to floppy, we use the SEEK/READ_ID 129 * before reading/writing a sector from/to floppy, we use the SEEK/READ_ID
130 * command to place the head at the desired location. Then we wait some 130 * command to place the head at the desired location. Then we wait some
131 * time before issuing the real command in order to let the drive become 131 * time before issuing the real command in order to let the drive become
132 * ready... 132 * ready...
133 */ 133 */
134int 134int
135mfm_rxprepare() 135mfm_rxprepare()
136{ 136{
137 int error; 137 int error;
138 138
139 error = mfm_command(DKC_CMD_SEEKREADID | 0x04); /* step=1, verify=0 */ 139 error = mfm_command(DKC_CMD_SEEKREADID | 0x04); /* step=1, verify=0 */
140 if (error) { 140 if (error) {
141 printf("error while stepping to position %d/%d/%x. Retry...\n", 141 printf("error while stepping to position %d/%d/%x. Retry...\n",
142 creg.udc_dsect, creg.udc_dhead, creg.udc_dcyl); 142 creg.udc_dsect, creg.udc_dhead, creg.udc_dcyl);
143 error = mfm_command(DKC_CMD_SEEKREADID | 0x04); 143 error = mfm_command(DKC_CMD_SEEKREADID | 0x04);
144 } 144 }
145 return error; 145 return error;
146} 146}
147 147
148int 148int
149mfm_rxselect(int unit) 149mfm_rxselect(int unit)
150{ 150{
151 int error; 151 int error;
152 152
153 /* 153 /*
154 * bring "creg" in some known-to-work state and 154 * bring "creg" in some known-to-work state and
155 * select the drive with the DRIVE SELECT command. 155 * select the drive with the DRIVE SELECT command.
156 */ 156 */
157 creg.udc_dma7 = 0; 157 creg.udc_dma7 = 0;
158 creg.udc_dma15 = 0; 158 creg.udc_dma15 = 0;
159 creg.udc_dma23 = 0; 159 creg.udc_dma23 = 0;
160 creg.udc_dsect = 1; /* sectors are numbered 1..15 !!! */ 160 creg.udc_dsect = 1; /* sectors are numbered 1..15 !!! */
161 creg.udc_dhead = 0; 161 creg.udc_dhead = 0;
162 creg.udc_dcyl = 0; 162 creg.udc_dcyl = 0;
163 creg.udc_scnt = 0; 163 creg.udc_scnt = 0;
164 164
165 creg.udc_rtcnt = UDC_RC_RX33READ; 165 creg.udc_rtcnt = UDC_RC_RX33READ;
166 creg.udc_mode = UDC_MD_RX33; 166 creg.udc_mode = UDC_MD_RX33;
167 creg.udc_term = UDC_TC_FDD; 167 creg.udc_term = UDC_TC_FDD;
168 168
169 /* 169 /*
170 * this is ... 170 * this is ...
171 */ 171 */
172 error = mfm_command(DKC_CMD_DRSEL_RX33 | unit); 172 error = mfm_command(DKC_CMD_DRSEL_RX33 | unit);
173 173
174 if ((error != 0) || ((sreg.udc_dstat & UDC_DS_READY) == 0)) { 174 if ((error != 0) || ((sreg.udc_dstat & UDC_DS_READY) == 0)) {
175 printf("\nfloppy-drive not ready (new floppy inserted?)\n\n"); 175 printf("\nfloppy-drive not ready (new floppy inserted?)\n\n");
176 176
177 creg.udc_rtcnt &= ~UDC_RC_INVRDY; /* clear INVRDY-flag */ 177 creg.udc_rtcnt &= ~UDC_RC_INVRDY; /* clear INVRDY-flag */
178 error = mfm_command(DKC_CMD_DRSEL_RX33 | unit); 178 error = mfm_command(DKC_CMD_DRSEL_RX33 | unit);
179 if ((error != 0) || ((sreg.udc_dstat & UDC_DS_READY) == 0)) { 179 if ((error != 0) || ((sreg.udc_dstat & UDC_DS_READY) == 0)) {
180 printf("diskette not ready(1): %x/%x\n", 180 printf("diskette not ready(1): %x/%x\n",
181 error, sreg.udc_dstat); 181 error, sreg.udc_dstat);
182 printf("floppy-drive offline?\n"); 182 printf("floppy-drive offline?\n");
183 return (-1); 183 return (-1);
184 } 184 }
185 if (sreg.udc_dstat & UDC_DS_TRK00) 185 if (sreg.udc_dstat & UDC_DS_TRK00)
186 error = mfm_command(DKC_CMD_STEPIN_FDD); 186 error = mfm_command(DKC_CMD_STEPIN_FDD);
187 else 187 else
188 error = mfm_command(DKC_CMD_STEPOUT_FDD); 188 error = mfm_command(DKC_CMD_STEPOUT_FDD);
189 189
190 /* 190 /*
191 * now ready should be 0, cause INVRDY is not set 191 * now ready should be 0, cause INVRDY is not set
192 * (retrying a command makes this fail...) 192 * (retrying a command makes this fail...)
193 */ 193 */
194 if ((error != 0) || ((sreg.udc_dstat & UDC_DS_READY) == 1)) { 194 if ((error != 0) || ((sreg.udc_dstat & UDC_DS_READY) == 1)) {
195 printf("diskette not ready(2): %x/%x\n", 195 printf("diskette not ready(2): %x/%x\n",
196 error, sreg.udc_dstat); 196 error, sreg.udc_dstat);
197 } 197 }
198 creg.udc_rtcnt |= UDC_RC_INVRDY; 198 creg.udc_rtcnt |= UDC_RC_INVRDY;
199 error = mfm_command(DKC_CMD_DRSEL_RX33 | unit); 199 error = mfm_command(DKC_CMD_DRSEL_RX33 | unit);
200 200
201 if ((error != 0) || ((sreg.udc_dstat & UDC_DS_READY) == 0)) { 201 if ((error != 0) || ((sreg.udc_dstat & UDC_DS_READY) == 0)) {
202 printf("diskette not ready(3): %x/%x\n", 202 printf("diskette not ready(3): %x/%x\n",
203 error, sreg.udc_dstat); 203 error, sreg.udc_dstat);
204 printf("no floppy inserted or floppy-door open\n"); 204 printf("no floppy inserted or floppy-door open\n");
205 return (-1); 205 return (-1);
206 } 206 }
207 printf("floppy-drive reselected.\n"); 207 printf("floppy-drive reselected.\n");
208 } 208 }
209 return (error); 209 return (error);
210} 210}
211 211
212int 212int
213mfm_rdselect(int unit) 213mfm_rdselect(int unit)
214{ 214{
215 int error; 215 int error;
216 216
217 /* 217 /*
218 * bring "creg" in some known-to-work state and 218 * bring "creg" in some known-to-work state and
219 * select the drive with the DRIVE SELECT command. 219 * select the drive with the DRIVE SELECT command.
220 */ 220 */
221 creg.udc_dma7 = 0; 221 creg.udc_dma7 = 0;
222 creg.udc_dma15 = 0; 222 creg.udc_dma15 = 0;
223 creg.udc_dma23 = 0; 223 creg.udc_dma23 = 0;
224 creg.udc_dsect = 0; /* sectors are numbered 0..16 */ 224 creg.udc_dsect = 0; /* sectors are numbered 0..16 */
225 creg.udc_dhead = 0; 225 creg.udc_dhead = 0;
226 creg.udc_dcyl = 0; 226 creg.udc_dcyl = 0;
227 creg.udc_scnt = 0; 227 creg.udc_scnt = 0;
228 228
229 creg.udc_rtcnt = UDC_RC_HDD_READ; 229 creg.udc_rtcnt = UDC_RC_HDD_READ;
230 creg.udc_mode = UDC_MD_HDD; 230 creg.udc_mode = UDC_MD_HDD;
231 creg.udc_term = UDC_TC_HDD; 231 creg.udc_term = UDC_TC_HDD;
232 232
233 error = mfm_command(DKC_CMD_DRSEL_HDD | unit); 233 error = mfm_command(DKC_CMD_DRSEL_HDD | unit);
234 234
235 return (error); 235 return (error);
236} 236}
237 237
238static int mfm_retry = 0; 238static int mfm_retry = 0;
239 239
240int 240int
241mfm_command(int cmd) 241mfm_command(int cmd)
242{ 242{
243 int termcode, ready, i; 243 int termcode, ready, i;
244 244
245 creg_write(); /* write command-registers */ 245 creg_write(); /* write command-registers */
246 *ka410_intclr = INTR_DC; 246 *ka410_intclr = INTR_DC;
247 dkc->dkc_cmd = cmd; /* issue command */ 247 dkc->dkc_cmd = cmd; /* issue command */
248 for (i = 0; i < MAX_WAIT; i++) { 248 for (i = 0; i < MAX_WAIT; i++) {
249 if (*ka410_intreq & INTR_DC) /* wait for interrupt */ 249 if (*ka410_intreq & INTR_DC) /* wait for interrupt */
250 break; 250 break;
251 } 251 }
252 if ((*ka410_intreq & INTR_DC) == 0) 252 if ((*ka410_intreq & INTR_DC) == 0)
253 printf("timeout in mfm_command...\n"); 253 printf("timeout in mfm_command...\n");
254 254
255 sreg_read(); /* read status-registers */ 255 sreg_read(); /* read status-registers */
256 256
257 if (dkc->dkc_stat == (DKC_ST_DONE | DKC_TC_SUCCESS)) 257 if (dkc->dkc_stat == (DKC_ST_DONE | DKC_TC_SUCCESS))
258 return (0); 258 return (0);
259 259
260 if (sreg.udc_cstat & UDC_CS_ECCERR) { 260 if (sreg.udc_cstat & UDC_CS_ECCERR) {
261 printf( 261 printf(
262"\nspurious(?) ECC/CRC error at s%d/t%d/c%d [s%d/t%d/c%d(%d)]\n", 262"\nspurious(?) ECC/CRC error at s%d/t%d/c%d [s%d/t%d/c%d(%d)]\n",
263 sreg.udc_csect, sreg.udc_chead, sreg.udc_ccyl, 263 sreg.udc_csect, sreg.udc_chead, sreg.udc_ccyl,
264 creg.udc_dsect, creg.udc_dhead, creg.udc_dcyl,creg.udc_scnt); 264 creg.udc_dsect, creg.udc_dhead, creg.udc_dcyl,creg.udc_scnt);
265 if (sreg.udc_csect != creg.udc_dsect + creg.udc_scnt - 1) { 265 if (sreg.udc_csect != creg.udc_dsect + creg.udc_scnt - 1) {
266 printf("DMA: %x %x %x [%x]\n", 266 printf("DMA: %x %x %x [%x]\n",
267 sreg.udc_dma23, sreg.udc_dma15, 267 sreg.udc_dma23, sreg.udc_dma15,
268 sreg.udc_dma7, 512 * (sreg.udc_csect - 268 sreg.udc_dma7, 512 * (sreg.udc_csect -
269 creg.udc_dsect)); 269 creg.udc_dsect));
270 creg.udc_scnt = creg.udc_scnt - 270 creg.udc_scnt = creg.udc_scnt -
271 (sreg.udc_csect - creg.udc_dsect) - 1; 271 (sreg.udc_csect - creg.udc_dsect) - 1;
272 creg.udc_dsect = sreg.udc_csect + 1; 272 creg.udc_dsect = sreg.udc_csect + 1;
273 creg.udc_dma23 = sreg.udc_dma23; 273 creg.udc_dma23 = sreg.udc_dma23;
274 creg.udc_dma15 = sreg.udc_dma15 + 2; 274 creg.udc_dma15 = sreg.udc_dma15 + 2;
275 creg.udc_dma7 = 0; 275 creg.udc_dma7 = 0;
276 printf("Retry starting from s%d/t%d/c%d (%d). ", 276 printf("Retry starting from s%d/t%d/c%d (%d). ",
277 creg.udc_dsect, creg.udc_dhead, creg.udc_dcyl, 277 creg.udc_dsect, creg.udc_dhead, creg.udc_dcyl,
278 creg.udc_scnt); 278 creg.udc_scnt);
279 } 279 }
280 goto retry; 280 goto retry;
281 } 281 }
282 termcode = (dkc->dkc_stat & DKC_ST_TERMCOD) >> 3; 282 termcode = (dkc->dkc_stat & DKC_ST_TERMCOD) >> 3;
283 ready = sreg.udc_dstat & UDC_DS_READY; 283 ready = sreg.udc_dstat & UDC_DS_READY;
284 284
285 printf("cmd:0x%x: termcode=0x%x, status=0x%x, cstat=0x%x, dstat=0x%x\n", 285 printf("cmd:0x%x: termcode=0x%x, status=0x%x, cstat=0x%x, dstat=0x%x\n",
286 cmd, termcode, dkc->dkc_stat, sreg.udc_cstat, sreg.udc_dstat); 286 cmd, termcode, dkc->dkc_stat, sreg.udc_cstat, sreg.udc_dstat);
287 287
288 if (dkc->dkc_stat & DKC_ST_BADSECT) 288 if (dkc->dkc_stat & DKC_ST_BADSECT)
289 printf("bad sector found: s%d/t%d/c%d\n", creg.udc_dsect, 289 printf("bad sector found: s%d/t%d/c%d\n", creg.udc_dsect,
290 creg.udc_dhead, creg.udc_dcyl); 290 creg.udc_dhead, creg.udc_dcyl);
291retry: 291retry:
292 if ((mfm_retry == 0) && (sreg.udc_cstat & UDC_CS_RETREQ)) { 292 if ((mfm_retry == 0) && (sreg.udc_cstat & UDC_CS_RETREQ)) {
293 mfm_retry = 1; 293 mfm_retry = 1;
294 printf("Retrying... "); 294 printf("Retrying... ");
295 mfm_command(cmd); 295 mfm_command(cmd);
296 printf("Retry done.\n"); 296 printf("Retry done.\n");
297 mfm_retry = 0; 297 mfm_retry = 0;
298 } 298 }
299 return ((dkc->dkc_stat & DKC_ST_TERMCOD) >> 3); 299 return ((dkc->dkc_stat & DKC_ST_TERMCOD) >> 3);
300} 300}
301 301
302/* 302/*
303 * on-disk geometry block 303 * on-disk geometry block
304 */ 304 */
305#define _aP __attribute__ ((packed)) /* force byte-alignment */ 305#define _aP __attribute__ ((packed)) /* force byte-alignment */
306 306
307volatile struct mfm_xbn { 307volatile struct mfm_xbn {
308 char mbz[10];/* 10 bytes of zero */ 308 char mbz[10];/* 10 bytes of zero */
309 long xbn_count _aP; /* number of XBNs */ 309 long xbn_count _aP; /* number of XBNs */
310 long dbn_count _aP; /* number of DBNs */ 310 long dbn_count _aP; /* number of DBNs */
311 long lbn_count _aP; /* number of LBNs (Logical-Block-Numbers) */ 311 long lbn_count _aP; /* number of LBNs (Logical-Block-Numbers) */
312 long rbn_count _aP; /* number of RBNs (Replacement-Block-Numbers) */ 312 long rbn_count _aP; /* number of RBNs (Replacement-Block-Numbers) */
313 short nspt; /* number of sectors per track */ 313 short nspt; /* number of sectors per track */
314 short ntracks;/* number of tracks */ 314 short ntracks;/* number of tracks */
315 short ncylinders; /* number of cylinders */ 315 short ncylinders; /* number of cylinders */
316 short precomp;/* first cylinder for write precompensation */ 316 short precomp;/* first cylinder for write precompensation */
317 short reduced;/* first cylinder for reduced write current */ 317 short reduced;/* first cylinder for reduced write current */
318 short seek_rate; /* seek rate or zero for buffered 318 short seek_rate; /* seek rate or zero for buffered
319 * seeks */ 319 * seeks */
320 short crc_eec;/* 0 if CRC is being used or 1 if ECC is 320 short crc_eec;/* 0 if CRC is being used or 1 if ECC is
321 * being used */ 321 * being used */
322 short rct; /* "replacement control table" (RCT) */ 322 short rct; /* "replacement control table" (RCT) */
323 short rct_ncopies; /* number of copies of the RCT */ 323 short rct_ncopies; /* number of copies of the RCT */
324 long media_id _aP; /* media identifier */ 324 long media_id _aP; /* media identifier */
325 short interleave; /* sector-to-sector interleave */ 325 short interleave; /* sector-to-sector interleave */
326 short headskew; /* head-to-head skew */ 326 short headskew; /* head-to-head skew */
327 short cylskew;/* cylinder-to-cylinder skew */ 327 short cylskew;/* cylinder-to-cylinder skew */
328 short gap0_size; /* size of GAP 0 in the MFM format */ 328 short gap0_size; /* size of GAP 0 in the MFM format */
329 short gap1_size; /* size of GAP 1 in the MFM format */ 329 short gap1_size; /* size of GAP 1 in the MFM format */
330 short gap2_size; /* size of GAP 2 in the MFM format */ 330 short gap2_size; /* size of GAP 2 in the MFM format */
331 short gap3_size; /* size of GAP 3 in the MFM format */ 331 short gap3_size; /* size of GAP 3 in the MFM format */
332 short sync_value; /* sync value used to start a track 332 short sync_value; /* sync value used to start a track
333 * when formatting */ 333 * when formatting */
334 char reserved[32]; /* reserved for use by the RQDX1/2/3 334 char reserved[32]; /* reserved for use by the RQDX1/2/3
335 * formatter */ 335 * formatter */
336 short serial_number; /* serial number */ 336 short serial_number; /* serial number */
337 char fill[412]; /* Filler bytes to the end of the 337 char fill[412]; /* Filler bytes to the end of the
338 * block */ 338 * block */
339 short checksum; /* checksum over the XBN */ 339 short checksum; /* checksum over the XBN */
340} mfm_xbn; 340} mfm_xbn;
341 341
342#ifdef verbose 342#ifdef verbose
343display_xbn(struct mfm_xbn *p) 343display_xbn(struct mfm_xbn *p)
344{ 344{
345 printf("**DiskData** XBNs: %d, DBNs: %d, LBNs: %d, RBNs: %d\n", 345 printf("**DiskData** XBNs: %d, DBNs: %d, LBNs: %d, RBNs: %d\n",
346 p->xbn_count, p->dbn_count, p->lbn_count, p->rbn_count); 346 p->xbn_count, p->dbn_count, p->lbn_count, p->rbn_count);
347 printf("sect/track: %d, tracks: %d, cyl: %d, precomp/reduced: %d/%d\n", 347 printf("sect/track: %d, tracks: %d, cyl: %d, precomp/reduced: %d/%d\n",
348 p->nspt, p->ntracks, p->ncylinders, p->precomp, p->reduced); 348 p->nspt, p->ntracks, p->ncylinders, p->precomp, p->reduced);
349 printf("seek-rate: %d, crc/eec: %s, RCT: %d, RCT-copies: %d\n", 349 printf("seek-rate: %d, crc/eec: %s, RCT: %d, RCT-copies: %d\n",
350 p->seek_rate, p->crc_eec ? "EEC" : "CRC", p->rct, p->rct_ncopies); 350 p->seek_rate, p->crc_eec ? "EEC" : "CRC", p->rct, p->rct_ncopies);
351 printf("media-ID: 0x%x, interleave: %d, headskew: %d, cylskew: %d\n", 351 printf("media-ID: 0x%x, interleave: %d, headskew: %d, cylskew: %d\n",
352 &p->media_id, p->interleave, p->headskew, p->cylskew); 352 &p->media_id, p->interleave, p->headskew, p->cylskew);
353 printf("gap0: %d, gap1: %d, gap2: %d, gap3: %d, sync-value: %d\n", 353 printf("gap0: %d, gap1: %d, gap2: %d, gap3: %d, sync-value: %d\n",
354 p->gap0_size, p->gap1_size, p->gap2_size, p->gap3_size, 354 p->gap0_size, p->gap1_size, p->gap2_size, p->gap3_size,
355 p->sync_value); 355 p->sync_value);
356 printf("serial: %d, checksum: %d, size: %d, reserved: %32c\n", 356 printf("serial: %d, checksum: %d, size: %d, reserved: %32c\n",
357 p->serial_number, p->checksum, sizeof(*p), p->reserved); 357 p->serial_number, p->checksum, sizeof(*p), p->reserved);
358} 358}
359#endif 359#endif
360 360
361int 361int
362mfmopen(struct open_file *f, adapt, int ctlr, int unit, int part) 362mfmopen(struct open_file *f, int adapt, int ctlr, int unit, int part)
363{ 363{
364 char *msg; 364 char *msg;
365 struct disklabel *lp = &mfmlabel; 365 struct disklabel *lp = &mfmlabel;
366 struct mfm_softc *msc = &mfm_softc; 366 struct mfm_softc *msc = &mfm_softc;
367 int err; 367 int err;
368 size_t i; 368 size_t i;
369 369
370 bzero(lp, sizeof(struct disklabel)); 370 bzero(lp, sizeof(struct disklabel));
371 msc->unit = unit; 371 msc->unit = unit;
372 msc->part = part; 372 msc->part = part;
373 373
374 err = mfmstrategy(msc, F_READ, LABELSECTOR, DEV_BSIZE, io_buf, &i); 374 err = mfmstrategy(msc, F_READ, LABELSECTOR, DEV_BSIZE, io_buf, &i);
375 if (err) { 375 if (err) {
376 printf("reading disklabel: %s\n", strerror(err)); 376 printf("reading disklabel: %s\n", strerror(err));
377 return 0; 377 return 0;
378 } 378 }
379 msg = getdisklabel(io_buf + LABELOFFSET, lp); 379 msg = getdisklabel(io_buf + LABELOFFSET, lp);
380 if (msg) 380 if (msg)
381 printf("getdisklabel: %s\n", msg); 381 printf("getdisklabel: %s\n", msg);
382 382
383 f->f_devdata = (void *) msc; 383 f->f_devdata = (void *) msc;
384 384
385 { 385 {
386#ifdef verbose 386#ifdef verbose
387 int k; 387 int k;
388 unsigned char *ucp; 388 unsigned char *ucp;
389 struct mfm_xbn *xp; 389 struct mfm_xbn *xp;
390#endif 390#endif
391 391
392 /* mfmstrategy(msc, F_READ, -16, 8192, io_buf, &i); */ 392 /* mfmstrategy(msc, F_READ, -16, 8192, io_buf, &i); */
393 mfmstrategy(msc, F_READ, -16, 512, io_buf, &i); 393 mfmstrategy(msc, F_READ, -16, 512, io_buf, &i);
394#ifdef verbose 394#ifdef verbose
395 printf("dumping raw disk-block #0:\n"); 395 printf("dumping raw disk-block #0:\n");
396 ucp = io_buf; 396 ucp = io_buf;
397 for (k = 0; k < 128; k++) { 397 for (k = 0; k < 128; k++) {
398 if (ucp[k] < 0x10) 398 if (ucp[k] < 0x10)
399 printf("0"); 399 printf("0");
400 printf("%x ", ucp[k]); 400 printf("%x ", ucp[k]);
401 if (k % 8 == 7) 401 if (k % 8 == 7)
402 printf(" "); 402 printf(" ");
403 if (k % 16 == 15) 403 if (k % 16 == 15)
404 printf("\n"); 404 printf("\n");
405 } 405 }
406 printf("\n"); 406 printf("\n");
407 407
408 xp = (void *) io_buf; 408 xp = (void *) io_buf;
409 display_xbn(xp); 409 display_xbn(xp);
410 printf("\n"); 410 printf("\n");
411#endif 411#endif
412 } 412 }
413 413
414 if (unit == 2) { /* floppy! */ 414 if (unit == 2) { /* floppy! */
415 if (lp->d_ntracks != 2) { 415 if (lp->d_ntracks != 2) {
416#ifdef verbose 416#ifdef verbose
417 printf("changing number of tracks from %d to %d.\n", 417 printf("changing number of tracks from %d to %d.\n",
418 lp->d_ntracks, 2); 418 lp->d_ntracks, 2);
419#endif 419#endif
420 lp->d_ntracks = 2; 420 lp->d_ntracks = 2;
421 } 421 }
422 } else { /* hard-disk */ 422 } else { /* hard-disk */
423 unsigned short *usp = (void *) io_buf; 423 unsigned short *usp = (void *) io_buf;
424#ifdef verbose 424#ifdef verbose
425 printf("label says: s/t/c = %d/%d/%d\n", 425 printf("label says: s/t/c = %d/%d/%d\n",
426 lp->d_nsectors, lp->d_ntracks, lp->d_ncylinders); 426 lp->d_nsectors, lp->d_ntracks, lp->d_ncylinders);
427#endif 427#endif
428 if (lp->d_nsectors != usp[13]) { 428 if (lp->d_nsectors != usp[13]) {
429#ifdef verbose 429#ifdef verbose
430 printf("changing number of sectors from %d to %d.\n", 430 printf("changing number of sectors from %d to %d.\n",
431 lp->d_nsectors, usp[13]); 431 lp->d_nsectors, usp[13]);
432#endif 432#endif
433 lp->d_nsectors = usp[13]; 433 lp->d_nsectors = usp[13];
434 } 434 }
435 if (lp->d_ntracks != usp[14]) { 435 if (lp->d_ntracks != usp[14]) {
436#ifdef verbose 436#ifdef verbose
437 printf("changing number of heads/tracks from %d to %d.\n", 437 printf("changing number of heads/tracks from %d to %d.\n",
438 lp->d_ntracks, usp[14]); 438 lp->d_ntracks, usp[14]);
439#endif 439#endif
440 lp->d_ntracks = usp[14]; 440 lp->d_ntracks = usp[14];
441 } 441 }
442 if (lp->d_ncylinders != usp[15]) { 442 if (lp->d_ncylinders != usp[15]) {
443#ifdef verbose 443#ifdef verbose
444 printf("changing number of cylinders from %d to %d.\n", 444 printf("changing number of cylinders from %d to %d.\n",
445 lp->d_ncylinders, usp[15]); 445 lp->d_ncylinders, usp[15]);
446#endif 446#endif
447 lp->d_ncylinders = usp[15]; 447 lp->d_ncylinders = usp[15];
448 } 448 }
449 lp->d_secpercyl = lp->d_nsectors * lp->d_ntracks; 449 lp->d_secpercyl = lp->d_nsectors * lp->d_ntracks;
450 } 450 }
451 451
452 return (0); 452 return (0);
453} 453}
454 454
455int 455int
456mfm_rxstrategy(void *f, int func, daddr_t dblk, size_t size, void *buf, size_t *rsize) { 456mfm_rxstrategy(void *f, int func, daddr_t dblk, size_t size, void *buf, size_t *rsize) {
457 struct mfm_softc *msc = f; 457 struct mfm_softc *msc = f;
458 struct disklabel *lp; 458 struct disklabel *lp;
459 int block, sect, head, cyl, scount, res; 459 int block, sect, head, cyl, scount, res;
460 char *cbuf; 460 char *cbuf;
461 461
462 cbuf = (char*)buf; 462 cbuf = (char*)buf;
463 463
464 lp = &mfmlabel; 464 lp = &mfmlabel;
465 block = (dblk < 0 ? 0 : dblk + lp->d_partitions[msc->part].p_offset); 465 block = (dblk < 0 ? 0 : dblk + lp->d_partitions[msc->part].p_offset);
466 466
467 mfm_rxselect(msc->unit); 467 mfm_rxselect(msc->unit);
468 468
469 /* 469 /*
470 * if label is empty, assume RX33 470 * if label is empty, assume RX33
471 */ 471 */
472 if (lp->d_nsectors == 0) 472 if (lp->d_nsectors == 0)
473 lp->d_nsectors = 15; 473 lp->d_nsectors = 15;
474 if (lp->d_ntracks == 0) 474 if (lp->d_ntracks == 0)
475 lp->d_ntracks = 2; 475 lp->d_ntracks = 2;
476 if (lp->d_secpercyl == 0) 476 if (lp->d_secpercyl == 0)
477 lp->d_secpercyl = 30; 477 lp->d_secpercyl = 30;
478 478
479 bzero((void *) 0x200D0000, size); 479 bzero((void *) 0x200D0000, size);
480 scount = size / 512; 480 scount = size / 512;
481 481
482 while (scount) { 482 while (scount) {
483 /* 483 /*
484 * prepare drive/operation parameter 484 * prepare drive/operation parameter
485 */ 485 */
486 cyl = block / lp->d_secpercyl; 486 cyl = block / lp->d_secpercyl;
487 sect = block % lp->d_secpercyl; 487 sect = block % lp->d_secpercyl;
488 head = sect / lp->d_nsectors; 488 head = sect / lp->d_nsectors;
489 sect = sect % lp->d_nsectors; 489 sect = sect % lp->d_nsectors;
490 490
491 /* 491 /*
492 * *rsize = 512; one sector after the other 492 * *rsize = 512; one sector after the other
493 * ... 493 * ...
494 */ 494 */
495 *rsize = 512 * min(scount, lp->d_nsectors - sect); 495 *rsize = 512 * min(scount, lp->d_nsectors - sect);
496 496
497 /* 497 /*
498 * now initialize the register values ... 498 * now initialize the register values ...
499 */ 499 */
500 creg.udc_dma7 = 0; 500 creg.udc_dma7 = 0;
501 creg.udc_dma15 = 0; 501 creg.udc_dma15 = 0;
502 creg.udc_dma23 = 0; 502 creg.udc_dma23 = 0;
503 503
504 creg.udc_dsect = sect + 1; /* sectors are numbered 1..15 504 creg.udc_dsect = sect + 1; /* sectors are numbered 1..15
505 * !!! */ 505 * !!! */
506 head |= (cyl >> 4) & 0x70; 506 head |= (cyl >> 4) & 0x70;
507 creg.udc_dhead = head; 507 creg.udc_dhead = head;
508 creg.udc_dcyl = cyl; 508 creg.udc_dcyl = cyl;
509 509
510 creg.udc_scnt = *rsize / 512; 510 creg.udc_scnt = *rsize / 512;
511 511
512 if (func == F_WRITE) { 512 if (func == F_WRITE) {
513 creg.udc_rtcnt = UDC_RC_RX33WRT; 513 creg.udc_rtcnt = UDC_RC_RX33WRT;
514 creg.udc_mode = UDC_MD_RX33; 514 creg.udc_mode = UDC_MD_RX33;
515 creg.udc_term = UDC_TC_FDD; 515 creg.udc_term = UDC_TC_FDD;
516 516
517 mfm_rxprepare(); 517 mfm_rxprepare();
518 /* copy from buf */ 518 /* copy from buf */
519 bcopy(cbuf, (void *) 0x200D0000, *rsize); 519 bcopy(cbuf, (void *) 0x200D0000, *rsize);
520 res = mfm_command(DKC_CMD_WRITE_RX33); 520 res = mfm_command(DKC_CMD_WRITE_RX33);
521 } else { 521 } else {
522 creg.udc_rtcnt = UDC_RC_RX33READ; 522 creg.udc_rtcnt = UDC_RC_RX33READ;
523 creg.udc_mode = UDC_MD_RX33; 523 creg.udc_mode = UDC_MD_RX33;
524 creg.udc_term = UDC_TC_FDD; 524 creg.udc_term = UDC_TC_FDD;
525 525
526 mfm_rxprepare(); 526 mfm_rxprepare();
527 /* clear disk buffer */ 527 /* clear disk buffer */
528 bzero((void *) 0x200D0000, *rsize); 528 bzero((void *) 0x200D0000, *rsize);
529 res = mfm_command(DKC_CMD_READ_RX33); 529 res = mfm_command(DKC_CMD_READ_RX33);
530 /* copy to buf */ 530 /* copy to buf */
531 bcopy((void *) 0x200D0000, cbuf, *rsize); 531 bcopy((void *) 0x200D0000, cbuf, *rsize);
532 } 532 }
533 533
534 scount -= *rsize / 512; 534 scount -= *rsize / 512;
535 block += *rsize / 512; 535 block += *rsize / 512;
536 cbuf += *rsize; 536 cbuf += *rsize;
537 } 537 }
538 538
539 *rsize = size; 539 *rsize = size;
540 return 0; 540 return 0;
541} 541}
542 542
543int 543int
544mfm_rdstrategy(void *f, int func, daddr_t dblk, size_t size, void *buf, size_t *rsize) { 544mfm_rdstrategy(void *f, int func, daddr_t dblk, size_t size, void *buf, size_t *rsize) {
545 struct mfm_softc *msc = f; 545 struct mfm_softc *msc = f;
546 struct disklabel *lp; 546 struct disklabel *lp;
547 int block, sect, head, cyl, scount, cmd, res; 547 int block, sect, head, cyl, scount, cmd, res;
548 char *cbuf; 548 char *cbuf;
549 549
550 cbuf = (char *)buf; 550 cbuf = (char *)buf;
551 551
552 lp = &mfmlabel; 552 lp = &mfmlabel;
553 block = (dblk < 0 ? 0 : dblk + lp->d_partitions[msc->part].p_offset); 553 block = (dblk < 0 ? 0 : dblk + lp->d_partitions[msc->part].p_offset);
554 554
555 /* 555 /*
556 * if label is empty, assume RD32 (XXX this must go away!!!) 556 * if label is empty, assume RD32 (XXX this must go away!!!)
557 */ 557 */
558 if (lp->d_nsectors == 0) 558 if (lp->d_nsectors == 0)
559 lp->d_nsectors = 17; 559 lp->d_nsectors = 17;
560 if (lp->d_ntracks == 0) 560 if (lp->d_ntracks == 0)
561 lp->d_ntracks = 6; 561 lp->d_ntracks = 6;
562 if (lp->d_secpercyl == 0) 562 if (lp->d_secpercyl == 0)
563 lp->d_secpercyl = 102; 563 lp->d_secpercyl = 102;
564 564
565 mfm_rdselect(msc->unit); 565 mfm_rdselect(msc->unit);
566 566
567 bzero((void *) 0x200D0000, size); 567 bzero((void *) 0x200D0000, size);
568 scount = size / 512; 568 scount = size / 512;
569 569
570 while (scount) { 570 while (scount) {
571 /* 571 /*
572 * prepare drive/operation parameter 572 * prepare drive/operation parameter
573 */ 573 */
574 cyl = block / lp->d_secpercyl; 574 cyl = block / lp->d_secpercyl;
575 sect = block % lp->d_secpercyl; 575 sect = block % lp->d_secpercyl;
576 head = sect / lp->d_nsectors; 576 head = sect / lp->d_nsectors;
577 sect = sect % lp->d_nsectors; 577 sect = sect % lp->d_nsectors;
578 578
579 if (dblk < 0) { 579 if (dblk < 0) {
580#ifdef verbose 580#ifdef verbose
581 printf("using raw diskblock-data!\n"); 581 printf("using raw diskblock-data!\n");
582 printf("block %d, dblk %d ==> cyl %d, head %d, sect %d\n", 582 printf("block %d, dblk %d ==> cyl %d, head %d, sect %d\n",
583 block, dblk, cyl, sect, head); 583 block, dblk, cyl, sect, head);
584#endif 584#endif
585 } else 585 } else
586 cyl += 1; /* first cylinder is reserved for 586 cyl += 1; /* first cylinder is reserved for
587 * controller! */ 587 * controller! */
588 588
589 *rsize = 512 * min(scount, lp->d_nsectors - sect); 589 *rsize = 512 * min(scount, lp->d_nsectors - sect);
590 /* 590 /*
591 * now re-initialize the register values ... 591 * now re-initialize the register values ...
592 */ 592 */
593 creg.udc_dma7 = 0; 593 creg.udc_dma7 = 0;
594 creg.udc_dma15 = 0; 594 creg.udc_dma15 = 0;
595 creg.udc_dma23 = 0; 595 creg.udc_dma23 = 0;
596 596
597 creg.udc_dsect = sect; 597 creg.udc_dsect = sect;
598 head |= (cyl >> 4) & 0x70; 598 head |= (cyl >> 4) & 0x70;
599 creg.udc_dhead = head; 599 creg.udc_dhead = head;
600 creg.udc_dcyl = cyl; 600 creg.udc_dcyl = cyl;
601 601
602 creg.udc_scnt = *rsize / 512; 602 creg.udc_scnt = *rsize / 512;
603 603
604 if (func == F_WRITE) { 604 if (func == F_WRITE) {
605 creg.udc_rtcnt = UDC_RC_HDD_WRT; 605 creg.udc_rtcnt = UDC_RC_HDD_WRT;
606 creg.udc_mode = UDC_MD_HDD; 606 creg.udc_mode = UDC_MD_HDD;
607 creg.udc_term = UDC_TC_HDD; 607 creg.udc_term = UDC_TC_HDD;
608 cmd = DKC_CMD_WRITE_HDD; 608 cmd = DKC_CMD_WRITE_HDD;
609 609
610 bcopy(cbuf, (void *) 0x200D0000, *rsize); 610 bcopy(cbuf, (void *) 0x200D0000, *rsize);
611 res = mfm_command(cmd); 611 res = mfm_command(cmd);
612 } else { 612 } else {
613 creg.udc_rtcnt = UDC_RC_HDD_READ; 613 creg.udc_rtcnt = UDC_RC_HDD_READ;
614 creg.udc_mode = UDC_MD_HDD; 614 creg.udc_mode = UDC_MD_HDD;
615 creg.udc_term = UDC_TC_HDD; 615 creg.udc_term = UDC_TC_HDD;
616 cmd = DKC_CMD_READ_HDD; 616 cmd = DKC_CMD_READ_HDD;
617 617
618 bzero((void *) 0x200D0000, *rsize); 618 bzero((void *) 0x200D0000, *rsize);
619 res = mfm_command(cmd); 619 res = mfm_command(cmd);
620 bcopy((void *) 0x200D0000, cbuf, *rsize); 620 bcopy((void *) 0x200D0000, cbuf, *rsize);
621 } 621 }
622 622
623 scount -= *rsize / 512; 623 scount -= *rsize / 512;
624 block += *rsize / 512; 624 block += *rsize / 512;
625 cbuf += *rsize; 625 cbuf += *rsize;
626 } 626 }
627 627
628 /* 628 /*
629 * unselect the drive ... 629 * unselect the drive ...
630 */ 630 */
631 mfm_command(DKC_CMD_DRDESELECT); 631 mfm_command(DKC_CMD_DRDESELECT);
632 632
633 *rsize = size; 633 *rsize = size;
634 return 0; 634 return 0;
635} 635}
636 636
637int 637int
638mfmstrategy(void *f, int func, daddr_t dblk, size_t size, void *buf, size_t *rsize) 638mfmstrategy(void *f, int func, daddr_t dblk, size_t size, void *buf, size_t *rsize)
639{ 639{
640 struct mfm_softc *msc = f; 640 struct mfm_softc *msc = f;
641 int res = -1; 641 int res = -1;
642 642
643 switch (msc->unit) { 643 switch (msc->unit) {
644 case 0: 644 case 0:
645 case 1: 645 case 1:
646 res = mfm_rdstrategy(f, func, dblk, size, buf, rsize); 646 res = mfm_rdstrategy(f, func, dblk, size, buf, rsize);
647 break; 647 break;
648 case 2: 648 case 2:
649 res = mfm_rxstrategy(f, func, dblk, size, buf, rsize); 649 res = mfm_rxstrategy(f, func, dblk, size, buf, rsize);
650 break; 650 break;
651 default: 651 default:
652 printf("invalid unit %d in mfmstrategy()\n", msc->unit); 652 printf("invalid unit %d in mfmstrategy()\n", msc->unit);
653 } 653 }
654 return (res); 654 return (res);
655} 655}

cvs diff -r1.7 -r1.8 src/sys/arch/vax/boot/boot/tmscp.c (switch to unified diff)

--- src/sys/arch/vax/boot/boot/tmscp.c 2009/03/14 21:04:16 1.7
+++ src/sys/arch/vax/boot/boot/tmscp.c 2009/03/17 18:19:15 1.8
@@ -1,196 +1,196 @@ @@ -1,196 +1,196 @@
1/* $NetBSD: tmscp.c,v 1.7 2009/03/14 21:04:16 dsl Exp $ */ 1/* $NetBSD: tmscp.c,v 1.8 2009/03/17 18:19:15 dsl Exp $ */
2/* 2/*
3 * Copyright (c) 1995 Ludd, University of Lule}, Sweden. 3 * Copyright (c) 1995 Ludd, University of Lule}, Sweden.
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software 14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement: 15 * must display the following acknowledgement:
16 * This product includes software developed at Ludd, University of Lule}. 16 * This product includes software developed at Ludd, University of Lule}.
17 * 4. The name of the author may not be used to endorse or promote products 17 * 4. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission 18 * derived from this software without specific prior written permission
19 * 19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32 /* All bugs are subject to removal without further notice */ 32 /* All bugs are subject to removal without further notice */
33 33
34#define NRSP 0 /* Kludge */ 34#define NRSP 0 /* Kludge */
35#define NCMD 0 /* Kludge */ 35#define NCMD 0 /* Kludge */
36 36
37#include <sys/param.h> 37#include <sys/param.h>
38#include <sys/disklabel.h> 38#include <sys/disklabel.h>
39 39
40#include <lib/libsa/stand.h> 40#include <lib/libsa/stand.h>
41 41
42#include "../include/pte.h" 42#include "../include/pte.h"
43#include <dev/mscp/mscp.h> 43#include <dev/mscp/mscp.h>
44#include <dev/mscp/mscpreg.h> 44#include <dev/mscp/mscpreg.h>
45 45
46#include "vaxstand.h" 46#include "vaxstand.h"
47 47
48static command(int,int); 48static command(int,int);
49 49
50/* 50/*
51 * These routines for TMSCP tape standalone boot is very simple, 51 * These routines for TMSCP tape standalone boot is very simple,
52 * assuming a lots of thing like that we only working at one tape at 52 * assuming a lots of thing like that we only working at one tape at
53 * a time, no separate routines for uba driver etc.. 53 * a time, no separate routines for uba driver etc..
54 * This code is directly copied from ra disk driver. 54 * This code is directly copied from ra disk driver.
55 */ 55 */
56 56
57struct ra_softc { 57struct ra_softc {
58 int udaddr; 58 int udaddr;
59 int ubaddr; 59 int ubaddr;
60 int unit; 60 int unit;
61}; 61};
62 62
63static volatile struct uda { 63static volatile struct uda {
64 struct mscp_1ca uda_ca; /* communications area */ 64 struct mscp_1ca uda_ca; /* communications area */
65 struct mscp uda_rsp; /* response packets */ 65 struct mscp uda_rsp; /* response packets */
66 struct mscp uda_cmd; /* command packets */ 66 struct mscp uda_cmd; /* command packets */
67} uda; 67} uda;
68 68
69struct udadevice { 69struct udadevice {
70 short udaip; 70 short udaip;
71 short udasa; 71 short udasa;
72}; 72};
73 73
74static volatile struct uda *ubauda; 74static volatile struct uda *ubauda;
75static volatile struct udadevice *udacsr; 75static volatile struct udadevice *udacsr;
76static struct ra_softc ra_softc; 76static struct ra_softc ra_softc;
77static int curblock; 77static int curblock;
78 78
79 79
80tmscpopen(struct open_file *f, adapt, int ctlr, int unit, int part) 80tmscpopen(struct open_file *f, int adapt, int ctlr, int unit, int part)
81{ 81{
82 char *msg; 82 char *msg;
83 extern u_int tmsaddr; 83 extern u_int tmsaddr;
84 volatile struct ra_softc *ra=&ra_softc; 84 volatile struct ra_softc *ra=&ra_softc;
85 volatile u_int *nisse; 85 volatile u_int *nisse;
86 unsigned short johan; 86 unsigned short johan;
87 int i,err; 87 int i,err;
88 88
89 curblock = 0; 89 curblock = 0;
90 if(adapt>nuba) return(EADAPT); 90 if(adapt>nuba) return(EADAPT);
91 if(ctlr>nuda) return(ECTLR); 91 if(ctlr>nuda) return(ECTLR);
92 ra->udaddr=uioaddr[adapt]+tmsaddr; 92 ra->udaddr=uioaddr[adapt]+tmsaddr;
93 ra->ubaddr=(int)ubaaddr[adapt]; 93 ra->ubaddr=(int)ubaaddr[adapt];
94 ra->unit=unit; 94 ra->unit=unit;
95 udacsr=(void*)ra->udaddr; 95 udacsr=(void*)ra->udaddr;
96 nisse=((u_int *)ubaaddr[adapt]) + 512; 96 nisse=((u_int *)ubaaddr[adapt]) + 512;
97 nisse[494]=PG_V|(((u_int)&uda)>>9); 97 nisse[494]=PG_V|(((u_int)&uda)>>9);
98 nisse[495]=nisse[494]+1; 98 nisse[495]=nisse[494]+1;
99 ubauda=(void*)0x3dc00+(((u_int)(&uda))&0x1ff); 99 ubauda=(void*)0x3dc00+(((u_int)(&uda))&0x1ff);
100 100
101 /* 101 /*
102 * Init of this tmscp ctlr. 102 * Init of this tmscp ctlr.
103 */ 103 */
104 udacsr->udaip=0; /* Start init */ 104 udacsr->udaip=0; /* Start init */
105 while((udacsr->udasa&MP_STEP1) == 0); 105 while((udacsr->udasa&MP_STEP1) == 0);
106 udacsr->udasa=0x8000; 106 udacsr->udasa=0x8000;
107 while((udacsr->udasa&MP_STEP2) == 0); 107 while((udacsr->udasa&MP_STEP2) == 0);
108 johan=(((u_int)ubauda)&0xffff)+8; 108 johan=(((u_int)ubauda)&0xffff)+8;
109 udacsr->udasa=johan; 109 udacsr->udasa=johan;
110 while((udacsr->udasa&MP_STEP3) == 0); 110 while((udacsr->udasa&MP_STEP3) == 0);
111 udacsr->udasa=3; 111 udacsr->udasa=3;
112 while((udacsr->udasa&MP_STEP4) == 0); 112 while((udacsr->udasa&MP_STEP4) == 0);
113 udacsr->udasa=0x0001; 113 udacsr->udasa=0x0001;
114 114
115 uda.uda_ca.ca_rspdsc=(int)&ubauda->uda_rsp.mscp_cmdref; 115 uda.uda_ca.ca_rspdsc=(int)&ubauda->uda_rsp.mscp_cmdref;
116 uda.uda_ca.ca_cmddsc=(int)&ubauda->uda_cmd.mscp_cmdref; 116 uda.uda_ca.ca_cmddsc=(int)&ubauda->uda_cmd.mscp_cmdref;
117 uda.uda_cmd.mscp_un.un_seq.seq_addr = (long *)&uda.uda_ca.ca_cmddsc; 117 uda.uda_cmd.mscp_un.un_seq.seq_addr = (long *)&uda.uda_ca.ca_cmddsc;
118 uda.uda_rsp.mscp_un.un_seq.seq_addr = (long *)&uda.uda_ca.ca_rspdsc; 118 uda.uda_rsp.mscp_un.un_seq.seq_addr = (long *)&uda.uda_ca.ca_rspdsc;
119 uda.uda_cmd.mscp_vcid = 1; 119 uda.uda_cmd.mscp_vcid = 1;
120 uda.uda_cmd.mscp_un.un_sccc.sccc_ctlrflags = 0; 120 uda.uda_cmd.mscp_un.un_sccc.sccc_ctlrflags = 0;
121 121
122 command(M_OP_SETCTLRC, 0); 122 command(M_OP_SETCTLRC, 0);
123 uda.uda_cmd.mscp_unit=ra->unit; 123 uda.uda_cmd.mscp_unit=ra->unit;
124 command(M_OP_ONLINE, 0); 124 command(M_OP_ONLINE, 0);
125 125
126 if (part) { 126 if (part) {
127 uda.uda_cmd.mscp_un.un_seq.seq_buffer = part; 127 uda.uda_cmd.mscp_un.un_seq.seq_buffer = part;
128 command(M_OP_POS, 0); 128 command(M_OP_POS, 0);
129 uda.uda_cmd.mscp_un.un_seq.seq_buffer = 0; 129 uda.uda_cmd.mscp_un.un_seq.seq_buffer = 0;
130 } 130 }
131 131
132 f->f_devdata=(void *)ra; 132 f->f_devdata=(void *)ra;
133 return(0); 133 return(0);
134} 134}
135 135
136static 136static
137command(cmd, arg) 137command(cmd, arg)
138{ 138{
139 volatile int hej; 139 volatile int hej;
140 140
141 uda.uda_cmd.mscp_opcode = cmd; 141 uda.uda_cmd.mscp_opcode = cmd;
142 uda.uda_cmd.mscp_modifier = arg; 142 uda.uda_cmd.mscp_modifier = arg;
143 143
144 uda.uda_cmd.mscp_msglen = MSCP_MSGLEN; 144 uda.uda_cmd.mscp_msglen = MSCP_MSGLEN;
145 uda.uda_rsp.mscp_msglen = MSCP_MSGLEN; 145 uda.uda_rsp.mscp_msglen = MSCP_MSGLEN;
146 146
147 uda.uda_ca.ca_rspdsc |= MSCP_OWN|MSCP_INT; 147 uda.uda_ca.ca_rspdsc |= MSCP_OWN|MSCP_INT;
148 uda.uda_ca.ca_cmddsc |= MSCP_OWN|MSCP_INT; 148 uda.uda_ca.ca_cmddsc |= MSCP_OWN|MSCP_INT;
149 hej = udacsr->udaip; 149 hej = udacsr->udaip;
150 while (uda.uda_ca.ca_rspdsc < 0) { 150 while (uda.uda_ca.ca_rspdsc < 0) {
151 if (uda.uda_ca.ca_cmdint) 151 if (uda.uda_ca.ca_cmdint)
152 uda.uda_ca.ca_cmdint = 0; 152 uda.uda_ca.ca_cmdint = 0;
153 } 153 }
154 154
155} 155}
156 156
157tmscpstrategy(struct ra_softc *ra, int func, daddr_t dblk, u_int size, char *buf, u_int *rsize) 157tmscpstrategy(struct ra_softc *ra, int func, daddr_t dblk, u_int size, char *buf, u_int *rsize)
158{ 158{
159 u_int i,j,pfnum, mapnr, nsize, bn, cn, sn, tn; 159 u_int i,j,pfnum, mapnr, nsize, bn, cn, sn, tn;
160 volatile struct udadevice *udadev=(void*)ra->udaddr; 160 volatile struct udadevice *udadev=(void*)ra->udaddr;
161 volatile u_int *ptmapp = (u_int *)ra->ubaddr + 512; 161 volatile u_int *ptmapp = (u_int *)ra->ubaddr + 512;
162 volatile int hej; 162 volatile int hej;
163 163
164 pfnum=(u_int)buf>>VAX_PGSHIFT; 164 pfnum=(u_int)buf>>VAX_PGSHIFT;
165 165
166 for(mapnr=0, nsize=size;(nsize+VAX_NBPG)>0;nsize-=VAX_NBPG) 166 for(mapnr=0, nsize=size;(nsize+VAX_NBPG)>0;nsize-=VAX_NBPG)
167 ptmapp[mapnr++]=PG_V|pfnum++; 167 ptmapp[mapnr++]=PG_V|pfnum++;
168 168
169 /* 169 /*
170 * First position tape. Remember where we are. 170 * First position tape. Remember where we are.
171 */ 171 */
172 if (dblk < curblock) { 172 if (dblk < curblock) {
173 uda.uda_cmd.mscp_seq.seq_bytecount = curblock - dblk; 173 uda.uda_cmd.mscp_seq.seq_bytecount = curblock - dblk;
174 command(M_OP_POS, 12); /* 12 == step block backward */ 174 command(M_OP_POS, 12); /* 12 == step block backward */
175 } else { 175 } else {
176 uda.uda_cmd.mscp_seq.seq_bytecount = dblk - curblock; 176 uda.uda_cmd.mscp_seq.seq_bytecount = dblk - curblock;
177 command(M_OP_POS, 4); /* 4 == step block forward */ 177 command(M_OP_POS, 4); /* 4 == step block forward */
178 } 178 }
179 curblock = size/512 + dblk; 179 curblock = size/512 + dblk;
180 180
181 /* 181 /*
182 * Read in the number of blocks we need. 182 * Read in the number of blocks we need.
183 * Why doesn't read of multiple blocks work????? 183 * Why doesn't read of multiple blocks work?????
184 */ 184 */
185 for (i = 0 ; i < size/512 ; i++) { 185 for (i = 0 ; i < size/512 ; i++) {
186 uda.uda_cmd.mscp_seq.seq_lbn = 1; 186 uda.uda_cmd.mscp_seq.seq_lbn = 1;
187 uda.uda_cmd.mscp_seq.seq_bytecount = 512; 187 uda.uda_cmd.mscp_seq.seq_bytecount = 512;
188 uda.uda_cmd.mscp_seq.seq_buffer = 188 uda.uda_cmd.mscp_seq.seq_buffer =
189 (((u_int)buf) & 0x1ff) + i * 512; 189 (((u_int)buf) & 0x1ff) + i * 512;
190 uda.uda_cmd.mscp_unit = ra->unit; 190 uda.uda_cmd.mscp_unit = ra->unit;
191 command(M_OP_READ, 0); 191 command(M_OP_READ, 0);
192 } 192 }
193 193
194 *rsize=size; 194 *rsize=size;
195 return 0; 195 return 0;
196} 196}

cvs diff -r1.47 -r1.48 src/sys/dev/isa/Attic/if_hp.c (switch to unified diff)

--- src/sys/dev/isa/Attic/if_hp.c 2009/03/14 21:04:20 1.47
+++ src/sys/dev/isa/Attic/if_hp.c 2009/03/17 18:19:15 1.48
@@ -1,1012 +1,1012 @@ @@ -1,1012 +1,1012 @@
1/* $NetBSD: if_hp.c,v 1.47 2009/03/14 21:04:20 dsl Exp $ */ 1/* $NetBSD: if_hp.c,v 1.48 2009/03/17 18:19:15 dsl Exp $ */
2 2
3/* XXX THIS DRIVER IS BROKEN. IT WILL NOT EVEN COMPILE. */ 3/* XXX THIS DRIVER IS BROKEN. IT WILL NOT EVEN COMPILE. */
4 4
5/*- 5/*-
6 * Copyright (c) 1990 The Regents of the University of California. 6 * Copyright (c) 1990 The Regents of the University of California.
7 * All rights reserved. 7 * All rights reserved.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the University nor the names of its contributors 17 * 3. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software 18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 19 * without specific prior written permission.
20 * 20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE. 31 * SUCH DAMAGE.
32 */ 32 */
33 33
34/*- 34/*-
35 * Copyright (c) 1990, 1991 William F. Jolitz. 35 * Copyright (c) 1990, 1991 William F. Jolitz.
36 * 36 *
37 * Redistribution and use in source and binary forms, with or without 37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions 38 * modification, are permitted provided that the following conditions
39 * are met: 39 * are met:
40 * 1. Redistributions of source code must retain the above copyright 40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer. 41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright 42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the 43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution. 44 * documentation and/or other materials provided with the distribution.
45 * 3. All advertising materials mentioning features or use of this software 45 * 3. All advertising materials mentioning features or use of this software
46 * must display the following acknowledgement: 46 * must display the following acknowledgement:
47 * This product includes software developed by the University of 47 * This product includes software developed by the University of
48 * California, Berkeley and its contributors. 48 * California, Berkeley and its contributors.
49 * 4. Neither the name of the University nor the names of its contributors 49 * 4. Neither the name of the University nor the names of its contributors
50 * may be used to endorse or promote products derived from this software 50 * may be used to endorse or promote products derived from this software
51 * without specific prior written permission. 51 * without specific prior written permission.
52 * 52 *
53 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 53 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
54 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 54 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 56 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63 * SUCH DAMAGE. 63 * SUCH DAMAGE.
64 */ 64 */
65 65
66/* 66/*
67 * HP LAN Ethernet driver 67 * HP LAN Ethernet driver
68 * 68 *
69 * Parts inspired from Tim Tucker's if_wd driver for the wd8003, 69 * Parts inspired from Tim Tucker's if_wd driver for the wd8003,
70 * insight on the ne2000 gained from Robert Clements PC/FTP driver. 70 * insight on the ne2000 gained from Robert Clements PC/FTP driver.
71 * 71 *
72 * receive bottom end totally rewritten by Curt Mayer, Dec 1992. 72 * receive bottom end totally rewritten by Curt Mayer, Dec 1992.
73 * no longer loses back to back packets. 73 * no longer loses back to back packets.
74 * note to driver writers: RTFM! 74 * note to driver writers: RTFM!
75 * 75 *
76 * hooks for packet filter added by Charles Hannum, 29DEC1992. 76 * hooks for packet filter added by Charles Hannum, 29DEC1992.
77 * 77 *
78 * Mostly rewritten for HP-labelled EISA controllers by Charles Hannum, 78 * Mostly rewritten for HP-labelled EISA controllers by Charles Hannum,
79 * 18JAN1993. 79 * 18JAN1993.
80 */ 80 */
81 81
82#include <sys/cdefs.h> 82#include <sys/cdefs.h>
83__KERNEL_RCSID(0, "$NetBSD: if_hp.c,v 1.47 2009/03/14 21:04:20 dsl Exp $"); 83__KERNEL_RCSID(0, "$NetBSD: if_hp.c,v 1.48 2009/03/17 18:19:15 dsl Exp $");
84 84
85#include "hp.h" 85#include "hp.h"
86#if NHP > 0 86#if NHP > 0
87 87
88#include "opt_inet.h" 88#include "opt_inet.h"
89#include "rnd.h" 89#include "rnd.h"
90 90
91#include <sys/param.h> 91#include <sys/param.h>
92#include <sys/systm.h> 92#include <sys/systm.h>
93#include <sys/mbuf.h> 93#include <sys/mbuf.h>
94#include <sys/buf.h> 94#include <sys/buf.h>
95#include <sys/protosw.h> 95#include <sys/protosw.h>
96#include <sys/socket.h> 96#include <sys/socket.h>
97#include <sys/ioctl.h> 97#include <sys/ioctl.h>
98#include <sys/errno.h> 98#include <sys/errno.h>
99#include <sys/syslog.h> 99#include <sys/syslog.h>
100#if NRND > 0 100#if NRND > 0
101#include <sys/rnd.h> 101#include <sys/rnd.h>
102#endif 102#endif
103 103
104#include <net/if.h> 104#include <net/if.h>
105#include <net/if_ether.h> 105#include <net/if_ether.h>
106 106
107#ifdef INET 107#ifdef INET
108#include <netinet/in.h> 108#include <netinet/in.h>
109#include <netinet/in_systm.h> 109#include <netinet/in_systm.h>
110#include <netinet/in_var.h> 110#include <netinet/in_var.h>
111#include <netinet/ip.h> 111#include <netinet/ip.h>
112#include <netinet/if_inarp.h> 112#include <netinet/if_inarp.h>
113#endif 113#endif
114 114
115 115
116#include "bpfilter.h" 116#include "bpfilter.h"
117#if NBPFILTER > 0 117#if NBPFILTER > 0
118#include <sys/select.h> 118#include <sys/select.h>
119#include <net/bpf.h> 119#include <net/bpf.h>
120#include <net/bpfdesc.h> 120#include <net/bpfdesc.h>
121#endif 121#endif
122 122
123#include <sys/cpu.h> 123#include <sys/cpu.h>
124#include <machine/pio.h> 124#include <machine/pio.h>
125 125
126#include <i386/isa/isa_device.h> /* XXX BROKEN */ 126#include <i386/isa/isa_device.h> /* XXX BROKEN */
127#include <dev/isa/if_nereg.h> 127#include <dev/isa/if_nereg.h>
128#include <i386/isa/icu.h> /* XXX BROKEN */ 128#include <i386/isa/icu.h> /* XXX BROKEN */
129 129
130int hpprobe(), hpattach(), hpintr(); 130int hpprobe(), hpattach(), hpintr();
131int hpstart(), hpinit(), ether_output(), hpioctl(); 131int hpstart(), hpinit(), ether_output(), hpioctl();
132 132
133struct isa_driver hpdriver = 133struct isa_driver hpdriver =
134{ 134{
135 hpprobe, hpattach, "hp", 135 hpprobe, hpattach, "hp",
136}; 136};
137 137
138struct mbuf *hpget(); 138struct mbuf *hpget();
139 139
140/* 140/*
141 * Ethernet software status per interface. 141 * Ethernet software status per interface.
142 * 142 *
143 * Each interface is referenced by a network interface structure, 143 * Each interface is referenced by a network interface structure,
144 * ns_if, which the routing code uses to locate the interface. 144 * ns_if, which the routing code uses to locate the interface.
145 * This structure contains the output queue for the interface, its address, ... 145 * This structure contains the output queue for the interface, its address, ...
146 */ 146 */
147struct hp_softc { 147struct hp_softc {
148 struct ethercom ns_ec; /* Ethernet common part */ 148 struct ethercom ns_ec; /* Ethernet common part */
149#define ns_if ns_ac.ac_if /* network-visible interface */ 149#define ns_if ns_ac.ac_if /* network-visible interface */
150 int ns_flags; 150 int ns_flags;
151#define DSF_LOCK 1 /* block re-entering enstart */ 151#define DSF_LOCK 1 /* block re-entering enstart */
152 int ns_oactive; 152 int ns_oactive;
153 int ns_mask; 153 int ns_mask;
154 struct prhdr ns_ph; /* hardware header of incoming packet */ 154 struct prhdr ns_ph; /* hardware header of incoming packet */
155 u_char ns_pb[2048]; 155 u_char ns_pb[2048];
156 u_char ns_txstart; /* transmitter buffer start */ 156 u_char ns_txstart; /* transmitter buffer start */
157 u_char ns_rxstart; /* receiver buffer start */ 157 u_char ns_rxstart; /* receiver buffer start */
158 u_char ns_rxend; /* receiver buffer end */ 158 u_char ns_rxend; /* receiver buffer end */
159 u_char hp_type; /* HP board type */ 159 u_char hp_type; /* HP board type */
160 u_char hp_irq; /* interrupt vector */ 160 u_char hp_irq; /* interrupt vector */
161 short ns_port; /* i/o port base */ 161 short ns_port; /* i/o port base */
162 short ns_mode; /* word/byte mode */ 162 short ns_mode; /* word/byte mode */
163 short ns_rcr; 163 short ns_rcr;
164#if NBPFILTER > 0 164#if NBPFILTER > 0
165 void *ns_bpf; 165 void *ns_bpf;
166#endif 166#endif
167 u_int8_t ns_addrp[ETHER_ADDR_LEN]; /* hardware Ethernet address */ 167 u_int8_t ns_addrp[ETHER_ADDR_LEN]; /* hardware Ethernet address */
168 168
169#if NRND > 0 169#if NRND > 0
170 rndsource_element_t rnd_source; 170 rndsource_element_t rnd_source;
171#endif 171#endif
172} 172}
173 hp_softc[NHP]; 173 hp_softc[NHP];
174#define ENBUFSIZE (sizeof(struct ether_header) + ETHERMTU + 2 + ETHER_MIN_LEN) 174#define ENBUFSIZE (sizeof(struct ether_header) + ETHERMTU + 2 + ETHER_MIN_LEN)
175 175
176#define PAT(n) (0xa55a + 37*(n)) 176#define PAT(n) (0xa55a + 37*(n))
177 177
178u_short boarddata[16]; 178u_short boarddata[16];
179 179
180#define hp_option (-8) 180#define hp_option (-8)
181#define hp_data (-4) 181#define hp_data (-4)
182#define HP_RUN (0x01) 182#define HP_RUN (0x01)
183#define HP_DATA (0x10) 183#define HP_DATA (0x10)
184 184
185hpprobe(struct isa_device *dvp) 185hpprobe(struct isa_device *dvp)
186{ 186{
187 int val, i, s, sum, pat; 187 int val, i, s, sum, pat;
188 struct hp_softc *ns = &hp_softc[0]; 188 struct hp_softc *ns = &hp_softc[0];
189 int hpc; 189 int hpc;
190 190
191#ifdef lint 191#ifdef lint
192 hpintr(0); 192 hpintr(0);
193#endif 193#endif
194 194
195 hpc = (ns->ns_port = dvp->id_iobase + 0x10); 195 hpc = (ns->ns_port = dvp->id_iobase + 0x10);
196 s = splnet(); 196 s = splnet();
197 197
198 ns->hp_irq = ffs(dvp->id_irq) - 1; 198 ns->hp_irq = ffs(dvp->id_irq) - 1;
199 199
200 /* Extract board address */ 200 /* Extract board address */
201 for (i = 0; i < 6; i++) 201 for (i = 0; i < 6; i++)
202 ns->ns_addrp[i] = inb(hpc - 0x10 + i); 202 ns->ns_addrp[i] = inb(hpc - 0x10 + i);
203 ns->hp_type = inb(hpc - 0x10 + 7); 203 ns->hp_type = inb(hpc - 0x10 + 7);
204 204
205 if (ns->ns_addrp[0] != 0x08 || 205 if (ns->ns_addrp[0] != 0x08 ||
206 ns->ns_addrp[1] != 0x00 || 206 ns->ns_addrp[1] != 0x00 ||
207 ns->ns_addrp[2] != 0x09) { 207 ns->ns_addrp[2] != 0x09) {
208 splx(s); 208 splx(s);
209 return 0; 209 return 0;
210 } 210 }
211 /* Word Transfers, Burst Mode Select, Fifo at 8 bytes */ 211 /* Word Transfers, Burst Mode Select, Fifo at 8 bytes */
212 /* On this board, WTS means 32-bit transfers, which is still 212 /* On this board, WTS means 32-bit transfers, which is still
213 * experimental. - mycroft, 18JAN93 */ 213 * experimental. - mycroft, 18JAN93 */
214#ifdef HP_32BIT 214#ifdef HP_32BIT
215 ns->ns_mode = DSDC_WTS | DSDC_BMS | DSDC_FT1; 215 ns->ns_mode = DSDC_WTS | DSDC_BMS | DSDC_FT1;
216#else 216#else
217 ns->ns_mode = DSDC_BMS | DSDC_FT1; 217 ns->ns_mode = DSDC_BMS | DSDC_FT1;
218#endif 218#endif
219 ns->ns_txstart = 0 * 1024 / DS_PGSIZE; 219 ns->ns_txstart = 0 * 1024 / DS_PGSIZE;
220 ns->ns_rxend = 32 * 1024 / DS_PGSIZE; 220 ns->ns_rxend = 32 * 1024 / DS_PGSIZE;
221 221
222 ns->ns_rxstart = ns->ns_txstart + (PKTSZ / DS_PGSIZE); 222 ns->ns_rxstart = ns->ns_txstart + (PKTSZ / DS_PGSIZE);
223 223
224 outb(hpc + hp_option, HP_RUN); 224 outb(hpc + hp_option, HP_RUN);
225 225
226#if 0 226#if 0
227 outb(hpc + ds0_isr, 0xff); 227 outb(hpc + ds0_isr, 0xff);
228 outb(hpc + ds_cmd, DSCM_NODMA | DSCM_PG0 | DSCM_STOP); 228 outb(hpc + ds_cmd, DSCM_NODMA | DSCM_PG0 | DSCM_STOP);
229 delay(1000); 229 delay(1000);
230 230
231 /* Check cmd reg and fail if not right */ 231 /* Check cmd reg and fail if not right */
232 if ((i = inb(hpc + ds_cmd)) != (DSCM_NODMA | DSCM_PG0 | DSCM_STOP)) { 232 if ((i = inb(hpc + ds_cmd)) != (DSCM_NODMA | DSCM_PG0 | DSCM_STOP)) {
233 splx(s); 233 splx(s);
234 return (0); 234 return (0);
235 } 235 }
236#endif 236#endif
237 237
238 outb(hpc + hp_option, 0); 238 outb(hpc + hp_option, 0);
239 239
240 splx(s); 240 splx(s);
241 return (32); 241 return (32);
242} 242}
243/* 243/*
244 * Fetch from onboard ROM/RAM 244 * Fetch from onboard ROM/RAM
245 */ 245 */
246hpfetch(struct hp_softc *ns, void *up, ad, len) 246hpfetch(struct hp_softc *ns, void *up, int ad, int len)
247{ 247{
248 u_char cmd; 248 u_char cmd;
249 int hpc = ns->ns_port; 249 int hpc = ns->ns_port;
250 int counter = 100000; 250 int counter = 100000;
251 251
252 outb(hpc + hp_option, inb(hpc + hp_option) | HP_DATA); 252 outb(hpc + hp_option, inb(hpc + hp_option) | HP_DATA);
253 253
254 cmd = inb(hpc + ds_cmd); 254 cmd = inb(hpc + ds_cmd);
255 outb(hpc + ds_cmd, DSCM_NODMA | DSCM_PG0 | DSCM_START); 255 outb(hpc + ds_cmd, DSCM_NODMA | DSCM_PG0 | DSCM_START);
256 256
257 /* Setup remote DMA */ 257 /* Setup remote DMA */
258 outb(hpc + ds0_isr, DSIS_RDC); 258 outb(hpc + ds0_isr, DSIS_RDC);
259 259
260 if (ns->ns_mode & DSDC_WTS) 260 if (ns->ns_mode & DSDC_WTS)
261 len = (len + 3) & ~3; 261 len = (len + 3) & ~3;
262 else 262 else
263 len = (len + 1) & ~1; 263 len = (len + 1) & ~1;
264 264
265 outb(hpc + ds0_rbcr0, len); 265 outb(hpc + ds0_rbcr0, len);
266 outb(hpc + ds0_rbcr1, len >> 8); 266 outb(hpc + ds0_rbcr1, len >> 8);
267 outb(hpc + ds0_rsar0, ad); 267 outb(hpc + ds0_rsar0, ad);
268 outb(hpc + ds0_rsar1, ad >> 8); 268 outb(hpc + ds0_rsar1, ad >> 8);
269 269
270#ifdef HP_DEBUG 270#ifdef HP_DEBUG
271 printf("hpfetch: len=%d ioaddr=0x%03x addr=0x%04x option=0x%02x %d-bit\n", 271 printf("hpfetch: len=%d ioaddr=0x%03x addr=0x%04x option=0x%02x %d-bit\n",
272 len, hpc + hp_data, ad, inb(hpc + hp_option), 272 len, hpc + hp_data, ad, inb(hpc + hp_option),
273 ns->ns_mode & DSDC_WTS ? 32 : 16); 273 ns->ns_mode & DSDC_WTS ? 32 : 16);
274 printf("hpfetch: cmd=0x%02x isr=0x%02x ", 274 printf("hpfetch: cmd=0x%02x isr=0x%02x ",
275 inb(hpc + ds_cmd), inb(hpc + ds0_isr)); 275 inb(hpc + ds_cmd), inb(hpc + ds0_isr));
276 outb(hpc + ds_cmd, DSCM_NODMA | DSCM_PG2 | DSCM_START); 276 outb(hpc + ds_cmd, DSCM_NODMA | DSCM_PG2 | DSCM_START);
277 printf("imr=0x%02x rcr=0x%02x tcr=0x%02x dcr=0x%02x\n", 277 printf("imr=0x%02x rcr=0x%02x tcr=0x%02x dcr=0x%02x\n",
278 inb(hpc + ds0_imr), inb(hpc + ds0_rcr), inb(hpc + ds0_tcr), 278 inb(hpc + ds0_imr), inb(hpc + ds0_rcr), inb(hpc + ds0_tcr),
279 inb(hpc + ds0_dcr)); 279 inb(hpc + ds0_dcr));
280#endif 280#endif
281 281
282 /* Execute & extract from card */ 282 /* Execute & extract from card */
283 outb(hpc + ds_cmd, DSCM_RREAD | DSCM_PG0 | DSCM_START); 283 outb(hpc + ds_cmd, DSCM_RREAD | DSCM_PG0 | DSCM_START);
284 284
285#ifdef HP_32BIT 285#ifdef HP_32BIT
286 if (ns->ns_mode & DSDC_WTS) 286 if (ns->ns_mode & DSDC_WTS)
287 len = (void *) insd(hpc + hp_data, up, len >> 2) - up; 287 len = (void *) insd(hpc + hp_data, up, len >> 2) - up;
288 else 288 else
289#endif 289#endif
290 len = (void *) insw(hpc + hp_data, up, len >> 1) - up; 290 len = (void *) insw(hpc + hp_data, up, len >> 1) - up;
291 291
292#ifdef HP_DEBUG 292#ifdef HP_DEBUG
293 printf("hpfetch: done len=%d\n", len); 293 printf("hpfetch: done len=%d\n", len);
294#endif 294#endif
295 295
296 /* Wait till done, then shutdown feature */ 296 /* Wait till done, then shutdown feature */
297 while ((inb(hpc + ds0_isr) & DSIS_RDC) == 0 && counter-- > 0); 297 while ((inb(hpc + ds0_isr) & DSIS_RDC) == 0 && counter-- > 0);
298 outb(hpc + ds0_isr, DSIS_RDC); 298 outb(hpc + ds0_isr, DSIS_RDC);
299 outb(hpc + ds_cmd, cmd); 299 outb(hpc + ds_cmd, cmd);
300 300
301 outb(hpc + hp_option, inb(hpc + hp_option) & ~HP_DATA); 301 outb(hpc + hp_option, inb(hpc + hp_option) & ~HP_DATA);
302} 302}
303/* 303/*
304 * Put to onboard RAM 304 * Put to onboard RAM
305 */ 305 */
306hpput(struct hp_softc *ns, void *up, ad, len) 306hpput(struct hp_softc *ns, void *up, int ad, int len)
307{ 307{
308 u_char cmd; 308 u_char cmd;
309 int hpc = ns->ns_port; 309 int hpc = ns->ns_port;
310 int counter = 100000; 310 int counter = 100000;
311 311
312 outb(hpc + hp_option, inb(hpc + hp_option) | HP_DATA); 312 outb(hpc + hp_option, inb(hpc + hp_option) | HP_DATA);
313 313
314 cmd = inb(hpc + ds_cmd); 314 cmd = inb(hpc + ds_cmd);
315 outb(hpc + ds_cmd, DSCM_NODMA | DSCM_PG0 | DSCM_START); 315 outb(hpc + ds_cmd, DSCM_NODMA | DSCM_PG0 | DSCM_START);
316 316
317 /* Setup for remote DMA */ 317 /* Setup for remote DMA */
318 outb(hpc + ds0_isr, DSIS_RDC); 318 outb(hpc + ds0_isr, DSIS_RDC);
319 319
320 if (ns->ns_mode & DSDC_WTS) 320 if (ns->ns_mode & DSDC_WTS)
321 len = (len + 3) & ~3; 321 len = (len + 3) & ~3;
322 else 322 else
323 len = (len + 1) & ~1; 323 len = (len + 1) & ~1;
324 324
325#ifdef HP_DEBUG 325#ifdef HP_DEBUG
326 printf("hpput: len=%d ioaddr=0x%03x addr=0x%04x option=0x%02x %d-bit\n", 326 printf("hpput: len=%d ioaddr=0x%03x addr=0x%04x option=0x%02x %d-bit\n",
327 len, hpc + hp_data, ad, inb(hpc + hp_option), 327 len, hpc + hp_data, ad, inb(hpc + hp_option),
328 ns->ns_mode & DSDC_WTS ? 32 : 16); 328 ns->ns_mode & DSDC_WTS ? 32 : 16);
329 printf("hpput: cmd=0x%02x isr=0x%02x ", 329 printf("hpput: cmd=0x%02x isr=0x%02x ",
330 inb(hpc + ds_cmd), inb(hpc + ds0_isr)); 330 inb(hpc + ds_cmd), inb(hpc + ds0_isr));
331 outb(hpc + ds_cmd, DSCM_NODMA | DSCM_PG2 | DSCM_START); 331 outb(hpc + ds_cmd, DSCM_NODMA | DSCM_PG2 | DSCM_START);
332 printf("imr=0x%02x rcr=0x%02x tcr=0x%02x dcr=0x%02x\n", 332 printf("imr=0x%02x rcr=0x%02x tcr=0x%02x dcr=0x%02x\n",
333 inb(hpc + ds0_imr), inb(hpc + ds0_rcr), inb(hpc + ds0_tcr), 333 inb(hpc + ds0_imr), inb(hpc + ds0_rcr), inb(hpc + ds0_tcr),
334 inb(hpc + ds0_dcr)); 334 inb(hpc + ds0_dcr));
335 { 335 {
336 unsigned char *p = (unsigned char *) up; 336 unsigned char *p = (unsigned char *) up;
337 int n = len; 337 int n = len;
338 printf("hpput:"); 338 printf("hpput:");
339 while (n--) 339 while (n--)
340 printf(" %02x", *(p++)); 340 printf(" %02x", *(p++));
341 printf("\n"); 341 printf("\n");
342 } 342 }
343#endif 343#endif
344 344
345 outb(hpc + ds_cmd, DSCM_NODMA | DSCM_PG0 | DSCM_START); 345 outb(hpc + ds_cmd, DSCM_NODMA | DSCM_PG0 | DSCM_START);
346 outb(hpc + ds0_rbcr0, 0xff); 346 outb(hpc + ds0_rbcr0, 0xff);
347 outb(hpc + ds_cmd, DSCM_RREAD | DSCM_PG0 | DSCM_START); 347 outb(hpc + ds_cmd, DSCM_RREAD | DSCM_PG0 | DSCM_START);
348 348
349 outb(hpc + ds0_rbcr0, len); 349 outb(hpc + ds0_rbcr0, len);
350 outb(hpc + ds0_rbcr1, len >> 8); 350 outb(hpc + ds0_rbcr1, len >> 8);
351 outb(hpc + ds0_rsar0, ad); 351 outb(hpc + ds0_rsar0, ad);
352 outb(hpc + ds0_rsar1, ad >> 8); 352 outb(hpc + ds0_rsar1, ad >> 8);
353 353
354 /* Execute & stuff to card */ 354 /* Execute & stuff to card */
355 outb(hpc + ds_cmd, DSCM_RWRITE | DSCM_PG0 | DSCM_START); 355 outb(hpc + ds_cmd, DSCM_RWRITE | DSCM_PG0 | DSCM_START);
356 356
357#ifdef HP_32BIT 357#ifdef HP_32BIT
358 if (ns->ns_mode & DSDC_WTS) 358 if (ns->ns_mode & DSDC_WTS)
359 len = (void *) outsd(hpc + hp_data, up, len >> 2) - up; 359 len = (void *) outsd(hpc + hp_data, up, len >> 2) - up;
360 else 360 else
361#endif 361#endif
362 len = (void *) outsw(hpc + hp_data, up, len >> 1) - up; 362 len = (void *) outsw(hpc + hp_data, up, len >> 1) - up;
363 363
364#ifdef HP_DEBUG 364#ifdef HP_DEBUG
365 printf("hpput: done len=%d\n", len); 365 printf("hpput: done len=%d\n", len);
366#endif 366#endif
367 367
368 /* Wait till done, then shutdown feature */ 368 /* Wait till done, then shutdown feature */
369 while ((inb(hpc + ds0_isr) & DSIS_RDC) == 0 && counter-- > 0); 369 while ((inb(hpc + ds0_isr) & DSIS_RDC) == 0 && counter-- > 0);
370 outb(hpc + ds0_isr, DSIS_RDC); 370 outb(hpc + ds0_isr, DSIS_RDC);
371 outb(hpc + ds_cmd, cmd); 371 outb(hpc + ds_cmd, cmd);
372 372
373 outb(hpc + hp_option, inb(hpc + hp_option) & ~HP_DATA); 373 outb(hpc + hp_option, inb(hpc + hp_option) & ~HP_DATA);
374} 374}
375/* 375/*
376 * Reset of interface. 376 * Reset of interface.
377 */ 377 */
378hpreset(int unit, int uban) 378hpreset(int unit, int uban)
379{ 379{
380 struct hp_softc *ns = &hp_softc[unit]; 380 struct hp_softc *ns = &hp_softc[unit];
381 int hpc = ns->ns_port; 381 int hpc = ns->ns_port;
382 if (unit >= NHP) 382 if (unit >= NHP)
383 return; 383 return;
384 printf("hp%d: reset\n", unit); 384 printf("hp%d: reset\n", unit);
385 outb(hpc + hp_option, 0); 385 outb(hpc + hp_option, 0);
386 ns->ns_flags &= ~DSF_LOCK; 386 ns->ns_flags &= ~DSF_LOCK;
387 hpinit(unit); 387 hpinit(unit);
388} 388}
389 389
390static char * 390static char *
391hp_id(u_char type) 391hp_id(u_char type)
392{ 392{
393 static struct { 393 static struct {
394 u_char type; 394 u_char type;
395 char *name; 395 char *name;
396 } boards[] = { 396 } boards[] = {
397 { 397 {
398 0x00, "hp27240" 398 0x00, "hp27240"
399 }, { 399 }, {
400 0x10, "hp24240" 400 0x10, "hp24240"
401 }, { 401 }, {
402 0x01, "hp27245" 402 0x01, "hp27245"
403 }, { 403 }, {
404 0x02, "hp27250" 404 0x02, "hp27250"
405 }, { 405 }, {
406 0x81, "hp27247" 406 0x81, "hp27247"
407 }, { 407 }, {
408 0x91, "hp27247r1" 408 0x91, "hp27247r1"
409 } 409 }
410 }; 410 };
411 int n = sizeof(boards) / sizeof(boards[0]); 411 int n = sizeof(boards) / sizeof(boards[0]);
412 412
413 while (n) 413 while (n)
414 if (boards[--n].type == type) 414 if (boards[--n].type == type)
415 return boards[n].name; 415 return boards[n].name;
416 416
417 return "UNKNOWN"; 417 return "UNKNOWN";
418} 418}
419/* 419/*
420 * Interface exists: make available by filling in network interface 420 * Interface exists: make available by filling in network interface
421 * record. System will initialize the interface when it is ready 421 * record. System will initialize the interface when it is ready
422 * to accept packets. We get the ethernet address here. 422 * to accept packets. We get the ethernet address here.
423 */ 423 */
424hpattach(struct isa_device *dvp) 424hpattach(struct isa_device *dvp)
425{ 425{
426 int unit = dvp->id_unit; 426 int unit = dvp->id_unit;
427 struct hp_softc *ns = &hp_softc[unit]; 427 struct hp_softc *ns = &hp_softc[unit];
428 struct ifnet *ifp = &ns->ns_if; 428 struct ifnet *ifp = &ns->ns_if;
429 429
430 ifp->if_unit = unit; 430 ifp->if_unit = unit;
431 ifp->if_name = hpdriver.name; 431 ifp->if_name = hpdriver.name;
432 ifp->if_mtu = ETHERMTU; 432 ifp->if_mtu = ETHERMTU;
433 printf("hp%d: %s %d-bit ethernet address %s\n", unit, 433 printf("hp%d: %s %d-bit ethernet address %s\n", unit,
434 hp_id(ns->hp_type), ns->ns_mode & DSDC_WTS ? 32 : 16, 434 hp_id(ns->hp_type), ns->ns_mode & DSDC_WTS ? 32 : 16,
435 ether_sprintf(ns->ns_addrp)); 435 ether_sprintf(ns->ns_addrp));
436 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS; 436 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS;
437 ifp->if_output = ether_output; 437 ifp->if_output = ether_output;
438 ifp->if_start = hpstart; 438 ifp->if_start = hpstart;
439 ifp->if_ioctl = hpioctl; 439 ifp->if_ioctl = hpioctl;
440 ifp->if_reset = hpreset; 440 ifp->if_reset = hpreset;
441 ifp->if_watchdog = 0; 441 ifp->if_watchdog = 0;
442 IFQ_SET_READY(&ifp->if_snd); 442 IFQ_SET_READY(&ifp->if_snd);
443 if_attach(ifp); 443 if_attach(ifp);
444 444
445#if NBPFILTER > 0 445#if NBPFILTER > 0
446 bpfattach(&ns->ns_bpf, ifp, DLT_EN10MB, 446 bpfattach(&ns->ns_bpf, ifp, DLT_EN10MB,
447 sizeof(struct ether_header)); 447 sizeof(struct ether_header));
448#endif 448#endif
449 449
450#if NRND > 0 450#if NRND > 0
451 rnd_attach_source(&ns->rnd_source, device_xname(&ns->sc_dev), 451 rnd_attach_source(&ns->rnd_source, device_xname(&ns->sc_dev),
452 RND_TYPE_NET, 0); 452 RND_TYPE_NET, 0);
453#endif 453#endif
454 454
455} 455}
456/* 456/*
457 * Initialization of interface; set up initialization block 457 * Initialization of interface; set up initialization block
458 * and transmit/receive descriptor rings. 458 * and transmit/receive descriptor rings.
459 */ 459 */
460hpinit(int unit) 460hpinit(int unit)
461{ 461{
462 struct hp_softc *ns = &hp_softc[unit]; 462 struct hp_softc *ns = &hp_softc[unit];
463 struct ifnet *ifp = &ns->ns_if; 463 struct ifnet *ifp = &ns->ns_if;
464 int s; 464 int s;
465 int i; 465 int i;
466 char *cp; 466 char *cp;
467 int hpc = ns->ns_port; 467 int hpc = ns->ns_port;
468 468
469 if (IFADDR_EMPTY(ifp)) 469 if (IFADDR_EMPTY(ifp))
470 return; 470 return;
471 if (ifp->if_flags & IFF_RUNNING) 471 if (ifp->if_flags & IFF_RUNNING)
472 return; 472 return;
473 473
474 s = splnet(); 474 s = splnet();
475 475
476#ifdef HP_DEBUG 476#ifdef HP_DEBUG
477 printf("hpinit: hp%d at 0x%x irq %d\n", unit, hpc, (int) ns->hp_irq); 477 printf("hpinit: hp%d at 0x%x irq %d\n", unit, hpc, (int) ns->hp_irq);
478 printf("hpinit: promiscuous mode %s\n", 478 printf("hpinit: promiscuous mode %s\n",
479 ns->ns_if.if_flags & IFF_PROMISC ? "on" : "off"); 479 ns->ns_if.if_flags & IFF_PROMISC ? "on" : "off");
480#endif 480#endif
481 481
482 ns->ns_rcr = (ns->ns_if.if_flags & IFF_BROADCAST ? DSRC_AB : 0) | 482 ns->ns_rcr = (ns->ns_if.if_flags & IFF_BROADCAST ? DSRC_AB : 0) |
483 (ns->ns_if.if_flags & IFF_PROMISC ? DSRC_PRO : 0); 483 (ns->ns_if.if_flags & IFF_PROMISC ? DSRC_PRO : 0);
484#ifdef HP_LOG_ERRORS 484#ifdef HP_LOG_ERRORS
485 ns->ns_rcr |= DSRC_SEP; 485 ns->ns_rcr |= DSRC_SEP;
486#endif 486#endif
487 487
488 /* set irq and turn on board */ 488 /* set irq and turn on board */
489 outb(hpc + hp_option, HP_RUN | (ns->hp_irq << 1)); 489 outb(hpc + hp_option, HP_RUN | (ns->hp_irq << 1));
490 490
491 /* init regs */ 491 /* init regs */
492 outb(hpc + ds_cmd, DSCM_NODMA | DSCM_PG0 | DSCM_STOP); 492 outb(hpc + ds_cmd, DSCM_NODMA | DSCM_PG0 | DSCM_STOP);
493 outb(hpc + ds0_dcr, 0); 493 outb(hpc + ds0_dcr, 0);
494 outb(hpc + ds0_rbcr0, 0); 494 outb(hpc + ds0_rbcr0, 0);
495 outb(hpc + ds0_rbcr1, 0); 495 outb(hpc + ds0_rbcr1, 0);
496 outb(hpc + ds0_rcr, DSRC_MON); 496 outb(hpc + ds0_rcr, DSRC_MON);
497 outb(hpc + ds0_tpsr, ns->ns_txstart); 497 outb(hpc + ds0_tpsr, ns->ns_txstart);
498 outb(hpc + ds0_imr, 0); 498 outb(hpc + ds0_imr, 0);
499 outb(hpc + ds0_tcr, DSTC_LB0); 499 outb(hpc + ds0_tcr, DSTC_LB0);
500 outb(hpc + ds0_pstart, ns->ns_rxstart); 500 outb(hpc + ds0_pstart, ns->ns_rxstart);
501 outb(hpc + ds0_bnry, ns->ns_rxend - 1); 501 outb(hpc + ds0_bnry, ns->ns_rxend - 1);
502 outb(hpc + ds0_pstop, ns->ns_rxend); 502 outb(hpc + ds0_pstop, ns->ns_rxend);
503 outb(hpc + ds0_isr, 0xff); 503 outb(hpc + ds0_isr, 0xff);
504 outb(hpc + ds_cmd, DSCM_NODMA | DSCM_PG1 | DSCM_STOP); 504 outb(hpc + ds_cmd, DSCM_NODMA | DSCM_PG1 | DSCM_STOP);
505 outb(hpc + ds1_curr, ns->ns_rxstart); 505 outb(hpc + ds1_curr, ns->ns_rxstart);
506 506
507 /* set physical address on ethernet */ 507 /* set physical address on ethernet */
508 for (i = 0; i < 6; i++) 508 for (i = 0; i < 6; i++)
509 outb(hpc + ds1_par0 + i, ns->ns_addrp[i]); 509 outb(hpc + ds1_par0 + i, ns->ns_addrp[i]);
510 510
511 /* clr logical address hash filter for now */ 511 /* clr logical address hash filter for now */
512 for (i = 0; i < 8; i++) 512 for (i = 0; i < 8; i++)
513 outb(hpc + ds1_mar0 + i, 0xff); 513 outb(hpc + ds1_mar0 + i, 0xff);
514 514
515 /* fire it up */ 515 /* fire it up */
516 outb(hpc + ds_cmd, DSCM_NODMA | DSCM_PG0 | DSCM_START); 516 outb(hpc + ds_cmd, DSCM_NODMA | DSCM_PG0 | DSCM_START);
517 outb(hpc + ds0_dcr, ns->ns_mode); 517 outb(hpc + ds0_dcr, ns->ns_mode);
518 outb(hpc + ds0_rcr, ns->ns_rcr); 518 outb(hpc + ds0_rcr, ns->ns_rcr);
519 outb(hpc + ds0_tcr, 0); 519 outb(hpc + ds0_tcr, 0);
520 outb(hpc + ds0_imr, 0xff); 520 outb(hpc + ds0_imr, 0xff);
521 521
522 ns->ns_if.if_flags |= IFF_RUNNING; 522 ns->ns_if.if_flags |= IFF_RUNNING;
523 ns->ns_flags &= ~DSF_LOCK; 523 ns->ns_flags &= ~DSF_LOCK;
524 ns->ns_oactive = 0; 524 ns->ns_oactive = 0;
525 ns->ns_mask = ~0; 525 ns->ns_mask = ~0;
526 hpstart(ifp); 526 hpstart(ifp);
527 527
528#ifdef HP_DEBUG 528#ifdef HP_DEBUG
529 printf("hpinit: done\n", unit, hpc); 529 printf("hpinit: done\n", unit, hpc);
530#endif 530#endif
531 531
532 splx(s); 532 splx(s);
533} 533}
534/* 534/*
535 * Setup output on interface. 535 * Setup output on interface.
536 * Get another datagram to send off of the interface queue, 536 * Get another datagram to send off of the interface queue,
537 * and map it to the interface before starting the output. 537 * and map it to the interface before starting the output.
538 * called only at splnet or interrupt level. 538 * called only at splnet or interrupt level.
539 */ 539 */
540hpstart(struct ifnet *ifp) 540hpstart(struct ifnet *ifp)
541{ 541{
542 struct hp_softc *ns = &hp_softc[ifp->if_unit]; 542 struct hp_softc *ns = &hp_softc[ifp->if_unit];
543 struct mbuf *m0, *m; 543 struct mbuf *m0, *m;
544 int buffer; 544 int buffer;
545 int len, i, total; 545 int len, i, total;
546 int hpc = ns->ns_port; 546 int hpc = ns->ns_port;
547 547
548 /* 548 /*
549 * The DS8390 has only one transmit buffer, if it is busy we 549 * The DS8390 has only one transmit buffer, if it is busy we
550 * must wait until the transmit interrupt completes. 550 * must wait until the transmit interrupt completes.
551 */ 551 */
552 if (ns->ns_flags & DSF_LOCK) 552 if (ns->ns_flags & DSF_LOCK)
553 return; 553 return;
554 554
555 if (inb(hpc + ds_cmd) & DSCM_TRANS) 555 if (inb(hpc + ds_cmd) & DSCM_TRANS)
556 return; 556 return;
557 557
558 if ((ns->ns_if.if_flags & IFF_RUNNING) == 0) 558 if ((ns->ns_if.if_flags & IFF_RUNNING) == 0)
559 return; 559 return;
560 560
561 IFQ_DEQUEUE(&ns->ns_if.if_snd, m); 561 IFQ_DEQUEUE(&ns->ns_if.if_snd, m);
562 562
563 if (m == 0) 563 if (m == 0)
564 return; 564 return;
565 565
566 /* 566 /*
567 * Copy the mbuf chain into the transmit buffer 567 * Copy the mbuf chain into the transmit buffer
568 */ 568 */
569 569
570 ns->ns_flags |= DSF_LOCK; /* prevent entering hpstart */ 570 ns->ns_flags |= DSF_LOCK; /* prevent entering hpstart */
571 buffer = ns->ns_txstart * DS_PGSIZE; 571 buffer = ns->ns_txstart * DS_PGSIZE;
572 i = 0; 572 i = 0;
573 total = len = m->m_pkthdr.len; 573 total = len = m->m_pkthdr.len;
574 574
575#ifdef HP_DEBUG 575#ifdef HP_DEBUG
576 printf("hpstart: len=%d\n", len); 576 printf("hpstart: len=%d\n", len);
577#endif 577#endif
578 578
579#if NBPFILTER > 0 579#if NBPFILTER > 0
580 if (ns->ns_bpf) 580 if (ns->ns_bpf)
581 bpf_mtap(ns->ns_bpf, m); 581 bpf_mtap(ns->ns_bpf, m);
582#endif 582#endif
583 583
584 for (m0 = m; m != 0;) { 584 for (m0 = m; m != 0;) {
585 if (m->m_len & 1 && t > m->m_len) { 585 if (m->m_len & 1 && t > m->m_len) {
586 m->m_len -= 1; 586 m->m_len -= 1;
587 hpput(ns, mtod(m, void *), buffer, m->m_len); 587 hpput(ns, mtod(m, void *), buffer, m->m_len);
588 t -= m->m_len; 588 t -= m->m_len;
589 buffer += m->m_len; 589 buffer += m->m_len;
590 m->m_data += m->m_len; 590 m->m_data += m->m_len;
591 m->m_len = 1; 591 m->m_len = 1;
592 m = m_pullup(m, 2); 592 m = m_pullup(m, 2);
593 } else { 593 } else {
594 hpput(ns, mtod(m, void *), buffer, m->m_len); 594 hpput(ns, mtod(m, void *), buffer, m->m_len);
595 t -= m->m_len; 595 t -= m->m_len;
596 buffer += m->m_len; 596 buffer += m->m_len;
597 MFREE(m, m0); 597 MFREE(m, m0);
598 m = m0; 598 m = m0;
599 } 599 }
600 } 600 }
601 601
602 /* 602 /*
603 * Init transmit length registers, and set transmit start flag. 603 * Init transmit length registers, and set transmit start flag.
604 */ 604 */
605 len = total; 605 len = total;
606 if (len < ETHER_MIN_LEN) 606 if (len < ETHER_MIN_LEN)
607 len = ETHER_MIN_LEN; 607 len = ETHER_MIN_LEN;
608#error broken here ! need to set to 0 the pad space in buffer ! 608#error broken here ! need to set to 0 the pad space in buffer !
609 outb(hpc + ds_cmd, DSCM_NODMA | DSCM_PG0 | DSCM_START); 609 outb(hpc + ds_cmd, DSCM_NODMA | DSCM_PG0 | DSCM_START);
610 outb(hpc + ds0_tbcr0, len & 0xff); 610 outb(hpc + ds0_tbcr0, len & 0xff);
611 outb(hpc + ds0_tbcr1, (len >> 8) & 0xff); 611 outb(hpc + ds0_tbcr1, (len >> 8) & 0xff);
612 outb(hpc + ds0_tpsr, ns->ns_txstart); 612 outb(hpc + ds0_tpsr, ns->ns_txstart);
613 outb(hpc + ds_cmd, DSCM_TRANS | DSCM_NODMA | DSCM_PG0 | DSCM_START); 613 outb(hpc + ds_cmd, DSCM_TRANS | DSCM_NODMA | DSCM_PG0 | DSCM_START);
614 614
615#ifdef HP_DEBUG 615#ifdef HP_DEBUG
616 printf("hpstart: done\n", hpc); 616 printf("hpstart: done\n", hpc);
617#endif 617#endif
618} 618}
619/* 619/*
620 * Controller interrupt. 620 * Controller interrupt.
621 */ 621 */
622hpintr(unit) 622hpintr(unit)
623{ 623{
624 struct hp_softc *ns = &hp_softc[unit]; 624 struct hp_softc *ns = &hp_softc[unit];
625 u_char cmd, isr; 625 u_char cmd, isr;
626 int hpc = ns->ns_port; 626 int hpc = ns->ns_port;
627 u_char err; 627 u_char err;
628 628
629 /* Save cmd, clear interrupt */ 629 /* Save cmd, clear interrupt */
630 cmd = inb(hpc + ds_cmd); 630 cmd = inb(hpc + ds_cmd);
631loop: 631loop:
632 isr = inb(hpc + ds0_isr); 632 isr = inb(hpc + ds0_isr);
633 outb(hpc + ds_cmd, DSCM_NODMA | DSCM_PG0 | DSCM_START); 633 outb(hpc + ds_cmd, DSCM_NODMA | DSCM_PG0 | DSCM_START);
634 outb(hpc + ds0_isr, isr); 634 outb(hpc + ds0_isr, isr);
635 635
636 /* Receiver error */ 636 /* Receiver error */
637 if (isr & DSIS_RXE) { 637 if (isr & DSIS_RXE) {
638 /* need to read these registers to clear status */ 638 /* need to read these registers to clear status */
639 err = inb(hpc + ds0_rsr); 639 err = inb(hpc + ds0_rsr);
640 (void) inb(hpc + 0xD); 640 (void) inb(hpc + 0xD);
641 (void) inb(hpc + 0xE); 641 (void) inb(hpc + 0xE);
642 (void) inb(hpc + 0xF); 642 (void) inb(hpc + 0xF);
643 ns->ns_if.if_ierrors++; 643 ns->ns_if.if_ierrors++;
644#ifdef HP_LOG_ERRORS 644#ifdef HP_LOG_ERRORS
645 isr |= DSIS_RX; 645 isr |= DSIS_RX;
646#endif 646#endif
647 } 647 }
648 /* We received something */ 648 /* We received something */
649 if (isr & DSIS_RX) { 649 if (isr & DSIS_RX) {
650 u_char bnry; 650 u_char bnry;
651 u_char curr; 651 u_char curr;
652 u_short addr; 652 u_short addr;
653 int len; 653 int len;
654 int i; 654 int i;
655 unsigned char c; 655 unsigned char c;
656 656
657 while (1) { 657 while (1) {
658 outb(hpc + ds_cmd, DSCM_START | DSCM_NODMA | DSCM_PG0); 658 outb(hpc + ds_cmd, DSCM_START | DSCM_NODMA | DSCM_PG0);
659 bnry = inb(hpc + ds0_bnry); 659 bnry = inb(hpc + ds0_bnry);
660 outb(hpc + ds_cmd, DSCM_START | DSCM_NODMA | DSCM_PG1); 660 outb(hpc + ds_cmd, DSCM_START | DSCM_NODMA | DSCM_PG1);
661 curr = inb(hpc + ds1_curr); 661 curr = inb(hpc + ds1_curr);
662 662
663#ifdef HP_DEBUG 663#ifdef HP_DEBUG
664 printf("hpintr: receive isr=0x%02x bnry=0x%02x curr=0x%02x\n", 664 printf("hpintr: receive isr=0x%02x bnry=0x%02x curr=0x%02x\n",
665 isr, bnry, curr); 665 isr, bnry, curr);
666#endif 666#endif
667 667
668 if (++bnry >= ns->ns_rxend) 668 if (++bnry >= ns->ns_rxend)
669 bnry = ns->ns_rxstart; 669 bnry = ns->ns_rxstart;
670 670
671 /* if ring empty, done! */ 671 /* if ring empty, done! */
672 if (bnry == curr) 672 if (bnry == curr)
673 break; 673 break;
674 674
675 addr = bnry * DS_PGSIZE; 675 addr = bnry * DS_PGSIZE;
676 676
677 outb(hpc + hp_option, inb(hpc + hp_option) | HP_DATA); 677 outb(hpc + hp_option, inb(hpc + hp_option) | HP_DATA);
678 678
679#if 0 679#if 0
680 /* send packet with auto packet release */ 680 /* send packet with auto packet release */
681 outb(hpc + ds_cmd, DSCM_START | DSCM_NODMA | DSCM_PG0); 681 outb(hpc + ds_cmd, DSCM_START | DSCM_NODMA | DSCM_PG0);
682 outb(hpc + ds0_rbcr1, 0x0f); 682 outb(hpc + ds0_rbcr1, 0x0f);
683 outb(hpc + ds0_dcr, ns->ns_mode | DSDC_AR); 683 outb(hpc + ds0_dcr, ns->ns_mode | DSDC_AR);
684 outb(hpc + ds_cmd, DSCM_SENDP | DSCM_PG0 | DSCM_START); 684 outb(hpc + ds_cmd, DSCM_SENDP | DSCM_PG0 | DSCM_START);
685#endif 685#endif
686 686
687 /* get length */ 687 /* get length */
688 hpfetch(ns, (void *) & ns->ns_ph, addr, sizeof ns->ns_ph); 688 hpfetch(ns, (void *) & ns->ns_ph, addr, sizeof ns->ns_ph);
689 addr += sizeof ns->ns_ph; 689 addr += sizeof ns->ns_ph;
690 690
691#ifdef HP_DEBUG 691#ifdef HP_DEBUG
692 printf("hpintr: sendp packet hdr: %x %x %x %x\n", 692 printf("hpintr: sendp packet hdr: %x %x %x %x\n",
693 ns->ns_ph.pr_status, 693 ns->ns_ph.pr_status,
694 ns->ns_ph.pr_nxtpg, 694 ns->ns_ph.pr_nxtpg,
695 ns->ns_ph.pr_sz0, 695 ns->ns_ph.pr_sz0,
696 ns->ns_ph.pr_sz1); 696 ns->ns_ph.pr_sz1);
697#endif 697#endif
698 698
699#ifdef HP_LOG_ERRORS 699#ifdef HP_LOG_ERRORS
700 if (ns->ns_ph.pr_status & (DSRS_CRC | DSRS_FO | DSRS_DFR)) { 700 if (ns->ns_ph.pr_status & (DSRS_CRC | DSRS_FO | DSRS_DFR)) {
701 /* Get packet header */ 701 /* Get packet header */
702 if (len > 14) 702 if (len > 14)
703 len = 14; 703 len = 14;
704 hpfetch(ns, (void *) (ns->ns_pb), addr, len); 704 hpfetch(ns, (void *) (ns->ns_pb), addr, len);
705 705
706 /* move boundary up */ 706 /* move boundary up */
707 bnry = ns->ns_ph.pr_nxtpg; 707 bnry = ns->ns_ph.pr_nxtpg;
708 if (--bnry < ns->ns_rxstart) 708 if (--bnry < ns->ns_rxstart)
709 bnry = ns->ns_rxend - 1; 709 bnry = ns->ns_rxend - 1;
710 outb(hpc + ds_cmd, DSCM_START | DSCM_NODMA | DSCM_PG0); 710 outb(hpc + ds_cmd, DSCM_START | DSCM_NODMA | DSCM_PG0);
711 outb(hpc + ds0_bnry, bnry); 711 outb(hpc + ds0_bnry, bnry);
712 712
713 printf("hp%d: receive error status=0x%02x\n", unit, 713 printf("hp%d: receive error status=0x%02x\n", unit,
714 ns->ns_ph.pr_status); 714 ns->ns_ph.pr_status);
715 printf("hp%d: packet header:", unit); 715 printf("hp%d: packet header:", unit);
716 { 716 {
717 int n; 717 int n;
718 for (n = 0; n < len; n++) 718 for (n = 0; n < len; n++)
719 printf(" %02x", ns->ns_pb[n]); 719 printf(" %02x", ns->ns_pb[n]);
720 } 720 }
721 printf("\n"); 721 printf("\n");
722 722
723 continue; 723 continue;
724 } 724 }
725#endif 725#endif
726 726
727 ns->ns_if.if_ipackets++; 727 ns->ns_if.if_ipackets++;
728 len = ns->ns_ph.pr_sz0 + (ns->ns_ph.pr_sz1 << 8); 728 len = ns->ns_ph.pr_sz0 + (ns->ns_ph.pr_sz1 << 8);
729 if (len < ETHER_MIN_LEN || len > ETHER_MAX_LEN) { 729 if (len < ETHER_MIN_LEN || len > ETHER_MAX_LEN) {
730 printf("hpintr: bnry %x curr %x\n", bnry, curr); 730 printf("hpintr: bnry %x curr %x\n", bnry, curr);
731 printf("hpintr: packet hdr: %x %x %x %x\n", 731 printf("hpintr: packet hdr: %x %x %x %x\n",
732 ns->ns_ph.pr_status, 732 ns->ns_ph.pr_status,
733 ns->ns_ph.pr_nxtpg, 733 ns->ns_ph.pr_nxtpg,
734 ns->ns_ph.pr_sz0, 734 ns->ns_ph.pr_sz0,
735 ns->ns_ph.pr_sz1); 735 ns->ns_ph.pr_sz1);
736 printf("isr = 0x%x reg_isr=0x%x\n", 736 printf("isr = 0x%x reg_isr=0x%x\n",
737 isr, inb(hpc + ds0_isr)); 737 isr, inb(hpc + ds0_isr));
738 outb(hpc + ds_cmd, DSCM_START | DSCM_NODMA | DSCM_PG0); 738 outb(hpc + ds_cmd, DSCM_START | DSCM_NODMA | DSCM_PG0);
739 bnry = inb(hpc + ds0_bnry); 739 bnry = inb(hpc + ds0_bnry);
740 outb(hpc + ds_cmd, DSCM_START | DSCM_NODMA | DSCM_PG1); 740 outb(hpc + ds_cmd, DSCM_START | DSCM_NODMA | DSCM_PG1);
741 curr = inb(hpc + ds1_curr); 741 curr = inb(hpc + ds1_curr);
742 printf("hpintr: new bnry %x curr %x\n", bnry, curr); 742 printf("hpintr: new bnry %x curr %x\n", bnry, curr);
743 printf("hpintr: bad len %d\n-hanging-\n", 743 printf("hpintr: bad len %d\n-hanging-\n",
744 len); 744 len);
745 while (1); 745 while (1);
746 } 746 }
747 /* read packet */ 747 /* read packet */
748 hpfetch(ns, (void *) (ns->ns_pb), addr, len); 748 hpfetch(ns, (void *) (ns->ns_pb), addr, len);
749 749
750 /* move boundary up */ 750 /* move boundary up */
751 bnry = ns->ns_ph.pr_nxtpg; 751 bnry = ns->ns_ph.pr_nxtpg;
752 if (--bnry < ns->ns_rxstart) 752 if (--bnry < ns->ns_rxstart)
753 bnry = ns->ns_rxend - 1; 753 bnry = ns->ns_rxend - 1;
754 outb(hpc + ds_cmd, DSCM_START | DSCM_NODMA | DSCM_PG0); 754 outb(hpc + ds_cmd, DSCM_START | DSCM_NODMA | DSCM_PG0);
755 outb(hpc + ds0_bnry, bnry); 755 outb(hpc + ds0_bnry, bnry);
756 756
757#ifdef HP_DEBUG 757#ifdef HP_DEBUG
758 printf("hpintr: receive done bnry=0x%02x\n", bnry); 758 printf("hpintr: receive done bnry=0x%02x\n", bnry);
759#endif 759#endif
760 760
761 outb(hpc + hp_option, inb(hpc + hp_option) & ~HP_DATA); 761 outb(hpc + hp_option, inb(hpc + hp_option) & ~HP_DATA);
762 762
763 /* adjust for ether header and checksum */ 763 /* adjust for ether header and checksum */
764 len -= sizeof(struct ether_header) + sizeof(long); 764 len -= sizeof(struct ether_header) + sizeof(long);
765 765
766 /* process packet */ 766 /* process packet */
767 hpread(ns, (void *) (ns->ns_pb), len); 767 hpread(ns, (void *) (ns->ns_pb), len);
768 } 768 }
769 } 769 }
770 /* Transmit error */ 770 /* Transmit error */
771 if (isr & DSIS_TXE) { 771 if (isr & DSIS_TXE) {
772 ns->ns_flags &= ~DSF_LOCK; 772 ns->ns_flags &= ~DSF_LOCK;
773 /* Need to read these registers to clear status */ 773 /* Need to read these registers to clear status */
774 ns->ns_if.if_collisions += inb(hpc + ds0_tbcr0); 774 ns->ns_if.if_collisions += inb(hpc + ds0_tbcr0);
775 ns->ns_if.if_oerrors++; 775 ns->ns_if.if_oerrors++;
776 } 776 }
777 /* Packet Transmitted */ 777 /* Packet Transmitted */
778 if (isr & DSIS_TX) { 778 if (isr & DSIS_TX) {
779 ns->ns_flags &= ~DSF_LOCK; 779 ns->ns_flags &= ~DSF_LOCK;
780 ++ns->ns_if.if_opackets; 780 ++ns->ns_if.if_opackets;
781 ns->ns_if.if_collisions += inb(hpc + ds0_tbcr0); 781 ns->ns_if.if_collisions += inb(hpc + ds0_tbcr0);
782 } 782 }
783 /* Receiver ovverun? */ 783 /* Receiver ovverun? */
784 if (isr & DSIS_ROVRN) { 784 if (isr & DSIS_ROVRN) {
785 log(LOG_ERR, "hp%d: error: isr %x\n", ns - hp_softc, isr 785 log(LOG_ERR, "hp%d: error: isr %x\n", ns - hp_softc, isr
786 /* , DSIS_BITS */ ); 786 /* , DSIS_BITS */ );
787 outb(hpc + ds0_rbcr0, 0); 787 outb(hpc + ds0_rbcr0, 0);
788 outb(hpc + ds0_rbcr1, 0); 788 outb(hpc + ds0_rbcr1, 0);
789 outb(hpc + ds0_tcr, DSTC_LB0); 789 outb(hpc + ds0_tcr, DSTC_LB0);
790 outb(hpc + ds0_rcr, DSRC_MON); 790 outb(hpc + ds0_rcr, DSRC_MON);
791 outb(hpc + ds_cmd, DSCM_START | DSCM_NODMA); 791 outb(hpc + ds_cmd, DSCM_START | DSCM_NODMA);
792 outb(hpc + ds0_rcr, ns->ns_rcr); 792 outb(hpc + ds0_rcr, ns->ns_rcr);
793 outb(hpc + ds0_tcr, 0); 793 outb(hpc + ds0_tcr, 0);
794 } 794 }
795 /* Any more to send? */ 795 /* Any more to send? */
796 outb(hpc + ds_cmd, DSCM_NODMA | DSCM_PG0 | DSCM_START); 796 outb(hpc + ds_cmd, DSCM_NODMA | DSCM_PG0 | DSCM_START);
797 hpstart(&ns->ns_if); 797 hpstart(&ns->ns_if);
798 outb(hpc + ds_cmd, cmd); 798 outb(hpc + ds_cmd, cmd);
799 outb(hpc + ds0_imr, 0xff); 799 outb(hpc + ds0_imr, 0xff);
800 800
801#if NRND > 0 801#if NRND > 0
802 if (irs) 802 if (irs)
803 rnd_add_uint32(&sc->rnd_source, isr); 803 rnd_add_uint32(&sc->rnd_source, isr);
804#endif 804#endif
805 805
806 /* Still more to do? */ 806 /* Still more to do? */
807 isr = inb(hpc + ds0_isr); 807 isr = inb(hpc + ds0_isr);
808 if (isr) 808 if (isr)
809 goto loop; 809 goto loop;
810} 810}
811/* 811/*
812 * Pass a packet to the higher levels. 812 * Pass a packet to the higher levels.
813 * We deal with the trailer protocol here. 813 * We deal with the trailer protocol here.
814 */ 814 */
815hpread(struct hp_softc *ns, char *buf, int len) 815hpread(struct hp_softc *ns, char *buf, int len)
816{ 816{
817 struct ether_header *eh; 817 struct ether_header *eh;
818 struct mbuf *m; 818 struct mbuf *m;
819 int off, resid; 819 int off, resid;
820 struct ifqueue *inq; 820 struct ifqueue *inq;
821 u_short etype; 821 u_short etype;
822 822
823 /* 823 /*
824 * Deal with trailer protocol: if type is trailer type 824 * Deal with trailer protocol: if type is trailer type
825 * get true type from first 16-bit word past data. 825 * get true type from first 16-bit word past data.
826 * Remember that type was trailer by setting off. 826 * Remember that type was trailer by setting off.
827 */ 827 */
828 eh = (struct ether_header *) buf; 828 eh = (struct ether_header *) buf;
829 etype = ntohs((u_short) eh->ether_type); 829 etype = ntohs((u_short) eh->ether_type);
830#define hpdataaddr(eh, off, type) ((type)(((void *)((eh)+1)+(off)))) 830#define hpdataaddr(eh, off, type) ((type)(((void *)((eh)+1)+(off))))
831 if (etype >= ETHERTYPE_TRAIL && 831 if (etype >= ETHERTYPE_TRAIL &&
832 etype < ETHERTYPE_TRAIL + ETHERTYPE_NTRAILER) { 832 etype < ETHERTYPE_TRAIL + ETHERTYPE_NTRAILER) {
833 off = (etype - ETHERTYPE_TRAIL) * 512; 833 off = (etype - ETHERTYPE_TRAIL) * 512;
834 if (off >= ETHERMTU) 834 if (off >= ETHERMTU)
835 return; /* sanity */ 835 return; /* sanity */
836 eh->ether_type = *hpdataaddr(eh, off, u_short *); 836 eh->ether_type = *hpdataaddr(eh, off, u_short *);
837 resid = ntohs(*(hpdataaddr(eh, off + 2, u_short *))); 837 resid = ntohs(*(hpdataaddr(eh, off + 2, u_short *)));
838 if (off + resid > len) 838 if (off + resid > len)
839 return; /* sanity */ 839 return; /* sanity */
840 len = off + resid; 840 len = off + resid;
841 } else 841 } else
842 off = 0; 842 off = 0;
843 843
844 if (len == 0) 844 if (len == 0)
845 return; 845 return;
846 846
847#if NBPFILTER > 0 847#if NBPFILTER > 0
848 if (ns->ns_bpf) 848 if (ns->ns_bpf)
849 bpf_tap(ns->ns_bpf, buf, len + sizeof(struct ether_header)); 849 bpf_tap(ns->ns_bpf, buf, len + sizeof(struct ether_header));
850#endif 850#endif
851 851
852 if ((ns->ns_if.if_flags & IFF_PROMISC) 852 if ((ns->ns_if.if_flags & IFF_PROMISC)
853 && memcmp(eh->ether_dhost, ns->ns_addrp, 853 && memcmp(eh->ether_dhost, ns->ns_addrp,
854 sizeof(eh->ether_dhost)) != 0 854 sizeof(eh->ether_dhost)) != 0
855 && memcmp(eh->ether_dhost, etherbroadcastaddr, 855 && memcmp(eh->ether_dhost, etherbroadcastaddr,
856 sizeof(eh->ether_dhost)) != 0) 856 sizeof(eh->ether_dhost)) != 0)
857 return; 857 return;
858 858
859 /* 859 /*
860 * Pull packet off interface. Off is nonzero if packet 860 * Pull packet off interface. Off is nonzero if packet
861 * has trailing header; hpget will then force this header 861 * has trailing header; hpget will then force this header
862 * information to be at the front, but we still have to drop 862 * information to be at the front, but we still have to drop
863 * the type and length which are at the front of any trailer data. 863 * the type and length which are at the front of any trailer data.
864 */ 864 */
865 m = hpget(buf, len, off, &ns->ns_if); 865 m = hpget(buf, len, off, &ns->ns_if);
866 if (m == 0) 866 if (m == 0)
867 return; 867 return;
868 868
869 ether_input(&ns->ns_if, eh, m); 869 ether_input(&ns->ns_if, eh, m);
870} 870}
871/* 871/*
872 * Supporting routines 872 * Supporting routines
873 */ 873 */
874 874
875/* 875/*
876 * Pull read data off a interface. 876 * Pull read data off a interface.
877 * Len is length of data, with local net header stripped. 877 * Len is length of data, with local net header stripped.
878 * Off is non-zero if a trailer protocol was used, and 878 * Off is non-zero if a trailer protocol was used, and
879 * gives the offset of the trailer information. 879 * gives the offset of the trailer information.
880 * We copy the trailer information and then all the normal 880 * We copy the trailer information and then all the normal
881 * data into mbufs. When full cluster sized units are present 881 * data into mbufs. When full cluster sized units are present
882 * we copy into clusters. 882 * we copy into clusters.
883 */ 883 */
884struct mbuf * 884struct mbuf *
885hpget(void *buf, int totlen, int off0, struct ifnet *ifp) 885hpget(void *buf, int totlen, int off0, struct ifnet *ifp)
886{ 886{
887 struct mbuf *top, **mp, *m, *p; 887 struct mbuf *top, **mp, *m, *p;
888 int off = off0, len; 888 int off = off0, len;
889 void *cp = buf; 889 void *cp = buf;
890 char *epkt; 890 char *epkt;
891 891
892 buf += sizeof(struct ether_header); 892 buf += sizeof(struct ether_header);
893 cp = buf; 893 cp = buf;
894 epkt = cp + totlen; 894 epkt = cp + totlen;
895 895
896 896
897 if (off) { 897 if (off) {
898 cp += off + 2 * sizeof(u_short); 898 cp += off + 2 * sizeof(u_short);
899 totlen -= 2 * sizeof(u_short); 899 totlen -= 2 * sizeof(u_short);
900 } 900 }
901 MGETHDR(m, M_DONTWAIT, MT_DATA); 901 MGETHDR(m, M_DONTWAIT, MT_DATA);
902 if (m == 0) 902 if (m == 0)
903 return (0); 903 return (0);
904 m->m_pkthdr.rcvif = ifp; 904 m->m_pkthdr.rcvif = ifp;
905 m->m_pkthdr.len = totlen; 905 m->m_pkthdr.len = totlen;
906 m->m_len = MHLEN; 906 m->m_len = MHLEN;
907 907
908 top = 0; 908 top = 0;
909 mp = &top; 909 mp = &top;
910 while (totlen > 0) { 910 while (totlen > 0) {
911 if (top) { 911 if (top) {
912 MGET(m, M_DONTWAIT, MT_DATA); 912 MGET(m, M_DONTWAIT, MT_DATA);
913 if (m == 0) { 913 if (m == 0) {
914 m_freem(top); 914 m_freem(top);
915 return (0); 915 return (0);
916 } 916 }
917 m->m_len = MLEN; 917 m->m_len = MLEN;
918 } 918 }
919 len = min(totlen, epkt - cp); 919 len = min(totlen, epkt - cp);
920 if (len >= MINCLSIZE) { 920 if (len >= MINCLSIZE) {
921 MCLGET(m, M_DONTWAIT); 921 MCLGET(m, M_DONTWAIT);
922 if (m->m_flags & M_EXT) 922 if (m->m_flags & M_EXT)
923 m->m_len = len = min(len, MCLBYTES); 923 m->m_len = len = min(len, MCLBYTES);
924 else 924 else
925 len = m->m_len; 925 len = m->m_len;
926 } else { 926 } else {
927 /* 927 /*
928 * Place initial small packet/header at end of mbuf. 928 * Place initial small packet/header at end of mbuf.
929 */ 929 */
930 if (len < m->m_len) { 930 if (len < m->m_len) {
931 if (top == 0 && len + max_linkhdr <= m->m_len) 931 if (top == 0 && len + max_linkhdr <= m->m_len)
932 m->m_data += max_linkhdr; 932 m->m_data += max_linkhdr;
933 m->m_len = len; 933 m->m_len = len;
934 } else 934 } else
935 len = m->m_len; 935 len = m->m_len;
936 } 936 }
937 memcpy(mtod(m, void *), cp, (unsigned) len); 937 memcpy(mtod(m, void *), cp, (unsigned) len);
938 cp += len; 938 cp += len;
939 *mp = m; 939 *mp = m;
940 mp = &m->m_next; 940 mp = &m->m_next;
941 totlen -= len; 941 totlen -= len;
942 if (cp == epkt) 942 if (cp == epkt)
943 cp = buf; 943 cp = buf;
944 } 944 }
945 return (top); 945 return (top);
946} 946}
947/* 947/*
948 * Process an ioctl request. 948 * Process an ioctl request.
949 */ 949 */
950hpioctl(struct ifnet *ifp, u_long cmd, void *data) 950hpioctl(struct ifnet *ifp, u_long cmd, void *data)
951{ 951{
952 struct ifaddr *ifa = (struct ifaddr *) data; 952 struct ifaddr *ifa = (struct ifaddr *) data;
953 struct hp_softc *ns = &hp_softc[ifp->if_unit]; 953 struct hp_softc *ns = &hp_softc[ifp->if_unit];
954 struct ifreq *ifr = (struct ifreq *) data; 954 struct ifreq *ifr = (struct ifreq *) data;
955 int s = splnet(), error = 0; 955 int s = splnet(), error = 0;
956 956
957 957
958 switch (cmd) { 958 switch (cmd) {
959 959
960 case SIOCINITIFADDR: 960 case SIOCINITIFADDR:
961 ifp->if_flags |= IFF_UP; 961 ifp->if_flags |= IFF_UP;
962 962
963 hpinit(ifp->if_unit); 963 hpinit(ifp->if_unit);
964 switch (ifa->ifa_addr->sa_family) { 964 switch (ifa->ifa_addr->sa_family) {
965#ifdef INET 965#ifdef INET
966 case AF_INET: 966 case AF_INET:
967 ((struct arpcom *) ifp)->ac_ipaddr = 967 ((struct arpcom *) ifp)->ac_ipaddr =
968 IA_SIN(ifa)->sin_addr; 968 IA_SIN(ifa)->sin_addr;
969 arpwhohas((struct arpcom *) ifp, &IA_SIN(ifa)->sin_addr); 969 arpwhohas((struct arpcom *) ifp, &IA_SIN(ifa)->sin_addr);
970 break; 970 break;
971#endif 971#endif
972 default: 972 default:
973 break; 973 break;
974 } 974 }
975 break; 975 break;
976 976
977 case SIOCSIFFLAGS: 977 case SIOCSIFFLAGS:
978 if ((error = ifioctl_common(ifp, cmd, data)) != 0) 978 if ((error = ifioctl_common(ifp, cmd, data)) != 0)
979 break; 979 break;
980#ifdef HP_DEBUG 980#ifdef HP_DEBUG
981 printf("hp: setting flags, up: %s, running: %s\n", 981 printf("hp: setting flags, up: %s, running: %s\n",
982 ifp->if_flags & IFF_UP ? "yes" : "no", 982 ifp->if_flags & IFF_UP ? "yes" : "no",
983 ifp->if_flags & IFF_RUNNING ? "yes" : "no"); 983 ifp->if_flags & IFF_RUNNING ? "yes" : "no");
984#endif 984#endif
985 /* XXX re-use ether_ioctl() */ 985 /* XXX re-use ether_ioctl() */
986 switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) { 986 switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) {
987 case IFF_RUNNING: 987 case IFF_RUNNING:
988 ifp->if_flags &= ~IFF_RUNNING; 988 ifp->if_flags &= ~IFF_RUNNING;
989 outb(ns->ns_port + ds_cmd, DSCM_STOP | DSCM_NODMA); 989 outb(ns->ns_port + ds_cmd, DSCM_STOP | DSCM_NODMA);
990 break; 990 break;
991 case IFF_UP: 991 case IFF_UP:
992 hpinit(ifp->if_unit); 992 hpinit(ifp->if_unit);
993 break; 993 break;
994 default: 994 default:
995 break; 995 break;
996 } 996 }
997 break; 997 break;
998 998
999#ifdef notdef 999#ifdef notdef
1000 case SIOCGHWADDR: 1000 case SIOCGHWADDR:
1001 memcpy((void *) & ifr->ifr_data, (void *) ns->ns_addrp, 1001 memcpy((void *) & ifr->ifr_data, (void *) ns->ns_addrp,
1002 sizeof(ns->ns_addrp)); 1002 sizeof(ns->ns_addrp));
1003 break; 1003 break;
1004#endif 1004#endif
1005 1005
1006 default: 1006 default:
1007 error = ether_ioctl(ifp, cmd, data); 1007 error = ether_ioctl(ifp, cmd, data);
1008 } 1008 }
1009 splx(s); 1009 splx(s);
1010 return (error); 1010 return (error);
1011} 1011}
1012#endif 1012#endif