1/*- 2 * Copyright (c) 1999 Luoqi Chen. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD$"); 29 30#include <sys/param.h> 31#include <sys/conf.h> 32#include <sys/systm.h> 33#include <sys/kernel.h> 34#include <sys/lock.h> 35#include <sys/mutex.h> 36#include <sys/malloc.h> 37#include <sys/bus.h> 38 39#include <machine/bus.h> 40#include <sys/rman.h> 41 42#include <cam/cam.h> 43#include <cam/cam_ccb.h> 44#include <cam/cam_sim.h> 45#include <cam/cam_xpt_sim.h> 46#include <cam/cam_debug.h> 47 48#include <cam/scsi/scsi_message.h> 49 50#include <dev/aic/aic6360reg.h> 51#include <dev/aic/aicvar.h> 52 53static void aic_action(struct cam_sim *sim, union ccb *ccb); 54static void aic_execute_scb(void *arg, bus_dma_segment_t *dm_segs, 55 int nseg, int error); 56static void aic_intr_locked(struct aic_softc *aic); 57static void aic_start(struct aic_softc *aic); 58static void aic_select(struct aic_softc *aic); 59static void aic_selected(struct aic_softc *aic); 60static void aic_reselected(struct aic_softc *aic); 61static void aic_reconnect(struct aic_softc *aic, int tag); 62static void aic_cmd(struct aic_softc *aic); 63static void aic_msgin(struct aic_softc *aic); 64static void aic_handle_msgin(struct aic_softc *aic); 65static void aic_msgout(struct aic_softc *aic); 66static void aic_datain(struct aic_softc *aic); 67static void aic_dataout(struct aic_softc *aic); 68static void aic_done(struct aic_softc *aic, struct aic_scb *scb); 69static void aic_poll(struct cam_sim *sim); 70static void aic_timeout(void *arg); 71static void aic_scsi_reset(struct aic_softc *aic); 72static void aic_chip_reset(struct aic_softc *aic); 73static void aic_reset(struct aic_softc *aic, int initiate_reset); 74 75devclass_t aic_devclass; 76 77static struct aic_scb * 78aic_get_scb(struct aic_softc *aic) 79{ 80 struct aic_scb *scb; 81 82 if (!dumping) 83 mtx_assert(&aic->lock, MA_OWNED); 84 if ((scb = SLIST_FIRST(&aic->free_scbs)) != NULL) 85 SLIST_REMOVE_HEAD(&aic->free_scbs, link); 86 return (scb); 87} 88 89static void 90aic_free_scb(struct aic_softc *aic, struct aic_scb *scb) 91{ 92 93 if (!dumping) 94 mtx_assert(&aic->lock, MA_OWNED); 95 if ((aic->flags & AIC_RESOURCE_SHORTAGE) != 0 && 96 (scb->ccb->ccb_h.status & CAM_RELEASE_SIMQ) == 0) { 97 scb->ccb->ccb_h.status |= CAM_RELEASE_SIMQ; 98 aic->flags &= ~AIC_RESOURCE_SHORTAGE; 99 } 100 scb->flags = 0; 101 SLIST_INSERT_HEAD(&aic->free_scbs, scb, link); 102} 103 104static void 105aic_action(struct cam_sim *sim, union ccb *ccb) 106{ 107 struct aic_softc *aic; 108 109 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("aic_action\n")); 110 111 aic = (struct aic_softc *)cam_sim_softc(sim); 112 mtx_assert(&aic->lock, MA_OWNED); 113 114 switch (ccb->ccb_h.func_code) { 115 case XPT_SCSI_IO: /* Execute the requested I/O operation */ 116 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */ 117 { 118 struct aic_scb *scb; 119 120 if ((scb = aic_get_scb(aic)) == NULL) { 121 aic->flags |= AIC_RESOURCE_SHORTAGE; 122 xpt_freeze_simq(aic->sim, /*count*/1); 123 ccb->ccb_h.status = CAM_REQUEUE_REQ; 124 xpt_done(ccb); 125 return; 126 } 127 128 scb->ccb = ccb; 129 ccb->ccb_h.ccb_scb_ptr = scb; 130 ccb->ccb_h.ccb_aic_ptr = aic; 131 132 scb->target = ccb->ccb_h.target_id; 133 scb->lun = ccb->ccb_h.target_lun; 134 135 if (ccb->ccb_h.func_code == XPT_SCSI_IO) { 136 scb->cmd_len = ccb->csio.cdb_len; 137 if (ccb->ccb_h.flags & CAM_CDB_POINTER) { 138 if (ccb->ccb_h.flags & CAM_CDB_PHYS) { 139 ccb->ccb_h.status = CAM_REQ_INVALID; 140 aic_free_scb(aic, scb); 141 xpt_done(ccb); 142 return; 143 } 144 scb->cmd_ptr = ccb->csio.cdb_io.cdb_ptr; 145 } else { 146 scb->cmd_ptr = ccb->csio.cdb_io.cdb_bytes; 147 } 148 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 149 if ((ccb->ccb_h.flags & CAM_DATA_MASK) != 150 CAM_DATA_VADDR) { 151 ccb->ccb_h.status = CAM_REQ_INVALID; 152 aic_free_scb(aic, scb); 153 xpt_done(ccb); 154 return; 155 } 156 scb->data_ptr = ccb->csio.data_ptr; 157 scb->data_len = ccb->csio.dxfer_len; 158 } else { 159 scb->data_ptr = NULL; 160 scb->data_len = 0; 161 } 162 aic_execute_scb(scb, NULL, 0, 0); 163 } else { 164 scb->flags |= SCB_DEVICE_RESET; 165 aic_execute_scb(scb, NULL, 0, 0); 166 } 167 break; 168 } 169 case XPT_SET_TRAN_SETTINGS: 170 { 171 struct ccb_trans_settings *cts = &ccb->cts; 172 struct aic_tinfo *ti = &aic->tinfo[ccb->ccb_h.target_id]; 173 struct ccb_trans_settings_scsi *scsi = 174 &cts->proto_specific.scsi; 175 struct ccb_trans_settings_spi *spi = 176 &cts->xport_specific.spi; 177 178 if ((spi->valid & CTS_SPI_VALID_DISC) != 0 && 179 (aic->flags & AIC_DISC_ENABLE) != 0) { 180 if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0) 181 ti->flags |= TINFO_DISC_ENB; 182 else 183 ti->flags &= ~TINFO_DISC_ENB; 184 } 185 186 if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) { 187 if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) 188 ti->flags |= TINFO_TAG_ENB; 189 else 190 ti->flags &= ~TINFO_TAG_ENB; 191 } 192 193 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) { 194 ti->goal.period = spi->sync_period; 195 196 if (ti->goal.period > aic->min_period) { 197 ti->goal.period = 0; 198 ti->goal.offset = 0; 199 } else if (ti->goal.period < aic->max_period) 200 ti->goal.period = aic->max_period; 201 } 202 203 if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0) { 204 ti->goal.offset = spi->sync_offset; 205 if (ti->goal.offset == 0) 206 ti->goal.period = 0; 207 else if (ti->goal.offset > AIC_SYNC_OFFSET) 208 ti->goal.offset = AIC_SYNC_OFFSET; 209 } 210 211 if ((ti->goal.period != ti->current.period) 212 || (ti->goal.offset != ti->current.offset)) 213 ti->flags |= TINFO_SDTR_NEGO; 214 215 ccb->ccb_h.status = CAM_REQ_CMP; 216 xpt_done(ccb); 217 break; 218 } 219 case XPT_GET_TRAN_SETTINGS: 220 { 221 struct ccb_trans_settings *cts = &ccb->cts; 222 struct aic_tinfo *ti = &aic->tinfo[ccb->ccb_h.target_id]; 223 struct ccb_trans_settings_scsi *scsi = 224 &cts->proto_specific.scsi; 225 struct ccb_trans_settings_spi *spi = 226 &cts->xport_specific.spi; 227 228 cts->protocol = PROTO_SCSI; 229 cts->protocol_version = SCSI_REV_2; 230 cts->transport = XPORT_SPI; 231 cts->transport_version = 2; 232 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; 233 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB; 234 235 if ((ti->flags & TINFO_DISC_ENB) != 0) 236 spi->flags |= CTS_SPI_FLAGS_DISC_ENB; 237 if ((ti->flags & TINFO_TAG_ENB) != 0) 238 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; 239 240 if (cts->type == CTS_TYPE_CURRENT_SETTINGS) { 241 spi->sync_period = ti->current.period; 242 spi->sync_offset = ti->current.offset; 243 } else { 244 spi->sync_period = ti->user.period; 245 spi->sync_offset = ti->user.offset; 246 } 247 248 spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT; 249 spi->valid = CTS_SPI_VALID_SYNC_RATE 250 | CTS_SPI_VALID_SYNC_OFFSET 251 | CTS_SPI_VALID_BUS_WIDTH 252 | CTS_SPI_VALID_DISC; 253 scsi->valid = CTS_SCSI_VALID_TQ; 254 255 ccb->ccb_h.status = CAM_REQ_CMP; 256 xpt_done(ccb); 257 break; 258 } 259 case XPT_CALC_GEOMETRY: 260 { 261 cam_calc_geometry(&ccb->ccg, /*extended*/1); 262 xpt_done(ccb); 263 break; 264 } 265 case XPT_RESET_BUS: /* Reset the specified SCSI bus */ 266 aic_reset(aic, /*initiate_reset*/TRUE); 267 ccb->ccb_h.status = CAM_REQ_CMP; 268 xpt_done(ccb); 269 break; 270 case XPT_PATH_INQ: /* Path routing inquiry */ 271 { 272 struct ccb_pathinq *cpi = &ccb->cpi; 273 274 cpi->version_num = 1; /* XXX??? */ 275 cpi->hba_inquiry = PI_SDTR_ABLE | PI_TAG_ABLE; 276 cpi->target_sprt = 0; 277 cpi->hba_misc = 0; 278 cpi->hba_eng_cnt = 0; 279 cpi->max_target = 7; 280 cpi->max_lun = 7; 281 cpi->initiator_id = aic->initiator; 282 cpi->bus_id = cam_sim_bus(sim); 283 cpi->base_transfer_speed = 3300; 284 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 285 strncpy(cpi->hba_vid, "Adaptec", HBA_IDLEN); 286 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 287 cpi->unit_number = cam_sim_unit(sim); 288 cpi->transport = XPORT_SPI; 289 cpi->transport_version = 2; 290 cpi->protocol = PROTO_SCSI; 291 cpi->protocol_version = SCSI_REV_2; 292 cpi->ccb_h.status = CAM_REQ_CMP; 293 xpt_done(ccb); 294 break; 295 } 296 default: 297 ccb->ccb_h.status = CAM_REQ_INVALID; 298 xpt_done(ccb); 299 break; 300 } 301} 302 303static void 304aic_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) 305{ 306 struct aic_scb *scb = (struct aic_scb *)arg; 307 union ccb *ccb = scb->ccb; 308 struct aic_softc *aic = (struct aic_softc *)ccb->ccb_h.ccb_aic_ptr; 309 310 if (!dumping) 311 mtx_assert(&aic->lock, MA_OWNED); 312 if (ccb->ccb_h.status != CAM_REQ_INPROG) { 313 aic_free_scb(aic, scb); 314 xpt_done(ccb); 315 return; 316 } 317 318 scb->flags |= SCB_ACTIVE; 319 ccb->ccb_h.status |= CAM_SIM_QUEUED; 320 TAILQ_INSERT_TAIL(&aic->pending_ccbs, &ccb->ccb_h, sim_links.tqe); 321 322 callout_reset(&scb->timer, (ccb->ccb_h.timeout * hz) / 1000, 323 aic_timeout, scb); 324 325 aic_start(aic); 326} 327 328/* 329 * Start another command if the controller is not busy. 330 */ 331static void 332aic_start(struct aic_softc *aic) 333{ 334 struct ccb_hdr *ccb_h; 335 struct aic_tinfo *ti; 336 337 if (aic->state != AIC_IDLE) 338 return; 339 340 TAILQ_FOREACH(ccb_h, &aic->pending_ccbs, sim_links.tqe) { 341 ti = &aic->tinfo[ccb_h->target_id]; 342 if ((ti->lubusy & (1 << ccb_h->target_lun)) == 0) { 343 TAILQ_REMOVE(&aic->pending_ccbs, ccb_h, sim_links.tqe); 344 aic->nexus = (struct aic_scb *)ccb_h->ccb_scb_ptr; 345 aic_select(aic); 346 return; 347 } 348 } 349 350 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_start: idle\n")); 351 352 aic_outb(aic, SIMODE0, ENSELDI); 353 aic_outb(aic, SIMODE1, ENSCSIRST); 354 aic_outb(aic, SCSISEQ, ENRESELI); 355} 356 357/* 358 * Start a selection. 359 */ 360static void 361aic_select(struct aic_softc *aic) 362{ 363 struct aic_scb *scb = aic->nexus; 364 365 CAM_DEBUG(scb->ccb->ccb_h.path, CAM_DEBUG_TRACE, 366 ("aic_select - ccb %p\n", scb->ccb)); 367 368 aic->state = AIC_SELECTING; 369 370 aic_outb(aic, DMACNTRL1, 0); 371 aic_outb(aic, SCSIID, aic->initiator << OID_S | scb->target); 372 aic_outb(aic, SXFRCTL1, STIMO_256ms | ENSTIMER | 373 (aic->flags & AIC_PARITY_ENABLE ? ENSPCHK : 0)); 374 375 aic_outb(aic, SIMODE0, ENSELDI|ENSELDO); 376 aic_outb(aic, SIMODE1, ENSCSIRST|ENSELTIMO); 377 aic_outb(aic, SCSISEQ, ENRESELI|ENSELO|ENAUTOATNO); 378} 379 380/* 381 * We have successfully selected a target, prepare for the information 382 * transfer phases. 383 */ 384static void 385aic_selected(struct aic_softc *aic) 386{ 387 struct aic_scb *scb = aic->nexus; 388 union ccb *ccb = scb->ccb; 389 struct aic_tinfo *ti = &aic->tinfo[scb->target]; 390 391 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, 392 ("aic_selected - ccb %p\n", ccb)); 393 394 aic->state = AIC_HASNEXUS; 395 396 if (scb->flags & SCB_DEVICE_RESET) { 397 aic->msg_buf[0] = MSG_BUS_DEV_RESET; 398 aic->msg_len = 1; 399 aic->msg_outq = AIC_MSG_MSGBUF; 400 } else { 401 aic->msg_outq = AIC_MSG_IDENTIFY; 402 if ((ti->flags & TINFO_TAG_ENB) != 0 && 403 (ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) != 0) 404 aic->msg_outq |= AIC_MSG_TAG_Q; 405 else 406 ti->lubusy |= 1 << scb->lun; 407 if ((ti->flags & TINFO_SDTR_NEGO) != 0) 408 aic->msg_outq |= AIC_MSG_SDTR; 409 } 410 411 aic_outb(aic, CLRSINT0, CLRSELDO); 412 aic_outb(aic, CLRSINT1, CLRBUSFREE); 413 aic_outb(aic, SCSISEQ, ENAUTOATNP); 414 aic_outb(aic, SIMODE0, 0); 415 aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT); 416 aic_outb(aic, SCSIRATE, ti->scsirate); 417} 418 419/* 420 * We are re-selected by a target, save the target id and wait for the 421 * target to further identify itself. 422 */ 423static void 424aic_reselected(struct aic_softc *aic) 425{ 426 u_int8_t selid; 427 428 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_reselected\n")); 429 430 /* 431 * If we have started a selection, it must have lost out in 432 * the arbitration, put the command back to the pending queue. 433 */ 434 if (aic->nexus) { 435 TAILQ_INSERT_HEAD(&aic->pending_ccbs, 436 &aic->nexus->ccb->ccb_h, sim_links.tqe); 437 aic->nexus = NULL; 438 } 439 440 selid = aic_inb(aic, SELID) & ~(1 << aic->initiator); 441 if (selid & (selid - 1)) { 442 /* this should never have happened */ 443 printf("aic_reselected: invalid selid %x\n", selid); 444 aic_reset(aic, /*initiate_reset*/TRUE); 445 return; 446 } 447 448 aic->state = AIC_RESELECTED; 449 aic->target = ffs(selid) - 1; 450 aic->lun = -1; 451 452 aic_outb(aic, CLRSINT0, CLRSELDI); 453 aic_outb(aic, CLRSINT1, CLRBUSFREE); 454 aic_outb(aic, SIMODE0, 0); 455 aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT); 456 aic_outb(aic, SCSISEQ, ENAUTOATNP); 457 aic_outb(aic, SCSIRATE, aic->tinfo[aic->target].scsirate); 458} 459 460/* 461 * Raise ATNO to signal the target that we have a message for it. 462 */ 463static __inline void 464aic_sched_msgout(struct aic_softc *aic, u_int8_t msg) 465{ 466 if (msg) { 467 aic->msg_buf[0] = msg; 468 aic->msg_len = 1; 469 } 470 aic->msg_outq |= AIC_MSG_MSGBUF; 471 aic_outb(aic, SCSISIGO, aic_inb(aic, SCSISIGI) | ATNO); 472} 473 474/* 475 * Wait for SPIORDY (SCSI PIO ready) flag, or a phase change. 476 */ 477static __inline int 478aic_spiordy(struct aic_softc *aic) 479{ 480 while (!(aic_inb(aic, DMASTAT) & INTSTAT) && 481 !(aic_inb(aic, SSTAT0) & SPIORDY)) 482 ; 483 return !(aic_inb(aic, DMASTAT) & INTSTAT); 484} 485 486/* 487 * Reestablish a disconnected nexus. 488 */ 489static void 490aic_reconnect(struct aic_softc *aic, int tag) 491{ 492 struct aic_scb *scb; 493 struct ccb_hdr *ccb_h; 494 495 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_reconnect\n")); 496 497 /* Find the nexus */ 498 scb = NULL; 499 TAILQ_FOREACH(ccb_h, &aic->nexus_ccbs, sim_links.tqe) { 500 scb = (struct aic_scb *)ccb_h->ccb_scb_ptr; 501 if (scb->target == aic->target && scb->lun == aic->lun && 502 (tag == -1 || scb->tag == tag)) 503 break; 504 } 505 506 /* ABORT if nothing is found */ 507 if (!ccb_h) { 508 if (tag == -1) 509 aic_sched_msgout(aic, MSG_ABORT); 510 else 511 aic_sched_msgout(aic, MSG_ABORT_TAG); 512 xpt_async(AC_UNSOL_RESEL, aic->path, NULL); 513 return; 514 } 515 516 /* Reestablish the nexus */ 517 TAILQ_REMOVE(&aic->nexus_ccbs, ccb_h, sim_links.tqe); 518 aic->nexus = scb; 519 scb->flags &= ~SCB_DISCONNECTED; 520 aic->state = AIC_HASNEXUS; 521} 522 523/* 524 * Read messages. 525 */ 526static void 527aic_msgin(struct aic_softc *aic) 528{ 529 int msglen; 530 531 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_msgin\n")); 532 533 aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE); 534 aic_outb(aic, SXFRCTL0, CHEN|SPIOEN); 535 536 aic->flags &= ~AIC_DROP_MSGIN; 537 aic->msg_len = 0; 538 do { 539 /* 540 * If a parity error is detected, drop the remaining 541 * bytes and inform the target so it could resend 542 * the messages. 543 */ 544 if (aic_inb(aic, SSTAT1) & SCSIPERR) { 545 aic_outb(aic, CLRSINT1, CLRSCSIPERR); 546 aic->flags |= AIC_DROP_MSGIN; 547 aic_sched_msgout(aic, MSG_PARITY_ERROR); 548 } 549 if ((aic->flags & AIC_DROP_MSGIN)) { 550 aic_inb(aic, SCSIDAT); 551 continue; 552 } 553 /* read the message byte without ACKing on it */ 554 aic->msg_buf[aic->msg_len++] = aic_inb(aic, SCSIBUS); 555 if (aic->msg_buf[0] == MSG_EXTENDED) { 556 if (aic->msg_len < 2) { 557 (void) aic_inb(aic, SCSIDAT); 558 continue; 559 } 560 switch (aic->msg_buf[2]) { 561 case MSG_EXT_SDTR: 562 msglen = MSG_EXT_SDTR_LEN; 563 break; 564 case MSG_EXT_WDTR: 565 msglen = MSG_EXT_WDTR_LEN; 566 break; 567 default: 568 msglen = 0; 569 break; 570 } 571 if (aic->msg_buf[1] != msglen) { 572 aic->flags |= AIC_DROP_MSGIN; 573 aic_sched_msgout(aic, MSG_MESSAGE_REJECT); 574 } 575 msglen += 2; 576 } else if (aic->msg_buf[0] >= 0x20 && aic->msg_buf[0] <= 0x2f) 577 msglen = 2; 578 else 579 msglen = 1; 580 /* 581 * If we have a complete message, handle it before the final 582 * ACK (in case we decide to reject the message). 583 */ 584 if (aic->msg_len == msglen) { 585 aic_handle_msgin(aic); 586 aic->msg_len = 0; 587 } 588 /* ACK on the message byte */ 589 (void) aic_inb(aic, SCSIDAT); 590 } while (aic_spiordy(aic)); 591 592 aic_outb(aic, SXFRCTL0, CHEN); 593 aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT); 594} 595 596/* 597 * Handle a message. 598 */ 599static void 600aic_handle_msgin(struct aic_softc *aic) 601{ 602 struct aic_scb *scb; 603 struct ccb_hdr *ccb_h; 604 struct aic_tinfo *ti; 605 struct ccb_trans_settings neg; 606 struct ccb_trans_settings_spi *spi = &neg.xport_specific.spi; 607 608 if (aic->state == AIC_RESELECTED) { 609 if (!MSG_ISIDENTIFY(aic->msg_buf[0])) { 610 aic_sched_msgout(aic, MSG_MESSAGE_REJECT); 611 return; 612 } 613 aic->lun = aic->msg_buf[0] & MSG_IDENTIFY_LUNMASK; 614 if (aic->tinfo[aic->target].lubusy & (1 << aic->lun)) 615 aic_reconnect(aic, -1); 616 else 617 aic->state = AIC_RECONNECTING; 618 return; 619 } 620 621 if (aic->state == AIC_RECONNECTING) { 622 if (aic->msg_buf[0] != MSG_SIMPLE_Q_TAG) { 623 aic_sched_msgout(aic, MSG_MESSAGE_REJECT); 624 return; 625 } 626 aic_reconnect(aic, aic->msg_buf[1]); 627 return; 628 } 629 630 switch (aic->msg_buf[0]) { 631 case MSG_CMDCOMPLETE: { 632 struct ccb_scsiio *csio; 633 scb = aic->nexus; 634 ccb_h = &scb->ccb->ccb_h; 635 csio = &scb->ccb->csio; 636 if ((scb->flags & SCB_SENSE) != 0) { 637 /* auto REQUEST SENSE command */ 638 scb->flags &= ~SCB_SENSE; 639 csio->sense_resid = scb->data_len; 640 if (scb->status == SCSI_STATUS_OK) { 641 ccb_h->status |= 642 CAM_SCSI_STATUS_ERROR|CAM_AUTOSNS_VALID; 643 /*scsi_sense_print(csio);*/ 644 } else { 645 ccb_h->status |= CAM_AUTOSENSE_FAIL; 646 printf("ccb %p sense failed %x\n", 647 ccb_h, scb->status); 648 } 649 } else { 650 csio->scsi_status = scb->status; 651 csio->resid = scb->data_len; 652 if (scb->status == SCSI_STATUS_OK) { 653 /* everything goes well */ 654 ccb_h->status |= CAM_REQ_CMP; 655 } else if ((ccb_h->flags & CAM_DIS_AUTOSENSE) == 0 && 656 (csio->scsi_status == SCSI_STATUS_CHECK_COND || 657 csio->scsi_status == SCSI_STATUS_CMD_TERMINATED)) { 658 /* try to retrieve sense information */ 659 scb->flags |= SCB_SENSE; 660 aic->flags |= AIC_BUSFREE_OK; 661 return; 662 } else 663 ccb_h->status |= CAM_SCSI_STATUS_ERROR; 664 } 665 aic_done(aic, scb); 666 aic->flags |= AIC_BUSFREE_OK; 667 break; 668 } 669 case MSG_EXTENDED: 670 switch (aic->msg_buf[2]) { 671 case MSG_EXT_SDTR: 672 scb = aic->nexus; 673 ti = &aic->tinfo[scb->target]; 674 if (ti->flags & TINFO_SDTR_SENT) { 675 ti->current.period = aic->msg_buf[3]; 676 ti->current.offset = aic->msg_buf[4]; 677 } else { 678 ti->current.period = aic->msg_buf[3] = 679 max(ti->goal.period, aic->msg_buf[3]); 680 ti->current.offset = aic->msg_buf[4] = 681 min(ti->goal.offset, aic->msg_buf[4]); 682 /* 683 * The target initiated the negotiation, 684 * send back a response. 685 */ 686 aic_sched_msgout(aic, 0); 687 } 688 ti->flags &= ~(TINFO_SDTR_SENT|TINFO_SDTR_NEGO); 689 ti->scsirate = ti->current.offset ? ti->current.offset | 690 ((ti->current.period * 4 + 49) / 50 - 2) << 4 : 0; 691 aic_outb(aic, SCSIRATE, ti->scsirate); 692 memset(&neg, 0, sizeof (neg)); 693 neg.protocol = PROTO_SCSI; 694 neg.protocol_version = SCSI_REV_2; 695 neg.transport = XPORT_SPI; 696 neg.transport_version = 2; 697 spi->sync_period = ti->goal.period = ti->current.period; 698 spi->sync_offset = ti->goal.offset = ti->current.offset; 699 spi->valid = CTS_SPI_VALID_SYNC_RATE 700 | CTS_SPI_VALID_SYNC_OFFSET; 701 ccb_h = &scb->ccb->ccb_h; 702 xpt_setup_ccb(&neg.ccb_h, ccb_h->path, 1); 703 xpt_async(AC_TRANSFER_NEG, ccb_h->path, &neg); 704 break; 705 case MSG_EXT_WDTR: 706 default: 707 aic_sched_msgout(aic, MSG_MESSAGE_REJECT); 708 break; 709 } 710 break; 711 case MSG_DISCONNECT: 712 scb = aic->nexus; 713 ccb_h = &scb->ccb->ccb_h; 714 TAILQ_INSERT_TAIL(&aic->nexus_ccbs, ccb_h, sim_links.tqe); 715 scb->flags |= SCB_DISCONNECTED; 716 aic->flags |= AIC_BUSFREE_OK; 717 aic->nexus = NULL; 718 CAM_DEBUG(ccb_h->path, CAM_DEBUG_TRACE, ("disconnected\n")); 719 break; 720 case MSG_MESSAGE_REJECT: 721 switch (aic->msg_outq & -aic->msg_outq) { 722 case AIC_MSG_TAG_Q: 723 scb = aic->nexus; 724 ti = &aic->tinfo[scb->target]; 725 ti->flags &= ~TINFO_TAG_ENB; 726 ti->lubusy |= 1 << scb->lun; 727 break; 728 case AIC_MSG_SDTR: 729 scb = aic->nexus; 730 ti = &aic->tinfo[scb->target]; 731 ti->current.period = ti->goal.period = 0; 732 ti->current.offset = ti->goal.offset = 0; 733 ti->flags &= ~(TINFO_SDTR_SENT|TINFO_SDTR_NEGO); 734 ti->scsirate = 0; 735 aic_outb(aic, SCSIRATE, ti->scsirate); 736 memset(&neg, 0, sizeof (neg)); 737 neg.protocol = PROTO_SCSI; 738 neg.protocol_version = SCSI_REV_2; 739 neg.transport = XPORT_SPI; 740 neg.transport_version = 2; 741 spi->sync_period = ti->current.period; 742 spi->sync_offset = ti->current.offset; 743 spi->valid = CTS_SPI_VALID_SYNC_RATE 744 | CTS_SPI_VALID_SYNC_OFFSET; 745 ccb_h = &scb->ccb->ccb_h; 746 xpt_setup_ccb(&neg.ccb_h, ccb_h->path, 1); 747 xpt_async(AC_TRANSFER_NEG, ccb_h->path, &neg); 748 break; 749 default: 750 break; 751 } 752 break; 753 case MSG_SAVEDATAPOINTER: 754 break; 755 case MSG_RESTOREPOINTERS: 756 break; 757 case MSG_NOOP: 758 break; 759 default: 760 aic_sched_msgout(aic, MSG_MESSAGE_REJECT); 761 break; 762 } 763} 764 765/* 766 * Send messages. 767 */ 768static void 769aic_msgout(struct aic_softc *aic) 770{ 771 struct aic_scb *scb; 772 union ccb *ccb; 773 struct aic_tinfo *ti; 774 int msgidx = 0; 775 776 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_msgout\n")); 777 778 aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE); 779 aic_outb(aic, SXFRCTL0, CHEN|SPIOEN); 780 781 /* 782 * If the previous phase is also the message out phase, 783 * we need to retransmit all the messages, probably 784 * because the target has detected a parity error during 785 * the past transmission. 786 */ 787 if (aic->prev_phase == PH_MSGOUT) 788 aic->msg_outq = aic->msg_sent; 789 790 do { 791 int q = aic->msg_outq; 792 if (msgidx > 0 && msgidx == aic->msg_len) { 793 /* complete message sent, start the next one */ 794 q &= -q; 795 aic->msg_sent |= q; 796 aic->msg_outq ^= q; 797 q = aic->msg_outq; 798 msgidx = 0; 799 } 800 if (msgidx == 0) { 801 /* setup the message */ 802 switch (q & -q) { 803 case AIC_MSG_IDENTIFY: 804 scb = aic->nexus; 805 ccb = scb->ccb; 806 ti = &aic->tinfo[scb->target]; 807 aic->msg_buf[0] = MSG_IDENTIFY(scb->lun, 808 (ti->flags & TINFO_DISC_ENB) && 809 !(ccb->ccb_h.flags & CAM_DIS_DISCONNECT)); 810 aic->msg_len = 1; 811 break; 812 case AIC_MSG_TAG_Q: 813 scb = aic->nexus; 814 ccb = scb->ccb; 815 aic->msg_buf[0] = ccb->csio.tag_action; 816 aic->msg_buf[1] = scb->tag; 817 aic->msg_len = 2; 818 break; 819 case AIC_MSG_SDTR: 820 scb = aic->nexus; 821 ti = &aic->tinfo[scb->target]; 822 aic->msg_buf[0] = MSG_EXTENDED; 823 aic->msg_buf[1] = MSG_EXT_SDTR_LEN; 824 aic->msg_buf[2] = MSG_EXT_SDTR; 825 aic->msg_buf[3] = ti->goal.period; 826 aic->msg_buf[4] = ti->goal.offset; 827 aic->msg_len = MSG_EXT_SDTR_LEN + 2; 828 ti->flags |= TINFO_SDTR_SENT; 829 break; 830 case AIC_MSG_MSGBUF: 831 /* a single message already in the buffer */ 832 if (aic->msg_buf[0] == MSG_BUS_DEV_RESET || 833 aic->msg_buf[0] == MSG_ABORT || 834 aic->msg_buf[0] == MSG_ABORT_TAG) 835 aic->flags |= AIC_BUSFREE_OK; 836 break; 837 } 838 } 839 /* 840 * If this is the last message byte of all messages, 841 * clear ATNO to signal transmission complete. 842 */ 843 if ((q & (q - 1)) == 0 && msgidx == aic->msg_len - 1) 844 aic_outb(aic, CLRSINT1, CLRATNO); 845 /* transmit the message byte */ 846 aic_outb(aic, SCSIDAT, aic->msg_buf[msgidx++]); 847 } while (aic_spiordy(aic)); 848 849 aic_outb(aic, SXFRCTL0, CHEN); 850 aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT); 851} 852 853/* 854 * Read data bytes. 855 */ 856static void 857aic_datain(struct aic_softc *aic) 858{ 859 struct aic_scb *scb = aic->nexus; 860 u_int8_t dmastat, dmacntrl0; 861 int n; 862 863 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_datain\n")); 864 865 aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE); 866 aic_outb(aic, SXFRCTL0, SCSIEN|DMAEN|CHEN); 867 868 dmacntrl0 = ENDMA; 869 if (aic->flags & AIC_DWIO_ENABLE) 870 dmacntrl0 |= DWORDPIO; 871 aic_outb(aic, DMACNTRL0, dmacntrl0); 872 873 while (scb->data_len > 0) { 874 for (;;) { 875 /* wait for the fifo to fill up or a phase change */ 876 dmastat = aic_inb(aic, DMASTAT); 877 if (dmastat & (INTSTAT|DFIFOFULL)) 878 break; 879 } 880 if (dmastat & DFIFOFULL) { 881 n = FIFOSIZE; 882 } else { 883 /* 884 * No more data, wait for the remaining bytes in 885 * the scsi fifo to be transfer to the host fifo. 886 */ 887 while (!(aic_inb(aic, SSTAT2) & SEMPTY)) 888 ; 889 n = aic_inb(aic, FIFOSTAT); 890 } 891 n = imin(scb->data_len, n); 892 if (aic->flags & AIC_DWIO_ENABLE) { 893 if (n >= 12) { 894 aic_insl(aic, DMADATALONG, scb->data_ptr, n>>2); 895 scb->data_ptr += n & ~3; 896 scb->data_len -= n & ~3; 897 n &= 3; 898 } 899 } else { 900 if (n >= 8) { 901 aic_insw(aic, DMADATA, scb->data_ptr, n >> 1); 902 scb->data_ptr += n & ~1; 903 scb->data_len -= n & ~1; 904 n &= 1; 905 } 906 } 907 if (n) { 908 aic_outb(aic, DMACNTRL0, ENDMA|B8MODE); 909 aic_insb(aic, DMADATA, scb->data_ptr, n); 910 scb->data_ptr += n; 911 scb->data_len -= n; 912 aic_outb(aic, DMACNTRL0, dmacntrl0); 913 } 914 915 if (dmastat & INTSTAT) 916 break; 917 } 918 919 aic_outb(aic, SXFRCTL0, CHEN); 920 aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT); 921} 922 923/* 924 * Send data bytes. 925 */ 926static void 927aic_dataout(struct aic_softc *aic) 928{ 929 struct aic_scb *scb = aic->nexus; 930 u_int8_t dmastat, dmacntrl0, sstat2; 931 int n; 932 933 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_dataout\n")); 934 935 aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE); 936 aic_outb(aic, SXFRCTL0, SCSIEN|DMAEN|CHEN); 937 938 dmacntrl0 = ENDMA|WRITE; 939 if (aic->flags & AIC_DWIO_ENABLE) 940 dmacntrl0 |= DWORDPIO; 941 aic_outb(aic, DMACNTRL0, dmacntrl0); 942 943 while (scb->data_len > 0) { 944 for (;;) { 945 /* wait for the fifo to clear up or a phase change */ 946 dmastat = aic_inb(aic, DMASTAT); 947 if (dmastat & (INTSTAT|DFIFOEMP)) 948 break; 949 } 950 if (dmastat & INTSTAT) 951 break; 952 n = imin(scb->data_len, FIFOSIZE); 953 if (aic->flags & AIC_DWIO_ENABLE) { 954 if (n >= 12) { 955 aic_outsl(aic, DMADATALONG, scb->data_ptr,n>>2); 956 scb->data_ptr += n & ~3; 957 scb->data_len -= n & ~3; 958 n &= 3; 959 } 960 } else { 961 if (n >= 8) { 962 aic_outsw(aic, DMADATA, scb->data_ptr, n >> 1); 963 scb->data_ptr += n & ~1; 964 scb->data_len -= n & ~1; 965 n &= 1; 966 } 967 } 968 if (n) { 969 aic_outb(aic, DMACNTRL0, ENDMA|WRITE|B8MODE); 970 aic_outsb(aic, DMADATA, scb->data_ptr, n); 971 scb->data_ptr += n; 972 scb->data_len -= n; 973 aic_outb(aic, DMACNTRL0, dmacntrl0); 974 } 975 } 976 977 for (;;) { 978 /* wait until all bytes in the fifos are transmitted */ 979 dmastat = aic_inb(aic, DMASTAT); 980 sstat2 = aic_inb(aic, SSTAT2); 981 if ((dmastat & DFIFOEMP) && (sstat2 & SEMPTY)) 982 break; 983 if (dmastat & INTSTAT) { 984 /* adjust for untransmitted bytes */ 985 n = aic_inb(aic, FIFOSTAT) + (sstat2 & 0xf); 986 scb->data_ptr -= n; 987 scb->data_len += n; 988 /* clear the fifo */ 989 aic_outb(aic, SXFRCTL0, CHEN|CLRCH); 990 aic_outb(aic, DMACNTRL0, RSTFIFO); 991 break; 992 } 993 } 994 995 aic_outb(aic, SXFRCTL0, CHEN); 996 aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT); 997} 998 999/* 1000 * Send the scsi command. 1001 */ 1002static void 1003aic_cmd(struct aic_softc *aic) 1004{ 1005 struct aic_scb *scb = aic->nexus; 1006 struct scsi_request_sense sense_cmd; 1007 1008 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_cmd\n")); 1009 1010 if (scb->flags & SCB_SENSE) { 1011 /* autosense request */ 1012 sense_cmd.opcode = REQUEST_SENSE; 1013 sense_cmd.byte2 = scb->lun << 5; 1014 sense_cmd.length = scb->ccb->csio.sense_len; 1015 sense_cmd.control = 0; 1016 sense_cmd.unused[0] = 0; 1017 sense_cmd.unused[1] = 0; 1018 scb->cmd_ptr = (u_int8_t *)&sense_cmd; 1019 scb->cmd_len = sizeof(sense_cmd); 1020 scb->data_ptr = (u_int8_t *)&scb->ccb->csio.sense_data; 1021 scb->data_len = scb->ccb->csio.sense_len; 1022 } 1023 1024 aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE); 1025 aic_outb(aic, DMACNTRL0, ENDMA|WRITE); 1026 aic_outb(aic, SXFRCTL0, SCSIEN|DMAEN|CHEN); 1027 aic_outsw(aic, DMADATA, (u_int16_t *)scb->cmd_ptr, scb->cmd_len >> 1); 1028 while ((aic_inb(aic, SSTAT2) & SEMPTY) == 0 && 1029 (aic_inb(aic, DMASTAT) & INTSTAT) == 0) 1030 ; 1031 aic_outb(aic, SXFRCTL0, CHEN); 1032 aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT); 1033} 1034 1035/* 1036 * Finish off a command. The caller is responsible to remove the ccb 1037 * from any queue. 1038 */ 1039static void 1040aic_done(struct aic_softc *aic, struct aic_scb *scb) 1041{ 1042 union ccb *ccb = scb->ccb; 1043 1044 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, 1045 ("aic_done - ccb %p status %x resid %d\n", 1046 ccb, ccb->ccb_h.status, ccb->csio.resid)); 1047 1048 callout_stop(&scb->timer); 1049 1050 if ((scb->flags & SCB_DEVICE_RESET) != 0 && 1051 ccb->ccb_h.func_code != XPT_RESET_DEV) { 1052 struct cam_path *path; 1053 struct ccb_hdr *ccb_h; 1054 cam_status error; 1055 1056 error = xpt_create_path(&path, /*periph*/NULL, 1057 cam_sim_path(aic->sim), 1058 scb->target, 1059 CAM_LUN_WILDCARD); 1060 1061 if (error == CAM_REQ_CMP) { 1062 xpt_async(AC_SENT_BDR, path, NULL); 1063 xpt_free_path(path); 1064 } 1065 1066 ccb_h = TAILQ_FIRST(&aic->pending_ccbs); 1067 while (ccb_h != NULL) { 1068 struct aic_scb *pending_scb; 1069 1070 pending_scb = (struct aic_scb *)ccb_h->ccb_scb_ptr; 1071 if (ccb_h->target_id == scb->target) { 1072 ccb_h->status |= CAM_BDR_SENT; 1073 ccb_h = TAILQ_NEXT(ccb_h, sim_links.tqe); 1074 TAILQ_REMOVE(&aic->pending_ccbs, 1075 &pending_scb->ccb->ccb_h, sim_links.tqe); 1076 aic_done(aic, pending_scb); 1077 } else { 1078 callout_reset(&pending_scb->timer, 1079 (ccb_h->timeout * hz) / 1000, aic_timeout, 1080 pending_scb); 1081 ccb_h = TAILQ_NEXT(ccb_h, sim_links.tqe); 1082 } 1083 } 1084 1085 ccb_h = TAILQ_FIRST(&aic->nexus_ccbs); 1086 while (ccb_h != NULL) { 1087 struct aic_scb *nexus_scb; 1088 1089 nexus_scb = (struct aic_scb *)ccb_h->ccb_scb_ptr; 1090 if (ccb_h->target_id == scb->target) { 1091 ccb_h->status |= CAM_BDR_SENT; 1092 ccb_h = TAILQ_NEXT(ccb_h, sim_links.tqe); 1093 TAILQ_REMOVE(&aic->nexus_ccbs, 1094 &nexus_scb->ccb->ccb_h, sim_links.tqe); 1095 aic_done(aic, nexus_scb); 1096 } else { 1097 callout_reset(&nexus_scb->timer, 1098 (ccb_h->timeout * hz) / 1000, aic_timeout, 1099 nexus_scb); 1100 ccb_h = TAILQ_NEXT(ccb_h, sim_links.tqe); 1101 } 1102 } 1103 } 1104 1105 if (aic->nexus == scb || scb->flags & SCB_DISCONNECTED) 1106 aic->tinfo[scb->target].lubusy &= ~(1 << scb->lun); 1107 1108 if (aic->nexus == scb) { 1109 aic->nexus = NULL; 1110 } 1111 aic_free_scb(aic, scb); 1112 xpt_done(ccb); 1113} 1114 1115static void 1116aic_poll(struct cam_sim *sim) 1117{ 1118 aic_intr_locked(cam_sim_softc(sim)); 1119} 1120 1121static void 1122aic_timeout(void *arg) 1123{ 1124 struct aic_scb *scb = (struct aic_scb *)arg; 1125 union ccb *ccb = scb->ccb; 1126 struct aic_softc *aic = (struct aic_softc *)ccb->ccb_h.ccb_aic_ptr; 1127 1128 mtx_assert(&aic->lock, MA_OWNED); 1129 xpt_print_path(ccb->ccb_h.path); 1130 printf("ccb %p - timed out", ccb); 1131 if (aic->nexus && aic->nexus != scb) 1132 printf(", nexus %p", aic->nexus->ccb); 1133 printf(", phase 0x%x, state %d\n", aic_inb(aic, SCSISIGI), aic->state); 1134 1135 if ((scb->flags & SCB_ACTIVE) == 0) { 1136 xpt_print_path(ccb->ccb_h.path); 1137 printf("ccb %p - timed out already completed\n", ccb); 1138 return; 1139 } 1140 1141 if ((scb->flags & SCB_DEVICE_RESET) == 0 && aic->nexus == scb) { 1142 struct ccb_hdr *ccb_h = &scb->ccb->ccb_h; 1143 struct aic_scb *pending_scb; 1144 1145 if ((ccb_h->status & CAM_RELEASE_SIMQ) == 0) { 1146 xpt_freeze_simq(aic->sim, /*count*/1); 1147 ccb_h->status |= CAM_RELEASE_SIMQ; 1148 } 1149 1150 TAILQ_FOREACH(ccb_h, &aic->pending_ccbs, sim_links.tqe) { 1151 pending_scb = ccb_h->ccb_scb_ptr; 1152 callout_stop(&pending_scb->timer); 1153 } 1154 1155 TAILQ_FOREACH(ccb_h, &aic->nexus_ccbs, sim_links.tqe) { 1156 pending_scb = ccb_h->ccb_scb_ptr; 1157 callout_stop(&pending_scb->timer); 1158 } 1159 1160 scb->flags |= SCB_DEVICE_RESET; 1161 callout_reset(&scb->timer, 5 * hz, aic_timeout, scb); 1162 aic_sched_msgout(aic, MSG_BUS_DEV_RESET); 1163 } else { 1164 if (aic->nexus == scb) { 1165 ccb->ccb_h.status |= CAM_CMD_TIMEOUT; 1166 aic_done(aic, scb); 1167 } 1168 aic_reset(aic, /*initiate_reset*/TRUE); 1169 } 1170} 1171 1172void 1173aic_intr(void *arg) 1174{ 1175 struct aic_softc *aic = (struct aic_softc *)arg; 1176 1177 mtx_lock(&aic->lock); 1178 aic_intr_locked(aic); 1179 mtx_unlock(&aic->lock); 1180} 1181 1182void 1183aic_intr_locked(struct aic_softc *aic) 1184{ 1185 u_int8_t sstat0, sstat1; 1186 union ccb *ccb; 1187 struct aic_scb *scb; 1188 1189 if (!(aic_inb(aic, DMASTAT) & INTSTAT)) 1190 return; 1191 1192 aic_outb(aic, DMACNTRL0, 0); 1193 1194 sstat0 = aic_inb(aic, SSTAT0); 1195 sstat1 = aic_inb(aic, SSTAT1); 1196 1197 if ((sstat1 & SCSIRSTI) != 0) { 1198 /* a device-initiated bus reset */ 1199 aic_outb(aic, CLRSINT1, CLRSCSIRSTI); 1200 aic_reset(aic, /*initiate_reset*/FALSE); 1201 return; 1202 } 1203 1204 if ((sstat1 & SCSIPERR) != 0) { 1205 aic_outb(aic, CLRSINT1, CLRSCSIPERR); 1206 aic_sched_msgout(aic, MSG_PARITY_ERROR); 1207 aic_outb(aic, DMACNTRL0, INTEN); 1208 return; 1209 } 1210 1211 if (aic_inb(aic, SSTAT4)) { 1212 aic_outb(aic, CLRSERR, CLRSYNCERR|CLRFWERR|CLRFRERR); 1213 aic_reset(aic, /*initiate_reset*/TRUE); 1214 return; 1215 } 1216 1217 if (aic->state <= AIC_SELECTING) { 1218 if ((sstat0 & SELDI) != 0) { 1219 aic_reselected(aic); 1220 aic_outb(aic, DMACNTRL0, INTEN); 1221 return; 1222 } 1223 1224 if ((sstat0 & SELDO) != 0) { 1225 aic_selected(aic); 1226 aic_outb(aic, DMACNTRL0, INTEN); 1227 return; 1228 } 1229 1230 if ((sstat1 & SELTO) != 0) { 1231 scb = aic->nexus; 1232 ccb = scb->ccb; 1233 ccb->ccb_h.status = CAM_SEL_TIMEOUT; 1234 aic_done(aic, scb); 1235 while ((sstat1 & BUSFREE) == 0) 1236 sstat1 = aic_inb(aic, SSTAT1); 1237 aic->flags |= AIC_BUSFREE_OK; 1238 } 1239 } 1240 1241 if ((sstat1 & BUSFREE) != 0) { 1242 aic_outb(aic, SCSISEQ, 0); 1243 aic_outb(aic, CLRSINT0, sstat0); 1244 aic_outb(aic, CLRSINT1, sstat1); 1245 if ((scb = aic->nexus)) { 1246 if ((aic->flags & AIC_BUSFREE_OK) == 0) { 1247 ccb = scb->ccb; 1248 ccb->ccb_h.status = CAM_UNEXP_BUSFREE; 1249 aic_done(aic, scb); 1250 } else if (scb->flags & SCB_DEVICE_RESET) { 1251 ccb = scb->ccb; 1252 if (ccb->ccb_h.func_code == XPT_RESET_DEV) { 1253 xpt_async(AC_SENT_BDR, 1254 ccb->ccb_h.path, NULL); 1255 ccb->ccb_h.status |= CAM_REQ_CMP; 1256 } else 1257 ccb->ccb_h.status |= CAM_CMD_TIMEOUT; 1258 aic_done(aic, scb); 1259 } else if (scb->flags & SCB_SENSE) { 1260 /* autosense request */ 1261 aic->flags &= ~AIC_BUSFREE_OK; 1262 aic->tinfo[scb->target].lubusy &= 1263 ~(1 << scb->lun); 1264 aic_select(aic); 1265 aic_outb(aic, DMACNTRL0, INTEN); 1266 return; 1267 } 1268 } 1269 aic->flags &= ~AIC_BUSFREE_OK; 1270 aic->state = AIC_IDLE; 1271 aic_start(aic); 1272 aic_outb(aic, DMACNTRL0, INTEN); 1273 return; 1274 } 1275 1276 if ((sstat1 & REQINIT) != 0) { 1277 u_int8_t phase = aic_inb(aic, SCSISIGI) & PH_MASK; 1278 aic_outb(aic, SCSISIGO, phase); 1279 aic_outb(aic, CLRSINT1, CLRPHASECHG); 1280 1281 switch (phase) { 1282 case PH_MSGOUT: 1283 aic_msgout(aic); 1284 break; 1285 case PH_MSGIN: 1286 aic_msgin(aic); 1287 break; 1288 case PH_STAT: 1289 scb = aic->nexus; 1290 ccb = scb->ccb; 1291 aic_outb(aic, DMACNTRL0, 0); 1292 aic_outb(aic, SXFRCTL0, CHEN|SPIOEN); 1293 scb->status = aic_inb(aic, SCSIDAT); 1294 aic_outb(aic, SXFRCTL0, CHEN); 1295 break; 1296 case PH_CMD: 1297 aic_cmd(aic); 1298 break; 1299 case PH_DATAIN: 1300 aic_datain(aic); 1301 break; 1302 case PH_DATAOUT: 1303 aic_dataout(aic); 1304 break; 1305 } 1306 aic->prev_phase = phase; 1307 aic_outb(aic, DMACNTRL0, INTEN); 1308 return; 1309 } 1310 1311 printf("aic_intr: unexpected intr sstat0 %x sstat1 %x\n", 1312 sstat0, sstat1); 1313 aic_outb(aic, DMACNTRL0, INTEN); 1314} 1315 1316/* 1317 * Reset ourselves. 1318 */ 1319static void 1320aic_chip_reset(struct aic_softc *aic) 1321{ 1322 /* 1323 * Doc. recommends to clear these two registers before 1324 * operations commence 1325 */ 1326 aic_outb(aic, SCSITEST, 0); 1327 aic_outb(aic, TEST, 0); 1328 1329 /* Reset SCSI-FIFO and abort any transfers */ 1330 aic_outb(aic, SXFRCTL0, CHEN|CLRCH|CLRSTCNT); 1331 1332 /* Reset HOST-FIFO */ 1333 aic_outb(aic, DMACNTRL0, RSTFIFO); 1334 aic_outb(aic, DMACNTRL1, 0); 1335 1336 /* Disable all selection features */ 1337 aic_outb(aic, SCSISEQ, 0); 1338 aic_outb(aic, SXFRCTL1, 0); 1339 1340 /* Disable interrupts */ 1341 aic_outb(aic, SIMODE0, 0); 1342 aic_outb(aic, SIMODE1, 0); 1343 1344 /* Clear interrupts */ 1345 aic_outb(aic, CLRSINT0, 0x7f); 1346 aic_outb(aic, CLRSINT1, 0xef); 1347 1348 /* Disable synchronous transfers */ 1349 aic_outb(aic, SCSIRATE, 0); 1350 1351 /* Haven't seen ant errors (yet) */ 1352 aic_outb(aic, CLRSERR, 0x07); 1353 1354 /* Set our SCSI-ID */ 1355 aic_outb(aic, SCSIID, aic->initiator << OID_S); 1356 aic_outb(aic, BRSTCNTRL, EISA_BRST_TIM); 1357} 1358 1359/* 1360 * Reset the SCSI bus 1361 */ 1362static void 1363aic_scsi_reset(struct aic_softc *aic) 1364{ 1365 aic_outb(aic, SCSISEQ, SCSIRSTO); 1366 DELAY(500); 1367 aic_outb(aic, SCSISEQ, 0); 1368 DELAY(50); 1369} 1370 1371/* 1372 * Reset. Abort all pending commands. 1373 */ 1374static void 1375aic_reset(struct aic_softc *aic, int initiate_reset) 1376{ 1377 struct ccb_hdr *ccb_h; 1378 1379 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_reset\n")); 1380 1381 if (initiate_reset) 1382 aic_scsi_reset(aic); 1383 aic_chip_reset(aic); 1384 1385 xpt_async(AC_BUS_RESET, aic->path, NULL); 1386 1387 while ((ccb_h = TAILQ_FIRST(&aic->pending_ccbs)) != NULL) { 1388 TAILQ_REMOVE(&aic->pending_ccbs, ccb_h, sim_links.tqe); 1389 ccb_h->status |= CAM_SCSI_BUS_RESET; 1390 aic_done(aic, (struct aic_scb *)ccb_h->ccb_scb_ptr); 1391 } 1392 1393 while ((ccb_h = TAILQ_FIRST(&aic->nexus_ccbs)) != NULL) { 1394 TAILQ_REMOVE(&aic->nexus_ccbs, ccb_h, sim_links.tqe); 1395 ccb_h->status |= CAM_SCSI_BUS_RESET; 1396 aic_done(aic, (struct aic_scb *)ccb_h->ccb_scb_ptr); 1397 } 1398 1399 if (aic->nexus) { 1400 ccb_h = &aic->nexus->ccb->ccb_h; 1401 ccb_h->status |= CAM_SCSI_BUS_RESET; 1402 aic_done(aic, aic->nexus); 1403 } 1404 1405 aic->state = AIC_IDLE; 1406 aic_outb(aic, DMACNTRL0, INTEN); 1407} 1408 1409static char *aic_chip_names[] = { 1410 "AIC6260", "AIC6360", "AIC6370", "GM82C700", 1411}; 1412 1413static struct { 1414 int type; 1415 char *idstring; 1416} aic_chip_ids[] = { 1417 { AIC6360, IDSTRING_AIC6360 }, 1418 { AIC6370, IDSTRING_AIC6370 }, 1419 { GM82C700, IDSTRING_GM82C700 }, 1420}; 1421 1422static void 1423aic_init(struct aic_softc *aic) 1424{ 1425 struct aic_scb *scb; 1426 struct aic_tinfo *ti; 1427 u_int8_t porta, portb; 1428 char chip_id[33]; 1429 int i; 1430 1431 TAILQ_INIT(&aic->pending_ccbs); 1432 TAILQ_INIT(&aic->nexus_ccbs); 1433 SLIST_INIT(&aic->free_scbs); 1434 aic->nexus = NULL; 1435 aic->state = AIC_IDLE; 1436 aic->prev_phase = -1; 1437 aic->flags = 0; 1438 1439 aic_chip_reset(aic); 1440 aic_scsi_reset(aic); 1441 1442 /* determine the chip type from its ID string */ 1443 aic->chip_type = AIC6260; 1444 aic_insb(aic, ID, chip_id, sizeof(chip_id) - 1); 1445 chip_id[sizeof(chip_id) - 1] = '\0'; 1446 for (i = 0; i < sizeof(aic_chip_ids) / sizeof(aic_chip_ids[0]); i++) { 1447 if (!strcmp(chip_id, aic_chip_ids[i].idstring)) { 1448 aic->chip_type = aic_chip_ids[i].type; 1449 break; 1450 } 1451 } 1452 1453 porta = aic_inb(aic, PORTA); 1454 portb = aic_inb(aic, PORTB); 1455 1456 aic->initiator = PORTA_ID(porta); 1457 if (PORTA_PARITY(porta)) 1458 aic->flags |= AIC_PARITY_ENABLE; 1459 if (PORTB_DISC(portb)) 1460 aic->flags |= AIC_DISC_ENABLE; 1461 if (PORTB_DMA(portb)) 1462 aic->flags |= AIC_DMA_ENABLE; 1463 1464 /* 1465 * We can do fast SCSI (10MHz clock rate) if bit 4 of portb 1466 * is set and we've got a 6360. The 6260 can only do standard 1467 * 5MHz SCSI. 1468 */ 1469 if (aic->chip_type > AIC6260 || aic_inb(aic, REV)) { 1470 if (PORTB_FSYNC(portb)) 1471 aic->flags |= AIC_FAST_ENABLE; 1472 aic->flags |= AIC_DWIO_ENABLE; 1473 } 1474 1475 if (aic->flags & AIC_FAST_ENABLE) 1476 aic->max_period = AIC_FAST_SYNC_PERIOD; 1477 else 1478 aic->max_period = AIC_SYNC_PERIOD; 1479 aic->min_period = AIC_MIN_SYNC_PERIOD; 1480 1481 for (i = 255; i >= 0; i--) { 1482 scb = &aic->scbs[i]; 1483 scb->tag = i; 1484 callout_init_mtx(&scb->timer, &aic->lock, 0); 1485 aic_free_scb(aic, scb); 1486 } 1487 1488 for (i = 0; i < 8; i++) { 1489 if (i == aic->initiator) 1490 continue; 1491 ti = &aic->tinfo[i]; 1492 bzero(ti, sizeof(*ti)); 1493 ti->flags = TINFO_TAG_ENB; 1494 if (aic->flags & AIC_DISC_ENABLE) 1495 ti->flags |= TINFO_DISC_ENB; 1496 ti->user.period = aic->max_period; 1497 ti->user.offset = AIC_SYNC_OFFSET; 1498 ti->scsirate = 0; 1499 } 1500 1501 aic_outb(aic, DMACNTRL0, INTEN); 1502} 1503 1504int 1505aic_probe(struct aic_softc *aic) 1506{ 1507 int i; 1508 1509 /* Remove aic6360 from possible powerdown mode */ 1510 aic_outb(aic, DMACNTRL0, 0); 1511 1512#define STSIZE 16 1513 aic_outb(aic, DMACNTRL1, 0); /* Reset stack pointer */ 1514 for (i = 0; i < STSIZE; i++) 1515 aic_outb(aic, STACK, i); 1516 1517 /* See if we can pull out the same sequence */ 1518 aic_outb(aic, DMACNTRL1, 0); 1519 for (i = 0; i < STSIZE && aic_inb(aic, STACK) == i; i++) 1520 ; 1521 if (i != STSIZE) 1522 return (ENXIO); 1523#undef STSIZE 1524 return (0); 1525} 1526 1527int 1528aic_attach(struct aic_softc *aic) 1529{ 1530 struct cam_devq *devq; 1531 1532 /* 1533 * Create the device queue for our SIM. 1534 */ 1535 devq = cam_simq_alloc(256); 1536 if (devq == NULL) 1537 return (ENOMEM); 1538 1539 /* 1540 * Construct our SIM entry 1541 */ 1542 aic->sim = cam_sim_alloc(aic_action, aic_poll, "aic", aic, 1543 device_get_unit(aic->dev), &aic->lock, 2, 256, devq); 1544 if (aic->sim == NULL) { 1545 cam_simq_free(devq); 1546 return (ENOMEM); 1547 } 1548 1549 mtx_lock(&aic->lock); 1550 if (xpt_bus_register(aic->sim, aic->dev, 0) != CAM_SUCCESS) { 1551 cam_sim_free(aic->sim, /*free_devq*/TRUE); 1552 mtx_unlock(&aic->lock); 1553 return (ENXIO); 1554 } 1555 1556 if (xpt_create_path(&aic->path, /*periph*/NULL, 1557 cam_sim_path(aic->sim), CAM_TARGET_WILDCARD, 1558 CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 1559 xpt_bus_deregister(cam_sim_path(aic->sim)); 1560 cam_sim_free(aic->sim, /*free_devq*/TRUE); 1561 mtx_unlock(&aic->lock); 1562 return (ENXIO); 1563 } 1564 1565 aic_init(aic); 1566 1567 device_printf(aic->dev, "%s", aic_chip_names[aic->chip_type]); 1568 if (aic->flags & AIC_DMA_ENABLE) 1569 printf(", dma"); 1570 if (aic->flags & AIC_DISC_ENABLE) 1571 printf(", disconnection"); 1572 if (aic->flags & AIC_PARITY_ENABLE) 1573 printf(", parity check"); 1574 if (aic->flags & AIC_FAST_ENABLE) 1575 printf(", fast SCSI"); 1576 printf("\n"); 1577 mtx_unlock(&aic->lock); 1578 return (0); 1579} 1580 1581int 1582aic_detach(struct aic_softc *aic) 1583{ 1584 struct aic_scb *scb; 1585 int i; 1586 1587 mtx_lock(&aic->lock); 1588 xpt_async(AC_LOST_DEVICE, aic->path, NULL); 1589 xpt_free_path(aic->path); 1590 xpt_bus_deregister(cam_sim_path(aic->sim)); 1591 cam_sim_free(aic->sim, /*free_devq*/TRUE); 1592 mtx_unlock(&aic->lock); 1593 for (i = 255; i >= 0; i--) { 1594 scb = &aic->scbs[i]; 1595 callout_drain(&scb->timer); 1596 } 1597 return (0); 1598} 1599