3 * This file is subject to the terms and conditions of the GNU General Public
4 * License. See the file "COPYING" in the main directory of this archive
7 * Copyright (c) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
10 #include <linux/types.h>
11 #include <linux/slab.h>
12 #include <asm/sn/sgi.h>
13 #include <asm/sn/driver.h>
14 #include <asm/sn/io.h>
15 #include <asm/sn/iograph.h>
16 #include <asm/sn/invent.h>
17 #include <asm/sn/hcl.h>
18 #include <asm/sn/labelcl.h>
19 #include <asm/sn/hcl_util.h>
20 #include <asm/sn/xtalk/xtalk.h>
21 #include <asm/sn/xtalk/xswitch.h>
22 #include <asm/sn/xtalk/xwidget.h>
23 #include <asm/sn/xtalk/xtalk_private.h>
26 * Implement crosstalk provider operations. The xtalk* layer provides a
27 * platform-independent interface for crosstalk devices. This layer
28 * switches among the possible implementations of a crosstalk adapter.
30 * On platforms with only one possible xtalk provider, macros can be
31 * set up at the top that cause the table lookups and indirections to
32 * completely disappear.
35 #define NEW(ptr) (ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
36 #define DEL(ptr) (kfree(ptr))
38 char widget_info_fingerprint[] = "widget_info";
40 #define DEV_FUNC(dev,func) hub_##func
41 #define CAST_PIOMAP(x) ((hub_piomap_t)(x))
42 #define CAST_DMAMAP(x) ((hub_dmamap_t)(x))
43 #define CAST_INTR(x) ((hub_intr_t)(x))
45 /* =====================================================================
46 * Function Table of Contents
48 xtalk_piomap_t xtalk_piomap_alloc(vertex_hdl_t, device_desc_t, iopaddr_t, size_t, size_t, unsigned);
49 void xtalk_piomap_free(xtalk_piomap_t);
50 caddr_t xtalk_piomap_addr(xtalk_piomap_t, iopaddr_t, size_t);
51 void xtalk_piomap_done(xtalk_piomap_t);
52 caddr_t xtalk_piotrans_addr(vertex_hdl_t, device_desc_t, iopaddr_t, size_t, unsigned);
53 caddr_t xtalk_pio_addr(vertex_hdl_t, device_desc_t, iopaddr_t, size_t, xtalk_piomap_t *, unsigned);
54 void xtalk_set_early_piotrans_addr(xtalk_early_piotrans_addr_f *);
55 caddr_t xtalk_early_piotrans_addr(xwidget_part_num_t, xwidget_mfg_num_t, int, iopaddr_t, size_t, unsigned);
56 static caddr_t null_xtalk_early_piotrans_addr(xwidget_part_num_t, xwidget_mfg_num_t, int, iopaddr_t, size_t, unsigned);
57 xtalk_dmamap_t xtalk_dmamap_alloc(vertex_hdl_t, device_desc_t, size_t, unsigned);
58 void xtalk_dmamap_free(xtalk_dmamap_t);
59 iopaddr_t xtalk_dmamap_addr(xtalk_dmamap_t, paddr_t, size_t);
60 alenlist_t xtalk_dmamap_list(xtalk_dmamap_t, alenlist_t, unsigned);
61 void xtalk_dmamap_done(xtalk_dmamap_t);
62 iopaddr_t xtalk_dmatrans_addr(vertex_hdl_t, device_desc_t, paddr_t, size_t, unsigned);
63 alenlist_t xtalk_dmatrans_list(vertex_hdl_t, device_desc_t, alenlist_t, unsigned);
64 void xtalk_dmamap_drain(xtalk_dmamap_t);
65 void xtalk_dmaaddr_drain(vertex_hdl_t, iopaddr_t, size_t);
66 void xtalk_dmalist_drain(vertex_hdl_t, alenlist_t);
67 xtalk_intr_t xtalk_intr_alloc(vertex_hdl_t, device_desc_t, vertex_hdl_t);
68 xtalk_intr_t xtalk_intr_alloc_nothd(vertex_hdl_t, device_desc_t, vertex_hdl_t);
69 void xtalk_intr_free(xtalk_intr_t);
70 int xtalk_intr_connect(xtalk_intr_t, intr_func_t, intr_arg_t, xtalk_intr_setfunc_t, void *);
71 void xtalk_intr_disconnect(xtalk_intr_t);
72 vertex_hdl_t xtalk_intr_cpu_get(xtalk_intr_t);
73 int xtalk_error_handler(vertex_hdl_t, int, ioerror_mode_t, ioerror_t *);
74 int xtalk_error_devenable(vertex_hdl_t, int, int);
75 void xtalk_provider_startup(vertex_hdl_t);
76 void xtalk_provider_shutdown(vertex_hdl_t);
77 vertex_hdl_t xtalk_intr_dev_get(xtalk_intr_t);
78 xwidgetnum_t xtalk_intr_target_get(xtalk_intr_t);
79 xtalk_intr_vector_t xtalk_intr_vector_get(xtalk_intr_t);
80 iopaddr_t xtalk_intr_addr_get(struct xtalk_intr_s *);
81 void *xtalk_intr_sfarg_get(xtalk_intr_t);
82 vertex_hdl_t xtalk_pio_dev_get(xtalk_piomap_t);
83 xwidgetnum_t xtalk_pio_target_get(xtalk_piomap_t);
84 iopaddr_t xtalk_pio_xtalk_addr_get(xtalk_piomap_t);
85 ulong xtalk_pio_mapsz_get(xtalk_piomap_t);
86 caddr_t xtalk_pio_kvaddr_get(xtalk_piomap_t);
87 vertex_hdl_t xtalk_dma_dev_get(xtalk_dmamap_t);
88 xwidgetnum_t xtalk_dma_target_get(xtalk_dmamap_t);
89 xwidget_info_t xwidget_info_chk(vertex_hdl_t);
90 xwidget_info_t xwidget_info_get(vertex_hdl_t);
91 void xwidget_info_set(vertex_hdl_t, xwidget_info_t);
92 vertex_hdl_t xwidget_info_dev_get(xwidget_info_t);
93 xwidgetnum_t xwidget_info_id_get(xwidget_info_t);
94 vertex_hdl_t xwidget_info_master_get(xwidget_info_t);
95 xwidgetnum_t xwidget_info_masterid_get(xwidget_info_t);
96 xwidget_part_num_t xwidget_info_part_num_get(xwidget_info_t);
97 xwidget_mfg_num_t xwidget_info_mfg_num_get(xwidget_info_t);
98 char *xwidget_info_name_get(xwidget_info_t);
99 void xtalk_provider_register(vertex_hdl_t, xtalk_provider_t *);
100 void xtalk_provider_unregister(vertex_hdl_t);
101 xtalk_provider_t *xtalk_provider_fns_get(vertex_hdl_t);
102 int xwidget_driver_register(xwidget_part_num_t,
105 void xwidget_driver_unregister(char *);
106 int xwidget_register(xwidget_hwid_t, vertex_hdl_t,
107 xwidgetnum_t, vertex_hdl_t,
109 int xwidget_unregister(vertex_hdl_t);
110 void xwidget_reset(vertex_hdl_t);
111 char *xwidget_name_get(vertex_hdl_t);
112 #if !defined(DEV_FUNC)
114 * There is more than one possible provider
115 * for this platform. We need to examine the
116 * master vertex of the current vertex for
117 * a provider function structure, and indirect
118 * through the appropriately named member.
120 #define DEV_FUNC(dev,func) xwidget_to_provider_fns(dev)->func
121 #define CAST_PIOMAP(x) ((xtalk_piomap_t)(x))
122 #define CAST_DMAMAP(x) ((xtalk_dmamap_t)(x))
123 #define CAST_INTR(x) ((xtalk_intr_t)(x))
125 static xtalk_provider_t *
126 xwidget_to_provider_fns(vertex_hdl_t xconn)
128 xwidget_info_t widget_info;
129 xtalk_provider_t *provider_fns;
131 widget_info = xwidget_info_get(xconn);
132 ASSERT(widget_info != NULL);
134 provider_fns = xwidget_info_pops_get(widget_info);
135 ASSERT(provider_fns != NULL);
137 return (provider_fns);
142 * Many functions are not passed their vertex
143 * information directly; rather, they must
144 * dive through a resource map. These macros
145 * are available to coordinate this detail.
147 #define PIOMAP_FUNC(map,func) DEV_FUNC(map->xp_dev,func)
148 #define DMAMAP_FUNC(map,func) DEV_FUNC(map->xd_dev,func)
149 #define INTR_FUNC(intr,func) DEV_FUNC(intr_hdl->xi_dev,func)
151 /* =====================================================================
154 * For mapping system virtual address space to
155 * xtalk space on a specified widget
159 xtalk_piomap_alloc(vertex_hdl_t dev, /* set up mapping for this device */
160 device_desc_t dev_desc, /* device descriptor */
161 iopaddr_t xtalk_addr, /* map for this xtalk_addr range */
163 size_t byte_count_max, /* maximum size of a mapping */
165 { /* defined in sys/pio.h */
166 return (xtalk_piomap_t) DEV_FUNC(dev, piomap_alloc)
167 (dev, dev_desc, xtalk_addr, byte_count, byte_count_max, flags);
172 xtalk_piomap_free(xtalk_piomap_t xtalk_piomap)
174 PIOMAP_FUNC(xtalk_piomap, piomap_free)
175 (CAST_PIOMAP(xtalk_piomap));
180 xtalk_piomap_addr(xtalk_piomap_t xtalk_piomap, /* mapping resources */
181 iopaddr_t xtalk_addr, /* map for this xtalk address */
183 { /* map this many bytes */
184 return PIOMAP_FUNC(xtalk_piomap, piomap_addr)
185 (CAST_PIOMAP(xtalk_piomap), xtalk_addr, byte_count);
190 xtalk_piomap_done(xtalk_piomap_t xtalk_piomap)
192 PIOMAP_FUNC(xtalk_piomap, piomap_done)
193 (CAST_PIOMAP(xtalk_piomap));
198 xtalk_piotrans_addr(vertex_hdl_t dev, /* translate for this device */
199 device_desc_t dev_desc, /* device descriptor */
200 iopaddr_t xtalk_addr, /* Crosstalk address */
201 size_t byte_count, /* map this many bytes */
203 { /* (currently unused) */
204 return DEV_FUNC(dev, piotrans_addr)
205 (dev, dev_desc, xtalk_addr, byte_count, flags);
209 xtalk_pio_addr(vertex_hdl_t dev, /* translate for this device */
210 device_desc_t dev_desc, /* device descriptor */
211 iopaddr_t addr, /* starting address (or offset in window) */
212 size_t byte_count, /* map this many bytes */
213 xtalk_piomap_t *mapp, /* where to return the map pointer */
216 xtalk_piomap_t map = 0;
220 *mapp = 0; /* record "no map used" */
222 res = xtalk_piotrans_addr
223 (dev, dev_desc, addr, byte_count, flags);
225 return res; /* xtalk_piotrans worked */
227 map = xtalk_piomap_alloc
228 (dev, dev_desc, addr, byte_count, byte_count, flags);
230 return res; /* xtalk_piomap_alloc failed */
232 res = xtalk_piomap_addr
233 (map, addr, byte_count);
235 xtalk_piomap_free(map);
236 return res; /* xtalk_piomap_addr failed */
239 *mapp = map; /* pass back map used */
241 return res; /* xtalk_piomap_addr succeeded */
244 /* =====================================================================
245 * EARLY PIOTRANS SUPPORT
247 * There are places where drivers (mgras, for instance)
248 * need to get PIO translations before the infrastructure
249 * is extended to them (setting up textports, for
250 * instance). These drivers should call
251 * xtalk_early_piotrans_addr with their xtalk ID
252 * information, a sequence number (so we can use the second
253 * mgras for instance), and the usual piotrans parameters.
255 * Machine specific code should provide an implementation
256 * of early_piotrans_addr, and present a pointer to this
257 * function to xtalk_set_early_piotrans_addr so it can be
258 * used by clients without the clients having to know what
259 * platform or what xtalk provider is in use.
262 static xtalk_early_piotrans_addr_f null_xtalk_early_piotrans_addr;
264 xtalk_early_piotrans_addr_f *impl_early_piotrans_addr = null_xtalk_early_piotrans_addr;
266 /* xtalk_set_early_piotrans_addr:
267 * specify the early_piotrans_addr implementation function.
270 xtalk_set_early_piotrans_addr(xtalk_early_piotrans_addr_f *impl)
272 impl_early_piotrans_addr = impl;
275 /* xtalk_early_piotrans_addr:
276 * figure out a PIO address for the "nth" crosstalk widget that
277 * matches the specified part and mfgr number. Returns NULL if
278 * there is no such widget, or if the requested mapping can not
280 * Limitations on which crosstalk slots (and busses) are
281 * checked, and definitions of the ordering of the search across
282 * the crosstalk slots, are defined by the platform.
285 xtalk_early_piotrans_addr(xwidget_part_num_t part_num,
286 xwidget_mfg_num_t mfg_num,
288 iopaddr_t xtalk_addr,
292 return impl_early_piotrans_addr
293 (part_num, mfg_num, which, xtalk_addr, byte_count, flags);
296 /* null_xtalk_early_piotrans_addr:
297 * used as the early_piotrans_addr implementation until and
298 * unless a real implementation is provided. In DEBUG kernels,
299 * we want to know who is calling before the implementation is
300 * registered; in non-DEBUG kernels, return NULL representing
301 * lack of mapping support.
305 null_xtalk_early_piotrans_addr(xwidget_part_num_t part_num,
306 xwidget_mfg_num_t mfg_num,
308 iopaddr_t xtalk_addr,
313 PRINT_PANIC("null_xtalk_early_piotrans_addr");
318 /* =====================================================================
321 * For mapping from crosstalk space to system
326 xtalk_dmamap_alloc(vertex_hdl_t dev, /* set up mappings for this device */
327 device_desc_t dev_desc, /* device descriptor */
328 size_t byte_count_max, /* max size of a mapping */
330 { /* defined in dma.h */
331 return (xtalk_dmamap_t) DEV_FUNC(dev, dmamap_alloc)
332 (dev, dev_desc, byte_count_max, flags);
337 xtalk_dmamap_free(xtalk_dmamap_t xtalk_dmamap)
339 DMAMAP_FUNC(xtalk_dmamap, dmamap_free)
340 (CAST_DMAMAP(xtalk_dmamap));
345 xtalk_dmamap_addr(xtalk_dmamap_t xtalk_dmamap, /* use these mapping resources */
346 paddr_t paddr, /* map for this address */
348 { /* map this many bytes */
349 return DMAMAP_FUNC(xtalk_dmamap, dmamap_addr)
350 (CAST_DMAMAP(xtalk_dmamap), paddr, byte_count);
355 xtalk_dmamap_list(xtalk_dmamap_t xtalk_dmamap, /* use these mapping resources */
356 alenlist_t alenlist, /* map this Address/Length List */
359 return DMAMAP_FUNC(xtalk_dmamap, dmamap_list)
360 (CAST_DMAMAP(xtalk_dmamap), alenlist, flags);
365 xtalk_dmamap_done(xtalk_dmamap_t xtalk_dmamap)
367 DMAMAP_FUNC(xtalk_dmamap, dmamap_done)
368 (CAST_DMAMAP(xtalk_dmamap));
373 xtalk_dmatrans_addr(vertex_hdl_t dev, /* translate for this device */
374 device_desc_t dev_desc, /* device descriptor */
375 paddr_t paddr, /* system physical address */
376 size_t byte_count, /* length */
378 { /* defined in dma.h */
379 return DEV_FUNC(dev, dmatrans_addr)
380 (dev, dev_desc, paddr, byte_count, flags);
385 xtalk_dmatrans_list(vertex_hdl_t dev, /* translate for this device */
386 device_desc_t dev_desc, /* device descriptor */
387 alenlist_t palenlist, /* system address/length list */
389 { /* defined in dma.h */
390 return DEV_FUNC(dev, dmatrans_list)
391 (dev, dev_desc, palenlist, flags);
395 xtalk_dmamap_drain(xtalk_dmamap_t map)
397 DMAMAP_FUNC(map, dmamap_drain)
402 xtalk_dmaaddr_drain(vertex_hdl_t dev, paddr_t addr, size_t size)
404 DEV_FUNC(dev, dmaaddr_drain)
409 xtalk_dmalist_drain(vertex_hdl_t dev, alenlist_t list)
411 DEV_FUNC(dev, dmalist_drain)
415 /* =====================================================================
416 * INTERRUPT MANAGEMENT
418 * Allow crosstalk devices to establish interrupts
422 * Allocate resources required for an interrupt as specified in intr_desc.
423 * Return resource handle in intr_hdl.
426 xtalk_intr_alloc(vertex_hdl_t dev, /* which Crosstalk device */
427 device_desc_t dev_desc, /* device descriptor */
428 vertex_hdl_t owner_dev)
429 { /* owner of this interrupt */
430 return (xtalk_intr_t) DEV_FUNC(dev, intr_alloc)
431 (dev, dev_desc, owner_dev);
435 * Allocate resources required for an interrupt as specified in dev_desc.
436 * Unconditionally setup resources to be non-threaded.
437 * Return resource handle in intr_hdl.
440 xtalk_intr_alloc_nothd(vertex_hdl_t dev, /* which Crosstalk device */
441 device_desc_t dev_desc, /* device descriptor */
442 vertex_hdl_t owner_dev) /* owner of this interrupt */
444 return (xtalk_intr_t) DEV_FUNC(dev, intr_alloc_nothd)
445 (dev, dev_desc, owner_dev);
449 * Free resources consumed by intr_alloc.
452 xtalk_intr_free(xtalk_intr_t intr_hdl)
454 INTR_FUNC(intr_hdl, intr_free)
455 (CAST_INTR(intr_hdl));
460 * Associate resources allocated with a previous xtalk_intr_alloc call with the
461 * described handler, arg, name, etc.
463 * Returns 0 on success, returns <0 on failure.
466 xtalk_intr_connect(xtalk_intr_t intr_hdl, /* xtalk intr resource handle */
467 intr_func_t intr_func, /* xtalk intr handler */
468 intr_arg_t intr_arg, /* arg to intr handler */
469 xtalk_intr_setfunc_t setfunc, /* func to set intr hw */
470 void *setfunc_arg) /* arg to setfunc */
472 return INTR_FUNC(intr_hdl, intr_connect)
473 (CAST_INTR(intr_hdl), intr_func, intr_arg, setfunc, setfunc_arg);
478 * Disassociate handler with the specified interrupt.
481 xtalk_intr_disconnect(xtalk_intr_t intr_hdl)
483 INTR_FUNC(intr_hdl, intr_disconnect)
484 (CAST_INTR(intr_hdl));
489 * Return a hwgraph vertex that represents the CPU currently
490 * targeted by an interrupt.
493 xtalk_intr_cpu_get(xtalk_intr_t intr_hdl)
495 return (vertex_hdl_t)0;
500 * =====================================================================
505 * xtalk_error_handler:
506 * pass this error on to the handler registered
507 * at the specified xtalk connecdtion point,
508 * or complain about it here if there is no handler.
510 * This routine plays two roles during error delivery
511 * to most widgets: first, the external agent (heart,
512 * hub, or whatever) calls in with the error and the
513 * connect point representing the crosstalk switch,
514 * or whatever crosstalk device is directly connected
517 * If there is a switch, it will generally look at the
518 * widget number stashed in the ioerror structure; and,
519 * if the error came from some widget other than the
520 * switch, it will call back into xtalk_error_handler
521 * with the connection point of the offending port.
530 xwidget_info_t xwidget_info;
532 xwidget_info = xwidget_info_get(xconn);
533 /* Make sure that xwidget_info is a valid pointer before derefencing it.
534 * We could come in here during very early initialization.
536 if (xwidget_info && xwidget_info->w_efunc)
537 return xwidget_info->w_efunc
538 (xwidget_info->w_einfo,
539 error_code, mode, ioerror);
541 * no error handler registered for
542 * the offending port. it's not clear
543 * what needs to be done, but reporting
544 * it would be a good thing, unless it
545 * is a mode that requires nothing.
547 if ((mode == MODE_DEVPROBE) || (mode == MODE_DEVUSERERROR) ||
548 (mode == MODE_DEVREENABLE))
549 return IOERROR_HANDLED;
551 #if defined(SUPPORT_PRINTING_V_FORMAT)
552 printk(KERN_WARNING "Xbow at %v encountered Fatal error", xconn);
554 printk(KERN_WARNING "Xbow at 0x%p encountered Fatal error", (void *)xconn);
556 ioerror_dump("xtalk", error_code, mode, ioerror);
558 return IOERROR_UNHANDLED;
562 xtalk_error_devenable(vertex_hdl_t xconn_vhdl, int devnum, int error_code)
564 return DEV_FUNC(xconn_vhdl, error_devenable) (xconn_vhdl, devnum, error_code);
568 /* =====================================================================
569 * CONFIGURATION MANAGEMENT
573 * Startup a crosstalk provider
576 xtalk_provider_startup(vertex_hdl_t xtalk_provider)
578 DEV_FUNC(xtalk_provider, provider_startup)
584 * Shutdown a crosstalk provider
587 xtalk_provider_shutdown(vertex_hdl_t xtalk_provider)
589 DEV_FUNC(xtalk_provider, provider_shutdown)
594 * Enable a device on a xtalk widget
597 xtalk_widgetdev_enable(vertex_hdl_t xconn_vhdl, int devnum)
603 * Shutdown a device on a xtalk widget
606 xtalk_widgetdev_shutdown(vertex_hdl_t xconn_vhdl, int devnum)
612 xtalk_dma_enabled(vertex_hdl_t xconn_vhdl)
614 return DEV_FUNC(xconn_vhdl, dma_enabled) (xconn_vhdl);
617 * Generic crosstalk functions, for use with all crosstalk providers
618 * and all crosstalk devices.
621 /****** Generic crosstalk interrupt interfaces ******/
623 xtalk_intr_dev_get(xtalk_intr_t xtalk_intr)
625 return (xtalk_intr->xi_dev);
629 xtalk_intr_target_get(xtalk_intr_t xtalk_intr)
631 return (xtalk_intr->xi_target);
635 xtalk_intr_vector_get(xtalk_intr_t xtalk_intr)
637 return (xtalk_intr->xi_vector);
641 xtalk_intr_addr_get(struct xtalk_intr_s *xtalk_intr)
643 return (xtalk_intr->xi_addr);
647 xtalk_intr_sfarg_get(xtalk_intr_t xtalk_intr)
649 return (xtalk_intr->xi_sfarg);
652 /****** Generic crosstalk pio interfaces ******/
654 xtalk_pio_dev_get(xtalk_piomap_t xtalk_piomap)
656 return (xtalk_piomap->xp_dev);
660 xtalk_pio_target_get(xtalk_piomap_t xtalk_piomap)
662 return (xtalk_piomap->xp_target);
666 xtalk_pio_xtalk_addr_get(xtalk_piomap_t xtalk_piomap)
668 return (xtalk_piomap->xp_xtalk_addr);
672 xtalk_pio_mapsz_get(xtalk_piomap_t xtalk_piomap)
674 return (xtalk_piomap->xp_mapsz);
678 xtalk_pio_kvaddr_get(xtalk_piomap_t xtalk_piomap)
680 return (xtalk_piomap->xp_kvaddr);
684 /****** Generic crosstalk dma interfaces ******/
686 xtalk_dma_dev_get(xtalk_dmamap_t xtalk_dmamap)
688 return (xtalk_dmamap->xd_dev);
692 xtalk_dma_target_get(xtalk_dmamap_t xtalk_dmamap)
694 return (xtalk_dmamap->xd_target);
698 /****** Generic crosstalk widget information interfaces ******/
701 * check to see if this vertex is a widget;
702 * if so, return its widget_info (if any).
703 * if not, return NULL.
706 xwidget_info_chk(vertex_hdl_t xwidget)
708 arbitrary_info_t ainfo = 0;
710 hwgraph_info_get_LBL(xwidget, INFO_LBL_XWIDGET, &ainfo);
711 return (xwidget_info_t) ainfo;
716 xwidget_info_get(vertex_hdl_t xwidget)
718 xwidget_info_t widget_info;
720 widget_info = (xwidget_info_t)
721 hwgraph_fastinfo_get(xwidget);
723 return (widget_info);
727 xwidget_info_set(vertex_hdl_t xwidget, xwidget_info_t widget_info)
729 if (widget_info != NULL)
730 widget_info->w_fingerprint = widget_info_fingerprint;
732 hwgraph_fastinfo_set(xwidget, (arbitrary_info_t) widget_info);
734 /* Also, mark this vertex as an xwidget,
735 * and use the widget_info, so xwidget_info_chk
736 * can work (and be fairly efficient).
738 hwgraph_info_add_LBL(xwidget, INFO_LBL_XWIDGET,
739 (arbitrary_info_t) widget_info);
743 xwidget_info_dev_get(xwidget_info_t xwidget_info)
745 if (xwidget_info == NULL)
746 panic("xwidget_info_dev_get: null xwidget_info");
747 return (xwidget_info->w_vertex);
751 xwidget_info_id_get(xwidget_info_t xwidget_info)
753 if (xwidget_info == NULL)
754 panic("xwidget_info_id_get: null xwidget_info");
755 return (xwidget_info->w_id);
760 xwidget_info_master_get(xwidget_info_t xwidget_info)
762 if (xwidget_info == NULL)
763 panic("xwidget_info_master_get: null xwidget_info");
764 return (xwidget_info->w_master);
768 xwidget_info_masterid_get(xwidget_info_t xwidget_info)
770 if (xwidget_info == NULL)
771 panic("xwidget_info_masterid_get: null xwidget_info");
772 return (xwidget_info->w_masterid);
776 xwidget_info_part_num_get(xwidget_info_t xwidget_info)
778 if (xwidget_info == NULL)
779 panic("xwidget_info_part_num_get: null xwidget_info");
780 return (xwidget_info->w_hwid.part_num);
784 xwidget_info_mfg_num_get(xwidget_info_t xwidget_info)
786 if (xwidget_info == NULL)
787 panic("xwidget_info_mfg_num_get: null xwidget_info");
788 return (xwidget_info->w_hwid.mfg_num);
790 /* Extract the widget name from the widget information
791 * for the xtalk widget.
794 xwidget_info_name_get(xwidget_info_t xwidget_info)
796 if (xwidget_info == NULL)
797 panic("xwidget_info_name_get: null xwidget_info");
798 return(xwidget_info->w_name);
800 /****** Generic crosstalk initialization interfaces ******/
803 * Associate a set of xtalk_provider functions with a vertex.
806 xtalk_provider_register(vertex_hdl_t provider, xtalk_provider_t *xtalk_fns)
808 hwgraph_fastinfo_set(provider, (arbitrary_info_t) xtalk_fns);
812 * Disassociate a set of xtalk_provider functions with a vertex.
815 xtalk_provider_unregister(vertex_hdl_t provider)
817 hwgraph_fastinfo_set(provider, (arbitrary_info_t)NULL);
821 * Obtain a pointer to the xtalk_provider functions for a specified Crosstalk
825 xtalk_provider_fns_get(vertex_hdl_t provider)
827 return ((xtalk_provider_t *) hwgraph_fastinfo_get(provider));
831 * Inform xtalk infrastructure that a driver is no longer available for
832 * handling any widgets.
835 xwidget_driver_unregister(char *driver_prefix)
841 * Call some function with each vertex that
842 * might be one of this driver's attach points.
845 xtalk_iterate(char *driver_prefix,
852 * Register a xtalk device (xwidget) by doing the following.
853 * -allocate and initialize xwidget_info data
854 * -allocate a hwgraph vertex with name based on widget number (id)
855 * -look up the widget's initialization function and call it,
856 * or remember the vertex for later initialization.
860 xwidget_register(xwidget_hwid_t hwid, /* widget's hardware ID */
861 vertex_hdl_t widget, /* widget to initialize */
862 xwidgetnum_t id, /* widget's target id (0..f) */
863 vertex_hdl_t master, /* widget's master vertex */
864 xwidgetnum_t targetid) /* master's target id (9/a) */
866 xwidget_info_t widget_info;
867 char *s,devnm[MAXDEVNAME];
869 /* Allocate widget_info and associate it with widget vertex */
872 /* Initialize widget_info */
873 widget_info->w_vertex = widget;
874 widget_info->w_id = id;
875 widget_info->w_master = master;
876 widget_info->w_masterid = targetid;
877 widget_info->w_hwid = *hwid; /* structure copy */
878 widget_info->w_efunc = 0;
879 widget_info->w_einfo = 0;
881 * get the name of this xwidget vertex and keep the info.
882 * This is needed during errors and interupts, but as
883 * long as we have it, we can use it elsewhere.
885 s = dev_to_name(widget,devnm,MAXDEVNAME);
886 widget_info->w_name = kmalloc(strlen(s) + 1, GFP_KERNEL);
887 strcpy(widget_info->w_name,s);
889 xwidget_info_set(widget, widget_info);
891 device_master_set(widget, master);
894 * Add pointer to async attach info -- tear down will be done when
895 * the particular descendant is done with the info.
897 return cdl_add_connpt(hwid->part_num, hwid->mfg_num,
902 * xwidget_unregister :
903 * Unregister the xtalk device and detach all its hwgraph namespace.
906 xwidget_unregister(vertex_hdl_t widget)
908 xwidget_info_t widget_info;
911 /* Make sure that we have valid widget information initialized */
912 if (!(widget_info = xwidget_info_get(widget)))
915 /* Remove the inventory information associated
918 hwgraph_inventory_remove(widget, -1, -1, -1, -1, -1);
920 hwid = &(widget_info->w_hwid);
922 /* Clean out the xwidget information */
923 (void)kfree(widget_info->w_name);
924 BZERO((void *)widget_info, sizeof(widget_info));
931 xwidget_error_register(vertex_hdl_t xwidget,
932 error_handler_f *efunc,
933 error_handler_arg_t einfo)
935 xwidget_info_t xwidget_info;
937 xwidget_info = xwidget_info_get(xwidget);
938 ASSERT(xwidget_info != NULL);
939 xwidget_info->w_efunc = efunc;
940 xwidget_info->w_einfo = einfo;
944 * Issue a link reset to a widget.
947 xwidget_reset(vertex_hdl_t xwidget)
949 xswitch_reset_link(xwidget);
954 xwidget_gfx_reset(vertex_hdl_t xwidget)
959 #define ANON_XWIDGET_NAME "No Name" /* Default Widget Name */
961 /* Get the canonical hwgraph name of xtalk widget */
963 xwidget_name_get(vertex_hdl_t xwidget_vhdl)
967 /* If we have a bogus widget handle then return
968 * a default anonymous widget name.
970 if (xwidget_vhdl == GRAPH_VERTEX_NONE)
971 return(ANON_XWIDGET_NAME);
972 /* Read the widget name stored in the widget info
973 * for the widget setup during widget initialization.
975 info = xwidget_info_get(xwidget_vhdl);
976 ASSERT(info != NULL);
977 return(xwidget_info_name_get(info));