1/*- 2 * Copyright (c) 1997-2006 by Matthew Jacob 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice immediately at the beginning of the file, without modification, 10 * this list of conditions, and the following disclaimer. 11 * 2. The name of the author may not be used to endorse or promote products 12 * derived from this software without specific prior written permission. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 18 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26/* 27 * SBus specific probe and attach routines for Qlogic ISP SCSI adapters. 28 * FreeBSD Version. 29 */ 30 31#include <sys/cdefs.h> 32__FBSDID("$FreeBSD: releng/10.3/sys/dev/isp/isp_sbus.c 292929 2015-12-30 11:54:37Z mav $"); 33 34#include <sys/param.h> 35#include <sys/systm.h> 36#include <sys/linker.h> 37#include <sys/firmware.h> 38#include <sys/bus.h> 39#include <sys/kernel.h> 40#include <sys/module.h> 41#include <sys/resource.h> 42 43#include <dev/ofw/ofw_bus.h> 44#include <dev/ofw/openfirm.h> 45 46#include <machine/bus.h> 47#include <machine/ofw_machdep.h> 48#include <machine/resource.h> 49#include <sys/rman.h> 50#include <sparc64/sbus/sbusvar.h> 51 52#include <dev/isp/isp_freebsd.h> 53 54static uint32_t isp_sbus_rd_reg(ispsoftc_t *, int); 55static void isp_sbus_wr_reg(ispsoftc_t *, int, uint32_t); 56static int isp_sbus_rd_isr(ispsoftc_t *, uint16_t *, uint16_t *, uint16_t *); 57static int isp_sbus_mbxdma(ispsoftc_t *); 58static int isp_sbus_dmasetup(ispsoftc_t *, XS_T *, void *); 59 60 61static void isp_sbus_reset0(ispsoftc_t *); 62static void isp_sbus_reset1(ispsoftc_t *); 63static void isp_sbus_dumpregs(ispsoftc_t *, const char *); 64 65static struct ispmdvec mdvec = { 66 isp_sbus_rd_isr, 67 isp_sbus_rd_reg, 68 isp_sbus_wr_reg, 69 isp_sbus_mbxdma, 70 isp_sbus_dmasetup, 71 isp_common_dmateardown, 72 isp_sbus_reset0, 73 isp_sbus_reset1, 74 isp_sbus_dumpregs, 75 NULL, 76 BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_64 77}; 78 79static int isp_sbus_probe (device_t); 80static int isp_sbus_attach (device_t); 81static int isp_sbus_detach (device_t); 82 83 84#define ISP_SBD(isp) ((struct isp_sbussoftc *)isp)->sbus_dev 85struct isp_sbussoftc { 86 ispsoftc_t sbus_isp; 87 device_t sbus_dev; 88 struct resource * regs; 89 void * irq; 90 int iqd; 91 int rgd; 92 void * ih; 93 int16_t sbus_poff[_NREG_BLKS]; 94 sdparam sbus_param; 95 struct isp_spi sbus_spi; 96 struct ispmdvec sbus_mdvec; 97}; 98 99 100static device_method_t isp_sbus_methods[] = { 101 /* Device interface */ 102 DEVMETHOD(device_probe, isp_sbus_probe), 103 DEVMETHOD(device_attach, isp_sbus_attach), 104 DEVMETHOD(device_detach, isp_sbus_detach), 105 { 0, 0 } 106}; 107 108static driver_t isp_sbus_driver = { 109 "isp", isp_sbus_methods, sizeof (struct isp_sbussoftc) 110}; 111static devclass_t isp_devclass; 112DRIVER_MODULE(isp, sbus, isp_sbus_driver, isp_devclass, 0, 0); 113MODULE_DEPEND(isp, cam, 1, 1, 1); 114MODULE_DEPEND(isp, firmware, 1, 1, 1); 115 116static int 117isp_sbus_probe(device_t dev) 118{ 119 int found = 0; 120 const char *name = ofw_bus_get_name(dev); 121 if (strcmp(name, "SUNW,isp") == 0 || 122 strcmp(name, "QLGC,isp") == 0 || 123 strcmp(name, "ptisp") == 0 || 124 strcmp(name, "PTI,ptisp") == 0) { 125 found++; 126 } 127 if (!found) 128 return (ENXIO); 129 130 if (isp_announced == 0 && bootverbose) { 131 printf("Qlogic ISP Driver, FreeBSD Version %d.%d, " 132 "Core Version %d.%d\n", 133 ISP_PLATFORM_VERSION_MAJOR, ISP_PLATFORM_VERSION_MINOR, 134 ISP_CORE_VERSION_MAJOR, ISP_CORE_VERSION_MINOR); 135 isp_announced++; 136 } 137 return (0); 138} 139 140static int 141isp_sbus_attach(device_t dev) 142{ 143 int tval, isp_debug, role, ispburst, default_id; 144 struct isp_sbussoftc *sbs; 145 ispsoftc_t *isp = NULL; 146 int locksetup = 0; 147 int ints_setup = 0; 148 149 sbs = device_get_softc(dev); 150 if (sbs == NULL) { 151 device_printf(dev, "cannot get softc\n"); 152 return (ENOMEM); 153 } 154 155 sbs->sbus_dev = dev; 156 sbs->sbus_mdvec = mdvec; 157 158 role = 0; 159 if (resource_int_value(device_get_name(dev), device_get_unit(dev), 160 "role", &role) == 0 && 161 ((role & ~(ISP_ROLE_INITIATOR|ISP_ROLE_TARGET)) == 0)) { 162 device_printf(dev, "setting role to 0x%x\n", role); 163 } else { 164 role = ISP_DEFAULT_ROLES; 165 } 166 167 sbs->irq = sbs->regs = NULL; 168 sbs->rgd = sbs->iqd = 0; 169 170 sbs->regs = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sbs->rgd, 171 RF_ACTIVE); 172 if (sbs->regs == NULL) { 173 device_printf(dev, "unable to map registers\n"); 174 goto bad; 175 } 176 177 sbs->sbus_poff[BIU_BLOCK >> _BLK_REG_SHFT] = BIU_REGS_OFF; 178 sbs->sbus_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = SBUS_MBOX_REGS_OFF; 179 sbs->sbus_poff[SXP_BLOCK >> _BLK_REG_SHFT] = SBUS_SXP_REGS_OFF; 180 sbs->sbus_poff[RISC_BLOCK >> _BLK_REG_SHFT] = SBUS_RISC_REGS_OFF; 181 sbs->sbus_poff[DMA_BLOCK >> _BLK_REG_SHFT] = DMA_REGS_OFF; 182 isp = &sbs->sbus_isp; 183 isp->isp_regs = sbs->regs; 184 isp->isp_mdvec = &sbs->sbus_mdvec; 185 isp->isp_bustype = ISP_BT_SBUS; 186 isp->isp_type = ISP_HA_SCSI_UNKNOWN; 187 isp->isp_param = &sbs->sbus_param; 188 isp->isp_osinfo.pc.ptr = &sbs->sbus_spi; 189 isp->isp_revision = 0; /* XXX */ 190 isp->isp_dev = dev; 191 isp->isp_nchan = 1; 192 if (IS_FC(isp)) 193 ISP_FC_PC(isp, 0)->def_role = role; 194 195 /* 196 * Get the clock frequency and convert it from HZ to MHz, 197 * rounding up. This defaults to 25MHz if there isn't a 198 * device specific one in the OFW device tree. 199 */ 200 sbs->sbus_mdvec.dv_clock = (sbus_get_clockfreq(dev) + 500000)/1000000; 201 202 /* 203 * Now figure out what the proper burst sizes, etc., to use. 204 * Unfortunately, there is no ddi_dma_burstsizes here which 205 * walks up the tree finding the limiting burst size node (if 206 * any). We just use what's here for isp. 207 */ 208 ispburst = sbus_get_burstsz(dev); 209 if (ispburst == 0) { 210 ispburst = SBUS_BURST_32 - 1; 211 } 212 sbs->sbus_mdvec.dv_conf1 = 0; 213 if (ispburst & (1 << 5)) { 214 sbs->sbus_mdvec.dv_conf1 = BIU_SBUS_CONF1_FIFO_32; 215 } else if (ispburst & (1 << 4)) { 216 sbs->sbus_mdvec.dv_conf1 = BIU_SBUS_CONF1_FIFO_16; 217 } else if (ispburst & (1 << 3)) { 218 sbs->sbus_mdvec.dv_conf1 = 219 BIU_SBUS_CONF1_BURST8 | BIU_SBUS_CONF1_FIFO_8; 220 } 221 if (sbs->sbus_mdvec.dv_conf1) { 222 sbs->sbus_mdvec.dv_conf1 |= BIU_BURST_ENABLE; 223 } 224 225 /* 226 * We don't trust NVRAM on SBus cards 227 */ 228 isp->isp_confopts |= ISP_CFG_NONVRAM; 229 230 /* 231 * Mark things if we're a PTI SBus adapter. 232 */ 233 if (strcmp("PTI,ptisp", ofw_bus_get_name(dev)) == 0 || 234 strcmp("ptisp", ofw_bus_get_name(dev)) == 0) { 235 SDPARAM(isp, 0)->isp_ptisp = 1; 236 } 237 238 isp->isp_osinfo.fw = firmware_get("isp_1000"); 239 if (isp->isp_osinfo.fw) { 240 union { 241 const void *cp; 242 uint16_t *sp; 243 } stupid; 244 stupid.cp = isp->isp_osinfo.fw->data; 245 isp->isp_mdvec->dv_ispfw = stupid.sp; 246 } 247 248 tval = 0; 249 if (resource_int_value(device_get_name(dev), device_get_unit(dev), 250 "fwload_disable", &tval) == 0 && tval != 0) { 251 isp->isp_confopts |= ISP_CFG_NORELOAD; 252 } 253 254 default_id = -1; 255 if (resource_int_value(device_get_name(dev), device_get_unit(dev), 256 "iid", &tval) == 0) { 257 default_id = tval; 258 isp->isp_confopts |= ISP_CFG_OWNLOOPID; 259 } 260 if (default_id == -1) { 261 default_id = OF_getscsinitid(dev); 262 } 263 ISP_SPI_PC(isp, 0)->iid = default_id; 264 265 isp_debug = 0; 266 (void) resource_int_value(device_get_name(dev), device_get_unit(dev), 267 "debug", &isp_debug); 268 269 /* Make sure the lock is set up. */ 270 mtx_init(&isp->isp_osinfo.lock, "isp", NULL, MTX_DEF); 271 locksetup++; 272 273 sbs->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sbs->iqd, 274 RF_ACTIVE | RF_SHAREABLE); 275 if (sbs->irq == NULL) { 276 device_printf(dev, "could not allocate interrupt\n"); 277 goto bad; 278 } 279 280 if (isp_setup_intr(dev, sbs->irq, ISP_IFLAGS, NULL, isp_platform_intr, 281 isp, &sbs->ih)) { 282 device_printf(dev, "could not setup interrupt\n"); 283 goto bad; 284 } 285 ints_setup++; 286 287 /* 288 * Set up logging levels. 289 */ 290 if (isp_debug) { 291 isp->isp_dblev = isp_debug; 292 } else { 293 isp->isp_dblev = ISP_LOGWARN|ISP_LOGERR; 294 } 295 if (bootverbose) { 296 isp->isp_dblev |= ISP_LOGCONFIG|ISP_LOGINFO; 297 } 298 299 /* 300 * Make sure we're in reset state. 301 */ 302 ISP_LOCK(isp); 303 if (isp_reinit(isp, 1) != 0) { 304 isp_uninit(isp); 305 ISP_UNLOCK(isp); 306 goto bad; 307 } 308 ISP_UNLOCK(isp); 309 if (isp_attach(isp)) { 310 ISP_LOCK(isp); 311 isp_uninit(isp); 312 ISP_UNLOCK(isp); 313 goto bad; 314 } 315 return (0); 316 317bad: 318 319 if (sbs && ints_setup) { 320 (void) bus_teardown_intr(dev, sbs->irq, sbs->ih); 321 } 322 323 if (sbs && sbs->irq) { 324 bus_release_resource(dev, SYS_RES_IRQ, sbs->iqd, sbs->irq); 325 } 326 327 if (locksetup && isp) { 328 mtx_destroy(&isp->isp_osinfo.lock); 329 } 330 331 if (sbs->regs) { 332 (void) bus_release_resource(dev, SYS_RES_MEMORY, sbs->rgd, 333 sbs->regs); 334 } 335 return (ENXIO); 336} 337 338static int 339isp_sbus_detach(device_t dev) 340{ 341 struct isp_sbussoftc *sbs; 342 ispsoftc_t *isp; 343 int status; 344 345 sbs = device_get_softc(dev); 346 if (sbs == NULL) { 347 return (ENXIO); 348 } 349 isp = (ispsoftc_t *) sbs; 350 status = isp_detach(isp); 351 if (status) 352 return (status); 353 ISP_LOCK(isp); 354 isp_uninit(isp); 355 if (sbs->ih) { 356 (void) bus_teardown_intr(dev, sbs->irq, sbs->ih); 357 } 358 ISP_UNLOCK(isp); 359 mtx_destroy(&isp->isp_osinfo.lock); 360 (void) bus_release_resource(dev, SYS_RES_IRQ, sbs->iqd, sbs->irq); 361 (void) bus_release_resource(dev, SYS_RES_MEMORY, sbs->rgd, sbs->regs); 362 return (0); 363} 364 365#define IspVirt2Off(a, x) \ 366 (((struct isp_sbussoftc *)a)->sbus_poff[((x) & _BLK_REG_MASK) >> \ 367 _BLK_REG_SHFT] + ((x) & 0xff)) 368 369#define BXR2(isp, off) bus_read_2((isp)->isp_regs, (off)) 370 371static int 372isp_sbus_rd_isr(ispsoftc_t *isp, uint16_t *isrp, uint16_t *semap, uint16_t *info) 373{ 374 uint16_t isr, sema; 375 376 isr = BXR2(isp, IspVirt2Off(isp, BIU_ISR)); 377 sema = BXR2(isp, IspVirt2Off(isp, BIU_SEMA)); 378 isp_prt(isp, ISP_LOGDEBUG3, "ISR 0x%x SEMA 0x%x", isr, sema); 379 isr &= INT_PENDING_MASK(isp); 380 sema &= BIU_SEMA_LOCK; 381 if (isr == 0 && sema == 0) { 382 return (0); 383 } 384 *isrp = isr; 385 if ((*semap = sema) != 0) 386 *info = BXR2(isp, IspVirt2Off(isp, OUTMAILBOX0)); 387 return (1); 388} 389 390static uint32_t 391isp_sbus_rd_reg(ispsoftc_t *isp, int regoff) 392{ 393 uint16_t rval; 394 struct isp_sbussoftc *sbs = (struct isp_sbussoftc *) isp; 395 int offset = sbs->sbus_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT]; 396 offset += (regoff & 0xff); 397 rval = BXR2(isp, offset); 398 isp_prt(isp, ISP_LOGDEBUG3, 399 "isp_sbus_rd_reg(off %x) = %x", regoff, rval); 400 return (rval); 401} 402 403static void 404isp_sbus_wr_reg(ispsoftc_t *isp, int regoff, uint32_t val) 405{ 406 struct isp_sbussoftc *sbs = (struct isp_sbussoftc *) isp; 407 int offset = sbs->sbus_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT]; 408 offset += (regoff & 0xff); 409 isp_prt(isp, ISP_LOGDEBUG3, 410 "isp_sbus_wr_reg(off %x) = %x", regoff, val); 411 bus_write_2(isp->isp_regs, offset, val); 412 MEMORYBARRIER(isp, SYNC_REG, offset, 2, -1); 413} 414 415struct imush { 416 bus_addr_t maddr; 417 int error; 418}; 419 420static void imc(void *, bus_dma_segment_t *, int, int); 421 422static void 423imc(void *arg, bus_dma_segment_t *segs, int nseg, int error) 424{ 425 struct imush *imushp = (struct imush *) arg; 426 427 if (!(imushp->error = error)) 428 imushp->maddr = segs[0].ds_addr; 429} 430 431static int 432isp_sbus_mbxdma(ispsoftc_t *isp) 433{ 434 caddr_t base; 435 uint32_t len; 436 int i, error; 437 struct imush im; 438 439 /* 440 * Already been here? If so, leave... 441 */ 442 if (isp->isp_rquest) { 443 return (0); 444 } 445 446 ISP_UNLOCK(isp); 447 448 len = sizeof (struct isp_pcmd) * isp->isp_maxcmds; 449 isp->isp_osinfo.pcmd_pool = (struct isp_pcmd *) 450 malloc(len, M_DEVBUF, M_WAITOK | M_ZERO); 451 if (isp->isp_osinfo.pcmd_pool == NULL) { 452 isp_prt(isp, ISP_LOGERR, "cannot alloc pcmd pool"); 453 ISP_LOCK(isp); 454 return (1); 455 } 456 457 len = sizeof (isp_hdl_t *) * isp->isp_maxcmds; 458 isp->isp_xflist = (isp_hdl_t *) malloc(len, M_DEVBUF, M_WAITOK | M_ZERO); 459 if (isp->isp_xflist == NULL) { 460 isp_prt(isp, ISP_LOGERR, "cannot alloc xflist array"); 461 ISP_LOCK(isp); 462 return (1); 463 } 464 for (len = 0; len < isp->isp_maxcmds - 1; len++) { 465 isp->isp_xflist[len].cmd = &isp->isp_xflist[len+1]; 466 } 467 isp->isp_xffree = isp->isp_xflist; 468 len = sizeof (bus_dmamap_t) * isp->isp_maxcmds; 469 470 if (isp_dma_tag_create(BUS_DMA_ROOTARG(ISP_SBD(isp)), 1, 471 BUS_SPACE_MAXADDR_24BIT+1, BUS_SPACE_MAXADDR_32BIT, 472 BUS_SPACE_MAXADDR_32BIT, NULL, NULL, BUS_SPACE_MAXSIZE_32BIT, 473 ISP_NSEG_MAX, BUS_SPACE_MAXADDR_24BIT, 0, &isp->isp_osinfo.dmat)) { 474 isp_prt(isp, ISP_LOGERR, "could not create master dma tag"); 475 goto bad; 476 } 477 478 /* 479 * Allocate and map the request queue. 480 */ 481 len = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)); 482 if (isp_dma_tag_create(isp->isp_osinfo.dmat, QENTRY_LEN, BUS_SPACE_MAXADDR_24BIT+1, 483 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, 484 len, 1, len, 0, &isp->isp_osinfo.reqdmat)) { 485 isp_prt(isp, ISP_LOGERR, "cannot create request DMA tag"); 486 goto bad; 487 } 488 if (bus_dmamem_alloc(isp->isp_osinfo.reqdmat, (void **)&base, 489 BUS_DMA_COHERENT, &isp->isp_osinfo.reqmap) != 0) { 490 isp_prt(isp, ISP_LOGERR, "cannot allocate request DMA memory"); 491 bus_dma_tag_destroy(isp->isp_osinfo.reqdmat); 492 goto bad; 493 } 494 im.error = 0; 495 if (bus_dmamap_load(isp->isp_osinfo.reqdmat, isp->isp_osinfo.reqmap, 496 base, len, imc, &im, 0) || im.error) { 497 isp_prt(isp, ISP_LOGERR, "error loading request DMA map %d", im.error); 498 goto bad; 499 } 500 isp_prt(isp, ISP_LOGDEBUG0, "request area @ 0x%jx/0x%jx", 501 (uintmax_t)im.maddr, (uintmax_t)len); 502 isp->isp_rquest = base; 503 isp->isp_rquest_dma = im.maddr; 504 505 /* 506 * Allocate and map the result queue. 507 */ 508 len = ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp)); 509 if (isp_dma_tag_create(isp->isp_osinfo.dmat, QENTRY_LEN, BUS_SPACE_MAXADDR_24BIT+1, 510 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, 511 len, 1, len, 0, &isp->isp_osinfo.respdmat)) { 512 isp_prt(isp, ISP_LOGERR, "cannot create response DMA tag"); 513 goto bad; 514 } 515 if (bus_dmamem_alloc(isp->isp_osinfo.respdmat, (void **)&base, 516 BUS_DMA_COHERENT, &isp->isp_osinfo.respmap) != 0) { 517 isp_prt(isp, ISP_LOGERR, "cannot allocate response DMA memory"); 518 bus_dma_tag_destroy(isp->isp_osinfo.respdmat); 519 goto bad; 520 } 521 im.error = 0; 522 if (bus_dmamap_load(isp->isp_osinfo.respdmat, isp->isp_osinfo.respmap, 523 base, len, imc, &im, 0) || im.error) { 524 isp_prt(isp, ISP_LOGERR, "error loading response DMA map %d", im.error); 525 goto bad; 526 } 527 isp_prt(isp, ISP_LOGDEBUG0, "response area @ 0x%jx/0x%jx", 528 (uintmax_t)im.maddr, (uintmax_t)len); 529 isp->isp_result = base; 530 isp->isp_result_dma = im.maddr; 531 532 for (i = 0; i < isp->isp_maxcmds; i++) { 533 struct isp_pcmd *pcmd = &isp->isp_osinfo.pcmd_pool[i]; 534 error = bus_dmamap_create(isp->isp_osinfo.dmat, 0, &pcmd->dmap); 535 if (error) { 536 isp_prt(isp, ISP_LOGERR, 537 "error %d creating per-cmd DMA maps", error); 538 while (--i >= 0) { 539 bus_dmamap_destroy(isp->isp_osinfo.dmat, 540 isp->isp_osinfo.pcmd_pool[i].dmap); 541 } 542 goto bad; 543 } 544 callout_init_mtx(&pcmd->wdog, &isp->isp_osinfo.lock, 0); 545 if (i == isp->isp_maxcmds-1) { 546 pcmd->next = NULL; 547 } else { 548 pcmd->next = &isp->isp_osinfo.pcmd_pool[i+1]; 549 } 550 } 551 isp->isp_osinfo.pcmd_free = &isp->isp_osinfo.pcmd_pool[0]; 552 ISP_LOCK(isp); 553 return (0); 554 555bad: 556 if (isp->isp_rquest_dma != 0) { 557 bus_dmamap_unload(isp->isp_osinfo.reqdmat, 558 isp->isp_osinfo.reqmap); 559 } 560 if (isp->isp_rquest != NULL) { 561 bus_dmamem_free(isp->isp_osinfo.reqdmat, isp->isp_rquest, 562 isp->isp_osinfo.reqmap); 563 bus_dma_tag_destroy(isp->isp_osinfo.reqdmat); 564 } 565 if (isp->isp_result_dma != 0) { 566 bus_dmamap_unload(isp->isp_osinfo.respdmat, 567 isp->isp_osinfo.respmap); 568 } 569 if (isp->isp_result != NULL) { 570 bus_dmamem_free(isp->isp_osinfo.respdmat, isp->isp_result, 571 isp->isp_osinfo.respmap); 572 bus_dma_tag_destroy(isp->isp_osinfo.respdmat); 573 } 574 free(isp->isp_xflist, M_DEVBUF); 575 free(isp->isp_osinfo.pcmd_pool, M_DEVBUF); 576 isp->isp_rquest = NULL; 577 ISP_LOCK(isp); 578 return (1); 579} 580 581typedef struct { 582 ispsoftc_t *isp; 583 void *cmd_token; 584 void *rq; /* original request */ 585 int error; 586 bus_size_t mapsize; 587} mush_t; 588 589#define MUSHERR_NOQENTRIES -2 590 591static void dma2(void *, bus_dma_segment_t *, int, int); 592 593static void 594dma2(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) 595{ 596 mush_t *mp; 597 ispsoftc_t *isp; 598 struct ccb_scsiio *csio; 599 isp_ddir_t ddir; 600 ispreq_t *rq; 601 602 mp = (mush_t *) arg; 603 if (error) { 604 mp->error = error; 605 return; 606 } 607 csio = mp->cmd_token; 608 isp = mp->isp; 609 rq = mp->rq; 610 if (nseg) { 611 if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { 612 bus_dmamap_sync(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap, BUS_DMASYNC_PREREAD); 613 ddir = ISP_FROM_DEVICE; 614 } else if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) { 615 bus_dmamap_sync(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap, BUS_DMASYNC_PREWRITE); 616 ddir = ISP_TO_DEVICE; 617 } else { 618 ddir = ISP_NOXFR; 619 } 620 } else { 621 dm_segs = NULL; 622 nseg = 0; 623 ddir = ISP_NOXFR; 624 } 625 626 if (isp_send_cmd(isp, rq, dm_segs, nseg, XS_XFRLEN(csio), ddir, NULL) != CMD_QUEUED) { 627 mp->error = MUSHERR_NOQENTRIES; 628 } 629} 630 631static int 632isp_sbus_dmasetup(ispsoftc_t *isp, struct ccb_scsiio *csio, void *ff) 633{ 634 mush_t mush, *mp; 635 void (*eptr)(void *, bus_dma_segment_t *, int, int); 636 int error; 637 638 mp = &mush; 639 mp->isp = isp; 640 mp->cmd_token = csio; 641 mp->rq = ff; 642 mp->error = 0; 643 mp->mapsize = 0; 644 645 eptr = dma2; 646 647 error = bus_dmamap_load_ccb(isp->isp_osinfo.dmat, 648 PISP_PCMD(csio)->dmap, (union ccb *)csio, eptr, mp, 0); 649 if (error == EINPROGRESS) { 650 bus_dmamap_unload(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap); 651 mp->error = EINVAL; 652 isp_prt(isp, ISP_LOGERR, 653 "deferred dma allocation not supported"); 654 } else if (error && mp->error == 0) { 655#ifdef DIAGNOSTIC 656 isp_prt(isp, ISP_LOGERR, "error %d in dma mapping code", error); 657#endif 658 mp->error = error; 659 } 660 if (mp->error) { 661 int retval = CMD_COMPLETE; 662 if (mp->error == MUSHERR_NOQENTRIES) { 663 retval = CMD_EAGAIN; 664 } else if (mp->error == EFBIG) { 665 XS_SETERR(csio, CAM_REQ_TOO_BIG); 666 } else if (mp->error == EINVAL) { 667 XS_SETERR(csio, CAM_REQ_INVALID); 668 } else { 669 XS_SETERR(csio, CAM_UNREC_HBA_ERROR); 670 } 671 return (retval); 672 } 673 return (CMD_QUEUED); 674} 675 676static void 677isp_sbus_reset0(ispsoftc_t *isp) 678{ 679 ISP_DISABLE_INTS(isp); 680} 681 682static void 683isp_sbus_reset1(ispsoftc_t *isp) 684{ 685 ISP_ENABLE_INTS(isp); 686} 687 688static void 689isp_sbus_dumpregs(ispsoftc_t *isp, const char *msg) 690{ 691 if (msg) 692 printf("%s: %s\n", device_get_nameunit(isp->isp_dev), msg); 693 else 694 printf("%s:\n", device_get_nameunit(isp->isp_dev)); 695 printf(" biu_conf1=%x", ISP_READ(isp, BIU_CONF1)); 696 printf(" biu_icr=%x biu_isr=%x biu_sema=%x ", ISP_READ(isp, BIU_ICR), 697 ISP_READ(isp, BIU_ISR), ISP_READ(isp, BIU_SEMA)); 698 printf("risc_hccr=%x\n", ISP_READ(isp, HCCR)); 699 700 701 ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE); 702 printf(" cdma_conf=%x cdma_sts=%x cdma_fifostat=%x\n", 703 ISP_READ(isp, CDMA_CONF), ISP_READ(isp, CDMA_STATUS), 704 ISP_READ(isp, CDMA_FIFO_STS)); 705 printf(" ddma_conf=%x ddma_sts=%x ddma_fifostat=%x\n", 706 ISP_READ(isp, DDMA_CONF), ISP_READ(isp, DDMA_STATUS), 707 ISP_READ(isp, DDMA_FIFO_STS)); 708 printf(" sxp_int=%x sxp_gross=%x sxp(scsi_ctrl)=%x\n", 709 ISP_READ(isp, SXP_INTERRUPT), 710 ISP_READ(isp, SXP_GROSS_ERR), 711 ISP_READ(isp, SXP_PINS_CTRL)); 712 ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE); 713 printf(" mbox regs: %x %x %x %x %x\n", 714 ISP_READ(isp, OUTMAILBOX0), ISP_READ(isp, OUTMAILBOX1), 715 ISP_READ(isp, OUTMAILBOX2), ISP_READ(isp, OUTMAILBOX3), 716 ISP_READ(isp, OUTMAILBOX4)); 717} 718