Esempio n. 1
0
int fnic_fc_trace_init(void)
{
	unsigned long fc_trace_buf_head;
	int err = 0;
	int i;

	fc_trace_max_entries = (fnic_fc_trace_max_pages * PAGE_SIZE)/
				FC_TRC_SIZE_BYTES;
	fnic_fc_ctlr_trace_buf_p = (unsigned long)vmalloc(
					fnic_fc_trace_max_pages * PAGE_SIZE);
	if (!fnic_fc_ctlr_trace_buf_p) {
		pr_err("fnic: Failed to allocate memory for "
		       "FC Control Trace Buf\n");
		err = -ENOMEM;
		goto err_fnic_fc_ctlr_trace_buf_init;
	}

	memset((void *)fnic_fc_ctlr_trace_buf_p, 0,
			fnic_fc_trace_max_pages * PAGE_SIZE);

	/* Allocate memory for page offset */
	fc_trace_entries.page_offset = vmalloc(fc_trace_max_entries *
						sizeof(unsigned long));
	if (!fc_trace_entries.page_offset) {
		pr_err("fnic:Failed to allocate memory for page_offset\n");
		if (fnic_fc_ctlr_trace_buf_p) {
			pr_err("fnic: Freeing FC Control Trace Buf\n");
			vfree((void *)fnic_fc_ctlr_trace_buf_p);
			fnic_fc_ctlr_trace_buf_p = 0;
		}
		err = -ENOMEM;
		goto err_fnic_fc_ctlr_trace_buf_init;
	}
	memset((void *)fc_trace_entries.page_offset, 0,
	       (fc_trace_max_entries * sizeof(unsigned long)));

	fc_trace_entries.rd_idx = fc_trace_entries.wr_idx = 0;
	fc_trace_buf_head = fnic_fc_ctlr_trace_buf_p;

	/*
	* Set up fc_trace_entries.page_offset field with memory location
	* for every trace entry
	*/
	for (i = 0; i < fc_trace_max_entries; i++) {
		fc_trace_entries.page_offset[i] = fc_trace_buf_head;
		fc_trace_buf_head += FC_TRC_SIZE_BYTES;
	}
	err = fnic_fc_trace_debugfs_init();
	if (err < 0) {
		pr_err("fnic: Failed to initialize FC_CTLR tracing.\n");
		goto err_fnic_fc_ctlr_trace_debugfs_init;
	}
	pr_info("fnic: Successfully Initialized FC_CTLR Trace Buffer\n");
	return err;

err_fnic_fc_ctlr_trace_debugfs_init:
	fnic_fc_trace_free();
err_fnic_fc_ctlr_trace_buf_init:
	return err;
}
Esempio n. 2
0
static void __exit fnic_cleanup_module(void)
{
	pci_unregister_driver(&fnic_driver);
	destroy_workqueue(fnic_event_queue);
	if (fnic_fip_queue) {
		flush_workqueue(fnic_fip_queue);
		destroy_workqueue(fnic_fip_queue);
	}
	kmem_cache_destroy(fnic_sgl_cache[FNIC_SGL_CACHE_MAX]);
	kmem_cache_destroy(fnic_sgl_cache[FNIC_SGL_CACHE_DFLT]);
	kmem_cache_destroy(fnic_io_req_cache);
	fc_release_transport(fnic_fc_transport);
	fnic_trace_free();
	fnic_fc_trace_free();
	fnic_debugfs_terminate();
}
Esempio n. 3
0
static int __init fnic_init_module(void)
{
	size_t len;
	int err = 0;

	printk(KERN_INFO PFX "%s, ver %s\n", DRV_DESCRIPTION, DRV_VERSION);

	/* Create debugfs entries for fnic */
	err = fnic_debugfs_init();
	if (err < 0) {
		printk(KERN_ERR PFX "Failed to create fnic directory "
				"for tracing and stats logging\n");
		fnic_debugfs_terminate();
	}

	/* Allocate memory for trace buffer */
	err = fnic_trace_buf_init();
	if (err < 0) {
		printk(KERN_ERR PFX
		       "Trace buffer initialization Failed. "
		       "Fnic Tracing utility is disabled\n");
		fnic_trace_free();
	}

    /* Allocate memory for fc trace buffer */
	err = fnic_fc_trace_init();
	if (err < 0) {
		printk(KERN_ERR PFX "FC trace buffer initialization Failed "
		       "FC frame tracing utility is disabled\n");
		fnic_fc_trace_free();
	}

	/* Create a cache for allocation of default size sgls */
	len = sizeof(struct fnic_dflt_sgl_list);
	fnic_sgl_cache[FNIC_SGL_CACHE_DFLT] = kmem_cache_create
		("fnic_sgl_dflt", len + FNIC_SG_DESC_ALIGN, FNIC_SG_DESC_ALIGN,
		 SLAB_HWCACHE_ALIGN,
		 NULL);
	if (!fnic_sgl_cache[FNIC_SGL_CACHE_DFLT]) {
		printk(KERN_ERR PFX "failed to create fnic dflt sgl slab\n");
		err = -ENOMEM;
		goto err_create_fnic_sgl_slab_dflt;
	}

	/* Create a cache for allocation of max size sgls*/
	len = sizeof(struct fnic_sgl_list);
	fnic_sgl_cache[FNIC_SGL_CACHE_MAX] = kmem_cache_create
		("fnic_sgl_max", len + FNIC_SG_DESC_ALIGN, FNIC_SG_DESC_ALIGN,
		  SLAB_HWCACHE_ALIGN,
		  NULL);
	if (!fnic_sgl_cache[FNIC_SGL_CACHE_MAX]) {
		printk(KERN_ERR PFX "failed to create fnic max sgl slab\n");
		err = -ENOMEM;
		goto err_create_fnic_sgl_slab_max;
	}

	/* Create a cache of io_req structs for use via mempool */
	fnic_io_req_cache = kmem_cache_create("fnic_io_req",
					      sizeof(struct fnic_io_req),
					      0, SLAB_HWCACHE_ALIGN, NULL);
	if (!fnic_io_req_cache) {
		printk(KERN_ERR PFX "failed to create fnic io_req slab\n");
		err = -ENOMEM;
		goto err_create_fnic_ioreq_slab;
	}

	fnic_event_queue = create_singlethread_workqueue("fnic_event_wq");
	if (!fnic_event_queue) {
		printk(KERN_ERR PFX "fnic work queue create failed\n");
		err = -ENOMEM;
		goto err_create_fnic_workq;
	}

	spin_lock_init(&fnic_list_lock);
	INIT_LIST_HEAD(&fnic_list);

	fnic_fip_queue = create_singlethread_workqueue("fnic_fip_q");
	if (!fnic_fip_queue) {
		printk(KERN_ERR PFX "fnic FIP work queue create failed\n");
		err = -ENOMEM;
		goto err_create_fip_workq;
	}

	fnic_fc_transport = fc_attach_transport(&fnic_fc_functions);
	if (!fnic_fc_transport) {
		printk(KERN_ERR PFX "fc_attach_transport error\n");
		err = -ENOMEM;
		goto err_fc_transport;
	}

	/* register the driver with PCI system */
	err = pci_register_driver(&fnic_driver);
	if (err < 0) {
		printk(KERN_ERR PFX "pci register error\n");
		goto err_pci_register;
	}
	return err;

err_pci_register:
	fc_release_transport(fnic_fc_transport);
err_fc_transport:
	destroy_workqueue(fnic_fip_queue);
err_create_fip_workq:
	destroy_workqueue(fnic_event_queue);
err_create_fnic_workq:
	kmem_cache_destroy(fnic_io_req_cache);
err_create_fnic_ioreq_slab:
	kmem_cache_destroy(fnic_sgl_cache[FNIC_SGL_CACHE_MAX]);
err_create_fnic_sgl_slab_max:
	kmem_cache_destroy(fnic_sgl_cache[FNIC_SGL_CACHE_DFLT]);
err_create_fnic_sgl_slab_dflt:
	fnic_trace_free();
	fnic_fc_trace_free();
	fnic_debugfs_terminate();
	return err;
}