1 /* 2 * Bus independent FreeBSD shim for the aic7xxx based adaptec SCSI controllers 3 * 4 * Copyright (c) 1994-2002 Justin T. Gibbs. 5 * Copyright (c) 2001-2002 Adaptec Inc. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions, and the following disclaimer, 13 * without modification. 14 * 2. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * Alternatively, this software may be distributed under the terms of the 18 * GNU Public License ("GPL"). 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 24 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#27 $ 33 * 34 * $FreeBSD$ 35 */ 36 37 #include <dev/aic7xxx/aic79xx_osm.h> 38 #include <dev/aic7xxx/aic79xx_inline.h> 39 40 #include "opt_ddb.h" 41 #ifdef DDB 42 #include <ddb/ddb.h> 43 #endif 44 45 #ifndef AHD_TMODE_ENABLE 46 #define AHD_TMODE_ENABLE 0 47 #endif 48 49 #define ccb_scb_ptr spriv_ptr0 50 51 #if UNUSED 52 static void ahd_dump_targcmd(struct target_cmd *cmd); 53 #endif 54 static int ahd_modevent(module_t mod, int type, void *data); 55 static void ahd_action(struct cam_sim *sim, union ccb *ccb); 56 static void ahd_set_tran_settings(struct ahd_softc *ahd, 57 int our_id, char channel, 58 struct ccb_trans_settings *cts); 59 static void ahd_get_tran_settings(struct ahd_softc *ahd, 60 int our_id, char channel, 61 struct ccb_trans_settings *cts); 62 static void ahd_async(void *callback_arg, uint32_t code, 63 struct cam_path *path, void *arg); 64 static void ahd_execute_scb(void *arg, bus_dma_segment_t *dm_segs, 65 int nsegments, int error); 66 static void ahd_poll(struct cam_sim *sim); 67 static void ahd_setup_data(struct ahd_softc *ahd, struct cam_sim *sim, 68 struct ccb_scsiio *csio, struct scb *scb); 69 static void ahd_abort_ccb(struct ahd_softc *ahd, struct cam_sim *sim, 70 union ccb *ccb); 71 static int ahd_create_path(struct ahd_softc *ahd, 72 char channel, u_int target, u_int lun, 73 struct cam_path **path); 74 75 #if NOT_YET 76 static void ahd_set_recoveryscb(struct ahd_softc *ahd, struct scb *scb); 77 #endif 78 79 static int 80 ahd_create_path(struct ahd_softc *ahd, char channel, u_int target, 81 u_int lun, struct cam_path **path) 82 { 83 path_id_t path_id; 84 85 if (channel == 'B') 86 path_id = cam_sim_path(ahd->platform_data->sim_b); 87 else 88 path_id = cam_sim_path(ahd->platform_data->sim); 89 90 return (xpt_create_path(path, /*periph*/NULL, 91 path_id, target, lun)); 92 } 93 94 int 95 ahd_map_int(struct ahd_softc *ahd) 96 { 97 int error; 98 99 /* Hook up our interrupt handler */ 100 error = bus_setup_intr(ahd->dev_softc, ahd->platform_data->irq, 101 INTR_TYPE_CAM, ahd_platform_intr, ahd, 102 &ahd->platform_data->ih); 103 if (error != 0) 104 device_printf(ahd->dev_softc, "bus_setup_intr() failed: %d\n", 105 error); 106 return (error); 107 } 108 109 /* 110 * Attach all the sub-devices we can find 111 */ 112 int 113 ahd_attach(struct ahd_softc *ahd) 114 { 115 char ahd_info[256]; 116 struct ccb_setasync csa; 117 struct cam_devq *devq; 118 struct cam_sim *sim; 119 struct cam_path *path; 120 long s; 121 int count; 122 123 count = 0; 124 sim = NULL; 125 126 ahd_controller_info(ahd, ahd_info); 127 printf("%s\n", ahd_info); 128 ahd_lock(ahd, &s); 129 130 /* 131 * Create the device queue for our SIM(s). 132 */ 133 devq = cam_simq_alloc(AHD_MAX_QUEUE); 134 if (devq == NULL) 135 goto fail; 136 137 /* 138 * Construct our SIM entry 139 */ 140 sim = cam_sim_alloc(ahd_action, ahd_poll, "ahd", ahd, 141 device_get_unit(ahd->dev_softc), 142 1, /*XXX*/256, devq); 143 if (sim == NULL) { 144 cam_simq_free(devq); 145 goto fail; 146 } 147 148 if (xpt_bus_register(sim, /*bus_id*/0) != CAM_SUCCESS) { 149 cam_sim_free(sim, /*free_devq*/TRUE); 150 sim = NULL; 151 goto fail; 152 } 153 154 if (xpt_create_path(&path, /*periph*/NULL, 155 cam_sim_path(sim), CAM_TARGET_WILDCARD, 156 CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 157 xpt_bus_deregister(cam_sim_path(sim)); 158 cam_sim_free(sim, /*free_devq*/TRUE); 159 sim = NULL; 160 goto fail; 161 } 162 163 xpt_setup_ccb(&csa.ccb_h, path, /*priority*/5); 164 csa.ccb_h.func_code = XPT_SASYNC_CB; 165 csa.event_enable = AC_LOST_DEVICE; 166 csa.callback = ahd_async; 167 csa.callback_arg = sim; 168 xpt_action((union ccb *)&csa); 169 count++; 170 171 fail: 172 ahd->platform_data->sim = sim; 173 ahd->platform_data->path = path; 174 if (count != 0) { 175 /* We have to wait until after any system dumps... */ 176 ahd->platform_data->eh = 177 EVENTHANDLER_REGISTER(shutdown_final, ahd_shutdown, 178 ahd, SHUTDOWN_PRI_DEFAULT); 179 ahd_intr_enable(ahd, TRUE); 180 } 181 182 ahd_unlock(ahd, &s); 183 184 return (count); 185 } 186 187 /* 188 * Catch an interrupt from the adapter 189 */ 190 void 191 ahd_platform_intr(void *arg) 192 { 193 struct ahd_softc *ahd; 194 195 ahd = (struct ahd_softc *)arg; 196 ahd_intr(ahd); 197 } 198 199 /* 200 * We have an scb which has been processed by the 201 * adaptor, now we look to see how the operation 202 * went. 203 */ 204 void 205 ahd_done(struct ahd_softc *ahd, struct scb *scb) 206 { 207 union ccb *ccb; 208 209 CAM_DEBUG(scb->io_ctx->ccb_h.path, CAM_DEBUG_TRACE, 210 ("ahd_done - scb %d\n", SCB_GET_TAG(scb))); 211 212 ccb = scb->io_ctx; 213 LIST_REMOVE(scb, pending_links); 214 215 untimeout(ahd_timeout, (caddr_t)scb, ccb->ccb_h.timeout_ch); 216 217 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 218 bus_dmasync_op_t op; 219 220 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) 221 op = BUS_DMASYNC_POSTREAD; 222 else 223 op = BUS_DMASYNC_POSTWRITE; 224 bus_dmamap_sync(ahd->buffer_dmat, scb->dmamap, op); 225 bus_dmamap_unload(ahd->buffer_dmat, scb->dmamap); 226 } 227 228 #ifdef AHD_TARGET_MODE 229 if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) { 230 struct cam_path *ccb_path; 231 232 /* 233 * If we have finally disconnected, clean up our 234 * pending device state. 235 * XXX - There may be error states that cause where 236 * we will remain connected. 237 */ 238 ccb_path = ccb->ccb_h.path; 239 if (ahd->pending_device != NULL 240 && xpt_path_comp(ahd->pending_device->path, ccb_path) == 0) { 241 242 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) { 243 ahd->pending_device = NULL; 244 } else { 245 xpt_print_path(ccb->ccb_h.path); 246 printf("Still disconnected\n"); 247 ahd_freeze_ccb(ccb); 248 } 249 } 250 251 if (ahd_get_transaction_status(scb) == CAM_REQ_INPROG) 252 ccb->ccb_h.status |= CAM_REQ_CMP; 253 ccb->ccb_h.status &= ~CAM_SIM_QUEUED; 254 ahd_free_scb(ahd, scb); 255 xpt_done(ccb); 256 return; 257 } 258 #endif 259 260 /* 261 * If the recovery SCB completes, we have to be 262 * out of our timeout. 263 */ 264 if ((scb->flags & SCB_RECOVERY_SCB) != 0) { 265 struct scb *list_scb; 266 267 /* 268 * We were able to complete the command successfully, 269 * so reinstate the timeouts for all other pending 270 * commands. 271 */ 272 LIST_FOREACH(list_scb, &ahd->pending_scbs, pending_links) { 273 union ccb *ccb; 274 uint64_t time; 275 276 ccb = list_scb->io_ctx; 277 if (ccb->ccb_h.timeout == CAM_TIME_INFINITY) 278 continue; 279 280 time = ccb->ccb_h.timeout; 281 time *= hz; 282 time /= 1000; 283 ccb->ccb_h.timeout_ch = 284 timeout(ahd_timeout, list_scb, time); 285 } 286 287 if (ahd_get_transaction_status(scb) == CAM_BDR_SENT 288 || ahd_get_transaction_status(scb) == CAM_REQ_ABORTED) 289 ahd_set_transaction_status(scb, CAM_CMD_TIMEOUT); 290 ahd_print_path(ahd, scb); 291 printf("no longer in timeout, status = %x\n", 292 ccb->ccb_h.status); 293 } 294 295 /* Don't clobber any existing error state */ 296 if (ahd_get_transaction_status(scb) == CAM_REQ_INPROG) { 297 ccb->ccb_h.status |= CAM_REQ_CMP; 298 } else if ((scb->flags & SCB_SENSE) != 0) { 299 /* 300 * We performed autosense retrieval. 301 * 302 * Zero any sense not transferred by the 303 * device. The SCSI spec mandates that any 304 * untransfered data should be assumed to be 305 * zero. Complete the 'bounce' of sense information 306 * through buffers accessible via bus-space by 307 * copying it into the clients csio. 308 */ 309 memset(&ccb->csio.sense_data, 0, sizeof(ccb->csio.sense_data)); 310 memcpy(&ccb->csio.sense_data, 311 ahd_get_sense_buf(ahd, scb), 312 /* XXX What size do we want to use??? */ 313 sizeof(ccb->csio.sense_data) 314 - ccb->csio.sense_resid); 315 scb->io_ctx->ccb_h.status |= CAM_AUTOSNS_VALID; 316 } else if ((scb->flags & SCB_PKT_SENSE) != 0) { 317 struct scsi_status_iu_header *siu; 318 u_int sense_len; 319 int i; 320 321 /* 322 * Copy only the sense data into the provided buffer. 323 */ 324 siu = (struct scsi_status_iu_header *)scb->sense_data; 325 sense_len = MIN(scsi_4btoul(siu->sense_length), 326 sizeof(ccb->csio.sense_data)); 327 memset(&ccb->csio.sense_data, 0, sizeof(ccb->csio.sense_data)); 328 memcpy(&ccb->csio.sense_data, 329 ahd_get_sense_buf(ahd, scb) + SIU_SENSE_OFFSET(siu), 330 sense_len); 331 printf("Copied %d bytes of sense data offset %d:", sense_len, 332 SIU_SENSE_OFFSET(siu)); 333 for (i = 0; i < sense_len; i++) 334 printf(" 0x%x", ((uint8_t *)&ccb->csio.sense_data)[i]); 335 printf("\n"); 336 scb->io_ctx->ccb_h.status |= CAM_AUTOSNS_VALID; 337 } 338 ccb->ccb_h.status &= ~CAM_SIM_QUEUED; 339 ahd_free_scb(ahd, scb); 340 xpt_done(ccb); 341 } 342 343 static void 344 ahd_action(struct cam_sim *sim, union ccb *ccb) 345 { 346 struct ahd_softc *ahd; 347 #ifdef AHD_TARGET_MODE 348 struct ahd_tmode_lstate *lstate; 349 #endif 350 u_int target_id; 351 u_int our_id; 352 long s; 353 354 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("ahd_action\n")); 355 356 ahd = (struct ahd_softc *)cam_sim_softc(sim); 357 358 target_id = ccb->ccb_h.target_id; 359 our_id = SIM_SCSI_ID(ahd, sim); 360 361 switch (ccb->ccb_h.func_code) { 362 /* Common cases first */ 363 #ifdef AHD_TARGET_MODE 364 case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */ 365 case XPT_CONT_TARGET_IO:/* Continue Host Target I/O Connection*/ 366 { 367 struct ahd_tmode_tstate *tstate; 368 cam_status status; 369 370 status = ahd_find_tmode_devs(ahd, sim, ccb, &tstate, 371 &lstate, TRUE); 372 373 if (status != CAM_REQ_CMP) { 374 if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) { 375 /* Response from the black hole device */ 376 tstate = NULL; 377 lstate = ahd->black_hole; 378 } else { 379 ccb->ccb_h.status = status; 380 xpt_done(ccb); 381 break; 382 } 383 } 384 if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) { 385 386 ahd_lock(ahd, &s); 387 SLIST_INSERT_HEAD(&lstate->accept_tios, &ccb->ccb_h, 388 sim_links.sle); 389 ccb->ccb_h.status = CAM_REQ_INPROG; 390 if ((ahd->flags & AHD_TQINFIFO_BLOCKED) != 0) 391 ahd_run_tqinfifo(ahd, /*paused*/FALSE); 392 ahd_unlock(ahd, &s); 393 break; 394 } 395 396 /* 397 * The target_id represents the target we attempt to 398 * select. In target mode, this is the initiator of 399 * the original command. 400 */ 401 our_id = target_id; 402 target_id = ccb->csio.init_id; 403 /* FALLTHROUGH */ 404 } 405 #endif 406 case XPT_SCSI_IO: /* Execute the requested I/O operation */ 407 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */ 408 { 409 struct scb *scb; 410 struct hardware_scb *hscb; 411 struct ahd_initiator_tinfo *tinfo; 412 struct ahd_tmode_tstate *tstate; 413 u_int col_idx; 414 415 if ((ahd->flags & AHD_INITIATORROLE) == 0 416 && (ccb->ccb_h.func_code == XPT_SCSI_IO 417 || ccb->ccb_h.func_code == XPT_RESET_DEV)) { 418 ccb->ccb_h.status = CAM_PROVIDE_FAIL; 419 xpt_done(ccb); 420 return; 421 } 422 423 /* 424 * get an scb to use. 425 */ 426 ahd_lock(ahd, &s); 427 tinfo = ahd_fetch_transinfo(ahd, 'A', our_id, 428 target_id, &tstate); 429 if ((ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) == 0 430 || (tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0 431 || ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) { 432 col_idx = AHD_NEVER_COL_IDX; 433 } else { 434 col_idx = AHD_BUILD_COL_IDX(target_id, 435 ccb->ccb_h.target_lun); 436 } 437 if ((scb = ahd_get_scb(ahd, col_idx)) == NULL) { 438 439 xpt_freeze_simq(sim, /*count*/1); 440 ahd->flags |= AHD_RESOURCE_SHORTAGE; 441 ahd_unlock(ahd, &s); 442 ccb->ccb_h.status = CAM_REQUEUE_REQ; 443 xpt_done(ccb); 444 return; 445 } 446 ahd_unlock(ahd, &s); 447 448 hscb = scb->hscb; 449 450 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_SUBTRACE, 451 ("start scb(%p)\n", scb)); 452 scb->io_ctx = ccb; 453 /* 454 * So we can find the SCB when an abort is requested 455 */ 456 ccb->ccb_h.ccb_scb_ptr = scb; 457 458 /* 459 * Put all the arguments for the xfer in the scb 460 */ 461 hscb->control = 0; 462 hscb->scsiid = BUILD_SCSIID(ahd, sim, target_id, our_id); 463 hscb->lun = ccb->ccb_h.target_lun; 464 if (ccb->ccb_h.func_code == XPT_RESET_DEV) { 465 hscb->cdb_len = 0; 466 scb->flags |= SCB_DEVICE_RESET; 467 hscb->control |= MK_MESSAGE; 468 hscb->task_management = SIU_TASKMGMT_LUN_RESET; 469 ahd_execute_scb(scb, NULL, 0, 0); 470 } else { 471 #ifdef AHD_TARGET_MODE 472 if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) { 473 struct target_data *tdata; 474 475 tdata = &hscb->shared_data.tdata; 476 if (ahd->pending_device == lstate) 477 scb->flags |= SCB_TARGET_IMMEDIATE; 478 hscb->control |= TARGET_SCB; 479 tdata->target_phases = 0; 480 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) { 481 tdata->target_phases |= SPHASE_PENDING; 482 tdata->scsi_status = 483 ccb->csio.scsi_status; 484 } 485 if (ccb->ccb_h.flags & CAM_DIS_DISCONNECT) 486 tdata->target_phases |= NO_DISCONNECT; 487 488 tdata->initiator_tag = 489 ahd_htole16(ccb->csio.tag_id); 490 } 491 #endif 492 hscb->task_management = 0; 493 if (ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) 494 hscb->control |= ccb->csio.tag_action; 495 496 ahd_setup_data(ahd, sim, &ccb->csio, scb); 497 } 498 break; 499 } 500 #ifdef AHD_TARGET_MODE 501 case XPT_NOTIFY_ACK: 502 case XPT_IMMED_NOTIFY: 503 { 504 struct ahd_tmode_tstate *tstate; 505 struct ahd_tmode_lstate *lstate; 506 cam_status status; 507 508 status = ahd_find_tmode_devs(ahd, sim, ccb, &tstate, 509 &lstate, TRUE); 510 511 if (status != CAM_REQ_CMP) { 512 ccb->ccb_h.status = status; 513 xpt_done(ccb); 514 break; 515 } 516 SLIST_INSERT_HEAD(&lstate->immed_notifies, &ccb->ccb_h, 517 sim_links.sle); 518 ccb->ccb_h.status = CAM_REQ_INPROG; 519 ahd_send_lstate_events(ahd, lstate); 520 break; 521 } 522 case XPT_EN_LUN: /* Enable LUN as a target */ 523 ahd_handle_en_lun(ahd, sim, ccb); 524 xpt_done(ccb); 525 break; 526 #endif 527 case XPT_ABORT: /* Abort the specified CCB */ 528 { 529 ahd_abort_ccb(ahd, sim, ccb); 530 break; 531 } 532 case XPT_SET_TRAN_SETTINGS: 533 { 534 ahd_lock(ahd, &s); 535 ahd_set_tran_settings(ahd, SIM_SCSI_ID(ahd, sim), 536 SIM_CHANNEL(ahd, sim), &ccb->cts); 537 ahd_unlock(ahd, &s); 538 xpt_done(ccb); 539 break; 540 } 541 case XPT_GET_TRAN_SETTINGS: 542 /* Get default/user set transfer settings for the target */ 543 { 544 ahd_lock(ahd, &s); 545 ahd_get_tran_settings(ahd, SIM_SCSI_ID(ahd, sim), 546 SIM_CHANNEL(ahd, sim), &ccb->cts); 547 ahd_unlock(ahd, &s); 548 xpt_done(ccb); 549 break; 550 } 551 case XPT_CALC_GEOMETRY: 552 { 553 int extended; 554 555 extended = ahd->flags & AHD_EXTENDED_TRANS_A; 556 cam_calc_geometry(&ccb->ccg, extended); 557 xpt_done(ccb); 558 break; 559 } 560 case XPT_RESET_BUS: /* Reset the specified SCSI bus */ 561 { 562 int found; 563 564 ahd_lock(ahd, &s); 565 found = ahd_reset_channel(ahd, SIM_CHANNEL(ahd, sim), 566 /*initiate reset*/TRUE); 567 ahd_unlock(ahd, &s); 568 if (bootverbose) { 569 xpt_print_path(SIM_PATH(ahd, sim)); 570 printf("SCSI bus reset delivered. " 571 "%d SCBs aborted.\n", found); 572 } 573 ccb->ccb_h.status = CAM_REQ_CMP; 574 xpt_done(ccb); 575 break; 576 } 577 case XPT_TERM_IO: /* Terminate the I/O process */ 578 /* XXX Implement */ 579 ccb->ccb_h.status = CAM_REQ_INVALID; 580 xpt_done(ccb); 581 break; 582 case XPT_PATH_INQ: /* Path routing inquiry */ 583 { 584 struct ccb_pathinq *cpi = &ccb->cpi; 585 586 cpi->version_num = 1; /* XXX??? */ 587 cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE; 588 if ((ahd->features & AHD_WIDE) != 0) 589 cpi->hba_inquiry |= PI_WIDE_16; 590 if ((ahd->features & AHD_TARGETMODE) != 0) { 591 cpi->target_sprt = PIT_PROCESSOR 592 | PIT_DISCONNECT 593 | PIT_TERM_IO; 594 } else { 595 cpi->target_sprt = 0; 596 } 597 cpi->hba_misc = 0; 598 cpi->hba_eng_cnt = 0; 599 cpi->max_target = (ahd->features & AHD_WIDE) ? 15 : 7; 600 cpi->max_lun = AHD_NUM_LUNS - 1; 601 cpi->initiator_id = ahd->our_id; 602 if ((ahd->flags & AHD_RESET_BUS_A) == 0) { 603 cpi->hba_misc |= PIM_NOBUSRESET; 604 } 605 cpi->bus_id = cam_sim_bus(sim); 606 cpi->base_transfer_speed = 3300; 607 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 608 strncpy(cpi->hba_vid, "Adaptec", HBA_IDLEN); 609 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 610 cpi->unit_number = cam_sim_unit(sim); 611 #ifdef AHD_NEW_TRAN_SETTINGS 612 cpi->protocol = PROTO_SCSI; 613 cpi->protocol_version = SCSI_REV_2; 614 cpi->transport = XPORT_SPI; 615 cpi->transport_version = 2; 616 cpi->xport_specific.spi.ppr_options = SID_SPI_CLOCK_ST; 617 cpi->transport_version = 4; 618 cpi->xport_specific.spi.ppr_options = SID_SPI_CLOCK_DT_ST; 619 #endif 620 cpi->ccb_h.status = CAM_REQ_CMP; 621 xpt_done(ccb); 622 break; 623 } 624 default: 625 ccb->ccb_h.status = CAM_PROVIDE_FAIL; 626 xpt_done(ccb); 627 break; 628 } 629 } 630 631 632 static void 633 ahd_set_tran_settings(struct ahd_softc *ahd, int our_id, char channel, 634 struct ccb_trans_settings *cts) 635 { 636 #ifdef AHD_NEW_TRAN_SETTINGS 637 struct ahd_devinfo devinfo; 638 struct ccb_trans_settings_scsi *scsi; 639 struct ccb_trans_settings_spi *spi; 640 struct ahd_initiator_tinfo *tinfo; 641 struct ahd_tmode_tstate *tstate; 642 uint16_t *discenable; 643 uint16_t *tagenable; 644 u_int update_type; 645 646 scsi = &cts->proto_specific.scsi; 647 spi = &cts->xport_specific.spi; 648 ahd_compile_devinfo(&devinfo, SIM_SCSI_ID(ahd, sim), 649 cts->ccb_h.target_id, 650 cts->ccb_h.target_lun, 651 SIM_CHANNEL(ahd, sim), 652 ROLE_UNKNOWN); 653 tinfo = ahd_fetch_transinfo(ahd, devinfo.channel, 654 devinfo.our_scsiid, 655 devinfo.target, &tstate); 656 update_type = 0; 657 if (cts->type == CTS_TYPE_CURRENT_SETTINGS) { 658 update_type |= AHD_TRANS_GOAL; 659 discenable = &tstate->discenable; 660 tagenable = &tstate->tagenable; 661 tinfo->curr.protocol_version = cts->protocol_version; 662 tinfo->curr.transport_version = cts->transport_version; 663 tinfo->goal.protocol_version = cts->protocol_version; 664 tinfo->goal.transport_version = cts->transport_version; 665 } else if (cts->type == CTS_TYPE_USER_SETTINGS) { 666 update_type |= AHD_TRANS_USER; 667 discenable = &ahd->user_discenable; 668 tagenable = &ahd->user_tagenable; 669 tinfo->user.protocol_version = cts->protocol_version; 670 tinfo->user.transport_version = cts->transport_version; 671 } else { 672 cts->ccb_h.status = CAM_REQ_INVALID; 673 return; 674 } 675 676 if ((spi->valid & CTS_SPI_VALID_DISC) != 0) { 677 if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0) 678 *discenable |= devinfo.target_mask; 679 else 680 *discenable &= ~devinfo.target_mask; 681 } 682 683 if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) { 684 if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) 685 *tagenable |= devinfo.target_mask; 686 else 687 *tagenable &= ~devinfo.target_mask; 688 } 689 690 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) { 691 ahd_validate_width(ahd, /*tinfo limit*/NULL, 692 &spi->bus_width, ROLE_UNKNOWN); 693 ahd_set_width(ahd, &devinfo, spi->bus_width, 694 update_type, /*paused*/FALSE); 695 } 696 697 if ((spi->valid & CTS_SPI_VALID_PPR_OPTIONS) == 0) { 698 if (update_type == AHD_TRANS_USER) 699 spi->ppr_options = tinfo->user.ppr_options; 700 else 701 spi->ppr_options = tinfo->goal.ppr_options; 702 } 703 704 if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) == 0) { 705 if (update_type == AHD_TRANS_USER) 706 spi->sync_offset = tinfo->user.offset; 707 else 708 spi->sync_offset = tinfo->goal.offset; 709 } 710 711 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) == 0) { 712 if (update_type == AHD_TRANS_USER) 713 spi->sync_period = tinfo->user.period; 714 else 715 spi->sync_period = tinfo->goal.period; 716 } 717 718 if (((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) 719 || ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)) { 720 u_int maxsync; 721 722 maxsync = AHD_SYNCRATE_MAX; 723 724 if (spi->bus_width != MSG_EXT_WDTR_BUS_16_BIT) 725 spi->ppr_options &= ~MSG_EXT_PPR_DT_REQ; 726 727 if ((*discenable & devinfo.target_mask) == 0) 728 spi->ppr_options &= ~MSG_EXT_PPR_IU_REQ; 729 730 ahd_find_syncrate(ahd, &spi->sync_period, 731 &spi->ppr_options, maxsync); 732 ahd_validate_offset(ahd, /*tinfo limit*/NULL, 733 spi->sync_period, &spi->sync_offset, 734 spi->bus_width, ROLE_UNKNOWN); 735 736 /* We use a period of 0 to represent async */ 737 if (spi->sync_offset == 0) { 738 spi->sync_period = 0; 739 spi->ppr_options = 0; 740 } 741 742 ahd_set_syncrate(ahd, &devinfo, spi->sync_period, 743 spi->sync_offset, spi->ppr_options, 744 update_type, /*paused*/FALSE); 745 } 746 cts->ccb_h.status = CAM_REQ_CMP; 747 #else 748 struct ahd_devinfo devinfo; 749 struct ahd_initiator_tinfo *tinfo; 750 struct ahd_tmode_tstate *tstate; 751 uint16_t *discenable; 752 uint16_t *tagenable; 753 u_int update_type; 754 755 ahd_compile_devinfo(&devinfo, SIM_SCSI_ID(ahd, sim), 756 cts->ccb_h.target_id, 757 cts->ccb_h.target_lun, 758 SIM_CHANNEL(ahd, sim), 759 ROLE_UNKNOWN); 760 tinfo = ahd_fetch_transinfo(ahd, devinfo.channel, 761 devinfo.our_scsiid, 762 devinfo.target, &tstate); 763 update_type = 0; 764 if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0) { 765 update_type |= AHD_TRANS_GOAL; 766 discenable = &tstate->discenable; 767 tagenable = &tstate->tagenable; 768 } else if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) { 769 update_type |= AHD_TRANS_USER; 770 discenable = &ahd->user_discenable; 771 tagenable = &ahd->user_tagenable; 772 } else { 773 cts->ccb_h.status = CAM_REQ_INVALID; 774 return; 775 } 776 777 if ((cts->valid & CCB_TRANS_DISC_VALID) != 0) { 778 if ((cts->flags & CCB_TRANS_DISC_ENB) != 0) 779 *discenable |= devinfo.target_mask; 780 else 781 *discenable &= ~devinfo.target_mask; 782 } 783 784 if ((cts->valid & CCB_TRANS_TQ_VALID) != 0) { 785 if ((cts->flags & CCB_TRANS_TAG_ENB) != 0) 786 *tagenable |= devinfo.target_mask; 787 else 788 *tagenable &= ~devinfo.target_mask; 789 } 790 791 if ((cts->valid & CCB_TRANS_BUS_WIDTH_VALID) != 0) { 792 ahd_validate_width(ahd, /*tinfo limit*/NULL, 793 &cts->bus_width, ROLE_UNKNOWN); 794 ahd_set_width(ahd, &devinfo, cts->bus_width, 795 update_type, /*paused*/FALSE); 796 } 797 798 if ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) == 0) { 799 if (update_type == AHD_TRANS_USER) 800 cts->sync_offset = tinfo->user.offset; 801 else 802 cts->sync_offset = tinfo->goal.offset; 803 } 804 805 if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) == 0) { 806 if (update_type == AHD_TRANS_USER) 807 cts->sync_period = tinfo->user.period; 808 else 809 cts->sync_period = tinfo->goal.period; 810 } 811 812 if (((cts->valid & CCB_TRANS_SYNC_RATE_VALID) != 0) 813 || ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) != 0) 814 || ((cts->valid & CCB_TRANS_TQ_VALID) != 0) 815 || ((cts->valid & CCB_TRANS_DISC_VALID) != 0)) { 816 u_int ppr_options; 817 u_int maxsync; 818 819 maxsync = AHD_SYNCRATE_MAX; 820 ppr_options = 0; 821 if (cts->sync_period <= AHD_SYNCRATE_DT 822 && cts->bus_width == MSG_EXT_WDTR_BUS_16_BIT) { 823 ppr_options = tinfo->user.ppr_options 824 | MSG_EXT_PPR_DT_REQ; 825 } 826 827 if ((*tagenable & devinfo.target_mask) == 0 828 || (*discenable & devinfo.target_mask) == 0) 829 ppr_options &= ~MSG_EXT_PPR_IU_REQ; 830 831 ahd_find_syncrate(ahd, &cts->sync_period, 832 &ppr_options, maxsync); 833 ahd_validate_offset(ahd, /*tinfo limit*/NULL, 834 cts->sync_period, &cts->sync_offset, 835 MSG_EXT_WDTR_BUS_8_BIT, 836 ROLE_UNKNOWN); 837 838 /* We use a period of 0 to represent async */ 839 if (cts->sync_offset == 0) { 840 cts->sync_period = 0; 841 ppr_options = 0; 842 } 843 844 if (ppr_options != 0 845 && tinfo->user.transport_version >= 3) { 846 tinfo->goal.transport_version = 847 tinfo->user.transport_version; 848 tinfo->curr.transport_version = 849 tinfo->user.transport_version; 850 } 851 852 ahd_set_syncrate(ahd, &devinfo, cts->sync_period, 853 cts->sync_offset, ppr_options, 854 update_type, /*paused*/FALSE); 855 } 856 cts->ccb_h.status = CAM_REQ_CMP; 857 #endif 858 } 859 860 static void 861 ahd_get_tran_settings(struct ahd_softc *ahd, int our_id, char channel, 862 struct ccb_trans_settings *cts) 863 { 864 #ifdef AHD_NEW_TRAN_SETTINGS 865 struct ahd_devinfo devinfo; 866 struct ccb_trans_settings_scsi *scsi; 867 struct ccb_trans_settings_spi *spi; 868 struct ahd_initiator_tinfo *targ_info; 869 struct ahd_tmode_tstate *tstate; 870 struct ahd_transinfo *tinfo; 871 872 scsi = &cts->proto_specific.scsi; 873 spi = &cts->xport_specific.spi; 874 ahd_compile_devinfo(&devinfo, our_id, 875 cts->ccb_h.target_id, 876 cts->ccb_h.target_lun, 877 channel, ROLE_UNKNOWN); 878 targ_info = ahd_fetch_transinfo(ahd, devinfo.channel, 879 devinfo.our_scsiid, 880 devinfo.target, &tstate); 881 882 if (cts->type == CTS_TYPE_CURRENT_SETTINGS) 883 tinfo = &targ_info->curr; 884 else 885 tinfo = &targ_info->user; 886 887 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; 888 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB; 889 if (cts->type == CTS_TYPE_USER_SETTINGS) { 890 if ((ahd->user_discenable & devinfo.target_mask) != 0) 891 spi->flags |= CTS_SPI_FLAGS_DISC_ENB; 892 893 if ((ahd->user_tagenable & devinfo.target_mask) != 0) 894 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; 895 } else { 896 if ((tstate->discenable & devinfo.target_mask) != 0) 897 spi->flags |= CTS_SPI_FLAGS_DISC_ENB; 898 899 if ((tstate->tagenable & devinfo.target_mask) != 0) 900 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; 901 } 902 cts->protocol_version = tinfo->protocol_version; 903 cts->transport_version = tinfo->transport_version; 904 905 spi->sync_period = tinfo->period; 906 spi->sync_offset = tinfo->offset; 907 spi->bus_width = tinfo->width; 908 spi->ppr_options = tinfo->ppr_options; 909 910 cts->protocol = PROTO_SCSI; 911 cts->transport = XPORT_SPI; 912 spi->valid = CTS_SPI_VALID_SYNC_RATE 913 | CTS_SPI_VALID_SYNC_OFFSET 914 | CTS_SPI_VALID_BUS_WIDTH 915 | CTS_SPI_VALID_PPR_OPTIONS; 916 917 if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) { 918 scsi->valid = CTS_SCSI_VALID_TQ; 919 spi->valid |= CTS_SPI_VALID_DISC; 920 } else { 921 scsi->valid = 0; 922 } 923 924 cts->ccb_h.status = CAM_REQ_CMP; 925 #else 926 struct ahd_devinfo devinfo; 927 struct ahd_initiator_tinfo *targ_info; 928 struct ahd_tmode_tstate *tstate; 929 struct ahd_transinfo *tinfo; 930 931 ahd_compile_devinfo(&devinfo, our_id, 932 cts->ccb_h.target_id, 933 cts->ccb_h.target_lun, 934 channel, ROLE_UNKNOWN); 935 targ_info = ahd_fetch_transinfo(ahd, devinfo.channel, 936 devinfo.our_scsiid, 937 devinfo.target, &tstate); 938 939 if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0) 940 tinfo = &targ_info->curr; 941 else 942 tinfo = &targ_info->user; 943 944 cts->flags &= ~(CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB); 945 if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) == 0) { 946 if ((ahd->user_discenable & devinfo.target_mask) != 0) 947 cts->flags |= CCB_TRANS_DISC_ENB; 948 949 if ((ahd->user_tagenable & devinfo.target_mask) != 0) 950 cts->flags |= CCB_TRANS_TAG_ENB; 951 } else { 952 if ((tstate->discenable & devinfo.target_mask) != 0) 953 cts->flags |= CCB_TRANS_DISC_ENB; 954 955 if ((tstate->tagenable & devinfo.target_mask) != 0) 956 cts->flags |= CCB_TRANS_TAG_ENB; 957 } 958 cts->sync_period = tinfo->period; 959 cts->sync_offset = tinfo->offset; 960 cts->bus_width = tinfo->width; 961 962 cts->valid = CCB_TRANS_SYNC_RATE_VALID 963 | CCB_TRANS_SYNC_OFFSET_VALID 964 | CCB_TRANS_BUS_WIDTH_VALID; 965 966 if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) 967 cts->valid |= CCB_TRANS_DISC_VALID|CCB_TRANS_TQ_VALID; 968 969 cts->ccb_h.status = CAM_REQ_CMP; 970 #endif 971 } 972 973 static void 974 ahd_async(void *callback_arg, uint32_t code, struct cam_path *path, void *arg) 975 { 976 struct ahd_softc *ahd; 977 struct cam_sim *sim; 978 979 sim = (struct cam_sim *)callback_arg; 980 ahd = (struct ahd_softc *)cam_sim_softc(sim); 981 switch (code) { 982 case AC_LOST_DEVICE: 983 { 984 struct ahd_devinfo devinfo; 985 long s; 986 987 ahd_compile_devinfo(&devinfo, SIM_SCSI_ID(ahd, sim), 988 xpt_path_target_id(path), 989 xpt_path_lun_id(path), 990 SIM_CHANNEL(ahd, sim), 991 ROLE_UNKNOWN); 992 993 /* 994 * Revert to async/narrow transfers 995 * for the next device. 996 */ 997 ahd_lock(ahd, &s); 998 ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, 999 AHD_TRANS_GOAL|AHD_TRANS_CUR, /*paused*/FALSE); 1000 ahd_set_syncrate(ahd, &devinfo, /*period*/0, /*offset*/0, 1001 /*ppr_options*/0, AHD_TRANS_GOAL|AHD_TRANS_CUR, 1002 /*paused*/FALSE); 1003 ahd_unlock(ahd, &s); 1004 break; 1005 } 1006 default: 1007 break; 1008 } 1009 } 1010 1011 static void 1012 ahd_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments, 1013 int error) 1014 { 1015 struct scb *scb; 1016 union ccb *ccb; 1017 struct ahd_softc *ahd; 1018 struct ahd_initiator_tinfo *tinfo; 1019 struct ahd_tmode_tstate *tstate; 1020 u_int mask; 1021 u_long s; 1022 1023 scb = (struct scb *)arg; 1024 ccb = scb->io_ctx; 1025 ahd = scb->ahd_softc; 1026 1027 if (error != 0) { 1028 if (error == EFBIG) 1029 ahd_set_transaction_status(scb, CAM_REQ_TOO_BIG); 1030 else 1031 ahd_set_transaction_status(scb, CAM_REQ_CMP_ERR); 1032 if (nsegments != 0) 1033 bus_dmamap_unload(ahd->buffer_dmat, scb->dmamap); 1034 ahd_lock(ahd, &s); 1035 ahd_free_scb(ahd, scb); 1036 ahd_unlock(ahd, &s); 1037 xpt_done(ccb); 1038 return; 1039 } 1040 scb->sg_count = 0; 1041 if (nsegments != 0) { 1042 void *sg; 1043 bus_dmasync_op_t op; 1044 u_int i; 1045 1046 /* Copy the segments into our SG list */ 1047 for (i = nsegments, sg = scb->sg_list; i > 0; i--) { 1048 1049 sg = ahd_sg_setup(ahd, scb, sg, dm_segs->ds_addr, 1050 dm_segs->ds_len, 1051 /*last*/i == 1); 1052 dm_segs++; 1053 } 1054 1055 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) 1056 op = BUS_DMASYNC_PREREAD; 1057 else 1058 op = BUS_DMASYNC_PREWRITE; 1059 1060 bus_dmamap_sync(ahd->buffer_dmat, scb->dmamap, op); 1061 1062 if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) { 1063 struct target_data *tdata; 1064 1065 tdata = &scb->hscb->shared_data.tdata; 1066 tdata->target_phases |= DPHASE_PENDING; 1067 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) 1068 tdata->data_phase = P_DATAOUT; 1069 else 1070 tdata->data_phase = P_DATAIN; 1071 } 1072 } 1073 1074 ahd_lock(ahd, &s); 1075 1076 /* 1077 * Last time we need to check if this SCB needs to 1078 * be aborted. 1079 */ 1080 if (ahd_get_transaction_status(scb) != CAM_REQ_INPROG) { 1081 if (nsegments != 0) 1082 bus_dmamap_unload(ahd->buffer_dmat, 1083 scb->dmamap); 1084 ahd_free_scb(ahd, scb); 1085 ahd_unlock(ahd, &s); 1086 xpt_done(ccb); 1087 return; 1088 } 1089 1090 tinfo = ahd_fetch_transinfo(ahd, SCSIID_CHANNEL(ahd, scb->hscb->scsiid), 1091 SCSIID_OUR_ID(scb->hscb->scsiid), 1092 SCSIID_TARGET(ahd, scb->hscb->scsiid), 1093 &tstate); 1094 1095 mask = SCB_GET_TARGET_MASK(ahd, scb); 1096 1097 if ((tstate->discenable & mask) != 0 1098 && (ccb->ccb_h.flags & CAM_DIS_DISCONNECT) == 0) 1099 scb->hscb->control |= DISCENB; 1100 1101 if ((tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0) { 1102 scb->flags |= SCB_PACKETIZED; 1103 if (scb->hscb->task_management != 0) 1104 scb->hscb->control &= ~MK_MESSAGE; 1105 } 1106 1107 if ((ccb->ccb_h.flags & CAM_NEGOTIATE) != 0 1108 && (tinfo->goal.width != 0 1109 || tinfo->goal.period != 0 1110 || tinfo->goal.ppr_options != 0)) { 1111 scb->flags |= SCB_NEGOTIATE; 1112 scb->hscb->control |= MK_MESSAGE; 1113 } else if ((tstate->auto_negotiate & mask) != 0) { 1114 scb->flags |= SCB_AUTO_NEGOTIATE; 1115 scb->hscb->control |= MK_MESSAGE; 1116 } 1117 1118 LIST_INSERT_HEAD(&ahd->pending_scbs, scb, pending_links); 1119 1120 ccb->ccb_h.status |= CAM_SIM_QUEUED; 1121 1122 if (ccb->ccb_h.timeout != CAM_TIME_INFINITY) { 1123 uint64_t time; 1124 1125 if (ccb->ccb_h.timeout == CAM_TIME_DEFAULT) 1126 ccb->ccb_h.timeout = 5 * 1000; 1127 1128 time = ccb->ccb_h.timeout; 1129 time *= hz; 1130 time /= 1000; 1131 ccb->ccb_h.timeout_ch = 1132 timeout(ahd_timeout, (caddr_t)scb, time); 1133 } 1134 1135 if ((scb->flags & SCB_TARGET_IMMEDIATE) != 0) { 1136 /* Define a mapping from our tag to the SCB. */ 1137 ahd->scb_data.scbindex[SCB_GET_TAG(scb)] = scb; 1138 ahd_pause(ahd); 1139 ahd_set_scbptr(ahd, SCB_GET_TAG(scb)); 1140 ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_TARG); 1141 ahd_unpause(ahd); 1142 } else { 1143 ahd_queue_scb(ahd, scb); 1144 } 1145 1146 ahd_unlock(ahd, &s); 1147 } 1148 1149 static void 1150 ahd_poll(struct cam_sim *sim) 1151 { 1152 ahd_intr(cam_sim_softc(sim)); 1153 } 1154 1155 static void 1156 ahd_setup_data(struct ahd_softc *ahd, struct cam_sim *sim, 1157 struct ccb_scsiio *csio, struct scb *scb) 1158 { 1159 struct hardware_scb *hscb; 1160 struct ccb_hdr *ccb_h; 1161 1162 hscb = scb->hscb; 1163 ccb_h = &csio->ccb_h; 1164 1165 csio->resid = 0; 1166 csio->sense_resid = 0; 1167 if (ccb_h->func_code == XPT_SCSI_IO) { 1168 hscb->cdb_len = csio->cdb_len; 1169 if ((ccb_h->flags & CAM_CDB_POINTER) != 0) { 1170 1171 if (hscb->cdb_len > MAX_CDB_LEN 1172 && (ccb_h->flags & CAM_CDB_PHYS) == 0) { 1173 u_long s; 1174 1175 /* 1176 * Should CAM start to support CDB sizes 1177 * greater than 16 bytes, we could use 1178 * the sense buffer to store the CDB. 1179 */ 1180 ahd_set_transaction_status(scb, 1181 CAM_REQ_INVALID); 1182 ahd_lock(ahd, &s); 1183 ahd_free_scb(ahd, scb); 1184 ahd_unlock(ahd, &s); 1185 xpt_done((union ccb *)csio); 1186 return; 1187 } 1188 if ((ccb_h->flags & CAM_CDB_PHYS) != 0) { 1189 hscb->shared_data.idata.cdb_from_host.cdbptr = 1190 ahd_htole64((uintptr_t)csio->cdb_io.cdb_ptr); 1191 hscb->shared_data.idata.cdb_from_host.cdblen = 1192 csio->cdb_len; 1193 hscb->cdb_len |= SCB_CDB_LEN_PTR; 1194 } else { 1195 memcpy(hscb->shared_data.idata.cdb, 1196 csio->cdb_io.cdb_ptr, 1197 hscb->cdb_len); 1198 } 1199 } else { 1200 if (hscb->cdb_len > MAX_CDB_LEN) { 1201 u_long s; 1202 1203 ahd_set_transaction_status(scb, 1204 CAM_REQ_INVALID); 1205 ahd_lock(ahd, &s); 1206 ahd_free_scb(ahd, scb); 1207 ahd_unlock(ahd, &s); 1208 xpt_done((union ccb *)csio); 1209 return; 1210 } 1211 memcpy(hscb->shared_data.idata.cdb, 1212 csio->cdb_io.cdb_bytes, hscb->cdb_len); 1213 } 1214 } 1215 1216 /* Only use S/G if there is a transfer */ 1217 if ((ccb_h->flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 1218 if ((ccb_h->flags & CAM_SCATTER_VALID) == 0) { 1219 /* We've been given a pointer to a single buffer */ 1220 if ((ccb_h->flags & CAM_DATA_PHYS) == 0) { 1221 int s; 1222 int error; 1223 1224 s = splsoftvm(); 1225 error = bus_dmamap_load(ahd->buffer_dmat, 1226 scb->dmamap, 1227 csio->data_ptr, 1228 csio->dxfer_len, 1229 ahd_execute_scb, 1230 scb, /*flags*/0); 1231 if (error == EINPROGRESS) { 1232 /* 1233 * So as to maintain ordering, 1234 * freeze the controller queue 1235 * until our mapping is 1236 * returned. 1237 */ 1238 xpt_freeze_simq(sim, 1239 /*count*/1); 1240 scb->io_ctx->ccb_h.status |= 1241 CAM_RELEASE_SIMQ; 1242 } 1243 splx(s); 1244 } else { 1245 struct bus_dma_segment seg; 1246 1247 /* Pointer to physical buffer */ 1248 if (csio->dxfer_len > AHD_MAXTRANSFER_SIZE) 1249 panic("ahd_setup_data - Transfer size " 1250 "larger than can device max"); 1251 1252 seg.ds_addr = 1253 (bus_addr_t)(vm_offset_t)csio->data_ptr; 1254 seg.ds_len = csio->dxfer_len; 1255 ahd_execute_scb(scb, &seg, 1, 0); 1256 } 1257 } else { 1258 struct bus_dma_segment *segs; 1259 1260 if ((ccb_h->flags & CAM_DATA_PHYS) != 0) 1261 panic("ahd_setup_data - Physical segment " 1262 "pointers unsupported"); 1263 1264 if ((ccb_h->flags & CAM_SG_LIST_PHYS) == 0) 1265 panic("ahd_setup_data - Virtual segment " 1266 "addresses unsupported"); 1267 1268 /* Just use the segments provided */ 1269 segs = (struct bus_dma_segment *)csio->data_ptr; 1270 ahd_execute_scb(scb, segs, csio->sglist_cnt, 0); 1271 } 1272 } else { 1273 ahd_execute_scb(scb, NULL, 0, 0); 1274 } 1275 } 1276 1277 #if NOT_YET 1278 static void 1279 ahd_set_recoveryscb(struct ahd_softc *ahd, struct scb *scb) { 1280 1281 if ((scb->flags & SCB_RECOVERY_SCB) == 0) { 1282 struct scb *list_scb; 1283 1284 scb->flags |= SCB_RECOVERY_SCB; 1285 1286 /* 1287 * Take all queued, but not sent SCBs out of the equation. 1288 * Also ensure that no new CCBs are queued to us while we 1289 * try to fix this problem. 1290 */ 1291 if ((scb->io_ctx->ccb_h.status & CAM_RELEASE_SIMQ) == 0) { 1292 xpt_freeze_simq(SCB_GET_SIM(ahd, scb), /*count*/1); 1293 scb->io_ctx->ccb_h.status |= CAM_RELEASE_SIMQ; 1294 } 1295 1296 /* 1297 * Go through all of our pending SCBs and remove 1298 * any scheduled timeouts for them. We will reschedule 1299 * them after we've successfully fixed this problem. 1300 */ 1301 LIST_FOREACH(list_scb, &ahd->pending_scbs, pending_links) { 1302 union ccb *ccb; 1303 1304 ccb = list_scb->io_ctx; 1305 untimeout(ahd_timeout, list_scb, ccb->ccb_h.timeout_ch); 1306 } 1307 } 1308 } 1309 #endif 1310 1311 void 1312 ahd_timeout(void *arg) 1313 { 1314 struct scb *scb; 1315 struct ahd_softc *ahd; 1316 ahd_mode_state saved_modes; 1317 long s; 1318 int target; 1319 int lun; 1320 char channel; 1321 1322 #if NOT_YET 1323 int i; 1324 int found; 1325 u_int last_phase; 1326 #endif 1327 1328 scb = (struct scb *)arg; 1329 ahd = (struct ahd_softc *)scb->ahd_softc; 1330 1331 ahd_lock(ahd, &s); 1332 1333 ahd_pause_and_flushwork(ahd); 1334 1335 saved_modes = ahd_save_modes(ahd); 1336 #if 0 1337 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); 1338 ahd_outb(ahd, SCSISIGO, ACKO); 1339 printf("set ACK\n"); 1340 ahd_outb(ahd, SCSISIGO, 0); 1341 printf("clearing Ack\n"); 1342 ahd_restore_modes(ahd, saved_modes); 1343 #endif 1344 if ((scb->flags & SCB_ACTIVE) == 0) { 1345 /* Previous timeout took care of me already */ 1346 printf("%s: Timedout SCB already complete. " 1347 "Interrupts may not be functioning.\n", ahd_name(ahd)); 1348 ahd_unpause(ahd); 1349 ahd_unlock(ahd, &s); 1350 return; 1351 } 1352 1353 target = SCB_GET_TARGET(ahd, scb); 1354 channel = SCB_GET_CHANNEL(ahd, scb); 1355 lun = SCB_GET_LUN(scb); 1356 1357 ahd_print_path(ahd, scb); 1358 printf("SCB 0x%x - timed out\n", SCB_GET_TAG(scb)); 1359 ahd_dump_card_state(ahd); 1360 ahd_reset_channel(ahd, SIM_CHANNEL(ahd, sim), 1361 /*initiate reset*/TRUE); 1362 ahd_unlock(ahd, &s); 1363 return; 1364 #if NOT_YET 1365 last_phase = ahd_inb(ahd, LASTPHASE); 1366 if (scb->sg_count > 0) { 1367 for (i = 0; i < scb->sg_count; i++) { 1368 printf("sg[%d] - Addr 0x%x : Length %d\n", 1369 i, 1370 ((struct ahd_dma_seg *)scb->sg_list)[i].addr, 1371 ((struct ahd_dma_seg *)scb->sg_list)[i].len 1372 & AHD_SG_LEN_MASK); 1373 } 1374 } 1375 if (scb->flags & (SCB_DEVICE_RESET|SCB_ABORT)) { 1376 /* 1377 * Been down this road before. 1378 * Do a full bus reset. 1379 */ 1380 bus_reset: 1381 ahd_set_transaction_status(scb, CAM_CMD_TIMEOUT); 1382 found = ahd_reset_channel(ahd, channel, /*Initiate Reset*/TRUE); 1383 printf("%s: Issued Channel %c Bus Reset. " 1384 "%d SCBs aborted\n", ahd_name(ahd), channel, found); 1385 } else { 1386 /* 1387 * If we are a target, transition to bus free and report 1388 * the timeout. 1389 * 1390 * The target/initiator that is holding up the bus may not 1391 * be the same as the one that triggered this timeout 1392 * (different commands have different timeout lengths). 1393 * If the bus is idle and we are actiing as the initiator 1394 * for this request, queue a BDR message to the timed out 1395 * target. Otherwise, if the timed out transaction is 1396 * active: 1397 * Initiator transaction: 1398 * Stuff the message buffer with a BDR message and assert 1399 * ATN in the hopes that the target will let go of the bus 1400 * and go to the mesgout phase. If this fails, we'll 1401 * get another timeout 2 seconds later which will attempt 1402 * a bus reset. 1403 * 1404 * Target transaction: 1405 * Transition to BUS FREE and report the error. 1406 * It's good to be the target! 1407 */ 1408 u_int active_scb_index; 1409 u_int saved_scbptr; 1410 1411 saved_scbptr = ahd_get_scbptr(ahd); 1412 active_scb_index = saved_scbptr; 1413 1414 if (last_phase != P_BUSFREE 1415 && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) == 0 1416 && (active_scb_index < ahd->scb_data.numscbs)) { 1417 struct scb *active_scb; 1418 1419 /* 1420 * If the active SCB is not us, assume that 1421 * the active SCB has a longer timeout than 1422 * the timedout SCB, and wait for the active 1423 * SCB to timeout. 1424 */ 1425 active_scb = ahd_lookup_scb(ahd, active_scb_index); 1426 if (active_scb != scb) { 1427 struct ccb_hdr *ccbh; 1428 uint64_t newtimeout; 1429 1430 ahd_print_path(ahd, scb); 1431 printf("Other SCB Timeout%s", 1432 (scb->flags & SCB_OTHERTCL_TIMEOUT) != 0 1433 ? " again\n" : "\n"); 1434 scb->flags |= SCB_OTHERTCL_TIMEOUT; 1435 newtimeout = 1436 MAX(active_scb->io_ctx->ccb_h.timeout, 1437 scb->io_ctx->ccb_h.timeout); 1438 newtimeout *= hz; 1439 newtimeout /= 1000; 1440 ccbh = &scb->io_ctx->ccb_h; 1441 scb->io_ctx->ccb_h.timeout_ch = 1442 timeout(ahd_timeout, scb, newtimeout); 1443 ahd_unpause(ahd); 1444 ahd_unlock(ahd, &s); 1445 return; 1446 } 1447 1448 /* It's us */ 1449 if ((scb->hscb->control & TARGET_SCB) != 0) { 1450 1451 /* 1452 * Send back any queued up transactions 1453 * and properly record the error condition. 1454 */ 1455 ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb), 1456 SCB_GET_CHANNEL(ahd, scb), 1457 SCB_GET_LUN(scb), 1458 SCB_GET_TAG(scb), 1459 ROLE_TARGET, 1460 CAM_CMD_TIMEOUT); 1461 1462 /* Will clear us from the bus */ 1463 ahd_restart(ahd); 1464 ahd_unlock(ahd, &s); 1465 return; 1466 } 1467 1468 ahd_set_recoveryscb(ahd, active_scb); 1469 ahd_outb(ahd, MSG_OUT, HOST_MSG); 1470 ahd_outb(ahd, SCSISIGO, last_phase|ATNO); 1471 ahd_print_path(ahd, active_scb); 1472 printf("BDR message in message buffer\n"); 1473 active_scb->flags |= SCB_DEVICE_RESET; 1474 active_scb->io_ctx->ccb_h.timeout_ch = 1475 timeout(ahd_timeout, (caddr_t)active_scb, 2 * hz); 1476 ahd_unpause(ahd); 1477 } else { 1478 int disconnected; 1479 1480 /* XXX Shouldn't panic. Just punt instead? */ 1481 if ((scb->hscb->control & TARGET_SCB) != 0) 1482 panic("Timed-out target SCB but bus idle"); 1483 1484 if (last_phase != P_BUSFREE 1485 && (ahd_inb(ahd, SSTAT0) & TARGET) != 0) { 1486 /* XXX What happened to the SCB? */ 1487 /* Hung target selection. Goto busfree */ 1488 printf("%s: Hung target selection\n", 1489 ahd_name(ahd)); 1490 ahd_restart(ahd); 1491 ahd_unlock(ahd, &s); 1492 return; 1493 } 1494 1495 if (ahd_search_qinfifo(ahd, target, channel, lun, 1496 SCB_GET_TAG(scb), ROLE_INITIATOR, 1497 /*status*/0, SEARCH_COUNT) > 0) { 1498 disconnected = FALSE; 1499 } else { 1500 disconnected = TRUE; 1501 } 1502 1503 if (disconnected) { 1504 1505 ahd_set_recoveryscb(ahd, scb); 1506 /* 1507 * Actually re-queue this SCB in an attempt 1508 * to select the device before it reconnects. 1509 * In either case (selection or reselection), 1510 * we will now issue a target reset to the 1511 * timed-out device. 1512 * 1513 * Set the MK_MESSAGE control bit indicating 1514 * that we desire to send a message. We 1515 * also set the disconnected flag since 1516 * in the paging case there is no guarantee 1517 * that our SCB control byte matches the 1518 * version on the card. We don't want the 1519 * sequencer to abort the command thinking 1520 * an unsolicited reselection occurred. 1521 */ 1522 scb->hscb->control |= MK_MESSAGE|DISCONNECTED; 1523 scb->flags |= SCB_DEVICE_RESET; 1524 1525 /* 1526 * The sequencer will never re-reference the 1527 * in-core SCB. To make sure we are notified 1528 * during reslection, set the MK_MESSAGE flag 1529 * in the card's copy of the SCB. 1530 */ 1531 ahd_set_scbptr(ahd, SCB_GET_TAG(scb)); 1532 ahd_outb(ahd, SCB_CONTROL, 1533 ahd_inb(ahd, SCB_CONTROL)|MK_MESSAGE); 1534 1535 /* 1536 * Clear out any entries in the QINFIFO first 1537 * so we are the next SCB for this target 1538 * to run. 1539 */ 1540 ahd_search_qinfifo(ahd, 1541 SCB_GET_TARGET(ahd, scb), 1542 channel, SCB_GET_LUN(scb), 1543 SCB_LIST_NULL, 1544 ROLE_INITIATOR, 1545 CAM_REQUEUE_REQ, 1546 SEARCH_COMPLETE); 1547 ahd_print_path(ahd, scb); 1548 printf("Queuing a BDR SCB\n"); 1549 ahd_qinfifo_requeue_tail(ahd, scb); 1550 ahd_set_scbptr(ahd, saved_scbptr); 1551 scb->io_ctx->ccb_h.timeout_ch = 1552 timeout(ahd_timeout, (caddr_t)scb, 2 * hz); 1553 ahd_unpause(ahd); 1554 } else { 1555 /* Go "immediatly" to the bus reset */ 1556 /* This shouldn't happen */ 1557 ahd_set_recoveryscb(ahd, scb); 1558 ahd_print_path(ahd, scb); 1559 printf("SCB %d: Immediate reset. " 1560 "Flags = 0x%x\n", SCB_GET_TAG(scb), 1561 scb->flags); 1562 goto bus_reset; 1563 } 1564 } 1565 } 1566 ahd_unlock(ahd, &s); 1567 #endif 1568 } 1569 1570 static void 1571 ahd_abort_ccb(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb) 1572 { 1573 union ccb *abort_ccb; 1574 1575 abort_ccb = ccb->cab.abort_ccb; 1576 switch (abort_ccb->ccb_h.func_code) { 1577 #ifdef AHD_TARGET_MODE 1578 case XPT_ACCEPT_TARGET_IO: 1579 case XPT_IMMED_NOTIFY: 1580 case XPT_CONT_TARGET_IO: 1581 { 1582 struct ahd_tmode_tstate *tstate; 1583 struct ahd_tmode_lstate *lstate; 1584 struct ccb_hdr_slist *list; 1585 cam_status status; 1586 1587 status = ahd_find_tmode_devs(ahd, sim, abort_ccb, &tstate, 1588 &lstate, TRUE); 1589 1590 if (status != CAM_REQ_CMP) { 1591 ccb->ccb_h.status = status; 1592 break; 1593 } 1594 1595 if (abort_ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) 1596 list = &lstate->accept_tios; 1597 else if (abort_ccb->ccb_h.func_code == XPT_IMMED_NOTIFY) 1598 list = &lstate->immed_notifies; 1599 else 1600 list = NULL; 1601 1602 if (list != NULL) { 1603 struct ccb_hdr *curelm; 1604 int found; 1605 1606 curelm = SLIST_FIRST(list); 1607 found = 0; 1608 if (curelm == &abort_ccb->ccb_h) { 1609 found = 1; 1610 SLIST_REMOVE_HEAD(list, sim_links.sle); 1611 } else { 1612 while(curelm != NULL) { 1613 struct ccb_hdr *nextelm; 1614 1615 nextelm = 1616 SLIST_NEXT(curelm, sim_links.sle); 1617 1618 if (nextelm == &abort_ccb->ccb_h) { 1619 found = 1; 1620 SLIST_NEXT(curelm, 1621 sim_links.sle) = 1622 SLIST_NEXT(nextelm, 1623 sim_links.sle); 1624 break; 1625 } 1626 curelm = nextelm; 1627 } 1628 } 1629 1630 if (found) { 1631 abort_ccb->ccb_h.status = CAM_REQ_ABORTED; 1632 xpt_done(abort_ccb); 1633 ccb->ccb_h.status = CAM_REQ_CMP; 1634 } else { 1635 xpt_print_path(abort_ccb->ccb_h.path); 1636 printf("Not found\n"); 1637 ccb->ccb_h.status = CAM_PATH_INVALID; 1638 } 1639 break; 1640 } 1641 /* FALLTHROUGH */ 1642 } 1643 #endif 1644 case XPT_SCSI_IO: 1645 /* XXX Fully implement the hard ones */ 1646 ccb->ccb_h.status = CAM_UA_ABORT; 1647 break; 1648 default: 1649 ccb->ccb_h.status = CAM_REQ_INVALID; 1650 break; 1651 } 1652 xpt_done(ccb); 1653 } 1654 1655 void 1656 ahd_send_async(struct ahd_softc *ahd, char channel, u_int target, 1657 u_int lun, ac_code code, void *opt_arg) 1658 { 1659 struct ccb_trans_settings cts; 1660 struct cam_path *path; 1661 void *arg; 1662 int error; 1663 1664 arg = NULL; 1665 error = ahd_create_path(ahd, channel, target, lun, &path); 1666 1667 if (error != CAM_REQ_CMP) 1668 return; 1669 1670 switch (code) { 1671 case AC_TRANSFER_NEG: 1672 { 1673 #ifdef AHD_NEW_TRAN_SETTINGS 1674 struct ccb_trans_settings_scsi *scsi; 1675 1676 cts.type = CTS_TYPE_CURRENT_SETTINGS; 1677 scsi = &cts.proto_specific.scsi; 1678 #else 1679 cts.flags = CCB_TRANS_CURRENT_SETTINGS; 1680 #endif 1681 cts.ccb_h.path = path; 1682 cts.ccb_h.target_id = target; 1683 cts.ccb_h.target_lun = lun; 1684 ahd_get_tran_settings(ahd, ahd->our_id, channel, &cts); 1685 arg = &cts; 1686 #ifdef AHD_NEW_TRAN_SETTINGS 1687 scsi->valid &= ~CTS_SCSI_VALID_TQ; 1688 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; 1689 #else 1690 cts.valid &= ~CCB_TRANS_TQ_VALID; 1691 cts.flags &= ~CCB_TRANS_TAG_ENB; 1692 #endif 1693 if (opt_arg == NULL) 1694 break; 1695 if (*((ahd_queue_alg *)opt_arg) == AHD_QUEUE_TAGGED) 1696 #ifdef AHD_NEW_TRAN_SETTINGS 1697 scsi->flags |= ~CTS_SCSI_FLAGS_TAG_ENB; 1698 scsi->valid |= CTS_SCSI_VALID_TQ; 1699 #else 1700 cts.flags |= CCB_TRANS_TAG_ENB; 1701 cts.valid |= CCB_TRANS_TQ_VALID; 1702 #endif 1703 break; 1704 } 1705 case AC_SENT_BDR: 1706 case AC_BUS_RESET: 1707 break; 1708 default: 1709 panic("ahd_send_async: Unexpected async event"); 1710 } 1711 xpt_async(code, path, arg); 1712 xpt_free_path(path); 1713 } 1714 1715 void 1716 ahd_platform_set_tags(struct ahd_softc *ahd, 1717 struct ahd_devinfo *devinfo, int enable) 1718 { 1719 } 1720 1721 int 1722 ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg) 1723 { 1724 ahd->platform_data = malloc(sizeof(struct ahd_platform_data), M_DEVBUF, 1725 M_NOWAIT | M_ZERO); 1726 if (ahd->platform_data == NULL) 1727 return (ENOMEM); 1728 return (0); 1729 } 1730 1731 void 1732 ahd_platform_free(struct ahd_softc *ahd) 1733 { 1734 struct ahd_platform_data *pdata; 1735 1736 pdata = ahd->platform_data; 1737 if (pdata != NULL) { 1738 if (pdata->regs[0] != NULL) 1739 bus_release_resource(ahd->dev_softc, 1740 pdata->regs_res_type[0], 1741 pdata->regs_res_id[0], 1742 pdata->regs[0]); 1743 1744 if (pdata->regs[1] != NULL) 1745 bus_release_resource(ahd->dev_softc, 1746 pdata->regs_res_type[1], 1747 pdata->regs_res_id[1], 1748 pdata->regs[1]); 1749 1750 if (pdata->irq != NULL) 1751 bus_release_resource(ahd->dev_softc, 1752 pdata->irq_res_type, 1753 0, pdata->irq); 1754 1755 if (pdata->sim_b != NULL) { 1756 xpt_async(AC_LOST_DEVICE, pdata->path_b, NULL); 1757 xpt_free_path(pdata->path_b); 1758 xpt_bus_deregister(cam_sim_path(pdata->sim_b)); 1759 cam_sim_free(pdata->sim_b, /*free_devq*/TRUE); 1760 } 1761 if (pdata->sim != NULL) { 1762 xpt_async(AC_LOST_DEVICE, pdata->path, NULL); 1763 xpt_free_path(pdata->path); 1764 xpt_bus_deregister(cam_sim_path(pdata->sim)); 1765 cam_sim_free(pdata->sim, /*free_devq*/TRUE); 1766 } 1767 if (pdata->eh != NULL) 1768 EVENTHANDLER_DEREGISTER(shutdown_final, pdata->eh); 1769 free(ahd->platform_data, M_DEVBUF); 1770 } 1771 } 1772 1773 int 1774 ahd_softc_comp(struct ahd_softc *lahd, struct ahd_softc *rahd) 1775 { 1776 /* We don't sort softcs under FreeBSD so report equal always */ 1777 return (0); 1778 } 1779 1780 int 1781 ahd_detach(device_t dev) 1782 { 1783 struct ahd_softc *ahd; 1784 u_long l; 1785 u_long s; 1786 1787 ahd_list_lock(&l); 1788 device_printf(dev, "detaching device\n"); 1789 ahd = device_get_softc(dev); 1790 ahd = ahd_find_softc(ahd); 1791 if (ahd == NULL) { 1792 device_printf(dev, "aic7xxx already detached\n"); 1793 ahd_list_unlock(&l); 1794 return (ENOENT); 1795 } 1796 ahd_lock(ahd, &s); 1797 ahd_intr_enable(ahd, FALSE); 1798 bus_teardown_intr(dev, ahd->platform_data->irq, ahd->platform_data->ih); 1799 ahd_unlock(ahd, &s); 1800 ahd_free(ahd); 1801 ahd_list_unlock(&l); 1802 return (0); 1803 } 1804 1805 #if UNUSED 1806 static void 1807 ahd_dump_targcmd(struct target_cmd *cmd) 1808 { 1809 uint8_t *byte; 1810 uint8_t *last_byte; 1811 int i; 1812 1813 byte = &cmd->initiator_channel; 1814 /* Debugging info for received commands */ 1815 last_byte = &cmd[1].initiator_channel; 1816 1817 i = 0; 1818 while (byte < last_byte) { 1819 if (i == 0) 1820 printf("\t"); 1821 printf("%#x", *byte++); 1822 i++; 1823 if (i == 8) { 1824 printf("\n"); 1825 i = 0; 1826 } else { 1827 printf(", "); 1828 } 1829 } 1830 } 1831 #endif 1832 1833 static int 1834 ahd_modevent(module_t mod, int type, void *data) 1835 { 1836 /* XXX Deal with busy status on unload. */ 1837 return 0; 1838 } 1839 1840 static moduledata_t ahd_mod = { 1841 "ahd", 1842 ahd_modevent, 1843 NULL 1844 }; 1845 1846 /********************************** DDB Hooks *********************************/ 1847 #ifdef DDB 1848 static struct ahd_softc *ahd_ddb_softc; 1849 static int ahd_ddb_paused; 1850 static int ahd_ddb_paused_on_entry; 1851 DB_COMMAND(ahd_set_unit, ahd_ddb_set_unit) 1852 { 1853 struct ahd_softc *list_ahd; 1854 1855 ahd_ddb_softc = NULL; 1856 TAILQ_FOREACH(list_ahd, &ahd_tailq, links) { 1857 if (list_ahd->unit == addr) 1858 ahd_ddb_softc = list_ahd; 1859 } 1860 if (ahd_ddb_softc == NULL) 1861 db_error("No matching softc found!\n"); 1862 } 1863 1864 DB_COMMAND(ahd_pause, ahd_ddb_pause) 1865 { 1866 if (ahd_ddb_softc == NULL) { 1867 db_error("Must set unit with ahd_set_unit first!\n"); 1868 return; 1869 } 1870 if (ahd_ddb_paused == 0) { 1871 ahd_ddb_paused++; 1872 if (ahd_is_paused(ahd_ddb_softc)) { 1873 ahd_ddb_paused_on_entry++; 1874 return; 1875 } 1876 ahd_pause(ahd_ddb_softc); 1877 } 1878 } 1879 1880 DB_COMMAND(ahd_unpause, ahd_ddb_unpause) 1881 { 1882 if (ahd_ddb_softc == NULL) { 1883 db_error("Must set unit with ahd_set_unit first!\n"); 1884 return; 1885 } 1886 if (ahd_ddb_paused != 0) { 1887 ahd_ddb_paused = 0; 1888 if (ahd_ddb_paused_on_entry) 1889 return; 1890 ahd_unpause(ahd_ddb_softc); 1891 } else if (ahd_ddb_paused_on_entry != 0) { 1892 /* Two unpauses to clear a paused on entry. */ 1893 ahd_ddb_paused_on_entry = 0; 1894 ahd_unpause(ahd_ddb_softc); 1895 } 1896 } 1897 1898 DB_COMMAND(ahd_in, ahd_ddb_in) 1899 { 1900 int c; 1901 int size; 1902 1903 if (ahd_ddb_softc == NULL) { 1904 db_error("Must set unit with ahd_set_unit first!\n"); 1905 return; 1906 } 1907 if (have_addr == 0) 1908 return; 1909 1910 size = 1; 1911 while ((c = *modif++) != '\0') { 1912 switch (c) { 1913 case 'b': 1914 size = 1; 1915 break; 1916 case 'w': 1917 size = 2; 1918 break; 1919 case 'l': 1920 size = 4; 1921 break; 1922 } 1923 } 1924 1925 if (count <= 0) 1926 count = 1; 1927 while (--count >= 0) { 1928 db_printf("%04lx (M)%x: \t", (u_long)addr, 1929 ahd_inb(ahd_ddb_softc, MODE_PTR)); 1930 switch (size) { 1931 case 1: 1932 db_printf("%02x\n", ahd_inb(ahd_ddb_softc, addr)); 1933 break; 1934 case 2: 1935 db_printf("%04x\n", ahd_inw(ahd_ddb_softc, addr)); 1936 break; 1937 case 4: 1938 db_printf("%08x\n", ahd_inl(ahd_ddb_softc, addr)); 1939 break; 1940 } 1941 } 1942 } 1943 1944 DB_SET(ahd_out, ahd_ddb_out, db_cmd_set, CS_MORE, NULL) 1945 { 1946 db_expr_t old_value; 1947 db_expr_t new_value; 1948 int size; 1949 1950 if (ahd_ddb_softc == NULL) { 1951 db_error("Must set unit with ahd_set_unit first!\n"); 1952 return; 1953 } 1954 1955 switch (modif[0]) { 1956 case '\0': 1957 case 'b': 1958 size = 1; 1959 break; 1960 case 'h': 1961 size = 2; 1962 break; 1963 case 'l': 1964 size = 4; 1965 break; 1966 default: 1967 db_error("Unknown size\n"); 1968 return; 1969 } 1970 1971 while (db_expression(&new_value)) { 1972 switch (size) { 1973 default: 1974 case 1: 1975 old_value = ahd_inb(ahd_ddb_softc, addr); 1976 ahd_outb(ahd_ddb_softc, addr, new_value); 1977 break; 1978 case 2: 1979 old_value = ahd_inw(ahd_ddb_softc, addr); 1980 ahd_outw(ahd_ddb_softc, addr, new_value); 1981 break; 1982 case 4: 1983 old_value = ahd_inl(ahd_ddb_softc, addr); 1984 ahd_outl(ahd_ddb_softc, addr, new_value); 1985 break; 1986 } 1987 db_printf("%04lx (M)%x: \t0x%lx\t=\t0x%lx", 1988 (u_long)addr, ahd_inb(ahd_ddb_softc, MODE_PTR), 1989 (u_long)old_value, (u_long)new_value); 1990 addr += size; 1991 } 1992 db_skip_to_eol(); 1993 } 1994 1995 #endif 1996 1997 1998 DECLARE_MODULE(ahd, ahd_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE); 1999 MODULE_DEPEND(ahd, cam, 1, 1, 1); 2000 MODULE_VERSION(ahd, 1); 2001