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; }
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(); }
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; }