siis.c revision 220591
1/*- 2 * Copyright (c) 2009 Alexander Motin <mav@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer, 10 * without modification, immediately at the beginning of the file. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD: head/sys/dev/siis/siis.c 220591 2011-04-13 06:36:22Z mav $"); 29 30#include <sys/param.h> 31#include <sys/module.h> 32#include <sys/systm.h> 33#include <sys/kernel.h> 34#include <sys/ata.h> 35#include <sys/bus.h> 36#include <sys/endian.h> 37#include <sys/malloc.h> 38#include <sys/lock.h> 39#include <sys/mutex.h> 40#include <sys/sema.h> 41#include <sys/taskqueue.h> 42#include <vm/uma.h> 43#include <machine/stdarg.h> 44#include <machine/resource.h> 45#include <machine/bus.h> 46#include <sys/rman.h> 47#include <dev/led/led.h> 48#include <dev/pci/pcivar.h> 49#include <dev/pci/pcireg.h> 50#include "siis.h" 51 52#include <cam/cam.h> 53#include <cam/cam_ccb.h> 54#include <cam/cam_sim.h> 55#include <cam/cam_xpt_sim.h> 56#include <cam/cam_debug.h> 57 58/* local prototypes */ 59static int siis_setup_interrupt(device_t dev); 60static void siis_intr(void *data); 61static int siis_suspend(device_t dev); 62static int siis_resume(device_t dev); 63static int siis_ch_init(device_t dev); 64static int siis_ch_deinit(device_t dev); 65static int siis_ch_suspend(device_t dev); 66static int siis_ch_resume(device_t dev); 67static void siis_ch_intr_locked(void *data); 68static void siis_ch_intr(void *data); 69static void siis_ch_led(void *priv, int onoff); 70static void siis_begin_transaction(device_t dev, union ccb *ccb); 71static void siis_dmasetprd(void *arg, bus_dma_segment_t *segs, int nsegs, int error); 72static void siis_execute_transaction(struct siis_slot *slot); 73static void siis_timeout(struct siis_slot *slot); 74static void siis_end_transaction(struct siis_slot *slot, enum siis_err_type et); 75static int siis_setup_fis(device_t dev, struct siis_cmd *ctp, union ccb *ccb, int tag); 76static void siis_dmainit(device_t dev); 77static void siis_dmasetupc_cb(void *xsc, bus_dma_segment_t *segs, int nsegs, int error); 78static void siis_dmafini(device_t dev); 79static void siis_slotsalloc(device_t dev); 80static void siis_slotsfree(device_t dev); 81static void siis_reset(device_t dev); 82static void siis_portinit(device_t dev); 83static int siis_wait_ready(device_t dev, int t); 84 85static int siis_sata_connect(struct siis_channel *ch); 86 87static void siis_issue_recovery(device_t dev); 88static void siis_process_read_log(device_t dev, union ccb *ccb); 89static void siis_process_request_sense(device_t dev, union ccb *ccb); 90 91static void siisaction(struct cam_sim *sim, union ccb *ccb); 92static void siispoll(struct cam_sim *sim); 93 94MALLOC_DEFINE(M_SIIS, "SIIS driver", "SIIS driver data buffers"); 95 96static struct { 97 uint32_t id; 98 const char *name; 99 int ports; 100 int quirks; 101#define SIIS_Q_SNTF 1 102#define SIIS_Q_NOMSI 2 103} siis_ids[] = { 104 {0x31241095, "SiI3124", 4, 0}, 105 {0x31248086, "SiI3124", 4, 0}, 106 {0x31321095, "SiI3132", 2, SIIS_Q_SNTF|SIIS_Q_NOMSI}, 107 {0x02421095, "SiI3132", 2, SIIS_Q_SNTF|SIIS_Q_NOMSI}, 108 {0x02441095, "SiI3132", 2, SIIS_Q_SNTF|SIIS_Q_NOMSI}, 109 {0x31311095, "SiI3131", 1, SIIS_Q_SNTF|SIIS_Q_NOMSI}, 110 {0x35311095, "SiI3531", 1, SIIS_Q_SNTF|SIIS_Q_NOMSI}, 111 {0, NULL, 0, 0} 112}; 113 114#define recovery_type spriv_field0 115#define RECOVERY_NONE 0 116#define RECOVERY_READ_LOG 1 117#define RECOVERY_REQUEST_SENSE 2 118#define recovery_slot spriv_field1 119 120static int 121siis_probe(device_t dev) 122{ 123 char buf[64]; 124 int i; 125 uint32_t devid = pci_get_devid(dev); 126 127 for (i = 0; siis_ids[i].id != 0; i++) { 128 if (siis_ids[i].id == devid) { 129 snprintf(buf, sizeof(buf), "%s SATA controller", 130 siis_ids[i].name); 131 device_set_desc_copy(dev, buf); 132 return (BUS_PROBE_VENDOR); 133 } 134 } 135 return (ENXIO); 136} 137 138static int 139siis_attach(device_t dev) 140{ 141 struct siis_controller *ctlr = device_get_softc(dev); 142 uint32_t devid = pci_get_devid(dev); 143 device_t child; 144 int error, i, unit; 145 146 ctlr->dev = dev; 147 for (i = 0; siis_ids[i].id != 0; i++) { 148 if (siis_ids[i].id == devid) 149 break; 150 } 151 ctlr->quirks = siis_ids[i].quirks; 152 /* Global memory */ 153 ctlr->r_grid = PCIR_BAR(0); 154 if (!(ctlr->r_gmem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 155 &ctlr->r_grid, RF_ACTIVE))) 156 return (ENXIO); 157 ctlr->gctl = ATA_INL(ctlr->r_gmem, SIIS_GCTL); 158 /* Channels memory */ 159 ctlr->r_rid = PCIR_BAR(2); 160 if (!(ctlr->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 161 &ctlr->r_rid, RF_ACTIVE))) 162 return (ENXIO); 163 /* Setup our own memory management for channels. */ 164 ctlr->sc_iomem.rm_start = rman_get_start(ctlr->r_mem); 165 ctlr->sc_iomem.rm_end = rman_get_end(ctlr->r_mem); 166 ctlr->sc_iomem.rm_type = RMAN_ARRAY; 167 ctlr->sc_iomem.rm_descr = "I/O memory addresses"; 168 if ((error = rman_init(&ctlr->sc_iomem)) != 0) { 169 bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem); 170 bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_grid, ctlr->r_gmem); 171 return (error); 172 } 173 if ((error = rman_manage_region(&ctlr->sc_iomem, 174 rman_get_start(ctlr->r_mem), rman_get_end(ctlr->r_mem))) != 0) { 175 bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem); 176 bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_grid, ctlr->r_gmem); 177 rman_fini(&ctlr->sc_iomem); 178 return (error); 179 } 180 pci_enable_busmaster(dev); 181 /* Reset controller */ 182 siis_resume(dev); 183 /* Number of HW channels */ 184 ctlr->channels = siis_ids[i].ports; 185 /* Setup interrupts. */ 186 if (siis_setup_interrupt(dev)) { 187 bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem); 188 bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_grid, ctlr->r_gmem); 189 rman_fini(&ctlr->sc_iomem); 190 return ENXIO; 191 } 192 /* Attach all channels on this controller */ 193 for (unit = 0; unit < ctlr->channels; unit++) { 194 child = device_add_child(dev, "siisch", -1); 195 if (child == NULL) 196 device_printf(dev, "failed to add channel device\n"); 197 else 198 device_set_ivars(child, (void *)(intptr_t)unit); 199 } 200 bus_generic_attach(dev); 201 return 0; 202} 203 204static int 205siis_detach(device_t dev) 206{ 207 struct siis_controller *ctlr = device_get_softc(dev); 208 device_t *children; 209 int nchildren, i; 210 211 /* Detach & delete all children */ 212 if (!device_get_children(dev, &children, &nchildren)) { 213 for (i = 0; i < nchildren; i++) 214 device_delete_child(dev, children[i]); 215 free(children, M_TEMP); 216 } 217 /* Free interrupts. */ 218 if (ctlr->irq.r_irq) { 219 bus_teardown_intr(dev, ctlr->irq.r_irq, 220 ctlr->irq.handle); 221 bus_release_resource(dev, SYS_RES_IRQ, 222 ctlr->irq.r_irq_rid, ctlr->irq.r_irq); 223 } 224 pci_release_msi(dev); 225 /* Free memory. */ 226 rman_fini(&ctlr->sc_iomem); 227 bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem); 228 bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_grid, ctlr->r_gmem); 229 return (0); 230} 231 232static int 233siis_suspend(device_t dev) 234{ 235 struct siis_controller *ctlr = device_get_softc(dev); 236 237 bus_generic_suspend(dev); 238 /* Put controller into reset state. */ 239 ctlr->gctl |= SIIS_GCTL_GRESET; 240 ATA_OUTL(ctlr->r_gmem, SIIS_GCTL, ctlr->gctl); 241 return 0; 242} 243 244static int 245siis_resume(device_t dev) 246{ 247 struct siis_controller *ctlr = device_get_softc(dev); 248 249 /* Set PCIe max read request size to at least 1024 bytes */ 250 if (pci_get_max_read_req(dev) < 1024) 251 pci_set_max_read_req(dev, 1024); 252 /* Put controller into reset state. */ 253 ctlr->gctl |= SIIS_GCTL_GRESET; 254 ATA_OUTL(ctlr->r_gmem, SIIS_GCTL, ctlr->gctl); 255 DELAY(10000); 256 /* Get controller out of reset state and enable port interrupts. */ 257 ctlr->gctl &= ~(SIIS_GCTL_GRESET | SIIS_GCTL_I2C_IE); 258 ctlr->gctl |= 0x0000000f; 259 ATA_OUTL(ctlr->r_gmem, SIIS_GCTL, ctlr->gctl); 260 return (bus_generic_resume(dev)); 261} 262 263static int 264siis_setup_interrupt(device_t dev) 265{ 266 struct siis_controller *ctlr = device_get_softc(dev); 267 int msi = ctlr->quirks & SIIS_Q_NOMSI ? 0 : 1; 268 269 /* Process hints. */ 270 resource_int_value(device_get_name(dev), 271 device_get_unit(dev), "msi", &msi); 272 if (msi < 0) 273 msi = 0; 274 else if (msi > 0) 275 msi = min(1, pci_msi_count(dev)); 276 /* Allocate MSI if needed/present. */ 277 if (msi && pci_alloc_msi(dev, &msi) != 0) 278 msi = 0; 279 /* Allocate all IRQs. */ 280 ctlr->irq.r_irq_rid = msi ? 1 : 0; 281 if (!(ctlr->irq.r_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, 282 &ctlr->irq.r_irq_rid, RF_SHAREABLE | RF_ACTIVE))) { 283 device_printf(dev, "unable to map interrupt\n"); 284 return ENXIO; 285 } 286 if ((bus_setup_intr(dev, ctlr->irq.r_irq, ATA_INTR_FLAGS, NULL, 287 siis_intr, ctlr, &ctlr->irq.handle))) { 288 /* SOS XXX release r_irq */ 289 device_printf(dev, "unable to setup interrupt\n"); 290 return ENXIO; 291 } 292 return (0); 293} 294 295/* 296 * Common case interrupt handler. 297 */ 298static void 299siis_intr(void *data) 300{ 301 struct siis_controller *ctlr = (struct siis_controller *)data; 302 u_int32_t is; 303 void *arg; 304 int unit; 305 306 is = ATA_INL(ctlr->r_gmem, SIIS_IS); 307 for (unit = 0; unit < ctlr->channels; unit++) { 308 if ((is & SIIS_IS_PORT(unit)) != 0 && 309 (arg = ctlr->interrupt[unit].argument)) { 310 ctlr->interrupt[unit].function(arg); 311 } 312 } 313 /* Acknowledge interrupt, if MSI enabled. */ 314 if (ctlr->irq.r_irq_rid) { 315 ATA_OUTL(ctlr->r_gmem, SIIS_GCTL, 316 ctlr->gctl | SIIS_GCTL_MSIACK); 317 } 318} 319 320static struct resource * 321siis_alloc_resource(device_t dev, device_t child, int type, int *rid, 322 u_long start, u_long end, u_long count, u_int flags) 323{ 324 struct siis_controller *ctlr = device_get_softc(dev); 325 int unit = ((struct siis_channel *)device_get_softc(child))->unit; 326 struct resource *res = NULL; 327 int offset = unit << 13; 328 long st; 329 330 switch (type) { 331 case SYS_RES_MEMORY: 332 st = rman_get_start(ctlr->r_mem); 333 res = rman_reserve_resource(&ctlr->sc_iomem, st + offset, 334 st + offset + 0x2000, 0x2000, RF_ACTIVE, child); 335 if (res) { 336 bus_space_handle_t bsh; 337 bus_space_tag_t bst; 338 bsh = rman_get_bushandle(ctlr->r_mem); 339 bst = rman_get_bustag(ctlr->r_mem); 340 bus_space_subregion(bst, bsh, offset, 0x2000, &bsh); 341 rman_set_bushandle(res, bsh); 342 rman_set_bustag(res, bst); 343 } 344 break; 345 case SYS_RES_IRQ: 346 if (*rid == ATA_IRQ_RID) 347 res = ctlr->irq.r_irq; 348 break; 349 } 350 return (res); 351} 352 353static int 354siis_release_resource(device_t dev, device_t child, int type, int rid, 355 struct resource *r) 356{ 357 358 switch (type) { 359 case SYS_RES_MEMORY: 360 rman_release_resource(r); 361 return (0); 362 case SYS_RES_IRQ: 363 if (rid != ATA_IRQ_RID) 364 return ENOENT; 365 return (0); 366 } 367 return (EINVAL); 368} 369 370static int 371siis_setup_intr(device_t dev, device_t child, struct resource *irq, 372 int flags, driver_filter_t *filter, driver_intr_t *function, 373 void *argument, void **cookiep) 374{ 375 struct siis_controller *ctlr = device_get_softc(dev); 376 int unit = (intptr_t)device_get_ivars(child); 377 378 if (filter != NULL) { 379 printf("siis.c: we cannot use a filter here\n"); 380 return (EINVAL); 381 } 382 ctlr->interrupt[unit].function = function; 383 ctlr->interrupt[unit].argument = argument; 384 return (0); 385} 386 387static int 388siis_teardown_intr(device_t dev, device_t child, struct resource *irq, 389 void *cookie) 390{ 391 struct siis_controller *ctlr = device_get_softc(dev); 392 int unit = (intptr_t)device_get_ivars(child); 393 394 ctlr->interrupt[unit].function = NULL; 395 ctlr->interrupt[unit].argument = NULL; 396 return (0); 397} 398 399static int 400siis_print_child(device_t dev, device_t child) 401{ 402 int retval; 403 404 retval = bus_print_child_header(dev, child); 405 retval += printf(" at channel %d", 406 (int)(intptr_t)device_get_ivars(child)); 407 retval += bus_print_child_footer(dev, child); 408 409 return (retval); 410} 411 412static int 413siis_child_location_str(device_t dev, device_t child, char *buf, 414 size_t buflen) 415{ 416 417 snprintf(buf, buflen, "channel=%d", 418 (int)(intptr_t)device_get_ivars(child)); 419 return (0); 420} 421 422devclass_t siis_devclass; 423static device_method_t siis_methods[] = { 424 DEVMETHOD(device_probe, siis_probe), 425 DEVMETHOD(device_attach, siis_attach), 426 DEVMETHOD(device_detach, siis_detach), 427 DEVMETHOD(device_suspend, siis_suspend), 428 DEVMETHOD(device_resume, siis_resume), 429 DEVMETHOD(bus_print_child, siis_print_child), 430 DEVMETHOD(bus_alloc_resource, siis_alloc_resource), 431 DEVMETHOD(bus_release_resource, siis_release_resource), 432 DEVMETHOD(bus_setup_intr, siis_setup_intr), 433 DEVMETHOD(bus_teardown_intr,siis_teardown_intr), 434 DEVMETHOD(bus_child_location_str, siis_child_location_str), 435 { 0, 0 } 436}; 437static driver_t siis_driver = { 438 "siis", 439 siis_methods, 440 sizeof(struct siis_controller) 441}; 442DRIVER_MODULE(siis, pci, siis_driver, siis_devclass, 0, 0); 443MODULE_VERSION(siis, 1); 444MODULE_DEPEND(siis, cam, 1, 1, 1); 445 446static int 447siis_ch_probe(device_t dev) 448{ 449 450 device_set_desc_copy(dev, "SIIS channel"); 451 return (0); 452} 453 454static int 455siis_ch_attach(device_t dev) 456{ 457 struct siis_controller *ctlr = device_get_softc(device_get_parent(dev)); 458 struct siis_channel *ch = device_get_softc(dev); 459 struct cam_devq *devq; 460 int rid, error, i, sata_rev = 0; 461 462 ch->dev = dev; 463 ch->unit = (intptr_t)device_get_ivars(dev); 464 ch->quirks = ctlr->quirks; 465 resource_int_value(device_get_name(dev), 466 device_get_unit(dev), "pm_level", &ch->pm_level); 467 resource_int_value(device_get_name(dev), 468 device_get_unit(dev), "sata_rev", &sata_rev); 469 for (i = 0; i < 16; i++) { 470 ch->user[i].revision = sata_rev; 471 ch->user[i].mode = 0; 472 ch->user[i].bytecount = 8192; 473 ch->user[i].tags = SIIS_MAX_SLOTS; 474 ch->curr[i] = ch->user[i]; 475 if (ch->pm_level) 476 ch->user[i].caps = CTS_SATA_CAPS_H_PMREQ; 477 } 478 mtx_init(&ch->mtx, "SIIS channel lock", NULL, MTX_DEF); 479 rid = ch->unit; 480 if (!(ch->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 481 &rid, RF_ACTIVE))) 482 return (ENXIO); 483 siis_dmainit(dev); 484 siis_slotsalloc(dev); 485 siis_ch_init(dev); 486 mtx_lock(&ch->mtx); 487 rid = ATA_IRQ_RID; 488 if (!(ch->r_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, 489 &rid, RF_SHAREABLE | RF_ACTIVE))) { 490 device_printf(dev, "Unable to map interrupt\n"); 491 error = ENXIO; 492 goto err0; 493 } 494 if ((bus_setup_intr(dev, ch->r_irq, ATA_INTR_FLAGS, NULL, 495 siis_ch_intr_locked, dev, &ch->ih))) { 496 device_printf(dev, "Unable to setup interrupt\n"); 497 error = ENXIO; 498 goto err1; 499 } 500 /* Create the device queue for our SIM. */ 501 devq = cam_simq_alloc(SIIS_MAX_SLOTS); 502 if (devq == NULL) { 503 device_printf(dev, "Unable to allocate simq\n"); 504 error = ENOMEM; 505 goto err1; 506 } 507 /* Construct SIM entry */ 508 ch->sim = cam_sim_alloc(siisaction, siispoll, "siisch", ch, 509 device_get_unit(dev), &ch->mtx, 2, SIIS_MAX_SLOTS, devq); 510 if (ch->sim == NULL) { 511 cam_simq_free(devq); 512 device_printf(dev, "unable to allocate sim\n"); 513 error = ENOMEM; 514 goto err1; 515 } 516 if (xpt_bus_register(ch->sim, dev, 0) != CAM_SUCCESS) { 517 device_printf(dev, "unable to register xpt bus\n"); 518 error = ENXIO; 519 goto err2; 520 } 521 if (xpt_create_path(&ch->path, /*periph*/NULL, cam_sim_path(ch->sim), 522 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 523 device_printf(dev, "unable to create path\n"); 524 error = ENXIO; 525 goto err3; 526 } 527 mtx_unlock(&ch->mtx); 528 ch->led = led_create(siis_ch_led, dev, device_get_nameunit(dev)); 529 return (0); 530 531err3: 532 xpt_bus_deregister(cam_sim_path(ch->sim)); 533err2: 534 cam_sim_free(ch->sim, /*free_devq*/TRUE); 535err1: 536 bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ch->r_irq); 537err0: 538 bus_release_resource(dev, SYS_RES_MEMORY, ch->unit, ch->r_mem); 539 mtx_unlock(&ch->mtx); 540 mtx_destroy(&ch->mtx); 541 return (error); 542} 543 544static int 545siis_ch_detach(device_t dev) 546{ 547 struct siis_channel *ch = device_get_softc(dev); 548 549 led_destroy(ch->led); 550 mtx_lock(&ch->mtx); 551 xpt_async(AC_LOST_DEVICE, ch->path, NULL); 552 xpt_free_path(ch->path); 553 xpt_bus_deregister(cam_sim_path(ch->sim)); 554 cam_sim_free(ch->sim, /*free_devq*/TRUE); 555 mtx_unlock(&ch->mtx); 556 557 bus_teardown_intr(dev, ch->r_irq, ch->ih); 558 bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ch->r_irq); 559 560 siis_ch_deinit(dev); 561 siis_slotsfree(dev); 562 siis_dmafini(dev); 563 564 bus_release_resource(dev, SYS_RES_MEMORY, ch->unit, ch->r_mem); 565 mtx_destroy(&ch->mtx); 566 return (0); 567} 568 569static int 570siis_ch_init(device_t dev) 571{ 572 struct siis_channel *ch = device_get_softc(dev); 573 574 /* Get port out of reset state. */ 575 ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_PORT_RESET); 576 ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_32BIT); 577 if (ch->pm_present) 578 ATA_OUTL(ch->r_mem, SIIS_P_CTLSET, SIIS_P_CTL_PME); 579 else 580 ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_PME); 581 /* Enable port interrupts */ 582 ATA_OUTL(ch->r_mem, SIIS_P_IESET, SIIS_P_IX_ENABLED); 583 return (0); 584} 585 586static int 587siis_ch_deinit(device_t dev) 588{ 589 struct siis_channel *ch = device_get_softc(dev); 590 591 /* Put port into reset state. */ 592 ATA_OUTL(ch->r_mem, SIIS_P_CTLSET, SIIS_P_CTL_PORT_RESET); 593 return (0); 594} 595 596static int 597siis_ch_suspend(device_t dev) 598{ 599 struct siis_channel *ch = device_get_softc(dev); 600 601 mtx_lock(&ch->mtx); 602 xpt_freeze_simq(ch->sim, 1); 603 while (ch->oslots) 604 msleep(ch, &ch->mtx, PRIBIO, "siissusp", hz/100); 605 siis_ch_deinit(dev); 606 mtx_unlock(&ch->mtx); 607 return (0); 608} 609 610static int 611siis_ch_resume(device_t dev) 612{ 613 struct siis_channel *ch = device_get_softc(dev); 614 615 mtx_lock(&ch->mtx); 616 siis_ch_init(dev); 617 siis_reset(dev); 618 xpt_release_simq(ch->sim, TRUE); 619 mtx_unlock(&ch->mtx); 620 return (0); 621} 622 623devclass_t siisch_devclass; 624static device_method_t siisch_methods[] = { 625 DEVMETHOD(device_probe, siis_ch_probe), 626 DEVMETHOD(device_attach, siis_ch_attach), 627 DEVMETHOD(device_detach, siis_ch_detach), 628 DEVMETHOD(device_suspend, siis_ch_suspend), 629 DEVMETHOD(device_resume, siis_ch_resume), 630 { 0, 0 } 631}; 632static driver_t siisch_driver = { 633 "siisch", 634 siisch_methods, 635 sizeof(struct siis_channel) 636}; 637DRIVER_MODULE(siisch, siis, siisch_driver, siis_devclass, 0, 0); 638 639static void 640siis_ch_led(void *priv, int onoff) 641{ 642 device_t dev; 643 struct siis_channel *ch; 644 645 dev = (device_t)priv; 646 ch = device_get_softc(dev); 647 648 if (onoff == 0) 649 ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_LED_ON); 650 else 651 ATA_OUTL(ch->r_mem, SIIS_P_CTLSET, SIIS_P_CTL_LED_ON); 652} 653 654struct siis_dc_cb_args { 655 bus_addr_t maddr; 656 int error; 657}; 658 659static void 660siis_dmainit(device_t dev) 661{ 662 struct siis_channel *ch = device_get_softc(dev); 663 struct siis_dc_cb_args dcba; 664 665 /* Command area. */ 666 if (bus_dma_tag_create(bus_get_dma_tag(dev), 1024, 0, 667 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, 668 NULL, NULL, SIIS_WORK_SIZE, 1, SIIS_WORK_SIZE, 669 0, NULL, NULL, &ch->dma.work_tag)) 670 goto error; 671 if (bus_dmamem_alloc(ch->dma.work_tag, (void **)&ch->dma.work, 0, 672 &ch->dma.work_map)) 673 goto error; 674 if (bus_dmamap_load(ch->dma.work_tag, ch->dma.work_map, ch->dma.work, 675 SIIS_WORK_SIZE, siis_dmasetupc_cb, &dcba, 0) || dcba.error) { 676 bus_dmamem_free(ch->dma.work_tag, ch->dma.work, ch->dma.work_map); 677 goto error; 678 } 679 ch->dma.work_bus = dcba.maddr; 680 /* Data area. */ 681 if (bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0, 682 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, 683 NULL, NULL, 684 SIIS_SG_ENTRIES * PAGE_SIZE * SIIS_MAX_SLOTS, 685 SIIS_SG_ENTRIES, 0xFFFFFFFF, 686 0, busdma_lock_mutex, &ch->mtx, &ch->dma.data_tag)) { 687 goto error; 688 } 689 return; 690 691error: 692 device_printf(dev, "WARNING - DMA initialization failed\n"); 693 siis_dmafini(dev); 694} 695 696static void 697siis_dmasetupc_cb(void *xsc, bus_dma_segment_t *segs, int nsegs, int error) 698{ 699 struct siis_dc_cb_args *dcba = (struct siis_dc_cb_args *)xsc; 700 701 if (!(dcba->error = error)) 702 dcba->maddr = segs[0].ds_addr; 703} 704 705static void 706siis_dmafini(device_t dev) 707{ 708 struct siis_channel *ch = device_get_softc(dev); 709 710 if (ch->dma.data_tag) { 711 bus_dma_tag_destroy(ch->dma.data_tag); 712 ch->dma.data_tag = NULL; 713 } 714 if (ch->dma.work_bus) { 715 bus_dmamap_unload(ch->dma.work_tag, ch->dma.work_map); 716 bus_dmamem_free(ch->dma.work_tag, ch->dma.work, ch->dma.work_map); 717 ch->dma.work_bus = 0; 718 ch->dma.work_map = NULL; 719 ch->dma.work = NULL; 720 } 721 if (ch->dma.work_tag) { 722 bus_dma_tag_destroy(ch->dma.work_tag); 723 ch->dma.work_tag = NULL; 724 } 725} 726 727static void 728siis_slotsalloc(device_t dev) 729{ 730 struct siis_channel *ch = device_get_softc(dev); 731 int i; 732 733 /* Alloc and setup command/dma slots */ 734 bzero(ch->slot, sizeof(ch->slot)); 735 for (i = 0; i < SIIS_MAX_SLOTS; i++) { 736 struct siis_slot *slot = &ch->slot[i]; 737 738 slot->dev = dev; 739 slot->slot = i; 740 slot->state = SIIS_SLOT_EMPTY; 741 slot->ccb = NULL; 742 callout_init_mtx(&slot->timeout, &ch->mtx, 0); 743 744 if (bus_dmamap_create(ch->dma.data_tag, 0, &slot->dma.data_map)) 745 device_printf(ch->dev, "FAILURE - create data_map\n"); 746 } 747} 748 749static void 750siis_slotsfree(device_t dev) 751{ 752 struct siis_channel *ch = device_get_softc(dev); 753 int i; 754 755 /* Free all dma slots */ 756 for (i = 0; i < SIIS_MAX_SLOTS; i++) { 757 struct siis_slot *slot = &ch->slot[i]; 758 759 callout_drain(&slot->timeout); 760 if (slot->dma.data_map) { 761 bus_dmamap_destroy(ch->dma.data_tag, slot->dma.data_map); 762 slot->dma.data_map = NULL; 763 } 764 } 765} 766 767static void 768siis_notify_events(device_t dev) 769{ 770 struct siis_channel *ch = device_get_softc(dev); 771 struct cam_path *dpath; 772 u_int32_t status; 773 int i; 774 775 if (ch->quirks & SIIS_Q_SNTF) { 776 status = ATA_INL(ch->r_mem, SIIS_P_SNTF); 777 ATA_OUTL(ch->r_mem, SIIS_P_SNTF, status); 778 } else { 779 /* 780 * Without SNTF we have no idea which device sent notification. 781 * If PMP is connected, assume it, else - device. 782 */ 783 status = (ch->pm_present) ? 0x8000 : 0x0001; 784 } 785 if (bootverbose) 786 device_printf(dev, "SNTF 0x%04x\n", status); 787 for (i = 0; i < 16; i++) { 788 if ((status & (1 << i)) == 0) 789 continue; 790 if (xpt_create_path(&dpath, NULL, 791 xpt_path_path_id(ch->path), i, 0) == CAM_REQ_CMP) { 792 xpt_async(AC_SCSI_AEN, dpath, NULL); 793 xpt_free_path(dpath); 794 } 795 } 796 797} 798 799static void 800siis_phy_check_events(device_t dev) 801{ 802 struct siis_channel *ch = device_get_softc(dev); 803 804 /* If we have a connection event, deal with it */ 805 if (ch->pm_level == 0) { 806 u_int32_t status = ATA_INL(ch->r_mem, SIIS_P_SSTS); 807 union ccb *ccb; 808 809 if (bootverbose) { 810 if (((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_ONLINE) && 811 ((status & ATA_SS_SPD_MASK) != ATA_SS_SPD_NO_SPEED) && 812 ((status & ATA_SS_IPM_MASK) == ATA_SS_IPM_ACTIVE)) { 813 device_printf(dev, "CONNECT requested\n"); 814 } else 815 device_printf(dev, "DISCONNECT requested\n"); 816 } 817 siis_reset(dev); 818 if ((ccb = xpt_alloc_ccb_nowait()) == NULL) 819 return; 820 if (xpt_create_path(&ccb->ccb_h.path, NULL, 821 cam_sim_path(ch->sim), 822 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 823 xpt_free_ccb(ccb); 824 return; 825 } 826 xpt_rescan(ccb); 827 } 828} 829 830static void 831siis_ch_intr_locked(void *data) 832{ 833 device_t dev = (device_t)data; 834 struct siis_channel *ch = device_get_softc(dev); 835 836 mtx_lock(&ch->mtx); 837 siis_ch_intr(data); 838 mtx_unlock(&ch->mtx); 839} 840 841static void 842siis_ch_intr(void *data) 843{ 844 device_t dev = (device_t)data; 845 struct siis_channel *ch = device_get_softc(dev); 846 uint32_t istatus, sstatus, ctx, estatus, ok, err = 0; 847 enum siis_err_type et; 848 int i, ccs, port, tslots; 849 850 mtx_assert(&ch->mtx, MA_OWNED); 851 /* Read command statuses. */ 852 sstatus = ATA_INL(ch->r_mem, SIIS_P_SS); 853 ok = ch->rslots & ~sstatus; 854 /* Complete all successfull commands. */ 855 for (i = 0; i < SIIS_MAX_SLOTS; i++) { 856 if ((ok >> i) & 1) 857 siis_end_transaction(&ch->slot[i], SIIS_ERR_NONE); 858 } 859 /* Do we have any other events? */ 860 if ((sstatus & SIIS_P_SS_ATTN) == 0) 861 return; 862 /* Read and clear interrupt statuses. */ 863 istatus = ATA_INL(ch->r_mem, SIIS_P_IS) & 864 (0xFFFF & ~SIIS_P_IX_COMMCOMP); 865 ATA_OUTL(ch->r_mem, SIIS_P_IS, istatus); 866 /* Process PHY events */ 867 if (istatus & SIIS_P_IX_PHYRDYCHG) 868 siis_phy_check_events(dev); 869 /* Process NOTIFY events */ 870 if (istatus & SIIS_P_IX_SDBN) 871 siis_notify_events(dev); 872 /* Process command errors */ 873 if (istatus & SIIS_P_IX_COMMERR) { 874 estatus = ATA_INL(ch->r_mem, SIIS_P_CMDERR); 875 ctx = ATA_INL(ch->r_mem, SIIS_P_CTX); 876 ccs = (ctx & SIIS_P_CTX_SLOT) >> SIIS_P_CTX_SLOT_SHIFT; 877 port = (ctx & SIIS_P_CTX_PMP) >> SIIS_P_CTX_PMP_SHIFT; 878 err = ch->rslots & sstatus; 879//device_printf(dev, "%s ERROR ss %08x is %08x rs %08x es %d act %d port %d serr %08x\n", 880// __func__, sstatus, istatus, ch->rslots, estatus, ccs, port, 881// ATA_INL(ch->r_mem, SIIS_P_SERR)); 882 883 if (!ch->recoverycmd && !ch->recovery) { 884 xpt_freeze_simq(ch->sim, ch->numrslots); 885 ch->recovery = 1; 886 } 887 if (ch->frozen) { 888 union ccb *fccb = ch->frozen; 889 ch->frozen = NULL; 890 fccb->ccb_h.status &= ~CAM_STATUS_MASK; 891 fccb->ccb_h.status |= CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ; 892 if (!(fccb->ccb_h.status & CAM_DEV_QFRZN)) { 893 xpt_freeze_devq(fccb->ccb_h.path, 1); 894 fccb->ccb_h.status |= CAM_DEV_QFRZN; 895 } 896 xpt_done(fccb); 897 } 898 if (estatus == SIIS_P_CMDERR_DEV || 899 estatus == SIIS_P_CMDERR_SDB || 900 estatus == SIIS_P_CMDERR_DATAFIS) { 901 tslots = ch->numtslots[port]; 902 for (i = 0; i < SIIS_MAX_SLOTS; i++) { 903 /* XXX: requests in loading state. */ 904 if (((ch->rslots >> i) & 1) == 0) 905 continue; 906 if (ch->slot[i].ccb->ccb_h.target_id != port) 907 continue; 908 if (tslots == 0) { 909 /* Untagged operation. */ 910 if (i == ccs) 911 et = SIIS_ERR_TFE; 912 else 913 et = SIIS_ERR_INNOCENT; 914 } else { 915 /* Tagged operation. */ 916 et = SIIS_ERR_NCQ; 917 } 918 siis_end_transaction(&ch->slot[i], et); 919 } 920 /* 921 * We can't reinit port if there are some other 922 * commands active, use resume to complete them. 923 */ 924 if (ch->rslots != 0 && !ch->recoverycmd) 925 ATA_OUTL(ch->r_mem, SIIS_P_CTLSET, SIIS_P_CTL_RESUME); 926 } else { 927 if (estatus == SIIS_P_CMDERR_SENDFIS || 928 estatus == SIIS_P_CMDERR_INCSTATE || 929 estatus == SIIS_P_CMDERR_PPE || 930 estatus == SIIS_P_CMDERR_SERVICE) { 931 et = SIIS_ERR_SATA; 932 } else 933 et = SIIS_ERR_INVALID; 934 for (i = 0; i < SIIS_MAX_SLOTS; i++) { 935 /* XXX: requests in loading state. */ 936 if (((ch->rslots >> i) & 1) == 0) 937 continue; 938 siis_end_transaction(&ch->slot[i], et); 939 } 940 } 941 } 942} 943 944/* Must be called with channel locked. */ 945static int 946siis_check_collision(device_t dev, union ccb *ccb) 947{ 948 struct siis_channel *ch = device_get_softc(dev); 949 950 mtx_assert(&ch->mtx, MA_OWNED); 951 if ((ccb->ccb_h.func_code == XPT_ATA_IO) && 952 (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) { 953 /* Tagged command while we have no supported tag free. */ 954 if (((~ch->oslots) & (0x7fffffff >> (31 - 955 ch->curr[ccb->ccb_h.target_id].tags))) == 0) 956 return (1); 957 } 958 if ((ccb->ccb_h.func_code == XPT_ATA_IO) && 959 (ccb->ataio.cmd.flags & (CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT))) { 960 /* Atomic command while anything active. */ 961 if (ch->numrslots != 0) 962 return (1); 963 } 964 /* We have some atomic command running. */ 965 if (ch->aslots != 0) 966 return (1); 967 return (0); 968} 969 970/* Must be called with channel locked. */ 971static void 972siis_begin_transaction(device_t dev, union ccb *ccb) 973{ 974 struct siis_channel *ch = device_get_softc(dev); 975 struct siis_slot *slot; 976 int tag, tags; 977 978 mtx_assert(&ch->mtx, MA_OWNED); 979 /* Choose empty slot. */ 980 tags = SIIS_MAX_SLOTS; 981 if ((ccb->ccb_h.func_code == XPT_ATA_IO) && 982 (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) 983 tags = ch->curr[ccb->ccb_h.target_id].tags; 984 tag = fls((~ch->oslots) & (0x7fffffff >> (31 - tags))) - 1; 985 /* Occupy chosen slot. */ 986 slot = &ch->slot[tag]; 987 slot->ccb = ccb; 988 /* Update channel stats. */ 989 ch->oslots |= (1 << slot->slot); 990 ch->numrslots++; 991 if ((ccb->ccb_h.func_code == XPT_ATA_IO) && 992 (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) { 993 ch->numtslots[ccb->ccb_h.target_id]++; 994 } 995 if ((ccb->ccb_h.func_code == XPT_ATA_IO) && 996 (ccb->ataio.cmd.flags & (CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT))) 997 ch->aslots |= (1 << slot->slot); 998 slot->dma.nsegs = 0; 999 /* If request moves data, setup and load SG list */ 1000 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 1001 void *buf; 1002 bus_size_t size; 1003 1004 slot->state = SIIS_SLOT_LOADING; 1005 if (ccb->ccb_h.func_code == XPT_ATA_IO) { 1006 buf = ccb->ataio.data_ptr; 1007 size = ccb->ataio.dxfer_len; 1008 } else { 1009 buf = ccb->csio.data_ptr; 1010 size = ccb->csio.dxfer_len; 1011 } 1012 bus_dmamap_load(ch->dma.data_tag, slot->dma.data_map, 1013 buf, size, siis_dmasetprd, slot, 0); 1014 } else 1015 siis_execute_transaction(slot); 1016} 1017 1018/* Locked by busdma engine. */ 1019static void 1020siis_dmasetprd(void *arg, bus_dma_segment_t *segs, int nsegs, int error) 1021{ 1022 struct siis_slot *slot = arg; 1023 struct siis_channel *ch = device_get_softc(slot->dev); 1024 struct siis_cmd *ctp; 1025 struct siis_dma_prd *prd; 1026 int i; 1027 1028 mtx_assert(&ch->mtx, MA_OWNED); 1029 if (error) { 1030 device_printf(slot->dev, "DMA load error\n"); 1031 if (!ch->recoverycmd) 1032 xpt_freeze_simq(ch->sim, 1); 1033 siis_end_transaction(slot, SIIS_ERR_INVALID); 1034 return; 1035 } 1036 KASSERT(nsegs <= SIIS_SG_ENTRIES, ("too many DMA segment entries\n")); 1037 /* Get a piece of the workspace for this request */ 1038 ctp = (struct siis_cmd *) 1039 (ch->dma.work + SIIS_CT_OFFSET + (SIIS_CT_SIZE * slot->slot)); 1040 /* Fill S/G table */ 1041 if (slot->ccb->ccb_h.func_code == XPT_ATA_IO) 1042 prd = &ctp->u.ata.prd[0]; 1043 else 1044 prd = &ctp->u.atapi.prd[0]; 1045 for (i = 0; i < nsegs; i++) { 1046 prd[i].dba = htole64(segs[i].ds_addr); 1047 prd[i].dbc = htole32(segs[i].ds_len); 1048 prd[i].control = 0; 1049 } 1050 prd[nsegs - 1].control = htole32(SIIS_PRD_TRM); 1051 slot->dma.nsegs = nsegs; 1052 bus_dmamap_sync(ch->dma.data_tag, slot->dma.data_map, 1053 ((slot->ccb->ccb_h.flags & CAM_DIR_IN) ? 1054 BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE)); 1055 siis_execute_transaction(slot); 1056} 1057 1058/* Must be called with channel locked. */ 1059static void 1060siis_execute_transaction(struct siis_slot *slot) 1061{ 1062 device_t dev = slot->dev; 1063 struct siis_channel *ch = device_get_softc(dev); 1064 struct siis_cmd *ctp; 1065 union ccb *ccb = slot->ccb; 1066 u_int64_t prb_bus; 1067 1068 mtx_assert(&ch->mtx, MA_OWNED); 1069 /* Get a piece of the workspace for this request */ 1070 ctp = (struct siis_cmd *) 1071 (ch->dma.work + SIIS_CT_OFFSET + (SIIS_CT_SIZE * slot->slot)); 1072 ctp->control = 0; 1073 ctp->protocol_override = 0; 1074 ctp->transfer_count = 0; 1075 /* Special handling for Soft Reset command. */ 1076 if (ccb->ccb_h.func_code == XPT_ATA_IO) { 1077 if (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) { 1078 ctp->control |= htole16(SIIS_PRB_SOFT_RESET); 1079 } else { 1080 ctp->control |= htole16(SIIS_PRB_PROTOCOL_OVERRIDE); 1081 if (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA) { 1082 ctp->protocol_override |= 1083 htole16(SIIS_PRB_PROTO_NCQ); 1084 } 1085 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { 1086 ctp->protocol_override |= 1087 htole16(SIIS_PRB_PROTO_READ); 1088 } else 1089 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) { 1090 ctp->protocol_override |= 1091 htole16(SIIS_PRB_PROTO_WRITE); 1092 } 1093 } 1094 } else if (ccb->ccb_h.func_code == XPT_SCSI_IO) { 1095 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) 1096 ctp->control |= htole16(SIIS_PRB_PACKET_READ); 1097 else 1098 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) 1099 ctp->control |= htole16(SIIS_PRB_PACKET_WRITE); 1100 } 1101 /* Special handling for Soft Reset command. */ 1102 if ((ccb->ccb_h.func_code == XPT_ATA_IO) && 1103 (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) && 1104 (ccb->ataio.cmd.control & ATA_A_RESET)) { 1105 /* Kick controller into sane state */ 1106 siis_portinit(dev); 1107 } 1108 /* Setup the FIS for this request */ 1109 if (!siis_setup_fis(dev, ctp, ccb, slot->slot)) { 1110 device_printf(ch->dev, "Setting up SATA FIS failed\n"); 1111 if (!ch->recoverycmd) 1112 xpt_freeze_simq(ch->sim, 1); 1113 siis_end_transaction(slot, SIIS_ERR_INVALID); 1114 return; 1115 } 1116 bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map, 1117 BUS_DMASYNC_PREWRITE); 1118 /* Issue command to the controller. */ 1119 slot->state = SIIS_SLOT_RUNNING; 1120 ch->rslots |= (1 << slot->slot); 1121 prb_bus = ch->dma.work_bus + 1122 SIIS_CT_OFFSET + (SIIS_CT_SIZE * slot->slot); 1123 ATA_OUTL(ch->r_mem, SIIS_P_CACTL(slot->slot), prb_bus); 1124 ATA_OUTL(ch->r_mem, SIIS_P_CACTH(slot->slot), prb_bus >> 32); 1125 /* Start command execution timeout */ 1126 callout_reset(&slot->timeout, (int)ccb->ccb_h.timeout * hz / 1000, 1127 (timeout_t*)siis_timeout, slot); 1128 return; 1129} 1130 1131/* Must be called with channel locked. */ 1132static void 1133siis_process_timeout(device_t dev) 1134{ 1135 struct siis_channel *ch = device_get_softc(dev); 1136 int i; 1137 1138 mtx_assert(&ch->mtx, MA_OWNED); 1139 if (!ch->recoverycmd && !ch->recovery) { 1140 xpt_freeze_simq(ch->sim, ch->numrslots); 1141 ch->recovery = 1; 1142 } 1143 /* Handle the rest of commands. */ 1144 for (i = 0; i < SIIS_MAX_SLOTS; i++) { 1145 /* Do we have a running request on slot? */ 1146 if (ch->slot[i].state < SIIS_SLOT_RUNNING) 1147 continue; 1148 siis_end_transaction(&ch->slot[i], SIIS_ERR_TIMEOUT); 1149 } 1150} 1151 1152/* Must be called with channel locked. */ 1153static void 1154siis_rearm_timeout(device_t dev) 1155{ 1156 struct siis_channel *ch = device_get_softc(dev); 1157 int i; 1158 1159 mtx_assert(&ch->mtx, MA_OWNED); 1160 for (i = 0; i < SIIS_MAX_SLOTS; i++) { 1161 struct siis_slot *slot = &ch->slot[i]; 1162 1163 /* Do we have a running request on slot? */ 1164 if (slot->state < SIIS_SLOT_RUNNING) 1165 continue; 1166 if ((ch->toslots & (1 << i)) == 0) 1167 continue; 1168 callout_reset(&slot->timeout, 1169 (int)slot->ccb->ccb_h.timeout * hz / 1000, 1170 (timeout_t*)siis_timeout, slot); 1171 } 1172} 1173 1174/* Locked by callout mechanism. */ 1175static void 1176siis_timeout(struct siis_slot *slot) 1177{ 1178 device_t dev = slot->dev; 1179 struct siis_channel *ch = device_get_softc(dev); 1180 1181 mtx_assert(&ch->mtx, MA_OWNED); 1182 /* Check for stale timeout. */ 1183 if (slot->state < SIIS_SLOT_RUNNING) 1184 return; 1185 device_printf(dev, "Timeout on slot %d\n", slot->slot); 1186 device_printf(dev, "%s is %08x ss %08x rs %08x es %08x sts %08x serr %08x\n", 1187 __func__, ATA_INL(ch->r_mem, SIIS_P_IS), 1188 ATA_INL(ch->r_mem, SIIS_P_SS), ch->rslots, 1189 ATA_INL(ch->r_mem, SIIS_P_CMDERR), ATA_INL(ch->r_mem, SIIS_P_STS), 1190 ATA_INL(ch->r_mem, SIIS_P_SERR)); 1191 1192 if (ch->toslots == 0) 1193 xpt_freeze_simq(ch->sim, 1); 1194 ch->toslots |= (1 << slot->slot); 1195 if ((ch->rslots & ~ch->toslots) == 0) 1196 siis_process_timeout(dev); 1197 else 1198 device_printf(dev, " ... waiting for slots %08x\n", 1199 ch->rslots & ~ch->toslots); 1200} 1201 1202/* Must be called with channel locked. */ 1203static void 1204siis_end_transaction(struct siis_slot *slot, enum siis_err_type et) 1205{ 1206 device_t dev = slot->dev; 1207 struct siis_channel *ch = device_get_softc(dev); 1208 union ccb *ccb = slot->ccb; 1209 int lastto; 1210 1211 mtx_assert(&ch->mtx, MA_OWNED); 1212 bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map, 1213 BUS_DMASYNC_POSTWRITE); 1214 /* Read result registers to the result struct 1215 * May be incorrect if several commands finished same time, 1216 * so read only when sure or have to. 1217 */ 1218 if (ccb->ccb_h.func_code == XPT_ATA_IO) { 1219 struct ata_res *res = &ccb->ataio.res; 1220 if ((et == SIIS_ERR_TFE) || 1221 (ccb->ataio.cmd.flags & CAM_ATAIO_NEEDRESULT)) { 1222 int offs = SIIS_P_LRAM_SLOT(slot->slot) + 8; 1223 1224 res->status = ATA_INB(ch->r_mem, offs + 2); 1225 res->error = ATA_INB(ch->r_mem, offs + 3); 1226 res->lba_low = ATA_INB(ch->r_mem, offs + 4); 1227 res->lba_mid = ATA_INB(ch->r_mem, offs + 5); 1228 res->lba_high = ATA_INB(ch->r_mem, offs + 6); 1229 res->device = ATA_INB(ch->r_mem, offs + 7); 1230 res->lba_low_exp = ATA_INB(ch->r_mem, offs + 8); 1231 res->lba_mid_exp = ATA_INB(ch->r_mem, offs + 9); 1232 res->lba_high_exp = ATA_INB(ch->r_mem, offs + 10); 1233 res->sector_count = ATA_INB(ch->r_mem, offs + 12); 1234 res->sector_count_exp = ATA_INB(ch->r_mem, offs + 13); 1235 } else 1236 bzero(res, sizeof(*res)); 1237 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN && 1238 ch->numrslots == 1) { 1239 ccb->ataio.resid = ccb->ataio.dxfer_len - 1240 ATA_INL(ch->r_mem, SIIS_P_LRAM_SLOT(slot->slot) + 4); 1241 } 1242 } else { 1243 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN && 1244 ch->numrslots == 1) { 1245 ccb->csio.resid = ccb->csio.dxfer_len - 1246 ATA_INL(ch->r_mem, SIIS_P_LRAM_SLOT(slot->slot) + 4); 1247 } 1248 } 1249 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 1250 bus_dmamap_sync(ch->dma.data_tag, slot->dma.data_map, 1251 (ccb->ccb_h.flags & CAM_DIR_IN) ? 1252 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 1253 bus_dmamap_unload(ch->dma.data_tag, slot->dma.data_map); 1254 } 1255 /* Set proper result status. */ 1256 if (et != SIIS_ERR_NONE || ch->recovery) { 1257 ch->eslots |= (1 << slot->slot); 1258 ccb->ccb_h.status |= CAM_RELEASE_SIMQ; 1259 } 1260 /* In case of error, freeze device for proper recovery. */ 1261 if (et != SIIS_ERR_NONE && (!ch->recoverycmd) && 1262 !(ccb->ccb_h.status & CAM_DEV_QFRZN)) { 1263 xpt_freeze_devq(ccb->ccb_h.path, 1); 1264 ccb->ccb_h.status |= CAM_DEV_QFRZN; 1265 } 1266 ccb->ccb_h.status &= ~CAM_STATUS_MASK; 1267 switch (et) { 1268 case SIIS_ERR_NONE: 1269 ccb->ccb_h.status |= CAM_REQ_CMP; 1270 if (ccb->ccb_h.func_code == XPT_SCSI_IO) 1271 ccb->csio.scsi_status = SCSI_STATUS_OK; 1272 break; 1273 case SIIS_ERR_INVALID: 1274 ch->fatalerr = 1; 1275 ccb->ccb_h.status |= CAM_REQ_INVALID; 1276 break; 1277 case SIIS_ERR_INNOCENT: 1278 ccb->ccb_h.status |= CAM_REQUEUE_REQ; 1279 break; 1280 case SIIS_ERR_TFE: 1281 case SIIS_ERR_NCQ: 1282 if (ccb->ccb_h.func_code == XPT_SCSI_IO) { 1283 ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR; 1284 ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND; 1285 } else { 1286 ccb->ccb_h.status |= CAM_ATA_STATUS_ERROR; 1287 } 1288 break; 1289 case SIIS_ERR_SATA: 1290 ch->fatalerr = 1; 1291 ccb->ccb_h.status |= CAM_UNCOR_PARITY; 1292 break; 1293 case SIIS_ERR_TIMEOUT: 1294 ch->fatalerr = 1; 1295 ccb->ccb_h.status |= CAM_CMD_TIMEOUT; 1296 break; 1297 default: 1298 ccb->ccb_h.status |= CAM_REQ_CMP_ERR; 1299 } 1300 /* Free slot. */ 1301 ch->oslots &= ~(1 << slot->slot); 1302 ch->rslots &= ~(1 << slot->slot); 1303 ch->aslots &= ~(1 << slot->slot); 1304 slot->state = SIIS_SLOT_EMPTY; 1305 slot->ccb = NULL; 1306 /* Update channel stats. */ 1307 ch->numrslots--; 1308 if ((ccb->ccb_h.func_code == XPT_ATA_IO) && 1309 (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) { 1310 ch->numtslots[ccb->ccb_h.target_id]--; 1311 } 1312 /* Cancel timeout state if request completed normally. */ 1313 if (et != SIIS_ERR_TIMEOUT) { 1314 lastto = (ch->toslots == (1 << slot->slot)); 1315 ch->toslots &= ~(1 << slot->slot); 1316 if (lastto) 1317 xpt_release_simq(ch->sim, TRUE); 1318 } 1319 /* If it was our READ LOG command - process it. */ 1320 if (ccb->ccb_h.recovery_type == RECOVERY_READ_LOG) { 1321 siis_process_read_log(dev, ccb); 1322 /* If it was our REQUEST SENSE command - process it. */ 1323 } else if (ccb->ccb_h.recovery_type == RECOVERY_REQUEST_SENSE) { 1324 siis_process_request_sense(dev, ccb); 1325 /* If it was NCQ or ATAPI command error, put result on hold. */ 1326 } else if (et == SIIS_ERR_NCQ || 1327 ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR && 1328 (ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)) { 1329 ch->hold[slot->slot] = ccb; 1330 ch->numhslots++; 1331 } else 1332 xpt_done(ccb); 1333 /* Unfreeze frozen command. */ 1334 if (ch->frozen && !siis_check_collision(dev, ch->frozen)) { 1335 union ccb *fccb = ch->frozen; 1336 ch->frozen = NULL; 1337 siis_begin_transaction(dev, fccb); 1338 xpt_release_simq(ch->sim, TRUE); 1339 } 1340 /* If we have no other active commands, ... */ 1341 if (ch->rslots == 0) { 1342 /* if there were timeouts or fatal error - reset port. */ 1343 if (ch->toslots != 0 || ch->fatalerr) { 1344 siis_reset(dev); 1345 } else { 1346 /* if we have slots in error, we can reinit port. */ 1347 if (ch->eslots != 0) 1348 siis_portinit(dev); 1349 /* if there commands on hold, we can do recovery. */ 1350 if (!ch->recoverycmd && ch->numhslots) 1351 siis_issue_recovery(dev); 1352 } 1353 /* If all the reset of commands are in timeout - abort them. */ 1354 } else if ((ch->rslots & ~ch->toslots) == 0 && 1355 et != SIIS_ERR_TIMEOUT) 1356 siis_rearm_timeout(dev); 1357} 1358 1359static void 1360siis_issue_recovery(device_t dev) 1361{ 1362 struct siis_channel *ch = device_get_softc(dev); 1363 union ccb *ccb; 1364 struct ccb_ataio *ataio; 1365 struct ccb_scsiio *csio; 1366 int i; 1367 1368 /* Find some holden command. */ 1369 for (i = 0; i < SIIS_MAX_SLOTS; i++) { 1370 if (ch->hold[i]) 1371 break; 1372 } 1373 if (i == SIIS_MAX_SLOTS) 1374 return; 1375 ch->recoverycmd = 1; 1376 ccb = xpt_alloc_ccb_nowait(); 1377 if (ccb == NULL) { 1378 device_printf(dev, "Unable allocate READ LOG command"); 1379 return; /* XXX */ 1380 } 1381 ccb->ccb_h = ch->hold[i]->ccb_h; /* Reuse old header. */ 1382 if (ccb->ccb_h.func_code == XPT_ATA_IO) { 1383 /* READ LOG */ 1384 ccb->ccb_h.recovery_type = RECOVERY_READ_LOG; 1385 ccb->ccb_h.func_code = XPT_ATA_IO; 1386 ccb->ccb_h.flags = CAM_DIR_IN; 1387 ccb->ccb_h.timeout = 1000; /* 1s should be enough. */ 1388 ataio = &ccb->ataio; 1389 ataio->data_ptr = malloc(512, M_SIIS, M_NOWAIT); 1390 if (ataio->data_ptr == NULL) { 1391 xpt_free_ccb(ccb); 1392 device_printf(dev, "Unable allocate memory for READ LOG command"); 1393 return; /* XXX */ 1394 } 1395 ataio->dxfer_len = 512; 1396 bzero(&ataio->cmd, sizeof(ataio->cmd)); 1397 ataio->cmd.flags = CAM_ATAIO_48BIT; 1398 ataio->cmd.command = 0x2F; /* READ LOG EXT */ 1399 ataio->cmd.sector_count = 1; 1400 ataio->cmd.sector_count_exp = 0; 1401 ataio->cmd.lba_low = 0x10; 1402 ataio->cmd.lba_mid = 0; 1403 ataio->cmd.lba_mid_exp = 0; 1404 } else { 1405 /* REQUEST SENSE */ 1406 ccb->ccb_h.recovery_type = RECOVERY_REQUEST_SENSE; 1407 ccb->ccb_h.recovery_slot = i; 1408 ccb->ccb_h.func_code = XPT_SCSI_IO; 1409 ccb->ccb_h.flags = CAM_DIR_IN; 1410 ccb->ccb_h.status = 0; 1411 ccb->ccb_h.timeout = 1000; /* 1s should be enough. */ 1412 csio = &ccb->csio; 1413 csio->data_ptr = (void *)&ch->hold[i]->csio.sense_data; 1414 csio->dxfer_len = ch->hold[i]->csio.sense_len; 1415 csio->cdb_len = 6; 1416 bzero(&csio->cdb_io, sizeof(csio->cdb_io)); 1417 csio->cdb_io.cdb_bytes[0] = 0x03; 1418 csio->cdb_io.cdb_bytes[4] = csio->dxfer_len; 1419 } 1420 siis_begin_transaction(dev, ccb); 1421} 1422 1423static void 1424siis_process_read_log(device_t dev, union ccb *ccb) 1425{ 1426 struct siis_channel *ch = device_get_softc(dev); 1427 uint8_t *data; 1428 struct ata_res *res; 1429 int i; 1430 1431 ch->recoverycmd = 0; 1432 data = ccb->ataio.data_ptr; 1433 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP && 1434 (data[0] & 0x80) == 0) { 1435 for (i = 0; i < SIIS_MAX_SLOTS; i++) { 1436 if (!ch->hold[i]) 1437 continue; 1438 if (ch->hold[i]->ccb_h.target_id != ccb->ccb_h.target_id) 1439 continue; 1440 if ((data[0] & 0x1F) == i) { 1441 res = &ch->hold[i]->ataio.res; 1442 res->status = data[2]; 1443 res->error = data[3]; 1444 res->lba_low = data[4]; 1445 res->lba_mid = data[5]; 1446 res->lba_high = data[6]; 1447 res->device = data[7]; 1448 res->lba_low_exp = data[8]; 1449 res->lba_mid_exp = data[9]; 1450 res->lba_high_exp = data[10]; 1451 res->sector_count = data[12]; 1452 res->sector_count_exp = data[13]; 1453 } else { 1454 ch->hold[i]->ccb_h.status &= ~CAM_STATUS_MASK; 1455 ch->hold[i]->ccb_h.status |= CAM_REQUEUE_REQ; 1456 } 1457 xpt_done(ch->hold[i]); 1458 ch->hold[i] = NULL; 1459 ch->numhslots--; 1460 } 1461 } else { 1462 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) 1463 device_printf(dev, "Error while READ LOG EXT\n"); 1464 else if ((data[0] & 0x80) == 0) { 1465 device_printf(dev, "Non-queued command error in READ LOG EXT\n"); 1466 } 1467 for (i = 0; i < SIIS_MAX_SLOTS; i++) { 1468 if (!ch->hold[i]) 1469 continue; 1470 if (ch->hold[i]->ccb_h.target_id != ccb->ccb_h.target_id) 1471 continue; 1472 xpt_done(ch->hold[i]); 1473 ch->hold[i] = NULL; 1474 ch->numhslots--; 1475 } 1476 } 1477 free(ccb->ataio.data_ptr, M_SIIS); 1478 xpt_free_ccb(ccb); 1479} 1480 1481static void 1482siis_process_request_sense(device_t dev, union ccb *ccb) 1483{ 1484 struct siis_channel *ch = device_get_softc(dev); 1485 int i; 1486 1487 ch->recoverycmd = 0; 1488 1489 i = ccb->ccb_h.recovery_slot; 1490 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { 1491 ch->hold[i]->ccb_h.status |= CAM_AUTOSNS_VALID; 1492 } else { 1493 ch->hold[i]->ccb_h.status &= ~CAM_STATUS_MASK; 1494 ch->hold[i]->ccb_h.status |= CAM_AUTOSENSE_FAIL; 1495 } 1496 xpt_done(ch->hold[i]); 1497 ch->hold[i] = NULL; 1498 ch->numhslots--; 1499 xpt_free_ccb(ccb); 1500} 1501 1502static void 1503siis_portinit(device_t dev) 1504{ 1505 struct siis_channel *ch = device_get_softc(dev); 1506 int i; 1507 1508 ch->eslots = 0; 1509 ch->recovery = 0; 1510 ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_RESUME); 1511 for (i = 0; i < 16; i++) { 1512 ATA_OUTL(ch->r_mem, SIIS_P_PMPSTS(i), 0), 1513 ATA_OUTL(ch->r_mem, SIIS_P_PMPQACT(i), 0); 1514 } 1515 ATA_OUTL(ch->r_mem, SIIS_P_CTLSET, SIIS_P_CTL_PORT_INIT); 1516 siis_wait_ready(dev, 1000); 1517} 1518 1519static int 1520siis_devreset(device_t dev) 1521{ 1522 struct siis_channel *ch = device_get_softc(dev); 1523 int timeout = 0; 1524 uint32_t val; 1525 1526 ATA_OUTL(ch->r_mem, SIIS_P_CTLSET, SIIS_P_CTL_DEV_RESET); 1527 while (((val = ATA_INL(ch->r_mem, SIIS_P_STS)) & 1528 SIIS_P_CTL_DEV_RESET) != 0) { 1529 DELAY(1000); 1530 if (timeout++ > 100) { 1531 device_printf(dev, "device reset stuck (timeout %dms) " 1532 "status = %08x\n", timeout, val); 1533 return (EBUSY); 1534 } 1535 } 1536 return (0); 1537} 1538 1539static int 1540siis_wait_ready(device_t dev, int t) 1541{ 1542 struct siis_channel *ch = device_get_softc(dev); 1543 int timeout = 0; 1544 uint32_t val; 1545 1546 while (((val = ATA_INL(ch->r_mem, SIIS_P_STS)) & 1547 SIIS_P_CTL_READY) == 0) { 1548 DELAY(1000); 1549 if (timeout++ > t) { 1550 device_printf(dev, "port is not ready (timeout %dms) " 1551 "status = %08x\n", t, val); 1552 return (EBUSY); 1553 } 1554 } 1555 return (0); 1556} 1557 1558static void 1559siis_reset(device_t dev) 1560{ 1561 struct siis_channel *ch = device_get_softc(dev); 1562 int i, retry = 0, sata_rev; 1563 uint32_t val; 1564 1565 xpt_freeze_simq(ch->sim, 1); 1566 if (bootverbose) 1567 device_printf(dev, "SIIS reset...\n"); 1568 if (!ch->recoverycmd && !ch->recovery) 1569 xpt_freeze_simq(ch->sim, ch->numrslots); 1570 /* Requeue frozen command. */ 1571 if (ch->frozen) { 1572 union ccb *fccb = ch->frozen; 1573 ch->frozen = NULL; 1574 fccb->ccb_h.status &= ~CAM_STATUS_MASK; 1575 fccb->ccb_h.status |= CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ; 1576 if (!(fccb->ccb_h.status & CAM_DEV_QFRZN)) { 1577 xpt_freeze_devq(fccb->ccb_h.path, 1); 1578 fccb->ccb_h.status |= CAM_DEV_QFRZN; 1579 } 1580 xpt_done(fccb); 1581 } 1582 /* Requeue all running commands. */ 1583 for (i = 0; i < SIIS_MAX_SLOTS; i++) { 1584 /* Do we have a running request on slot? */ 1585 if (ch->slot[i].state < SIIS_SLOT_RUNNING) 1586 continue; 1587 /* XXX; Commands in loading state. */ 1588 siis_end_transaction(&ch->slot[i], SIIS_ERR_INNOCENT); 1589 } 1590 /* Finish all holden commands as-is. */ 1591 for (i = 0; i < SIIS_MAX_SLOTS; i++) { 1592 if (!ch->hold[i]) 1593 continue; 1594 xpt_done(ch->hold[i]); 1595 ch->hold[i] = NULL; 1596 ch->numhslots--; 1597 } 1598 if (ch->toslots != 0) 1599 xpt_release_simq(ch->sim, TRUE); 1600 ch->eslots = 0; 1601 ch->recovery = 0; 1602 ch->toslots = 0; 1603 ch->fatalerr = 0; 1604 /* Disable port interrupts */ 1605 ATA_OUTL(ch->r_mem, SIIS_P_IECLR, 0x0000FFFF); 1606 /* Set speed limit. */ 1607 sata_rev = ch->user[ch->pm_present ? 15 : 0].revision; 1608 if (sata_rev == 1) 1609 val = ATA_SC_SPD_SPEED_GEN1; 1610 else if (sata_rev == 2) 1611 val = ATA_SC_SPD_SPEED_GEN2; 1612 else if (sata_rev == 3) 1613 val = ATA_SC_SPD_SPEED_GEN3; 1614 else 1615 val = 0; 1616 ATA_OUTL(ch->r_mem, SIIS_P_SCTL, 1617 ATA_SC_DET_IDLE | val | ((ch->pm_level > 0) ? 0 : 1618 (ATA_SC_IPM_DIS_PARTIAL | ATA_SC_IPM_DIS_SLUMBER))); 1619retry: 1620 siis_devreset(dev); 1621 /* Reset and reconnect PHY, */ 1622 if (!siis_sata_connect(ch)) { 1623 ch->devices = 0; 1624 /* Enable port interrupts */ 1625 ATA_OUTL(ch->r_mem, SIIS_P_IESET, SIIS_P_IX_ENABLED); 1626 if (bootverbose) 1627 device_printf(dev, 1628 "SIIS reset done: phy reset found no device\n"); 1629 /* Tell the XPT about the event */ 1630 xpt_async(AC_BUS_RESET, ch->path, NULL); 1631 xpt_release_simq(ch->sim, TRUE); 1632 return; 1633 } 1634 /* Wait for port ready status. */ 1635 if (siis_wait_ready(dev, 1000)) { 1636 device_printf(dev, "port ready timeout\n"); 1637 if (!retry) { 1638 device_printf(dev, "trying full port reset ...\n"); 1639 /* Get port to the reset state. */ 1640 ATA_OUTL(ch->r_mem, SIIS_P_CTLSET, SIIS_P_CTL_PORT_RESET); 1641 DELAY(10000); 1642 /* Get port out of reset state. */ 1643 ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_PORT_RESET); 1644 ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_32BIT); 1645 if (ch->pm_present) 1646 ATA_OUTL(ch->r_mem, SIIS_P_CTLSET, SIIS_P_CTL_PME); 1647 else 1648 ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_PME); 1649 siis_wait_ready(dev, 5000); 1650 retry = 1; 1651 goto retry; 1652 } 1653 } 1654 ch->devices = 1; 1655 /* Enable port interrupts */ 1656 ATA_OUTL(ch->r_mem, SIIS_P_IS, 0xFFFFFFFF); 1657 ATA_OUTL(ch->r_mem, SIIS_P_IESET, SIIS_P_IX_ENABLED); 1658 if (bootverbose) 1659 device_printf(dev, "SIIS reset done: devices=%08x\n", ch->devices); 1660 /* Tell the XPT about the event */ 1661 xpt_async(AC_BUS_RESET, ch->path, NULL); 1662 xpt_release_simq(ch->sim, TRUE); 1663} 1664 1665static int 1666siis_setup_fis(device_t dev, struct siis_cmd *ctp, union ccb *ccb, int tag) 1667{ 1668 struct siis_channel *ch = device_get_softc(dev); 1669 u_int8_t *fis = &ctp->fis[0]; 1670 1671 bzero(fis, 24); 1672 fis[0] = 0x27; /* host to device */ 1673 fis[1] = (ccb->ccb_h.target_id & 0x0f); 1674 if (ccb->ccb_h.func_code == XPT_SCSI_IO) { 1675 fis[1] |= 0x80; 1676 fis[2] = ATA_PACKET_CMD; 1677 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE && 1678 ch->curr[ccb->ccb_h.target_id].mode >= ATA_DMA) 1679 fis[3] = ATA_F_DMA; 1680 else { 1681 fis[5] = ccb->csio.dxfer_len; 1682 fis[6] = ccb->csio.dxfer_len >> 8; 1683 } 1684 fis[7] = ATA_D_LBA; 1685 fis[15] = ATA_A_4BIT; 1686 bzero(ctp->u.atapi.ccb, 16); 1687 bcopy((ccb->ccb_h.flags & CAM_CDB_POINTER) ? 1688 ccb->csio.cdb_io.cdb_ptr : ccb->csio.cdb_io.cdb_bytes, 1689 ctp->u.atapi.ccb, ccb->csio.cdb_len); 1690 } else if ((ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) == 0) { 1691 fis[1] |= 0x80; 1692 fis[2] = ccb->ataio.cmd.command; 1693 fis[3] = ccb->ataio.cmd.features; 1694 fis[4] = ccb->ataio.cmd.lba_low; 1695 fis[5] = ccb->ataio.cmd.lba_mid; 1696 fis[6] = ccb->ataio.cmd.lba_high; 1697 fis[7] = ccb->ataio.cmd.device; 1698 fis[8] = ccb->ataio.cmd.lba_low_exp; 1699 fis[9] = ccb->ataio.cmd.lba_mid_exp; 1700 fis[10] = ccb->ataio.cmd.lba_high_exp; 1701 fis[11] = ccb->ataio.cmd.features_exp; 1702 if (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA) { 1703 fis[12] = tag << 3; 1704 fis[13] = 0; 1705 } else { 1706 fis[12] = ccb->ataio.cmd.sector_count; 1707 fis[13] = ccb->ataio.cmd.sector_count_exp; 1708 } 1709 fis[15] = ATA_A_4BIT; 1710 } else { 1711 /* Soft reset. */ 1712 } 1713 return (20); 1714} 1715 1716static int 1717siis_sata_connect(struct siis_channel *ch) 1718{ 1719 u_int32_t status; 1720 int timeout; 1721 1722 /* Wait up to 100ms for "connect well" */ 1723 for (timeout = 0; timeout < 100 ; timeout++) { 1724 status = ATA_INL(ch->r_mem, SIIS_P_SSTS); 1725 if (((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_ONLINE) && 1726 ((status & ATA_SS_SPD_MASK) != ATA_SS_SPD_NO_SPEED) && 1727 ((status & ATA_SS_IPM_MASK) == ATA_SS_IPM_ACTIVE)) 1728 break; 1729 DELAY(1000); 1730 } 1731 if (timeout >= 100) { 1732 if (bootverbose) { 1733 device_printf(ch->dev, "SATA connect timeout status=%08x\n", 1734 status); 1735 } 1736 return (0); 1737 } 1738 if (bootverbose) { 1739 device_printf(ch->dev, "SATA connect time=%dms status=%08x\n", 1740 timeout, status); 1741 } 1742 /* Clear SATA error register */ 1743 ATA_OUTL(ch->r_mem, SIIS_P_SERR, 0xffffffff); 1744 return (1); 1745} 1746 1747static int 1748siis_check_ids(device_t dev, union ccb *ccb) 1749{ 1750 1751 if (ccb->ccb_h.target_id > 15) { 1752 ccb->ccb_h.status = CAM_TID_INVALID; 1753 xpt_done(ccb); 1754 return (-1); 1755 } 1756 if (ccb->ccb_h.target_lun != 0) { 1757 ccb->ccb_h.status = CAM_LUN_INVALID; 1758 xpt_done(ccb); 1759 return (-1); 1760 } 1761 return (0); 1762} 1763 1764static void 1765siisaction(struct cam_sim *sim, union ccb *ccb) 1766{ 1767 device_t dev, parent; 1768 struct siis_channel *ch; 1769 1770 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("siisaction func_code=%x\n", 1771 ccb->ccb_h.func_code)); 1772 1773 ch = (struct siis_channel *)cam_sim_softc(sim); 1774 dev = ch->dev; 1775 mtx_assert(&ch->mtx, MA_OWNED); 1776 switch (ccb->ccb_h.func_code) { 1777 /* Common cases first */ 1778 case XPT_ATA_IO: /* Execute the requested I/O operation */ 1779 case XPT_SCSI_IO: 1780 if (siis_check_ids(dev, ccb)) 1781 return; 1782 if (ch->devices == 0 || 1783 (ch->pm_present == 0 && 1784 ccb->ccb_h.target_id > 0 && ccb->ccb_h.target_id < 15)) { 1785 ccb->ccb_h.status = CAM_SEL_TIMEOUT; 1786 break; 1787 } 1788 ccb->ccb_h.recovery_type = RECOVERY_NONE; 1789 /* Check for command collision. */ 1790 if (siis_check_collision(dev, ccb)) { 1791 /* Freeze command. */ 1792 ch->frozen = ccb; 1793 /* We have only one frozen slot, so freeze simq also. */ 1794 xpt_freeze_simq(ch->sim, 1); 1795 return; 1796 } 1797 siis_begin_transaction(dev, ccb); 1798 return; 1799 case XPT_EN_LUN: /* Enable LUN as a target */ 1800 case XPT_TARGET_IO: /* Execute target I/O request */ 1801 case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */ 1802 case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/ 1803 case XPT_ABORT: /* Abort the specified CCB */ 1804 /* XXX Implement */ 1805 ccb->ccb_h.status = CAM_REQ_INVALID; 1806 break; 1807 case XPT_SET_TRAN_SETTINGS: 1808 { 1809 struct ccb_trans_settings *cts = &ccb->cts; 1810 struct siis_device *d; 1811 1812 if (siis_check_ids(dev, ccb)) 1813 return; 1814 if (cts->type == CTS_TYPE_CURRENT_SETTINGS) 1815 d = &ch->curr[ccb->ccb_h.target_id]; 1816 else 1817 d = &ch->user[ccb->ccb_h.target_id]; 1818 if (cts->xport_specific.sata.valid & CTS_SATA_VALID_REVISION) 1819 d->revision = cts->xport_specific.sata.revision; 1820 if (cts->xport_specific.sata.valid & CTS_SATA_VALID_MODE) 1821 d->mode = cts->xport_specific.sata.mode; 1822 if (cts->xport_specific.sata.valid & CTS_SATA_VALID_BYTECOUNT) 1823 d->bytecount = min(8192, cts->xport_specific.sata.bytecount); 1824 if (cts->xport_specific.sata.valid & CTS_SATA_VALID_TAGS) 1825 d->tags = min(SIIS_MAX_SLOTS, cts->xport_specific.sata.tags); 1826 if (cts->xport_specific.sata.valid & CTS_SATA_VALID_PM) { 1827 ch->pm_present = cts->xport_specific.sata.pm_present; 1828 if (ch->pm_present) 1829 ATA_OUTL(ch->r_mem, SIIS_P_CTLSET, SIIS_P_CTL_PME); 1830 else 1831 ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_PME); 1832 } 1833 if (cts->xport_specific.sata.valid & CTS_SATA_VALID_TAGS) 1834 d->atapi = cts->xport_specific.sata.atapi; 1835 if (cts->xport_specific.sata.valid & CTS_SATA_VALID_CAPS) 1836 d->caps = cts->xport_specific.sata.caps; 1837 ccb->ccb_h.status = CAM_REQ_CMP; 1838 break; 1839 } 1840 case XPT_GET_TRAN_SETTINGS: 1841 /* Get default/user set transfer settings for the target */ 1842 { 1843 struct ccb_trans_settings *cts = &ccb->cts; 1844 struct siis_device *d; 1845 uint32_t status; 1846 1847 if (siis_check_ids(dev, ccb)) 1848 return; 1849 if (cts->type == CTS_TYPE_CURRENT_SETTINGS) 1850 d = &ch->curr[ccb->ccb_h.target_id]; 1851 else 1852 d = &ch->user[ccb->ccb_h.target_id]; 1853 cts->protocol = PROTO_ATA; 1854 cts->protocol_version = PROTO_VERSION_UNSPECIFIED; 1855 cts->transport = XPORT_SATA; 1856 cts->transport_version = XPORT_VERSION_UNSPECIFIED; 1857 cts->proto_specific.valid = 0; 1858 cts->xport_specific.sata.valid = 0; 1859 if (cts->type == CTS_TYPE_CURRENT_SETTINGS && 1860 (ccb->ccb_h.target_id == 15 || 1861 (ccb->ccb_h.target_id == 0 && !ch->pm_present))) { 1862 status = ATA_INL(ch->r_mem, SIIS_P_SSTS) & ATA_SS_SPD_MASK; 1863 if (status & 0x0f0) { 1864 cts->xport_specific.sata.revision = 1865 (status & 0x0f0) >> 4; 1866 cts->xport_specific.sata.valid |= 1867 CTS_SATA_VALID_REVISION; 1868 } 1869 cts->xport_specific.sata.caps = d->caps & CTS_SATA_CAPS_D; 1870 if (ch->pm_level) 1871 cts->xport_specific.sata.caps |= CTS_SATA_CAPS_H_PMREQ; 1872 cts->xport_specific.sata.caps &= 1873 ch->user[ccb->ccb_h.target_id].caps; 1874 cts->xport_specific.sata.valid |= CTS_SATA_VALID_CAPS; 1875 } else { 1876 cts->xport_specific.sata.revision = d->revision; 1877 cts->xport_specific.sata.valid |= CTS_SATA_VALID_REVISION; 1878 cts->xport_specific.sata.caps = d->caps; 1879 cts->xport_specific.sata.valid |= CTS_SATA_VALID_CAPS; 1880 } 1881 cts->xport_specific.sata.mode = d->mode; 1882 cts->xport_specific.sata.valid |= CTS_SATA_VALID_MODE; 1883 cts->xport_specific.sata.bytecount = d->bytecount; 1884 cts->xport_specific.sata.valid |= CTS_SATA_VALID_BYTECOUNT; 1885 cts->xport_specific.sata.pm_present = ch->pm_present; 1886 cts->xport_specific.sata.valid |= CTS_SATA_VALID_PM; 1887 cts->xport_specific.sata.tags = d->tags; 1888 cts->xport_specific.sata.valid |= CTS_SATA_VALID_TAGS; 1889 cts->xport_specific.sata.atapi = d->atapi; 1890 cts->xport_specific.sata.valid |= CTS_SATA_VALID_ATAPI; 1891 ccb->ccb_h.status = CAM_REQ_CMP; 1892 break; 1893 } 1894 case XPT_RESET_BUS: /* Reset the specified SCSI bus */ 1895 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */ 1896 siis_reset(dev); 1897 ccb->ccb_h.status = CAM_REQ_CMP; 1898 break; 1899 case XPT_TERM_IO: /* Terminate the I/O process */ 1900 /* XXX Implement */ 1901 ccb->ccb_h.status = CAM_REQ_INVALID; 1902 break; 1903 case XPT_PATH_INQ: /* Path routing inquiry */ 1904 { 1905 struct ccb_pathinq *cpi = &ccb->cpi; 1906 1907 parent = device_get_parent(dev); 1908 cpi->version_num = 1; /* XXX??? */ 1909 cpi->hba_inquiry = PI_SDTR_ABLE | PI_TAG_ABLE; 1910 cpi->hba_inquiry |= PI_SATAPM; 1911 cpi->target_sprt = 0; 1912 cpi->hba_misc = PIM_SEQSCAN; 1913 cpi->hba_eng_cnt = 0; 1914 cpi->max_target = 15; 1915 cpi->max_lun = 0; 1916 cpi->initiator_id = 0; 1917 cpi->bus_id = cam_sim_bus(sim); 1918 cpi->base_transfer_speed = 150000; 1919 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 1920 strncpy(cpi->hba_vid, "SIIS", HBA_IDLEN); 1921 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 1922 cpi->unit_number = cam_sim_unit(sim); 1923 cpi->transport = XPORT_SATA; 1924 cpi->transport_version = XPORT_VERSION_UNSPECIFIED; 1925 cpi->protocol = PROTO_ATA; 1926 cpi->protocol_version = PROTO_VERSION_UNSPECIFIED; 1927 cpi->maxio = MAXPHYS; 1928 cpi->hba_vendor = pci_get_vendor(parent); 1929 cpi->hba_device = pci_get_device(parent); 1930 cpi->hba_subvendor = pci_get_subvendor(parent); 1931 cpi->hba_subdevice = pci_get_subdevice(parent); 1932 cpi->ccb_h.status = CAM_REQ_CMP; 1933 break; 1934 } 1935 default: 1936 ccb->ccb_h.status = CAM_REQ_INVALID; 1937 break; 1938 } 1939 xpt_done(ccb); 1940} 1941 1942static void 1943siispoll(struct cam_sim *sim) 1944{ 1945 struct siis_channel *ch = (struct siis_channel *)cam_sim_softc(sim); 1946 1947 siis_ch_intr(ch->dev); 1948} 1949