sii_ds.c revision 1.7
11.7Smatt/* $NetBSD: sii_ds.c,v 1.7 2011/02/20 07:50:24 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.7Smatt__KERNEL_RCSID(0, "$NetBSD: sii_ds.c,v 1.7 2011/02/20 07:50:24 matt 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.4Sdslstatic void kn230_copytobuf(u_short *src, /* NB: must be short aligned */ 461.4Sdsl volatile u_short *dst, int length); 471.4Sdslstatic void kn230_copyfrombuf(volatile u_short *src, char *dst, 481.4Sdsl int length); 491.4Sdsl 501.4Sdslstatic void kn01_copytobuf(u_short *src, /* NB: must be short aligned */ 511.4Sdsl volatile u_short *dst, int length); 521.4Sdslstatic void kn01_copyfrombuf(volatile u_short *src, char *dst, 531.4Sdsl int length); 541.2Sad 551.2Sad/* 561.2Sad * Autoconfig definition of driver front-end 571.2Sad */ 581.7Smattstatic int sii_ds_match(device_t, struct cfdata *, void *); 591.7Smattstatic void sii_ds_attach(device_t, device_t, void *); 601.2Sad 611.2SadCFATTACH_DECL(sii_ds, sizeof(struct siisoftc), 621.2Sad sii_ds_match, sii_ds_attach, NULL, NULL); 631.2Sad 641.2Sad/* define a safe address in the SCSI buffer for doing status & message DMA */ 651.2Sad#define SII_BUF_ADDR (MIPS_PHYS_TO_KSEG1(KN01_SYS_SII_B_START) \ 661.2Sad + SII_MAX_DMA_XFER_LENGTH * 14) 671.2Sad 681.2Sad/* 691.2Sad * Match driver on Decstation (2100, 3100, 5100) based on name and probe. 701.2Sad */ 711.2Sadstatic int 721.7Smattsii_ds_match(device_t parent, cfdata_t cf, void *aux) 731.2Sad{ 741.2Sad struct ibus_attach_args *ia = aux; 751.3Schristos void *siiaddr; 761.2Sad 771.2Sad if (strcmp(ia->ia_name, "sii") != 0) 781.2Sad return (0); 791.2Sad siiaddr = (void *)ia->ia_addr; 801.2Sad if (badaddr(siiaddr, 4)) 811.2Sad return (0); 821.2Sad return (1); 831.2Sad} 841.2Sad 851.2Sadstatic void 861.7Smattsii_ds_attach(device_t parent, device_t self, void *aux) 871.2Sad{ 881.2Sad struct ibus_attach_args *ia = aux; 891.7Smatt struct siisoftc *sc = device_private(self); 901.2Sad 911.2Sad sc->sc_regs = (SIIRegs *)MIPS_PHYS_TO_KSEG1(ia->ia_addr); 921.2Sad 931.2Sad /* set up scsi buffer. XXX Why statically allocated? */ 941.2Sad sc->sc_buf = (void*)(MIPS_PHYS_TO_KSEG1(KN01_SYS_SII_B_START)); 951.2Sad 961.2Sad if (systype == DS_PMAX) { 971.2Sad#if 0 981.2Sad sc->sii_copytobuf = CopyToBuffer; 991.2Sad sc->sii_copyfrombuf = CopyFromBuffer; 1001.2Sad#else 1011.2Sad sc->sii_copytobuf = kn01_copytobuf; 1021.2Sad sc->sii_copyfrombuf = kn01_copyfrombuf; 1031.2Sad#endif 1041.2Sad } else { 1051.2Sad sc->sii_copytobuf = kn230_copytobuf; 1061.2Sad sc->sii_copyfrombuf = kn230_copyfrombuf; 1071.2Sad } 1081.2Sad 1091.2Sad /* Do the common parts of attachment. */ 1101.2Sad sc->sc_adapter.adapt_request = sii_scsi_request; 1111.2Sad sc->sc_adapter.adapt_minphys = minphys; 1121.2Sad siiattach(sc); 1131.2Sad 1141.2Sad /* tie pseudo-slot to device */ 1151.2Sad ibus_intr_establish(parent, (void*)ia->ia_cookie, IPL_BIO, siiintr, sc); 1161.2Sad} 1171.2Sad 1181.2Sad 1191.2Sad/* 1201.2Sad * Padded DMA copy functions 1211.2Sad * 1221.2Sad */ 1231.2Sad 1241.2Sad/* 1251.2Sad * XXX assumes src is always 32-bit aligned. 1261.2Sad * currently safe on sii driver, but API and casts should be changed. 1271.2Sad */ 1281.2Sadstatic void 1291.5Sdslkn230_copytobuf(u_short *src, volatile u_short *dst, int len) 1301.2Sad{ 1311.2Sad u_int *wsrc = (u_int *)src; 1321.2Sad volatile u_int *wdst = (volatile u_int *)dst; 1331.2Sad int i, n; 1341.2Sad 1351.2Sad#if defined(DIAGNOSTIC) || defined(DEBUG) 1361.2Sad if ((u_int)(src) & 0x3) { 1371.2Sad printf("kn230: copytobuf, src %p misaligned\n", src); 1381.2Sad } 1391.2Sad if ((u_int)(dst) & 0x3) { 1401.2Sad printf("kn230: copytobuf, dst %p misaligned\n", dst); 1411.2Sad } 1421.2Sad#endif 1431.2Sad 1441.2Sad /* DMA buffer is allocated in 32-bit words, so just copy words. */ 1451.2Sad n = len / 4; 1461.2Sad if (len & 0x3) 1471.2Sad n++; 1481.2Sad for (i = 0; i < n; i++) { 1491.2Sad *wdst = *wsrc; 1501.2Sad wsrc++; 1511.2Sad wdst+= 2; 1521.2Sad } 1531.2Sad 1541.2Sad wbflush(); /* XXX not necessary? */ 1551.2Sad} 1561.2Sad 1571.2Sad 1581.2Sad/* 1591.2Sad * XXX assumes dst is always 32-bit aligned. 1601.2Sad * currently safe on sii driver, but API and casts should be changed. 1611.2Sad */ 1621.2Sadstatic void 1631.6Sdslkn230_copyfrombuf(volatile u_short *src, char *dst, int len) 1641.6Sdsl /* dst: XXX assume 32-bit aligned? */ 1651.2Sad{ 1661.2Sad volatile u_int *wsrc = (volatile u_int *)src; 1671.2Sad u_int *wdst = (u_int *)dst; 1681.2Sad int i, n; 1691.2Sad 1701.2Sad#if defined(DIAGNOSTIC) || defined(DEBUG) 1711.2Sad if ((u_int)(src) & 0x3) { 1721.2Sad printf("kn230: copyfrombuf, src %p misaligned\n", src); 1731.2Sad } 1741.2Sad if ((u_int)(dst) & 0x3) { 1751.2Sad printf("kn230: copyfrombuf, dst %p misaligned\n", dst); 1761.2Sad } 1771.2Sad#endif 1781.2Sad 1791.2Sad n = len / 4; 1801.2Sad 1811.2Sad for (i = 0; i < n; i++) { 1821.2Sad *wdst = *wsrc; 1831.2Sad wsrc += 2; 1841.2Sad wdst++; 1851.2Sad } 1861.2Sad 1871.2Sad if (len & 0x3) { 1881.2Sad u_int lastword = *wsrc; 1891.2Sad 1901.2Sad if (len & 0x2) 1911.2Sad *((u_short*)(wdst)) = (u_short) (lastword); 1921.2Sad 1931.2Sad if (len & 0x1) 1941.2Sad ((u_char*)(wdst))[2] = (u_char) (lastword >> 16); 1951.2Sad } 1961.2Sad 1971.2Sad wbflush(); /* XXX not necessary? */ 1981.2Sad} 1991.2Sad 2001.2Sad 2011.2Sadstatic void 2021.5Sdslkn01_copytobuf(u_short *src, volatile u_short *dst, int len) 2031.2Sad{ 2041.2Sad#if defined(DIAGNOSTIC) || defined(DEBUG) 2051.2Sad if ((u_int)(src) & 0x3) { 2061.2Sad printf("kn01: copytobuf, src %p misaligned\n", src); 2071.2Sad } 2081.2Sad if ((u_int)(dst) & 0x3) { 2091.2Sad printf("kn01: copytobuf, dst %p misaligned\n", dst); 2101.2Sad } 2111.2Sad#endif 2121.2Sad 2131.2Sad CopyToBuffer(src, dst, len); 2141.2Sad} 2151.2Sad 2161.2Sadstatic void 2171.6Sdslkn01_copyfrombuf(volatile u_short *src, char *dst, int len) 2181.6Sdsl /* dst: XXX assume 32-bit aligned? */ 2191.2Sad{ 2201.2Sad#if defined(DIAGNOSTIC) || defined(DEBUG) 2211.2Sad if ((u_int)(src) & 0x3) { 2221.2Sad printf("kn01: copyfrombuf, src %p misaligned\n", src); 2231.2Sad } 2241.2Sad if ((u_int)(dst) & 0x3) { 2251.2Sad printf("kn01: copyfrombuf, dst %p misaligned\n", dst); 2261.2Sad } 2271.2Sad 2281.2Sad#endif 2291.2Sad CopyFromBuffer(src, dst, len); 2301.2Sad 2311.2Sad} 232