Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 27 Dec 2010 07:38:33 +0000 (UTC)
From:      Jeff Roberson <jeff@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r216732 - in projects/ofed/head/sys/ofed: drivers/infiniband/hw/mlx4 drivers/infiniband/hw/mthca drivers/net/mlx4 include/linux
Message-ID:  <201012270738.oBR7cXbL015192@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jeff
Date: Mon Dec 27 07:38:33 2010
New Revision: 216732
URL: http://svn.freebsd.org/changeset/base/216732

Log:
   - Eliminate the laregest source of linux incompatibilities in drivers
     by supplying a compatible iounmap and ioremap.  A hash of addresses
     and lenghts was necessary to remember the length for pmap_unmapdev.
  
  Sponsored by:	Isilon Systems, iX Systems, and Panasas.

Modified:
  projects/ofed/head/sys/ofed/drivers/infiniband/hw/mlx4/main.c
  projects/ofed/head/sys/ofed/drivers/infiniband/hw/mthca/mthca_av.c
  projects/ofed/head/sys/ofed/drivers/infiniband/hw/mthca/mthca_catas.c
  projects/ofed/head/sys/ofed/drivers/infiniband/hw/mthca/mthca_cmd.c
  projects/ofed/head/sys/ofed/drivers/infiniband/hw/mthca/mthca_eq.c
  projects/ofed/head/sys/ofed/drivers/infiniband/hw/mthca/mthca_main.c
  projects/ofed/head/sys/ofed/drivers/infiniband/hw/mthca/mthca_mr.c
  projects/ofed/head/sys/ofed/drivers/infiniband/hw/mthca/mthca_reset.c
  projects/ofed/head/sys/ofed/drivers/net/mlx4/catas.c
  projects/ofed/head/sys/ofed/drivers/net/mlx4/cmd.c
  projects/ofed/head/sys/ofed/drivers/net/mlx4/eq.c
  projects/ofed/head/sys/ofed/drivers/net/mlx4/main.c
  projects/ofed/head/sys/ofed/drivers/net/mlx4/reset.c
  projects/ofed/head/sys/ofed/include/linux/io.h
  projects/ofed/head/sys/ofed/include/linux/linux_compat.c

Modified: projects/ofed/head/sys/ofed/drivers/infiniband/hw/mlx4/main.c
==============================================================================
--- projects/ofed/head/sys/ofed/drivers/infiniband/hw/mlx4/main.c	Mon Dec 27 07:12:22 2010	(r216731)
+++ projects/ofed/head/sys/ofed/drivers/infiniband/hw/mlx4/main.c	Mon Dec 27 07:38:33 2010	(r216732)
@@ -1469,11 +1469,7 @@ err_counter:
 		mlx4_counter_free(ibdev->dev, ibdev->counters[k - 1]);
 
 err_map:
-#ifdef __linux__
 	iounmap(ibdev->uar_map);
-#else
-	pmap_unmapdev((vm_offset_t)ibdev->uar_map, PAGE_SIZE);
-#endif
 
 err_uar:
 	mlx4_uar_free(dev, &ibdev->priv_uar);
@@ -1507,11 +1503,7 @@ static void mlx4_ib_remove(struct mlx4_d
 		flush_workqueue(wq);
 		ibdev->iboe.nb.notifier_call = NULL;
 	}
-#ifdef __linux__
 	iounmap(ibdev->uar_map);
-#else
-	pmap_unmapdev((vm_offset_t)ibdev->uar_map, PAGE_SIZE);
-#endif
 
 	mlx4_foreach_port(p, dev, MLX4_PORT_TYPE_IB)
 		mlx4_CLOSE_PORT(dev, p);

Modified: projects/ofed/head/sys/ofed/drivers/infiniband/hw/mthca/mthca_av.c
==============================================================================
--- projects/ofed/head/sys/ofed/drivers/infiniband/hw/mthca/mthca_av.c	Mon Dec 27 07:12:22 2010	(r216731)
+++ projects/ofed/head/sys/ofed/drivers/infiniband/hw/mthca/mthca_av.c	Mon Dec 27 07:38:33 2010	(r216732)
@@ -370,11 +370,7 @@ void mthca_cleanup_av_table(struct mthca
 		return;
 
 	if (dev->av_table.av_map)
-#ifdef __linux__
 		iounmap(dev->av_table.av_map);
-#else
-		pmap_unmapdev((vm_offset_t)dev->av_table.av_map, MTHCA_AV_SIZE);
-#endif
 	pci_pool_destroy(dev->av_table.pool);
 	mthca_alloc_cleanup(&dev->av_table.alloc);
 }

Modified: projects/ofed/head/sys/ofed/drivers/infiniband/hw/mthca/mthca_catas.c
==============================================================================
--- projects/ofed/head/sys/ofed/drivers/infiniband/hw/mthca/mthca_catas.c	Mon Dec 27 07:12:22 2010	(r216731)
+++ projects/ofed/head/sys/ofed/drivers/infiniband/hw/mthca/mthca_catas.c	Mon Dec 27 07:38:33 2010	(r216732)
@@ -174,12 +174,7 @@ void mthca_stop_catas_poll(struct mthca_
 	del_timer_sync(&dev->catas_err.timer);
 
 	if (dev->catas_err.map)
-#ifdef __linux__
 		iounmap(dev->catas_err.map);
-#else
-		pmap_unmapdev((vm_offset_t)dev->catas_err.map,
-		    dev->catas_err.size * 4);
-#endif
 
 	spin_lock_irq(&catas_lock);
 	list_del(&dev->catas_err.list);

Modified: projects/ofed/head/sys/ofed/drivers/infiniband/hw/mthca/mthca_cmd.c
==============================================================================
--- projects/ofed/head/sys/ofed/drivers/infiniband/hw/mthca/mthca_cmd.c	Mon Dec 27 07:12:22 2010	(r216731)
+++ projects/ofed/head/sys/ofed/drivers/infiniband/hw/mthca/mthca_cmd.c	Mon Dec 27 07:38:33 2010	(r216732)
@@ -490,11 +490,7 @@ int mthca_cmd_init(struct mthca_dev *dev
 					MTHCA_MAILBOX_SIZE,
 					MTHCA_MAILBOX_SIZE, 0);
 	if (!dev->cmd.pool) {
-#ifdef __linux__
 		iounmap(dev->hcr);
-#else
-		pmap_unmapdev((vm_offset_t)dev->hcr, MTHCA_HCR_SIZE);
-#endif
 		return -ENOMEM;
 	}
 
@@ -504,18 +500,9 @@ int mthca_cmd_init(struct mthca_dev *dev
 void mthca_cmd_cleanup(struct mthca_dev *dev)
 {
 	pci_pool_destroy(dev->cmd.pool);
-#ifdef __linux__
 	iounmap(dev->hcr);
-#else
-	pmap_unmapdev((vm_offset_t)dev->hcr, MTHCA_HCR_SIZE);
-#endif
 	if (dev->cmd.flags & MTHCA_CMD_POST_DOORBELLS)
-#ifdef __linux__
 		iounmap(dev->cmd.dbell_map);
-#else
-		pmap_unmapdev((vm_offset_t)dev->cmd.dbell_map,
-		    dev->cmd.dbell_size);
-#endif
 }
 
 /*

Modified: projects/ofed/head/sys/ofed/drivers/infiniband/hw/mthca/mthca_eq.c
==============================================================================
--- projects/ofed/head/sys/ofed/drivers/infiniband/hw/mthca/mthca_eq.c	Mon Dec 27 07:12:22 2010	(r216731)
+++ projects/ofed/head/sys/ofed/drivers/infiniband/hw/mthca/mthca_eq.c	Mon Dec 27 07:38:33 2010	(r216732)
@@ -687,12 +687,7 @@ static int mthca_map_eq_regs(struct mthc
 					dev->fw.arbel.eq_arm_base) + 4, 4,
 				  &dev->eq_regs.arbel.eq_arm)) {
 			mthca_err(dev, "Couldn't map EQ arm register, aborting.\n");
-#ifdef __linux__
 			iounmap(dev->clr_base);
-#else
-			pmap_unmapdev((vm_offset_t)dev->clr_base,
-			    MTHCA_CLR_INT_SIZE);
-#endif
 			return -ENOMEM;
 		}
 
@@ -701,15 +696,8 @@ static int mthca_map_eq_regs(struct mthc
 				  MTHCA_EQ_SET_CI_SIZE,
 				  &dev->eq_regs.arbel.eq_set_ci_base)) {
 			mthca_err(dev, "Couldn't map EQ CI register, aborting.\n");
-#ifdef __linux__
 			iounmap(dev->eq_regs.arbel.eq_arm);
 			iounmap(dev->clr_base);
-#else
-			pmap_unmapdev((vm_offset_t)dev->eq_regs.arbel.eq_arm,
-			    4);
-			pmap_unmapdev((vm_offset_t)dev->clr_base,
-			    MTHCA_CLR_INT_SIZE);
-#endif
 			return -ENOMEM;
 		}
 	} else {
@@ -725,12 +713,7 @@ static int mthca_map_eq_regs(struct mthc
 				  &dev->eq_regs.tavor.ecr_base)) {
 			mthca_err(dev, "Couldn't map ecr register, "
 				  "aborting.\n");
-#ifdef __linux__
 			iounmap(dev->clr_base);
-#else
-			pmap_unmapdev((vm_offset_t)dev->clr_base,
-			    MTHCA_CLR_INT_SIZE);
-#endif
 			return -ENOMEM;
 		}
 	}
@@ -742,25 +725,12 @@ static int mthca_map_eq_regs(struct mthc
 static void mthca_unmap_eq_regs(struct mthca_dev *dev)
 {
 	if (mthca_is_memfree(dev)) {
-#ifdef __linux__
 		iounmap(dev->eq_regs.arbel.eq_set_ci_base);
 		iounmap(dev->eq_regs.arbel.eq_arm);
 		iounmap(dev->clr_base);
-#else
-		pmap_unmapdev((vm_offset_t)dev->eq_regs.arbel.eq_set_ci_base,
-		    MTHCA_EQ_SET_CI_SIZE);
-		pmap_unmapdev((vm_offset_t)dev->eq_regs.arbel.eq_arm, 4);
-		pmap_unmapdev((vm_offset_t)dev->clr_base, MTHCA_CLR_INT_SIZE);
-#endif
 	} else {
-#ifdef __linux__
 		iounmap(dev->eq_regs.tavor.ecr_base);
 		iounmap(dev->clr_base);
-#else
-		pmap_unmapdev((vm_offset_t)dev->eq_regs.tavor.ecr_base,
-		    MTHCA_ECR_SIZE + MTHCA_ECR_CLR_SIZE);
-		pmap_unmapdev((vm_offset_t)dev->clr_base, MTHCA_CLR_INT_SIZE);
-#endif
 	}
 }
 

Modified: projects/ofed/head/sys/ofed/drivers/infiniband/hw/mthca/mthca_main.c
==============================================================================
--- projects/ofed/head/sys/ofed/drivers/infiniband/hw/mthca/mthca_main.c	Mon Dec 27 07:12:22 2010	(r216731)
+++ projects/ofed/head/sys/ofed/drivers/infiniband/hw/mthca/mthca_main.c	Mon Dec 27 07:38:33 2010	(r216732)
@@ -916,11 +916,7 @@ err_pd_table_free:
 	mthca_cleanup_pd_table(dev);
 
 err_kar_unmap:
-#ifdef __linux__
 	iounmap(dev->kar);
-#else
-	pmap_unmapdev((vm_offset_t)dev->kar, PAGE_SIZE);
-#endif
 
 err_uar_free:
 	mthca_uar_free(dev, &dev->driver_uar);
@@ -1189,11 +1185,7 @@ static void __mthca_remove_one(struct pc
 		mthca_cleanup_mr_table(mdev);
 		mthca_cleanup_pd_table(mdev);
 
-#ifdef __linux__
 		iounmap(mdev->kar);
-#else
-		pmap_unmapdev((vm_offset_t)mdev->kar, PAGE_SIZE);
-#endif
 		mthca_uar_free(mdev, &mdev->driver_uar);
 		mthca_cleanup_uar_table(mdev);
 		mthca_close_hca(mdev);

Modified: projects/ofed/head/sys/ofed/drivers/infiniband/hw/mthca/mthca_mr.c
==============================================================================
--- projects/ofed/head/sys/ofed/drivers/infiniband/hw/mthca/mthca_mr.c	Mon Dec 27 07:12:22 2010	(r216731)
+++ projects/ofed/head/sys/ofed/drivers/infiniband/hw/mthca/mthca_mr.c	Mon Dec 27 07:38:33 2010	(r216732)
@@ -955,22 +955,11 @@ err_reserve_fmr:
 
 err_fmr_mtt_buddy:
 	if (dev->mr_table.tavor_fmr.mtt_base)
-#ifdef __linux__
 		iounmap(dev->mr_table.tavor_fmr.mtt_base);
-#else
-		pmap_unmapdev((vm_offset_t)dev->mr_table.tavor_fmr.mtt_base,
-		    dev->mr_table.tavor_fmr.mtt_size);
-		
-#endif
 
 err_fmr_mtt:
 	if (dev->mr_table.tavor_fmr.mpt_base)
-#ifdef __linux__
 		iounmap(dev->mr_table.tavor_fmr.mpt_base);
-#else
-		pmap_unmapdev((vm_offset_t)dev->mr_table.tavor_fmr.mpt_base,
-		    dev->mr_table.tavor_fmr.mpt_size);
-#endif
 
 err_fmr_mpt:
 	mthca_buddy_cleanup(&dev->mr_table.mtt_buddy);
@@ -990,19 +979,9 @@ void mthca_cleanup_mr_table(struct mthca
 	mthca_buddy_cleanup(&dev->mr_table.mtt_buddy);
 
 	if (dev->mr_table.tavor_fmr.mtt_base)
-#ifdef __linux__
 		iounmap(dev->mr_table.tavor_fmr.mtt_base);
-#else
-		pmap_unmapdev((vm_offset_t)dev->mr_table.tavor_fmr.mtt_base,
-		    dev->mr_table.tavor_fmr.mtt_size);
-#endif
 	if (dev->mr_table.tavor_fmr.mpt_base)
-#ifdef __linux__
 		iounmap(dev->mr_table.tavor_fmr.mpt_base);
-#else
-		pmap_unmapdev((vm_offset_t)dev->mr_table.tavor_fmr.mpt_base,
-		    dev->mr_table.tavor_fmr.mpt_size);
-#endif
 
 	mthca_alloc_cleanup(&dev->mr_table.mpt_alloc);
 }

Modified: projects/ofed/head/sys/ofed/drivers/infiniband/hw/mthca/mthca_reset.c
==============================================================================
--- projects/ofed/head/sys/ofed/drivers/infiniband/hw/mthca/mthca_reset.c	Mon Dec 27 07:12:22 2010	(r216731)
+++ projects/ofed/head/sys/ofed/drivers/infiniband/hw/mthca/mthca_reset.c	Mon Dec 27 07:38:33 2010	(r216732)
@@ -164,11 +164,7 @@ int mthca_reset(struct mthca_dev *mdev)
 		}
 
 		writel(MTHCA_RESET_VALUE, reset);
-#ifdef __linux__
 		iounmap(reset);
-#else
-		pmap_unmapdev((vm_offset_t)reset, 4);
-#endif
 	}
 
 	/* Docs say to wait one second before accessing device */

Modified: projects/ofed/head/sys/ofed/drivers/net/mlx4/catas.c
==============================================================================
--- projects/ofed/head/sys/ofed/drivers/net/mlx4/catas.c	Mon Dec 27 07:12:22 2010	(r216731)
+++ projects/ofed/head/sys/ofed/drivers/net/mlx4/catas.c	Mon Dec 27 07:38:33 2010	(r216732)
@@ -145,12 +145,7 @@ void mlx4_stop_catas_poll(struct mlx4_de
 	del_timer_sync(&priv->catas_err.timer);
 
 	if (priv->catas_err.map)
-#ifdef __linux__
 		iounmap(priv->catas_err.map);
-#else
-		pmap_unmapdev((vm_offset_t)priv->catas_err.map,
-		    priv->fw.catas_size * 4);
-#endif
 
 	spin_lock_irq(&catas_lock);
 	list_del(&priv->catas_err.list);

Modified: projects/ofed/head/sys/ofed/drivers/net/mlx4/cmd.c
==============================================================================
--- projects/ofed/head/sys/ofed/drivers/net/mlx4/cmd.c	Mon Dec 27 07:12:22 2010	(r216731)
+++ projects/ofed/head/sys/ofed/drivers/net/mlx4/cmd.c	Mon Dec 27 07:38:33 2010	(r216732)
@@ -348,11 +348,7 @@ int mlx4_cmd_init(struct mlx4_dev *dev)
 					 MLX4_MAILBOX_SIZE,
 					 MLX4_MAILBOX_SIZE, 0);
 	if (!priv->cmd.pool) {
-#ifdef __linux__
 		iounmap(priv->cmd.hcr);
-#else
-		pmap_unmapdev((vm_offset_t)priv->cmd.hcr, MLX4_HCR_SIZE);
-#endif
 		return -ENOMEM;
 	}
 
@@ -364,11 +360,7 @@ void mlx4_cmd_cleanup(struct mlx4_dev *d
 	struct mlx4_priv *priv = mlx4_priv(dev);
 
 	pci_pool_destroy(priv->cmd.pool);
-#ifdef __linux__
 	iounmap(priv->cmd.hcr);
-#else
-	pmap_unmapdev((vm_offset_t)priv->cmd.hcr, MLX4_HCR_SIZE);
-#endif
 }
 
 /*

Modified: projects/ofed/head/sys/ofed/drivers/net/mlx4/eq.c
==============================================================================
--- projects/ofed/head/sys/ofed/drivers/net/mlx4/eq.c	Mon Dec 27 07:12:22 2010	(r216731)
+++ projects/ofed/head/sys/ofed/drivers/net/mlx4/eq.c	Mon Dec 27 07:38:33 2010	(r216732)
@@ -523,11 +523,7 @@ static void mlx4_unmap_clr_int(struct ml
 {
 	struct mlx4_priv *priv = mlx4_priv(dev);
 
-#ifdef __linux__
 	iounmap(priv->clr_base);
-#else
-	pmap_unmapdev((vm_offset_t)priv->clr_base, MLX4_CLR_INT_SIZE);
-#endif
 }
 
 int mlx4_alloc_eq_table(struct mlx4_dev *dev)
@@ -679,12 +675,7 @@ void mlx4_cleanup_eq_table(struct mlx4_d
 
 	for (i = 0; i < mlx4_num_eq_uar(dev); ++i)
 		if (priv->eq_table.uar_map[i])
-#ifdef __linux__
 			iounmap(priv->eq_table.uar_map[i]);
-#else
-			pmap_unmapdev((vm_offset_t)priv->eq_table.uar_map[i],
-			    PAGE_SIZE);
-#endif
 
 	mlx4_bitmap_cleanup(&priv->eq_table.bitmap);
 

Modified: projects/ofed/head/sys/ofed/drivers/net/mlx4/main.c
==============================================================================
--- projects/ofed/head/sys/ofed/drivers/net/mlx4/main.c	Mon Dec 27 07:12:22 2010	(r216731)
+++ projects/ofed/head/sys/ofed/drivers/net/mlx4/main.c	Mon Dec 27 07:38:33 2010	(r216732)
@@ -1192,11 +1192,7 @@ err_pd_table_free:
 	mlx4_cleanup_pd_table(dev);
 
 err_kar_unmap:
-#ifdef __linux__
 	iounmap(priv->kar);
-#else
-	pmap_unmapdev((vm_offset_t)priv->kar, PAGE_SIZE);
-#endif
 
 err_uar_free:
 	mlx4_uar_free(dev, &priv->driver_uar);
@@ -1528,11 +1524,7 @@ static void mlx4_remove_one(struct pci_d
 		mlx4_cleanup_xrcd_table(dev);
 		mlx4_cleanup_pd_table(dev);
 
-#ifdef __linux__
 		iounmap(priv->kar);
-#else
-		pmap_unmapdev((vm_offset_t)priv->kar, PAGE_SIZE);
-#endif
 		mlx4_uar_free(dev, &priv->driver_uar);
 		mlx4_cleanup_uar_table(dev);
 		mlx4_free_eq_table(dev);

Modified: projects/ofed/head/sys/ofed/drivers/net/mlx4/reset.c
==============================================================================
--- projects/ofed/head/sys/ofed/drivers/net/mlx4/reset.c	Mon Dec 27 07:12:22 2010	(r216731)
+++ projects/ofed/head/sys/ofed/drivers/net/mlx4/reset.c	Mon Dec 27 07:38:33 2010	(r216732)
@@ -112,21 +112,13 @@ int mlx4_reset(struct mlx4_dev *dev)
 	if (sem) {
 		mlx4_err(dev, "Failed to obtain HW semaphore, aborting\n");
 		err = -EAGAIN;
-#ifdef __linux__
 		iounmap(reset);
-#else
-		pmap_unmapdev((vm_offset_t)reset, MLX4_RESET_SIZE);
-#endif
 		goto out;
 	}
 
 	/* actually hit reset */
 	writel(MLX4_RESET_VALUE, reset + MLX4_RESET_OFFSET);
-#ifdef __linux__
 	iounmap(reset);
-#else
-	pmap_unmapdev((vm_offset_t)reset, MLX4_RESET_SIZE);
-#endif
 
 	/* Docs say to wait one second before accessing device */
 	msleep(1000);

Modified: projects/ofed/head/sys/ofed/include/linux/io.h
==============================================================================
--- projects/ofed/head/sys/ofed/include/linux/io.h	Mon Dec 27 07:12:22 2010	(r216731)
+++ projects/ofed/head/sys/ofed/include/linux/io.h	Mon Dec 27 07:38:33 2010	(r216732)
@@ -29,10 +29,6 @@
 #ifndef	_LINUX_IO_H_
 #define	_LINUX_IO_H_
 
-#include <vm/vm.h>
-#include <vm/pmap.h>
-#include <machine/pmap.h>
-
 static inline uint32_t
 __raw_readl(const volatile void *addr)
 {
@@ -90,15 +86,11 @@ writew(uint16_t b, void *addr)
         *(volatile uint16_t *)addr = b;
 }
 
-#define	ioremap	pmap_mapdev
+void *ioremap(vm_paddr_t phys_addr, unsigned long size);
+void iounmap(void *addr);
 
 #define	memset_io(a, b, c)	memset((a), (b), (c))
 #define	memcpy_fromio(a, b, c)	memcpy((a), (b), (c))
 #define	memcpy_toio(a, b, c)	memcpy((a), (b), (c))
 
-/*
- * iounmap is not defined as pmap_unmapdev requires a length that can
- * not easily be determined on BSD.
- */
-
 #endif	/* _LINUX_IO_H_ */

Modified: projects/ofed/head/sys/ofed/include/linux/linux_compat.c
==============================================================================
--- projects/ofed/head/sys/ofed/include/linux/linux_compat.c	Mon Dec 27 07:12:22 2010	(r216731)
+++ projects/ofed/head/sys/ofed/include/linux/linux_compat.c	Mon Dec 27 07:38:33 2010	(r216732)
@@ -35,7 +35,11 @@
 #include <sys/mutex.h>
 #include <sys/bus.h>
 
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
 #include <machine/stdarg.h>
+#include <machine/pmap.h>
 
 #include <linux/kobject.h>
 #include <linux/device.h>
@@ -45,6 +49,7 @@
 #include <linux/file.h>
 #include <linux/sysfs.h>
 #include <linux/mm.h>
+#include <linux/io.h>
 
 #include <vm/vm_pager.h>
 
@@ -56,6 +61,12 @@ MALLOC_DEFINE(M_KMALLOC, "linux", "Linux
 #undef file
 #undef cdev
 #define	RB_ROOT(head)	(head)->rbh_root
+#undef LIST_HEAD
+/* From sys/queue.h */
+#define LIST_HEAD(name, type)						\
+struct name {								\
+	struct type *lh_first;	/* first element */			\
+}
 
 struct kobject class_root;
 struct device linux_rootdev;
@@ -510,10 +521,67 @@ struct fileops linuxfileops = {
 	.fo_close = linux_file_close
 };
 
+/*
+ * Hash of iomap addresses.  This is infrequently accessed and does not
+ * need to be particularly large.  This is done because we must store the
+ * caller's idea of the map size to properly unmap.
+ */
+struct iomap {
+	LIST_ENTRY(iomap)	im_next;
+	void 			*im_addr;
+	unsigned long		im_size;
+};
+
+LIST_HEAD(iomaphd, iomap);
+#define	IOMAP_HASH_SIZE	64
+#define	IOMAP_HASH_MASK	(IOMAP_HASH_SIZE - 1)
+#define	IO_HASH(addr)	((uintptr_t)(addr) >> PAGE_SHIFT) & IOMAP_HASH_MASK
+static struct iomaphd iomaphead[IOMAP_HASH_SIZE];
+static struct mtx iomaplock;
+
+void *
+ioremap(vm_paddr_t phys_addr, unsigned long size)
+{
+	struct iomap *iomap;
+	void *addr;
+
+	addr = pmap_mapdev(phys_addr, size);
+	if (addr == NULL)
+		return (NULL);
+	iomap = kmalloc(sizeof(*iomap), GFP_KERNEL);
+	mtx_lock(&iomaplock);
+	iomap->im_size = size;
+	iomap->im_addr = addr;
+	LIST_INSERT_HEAD(&iomaphead[IO_HASH(addr)], iomap, im_next);
+	mtx_unlock(&iomaplock);
+
+	return (addr);
+}
+
+void
+iounmap(void *addr)
+{
+	struct iomap *iomap;
+
+	mtx_lock(&iomaplock);
+	LIST_FOREACH(iomap, &iomaphead[IO_HASH(addr)], im_next)
+		if (iomap->im_addr == addr)
+			break;
+	if (iomap)
+		LIST_REMOVE(iomap, im_next);
+	mtx_unlock(&iomaplock);
+	if (iomap == NULL)
+		return;
+	pmap_unmapdev((vm_offset_t)addr, iomap->im_size);
+	kfree(iomap);
+}
+
+
 static void
 linux_compat_init(void)
 {
 	struct sysctl_oid *rootoid;
+	int i;
 
 	rootoid = SYSCTL_ADD_NODE(NULL, SYSCTL_STATIC_CHILDREN(),
 	    OID_AUTO, "sys", CTLFLAG_RD|CTLFLAG_MPSAFE, NULL, "sys");
@@ -532,6 +600,9 @@ linux_compat_init(void)
 	INIT_LIST_HEAD(&pci_drivers);
 	INIT_LIST_HEAD(&pci_devices);
 	spin_lock_init(&pci_lock);
+	mtx_init(&iomaplock, "IO Map lock", NULL, MTX_DEF);
+	for (i = 0; i < IOMAP_HASH_SIZE; i++)
+		LIST_INIT(&iomaphead[i]);
 }
 
 SYSINIT(linux_compat, SI_SUB_DRIVERS, SI_ORDER_SECOND, linux_compat_init, NULL);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201012270738.oBR7cXbL015192>