cregit-Linux how code gets into the kernel

Release 4.11 drivers/misc/mic/scif/scif_main.c

/*
 * Intel MIC Platform Software Stack (MPSS)
 *
 * Copyright(c) 2014 Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License, version 2, 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.
 *
 * Intel SCIF driver.
 *
 */
#include <linux/module.h>
#include <linux/idr.h>

#include <linux/mic_common.h>
#include "../common/mic_dev.h"
#include "../bus/scif_bus.h"
#include "scif_peer_bus.h"
#include "scif_main.h"
#include "scif_map.h"


struct scif_info scif_info = {
	.mdev = {
		.minor = MISC_DYNAMIC_MINOR,
		.name = "scif",
		.fops = &scif_fops,
        }
};


struct scif_dev *scif_dev;

struct kmem_cache *unaligned_cache;

static atomic_t g_loopb_cnt;

/* Runs in the context of intr_wq */

static void scif_intr_bh_handler(struct work_struct *work) { struct scif_dev *scifdev = container_of(work, struct scif_dev, intr_bh); if (scifdev_self(scifdev)) scif_loopb_msg_handler(scifdev, scifdev->qpairs); else scif_nodeqp_intrhandler(scifdev, scifdev->qpairs); }

Contributors

PersonTokensPropCommitsCommitProp
Sudeep Dutt52100.00%1100.00%
Total52100.00%1100.00%


int scif_setup_intr_wq(struct scif_dev *scifdev) { if (!scifdev->intr_wq) { snprintf(scifdev->intr_wqname, sizeof(scifdev->intr_wqname), "SCIF INTR %d", scifdev->node); scifdev->intr_wq = alloc_ordered_workqueue(scifdev->intr_wqname, 0); if (!scifdev->intr_wq) return -ENOMEM; INIT_WORK(&scifdev->intr_bh, scif_intr_bh_handler); } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Sudeep Dutt76100.00%1100.00%
Total76100.00%1100.00%


void scif_destroy_intr_wq(struct scif_dev *scifdev) { if (scifdev->intr_wq) { destroy_workqueue(scifdev->intr_wq); scifdev->intr_wq = NULL; } }

Contributors

PersonTokensPropCommitsCommitProp
Sudeep Dutt31100.00%1100.00%
Total31100.00%1100.00%


irqreturn_t scif_intr_handler(int irq, void *data) { struct scif_dev *scifdev = data; struct scif_hw_dev *sdev = scifdev->sdev; sdev->hw_ops->ack_interrupt(sdev, scifdev->db); queue_work(scifdev->intr_wq, &scifdev->intr_bh); return IRQ_HANDLED; }

Contributors

PersonTokensPropCommitsCommitProp
Sudeep Dutt56100.00%1100.00%
Total56100.00%1100.00%


static void scif_qp_setup_handler(struct work_struct *work) { struct scif_dev *scifdev = container_of(work, struct scif_dev, qp_dwork.work); struct scif_hw_dev *sdev = scifdev->sdev; dma_addr_t da = 0; int err; if (scif_is_mgmt_node()) { struct mic_bootparam *bp = sdev->dp; da = bp->scif_card_dma_addr; scifdev->rdb = bp->h2c_scif_db; } else { struct mic_bootparam __iomem *bp = sdev->rdp; da = readq(&bp->scif_host_dma_addr); scifdev->rdb = ioread8(&bp->c2h_scif_db); } if (da) { err = scif_qp_response(da, scifdev); if (err) dev_err(&scifdev->sdev->dev, "scif_qp_response err %d\n", err); } else { schedule_delayed_work(&scifdev->qp_dwork, msecs_to_jiffies(1000)); } }

Contributors

PersonTokensPropCommitsCommitProp
Sudeep Dutt159100.00%1100.00%
Total159100.00%1100.00%


static int scif_setup_scifdev(void) { /* We support a maximum of 129 SCIF nodes including the mgmt node */ #define MAX_SCIF_NODES 129 int i; u8 num_nodes = MAX_SCIF_NODES; scif_dev = kcalloc(num_nodes, sizeof(*scif_dev), GFP_KERNEL); if (!scif_dev) return -ENOMEM; for (i = 0; i < num_nodes; i++) { struct scif_dev *scifdev = &scif_dev[i]; scifdev->node = i; scifdev->exit = OP_IDLE; init_waitqueue_head(&scifdev->disconn_wq); mutex_init(&scifdev->lock); INIT_WORK(&scifdev->peer_add_work, scif_add_peer_device); INIT_DELAYED_WORK(&scifdev->p2p_dwork, scif_poll_qp_state); INIT_DELAYED_WORK(&scifdev->qp_dwork, scif_qp_setup_handler); INIT_LIST_HEAD(&scifdev->p2p); RCU_INIT_POINTER(scifdev->spdev, NULL); } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Sudeep Dutt14093.96%150.00%
Ashutosh Dixit96.04%150.00%
Total149100.00%2100.00%


static void scif_destroy_scifdev(void) { kfree(scif_dev); }

Contributors

PersonTokensPropCommitsCommitProp
Sudeep Dutt13100.00%1100.00%
Total13100.00%1100.00%


static int scif_probe(struct scif_hw_dev *sdev) { struct scif_dev *scifdev = &scif_dev[sdev->dnode]; int rc; dev_set_drvdata(&sdev->dev, sdev); scifdev->sdev = sdev; if (1 == atomic_add_return(1, &g_loopb_cnt)) { struct scif_dev *loopb_dev = &scif_dev[sdev->snode]; loopb_dev->sdev = sdev; rc = scif_setup_loopback_qp(loopb_dev); if (rc) goto exit; } rc = scif_setup_intr_wq(scifdev); if (rc) goto destroy_loopb; rc = scif_setup_qp(scifdev); if (rc) goto destroy_intr; scifdev->db = sdev->hw_ops->next_db(sdev); scifdev->cookie = sdev->hw_ops->request_irq(sdev, scif_intr_handler, "SCIF_INTR", scifdev, scifdev->db); if (IS_ERR(scifdev->cookie)) { rc = PTR_ERR(scifdev->cookie); goto free_qp; } if (scif_is_mgmt_node()) { struct mic_bootparam *bp = sdev->dp; bp->c2h_scif_db = scifdev->db; bp->scif_host_dma_addr = scifdev->qp_dma_addr; } else { struct mic_bootparam __iomem *bp = sdev->rdp; iowrite8(scifdev->db, &bp->h2c_scif_db); writeq(scifdev->qp_dma_addr, &bp->scif_card_dma_addr); } schedule_delayed_work(&scifdev->qp_dwork, msecs_to_jiffies(1000)); return rc; free_qp: scif_free_qp(scifdev); destroy_intr: scif_destroy_intr_wq(scifdev); destroy_loopb: if (atomic_dec_and_test(&g_loopb_cnt)) scif_destroy_loopback_qp(&scif_dev[sdev->snode]); exit: return rc; }

Contributors

PersonTokensPropCommitsCommitProp
Sudeep Dutt28594.37%150.00%
Ashutosh Dixit175.63%150.00%
Total302100.00%2100.00%


void scif_stop(struct scif_dev *scifdev) { struct scif_dev *dev; int i; for (i = scif_info.maxid; i >= 0; i--) { dev = &scif_dev[i]; if (scifdev_self(dev)) continue; scif_handle_remove_node(i); } }

Contributors

PersonTokensPropCommitsCommitProp
Sudeep Dutt56100.00%1100.00%
Total56100.00%1100.00%


static void scif_remove(struct scif_hw_dev *sdev) { struct scif_dev *scifdev = &scif_dev[sdev->dnode]; if (scif_is_mgmt_node()) { struct mic_bootparam *bp = sdev->dp; bp->c2h_scif_db = -1; bp->scif_host_dma_addr = 0x0; } else { struct mic_bootparam __iomem *bp = sdev->rdp; iowrite8(-1, &bp->h2c_scif_db); writeq(0x0, &bp->scif_card_dma_addr); } if (scif_is_mgmt_node()) { scif_disconnect_node(scifdev->node, true); } else { scif_info.card_initiated_exit = true; scif_stop(scifdev); } if (atomic_dec_and_test(&g_loopb_cnt)) scif_destroy_loopback_qp(&scif_dev[sdev->snode]); if (scifdev->cookie) { sdev->hw_ops->free_irq(sdev, scifdev->cookie, scifdev); scifdev->cookie = NULL; } scif_destroy_intr_wq(scifdev); cancel_delayed_work(&scifdev->qp_dwork); scif_free_qp(scifdev); scifdev->rdb = -1; scifdev->sdev = NULL; }

Contributors

PersonTokensPropCommitsCommitProp
Sudeep Dutt196100.00%1100.00%
Total196100.00%1100.00%

static struct scif_hw_dev_id id_table[] = { { MIC_SCIF_DEV, SCIF_DEV_ANY_ID }, { 0 }, }; static struct scif_driver scif_driver = { .driver.name = KBUILD_MODNAME, .driver.owner = THIS_MODULE, .id_table = id_table, .probe = scif_probe, .remove = scif_remove, };
static int _scif_init(void) { int rc; mutex_init(&scif_info.eplock); spin_lock_init(&scif_info.rmalock); spin_lock_init(&scif_info.nb_connect_lock); spin_lock_init(&scif_info.port_lock); mutex_init(&scif_info.conflock); mutex_init(&scif_info.connlock); mutex_init(&scif_info.fencelock); INIT_LIST_HEAD(&scif_info.uaccept); INIT_LIST_HEAD(&scif_info.listen); INIT_LIST_HEAD(&scif_info.zombie); INIT_LIST_HEAD(&scif_info.connected); INIT_LIST_HEAD(&scif_info.disconnected); INIT_LIST_HEAD(&scif_info.rma); INIT_LIST_HEAD(&scif_info.rma_tc); INIT_LIST_HEAD(&scif_info.mmu_notif_cleanup); INIT_LIST_HEAD(&scif_info.fence); INIT_LIST_HEAD(&scif_info.nb_connect_list); init_waitqueue_head(&scif_info.exitwq); scif_info.rma_tc_limit = SCIF_RMA_TEMP_CACHE_LIMIT; scif_info.en_msg_log = 0; scif_info.p2p_enable = 1; rc = scif_setup_scifdev(); if (rc) goto error; unaligned_cache = kmem_cache_create("Unaligned_DMA", SCIF_KMEM_UNALIGNED_BUF_SIZE, 0, SLAB_HWCACHE_ALIGN, NULL); if (!unaligned_cache) { rc = -ENOMEM; goto free_sdev; } INIT_WORK(&scif_info.misc_work, scif_misc_handler); INIT_WORK(&scif_info.mmu_notif_work, scif_mmu_notif_handler); INIT_WORK(&scif_info.conn_work, scif_conn_handler); idr_init(&scif_ports); return 0; free_sdev: scif_destroy_scifdev(); error: return rc; }

Contributors

PersonTokensPropCommitsCommitProp
Sudeep Dutt23488.64%250.00%
Ashutosh Dixit207.58%125.00%
Nikhil P Rao103.79%125.00%
Total264100.00%4100.00%


static void _scif_exit(void) { idr_destroy(&scif_ports); kmem_cache_destroy(unaligned_cache); scif_destroy_scifdev(); }

Contributors

PersonTokensPropCommitsCommitProp
Sudeep Dutt22100.00%2100.00%
Total22100.00%2100.00%


static int __init scif_init(void) { struct miscdevice *mdev = &scif_info.mdev; int rc; _scif_init(); iova_cache_get(); rc = scif_peer_bus_init(); if (rc) goto exit; rc = scif_register_driver(&scif_driver); if (rc) goto peer_bus_exit; rc = misc_register(mdev); if (rc) goto unreg_scif; scif_init_debugfs(); return 0; unreg_scif: scif_unregister_driver(&scif_driver); peer_bus_exit: scif_peer_bus_exit(); exit: _scif_exit(); return rc; }

Contributors

PersonTokensPropCommitsCommitProp
Sudeep Dutt9598.96%266.67%
Ashutosh Dixit11.04%133.33%
Total96100.00%3100.00%


static void __exit scif_exit(void) { scif_exit_debugfs(); misc_deregister(&scif_info.mdev); scif_unregister_driver(&scif_driver); scif_peer_bus_exit(); iova_cache_put(); _scif_exit(); }

Contributors

PersonTokensPropCommitsCommitProp
Sudeep Dutt35100.00%2100.00%
Total35100.00%2100.00%

module_init(scif_init); module_exit(scif_exit); MODULE_DEVICE_TABLE(scif, id_table); MODULE_AUTHOR("Intel Corporation"); MODULE_DESCRIPTION("Intel(R) SCIF driver"); MODULE_LICENSE("GPL v2");

Overall Contributors

PersonTokensPropCommitsCommitProp
Sudeep Dutt160396.57%250.00%
Ashutosh Dixit472.83%125.00%
Nikhil P Rao100.60%125.00%
Total1660100.00%4100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.