Ejemplo n.º 1
0
/* the real citty_ioctl function.
 * The above is done to get the small functions*/
static int citty_ioctl(struct tty_struct *tty,
		       unsigned int cmd, unsigned long arg)
{
	struct file *file = NULL;
	F_ENTER();

	switch (cmd) {
	case TIOCGSERIAL:
		return citty_ioctl_tiocgserial(tty, file, cmd, arg);
	case TIOCMIWAIT:
		return citty_ioctl_tiocmiwait(tty, file, cmd, arg);
	case TIOCGICOUNT:
		return citty_ioctl_tiocgicount(tty, file, cmd, arg);
#ifndef TCGETS2
	case TCSETS:
		if (user_termios_to_kernel_termios(&tty->termios,
				(struct termios __user *) arg))
			return -EFAULT;
		else
			return 0;
	case TCGETS:
		if (kernel_termios_to_user_termios(
				(struct termios __user *)arg, &tty->termios))
			return -EFAULT;
		else
			return 0;
#else
	case TCSETS:
		if (user_termios_to_kernel_termios_1(&tty->termios,
				(struct termios __user *) arg))
			return -EFAULT;
		else
			return 0;
	case TCSETS2:
		if (user_termios_to_kernel_termios(&tty->termios,
				(struct termios2 __user *) arg))
			return -EFAULT;
		else
			return 0;
	case TCGETS:
		if (kernel_termios_to_user_termios_1(
				(struct termios __user *)arg, &tty->termios))
			return -EFAULT;
		else
			return 0;
	case TCGETS2:
		if (kernel_termios_to_user_termios(
				(struct termios2 __user *)arg, &tty->termios))
			return -EFAULT;
		else
			return 0;
#endif
	case TCSETSF:             /* 0x5404 */
	case TCSETAF:             /* 0x5408 */

		return 0;         /* has to return zero for qtopia to work */
	default:
		PDEBUG("citty_ioctl cmd: %d.\n", cmd);
		return -ENOIOCTLCMD;           /* for PPPD to work? */

		break;
	}

	F_LEAVE();

}
Ejemplo n.º 2
0
static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
				 void * (*start_routine)(void *), void *arg,
				 sigset_t * mask, int father_pid,
				 int report_events,
				 td_thr_events_t *event_maskp)
{
  size_t sseg;
  int pid;
  pthread_descr new_thread;
  char * new_thread_bottom;
  pthread_t new_thread_id;
  char *guardaddr = NULL;
  size_t guardsize = 0;
  int pagesize = getpagesize();
  int saved_errno = 0;

  /* First check whether we have to change the policy and if yes, whether
     we can  do this.  Normally this should be done by examining the
     return value of the sched_setscheduler call in pthread_start_thread
     but this is hard to implement.  FIXME  */
  if (attr != NULL && attr->__schedpolicy != SCHED_OTHER && geteuid () != 0)
    return EPERM;
  /* Find a free segment for the thread, and allocate a stack if needed */
  for (sseg = 2; ; sseg++)
    {
      if (sseg >= PTHREAD_THREADS_MAX)
	return EAGAIN;
      if (__pthread_handles[sseg].h_descr != NULL)
	continue;
      if (pthread_allocate_stack(attr, thread_segment(sseg), pagesize,
                                 &new_thread, &new_thread_bottom,
                                 &guardaddr, &guardsize) == 0)
        break;
#ifndef __ARCH_USE_MMU__
      else
        /* When there is MMU, mmap () is used to allocate the stack. If one
         * segment is already mapped, we should continue to see if we can
         * use the next one. However, when there is no MMU, malloc () is used.
         * It's waste of CPU cycles to continue to try if it fails.  */
        return EAGAIN;
#endif
    }
  __pthread_handles_num++;
  /* Allocate new thread identifier */
  pthread_threads_counter += PTHREAD_THREADS_MAX;
  new_thread_id = sseg + pthread_threads_counter;
  /* Initialize the thread descriptor.  Elements which have to be
     initialized to zero already have this value.  */
  new_thread->p_tid = new_thread_id;
  new_thread->p_lock = &(__pthread_handles[sseg].h_lock);
  new_thread->p_cancelstate = PTHREAD_CANCEL_ENABLE;
  new_thread->p_canceltype = PTHREAD_CANCEL_DEFERRED;
  new_thread->p_errnop = &new_thread->p_errno;
  new_thread->p_h_errnop = &new_thread->p_h_errno;
#ifdef __UCLIBC_HAS_XLOCALE__
  /* Initialize thread's locale to the global locale. */
  new_thread->locale = __global_locale;
#endif /* __UCLIBC_HAS_XLOCALE__ */
  new_thread->p_guardaddr = guardaddr;
  new_thread->p_guardsize = guardsize;
  new_thread->p_self = new_thread;
  new_thread->p_nr = sseg;
  /* Initialize the thread handle */
  __pthread_init_lock(&__pthread_handles[sseg].h_lock);
  __pthread_handles[sseg].h_descr = new_thread;
  __pthread_handles[sseg].h_bottom = new_thread_bottom;
  /* Determine scheduling parameters for the thread */
  new_thread->p_start_args.schedpolicy = -1;
  if (attr != NULL) {
    new_thread->p_detached = attr->__detachstate;
    new_thread->p_userstack = attr->__stackaddr_set;

    switch(attr->__inheritsched) {
    case PTHREAD_EXPLICIT_SCHED:
      new_thread->p_start_args.schedpolicy = attr->__schedpolicy;
      memcpy (&new_thread->p_start_args.schedparam, &attr->__schedparam,
	      sizeof (struct sched_param));
      break;
    case PTHREAD_INHERIT_SCHED:
      new_thread->p_start_args.schedpolicy = sched_getscheduler(father_pid);
      sched_getparam(father_pid, &new_thread->p_start_args.schedparam);
      break;
    }
    new_thread->p_priority =
      new_thread->p_start_args.schedparam.sched_priority;
  }
  /* Finish setting up arguments to pthread_start_thread */
  new_thread->p_start_args.start_routine = start_routine;
  new_thread->p_start_args.arg = arg;
  new_thread->p_start_args.mask = *mask;
  /* Raise priority of thread manager if needed */
  __pthread_manager_adjust_prio(new_thread->p_priority);
  /* Do the cloning.  We have to use two different functions depending
     on whether we are debugging or not.  */
  pid = 0;     /* Note that the thread never can have PID zero.  */


  /* ******************************************************** */
  /*  This code was moved from below to cope with running threads
   *  on uClinux systems.  See comment below...
   * Insert new thread in doubly linked list of active threads */ 
  new_thread->p_prevlive = __pthread_main_thread;
  new_thread->p_nextlive = __pthread_main_thread->p_nextlive;
  __pthread_main_thread->p_nextlive->p_prevlive = new_thread;
  __pthread_main_thread->p_nextlive = new_thread;
  /* ********************************************************* */

  if (report_events)
    {
      /* See whether the TD_CREATE event bit is set in any of the
         masks.  */
      int idx = __td_eventword (TD_CREATE);
      uint32_t mask = __td_eventmask (TD_CREATE);

      if ((mask & (__pthread_threads_events.event_bits[idx]
		   | event_maskp->event_bits[idx])) != 0)
	{
	  /* Lock the mutex the child will use now so that it will stop.  */
	  __pthread_lock(new_thread->p_lock, NULL);

	  /* We have to report this event.  */
#ifdef __ia64__
	  pid = __clone2(pthread_start_thread_event, (void **) new_thread,
			(char *)new_thread - new_thread_bottom,
			CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
			__pthread_sig_cancel, new_thread);
#else
	  pid = clone(pthread_start_thread_event, (void **) new_thread,
			CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
			__pthread_sig_cancel, new_thread);
#endif

	  saved_errno = errno;
	  if (pid != -1)
	    {
	      /* Now fill in the information about the new thread in
	         the newly created thread's data structure.  We cannot let
	         the new thread do this since we don't know whether it was
	         already scheduled when we send the event.  */
	      new_thread->p_eventbuf.eventdata = new_thread;
	      new_thread->p_eventbuf.eventnum = TD_CREATE;
	      __pthread_last_event = new_thread;

	      /* We have to set the PID here since the callback function
		 in the debug library will need it and we cannot guarantee
		 the child got scheduled before the debugger.  */
	      new_thread->p_pid = pid;

	      /* Now call the function which signals the event.  */
	      __linuxthreads_create_event ();

	      /* Now restart the thread.  */
	      __pthread_unlock(new_thread->p_lock);
	    }
	}
    }
  if (pid == 0)
    {
      PDEBUG("cloning new_thread = %p\n", new_thread);
#ifdef __ia64__
      pid = __clone2(pthread_start_thread, (void **) new_thread,
			(char *)new_thread - new_thread_bottom,
		    CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
		    __pthread_sig_cancel, new_thread);
#else
      pid = clone(pthread_start_thread, (void **) new_thread,
		    CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
		    __pthread_sig_cancel, new_thread);
#endif
      saved_errno = errno;
    }
  /* Check if cloning succeeded */
  if (pid == -1) {
    /******************************************************** 
     * Code inserted to remove the thread from our list of active
     * threads in case of failure (needed to cope with uClinux), 
     * See comment below. */
    new_thread->p_nextlive->p_prevlive = new_thread->p_prevlive;
    new_thread->p_prevlive->p_nextlive = new_thread->p_nextlive;
    /********************************************************/

    /* Free the stack if we allocated it */
    if (attr == NULL || !attr->__stackaddr_set)
      {
#ifdef __ARCH_USE_MMU__
	if (new_thread->p_guardsize != 0)
	  munmap(new_thread->p_guardaddr, new_thread->p_guardsize);
	munmap((caddr_t)((char *)(new_thread+1) - INITIAL_STACK_SIZE),
	       INITIAL_STACK_SIZE);
#else
	free(new_thread_bottom);
#endif /* __ARCH_USE_MMU__ */
      }
    __pthread_handles[sseg].h_descr = NULL;
    __pthread_handles[sseg].h_bottom = NULL;
    __pthread_handles_num--;
    return errno;
  }
  PDEBUG("new thread pid = %d\n", pid);

#if 0
  /* ***********************************************************
   This code has been moved before the call to clone().  In uClinux,
   the use of wait on a semaphore is dependant upon that the child so
   the child must be in the active threads list. This list is used in
   pthread_find_self() to get the pthread_descr of self. So, if the
   child calls sem_wait before this code is executed , it will hang
   forever and initial_thread will instead be posted by a sem_post
   call. */

  /* Insert new thread in doubly linked list of active threads */
  new_thread->p_prevlive = __pthread_main_thread;
  new_thread->p_nextlive = __pthread_main_thread->p_nextlive;
  __pthread_main_thread->p_nextlive->p_prevlive = new_thread;
  __pthread_main_thread->p_nextlive = new_thread;
  /************************************************************/
#endif

  /* Set pid field of the new thread, in case we get there before the
     child starts. */
  new_thread->p_pid = pid;
  /* We're all set */
  *thread = new_thread_id;
  return 0;
}
static void spi_worker_thread(void *arg)
{
    struct _spi_device_st *spi_device = spi_dev;
    struct _smsspi_txmsg *msg = NULL;
    struct _spi_msg txmsg;

    PDEBUG("worker start");
    do {
        /* do we have a msg to write ? */
        if (!msg && !list_empty(&spi_device->txqueue))
            msg = (struct _smsspi_txmsg *)
                  list_entry(spi_device->txqueue.
                             next, struct _smsspi_txmsg, node);

        if (msg) {
            if (msg->add_preamble)
            {
                txmsg.len =
                    min(msg->size + sizeof(smsspi_preamble),
                        (size_t) TX_BUFFER_SIZE);
                txmsg.buf = spi_device->txbuf;
                txmsg.buf_phy_addr = spi_device->txbuf_phy_addr;
                memcpy(txmsg.buf, smsspi_preamble,
                       sizeof(smsspi_preamble));
                memcpy(&txmsg.buf[sizeof(smsspi_preamble)],
                       msg->buffer,
                       txmsg.len - sizeof(smsspi_preamble));
                msg->add_preamble = 0;
                msg->buffer +=
                    txmsg.len - sizeof(smsspi_preamble);
                msg->size -=
                    txmsg.len - sizeof(smsspi_preamble);
                /* zero out the rest of aligned buffer */
                memset(&txmsg.buf[txmsg.len], 0,
                       TX_BUFFER_SIZE - txmsg.len);
                smsspi_common_transfer_msg(&spi_device->dev,
                                           &txmsg, 1);
            } else {
                txmsg.len =
                    min(msg->size, (size_t) TX_BUFFER_SIZE);
                txmsg.buf = spi_device->txbuf;
                txmsg.buf_phy_addr = spi_device->txbuf_phy_addr;
                memcpy(txmsg.buf, msg->buffer, txmsg.len);

                msg->buffer += txmsg.len;
                msg->size -= txmsg.len;
                /* zero out the rest of aligned buffer */
                memset(&txmsg.buf[txmsg.len], 0,
                       TX_BUFFER_SIZE - txmsg.len);
                smsspi_common_transfer_msg(&spi_device->dev,
                                           &txmsg, 0);
            }

        } else {
            smsspi_common_transfer_msg(&spi_device->dev, NULL, 1);
        }

        /* if there was write, have we finished ? */
        if (msg && !msg->size) {
            /* call postwrite call back */
            if (msg->postwrite)
                msg->postwrite(spi_device);

            list_del(&msg->node);
            complete(&msg->completion);
            msg = NULL;
        }
        /* if there was read, did we read anything ? */

    } while (!list_empty(&spi_device->txqueue) || msg);

    PDEBUG("worker end");

}
Ejemplo n.º 4
0
/* startup()
 *
 * Handles mundane tasks of setting up logging, becoming a daemon, and
 * initializing signal handlers.
 */
static int startup(int argc, char **argv)
{
	struct sigaction handler;
#ifdef MORE_FDS
	int filemax;
	struct rlimit lim;
#endif

	if (is_daemon) {
		int logfd;
#ifndef CAPFS_LOG_DIR
		/* old behavior */
		char logname[] = "/tmp/capfsdlog.XXXXXX";

		if ((logfd = mkstemp(logname)) == -1) 
#else
		/* new, less obtuse behavior */
		char logname[4096];

		snprintf(logname, 4095, "%s/capfsd", CAPFS_LOG_DIR);
		if ((logfd = open(logname, O_APPEND|O_CREAT|O_RDWR, 0700)) == -1) 
#endif
		{
			PDEBUG(D_SPECIAL, "couldn't create logfile...continuing...\n");
			close(0); close(1); close(2);
		}
		else {
			fchmod(logfd, 0755);
			dup2(logfd, 2);
			dup2(logfd, 1);
			close(0);
		}
		if (fork()) {
			exit(0); /* fork() and kill parent */
		}
		setsid();
	}	

#ifdef MORE_FDS
	/* Try to increase number of open FDs.
	 *
	 * NOTE:
	 * The system maximum must be increased in order for us to be able to
	 * take advantage of an increase for this process.  This value is
	 * stored in /proc/sys/fs/file-max and is manipulated here with the
	 * get_filemax() and set_filemax() functions.
	 *
	 * NONE OF THIS CODE IS ANY GOOD UNTIL THE UNDERLYING TRANSPORT IS
	 * BETTER.  Specifically the sockset code needs to utilize larger
	 * numbers of FDs, as well as the code that associates sockets with
	 * files in the job code.  I'm going to leave this code here, but
	 * it's useless for the moment.
	 */
	if ((filemax = get_filemax()) < 0) {
		PERROR( "warning: get_filemax failed\n");
	}
	/* let's make sure there are plenty of FDs to go around */
	else if (filemax < 2*CAPFSD_NOFILE) {
		if ((filemax = set_filemax(2*CAPFSD_NOFILE)) < 0) {
			PERROR( "warning: set_filemax failed\n");
		}
	}
	/* now we take care of the per-process limits */
	if (getrlimit(RLIMIT_NOFILE, &lim) < 0) {
		PERROR( "warning: getrlimit failed\n");
	}
	else {
		lim.rlim_cur=(lim.rlim_cur<CAPFSD_NOFILE) ? CAPFSD_NOFILE : lim.rlim_cur;
		lim.rlim_max=(lim.rlim_max<CAPFSD_NOFILE) ? CAPFSD_NOFILE : lim.rlim_max;
		if (setrlimit(RLIMIT_NOFILE, &lim) < 0) {
			PERROR( "warning: setrlimit failed\n");
		}
	}
#endif

	/* change working dir to avoid unnecessary busy file systems */
	if (chdir("/") != 0) {
		exiterror("could not change working directory to /\n");
		exit(1);
	}

	memset(&handler, 0, sizeof(struct sigaction));
	handler.sa_sigaction = (void *) do_signal;
	handler.sa_flags = SA_SIGINFO;
	/* set up SIGINT handler to shut things down */
	if (sigaction(SIGINT, &handler, NULL) != 0) {
		exiterror("Could not setup signal handler for SIGINT");
		exit(1);
	}
	/* set up SIGTERM handler to shut things down */
	if (sigaction(SIGTERM, &handler, NULL) != 0) {
		exiterror("Could not setup signal handler for SIGTERM");
		exit(1);
	}
	/* set up SIGHUP handler to restart the daemon */
	if (sigaction(SIGHUP, &handler, NULL) != 0) {
		exiterror("Could not setup signal handler for SIGHUP");
		exit(1);
	}
	/* catch SIGPIPE and SIGSEGV signals and log them, on SEGV we die */
	if (sigaction(SIGPIPE, &handler, NULL) != 0) {
		exiterror("Could not setup signal handler for SIGPIPE");
		exit(1);
	}
	if (sigaction(SIGSEGV, &handler, NULL) != 0) {
		exiterror("Could not setup signal handler for SIGSEGV");
		exit(1);
	}

	return 0;
} /* end of startup() */
Ejemplo n.º 5
0
int attribute_noreturn __pthread_manager(void *arg)
{
  int reqfd = (int) (long int) arg;
#ifdef USE_SELECT
  struct timeval tv;
  fd_set fd;
#else
  struct pollfd ufd;
#endif
  sigset_t manager_mask;
  int n;
  struct pthread_request request;

  /* If we have special thread_self processing, initialize it.  */
#ifdef INIT_THREAD_SELF
  INIT_THREAD_SELF(&__pthread_manager_thread, 1);
#endif
  /* Set the error variable.  */
  __pthread_manager_thread.p_errnop = &__pthread_manager_thread.p_errno;
  __pthread_manager_thread.p_h_errnop = &__pthread_manager_thread.p_h_errno;

#ifdef __UCLIBC_HAS_XLOCALE__
  /* Initialize thread's locale to the global locale. */
  __pthread_manager_thread.locale = __global_locale;
#endif /* __UCLIBC_HAS_XLOCALE__ */

  /* Block all signals except __pthread_sig_cancel and SIGTRAP */
  sigfillset(&manager_mask);
  sigdelset(&manager_mask, __pthread_sig_cancel); /* for thread termination */
  sigdelset(&manager_mask, SIGTRAP);            /* for debugging purposes */
  if (__pthread_threads_debug && __pthread_sig_debug > 0)
      sigdelset(&manager_mask, __pthread_sig_debug);
  sigprocmask(SIG_SETMASK, &manager_mask, NULL);
  /* Raise our priority to match that of main thread */
  __pthread_manager_adjust_prio(__pthread_main_thread->p_priority);
  /* Synchronize debugging of the thread manager */
  n = TEMP_FAILURE_RETRY(__libc_read(reqfd, (char *)&request,
				     sizeof(request)));
#ifndef USE_SELECT
  ufd.fd = reqfd;
  ufd.events = POLLIN;
#endif
  /* Enter server loop */
  while(1) {
#ifdef USE_SELECT
    tv.tv_sec = 2;
    tv.tv_usec = 0;
    FD_ZERO (&fd);
    FD_SET (reqfd, &fd);
    n = select (reqfd + 1, &fd, NULL, NULL, &tv);
#else
    PDEBUG("before poll\n");
    n = poll(&ufd, 1, 2000);
    PDEBUG("after poll\n");
#endif
    /* Check for termination of the main thread */
    if (getppid() == 1) {
      pthread_kill_all_threads(SIGKILL, 0);
      _exit(0);
    }
    /* Check for dead children */
    if (terminated_children) {
      terminated_children = 0;
      pthread_reap_children();
    }
    /* Read and execute request */
#ifdef USE_SELECT
    if (n == 1)
#else
    if (n == 1 && (ufd.revents & POLLIN))
#endif
    {

      PDEBUG("before __libc_read\n");
      n = __libc_read(reqfd, (char *)&request, sizeof(request));
      PDEBUG("after __libc_read, n=%d\n", n);
      switch(request.req_kind) {
      case REQ_CREATE:
        PDEBUG("got REQ_CREATE\n");
        request.req_thread->p_retcode =
          pthread_handle_create((pthread_t *) &request.req_thread->p_retval,
                                request.req_args.create.attr,
                                request.req_args.create.fn,
                                request.req_args.create.arg,
                                &request.req_args.create.mask,
                                request.req_thread->p_pid,
                                request.req_thread->p_report_events,
                                &request.req_thread->p_eventbuf.eventmask);
        PDEBUG("restarting %d\n", request.req_thread);
        restart(request.req_thread);
        break;
      case REQ_FREE:
        PDEBUG("got REQ_FREE\n");
        pthread_handle_free(request.req_args.free.thread_id);
        break;
      case REQ_PROCESS_EXIT:
        PDEBUG("got REQ_PROCESS_EXIT from %d, exit code = %d\n", 
        request.req_thread, request.req_args.exit.code);
        pthread_handle_exit(request.req_thread,
                            request.req_args.exit.code);
        break;
      case REQ_MAIN_THREAD_EXIT:
        PDEBUG("got REQ_MAIN_THREAD_EXIT\n");
        main_thread_exiting = 1;
	/* Reap children in case all other threads died and the signal handler
	   went off before we set main_thread_exiting to 1, and therefore did
	   not do REQ_KICK. */
	pthread_reap_children();

        if (__pthread_main_thread->p_nextlive == __pthread_main_thread) {
          restart(__pthread_main_thread);
	  /* The main thread will now call exit() which will trigger an
	     __on_exit handler, which in turn will send REQ_PROCESS_EXIT
	     to the thread manager. In case you are wondering how the
	     manager terminates from its loop here. */
	}
        break;
      case REQ_POST:
        PDEBUG("got REQ_POST\n");
        __new_sem_post(request.req_args.post);
        break;
      case REQ_DEBUG:
        PDEBUG("got REQ_DEBUG\n");
	/* Make gdb aware of new thread and gdb will restart the
	   new thread when it is ready to handle the new thread. */
	if (__pthread_threads_debug && __pthread_sig_debug > 0) {
      PDEBUG("about to call raise(__pthread_sig_debug)\n");
	  raise(__pthread_sig_debug);
	}
      case REQ_KICK:
	/* This is just a prod to get the manager to reap some
	   threads right away, avoiding a potential delay at shutdown. */
	break;
      }
    }
  }
}
Ejemplo n.º 6
0
static int load_bof_binary(struct linux_binprm *bprm, struct  pt_regs *regs)
{
	int retval;
	struct bofhdr bhdr;
	struct bofhdr * bhdrp;

	bhdr = *((struct bofhdr *) bprm->buf);
	if (bhdr.ident[0] != 0x19 || bhdr.ident[1] != 'B' ||
	    bhdr.ident[2] != 'O' || bhdr.ident[3] != 'F') {
		return -ENOEXEC;
	}
	PDEBUG(9, "b_machine=0x%x, b_elfmachine=0x%x, b_version=0x%x\n",
	       bhdr.b_machine, bhdr.b_elfmachine, bhdr.b_version);

	// check machine
	if (
#ifdef CONFIG_ROACH
	    bhdr.b_machine != BM_ROACH ||
#else
	    bhdr.b_machine != BM_BEE2 ||
#endif
#ifndef __arch_um__
	    bhdr.b_elfmachine != EM_PPC
#else
	    (bhdr.b_elfmachine != EM_386 && bhdr.b_elfmachine != EM_486)
#endif
		) {
		PDEBUG(9, "Wrong b_machine or b_elfmachine!\n");
		return -ENOEXEC;
	}

	// only handle version 6
	if (bhdr.b_version != 6) {
		return -ENOEXEC;
	}

	// bof file is valid
	if (bof_has_fpga(&bhdr)) {    
		struct execq_item* execq_item;
		unsigned long flags;
		PDEBUG(9, "queue this file to bkexecd...\n");
		// HHH should change to slab

		execq_item = kmalloc(sizeof(struct execq_item), GFP_KERNEL);
		execq_item->bprm = bprm;
		execq_item->task = current;
    
		spin_lock_irqsave(&bked_info.execq_lock, flags);
		list_add_tail(&(execq_item->list), &bked_info.execq_list);
		spin_unlock_irqrestore(&bked_info.execq_lock, flags);
		
		//wake_up_sync(&bked_info.more_exec);
		wake_up(&bked_info.more_exec);

		/* Sleep till our fpga partner is done.
		 * It is less efficient but save me trouble for synching 
		 * the 2 sides */
		set_current_state(TASK_INTERRUPTIBLE);
		schedule();
	}

	/* hw should have been loaded by now...  I spent all my time
	 * to setup bkexecd to do the hw loading but now I realize
	 * there's no way to notify binfmt if it fails... bummer... so
	 * right now I'll just use a byte in bofhdr (in brpm->buf) to
	 * store the return value...
	 * To fix it?  Note that for "simplicity" sake, hw loading is
	 * synchronous to sw, thus I could have eliminated bkexecd all
	 * together as a thread.  Instead, just all the functions
	 * directly here.
	 */
	bhdrp = (struct bofhdr*) (bprm->buf);
	if (bhdrp->load_err) {
		PDEBUG(5, "hw load error\n");
		return bhdrp->load_err;
	}

	// make it looks like an ELF and start over
	retval = kernel_read(bprm->file, bhdr.b_elfoff, bprm->buf, BINPRM_BUF_SIZE);
	if (retval < 0) {
		PDEBUG(5, "kernel_read failed\n");
		return -ENOEXEC;
	}

	PDEBUG(9, "read elf header at 0x%x [%02x %02x %02x %02x]\n", 
	       bhdr.b_elfoff,
	       bprm->buf[0], bprm->buf[1], bprm->buf[2], bprm->buf[3]);
	return search_binary_handler(bprm,regs);
}
Ejemplo n.º 7
0
int QpskSymbolMapper::process(Buffer* const dataIn, Buffer* dataOut)
{
    PDEBUG("QpskSymbolMapper::process"
            "(dataIn: %p, dataOut: %p)\n",
            dataIn, dataOut);

    dataOut->setLength(dataIn->getLength() * 4 * 2 * sizeof(float));   // 4 output complex symbols per input byte
#ifdef __SSE__
    const uint8_t* in = reinterpret_cast<const uint8_t*>(dataIn->getData());
    __m128* out = reinterpret_cast<__m128*>(dataOut->getData());

    if (dataIn->getLength() % (d_carriers / 4) != 0) {
        fprintf(stderr, "%zu (input size) %% (%zu (carriers) / 4) != 0\n",
                dataIn->getLength(), d_carriers);
        throw std::runtime_error(
                "QpskSymbolMapper::process input size not valid!");
    }

    const static __m128 symbols[16] = {
        _mm_setr_ps( M_SQRT1_2,  M_SQRT1_2,  M_SQRT1_2,  M_SQRT1_2),
        _mm_setr_ps( M_SQRT1_2,  M_SQRT1_2,  M_SQRT1_2, -M_SQRT1_2),
        _mm_setr_ps( M_SQRT1_2, -M_SQRT1_2,  M_SQRT1_2,  M_SQRT1_2),
        _mm_setr_ps( M_SQRT1_2, -M_SQRT1_2,  M_SQRT1_2, -M_SQRT1_2),
        _mm_setr_ps( M_SQRT1_2,  M_SQRT1_2, -M_SQRT1_2,  M_SQRT1_2),
        _mm_setr_ps( M_SQRT1_2,  M_SQRT1_2, -M_SQRT1_2, -M_SQRT1_2),
        _mm_setr_ps( M_SQRT1_2, -M_SQRT1_2, -M_SQRT1_2,  M_SQRT1_2),
        _mm_setr_ps( M_SQRT1_2, -M_SQRT1_2, -M_SQRT1_2, -M_SQRT1_2),
        _mm_setr_ps(-M_SQRT1_2,  M_SQRT1_2,  M_SQRT1_2,  M_SQRT1_2),
        _mm_setr_ps(-M_SQRT1_2,  M_SQRT1_2,  M_SQRT1_2, -M_SQRT1_2),
        _mm_setr_ps(-M_SQRT1_2,- M_SQRT1_2,  M_SQRT1_2,  M_SQRT1_2),
        _mm_setr_ps(-M_SQRT1_2,- M_SQRT1_2,  M_SQRT1_2, -M_SQRT1_2),
        _mm_setr_ps(-M_SQRT1_2,  M_SQRT1_2, -M_SQRT1_2,  M_SQRT1_2),
        _mm_setr_ps(-M_SQRT1_2,  M_SQRT1_2, -M_SQRT1_2, -M_SQRT1_2),
        _mm_setr_ps(-M_SQRT1_2,- M_SQRT1_2, -M_SQRT1_2,  M_SQRT1_2),
        _mm_setr_ps(-M_SQRT1_2,- M_SQRT1_2, -M_SQRT1_2, -M_SQRT1_2)
    };
    size_t inOffset = 0;
    size_t outOffset = 0;
    uint8_t tmp = 0;
    for (size_t i = 0; i < dataIn->getLength(); i += d_carriers / 4) {
        for (size_t j = 0; j < d_carriers / 8; ++j) {
            tmp =  (in[inOffset] & 0xc0) >> 4;
            tmp |= (in[inOffset + (d_carriers / 8)] & 0xc0) >> 6;
            out[outOffset] = symbols[tmp];
            tmp =  (in[inOffset] & 0x30) >> 2;
            tmp |= (in[inOffset + (d_carriers / 8)] & 0x30) >> 4;
            out[outOffset + 1] = symbols[tmp];
            tmp =  (in[inOffset] & 0x0c);
            tmp |= (in[inOffset + (d_carriers / 8)] & 0x0c) >> 2;
            out[outOffset + 2] = symbols[tmp];
            tmp =  (in[inOffset] & 0x03) << 2;
            tmp |= (in[inOffset + (d_carriers / 8)] & 0x03);
            out[outOffset + 3] = symbols[tmp];
            ++inOffset;
            outOffset += 4;
        }
        inOffset += d_carriers / 8;
    }
#else // !__SSE__
    const uint8_t* in = reinterpret_cast<const uint8_t*>(dataIn->getData());
    float* out = reinterpret_cast<float*>(dataOut->getData());
    if (dataIn->getLength() % (d_carriers / 4) != 0) {
        throw std::runtime_error(
                "QpskSymbolMapper::process input size not valid!");
    }
    if (dataOut->getLength() / sizeof(float) != dataIn->getLength() * 4 * 2) {    // 4 output complex symbols per input byte
        throw std::runtime_error(
                "QpskSymbolMapper::process output size not valid!");
    }

    const static float symbols[16][4] = {
        { M_SQRT1_2,  M_SQRT1_2,  M_SQRT1_2,  M_SQRT1_2},
        { M_SQRT1_2,  M_SQRT1_2,  M_SQRT1_2, -M_SQRT1_2},
        { M_SQRT1_2, -M_SQRT1_2,  M_SQRT1_2,  M_SQRT1_2},
        { M_SQRT1_2, -M_SQRT1_2,  M_SQRT1_2, -M_SQRT1_2},
        { M_SQRT1_2,  M_SQRT1_2, -M_SQRT1_2,  M_SQRT1_2},
        { M_SQRT1_2,  M_SQRT1_2, -M_SQRT1_2, -M_SQRT1_2},
        { M_SQRT1_2, -M_SQRT1_2, -M_SQRT1_2,  M_SQRT1_2},
        { M_SQRT1_2, -M_SQRT1_2, -M_SQRT1_2, -M_SQRT1_2},
        {-M_SQRT1_2,  M_SQRT1_2,  M_SQRT1_2,  M_SQRT1_2},
        {-M_SQRT1_2,  M_SQRT1_2,  M_SQRT1_2, -M_SQRT1_2},
        {-M_SQRT1_2,- M_SQRT1_2,  M_SQRT1_2,  M_SQRT1_2},
        {-M_SQRT1_2,- M_SQRT1_2,  M_SQRT1_2, -M_SQRT1_2},
        {-M_SQRT1_2,  M_SQRT1_2, -M_SQRT1_2,  M_SQRT1_2},
        {-M_SQRT1_2,  M_SQRT1_2, -M_SQRT1_2, -M_SQRT1_2},
        {-M_SQRT1_2,- M_SQRT1_2, -M_SQRT1_2,  M_SQRT1_2},
        {-M_SQRT1_2,- M_SQRT1_2, -M_SQRT1_2, -M_SQRT1_2}
    };
    size_t inOffset = 0;
    size_t outOffset = 0;
    uint8_t tmp;
    for (size_t i = 0; i < dataIn->getLength(); i += d_carriers / 4) {
        for (size_t j = 0; j < d_carriers / 8; ++j) {
            tmp =  (in[inOffset] & 0xc0) >> 4;
            tmp |= (in[inOffset + (d_carriers / 8)] & 0xc0) >> 6;
            memcpy(&out[outOffset], symbols[tmp], sizeof(float) * 4);
            tmp =  (in[inOffset] & 0x30) >> 2;
            tmp |= (in[inOffset + (d_carriers / 8)] & 0x30) >> 4;
            memcpy(&out[outOffset + 4], symbols[tmp], sizeof(float) * 4);
            tmp =  (in[inOffset] & 0x0c);
            tmp |= (in[inOffset + (d_carriers / 8)] & 0x0c) >> 2;
            memcpy(&out[outOffset + 8], symbols[tmp], sizeof(float) * 4);
            tmp =  (in[inOffset] & 0x03) << 2;
            tmp |= (in[inOffset + (d_carriers / 8)] & 0x03);
            memcpy(&out[outOffset + 12], symbols[tmp], sizeof(float) * 4);
            ++inOffset;
            outOffset += 4*4;
        }
        inOffset += d_carriers / 8;
    }
#endif // __SSE__

    return 1;
}
Ejemplo n.º 8
0
int DabModulator::process(Buffer* const dataIn, Buffer* dataOut)
{
    PDEBUG("DabModulator::process(dataIn: %p, dataOut: %p)\n",
            dataIn, dataOut);

    myEtiReader.process(dataIn);
    if (myFlowgraph == NULL) {
        unsigned mode = myEtiReader.getMode();
        if (myDabMode != 0) {
            mode = myDabMode;
        } else if (mode == 0) {
            mode = 4;
        }
        setMode(mode);

        myFlowgraph = new Flowgraph();
        ////////////////////////////////////////////////////////////////
        // CIF data initialisation
        ////////////////////////////////////////////////////////////////
        FrameMultiplexer* cifMux = NULL;
        PrbsGenerator* cifPrbs = NULL;
        BlockPartitioner* cifPart = NULL;
        QpskSymbolMapper* cifMap = NULL;
        FrequencyInterleaver* cifFreq = NULL;
        PhaseReference* cifRef = NULL;
        DifferentialModulator* cifDiff = NULL;
        NullSymbol* cifNull = NULL;
        SignalMultiplexer* cifSig = NULL;
        CicEqualizer* cifCicEq = NULL;
        OfdmGenerator* cifOfdm = NULL;
        GainControl* cifGain = NULL;
        GuardIntervalInserter* cifGuard = NULL;
        FIRFilter* cifFilter = NULL;
        Resampler* cifRes = NULL;

        cifPrbs = new PrbsGenerator(864 * 8, 0x110);
        cifMux = new FrameMultiplexer(myFicSizeOut + 864 * 8,
                &myEtiReader.getSubchannels());
        cifPart = new BlockPartitioner(mode, myEtiReader.getFp());
        cifMap = new QpskSymbolMapper(myNbCarriers);
        cifRef = new PhaseReference(mode);
        cifFreq = new FrequencyInterleaver(mode);
        cifDiff = new DifferentialModulator(myNbCarriers);
        cifNull = new NullSymbol(myNbCarriers);
        cifSig = new SignalMultiplexer(
                (1 + myNbSymbols) * myNbCarriers * sizeof(complexf));

        if (myClockRate) {
            unsigned ratio = myClockRate / myOutputRate;
            ratio /= 4; // FPGA DUC
            if (myClockRate == 400000000) { // USRP2
                if (ratio & 1) { // odd
                    cifCicEq = new CicEqualizer(myNbCarriers,
                            (float)mySpacing * (float)myOutputRate / 2048000.0f,
                            ratio);
                } // even, no filter
            } else {
                cifCicEq = new CicEqualizer(myNbCarriers,
                        (float)mySpacing * (float)myOutputRate / 2048000.0f,
                        ratio);
            }
        }

        cifOfdm = new OfdmGenerator((1 + myNbSymbols), myNbCarriers, mySpacing);
        cifGain = new GainControl(mySpacing, myGainMode, myFactor);
        cifGuard = new GuardIntervalInserter(myNbSymbols, mySpacing,
                myNullSize, mySymSize);
        if (myFilterTapsFilename != "") {
            cifFilter = new FIRFilter(myFilterTapsFilename);
            cifFilter->enrol_at(*myRC);
        }
        myOutput = new OutputMemory();

        if (myOutputRate != 2048000) {
            cifRes = new Resampler(2048000, myOutputRate, mySpacing);
        } else {
            fprintf(stderr, "No resampler\n");
        }

        myFlowgraph->connect(cifPrbs, cifMux);

        ////////////////////////////////////////////////////////////////
        // Processing FIC
        ////////////////////////////////////////////////////////////////
        FicSource* fic = myEtiReader.getFic();
        PrbsGenerator* ficPrbs = NULL;
        ConvEncoder* ficConv = NULL;
        PuncturingEncoder* ficPunc = NULL;
        ////////////////////////////////////////////////////////////////
        // Data initialisation
        ////////////////////////////////////////////////////////////////
        myFicSizeIn = fic->getFramesize();

        ////////////////////////////////////////////////////////////////
        // Modules configuration
        ////////////////////////////////////////////////////////////////

        // Configuring FIC channel

        PDEBUG("FIC:\n");
        PDEBUG(" Framesize: %zu\n", fic->getFramesize());

        // Configuring prbs generator
        ficPrbs = new PrbsGenerator(myFicSizeIn, 0x110);

        // Configuring convolutionnal encoder
        ficConv = new ConvEncoder(myFicSizeIn);

        // Configuring puncturing encoder
        ficPunc = new PuncturingEncoder();
        std::vector<PuncturingRule*> rules = fic->get_rules();
        std::vector<PuncturingRule*>::const_iterator rule;
        for (rule = rules.begin(); rule != rules.end(); ++rule) {
            PDEBUG(" Adding rule:\n");
            PDEBUG("  Length: %zu\n", (*rule)->length());
            PDEBUG("  Pattern: 0x%x\n", (*rule)->pattern());
            ficPunc->append_rule(*(*rule));
        }
        PDEBUG(" Adding tail\n");
        ficPunc->append_tail_rule(PuncturingRule(3, 0xcccccc));

        myFlowgraph->connect(fic, ficPrbs);
        myFlowgraph->connect(ficPrbs, ficConv);
        myFlowgraph->connect(ficConv, ficPunc);
        myFlowgraph->connect(ficPunc, cifPart);

        ////////////////////////////////////////////////////////////////
        // Configuring subchannels
        ////////////////////////////////////////////////////////////////
        std::vector<SubchannelSource*> subchannels =
            myEtiReader.getSubchannels();
        std::vector<SubchannelSource*>::const_iterator subchannel;
        for (subchannel = subchannels.begin();
                subchannel != subchannels.end();
                ++subchannel) {
            PrbsGenerator* subchPrbs = NULL;
            ConvEncoder* subchConv = NULL;
            PuncturingEncoder* subchPunc = NULL;
            TimeInterleaver* subchInterleaver = NULL;

            ////////////////////////////////////////////////////////////
            // Data initialisation
            ////////////////////////////////////////////////////////////
            size_t subchSizeIn = (*subchannel)->framesize();
            size_t subchSizeOut = (*subchannel)->framesizeCu() * 8;

            ////////////////////////////////////////////////////////////
            // Modules configuration
            ////////////////////////////////////////////////////////////

            // Configuring subchannel
            PDEBUG("Subchannel:\n");
            PDEBUG(" Start address: %zu\n",
                    (*subchannel)->startAddress());
            PDEBUG(" Framesize: %zu\n",
                    (*subchannel)->framesize());
            PDEBUG(" Bitrate: %zu\n", (*subchannel)->bitrate());
            PDEBUG(" Framesize CU: %zu\n",
                    (*subchannel)->framesizeCu());
            PDEBUG(" Protection: %zu\n",
                    (*subchannel)->protection());
            PDEBUG("  Form: %zu\n",
                    (*subchannel)->protectionForm());
            PDEBUG("  Level: %zu\n",
                    (*subchannel)->protectionLevel());
            PDEBUG("  Option: %zu\n",
                    (*subchannel)->protectionOption());

            // Configuring prbs genrerator
            subchPrbs = new PrbsGenerator(subchSizeIn, 0x110);

            // Configuring convolutionnal encoder
            subchConv = new ConvEncoder(subchSizeIn);

            // Configuring puncturing encoder
            subchPunc = new PuncturingEncoder();
            std::vector<PuncturingRule*> rules = (*subchannel)->get_rules();
            std::vector<PuncturingRule*>::const_iterator rule;
            for (rule = rules.begin(); rule != rules.end(); ++rule) {
                PDEBUG(" Adding rule:\n");
                PDEBUG("  Length: %zu\n", (*rule)->length());
                PDEBUG("  Pattern: 0x%x\n", (*rule)->pattern());
                subchPunc->append_rule(*(*rule));
            }
            PDEBUG(" Adding tail\n");
            subchPunc->append_tail_rule(PuncturingRule(3, 0xcccccc));

            // Configuring time interleaver
            subchInterleaver = new TimeInterleaver(subchSizeOut);

            myFlowgraph->connect(*subchannel, subchPrbs);
            myFlowgraph->connect(subchPrbs, subchConv);
            myFlowgraph->connect(subchConv, subchPunc);
            myFlowgraph->connect(subchPunc, subchInterleaver);
            myFlowgraph->connect(subchInterleaver, cifMux);
        }

        myFlowgraph->connect(cifMux, cifPart);
        myFlowgraph->connect(cifPart, cifMap);
        myFlowgraph->connect(cifMap, cifFreq);
        myFlowgraph->connect(cifRef, cifDiff);
        myFlowgraph->connect(cifFreq, cifDiff);
        myFlowgraph->connect(cifNull, cifSig);
        myFlowgraph->connect(cifDiff, cifSig);
        if (myClockRate) {
            myFlowgraph->connect(cifSig, cifCicEq);
            myFlowgraph->connect(cifCicEq, cifOfdm);
        } else {
            myFlowgraph->connect(cifSig, cifOfdm);
        }
        myFlowgraph->connect(cifOfdm, cifGain);
        myFlowgraph->connect(cifGain, cifGuard);

        if (myFilterTapsFilename != "") {
            myFlowgraph->connect(cifGuard, cifFilter);
            if (cifRes != NULL) {
                myFlowgraph->connect(cifFilter, cifRes);
                myFlowgraph->connect(cifRes, myOutput);
            } else {
                myFlowgraph->connect(cifFilter, myOutput);
            }
        }
        else { //no filtering
            if (cifRes != NULL) {
                myFlowgraph->connect(cifGuard, cifRes);
                myFlowgraph->connect(cifRes, myOutput);
            } else {
                myFlowgraph->connect(cifGuard, myOutput);
            }

        }
    }

    ////////////////////////////////////////////////////////////////////
    // Proccessing data
    ////////////////////////////////////////////////////////////////////
    myOutput->setOutput(dataOut);
    return myFlowgraph->run();
}
Ejemplo n.º 9
0
DabModulator::~DabModulator()
{
    PDEBUG("DabModulator::~DabModulator() @ %p\n", this);

    delete myFlowgraph;
}
Ejemplo n.º 10
0
Archivo: sio.c Proyecto: boris-r-v/RIO
/**********************************************************************
 *  sio_open
 *
 *  Open and initiate serial port
 *  default open port in noncanonical mode
 *
 *  Arguments:
 *    port    a string point to the name of serial device,
 *				such as "/dev/ttyS0"
 *    baud    B0, B50... B9600, B19200, B38400...
 *    data    Data bit(s), unsigned char
 *    parity  Parity, unsigned char
 *    stop    Stop bit(s), unsigned char
 *
 *  Returned:
 *    This function returns int port descriptor for the port opened
 *    successfully. Return value ERR_PORT_OPEN if failed.
 *
 **********************************************************************/
int
sio_open(const char *port, speed_t baud, tcflag_t data, tcflag_t parity,
		 tcflag_t stop)
{
	struct sio *sio;			/* point to current sio structure */

	int fd;						/* file descriptor for current port */
	int r;

	struct termios *options;	/* options for current port */

	PDEBUG("sio_open: start\n");

  /***************
   *  open port  *
   ***************/
	fd = _sio_device(port);
	if (fd == 0) {				/* device is not yet opened, so, open it */
		// fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY);
		//printf("%s ... open %s\n",__FUNCTION__, port);
		fd = open(port, O_RDWR | O_NOCTTY);
	}
	PDEBUG("          fd = %u\n", fd);

	if (fd == -1) {				/* Could not open the port */
		PDEBUG("sio_open: Unable to open %s - %s\n", strerror(errno),
			   port);
		return (ERR_PORT_OPEN);
	}

  /********************************
   *  allocate new sio structure  *
   ********************************/
	sio = _sio_follow(fd);
	if (!sio) {					/* out of memory */
		close(fd);
		return (ERR_PORT_OPEN);
	}

	sio->fd = fd;
	sio->name = port;

	// fcntl(fd, F_SETFL, FNDELAY); /* nonblocking */

	tcgetattr(fd, sio->old_options);	/* save the original options */
	tcgetattr(fd, sio->options);	/* Get the current options */

	options = sio->options;

	/*
	 * printf("\nsio_open\n"); printf("name : %s\n", sio->name);
	 * printf("fd : %d\n", fd); printf("sio : %lx\n", sio);
	 * printf("sio->options : %lx\n", sio->options);
	 * printf("sio->old_options : %lx\n", sio->old_options);
	 * printf("options : %lx\n", options); printf("\n"); 
	 */

  /*********************
   *  select Baudrate  *
   *********************/
	r = cfsetispeed(options, baud);	/* input */
	if (r) {
		PDEBUG("sio_open: fails to set input baudrate!\n", r);
		close(fd);
		return (r);
	}
	r = cfsetospeed(options, baud);	/* output */
	if (r) {
		PDEBUG("sio_open: fails to set output baudrate!\n", r);
		close(fd);
		return (r);
	}

  /**********************
   *  select data bits  *
   **********************/
	options->c_cflag &= ~CSIZE;	/* bit mask for data bits */
	options->c_cflag |= data;
	/*
	 * close(fd); PDEBUG("undefined data bits number %d, port %s
	 * closed.\n", data, port); return (ERR_PORT_OPEN); 
	 */

  /*******************
   *  select parity  *
   *******************/
	switch (parity) {
	case NO_PARITY:
		options->c_cflag &= ~(PARENB | PARODD);
		break;
	case ODD_PARITY:
		options->c_cflag |= PARODD;
		break;
	case EVEN_PARITY:
		options->c_cflag |= PARENB;
		break;
	default:
		tcsetattr(fd, TCSANOW, sio->old_options);
		close(fd);
		_sio_trim(fd);
		PDEBUG("undefined parity code %d, port %s closed.\n", parity,
			   port);
		return (ERR_PORT_OPEN);
	}

  /************************
   *  select stop bit(s)  *
   ************************/
	switch (stop) {
	case ONE_STOP_BIT:
		options->c_cflag &= ~CSTOPB;
		break;
	case TWO_STOP_BITS:
		options->c_cflag |= CSTOPB;
		break;
	default:
		tcsetattr(fd, TCSANOW, sio->old_options);
		close(fd);
		_sio_trim(fd);
		PDEBUG("undefined stop bits code %d, port %s closed.\n", stop,
			   port);
		return (ERR_PORT_OPEN);
	}

  /**********************
   *  other parameterm  *
   **********************/
	/*
	 * posix input mode flags 
	 */
	options->c_iflag &= ~ICRNL;	/* disable map CR to NL for noncanonical */
	options->c_iflag &= ~INLCR;
	options->c_iflag &= ~IXON;	/* disable software flow control
								   * (outgoing) */
	options->c_iflag &= ~IXOFF;	/* disable software flow control
								   * (incoming) */

	/*
	 * posix output mode flags 
	 */
	options->c_oflag &= ~OPOST;	/* raw output */
	options->c_oflag &= ~OLCUC;	/* do not transfer the case */
	options->c_oflag &= ~ONLCR;	/* do not translate the CR and NL */
	options->c_oflag &= ~OCRNL;
	options->c_oflag &= ~NLDLY;	/* no delay for NL */
	options->c_oflag &= ~CRDLY;	/* no delay for CR */
	options->c_oflag &= ~TABDLY;	/* no delay for TAB */
	options->c_oflag &= ~BSDLY;	/* no delay for BS */
	options->c_oflag &= ~VTDLY;	/* no delay for VT */
	options->c_oflag &= ~FFDLY;	/* no delay for FF */

	/*
	 * posix control mode flags 
	 */
	options->c_cflag |= CLOCAL;	/* Local line */
	/*
	 * do not change "owner" of port 
	 */
	options->c_cflag |= CREAD;	/* Enable receiver */

	options->c_cflag &= ~CRTSCTS;	/* Disable hardware flow control */

	/*
	 * posix local mode flags 
	 */
	options->c_lflag &= ~ICANON;	/* default for noncanonical mode */
	options->c_lflag &= ~ECHO;	/* Disable echoing of input characters */
	options->c_lflag &= ~ISIG;	/* disable signals */

	/*
	 * posix control characters 
	 */
	options->c_cc[VINTR] = 0;
	options->c_cc[VQUIT] = 0;
	options->c_cc[VERASE] = 0;
	options->c_cc[VKILL] = 0;
	options->c_cc[VEOF] = 4;
	options->c_cc[VTIME] = 0;	/* Time to wait for data (tenths of
								   * seconds) */
	options->c_cc[VMIN] = 1;
	options->c_cc[VSWTC] = 0;
	options->c_cc[VSTART] = 0;
	options->c_cc[VSTOP] = 0;
	options->c_cc[VSUSP] = 0;
	options->c_cc[VEOL] = 0;
	options->c_cc[VREPRINT] = 0;
	options->c_cc[VDISCARD] = 0;
	options->c_cc[VWERASE] = 0;
	options->c_cc[VLNEXT] = 0;
	options->c_cc[VEOL2] = 0;

  /**************************************
   *  set the new options for the port  *
   **************************************/
	// tcsetattr(fd, TCSANOW, options);
	tcsetattr(fd, TCSAFLUSH, options);	/* flush input and output buffers,
										   * and make the change */
# ifdef I7K_DEBUG
	_sio_poptions(fd);
# endif							/* I7K_DEBUG */

	return (fd);
}
Ejemplo n.º 11
0
ssize_t rpc_kern_write(int opt, const char *buf, size_t count)
{
    RPC_KERN_Dev *dev;
    int temp, size;
    ssize_t ret = 0;
    char *ptmp;

    dev = &rpc_kern_devices[opt*RPC_NR_KERN_DEVS/RPC_NR_PAIR];
    PDEBUG("read rpc_kern_device: %x \n", (unsigned int)dev);
    if (down_interruptible(&dev->writeSem))
        return -ERESTARTSYS;

    if (dev->ringIn == dev->ringOut)
        size = 0;   // the ring is empty
    else if (dev->ringIn > dev->ringOut)
        size = dev->ringIn - dev->ringOut;
    else
        size = RPC_RING_SIZE + dev->ringIn - dev->ringOut;

	if (count > (RPC_RING_SIZE - size - 1))
		goto out;

	temp = dev->ringEnd - dev->ringIn;
	if (temp >= count) {
		if (my_copy_user((int *)dev->ringIn, (int *)buf, count)) {
        	ret = -EFAULT;
			goto out;
		}
		ret += count;
		ptmp = dev->ringIn + ((count+3) & 0xfffffffc);

		__asm__ __volatile__ ("sync;");

		if (ptmp == dev->ringEnd)
			dev->ringIn = dev->ringStart;
		else
			dev->ringIn = ptmp;
    	
    	PDEBUG("RPC Write is in 1st kind...\n");
	} else {
		if (my_copy_user((int *)dev->ringIn, (int *)buf, temp)) {
        	ret = -EFAULT;
			goto out;
		}
		count -= temp;
		
		if (my_copy_user((int *)dev->ringStart, (int *)(buf+temp), count)) {
        	ret = -EFAULT;
			goto out;
		}
		ret += (temp + count);

		__asm__ __volatile__ ("sync;");

		dev->ringIn = dev->ringStart+((count+3) & 0xfffffffc);
    	
    	PDEBUG("RPC Write is in 2nd kind...\n");
	}

	if (opt == RPC_AUDIO)
		writel(0x3, (void *)0xb801a104);        // audio
	else if (opt == RPC_VIDEO)
		writel(0x5, (void *)0xb801a104);        // video
	else
		printk("error device number...\n");

out:
    PDEBUG("RPC kern ringIn pointer is : 0x%8x\n", (int)dev->ringIn);
    up(&dev->writeSem);
    return ret;
}
Ejemplo n.º 12
0
Archivo: sio.c Proyecto: boris-r-v/RIO
void _sio_poptions(int fd)
{
	struct sio *sio;

	sio = _sio_follow(fd);

	PDEBUG("sio->old_options->c_iflag = %08x\n",
		   sio->old_options->c_iflag);
	PDEBUG("sio->old_options->c_oflag = %08x\n",
		   sio->old_options->c_oflag);
	PDEBUG("sio->old_options->c_cflag = %08x\n",
		   sio->old_options->c_cflag);
	PDEBUG("sio->old_options->c_lflag = %08x\n",
		   sio->old_options->c_lflag);
	PDEBUG("sio->old_options->c_line  = %08x\n", sio->old_options->c_line);
	PDEBUG("-----------------------------------\n");
	PDEBUG("sio->options->c_iflag = %08x\n", sio->options->c_iflag);
	PDEBUG("sio->options->c_oflag = %08x\n", sio->options->c_oflag);
	PDEBUG("sio->options->c_cflag = %08x\n", sio->options->c_cflag);
	PDEBUG("sio->options->c_lflag = %08x\n", sio->options->c_lflag);
	PDEBUG("sio->options->c_line  = %08x\n", sio->options->c_line);
	PDEBUG("-----------------------------------\n");
}
Ejemplo n.º 13
0
static int gl860_guess_sensor(struct gspca_dev *gspca_dev,
				u16 vendor_id, u16 product_id)
{
	struct sd *sd = (struct sd *) gspca_dev;
	u8 probe, nb26, nb96, nOV, ntry;

	if (product_id == 0xf191)
		sd->sensor = ID_MI1320;

	if (sd->sensor == 0xff) {
		ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0004, 1, &probe);
		ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0004, 1, &probe);

		ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x0000, 0, NULL);
		msleep(3);
		ctrl_out(gspca_dev, 0x40, 1, 0x0010, 0x0010, 0, NULL);
		msleep(3);
		ctrl_out(gspca_dev, 0x40, 1, 0x0008, 0x00c0, 0, NULL);
		msleep(3);
		ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x00c1, 0, NULL);
		msleep(3);
		ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x00c2, 0, NULL);
		msleep(3);
		ctrl_out(gspca_dev, 0x40, 1, 0x0020, 0x0006, 0, NULL);
		msleep(3);
		ctrl_out(gspca_dev, 0x40, 1, 0x006a, 0x000d, 0, NULL);
		msleep(56);

		PDEBUG(D_PROBE, "probing for sensor MI2020 or OVXXXX");
		nOV = 0;
		for (ntry = 0; ntry < 4; ntry++) {
			ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL);
			msleep(3);
			ctrl_out(gspca_dev, 0x40, 1, 0x0063, 0x0006, 0, NULL);
			msleep(3);
			ctrl_out(gspca_dev, 0x40, 1, 0x7a00, 0x8030, 0, NULL);
			msleep(10);
			ctrl_in(gspca_dev, 0xc0, 2, 0x7a00, 0x8030, 1, &probe);
			PDEBUG(D_PROBE, "probe=0x%02x", probe);
			if (probe == 0xff)
				nOV++;
		}

		if (nOV) {
			PDEBUG(D_PROBE, "0xff -> OVXXXX");
			PDEBUG(D_PROBE, "probing for sensor OV2640 or OV9655");

			nb26 = nb96 = 0;
			for (ntry = 0; ntry < 4; ntry++) {
				ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000,
						0, NULL);
				msleep(3);
				ctrl_out(gspca_dev, 0x40, 1, 0x6000, 0x800a,
						0, NULL);
				msleep(10);

				/* Wait for 26(OV2640) or 96(OV9655) */
				ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x800a,
						1, &probe);

				if (probe == 0x26 || probe == 0x40) {
					PDEBUG(D_PROBE,
						"probe=0x%02x -> OV2640",
						probe);
					sd->sensor = ID_OV2640;
					nb26 += 4;
					break;
				}
				if (probe == 0x96 || probe == 0x55) {
					PDEBUG(D_PROBE,
						"probe=0x%02x -> OV9655",
						probe);
					sd->sensor = ID_OV9655;
					nb96 += 4;
					break;
				}
				PDEBUG(D_PROBE, "probe=0x%02x", probe);
				if (probe == 0x00)
					nb26++;
				if (probe == 0xff)
					nb96++;
				msleep(3);
			}
			if (nb26 < 4 && nb96 < 4)
				return -1;
		} else {
			PDEBUG(D_PROBE, "Not any 0xff -> MI2020");
			sd->sensor = ID_MI2020;
		}
	}

	if (_MI1320_) {
		PDEBUG(D_PROBE, "05e3:f191 sensor MI1320 (1.3M)");
	} else if (_MI2020_) {
		PDEBUG(D_PROBE, "05e3:0503 sensor MI2020 (2.0M)");
	} else if (_OV9655_) {
		PDEBUG(D_PROBE, "05e3:0503 sensor OV9655 (1.3M)");
	} else if (_OV2640_) {
		PDEBUG(D_PROBE, "05e3:0503 sensor OV2640 (2.0M)");
	} else {
		PDEBUG(D_PROBE, "***** Unknown sensor *****");
		return -1;
	}

	return 0;
}
Ejemplo n.º 14
0
PrbsGenerator::~PrbsGenerator()
{
    PDEBUG("PrbsGenerator::~PrbsGenerator() @ %p\n", this);

}
Ejemplo n.º 15
0
static int __init init_bof_binfmt (void) {
	PDEBUG(0, "binfmt_bof v4 loaded\n");
	return register_binfmt(&bof_format);
}
Ejemplo n.º 16
0
/*
**===========================================================================
** 8.0			pcidriver_ioctl()
**===========================================================================
** Description: 
**
** Parameters:  cmd and a argument
**              
**
** Returns:     some stuff ...
**
** Globals:     
*/
int plx_drv_ioctl(struct inode *inode, struct file *file,
		    unsigned int cmd, unsigned long arg)
{

driver_t  *dev = file->private_data;

  static unsigned char localbuf[IOC_BUFSIZE];
  /* Define "alias" names for the localbuf */
  void *karg = localbuf;
  Register *reg = karg;
  unsigned long *klong = karg;
  Container *container = karg;
 int size = _IOC_SIZE(cmd); /* the size bitfield in cmd */
  int retval = 0; /* success by default */

#if ZERO
PDEBUG(("function: %s, file: %s line: %d invoked\n", __FUNCTION__, __FILE__, __LINE__));
#endif

 /*
   * Extract the type and number bitfields, and don't decode
   * wrong cmds: return EINVAL before verify_area()
   */
  if (_IOC_TYPE(cmd) != MAG_NUM) return -ENOTTY;
  if (_IOC_NR(cmd) > IOC_MAXNR) return -ENOTTY;

  /*
   * The direction is a bitmask, and VERIFY_WRITE catches R/W
   * transfers. `Dir' is user-oriented, while
   * verify_area is kernel-oriented, so the concept of "read" and
   * "write" is reversed
   */
  if (_IOC_DIR(cmd) & _IOC_READ) {
    if (!access_ok(VERIFY_WRITE, (void *)arg, size))
      return -EFAULT;
  }
  else if (_IOC_DIR(cmd) & _IOC_WRITE) {
    if (!access_ok(VERIFY_READ, (void *)arg, size))
      return -EFAULT;
  }

#if ZERO
  PDEBUG(("ioctl.c: %08x %08lx: nr %i, size %i, dir %i\n",
	 cmd, arg, _IOC_NR(cmd), _IOC_SIZE(cmd), _IOC_DIR(cmd)));
#endif

  /* First, retrieve data from userspace */
  if ((_IOC_DIR(cmd) & _IOC_WRITE) && (size <= IOC_BUFSIZE))
    if (copy_from_user(karg, (void *)arg, size))
      return -EFAULT;

  /* We are ready to switch ... */
  switch (cmd) {

  case READ_PLX_REG:
   {
     if ((plx_read_plx_reg(dev, reg->addr, &(reg->data)) == 0)) { 
//       PDEBUG(("plx_read_fpga_reg: addr: %x and data %x\n", reg->addr, reg->data));
      }
      else
       return -EIO;
 
   }
   break;
  case WRITE_PLX_REG:
   {
     if((plx_write_plx_reg(dev, reg->addr, reg->data)) == 0) {
//         PDEBUG(("plx_write_fpga_reg: addr: %x and data %x\n", reg->addr, reg->data));
      }
      else
       return -EIO; 
 
   }

  break;


  case FILL_PCI_MEM:
    PDEBUG(("plx_ioctl: Fill PCI memory with test pattern!\n")); 

   memset_io(dev->PciBar[2].pVa, 0x11, DMA_SIZE/4);
   memset_io((dev->PciBar[2].pVa)+0x2000, 0x22, DMA_SIZE/4); 
   memset_io((dev->PciBar[2].pVa)+(0x2000*2), 0x33, DMA_SIZE/4); 
   memset_io((dev->PciBar[2].pVa)+(0x2000*3), 0x44, DMA_SIZE/4); 
  break;


 case READ_FPGA_REG:
      if ((plx_read_fpga_reg(dev, reg->addr, &(reg->data)) == 0)) { 
       PDEBUG(("plx_read_fpga_reg: addr: %x and data %x\n", reg->addr, reg->data));
      }
      else
       return -EIO; // Physical input/output error occured
   break;

case WRITE_FPGA_REG:
     if((plx_write_fpga_reg(dev, reg->addr, reg->data)) == 0) {
         PDEBUG(("plx_write_fpga_reg: addr: %x and data %x\n", reg->addr, reg->data));
      }
      else
       return -EIO; 

   break;

case WRITE_SRAM:
     if((plx_write_sram(dev, reg->addr, reg->data)) == 0) {
         PDEBUG(("plx_write_sram: addr: %x and data %x\n", reg->addr, reg->data));
      }
      else
       return -EIO; 

   break;


 case READ_COMMAND_LINK_REG:
    
      if ((plx_read_reg(dev, reg->addr, &(reg->data)) == 0)) { 
       PDEBUG(("plx_read_reg: addr: %x and data %x\n", reg->addr, reg->data));
      }
      else
       return -EIO; 
   
    break;

  case WRITE_COMMAND_LINK_REG:
    PDEBUG(("ioctl.c: addr: %x and data %x\n", reg->addr, reg->data));
  
      if((plx_write_reg(dev, reg->addr, reg->data)) == 0) {
         PDEBUG(("plx_write_reg: addr: %x and data %x\n", reg->addr, reg->data));
      }
      else
       return -EIO; 
    break;

    case IMMEDIATE_COMMAND:
      switch( *klong) {
 
      case XL_EXEC:
        /* Read the micro sec counter */
        plx_diff_since_read(dev);
      case XL_NOP:
      case XL_INIT:
      case XL_STOP:
        if((plx_immediate_cmd(dev, *klong) == 0)) {
       }
       else {
	retval = -EIO;
        }
       break;
    default :
      retval = -EFAULT;     
   }
   break;


  case ORDER_HW:

     switch (container->order) {
 
     case 0x1:  // Dump PCI memory
       { int i; unsigned int tmp;
       PDEBUG(("ioctl: order_hw, start_addr%x\n", container->start_addr));
       for (i = 0; i <16; i++) { 
         tmp = SRAM_READ(dev, (container->start_addr) +(i*4)); 
         container->array[i] = tmp; 

       } 

       }

       break; 
     case 0x2:   // Reset HW
       plx_board_reset(dev);
       break;
     case 0x3:  // Read and clear device driver counters
      {
       container->array[0] = dev->cntr_circ_empty_rp;
       container->array[1] = dev->cntr_irq_count;
       container->array[2] = dev->cntr_irq_processed;
       container->array[3] = dev->cntr_irq_none;
       container->array[4] = dev->cntr_low_power_state;
       container->array[5] = dev->cntr_pci_master_disabled;
       container->array[6] = dev->cntr_lost_ints;
       container->array[7] = dev->cntr_read;
       container->array[8] = dev->cntr_poll;
       container->array[9] = dev->cntr_failed_dma;
       container->array[10] = dev->cntr_circ_full_wp;
       container->array[11] = dev->cntr_circ_full_ip;
       container->array[12] = dev->cntr_2_user_space;
       container->array[13] = dev->cntr_tmo_rdr;
       container->array[14] = dev->cntr_tmo_tbe;
       container->array[15] = dev->cntr_lost_hw_ints;

       dev->cntr_circ_empty_rp = dev->cntr_irq_count = dev->cntr_irq_processed = dev->cntr_irq_none = 0;
       dev->cntr_low_power_state = dev->cntr_pci_master_disabled =  0;
       dev->cntr_read = dev->cntr_poll = dev->cntr_failed_dma = dev->cntr_2_user_space = 0;
       dev->cntr_tmo_rdr = dev->cntr_tmo_tbe = dev->cntr_circ_full_wp = dev->cntr_lost_ints = 0;
       dev->cntr_lost_hw_ints = dev->cntr_circ_full_ip = 0;
      }
      break;
     case 0x4:

     break;
     case 0x5:
#if ZERO
       PDEBUG(("order_hw: read time:%d\n", plx_diff_since_read(dev)));
#endif
     break;

#if DMA_DEBUG
     case 0x6:

     {
        int r;

        /* Write a test pattern at start address  in kernel mem */

       for(r = 0; r < NO_OF_BUFFERS ; r++) {
        *(unsigned long *)(dev->frames[r]) = 0xcdcdfbfb;

       }
     }
     break;

     case 0x7:

     {
        int r;

        /* Read test pattern at start address  in kernel mem */

       for(r = 0; r < NO_OF_BUFFERS ; r++) {
       PDEBUG(("r:%d:%lx\n", r, *(unsigned long *)(dev->frames[r])));

       }
     }
     break;

     case 0x8:
      {
          U32 RegValue;


   /* Abort a DMA, should generate an interrupt */
    RegValue =
	PLX_9000_REG_READ(
			  dev,
			  PCI8311_DMA_COMMAND_STAT
			  );

     // Abort the transfer (should cause an interrupt)
      PLX_9000_REG_WRITE(
			 dev,
			 PCI8311_DMA_COMMAND_STAT,
			 RegValue | ((1 << 2))
			 );

      }
     break;
#endif
     case 0x9:
        PDEBUG(("order_hw: ip%d, wp%d, rp%d\n", dev->ip , dev->wp, dev->rp));
        dev->wp = dev->rp = dev->ip = 0;
      break;

     /* Disable driver debug */
     case 0xa:
        debug = 0;
      break;

     /* Enable driver debug */
     case 0xb:
        debug = 1;
      break;

     /* Reset sequence counters in hw and driver */
     case 0xc:
        dev->seq_cntr = 0;
        plx_immediate_cmd(dev, XL_INIT);
      break;

     /* Generate a local interrupt */
     case 0xd:
      { u32 RegDetectorInt;

        RegDetectorInt = COMMAND_LINK_REG_READ(dev, PCI_MC_CARD_STATUS);
        RegDetectorInt |= (1<<29);
        COMMAND_LINK_REG_WRITE(dev,PCI_MC_CARD_STATUS,RegDetectorInt); 

      }  
      break;

     default:
       ERROR(("ioctl: no such order: %x\n", container->order));
       retval = -EFAULT;     
       break;
     }

  case DRIVER_VERSION:
   reg->data = DEVICE_DRIVER_VERSION;
   break;	

  case READ_CONFIG_REG:
  {
    PLX_PCI_REG_READ(dev, reg->addr,&reg->data);
   }
   break;

  default:
    ERROR(("ioctl: no such command: %x\n", cmd));
    return -ENOIOCTLCMD; 
}

  /* Finally, copy data to user space and return */
  if (retval < 0) return retval;
  if ((_IOC_DIR(cmd) & _IOC_READ) && (size <= IOC_BUFSIZE))
    if (copy_to_user((void *)arg, karg, size))
      return -EFAULT;
  return retval; /* sometimes, positive is what I want */
}
Ejemplo n.º 17
0
static void __exit exit_bof_binfmt(void) {
	PDEBUG(0, "binfmt_bof v4 unloaded\n");
	unregister_binfmt(&bof_format);
}
Ejemplo n.º 18
0
me_device_t *me4600_pci_constructor(struct pci_dev *pci_device)
#endif				//BOSCH
{
	me4600_device_t *me4600_device;
	me_subdevice_t *subdevice;
	unsigned int version_idx;
	int err;
	int i;

	PDEBUG("executed.\n");

	// Allocate structure for device instance.
	me4600_device = kmalloc(sizeof(me4600_device_t), GFP_KERNEL);

	if (!me4600_device) {
		PERROR("Cannot get memory for ME-4600 device instance.\n");
		return NULL;
	}

	memset(me4600_device, 0, sizeof(me4600_device_t));

	// Initialize base class structure.
	err = me_device_pci_init((me_device_t *) me4600_device, pci_device);

	if (err) {
		kfree(me4600_device);
		PERROR("Cannot initialize device base class.\n");
		return NULL;
	}
	// Download the xilinx firmware.
	if (me4600_device->base.info.pci.device_id == PCI_DEVICE_ID_MEILHAUS_ME4610) {	//Jekyll <=> me4610
		err =
		    me_xilinx_download(me4600_device->base.info.pci.
				       reg_bases[1],
				       me4600_device->base.info.pci.
				       reg_bases[5], &pci_device->dev,
				       "me4610.bin");
	} else {		// General me4600 firmware
#ifdef BOSCH
		err =
		    me_xilinx_download(me4600_device->base.info.pci.
				       reg_bases[1],
				       me4600_device->base.info.pci.
				       reg_bases[5], &pci_device->dev,
				       (me_bosch_fw) ? "me4600_bosch.bin" :
				       "me4600.bin");
#else //~BOSCH
		err =
		    me_xilinx_download(me4600_device->base.info.pci.
				       reg_bases[1],
				       me4600_device->base.info.pci.
				       reg_bases[5], &pci_device->dev,
				       "me4600.bin");
#endif
	}

	if (err) {
		me_device_deinit((me_device_t *) me4600_device);
		kfree(me4600_device);
		PERROR("Cannot download firmware.\n");
		return NULL;
	}
	// Get the index in the device version information table.
	version_idx =
	    me4600_versions_get_device_index(me4600_device->base.info.pci.
					     device_id);

	// Initialize spin locks.
	spin_lock_init(&me4600_device->preload_reg_lock);

	me4600_device->preload_flags = 0;

	spin_lock_init(&me4600_device->dio_lock);
	spin_lock_init(&me4600_device->ai_ctrl_lock);
	spin_lock_init(&me4600_device->ctr_ctrl_reg_lock);
	spin_lock_init(&me4600_device->ctr_clk_src_reg_lock);

	// Create digital input instances.
	for (i = 0; i < me4600_versions[version_idx].di_subdevices; i++) {
		subdevice =
		    (me_subdevice_t *) me4600_di_constructor(me4600_device->
							     base.info.pci.
							     reg_bases[2],
							     &me4600_device->
							     dio_lock);

		if (!subdevice) {
			me_device_deinit((me_device_t *) me4600_device);
			kfree(me4600_device);
			PERROR("Cannot get memory for subdevice.\n");
			return NULL;
		}

		me_slist_add_subdevice_tail(&me4600_device->base.slist,
					    subdevice);
	}

	// Create digital output instances.
	for (i = 0; i < me4600_versions[version_idx].do_subdevices; i++) {
		subdevice =
		    (me_subdevice_t *) me4600_do_constructor(me4600_device->
							     base.info.pci.
							     reg_bases[2],
							     &me4600_device->
							     dio_lock);

		if (!subdevice) {
			me_device_deinit((me_device_t *) me4600_device);
			kfree(me4600_device);
			PERROR("Cannot get memory for subdevice.\n");
			return NULL;
		}

		me_slist_add_subdevice_tail(&me4600_device->base.slist,
					    subdevice);
	}

	// Create digital input/output instances.
	for (i = 0; i < me4600_versions[version_idx].dio_subdevices; i++) {
		subdevice =
		    (me_subdevice_t *) me4600_dio_constructor(me4600_device->
							      base.info.pci.
							      reg_bases[2],
							      me4600_versions
							      [version_idx].
							      do_subdevices +
							      me4600_versions
							      [version_idx].
							      di_subdevices + i,
							      &me4600_device->
							      dio_lock);

		if (!subdevice) {
			me_device_deinit((me_device_t *) me4600_device);
			kfree(me4600_device);
			PERROR("Cannot get memory for subdevice.\n");
			return NULL;
		}

		me_slist_add_subdevice_tail(&me4600_device->base.slist,
					    subdevice);
	}

	// Create analog input instances.
	for (i = 0; i < me4600_versions[version_idx].ai_subdevices; i++) {
		subdevice =
		    (me_subdevice_t *) me4600_ai_constructor(me4600_device->
							     base.info.pci.
							     reg_bases[2],
							     me4600_versions
							     [version_idx].
							     ai_channels,
							     me4600_versions
							     [version_idx].
							     ai_ranges,
							     me4600_versions
							     [version_idx].
							     ai_isolated,
							     me4600_versions
							     [version_idx].
							     ai_sh,
							     me4600_device->
							     base.irq,
							     &me4600_device->
							     ai_ctrl_lock,
							     me4600_workqueue);

		if (!subdevice) {
			me_device_deinit((me_device_t *) me4600_device);
			kfree(me4600_device);
			PERROR("Cannot get memory for subdevice.\n");
			return NULL;
		}

		me_slist_add_subdevice_tail(&me4600_device->base.slist,
					    subdevice);
	}

	// Create analog output instances.
	for (i = 0; i < me4600_versions[version_idx].ao_subdevices; i++) {
#ifdef BOSCH
		subdevice =
		    (me_subdevice_t *) me4600_ao_constructor(me4600_device->
							     base.info.pci.
							     reg_bases[2],
							     &me4600_device->
							     preload_reg_lock,
							     &me4600_device->
							     preload_flags, i,
							     me4600_versions
							     [version_idx].
							     ao_fifo,
							     me4600_device->
							     base.irq);
#else //~BOSCH
		subdevice =
		    (me_subdevice_t *) me4600_ao_constructor(me4600_device->
							     base.info.pci.
							     reg_bases[2],
							     &me4600_device->
							     preload_reg_lock,
							     &me4600_device->
							     preload_flags, i,
							     me4600_versions
							     [version_idx].
							     ao_fifo,
							     me4600_device->
							     base.irq,
							     me4600_workqueue);
#endif

		if (!subdevice) {
			me_device_deinit((me_device_t *) me4600_device);
			kfree(me4600_device);
			PERROR("Cannot get memory for subdevice.\n");
			return NULL;
		}

		me_slist_add_subdevice_tail(&me4600_device->base.slist,
					    subdevice);
	}

	// Create counter instances.
	for (i = 0; i < me4600_versions[version_idx].ctr_subdevices; i++) {
		subdevice =
		    (me_subdevice_t *) me8254_constructor(me4600_device->base.
							  info.pci.device_id,
							  me4600_device->base.
							  info.pci.reg_bases[3],
							  0, i,
							  &me4600_device->
							  ctr_ctrl_reg_lock,
							  &me4600_device->
							  ctr_clk_src_reg_lock);

		if (!subdevice) {
			me_device_deinit((me_device_t *) me4600_device);
			kfree(me4600_device);
			PERROR("Cannot get memory for subdevice.\n");
			return NULL;
		}

		me_slist_add_subdevice_tail(&me4600_device->base.slist,
					    subdevice);
	}

	// Create external interrupt instances.
	for (i = 0; i < me4600_versions[version_idx].ext_irq_subdevices; i++) {
		subdevice =
		    (me_subdevice_t *)
		    me4600_ext_irq_constructor(me4600_device->base.info.pci.
					       reg_bases[2],
					       me4600_device->base.irq,
					       &me4600_device->ai_ctrl_lock);

		if (!subdevice) {
			me_device_deinit((me_device_t *) me4600_device);
			kfree(me4600_device);
			PERROR("Cannot get memory for subdevice.\n");
			return NULL;
		}

		me_slist_add_subdevice_tail(&me4600_device->base.slist,
					    subdevice);
	}

	return (me_device_t *) me4600_device;
}
Ejemplo n.º 19
0
QpskSymbolMapper::~QpskSymbolMapper()
{
    PDEBUG("QpskSymbolMapper::~QpskSymbolMapper() @ %p\n", this);

}
Ejemplo n.º 20
0
/**
 * Convert guest absolute VFS path (starting from VFS root) to a host path
 * within mounted shared folder (returning it as a char *).
 *
 * @param mp            Mount data structure
 * @param pszGuestPath  Guest absolute VFS path (starting from VFS root)
 * @param cbGuestPath   Size of pszGuestPath
 * @param pszHostPath   Returned char * wich contains host path
 * @param cbHostPath    Returned pszHostPath size
 *
 * @return 0 on success, error code otherwise
 */
int
vboxvfs_guest_path_to_char_path_internal(mount_t mp, char *pszGuestPath, int cbGuestPath, char **pszHostPath, int *cbHostPath)
{
    vboxvfs_mount_t *pMount;

    /* Guest side: mount point path buffer and its size */
    char       *pszMntPointPath;
    int         cbMntPointPath = MAXPATHLEN;

    /* Host side: path within mounted shared folder and its size */
    char       *pszHostPathInternal;
    size_t      cbHostPathInternal;

    int rc;

    AssertReturn(mp, EINVAL);
    AssertReturn(pszGuestPath, EINVAL); AssertReturn(cbGuestPath >= 0, EINVAL);
    AssertReturn(pszHostPath,  EINVAL); AssertReturn(cbHostPath,       EINVAL);

    pMount = (vboxvfs_mount_t *)vfs_fsprivate(mp); AssertReturn(pMount, EINVAL); AssertReturn(pMount->pRootVnode, EINVAL);

    /* Get mount point path */
    pszMntPointPath = (char *)RTMemAllocZ(cbMntPointPath);
    if (pszMntPointPath)
    {
        rc = vn_getpath(pMount->pRootVnode, pszMntPointPath, &cbMntPointPath);
        if (rc == 0 && cbGuestPath >= cbMntPointPath)
        {
            cbHostPathInternal  = cbGuestPath - cbMntPointPath + 1;
            pszHostPathInternal = (char *)RTMemAllocZ(cbHostPathInternal);
            if (pszHostPathInternal)
            {
                memcpy(pszHostPathInternal, pszGuestPath + cbMntPointPath, cbGuestPath - cbMntPointPath);
                PDEBUG("guest<->host path converion result: '%s' mounted to '%s'", pszHostPathInternal, pszMntPointPath);

                RTMemFree(pszMntPointPath);

                *pszHostPath = pszHostPathInternal;
                *cbHostPath  = cbGuestPath - cbMntPointPath;

                return 0;

            }
            else
            {
                PDEBUG("No memory to allocate buffer for guest<->host path conversion (cbHostPathInternal)");
                rc = ENOMEM;
            }

        }
        else
        {
            PDEBUG("Unable to get guest vnode path: %d", rc);
        }

        RTMemFree(pszMntPointPath);
    }
    else
    {
        PDEBUG("No memory to allocate buffer for guest<->host path conversion (pszMntPointPath)");
        rc = ENOMEM;
    }

    return rc;
}
Ejemplo n.º 21
0
int main(int argc, char **argv)
{
	int err;
	struct capfs_upcall up;
	struct capfs_downcall down;
	struct capfs_dirent *dent = NULL;
	char *link_name = NULL;
	int opt = 0;
	int capfsd_log_level = CRITICAL_MSG | WARNING_MSG;
	char options[256];
	struct cas_options cas_options = {
doInstrumentation:0,
use_sockets:0,
	};

#ifdef DEBUG
	capfsd_log_level |= INFO_MSG;
	capfsd_log_level |= DEBUG_MSG;
#endif
	set_log_level(capfsd_log_level);
	/* capfsd must register a callback with the meta-data server at the time of mount */
	check_for_registration = 1;
	while((opt = getopt(argc, argv, "dhsn:p:")) != EOF) {
		switch(opt){
			case 's':
				cas_options.use_sockets = 1;
				break;
			case  'd':
				is_daemon = 0;
				break;
			case 'p':
				err = sscanf(optarg, "%x", &capfs_debug);
				if(err != 1){
					usage();
					exiterror("bad arguments");
					exit(1);
				}
				break;
			case 'n':
				num_threads = atoi(optarg);
				break;
			case 'h':
				usage();
				exit(0);
			case '?':
			default:
				usage();
				exiterror("bad arguments");
				exit(1);
		}
	}
		
	if (getuid() != 0 && geteuid() != 0) {
		exiterror("must be run as root");
		exit(1);
	}

	if (setup_capfsdev() < 0) {
		exiterror("setup_capfsdev() failed");
		exit(1);
	}

	if ((dev_fd = open_capfsdev()) < 0) {
		exiterror("open_capfsdev() failed");
		exit(1);
	}
	
	startup(argc, argv);
	/* Initialize the plugin interface */
	capfsd_plugin_init();

	capfs_comm_init();


	/* allocate a 64K, page-aligned buffer for small operations */
	capfs_opt_io_size = ROUND_UP(CAPFS_OPT_IO_SIZE);
	if ((orig_iobuf = (char *) valloc(capfs_opt_io_size)) == NULL) {
		exiterror("calloc failed");
		capfsd_plugin_cleanup();
		exit(1);
	}
	memset(orig_iobuf, 0, capfs_opt_io_size);
	capfs_dent_size = ROUND_UP((FETCH_DENTRY_COUNT * sizeof(struct capfs_dirent)));
	/* allocate a suitably large dent buffer for getdents speed up */
	if ((dent = (struct capfs_dirent *) valloc(capfs_dent_size)) == NULL) {
		exiterror("calloc failed");
		capfsd_plugin_cleanup();
		exit(1);
	}
	memset(dent, 0, capfs_dent_size);
	/* maximum size of a link target cannot be > 4096 */
	capfs_link_size = ROUND_UP(4096);
	link_name = (char *) valloc(capfs_link_size);
	if(!link_name) {
		exiterror("calloc failed");
		capfsd_plugin_cleanup();
		exit(1);
	}
	memset(link_name, 0, capfs_link_size);
	
	fprintf(stderr, "------------ Starting client daemon servicing VFS requests using a thread pool [%d threads] ----------\n",
			num_threads);
	/*
	 * Start up the local RPC service on both TCP/UDP 
	 * for callbacks.
	 */
	pmap_unset(CAPFS_CAPFSD, clientv1);
	if (setup_service(CAPFS_CAPFSD /* program number */,
				clientv1 /* version */,
				-1 /* both tcp/udp */,
				-1 /* any available port */,
				CAPFS_DISPATCH_FN(clientv1) /* dispatch routine */,
				&info) < 0) {
		exiterror("Could not setup local RPC service!\n");
		capfsd_plugin_cleanup();
		exit(1);
	}
	/*
	 * Initialize the hash cache.
	 * Note that we are using default values of cache sizes,
	 * and this should probably be an exposed knob to the user.
	 * CMGR_BSIZE is == CAPFS_MAXHASHLENGTH for SHA1-hash. So we dont need to set
	 * that. We use environment variables to communicate the parameters
	 * to the caches.
	 */
	snprintf(options, 256, "%d", CAPFS_CHUNK_SIZE);
	setenv("CMGR_CHUNK_SIZE", options, 1);
	snprintf(options, 256, "%d", CAPFS_HCACHE_COUNT);
	setenv("CMGR_BCOUNT", options, 1);
	init_hashes();
#if 0
	/*
	 * Initialize the client-side data cache.
	 * Note that we are not using this layer
	 * right now. It is getting fairly complicated already.
	 */
	snprintf(options, 256, "%d", CAPFS_DCACHE_BSIZE);
	setenv("CMGR_BSIZE", options, 1);
	snprintf(options, 256, "%d", CAPFS_DCACHE_COUNT);
	setenv("CMGR_BCOUNT", options, 1);
#endif
	/*
	 * Initialize the client-side data server communication
	 * stuff.
	 */
	clnt_init(&cas_options, num_threads, CAPFS_CHUNK_SIZE);
	
	/* loop forever, doing:
	 * - read from device
	 * - service request
	 * - write back response
	 */
	for (;;) {
		struct timeval begin, end;

		err = read_capfsdev(dev_fd, &up, 30);
		if (err < 0) {
			/* cleanup the hash cache */
			cleanup_hashes();
			/* Cleanup the RPC service */
			cleanup_service(&info);
			capfs_comm_shutdown();
			close_capfsdev(dev_fd);
			/* cleanup the plugins */
			capfsd_plugin_cleanup();
			/* cleanup the client-side stuff */
			clnt_finalize();
			exiterror("read failed\n");
			exit(1);
		}
		if (err == 0) {
			/* timed out */
			capfs_comm_idle();
			continue;
		}
		gettimeofday(&begin, NULL);
		/* the do_capfs_op() call does this already; can probably remove */
		init_downcall(&down, &up);

		err = 0;
		switch (up.type) {
			/* all the easy operations */
		case GETMETA_OP:
		case SETMETA_OP:
		case LOOKUP_OP:
		case CREATE_OP:
		case REMOVE_OP:
		case RENAME_OP:
		case SYMLINK_OP:
		case MKDIR_OP:
		case RMDIR_OP:
		case STATFS_OP:
		case HINT_OP:
		case FSYNC_OP:
		case LINK_OP:
		{
			PDEBUG(D_UPCALL, "read upcall; type = %d, name = %s\n", up.type,
					 up.v1.fhname);
			err = do_capfs_op(&up, &down);
			if (err < 0) {
				PDEBUG(D_LIB, "do_capfs_op failed for type %d\n", up.type);
			}
			break;
			/* the more interesting ones */
		}
		case GETDENTS_OP:
			/* need to pass location and size of buffer to do_capfs_op() */
			up.xfer.ptr = dent;
			up.xfer.size = capfs_dent_size;
			err = do_capfs_op(&up, &down);
			if (err < 0) {
				PDEBUG(D_LIB, "do_capfs_op failed for getdents\n");
			}
			break;
		case READLINK_OP:
			/* need to pass location and size of buffer to hold the target name */
			up.xfer.ptr = link_name;
			up.xfer.size = capfs_link_size;
			err = do_capfs_op(&up, &down);
			if(err < 0) {
				PDEBUG(D_LIB, "do_capfs_op failed for readlink\n");
			}
			break;
		case READ_OP:
			err = read_op(&up, &down);
			if (err < 0) {
				PDEBUG(D_LIB, "read_op failed\n");
			}
			break;
		case WRITE_OP:
			err = write_op(&up, &down);
			if (err < 0) {
				PDEBUG(D_LIB, "do_capfs_op failed\n");
			}
			break;
			/* things that aren't done yet */
		default:
			err = -ENOSYS;
			break;
		}
		gettimeofday(&end, NULL);
		/* calculate the total time spent servicing this call */
		if (end.tv_usec < begin.tv_usec) {
			end.tv_usec += 1000000;
			end.tv_sec--;
		}
		end.tv_sec -= begin.tv_sec;
		end.tv_usec -= begin.tv_usec;
		down.total_time = (end.tv_sec * 1000000 + end.tv_usec);
		down.error = err;

		switch(up.type)
		{
		case HINT_OP:
			/* this is a one shot hint, we don't want a response in case of HINT_OPEN/HINT_CLOSE */
			if (up.u.hint.hint == HINT_CLOSE || up.u.hint.hint == HINT_OPEN) {
				err = 0;
				break;
			}
			/* fall through */
		default:
			/* the default behavior is to write a response to the device */
			err = write_capfsdev(dev_fd, &down, -1);
			if (err < 0) {
				/* cleanup the hash cache */
				cleanup_hashes();
				/* Cleanup the RPC service */
				cleanup_service(&info);
				capfs_comm_shutdown();
				close_capfsdev(dev_fd);
				/* Cleanup the plugins */
				capfsd_plugin_cleanup();
				/* cleanup the client-side stuff */
				clnt_finalize();
				exiterror("write failed");
				exit(1);
			}
			break;
		}

		/* If we used a big I/O buffer, free it after we have successfully
		 * returned the downcall.
		 */
		if (big_iobuf != NULL) {
			free(big_iobuf);
			big_iobuf = NULL;
		}
	}
	/* Not reached */
	/* cleanup the hash cache */
	cleanup_hashes();
	/* Cleanup the RPC service */
	cleanup_service(&info);
	capfs_comm_shutdown();
	close_capfsdev(dev_fd);
	/* cleanup the plugins */
	capfsd_plugin_cleanup();
	/* cleanup the client-side stuff */
	clnt_finalize();
	exit(1);
}
Ejemplo n.º 22
0
/**
 * Helper function to create XNU VFS vnode object.
 *
 * @param mp        Mount data structure
 * @param type      vnode type (directory, regular file, etc)
 * @param pParent   Parent vnode object (NULL for VBoxVFS root vnode)
 * @param fIsRoot   Flag that indicates if created vnode object is
 *                  VBoxVFS root vnode (TRUE for VBoxVFS root vnode, FALSE
 *                  for all aother vnodes)
 * @param           Path within Shared Folder
 * @param ret       Returned newly created vnode
 *
 * @return 0 on success, error code otherwise
 */
int
vboxvfs_create_vnode_internal(struct mount *mp, enum vtype type, vnode_t pParent, int fIsRoot, PSHFLSTRING Path, vnode_t *ret)
{
    int     rc;
    vnode_t vnode;

    vboxvfs_vnode_t  *pVnodeData;
    vboxvfs_mount_t  *pMount;

    AssertReturn(mp, EINVAL);

    pMount = (vboxvfs_mount_t *)vfs_fsprivate(mp);
    AssertReturn(pMount, EINVAL);
    AssertReturn(pMount->pLockGroup, EINVAL);

    AssertReturn(Path, EINVAL);

    pVnodeData = (vboxvfs_vnode_t *)RTMemAllocZ(sizeof(vboxvfs_vnode_t));
    AssertReturn(pVnodeData, ENOMEM);

    /* Initialize private data */
    pVnodeData->pHandle = SHFL_HANDLE_NIL;
    pVnodeData->pPath   = Path;

    pVnodeData->pLockAttr = lck_attr_alloc_init();
    if (pVnodeData->pLockAttr)
    {
        pVnodeData->pLock = lck_rw_alloc_init(pMount->pLockGroup, pVnodeData->pLockAttr);
        if (pVnodeData->pLock)
        {
            struct vnode_fsparam vnode_params;

            vnode_params.vnfs_mp         = mp;
            vnode_params.vnfs_vtype      = type;
            vnode_params.vnfs_str        = NULL;
            vnode_params.vnfs_dvp        = pParent;
            vnode_params.vnfs_fsnode     = pVnodeData;  /** Private data attached per xnu's vnode object */
            vnode_params.vnfs_vops       = g_VBoxVFSVnodeDirOpsVector;

            vnode_params.vnfs_markroot   = fIsRoot;
            vnode_params.vnfs_marksystem = FALSE;
            vnode_params.vnfs_rdev       = 0;
            vnode_params.vnfs_filesize   = 0;
            vnode_params.vnfs_cnp        = NULL;

            vnode_params.vnfs_flags      = VNFS_ADDFSREF | VNFS_NOCACHE;

            rc = vnode_create(VNCREATE_FLAVOR, sizeof(vnode_params), &vnode_params, &vnode);
            if (rc == 0)
                *ret = vnode;

            return 0;
        }
        else
        {
            PDEBUG("Unable to allocate lock");
            rc = ENOMEM;
        }

        lck_attr_free(pVnodeData->pLockAttr);
    }
    else
    {
        PDEBUG("Unable to allocate lock attr");
        rc = ENOMEM;
    }

    return rc;
}
Ejemplo n.º 23
0
static void prism2_host_roaming(local_info_t *local)
{
	struct hfa384x_join_request req;
	struct net_device *dev = local->dev;
	struct hfa384x_hostscan_result *selected, *entry;
	int i;
	unsigned long flags;

	if (local->last_join_time &&
	    time_before(jiffies, local->last_join_time + 10 * HZ)) {
		PDEBUG(DEBUG_EXTRA, "%s: last join request has not yet been "
		       "completed - waiting for it before issuing new one\n",
		       dev->name);
		return;
	}

	/* ScanResults are sorted: first ESS results in decreasing signal
	 * quality then IBSS results in similar order.
	 * Trivial roaming policy: just select the first entry.
	 * This could probably be improved by adding hysteresis to limit
	 * number of handoffs, etc.
	 *
	 * Could do periodic RID_SCANREQUEST or Inquire F101 to get new
	 * ScanResults */
	spin_lock_irqsave(&local->lock, flags);
	if (local->last_scan_results == NULL ||
	    local->last_scan_results_count == 0) {
		spin_unlock_irqrestore(&local->lock, flags);
		PDEBUG(DEBUG_EXTRA, "%s: no scan results for host roaming\n",
		       dev->name);
		return;
	}

	selected = &local->last_scan_results[0];

	if (local->preferred_ap[0] || local->preferred_ap[1] ||
	    local->preferred_ap[2] || local->preferred_ap[3] ||
	    local->preferred_ap[4] || local->preferred_ap[5]) {
		/* Try to find preferred AP */
		PDEBUG(DEBUG_EXTRA, "%s: Preferred AP BSSID %pM\n",
		       dev->name, local->preferred_ap);
		for (i = 0; i < local->last_scan_results_count; i++) {
			entry = &local->last_scan_results[i];
			if (memcmp(local->preferred_ap, entry->bssid, 6) == 0)
			{
				PDEBUG(DEBUG_EXTRA, "%s: using preferred AP "
				       "selection\n", dev->name);
				selected = entry;
				break;
			}
		}
	}

	memcpy(req.bssid, selected->bssid, 6);
	req.channel = selected->chid;
	spin_unlock_irqrestore(&local->lock, flags);

	PDEBUG(DEBUG_EXTRA, "%s: JoinRequest: BSSID=%pM"
	       " channel=%d\n",
	       dev->name, req.bssid, le16_to_cpu(req.channel));
	if (local->func->set_rid(dev, HFA384X_RID_JOINREQUEST, &req,
				 sizeof(req))) {
;
	}
	local->last_join_time = jiffies;
}
static int __init me1400_init(void)
{
	PDEBUG("executed.\n");
	return 0;
}
Ejemplo n.º 25
0
static int pthread_allocate_stack(const pthread_attr_t *attr,
                                  pthread_descr default_new_thread,
                                  int pagesize,
                                  pthread_descr * out_new_thread,
                                  char ** out_new_thread_bottom,
                                  char ** out_guardaddr,
                                  size_t * out_guardsize)
{
  pthread_descr new_thread;
  char * new_thread_bottom;
  char * guardaddr;
  size_t stacksize, guardsize;

  if (attr != NULL && attr->__stackaddr_set)
    {
      /* The user provided a stack. */
      new_thread =
        (pthread_descr) ((long)(attr->__stackaddr) & -sizeof(void *)) - 1;
      new_thread_bottom = (char *) attr->__stackaddr - attr->__stacksize;
      guardaddr = NULL;
      guardsize = 0;
      __pthread_nonstandard_stacks = 1;
    }
  else
    {
#ifdef __ARCH_USE_MMU__
      stacksize = STACK_SIZE - pagesize;
      if (attr != NULL)
        stacksize = MIN (stacksize, roundup(attr->__stacksize, pagesize));
      /* Allocate space for stack and thread descriptor at default address */
      new_thread = default_new_thread;
      new_thread_bottom = (char *) (new_thread + 1) - stacksize;
      if (mmap((caddr_t)((char *)(new_thread + 1) - INITIAL_STACK_SIZE),
               INITIAL_STACK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
               MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED | MAP_GROWSDOWN,
               -1, 0) == MAP_FAILED)
        /* Bad luck, this segment is already mapped. */
        return -1;
      /* We manage to get a stack.  Now see whether we need a guard
         and allocate it if necessary.  Notice that the default
         attributes (stack_size = STACK_SIZE - pagesize) do not need
	 a guard page, since the RLIMIT_STACK soft limit prevents stacks
	 from running into one another. */
      if (stacksize == (size_t) (STACK_SIZE - pagesize))
        {
          /* We don't need a guard page. */
          guardaddr = NULL;
          guardsize = 0;
        }
      else
        {
          /* Put a bad page at the bottom of the stack */
          guardsize = attr->__guardsize;
          guardaddr = (void *)new_thread_bottom - guardsize;
          if (mmap ((caddr_t) guardaddr, guardsize, 0, MAP_FIXED, -1, 0)
              == MAP_FAILED)
            {
              /* We don't make this an error.  */
              guardaddr = NULL;
              guardsize = 0;
            }
        }
#else
      /* We cannot mmap to this huge chunk of stack space when we don't have
       * an MMU. Pretend we are using a user provided stack even if there was
       * none provided by the user. Thus, we get around the mmap and reservation
       * of a huge stack segment. -StS */

      stacksize = INITIAL_STACK_SIZE;
      /* The user may want to use a non-default stacksize */
      if (attr != NULL)
	{
	  stacksize = attr->__stacksize;
	}
      
      /* malloc a stack - memory from the bottom up */
      if ((new_thread_bottom = malloc(stacksize)) == NULL)
	{
	  /* bad luck, we cannot malloc any more */
	  return -1 ;
	}
      PDEBUG("malloced chunk: base=%p, size=0x%04x\n", new_thread_bottom, stacksize);

      /* Set up the pointers. new_thread marks the TOP of the stack frame and
       * the address of the pthread_descr struct at the same time. Therefore we
       * must account for its size and fit it in the malloc()'ed block. The
       * value of `new_thread' is then passed to clone() as the stack argument.
       *
       *               ^ +------------------------+
       *               | |  pthread_descr struct  |
       *               | +------------------------+  <- new_thread 
       * malloc block  | |                        |
       *               | |  thread stack          |
       *               | |                        |
       *               v +------------------------+  <- new_thread_bottom
       *
       * Note: The calculated value of new_thread must be word aligned otherwise
       * the kernel chokes on a non-aligned stack frame. Choose the lower
       * available word boundary.
       */
      new_thread = ((pthread_descr) ((int)(new_thread_bottom + stacksize) & -sizeof(void*))) - 1;
      guardaddr = NULL;
      guardsize = 0;
      
      PDEBUG("thread stack: bos=%p, tos=%p\n", new_thread_bottom, new_thread);
      
      /* check the initial thread stack boundaries so they don't overlap */
      NOMMU_INITIAL_THREAD_BOUNDS((char *) new_thread, (char *) new_thread_bottom);
      
      PDEBUG("initial stack: bos=%p, tos=%p\n", __pthread_initial_thread_bos, 
	     __pthread_initial_thread_tos);
      
      /* on non-MMU systems we always have non-standard stack frames */
      __pthread_nonstandard_stacks = 1;
      
#endif /* __ARCH_USE_MMU__ */
    }

  /* Clear the thread data structure.  */
  memset (new_thread, '\0', sizeof (*new_thread));
  *out_new_thread = new_thread;
  *out_new_thread_bottom = new_thread_bottom;
  *out_guardaddr = guardaddr;
  *out_guardsize = guardsize;
  return 0;
}
static void __exit me1400_exit(void)
{
	PDEBUG("executed.\n");
}
/*! Release device STUB

\param[in]	dev:		device control block
\return		void
*/
static void smsspi_release(struct device *dev)
{
    PDEBUG("nothing to do\n");
    /* Nothing to release */
}
me_device_t *me1400_pci_constructor(struct pci_dev *pci_device)
{
	int err;
	me1400_device_t *me1400_device;
	me_subdevice_t *subdevice;
	unsigned int version_idx;
	unsigned int me8255_idx;
	unsigned int dio_idx;
	unsigned int me8254_idx;
	unsigned int ctr_idx;
	unsigned int ext_irq_idx;

	PDEBUG("executed.\n");

	// Allocate structure for device instance.
	me1400_device = kmalloc(sizeof(me1400_device_t), GFP_KERNEL);

	if (!me1400_device) {
		PERROR("Cannot get memory for 1400ate device instance.\n");
		return NULL;
	}

	memset(me1400_device, 0, sizeof(me1400_device_t));

	// Initialize base class structure.
	err = me_device_pci_init((me_device_t *) me1400_device, pci_device);

	if (err) {
		kfree(me1400_device);
		PERROR("Cannot initialize device base class.\n");
		return NULL;
	}

	/* Check for ME1400 extension device. If detected we fake a ME-1400 D device id. */
	if (me1400_device->base.info.pci.device_id ==
	    PCI_DEVICE_ID_MEILHAUS_ME140C) {
		uint8_t ctrl;
		ctrl =
		    inb(me1400_device->base.info.pci.reg_bases[2] +
			ME1400D_CLK_SRC_2_REG);
		PDEBUG_REG("xxx_reg inb(0x%X+0x%X)=0x%x\n",
			   me1400_device->base.info.pci.reg_bases[2],
			   ME1400D_CLK_SRC_2_REG, ctrl);
		outb(ctrl | 0xF0,
		     me1400_device->base.info.pci.reg_bases[2] +
		     ME1400D_CLK_SRC_2_REG);
		PDEBUG_REG("xxx_reg outb(0x%X+0x%X)=0x%x\n",
			   me1400_device->base.info.pci.reg_bases[2],
			   ME1400D_CLK_SRC_2_REG, ctrl | 0xF0);
		ctrl =
		    inb(me1400_device->base.info.pci.reg_bases[2] +
			ME1400D_CLK_SRC_2_REG);
		PDEBUG_REG("xxx_reg inb(0x%X+0x%X)=0x%x\n",
			   me1400_device->base.info.pci.reg_bases[2],
			   ME1400D_CLK_SRC_2_REG, ctrl);

		if ((ctrl & 0xF0) == 0xF0) {
			PINFO("ME1400 D detected.\n");
			me1400_device->base.info.pci.device_id =
			    PCI_DEVICE_ID_MEILHAUS_ME140D;
		}
	}

	/* Initialize global stuff of digital i/o subdevices. */
	for (me8255_idx = 0; me8255_idx < ME1400_MAX_8255; me8255_idx++) {
		me1400_device->dio_current_mode[me8255_idx] = 0;
		spin_lock_init(&me1400_device->dio_ctrl_reg_lock[me8255_idx]);
	}

	/* Initialize global stuff of counter subdevices. */
	spin_lock_init(&me1400_device->clk_src_reg_lock);

	for (me8254_idx = 0; me8254_idx < ME1400_MAX_8254; me8254_idx++)
		spin_lock_init(&me1400_device->ctr_ctrl_reg_lock[me8254_idx]);

	/* Get the index in the device version information table. */
	version_idx =
	    me1400_versions_get_device_index(me1400_device->base.info.pci.
					     device_id);

	/* Generate DIO subdevice instances. */
	for (me8255_idx = 0;
	     me8255_idx < me1400_versions[version_idx].dio_chips;
	     me8255_idx++) {
		for (dio_idx = 0; dio_idx < 3; dio_idx++) {
			subdevice =
			    (me_subdevice_t *)
			    me8255_constructor(me1400_versions[version_idx].
					       device_id,
					       me1400_device->base.info.pci.
					       reg_bases[2], me8255_idx,
					       dio_idx,
					       &me1400_device->
					       dio_current_mode[me8255_idx],
					       &me1400_device->
					       dio_ctrl_reg_lock[me8255_idx]);

			if (!subdevice) {
				me_device_deinit((me_device_t *) me1400_device);
				kfree(me1400_device);
				PERROR("Cannot get memory for subdevice.\n");
				return NULL;
			}

			me_slist_add_subdevice_tail(&me1400_device->base.slist,
						    subdevice);
		}
	}

	/* Generate counter subdevice instances. */
	for (me8254_idx = 0;
	     me8254_idx < me1400_versions[version_idx].ctr_chips;
	     me8254_idx++) {
		for (ctr_idx = 0; ctr_idx < 3; ctr_idx++) {
			subdevice =
			    (me_subdevice_t *)
			    me8254_constructor(me1400_device->base.info.pci.
					       device_id,
					       me1400_device->base.info.pci.
					       reg_bases[2], me8254_idx,
					       ctr_idx,
					       &me1400_device->
					       ctr_ctrl_reg_lock[me8254_idx],
					       &me1400_device->
					       clk_src_reg_lock);

			if (!subdevice) {
				me_device_deinit((me_device_t *) me1400_device);
				kfree(me1400_device);
				PERROR("Cannot get memory for subdevice.\n");
				return NULL;
			}

			me_slist_add_subdevice_tail(&me1400_device->base.slist,
						    subdevice);
		}
	}

	/* Generate external interrupt subdevice instances. */
	for (ext_irq_idx = 0;
	     ext_irq_idx < me1400_versions[version_idx].ext_irq_subdevices;
	     ext_irq_idx++) {
		subdevice =
		    (me_subdevice_t *)
		    me1400_ext_irq_constructor(me1400_device->base.info.pci.
					       device_id,
					       me1400_device->base.info.pci.
					       reg_bases[1],
					       me1400_device->base.info.pci.
					       reg_bases[2],
					       &me1400_device->clk_src_reg_lock,
					       me1400_device->base.irq);

		if (!subdevice) {
			me_device_deinit((me_device_t *) me1400_device);
			kfree(me1400_device);
			PERROR("Cannot get memory for subdevice.\n");
			return NULL;
		}

		me_slist_add_subdevice_tail(&me1400_device->base.slist,
					    subdevice);
	}

	return (me_device_t *) me1400_device;
}
Ejemplo n.º 29
0
static int me8100_di_io_irq_start(me_subdevice_t *subdevice,
				  struct file *filep,
				  int channel,
				  int irq_source,
				  int irq_edge, int irq_arg, int flags)
{
	me8100_di_subdevice_t *instance;
	int err = ME_ERRNO_SUCCESS;
	uint16_t ctrl;
	unsigned long cpu_flags;

	PDEBUG("executed.\n");

	instance = (me8100_di_subdevice_t *) subdevice;

	if (irq_source == ME_IRQ_SOURCE_DIO_PATTERN) {
		if (flags &
		    ~(ME_IO_IRQ_START_PATTERN_FILTERING |
		      ME_IO_IRQ_START_DIO_WORD)) {
			PERROR("Invalid flag specified.\n");
			return ME_ERRNO_INVALID_FLAGS;
		}

		if (irq_edge != ME_IRQ_EDGE_NOT_USED) {
			PERROR("Invalid irq edge specified.\n");
			return ME_ERRNO_INVALID_IRQ_EDGE;
		}
	} else if (irq_source == ME_IRQ_SOURCE_DIO_MASK) {
		if (flags &
		    ~(ME_IO_IRQ_START_EXTENDED_STATUS |
		      ME_IO_IRQ_START_DIO_WORD)) {
			PERROR("Invalid flag specified.\n");
			return ME_ERRNO_INVALID_FLAGS;
		}

		if (irq_edge != ME_IRQ_EDGE_ANY) {
			PERROR("Invalid irq edge specified.\n");
			return ME_ERRNO_INVALID_IRQ_EDGE;
		}

		if (!(irq_arg & 0xFFFF)) {
			PERROR("No mask specified.\n");
			return ME_ERRNO_INVALID_IRQ_ARG;
		}
	} else {
		PERROR("Invalid irq source specified.\n");
		return ME_ERRNO_INVALID_IRQ_SOURCE;
	}

	if (channel) {
		PERROR("Invalid channel specified.\n");
		return ME_ERRNO_INVALID_CHANNEL;
	}

	ME_SUBDEVICE_ENTER;

	spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
	if (irq_source == ME_IRQ_SOURCE_DIO_PATTERN) {
		outw(irq_arg, instance->pattern_reg);
		instance->compare_value = irq_arg;
		instance->filtering_flag =
		    (flags & ME_IO_IRQ_START_PATTERN_FILTERING) ? 1 : 0;
	}
	if (irq_source == ME_IRQ_SOURCE_DIO_MASK) {
		outw(irq_arg, instance->mask_reg);
	}

	spin_lock(instance->ctrl_reg_lock);
	ctrl = inw(instance->ctrl_reg);
	ctrl |= ME8100_DIO_CTRL_BIT_INTB_0;
	if (irq_source == ME_IRQ_SOURCE_DIO_PATTERN) {
		ctrl &= ~ME8100_DIO_CTRL_BIT_INTB_1;
	}

	if (irq_source == ME_IRQ_SOURCE_DIO_MASK) {
		ctrl |= ME8100_DIO_CTRL_BIT_INTB_1;
	}
	outw(ctrl, instance->ctrl_reg);
	PDEBUG_REG("ctrl_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
		   instance->ctrl_reg - instance->reg_base, ctrl);
	spin_unlock(instance->ctrl_reg_lock);

	instance->rised = 0;
	instance->status_value = 0;
	instance->status_value_edges = 0;
	instance->line_value = inw(instance->port_reg);
	instance->status_flag = flags & ME_IO_IRQ_START_EXTENDED_STATUS;
	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);

	ME_SUBDEVICE_EXIT;

	return err;
}
Ejemplo n.º 30
0
static void citty_set_termios(struct tty_struct *tty,
			      struct ktermios *old_termios)
{
	unsigned int cflag;

	F_ENTER();
	cflag = tty->termios.c_cflag;

	/* check that they really want us to change something */
	if (old_termios) {
		if ((cflag == old_termios->c_cflag) &&
		    (RELEVANT_IFLAG(tty->termios.c_iflag) ==
		     RELEVANT_IFLAG(old_termios->c_iflag))) {
			PDEBUG(" - nothing to change...\n");
			return;
		}
	}

	/* get the byte size */
	switch (cflag & CSIZE) {
	case CS5:
		PDEBUG(" - data bits = 5\n");
		break;
	case CS6:
		PDEBUG(" - data bits = 6\n");
		break;
	case CS7:
		PDEBUG(" - data bits = 7\n");
		break;
	default:
	case CS8:
		PDEBUG(" - data bits = 8\n");
		break;
	}

	/* determine the parity */
	if (cflag & PARENB)
		if (cflag & PARODD)
			PDEBUG(" - parity = odd\n");
		else
			PDEBUG(" - parity = even\n");
	else
		PDEBUG(" - parity = none\n");

	/* figure out the stop bits requested */
	if (cflag & CSTOPB)
		PDEBUG(" - stop bits = 2\n");
	else
		PDEBUG(" - stop bits = 1\n");

	/* figure out the hardware flow control settings */
	if (cflag & CRTSCTS)
		PDEBUG(" - RTS/CTS is enabled\n");
	else
		PDEBUG(" - RTS/CTS is disabled\n");

	/* determine software flow control */
	/* if we are implementing XON/XOFF, set the start and
	 * stop character in the device */
	if (I_IXOFF(tty) || I_IXON(tty)) {
		/* CHECKPOINT */
		/* Invalid code here;
		 * seems software flow control is not supported
		 */
#if 0
		unsigned char stop_char  = STOP_CHAR(tty);
		unsigned char start_char = START_CHAR(tty);

		/* if we are implementing INBOUND XON/XOFF */
		if (I_IXOFF(tty))
			PDEBUG(" - INBOUND XON/XOFF is enabled, "
			       "XON = %2x, XOFF = %2x", start_char, stop_char);
		else
			PDEBUG(" - INBOUND XON/XOFF is disabled");

		/* if we are implementing OUTBOUND XON/XOFF */
		if (I_IXON(tty))
			PDEBUG(" - OUTBOUND XON/XOFF is enabled, "
			       "XON = %2x, XOFF = %2x", start_char, stop_char);
		else
			PDEBUG(" - OUTBOUND XON/XOFF is disabled");
#endif
	}

	/* get the baud rate wanted */
	PDEBUG(" - baud rate = %d", tty_get_baud_rate(tty));

	F_LEAVE();
}