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