xref: /netbsd-src/sys/arch/pmax/ibus/sii_ds.c (revision 1b9578b8c2c1f848eeb16dabbfd7d1f0d9fdefbd)
1 /*	$NetBSD: sii_ds.c,v 1.8 2011/06/04 01:31:23 tsutsui Exp $	*/
2 
3 /*
4  * Copyright 1996 The Board of Trustees of The Leland Stanford
5  * Junior University. All Rights Reserved.
6  *
7  * Permission to use, copy, modify, and distribute this
8  * software and its documentation for any purpose and without
9  * fee is hereby granted, provided that the above copyright
10  * notice appear in all copies.  Stanford University
11  * makes no representations about the suitability of this
12  * software for any purpose.  It is provided "as is" without
13  * express or implied warranty.
14  *
15  * this driver contributed by Jonathan Stone
16  */
17 
18 #include <sys/cdefs.h>
19 __KERNEL_RCSID(0, "$NetBSD: sii_ds.c,v 1.8 2011/06/04 01:31:23 tsutsui Exp $");
20 
21 #include "sii.h"
22 
23 #include <sys/param.h>
24 #include <sys/systm.h>
25 #include <sys/device.h>
26 #include <sys/buf.h>
27 
28 #include <machine/locore.h>
29 
30 #include <dev/scsipi/scsi_all.h>
31 #include <dev/scsipi/scsipi_all.h>
32 #include <dev/scsipi/scsiconf.h>
33 #include <dev/scsipi/scsi_message.h>
34 
35 #include <machine/bus.h>
36 #include <pmax/ibus/siireg.h>
37 #include <pmax/ibus/siivar.h>
38 
39 #include <pmax/ibus/ibusvar.h>		/* interrupt etablish */
40 
41 #include <pmax/pmax/kn01.h>		/* kn01 (ds3100) address constants */
42 #include <pmax/pmax/pmaxtype.h>
43 
44 
45 static void	kn230_copytobuf(u_short *src, 	/* NB: must be short aligned */
46 		    volatile u_short *dst, int length);
47 static void	kn230_copyfrombuf(volatile u_short *src, char *dst,
48 		    int length);
49 
50 static void	kn01_copytobuf(u_short *src, 	/* NB: must be short aligned */
51 		    volatile u_short *dst, int length);
52 static void	kn01_copyfrombuf(volatile u_short *src, char *dst,
53 		    int length);
54 
55 /*
56  * Autoconfig definition of driver front-end
57  */
58 static int	sii_ds_match(device_t, struct cfdata *, void *);
59 static void	sii_ds_attach(device_t, device_t, void *);
60 
61 CFATTACH_DECL_NEW(sii_ds, sizeof(struct siisoftc),
62     sii_ds_match, sii_ds_attach, NULL, NULL);
63 
64 /* define a safe address in the SCSI buffer for doing status & message DMA */
65 #define SII_BUF_ADDR	(MIPS_PHYS_TO_KSEG1(KN01_SYS_SII_B_START) \
66 		+ SII_MAX_DMA_XFER_LENGTH * 14)
67 
68 /*
69  * Match driver on Decstation (2100, 3100, 5100) based on name and probe.
70  */
71 static int
72 sii_ds_match(device_t parent, cfdata_t cf, void *aux)
73 {
74 	struct ibus_attach_args *ia = aux;
75 	void *siiaddr;
76 
77 	if (strcmp(ia->ia_name, "sii") != 0)
78 		return (0);
79 	siiaddr = (void *)ia->ia_addr;
80 	if (badaddr(siiaddr, 4))
81 		return (0);
82 	return (1);
83 }
84 
85 static void
86 sii_ds_attach(device_t parent, device_t self, void *aux)
87 {
88 	struct ibus_attach_args *ia = aux;
89 	struct siisoftc *sc = device_private(self);
90 
91 	sc->sc_dev = self;
92 	sc->sc_regs = (SIIRegs *)MIPS_PHYS_TO_KSEG1(ia->ia_addr);
93 
94 	/* set up scsi buffer.  XXX Why statically allocated? */
95 	sc->sc_buf = (void*)(MIPS_PHYS_TO_KSEG1(KN01_SYS_SII_B_START));
96 
97 	if (systype == DS_PMAX) {
98 #if 0
99 		sc->sii_copytobuf = CopyToBuffer;
100 		sc->sii_copyfrombuf = CopyFromBuffer;
101 #else
102 		sc->sii_copytobuf = kn01_copytobuf;
103 		sc->sii_copyfrombuf = kn01_copyfrombuf;
104 #endif
105 	} else {
106 		sc->sii_copytobuf = kn230_copytobuf;
107 		sc->sii_copyfrombuf = kn230_copyfrombuf;
108 	}
109 
110 	/* Do the common parts of attachment. */
111 	sc->sc_adapter.adapt_request = sii_scsi_request;
112 	sc->sc_adapter.adapt_minphys = minphys;
113 	siiattach(sc);
114 
115 	/* tie pseudo-slot to device */
116 	ibus_intr_establish(parent, (void*)ia->ia_cookie, IPL_BIO, siiintr, sc);
117 }
118 
119 
120 /*
121  * Padded DMA copy functions
122  *
123  */
124 
125 /*
126  * XXX assumes src is always 32-bit aligned.
127  * currently safe on sii driver, but API and casts should be changed.
128  */
129 static void
130 kn230_copytobuf(u_short *src, volatile u_short *dst, int len)
131 {
132 	u_int *wsrc = (u_int *)src;
133 	volatile u_int *wdst = (volatile u_int *)dst;
134 	int i, n;
135 
136 #if defined(DIAGNOSTIC) || defined(DEBUG)
137 	if ((u_int)(src) & 0x3) {
138 		printf("kn230: copytobuf, src %p misaligned\n",  src);
139 	}
140 	if ((u_int)(dst) & 0x3) {
141 		printf("kn230: copytobuf, dst %p misaligned\n",  dst);
142 	}
143 #endif
144 
145 	/* DMA buffer is allocated in 32-bit words, so just copy words. */
146 	n = len / 4;
147 	if (len & 0x3)
148 		n++;
149 	for (i = 0; i < n; i++) {
150 		*wdst = *wsrc;
151 		wsrc++;
152 		wdst+= 2;
153 	}
154 
155 	wbflush();		/* XXX not necessary? */
156 }
157 
158 
159 /*
160  * XXX assumes dst is always 32-bit aligned.
161  * currently safe on sii driver, but API and casts should be changed.
162  */
163 static void
164 kn230_copyfrombuf(volatile u_short *src, char *dst, int len)
165 	/* dst:		 XXX assume 32-bit aligned? */
166 {
167 	volatile u_int *wsrc = (volatile u_int *)src;
168 	u_int *wdst = (u_int *)dst;
169 	int i, n;
170 
171 #if defined(DIAGNOSTIC) || defined(DEBUG)
172 	if ((u_int)(src) & 0x3) {
173 		printf("kn230: copyfrombuf, src %p misaligned\n",  src);
174 	}
175 	if ((u_int)(dst) & 0x3) {
176 		printf("kn230: copyfrombuf, dst %p misaligned\n",  dst);
177 	}
178 #endif
179 
180 	n = len / 4;
181 
182 	for (i = 0; i < n; i++) {
183 		*wdst = *wsrc;
184 		wsrc += 2;
185 		wdst++;
186 	}
187 
188 	if (len & 0x3) {
189 		u_int lastword = *wsrc;
190 
191 		if (len & 0x2)
192 		    *((u_short*)(wdst)) = (u_short) (lastword);
193 
194 		if (len & 0x1)
195 		    ((u_char*)(wdst))[2] = (u_char) (lastword >> 16);
196 	}
197 
198 	wbflush();		/* XXX not necessary? */
199 }
200 
201 
202 static void
203 kn01_copytobuf(u_short *src, volatile u_short *dst, int len)
204 {
205 #if defined(DIAGNOSTIC) || defined(DEBUG)
206 	if ((u_int)(src) & 0x3) {
207 		printf("kn01: copytobuf, src %p misaligned\n",  src);
208 	}
209 	if ((u_int)(dst) & 0x3) {
210 		printf("kn01: copytobuf, dst %p misaligned\n",  dst);
211 	}
212 #endif
213 
214 	CopyToBuffer(src, dst, len);
215 }
216 
217 static void
218 kn01_copyfrombuf(volatile u_short *src, char *dst, int len)
219 	/* dst:		 XXX assume 32-bit aligned? */
220 {
221 #if defined(DIAGNOSTIC) || defined(DEBUG)
222 	if ((u_int)(src) & 0x3) {
223 		printf("kn01: copyfrombuf, src %p misaligned\n",  src);
224 	}
225 	if ((u_int)(dst) & 0x3) {
226 		printf("kn01: copyfrombuf, dst %p misaligned\n",  dst);
227 	}
228 
229 #endif
230 	CopyFromBuffer(src, dst, len);
231 
232 }
233