static int pp_check_ntb(struct ntb_dev *ntb) { u64 pmask; if (ntb_db_is_unsafe(ntb)) { dev_dbg(&ntb->dev, "Doorbell is unsafe\n"); if (!unsafe) return -EINVAL; } if (ntb_spad_is_unsafe(ntb)) { dev_dbg(&ntb->dev, "Scratchpad is unsafe\n"); if (!unsafe) return -EINVAL; } pmask = GENMASK_ULL(ntb_peer_port_count(ntb), 0); if ((ntb_db_valid_mask(ntb) & pmask) != pmask) { dev_err(&ntb->dev, "Unsupported DB configuration\n"); return -EINVAL; } if (ntb_spad_count(ntb) < 1 && ntb_msg_count(ntb) < 1) { dev_err(&ntb->dev, "Scratchpads and messages unsupported\n"); return -EINVAL; } else if (ntb_spad_count(ntb) < 1) { dev_dbg(&ntb->dev, "Scratchpads unsupported\n"); } else if (ntb_msg_count(ntb) < 1) { dev_dbg(&ntb->dev, "Messages unsupported\n"); } return 0; }
static int perf_probe(struct ntb_client *client, struct ntb_dev *ntb) { struct pci_dev *pdev = ntb->pdev; struct perf_ctx *perf; int node; int rc = 0; if (ntb_spad_count(ntb) < MAX_SPAD) { dev_err(&ntb->dev, "Not enough scratch pad registers for %s", DRIVER_NAME); return -EIO; } node = dev_to_node(&pdev->dev); perf = kzalloc_node(sizeof(*perf), GFP_KERNEL, node); if (!perf) { rc = -ENOMEM; goto err_perf; } perf->ntb = ntb; perf->perf_threads = 1; atomic_set(&perf->tsync, 0); mutex_init(&perf->run_mutex); spin_lock_init(&perf->db_lock); perf_setup_mw(ntb, perf); init_waitqueue_head(&perf->link_wq); INIT_DELAYED_WORK(&perf->link_work, perf_link_work); rc = ntb_set_ctx(ntb, perf, &perf_ops); if (rc) goto err_ctx; perf->link_is_up = false; ntb_link_enable(ntb, NTB_SPEED_AUTO, NTB_WIDTH_AUTO); ntb_link_event(ntb); rc = perf_debugfs_setup(perf); if (rc) goto err_ctx; perf_clear_thread_status(perf); return 0; err_ctx: cancel_delayed_work_sync(&perf->link_work); kfree(perf); err_perf: return rc; }
static ssize_t tool_spadfn_read(struct tool_ctx *tc, char __user *ubuf, size_t size, loff_t *offp, u32 (*spad_read_fn)(struct ntb_dev *, int)) { size_t buf_size; char *buf; ssize_t pos, rc; int i, spad_count; if (!spad_read_fn) return -EINVAL; spad_count = ntb_spad_count(tc->ntb); /* * We multiply the number of spads by 15 to get the buffer size * this is from 3 for the %d, 10 for the largest hex value * (0x00000000) and 2 for the tab and line feed. */ buf_size = min_t(size_t, size, spad_count * 15); buf = kmalloc(buf_size, GFP_KERNEL); if (!buf) return -ENOMEM; pos = 0; for (i = 0; i < spad_count; ++i) { pos += scnprintf(buf + pos, buf_size - pos, "%d\t%#x\n", i, spad_read_fn(tc->ntb, i)); } rc = simple_read_from_buffer(ubuf, size, offp, buf, pos); kfree(buf); return rc; }
static int tool_probe(struct ntb_client *self, struct ntb_dev *ntb) { struct tool_ctx *tc; int rc; int i; if (!ntb->ops->mw_set_trans) { dev_dbg(&ntb->dev, "need inbound MW based NTB API\n"); rc = -EINVAL; goto err_tc; } if (ntb_spad_count(ntb) < 1) { dev_dbg(&ntb->dev, "no enough scratchpads\n"); rc = -EINVAL; goto err_tc; } if (ntb_db_is_unsafe(ntb)) dev_dbg(&ntb->dev, "doorbell is unsafe\n"); if (ntb_spad_is_unsafe(ntb)) dev_dbg(&ntb->dev, "scratchpad is unsafe\n"); if (ntb_peer_port_count(ntb) != NTB_DEF_PEER_CNT) dev_warn(&ntb->dev, "multi-port NTB is unsupported\n"); tc = kzalloc(sizeof(*tc), GFP_KERNEL); if (!tc) { rc = -ENOMEM; goto err_tc; } tc->ntb = ntb; init_waitqueue_head(&tc->link_wq); tc->mw_count = min(ntb_peer_mw_count(tc->ntb), MAX_MWS); for (i = 0; i < tc->mw_count; i++) { rc = tool_init_mw(tc, i); if (rc) goto err_ctx; } tool_setup_dbgfs(tc); rc = ntb_set_ctx(ntb, tc, &tool_ops); if (rc) goto err_ctx; ntb_link_enable(ntb, NTB_SPEED_AUTO, NTB_WIDTH_AUTO); ntb_link_event(ntb); return 0; err_ctx: tool_free_mws(tc); debugfs_remove_recursive(tc->dbgfs); kfree(tc); err_tc: return rc; }