Beispiel #1
0
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;
}
Beispiel #2
0
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);
}
Beispiel #3
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
}
Beispiel #4
0
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;
}
Beispiel #5
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);
}
Beispiel #6
0
/***************************************************************************
 * 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;
}
Beispiel #7
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");
		}
	}
}
Beispiel #8
0
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(&params, 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(&params, &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;
}
Beispiel #9
0
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;
}
Beispiel #10
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;
}
Beispiel #11
0
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;
}
Beispiel #12
0
/* 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;
		}
	}
}
Beispiel #13
0
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;
		}
	}
}
Beispiel #14
0
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;
}
Beispiel #15
0
//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); 
}
Beispiel #16
0
/* 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;
}	     
Beispiel #17
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);
}
Beispiel #18
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;
}
Beispiel #19
0
/***************************************************************************
 * 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;
}
Beispiel #20
0
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;
}
Beispiel #21
0
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;
}
Beispiel #22
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;
}
Beispiel #23
0
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;
}
Beispiel #24
0
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;
}
Beispiel #25
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;
}
Beispiel #26
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;
	}
}
Beispiel #27
0
/* 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;
}
Beispiel #28
0
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;
}
Beispiel #30
0
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;
}