2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
6 * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
9 #include <linux/types.h>
10 #include <linux/slab.h>
11 #include <linux/sched.h>
12 #include <asm/sn/types.h>
13 #include <asm/sn/sgi.h>
14 #include <asm/sn/driver.h>
15 #include <asm/param.h>
16 #include <asm/sn/pio.h>
17 #include <asm/sn/xtalk/xwidget.h>
18 #include <asm/sn/io.h>
19 #include <asm/sn/sn_private.h>
20 #include <asm/sn/addrs.h>
21 #include <asm/sn/hcl.h>
22 #include <asm/sn/hcl_util.h>
23 #include <asm/sn/intr.h>
24 #include <asm/sn/xtalk/xtalkaddrs.h>
25 #include <asm/sn/klconfig.h>
26 #include <asm/sn/sn_cpuid.h>
28 extern xtalk_provider_t hub_provider
;
30 static int force_fire_and_forget
= 1;
31 static int ignore_conveyor_override
;
35 * Implementation of hub iobus operations.
37 * Hub provides a crosstalk "iobus" on IP27 systems. These routines
38 * provide a platform-specific implementation of xtalk used by all xtalk
39 * cards on IP27 systems.
41 * Called from corresponding xtalk_* routines.
46 /* For mapping system virtual address space to xtalk space on a specified widget */
49 * Setup pio structures needed for a particular hub.
52 hub_pio_init(vertex_hdl_t hubv
)
58 hub_piomap_t hub_piomap
;
60 hubinfo_get(hubv
, &hubinfo
);
61 nasid
= hubinfo
->h_nasid
;
63 /* Initialize small window piomaps for this hub */
64 for (widget
=0; widget
<= HUB_WIDGET_ID_MAX
; widget
++) {
65 hub_piomap
= hubinfo_swin_piomap_get(hubinfo
, (int)widget
);
66 hub_piomap
->hpio_xtalk_info
.xp_target
= widget
;
67 hub_piomap
->hpio_xtalk_info
.xp_xtalk_addr
= 0;
68 hub_piomap
->hpio_xtalk_info
.xp_mapsz
= SWIN_SIZE
;
69 hub_piomap
->hpio_xtalk_info
.xp_kvaddr
= (caddr_t
)NODE_SWIN_BASE(nasid
, widget
);
70 hub_piomap
->hpio_hub
= hubv
;
71 hub_piomap
->hpio_flags
= HUB_PIOMAP_IS_VALID
;
74 /* Initialize big window piomaps for this hub */
75 for (bigwin
=0; bigwin
< HUB_NUM_BIG_WINDOW
; bigwin
++) {
76 hub_piomap
= hubinfo_bwin_piomap_get(hubinfo
, bigwin
);
77 hub_piomap
->hpio_xtalk_info
.xp_mapsz
= BWIN_SIZE
;
78 hub_piomap
->hpio_hub
= hubv
;
79 hub_piomap
->hpio_holdcnt
= 0;
80 hub_piomap
->hpio_flags
= HUB_PIOMAP_IS_BIGWINDOW
;
81 IIO_ITTE_DISABLE(nasid
, bigwin
);
83 hub_set_piomode(nasid
, HUB_PIO_CONVEYOR
);
85 spin_lock_init(&hubinfo
->h_bwlock
);
86 init_waitqueue_head(&hubinfo
->h_bwwait
);
90 * Create a caddr_t-to-xtalk_addr mapping.
92 * Use a small window if possible (that's the usual case), but
93 * manage big windows if needed. Big window mappings can be
94 * either FIXED or UNFIXED -- we keep at least 1 big window available
95 * for UNFIXED mappings.
97 * Returns an opaque pointer-sized type which can be passed to
98 * other hub_pio_* routines on success, or NULL if the request
99 * cannot be satisfied.
103 hub_piomap_alloc(vertex_hdl_t dev
, /* set up mapping for this device */
104 device_desc_t dev_desc
, /* device descriptor */
105 iopaddr_t xtalk_addr
, /* map for this xtalk_addr range */
107 size_t byte_count_max
, /* maximum size of a mapping */
108 unsigned flags
) /* defined in sys/pio.h */
110 xwidget_info_t widget_info
= xwidget_info_get(dev
);
111 xwidgetnum_t widget
= xwidget_info_id_get(widget_info
);
112 vertex_hdl_t hubv
= xwidget_info_master_get(widget_info
);
114 hub_piomap_t bw_piomap
;
115 int bigwin
, free_bw_index
;
117 volatile hubreg_t junk
;
119 #ifdef PIOMAP_UNC_ACC_SPACE
124 if (byte_count_max
> byte_count
)
127 hubinfo_get(hubv
, &hubinfo
);
129 /* If xtalk_addr range is mapped by a small window, we don't have
132 if (xtalk_addr
+ byte_count
<= SWIN_SIZE
) {
135 piomap
= hubinfo_swin_piomap_get(hubinfo
, (int)widget
);
136 #ifdef PIOMAP_UNC_ACC_SPACE
137 if (flags
& PIOMAP_UNC_ACC
) {
138 addr
= (uint64_t)piomap
->hpio_xtalk_info
.xp_kvaddr
;
139 addr
|= PIOMAP_UNC_ACC_SPACE
;
140 piomap
->hpio_xtalk_info
.xp_kvaddr
= (caddr_t
)addr
;
146 /* We need to use a big window mapping. */
149 * TBD: Allow requests that would consume multiple big windows --
150 * split the request up and use multiple mapping entries.
151 * For now, reject requests that span big windows.
153 if ((xtalk_addr
% BWIN_SIZE
) + byte_count
> BWIN_SIZE
)
157 /* Round xtalk address down for big window alignement */
158 xtalk_addr
= xtalk_addr
& ~(BWIN_SIZE
-1);
161 * Check to see if an existing big window mapping will suffice.
165 spin_lock(&hubinfo
->h_bwlock
);
166 for (bigwin
=0; bigwin
< HUB_NUM_BIG_WINDOW
; bigwin
++) {
167 bw_piomap
= hubinfo_bwin_piomap_get(hubinfo
, bigwin
);
169 /* If mapping is not valid, skip it */
170 if (!(bw_piomap
->hpio_flags
& HUB_PIOMAP_IS_VALID
)) {
171 free_bw_index
= bigwin
;
176 * If mapping is UNFIXED, skip it. We don't allow sharing
177 * of UNFIXED mappings, because this would allow starvation.
179 if (!(bw_piomap
->hpio_flags
& HUB_PIOMAP_IS_FIXED
))
182 if ( xtalk_addr
== bw_piomap
->hpio_xtalk_info
.xp_xtalk_addr
&&
183 widget
== bw_piomap
->hpio_xtalk_info
.xp_target
) {
184 bw_piomap
->hpio_holdcnt
++;
185 spin_unlock(&hubinfo
->h_bwlock
);
191 * None of the existing big window mappings will work for us --
192 * we need to establish a new mapping.
195 /* Insure that we don't consume all big windows with FIXED mappings */
196 if (flags
& PIOMAP_FIXED
) {
197 if (hubinfo
->h_num_big_window_fixed
< HUB_NUM_BIG_WINDOW
-1) {
198 ASSERT(free_bw_index
>= 0);
199 hubinfo
->h_num_big_window_fixed
++;
204 } else /* PIOMAP_UNFIXED */ {
205 if (free_bw_index
< 0) {
206 if (flags
& PIOMAP_NOSLEEP
) {
210 DECLARE_WAITQUEUE(wait
, current
);
212 spin_unlock(&hubinfo
->h_bwlock
);
213 set_current_state(TASK_UNINTERRUPTIBLE
);
214 add_wait_queue_exclusive(&hubinfo
->h_bwwait
, &wait
);
216 remove_wait_queue(&hubinfo
->h_bwwait
, &wait
);
223 /* OK! Allocate big window free_bw_index for this mapping. */
225 * The code below does a PIO write to setup an ITTE entry.
226 * We need to prevent other CPUs from seeing our updated memory
227 * shadow of the ITTE (in the piomap) until the ITTE entry is
228 * actually set up; otherwise, another CPU might attempt a PIO
231 * Also, the only way we can know that an entry has been received
232 * by the hub and can be used by future PIO reads/writes is by
233 * reading back the ITTE entry after writing it.
235 * For these two reasons, we PIO read back the ITTE entry after
239 nasid
= hubinfo
->h_nasid
;
240 IIO_ITTE_PUT(nasid
, free_bw_index
, HUB_PIO_MAP_TO_MEM
, widget
, xtalk_addr
);
241 junk
= HUB_L(IIO_ITTE_GET(nasid
, free_bw_index
));
243 bw_piomap
= hubinfo_bwin_piomap_get(hubinfo
, free_bw_index
);
244 bw_piomap
->hpio_xtalk_info
.xp_dev
= dev
;
245 bw_piomap
->hpio_xtalk_info
.xp_target
= widget
;
246 bw_piomap
->hpio_xtalk_info
.xp_xtalk_addr
= xtalk_addr
;
247 kvaddr
= (caddr_t
)NODE_BWIN_BASE(nasid
, free_bw_index
);
248 #ifdef PIOMAP_UNC_ACC_SPACE
249 if (flags
& PIOMAP_UNC_ACC
) {
250 addr
= (uint64_t)kvaddr
;
251 addr
|= PIOMAP_UNC_ACC_SPACE
;
252 kvaddr
= (caddr_t
)addr
;
255 bw_piomap
->hpio_xtalk_info
.xp_kvaddr
= kvaddr
;
256 bw_piomap
->hpio_holdcnt
++;
257 bw_piomap
->hpio_bigwin_num
= free_bw_index
;
259 if (flags
& PIOMAP_FIXED
)
260 bw_piomap
->hpio_flags
|= HUB_PIOMAP_IS_VALID
| HUB_PIOMAP_IS_FIXED
;
262 bw_piomap
->hpio_flags
|= HUB_PIOMAP_IS_VALID
;
265 spin_unlock(&hubinfo
->h_bwlock
);
270 * hub_piomap_free destroys a caddr_t-to-xtalk pio mapping and frees
271 * any associated mapping resources.
273 * If this * piomap was handled with a small window, or if it was handled
274 * in a big window that's still in use by someone else, then there's
275 * nothing to do. On the other hand, if this mapping was handled
276 * with a big window, AND if we were the final user of that mapping,
277 * then destroy the mapping.
280 hub_piomap_free(hub_piomap_t hub_piomap
)
287 * Small windows are permanently mapped to corresponding widgets,
288 * so there're no resources to free.
290 if (!(hub_piomap
->hpio_flags
& HUB_PIOMAP_IS_BIGWINDOW
))
293 ASSERT(hub_piomap
->hpio_flags
& HUB_PIOMAP_IS_VALID
);
294 ASSERT(hub_piomap
->hpio_holdcnt
> 0);
296 hubv
= hub_piomap
->hpio_hub
;
297 hubinfo_get(hubv
, &hubinfo
);
298 nasid
= hubinfo
->h_nasid
;
300 spin_lock(&hubinfo
->h_bwlock
);
303 * If this is the last hold on this mapping, free it.
305 if (--hub_piomap
->hpio_holdcnt
== 0) {
306 IIO_ITTE_DISABLE(nasid
, hub_piomap
->hpio_bigwin_num
);
308 if (hub_piomap
->hpio_flags
& HUB_PIOMAP_IS_FIXED
) {
309 hub_piomap
->hpio_flags
&= ~(HUB_PIOMAP_IS_VALID
| HUB_PIOMAP_IS_FIXED
);
310 hubinfo
->h_num_big_window_fixed
--;
311 ASSERT(hubinfo
->h_num_big_window_fixed
>= 0);
313 hub_piomap
->hpio_flags
&= ~HUB_PIOMAP_IS_VALID
;
315 wake_up(&hubinfo
->h_bwwait
);
318 spin_unlock(&hubinfo
->h_bwlock
);
322 * Establish a mapping to a given xtalk address range using the resources
326 hub_piomap_addr(hub_piomap_t hub_piomap
, /* mapping resources */
327 iopaddr_t xtalk_addr
, /* map for this xtalk address */
328 size_t byte_count
) /* map this many bytes */
330 /* Verify that range can be mapped using the specified piomap */
331 if (xtalk_addr
< hub_piomap
->hpio_xtalk_info
.xp_xtalk_addr
)
334 if (xtalk_addr
+ byte_count
>
335 ( hub_piomap
->hpio_xtalk_info
.xp_xtalk_addr
+
336 hub_piomap
->hpio_xtalk_info
.xp_mapsz
))
339 if (hub_piomap
->hpio_flags
& HUB_PIOMAP_IS_VALID
)
340 return hub_piomap
->hpio_xtalk_info
.xp_kvaddr
+
341 (xtalk_addr
% hub_piomap
->hpio_xtalk_info
.xp_mapsz
);
348 * Driver indicates that it's done with PIO's from an earlier piomap_addr.
352 hub_piomap_done(hub_piomap_t hub_piomap
) /* done with these mapping resources */
359 * For translations that require no mapping resources, supply a kernel virtual
360 * address that maps to the specified xtalk address range.
364 hub_piotrans_addr( vertex_hdl_t dev
, /* translate to this device */
365 device_desc_t dev_desc
, /* device descriptor */
366 iopaddr_t xtalk_addr
, /* Crosstalk address */
367 size_t byte_count
, /* map this many bytes */
368 unsigned flags
) /* (currently unused) */
370 xwidget_info_t widget_info
= xwidget_info_get(dev
);
371 xwidgetnum_t widget
= xwidget_info_id_get(widget_info
);
372 vertex_hdl_t hubv
= xwidget_info_master_get(widget_info
);
373 hub_piomap_t hub_piomap
;
377 hubinfo_get(hubv
, &hubinfo
);
379 if (xtalk_addr
+ byte_count
<= SWIN_SIZE
) {
380 hub_piomap
= hubinfo_swin_piomap_get(hubinfo
, (int)widget
);
381 addr
= hub_piomap_addr(hub_piomap
, xtalk_addr
, byte_count
);
382 #ifdef PIOMAP_UNC_ACC_SPACE
383 if (flags
& PIOMAP_UNC_ACC
) {
385 iaddr
= (uint64_t)addr
;
386 iaddr
|= PIOMAP_UNC_ACC_SPACE
;
387 addr
= (caddr_t
)iaddr
;
397 /* Mapping from crosstalk space to system physical space */
401 * Allocate resources needed to set up DMA mappings up to a specified size
402 * on a specified adapter.
404 * We don't actually use the adapter ID for anything. It's just the adapter
405 * that the lower level driver plans to use for DMA.
409 hub_dmamap_alloc( vertex_hdl_t dev
, /* set up mappings for this device */
410 device_desc_t dev_desc
, /* device descriptor */
411 size_t byte_count_max
, /* max size of a mapping */
412 unsigned flags
) /* defined in dma.h */
415 xwidget_info_t widget_info
= xwidget_info_get(dev
);
416 xwidgetnum_t widget
= xwidget_info_id_get(widget_info
);
417 vertex_hdl_t hubv
= xwidget_info_master_get(widget_info
);
419 dmamap
= kmalloc(sizeof(struct hub_dmamap_s
), GFP_ATOMIC
);
420 dmamap
->hdma_xtalk_info
.xd_dev
= dev
;
421 dmamap
->hdma_xtalk_info
.xd_target
= widget
;
422 dmamap
->hdma_hub
= hubv
;
423 dmamap
->hdma_flags
= HUB_DMAMAP_IS_VALID
;
424 if (flags
& XTALK_FIXED
)
425 dmamap
->hdma_flags
|= HUB_DMAMAP_IS_FIXED
;
431 * Destroy a DMA mapping from crosstalk space to system address space.
432 * There is no actual mapping hardware to destroy, but we at least mark
433 * the dmamap INVALID and free the space that it took.
436 hub_dmamap_free(hub_dmamap_t hub_dmamap
)
438 hub_dmamap
->hdma_flags
&= ~HUB_DMAMAP_IS_VALID
;
443 * Establish a DMA mapping using the resources allocated in a previous dmamap_alloc.
444 * Return an appropriate crosstalk address range that maps to the specified physical
449 hub_dmamap_addr( hub_dmamap_t dmamap
, /* use these mapping resources */
450 paddr_t paddr
, /* map for this address */
451 size_t byte_count
) /* map this many bytes */
455 ASSERT(dmamap
->hdma_flags
& HUB_DMAMAP_IS_VALID
);
457 if (dmamap
->hdma_flags
& HUB_DMAMAP_USED
) {
458 /* If the map is FIXED, re-use is OK. */
459 if (!(dmamap
->hdma_flags
& HUB_DMAMAP_IS_FIXED
)) {
460 char name
[MAXDEVNAME
];
461 vhdl
= dmamap
->hdma_xtalk_info
.xd_dev
;
462 printk(KERN_WARNING
"%s: hub_dmamap_addr re-uses dmamap.\n", vertex_to_name(vhdl
, name
, MAXDEVNAME
));
465 dmamap
->hdma_flags
|= HUB_DMAMAP_USED
;
468 /* There isn't actually any DMA mapping hardware on the hub. */
469 return (PHYS_TO_DMA(paddr
));
473 * Driver indicates that it has completed whatever DMA it may have started
474 * after an earlier dmamap_addr call.
477 hub_dmamap_done(hub_dmamap_t hub_dmamap
) /* done with these mapping resources */
481 if (hub_dmamap
->hdma_flags
& HUB_DMAMAP_USED
) {
482 hub_dmamap
->hdma_flags
&= ~HUB_DMAMAP_USED
;
484 /* If the map is FIXED, re-done is OK. */
485 if (!(hub_dmamap
->hdma_flags
& HUB_DMAMAP_IS_FIXED
)) {
486 char name
[MAXDEVNAME
];
487 vhdl
= hub_dmamap
->hdma_xtalk_info
.xd_dev
;
488 printk(KERN_WARNING
"%s: hub_dmamap_done already done with dmamap\n", vertex_to_name(vhdl
, name
, MAXDEVNAME
));
494 * Translate a single system physical address into a crosstalk address.
498 hub_dmatrans_addr( vertex_hdl_t dev
, /* translate for this device */
499 device_desc_t dev_desc
, /* device descriptor */
500 paddr_t paddr
, /* system physical address */
501 size_t byte_count
, /* length */
502 unsigned flags
) /* defined in dma.h */
504 return (PHYS_TO_DMA(paddr
));
509 hub_dmamap_drain( hub_dmamap_t map
)
511 /* XXX- flush caches, if cache coherency WAR is needed */
516 hub_dmaaddr_drain( vertex_hdl_t vhdl
,
520 /* XXX- flush caches, if cache coherency WAR is needed */
524 /* CONFIGURATION MANAGEMENT */
527 * Perform initializations that allow this hub to start crosstalk support.
530 hub_provider_startup(vertex_hdl_t hubv
)
534 hubinfo_get(hubv
, &hubinfo
);
536 intr_init_vecblk(nasid_to_cnodeid(hubinfo
->h_nasid
));
540 * Shutdown crosstalk support from a hub.
543 hub_provider_shutdown(vertex_hdl_t hub
)
546 xtalk_provider_unregister(hub
);
550 * Check that an address is in the real small window widget 0 space
551 * or else in the big window we're using to emulate small window 0
555 hub_check_is_widget0(void *addr
)
557 nasid_t nasid
= NASID_GET(addr
);
559 if (((unsigned long)addr
>= RAW_NODE_SWIN_BASE(nasid
, 0)) &&
560 ((unsigned long)addr
< RAW_NODE_SWIN_BASE(nasid
, 1)))
567 * Check that two addresses use the same widget
570 hub_check_window_equiv(void *addra
, void *addrb
)
572 if (hub_check_is_widget0(addra
) && hub_check_is_widget0(addrb
))
575 /* XXX - Assume this is really a small window address */
576 if (WIDGETID_GET((unsigned long)addra
) ==
577 WIDGETID_GET((unsigned long)addrb
))
585 * hub_setup_prb(nasid, prbnum, credits, conveyor)
587 * Put a PRB into fire-and-forget mode if conveyor isn't set. Otherwise,
588 * put it into conveyor belt mode with the specified number of credits.
591 hub_setup_prb(nasid_t nasid
, int prbnum
, int credits
, int conveyor
)
596 if (force_fire_and_forget
&& !ignore_conveyor_override
)
597 if (conveyor
== HUB_PIO_CONVEYOR
)
598 conveyor
= HUB_PIO_FIRE_N_FORGET
;
601 * Get the current register value.
603 prb_offset
= IIO_IOPRB(prbnum
);
604 prb
.iprb_regval
= REMOTE_HUB_L(nasid
, prb_offset
);
607 * Clear out some fields.
610 prb
.iprb_bnakctr
= 0;
611 prb
.iprb_anakctr
= 0;
614 * Enable or disable fire-and-forget mode.
616 prb
.iprb_ff
= ((conveyor
== HUB_PIO_CONVEYOR
) ? 0 : 1);
619 * Set the appropriate number of PIO cresits for the widget.
621 prb
.iprb_xtalkctr
= credits
;
624 * Store the new value to the register.
626 REMOTE_HUB_S(nasid
, prb_offset
, prb
.iprb_regval
);
632 * Put the hub into either "PIO conveyor belt" mode or "fire-and-forget"
633 * mode. To do this, we have to make absolutely sure that no PIOs
634 * are in progress so we turn off access to all widgets for the duration
637 * XXX - This code should really check what kind of widget we're talking
638 * to. Bridges can only handle three requests, but XG will do more.
639 * How many can crossbow handle to widget 0? We're assuming 1.
641 * XXX - There is a bug in the crossbow that link reset PIOs do not
642 * return write responses. The easiest solution to this problem is to
643 * leave widget 0 (xbow) in fire-and-forget mode at all times. This
644 * only affects pio's to xbow registers, which should be rare.
647 hub_set_piomode(nasid_t nasid
, int conveyor
)
654 ASSERT(nasid_to_cnodeid(nasid
) != INVALID_CNODEID
);
656 ii_iowa
= REMOTE_HUB_L(nasid
, IIO_OUTWIDGET_ACCESS
);
657 REMOTE_HUB_S(nasid
, IIO_OUTWIDGET_ACCESS
, 0);
659 ii_wcr
.wcr_reg_value
= REMOTE_HUB_L(nasid
, IIO_WCR
);
660 direct_connect
= ii_wcr
.iwcr_dir_con
;
662 if (direct_connect
) {
664 * Assume a bridge here.
666 hub_setup_prb(nasid
, 0, 3, conveyor
);
669 * Assume a crossbow here.
671 hub_setup_prb(nasid
, 0, 1, conveyor
);
674 for (prbnum
= HUB_WIDGET_ID_MIN
; prbnum
<= HUB_WIDGET_ID_MAX
; prbnum
++) {
676 * XXX - Here's where we should take the widget type into
677 * when account assigning credits.
679 /* Always set the PRBs in fire-and-forget mode */
680 hub_setup_prb(nasid
, prbnum
, 3, conveyor
);
683 REMOTE_HUB_S(nasid
, IIO_OUTWIDGET_ACCESS
, ii_iowa
);
685 /* Interface to allow special drivers to set hub specific
687 * Return 0 on failure , 1 on success
690 hub_widget_flags_set(nasid_t nasid
,
691 xwidgetnum_t widget_num
,
692 hub_widget_flags_t flags
)
695 ASSERT((flags
& HUB_WIDGET_FLAGS
) == flags
);
697 if (flags
& HUB_PIO_CONVEYOR
) {
698 hub_setup_prb(nasid
,widget_num
,
699 3,HUB_PIO_CONVEYOR
); /* set the PRB in conveyor
700 * belt mode with 3 credits
702 } else if (flags
& HUB_PIO_FIRE_N_FORGET
) {
703 hub_setup_prb(nasid
,widget_num
,
704 3,HUB_PIO_FIRE_N_FORGET
); /* set the PRB in fire
713 * A pointer to this structure hangs off of every hub hwgraph vertex.
714 * The generic xtalk layer may indirect through it to get to this specific
715 * crosstalk bus provider.
717 xtalk_provider_t hub_provider
= {
718 .piomap_alloc
= (xtalk_piomap_alloc_f
*) hub_piomap_alloc
,
719 .piomap_free
= (xtalk_piomap_free_f
*) hub_piomap_free
,
720 .piomap_addr
= (xtalk_piomap_addr_f
*) hub_piomap_addr
,
721 .piomap_done
= (xtalk_piomap_done_f
*) hub_piomap_done
,
722 .piotrans_addr
= (xtalk_piotrans_addr_f
*) hub_piotrans_addr
,
724 .dmamap_alloc
= (xtalk_dmamap_alloc_f
*) hub_dmamap_alloc
,
725 .dmamap_free
= (xtalk_dmamap_free_f
*) hub_dmamap_free
,
726 .dmamap_addr
= (xtalk_dmamap_addr_f
*) hub_dmamap_addr
,
727 .dmamap_done
= (xtalk_dmamap_done_f
*) hub_dmamap_done
,
728 .dmatrans_addr
= (xtalk_dmatrans_addr_f
*) hub_dmatrans_addr
,
729 .dmamap_drain
= (xtalk_dmamap_drain_f
*) hub_dmamap_drain
,
730 .dmaaddr_drain
= (xtalk_dmaaddr_drain_f
*) hub_dmaaddr_drain
,
732 .intr_alloc
= (xtalk_intr_alloc_f
*) hub_intr_alloc
,
733 .intr_alloc_nothd
= (xtalk_intr_alloc_f
*) hub_intr_alloc_nothd
,
734 .intr_free
= (xtalk_intr_free_f
*) hub_intr_free
,
735 .intr_connect
= (xtalk_intr_connect_f
*) hub_intr_connect
,
736 .intr_disconnect
= (xtalk_intr_disconnect_f
*) hub_intr_disconnect
,
737 .provider_startup
= (xtalk_provider_startup_f
*) hub_provider_startup
,
738 .provider_shutdown
= (xtalk_provider_shutdown_f
*) hub_provider_shutdown
,