/* * hub_pio_init - PIO-related hub initialization * * @hub: hubinfo structure for our hub */ void hub_pio_init(cnodeid_t cnode) { nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode); unsigned i; /* initialize big window piomaps for this hub */ bitmap_zero(hub_data(cnode)->h_bigwin_used, HUB_NUM_BIG_WINDOW); for (i = 0; i < HUB_NUM_BIG_WINDOW; i++) IIO_ITTE_DISABLE(nasid, i); hub_set_piomode(nasid); }
/* * Setup pio structures needed for a particular hub. */ static void hub_pio_init(devfs_handle_t hubv) { xwidgetnum_t widget; hubinfo_t hubinfo; nasid_t nasid; int bigwin; hub_piomap_t hub_piomap; hubinfo_get(hubv, &hubinfo); nasid = hubinfo->h_nasid; /* Initialize small window piomaps for this hub */ for (widget=0; widget <= HUB_WIDGET_ID_MAX; widget++) { hub_piomap = hubinfo_swin_piomap_get(hubinfo, (int)widget); hub_piomap->hpio_xtalk_info.xp_target = widget; hub_piomap->hpio_xtalk_info.xp_xtalk_addr = 0; hub_piomap->hpio_xtalk_info.xp_mapsz = SWIN_SIZE; hub_piomap->hpio_xtalk_info.xp_kvaddr = (caddr_t)NODE_SWIN_BASE(nasid, widget); hub_piomap->hpio_hub = hubv; hub_piomap->hpio_flags = HUB_PIOMAP_IS_VALID; } /* Initialize big window piomaps for this hub */ for (bigwin=0; bigwin < HUB_NUM_BIG_WINDOW; bigwin++) { hub_piomap = hubinfo_bwin_piomap_get(hubinfo, bigwin); hub_piomap->hpio_xtalk_info.xp_mapsz = BWIN_SIZE; hub_piomap->hpio_hub = hubv; hub_piomap->hpio_holdcnt = 0; hub_piomap->hpio_flags = HUB_PIOMAP_IS_BIGWINDOW; IIO_ITTE_DISABLE(nasid, bigwin); } #ifdef BRINGUP hub_set_piomode(nasid, HUB_PIO_CONVEYOR); #else /* Set all the xwidgets in fire-and-forget mode * by default */ hub_set_piomode(nasid, HUB_PIO_FIRE_N_FORGET); #endif /* BRINGUP */ sv_init(&hubinfo->h_bwwait, SV_FIFO, "bigwin"); spinlock_init(&hubinfo->h_bwlock, "bigwin"); }
/* * hub_piomap_free destroys a caddr_t-to-xtalk pio mapping and frees * any associated mapping resources. * * If this * piomap was handled with a small window, or if it was handled * in a big window that's still in use by someone else, then there's * nothing to do. On the other hand, if this mapping was handled * with a big window, AND if we were the final user of that mapping, * then destroy the mapping. */ void hub_piomap_free(hub_piomap_t hub_piomap) { devfs_handle_t hubv; hubinfo_t hubinfo; nasid_t nasid; int s; /* * Small windows are permanently mapped to corresponding widgets, * so there're no resources to free. */ if (!(hub_piomap->hpio_flags & HUB_PIOMAP_IS_BIGWINDOW)) return; ASSERT(hub_piomap->hpio_flags & HUB_PIOMAP_IS_VALID); ASSERT(hub_piomap->hpio_holdcnt > 0); hubv = hub_piomap->hpio_hub; hubinfo_get(hubv, &hubinfo); nasid = hubinfo->h_nasid; s = mutex_spinlock(&hubinfo->h_bwlock); /* * If this is the last hold on this mapping, free it. */ if (--hub_piomap->hpio_holdcnt == 0) { IIO_ITTE_DISABLE(nasid, hub_piomap->hpio_bigwin_num ); if (hub_piomap->hpio_flags & HUB_PIOMAP_IS_FIXED) { hub_piomap->hpio_flags &= ~(HUB_PIOMAP_IS_VALID | HUB_PIOMAP_IS_FIXED); hubinfo->h_num_big_window_fixed--; ASSERT(hubinfo->h_num_big_window_fixed >= 0); } else hub_piomap->hpio_flags &= ~HUB_PIOMAP_IS_VALID; (void)sv_signal(&hubinfo->h_bwwait); } mutex_spinunlock(&hubinfo->h_bwlock, s); }