1 /* $OpenBSD: twe.c,v 1.66 2021/07/14 01:11:13 daniel Exp $ */ 2 3 /* 4 * Copyright (c) 2000-2002 Michael Shalayeff. All rights reserved. 5 * 6 * The SCSI emulation layer is derived from gdt(4) driver, 7 * Copyright (c) 1999, 2000 Niklas Hallqvist. All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, 22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 27 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 /* #define TWE_DEBUG */ 32 33 #include <sys/param.h> 34 #include <sys/systm.h> 35 #include <sys/buf.h> 36 #include <sys/device.h> 37 #include <sys/malloc.h> 38 #include <sys/kthread.h> 39 40 #include <machine/bus.h> 41 42 #include <scsi/scsi_all.h> 43 #include <scsi/scsi_disk.h> 44 #include <scsi/scsiconf.h> 45 46 #include <dev/ic/twereg.h> 47 #include <dev/ic/twevar.h> 48 49 #ifdef TWE_DEBUG 50 #define TWE_DPRINTF(m,a) if (twe_debug & (m)) printf a 51 #define TWE_D_CMD 0x0001 52 #define TWE_D_INTR 0x0002 53 #define TWE_D_MISC 0x0004 54 #define TWE_D_DMA 0x0008 55 #define TWE_D_AEN 0x0010 56 int twe_debug = 0; 57 #else 58 #define TWE_DPRINTF(m,a) /* m, a */ 59 #endif 60 61 struct cfdriver twe_cd = { 62 NULL, "twe", DV_DULL 63 }; 64 65 void twe_scsi_cmd(struct scsi_xfer *); 66 67 struct scsi_adapter twe_switch = { 68 twe_scsi_cmd, NULL, NULL, NULL, NULL 69 }; 70 71 void *twe_get_ccb(void *); 72 void twe_put_ccb(void *, void *); 73 void twe_dispose(struct twe_softc *sc); 74 int twe_cmd(struct twe_ccb *ccb, int flags, int wait); 75 int twe_start(struct twe_ccb *ccb, int wait); 76 int twe_complete(struct twe_ccb *ccb); 77 int twe_done(struct twe_softc *sc, struct twe_ccb *ccb); 78 void twe_thread_create(void *v); 79 void twe_thread(void *v); 80 void twe_aen(void *, void *); 81 82 void * 83 twe_get_ccb(void *xsc) 84 { 85 struct twe_softc *sc = xsc; 86 struct twe_ccb *ccb; 87 88 mtx_enter(&sc->sc_ccb_mtx); 89 ccb = TAILQ_LAST(&sc->sc_free_ccb, twe_queue_head); 90 if (ccb != NULL) 91 TAILQ_REMOVE(&sc->sc_free_ccb, ccb, ccb_link); 92 mtx_leave(&sc->sc_ccb_mtx); 93 94 return (ccb); 95 } 96 97 void 98 twe_put_ccb(void *xsc, void *xccb) 99 { 100 struct twe_softc *sc = xsc; 101 struct twe_ccb *ccb = xccb; 102 103 ccb->ccb_state = TWE_CCB_FREE; 104 mtx_enter(&sc->sc_ccb_mtx); 105 TAILQ_INSERT_TAIL(&sc->sc_free_ccb, ccb, ccb_link); 106 mtx_leave(&sc->sc_ccb_mtx); 107 } 108 109 void 110 twe_dispose(struct twe_softc *sc) 111 { 112 register struct twe_ccb *ccb; 113 if (sc->sc_cmdmap != NULL) { 114 bus_dmamap_destroy(sc->dmat, sc->sc_cmdmap); 115 /* traverse the ccbs and destroy the maps */ 116 for (ccb = &sc->sc_ccbs[TWE_MAXCMDS - 1]; ccb >= sc->sc_ccbs; ccb--) 117 if (ccb->ccb_dmamap) 118 bus_dmamap_destroy(sc->dmat, ccb->ccb_dmamap); 119 } 120 bus_dmamem_unmap(sc->dmat, sc->sc_cmds, 121 sizeof(struct twe_cmd) * TWE_MAXCMDS); 122 bus_dmamem_free(sc->dmat, sc->sc_cmdseg, 1); 123 } 124 125 int 126 twe_attach(struct twe_softc *sc) 127 { 128 struct scsibus_attach_args saa; 129 /* this includes a buffer for drive config req, and a capacity req */ 130 u_int8_t param_buf[2 * TWE_SECTOR_SIZE + TWE_ALIGN - 1]; 131 struct twe_param *pb = (void *) 132 (((u_long)param_buf + TWE_ALIGN - 1) & ~(TWE_ALIGN - 1)); 133 struct twe_param *cap = (void *)((u_int8_t *)pb + TWE_SECTOR_SIZE); 134 struct twe_ccb *ccb; 135 struct twe_cmd *cmd; 136 u_int32_t status; 137 int error, i, retry, nunits, nseg; 138 const char *errstr; 139 twe_lock_t lock; 140 paddr_t pa; 141 142 error = bus_dmamem_alloc(sc->dmat, sizeof(struct twe_cmd) * TWE_MAXCMDS, 143 PAGE_SIZE, 0, sc->sc_cmdseg, 1, &nseg, BUS_DMA_NOWAIT); 144 if (error) { 145 printf(": cannot allocate commands (%d)\n", error); 146 return (1); 147 } 148 149 error = bus_dmamem_map(sc->dmat, sc->sc_cmdseg, nseg, 150 sizeof(struct twe_cmd) * TWE_MAXCMDS, 151 (caddr_t *)&sc->sc_cmds, BUS_DMA_NOWAIT); 152 if (error) { 153 printf(": cannot map commands (%d)\n", error); 154 bus_dmamem_free(sc->dmat, sc->sc_cmdseg, 1); 155 return (1); 156 } 157 158 error = bus_dmamap_create(sc->dmat, 159 sizeof(struct twe_cmd) * TWE_MAXCMDS, TWE_MAXCMDS, 160 sizeof(struct twe_cmd) * TWE_MAXCMDS, 0, 161 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &sc->sc_cmdmap); 162 if (error) { 163 printf(": cannot create ccb cmd dmamap (%d)\n", error); 164 twe_dispose(sc); 165 return (1); 166 } 167 error = bus_dmamap_load(sc->dmat, sc->sc_cmdmap, sc->sc_cmds, 168 sizeof(struct twe_cmd) * TWE_MAXCMDS, NULL, BUS_DMA_NOWAIT); 169 if (error) { 170 printf(": cannot load command dma map (%d)\n", error); 171 twe_dispose(sc); 172 return (1); 173 } 174 175 TAILQ_INIT(&sc->sc_ccb2q); 176 TAILQ_INIT(&sc->sc_ccbq); 177 TAILQ_INIT(&sc->sc_free_ccb); 178 TAILQ_INIT(&sc->sc_done_ccb); 179 mtx_init(&sc->sc_ccb_mtx, IPL_BIO); 180 scsi_iopool_init(&sc->sc_iopool, sc, twe_get_ccb, twe_put_ccb); 181 182 scsi_ioh_set(&sc->sc_aen, &sc->sc_iopool, twe_aen, sc); 183 184 pa = sc->sc_cmdmap->dm_segs[0].ds_addr + 185 sizeof(struct twe_cmd) * (TWE_MAXCMDS - 1); 186 for (cmd = (struct twe_cmd *)sc->sc_cmds + TWE_MAXCMDS - 1; 187 cmd >= (struct twe_cmd *)sc->sc_cmds; cmd--, pa -= sizeof(*cmd)) { 188 189 cmd->cmd_index = cmd - (struct twe_cmd *)sc->sc_cmds; 190 ccb = &sc->sc_ccbs[cmd->cmd_index]; 191 error = bus_dmamap_create(sc->dmat, 192 TWE_MAXFER, TWE_MAXOFFSETS, TWE_MAXFER, 0, 193 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &ccb->ccb_dmamap); 194 if (error) { 195 printf(": cannot create ccb dmamap (%d)\n", error); 196 twe_dispose(sc); 197 return (1); 198 } 199 ccb->ccb_sc = sc; 200 ccb->ccb_cmd = cmd; 201 ccb->ccb_cmdpa = pa; 202 ccb->ccb_state = TWE_CCB_FREE; 203 TAILQ_INSERT_TAIL(&sc->sc_free_ccb, ccb, ccb_link); 204 } 205 206 for (errstr = NULL, retry = 3; retry--; ) { 207 int veseen_srst; 208 u_int16_t aen; 209 210 if (errstr) 211 TWE_DPRINTF(TWE_D_MISC, ("%s ", errstr)); 212 213 for (i = 350000; i--; DELAY(100)) { 214 status = bus_space_read_4(sc->iot, sc->ioh, TWE_STATUS); 215 if (status & TWE_STAT_CPURDY) 216 break; 217 } 218 219 if (!(status & TWE_STAT_CPURDY)) { 220 errstr = ": card CPU is not ready\n"; 221 continue; 222 } 223 224 /* soft reset, disable ints */ 225 bus_space_write_4(sc->iot, sc->ioh, TWE_CONTROL, 226 TWE_CTRL_SRST | 227 TWE_CTRL_CHOSTI | TWE_CTRL_CATTNI | TWE_CTRL_CERR | 228 TWE_CTRL_MCMDI | TWE_CTRL_MRDYI | 229 TWE_CTRL_MINT); 230 231 for (i = 350000; i--; DELAY(100)) { 232 status = bus_space_read_4(sc->iot, sc->ioh, TWE_STATUS); 233 if (status & TWE_STAT_ATTNI) 234 break; 235 } 236 237 if (!(status & TWE_STAT_ATTNI)) { 238 errstr = ": cannot get card's attention\n"; 239 continue; 240 } 241 242 /* drain aen queue */ 243 for (veseen_srst = 0, aen = -1; aen != TWE_AEN_QEMPTY; ) { 244 245 ccb = scsi_io_get(&sc->sc_iopool, 0); 246 if (ccb == NULL) { 247 errstr = ": out of ccbs\n"; 248 break; 249 } 250 251 ccb->ccb_xs = NULL; 252 ccb->ccb_data = pb; 253 ccb->ccb_length = TWE_SECTOR_SIZE; 254 ccb->ccb_state = TWE_CCB_READY; 255 cmd = ccb->ccb_cmd; 256 cmd->cmd_unit_host = TWE_UNITHOST(0, 0); 257 cmd->cmd_op = TWE_CMD_GPARAM; 258 cmd->cmd_param.count = 1; 259 260 pb->table_id = TWE_PARAM_AEN; 261 pb->param_id = 2; 262 pb->param_size = 2; 263 264 error = twe_cmd(ccb, BUS_DMA_NOWAIT, 1); 265 scsi_io_put(&sc->sc_iopool, ccb); 266 if (error) { 267 errstr = ": error draining attention queue\n"; 268 break; 269 } 270 271 aen = *(u_int16_t *)pb->data; 272 TWE_DPRINTF(TWE_D_AEN, ("aen=%x ", aen)); 273 if (aen == TWE_AEN_SRST) 274 veseen_srst++; 275 } 276 277 if (!veseen_srst) { 278 errstr = ": we don't get it\n"; 279 continue; 280 } 281 282 if (status & TWE_STAT_CPUERR) { 283 errstr = ": card CPU error detected\n"; 284 continue; 285 } 286 287 if (status & TWE_STAT_PCIPAR) { 288 errstr = ": PCI parity error detected\n"; 289 continue; 290 } 291 292 if (status & TWE_STAT_QUEUEE ) { 293 errstr = ": queuing error detected\n"; 294 continue; 295 } 296 297 if (status & TWE_STAT_PCIABR) { 298 errstr = ": PCI abort\n"; 299 continue; 300 } 301 302 while (!(status & TWE_STAT_RQE)) { 303 bus_space_read_4(sc->iot, sc->ioh, TWE_READYQUEUE); 304 status = bus_space_read_4(sc->iot, sc->ioh, TWE_STATUS); 305 } 306 307 break; 308 } 309 310 if (retry < 0) { 311 printf("%s", errstr); 312 twe_dispose(sc); 313 return 1; 314 } 315 316 ccb = scsi_io_get(&sc->sc_iopool, 0); 317 if (ccb == NULL) { 318 printf(": out of ccbs\n"); 319 twe_dispose(sc); 320 return 1; 321 } 322 323 ccb->ccb_xs = NULL; 324 ccb->ccb_data = pb; 325 ccb->ccb_length = TWE_SECTOR_SIZE; 326 ccb->ccb_state = TWE_CCB_READY; 327 cmd = ccb->ccb_cmd; 328 cmd->cmd_unit_host = TWE_UNITHOST(0, 0); 329 cmd->cmd_op = TWE_CMD_GPARAM; 330 cmd->cmd_param.count = 1; 331 332 pb->table_id = TWE_PARAM_UC; 333 pb->param_id = TWE_PARAM_UC; 334 pb->param_size = TWE_MAX_UNITS; 335 336 error = twe_cmd(ccb, BUS_DMA_NOWAIT, 1); 337 scsi_io_put(&sc->sc_iopool, ccb); 338 if (error) { 339 printf(": failed to fetch unit parameters\n"); 340 twe_dispose(sc); 341 return 1; 342 } 343 344 /* we are assuming last read status was good */ 345 printf(": Escalade V%d.%d\n", TWE_MAJV(status), TWE_MINV(status)); 346 347 for (nunits = i = 0; i < TWE_MAX_UNITS; i++) { 348 if (pb->data[i] == 0) 349 continue; 350 351 ccb = scsi_io_get(&sc->sc_iopool, 0); 352 if (ccb == NULL) { 353 printf(": out of ccbs\n"); 354 twe_dispose(sc); 355 return 1; 356 } 357 358 ccb->ccb_xs = NULL; 359 ccb->ccb_data = cap; 360 ccb->ccb_length = TWE_SECTOR_SIZE; 361 ccb->ccb_state = TWE_CCB_READY; 362 cmd = ccb->ccb_cmd; 363 cmd->cmd_unit_host = TWE_UNITHOST(0, 0); 364 cmd->cmd_op = TWE_CMD_GPARAM; 365 cmd->cmd_param.count = 1; 366 367 cap->table_id = TWE_PARAM_UI + i; 368 cap->param_id = 4; 369 cap->param_size = 4; /* 4 bytes */ 370 371 lock = TWE_LOCK(sc); 372 error = twe_cmd(ccb, BUS_DMA_NOWAIT, 1); 373 TWE_UNLOCK(sc, lock); 374 scsi_io_put(&sc->sc_iopool, ccb); 375 if (error) { 376 printf("%s: error fetching capacity for unit %d\n", 377 sc->sc_dev.dv_xname, i); 378 continue; 379 } 380 381 nunits++; 382 sc->sc_hdr[i].hd_present = 1; 383 sc->sc_hdr[i].hd_devtype = 0; 384 sc->sc_hdr[i].hd_size = letoh32(*(u_int32_t *)cap->data); 385 TWE_DPRINTF(TWE_D_MISC, ("twed%d: size=%d\n", 386 i, sc->sc_hdr[i].hd_size)); 387 } 388 389 if (!nunits) 390 nunits++; 391 392 /* TODO: fetch & print cache params? */ 393 394 saa.saa_adapter_softc = sc; 395 saa.saa_adapter = &twe_switch; 396 saa.saa_adapter_target = SDEV_NO_ADAPTER_TARGET; 397 saa.saa_adapter_buswidth = TWE_MAX_UNITS; 398 saa.saa_luns = 8; 399 saa.saa_openings = TWE_MAXCMDS / nunits; 400 saa.saa_pool = &sc->sc_iopool; 401 saa.saa_quirks = saa.saa_flags = 0; 402 saa.saa_wwpn = saa.saa_wwnn = 0; 403 404 config_found(&sc->sc_dev, &saa, scsiprint); 405 406 kthread_create_deferred(twe_thread_create, sc); 407 408 return (0); 409 } 410 411 void 412 twe_thread_create(void *v) 413 { 414 struct twe_softc *sc = v; 415 416 if (kthread_create(twe_thread, sc, &sc->sc_thread, 417 sc->sc_dev.dv_xname)) { 418 /* TODO disable twe */ 419 printf("%s: failed to create kernel thread, disabled\n", 420 sc->sc_dev.dv_xname); 421 return; 422 } 423 424 TWE_DPRINTF(TWE_D_CMD, ("stat=%b ", 425 bus_space_read_4(sc->iot, sc->ioh, TWE_STATUS), TWE_STAT_BITS)); 426 /* 427 * ack all before enable, cannot be done in one 428 * operation as it seems clear is not processed 429 * if enable is specified. 430 */ 431 bus_space_write_4(sc->iot, sc->ioh, TWE_CONTROL, 432 TWE_CTRL_CHOSTI | TWE_CTRL_CATTNI | TWE_CTRL_CERR); 433 TWE_DPRINTF(TWE_D_CMD, ("stat=%b ", 434 bus_space_read_4(sc->iot, sc->ioh, TWE_STATUS), TWE_STAT_BITS)); 435 /* enable interrupts */ 436 bus_space_write_4(sc->iot, sc->ioh, TWE_CONTROL, 437 TWE_CTRL_EINT | TWE_CTRL_ERDYI | 438 /*TWE_CTRL_HOSTI |*/ TWE_CTRL_MCMDI); 439 } 440 441 void 442 twe_thread(void *v) 443 { 444 struct twe_softc *sc = v; 445 struct twe_ccb *ccb; 446 twe_lock_t lock; 447 u_int32_t status; 448 int err; 449 450 for (;;) { 451 lock = TWE_LOCK(sc); 452 453 while (!TAILQ_EMPTY(&sc->sc_done_ccb)) { 454 ccb = TAILQ_FIRST(&sc->sc_done_ccb); 455 TAILQ_REMOVE(&sc->sc_done_ccb, ccb, ccb_link); 456 if ((err = twe_done(sc, ccb))) 457 printf("%s: done failed (%d)\n", 458 sc->sc_dev.dv_xname, err); 459 } 460 461 status = bus_space_read_4(sc->iot, sc->ioh, TWE_STATUS); 462 TWE_DPRINTF(TWE_D_INTR, ("twe_thread stat=%b ", 463 status & TWE_STAT_FLAGS, TWE_STAT_BITS)); 464 while (!(status & TWE_STAT_CQF) && 465 !TAILQ_EMPTY(&sc->sc_ccb2q)) { 466 467 ccb = TAILQ_LAST(&sc->sc_ccb2q, twe_queue_head); 468 TAILQ_REMOVE(&sc->sc_ccb2q, ccb, ccb_link); 469 470 ccb->ccb_state = TWE_CCB_QUEUED; 471 TAILQ_INSERT_TAIL(&sc->sc_ccbq, ccb, ccb_link); 472 bus_space_write_4(sc->iot, sc->ioh, TWE_COMMANDQUEUE, 473 ccb->ccb_cmdpa); 474 475 status = bus_space_read_4(sc->iot, sc->ioh, TWE_STATUS); 476 TWE_DPRINTF(TWE_D_INTR, ("twe_thread stat=%b ", 477 status & TWE_STAT_FLAGS, TWE_STAT_BITS)); 478 } 479 480 if (!TAILQ_EMPTY(&sc->sc_ccb2q)) 481 bus_space_write_4(sc->iot, sc->ioh, TWE_CONTROL, 482 TWE_CTRL_ECMDI); 483 484 TWE_UNLOCK(sc, lock); 485 sc->sc_thread_on = 1; 486 tsleep_nsec(sc, PWAIT, "twespank", INFSLP); 487 } 488 } 489 490 int 491 twe_cmd(struct twe_ccb *ccb, int flags, int wait) 492 { 493 struct twe_softc *sc = ccb->ccb_sc; 494 bus_dmamap_t dmap; 495 struct twe_cmd *cmd; 496 struct twe_segs *sgp; 497 int error, i; 498 499 if (ccb->ccb_data && ((u_long)ccb->ccb_data & (TWE_ALIGN - 1))) { 500 TWE_DPRINTF(TWE_D_DMA, ("data=%p is unaligned ",ccb->ccb_data)); 501 ccb->ccb_realdata = ccb->ccb_data; 502 503 error = bus_dmamem_alloc(sc->dmat, ccb->ccb_length, PAGE_SIZE, 504 0, ccb->ccb_2bseg, TWE_MAXOFFSETS, &ccb->ccb_2nseg, 505 BUS_DMA_NOWAIT); 506 if (error) { 507 TWE_DPRINTF(TWE_D_DMA, ("2buf alloc failed(%d) ", error)); 508 return (ENOMEM); 509 } 510 511 error = bus_dmamem_map(sc->dmat, ccb->ccb_2bseg, ccb->ccb_2nseg, 512 ccb->ccb_length, (caddr_t *)&ccb->ccb_data, BUS_DMA_NOWAIT); 513 if (error) { 514 TWE_DPRINTF(TWE_D_DMA, ("2buf map failed(%d) ", error)); 515 bus_dmamem_free(sc->dmat, ccb->ccb_2bseg, ccb->ccb_2nseg); 516 return (ENOMEM); 517 } 518 bcopy(ccb->ccb_realdata, ccb->ccb_data, ccb->ccb_length); 519 } else 520 ccb->ccb_realdata = NULL; 521 522 dmap = ccb->ccb_dmamap; 523 cmd = ccb->ccb_cmd; 524 cmd->cmd_status = 0; 525 526 if (ccb->ccb_data) { 527 error = bus_dmamap_load(sc->dmat, dmap, ccb->ccb_data, 528 ccb->ccb_length, NULL, flags); 529 if (error) { 530 if (error == EFBIG) 531 printf("more than %d dma segs\n", TWE_MAXOFFSETS); 532 else 533 printf("error %d loading dma map\n", error); 534 535 if (ccb->ccb_realdata) { 536 bus_dmamem_unmap(sc->dmat, ccb->ccb_data, 537 ccb->ccb_length); 538 bus_dmamem_free(sc->dmat, ccb->ccb_2bseg, 539 ccb->ccb_2nseg); 540 } 541 return error; 542 } 543 /* load addresses into command */ 544 switch (cmd->cmd_op) { 545 case TWE_CMD_GPARAM: 546 case TWE_CMD_SPARAM: 547 sgp = cmd->cmd_param.segs; 548 break; 549 case TWE_CMD_READ: 550 case TWE_CMD_WRITE: 551 sgp = cmd->cmd_io.segs; 552 break; 553 default: 554 /* no data transfer */ 555 TWE_DPRINTF(TWE_D_DMA, ("twe_cmd: unknown sgp op=%x\n", 556 cmd->cmd_op)); 557 sgp = NULL; 558 break; 559 } 560 TWE_DPRINTF(TWE_D_DMA, ("data=%p<", ccb->ccb_data)); 561 if (sgp) { 562 /* 563 * we know that size is in the upper byte, 564 * and we do not worry about overflow 565 */ 566 cmd->cmd_op += (2 * dmap->dm_nsegs) << 8; 567 bzero (sgp, TWE_MAXOFFSETS * sizeof(*sgp)); 568 for (i = 0; i < dmap->dm_nsegs; i++, sgp++) { 569 sgp->twes_addr = htole32(dmap->dm_segs[i].ds_addr); 570 sgp->twes_len = htole32(dmap->dm_segs[i].ds_len); 571 TWE_DPRINTF(TWE_D_DMA, ("%lx[%lx] ", 572 dmap->dm_segs[i].ds_addr, 573 dmap->dm_segs[i].ds_len)); 574 } 575 } 576 TWE_DPRINTF(TWE_D_DMA, ("> ")); 577 bus_dmamap_sync(sc->dmat, dmap, 0, dmap->dm_mapsize, 578 BUS_DMASYNC_PREWRITE); 579 } 580 bus_dmamap_sync(sc->dmat, sc->sc_cmdmap, 0, sc->sc_cmdmap->dm_mapsize, 581 BUS_DMASYNC_PREWRITE); 582 583 if ((error = twe_start(ccb, wait))) { 584 bus_dmamap_unload(sc->dmat, dmap); 585 if (ccb->ccb_realdata) { 586 bus_dmamem_unmap(sc->dmat, ccb->ccb_data, 587 ccb->ccb_length); 588 bus_dmamem_free(sc->dmat, ccb->ccb_2bseg, 589 ccb->ccb_2nseg); 590 } 591 return (error); 592 } 593 594 return wait? twe_complete(ccb) : 0; 595 } 596 597 int 598 twe_start(struct twe_ccb *ccb, int wait) 599 { 600 struct twe_softc*sc = ccb->ccb_sc; 601 struct twe_cmd *cmd = ccb->ccb_cmd; 602 u_int32_t status; 603 int i; 604 605 cmd->cmd_op = htole16(cmd->cmd_op); 606 607 if (!wait) { 608 609 TWE_DPRINTF(TWE_D_CMD, ("prequeue(%d) ", cmd->cmd_index)); 610 ccb->ccb_state = TWE_CCB_PREQUEUED; 611 TAILQ_INSERT_TAIL(&sc->sc_ccb2q, ccb, ccb_link); 612 wakeup(sc); 613 return 0; 614 } 615 616 for (i = 1000; i--; DELAY(10)) { 617 618 status = bus_space_read_4(sc->iot, sc->ioh, TWE_STATUS); 619 if (!(status & TWE_STAT_CQF)) 620 break; 621 TWE_DPRINTF(TWE_D_CMD, ("twe_start stat=%b ", 622 status & TWE_STAT_FLAGS, TWE_STAT_BITS)); 623 } 624 625 if (!(status & TWE_STAT_CQF)) { 626 bus_space_write_4(sc->iot, sc->ioh, TWE_COMMANDQUEUE, 627 ccb->ccb_cmdpa); 628 629 TWE_DPRINTF(TWE_D_CMD, ("queue(%d) ", cmd->cmd_index)); 630 ccb->ccb_state = TWE_CCB_QUEUED; 631 TAILQ_INSERT_TAIL(&sc->sc_ccbq, ccb, ccb_link); 632 return 0; 633 634 } else { 635 636 printf("%s: twe_start(%d) timed out\n", 637 sc->sc_dev.dv_xname, cmd->cmd_index); 638 639 return EPERM; 640 } 641 } 642 643 int 644 twe_complete(struct twe_ccb *ccb) 645 { 646 struct twe_softc *sc = ccb->ccb_sc; 647 struct scsi_xfer *xs = ccb->ccb_xs; 648 int i; 649 650 for (i = 100 * (xs? xs->timeout : 35000); i--; DELAY(10)) { 651 u_int32_t status = bus_space_read_4(sc->iot, sc->ioh, TWE_STATUS); 652 653 /* TWE_DPRINTF(TWE_D_CMD, ("twe_intr stat=%b ", 654 status & TWE_STAT_FLAGS, TWE_STAT_BITS)); */ 655 656 while (!(status & TWE_STAT_RQE)) { 657 struct twe_ccb *ccb1; 658 u_int32_t ready; 659 660 ready = bus_space_read_4(sc->iot, sc->ioh, 661 TWE_READYQUEUE); 662 663 TWE_DPRINTF(TWE_D_CMD, ("ready=%x ", ready)); 664 665 ccb1 = &sc->sc_ccbs[TWE_READYID(ready)]; 666 TAILQ_REMOVE(&sc->sc_ccbq, ccb1, ccb_link); 667 ccb1->ccb_state = TWE_CCB_DONE; 668 if (!twe_done(sc, ccb1) && ccb1 == ccb) { 669 TWE_DPRINTF(TWE_D_CMD, ("complete\n")); 670 return 0; 671 } 672 673 status = bus_space_read_4(sc->iot, sc->ioh, TWE_STATUS); 674 /* TWE_DPRINTF(TWE_D_CMD, ("twe_intr stat=%b ", 675 status & TWE_STAT_FLAGS, TWE_STAT_BITS)); */ 676 } 677 } 678 679 return 1; 680 } 681 682 int 683 twe_done(struct twe_softc *sc, struct twe_ccb *ccb) 684 { 685 struct twe_cmd *cmd = ccb->ccb_cmd; 686 struct scsi_xfer *xs = ccb->ccb_xs; 687 bus_dmamap_t dmap; 688 twe_lock_t lock; 689 690 TWE_DPRINTF(TWE_D_CMD, ("done(%d) ", cmd->cmd_index)); 691 692 if (ccb->ccb_state != TWE_CCB_DONE) { 693 printf("%s: undone ccb %d ready\n", 694 sc->sc_dev.dv_xname, cmd->cmd_index); 695 return 1; 696 } 697 698 dmap = ccb->ccb_dmamap; 699 if (xs) { 700 if (xs->cmd.opcode != PREVENT_ALLOW && 701 xs->cmd.opcode != SYNCHRONIZE_CACHE) { 702 bus_dmamap_sync(sc->dmat, dmap, 0, 703 dmap->dm_mapsize, (xs->flags & SCSI_DATA_IN) ? 704 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 705 bus_dmamap_unload(sc->dmat, dmap); 706 } 707 } else { 708 switch (letoh16(cmd->cmd_op)) { 709 case TWE_CMD_GPARAM: 710 case TWE_CMD_READ: 711 bus_dmamap_sync(sc->dmat, dmap, 0, 712 dmap->dm_mapsize, BUS_DMASYNC_POSTREAD); 713 bus_dmamap_unload(sc->dmat, dmap); 714 break; 715 case TWE_CMD_SPARAM: 716 case TWE_CMD_WRITE: 717 bus_dmamap_sync(sc->dmat, dmap, 0, 718 dmap->dm_mapsize, BUS_DMASYNC_POSTWRITE); 719 bus_dmamap_unload(sc->dmat, dmap); 720 break; 721 default: 722 /* no data */ 723 break; 724 } 725 } 726 727 if (ccb->ccb_realdata) { 728 bcopy(ccb->ccb_data, ccb->ccb_realdata, ccb->ccb_length); 729 bus_dmamem_unmap(sc->dmat, ccb->ccb_data, ccb->ccb_length); 730 bus_dmamem_free(sc->dmat, ccb->ccb_2bseg, ccb->ccb_2nseg); 731 } 732 733 lock = TWE_LOCK(sc); 734 735 if (xs) { 736 xs->resid = 0; 737 scsi_done(xs); 738 } 739 TWE_UNLOCK(sc, lock); 740 741 return 0; 742 } 743 744 void 745 twe_scsi_cmd(struct scsi_xfer *xs) 746 { 747 struct scsi_link *link = xs->sc_link; 748 struct twe_softc *sc = link->bus->sb_adapter_softc; 749 struct twe_ccb *ccb = xs->io; 750 struct twe_cmd *cmd; 751 struct scsi_inquiry_data inq; 752 struct scsi_sense_data sd; 753 struct scsi_read_cap_data rcd; 754 u_int8_t target = link->target; 755 u_int32_t blockno, blockcnt; 756 struct scsi_rw *rw; 757 struct scsi_rw_10 *rw10; 758 int error, op, flags, wait; 759 twe_lock_t lock; 760 761 762 if (target >= TWE_MAX_UNITS || !sc->sc_hdr[target].hd_present || 763 link->lun != 0) { 764 xs->error = XS_DRIVER_STUFFUP; 765 scsi_done(xs); 766 return; 767 } 768 769 TWE_DPRINTF(TWE_D_CMD, ("twe_scsi_cmd ")); 770 771 xs->error = XS_NOERROR; 772 773 switch (xs->cmd.opcode) { 774 case TEST_UNIT_READY: 775 case START_STOP: 776 #if 0 777 case VERIFY: 778 #endif 779 TWE_DPRINTF(TWE_D_CMD, ("opc %d tgt %d ", xs->cmd.opcode, 780 target)); 781 break; 782 783 case REQUEST_SENSE: 784 TWE_DPRINTF(TWE_D_CMD, ("REQUEST SENSE tgt %d ", target)); 785 bzero(&sd, sizeof sd); 786 sd.error_code = SSD_ERRCODE_CURRENT; 787 sd.segment = 0; 788 sd.flags = SKEY_NO_SENSE; 789 *(u_int32_t*)sd.info = htole32(0); 790 sd.extra_len = 0; 791 scsi_copy_internal_data(xs, &sd, sizeof(sd)); 792 break; 793 794 case INQUIRY: 795 TWE_DPRINTF(TWE_D_CMD, ("INQUIRY tgt %d devtype %x ", target, 796 sc->sc_hdr[target].hd_devtype)); 797 bzero(&inq, sizeof inq); 798 inq.device = 799 (sc->sc_hdr[target].hd_devtype & 4) ? T_CDROM : T_DIRECT; 800 inq.dev_qual2 = 801 (sc->sc_hdr[target].hd_devtype & 1) ? SID_REMOVABLE : 0; 802 inq.version = SCSI_REV_2; 803 inq.response_format = SID_SCSI2_RESPONSE; 804 inq.additional_length = SID_SCSI2_ALEN; 805 strlcpy(inq.vendor, "3WARE ", sizeof inq.vendor); 806 snprintf(inq.product, sizeof inq.product, "Host drive #%02d", 807 target); 808 strlcpy(inq.revision, " ", sizeof inq.revision); 809 scsi_copy_internal_data(xs, &inq, sizeof(inq)); 810 break; 811 812 case READ_CAPACITY: 813 TWE_DPRINTF(TWE_D_CMD, ("READ CAPACITY tgt %d ", target)); 814 bzero(&rcd, sizeof rcd); 815 _lto4b(sc->sc_hdr[target].hd_size - 1, rcd.addr); 816 _lto4b(TWE_SECTOR_SIZE, rcd.length); 817 scsi_copy_internal_data(xs, &rcd, sizeof(rcd)); 818 break; 819 820 case PREVENT_ALLOW: 821 TWE_DPRINTF(TWE_D_CMD, ("PREVENT/ALLOW ")); 822 scsi_done(xs); 823 return; 824 825 case READ_COMMAND: 826 case READ_10: 827 case WRITE_COMMAND: 828 case WRITE_10: 829 case SYNCHRONIZE_CACHE: 830 lock = TWE_LOCK(sc); 831 832 flags = 0; 833 if (xs->cmd.opcode == SYNCHRONIZE_CACHE) { 834 blockno = blockcnt = 0; 835 } else { 836 /* A read or write operation. */ 837 if (xs->cmdlen == 6) { 838 rw = (struct scsi_rw *)&xs->cmd; 839 blockno = _3btol(rw->addr) & 840 (SRW_TOPADDR << 16 | 0xffff); 841 blockcnt = rw->length ? rw->length : 0x100; 842 } else { 843 rw10 = (struct scsi_rw_10 *)&xs->cmd; 844 blockno = _4btol(rw10->addr); 845 blockcnt = _2btol(rw10->length); 846 /* reflect DPO & FUA flags */ 847 if (xs->cmd.opcode == WRITE_10 && 848 rw10->byte2 & 0x18) 849 flags = TWE_FLAGS_CACHEDISABLE; 850 } 851 if (blockno >= sc->sc_hdr[target].hd_size || 852 blockno + blockcnt > sc->sc_hdr[target].hd_size) { 853 printf("%s: out of bounds %u-%u >= %u\n", 854 sc->sc_dev.dv_xname, blockno, blockcnt, 855 sc->sc_hdr[target].hd_size); 856 xs->error = XS_DRIVER_STUFFUP; 857 scsi_done(xs); 858 TWE_UNLOCK(sc, lock); 859 return; 860 } 861 } 862 863 switch (xs->cmd.opcode) { 864 case READ_COMMAND: op = TWE_CMD_READ; break; 865 case READ_10: op = TWE_CMD_READ; break; 866 case WRITE_COMMAND: op = TWE_CMD_WRITE; break; 867 case WRITE_10: op = TWE_CMD_WRITE; break; 868 default: op = TWE_CMD_NOP; break; 869 } 870 871 ccb->ccb_xs = xs; 872 ccb->ccb_data = xs->data; 873 ccb->ccb_length = xs->datalen; 874 ccb->ccb_state = TWE_CCB_READY; 875 cmd = ccb->ccb_cmd; 876 cmd->cmd_unit_host = TWE_UNITHOST(target, 0); /* XXX why 0? */ 877 cmd->cmd_op = op; 878 cmd->cmd_flags = flags; 879 cmd->cmd_io.count = htole16(blockcnt); 880 cmd->cmd_io.lba = htole32(blockno); 881 wait = xs->flags & SCSI_POLL; 882 if (!sc->sc_thread_on) 883 wait |= SCSI_POLL; 884 885 if ((error = twe_cmd(ccb, ((xs->flags & SCSI_NOSLEEP)? 886 BUS_DMA_NOWAIT : BUS_DMA_WAITOK), wait))) { 887 888 TWE_DPRINTF(TWE_D_CMD, ("failed %p ", xs)); 889 xs->error = XS_DRIVER_STUFFUP; 890 scsi_done(xs); 891 } 892 893 TWE_UNLOCK(sc, lock); 894 return; 895 896 default: 897 TWE_DPRINTF(TWE_D_CMD, ("unsupported scsi command %#x tgt %d ", 898 xs->cmd.opcode, target)); 899 xs->error = XS_DRIVER_STUFFUP; 900 } 901 902 scsi_done(xs); 903 } 904 905 int 906 twe_intr(void *v) 907 { 908 struct twe_softc *sc = v; 909 struct twe_ccb *ccb; 910 u_int32_t status; 911 int rv = 0; 912 913 status = bus_space_read_4(sc->iot, sc->ioh, TWE_STATUS); 914 TWE_DPRINTF(TWE_D_INTR, ("twe_intr stat=%b ", 915 status & TWE_STAT_FLAGS, TWE_STAT_BITS)); 916 #if 0 917 if (status & TWE_STAT_HOSTI) { 918 919 bus_space_write_4(sc->iot, sc->ioh, TWE_CONTROL, 920 TWE_CTRL_CHOSTI); 921 } 922 #endif 923 924 if (status & TWE_STAT_RDYI) { 925 926 while (!(status & TWE_STAT_RQE)) { 927 928 u_int32_t ready; 929 930 /* 931 * it seems that reading ready queue 932 * we get all the status bits in each ready word. 933 * i wonder if it's legal to use those for 934 * status and avoid extra read below 935 */ 936 ready = bus_space_read_4(sc->iot, sc->ioh, 937 TWE_READYQUEUE); 938 939 ccb = &sc->sc_ccbs[TWE_READYID(ready)]; 940 TAILQ_REMOVE(&sc->sc_ccbq, ccb, ccb_link); 941 ccb->ccb_state = TWE_CCB_DONE; 942 TAILQ_INSERT_TAIL(&sc->sc_done_ccb, ccb, ccb_link); 943 rv++; 944 945 status = bus_space_read_4(sc->iot, sc->ioh, TWE_STATUS); 946 TWE_DPRINTF(TWE_D_INTR, ("twe_intr stat=%b ", 947 status & TWE_STAT_FLAGS, TWE_STAT_BITS)); 948 } 949 } 950 951 if (status & TWE_STAT_CMDI) { 952 rv++; 953 bus_space_write_4(sc->iot, sc->ioh, TWE_CONTROL, 954 TWE_CTRL_MCMDI); 955 } 956 957 if (rv) 958 wakeup(sc); 959 960 if (status & TWE_STAT_ATTNI) { 961 /* 962 * we know no attentions of interest right now. 963 * one of those would be mirror degradation i think. 964 * or, what else exists in there? 965 * maybe 3ware can answer that? 966 */ 967 bus_space_write_4(sc->iot, sc->ioh, TWE_CONTROL, 968 TWE_CTRL_CATTNI); 969 970 scsi_ioh_add(&sc->sc_aen); 971 } 972 973 return rv; 974 } 975 976 void 977 twe_aen(void *cookie, void *io) 978 { 979 struct twe_softc *sc = cookie; 980 struct twe_ccb *ccb = io; 981 struct twe_cmd *cmd = ccb->ccb_cmd; 982 983 u_int8_t param_buf[2 * TWE_SECTOR_SIZE + TWE_ALIGN - 1]; 984 struct twe_param *pb = (void *) (((u_long)param_buf + 985 TWE_ALIGN - 1) & ~(TWE_ALIGN - 1)); 986 u_int16_t aen; 987 988 twe_lock_t lock; 989 int error; 990 991 ccb->ccb_xs = NULL; 992 ccb->ccb_data = pb; 993 ccb->ccb_length = TWE_SECTOR_SIZE; 994 ccb->ccb_state = TWE_CCB_READY; 995 cmd->cmd_unit_host = TWE_UNITHOST(0, 0); 996 cmd->cmd_op = TWE_CMD_GPARAM; 997 cmd->cmd_flags = 0; 998 cmd->cmd_param.count = 1; 999 1000 pb->table_id = TWE_PARAM_AEN; 1001 pb->param_id = 2; 1002 pb->param_size = 2; 1003 1004 lock = TWE_LOCK(sc); 1005 error = twe_cmd(ccb, BUS_DMA_NOWAIT, 1); 1006 TWE_UNLOCK(sc, lock); 1007 scsi_io_put(&sc->sc_iopool, ccb); 1008 1009 if (error) { 1010 printf("%s: error draining attention queue\n", 1011 sc->sc_dev.dv_xname); 1012 return; 1013 } 1014 1015 aen = *(u_int16_t *)pb->data; 1016 if (aen != TWE_AEN_QEMPTY) 1017 scsi_ioh_add(&sc->sc_aen); 1018 } 1019