Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/browser/locales/en-US/browser/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 1 kB image not shown  

Quelle  pci_io.h   Sprache: C

 
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_S390_PCI_IO_H
#define _ASM_S390_PCI_IO_H

#ifdef CONFIG_PCI

#include <linux/kernel.h>
#include <linux/slab.h>
#include <asm/pci_insn.h>

/* I/O size constraints */
#define ZPCI_MAX_READ_SIZE 8
#define ZPCI_MAX_WRITE_SIZE 128
#define ZPCI_BOUNDARY_SIZE (1 << 12)
#define ZPCI_BOUNDARY_MASK (ZPCI_BOUNDARY_SIZE - 1)

/* I/O Map */
#define ZPCI_IOMAP_SHIFT  48
#define ZPCI_IOMAP_ADDR_SHIFT  62
#define ZPCI_IOMAP_ADDR_BASE  (1UL << ZPCI_IOMAP_ADDR_SHIFT)
#define ZPCI_IOMAP_ADDR_OFF_MASK ((1UL << ZPCI_IOMAP_SHIFT) - 1)
#define ZPCI_IOMAP_MAX_ENTRIES       \
 (1UL << (ZPCI_IOMAP_ADDR_SHIFT - ZPCI_IOMAP_SHIFT))
#define ZPCI_IOMAP_ADDR_IDX_MASK      \
 ((ZPCI_IOMAP_ADDR_BASE - 1) & ~ZPCI_IOMAP_ADDR_OFF_MASK)

struct zpci_iomap_entry {
 u32 fh;
 u8 bar;
 u16 count;
};

extern struct zpci_iomap_entry *zpci_iomap_start;

#define ZPCI_ADDR(idx) (ZPCI_IOMAP_ADDR_BASE | ((u64) idx << ZPCI_IOMAP_SHIFT))
#define ZPCI_IDX(addr)        \
 (((__force u64) addr & ZPCI_IOMAP_ADDR_IDX_MASK) >> ZPCI_IOMAP_SHIFT)
#define ZPCI_OFFSET(addr)       \
 ((__force u64) addr & ZPCI_IOMAP_ADDR_OFF_MASK)

#define ZPCI_CREATE_REQ(handle, space, len)     \
 ((u64) handle << 32 | space << 16 | len)

#define zpci_read(LENGTH, RETTYPE)      \
static inline RETTYPE zpci_read_##RETTYPE(const volatile void __iomem *addr) \
{          \
 u64 data;        \
 int rc;         \
          \
 rc = zpci_load(&data, addr, LENGTH);     \
 if (rc)         \
  data = -1ULL;       \
 return (RETTYPE) data;       \
}

#define zpci_write(LENGTH, VALTYPE)      \
static inline void zpci_write_##VALTYPE(VALTYPE val,    \
     const volatile void __iomem *addr) \
{          \
 u64 data = (VALTYPE) val;      \
          \
 zpci_store(addr, data, LENGTH);      \
}

zpci_read(8, u64)
zpci_read(4, u32)
zpci_read(2, u16)
zpci_read(1, u8)
zpci_write(8, u64)
zpci_write(4, u32)
zpci_write(2, u16)
zpci_write(1, u8)

static inline int zpci_write_single(volatile void __iomem *dst, const void *src,
        unsigned long len)
{
 u64 val;

 switch (len) {
 case 1:
  val = (u64) *((u8 *) src);
  break;
 case 2:
  val = (u64) *((u16 *) src);
  break;
 case 4:
  val = (u64) *((u32 *) src);
  break;
 case 8:
  val = (u64) *((u64 *) src);
  break;
 default:
  val = 0;  /* let FW report error */
  break;
 }
 return zpci_store(dst, val, len);
}

static inline int zpci_read_single(void *dst, const volatile void __iomem *src,
       unsigned long len)
{
 u64 data;
 int cc;

 cc = zpci_load(&data, src, len);
 if (cc)
  goto out;

 switch (len) {
 case 1:
  *((u8 *) dst) = (u8) data;
  break;
 case 2:
  *((u16 *) dst) = (u16) data;
  break;
 case 4:
  *((u32 *) dst) = (u32) data;
  break;
 case 8:
  *((u64 *) dst) = (u64) data;
  break;
 }
out:
 return cc;
}

int zpci_write_block(volatile void __iomem *dst, const void *src,
       unsigned long len);

static inline int zpci_get_max_io_size(u64 src, u64 dst, int len, int max)
{
 int offset = dst & ZPCI_BOUNDARY_MASK;
 int size;

 size = min3(len, ZPCI_BOUNDARY_SIZE - offset, max);
 if (IS_ALIGNED(src, 8) && IS_ALIGNED(dst, 8) && IS_ALIGNED(size, 8))
  return size;

 if (size >= 8)
  return 8;
 return rounddown_pow_of_two(size);
}

static inline int zpci_memcpy_fromio(void *dst,
         const volatile void __iomem *src,
         size_t n)
{
 int size, rc = 0;

 while (n > 0) {
  size = zpci_get_max_io_size((u64 __force) src,
         (u64) dst, n,
         ZPCI_MAX_READ_SIZE);
  rc = zpci_read_single(dst, src, size);
  if (rc)
   break;
  src += size;
  dst += size;
  n -= size;
 }
 return rc;
}

static inline int zpci_memcpy_toio(volatile void __iomem *dst,
       const void *src, size_t n)
{
 int size, rc = 0;

 if (!src)
  return -EINVAL;

 while (n > 0) {
  size = zpci_get_max_io_size((u64 __force) dst,
         (u64) src, n,
         ZPCI_MAX_WRITE_SIZE);
  if (size > 8) /* main path */
   rc = zpci_write_block(dst, src, size);
  else
   rc = zpci_write_single(dst, src, size);
  if (rc)
   break;
  src += size;
  dst += size;
  n -= size;
 }
 return rc;
}

static inline int zpci_memset_io(volatile void __iomem *dst,
     int val, size_t count)
{
 u8 *src = kmalloc(count, GFP_KERNEL);
 int rc;

 if (src == NULL)
  return -ENOMEM;
 memset(src, val, count);

 rc = zpci_memcpy_toio(dst, src, count);
 kfree(src);
 return rc;
}

#endif /* CONFIG_PCI */

#endif /* _ASM_S390_PCI_IO_H */

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

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