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