// SPDX-License-Identifier: GPL-2.0-or-later /* * Device driver for the SYMBIOS/LSILOGIC 53C8XX and 53C1010 family * of PCI-SCSI IO processors. * * Copyright (C) 1999-2001 Gerard Roudier <[email protected]> * * This driver is derived from the Linux sym53c8xx driver. * Copyright (C) 1998-2000 Gerard Roudier * * The sym53c8xx driver is derived from the ncr53c8xx driver that had been * a port of the FreeBSD ncr driver to Linux-1.2.13. * * The original ncr driver has been written for 386bsd and FreeBSD by * Wolfgang Stanglmeier <[email protected]> * Stefan Esser <[email protected]> * Copyright (C) 1994 Wolfgang Stanglmeier * * Other major contributions: * * NVRAM detection and reading. * Copyright (C) 1997 Richard Waltham <[email protected]> * *----------------------------------------------------------------------------- */ #include "sym_glue.h" /* * Simple power of two buddy-like generic allocator. * Provides naturally aligned memory chunks. * * This simple code is not intended to be fast, but to * provide power of 2 aligned memory allocations. * Since the SCRIPTS processor only supplies 8 bit arithmetic, * this allocator allows simple and fast address calculations * from the SCRIPTS code. In addition, cache line alignment * is guaranteed for power of 2 cache line size. * * This allocator has been developed for the Linux sym53c8xx * driver, since this O/S does not provide naturally aligned * allocations. * It has the advantage of allowing the driver to use private * pages of memory that will be useful if we ever need to deal * with IO MMUs for PCI. */ static void *___sym_malloc(m_pool_p mp, int size) { … } /* * Counter-part of the generic allocator. */ static void ___sym_mfree(m_pool_p mp, void *ptr, int size) { … } /* * Verbose and zeroing allocator that wrapps to the generic allocator. */ static void *__sym_calloc2(m_pool_p mp, int size, char *name, int uflags) { … } #define __sym_calloc(mp, s, n) … /* * Its counter-part. */ static void __sym_mfree(m_pool_p mp, void *ptr, int size, char *name) { … } /* * Default memory pool we donnot need to involve in DMA. * * With DMA abstraction, we use functions (methods), to * distinguish between non DMAable memory and DMAable memory. */ static void *___mp0_get_mem_cluster(m_pool_p mp) { … } #ifdef SYM_MEM_FREE_UNUSED static void ___mp0_free_mem_cluster(m_pool_p mp, void *m) { … } #else #define ___mp0_free_mem_cluster … #endif static struct sym_m_pool mp0 = …; /* * Methods that maintains DMAable pools according to user allocations. * New pools are created on the fly when a new pool id is provided. * They are deleted on the fly when they get emptied. */ /* Get a memory cluster that matches the DMA constraints of a given pool */ static void * ___get_dma_mem_cluster(m_pool_p mp) { … } #ifdef SYM_MEM_FREE_UNUSED /* Free a memory cluster and associated resources for DMA */ static void ___free_dma_mem_cluster(m_pool_p mp, void *m) { … } #endif /* Fetch the memory pool for a given pool id (i.e. DMA constraints) */ static inline m_pool_p ___get_dma_pool(m_pool_ident_t dev_dmat) { … } /* Create a new memory DMAable pool (when fetch failed) */ static m_pool_p ___cre_dma_pool(m_pool_ident_t dev_dmat) { … } #ifdef SYM_MEM_FREE_UNUSED /* Destroy a DMAable memory pool (when got emptied) */ static void ___del_dma_pool(m_pool_p p) { … } #endif /* This lock protects only the memory allocation/free. */ static DEFINE_SPINLOCK(sym53c8xx_lock); /* * Actual allocator for DMAable memory. */ void *__sym_calloc_dma(m_pool_ident_t dev_dmat, int size, char *name) { … } void __sym_mfree_dma(m_pool_ident_t dev_dmat, void *m, int size, char *name) { … } /* * Actual virtual to bus physical address translator * for 32 bit addressable DMAable memory. */ dma_addr_t __vtobus(m_pool_ident_t dev_dmat, void *m) { … }