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 <sys/cdefs.h> 35 __FBSDID("$FreeBSD$"); 36 37 #include <dev/aic7xxx/aic7xxx_osm.h> 38 #include <dev/aic7xxx/aic7xxx_inline.h> 39 40 #include <sys/kthread.h> 41 42 #ifndef AHC_TMODE_ENABLE 43 #define AHC_TMODE_ENABLE 0 44 #endif 45 46 #include <dev/aic7xxx/aic_osm_lib.c> 47 48 #define ccb_scb_ptr spriv_ptr0 49 50 devclass_t ahc_devclass; 51 52 #if 0 53 static void ahc_dump_targcmd(struct target_cmd *cmd); 54 #endif 55 static int ahc_modevent(module_t mod, int type, void *data); 56 static void ahc_action(struct cam_sim *sim, union ccb *ccb); 57 static void ahc_get_tran_settings(struct ahc_softc *ahc, 58 int our_id, char channel, 59 struct ccb_trans_settings *cts); 60 static void ahc_async(void *callback_arg, uint32_t code, 61 struct cam_path *path, void *arg); 62 static void ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, 63 int nsegments, int error); 64 static void ahc_poll(struct cam_sim *sim); 65 static void ahc_setup_data(struct ahc_softc *ahc, struct cam_sim *sim, 66 struct ccb_scsiio *csio, struct scb *scb); 67 static void ahc_abort_ccb(struct ahc_softc *ahc, struct cam_sim *sim, 68 union ccb *ccb); 69 static int ahc_create_path(struct ahc_softc *ahc, 70 char channel, u_int target, u_int lun, 71 struct cam_path **path); 72 73 74 static int 75 ahc_create_path(struct ahc_softc *ahc, char channel, u_int target, 76 u_int lun, struct cam_path **path) 77 { 78 path_id_t path_id; 79 80 if (channel == 'B') 81 path_id = cam_sim_path(ahc->platform_data->sim_b); 82 else 83 path_id = cam_sim_path(ahc->platform_data->sim); 84 85 return (xpt_create_path(path, /*periph*/NULL, 86 path_id, target, lun)); 87 } 88 89 int 90 ahc_map_int(struct ahc_softc *ahc) 91 { 92 int error; 93 int zero; 94 int shareable; 95 96 zero = 0; 97 shareable = (ahc->flags & AHC_EDGE_INTERRUPT) ? 0: RF_SHAREABLE; 98 ahc->platform_data->irq = 99 bus_alloc_resource_any(ahc->dev_softc, SYS_RES_IRQ, &zero, 100 RF_ACTIVE | shareable); 101 if (ahc->platform_data->irq == NULL) { 102 device_printf(ahc->dev_softc, 103 "bus_alloc_resource() failed to allocate IRQ\n"); 104 return (ENOMEM); 105 } 106 ahc->platform_data->irq_res_type = SYS_RES_IRQ; 107 108 /* Hook up our interrupt handler */ 109 error = bus_setup_intr(ahc->dev_softc, ahc->platform_data->irq, 110 INTR_TYPE_CAM, ahc_platform_intr, ahc, 111 &ahc->platform_data->ih); 112 113 if (error != 0) 114 device_printf(ahc->dev_softc, "bus_setup_intr() failed: %d\n", 115 error); 116 return (error); 117 } 118 119 int 120 aic7770_map_registers(struct ahc_softc *ahc, u_int unused_ioport_arg) 121 { 122 struct resource *regs; 123 int rid; 124 125 rid = 0; 126 regs = bus_alloc_resource_any(ahc->dev_softc, SYS_RES_IOPORT, &rid, 127 RF_ACTIVE); 128 if (regs == NULL) { 129 device_printf(ahc->dev_softc, "Unable to map I/O space?!\n"); 130 return ENOMEM; 131 } 132 ahc->platform_data->regs_res_type = SYS_RES_IOPORT; 133 ahc->platform_data->regs_res_id = rid, 134 ahc->platform_data->regs = regs; 135 ahc->tag = rman_get_bustag(regs); 136 ahc->bsh = rman_get_bushandle(regs); 137 return (0); 138 } 139 140 /* 141 * Attach all the sub-devices we can find 142 */ 143 int 144 ahc_attach(struct ahc_softc *ahc) 145 { 146 char ahc_info[256]; 147 struct ccb_setasync csa; 148 struct cam_devq *devq; 149 int bus_id; 150 int bus_id2; 151 struct cam_sim *sim; 152 struct cam_sim *sim2; 153 struct cam_path *path; 154 struct cam_path *path2; 155 long s; 156 int count; 157 158 count = 0; 159 sim = NULL; 160 sim2 = NULL; 161 162 /* 163 * Create a thread to perform all recovery. 164 */ 165 if (ahc_spawn_recovery_thread(ahc) != 0) 166 goto fail; 167 168 ahc_controller_info(ahc, ahc_info); 169 printf("%s\n", ahc_info); 170 ahc_lock(ahc, &s); 171 172 /* 173 * Attach secondary channel first if the user has 174 * declared it the primary channel. 175 */ 176 if ((ahc->features & AHC_TWIN) != 0 177 && (ahc->flags & AHC_PRIMARY_CHANNEL) != 0) { 178 bus_id = 1; 179 bus_id2 = 0; 180 } else { 181 bus_id = 0; 182 bus_id2 = 1; 183 } 184 185 /* 186 * Create the device queue for our SIM(s). 187 */ 188 devq = cam_simq_alloc(AHC_MAX_QUEUE); 189 if (devq == NULL) 190 goto fail; 191 192 /* 193 * Construct our first channel SIM entry 194 */ 195 sim = cam_sim_alloc(ahc_action, ahc_poll, "ahc", ahc, 196 device_get_unit(ahc->dev_softc), 197 1, AHC_MAX_QUEUE, devq); 198 if (sim == NULL) { 199 cam_simq_free(devq); 200 goto fail; 201 } 202 203 if (xpt_bus_register(sim, bus_id) != CAM_SUCCESS) { 204 cam_sim_free(sim, /*free_devq*/TRUE); 205 sim = NULL; 206 goto fail; 207 } 208 209 if (xpt_create_path(&path, /*periph*/NULL, 210 cam_sim_path(sim), CAM_TARGET_WILDCARD, 211 CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 212 xpt_bus_deregister(cam_sim_path(sim)); 213 cam_sim_free(sim, /*free_devq*/TRUE); 214 sim = NULL; 215 goto fail; 216 } 217 218 xpt_setup_ccb(&csa.ccb_h, path, /*priority*/5); 219 csa.ccb_h.func_code = XPT_SASYNC_CB; 220 csa.event_enable = AC_LOST_DEVICE; 221 csa.callback = ahc_async; 222 csa.callback_arg = sim; 223 xpt_action((union ccb *)&csa); 224 count++; 225 226 if (ahc->features & AHC_TWIN) { 227 sim2 = cam_sim_alloc(ahc_action, ahc_poll, "ahc", 228 ahc, device_get_unit(ahc->dev_softc), 1, 229 AHC_MAX_QUEUE, devq); 230 231 if (sim2 == NULL) { 232 printf("ahc_attach: Unable to attach second " 233 "bus due to resource shortage"); 234 goto fail; 235 } 236 237 if (xpt_bus_register(sim2, bus_id2) != CAM_SUCCESS) { 238 printf("ahc_attach: Unable to attach second " 239 "bus due to resource shortage"); 240 /* 241 * We do not want to destroy the device queue 242 * because the first bus is using it. 243 */ 244 cam_sim_free(sim2, /*free_devq*/FALSE); 245 goto fail; 246 } 247 248 if (xpt_create_path(&path2, /*periph*/NULL, 249 cam_sim_path(sim2), 250 CAM_TARGET_WILDCARD, 251 CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 252 xpt_bus_deregister(cam_sim_path(sim2)); 253 cam_sim_free(sim2, /*free_devq*/FALSE); 254 sim2 = NULL; 255 goto fail; 256 } 257 xpt_setup_ccb(&csa.ccb_h, path2, /*priority*/5); 258 csa.ccb_h.func_code = XPT_SASYNC_CB; 259 csa.event_enable = AC_LOST_DEVICE; 260 csa.callback = ahc_async; 261 csa.callback_arg = sim2; 262 xpt_action((union ccb *)&csa); 263 count++; 264 } 265 266 fail: 267 if ((ahc->features & AHC_TWIN) != 0 268 && (ahc->flags & AHC_PRIMARY_CHANNEL) != 0) { 269 ahc->platform_data->sim_b = sim; 270 ahc->platform_data->path_b = path; 271 ahc->platform_data->sim = sim2; 272 ahc->platform_data->path = path2; 273 } else { 274 ahc->platform_data->sim = sim; 275 ahc->platform_data->path = path; 276 ahc->platform_data->sim_b = sim2; 277 ahc->platform_data->path_b = path2; 278 } 279 280 if (count != 0) { 281 /* We have to wait until after any system dumps... */ 282 ahc->platform_data->eh = 283 EVENTHANDLER_REGISTER(shutdown_final, ahc_shutdown, 284 ahc, SHUTDOWN_PRI_DEFAULT); 285 ahc_intr_enable(ahc, TRUE); 286 } 287 288 ahc_unlock(ahc, &s); 289 return (count); 290 } 291 292 /* 293 * Catch an interrupt from the adapter 294 */ 295 void 296 ahc_platform_intr(void *arg) 297 { 298 struct ahc_softc *ahc; 299 300 ahc = (struct ahc_softc *)arg; 301 ahc_intr(ahc); 302 } 303 304 /* 305 * We have an scb which has been processed by the 306 * adaptor, now we look to see how the operation 307 * went. 308 */ 309 void 310 ahc_done(struct ahc_softc *ahc, struct scb *scb) 311 { 312 union ccb *ccb; 313 314 CAM_DEBUG(scb->io_ctx->ccb_h.path, CAM_DEBUG_TRACE, 315 ("ahc_done - scb %d\n", scb->hscb->tag)); 316 317 ccb = scb->io_ctx; 318 LIST_REMOVE(scb, pending_links); 319 if ((scb->flags & SCB_TIMEDOUT) != 0) 320 LIST_REMOVE(scb, timedout_links); 321 if ((scb->flags & SCB_UNTAGGEDQ) != 0) { 322 struct scb_tailq *untagged_q; 323 int target_offset; 324 325 target_offset = SCB_GET_TARGET_OFFSET(ahc, scb); 326 untagged_q = &ahc->untagged_queues[target_offset]; 327 TAILQ_REMOVE(untagged_q, scb, links.tqe); 328 scb->flags &= ~SCB_UNTAGGEDQ; 329 ahc_run_untagged_queue(ahc, untagged_q); 330 } 331 332 untimeout(ahc_platform_timeout, (caddr_t)scb, ccb->ccb_h.timeout_ch); 333 334 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 335 bus_dmasync_op_t op; 336 337 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) 338 op = BUS_DMASYNC_POSTREAD; 339 else 340 op = BUS_DMASYNC_POSTWRITE; 341 bus_dmamap_sync(ahc->buffer_dmat, scb->dmamap, op); 342 bus_dmamap_unload(ahc->buffer_dmat, scb->dmamap); 343 } 344 345 if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) { 346 struct cam_path *ccb_path; 347 348 /* 349 * If we have finally disconnected, clean up our 350 * pending device state. 351 * XXX - There may be error states that cause where 352 * we will remain connected. 353 */ 354 ccb_path = ccb->ccb_h.path; 355 if (ahc->pending_device != NULL 356 && xpt_path_comp(ahc->pending_device->path, ccb_path) == 0) { 357 358 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) { 359 ahc->pending_device = NULL; 360 } else { 361 if (bootverbose) { 362 xpt_print_path(ccb->ccb_h.path); 363 printf("Still connected\n"); 364 } 365 aic_freeze_ccb(ccb); 366 } 367 } 368 369 if (aic_get_transaction_status(scb) == CAM_REQ_INPROG) 370 ccb->ccb_h.status |= CAM_REQ_CMP; 371 ccb->ccb_h.status &= ~CAM_SIM_QUEUED; 372 ahc_free_scb(ahc, scb); 373 xpt_done(ccb); 374 return; 375 } 376 377 /* 378 * If the recovery SCB completes, we have to be 379 * out of our timeout. 380 */ 381 if ((scb->flags & SCB_RECOVERY_SCB) != 0) { 382 struct scb *list_scb; 383 384 ahc->scb_data->recovery_scbs--; 385 386 if (aic_get_transaction_status(scb) == CAM_BDR_SENT 387 || aic_get_transaction_status(scb) == CAM_REQ_ABORTED) 388 aic_set_transaction_status(scb, CAM_CMD_TIMEOUT); 389 390 if (ahc->scb_data->recovery_scbs == 0) { 391 /* 392 * All recovery actions have completed successfully, 393 * so reinstate the timeouts for all other pending 394 * commands. 395 */ 396 LIST_FOREACH(list_scb, &ahc->pending_scbs, 397 pending_links) { 398 399 aic_scb_timer_reset(list_scb, 400 aic_get_timeout(scb)); 401 } 402 403 ahc_print_path(ahc, scb); 404 printf("no longer in timeout, status = %x\n", 405 ccb->ccb_h.status); 406 } 407 } 408 409 /* Don't clobber any existing error state */ 410 if (aic_get_transaction_status(scb) == CAM_REQ_INPROG) { 411 ccb->ccb_h.status |= CAM_REQ_CMP; 412 } else if ((scb->flags & SCB_SENSE) != 0) { 413 /* 414 * We performed autosense retrieval. 415 * 416 * Zero any sense not transferred by the 417 * device. The SCSI spec mandates that any 418 * untransfered data should be assumed to be 419 * zero. Complete the 'bounce' of sense information 420 * through buffers accessible via bus-space by 421 * copying it into the clients csio. 422 */ 423 memset(&ccb->csio.sense_data, 0, sizeof(ccb->csio.sense_data)); 424 memcpy(&ccb->csio.sense_data, 425 ahc_get_sense_buf(ahc, scb), 426 (aic_le32toh(scb->sg_list->len) & AHC_SG_LEN_MASK) 427 - ccb->csio.sense_resid); 428 scb->io_ctx->ccb_h.status |= CAM_AUTOSNS_VALID; 429 } 430 ccb->ccb_h.status &= ~CAM_SIM_QUEUED; 431 ahc_free_scb(ahc, scb); 432 xpt_done(ccb); 433 } 434 435 static void 436 ahc_action(struct cam_sim *sim, union ccb *ccb) 437 { 438 struct ahc_softc *ahc; 439 struct ahc_tmode_lstate *lstate; 440 u_int target_id; 441 u_int our_id; 442 long s; 443 444 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("ahc_action\n")); 445 446 ahc = (struct ahc_softc *)cam_sim_softc(sim); 447 448 target_id = ccb->ccb_h.target_id; 449 our_id = SIM_SCSI_ID(ahc, sim); 450 451 switch (ccb->ccb_h.func_code) { 452 /* Common cases first */ 453 case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */ 454 case XPT_CONT_TARGET_IO:/* Continue Host Target I/O Connection*/ 455 { 456 struct ahc_tmode_tstate *tstate; 457 cam_status status; 458 459 status = ahc_find_tmode_devs(ahc, sim, ccb, &tstate, 460 &lstate, TRUE); 461 462 if (status != CAM_REQ_CMP) { 463 if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) { 464 /* Response from the black hole device */ 465 tstate = NULL; 466 lstate = ahc->black_hole; 467 } else { 468 ccb->ccb_h.status = status; 469 xpt_done(ccb); 470 break; 471 } 472 } 473 if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) { 474 475 ahc_lock(ahc, &s); 476 SLIST_INSERT_HEAD(&lstate->accept_tios, &ccb->ccb_h, 477 sim_links.sle); 478 ccb->ccb_h.status = CAM_REQ_INPROG; 479 if ((ahc->flags & AHC_TQINFIFO_BLOCKED) != 0) 480 ahc_run_tqinfifo(ahc, /*paused*/FALSE); 481 ahc_unlock(ahc, &s); 482 break; 483 } 484 485 /* 486 * The target_id represents the target we attempt to 487 * select. In target mode, this is the initiator of 488 * the original command. 489 */ 490 our_id = target_id; 491 target_id = ccb->csio.init_id; 492 /* FALLTHROUGH */ 493 } 494 case XPT_SCSI_IO: /* Execute the requested I/O operation */ 495 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */ 496 { 497 struct scb *scb; 498 struct hardware_scb *hscb; 499 500 if ((ahc->flags & AHC_INITIATORROLE) == 0 501 && (ccb->ccb_h.func_code == XPT_SCSI_IO 502 || ccb->ccb_h.func_code == XPT_RESET_DEV)) { 503 ccb->ccb_h.status = CAM_PROVIDE_FAIL; 504 xpt_done(ccb); 505 return; 506 } 507 508 /* 509 * get an scb to use. 510 */ 511 ahc_lock(ahc, &s); 512 if ((scb = ahc_get_scb(ahc)) == NULL) { 513 514 xpt_freeze_simq(sim, /*count*/1); 515 ahc->flags |= AHC_RESOURCE_SHORTAGE; 516 ahc_unlock(ahc, &s); 517 ccb->ccb_h.status = CAM_REQUEUE_REQ; 518 xpt_done(ccb); 519 return; 520 } 521 ahc_unlock(ahc, &s); 522 523 hscb = scb->hscb; 524 525 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_SUBTRACE, 526 ("start scb(%p)\n", scb)); 527 scb->io_ctx = ccb; 528 /* 529 * So we can find the SCB when an abort is requested 530 */ 531 ccb->ccb_h.ccb_scb_ptr = scb; 532 533 /* 534 * Put all the arguments for the xfer in the scb 535 */ 536 hscb->control = 0; 537 hscb->scsiid = BUILD_SCSIID(ahc, sim, target_id, our_id); 538 hscb->lun = ccb->ccb_h.target_lun; 539 if (ccb->ccb_h.func_code == XPT_RESET_DEV) { 540 hscb->cdb_len = 0; 541 scb->flags |= SCB_DEVICE_RESET; 542 hscb->control |= MK_MESSAGE; 543 ahc_execute_scb(scb, NULL, 0, 0); 544 } else { 545 if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) { 546 struct target_data *tdata; 547 548 tdata = &hscb->shared_data.tdata; 549 if (ahc->pending_device == lstate) 550 scb->flags |= SCB_TARGET_IMMEDIATE; 551 hscb->control |= TARGET_SCB; 552 scb->flags |= SCB_TARGET_SCB; 553 tdata->target_phases = 0; 554 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) { 555 tdata->target_phases |= SPHASE_PENDING; 556 tdata->scsi_status = 557 ccb->csio.scsi_status; 558 } 559 if (ccb->ccb_h.flags & CAM_DIS_DISCONNECT) 560 tdata->target_phases |= NO_DISCONNECT; 561 562 tdata->initiator_tag = ccb->csio.tag_id; 563 } 564 if (ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) 565 hscb->control |= ccb->csio.tag_action; 566 567 ahc_setup_data(ahc, sim, &ccb->csio, scb); 568 } 569 break; 570 } 571 case XPT_NOTIFY_ACK: 572 case XPT_IMMED_NOTIFY: 573 { 574 struct ahc_tmode_tstate *tstate; 575 struct ahc_tmode_lstate *lstate; 576 cam_status status; 577 578 status = ahc_find_tmode_devs(ahc, sim, ccb, &tstate, 579 &lstate, TRUE); 580 581 if (status != CAM_REQ_CMP) { 582 ccb->ccb_h.status = status; 583 xpt_done(ccb); 584 break; 585 } 586 SLIST_INSERT_HEAD(&lstate->immed_notifies, &ccb->ccb_h, 587 sim_links.sle); 588 ccb->ccb_h.status = CAM_REQ_INPROG; 589 ahc_send_lstate_events(ahc, lstate); 590 break; 591 } 592 case XPT_EN_LUN: /* Enable LUN as a target */ 593 ahc_handle_en_lun(ahc, sim, ccb); 594 xpt_done(ccb); 595 break; 596 case XPT_ABORT: /* Abort the specified CCB */ 597 { 598 ahc_abort_ccb(ahc, sim, ccb); 599 break; 600 } 601 case XPT_SET_TRAN_SETTINGS: 602 { 603 #ifdef AHC_NEW_TRAN_SETTINGS 604 struct ahc_devinfo devinfo; 605 struct ccb_trans_settings *cts; 606 struct ccb_trans_settings_scsi *scsi; 607 struct ccb_trans_settings_spi *spi; 608 struct ahc_initiator_tinfo *tinfo; 609 struct ahc_tmode_tstate *tstate; 610 uint16_t *discenable; 611 uint16_t *tagenable; 612 u_int update_type; 613 614 cts = &ccb->cts; 615 scsi = &cts->proto_specific.scsi; 616 spi = &cts->xport_specific.spi; 617 ahc_compile_devinfo(&devinfo, SIM_SCSI_ID(ahc, sim), 618 cts->ccb_h.target_id, 619 cts->ccb_h.target_lun, 620 SIM_CHANNEL(ahc, sim), 621 ROLE_UNKNOWN); 622 tinfo = ahc_fetch_transinfo(ahc, devinfo.channel, 623 devinfo.our_scsiid, 624 devinfo.target, &tstate); 625 update_type = 0; 626 if (cts->type == CTS_TYPE_CURRENT_SETTINGS) { 627 update_type |= AHC_TRANS_GOAL; 628 discenable = &tstate->discenable; 629 tagenable = &tstate->tagenable; 630 tinfo->curr.protocol_version = 631 cts->protocol_version; 632 tinfo->curr.transport_version = 633 cts->transport_version; 634 tinfo->goal.protocol_version = 635 cts->protocol_version; 636 tinfo->goal.transport_version = 637 cts->transport_version; 638 } else if (cts->type == CTS_TYPE_USER_SETTINGS) { 639 update_type |= AHC_TRANS_USER; 640 discenable = &ahc->user_discenable; 641 tagenable = &ahc->user_tagenable; 642 tinfo->user.protocol_version = 643 cts->protocol_version; 644 tinfo->user.transport_version = 645 cts->transport_version; 646 } else { 647 ccb->ccb_h.status = CAM_REQ_INVALID; 648 xpt_done(ccb); 649 break; 650 } 651 652 ahc_lock(ahc, &s); 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 ahc_unlock(ahc, &s); 730 ccb->ccb_h.status = CAM_REQ_CMP; 731 xpt_done(ccb); 732 #else 733 struct ahc_devinfo devinfo; 734 struct ccb_trans_settings *cts; 735 struct ahc_initiator_tinfo *tinfo; 736 struct ahc_tmode_tstate *tstate; 737 uint16_t *discenable; 738 uint16_t *tagenable; 739 u_int update_type; 740 long s; 741 742 cts = &ccb->cts; 743 ahc_compile_devinfo(&devinfo, SIM_SCSI_ID(ahc, sim), 744 cts->ccb_h.target_id, 745 cts->ccb_h.target_lun, 746 SIM_CHANNEL(ahc, sim), 747 ROLE_UNKNOWN); 748 tinfo = ahc_fetch_transinfo(ahc, devinfo.channel, 749 devinfo.our_scsiid, 750 devinfo.target, &tstate); 751 update_type = 0; 752 if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0) { 753 update_type |= AHC_TRANS_GOAL; 754 discenable = &tstate->discenable; 755 tagenable = &tstate->tagenable; 756 } else if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) { 757 update_type |= AHC_TRANS_USER; 758 discenable = &ahc->user_discenable; 759 tagenable = &ahc->user_tagenable; 760 } else { 761 ccb->ccb_h.status = CAM_REQ_INVALID; 762 xpt_done(ccb); 763 break; 764 } 765 766 ahc_lock(ahc, &s); 767 768 if ((cts->valid & CCB_TRANS_DISC_VALID) != 0) { 769 if ((cts->flags & CCB_TRANS_DISC_ENB) != 0) 770 *discenable |= devinfo.target_mask; 771 else 772 *discenable &= ~devinfo.target_mask; 773 } 774 775 if ((cts->valid & CCB_TRANS_TQ_VALID) != 0) { 776 if ((cts->flags & CCB_TRANS_TAG_ENB) != 0) 777 *tagenable |= devinfo.target_mask; 778 else 779 *tagenable &= ~devinfo.target_mask; 780 } 781 782 if ((cts->valid & CCB_TRANS_BUS_WIDTH_VALID) != 0) { 783 ahc_validate_width(ahc, /*tinfo limit*/NULL, 784 &cts->bus_width, ROLE_UNKNOWN); 785 ahc_set_width(ahc, &devinfo, cts->bus_width, 786 update_type, /*paused*/FALSE); 787 } 788 789 if ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) == 0) { 790 if (update_type == AHC_TRANS_USER) 791 cts->sync_offset = tinfo->user.offset; 792 else 793 cts->sync_offset = tinfo->goal.offset; 794 } 795 796 if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) == 0) { 797 if (update_type == AHC_TRANS_USER) 798 cts->sync_period = tinfo->user.period; 799 else 800 cts->sync_period = tinfo->goal.period; 801 } 802 803 if (((cts->valid & CCB_TRANS_SYNC_RATE_VALID) != 0) 804 || ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) != 0)) { 805 struct ahc_syncrate *syncrate; 806 u_int ppr_options; 807 u_int maxsync; 808 809 if ((ahc->features & AHC_ULTRA2) != 0) 810 maxsync = AHC_SYNCRATE_DT; 811 else if ((ahc->features & AHC_ULTRA) != 0) 812 maxsync = AHC_SYNCRATE_ULTRA; 813 else 814 maxsync = AHC_SYNCRATE_FAST; 815 816 ppr_options = 0; 817 if (cts->sync_period <= 9 818 && cts->bus_width == MSG_EXT_WDTR_BUS_16_BIT) 819 ppr_options = MSG_EXT_PPR_DT_REQ; 820 821 syncrate = ahc_find_syncrate(ahc, &cts->sync_period, 822 &ppr_options, 823 maxsync); 824 ahc_validate_offset(ahc, /*tinfo limit*/NULL, 825 syncrate, &cts->sync_offset, 826 MSG_EXT_WDTR_BUS_8_BIT, 827 ROLE_UNKNOWN); 828 829 /* We use a period of 0 to represent async */ 830 if (cts->sync_offset == 0) { 831 cts->sync_period = 0; 832 ppr_options = 0; 833 } 834 835 if (ppr_options == MSG_EXT_PPR_DT_REQ 836 && tinfo->user.transport_version >= 3) { 837 tinfo->goal.transport_version = 838 tinfo->user.transport_version; 839 tinfo->curr.transport_version = 840 tinfo->user.transport_version; 841 } 842 843 ahc_set_syncrate(ahc, &devinfo, syncrate, 844 cts->sync_period, cts->sync_offset, 845 ppr_options, update_type, 846 /*paused*/FALSE); 847 } 848 ahc_unlock(ahc, &s); 849 ccb->ccb_h.status = CAM_REQ_CMP; 850 xpt_done(ccb); 851 #endif 852 break; 853 } 854 case XPT_GET_TRAN_SETTINGS: 855 /* Get default/user set transfer settings for the target */ 856 { 857 858 ahc_lock(ahc, &s); 859 ahc_get_tran_settings(ahc, SIM_SCSI_ID(ahc, sim), 860 SIM_CHANNEL(ahc, sim), &ccb->cts); 861 ahc_unlock(ahc, &s); 862 xpt_done(ccb); 863 break; 864 } 865 case XPT_CALC_GEOMETRY: 866 { 867 int extended; 868 869 extended = SIM_IS_SCSIBUS_B(ahc, sim) 870 ? ahc->flags & AHC_EXTENDED_TRANS_B 871 : ahc->flags & AHC_EXTENDED_TRANS_A; 872 aic_calc_geometry(&ccb->ccg, extended); 873 xpt_done(ccb); 874 break; 875 } 876 case XPT_RESET_BUS: /* Reset the specified SCSI bus */ 877 { 878 int found; 879 880 ahc_lock(ahc, &s); 881 found = ahc_reset_channel(ahc, SIM_CHANNEL(ahc, sim), 882 /*initiate reset*/TRUE); 883 ahc_unlock(ahc, &s); 884 if (bootverbose) { 885 xpt_print_path(SIM_PATH(ahc, sim)); 886 printf("SCSI bus reset delivered. " 887 "%d SCBs aborted.\n", found); 888 } 889 ccb->ccb_h.status = CAM_REQ_CMP; 890 xpt_done(ccb); 891 break; 892 } 893 case XPT_TERM_IO: /* Terminate the I/O process */ 894 /* XXX Implement */ 895 ccb->ccb_h.status = CAM_REQ_INVALID; 896 xpt_done(ccb); 897 break; 898 case XPT_PATH_INQ: /* Path routing inquiry */ 899 { 900 struct ccb_pathinq *cpi = &ccb->cpi; 901 902 cpi->version_num = 1; /* XXX??? */ 903 cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE; 904 if ((ahc->features & AHC_WIDE) != 0) 905 cpi->hba_inquiry |= PI_WIDE_16; 906 if ((ahc->features & AHC_TARGETMODE) != 0) { 907 cpi->target_sprt = PIT_PROCESSOR 908 | PIT_DISCONNECT 909 | PIT_TERM_IO; 910 } else { 911 cpi->target_sprt = 0; 912 } 913 cpi->hba_misc = 0; 914 cpi->hba_eng_cnt = 0; 915 cpi->max_target = (ahc->features & AHC_WIDE) ? 15 : 7; 916 cpi->max_lun = AHC_NUM_LUNS - 1; 917 if (SIM_IS_SCSIBUS_B(ahc, sim)) { 918 cpi->initiator_id = ahc->our_id_b; 919 if ((ahc->flags & AHC_RESET_BUS_B) == 0) 920 cpi->hba_misc |= PIM_NOBUSRESET; 921 } else { 922 cpi->initiator_id = ahc->our_id; 923 if ((ahc->flags & AHC_RESET_BUS_A) == 0) 924 cpi->hba_misc |= PIM_NOBUSRESET; 925 } 926 cpi->bus_id = cam_sim_bus(sim); 927 cpi->base_transfer_speed = 3300; 928 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 929 strncpy(cpi->hba_vid, "Adaptec", HBA_IDLEN); 930 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 931 cpi->unit_number = cam_sim_unit(sim); 932 #ifdef AHC_NEW_TRAN_SETTINGS 933 cpi->protocol = PROTO_SCSI; 934 cpi->protocol_version = SCSI_REV_2; 935 cpi->transport = XPORT_SPI; 936 cpi->transport_version = 2; 937 cpi->xport_specific.spi.ppr_options = SID_SPI_CLOCK_ST; 938 if ((ahc->features & AHC_DT) != 0) { 939 cpi->transport_version = 3; 940 cpi->xport_specific.spi.ppr_options = 941 SID_SPI_CLOCK_DT_ST; 942 } 943 #endif 944 cpi->ccb_h.status = CAM_REQ_CMP; 945 xpt_done(ccb); 946 break; 947 } 948 default: 949 ccb->ccb_h.status = CAM_PROVIDE_FAIL; 950 xpt_done(ccb); 951 break; 952 } 953 } 954 955 static void 956 ahc_get_tran_settings(struct ahc_softc *ahc, int our_id, char channel, 957 struct ccb_trans_settings *cts) 958 { 959 #ifdef AHC_NEW_TRAN_SETTINGS 960 struct ahc_devinfo devinfo; 961 struct ccb_trans_settings_scsi *scsi; 962 struct ccb_trans_settings_spi *spi; 963 struct ahc_initiator_tinfo *targ_info; 964 struct ahc_tmode_tstate *tstate; 965 struct ahc_transinfo *tinfo; 966 967 scsi = &cts->proto_specific.scsi; 968 spi = &cts->xport_specific.spi; 969 ahc_compile_devinfo(&devinfo, our_id, 970 cts->ccb_h.target_id, 971 cts->ccb_h.target_lun, 972 channel, ROLE_UNKNOWN); 973 targ_info = ahc_fetch_transinfo(ahc, devinfo.channel, 974 devinfo.our_scsiid, 975 devinfo.target, &tstate); 976 977 if (cts->type == CTS_TYPE_CURRENT_SETTINGS) 978 tinfo = &targ_info->curr; 979 else 980 tinfo = &targ_info->user; 981 982 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; 983 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB; 984 if (cts->type == CTS_TYPE_USER_SETTINGS) { 985 if ((ahc->user_discenable & devinfo.target_mask) != 0) 986 spi->flags |= CTS_SPI_FLAGS_DISC_ENB; 987 988 if ((ahc->user_tagenable & devinfo.target_mask) != 0) 989 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; 990 } else { 991 if ((tstate->discenable & devinfo.target_mask) != 0) 992 spi->flags |= CTS_SPI_FLAGS_DISC_ENB; 993 994 if ((tstate->tagenable & devinfo.target_mask) != 0) 995 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; 996 } 997 cts->protocol_version = tinfo->protocol_version; 998 cts->transport_version = tinfo->transport_version; 999 1000 spi->sync_period = tinfo->period; 1001 spi->sync_offset = tinfo->offset; 1002 spi->bus_width = tinfo->width; 1003 spi->ppr_options = tinfo->ppr_options; 1004 1005 cts->protocol = PROTO_SCSI; 1006 cts->transport = XPORT_SPI; 1007 spi->valid = CTS_SPI_VALID_SYNC_RATE 1008 | CTS_SPI_VALID_SYNC_OFFSET 1009 | CTS_SPI_VALID_BUS_WIDTH 1010 | CTS_SPI_VALID_PPR_OPTIONS; 1011 1012 if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) { 1013 scsi->valid = CTS_SCSI_VALID_TQ; 1014 spi->valid |= CTS_SPI_VALID_DISC; 1015 } else { 1016 scsi->valid = 0; 1017 } 1018 1019 cts->ccb_h.status = CAM_REQ_CMP; 1020 #else 1021 struct ahc_devinfo devinfo; 1022 struct ahc_initiator_tinfo *targ_info; 1023 struct ahc_tmode_tstate *tstate; 1024 struct ahc_transinfo *tinfo; 1025 1026 ahc_compile_devinfo(&devinfo, our_id, 1027 cts->ccb_h.target_id, 1028 cts->ccb_h.target_lun, 1029 channel, ROLE_UNKNOWN); 1030 targ_info = ahc_fetch_transinfo(ahc, devinfo.channel, 1031 devinfo.our_scsiid, 1032 devinfo.target, &tstate); 1033 1034 if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0) 1035 tinfo = &targ_info->curr; 1036 else 1037 tinfo = &targ_info->user; 1038 1039 cts->flags &= ~(CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB); 1040 if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) == 0) { 1041 if ((ahc->user_discenable & devinfo.target_mask) != 0) 1042 cts->flags |= CCB_TRANS_DISC_ENB; 1043 1044 if ((ahc->user_tagenable & devinfo.target_mask) != 0) 1045 cts->flags |= CCB_TRANS_TAG_ENB; 1046 } else { 1047 if ((tstate->discenable & devinfo.target_mask) != 0) 1048 cts->flags |= CCB_TRANS_DISC_ENB; 1049 1050 if ((tstate->tagenable & devinfo.target_mask) != 0) 1051 cts->flags |= CCB_TRANS_TAG_ENB; 1052 } 1053 cts->sync_period = tinfo->period; 1054 cts->sync_offset = tinfo->offset; 1055 cts->bus_width = tinfo->width; 1056 1057 cts->valid = CCB_TRANS_SYNC_RATE_VALID 1058 | CCB_TRANS_SYNC_OFFSET_VALID 1059 | CCB_TRANS_BUS_WIDTH_VALID; 1060 1061 if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) 1062 cts->valid |= CCB_TRANS_DISC_VALID|CCB_TRANS_TQ_VALID; 1063 1064 cts->ccb_h.status = CAM_REQ_CMP; 1065 #endif 1066 } 1067 1068 static void 1069 ahc_async(void *callback_arg, uint32_t code, struct cam_path *path, void *arg) 1070 { 1071 struct ahc_softc *ahc; 1072 struct cam_sim *sim; 1073 1074 sim = (struct cam_sim *)callback_arg; 1075 ahc = (struct ahc_softc *)cam_sim_softc(sim); 1076 switch (code) { 1077 case AC_LOST_DEVICE: 1078 { 1079 struct ahc_devinfo devinfo; 1080 long s; 1081 1082 ahc_compile_devinfo(&devinfo, SIM_SCSI_ID(ahc, sim), 1083 xpt_path_target_id(path), 1084 xpt_path_lun_id(path), 1085 SIM_CHANNEL(ahc, sim), 1086 ROLE_UNKNOWN); 1087 1088 /* 1089 * Revert to async/narrow transfers 1090 * for the next device. 1091 */ 1092 ahc_lock(ahc, &s); 1093 ahc_set_width(ahc, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, 1094 AHC_TRANS_GOAL|AHC_TRANS_CUR, /*paused*/FALSE); 1095 ahc_set_syncrate(ahc, &devinfo, /*syncrate*/NULL, 1096 /*period*/0, /*offset*/0, /*ppr_options*/0, 1097 AHC_TRANS_GOAL|AHC_TRANS_CUR, 1098 /*paused*/FALSE); 1099 ahc_unlock(ahc, &s); 1100 break; 1101 } 1102 default: 1103 break; 1104 } 1105 } 1106 1107 static void 1108 ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments, 1109 int error) 1110 { 1111 struct scb *scb; 1112 union ccb *ccb; 1113 struct ahc_softc *ahc; 1114 struct ahc_initiator_tinfo *tinfo; 1115 struct ahc_tmode_tstate *tstate; 1116 u_int mask; 1117 long s; 1118 1119 scb = (struct scb *)arg; 1120 ccb = scb->io_ctx; 1121 ahc = scb->ahc_softc; 1122 1123 if (error != 0) { 1124 if (error == EFBIG) 1125 aic_set_transaction_status(scb, CAM_REQ_TOO_BIG); 1126 else 1127 aic_set_transaction_status(scb, CAM_REQ_CMP_ERR); 1128 if (nsegments != 0) 1129 bus_dmamap_unload(ahc->buffer_dmat, scb->dmamap); 1130 ahc_lock(ahc, &s); 1131 ahc_free_scb(ahc, scb); 1132 ahc_unlock(ahc, &s); 1133 xpt_done(ccb); 1134 return; 1135 } 1136 if (nsegments != 0) { 1137 struct ahc_dma_seg *sg; 1138 bus_dma_segment_t *end_seg; 1139 bus_dmasync_op_t op; 1140 1141 end_seg = dm_segs + nsegments; 1142 1143 /* Copy the segments into our SG list */ 1144 sg = scb->sg_list; 1145 while (dm_segs < end_seg) { 1146 uint32_t len; 1147 1148 sg->addr = aic_htole32(dm_segs->ds_addr); 1149 len = dm_segs->ds_len 1150 | ((dm_segs->ds_addr >> 8) & 0x7F000000); 1151 sg->len = aic_htole32(len); 1152 sg++; 1153 dm_segs++; 1154 } 1155 1156 /* 1157 * Note where to find the SG entries in bus space. 1158 * We also set the full residual flag which the 1159 * sequencer will clear as soon as a data transfer 1160 * occurs. 1161 */ 1162 scb->hscb->sgptr = aic_htole32(scb->sg_list_phys|SG_FULL_RESID); 1163 1164 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) 1165 op = BUS_DMASYNC_PREREAD; 1166 else 1167 op = BUS_DMASYNC_PREWRITE; 1168 1169 bus_dmamap_sync(ahc->buffer_dmat, scb->dmamap, op); 1170 1171 if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) { 1172 struct target_data *tdata; 1173 1174 tdata = &scb->hscb->shared_data.tdata; 1175 tdata->target_phases |= DPHASE_PENDING; 1176 /* 1177 * CAM data direction is relative to the initiator. 1178 */ 1179 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) 1180 tdata->data_phase = P_DATAOUT; 1181 else 1182 tdata->data_phase = P_DATAIN; 1183 1184 /* 1185 * If the transfer is of an odd length and in the 1186 * "in" direction (scsi->HostBus), then it may 1187 * trigger a bug in the 'WideODD' feature of 1188 * non-Ultra2 chips. Force the total data-length 1189 * to be even by adding an extra, 1 byte, SG, 1190 * element. We do this even if we are not currently 1191 * negotiated wide as negotiation could occur before 1192 * this command is executed. 1193 */ 1194 if ((ahc->bugs & AHC_TMODE_WIDEODD_BUG) != 0 1195 && (ccb->csio.dxfer_len & 0x1) != 0 1196 && (ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) { 1197 1198 nsegments++; 1199 if (nsegments > AHC_NSEG) { 1200 1201 aic_set_transaction_status(scb, 1202 CAM_REQ_TOO_BIG); 1203 bus_dmamap_unload(ahc->buffer_dmat, 1204 scb->dmamap); 1205 ahc_lock(ahc, &s); 1206 ahc_free_scb(ahc, scb); 1207 ahc_unlock(ahc, &s); 1208 xpt_done(ccb); 1209 return; 1210 } 1211 sg->addr = aic_htole32(ahc->dma_bug_buf); 1212 sg->len = aic_htole32(1); 1213 sg++; 1214 } 1215 } 1216 sg--; 1217 sg->len |= aic_htole32(AHC_DMA_LAST_SEG); 1218 1219 /* Copy the first SG into the "current" data pointer area */ 1220 scb->hscb->dataptr = scb->sg_list->addr; 1221 scb->hscb->datacnt = scb->sg_list->len; 1222 } else { 1223 scb->hscb->sgptr = aic_htole32(SG_LIST_NULL); 1224 scb->hscb->dataptr = 0; 1225 scb->hscb->datacnt = 0; 1226 } 1227 1228 scb->sg_count = nsegments; 1229 1230 ahc_lock(ahc, &s); 1231 1232 /* 1233 * Last time we need to check if this SCB needs to 1234 * be aborted. 1235 */ 1236 if (aic_get_transaction_status(scb) != CAM_REQ_INPROG) { 1237 if (nsegments != 0) 1238 bus_dmamap_unload(ahc->buffer_dmat, scb->dmamap); 1239 ahc_free_scb(ahc, scb); 1240 ahc_unlock(ahc, &s); 1241 xpt_done(ccb); 1242 return; 1243 } 1244 1245 tinfo = ahc_fetch_transinfo(ahc, SCSIID_CHANNEL(ahc, scb->hscb->scsiid), 1246 SCSIID_OUR_ID(scb->hscb->scsiid), 1247 SCSIID_TARGET(ahc, scb->hscb->scsiid), 1248 &tstate); 1249 1250 mask = SCB_GET_TARGET_MASK(ahc, scb); 1251 scb->hscb->scsirate = tinfo->scsirate; 1252 scb->hscb->scsioffset = tinfo->curr.offset; 1253 if ((tstate->ultraenb & mask) != 0) 1254 scb->hscb->control |= ULTRAENB; 1255 1256 if ((tstate->discenable & mask) != 0 1257 && (ccb->ccb_h.flags & CAM_DIS_DISCONNECT) == 0) 1258 scb->hscb->control |= DISCENB; 1259 1260 if ((ccb->ccb_h.flags & CAM_NEGOTIATE) != 0 1261 && (tinfo->goal.width != 0 1262 || tinfo->goal.offset != 0 1263 || tinfo->goal.ppr_options != 0)) { 1264 scb->flags |= SCB_NEGOTIATE; 1265 scb->hscb->control |= MK_MESSAGE; 1266 } else if ((tstate->auto_negotiate & mask) != 0) { 1267 scb->flags |= SCB_AUTO_NEGOTIATE; 1268 scb->hscb->control |= MK_MESSAGE; 1269 } 1270 1271 LIST_INSERT_HEAD(&ahc->pending_scbs, scb, pending_links); 1272 1273 ccb->ccb_h.status |= CAM_SIM_QUEUED; 1274 1275 /* 1276 * We only allow one untagged transaction 1277 * per target in the initiator role unless 1278 * we are storing a full busy target *lun* 1279 * table in SCB space. 1280 */ 1281 if ((scb->hscb->control & (TARGET_SCB|TAG_ENB)) == 0 1282 && (ahc->flags & AHC_SCB_BTT) == 0) { 1283 struct scb_tailq *untagged_q; 1284 int target_offset; 1285 1286 target_offset = SCB_GET_TARGET_OFFSET(ahc, scb); 1287 untagged_q = &(ahc->untagged_queues[target_offset]); 1288 TAILQ_INSERT_TAIL(untagged_q, scb, links.tqe); 1289 scb->flags |= SCB_UNTAGGEDQ; 1290 if (TAILQ_FIRST(untagged_q) != scb) { 1291 ahc_unlock(ahc, &s); 1292 return; 1293 } 1294 } 1295 scb->flags |= SCB_ACTIVE; 1296 1297 /* 1298 * Timers are disabled while recovery is in progress. 1299 */ 1300 aic_scb_timer_start(scb); 1301 1302 if ((scb->flags & SCB_TARGET_IMMEDIATE) != 0) { 1303 /* Define a mapping from our tag to the SCB. */ 1304 ahc->scb_data->scbindex[scb->hscb->tag] = scb; 1305 ahc_pause(ahc); 1306 if ((ahc->flags & AHC_PAGESCBS) == 0) 1307 ahc_outb(ahc, SCBPTR, scb->hscb->tag); 1308 ahc_outb(ahc, TARG_IMMEDIATE_SCB, scb->hscb->tag); 1309 ahc_unpause(ahc); 1310 } else { 1311 ahc_queue_scb(ahc, scb); 1312 } 1313 1314 ahc_unlock(ahc, &s); 1315 } 1316 1317 static void 1318 ahc_poll(struct cam_sim *sim) 1319 { 1320 struct ahc_softc *ahc; 1321 1322 ahc = (struct ahc_softc *)cam_sim_softc(sim); 1323 ahc_intr(ahc); 1324 } 1325 1326 static void 1327 ahc_setup_data(struct ahc_softc *ahc, struct cam_sim *sim, 1328 struct ccb_scsiio *csio, struct scb *scb) 1329 { 1330 struct hardware_scb *hscb; 1331 struct ccb_hdr *ccb_h; 1332 1333 hscb = scb->hscb; 1334 ccb_h = &csio->ccb_h; 1335 1336 csio->resid = 0; 1337 csio->sense_resid = 0; 1338 if (ccb_h->func_code == XPT_SCSI_IO) { 1339 hscb->cdb_len = csio->cdb_len; 1340 if ((ccb_h->flags & CAM_CDB_POINTER) != 0) { 1341 1342 if (hscb->cdb_len > sizeof(hscb->cdb32) 1343 || (ccb_h->flags & CAM_CDB_PHYS) != 0) { 1344 u_long s; 1345 1346 aic_set_transaction_status(scb, 1347 CAM_REQ_INVALID); 1348 ahc_lock(ahc, &s); 1349 ahc_free_scb(ahc, scb); 1350 ahc_unlock(ahc, &s); 1351 xpt_done((union ccb *)csio); 1352 return; 1353 } 1354 if (hscb->cdb_len > 12) { 1355 memcpy(hscb->cdb32, 1356 csio->cdb_io.cdb_ptr, 1357 hscb->cdb_len); 1358 scb->flags |= SCB_CDB32_PTR; 1359 } else { 1360 memcpy(hscb->shared_data.cdb, 1361 csio->cdb_io.cdb_ptr, 1362 hscb->cdb_len); 1363 } 1364 } else { 1365 if (hscb->cdb_len > 12) { 1366 memcpy(hscb->cdb32, csio->cdb_io.cdb_bytes, 1367 hscb->cdb_len); 1368 scb->flags |= SCB_CDB32_PTR; 1369 } else { 1370 memcpy(hscb->shared_data.cdb, 1371 csio->cdb_io.cdb_bytes, 1372 hscb->cdb_len); 1373 } 1374 } 1375 } 1376 1377 /* Only use S/G if there is a transfer */ 1378 if ((ccb_h->flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 1379 if ((ccb_h->flags & CAM_SCATTER_VALID) == 0) { 1380 /* We've been given a pointer to a single buffer */ 1381 if ((ccb_h->flags & CAM_DATA_PHYS) == 0) { 1382 int s; 1383 int error; 1384 1385 s = splsoftvm(); 1386 error = bus_dmamap_load(ahc->buffer_dmat, 1387 scb->dmamap, 1388 csio->data_ptr, 1389 csio->dxfer_len, 1390 ahc_execute_scb, 1391 scb, /*flags*/0); 1392 if (error == EINPROGRESS) { 1393 /* 1394 * So as to maintain ordering, 1395 * freeze the controller queue 1396 * until our mapping is 1397 * returned. 1398 */ 1399 xpt_freeze_simq(sim, 1400 /*count*/1); 1401 scb->io_ctx->ccb_h.status |= 1402 CAM_RELEASE_SIMQ; 1403 } 1404 splx(s); 1405 } else { 1406 struct bus_dma_segment seg; 1407 1408 /* Pointer to physical buffer */ 1409 if (csio->dxfer_len > AHC_MAXTRANSFER_SIZE) 1410 panic("ahc_setup_data - Transfer size " 1411 "larger than can device max"); 1412 1413 seg.ds_addr = 1414 (bus_addr_t)(vm_offset_t)csio->data_ptr; 1415 seg.ds_len = csio->dxfer_len; 1416 ahc_execute_scb(scb, &seg, 1, 0); 1417 } 1418 } else { 1419 struct bus_dma_segment *segs; 1420 1421 if ((ccb_h->flags & CAM_DATA_PHYS) != 0) 1422 panic("ahc_setup_data - Physical segment " 1423 "pointers unsupported"); 1424 1425 if ((ccb_h->flags & CAM_SG_LIST_PHYS) == 0) 1426 panic("ahc_setup_data - Virtual segment " 1427 "addresses unsupported"); 1428 1429 /* Just use the segments provided */ 1430 segs = (struct bus_dma_segment *)csio->data_ptr; 1431 ahc_execute_scb(scb, segs, csio->sglist_cnt, 0); 1432 } 1433 } else { 1434 ahc_execute_scb(scb, NULL, 0, 0); 1435 } 1436 } 1437 1438 static void 1439 ahc_abort_ccb(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb) 1440 { 1441 union ccb *abort_ccb; 1442 1443 abort_ccb = ccb->cab.abort_ccb; 1444 switch (abort_ccb->ccb_h.func_code) { 1445 case XPT_ACCEPT_TARGET_IO: 1446 case XPT_IMMED_NOTIFY: 1447 case XPT_CONT_TARGET_IO: 1448 { 1449 struct ahc_tmode_tstate *tstate; 1450 struct ahc_tmode_lstate *lstate; 1451 struct ccb_hdr_slist *list; 1452 cam_status status; 1453 1454 status = ahc_find_tmode_devs(ahc, sim, abort_ccb, &tstate, 1455 &lstate, TRUE); 1456 1457 if (status != CAM_REQ_CMP) { 1458 ccb->ccb_h.status = status; 1459 break; 1460 } 1461 1462 if (abort_ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) 1463 list = &lstate->accept_tios; 1464 else if (abort_ccb->ccb_h.func_code == XPT_IMMED_NOTIFY) 1465 list = &lstate->immed_notifies; 1466 else 1467 list = NULL; 1468 1469 if (list != NULL) { 1470 struct ccb_hdr *curelm; 1471 int found; 1472 1473 curelm = SLIST_FIRST(list); 1474 found = 0; 1475 if (curelm == &abort_ccb->ccb_h) { 1476 found = 1; 1477 SLIST_REMOVE_HEAD(list, sim_links.sle); 1478 } else { 1479 while(curelm != NULL) { 1480 struct ccb_hdr *nextelm; 1481 1482 nextelm = 1483 SLIST_NEXT(curelm, sim_links.sle); 1484 1485 if (nextelm == &abort_ccb->ccb_h) { 1486 found = 1; 1487 SLIST_NEXT(curelm, 1488 sim_links.sle) = 1489 SLIST_NEXT(nextelm, 1490 sim_links.sle); 1491 break; 1492 } 1493 curelm = nextelm; 1494 } 1495 } 1496 1497 if (found) { 1498 abort_ccb->ccb_h.status = CAM_REQ_ABORTED; 1499 xpt_done(abort_ccb); 1500 ccb->ccb_h.status = CAM_REQ_CMP; 1501 } else { 1502 xpt_print_path(abort_ccb->ccb_h.path); 1503 printf("Not found\n"); 1504 ccb->ccb_h.status = CAM_PATH_INVALID; 1505 } 1506 break; 1507 } 1508 /* FALLTHROUGH */ 1509 } 1510 case XPT_SCSI_IO: 1511 /* XXX Fully implement the hard ones */ 1512 ccb->ccb_h.status = CAM_UA_ABORT; 1513 break; 1514 default: 1515 ccb->ccb_h.status = CAM_REQ_INVALID; 1516 break; 1517 } 1518 xpt_done(ccb); 1519 } 1520 1521 void 1522 ahc_send_async(struct ahc_softc *ahc, char channel, u_int target, 1523 u_int lun, ac_code code, void *opt_arg) 1524 { 1525 struct ccb_trans_settings cts; 1526 struct cam_path *path; 1527 void *arg; 1528 int error; 1529 1530 arg = NULL; 1531 error = ahc_create_path(ahc, channel, target, lun, &path); 1532 1533 if (error != CAM_REQ_CMP) 1534 return; 1535 1536 switch (code) { 1537 case AC_TRANSFER_NEG: 1538 { 1539 #ifdef AHC_NEW_TRAN_SETTINGS 1540 struct ccb_trans_settings_scsi *scsi; 1541 1542 cts.type = CTS_TYPE_CURRENT_SETTINGS; 1543 scsi = &cts.proto_specific.scsi; 1544 #else 1545 cts.flags = CCB_TRANS_CURRENT_SETTINGS; 1546 #endif 1547 cts.ccb_h.path = path; 1548 cts.ccb_h.target_id = target; 1549 cts.ccb_h.target_lun = lun; 1550 ahc_get_tran_settings(ahc, channel == 'A' ? ahc->our_id 1551 : ahc->our_id_b, 1552 channel, &cts); 1553 arg = &cts; 1554 #ifdef AHC_NEW_TRAN_SETTINGS 1555 scsi->valid &= ~CTS_SCSI_VALID_TQ; 1556 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; 1557 #else 1558 cts.valid &= ~CCB_TRANS_TQ_VALID; 1559 cts.flags &= ~CCB_TRANS_TAG_ENB; 1560 #endif 1561 if (opt_arg == NULL) 1562 break; 1563 if (*((ahc_queue_alg *)opt_arg) == AHC_QUEUE_TAGGED) 1564 #ifdef AHC_NEW_TRAN_SETTINGS 1565 scsi->flags |= ~CTS_SCSI_FLAGS_TAG_ENB; 1566 scsi->valid |= CTS_SCSI_VALID_TQ; 1567 #else 1568 cts.flags |= CCB_TRANS_TAG_ENB; 1569 cts.valid |= CCB_TRANS_TQ_VALID; 1570 #endif 1571 break; 1572 } 1573 case AC_SENT_BDR: 1574 case AC_BUS_RESET: 1575 break; 1576 default: 1577 panic("ahc_send_async: Unexpected async event"); 1578 } 1579 xpt_async(code, path, arg); 1580 xpt_free_path(path); 1581 } 1582 1583 void 1584 ahc_platform_set_tags(struct ahc_softc *ahc, 1585 struct ahc_devinfo *devinfo, int enable) 1586 { 1587 } 1588 1589 int 1590 ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg) 1591 { 1592 ahc->platform_data = malloc(sizeof(struct ahc_platform_data), M_DEVBUF, 1593 M_NOWAIT | M_ZERO); 1594 if (ahc->platform_data == NULL) 1595 return (ENOMEM); 1596 return (0); 1597 } 1598 1599 void 1600 ahc_platform_free(struct ahc_softc *ahc) 1601 { 1602 struct ahc_platform_data *pdata; 1603 1604 pdata = ahc->platform_data; 1605 if (pdata != NULL) { 1606 if (pdata->regs != NULL) 1607 bus_release_resource(ahc->dev_softc, 1608 pdata->regs_res_type, 1609 pdata->regs_res_id, 1610 pdata->regs); 1611 1612 if (pdata->irq != NULL) 1613 bus_release_resource(ahc->dev_softc, 1614 pdata->irq_res_type, 1615 0, pdata->irq); 1616 1617 if (pdata->sim_b != NULL) { 1618 xpt_async(AC_LOST_DEVICE, pdata->path_b, NULL); 1619 xpt_free_path(pdata->path_b); 1620 xpt_bus_deregister(cam_sim_path(pdata->sim_b)); 1621 cam_sim_free(pdata->sim_b, /*free_devq*/TRUE); 1622 } 1623 if (pdata->sim != NULL) { 1624 xpt_async(AC_LOST_DEVICE, pdata->path, NULL); 1625 xpt_free_path(pdata->path); 1626 xpt_bus_deregister(cam_sim_path(pdata->sim)); 1627 cam_sim_free(pdata->sim, /*free_devq*/TRUE); 1628 } 1629 if (pdata->eh != NULL) 1630 EVENTHANDLER_DEREGISTER(shutdown_final, pdata->eh); 1631 free(ahc->platform_data, M_DEVBUF); 1632 } 1633 } 1634 1635 int 1636 ahc_softc_comp(struct ahc_softc *lahc, struct ahc_softc *rahc) 1637 { 1638 /* We don't sort softcs under FreeBSD so report equal always */ 1639 return (0); 1640 } 1641 1642 int 1643 ahc_detach(device_t dev) 1644 { 1645 struct ahc_softc *ahc; 1646 u_long l; 1647 u_long s; 1648 1649 ahc_list_lock(&l); 1650 device_printf(dev, "detaching device\n"); 1651 ahc = device_get_softc(dev); 1652 ahc = ahc_find_softc(ahc); 1653 if (ahc == NULL) { 1654 device_printf(dev, "aic7xxx already detached\n"); 1655 ahc_list_unlock(&l); 1656 return (ENOENT); 1657 } 1658 TAILQ_REMOVE(&ahc_tailq, ahc, links); 1659 ahc_list_unlock(&l); 1660 ahc_lock(ahc, &s); 1661 ahc_intr_enable(ahc, FALSE); 1662 bus_teardown_intr(dev, ahc->platform_data->irq, ahc->platform_data->ih); 1663 ahc_unlock(ahc, &s); 1664 ahc_free(ahc); 1665 return (0); 1666 } 1667 1668 #if 0 1669 static void 1670 ahc_dump_targcmd(struct target_cmd *cmd) 1671 { 1672 uint8_t *byte; 1673 uint8_t *last_byte; 1674 int i; 1675 1676 byte = &cmd->initiator_channel; 1677 /* Debugging info for received commands */ 1678 last_byte = &cmd[1].initiator_channel; 1679 1680 i = 0; 1681 while (byte < last_byte) { 1682 if (i == 0) 1683 printf("\t"); 1684 printf("%#x", *byte++); 1685 i++; 1686 if (i == 8) { 1687 printf("\n"); 1688 i = 0; 1689 } else { 1690 printf(", "); 1691 } 1692 } 1693 } 1694 #endif 1695 1696 static int 1697 ahc_modevent(module_t mod, int type, void *data) 1698 { 1699 /* XXX Deal with busy status on unload. */ 1700 /* XXX Deal with unknown events */ 1701 return 0; 1702 } 1703 1704 static moduledata_t ahc_mod = { 1705 "ahc", 1706 ahc_modevent, 1707 NULL 1708 }; 1709 1710 DECLARE_MODULE(ahc, ahc_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE); 1711 MODULE_DEPEND(ahc, cam, 1, 1, 1); 1712 MODULE_VERSION(ahc, 1); 1713