📄 xtalk.c
字号:
/* * Shutdown a crosstalk provider */voidxtalk_provider_shutdown(devfs_handle_t xtalk_provider){ DEV_FUNC(xtalk_provider, provider_shutdown) (xtalk_provider);}/* * Enable a device on a xtalk widget */voidxtalk_widgetdev_enable(devfs_handle_t xconn_vhdl, int devnum){ DEV_FUNC(xconn_vhdl, widgetdev_enable) (xconn_vhdl, devnum);}/* * Shutdown a device on a xtalk widget */voidxtalk_widgetdev_shutdown(devfs_handle_t xconn_vhdl, int devnum){ DEV_FUNC(xconn_vhdl, widgetdev_shutdown) (xconn_vhdl, devnum);}intxtalk_dma_enabled(devfs_handle_t xconn_vhdl){ return DEV_FUNC(xconn_vhdl, dma_enabled) (xconn_vhdl);}/* * Generic crosstalk functions, for use with all crosstalk providers * and all crosstalk devices. *//****** Generic crosstalk interrupt interfaces ******/devfs_handle_txtalk_intr_dev_get(xtalk_intr_t xtalk_intr){ return (xtalk_intr->xi_dev);}xwidgetnum_txtalk_intr_target_get(xtalk_intr_t xtalk_intr){ return (xtalk_intr->xi_target);}xtalk_intr_vector_txtalk_intr_vector_get(xtalk_intr_t xtalk_intr){ return (xtalk_intr->xi_vector);}iopaddr_txtalk_intr_addr_get(struct xtalk_intr_s *xtalk_intr){ return (xtalk_intr->xi_addr);}void *xtalk_intr_sfarg_get(xtalk_intr_t xtalk_intr){ return (xtalk_intr->xi_sfarg);}/****** Generic crosstalk pio interfaces ******/devfs_handle_txtalk_pio_dev_get(xtalk_piomap_t xtalk_piomap){ return (xtalk_piomap->xp_dev);}xwidgetnum_txtalk_pio_target_get(xtalk_piomap_t xtalk_piomap){ return (xtalk_piomap->xp_target);}iopaddr_txtalk_pio_xtalk_addr_get(xtalk_piomap_t xtalk_piomap){ return (xtalk_piomap->xp_xtalk_addr);}ulongxtalk_pio_mapsz_get(xtalk_piomap_t xtalk_piomap){ return (xtalk_piomap->xp_mapsz);}caddr_txtalk_pio_kvaddr_get(xtalk_piomap_t xtalk_piomap){ return (xtalk_piomap->xp_kvaddr);}/****** Generic crosstalk dma interfaces ******/devfs_handle_txtalk_dma_dev_get(xtalk_dmamap_t xtalk_dmamap){ return (xtalk_dmamap->xd_dev);}xwidgetnum_txtalk_dma_target_get(xtalk_dmamap_t xtalk_dmamap){ return (xtalk_dmamap->xd_target);}/****** Generic crosstalk widget information interfaces ******//* xwidget_info_chk: * check to see if this vertex is a widget; * if so, return its widget_info (if any). * if not, return NULL. */xwidget_info_txwidget_info_chk(devfs_handle_t xwidget){ arbitrary_info_t ainfo = 0; hwgraph_info_get_LBL(xwidget, INFO_LBL_XWIDGET, &ainfo); return (xwidget_info_t) ainfo;}xwidget_info_txwidget_info_get(devfs_handle_t xwidget){ xwidget_info_t widget_info; widget_info = (xwidget_info_t) hwgraph_fastinfo_get(xwidget);#ifdef LATER if ((widget_info != NULL) && (widget_info->w_fingerprint != widget_info_fingerprint))#ifdef SUPPORT_PRINTING_V_FORMAT PRINT_PANIC("%v bad xwidget_info", xwidget);#else PRINT_PANIC("%x bad xwidget_info", xwidget);#endif#endif /* LATER */ return (widget_info);}voidxwidget_info_set(devfs_handle_t xwidget, xwidget_info_t widget_info){ if (widget_info != NULL) widget_info->w_fingerprint = widget_info_fingerprint; hwgraph_fastinfo_set(xwidget, (arbitrary_info_t) widget_info); /* Also, mark this vertex as an xwidget, * and use the widget_info, so xwidget_info_chk * can work (and be fairly efficient). */ hwgraph_info_add_LBL(xwidget, INFO_LBL_XWIDGET, (arbitrary_info_t) widget_info);}devfs_handle_txwidget_info_dev_get(xwidget_info_t xwidget_info){ if (xwidget_info == NULL) panic("null xwidget_info"); return (xwidget_info->w_vertex);}xwidgetnum_txwidget_info_id_get(xwidget_info_t xwidget_info){ if (xwidget_info == NULL) panic("null xwidget_info"); return (xwidget_info->w_id);}devfs_handle_txwidget_info_master_get(xwidget_info_t xwidget_info){ if (xwidget_info == NULL) panic("null xwidget_info"); return (xwidget_info->w_master);}xwidgetnum_txwidget_info_masterid_get(xwidget_info_t xwidget_info){ if (xwidget_info == NULL) panic("null xwidget_info"); return (xwidget_info->w_masterid);}xwidget_part_num_txwidget_info_part_num_get(xwidget_info_t xwidget_info){ if (xwidget_info == NULL) panic("null xwidget_info"); return (xwidget_info->w_hwid.part_num);}xwidget_mfg_num_txwidget_info_mfg_num_get(xwidget_info_t xwidget_info){ if (xwidget_info == NULL) panic("null xwidget_info"); return (xwidget_info->w_hwid.mfg_num);}/* Extract the widget name from the widget information * for the xtalk widget. */char *xwidget_info_name_get(xwidget_info_t xwidget_info){ if (xwidget_info == NULL) panic("null xwidget info"); return(xwidget_info->w_name);}/****** Generic crosstalk initialization interfaces ******//* * One-time initialization needed for systems that support crosstalk. */voidxtalk_init(void){ cdl_p cp;#if DEBUG && ATTACH_DEBUG printf("xtalk_init\n");#endif /* Allocate the registry. * We might already have one. * If we don't, go get one. * MPness: someone might have * set one up for us while we * were not looking; use an atomic * compare-and-swap to commit to * using the new registry if and * only if nobody else did first. * If someone did get there first, * toss the one we allocated back * into the pool. */ if (xtalk_registry == NULL) { cp = cdl_new(EDGE_LBL_XIO, "part", "mfgr"); if (!compare_and_swap_ptr((void **) &xtalk_registry, NULL, (void *) cp)) { cdl_del(cp); } } ASSERT(xtalk_registry != NULL);}/* * Associate a set of xtalk_provider functions with a vertex. */voidxtalk_provider_register(devfs_handle_t provider, xtalk_provider_t *xtalk_fns){ hwgraph_fastinfo_set(provider, (arbitrary_info_t) xtalk_fns);}/* * Disassociate a set of xtalk_provider functions with a vertex. */voidxtalk_provider_unregister(devfs_handle_t provider){ hwgraph_fastinfo_set(provider, (arbitrary_info_t)NULL);}/* * Obtain a pointer to the xtalk_provider functions for a specified Crosstalk * provider. */xtalk_provider_t *xtalk_provider_fns_get(devfs_handle_t provider){ return ((xtalk_provider_t *) hwgraph_fastinfo_get(provider));}/* * Announce a driver for a particular crosstalk part. * Returns 0 on success or -1 on failure. Failure occurs if the * specified hardware already has a driver. *//*ARGSUSED4 */intxwidget_driver_register(xwidget_part_num_t part_num, xwidget_mfg_num_t mfg_num, char *driver_prefix, unsigned flags){ /* a driver's init routine could call * xwidget_driver_register before the * system calls xtalk_init; so, we * make the call here. */ if (xtalk_registry == NULL) xtalk_init(); return cdl_add_driver(xtalk_registry, part_num, mfg_num, driver_prefix, flags, NULL);}/* * Inform xtalk infrastructure that a driver is no longer available for * handling any widgets. */voidxwidget_driver_unregister(char *driver_prefix){ /* before a driver calls unregister, * it must have called registger; so we * can assume we have a registry here. */ ASSERT(xtalk_registry != NULL); cdl_del_driver(xtalk_registry, driver_prefix, NULL);}/* * Call some function with each vertex that * might be one of this driver's attach points. */voidxtalk_iterate(char *driver_prefix, xtalk_iter_f *func){ ASSERT(xtalk_registry != NULL); cdl_iterate(xtalk_registry, driver_prefix, (cdl_iter_f *)func);}/* * xwidget_register: * Register a xtalk device (xwidget) by doing the following. * -allocate and initialize xwidget_info data * -allocate a hwgraph vertex with name based on widget number (id) * -look up the widget's initialization function and call it, * or remember the vertex for later initialization. * */intxwidget_register(xwidget_hwid_t hwid, /* widget's hardware ID */ devfs_handle_t widget, /* widget to initialize */ xwidgetnum_t id, /* widget's target id (0..f) */ devfs_handle_t master, /* widget's master vertex */ xwidgetnum_t targetid, /* master's target id (9/a) */ async_attach_t aa){ xwidget_info_t widget_info; char *s,devnm[MAXDEVNAME]; /* Allocate widget_info and associate it with widget vertex */ NEW(widget_info); /* Initialize widget_info */ widget_info->w_vertex = widget; widget_info->w_id = id; widget_info->w_master = master; widget_info->w_masterid = targetid; widget_info->w_hwid = *hwid; /* structure copy */ widget_info->w_efunc = 0; widget_info->w_einfo = 0; /* * get the name of this xwidget vertex and keep the info. * This is needed during errors and interupts, but as * long as we have it, we can use it elsewhere. */ s = dev_to_name(widget,devnm,MAXDEVNAME); widget_info->w_name = kmalloc(strlen(s) + 1, GFP_KERNEL); strcpy(widget_info->w_name,s); xwidget_info_set(widget, widget_info); device_master_set(widget, master); /* All the driver init routines (including * xtalk_init) are called before we get into * attaching devices, so we can assume we * have a registry here. */ ASSERT(xtalk_registry != NULL); /* * Add pointer to async attach info -- tear down will be done when * the particular descendant is done with the info. */ if (aa) async_attach_add_info(widget, aa); return cdl_add_connpt(xtalk_registry, hwid->part_num, hwid->mfg_num, widget, 0);}/* * xwidget_unregister : * Unregister the xtalk device and detach all its hwgraph namespace. */intxwidget_unregister(devfs_handle_t widget){ xwidget_info_t widget_info; xwidget_hwid_t hwid; /* Make sure that we have valid widget information initialized */ if (!(widget_info = xwidget_info_get(widget))) return(1); /* Remove the inventory information associated * with the widget. */ hwgraph_inventory_remove(widget, -1, -1, -1, -1, -1); hwid = &(widget_info->w_hwid); cdl_del_connpt(xtalk_registry, hwid->part_num, hwid->mfg_num, widget, 0); /* Clean out the xwidget information */ (void)kfree(widget_info->w_name); BZERO((void *)widget_info, sizeof(widget_info)); DEL(widget_info); return(0);}/* * Issue a link reset to a widget. */voidxwidget_reset(devfs_handle_t xwidget){ xswitch_reset_link(xwidget);}voidxwidget_gfx_reset(devfs_handle_t xwidget){ xwidget_info_t info; xswitch_reset_link(xwidget); info = xwidget_info_get(xwidget);#ifdef LATER ASSERT_ALWAYS(info != NULL);#endif /* * Enable this for other architectures once we add widget_reset to the * xtalk provider interface. */ DEV_FUNC(xtalk_provider, widget_reset) (xwidget_info_master_get(info), xwidget_info_id_get(info));}#define ANON_XWIDGET_NAME "No Name" /* Default Widget Name *//* Get the canonical hwgraph name of xtalk widget */char *xwidget_name_get(devfs_handle_t xwidget_vhdl){ xwidget_info_t info; /* If we have a bogus widget handle then return * a default anonymous widget name. */ if (xwidget_vhdl == GRAPH_VERTEX_NONE) return(ANON_XWIDGET_NAME); /* Read the widget name stored in the widget info * for the widget setup during widget initialization. */ info = xwidget_info_get(xwidget_vhdl); ASSERT(info != NULL); return(xwidget_info_name_get(info));}/* * xtalk_device_shutdown * Disable the specified xtalk widget and clean out all the software * state associated with it. */intxtalk_device_shutdown(devfs_handle_t xbus_vhdl, xwidgetnum_t widget){ devfs_handle_t widget_vhdl; char edge_name[8]; sprintf(edge_name, "%d", widget); if (hwgraph_traverse(xbus_vhdl, edge_name, &widget_vhdl) != GRAPH_SUCCESS) return(1); xwidget_unregister(widget_vhdl); return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -