ntb_hw.c revision 255269
1/*- 2 * Copyright (C) 2013 Intel Corporation 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD: head/sys/dev/ntb/ntb_hw/ntb_hw.c 255269 2013-09-05 22:52:40Z carl $"); 29 30#include <sys/param.h> 31#include <sys/kernel.h> 32#include <sys/systm.h> 33#include <sys/bus.h> 34#include <sys/malloc.h> 35#include <sys/module.h> 36#include <sys/queue.h> 37#include <sys/rman.h> 38#include <vm/vm.h> 39#include <vm/pmap.h> 40#include <machine/bus.h> 41#include <machine/pmap.h> 42#include <machine/resource.h> 43#include <dev/pci/pcireg.h> 44#include <dev/pci/pcivar.h> 45 46#include "ntb_regs.h" 47#include "ntb_hw.h" 48 49/* 50 * The Non-Transparent Bridge (NTB) is a device on some Intel processors that 51 * allows you to connect two systems using a PCI-e link. 52 * 53 * This module contains the hardware abstraction layer for the NTB. It allows 54 * you to send and recieve interrupts, map the memory windows and send and 55 * receive messages in the scratch-pad registers. 56 * 57 * NOTE: Much of the code in this module is shared with Linux. Any patches may 58 * be picked up and redistributed in Linux with a dual GPL/BSD license. 59 */ 60 61#define NTB_CONFIG_BAR 0 62#define NTB_B2B_BAR_1 1 63#define NTB_B2B_BAR_2 2 64#define NTB_MAX_BARS 3 65#define NTB_MW_TO_BAR(mw) ((mw) + 1) 66 67#define MAX_MSIX_INTERRUPTS MAX(XEON_MAX_DB_BITS, SOC_MAX_DB_BITS) 68 69#define NTB_HB_TIMEOUT 1 /* second */ 70#define SOC_LINK_RECOVERY_TIME 500 71 72#define DEVICE2SOFTC(dev) ((struct ntb_softc *) device_get_softc(dev)) 73 74enum ntb_device_type { 75 NTB_XEON, 76 NTB_SOC 77}; 78 79struct ntb_hw_info { 80 uint32_t device_id; 81 enum ntb_device_type type; 82 const char *desc; 83}; 84 85struct ntb_pci_bar_info { 86 bus_space_tag_t pci_bus_tag; 87 bus_space_handle_t pci_bus_handle; 88 int pci_resource_id; 89 struct resource *pci_resource; 90 vm_paddr_t pbase; 91 void *vbase; 92 u_long size; 93}; 94 95struct ntb_int_info { 96 struct resource *res; 97 int rid; 98 void *tag; 99}; 100 101struct ntb_db_cb { 102 ntb_db_callback callback; 103 unsigned int db_num; 104 void *data; 105 struct ntb_softc *ntb; 106}; 107 108struct ntb_softc { 109 device_t device; 110 enum ntb_device_type type; 111 112 struct ntb_pci_bar_info bar_info[NTB_MAX_BARS]; 113 struct ntb_int_info int_info[MAX_MSIX_INTERRUPTS]; 114 uint32_t allocated_interrupts; 115 116 struct callout heartbeat_timer; 117 struct callout lr_timer; 118 119 void *ntb_transport; 120 ntb_event_callback event_cb; 121 struct ntb_db_cb *db_cb; 122 123 struct { 124 uint32_t max_spads; 125 uint32_t max_db_bits; 126 uint32_t msix_cnt; 127 } limits; 128 struct { 129 uint32_t pdb; 130 uint32_t pdb_mask; 131 uint32_t sdb; 132 uint32_t sbar2_xlat; 133 uint32_t sbar4_xlat; 134 uint32_t spad_remote; 135 uint32_t spad_local; 136 uint32_t lnk_cntl; 137 uint32_t lnk_stat; 138 uint32_t spci_cmd; 139 } reg_ofs; 140 uint8_t conn_type; 141 uint8_t dev_type; 142 uint8_t bits_per_vector; 143 uint8_t link_status; 144 uint8_t link_width; 145 uint8_t link_speed; 146}; 147 148#define ntb_reg_read(SIZE, offset) \ 149 bus_space_read_ ## SIZE (ntb->bar_info[NTB_CONFIG_BAR].pci_bus_tag, \ 150 ntb->bar_info[NTB_CONFIG_BAR].pci_bus_handle, (offset)) 151#define ntb_reg_write(SIZE, offset, val) \ 152 bus_space_write_ ## SIZE (ntb->bar_info[NTB_CONFIG_BAR].pci_bus_tag, \ 153 ntb->bar_info[NTB_CONFIG_BAR].pci_bus_handle, (offset), (val)) 154 155#define ntb_read_1(offset) ntb_reg_read(1, (offset)) 156#define ntb_read_2(offset) ntb_reg_read(2, (offset)) 157#define ntb_read_4(offset) ntb_reg_read(4, (offset)) 158#define ntb_read_8(offset) ntb_reg_read(8, (offset)) 159#define ntb_write_1(offset, val) ntb_reg_write(1, (offset), (val)) 160#define ntb_write_2(offset, val) ntb_reg_write(2, (offset), (val)) 161#define ntb_write_4(offset, val) ntb_reg_write(4, (offset), (val)) 162#define ntb_write_8(offset, val) ntb_reg_write(8, (offset), (val)) 163 164static int ntb_probe(device_t device); 165static int ntb_attach(device_t device); 166static int ntb_detach(device_t device); 167static int ntb_map_pci_bar(struct ntb_softc *ntb); 168static void ntb_unmap_pci_bar(struct ntb_softc *ntb); 169static int ntb_setup_interrupts(struct ntb_softc *ntb); 170static void ntb_teardown_interrupts(struct ntb_softc *ntb); 171static void handle_soc_irq(void *arg); 172static void handle_xeon_irq(void *arg); 173static void handle_xeon_event_irq(void *arg); 174static void ntb_handle_legacy_interrupt(void *arg); 175static int ntb_create_callbacks(struct ntb_softc *ntb, int num_vectors); 176static void ntb_free_callbacks(struct ntb_softc *ntb); 177static struct ntb_hw_info *ntb_get_device_info(uint32_t device_id); 178static int ntb_initialize_hw(struct ntb_softc *ntb); 179static int ntb_setup_xeon(struct ntb_softc *ntb); 180static int ntb_setup_soc(struct ntb_softc *ntb); 181static void ntb_handle_heartbeat(void *arg); 182static void ntb_handle_link_event(struct ntb_softc *ntb, int link_state); 183static void recover_soc_link(void *arg); 184static int ntb_check_link_status(struct ntb_softc *ntb); 185static bool is_bar_for_data_transfer(int bar_num); 186 187static struct ntb_hw_info pci_ids[] = { 188 { 0x3C0D8086, NTB_XEON, "Xeon E5/Core i7 Non-Transparent Bridge B2B" }, 189 { 0x0C4E8086, NTB_SOC, "Atom Processor S1200 NTB Primary B2B" }, 190 { 0x0E0D8086, NTB_XEON, "Xeon E5 V2 Non-Transparent Bridge B2B" }, 191 { 0x00000000, NTB_SOC, NULL } 192}; 193 194/* 195 * OS <-> Driver interface structures 196 */ 197MALLOC_DEFINE(M_NTB, "ntb_hw", "ntb_hw driver memory allocations"); 198 199static device_method_t ntb_pci_methods[] = { 200 /* Device interface */ 201 DEVMETHOD(device_probe, ntb_probe), 202 DEVMETHOD(device_attach, ntb_attach), 203 DEVMETHOD(device_detach, ntb_detach), 204 DEVMETHOD_END 205}; 206 207static driver_t ntb_pci_driver = { 208 "ntb_hw", 209 ntb_pci_methods, 210 sizeof(struct ntb_softc), 211}; 212 213static devclass_t ntb_devclass; 214DRIVER_MODULE(ntb_hw, pci, ntb_pci_driver, ntb_devclass, NULL, NULL); 215MODULE_VERSION(ntb_hw, 1); 216 217/* 218 * OS <-> Driver linkage functions 219 */ 220static int 221ntb_probe(device_t device) 222{ 223 struct ntb_hw_info *p = ntb_get_device_info(pci_get_devid(device)); 224 225 if (p != NULL) { 226 device_set_desc(device, p->desc); 227 return (0); 228 } else 229 return (ENXIO); 230} 231 232#define DETACH_ON_ERROR(func) \ 233 error = func; \ 234 if (error < 0) { \ 235 ntb_detach(device); \ 236 return (error); \ 237 } 238 239static int 240ntb_attach(device_t device) 241{ 242 struct ntb_softc *ntb = DEVICE2SOFTC(device); 243 struct ntb_hw_info *p = ntb_get_device_info(pci_get_devid(device)); 244 int error; 245 246 ntb->device = device; 247 ntb->type = p->type; 248 249 /* Heartbeat timer for NTB_SOC since there is no link interrupt */ 250 callout_init(&ntb->heartbeat_timer, CALLOUT_MPSAFE); 251 callout_init(&ntb->lr_timer, CALLOUT_MPSAFE); 252 253 DETACH_ON_ERROR(ntb_map_pci_bar(ntb)); 254 DETACH_ON_ERROR(ntb_initialize_hw(ntb)); 255 DETACH_ON_ERROR(ntb_setup_interrupts(ntb)); 256 257 pci_enable_busmaster(ntb->device); 258 259 return (error); 260} 261 262static int 263ntb_detach(device_t device) 264{ 265 struct ntb_softc *ntb = DEVICE2SOFTC(device); 266 267 callout_drain(&ntb->heartbeat_timer); 268 callout_drain(&ntb->lr_timer); 269 ntb_teardown_interrupts(ntb); 270 ntb_unmap_pci_bar(ntb); 271 272 return (0); 273} 274 275static int 276ntb_map_pci_bar(struct ntb_softc *ntb) 277{ 278 struct ntb_pci_bar_info *current_bar; 279 int rc, i; 280 281 ntb->bar_info[NTB_CONFIG_BAR].pci_resource_id = PCIR_BAR(0); 282 ntb->bar_info[NTB_B2B_BAR_1].pci_resource_id = PCIR_BAR(2); 283 ntb->bar_info[NTB_B2B_BAR_2].pci_resource_id = PCIR_BAR(4); 284 285 for (i = 0; i< NTB_MAX_BARS; i++) { 286 current_bar = &ntb->bar_info[i]; 287 current_bar->pci_resource = 288 bus_alloc_resource(ntb->device, 289 SYS_RES_MEMORY, 290 ¤t_bar->pci_resource_id, 0, ~0, 1, 291 RF_ACTIVE); 292 293 if (current_bar->pci_resource == NULL) { 294 device_printf(ntb->device, 295 "unable to allocate pci resource\n"); 296 return (ENXIO); 297 } 298 else { 299 current_bar->pci_bus_tag = 300 rman_get_bustag(current_bar->pci_resource); 301 current_bar->pci_bus_handle = 302 rman_get_bushandle(current_bar->pci_resource); 303 current_bar->pbase = 304 rman_get_start(current_bar->pci_resource); 305 current_bar->size = 306 rman_get_size(current_bar->pci_resource); 307 current_bar->vbase = 308 rman_get_virtual(current_bar->pci_resource); 309 if (is_bar_for_data_transfer(i)) { 310 /* 311 * Mark bar region as write combining to improve 312 * performance. 313 */ 314 rc = pmap_change_attr( 315 (vm_offset_t)current_bar->vbase, 316 current_bar->size, 317 VM_MEMATTR_WRITE_COMBINING); 318 if (rc != 0) { 319 device_printf(ntb->device, 320 "Couldn't mark bar as" 321 " WRITE_COMBINING\n"); 322 return (rc); 323 } 324 } 325 device_printf(ntb->device, 326 "Bar size = %lx, v %p, p %p\n", 327 current_bar->size, current_bar->vbase, 328 (void *)(current_bar->pbase)); 329 } 330 } 331 return (0); 332} 333 334static void 335ntb_unmap_pci_bar(struct ntb_softc *ntb) 336{ 337 struct ntb_pci_bar_info *current_bar; 338 int i; 339 340 for (i = 0; i< NTB_MAX_BARS; i++) { 341 current_bar = &ntb->bar_info[i]; 342 if (current_bar->pci_resource != NULL) 343 bus_release_resource(ntb->device, SYS_RES_MEMORY, 344 current_bar->pci_resource_id, 345 current_bar->pci_resource); 346 } 347} 348 349static int 350ntb_setup_interrupts(struct ntb_softc *ntb) 351{ 352 void (*interrupt_handler)(void *); 353 void *int_arg; 354 bool use_msix = 0; 355 uint32_t num_vectors; 356 int i; 357 358 ntb->allocated_interrupts = 0; 359 /* 360 * On SOC, disable all interrupts. On XEON, disable all but Link 361 * Interrupt. The rest will be unmasked as callbacks are registered. 362 */ 363 if (ntb->type == NTB_SOC) 364 ntb_write_8(ntb->reg_ofs.pdb_mask, ~0); 365 else 366 ntb_write_2(ntb->reg_ofs.pdb_mask, 367 ~(1 << ntb->limits.max_db_bits)); 368 369 num_vectors = MIN(pci_msix_count(ntb->device), 370 ntb->limits.max_db_bits); 371 if (num_vectors >= 1) { 372 pci_alloc_msix(ntb->device, &num_vectors); 373 if (num_vectors >= 4) 374 use_msix = TRUE; 375 } 376 377 ntb_create_callbacks(ntb, num_vectors); 378 if (use_msix == TRUE) { 379 for (i = 0; i < num_vectors; i++) { 380 ntb->int_info[i].rid = i + 1; 381 ntb->int_info[i].res = bus_alloc_resource_any( 382 ntb->device, SYS_RES_IRQ, &ntb->int_info[i].rid, 383 RF_ACTIVE); 384 if (ntb->int_info[i].res == NULL) { 385 device_printf(ntb->device, 386 "bus_alloc_resource failed\n"); 387 return (-1); 388 } 389 ntb->int_info[i].tag = NULL; 390 ntb->allocated_interrupts++; 391 if (ntb->type == NTB_SOC) { 392 interrupt_handler = handle_soc_irq; 393 int_arg = &ntb->db_cb[i]; 394 } else { 395 if (i == num_vectors - 1) { 396 interrupt_handler = handle_xeon_event_irq; 397 int_arg = ntb; 398 } else { 399 interrupt_handler = 400 handle_xeon_irq; 401 int_arg = &ntb->db_cb[i]; 402 } 403 } 404 if (bus_setup_intr(ntb->device, ntb->int_info[i].res, 405 INTR_MPSAFE | INTR_TYPE_MISC, NULL, 406 interrupt_handler, int_arg, 407 &ntb->int_info[i].tag) != 0) { 408 device_printf(ntb->device, 409 "bus_setup_intr failed\n"); 410 return (ENXIO); 411 } 412 } 413 } 414 else { 415 ntb->int_info[0].rid = 0; 416 ntb->int_info[0].res = bus_alloc_resource_any(ntb->device, SYS_RES_IRQ, 417 &ntb->int_info[0].rid, RF_SHAREABLE|RF_ACTIVE); 418 interrupt_handler = ntb_handle_legacy_interrupt; 419 if (ntb->int_info[0].res == NULL) { 420 device_printf(ntb->device, 421 "bus_alloc_resource failed\n"); 422 return (-1); 423 } 424 ntb->int_info[0].tag = NULL; 425 ntb->allocated_interrupts = 1; 426 427 if (bus_setup_intr(ntb->device, ntb->int_info[0].res, 428 INTR_MPSAFE | INTR_TYPE_MISC, NULL, 429 interrupt_handler, ntb, &ntb->int_info[0].tag) != 0) { 430 431 device_printf(ntb->device, "bus_setup_intr failed\n"); 432 return (ENXIO); 433 } 434 } 435 436 return (0); 437} 438 439static void 440ntb_teardown_interrupts(struct ntb_softc *ntb) 441{ 442 struct ntb_int_info *current_int; 443 int i; 444 445 for (i=0; i<ntb->allocated_interrupts; i++) { 446 current_int = &ntb->int_info[i]; 447 if (current_int->tag != NULL) 448 bus_teardown_intr(ntb->device, current_int->res, 449 current_int->tag); 450 451 if (current_int->res != NULL) 452 bus_release_resource(ntb->device, SYS_RES_IRQ, 453 rman_get_rid(current_int->res), current_int->res); 454 } 455 456 ntb_free_callbacks(ntb); 457 pci_release_msi(ntb->device); 458} 459 460static void 461handle_soc_irq(void *arg) 462{ 463 struct ntb_db_cb *db_cb = arg; 464 struct ntb_softc *ntb = db_cb->ntb; 465 466 ntb_write_8(ntb->reg_ofs.pdb, (uint64_t) 1 << db_cb->db_num); 467 468 if (db_cb->callback != NULL) 469 db_cb->callback(db_cb->data, db_cb->db_num); 470} 471 472static void 473handle_xeon_irq(void *arg) 474{ 475 struct ntb_db_cb *db_cb = arg; 476 struct ntb_softc *ntb = db_cb->ntb; 477 478 /* 479 * On Xeon, there are 16 bits in the interrupt register 480 * but only 4 vectors. So, 5 bits are assigned to the first 3 481 * vectors, with the 4th having a single bit for link 482 * interrupts. 483 */ 484 ntb_write_2(ntb->reg_ofs.pdb, 485 ((1 << ntb->bits_per_vector) - 1) << 486 (db_cb->db_num * ntb->bits_per_vector)); 487 488 if (db_cb->callback != NULL) 489 db_cb->callback(db_cb->data, db_cb->db_num); 490} 491 492/* Since we do not have a HW doorbell in SOC, this is only used in JF/JT */ 493static void 494handle_xeon_event_irq(void *arg) 495{ 496 struct ntb_softc *ntb = arg; 497 int rc; 498 499 rc = ntb_check_link_status(ntb); 500 if (rc != 0) 501 device_printf(ntb->device, "Error determining link status\n"); 502 503 /* bit 15 is always the link bit */ 504 ntb_write_2(ntb->reg_ofs.pdb, 1 << ntb->limits.max_db_bits); 505} 506 507static void 508ntb_handle_legacy_interrupt(void *arg) 509{ 510 struct ntb_softc *ntb = arg; 511 unsigned int i = 0; 512 uint64_t pdb64; 513 uint16_t pdb16; 514 515 if (ntb->type == NTB_SOC) { 516 pdb64 = ntb_read_8(ntb->reg_ofs.pdb); 517 518 while (pdb64) { 519 i = ffs(pdb64); 520 pdb64 &= pdb64 - 1; 521 handle_soc_irq(&ntb->db_cb[i]); 522 } 523 } else { 524 pdb16 = ntb_read_2(ntb->reg_ofs.pdb); 525 526 if ((pdb16 & XEON_DB_HW_LINK) != 0) { 527 handle_xeon_event_irq(ntb); 528 pdb16 &= ~XEON_DB_HW_LINK; 529 } 530 531 while (pdb16 != 0) { 532 i = ffs(pdb16); 533 pdb16 &= pdb16 - 1; 534 handle_xeon_irq(&ntb->db_cb[i]); 535 } 536 } 537 538} 539 540static int 541ntb_create_callbacks(struct ntb_softc *ntb, int num_vectors) 542{ 543 int i; 544 545 ntb->db_cb = malloc(num_vectors * sizeof(struct ntb_db_cb), M_NTB, 546 M_ZERO | M_WAITOK); 547 for (i = 0; i < num_vectors; i++) { 548 ntb->db_cb[i].db_num = i; 549 ntb->db_cb[i].ntb = ntb; 550 } 551 552 return (0); 553} 554 555static void 556ntb_free_callbacks(struct ntb_softc *ntb) 557{ 558 int i; 559 560 for (i = 0; i < ntb->limits.max_db_bits; i++) 561 ntb_unregister_db_callback(ntb, i); 562 563 free(ntb->db_cb, M_NTB); 564} 565 566static struct ntb_hw_info * 567ntb_get_device_info(uint32_t device_id) 568{ 569 struct ntb_hw_info *ep = pci_ids; 570 571 while (ep->device_id) { 572 if (ep->device_id == device_id) 573 return (ep); 574 ++ep; 575 } 576 return (NULL); 577} 578 579static int 580ntb_initialize_hw(struct ntb_softc *ntb) 581{ 582 583 if (ntb->type == NTB_SOC) 584 return (ntb_setup_soc(ntb)); 585 else 586 return (ntb_setup_xeon(ntb)); 587} 588 589static int 590ntb_setup_xeon(struct ntb_softc *ntb) 591{ 592 uint8_t val, connection_type; 593 594 val = pci_read_config(ntb->device, NTB_PPD_OFFSET, 1); 595 596 connection_type = val & XEON_PPD_CONN_TYPE; 597 switch (connection_type) { 598 case NTB_CONN_B2B: 599 ntb->conn_type = NTB_CONN_B2B; 600 break; 601 case NTB_CONN_CLASSIC: 602 case NTB_CONN_RP: 603 default: 604 device_printf(ntb->device, "Connection type %d not supported\n", 605 connection_type); 606 return (ENXIO); 607 } 608 609 if ((val & XEON_PPD_DEV_TYPE) != 0) 610 ntb->dev_type = NTB_DEV_DSD; 611 else 612 ntb->dev_type = NTB_DEV_USD; 613 614 ntb->reg_ofs.pdb = XEON_PDOORBELL_OFFSET; 615 ntb->reg_ofs.pdb_mask = XEON_PDBMSK_OFFSET; 616 ntb->reg_ofs.sbar2_xlat = XEON_SBAR2XLAT_OFFSET; 617 ntb->reg_ofs.sbar4_xlat = XEON_SBAR4XLAT_OFFSET; 618 ntb->reg_ofs.lnk_cntl = XEON_NTBCNTL_OFFSET; 619 ntb->reg_ofs.lnk_stat = XEON_LINK_STATUS_OFFSET; 620 ntb->reg_ofs.spad_local = XEON_SPAD_OFFSET; 621 ntb->reg_ofs.spci_cmd = XEON_PCICMD_OFFSET; 622 623 if (ntb->conn_type == NTB_CONN_B2B) { 624 ntb->reg_ofs.sdb = XEON_B2B_DOORBELL_OFFSET; 625 ntb->reg_ofs.spad_remote = XEON_B2B_SPAD_OFFSET; 626 ntb->limits.max_spads = XEON_MAX_SPADS; 627 } else { 628 ntb->reg_ofs.sdb = XEON_SDOORBELL_OFFSET; 629 ntb->reg_ofs.spad_remote = XEON_SPAD_OFFSET; 630 ntb->limits.max_spads = XEON_MAX_COMPAT_SPADS; 631 } 632 633 ntb->limits.max_db_bits = XEON_MAX_DB_BITS; 634 ntb->limits.msix_cnt = XEON_MSIX_CNT; 635 ntb->bits_per_vector = XEON_DB_BITS_PER_VEC; 636 637 /* Enable Bus Master and Memory Space on the secondary side */ 638 ntb_write_2(ntb->reg_ofs.spci_cmd, 639 PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN); 640 641 /* Enable link training */ 642 ntb_write_4(ntb->reg_ofs.lnk_cntl, 643 NTB_CNTL_BAR23_SNOOP | NTB_CNTL_BAR45_SNOOP); 644 645 return (0); 646} 647 648static int 649ntb_setup_soc(struct ntb_softc *ntb) 650{ 651 uint32_t val, connection_type; 652 653 val = pci_read_config(ntb->device, NTB_PPD_OFFSET, 4); 654 655 connection_type = (val & SOC_PPD_CONN_TYPE) >> 8; 656 switch (connection_type) { 657 case NTB_CONN_B2B: 658 ntb->conn_type = NTB_CONN_B2B; 659 break; 660 case NTB_CONN_RP: 661 default: 662 device_printf(ntb->device, "Connection type %d not supported\n", 663 connection_type); 664 return (ENXIO); 665 } 666 667 if ((val & SOC_PPD_DEV_TYPE) != 0) 668 ntb->dev_type = NTB_DEV_DSD; 669 else 670 ntb->dev_type = NTB_DEV_USD; 671 672 /* Initiate PCI-E link training */ 673 pci_write_config(ntb->device, NTB_PPD_OFFSET, val | SOC_PPD_INIT_LINK, 674 4); 675 676 ntb->reg_ofs.pdb = SOC_PDOORBELL_OFFSET; 677 ntb->reg_ofs.pdb_mask = SOC_PDBMSK_OFFSET; 678 ntb->reg_ofs.sbar2_xlat = SOC_SBAR2XLAT_OFFSET; 679 ntb->reg_ofs.sbar4_xlat = SOC_SBAR4XLAT_OFFSET; 680 ntb->reg_ofs.lnk_cntl = SOC_NTBCNTL_OFFSET; 681 ntb->reg_ofs.lnk_stat = SOC_LINK_STATUS_OFFSET; 682 ntb->reg_ofs.spad_local = SOC_SPAD_OFFSET; 683 ntb->reg_ofs.spci_cmd = SOC_PCICMD_OFFSET; 684 685 if (ntb->conn_type == NTB_CONN_B2B) { 686 ntb->reg_ofs.sdb = SOC_B2B_DOORBELL_OFFSET; 687 ntb->reg_ofs.spad_remote = SOC_B2B_SPAD_OFFSET; 688 ntb->limits.max_spads = SOC_MAX_SPADS; 689 } else { 690 ntb->reg_ofs.sdb = SOC_PDOORBELL_OFFSET; 691 ntb->reg_ofs.spad_remote = SOC_SPAD_OFFSET; 692 ntb->limits.max_spads = SOC_MAX_COMPAT_SPADS; 693 } 694 695 ntb->limits.max_db_bits = SOC_MAX_DB_BITS; 696 ntb->limits.msix_cnt = SOC_MSIX_CNT; 697 ntb->bits_per_vector = SOC_DB_BITS_PER_VEC; 698 699 /* 700 * FIXME - MSI-X bug on early SOC HW, remove once internal issue is 701 * resolved. Mask transaction layer internal parity errors. 702 */ 703 pci_write_config(ntb->device, 0xFC, 0x4, 4); 704 705 /* 706 * Some BIOSes aren't filling out the XLAT offsets. 707 * Check and correct the issue. 708 */ 709 if (ntb->dev_type == NTB_DEV_USD) { 710 if (ntb_read_8(SOC_PBAR2XLAT_OFFSET) == 0) 711 ntb_write_8(SOC_PBAR2XLAT_OFFSET, 712 SOC_PBAR2XLAT_USD_ADDR); 713 714 if (ntb_read_8(SOC_PBAR4XLAT_OFFSET) == 0) 715 ntb_write_8(SOC_PBAR4XLAT_OFFSET, 716 SOC_PBAR4XLAT_USD_ADDR); 717 718 if (ntb_read_8(SOC_MBAR23_OFFSET) == 0xC) 719 ntb_write_8(SOC_MBAR23_OFFSET, SOC_MBAR23_USD_ADDR); 720 721 if (ntb_read_8(SOC_MBAR45_OFFSET) == 0xC) 722 ntb_write_8(SOC_MBAR45_OFFSET, SOC_MBAR45_USD_ADDR); 723 } else { 724 if (ntb_read_8(SOC_PBAR2XLAT_OFFSET) == 0) 725 ntb_write_8(SOC_PBAR2XLAT_OFFSET, 726 SOC_PBAR2XLAT_DSD_ADDR); 727 728 if (ntb_read_8(SOC_PBAR4XLAT_OFFSET) == 0) 729 ntb_write_8(SOC_PBAR4XLAT_OFFSET, 730 SOC_PBAR4XLAT_DSD_ADDR); 731 732 if (ntb_read_8(SOC_MBAR23_OFFSET) == 0xC) 733 ntb_write_8(SOC_MBAR23_OFFSET, SOC_MBAR23_DSD_ADDR); 734 735 if (ntb_read_8(SOC_MBAR45_OFFSET) == 0xC) 736 ntb_write_8(SOC_MBAR45_OFFSET, SOC_MBAR45_DSD_ADDR); 737 } 738 739 /* Enable Bus Master and Memory Space on the secondary side */ 740 ntb_write_2(ntb->reg_ofs.spci_cmd, 741 PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN); 742 callout_reset(&ntb->heartbeat_timer, 0, ntb_handle_heartbeat, ntb); 743 744 return (0); 745} 746 747/* SOC doesn't have link status interrupt, poll on that platform */ 748static void 749ntb_handle_heartbeat(void *arg) 750{ 751 struct ntb_softc *ntb = arg; 752 uint32_t status32; 753 int rc = ntb_check_link_status(ntb); 754 755 if (rc != 0) 756 device_printf(ntb->device, 757 "Error determining link status\n"); 758 /* Check to see if a link error is the cause of the link down */ 759 if (ntb->link_status == NTB_LINK_DOWN) { 760 status32 = ntb_read_4(SOC_LTSSMSTATEJMP_OFFSET); 761 if ((status32 & SOC_LTSSMSTATEJMP_FORCEDETECT) != 0) { 762 callout_reset(&ntb->lr_timer, 0, recover_soc_link, 763 ntb); 764 return; 765 } 766 } 767 768 callout_reset(&ntb->heartbeat_timer, NTB_HB_TIMEOUT * hz, 769 ntb_handle_heartbeat, ntb); 770} 771 772static void 773soc_perform_link_restart(struct ntb_softc *ntb) 774{ 775 uint32_t status; 776 777 /* Driver resets the NTB ModPhy lanes - magic! */ 778 ntb_write_1(SOC_MODPHY_PCSREG6, 0xe0); 779 ntb_write_1(SOC_MODPHY_PCSREG4, 0x40); 780 ntb_write_1(SOC_MODPHY_PCSREG4, 0x60); 781 ntb_write_1(SOC_MODPHY_PCSREG6, 0x60); 782 783 /* Driver waits 100ms to allow the NTB ModPhy to settle */ 784 pause("ModPhy", hz / 10); 785 786 /* Clear AER Errors, write to clear */ 787 status = ntb_read_4(SOC_ERRCORSTS_OFFSET); 788 status &= PCIM_AER_COR_REPLAY_ROLLOVER; 789 ntb_write_4(SOC_ERRCORSTS_OFFSET, status); 790 791 /* Clear unexpected electrical idle event in LTSSM, write to clear */ 792 status = ntb_read_4(SOC_LTSSMERRSTS0_OFFSET); 793 status |= SOC_LTSSMERRSTS0_UNEXPECTEDEI; 794 ntb_write_4(SOC_LTSSMERRSTS0_OFFSET, status); 795 796 /* Clear DeSkew Buffer error, write to clear */ 797 status = ntb_read_4(SOC_DESKEWSTS_OFFSET); 798 status |= SOC_DESKEWSTS_DBERR; 799 ntb_write_4(SOC_DESKEWSTS_OFFSET, status); 800 801 status = ntb_read_4(SOC_IBSTERRRCRVSTS0_OFFSET); 802 status &= SOC_IBIST_ERR_OFLOW; 803 ntb_write_4(SOC_IBSTERRRCRVSTS0_OFFSET, status); 804 805 /* Releases the NTB state machine to allow the link to retrain */ 806 status = ntb_read_4(SOC_LTSSMSTATEJMP_OFFSET); 807 status &= ~SOC_LTSSMSTATEJMP_FORCEDETECT; 808 ntb_write_4(SOC_LTSSMSTATEJMP_OFFSET, status); 809} 810 811static void 812ntb_handle_link_event(struct ntb_softc *ntb, int link_state) 813{ 814 enum ntb_hw_event event; 815 uint16_t status; 816 817 if (ntb->link_status == link_state) 818 return; 819 820 if (link_state == NTB_LINK_UP) { 821 device_printf(ntb->device, "Link Up\n"); 822 ntb->link_status = NTB_LINK_UP; 823 event = NTB_EVENT_HW_LINK_UP; 824 825 if (ntb->type == NTB_SOC) 826 status = ntb_read_2(ntb->reg_ofs.lnk_stat); 827 else 828 status = pci_read_config(ntb->device, 829 XEON_LINK_STATUS_OFFSET, 2); 830 ntb->link_width = (status & NTB_LINK_WIDTH_MASK) >> 4; 831 ntb->link_speed = (status & NTB_LINK_SPEED_MASK); 832 device_printf(ntb->device, "Link Width %d, Link Speed %d\n", 833 ntb->link_width, ntb->link_speed); 834 callout_reset(&ntb->heartbeat_timer, NTB_HB_TIMEOUT * hz, 835 ntb_handle_heartbeat, ntb); 836 } else { 837 device_printf(ntb->device, "Link Down\n"); 838 ntb->link_status = NTB_LINK_DOWN; 839 event = NTB_EVENT_HW_LINK_DOWN; 840 /* Don't modify link width/speed, we need it in link recovery */ 841 } 842 843 /* notify the upper layer if we have an event change */ 844 if (ntb->event_cb != NULL) 845 ntb->event_cb(ntb->ntb_transport, event); 846} 847 848static void 849recover_soc_link(void *arg) 850{ 851 struct ntb_softc *ntb = arg; 852 uint8_t speed, width; 853 uint32_t status32; 854 uint16_t status16; 855 856 soc_perform_link_restart(ntb); 857 pause("Link", SOC_LINK_RECOVERY_TIME * hz / 1000); 858 859 status32 = ntb_read_4(SOC_LTSSMSTATEJMP_OFFSET); 860 if ((status32 & SOC_LTSSMSTATEJMP_FORCEDETECT) != 0) 861 goto retry; 862 863 status32 = ntb_read_4(SOC_IBSTERRRCRVSTS0_OFFSET); 864 if ((status32 & SOC_IBIST_ERR_OFLOW) != 0) 865 goto retry; 866 867 status16 = ntb_read_2(ntb->reg_ofs.lnk_stat); 868 width = (status16 & NTB_LINK_WIDTH_MASK) >> 4; 869 speed = (status16 & NTB_LINK_SPEED_MASK); 870 if (ntb->link_width != width || ntb->link_speed != speed) 871 goto retry; 872 873 callout_reset(&ntb->heartbeat_timer, NTB_HB_TIMEOUT * hz, 874 ntb_handle_heartbeat, ntb); 875 return; 876 877retry: 878 callout_reset(&ntb->lr_timer, NTB_HB_TIMEOUT * hz, recover_soc_link, 879 ntb); 880} 881 882static int 883ntb_check_link_status(struct ntb_softc *ntb) 884{ 885 int link_state; 886 uint32_t ntb_cntl; 887 uint16_t status; 888 889 if (ntb->type == NTB_SOC) { 890 ntb_cntl = ntb_read_4(ntb->reg_ofs.lnk_cntl); 891 if ((ntb_cntl & SOC_CNTL_LINK_DOWN) != 0) 892 link_state = NTB_LINK_DOWN; 893 else 894 link_state = NTB_LINK_UP; 895 } else { 896 status = pci_read_config(ntb->device, XEON_LINK_STATUS_OFFSET, 897 2); 898 899 if ((status & NTB_LINK_STATUS_ACTIVE) != 0) 900 link_state = NTB_LINK_UP; 901 else 902 link_state = NTB_LINK_DOWN; 903 } 904 905 ntb_handle_link_event(ntb, link_state); 906 907 return (0); 908} 909 910/** 911 * ntb_register_event_callback() - register event callback 912 * @ntb: pointer to ntb_softc instance 913 * @func: callback function to register 914 * 915 * This function registers a callback for any HW driver events such as link 916 * up/down, power management notices and etc. 917 * 918 * RETURNS: An appropriate -ERRNO error value on error, or zero for success. 919 */ 920int 921ntb_register_event_callback(struct ntb_softc *ntb, ntb_event_callback func) 922{ 923 924 if (ntb->event_cb != NULL) 925 return (EINVAL); 926 927 ntb->event_cb = func; 928 929 return (0); 930} 931 932/** 933 * ntb_unregister_event_callback() - unregisters the event callback 934 * @ntb: pointer to ntb_softc instance 935 * 936 * This function unregisters the existing callback from transport 937 */ 938void 939ntb_unregister_event_callback(struct ntb_softc *ntb) 940{ 941 942 ntb->event_cb = NULL; 943} 944 945/** 946 * ntb_register_db_callback() - register a callback for doorbell interrupt 947 * @ntb: pointer to ntb_softc instance 948 * @idx: doorbell index to register callback, zero based 949 * @func: callback function to register 950 * 951 * This function registers a callback function for the doorbell interrupt 952 * on the primary side. The function will unmask the doorbell as well to 953 * allow interrupt. 954 * 955 * RETURNS: An appropriate -ERRNO error value on error, or zero for success. 956 */ 957int 958ntb_register_db_callback(struct ntb_softc *ntb, unsigned int idx, void *data, 959 ntb_db_callback func) 960{ 961 uint16_t mask; 962 963 if (idx >= ntb->allocated_interrupts || ntb->db_cb[idx].callback) { 964 device_printf(ntb->device, "Invalid Index.\n"); 965 return (EINVAL); 966 } 967 968 ntb->db_cb[idx].callback = func; 969 ntb->db_cb[idx].data = data; 970 971 /* unmask interrupt */ 972 mask = ntb_read_2(ntb->reg_ofs.pdb_mask); 973 mask &= ~(1 << (idx * ntb->bits_per_vector)); 974 ntb_write_2(ntb->reg_ofs.pdb_mask, mask); 975 976 return (0); 977} 978 979/** 980 * ntb_unregister_db_callback() - unregister a callback for doorbell interrupt 981 * @ntb: pointer to ntb_softc instance 982 * @idx: doorbell index to register callback, zero based 983 * 984 * This function unregisters a callback function for the doorbell interrupt 985 * on the primary side. The function will also mask the said doorbell. 986 */ 987void 988ntb_unregister_db_callback(struct ntb_softc *ntb, unsigned int idx) 989{ 990 unsigned long mask; 991 992 if (idx >= ntb->allocated_interrupts || !ntb->db_cb[idx].callback) 993 return; 994 995 mask = ntb_read_2(ntb->reg_ofs.pdb_mask); 996 mask |= 1 << (idx * ntb->bits_per_vector); 997 ntb_write_2(ntb->reg_ofs.pdb_mask, mask); 998 999 ntb->db_cb[idx].callback = NULL; 1000} 1001 1002/** 1003 * ntb_find_transport() - find the transport pointer 1004 * @transport: pointer to pci device 1005 * 1006 * Given the pci device pointer, return the transport pointer passed in when 1007 * the transport attached when it was inited. 1008 * 1009 * RETURNS: pointer to transport. 1010 */ 1011void * 1012ntb_find_transport(struct ntb_softc *ntb) 1013{ 1014 1015 return (ntb->ntb_transport); 1016} 1017 1018/** 1019 * ntb_register_transport() - Register NTB transport with NTB HW driver 1020 * @transport: transport identifier 1021 * 1022 * This function allows a transport to reserve the hardware driver for 1023 * NTB usage. 1024 * 1025 * RETURNS: pointer to ntb_softc, NULL on error. 1026 */ 1027struct ntb_softc * 1028ntb_register_transport(struct ntb_softc *ntb, void *transport) 1029{ 1030 1031 /* 1032 * TODO: when we have more than one transport, we will need to rewrite 1033 * this to prevent race conditions 1034 */ 1035 if (ntb->ntb_transport != NULL) 1036 return (NULL); 1037 1038 ntb->ntb_transport = transport; 1039 return (ntb); 1040} 1041 1042/** 1043 * ntb_unregister_transport() - Unregister the transport with the NTB HW driver 1044 * @ntb - ntb_softc of the transport to be freed 1045 * 1046 * This function unregisters the transport from the HW driver and performs any 1047 * necessary cleanups. 1048 */ 1049void 1050ntb_unregister_transport(struct ntb_softc *ntb) 1051{ 1052 int i; 1053 1054 if (ntb->ntb_transport == NULL) 1055 return; 1056 1057 for (i = 0; i < ntb->allocated_interrupts; i++) 1058 ntb_unregister_db_callback(ntb, i); 1059 1060 ntb_unregister_event_callback(ntb); 1061 ntb->ntb_transport = NULL; 1062} 1063 1064/** 1065 * ntb_get_max_spads() - get the total scratch regs usable 1066 * @ntb: pointer to ntb_softc instance 1067 * 1068 * This function returns the max 32bit scratchpad registers usable by the 1069 * upper layer. 1070 * 1071 * RETURNS: total number of scratch pad registers available 1072 */ 1073int 1074ntb_get_max_spads(struct ntb_softc *ntb) 1075{ 1076 1077 return (ntb->limits.max_spads); 1078} 1079 1080/** 1081 * ntb_write_local_spad() - write to the secondary scratchpad register 1082 * @ntb: pointer to ntb_softc instance 1083 * @idx: index to the scratchpad register, 0 based 1084 * @val: the data value to put into the register 1085 * 1086 * This function allows writing of a 32bit value to the indexed scratchpad 1087 * register. The register resides on the secondary (external) side. 1088 * 1089 * RETURNS: An appropriate -ERRNO error value on error, or zero for success. 1090 */ 1091int 1092ntb_write_local_spad(struct ntb_softc *ntb, unsigned int idx, uint32_t val) 1093{ 1094 1095 if (idx >= ntb->limits.max_spads) 1096 return (EINVAL); 1097 1098 ntb_write_4(ntb->reg_ofs.spad_local + idx * 4, val); 1099 1100 return (0); 1101} 1102 1103/** 1104 * ntb_read_local_spad() - read from the primary scratchpad register 1105 * @ntb: pointer to ntb_softc instance 1106 * @idx: index to scratchpad register, 0 based 1107 * @val: pointer to 32bit integer for storing the register value 1108 * 1109 * This function allows reading of the 32bit scratchpad register on 1110 * the primary (internal) side. 1111 * 1112 * RETURNS: An appropriate -ERRNO error value on error, or zero for success. 1113 */ 1114int 1115ntb_read_local_spad(struct ntb_softc *ntb, unsigned int idx, uint32_t *val) 1116{ 1117 1118 if (idx >= ntb->limits.max_spads) 1119 return (EINVAL); 1120 1121 *val = ntb_read_4(ntb->reg_ofs.spad_local + idx * 4); 1122 1123 return (0); 1124} 1125 1126/** 1127 * ntb_write_remote_spad() - write to the secondary scratchpad register 1128 * @ntb: pointer to ntb_softc instance 1129 * @idx: index to the scratchpad register, 0 based 1130 * @val: the data value to put into the register 1131 * 1132 * This function allows writing of a 32bit value to the indexed scratchpad 1133 * register. The register resides on the secondary (external) side. 1134 * 1135 * RETURNS: An appropriate -ERRNO error value on error, or zero for success. 1136 */ 1137int 1138ntb_write_remote_spad(struct ntb_softc *ntb, unsigned int idx, uint32_t val) 1139{ 1140 1141 if (idx >= ntb->limits.max_spads) 1142 return (EINVAL); 1143 1144 ntb_write_4(ntb->reg_ofs.spad_remote + idx * 4, val); 1145 1146 return (0); 1147} 1148 1149/** 1150 * ntb_read_remote_spad() - read from the primary scratchpad register 1151 * @ntb: pointer to ntb_softc instance 1152 * @idx: index to scratchpad register, 0 based 1153 * @val: pointer to 32bit integer for storing the register value 1154 * 1155 * This function allows reading of the 32bit scratchpad register on 1156 * the primary (internal) side. 1157 * 1158 * RETURNS: An appropriate -ERRNO error value on error, or zero for success. 1159 */ 1160int 1161ntb_read_remote_spad(struct ntb_softc *ntb, unsigned int idx, uint32_t *val) 1162{ 1163 1164 if (idx >= ntb->limits.max_spads) 1165 return (EINVAL); 1166 1167 *val = ntb_read_4(ntb->reg_ofs.spad_remote + idx * 4); 1168 1169 return (0); 1170} 1171 1172/** 1173 * ntb_get_mw_vbase() - get virtual addr for the NTB memory window 1174 * @ntb: pointer to ntb_softc instance 1175 * @mw: memory window number 1176 * 1177 * This function provides the base virtual address of the memory window 1178 * specified. 1179 * 1180 * RETURNS: pointer to virtual address, or NULL on error. 1181 */ 1182void * 1183ntb_get_mw_vbase(struct ntb_softc *ntb, unsigned int mw) 1184{ 1185 1186 if (mw >= NTB_NUM_MW) 1187 return (NULL); 1188 1189 return (ntb->bar_info[NTB_MW_TO_BAR(mw)].vbase); 1190} 1191 1192vm_paddr_t 1193ntb_get_mw_pbase(struct ntb_softc *ntb, unsigned int mw) 1194{ 1195 1196 if (mw >= NTB_NUM_MW) 1197 return (0); 1198 1199 return (ntb->bar_info[NTB_MW_TO_BAR(mw)].pbase); 1200} 1201 1202/** 1203 * ntb_get_mw_size() - return size of NTB memory window 1204 * @ntb: pointer to ntb_softc instance 1205 * @mw: memory window number 1206 * 1207 * This function provides the physical size of the memory window specified 1208 * 1209 * RETURNS: the size of the memory window or zero on error 1210 */ 1211u_long 1212ntb_get_mw_size(struct ntb_softc *ntb, unsigned int mw) 1213{ 1214 1215 if (mw >= NTB_NUM_MW) 1216 return (0); 1217 1218 return (ntb->bar_info[NTB_MW_TO_BAR(mw)].size); 1219} 1220 1221/** 1222 * ntb_set_mw_addr - set the memory window address 1223 * @ntb: pointer to ntb_softc instance 1224 * @mw: memory window number 1225 * @addr: base address for data 1226 * 1227 * This function sets the base physical address of the memory window. This 1228 * memory address is where data from the remote system will be transfered into 1229 * or out of depending on how the transport is configured. 1230 */ 1231void 1232ntb_set_mw_addr(struct ntb_softc *ntb, unsigned int mw, uint64_t addr) 1233{ 1234 1235 if (mw >= NTB_NUM_MW) 1236 return; 1237 1238 switch (NTB_MW_TO_BAR(mw)) { 1239 case NTB_B2B_BAR_1: 1240 ntb_write_8(ntb->reg_ofs.sbar2_xlat, addr); 1241 break; 1242 case NTB_B2B_BAR_2: 1243 ntb_write_8(ntb->reg_ofs.sbar4_xlat, addr); 1244 break; 1245 } 1246} 1247 1248/** 1249 * ntb_ring_sdb() - Set the doorbell on the secondary/external side 1250 * @ntb: pointer to ntb_softc instance 1251 * @db: doorbell to ring 1252 * 1253 * This function allows triggering of a doorbell on the secondary/external 1254 * side that will initiate an interrupt on the remote host 1255 * 1256 * RETURNS: An appropriate -ERRNO error value on error, or zero for success. 1257 */ 1258void 1259ntb_ring_sdb(struct ntb_softc *ntb, unsigned int db) 1260{ 1261 1262 if (ntb->type == NTB_SOC) 1263 ntb_write_8(ntb->reg_ofs.sdb, (uint64_t) 1 << db); 1264 else 1265 ntb_write_2(ntb->reg_ofs.sdb, 1266 ((1 << ntb->bits_per_vector) - 1) << 1267 (db * ntb->bits_per_vector)); 1268} 1269 1270/** 1271 * ntb_query_link_status() - return the hardware link status 1272 * @ndev: pointer to ntb_device instance 1273 * 1274 * Returns true if the hardware is connected to the remote system 1275 * 1276 * RETURNS: true or false based on the hardware link state 1277 */ 1278bool 1279ntb_query_link_status(struct ntb_softc *ntb) 1280{ 1281 1282 return (ntb->link_status == NTB_LINK_UP); 1283} 1284 1285static bool 1286is_bar_for_data_transfer(int bar_num) 1287{ 1288 if ((bar_num > NTB_CONFIG_BAR) && (bar_num < NTB_MAX_BARS)) 1289 return true; 1290 else 1291 return false; 1292} 1293 1294device_t ntb_get_device(struct ntb_softc *ntb) 1295{ 1296 1297 return (ntb->device); 1298} 1299