sii_ds.c revision 1.2
1/* $NetBSD: sii_ds.c,v 1.2 2006/07/29 19:10:57 ad 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.2 2006/07/29 19:10:57 ad 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 45static void kn230_copytobuf __P((u_short *src, /* NB: must be short aligned */ 46 volatile u_short *dst, int length)); 47static void kn230_copyfrombuf __P((volatile u_short *src, char *dst, 48 int length)); 49 50static void kn01_copytobuf __P((u_short *src, /* NB: must be short aligned */ 51 volatile u_short *dst, int length)); 52static void kn01_copyfrombuf __P((volatile u_short *src, char *dst, 53 int length)); 54 55/* 56 * Autoconfig definition of driver front-end 57 */ 58static int sii_ds_match __P((struct device* parent, struct cfdata *match, 59 void *aux)); 60static void sii_ds_attach __P((struct device *parent, struct device *self, 61 void *aux)); 62 63CFATTACH_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 */ 73static int 74sii_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 90static void 91sii_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 */ 136static void 137kn230_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 */ 173static void 174kn230_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 214static void 215kn01_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 232static void 233kn01_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