/* * This file is part of the Chelsio FCoE driver for Linux. * * Copyright (c) 2008-2012 Chelsio Communications, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU * General Public License (GPL) Version 2, available from the file * COPYING in the main directory of this source tree, or the * OpenIB.org BSD license below: * * 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 * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE.
*/
staticint csio_setup_debugfs(struct csio_hw *hw)
{ int i;
if (IS_ERR_OR_NULL(hw->debugfs_root)) return -1;
i = csio_rd_reg32(hw, MA_TARGET_MEM_ENABLE_A); if (i & EDRAM0_ENABLE_F)
csio_add_debugfs_mem(hw, "edc0", MEM_EDC0, 5); if (i & EDRAM1_ENABLE_F)
csio_add_debugfs_mem(hw, "edc1", MEM_EDC1, 5);
/* * csio_dfs_init - Debug filesystem initialization for the module. *
*/ staticvoid
csio_dfs_init(void)
{
csio_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
}
/* * csio_dfs_exit - debugfs cleanup for the module.
*/ staticvoid
csio_dfs_exit(void)
{
debugfs_remove(csio_debugfs_root);
}
/* * csio_pci_init - PCI initialization. * @pdev: PCI device. * @bars: Bitmask of bars to be requested. * * Initializes the PCI function by enabling MMIO, setting bus * mastership and setting DMA mask.
*/ staticint
csio_pci_init(struct pci_dev *pdev, int *bars)
{ int rv = -ENODEV;
*bars = pci_select_bars(pdev, IORESOURCE_MEM);
if (pci_enable_device_mem(pdev)) goto err;
if (pci_request_selected_regions(pdev, *bars, KBUILD_MODNAME)) goto err_disable_device;
pci_set_master(pdev);
pci_try_set_mwi(pdev);
rv = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); if (rv)
rv = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); if (rv) {
rv = -ENODEV;
dev_err(&pdev->dev, "No suitable DMA available.\n"); goto err_release_regions;
}
/* * csio_config_queues - Configure the DMA queues. * @hw: HW module. * * Allocates memory for queues are registers them with FW.
*/ int
csio_config_queues(struct csio_hw *hw)
{ int i, j, idx, k = 0; int rv; struct csio_scsi_qset *sqset; struct csio_mgmtm *mgmtm = csio_hw_to_mgmtm(hw); struct csio_scsi_qset *orig; struct csio_scsi_cpu_info *info;
if (hw->flags & CSIO_HWF_Q_MEM_ALLOCED) return csio_create_queues(hw);
/* Calculate number of SCSI queues for MSIX we would like */
hw->num_scsi_msix_cpus = num_online_cpus();
hw->num_sqsets = num_online_cpus() * hw->num_pports;
/* Initialize max_cpus, may get reduced during msix allocations */ for (i = 0; i < hw->num_pports; i++)
hw->scsi_cpu_info[i].max_cpus = hw->num_scsi_msix_cpus;
idx = csio_wr_alloc_q(hw, CSIO_SCSI_IQSIZE,
CSIO_SCSI_IQ_WRSZ, CSIO_INGRESS,
(void *)hw, 0, 0,
csio_scsi_intx_handler); if (idx == -1) {
csio_err(hw, "IQ creation failed for idx:%d\n",
idx); goto intr_disable;
}
sqset->iq_idx = idx;
} /* for all CPUs */
} /* For all ports */
hw->flags |= CSIO_HWF_Q_MEM_ALLOCED;
rv = csio_create_queues(hw); if (rv != 0) goto intr_disable;
/* * Now request IRQs for the vectors. In the event of a failure, * cleanup is handled internally by this function.
*/
rv = csio_request_irqs(hw); if (rv != 0) return -EINVAL;
/* memory pool/DMA pool allocation */ if (csio_resource_alloc(hw)) goto err_free_hw;
/* Get the start address of registers from BAR 0 */
hw->regstart = ioremap(pci_resource_start(pdev, 0),
pci_resource_len(pdev, 0)); if (!hw->regstart) {
csio_err(hw, "Could not map BAR 0, regstart = %p\n",
hw->regstart); goto err_resource_free;
}
/** * csio_shost_init - Create and initialize the lnode module. * @hw: The HW module. * @dev: The device associated with this invocation. * @probe: Called from probe context or not? * @pln: Parent lnode if any. * * Allocates lnode structure via scsi_host_alloc, initializes * shost, initializes lnode module and registers with SCSI ML * via scsi_host_add. This function is shared between physical and * virtual node ports.
*/ struct csio_lnode *
csio_shost_init(struct csio_hw *hw, struct device *dev, bool probe, struct csio_lnode *pln)
{ struct Scsi_Host *shost = NULL; struct csio_lnode *ln;
/* * hw->pdev is the physical port's PCI dev structure, * which will be different from the NPIV dev structure.
*/ if (dev == &hw->pdev->dev)
shost = scsi_host_alloc(
&csio_fcoe_shost_template, sizeof(struct csio_lnode)); else
shost = scsi_host_alloc(
&csio_fcoe_shost_vport_template, sizeof(struct csio_lnode));
/** * csio_shost_exit - De-instantiate the shost. * @ln: The lnode module corresponding to the shost. *
*/ void
csio_shost_exit(struct csio_lnode *ln)
{ struct Scsi_Host *shost = csio_ln_to_shost(ln); struct csio_hw *hw = csio_lnode_to_hw(ln);
/* Inform transport */
fc_remove_host(shost);
/* Inform SCSI ML */
scsi_remove_host(shost);
/* Flush all the events, so that any rnode removal events * already queued are all handled, before we remove the lnode.
*/
spin_lock_irq(&hw->lock);
csio_evtq_flush(hw);
spin_unlock_irq(&hw->lock);
/* * csio_probe_one - Instantiate this function. * @pdev: PCI device * @id: Device ID * * This is the .probe() callback of the driver. This function: * - Initializes the PCI function by enabling MMIO, setting bus * mastership and setting DMA mask. * - Allocates HW structure, DMA, memory resources, maps BARS to * host memory and initializes HW module. * - Allocates lnode structure via scsi_host_alloc, initializes * shost, initialized lnode module and registers with SCSI ML * via scsi_host_add. * - Enables interrupts, and starts the chip by kicking off the * HW state machine. * - Once hardware is ready, initiated scan of the host via * scsi_scan_host.
*/ staticint csio_probe_one(struct pci_dev *pdev, conststruct pci_device_id *id)
{ int rv; int bars; int i; struct csio_hw *hw; struct csio_lnode *ln;
/* probe only T5 and T6 cards */ if (!csio_is_t5((pdev->device & CSIO_HW_CHIP_MASK)) &&
!csio_is_t6((pdev->device & CSIO_HW_CHIP_MASK))) return -ENODEV;
rv = csio_pci_init(pdev, &bars); if (rv) goto err;
/* * csio_remove_one - Remove one instance of the driver at this PCI function. * @pdev: PCI device * * Used during hotplug operation.
*/ staticvoid csio_remove_one(struct pci_dev *pdev)
{ struct csio_hw *hw = pci_get_drvdata(pdev); int bars = pci_select_bars(pdev, IORESOURCE_MEM);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.