1 /* $OpenBSD: sili.c,v 1.39 2007/11/28 13:47:09 dlg Exp $ */ 2 3 /* 4 * Copyright (c) 2007 David Gwynne <dlg@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/param.h> 20 #include <sys/systm.h> 21 #include <sys/buf.h> 22 #include <sys/device.h> 23 #include <sys/proc.h> 24 #include <sys/malloc.h> 25 #include <sys/kernel.h> 26 #include <sys/mutex.h> 27 28 #include <machine/bus.h> 29 30 #include <dev/ata/atascsi.h> 31 32 #include <dev/ic/silireg.h> 33 #include <dev/ic/silivar.h> 34 35 /* use SILI_DEBUG for dmesg spam */ 36 #define NO_SILI_DEBUG 37 38 #ifdef SILI_DEBUG 39 #define SILI_D_VERBOSE (1<<0) 40 #define SILI_D_INTR (1<<1) 41 42 int silidebug = SILI_D_VERBOSE; 43 44 #define DPRINTF(m, a...) do { if ((m) & silidebug) printf(a); } while (0) 45 #else 46 #define DPRINTF(m, a...) 47 #endif 48 49 struct cfdriver sili_cd = { 50 NULL, "sili", DV_DULL 51 }; 52 53 /* wrapper around dma memory */ 54 struct sili_dmamem { 55 bus_dmamap_t sdm_map; 56 bus_dma_segment_t sdm_seg; 57 size_t sdm_size; 58 caddr_t sdm_kva; 59 }; 60 #define SILI_DMA_MAP(_sdm) ((_sdm)->sdm_map) 61 #define SILI_DMA_DVA(_sdm) ((_sdm)->sdm_map->dm_segs[0].ds_addr) 62 #define SILI_DMA_KVA(_sdm) ((void *)(_sdm)->sdm_kva) 63 64 struct sili_dmamem *sili_dmamem_alloc(struct sili_softc *, bus_size_t, 65 bus_size_t); 66 void sili_dmamem_free(struct sili_softc *, 67 struct sili_dmamem *); 68 69 /* per port goo */ 70 struct sili_ccb; 71 72 /* size of scratch space for use in error recovery. */ 73 #define SILI_SCRATCH_LEN 512 /* must be at least 1 sector */ 74 75 struct sili_port { 76 struct sili_softc *sp_sc; 77 bus_space_handle_t sp_ioh; 78 79 struct sili_ccb *sp_ccbs; 80 struct sili_dmamem *sp_cmds; 81 struct sili_dmamem *sp_scratch; 82 83 TAILQ_HEAD(, sili_ccb) sp_free_ccbs; 84 struct mutex sp_free_ccb_mtx; 85 86 volatile u_int32_t sp_active; 87 TAILQ_HEAD(, sili_ccb) sp_active_ccbs; 88 TAILQ_HEAD(, sili_ccb) sp_deferred_ccbs; 89 90 #ifdef SILI_DEBUG 91 char sp_name[16]; 92 #define PORTNAME(_sp) ((_sp)->sp_name) 93 #else 94 #define PORTNAME(_sp) DEVNAME((_sp)->sp_sc) 95 #endif 96 }; 97 98 int sili_ports_alloc(struct sili_softc *); 99 void sili_ports_free(struct sili_softc *); 100 101 /* ccb shizz */ 102 103 /* 104 * the dma memory for each command will be made up of a prb followed by 105 * 7 sgts, this is a neat 512 bytes. 106 */ 107 #define SILI_CMD_LEN 512 108 109 /* 110 * you can fit 22 sge's into 7 sgts and a prb: 111 * there's 1 sgl in an atapi prb (two in the ata one, but we cant over 112 * advertise), but that's needed for the chain element. you get three sges 113 * per sgt cos you lose the 4th sge for the chaining, but you keep it in 114 * the last sgt. so 3 x 6 + 4 is 22. 115 */ 116 #define SILI_DMA_SEGS 22 117 118 struct sili_ccb { 119 struct ata_xfer ccb_xa; 120 121 void *ccb_cmd; 122 u_int64_t ccb_cmd_dva; 123 bus_dmamap_t ccb_dmamap; 124 125 struct sili_port *ccb_port; 126 127 TAILQ_ENTRY(sili_ccb) ccb_entry; 128 }; 129 130 int sili_ccb_alloc(struct sili_port *); 131 void sili_ccb_free(struct sili_port *); 132 struct sili_ccb *sili_get_ccb(struct sili_port *); 133 void sili_put_ccb(struct sili_ccb *); 134 135 /* bus space ops */ 136 u_int32_t sili_read(struct sili_softc *, bus_size_t); 137 void sili_write(struct sili_softc *, bus_size_t, u_int32_t); 138 u_int32_t sili_pread(struct sili_port *, bus_size_t); 139 void sili_pwrite(struct sili_port *, bus_size_t, u_int32_t); 140 int sili_pwait_eq(struct sili_port *, bus_size_t, 141 u_int32_t, u_int32_t, int); 142 int sili_pwait_ne(struct sili_port *, bus_size_t, 143 u_int32_t, u_int32_t, int); 144 145 /* command handling */ 146 void sili_post_direct(struct sili_port *, u_int, 147 void *, size_t buflen); 148 void sili_post_indirect(struct sili_port *, 149 struct sili_ccb *); 150 void sili_pread_fis(struct sili_port *, u_int, 151 struct ata_fis_d2h *); 152 u_int32_t sili_signature(struct sili_port *, u_int); 153 int sili_load(struct sili_ccb *, struct sili_sge *, int); 154 void sili_unload(struct sili_ccb *); 155 int sili_poll(struct sili_ccb *, int, void (*)(void *)); 156 void sili_start(struct sili_port *, struct sili_ccb *); 157 int sili_read_ncq_error(struct sili_port *, int *); 158 159 /* port interrupt handler */ 160 u_int32_t sili_port_intr(struct sili_port *, int); 161 162 /* atascsi interface */ 163 int sili_ata_probe(void *, int); 164 void sili_ata_free(void *, int); 165 struct ata_xfer *sili_ata_get_xfer(void *, int); 166 void sili_ata_put_xfer(struct ata_xfer *); 167 int sili_ata_cmd(struct ata_xfer *); 168 169 struct atascsi_methods sili_atascsi_methods = { 170 sili_ata_probe, 171 sili_ata_free, 172 sili_ata_get_xfer, 173 sili_ata_cmd 174 }; 175 176 /* completion paths */ 177 void sili_ata_cmd_done(struct sili_ccb *, int); 178 void sili_ata_cmd_timeout(void *); 179 180 int 181 sili_attach(struct sili_softc *sc) 182 { 183 struct atascsi_attach_args aaa; 184 185 printf("\n"); 186 187 if (sili_ports_alloc(sc) != 0) { 188 /* error already printed by sili_port_alloc */ 189 return (1); 190 } 191 192 /* bounce the controller */ 193 sili_write(sc, SILI_REG_GC, SILI_REG_GC_GR); 194 sili_write(sc, SILI_REG_GC, 0x0); 195 196 bzero(&aaa, sizeof(aaa)); 197 aaa.aaa_cookie = sc; 198 aaa.aaa_methods = &sili_atascsi_methods; 199 aaa.aaa_minphys = minphys; 200 aaa.aaa_nports = sc->sc_nports; 201 aaa.aaa_ncmds = SILI_MAX_CMDS; 202 aaa.aaa_capability = ASAA_CAP_NCQ; 203 204 sc->sc_atascsi = atascsi_attach(&sc->sc_dev, &aaa); 205 206 return (0); 207 } 208 209 int 210 sili_detach(struct sili_softc *sc, int flags) 211 { 212 int rv; 213 214 if (sc->sc_atascsi != NULL) { 215 rv = atascsi_detach(sc->sc_atascsi, flags); 216 if (rv != 0) 217 return (rv); 218 } 219 220 if (sc->sc_ports != NULL) 221 sili_ports_free(sc); 222 223 return (0); 224 } 225 226 u_int32_t 227 sili_port_intr(struct sili_port *sp, int timeout_slot) 228 { 229 u_int32_t is, pss_saved, pss_masked; 230 u_int32_t processed = 0, need_restart = 0; 231 int slot; 232 struct sili_ccb *ccb; 233 234 is = sili_pread(sp, SILI_PREG_IS); 235 pss_saved = sili_pread(sp, SILI_PREG_PSS); /* reading acks CMDCOMP */ 236 237 #ifdef SILI_DEBUG 238 if ((pss_saved & SILI_PREG_PSS_ALL_SLOTS) != sp->sp_active || 239 ((is >> 16) & ~SILI_PREG_IS_CMDCOMP)) { 240 DPRINTF(SILI_D_INTR, "%s: IS: 0x%08x (0x%b), PSS: %08x, " 241 "active: %08x\n", PORTNAME(sp), is, is >> 16, SILI_PFMT_IS, 242 pss_saved, sp->sp_active); 243 } 244 #endif 245 246 /* Only interested in slot status bits. */ 247 pss_saved &= SILI_PREG_PSS_ALL_SLOTS; 248 249 if (is & SILI_PREG_IS_CMDERR) { 250 int err_slot, err_code; 251 u_int32_t sactive = 0; 252 253 sili_pwrite(sp, SILI_PREG_IS, SILI_PREG_IS_CMDERR); 254 err_slot = SILI_PREG_PCS_ACTIVE(sili_pread(sp, SILI_PREG_PCS)); 255 err_code = sili_pread(sp, SILI_PREG_CE); 256 ccb = &sp->sp_ccbs[err_slot]; 257 258 switch (err_code) { 259 case SILI_PREG_CE_DEVICEERROR: 260 case SILI_PREG_CE_DATAFISERROR: 261 /* Extract error from command slot in LRAM. */ 262 sili_pread_fis(sp, err_slot, &ccb->ccb_xa.rfis); 263 break; 264 265 case SILI_PREG_CE_SDBERROR: 266 /* No NCQ commands active? Treat as a normal error. */ 267 sactive = sili_pread(sp, SILI_PREG_SACT);/* XXX Pmult */ 268 if (sactive == 0) 269 break; 270 271 /* Extract real NCQ error slot & RFIS from log page. */ 272 if (!sili_read_ncq_error(sp, &err_slot)) { 273 /* got real err_slot */ 274 ccb = &sp->sp_ccbs[err_slot]; 275 break; 276 } 277 278 /* failed to get error or not NCQ */ 279 280 /* FALLTHROUGH */ 281 default: 282 /* All other error types are fatal. */ 283 printf("%s: fatal error (%d), aborting active slots " 284 "(%08x) and resetting device.\n", PORTNAME(sp), 285 err_code, pss_saved); 286 while (pss_saved) { 287 slot = ffs(pss_saved) - 1; 288 pss_saved &= ~(1 << slot); 289 290 ccb = &sp->sp_ccbs[slot]; 291 KASSERT(ccb->ccb_xa.state == ATA_S_ONCHIP); 292 ccb->ccb_xa.state = ATA_S_ERROR; 293 } 294 need_restart = SILI_PREG_PCS_DEVRESET; 295 goto fatal; 296 } 297 298 DPRINTF(SILI_D_VERBOSE, "%s: %serror, code %d, slot %d, " 299 "active %08x\n", PORTNAME(sp), sactive ? "NCQ " : "", 300 err_code, err_slot, sp->sp_active); 301 302 /* Clear the failed commmand in saved PSS so cmd_done runs. */ 303 pss_saved &= ~(1 << err_slot); 304 305 KASSERT(ccb->ccb_xa.state == ATA_S_ONCHIP); 306 ccb->ccb_xa.state = ATA_S_ERROR; 307 308 need_restart = SILI_PREG_PCS_PORTINIT; 309 } 310 fatal: 311 312 /* Process command timeout request only if command is still active. */ 313 if (timeout_slot >= 0 && (pss_saved & (1 << timeout_slot))) { 314 DPRINTF(SILI_D_VERBOSE, "%s: timing out slot %d, active %08x\n", 315 PORTNAME(sp), timeout_slot, sp->sp_active); 316 317 /* Clear the failed commmand in saved PSS so cmd_done runs. */ 318 pss_saved &= ~(1 << timeout_slot); 319 320 ccb = &sp->sp_ccbs[timeout_slot]; 321 KASSERT(ccb->ccb_xa.state == ATA_S_ONCHIP); 322 ccb->ccb_xa.state = ATA_S_TIMEOUT; 323 324 /* Reset device to abort all commands (including this one). */ 325 need_restart = SILI_PREG_PCS_DEVRESET; 326 } 327 328 /* Command slot is complete if its bit in PSS is 0 but 1 in active. */ 329 pss_masked = ~pss_saved & sp->sp_active; 330 while (pss_masked) { 331 slot = ffs(pss_masked) - 1; 332 ccb = &sp->sp_ccbs[slot]; 333 pss_masked &= ~(1 << slot); 334 335 DPRINTF(SILI_D_INTR, "%s: slot %d is complete%s\n", 336 PORTNAME(sp), slot, ccb->ccb_xa.state == ATA_S_ERROR ? 337 " (error)" : (ccb->ccb_xa.state == ATA_S_TIMEOUT ? 338 " (timeout)" : "")); 339 340 sili_ata_cmd_done(ccb, need_restart); 341 342 processed |= 1 << slot; 343 } 344 345 if (need_restart) { 346 /* Re-enable transfers on port. */ 347 sili_pwrite(sp, SILI_PREG_PCS, need_restart); 348 if (!sili_pwait_eq(sp, SILI_PREG_PCS, SILI_PREG_PCS_PORTRDY, 349 SILI_PREG_PCS_PORTRDY, 1000)) { 350 printf("%s: couldn't restart port after error\n", 351 PORTNAME(sp)); 352 } 353 354 /* Restart CCBs in the order they were originally queued. */ 355 pss_masked = pss_saved; 356 TAILQ_FOREACH(ccb, &sp->sp_active_ccbs, ccb_entry) { 357 DPRINTF(SILI_D_VERBOSE, "%s: restarting slot %d " 358 "after error, state %02x\n", PORTNAME(sp), 359 ccb->ccb_xa.tag, ccb->ccb_xa.state); 360 if (!(pss_masked & (1 << ccb->ccb_xa.tag))) { 361 panic("sili_intr: slot %d not active in " 362 "pss_masked: %08x, state %02x", 363 ccb->ccb_xa.tag, pss_masked, 364 ccb->ccb_xa.state); 365 } 366 pss_masked &= ~(1 << ccb->ccb_xa.tag); 367 368 KASSERT(ccb->ccb_xa.state == ATA_S_ONCHIP); 369 sili_post_indirect(sp, ccb); 370 } 371 KASSERT(pss_masked == 0); 372 373 /* 374 * Finally, run atascsi completion for any finished CCBs. If 375 * we had run these during cmd_done above, any ccbs that their 376 * completion generated would have been activated out of order. 377 */ 378 while ((ccb = TAILQ_FIRST(&sp->sp_deferred_ccbs)) != NULL) { 379 TAILQ_REMOVE(&sp->sp_deferred_ccbs, ccb, ccb_entry); 380 381 KASSERT(ccb->ccb_xa.state == ATA_S_COMPLETE || 382 ccb->ccb_xa.state == ATA_S_ERROR || 383 ccb->ccb_xa.state == ATA_S_TIMEOUT); 384 ccb->ccb_xa.complete(&ccb->ccb_xa); 385 } 386 } 387 388 return (processed); 389 } 390 391 int 392 sili_intr(void *arg) 393 { 394 struct sili_softc *sc = arg; 395 u_int32_t is; 396 int port; 397 398 /* If the card has gone away, this will return 0xffffffff. */ 399 is = sili_read(sc, SILI_REG_GIS); 400 if (is == 0 || is == 0xffffffff) 401 return (0); 402 sili_write(sc, SILI_REG_GIS, is); 403 DPRINTF(SILI_D_INTR, "sili_intr, GIS: %08x\n", is); 404 405 while (is & SILI_REG_GIS_PIS_MASK) { 406 port = ffs(is) - 1; 407 sili_port_intr(&sc->sc_ports[port], -1); 408 is &= ~(1 << port); 409 } 410 411 return (1); 412 } 413 414 int 415 sili_ports_alloc(struct sili_softc *sc) 416 { 417 struct sili_port *sp; 418 int i; 419 420 sc->sc_ports = malloc(sizeof(struct sili_port) * sc->sc_nports, 421 M_DEVBUF, M_WAITOK | M_ZERO); 422 423 for (i = 0; i < sc->sc_nports; i++) { 424 sp = &sc->sc_ports[i]; 425 426 sp->sp_sc = sc; 427 #ifdef SILI_DEBUG 428 snprintf(sp->sp_name, sizeof(sp->sp_name), "%s.%d", 429 DEVNAME(sc), i); 430 #endif 431 if (bus_space_subregion(sc->sc_iot_port, sc->sc_ioh_port, 432 SILI_PORT_OFFSET(i), SILI_PORT_SIZE, &sp->sp_ioh) != 0) { 433 printf("%s: unable to create register window " 434 "for port %d\n", DEVNAME(sc), i); 435 goto freeports; 436 } 437 } 438 439 return (0); 440 441 freeports: 442 /* bus_space(9) says subregions dont have to be freed */ 443 free(sp, M_DEVBUF); 444 sc->sc_ports = NULL; 445 return (1); 446 } 447 448 void 449 sili_ports_free(struct sili_softc *sc) 450 { 451 struct sili_port *sp; 452 int i; 453 454 for (i = 0; i < sc->sc_nports; i++) { 455 sp = &sc->sc_ports[i]; 456 457 if (sp->sp_ccbs != NULL) 458 sili_ccb_free(sp); 459 } 460 461 /* bus_space(9) says subregions dont have to be freed */ 462 free(sc->sc_ports, M_DEVBUF); 463 sc->sc_ports = NULL; 464 } 465 466 int 467 sili_ccb_alloc(struct sili_port *sp) 468 { 469 struct sili_softc *sc = sp->sp_sc; 470 struct sili_ccb *ccb; 471 struct sili_prb *prb; 472 int i; 473 474 TAILQ_INIT(&sp->sp_free_ccbs); 475 mtx_init(&sp->sp_free_ccb_mtx, IPL_BIO); 476 TAILQ_INIT(&sp->sp_active_ccbs); 477 TAILQ_INIT(&sp->sp_deferred_ccbs); 478 479 sp->sp_ccbs = malloc(sizeof(struct sili_ccb) * SILI_MAX_CMDS, 480 M_DEVBUF, M_WAITOK); 481 sp->sp_cmds = sili_dmamem_alloc(sc, SILI_CMD_LEN * SILI_MAX_CMDS, 482 SILI_PRB_ALIGN); 483 if (sp->sp_cmds == NULL) 484 goto free_ccbs; 485 sp->sp_scratch = sili_dmamem_alloc(sc, SILI_SCRATCH_LEN, PAGE_SIZE); 486 if (sp->sp_scratch == NULL) 487 goto free_cmds; 488 489 bzero(sp->sp_ccbs, sizeof(struct sili_ccb) * SILI_MAX_CMDS); 490 491 for (i = 0; i < SILI_MAX_CMDS; i++) { 492 ccb = &sp->sp_ccbs[i]; 493 ccb->ccb_port = sp; 494 ccb->ccb_cmd = SILI_DMA_KVA(sp->sp_cmds) + i * SILI_CMD_LEN; 495 ccb->ccb_cmd_dva = SILI_DMA_DVA(sp->sp_cmds) + i * SILI_CMD_LEN; 496 if (bus_dmamap_create(sc->sc_dmat, MAXPHYS, SILI_DMA_SEGS, 497 MAXPHYS, 0, BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, 498 &ccb->ccb_dmamap) != 0) 499 goto free_scratch; 500 501 prb = ccb->ccb_cmd; 502 ccb->ccb_xa.fis = (struct ata_fis_h2d *)&prb->fis; 503 ccb->ccb_xa.packetcmd = ((struct sili_prb_packet *)prb)->cdb; 504 ccb->ccb_xa.tag = i; 505 ccb->ccb_xa.ata_put_xfer = sili_ata_put_xfer; 506 ccb->ccb_xa.state = ATA_S_COMPLETE; 507 508 sili_put_ccb(ccb); 509 } 510 511 return (0); 512 513 free_scratch: 514 sili_dmamem_free(sc, sp->sp_scratch); 515 free_cmds: 516 sili_dmamem_free(sc, sp->sp_cmds); 517 free_ccbs: 518 sili_ccb_free(sp); 519 return (1); 520 } 521 522 void 523 sili_ccb_free(struct sili_port *sp) 524 { 525 struct sili_softc *sc = sp->sp_sc; 526 struct sili_ccb *ccb; 527 528 while ((ccb = sili_get_ccb(sp)) != NULL) 529 bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap); 530 531 free(sp->sp_ccbs, M_DEVBUF); 532 sp->sp_ccbs = NULL; 533 } 534 535 struct sili_ccb * 536 sili_get_ccb(struct sili_port *sp) 537 { 538 struct sili_ccb *ccb; 539 540 mtx_enter(&sp->sp_free_ccb_mtx); 541 ccb = TAILQ_FIRST(&sp->sp_free_ccbs); 542 if (ccb != NULL) { 543 KASSERT(ccb->ccb_xa.state == ATA_S_PUT); 544 TAILQ_REMOVE(&sp->sp_free_ccbs, ccb, ccb_entry); 545 ccb->ccb_xa.state = ATA_S_SETUP; 546 } 547 mtx_leave(&sp->sp_free_ccb_mtx); 548 549 return (ccb); 550 } 551 552 void 553 sili_put_ccb(struct sili_ccb *ccb) 554 { 555 struct sili_port *sp = ccb->ccb_port; 556 557 #ifdef DIAGNOSTIC 558 if (ccb->ccb_xa.state != ATA_S_COMPLETE && 559 ccb->ccb_xa.state != ATA_S_TIMEOUT && 560 ccb->ccb_xa.state != ATA_S_ERROR) { 561 printf("%s: invalid ata_xfer state %02x in sili_put_ccb, " 562 "slot %d\n", PORTNAME(sp), ccb->ccb_xa.state, 563 ccb->ccb_xa.tag); 564 } 565 #endif 566 567 ccb->ccb_xa.state = ATA_S_PUT; 568 mtx_enter(&sp->sp_free_ccb_mtx); 569 TAILQ_INSERT_TAIL(&sp->sp_free_ccbs, ccb, ccb_entry); 570 mtx_leave(&sp->sp_free_ccb_mtx); 571 } 572 573 struct sili_dmamem * 574 sili_dmamem_alloc(struct sili_softc *sc, bus_size_t size, bus_size_t align) 575 { 576 struct sili_dmamem *sdm; 577 int nsegs; 578 579 sdm = malloc(sizeof(*sdm), M_DEVBUF, M_WAITOK | M_ZERO); 580 sdm->sdm_size = size; 581 582 if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, 583 BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, &sdm->sdm_map) != 0) 584 goto sdmfree; 585 586 if (bus_dmamem_alloc(sc->sc_dmat, size, align, 0, &sdm->sdm_seg, 587 1, &nsegs, BUS_DMA_NOWAIT) != 0) 588 goto destroy; 589 590 if (bus_dmamem_map(sc->sc_dmat, &sdm->sdm_seg, nsegs, size, 591 &sdm->sdm_kva, BUS_DMA_NOWAIT) != 0) 592 goto free; 593 594 if (bus_dmamap_load(sc->sc_dmat, sdm->sdm_map, sdm->sdm_kva, size, 595 NULL, BUS_DMA_NOWAIT) != 0) 596 goto unmap; 597 598 bzero(sdm->sdm_kva, size); 599 600 return (sdm); 601 602 unmap: 603 bus_dmamem_unmap(sc->sc_dmat, sdm->sdm_kva, size); 604 free: 605 bus_dmamem_free(sc->sc_dmat, &sdm->sdm_seg, 1); 606 destroy: 607 bus_dmamap_destroy(sc->sc_dmat, sdm->sdm_map); 608 sdmfree: 609 free(sdm, M_DEVBUF); 610 611 return (NULL); 612 } 613 614 void 615 sili_dmamem_free(struct sili_softc *sc, struct sili_dmamem *sdm) 616 { 617 bus_dmamap_unload(sc->sc_dmat, sdm->sdm_map); 618 bus_dmamem_unmap(sc->sc_dmat, sdm->sdm_kva, sdm->sdm_size); 619 bus_dmamem_free(sc->sc_dmat, &sdm->sdm_seg, 1); 620 bus_dmamap_destroy(sc->sc_dmat, sdm->sdm_map); 621 free(sdm, M_DEVBUF); 622 } 623 624 u_int32_t 625 sili_read(struct sili_softc *sc, bus_size_t r) 626 { 627 u_int32_t rv; 628 629 bus_space_barrier(sc->sc_iot_global, sc->sc_ioh_global, r, 4, 630 BUS_SPACE_BARRIER_READ); 631 rv = bus_space_read_4(sc->sc_iot_global, sc->sc_ioh_global, r); 632 633 return (rv); 634 } 635 636 void 637 sili_write(struct sili_softc *sc, bus_size_t r, u_int32_t v) 638 { 639 bus_space_write_4(sc->sc_iot_global, sc->sc_ioh_global, r, v); 640 bus_space_barrier(sc->sc_iot_global, sc->sc_ioh_global, r, 4, 641 BUS_SPACE_BARRIER_WRITE); 642 } 643 644 u_int32_t 645 sili_pread(struct sili_port *sp, bus_size_t r) 646 { 647 u_int32_t rv; 648 649 bus_space_barrier(sp->sp_sc->sc_iot_port, sp->sp_ioh, r, 4, 650 BUS_SPACE_BARRIER_READ); 651 rv = bus_space_read_4(sp->sp_sc->sc_iot_port, sp->sp_ioh, r); 652 653 return (rv); 654 } 655 656 void 657 sili_pwrite(struct sili_port *sp, bus_size_t r, u_int32_t v) 658 { 659 bus_space_write_4(sp->sp_sc->sc_iot_port, sp->sp_ioh, r, v); 660 bus_space_barrier(sp->sp_sc->sc_iot_port, sp->sp_ioh, r, 4, 661 BUS_SPACE_BARRIER_WRITE); 662 } 663 664 int 665 sili_pwait_eq(struct sili_port *sp, bus_size_t r, u_int32_t mask, 666 u_int32_t value, int timeout) 667 { 668 while ((sili_pread(sp, r) & mask) != value) { 669 if (timeout == 0) 670 return (0); 671 672 delay(1000); 673 timeout--; 674 } 675 676 return (1); 677 } 678 679 int 680 sili_pwait_ne(struct sili_port *sp, bus_size_t r, u_int32_t mask, 681 u_int32_t value, int timeout) 682 { 683 while ((sili_pread(sp, r) & mask) == value) { 684 if (timeout == 0) 685 return (0); 686 687 delay(1000); 688 timeout--; 689 } 690 691 return (1); 692 } 693 694 void 695 sili_post_direct(struct sili_port *sp, u_int slot, void *buf, size_t buflen) 696 { 697 bus_size_t r = SILI_PREG_SLOT(slot); 698 699 #ifdef DIAGNOSTIC 700 if (buflen != 64 && buflen != 128) 701 panic("sili_pcopy: buflen of %zu is not 64 or 128", buflen); 702 #endif 703 704 bus_space_write_raw_region_4(sp->sp_sc->sc_iot_port, sp->sp_ioh, r, 705 buf, buflen); 706 bus_space_barrier(sp->sp_sc->sc_iot_port, sp->sp_ioh, r, buflen, 707 BUS_SPACE_BARRIER_WRITE); 708 709 sili_pwrite(sp, SILI_PREG_FIFO, slot); 710 } 711 712 void 713 sili_pread_fis(struct sili_port *sp, u_int slot, struct ata_fis_d2h *fis) 714 { 715 bus_size_t r = SILI_PREG_SLOT(slot) + 8; 716 717 bus_space_barrier(sp->sp_sc->sc_iot_port, sp->sp_ioh, r, 718 sizeof(struct ata_fis_d2h), BUS_SPACE_BARRIER_READ); 719 bus_space_read_raw_region_4(sp->sp_sc->sc_iot_port, sp->sp_ioh, r, 720 fis, sizeof(struct ata_fis_d2h)); 721 } 722 723 void 724 sili_post_indirect(struct sili_port *sp, struct sili_ccb *ccb) 725 { 726 sili_pwrite(sp, SILI_PREG_CAR_LO(ccb->ccb_xa.tag), 727 (u_int32_t)ccb->ccb_cmd_dva); 728 sili_pwrite(sp, SILI_PREG_CAR_HI(ccb->ccb_xa.tag), 729 (u_int32_t)(ccb->ccb_cmd_dva >> 32)); 730 } 731 732 u_int32_t 733 sili_signature(struct sili_port *sp, u_int slot) 734 { 735 u_int32_t sig_hi, sig_lo; 736 737 sig_hi = sili_pread(sp, SILI_PREG_SIG_HI(slot)); 738 sig_hi <<= SILI_PREG_SIG_HI_SHIFT; 739 sig_lo = sili_pread(sp, SILI_PREG_SIG_LO(slot)); 740 sig_lo &= SILI_PREG_SIG_LO_MASK; 741 742 return (sig_hi | sig_lo); 743 } 744 745 int 746 sili_ata_probe(void *xsc, int port) 747 { 748 struct sili_softc *sc = xsc; 749 struct sili_port *sp = &sc->sc_ports[port]; 750 struct sili_prb_softreset sreset; 751 u_int32_t signature; 752 int port_type; 753 754 sili_pwrite(sp, SILI_PREG_PCC, SILI_PREG_PCC_PORTRESET); 755 sili_pwrite(sp, SILI_PREG_PCC, SILI_PREG_PCC_A32B); 756 757 if (!sili_pwait_eq(sp, SILI_PREG_SSTS, SATA_SStatus_DET, 758 SATA_SStatus_DET_DEV, 1000)) 759 return (ATA_PORT_T_NONE); 760 761 DPRINTF(SILI_D_VERBOSE, "%s: SSTS 0x%08x\n", PORTNAME(sp), 762 sili_pread(sp, SILI_PREG_SSTS)); 763 764 bzero(&sreset, sizeof(sreset)); 765 sreset.control = htole16(SILI_PRB_SOFT_RESET | SILI_PRB_INTERRUPT_MASK); 766 /* XXX sreset fis pmp field */ 767 768 /* we use slot 0 */ 769 sili_post_direct(sp, 0, &sreset, sizeof(sreset)); 770 if (!sili_pwait_eq(sp, SILI_PREG_PSS, (1 << 0), 0, 1000)) { 771 DPRINTF(SILI_D_VERBOSE, "%s: timed out while waiting for soft " 772 "reset\n", PORTNAME(sp)); 773 return (ATA_PORT_T_NONE); 774 } 775 776 /* Read device signature from command slot. */ 777 signature = sili_signature(sp, 0); 778 779 DPRINTF(SILI_D_VERBOSE, "%s: signature 0x%08x\n", PORTNAME(sp), 780 signature); 781 782 switch (signature) { 783 case SATA_SIGNATURE_DISK: 784 port_type = ATA_PORT_T_DISK; 785 break; 786 case SATA_SIGNATURE_ATAPI: 787 port_type = ATA_PORT_T_ATAPI; 788 break; 789 case SATA_SIGNATURE_PORT_MULTIPLIER: 790 default: 791 return (ATA_PORT_T_NONE); 792 } 793 794 /* allocate port resources */ 795 if (sili_ccb_alloc(sp) != 0) 796 return (ATA_PORT_T_NONE); 797 798 /* enable port interrupts */ 799 sili_write(sc, SILI_REG_GC, sili_read(sc, SILI_REG_GC) | 1 << port); 800 sili_pwrite(sp, SILI_PREG_IES, SILI_PREG_IE_CMDERR | 801 SILI_PREG_IE_CMDCOMP); 802 803 return (port_type); 804 } 805 806 void 807 sili_ata_free(void *xsc, int port) 808 { 809 struct sili_softc *sc = xsc; 810 struct sili_port *sp = &sc->sc_ports[port]; 811 812 if (sp->sp_ccbs != NULL) 813 sili_ccb_free(sp); 814 815 /* XXX we should do more here */ 816 } 817 818 int 819 sili_ata_cmd(struct ata_xfer *xa) 820 { 821 struct sili_ccb *ccb = (struct sili_ccb *)xa; 822 struct sili_port *sp = ccb->ccb_port; 823 struct sili_softc *sc = sp->sp_sc; 824 struct sili_prb_ata *ata; 825 struct sili_prb_packet *atapi; 826 struct sili_sge *sgl; 827 int sgllen; 828 int s; 829 830 KASSERT(xa->state == ATA_S_SETUP); 831 832 if (xa->flags & ATA_F_PACKET) { 833 atapi = ccb->ccb_cmd; 834 835 if (xa->flags & ATA_F_WRITE) 836 atapi->control = htole16(SILI_PRB_PACKET_WRITE); 837 else 838 atapi->control = htole16(SILI_PRB_PACKET_READ); 839 840 sgl = atapi->sgl; 841 sgllen = sizeofa(atapi->sgl); 842 } else { 843 ata = ccb->ccb_cmd; 844 845 ata->control = 0; 846 847 sgl = ata->sgl; 848 sgllen = sizeofa(ata->sgl); 849 } 850 851 if (sili_load(ccb, sgl, sgllen) != 0) 852 goto failcmd; 853 854 bus_dmamap_sync(sc->sc_dmat, SILI_DMA_MAP(sp->sp_cmds), 855 xa->tag * SILI_CMD_LEN, SILI_CMD_LEN, BUS_DMASYNC_PREWRITE); 856 857 timeout_set(&xa->stimeout, sili_ata_cmd_timeout, ccb); 858 859 xa->state = ATA_S_PENDING; 860 861 if (xa->flags & ATA_F_POLL) { 862 sili_poll(ccb, xa->timeout, sili_ata_cmd_timeout); 863 return (ATA_COMPLETE); 864 } 865 866 timeout_add(&xa->stimeout, (xa->timeout * hz) / 1000); 867 868 s = splbio(); 869 sili_start(sp, ccb); 870 splx(s); 871 return (ATA_QUEUED); 872 873 failcmd: 874 s = splbio(); 875 xa->state = ATA_S_ERROR; 876 xa->complete(xa); 877 splx(s); 878 return (ATA_ERROR); 879 } 880 881 void 882 sili_ata_cmd_done(struct sili_ccb *ccb, int defer_completion) 883 { 884 struct sili_port *sp = ccb->ccb_port; 885 struct sili_softc *sc = sp->sp_sc; 886 struct ata_xfer *xa = &ccb->ccb_xa; 887 888 splassert(IPL_BIO); 889 890 timeout_del(&xa->stimeout); 891 892 bus_dmamap_sync(sc->sc_dmat, SILI_DMA_MAP(sp->sp_cmds), 893 xa->tag * SILI_CMD_LEN, SILI_CMD_LEN, BUS_DMASYNC_POSTWRITE); 894 895 sili_unload(ccb); 896 897 TAILQ_REMOVE(&sp->sp_active_ccbs, ccb, ccb_entry); 898 sp->sp_active &= ~(1 << xa->tag); 899 900 if (xa->state == ATA_S_ONCHIP) 901 xa->state = ATA_S_COMPLETE; 902 #ifdef DIAGNOSTIC 903 else if (xa->state != ATA_S_ERROR && xa->state != ATA_S_TIMEOUT) 904 printf("%s: invalid ata_xfer state %02x in sili_ata_cmd_done, " 905 "slot %d\n", PORTNAME(sp), xa->state, xa->tag); 906 #endif 907 if (defer_completion) 908 TAILQ_INSERT_TAIL(&sp->sp_deferred_ccbs, ccb, ccb_entry); 909 else if (xa->state == ATA_S_COMPLETE) 910 xa->complete(xa); 911 #ifdef DIAGNOSTIC 912 else 913 printf("%s: completion not deferred, but xa->state is %02x?\n", 914 PORTNAME(sp), xa->state); 915 #endif 916 } 917 918 void 919 sili_ata_cmd_timeout(void *xccb) 920 { 921 struct sili_ccb *ccb = xccb; 922 struct sili_port *sp = ccb->ccb_port; 923 int s; 924 925 s = splbio(); 926 sili_port_intr(sp, ccb->ccb_xa.tag); 927 splx(s); 928 } 929 930 int 931 sili_load(struct sili_ccb *ccb, struct sili_sge *sgl, int sgllen) 932 { 933 struct sili_port *sp = ccb->ccb_port; 934 struct sili_softc *sc = sp->sp_sc; 935 struct ata_xfer *xa = &ccb->ccb_xa; 936 struct sili_sge *nsge = sgl, *ce = NULL; 937 bus_dmamap_t dmap = ccb->ccb_dmamap; 938 u_int64_t addr; 939 int error; 940 int i; 941 942 if (xa->datalen == 0) 943 return (0); 944 945 error = bus_dmamap_load(sc->sc_dmat, dmap, xa->data, xa->datalen, NULL, 946 (xa->flags & ATA_F_NOWAIT) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK); 947 if (error != 0) { 948 printf("%s: error %d loading dmamap\n", PORTNAME(sp), error); 949 return (1); 950 } 951 952 if (dmap->dm_nsegs > sgllen) 953 ce = &sgl[sgllen - 1]; 954 955 for (i = 0; i < dmap->dm_nsegs; i++) { 956 if (nsge == ce) { 957 nsge++; 958 959 addr = ccb->ccb_cmd_dva; 960 addr += ((u_int8_t *)nsge - (u_int8_t *)ccb->ccb_cmd); 961 962 ce->addr_lo = htole32((u_int32_t)addr); 963 ce->addr_hi = htole32((u_int32_t)(addr >> 32)); 964 ce->flags = htole32(SILI_SGE_LNK); 965 966 if ((dmap->dm_nsegs - i) > SILI_SGT_SGLLEN) 967 ce += SILI_SGT_SGLLEN; 968 else 969 ce = NULL; 970 } 971 972 sgl = nsge; 973 974 addr = dmap->dm_segs[i].ds_addr; 975 sgl->addr_lo = htole32((u_int32_t)addr); 976 sgl->addr_hi = htole32((u_int32_t)(addr >> 32)); 977 sgl->data_count = htole32(dmap->dm_segs[i].ds_len); 978 sgl->flags = 0; 979 980 nsge++; 981 } 982 sgl->flags |= htole32(SILI_SGE_TRM); 983 984 bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize, 985 (xa->flags & ATA_F_READ) ? BUS_DMASYNC_PREREAD : 986 BUS_DMASYNC_PREWRITE); 987 988 return (0); 989 } 990 991 void 992 sili_unload(struct sili_ccb *ccb) 993 { 994 struct sili_port *sp = ccb->ccb_port; 995 struct sili_softc *sc = sp->sp_sc; 996 struct ata_xfer *xa = &ccb->ccb_xa; 997 bus_dmamap_t dmap = ccb->ccb_dmamap; 998 999 if (xa->datalen == 0) 1000 return; 1001 1002 bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize, 1003 (xa->flags & ATA_F_READ) ? BUS_DMASYNC_POSTREAD : 1004 BUS_DMASYNC_POSTWRITE); 1005 bus_dmamap_unload(sc->sc_dmat, dmap); 1006 1007 if (xa->flags & ATA_F_READ) 1008 xa->resid = xa->datalen - sili_pread(sp, 1009 SILI_PREG_RX_COUNT(xa->tag)); 1010 else 1011 xa->resid = 0; 1012 } 1013 1014 int 1015 sili_poll(struct sili_ccb *ccb, int timeout, void (*timeout_fn)(void *)) 1016 { 1017 struct sili_port *sp = ccb->ccb_port; 1018 int s; 1019 1020 s = splbio(); 1021 sili_start(sp, ccb); 1022 do { 1023 if (sili_port_intr(sp, -1) & (1 << ccb->ccb_xa.tag)) { 1024 splx(s); 1025 return (0); 1026 } 1027 1028 delay(1000); 1029 } while (--timeout > 0); 1030 1031 /* Run timeout while at splbio, otherwise sili_intr could interfere. */ 1032 if (timeout_fn != NULL) 1033 timeout_fn(ccb); 1034 1035 splx(s); 1036 1037 return (1); 1038 } 1039 1040 void 1041 sili_start(struct sili_port *sp, struct sili_ccb *ccb) 1042 { 1043 int slot = ccb->ccb_xa.tag; 1044 1045 splassert(IPL_BIO); 1046 KASSERT(ccb->ccb_xa.state == ATA_S_PENDING); 1047 1048 TAILQ_INSERT_TAIL(&sp->sp_active_ccbs, ccb, ccb_entry); 1049 sp->sp_active |= 1 << slot; 1050 ccb->ccb_xa.state = ATA_S_ONCHIP; 1051 1052 sili_post_indirect(sp, ccb); 1053 } 1054 1055 int 1056 sili_read_ncq_error(struct sili_port *sp, int *err_slotp) 1057 { 1058 struct sili_softc *sc = sp->sp_sc; 1059 struct sili_prb_ata read_10h; 1060 u_int64_t addr; 1061 struct ata_fis_h2d *fis; 1062 struct ata_log_page_10h *log; 1063 struct sili_ccb *ccb; 1064 int rc; 1065 1066 sili_pwrite(sp, SILI_PREG_PCS, SILI_PREG_PCS_PORTINIT); 1067 if (!sili_pwait_eq(sp, SILI_PREG_PCS, SILI_PREG_PCS_PORTRDY, 1068 SILI_PREG_PCS_PORTRDY, 1000)) { 1069 printf("%s: couldn't ready port during log page read\n", 1070 PORTNAME(sp)); 1071 return (1); 1072 } 1073 1074 /* READ LOG EXT 10h into scratch space */ 1075 bzero(&read_10h, sizeof(read_10h)); 1076 read_10h.control = htole16(SILI_PRB_INTERRUPT_MASK); 1077 1078 addr = SILI_DMA_DVA(sp->sp_scratch); 1079 read_10h.sgl[0].addr_lo = htole32((u_int32_t)addr); 1080 read_10h.sgl[0].addr_hi = htole32((u_int32_t)(addr >> 32)); 1081 read_10h.sgl[0].data_count = htole32(512); 1082 read_10h.sgl[0].flags = htole32(SILI_SGE_TRM); 1083 1084 fis = (struct ata_fis_h2d *)read_10h.fis; 1085 fis->type = ATA_FIS_TYPE_H2D; 1086 fis->flags = ATA_H2D_FLAGS_CMD; /* XXX fis pmp field */ 1087 fis->command = ATA_C_READ_LOG_EXT; 1088 fis->lba_low = 0x10; /* queued error log page (10h) */ 1089 fis->sector_count = 1; /* number of sectors (1) */ 1090 fis->sector_count_exp = 0; 1091 fis->lba_mid = 0; /* starting offset */ 1092 fis->lba_mid_exp = 0; 1093 fis->device = 0; 1094 1095 bus_dmamap_sync(sc->sc_dmat, SILI_DMA_MAP(sp->sp_scratch), 0, 1096 512, BUS_DMASYNC_PREREAD); 1097 1098 /* issue read and poll for completion */ 1099 sili_post_direct(sp, 0, &read_10h, sizeof(read_10h)); 1100 rc = sili_pwait_eq(sp, SILI_PREG_PSS, (1 << 0), 0, 1000); 1101 1102 bus_dmamap_sync(sc->sc_dmat, SILI_DMA_MAP(sp->sp_scratch), 0, 1103 512, BUS_DMASYNC_POSTREAD); 1104 1105 if (!rc) { 1106 DPRINTF(SILI_D_VERBOSE, "%s: timed out while waiting for log " 1107 "page read\n", PORTNAME(sp)); 1108 return (1); 1109 } 1110 1111 /* Extract failed register set and tags from the scratch space. */ 1112 log = (struct ata_log_page_10h *)SILI_DMA_KVA(sp->sp_scratch); 1113 if (ISSET(log->err_regs.type, ATA_LOG_10H_TYPE_NOTQUEUED)) { 1114 /* Not queued bit was set - wasn't an NCQ error? */ 1115 printf("%s: read NCQ error page, but not an NCQ error?\n", 1116 PORTNAME(sp)); 1117 return (1); 1118 } 1119 1120 /* Copy back the log record as a D2H register FIS. */ 1121 *err_slotp = log->err_regs.type & ATA_LOG_10H_TYPE_TAG_MASK; 1122 1123 ccb = &sp->sp_ccbs[*err_slotp]; 1124 memcpy(&ccb->ccb_xa.rfis, &log->err_regs, sizeof(struct ata_fis_d2h)); 1125 ccb->ccb_xa.rfis.type = ATA_FIS_TYPE_D2H; 1126 ccb->ccb_xa.rfis.flags = 0; 1127 1128 return (0); 1129 } 1130 1131 struct ata_xfer * 1132 sili_ata_get_xfer(void *xsc, int port) 1133 { 1134 struct sili_softc *sc = xsc; 1135 struct sili_port *sp = &sc->sc_ports[port]; 1136 struct sili_ccb *ccb; 1137 1138 ccb = sili_get_ccb(sp); 1139 if (ccb == NULL) { 1140 printf("sili_ata_get_xfer: NULL ccb\n"); 1141 return (NULL); 1142 } 1143 1144 bzero(ccb->ccb_cmd, SILI_CMD_LEN); 1145 1146 return ((struct ata_xfer *)ccb); 1147 } 1148 1149 void 1150 sili_ata_put_xfer(struct ata_xfer *xa) 1151 { 1152 struct sili_ccb *ccb = (struct sili_ccb *)xa; 1153 1154 sili_put_ccb(ccb); 1155 } 1156