1 /* $NetBSD: ciss.c,v 1.38 2018/02/12 23:11:00 joerg Exp $ */ 2 /* $OpenBSD: ciss.c,v 1.68 2013/05/30 16:15:02 deraadt Exp $ */ 3 4 /* 5 * Copyright (c) 2005,2006 Michael Shalayeff 6 * All rights reserved. 7 * 8 * Permission to use, copy, modify, and distribute this software for any 9 * purpose with or without fee is hereby granted, provided that the above 10 * copyright notice and this permission notice appear in all copies. 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN 17 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 18 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 */ 20 21 #include <sys/cdefs.h> 22 __KERNEL_RCSID(0, "$NetBSD: ciss.c,v 1.38 2018/02/12 23:11:00 joerg Exp $"); 23 24 #include "bio.h" 25 26 /* #define CISS_DEBUG */ 27 28 #include <sys/param.h> 29 #include <sys/systm.h> 30 #include <sys/buf.h> 31 #include <sys/ioctl.h> 32 #include <sys/device.h> 33 #include <sys/kernel.h> 34 #include <sys/malloc.h> 35 #include <sys/proc.h> 36 37 #include <sys/bus.h> 38 39 #include <dev/scsipi/scsi_all.h> 40 #include <dev/scsipi/scsi_disk.h> 41 #include <dev/scsipi/scsiconf.h> 42 #include <dev/scsipi/scsipi_all.h> 43 44 #include <dev/ic/cissreg.h> 45 #include <dev/ic/cissvar.h> 46 47 #if NBIO > 0 48 #include <dev/biovar.h> 49 #endif /* NBIO > 0 */ 50 51 #ifdef CISS_DEBUG 52 #define CISS_DPRINTF(m,a) if (ciss_debug & (m)) printf a 53 #define CISS_D_CMD 0x0001 54 #define CISS_D_INTR 0x0002 55 #define CISS_D_MISC 0x0004 56 #define CISS_D_DMA 0x0008 57 #define CISS_D_IOCTL 0x0010 58 #define CISS_D_ERR 0x0020 59 int ciss_debug = 0 60 | CISS_D_CMD 61 | CISS_D_INTR 62 | CISS_D_MISC 63 | CISS_D_DMA 64 | CISS_D_IOCTL 65 | CISS_D_ERR 66 ; 67 #else 68 #define CISS_DPRINTF(m,a) /* m, a */ 69 #endif 70 71 static void ciss_scsi_cmd(struct scsipi_channel *chan, 72 scsipi_adapter_req_t req, void *arg); 73 static int ciss_scsi_ioctl(struct scsipi_channel *chan, u_long cmd, 74 void *addr, int flag, struct proc *p); 75 static void cissminphys(struct buf *bp); 76 77 #if 0 78 static void ciss_scsi_raw_cmd(struct scsipi_channel *chan, 79 scsipi_adapter_req_t req, void *arg); 80 #endif 81 82 static int ciss_sync(struct ciss_softc *sc); 83 static void ciss_heartbeat(void *v); 84 static void ciss_shutdown(void *v); 85 86 static struct ciss_ccb *ciss_get_ccb(struct ciss_softc *sc); 87 static void ciss_put_ccb(struct ciss_ccb *ccb); 88 static int ciss_cmd(struct ciss_ccb *ccb, int flags, int wait); 89 static int ciss_done(struct ciss_ccb *ccb); 90 static int ciss_error(struct ciss_ccb *ccb); 91 struct ciss_ld *ciss_pdscan(struct ciss_softc *sc, int ld); 92 static int ciss_inq(struct ciss_softc *sc, struct ciss_inquiry *inq); 93 int ciss_ldid(struct ciss_softc *, int, struct ciss_ldid *); 94 int ciss_ldstat(struct ciss_softc *, int, struct ciss_ldstat *); 95 static int ciss_ldmap(struct ciss_softc *sc); 96 int ciss_pdid(struct ciss_softc *, u_int8_t, struct ciss_pdid *, int); 97 98 #if NBIO > 0 99 int ciss_ioctl(device_t, u_long, void *); 100 int ciss_ioctl_vol(struct ciss_softc *, struct bioc_vol *); 101 int ciss_blink(struct ciss_softc *, int, int, int, struct ciss_blink *); 102 int ciss_create_sensors(struct ciss_softc *); 103 void ciss_sensor_refresh(struct sysmon_envsys *, envsys_data_t *); 104 #endif /* NBIO > 0 */ 105 106 static struct ciss_ccb * 107 ciss_get_ccb(struct ciss_softc *sc) 108 { 109 struct ciss_ccb *ccb; 110 111 mutex_enter(&sc->sc_mutex); 112 if ((ccb = TAILQ_LAST(&sc->sc_free_ccb, ciss_queue_head))) { 113 TAILQ_REMOVE(&sc->sc_free_ccb, ccb, ccb_link); 114 ccb->ccb_state = CISS_CCB_READY; 115 } 116 mutex_exit(&sc->sc_mutex); 117 return ccb; 118 } 119 120 static void 121 ciss_put_ccb(struct ciss_ccb *ccb) 122 { 123 struct ciss_softc *sc = ccb->ccb_sc; 124 125 ccb->ccb_state = CISS_CCB_FREE; 126 mutex_enter(&sc->sc_mutex); 127 TAILQ_INSERT_TAIL(&sc->sc_free_ccb, ccb, ccb_link); 128 mutex_exit(&sc->sc_mutex); 129 } 130 131 int 132 ciss_attach(struct ciss_softc *sc) 133 { 134 struct ciss_ccb *ccb; 135 struct ciss_cmd *cmd; 136 struct ciss_inquiry *inq; 137 bus_dma_segment_t seg[1]; 138 int error, i, total, rseg, maxfer; 139 paddr_t pa; 140 141 bus_space_read_region_4(sc->sc_iot, sc->cfg_ioh, sc->cfgoff, 142 (u_int32_t *)&sc->cfg, sizeof(sc->cfg) / 4); 143 144 if (sc->cfg.signature != CISS_SIGNATURE) { 145 aprint_error(": bad sign 0x%08x\n", sc->cfg.signature); 146 return -1; 147 } 148 149 if (!(sc->cfg.methods & CISS_METH_SIMPL)) { 150 aprint_error(": not simple 0x%08x\n", sc->cfg.methods); 151 return -1; 152 } 153 154 sc->cfg.rmethod = CISS_METH_SIMPL; 155 sc->cfg.paddr_lim = 0; /* 32bit addrs */ 156 sc->cfg.int_delay = 0; /* disable coalescing */ 157 sc->cfg.int_count = 0; 158 strlcpy(sc->cfg.hostname, "HUMPPA", sizeof(sc->cfg.hostname)); 159 sc->cfg.driverf |= CISS_DRV_PRF; /* enable prefetch */ 160 if (!sc->cfg.maxsg) 161 sc->cfg.maxsg = MAXPHYS / PAGE_SIZE + 1; 162 163 bus_space_write_region_4(sc->sc_iot, sc->cfg_ioh, sc->cfgoff, 164 (u_int32_t *)&sc->cfg, sizeof(sc->cfg) / 4); 165 bus_space_barrier(sc->sc_iot, sc->cfg_ioh, sc->cfgoff, sizeof(sc->cfg), 166 BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE); 167 168 bus_space_write_4(sc->sc_iot, sc->sc_ioh, CISS_IDB, CISS_IDB_CFG); 169 bus_space_barrier(sc->sc_iot, sc->sc_ioh, CISS_IDB, 4, 170 BUS_SPACE_BARRIER_WRITE); 171 for (i = 1000; i--; DELAY(1000)) { 172 /* XXX maybe IDB is really 64bit? - hp dl380 needs this */ 173 (void)bus_space_read_4(sc->sc_iot, sc->sc_ioh, CISS_IDB + 4); 174 if (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, CISS_IDB) & CISS_IDB_CFG)) 175 break; 176 bus_space_barrier(sc->sc_iot, sc->sc_ioh, CISS_IDB, 4, 177 BUS_SPACE_BARRIER_READ); 178 } 179 180 if (bus_space_read_4(sc->sc_iot, sc->sc_ioh, CISS_IDB) & CISS_IDB_CFG) { 181 printf(": cannot set config\n"); 182 return -1; 183 } 184 185 bus_space_read_region_4(sc->sc_iot, sc->cfg_ioh, sc->cfgoff, 186 (u_int32_t *)&sc->cfg, sizeof(sc->cfg) / 4); 187 188 if (!(sc->cfg.amethod & CISS_METH_SIMPL)) { 189 printf(": cannot simplify 0x%08x\n", sc->cfg.amethod); 190 return -1; 191 } 192 193 /* i'm ready for you and i hope you're ready for me */ 194 for (i = 30000; i--; DELAY(1000)) { 195 if (bus_space_read_4(sc->sc_iot, sc->cfg_ioh, sc->cfgoff + 196 offsetof(struct ciss_config, amethod)) & CISS_METH_READY) 197 break; 198 bus_space_barrier(sc->sc_iot, sc->cfg_ioh, sc->cfgoff + 199 offsetof(struct ciss_config, amethod), 4, 200 BUS_SPACE_BARRIER_READ); 201 } 202 203 if (!(bus_space_read_4(sc->sc_iot, sc->cfg_ioh, sc->cfgoff + 204 offsetof(struct ciss_config, amethod)) & CISS_METH_READY)) { 205 aprint_error(": she never came ready for me 0x%08x\n", 206 sc->cfg.amethod); 207 return -1; 208 } 209 210 mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_VM); 211 mutex_init(&sc->sc_mutex_scratch, MUTEX_DEFAULT, IPL_VM); 212 cv_init(&sc->sc_condvar, "ciss_cmd"); 213 sc->maxcmd = sc->cfg.maxcmd; 214 sc->maxsg = sc->cfg.maxsg; 215 if (sc->maxsg > MAXPHYS / PAGE_SIZE + 1) 216 sc->maxsg = MAXPHYS / PAGE_SIZE + 1; 217 i = sizeof(struct ciss_ccb) + 218 sizeof(ccb->ccb_cmd.sgl[0]) * (sc->maxsg - 1); 219 for (sc->ccblen = 0x10; sc->ccblen < i; sc->ccblen <<= 1); 220 221 total = sc->ccblen * sc->maxcmd; 222 if ((error = bus_dmamem_alloc(sc->sc_dmat, total, PAGE_SIZE, 0, 223 sc->cmdseg, 1, &rseg, BUS_DMA_NOWAIT))) { 224 aprint_error(": cannot allocate CCBs (%d)\n", error); 225 return -1; 226 } 227 228 if ((error = bus_dmamem_map(sc->sc_dmat, sc->cmdseg, rseg, total, 229 (void **)&sc->ccbs, BUS_DMA_NOWAIT))) { 230 aprint_error(": cannot map CCBs (%d)\n", error); 231 return -1; 232 } 233 memset(sc->ccbs, 0, total); 234 235 if ((error = bus_dmamap_create(sc->sc_dmat, total, 1, 236 total, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &sc->cmdmap))) { 237 aprint_error(": cannot create CCBs dmamap (%d)\n", error); 238 bus_dmamem_free(sc->sc_dmat, sc->cmdseg, 1); 239 return -1; 240 } 241 242 if ((error = bus_dmamap_load(sc->sc_dmat, sc->cmdmap, sc->ccbs, total, 243 NULL, BUS_DMA_NOWAIT))) { 244 aprint_error(": cannot load CCBs dmamap (%d)\n", error); 245 bus_dmamem_free(sc->sc_dmat, sc->cmdseg, 1); 246 bus_dmamap_destroy(sc->sc_dmat, sc->cmdmap); 247 return -1; 248 } 249 250 TAILQ_INIT(&sc->sc_ccbq); 251 TAILQ_INIT(&sc->sc_ccbdone); 252 TAILQ_INIT(&sc->sc_free_ccb); 253 254 maxfer = sc->maxsg * PAGE_SIZE; 255 for (i = 0; total > 0 && i < sc->maxcmd; i++, total -= sc->ccblen) { 256 ccb = (struct ciss_ccb *) ((char *)sc->ccbs + i * sc->ccblen); 257 cmd = &ccb->ccb_cmd; 258 pa = sc->cmdseg[0].ds_addr + i * sc->ccblen; 259 260 ccb->ccb_sc = sc; 261 ccb->ccb_cmdpa = pa + offsetof(struct ciss_ccb, ccb_cmd); 262 ccb->ccb_state = CISS_CCB_FREE; 263 264 cmd->id = htole32(i << 2); 265 cmd->id_hi = htole32(0); 266 cmd->sgin = sc->maxsg; 267 cmd->sglen = htole16((u_int16_t)cmd->sgin); 268 cmd->err_len = htole32(sizeof(ccb->ccb_err)); 269 pa += offsetof(struct ciss_ccb, ccb_err); 270 cmd->err_pa = htole64((u_int64_t)pa); 271 272 if ((error = bus_dmamap_create(sc->sc_dmat, maxfer, sc->maxsg, 273 maxfer, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, 274 &ccb->ccb_dmamap))) 275 break; 276 277 TAILQ_INSERT_TAIL(&sc->sc_free_ccb, ccb, ccb_link); 278 } 279 280 if (i < sc->maxcmd) { 281 aprint_error(": cannot create ccb#%d dmamap (%d)\n", i, error); 282 if (i == 0) { 283 /* TODO leaking cmd's dmamaps and shitz */ 284 bus_dmamem_free(sc->sc_dmat, sc->cmdseg, 1); 285 bus_dmamap_destroy(sc->sc_dmat, sc->cmdmap); 286 return -1; 287 } 288 } 289 290 if ((error = bus_dmamem_alloc(sc->sc_dmat, PAGE_SIZE, PAGE_SIZE, 0, 291 seg, 1, &rseg, BUS_DMA_NOWAIT))) { 292 aprint_error(": cannot allocate scratch buffer (%d)\n", error); 293 return -1; 294 } 295 296 if ((error = bus_dmamem_map(sc->sc_dmat, seg, rseg, PAGE_SIZE, 297 (void **)&sc->scratch, BUS_DMA_NOWAIT))) { 298 aprint_error(": cannot map scratch buffer (%d)\n", error); 299 return -1; 300 } 301 memset(sc->scratch, 0, PAGE_SIZE); 302 sc->sc_waitflag = XS_CTL_NOSLEEP; /* can't sleep yet */ 303 304 mutex_enter(&sc->sc_mutex_scratch); /* is this really needed? */ 305 inq = sc->scratch; 306 if (ciss_inq(sc, inq)) { 307 aprint_error(": adapter inquiry failed\n"); 308 mutex_exit(&sc->sc_mutex_scratch); 309 bus_dmamem_free(sc->sc_dmat, sc->cmdseg, 1); 310 bus_dmamap_destroy(sc->sc_dmat, sc->cmdmap); 311 return -1; 312 } 313 314 if (!(inq->flags & CISS_INQ_BIGMAP)) { 315 aprint_error(": big map is not supported, flags=0x%x\n", 316 inq->flags); 317 mutex_exit(&sc->sc_mutex_scratch); 318 bus_dmamem_free(sc->sc_dmat, sc->cmdseg, 1); 319 bus_dmamap_destroy(sc->sc_dmat, sc->cmdmap); 320 return -1; 321 } 322 323 sc->maxunits = inq->numld; 324 sc->nbus = inq->nscsi_bus; 325 sc->ndrives = inq->buswidth ? inq->buswidth : 256; 326 aprint_normal(": %d LD%s, HW rev %d, FW %4.4s/%4.4s", 327 inq->numld, inq->numld == 1? "" : "s", 328 inq->hw_rev, inq->fw_running, inq->fw_stored); 329 330 if (sc->cfg.methods & CISS_METH_FIFO64) 331 aprint_normal(", 64bit fifo"); 332 else if (sc->cfg.methods & CISS_METH_FIFO64_RRO) 333 aprint_normal(", 64bit fifo rro"); 334 aprint_normal("\n"); 335 336 mutex_exit(&sc->sc_mutex_scratch); 337 338 callout_init(&sc->sc_hb, 0); 339 callout_setfunc(&sc->sc_hb, ciss_heartbeat, sc); 340 callout_schedule(&sc->sc_hb, hz * 3); 341 342 /* map LDs */ 343 if (ciss_ldmap(sc)) { 344 aprint_error_dev(sc->sc_dev, "adapter LD map failed\n"); 345 bus_dmamem_free(sc->sc_dmat, sc->cmdseg, 1); 346 bus_dmamap_destroy(sc->sc_dmat, sc->cmdmap); 347 return -1; 348 } 349 350 if (!(sc->sc_lds = malloc(sc->maxunits * sizeof(*sc->sc_lds), 351 M_DEVBUF, M_NOWAIT))) { 352 bus_dmamem_free(sc->sc_dmat, sc->cmdseg, 1); 353 bus_dmamap_destroy(sc->sc_dmat, sc->cmdmap); 354 return -1; 355 } 356 memset(sc->sc_lds, 0, sc->maxunits * sizeof(*sc->sc_lds)); 357 358 sc->sc_flush = CISS_FLUSH_ENABLE; 359 if (!(sc->sc_sh = shutdownhook_establish(ciss_shutdown, sc))) { 360 aprint_error_dev(sc->sc_dev, 361 "unable to establish shutdown hook\n"); 362 bus_dmamem_free(sc->sc_dmat, sc->cmdseg, 1); 363 bus_dmamap_destroy(sc->sc_dmat, sc->cmdmap); 364 return -1; 365 } 366 367 sc->sc_channel.chan_adapter = &sc->sc_adapter; 368 sc->sc_channel.chan_bustype = &scsi_bustype; 369 sc->sc_channel.chan_channel = 0; 370 sc->sc_channel.chan_ntargets = sc->maxunits; 371 sc->sc_channel.chan_nluns = 1; /* ciss doesn't really have SCSI luns */ 372 sc->sc_channel.chan_openings = sc->maxcmd; 373 #if NBIO > 0 374 /* XXX Reserve some ccb's for sensor and bioctl. */ 375 if (sc->sc_channel.chan_openings > 2) 376 sc->sc_channel.chan_openings -= 2; 377 #endif 378 sc->sc_channel.chan_flags = 0; 379 sc->sc_channel.chan_id = sc->maxunits; 380 381 sc->sc_adapter.adapt_dev = sc->sc_dev; 382 sc->sc_adapter.adapt_openings = sc->sc_channel.chan_openings; 383 sc->sc_adapter.adapt_max_periph = min(sc->sc_adapter.adapt_openings, 256); 384 sc->sc_adapter.adapt_request = ciss_scsi_cmd; 385 sc->sc_adapter.adapt_minphys = cissminphys; 386 sc->sc_adapter.adapt_ioctl = ciss_scsi_ioctl; 387 sc->sc_adapter.adapt_nchannels = 1; 388 config_found(sc->sc_dev, &sc->sc_channel, scsiprint); 389 390 #if 0 391 sc->sc_link_raw.adapter_softc = sc; 392 sc->sc_link.openings = sc->sc_channel.chan_openings; 393 sc->sc_link_raw.adapter = &ciss_raw_switch; 394 sc->sc_link_raw.adapter_target = sc->ndrives; 395 sc->sc_link_raw.adapter_buswidth = sc->ndrives; 396 config_found(sc->sc_dev, &sc->sc_channel, scsiprint); 397 #endif 398 399 #if NBIO > 0 400 /* now map all the physdevs into their lds */ 401 /* XXX currently we assign all of them into ld0 */ 402 for (i = 0; i < sc->maxunits && i < 1; i++) 403 if (!(sc->sc_lds[i] = ciss_pdscan(sc, i))) { 404 sc->sc_waitflag = 0; /* we can sleep now */ 405 return 0; 406 } 407 408 if (bio_register(sc->sc_dev, ciss_ioctl) != 0) 409 aprint_error_dev(sc->sc_dev, "controller registration failed"); 410 else 411 sc->sc_ioctl = ciss_ioctl; 412 if (ciss_create_sensors(sc) != 0) 413 aprint_error_dev(sc->sc_dev, "unable to create sensors"); 414 #endif 415 sc->sc_waitflag = 0; /* we can sleep now */ 416 417 return 0; 418 } 419 420 static void 421 ciss_shutdown(void *v) 422 { 423 struct ciss_softc *sc = v; 424 425 sc->sc_flush = CISS_FLUSH_DISABLE; 426 /* timeout_del(&sc->sc_hb); */ 427 ciss_sync(sc); 428 } 429 430 static void 431 cissminphys(struct buf *bp) 432 { 433 #if 0 /* TODO */ 434 #define CISS_MAXFER (PAGE_SIZE * (sc->maxsg + 1)) 435 if (bp->b_bcount > CISS_MAXFER) 436 bp->b_bcount = CISS_MAXFER; 437 #endif 438 minphys(bp); 439 } 440 441 static struct ciss_ccb * 442 ciss_poll1(struct ciss_softc *sc) 443 { 444 struct ciss_ccb *ccb; 445 uint32_t id; 446 447 if (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, CISS_ISR) & sc->iem)) { 448 CISS_DPRINTF(CISS_D_CMD, ("N")); 449 return NULL; 450 } 451 452 if (sc->cfg.methods & CISS_METH_FIFO64) { 453 if (bus_space_read_4(sc->sc_iot, sc->sc_ioh, CISS_OUTQ64_HI) == 454 0xffffffff) { 455 CISS_DPRINTF(CISS_D_CMD, ("Q")); 456 return NULL; 457 } 458 id = bus_space_read_4(sc->sc_iot, sc->sc_ioh, CISS_OUTQ64_LO); 459 } else if (sc->cfg.methods & CISS_METH_FIFO64_RRO) { 460 id = bus_space_read_4(sc->sc_iot, sc->sc_ioh, CISS_OUTQ64_LO); 461 if (id == 0xffffffff) { 462 CISS_DPRINTF(CISS_D_CMD, ("Q")); 463 return NULL; 464 } 465 (void)bus_space_read_4(sc->sc_iot, sc->sc_ioh, CISS_OUTQ64_HI); 466 } else { 467 id = bus_space_read_4(sc->sc_iot, sc->sc_ioh, CISS_OUTQ); 468 if (id == 0xffffffff) { 469 CISS_DPRINTF(CISS_D_CMD, ("Q")); 470 return NULL; 471 } 472 } 473 474 CISS_DPRINTF(CISS_D_CMD, ("got=0x%x ", id)); 475 ccb = (struct ciss_ccb *) ((char *)sc->ccbs + (id >> 2) * sc->ccblen); 476 ccb->ccb_cmd.id = htole32(id); 477 ccb->ccb_cmd.id_hi = htole32(0); 478 return ccb; 479 } 480 481 static int 482 ciss_poll(struct ciss_softc *sc, struct ciss_ccb *ccb, int ms) 483 { 484 struct ciss_ccb *ccb1; 485 486 ms /= 10; 487 488 while (ms-- > 0) { 489 DELAY(10); 490 ccb1 = ciss_poll1(sc); 491 if (ccb1 == NULL) 492 continue; 493 ciss_done(ccb1); 494 if (ccb1 == ccb) 495 return 0; 496 } 497 498 return ETIMEDOUT; 499 } 500 501 static int 502 ciss_wait(struct ciss_softc *sc, struct ciss_ccb *ccb, int ms) 503 { 504 int tohz, etick; 505 506 tohz = mstohz(ms); 507 if (tohz == 0) 508 tohz = 1; 509 etick = hardclock_ticks + tohz; 510 511 for (;;) { 512 ccb->ccb_state = CISS_CCB_POLL; 513 CISS_DPRINTF(CISS_D_CMD, ("cv_timedwait(%d) ", tohz)); 514 mutex_enter(&sc->sc_mutex); 515 if (cv_timedwait(&sc->sc_condvar, &sc->sc_mutex, tohz) 516 == EWOULDBLOCK) { 517 mutex_exit(&sc->sc_mutex); 518 return EWOULDBLOCK; 519 } 520 mutex_exit(&sc->sc_mutex); 521 if (ccb->ccb_state == CISS_CCB_ONQ) { 522 ciss_done(ccb); 523 return 0; 524 } 525 tohz = etick - hardclock_ticks; 526 if (tohz <= 0) 527 return EWOULDBLOCK; 528 CISS_DPRINTF(CISS_D_CMD, ("T")); 529 } 530 } 531 532 /* 533 * submit a command and optionally wait for completition. 534 * wait arg abuses XS_CTL_POLL|XS_CTL_NOSLEEP flags to request 535 * to wait (XS_CTL_POLL) and to allow tsleep() (!XS_CTL_NOSLEEP) 536 * instead of busy loop waiting 537 */ 538 static int 539 ciss_cmd(struct ciss_ccb *ccb, int flags, int wait) 540 { 541 struct ciss_softc *sc = ccb->ccb_sc; 542 struct ciss_cmd *cmd = &ccb->ccb_cmd; 543 bus_dmamap_t dmap = ccb->ccb_dmamap; 544 u_int64_t addr; 545 int i, error = 0; 546 547 if (ccb->ccb_state != CISS_CCB_READY) { 548 printf("%s: ccb %d not ready state=0x%x\n", device_xname(sc->sc_dev), 549 cmd->id, ccb->ccb_state); 550 return (EINVAL); 551 } 552 553 if (ccb->ccb_data) { 554 bus_dma_segment_t *sgd; 555 556 if ((error = bus_dmamap_load(sc->sc_dmat, dmap, ccb->ccb_data, 557 ccb->ccb_len, NULL, flags))) { 558 if (error == EFBIG) 559 printf("more than %d dma segs\n", sc->maxsg); 560 else 561 printf("error %d loading dma map\n", error); 562 ciss_put_ccb(ccb); 563 return (error); 564 } 565 cmd->sgin = dmap->dm_nsegs; 566 567 sgd = dmap->dm_segs; 568 CISS_DPRINTF(CISS_D_DMA, ("data=%p/%zu<%#" PRIxPADDR "/%zu", 569 ccb->ccb_data, ccb->ccb_len, sgd->ds_addr, sgd->ds_len)); 570 571 for (i = 0; i < dmap->dm_nsegs; sgd++, i++) { 572 cmd->sgl[i].addr_lo = htole32(sgd->ds_addr); 573 cmd->sgl[i].addr_hi = 574 htole32((u_int64_t)sgd->ds_addr >> 32); 575 cmd->sgl[i].len = htole32(sgd->ds_len); 576 cmd->sgl[i].flags = htole32(0); 577 if (i) { 578 CISS_DPRINTF(CISS_D_DMA, 579 (",%#" PRIxPADDR "/%zu", sgd->ds_addr, 580 sgd->ds_len)); 581 } 582 } 583 584 CISS_DPRINTF(CISS_D_DMA, ("> ")); 585 586 bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize, 587 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 588 } else 589 cmd->sgin = 0; 590 cmd->sglen = htole16((u_int16_t)cmd->sgin); 591 memset(&ccb->ccb_err, 0, sizeof(ccb->ccb_err)); 592 593 bus_dmamap_sync(sc->sc_dmat, sc->cmdmap, 0, sc->cmdmap->dm_mapsize, 594 BUS_DMASYNC_PREWRITE); 595 596 #ifndef CISS_NO_INTERRUPT_HACK 597 if ((wait & (XS_CTL_POLL|XS_CTL_NOSLEEP)) == (XS_CTL_POLL|XS_CTL_NOSLEEP)) 598 bus_space_write_4(sc->sc_iot, sc->sc_ioh, CISS_IMR, 599 bus_space_read_4(sc->sc_iot, sc->sc_ioh, CISS_IMR) | sc->iem); 600 #endif 601 602 mutex_enter(&sc->sc_mutex); 603 TAILQ_INSERT_TAIL(&sc->sc_ccbq, ccb, ccb_link); 604 mutex_exit(&sc->sc_mutex); 605 ccb->ccb_state = CISS_CCB_ONQ; 606 CISS_DPRINTF(CISS_D_CMD, ("submit=0x%x ", cmd->id)); 607 if (sc->cfg.methods & (CISS_METH_FIFO64|CISS_METH_FIFO64_RRO)) { 608 /* 609 * Write the upper 32bits immediately before the lower 610 * 32bits and set bit 63 to indicate 64bit FIFO mode. 611 */ 612 addr = (u_int64_t)ccb->ccb_cmdpa; 613 bus_space_write_4(sc->sc_iot, sc->sc_ioh, CISS_INQ64_HI, 614 (addr >> 32) | 0x80000000); 615 bus_space_write_4(sc->sc_iot, sc->sc_ioh, CISS_INQ64_LO, 616 addr & 0x00000000ffffffffULL); 617 } else 618 bus_space_write_4(sc->sc_iot, sc->sc_ioh, CISS_INQ, 619 ccb->ccb_cmdpa); 620 621 if (wait & XS_CTL_POLL) { 622 int ms; 623 CISS_DPRINTF(CISS_D_CMD, ("waiting ")); 624 625 ms = ccb->ccb_xs ? ccb->ccb_xs->timeout : 60000; 626 if (wait & XS_CTL_NOSLEEP) 627 error = ciss_poll(sc, ccb, ms); 628 else 629 error = ciss_wait(sc, ccb, ms); 630 631 /* if never got a chance to be done above... */ 632 if (ccb->ccb_state != CISS_CCB_FREE) { 633 KASSERT(error); 634 ccb->ccb_err.cmd_stat = CISS_ERR_TMO; 635 error = ciss_done(ccb); 636 } 637 638 CISS_DPRINTF(CISS_D_CMD, ("done %d:%d", 639 ccb->ccb_err.cmd_stat, ccb->ccb_err.scsi_stat)); 640 } 641 642 #ifndef CISS_NO_INTERRUPT_HACK 643 if ((wait & (XS_CTL_POLL|XS_CTL_NOSLEEP)) == (XS_CTL_POLL|XS_CTL_NOSLEEP)) 644 bus_space_write_4(sc->sc_iot, sc->sc_ioh, CISS_IMR, 645 bus_space_read_4(sc->sc_iot, sc->sc_ioh, CISS_IMR) & ~sc->iem); 646 #endif 647 648 return (error); 649 } 650 651 static int 652 ciss_done(struct ciss_ccb *ccb) 653 { 654 struct ciss_softc *sc = ccb->ccb_sc; 655 struct scsipi_xfer *xs = ccb->ccb_xs; 656 struct ciss_cmd *cmd; 657 int error = 0; 658 659 CISS_DPRINTF(CISS_D_CMD, ("ciss_done(%p) ", ccb)); 660 661 if (ccb->ccb_state != CISS_CCB_ONQ) { 662 printf("%s: unqueued ccb %p ready, state=0x%x\n", 663 device_xname(sc->sc_dev), ccb, ccb->ccb_state); 664 return 1; 665 } 666 667 ccb->ccb_state = CISS_CCB_READY; 668 mutex_enter(&sc->sc_mutex); 669 TAILQ_REMOVE(&sc->sc_ccbq, ccb, ccb_link); 670 mutex_exit(&sc->sc_mutex); 671 672 if (ccb->ccb_cmd.id & CISS_CMD_ERR) 673 error = ciss_error(ccb); 674 675 cmd = &ccb->ccb_cmd; 676 if (ccb->ccb_data) { 677 bus_dmamap_sync(sc->sc_dmat, ccb->ccb_dmamap, 0, 678 ccb->ccb_dmamap->dm_mapsize, (cmd->flags & CISS_CDB_IN) ? 679 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 680 bus_dmamap_unload(sc->sc_dmat, ccb->ccb_dmamap); 681 ccb->ccb_xs = NULL; 682 ccb->ccb_data = NULL; 683 } 684 685 ciss_put_ccb(ccb); 686 687 if (xs) { 688 xs->resid = 0; 689 CISS_DPRINTF(CISS_D_CMD, ("scsipi_done(%p) ", xs)); 690 if (xs->cmd->opcode == INQUIRY) { 691 struct scsipi_inquiry_data *inq; 692 inq = (struct scsipi_inquiry_data *)xs->data; 693 if ((inq->version & SID_ANSII) == 0 && 694 (inq->flags3 & SID_CmdQue) != 0) { 695 inq->version |= 2; 696 } 697 } 698 scsipi_done(xs); 699 } 700 701 return error; 702 } 703 704 static int 705 ciss_error(struct ciss_ccb *ccb) 706 { 707 struct ciss_softc *sc = ccb->ccb_sc; 708 struct ciss_error *err = &ccb->ccb_err; 709 struct scsipi_xfer *xs = ccb->ccb_xs; 710 int rv; 711 712 switch ((rv = le16toh(err->cmd_stat))) { 713 case CISS_ERR_OK: 714 rv = 0; 715 break; 716 717 case CISS_ERR_INVCMD: 718 if (xs == NULL || 719 xs->cmd->opcode != SCSI_SYNCHRONIZE_CACHE_10) 720 printf("%s: invalid cmd 0x%x: 0x%x is not valid @ 0x%x[%d]\n", 721 device_xname(sc->sc_dev), ccb->ccb_cmd.id, 722 err->err_info, err->err_type[3], err->err_type[2]); 723 if (xs) { 724 memset(&xs->sense, 0, sizeof(xs->sense)); 725 xs->sense.scsi_sense.response_code = 726 SSD_RCODE_CURRENT | SSD_RCODE_VALID; 727 xs->sense.scsi_sense.flags = SKEY_ILLEGAL_REQUEST; 728 xs->sense.scsi_sense.asc = 0x24; /* ill field */ 729 xs->sense.scsi_sense.ascq = 0x0; 730 xs->error = XS_SENSE; 731 } 732 rv = EIO; 733 break; 734 735 case CISS_ERR_TMO: 736 xs->error = XS_TIMEOUT; 737 rv = ETIMEDOUT; 738 break; 739 740 case CISS_ERR_UNRUN: 741 /* Underrun */ 742 xs->resid = le32toh(err->resid); 743 CISS_DPRINTF(CISS_D_CMD, (" underrun resid=0x%x ", 744 xs->resid)); 745 rv = EIO; 746 break; 747 default: 748 if (xs) { 749 CISS_DPRINTF(CISS_D_CMD, ("scsi_stat=%x ", err->scsi_stat)); 750 switch (err->scsi_stat) { 751 case SCSI_CHECK: 752 xs->error = XS_SENSE; 753 memcpy(&xs->sense, &err->sense[0], 754 sizeof(xs->sense)); 755 CISS_DPRINTF(CISS_D_CMD, (" sense=%02x %02x %02x %02x ", 756 err->sense[0], err->sense[1], err->sense[2], err->sense[3])); 757 rv = EIO; 758 break; 759 760 case XS_BUSY: 761 xs->error = XS_BUSY; 762 rv = EBUSY; 763 break; 764 765 default: 766 CISS_DPRINTF(CISS_D_ERR, ("%s: " 767 "cmd_stat=%x scsi_stat=0x%x resid=0x%x\n", 768 device_xname(sc->sc_dev), rv, err->scsi_stat, 769 le32toh(err->resid))); 770 printf("ciss driver stuffup in %s:%d: %s()\n", 771 __FILE__, __LINE__, __func__); 772 xs->error = XS_DRIVER_STUFFUP; 773 rv = EIO; 774 break; 775 } 776 xs->resid = le32toh(err->resid); 777 } else 778 rv = EIO; 779 } 780 ccb->ccb_cmd.id &= htole32(~3); 781 782 return rv; 783 } 784 785 static int 786 ciss_inq(struct ciss_softc *sc, struct ciss_inquiry *inq) 787 { 788 struct ciss_ccb *ccb; 789 struct ciss_cmd *cmd; 790 791 ccb = ciss_get_ccb(sc); 792 ccb->ccb_len = sizeof(*inq); 793 ccb->ccb_data = inq; 794 ccb->ccb_xs = NULL; 795 cmd = &ccb->ccb_cmd; 796 cmd->tgt = htole32(CISS_CMD_MODE_PERIPH); 797 cmd->tgt2 = 0; 798 cmd->cdblen = 10; 799 cmd->flags = CISS_CDB_CMD | CISS_CDB_SIMPL | CISS_CDB_IN; 800 cmd->tmo = htole16(0); 801 memset(&cmd->cdb[0], 0, sizeof(cmd->cdb)); 802 cmd->cdb[0] = CISS_CMD_CTRL_GET; 803 cmd->cdb[6] = CISS_CMS_CTRL_CTRL; 804 cmd->cdb[7] = sizeof(*inq) >> 8; /* biiiig endian */ 805 cmd->cdb[8] = sizeof(*inq) & 0xff; 806 807 return ciss_cmd(ccb, BUS_DMA_NOWAIT, XS_CTL_POLL|XS_CTL_NOSLEEP); 808 } 809 810 static int 811 ciss_ldmap(struct ciss_softc *sc) 812 { 813 struct ciss_ccb *ccb; 814 struct ciss_cmd *cmd; 815 struct ciss_ldmap *lmap; 816 int total, rv; 817 818 mutex_enter(&sc->sc_mutex_scratch); 819 lmap = sc->scratch; 820 lmap->size = htobe32(sc->maxunits * sizeof(lmap->map)); 821 total = sizeof(*lmap) + (sc->maxunits - 1) * sizeof(lmap->map); 822 823 ccb = ciss_get_ccb(sc); 824 ccb->ccb_len = total; 825 ccb->ccb_data = lmap; 826 ccb->ccb_xs = NULL; 827 cmd = &ccb->ccb_cmd; 828 cmd->tgt = CISS_CMD_MODE_PERIPH; 829 cmd->tgt2 = 0; 830 cmd->cdblen = 12; 831 cmd->flags = CISS_CDB_CMD | CISS_CDB_SIMPL | CISS_CDB_IN; 832 cmd->tmo = htole16(30); 833 memset(&cmd->cdb[0], 0, sizeof(cmd->cdb)); 834 cmd->cdb[0] = CISS_CMD_LDMAP; 835 cmd->cdb[8] = total >> 8; /* biiiig endian */ 836 cmd->cdb[9] = total & 0xff; 837 838 rv = ciss_cmd(ccb, BUS_DMA_NOWAIT, XS_CTL_POLL|XS_CTL_NOSLEEP); 839 840 if (rv) { 841 mutex_exit(&sc->sc_mutex_scratch); 842 return rv; 843 } 844 845 CISS_DPRINTF(CISS_D_MISC, ("lmap %x:%x\n", 846 lmap->map[0].tgt, lmap->map[0].tgt2)); 847 848 mutex_exit(&sc->sc_mutex_scratch); 849 return 0; 850 } 851 852 static int 853 ciss_sync(struct ciss_softc *sc) 854 { 855 struct ciss_ccb *ccb; 856 struct ciss_cmd *cmd; 857 struct ciss_flush *flush; 858 int rv; 859 860 mutex_enter(&sc->sc_mutex_scratch); 861 flush = sc->scratch; 862 memset(flush, 0, sizeof(*flush)); 863 flush->flush = sc->sc_flush; 864 865 ccb = ciss_get_ccb(sc); 866 ccb->ccb_len = sizeof(*flush); 867 ccb->ccb_data = flush; 868 ccb->ccb_xs = NULL; 869 cmd = &ccb->ccb_cmd; 870 cmd->tgt = CISS_CMD_MODE_PERIPH; 871 cmd->tgt2 = 0; 872 cmd->cdblen = 10; 873 cmd->flags = CISS_CDB_CMD | CISS_CDB_SIMPL | CISS_CDB_OUT; 874 cmd->tmo = 0; 875 memset(&cmd->cdb[0], 0, sizeof(cmd->cdb)); 876 cmd->cdb[0] = CISS_CMD_CTRL_SET; 877 cmd->cdb[6] = CISS_CMS_CTRL_FLUSH; 878 cmd->cdb[7] = sizeof(*flush) >> 8; /* biiiig endian */ 879 cmd->cdb[8] = sizeof(*flush) & 0xff; 880 881 rv = ciss_cmd(ccb, BUS_DMA_NOWAIT, XS_CTL_POLL|XS_CTL_NOSLEEP); 882 mutex_exit(&sc->sc_mutex_scratch); 883 884 return rv; 885 } 886 887 int 888 ciss_ldid(struct ciss_softc *sc, int target, struct ciss_ldid *id) 889 { 890 struct ciss_ccb *ccb; 891 struct ciss_cmd *cmd; 892 893 ccb = ciss_get_ccb(sc); 894 if (ccb == NULL) 895 return ENOMEM; 896 ccb->ccb_len = sizeof(*id); 897 ccb->ccb_data = id; 898 ccb->ccb_xs = NULL; 899 cmd = &ccb->ccb_cmd; 900 cmd->tgt = htole32(CISS_CMD_MODE_PERIPH); 901 cmd->tgt2 = 0; 902 cmd->cdblen = 10; 903 cmd->flags = CISS_CDB_CMD | CISS_CDB_SIMPL | CISS_CDB_IN; 904 cmd->tmo = htole16(0); 905 memset(&cmd->cdb[0], 0, sizeof(cmd->cdb)); 906 cmd->cdb[0] = CISS_CMD_CTRL_GET; 907 cmd->cdb[1] = target; 908 cmd->cdb[6] = CISS_CMS_CTRL_LDIDEXT; 909 cmd->cdb[7] = sizeof(*id) >> 8; /* biiiig endian */ 910 cmd->cdb[8] = sizeof(*id) & 0xff; 911 912 return ciss_cmd(ccb, BUS_DMA_NOWAIT, XS_CTL_POLL | sc->sc_waitflag); 913 } 914 915 int 916 ciss_ldstat(struct ciss_softc *sc, int target, struct ciss_ldstat *stat) 917 { 918 struct ciss_ccb *ccb; 919 struct ciss_cmd *cmd; 920 921 ccb = ciss_get_ccb(sc); 922 if (ccb == NULL) 923 return ENOMEM; 924 ccb->ccb_len = sizeof(*stat); 925 ccb->ccb_data = stat; 926 ccb->ccb_xs = NULL; 927 cmd = &ccb->ccb_cmd; 928 cmd->tgt = htole32(CISS_CMD_MODE_PERIPH); 929 cmd->tgt2 = 0; 930 cmd->cdblen = 10; 931 cmd->flags = CISS_CDB_CMD | CISS_CDB_SIMPL | CISS_CDB_IN; 932 cmd->tmo = htole16(0); 933 memset(&cmd->cdb[0], 0, sizeof(cmd->cdb)); 934 cmd->cdb[0] = CISS_CMD_CTRL_GET; 935 cmd->cdb[1] = target; 936 cmd->cdb[6] = CISS_CMS_CTRL_LDSTAT; 937 cmd->cdb[7] = sizeof(*stat) >> 8; /* biiiig endian */ 938 cmd->cdb[8] = sizeof(*stat) & 0xff; 939 940 return ciss_cmd(ccb, BUS_DMA_NOWAIT, XS_CTL_POLL | sc->sc_waitflag); 941 } 942 943 int 944 ciss_pdid(struct ciss_softc *sc, u_int8_t drv, struct ciss_pdid *id, int wait) 945 { 946 struct ciss_ccb *ccb; 947 struct ciss_cmd *cmd; 948 949 ccb = ciss_get_ccb(sc); 950 if (ccb == NULL) 951 return ENOMEM; 952 ccb->ccb_len = sizeof(*id); 953 ccb->ccb_data = id; 954 ccb->ccb_xs = NULL; 955 cmd = &ccb->ccb_cmd; 956 cmd->tgt = htole32(CISS_CMD_MODE_PERIPH); 957 cmd->tgt2 = 0; 958 cmd->cdblen = 10; 959 cmd->flags = CISS_CDB_CMD | CISS_CDB_SIMPL | CISS_CDB_IN; 960 cmd->tmo = htole16(0); 961 memset(&cmd->cdb[0], 0, sizeof(cmd->cdb)); 962 cmd->cdb[0] = CISS_CMD_CTRL_GET; 963 cmd->cdb[2] = drv; 964 cmd->cdb[6] = CISS_CMS_CTRL_PDID; 965 cmd->cdb[7] = sizeof(*id) >> 8; /* biiiig endian */ 966 cmd->cdb[8] = sizeof(*id) & 0xff; 967 968 return ciss_cmd(ccb, BUS_DMA_NOWAIT, wait); 969 } 970 971 972 struct ciss_ld * 973 ciss_pdscan(struct ciss_softc *sc, int ld) 974 { 975 struct ciss_pdid *pdid; 976 struct ciss_ld *ldp; 977 u_int8_t drv, buf[128]; 978 int i, j, k = 0; 979 980 mutex_enter(&sc->sc_mutex_scratch); 981 pdid = sc->scratch; 982 if (sc->ndrives == 256) { 983 for (i = 0; i < CISS_BIGBIT; i++) 984 if (!ciss_pdid(sc, i, pdid, 985 XS_CTL_POLL|XS_CTL_NOSLEEP) && 986 (pdid->present & CISS_PD_PRESENT)) 987 buf[k++] = i; 988 } else 989 for (i = 0; i < sc->nbus; i++) 990 for (j = 0; j < sc->ndrives; j++) { 991 drv = CISS_BIGBIT + i * sc->ndrives + j; 992 if (!ciss_pdid(sc, drv, pdid, 993 XS_CTL_POLL|XS_CTL_NOSLEEP)) 994 buf[k++] = drv; 995 } 996 mutex_exit(&sc->sc_mutex_scratch); 997 998 if (!k) 999 return NULL; 1000 1001 ldp = malloc(sizeof(*ldp) + (k-1), M_DEVBUF, M_NOWAIT); 1002 if (!ldp) 1003 return NULL; 1004 1005 memset(&ldp->bling, 0, sizeof(ldp->bling)); 1006 ldp->ndrives = k; 1007 ldp->xname[0] = 0; 1008 memcpy(ldp->tgts, buf, k); 1009 return ldp; 1010 } 1011 1012 #if 0 1013 static void 1014 ciss_scsi_raw_cmd(struct scsipi_channel *chan, scsipi_adapter_req_t req, 1015 void *arg) /* TODO */ 1016 { 1017 struct scsipi_xfer *xs = (struct scsipi_xfer *) arg; 1018 struct ciss_rawsoftc *rsc = device_private( 1019 chan->chan_adapter->adapt_dev); 1020 struct ciss_softc *sc = rsc->sc_softc; 1021 struct ciss_ccb *ccb; 1022 struct ciss_cmd *cmd; 1023 int error; 1024 1025 CISS_DPRINTF(CISS_D_CMD, ("ciss_scsi_raw_cmd ")); 1026 1027 switch (req) 1028 { 1029 case ADAPTER_REQ_RUN_XFER: 1030 if (xs->cmdlen > CISS_MAX_CDB) { 1031 CISS_DPRINTF(CISS_D_CMD, ("CDB too big %p ", xs)); 1032 memset(&xs->sense, 0, sizeof(xs->sense)); 1033 printf("ciss driver stuffup in %s:%d: %s()\n", 1034 __FILE__, __LINE__, __func__); 1035 xs->error = XS_DRIVER_STUFFUP; 1036 scsipi_done(xs); 1037 break; 1038 } 1039 1040 error = 0; 1041 xs->error = XS_NOERROR; 1042 1043 /* TODO check this target has not yet employed w/ any volume */ 1044 1045 ccb = ciss_get_ccb(sc); 1046 cmd = &ccb->ccb_cmd; 1047 ccb->ccb_len = xs->datalen; 1048 ccb->ccb_data = xs->data; 1049 ccb->ccb_xs = xs; 1050 1051 cmd->cdblen = xs->cmdlen; 1052 cmd->flags = CISS_CDB_CMD | CISS_CDB_SIMPL; 1053 if (xs->xs_control & XS_CTL_DATA_IN) 1054 cmd->flags |= CISS_CDB_IN; 1055 else if (xs->xs_control & XS_CTL_DATA_OUT) 1056 cmd->flags |= CISS_CDB_OUT; 1057 cmd->tmo = xs->timeout < 1000? 1 : xs->timeout / 1000; 1058 memset(&cmd->cdb[0], 0, sizeof(cmd->cdb)); 1059 memcpy(&cmd->cdb[0], xs->cmd, CISS_MAX_CDB); 1060 1061 if (ciss_cmd(ccb, BUS_DMA_WAITOK, 1062 xs->xs_control & (XS_CTL_POLL|XS_CTL_NOSLEEP))) { 1063 printf("ciss driver stuffup in %s:%d: %s()\n", 1064 __FILE__, __LINE__, __func__); 1065 xs->error = XS_DRIVER_STUFFUP; 1066 scsipi_done(xs); 1067 break; 1068 } 1069 1070 break; 1071 1072 case ADAPTER_REQ_GROW_RESOURCES: 1073 /* 1074 * Not supported. 1075 */ 1076 break; 1077 1078 case ADAPTER_REQ_SET_XFER_MODE: 1079 /* 1080 * We can't change the transfer mode, but at least let 1081 * scsipi know what the adapter has negociated. 1082 */ 1083 /* Get xfer mode and return it */ 1084 break; 1085 } 1086 } 1087 #endif 1088 1089 static void 1090 ciss_scsi_cmd(struct scsipi_channel *chan, scsipi_adapter_req_t req, 1091 void *arg) 1092 { 1093 struct scsipi_xfer *xs; 1094 struct scsipi_xfer_mode *xm; 1095 struct ciss_softc *sc = device_private(chan->chan_adapter->adapt_dev); 1096 u_int8_t target; 1097 struct ciss_ccb *ccb; 1098 struct ciss_cmd *cmd; 1099 1100 CISS_DPRINTF(CISS_D_CMD, ("ciss_scsi_cmd ")); 1101 1102 switch (req) 1103 { 1104 case ADAPTER_REQ_RUN_XFER: 1105 xs = (struct scsipi_xfer *) arg; 1106 target = xs->xs_periph->periph_target; 1107 CISS_DPRINTF(CISS_D_CMD, ("targ=%d ", target)); 1108 if (xs->cmdlen > CISS_MAX_CDB) { 1109 CISS_DPRINTF(CISS_D_CMD, ("CDB too big %p ", xs)); 1110 memset(&xs->sense, 0, sizeof(xs->sense)); 1111 xs->error = XS_SENSE; 1112 printf("ciss driver stuffup in %s:%d: %s()\n", 1113 __FILE__, __LINE__, __func__); 1114 scsipi_done(xs); 1115 break; 1116 } 1117 1118 xs->error = XS_NOERROR; 1119 1120 /* XXX emulate SYNCHRONIZE_CACHE ??? */ 1121 1122 ccb = ciss_get_ccb(sc); 1123 cmd = &ccb->ccb_cmd; 1124 ccb->ccb_len = xs->datalen; 1125 ccb->ccb_data = xs->data; 1126 ccb->ccb_xs = xs; 1127 cmd->tgt = CISS_CMD_MODE_LD | target; 1128 cmd->tgt2 = 0; 1129 cmd->cdblen = xs->cmdlen; 1130 cmd->flags = CISS_CDB_CMD | CISS_CDB_SIMPL; 1131 if (xs->xs_control & XS_CTL_DATA_IN) 1132 cmd->flags |= CISS_CDB_IN; 1133 else if (xs->xs_control & XS_CTL_DATA_OUT) 1134 cmd->flags |= CISS_CDB_OUT; 1135 cmd->tmo = htole16(xs->timeout < 1000? 1 : xs->timeout / 1000); 1136 memset(&cmd->cdb[0], 0, sizeof(cmd->cdb)); 1137 memcpy(&cmd->cdb[0], xs->cmd, CISS_MAX_CDB); 1138 CISS_DPRINTF(CISS_D_CMD, ("cmd=%02x %02x %02x %02x %02x %02x ", 1139 cmd->cdb[0], cmd->cdb[1], cmd->cdb[2], 1140 cmd->cdb[3], cmd->cdb[4], cmd->cdb[5])); 1141 1142 if (ciss_cmd(ccb, BUS_DMA_WAITOK, 1143 xs->xs_control & (XS_CTL_POLL|XS_CTL_NOSLEEP))) { 1144 printf("ciss driver stuffup in %s:%d: %s()\n", 1145 __FILE__, __LINE__, __func__); 1146 xs->error = XS_DRIVER_STUFFUP; 1147 scsipi_done(xs); 1148 return; 1149 } 1150 1151 break; 1152 case ADAPTER_REQ_GROW_RESOURCES: 1153 /* 1154 * Not supported. 1155 */ 1156 break; 1157 case ADAPTER_REQ_SET_XFER_MODE: 1158 /* 1159 * We can't change the transfer mode, but at least let 1160 * scsipi know what the adapter has negociated. 1161 */ 1162 xm = (struct scsipi_xfer_mode *)arg; 1163 xm->xm_mode |= PERIPH_CAP_TQING; 1164 scsipi_async_event(chan, ASYNC_EVENT_XFER_MODE, xm); 1165 break; 1166 default: 1167 printf("%s: %d %d unsupported\n", __func__, __LINE__, req); 1168 } 1169 } 1170 1171 int 1172 ciss_intr(void *v) 1173 { 1174 struct ciss_softc *sc = v; 1175 struct ciss_ccb *ccb; 1176 u_int32_t id; 1177 bus_size_t reg; 1178 int hit = 0; 1179 1180 CISS_DPRINTF(CISS_D_INTR, ("intr ")); 1181 1182 if (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, CISS_ISR) & sc->iem)) 1183 return 0; 1184 1185 if (sc->cfg.methods & CISS_METH_FIFO64) 1186 reg = CISS_OUTQ64_HI; 1187 else if (sc->cfg.methods & CISS_METH_FIFO64_RRO) 1188 reg = CISS_OUTQ64_LO; 1189 else 1190 reg = CISS_OUTQ; 1191 while ((id = bus_space_read_4(sc->sc_iot, sc->sc_ioh, reg)) != 1192 0xffffffff) { 1193 if (reg == CISS_OUTQ64_HI) 1194 id = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 1195 CISS_OUTQ64_LO); 1196 else if (reg == CISS_OUTQ64_LO) 1197 (void)bus_space_read_4(sc->sc_iot, sc->sc_ioh, 1198 CISS_OUTQ64_HI); 1199 1200 ccb = (struct ciss_ccb *) ((char *)sc->ccbs + (id >> 2) * sc->ccblen); 1201 ccb->ccb_cmd.id = htole32(id); 1202 ccb->ccb_cmd.id_hi = htole32(0); /* ignore the upper 32bits */ 1203 if (ccb->ccb_state == CISS_CCB_POLL) { 1204 ccb->ccb_state = CISS_CCB_ONQ; 1205 mutex_enter(&sc->sc_mutex); 1206 cv_broadcast(&sc->sc_condvar); 1207 mutex_exit(&sc->sc_mutex); 1208 } else 1209 ciss_done(ccb); 1210 1211 hit = 1; 1212 } 1213 1214 CISS_DPRINTF(CISS_D_INTR, ("exit\n")); 1215 return hit; 1216 } 1217 1218 static void 1219 ciss_heartbeat(void *v) 1220 { 1221 struct ciss_softc *sc = v; 1222 u_int32_t hb; 1223 1224 hb = bus_space_read_4(sc->sc_iot, sc->cfg_ioh, 1225 sc->cfgoff + offsetof(struct ciss_config, heartbeat)); 1226 if (hb == sc->heartbeat) { 1227 sc->fibrillation++; 1228 CISS_DPRINTF(CISS_D_ERR, ("%s: fibrillation #%d (value=%d)\n", 1229 device_xname(sc->sc_dev), sc->fibrillation, hb)); 1230 if (sc->fibrillation >= 11) { 1231 /* No heartbeat for 33 seconds */ 1232 panic("%s: dead", device_xname(sc->sc_dev)); /* XXX reset! */ 1233 } 1234 } else { 1235 sc->heartbeat = hb; 1236 if (sc->fibrillation) { 1237 CISS_DPRINTF(CISS_D_ERR, ("%s: " 1238 "fibrillation ended (value=%d)\n", 1239 device_xname(sc->sc_dev), hb)); 1240 } 1241 sc->fibrillation = 0; 1242 } 1243 1244 callout_schedule(&sc->sc_hb, hz * 3); 1245 } 1246 1247 static int 1248 ciss_scsi_ioctl(struct scsipi_channel *chan, u_long cmd, 1249 void *addr, int flag, struct proc *p) 1250 { 1251 #if NBIO > 0 1252 return ciss_ioctl(chan->chan_adapter->adapt_dev, cmd, addr); 1253 #else 1254 return ENOTTY; 1255 #endif 1256 } 1257 1258 #if NBIO > 0 1259 const int ciss_level[] = { 0, 4, 1, 5, 51, 7 }; 1260 const int ciss_stat[] = { BIOC_SVONLINE, BIOC_SVOFFLINE, BIOC_SVOFFLINE, 1261 BIOC_SVDEGRADED, BIOC_SVREBUILD, BIOC_SVREBUILD, BIOC_SVDEGRADED, 1262 BIOC_SVDEGRADED, BIOC_SVINVALID, BIOC_SVINVALID, BIOC_SVBUILDING, 1263 BIOC_SVOFFLINE, BIOC_SVBUILDING }; 1264 1265 int 1266 ciss_ioctl(device_t dev, u_long cmd, void *addr) 1267 { 1268 struct ciss_softc *sc = device_private(dev); 1269 struct bioc_inq *bi; 1270 struct bioc_disk *bd; 1271 struct bioc_blink *bb; 1272 struct ciss_ldstat *ldstat; 1273 struct ciss_pdid *pdid; 1274 struct ciss_blink *blink; 1275 struct ciss_ld *ldp; 1276 u_int8_t drv; 1277 int ld, pd, error = 0; 1278 1279 switch (cmd) { 1280 case BIOCINQ: 1281 bi = (struct bioc_inq *)addr; 1282 strlcpy(bi->bi_dev, device_xname(sc->sc_dev), sizeof(bi->bi_dev)); 1283 bi->bi_novol = sc->maxunits; 1284 bi->bi_nodisk = sc->sc_lds[0]->ndrives; 1285 break; 1286 1287 case BIOCVOL: 1288 error = ciss_ioctl_vol(sc, (struct bioc_vol *)addr); 1289 break; 1290 1291 case BIOCDISK_NOVOL: 1292 /* 1293 * XXX since we don't know how to associate physical drives with logical drives 1294 * yet, BIOCDISK_NOVOL is equivalent to BIOCDISK to the volume that we've 1295 * associated all physical drives to. 1296 * Maybe assoicate all physical drives to all logical volumes, but only return 1297 * physical drives on one logical volume. Which one? Either 1st volume that 1298 * is degraded, rebuilding, or failed? 1299 */ 1300 bd = (struct bioc_disk *)addr; 1301 bd->bd_volid = 0; 1302 bd->bd_disknovol = true; 1303 /* FALLTHROUGH */ 1304 case BIOCDISK: 1305 bd = (struct bioc_disk *)addr; 1306 if (bd->bd_volid < 0 || bd->bd_volid > sc->maxunits) { 1307 error = EINVAL; 1308 break; 1309 } 1310 ldp = sc->sc_lds[0]; 1311 if (!ldp || (pd = bd->bd_diskid) < 0 || pd > ldp->ndrives) { 1312 error = EINVAL; 1313 break; 1314 } 1315 ldstat = sc->scratch; 1316 if ((error = ciss_ldstat(sc, bd->bd_volid, ldstat))) { 1317 break; 1318 } 1319 bd->bd_status = -1; 1320 if (ldstat->stat == CISS_LD_REBLD && 1321 ldstat->bigrebuild == ldp->tgts[pd]) 1322 bd->bd_status = BIOC_SDREBUILD; 1323 if (ciss_bitset(ldp->tgts[pd] & (~CISS_BIGBIT), 1324 ldstat->bigfailed)) { 1325 bd->bd_status = BIOC_SDFAILED; 1326 bd->bd_size = 0; 1327 bd->bd_channel = (ldp->tgts[pd] & (~CISS_BIGBIT)) / 1328 sc->ndrives; 1329 bd->bd_target = ldp->tgts[pd] % sc->ndrives; 1330 bd->bd_lun = 0; 1331 bd->bd_vendor[0] = '\0'; 1332 bd->bd_serial[0] = '\0'; 1333 bd->bd_procdev[0] = '\0'; 1334 } else { 1335 pdid = sc->scratch; 1336 if ((error = ciss_pdid(sc, ldp->tgts[pd], pdid, 1337 XS_CTL_POLL))) { 1338 bd->bd_status = BIOC_SDFAILED; 1339 bd->bd_size = 0; 1340 bd->bd_channel = (ldp->tgts[pd] & (~CISS_BIGBIT)) / 1341 sc->ndrives; 1342 bd->bd_target = ldp->tgts[pd] % sc->ndrives; 1343 bd->bd_lun = 0; 1344 bd->bd_vendor[0] = '\0'; 1345 bd->bd_serial[0] = '\0'; 1346 bd->bd_procdev[0] = '\0'; 1347 error = 0; 1348 break; 1349 } 1350 if (bd->bd_status < 0) { 1351 if (pdid->config & CISS_PD_SPARE) 1352 bd->bd_status = BIOC_SDHOTSPARE; 1353 else if (pdid->present & CISS_PD_PRESENT) 1354 bd->bd_status = BIOC_SDONLINE; 1355 else 1356 bd->bd_status = BIOC_SDINVALID; 1357 } 1358 bd->bd_size = (u_int64_t)le32toh(pdid->nblocks) * 1359 le16toh(pdid->blksz); 1360 bd->bd_channel = pdid->bus; 1361 bd->bd_target = pdid->target; 1362 bd->bd_lun = 0; 1363 strlcpy(bd->bd_vendor, pdid->model, 1364 sizeof(bd->bd_vendor)); 1365 strlcpy(bd->bd_serial, pdid->serial, 1366 sizeof(bd->bd_serial)); 1367 bd->bd_procdev[0] = '\0'; 1368 } 1369 break; 1370 1371 case BIOCBLINK: 1372 bb = (struct bioc_blink *)addr; 1373 blink = sc->scratch; 1374 error = EINVAL; 1375 /* XXX workaround completely dumb scsi addressing */ 1376 for (ld = 0; ld < sc->maxunits; ld++) { 1377 ldp = sc->sc_lds[ld]; 1378 if (!ldp) 1379 continue; 1380 if (sc->ndrives == 256) 1381 drv = bb->bb_target; 1382 else 1383 drv = CISS_BIGBIT + 1384 bb->bb_channel * sc->ndrives + 1385 bb->bb_target; 1386 for (pd = 0; pd < ldp->ndrives; pd++) 1387 if (ldp->tgts[pd] == drv) 1388 error = ciss_blink(sc, ld, pd, 1389 bb->bb_status, blink); 1390 } 1391 break; 1392 1393 case BIOCALARM: 1394 case BIOCSETSTATE: 1395 default: 1396 error = EINVAL; 1397 } 1398 1399 return (error); 1400 } 1401 1402 int 1403 ciss_ioctl_vol(struct ciss_softc *sc, struct bioc_vol *bv) 1404 { 1405 struct ciss_ldid *ldid; 1406 struct ciss_ld *ldp; 1407 struct ciss_ldstat *ldstat; 1408 struct ciss_pdid *pdid; 1409 int error = 0; 1410 u_int blks; 1411 1412 if (bv->bv_volid < 0 || bv->bv_volid > sc->maxunits) { 1413 return EINVAL; 1414 } 1415 ldp = sc->sc_lds[bv->bv_volid]; 1416 ldid = sc->scratch; 1417 if ((error = ciss_ldid(sc, bv->bv_volid, ldid))) { 1418 return error; 1419 } 1420 bv->bv_status = BIOC_SVINVALID; 1421 blks = (u_int)le16toh(ldid->nblocks[1]) << 16 | 1422 le16toh(ldid->nblocks[0]); 1423 bv->bv_size = blks * (u_quad_t)le16toh(ldid->blksize); 1424 bv->bv_level = ciss_level[ldid->type]; 1425 /* 1426 * XXX Should only return bv_nodisk for logigal volume that we've associated 1427 * the physical drives to: either the 1st degraded, rebuilding, or failed 1428 * volume else volume 0? 1429 */ 1430 if (ldp) { 1431 bv->bv_nodisk = ldp->ndrives; 1432 strlcpy(bv->bv_dev, ldp->xname, sizeof(bv->bv_dev)); 1433 } 1434 strlcpy(bv->bv_vendor, "CISS", sizeof(bv->bv_vendor)); 1435 ldstat = sc->scratch; 1436 memset(ldstat, 0, sizeof(*ldstat)); 1437 if ((error = ciss_ldstat(sc, bv->bv_volid, ldstat))) { 1438 return error; 1439 } 1440 bv->bv_percent = -1; 1441 bv->bv_seconds = 0; 1442 if (ldstat->stat < sizeof(ciss_stat)/sizeof(ciss_stat[0])) 1443 bv->bv_status = ciss_stat[ldstat->stat]; 1444 if (bv->bv_status == BIOC_SVREBUILD || 1445 bv->bv_status == BIOC_SVBUILDING) { 1446 u_int64_t prog; 1447 1448 ldp = sc->sc_lds[0]; 1449 if (ldp) { 1450 bv->bv_nodisk = ldp->ndrives; 1451 strlcpy(bv->bv_dev, ldp->xname, sizeof(bv->bv_dev)); 1452 } 1453 /* 1454 * XXX ldstat->prog is blocks remaining on physical drive being rebuilt 1455 * blks is only correct for a RAID1 set; RAID5 needs to determine the 1456 * size of the physical device - which we don't yet know. 1457 * ldstat->bigrebuild has physical device target, so could be used with 1458 * pdid to get size. Another way is to save pd information in sc so it's 1459 * easy to reference. 1460 */ 1461 prog = (u_int64_t)((ldstat->prog[3] << 24) | 1462 (ldstat->prog[2] << 16) | (ldstat->prog[1] << 8) | 1463 ldstat->prog[0]); 1464 pdid = sc->scratch; 1465 if (!ciss_pdid(sc, ldstat->bigrebuild, pdid, XS_CTL_POLL)) { 1466 blks = le32toh(pdid->nblocks); 1467 bv->bv_percent = (blks - prog) * 1000ULL / blks; 1468 } 1469 } 1470 return 0; 1471 } 1472 1473 int 1474 ciss_blink(struct ciss_softc *sc, int ld, int pd, int stat, 1475 struct ciss_blink *blink) 1476 { 1477 struct ciss_ccb *ccb; 1478 struct ciss_cmd *cmd; 1479 struct ciss_ld *ldp; 1480 1481 if (ld > sc->maxunits) 1482 return EINVAL; 1483 1484 ldp = sc->sc_lds[ld]; 1485 if (!ldp || pd > ldp->ndrives) 1486 return EINVAL; 1487 1488 ldp->bling.pdtab[ldp->tgts[pd]] = stat == BIOC_SBUNBLINK? 0 : 1489 CISS_BLINK_ALL; 1490 memcpy(blink, &ldp->bling, sizeof(*blink)); 1491 1492 ccb = ciss_get_ccb(sc); 1493 if (ccb == NULL) 1494 return ENOMEM; 1495 ccb->ccb_len = sizeof(*blink); 1496 ccb->ccb_data = blink; 1497 ccb->ccb_xs = NULL; 1498 cmd = &ccb->ccb_cmd; 1499 cmd->tgt = htole32(CISS_CMD_MODE_PERIPH); 1500 cmd->tgt2 = 0; 1501 cmd->cdblen = 10; 1502 cmd->flags = CISS_CDB_CMD | CISS_CDB_SIMPL | CISS_CDB_OUT; 1503 cmd->tmo = htole16(0); 1504 memset(&cmd->cdb[0], 0, sizeof(cmd->cdb)); 1505 cmd->cdb[0] = CISS_CMD_CTRL_SET; 1506 cmd->cdb[6] = CISS_CMS_CTRL_PDBLINK; 1507 cmd->cdb[7] = sizeof(*blink) >> 8; /* biiiig endian */ 1508 cmd->cdb[8] = sizeof(*blink) & 0xff; 1509 1510 return ciss_cmd(ccb, BUS_DMA_NOWAIT, XS_CTL_POLL); 1511 } 1512 1513 int 1514 ciss_create_sensors(struct ciss_softc *sc) 1515 { 1516 int i; 1517 int nsensors = sc->maxunits; 1518 1519 if (nsensors == 0) { 1520 return 0; 1521 } 1522 1523 sc->sc_sme = sysmon_envsys_create(); 1524 sc->sc_sensor = malloc(sizeof(envsys_data_t) * nsensors, 1525 M_DEVBUF, M_NOWAIT | M_ZERO); 1526 if (sc->sc_sensor == NULL) { 1527 aprint_error_dev(sc->sc_dev, "can't allocate envsys_data"); 1528 return(ENOMEM); 1529 } 1530 1531 for (i = 0; i < nsensors; i++) { 1532 sc->sc_sensor[i].units = ENVSYS_DRIVE; 1533 sc->sc_sensor[i].state = ENVSYS_SINVALID; 1534 sc->sc_sensor[i].value_cur = ENVSYS_DRIVE_EMPTY; 1535 /* Enable monitoring for drive state changes */ 1536 sc->sc_sensor[i].flags |= ENVSYS_FMONSTCHANGED; 1537 /* logical drives */ 1538 snprintf(sc->sc_sensor[i].desc, 1539 sizeof(sc->sc_sensor[i].desc), "%s:%d", 1540 device_xname(sc->sc_dev), i); 1541 if (sysmon_envsys_sensor_attach(sc->sc_sme, 1542 &sc->sc_sensor[i])) 1543 goto out; 1544 } 1545 1546 sc->sc_sme->sme_name = device_xname(sc->sc_dev); 1547 sc->sc_sme->sme_cookie = sc; 1548 sc->sc_sme->sme_refresh = ciss_sensor_refresh; 1549 if (sysmon_envsys_register(sc->sc_sme)) { 1550 printf("%s: unable to register with sysmon\n", 1551 device_xname(sc->sc_dev)); 1552 return(1); 1553 } 1554 return (0); 1555 1556 out: 1557 free(sc->sc_sensor, M_DEVBUF); 1558 sysmon_envsys_destroy(sc->sc_sme); 1559 return EINVAL; 1560 } 1561 1562 void 1563 ciss_sensor_refresh(struct sysmon_envsys *sme, envsys_data_t *edata) 1564 { 1565 struct ciss_softc *sc = sme->sme_cookie; 1566 struct bioc_vol bv; 1567 1568 if (edata->sensor >= sc->maxunits) 1569 return; 1570 1571 memset(&bv, 0, sizeof(bv)); 1572 bv.bv_volid = edata->sensor; 1573 if (ciss_ioctl_vol(sc, &bv)) 1574 bv.bv_status = BIOC_SVINVALID; 1575 1576 bio_vol_to_envsys(edata, &bv); 1577 } 1578 #endif /* NBIO > 0 */ 1579