aha.c revision 112782
1/* 2 * Generic register and struct definitions for the Adaptech 154x/164x 3 * SCSI host adapters. Product specific probe and attach routines can 4 * be found in: 5 * aha 1540/1542B/1542C/1542CF/1542CP aha_isa.c 6 * 7 * Copyright (c) 1998 M. Warner Losh. 8 * All Rights Reserved. 9 * 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification, immediately at the beginning of the file. 17 * 2. The name of the author may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 24 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * Derived from bt.c written by: 33 * 34 * Copyright (c) 1998 Justin T. Gibbs. 35 * All rights reserved. 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 1. Redistributions of source code must retain the above copyright 41 * notice, this list of conditions, and the following disclaimer, 42 * without modification, immediately at the beginning of the file. 43 * 2. The name of the author may not be used to endorse or promote products 44 * derived from this software without specific prior written permission. 45 * 46 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 47 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 49 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 50 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 51 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 52 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 54 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 56 * SUCH DAMAGE. 57 * 58 * $FreeBSD: head/sys/dev/aha/aha.c 112782 2003-03-29 09:46:10Z mdodd $ 59 */ 60 61#include <sys/param.h> 62#include <sys/systm.h> 63#include <sys/malloc.h> 64#include <sys/kernel.h> 65 66#include <machine/bus_pio.h> 67#include <machine/bus.h> 68 69#include <cam/cam.h> 70#include <cam/cam_ccb.h> 71#include <cam/cam_sim.h> 72#include <cam/cam_xpt_sim.h> 73#include <cam/cam_debug.h> 74 75#include <cam/scsi/scsi_message.h> 76 77#include <dev/aha/ahareg.h> 78 79#define PRVERB(x) if (bootverbose) printf x 80 81/* Macro to determine that a rev is potentially a new valid one 82 * so that the driver doesn't keep breaking on new revs as it 83 * did for the CF and CP. 84 */ 85#define PROBABLY_NEW_BOARD(REV) (REV > 0x43 && REV < 0x56) 86 87/* MailBox Management functions */ 88static __inline void ahanextinbox(struct aha_softc *aha); 89static __inline void ahanextoutbox(struct aha_softc *aha); 90 91static __inline void 92ahanextinbox(struct aha_softc *aha) 93{ 94 if (aha->cur_inbox == aha->last_inbox) 95 aha->cur_inbox = aha->in_boxes; 96 else 97 aha->cur_inbox++; 98} 99 100static __inline void 101ahanextoutbox(struct aha_softc *aha) 102{ 103 if (aha->cur_outbox == aha->last_outbox) 104 aha->cur_outbox = aha->out_boxes; 105 else 106 aha->cur_outbox++; 107} 108 109#define ahautoa24(u,s3) \ 110 (s3)[0] = ((u) >> 16) & 0xff; \ 111 (s3)[1] = ((u) >> 8) & 0xff; \ 112 (s3)[2] = (u) & 0xff; 113 114#define aha_a24tou(s3) \ 115 (((s3)[0] << 16) | ((s3)[1] << 8) | (s3)[2]) 116 117/* CCB Mangement functions */ 118static __inline u_int32_t ahaccbvtop(struct aha_softc *aha, 119 struct aha_ccb *accb); 120static __inline struct aha_ccb* ahaccbptov(struct aha_softc *aha, 121 u_int32_t ccb_addr); 122 123static __inline u_int32_t 124ahaccbvtop(struct aha_softc *aha, struct aha_ccb *accb) 125{ 126 return (aha->aha_ccb_physbase 127 + (u_int32_t)((caddr_t)accb - (caddr_t)aha->aha_ccb_array)); 128} 129static __inline struct aha_ccb * 130ahaccbptov(struct aha_softc *aha, u_int32_t ccb_addr) 131{ 132 return (aha->aha_ccb_array + 133 + ((struct aha_ccb*)(uintptr_t)ccb_addr - 134 (struct aha_ccb*)(uintptr_t)aha->aha_ccb_physbase)); 135} 136 137static struct aha_ccb* ahagetccb(struct aha_softc *aha); 138static __inline void ahafreeccb(struct aha_softc *aha, struct aha_ccb *accb); 139static void ahaallocccbs(struct aha_softc *aha); 140static bus_dmamap_callback_t ahaexecuteccb; 141static void ahadone(struct aha_softc *aha, struct aha_ccb *accb, 142 aha_mbi_comp_code_t comp_code); 143 144/* Host adapter command functions */ 145static int ahareset(struct aha_softc* aha, int hard_reset); 146 147/* Initialization functions */ 148static int ahainitmboxes(struct aha_softc *aha); 149static bus_dmamap_callback_t ahamapmboxes; 150static bus_dmamap_callback_t ahamapccbs; 151static bus_dmamap_callback_t ahamapsgs; 152 153/* Transfer Negotiation Functions */ 154static void ahafetchtransinfo(struct aha_softc *aha, 155 struct ccb_trans_settings *cts); 156 157/* CAM SIM entry points */ 158#define ccb_accb_ptr spriv_ptr0 159#define ccb_aha_ptr spriv_ptr1 160static void ahaaction(struct cam_sim *sim, union ccb *ccb); 161static void ahapoll(struct cam_sim *sim); 162 163/* Our timeout handler */ 164static timeout_t ahatimeout; 165 166u_long aha_unit = 0; 167 168/* 169 * Do our own re-probe protection until a configuration 170 * manager can do it for us. This ensures that we don't 171 * reprobe a card already found by the EISA or PCI probes. 172 */ 173static struct aha_isa_port aha_isa_ports[] = 174{ 175 { 0x130, 4 }, 176 { 0x134, 5 }, 177 { 0x230, 2 }, 178 { 0x234, 3 }, 179 { 0x330, 0 }, 180 { 0x334, 1 } 181}; 182 183/* 184 * I/O ports listed in the order enumerated by the 185 * card for certain op codes. 186 */ 187static u_int16_t aha_board_ports[] = 188{ 189 0x330, 190 0x334, 191 0x230, 192 0x234, 193 0x130, 194 0x134 195}; 196 197/* Exported functions */ 198struct aha_softc * 199aha_alloc(int unit, bus_space_tag_t tag, bus_space_handle_t bsh) 200{ 201 struct aha_softc *aha; 202 203 aha = malloc(sizeof(struct aha_softc), M_DEVBUF, M_NOWAIT | M_ZERO); 204 if (!aha) { 205 printf("aha%d: cannot malloc!\n", unit); 206 return NULL; 207 } 208 SLIST_INIT(&aha->free_aha_ccbs); 209 LIST_INIT(&aha->pending_ccbs); 210 SLIST_INIT(&aha->sg_maps); 211 aha->unit = unit; 212 aha->tag = tag; 213 aha->bsh = bsh; 214 aha->ccb_sg_opcode = INITIATOR_SG_CCB_WRESID; 215 aha->ccb_ccb_opcode = INITIATOR_CCB_WRESID; 216 return (aha); 217} 218 219void 220aha_free(struct aha_softc *aha) 221{ 222 switch (aha->init_level) { 223 default: 224 case 8: 225 { 226 struct sg_map_node *sg_map; 227 228 while ((sg_map = SLIST_FIRST(&aha->sg_maps))!= NULL) { 229 SLIST_REMOVE_HEAD(&aha->sg_maps, links); 230 bus_dmamap_unload(aha->sg_dmat, 231 sg_map->sg_dmamap); 232 bus_dmamem_free(aha->sg_dmat, sg_map->sg_vaddr, 233 sg_map->sg_dmamap); 234 free(sg_map, M_DEVBUF); 235 } 236 bus_dma_tag_destroy(aha->sg_dmat); 237 } 238 case 7: 239 bus_dmamap_unload(aha->ccb_dmat, aha->ccb_dmamap); 240 case 6: 241 bus_dmamap_destroy(aha->ccb_dmat, aha->ccb_dmamap); 242 bus_dmamem_free(aha->ccb_dmat, aha->aha_ccb_array, 243 aha->ccb_dmamap); 244 case 5: 245 bus_dma_tag_destroy(aha->ccb_dmat); 246 case 4: 247 bus_dmamap_unload(aha->mailbox_dmat, aha->mailbox_dmamap); 248 case 3: 249 bus_dmamem_free(aha->mailbox_dmat, aha->in_boxes, 250 aha->mailbox_dmamap); 251 bus_dmamap_destroy(aha->mailbox_dmat, aha->mailbox_dmamap); 252 case 2: 253 bus_dma_tag_destroy(aha->buffer_dmat); 254 case 1: 255 bus_dma_tag_destroy(aha->mailbox_dmat); 256 case 0: 257 break; 258 } 259 free(aha, M_DEVBUF); 260} 261 262/* 263 * Probe the adapter and verify that the card is an Adaptec. 264 */ 265int 266aha_probe(struct aha_softc* aha) 267{ 268 u_int status; 269 u_int intstat; 270 int error; 271 board_id_data_t board_id; 272 273 /* 274 * See if the three I/O ports look reasonable. 275 * Touch the minimal number of registers in the 276 * failure case. 277 */ 278 status = aha_inb(aha, STATUS_REG); 279 if ((status == 0) 280 || (status & (DIAG_ACTIVE|CMD_REG_BUSY| 281 STATUS_REG_RSVD)) != 0) { 282 PRVERB(("%s: status reg test failed %x\n", aha_name(aha), 283 status)); 284 return (ENXIO); 285 } 286 287 intstat = aha_inb(aha, INTSTAT_REG); 288 if ((intstat & INTSTAT_REG_RSVD) != 0) { 289 PRVERB(("%s: Failed Intstat Reg Test\n", aha_name(aha))); 290 return (ENXIO); 291 } 292 293 /* 294 * Looking good so far. Final test is to reset the 295 * adapter and fetch the board ID and ensure we aren't 296 * looking at a BusLogic. 297 */ 298 if ((error = ahareset(aha, /*hard_reset*/TRUE)) != 0) { 299 PRVERB(("%s: Failed Reset\n", aha_name(aha))); 300 return (ENXIO); 301 } 302 303 /* 304 * Get the board ID. We use this to see if we're dealing with 305 * a buslogic card or an aha card (or clone). 306 */ 307 error = aha_cmd(aha, AOP_INQUIRE_BOARD_ID, NULL, /*parmlen*/0, 308 (u_int8_t*)&board_id, sizeof(board_id), 309 DEFAULT_CMD_TIMEOUT); 310 if (error != 0) { 311 PRVERB(("%s: INQUIRE failed %x\n", aha_name(aha), error)); 312 return (ENXIO); 313 } 314 aha->fw_major = board_id.firmware_rev_major; 315 aha->fw_minor = board_id.firmware_rev_minor; 316 aha->boardid = board_id.board_type; 317 318 /* 319 * The Buslogic cards have an id of either 0x41 or 0x42. So 320 * if those come up in the probe, we test the geometry register 321 * of the board. Adaptec boards that are this old will not have 322 * this register, and return 0xff, while buslogic cards will return 323 * something different. 324 * 325 * It appears that for reasons unknow, for the for the 326 * aha-1542B cards, we need to wait a little bit before trying 327 * to read the geometry register. I picked 10ms since we have 328 * reports that a for loop to 1000 did the trick, and this 329 * errs on the side of conservatism. Besides, no one will 330 * notice a 10mS delay here, even the 1542B card users :-) 331 * 332 * Some compatible cards return 0 here. Some cards also 333 * seem to return 0x7f. 334 * 335 * XXX I'm not sure how this will impact other cloned cards 336 * 337 * This really should be replaced with the esetup command, since 338 * that appears to be more reliable. This becomes more and more 339 * true over time as we discover more cards that don't read the 340 * geometry register consistantly. 341 */ 342 if (aha->boardid <= 0x42) { 343 /* Wait 10ms before reading */ 344 DELAY(10000); 345 status = aha_inb(aha, GEOMETRY_REG); 346 if (status != 0xff && status != 0x00 && status != 0x7f) { 347 PRVERB(("%s: Geometry Register test failed 0x%x\n", 348 aha_name(aha), status)); 349 return (ENXIO); 350 } 351 } 352 353 return (0); 354} 355 356/* 357 * Pull the boards setup information and record it in our softc. 358 */ 359int 360aha_fetch_adapter_info(struct aha_softc *aha) 361{ 362 setup_data_t setup_info; 363 config_data_t config_data; 364 u_int8_t length_param; 365 int error; 366 struct aha_extbios extbios; 367 368 switch (aha->boardid) { 369 case BOARD_1540_16HEAD_BIOS: 370 snprintf(aha->model, sizeof(aha->model), "1540 16 head BIOS"); 371 break; 372 case BOARD_1540_64HEAD_BIOS: 373 snprintf(aha->model, sizeof(aha->model), "1540 64 head BIOS"); 374 break; 375 case BOARD_1542: 376 snprintf(aha->model, sizeof(aha->model), "1540/1542 64 head BIOS"); 377 break; 378 case BOARD_1640: 379 snprintf(aha->model, sizeof(aha->model), "1640"); 380 break; 381 case BOARD_1740: 382 snprintf(aha->model, sizeof(aha->model), "1740A/1742A/1744"); 383 break; 384 case BOARD_1542C: 385 snprintf(aha->model, sizeof(aha->model), "1542C"); 386 break; 387 case BOARD_1542CF: 388 snprintf(aha->model, sizeof(aha->model), "1542CF"); 389 break; 390 case BOARD_1542CP: 391 snprintf(aha->model, sizeof(aha->model), "1542CP"); 392 break; 393 default: 394 snprintf(aha->model, sizeof(aha->model), "Unknown"); 395 break; 396 } 397 /* 398 * If we are a new type of 1542 board (anything newer than a 1542C) 399 * then disable the extended bios so that the 400 * mailbox interface is unlocked. 401 * This is also true for the 1542B Version 3.20. First Adaptec 402 * board that supports >1Gb drives. 403 * No need to check the extended bios flags as some of the 404 * extensions that cause us problems are not flagged in that byte. 405 */ 406 if (PROBABLY_NEW_BOARD(aha->boardid) || 407 (aha->boardid == 0x41 408 && aha->fw_major == 0x31 && 409 aha->fw_minor >= 0x34)) { 410 error = aha_cmd(aha, AOP_RETURN_EXT_BIOS_INFO, NULL, 411 /*paramlen*/0, (u_char *)&extbios, sizeof(extbios), 412 DEFAULT_CMD_TIMEOUT); 413 error = aha_cmd(aha, AOP_MBOX_IF_ENABLE, (u_int8_t *)&extbios, 414 /*paramlen*/2, NULL, 0, DEFAULT_CMD_TIMEOUT); 415 } 416 if (aha->boardid < 0x41) 417 printf("%s: Warning: aha-1542A won't likely work.\n", 418 aha_name(aha)); 419 420 aha->max_sg = 17; /* Need >= 17 to do 64k I/O */ 421 aha->diff_bus = 0; 422 aha->extended_lun = 0; 423 aha->extended_trans = 0; 424 aha->max_ccbs = 16; 425 /* Determine Sync/Wide/Disc settings */ 426 length_param = sizeof(setup_info); 427 error = aha_cmd(aha, AOP_INQUIRE_SETUP_INFO, &length_param, 428 /*paramlen*/1, (u_int8_t*)&setup_info, 429 sizeof(setup_info), DEFAULT_CMD_TIMEOUT); 430 if (error != 0) { 431 printf("%s: aha_fetch_adapter_info - Failed " 432 "Get Setup Info\n", aha_name(aha)); 433 return (error); 434 } 435 if (setup_info.initiate_sync != 0) { 436 aha->sync_permitted = ALL_TARGETS; 437 } 438 aha->disc_permitted = ALL_TARGETS; 439 440 /* We need as many mailboxes as we can have ccbs */ 441 aha->num_boxes = aha->max_ccbs; 442 443 /* Determine our SCSI ID */ 444 445 error = aha_cmd(aha, AOP_INQUIRE_CONFIG, NULL, /*parmlen*/0, 446 (u_int8_t*)&config_data, sizeof(config_data), 447 DEFAULT_CMD_TIMEOUT); 448 if (error != 0) { 449 printf("%s: aha_fetch_adapter_info - Failed Get Config\n", 450 aha_name(aha)); 451 return (error); 452 } 453 aha->scsi_id = config_data.scsi_id; 454 return (0); 455} 456 457/* 458 * Start the board, ready for normal operation 459 */ 460int 461aha_init(struct aha_softc* aha) 462{ 463 /* Announce the Adapter */ 464 printf("%s: AHA-%s FW Rev. %c.%c (ID=%x) ", aha_name(aha), 465 aha->model, aha->fw_major, aha->fw_minor, aha->boardid); 466 467 if (aha->diff_bus != 0) 468 printf("Diff "); 469 470 printf("SCSI Host Adapter, SCSI ID %d, %d CCBs\n", aha->scsi_id, 471 aha->max_ccbs); 472 473 /* 474 * Create our DMA tags. These tags define the kinds of device 475 * accessible memory allocations and memory mappings we will 476 * need to perform during normal operation. 477 * 478 * Unless we need to further restrict the allocation, we rely 479 * on the restrictions of the parent dmat, hence the common 480 * use of MAXADDR and MAXSIZE. 481 */ 482 483 /* DMA tag for mapping buffers into device visible space. */ 484 if (bus_dma_tag_create( /* parent */ aha->parent_dmat, 485 /* alignment */ 1, 486 /* boundary */ 0, 487 /* lowaddr */ BUS_SPACE_MAXADDR, 488 /* highaddr */ BUS_SPACE_MAXADDR, 489 /* filter */ NULL, 490 /* filterarg */ NULL, 491 /* maxsize */ MAXBSIZE, 492 /* nsegments */ AHA_NSEG, 493 /* maxsegsz */ BUS_SPACE_MAXSIZE_24BIT, 494 /* flags */ BUS_DMA_ALLOCNOW, 495 &aha->buffer_dmat) != 0) { 496 goto error_exit; 497 } 498 499 aha->init_level++; 500 /* DMA tag for our mailboxes */ 501 if (bus_dma_tag_create( /* parent */ aha->parent_dmat, 502 /* alignment */ 1, 503 /* boundary */ 0, 504 /* lowaddr */ BUS_SPACE_MAXADDR, 505 /* highaddr */ BUS_SPACE_MAXADDR, 506 /* filter */ NULL, 507 /* filterarg */ NULL, 508 /* maxsize */ aha->num_boxes * 509 (sizeof(aha_mbox_in_t) + 510 sizeof(aha_mbox_out_t)), 511 /* nsegments */ 1, 512 /* maxsegsz */ BUS_SPACE_MAXSIZE_24BIT, 513 /* flags */ 0, 514 &aha->mailbox_dmat) != 0) { 515 goto error_exit; 516 } 517 518 aha->init_level++; 519 520 /* Allocation for our mailboxes */ 521 if (bus_dmamem_alloc(aha->mailbox_dmat, (void **)&aha->out_boxes, 522 BUS_DMA_NOWAIT, &aha->mailbox_dmamap) != 0) { 523 goto error_exit; 524 } 525 526 aha->init_level++; 527 528 /* And permanently map them */ 529 bus_dmamap_load(aha->mailbox_dmat, aha->mailbox_dmamap, 530 aha->out_boxes, 531 aha->num_boxes * (sizeof(aha_mbox_in_t) 532 + sizeof(aha_mbox_out_t)), 533 ahamapmboxes, aha, /*flags*/0); 534 535 aha->init_level++; 536 537 aha->in_boxes = (aha_mbox_in_t *)&aha->out_boxes[aha->num_boxes]; 538 539 ahainitmboxes(aha); 540 541 /* DMA tag for our ccb structures */ 542 if (bus_dma_tag_create( /* parent */ aha->parent_dmat, 543 /* alignment */ 1, 544 /* boundary */ 0, 545 /* lowaddr */ BUS_SPACE_MAXADDR, 546 /* highaddr */ BUS_SPACE_MAXADDR, 547 /* filter */ NULL, 548 /* filterarg */ NULL, 549 /* maxsize */ aha->max_ccbs * 550 sizeof(struct aha_ccb), 551 /* nsegments */ 1, 552 /* maxsegsz */ BUS_SPACE_MAXSIZE_24BIT, 553 /* flags */ 0, 554 &aha->ccb_dmat) != 0) { 555 goto error_exit; 556 } 557 558 aha->init_level++; 559 560 /* Allocation for our ccbs */ 561 if (bus_dmamem_alloc(aha->ccb_dmat, (void **)&aha->aha_ccb_array, 562 BUS_DMA_NOWAIT, &aha->ccb_dmamap) != 0) { 563 goto error_exit; 564 } 565 566 aha->init_level++; 567 568 /* And permanently map them */ 569 bus_dmamap_load(aha->ccb_dmat, aha->ccb_dmamap, 570 aha->aha_ccb_array, 571 aha->max_ccbs * sizeof(struct aha_ccb), 572 ahamapccbs, aha, /*flags*/0); 573 574 aha->init_level++; 575 576 /* DMA tag for our S/G structures. We allocate in page sized chunks */ 577 if (bus_dma_tag_create( /* parent */ aha->parent_dmat, 578 /* alignment */ 1, 579 /* boundary */ 0, 580 /* lowaddr */ BUS_SPACE_MAXADDR, 581 /* highaddr */ BUS_SPACE_MAXADDR, 582 /* filter */ NULL, 583 /* filterarg */ NULL, 584 /* maxsize */ PAGE_SIZE, 585 /* nsegments */ 1, 586 /* maxsegsz */ BUS_SPACE_MAXSIZE_24BIT, 587 /* flags */ 0, 588 &aha->sg_dmat) != 0) { 589 goto error_exit; 590 } 591 592 aha->init_level++; 593 594 /* Perform initial CCB allocation */ 595 bzero(aha->aha_ccb_array, aha->max_ccbs * sizeof(struct aha_ccb)); 596 ahaallocccbs(aha); 597 598 if (aha->num_ccbs == 0) { 599 printf("%s: aha_init - Unable to allocate initial ccbs\n", 600 aha_name(aha)); 601 goto error_exit; 602 } 603 604 /* 605 * Note that we are going and return (to probe) 606 */ 607 return 0; 608 609error_exit: 610 611 return (ENXIO); 612} 613 614int 615aha_attach(struct aha_softc *aha) 616{ 617 int tagged_dev_openings; 618 struct cam_devq *devq; 619 620 /* 621 * We don't do tagged queueing, since the aha cards don't 622 * support it. 623 */ 624 tagged_dev_openings = 0; 625 626 /* 627 * Create the device queue for our SIM. 628 */ 629 devq = cam_simq_alloc(aha->max_ccbs - 1); 630 if (devq == NULL) 631 return (ENOMEM); 632 633 /* 634 * Construct our SIM entry 635 */ 636 aha->sim = cam_sim_alloc(ahaaction, ahapoll, "aha", aha, aha->unit, 637 2, tagged_dev_openings, devq); 638 if (aha->sim == NULL) { 639 cam_simq_free(devq); 640 return (ENOMEM); 641 } 642 643 if (xpt_bus_register(aha->sim, 0) != CAM_SUCCESS) { 644 cam_sim_free(aha->sim, /*free_devq*/TRUE); 645 return (ENXIO); 646 } 647 648 if (xpt_create_path(&aha->path, /*periph*/NULL, 649 cam_sim_path(aha->sim), CAM_TARGET_WILDCARD, 650 CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 651 xpt_bus_deregister(cam_sim_path(aha->sim)); 652 cam_sim_free(aha->sim, /*free_devq*/TRUE); 653 return (ENXIO); 654 } 655 656 return (0); 657} 658 659char * 660aha_name(struct aha_softc *aha) 661{ 662 static char name[10]; 663 664 snprintf(name, sizeof(name), "aha%d", aha->unit); 665 return (name); 666} 667 668void 669aha_find_probe_range(int ioport, int *port_index, int *max_port_index) 670{ 671 if (ioport > 0) { 672 int i; 673 674 for (i = 0;i < AHA_NUM_ISAPORTS; i++) 675 if (ioport <= aha_isa_ports[i].addr) 676 break; 677 if ((i >= AHA_NUM_ISAPORTS) 678 || (ioport != aha_isa_ports[i].addr)) { 679 printf("\n" 680"aha_isa_probe: Invalid baseport of 0x%x specified.\n" 681"aha_isa_probe: Nearest valid baseport is 0x%x.\n" 682"aha_isa_probe: Failing probe.\n", 683 ioport, 684 (i < AHA_NUM_ISAPORTS) 685 ? aha_isa_ports[i].addr 686 : aha_isa_ports[AHA_NUM_ISAPORTS - 1].addr); 687 *port_index = *max_port_index = -1; 688 return; 689 } 690 *port_index = *max_port_index = aha_isa_ports[i].bio; 691 } else { 692 *port_index = 0; 693 *max_port_index = AHA_NUM_ISAPORTS - 1; 694 } 695} 696 697int 698aha_iop_from_bio(isa_compat_io_t bio_index) 699{ 700 if (bio_index >= 0 && bio_index < AHA_NUM_ISAPORTS) 701 return (aha_board_ports[bio_index]); 702 return (-1); 703} 704 705static void 706ahaallocccbs(struct aha_softc *aha) 707{ 708 struct aha_ccb *next_ccb; 709 struct sg_map_node *sg_map; 710 bus_addr_t physaddr; 711 aha_sg_t *segs; 712 int newcount; 713 int i; 714 715 next_ccb = &aha->aha_ccb_array[aha->num_ccbs]; 716 717 sg_map = malloc(sizeof(*sg_map), M_DEVBUF, M_NOWAIT); 718 719 if (sg_map == NULL) 720 return; 721 722 /* Allocate S/G space for the next batch of CCBS */ 723 if (bus_dmamem_alloc(aha->sg_dmat, (void **)&sg_map->sg_vaddr, 724 BUS_DMA_NOWAIT, &sg_map->sg_dmamap) != 0) { 725 free(sg_map, M_DEVBUF); 726 return; 727 } 728 729 SLIST_INSERT_HEAD(&aha->sg_maps, sg_map, links); 730 731 bus_dmamap_load(aha->sg_dmat, sg_map->sg_dmamap, sg_map->sg_vaddr, 732 PAGE_SIZE, ahamapsgs, aha, /*flags*/0); 733 734 segs = sg_map->sg_vaddr; 735 physaddr = sg_map->sg_physaddr; 736 737 newcount = (PAGE_SIZE / (AHA_NSEG * sizeof(aha_sg_t))); 738 for (i = 0; aha->num_ccbs < aha->max_ccbs && i < newcount; i++) { 739 int error; 740 741 next_ccb->sg_list = segs; 742 next_ccb->sg_list_phys = physaddr; 743 next_ccb->flags = ACCB_FREE; 744 error = bus_dmamap_create(aha->buffer_dmat, /*flags*/0, 745 &next_ccb->dmamap); 746 if (error != 0) 747 break; 748 SLIST_INSERT_HEAD(&aha->free_aha_ccbs, next_ccb, links); 749 segs += AHA_NSEG; 750 physaddr += (AHA_NSEG * sizeof(aha_sg_t)); 751 next_ccb++; 752 aha->num_ccbs++; 753 } 754 755 /* Reserve a CCB for error recovery */ 756 if (aha->recovery_accb == NULL) { 757 aha->recovery_accb = SLIST_FIRST(&aha->free_aha_ccbs); 758 SLIST_REMOVE_HEAD(&aha->free_aha_ccbs, links); 759 } 760} 761 762static __inline void 763ahafreeccb(struct aha_softc *aha, struct aha_ccb *accb) 764{ 765 int s; 766 767 s = splcam(); 768 if ((accb->flags & ACCB_ACTIVE) != 0) 769 LIST_REMOVE(&accb->ccb->ccb_h, sim_links.le); 770 if (aha->resource_shortage != 0 771 && (accb->ccb->ccb_h.status & CAM_RELEASE_SIMQ) == 0) { 772 accb->ccb->ccb_h.status |= CAM_RELEASE_SIMQ; 773 aha->resource_shortage = FALSE; 774 } 775 accb->flags = ACCB_FREE; 776 SLIST_INSERT_HEAD(&aha->free_aha_ccbs, accb, links); 777 aha->active_ccbs--; 778 splx(s); 779} 780 781static struct aha_ccb* 782ahagetccb(struct aha_softc *aha) 783{ 784 struct aha_ccb* accb; 785 int s; 786 787 s = splcam(); 788 if ((accb = SLIST_FIRST(&aha->free_aha_ccbs)) != NULL) { 789 SLIST_REMOVE_HEAD(&aha->free_aha_ccbs, links); 790 aha->active_ccbs++; 791 } else if (aha->num_ccbs < aha->max_ccbs) { 792 ahaallocccbs(aha); 793 accb = SLIST_FIRST(&aha->free_aha_ccbs); 794 if (accb == NULL) 795 printf("%s: Can't malloc ACCB\n", aha_name(aha)); 796 else { 797 SLIST_REMOVE_HEAD(&aha->free_aha_ccbs, links); 798 aha->active_ccbs++; 799 } 800 } 801 splx(s); 802 803 return (accb); 804} 805 806static void 807ahaaction(struct cam_sim *sim, union ccb *ccb) 808{ 809 struct aha_softc *aha; 810 811 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("ahaaction\n")); 812 813 aha = (struct aha_softc *)cam_sim_softc(sim); 814 815 switch (ccb->ccb_h.func_code) { 816 /* Common cases first */ 817 case XPT_SCSI_IO: /* Execute the requested I/O operation */ 818 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */ 819 { 820 struct aha_ccb *accb; 821 struct aha_hccb *hccb; 822 823 /* 824 * Get an accb to use. 825 */ 826 if ((accb = ahagetccb(aha)) == NULL) { 827 int s; 828 829 s = splcam(); 830 aha->resource_shortage = TRUE; 831 splx(s); 832 xpt_freeze_simq(aha->sim, /*count*/1); 833 ccb->ccb_h.status = CAM_REQUEUE_REQ; 834 xpt_done(ccb); 835 return; 836 } 837 838 hccb = &accb->hccb; 839 840 /* 841 * So we can find the ACCB when an abort is requested 842 */ 843 accb->ccb = ccb; 844 ccb->ccb_h.ccb_accb_ptr = accb; 845 ccb->ccb_h.ccb_aha_ptr = aha; 846 847 /* 848 * Put all the arguments for the xfer in the accb 849 */ 850 hccb->target = ccb->ccb_h.target_id; 851 hccb->lun = ccb->ccb_h.target_lun; 852 hccb->ahastat = 0; 853 hccb->sdstat = 0; 854 855 if (ccb->ccb_h.func_code == XPT_SCSI_IO) { 856 struct ccb_scsiio *csio; 857 struct ccb_hdr *ccbh; 858 859 csio = &ccb->csio; 860 ccbh = &csio->ccb_h; 861 hccb->opcode = aha->ccb_ccb_opcode; 862 hccb->datain = (ccb->ccb_h.flags & CAM_DIR_IN) != 0; 863 hccb->dataout = (ccb->ccb_h.flags & CAM_DIR_OUT) != 0; 864 hccb->cmd_len = csio->cdb_len; 865 if (hccb->cmd_len > sizeof(hccb->scsi_cdb)) { 866 ccb->ccb_h.status = CAM_REQ_INVALID; 867 ahafreeccb(aha, accb); 868 xpt_done(ccb); 869 return; 870 } 871 hccb->sense_len = csio->sense_len; 872 if ((ccbh->flags & CAM_CDB_POINTER) != 0) { 873 if ((ccbh->flags & CAM_CDB_PHYS) == 0) { 874 bcopy(csio->cdb_io.cdb_ptr, 875 hccb->scsi_cdb, hccb->cmd_len); 876 } else { 877 /* I guess I could map it in... */ 878 ccbh->status = CAM_REQ_INVALID; 879 ahafreeccb(aha, accb); 880 xpt_done(ccb); 881 return; 882 } 883 } else { 884 bcopy(csio->cdb_io.cdb_bytes, 885 hccb->scsi_cdb, hccb->cmd_len); 886 } 887 /* 888 * If we have any data to send with this command, 889 * map it into bus space. 890 */ 891 /* Only use S/G if there is a transfer */ 892 if ((ccbh->flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 893 if ((ccbh->flags & CAM_SCATTER_VALID) == 0) { 894 /* 895 * We've been given a pointer 896 * to a single buffer. 897 */ 898 if ((ccbh->flags & CAM_DATA_PHYS)==0) { 899 int s; 900 int error; 901 902 s = splsoftvm(); 903 error = bus_dmamap_load( 904 aha->buffer_dmat, 905 accb->dmamap, 906 csio->data_ptr, 907 csio->dxfer_len, 908 ahaexecuteccb, 909 accb, 910 /*flags*/0); 911 if (error == EINPROGRESS) { 912 /* 913 * So as to maintain 914 * ordering, freeze the 915 * controller queue 916 * until our mapping is 917 * returned. 918 */ 919 xpt_freeze_simq(aha->sim, 920 1); 921 csio->ccb_h.status |= 922 CAM_RELEASE_SIMQ; 923 } 924 splx(s); 925 } else { 926 struct bus_dma_segment seg; 927 928 /* Pointer to physical buffer */ 929 seg.ds_addr = 930 (bus_addr_t)csio->data_ptr; 931 seg.ds_len = csio->dxfer_len; 932 ahaexecuteccb(accb, &seg, 1, 0); 933 } 934 } else { 935 struct bus_dma_segment *segs; 936 937 if ((ccbh->flags & CAM_DATA_PHYS) != 0) 938 panic("ahaaction - Physical " 939 "segment pointers " 940 "unsupported"); 941 942 if ((ccbh->flags&CAM_SG_LIST_PHYS)==0) 943 panic("ahaaction - Virtual " 944 "segment addresses " 945 "unsupported"); 946 947 /* Just use the segments provided */ 948 segs = (struct bus_dma_segment *) 949 csio->data_ptr; 950 ahaexecuteccb(accb, segs, 951 csio->sglist_cnt, 0); 952 } 953 } else { 954 ahaexecuteccb(accb, NULL, 0, 0); 955 } 956 } else { 957 hccb->opcode = INITIATOR_BUS_DEV_RESET; 958 /* No data transfer */ 959 hccb->datain = TRUE; 960 hccb->dataout = TRUE; 961 hccb->cmd_len = 0; 962 hccb->sense_len = 0; 963 ahaexecuteccb(accb, NULL, 0, 0); 964 } 965 break; 966 } 967 case XPT_EN_LUN: /* Enable LUN as a target */ 968 case XPT_TARGET_IO: /* Execute target I/O request */ 969 case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */ 970 case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/ 971 case XPT_ABORT: /* Abort the specified CCB */ 972 /* XXX Implement */ 973 ccb->ccb_h.status = CAM_REQ_INVALID; 974 xpt_done(ccb); 975 break; 976 case XPT_SET_TRAN_SETTINGS: 977 { 978 /* XXX Implement */ 979 ccb->ccb_h.status = CAM_PROVIDE_FAIL; 980 xpt_done(ccb); 981 break; 982 } 983 case XPT_GET_TRAN_SETTINGS: 984 /* Get default/user set transfer settings for the target */ 985 { 986 struct ccb_trans_settings *cts; 987 u_int target_mask; 988 989 cts = &ccb->cts; 990 target_mask = 0x01 << ccb->ccb_h.target_id; 991 if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) { 992 cts->flags = 0; 993 if ((aha->disc_permitted & target_mask) != 0) 994 cts->flags |= CCB_TRANS_DISC_ENB; 995 cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT; 996 if ((aha->sync_permitted & target_mask) != 0) { 997 if (aha->boardid >= BOARD_1542CF) 998 cts->sync_period = 25; 999 else 1000 cts->sync_period = 50; 1001 } else 1002 cts->sync_period = 0; 1003 1004 if (cts->sync_period != 0) 1005 cts->sync_offset = 15; 1006 1007 cts->valid = CCB_TRANS_SYNC_RATE_VALID 1008 | CCB_TRANS_SYNC_OFFSET_VALID 1009 | CCB_TRANS_BUS_WIDTH_VALID 1010 | CCB_TRANS_DISC_VALID 1011 | CCB_TRANS_TQ_VALID; 1012 } else { 1013 ahafetchtransinfo(aha, cts); 1014 } 1015 1016 ccb->ccb_h.status = CAM_REQ_CMP; 1017 xpt_done(ccb); 1018 break; 1019 } 1020 case XPT_CALC_GEOMETRY: 1021 { 1022 struct ccb_calc_geometry *ccg; 1023 u_int32_t size_mb; 1024 u_int32_t secs_per_cylinder; 1025 1026 ccg = &ccb->ccg; 1027 size_mb = ccg->volume_size 1028 / ((1024L * 1024L) / ccg->block_size); 1029 1030 if (size_mb >= 1024 && (aha->extended_trans != 0)) { 1031 if (size_mb >= 2048) { 1032 ccg->heads = 255; 1033 ccg->secs_per_track = 63; 1034 } else { 1035 ccg->heads = 128; 1036 ccg->secs_per_track = 32; 1037 } 1038 } else { 1039 ccg->heads = 64; 1040 ccg->secs_per_track = 32; 1041 } 1042 secs_per_cylinder = ccg->heads * ccg->secs_per_track; 1043 ccg->cylinders = ccg->volume_size / secs_per_cylinder; 1044 ccb->ccb_h.status = CAM_REQ_CMP; 1045 xpt_done(ccb); 1046 break; 1047 } 1048 case XPT_RESET_BUS: /* Reset the specified SCSI bus */ 1049 { 1050 ahareset(aha, /*hardreset*/TRUE); 1051 ccb->ccb_h.status = CAM_REQ_CMP; 1052 xpt_done(ccb); 1053 break; 1054 } 1055 case XPT_TERM_IO: /* Terminate the I/O process */ 1056 /* XXX Implement */ 1057 ccb->ccb_h.status = CAM_REQ_INVALID; 1058 xpt_done(ccb); 1059 break; 1060 case XPT_PATH_INQ: /* Path routing inquiry */ 1061 { 1062 struct ccb_pathinq *cpi = &ccb->cpi; 1063 1064 cpi->version_num = 1; /* XXX??? */ 1065 cpi->hba_inquiry = PI_SDTR_ABLE; 1066 cpi->target_sprt = 0; 1067 cpi->hba_misc = 0; 1068 cpi->hba_eng_cnt = 0; 1069 cpi->max_target = 7; 1070 cpi->max_lun = 7; 1071 cpi->initiator_id = aha->scsi_id; 1072 cpi->bus_id = cam_sim_bus(sim); 1073 cpi->base_transfer_speed = 3300; 1074 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 1075 strncpy(cpi->hba_vid, "Adaptec", HBA_IDLEN); 1076 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 1077 cpi->unit_number = cam_sim_unit(sim); 1078 cpi->ccb_h.status = CAM_REQ_CMP; 1079 xpt_done(ccb); 1080 break; 1081 } 1082 default: 1083 ccb->ccb_h.status = CAM_REQ_INVALID; 1084 xpt_done(ccb); 1085 break; 1086 } 1087} 1088 1089static void 1090ahaexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) 1091{ 1092 struct aha_ccb *accb; 1093 union ccb *ccb; 1094 struct aha_softc *aha; 1095 int s; 1096 u_int32_t paddr; 1097 1098 accb = (struct aha_ccb *)arg; 1099 ccb = accb->ccb; 1100 aha = (struct aha_softc *)ccb->ccb_h.ccb_aha_ptr; 1101 1102 if (error != 0) { 1103 if (error != EFBIG) 1104 printf("%s: Unexepected error 0x%x returned from " 1105 "bus_dmamap_load\n", aha_name(aha), error); 1106 if (ccb->ccb_h.status == CAM_REQ_INPROG) { 1107 xpt_freeze_devq(ccb->ccb_h.path, /*count*/1); 1108 ccb->ccb_h.status = CAM_REQ_TOO_BIG|CAM_DEV_QFRZN; 1109 } 1110 ahafreeccb(aha, accb); 1111 xpt_done(ccb); 1112 return; 1113 } 1114 1115 if (nseg != 0) { 1116 aha_sg_t *sg; 1117 bus_dma_segment_t *end_seg; 1118 bus_dmasync_op_t op; 1119 1120 end_seg = dm_segs + nseg; 1121 1122 /* Copy the segments into our SG list */ 1123 sg = accb->sg_list; 1124 while (dm_segs < end_seg) { 1125 ahautoa24(dm_segs->ds_len, sg->len); 1126 ahautoa24(dm_segs->ds_addr, sg->addr); 1127 sg++; 1128 dm_segs++; 1129 } 1130 1131 if (nseg > 1) { 1132 accb->hccb.opcode = aha->ccb_sg_opcode; 1133 ahautoa24((sizeof(aha_sg_t) * nseg), 1134 accb->hccb.data_len); 1135 ahautoa24(accb->sg_list_phys, accb->hccb.data_addr); 1136 } else { 1137 bcopy(accb->sg_list->len, accb->hccb.data_len, 3); 1138 bcopy(accb->sg_list->addr, accb->hccb.data_addr, 3); 1139 } 1140 1141 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) 1142 op = BUS_DMASYNC_PREREAD; 1143 else 1144 op = BUS_DMASYNC_PREWRITE; 1145 1146 bus_dmamap_sync(aha->buffer_dmat, accb->dmamap, op); 1147 1148 } else { 1149 accb->hccb.opcode = INITIATOR_CCB; 1150 ahautoa24(0, accb->hccb.data_len); 1151 ahautoa24(0, accb->hccb.data_addr); 1152 } 1153 1154 s = splcam(); 1155 1156 /* 1157 * Last time we need to check if this CCB needs to 1158 * be aborted. 1159 */ 1160 if (ccb->ccb_h.status != CAM_REQ_INPROG) { 1161 if (nseg != 0) 1162 bus_dmamap_unload(aha->buffer_dmat, accb->dmamap); 1163 ahafreeccb(aha, accb); 1164 xpt_done(ccb); 1165 splx(s); 1166 return; 1167 } 1168 1169 accb->flags = ACCB_ACTIVE; 1170 ccb->ccb_h.status |= CAM_SIM_QUEUED; 1171 LIST_INSERT_HEAD(&aha->pending_ccbs, &ccb->ccb_h, sim_links.le); 1172 1173 ccb->ccb_h.timeout_ch = 1174 timeout(ahatimeout, (caddr_t)accb, 1175 (ccb->ccb_h.timeout * hz) / 1000); 1176 1177 /* Tell the adapter about this command */ 1178 if (aha->cur_outbox->action_code != AMBO_FREE) { 1179 /* 1180 * We should never encounter a busy mailbox. 1181 * If we do, warn the user, and treat it as 1182 * a resource shortage. If the controller is 1183 * hung, one of the pending transactions will 1184 * timeout causing us to start recovery operations. 1185 */ 1186 printf("%s: Encountered busy mailbox with %d out of %d " 1187 "commands active!!!", aha_name(aha), aha->active_ccbs, 1188 aha->max_ccbs); 1189 untimeout(ahatimeout, accb, ccb->ccb_h.timeout_ch); 1190 if (nseg != 0) 1191 bus_dmamap_unload(aha->buffer_dmat, accb->dmamap); 1192 ahafreeccb(aha, accb); 1193 aha->resource_shortage = TRUE; 1194 xpt_freeze_simq(aha->sim, /*count*/1); 1195 ccb->ccb_h.status = CAM_REQUEUE_REQ; 1196 xpt_done(ccb); 1197 return; 1198 } 1199 paddr = ahaccbvtop(aha, accb); 1200 ahautoa24(paddr, aha->cur_outbox->ccb_addr); 1201 aha->cur_outbox->action_code = AMBO_START; 1202 aha_outb(aha, COMMAND_REG, AOP_START_MBOX); 1203 1204 ahanextoutbox(aha); 1205 splx(s); 1206} 1207 1208void 1209aha_intr(void *arg) 1210{ 1211 struct aha_softc *aha; 1212 u_int intstat; 1213 1214 aha = (struct aha_softc *)arg; 1215 while (((intstat = aha_inb(aha, INTSTAT_REG)) & INTR_PENDING) != 0) { 1216 if ((intstat & CMD_COMPLETE) != 0) { 1217 aha->latched_status = aha_inb(aha, STATUS_REG); 1218 aha->command_cmp = TRUE; 1219 } 1220 1221 aha_outb(aha, CONTROL_REG, RESET_INTR); 1222 1223 if ((intstat & IMB_LOADED) != 0) { 1224 while (aha->cur_inbox->comp_code != AMBI_FREE) { 1225 u_int32_t paddr; 1226 paddr = aha_a24tou(aha->cur_inbox->ccb_addr); 1227 ahadone(aha, 1228 ahaccbptov(aha, paddr), 1229 aha->cur_inbox->comp_code); 1230 aha->cur_inbox->comp_code = AMBI_FREE; 1231 ahanextinbox(aha); 1232 } 1233 } 1234 1235 if ((intstat & SCSI_BUS_RESET) != 0) { 1236 ahareset(aha, /*hardreset*/FALSE); 1237 } 1238 } 1239} 1240 1241static void 1242ahadone(struct aha_softc *aha, struct aha_ccb *accb, aha_mbi_comp_code_t comp_code) 1243{ 1244 union ccb *ccb; 1245 struct ccb_scsiio *csio; 1246 1247 ccb = accb->ccb; 1248 csio = &accb->ccb->csio; 1249 1250 if ((accb->flags & ACCB_ACTIVE) == 0) { 1251 printf("%s: ahadone - Attempt to free non-active ACCB %p\n", 1252 aha_name(aha), (void *)accb); 1253 return; 1254 } 1255 1256 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 1257 bus_dmasync_op_t op; 1258 1259 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) 1260 op = BUS_DMASYNC_POSTREAD; 1261 else 1262 op = BUS_DMASYNC_POSTWRITE; 1263 bus_dmamap_sync(aha->buffer_dmat, accb->dmamap, op); 1264 bus_dmamap_unload(aha->buffer_dmat, accb->dmamap); 1265 } 1266 1267 if (accb == aha->recovery_accb) { 1268 /* 1269 * The recovery ACCB does not have a CCB associated 1270 * with it, so short circuit the normal error handling. 1271 * We now traverse our list of pending CCBs and process 1272 * any that were terminated by the recovery CCBs action. 1273 * We also reinstate timeouts for all remaining, pending, 1274 * CCBs. 1275 */ 1276 struct cam_path *path; 1277 struct ccb_hdr *ccb_h; 1278 cam_status error; 1279 1280 /* Notify all clients that a BDR occured */ 1281 error = xpt_create_path(&path, /*periph*/NULL, 1282 cam_sim_path(aha->sim), 1283 accb->hccb.target, 1284 CAM_LUN_WILDCARD); 1285 1286 if (error == CAM_REQ_CMP) 1287 xpt_async(AC_SENT_BDR, path, NULL); 1288 1289 ccb_h = LIST_FIRST(&aha->pending_ccbs); 1290 while (ccb_h != NULL) { 1291 struct aha_ccb *pending_accb; 1292 1293 pending_accb = (struct aha_ccb *)ccb_h->ccb_accb_ptr; 1294 if (pending_accb->hccb.target == accb->hccb.target) { 1295 pending_accb->hccb.ahastat = AHASTAT_HA_BDR; 1296 ccb_h = LIST_NEXT(ccb_h, sim_links.le); 1297 ahadone(aha, pending_accb, AMBI_ERROR); 1298 } else { 1299 ccb_h->timeout_ch = 1300 timeout(ahatimeout, (caddr_t)pending_accb, 1301 (ccb_h->timeout * hz) / 1000); 1302 ccb_h = LIST_NEXT(ccb_h, sim_links.le); 1303 } 1304 } 1305 printf("%s: No longer in timeout\n", aha_name(aha)); 1306 return; 1307 } 1308 1309 untimeout(ahatimeout, accb, ccb->ccb_h.timeout_ch); 1310 1311 switch (comp_code) { 1312 case AMBI_FREE: 1313 printf("%s: ahadone - CCB completed with free status!\n", 1314 aha_name(aha)); 1315 break; 1316 case AMBI_NOT_FOUND: 1317 printf("%s: ahadone - CCB Abort failed to find CCB\n", 1318 aha_name(aha)); 1319 break; 1320 case AMBI_ABORT: 1321 case AMBI_ERROR: 1322 /* An error occured */ 1323 if (accb->hccb.opcode < INITIATOR_CCB_WRESID) 1324 csio->resid = 0; 1325 else 1326 csio->resid = aha_a24tou(accb->hccb.data_len); 1327 switch(accb->hccb.ahastat) { 1328 case AHASTAT_DATARUN_ERROR: 1329 { 1330 if (csio->resid <= 0) { 1331 csio->ccb_h.status = CAM_DATA_RUN_ERR; 1332 break; 1333 } 1334 /* FALLTHROUGH */ 1335 } 1336 case AHASTAT_NOERROR: 1337 csio->scsi_status = accb->hccb.sdstat; 1338 csio->ccb_h.status |= CAM_SCSI_STATUS_ERROR; 1339 switch(csio->scsi_status) { 1340 case SCSI_STATUS_CHECK_COND: 1341 case SCSI_STATUS_CMD_TERMINATED: 1342 csio->ccb_h.status |= CAM_AUTOSNS_VALID; 1343 /* 1344 * The aha writes the sense data at different 1345 * offsets based on the scsi cmd len 1346 */ 1347 bcopy((caddr_t) &accb->hccb.scsi_cdb + 1348 accb->hccb.cmd_len, 1349 (caddr_t) &csio->sense_data, 1350 accb->hccb.sense_len); 1351 break; 1352 default: 1353 break; 1354 case SCSI_STATUS_OK: 1355 csio->ccb_h.status = CAM_REQ_CMP; 1356 break; 1357 } 1358 break; 1359 case AHASTAT_SELTIMEOUT: 1360 csio->ccb_h.status = CAM_SEL_TIMEOUT; 1361 break; 1362 case AHASTAT_UNEXPECTED_BUSFREE: 1363 csio->ccb_h.status = CAM_UNEXP_BUSFREE; 1364 break; 1365 case AHASTAT_INVALID_PHASE: 1366 csio->ccb_h.status = CAM_SEQUENCE_FAIL; 1367 break; 1368 case AHASTAT_INVALID_ACTION_CODE: 1369 panic("%s: Inavlid Action code", aha_name(aha)); 1370 break; 1371 case AHASTAT_INVALID_OPCODE: 1372 if (accb->hccb.opcode < INITIATOR_CCB_WRESID) 1373 panic("%s: Invalid CCB Opcode %x hccb = %p", 1374 aha_name(aha), accb->hccb.opcode, 1375 &accb->hccb); 1376 printf("%s: AHA-1540A detected, compensating\n", 1377 aha_name(aha)); 1378 aha->ccb_sg_opcode = INITIATOR_SG_CCB; 1379 aha->ccb_ccb_opcode = INITIATOR_CCB; 1380 xpt_freeze_devq(ccb->ccb_h.path, /*count*/1); 1381 csio->ccb_h.status = CAM_REQUEUE_REQ; 1382 break; 1383 case AHASTAT_LINKED_CCB_LUN_MISMATCH: 1384 /* We don't even support linked commands... */ 1385 panic("%s: Linked CCB Lun Mismatch", aha_name(aha)); 1386 break; 1387 case AHASTAT_INVALID_CCB_OR_SG_PARAM: 1388 panic("%s: Invalid CCB or SG list", aha_name(aha)); 1389 break; 1390 case AHASTAT_HA_SCSI_BUS_RESET: 1391 if ((csio->ccb_h.status & CAM_STATUS_MASK) 1392 != CAM_CMD_TIMEOUT) 1393 csio->ccb_h.status = CAM_SCSI_BUS_RESET; 1394 break; 1395 case AHASTAT_HA_BDR: 1396 if ((accb->flags & ACCB_DEVICE_RESET) == 0) 1397 csio->ccb_h.status = CAM_BDR_SENT; 1398 else 1399 csio->ccb_h.status = CAM_CMD_TIMEOUT; 1400 break; 1401 } 1402 if (csio->ccb_h.status != CAM_REQ_CMP) { 1403 xpt_freeze_devq(csio->ccb_h.path, /*count*/1); 1404 csio->ccb_h.status |= CAM_DEV_QFRZN; 1405 } 1406 if ((accb->flags & ACCB_RELEASE_SIMQ) != 0) 1407 ccb->ccb_h.status |= CAM_RELEASE_SIMQ; 1408 ahafreeccb(aha, accb); 1409 xpt_done(ccb); 1410 break; 1411 case AMBI_OK: 1412 /* All completed without incident */ 1413 /* XXX DO WE NEED TO COPY SENSE BYTES HERE???? XXX */ 1414 /* I don't think so since it works???? */ 1415 ccb->ccb_h.status |= CAM_REQ_CMP; 1416 if ((accb->flags & ACCB_RELEASE_SIMQ) != 0) 1417 ccb->ccb_h.status |= CAM_RELEASE_SIMQ; 1418 ahafreeccb(aha, accb); 1419 xpt_done(ccb); 1420 break; 1421 } 1422} 1423 1424static int 1425ahareset(struct aha_softc* aha, int hard_reset) 1426{ 1427 struct ccb_hdr *ccb_h; 1428 u_int status; 1429 u_int timeout; 1430 u_int8_t reset_type; 1431 1432 if (hard_reset != 0) 1433 reset_type = HARD_RESET; 1434 else 1435 reset_type = SOFT_RESET; 1436 aha_outb(aha, CONTROL_REG, reset_type); 1437 1438 /* Wait 5sec. for Diagnostic start */ 1439 timeout = 5 * 10000; 1440 while (--timeout) { 1441 status = aha_inb(aha, STATUS_REG); 1442 if ((status & DIAG_ACTIVE) != 0) 1443 break; 1444 DELAY(100); 1445 } 1446 if (timeout == 0) { 1447 PRVERB(("%s: ahareset - Diagnostic Active failed to " 1448 "assert. status = 0x%x\n", aha_name(aha), 1449 status)); 1450 return (ETIMEDOUT); 1451 } 1452 1453 /* Wait 10sec. for Diagnostic end */ 1454 timeout = 10 * 10000; 1455 while (--timeout) { 1456 status = aha_inb(aha, STATUS_REG); 1457 if ((status & DIAG_ACTIVE) == 0) 1458 break; 1459 DELAY(100); 1460 } 1461 if (timeout == 0) { 1462 panic("%s: ahareset - Diagnostic Active failed to drop. " 1463 "status = 0x%x\n", aha_name(aha), status); 1464 return (ETIMEDOUT); 1465 } 1466 1467 /* Wait for the host adapter to become ready or report a failure */ 1468 timeout = 10000; 1469 while (--timeout) { 1470 status = aha_inb(aha, STATUS_REG); 1471 if ((status & (DIAG_FAIL|HA_READY|DATAIN_REG_READY)) != 0) 1472 break; 1473 DELAY(100); 1474 } 1475 if (timeout == 0) { 1476 printf("%s: ahareset - Host adapter failed to come ready. " 1477 "status = 0x%x\n", aha_name(aha), status); 1478 return (ETIMEDOUT); 1479 } 1480 1481 /* If the diagnostics failed, tell the user */ 1482 if ((status & DIAG_FAIL) != 0 1483 || (status & HA_READY) == 0) { 1484 printf("%s: ahareset - Adapter failed diagnostics\n", 1485 aha_name(aha)); 1486 1487 if ((status & DATAIN_REG_READY) != 0) 1488 printf("%s: ahareset - Host Adapter Error " 1489 "code = 0x%x\n", aha_name(aha), 1490 aha_inb(aha, DATAIN_REG)); 1491 return (ENXIO); 1492 } 1493 1494 /* If we've allocated mailboxes, initialize them */ 1495 if (aha->init_level > 4) 1496 ahainitmboxes(aha); 1497 1498 /* If we've attached to the XPT, tell it about the event */ 1499 if (aha->path != NULL) 1500 xpt_async(AC_BUS_RESET, aha->path, NULL); 1501 1502 /* 1503 * Perform completion processing for all outstanding CCBs. 1504 */ 1505 while ((ccb_h = LIST_FIRST(&aha->pending_ccbs)) != NULL) { 1506 struct aha_ccb *pending_accb; 1507 1508 pending_accb = (struct aha_ccb *)ccb_h->ccb_accb_ptr; 1509 pending_accb->hccb.ahastat = AHASTAT_HA_SCSI_BUS_RESET; 1510 ahadone(aha, pending_accb, AMBI_ERROR); 1511 } 1512 1513 return (0); 1514} 1515 1516/* 1517 * Send a command to the adapter. 1518 */ 1519int 1520aha_cmd(struct aha_softc *aha, aha_op_t opcode, u_int8_t *params, 1521 u_int param_len, u_int8_t *reply_data, u_int reply_len, 1522 u_int cmd_timeout) 1523{ 1524 u_int timeout; 1525 u_int status; 1526 u_int saved_status; 1527 u_int intstat; 1528 u_int reply_buf_size; 1529 int s; 1530 int cmd_complete; 1531 int error; 1532 1533 /* No data returned to start */ 1534 reply_buf_size = reply_len; 1535 reply_len = 0; 1536 intstat = 0; 1537 cmd_complete = 0; 1538 saved_status = 0; 1539 error = 0; 1540 1541 /* 1542 * All commands except for the "start mailbox" and the "enable 1543 * outgoing mailbox read interrupt" commands cannot be issued 1544 * while there are pending transactions. Freeze our SIMQ 1545 * and wait for all completions to occur if necessary. 1546 */ 1547 timeout = 100000; 1548 s = splcam(); 1549 while (LIST_FIRST(&aha->pending_ccbs) != NULL && --timeout) { 1550 /* Fire the interrupt handler in case interrupts are blocked */ 1551 aha_intr(aha); 1552 splx(s); 1553 DELAY(100); 1554 s = splcam(); 1555 } 1556 splx(s); 1557 1558 if (timeout == 0) { 1559 printf("%s: aha_cmd: Timeout waiting for adapter idle\n", 1560 aha_name(aha)); 1561 return (ETIMEDOUT); 1562 } 1563 aha->command_cmp = 0; 1564 /* 1565 * Wait up to 10 sec. for the adapter to become 1566 * ready to accept commands. 1567 */ 1568 timeout = 100000; 1569 while (--timeout) { 1570 1571 status = aha_inb(aha, STATUS_REG); 1572 if ((status & HA_READY) != 0 1573 && (status & CMD_REG_BUSY) == 0) 1574 break; 1575 /* 1576 * Throw away any pending data which may be 1577 * left over from earlier commands that we 1578 * timedout on. 1579 */ 1580 if ((status & DATAIN_REG_READY) != 0) 1581 (void)aha_inb(aha, DATAIN_REG); 1582 DELAY(100); 1583 } 1584 if (timeout == 0) { 1585 printf("%s: aha_cmd: Timeout waiting for adapter ready, " 1586 "status = 0x%x\n", aha_name(aha), status); 1587 return (ETIMEDOUT); 1588 } 1589 1590 /* 1591 * Send the opcode followed by any necessary parameter bytes. 1592 */ 1593 aha_outb(aha, COMMAND_REG, opcode); 1594 1595 /* 1596 * Wait for up to 1sec to get the parameter list sent 1597 */ 1598 timeout = 10000; 1599 while (param_len && --timeout) { 1600 DELAY(100); 1601 s = splcam(); 1602 status = aha_inb(aha, STATUS_REG); 1603 intstat = aha_inb(aha, INTSTAT_REG); 1604 splx(s); 1605 1606 if ((intstat & (INTR_PENDING|CMD_COMPLETE)) 1607 == (INTR_PENDING|CMD_COMPLETE)) { 1608 saved_status = status; 1609 cmd_complete = 1; 1610 break; 1611 } 1612 1613 if (aha->command_cmp != 0) { 1614 saved_status = aha->latched_status; 1615 cmd_complete = 1; 1616 break; 1617 } 1618 if ((status & DATAIN_REG_READY) != 0) 1619 break; 1620 if ((status & CMD_REG_BUSY) == 0) { 1621 aha_outb(aha, COMMAND_REG, *params++); 1622 param_len--; 1623 timeout = 10000; 1624 } 1625 } 1626 if (timeout == 0) { 1627 printf("%s: aha_cmd: Timeout sending parameters, " 1628 "status = 0x%x\n", aha_name(aha), status); 1629 error = ETIMEDOUT; 1630 } 1631 1632 /* 1633 * For all other commands, we wait for any output data 1634 * and the final comand completion interrupt. 1635 */ 1636 while (cmd_complete == 0 && --cmd_timeout) { 1637 1638 s = splcam(); 1639 status = aha_inb(aha, STATUS_REG); 1640 intstat = aha_inb(aha, INTSTAT_REG); 1641 splx(s); 1642 1643 if (aha->command_cmp != 0) { 1644 cmd_complete = 1; 1645 saved_status = aha->latched_status; 1646 } else if ((intstat & (INTR_PENDING|CMD_COMPLETE)) 1647 == (INTR_PENDING|CMD_COMPLETE)) { 1648 /* 1649 * Our poll (in case interrupts are blocked) 1650 * saw the CMD_COMPLETE interrupt. 1651 */ 1652 cmd_complete = 1; 1653 saved_status = status; 1654 } 1655 if ((status & DATAIN_REG_READY) != 0) { 1656 u_int8_t data; 1657 1658 data = aha_inb(aha, DATAIN_REG); 1659 if (reply_len < reply_buf_size) { 1660 *reply_data++ = data; 1661 } else { 1662 printf("%s: aha_cmd - Discarded reply data " 1663 "byte for opcode 0x%x\n", aha_name(aha), 1664 opcode); 1665 } 1666 /* 1667 * Reset timeout to ensure at least a second 1668 * between response bytes. 1669 */ 1670 cmd_timeout = MAX(cmd_timeout, 10000); 1671 reply_len++; 1672 } 1673 DELAY(100); 1674 } 1675 if (cmd_timeout == 0) { 1676 printf("%s: aha_cmd: Timeout waiting for reply data and " 1677 "command complete.\n%s: status = 0x%x, intstat = 0x%x, " 1678 "reply_len = %d\n", aha_name(aha), aha_name(aha), status, 1679 intstat, reply_len); 1680 return (ETIMEDOUT); 1681 } 1682 1683 /* 1684 * Clear any pending interrupts. Block interrupts so our 1685 * interrupt handler is not re-entered. 1686 */ 1687 s = splcam(); 1688 aha_intr(aha); 1689 splx(s); 1690 1691 if (error != 0) 1692 return (error); 1693 1694 /* 1695 * If the command was rejected by the controller, tell the caller. 1696 */ 1697 if ((saved_status & CMD_INVALID) != 0) { 1698 PRVERB(("%s: Invalid Command 0x%x\n", aha_name(aha), opcode)); 1699 /* 1700 * Some early adapters may not recover properly from 1701 * an invalid command. If it appears that the controller 1702 * has wedged (i.e. status was not cleared by our interrupt 1703 * reset above), perform a soft reset. 1704 */ 1705 DELAY(1000); 1706 status = aha_inb(aha, STATUS_REG); 1707 if ((status & (CMD_INVALID|STATUS_REG_RSVD|DATAIN_REG_READY| 1708 CMD_REG_BUSY|DIAG_FAIL|DIAG_ACTIVE)) != 0 1709 || (status & (HA_READY|INIT_REQUIRED)) 1710 != (HA_READY|INIT_REQUIRED)) { 1711 ahareset(aha, /*hard_reset*/FALSE); 1712 } 1713 return (EINVAL); 1714 } 1715 1716 if (param_len > 0) { 1717 /* The controller did not accept the full argument list */ 1718 PRVERB(("%s: Controller did not accept full argument list " 1719 "(%d > 0)\n", 1720 aha_name(aha), param_len)); 1721 return (E2BIG); 1722 } 1723 1724 if (reply_len != reply_buf_size) { 1725 /* Too much or too little data received */ 1726 PRVERB(("%s: Too much or too little data received (%d != %d)\n", 1727 aha_name(aha), reply_len, reply_buf_size)); 1728 return (EMSGSIZE); 1729 } 1730 1731 /* We were successful */ 1732 return (0); 1733} 1734 1735static int 1736ahainitmboxes(struct aha_softc *aha) 1737{ 1738 int error; 1739 init_24b_mbox_params_t init_mbox; 1740 1741 bzero(aha->in_boxes, sizeof(aha_mbox_in_t) * aha->num_boxes); 1742 bzero(aha->out_boxes, sizeof(aha_mbox_out_t) * aha->num_boxes); 1743 aha->cur_inbox = aha->in_boxes; 1744 aha->last_inbox = aha->in_boxes + aha->num_boxes - 1; 1745 aha->cur_outbox = aha->out_boxes; 1746 aha->last_outbox = aha->out_boxes + aha->num_boxes - 1; 1747 1748 /* Tell the adapter about them */ 1749 init_mbox.num_mboxes = aha->num_boxes; 1750 ahautoa24(aha->mailbox_physbase, init_mbox.base_addr); 1751 error = aha_cmd(aha, AOP_INITIALIZE_MBOX, (u_int8_t *)&init_mbox, 1752 /*parmlen*/sizeof(init_mbox), /*reply_buf*/NULL, 1753 /*reply_len*/0, DEFAULT_CMD_TIMEOUT); 1754 1755 if (error != 0) 1756 printf("ahainitmboxes: Initialization command failed\n"); 1757 return (error); 1758} 1759 1760/* 1761 * Update the XPT's idea of the negotiated transfer 1762 * parameters for a particular target. 1763 */ 1764static void 1765ahafetchtransinfo(struct aha_softc *aha, struct ccb_trans_settings* cts) 1766{ 1767 setup_data_t setup_info; 1768 u_int target; 1769 u_int targ_offset; 1770 u_int sync_period; 1771 int error; 1772 u_int8_t param; 1773 targ_syncinfo_t sync_info; 1774 1775 target = cts->ccb_h.target_id; 1776 targ_offset = (target & 0x7); 1777 1778 /* 1779 * Inquire Setup Information. This command retreives 1780 * the sync info for older models. 1781 */ 1782 param = sizeof(setup_info); 1783 error = aha_cmd(aha, AOP_INQUIRE_SETUP_INFO, ¶m, /*paramlen*/1, 1784 (u_int8_t*)&setup_info, sizeof(setup_info), 1785 DEFAULT_CMD_TIMEOUT); 1786 1787 if (error != 0) { 1788 printf("%s: ahafetchtransinfo - Inquire Setup Info Failed %d\n", 1789 aha_name(aha), error); 1790 return; 1791 } 1792 1793 sync_info = setup_info.syncinfo[targ_offset]; 1794 1795 if (sync_info.sync == 0) 1796 cts->sync_offset = 0; 1797 else 1798 cts->sync_offset = sync_info.offset; 1799 1800 cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT; 1801 1802 if (aha->boardid >= BOARD_1542CF) 1803 sync_period = 1000; 1804 else 1805 sync_period = 2000; 1806 sync_period += 500 * sync_info.period; 1807 1808 /* Convert ns value to standard SCSI sync rate */ 1809 if (cts->sync_offset != 0) 1810 cts->sync_period = scsi_calc_syncparam(sync_period); 1811 else 1812 cts->sync_period = 0; 1813 1814 cts->valid = CCB_TRANS_SYNC_RATE_VALID 1815 | CCB_TRANS_SYNC_OFFSET_VALID 1816 | CCB_TRANS_BUS_WIDTH_VALID; 1817 xpt_async(AC_TRANSFER_NEG, cts->ccb_h.path, cts); 1818} 1819 1820static void 1821ahamapmboxes(void *arg, bus_dma_segment_t *segs, int nseg, int error) 1822{ 1823 struct aha_softc* aha; 1824 1825 aha = (struct aha_softc*)arg; 1826 aha->mailbox_physbase = segs->ds_addr; 1827} 1828 1829static void 1830ahamapccbs(void *arg, bus_dma_segment_t *segs, int nseg, int error) 1831{ 1832 struct aha_softc* aha; 1833 1834 aha = (struct aha_softc*)arg; 1835 aha->aha_ccb_physbase = segs->ds_addr; 1836} 1837 1838static void 1839ahamapsgs(void *arg, bus_dma_segment_t *segs, int nseg, int error) 1840{ 1841 1842 struct aha_softc* aha; 1843 1844 aha = (struct aha_softc*)arg; 1845 SLIST_FIRST(&aha->sg_maps)->sg_physaddr = segs->ds_addr; 1846} 1847 1848static void 1849ahapoll(struct cam_sim *sim) 1850{ 1851 aha_intr(cam_sim_softc(sim)); 1852} 1853 1854static void 1855ahatimeout(void *arg) 1856{ 1857 struct aha_ccb *accb; 1858 union ccb *ccb; 1859 struct aha_softc *aha; 1860 int s; 1861 u_int32_t paddr; 1862 1863 accb = (struct aha_ccb *)arg; 1864 ccb = accb->ccb; 1865 aha = (struct aha_softc *)ccb->ccb_h.ccb_aha_ptr; 1866 xpt_print_path(ccb->ccb_h.path); 1867 printf("CCB %p - timed out\n", (void *)accb); 1868 1869 s = splcam(); 1870 1871 if ((accb->flags & ACCB_ACTIVE) == 0) { 1872 xpt_print_path(ccb->ccb_h.path); 1873 printf("CCB %p - timed out CCB already completed\n", 1874 (void *)accb); 1875 splx(s); 1876 return; 1877 } 1878 1879 /* 1880 * In order to simplify the recovery process, we ask the XPT 1881 * layer to halt the queue of new transactions and we traverse 1882 * the list of pending CCBs and remove their timeouts. This 1883 * means that the driver attempts to clear only one error 1884 * condition at a time. In general, timeouts that occur 1885 * close together are related anyway, so there is no benefit 1886 * in attempting to handle errors in parrallel. Timeouts will 1887 * be reinstated when the recovery process ends. 1888 */ 1889 if ((accb->flags & ACCB_DEVICE_RESET) == 0) { 1890 struct ccb_hdr *ccb_h; 1891 1892 if ((accb->flags & ACCB_RELEASE_SIMQ) == 0) { 1893 xpt_freeze_simq(aha->sim, /*count*/1); 1894 accb->flags |= ACCB_RELEASE_SIMQ; 1895 } 1896 1897 ccb_h = LIST_FIRST(&aha->pending_ccbs); 1898 while (ccb_h != NULL) { 1899 struct aha_ccb *pending_accb; 1900 1901 pending_accb = (struct aha_ccb *)ccb_h->ccb_accb_ptr; 1902 untimeout(ahatimeout, pending_accb, ccb_h->timeout_ch); 1903 ccb_h = LIST_NEXT(ccb_h, sim_links.le); 1904 } 1905 } 1906 1907 if ((accb->flags & ACCB_DEVICE_RESET) != 0 1908 || aha->cur_outbox->action_code != AMBO_FREE) { 1909 /* 1910 * Try a full host adapter/SCSI bus reset. 1911 * We do this only if we have already attempted 1912 * to clear the condition with a BDR, or we cannot 1913 * attempt a BDR for lack of mailbox resources. 1914 */ 1915 ccb->ccb_h.status = CAM_CMD_TIMEOUT; 1916 ahareset(aha, /*hardreset*/TRUE); 1917 printf("%s: No longer in timeout\n", aha_name(aha)); 1918 } else { 1919 /* 1920 * Send a Bus Device Reset message: 1921 * The target that is holding up the bus may not 1922 * be the same as the one that triggered this timeout 1923 * (different commands have different timeout lengths), 1924 * but we have no way of determining this from our 1925 * timeout handler. Our strategy here is to queue a 1926 * BDR message to the target of the timed out command. 1927 * If this fails, we'll get another timeout 2 seconds 1928 * later which will attempt a bus reset. 1929 */ 1930 accb->flags |= ACCB_DEVICE_RESET; 1931 ccb->ccb_h.timeout_ch = timeout(ahatimeout, (caddr_t)accb, 2 * hz); 1932 aha->recovery_accb->hccb.opcode = INITIATOR_BUS_DEV_RESET; 1933 1934 /* No Data Transfer */ 1935 aha->recovery_accb->hccb.datain = TRUE; 1936 aha->recovery_accb->hccb.dataout = TRUE; 1937 aha->recovery_accb->hccb.ahastat = 0; 1938 aha->recovery_accb->hccb.sdstat = 0; 1939 aha->recovery_accb->hccb.target = ccb->ccb_h.target_id; 1940 1941 /* Tell the adapter about this command */ 1942 paddr = ahaccbvtop(aha, aha->recovery_accb); 1943 ahautoa24(paddr, aha->cur_outbox->ccb_addr); 1944 aha->cur_outbox->action_code = AMBO_START; 1945 aha_outb(aha, COMMAND_REG, AOP_START_MBOX); 1946 ahanextoutbox(aha); 1947 } 1948 1949 splx(s); 1950} 1951 1952int 1953aha_detach(struct aha_softc *aha) 1954{ 1955 xpt_async(AC_LOST_DEVICE, aha->path, NULL); 1956 xpt_free_path(aha->path); 1957 xpt_bus_deregister(cam_sim_path(aha->sim)); 1958 cam_sim_free(aha->sim, /*free_devq*/TRUE); 1959 return (0); 1960} 1961