From owner-svn-src-projects@FreeBSD.ORG Thu Jul 15 01:17:07 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 D4E741065676; Thu, 15 Jul 2010 01:17:07 +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 C32BE8FC1A; Thu, 15 Jul 2010 01:17:07 +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 o6F1H7X0036167; Thu, 15 Jul 2010 01:17:07 GMT (envelope-from jeff@svn.freebsd.org) Received: (from jeff@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o6F1H7UN036161; Thu, 15 Jul 2010 01:17:07 GMT (envelope-from jeff@svn.freebsd.org) Message-Id: <201007150117.o6F1H7UN036161@svn.freebsd.org> From: Jeff Roberson Date: Thu, 15 Jul 2010 01:17:07 +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: r210093 - projects/ofed/head/sys/ofed/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: Thu, 15 Jul 2010 01:17:07 -0000 Author: jeff Date: Thu Jul 15 01:17:07 2010 New Revision: 210093 URL: http://svn.freebsd.org/changeset/base/210093 Log: - Add device, devclass, dma, and cdev wrappers. Sponsored by: Isilon Systems, iX Systems, and Panasas. Added: projects/ofed/head/sys/ofed/include/linux/dmapool.h Modified: projects/ofed/head/sys/ofed/include/linux/cdev.h projects/ofed/head/sys/ofed/include/linux/device.h projects/ofed/head/sys/ofed/include/linux/dma-mapping.h projects/ofed/head/sys/ofed/include/linux/miscdevice.h Modified: projects/ofed/head/sys/ofed/include/linux/cdev.h ============================================================================== --- projects/ofed/head/sys/ofed/include/linux/cdev.h Thu Jul 15 01:15:31 2010 (r210092) +++ projects/ofed/head/sys/ofed/include/linux/cdev.h Thu Jul 15 01:17:07 2010 (r210093) @@ -33,44 +33,64 @@ #include #include -#define cdev linux_cdev - struct file_operations; struct inode; struct module; -struct cdev { +extern struct cdevsw linuxcdevsw; + +struct linux_cdev { struct kobject kobj; struct module *owner; + struct cdev *cdev; dev_t dev; const struct file_operations *ops; }; static inline void -cdev_init(struct cdev *cdev, const struct file_operations *ops) +cdev_init(struct linux_cdev *cdev, const struct file_operations *ops) { + + kobject_init(&cdev->kobj, NULL); + cdev->ops = ops; } -static inline struct cdev * +static inline struct linux_cdev * cdev_alloc(void) { - return (NULL); + struct linux_cdev *cdev; + + cdev = kzalloc(sizeof(struct linux_cdev), M_WAITOK); + if (cdev) + kobject_init(&cdev->kobj, NULL); + return (cdev); } static inline void -cdev_put(struct cdev *p) +cdev_put(struct linux_cdev *p) { + kobject_put(&p->kobj); } static inline int -cdev_add(struct cdev *cdev, dev_t dev, unsigned count) +cdev_add(struct linux_cdev *cdev, dev_t dev, unsigned count) { + if (count != 1) + panic("cdev_add: Unsupported count: %d", count); + cdev->cdev = make_dev(&linuxcdevsw, MINOR(dev), 0, 0, 0700, + kobject_name(&cdev->kobj)); return (0); } static inline void -cdev_del(struct cdev *cdev) +cdev_del(struct linux_cdev *cdev) { + if (cdev->cdev) + destroy_dev(cdev->cdev); + kobject_put(&cdev->kobj); + kfree(cdev); /* XXX ref cnt */ } +#define cdev linux_cdev + #endif /* _LINUX_CDEV_H_ */ Modified: projects/ofed/head/sys/ofed/include/linux/device.h ============================================================================== --- projects/ofed/head/sys/ofed/include/linux/device.h Thu Jul 15 01:15:31 2010 (r210092) +++ projects/ofed/head/sys/ofed/include/linux/device.h Thu Jul 15 01:17:07 2010 (r210093) @@ -28,6 +28,7 @@ #ifndef _LINUX_DEVICE_H_ #define _LINUX_DEVICE_H_ +#include #include #include #include @@ -35,22 +36,30 @@ #include #include #include +#include #include +#include + struct class { const char *name; struct module *owner; + devclass_t bsdclass; }; -struct device { - struct device *parent; +struct linux_device { + struct linux_device *parent; + device_t bsddev; dev_t devt; struct class *class; - void (*release)(struct device *dev); + void (*release)(struct linux_device *dev); struct kobject kobj; + uint64_t *dma_mask; void *driver_data; }; +#define device linux_device + struct class_attribute { struct attribute attr; ssize_t (*show)(struct class *, char *); @@ -65,28 +74,47 @@ struct device_attribute { ssize_t (*show)(struct device *, struct device_attribute *, char *); ssize_t (*store)(struct device *, - struct device_attribute *, char *, size_t); + struct device_attribute *, const char *, size_t); }; #define DEVICE_ATTR(_name, _mode, _show, _store) \ struct device_attribute dev_attr_##_name = \ { { #_name, NULL, _mode }, _show, _store } +#define dev_err(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) +#define dev_warn(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) +#define dev_info(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) +#define dev_printk(lvl, dev, fmt, ...) \ + device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) + static inline void * dev_get_drvdata(struct device *dev) { + return dev->driver_data; } static inline void dev_set_drvdata(struct device *dev, void *data) { + dev->driver_data = data; } +static inline struct device * +get_device(struct device *dev) +{ + + if (dev) + kobject_get(&dev->kobj); + + return (dev); +} + static inline char * dev_name(const struct device *dev) { + return kobject_name(&dev->kobj); } @@ -96,76 +124,133 @@ dev_name(const struct device *dev) static inline void put_device(struct device *dev) { + + if (dev) + kobject_put(&dev->kobj); } static inline int class_register(struct class *class) { + + class->bsdclass = devclass_create(class->name); return 0; } static inline void class_unregister(struct class *class) { + return; } -static inline void -device_unregister(struct device *dev) +/* + * Devices are registered and created for exporting to sysfs. create + * implies register and register assumes the device fields have been + * setup appropriately before being called. + */ +static inline int +device_register(struct device *dev) { -} + device_t bsddev; + int unit; -static inline struct device * -device_create(struct class *cls, struct device *parent, dev_t devt, - void *drvdata, const char *fmt, ...) -{ - return (NULL); + bsddev = NULL; + if (dev->devt) { + unit = MINOR(dev->devt); + bsddev = devclass_get_device(dev->class->bsdclass, unit); + } else + unit = -1; + if (bsddev == NULL) + bsddev = device_add_child(dev->parent->bsddev, + dev->kobj.name, unit); + if (bsddev) { + if (dev->devt == 0) + dev->devt = device_get_unit(bsddev); + device_set_softc(bsddev, dev); + } + dev->bsddev = bsddev; + kobject_init(&dev->kobj, NULL); + get_device(dev); + + return (0); } static inline void -device_destroy(struct class *class, dev_t dev) +device_unregister(struct device *dev) { -} + device_t bsddev; -static inline int -device_create_file(struct device *device, const struct device_attribute *entry) -{ - return (0); + bsddev = dev->bsddev; + if (bsddev) + device_delete_child(device_get_parent(bsddev), bsddev); + put_device(dev); } +struct device *device_create(struct class *class, struct device *parent, + dev_t devt, void *drvdata, const char *fmt, ...); + static inline void -device_remove_file(struct device *dev, const struct device_attribute *attr) +device_destroy(struct class *class, dev_t devt) { - return; + struct device *dev; + device_t bsddev; + int unit; + + unit = MINOR(devt); + bsddev = devclass_get_device(class->bsdclass, unit); + if (bsddev) { + dev = device_get_softc(bsddev); + device_unregister(dev); + put_device(dev); + } } static inline struct class * class_create(struct module *owner, const char *name) { - return (NULL); + struct class *class; + + class = kzalloc(sizeof(*class), M_WAITOK); + class->owner = owner; + class->name= name; + + return (class); } static inline void class_destroy(struct class *class) { + /* XXX Missing ref count. */ + kfree(class); } +/* + * These are supposed to create the sysfs entry for the attribute. Should + * instead create a sysctl tree. XXX + */ static inline int -class_create_file(struct class *class, const struct class_attribute *attr) +device_create_file(struct device *device, const struct device_attribute *entry) { return (0); } static inline void -class_remove_file(struct class *class, const struct class_attribute *attr) +device_remove_file(struct device *dev, const struct device_attribute *attr) { return; } static inline int -device_register(struct device *dev) +class_create_file(struct class *class, const struct class_attribute *attr) { return (0); } +static inline void +class_remove_file(struct class *class, const struct class_attribute *attr) +{ + return; +} + #endif /* _LINUX_DEVICE_H_ */ Modified: projects/ofed/head/sys/ofed/include/linux/dma-mapping.h ============================================================================== --- projects/ofed/head/sys/ofed/include/linux/dma-mapping.h Thu Jul 15 01:15:31 2010 (r210092) +++ projects/ofed/head/sys/ofed/include/linux/dma-mapping.h Thu Jul 15 01:17:07 2010 (r210093) @@ -28,16 +28,23 @@ #ifndef _LINUX_DMA_MAPPING_H_ #define _LINUX_DMA_MAPPING_H_ -#include -#include -#include - +#include #include #include #include #include #include +#include +#include + +#include +#include +#include + +#include +#include + enum dma_data_direction { DMA_BIDIRECTIONAL = 0, DMA_TO_DEVICE = 1, @@ -78,42 +85,80 @@ struct dma_map_ops { int is_phys; }; +#define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL << (n)) - 1)) + static inline int dma_supported(struct device *dev, u64 mask) { - KASSERT(0, ("%s", __FUNCTION__)); + + /* XXX busdma takes care of this elsewhere. */ + return (1); } static inline int dma_set_mask(struct device *dev, u64 dma_mask) { - KASSERT(0, ("%s", __FUNCTION__)); + + if (!dev->dma_mask || !dma_supported(dev, dma_mask)) + return -EIO; + + *dev->dma_mask = dma_mask; } +MALLOC_DECLARE(M_LINUX_DMA); + static inline void * dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag) { - KASSERT(0, ("%s", __FUNCTION__)); + vm_paddr_t high; + void *mem; + + if (dev->dma_mask) + high = *dev->dma_mask; + else + high = BUS_SPACE_MAXADDR_32BIT; + + mem = contigmalloc(size, M_LINUX_DMA, flag, 0, high, 1, 0); + if (mem) + *dma_handle = vtophys(mem); + else + *dma_handle = 0; + return (mem); } static inline void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t dma_handle) { - KASSERT(0, ("%s", __FUNCTION__)); + contigfree(cpu_addr, size, M_LINUX_DMA); } - + +/* XXX This only works with no iommu. */ static inline dma_addr_t -dma_map_single(struct device *dev, void *cpu_addr, size_t size, - enum dma_data_direction direction) +dma_map_single_attrs(struct device *dev, void *ptr, size_t size, + enum dma_data_direction dir, struct dma_attrs *attrs) +{ + + return vtophys(ptr); +} + +static inline void +dma_unmap_single_attrs(struct device *dev, dma_addr_t addr, size_t size, + enum dma_data_direction dir, struct dma_attrs *attrs) +{ +} + +static inline int +dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, int nents, + enum dma_data_direction dir, struct dma_attrs *attrs) { KASSERT(0, ("%s", __FUNCTION__)); } - + static inline void -dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, - enum dma_data_direction direction) +dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg, int nents, + enum dma_data_direction dir, struct dma_attrs *attrs) { KASSERT(0, ("%s", __FUNCTION__)); } @@ -122,88 +167,53 @@ static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long offset, size_t size, enum dma_data_direction direction) { - KASSERT(0, ("%s", __FUNCTION__)); -; + + return VM_PAGE_TO_PHYS(page) + offset; } static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size, enum dma_data_direction direction) { - KASSERT(0, ("%s", __FUNCTION__)); -} - -static inline int -dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, - enum dma_data_direction direction) -{ - KASSERT(0, ("%s", __FUNCTION__)); } +/* XXX This is x86 specific, no syncs required. */ static inline void -dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, +dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) -{ - KASSERT(0, ("%s", __FUNCTION__)); +{ } static inline void -dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, - enum dma_data_direction direction) +dma_sync_single(struct device *dev, dma_addr_t addr, size_t size, + enum dma_data_direction dir) { - KASSERT(0, ("%s", __FUNCTION__)); + dma_sync_single_for_cpu(dev, addr, size, dir); } static inline void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) { - KASSERT(0, ("%s", __FUNCTION__)); } static inline void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction) { - KASSERT(0, ("%s", __FUNCTION__)); } static inline void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction) { - KASSERT(0, ("%s", __FUNCTION__)); } static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { - KASSERT(0, ("%s", __FUNCTION__)); -} - -static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr, - size_t size, enum dma_data_direction dir, struct dma_attrs *attrs) -{ - KASSERT(0, ("%s", __FUNCTION__)); -} - -static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t addr, - size_t size, enum dma_data_direction dir, struct dma_attrs *attrs) -{ - KASSERT(0, ("%s", __FUNCTION__)); -} - -static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, - int nents, enum dma_data_direction dir, struct dma_attrs *attrs) -{ - KASSERT(0, ("%s", __FUNCTION__)); -} -static inline void dma_unmap_sg_attrs(struct device *dev, - struct scatterlist *sg, int nents, enum dma_data_direction dir, - struct dma_attrs *attrs) -{ - KASSERT(0, ("%s", __FUNCTION__)); + return (0); } #define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, NULL) @@ -211,4 +221,7 @@ static inline void dma_unmap_sg_attrs(st #define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, NULL) #define dma_unmap_sg(d, s, n, r) dma_unmap_sg_attrs(d, s, n, r, NULL) +extern int uma_align_cache; +#define dma_get_cache_alignment() uma_align_cache + #endif /* _LINUX_DMA_MAPPING_H_ */ Added: projects/ofed/head/sys/ofed/include/linux/dmapool.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/ofed/head/sys/ofed/include/linux/dmapool.h Thu Jul 15 01:17:07 2010 (r210093) @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 2010 Isilon Systems, Inc. + * Copyright (c) 2010 iX Systems, Inc. + * Copyright (c) 2010 Panasas, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LINUX_DMAPOOL_H_ +#define _LINUX_DMAPOOL_H_ + +#include +#include +#include + +struct dma_pool *dma_pool_create(const char *name, struct linux_device *dev, + size_t size, size_t align, size_t allocation); +void dma_pool_destroy(struct dma_pool *pool); +void *dma_pool_alloc(struct dma_pool *pool, gfp_t mem_flags, + dma_addr_t *handle); +void dma_pool_free(struct dma_pool *pool, void *vaddr, dma_addr_t addr); + +#endif /* _LINUX_DMAPOOL_H_ */ Modified: projects/ofed/head/sys/ofed/include/linux/miscdevice.h ============================================================================== --- projects/ofed/head/sys/ofed/include/linux/miscdevice.h Thu Jul 15 01:15:31 2010 (r210092) +++ projects/ofed/head/sys/ofed/include/linux/miscdevice.h Thu Jul 15 01:17:07 2010 (r210093) @@ -29,7 +29,9 @@ #ifndef _LINUX_MISCDEVICE_H_ #define _LINUX_MISCDEVICE_H_ -#define MISC_DYNAMIC_MINOR 255 +#define MISC_DYNAMIC_MINOR -1 + +#include struct miscdevice { const char *name; @@ -38,15 +40,24 @@ struct miscdevice { int minor; }; +extern struct class miscclass; +extern struct device miscroot; + +/* + * XXX Missing cdev. + */ static inline int misc_register(struct miscdevice *misc) { + misc->this_device = device_create(&miscclass, &miscroot, 0, misc, + misc->name); return (0); } static inline int misc_deregister(struct miscdevice *misc) { + device_destroy(&miscclass, misc->this_device->devt); return (0); }