sii_ds.c revision 1.9
11.9Smatt/* $NetBSD: sii_ds.c,v 1.9 2011/07/09 17:32:30 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.9Smatt__KERNEL_RCSID(0, "$NetBSD: sii_ds.c,v 1.9 2011/07/09 17:32:30 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.9Smatt#include <sys/device.h> 271.2Sad#include <sys/systm.h> 281.2Sad 291.9Smatt#include <mips/locore.h> 301.9Smatt#include <pmax/locore.h> 311.2Sad 321.2Sad#include <dev/scsipi/scsi_all.h> 331.2Sad#include <dev/scsipi/scsipi_all.h> 341.2Sad#include <dev/scsipi/scsiconf.h> 351.2Sad#include <dev/scsipi/scsi_message.h> 361.2Sad 371.2Sad#include <pmax/ibus/siireg.h> 381.2Sad#include <pmax/ibus/siivar.h> 391.2Sad 401.2Sad#include <pmax/ibus/ibusvar.h> /* interrupt etablish */ 411.2Sad 421.2Sad#include <pmax/pmax/kn01.h> /* kn01 (ds3100) address constants */ 431.2Sad#include <pmax/pmax/pmaxtype.h> 441.2Sad 451.2Sad 461.4Sdslstatic void kn230_copytobuf(u_short *src, /* NB: must be short aligned */ 471.4Sdsl volatile u_short *dst, int length); 481.4Sdslstatic void kn230_copyfrombuf(volatile u_short *src, char *dst, 491.4Sdsl int length); 501.4Sdsl 511.4Sdslstatic void kn01_copytobuf(u_short *src, /* NB: must be short aligned */ 521.4Sdsl volatile u_short *dst, int length); 531.4Sdslstatic void kn01_copyfrombuf(volatile u_short *src, char *dst, 541.4Sdsl int length); 551.2Sad 561.2Sad/* 571.2Sad * Autoconfig definition of driver front-end 581.2Sad */ 591.7Smattstatic int sii_ds_match(device_t, struct cfdata *, void *); 601.7Smattstatic void sii_ds_attach(device_t, device_t, void *); 611.2Sad 621.8StsutsuiCFATTACH_DECL_NEW(sii_ds, sizeof(struct siisoftc), 631.2Sad sii_ds_match, sii_ds_attach, NULL, NULL); 641.2Sad 651.2Sad/* define a safe address in the SCSI buffer for doing status & message DMA */ 661.2Sad#define SII_BUF_ADDR (MIPS_PHYS_TO_KSEG1(KN01_SYS_SII_B_START) \ 671.2Sad + SII_MAX_DMA_XFER_LENGTH * 14) 681.2Sad 691.2Sad/* 701.2Sad * Match driver on Decstation (2100, 3100, 5100) based on name and probe. 711.2Sad */ 721.2Sadstatic int 731.7Smattsii_ds_match(device_t parent, cfdata_t cf, void *aux) 741.2Sad{ 751.2Sad struct ibus_attach_args *ia = aux; 761.3Schristos void *siiaddr; 771.2Sad 781.2Sad if (strcmp(ia->ia_name, "sii") != 0) 791.2Sad return (0); 801.2Sad siiaddr = (void *)ia->ia_addr; 811.2Sad if (badaddr(siiaddr, 4)) 821.2Sad return (0); 831.2Sad return (1); 841.2Sad} 851.2Sad 861.2Sadstatic void 871.7Smattsii_ds_attach(device_t parent, device_t self, void *aux) 881.2Sad{ 891.2Sad struct ibus_attach_args *ia = aux; 901.7Smatt struct siisoftc *sc = device_private(self); 911.2Sad 921.8Stsutsui sc->sc_dev = self; 931.2Sad sc->sc_regs = (SIIRegs *)MIPS_PHYS_TO_KSEG1(ia->ia_addr); 941.2Sad 951.2Sad /* set up scsi buffer. XXX Why statically allocated? */ 961.2Sad sc->sc_buf = (void*)(MIPS_PHYS_TO_KSEG1(KN01_SYS_SII_B_START)); 971.2Sad 981.2Sad if (systype == DS_PMAX) { 991.2Sad#if 0 1001.2Sad sc->sii_copytobuf = CopyToBuffer; 1011.2Sad sc->sii_copyfrombuf = CopyFromBuffer; 1021.2Sad#else 1031.2Sad sc->sii_copytobuf = kn01_copytobuf; 1041.2Sad sc->sii_copyfrombuf = kn01_copyfrombuf; 1051.2Sad#endif 1061.2Sad } else { 1071.2Sad sc->sii_copytobuf = kn230_copytobuf; 1081.2Sad sc->sii_copyfrombuf = kn230_copyfrombuf; 1091.2Sad } 1101.2Sad 1111.2Sad /* Do the common parts of attachment. */ 1121.2Sad sc->sc_adapter.adapt_request = sii_scsi_request; 1131.2Sad sc->sc_adapter.adapt_minphys = minphys; 1141.2Sad siiattach(sc); 1151.2Sad 1161.2Sad /* tie pseudo-slot to device */ 1171.2Sad ibus_intr_establish(parent, (void*)ia->ia_cookie, IPL_BIO, siiintr, sc); 1181.2Sad} 1191.2Sad 1201.2Sad 1211.2Sad/* 1221.2Sad * Padded DMA copy functions 1231.2Sad * 1241.2Sad */ 1251.2Sad 1261.2Sad/* 1271.2Sad * XXX assumes src is always 32-bit aligned. 1281.2Sad * currently safe on sii driver, but API and casts should be changed. 1291.2Sad */ 1301.2Sadstatic void 1311.5Sdslkn230_copytobuf(u_short *src, volatile u_short *dst, int len) 1321.2Sad{ 1331.2Sad u_int *wsrc = (u_int *)src; 1341.2Sad volatile u_int *wdst = (volatile u_int *)dst; 1351.2Sad int i, n; 1361.2Sad 1371.2Sad#if defined(DIAGNOSTIC) || defined(DEBUG) 1381.2Sad if ((u_int)(src) & 0x3) { 1391.2Sad printf("kn230: copytobuf, src %p misaligned\n", src); 1401.2Sad } 1411.2Sad if ((u_int)(dst) & 0x3) { 1421.2Sad printf("kn230: copytobuf, dst %p misaligned\n", dst); 1431.2Sad } 1441.2Sad#endif 1451.2Sad 1461.2Sad /* DMA buffer is allocated in 32-bit words, so just copy words. */ 1471.2Sad n = len / 4; 1481.2Sad if (len & 0x3) 1491.2Sad n++; 1501.2Sad for (i = 0; i < n; i++) { 1511.2Sad *wdst = *wsrc; 1521.2Sad wsrc++; 1531.2Sad wdst+= 2; 1541.2Sad } 1551.2Sad 1561.2Sad wbflush(); /* XXX not necessary? */ 1571.2Sad} 1581.2Sad 1591.2Sad 1601.2Sad/* 1611.2Sad * XXX assumes dst is always 32-bit aligned. 1621.2Sad * currently safe on sii driver, but API and casts should be changed. 1631.2Sad */ 1641.2Sadstatic void 1651.6Sdslkn230_copyfrombuf(volatile u_short *src, char *dst, int len) 1661.6Sdsl /* dst: XXX assume 32-bit aligned? */ 1671.2Sad{ 1681.2Sad volatile u_int *wsrc = (volatile u_int *)src; 1691.2Sad u_int *wdst = (u_int *)dst; 1701.2Sad int i, n; 1711.2Sad 1721.2Sad#if defined(DIAGNOSTIC) || defined(DEBUG) 1731.2Sad if ((u_int)(src) & 0x3) { 1741.2Sad printf("kn230: copyfrombuf, src %p misaligned\n", src); 1751.2Sad } 1761.2Sad if ((u_int)(dst) & 0x3) { 1771.2Sad printf("kn230: copyfrombuf, dst %p misaligned\n", dst); 1781.2Sad } 1791.2Sad#endif 1801.2Sad 1811.2Sad n = len / 4; 1821.2Sad 1831.2Sad for (i = 0; i < n; i++) { 1841.2Sad *wdst = *wsrc; 1851.2Sad wsrc += 2; 1861.2Sad wdst++; 1871.2Sad } 1881.2Sad 1891.2Sad if (len & 0x3) { 1901.2Sad u_int lastword = *wsrc; 1911.2Sad 1921.2Sad if (len & 0x2) 1931.2Sad *((u_short*)(wdst)) = (u_short) (lastword); 1941.2Sad 1951.2Sad if (len & 0x1) 1961.2Sad ((u_char*)(wdst))[2] = (u_char) (lastword >> 16); 1971.2Sad } 1981.2Sad 1991.2Sad wbflush(); /* XXX not necessary? */ 2001.2Sad} 2011.2Sad 2021.2Sad 2031.2Sadstatic void 2041.5Sdslkn01_copytobuf(u_short *src, volatile u_short *dst, int len) 2051.2Sad{ 2061.2Sad#if defined(DIAGNOSTIC) || defined(DEBUG) 2071.2Sad if ((u_int)(src) & 0x3) { 2081.2Sad printf("kn01: copytobuf, src %p misaligned\n", src); 2091.2Sad } 2101.2Sad if ((u_int)(dst) & 0x3) { 2111.2Sad printf("kn01: copytobuf, dst %p misaligned\n", dst); 2121.2Sad } 2131.2Sad#endif 2141.2Sad 2151.2Sad CopyToBuffer(src, dst, len); 2161.2Sad} 2171.2Sad 2181.2Sadstatic void 2191.6Sdslkn01_copyfrombuf(volatile u_short *src, char *dst, int len) 2201.6Sdsl /* dst: XXX assume 32-bit aligned? */ 2211.2Sad{ 2221.2Sad#if defined(DIAGNOSTIC) || defined(DEBUG) 2231.2Sad if ((u_int)(src) & 0x3) { 2241.2Sad printf("kn01: copyfrombuf, src %p misaligned\n", src); 2251.2Sad } 2261.2Sad if ((u_int)(dst) & 0x3) { 2271.2Sad printf("kn01: copyfrombuf, dst %p misaligned\n", dst); 2281.2Sad } 2291.2Sad 2301.2Sad#endif 2311.2Sad CopyFromBuffer(src, dst, len); 2321.2Sad 2331.2Sad} 234