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