Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/infiniband/hw/mthca/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 7 kB image not shown  

Quelle  mthca_reset.c   Sprache: C

 
/*
 * Copyright (c) 2004 Topspin Communications.  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.
 */


#include <linux/errno.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/slab.h>

#include "mthca_dev.h"
#include "mthca_cmd.h"

int mthca_reset(struct mthca_dev *mdev)
{
 int i;
 int err = 0;
 u32 *hca_header    = NULL;
 u32 *bridge_header = NULL;
 struct pci_dev *bridge = NULL;
 int bridge_pcix_cap = 0;
 int hca_pcie_cap = 0;
 int hca_pcix_cap = 0;

 u16 devctl;
 u16 linkctl;

#define MTHCA_RESET_OFFSET 0xf0010
#define MTHCA_RESET_VALUE  swab32(1)

 /*
 * Reset the chip.  This is somewhat ugly because we have to
 * save off the PCI header before reset and then restore it
 * after the chip reboots.  We skip config space offsets 22
 * and 23 since those have a special meaning.
 *
 * To make matters worse, for Tavor (PCI-X HCA) we have to
 * find the associated bridge device and save off its PCI
 * header as well.
 */


 if (!(mdev->mthca_flags & MTHCA_FLAG_PCIE)) {
  /* Look for the bridge -- its device ID will be 2 more
   than HCA's device ID. */

  while ((bridge = pci_get_device(mdev->pdev->vendor,
      mdev->pdev->device + 2,
      bridge)) != NULL) {
   if (bridge->hdr_type    == PCI_HEADER_TYPE_BRIDGE &&
       bridge->subordinate == mdev->pdev->bus) {
    mthca_dbg(mdev, "Found bridge: %s\n",
       pci_name(bridge));
    break;
   }
  }

  if (!bridge) {
   /*
 * Didn't find a bridge for a Tavor device --
 * assume we're in no-bridge mode and hope for
 * the best.
 */

   mthca_warn(mdev, "No bridge found for %s\n",
      pci_name(mdev->pdev));
  }

 }

 /* For Arbel do we need to save off the full 4K PCI Express header?? */
 hca_header = kmalloc(256, GFP_KERNEL);
 if (!hca_header) {
  err = -ENOMEM;
  goto put_dev;
 }

 for (i = 0; i < 64; ++i) {
  if (i == 22 || i == 23)
   continue;
  if (pci_read_config_dword(mdev->pdev, i * 4, hca_header + i)) {
   err = -ENODEV;
   mthca_err(mdev, "Couldn't save HCA "
      "PCI header, aborting.\n");
   goto free_hca;
  }
 }

 hca_pcix_cap = pci_find_capability(mdev->pdev, PCI_CAP_ID_PCIX);
 hca_pcie_cap = pci_pcie_cap(mdev->pdev);

 if (bridge) {
  bridge_header = kmalloc(256, GFP_KERNEL);
  if (!bridge_header) {
   err = -ENOMEM;
   goto free_hca;
  }

  for (i = 0; i < 64; ++i) {
   if (i == 22 || i == 23)
    continue;
   if (pci_read_config_dword(bridge, i * 4, bridge_header + i)) {
    err = -ENODEV;
    mthca_err(mdev, "Couldn't save HCA bridge "
       "PCI header, aborting.\n");
    goto free_bh;
   }
  }
  bridge_pcix_cap = pci_find_capability(bridge, PCI_CAP_ID_PCIX);
  if (!bridge_pcix_cap) {
    err = -ENODEV;
    mthca_err(mdev, "Couldn't locate HCA bridge "
       "PCI-X capability, aborting.\n");
    goto free_bh;
  }
 }

 /* actually hit reset */
 {
  void __iomem *reset = ioremap(pci_resource_start(mdev->pdev, 0) +
           MTHCA_RESET_OFFSET, 4);

  if (!reset) {
   err = -ENOMEM;
   mthca_err(mdev, "Couldn't map HCA reset register, "
      "aborting.\n");
   goto free_bh;
  }

  writel(MTHCA_RESET_VALUE, reset);
  iounmap(reset);
 }

 /* Docs say to wait one second before accessing device */
 msleep(1000);

 /* Now wait for PCI device to start responding again */
 {
  u32 v;
  int c = 0;

  for (c = 0; c < 100; ++c) {
   if (pci_read_config_dword(bridge ? bridge : mdev->pdev, 0, &v)) {
    err = -ENODEV;
    mthca_err(mdev, "Couldn't access HCA after reset, "
       "aborting.\n");
    goto free_bh;
   }

   if (v != 0xffffffff)
    goto good;

   msleep(100);
  }

  err = -ENODEV;
  mthca_err(mdev, "PCI device did not come back after reset, "
     "aborting.\n");
  goto free_bh;
 }

good:
 /* Now restore the PCI headers */
 if (bridge) {
  if (pci_write_config_dword(bridge, bridge_pcix_cap + 0x8,
     bridge_header[(bridge_pcix_cap + 0x8) / 4])) {
   err = -ENODEV;
   mthca_err(mdev, "Couldn't restore HCA bridge Upstream "
      "split transaction control, aborting.\n");
   goto free_bh;
  }
  if (pci_write_config_dword(bridge, bridge_pcix_cap + 0xc,
     bridge_header[(bridge_pcix_cap + 0xc) / 4])) {
   err = -ENODEV;
   mthca_err(mdev, "Couldn't restore HCA bridge Downstream "
      "split transaction control, aborting.\n");
   goto free_bh;
  }
  /*
 * Bridge control register is at 0x3e, so we'll
 * naturally restore it last in this loop.
 */

  for (i = 0; i < 16; ++i) {
   if (i * 4 == PCI_COMMAND)
    continue;

   if (pci_write_config_dword(bridge, i * 4, bridge_header[i])) {
    err = -ENODEV;
    mthca_err(mdev, "Couldn't restore HCA bridge reg %x, "
       "aborting.\n", i);
    goto free_bh;
   }
  }

  if (pci_write_config_dword(bridge, PCI_COMMAND,
        bridge_header[PCI_COMMAND / 4])) {
   err = -ENODEV;
   mthca_err(mdev, "Couldn't restore HCA bridge COMMAND, "
      "aborting.\n");
   goto free_bh;
  }
 }

 if (hca_pcix_cap) {
  if (pci_write_config_dword(mdev->pdev, hca_pcix_cap,
     hca_header[hca_pcix_cap / 4])) {
   err = -ENODEV;
   mthca_err(mdev, "Couldn't restore HCA PCI-X "
      "command register, aborting.\n");
   goto free_bh;
  }
 }

 if (hca_pcie_cap) {
  devctl = hca_header[(hca_pcie_cap + PCI_EXP_DEVCTL) / 4];
  if (pcie_capability_write_word(mdev->pdev, PCI_EXP_DEVCTL,
            devctl)) {
   err = -ENODEV;
   mthca_err(mdev, "Couldn't restore HCA PCI Express "
      "Device Control register, aborting.\n");
   goto free_bh;
  }
  linkctl = hca_header[(hca_pcie_cap + PCI_EXP_LNKCTL) / 4];
  if (pcie_capability_write_word(mdev->pdev, PCI_EXP_LNKCTL,
            linkctl)) {
   err = -ENODEV;
   mthca_err(mdev, "Couldn't restore HCA PCI Express "
      "Link control register, aborting.\n");
   goto free_bh;
  }
 }

 for (i = 0; i < 16; ++i) {
  if (i * 4 == PCI_COMMAND)
   continue;

  if (pci_write_config_dword(mdev->pdev, i * 4, hca_header[i])) {
   err = -ENODEV;
   mthca_err(mdev, "Couldn't restore HCA reg %x, "
      "aborting.\n", i);
   goto free_bh;
  }
 }

 if (pci_write_config_dword(mdev->pdev, PCI_COMMAND,
       hca_header[PCI_COMMAND / 4])) {
  err = -ENODEV;
  mthca_err(mdev, "Couldn't restore HCA COMMAND, "
     "aborting.\n");
 }
free_bh:
 kfree(bridge_header);
free_hca:
 kfree(hca_header);
put_dev:
 pci_dev_put(bridge);
 return err;
}

Messung V0.5
C=97 H=32 G=72

¤ Dauer der Verarbeitung: 0.0 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

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.