sii_ds.c revision 1.3
11.3Schristos/* $NetBSD: sii_ds.c,v 1.3 2007/03/04 06:00:33 christos Exp $ */ 21.2Sad 31.2Sad/* 41.2Sad * Copyright 1996 The Board of Trustees of The Leland Stanford 51.2Sad * Junior University. All Rights Reserved. 61.2Sad * 71.2Sad * Permission to use, copy, modify, and distribute this 81.2Sad * software and its documentation for any purpose and without 91.2Sad * fee is hereby granted, provided that the above copyright 101.2Sad * notice appear in all copies. Stanford University 111.2Sad * makes no representations about the suitability of this 121.2Sad * software for any purpose. It is provided "as is" without 131.2Sad * express or implied warranty. 141.2Sad * 151.2Sad * this driver contributed by Jonathan Stone 161.2Sad */ 171.2Sad 181.2Sad#include <sys/cdefs.h> 191.3Schristos__KERNEL_RCSID(0, "$NetBSD: sii_ds.c,v 1.3 2007/03/04 06:00:33 christos Exp $"); 201.2Sad 211.2Sad#include "sii.h" 221.2Sad 231.2Sad#include <sys/param.h> 241.2Sad#include <sys/systm.h> 251.2Sad#include <sys/device.h> 261.2Sad#include <sys/buf.h> 271.2Sad 281.2Sad#include <machine/locore.h> 291.2Sad 301.2Sad#include <dev/scsipi/scsi_all.h> 311.2Sad#include <dev/scsipi/scsipi_all.h> 321.2Sad#include <dev/scsipi/scsiconf.h> 331.2Sad#include <dev/scsipi/scsi_message.h> 341.2Sad 351.2Sad#include <machine/bus.h> 361.2Sad#include <pmax/ibus/siireg.h> 371.2Sad#include <pmax/ibus/siivar.h> 381.2Sad 391.2Sad#include <pmax/ibus/ibusvar.h> /* interrupt etablish */ 401.2Sad 411.2Sad#include <pmax/pmax/kn01.h> /* kn01 (ds3100) address constants */ 421.2Sad#include <pmax/pmax/pmaxtype.h> 431.2Sad 441.2Sad 451.2Sadstatic void kn230_copytobuf __P((u_short *src, /* NB: must be short aligned */ 461.2Sad volatile u_short *dst, int length)); 471.2Sadstatic void kn230_copyfrombuf __P((volatile u_short *src, char *dst, 481.2Sad int length)); 491.2Sad 501.2Sadstatic void kn01_copytobuf __P((u_short *src, /* NB: must be short aligned */ 511.2Sad volatile u_short *dst, int length)); 521.2Sadstatic void kn01_copyfrombuf __P((volatile u_short *src, char *dst, 531.2Sad int length)); 541.2Sad 551.2Sad/* 561.2Sad * Autoconfig definition of driver front-end 571.2Sad */ 581.2Sadstatic int sii_ds_match __P((struct device* parent, struct cfdata *match, 591.2Sad void *aux)); 601.2Sadstatic void sii_ds_attach __P((struct device *parent, struct device *self, 611.2Sad void *aux)); 621.2Sad 631.2SadCFATTACH_DECL(sii_ds, sizeof(struct siisoftc), 641.2Sad sii_ds_match, sii_ds_attach, NULL, NULL); 651.2Sad 661.2Sad/* define a safe address in the SCSI buffer for doing status & message DMA */ 671.2Sad#define SII_BUF_ADDR (MIPS_PHYS_TO_KSEG1(KN01_SYS_SII_B_START) \ 681.2Sad + SII_MAX_DMA_XFER_LENGTH * 14) 691.2Sad 701.2Sad/* 711.2Sad * Match driver on Decstation (2100, 3100, 5100) based on name and probe. 721.2Sad */ 731.2Sadstatic int 741.2Sadsii_ds_match(parent, match, aux) 751.2Sad struct device *parent; 761.2Sad struct cfdata *match; 771.2Sad void *aux; 781.2Sad{ 791.2Sad struct ibus_attach_args *ia = aux; 801.3Schristos void *siiaddr; 811.2Sad 821.2Sad if (strcmp(ia->ia_name, "sii") != 0) 831.2Sad return (0); 841.2Sad siiaddr = (void *)ia->ia_addr; 851.2Sad if (badaddr(siiaddr, 4)) 861.2Sad return (0); 871.2Sad return (1); 881.2Sad} 891.2Sad 901.2Sadstatic void 911.2Sadsii_ds_attach(parent, self, aux) 921.2Sad struct device *parent; 931.2Sad struct device *self; 941.2Sad void *aux; 951.2Sad{ 961.2Sad struct ibus_attach_args *ia = aux; 971.2Sad struct siisoftc *sc = (struct siisoftc *) self; 981.2Sad 991.2Sad sc->sc_regs = (SIIRegs *)MIPS_PHYS_TO_KSEG1(ia->ia_addr); 1001.2Sad 1011.2Sad /* set up scsi buffer. XXX Why statically allocated? */ 1021.2Sad sc->sc_buf = (void*)(MIPS_PHYS_TO_KSEG1(KN01_SYS_SII_B_START)); 1031.2Sad 1041.2Sad if (systype == DS_PMAX) { 1051.2Sad#if 0 1061.2Sad sc->sii_copytobuf = CopyToBuffer; 1071.2Sad sc->sii_copyfrombuf = CopyFromBuffer; 1081.2Sad#else 1091.2Sad sc->sii_copytobuf = kn01_copytobuf; 1101.2Sad sc->sii_copyfrombuf = kn01_copyfrombuf; 1111.2Sad#endif 1121.2Sad } else { 1131.2Sad sc->sii_copytobuf = kn230_copytobuf; 1141.2Sad sc->sii_copyfrombuf = kn230_copyfrombuf; 1151.2Sad } 1161.2Sad 1171.2Sad /* Do the common parts of attachment. */ 1181.2Sad sc->sc_adapter.adapt_request = sii_scsi_request; 1191.2Sad sc->sc_adapter.adapt_minphys = minphys; 1201.2Sad siiattach(sc); 1211.2Sad 1221.2Sad /* tie pseudo-slot to device */ 1231.2Sad ibus_intr_establish(parent, (void*)ia->ia_cookie, IPL_BIO, siiintr, sc); 1241.2Sad} 1251.2Sad 1261.2Sad 1271.2Sad/* 1281.2Sad * Padded DMA copy functions 1291.2Sad * 1301.2Sad */ 1311.2Sad 1321.2Sad/* 1331.2Sad * XXX assumes src is always 32-bit aligned. 1341.2Sad * currently safe on sii driver, but API and casts should be changed. 1351.2Sad */ 1361.2Sadstatic void 1371.2Sadkn230_copytobuf(src, dst, len) 1381.2Sad u_short *src; 1391.2Sad volatile u_short *dst; 1401.2Sad int len; 1411.2Sad{ 1421.2Sad u_int *wsrc = (u_int *)src; 1431.2Sad volatile u_int *wdst = (volatile u_int *)dst; 1441.2Sad int i, n; 1451.2Sad 1461.2Sad#if defined(DIAGNOSTIC) || defined(DEBUG) 1471.2Sad if ((u_int)(src) & 0x3) { 1481.2Sad printf("kn230: copytobuf, src %p misaligned\n", src); 1491.2Sad } 1501.2Sad if ((u_int)(dst) & 0x3) { 1511.2Sad printf("kn230: copytobuf, dst %p misaligned\n", dst); 1521.2Sad } 1531.2Sad#endif 1541.2Sad 1551.2Sad /* DMA buffer is allocated in 32-bit words, so just copy words. */ 1561.2Sad n = len / 4; 1571.2Sad if (len & 0x3) 1581.2Sad n++; 1591.2Sad for (i = 0; i < n; i++) { 1601.2Sad *wdst = *wsrc; 1611.2Sad wsrc++; 1621.2Sad wdst+= 2; 1631.2Sad } 1641.2Sad 1651.2Sad wbflush(); /* XXX not necessary? */ 1661.2Sad} 1671.2Sad 1681.2Sad 1691.2Sad/* 1701.2Sad * XXX assumes dst is always 32-bit aligned. 1711.2Sad * currently safe on sii driver, but API and casts should be changed. 1721.2Sad */ 1731.2Sadstatic void 1741.2Sadkn230_copyfrombuf(src, dst, len) 1751.2Sad volatile u_short *src; 1761.2Sad char *dst; /* XXX assume 32-bit aligned? */ 1771.2Sad int len; 1781.2Sad{ 1791.2Sad volatile u_int *wsrc = (volatile u_int *)src; 1801.2Sad u_int *wdst = (u_int *)dst; 1811.2Sad int i, n; 1821.2Sad 1831.2Sad#if defined(DIAGNOSTIC) || defined(DEBUG) 1841.2Sad if ((u_int)(src) & 0x3) { 1851.2Sad printf("kn230: copyfrombuf, src %p misaligned\n", src); 1861.2Sad } 1871.2Sad if ((u_int)(dst) & 0x3) { 1881.2Sad printf("kn230: copyfrombuf, dst %p misaligned\n", dst); 1891.2Sad } 1901.2Sad#endif 1911.2Sad 1921.2Sad n = len / 4; 1931.2Sad 1941.2Sad for (i = 0; i < n; i++) { 1951.2Sad *wdst = *wsrc; 1961.2Sad wsrc += 2; 1971.2Sad wdst++; 1981.2Sad } 1991.2Sad 2001.2Sad if (len & 0x3) { 2011.2Sad u_int lastword = *wsrc; 2021.2Sad 2031.2Sad if (len & 0x2) 2041.2Sad *((u_short*)(wdst)) = (u_short) (lastword); 2051.2Sad 2061.2Sad if (len & 0x1) 2071.2Sad ((u_char*)(wdst))[2] = (u_char) (lastword >> 16); 2081.2Sad } 2091.2Sad 2101.2Sad wbflush(); /* XXX not necessary? */ 2111.2Sad} 2121.2Sad 2131.2Sad 2141.2Sadstatic void 2151.2Sadkn01_copytobuf(src, dst, len) 2161.2Sad u_short *src; 2171.2Sad volatile u_short *dst; 2181.2Sad int len; 2191.2Sad{ 2201.2Sad#if defined(DIAGNOSTIC) || defined(DEBUG) 2211.2Sad if ((u_int)(src) & 0x3) { 2221.2Sad printf("kn01: copytobuf, src %p misaligned\n", src); 2231.2Sad } 2241.2Sad if ((u_int)(dst) & 0x3) { 2251.2Sad printf("kn01: copytobuf, dst %p misaligned\n", dst); 2261.2Sad } 2271.2Sad#endif 2281.2Sad 2291.2Sad CopyToBuffer(src, dst, len); 2301.2Sad} 2311.2Sad 2321.2Sadstatic void 2331.2Sadkn01_copyfrombuf(src, dst, len) 2341.2Sad volatile u_short *src; 2351.2Sad char *dst; /* XXX assume 32-bit aligned? */ 2361.2Sad int len; 2371.2Sad{ 2381.2Sad#if defined(DIAGNOSTIC) || defined(DEBUG) 2391.2Sad if ((u_int)(src) & 0x3) { 2401.2Sad printf("kn01: copyfrombuf, src %p misaligned\n", src); 2411.2Sad } 2421.2Sad if ((u_int)(dst) & 0x3) { 2431.2Sad printf("kn01: copyfrombuf, dst %p misaligned\n", dst); 2441.2Sad } 2451.2Sad 2461.2Sad#endif 2471.2Sad CopyFromBuffer(src, dst, len); 2481.2Sad 2491.2Sad} 250