Example #1
0
static int __init r3964_init(void)
{
   int status;
   
   printk ("r3964: Philips r3964 Driver $Revision: 1.1.1.1 $\n");

   /*
    * Register the tty line discipline
    */
   
   status = tty_register_ldisc (N_R3964, &tty_ldisc_N_R3964);
   if (status == 0)
     {
       TRACE_L("line discipline %d registered", N_R3964);
       TRACE_L("flags=%x num=%x", tty_ldisc_N_R3964.flags, 
               tty_ldisc_N_R3964.num);
       TRACE_L("open=%x", (int)tty_ldisc_N_R3964.open);
       TRACE_L("tty_ldisc_N_R3964 = %x", (int)&tty_ldisc_N_R3964);
     }
   else
     {
       printk (KERN_ERR "r3964: error registering line discipline: %d\n", status);
     }
   return status;
}
Example #2
0
static int r3964_open(struct tty_struct *tty)
{
	struct r3964_info *pInfo;

	TRACE_L("open");
	TRACE_L("tty=%p, PID=%d, disc_data=%p",
		tty, current->pid, tty->disc_data);

	pInfo = kmalloc(sizeof(struct r3964_info), GFP_KERNEL);
	TRACE_M("r3964_open - info kmalloc %p", pInfo);

	if (!pInfo) {
		printk(KERN_ERR "r3964: failed to alloc info structure\n");
		return -ENOMEM;
	}

	pInfo->rx_buf = kmalloc(RX_BUF_SIZE, GFP_KERNEL);
	TRACE_M("r3964_open - rx_buf kmalloc %p", pInfo->rx_buf);

	if (!pInfo->rx_buf) {
		printk(KERN_ERR "r3964: failed to alloc receive buffer\n");
		kfree(pInfo);
		TRACE_M("r3964_open - info kfree %p", pInfo);
		return -ENOMEM;
	}

	pInfo->tx_buf = kmalloc(TX_BUF_SIZE, GFP_KERNEL);
	TRACE_M("r3964_open - tx_buf kmalloc %p", pInfo->tx_buf);

	if (!pInfo->tx_buf) {
		printk(KERN_ERR "r3964: failed to alloc transmit buffer\n");
		kfree(pInfo->rx_buf);
		TRACE_M("r3964_open - rx_buf kfree %p", pInfo->rx_buf);
		kfree(pInfo);
		TRACE_M("r3964_open - info kfree %p", pInfo);
		return -ENOMEM;
	}

	spin_lock_init(&pInfo->lock);
	pInfo->tty = tty;
	init_waitqueue_head(&pInfo->read_wait);
	pInfo->priority = R3964_MASTER;
	pInfo->rx_first = pInfo->rx_last = NULL;
	pInfo->tx_first = pInfo->tx_last = NULL;
	pInfo->rx_position = 0;
	pInfo->tx_position = 0;
	pInfo->last_rx = 0;
	pInfo->blocks_in_rx_queue = 0;
	pInfo->firstClient = NULL;
	pInfo->state = R3964_IDLE;
	pInfo->flags = R3964_DEBUG;
	pInfo->nRetry = 0;

	tty->disc_data = pInfo;
	tty->receive_room = 65536;

	setup_timer(&pInfo->tmr, on_timeout, (unsigned long)pInfo);

	return 0;
}
static ssize_t r3964_write(struct tty_struct *tty, struct file *file,
			   const unsigned char *data, size_t count)
{
	struct r3964_info *pInfo = tty->disc_data;
	struct r3964_block_header *pHeader;
	struct r3964_client_info *pClient;
	unsigned char *new_data;

	TRACE_L("write request, %d characters", count);

	if (!pInfo)
		return -EIO;

	if (count > R3964_MTU) {
		if (pInfo->flags & R3964_DEBUG) {
			TRACE_L(KERN_WARNING "r3964_write: truncating user "
				"packet from %u to mtu %d", count, R3964_MTU);
		}
		count = R3964_MTU;
	}
	new_data = kmalloc(count + sizeof(struct r3964_block_header),
			GFP_KERNEL);
	TRACE_M("r3964_write - kmalloc %p", new_data);
	if (new_data == NULL) {
		if (pInfo->flags & R3964_DEBUG) {
			printk(KERN_ERR "r3964_write: no memory\n");
		}
		return -ENOSPC;
	}

	pHeader = (struct r3964_block_header *)new_data;
	pHeader->data = new_data + sizeof(struct r3964_block_header);
	pHeader->length = count;
	pHeader->locks = 0;
	pHeader->owner = NULL;

	tty_lock();

	pClient = findClient(pInfo, task_pid(current));
	if (pClient) {
		pHeader->owner = pClient;
	}

	memcpy(pHeader->data, data, count);	

	if (pInfo->flags & R3964_DEBUG) {
		dump_block(pHeader->data, count);
	}

	add_tx_queue(pInfo, pHeader);
	trigger_transmit(pInfo);

	tty_unlock();

	return 0;
}
Example #4
0
/* Called without the kernel lock held - fine */
static unsigned int r3964_poll(struct tty_struct * tty, struct file * file,
		      struct poll_table_struct *wait)
{
   struct r3964_info *pInfo=(struct r3964_info*)tty->disc_data;
   int pid=current->pid;
   struct r3964_client_info *pClient;
   struct r3964_message *pMsg=NULL;
   unsigned long flags;
   int result = POLLOUT;

   TRACE_L("POLL");

   pClient=findClient(pInfo,pid);
   if(pClient)
     {
       poll_wait(file, &pInfo->read_wait, wait);
       save_flags(flags);
       cli();
       pMsg=pClient->first_msg;
       restore_flags(flags);
       if(pMsg)
	   result |= POLLIN | POLLRDNORM;
     }
   else
     {
       result = -EINVAL;
     }
   return result;
}
Example #5
0
static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
			  unsigned char *buf, size_t nr)
{
   struct r3964_info *pInfo=(struct r3964_info*)tty->disc_data;
   struct r3964_client_info *pClient;
   struct r3964_message *pMsg;
   struct r3964_client_message theMsg;
   DECLARE_WAITQUEUE (wait, current);
   
   int pid = current->pid;
   int count;
   
   TRACE_L("read()");
 
   pClient=findClient(pInfo, pid);
   if(pClient)
   {
      pMsg = remove_msg(pInfo, pClient);
      if(pMsg==NULL)
      {
		 /* no messages available. */
         if (file->f_flags & O_NONBLOCK)
		 {
            return -EAGAIN;
		 }
         /* block until there is a message: */
         add_wait_queue(&pInfo->read_wait, &wait);
repeat:
         current->state = TASK_INTERRUPTIBLE;
         pMsg = remove_msg(pInfo, pClient);
	 if (!pMsg && !signal_pending(current))
		 {
            schedule();
            goto repeat;
         }
         current->state = TASK_RUNNING;
         remove_wait_queue(&pInfo->read_wait, &wait);
      }
      
      /* If we still haven't got a message, we must have been signalled */

      if (!pMsg) return -EINTR;

      /* deliver msg to client process: */
      theMsg.msg_id = pMsg->msg_id;
      theMsg.arg    = pMsg->arg;
      theMsg.error_code = pMsg->error_code;
      count = sizeof(struct r3964_client_message);

      kfree(pMsg);
      TRACE_M("r3964_read - msg kfree %x",(int)pMsg);

      if (copy_to_user(buf,&theMsg, count))
	return -EFAULT;

      TRACE_PS("read - return %d", count);
      return count;
   }
   return -EPERM;
}
Example #6
0
/**
  Initialize a regular expression structure.

  Allocates then sets all the basic types.

  @param regexpr A pointer to the regular expression structure.
  @param max The maximum length of strings that can be processed.

  Note: .err set to ERR_ALLOC or ERR_INDEX on failure, ERR_NONE otherwise.
*/
void re_init(t_regexp2 *regexpr, t_nfa_ind max)
{
  TRACE_L("re_init");

  // Test the maximum length argument
  if ((max <= 1) || (max >= IND_NULL)) {
    re_empty(regexpr); 
    ERR_L(ERR_INDEX, ,"re_init:  Invalid length argument:  %i - Should be:  %i to %i",
      max, 1, IND_NULL - 1); }
Example #7
0
static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
			  unsigned char __user * buf, size_t nr)
{
	struct r3964_info *pInfo = tty->disc_data;
	struct r3964_client_info *pClient;
	struct r3964_message *pMsg;
	struct r3964_client_message theMsg;
	int ret;

	TRACE_L("read()");

	tty_lock();

	pClient = findClient(pInfo, task_pid(current));
	if (pClient) {
		pMsg = remove_msg(pInfo, pClient);
		if (pMsg == NULL) {
			/* no messages available. */
			if (file->f_flags & O_NONBLOCK) {
				ret = -EAGAIN;
				goto unlock;
			}
			/* block until there is a message: */
			wait_event_interruptible_tty(pInfo->read_wait,
					(pMsg = remove_msg(pInfo, pClient)));
		}

		/* If we still haven't got a message, we must have been signalled */

		if (!pMsg) {
			ret = -EINTR;
			goto unlock;
		}

		/* deliver msg to client process: */
		theMsg.msg_id = pMsg->msg_id;
		theMsg.arg = pMsg->arg;
		theMsg.error_code = pMsg->error_code;
		ret = sizeof(struct r3964_client_message);

		kfree(pMsg);
		TRACE_M("r3964_read - msg kfree %p", pMsg);

		if (copy_to_user(buf, &theMsg, ret)) {
			ret = -EFAULT;
			goto unlock;
		}

		TRACE_PS("read - return %d", ret);
		goto unlock;
	}
	ret = -EPERM;
unlock:
	tty_unlock();
	return ret;
}
static void r3964_close(struct tty_struct *tty)
{
   struct r3964_info *pInfo=(struct r3964_info*)tty->disc_data;
   struct r3964_client_info *pClient, *pNext;
   struct r3964_message *pMsg;
   struct r3964_block_header *pHeader, *pNextHeader;
   unsigned long flags;

   TRACE_L("close");

    /*
     * Make sure that our task queue isn't activated.  If it
     * is, take it out of the linked list.
     */
    del_timer_sync(&pInfo->tmr);

   /* Remove client-structs and message queues: */
    pClient=pInfo->firstClient;
    while(pClient)
    {
       pNext=pClient->next;
       while(pClient->msg_count)
       {
          pMsg=remove_msg(pInfo, pClient);
          if(pMsg)
          {
             kfree(pMsg);
             TRACE_M("r3964_close - msg kfree %p",pMsg);
          }
       }
       kfree(pClient);
       TRACE_M("r3964_close - client kfree %p",pClient);
       pClient=pNext;
    }
    /* Remove jobs from tx_queue: */
        spin_lock_irqsave(&pInfo->lock, flags);
	pHeader=pInfo->tx_first;
	pInfo->tx_first=pInfo->tx_last=NULL;
	spin_unlock_irqrestore(&pInfo->lock, flags);
	
    while(pHeader)
	{
	   pNextHeader=pHeader->next;
	   kfree(pHeader);
	   pHeader=pNextHeader;
	}

    /* Free buffers: */
    wake_up_interruptible(&pInfo->read_wait);
    kfree(pInfo->rx_buf);
    TRACE_M("r3964_close - rx_buf kfree %p",pInfo->rx_buf);
    kfree(pInfo->tx_buf);
    TRACE_M("r3964_close - tx_buf kfree %p",pInfo->tx_buf);
    kfree(pInfo);
    TRACE_M("r3964_close - info kfree %p",pInfo);
}
Example #9
0
static int __init r3964_init(void)
{
	int status;

;

	/*
	 * Register the tty line discipline
	 */

	status = tty_register_ldisc(N_R3964, &tty_ldisc_N_R3964);
	if (status == 0) {
		TRACE_L("line discipline %d registered", N_R3964);
		TRACE_L("flags=%x num=%x", tty_ldisc_N_R3964.flags,
			tty_ldisc_N_R3964.num);
		TRACE_L("open=%p", tty_ldisc_N_R3964.open);
		TRACE_L("tty_ldisc_N_R3964 = %p", &tty_ldisc_N_R3964);
	} else {
//		printk(KERN_ERR "r3964: error registering line discipline: "
;
	}
	return status;
}
static void r3964_close(struct tty_struct *tty)
{
	struct r3964_info *pInfo = tty->disc_data;
	struct r3964_client_info *pClient, *pNext;
	struct r3964_message *pMsg;
	struct r3964_block_header *pHeader, *pNextHeader;
	unsigned long flags;

	TRACE_L("close");

	del_timer_sync(&pInfo->tmr);

	
	pClient = pInfo->firstClient;
	while (pClient) {
		pNext = pClient->next;
		while (pClient->msg_count) {
			pMsg = remove_msg(pInfo, pClient);
			if (pMsg) {
				kfree(pMsg);
				TRACE_M("r3964_close - msg kfree %p", pMsg);
			}
		}
		put_pid(pClient->pid);
		kfree(pClient);
		TRACE_M("r3964_close - client kfree %p", pClient);
		pClient = pNext;
	}
	
	spin_lock_irqsave(&pInfo->lock, flags);
	pHeader = pInfo->tx_first;
	pInfo->tx_first = pInfo->tx_last = NULL;
	spin_unlock_irqrestore(&pInfo->lock, flags);

	while (pHeader) {
		pNextHeader = pHeader->next;
		kfree(pHeader);
		pHeader = pNextHeader;
	}

	
	wake_up_interruptible(&pInfo->read_wait);
	kfree(pInfo->rx_buf);
	TRACE_M("r3964_close - rx_buf kfree %p", pInfo->rx_buf);
	kfree(pInfo->tx_buf);
	TRACE_M("r3964_close - tx_buf kfree %p", pInfo->tx_buf);
	kfree(pInfo);
	TRACE_M("r3964_close - info kfree %p", pInfo);
}
Example #11
0
static void __exit r3964_exit(void)
{
	int status;

	TRACE_M("cleanup_module()");

	status = tty_unregister_ldisc(N_R3964);

	if (status != 0) {
		printk(KERN_ERR "r3964: error unregistering linediscipline: "
				"%d\n", status);
	} else {
		TRACE_L("linediscipline successfully unregistered");
	}
}
Example #12
0
/**
  Create and allocate a new regular expression structure.
  
  @param max The size of the array of states in the regular expression.

  @return A pointer to the newly allocated a structure, or NULL on failure.
*/
t_regexp2 *re_new(t_nfa_ind max)
{
  TRACE_L("re_new");

  // Allocate the structure, and check the allocation
  t_regexp2 *regexpr = (t_regexp2 *)sysmem_newptr(sizeof(t_regexp2));
  if (!regexpr) { return NULL; }

  // Initialize the structure
  re_init(regexpr, max);

  // Test the initialization
  if (regexpr->err != ERR_NONE) { sysmem_freeptr(regexpr); return NULL; }

  return regexpr;
}
Example #13
0
void Regex::debug(const Composition& comp) const {
    ECHO("[" + std::to_string(comp.id) + "]");
    TRACE(comp.pattern);
    TRACE(comp.min);
    TRACE(comp.max);
    TRACE(comp.nestingLevel);
    TRACE(comp.special);
    if (comp.next.size() > 0) {
        std::cout << "comp.next = ";
        for (std::size_t i = 0; i < comp.next.size(); i++) {
            if (i > 0) std::cout << ",";
            std::cout << comp.next[i];
        }
        std::cout << std::endl;
    } else {
        TRACE_L("comp.next", "undefined");
    }
    TRACE(comp.ready);
}
Example #14
0
/* Called without the kernel lock held - fine */
static unsigned int r3964_poll(struct tty_struct *tty, struct file *file,
			struct poll_table_struct *wait)
{
	struct r3964_info *pInfo = tty->disc_data;
	struct r3964_client_info *pClient;
	struct r3964_message *pMsg = NULL;
	unsigned long flags;
	int result = POLLOUT;

	TRACE_L("POLL");

	pClient = findClient(pInfo, task_pid(current));
	if (pClient) {
		poll_wait(file, &pInfo->read_wait, wait);
		spin_lock_irqsave(&pInfo->lock, flags);
		pMsg = pClient->first_msg;
		spin_unlock_irqrestore(&pInfo->lock, flags);
		if (pMsg)
			result |= POLLIN | POLLRDNORM;
	} else {
		result = -EINVAL;
	}
	return result;
}
Example #15
0
static int r3964_open(struct tty_struct *tty)
{
   struct r3964_info *pInfo;
   
   MOD_INC_USE_COUNT;

   TRACE_L("open");
   TRACE_L("tty=%x, PID=%d, disc_data=%x", 
          (int)tty, current->pid, (int)tty->disc_data);
   
   pInfo=kmalloc(sizeof(struct r3964_info), GFP_KERNEL); 
   TRACE_M("r3964_open - info kmalloc %x",(int)pInfo);

   if(!pInfo)
   {
      printk(KERN_ERR "r3964: failed to alloc info structure\n");
      return -ENOMEM;
   }

   pInfo->rx_buf = kmalloc(RX_BUF_SIZE, GFP_KERNEL);
   TRACE_M("r3964_open - rx_buf kmalloc %x",(int)pInfo->rx_buf);

   if(!pInfo->rx_buf)
   {
      printk(KERN_ERR "r3964: failed to alloc receive buffer\n");
      kfree(pInfo);
      TRACE_M("r3964_open - info kfree %x",(int)pInfo);
      return -ENOMEM;
   }
   
   pInfo->tx_buf = kmalloc(TX_BUF_SIZE, GFP_KERNEL);
   TRACE_M("r3964_open - tx_buf kmalloc %x",(int)pInfo->tx_buf);

   if(!pInfo->tx_buf)
   {
      printk(KERN_ERR "r3964: failed to alloc transmit buffer\n");
      kfree(pInfo->rx_buf);
      TRACE_M("r3964_open - rx_buf kfree %x",(int)pInfo->rx_buf);
      kfree(pInfo);
      TRACE_M("r3964_open - info kfree %x",(int)pInfo);
      return -ENOMEM;
   }

   pInfo->tty = tty;
   init_waitqueue_head (&pInfo->read_wait);
   pInfo->priority = R3964_MASTER;
   pInfo->rx_first = pInfo->rx_last = NULL;
   pInfo->tx_first = pInfo->tx_last = NULL;
   pInfo->rx_position = 0;
   pInfo->tx_position = 0;
   pInfo->last_rx = 0;
   pInfo->blocks_in_rx_queue = 0;
   pInfo->firstClient=NULL;
   pInfo->state=R3964_IDLE;
   pInfo->flags = R3964_DEBUG;
   pInfo->count_down = 0;
   pInfo->nRetry = 0;
   
   tty->disc_data = pInfo;

   /*
    * Add 'on_timer' to timer task queue
    * (will be called from timer bh)
    */
   INIT_LIST_HEAD(&pInfo->bh_1.list);
   pInfo->bh_1.sync = 0;
   pInfo->bh_1.routine = &on_timer_1;
   pInfo->bh_1.data = pInfo;
   
   INIT_LIST_HEAD(&pInfo->bh_2.list);
   pInfo->bh_2.sync = 0;
   pInfo->bh_2.routine = &on_timer_2;
   pInfo->bh_2.data = pInfo;

   queue_task(&pInfo->bh_1, &tq_timer);

   return 0;
}
Example #16
0
static ssize_t r3964_write(struct tty_struct *tty, struct file *file,
			   const unsigned char *data, size_t count)
{
	struct r3964_info *pInfo = (struct r3964_info *)tty->disc_data;
	struct r3964_block_header *pHeader;
	struct r3964_client_info *pClient;
	unsigned char *new_data;

	TRACE_L("write request, %d characters", count);
/* 
 * Verify the pointers 
 */

	if (!pInfo)
		return -EIO;

/*
 * Ensure that the caller does not wish to send too much.
 */
	if (count > R3964_MTU) {
		if (pInfo->flags & R3964_DEBUG) {
			TRACE_L(KERN_WARNING "r3964_write: truncating user "
				"packet from %u to mtu %d", count, R3964_MTU);
		}
		count = R3964_MTU;
	}
/*
 * Allocate a buffer for the data and copy it from the buffer with header prepended
 */
	new_data = kmalloc(count + sizeof(struct r3964_block_header),
			GFP_KERNEL);
	TRACE_M("r3964_write - kmalloc %p", new_data);
	if (new_data == NULL) {
		if (pInfo->flags & R3964_DEBUG) {
			printk(KERN_ERR "r3964_write: no memory\n");
		}
		return -ENOSPC;
	}

	pHeader = (struct r3964_block_header *)new_data;
	pHeader->data = new_data + sizeof(struct r3964_block_header);
	pHeader->length = count;
	pHeader->locks = 0;
	pHeader->owner = NULL;

	pClient = findClient(pInfo, task_pid(current));
	if (pClient) {
		pHeader->owner = pClient;
	}

	memcpy(pHeader->data, data, count);	/* We already verified this */

	if (pInfo->flags & R3964_DEBUG) {
		dump_block(pHeader->data, count);
	}

/*
 * Add buffer to transmit-queue:
 */
	add_tx_queue(pInfo, pHeader);
	trigger_transmit(pInfo);

	return 0;
}
Example #17
0
static void r3964_set_termios(struct tty_struct *tty, struct ktermios *old)
{
	TRACE_L("set_termios");
}
Example #18
0
static int r3964_receive_room(struct tty_struct *tty)
{
   TRACE_L("receive_room");
   return -1;
}