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