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