1/*- 2 * Copyright (c) 2004 Scott Long 3 * Copyright (c) 2005 Marius Strobl <marius@FreeBSD.org> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 */ 28 29/* $NetBSD: esp_sbus.c,v 1.51 2009/09/17 16:28:12 tsutsui Exp $ */ 30 31/*- 32 * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. 33 * All rights reserved. 34 * 35 * This code is derived from software contributed to The NetBSD Foundation 36 * by Charles M. Hannum; Jason R. Thorpe of the Numerical Aerospace 37 * Simulation Facility, NASA Ames Research Center; Paul Kranenburg. 38 * 39 * Redistribution and use in source and binary forms, with or without 40 * modification, are permitted provided that the following conditions 41 * are met: 42 * 1. Redistributions of source code must retain the above copyright 43 * notice, this list of conditions and the following disclaimer. 44 * 2. Redistributions in binary form must reproduce the above copyright 45 * notice, this list of conditions and the following disclaimer in the 46 * documentation and/or other materials provided with the distribution. 47 * 48 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 49 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 50 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 51 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 52 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 53 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 54 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 55 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 56 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 57 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 58 * POSSIBILITY OF SUCH DAMAGE. 59 */ 60 61#include <sys/cdefs.h>
| 1/*- 2 * Copyright (c) 2004 Scott Long 3 * Copyright (c) 2005 Marius Strobl <marius@FreeBSD.org> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 */ 28 29/* $NetBSD: esp_sbus.c,v 1.51 2009/09/17 16:28:12 tsutsui Exp $ */ 30 31/*- 32 * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. 33 * All rights reserved. 34 * 35 * This code is derived from software contributed to The NetBSD Foundation 36 * by Charles M. Hannum; Jason R. Thorpe of the Numerical Aerospace 37 * Simulation Facility, NASA Ames Research Center; Paul Kranenburg. 38 * 39 * Redistribution and use in source and binary forms, with or without 40 * modification, are permitted provided that the following conditions 41 * are met: 42 * 1. Redistributions of source code must retain the above copyright 43 * notice, this list of conditions and the following disclaimer. 44 * 2. Redistributions in binary form must reproduce the above copyright 45 * notice, this list of conditions and the following disclaimer in the 46 * documentation and/or other materials provided with the distribution. 47 * 48 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 49 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 50 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 51 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 52 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 53 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 54 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 55 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 56 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 57 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 58 * POSSIBILITY OF SUCH DAMAGE. 59 */ 60 61#include <sys/cdefs.h>
|
62__FBSDID("$FreeBSD: head/sys/dev/esp/esp_sbus.c 226381 2011-10-15 09:29:43Z marius $");
| 62__FBSDID("$FreeBSD: head/sys/dev/esp/esp_sbus.c 226947 2011-10-30 21:17:42Z marius $");
|
63 64#include <sys/param.h> 65#include <sys/systm.h> 66#include <sys/bus.h> 67#include <sys/kernel.h> 68#include <sys/lock.h> 69#include <sys/module.h> 70#include <sys/mutex.h>
| 63 64#include <sys/param.h> 65#include <sys/systm.h> 66#include <sys/bus.h> 67#include <sys/kernel.h> 68#include <sys/lock.h> 69#include <sys/module.h> 70#include <sys/mutex.h>
|
| 71#include <sys/rman.h>
|
71 72#include <dev/ofw/ofw_bus.h> 73#include <dev/ofw/openfirm.h> 74#include <machine/bus.h> 75#include <machine/ofw_machdep.h> 76#include <machine/resource.h>
| 72 73#include <dev/ofw/ofw_bus.h> 74#include <dev/ofw/openfirm.h> 75#include <machine/bus.h> 76#include <machine/ofw_machdep.h> 77#include <machine/resource.h>
|
77#include <sys/rman.h>
| |
78 79#include <cam/cam.h> 80#include <cam/cam_ccb.h> 81#include <cam/scsi/scsi_all.h> 82#include <cam/scsi/scsi_message.h> 83 84#include <sparc64/sbus/lsi64854reg.h> 85#include <sparc64/sbus/lsi64854var.h> 86#include <sparc64/sbus/sbusvar.h> 87 88#include <dev/esp/ncr53c9xreg.h> 89#include <dev/esp/ncr53c9xvar.h> 90 91/* #define ESP_SBUS_DEBUG */ 92 93struct esp_softc { 94 struct ncr53c9x_softc sc_ncr53c9x; /* glue to MI code */
| 78 79#include <cam/cam.h> 80#include <cam/cam_ccb.h> 81#include <cam/scsi/scsi_all.h> 82#include <cam/scsi/scsi_message.h> 83 84#include <sparc64/sbus/lsi64854reg.h> 85#include <sparc64/sbus/lsi64854var.h> 86#include <sparc64/sbus/sbusvar.h> 87 88#include <dev/esp/ncr53c9xreg.h> 89#include <dev/esp/ncr53c9xvar.h> 90 91/* #define ESP_SBUS_DEBUG */ 92 93struct esp_softc { 94 struct ncr53c9x_softc sc_ncr53c9x; /* glue to MI code */
|
95 struct device *sc_dev;
| 95 device_t sc_dev;
|
96 97 struct resource *sc_res; 98 99 struct resource *sc_irqres; 100 void *sc_irq; 101 102 struct lsi64854_softc *sc_dma; /* pointer to my DMA */ 103}; 104
| 96 97 struct resource *sc_res; 98 99 struct resource *sc_irqres; 100 void *sc_irq; 101 102 struct lsi64854_softc *sc_dma; /* pointer to my DMA */ 103}; 104
|
105static devclass_t esp_devclass; 106
| |
107static int esp_probe(device_t); 108static int esp_dma_attach(device_t); 109static int esp_dma_detach(device_t); 110static int esp_sbus_attach(device_t); 111static int esp_sbus_detach(device_t); 112static int esp_suspend(device_t); 113static int esp_resume(device_t); 114 115static device_method_t esp_dma_methods[] = { 116 DEVMETHOD(device_probe, esp_probe), 117 DEVMETHOD(device_attach, esp_dma_attach), 118 DEVMETHOD(device_detach, esp_dma_detach), 119 DEVMETHOD(device_suspend, esp_suspend), 120 DEVMETHOD(device_resume, esp_resume),
| 105static int esp_probe(device_t); 106static int esp_dma_attach(device_t); 107static int esp_dma_detach(device_t); 108static int esp_sbus_attach(device_t); 109static int esp_sbus_detach(device_t); 110static int esp_suspend(device_t); 111static int esp_resume(device_t); 112 113static device_method_t esp_dma_methods[] = { 114 DEVMETHOD(device_probe, esp_probe), 115 DEVMETHOD(device_attach, esp_dma_attach), 116 DEVMETHOD(device_detach, esp_dma_detach), 117 DEVMETHOD(device_suspend, esp_suspend), 118 DEVMETHOD(device_resume, esp_resume),
|
121 {0, 0}
| 119 120 KOBJMETHOD_END
|
122}; 123 124static driver_t esp_dma_driver = { 125 "esp", 126 esp_dma_methods, 127 sizeof(struct esp_softc) 128}; 129 130DRIVER_MODULE(esp, dma, esp_dma_driver, esp_devclass, 0, 0); 131MODULE_DEPEND(esp, dma, 1, 1, 1); 132 133static device_method_t esp_sbus_methods[] = { 134 DEVMETHOD(device_probe, esp_probe), 135 DEVMETHOD(device_attach, esp_sbus_attach), 136 DEVMETHOD(device_detach, esp_sbus_detach), 137 DEVMETHOD(device_suspend, esp_suspend), 138 DEVMETHOD(device_resume, esp_resume),
| 121}; 122 123static driver_t esp_dma_driver = { 124 "esp", 125 esp_dma_methods, 126 sizeof(struct esp_softc) 127}; 128 129DRIVER_MODULE(esp, dma, esp_dma_driver, esp_devclass, 0, 0); 130MODULE_DEPEND(esp, dma, 1, 1, 1); 131 132static device_method_t esp_sbus_methods[] = { 133 DEVMETHOD(device_probe, esp_probe), 134 DEVMETHOD(device_attach, esp_sbus_attach), 135 DEVMETHOD(device_detach, esp_sbus_detach), 136 DEVMETHOD(device_suspend, esp_suspend), 137 DEVMETHOD(device_resume, esp_resume),
|
139 {0, 0}
| 138 139 KOBJMETHOD_END
|
140}; 141 142static driver_t esp_sbus_driver = { 143 "esp", 144 esp_sbus_methods, 145 sizeof(struct esp_softc) 146}; 147 148DRIVER_MODULE(esp, sbus, esp_sbus_driver, esp_devclass, 0, 0); 149MODULE_DEPEND(esp, sbus, 1, 1, 1); 150 151/* 152 * Functions and the switch for the MI code 153 */ 154static uint8_t esp_read_reg(struct ncr53c9x_softc *sc, int reg); 155static void esp_write_reg(struct ncr53c9x_softc *sc, int reg, uint8_t v); 156static int esp_dma_isintr(struct ncr53c9x_softc *sc); 157static void esp_dma_reset(struct ncr53c9x_softc *sc); 158static int esp_dma_intr(struct ncr53c9x_softc *sc); 159static int esp_dma_setup(struct ncr53c9x_softc *sc, void **addr, 160 size_t *len, int datain, size_t *dmasize); 161static void esp_dma_go(struct ncr53c9x_softc *sc); 162static void esp_dma_stop(struct ncr53c9x_softc *sc); 163static int esp_dma_isactive(struct ncr53c9x_softc *sc); 164static int espattach(struct esp_softc *esc, 165 const struct ncr53c9x_glue *gluep); 166static int espdetach(struct esp_softc *esc); 167 168static const struct ncr53c9x_glue const esp_sbus_glue = { 169 esp_read_reg, 170 esp_write_reg, 171 esp_dma_isintr, 172 esp_dma_reset, 173 esp_dma_intr, 174 esp_dma_setup, 175 esp_dma_go, 176 esp_dma_stop, 177 esp_dma_isactive,
| 140}; 141 142static driver_t esp_sbus_driver = { 143 "esp", 144 esp_sbus_methods, 145 sizeof(struct esp_softc) 146}; 147 148DRIVER_MODULE(esp, sbus, esp_sbus_driver, esp_devclass, 0, 0); 149MODULE_DEPEND(esp, sbus, 1, 1, 1); 150 151/* 152 * Functions and the switch for the MI code 153 */ 154static uint8_t esp_read_reg(struct ncr53c9x_softc *sc, int reg); 155static void esp_write_reg(struct ncr53c9x_softc *sc, int reg, uint8_t v); 156static int esp_dma_isintr(struct ncr53c9x_softc *sc); 157static void esp_dma_reset(struct ncr53c9x_softc *sc); 158static int esp_dma_intr(struct ncr53c9x_softc *sc); 159static int esp_dma_setup(struct ncr53c9x_softc *sc, void **addr, 160 size_t *len, int datain, size_t *dmasize); 161static void esp_dma_go(struct ncr53c9x_softc *sc); 162static void esp_dma_stop(struct ncr53c9x_softc *sc); 163static int esp_dma_isactive(struct ncr53c9x_softc *sc); 164static int espattach(struct esp_softc *esc, 165 const struct ncr53c9x_glue *gluep); 166static int espdetach(struct esp_softc *esc); 167 168static const struct ncr53c9x_glue const esp_sbus_glue = { 169 esp_read_reg, 170 esp_write_reg, 171 esp_dma_isintr, 172 esp_dma_reset, 173 esp_dma_intr, 174 esp_dma_setup, 175 esp_dma_go, 176 esp_dma_stop, 177 esp_dma_isactive,
|
178 NULL, /* gl_clear_latched_intr */
| |
179}; 180 181static int 182esp_probe(device_t dev) 183{ 184 const char *name; 185 186 name = ofw_bus_get_name(dev); 187 if (strcmp("SUNW,fas", name) == 0) { 188 device_set_desc(dev, "Sun FAS366 Fast-Wide SCSI"); 189 return (BUS_PROBE_DEFAULT); 190 } else if (strcmp("esp", name) == 0) { 191 device_set_desc(dev, "Sun ESP SCSI/Sun FAS Fast-SCSI"); 192 return (BUS_PROBE_DEFAULT); 193 } 194 195 return (ENXIO); 196} 197 198static int 199esp_sbus_attach(device_t dev) 200{ 201 struct esp_softc *esc; 202 struct ncr53c9x_softc *sc; 203 struct lsi64854_softc *lsc; 204 device_t *children; 205 int error, i, nchildren; 206 207 esc = device_get_softc(dev); 208 sc = &esc->sc_ncr53c9x; 209 210 lsc = NULL; 211 esc->sc_dev = dev; 212 sc->sc_freq = sbus_get_clockfreq(dev); 213 214 if (strcmp(ofw_bus_get_name(dev), "SUNW,fas") == 0) { 215 /* 216 * Allocate space for DMA, in SUNW,fas there are no 217 * separate DMA devices. 218 */ 219 lsc = malloc(sizeof (struct lsi64854_softc), M_DEVBUF, 220 M_NOWAIT | M_ZERO); 221 if (lsc == NULL) { 222 device_printf(dev, "out of memory (lsi64854_softc)\n"); 223 return (ENOMEM); 224 } 225 esc->sc_dma = lsc; 226 227 /* 228 * SUNW,fas have 2 register spaces: DMA (lsi64854) and 229 * SCSI core (ncr53c9x). 230 */ 231 232 /* Allocate DMA registers. */ 233 i = 0; 234 if ((lsc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 235 &i, RF_ACTIVE)) == NULL) { 236 device_printf(dev, "cannot allocate DMA registers\n"); 237 error = ENXIO; 238 goto fail_sbus_lsc; 239 } 240 241 /* Create a parent DMA tag based on this bus. */ 242 error = bus_dma_tag_create( 243 bus_get_dma_tag(dev), /* parent */ 244 1, 0, /* alignment, boundary */ 245 BUS_SPACE_MAXADDR, /* lowaddr */ 246 BUS_SPACE_MAXADDR, /* highaddr */ 247 NULL, NULL, /* filter, filterarg */
| 178}; 179 180static int 181esp_probe(device_t dev) 182{ 183 const char *name; 184 185 name = ofw_bus_get_name(dev); 186 if (strcmp("SUNW,fas", name) == 0) { 187 device_set_desc(dev, "Sun FAS366 Fast-Wide SCSI"); 188 return (BUS_PROBE_DEFAULT); 189 } else if (strcmp("esp", name) == 0) { 190 device_set_desc(dev, "Sun ESP SCSI/Sun FAS Fast-SCSI"); 191 return (BUS_PROBE_DEFAULT); 192 } 193 194 return (ENXIO); 195} 196 197static int 198esp_sbus_attach(device_t dev) 199{ 200 struct esp_softc *esc; 201 struct ncr53c9x_softc *sc; 202 struct lsi64854_softc *lsc; 203 device_t *children; 204 int error, i, nchildren; 205 206 esc = device_get_softc(dev); 207 sc = &esc->sc_ncr53c9x; 208 209 lsc = NULL; 210 esc->sc_dev = dev; 211 sc->sc_freq = sbus_get_clockfreq(dev); 212 213 if (strcmp(ofw_bus_get_name(dev), "SUNW,fas") == 0) { 214 /* 215 * Allocate space for DMA, in SUNW,fas there are no 216 * separate DMA devices. 217 */ 218 lsc = malloc(sizeof (struct lsi64854_softc), M_DEVBUF, 219 M_NOWAIT | M_ZERO); 220 if (lsc == NULL) { 221 device_printf(dev, "out of memory (lsi64854_softc)\n"); 222 return (ENOMEM); 223 } 224 esc->sc_dma = lsc; 225 226 /* 227 * SUNW,fas have 2 register spaces: DMA (lsi64854) and 228 * SCSI core (ncr53c9x). 229 */ 230 231 /* Allocate DMA registers. */ 232 i = 0; 233 if ((lsc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 234 &i, RF_ACTIVE)) == NULL) { 235 device_printf(dev, "cannot allocate DMA registers\n"); 236 error = ENXIO; 237 goto fail_sbus_lsc; 238 } 239 240 /* Create a parent DMA tag based on this bus. */ 241 error = bus_dma_tag_create( 242 bus_get_dma_tag(dev), /* parent */ 243 1, 0, /* alignment, boundary */ 244 BUS_SPACE_MAXADDR, /* lowaddr */ 245 BUS_SPACE_MAXADDR, /* highaddr */ 246 NULL, NULL, /* filter, filterarg */
|
248 BUS_SPACE_MAXSIZE_32BIT, /* maxsize */ 249 0, /* nsegments */ 250 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
| 247 BUS_SPACE_MAXSIZE, /* maxsize */ 248 BUS_SPACE_UNRESTRICTED, /* nsegments */ 249 BUS_SPACE_MAXSIZE, /* maxsegsize */
|
251 0, /* flags */ 252 NULL, NULL, /* no locking */ 253 &lsc->sc_parent_dmat); 254 if (error != 0) { 255 device_printf(dev, "cannot allocate parent DMA tag\n"); 256 goto fail_sbus_lres; 257 } 258 259 i = sbus_get_burstsz(dev); 260 261#ifdef ESP_SBUS_DEBUG 262 printf("%s: burst 0x%x\n", __func__, i); 263#endif 264 265 lsc->sc_burst = (i & SBUS_BURST_32) ? 32 : 266 (i & SBUS_BURST_16) ? 16 : 0; 267 268 lsc->sc_channel = L64854_CHANNEL_SCSI; 269 lsc->sc_client = sc; 270 lsc->sc_dev = dev; 271 272 /* 273 * Allocate SCSI core registers. 274 */ 275 i = 1; 276 if ((esc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 277 &i, RF_ACTIVE)) == NULL) { 278 device_printf(dev, 279 "cannot allocate SCSI core registers\n"); 280 error = ENXIO; 281 goto fail_sbus_lpdma; 282 } 283 } else { 284 /* 285 * Search accompanying DMA engine. It should have been 286 * already attached otherwise there isn't much we can do. 287 */ 288 if (device_get_children(device_get_parent(dev), &children, 289 &nchildren) != 0) { 290 device_printf(dev, "cannot determine siblings\n"); 291 return (ENXIO); 292 } 293 for (i = 0; i < nchildren; i++) { 294 if (device_is_attached(children[i]) &&
| 250 0, /* flags */ 251 NULL, NULL, /* no locking */ 252 &lsc->sc_parent_dmat); 253 if (error != 0) { 254 device_printf(dev, "cannot allocate parent DMA tag\n"); 255 goto fail_sbus_lres; 256 } 257 258 i = sbus_get_burstsz(dev); 259 260#ifdef ESP_SBUS_DEBUG 261 printf("%s: burst 0x%x\n", __func__, i); 262#endif 263 264 lsc->sc_burst = (i & SBUS_BURST_32) ? 32 : 265 (i & SBUS_BURST_16) ? 16 : 0; 266 267 lsc->sc_channel = L64854_CHANNEL_SCSI; 268 lsc->sc_client = sc; 269 lsc->sc_dev = dev; 270 271 /* 272 * Allocate SCSI core registers. 273 */ 274 i = 1; 275 if ((esc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 276 &i, RF_ACTIVE)) == NULL) { 277 device_printf(dev, 278 "cannot allocate SCSI core registers\n"); 279 error = ENXIO; 280 goto fail_sbus_lpdma; 281 } 282 } else { 283 /* 284 * Search accompanying DMA engine. It should have been 285 * already attached otherwise there isn't much we can do. 286 */ 287 if (device_get_children(device_get_parent(dev), &children, 288 &nchildren) != 0) { 289 device_printf(dev, "cannot determine siblings\n"); 290 return (ENXIO); 291 } 292 for (i = 0; i < nchildren; i++) { 293 if (device_is_attached(children[i]) &&
|
295 sbus_get_slot(children[i]) == sbus_get_slot(dev) && 296 strcmp(ofw_bus_get_name(children[i]), "dma") == 0) {
| 294 sbus_get_slot(children[i]) == 295 sbus_get_slot(dev) && 296 strcmp(ofw_bus_get_name(children[i]), 297 "dma") == 0) {
|
297 /* XXX hackery */ 298 esc->sc_dma = (struct lsi64854_softc *) 299 device_get_softc(children[i]); 300 break; 301 } 302 } 303 free(children, M_TEMP); 304 if (esc->sc_dma == NULL) { 305 device_printf(dev, "cannot find DMA engine\n"); 306 return (ENXIO); 307 } 308 esc->sc_dma->sc_client = sc; 309 310 /* 311 * Allocate SCSI core registers. 312 */ 313 i = 0; 314 if ((esc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 315 &i, RF_ACTIVE)) == NULL) { 316 device_printf(dev, 317 "cannot allocate SCSI core registers\n"); 318 return (ENXIO); 319 } 320 } 321 322 error = espattach(esc, &esp_sbus_glue); 323 if (error != 0) { 324 device_printf(dev, "espattach failed\n"); 325 goto fail_sbus_eres; 326 } 327 328 return (0); 329 330 fail_sbus_eres: 331 bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(esc->sc_res), 332 esc->sc_res); 333 if (strcmp(ofw_bus_get_name(dev), "SUNW,fas") != 0) 334 return (error); 335 fail_sbus_lpdma: 336 bus_dma_tag_destroy(lsc->sc_parent_dmat); 337 fail_sbus_lres: 338 bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(lsc->sc_res), 339 lsc->sc_res); 340 fail_sbus_lsc: 341 free(lsc, M_DEVBUF); 342 return (error); 343} 344 345static int 346esp_sbus_detach(device_t dev) 347{ 348 struct esp_softc *esc; 349 struct lsi64854_softc *lsc; 350 int error; 351 352 esc = device_get_softc(dev); 353 lsc = esc->sc_dma; 354 355 error = espdetach(esc); 356 if (error != 0) 357 return (error); 358 bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(esc->sc_res), 359 esc->sc_res); 360 if (strcmp(ofw_bus_get_name(dev), "SUNW,fas") != 0) 361 return (0); 362 bus_dma_tag_destroy(lsc->sc_parent_dmat); 363 bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(lsc->sc_res), 364 lsc->sc_res); 365 free(lsc, M_DEVBUF); 366 367 return (0); 368} 369 370static int 371esp_dma_attach(device_t dev) 372{ 373 struct esp_softc *esc; 374 struct ncr53c9x_softc *sc; 375 int error, i; 376 377 esc = device_get_softc(dev); 378 sc = &esc->sc_ncr53c9x; 379 380 esc->sc_dev = dev; 381 if (OF_getprop(ofw_bus_get_node(dev), "clock-frequency", 382 &sc->sc_freq, sizeof(sc->sc_freq)) == -1) { 383 printf("failed to query OFW for clock-frequency\n"); 384 return (ENXIO); 385 } 386 387 /* XXX hackery */ 388 esc->sc_dma = (struct lsi64854_softc *) 389 device_get_softc(device_get_parent(dev)); 390 esc->sc_dma->sc_client = sc; 391 392 /* 393 * Allocate SCSI core registers. 394 */ 395 i = 0; 396 if ((esc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 397 &i, RF_ACTIVE)) == NULL) { 398 device_printf(dev, "cannot allocate SCSI core registers\n"); 399 return (ENXIO); 400 } 401 402 error = espattach(esc, &esp_sbus_glue); 403 if (error != 0) { 404 device_printf(dev, "espattach failed\n"); 405 goto fail_dma_eres; 406 } 407 408 return (0); 409 410 fail_dma_eres: 411 bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(esc->sc_res), 412 esc->sc_res); 413 return (error); 414} 415 416static int 417esp_dma_detach(device_t dev) 418{ 419 struct esp_softc *esc; 420 int error; 421 422 esc = device_get_softc(dev); 423 424 error = espdetach(esc); 425 if (error != 0) 426 return (error); 427 bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(esc->sc_res), 428 esc->sc_res); 429 430 return (0); 431} 432 433static int 434esp_suspend(device_t dev) 435{ 436 437 return (ENXIO); 438} 439 440static int 441esp_resume(device_t dev) 442{ 443 444 return (ENXIO); 445} 446 447static int 448espattach(struct esp_softc *esc, const struct ncr53c9x_glue *gluep) 449{ 450 struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x; 451 unsigned int uid = 0; 452 int error, i; 453 454 NCR_LOCK_INIT(sc); 455
| 298 /* XXX hackery */ 299 esc->sc_dma = (struct lsi64854_softc *) 300 device_get_softc(children[i]); 301 break; 302 } 303 } 304 free(children, M_TEMP); 305 if (esc->sc_dma == NULL) { 306 device_printf(dev, "cannot find DMA engine\n"); 307 return (ENXIO); 308 } 309 esc->sc_dma->sc_client = sc; 310 311 /* 312 * Allocate SCSI core registers. 313 */ 314 i = 0; 315 if ((esc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 316 &i, RF_ACTIVE)) == NULL) { 317 device_printf(dev, 318 "cannot allocate SCSI core registers\n"); 319 return (ENXIO); 320 } 321 } 322 323 error = espattach(esc, &esp_sbus_glue); 324 if (error != 0) { 325 device_printf(dev, "espattach failed\n"); 326 goto fail_sbus_eres; 327 } 328 329 return (0); 330 331 fail_sbus_eres: 332 bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(esc->sc_res), 333 esc->sc_res); 334 if (strcmp(ofw_bus_get_name(dev), "SUNW,fas") != 0) 335 return (error); 336 fail_sbus_lpdma: 337 bus_dma_tag_destroy(lsc->sc_parent_dmat); 338 fail_sbus_lres: 339 bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(lsc->sc_res), 340 lsc->sc_res); 341 fail_sbus_lsc: 342 free(lsc, M_DEVBUF); 343 return (error); 344} 345 346static int 347esp_sbus_detach(device_t dev) 348{ 349 struct esp_softc *esc; 350 struct lsi64854_softc *lsc; 351 int error; 352 353 esc = device_get_softc(dev); 354 lsc = esc->sc_dma; 355 356 error = espdetach(esc); 357 if (error != 0) 358 return (error); 359 bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(esc->sc_res), 360 esc->sc_res); 361 if (strcmp(ofw_bus_get_name(dev), "SUNW,fas") != 0) 362 return (0); 363 bus_dma_tag_destroy(lsc->sc_parent_dmat); 364 bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(lsc->sc_res), 365 lsc->sc_res); 366 free(lsc, M_DEVBUF); 367 368 return (0); 369} 370 371static int 372esp_dma_attach(device_t dev) 373{ 374 struct esp_softc *esc; 375 struct ncr53c9x_softc *sc; 376 int error, i; 377 378 esc = device_get_softc(dev); 379 sc = &esc->sc_ncr53c9x; 380 381 esc->sc_dev = dev; 382 if (OF_getprop(ofw_bus_get_node(dev), "clock-frequency", 383 &sc->sc_freq, sizeof(sc->sc_freq)) == -1) { 384 printf("failed to query OFW for clock-frequency\n"); 385 return (ENXIO); 386 } 387 388 /* XXX hackery */ 389 esc->sc_dma = (struct lsi64854_softc *) 390 device_get_softc(device_get_parent(dev)); 391 esc->sc_dma->sc_client = sc; 392 393 /* 394 * Allocate SCSI core registers. 395 */ 396 i = 0; 397 if ((esc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 398 &i, RF_ACTIVE)) == NULL) { 399 device_printf(dev, "cannot allocate SCSI core registers\n"); 400 return (ENXIO); 401 } 402 403 error = espattach(esc, &esp_sbus_glue); 404 if (error != 0) { 405 device_printf(dev, "espattach failed\n"); 406 goto fail_dma_eres; 407 } 408 409 return (0); 410 411 fail_dma_eres: 412 bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(esc->sc_res), 413 esc->sc_res); 414 return (error); 415} 416 417static int 418esp_dma_detach(device_t dev) 419{ 420 struct esp_softc *esc; 421 int error; 422 423 esc = device_get_softc(dev); 424 425 error = espdetach(esc); 426 if (error != 0) 427 return (error); 428 bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(esc->sc_res), 429 esc->sc_res); 430 431 return (0); 432} 433 434static int 435esp_suspend(device_t dev) 436{ 437 438 return (ENXIO); 439} 440 441static int 442esp_resume(device_t dev) 443{ 444 445 return (ENXIO); 446} 447 448static int 449espattach(struct esp_softc *esc, const struct ncr53c9x_glue *gluep) 450{ 451 struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x; 452 unsigned int uid = 0; 453 int error, i; 454 455 NCR_LOCK_INIT(sc); 456
|
456 /* Attach the DMA engine. */ 457 error = lsi64854_attach(esc->sc_dma); 458 if (error != 0) { 459 device_printf(esc->sc_dev, "lsi64854_attach failed\n"); 460 goto fail_lock; 461 } 462
| |
463 sc->sc_id = OF_getscsinitid(esc->sc_dev); 464 465#ifdef ESP_SBUS_DEBUG 466 device_printf(esc->sc_dev, "%s: sc_id %d, freq %d\n", 467 __func__, sc->sc_id, sc->sc_freq); 468#endif 469 470 /* 471 * The `ESC' DMA chip must be reset before we can access 472 * the ESP registers. 473 */ 474 if (esc->sc_dma->sc_rev == DMAREV_ESC) 475 DMA_RESET(esc->sc_dma); 476 477 /* 478 * Set up glue for MI code early; we use some of it here. 479 */ 480 sc->sc_glue = gluep; 481 482 /* gimme MHz */ 483 sc->sc_freq /= 1000000; 484 485 /* 486 * XXX More of this should be in ncr53c9x_attach(), but 487 * XXX should we really poke around the chip that much in 488 * XXX the MI code? Think about this more... 489 */ 490 491 /* 492 * Read the part-unique ID code of the SCSI chip. The contained 493 * value is only valid if all of the following conditions are met: 494 * - After power-up or chip reset. 495 * - Before any value is written to this register. 496 * - The NCRCFG2_FE bit is set. 497 * - A (NCRCMD_NOP | NCRCMD_DMA) command has been issued. 498 */ 499 NCRCMD(sc, NCRCMD_RSTCHIP); 500 NCRCMD(sc, NCRCMD_NOP); 501 sc->sc_cfg2 = NCRCFG2_FE; 502 NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2); 503 NCRCMD(sc, NCRCMD_NOP | NCRCMD_DMA); 504 uid = NCR_READ_REG(sc, NCR_UID); 505 506 /* 507 * It is necessary to try to load the 2nd config register here, 508 * to find out what rev the esp chip is, else the ncr53c9x_reset 509 * will not set up the defaults correctly. 510 */ 511 sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB; 512 NCR_WRITE_REG(sc, NCR_CFG1, sc->sc_cfg1); 513 sc->sc_cfg2 = 0; 514 NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2); 515 sc->sc_cfg2 = NCRCFG2_SCSI2 | NCRCFG2_RPE; 516 NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2); 517 518 if ((NCR_READ_REG(sc, NCR_CFG2) & ~NCRCFG2_RSVD) !=
| 457 sc->sc_id = OF_getscsinitid(esc->sc_dev); 458 459#ifdef ESP_SBUS_DEBUG 460 device_printf(esc->sc_dev, "%s: sc_id %d, freq %d\n", 461 __func__, sc->sc_id, sc->sc_freq); 462#endif 463 464 /* 465 * The `ESC' DMA chip must be reset before we can access 466 * the ESP registers. 467 */ 468 if (esc->sc_dma->sc_rev == DMAREV_ESC) 469 DMA_RESET(esc->sc_dma); 470 471 /* 472 * Set up glue for MI code early; we use some of it here. 473 */ 474 sc->sc_glue = gluep; 475 476 /* gimme MHz */ 477 sc->sc_freq /= 1000000; 478 479 /* 480 * XXX More of this should be in ncr53c9x_attach(), but 481 * XXX should we really poke around the chip that much in 482 * XXX the MI code? Think about this more... 483 */ 484 485 /* 486 * Read the part-unique ID code of the SCSI chip. The contained 487 * value is only valid if all of the following conditions are met: 488 * - After power-up or chip reset. 489 * - Before any value is written to this register. 490 * - The NCRCFG2_FE bit is set. 491 * - A (NCRCMD_NOP | NCRCMD_DMA) command has been issued. 492 */ 493 NCRCMD(sc, NCRCMD_RSTCHIP); 494 NCRCMD(sc, NCRCMD_NOP); 495 sc->sc_cfg2 = NCRCFG2_FE; 496 NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2); 497 NCRCMD(sc, NCRCMD_NOP | NCRCMD_DMA); 498 uid = NCR_READ_REG(sc, NCR_UID); 499 500 /* 501 * It is necessary to try to load the 2nd config register here, 502 * to find out what rev the esp chip is, else the ncr53c9x_reset 503 * will not set up the defaults correctly. 504 */ 505 sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB; 506 NCR_WRITE_REG(sc, NCR_CFG1, sc->sc_cfg1); 507 sc->sc_cfg2 = 0; 508 NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2); 509 sc->sc_cfg2 = NCRCFG2_SCSI2 | NCRCFG2_RPE; 510 NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2); 511 512 if ((NCR_READ_REG(sc, NCR_CFG2) & ~NCRCFG2_RSVD) !=
|
519 (NCRCFG2_SCSI2 | NCRCFG2_RPE)) {
| 513 (NCRCFG2_SCSI2 | NCRCFG2_RPE))
|
520 sc->sc_rev = NCR_VARIANT_ESP100;
| 514 sc->sc_rev = NCR_VARIANT_ESP100;
|
521 } else {
| 515 else {
|
522 sc->sc_cfg2 = NCRCFG2_SCSI2; 523 NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2); 524 sc->sc_cfg3 = 0; 525 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3); 526 sc->sc_cfg3 = (NCRCFG3_CDB | NCRCFG3_FCLK); 527 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3); 528 if (NCR_READ_REG(sc, NCR_CFG3) !=
| 516 sc->sc_cfg2 = NCRCFG2_SCSI2; 517 NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2); 518 sc->sc_cfg3 = 0; 519 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3); 520 sc->sc_cfg3 = (NCRCFG3_CDB | NCRCFG3_FCLK); 521 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3); 522 if (NCR_READ_REG(sc, NCR_CFG3) !=
|
529 (NCRCFG3_CDB | NCRCFG3_FCLK)) {
| 523 (NCRCFG3_CDB | NCRCFG3_FCLK))
|
530 sc->sc_rev = NCR_VARIANT_ESP100A;
| 524 sc->sc_rev = NCR_VARIANT_ESP100A;
|
531 } else {
| 525 else {
|
532 /* NCRCFG2_FE enables > 64K transfers. */ 533 sc->sc_cfg2 |= NCRCFG2_FE; 534 sc->sc_cfg3 = 0; 535 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3); 536 if (sc->sc_freq <= 25) 537 sc->sc_rev = NCR_VARIANT_ESP200; 538 else { 539 switch ((uid & 0xf8) >> 3) { 540 case 0x00: 541 sc->sc_rev = NCR_VARIANT_FAS100A; 542 break; 543 544 case 0x02: 545 if ((uid & 0x07) == 0x02)
| 526 /* NCRCFG2_FE enables > 64K transfers. */ 527 sc->sc_cfg2 |= NCRCFG2_FE; 528 sc->sc_cfg3 = 0; 529 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3); 530 if (sc->sc_freq <= 25) 531 sc->sc_rev = NCR_VARIANT_ESP200; 532 else { 533 switch ((uid & 0xf8) >> 3) { 534 case 0x00: 535 sc->sc_rev = NCR_VARIANT_FAS100A; 536 break; 537 538 case 0x02: 539 if ((uid & 0x07) == 0x02)
|
546 sc->sc_rev = NCR_VARIANT_FAS216;
| 540 sc->sc_rev = 541 NCR_VARIANT_FAS216;
|
547 else
| 542 else
|
548 sc->sc_rev = NCR_VARIANT_FAS236;
| 543 sc->sc_rev = 544 NCR_VARIANT_FAS236;
|
549 break; 550 551 case 0x0a: 552 sc->sc_rev = NCR_VARIANT_FAS366; 553 break; 554 555 default: 556 /* 557 * We could just treat unknown chips 558 * as ESP200 but then we would most 559 * likely drive them out of specs. 560 */ 561 device_printf(esc->sc_dev, 562 "Unknown chip\n");
| 545 break; 546 547 case 0x0a: 548 sc->sc_rev = NCR_VARIANT_FAS366; 549 break; 550 551 default: 552 /* 553 * We could just treat unknown chips 554 * as ESP200 but then we would most 555 * likely drive them out of specs. 556 */ 557 device_printf(esc->sc_dev, 558 "Unknown chip\n");
|
563 goto fail_lsi;
| 559 error = ENXIO; 560 goto fail_lock;
|
564 } 565 } 566 } 567 } 568 569#ifdef ESP_SBUS_DEBUG 570 printf("%s: revision %d, uid 0x%x\n", __func__, sc->sc_rev, uid); 571#endif 572 573 /*
| 561 } 562 } 563 } 564 } 565 566#ifdef ESP_SBUS_DEBUG 567 printf("%s: revision %d, uid 0x%x\n", __func__, sc->sc_rev, uid); 568#endif 569 570 /*
|
574 * XXX minsync and maxxfer _should_ be set up in MI code, 575 * XXX but it appears to have some dependency on what sort 576 * XXX of DMA we're hooked up to, etc. 577 */ 578 579 /*
| |
580 * This is the value used to start sync negotiations 581 * Note that the NCR register "SYNCTP" is programmed 582 * in "clocks per byte", and has a minimum value of 4. 583 * The SCSI period used in negotiation is one-fourth 584 * of the time (in nanoseconds) needed to transfer one byte. 585 * Since the chip's clock is given in MHz, we have the following 586 * formula: 4 * period = (1000 / freq) * 4 587 */ 588 sc->sc_minsync = 1000 / sc->sc_freq; 589
| 571 * This is the value used to start sync negotiations 572 * Note that the NCR register "SYNCTP" is programmed 573 * in "clocks per byte", and has a minimum value of 4. 574 * The SCSI period used in negotiation is one-fourth 575 * of the time (in nanoseconds) needed to transfer one byte. 576 * Since the chip's clock is given in MHz, we have the following 577 * formula: 4 * period = (1000 / freq) * 4 578 */ 579 sc->sc_minsync = 1000 / sc->sc_freq; 580
|
| 581 /* 582 * Except for some variants the maximum transfer size is 64k. 583 */ 584 sc->sc_maxxfer = 64 * 1024;
|
590 sc->sc_maxoffset = 15; 591 sc->sc_extended_geom = 1; 592 593 /* 594 * Alas, we must now modify the value a bit, because it's
| 585 sc->sc_maxoffset = 15; 586 sc->sc_extended_geom = 1; 587 588 /* 589 * Alas, we must now modify the value a bit, because it's
|
595 * only valid when can switch on FASTCLK and FASTSCSI bits 596 * in config register 3...
| 590 * only valid when we can switch on FASTCLK and FASTSCSI bits 591 * in the config register 3...
|
597 */ 598 switch (sc->sc_rev) { 599 case NCR_VARIANT_ESP100: 600 sc->sc_maxwidth = MSG_EXT_WDTR_BUS_8_BIT;
| 592 */ 593 switch (sc->sc_rev) { 594 case NCR_VARIANT_ESP100: 595 sc->sc_maxwidth = MSG_EXT_WDTR_BUS_8_BIT;
|
601 sc->sc_maxxfer = 64 * 1024;
| |
602 sc->sc_minsync = 0; /* No synch on old chip? */ 603 break; 604 605 case NCR_VARIANT_ESP100A:
| 596 sc->sc_minsync = 0; /* No synch on old chip? */ 597 break; 598 599 case NCR_VARIANT_ESP100A:
|
606 sc->sc_maxwidth = MSG_EXT_WDTR_BUS_8_BIT; 607 sc->sc_maxxfer = 64 * 1024; 608 /* Min clocks/byte is 5 */ 609 sc->sc_minsync = ncr53c9x_cpb2stp(sc, 5); 610 break; 611
| |
612 case NCR_VARIANT_ESP200: 613 sc->sc_maxwidth = MSG_EXT_WDTR_BUS_8_BIT;
| 600 case NCR_VARIANT_ESP200: 601 sc->sc_maxwidth = MSG_EXT_WDTR_BUS_8_BIT;
|
614 sc->sc_maxxfer = 16 * 1024 * 1024;
| |
615 /* Min clocks/byte is 5 */ 616 sc->sc_minsync = ncr53c9x_cpb2stp(sc, 5); 617 break; 618 619 case NCR_VARIANT_FAS100A: 620 case NCR_VARIANT_FAS216: 621 case NCR_VARIANT_FAS236: 622 /* 623 * The onboard SCSI chips in Sun Ultra 1 are actually 624 * documented to be NCR53C9X which use NCRCFG3_FCLK and 625 * NCRCFG3_FSCSI. BSD/OS however probes these chips as 626 * FAS100A and uses NCRF9XCFG3_FCLK and NCRF9XCFG3_FSCSI 627 * instead which seems to be correct as otherwise sync 628 * negotiation just doesn't work. Using NCRF9XCFG3_FCLK 629 * and NCRF9XCFG3_FSCSI with these chips in fact also 630 * yields Fast-SCSI speed. 631 */ 632 sc->sc_features = NCR_F_FASTSCSI; 633 sc->sc_cfg3 = NCRF9XCFG3_FCLK; 634 sc->sc_cfg3_fscsi = NCRF9XCFG3_FSCSI; 635 sc->sc_maxwidth = MSG_EXT_WDTR_BUS_8_BIT; 636 sc->sc_maxxfer = 16 * 1024 * 1024; 637 break; 638 639 case NCR_VARIANT_FAS366: 640 sc->sc_maxwidth = MSG_EXT_WDTR_BUS_16_BIT; 641 sc->sc_maxxfer = 16 * 1024 * 1024; 642 break; 643 } 644
| 602 /* Min clocks/byte is 5 */ 603 sc->sc_minsync = ncr53c9x_cpb2stp(sc, 5); 604 break; 605 606 case NCR_VARIANT_FAS100A: 607 case NCR_VARIANT_FAS216: 608 case NCR_VARIANT_FAS236: 609 /* 610 * The onboard SCSI chips in Sun Ultra 1 are actually 611 * documented to be NCR53C9X which use NCRCFG3_FCLK and 612 * NCRCFG3_FSCSI. BSD/OS however probes these chips as 613 * FAS100A and uses NCRF9XCFG3_FCLK and NCRF9XCFG3_FSCSI 614 * instead which seems to be correct as otherwise sync 615 * negotiation just doesn't work. Using NCRF9XCFG3_FCLK 616 * and NCRF9XCFG3_FSCSI with these chips in fact also 617 * yields Fast-SCSI speed. 618 */ 619 sc->sc_features = NCR_F_FASTSCSI; 620 sc->sc_cfg3 = NCRF9XCFG3_FCLK; 621 sc->sc_cfg3_fscsi = NCRF9XCFG3_FSCSI; 622 sc->sc_maxwidth = MSG_EXT_WDTR_BUS_8_BIT; 623 sc->sc_maxxfer = 16 * 1024 * 1024; 624 break; 625 626 case NCR_VARIANT_FAS366: 627 sc->sc_maxwidth = MSG_EXT_WDTR_BUS_16_BIT; 628 sc->sc_maxxfer = 16 * 1024 * 1024; 629 break; 630 } 631
|
| 632 /* 633 * Given that we allocate resources based on sc->sc_maxxfer it doesn't 634 * make sense to supply a value higher than the maximum actually used. 635 */ 636 sc->sc_maxxfer = min(sc->sc_maxxfer, MAXPHYS); 637 638 /* Attach the DMA engine. */ 639 error = lsi64854_attach(esc->sc_dma); 640 if (error != 0) { 641 device_printf(esc->sc_dev, "lsi64854_attach failed\n"); 642 goto fail_lock; 643 } 644
|
645 /* Establish interrupt channel. */ 646 i = 0; 647 if ((esc->sc_irqres = bus_alloc_resource_any(esc->sc_dev, SYS_RES_IRQ, 648 &i, RF_SHAREABLE|RF_ACTIVE)) == NULL) { 649 device_printf(esc->sc_dev, "cannot allocate interrupt\n"); 650 goto fail_lsi; 651 } 652 if (bus_setup_intr(esc->sc_dev, esc->sc_irqres, 653 INTR_MPSAFE | INTR_TYPE_CAM, NULL, ncr53c9x_intr, sc, 654 &esc->sc_irq)) { 655 device_printf(esc->sc_dev, "cannot set up interrupt\n"); 656 error = ENXIO; 657 goto fail_ires; 658 } 659 660 /* Turn on target selection using the `DMA' method. */ 661 if (sc->sc_rev != NCR_VARIANT_FAS366) 662 sc->sc_features |= NCR_F_DMASELECT; 663 664 /* Do the common parts of attachment. */ 665 sc->sc_dev = esc->sc_dev; 666 error = ncr53c9x_attach(sc); 667 if (error != 0) { 668 device_printf(esc->sc_dev, "ncr53c9x_attach failed\n"); 669 goto fail_intr; 670 } 671 672 return (0); 673 674 fail_intr: 675 bus_teardown_intr(esc->sc_dev, esc->sc_irqres, esc->sc_irq); 676 fail_ires: 677 bus_release_resource(esc->sc_dev, SYS_RES_IRQ, 678 rman_get_rid(esc->sc_irqres), esc->sc_irqres); 679 fail_lsi: 680 lsi64854_detach(esc->sc_dma); 681 fail_lock: 682 NCR_LOCK_DESTROY(sc); 683 return (error); 684} 685 686static int 687espdetach(struct esp_softc *esc) 688{ 689 struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x; 690 int error; 691 692 bus_teardown_intr(esc->sc_dev, esc->sc_irqres, esc->sc_irq); 693 error = ncr53c9x_detach(sc); 694 if (error != 0) 695 return (error); 696 error = lsi64854_detach(esc->sc_dma); 697 if (error != 0) 698 return (error); 699 NCR_LOCK_DESTROY(sc); 700 bus_release_resource(esc->sc_dev, SYS_RES_IRQ, 701 rman_get_rid(esc->sc_irqres), esc->sc_irqres); 702 703 return (0); 704} 705 706/* 707 * Glue functions 708 */ 709 710#ifdef ESP_SBUS_DEBUG 711static int esp_sbus_debug = 0; 712 713static const struct { 714 const char *r_name; 715 int r_flag; 716} const esp__read_regnames [] = { 717 { "TCL", 0}, /* 0/00 */ 718 { "TCM", 0}, /* 1/04 */ 719 { "FIFO", 0}, /* 2/08 */ 720 { "CMD", 0}, /* 3/0c */ 721 { "STAT", 0}, /* 4/10 */ 722 { "INTR", 0}, /* 5/14 */ 723 { "STEP", 0}, /* 6/18 */ 724 { "FFLAGS", 1}, /* 7/1c */ 725 { "CFG1", 1}, /* 8/20 */ 726 { "STAT2", 0}, /* 9/24 */ 727 { "CFG4", 1}, /* a/28 */ 728 { "CFG2", 1}, /* b/2c */ 729 { "CFG3", 1}, /* c/30 */ 730 { "-none", 1}, /* d/34 */ 731 { "TCH", 1}, /* e/38 */ 732 { "TCX", 1}, /* f/3c */ 733}; 734 735static const const struct { 736 const char *r_name; 737 int r_flag; 738} const esp__write_regnames[] = { 739 { "TCL", 1}, /* 0/00 */ 740 { "TCM", 1}, /* 1/04 */ 741 { "FIFO", 0}, /* 2/08 */ 742 { "CMD", 0}, /* 3/0c */ 743 { "SELID", 1}, /* 4/10 */ 744 { "TIMEOUT", 1}, /* 5/14 */ 745 { "SYNCTP", 1}, /* 6/18 */ 746 { "SYNCOFF", 1}, /* 7/1c */ 747 { "CFG1", 1}, /* 8/20 */ 748 { "CCF", 1}, /* 9/24 */ 749 { "TEST", 1}, /* a/28 */ 750 { "CFG2", 1}, /* b/2c */ 751 { "CFG3", 1}, /* c/30 */ 752 { "-none", 1}, /* d/34 */ 753 { "TCH", 1}, /* e/38 */ 754 { "TCX", 1}, /* f/3c */ 755}; 756#endif 757 758static uint8_t 759esp_read_reg(struct ncr53c9x_softc *sc, int reg) 760{ 761 struct esp_softc *esc = (struct esp_softc *)sc; 762 uint8_t v; 763 764 v = bus_read_1(esc->sc_res, reg * 4); 765 766#ifdef ESP_SBUS_DEBUG 767 if (esp_sbus_debug && (reg < 0x10) && esp__read_regnames[reg].r_flag) 768 printf("RD:%x <%s> %x\n", reg * 4, ((unsigned)reg < 0x10) ? 769 esp__read_regnames[reg].r_name : "<***>", v); 770#endif 771 772 return (v); 773} 774 775static void 776esp_write_reg(struct ncr53c9x_softc *sc, int reg, uint8_t v) 777{ 778 struct esp_softc *esc = (struct esp_softc *)sc; 779 780#ifdef ESP_SBUS_DEBUG 781 if (esp_sbus_debug && (reg < 0x10) && esp__write_regnames[reg].r_flag) 782 printf("WR:%x <%s> %x\n", reg * 4, ((unsigned)reg < 0x10) ? 783 esp__write_regnames[reg].r_name : "<***>", v); 784#endif 785 786 bus_write_1(esc->sc_res, reg * 4, v); 787} 788 789static int 790esp_dma_isintr(struct ncr53c9x_softc *sc) 791{ 792 struct esp_softc *esc = (struct esp_softc *)sc; 793 794 return (DMA_ISINTR(esc->sc_dma)); 795} 796 797static void 798esp_dma_reset(struct ncr53c9x_softc *sc) 799{ 800 struct esp_softc *esc = (struct esp_softc *)sc; 801 802 DMA_RESET(esc->sc_dma); 803} 804 805static int 806esp_dma_intr(struct ncr53c9x_softc *sc) 807{ 808 struct esp_softc *esc = (struct esp_softc *)sc; 809 810 return (DMA_INTR(esc->sc_dma)); 811} 812 813static int 814esp_dma_setup(struct ncr53c9x_softc *sc, void **addr, size_t *len, 815 int datain, size_t *dmasize) 816{ 817 struct esp_softc *esc = (struct esp_softc *)sc; 818 819 return (DMA_SETUP(esc->sc_dma, addr, len, datain, dmasize)); 820} 821 822static void 823esp_dma_go(struct ncr53c9x_softc *sc) 824{ 825 struct esp_softc *esc = (struct esp_softc *)sc; 826 827 DMA_GO(esc->sc_dma); 828} 829 830static void 831esp_dma_stop(struct ncr53c9x_softc *sc) 832{ 833 struct esp_softc *esc = (struct esp_softc *)sc; 834 835 L64854_SCSR(esc->sc_dma, L64854_GCSR(esc->sc_dma) & ~D_EN_DMA); 836} 837 838static int 839esp_dma_isactive(struct ncr53c9x_softc *sc) 840{ 841 struct esp_softc *esc = (struct esp_softc *)sc; 842 843 return (DMA_ISACTIVE(esc->sc_dma)); 844}
| 645 /* Establish interrupt channel. */ 646 i = 0; 647 if ((esc->sc_irqres = bus_alloc_resource_any(esc->sc_dev, SYS_RES_IRQ, 648 &i, RF_SHAREABLE|RF_ACTIVE)) == NULL) { 649 device_printf(esc->sc_dev, "cannot allocate interrupt\n"); 650 goto fail_lsi; 651 } 652 if (bus_setup_intr(esc->sc_dev, esc->sc_irqres, 653 INTR_MPSAFE | INTR_TYPE_CAM, NULL, ncr53c9x_intr, sc, 654 &esc->sc_irq)) { 655 device_printf(esc->sc_dev, "cannot set up interrupt\n"); 656 error = ENXIO; 657 goto fail_ires; 658 } 659 660 /* Turn on target selection using the `DMA' method. */ 661 if (sc->sc_rev != NCR_VARIANT_FAS366) 662 sc->sc_features |= NCR_F_DMASELECT; 663 664 /* Do the common parts of attachment. */ 665 sc->sc_dev = esc->sc_dev; 666 error = ncr53c9x_attach(sc); 667 if (error != 0) { 668 device_printf(esc->sc_dev, "ncr53c9x_attach failed\n"); 669 goto fail_intr; 670 } 671 672 return (0); 673 674 fail_intr: 675 bus_teardown_intr(esc->sc_dev, esc->sc_irqres, esc->sc_irq); 676 fail_ires: 677 bus_release_resource(esc->sc_dev, SYS_RES_IRQ, 678 rman_get_rid(esc->sc_irqres), esc->sc_irqres); 679 fail_lsi: 680 lsi64854_detach(esc->sc_dma); 681 fail_lock: 682 NCR_LOCK_DESTROY(sc); 683 return (error); 684} 685 686static int 687espdetach(struct esp_softc *esc) 688{ 689 struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x; 690 int error; 691 692 bus_teardown_intr(esc->sc_dev, esc->sc_irqres, esc->sc_irq); 693 error = ncr53c9x_detach(sc); 694 if (error != 0) 695 return (error); 696 error = lsi64854_detach(esc->sc_dma); 697 if (error != 0) 698 return (error); 699 NCR_LOCK_DESTROY(sc); 700 bus_release_resource(esc->sc_dev, SYS_RES_IRQ, 701 rman_get_rid(esc->sc_irqres), esc->sc_irqres); 702 703 return (0); 704} 705 706/* 707 * Glue functions 708 */ 709 710#ifdef ESP_SBUS_DEBUG 711static int esp_sbus_debug = 0; 712 713static const struct { 714 const char *r_name; 715 int r_flag; 716} const esp__read_regnames [] = { 717 { "TCL", 0}, /* 0/00 */ 718 { "TCM", 0}, /* 1/04 */ 719 { "FIFO", 0}, /* 2/08 */ 720 { "CMD", 0}, /* 3/0c */ 721 { "STAT", 0}, /* 4/10 */ 722 { "INTR", 0}, /* 5/14 */ 723 { "STEP", 0}, /* 6/18 */ 724 { "FFLAGS", 1}, /* 7/1c */ 725 { "CFG1", 1}, /* 8/20 */ 726 { "STAT2", 0}, /* 9/24 */ 727 { "CFG4", 1}, /* a/28 */ 728 { "CFG2", 1}, /* b/2c */ 729 { "CFG3", 1}, /* c/30 */ 730 { "-none", 1}, /* d/34 */ 731 { "TCH", 1}, /* e/38 */ 732 { "TCX", 1}, /* f/3c */ 733}; 734 735static const const struct { 736 const char *r_name; 737 int r_flag; 738} const esp__write_regnames[] = { 739 { "TCL", 1}, /* 0/00 */ 740 { "TCM", 1}, /* 1/04 */ 741 { "FIFO", 0}, /* 2/08 */ 742 { "CMD", 0}, /* 3/0c */ 743 { "SELID", 1}, /* 4/10 */ 744 { "TIMEOUT", 1}, /* 5/14 */ 745 { "SYNCTP", 1}, /* 6/18 */ 746 { "SYNCOFF", 1}, /* 7/1c */ 747 { "CFG1", 1}, /* 8/20 */ 748 { "CCF", 1}, /* 9/24 */ 749 { "TEST", 1}, /* a/28 */ 750 { "CFG2", 1}, /* b/2c */ 751 { "CFG3", 1}, /* c/30 */ 752 { "-none", 1}, /* d/34 */ 753 { "TCH", 1}, /* e/38 */ 754 { "TCX", 1}, /* f/3c */ 755}; 756#endif 757 758static uint8_t 759esp_read_reg(struct ncr53c9x_softc *sc, int reg) 760{ 761 struct esp_softc *esc = (struct esp_softc *)sc; 762 uint8_t v; 763 764 v = bus_read_1(esc->sc_res, reg * 4); 765 766#ifdef ESP_SBUS_DEBUG 767 if (esp_sbus_debug && (reg < 0x10) && esp__read_regnames[reg].r_flag) 768 printf("RD:%x <%s> %x\n", reg * 4, ((unsigned)reg < 0x10) ? 769 esp__read_regnames[reg].r_name : "<***>", v); 770#endif 771 772 return (v); 773} 774 775static void 776esp_write_reg(struct ncr53c9x_softc *sc, int reg, uint8_t v) 777{ 778 struct esp_softc *esc = (struct esp_softc *)sc; 779 780#ifdef ESP_SBUS_DEBUG 781 if (esp_sbus_debug && (reg < 0x10) && esp__write_regnames[reg].r_flag) 782 printf("WR:%x <%s> %x\n", reg * 4, ((unsigned)reg < 0x10) ? 783 esp__write_regnames[reg].r_name : "<***>", v); 784#endif 785 786 bus_write_1(esc->sc_res, reg * 4, v); 787} 788 789static int 790esp_dma_isintr(struct ncr53c9x_softc *sc) 791{ 792 struct esp_softc *esc = (struct esp_softc *)sc; 793 794 return (DMA_ISINTR(esc->sc_dma)); 795} 796 797static void 798esp_dma_reset(struct ncr53c9x_softc *sc) 799{ 800 struct esp_softc *esc = (struct esp_softc *)sc; 801 802 DMA_RESET(esc->sc_dma); 803} 804 805static int 806esp_dma_intr(struct ncr53c9x_softc *sc) 807{ 808 struct esp_softc *esc = (struct esp_softc *)sc; 809 810 return (DMA_INTR(esc->sc_dma)); 811} 812 813static int 814esp_dma_setup(struct ncr53c9x_softc *sc, void **addr, size_t *len, 815 int datain, size_t *dmasize) 816{ 817 struct esp_softc *esc = (struct esp_softc *)sc; 818 819 return (DMA_SETUP(esc->sc_dma, addr, len, datain, dmasize)); 820} 821 822static void 823esp_dma_go(struct ncr53c9x_softc *sc) 824{ 825 struct esp_softc *esc = (struct esp_softc *)sc; 826 827 DMA_GO(esc->sc_dma); 828} 829 830static void 831esp_dma_stop(struct ncr53c9x_softc *sc) 832{ 833 struct esp_softc *esc = (struct esp_softc *)sc; 834 835 L64854_SCSR(esc->sc_dma, L64854_GCSR(esc->sc_dma) & ~D_EN_DMA); 836} 837 838static int 839esp_dma_isactive(struct ncr53c9x_softc *sc) 840{ 841 struct esp_softc *esc = (struct esp_softc *)sc; 842 843 return (DMA_ISACTIVE(esc->sc_dma)); 844}
|