1 /*- 2 * Bus independent FreeBSD shim for the aic7xxx based Adaptec SCSI controllers 3 * 4 * Copyright (c) 1994-2001 Justin T. Gibbs. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions, and the following disclaimer, 12 * without modification. 13 * 2. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * Alternatively, this software may be distributed under the terms of the 17 * GNU Public License ("GPL"). 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 * 31 * $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.c#20 $ 32 */ 33 34 #include <dev/aic7xxx/aic7xxx_osm.h> 35 #include <dev/aic7xxx/aic7xxx_inline.h> 36 37 #include <sys/kthread.h> 38 39 #ifndef AHC_TMODE_ENABLE 40 #define AHC_TMODE_ENABLE 0 41 #endif 42 43 #include <dev/aic7xxx/aic_osm_lib.c> 44 45 #define ccb_scb_ptr spriv_ptr0 46 47 #if 0 48 static void ahc_dump_targcmd(struct target_cmd *cmd); 49 #endif 50 static int ahc_modevent(module_t mod, int type, void *data); 51 static void ahc_action(struct cam_sim *sim, union ccb *ccb); 52 static void ahc_get_tran_settings(struct ahc_softc *ahc, 53 int our_id, char channel, 54 struct ccb_trans_settings *cts); 55 static void ahc_async(void *callback_arg, uint32_t code, 56 struct cam_path *path, void *arg); 57 static void ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, 58 int nsegments, int error); 59 static void ahc_poll(struct cam_sim *sim); 60 static void ahc_setup_data(struct ahc_softc *ahc, struct cam_sim *sim, 61 struct ccb_scsiio *csio, struct scb *scb); 62 static void ahc_abort_ccb(struct ahc_softc *ahc, struct cam_sim *sim, 63 union ccb *ccb); 64 static int ahc_create_path(struct ahc_softc *ahc, 65 char channel, u_int target, u_int lun, 66 struct cam_path **path); 67 68 static int 69 ahc_create_path(struct ahc_softc *ahc, char channel, u_int target, 70 u_int lun, struct cam_path **path) 71 { 72 path_id_t path_id; 73 74 if (channel == 'B') 75 path_id = cam_sim_path(ahc->platform_data->sim_b); 76 else 77 path_id = cam_sim_path(ahc->platform_data->sim); 78 79 return (xpt_create_path(path, /*periph*/NULL, 80 path_id, target, lun)); 81 } 82 83 int 84 ahc_map_int(struct ahc_softc *ahc) 85 { 86 int error; 87 int zero; 88 int shareable; 89 90 zero = 0; 91 shareable = (ahc->flags & AHC_EDGE_INTERRUPT) ? 0: RF_SHAREABLE; 92 ahc->platform_data->irq = 93 bus_alloc_resource_any(ahc->dev_softc, SYS_RES_IRQ, &zero, 94 RF_ACTIVE | shareable); 95 if (ahc->platform_data->irq == NULL) { 96 device_printf(ahc->dev_softc, 97 "bus_alloc_resource() failed to allocate IRQ\n"); 98 return (ENOMEM); 99 } 100 ahc->platform_data->irq_res_type = SYS_RES_IRQ; 101 102 /* Hook up our interrupt handler */ 103 error = bus_setup_intr(ahc->dev_softc, ahc->platform_data->irq, 104 INTR_TYPE_CAM|INTR_MPSAFE, NULL, 105 ahc_platform_intr, ahc, &ahc->platform_data->ih); 106 107 if (error != 0) 108 device_printf(ahc->dev_softc, "bus_setup_intr() failed: %d\n", 109 error); 110 return (error); 111 } 112 113 int 114 aic7770_map_registers(struct ahc_softc *ahc, u_int unused_ioport_arg) 115 { 116 struct resource *regs; 117 int rid; 118 119 rid = 0; 120 regs = bus_alloc_resource_any(ahc->dev_softc, SYS_RES_IOPORT, &rid, 121 RF_ACTIVE); 122 if (regs == NULL) { 123 device_printf(ahc->dev_softc, "Unable to map I/O space?!\n"); 124 return ENOMEM; 125 } 126 ahc->platform_data->regs_res_type = SYS_RES_IOPORT; 127 ahc->platform_data->regs_res_id = rid; 128 ahc->platform_data->regs = regs; 129 ahc->tag = rman_get_bustag(regs); 130 ahc->bsh = rman_get_bushandle(regs); 131 return (0); 132 } 133 134 /* 135 * Attach all the sub-devices we can find 136 */ 137 int 138 ahc_attach(struct ahc_softc *ahc) 139 { 140 char ahc_info[256]; 141 struct ccb_setasync csa; 142 struct cam_devq *devq; 143 int bus_id; 144 int bus_id2; 145 struct cam_sim *sim; 146 struct cam_sim *sim2; 147 struct cam_path *path; 148 struct cam_path *path2; 149 int count; 150 151 count = 0; 152 sim = NULL; 153 sim2 = NULL; 154 path = NULL; 155 path2 = NULL; 156 157 /* 158 * Create a thread to perform all recovery. 159 */ 160 if (ahc_spawn_recovery_thread(ahc) != 0) 161 goto fail; 162 163 ahc_controller_info(ahc, ahc_info); 164 printf("%s\n", ahc_info); 165 ahc_lock(ahc); 166 167 /* 168 * Attach secondary channel first if the user has 169 * declared it the primary channel. 170 */ 171 if ((ahc->features & AHC_TWIN) != 0 172 && (ahc->flags & AHC_PRIMARY_CHANNEL) != 0) { 173 bus_id = 1; 174 bus_id2 = 0; 175 } else { 176 bus_id = 0; 177 bus_id2 = 1; 178 } 179 180 /* 181 * Create the device queue for our SIM(s). 182 */ 183 devq = cam_simq_alloc(AHC_MAX_QUEUE); 184 if (devq == NULL) 185 goto fail; 186 187 /* 188 * Construct our first channel SIM entry 189 */ 190 sim = cam_sim_alloc(ahc_action, ahc_poll, "ahc", ahc, 191 device_get_unit(ahc->dev_softc), 192 &ahc->platform_data->mtx, 1, AHC_MAX_QUEUE, devq); 193 if (sim == NULL) { 194 cam_simq_free(devq); 195 goto fail; 196 } 197 198 if (xpt_bus_register(sim, ahc->dev_softc, bus_id) != CAM_SUCCESS) { 199 cam_sim_free(sim, /*free_devq*/TRUE); 200 sim = NULL; 201 goto fail; 202 } 203 204 if (xpt_create_path(&path, /*periph*/NULL, 205 cam_sim_path(sim), CAM_TARGET_WILDCARD, 206 CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 207 xpt_bus_deregister(cam_sim_path(sim)); 208 cam_sim_free(sim, /*free_devq*/TRUE); 209 sim = NULL; 210 goto fail; 211 } 212 213 memset(&csa, 0, sizeof(csa)); 214 xpt_setup_ccb(&csa.ccb_h, path, /*priority*/5); 215 csa.ccb_h.func_code = XPT_SASYNC_CB; 216 csa.event_enable = AC_LOST_DEVICE; 217 csa.callback = ahc_async; 218 csa.callback_arg = sim; 219 xpt_action((union ccb *)&csa); 220 count++; 221 222 if (ahc->features & AHC_TWIN) { 223 sim2 = cam_sim_alloc(ahc_action, ahc_poll, "ahc", 224 ahc, device_get_unit(ahc->dev_softc), 225 &ahc->platform_data->mtx, 1, 226 AHC_MAX_QUEUE, devq); 227 228 if (sim2 == NULL) { 229 printf("ahc_attach: Unable to attach second " 230 "bus due to resource shortage"); 231 goto fail; 232 } 233 234 if (xpt_bus_register(sim2, ahc->dev_softc, bus_id2) != 235 CAM_SUCCESS) { 236 printf("ahc_attach: Unable to attach second " 237 "bus due to resource shortage"); 238 /* 239 * We do not want to destroy the device queue 240 * because the first bus is using it. 241 */ 242 cam_sim_free(sim2, /*free_devq*/FALSE); 243 goto fail; 244 } 245 246 if (xpt_create_path(&path2, /*periph*/NULL, 247 cam_sim_path(sim2), 248 CAM_TARGET_WILDCARD, 249 CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 250 xpt_bus_deregister(cam_sim_path(sim2)); 251 cam_sim_free(sim2, /*free_devq*/FALSE); 252 sim2 = NULL; 253 goto fail; 254 } 255 xpt_setup_ccb(&csa.ccb_h, path2, /*priority*/5); 256 csa.ccb_h.func_code = XPT_SASYNC_CB; 257 csa.event_enable = AC_LOST_DEVICE; 258 csa.callback = ahc_async; 259 csa.callback_arg = sim2; 260 xpt_action((union ccb *)&csa); 261 count++; 262 } 263 264 fail: 265 if ((ahc->features & AHC_TWIN) != 0 266 && (ahc->flags & AHC_PRIMARY_CHANNEL) != 0) { 267 ahc->platform_data->sim_b = sim; 268 ahc->platform_data->path_b = path; 269 ahc->platform_data->sim = sim2; 270 ahc->platform_data->path = path2; 271 } else { 272 ahc->platform_data->sim = sim; 273 ahc->platform_data->path = path; 274 ahc->platform_data->sim_b = sim2; 275 ahc->platform_data->path_b = path2; 276 } 277 ahc_unlock(ahc); 278 279 if (count != 0) { 280 /* We have to wait until after any system dumps... */ 281 ahc->platform_data->eh = 282 EVENTHANDLER_REGISTER(shutdown_final, ahc_shutdown, 283 ahc, SHUTDOWN_PRI_DEFAULT); 284 ahc_intr_enable(ahc, TRUE); 285 } 286 287 return (count); 288 } 289 290 /* 291 * Catch an interrupt from the adapter 292 */ 293 void 294 ahc_platform_intr(void *arg) 295 { 296 struct ahc_softc *ahc; 297 298 ahc = (struct ahc_softc *)arg; 299 ahc_lock(ahc); 300 ahc_intr(ahc); 301 ahc_unlock(ahc); 302 } 303 304 static void 305 ahc_sync_ccb(struct ahc_softc *ahc, struct scb *scb, union ccb *ccb, bool post) 306 { 307 bus_dmasync_op_t op; 308 uint32_t rdmask; 309 310 if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) 311 rdmask = CAM_DIR_OUT; 312 else 313 rdmask = CAM_DIR_IN; 314 315 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == rdmask) 316 op = post ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_PREREAD; 317 else 318 op = post ? BUS_DMASYNC_POSTWRITE : BUS_DMASYNC_PREWRITE; 319 320 bus_dmamap_sync(ahc->buffer_dmat, scb->dmamap, op); 321 } 322 323 /* 324 * We have an scb which has been processed by the 325 * adaptor, now we look to see how the operation 326 * went. 327 */ 328 void 329 ahc_done(struct ahc_softc *ahc, struct scb *scb) 330 { 331 union ccb *ccb; 332 333 CAM_DEBUG(scb->io_ctx->ccb_h.path, CAM_DEBUG_TRACE, 334 ("ahc_done - scb %d\n", scb->hscb->tag)); 335 336 ccb = scb->io_ctx; 337 LIST_REMOVE(scb, pending_links); 338 if ((scb->flags & SCB_TIMEDOUT) != 0) 339 LIST_REMOVE(scb, timedout_links); 340 if ((scb->flags & SCB_UNTAGGEDQ) != 0) { 341 struct scb_tailq *untagged_q; 342 int target_offset; 343 344 target_offset = SCB_GET_TARGET_OFFSET(ahc, scb); 345 untagged_q = &ahc->untagged_queues[target_offset]; 346 TAILQ_REMOVE(untagged_q, scb, links.tqe); 347 scb->flags &= ~SCB_UNTAGGEDQ; 348 ahc_run_untagged_queue(ahc, untagged_q); 349 } 350 351 callout_stop(&scb->io_timer); 352 353 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 354 ahc_sync_ccb(ahc, scb, ccb, true); 355 bus_dmamap_unload(ahc->buffer_dmat, scb->dmamap); 356 } 357 358 if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) { 359 struct cam_path *ccb_path; 360 361 /* 362 * If we have finally disconnected, clean up our 363 * pending device state. 364 * XXX - There may be error states that cause where 365 * we will remain connected. 366 */ 367 ccb_path = ccb->ccb_h.path; 368 if (ahc->pending_device != NULL 369 && xpt_path_comp(ahc->pending_device->path, ccb_path) == 0) { 370 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) { 371 ahc->pending_device = NULL; 372 } else { 373 if (bootverbose) { 374 xpt_print_path(ccb->ccb_h.path); 375 printf("Still connected\n"); 376 } 377 aic_freeze_ccb(ccb); 378 } 379 } 380 381 if (aic_get_transaction_status(scb) == CAM_REQ_INPROG) 382 ccb->ccb_h.status |= CAM_REQ_CMP; 383 ccb->ccb_h.status &= ~CAM_SIM_QUEUED; 384 ahc_free_scb(ahc, scb); 385 xpt_done(ccb); 386 return; 387 } 388 389 /* 390 * If the recovery SCB completes, we have to be 391 * out of our timeout. 392 */ 393 if ((scb->flags & SCB_RECOVERY_SCB) != 0) { 394 struct scb *list_scb; 395 396 ahc->scb_data->recovery_scbs--; 397 398 if (aic_get_transaction_status(scb) == CAM_BDR_SENT 399 || aic_get_transaction_status(scb) == CAM_REQ_ABORTED) 400 aic_set_transaction_status(scb, CAM_CMD_TIMEOUT); 401 402 if (ahc->scb_data->recovery_scbs == 0) { 403 /* 404 * All recovery actions have completed successfully, 405 * so reinstate the timeouts for all other pending 406 * commands. 407 */ 408 LIST_FOREACH(list_scb, &ahc->pending_scbs, 409 pending_links) { 410 aic_scb_timer_reset(list_scb, 411 aic_get_timeout(scb)); 412 } 413 414 ahc_print_path(ahc, scb); 415 printf("no longer in timeout, status = %x\n", 416 ccb->ccb_h.status); 417 } 418 } 419 420 /* Don't clobber any existing error state */ 421 if (aic_get_transaction_status(scb) == CAM_REQ_INPROG) { 422 ccb->ccb_h.status |= CAM_REQ_CMP; 423 } else if ((scb->flags & SCB_SENSE) != 0) { 424 /* 425 * We performed autosense retrieval. 426 * 427 * Zero any sense not transferred by the 428 * device. The SCSI spec mandates that any 429 * untransfered data should be assumed to be 430 * zero. Complete the 'bounce' of sense information 431 * through buffers accessible via bus-space by 432 * copying it into the clients csio. 433 */ 434 memset(&ccb->csio.sense_data, 0, sizeof(ccb->csio.sense_data)); 435 memcpy(&ccb->csio.sense_data, 436 ahc_get_sense_buf(ahc, scb), 437 (aic_le32toh(scb->sg_list->len) & AHC_SG_LEN_MASK) 438 - ccb->csio.sense_resid); 439 scb->io_ctx->ccb_h.status |= CAM_AUTOSNS_VALID; 440 } 441 ccb->ccb_h.status &= ~CAM_SIM_QUEUED; 442 ahc_free_scb(ahc, scb); 443 xpt_done(ccb); 444 } 445 446 static void 447 ahc_action(struct cam_sim *sim, union ccb *ccb) 448 { 449 struct ahc_softc *ahc; 450 struct ahc_tmode_lstate *lstate; 451 u_int target_id; 452 u_int our_id; 453 454 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("ahc_action\n")); 455 456 ahc = (struct ahc_softc *)cam_sim_softc(sim); 457 458 target_id = ccb->ccb_h.target_id; 459 our_id = SIM_SCSI_ID(ahc, sim); 460 461 switch (ccb->ccb_h.func_code) { 462 /* Common cases first */ 463 case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */ 464 case XPT_CONT_TARGET_IO:/* Continue Host Target I/O Connection*/ 465 { 466 struct ahc_tmode_tstate *tstate; 467 cam_status status; 468 469 status = ahc_find_tmode_devs(ahc, sim, ccb, &tstate, 470 &lstate, TRUE); 471 472 if (status != CAM_REQ_CMP) { 473 if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) { 474 /* Response from the black hole device */ 475 tstate = NULL; 476 lstate = ahc->black_hole; 477 } else { 478 ccb->ccb_h.status = status; 479 xpt_done(ccb); 480 break; 481 } 482 } 483 if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) { 484 SLIST_INSERT_HEAD(&lstate->accept_tios, &ccb->ccb_h, 485 sim_links.sle); 486 ccb->ccb_h.status = CAM_REQ_INPROG; 487 if ((ahc->flags & AHC_TQINFIFO_BLOCKED) != 0) 488 ahc_run_tqinfifo(ahc, /*paused*/FALSE); 489 break; 490 } 491 492 /* 493 * The target_id represents the target we attempt to 494 * select. In target mode, this is the initiator of 495 * the original command. 496 */ 497 our_id = target_id; 498 target_id = ccb->csio.init_id; 499 /* FALLTHROUGH */ 500 } 501 case XPT_SCSI_IO: /* Execute the requested I/O operation */ 502 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */ 503 { 504 struct scb *scb; 505 struct hardware_scb *hscb; 506 507 if ((ahc->flags & AHC_INITIATORROLE) == 0 508 && (ccb->ccb_h.func_code == XPT_SCSI_IO 509 || ccb->ccb_h.func_code == XPT_RESET_DEV)) { 510 ccb->ccb_h.status = CAM_PROVIDE_FAIL; 511 xpt_done(ccb); 512 return; 513 } 514 515 /* 516 * get an scb to use. 517 */ 518 if ((scb = ahc_get_scb(ahc)) == NULL) { 519 xpt_freeze_simq(sim, /*count*/1); 520 ahc->flags |= AHC_RESOURCE_SHORTAGE; 521 ccb->ccb_h.status = CAM_REQUEUE_REQ; 522 xpt_done(ccb); 523 return; 524 } 525 526 hscb = scb->hscb; 527 528 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_SUBTRACE, 529 ("start scb(%p)\n", scb)); 530 scb->io_ctx = ccb; 531 /* 532 * So we can find the SCB when an abort is requested 533 */ 534 ccb->ccb_h.ccb_scb_ptr = scb; 535 536 /* 537 * Put all the arguments for the xfer in the scb 538 */ 539 hscb->control = 0; 540 hscb->scsiid = BUILD_SCSIID(ahc, sim, target_id, our_id); 541 hscb->lun = ccb->ccb_h.target_lun; 542 if (ccb->ccb_h.func_code == XPT_RESET_DEV) { 543 hscb->cdb_len = 0; 544 scb->flags |= SCB_DEVICE_RESET; 545 hscb->control |= MK_MESSAGE; 546 ahc_execute_scb(scb, NULL, 0, 0); 547 } else { 548 if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) { 549 struct target_data *tdata; 550 551 tdata = &hscb->shared_data.tdata; 552 if (ahc->pending_device == lstate) 553 scb->flags |= SCB_TARGET_IMMEDIATE; 554 hscb->control |= TARGET_SCB; 555 scb->flags |= SCB_TARGET_SCB; 556 tdata->target_phases = 0; 557 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) { 558 tdata->target_phases |= SPHASE_PENDING; 559 tdata->scsi_status = 560 ccb->csio.scsi_status; 561 } 562 if (ccb->ccb_h.flags & CAM_DIS_DISCONNECT) 563 tdata->target_phases |= NO_DISCONNECT; 564 565 tdata->initiator_tag = ccb->csio.tag_id; 566 } 567 if (ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) 568 hscb->control |= ccb->csio.tag_action; 569 570 ahc_setup_data(ahc, sim, &ccb->csio, scb); 571 } 572 break; 573 } 574 case XPT_NOTIFY_ACKNOWLEDGE: 575 case XPT_IMMEDIATE_NOTIFY: 576 { 577 struct ahc_tmode_tstate *tstate; 578 struct ahc_tmode_lstate *lstate; 579 cam_status status; 580 581 status = ahc_find_tmode_devs(ahc, sim, ccb, &tstate, 582 &lstate, TRUE); 583 584 if (status != CAM_REQ_CMP) { 585 ccb->ccb_h.status = status; 586 xpt_done(ccb); 587 break; 588 } 589 SLIST_INSERT_HEAD(&lstate->immed_notifies, &ccb->ccb_h, 590 sim_links.sle); 591 ccb->ccb_h.status = CAM_REQ_INPROG; 592 ahc_send_lstate_events(ahc, lstate); 593 break; 594 } 595 case XPT_EN_LUN: /* Enable LUN as a target */ 596 ahc_handle_en_lun(ahc, sim, ccb); 597 xpt_done(ccb); 598 break; 599 case XPT_ABORT: /* Abort the specified CCB */ 600 { 601 ahc_abort_ccb(ahc, sim, ccb); 602 break; 603 } 604 case XPT_SET_TRAN_SETTINGS: 605 { 606 struct ahc_devinfo devinfo; 607 struct ccb_trans_settings *cts; 608 struct ccb_trans_settings_scsi *scsi; 609 struct ccb_trans_settings_spi *spi; 610 struct ahc_initiator_tinfo *tinfo; 611 struct ahc_tmode_tstate *tstate; 612 uint16_t *discenable; 613 uint16_t *tagenable; 614 u_int update_type; 615 616 cts = &ccb->cts; 617 scsi = &cts->proto_specific.scsi; 618 spi = &cts->xport_specific.spi; 619 ahc_compile_devinfo(&devinfo, SIM_SCSI_ID(ahc, sim), 620 cts->ccb_h.target_id, 621 cts->ccb_h.target_lun, 622 SIM_CHANNEL(ahc, sim), 623 ROLE_UNKNOWN); 624 tinfo = ahc_fetch_transinfo(ahc, devinfo.channel, 625 devinfo.our_scsiid, 626 devinfo.target, &tstate); 627 update_type = 0; 628 if (cts->type == CTS_TYPE_CURRENT_SETTINGS) { 629 update_type |= AHC_TRANS_GOAL; 630 discenable = &tstate->discenable; 631 tagenable = &tstate->tagenable; 632 tinfo->curr.protocol_version = 633 cts->protocol_version; 634 tinfo->curr.transport_version = 635 cts->transport_version; 636 tinfo->goal.protocol_version = 637 cts->protocol_version; 638 tinfo->goal.transport_version = 639 cts->transport_version; 640 } else if (cts->type == CTS_TYPE_USER_SETTINGS) { 641 update_type |= AHC_TRANS_USER; 642 discenable = &ahc->user_discenable; 643 tagenable = &ahc->user_tagenable; 644 tinfo->user.protocol_version = 645 cts->protocol_version; 646 tinfo->user.transport_version = 647 cts->transport_version; 648 } else { 649 ccb->ccb_h.status = CAM_REQ_INVALID; 650 xpt_done(ccb); 651 break; 652 } 653 654 if ((spi->valid & CTS_SPI_VALID_DISC) != 0) { 655 if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0) 656 *discenable |= devinfo.target_mask; 657 else 658 *discenable &= ~devinfo.target_mask; 659 } 660 661 if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) { 662 if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) 663 *tagenable |= devinfo.target_mask; 664 else 665 *tagenable &= ~devinfo.target_mask; 666 } 667 668 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) { 669 ahc_validate_width(ahc, /*tinfo limit*/NULL, 670 &spi->bus_width, ROLE_UNKNOWN); 671 ahc_set_width(ahc, &devinfo, spi->bus_width, 672 update_type, /*paused*/FALSE); 673 } 674 675 if ((spi->valid & CTS_SPI_VALID_PPR_OPTIONS) == 0) { 676 if (update_type == AHC_TRANS_USER) 677 spi->ppr_options = tinfo->user.ppr_options; 678 else 679 spi->ppr_options = tinfo->goal.ppr_options; 680 } 681 682 if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) == 0) { 683 if (update_type == AHC_TRANS_USER) 684 spi->sync_offset = tinfo->user.offset; 685 else 686 spi->sync_offset = tinfo->goal.offset; 687 } 688 689 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) == 0) { 690 if (update_type == AHC_TRANS_USER) 691 spi->sync_period = tinfo->user.period; 692 else 693 spi->sync_period = tinfo->goal.period; 694 } 695 696 if (((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) 697 || ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)) { 698 struct ahc_syncrate *syncrate; 699 u_int maxsync; 700 701 if ((ahc->features & AHC_ULTRA2) != 0) 702 maxsync = AHC_SYNCRATE_DT; 703 else if ((ahc->features & AHC_ULTRA) != 0) 704 maxsync = AHC_SYNCRATE_ULTRA; 705 else 706 maxsync = AHC_SYNCRATE_FAST; 707 708 if (spi->bus_width != MSG_EXT_WDTR_BUS_16_BIT) 709 spi->ppr_options &= ~MSG_EXT_PPR_DT_REQ; 710 711 syncrate = ahc_find_syncrate(ahc, &spi->sync_period, 712 &spi->ppr_options, 713 maxsync); 714 ahc_validate_offset(ahc, /*tinfo limit*/NULL, 715 syncrate, &spi->sync_offset, 716 spi->bus_width, ROLE_UNKNOWN); 717 718 /* We use a period of 0 to represent async */ 719 if (spi->sync_offset == 0) { 720 spi->sync_period = 0; 721 spi->ppr_options = 0; 722 } 723 724 ahc_set_syncrate(ahc, &devinfo, syncrate, 725 spi->sync_period, spi->sync_offset, 726 spi->ppr_options, update_type, 727 /*paused*/FALSE); 728 } 729 ccb->ccb_h.status = CAM_REQ_CMP; 730 xpt_done(ccb); 731 break; 732 } 733 case XPT_GET_TRAN_SETTINGS: 734 /* Get default/user set transfer settings for the target */ 735 { 736 ahc_get_tran_settings(ahc, SIM_SCSI_ID(ahc, sim), 737 SIM_CHANNEL(ahc, sim), &ccb->cts); 738 xpt_done(ccb); 739 break; 740 } 741 case XPT_CALC_GEOMETRY: 742 { 743 int extended; 744 745 extended = SIM_IS_SCSIBUS_B(ahc, sim) 746 ? ahc->flags & AHC_EXTENDED_TRANS_B 747 : ahc->flags & AHC_EXTENDED_TRANS_A; 748 aic_calc_geometry(&ccb->ccg, extended); 749 xpt_done(ccb); 750 break; 751 } 752 case XPT_RESET_BUS: /* Reset the specified SCSI bus */ 753 { 754 int found; 755 756 found = ahc_reset_channel(ahc, SIM_CHANNEL(ahc, sim), 757 /*initiate reset*/TRUE); 758 if (bootverbose) { 759 xpt_print_path(SIM_PATH(ahc, sim)); 760 printf("SCSI bus reset delivered. " 761 "%d SCBs aborted.\n", found); 762 } 763 ccb->ccb_h.status = CAM_REQ_CMP; 764 xpt_done(ccb); 765 break; 766 } 767 case XPT_TERM_IO: /* Terminate the I/O process */ 768 /* XXX Implement */ 769 ccb->ccb_h.status = CAM_REQ_INVALID; 770 xpt_done(ccb); 771 break; 772 case XPT_PATH_INQ: /* Path routing inquiry */ 773 { 774 struct ccb_pathinq *cpi = &ccb->cpi; 775 776 cpi->version_num = 1; /* XXX??? */ 777 cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE; 778 if ((ahc->features & AHC_WIDE) != 0) 779 cpi->hba_inquiry |= PI_WIDE_16; 780 if ((ahc->features & AHC_TARGETMODE) != 0) { 781 cpi->target_sprt = PIT_PROCESSOR 782 | PIT_DISCONNECT 783 | PIT_TERM_IO; 784 } else { 785 cpi->target_sprt = 0; 786 } 787 cpi->hba_misc = 0; 788 cpi->hba_eng_cnt = 0; 789 cpi->max_target = (ahc->features & AHC_WIDE) ? 15 : 7; 790 cpi->max_lun = AHC_NUM_LUNS - 1; 791 if (SIM_IS_SCSIBUS_B(ahc, sim)) { 792 cpi->initiator_id = ahc->our_id_b; 793 if ((ahc->flags & AHC_RESET_BUS_B) == 0) 794 cpi->hba_misc |= PIM_NOBUSRESET; 795 } else { 796 cpi->initiator_id = ahc->our_id; 797 if ((ahc->flags & AHC_RESET_BUS_A) == 0) 798 cpi->hba_misc |= PIM_NOBUSRESET; 799 } 800 cpi->bus_id = cam_sim_bus(sim); 801 cpi->base_transfer_speed = 3300; 802 strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 803 strlcpy(cpi->hba_vid, "Adaptec", HBA_IDLEN); 804 strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 805 cpi->unit_number = cam_sim_unit(sim); 806 cpi->protocol = PROTO_SCSI; 807 cpi->protocol_version = SCSI_REV_2; 808 cpi->transport = XPORT_SPI; 809 cpi->transport_version = 2; 810 cpi->xport_specific.spi.ppr_options = SID_SPI_CLOCK_ST; 811 if ((ahc->features & AHC_DT) != 0) { 812 cpi->transport_version = 3; 813 cpi->xport_specific.spi.ppr_options = 814 SID_SPI_CLOCK_DT_ST; 815 } 816 cpi->ccb_h.status = CAM_REQ_CMP; 817 xpt_done(ccb); 818 break; 819 } 820 default: 821 ccb->ccb_h.status = CAM_PROVIDE_FAIL; 822 xpt_done(ccb); 823 break; 824 } 825 } 826 827 static void 828 ahc_get_tran_settings(struct ahc_softc *ahc, int our_id, char channel, 829 struct ccb_trans_settings *cts) 830 { 831 struct ahc_devinfo devinfo; 832 struct ccb_trans_settings_scsi *scsi; 833 struct ccb_trans_settings_spi *spi; 834 struct ahc_initiator_tinfo *targ_info; 835 struct ahc_tmode_tstate *tstate; 836 struct ahc_transinfo *tinfo; 837 838 scsi = &cts->proto_specific.scsi; 839 spi = &cts->xport_specific.spi; 840 ahc_compile_devinfo(&devinfo, our_id, 841 cts->ccb_h.target_id, 842 cts->ccb_h.target_lun, 843 channel, ROLE_UNKNOWN); 844 targ_info = ahc_fetch_transinfo(ahc, devinfo.channel, 845 devinfo.our_scsiid, 846 devinfo.target, &tstate); 847 848 if (cts->type == CTS_TYPE_CURRENT_SETTINGS) 849 tinfo = &targ_info->curr; 850 else 851 tinfo = &targ_info->user; 852 853 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; 854 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB; 855 if (cts->type == CTS_TYPE_USER_SETTINGS) { 856 if ((ahc->user_discenable & devinfo.target_mask) != 0) 857 spi->flags |= CTS_SPI_FLAGS_DISC_ENB; 858 859 if ((ahc->user_tagenable & devinfo.target_mask) != 0) 860 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; 861 } else { 862 if ((tstate->discenable & devinfo.target_mask) != 0) 863 spi->flags |= CTS_SPI_FLAGS_DISC_ENB; 864 865 if ((tstate->tagenable & devinfo.target_mask) != 0) 866 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; 867 } 868 cts->protocol_version = tinfo->protocol_version; 869 cts->transport_version = tinfo->transport_version; 870 871 spi->sync_period = tinfo->period; 872 spi->sync_offset = tinfo->offset; 873 spi->bus_width = tinfo->width; 874 spi->ppr_options = tinfo->ppr_options; 875 876 cts->protocol = PROTO_SCSI; 877 cts->transport = XPORT_SPI; 878 spi->valid = CTS_SPI_VALID_SYNC_RATE 879 | CTS_SPI_VALID_SYNC_OFFSET 880 | CTS_SPI_VALID_BUS_WIDTH 881 | CTS_SPI_VALID_PPR_OPTIONS; 882 883 if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) { 884 scsi->valid = CTS_SCSI_VALID_TQ; 885 spi->valid |= CTS_SPI_VALID_DISC; 886 } else { 887 scsi->valid = 0; 888 } 889 890 cts->ccb_h.status = CAM_REQ_CMP; 891 } 892 893 static void 894 ahc_async(void *callback_arg, uint32_t code, struct cam_path *path, void *arg) 895 { 896 struct ahc_softc *ahc; 897 struct cam_sim *sim; 898 899 sim = (struct cam_sim *)callback_arg; 900 ahc = (struct ahc_softc *)cam_sim_softc(sim); 901 switch (code) { 902 case AC_LOST_DEVICE: 903 { 904 struct ahc_devinfo devinfo; 905 906 ahc_compile_devinfo(&devinfo, SIM_SCSI_ID(ahc, sim), 907 xpt_path_target_id(path), 908 xpt_path_lun_id(path), 909 SIM_CHANNEL(ahc, sim), 910 ROLE_UNKNOWN); 911 912 /* 913 * Revert to async/narrow transfers 914 * for the next device. 915 */ 916 ahc_set_width(ahc, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, 917 AHC_TRANS_GOAL|AHC_TRANS_CUR, /*paused*/FALSE); 918 ahc_set_syncrate(ahc, &devinfo, /*syncrate*/NULL, 919 /*period*/0, /*offset*/0, /*ppr_options*/0, 920 AHC_TRANS_GOAL|AHC_TRANS_CUR, 921 /*paused*/FALSE); 922 break; 923 } 924 default: 925 break; 926 } 927 } 928 929 static void 930 ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments, 931 int error) 932 { 933 struct scb *scb; 934 union ccb *ccb; 935 struct ahc_softc *ahc; 936 struct ahc_initiator_tinfo *tinfo; 937 struct ahc_tmode_tstate *tstate; 938 u_int mask; 939 940 scb = (struct scb *)arg; 941 ccb = scb->io_ctx; 942 ahc = scb->ahc_softc; 943 944 if (error != 0) { 945 if (error == EFBIG) 946 aic_set_transaction_status(scb, CAM_REQ_TOO_BIG); 947 else 948 aic_set_transaction_status(scb, CAM_REQ_CMP_ERR); 949 if (nsegments != 0) 950 bus_dmamap_unload(ahc->buffer_dmat, scb->dmamap); 951 ahc_free_scb(ahc, scb); 952 xpt_done(ccb); 953 return; 954 } 955 if (nsegments != 0) { 956 struct ahc_dma_seg *sg; 957 bus_dma_segment_t *end_seg; 958 959 end_seg = dm_segs + nsegments; 960 961 /* Copy the segments into our SG list */ 962 sg = scb->sg_list; 963 while (dm_segs < end_seg) { 964 uint32_t len; 965 966 sg->addr = aic_htole32(dm_segs->ds_addr); 967 len = dm_segs->ds_len 968 | ((dm_segs->ds_addr >> 8) & 0x7F000000); 969 sg->len = aic_htole32(len); 970 sg++; 971 dm_segs++; 972 } 973 974 /* 975 * Note where to find the SG entries in bus space. 976 * We also set the full residual flag which the 977 * sequencer will clear as soon as a data transfer 978 * occurs. 979 */ 980 scb->hscb->sgptr = aic_htole32(scb->sg_list_phys|SG_FULL_RESID); 981 982 ahc_sync_ccb(ahc, scb, ccb, false); 983 984 if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) { 985 struct target_data *tdata; 986 987 tdata = &scb->hscb->shared_data.tdata; 988 tdata->target_phases |= DPHASE_PENDING; 989 /* 990 * CAM data direction is relative to the initiator. 991 */ 992 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) 993 tdata->data_phase = P_DATAOUT; 994 else 995 tdata->data_phase = P_DATAIN; 996 997 /* 998 * If the transfer is of an odd length and in the 999 * "in" direction (scsi->HostBus), then it may 1000 * trigger a bug in the 'WideODD' feature of 1001 * non-Ultra2 chips. Force the total data-length 1002 * to be even by adding an extra, 1 byte, SG, 1003 * element. We do this even if we are not currently 1004 * negotiated wide as negotiation could occur before 1005 * this command is executed. 1006 */ 1007 if ((ahc->bugs & AHC_TMODE_WIDEODD_BUG) != 0 1008 && (ccb->csio.dxfer_len & 0x1) != 0 1009 && (ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) { 1010 nsegments++; 1011 if (nsegments > AHC_NSEG) { 1012 aic_set_transaction_status(scb, 1013 CAM_REQ_TOO_BIG); 1014 bus_dmamap_unload(ahc->buffer_dmat, 1015 scb->dmamap); 1016 ahc_free_scb(ahc, scb); 1017 xpt_done(ccb); 1018 return; 1019 } 1020 sg->addr = aic_htole32(ahc->dma_bug_buf); 1021 sg->len = aic_htole32(1); 1022 sg++; 1023 } 1024 } 1025 sg--; 1026 sg->len |= aic_htole32(AHC_DMA_LAST_SEG); 1027 1028 /* Copy the first SG into the "current" data pointer area */ 1029 scb->hscb->dataptr = scb->sg_list->addr; 1030 scb->hscb->datacnt = scb->sg_list->len; 1031 } else { 1032 scb->hscb->sgptr = aic_htole32(SG_LIST_NULL); 1033 scb->hscb->dataptr = 0; 1034 scb->hscb->datacnt = 0; 1035 } 1036 1037 scb->sg_count = nsegments; 1038 1039 /* 1040 * Last time we need to check if this SCB needs to 1041 * be aborted. 1042 */ 1043 if (aic_get_transaction_status(scb) != CAM_REQ_INPROG) { 1044 if (nsegments != 0) 1045 bus_dmamap_unload(ahc->buffer_dmat, scb->dmamap); 1046 ahc_free_scb(ahc, scb); 1047 xpt_done(ccb); 1048 return; 1049 } 1050 1051 tinfo = ahc_fetch_transinfo(ahc, SCSIID_CHANNEL(ahc, scb->hscb->scsiid), 1052 SCSIID_OUR_ID(scb->hscb->scsiid), 1053 SCSIID_TARGET(ahc, scb->hscb->scsiid), 1054 &tstate); 1055 1056 mask = SCB_GET_TARGET_MASK(ahc, scb); 1057 scb->hscb->scsirate = tinfo->scsirate; 1058 scb->hscb->scsioffset = tinfo->curr.offset; 1059 if ((tstate->ultraenb & mask) != 0) 1060 scb->hscb->control |= ULTRAENB; 1061 1062 if ((tstate->discenable & mask) != 0 1063 && (ccb->ccb_h.flags & CAM_DIS_DISCONNECT) == 0) 1064 scb->hscb->control |= DISCENB; 1065 1066 if ((ccb->ccb_h.flags & CAM_NEGOTIATE) != 0 1067 && (tinfo->goal.width != 0 1068 || tinfo->goal.offset != 0 1069 || tinfo->goal.ppr_options != 0)) { 1070 scb->flags |= SCB_NEGOTIATE; 1071 scb->hscb->control |= MK_MESSAGE; 1072 } else if ((tstate->auto_negotiate & mask) != 0) { 1073 scb->flags |= SCB_AUTO_NEGOTIATE; 1074 scb->hscb->control |= MK_MESSAGE; 1075 } 1076 1077 LIST_INSERT_HEAD(&ahc->pending_scbs, scb, pending_links); 1078 1079 ccb->ccb_h.status |= CAM_SIM_QUEUED; 1080 1081 /* 1082 * We only allow one untagged transaction 1083 * per target in the initiator role unless 1084 * we are storing a full busy target *lun* 1085 * table in SCB space. 1086 */ 1087 if ((scb->hscb->control & (TARGET_SCB|TAG_ENB)) == 0 1088 && (ahc->flags & AHC_SCB_BTT) == 0) { 1089 struct scb_tailq *untagged_q; 1090 int target_offset; 1091 1092 target_offset = SCB_GET_TARGET_OFFSET(ahc, scb); 1093 untagged_q = &(ahc->untagged_queues[target_offset]); 1094 TAILQ_INSERT_TAIL(untagged_q, scb, links.tqe); 1095 scb->flags |= SCB_UNTAGGEDQ; 1096 if (TAILQ_FIRST(untagged_q) != scb) { 1097 return; 1098 } 1099 } 1100 scb->flags |= SCB_ACTIVE; 1101 1102 /* 1103 * Timers are disabled while recovery is in progress. 1104 */ 1105 aic_scb_timer_start(scb); 1106 1107 if ((scb->flags & SCB_TARGET_IMMEDIATE) != 0) { 1108 /* Define a mapping from our tag to the SCB. */ 1109 ahc->scb_data->scbindex[scb->hscb->tag] = scb; 1110 ahc_pause(ahc); 1111 if ((ahc->flags & AHC_PAGESCBS) == 0) 1112 ahc_outb(ahc, SCBPTR, scb->hscb->tag); 1113 ahc_outb(ahc, TARG_IMMEDIATE_SCB, scb->hscb->tag); 1114 ahc_unpause(ahc); 1115 } else { 1116 ahc_queue_scb(ahc, scb); 1117 } 1118 } 1119 1120 static void 1121 ahc_poll(struct cam_sim *sim) 1122 { 1123 struct ahc_softc *ahc; 1124 1125 ahc = (struct ahc_softc *)cam_sim_softc(sim); 1126 ahc_intr(ahc); 1127 } 1128 1129 static void 1130 ahc_setup_data(struct ahc_softc *ahc, struct cam_sim *sim, 1131 struct ccb_scsiio *csio, struct scb *scb) 1132 { 1133 struct hardware_scb *hscb; 1134 struct ccb_hdr *ccb_h; 1135 int error; 1136 1137 hscb = scb->hscb; 1138 ccb_h = &csio->ccb_h; 1139 1140 csio->resid = 0; 1141 csio->sense_resid = 0; 1142 if (ccb_h->func_code == XPT_SCSI_IO) { 1143 hscb->cdb_len = csio->cdb_len; 1144 if ((ccb_h->flags & CAM_CDB_POINTER) != 0) { 1145 if (hscb->cdb_len > sizeof(hscb->cdb32) 1146 || (ccb_h->flags & CAM_CDB_PHYS) != 0) { 1147 aic_set_transaction_status(scb, 1148 CAM_REQ_INVALID); 1149 ahc_free_scb(ahc, scb); 1150 xpt_done((union ccb *)csio); 1151 return; 1152 } 1153 if (hscb->cdb_len > 12) { 1154 memcpy(hscb->cdb32, 1155 csio->cdb_io.cdb_ptr, 1156 hscb->cdb_len); 1157 scb->flags |= SCB_CDB32_PTR; 1158 } else { 1159 memcpy(hscb->shared_data.cdb, 1160 csio->cdb_io.cdb_ptr, 1161 hscb->cdb_len); 1162 } 1163 } else { 1164 if (hscb->cdb_len > 12) { 1165 memcpy(hscb->cdb32, csio->cdb_io.cdb_bytes, 1166 hscb->cdb_len); 1167 scb->flags |= SCB_CDB32_PTR; 1168 } else { 1169 memcpy(hscb->shared_data.cdb, 1170 csio->cdb_io.cdb_bytes, 1171 hscb->cdb_len); 1172 } 1173 } 1174 } 1175 1176 error = bus_dmamap_load_ccb(ahc->buffer_dmat, 1177 scb->dmamap, 1178 (union ccb *)csio, 1179 ahc_execute_scb, 1180 scb, 1181 0); 1182 if (error == EINPROGRESS) { 1183 /* 1184 * So as to maintain ordering, 1185 * freeze the controller queue 1186 * until our mapping is 1187 * returned. 1188 */ 1189 xpt_freeze_simq(sim, /*count*/1); 1190 scb->io_ctx->ccb_h.status |= CAM_RELEASE_SIMQ; 1191 } 1192 } 1193 1194 static void 1195 ahc_abort_ccb(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb) 1196 { 1197 union ccb *abort_ccb; 1198 1199 abort_ccb = ccb->cab.abort_ccb; 1200 switch (abort_ccb->ccb_h.func_code) { 1201 case XPT_ACCEPT_TARGET_IO: 1202 case XPT_IMMEDIATE_NOTIFY: 1203 case XPT_CONT_TARGET_IO: 1204 { 1205 struct ahc_tmode_tstate *tstate; 1206 struct ahc_tmode_lstate *lstate; 1207 struct ccb_hdr_slist *list; 1208 cam_status status; 1209 1210 status = ahc_find_tmode_devs(ahc, sim, abort_ccb, &tstate, 1211 &lstate, TRUE); 1212 1213 if (status != CAM_REQ_CMP) { 1214 ccb->ccb_h.status = status; 1215 break; 1216 } 1217 1218 if (abort_ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) 1219 list = &lstate->accept_tios; 1220 else if (abort_ccb->ccb_h.func_code == XPT_IMMEDIATE_NOTIFY) 1221 list = &lstate->immed_notifies; 1222 else 1223 list = NULL; 1224 1225 if (list != NULL) { 1226 struct ccb_hdr *curelm; 1227 int found; 1228 1229 curelm = SLIST_FIRST(list); 1230 found = 0; 1231 if (curelm == &abort_ccb->ccb_h) { 1232 found = 1; 1233 SLIST_REMOVE_HEAD(list, sim_links.sle); 1234 } else { 1235 while(curelm != NULL) { 1236 struct ccb_hdr *nextelm; 1237 1238 nextelm = 1239 SLIST_NEXT(curelm, sim_links.sle); 1240 1241 if (nextelm == &abort_ccb->ccb_h) { 1242 found = 1; 1243 SLIST_NEXT(curelm, 1244 sim_links.sle) = 1245 SLIST_NEXT(nextelm, 1246 sim_links.sle); 1247 break; 1248 } 1249 curelm = nextelm; 1250 } 1251 } 1252 1253 if (found) { 1254 abort_ccb->ccb_h.status = CAM_REQ_ABORTED; 1255 xpt_done(abort_ccb); 1256 ccb->ccb_h.status = CAM_REQ_CMP; 1257 } else { 1258 xpt_print_path(abort_ccb->ccb_h.path); 1259 printf("Not found\n"); 1260 ccb->ccb_h.status = CAM_PATH_INVALID; 1261 } 1262 break; 1263 } 1264 /* FALLTHROUGH */ 1265 } 1266 case XPT_SCSI_IO: 1267 /* XXX Fully implement the hard ones */ 1268 ccb->ccb_h.status = CAM_UA_ABORT; 1269 break; 1270 default: 1271 ccb->ccb_h.status = CAM_REQ_INVALID; 1272 break; 1273 } 1274 xpt_done(ccb); 1275 } 1276 1277 void 1278 ahc_send_async(struct ahc_softc *ahc, char channel, u_int target, 1279 u_int lun, ac_code code, void *opt_arg) 1280 { 1281 struct ccb_trans_settings cts; 1282 struct cam_path *path; 1283 void *arg; 1284 int error; 1285 1286 arg = NULL; 1287 error = ahc_create_path(ahc, channel, target, lun, &path); 1288 1289 if (error != CAM_REQ_CMP) 1290 return; 1291 1292 switch (code) { 1293 case AC_TRANSFER_NEG: 1294 { 1295 struct ccb_trans_settings_scsi *scsi; 1296 1297 cts.type = CTS_TYPE_CURRENT_SETTINGS; 1298 scsi = &cts.proto_specific.scsi; 1299 cts.ccb_h.path = path; 1300 cts.ccb_h.target_id = target; 1301 cts.ccb_h.target_lun = lun; 1302 ahc_get_tran_settings(ahc, channel == 'A' ? ahc->our_id 1303 : ahc->our_id_b, 1304 channel, &cts); 1305 arg = &cts; 1306 scsi->valid &= ~CTS_SCSI_VALID_TQ; 1307 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; 1308 if (opt_arg == NULL) 1309 break; 1310 if (*((ahc_queue_alg *)opt_arg) == AHC_QUEUE_TAGGED) 1311 scsi->flags |= ~CTS_SCSI_FLAGS_TAG_ENB; 1312 scsi->valid |= CTS_SCSI_VALID_TQ; 1313 break; 1314 } 1315 case AC_SENT_BDR: 1316 case AC_BUS_RESET: 1317 break; 1318 default: 1319 panic("ahc_send_async: Unexpected async event"); 1320 } 1321 xpt_async(code, path, arg); 1322 xpt_free_path(path); 1323 } 1324 1325 void 1326 ahc_platform_set_tags(struct ahc_softc *ahc, 1327 struct ahc_devinfo *devinfo, int enable) 1328 { 1329 } 1330 1331 int 1332 ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg) 1333 { 1334 ahc->platform_data = malloc(sizeof(struct ahc_platform_data), M_DEVBUF, 1335 M_NOWAIT | M_ZERO); 1336 if (ahc->platform_data == NULL) 1337 return (ENOMEM); 1338 return (0); 1339 } 1340 1341 void 1342 ahc_platform_free(struct ahc_softc *ahc) 1343 { 1344 struct ahc_platform_data *pdata; 1345 1346 pdata = ahc->platform_data; 1347 if (pdata != NULL) { 1348 if (pdata->regs != NULL) 1349 bus_release_resource(ahc->dev_softc, 1350 pdata->regs_res_type, 1351 pdata->regs_res_id, 1352 pdata->regs); 1353 1354 if (pdata->irq != NULL) 1355 bus_release_resource(ahc->dev_softc, 1356 pdata->irq_res_type, 1357 0, pdata->irq); 1358 1359 if (pdata->sim_b != NULL) { 1360 xpt_async(AC_LOST_DEVICE, pdata->path_b, NULL); 1361 xpt_free_path(pdata->path_b); 1362 xpt_bus_deregister(cam_sim_path(pdata->sim_b)); 1363 cam_sim_free(pdata->sim_b, /*free_devq*/TRUE); 1364 } 1365 if (pdata->sim != NULL) { 1366 xpt_async(AC_LOST_DEVICE, pdata->path, NULL); 1367 xpt_free_path(pdata->path); 1368 xpt_bus_deregister(cam_sim_path(pdata->sim)); 1369 cam_sim_free(pdata->sim, /*free_devq*/TRUE); 1370 } 1371 if (pdata->eh != NULL) 1372 EVENTHANDLER_DEREGISTER(shutdown_final, pdata->eh); 1373 free(ahc->platform_data, M_DEVBUF); 1374 } 1375 } 1376 1377 int 1378 ahc_softc_comp(struct ahc_softc *lahc, struct ahc_softc *rahc) 1379 { 1380 /* We don't sort softcs under FreeBSD so report equal always */ 1381 return (0); 1382 } 1383 1384 int 1385 ahc_detach(device_t dev) 1386 { 1387 struct ahc_softc *ahc; 1388 1389 device_printf(dev, "detaching device\n"); 1390 ahc = device_get_softc(dev); 1391 ahc_lock(ahc); 1392 TAILQ_REMOVE(&ahc_tailq, ahc, links); 1393 ahc_intr_enable(ahc, FALSE); 1394 bus_teardown_intr(dev, ahc->platform_data->irq, ahc->platform_data->ih); 1395 ahc_unlock(ahc); 1396 ahc_free(ahc); 1397 return (0); 1398 } 1399 1400 #if 0 1401 static void 1402 ahc_dump_targcmd(struct target_cmd *cmd) 1403 { 1404 uint8_t *byte; 1405 uint8_t *last_byte; 1406 int i; 1407 1408 byte = &cmd->initiator_channel; 1409 /* Debugging info for received commands */ 1410 last_byte = &cmd[1].initiator_channel; 1411 1412 i = 0; 1413 while (byte < last_byte) { 1414 if (i == 0) 1415 printf("\t"); 1416 printf("%#x", *byte++); 1417 i++; 1418 if (i == 8) { 1419 printf("\n"); 1420 i = 0; 1421 } else { 1422 printf(", "); 1423 } 1424 } 1425 } 1426 #endif 1427 1428 static int 1429 ahc_modevent(module_t mod, int type, void *data) 1430 { 1431 /* XXX Deal with busy status on unload. */ 1432 /* XXX Deal with unknown events */ 1433 return 0; 1434 } 1435 1436 static moduledata_t ahc_mod = { 1437 "ahc", 1438 ahc_modevent, 1439 NULL 1440 }; 1441 1442 DECLARE_MODULE(ahc, ahc_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE); 1443 MODULE_DEPEND(ahc, cam, 1, 1, 1); 1444 MODULE_VERSION(ahc, 1); 1445