adwcam.c revision 139749
1/*- 2 * CAM SCSI interface for the the Advanced Systems Inc. 3 * Second Generation SCSI controllers. 4 * 5 * Product specific probe and attach routines can be found in: 6 * 7 * adw_pci.c ABP[3]940UW, ABP950UW, ABP3940U2W 8 * 9 * Copyright (c) 1998, 1999, 2000 Justin Gibbs. 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions, and the following disclaimer, 17 * without modification. 18 * 2. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 25 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33/* 34 * Ported from: 35 * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters 36 * 37 * Copyright (c) 1995-1998 Advanced System Products, Inc. 38 * All Rights Reserved. 39 * 40 * Redistribution and use in source and binary forms, with or without 41 * modification, are permitted provided that redistributions of source 42 * code retain the above copyright notice and this comment without 43 * modification. 44 */ 45 46#include <sys/cdefs.h> 47__FBSDID("$FreeBSD: head/sys/dev/advansys/adwcam.c 139749 2005-01-06 01:43:34Z imp $"); 48 49#include <sys/param.h> 50#include <sys/systm.h> 51#include <sys/kernel.h> 52#include <sys/malloc.h> 53#include <sys/lock.h> 54#include <sys/mutex.h> 55#include <sys/bus.h> 56 57#include <machine/bus_pio.h> 58#include <machine/bus_memio.h> 59#include <machine/bus.h> 60#include <machine/resource.h> 61 62#include <sys/rman.h> 63 64#include <cam/cam.h> 65#include <cam/cam_ccb.h> 66#include <cam/cam_sim.h> 67#include <cam/cam_xpt_sim.h> 68#include <cam/cam_debug.h> 69 70#include <cam/scsi/scsi_message.h> 71 72#include <dev/advansys/adwvar.h> 73 74/* Definitions for our use of the SIM private CCB area */ 75#define ccb_acb_ptr spriv_ptr0 76#define ccb_adw_ptr spriv_ptr1 77 78u_long adw_unit; 79 80static __inline cam_status adwccbstatus(union ccb*); 81static __inline struct acb* adwgetacb(struct adw_softc *adw); 82static __inline void adwfreeacb(struct adw_softc *adw, 83 struct acb *acb); 84 85static void adwmapmem(void *arg, bus_dma_segment_t *segs, 86 int nseg, int error); 87static struct sg_map_node* 88 adwallocsgmap(struct adw_softc *adw); 89static int adwallocacbs(struct adw_softc *adw); 90 91static void adwexecuteacb(void *arg, bus_dma_segment_t *dm_segs, 92 int nseg, int error); 93static void adw_action(struct cam_sim *sim, union ccb *ccb); 94static void adw_poll(struct cam_sim *sim); 95static void adw_async(void *callback_arg, u_int32_t code, 96 struct cam_path *path, void *arg); 97static void adwprocesserror(struct adw_softc *adw, struct acb *acb); 98static void adwtimeout(void *arg); 99static void adw_handle_device_reset(struct adw_softc *adw, 100 u_int target); 101static void adw_handle_bus_reset(struct adw_softc *adw, 102 int initiated); 103 104static __inline cam_status 105adwccbstatus(union ccb* ccb) 106{ 107 return (ccb->ccb_h.status & CAM_STATUS_MASK); 108} 109 110static __inline struct acb* 111adwgetacb(struct adw_softc *adw) 112{ 113 struct acb* acb; 114 int s; 115 116 s = splcam(); 117 if ((acb = SLIST_FIRST(&adw->free_acb_list)) != NULL) { 118 SLIST_REMOVE_HEAD(&adw->free_acb_list, links); 119 } else if (adw->num_acbs < adw->max_acbs) { 120 adwallocacbs(adw); 121 acb = SLIST_FIRST(&adw->free_acb_list); 122 if (acb == NULL) 123 printf("%s: Can't malloc ACB\n", adw_name(adw)); 124 else { 125 SLIST_REMOVE_HEAD(&adw->free_acb_list, links); 126 } 127 } 128 splx(s); 129 130 return (acb); 131} 132 133static __inline void 134adwfreeacb(struct adw_softc *adw, struct acb *acb) 135{ 136 int s; 137 138 s = splcam(); 139 if ((acb->state & ACB_ACTIVE) != 0) 140 LIST_REMOVE(&acb->ccb->ccb_h, sim_links.le); 141 if ((acb->state & ACB_RELEASE_SIMQ) != 0) 142 acb->ccb->ccb_h.status |= CAM_RELEASE_SIMQ; 143 else if ((adw->state & ADW_RESOURCE_SHORTAGE) != 0 144 && (acb->ccb->ccb_h.status & CAM_RELEASE_SIMQ) == 0) { 145 acb->ccb->ccb_h.status |= CAM_RELEASE_SIMQ; 146 adw->state &= ~ADW_RESOURCE_SHORTAGE; 147 } 148 acb->state = ACB_FREE; 149 SLIST_INSERT_HEAD(&adw->free_acb_list, acb, links); 150 splx(s); 151} 152 153static void 154adwmapmem(void *arg, bus_dma_segment_t *segs, int nseg, int error) 155{ 156 bus_addr_t *busaddrp; 157 158 busaddrp = (bus_addr_t *)arg; 159 *busaddrp = segs->ds_addr; 160} 161 162static struct sg_map_node * 163adwallocsgmap(struct adw_softc *adw) 164{ 165 struct sg_map_node *sg_map; 166 167 sg_map = malloc(sizeof(*sg_map), M_DEVBUF, M_NOWAIT); 168 169 if (sg_map == NULL) 170 return (NULL); 171 172 /* Allocate S/G space for the next batch of ACBS */ 173 if (bus_dmamem_alloc(adw->sg_dmat, (void **)&sg_map->sg_vaddr, 174 BUS_DMA_NOWAIT, &sg_map->sg_dmamap) != 0) { 175 free(sg_map, M_DEVBUF); 176 return (NULL); 177 } 178 179 SLIST_INSERT_HEAD(&adw->sg_maps, sg_map, links); 180 181 bus_dmamap_load(adw->sg_dmat, sg_map->sg_dmamap, sg_map->sg_vaddr, 182 PAGE_SIZE, adwmapmem, &sg_map->sg_physaddr, /*flags*/0); 183 184 bzero(sg_map->sg_vaddr, PAGE_SIZE); 185 return (sg_map); 186} 187 188/* 189 * Allocate another chunk of CCB's. Return count of entries added. 190 * Assumed to be called at splcam(). 191 */ 192static int 193adwallocacbs(struct adw_softc *adw) 194{ 195 struct acb *next_acb; 196 struct sg_map_node *sg_map; 197 bus_addr_t busaddr; 198 struct adw_sg_block *blocks; 199 int newcount; 200 int i; 201 202 next_acb = &adw->acbs[adw->num_acbs]; 203 sg_map = adwallocsgmap(adw); 204 205 if (sg_map == NULL) 206 return (0); 207 208 blocks = sg_map->sg_vaddr; 209 busaddr = sg_map->sg_physaddr; 210 211 newcount = (PAGE_SIZE / (ADW_SG_BLOCKCNT * sizeof(*blocks))); 212 for (i = 0; adw->num_acbs < adw->max_acbs && i < newcount; i++) { 213 int error; 214 215 error = bus_dmamap_create(adw->buffer_dmat, /*flags*/0, 216 &next_acb->dmamap); 217 if (error != 0) 218 break; 219 next_acb->queue.scsi_req_baddr = acbvtob(adw, next_acb); 220 next_acb->queue.scsi_req_bo = acbvtobo(adw, next_acb); 221 next_acb->queue.sense_baddr = 222 acbvtob(adw, next_acb) + offsetof(struct acb, sense_data); 223 next_acb->sg_blocks = blocks; 224 next_acb->sg_busaddr = busaddr; 225 next_acb->state = ACB_FREE; 226 SLIST_INSERT_HEAD(&adw->free_acb_list, next_acb, links); 227 blocks += ADW_SG_BLOCKCNT; 228 busaddr += ADW_SG_BLOCKCNT * sizeof(*blocks); 229 next_acb++; 230 adw->num_acbs++; 231 } 232 return (i); 233} 234 235static void 236adwexecuteacb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) 237{ 238 struct acb *acb; 239 union ccb *ccb; 240 struct adw_softc *adw; 241 int s; 242 243 acb = (struct acb *)arg; 244 ccb = acb->ccb; 245 adw = (struct adw_softc *)ccb->ccb_h.ccb_adw_ptr; 246 247 if (error != 0) { 248 if (error != EFBIG) 249 printf("%s: Unexepected error 0x%x returned from " 250 "bus_dmamap_load\n", adw_name(adw), error); 251 if (ccb->ccb_h.status == CAM_REQ_INPROG) { 252 xpt_freeze_devq(ccb->ccb_h.path, /*count*/1); 253 ccb->ccb_h.status = CAM_REQ_TOO_BIG|CAM_DEV_QFRZN; 254 } 255 adwfreeacb(adw, acb); 256 xpt_done(ccb); 257 return; 258 } 259 260 if (nseg != 0) { 261 bus_dmasync_op_t op; 262 263 acb->queue.data_addr = dm_segs[0].ds_addr; 264 acb->queue.data_cnt = ccb->csio.dxfer_len; 265 if (nseg > 1) { 266 struct adw_sg_block *sg_block; 267 struct adw_sg_elm *sg; 268 bus_addr_t sg_busaddr; 269 u_int sg_index; 270 bus_dma_segment_t *end_seg; 271 272 end_seg = dm_segs + nseg; 273 274 sg_busaddr = acb->sg_busaddr; 275 sg_index = 0; 276 /* Copy the segments into our SG list */ 277 for (sg_block = acb->sg_blocks;; sg_block++) { 278 u_int i; 279 280 sg = sg_block->sg_list; 281 for (i = 0; i < ADW_NO_OF_SG_PER_BLOCK; i++) { 282 if (dm_segs >= end_seg) 283 break; 284 285 sg->sg_addr = dm_segs->ds_addr; 286 sg->sg_count = dm_segs->ds_len; 287 sg++; 288 dm_segs++; 289 } 290 sg_block->sg_cnt = i; 291 sg_index += i; 292 if (dm_segs == end_seg) { 293 sg_block->sg_busaddr_next = 0; 294 break; 295 } else { 296 sg_busaddr += 297 sizeof(struct adw_sg_block); 298 sg_block->sg_busaddr_next = sg_busaddr; 299 } 300 } 301 acb->queue.sg_real_addr = acb->sg_busaddr; 302 } else { 303 acb->queue.sg_real_addr = 0; 304 } 305 306 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) 307 op = BUS_DMASYNC_PREREAD; 308 else 309 op = BUS_DMASYNC_PREWRITE; 310 311 bus_dmamap_sync(adw->buffer_dmat, acb->dmamap, op); 312 313 } else { 314 acb->queue.data_addr = 0; 315 acb->queue.data_cnt = 0; 316 acb->queue.sg_real_addr = 0; 317 } 318 319 s = splcam(); 320 321 /* 322 * Last time we need to check if this CCB needs to 323 * be aborted. 324 */ 325 if (ccb->ccb_h.status != CAM_REQ_INPROG) { 326 if (nseg != 0) 327 bus_dmamap_unload(adw->buffer_dmat, acb->dmamap); 328 adwfreeacb(adw, acb); 329 xpt_done(ccb); 330 splx(s); 331 return; 332 } 333 334 acb->state |= ACB_ACTIVE; 335 ccb->ccb_h.status |= CAM_SIM_QUEUED; 336 LIST_INSERT_HEAD(&adw->pending_ccbs, &ccb->ccb_h, sim_links.le); 337 ccb->ccb_h.timeout_ch = 338 timeout(adwtimeout, (caddr_t)acb, 339 (ccb->ccb_h.timeout * hz) / 1000); 340 341 adw_send_acb(adw, acb, acbvtob(adw, acb)); 342 343 splx(s); 344} 345 346static void 347adw_action(struct cam_sim *sim, union ccb *ccb) 348{ 349 struct adw_softc *adw; 350 351 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("adw_action\n")); 352 353 adw = (struct adw_softc *)cam_sim_softc(sim); 354 355 switch (ccb->ccb_h.func_code) { 356 /* Common cases first */ 357 case XPT_SCSI_IO: /* Execute the requested I/O operation */ 358 { 359 struct ccb_scsiio *csio; 360 struct ccb_hdr *ccbh; 361 struct acb *acb; 362 363 csio = &ccb->csio; 364 ccbh = &ccb->ccb_h; 365 366 /* Max supported CDB length is 12 bytes */ 367 if (csio->cdb_len > 12) { 368 ccb->ccb_h.status = CAM_REQ_INVALID; 369 xpt_done(ccb); 370 return; 371 } 372 373 if ((acb = adwgetacb(adw)) == NULL) { 374 int s; 375 376 s = splcam(); 377 adw->state |= ADW_RESOURCE_SHORTAGE; 378 splx(s); 379 xpt_freeze_simq(sim, /*count*/1); 380 ccb->ccb_h.status = CAM_REQUEUE_REQ; 381 xpt_done(ccb); 382 return; 383 } 384 385 /* Link acb and ccb so we can find one from the other */ 386 acb->ccb = ccb; 387 ccb->ccb_h.ccb_acb_ptr = acb; 388 ccb->ccb_h.ccb_adw_ptr = adw; 389 390 acb->queue.cntl = 0; 391 acb->queue.target_cmd = 0; 392 acb->queue.target_id = ccb->ccb_h.target_id; 393 acb->queue.target_lun = ccb->ccb_h.target_lun; 394 395 acb->queue.mflag = 0; 396 acb->queue.sense_len = 397 MIN(csio->sense_len, sizeof(acb->sense_data)); 398 acb->queue.cdb_len = csio->cdb_len; 399 if ((ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) != 0) { 400 switch (csio->tag_action) { 401 case MSG_SIMPLE_Q_TAG: 402 acb->queue.scsi_cntl = ADW_QSC_SIMPLE_Q_TAG; 403 break; 404 case MSG_HEAD_OF_Q_TAG: 405 acb->queue.scsi_cntl = ADW_QSC_HEAD_OF_Q_TAG; 406 break; 407 case MSG_ORDERED_Q_TAG: 408 acb->queue.scsi_cntl = ADW_QSC_ORDERED_Q_TAG; 409 break; 410 default: 411 acb->queue.scsi_cntl = ADW_QSC_NO_TAGMSG; 412 break; 413 } 414 } else 415 acb->queue.scsi_cntl = ADW_QSC_NO_TAGMSG; 416 417 if ((ccb->ccb_h.flags & CAM_DIS_DISCONNECT) != 0) 418 acb->queue.scsi_cntl |= ADW_QSC_NO_DISC; 419 420 acb->queue.done_status = 0; 421 acb->queue.scsi_status = 0; 422 acb->queue.host_status = 0; 423 acb->queue.sg_wk_ix = 0; 424 if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) { 425 if ((ccb->ccb_h.flags & CAM_CDB_PHYS) == 0) { 426 bcopy(csio->cdb_io.cdb_ptr, 427 acb->queue.cdb, csio->cdb_len); 428 } else { 429 /* I guess I could map it in... */ 430 ccb->ccb_h.status = CAM_REQ_INVALID; 431 adwfreeacb(adw, acb); 432 xpt_done(ccb); 433 return; 434 } 435 } else { 436 bcopy(csio->cdb_io.cdb_bytes, 437 acb->queue.cdb, csio->cdb_len); 438 } 439 440 /* 441 * If we have any data to send with this command, 442 * map it into bus space. 443 */ 444 if ((ccbh->flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 445 if ((ccbh->flags & CAM_SCATTER_VALID) == 0) { 446 /* 447 * We've been given a pointer 448 * to a single buffer. 449 */ 450 if ((ccbh->flags & CAM_DATA_PHYS) == 0) { 451 int s; 452 int error; 453 454 s = splsoftvm(); 455 error = 456 bus_dmamap_load(adw->buffer_dmat, 457 acb->dmamap, 458 csio->data_ptr, 459 csio->dxfer_len, 460 adwexecuteacb, 461 acb, /*flags*/0); 462 if (error == EINPROGRESS) { 463 /* 464 * So as to maintain ordering, 465 * freeze the controller queue 466 * until our mapping is 467 * returned. 468 */ 469 xpt_freeze_simq(sim, 1); 470 acb->state |= CAM_RELEASE_SIMQ; 471 } 472 splx(s); 473 } else { 474 struct bus_dma_segment seg; 475 476 /* Pointer to physical buffer */ 477 seg.ds_addr = 478 (bus_addr_t)csio->data_ptr; 479 seg.ds_len = csio->dxfer_len; 480 adwexecuteacb(acb, &seg, 1, 0); 481 } 482 } else { 483 struct bus_dma_segment *segs; 484 485 if ((ccbh->flags & CAM_DATA_PHYS) != 0) 486 panic("adw_action - Physical " 487 "segment pointers " 488 "unsupported"); 489 490 if ((ccbh->flags&CAM_SG_LIST_PHYS)==0) 491 panic("adw_action - Virtual " 492 "segment addresses " 493 "unsupported"); 494 495 /* Just use the segments provided */ 496 segs = (struct bus_dma_segment *)csio->data_ptr; 497 adwexecuteacb(acb, segs, csio->sglist_cnt, 498 (csio->sglist_cnt < ADW_SGSIZE) 499 ? 0 : EFBIG); 500 } 501 } else { 502 adwexecuteacb(acb, NULL, 0, 0); 503 } 504 break; 505 } 506 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */ 507 { 508 adw_idle_cmd_status_t status; 509 510 status = adw_idle_cmd_send(adw, ADW_IDLE_CMD_DEVICE_RESET, 511 ccb->ccb_h.target_id); 512 if (status == ADW_IDLE_CMD_SUCCESS) { 513 ccb->ccb_h.status = CAM_REQ_CMP; 514 if (bootverbose) { 515 xpt_print_path(ccb->ccb_h.path); 516 printf("BDR Delivered\n"); 517 } 518 } else 519 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 520 xpt_done(ccb); 521 break; 522 } 523 case XPT_ABORT: /* Abort the specified CCB */ 524 /* XXX Implement */ 525 ccb->ccb_h.status = CAM_REQ_INVALID; 526 xpt_done(ccb); 527 break; 528 case XPT_SET_TRAN_SETTINGS: 529 { 530 struct ccb_trans_settings *cts; 531 u_int target_mask; 532 int s; 533 534 cts = &ccb->cts; 535 target_mask = 0x01 << ccb->ccb_h.target_id; 536 537 s = splcam(); 538 if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0) { 539 u_int sdtrdone; 540 541 sdtrdone = adw_lram_read_16(adw, ADW_MC_SDTR_DONE); 542 if ((cts->valid & CCB_TRANS_DISC_VALID) != 0) { 543 u_int discenb; 544 545 discenb = 546 adw_lram_read_16(adw, ADW_MC_DISC_ENABLE); 547 548 if ((cts->flags & CCB_TRANS_DISC_ENB) != 0) 549 discenb |= target_mask; 550 else 551 discenb &= ~target_mask; 552 553 adw_lram_write_16(adw, ADW_MC_DISC_ENABLE, 554 discenb); 555 } 556 557 if ((cts->valid & CCB_TRANS_TQ_VALID) != 0) { 558 559 if ((cts->flags & CCB_TRANS_TAG_ENB) != 0) 560 adw->tagenb |= target_mask; 561 else 562 adw->tagenb &= ~target_mask; 563 } 564 565 if ((cts->valid & CCB_TRANS_BUS_WIDTH_VALID) != 0) { 566 u_int wdtrenb_orig; 567 u_int wdtrenb; 568 u_int wdtrdone; 569 570 wdtrenb_orig = 571 adw_lram_read_16(adw, ADW_MC_WDTR_ABLE); 572 wdtrenb = wdtrenb_orig; 573 wdtrdone = adw_lram_read_16(adw, 574 ADW_MC_WDTR_DONE); 575 switch (cts->bus_width) { 576 case MSG_EXT_WDTR_BUS_32_BIT: 577 case MSG_EXT_WDTR_BUS_16_BIT: 578 wdtrenb |= target_mask; 579 break; 580 case MSG_EXT_WDTR_BUS_8_BIT: 581 default: 582 wdtrenb &= ~target_mask; 583 break; 584 } 585 if (wdtrenb != wdtrenb_orig) { 586 adw_lram_write_16(adw, 587 ADW_MC_WDTR_ABLE, 588 wdtrenb); 589 wdtrdone &= ~target_mask; 590 adw_lram_write_16(adw, 591 ADW_MC_WDTR_DONE, 592 wdtrdone); 593 /* Wide negotiation forces async */ 594 sdtrdone &= ~target_mask; 595 adw_lram_write_16(adw, 596 ADW_MC_SDTR_DONE, 597 sdtrdone); 598 } 599 } 600 601 if (((cts->valid & CCB_TRANS_SYNC_RATE_VALID) != 0) 602 || ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) != 0)) { 603 u_int sdtr_orig; 604 u_int sdtr; 605 u_int sdtrable_orig; 606 u_int sdtrable; 607 608 sdtr = adw_get_chip_sdtr(adw, 609 ccb->ccb_h.target_id); 610 sdtr_orig = sdtr; 611 sdtrable = adw_lram_read_16(adw, 612 ADW_MC_SDTR_ABLE); 613 sdtrable_orig = sdtrable; 614 615 if ((cts->valid 616 & CCB_TRANS_SYNC_RATE_VALID) != 0) { 617 618 sdtr = 619 adw_find_sdtr(adw, 620 cts->sync_period); 621 } 622 623 if ((cts->valid 624 & CCB_TRANS_SYNC_OFFSET_VALID) != 0) { 625 if (cts->sync_offset == 0) 626 sdtr = ADW_MC_SDTR_ASYNC; 627 } 628 629 if (sdtr == ADW_MC_SDTR_ASYNC) 630 sdtrable &= ~target_mask; 631 else 632 sdtrable |= target_mask; 633 if (sdtr != sdtr_orig 634 || sdtrable != sdtrable_orig) { 635 adw_set_chip_sdtr(adw, 636 ccb->ccb_h.target_id, 637 sdtr); 638 sdtrdone &= ~target_mask; 639 adw_lram_write_16(adw, ADW_MC_SDTR_ABLE, 640 sdtrable); 641 adw_lram_write_16(adw, ADW_MC_SDTR_DONE, 642 sdtrdone); 643 644 } 645 } 646 } 647 splx(s); 648 ccb->ccb_h.status = CAM_REQ_CMP; 649 xpt_done(ccb); 650 break; 651 } 652 case XPT_GET_TRAN_SETTINGS: 653 /* Get default/user set transfer settings for the target */ 654 { 655 struct ccb_trans_settings *cts; 656 u_int target_mask; 657 658 cts = &ccb->cts; 659 target_mask = 0x01 << ccb->ccb_h.target_id; 660 if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) { 661 u_int mc_sdtr; 662 663 cts->flags = 0; 664 if ((adw->user_discenb & target_mask) != 0) 665 cts->flags |= CCB_TRANS_DISC_ENB; 666 667 if ((adw->user_tagenb & target_mask) != 0) 668 cts->flags |= CCB_TRANS_TAG_ENB; 669 670 if ((adw->user_wdtr & target_mask) != 0) 671 cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT; 672 else 673 cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT; 674 675 mc_sdtr = adw_get_user_sdtr(adw, ccb->ccb_h.target_id); 676 cts->sync_period = adw_find_period(adw, mc_sdtr); 677 if (cts->sync_period != 0) 678 cts->sync_offset = 15; /* XXX ??? */ 679 else 680 cts->sync_offset = 0; 681 682 cts->valid = CCB_TRANS_SYNC_RATE_VALID 683 | CCB_TRANS_SYNC_OFFSET_VALID 684 | CCB_TRANS_BUS_WIDTH_VALID 685 | CCB_TRANS_DISC_VALID 686 | CCB_TRANS_TQ_VALID; 687 ccb->ccb_h.status = CAM_REQ_CMP; 688 } else { 689 u_int targ_tinfo; 690 691 cts->flags = 0; 692 if ((adw_lram_read_16(adw, ADW_MC_DISC_ENABLE) 693 & target_mask) != 0) 694 cts->flags |= CCB_TRANS_DISC_ENB; 695 696 if ((adw->tagenb & target_mask) != 0) 697 cts->flags |= CCB_TRANS_TAG_ENB; 698 699 targ_tinfo = 700 adw_lram_read_16(adw, 701 ADW_MC_DEVICE_HSHK_CFG_TABLE 702 + (2 * ccb->ccb_h.target_id)); 703 704 if ((targ_tinfo & ADW_HSHK_CFG_WIDE_XFR) != 0) 705 cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT; 706 else 707 cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT; 708 709 cts->sync_period = 710 adw_hshk_cfg_period_factor(targ_tinfo); 711 712 cts->sync_offset = targ_tinfo & ADW_HSHK_CFG_OFFSET; 713 if (cts->sync_period == 0) 714 cts->sync_offset = 0; 715 716 if (cts->sync_offset == 0) 717 cts->sync_period = 0; 718 } 719 cts->valid = CCB_TRANS_SYNC_RATE_VALID 720 | CCB_TRANS_SYNC_OFFSET_VALID 721 | CCB_TRANS_BUS_WIDTH_VALID 722 | CCB_TRANS_DISC_VALID 723 | CCB_TRANS_TQ_VALID; 724 ccb->ccb_h.status = CAM_REQ_CMP; 725 xpt_done(ccb); 726 break; 727 } 728 case XPT_CALC_GEOMETRY: 729 { 730 /* 731 * XXX Use Adaptec translation until I find out how to 732 * get this information from the card. 733 */ 734 cam_calc_geometry(&ccb->ccg, /*extended*/1); 735 xpt_done(ccb); 736 break; 737 } 738 case XPT_RESET_BUS: /* Reset the specified SCSI bus */ 739 { 740 int failure; 741 742 failure = adw_reset_bus(adw); 743 if (failure != 0) { 744 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 745 } else { 746 if (bootverbose) { 747 xpt_print_path(adw->path); 748 printf("Bus Reset Delivered\n"); 749 } 750 ccb->ccb_h.status = CAM_REQ_CMP; 751 } 752 xpt_done(ccb); 753 break; 754 } 755 case XPT_TERM_IO: /* Terminate the I/O process */ 756 /* XXX Implement */ 757 ccb->ccb_h.status = CAM_REQ_INVALID; 758 xpt_done(ccb); 759 break; 760 case XPT_PATH_INQ: /* Path routing inquiry */ 761 { 762 struct ccb_pathinq *cpi = &ccb->cpi; 763 764 cpi->version_num = 1; 765 cpi->hba_inquiry = PI_WIDE_16|PI_SDTR_ABLE|PI_TAG_ABLE; 766 cpi->target_sprt = 0; 767 cpi->hba_misc = 0; 768 cpi->hba_eng_cnt = 0; 769 cpi->max_target = ADW_MAX_TID; 770 cpi->max_lun = ADW_MAX_LUN; 771 cpi->initiator_id = adw->initiator_id; 772 cpi->bus_id = cam_sim_bus(sim); 773 cpi->base_transfer_speed = 3300; 774 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 775 strncpy(cpi->hba_vid, "AdvanSys", HBA_IDLEN); 776 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 777 cpi->unit_number = cam_sim_unit(sim); 778 cpi->ccb_h.status = CAM_REQ_CMP; 779 xpt_done(ccb); 780 break; 781 } 782 default: 783 ccb->ccb_h.status = CAM_REQ_INVALID; 784 xpt_done(ccb); 785 break; 786 } 787} 788 789static void 790adw_poll(struct cam_sim *sim) 791{ 792 adw_intr(cam_sim_softc(sim)); 793} 794 795static void 796adw_async(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg) 797{ 798} 799 800struct adw_softc * 801adw_alloc(device_t dev, struct resource *regs, int regs_type, int regs_id) 802{ 803 struct adw_softc *adw; 804 int i; 805 806 /* 807 * Allocate a storage area for us 808 */ 809 adw = malloc(sizeof(struct adw_softc), M_DEVBUF, M_NOWAIT | M_ZERO); 810 if (adw == NULL) { 811 printf("adw%d: cannot malloc!\n", device_get_unit(dev)); 812 return NULL; 813 } 814 LIST_INIT(&adw->pending_ccbs); 815 SLIST_INIT(&adw->sg_maps); 816 adw->device = dev; 817 adw->unit = device_get_unit(dev); 818 adw->regs_res_type = regs_type; 819 adw->regs_res_id = regs_id; 820 adw->regs = regs; 821 adw->tag = rman_get_bustag(regs); 822 adw->bsh = rman_get_bushandle(regs); 823 i = adw->unit / 10; 824 adw->name = malloc(sizeof("adw") + i + 1, M_DEVBUF, M_NOWAIT); 825 if (adw->name == NULL) { 826 printf("adw%d: cannot malloc name!\n", adw->unit); 827 free(adw, M_DEVBUF); 828 return NULL; 829 } 830 sprintf(adw->name, "adw%d", adw->unit); 831 return(adw); 832} 833 834void 835adw_free(struct adw_softc *adw) 836{ 837 switch (adw->init_level) { 838 case 9: 839 { 840 struct sg_map_node *sg_map; 841 842 while ((sg_map = SLIST_FIRST(&adw->sg_maps)) != NULL) { 843 SLIST_REMOVE_HEAD(&adw->sg_maps, links); 844 bus_dmamap_unload(adw->sg_dmat, 845 sg_map->sg_dmamap); 846 bus_dmamem_free(adw->sg_dmat, sg_map->sg_vaddr, 847 sg_map->sg_dmamap); 848 free(sg_map, M_DEVBUF); 849 } 850 bus_dma_tag_destroy(adw->sg_dmat); 851 } 852 case 8: 853 bus_dmamap_unload(adw->acb_dmat, adw->acb_dmamap); 854 case 7: 855 bus_dmamem_free(adw->acb_dmat, adw->acbs, 856 adw->acb_dmamap); 857 bus_dmamap_destroy(adw->acb_dmat, adw->acb_dmamap); 858 case 6: 859 bus_dma_tag_destroy(adw->acb_dmat); 860 case 5: 861 bus_dmamap_unload(adw->carrier_dmat, adw->carrier_dmamap); 862 case 4: 863 bus_dmamem_free(adw->carrier_dmat, adw->carriers, 864 adw->carrier_dmamap); 865 bus_dmamap_destroy(adw->carrier_dmat, adw->carrier_dmamap); 866 case 3: 867 bus_dma_tag_destroy(adw->carrier_dmat); 868 case 2: 869 bus_dma_tag_destroy(adw->buffer_dmat); 870 case 1: 871 bus_dma_tag_destroy(adw->parent_dmat); 872 case 0: 873 break; 874 } 875 876 if (adw->regs != NULL) 877 bus_release_resource(adw->device, 878 adw->regs_res_type, 879 adw->regs_res_id, 880 adw->regs); 881 882 if (adw->irq != NULL) 883 bus_release_resource(adw->device, 884 adw->irq_res_type, 885 0, adw->irq); 886 887 if (adw->sim != NULL) { 888 if (adw->path != NULL) { 889 xpt_async(AC_LOST_DEVICE, adw->path, NULL); 890 xpt_free_path(adw->path); 891 } 892 xpt_bus_deregister(cam_sim_path(adw->sim)); 893 cam_sim_free(adw->sim, /*free_devq*/TRUE); 894 } 895 free(adw->name, M_DEVBUF); 896 free(adw, M_DEVBUF); 897} 898 899int 900adw_init(struct adw_softc *adw) 901{ 902 struct adw_eeprom eep_config; 903 u_int tid; 904 u_int i; 905 u_int16_t checksum; 906 u_int16_t scsicfg1; 907 908 checksum = adw_eeprom_read(adw, &eep_config); 909 bcopy(eep_config.serial_number, adw->serial_number, 910 sizeof(adw->serial_number)); 911 if (checksum != eep_config.checksum) { 912 u_int16_t serial_number[3]; 913 914 adw->flags |= ADW_EEPROM_FAILED; 915 printf("%s: EEPROM checksum failed. Restoring Defaults\n", 916 adw_name(adw)); 917 918 /* 919 * Restore the default EEPROM settings. 920 * Assume the 6 byte board serial number that was read 921 * from EEPROM is correct even if the EEPROM checksum 922 * failed. 923 */ 924 bcopy(adw->default_eeprom, &eep_config, sizeof(eep_config)); 925 bcopy(adw->serial_number, eep_config.serial_number, 926 sizeof(serial_number)); 927 adw_eeprom_write(adw, &eep_config); 928 } 929 930 /* Pull eeprom information into our softc. */ 931 adw->bios_ctrl = eep_config.bios_ctrl; 932 adw->user_wdtr = eep_config.wdtr_able; 933 for (tid = 0; tid < ADW_MAX_TID; tid++) { 934 u_int mc_sdtr; 935 u_int16_t tid_mask; 936 937 tid_mask = 0x1 << tid; 938 if ((adw->features & ADW_ULTRA) != 0) { 939 /* 940 * Ultra chips store sdtr and ultraenb 941 * bits in their seeprom, so we must 942 * construct valid mc_sdtr entries for 943 * indirectly. 944 */ 945 if (eep_config.sync1.sync_enable & tid_mask) { 946 if (eep_config.sync2.ultra_enable & tid_mask) 947 mc_sdtr = ADW_MC_SDTR_20; 948 else 949 mc_sdtr = ADW_MC_SDTR_10; 950 } else 951 mc_sdtr = ADW_MC_SDTR_ASYNC; 952 } else { 953 switch (ADW_TARGET_GROUP(tid)) { 954 case 3: 955 mc_sdtr = eep_config.sync4.sdtr4; 956 break; 957 case 2: 958 mc_sdtr = eep_config.sync3.sdtr3; 959 break; 960 case 1: 961 mc_sdtr = eep_config.sync2.sdtr2; 962 break; 963 default: /* Shut up compiler */ 964 case 0: 965 mc_sdtr = eep_config.sync1.sdtr1; 966 break; 967 } 968 mc_sdtr >>= ADW_TARGET_GROUP_SHIFT(tid); 969 mc_sdtr &= 0xFF; 970 } 971 adw_set_user_sdtr(adw, tid, mc_sdtr); 972 } 973 adw->user_tagenb = eep_config.tagqng_able; 974 adw->user_discenb = eep_config.disc_enable; 975 adw->max_acbs = eep_config.max_host_qng; 976 adw->initiator_id = (eep_config.adapter_scsi_id & ADW_MAX_TID); 977 978 /* 979 * Sanity check the number of host openings. 980 */ 981 if (adw->max_acbs > ADW_DEF_MAX_HOST_QNG) 982 adw->max_acbs = ADW_DEF_MAX_HOST_QNG; 983 else if (adw->max_acbs < ADW_DEF_MIN_HOST_QNG) { 984 /* If the value is zero, assume it is uninitialized. */ 985 if (adw->max_acbs == 0) 986 adw->max_acbs = ADW_DEF_MAX_HOST_QNG; 987 else 988 adw->max_acbs = ADW_DEF_MIN_HOST_QNG; 989 } 990 991 scsicfg1 = 0; 992 if ((adw->features & ADW_ULTRA2) != 0) { 993 switch (eep_config.termination_lvd) { 994 default: 995 printf("%s: Invalid EEPROM LVD Termination Settings.\n", 996 adw_name(adw)); 997 printf("%s: Reverting to Automatic LVD Termination\n", 998 adw_name(adw)); 999 /* FALLTHROUGH */ 1000 case ADW_EEPROM_TERM_AUTO: 1001 break; 1002 case ADW_EEPROM_TERM_BOTH_ON: 1003 scsicfg1 |= ADW2_SCSI_CFG1_TERM_LVD_LO; 1004 /* FALLTHROUGH */ 1005 case ADW_EEPROM_TERM_HIGH_ON: 1006 scsicfg1 |= ADW2_SCSI_CFG1_TERM_LVD_HI; 1007 /* FALLTHROUGH */ 1008 case ADW_EEPROM_TERM_OFF: 1009 scsicfg1 |= ADW2_SCSI_CFG1_DIS_TERM_DRV; 1010 break; 1011 } 1012 } 1013 1014 switch (eep_config.termination_se) { 1015 default: 1016 printf("%s: Invalid SE EEPROM Termination Settings.\n", 1017 adw_name(adw)); 1018 printf("%s: Reverting to Automatic SE Termination\n", 1019 adw_name(adw)); 1020 /* FALLTHROUGH */ 1021 case ADW_EEPROM_TERM_AUTO: 1022 break; 1023 case ADW_EEPROM_TERM_BOTH_ON: 1024 scsicfg1 |= ADW_SCSI_CFG1_TERM_CTL_L; 1025 /* FALLTHROUGH */ 1026 case ADW_EEPROM_TERM_HIGH_ON: 1027 scsicfg1 |= ADW_SCSI_CFG1_TERM_CTL_H; 1028 /* FALLTHROUGH */ 1029 case ADW_EEPROM_TERM_OFF: 1030 scsicfg1 |= ADW_SCSI_CFG1_TERM_CTL_MANUAL; 1031 break; 1032 } 1033 printf("%s: SCSI ID %d, ", adw_name(adw), adw->initiator_id); 1034 1035 /* DMA tag for mapping buffers into device visible space. */ 1036 if (bus_dma_tag_create( 1037 /* parent */ adw->parent_dmat, 1038 /* alignment */ 1, 1039 /* boundary */ 0, 1040 /* lowaddr */ BUS_SPACE_MAXADDR_32BIT, 1041 /* highaddr */ BUS_SPACE_MAXADDR, 1042 /* filter */ NULL, 1043 /* filterarg */ NULL, 1044 /* maxsize */ MAXBSIZE, 1045 /* nsegments */ ADW_SGSIZE, 1046 /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT, 1047 /* flags */ BUS_DMA_ALLOCNOW, 1048 /* lockfunc */ busdma_lock_mutex, 1049 /* lockarg */ &Giant, 1050 &adw->buffer_dmat) != 0) { 1051 return (ENOMEM); 1052 } 1053 1054 adw->init_level++; 1055 1056 /* DMA tag for our ccb carrier structures */ 1057 if (bus_dma_tag_create( 1058 /* parent */ adw->parent_dmat, 1059 /* alignment */ 0x10, 1060 /* boundary */ 0, 1061 /* lowaddr */ BUS_SPACE_MAXADDR_32BIT, 1062 /* highaddr */ BUS_SPACE_MAXADDR, 1063 /* filter */ NULL, 1064 /* filterarg */ NULL, 1065 /* maxsize */ (adw->max_acbs + 1066 ADW_NUM_CARRIER_QUEUES + 1) * 1067 sizeof(struct adw_carrier), 1068 /* nsegments */ 1, 1069 /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT, 1070 /* flags */ 0, 1071 /* lockfunc */ busdma_lock_mutex, 1072 /* lockarg */ &Giant, 1073 &adw->carrier_dmat) != 0) { 1074 return (ENOMEM); 1075 } 1076 1077 adw->init_level++; 1078 1079 /* Allocation for our ccb carrier structures */ 1080 if (bus_dmamem_alloc(adw->carrier_dmat, (void **)&adw->carriers, 1081 BUS_DMA_NOWAIT, &adw->carrier_dmamap) != 0) { 1082 return (ENOMEM); 1083 } 1084 1085 adw->init_level++; 1086 1087 /* And permanently map them */ 1088 bus_dmamap_load(adw->carrier_dmat, adw->carrier_dmamap, 1089 adw->carriers, 1090 (adw->max_acbs + ADW_NUM_CARRIER_QUEUES + 1) 1091 * sizeof(struct adw_carrier), 1092 adwmapmem, &adw->carrier_busbase, /*flags*/0); 1093 1094 /* Clear them out. */ 1095 bzero(adw->carriers, (adw->max_acbs + ADW_NUM_CARRIER_QUEUES + 1) 1096 * sizeof(struct adw_carrier)); 1097 1098 /* Setup our free carrier list */ 1099 adw->free_carriers = adw->carriers; 1100 for (i = 0; i < adw->max_acbs + ADW_NUM_CARRIER_QUEUES; i++) { 1101 adw->carriers[i].carr_offset = 1102 carriervtobo(adw, &adw->carriers[i]); 1103 adw->carriers[i].carr_ba = 1104 carriervtob(adw, &adw->carriers[i]); 1105 adw->carriers[i].areq_ba = 0; 1106 adw->carriers[i].next_ba = 1107 carriervtobo(adw, &adw->carriers[i+1]); 1108 } 1109 /* Terminal carrier. Never leaves the freelist */ 1110 adw->carriers[i].carr_offset = 1111 carriervtobo(adw, &adw->carriers[i]); 1112 adw->carriers[i].carr_ba = 1113 carriervtob(adw, &adw->carriers[i]); 1114 adw->carriers[i].areq_ba = 0; 1115 adw->carriers[i].next_ba = ~0; 1116 1117 adw->init_level++; 1118 1119 /* DMA tag for our acb structures */ 1120 if (bus_dma_tag_create( 1121 /* parent */ adw->parent_dmat, 1122 /* alignment */ 1, 1123 /* boundary */ 0, 1124 /* lowaddr */ BUS_SPACE_MAXADDR, 1125 /* highaddr */ BUS_SPACE_MAXADDR, 1126 /* filter */ NULL, 1127 /* filterarg */ NULL, 1128 /* maxsize */ adw->max_acbs * sizeof(struct acb), 1129 /* nsegments */ 1, 1130 /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT, 1131 /* flags */ 0, 1132 /* lockfunc */ busdma_lock_mutex, 1133 /* lockarg */ &Giant, 1134 &adw->acb_dmat) != 0) { 1135 return (ENOMEM); 1136 } 1137 1138 adw->init_level++; 1139 1140 /* Allocation for our ccbs */ 1141 if (bus_dmamem_alloc(adw->acb_dmat, (void **)&adw->acbs, 1142 BUS_DMA_NOWAIT, &adw->acb_dmamap) != 0) 1143 return (ENOMEM); 1144 1145 adw->init_level++; 1146 1147 /* And permanently map them */ 1148 bus_dmamap_load(adw->acb_dmat, adw->acb_dmamap, 1149 adw->acbs, 1150 adw->max_acbs * sizeof(struct acb), 1151 adwmapmem, &adw->acb_busbase, /*flags*/0); 1152 1153 /* Clear them out. */ 1154 bzero(adw->acbs, adw->max_acbs * sizeof(struct acb)); 1155 1156 /* DMA tag for our S/G structures. We allocate in page sized chunks */ 1157 if (bus_dma_tag_create( 1158 /* parent */ adw->parent_dmat, 1159 /* alignment */ 1, 1160 /* boundary */ 0, 1161 /* lowaddr */ BUS_SPACE_MAXADDR, 1162 /* highaddr */ BUS_SPACE_MAXADDR, 1163 /* filter */ NULL, 1164 /* filterarg */ NULL, 1165 /* maxsize */ PAGE_SIZE, 1166 /* nsegments */ 1, 1167 /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT, 1168 /* flags */ 0, 1169 /* lockfunc */ busdma_lock_mutex, 1170 /* lockarg */ &Giant, 1171 &adw->sg_dmat) != 0) { 1172 return (ENOMEM); 1173 } 1174 1175 adw->init_level++; 1176 1177 /* Allocate our first batch of ccbs */ 1178 if (adwallocacbs(adw) == 0) 1179 return (ENOMEM); 1180 1181 if (adw_init_chip(adw, scsicfg1) != 0) 1182 return (ENXIO); 1183 1184 printf("Queue Depth %d\n", adw->max_acbs); 1185 1186 return (0); 1187} 1188 1189/* 1190 * Attach all the sub-devices we can find 1191 */ 1192int 1193adw_attach(struct adw_softc *adw) 1194{ 1195 struct ccb_setasync csa; 1196 struct cam_devq *devq; 1197 int s; 1198 int error; 1199 1200 error = 0; 1201 s = splcam(); 1202 /* Hook up our interrupt handler */ 1203 if ((error = bus_setup_intr(adw->device, adw->irq, 1204 INTR_TYPE_CAM | INTR_ENTROPY, adw_intr, 1205 adw, &adw->ih)) != 0) { 1206 device_printf(adw->device, "bus_setup_intr() failed: %d\n", 1207 error); 1208 goto fail; 1209 } 1210 1211 /* Start the Risc processor now that we are fully configured. */ 1212 adw_outw(adw, ADW_RISC_CSR, ADW_RISC_CSR_RUN); 1213 1214 /* 1215 * Create the device queue for our SIM. 1216 */ 1217 devq = cam_simq_alloc(adw->max_acbs); 1218 if (devq == NULL) 1219 return (ENOMEM); 1220 1221 /* 1222 * Construct our SIM entry. 1223 */ 1224 adw->sim = cam_sim_alloc(adw_action, adw_poll, "adw", adw, adw->unit, 1225 1, adw->max_acbs, devq); 1226 if (adw->sim == NULL) { 1227 error = ENOMEM; 1228 goto fail; 1229 } 1230 1231 /* 1232 * Register the bus. 1233 */ 1234 if (xpt_bus_register(adw->sim, 0) != CAM_SUCCESS) { 1235 cam_sim_free(adw->sim, /*free devq*/TRUE); 1236 error = ENOMEM; 1237 goto fail; 1238 } 1239 1240 if (xpt_create_path(&adw->path, /*periph*/NULL, cam_sim_path(adw->sim), 1241 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) 1242 == CAM_REQ_CMP) { 1243 xpt_setup_ccb(&csa.ccb_h, adw->path, /*priority*/5); 1244 csa.ccb_h.func_code = XPT_SASYNC_CB; 1245 csa.event_enable = AC_LOST_DEVICE; 1246 csa.callback = adw_async; 1247 csa.callback_arg = adw; 1248 xpt_action((union ccb *)&csa); 1249 } 1250 1251fail: 1252 splx(s); 1253 return (error); 1254} 1255 1256void 1257adw_intr(void *arg) 1258{ 1259 struct adw_softc *adw; 1260 u_int int_stat; 1261 1262 adw = (struct adw_softc *)arg; 1263 if ((adw_inw(adw, ADW_CTRL_REG) & ADW_CTRL_REG_HOST_INTR) == 0) 1264 return; 1265 1266 /* Reading the register clears the interrupt. */ 1267 int_stat = adw_inb(adw, ADW_INTR_STATUS_REG); 1268 1269 if ((int_stat & ADW_INTR_STATUS_INTRB) != 0) { 1270 u_int intrb_code; 1271 1272 /* Async Microcode Event */ 1273 intrb_code = adw_lram_read_8(adw, ADW_MC_INTRB_CODE); 1274 switch (intrb_code) { 1275 case ADW_ASYNC_CARRIER_READY_FAILURE: 1276 /* 1277 * The RISC missed our update of 1278 * the commandq. 1279 */ 1280 if (LIST_FIRST(&adw->pending_ccbs) != NULL) 1281 adw_tickle_risc(adw, ADW_TICKLE_A); 1282 break; 1283 case ADW_ASYNC_SCSI_BUS_RESET_DET: 1284 /* 1285 * The firmware detected a SCSI Bus reset. 1286 */ 1287 printf("Someone Reset the Bus\n"); 1288 adw_handle_bus_reset(adw, /*initiated*/FALSE); 1289 break; 1290 case ADW_ASYNC_RDMA_FAILURE: 1291 /* 1292 * Handle RDMA failure by resetting the 1293 * SCSI Bus and chip. 1294 */ 1295#if XXX 1296 AdvResetChipAndSB(adv_dvc_varp); 1297#endif 1298 break; 1299 1300 case ADW_ASYNC_HOST_SCSI_BUS_RESET: 1301 /* 1302 * Host generated SCSI bus reset occurred. 1303 */ 1304 adw_handle_bus_reset(adw, /*initiated*/TRUE); 1305 break; 1306 default: 1307 printf("adw_intr: unknown async code 0x%x\n", 1308 intrb_code); 1309 break; 1310 } 1311 } 1312 1313 /* 1314 * Run down the RequestQ. 1315 */ 1316 while ((adw->responseq->next_ba & ADW_RQ_DONE) != 0) { 1317 struct adw_carrier *free_carrier; 1318 struct acb *acb; 1319 union ccb *ccb; 1320 1321#if 0 1322 printf("0x%x, 0x%x, 0x%x, 0x%x\n", 1323 adw->responseq->carr_offset, 1324 adw->responseq->carr_ba, 1325 adw->responseq->areq_ba, 1326 adw->responseq->next_ba); 1327#endif 1328 /* 1329 * The firmware copies the adw_scsi_req_q.acb_baddr 1330 * field into the areq_ba field of the carrier. 1331 */ 1332 acb = acbbotov(adw, adw->responseq->areq_ba); 1333 1334 /* 1335 * The least significant four bits of the next_ba 1336 * field are used as flags. Mask them out and then 1337 * advance through the list. 1338 */ 1339 free_carrier = adw->responseq; 1340 adw->responseq = 1341 carrierbotov(adw, free_carrier->next_ba & ADW_NEXT_BA_MASK); 1342 free_carrier->next_ba = adw->free_carriers->carr_offset; 1343 adw->free_carriers = free_carrier; 1344 1345 /* Process CCB */ 1346 ccb = acb->ccb; 1347 untimeout(adwtimeout, acb, ccb->ccb_h.timeout_ch); 1348 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 1349 bus_dmasync_op_t op; 1350 1351 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) 1352 op = BUS_DMASYNC_POSTREAD; 1353 else 1354 op = BUS_DMASYNC_POSTWRITE; 1355 bus_dmamap_sync(adw->buffer_dmat, acb->dmamap, op); 1356 bus_dmamap_unload(adw->buffer_dmat, acb->dmamap); 1357 ccb->csio.resid = acb->queue.data_cnt; 1358 } else 1359 ccb->csio.resid = 0; 1360 1361 /* Common Cases inline... */ 1362 if (acb->queue.host_status == QHSTA_NO_ERROR 1363 && (acb->queue.done_status == QD_NO_ERROR 1364 || acb->queue.done_status == QD_WITH_ERROR)) { 1365 ccb->csio.scsi_status = acb->queue.scsi_status; 1366 ccb->ccb_h.status = 0; 1367 switch (ccb->csio.scsi_status) { 1368 case SCSI_STATUS_OK: 1369 ccb->ccb_h.status |= CAM_REQ_CMP; 1370 break; 1371 case SCSI_STATUS_CHECK_COND: 1372 case SCSI_STATUS_CMD_TERMINATED: 1373 bcopy(&acb->sense_data, &ccb->csio.sense_data, 1374 ccb->csio.sense_len); 1375 ccb->ccb_h.status |= CAM_AUTOSNS_VALID; 1376 ccb->csio.sense_resid = acb->queue.sense_len; 1377 /* FALLTHROUGH */ 1378 default: 1379 ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR 1380 | CAM_DEV_QFRZN; 1381 xpt_freeze_devq(ccb->ccb_h.path, /*count*/1); 1382 break; 1383 } 1384 adwfreeacb(adw, acb); 1385 xpt_done(ccb); 1386 } else { 1387 adwprocesserror(adw, acb); 1388 } 1389 } 1390} 1391 1392static void 1393adwprocesserror(struct adw_softc *adw, struct acb *acb) 1394{ 1395 union ccb *ccb; 1396 1397 ccb = acb->ccb; 1398 if (acb->queue.done_status == QD_ABORTED_BY_HOST) { 1399 ccb->ccb_h.status = CAM_REQ_ABORTED; 1400 } else { 1401 1402 switch (acb->queue.host_status) { 1403 case QHSTA_M_SEL_TIMEOUT: 1404 ccb->ccb_h.status = CAM_SEL_TIMEOUT; 1405 break; 1406 case QHSTA_M_SXFR_OFF_UFLW: 1407 case QHSTA_M_SXFR_OFF_OFLW: 1408 case QHSTA_M_DATA_OVER_RUN: 1409 ccb->ccb_h.status = CAM_DATA_RUN_ERR; 1410 break; 1411 case QHSTA_M_SXFR_DESELECTED: 1412 case QHSTA_M_UNEXPECTED_BUS_FREE: 1413 ccb->ccb_h.status = CAM_UNEXP_BUSFREE; 1414 break; 1415 case QHSTA_M_SCSI_BUS_RESET: 1416 case QHSTA_M_SCSI_BUS_RESET_UNSOL: 1417 ccb->ccb_h.status = CAM_SCSI_BUS_RESET; 1418 break; 1419 case QHSTA_M_BUS_DEVICE_RESET: 1420 ccb->ccb_h.status = CAM_BDR_SENT; 1421 break; 1422 case QHSTA_M_QUEUE_ABORTED: 1423 /* BDR or Bus Reset */ 1424 printf("Saw Queue Aborted\n"); 1425 ccb->ccb_h.status = adw->last_reset; 1426 break; 1427 case QHSTA_M_SXFR_SDMA_ERR: 1428 case QHSTA_M_SXFR_SXFR_PERR: 1429 case QHSTA_M_RDMA_PERR: 1430 ccb->ccb_h.status = CAM_UNCOR_PARITY; 1431 break; 1432 case QHSTA_M_WTM_TIMEOUT: 1433 case QHSTA_M_SXFR_WD_TMO: 1434 { 1435 /* The SCSI bus hung in a phase */ 1436 xpt_print_path(adw->path); 1437 printf("Watch Dog timer expired. Reseting bus\n"); 1438 adw_reset_bus(adw); 1439 break; 1440 } 1441 case QHSTA_M_SXFR_XFR_PH_ERR: 1442 ccb->ccb_h.status = CAM_SEQUENCE_FAIL; 1443 break; 1444 case QHSTA_M_SXFR_UNKNOWN_ERROR: 1445 break; 1446 case QHSTA_M_BAD_CMPL_STATUS_IN: 1447 /* No command complete after a status message */ 1448 ccb->ccb_h.status = CAM_SEQUENCE_FAIL; 1449 break; 1450 case QHSTA_M_AUTO_REQ_SENSE_FAIL: 1451 ccb->ccb_h.status = CAM_AUTOSENSE_FAIL; 1452 break; 1453 case QHSTA_M_INVALID_DEVICE: 1454 ccb->ccb_h.status = CAM_PATH_INVALID; 1455 break; 1456 case QHSTA_M_NO_AUTO_REQ_SENSE: 1457 /* 1458 * User didn't request sense, but we got a 1459 * check condition. 1460 */ 1461 ccb->csio.scsi_status = acb->queue.scsi_status; 1462 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR; 1463 break; 1464 default: 1465 panic("%s: Unhandled Host status error %x", 1466 adw_name(adw), acb->queue.host_status); 1467 /* NOTREACHED */ 1468 } 1469 } 1470 if ((acb->state & ACB_RECOVERY_ACB) != 0) { 1471 if (ccb->ccb_h.status == CAM_SCSI_BUS_RESET 1472 || ccb->ccb_h.status == CAM_BDR_SENT) 1473 ccb->ccb_h.status = CAM_CMD_TIMEOUT; 1474 } 1475 if (ccb->ccb_h.status != CAM_REQ_CMP) { 1476 xpt_freeze_devq(ccb->ccb_h.path, /*count*/1); 1477 ccb->ccb_h.status |= CAM_DEV_QFRZN; 1478 } 1479 adwfreeacb(adw, acb); 1480 xpt_done(ccb); 1481} 1482 1483static void 1484adwtimeout(void *arg) 1485{ 1486 struct acb *acb; 1487 union ccb *ccb; 1488 struct adw_softc *adw; 1489 adw_idle_cmd_status_t status; 1490 int target_id; 1491 int s; 1492 1493 acb = (struct acb *)arg; 1494 ccb = acb->ccb; 1495 adw = (struct adw_softc *)ccb->ccb_h.ccb_adw_ptr; 1496 xpt_print_path(ccb->ccb_h.path); 1497 printf("ACB %p - timed out\n", (void *)acb); 1498 1499 s = splcam(); 1500 1501 if ((acb->state & ACB_ACTIVE) == 0) { 1502 xpt_print_path(ccb->ccb_h.path); 1503 printf("ACB %p - timed out CCB already completed\n", 1504 (void *)acb); 1505 splx(s); 1506 return; 1507 } 1508 1509 acb->state |= ACB_RECOVERY_ACB; 1510 target_id = ccb->ccb_h.target_id; 1511 1512 /* Attempt a BDR first */ 1513 status = adw_idle_cmd_send(adw, ADW_IDLE_CMD_DEVICE_RESET, 1514 ccb->ccb_h.target_id); 1515 splx(s); 1516 if (status == ADW_IDLE_CMD_SUCCESS) { 1517 printf("%s: BDR Delivered. No longer in timeout\n", 1518 adw_name(adw)); 1519 adw_handle_device_reset(adw, target_id); 1520 } else { 1521 adw_reset_bus(adw); 1522 xpt_print_path(adw->path); 1523 printf("Bus Reset Delivered. No longer in timeout\n"); 1524 } 1525} 1526 1527static void 1528adw_handle_device_reset(struct adw_softc *adw, u_int target) 1529{ 1530 struct cam_path *path; 1531 cam_status error; 1532 1533 error = xpt_create_path(&path, /*periph*/NULL, cam_sim_path(adw->sim), 1534 target, CAM_LUN_WILDCARD); 1535 1536 if (error == CAM_REQ_CMP) { 1537 xpt_async(AC_SENT_BDR, path, NULL); 1538 xpt_free_path(path); 1539 } 1540 adw->last_reset = CAM_BDR_SENT; 1541} 1542 1543static void 1544adw_handle_bus_reset(struct adw_softc *adw, int initiated) 1545{ 1546 if (initiated) { 1547 /* 1548 * The microcode currently sets the SCSI Bus Reset signal 1549 * while handling the AscSendIdleCmd() IDLE_CMD_SCSI_RESET 1550 * command above. But the SCSI Bus Reset Hold Time in the 1551 * microcode is not deterministic (it may in fact be for less 1552 * than the SCSI Spec. minimum of 25 us). Therefore on return 1553 * the Adv Library sets the SCSI Bus Reset signal for 1554 * ADW_SCSI_RESET_HOLD_TIME_US, which is defined to be greater 1555 * than 25 us. 1556 */ 1557 u_int scsi_ctrl; 1558 1559 scsi_ctrl = adw_inw(adw, ADW_SCSI_CTRL) & ~ADW_SCSI_CTRL_RSTOUT; 1560 adw_outw(adw, ADW_SCSI_CTRL, scsi_ctrl | ADW_SCSI_CTRL_RSTOUT); 1561 DELAY(ADW_SCSI_RESET_HOLD_TIME_US); 1562 adw_outw(adw, ADW_SCSI_CTRL, scsi_ctrl); 1563 1564 /* 1565 * We will perform the async notification when the 1566 * SCSI Reset interrupt occurs. 1567 */ 1568 } else 1569 xpt_async(AC_BUS_RESET, adw->path, NULL); 1570 adw->last_reset = CAM_SCSI_BUS_RESET; 1571} 1572