1 /* $NetBSD: sii_ds.c,v 1.3 2007/03/04 06:00:33 christos 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.3 2007/03/04 06:00:33 christos 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 __P((u_short *src, /* NB: must be short aligned */ 46 volatile u_short *dst, int length)); 47 static void kn230_copyfrombuf __P((volatile u_short *src, char *dst, 48 int length)); 49 50 static void kn01_copytobuf __P((u_short *src, /* NB: must be short aligned */ 51 volatile u_short *dst, int length)); 52 static void kn01_copyfrombuf __P((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 __P((struct device* parent, struct cfdata *match, 59 void *aux)); 60 static void sii_ds_attach __P((struct device *parent, struct device *self, 61 void *aux)); 62 63 CFATTACH_DECL(sii_ds, sizeof(struct siisoftc), 64 sii_ds_match, sii_ds_attach, NULL, NULL); 65 66 /* define a safe address in the SCSI buffer for doing status & message DMA */ 67 #define SII_BUF_ADDR (MIPS_PHYS_TO_KSEG1(KN01_SYS_SII_B_START) \ 68 + SII_MAX_DMA_XFER_LENGTH * 14) 69 70 /* 71 * Match driver on Decstation (2100, 3100, 5100) based on name and probe. 72 */ 73 static int 74 sii_ds_match(parent, match, aux) 75 struct device *parent; 76 struct cfdata *match; 77 void *aux; 78 { 79 struct ibus_attach_args *ia = aux; 80 void *siiaddr; 81 82 if (strcmp(ia->ia_name, "sii") != 0) 83 return (0); 84 siiaddr = (void *)ia->ia_addr; 85 if (badaddr(siiaddr, 4)) 86 return (0); 87 return (1); 88 } 89 90 static void 91 sii_ds_attach(parent, self, aux) 92 struct device *parent; 93 struct device *self; 94 void *aux; 95 { 96 struct ibus_attach_args *ia = aux; 97 struct siisoftc *sc = (struct siisoftc *) self; 98 99 sc->sc_regs = (SIIRegs *)MIPS_PHYS_TO_KSEG1(ia->ia_addr); 100 101 /* set up scsi buffer. XXX Why statically allocated? */ 102 sc->sc_buf = (void*)(MIPS_PHYS_TO_KSEG1(KN01_SYS_SII_B_START)); 103 104 if (systype == DS_PMAX) { 105 #if 0 106 sc->sii_copytobuf = CopyToBuffer; 107 sc->sii_copyfrombuf = CopyFromBuffer; 108 #else 109 sc->sii_copytobuf = kn01_copytobuf; 110 sc->sii_copyfrombuf = kn01_copyfrombuf; 111 #endif 112 } else { 113 sc->sii_copytobuf = kn230_copytobuf; 114 sc->sii_copyfrombuf = kn230_copyfrombuf; 115 } 116 117 /* Do the common parts of attachment. */ 118 sc->sc_adapter.adapt_request = sii_scsi_request; 119 sc->sc_adapter.adapt_minphys = minphys; 120 siiattach(sc); 121 122 /* tie pseudo-slot to device */ 123 ibus_intr_establish(parent, (void*)ia->ia_cookie, IPL_BIO, siiintr, sc); 124 } 125 126 127 /* 128 * Padded DMA copy functions 129 * 130 */ 131 132 /* 133 * XXX assumes src is always 32-bit aligned. 134 * currently safe on sii driver, but API and casts should be changed. 135 */ 136 static void 137 kn230_copytobuf(src, dst, len) 138 u_short *src; 139 volatile u_short *dst; 140 int len; 141 { 142 u_int *wsrc = (u_int *)src; 143 volatile u_int *wdst = (volatile u_int *)dst; 144 int i, n; 145 146 #if defined(DIAGNOSTIC) || defined(DEBUG) 147 if ((u_int)(src) & 0x3) { 148 printf("kn230: copytobuf, src %p misaligned\n", src); 149 } 150 if ((u_int)(dst) & 0x3) { 151 printf("kn230: copytobuf, dst %p misaligned\n", dst); 152 } 153 #endif 154 155 /* DMA buffer is allocated in 32-bit words, so just copy words. */ 156 n = len / 4; 157 if (len & 0x3) 158 n++; 159 for (i = 0; i < n; i++) { 160 *wdst = *wsrc; 161 wsrc++; 162 wdst+= 2; 163 } 164 165 wbflush(); /* XXX not necessary? */ 166 } 167 168 169 /* 170 * XXX assumes dst is always 32-bit aligned. 171 * currently safe on sii driver, but API and casts should be changed. 172 */ 173 static void 174 kn230_copyfrombuf(src, dst, len) 175 volatile u_short *src; 176 char *dst; /* XXX assume 32-bit aligned? */ 177 int len; 178 { 179 volatile u_int *wsrc = (volatile u_int *)src; 180 u_int *wdst = (u_int *)dst; 181 int i, n; 182 183 #if defined(DIAGNOSTIC) || defined(DEBUG) 184 if ((u_int)(src) & 0x3) { 185 printf("kn230: copyfrombuf, src %p misaligned\n", src); 186 } 187 if ((u_int)(dst) & 0x3) { 188 printf("kn230: copyfrombuf, dst %p misaligned\n", dst); 189 } 190 #endif 191 192 n = len / 4; 193 194 for (i = 0; i < n; i++) { 195 *wdst = *wsrc; 196 wsrc += 2; 197 wdst++; 198 } 199 200 if (len & 0x3) { 201 u_int lastword = *wsrc; 202 203 if (len & 0x2) 204 *((u_short*)(wdst)) = (u_short) (lastword); 205 206 if (len & 0x1) 207 ((u_char*)(wdst))[2] = (u_char) (lastword >> 16); 208 } 209 210 wbflush(); /* XXX not necessary? */ 211 } 212 213 214 static void 215 kn01_copytobuf(src, dst, len) 216 u_short *src; 217 volatile u_short *dst; 218 int len; 219 { 220 #if defined(DIAGNOSTIC) || defined(DEBUG) 221 if ((u_int)(src) & 0x3) { 222 printf("kn01: copytobuf, src %p misaligned\n", src); 223 } 224 if ((u_int)(dst) & 0x3) { 225 printf("kn01: copytobuf, dst %p misaligned\n", dst); 226 } 227 #endif 228 229 CopyToBuffer(src, dst, len); 230 } 231 232 static void 233 kn01_copyfrombuf(src, dst, len) 234 volatile u_short *src; 235 char *dst; /* XXX assume 32-bit aligned? */ 236 int len; 237 { 238 #if defined(DIAGNOSTIC) || defined(DEBUG) 239 if ((u_int)(src) & 0x3) { 240 printf("kn01: copyfrombuf, src %p misaligned\n", src); 241 } 242 if ((u_int)(dst) & 0x3) { 243 printf("kn01: copyfrombuf, dst %p misaligned\n", dst); 244 } 245 246 #endif 247 CopyFromBuffer(src, dst, len); 248 249 } 250