From owner-svn-src-projects@FreeBSD.ORG Mon Dec 27 07:38:34 2010 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 07185106564A; Mon, 27 Dec 2010 07:38:34 +0000 (UTC) (envelope-from jeff@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id E7E4A8FC12; Mon, 27 Dec 2010 07:38:33 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id oBR7cXoH015208; Mon, 27 Dec 2010 07:38:33 GMT (envelope-from jeff@svn.freebsd.org) Received: (from jeff@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id oBR7cXbL015192; Mon, 27 Dec 2010 07:38:33 GMT (envelope-from jeff@svn.freebsd.org) Message-Id: <201012270738.oBR7cXbL015192@svn.freebsd.org> From: Jeff Roberson Date: Mon, 27 Dec 2010 07:38:33 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r216732 - in projects/ofed/head/sys/ofed: drivers/infiniband/hw/mlx4 drivers/infiniband/hw/mthca drivers/net/mlx4 include/linux X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 27 Dec 2010 07:38:34 -0000 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 -#include -#include - 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 #include +#include +#include + #include +#include #include #include @@ -45,6 +49,7 @@ #include #include #include +#include #include @@ -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);