bt.c revision 39507
1/* 2 * Generic driver for the BusLogic MultiMaster SCSI host adapters 3 * Product specific probe and attach routines can be found in: 4 * i386/isa/bt_isa.c BT-54X, BT-445 cards 5 * i386/eisa/bt_eisa.c BT-74x, BT-75x cards 6 * pci/bt_pci.c BT-946, BT-948, BT-956, BT-958 cards 7 * 8 * Copyright (c) 1998 Justin T. Gibbs. 9 * All rights reserved. 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 * $Id: bt.c,v 1.3 1998/09/17 00:08:27 gibbs Exp $ 33 */ 34 35 /* 36 * Special thanks to Leonard N. Zubkoff for writing such a complete and 37 * well documented Mylex/BusLogic MultiMaster driver for Linux. Support 38 * in this driver for the wide range of MultiMaster controllers and 39 * firmware revisions, with their otherwise undocumented quirks, would not 40 * have been possible without his efforts. 41 */ 42 43#include <sys/param.h> 44#include <sys/systm.h> 45#include <sys/malloc.h> 46#include <sys/buf.h> 47#include <sys/kernel.h> 48#include <sys/sysctl.h> 49 50/* 51 * XXX It appears that BusLogic PCI adapters go out to lunch if you 52 * attempt to perform memory mapped I/O. 53 */ 54#if 0 55#include "pci.h" 56#if NPCI > 0 57#include <machine/bus_memio.h> 58#endif 59#endif 60#include <machine/bus_pio.h> 61#include <machine/bus.h> 62#include <machine/clock.h> 63 64#include <cam/cam.h> 65#include <cam/cam_ccb.h> 66#include <cam/cam_sim.h> 67#include <cam/cam_xpt_sim.h> 68#include <cam/cam_debug.h> 69 70#include <cam/scsi/scsi_message.h> 71 72#include <vm/vm.h> 73#include <vm/pmap.h> 74 75#include <dev/buslogic/btreg.h> 76 77struct bt_softc *bt_softcs[NBT]; 78 79/* MailBox Management functions */ 80static __inline void btnextinbox(struct bt_softc *bt); 81static __inline void btnextoutbox(struct bt_softc *bt); 82 83static __inline void 84btnextinbox(struct bt_softc *bt) 85{ 86 if (bt->cur_inbox == bt->last_inbox) 87 bt->cur_inbox = bt->in_boxes; 88 else 89 bt->cur_inbox++; 90} 91 92static __inline void 93btnextoutbox(struct bt_softc *bt) 94{ 95 if (bt->cur_outbox == bt->last_outbox) 96 bt->cur_outbox = bt->out_boxes; 97 else 98 bt->cur_outbox++; 99} 100 101/* CCB Mangement functions */ 102static __inline u_int32_t btccbvtop(struct bt_softc *bt, 103 struct bt_ccb *bccb); 104static __inline struct bt_ccb* btccbptov(struct bt_softc *bt, 105 u_int32_t ccb_addr); 106static __inline u_int32_t btsensepaddr(struct bt_softc *bt, 107 struct bt_ccb *bccb); 108static __inline struct scsi_sense_data* btsensevaddr(struct bt_softc *bt, 109 struct bt_ccb *bccb); 110 111static __inline u_int32_t 112btccbvtop(struct bt_softc *bt, struct bt_ccb *bccb) 113{ 114 return (bt->bt_ccb_physbase 115 + (u_int32_t)((caddr_t)bccb - (caddr_t)bt->bt_ccb_array)); 116} 117 118static __inline struct bt_ccb * 119btccbptov(struct bt_softc *bt, u_int32_t ccb_addr) 120{ 121 return (bt->bt_ccb_array + 122 ((struct bt_ccb*)ccb_addr-(struct bt_ccb*)bt->bt_ccb_physbase)); 123} 124 125static __inline u_int32_t 126btsensepaddr(struct bt_softc *bt, struct bt_ccb *bccb) 127{ 128 u_int index; 129 130 index = (u_int)(bccb - bt->bt_ccb_array); 131 return (bt->sense_buffers_physbase 132 + (index * sizeof(struct scsi_sense_data))); 133} 134 135static __inline struct scsi_sense_data * 136btsensevaddr(struct bt_softc *bt, struct bt_ccb *bccb) 137{ 138 u_int index; 139 140 index = (u_int)(bccb - bt->bt_ccb_array); 141 return (bt->sense_buffers + index); 142} 143 144static __inline struct bt_ccb* btgetccb(struct bt_softc *bt); 145static __inline void btfreeccb(struct bt_softc *bt, 146 struct bt_ccb *bccb); 147static void btallocccbs(struct bt_softc *bt); 148static bus_dmamap_callback_t btexecuteccb; 149static void btdone(struct bt_softc *bt, struct bt_ccb *bccb, 150 bt_mbi_comp_code_t comp_code); 151 152/* Host adapter command functions */ 153static int btreset(struct bt_softc* bt, int hard_reset); 154 155/* Initialization functions */ 156static int btinitmboxes(struct bt_softc *bt); 157static bus_dmamap_callback_t btmapmboxes; 158static bus_dmamap_callback_t btmapccbs; 159static bus_dmamap_callback_t btmapsgs; 160 161/* Transfer Negotiation Functions */ 162static void btfetchtransinfo(struct bt_softc *bt, 163 struct ccb_trans_settings *cts); 164 165/* CAM SIM entry points */ 166#define ccb_bccb_ptr spriv_ptr0 167#define ccb_bt_ptr spriv_ptr1 168static void btaction(struct cam_sim *sim, union ccb *ccb); 169static void btpoll(struct cam_sim *sim); 170 171/* Our timeout handler */ 172timeout_t bttimeout; 173 174u_long bt_unit = 0; 175 176/* 177 * XXX 178 * Do our own re-probe protection until a configuration 179 * manager can do it for us. This ensures that we don't 180 * reprobe a card already found by the EISA or PCI probes. 181 */ 182struct bt_isa_port bt_isa_ports[] = 183{ 184 { 0x330, 0 }, 185 { 0x334, 0 }, 186 { 0x230, 0 }, 187 { 0x234, 0 }, 188 { 0x130, 0 }, 189 { 0x134, 0 } 190}; 191 192/* Exported functions */ 193struct bt_softc * 194bt_alloc(int unit, bus_space_tag_t tag, bus_space_handle_t bsh) 195{ 196 struct bt_softc *bt; 197 int i; 198 199 if (unit != BT_TEMP_UNIT) { 200 if (unit >= NBT) { 201 printf("bt: unit number (%d) too high\n", unit); 202 return NULL; 203 } 204 205 /* 206 * Allocate a storage area for us 207 */ 208 if (bt_softcs[unit]) { 209 printf("bt%d: memory already allocated\n", unit); 210 return NULL; 211 } 212 } 213 214 bt = malloc(sizeof(struct bt_softc), M_DEVBUF, M_NOWAIT); 215 if (!bt) { 216 printf("bt%d: cannot malloc!\n", unit); 217 return NULL; 218 } 219 bzero(bt, sizeof(struct bt_softc)); 220 SLIST_INIT(&bt->free_bt_ccbs); 221 LIST_INIT(&bt->pending_ccbs); 222 SLIST_INIT(&bt->sg_maps); 223 bt->unit = unit; 224 bt->tag = tag; 225 bt->bsh = bsh; 226 227 if (bt->unit != BT_TEMP_UNIT) { 228 bt_softcs[unit] = bt; 229 } 230 return (bt); 231} 232 233void 234bt_free(struct bt_softc *bt) 235{ 236 switch (bt->init_level) { 237 default: 238 case 11: 239 bus_dmamap_unload(bt->sense_dmat, bt->sense_dmamap); 240 case 10: 241 bus_dmamem_free(bt->sense_dmat, bt->sense_buffers, 242 bt->sense_dmamap); 243 case 9: 244 bus_dma_tag_destroy(bt->sense_dmat); 245 case 8: 246 { 247 struct sg_map_node *sg_map; 248 249 while ((sg_map = SLIST_FIRST(&bt->sg_maps))!= NULL) { 250 SLIST_REMOVE_HEAD(&bt->sg_maps, links); 251 bus_dmamap_unload(bt->sg_dmat, 252 sg_map->sg_dmamap); 253 bus_dmamem_free(bt->sg_dmat, sg_map->sg_vaddr, 254 sg_map->sg_dmamap); 255 free(sg_map, M_DEVBUF); 256 } 257 bus_dma_tag_destroy(bt->sg_dmat); 258 } 259 case 7: 260 bus_dmamap_unload(bt->ccb_dmat, bt->ccb_dmamap); 261 case 6: 262 bus_dmamem_free(bt->ccb_dmat, bt->bt_ccb_array, 263 bt->ccb_dmamap); 264 bus_dmamap_destroy(bt->ccb_dmat, bt->ccb_dmamap); 265 case 5: 266 bus_dma_tag_destroy(bt->ccb_dmat); 267 case 4: 268 bus_dmamap_unload(bt->mailbox_dmat, bt->mailbox_dmamap); 269 case 3: 270 bus_dmamem_free(bt->mailbox_dmat, bt->in_boxes, 271 bt->mailbox_dmamap); 272 bus_dmamap_destroy(bt->mailbox_dmat, bt->mailbox_dmamap); 273 case 2: 274 bus_dma_tag_destroy(bt->buffer_dmat); 275 case 1: 276 bus_dma_tag_destroy(bt->mailbox_dmat); 277 case 0: 278 break; 279 } 280 if (bt->unit != BT_TEMP_UNIT) { 281 bt_softcs[bt->unit] = NULL; 282 } 283 free(bt, M_DEVBUF); 284} 285 286/* 287 * Probe the adapter and verify that the card is a BusLogic. 288 */ 289int 290bt_probe(struct bt_softc* bt) 291{ 292 esetup_info_data_t esetup_info; 293 u_int status; 294 u_int intstat; 295 u_int geometry; 296 int error; 297 u_int8_t param; 298 299 /* 300 * See if the three I/O ports look reasonable. 301 * Touch the minimal number of registers in the 302 * failure case. 303 */ 304 status = bt_inb(bt, STATUS_REG); 305 if ((status == 0) 306 || (status & (DIAG_ACTIVE|CMD_REG_BUSY| 307 STATUS_REG_RSVD|CMD_INVALID)) != 0) { 308 if (bootverbose) 309 printf("%s: Failed Status Reg Test - %x\n", bt_name(bt), 310 status); 311 return (ENXIO); 312 } 313 314 intstat = bt_inb(bt, INTSTAT_REG); 315 if ((intstat & INTSTAT_REG_RSVD) != 0) { 316 printf("%s: Failed Intstat Reg Test\n", bt_name(bt)); 317 return (ENXIO); 318 } 319 320 geometry = bt_inb(bt, GEOMETRY_REG); 321 if (geometry == 0xFF) { 322 if (bootverbose) 323 printf("%s: Failed Geometry Reg Test\n", bt_name(bt)); 324 return (ENXIO); 325 } 326 327 /* 328 * Looking good so far. Final test is to reset the 329 * adapter and attempt to fetch the extended setup 330 * information. This should filter out all 1542 cards. 331 */ 332 if ((error = btreset(bt, /*hard_reset*/TRUE)) != 0) { 333 if (bootverbose) 334 printf("%s: Failed Reset\n", bt_name(bt)); 335 return (ENXIO); 336 } 337 338 param = sizeof(esetup_info); 339 error = bt_cmd(bt, BOP_INQUIRE_ESETUP_INFO, ¶m, /*parmlen*/1, 340 (u_int8_t*)&esetup_info, sizeof(esetup_info), 341 DEFAULT_CMD_TIMEOUT); 342 if (error != 0) { 343 return (ENXIO); 344 } 345 346 return (0); 347} 348 349/* 350 * Pull the boards setup information and record it in our softc. 351 */ 352int 353bt_fetch_adapter_info(struct bt_softc *bt) 354{ 355 board_id_data_t board_id; 356 esetup_info_data_t esetup_info; 357 config_data_t config_data; 358 int error; 359 u_int8_t length_param; 360 361 /* First record the firmware version */ 362 error = bt_cmd(bt, BOP_INQUIRE_BOARD_ID, NULL, /*parmlen*/0, 363 (u_int8_t*)&board_id, sizeof(board_id), 364 DEFAULT_CMD_TIMEOUT); 365 if (error != 0) { 366 printf("%s: bt_fetch_adapter_info - Failed Get Board Info\n", 367 bt_name(bt)); 368 return (error); 369 } 370 bt->firmware_ver[0] = board_id.firmware_rev_major; 371 bt->firmware_ver[1] = '.'; 372 bt->firmware_ver[2] = board_id.firmware_rev_minor; 373 bt->firmware_ver[3] = '\0'; 374 375 /* 376 * Depending on the firmware major and minor version, 377 * we may be able to fetch additional minor version info. 378 */ 379 if (bt->firmware_ver[0] > '0') { 380 381 error = bt_cmd(bt, BOP_INQUIRE_FW_VER_3DIG, NULL, /*parmlen*/0, 382 (u_int8_t*)&bt->firmware_ver[3], 1, 383 DEFAULT_CMD_TIMEOUT); 384 if (error != 0) { 385 printf("%s: bt_fetch_adapter_info - Failed Get " 386 "Firmware 3rd Digit\n", bt_name(bt)); 387 return (error); 388 } 389 if (bt->firmware_ver[3] == ' ') 390 bt->firmware_ver[3] = '\0'; 391 bt->firmware_ver[4] = '\0'; 392 } 393 394 if (strcmp(bt->firmware_ver, "3.3") >= 0) { 395 396 error = bt_cmd(bt, BOP_INQUIRE_FW_VER_4DIG, NULL, /*parmlen*/0, 397 (u_int8_t*)&bt->firmware_ver[4], 1, 398 DEFAULT_CMD_TIMEOUT); 399 if (error != 0) { 400 printf("%s: bt_fetch_adapter_info - Failed Get " 401 "Firmware 4th Digit\n", bt_name(bt)); 402 return (error); 403 } 404 if (bt->firmware_ver[4] == ' ') 405 bt->firmware_ver[4] = '\0'; 406 bt->firmware_ver[5] = '\0'; 407 } 408 409 /* 410 * Some boards do not handle the "recently documented" 411 * Inquire Board Model Number command correctly or do not give 412 * exact information. Use the Firmware and Extended Setup 413 * information in these cases to come up with the right answer. 414 * The major firmware revision number indicates: 415 * 416 * 5.xx BusLogic "W" Series Host Adapters: 417 * BT-948/958/958D 418 * 4.xx BusLogic "C" Series Host Adapters: 419 * BT-946C/956C/956CD/747C/757C/757CD/445C/545C/540CF 420 * 3.xx BusLogic "S" Series Host Adapters: 421 * BT-747S/747D/757S/757D/445S/545S/542D 422 * BT-542B/742A (revision H) 423 * 2.xx BusLogic "A" Series Host Adapters: 424 * BT-542B/742A (revision G and below) 425 * 0.xx AMI FastDisk VLB/EISA BusLogic Clone Host Adapter 426 */ 427 length_param = sizeof(esetup_info); 428 error = bt_cmd(bt, BOP_INQUIRE_ESETUP_INFO, &length_param, /*parmlen*/1, 429 (u_int8_t*)&esetup_info, sizeof(esetup_info), 430 DEFAULT_CMD_TIMEOUT); 431 if (error != 0) { 432 return (error); 433 } 434 435 bt->bios_addr = esetup_info.bios_addr << 12; 436 437 if (esetup_info.bus_type == 'A' 438 && bt->firmware_ver[0] == '2') { 439 strcpy(bt->model, "542B"); 440 } else if (esetup_info.bus_type == 'E' 441 && (strncmp(bt->firmware_ver, "2.1", 3) == 0 442 || strncmp(bt->firmware_ver, "2.20", 4) == 0)) { 443 strcpy(bt->model, "742A"); 444 } else if (esetup_info.bus_type == 'E' 445 && bt->firmware_ver[0] == '0') { 446 /* AMI FastDisk EISA Series 441 0.x */ 447 strcpy(bt->model, "747A"); 448 } else { 449 ha_model_data_t model_data; 450 int i; 451 452 length_param = sizeof(model_data); 453 error = bt_cmd(bt, BOP_INQUIRE_MODEL, &length_param, 1, 454 (u_int8_t*)&model_data, sizeof(model_data), 455 DEFAULT_CMD_TIMEOUT); 456 if (error != 0) { 457 printf("%s: bt_fetch_adapter_info - Failed Inquire " 458 "Model Number\n", bt_name(bt)); 459 return (error); 460 } 461 for (i = 0; i < sizeof(model_data.ascii_model); i++) { 462 bt->model[i] = model_data.ascii_model[i]; 463 if (bt->model[i] == ' ') 464 break; 465 } 466 bt->model[i] = '\0'; 467 } 468 469 /* SG element limits */ 470 bt->max_sg = esetup_info.max_sg; 471 472 /* Set feature flags */ 473 bt->wide_bus = esetup_info.wide_bus; 474 bt->diff_bus = esetup_info.diff_bus; 475 bt->ultra_scsi = esetup_info.ultra_scsi; 476 477 if ((bt->firmware_ver[0] == '5') 478 || (bt->firmware_ver[0] == '4' && bt->wide_bus)) 479 bt->extended_lun = TRUE; 480 481 bt->strict_rr = (strcmp(bt->firmware_ver, "3.31") >= 0); 482 483 bt->extended_trans = 484 ((bt_inb(bt, GEOMETRY_REG) & EXTENDED_TRANSLATION) != 0); 485 486 /* 487 * Determine max CCB count and whether tagged queuing is 488 * available based on controller type. Tagged queuing 489 * only works on 'W' series adapters, 'C' series adapters 490 * with firmware of rev 4.42 and higher, and 'S' series 491 * adapters with firmware of rev 3.35 and higher. The 492 * maximum CCB counts are as follows: 493 * 494 * 192 BT-948/958/958D 495 * 100 BT-946C/956C/956CD/747C/757C/757CD/445C 496 * 50 BT-545C/540CF 497 * 30 BT-747S/747D/757S/757D/445S/545S/542D/542B/742A 498 */ 499 if (bt->firmware_ver[0] == '5') { 500 bt->max_ccbs = 192; 501 bt->tag_capable = TRUE; 502 } else if (bt->firmware_ver[0] == '4') { 503 if (bt->model[0] == '5') 504 bt->max_ccbs = 50; 505 else 506 bt->max_ccbs = 100; 507 bt->tag_capable = (strcmp(bt->firmware_ver, "4.22") >= 0); 508 } else { 509 bt->max_ccbs = 30; 510 if (bt->firmware_ver[0] == '3' 511 && (strcmp(bt->firmware_ver, "3.35") >= 0)) 512 bt->tag_capable = TRUE; 513 else 514 bt->tag_capable = FALSE; 515 } 516 517 if (bt->tag_capable != FALSE) 518 bt->tags_permitted = ALL_TARGETS; 519 520 /* Determine Sync/Wide/Disc settings */ 521 if (bt->firmware_ver[0] >= '4') { 522 auto_scsi_data_t auto_scsi_data; 523 fetch_lram_params_t fetch_lram_params; 524 int error; 525 526 /* 527 * These settings are stored in the 528 * AutoSCSI data in LRAM of 'W' and 'C' 529 * adapters. 530 */ 531 fetch_lram_params.offset = AUTO_SCSI_BYTE_OFFSET; 532 fetch_lram_params.response_len = sizeof(auto_scsi_data); 533 error = bt_cmd(bt, BOP_FETCH_LRAM, 534 (u_int8_t*)&fetch_lram_params, 535 sizeof(fetch_lram_params), 536 (u_int8_t*)&auto_scsi_data, 537 sizeof(auto_scsi_data), DEFAULT_CMD_TIMEOUT); 538 539 if (error != 0) { 540 printf("%s: bt_fetch_adapter_info - Failed " 541 "Get Auto SCSI Info\n", bt_name(bt)); 542 return (error); 543 } 544 545 bt->disc_permitted = auto_scsi_data.low_disc_permitted 546 | (auto_scsi_data.high_disc_permitted << 8); 547 bt->sync_permitted = auto_scsi_data.low_sync_permitted 548 | (auto_scsi_data.high_sync_permitted << 8); 549 bt->fast_permitted = auto_scsi_data.low_fast_permitted 550 | (auto_scsi_data.high_fast_permitted << 8); 551 bt->ultra_permitted = auto_scsi_data.low_ultra_permitted 552 | (auto_scsi_data.high_ultra_permitted << 8); 553 bt->wide_permitted = auto_scsi_data.low_wide_permitted 554 | (auto_scsi_data.high_wide_permitted << 8); 555 556 if (bt->ultra_scsi == FALSE) 557 bt->ultra_permitted = 0; 558 559 if (bt->wide_bus == FALSE) 560 bt->wide_permitted = 0; 561 } else { 562 /* 563 * 'S' and 'A' series have this information in the setup 564 * information structure. 565 */ 566 setup_data_t setup_info; 567 568 length_param = sizeof(setup_info); 569 error = bt_cmd(bt, BOP_INQUIRE_SETUP_INFO, &length_param, 570 /*paramlen*/1, (u_int8_t*)&setup_info, 571 sizeof(setup_info), DEFAULT_CMD_TIMEOUT); 572 573 if (error != 0) { 574 printf("%s: bt_fetch_adapter_info - Failed " 575 "Get Setup Info\n", bt_name(bt)); 576 return (error); 577 } 578 579 if (setup_info.initiate_sync != 0) { 580 bt->sync_permitted = ALL_TARGETS; 581 582 if (bt->model[0] == '7') { 583 if (esetup_info.sync_neg10MB != 0) 584 bt->fast_permitted = ALL_TARGETS; 585 if (strcmp(bt->model, "757") == 0) 586 bt->wide_permitted = ALL_TARGETS; 587 } 588 } 589 bt->disc_permitted = ALL_TARGETS; 590 } 591 592 /* We need as many mailboxes as we can have ccbs */ 593 bt->num_boxes = bt->max_ccbs; 594 595 /* Determine our SCSI ID */ 596 597 error = bt_cmd(bt, BOP_INQUIRE_CONFIG, NULL, /*parmlen*/0, 598 (u_int8_t*)&config_data, sizeof(config_data), 599 DEFAULT_CMD_TIMEOUT); 600 if (error != 0) { 601 printf("%s: bt_fetch_adapter_info - Failed Get Config\n", 602 bt_name(bt)); 603 return (error); 604 } 605 bt->scsi_id = config_data.scsi_id; 606 607 return (0); 608} 609 610/* 611 * Start the board, ready for normal operation 612 */ 613int 614bt_init(struct bt_softc* bt) 615{ 616 /* Announce the Adapter */ 617 printf("%s: BT-%s FW Rev. %s ", bt_name(bt), 618 bt->model, bt->firmware_ver); 619 620 if (bt->ultra_scsi != 0) 621 printf("Ultra "); 622 623 if (bt->wide_bus != 0) 624 printf("Wide "); 625 else 626 printf("Narrow "); 627 628 if (bt->diff_bus != 0) 629 printf("Diff "); 630 631 printf("SCSI Host Adapter, SCSI ID %d, %d CCBs\n", bt->scsi_id, 632 bt->max_ccbs); 633 634 /* 635 * Create our DMA tags. These tags define the kinds of device 636 * accessable memory allocations and memory mappings we will 637 * need to perform during normal operation. 638 * 639 * Unless we need to further restrict the allocation, we rely 640 * on the restrictions of the parent dmat, hence the common 641 * use of MAXADDR and MAXSIZE. 642 */ 643 644 /* DMA tag for mapping buffers into device visible space. */ 645 if (bus_dma_tag_create(bt->parent_dmat, /*alignment*/0, /*boundary*/0, 646 /*lowaddr*/BUS_SPACE_MAXADDR, 647 /*highaddr*/BUS_SPACE_MAXADDR, 648 /*filter*/NULL, /*filterarg*/NULL, 649 /*maxsize*/MAXBSIZE, /*nsegments*/BT_NSEG, 650 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, 651 /*flags*/BUS_DMA_ALLOCNOW, 652 &bt->buffer_dmat) != 0) { 653 goto error_exit; 654 } 655 656 bt->init_level++; 657 /* DMA tag for our mailboxes */ 658 if (bus_dma_tag_create(bt->parent_dmat, /*alignment*/0, /*boundary*/0, 659 /*lowaddr*/BUS_SPACE_MAXADDR, 660 /*highaddr*/BUS_SPACE_MAXADDR, 661 /*filter*/NULL, /*filterarg*/NULL, 662 bt->num_boxes * (sizeof(bt_mbox_in_t) 663 + sizeof(bt_mbox_out_t)), 664 /*nsegments*/1, 665 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, 666 /*flags*/0, &bt->mailbox_dmat) != 0) { 667 goto error_exit; 668 } 669 670 bt->init_level++; 671 672 /* Allocation for our mailboxes */ 673 if (bus_dmamem_alloc(bt->mailbox_dmat, (void **)&bt->out_boxes, 674 BUS_DMA_NOWAIT, &bt->mailbox_dmamap) != 0) { 675 goto error_exit; 676 } 677 678 bt->init_level++; 679 680 /* And permanently map them */ 681 bus_dmamap_load(bt->mailbox_dmat, bt->mailbox_dmamap, 682 bt->out_boxes, 683 bt->num_boxes * (sizeof(bt_mbox_in_t) 684 + sizeof(bt_mbox_out_t)), 685 btmapmboxes, bt, /*flags*/0); 686 687 bt->init_level++; 688 689 bt->in_boxes = (bt_mbox_in_t *)&bt->out_boxes[bt->num_boxes]; 690 691 btinitmboxes(bt); 692 693 /* DMA tag for our ccb structures */ 694 if (bus_dma_tag_create(bt->parent_dmat, /*alignment*/0, /*boundary*/0, 695 /*lowaddr*/BUS_SPACE_MAXADDR, 696 /*highaddr*/BUS_SPACE_MAXADDR, 697 /*filter*/NULL, /*filterarg*/NULL, 698 bt->max_ccbs * sizeof(struct bt_ccb), 699 /*nsegments*/1, 700 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, 701 /*flags*/0, &bt->ccb_dmat) != 0) { 702 goto error_exit; 703 } 704 705 bt->init_level++; 706 707 /* Allocation for our ccbs */ 708 if (bus_dmamem_alloc(bt->ccb_dmat, (void **)&bt->bt_ccb_array, 709 BUS_DMA_NOWAIT, &bt->ccb_dmamap) != 0) { 710 goto error_exit; 711 } 712 713 bt->init_level++; 714 715 /* And permanently map them */ 716 bus_dmamap_load(bt->ccb_dmat, bt->ccb_dmamap, 717 bt->bt_ccb_array, 718 bt->max_ccbs * sizeof(struct bt_ccb), 719 btmapccbs, bt, /*flags*/0); 720 721 bt->init_level++; 722 723 /* DMA tag for our S/G structures. We allocate in page sized chunks */ 724 if (bus_dma_tag_create(bt->parent_dmat, /*alignment*/0, /*boundary*/0, 725 /*lowaddr*/BUS_SPACE_MAXADDR, 726 /*highaddr*/BUS_SPACE_MAXADDR, 727 /*filter*/NULL, /*filterarg*/NULL, 728 PAGE_SIZE, /*nsegments*/1, 729 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, 730 /*flags*/0, &bt->sg_dmat) != 0) { 731 goto error_exit; 732 } 733 734 bt->init_level++; 735 736 /* Perform initial CCB allocation */ 737 bzero(bt->bt_ccb_array, bt->max_ccbs * sizeof(struct bt_ccb)); 738 btallocccbs(bt); 739 740 if (bt->num_ccbs == 0) { 741 printf("%s: bt_init - Unable to allocate initial ccbs\n", 742 bt_name(bt)); 743 goto error_exit; 744 } 745 746 /* 747 * Note that we are going and return (to probe) 748 */ 749 return 0; 750 751error_exit: 752 753 return (ENXIO); 754} 755 756int 757bt_attach(struct bt_softc *bt) 758{ 759 int tagged_dev_openings; 760 struct cam_devq *devq; 761 762 /* 763 * We reserve 1 ccb for error recovery, so don't 764 * tell the XPT about it. 765 */ 766 if (bt->tag_capable != 0) 767 tagged_dev_openings = bt->max_ccbs - 1; 768 else 769 tagged_dev_openings = 0; 770 771 /* 772 * Create the device queue for our SIM. 773 */ 774 devq = cam_simq_alloc(bt->max_ccbs - 1); 775 if (devq == NULL) 776 return (ENOMEM); 777 778 /* 779 * Construct our SIM entry 780 */ 781 bt->sim = cam_sim_alloc(btaction, btpoll, "bt", bt, bt->unit, 782 2, tagged_dev_openings, devq); 783 if (bt->sim == NULL) { 784 cam_simq_free(devq); 785 return (ENOMEM); 786 } 787 788 if (xpt_bus_register(bt->sim, 0) != CAM_SUCCESS) { 789 cam_sim_free(bt->sim, /*free_devq*/TRUE); 790 return (ENXIO); 791 } 792 793 if (xpt_create_path(&bt->path, /*periph*/NULL, 794 cam_sim_path(bt->sim), CAM_TARGET_WILDCARD, 795 CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 796 xpt_bus_deregister(cam_sim_path(bt->sim)); 797 cam_sim_free(bt->sim, /*free_devq*/TRUE); 798 return (ENXIO); 799 } 800 801 return (0); 802} 803 804char * 805bt_name(struct bt_softc *bt) 806{ 807 static char name[10]; 808 809 sprintf(name, "bt%d", bt->unit); 810 return (name); 811} 812 813int 814bt_check_probed_iop(u_int ioport) 815{ 816 u_int i; 817 818 for (i=0; i < BT_NUM_ISAPORTS; i++) { 819 if (bt_isa_ports[i].addr == ioport) { 820 if (bt_isa_ports[i].probed != 0) 821 return (1); 822 else { 823 return (0); 824 } 825 } 826 } 827 return (1); 828} 829 830void 831bt_mark_probed_bio(isa_compat_io_t port) 832{ 833 if (port < BIO_DISABLED) 834 bt_isa_ports[port].probed = 1; 835} 836 837void 838bt_mark_probed_iop(u_int ioport) 839{ 840 u_int i; 841 842 for (i = 0; i < BT_NUM_ISAPORTS; i++) { 843 if (ioport == bt_isa_ports[i].addr) { 844 bt_isa_ports[i].probed = 1; 845 break; 846 } 847 } 848} 849 850static void 851btallocccbs(struct bt_softc *bt) 852{ 853 struct bt_ccb *next_ccb; 854 struct sg_map_node *sg_map; 855 bus_addr_t physaddr; 856 bt_sg_t *segs; 857 int newcount; 858 int i; 859 860 next_ccb = &bt->bt_ccb_array[bt->num_ccbs]; 861 862 sg_map = malloc(sizeof(*sg_map), M_DEVBUF, M_NOWAIT); 863 864 if (sg_map == NULL) 865 return; 866 867 /* Allocate S/G space for the next batch of CCBS */ 868 if (bus_dmamem_alloc(bt->sg_dmat, (void **)&sg_map->sg_vaddr, 869 BUS_DMA_NOWAIT, &sg_map->sg_dmamap) != 0) { 870 free(sg_map, M_DEVBUF); 871 return; 872 } 873 874 SLIST_INSERT_HEAD(&bt->sg_maps, sg_map, links); 875 876 bus_dmamap_load(bt->sg_dmat, sg_map->sg_dmamap, sg_map->sg_vaddr, 877 PAGE_SIZE, btmapsgs, bt, /*flags*/0); 878 879 segs = sg_map->sg_vaddr; 880 physaddr = sg_map->sg_physaddr; 881 882 newcount = (PAGE_SIZE / (BT_NSEG * sizeof(bt_sg_t))); 883 for (i = 0; bt->num_ccbs < bt->max_ccbs && i < newcount; i++) { 884 int error; 885 886 next_ccb->sg_list = segs; 887 next_ccb->sg_list_phys = physaddr; 888 next_ccb->flags = BCCB_FREE; 889 error = bus_dmamap_create(bt->buffer_dmat, /*flags*/0, 890 &next_ccb->dmamap); 891 if (error != 0) 892 break; 893 SLIST_INSERT_HEAD(&bt->free_bt_ccbs, next_ccb, links); 894 segs += BT_NSEG; 895 physaddr += (BT_NSEG * sizeof(bt_sg_t)); 896 next_ccb++; 897 bt->num_ccbs++; 898 } 899 900 /* Reserve a CCB for error recovery */ 901 if (bt->recovery_bccb == NULL) { 902 bt->recovery_bccb = SLIST_FIRST(&bt->free_bt_ccbs); 903 SLIST_REMOVE_HEAD(&bt->free_bt_ccbs, links); 904 } 905} 906 907static __inline void 908btfreeccb(struct bt_softc *bt, struct bt_ccb *bccb) 909{ 910 int s; 911 912 s = splcam(); 913 if ((bccb->flags & BCCB_ACTIVE) != 0) 914 LIST_REMOVE(&bccb->ccb->ccb_h, sim_links.le); 915 if (bt->resource_shortage != 0 916 && (bccb->ccb->ccb_h.status & CAM_RELEASE_SIMQ) == 0) { 917 bccb->ccb->ccb_h.status |= CAM_RELEASE_SIMQ; 918 bt->resource_shortage = FALSE; 919 } 920 bccb->flags = BCCB_FREE; 921 SLIST_INSERT_HEAD(&bt->free_bt_ccbs, bccb, links); 922 splx(s); 923} 924 925static __inline struct bt_ccb* 926btgetccb(struct bt_softc *bt) 927{ 928 struct bt_ccb* bccb; 929 int s; 930 931 s = splcam(); 932 if ((bccb = SLIST_FIRST(&bt->free_bt_ccbs)) != NULL) { 933 SLIST_REMOVE_HEAD(&bt->free_bt_ccbs, links); 934 } else if (bt->num_ccbs < bt->max_ccbs) { 935 btallocccbs(bt); 936 bccb = SLIST_FIRST(&bt->free_bt_ccbs); 937 if (bccb == NULL) 938 printf("%s: Can't malloc BCCB\n", bt_name(bt)); 939 else 940 SLIST_REMOVE_HEAD(&bt->free_bt_ccbs, links); 941 } 942 splx(s); 943 944 return (bccb); 945} 946 947static void 948btaction(struct cam_sim *sim, union ccb *ccb) 949{ 950 struct bt_softc *bt; 951 int s; 952 953 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("btaction\n")); 954 955 bt = (struct bt_softc *)cam_sim_softc(sim); 956 957 switch (ccb->ccb_h.func_code) { 958 /* Common cases first */ 959 case XPT_SCSI_IO: /* Execute the requested I/O operation */ 960 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */ 961 { 962 struct bt_ccb *bccb; 963 struct bt_hccb *hccb; 964 u_int16_t targ_mask; 965 966 /* 967 * get a bccb to use. 968 */ 969 if ((bccb = btgetccb(bt)) == NULL) { 970 int s; 971 972 s = splcam(); 973 bt->resource_shortage = TRUE; 974 splx(s); 975 xpt_freeze_simq(bt->sim, /*count*/1); 976 ccb->ccb_h.status = CAM_REQUEUE_REQ; 977 xpt_done(ccb); 978 return; 979 } 980 981 hccb = &bccb->hccb; 982 983 /* 984 * So we can find the BCCB when an abort is requested 985 */ 986 bccb->ccb = ccb; 987 ccb->ccb_h.ccb_bccb_ptr = bccb; 988 ccb->ccb_h.ccb_bt_ptr = bt; 989 990 /* 991 * Put all the arguments for the xfer in the bccb 992 */ 993 hccb->target_id = ccb->ccb_h.target_id; 994 hccb->target_lun = ccb->ccb_h.target_lun; 995 hccb->btstat = 0; 996 hccb->sdstat = 0; 997 targ_mask = (0x01 << hccb->target_id); 998 999 if (ccb->ccb_h.func_code == XPT_SCSI_IO) { 1000 struct ccb_scsiio *csio; 1001 struct ccb_hdr *ccbh; 1002 1003 csio = &ccb->csio; 1004 ccbh = &csio->ccb_h; 1005 hccb->opcode = INITIATOR_CCB_WRESID; 1006 hccb->datain = (ccb->ccb_h.flags & CAM_DIR_IN) != 0; 1007 hccb->dataout = (ccb->ccb_h.flags & CAM_DIR_OUT) != 0; 1008 hccb->cmd_len = csio->cdb_len; 1009 if (hccb->cmd_len > sizeof(hccb->scsi_cdb)) { 1010 ccb->ccb_h.status = CAM_REQ_INVALID; 1011 btfreeccb(bt, bccb); 1012 xpt_done(ccb); 1013 return; 1014 } 1015 hccb->sense_len = csio->sense_len; 1016 if ((ccbh->flags & CAM_TAG_ACTION_VALID) != 0) { 1017 hccb->tag_enable = TRUE; 1018 hccb->tag_type = (ccb->csio.tag_action & 0x3); 1019 } else { 1020 hccb->tag_enable = FALSE; 1021 hccb->tag_type = 0; 1022 } 1023 if ((ccbh->flags & CAM_CDB_POINTER) != 0) { 1024 if ((ccbh->flags & CAM_CDB_PHYS) == 0) { 1025 bcopy(csio->cdb_io.cdb_ptr, 1026 hccb->scsi_cdb, hccb->cmd_len); 1027 } else { 1028 /* I guess I could map it in... */ 1029 ccbh->status = CAM_REQ_INVALID; 1030 btfreeccb(bt, bccb); 1031 xpt_done(ccb); 1032 return; 1033 } 1034 } else { 1035 bcopy(csio->cdb_io.cdb_bytes, 1036 hccb->scsi_cdb, hccb->cmd_len); 1037 } 1038 /* If need be, bounce our sense buffer */ 1039 if (bt->sense_buffers != NULL) { 1040 hccb->sense_addr = btsensepaddr(bt, bccb); 1041 } else { 1042 hccb->sense_addr = vtophys(&csio->sense_data); 1043 } 1044 /* 1045 * If we have any data to send with this command, 1046 * map it into bus space. 1047 */ 1048 /* Only use S/G if there is a transfer */ 1049 if ((ccbh->flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 1050 if ((ccbh->flags & CAM_SCATTER_VALID) == 0) { 1051 /* 1052 * We've been given a pointer 1053 * to a single buffer. 1054 */ 1055 if ((ccbh->flags & CAM_DATA_PHYS)==0) { 1056 int s; 1057 int error; 1058 1059 s = splsoftvm(); 1060 error = bus_dmamap_load( 1061 bt->buffer_dmat, 1062 bccb->dmamap, 1063 csio->data_ptr, 1064 csio->dxfer_len, 1065 btexecuteccb, 1066 bccb, 1067 /*flags*/0); 1068 if (error == EINPROGRESS) { 1069 /* 1070 * So as to maintain 1071 * ordering, freeze the 1072 * controller queue 1073 * until our mapping is 1074 * returned. 1075 */ 1076 xpt_freeze_simq(bt->sim, 1077 1); 1078 csio->ccb_h.status |= 1079 CAM_RELEASE_SIMQ; 1080 } 1081 splx(s); 1082 } else { 1083 struct bus_dma_segment seg; 1084 1085 /* Pointer to physical buffer */ 1086 seg.ds_addr = 1087 (bus_addr_t)csio->data_ptr; 1088 seg.ds_len = csio->dxfer_len; 1089 btexecuteccb(bccb, &seg, 1, 0); 1090 } 1091 } else { 1092 struct bus_dma_segment *segs; 1093 1094 if ((ccbh->flags & CAM_DATA_PHYS) != 0) 1095 panic("btaction - Physical " 1096 "segment pointers " 1097 "unsupported"); 1098 1099 if ((ccbh->flags&CAM_SG_LIST_PHYS)==0) 1100 panic("btaction - Virtual " 1101 "segment addresses " 1102 "unsupported"); 1103 1104 /* Just use the segments provided */ 1105 segs = (struct bus_dma_segment *) 1106 csio->data_ptr; 1107 btexecuteccb(bccb, segs, 1108 csio->sglist_cnt, 0); 1109 } 1110 } else { 1111 btexecuteccb(bccb, NULL, 0, 0); 1112 } 1113 } else { 1114 hccb->opcode = INITIATOR_BUS_DEV_RESET; 1115 /* No data transfer */ 1116 hccb->datain = TRUE; 1117 hccb->dataout = TRUE; 1118 hccb->cmd_len = 0; 1119 hccb->sense_len = 0; 1120 hccb->tag_enable = FALSE; 1121 hccb->tag_type = 0; 1122 btexecuteccb(bccb, NULL, 0, 0); 1123 } 1124 break; 1125 } 1126 case XPT_EN_LUN: /* Enable LUN as a target */ 1127 case XPT_TARGET_IO: /* Execute target I/O request */ 1128 case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */ 1129 case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/ 1130 case XPT_ABORT: /* Abort the specified CCB */ 1131 /* XXX Implement */ 1132 ccb->ccb_h.status = CAM_REQ_INVALID; 1133 xpt_done(ccb); 1134 break; 1135 case XPT_SET_TRAN_SETTINGS: 1136 { 1137 /* XXX Implement */ 1138 ccb->ccb_h.status = CAM_REQ_CMP; 1139 xpt_done(ccb); 1140 break; 1141 } 1142 case XPT_GET_TRAN_SETTINGS: 1143 /* Get default/user set transfer settings for the target */ 1144 { 1145 struct ccb_trans_settings *cts; 1146 u_int target_mask; 1147 1148 cts = &ccb->cts; 1149 target_mask = 0x01 << ccb->ccb_h.target_id; 1150 if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) { 1151 cts->flags = 0; 1152 if ((bt->disc_permitted & target_mask) != 0) 1153 cts->flags |= CCB_TRANS_DISC_ENB; 1154 if ((bt->tags_permitted & target_mask) != 0) 1155 cts->flags |= CCB_TRANS_TAG_ENB; 1156 if ((bt->wide_permitted & target_mask) != 0) 1157 cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT; 1158 else 1159 cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT; 1160 if ((bt->ultra_permitted & target_mask) != 0) 1161 cts->sync_period = 12; 1162 else if ((bt->fast_permitted & target_mask) != 0) 1163 cts->sync_period = 25; 1164 else if ((bt->sync_permitted & target_mask) != 0) 1165 cts->sync_period = 50; 1166 else 1167 cts->sync_period = 0; 1168 1169 if (cts->sync_period != 0) 1170 cts->sync_offset = 15; 1171 1172 cts->valid = CCB_TRANS_SYNC_RATE_VALID 1173 | CCB_TRANS_SYNC_OFFSET_VALID 1174 | CCB_TRANS_BUS_WIDTH_VALID 1175 | CCB_TRANS_DISC_VALID 1176 | CCB_TRANS_TQ_VALID; 1177 } else { 1178 btfetchtransinfo(bt, cts); 1179 } 1180 1181 ccb->ccb_h.status = CAM_REQ_CMP; 1182 xpt_done(ccb); 1183 break; 1184 } 1185 case XPT_CALC_GEOMETRY: 1186 { 1187 struct ccb_calc_geometry *ccg; 1188 u_int32_t size_mb; 1189 u_int32_t secs_per_cylinder; 1190 1191 ccg = &ccb->ccg; 1192 size_mb = ccg->volume_size 1193 / ((1024L * 1024L) / ccg->block_size); 1194 1195 if (size_mb >= 1024 && (bt->extended_trans != 0)) { 1196 if (size_mb >= 2048) { 1197 ccg->heads = 255; 1198 ccg->secs_per_track = 63; 1199 } else { 1200 ccg->heads = 128; 1201 ccg->secs_per_track = 32; 1202 } 1203 } else { 1204 ccg->heads = 64; 1205 ccg->secs_per_track = 32; 1206 } 1207 secs_per_cylinder = ccg->heads * ccg->secs_per_track; 1208 ccg->cylinders = ccg->volume_size / secs_per_cylinder; 1209 ccb->ccb_h.status = CAM_REQ_CMP; 1210 xpt_done(ccb); 1211 break; 1212 } 1213 case XPT_RESET_BUS: /* Reset the specified SCSI bus */ 1214 { 1215 btreset(bt, /*hardreset*/TRUE); 1216 ccb->ccb_h.status = CAM_REQ_CMP; 1217 xpt_done(ccb); 1218 break; 1219 } 1220 case XPT_TERM_IO: /* Terminate the I/O process */ 1221 /* XXX Implement */ 1222 ccb->ccb_h.status = CAM_REQ_INVALID; 1223 xpt_done(ccb); 1224 break; 1225 case XPT_PATH_INQ: /* Path routing inquiry */ 1226 { 1227 struct ccb_pathinq *cpi = &ccb->cpi; 1228 1229 cpi->version_num = 1; /* XXX??? */ 1230 cpi->hba_inquiry = PI_SDTR_ABLE; 1231 if (bt->tag_capable != 0) 1232 cpi->hba_inquiry |= PI_TAG_ABLE; 1233 if (bt->wide_bus != 0) 1234 cpi->hba_inquiry |= PI_WIDE_16; 1235 cpi->target_sprt = 0; 1236 cpi->hba_misc = 0; 1237 cpi->hba_eng_cnt = 0; 1238 cpi->max_target = bt->wide_bus ? 15 : 7; 1239 cpi->max_lun = 7; 1240 cpi->initiator_id = bt->scsi_id; 1241 cpi->bus_id = cam_sim_bus(sim); 1242 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 1243 strncpy(cpi->hba_vid, "BusLogic", HBA_IDLEN); 1244 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 1245 cpi->unit_number = cam_sim_unit(sim); 1246 cpi->ccb_h.status = CAM_REQ_CMP; 1247 xpt_done(ccb); 1248 break; 1249 } 1250 default: 1251 ccb->ccb_h.status = CAM_REQ_INVALID; 1252 xpt_done(ccb); 1253 break; 1254 } 1255} 1256 1257static void 1258btexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) 1259{ 1260 struct bt_ccb *bccb; 1261 union ccb *ccb; 1262 struct bt_softc *bt; 1263 int s, i; 1264 1265 bccb = (struct bt_ccb *)arg; 1266 ccb = bccb->ccb; 1267 bt = (struct bt_softc *)ccb->ccb_h.ccb_bt_ptr; 1268 1269 if (error != 0) { 1270 if (error != EFBIG) 1271 printf("%s: Unexepected error 0x%x returned from " 1272 "bus_dmamap_load\n", bt_name(bt), error); 1273 if (ccb->ccb_h.status == CAM_REQ_INPROG) { 1274 xpt_freeze_devq(ccb->ccb_h.path, /*count*/1); 1275 ccb->ccb_h.status = CAM_REQ_TOO_BIG|CAM_DEV_QFRZN; 1276 } 1277 btfreeccb(bt, bccb); 1278 xpt_done(ccb); 1279 return; 1280 } 1281 1282 if (nseg != 0) { 1283 bt_sg_t *sg; 1284 bus_dma_segment_t *end_seg; 1285 bus_dmasync_op_t op; 1286 1287 end_seg = dm_segs + nseg; 1288 1289 /* Copy the segments into our SG list */ 1290 sg = bccb->sg_list; 1291 while (dm_segs < end_seg) { 1292 sg->len = dm_segs->ds_len; 1293 sg->addr = dm_segs->ds_addr; 1294 sg++; 1295 dm_segs++; 1296 } 1297 1298 if (nseg > 1) { 1299 bccb->hccb.opcode = INITIATOR_SG_CCB_WRESID; 1300 bccb->hccb.data_len = sizeof(bt_sg_t) * nseg; 1301 bccb->hccb.data_addr = bccb->sg_list_phys; 1302 } else { 1303 bccb->hccb.data_len = bccb->sg_list->len; 1304 bccb->hccb.data_addr = bccb->sg_list->addr; 1305 } 1306 1307 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) 1308 op = BUS_DMASYNC_PREREAD; 1309 else 1310 op = BUS_DMASYNC_PREWRITE; 1311 1312 bus_dmamap_sync(bt->buffer_dmat, bccb->dmamap, op); 1313 1314 } else { 1315 bccb->hccb.opcode = INITIATOR_SG_CCB; 1316 bccb->hccb.data_len = 0; 1317 bccb->hccb.data_addr = 0; 1318 } 1319 1320 s = splcam(); 1321 1322 /* 1323 * Last time we need to check if this CCB needs to 1324 * be aborted. 1325 */ 1326 if (ccb->ccb_h.status != CAM_REQ_INPROG) { 1327 if (nseg != 0) 1328 bus_dmamap_unload(bt->buffer_dmat, bccb->dmamap); 1329 btfreeccb(bt, bccb); 1330 xpt_done(ccb); 1331 splx(s); 1332 return; 1333 } 1334 1335 bccb->flags = BCCB_ACTIVE; 1336 ccb->ccb_h.status |= CAM_SIM_QUEUED; 1337 LIST_INSERT_HEAD(&bt->pending_ccbs, &ccb->ccb_h, sim_links.le); 1338 1339 ccb->ccb_h.timeout_ch = 1340 timeout(bttimeout, (caddr_t)bccb, 1341 (ccb->ccb_h.timeout * hz) / 1000); 1342 1343 /* Tell the adapter about this command */ 1344 bt->cur_outbox->ccb_addr = btccbvtop(bt, bccb); 1345 if (bt->cur_outbox->action_code != BMBO_FREE) 1346 panic("%s: Too few mailboxes or to many ccbs???", bt_name(bt)); 1347 bt->cur_outbox->action_code = BMBO_START; 1348 bt_outb(bt, COMMAND_REG, BOP_START_MBOX); 1349 btnextoutbox(bt); 1350 splx(s); 1351} 1352 1353void 1354bt_intr(void *arg) 1355{ 1356 struct bt_softc *bt; 1357 u_int intstat; 1358 1359 bt = (struct bt_softc *)arg; 1360 while (((intstat = bt_inb(bt, INTSTAT_REG)) & INTR_PENDING) != 0) { 1361 1362 if ((intstat & CMD_COMPLETE) != 0) { 1363 bt->latched_status = bt_inb(bt, STATUS_REG); 1364 bt->command_cmp = TRUE; 1365 } 1366 1367 bt_outb(bt, CONTROL_REG, RESET_INTR); 1368 1369 if ((intstat & IMB_LOADED) != 0) { 1370 while (bt->cur_inbox->comp_code != BMBI_FREE) { 1371 btdone(bt, 1372 btccbptov(bt, bt->cur_inbox->ccb_addr), 1373 bt->cur_inbox->comp_code); 1374 bt->cur_inbox->comp_code = BMBI_FREE; 1375 btnextinbox(bt); 1376 } 1377 } 1378 1379 if ((intstat & SCSI_BUS_RESET) != 0) { 1380 btreset(bt, /*hardreset*/FALSE); 1381 } 1382 } 1383} 1384 1385static void 1386btdone(struct bt_softc *bt, struct bt_ccb *bccb, bt_mbi_comp_code_t comp_code) 1387{ 1388 union ccb *ccb; 1389 struct ccb_scsiio *csio; 1390 1391 ccb = bccb->ccb; 1392 csio = &bccb->ccb->csio; 1393 1394 if ((bccb->flags & BCCB_ACTIVE) == 0) { 1395 printf("%s: btdone - Attempt to free non-active BCCB %p\n", 1396 bt_name(bt), (void *)bccb); 1397 return; 1398 } 1399 1400 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 1401 bus_dmasync_op_t op; 1402 1403 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) 1404 op = BUS_DMASYNC_POSTREAD; 1405 else 1406 op = BUS_DMASYNC_POSTWRITE; 1407 bus_dmamap_sync(bt->buffer_dmat, bccb->dmamap, op); 1408 bus_dmamap_unload(bt->buffer_dmat, bccb->dmamap); 1409 } 1410 1411 if (bccb == bt->recovery_bccb) { 1412 /* 1413 * The recovery BCCB does not have a CCB associated 1414 * with it, so short circuit the normal error handling. 1415 * We now traverse our list of pending CCBs and process 1416 * any that were terminated by the recovery CCBs action. 1417 * We also reinstate timeouts for all remaining, pending, 1418 * CCBs. 1419 */ 1420 struct cam_path *path; 1421 struct ccb_hdr *ccb_h; 1422 cam_status error; 1423 1424 /* Notify all clients that a BDR occured */ 1425 error = xpt_create_path(&path, /*periph*/NULL, 1426 cam_sim_path(bt->sim), 1427 bccb->hccb.target_id, 1428 CAM_LUN_WILDCARD); 1429 1430 if (error == CAM_REQ_CMP) 1431 xpt_async(AC_SENT_BDR, path, NULL); 1432 1433 ccb_h = LIST_FIRST(&bt->pending_ccbs); 1434 while (ccb_h != NULL) { 1435 struct bt_ccb *pending_bccb; 1436 1437 pending_bccb = (struct bt_ccb *)ccb_h->ccb_bccb_ptr; 1438 if (pending_bccb->hccb.target_id 1439 == bccb->hccb.target_id) { 1440 pending_bccb->hccb.btstat = BTSTAT_HA_BDR; 1441 ccb_h = LIST_NEXT(ccb_h, sim_links.le); 1442 btdone(bt, pending_bccb, BMBI_ERROR); 1443 } else { 1444 ccb_h->timeout_ch = 1445 timeout(bttimeout, (caddr_t)pending_bccb, 1446 (ccb_h->timeout * hz) / 1000); 1447 ccb_h = LIST_NEXT(ccb_h, sim_links.le); 1448 } 1449 } 1450 printf("%s: No longer in timeout\n", bt_name(bt)); 1451 return; 1452 } 1453 1454 untimeout(bttimeout, bccb, ccb->ccb_h.timeout_ch); 1455 1456 switch (comp_code) { 1457 case BMBI_FREE: 1458 printf("%s: btdone - CCB completed with free status!\n", 1459 bt_name(bt)); 1460 break; 1461 case BMBI_NOT_FOUND: 1462 printf("%s: btdone - CCB Abort failed to find CCB\n", 1463 bt_name(bt)); 1464 break; 1465 case BMBI_ABORT: 1466 case BMBI_ERROR: 1467#if 0 1468 printf("bt: ccb %x - error %x occured. btstat = %x, sdstat = %x\n", 1469 bccb, comp_code, bccb->hccb.btstat, bccb->hccb.sdstat); 1470#endif 1471 /* An error occured */ 1472 switch(bccb->hccb.btstat) { 1473 case BTSTAT_DATARUN_ERROR: 1474 if (bccb->hccb.data_len <= 0) { 1475 csio->ccb_h.status = CAM_DATA_RUN_ERR; 1476 break; 1477 } 1478 /* FALLTHROUGH */ 1479 case BTSTAT_NOERROR: 1480 case BTSTAT_LINKED_CMD_COMPLETE: 1481 case BTSTAT_LINKED_CMD_FLAG_COMPLETE: 1482 case BTSTAT_DATAUNDERUN_ERROR: 1483 1484 csio->scsi_status = bccb->hccb.sdstat; 1485 csio->ccb_h.status |= CAM_SCSI_STATUS_ERROR; 1486 switch(csio->scsi_status) { 1487 case SCSI_STATUS_CHECK_COND: 1488 case SCSI_STATUS_CMD_TERMINATED: 1489 csio->ccb_h.status |= CAM_AUTOSNS_VALID; 1490 /* Bounce sense back if necessary */ 1491 if (bt->sense_buffers != NULL) { 1492 csio->sense_data = 1493 *btsensevaddr(bt, bccb); 1494 } 1495 break; 1496 default: 1497 break; 1498 case SCSI_STATUS_OK: 1499 csio->ccb_h.status = CAM_REQ_CMP; 1500 break; 1501 } 1502 csio->resid = bccb->hccb.data_len; 1503 break; 1504 case BTSTAT_SELTIMEOUT: 1505 csio->ccb_h.status = CAM_SEL_TIMEOUT; 1506 break; 1507 case BTSTAT_UNEXPECTED_BUSFREE: 1508 csio->ccb_h.status = CAM_UNEXP_BUSFREE; 1509 break; 1510 case BTSTAT_INVALID_PHASE: 1511 csio->ccb_h.status = CAM_SEQUENCE_FAIL; 1512 break; 1513 case BTSTAT_INVALID_ACTION_CODE: 1514 panic("%s: Inavlid Action code", bt_name(bt)); 1515 break; 1516 case BTSTAT_INVALID_OPCODE: 1517 panic("%s: Inavlid CCB Opcode code", bt_name(bt)); 1518 break; 1519 case BTSTAT_LINKED_CCB_LUN_MISMATCH: 1520 /* We don't even support linked commands... */ 1521 panic("%s: Linked CCB Lun Mismatch", bt_name(bt)); 1522 break; 1523 case BTSTAT_INVALID_CCB_OR_SG_PARAM: 1524 panic("%s: Invalid CCB or SG list", bt_name(bt)); 1525 break; 1526 case BTSTAT_AUTOSENSE_FAILED: 1527 csio->ccb_h.status = CAM_AUTOSENSE_FAIL; 1528 break; 1529 case BTSTAT_TAGGED_MSG_REJECTED: 1530 { 1531 struct ccb_trans_settings neg; 1532 1533 xpt_print_path(csio->ccb_h.path); 1534 printf("refuses tagged commands. Performing " 1535 "non-tagged I/O\n"); 1536 neg.flags = 0; 1537 neg.valid = CCB_TRANS_TQ_VALID; 1538 xpt_setup_ccb(&neg.ccb_h, csio->ccb_h.path, 1539 /*priority*/1); 1540 xpt_async(AC_TRANSFER_NEG, csio->ccb_h.path, &neg); 1541 bt->tags_permitted &= ~(0x01 << csio->ccb_h.target_id); 1542 csio->ccb_h.status = CAM_MSG_REJECT_REC; 1543 break; 1544 } 1545 case BTSTAT_UNSUPPORTED_MSG_RECEIVED: 1546 /* 1547 * XXX You would think that this is 1548 * a recoverable error... Hmmm. 1549 */ 1550 csio->ccb_h.status = CAM_REQ_CMP_ERR; 1551 break; 1552 case BTSTAT_HA_SOFTWARE_ERROR: 1553 case BTSTAT_HA_WATCHDOG_ERROR: 1554 case BTSTAT_HARDWARE_FAILURE: 1555 /* Hardware reset ??? Can we recover ??? */ 1556 csio->ccb_h.status = CAM_NO_HBA; 1557 break; 1558 case BTSTAT_TARGET_IGNORED_ATN: 1559 case BTSTAT_OTHER_SCSI_BUS_RESET: 1560 case BTSTAT_HA_SCSI_BUS_RESET: 1561 if ((csio->ccb_h.status & CAM_STATUS_MASK) 1562 != CAM_CMD_TIMEOUT) 1563 csio->ccb_h.status = CAM_SCSI_BUS_RESET; 1564 break; 1565 case BTSTAT_HA_BDR: 1566 if ((bccb->flags & BCCB_DEVICE_RESET) == 0) 1567 csio->ccb_h.status = CAM_BDR_SENT; 1568 else 1569 csio->ccb_h.status = CAM_CMD_TIMEOUT; 1570 break; 1571 case BTSTAT_INVALID_RECONNECT: 1572 case BTSTAT_ABORT_QUEUE_GENERATED: 1573 csio->ccb_h.status = CAM_REQ_TERMIO; 1574 break; 1575 case BTSTAT_SCSI_PERROR_DETECTED: 1576 csio->ccb_h.status = CAM_UNCOR_PARITY; 1577 break; 1578 } 1579 if (csio->ccb_h.status != CAM_REQ_CMP) { 1580 xpt_freeze_devq(csio->ccb_h.path, /*count*/1); 1581 csio->ccb_h.status |= CAM_DEV_QFRZN; 1582 } 1583 if ((bccb->flags & BCCB_RELEASE_SIMQ) != 0) 1584 ccb->ccb_h.status |= CAM_RELEASE_SIMQ; 1585 btfreeccb(bt, bccb); 1586 xpt_done(ccb); 1587 break; 1588 case BMBI_OK: 1589 /* All completed without incident */ 1590 ccb->ccb_h.status |= CAM_REQ_CMP; 1591 if ((bccb->flags & BCCB_RELEASE_SIMQ) != 0) 1592 ccb->ccb_h.status |= CAM_RELEASE_SIMQ; 1593 btfreeccb(bt, bccb); 1594 xpt_done(ccb); 1595 break; 1596 } 1597} 1598 1599static int 1600btreset(struct bt_softc* bt, int hard_reset) 1601{ 1602 struct ccb_hdr *ccb_h; 1603 u_int status; 1604 u_int timeout; 1605 u_int8_t reset_type; 1606 1607 if (hard_reset != 0) 1608 reset_type = HARD_RESET; 1609 else 1610 reset_type = SOFT_RESET; 1611 bt_outb(bt, CONTROL_REG, reset_type); 1612 1613 /* Wait 5sec. for Diagnostic start */ 1614 timeout = 5 * 10000; 1615 while (--timeout) { 1616 status = bt_inb(bt, STATUS_REG); 1617 if ((status & DIAG_ACTIVE) != 0) 1618 break; 1619 DELAY(100); 1620 } 1621 if (timeout == 0) { 1622 if (bootverbose) 1623 printf("%s: btreset - Diagnostic Active failed to " 1624 "assert. status = 0x%x\n", bt_name(bt), status); 1625 return (ETIMEDOUT); 1626 } 1627 1628 /* Wait 10sec. for Diagnostic end */ 1629 timeout = 10 * 10000; 1630 while (--timeout) { 1631 status = bt_inb(bt, STATUS_REG); 1632 if ((status & DIAG_ACTIVE) == 0) 1633 break; 1634 DELAY(100); 1635 } 1636 if (timeout == 0) { 1637 panic("%s: btreset - Diagnostic Active failed to drop. " 1638 "status = 0x%x\n", bt_name(bt), status); 1639 return (ETIMEDOUT); 1640 } 1641 1642 /* Wait for the host adapter to become ready or report a failure */ 1643 timeout = 10000; 1644 while (--timeout) { 1645 status = bt_inb(bt, STATUS_REG); 1646 if ((status & (DIAG_FAIL|HA_READY|DATAIN_REG_READY)) != 0) 1647 break; 1648 DELAY(100); 1649 } 1650 if (timeout == 0) { 1651 printf("%s: btreset - Host adapter failed to come ready. " 1652 "status = 0x%x\n", bt_name(bt), status); 1653 return (ETIMEDOUT); 1654 } 1655 1656 /* If the diagnostics failed, tell the user */ 1657 if ((status & DIAG_FAIL) != 0 1658 || (status & HA_READY) == 0) { 1659 printf("%s: btreset - Adapter failed diagnostics\n", 1660 bt_name(bt)); 1661 1662 if ((status & DATAIN_REG_READY) != 0) 1663 printf("%s: btreset - Host Adapter Error code = 0x%x\n", 1664 bt_name(bt), bt_inb(bt, DATAIN_REG)); 1665 return (ENXIO); 1666 } 1667 1668 /* If we've allocated mailboxes, initialize them */ 1669 if (bt->init_level > 4) 1670 btinitmboxes(bt); 1671 1672 /* If we've attached to the XPT, tell it about the event */ 1673 if (bt->path != NULL) 1674 xpt_async(AC_BUS_RESET, bt->path, NULL); 1675 1676 /* 1677 * Perform completion processing for all outstanding CCBs. 1678 */ 1679 while ((ccb_h = LIST_FIRST(&bt->pending_ccbs)) != NULL) { 1680 struct bt_ccb *pending_bccb; 1681 1682 pending_bccb = (struct bt_ccb *)ccb_h->ccb_bccb_ptr; 1683 pending_bccb->hccb.btstat = BTSTAT_HA_SCSI_BUS_RESET; 1684 btdone(bt, pending_bccb, BMBI_ERROR); 1685 } 1686 1687 return (0); 1688} 1689 1690/* 1691 * Send a command to the adapter. 1692 */ 1693int 1694bt_cmd(struct bt_softc *bt, bt_op_t opcode, u_int8_t *params, u_int param_len, 1695 u_int8_t *reply_data, u_int reply_len, u_int cmd_timeout) 1696{ 1697 u_int timeout; 1698 u_int status; 1699 u_int intstat; 1700 u_int reply_buf_size; 1701 int s; 1702 1703 /* No data returned to start */ 1704 reply_buf_size = reply_len; 1705 reply_len = 0; 1706 intstat = 0; 1707 1708 bt->command_cmp = 0; 1709 /* 1710 * Wait up to 1 sec. for the adapter to become 1711 * ready to accept commands. 1712 */ 1713 timeout = 10000; 1714 while (--timeout) { 1715 1716 status = bt_inb(bt, STATUS_REG); 1717 if ((status & HA_READY) != 0 1718 && (status & CMD_REG_BUSY) == 0) 1719 break; 1720 DELAY(100); 1721 } 1722 if (timeout == 0) { 1723 printf("%s: bt_cmd: Timeout waiting for adapter ready, " 1724 "status = 0x%x\n", bt_name(bt), status); 1725 return (ETIMEDOUT); 1726 } 1727 1728 /* 1729 * Send the opcode followed by any necessary parameter bytes. 1730 */ 1731 bt_outb(bt, COMMAND_REG, opcode); 1732 1733 /* 1734 * Wait for up to 1sec to get the parameter list sent 1735 */ 1736 timeout = 10000; 1737 while (param_len && --timeout) { 1738 DELAY(100); 1739 status = bt_inb(bt, STATUS_REG); 1740 intstat = bt_inb(bt, INTSTAT_REG); 1741 if ((intstat & (INTR_PENDING|CMD_COMPLETE)) 1742 == (INTR_PENDING|CMD_COMPLETE)) 1743 break; 1744 if (bt->command_cmp != 0) { 1745 status = bt->latched_status; 1746 break; 1747 } 1748 if ((status & DATAIN_REG_READY) != 0) 1749 break; 1750 if ((status & CMD_REG_BUSY) == 0) { 1751 bt_outb(bt, COMMAND_REG, *params++); 1752 param_len--; 1753 } 1754 } 1755 if (timeout == 0) { 1756 printf("%s: bt_cmd: Timeout sending parameters, " 1757 "status = 0x%x\n", bt_name(bt), status); 1758 return (ETIMEDOUT); 1759 } 1760 1761 /* 1762 * The BOP_MODIFY_IO_ADDR does not issue a CMD_COMPLETE, but 1763 * it should update the status register. So, we wait for 1764 * the CMD_REG_BUSY status to clear and check for a command 1765 * failure. 1766 */ 1767 if (opcode == BOP_MODIFY_IO_ADDR) { 1768 1769 while (--cmd_timeout) { 1770 status = bt_inb(bt, STATUS_REG); 1771 if ((status & CMD_REG_BUSY) == 0) { 1772 if ((status & CMD_INVALID) != 0) { 1773 printf("%s: bt_cmd - Modify I/O Address" 1774 " invalid\n", bt_name(bt)); 1775 return (EINVAL); 1776 } 1777 return (0); 1778 } 1779 DELAY(100); 1780 } 1781 if (timeout == 0) { 1782 printf("%s: bt_cmd: Timeout on Modify I/O Address CMD, " 1783 "status = 0x%x\n", bt_name(bt), status); 1784 return (ETIMEDOUT); 1785 } 1786 } 1787 1788 /* 1789 * For all other commands, we wait for any output data 1790 * and the final comand completion interrupt. 1791 */ 1792 while (--cmd_timeout) { 1793 1794 status = bt_inb(bt, STATUS_REG); 1795 intstat = bt_inb(bt, INTSTAT_REG); 1796 if ((intstat & (INTR_PENDING|CMD_COMPLETE)) 1797 == (INTR_PENDING|CMD_COMPLETE)) 1798 break; 1799 1800 if (bt->command_cmp != 0) { 1801 status = bt->latched_status; 1802 break; 1803 } 1804 1805 if ((status & DATAIN_REG_READY) != 0) { 1806 u_int8_t data; 1807 1808 data = bt_inb(bt, DATAIN_REG); 1809 if (reply_len < reply_buf_size) { 1810 *reply_data++ = data; 1811 } else { 1812 printf("%s: bt_cmd - Discarded reply data byte " 1813 "for opcode 0x%x\n", bt_name(bt), 1814 opcode); 1815 } 1816 reply_len++; 1817 } 1818 1819 if ((opcode == BOP_FETCH_LRAM) 1820 && (status & HA_READY) != 0) 1821 break; 1822 DELAY(100); 1823 } 1824 if (timeout == 0) { 1825 printf("%s: bt_cmd: Timeout waiting for reply data and " 1826 "command complete.\n%s: status = 0x%x, intstat = 0x%x, " 1827 "reply_len = %d\n", bt_name(bt), bt_name(bt), status, 1828 intstat, reply_len); 1829 return (ETIMEDOUT); 1830 } 1831 1832 /* 1833 * Clear any pending interrupts. Block interrupts so our 1834 * interrupt handler is not re-entered. 1835 */ 1836 s = splcam(); 1837 bt_intr(bt); 1838 splx(s); 1839 1840 /* 1841 * If the command was rejected by the controller, tell the caller. 1842 */ 1843 if ((status & CMD_INVALID) != 0) { 1844 /* 1845 * Some early adapters may not recover properly from 1846 * an invalid command. If it appears that the controller 1847 * has wedged (i.e. status was not cleared by our interrupt 1848 * reset above), perform a soft reset. 1849 */ 1850 if (bootverbose) 1851 printf("%s: Invalid Command 0x%x\n", bt_name(bt), 1852 opcode); 1853 DELAY(1000); 1854 status = bt_inb(bt, STATUS_REG); 1855 if ((status & (CMD_INVALID|STATUS_REG_RSVD|DATAIN_REG_READY| 1856 CMD_REG_BUSY|DIAG_FAIL|DIAG_ACTIVE)) != 0 1857 || (status & (HA_READY|INIT_REQUIRED)) 1858 != (HA_READY|INIT_REQUIRED)) { 1859 btreset(bt, /*hard_reset*/FALSE); 1860 } 1861 return (EINVAL); 1862 } 1863 1864 1865 if (param_len > 0) { 1866 /* The controller did not accept the full argument list */ 1867 return (E2BIG); 1868 } 1869 1870 if (reply_len != reply_buf_size) { 1871 /* Too much or too little data received */ 1872 return (EMSGSIZE); 1873 } 1874 1875 /* We were successful */ 1876 return (0); 1877} 1878 1879static int 1880btinitmboxes(struct bt_softc *bt) { 1881 init_32b_mbox_params_t init_mbox; 1882 int error; 1883 1884 bzero(bt->in_boxes, sizeof(bt_mbox_in_t) * bt->num_boxes); 1885 bzero(bt->out_boxes, sizeof(bt_mbox_out_t) * bt->num_boxes); 1886 bt->cur_inbox = bt->in_boxes; 1887 bt->last_inbox = bt->in_boxes + bt->num_boxes - 1; 1888 bt->cur_outbox = bt->out_boxes; 1889 bt->last_outbox = bt->out_boxes + bt->num_boxes - 1; 1890 1891 /* Tell the adapter about them */ 1892 init_mbox.num_boxes = bt->num_boxes; 1893 init_mbox.base_addr[0] = bt->mailbox_physbase & 0xFF; 1894 init_mbox.base_addr[1] = (bt->mailbox_physbase >> 8) & 0xFF; 1895 init_mbox.base_addr[2] = (bt->mailbox_physbase >> 16) & 0xFF; 1896 init_mbox.base_addr[3] = (bt->mailbox_physbase >> 24) & 0xFF; 1897 error = bt_cmd(bt, BOP_INITIALIZE_32BMBOX, (u_int8_t *)&init_mbox, 1898 /*parmlen*/sizeof(init_mbox), /*reply_buf*/NULL, 1899 /*reply_len*/0, DEFAULT_CMD_TIMEOUT); 1900 1901 if (error != 0) 1902 printf("btinitmboxes: Initialization command failed\n"); 1903 else if (bt->strict_rr != 0) { 1904 /* 1905 * If the controller supports 1906 * strict round robin mode, 1907 * enable it 1908 */ 1909 u_int8_t param; 1910 1911 param = 0; 1912 error = bt_cmd(bt, BOP_ENABLE_STRICT_RR, ¶m, 1, 1913 /*reply_buf*/NULL, /*reply_len*/0, 1914 DEFAULT_CMD_TIMEOUT); 1915 1916 if (error != 0) { 1917 printf("btinitmboxes: Unable to enable strict RR\n"); 1918 error = 0; 1919 } else if (bootverbose) { 1920 printf("%s: Using Strict Round Robin Mailbox Mode\n", 1921 bt_name(bt)); 1922 } 1923 } 1924 1925 return (error); 1926} 1927 1928/* 1929 * Update the XPT's idea of the negotiated transfer 1930 * parameters for a particular target. 1931 */ 1932static void 1933btfetchtransinfo(struct bt_softc *bt, struct ccb_trans_settings* cts) 1934{ 1935 setup_data_t setup_info; 1936 u_int target; 1937 u_int targ_offset; 1938 u_int targ_mask; 1939 u_int sync_period; 1940 int error; 1941 u_int8_t param; 1942 targ_syncinfo_t sync_info; 1943 1944 target = cts->ccb_h.target_id; 1945 targ_offset = (target & 0x7); 1946 targ_mask = (0x01 << targ_offset); 1947 1948 /* 1949 * Inquire Setup Information. This command retreives the 1950 * Wide negotiation status for recent adapters as well as 1951 * the sync info for older models. 1952 */ 1953 param = sizeof(setup_info); 1954 error = bt_cmd(bt, BOP_INQUIRE_SETUP_INFO, ¶m, /*paramlen*/1, 1955 (u_int8_t*)&setup_info, sizeof(setup_info), 1956 DEFAULT_CMD_TIMEOUT); 1957 1958 if (error != 0) { 1959 printf("%s: btfetchtransinfo - Inquire Setup Info Failed\n", 1960 bt_name(bt)); 1961 return; 1962 } 1963 1964 sync_info = (target < 8) ? setup_info.low_syncinfo[targ_offset] 1965 : setup_info.high_syncinfo[targ_offset]; 1966 1967 if (sync_info.sync == 0) 1968 cts->sync_offset = 0; 1969 else 1970 cts->sync_offset = sync_info.offset; 1971 1972 cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT; 1973 if (strcmp(bt->firmware_ver, "5.06L") >= 0) { 1974 u_int wide_active; 1975 1976 wide_active = 1977 (target < 8) ? (setup_info.low_wide_active & targ_mask) 1978 : (setup_info.high_wide_active & targ_mask); 1979 1980 if (wide_active) 1981 cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT; 1982 } else if ((bt->wide_permitted & targ_mask) != 0) { 1983 struct ccb_getdev cgd; 1984 1985 /* 1986 * Prior to rev 5.06L, wide status isn't provided, 1987 * so we "guess" that wide transfers are in effect 1988 * if the user settings allow for wide and the inquiry 1989 * data for the device indicates that it can handle 1990 * wide transfers. 1991 */ 1992 xpt_setup_ccb(&cgd.ccb_h, cts->ccb_h.path, /*priority*/1); 1993 cgd.ccb_h.func_code = XPT_GDEV_TYPE; 1994 xpt_action((union ccb *)&cgd); 1995 if ((cgd.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP 1996 && (cgd.inq_data.flags & SID_WBus16) != 0) 1997 cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT; 1998 } 1999 2000 if (bt->firmware_ver[0] >= 3) { 2001 /* 2002 * For adapters that can do fast or ultra speeds, 2003 * use the more exact Target Sync Information command. 2004 */ 2005 target_sync_info_data_t sync_info; 2006 2007 param = sizeof(sync_info); 2008 error = bt_cmd(bt, BOP_TARG_SYNC_INFO, ¶m, /*paramlen*/1, 2009 (u_int8_t*)&sync_info, sizeof(sync_info), 2010 DEFAULT_CMD_TIMEOUT); 2011 2012 if (error != 0) { 2013 printf("%s: btfetchtransinfo - Inquire Sync " 2014 "Info Failed 0x%x\n", bt_name(bt), error); 2015 return; 2016 } 2017 sync_period = sync_info.sync_rate[target] * 100; 2018 } else { 2019 sync_period = 2000 + (500 * sync_info.period); 2020 } 2021 2022 /* Convert ns value to standard SCSI sync rate */ 2023 if (cts->sync_offset != 0) 2024 cts->sync_period = scsi_calc_syncparam(sync_period); 2025 else 2026 cts->sync_period = 0; 2027 2028 cts->valid = CCB_TRANS_SYNC_RATE_VALID 2029 | CCB_TRANS_SYNC_OFFSET_VALID 2030 | CCB_TRANS_BUS_WIDTH_VALID; 2031 xpt_async(AC_TRANSFER_NEG, cts->ccb_h.path, cts); 2032} 2033 2034static void 2035btmapmboxes(void *arg, bus_dma_segment_t *segs, int nseg, int error) 2036{ 2037 struct bt_softc* bt; 2038 2039 bt = (struct bt_softc*)arg; 2040 bt->mailbox_physbase = segs->ds_addr; 2041} 2042 2043static void 2044btmapccbs(void *arg, bus_dma_segment_t *segs, int nseg, int error) 2045{ 2046 struct bt_softc* bt; 2047 2048 bt = (struct bt_softc*)arg; 2049 bt->bt_ccb_physbase = segs->ds_addr; 2050} 2051 2052static void 2053btmapsgs(void *arg, bus_dma_segment_t *segs, int nseg, int error) 2054{ 2055 2056 struct bt_softc* bt; 2057 2058 bt = (struct bt_softc*)arg; 2059 SLIST_FIRST(&bt->sg_maps)->sg_physaddr = segs->ds_addr; 2060} 2061 2062static void 2063btpoll(struct cam_sim *sim) 2064{ 2065} 2066 2067void 2068bttimeout(void *arg) 2069{ 2070 struct bt_ccb *bccb; 2071 union ccb *ccb; 2072 struct bt_softc *bt; 2073 int s; 2074 2075 bccb = (struct bt_ccb *)arg; 2076 ccb = bccb->ccb; 2077 bt = (struct bt_softc *)ccb->ccb_h.ccb_bt_ptr; 2078 xpt_print_path(ccb->ccb_h.path); 2079 printf("CCB %p - timed out\n", (void *)bccb); 2080 2081 s = splcam(); 2082 2083 if ((bccb->flags & BCCB_ACTIVE) == 0) { 2084 xpt_print_path(ccb->ccb_h.path); 2085 printf("CCB %p - timed out CCB already completed\n", 2086 (void *)bccb); 2087 splx(s); 2088 return; 2089 } 2090 2091 /* 2092 * In order to simplify the recovery process, we ask the XPT 2093 * layer to halt the queue of new transactions and we traverse 2094 * the list of pending CCBs and remove their timeouts. This 2095 * means that the driver attempts to clear only one error 2096 * condition at a time. In general, timeouts that occur 2097 * close together are related anyway, so there is no benefit 2098 * in attempting to handle errors in parrallel. Timeouts will 2099 * be reinstated when the recovery process ends. 2100 */ 2101 if ((bccb->flags & BCCB_DEVICE_RESET) == 0) { 2102 struct ccb_hdr *ccb_h; 2103 2104 if ((bccb->flags & BCCB_RELEASE_SIMQ) == 0) { 2105 xpt_freeze_simq(bt->sim, /*count*/1); 2106 bccb->flags |= BCCB_RELEASE_SIMQ; 2107 } 2108 2109 ccb_h = LIST_FIRST(&bt->pending_ccbs); 2110 while (ccb_h != NULL) { 2111 struct bt_ccb *pending_bccb; 2112 2113 pending_bccb = (struct bt_ccb *)ccb_h->ccb_bccb_ptr; 2114 untimeout(bttimeout, pending_bccb, ccb_h->timeout_ch); 2115 ccb_h = LIST_NEXT(ccb_h, sim_links.le); 2116 } 2117 } 2118 2119 if ((bccb->flags & BCCB_DEVICE_RESET) != 0 2120 || bt->cur_outbox->action_code != BMBO_FREE 2121 || ((ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) != 0 2122 && (bt->firmware_ver[0] < '5'))) { 2123 /* 2124 * Try a full host adapter/SCSI bus reset. 2125 * We do this only if we have already attempted 2126 * to clear the condition with a BDR, or we cannot 2127 * attempt a BDR for lack of mailbox resources 2128 * or because of faulty firmware. It turns out 2129 * that firmware versions prior to 5.xx treat BDRs 2130 * as untagged commands that cannot be sent until 2131 * all outstanding tagged commands have been processed. 2132 * This makes it somewhat difficult to use a BDR to 2133 * clear up a problem with an uncompleted tagged command. 2134 */ 2135 ccb->ccb_h.status = CAM_CMD_TIMEOUT; 2136 btreset(bt, /*hardreset*/TRUE); 2137 printf("%s: No longer in timeout\n", bt_name(bt)); 2138 } else { 2139 /* 2140 * Send a Bus Device Reset message: 2141 * The target that is holding up the bus may not 2142 * be the same as the one that triggered this timeout 2143 * (different commands have different timeout lengths), 2144 * but we have no way of determining this from our 2145 * timeout handler. Our strategy here is to queue a 2146 * BDR message to the target of the timed out command. 2147 * If this fails, we'll get another timeout 2 seconds 2148 * later which will attempt a bus reset. 2149 */ 2150 bccb->flags |= BCCB_DEVICE_RESET; 2151 ccb->ccb_h.timeout_ch = 2152 timeout(bttimeout, (caddr_t)bccb, 2 * hz); 2153 2154 bt->recovery_bccb->hccb.opcode = INITIATOR_BUS_DEV_RESET; 2155 2156 /* No Data Transfer */ 2157 bt->recovery_bccb->hccb.datain = TRUE; 2158 bt->recovery_bccb->hccb.dataout = TRUE; 2159 bt->recovery_bccb->hccb.btstat = 0; 2160 bt->recovery_bccb->hccb.sdstat = 0; 2161 bt->recovery_bccb->hccb.target_id = ccb->ccb_h.target_id; 2162 2163 /* Tell the adapter about this command */ 2164 bt->cur_outbox->ccb_addr = btccbvtop(bt, bt->recovery_bccb); 2165 bt->cur_outbox->action_code = BMBO_START; 2166 bt_outb(bt, COMMAND_REG, BOP_START_MBOX); 2167 btnextoutbox(bt); 2168 } 2169 2170 splx(s); 2171} 2172 2173