1255 lines · c
1/*2 * This file is part of the Chelsio FCoE driver for Linux.3 *4 * Copyright (c) 2008-2012 Chelsio Communications, Inc. All rights reserved.5 *6 * This software is available to you under a choice of one of two7 * licenses. You may choose to be licensed under the terms of the GNU8 * General Public License (GPL) Version 2, available from the file9 * COPYING in the main directory of this source tree, or the10 * OpenIB.org BSD license below:11 *12 * Redistribution and use in source and binary forms, with or13 * without modification, are permitted provided that the following14 * conditions are met:15 *16 * - Redistributions of source code must retain the above17 * copyright notice, this list of conditions and the following18 * disclaimer.19 *20 * - Redistributions in binary form must reproduce the above21 * copyright notice, this list of conditions and the following22 * disclaimer in the documentation and/or other materials23 * provided with the distribution.24 *25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE32 * SOFTWARE.33 */34 35#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt36 37#include <linux/kernel.h>38#include <linux/module.h>39#include <linux/init.h>40#include <linux/pci.h>41#include <linux/mm.h>42#include <linux/notifier.h>43#include <linux/kdebug.h>44#include <linux/seq_file.h>45#include <linux/debugfs.h>46#include <linux/string.h>47#include <linux/export.h>48 49#include "csio_init.h"50#include "csio_defs.h"51 52#define CSIO_MIN_MEMPOOL_SZ 6453 54static struct dentry *csio_debugfs_root;55 56static struct scsi_transport_template *csio_fcoe_transport;57static struct scsi_transport_template *csio_fcoe_transport_vport;58 59/*60 * debugfs support61 */62static ssize_t63csio_mem_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)64{65 loff_t pos = *ppos;66 loff_t avail = file_inode(file)->i_size;67 unsigned int mem = (uintptr_t)file->private_data & 3;68 struct csio_hw *hw = file->private_data - mem;69 70 if (pos < 0)71 return -EINVAL;72 if (pos >= avail)73 return 0;74 if (count > avail - pos)75 count = avail - pos;76 77 while (count) {78 size_t len;79 int ret, ofst;80 __be32 data[16];81 82 if (mem == MEM_MC)83 ret = hw->chip_ops->chip_mc_read(hw, 0, pos,84 data, NULL);85 else86 ret = hw->chip_ops->chip_edc_read(hw, mem, pos,87 data, NULL);88 if (ret)89 return ret;90 91 ofst = pos % sizeof(data);92 len = min(count, sizeof(data) - ofst);93 if (copy_to_user(buf, (u8 *)data + ofst, len))94 return -EFAULT;95 96 buf += len;97 pos += len;98 count -= len;99 }100 count = pos - *ppos;101 *ppos = pos;102 return count;103}104 105static const struct file_operations csio_mem_debugfs_fops = {106 .owner = THIS_MODULE,107 .open = simple_open,108 .read = csio_mem_read,109 .llseek = default_llseek,110};111 112void csio_add_debugfs_mem(struct csio_hw *hw, const char *name,113 unsigned int idx, unsigned int size_mb)114{115 debugfs_create_file_size(name, S_IRUSR, hw->debugfs_root,116 (void *)hw + idx, &csio_mem_debugfs_fops,117 size_mb << 20);118}119 120static int csio_setup_debugfs(struct csio_hw *hw)121{122 int i;123 124 if (IS_ERR_OR_NULL(hw->debugfs_root))125 return -1;126 127 i = csio_rd_reg32(hw, MA_TARGET_MEM_ENABLE_A);128 if (i & EDRAM0_ENABLE_F)129 csio_add_debugfs_mem(hw, "edc0", MEM_EDC0, 5);130 if (i & EDRAM1_ENABLE_F)131 csio_add_debugfs_mem(hw, "edc1", MEM_EDC1, 5);132 133 hw->chip_ops->chip_dfs_create_ext_mem(hw);134 return 0;135}136 137/*138 * csio_dfs_create - Creates and sets up per-hw debugfs.139 *140 */141static int142csio_dfs_create(struct csio_hw *hw)143{144 if (csio_debugfs_root) {145 hw->debugfs_root = debugfs_create_dir(pci_name(hw->pdev),146 csio_debugfs_root);147 csio_setup_debugfs(hw);148 }149 150 return 0;151}152 153/*154 * csio_dfs_destroy - Destroys per-hw debugfs.155 */156static void157csio_dfs_destroy(struct csio_hw *hw)158{159 debugfs_remove_recursive(hw->debugfs_root);160}161 162/*163 * csio_dfs_init - Debug filesystem initialization for the module.164 *165 */166static void167csio_dfs_init(void)168{169 csio_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);170}171 172/*173 * csio_dfs_exit - debugfs cleanup for the module.174 */175static void176csio_dfs_exit(void)177{178 debugfs_remove(csio_debugfs_root);179}180 181/*182 * csio_pci_init - PCI initialization.183 * @pdev: PCI device.184 * @bars: Bitmask of bars to be requested.185 *186 * Initializes the PCI function by enabling MMIO, setting bus187 * mastership and setting DMA mask.188 */189static int190csio_pci_init(struct pci_dev *pdev, int *bars)191{192 int rv = -ENODEV;193 194 *bars = pci_select_bars(pdev, IORESOURCE_MEM);195 196 if (pci_enable_device_mem(pdev))197 goto err;198 199 if (pci_request_selected_regions(pdev, *bars, KBUILD_MODNAME))200 goto err_disable_device;201 202 pci_set_master(pdev);203 pci_try_set_mwi(pdev);204 205 rv = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));206 if (rv)207 rv = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));208 if (rv) {209 rv = -ENODEV;210 dev_err(&pdev->dev, "No suitable DMA available.\n");211 goto err_release_regions;212 }213 214 return 0;215 216err_release_regions:217 pci_release_selected_regions(pdev, *bars);218err_disable_device:219 pci_disable_device(pdev);220err:221 return rv;222 223}224 225/*226 * csio_pci_exit - PCI unitialization.227 * @pdev: PCI device.228 * @bars: Bars to be released.229 *230 */231static void232csio_pci_exit(struct pci_dev *pdev, int *bars)233{234 pci_release_selected_regions(pdev, *bars);235 pci_disable_device(pdev);236}237 238/*239 * csio_hw_init_workers - Initialize the HW module's worker threads.240 * @hw: HW module.241 *242 */243static void244csio_hw_init_workers(struct csio_hw *hw)245{246 INIT_WORK(&hw->evtq_work, csio_evtq_worker);247}248 249static void250csio_hw_exit_workers(struct csio_hw *hw)251{252 cancel_work_sync(&hw->evtq_work);253}254 255static int256csio_create_queues(struct csio_hw *hw)257{258 int i, j;259 struct csio_mgmtm *mgmtm = csio_hw_to_mgmtm(hw);260 int rv;261 struct csio_scsi_cpu_info *info;262 263 if (hw->flags & CSIO_HWF_Q_FW_ALLOCED)264 return 0;265 266 if (hw->intr_mode != CSIO_IM_MSIX) {267 rv = csio_wr_iq_create(hw, NULL, hw->intr_iq_idx,268 0, hw->pport[0].portid, false, NULL);269 if (rv != 0) {270 csio_err(hw, " Forward Interrupt IQ failed!: %d\n", rv);271 return rv;272 }273 }274 275 /* FW event queue */276 rv = csio_wr_iq_create(hw, NULL, hw->fwevt_iq_idx,277 csio_get_fwevt_intr_idx(hw),278 hw->pport[0].portid, true, NULL);279 if (rv != 0) {280 csio_err(hw, "FW event IQ config failed!: %d\n", rv);281 return rv;282 }283 284 /* Create mgmt queue */285 rv = csio_wr_eq_create(hw, NULL, mgmtm->eq_idx,286 mgmtm->iq_idx, hw->pport[0].portid, NULL);287 288 if (rv != 0) {289 csio_err(hw, "Mgmt EQ create failed!: %d\n", rv);290 goto err;291 }292 293 /* Create SCSI queues */294 for (i = 0; i < hw->num_pports; i++) {295 info = &hw->scsi_cpu_info[i];296 297 for (j = 0; j < info->max_cpus; j++) {298 struct csio_scsi_qset *sqset = &hw->sqset[i][j];299 300 rv = csio_wr_iq_create(hw, NULL, sqset->iq_idx,301 sqset->intr_idx, i, false, NULL);302 if (rv != 0) {303 csio_err(hw,304 "SCSI module IQ config failed [%d][%d]:%d\n",305 i, j, rv);306 goto err;307 }308 rv = csio_wr_eq_create(hw, NULL, sqset->eq_idx,309 sqset->iq_idx, i, NULL);310 if (rv != 0) {311 csio_err(hw,312 "SCSI module EQ config failed [%d][%d]:%d\n",313 i, j, rv);314 goto err;315 }316 } /* for all CPUs */317 } /* For all ports */318 319 hw->flags |= CSIO_HWF_Q_FW_ALLOCED;320 return 0;321err:322 csio_wr_destroy_queues(hw, true);323 return -EINVAL;324}325 326/*327 * csio_config_queues - Configure the DMA queues.328 * @hw: HW module.329 *330 * Allocates memory for queues are registers them with FW.331 */332int333csio_config_queues(struct csio_hw *hw)334{335 int i, j, idx, k = 0;336 int rv;337 struct csio_scsi_qset *sqset;338 struct csio_mgmtm *mgmtm = csio_hw_to_mgmtm(hw);339 struct csio_scsi_qset *orig;340 struct csio_scsi_cpu_info *info;341 342 if (hw->flags & CSIO_HWF_Q_MEM_ALLOCED)343 return csio_create_queues(hw);344 345 /* Calculate number of SCSI queues for MSIX we would like */346 hw->num_scsi_msix_cpus = num_online_cpus();347 hw->num_sqsets = num_online_cpus() * hw->num_pports;348 349 if (hw->num_sqsets > CSIO_MAX_SCSI_QSETS) {350 hw->num_sqsets = CSIO_MAX_SCSI_QSETS;351 hw->num_scsi_msix_cpus = CSIO_MAX_SCSI_CPU;352 }353 354 /* Initialize max_cpus, may get reduced during msix allocations */355 for (i = 0; i < hw->num_pports; i++)356 hw->scsi_cpu_info[i].max_cpus = hw->num_scsi_msix_cpus;357 358 csio_dbg(hw, "nsqsets:%d scpus:%d\n",359 hw->num_sqsets, hw->num_scsi_msix_cpus);360 361 csio_intr_enable(hw);362 363 if (hw->intr_mode != CSIO_IM_MSIX) {364 365 /* Allocate Forward interrupt iq. */366 hw->intr_iq_idx = csio_wr_alloc_q(hw, CSIO_INTR_IQSIZE,367 CSIO_INTR_WRSIZE, CSIO_INGRESS,368 (void *)hw, 0, 0, NULL);369 if (hw->intr_iq_idx == -1) {370 csio_err(hw,371 "Forward interrupt queue creation failed\n");372 goto intr_disable;373 }374 }375 376 /* Allocate the FW evt queue */377 hw->fwevt_iq_idx = csio_wr_alloc_q(hw, CSIO_FWEVT_IQSIZE,378 CSIO_FWEVT_WRSIZE,379 CSIO_INGRESS, (void *)hw,380 CSIO_FWEVT_FLBUFS, 0,381 csio_fwevt_intx_handler);382 if (hw->fwevt_iq_idx == -1) {383 csio_err(hw, "FW evt queue creation failed\n");384 goto intr_disable;385 }386 387 /* Allocate the mgmt queue */388 mgmtm->eq_idx = csio_wr_alloc_q(hw, CSIO_MGMT_EQSIZE,389 CSIO_MGMT_EQ_WRSIZE,390 CSIO_EGRESS, (void *)hw, 0, 0, NULL);391 if (mgmtm->eq_idx == -1) {392 csio_err(hw, "Failed to alloc egress queue for mgmt module\n");393 goto intr_disable;394 }395 396 /* Use FW IQ for MGMT req completion */397 mgmtm->iq_idx = hw->fwevt_iq_idx;398 399 /* Allocate SCSI queues */400 for (i = 0; i < hw->num_pports; i++) {401 info = &hw->scsi_cpu_info[i];402 403 for (j = 0; j < hw->num_scsi_msix_cpus; j++) {404 sqset = &hw->sqset[i][j];405 406 if (j >= info->max_cpus) {407 k = j % info->max_cpus;408 orig = &hw->sqset[i][k];409 sqset->eq_idx = orig->eq_idx;410 sqset->iq_idx = orig->iq_idx;411 continue;412 }413 414 idx = csio_wr_alloc_q(hw, csio_scsi_eqsize, 0,415 CSIO_EGRESS, (void *)hw, 0, 0,416 NULL);417 if (idx == -1) {418 csio_err(hw, "EQ creation failed for idx:%d\n",419 idx);420 goto intr_disable;421 }422 423 sqset->eq_idx = idx;424 425 idx = csio_wr_alloc_q(hw, CSIO_SCSI_IQSIZE,426 CSIO_SCSI_IQ_WRSZ, CSIO_INGRESS,427 (void *)hw, 0, 0,428 csio_scsi_intx_handler);429 if (idx == -1) {430 csio_err(hw, "IQ creation failed for idx:%d\n",431 idx);432 goto intr_disable;433 }434 sqset->iq_idx = idx;435 } /* for all CPUs */436 } /* For all ports */437 438 hw->flags |= CSIO_HWF_Q_MEM_ALLOCED;439 440 rv = csio_create_queues(hw);441 if (rv != 0)442 goto intr_disable;443 444 /*445 * Now request IRQs for the vectors. In the event of a failure,446 * cleanup is handled internally by this function.447 */448 rv = csio_request_irqs(hw);449 if (rv != 0)450 return -EINVAL;451 452 return 0;453 454intr_disable:455 csio_intr_disable(hw, false);456 457 return -EINVAL;458}459 460static int461csio_resource_alloc(struct csio_hw *hw)462{463 struct csio_wrm *wrm = csio_hw_to_wrm(hw);464 int rv = -ENOMEM;465 466 wrm->num_q = ((CSIO_MAX_SCSI_QSETS * 2) + CSIO_HW_NIQ +467 CSIO_HW_NEQ + CSIO_HW_NFLQ + CSIO_HW_NINTXQ);468 469 hw->mb_mempool = mempool_create_kmalloc_pool(CSIO_MIN_MEMPOOL_SZ,470 sizeof(struct csio_mb));471 if (!hw->mb_mempool)472 goto err;473 474 hw->rnode_mempool = mempool_create_kmalloc_pool(CSIO_MIN_MEMPOOL_SZ,475 sizeof(struct csio_rnode));476 if (!hw->rnode_mempool)477 goto err_free_mb_mempool;478 479 hw->scsi_dma_pool = dma_pool_create("csio_scsi_dma_pool",480 &hw->pdev->dev, CSIO_SCSI_RSP_LEN,481 8, 0);482 if (!hw->scsi_dma_pool)483 goto err_free_rn_pool;484 485 return 0;486 487err_free_rn_pool:488 mempool_destroy(hw->rnode_mempool);489 hw->rnode_mempool = NULL;490err_free_mb_mempool:491 mempool_destroy(hw->mb_mempool);492 hw->mb_mempool = NULL;493err:494 return rv;495}496 497static void498csio_resource_free(struct csio_hw *hw)499{500 dma_pool_destroy(hw->scsi_dma_pool);501 hw->scsi_dma_pool = NULL;502 mempool_destroy(hw->rnode_mempool);503 hw->rnode_mempool = NULL;504 mempool_destroy(hw->mb_mempool);505 hw->mb_mempool = NULL;506}507 508/*509 * csio_hw_alloc - Allocate and initialize the HW module.510 * @pdev: PCI device.511 *512 * Allocates HW structure, DMA, memory resources, maps BARS to513 * host memory and initializes HW module.514 */515static struct csio_hw *csio_hw_alloc(struct pci_dev *pdev)516{517 struct csio_hw *hw;518 519 hw = kzalloc(sizeof(struct csio_hw), GFP_KERNEL);520 if (!hw)521 goto err;522 523 hw->pdev = pdev;524 strscpy(hw->drv_version, CSIO_DRV_VERSION,525 sizeof(hw->drv_version));526 527 /* memory pool/DMA pool allocation */528 if (csio_resource_alloc(hw))529 goto err_free_hw;530 531 /* Get the start address of registers from BAR 0 */532 hw->regstart = ioremap(pci_resource_start(pdev, 0),533 pci_resource_len(pdev, 0));534 if (!hw->regstart) {535 csio_err(hw, "Could not map BAR 0, regstart = %p\n",536 hw->regstart);537 goto err_resource_free;538 }539 540 csio_hw_init_workers(hw);541 542 if (csio_hw_init(hw))543 goto err_unmap_bar;544 545 csio_dfs_create(hw);546 547 csio_dbg(hw, "hw:%p\n", hw);548 549 return hw;550 551err_unmap_bar:552 csio_hw_exit_workers(hw);553 iounmap(hw->regstart);554err_resource_free:555 csio_resource_free(hw);556err_free_hw:557 kfree(hw);558err:559 return NULL;560}561 562/*563 * csio_hw_free - Uninitialize and free the HW module.564 * @hw: The HW module565 *566 * Disable interrupts, uninit the HW module, free resources, free hw.567 */568static void569csio_hw_free(struct csio_hw *hw)570{571 csio_intr_disable(hw, true);572 csio_hw_exit_workers(hw);573 csio_hw_exit(hw);574 iounmap(hw->regstart);575 csio_dfs_destroy(hw);576 csio_resource_free(hw);577 kfree(hw);578}579 580/**581 * csio_shost_init - Create and initialize the lnode module.582 * @hw: The HW module.583 * @dev: The device associated with this invocation.584 * @probe: Called from probe context or not?585 * @pln: Parent lnode if any.586 *587 * Allocates lnode structure via scsi_host_alloc, initializes588 * shost, initializes lnode module and registers with SCSI ML589 * via scsi_host_add. This function is shared between physical and590 * virtual node ports.591 */592struct csio_lnode *593csio_shost_init(struct csio_hw *hw, struct device *dev,594 bool probe, struct csio_lnode *pln)595{596 struct Scsi_Host *shost = NULL;597 struct csio_lnode *ln;598 599 csio_fcoe_shost_template.cmd_per_lun = csio_lun_qdepth;600 csio_fcoe_shost_vport_template.cmd_per_lun = csio_lun_qdepth;601 602 /*603 * hw->pdev is the physical port's PCI dev structure,604 * which will be different from the NPIV dev structure.605 */606 if (dev == &hw->pdev->dev)607 shost = scsi_host_alloc(608 &csio_fcoe_shost_template,609 sizeof(struct csio_lnode));610 else611 shost = scsi_host_alloc(612 &csio_fcoe_shost_vport_template,613 sizeof(struct csio_lnode));614 615 if (!shost)616 goto err;617 618 ln = shost_priv(shost);619 memset(ln, 0, sizeof(struct csio_lnode));620 621 /* Link common lnode to this lnode */622 ln->dev_num = (shost->host_no << 16);623 624 shost->can_queue = CSIO_MAX_QUEUE;625 shost->this_id = -1;626 shost->unique_id = shost->host_no;627 shost->max_cmd_len = 16; /* Max CDB length supported */628 shost->max_id = min_t(uint32_t, csio_fcoe_rnodes,629 hw->fres_info.max_ssns);630 shost->max_lun = CSIO_MAX_LUN;631 if (dev == &hw->pdev->dev)632 shost->transportt = csio_fcoe_transport;633 else634 shost->transportt = csio_fcoe_transport_vport;635 636 /* root lnode */637 if (!hw->rln)638 hw->rln = ln;639 640 /* Other initialization here: Common, Transport specific */641 if (csio_lnode_init(ln, hw, pln))642 goto err_shost_put;643 644 if (scsi_add_host_with_dma(shost, dev, &hw->pdev->dev))645 goto err_lnode_exit;646 647 return ln;648 649err_lnode_exit:650 csio_lnode_exit(ln);651err_shost_put:652 scsi_host_put(shost);653err:654 return NULL;655}656 657/**658 * csio_shost_exit - De-instantiate the shost.659 * @ln: The lnode module corresponding to the shost.660 *661 */662void663csio_shost_exit(struct csio_lnode *ln)664{665 struct Scsi_Host *shost = csio_ln_to_shost(ln);666 struct csio_hw *hw = csio_lnode_to_hw(ln);667 668 /* Inform transport */669 fc_remove_host(shost);670 671 /* Inform SCSI ML */672 scsi_remove_host(shost);673 674 /* Flush all the events, so that any rnode removal events675 * already queued are all handled, before we remove the lnode.676 */677 spin_lock_irq(&hw->lock);678 csio_evtq_flush(hw);679 spin_unlock_irq(&hw->lock);680 681 csio_lnode_exit(ln);682 scsi_host_put(shost);683}684 685struct csio_lnode *686csio_lnode_alloc(struct csio_hw *hw)687{688 return csio_shost_init(hw, &hw->pdev->dev, false, NULL);689}690 691void692csio_lnodes_block_request(struct csio_hw *hw)693{694 struct Scsi_Host *shost;695 struct csio_lnode *sln;696 struct csio_lnode *ln;697 struct list_head *cur_ln, *cur_cln;698 struct csio_lnode **lnode_list;699 int cur_cnt = 0, ii;700 701 lnode_list = kzalloc((sizeof(struct csio_lnode *) * hw->num_lns),702 GFP_KERNEL);703 if (!lnode_list) {704 csio_err(hw, "Failed to allocate lnodes_list");705 return;706 }707 708 spin_lock_irq(&hw->lock);709 /* Traverse sibling lnodes */710 list_for_each(cur_ln, &hw->sln_head) {711 sln = (struct csio_lnode *) cur_ln;712 lnode_list[cur_cnt++] = sln;713 714 /* Traverse children lnodes */715 list_for_each(cur_cln, &sln->cln_head)716 lnode_list[cur_cnt++] = (struct csio_lnode *) cur_cln;717 }718 spin_unlock_irq(&hw->lock);719 720 for (ii = 0; ii < cur_cnt; ii++) {721 csio_dbg(hw, "Blocking IOs on lnode: %p\n", lnode_list[ii]);722 ln = lnode_list[ii];723 shost = csio_ln_to_shost(ln);724 scsi_block_requests(shost);725 726 }727 kfree(lnode_list);728}729 730void731csio_lnodes_unblock_request(struct csio_hw *hw)732{733 struct csio_lnode *ln;734 struct Scsi_Host *shost;735 struct csio_lnode *sln;736 struct list_head *cur_ln, *cur_cln;737 struct csio_lnode **lnode_list;738 int cur_cnt = 0, ii;739 740 lnode_list = kzalloc((sizeof(struct csio_lnode *) * hw->num_lns),741 GFP_KERNEL);742 if (!lnode_list) {743 csio_err(hw, "Failed to allocate lnodes_list");744 return;745 }746 747 spin_lock_irq(&hw->lock);748 /* Traverse sibling lnodes */749 list_for_each(cur_ln, &hw->sln_head) {750 sln = (struct csio_lnode *) cur_ln;751 lnode_list[cur_cnt++] = sln;752 753 /* Traverse children lnodes */754 list_for_each(cur_cln, &sln->cln_head)755 lnode_list[cur_cnt++] = (struct csio_lnode *) cur_cln;756 }757 spin_unlock_irq(&hw->lock);758 759 for (ii = 0; ii < cur_cnt; ii++) {760 csio_dbg(hw, "unblocking IOs on lnode: %p\n", lnode_list[ii]);761 ln = lnode_list[ii];762 shost = csio_ln_to_shost(ln);763 scsi_unblock_requests(shost);764 }765 kfree(lnode_list);766}767 768void769csio_lnodes_block_by_port(struct csio_hw *hw, uint8_t portid)770{771 struct csio_lnode *ln;772 struct Scsi_Host *shost;773 struct csio_lnode *sln;774 struct list_head *cur_ln, *cur_cln;775 struct csio_lnode **lnode_list;776 int cur_cnt = 0, ii;777 778 lnode_list = kzalloc((sizeof(struct csio_lnode *) * hw->num_lns),779 GFP_KERNEL);780 if (!lnode_list) {781 csio_err(hw, "Failed to allocate lnodes_list");782 return;783 }784 785 spin_lock_irq(&hw->lock);786 /* Traverse sibling lnodes */787 list_for_each(cur_ln, &hw->sln_head) {788 sln = (struct csio_lnode *) cur_ln;789 if (sln->portid != portid)790 continue;791 792 lnode_list[cur_cnt++] = sln;793 794 /* Traverse children lnodes */795 list_for_each(cur_cln, &sln->cln_head)796 lnode_list[cur_cnt++] = (struct csio_lnode *) cur_cln;797 }798 spin_unlock_irq(&hw->lock);799 800 for (ii = 0; ii < cur_cnt; ii++) {801 csio_dbg(hw, "Blocking IOs on lnode: %p\n", lnode_list[ii]);802 ln = lnode_list[ii];803 shost = csio_ln_to_shost(ln);804 scsi_block_requests(shost);805 }806 kfree(lnode_list);807}808 809void810csio_lnodes_unblock_by_port(struct csio_hw *hw, uint8_t portid)811{812 struct csio_lnode *ln;813 struct Scsi_Host *shost;814 struct csio_lnode *sln;815 struct list_head *cur_ln, *cur_cln;816 struct csio_lnode **lnode_list;817 int cur_cnt = 0, ii;818 819 lnode_list = kzalloc((sizeof(struct csio_lnode *) * hw->num_lns),820 GFP_KERNEL);821 if (!lnode_list) {822 csio_err(hw, "Failed to allocate lnodes_list");823 return;824 }825 826 spin_lock_irq(&hw->lock);827 /* Traverse sibling lnodes */828 list_for_each(cur_ln, &hw->sln_head) {829 sln = (struct csio_lnode *) cur_ln;830 if (sln->portid != portid)831 continue;832 lnode_list[cur_cnt++] = sln;833 834 /* Traverse children lnodes */835 list_for_each(cur_cln, &sln->cln_head)836 lnode_list[cur_cnt++] = (struct csio_lnode *) cur_cln;837 }838 spin_unlock_irq(&hw->lock);839 840 for (ii = 0; ii < cur_cnt; ii++) {841 csio_dbg(hw, "unblocking IOs on lnode: %p\n", lnode_list[ii]);842 ln = lnode_list[ii];843 shost = csio_ln_to_shost(ln);844 scsi_unblock_requests(shost);845 }846 kfree(lnode_list);847}848 849void850csio_lnodes_exit(struct csio_hw *hw, bool npiv)851{852 struct csio_lnode *sln;853 struct csio_lnode *ln;854 struct list_head *cur_ln, *cur_cln;855 struct csio_lnode **lnode_list;856 int cur_cnt = 0, ii;857 858 lnode_list = kzalloc((sizeof(struct csio_lnode *) * hw->num_lns),859 GFP_KERNEL);860 if (!lnode_list) {861 csio_err(hw, "lnodes_exit: Failed to allocate lnodes_list.\n");862 return;863 }864 865 /* Get all child lnodes(NPIV ports) */866 spin_lock_irq(&hw->lock);867 list_for_each(cur_ln, &hw->sln_head) {868 sln = (struct csio_lnode *) cur_ln;869 870 /* Traverse children lnodes */871 list_for_each(cur_cln, &sln->cln_head)872 lnode_list[cur_cnt++] = (struct csio_lnode *) cur_cln;873 }874 spin_unlock_irq(&hw->lock);875 876 /* Delete NPIV lnodes */877 for (ii = 0; ii < cur_cnt; ii++) {878 csio_dbg(hw, "Deleting child lnode: %p\n", lnode_list[ii]);879 ln = lnode_list[ii];880 fc_vport_terminate(ln->fc_vport);881 }882 883 /* Delete only npiv lnodes */884 if (npiv)885 goto free_lnodes;886 887 cur_cnt = 0;888 /* Get all physical lnodes */889 spin_lock_irq(&hw->lock);890 /* Traverse sibling lnodes */891 list_for_each(cur_ln, &hw->sln_head) {892 sln = (struct csio_lnode *) cur_ln;893 lnode_list[cur_cnt++] = sln;894 }895 spin_unlock_irq(&hw->lock);896 897 /* Delete physical lnodes */898 for (ii = 0; ii < cur_cnt; ii++) {899 csio_dbg(hw, "Deleting parent lnode: %p\n", lnode_list[ii]);900 csio_shost_exit(lnode_list[ii]);901 }902 903free_lnodes:904 kfree(lnode_list);905}906 907/*908 * csio_lnode_init_post: Set lnode attributes after starting HW.909 * @ln: lnode.910 *911 */912static void913csio_lnode_init_post(struct csio_lnode *ln)914{915 struct Scsi_Host *shost = csio_ln_to_shost(ln);916 917 csio_fchost_attr_init(ln);918 919 scsi_scan_host(shost);920}921 922/*923 * csio_probe_one - Instantiate this function.924 * @pdev: PCI device925 * @id: Device ID926 *927 * This is the .probe() callback of the driver. This function:928 * - Initializes the PCI function by enabling MMIO, setting bus929 * mastership and setting DMA mask.930 * - Allocates HW structure, DMA, memory resources, maps BARS to931 * host memory and initializes HW module.932 * - Allocates lnode structure via scsi_host_alloc, initializes933 * shost, initialized lnode module and registers with SCSI ML934 * via scsi_host_add.935 * - Enables interrupts, and starts the chip by kicking off the936 * HW state machine.937 * - Once hardware is ready, initiated scan of the host via938 * scsi_scan_host.939 */940static int csio_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)941{942 int rv;943 int bars;944 int i;945 struct csio_hw *hw;946 struct csio_lnode *ln;947 948 /* probe only T5 and T6 cards */949 if (!csio_is_t5((pdev->device & CSIO_HW_CHIP_MASK)) &&950 !csio_is_t6((pdev->device & CSIO_HW_CHIP_MASK)))951 return -ENODEV;952 953 rv = csio_pci_init(pdev, &bars);954 if (rv)955 goto err;956 957 hw = csio_hw_alloc(pdev);958 if (!hw) {959 rv = -ENODEV;960 goto err_pci_exit;961 }962 963 if (!pcie_relaxed_ordering_enabled(pdev))964 hw->flags |= CSIO_HWF_ROOT_NO_RELAXED_ORDERING;965 966 pci_set_drvdata(pdev, hw);967 968 rv = csio_hw_start(hw);969 if (rv) {970 if (rv == -EINVAL) {971 dev_err(&pdev->dev,972 "Failed to start FW, continuing in debug mode.\n");973 return 0;974 }975 goto err_lnode_exit;976 }977 978 sprintf(hw->fwrev_str, "%u.%u.%u.%u\n",979 FW_HDR_FW_VER_MAJOR_G(hw->fwrev),980 FW_HDR_FW_VER_MINOR_G(hw->fwrev),981 FW_HDR_FW_VER_MICRO_G(hw->fwrev),982 FW_HDR_FW_VER_BUILD_G(hw->fwrev));983 984 for (i = 0; i < hw->num_pports; i++) {985 ln = csio_shost_init(hw, &pdev->dev, true, NULL);986 if (!ln) {987 rv = -ENODEV;988 break;989 }990 /* Initialize portid */991 ln->portid = hw->pport[i].portid;992 993 spin_lock_irq(&hw->lock);994 if (csio_lnode_start(ln) != 0)995 rv = -ENODEV;996 spin_unlock_irq(&hw->lock);997 998 if (rv)999 break;1000 1001 csio_lnode_init_post(ln);1002 }1003 1004 if (rv)1005 goto err_lnode_exit;1006 1007 return 0;1008 1009err_lnode_exit:1010 csio_lnodes_block_request(hw);1011 spin_lock_irq(&hw->lock);1012 csio_hw_stop(hw);1013 spin_unlock_irq(&hw->lock);1014 csio_lnodes_unblock_request(hw);1015 csio_lnodes_exit(hw, 0);1016 csio_hw_free(hw);1017err_pci_exit:1018 csio_pci_exit(pdev, &bars);1019err:1020 dev_err(&pdev->dev, "probe of device failed: %d\n", rv);1021 return rv;1022}1023 1024/*1025 * csio_remove_one - Remove one instance of the driver at this PCI function.1026 * @pdev: PCI device1027 *1028 * Used during hotplug operation.1029 */1030static void csio_remove_one(struct pci_dev *pdev)1031{1032 struct csio_hw *hw = pci_get_drvdata(pdev);1033 int bars = pci_select_bars(pdev, IORESOURCE_MEM);1034 1035 csio_lnodes_block_request(hw);1036 spin_lock_irq(&hw->lock);1037 1038 /* Stops lnode, Rnode s/m1039 * Quiesce IOs.1040 * All sessions with remote ports are unregistered.1041 */1042 csio_hw_stop(hw);1043 spin_unlock_irq(&hw->lock);1044 csio_lnodes_unblock_request(hw);1045 1046 csio_lnodes_exit(hw, 0);1047 csio_hw_free(hw);1048 csio_pci_exit(pdev, &bars);1049}1050 1051/*1052 * csio_pci_error_detected - PCI error was detected1053 * @pdev: PCI device1054 *1055 */1056static pci_ers_result_t1057csio_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state)1058{1059 struct csio_hw *hw = pci_get_drvdata(pdev);1060 1061 csio_lnodes_block_request(hw);1062 spin_lock_irq(&hw->lock);1063 1064 /* Post PCI error detected evt to HW s/m1065 * HW s/m handles this evt by quiescing IOs, unregisters rports1066 * and finally takes the device to offline.1067 */1068 csio_post_event(&hw->sm, CSIO_HWE_PCIERR_DETECTED);1069 spin_unlock_irq(&hw->lock);1070 csio_lnodes_unblock_request(hw);1071 csio_lnodes_exit(hw, 0);1072 csio_intr_disable(hw, true);1073 pci_disable_device(pdev);1074 return state == pci_channel_io_perm_failure ?1075 PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_NEED_RESET;1076}1077 1078/*1079 * csio_pci_slot_reset - PCI slot has been reset.1080 * @pdev: PCI device1081 *1082 */1083static pci_ers_result_t1084csio_pci_slot_reset(struct pci_dev *pdev)1085{1086 struct csio_hw *hw = pci_get_drvdata(pdev);1087 int ready;1088 1089 if (pci_enable_device(pdev)) {1090 dev_err(&pdev->dev, "cannot re-enable device in slot reset\n");1091 return PCI_ERS_RESULT_DISCONNECT;1092 }1093 1094 pci_set_master(pdev);1095 pci_restore_state(pdev);1096 pci_save_state(pdev);1097 1098 /* Bring HW s/m to ready state.1099 * but don't resume IOs.1100 */1101 spin_lock_irq(&hw->lock);1102 csio_post_event(&hw->sm, CSIO_HWE_PCIERR_SLOT_RESET);1103 ready = csio_is_hw_ready(hw);1104 spin_unlock_irq(&hw->lock);1105 1106 if (ready) {1107 return PCI_ERS_RESULT_RECOVERED;1108 } else {1109 dev_err(&pdev->dev, "Can't initialize HW when in slot reset\n");1110 return PCI_ERS_RESULT_DISCONNECT;1111 }1112}1113 1114/*1115 * csio_pci_resume - Resume normal operations1116 * @pdev: PCI device1117 *1118 */1119static void1120csio_pci_resume(struct pci_dev *pdev)1121{1122 struct csio_hw *hw = pci_get_drvdata(pdev);1123 struct csio_lnode *ln;1124 int rv = 0;1125 int i;1126 1127 /* Bring the LINK UP and Resume IO */1128 1129 for (i = 0; i < hw->num_pports; i++) {1130 ln = csio_shost_init(hw, &pdev->dev, true, NULL);1131 if (!ln) {1132 rv = -ENODEV;1133 break;1134 }1135 /* Initialize portid */1136 ln->portid = hw->pport[i].portid;1137 1138 spin_lock_irq(&hw->lock);1139 if (csio_lnode_start(ln) != 0)1140 rv = -ENODEV;1141 spin_unlock_irq(&hw->lock);1142 1143 if (rv)1144 break;1145 1146 csio_lnode_init_post(ln);1147 }1148 1149 if (rv)1150 goto err_resume_exit;1151 1152 return;1153 1154err_resume_exit:1155 csio_lnodes_block_request(hw);1156 spin_lock_irq(&hw->lock);1157 csio_hw_stop(hw);1158 spin_unlock_irq(&hw->lock);1159 csio_lnodes_unblock_request(hw);1160 csio_lnodes_exit(hw, 0);1161 csio_hw_free(hw);1162 dev_err(&pdev->dev, "resume of device failed: %d\n", rv);1163}1164 1165static struct pci_error_handlers csio_err_handler = {1166 .error_detected = csio_pci_error_detected,1167 .slot_reset = csio_pci_slot_reset,1168 .resume = csio_pci_resume,1169};1170 1171/*1172 * Macros needed to support the PCI Device ID Table ...1173 */1174#define CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN \1175 static const struct pci_device_id csio_pci_tbl[] = {1176/* Define for FCoE uses PF6 */1177#define CH_PCI_DEVICE_ID_FUNCTION 0x61178 1179#define CH_PCI_ID_TABLE_ENTRY(devid) \1180 { PCI_VDEVICE(CHELSIO, (devid)), 0 }1181 1182#define CH_PCI_DEVICE_ID_TABLE_DEFINE_END { 0, } }1183 1184#include "t4_pci_id_tbl.h"1185 1186static struct pci_driver csio_pci_driver = {1187 .name = KBUILD_MODNAME,1188 .id_table = csio_pci_tbl,1189 .probe = csio_probe_one,1190 .remove = csio_remove_one,1191 .err_handler = &csio_err_handler,1192};1193 1194/*1195 * csio_init - Chelsio storage driver initialization function.1196 *1197 */1198static int __init1199csio_init(void)1200{1201 int rv = -ENOMEM;1202 1203 pr_info("%s %s\n", CSIO_DRV_DESC, CSIO_DRV_VERSION);1204 1205 csio_dfs_init();1206 1207 csio_fcoe_transport = fc_attach_transport(&csio_fc_transport_funcs);1208 if (!csio_fcoe_transport)1209 goto err;1210 1211 csio_fcoe_transport_vport =1212 fc_attach_transport(&csio_fc_transport_vport_funcs);1213 if (!csio_fcoe_transport_vport)1214 goto err_vport;1215 1216 rv = pci_register_driver(&csio_pci_driver);1217 if (rv)1218 goto err_pci;1219 1220 return 0;1221 1222err_pci:1223 fc_release_transport(csio_fcoe_transport_vport);1224err_vport:1225 fc_release_transport(csio_fcoe_transport);1226err:1227 csio_dfs_exit();1228 return rv;1229}1230 1231/*1232 * csio_exit - Chelsio storage driver uninitialization .1233 *1234 * Function that gets called in the unload path.1235 */1236static void __exit1237csio_exit(void)1238{1239 pci_unregister_driver(&csio_pci_driver);1240 csio_dfs_exit();1241 fc_release_transport(csio_fcoe_transport_vport);1242 fc_release_transport(csio_fcoe_transport);1243}1244 1245module_init(csio_init);1246module_exit(csio_exit);1247MODULE_AUTHOR(CSIO_DRV_AUTHOR);1248MODULE_DESCRIPTION(CSIO_DRV_DESC);1249MODULE_LICENSE("Dual BSD/GPL");1250MODULE_DEVICE_TABLE(pci, csio_pci_tbl);1251MODULE_VERSION(CSIO_DRV_VERSION);1252MODULE_FIRMWARE(FW_FNAME_T5);1253MODULE_FIRMWARE(FW_FNAME_T6);1254MODULE_SOFTDEP("pre: cxgb4");1255