Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * This file is provided under a dual BSD/GPLv2 license.  When using or
0003  *   redistributing this file, you may do so under either license.
0004  *
0005  *   GPL LICENSE SUMMARY
0006  *
0007  *   Copyright (C) 2015 EMC Corporation. All Rights Reserved.
0008  *   Copyright (C) 2016 T-Platforms. All Rights Reserved.
0009  *
0010  *   This program is free software; you can redistribute it and/or modify
0011  *   it under the terms of version 2 of the GNU General Public License as
0012  *   published by the Free Software Foundation.
0013  *
0014  *   This program is distributed in the hope that it will be useful, but
0015  *   WITHOUT ANY WARRANTY; without even the implied warranty of
0016  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0017  *   General Public License for more details.
0018  *
0019  *   BSD LICENSE
0020  *
0021  *   Copyright (C) 2015 EMC Corporation. All Rights Reserved.
0022  *   Copyright (C) 2016 T-Platforms. All Rights Reserved.
0023  *
0024  *   Redistribution and use in source and binary forms, with or without
0025  *   modification, are permitted provided that the following conditions
0026  *   are met:
0027  *
0028  *     * Redistributions of source code must retain the above copyright
0029  *       notice, this list of conditions and the following disclaimer.
0030  *     * Redistributions in binary form must reproduce the above copy
0031  *       notice, this list of conditions and the following disclaimer in
0032  *       the documentation and/or other materials provided with the
0033  *       distribution.
0034  *     * Neither the name of Intel Corporation nor the names of its
0035  *       contributors may be used to endorse or promote products derived
0036  *       from this software without specific prior written permission.
0037  *
0038  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0039  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0040  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0041  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0042  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0043  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0044  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0045  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0046  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0047  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0048  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0049  *
0050  * PCIe NTB Linux driver
0051  *
0052  * Contact Information:
0053  * Allen Hubbe <Allen.Hubbe@emc.com>
0054  */
0055 
0056 #include <linux/device.h>
0057 #include <linux/kernel.h>
0058 #include <linux/module.h>
0059 
0060 #include <linux/ntb.h>
0061 #include <linux/pci.h>
0062 
0063 #define DRIVER_NAME         "ntb"
0064 #define DRIVER_DESCRIPTION      "PCIe NTB Driver Framework"
0065 
0066 #define DRIVER_VERSION          "1.0"
0067 #define DRIVER_RELDATE          "24 March 2015"
0068 #define DRIVER_AUTHOR           "Allen Hubbe <Allen.Hubbe@emc.com>"
0069 
0070 MODULE_LICENSE("Dual BSD/GPL");
0071 MODULE_VERSION(DRIVER_VERSION);
0072 MODULE_AUTHOR(DRIVER_AUTHOR);
0073 MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
0074 
0075 static struct bus_type ntb_bus;
0076 static void ntb_dev_release(struct device *dev);
0077 
0078 int __ntb_register_client(struct ntb_client *client, struct module *mod,
0079               const char *mod_name)
0080 {
0081     if (!client)
0082         return -EINVAL;
0083     if (!ntb_client_ops_is_valid(&client->ops))
0084         return -EINVAL;
0085 
0086     memset(&client->drv, 0, sizeof(client->drv));
0087     client->drv.bus = &ntb_bus;
0088     client->drv.name = mod_name;
0089     client->drv.owner = mod;
0090 
0091     return driver_register(&client->drv);
0092 }
0093 EXPORT_SYMBOL(__ntb_register_client);
0094 
0095 void ntb_unregister_client(struct ntb_client *client)
0096 {
0097     driver_unregister(&client->drv);
0098 }
0099 EXPORT_SYMBOL(ntb_unregister_client);
0100 
0101 int ntb_register_device(struct ntb_dev *ntb)
0102 {
0103     if (!ntb)
0104         return -EINVAL;
0105     if (!ntb->pdev)
0106         return -EINVAL;
0107     if (!ntb->ops)
0108         return -EINVAL;
0109     if (!ntb_dev_ops_is_valid(ntb->ops))
0110         return -EINVAL;
0111 
0112     init_completion(&ntb->released);
0113 
0114     ntb->dev.bus = &ntb_bus;
0115     ntb->dev.parent = &ntb->pdev->dev;
0116     ntb->dev.release = ntb_dev_release;
0117     dev_set_name(&ntb->dev, "%s", pci_name(ntb->pdev));
0118 
0119     ntb->ctx = NULL;
0120     ntb->ctx_ops = NULL;
0121     spin_lock_init(&ntb->ctx_lock);
0122 
0123     return device_register(&ntb->dev);
0124 }
0125 EXPORT_SYMBOL(ntb_register_device);
0126 
0127 void ntb_unregister_device(struct ntb_dev *ntb)
0128 {
0129     device_unregister(&ntb->dev);
0130     wait_for_completion(&ntb->released);
0131 }
0132 EXPORT_SYMBOL(ntb_unregister_device);
0133 
0134 int ntb_set_ctx(struct ntb_dev *ntb, void *ctx,
0135         const struct ntb_ctx_ops *ctx_ops)
0136 {
0137     unsigned long irqflags;
0138 
0139     if (!ntb_ctx_ops_is_valid(ctx_ops))
0140         return -EINVAL;
0141     if (ntb->ctx_ops)
0142         return -EINVAL;
0143 
0144     spin_lock_irqsave(&ntb->ctx_lock, irqflags);
0145     {
0146         ntb->ctx = ctx;
0147         ntb->ctx_ops = ctx_ops;
0148     }
0149     spin_unlock_irqrestore(&ntb->ctx_lock, irqflags);
0150 
0151     return 0;
0152 }
0153 EXPORT_SYMBOL(ntb_set_ctx);
0154 
0155 void ntb_clear_ctx(struct ntb_dev *ntb)
0156 {
0157     unsigned long irqflags;
0158 
0159     spin_lock_irqsave(&ntb->ctx_lock, irqflags);
0160     {
0161         ntb->ctx_ops = NULL;
0162         ntb->ctx = NULL;
0163     }
0164     spin_unlock_irqrestore(&ntb->ctx_lock, irqflags);
0165 }
0166 EXPORT_SYMBOL(ntb_clear_ctx);
0167 
0168 void ntb_link_event(struct ntb_dev *ntb)
0169 {
0170     unsigned long irqflags;
0171 
0172     spin_lock_irqsave(&ntb->ctx_lock, irqflags);
0173     {
0174         if (ntb->ctx_ops && ntb->ctx_ops->link_event)
0175             ntb->ctx_ops->link_event(ntb->ctx);
0176     }
0177     spin_unlock_irqrestore(&ntb->ctx_lock, irqflags);
0178 }
0179 EXPORT_SYMBOL(ntb_link_event);
0180 
0181 void ntb_db_event(struct ntb_dev *ntb, int vector)
0182 {
0183     unsigned long irqflags;
0184 
0185     spin_lock_irqsave(&ntb->ctx_lock, irqflags);
0186     {
0187         if (ntb->ctx_ops && ntb->ctx_ops->db_event)
0188             ntb->ctx_ops->db_event(ntb->ctx, vector);
0189     }
0190     spin_unlock_irqrestore(&ntb->ctx_lock, irqflags);
0191 }
0192 EXPORT_SYMBOL(ntb_db_event);
0193 
0194 void ntb_msg_event(struct ntb_dev *ntb)
0195 {
0196     unsigned long irqflags;
0197 
0198     spin_lock_irqsave(&ntb->ctx_lock, irqflags);
0199     {
0200         if (ntb->ctx_ops && ntb->ctx_ops->msg_event)
0201             ntb->ctx_ops->msg_event(ntb->ctx);
0202     }
0203     spin_unlock_irqrestore(&ntb->ctx_lock, irqflags);
0204 }
0205 EXPORT_SYMBOL(ntb_msg_event);
0206 
0207 int ntb_default_port_number(struct ntb_dev *ntb)
0208 {
0209     switch (ntb->topo) {
0210     case NTB_TOPO_PRI:
0211     case NTB_TOPO_B2B_USD:
0212         return NTB_PORT_PRI_USD;
0213     case NTB_TOPO_SEC:
0214     case NTB_TOPO_B2B_DSD:
0215         return NTB_PORT_SEC_DSD;
0216     default:
0217         return 0;
0218     }
0219 }
0220 EXPORT_SYMBOL(ntb_default_port_number);
0221 
0222 int ntb_default_peer_port_count(struct ntb_dev *ntb)
0223 {
0224     return NTB_DEF_PEER_CNT;
0225 }
0226 EXPORT_SYMBOL(ntb_default_peer_port_count);
0227 
0228 int ntb_default_peer_port_number(struct ntb_dev *ntb, int pidx)
0229 {
0230     if (pidx != NTB_DEF_PEER_IDX)
0231         return -EINVAL;
0232 
0233     switch (ntb->topo) {
0234     case NTB_TOPO_PRI:
0235     case NTB_TOPO_B2B_USD:
0236         return NTB_PORT_SEC_DSD;
0237     case NTB_TOPO_SEC:
0238     case NTB_TOPO_B2B_DSD:
0239         return NTB_PORT_PRI_USD;
0240     default:
0241         return 0;
0242     }
0243 }
0244 EXPORT_SYMBOL(ntb_default_peer_port_number);
0245 
0246 int ntb_default_peer_port_idx(struct ntb_dev *ntb, int port)
0247 {
0248     int peer_port = ntb_default_peer_port_number(ntb, NTB_DEF_PEER_IDX);
0249 
0250     if (peer_port == -EINVAL || port != peer_port)
0251         return -EINVAL;
0252 
0253     return 0;
0254 }
0255 EXPORT_SYMBOL(ntb_default_peer_port_idx);
0256 
0257 static int ntb_probe(struct device *dev)
0258 {
0259     struct ntb_dev *ntb;
0260     struct ntb_client *client;
0261     int rc;
0262 
0263     get_device(dev);
0264     ntb = dev_ntb(dev);
0265     client = drv_ntb_client(dev->driver);
0266 
0267     rc = client->ops.probe(client, ntb);
0268     if (rc)
0269         put_device(dev);
0270 
0271     return rc;
0272 }
0273 
0274 static void ntb_remove(struct device *dev)
0275 {
0276     struct ntb_dev *ntb;
0277     struct ntb_client *client;
0278 
0279     if (dev->driver) {
0280         ntb = dev_ntb(dev);
0281         client = drv_ntb_client(dev->driver);
0282 
0283         client->ops.remove(client, ntb);
0284         put_device(dev);
0285     }
0286 }
0287 
0288 static void ntb_dev_release(struct device *dev)
0289 {
0290     struct ntb_dev *ntb = dev_ntb(dev);
0291 
0292     complete(&ntb->released);
0293 }
0294 
0295 static struct bus_type ntb_bus = {
0296     .name = "ntb",
0297     .probe = ntb_probe,
0298     .remove = ntb_remove,
0299 };
0300 
0301 static int __init ntb_driver_init(void)
0302 {
0303     return bus_register(&ntb_bus);
0304 }
0305 module_init(ntb_driver_init);
0306 
0307 static void __exit ntb_driver_exit(void)
0308 {
0309     bus_unregister(&ntb_bus);
0310 }
0311 module_exit(ntb_driver_exit);