1 /* $Id: io.c,v 1.2 2001/06/26 14:02:43 pfg Exp $
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/config.h>
11 #include <linux/types.h>
12 #include <linux/slab.h>
13 #include <asm/sn/types.h>
14 #include <asm/sn/sgi.h>
15 #include <asm/sn/driver.h>
16 #include <asm/sn/iograph.h>
17 #include <asm/param.h>
18 #include <asm/sn/pio.h>
19 #include <asm/sn/xtalk/xwidget.h>
20 #include <asm/sn/io.h>
21 #include <asm/sn/sn_private.h>
22 #include <asm/sn/addrs.h>
23 #include <asm/sn/invent.h>
24 #include <asm/sn/hcl.h>
25 #include <asm/sn/hcl_util.h>
26 #include <asm/sn/intr.h>
27 #include <asm/sn/xtalk/xtalkaddrs.h>
28 #include <asm/sn/klconfig.h>
29 #include <asm/sn/sn_cpuid.h>
31 extern xtalk_provider_t hub_provider;
32 extern void hub_intr_init(vertex_hdl_t hubv);
34 static int force_fire_and_forget = 1;
35 static int ignore_conveyor_override;
39 * Implementation of hub iobus operations.
41 * Hub provides a crosstalk "iobus" on IP27 systems. These routines
42 * provide a platform-specific implementation of xtalk used by all xtalk
43 * cards on IP27 systems.
45 * Called from corresponding xtalk_* routines.
50 /* For mapping system virtual address space to xtalk space on a specified widget */
53 * Setup pio structures needed for a particular hub.
56 hub_pio_init(vertex_hdl_t hubv)
62 hub_piomap_t hub_piomap;
64 hubinfo_get(hubv, &hubinfo);
65 nasid = hubinfo->h_nasid;
67 /* Initialize small window piomaps for this hub */
68 for (widget=0; widget <= HUB_WIDGET_ID_MAX; widget++) {
69 hub_piomap = hubinfo_swin_piomap_get(hubinfo, (int)widget);
70 hub_piomap->hpio_xtalk_info.xp_target = widget;
71 hub_piomap->hpio_xtalk_info.xp_xtalk_addr = 0;
72 hub_piomap->hpio_xtalk_info.xp_mapsz = SWIN_SIZE;
73 hub_piomap->hpio_xtalk_info.xp_kvaddr = (caddr_t)NODE_SWIN_BASE(nasid, widget);
74 hub_piomap->hpio_hub = hubv;
75 hub_piomap->hpio_flags = HUB_PIOMAP_IS_VALID;
78 /* Initialize big window piomaps for this hub */
79 for (bigwin=0; bigwin < HUB_NUM_BIG_WINDOW; bigwin++) {
80 hub_piomap = hubinfo_bwin_piomap_get(hubinfo, bigwin);
81 hub_piomap->hpio_xtalk_info.xp_mapsz = BWIN_SIZE;
82 hub_piomap->hpio_hub = hubv;
83 hub_piomap->hpio_holdcnt = 0;
84 hub_piomap->hpio_flags = HUB_PIOMAP_IS_BIGWINDOW;
85 IIO_ITTE_DISABLE(nasid, bigwin);
87 hub_set_piomode(nasid, HUB_PIO_CONVEYOR);
89 mutex_spinlock_init(&hubinfo->h_bwlock);
90 init_waitqueue_head(&hubinfo->h_bwwait);
94 * Create a caddr_t-to-xtalk_addr mapping.
96 * Use a small window if possible (that's the usual case), but
97 * manage big windows if needed. Big window mappings can be
98 * either FIXED or UNFIXED -- we keep at least 1 big window available
99 * for UNFIXED mappings.
101 * Returns an opaque pointer-sized type which can be passed to
102 * other hub_pio_* routines on success, or NULL if the request
103 * cannot be satisfied.
107 hub_piomap_alloc(vertex_hdl_t dev, /* set up mapping for this device */
108 device_desc_t dev_desc, /* device descriptor */
109 iopaddr_t xtalk_addr, /* map for this xtalk_addr range */
111 size_t byte_count_max, /* maximum size of a mapping */
112 unsigned flags) /* defined in sys/pio.h */
114 xwidget_info_t widget_info = xwidget_info_get(dev);
115 xwidgetnum_t widget = xwidget_info_id_get(widget_info);
116 vertex_hdl_t hubv = xwidget_info_master_get(widget_info);
118 hub_piomap_t bw_piomap;
119 int bigwin, free_bw_index;
121 volatile hubreg_t junk;
124 #ifdef PIOMAP_UNC_ACC_SPACE
129 if (byte_count_max > byte_count)
132 hubinfo_get(hubv, &hubinfo);
134 /* If xtalk_addr range is mapped by a small window, we don't have
137 if (xtalk_addr + byte_count <= SWIN_SIZE) {
140 piomap = hubinfo_swin_piomap_get(hubinfo, (int)widget);
141 #ifdef PIOMAP_UNC_ACC_SPACE
142 if (flags & PIOMAP_UNC_ACC) {
143 addr = (uint64_t)piomap->hpio_xtalk_info.xp_kvaddr;
144 addr |= PIOMAP_UNC_ACC_SPACE;
145 piomap->hpio_xtalk_info.xp_kvaddr = (caddr_t)addr;
151 /* We need to use a big window mapping. */
154 * TBD: Allow requests that would consume multiple big windows --
155 * split the request up and use multiple mapping entries.
156 * For now, reject requests that span big windows.
158 if ((xtalk_addr % BWIN_SIZE) + byte_count > BWIN_SIZE)
162 /* Round xtalk address down for big window alignement */
163 xtalk_addr = xtalk_addr & ~(BWIN_SIZE-1);
166 * Check to see if an existing big window mapping will suffice.
170 s = mutex_spinlock(&hubinfo->h_bwlock);
171 for (bigwin=0; bigwin < HUB_NUM_BIG_WINDOW; bigwin++) {
172 bw_piomap = hubinfo_bwin_piomap_get(hubinfo, bigwin);
174 /* If mapping is not valid, skip it */
175 if (!(bw_piomap->hpio_flags & HUB_PIOMAP_IS_VALID)) {
176 free_bw_index = bigwin;
181 * If mapping is UNFIXED, skip it. We don't allow sharing
182 * of UNFIXED mappings, because this would allow starvation.
184 if (!(bw_piomap->hpio_flags & HUB_PIOMAP_IS_FIXED))
187 if ( xtalk_addr == bw_piomap->hpio_xtalk_info.xp_xtalk_addr &&
188 widget == bw_piomap->hpio_xtalk_info.xp_target) {
189 bw_piomap->hpio_holdcnt++;
190 mutex_spinunlock(&hubinfo->h_bwlock, s);
196 * None of the existing big window mappings will work for us --
197 * we need to establish a new mapping.
200 /* Insure that we don't consume all big windows with FIXED mappings */
201 if (flags & PIOMAP_FIXED) {
202 if (hubinfo->h_num_big_window_fixed < HUB_NUM_BIG_WINDOW-1) {
203 ASSERT(free_bw_index >= 0);
204 hubinfo->h_num_big_window_fixed++;
209 } else /* PIOMAP_UNFIXED */ {
210 if (free_bw_index < 0) {
211 if (flags & PIOMAP_NOSLEEP) {
215 DECLARE_WAITQUEUE(wait, current);
217 spin_unlock(&hubinfo->h_bwlock);
218 set_current_state(TASK_UNINTERRUPTIBLE);
219 add_wait_queue_exclusive(&hubinfo->h_bwwait, &wait);
221 remove_wait_queue(&hubinfo->h_bwwait, &wait);
228 /* OK! Allocate big window free_bw_index for this mapping. */
230 * The code below does a PIO write to setup an ITTE entry.
231 * We need to prevent other CPUs from seeing our updated memory
232 * shadow of the ITTE (in the piomap) until the ITTE entry is
233 * actually set up; otherwise, another CPU might attempt a PIO
236 * Also, the only way we can know that an entry has been received
237 * by the hub and can be used by future PIO reads/writes is by
238 * reading back the ITTE entry after writing it.
240 * For these two reasons, we PIO read back the ITTE entry after
244 nasid = hubinfo->h_nasid;
245 IIO_ITTE_PUT(nasid, free_bw_index, HUB_PIO_MAP_TO_MEM, widget, xtalk_addr);
246 junk = HUB_L(IIO_ITTE_GET(nasid, free_bw_index));
248 bw_piomap = hubinfo_bwin_piomap_get(hubinfo, free_bw_index);
249 bw_piomap->hpio_xtalk_info.xp_dev = dev;
250 bw_piomap->hpio_xtalk_info.xp_target = widget;
251 bw_piomap->hpio_xtalk_info.xp_xtalk_addr = xtalk_addr;
252 kvaddr = (caddr_t)NODE_BWIN_BASE(nasid, free_bw_index);
253 #ifdef PIOMAP_UNC_ACC_SPACE
254 if (flags & PIOMAP_UNC_ACC) {
255 addr = (uint64_t)kvaddr;
256 addr |= PIOMAP_UNC_ACC_SPACE;
257 kvaddr = (caddr_t)addr;
260 bw_piomap->hpio_xtalk_info.xp_kvaddr = kvaddr;
261 bw_piomap->hpio_holdcnt++;
262 bw_piomap->hpio_bigwin_num = free_bw_index;
264 if (flags & PIOMAP_FIXED)
265 bw_piomap->hpio_flags |= HUB_PIOMAP_IS_VALID | HUB_PIOMAP_IS_FIXED;
267 bw_piomap->hpio_flags |= HUB_PIOMAP_IS_VALID;
270 mutex_spinunlock(&hubinfo->h_bwlock, s);
275 * hub_piomap_free destroys a caddr_t-to-xtalk pio mapping and frees
276 * any associated mapping resources.
278 * If this * piomap was handled with a small window, or if it was handled
279 * in a big window that's still in use by someone else, then there's
280 * nothing to do. On the other hand, if this mapping was handled
281 * with a big window, AND if we were the final user of that mapping,
282 * then destroy the mapping.
285 hub_piomap_free(hub_piomap_t hub_piomap)
293 * Small windows are permanently mapped to corresponding widgets,
294 * so there're no resources to free.
296 if (!(hub_piomap->hpio_flags & HUB_PIOMAP_IS_BIGWINDOW))
299 ASSERT(hub_piomap->hpio_flags & HUB_PIOMAP_IS_VALID);
300 ASSERT(hub_piomap->hpio_holdcnt > 0);
302 hubv = hub_piomap->hpio_hub;
303 hubinfo_get(hubv, &hubinfo);
304 nasid = hubinfo->h_nasid;
306 s = mutex_spinlock(&hubinfo->h_bwlock);
309 * If this is the last hold on this mapping, free it.
311 if (--hub_piomap->hpio_holdcnt == 0) {
312 IIO_ITTE_DISABLE(nasid, hub_piomap->hpio_bigwin_num );
314 if (hub_piomap->hpio_flags & HUB_PIOMAP_IS_FIXED) {
315 hub_piomap->hpio_flags &= ~(HUB_PIOMAP_IS_VALID | HUB_PIOMAP_IS_FIXED);
316 hubinfo->h_num_big_window_fixed--;
317 ASSERT(hubinfo->h_num_big_window_fixed >= 0);
319 hub_piomap->hpio_flags &= ~HUB_PIOMAP_IS_VALID;
321 wake_up(&hubinfo->h_bwwait);
324 mutex_spinunlock(&hubinfo->h_bwlock, s);
328 * Establish a mapping to a given xtalk address range using the resources
332 hub_piomap_addr(hub_piomap_t hub_piomap, /* mapping resources */
333 iopaddr_t xtalk_addr, /* map for this xtalk address */
334 size_t byte_count) /* map this many bytes */
336 /* Verify that range can be mapped using the specified piomap */
337 if (xtalk_addr < hub_piomap->hpio_xtalk_info.xp_xtalk_addr)
340 if (xtalk_addr + byte_count >
341 ( hub_piomap->hpio_xtalk_info.xp_xtalk_addr +
342 hub_piomap->hpio_xtalk_info.xp_mapsz))
345 if (hub_piomap->hpio_flags & HUB_PIOMAP_IS_VALID)
346 return(hub_piomap->hpio_xtalk_info.xp_kvaddr +
347 (xtalk_addr % hub_piomap->hpio_xtalk_info.xp_mapsz));
354 * Driver indicates that it's done with PIO's from an earlier piomap_addr.
358 hub_piomap_done(hub_piomap_t hub_piomap) /* done with these mapping resources */
365 * For translations that require no mapping resources, supply a kernel virtual
366 * address that maps to the specified xtalk address range.
370 hub_piotrans_addr( vertex_hdl_t dev, /* translate to this device */
371 device_desc_t dev_desc, /* device descriptor */
372 iopaddr_t xtalk_addr, /* Crosstalk address */
373 size_t byte_count, /* map this many bytes */
374 unsigned flags) /* (currently unused) */
376 xwidget_info_t widget_info = xwidget_info_get(dev);
377 xwidgetnum_t widget = xwidget_info_id_get(widget_info);
378 vertex_hdl_t hubv = xwidget_info_master_get(widget_info);
379 hub_piomap_t hub_piomap;
383 hubinfo_get(hubv, &hubinfo);
385 if (xtalk_addr + byte_count <= SWIN_SIZE) {
386 hub_piomap = hubinfo_swin_piomap_get(hubinfo, (int)widget);
387 addr = hub_piomap_addr(hub_piomap, xtalk_addr, byte_count);
388 #ifdef PIOMAP_UNC_ACC_SPACE
389 if (flags & PIOMAP_UNC_ACC) {
391 iaddr = (uint64_t)addr;
392 iaddr |= PIOMAP_UNC_ACC_SPACE;
393 addr = (caddr_t)iaddr;
403 /* Mapping from crosstalk space to system physical space */
407 * Allocate resources needed to set up DMA mappings up to a specified size
408 * on a specified adapter.
410 * We don't actually use the adapter ID for anything. It's just the adapter
411 * that the lower level driver plans to use for DMA.
415 hub_dmamap_alloc( vertex_hdl_t dev, /* set up mappings for this device */
416 device_desc_t dev_desc, /* device descriptor */
417 size_t byte_count_max, /* max size of a mapping */
418 unsigned flags) /* defined in dma.h */
421 xwidget_info_t widget_info = xwidget_info_get(dev);
422 xwidgetnum_t widget = xwidget_info_id_get(widget_info);
423 vertex_hdl_t hubv = xwidget_info_master_get(widget_info);
425 dmamap = kmalloc(sizeof(struct hub_dmamap_s), GFP_ATOMIC);
426 dmamap->hdma_xtalk_info.xd_dev = dev;
427 dmamap->hdma_xtalk_info.xd_target = widget;
428 dmamap->hdma_hub = hubv;
429 dmamap->hdma_flags = HUB_DMAMAP_IS_VALID;
430 if (flags & XTALK_FIXED)
431 dmamap->hdma_flags |= HUB_DMAMAP_IS_FIXED;
437 * Destroy a DMA mapping from crosstalk space to system address space.
438 * There is no actual mapping hardware to destroy, but we at least mark
439 * the dmamap INVALID and free the space that it took.
442 hub_dmamap_free(hub_dmamap_t hub_dmamap)
444 hub_dmamap->hdma_flags &= ~HUB_DMAMAP_IS_VALID;
445 kern_free(hub_dmamap);
449 * Establish a DMA mapping using the resources allocated in a previous dmamap_alloc.
450 * Return an appropriate crosstalk address range that maps to the specified physical
455 hub_dmamap_addr( hub_dmamap_t dmamap, /* use these mapping resources */
456 paddr_t paddr, /* map for this address */
457 size_t byte_count) /* map this many bytes */
461 ASSERT(dmamap->hdma_flags & HUB_DMAMAP_IS_VALID);
463 if (dmamap->hdma_flags & HUB_DMAMAP_USED) {
464 /* If the map is FIXED, re-use is OK. */
465 if (!(dmamap->hdma_flags & HUB_DMAMAP_IS_FIXED)) {
466 vhdl = dmamap->hdma_xtalk_info.xd_dev;
467 #if defined(SUPPORT_PRINTING_V_FORMAT)
468 printk(KERN_WARNING "%v: hub_dmamap_addr re-uses dmamap.\n",vhdl);
470 printk(KERN_WARNING "%p: hub_dmamap_addr re-uses dmamap.\n", (void *)vhdl);
474 dmamap->hdma_flags |= HUB_DMAMAP_USED;
477 /* There isn't actually any DMA mapping hardware on the hub. */
478 return( (PHYS_TO_DMA(paddr)) );
482 * Establish a DMA mapping using the resources allocated in a previous dmamap_alloc.
483 * Return an appropriate crosstalk address list that maps to the specified physical
488 hub_dmamap_list(hub_dmamap_t hub_dmamap, /* use these mapping resources */
489 alenlist_t palenlist, /* map this area of memory */
494 ASSERT(hub_dmamap->hdma_flags & HUB_DMAMAP_IS_VALID);
496 if (hub_dmamap->hdma_flags & HUB_DMAMAP_USED) {
497 /* If the map is FIXED, re-use is OK. */
498 if (!(hub_dmamap->hdma_flags & HUB_DMAMAP_IS_FIXED)) {
499 vhdl = hub_dmamap->hdma_xtalk_info.xd_dev;
500 #if defined(SUPPORT_PRINTING_V_FORMAT)
501 printk(KERN_WARNING "%v: hub_dmamap_list re-uses dmamap\n",vhdl);
503 printk(KERN_WARNING "%p: hub_dmamap_list re-uses dmamap\n", (void *)vhdl);
507 hub_dmamap->hdma_flags |= HUB_DMAMAP_USED;
510 /* There isn't actually any DMA mapping hardware on the hub. */
515 * Driver indicates that it has completed whatever DMA it may have started
516 * after an earlier dmamap_addr or dmamap_list call.
519 hub_dmamap_done(hub_dmamap_t hub_dmamap) /* done with these mapping resources */
523 if (hub_dmamap->hdma_flags & HUB_DMAMAP_USED) {
524 hub_dmamap->hdma_flags &= ~HUB_DMAMAP_USED;
526 /* If the map is FIXED, re-done is OK. */
527 if (!(hub_dmamap->hdma_flags & HUB_DMAMAP_IS_FIXED)) {
528 vhdl = hub_dmamap->hdma_xtalk_info.xd_dev;
529 #if defined(SUPPORT_PRINTING_V_FORMAT)
530 printk(KERN_WARNING "%v: hub_dmamap_done already done with dmamap\n",vhdl);
532 printk(KERN_WARNING "%p: hub_dmamap_done already done with dmamap\n", (void *)vhdl);
539 * Translate a single system physical address into a crosstalk address.
543 hub_dmatrans_addr( vertex_hdl_t dev, /* translate for this device */
544 device_desc_t dev_desc, /* device descriptor */
545 paddr_t paddr, /* system physical address */
546 size_t byte_count, /* length */
547 unsigned flags) /* defined in dma.h */
549 return( (PHYS_TO_DMA(paddr)) );
553 * Translate a list of IP27 addresses and lengths into a list of crosstalk
554 * addresses and lengths. No actual hardware mapping takes place; the hub
555 * has no DMA mapping registers -- crosstalk addresses map directly.
559 hub_dmatrans_list( vertex_hdl_t dev, /* translate for this device */
560 device_desc_t dev_desc, /* device descriptor */
561 alenlist_t palenlist, /* system address/length list */
562 unsigned flags) /* defined in dma.h */
565 /* no translation needed */
571 hub_dmamap_drain( hub_dmamap_t map)
573 /* XXX- flush caches, if cache coherency WAR is needed */
578 hub_dmaaddr_drain( vertex_hdl_t vhdl,
582 /* XXX- flush caches, if cache coherency WAR is needed */
587 hub_dmalist_drain( vertex_hdl_t vhdl,
590 /* XXX- flush caches, if cache coherency WAR is needed */
595 /* CONFIGURATION MANAGEMENT */
598 * Perform initializations that allow this hub to start crosstalk support.
601 hub_provider_startup(vertex_hdl_t hubv)
608 * Shutdown crosstalk support from a hub.
611 hub_provider_shutdown(vertex_hdl_t hub)
614 xtalk_provider_unregister(hub);
618 * Check that an address is in the real small window widget 0 space
619 * or else in the big window we're using to emulate small window 0
623 hub_check_is_widget0(void *addr)
625 nasid_t nasid = NASID_GET(addr);
627 if (((__psunsigned_t)addr >= RAW_NODE_SWIN_BASE(nasid, 0)) &&
628 ((__psunsigned_t)addr < RAW_NODE_SWIN_BASE(nasid, 1)))
635 * Check that two addresses use the same widget
638 hub_check_window_equiv(void *addra, void *addrb)
640 if (hub_check_is_widget0(addra) && hub_check_is_widget0(addrb))
643 /* XXX - Assume this is really a small window address */
644 if (WIDGETID_GET((__psunsigned_t)addra) ==
645 WIDGETID_GET((__psunsigned_t)addrb))
653 * hub_setup_prb(nasid, prbnum, credits, conveyor)
655 * Put a PRB into fire-and-forget mode if conveyor isn't set. Otherwise,
656 * put it into conveyor belt mode with the specified number of credits.
659 hub_setup_prb(nasid_t nasid, int prbnum, int credits, int conveyor)
664 if (force_fire_and_forget && !ignore_conveyor_override)
665 if (conveyor == HUB_PIO_CONVEYOR)
666 conveyor = HUB_PIO_FIRE_N_FORGET;
669 * Get the current register value.
671 prb_offset = IIO_IOPRB(prbnum);
672 prb.iprb_regval = REMOTE_HUB_L(nasid, prb_offset);
675 * Clear out some fields.
678 prb.iprb_bnakctr = 0;
679 prb.iprb_anakctr = 0;
682 * Enable or disable fire-and-forget mode.
684 prb.iprb_ff = ((conveyor == HUB_PIO_CONVEYOR) ? 0 : 1);
687 * Set the appropriate number of PIO cresits for the widget.
689 prb.iprb_xtalkctr = credits;
692 * Store the new value to the register.
694 REMOTE_HUB_S(nasid, prb_offset, prb.iprb_regval);
700 * Put the hub into either "PIO conveyor belt" mode or "fire-and-forget"
701 * mode. To do this, we have to make absolutely sure that no PIOs
702 * are in progress so we turn off access to all widgets for the duration
705 * XXX - This code should really check what kind of widget we're talking
706 * to. Bridges can only handle three requests, but XG will do more.
707 * How many can crossbow handle to widget 0? We're assuming 1.
709 * XXX - There is a bug in the crossbow that link reset PIOs do not
710 * return write responses. The easiest solution to this problem is to
711 * leave widget 0 (xbow) in fire-and-forget mode at all times. This
712 * only affects pio's to xbow registers, which should be rare.
715 hub_set_piomode(nasid_t nasid, int conveyor)
722 ASSERT(NASID_TO_COMPACT_NODEID(nasid) != INVALID_CNODEID);
724 ii_iowa = REMOTE_HUB_L(nasid, IIO_OUTWIDGET_ACCESS);
725 REMOTE_HUB_S(nasid, IIO_OUTWIDGET_ACCESS, 0);
727 ii_wcr.wcr_reg_value = REMOTE_HUB_L(nasid, IIO_WCR);
728 direct_connect = ii_wcr.iwcr_dir_con;
730 if (direct_connect) {
732 * Assume a bridge here.
734 hub_setup_prb(nasid, 0, 3, conveyor);
737 * Assume a crossbow here.
739 hub_setup_prb(nasid, 0, 1, conveyor);
742 for (prbnum = HUB_WIDGET_ID_MIN; prbnum <= HUB_WIDGET_ID_MAX; prbnum++) {
744 * XXX - Here's where we should take the widget type into
745 * when account assigning credits.
747 /* Always set the PRBs in fire-and-forget mode */
748 hub_setup_prb(nasid, prbnum, 3, conveyor);
751 REMOTE_HUB_S(nasid, IIO_OUTWIDGET_ACCESS, ii_iowa);
753 /* Interface to allow special drivers to set hub specific
755 * Return 0 on failure , 1 on success
758 hub_widget_flags_set(nasid_t nasid,
759 xwidgetnum_t widget_num,
760 hub_widget_flags_t flags)
763 ASSERT((flags & HUB_WIDGET_FLAGS) == flags);
765 if (flags & HUB_PIO_CONVEYOR) {
766 hub_setup_prb(nasid,widget_num,
767 3,HUB_PIO_CONVEYOR); /* set the PRB in conveyor
768 * belt mode with 3 credits
770 } else if (flags & HUB_PIO_FIRE_N_FORGET) {
771 hub_setup_prb(nasid,widget_num,
772 3,HUB_PIO_FIRE_N_FORGET); /* set the PRB in fire
781 * A pointer to this structure hangs off of every hub hwgraph vertex.
782 * The generic xtalk layer may indirect through it to get to this specific
783 * crosstalk bus provider.
785 xtalk_provider_t hub_provider = {
786 (xtalk_piomap_alloc_f *) hub_piomap_alloc,
787 (xtalk_piomap_free_f *) hub_piomap_free,
788 (xtalk_piomap_addr_f *) hub_piomap_addr,
789 (xtalk_piomap_done_f *) hub_piomap_done,
790 (xtalk_piotrans_addr_f *) hub_piotrans_addr,
792 (xtalk_dmamap_alloc_f *) hub_dmamap_alloc,
793 (xtalk_dmamap_free_f *) hub_dmamap_free,
794 (xtalk_dmamap_addr_f *) hub_dmamap_addr,
795 (xtalk_dmamap_list_f *) hub_dmamap_list,
796 (xtalk_dmamap_done_f *) hub_dmamap_done,
797 (xtalk_dmatrans_addr_f *) hub_dmatrans_addr,
798 (xtalk_dmatrans_list_f *) hub_dmatrans_list,
799 (xtalk_dmamap_drain_f *) hub_dmamap_drain,
800 (xtalk_dmaaddr_drain_f *) hub_dmaaddr_drain,
801 (xtalk_dmalist_drain_f *) hub_dmalist_drain,
803 (xtalk_intr_alloc_f *) hub_intr_alloc,
804 (xtalk_intr_alloc_f *) hub_intr_alloc_nothd,
805 (xtalk_intr_free_f *) hub_intr_free,
806 (xtalk_intr_connect_f *) hub_intr_connect,
807 (xtalk_intr_disconnect_f *) hub_intr_disconnect,
808 (xtalk_provider_startup_f *) hub_provider_startup,
809 (xtalk_provider_shutdown_f *) hub_provider_shutdown,