Something went wrong. Try again.
(I'm so sorry!) Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318/* * This file is provided under a dual BSD/GPLv2 license. When using or * redistributing this file, you may do so under either license. * * GPL LICENSE SUMMARY * * Copyright (C) 2015 EMC Corporation. All Rights Reserved. * Copyright (C) 2016 T-Platforms. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * BSD LICENSE * * Copyright (C) 2015 EMC Corporation. All Rights Reserved. * Copyright (C) 2016 T-Platforms. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copy * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * PCIe NTB Linux driver * * Contact Information: * Allen Hubbe <Allen.Hubbe@emc.com> */
#include <linux/device.h>#include <linux/kernel.h>#include <linux/module.h>
#include <linux/ntb.h>#include <linux/pci.h>
#define DRIVER_NAME "ntb"#define DRIVER_DESCRIPTION "PCIe NTB Driver Framework"
#define DRIVER_VERSION "1.0"#define DRIVER_RELDATE "24 March 2015"#define DRIVER_AUTHOR "Allen Hubbe <Allen.Hubbe@emc.com>"
MODULE_LICENSE("Dual BSD/GPL");MODULE_VERSION(DRIVER_VERSION);MODULE_AUTHOR(DRIVER_AUTHOR);MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
static const struct bus_type ntb_bus;static void ntb_dev_release(struct device *dev);
int __ntb_register_client(struct ntb_client *client, struct module *mod, const char *mod_name){ if (!client) return -EINVAL; if (!ntb_client_ops_is_valid(&client->ops)) return -EINVAL;
memset(&client->drv, 0, sizeof(client->drv)); client->drv.bus = &ntb_bus; client->drv.name = mod_name; client->drv.owner = mod;
return driver_register(&client->drv);}EXPORT_SYMBOL(__ntb_register_client);
void ntb_unregister_client(struct ntb_client *client){ driver_unregister(&client->drv);}EXPORT_SYMBOL(ntb_unregister_client);
int ntb_register_device(struct ntb_dev *ntb){ int ret;
if (!ntb) return -EINVAL; if (!ntb->pdev) return -EINVAL; if (!ntb->ops) return -EINVAL; if (!ntb_dev_ops_is_valid(ntb->ops)) return -EINVAL;
init_completion(&ntb->released);
ntb->dev.bus = &ntb_bus; ntb->dev.parent = &ntb->pdev->dev; ntb->dev.release = ntb_dev_release; dev_set_name(&ntb->dev, "%s", pci_name(ntb->pdev));
ntb->ctx = NULL; ntb->ctx_ops = NULL; spin_lock_init(&ntb->ctx_lock);
ret = device_register(&ntb->dev); if (ret) put_device(&ntb->dev);
return ret;}EXPORT_SYMBOL(ntb_register_device);
void ntb_unregister_device(struct ntb_dev *ntb){ device_unregister(&ntb->dev); wait_for_completion(&ntb->released);}EXPORT_SYMBOL(ntb_unregister_device);
int ntb_set_ctx(struct ntb_dev *ntb, void *ctx, const struct ntb_ctx_ops *ctx_ops){ unsigned long irqflags;
if (!ntb_ctx_ops_is_valid(ctx_ops)) return -EINVAL; if (ntb->ctx_ops) return -EINVAL;
spin_lock_irqsave(&ntb->ctx_lock, irqflags); { ntb->ctx = ctx; ntb->ctx_ops = ctx_ops; } spin_unlock_irqrestore(&ntb->ctx_lock, irqflags);
return 0;}EXPORT_SYMBOL(ntb_set_ctx);
void ntb_clear_ctx(struct ntb_dev *ntb){ unsigned long irqflags;
spin_lock_irqsave(&ntb->ctx_lock, irqflags); { ntb->ctx_ops = NULL; ntb->ctx = NULL; } spin_unlock_irqrestore(&ntb->ctx_lock, irqflags);}EXPORT_SYMBOL(ntb_clear_ctx);
void ntb_link_event(struct ntb_dev *ntb){ unsigned long irqflags;
spin_lock_irqsave(&ntb->ctx_lock, irqflags); { if (ntb->ctx_ops && ntb->ctx_ops->link_event) ntb->ctx_ops->link_event(ntb->ctx); } spin_unlock_irqrestore(&ntb->ctx_lock, irqflags);}EXPORT_SYMBOL(ntb_link_event);
void ntb_db_event(struct ntb_dev *ntb, int vector){ unsigned long irqflags;
spin_lock_irqsave(&ntb->ctx_lock, irqflags); { if (ntb->ctx_ops && ntb->ctx_ops->db_event) ntb->ctx_ops->db_event(ntb->ctx, vector); } spin_unlock_irqrestore(&ntb->ctx_lock, irqflags);}EXPORT_SYMBOL(ntb_db_event);
void ntb_msg_event(struct ntb_dev *ntb){ unsigned long irqflags;
spin_lock_irqsave(&ntb->ctx_lock, irqflags); { if (ntb->ctx_ops && ntb->ctx_ops->msg_event) ntb->ctx_ops->msg_event(ntb->ctx); } spin_unlock_irqrestore(&ntb->ctx_lock, irqflags);}EXPORT_SYMBOL(ntb_msg_event);
int ntb_default_port_number(struct ntb_dev *ntb){ switch (ntb->topo) { case NTB_TOPO_PRI: case NTB_TOPO_B2B_USD: return NTB_PORT_PRI_USD; case NTB_TOPO_SEC: case NTB_TOPO_B2B_DSD: return NTB_PORT_SEC_DSD; default: return 0; }}EXPORT_SYMBOL(ntb_default_port_number);
int ntb_default_peer_port_count(struct ntb_dev *ntb){ return NTB_DEF_PEER_CNT;}EXPORT_SYMBOL(ntb_default_peer_port_count);
int ntb_default_peer_port_number(struct ntb_dev *ntb, int pidx){ if (pidx != NTB_DEF_PEER_IDX) return -EINVAL;
switch (ntb->topo) { case NTB_TOPO_PRI: case NTB_TOPO_B2B_USD: return NTB_PORT_SEC_DSD; case NTB_TOPO_SEC: case NTB_TOPO_B2B_DSD: return NTB_PORT_PRI_USD; default: return 0; }}EXPORT_SYMBOL(ntb_default_peer_port_number);
int ntb_default_peer_port_idx(struct ntb_dev *ntb, int port){ int peer_port = ntb_default_peer_port_number(ntb, NTB_DEF_PEER_IDX);
if (peer_port == -EINVAL || port != peer_port) return -EINVAL;
return 0;}EXPORT_SYMBOL(ntb_default_peer_port_idx);
static int ntb_probe(struct device *dev){ struct ntb_dev *ntb; struct ntb_client *client; int rc;
get_device(dev); ntb = dev_ntb(dev); client = drv_ntb_client(dev->driver);
rc = client->ops.probe(client, ntb); if (rc) put_device(dev);
return rc;}
static void ntb_remove(struct device *dev){ struct ntb_dev *ntb; struct ntb_client *client;
if (dev->driver) { ntb = dev_ntb(dev); client = drv_ntb_client(dev->driver);
client->ops.remove(client, ntb); put_device(dev); }}
static void ntb_dev_release(struct device *dev){ struct ntb_dev *ntb = dev_ntb(dev);
complete(&ntb->released);}
static const struct bus_type ntb_bus = { .name = "ntb", .probe = ntb_probe, .remove = ntb_remove,};
static int __init ntb_driver_init(void){ return bus_register(&ntb_bus);}module_init(ntb_driver_init);
static void __exit ntb_driver_exit(void){ bus_unregister(&ntb_bus);}module_exit(ntb_driver_exit);