initial commit with v2.6.9
[linux-2.6.9-moxart.git] / arch / ia64 / sn / io / io.c
blobcfc38abd5818e928c354e15958c4eb4499ebd3e8
1 /*
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
4 * for more details.
6 * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
7 */
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;
34 /*
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.
45 /* PIO MANAGEMENT */
46 /* For mapping system virtual address space to xtalk space on a specified widget */
49 * Setup pio structures needed for a particular hub.
51 static void
52 hub_pio_init(vertex_hdl_t hubv)
54 xwidgetnum_t widget;
55 hubinfo_t hubinfo;
56 nasid_t nasid;
57 int bigwin;
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);
89 /*
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.
101 /* ARGSUSED */
102 hub_piomap_t
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 */
106 size_t byte_count,
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);
113 hubinfo_t hubinfo;
114 hub_piomap_t bw_piomap;
115 int bigwin, free_bw_index;
116 nasid_t nasid;
117 volatile hubreg_t junk;
118 caddr_t kvaddr;
119 #ifdef PIOMAP_UNC_ACC_SPACE
120 uint64_t addr;
121 #endif
123 /* sanity check */
124 if (byte_count_max > byte_count)
125 return NULL;
127 hubinfo_get(hubv, &hubinfo);
129 /* If xtalk_addr range is mapped by a small window, we don't have
130 * to do much
132 if (xtalk_addr + byte_count <= SWIN_SIZE) {
133 hub_piomap_t piomap;
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;
142 #endif
143 return piomap;
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)
154 return NULL;
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.
163 tryagain:
164 free_bw_index = -1;
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;
172 continue;
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))
180 continue;
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);
186 return bw_piomap;
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++;
200 } else {
201 bw_piomap = NULL;
202 goto done;
204 } else /* PIOMAP_UNFIXED */ {
205 if (free_bw_index < 0) {
206 if (flags & PIOMAP_NOSLEEP) {
207 bw_piomap = NULL;
208 goto done;
209 } else {
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);
215 schedule();
216 remove_wait_queue(&hubinfo->h_bwwait, &wait);
217 goto tryagain;
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
229 * prematurely.
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
236 * we write it.
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;
254 #endif
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;
261 else
262 bw_piomap->hpio_flags |= HUB_PIOMAP_IS_VALID;
264 done:
265 spin_unlock(&hubinfo->h_bwlock);
266 return bw_piomap;
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.
279 void
280 hub_piomap_free(hub_piomap_t hub_piomap)
282 vertex_hdl_t hubv;
283 hubinfo_t hubinfo;
284 nasid_t nasid;
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))
291 return;
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);
312 } else
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
323 * allocated earlier.
325 caddr_t
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)
332 return 0;
334 if (xtalk_addr + byte_count >
335 ( hub_piomap->hpio_xtalk_info.xp_xtalk_addr +
336 hub_piomap->hpio_xtalk_info.xp_mapsz))
337 return 0;
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);
342 else
343 return 0;
348 * Driver indicates that it's done with PIO's from an earlier piomap_addr.
350 /* ARGSUSED */
351 void
352 hub_piomap_done(hub_piomap_t hub_piomap) /* done with these mapping resources */
354 /* Nothing to do */
359 * For translations that require no mapping resources, supply a kernel virtual
360 * address that maps to the specified xtalk address range.
362 /* ARGSUSED */
363 caddr_t
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;
374 hubinfo_t hubinfo;
375 caddr_t addr;
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) {
384 uint64_t iaddr;
385 iaddr = (uint64_t)addr;
386 iaddr |= PIOMAP_UNC_ACC_SPACE;
387 addr = (caddr_t)iaddr;
389 #endif
390 return addr;
391 } else
392 return 0;
396 /* DMA MANAGEMENT */
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.
407 /* ARGSUSED */
408 hub_dmamap_t
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 */
414 hub_dmamap_t dmamap;
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;
427 return dmamap;
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.
435 void
436 hub_dmamap_free(hub_dmamap_t hub_dmamap)
438 hub_dmamap->hdma_flags &= ~HUB_DMAMAP_IS_VALID;
439 kfree(hub_dmamap);
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
445 * address range.
447 /* ARGSUSED */
448 extern iopaddr_t
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 */
453 vertex_hdl_t vhdl;
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));
464 } else {
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.
476 void
477 hub_dmamap_done(hub_dmamap_t hub_dmamap) /* done with these mapping resources */
479 vertex_hdl_t vhdl;
481 if (hub_dmamap->hdma_flags & HUB_DMAMAP_USED) {
482 hub_dmamap->hdma_flags &= ~HUB_DMAMAP_USED;
483 } else {
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.
496 /* ARGSUSED */
497 iopaddr_t
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));
507 /*ARGSUSED*/
508 void
509 hub_dmamap_drain( hub_dmamap_t map)
511 /* XXX- flush caches, if cache coherency WAR is needed */
514 /*ARGSUSED*/
515 void
516 hub_dmaaddr_drain( vertex_hdl_t vhdl,
517 paddr_t addr,
518 size_t bytes)
520 /* XXX- flush caches, if cache coherency WAR is needed */
524 /* CONFIGURATION MANAGEMENT */
527 * Perform initializations that allow this hub to start crosstalk support.
529 void
530 hub_provider_startup(vertex_hdl_t hubv)
532 hubinfo_t hubinfo;
534 hubinfo_get(hubv, &hubinfo);
535 hub_pio_init(hubv);
536 intr_init_vecblk(nasid_to_cnodeid(hubinfo->h_nasid));
540 * Shutdown crosstalk support from a hub.
542 void
543 hub_provider_shutdown(vertex_hdl_t hub)
545 /* TBD */
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
552 * in the kernel.
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)))
561 return 1;
562 return 0;
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))
573 return 1;
575 /* XXX - Assume this is really a small window address */
576 if (WIDGETID_GET((unsigned long)addra) ==
577 WIDGETID_GET((unsigned long)addrb))
578 return 1;
580 return 0;
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.
590 void
591 hub_setup_prb(nasid_t nasid, int prbnum, int credits, int conveyor)
593 iprb_t prb;
594 int prb_offset;
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.
609 prb.iprb_ovflow = 1;
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);
630 * hub_set_piomode()
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
635 * of the function.
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.
646 void
647 hub_set_piomode(nasid_t nasid, int conveyor)
649 hubreg_t ii_iowa;
650 int direct_connect;
651 hubii_wcr_t ii_wcr;
652 int prbnum;
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);
667 } else {
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
686 * device flags.
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
705 * and forget mode
709 return 1;
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,