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

📄 xtalk.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* $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 Silicon Graphics, Inc. * Copyright (C) 2000 by Colin Ngam */#include <linux/types.h>#include <linux/config.h>#include <linux/slab.h>#include <asm/sn/sgi.h>#include <asm/sn/iobus.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;#include <asm/sn/agent.h>#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);void                    xtalk_intr_free(xtalk_intr_t);int                     xtalk_intr_connect(xtalk_intr_t, intr_func_t, intr_arg_t, xtalk_intr_setfunc_t, void *, 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_error_register(devfs_handle_t, error_handler_f *,					       error_handler_arg_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    cmn_err(CE_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_t

⌨️ 快捷键说明

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