📄 xtalk.c
字号:
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 interrupts, 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);}voidxwidget_error_register(devfs_handle_t xwidget, error_handler_f *efunc, error_handler_arg_t einfo){ xwidget_info_t xwidget_info; xwidget_info = xwidget_info_get(xwidget); ASSERT(xwidget_info != NULL); xwidget_info->w_efunc = efunc; xwidget_info->w_einfo = einfo;}/* * 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);}/* * xtalk_device_inquiry * Find out hardware information about the xtalk widget. */intxtalk_device_inquiry(devfs_handle_t xbus_vhdl, xwidgetnum_t widget){ extern void hub_device_inquiry(devfs_handle_t, xwidgetnum_t); hub_device_inquiry(xbus_vhdl, widget); return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -