int me8254_io_reset_subdevice(struct me_subdevice* subdevice, struct file* filep, int flags) { me8254_subdevice_t* instance; uint8_t clk_src; instance = (me8254_subdevice_t *) subdevice; PDEBUG("executed.\n"); if (flags) { PERROR("Invalid flags specified. Must be ME_IO_RESET_SUBDEVICE_NO_FLAGS.\n"); return ME_ERRNO_INVALID_FLAGS; } ME_SUBDEVICE_ENTER; ME_SUBDEVICE_LOCK; ME_SPIN_LOCK(instance->ctrl_reg_lock); if (instance->ctr_idx == 0) me_writeb(instance->base.dev, ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M0 | ME8254_CTRL_BIN, instance->ctrl_reg); else if (instance->ctr_idx == 1) me_writeb(instance->base.dev, ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M0 | ME8254_CTRL_BIN, instance->ctrl_reg); else me_writeb(instance->base.dev, ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M0 | ME8254_CTRL_BIN, instance->ctrl_reg); ME_SPIN_UNLOCK(instance->ctrl_reg_lock); me_writeb(instance->base.dev, 0x00, instance->val_reg); me_writeb(instance->base.dev, 0x00, instance->val_reg); ME_SPIN_LOCK(instance->clk_src_reg_lock); /** @todo Instead of ID features flags should be used. */ switch (instance->device_id) { case PCI_DEVICE_ID_MEILHAUS_ME1400: case PCI_DEVICE_ID_MEILHAUS_ME140A: case PCI_DEVICE_ID_MEILHAUS_ME140B: case PCI_DEVICE_ID_MEILHAUS_ME14E0: case PCI_DEVICE_ID_MEILHAUS_ME14EA: case PCI_DEVICE_ID_MEILHAUS_ME14EB: me_readb(instance->base.dev, &clk_src, instance->clk_src_reg); if (instance->me8254_idx == 0) { if (instance->ctr_idx == 0) clk_src &= ~(ME1400AB_8254_A_0_CLK_SRC_10MHZ | ME1400AB_8254_A_0_CLK_SRC_QUARZ); else if (instance->ctr_idx == 1) clk_src &= ~(ME1400AB_8254_A_1_CLK_SRC_PREV); else clk_src &= ~(ME1400AB_8254_A_2_CLK_SRC_PREV); } else { if (instance->ctr_idx == 0) clk_src &= ~(ME1400AB_8254_B_0_CLK_SRC_10MHZ | ME1400AB_8254_B_0_CLK_SRC_QUARZ); else if (instance->ctr_idx == 1) clk_src &= ~(ME1400AB_8254_B_1_CLK_SRC_PREV); else clk_src &= ~(ME1400AB_8254_B_2_CLK_SRC_PREV); } me_writeb(instance->base.dev, clk_src, instance->clk_src_reg); break; case PCI_DEVICE_ID_MEILHAUS_ME140C: case PCI_DEVICE_ID_MEILHAUS_ME140D: me_readb(instance->base.dev, &clk_src, instance->clk_src_reg); switch (instance->me8254_idx) { case 0: case 2: case 4: case 6: case 8: if (instance->ctr_idx == 0) clk_src &= ~(ME1400CD_8254_ACE_0_CLK_SRC_MASK); else if (instance->ctr_idx == 1) clk_src &= ~(ME1400CD_8254_ACE_1_CLK_SRC_MASK); else clk_src &= ~(ME1400CD_8254_ACE_2_CLK_SRC_MASK); break; default: if (instance->ctr_idx == 0) clk_src &= ~(ME1400CD_8254_BD_0_CLK_SRC_MASK); else if (instance->ctr_idx == 1) clk_src &= ~(ME1400CD_8254_BD_1_CLK_SRC_MASK); else clk_src &= ~(ME1400CD_8254_BD_2_CLK_SRC_MASK); break; } me_writeb(instance->base.dev, clk_src, instance->clk_src_reg); break; default: // No clock source register available. break; } ME_SPIN_UNLOCK(instance->clk_src_reg_lock); ME_SUBDEVICE_UNLOCK; ME_SUBDEVICE_EXIT; return ME_ERRNO_SUCCESS; }
int32_t _m_get_media_info(rmedia_handle_t *handle, void *ip) { smmedium_prop_t *medinfo = ip; struct dk_minfo media_info; struct dk_geom dkgeom; int32_t ret_val; enum dkio_state state = DKIO_NONE; if (handle == NULL) { DPRINTF("Null Handle\n"); errno = EINVAL; return (-1); } if (handle->sm_signature != (int32_t)LIBSMEDIA_SIGNATURE) { DPRINTF2( "Signature expected=0x%x, found=0x%x\n", LIBSMEDIA_SIGNATURE, handle->sm_signature); errno = EINVAL; return (-1); } if (handle->sm_fd < 0) { DPRINTF("Invalid file handle.\n"); errno = EINVAL; return (-1); } if (ioctl(handle->sm_fd, DKIOCSTATE, &state) < 0) { PERROR("DKIOCSTATE failed"); return (-1); } if (state != DKIO_INSERTED) { DPRINTF("No media.\n"); medinfo->sm_media_type = SM_NOT_PRESENT; medinfo->sm_version = SMMEDIA_PROP_V_1; return (0); } (void) memset((void *) medinfo, 0, sizeof (smmedium_prop_t)); ret_val = ioctl(handle->sm_fd, DKIOCGMEDIAINFO, &media_info); if (ret_val < 0) { DPRINTF("DKIOCGMEDIAINFO ioctl failed"); return (ret_val); } medinfo->sm_media_type = media_info.dki_media_type; medinfo->sm_blocksize = media_info.dki_lbsize; medinfo->sm_capacity = media_info.dki_capacity; /* Is it a removable magnetic disk? */ if (medinfo->sm_media_type == DK_FIXED_DISK) { int32_t removable = 0; ret_val = ioctl(handle->sm_fd, DKIOCREMOVABLE, &removable); if (ret_val < 0) { DPRINTF("DKIOCREMOVABLE ioctl failed"); return (ret_val); } if (removable) { medinfo->sm_media_type = SM_PCMCIA_ATA; } } ret_val = ioctl(handle->sm_fd, DKIOCGGEOM, &dkgeom); if (ret_val < 0) { #ifdef sparc DPRINTF("DKIOCGGEOM ioctl failed"); return (ret_val); #else /* !sparc */ /* * Try getting Physical geometry on x86. */ ret_val = ioctl(handle->sm_fd, DKIOCG_PHYGEOM, &dkgeom); if (ret_val < 0) { DPRINTF("DKIOCG_PHYGEOM ioctl failed"); return (ret_val); } #endif /* sparc */ } medinfo->sm_pcyl = dkgeom.dkg_pcyl; medinfo->sm_nhead = dkgeom.dkg_nhead; medinfo->sm_nsect = dkgeom.dkg_nsect; return (0); }
UInteger32 findIface(Octet * ifaceName, UInteger8 * communicationTechnology, Octet * uuid, NetPath * netPath) { #if defined(linux) /* depends on linux specific ioctls (see 'netdevice' man page) */ int i, flags; struct ifconf data; struct ifreq device[IFCONF_LENGTH]; data.ifc_len = sizeof(device); data.ifc_req = device; memset(data.ifc_buf, 0, data.ifc_len); flags = IFF_UP | IFF_RUNNING | IFF_MULTICAST; /* look for an interface if none specified */ if (ifaceName[0] != '\0') { i = 0; memcpy(device[i].ifr_name, ifaceName, IFACE_NAME_LENGTH); if (ioctl(netPath->eventSock, SIOCGIFHWADDR, &device[i]) < 0) DBGV("failed to get hardware address\n"); else if ((*communicationTechnology = lookupCommunicationTechnology(device[i].ifr_hwaddr.sa_family)) == PTP_DEFAULT) DBGV("unsupported communication technology (%d)\n", *communicationTechnology); else memcpy(uuid, device[i].ifr_hwaddr.sa_data, PTP_UUID_LENGTH); } else { /* no iface specified */ /* get list of network interfaces */ if (ioctl(netPath->eventSock, SIOCGIFCONF, &data) < 0) { PERROR("failed query network interfaces"); return 0; } if (data.ifc_len >= sizeof(device)) DBG("device list may exceed allocated space\n"); /* search through interfaces */ for (i = 0; i < data.ifc_len / sizeof(device[0]); ++i) { DBGV("%d %s %s\n", i, device[i].ifr_name, inet_ntoa(((struct sockaddr_in *)&device[i].ifr_addr)->sin_addr)); if (ioctl(netPath->eventSock, SIOCGIFFLAGS, &device[i]) < 0) DBGV("failed to get device flags\n"); else if ((device[i].ifr_flags & flags) != flags) DBGV("does not meet requirements (%08x, %08x)\n", device[i].ifr_flags, flags); else if (ioctl(netPath->eventSock, SIOCGIFHWADDR, &device[i]) < 0) DBGV("failed to get hardware address\n"); else if ((*communicationTechnology = lookupCommunicationTechnology(device[i].ifr_hwaddr.sa_family)) == PTP_DEFAULT) DBGV("unsupported communication technology (%d)\n", *communicationTechnology); else { DBGV("found interface (%s)\n", device[i].ifr_name); memcpy(uuid, device[i].ifr_hwaddr.sa_data, PTP_UUID_LENGTH); memcpy(ifaceName, device[i].ifr_name, IFACE_NAME_LENGTH); break; } } } if (ifaceName[0] == '\0') { ERROR("failed to find a usable interface\n"); return 0; } if (ioctl(netPath->eventSock, SIOCGIFADDR, &device[i]) < 0) { PERROR("failed to get ip address"); return 0; } return ((struct sockaddr_in *)&device[i].ifr_addr)->sin_addr.s_addr; #elif defined(BSD_INTERFACE_FUNCTIONS) struct ifaddrs *if_list, *ifv4, *ifh; if (getifaddrs(&if_list) < 0) { PERROR("getifaddrs() failed"); return FALSE; } /* find an IPv4, multicast, UP interface, right name(if supplied) */ for (ifv4 = if_list; ifv4 != NULL; ifv4 = ifv4->ifa_next) { if ((ifv4->ifa_flags & IFF_UP) == 0) continue; if ((ifv4->ifa_flags & IFF_RUNNING) == 0) continue; if ((ifv4->ifa_flags & IFF_LOOPBACK)) continue; if ((ifv4->ifa_flags & IFF_MULTICAST) == 0) continue; if (ifv4->ifa_addr->sa_family != AF_INET) /* must have IPv4 * address */ continue; if (ifaceName[0] && strncmp(ifv4->ifa_name, ifaceName, IF_NAMESIZE) != 0) continue; break; } if (ifv4 == NULL) { if (ifaceName[0]) { ERROR("interface \"%s\" does not exist, or is not appropriate\n", ifaceName); return FALSE; } ERROR("no suitable interfaces found!"); return FALSE; } /* find the AF_LINK info associated with the chosen interface */ for (ifh = if_list; ifh != NULL; ifh = ifh->ifa_next) { if (ifh->ifa_addr->sa_family != AF_LINK) continue; if (strncmp(ifv4->ifa_name, ifh->ifa_name, IF_NAMESIZE) == 0) break; } if (ifh == NULL) { ERROR("could not get hardware address for interface \"%s\"\n", ifv4->ifa_name); return FALSE; } /* check that the interface TYPE is OK */ if (((struct sockaddr_dl *)ifh->ifa_addr)->sdl_type != IFT_ETHER) { ERROR("\"%s\" is not an ethernet interface!\n", ifh->ifa_name); return FALSE; } DBG("==> %s %s %s\n", ifv4->ifa_name, inet_ntoa(((struct sockaddr_in *)ifv4->ifa_addr)->sin_addr), ether_ntoa((struct ether_addr *) LLADDR((struct sockaddr_dl *)ifh->ifa_addr))); *communicationTechnology = PTP_ETHER; memcpy(ifaceName, ifh->ifa_name, IFACE_NAME_LENGTH); memcpy(uuid, LLADDR((struct sockaddr_dl *)ifh->ifa_addr), PTP_UUID_LENGTH); return ((struct sockaddr_in *)ifv4->ifa_addr)->sin_addr.s_addr; #endif }
int video_init(int window_w, int window_h, int fullscreen, int vsync, const char* scaler_name, int scale_factor) { state.w = window_w; state.h = window_h; state.fs = fullscreen; state.vsync = vsync; state.fade = 1.0f; state.target = NULL; state.target_move_x = 0; state.target_move_y = 0; // Load scaler (if any) memset(state.scaler_name, 0, sizeof(state.scaler_name)); strncpy(state.scaler_name, scaler_name, sizeof(state.scaler_name)-1); if(video_load_scaler(scaler_name, scale_factor)) { DEBUG("Scaler \"%s\" plugin not found; using Nearest neighbour scaling.", scaler_name); state.scale_factor = 1; } else { DEBUG("Scaler \"%s\" loaded w/ factor %d", scaler_name, scale_factor); state.scale_factor = scale_factor; } // Clear palettes state.cur_palette = malloc(sizeof(screen_palette)); state.base_palette = malloc(sizeof(palette)); memset(state.cur_palette, 0, sizeof(screen_palette)); state.cur_palette->version = 1; // Form title string char title[32]; sprintf(title, "OpenOMF v%d.%d.%d", V_MAJOR, V_MINOR, V_PATCH); // Open window state.window = SDL_CreateWindow( title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, window_w, window_h, SDL_WINDOW_SHOWN); if(state.window == NULL) { PERROR("Could not create window: %s", SDL_GetError()); return 1; } // Set fullscreen if needed if(state.fs) { if(SDL_SetWindowFullscreen(state.window, SDL_WINDOW_FULLSCREEN) != 0) { PERROR("Could not set fullscreen mode!"); } else { DEBUG("Fullscreen enabled!"); } } else { SDL_SetWindowFullscreen(state.window, 0); } // Form flags int renderer_flags = SDL_RENDERER_ACCELERATED; if(state.vsync) { renderer_flags |= SDL_RENDERER_PRESENTVSYNC; } // Create renderer state.renderer = SDL_CreateRenderer( state.window, -1, renderer_flags); if(state.renderer == NULL) { PERROR("Could not create renderer: %s", SDL_GetError()); return 1; } // Default resolution for renderer. This will them get scaled up to screen size. SDL_RenderSetLogicalSize(state.renderer, NATIVE_W * state.scale_factor, NATIVE_H * state.scale_factor); // Disable screensaver :/ SDL_DisableScreenSaver(); // Set rendertargets reset_targets(); // Init texture cache tcache_init(state.renderer, state.scale_factor, &state.scaler); // Init hardware renderer state.cur_renderer = VIDEO_RENDERER_HW; video_hw_init(&state); // Get renderer data SDL_RendererInfo rinfo; SDL_GetRendererInfo(state.renderer, &rinfo); // Show some info INFO("Video Init OK"); INFO(" * Driver: %s", SDL_GetCurrentVideoDriver()); INFO(" * Renderer: %s", rinfo.name); INFO(" * Accelerated: %s", (rinfo.flags & SDL_RENDERER_ACCELERATED) ? "Yes" : "No"); INFO(" * VSync support: %s", (rinfo.flags & SDL_RENDERER_PRESENTVSYNC) ? "Yes" : "No"); INFO(" * Target support: %s", (rinfo.flags & SDL_RENDERER_TARGETTEXTURE) ? "Yes" : "No"); return 0; }
static void drct_rmw_write_complete_handler(spd_dev_t *dev) { int retval = 0; unsigned long flags = 0; u32 sector; int wsize; PTRACE(); PINFO("<spd%c>complete time=%dms errcode=%d", dev->id+'a', jiffies_to_msecs(dev->ticks), dev->errcode); if(dev->cache){ spd_cache_clr_dirty(dev->cache); } if(unlikely(dev->errcode < 0)){ retval = dev->errcode; goto ABORT; } if(dev->bdev->rmw_count == 0){ spin_lock_irqsave(&dev->bdev->rq_lock, flags); bdev_end_request(dev, 0); spin_unlock_irqrestore(&dev->bdev->rq_lock, flags); dev->complete_handler = NULL; spd_io_unlock(dev); return; } sector = dev->bdev->rmw_sector; wsize = spd_get_wsize(dev, sector); if(unlikely(wsize < 0)){ PERROR("<spd%c>spd_get_wsize() failed sector=%08x", dev->id+'a', sector); retval = -EINVAL; goto ABORT; } sector = align_sector(sector, wsize, spd_get_sector_offset(dev, sector)); if(sector == dev->bdev->rmw_sector && dev->bdev->rmw_count >= wsize){ dev->cache->sector = sector; dev->cache->n_sector = wsize; retval = drct_make_rmw_sg(dev); if(unlikely(retval < 0)){ PERROR("<spd%c>drct_make_rmw_sg() failed(%d)", dev->id+'a', retval); goto ABORT; } dev->complete_handler = drct_rmw_write_complete_handler; retval = spd_write_sector(dev, sector, wsize, dev->sg); if(unlikely(retval < 0)){ PERROR("<spd%c>spd_write_sector() failed(%d)", dev->id+'a', retval); goto ABORT; } dev->cache->sector = (u32)-1; spd_cache_clr_dirty(dev->cache); return; } dev->cache->sector = sector; dev->cache->n_sector = wsize; dev->complete_handler = drct_rmw_read_complete_handler; spd_cache_prepare(dev, SPD_DIR_READ); retval = spd_read_sector(dev, dev->cache->sector, dev->cache->n_sector, dev->cache->sg); if(unlikely(retval < 0)){ PERROR("<spd%c>spd_read_sector() failed(%d)", dev->id+'a', retval); goto ABORT; } return; ABORT: PINFO("<spd%c>ABORT at %s", dev->id+'a', __FUNCTION__); if(dev->cache){ dev->cache->sector = (u32)-1; spd_cache_clr_dirty(dev->cache); } spin_lock_irqsave(&dev->bdev->rq_lock, flags); bdev_end_request(dev, retval); spin_unlock_irqrestore(&dev->bdev->rq_lock, flags); dev->complete_handler = NULL; spd_io_unlock(dev); }
/*************************************************************************** * zion_dmaif_port_ioctl **************************************************************************/ int zion_dmaif_port_ioctl(zion_params_t * params, struct inode *inode, struct file *file, unsigned int function, unsigned long arg) { switch (function) { case ZION_EDMA_IOC_OPEN: { unsigned char ucReg = 0; zion_edma_params_t *edma_prms = (zion_edma_params_t *)file->private_data; int ch = -1; int rw = -1; unsigned long irq_flags = 0; /* Check EDMA parameters */ if (NULL == edma_prms) { PERROR("Private data is NULL!\n"); return (-ENODEV); } /* Get and check EDMA channel number */ ch = edma_prms->ch_no; if (ch < 0 || ZION_EDMA_NR_CH <= ch) { PERROR("Invalid ZION EDMA channel number(%d)!", ch); return (-ENODEV); } /* Get argument: I/O direction */ if (copy_from_user((void *)&rw, (void *)arg, sizeof(int))) return (-EFAULT); /* Check argument: I/O direction */ if ((ZION_EDMA_READ != rw) && (ZION_EDMA_WRITE != rw)) { PERROR("[CH%d] Invalid I/O direction(%d)!\n", ch, rw); return (-EINVAL); } /* Read EDMA command register */ ucReg = mbus_readb(MBUS_ADDR(params, ZION_MBUS_EDMA_DMACMD(ch) + 1)); /* Write EDMA command register: DmaOpen=1 */ ucReg |= (ZION_MBUS_EDMA_OPEN | (rw << 2)) & 0x0F; /* PDEBUG("[CH%d] EDMA open(0x%02X)\n", ch, ucReg); */ mbus_writeb(ucReg, MBUS_ADDR(params, ZION_MBUS_EDMA_DMACMD(ch) + 1)); /* Clear interrupt status */ spin_lock_irqsave( &(edma_prms->params_lock), irq_flags ); edma_prms->int_status = 0x0000; spin_unlock_irqrestore( &(edma_prms->params_lock), irq_flags ); break; } case ZION_EDMA_IOC_CLOSE: { unsigned char ucReg = 0; zion_edma_params_t *edma_prms = (zion_edma_params_t *)file->private_data; int ch = -1; /* Check EDMA parameters */ if (NULL == edma_prms) { PERROR("Private data is NULL!\n"); return (-ENODEV); } /* Get and check EDMA channel number */ ch = edma_prms->ch_no; if (ch < 0 || ZION_EDMA_NR_CH <= ch) { PERROR("Invalid ZION EDMA channel number(%d)!", ch); return (-ENODEV); } /* Read EDMA command register */ ucReg = mbus_readb( MBUS_ADDR(params, (ZION_MBUS_EDMA_DMACMD(ch)+1)) ); /* Write EDMA command register: DmaOpen=0 */ ucReg &= ZION_MBUS_EDMA_CLOSE & 0x0F; /* PDEBUG("[CH%d] EDMA close(0x%02X)\n", ch, ucReg); */ mbus_writeb( ucReg, MBUS_ADDR(params, (ZION_MBUS_EDMA_DMACMD(ch)+1)) ); /* Success */ break; } case ZION_EDMA_IOC_RUN: { unsigned char ucReg = 0; zion_edma_params_t *edma_prms = (zion_edma_params_t *)file->private_data; int ch = -1; unsigned short usCmdReg = 0; /* Check EDMA parameters */ if (NULL == edma_prms) { PERROR("Private data is NULL!\n"); return (-ENODEV); } /* Get and check EDMA channel number */ ch = edma_prms->ch_no; if (ch < 0 || ZION_EDMA_NR_CH <= ch) { PERROR("Invalid ZION EDMA channel number(%d)!", ch); return (-ENODEV); } /* Read EDMA command register */ ucReg = mbus_readb(MBUS_ADDR(params, ZION_MBUS_EDMA_DMACMD(ch) + 1)); /* Write EDMA command register: DmaRun=1 */ ucReg |= ZION_MBUS_EDMA_RUN; PDEBUG ("[CH%d] EDMA run(0x%02X)\n", ch, ucReg); mbus_writeb(ucReg, MBUS_ADDR(params, ZION_MBUS_EDMA_DMACMD(ch) + 1)); #ifdef NEO_WRITEBACK /* for DEBUG -- write back XXX */ usCmdReg = (unsigned short)mbus_readw( MBUS_ADDR(params, ZION_MBUS_EDMA_DMACMD(edma_prms->ch_no)) ); /* PDEBUG( "[CH%d] Write back DMA RUN: 0x%04X\n", */ /* edma_prms->ch_no, usCmdReg ); */ #endif /* NEO_WRITEBACK */ /* Success */ break; } case ZION_EDMA_IOC_STOP: { unsigned char ucReg = 0; zion_edma_params_t *edma_prms = (zion_edma_params_t *)file->private_data; int ch = -1; /* Check EDMA parameters */ if (NULL == edma_prms) { PERROR("Private data is NULL!\n"); return (-ENODEV); } /* Get and check EDMA channel number */ ch = edma_prms->ch_no; if (ch < 0 || ZION_EDMA_NR_CH <= ch) { PERROR("Invalid ZION EDMA channel number(%d)!", ch); return (-ENODEV); } /* Read EDMA command register */ ucReg = mbus_readb(MBUS_ADDR(params, ZION_MBUS_EDMA_DMACMD(ch) + 1)); /* Write EDMA command register: DmaRun=0 */ ucReg &= ZION_MBUS_EDMA_STOP & 0x0F; /* PDEBUG("[CH%d] EDMA stop(0x%02X)\n", ch, ucReg); */ mbus_writeb(ucReg, MBUS_ADDR(params, ZION_MBUS_EDMA_DMACMD(ch) + 1)); /* Success */ break; } case ZION_EDMA_IOC_READ: { /* EDMA read */ return (zion_edma_run(params, inode, file, ZION_EDMA_READ)); } case ZION_EDMA_IOC_WRITE: { /* EDMA write */ return (zion_edma_run(params, inode, file, ZION_EDMA_WRITE)); } case ZION_EDMA_IOC_SET_REGION: { struct zion_edma_region s_zion_edma_region; if (copy_from_user((void *)&s_zion_edma_region, (void *)arg, sizeof(struct zion_edma_region))) return (-EFAULT); return zion_edma_set_region(params, s_zion_edma_region.dma_ch, s_zion_edma_region.num, s_zion_edma_region.lower, s_zion_edma_region.upper); } case ZION_EDMA_IOC_GET_REGION: { struct zion_edma_region s_zion_edma_region; if (copy_from_user((void *)&s_zion_edma_region, (void *)arg, sizeof(struct zion_edma_region))) return (-EFAULT); if (zion_edma_get_region(params, s_zion_edma_region.dma_ch, s_zion_edma_region.num, &s_zion_edma_region.lower, &s_zion_edma_region.upper)) return -EINVAL; if (copy_to_user((void *)arg, (void *)&s_zion_edma_region, sizeof(struct zion_edma_region))) return -EFAULT; /* Success */ break; } /* Get interrupt status for poll-select */ case ZION_EDMA_IOC_GET_INTSTTS: { zion_edma_params_t *edma_prms = (zion_edma_params_t *)file->private_data; int ch = -1; unsigned long irq_flags = 0; /* Check EDMA parameters */ if (NULL == edma_prms) { PERROR("Invalid ZION EDMA parameters!\n"); return (-ENODEV); } /* Set and check EDMA channel number */ ch = edma_prms->ch_no; if (ch < 0 || ZION_EDMA_NR_CH <= ch) { PERROR("Invalid ZION EDMA channel number(%d)!", ch); return (-ENODEV); } /* Set interrupt status */ if (copy_to_user((void *)arg, (void *)&(edma_prms->int_status), sizeof(unsigned short))) return (-EFAULT); /* Clear interrupt status */ spin_lock_irqsave( &(edma_prms->params_lock), irq_flags ); edma_prms->int_status = 0x0000; spin_unlock_irqrestore( &(edma_prms->params_lock), irq_flags ); /* Success */ break; } default: PERROR("No such Ioctl command!\n"); return (-EINVAL); } /* The end of SWITCH(function) */ return 0; }
int main(int argc, char *argv[]) { struct sockaddr_in sin, sout, from; struct ifreq ifr; int fd, s, port, PORT, l; unsigned int soutlen, fromlen; char c, *p, *ip; char buf[1500]; fd_set fdset; int MODE = 0, TUNMODE = IFF_TUN, DEBUG = 0; while ((c = getopt(argc, argv, "s:c:ehd")) != -1) { switch (c) { case 'h': usage(); case 'd': DEBUG++; break; case 's': MODE = 1; PORT = atoi(optarg); break; case 'c': MODE = 2; p = (char*)memchr(optarg,':',16); if (!p) ERROR("invalid argument : [%s]\n",optarg); *p = 0; ip = optarg; port = atoi(p+1); PORT = 0; break; case 'e': TUNMODE = IFF_TAP; break; default: usage(); } } if (MODE == 0) usage(); /* if ( (fd = open("/dev/net/tun",O_RDWR)) < 0) PERROR("open"); memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = TUNMODE; strncpy(ifr.ifr_name, "toto%d", IFNAMSIZ); if (ioctl(fd, TUNSETIFF, (void *)&ifr) < 0) PERROR("ioctl"); printf("Allocated interface %s. Configure and use it\n", ifr.ifr_name); */ /* s = socket(AF_INET, SOCK_DGRAM, 0); bzero(&sin, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; // or htonl(INADDR_ANY); TODO ?! sin.sin_port = htons(PORT); if ( bind(s,(struct sockaddr *)&sin, sizeof(sin)) < 0) PERROR("bind"); */ printf("PORT=%d \n", PORT); // struct sockaddr_in sin; s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) error(1, 1, "Opening socket"); //length = sizeof(server); bzero(&sin, sizeof(sin)); sin.sin_family=AF_INET; sin.sin_addr.s_addr=INADDR_ANY; sin.sin_port=htons(PORT); // if (bind(sock,(struct sockaddr *)&server,length)<0) printf("Doing the bind\n"); if (bind(s,(struct sockaddr *)&sin, sizeof(sin))<0) error(1, 1, "binding"); printf("Doing the bind - DONE\n"); // fromlen = sizeof(struct sockaddr_in); printf("After bind in line %d\n", __LINE__); fromlen = sizeof(from); if (MODE == 1) { printf("Will wait for the passwor packet now...%d\n", __LINE__); while(1) { printf("Trying to receive password...%d\n", __LINE__); l = recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr *)&from, &fromlen); printf("Read password packet len=%d in line %d\n", l, __LINE__); if (l < 0) PERROR("recvfrom"); if (strncmp(MAGIC_WORD, buf, sizeof(MAGIC_WORD)) == 0) break; printf("Bad magic word from %s:%i\n", inet_ntoa(from.sin_addr), ntohs(from.sin_port)); } printf("Got correct password in line %d\n", __LINE__); printf("Sending reply line %d\n", __LINE__); l = sendto(s, MAGIC_WORD, sizeof(MAGIC_WORD), 0, (struct sockaddr *)&from, fromlen); printf("Sent reply line %d\n", __LINE__); if (l < 0) PERROR("sendto"); } else { from.sin_family = AF_INET; from.sin_port = htons(port); inet_aton(ip, &from.sin_addr); l =sendto(s, MAGIC_WORD, sizeof(MAGIC_WORD), 0, (struct sockaddr *)&from, sizeof(from)); if (l < 0) PERROR("sendto"); l = recvfrom(s,buf, sizeof(buf), 0, (struct sockaddr *)&from, &fromlen); if (l < 0) PERROR("recvfrom"); if (strncmp(MAGIC_WORD, buf, sizeof(MAGIC_WORD) != 0)) ERROR("Bad magic word for peer\n"); } printf("Connection with %s:%i established\n", inet_ntoa(from.sin_addr), ntohs(from.sin_port)); while (1) { FD_ZERO(&fdset); FD_SET(fd, &fdset); FD_SET(s, &fdset); if (select(fd+s+1, &fdset,NULL,NULL,NULL) < 0) PERROR("select"); if (FD_ISSET(fd, &fdset)) { if (DEBUG) write(1,">", 1); l = read(fd, buf, sizeof(buf)); if (l < 0) PERROR("read"); if (sendto(s, buf, l, 0, (struct sockaddr *)&from, fromlen) < 0) PERROR("sendto"); } else { if (DEBUG) write(1,"<", 1); l = recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr *)&sout, &soutlen); if ((sout.sin_addr.s_addr != from.sin_addr.s_addr) || (sout.sin_port != from.sin_port)) printf("Got packet from %s:%i instead of %s:%i\n", inet_ntoa(sout.sin_addr), ntohs(sout.sin_port), inet_ntoa(from.sin_addr), ntohs(from.sin_port)); if (write(fd, buf, l) < 0) PERROR("write"); } } }
int smsspi_register(void) { struct smsdevice_params_t params; int ret; struct _spi_device_st *spi_device; struct _spi_dev_cb_st common_cb; PDEBUG("entering \n"); spi_device = kmalloc(sizeof(struct _spi_device_st), GFP_KERNEL); spi_dev = spi_device; INIT_LIST_HEAD(&spi_device->txqueue); ret = platform_device_register(&smsspi_device); if (ret < 0) { PERROR("platform_device_register failed\n"); return ret; } #if defined(MOT_FEAT_OMAP_DMA_USE) spi_device->txbuf = dma_alloc_coherent(NULL, TX_BUFFER_SIZE, &spi_device->txbuf_phy_addr, GFP_KERNEL | GFP_DMA); if (!spi_device->txbuf) { printk(KERN_INFO "%s dma_alloc_coherent(...) failed\n", __func__); ret = -ENOMEM; goto txbuf_error; } #endif spi_device->phy_dev = smsspiphy_init(NULL, smsspi_int_handler, spi_device); if (spi_device->phy_dev == 0) { printk(KERN_INFO "%s smsspiphy_init(...) failed\n", __func__); goto phy_error; } common_cb.allocate_rx_buf = allocate_rx_buf; common_cb.free_rx_buf = free_rx_buf; common_cb.msg_found_cb = msg_found; common_cb.transfer_data_cb = smsspibus_xfer; ret = smsspicommon_init(&spi_device->dev, spi_device, spi_device->phy_dev, &common_cb); if (ret) { printk(KERN_INFO "%s smsspiphy_init(...) failed\n", __func__); goto common_error; } /* register in smscore */ memset(¶ms, 0, sizeof(params)); params.context = spi_device; params.device = &smsspi_device.dev; params.buffer_size = RX_BUFFER_SIZE; params.num_buffers = NUM_RX_BUFFERS; params.flags = SMS_DEVICE_NOT_READY; params.sendrequest_handler = smsspi_write; strcpy(params.devpath, "spi"); params.device_type = default_type; if (0) { /* device family */ /* params.setmode_handler = smsspi_setmode; */ } else { params.flags = SMS_DEVICE_FAMILY2 | SMS_DEVICE_NOT_READY; params.preload_handler = smsspi_preload; params.postload_handler = smsspi_postload; } ret = smscore_register_device(¶ms, &spi_device->coredev); if (ret < 0) { printk(KERN_INFO "%s smscore_register_device(...) failed\n", __func__); goto reg_device_error; } ret = smscore_start_device(spi_device->coredev); if (ret < 0) { printk(KERN_INFO "%s smscore_start_device(...) failed\n", __func__); goto start_device_error; } PDEBUG("exiting\n"); return 0; start_device_error: smscore_unregister_device(spi_device->coredev); reg_device_error: common_error: smsspiphy_deinit(spi_device->phy_dev); phy_error: dma_free_coherent(NULL, TX_BUFFER_SIZE, spi_device->txbuf, spi_device->txbuf_phy_addr); txbuf_error: platform_device_unregister(&smsspi_device); PDEBUG("exiting error %d\n", ret); return ret; }
int __cdecl main(int argc, char *argv[]) { enum { CMD_NONE = 0, CMD_USER, CMD_ATTACH, CMD_DETACH, } cmd = CMD_NONE; int ret; if (argc == 3 && strcasecmp(argv[1], "user") == 0) { cmd = CMD_USER; } else if (argc == 3 && strcasecmp(argv[1], "attach") == 0) { cmd = CMD_ATTACH; } else if (argc == 3 && strcasecmp(argv[1], "detach") == 0) { cmd = CMD_DETACH; } else { fprintf(stderr, "Usage: " APP_NAME " user <remote link ID>\n"); fprintf(stderr, " " APP_NAME " attach <kernel port ID>\n"); fprintf(stderr, " " APP_NAME " detach <kernel port ID>\n"); exit(1); } if (cmd == CMD_USER) { SMBSIM_SERIAL *host; CSFNET *net; CSFNET_PARAMS net_params; ret = smbsim_serial_create(&host); if (ret) { PERROR("smbsim_serial_create", ret); exit(2); } memset(&net_params, 0, sizeof(net_params)); net_params.server_host = "127.0.0.1"; net_params.server_port = 5000; net_params.local_link_id = smbsim_serial_get_link_id(host); net_params.remote_link_id = (UINT16) strtoul(argv[2], 0, 0); net_params.bus_type = CSF_BUS_TYPE_SMBUS; ret = csfnet_create(&net_params, &net); if (ret) { PERROR("csfnet_create", ret); smbsim_serial_delete(host); exit(3); } printf("Press enter key to terminate..."); getchar(); csfnet_delete(net); smbsim_serial_delete(host); } else { XPCF_UDEV *udev; int port_id; ret = xpcf_udev_open(DEV_NAME, &udev); if (ret) { PERROR("xpcf_udev_open", ret); exit(4); } port_id = strtoul(argv[2], 0, 0); if (cmd == CMD_ATTACH) { ret = xpcf_udev_ioctl(udev, IOCTL_SMBSIM_SERIAL_ATTACH_DEV, &port_id, sizeof(port_id), NULL); if (ret) { PERROR("ioctl(IOCTL_SMBSIM_SERIAL_ATTACH_DEV)", ret); xpcf_udev_close(udev); exit(5); } } else { ret = xpcf_udev_ioctl(udev, IOCTL_SMBSIM_SERIAL_DETACH_DEV, &port_id, sizeof(port_id), NULL); if (ret) { PERROR("ioctl(IOCTL_SMBSIM_SERIAL_DETACH_DEV)", ret); xpcf_udev_close(udev); exit(6); } } xpcf_udev_close(udev); } return 0; }
/* * Return < 0 on error, 0 if OK, 1 on hangup. */ static int handle_one_cmd(struct run_as_worker *worker) { int ret = 0; struct run_as_data data; ssize_t readlen, writelen; struct run_as_ret sendret; run_as_fct cmd; uid_t prev_euid; /* Read data */ readlen = lttcomm_recv_unix_sock(worker->sockpair[1], &data, sizeof(data)); if (readlen == 0) { /* hang up */ ret = 1; goto end; } if (readlen < sizeof(data)) { PERROR("lttcomm_recv_unix_sock error"); ret = -1; goto end; } cmd = run_as_enum_to_fct(data.cmd); if (!cmd) { ret = -1; goto end; } prev_euid = getuid(); if (data.gid != getegid()) { ret = setegid(data.gid); if (ret < 0) { PERROR("setegid"); goto write_return; } } if (data.uid != prev_euid) { ret = seteuid(data.uid); if (ret < 0) { PERROR("seteuid"); goto write_return; } } /* * Also set umask to 0 for mkdir executable bit. */ umask(0); ret = (*cmd)(&data); write_return: sendret.ret = ret; sendret._errno = errno; /* send back return value */ writelen = lttcomm_send_unix_sock(worker->sockpair[1], &sendret, sizeof(sendret)); if (writelen < sizeof(sendret)) { PERROR("lttcomm_send_unix_sock error"); ret = -1; goto end; } ret = do_send_fd(worker, data.cmd, ret); if (ret) { PERROR("do_send_fd error"); ret = -1; goto end; } if (seteuid(prev_euid) < 0) { PERROR("seteuid"); ret = -1; goto end; } ret = 0; end: return ret; }
LTTNG_HIDDEN int run_as_create_worker(char *procname) { pid_t pid; int i, ret = 0; ssize_t readlen; struct run_as_ret recvret; struct run_as_worker *worker; pthread_mutex_lock(&worker_lock); assert(!global_worker); if (!use_clone()) { /* * Don't initialize a worker, all run_as tasks will be performed * in the current process. */ ret = 0; goto end; } worker = zmalloc(sizeof(*worker)); if (!worker) { ret = -ENOMEM; goto end; } worker->procname = procname; /* Create unix socket. */ if (lttcomm_create_anon_unix_socketpair(worker->sockpair) < 0) { ret = -1; goto error_sock; } /* Fork worker. */ pid = fork(); if (pid < 0) { PERROR("fork"); ret = -1; goto error_fork; } else if (pid == 0) { /* Child */ reset_sighandler(); set_worker_sighandlers(); /* The child has no use for this lock. */ pthread_mutex_unlock(&worker_lock); /* Just close, no shutdown. */ if (close(worker->sockpair[0])) { PERROR("close"); exit(EXIT_FAILURE); } worker->sockpair[0] = -1; ret = run_as_worker(worker); if (lttcomm_close_unix_sock(worker->sockpair[1])) { PERROR("close"); ret = -1; } worker->sockpair[1] = -1; LOG(ret ? PRINT_ERR : PRINT_DBG, "run_as worker exiting (ret = %d)", ret); exit(ret ? EXIT_FAILURE : EXIT_SUCCESS); } else { /* Parent */ /* Just close, no shutdown. */ if (close(worker->sockpair[1])) { PERROR("close"); ret = -1; goto error_fork; } worker->sockpair[1] = -1; worker->pid = pid; /* Wait for worker to become ready. */ readlen = lttcomm_recv_unix_sock(worker->sockpair[0], &recvret, sizeof(recvret)); if (readlen < sizeof(recvret)) { ERR("readlen: %zd", readlen); PERROR("Error reading response from run_as at creation"); ret = -1; goto error_fork; } global_worker = worker; } end: pthread_mutex_unlock(&worker_lock); return ret; /* Error handling. */ error_fork: for (i = 0; i < 2; i++) { if (worker->sockpair[i] < 0) { continue; } if (lttcomm_close_unix_sock(worker->sockpair[i])) { PERROR("close"); } worker->sockpair[i] = -1; } error_sock: free(worker); pthread_mutex_unlock(&worker_lock); return ret; }
/* epoint sends a message to a join * */ void JoinPBX::message_epoint(unsigned int epoint_id, int message_type, union parameter *param) { class Join *cl; struct join_relation *relation, *reltemp; int num; int new_state; struct lcr_msg *message; // int size, writesize, oldpointer; char *number, *numbers; if (!epoint_id) { PERROR("software error, epoint == NULL\n"); return; } // if (options.deb & DEBUG_JOIN) { // PDEBUG(DEBUG_JOIN, "message %d received from ep%d.\n", message, epoint->ep_serial); // joinpbx_debug(join,"Join::message_epoint"); // } if (options.deb & DEBUG_JOIN) { if (message_type) { cl = join_first; while(cl) { if (cl->j_type == JOIN_TYPE_PBX) joinpbx_debug((class JoinPBX *)cl, "Join::message_epoint{all joins before processing}"); cl = cl->next; } } } /* check relation */ relation = j_relation; while(relation) { if (relation->epoint_id == epoint_id) break; relation = relation->next; } if (!relation) { PDEBUG(DEBUG_JOIN, "no relation back to the endpoint found, ignoring (join=%d, endpoint=%d)\n", j_serial, epoint_id); return; } /* count relations */ num=joinpbx_countrelations(j_serial); /* process party line */ if (message_type == MESSAGE_SETUP) if (param->setup.partyline && !j_partyline) { j_partyline = param->setup.partyline; j_partyline_jingle = param->setup.partyline_jingle; } if (j_partyline) { switch(message_type) { case MESSAGE_SETUP: PDEBUG(DEBUG_JOIN, "respsone with connect in partyline mode.\n"); relation->type = RELATION_TYPE_CONNECT; message = message_create(j_serial, epoint_id, JOIN_TO_EPOINT, MESSAGE_CONNECT); SPRINT(message->param.connectinfo.id, "%d", j_partyline); message->param.connectinfo.ntype = INFO_NTYPE_UNKNOWN; message_put(message); trigger_work(&j_updatebridge); if (j_partyline_jingle) play_jingle(1); break; case MESSAGE_AUDIOPATH: PDEBUG(DEBUG_JOIN, "join received channel message: %d.\n", param->audiopath); if (relation->channel_state != param->audiopath) { relation->channel_state = param->audiopath; trigger_work(&j_updatebridge); if (options.deb & DEBUG_JOIN) joinpbx_debug(this, "Join::message_epoint{after setting new channel state}"); } break; /* track notify */ case MESSAGE_NOTIFY: switch(param->notifyinfo.notify) { case INFO_NOTIFY_USER_SUSPENDED: case INFO_NOTIFY_USER_RESUMED: case INFO_NOTIFY_REMOTE_HOLD: case INFO_NOTIFY_REMOTE_RETRIEVAL: case INFO_NOTIFY_CONFERENCE_ESTABLISHED: case INFO_NOTIFY_CONFERENCE_DISCONNECTED: new_state = track_notify(relation->rx_state, param->notifyinfo.notify); if (new_state != relation->rx_state) { relation->rx_state = new_state; trigger_work(&j_updatebridge); if (options.deb & DEBUG_JOIN) joinpbx_debug(this, "Join::message_epoint{after setting new rx state}"); } break; } break; case MESSAGE_DISCONNECT: PDEBUG(DEBUG_JOIN, "releasing after receiving disconnect, because join in partyline mode.\n"); message = message_create(j_serial, epoint_id, JOIN_TO_EPOINT, MESSAGE_RELEASE); message->param.disconnectinfo.cause = CAUSE_NORMAL; message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL; message_put(message); // fall through case MESSAGE_RELEASE: PDEBUG(DEBUG_JOIN, "releasing from join\n"); release(relation, 0, 0); if (j_partyline_jingle) play_jingle(0); break; default: PDEBUG(DEBUG_JOIN, "ignoring message, because join in partyline mode.\n"); } return; } /* process messages */ switch(message_type) { /* process audio path message */ case MESSAGE_AUDIOPATH: PDEBUG(DEBUG_JOIN, "join received channel message: audiopath=%d, current relation's channel_state=%d\n", param->audiopath, relation->channel_state); if (relation->channel_state != param->audiopath) { relation->channel_state = param->audiopath; trigger_work(&j_updatebridge); if (options.deb & DEBUG_JOIN) joinpbx_debug(this, "Join::message_epoint{after setting new channel state}"); } return; /* track notify */ case MESSAGE_NOTIFY: switch(param->notifyinfo.notify) { case INFO_NOTIFY_USER_SUSPENDED: case INFO_NOTIFY_USER_RESUMED: case INFO_NOTIFY_REMOTE_HOLD: case INFO_NOTIFY_REMOTE_RETRIEVAL: case INFO_NOTIFY_CONFERENCE_ESTABLISHED: case INFO_NOTIFY_CONFERENCE_DISCONNECTED: new_state = track_notify(relation->rx_state, param->notifyinfo.notify); if (new_state != relation->rx_state) { relation->rx_state = new_state; trigger_work(&j_updatebridge); if (options.deb & DEBUG_JOIN) joinpbx_debug(this, "Join::message_epoint{after setting new rx state}"); } break; default: /* send notification to all other endpoints */ reltemp = j_relation; while(reltemp) { if (reltemp->epoint_id!=epoint_id && reltemp->epoint_id) { message = message_create(j_serial, reltemp->epoint_id, JOIN_TO_EPOINT, MESSAGE_NOTIFY); memcpy(&message->param, param, sizeof(union parameter)); message_put(message); } reltemp = reltemp->next; } } return; /* relations sends a connect */ case MESSAGE_CONNECT: /* outgoing setup type becomes connected */ if (relation->type == RELATION_TYPE_SETUP) relation->type = RELATION_TYPE_CONNECT; /* release other relations in setup state */ release_again: reltemp = j_relation; while(reltemp) { //printf("connect, checking relation %d\n", reltemp->epoint_id); if (reltemp->type == RELATION_TYPE_SETUP) { //printf("relation %d is of type setup, releasing\n", reltemp->epoint_id); /* send release to endpoint */ message = message_create(j_serial, reltemp->epoint_id, JOIN_TO_EPOINT, MESSAGE_RELEASE); message->param.disconnectinfo.cause = CAUSE_NONSELECTED; message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL; message_put(message); if (release(reltemp, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL)) // dummy cause, should not be used, since calling and connected endpoint still exist afterwards. return; // must return, because join IS destroyed goto release_again; } if (reltemp->type == RELATION_TYPE_CALLING) reltemp->type = RELATION_TYPE_CONNECT; reltemp = reltemp->next; } break; // continue with our message /* release is sent by endpoint */ case MESSAGE_RELEASE: switch(relation->type) { case RELATION_TYPE_SETUP: /* by called */ /* collect cause and send collected cause */ collect_cause(&j_multicause, &j_multilocation, param->disconnectinfo.cause, param->disconnectinfo.location); if (j_multicause) release(relation, j_multilocation, j_multicause); else release(relation, LOCATION_PRIVATE_LOCAL, CAUSE_UNSPECIFIED); break; case RELATION_TYPE_CALLING: /* by calling */ /* remove us, if we don't have a called releation yet */ if (!j_relation->next) { release(j_relation, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL); return; // must return, because join IS destroyed } /* in a conf, we don't kill the other members */ if (num > 2 && !joinpbx_onecalling_othersetup(j_relation)) { release(relation, 0, 0); return; } /* remove all relations that are of called type */ release_again2: reltemp = j_relation; while(reltemp) { if (reltemp->type == RELATION_TYPE_SETUP) { /* send release to endpoint */ message = message_create(j_serial, reltemp->epoint_id, JOIN_TO_EPOINT, message_type); memcpy(&message->param, param, sizeof(union parameter)); message_put(message); if (release(reltemp, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL)) return; // must return, because join IS destroyed goto release_again2; } reltemp = reltemp->next; } PERROR("we are still here, this should not happen\n"); break; default: /* by connected */ /* send current cause */ release(relation, param->disconnectinfo.location, param->disconnectinfo.cause); } return; // must return, because join may be destroyed } /* check number of relations */ if (num > 2 && !joinpbx_onecalling_othersetup(j_relation) && message_type != MESSAGE_CONNECT) { PDEBUG(DEBUG_JOIN, "we are in a conference, so we ignore the messages, except MESSAGE_CONNECT.\n"); return; } /* if join has no other relation, we process the setup message */ if (num == 1) { switch(message_type) { case MESSAGE_SETUP: if (param->setup.dialinginfo.itype == INFO_ITYPE_ISDN_EXTENSION) { /* in case of keypad */ numbers = param->setup.dialinginfo.keypad; if (numbers[0]) { while((number = strsep(&numbers, ","))) { if (out_setup(epoint_id, message_type, param, NULL, number)) return; // join destroyed } /* after keypad finish dialing */ break; } /* dialed number */ numbers = param->setup.dialinginfo.id; while((number = strsep(&numbers, ","))) { if (out_setup(epoint_id, message_type, param, number, NULL)) return; // join destroyed } break; } if (out_setup(epoint_id, message_type, param, param->setup.dialinginfo.id, param->setup.dialinginfo.keypad)) return; // join destroyed break; default: PDEBUG(DEBUG_JOIN, "no need to send a message because there is no other endpoint than the calling one.\n"); } } else { /* sending message to other relation(s) */ relation = j_relation; while(relation) { if (relation->epoint_id != epoint_id) { PDEBUG(DEBUG_JOIN, "sending message ep%ld -> ep%ld.\n", epoint_id, relation->epoint_id); message = message_create(j_serial, relation->epoint_id, JOIN_TO_EPOINT, message_type); memcpy(&message->param, param, sizeof(union parameter)); message_put(message); PDEBUG(DEBUG_JOIN, "message sent.\n"); } relation = relation->next; } } }
void JoinPBX::bridge(void) { struct join_relation *relation; struct lcr_msg *message; int numconnect = 0, relations = 0; class Endpoint *epoint; struct port_list *portlist; class Port *port; unsigned int bridge_id; class Join *join_3pty; class JoinPBX *joinpbx_3pty; #ifdef DEBUG_COREBRIDGE int allmISDN = 0; // never set for debug purpose #else int allmISDN = 1; // set until a non-mISDN relation is found #endif /* bridge id is the serial of join * if we have a 3pty with another join, we always use the lowest brigde id. * this way we use common ids, so both joins share same bridge */ if (j_3pty && j_3pty < j_serial) bridge_id = j_3pty; else bridge_id = j_serial; relation = j_relation; while(relation) { /* count all relations */ relations++; /* check for relation's objects */ epoint = find_epoint_id(relation->epoint_id); if (!epoint) { PERROR("software error: relation without existing endpoints.\n"); relation = relation->next; continue; } portlist = epoint->ep_portlist; if (!portlist) { PDEBUG(DEBUG_JOIN, "join%d ignoring relation without port object.\n", j_serial); //#warning testing: keep on hold until single audio stream available relation->channel_state = 0; relation = relation->next; continue; } if (portlist->next) { PDEBUG(DEBUG_JOIN, "join%d ignoring relation with ep%d due to port_list.\n", j_serial, epoint->ep_serial); //#warning testing: keep on hold until single audio stream available relation->channel_state = 0; relation = relation->next; continue; } port = find_port_id(portlist->port_id); if (!port) { PDEBUG(DEBUG_JOIN, "join%d ignoring relation without existing port object.\n", j_serial); relation = relation->next; continue; } if ((port->p_type&PORT_CLASS_MASK)!=PORT_CLASS_mISDN) { PDEBUG(DEBUG_JOIN, "join%d ignoring relation ep%d because it's port is not mISDN.\n", j_serial, epoint->ep_serial); if (allmISDN) { PDEBUG(DEBUG_JOIN, "join%d not all endpoints are mISDN.\n", j_serial); allmISDN = 0; } relation = relation->next; continue; } relation = relation->next; } /* check if 3pty members have no mISDN, so bridging via mISDN/lcr will be selected correctly */ join_3pty = find_join_id(j_3pty); if (join_3pty && join_3pty->j_type == JOIN_TYPE_PBX) { joinpbx_3pty = (class JoinPBX *)join_3pty; relation = joinpbx_3pty->j_relation; while(relation) { #if 0 no need to count, because j_3pty is taken into account below when checking relations /* count all relations */ relations++; #endif /* check for relation's objects */ epoint = find_epoint_id(relation->epoint_id); if (!epoint) { PERROR("software error: relation without existing endpoints.\n"); relation = relation->next; continue; } portlist = epoint->ep_portlist; if (!portlist) { PDEBUG(DEBUG_JOIN, "other 3pty join %d: ignoring relation without port object.\n", joinpbx_3pty->j_serial); //#warning testing: keep on hold until single audio stream available relation->channel_state = 0; relation = relation->next; continue; } if (portlist->next) { PDEBUG(DEBUG_JOIN, "other 3pty join %d: ignoring relation with ep%d due to port_list.\n", joinpbx_3pty->j_serial, epoint->ep_serial); //#warning testing: keep on hold until single audio stream available relation->channel_state = 0; relation = relation->next; continue; } port = find_port_id(portlist->port_id); if (!port) { PDEBUG(DEBUG_JOIN, "other 3pty join %d: ignoring relation without existing port object.\n", joinpbx_3pty->j_serial); relation = relation->next; continue; } if ((port->p_type&PORT_CLASS_MASK)!=PORT_CLASS_mISDN) { PDEBUG(DEBUG_JOIN, "other 3pty join %d: ignoring relation ep%d because it's port is not mISDN.\n", joinpbx_3pty->j_serial, epoint->ep_serial); if (allmISDN) { PDEBUG(DEBUG_JOIN, "other 3pty join %d: not all endpoints are mISDN.\n", joinpbx_3pty->j_serial); allmISDN = 0; } relation = relation->next; continue; } relation = relation->next; } } PDEBUG(DEBUG_JOIN, "join%d members=%d %s\n", j_serial, relations, (allmISDN)?"(all are mISDN-members)":"(not all are mISDN-members)"); /* we notify all relations about rxdata. */ relation = j_relation; while(relation) { /* count connected relations */ if ((relation->channel_state == 1) && (relation->rx_state != NOTIFY_STATE_SUSPEND) && (relation->rx_state != NOTIFY_STATE_HOLD)) numconnect ++; /* remove unconnected parties from conference, also remove remotely disconnected parties so conference will not be disturbed. */ /* mISDN */ if (relation->channel_state == 1 && relation->rx_state != NOTIFY_STATE_HOLD && relation->rx_state != NOTIFY_STATE_SUSPEND && relations>1 // no conf with one member && allmISDN) { // no conf if any member is not mISDN message = message_create(j_serial, relation->epoint_id, JOIN_TO_EPOINT, MESSAGE_mISDNSIGNAL); message->param.mISDNsignal.message = mISDNSIGNAL_CONF; message->param.mISDNsignal.conf = (bridge_id << 16) | j_pid; PDEBUG(DEBUG_JOIN, "join%d EP%d +on+ id: 0x%08x\n", j_serial, relation->epoint_id, message->param.mISDNsignal.conf); message_put(message); } else { message = message_create(j_serial, relation->epoint_id, JOIN_TO_EPOINT, MESSAGE_mISDNSIGNAL); message->param.mISDNsignal.message = mISDNSIGNAL_CONF; message->param.mISDNsignal.conf = 0; PDEBUG(DEBUG_JOIN, "join%d EP%d +off+ id: 0x%08x\n", j_serial, relation->epoint_id, message->param.mISDNsignal.conf); message_put(message); } /* core bridge */ if (relation->channel_state == 1 && relation->rx_state != NOTIFY_STATE_HOLD && relation->rx_state != NOTIFY_STATE_SUSPEND && relations>1 // no bridge with one member && !allmISDN) { // no bridge if all members are mISDN message = message_create(j_serial, relation->epoint_id, JOIN_TO_EPOINT, MESSAGE_BRIDGE); message->param.bridge_id = bridge_id; PDEBUG(DEBUG_JOIN, "join%u EP%u requests bridge=%u\n", j_serial, relation->epoint_id, bridge_id); message_put(message); } else { message = message_create(j_serial, relation->epoint_id, JOIN_TO_EPOINT, MESSAGE_BRIDGE); message->param.bridge_id = 0; PDEBUG(DEBUG_JOIN, "join%u EP%u drop bridge=%u\n", j_serial, relation->epoint_id, bridge_id); message_put(message); } relation = relation->next; } /* two people just exchange their states */ if (!j_3pty && relations==2 && !j_partyline) { PDEBUG(DEBUG_JOIN, "join%d 2 relations / no partyline\n", j_serial); relation = j_relation; relation->tx_state = notify_state_change(j_serial, relation->epoint_id, relation->tx_state, relation->next->rx_state); relation->next->tx_state = notify_state_change(j_serial, relation->next->epoint_id, relation->next->tx_state, relation->rx_state); } else /* one member in a join, so we put her on hold */ if (!j_3pty && (relations==1 || numconnect==1)/* && !j_partyline_jingle*/) { PDEBUG(DEBUG_JOIN, "join%d 1 member or only 1 connected, put on hold\n", j_serial); relation = j_relation; while(relation) { if ((relation->channel_state == 1) && (relation->rx_state != NOTIFY_STATE_SUSPEND) && (relation->rx_state != NOTIFY_STATE_HOLD)) relation->tx_state = notify_state_change(j_serial, relation->epoint_id, relation->tx_state, NOTIFY_STATE_HOLD); relation = relation->next; } } else { /* if conference/partyline (or more than two members and more than one is connected), so we set conference state */ PDEBUG(DEBUG_JOIN, "join%d %d members, %d connected, signal conference\n", j_serial, relations, numconnect); relation = j_relation; while(relation) { if ((relation->channel_state == 1) && (relation->rx_state != NOTIFY_STATE_SUSPEND) && (relation->rx_state != NOTIFY_STATE_HOLD)) relation->tx_state = notify_state_change(j_serial, relation->epoint_id, relation->tx_state, NOTIFY_STATE_CONFERENCE); relation = relation->next; } } }
me8254_subdevice_t* me8254_constr(uint16_t device_id, void* reg_base, unsigned int me8254_idx, unsigned int ctr_idx, me_lock_t* ctrl_reg_lock, me_lock_t* clk_src_reg_lock) { me8254_subdevice_t *subdevice; PDEBUG("executed.\n"); /** @todo Checkings should be removed. We can safetly assume that data passed from upper level are correct. */ // Check if counter index is out of range if (ctr_idx > 2) { PERROR("Counter index is out of range.\n"); return NULL; } // Check device specific values. switch (device_id) { case PCI_DEVICE_ID_MEILHAUS_ME140A: case PCI_DEVICE_ID_MEILHAUS_ME14EA: case PCI_DEVICE_ID_MEILHAUS_ME4610: case PCI_DEVICE_ID_MEILHAUS_ME4660: case PCI_DEVICE_ID_MEILHAUS_ME4660I: case PCI_DEVICE_ID_MEILHAUS_ME4660S: case PCI_DEVICE_ID_MEILHAUS_ME4660IS: case PCI_DEVICE_ID_MEILHAUS_ME4670: case PCI_DEVICE_ID_MEILHAUS_ME4670I: case PCI_DEVICE_ID_MEILHAUS_ME4670S: case PCI_DEVICE_ID_MEILHAUS_ME4670IS: case PCI_DEVICE_ID_MEILHAUS_ME4680: case PCI_DEVICE_ID_MEILHAUS_ME4680I: case PCI_DEVICE_ID_MEILHAUS_ME4680S: case PCI_DEVICE_ID_MEILHAUS_ME4680IS: case PCI_DEVICE_ID_MEILHAUS_ME4560: case PCI_DEVICE_ID_MEILHAUS_ME4560I: case PCI_DEVICE_ID_MEILHAUS_ME4560S: case PCI_DEVICE_ID_MEILHAUS_ME4560IS: case PCI_DEVICE_ID_MEILHAUS_ME4570: case PCI_DEVICE_ID_MEILHAUS_ME4570I: case PCI_DEVICE_ID_MEILHAUS_ME4570S: case PCI_DEVICE_ID_MEILHAUS_ME4570IS: case PCI_DEVICE_ID_MEILHAUS_ME4760: case PCI_DEVICE_ID_MEILHAUS_ME4760I: case PCI_DEVICE_ID_MEILHAUS_ME4760S: case PCI_DEVICE_ID_MEILHAUS_ME4760IS: case PCI_DEVICE_ID_MEILHAUS_ME4770: case PCI_DEVICE_ID_MEILHAUS_ME4770I: case PCI_DEVICE_ID_MEILHAUS_ME4770S: case PCI_DEVICE_ID_MEILHAUS_ME4770IS: case PCI_DEVICE_ID_MEILHAUS_ME4780: case PCI_DEVICE_ID_MEILHAUS_ME4780I: case PCI_DEVICE_ID_MEILHAUS_ME4780S: case PCI_DEVICE_ID_MEILHAUS_ME4780IS: case PCI_DEVICE_ID_MEILHAUS_ME4860: case PCI_DEVICE_ID_MEILHAUS_ME4860I: case PCI_DEVICE_ID_MEILHAUS_ME4860S: case PCI_DEVICE_ID_MEILHAUS_ME4860IS: case PCI_DEVICE_ID_MEILHAUS_ME4870: case PCI_DEVICE_ID_MEILHAUS_ME4870I: case PCI_DEVICE_ID_MEILHAUS_ME4870S: case PCI_DEVICE_ID_MEILHAUS_ME4870IS: case PCI_DEVICE_ID_MEILHAUS_ME4880: case PCI_DEVICE_ID_MEILHAUS_ME4880I: case PCI_DEVICE_ID_MEILHAUS_ME4880S: case PCI_DEVICE_ID_MEILHAUS_ME4880IS: case PCI_DEVICE_ID_MEILHAUS_ME0752: case PCI_DEVICE_ID_MEILHAUS_ME0754: case PCI_DEVICE_ID_MEILHAUS_ME0762: case PCI_DEVICE_ID_MEILHAUS_ME0764: case PCI_DEVICE_ID_MEILHAUS_ME0772: case PCI_DEVICE_ID_MEILHAUS_ME0774: case PCI_DEVICE_ID_MEILHAUS_ME0782: case PCI_DEVICE_ID_MEILHAUS_ME0784: case PCI_DEVICE_ID_MEILHAUS_ME8100_A: case PCI_DEVICE_ID_MEILHAUS_ME8100_B: if (me8254_idx > 0) { PERROR("8254 index is out of range. Must be 0.\n"); return NULL; } break; case PCI_DEVICE_ID_MEILHAUS_ME140B: case PCI_DEVICE_ID_MEILHAUS_ME14EB: if (me8254_idx > 1) { PERROR("8254 index is out of range. Must be 0 or 1.\n"); return NULL; } break; case PCI_DEVICE_ID_MEILHAUS_ME140C: if (me8254_idx > 4) { PERROR("8254 index is out of range. Must be between 0 and 3.\n"); return NULL; } case PCI_DEVICE_ID_MEILHAUS_ME140D: if (me8254_idx > 9) { PERROR("8254 index is out of range. Must be between 0 and 8.\n"); return NULL; } break; default: PERROR_CRITICAL("8254 registred for %x!\n", device_id); return NULL; } // Allocate memory for subdevice instance subdevice = kzalloc(sizeof(me8254_subdevice_t), GFP_KERNEL); if (!subdevice) { PERROR("Cannot get memory for 8254 instance.\n"); return NULL; } // Initialize subdevice base class if (me_subdevice_init(&subdevice->base)) { PERROR("Cannot initialize subdevice base class instance.\n"); kfree(subdevice); return NULL; } // Initialize spin locks. subdevice->ctrl_reg_lock = ctrl_reg_lock; subdevice->clk_src_reg_lock = clk_src_reg_lock; // Save type of Meilhaus device subdevice->device_id = device_id; // Save the subdevice indexes. subdevice->me8254_idx = me8254_idx; subdevice->ctr_idx = ctr_idx; subdevice->base.idx = ctr_idx + (me8254_idx * 3); /** @todo Setting flags for particular implementations create portibility problem. Flags should be passed from upper level. Also registers should be some how provided by upper level call. */ // Do device specific initialization switch (device_id) { case PCI_DEVICE_ID_MEILHAUS_ME140A: case PCI_DEVICE_ID_MEILHAUS_ME14EA: case PCI_DEVICE_ID_MEILHAUS_ME140B: case PCI_DEVICE_ID_MEILHAUS_ME14EB: // Initialize the counters capabilities subdevice->caps = ME_CAPS_CTR_CLK_EXTERNAL; if (ctr_idx == 0) subdevice->caps |= ME_CAPS_CTR_CLK_INTERNAL_1MHZ | ME_CAPS_CTR_CLK_INTERNAL_10MHZ; else subdevice->caps |= ME_CAPS_CTR_CLK_PREVIOUS; // Get the counters registers subdevice->val_reg = me1400AB_get_val_reg(reg_base, me8254_idx, ctr_idx); subdevice->ctrl_reg = me1400AB_get_ctrl_reg(reg_base, me8254_idx, ctr_idx); subdevice->clk_src_reg = me1400AB_get_clk_src_reg(reg_base, me8254_idx, ctr_idx); break; case PCI_DEVICE_ID_MEILHAUS_ME140C: case PCI_DEVICE_ID_MEILHAUS_ME140D: // Initialize the counters capabilities subdevice->caps = ME_CAPS_CTR_CLK_EXTERNAL | ME_CAPS_CTR_CLK_PREVIOUS; if (ctr_idx == 0) { subdevice->caps |= ME_CAPS_CTR_CLK_INTERNAL_1MHZ | ME_CAPS_CTR_CLK_INTERNAL_10MHZ; if ((me8254_idx == 0) || (me8254_idx == 5)) {// No cascading for first counter on first chips. subdevice->caps &= ~ME_CAPS_CTR_CLK_PREVIOUS; } } // Get the counters registers subdevice->val_reg = me1400CD_get_val_reg(reg_base, me8254_idx, ctr_idx); subdevice->ctrl_reg = me1400CD_get_ctrl_reg(reg_base, me8254_idx, ctr_idx); subdevice->clk_src_reg = me1400CD_get_clk_src_reg(reg_base, me8254_idx, ctr_idx); break; case PCI_DEVICE_ID_MEILHAUS_ME4610: case PCI_DEVICE_ID_MEILHAUS_ME4660: case PCI_DEVICE_ID_MEILHAUS_ME4660I: case PCI_DEVICE_ID_MEILHAUS_ME4660S: case PCI_DEVICE_ID_MEILHAUS_ME4660IS: case PCI_DEVICE_ID_MEILHAUS_ME4670: case PCI_DEVICE_ID_MEILHAUS_ME4670I: case PCI_DEVICE_ID_MEILHAUS_ME4670S: case PCI_DEVICE_ID_MEILHAUS_ME4670IS: case PCI_DEVICE_ID_MEILHAUS_ME4680: case PCI_DEVICE_ID_MEILHAUS_ME4680I: case PCI_DEVICE_ID_MEILHAUS_ME4680S: case PCI_DEVICE_ID_MEILHAUS_ME4680IS: case PCI_DEVICE_ID_MEILHAUS_ME4560: case PCI_DEVICE_ID_MEILHAUS_ME4560I: case PCI_DEVICE_ID_MEILHAUS_ME4560S: case PCI_DEVICE_ID_MEILHAUS_ME4560IS: case PCI_DEVICE_ID_MEILHAUS_ME4570: case PCI_DEVICE_ID_MEILHAUS_ME4570I: case PCI_DEVICE_ID_MEILHAUS_ME4570S: case PCI_DEVICE_ID_MEILHAUS_ME4570IS: case PCI_DEVICE_ID_MEILHAUS_ME4760: case PCI_DEVICE_ID_MEILHAUS_ME4760I: case PCI_DEVICE_ID_MEILHAUS_ME4760S: case PCI_DEVICE_ID_MEILHAUS_ME4760IS: case PCI_DEVICE_ID_MEILHAUS_ME4770: case PCI_DEVICE_ID_MEILHAUS_ME4770I: case PCI_DEVICE_ID_MEILHAUS_ME4770S: case PCI_DEVICE_ID_MEILHAUS_ME4770IS: case PCI_DEVICE_ID_MEILHAUS_ME4780: case PCI_DEVICE_ID_MEILHAUS_ME4780I: case PCI_DEVICE_ID_MEILHAUS_ME4780S: case PCI_DEVICE_ID_MEILHAUS_ME4780IS: case PCI_DEVICE_ID_MEILHAUS_ME4860: case PCI_DEVICE_ID_MEILHAUS_ME4860I: case PCI_DEVICE_ID_MEILHAUS_ME4860S: case PCI_DEVICE_ID_MEILHAUS_ME4860IS: case PCI_DEVICE_ID_MEILHAUS_ME4870: case PCI_DEVICE_ID_MEILHAUS_ME4870I: case PCI_DEVICE_ID_MEILHAUS_ME4870S: case PCI_DEVICE_ID_MEILHAUS_ME4870IS: case PCI_DEVICE_ID_MEILHAUS_ME4880: case PCI_DEVICE_ID_MEILHAUS_ME4880I: case PCI_DEVICE_ID_MEILHAUS_ME4880S: case PCI_DEVICE_ID_MEILHAUS_ME4880IS: case PCI_DEVICE_ID_MEILHAUS_ME0752: case PCI_DEVICE_ID_MEILHAUS_ME0754: case PCI_DEVICE_ID_MEILHAUS_ME0762: case PCI_DEVICE_ID_MEILHAUS_ME0764: case PCI_DEVICE_ID_MEILHAUS_ME0772: case PCI_DEVICE_ID_MEILHAUS_ME0774: case PCI_DEVICE_ID_MEILHAUS_ME0782: case PCI_DEVICE_ID_MEILHAUS_ME0784: // Initialize the counters capabilities subdevice->caps = ME_CAPS_CTR_CLK_EXTERNAL; // Get the counters registers subdevice->val_reg = me4600_get_val_reg(reg_base, me8254_idx, ctr_idx); subdevice->ctrl_reg = me4600_get_ctrl_reg(reg_base, me8254_idx, ctr_idx); subdevice->clk_src_reg = 0; // Not used break; case PCI_DEVICE_ID_MEILHAUS_ME8100_A: case PCI_DEVICE_ID_MEILHAUS_ME8100_B: // Initialize the counters capabilities subdevice->caps = ME_CAPS_CTR_CLK_EXTERNAL; // Get the counters registers subdevice->val_reg = me8100_get_val_reg(reg_base, me8254_idx, ctr_idx); subdevice->ctrl_reg = me8100_get_ctrl_reg(reg_base, me8254_idx, ctr_idx); subdevice->clk_src_reg = 0; // Not used break; default: PERROR("Unknown device type.\n"); me_subdevice_deinit(&subdevice->base); kfree(subdevice); return NULL; } // Overload subdevice base class methods. subdevice->base.me_subdevice_io_reset_subdevice = me8254_io_reset_subdevice; subdevice->base.me_subdevice_io_single_config = me8254_io_single_config; subdevice->base.me_subdevice_io_single_read = me8254_io_single_read; subdevice->base.me_subdevice_io_single_write = me8254_io_single_write; subdevice->base.me_subdevice_query_number_channels = me8254_query_number_channels; subdevice->base.me_subdevice_query_subdevice_type = me8254_query_subdevice_type; subdevice->base.me_subdevice_query_subdevice_caps = me8254_query_subdevice_caps; subdevice->base.me_subdevice_query_subdevice_caps_args = me8254_query_subdevice_caps_args; return subdevice; }
//int __attribute__((__section__(".text.main"))) int jpProcessos(void) { int mypid,pid,ret; char buffer[16]; int i; int j; int n; int tics; for(j=0; j<80*35; j++) write(1," ",1); PRINTF("\n****JP: Procesos********************\n"); PRINTF("Probamos getpid\n"); mypid=getpid(); proso_itoa(mypid,buffer); PRINTF("PID PADRE: "); PRINTF(buffer); PRINTF("\nCreacion primer proceso \n"); pid=fork(); if (pid==0){ PRINTF("HOLA SOY EL HIJO\n"); proso_itoa(getpid(),buffer); PRINTF("El pid del hijo es "); PRINTF(buffer); PRINTF("\n"); PRINTF("Soy el hijo y ME SUICIDO\n"); exit(); }else if (pid==-1){ PERROR(); FINJP; }else{ PRINTF("SOY EL PADRE: Creacion primer proceso OK\n"); } PRINTF("Creamos una jerarquia: un hijo y un nieto\n"); switch(fork()){ case 0:switch(fork()){ case 0:PRINTF("SOY EL NIETO: "); proso_itoa(getpid(),buffer); PRINTF(buffer); PRINTF("\n"); PRINTF("SOY EL NIETO y me suicido "); exit(); case -1:FINJP; default:PRINTF("SOY EL HIJO: "); proso_itoa(getpid(),buffer); PRINTF(buffer); PRINTF("\n"); PRINTF("SOY EL HIJO y me suicido "); exit(); break; } case -1:FINJP;break; default:break; } PRINTF("Creo N procesos concurrentes\n"); for (i=0;i<4;i++){ if (getpid()==mypid) CERROR(fork()); } for(i=0;i<100;i++){ buffer[0]='A'+(getpid()%4); CERROR(write(1,buffer,1)); } PRINTF("Dejo solo uno\n"); if (getpid()!=mypid){ PRINTF("SOY ");proso_itoa(getpid(),buffer); PRINTF(buffer);PRINTF(" Y Me suicido\n"); exit(); } PRINTF("Solo queda el proceso ");proso_itoa(getpid(),buffer); PRINTF(buffer); PRINTF(" y Deberia ser 0\n"); CHECK( nice(-1), -1, "Probando nice incorrecto(-1)"); CHECK( nice(0), -1, "Probando nice incorrecto(0)"); PRINTF("Probando nice correcto(10):"); n = nice(10); if (n < 0) {PRINTF("ERROR"); PERROR();} else { CHECK( nice(5), 10, "Probando nice correcto(5)"); CHECK( get_stats(-1, &tics), -1, "Probando get_stats pid incorrecto(-1)"); CHECK( get_stats(mypid, (int*)0), -1, "Probando get_stats @tics=0"); CHECK( get_stats(mypid, (int*)10009999999999999999999), -1, "Probando get_stats @tics=1000"); CHECK( get_stats(mypid, &tics), 0, "Probando get_stats OK"); } PRINTF("Creamos N procesos\n"); i=0; #if 1 while(((ret=fork())>0)&& (i<100)){ PRINTF("Creo 1 proceso\n"); i++; } #endif PRINTF("Matamos todos los procesos excepto el primero\n"); if (getpid()!=mypid) exit(); proso_itoa(i,buffer); PRINTF("Hemos creado ");PRINTF(buffer);PRINTF("procesos\n"); PRINTF("\n**************FIN JP**************** PID: "); proso_itoa(getpid(),buffer); PRINTF(buffer); PRINTF("\n"); while(1); }
/* capfs_file_create() */ int capfs_file_create(struct inode *dir, struct dentry *entry, int mode, struct nameidata *nd) { int error = 0, len_dir, len_file; struct inode *inode; struct capfs_meta meta; struct capfs_phys phys; struct capfs_inode *pinode, *parent_pinode = NULL; char *ptr, *namebuf; /* update the statistics */ if(capfs_collect_stats) capfs_vfs_stat.create++; PENTRY; parent_pinode = CAPFS_I(dir); if((error = write_lock_inode(parent_pinode)) < 0) { d_drop(entry); PEXIT; return error; } if((error = may_create(dir, entry, nd))) { PDEBUG(D_FILE, "Not allowed to create file %d\n", error); d_drop(entry); write_unlock_inode(parent_pinode); PEXIT; return error; } PDEBUG(D_FILE, "capfs_file_create called for %ld\n", dir->i_ino); len_dir = strlen(CAPFS_I(dir)->name); len_file = entry->d_name.len; namebuf = (char *) kmalloc(len_dir + len_file + 2, GFP_KERNEL); if (namebuf == NULL) { d_drop(entry); write_unlock_inode(parent_pinode); PEXIT; return -ENOMEM; } /* piece the whole file name together */ ptr = namebuf; strcpy(ptr, CAPFS_I(dir)->name); ptr += len_dir; *ptr = '/'; ptr++; strcpy(ptr, entry->d_name.name); /* do the create */ meta.valid = V_MODE | V_UID | V_GID | V_TIMES; meta.uid = current->fsuid; meta.gid = current->fsgid; meta.mode = mode; meta.mtime = meta.atime = meta.ctime = CURRENT_TIME.tv_sec; phys.blksize = DEFAULT_BLKSIZE; phys.dist = DEFAULT_DIST; phys.nodect = DEFAULT_NODECT; PDEBUG(D_FILE, "capfs_file_create calling ll_capfs_create for %s [atime: %lu] [mtime: %lu] [ctime: %lu]\n", namebuf, meta.atime, meta.mtime, meta.ctime); if ((error = ll_capfs_create(CAPFS_SB(dir->i_sb), namebuf, len_dir + len_file + 1, &meta, &phys)) < 0) { kfree(namebuf); d_drop(entry); write_unlock_inode(parent_pinode); PEXIT; return error; } /* do a lookup so we can fill in the inode. not special */ if ((error = ll_capfs_lookup(CAPFS_SB(dir->i_sb), namebuf, len_dir + len_file + 1, &meta, 0)) < 0) { kfree(namebuf); d_drop(entry); write_unlock_inode(parent_pinode); PEXIT; return error; } /* fill in inode structure and remainder of capfs_inode */ if ((inode = iget(dir->i_sb, meta.handle)) == NULL) { kfree(namebuf); d_drop(entry); write_unlock_inode(parent_pinode); PEXIT; return -ENOMEM; } pinode = CAPFS_I(inode); if (pinode == NULL) { PERROR("found NULL pinode pointer\n"); iput(inode); kfree(namebuf); d_drop(entry); write_unlock_inode(parent_pinode); PEXIT; return -EINVAL; } pinode->handle = inode->i_ino; capfs_meta_to_inode(&meta, inode); pinode->name = namebuf; /* name will be freed when the inode is freed and destroyed */ pinode->super = CAPFS_SB(inode->i_sb); /* Initialize the newly allocated inode's operation vector etc */ capfs_fill_inode(inode, inode->i_mode, 0); PDEBUG(D_FILE, "capfs_file_create: after a lookup name %s [atime: %lu] [mtime: %lu] [ctime: %lu]\n", CAPFS_I(inode)->name, meta.atime, meta.mtime, meta.ctime); d_instantiate(entry, inode); /* Update the ctime and mtime of the parent directory */ capfs_update_inode_time(dir); write_unlock_inode(parent_pinode); PEXIT; return 0; }
/*************************************************************************** * zion_edma_run * @func * Run ZION-NEO EDMA * @args * zion_params_t *params [in/out]: parameters of ZION driver * struct inode *inode [in] : inode * struct file *file [in] : file structure * int rw [in] : command * @return * int * 0 : success * < 0 : error * @comment * * @author * H. Hoshino **************************************************************************/ static int zion_edma_run(zion_params_t * params, struct inode *inode, struct file *file, int rw) { unsigned char ucDmaWnR = 0; #ifdef NEO_WRITEBACK unsigned short usCmdReg = 0; #endif /* NEO_WRITEBACK */ /* Get minor number */ int zion_minor = MINOR(inode->i_rdev); /* Get EDMA parameters */ zion_edma_params_t *edma_prms = (zion_edma_params_t *)file->private_data; /* Check EDMA parameters */ if (NULL == edma_prms) { PERROR("Private data is NULL!(minor:%d)\n", zion_minor); return (-ENODEV); } /* Check argument: rw and set DMA I/O direction */ switch (rw) { case ZION_EDMA_READ: /* for DEBUG */ /* PDEBUG("[CH%d minor%d]EDMA read\n", edma_prms->ch_no, zion_minor); */ ucDmaWnR = ZION_MBUS_EDMA_READ; break; case ZION_EDMA_WRITE: /* for DEBUG */ /* PDEBUG("[CH%d minor%d]EDMA write\n", edma_prms->ch_no, zion_minor); */ ucDmaWnR = ZION_MBUS_EDMA_WRITE; break; default: PERROR("[CH%d minor%d]Invalid I/O direction!(%d)\n", edma_prms->ch_no, zion_minor, rw); return (-EINVAL); } /* end of switch (rw) */ /* Set condition */ edma_prms->condition = ZION_DMAIF_DISPATCH_PENDING; /* Set timed out */ init_timer(&(edma_prms->timer)); edma_prms->timer.function = zion_edma_timeout; edma_prms->timer.data = (unsigned long)params; edma_prms->timer.expires = jiffies + ZION_DMAIF_TIMEOUT; add_timer(&(edma_prms->timer)); /* DMA Run */ mbus_writeb( ((ucDmaWnR | ZION_MBUS_EDMA_RUN | ZION_MBUS_EDMA_OPEN) & 0x0F), MBUS_ADDR(params, ZION_MBUS_EDMA_DMACMD(edma_prms->ch_no) + 1)); #ifdef NEO_WRITEBACK /* for DEBUG -- write back XXX */ usCmdReg = (unsigned short)mbus_readw( MBUS_ADDR(params, ZION_MBUS_EDMA_DMACMD(edma_prms->ch_no)) ); /* PDEBUG( "[CH%d minor%d] Write back DMA RUN: 0x%04X\n", */ /* edma_prms->ch_no, zion_minor, usCmdReg ); */ #endif /* NEO_WRITEBACK */ /* Sleep */ wait_event(edma_prms->zion_dmaif_wait_queue, (edma_prms->condition != ZION_DMAIF_DISPATCH_PENDING)); /* DMA End -- check timedout */ if (ZION_DMAIF_DISPATCH_TIMEOUT == edma_prms->condition) { PERROR("[CH%d minor%d]ZION EDMA Write Timedout!\n", edma_prms->ch_no, zion_minor); /* for DEBUG XXX */ debug_print_debugstts( params, 0, "" ); debug_print_debugstts( params, 2, "" ); debug_print_stts( params, 0, "" ); debug_print_stts( params, 1, "" ); debug_print_stts( params, 2, "" ); return (-ETIME); } /* Success */ return (0); }
/* * Return < 0 on error, 0 if OK, 1 on hangup. */ static int handle_one_cmd(struct run_as_worker *worker) { int ret = 0; struct run_as_data data; ssize_t readlen, writelen; struct run_as_ret sendret; run_as_fct cmd; uid_t prev_euid; memset(&sendret, 0, sizeof(sendret)); sendret.fd = -1; /* * Stage 1: Receive run_as_data struct from the master. * The structure contains the command type and all the parameters needed for * its execution */ readlen = lttcomm_recv_unix_sock(worker->sockpair[1], &data, sizeof(data)); if (readlen == 0) { /* hang up */ ret = 1; goto end; } if (readlen < sizeof(data)) { PERROR("lttcomm_recv_unix_sock error"); ret = -1; goto end; } cmd = run_as_enum_to_fct(data.cmd); if (!cmd) { ret = -1; goto end; } /* * Stage 2: Receive file descriptor from master. * Some commands need a file descriptor as input so if it's needed we * receive the fd using the Unix socket. */ ret = recv_fd_from_master(worker, data.cmd, &data.fd); if (ret < 0) { PERROR("recv_fd_from_master error"); ret = -1; goto end; } prev_euid = getuid(); if (data.gid != getegid()) { ret = setegid(data.gid); if (ret < 0) { sendret._error = true; sendret._errno = errno; PERROR("setegid"); goto write_return; } } if (data.uid != prev_euid) { ret = seteuid(data.uid); if (ret < 0) { sendret._error = true; sendret._errno = errno; PERROR("seteuid"); goto write_return; } } /* * Also set umask to 0 for mkdir executable bit. */ umask(0); /* * Stage 3: Execute the command */ ret = (*cmd)(&data, &sendret); if (ret < 0) { DBG("Execution of command returned an error"); } write_return: ret = cleanup_received_fd(data.cmd, data.fd); if (ret < 0) { ERR("Error cleaning up FD"); goto end; } /* * Stage 4: Send run_as_ret structure to the master. * This structure contain the return value of the command and the errno. */ writelen = lttcomm_send_unix_sock(worker->sockpair[1], &sendret, sizeof(sendret)); if (writelen < sizeof(sendret)) { PERROR("lttcomm_send_unix_sock error"); ret = -1; goto end; } /* * Stage 5: Send file descriptor to the master * Some commands return a file descriptor so if it's needed we pass it back * to the master using the Unix socket. */ ret = send_fd_to_master(worker, data.cmd, sendret.fd); if (ret < 0) { DBG("Sending FD to master returned an error"); goto end; } if (seteuid(prev_euid) < 0) { PERROR("seteuid"); ret = -1; goto end; } ret = 0; end: return ret; }
/*************************************************************************** * zion_dmaif_event * @func * Interruption handler for EDMA * @args * zion_params_t *params [in/out]: parameters of ZION driver * int irq [in] : IRQ number * void *dev_id [in] : Device ID * u16 pci_status[in] : PCI config interrupt status * @return * void * @comment * * @author * H. Hoshino **************************************************************************/ void zion_dmaif_event(zion_params_t * params, int bit, int irq, void *dev_id, u16 pci_status) { unsigned short int_status = 0; unsigned short int_mask = 0; int ch = 0; zion_edma_params_t *edma_prms = NULL; /*** Check EDMA interruption for each channel ***/ for (ch = 0; ch < ZION_EDMA_NR_CH; ++ch) { /* Get interrupt status and mask(enable) */ int_status = (unsigned short)mbus_readw( MBUS_ADDR(params, ZION_MBUS_EDMA_INTSTTS(ch)) ); int_mask = (unsigned short)mbus_readw( MBUS_ADDR(params, ZION_MBUS_EDMA_INTENB(ch)) ); /* Memorize it ! */ params->interrupt_bits.DMA_INT[ch] |= int_status; /* for DEBUG */ /* PDEBUG( "CH%d int_status: 0x%04X, mask: 0x%04X\n", */ /* ch, int_status, int_mask ); */ /** Check interruptions (Common port) **/ if ( int_status & int_mask ) { /* Get EDMA params */ edma_prms = &(ZION_DMAIF_PARAM(params)->port_params[ZION_EDMA_CMN_PORTNO(ch)]); /* for DEBUG */ /* PDEBUG( "[CH%d port%d] Get interruptions!\n", */ /* ch, ZION_EDMA_CMN_PORTNO(ch) ); */ if ( NULL == edma_prms ) { PERROR( "[CH%d port%d] EDMA params is NULL!!\n", ch, ZION_EDMA_CMN_PORTNO(ch) ); mbus_writew( (ZION_MBUS_EDMA_DMADONEINT | ZION_MBUS_EDMA_SYNCFRMINT | ZION_MBUS_EDMA_BUFFINT_MASK | ZION_MBUS_EDMA_ERRINT_MASK), MBUS_ADDR(params, ZION_MBUS_EDMA_INTCLR(ch))); /** Clear interrupt status INT B reg **/ zion_mbus_int_clear(params, Dmaif_Int); return; } /* Set interrupt status */ spin_lock( &(edma_prms->params_lock) ); /* Spin lock */ edma_prms->int_status |= int_status; /* edma_prms->int_status = int_status; */ spin_unlock( &(edma_prms->params_lock) ); /* Unlock spin lock */ /* Wake up */ spin_lock( &(edma_prms->params_lock) ); /* Spin lock */ edma_prms->condition = ZION_DMAIF_DISPATCH_DONE; spin_unlock( &(edma_prms->params_lock) ); /* Unlock spin lock */ wake_up(&(edma_prms->zion_dmaif_wait_queue)); } /** Check sync frame pulse interruption **/ if ( int_status & int_mask & ZION_MBUS_EDMA_SYNCFRMINT ) { /* Get EDMA params */ edma_prms = &(ZION_DMAIF_PARAM(params)->port_params[ZION_EDMA_FRM_PORTNO(ch)]); /* for DEBUG */ /* PDEBUG( "[CH%d port%d] Sync frame pulse!\n", */ /* ch, ZION_EDMA_FRM_PORTNO(ch) ); */ /* Set interrupt status */ spin_lock( &(edma_prms->params_lock) ); /* Spin lock */ if ( 0 == edma_prms->int_status ) { edma_prms->int_status = int_status; } else { /* PDEBUG( "[CH%d port%d] int_status is already set(0x%04X, 0x%04X)!\n", */ /* ch, ZION_EDMA_DMA_PORTNO(ch), edma_prms->int_status, int_status ); */ } spin_unlock( &(edma_prms->params_lock) ); /* Unlock spin lock */ /* Clear interrupt status: sync frame pulse */ mbus_writew(ZION_MBUS_EDMA_SYNCFRMINT, MBUS_ADDR(params, ZION_MBUS_EDMA_INTCLR(ch))); /* Wake up */ spin_lock( &(edma_prms->params_lock) ); /* Spin lock */ edma_prms->condition = ZION_DMAIF_DISPATCH_DONE; spin_unlock( &(edma_prms->params_lock) ); /* Unlock spin lock */ wake_up(&(edma_prms->zion_dmaif_wait_queue)); } /** Check DMA done interruption **/ if ( int_status & int_mask & ZION_MBUS_EDMA_DMADONEINT ) { /* Get EDMA params */ edma_prms = &(ZION_DMAIF_PARAM(params)->port_params[ZION_EDMA_DMA_PORTNO(ch)]); /* for DEBUG */ PDEBUG( "[CH%d port%d] DMA Done!\n", ch, ZION_EDMA_DMA_PORTNO(ch) ); /* PINFO( "[CH%d port%d] DMA Done!\n", */ /* ch, ZION_EDMA_DMA_PORTNO(ch) ); */ /* Stop DMA for G1&G2 transfer mode */ { unsigned char cmd = mbus_readb( MBUS_ADDR(params, (ZION_MBUS_EDMA_DMACMD(ch)+1)) ); mbus_writeb( (cmd & (~0x02)), MBUS_ADDR(params, (ZION_MBUS_EDMA_DMACMD(ch)+1)) ); } /* for DEBUG XXX*/ /* { */ /* unsigned short usPMT = mbus_readw( MBUS_ADDR(params, ZION_MBUS_EDMA_CURRPMT(ch)) ); */ /* PDEBUG( "[CH%d port%d] CurrPMT: 0x%04X\n", */ /* ch, ZION_EDMA_DMA_PORTNO(ch), usPMT ); */ /* } */ spin_lock( &(edma_prms->params_lock) ); /* Spin lock */ /* Set interrupt status */ /* PDEBUG( "[CH%d] int_status: 0x%04X, old: 0x%04X!\n", */ /* ch, int_status, edma_prms->int_status ); */ if ( 0 == edma_prms->int_status ) { edma_prms->int_status = int_status; } else { /* PDEBUG( "[CH%d port%d] int_status is already set(0x%04X, 0x%04X)!\n", */ /* ch, ZION_EDMA_DMA_PORTNO(ch), edma_prms->int_status, int_status ); */ } /* Delete timer */ del_timer_sync(&(edma_prms->timer)); spin_unlock( &(edma_prms->params_lock) ); /* Unlock spin lock */ /* Clear interrupt status: DMA done */ mbus_writew(ZION_MBUS_EDMA_DMADONEINT, MBUS_ADDR(params, ZION_MBUS_EDMA_INTCLR(ch))); /* Wake up */ spin_lock( &(edma_prms->params_lock) ); /* Spin lock */ edma_prms->condition = ZION_DMAIF_DISPATCH_DONE; spin_unlock( &(edma_prms->params_lock) ); /* Unlock spin lock */ wake_up(&(edma_prms->zion_dmaif_wait_queue)); } /** Check error and buffer empty/almost empty/almost full/full interruption **/ if ( int_status & int_mask & (ZION_MBUS_EDMA_BUFFINT_MASK | ZION_MBUS_EDMA_ERRINT_MASK) ) { /* Get EDMA parameters */ edma_prms = &(ZION_DMAIF_PARAM (params)->port_params[ZION_EDMA_BUF_PORTNO(ch)]); /* for DEBUG */ PDEBUG( "[CH%d port%d] Error or warning!\n", ch, ZION_EDMA_BUF_PORTNO(ch) ); /* Set interrupt status */ spin_lock( &(edma_prms->params_lock) ); /* Spin lock */ /* PDEBUG( "[CH%d] int_status: 0x%04X, old: 0x%04X!\n", */ /* ch, int_status, edma_prms->int_status ); */ if ( 0 == edma_prms->int_status ) { edma_prms->int_status = int_status; } else { /* PDEBUG( "[CH%d port%d] int_status is already set(0x%04X, 0x%04X)!\n", */ /* ch, ZION_EDMA_BUF_PORTNO(ch), edma_prms->int_status, int_status ); */ } spin_unlock( &(edma_prms->params_lock) ); /* Unlock spin lock */ /* Clear interrupt status */ mbus_writew((ZION_MBUS_EDMA_BUFFINT_MASK | ZION_MBUS_EDMA_ERRINT_MASK), MBUS_ADDR(params, ZION_MBUS_EDMA_INTCLR(ch))); /* Wake up */ spin_lock( &(edma_prms->params_lock) ); /* Spin lock */ edma_prms->condition = ZION_DMAIF_DISPATCH_DONE; spin_unlock( &(edma_prms->params_lock) ); /* Unlock spin lock */ wake_up(&(edma_prms->zion_dmaif_wait_queue)); } } /* The end of FOR(ch) */ /** Clear interrupt status INT B reg **/ zion_mbus_int_clear(params, Dmaif_Int); /* PDEBUG ("exit %s\n", __FUNCTION__); */ return; }
static int run_as_cmd(struct run_as_worker *worker, enum run_as_cmd cmd, struct run_as_data *data, struct run_as_ret *ret_value, uid_t uid, gid_t gid) { int ret = 0; ssize_t readlen, writelen; /* * If we are non-root, we can only deal with our own uid. */ if (geteuid() != 0) { if (uid != geteuid()) { ret = -1; ret_value->_errno = EPERM; ERR("Client (%d)/Server (%d) UID mismatch (and sessiond is not root)", (int) uid, (int) geteuid()); goto end; } } data->cmd = cmd; data->uid = uid; data->gid = gid; /* * Stage 1: Send the run_as_data struct to the worker process */ writelen = lttcomm_send_unix_sock(worker->sockpair[0], data, sizeof(*data)); if (writelen < sizeof(*data)) { PERROR("Error writing message to run_as"); ret = -1; ret_value->_errno = EIO; goto end; } /* * Stage 2: Send file descriptor to the worker process if needed */ ret = send_fd_to_worker(worker, data->cmd, data->fd); if (ret) { PERROR("do_send_fd error"); ret = -1; ret_value->_errno = EIO; goto end; } /* * Stage 3: Wait for the execution of the command */ /* * Stage 4: Receive the run_as_ret struct containing the return value and * errno */ readlen = lttcomm_recv_unix_sock(worker->sockpair[0], ret_value, sizeof(*ret_value)); if (!readlen) { ERR("Run-as worker has hung-up during run_as_cmd"); ret = -1; ret_value->_errno = EIO; goto end; } else if (readlen < sizeof(*ret_value)) { PERROR("Error reading response from run_as"); ret = -1; ret_value->_errno = errno; goto end; } if (ret_value->_error) { /* Skip stage 5 on error as there will be no fd to receive. */ goto end; } /* * Stage 5: Receive file descriptor if needed */ ret = recv_fd_from_worker(worker, data->cmd, &ret_value->fd); if (ret < 0) { ERR("Error receiving fd"); ret = -1; ret_value->_errno = EIO; } end: return ret; }
int video_reinit(int window_w, int window_h, int fullscreen, int vsync, const char* scaler_name, int scale_factor) { // Tells if something has changed in video settings int changed = 0; // Check scaler if(strcmp(scaler_name, state.scaler_name) != 0) { strncpy(state.scaler_name, scaler_name, sizeof(state.scaler_name)-1); changed = 1; } if(scale_factor != state.scale_factor) { changed = 1; } // Set window size if necessary if(window_w != state.w || window_h != state.h || fullscreen != state.fs) { SDL_SetWindowSize(state.window, window_w, window_h); DEBUG("Changing resolution to %dx%d", window_w, window_h); changed = 1; } // Set fullscreen if necessary if(fullscreen != state.fs) { if(SDL_SetWindowFullscreen(state.window, fullscreen ? SDL_WINDOW_FULLSCREEN : 0) != 0) { PERROR("Could not set fullscreen mode!"); } else { DEBUG("Fullscreen changed!"); } changed = 1; } // Center window if we are changing into or in window mode if(!fullscreen && changed) { SDL_SetWindowPosition(state.window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); } // Check for vsync changes if(vsync != state.vsync) { changed = 1; } // Set video state state.vsync = vsync; state.fs = fullscreen; state.w = window_w; state.h = window_h; // Load scaler if(video_load_scaler(scaler_name, scale_factor)) { DEBUG("Scaler %s plugin not found; using Nearest neighbour scaling."); state.scale_factor = 1; } else { DEBUG("Scaler %s loaded w/ factor %d", scaler_name, scale_factor); state.scale_factor = scale_factor; } // If any settings changed, reinit the screen if(changed) { video_reinit_renderer(); } state.cb.render_reinit(&state); return 0; }
static int run_as_create_worker_no_lock(const char *procname, post_fork_cleanup_cb clean_up_func, void *clean_up_user_data) { pid_t pid; int i, ret = 0; ssize_t readlen; struct run_as_ret recvret; struct run_as_worker *worker; assert(!global_worker); if (!use_clone()) { /* * Don't initialize a worker, all run_as tasks will be performed * in the current process. */ ret = 0; goto end; } worker = zmalloc(sizeof(*worker)); if (!worker) { ret = -ENOMEM; goto end; } worker->procname = strdup(procname); if (!worker->procname) { ret = -ENOMEM; goto error_procname_alloc; } /* Create unix socket. */ if (lttcomm_create_anon_unix_socketpair(worker->sockpair) < 0) { ret = -1; goto error_sock; } /* Fork worker. */ pid = fork(); if (pid < 0) { PERROR("fork"); ret = -1; goto error_fork; } else if (pid == 0) { /* Child */ reset_sighandler(); set_worker_sighandlers(); if (clean_up_func) { if (clean_up_func(clean_up_user_data) < 0) { ERR("Run-as post-fork clean-up failed, exiting."); exit(EXIT_FAILURE); } } /* Just close, no shutdown. */ if (close(worker->sockpair[0])) { PERROR("close"); exit(EXIT_FAILURE); } /* * Close all FDs aside from STDIN, STDOUT, STDERR and sockpair[1] * Sockpair[1] is used as a control channel with the master */ for (i = 3; i < sysconf(_SC_OPEN_MAX); i++) { if (i != worker->sockpair[1]) { (void) close(i); } } worker->sockpair[0] = -1; ret = run_as_worker(worker); if (lttcomm_close_unix_sock(worker->sockpair[1])) { PERROR("close"); ret = -1; } worker->sockpair[1] = -1; free(worker->procname); free(worker); LOG(ret ? PRINT_ERR : PRINT_DBG, "run_as worker exiting (ret = %d)", ret); exit(ret ? EXIT_FAILURE : EXIT_SUCCESS); } else { /* Parent */ /* Just close, no shutdown. */ if (close(worker->sockpair[1])) { PERROR("close"); ret = -1; goto error_fork; } worker->sockpair[1] = -1; worker->pid = pid; /* Wait for worker to become ready. */ readlen = lttcomm_recv_unix_sock(worker->sockpair[0], &recvret, sizeof(recvret)); if (readlen < sizeof(recvret)) { ERR("readlen: %zd", readlen); PERROR("Error reading response from run_as at creation"); ret = -1; goto error_fork; } global_worker = worker; } end: return ret; /* Error handling. */ error_fork: for (i = 0; i < 2; i++) { if (worker->sockpair[i] < 0) { continue; } if (lttcomm_close_unix_sock(worker->sockpair[i])) { PERROR("close"); } worker->sockpair[i] = -1; } error_sock: free(worker->procname); error_procname_alloc: free(worker); return ret; }
int drct_read_modify_write(spd_dev_t *dev) { unsigned long flags = 0; int retval; u32 sector; int wsize; struct request *req = dev->bdev->req; PTRACE(); dev->bdev->hard_nr_sectors = req->hard_nr_sectors; dev->bdev->rmw_sector = req->sector; dev->bdev->rmw_count = req->hard_nr_sectors; dev->bdev->rmw_sg = dev->bdev->sg; dev->bdev->rmw_sg_offset = 0; dev->bdev->rmw_bio = req->bio; dev->bdev->rmw_bio_offset = 0; dev->bdev->rmw_bvec_offset = 0; dev->bdev->rmw_bio_idx = req->bio->bi_idx; dev->retry = dev->dma_retry; dev->timeout = dev->dma_timeout; if(spd_cache_is_dirty(dev->cache)){ dev->complete_handler = drct_rmw_write_complete_handler; spd_cache_prepare(dev, SPD_DIR_WRITE); retval = spd_write_sector(dev, dev->cache->sector, dev->cache->n_sector, dev->cache->sg); if(unlikely(retval < 0)){ PERROR("<spd%c>spd_write_sector() failed(%d)", dev->id+'a', retval); goto ABORT; } return retval; } sector = dev->bdev->rmw_sector; wsize = spd_get_wsize(dev, sector); if(unlikely(wsize < 0)){ PERROR("<spd%c>spd_get_wsize() failed sector=%08x", dev->id+'a', sector); retval = -EINVAL; goto ABORT; } sector = align_sector(sector, wsize, spd_get_sector_offset(dev, sector)); if(sector == dev->bdev->rmw_sector && dev->bdev->rmw_count >= wsize){ dev->cache->sector = sector; dev->cache->n_sector = wsize; retval = drct_make_rmw_sg(dev); if(unlikely(retval < 0)){ PERROR("<spd%c>drct_make_rmw_sg() failed(%d)", dev->id+'a', retval); goto ABORT; } dev->complete_handler = drct_rmw_write_complete_handler; retval = spd_write_sector(dev, sector, wsize, dev->sg); if(unlikely(retval < 0)){ PERROR("<spd%c>spd_write_sector() failed(%d)", dev->id+'a', retval); goto ABORT; } dev->cache->sector = (u32)-1; spd_cache_clr_dirty(dev->cache); return 0; } dev->cache->sector = sector; dev->cache->n_sector = wsize; dev->complete_handler = drct_rmw_read_complete_handler; spd_cache_prepare(dev, SPD_DIR_READ); retval = spd_read_sector(dev, dev->cache->sector, dev->cache->n_sector, dev->cache->sg); if(unlikely(retval < 0)){ PERROR("<spd%c>spd_read_sector() failed(%d)", dev->id+'a', retval); goto ABORT; } return 0; ABORT: PINFO("<spd%c>ABORT at %s", dev->id+'a', __FUNCTION__); if(dev->cache){ dev->cache->sector = (u32)-1; spd_cache_clr_dirty(dev->cache); } spin_lock_irqsave(&dev->bdev->rq_lock, flags); bdev_end_request(dev, retval); spin_unlock_irqrestore(&dev->bdev->rq_lock, flags); dev->complete_handler = NULL; spd_io_unlock(dev); return retval; }
int zion_set_params(struct zionvga_reset_arg *reset_arg) { u16 reg = 0; int pal_line = reset_arg->pal_line; int spl_line = reset_arg->spl_line; zion_params_t *params = find_zion(0); if(params == NULL){ return -ENODEV; } reg = mbus_readw(MBUS_ADDR(params,ZIONVGA_VGA_SETTING)); reg &= VGA_RSTR_EN; //Don't touch VGA_RSTR_EN bit (It should be set by TX) if(pal_line==576) { reg |= PAL_LINE_SEL; ZIONVGA_Y_RES = 576; } else if(pal_line==480) { reg &= ~PAL_LINE_SEL; ZIONVGA_Y_RES = 480; } else { PERROR("Unsupported VGA SIZE : PAL-Line=%d",pal_line); return -EINVAL; } if(spl_line==720) { reg |= SPL_SEL; ZIONVGA_X_RES = 720; } else if(spl_line==640) { reg &= ~SPL_SEL; ZIONVGA_X_RES = 640; } else { PERROR("Unsupported VGA SIZE : SPL-Line=%d",spl_line); return -EINVAL; } #if defined(CONFIG_P2PF_K240) || defined(CONFIG_P2PF_K202) || defined(CONFIG_P2PF_K246A) reg |= (CSC_EN); #else reg |= (CSC_EN|TRS_ON); #endif //CONFIG_P2PF_K240 || CONFIG_P2PF_K246A mbus_writew(reg, MBUS_ADDR(params,ZIONVGA_VGA_SETTING)); // Just for assurance reg = mbus_readw(MBUS_ADDR(params,ZIONVGA_VGA_SETTING)); zionvga_encode_var( &default_var ); zion_fb_info.fb_info.var = default_var; return 0; }
static int drct_make_rmw_sg(spd_dev_t *dev) { spd_scatterlist_t *sg = dev->sg; struct bio *bio = dev->bdev->rmw_bio; int n,i; int len1, len2, len3; u8 *virt_addr; u32 b_size, size, offset, b_offset; u32 c_size; PTRACE(); PINFO("<spd%c>cache_sector=%08x, rmw_sector=%08x, rmw_count=%04x", dev->id+'a', dev->cache->sector, dev->bdev->rmw_sector, dev->bdev->rmw_count); PCOMMAND("<spd%c>USE_CACHE id=%02d, cache_sector=%08x, rmw_sector=%08x, rmw_count=%04x", dev->id+'a', dev->cache->id, dev->cache->sector, dev->bdev->rmw_sector, dev->bdev->rmw_count); n = 0; len1 = (dev->bdev->rmw_sector - dev->cache->sector); if(len1 + dev->bdev->rmw_count > dev->cache->n_sector){ len2 = dev->cache->n_sector - len1; len3 = 0; dev->bdev->rmw_count -= len2; dev->bdev->rmw_sector = dev->cache->sector+dev->cache->n_sector; } else { len2 = dev->bdev->rmw_count; len3 = dev->cache->n_sector -len2 - len1; dev->bdev->rmw_count = 0; dev->bdev->rmw_sector = (u32)-1; }; PINFO("<spd%c>len1=%d, len2=%d, len3=%d", dev->id+'a', len1, len2, len3); c_size = dev->cache->n_sector*SPD_HARDSECT_SIZE; if(c_size > SPD_CACHE_BUFFER_SIZE){ c_size = SPD_CACHE_BUFFER_SIZE; } if (len1 > 0){ i = 0; size = len1*SPD_HARDSECT_SIZE; while(size > 0){ virt_addr = dev->cache->buffer[i++]; b_size = (size<c_size?size:c_size); n = set_sg_entry(sg, n, virt_to_bus(virt_addr), b_size); if(unlikely(n < 0)){ PERROR("<spd%c>set_sg_entry() failed(%d)", dev->id+'a', n); return n; } size -= b_size; } } if(len2 > 0){ size = len2*SPD_HARDSECT_SIZE; bio = dev->bdev->rmw_bio; while(size > 0){ b_size = bio->bi_size - dev->bdev->rmw_bio_offset; PINFO("b_size=%lx size=%lx maxvec=%d", (unsigned long)b_size, (unsigned long)size, bio->bi_max_vecs); if(b_size > size){ PINFO("=="); n = drct_set_sg_entry(dev, n, bio, size); dev->bdev->rmw_bio_offset += size; break; } n = drct_set_sg_entry(dev, n, bio, b_size); if(unlikely(n < 0)){ PERROR("<spd%c>drct_set_sg_entry() failed(%d)",dev->id+'a', n); return n; } size -= b_size; bio = bio->bi_next; dev->bdev->rmw_bio = bio; dev->bdev->rmw_bio_offset = 0; dev->bdev->rmw_bvec_offset = 0; dev->bdev->rmw_bio_idx = bio ? bio->bi_idx : 0; } } if (len3 > 0){ size = len3*SPD_HARDSECT_SIZE; offset = (len1+len2)*SPD_HARDSECT_SIZE; b_offset = offset%c_size; b_size = c_size - b_offset; i = offset/c_size; virt_addr = dev->cache->buffer[i++] + b_offset; n = set_sg_entry(sg, n, virt_to_bus(virt_addr), b_size); if(unlikely(n < 0)){ PERROR("<spd%c>set_sg_entry() failed(%d)",dev->id+'a', n); return n; } size -= b_size; while(size > 0){ virt_addr = dev->cache->buffer[i++]; n = set_sg_entry(sg, n, virt_to_bus(virt_addr), c_size); if(unlikely(n < 0)){ PERROR("<spd%c>set_sg_entry() failed(%d)",dev->id+'a', n); return n; } size -= c_size; } } sg[n-1].count |= cpu_to_le32(SPD_SG_ENDMARK); dev->sg_n_entry = n; spd_dma_cache_wback(dev->dev, sg, sizeof(spd_scatterlist_t)*n); PRINT_SG(sg, n, dev->id); return 0; }
static int zionvga_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) { struct zionvga_init_arg init_arg; struct zionvga_reset_arg reset_arg; struct zionvga_phase_arg phase_arg; u16 color; u16 *pixel_p; unsigned long i; int ret, frame; switch(cmd){ case ZIONVGA_IOC_HARDRESET: if (copy_from_user(&reset_arg, (void *)arg, sizeof(struct zionvga_reset_arg))) { PERROR("failed copy_from_user()\n"); return -EFAULT; } PERROR("IOCTL HARDRESET\n"); return zion_set_params(&reset_arg); case ZIONVGA_IOC_RSTR_STOP: return zionvga_rstr_disable(); case ZIONVGA_IOC_RSTR_START: return zionvga_rstr_enable(); case ZIONVGA_IOC_INIT_FB: PDEBUG("IOCTL INIT_FB\n"); if (!access_ok(VERIFY_READ, (void *)arg, sizeof(struct zionvga_init_arg))) { PERROR("failed access_ok()\n"); return -EFAULT; } if (copy_from_user(&init_arg, (void *)arg, sizeof(struct zionvga_init_arg))) { PERROR("failed copy_from_user()\n"); return -EFAULT; } color = ((init_arg.red & 0x1f) << 11) | ((init_arg.green & 0x3f) << 5) | (init_arg.blue & 0x1f); pixel_p = (u16 *)zion_fb_info.ram_address; for (i = 0; i < ZIONVGA_VRAM_SIZE; i += ZIONVGA_BYTES_PER_PIXEL) { *pixel_p = color; pixel_p++; } return 0; case ZIONVGA_IOC_PURGE_FB: PDEBUG("IOCTL PURGE_FB\n"); ret = zionvga_start_dma(); if(ret < 0){ return ret; } else{ if(copy_to_user((void*)arg, &ret, sizeof(int))) { PERROR("failed copy_to_user()\n"); return -EFAULT; } return 0; } case ZIONVGA_IOC_UPDATE: if (copy_from_user(&frame, (void *)arg, sizeof(int))) { PERROR("failed copy_from_user()\n"); return -EFAULT; } return zionvga_image_reflection(frame); case ZIONVGA_IOC_INIT_PHASE: if(copy_from_user(&phase_arg, (void *)arg, sizeof(struct zionvga_phase_arg))) { PERROR("failed copy_from_user()\n"); return -EFAULT; } return zionvga_init_phase(&phase_arg); default: PERROR("invalid argument\n"); return -EINVAL; } }
/* on socket options, see the 'socket(7)' and 'ip' man pages */ Boolean netInit(NetPath * netPath, RunTimeOpts * rtOpts, PtpClock * ptpClock) { int temp, i; struct in_addr interfaceAddr, netAddr; struct sockaddr_in addr; struct ip_mreq imr; char addrStr[NET_ADDRESS_LENGTH]; char *s; DBG("netInit\n"); /* open sockets */ if ((netPath->eventSock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0 || (netPath->generalSock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { PERROR("failed to initalize sockets"); return FALSE; } /* find a network interface */ if (!(interfaceAddr.s_addr = findIface(rtOpts->ifaceName, &ptpClock->port_communication_technology, ptpClock->port_uuid_field, netPath))) return FALSE; temp = 1; /* allow address reuse */ if (setsockopt(netPath->eventSock, SOL_SOCKET, SO_REUSEADDR, &temp, sizeof(int)) < 0 || setsockopt(netPath->generalSock, SOL_SOCKET, SO_REUSEADDR, &temp, sizeof(int)) < 0) { DBG("failed to set socket reuse\n"); } /* bind sockets */ /* * need INADDR_ANY to allow receipt of multi-cast and uni-cast * messages */ addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(PTP_EVENT_PORT); if (bind(netPath->eventSock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) { PERROR("failed to bind event socket"); return FALSE; } addr.sin_port = htons(PTP_GENERAL_PORT); if (bind(netPath->generalSock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) { PERROR("failed to bind general socket"); return FALSE; } /* set general and port address */ *(Integer16 *) ptpClock->event_port_address = PTP_EVENT_PORT; *(Integer16 *) ptpClock->general_port_address = PTP_GENERAL_PORT; /* send a uni-cast address if specified (useful for testing) */ if (rtOpts->unicastAddress[0]) { if (!inet_aton(rtOpts->unicastAddress, &netAddr)) { ERROR("failed to encode uni-cast address: %s\n", rtOpts->unicastAddress); return FALSE; } netPath->unicastAddr = netAddr.s_addr; } else netPath->unicastAddr = 0; /* resolve PTP subdomain */ if (!lookupSubdomainAddress(rtOpts->subdomainName, addrStr)) return FALSE; if (!inet_aton(addrStr, &netAddr)) { ERROR("failed to encode multi-cast address: %s\n", addrStr); return FALSE; } netPath->multicastAddr = netAddr.s_addr; s = addrStr; for (i = 0; i < SUBDOMAIN_ADDRESS_LENGTH; ++i) { ptpClock->subdomain_address[i] = strtol(s, &s, 0); if (!s) break; ++s; } /* multicast send only on specified interface */ imr.imr_multiaddr.s_addr = netAddr.s_addr; imr.imr_interface.s_addr = interfaceAddr.s_addr; if (setsockopt(netPath->eventSock, IPPROTO_IP, IP_MULTICAST_IF, &imr.imr_interface.s_addr, sizeof(struct in_addr)) < 0 || setsockopt(netPath->generalSock, IPPROTO_IP, IP_MULTICAST_IF, &imr.imr_interface.s_addr, sizeof(struct in_addr)) < 0) { PERROR("failed to enable multi-cast on the interface"); return FALSE; } /* join multicast group (for receiving) on specified interface */ if (setsockopt(netPath->eventSock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr, sizeof(struct ip_mreq)) < 0 || setsockopt(netPath->generalSock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr, sizeof(struct ip_mreq)) < 0) { PERROR("failed to join the multi-cast group"); return FALSE; } /* set socket time-to-live */ if (setsockopt(netPath->eventSock, IPPROTO_IP, IP_MULTICAST_TTL, &rtOpts->ttl, sizeof(int)) < 0 || setsockopt(netPath->generalSock, IPPROTO_IP, IP_MULTICAST_TTL, &rtOpts->ttl, sizeof(int)) < 0) { PERROR("failed to set the multi-cast time-to-live"); return FALSE; } /* enable loopback */ temp = 1; if (setsockopt(netPath->eventSock, IPPROTO_IP, IP_MULTICAST_LOOP, &temp, sizeof(int)) < 0 || setsockopt(netPath->generalSock, IPPROTO_IP, IP_MULTICAST_LOOP, &temp, sizeof(int)) < 0) { PERROR("failed to enable multi-cast loopback"); return FALSE; } /* make timestamps available through recvmsg() */ temp = 1; #if defined(linux) if (setsockopt(netPath->eventSock, SOL_SOCKET, SO_TIMESTAMP, &temp, sizeof(int)) < 0 || setsockopt(netPath->generalSock, SOL_SOCKET, SO_TIMESTAMP, &temp, sizeof(int)) < 0) { #else /* BSD */ if (setsockopt(netPath->eventSock, SOL_SOCKET, SO_BINTIME, &temp, sizeof(int)) < 0 || setsockopt(netPath->generalSock, SOL_SOCKET, SO_BINTIME, &temp, sizeof(int)) < 0) { #endif /* linux or BSD */ PERROR("failed to enable receive time stamps"); return FALSE; } return TRUE; } /* shut down the UDP stuff */ Boolean netShutdown(NetPath * netPath) { struct ip_mreq imr; imr.imr_multiaddr.s_addr = netPath->multicastAddr; imr.imr_interface.s_addr = htonl(INADDR_ANY); setsockopt(netPath->eventSock, IPPROTO_IP, IP_DROP_MEMBERSHIP, &imr, sizeof(struct ip_mreq)); setsockopt(netPath->generalSock, IPPROTO_IP, IP_DROP_MEMBERSHIP, &imr, sizeof(struct ip_mreq)); netPath->multicastAddr = 0; netPath->unicastAddr = 0; if (netPath->eventSock > 0) close(netPath->eventSock); netPath->eventSock = -1; if (netPath->generalSock > 0) close(netPath->generalSock); netPath->generalSock = -1; return TRUE; } int netSelect(TimeInternal * timeout, NetPath * netPath) { int ret, nfds; fd_set readfds; struct timeval tv, *tv_ptr; if (timeout < 0) return FALSE; FD_ZERO(&readfds); FD_SET(netPath->eventSock, &readfds); FD_SET(netPath->generalSock, &readfds); if (timeout) { tv.tv_sec = timeout->seconds; tv.tv_usec = timeout->nanoseconds / 1000; tv_ptr = &tv; } else tv_ptr = 0; if (netPath->eventSock > netPath->generalSock) nfds = netPath->eventSock; else nfds = netPath->generalSock; ret = select(nfds + 1, &readfds, 0, 0, tv_ptr) > 0; if (ret < 0) { if (errno == EAGAIN || errno == EINTR) return 0; } return ret; }
int init_zion_vga(void) { int ret; zion_params_t *params = find_zion(0); u32 off_addr; if(params == NULL){ return -ENODEV; } PINFO("ZION VGA Frame Buffer Driver Installed.\n"); PDEBUG("compiled "__DATE__" "__TIME__"\n"); //Check Fireball if((params->revision & 0xF000) == 0xF000){ PINFO("This is fireball! ZION VGA cannot be used!!\n"); return 0; } #ifdef CONFIG_ZION_FB_SETUP PINFO("Setting FB Address ... %p and %p\n", (void *)CONFIG_ZION_FB_FIRST_ADDR, (void *)CONFIG_ZION_FB_SECOND_ADDR); mbus_writel(CONFIG_ZION_FB_FIRST_ADDR, MBUS_ADDR(params,ZIONVGA_BUFFER_BASE_ADDRESS_0)); mbus_writel(CONFIG_ZION_FB_SECOND_ADDR, MBUS_ADDR(params,ZIONVGA_BUFFER_BASE_ADDRESS_1)); #endif //CONFIG_ZION_FB_SETUP //Get VGA FB Region off_addr = mbus_readl(MBUS_ADDR(params, ZIONVGA_BUFFER_BASE_ADDRESS_0)); dma_direction[0] = params->whole_sdram_addr + off_addr; PINFO("FB1_BUS_ADDR:%p\n",(void *)dma_direction[0]); off_addr = mbus_readl(MBUS_ADDR(params, ZIONVGA_BUFFER_BASE_ADDRESS_1)); dma_direction[1] = params->whole_sdram_addr + off_addr; PINFO("FB2_BUS_ADDR:%p\n",(void *)dma_direction[1]); memset(&zion_fb_info, 0, sizeof(struct zion_vga_info)); zion_fb_info.ram_address = (unsigned long)__get_free_pages(GFP_KERNEL | __GFP_DMA, ZIONVGA_VRAM_ORDER); if(!zion_fb_info.ram_address){ PERROR("failed get_free_pages(): ram_address\n"); ret = -ENOMEM; goto fail_gfp_fb; } memset((void *)zion_fb_info.ram_address, 0, ZIONVGA_VRAM_SIZE); PDEBUG("ram_address = 0x%08lx (virtual)\n", (unsigned long)zion_fb_info.ram_address); PDEBUG("ram_address = 0x%08lx (physical)\n", virt_to_bus((void *)zion_fb_info.ram_address)); zion_fb_info.fb_info.screen_base = (void __iomem *)zion_fb_info.ram_address; zion_fb_info.fb_info.fbops = &zion_vga_ops; //setup var_screen_info zionvga_encode_var(&default_var); zion_fb_info.fb_info.var = default_var; zionvga_encode_fix(&zion_fb_info.fb_info.fix); zion_fb_info.fb_info.par = &zion_current_par; // This should give a reasonable default video mode ret = fb_alloc_cmap(&zion_fb_info.fb_info.cmap, 256, 0); if(ret){ PERROR( "failed fb_alloc_cmap()\n" ); ret = -ENOMEM; goto fail_alloc_cmap; } if(register_framebuffer(&zion_fb_info.fb_info) < 0){ PERROR("failed register_framebuffer()\n"); ret = -EINVAL; goto fail_reg_fb; } PINFO("fb%d: %s frame buffer device\n", zion_fb_info.fb_info.node, zion_fb_info.fb_info.fix.id); return 0; fail_reg_fb: fb_dealloc_cmap( &zion_fb_info.fb_info.cmap); fail_alloc_cmap: free_pages(zion_fb_info.ram_address, ZIONVGA_VRAM_ORDER); fail_gfp_fb: return ret; }
static int me6000_dio_io_single_write(me_subdevice_t * subdevice, struct file *filep, int channel, int value, int time_out, int flags) { me6000_dio_subdevice_t *instance; int err = ME_ERRNO_SUCCESS; uint8_t mode; uint8_t byte; PDEBUG("executed.\n"); instance = (me6000_dio_subdevice_t *) subdevice; ME_SUBDEVICE_ENTER spin_lock(&instance->subdevice_lock); spin_lock(instance->ctrl_reg_lock); switch (flags) { case ME_IO_SINGLE_TYPE_DIO_BIT: if ((channel >= 0) && (channel < 8)) { mode = inb(instance-> ctrl_reg) & ((ME6000_DIO_CTRL_BIT_MODE_0 | ME6000_DIO_CTRL_BIT_MODE_1) << (instance->dio_idx * 2)); if (mode == (ME6000_DIO_CTRL_BIT_MODE_0 << (instance->dio_idx * 2))) { byte = inb(instance->port_reg) & 0x00FF; if (value) byte |= 0x1 << channel; else byte &= ~(0x1 << channel); outb(byte, instance->port_reg); } else { PERROR("Port not in output or input mode.\n"); err = ME_ERRNO_PREVIOUS_CONFIG; } } else { PERROR("Invalid bit number specified.\n"); err = ME_ERRNO_INVALID_CHANNEL; } break; case ME_IO_SINGLE_NO_FLAGS: case ME_IO_SINGLE_TYPE_DIO_BYTE: if (channel == 0) { mode = inb(instance-> ctrl_reg) & ((ME6000_DIO_CTRL_BIT_MODE_0 | ME6000_DIO_CTRL_BIT_MODE_1) << (instance->dio_idx * 2)); if (mode == (ME6000_DIO_CTRL_BIT_MODE_0 << (instance->dio_idx * 2))) { outb(value, instance->port_reg); } else { PERROR("Port not in output or input mode.\n"); err = ME_ERRNO_PREVIOUS_CONFIG; } } else { PERROR("Invalid byte number specified.\n"); err = ME_ERRNO_INVALID_CHANNEL; } break; default: PERROR("Invalid flags specified.\n"); err = ME_ERRNO_INVALID_FLAGS; } spin_unlock(instance->ctrl_reg_lock); spin_unlock(&instance->subdevice_lock); ME_SUBDEVICE_EXIT; return err; }
int me8254_io_single_read(struct me_subdevice* subdevice, struct file* filep, int channel, int* value, int time_out, int flags) { me8254_subdevice_t* instance; uint8_t ctrl = ME8254_CTRL_TLO; uint8_t lo_byte = 0; uint8_t hi_byte = 0; uint8_t status_byte = 0; int err = ME_ERRNO_SUCCESS; PDEBUG("executed.\n"); if (flags) { PERROR("Invalid flags specified. Must be ME_IO_SINGLE_TYPE_NO_FLAGS.\n"); return ME_ERRNO_INVALID_FLAGS; } if (channel) { PERROR("Invalid channel. Must be 0.\n"); return ME_ERRNO_INVALID_CHANNEL; } instance = (me8254_subdevice_t *) subdevice; ME_SUBDEVICE_ENTER; ME_SUBDEVICE_LOCK; ME_SPIN_LOCK(instance->ctrl_reg_lock); switch (instance->ctr_idx) { case 0: ctrl |= ME8254_CTRL_SC0; break; case 1: ctrl |= ME8254_CTRL_SC1; break; default: ctrl |= ME8254_CTRL_SC2; } me_writeb(instance->base.dev, ME8254_STATUS_CMD | (0x2 << instance->ctr_idx), instance->ctrl_reg); me_readb(instance->base.dev, &status_byte, instance->val_reg); if (status_byte & 0x40) { PINFO("NULL count detected.\n"); err = ME_ERRNO_SUBDEVICE_NOT_RUNNING; goto EXIT; } me_writeb(instance->base.dev, ctrl, instance->ctrl_reg); me_readb(instance->base.dev, &lo_byte, instance->val_reg); me_readb(instance->base.dev, &hi_byte, instance->val_reg); EXIT: ME_SPIN_UNLOCK(instance->ctrl_reg_lock); *value = (int)lo_byte | ((int)hi_byte << 8); ME_SUBDEVICE_UNLOCK; ME_SUBDEVICE_EXIT; return err; }