Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/drivers/scsi/elx/efct/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 4 kB image not shown  

Quelle  efct_io.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2021 Broadcom. All Rights Reserved. The term
 * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
 */


#include "efct_driver.h"
#include "efct_hw.h"
#include "efct_io.h"

struct efct_io_pool {
 struct efct *efct;
 spinlock_t lock; /* IO pool lock */
 u32 io_num_ios;  /* Total IOs allocated */
 struct efct_io *ios[EFCT_NUM_SCSI_IOS];
 struct list_head freelist;

};

struct efct_io_pool *
efct_io_pool_create(struct efct *efct, u32 num_sgl)
{
 u32 i = 0;
 struct efct_io_pool *io_pool;
 struct efct_io *io;

 /* Allocate the IO pool */
 io_pool = kzalloc(sizeof(*io_pool), GFP_KERNEL);
 if (!io_pool)
  return NULL;

 io_pool->efct = efct;
 INIT_LIST_HEAD(&io_pool->freelist);
 /* initialize IO pool lock */
 spin_lock_init(&io_pool->lock);

 for (i = 0; i < EFCT_NUM_SCSI_IOS; i++) {
  io = kzalloc(sizeof(*io), GFP_KERNEL);
  if (!io)
   break;

  io_pool->io_num_ios++;
  io_pool->ios[i] = io;
  io->tag = i;
  io->instance_index = i;

  /* Allocate a response buffer */
  io->rspbuf.size = SCSI_RSP_BUF_LENGTH;
  io->rspbuf.virt = dma_alloc_coherent(&efct->pci->dev,
           io->rspbuf.size,
           &io->rspbuf.phys, GFP_KERNEL);
  if (!io->rspbuf.virt) {
   efc_log_err(efct, "dma_alloc rspbuf failed\n");
   efct_io_pool_free(io_pool);
   return NULL;
  }

  /* Allocate SGL */
  io->sgl = kzalloc(sizeof(*io->sgl) * num_sgl, GFP_KERNEL);
  if (!io->sgl) {
   efct_io_pool_free(io_pool);
   return NULL;
  }

  io->sgl_allocated = num_sgl;
  io->sgl_count = 0;

  INIT_LIST_HEAD(&io->list_entry);
  list_add_tail(&io->list_entry, &io_pool->freelist);
 }

 return io_pool;
}

int
efct_io_pool_free(struct efct_io_pool *io_pool)
{
 struct efct *efct;
 u32 i;
 struct efct_io *io;

 if (io_pool) {
  efct = io_pool->efct;

  for (i = 0; i < io_pool->io_num_ios; i++) {
   io = io_pool->ios[i];
   if (!io)
    continue;

   kfree(io->sgl);
   dma_free_coherent(&efct->pci->dev,
       io->rspbuf.size, io->rspbuf.virt,
       io->rspbuf.phys);
   memset(&io->rspbuf, 0, sizeof(struct efc_dma));
  }

  kfree(io_pool);
  efct->xport->io_pool = NULL;
 }

 return 0;
}

struct efct_io *
efct_io_pool_io_alloc(struct efct_io_pool *io_pool)
{
 struct efct_io *io = NULL;
 struct efct *efct;
 unsigned long flags = 0;

 efct = io_pool->efct;

 spin_lock_irqsave(&io_pool->lock, flags);

 if (!list_empty(&io_pool->freelist)) {
  io = list_first_entry(&io_pool->freelist, struct efct_io,
          list_entry);
  list_del_init(&io->list_entry);
 }

 spin_unlock_irqrestore(&io_pool->lock, flags);

 if (!io)
  return NULL;

 io->io_type = EFCT_IO_TYPE_MAX;
 io->hio_type = EFCT_HW_IO_MAX;
 io->hio = NULL;
 io->transferred = 0;
 io->efct = efct;
 io->timeout = 0;
 io->sgl_count = 0;
 io->tgt_task_tag = 0;
 io->init_task_tag = 0;
 io->hw_tag = 0;
 io->display_name = "pending";
 io->seq_init = 0;
 io->io_free = 0;
 io->release = NULL;
 atomic_add_return(1, &efct->xport->io_active_count);
 atomic_add_return(1, &efct->xport->io_total_alloc);
 return io;
}

/* Free an object used to track an IO */
void
efct_io_pool_io_free(struct efct_io_pool *io_pool, struct efct_io *io)
{
 struct efct *efct;
 struct efct_hw_io *hio = NULL;
 unsigned long flags = 0;

 efct = io_pool->efct;

 spin_lock_irqsave(&io_pool->lock, flags);
 hio = io->hio;
 io->hio = NULL;
 io->io_free = 1;
 INIT_LIST_HEAD(&io->list_entry);
 list_add(&io->list_entry, &io_pool->freelist);
 spin_unlock_irqrestore(&io_pool->lock, flags);

 if (hio)
  efct_hw_io_free(&efct->hw, hio);

 atomic_sub_return(1, &efct->xport->io_active_count);
 atomic_add_return(1, &efct->xport->io_total_free);
}

/* Find an I/O given it's node and ox_id */
struct efct_io *
efct_io_find_tgt_io(struct efct *efct, struct efct_node *node,
      u16 ox_id, u16 rx_id)
{
 struct efct_io *io = NULL;
 unsigned long flags = 0;
 u8 found = false;

 spin_lock_irqsave(&node->active_ios_lock, flags);
 list_for_each_entry(io, &node->active_ios, list_entry) {
  if ((io->cmd_tgt && io->init_task_tag == ox_id) &&
      (rx_id == 0xffff || io->tgt_task_tag == rx_id)) {
   if (kref_get_unless_zero(&io->ref))
    found = true;
   break;
  }
 }
 spin_unlock_irqrestore(&node->active_ios_lock, flags);
 return found ? io : NULL;
}

Messung V0.5
C=95 H=94 G=94

¤ Dauer der Verarbeitung: 0.1 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.