⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xtalk.c

📁 microwindows移植到S3C44B0的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Id$ * * This file is subject to the terms and conditions of the GNU General Public * License.  See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved. */#include <linux/types.h>#include <linux/slab.h>#include <asm/sn/sgi.h>#include <asm/sn/driver.h>#include <asm/sn/io.h>#include <asm/sn/iograph.h>#include <asm/sn/invent.h>#include <asm/sn/hcl.h>#include <asm/sn/labelcl.h>#include <asm/sn/hcl_util.h>#include <asm/sn/xtalk/xtalk.h>#include <asm/sn/xtalk/xswitch.h>#include <asm/sn/xtalk/xwidget.h>#include <asm/sn/xtalk/xtalk_private.h>/* * Implement crosstalk provider operations.  The xtalk* layer provides a * platform-independent interface for crosstalk devices.  This layer * switches among the possible implementations of a crosstalk adapter. * * On platforms with only one possible xtalk provider, macros can be * set up at the top that cause the table lookups and indirections to * completely disappear. */#define	NEW(ptr)	(ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))#define	DEL(ptr)	(kfree(ptr))char                    widget_info_fingerprint[] = "widget_info";cdl_p                   xtalk_registry = NULL;#define	DEV_FUNC(dev,func)	hub_##func#define	CAST_PIOMAP(x)		((hub_piomap_t)(x))#define	CAST_DMAMAP(x)		((hub_dmamap_t)(x))#define	CAST_INTR(x)		((hub_intr_t)(x))/* ===================================================================== *            Function Table of Contents */xtalk_piomap_t          xtalk_piomap_alloc(devfs_handle_t, device_desc_t, iopaddr_t, size_t, size_t, unsigned);void                    xtalk_piomap_free(xtalk_piomap_t);caddr_t                 xtalk_piomap_addr(xtalk_piomap_t, iopaddr_t, size_t);void                    xtalk_piomap_done(xtalk_piomap_t);caddr_t                 xtalk_piotrans_addr(devfs_handle_t, device_desc_t, iopaddr_t, size_t, unsigned);caddr_t                 xtalk_pio_addr(devfs_handle_t, device_desc_t, iopaddr_t, size_t, xtalk_piomap_t *, unsigned);void                    xtalk_set_early_piotrans_addr(xtalk_early_piotrans_addr_f *);caddr_t                 xtalk_early_piotrans_addr(xwidget_part_num_t, xwidget_mfg_num_t, int, iopaddr_t, size_t, unsigned);static caddr_t          null_xtalk_early_piotrans_addr(xwidget_part_num_t, xwidget_mfg_num_t, int, iopaddr_t, size_t, unsigned);xtalk_dmamap_t          xtalk_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned);void                    xtalk_dmamap_free(xtalk_dmamap_t);iopaddr_t               xtalk_dmamap_addr(xtalk_dmamap_t, paddr_t, size_t);alenlist_t              xtalk_dmamap_list(xtalk_dmamap_t, alenlist_t, unsigned);void                    xtalk_dmamap_done(xtalk_dmamap_t);iopaddr_t               xtalk_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned);alenlist_t              xtalk_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned);void			xtalk_dmamap_drain(xtalk_dmamap_t);void			xtalk_dmaaddr_drain(devfs_handle_t, iopaddr_t, size_t);void			xtalk_dmalist_drain(devfs_handle_t, alenlist_t);xtalk_intr_t            xtalk_intr_alloc(devfs_handle_t, device_desc_t, devfs_handle_t);xtalk_intr_t            xtalk_intr_alloc_nothd(devfs_handle_t, device_desc_t, devfs_handle_t);void                    xtalk_intr_free(xtalk_intr_t);int                     xtalk_intr_connect(xtalk_intr_t, xtalk_intr_setfunc_t, void *);void                    xtalk_intr_disconnect(xtalk_intr_t);devfs_handle_t            xtalk_intr_cpu_get(xtalk_intr_t);int                     xtalk_error_handler(devfs_handle_t, int, ioerror_mode_t, ioerror_t *);int                     xtalk_error_devenable(devfs_handle_t, int, int);void                    xtalk_provider_startup(devfs_handle_t);void                    xtalk_provider_shutdown(devfs_handle_t);devfs_handle_t            xtalk_intr_dev_get(xtalk_intr_t);xwidgetnum_t            xtalk_intr_target_get(xtalk_intr_t);xtalk_intr_vector_t     xtalk_intr_vector_get(xtalk_intr_t);iopaddr_t               xtalk_intr_addr_get(struct xtalk_intr_s *);void                   *xtalk_intr_sfarg_get(xtalk_intr_t);devfs_handle_t            xtalk_pio_dev_get(xtalk_piomap_t);xwidgetnum_t            xtalk_pio_target_get(xtalk_piomap_t);iopaddr_t               xtalk_pio_xtalk_addr_get(xtalk_piomap_t);ulong                   xtalk_pio_mapsz_get(xtalk_piomap_t);caddr_t                 xtalk_pio_kvaddr_get(xtalk_piomap_t);devfs_handle_t            xtalk_dma_dev_get(xtalk_dmamap_t);xwidgetnum_t            xtalk_dma_target_get(xtalk_dmamap_t);xwidget_info_t          xwidget_info_chk(devfs_handle_t);xwidget_info_t          xwidget_info_get(devfs_handle_t);void                    xwidget_info_set(devfs_handle_t, xwidget_info_t);devfs_handle_t            xwidget_info_dev_get(xwidget_info_t);xwidgetnum_t            xwidget_info_id_get(xwidget_info_t);devfs_handle_t            xwidget_info_master_get(xwidget_info_t);xwidgetnum_t            xwidget_info_masterid_get(xwidget_info_t);xwidget_part_num_t      xwidget_info_part_num_get(xwidget_info_t);xwidget_mfg_num_t       xwidget_info_mfg_num_get(xwidget_info_t);char 			*xwidget_info_name_get(xwidget_info_t);void                    xtalk_init(void);void                    xtalk_provider_register(devfs_handle_t, xtalk_provider_t *);void                    xtalk_provider_unregister(devfs_handle_t);xtalk_provider_t       *xtalk_provider_fns_get(devfs_handle_t);int                     xwidget_driver_register(xwidget_part_num_t, 						xwidget_mfg_num_t, 						char *, unsigned);void                    xwidget_driver_unregister(char *);int                     xwidget_register(xwidget_hwid_t, devfs_handle_t, 					 xwidgetnum_t, devfs_handle_t, 					 xwidgetnum_t, async_attach_t);int			xwidget_unregister(devfs_handle_t);void                    xwidget_reset(devfs_handle_t);char			*xwidget_name_get(devfs_handle_t);#if !defined(DEV_FUNC)/* * There is more than one possible provider * for this platform. We need to examine the * master vertex of the current vertex for * a provider function structure, and indirect * through the appropriately named member. */#define	DEV_FUNC(dev,func)	xwidget_to_provider_fns(dev)->func#define	CAST_PIOMAP(x)		((xtalk_piomap_t)(x))#define	CAST_DMAMAP(x)		((xtalk_dmamap_t)(x))#define	CAST_INTR(x)		((xtalk_intr_t)(x))static xtalk_provider_t *xwidget_to_provider_fns(devfs_handle_t xconn){    xwidget_info_t          widget_info;    xtalk_provider_t       *provider_fns;    widget_info = xwidget_info_get(xconn);    ASSERT(widget_info != NULL);    provider_fns = xwidget_info_pops_get(widget_info);    ASSERT(provider_fns != NULL);    return (provider_fns);}#endif/* * Many functions are not passed their vertex * information directly; rather, they must * dive through a resource map. These macros * are available to coordinate this detail. */#define	PIOMAP_FUNC(map,func)	DEV_FUNC(map->xp_dev,func)#define	DMAMAP_FUNC(map,func)	DEV_FUNC(map->xd_dev,func)#define	INTR_FUNC(intr,func)	DEV_FUNC(intr_hdl->xi_dev,func)/* ===================================================================== *                    PIO MANAGEMENT * *      For mapping system virtual address space to *      xtalk space on a specified widget */xtalk_piomap_txtalk_piomap_alloc(devfs_handle_t dev,	/* set up mapping for this device */		   device_desc_t dev_desc,	/* device descriptor */		   iopaddr_t xtalk_addr,	/* map for this xtalk_addr range */		   size_t byte_count,		   size_t byte_count_max,	/* maximum size of a mapping */		   unsigned flags){				/* defined in sys/pio.h */    return (xtalk_piomap_t) DEV_FUNC(dev, piomap_alloc)	(dev, dev_desc, xtalk_addr, byte_count, byte_count_max, flags);}voidxtalk_piomap_free(xtalk_piomap_t xtalk_piomap){    PIOMAP_FUNC(xtalk_piomap, piomap_free)	(CAST_PIOMAP(xtalk_piomap));}caddr_txtalk_piomap_addr(xtalk_piomap_t xtalk_piomap,	/* mapping resources */		  iopaddr_t xtalk_addr,		/* map for this xtalk address */		  size_t byte_count){				/* map this many bytes */    return PIOMAP_FUNC(xtalk_piomap, piomap_addr)	(CAST_PIOMAP(xtalk_piomap), xtalk_addr, byte_count);}voidxtalk_piomap_done(xtalk_piomap_t xtalk_piomap){    PIOMAP_FUNC(xtalk_piomap, piomap_done)	(CAST_PIOMAP(xtalk_piomap));}caddr_txtalk_piotrans_addr(devfs_handle_t dev,	/* translate for this device */		    device_desc_t dev_desc,	/* device descriptor */		    iopaddr_t xtalk_addr,	/* Crosstalk address */		    size_t byte_count,	/* map this many bytes */		    unsigned flags){				/* (currently unused) */    return DEV_FUNC(dev, piotrans_addr)	(dev, dev_desc, xtalk_addr, byte_count, flags);}caddr_txtalk_pio_addr(devfs_handle_t dev,	/* translate for this device */	       device_desc_t dev_desc,	/* device descriptor */	       iopaddr_t addr,		/* starting address (or offset in window) */	       size_t byte_count,	/* map this many bytes */	       xtalk_piomap_t *mapp,	/* where to return the map pointer */	       unsigned flags){					/* PIO flags */    xtalk_piomap_t          map = 0;    caddr_t                 res;    if (mapp)	*mapp = 0;			/* record "no map used" */    res = xtalk_piotrans_addr	(dev, dev_desc, addr, byte_count, flags);    if (res)	return res;			/* xtalk_piotrans worked */    map = xtalk_piomap_alloc	(dev, dev_desc, addr, byte_count, byte_count, flags);    if (!map)	return res;			/* xtalk_piomap_alloc failed */    res = xtalk_piomap_addr	(map, addr, byte_count);    if (!res) {	xtalk_piomap_free(map);	return res;			/* xtalk_piomap_addr failed */    }    if (mapp)	*mapp = map;			/* pass back map used */    return res;				/* xtalk_piomap_addr succeeded */}/* ===================================================================== *            EARLY PIOTRANS SUPPORT * *      There are places where drivers (mgras, for instance) *      need to get PIO translations before the infrastructure *      is extended to them (setting up textports, for *      instance). These drivers should call *      xtalk_early_piotrans_addr with their xtalk ID *      information, a sequence number (so we can use the second *      mgras for instance), and the usual piotrans parameters. * *      Machine specific code should provide an implementation *      of early_piotrans_addr, and present a pointer to this *      function to xtalk_set_early_piotrans_addr so it can be *      used by clients without the clients having to know what *      platform or what xtalk provider is in use. */static xtalk_early_piotrans_addr_f null_xtalk_early_piotrans_addr;xtalk_early_piotrans_addr_f *impl_early_piotrans_addr = null_xtalk_early_piotrans_addr;/* xtalk_set_early_piotrans_addr: * specify the early_piotrans_addr implementation function. */voidxtalk_set_early_piotrans_addr(xtalk_early_piotrans_addr_f *impl){    impl_early_piotrans_addr = impl;}/* xtalk_early_piotrans_addr: * figure out a PIO address for the "nth" crosstalk widget that * matches the specified part and mfgr number. Returns NULL if * there is no such widget, or if the requested mapping can not * be constructed. * Limitations on which crosstalk slots (and busses) are * checked, and definitions of the ordering of the search across * the crosstalk slots, are defined by the platform. */caddr_txtalk_early_piotrans_addr(xwidget_part_num_t part_num,			  xwidget_mfg_num_t mfg_num,			  int which,			  iopaddr_t xtalk_addr,			  size_t byte_count,			  unsigned flags){    return impl_early_piotrans_addr	(part_num, mfg_num, which, xtalk_addr, byte_count, flags);}/* null_xtalk_early_piotrans_addr: * used as the early_piotrans_addr implementation until and * unless a real implementation is provided. In DEBUG kernels, * we want to know who is calling before the implementation is * registered; in non-DEBUG kernels, return NULL representing * lack of mapping support. *//*ARGSUSED */static caddr_tnull_xtalk_early_piotrans_addr(xwidget_part_num_t part_num,			       xwidget_mfg_num_t mfg_num,			       int which,			       iopaddr_t xtalk_addr,			       size_t byte_count,			       unsigned flags){#if DEBUG    PRINT_PANIC("null_xtalk_early_piotrans_addr");#endif    return NULL;}/* ===================================================================== *                    DMA MANAGEMENT * *      For mapping from crosstalk space to system *      physical space. */xtalk_dmamap_txtalk_dmamap_alloc(devfs_handle_t dev,	/* set up mappings for this device */		   device_desc_t dev_desc,	/* device descriptor */		   size_t byte_count_max,	/* max size of a mapping */		   unsigned flags){				/* defined in dma.h */    return (xtalk_dmamap_t) DEV_FUNC(dev, dmamap_alloc)	(dev, dev_desc, byte_count_max, flags);}voidxtalk_dmamap_free(xtalk_dmamap_t xtalk_dmamap){    DMAMAP_FUNC(xtalk_dmamap, dmamap_free)	(CAST_DMAMAP(xtalk_dmamap));}iopaddr_txtalk_dmamap_addr(xtalk_dmamap_t xtalk_dmamap,	/* use these mapping resources */		  paddr_t paddr,	/* map for this address */		  size_t byte_count){				/* map this many bytes */    return DMAMAP_FUNC(xtalk_dmamap, dmamap_addr)	(CAST_DMAMAP(xtalk_dmamap), paddr, byte_count);}alenlist_txtalk_dmamap_list(xtalk_dmamap_t xtalk_dmamap,	/* use these mapping resources */		  alenlist_t alenlist,	/* map this Address/Length List */		  unsigned flags){    return DMAMAP_FUNC(xtalk_dmamap, dmamap_list)	(CAST_DMAMAP(xtalk_dmamap), alenlist, flags);}voidxtalk_dmamap_done(xtalk_dmamap_t xtalk_dmamap){    DMAMAP_FUNC(xtalk_dmamap, dmamap_done)	(CAST_DMAMAP(xtalk_dmamap));}iopaddr_txtalk_dmatrans_addr(devfs_handle_t dev,	/* translate for this device */		    device_desc_t dev_desc,	/* device descriptor */		    paddr_t paddr,	/* system physical address */		    size_t byte_count,	/* length */		    unsigned flags){				/* defined in dma.h */    return DEV_FUNC(dev, dmatrans_addr)	(dev, dev_desc, paddr, byte_count, flags);}alenlist_txtalk_dmatrans_list(devfs_handle_t dev,	/* translate for this device */		    device_desc_t dev_desc,	/* device descriptor */		    alenlist_t palenlist,	/* system address/length list */		    unsigned flags){				/* defined in dma.h */    return DEV_FUNC(dev, dmatrans_list)	(dev, dev_desc, palenlist, flags);}voidxtalk_dmamap_drain(xtalk_dmamap_t map){    DMAMAP_FUNC(map, dmamap_drain)	(CAST_DMAMAP(map));}voidxtalk_dmaaddr_drain(devfs_handle_t dev, paddr_t addr, size_t size){    DEV_FUNC(dev, dmaaddr_drain)	(dev, addr, size);}voidxtalk_dmalist_drain(devfs_handle_t dev, alenlist_t list){    DEV_FUNC(dev, dmalist_drain)	(dev, list);}/* ===================================================================== *                    INTERRUPT MANAGEMENT * *      Allow crosstalk devices to establish interrupts *//* * Allocate resources required for an interrupt as specified in intr_desc. * Return resource handle in intr_hdl. */xtalk_intr_txtalk_intr_alloc(devfs_handle_t dev,	/* which Crosstalk device */		 device_desc_t dev_desc,	/* device descriptor */		 devfs_handle_t owner_dev){				/* owner of this interrupt */    return (xtalk_intr_t) DEV_FUNC(dev, intr_alloc)	(dev, dev_desc, owner_dev);}/* * Allocate resources required for an interrupt as specified in dev_desc. * Unconditionally setup resources to be non-threaded. * Return resource handle in intr_hdl. */xtalk_intr_txtalk_intr_alloc_nothd(devfs_handle_t dev,	/* which Crosstalk device */		 	device_desc_t dev_desc,	/* device descriptor */		 	devfs_handle_t owner_dev)	/* owner of this interrupt */{    return (xtalk_intr_t) DEV_FUNC(dev, intr_alloc_nothd)	(dev, dev_desc, owner_dev);}/* * Free resources consumed by intr_alloc. */voidxtalk_intr_free(xtalk_intr_t intr_hdl){    INTR_FUNC(intr_hdl, intr_free)	(CAST_INTR(intr_hdl));}/* * Associate resources allocated with a previous xtalk_intr_alloc call with the * described handler, arg, name, etc. * * Returns 0 on success, returns <0 on failure. */intxtalk_intr_connect(xtalk_intr_t intr_hdl,	/* xtalk intr resource handle */		   xtalk_intr_setfunc_t setfunc,	/* func to set intr hw */		   void *setfunc_arg)	/* arg to setfunc */{    return INTR_FUNC(intr_hdl, intr_connect)	(CAST_INTR(intr_hdl), setfunc, setfunc_arg);}/* * Disassociate handler with the specified interrupt. */voidxtalk_intr_disconnect(xtalk_intr_t intr_hdl){    INTR_FUNC(intr_hdl, intr_disconnect)	(CAST_INTR(intr_hdl));}/* * Return a hwgraph vertex that represents the CPU currently * targeted by an interrupt. */devfs_handle_txtalk_intr_cpu_get(xtalk_intr_t intr_hdl){    return INTR_FUNC(intr_hdl, intr_cpu_get)	(CAST_INTR(intr_hdl));}/* ===================================================================== *                    CONFIGURATION MANAGEMENT *//* * Startup a crosstalk provider */voidxtalk_provider_startup(devfs_handle_t xtalk_provider){    DEV_FUNC(xtalk_provider, provider_startup)	(xtalk_provider);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -