sii_ds.c revision 1.10
11.10Smatt/* $NetBSD: sii_ds.c,v 1.10 2015/06/09 20:23:53 matt 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.10Smatt__KERNEL_RCSID(0, "$NetBSD: sii_ds.c,v 1.10 2015/06/09 20:23:53 matt Exp $"); 201.2Sad 211.2Sad#include "sii.h" 221.2Sad 231.2Sad#include <sys/param.h> 241.9Smatt#include <sys/buf.h> 251.9Smatt#include <sys/bus.h> 261.10Smatt#include <sys/cpu.h> 271.9Smatt#include <sys/device.h> 281.2Sad#include <sys/systm.h> 291.2Sad 301.9Smatt#include <mips/locore.h> 311.9Smatt#include <pmax/locore.h> 321.2Sad 331.2Sad#include <dev/scsipi/scsi_all.h> 341.2Sad#include <dev/scsipi/scsipi_all.h> 351.2Sad#include <dev/scsipi/scsiconf.h> 361.2Sad#include <dev/scsipi/scsi_message.h> 371.2Sad 381.2Sad#include <pmax/ibus/siireg.h> 391.2Sad#include <pmax/ibus/siivar.h> 401.2Sad 411.2Sad#include <pmax/ibus/ibusvar.h> /* interrupt etablish */ 421.2Sad 431.2Sad#include <pmax/pmax/kn01.h> /* kn01 (ds3100) address constants */ 441.2Sad#include <pmax/pmax/pmaxtype.h> 451.2Sad 461.2Sad 471.4Sdslstatic void kn230_copytobuf(u_short *src, /* NB: must be short aligned */ 481.4Sdsl volatile u_short *dst, int length); 491.4Sdslstatic void kn230_copyfrombuf(volatile u_short *src, char *dst, 501.4Sdsl int length); 511.4Sdsl 521.4Sdslstatic void kn01_copytobuf(u_short *src, /* NB: must be short aligned */ 531.4Sdsl volatile u_short *dst, int length); 541.4Sdslstatic void kn01_copyfrombuf(volatile u_short *src, char *dst, 551.4Sdsl int length); 561.2Sad 571.2Sad/* 581.2Sad * Autoconfig definition of driver front-end 591.2Sad */ 601.7Smattstatic int sii_ds_match(device_t, struct cfdata *, void *); 611.7Smattstatic void sii_ds_attach(device_t, device_t, void *); 621.2Sad 631.8StsutsuiCFATTACH_DECL_NEW(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.7Smattsii_ds_match(device_t parent, cfdata_t cf, void *aux) 751.2Sad{ 761.2Sad struct ibus_attach_args *ia = aux; 771.3Schristos void *siiaddr; 781.2Sad 791.2Sad if (strcmp(ia->ia_name, "sii") != 0) 801.2Sad return (0); 811.2Sad siiaddr = (void *)ia->ia_addr; 821.2Sad if (badaddr(siiaddr, 4)) 831.2Sad return (0); 841.2Sad return (1); 851.2Sad} 861.2Sad 871.2Sadstatic void 881.7Smattsii_ds_attach(device_t parent, device_t self, void *aux) 891.2Sad{ 901.2Sad struct ibus_attach_args *ia = aux; 911.7Smatt struct siisoftc *sc = device_private(self); 921.2Sad 931.8Stsutsui sc->sc_dev = self; 941.2Sad sc->sc_regs = (SIIRegs *)MIPS_PHYS_TO_KSEG1(ia->ia_addr); 951.2Sad 961.2Sad /* set up scsi buffer. XXX Why statically allocated? */ 971.2Sad sc->sc_buf = (void*)(MIPS_PHYS_TO_KSEG1(KN01_SYS_SII_B_START)); 981.2Sad 991.2Sad if (systype == DS_PMAX) { 1001.2Sad#if 0 1011.2Sad sc->sii_copytobuf = CopyToBuffer; 1021.2Sad sc->sii_copyfrombuf = CopyFromBuffer; 1031.2Sad#else 1041.2Sad sc->sii_copytobuf = kn01_copytobuf; 1051.2Sad sc->sii_copyfrombuf = kn01_copyfrombuf; 1061.2Sad#endif 1071.2Sad } else { 1081.2Sad sc->sii_copytobuf = kn230_copytobuf; 1091.2Sad sc->sii_copyfrombuf = kn230_copyfrombuf; 1101.2Sad } 1111.2Sad 1121.2Sad /* Do the common parts of attachment. */ 1131.2Sad sc->sc_adapter.adapt_request = sii_scsi_request; 1141.2Sad sc->sc_adapter.adapt_minphys = minphys; 1151.2Sad siiattach(sc); 1161.2Sad 1171.2Sad /* tie pseudo-slot to device */ 1181.2Sad ibus_intr_establish(parent, (void*)ia->ia_cookie, IPL_BIO, siiintr, sc); 1191.2Sad} 1201.2Sad 1211.2Sad 1221.2Sad/* 1231.2Sad * Padded DMA copy functions 1241.2Sad * 1251.2Sad */ 1261.2Sad 1271.2Sad/* 1281.2Sad * XXX assumes src is always 32-bit aligned. 1291.2Sad * currently safe on sii driver, but API and casts should be changed. 1301.2Sad */ 1311.2Sadstatic void 1321.5Sdslkn230_copytobuf(u_short *src, volatile u_short *dst, int len) 1331.2Sad{ 1341.2Sad u_int *wsrc = (u_int *)src; 1351.2Sad volatile u_int *wdst = (volatile u_int *)dst; 1361.2Sad int i, n; 1371.2Sad 1381.2Sad#if defined(DIAGNOSTIC) || defined(DEBUG) 1391.2Sad if ((u_int)(src) & 0x3) { 1401.2Sad printf("kn230: copytobuf, src %p misaligned\n", src); 1411.2Sad } 1421.2Sad if ((u_int)(dst) & 0x3) { 1431.2Sad printf("kn230: copytobuf, dst %p misaligned\n", dst); 1441.2Sad } 1451.2Sad#endif 1461.2Sad 1471.2Sad /* DMA buffer is allocated in 32-bit words, so just copy words. */ 1481.2Sad n = len / 4; 1491.2Sad if (len & 0x3) 1501.2Sad n++; 1511.2Sad for (i = 0; i < n; i++) { 1521.2Sad *wdst = *wsrc; 1531.2Sad wsrc++; 1541.2Sad wdst+= 2; 1551.2Sad } 1561.2Sad 1571.2Sad wbflush(); /* XXX not necessary? */ 1581.2Sad} 1591.2Sad 1601.2Sad 1611.2Sad/* 1621.2Sad * XXX assumes dst is always 32-bit aligned. 1631.2Sad * currently safe on sii driver, but API and casts should be changed. 1641.2Sad */ 1651.2Sadstatic void 1661.6Sdslkn230_copyfrombuf(volatile u_short *src, char *dst, int len) 1671.6Sdsl /* dst: XXX assume 32-bit aligned? */ 1681.2Sad{ 1691.2Sad volatile u_int *wsrc = (volatile u_int *)src; 1701.2Sad u_int *wdst = (u_int *)dst; 1711.2Sad int i, n; 1721.2Sad 1731.2Sad#if defined(DIAGNOSTIC) || defined(DEBUG) 1741.2Sad if ((u_int)(src) & 0x3) { 1751.2Sad printf("kn230: copyfrombuf, src %p misaligned\n", src); 1761.2Sad } 1771.2Sad if ((u_int)(dst) & 0x3) { 1781.2Sad printf("kn230: copyfrombuf, dst %p misaligned\n", dst); 1791.2Sad } 1801.2Sad#endif 1811.2Sad 1821.2Sad n = len / 4; 1831.2Sad 1841.2Sad for (i = 0; i < n; i++) { 1851.2Sad *wdst = *wsrc; 1861.2Sad wsrc += 2; 1871.2Sad wdst++; 1881.2Sad } 1891.2Sad 1901.2Sad if (len & 0x3) { 1911.2Sad u_int lastword = *wsrc; 1921.2Sad 1931.2Sad if (len & 0x2) 1941.2Sad *((u_short*)(wdst)) = (u_short) (lastword); 1951.2Sad 1961.2Sad if (len & 0x1) 1971.2Sad ((u_char*)(wdst))[2] = (u_char) (lastword >> 16); 1981.2Sad } 1991.2Sad 2001.2Sad wbflush(); /* XXX not necessary? */ 2011.2Sad} 2021.2Sad 2031.2Sad 2041.2Sadstatic void 2051.5Sdslkn01_copytobuf(u_short *src, volatile u_short *dst, int len) 2061.2Sad{ 2071.2Sad#if defined(DIAGNOSTIC) || defined(DEBUG) 2081.2Sad if ((u_int)(src) & 0x3) { 2091.2Sad printf("kn01: copytobuf, src %p misaligned\n", src); 2101.2Sad } 2111.2Sad if ((u_int)(dst) & 0x3) { 2121.2Sad printf("kn01: copytobuf, dst %p misaligned\n", dst); 2131.2Sad } 2141.2Sad#endif 2151.2Sad 2161.2Sad CopyToBuffer(src, dst, len); 2171.2Sad} 2181.2Sad 2191.2Sadstatic void 2201.6Sdslkn01_copyfrombuf(volatile u_short *src, char *dst, int len) 2211.6Sdsl /* dst: XXX assume 32-bit aligned? */ 2221.2Sad{ 2231.2Sad#if defined(DIAGNOSTIC) || defined(DEBUG) 2241.2Sad if ((u_int)(src) & 0x3) { 2251.2Sad printf("kn01: copyfrombuf, src %p misaligned\n", src); 2261.2Sad } 2271.2Sad if ((u_int)(dst) & 0x3) { 2281.2Sad printf("kn01: copyfrombuf, dst %p misaligned\n", dst); 2291.2Sad } 2301.2Sad 2311.2Sad#endif 2321.2Sad CopyFromBuffer(src, dst, len); 2331.2Sad 2341.2Sad} 235