Exemple #1
0
static int smd_tty_write(struct tty_struct *tty, const unsigned char *buf, int len)
{
	struct smd_tty_info *info = tty->driver_data;
	int avail;

	/* if we're writing to a packet channel we will
	** never be able to write more data than there
	** is currently space for
	*/
	if (is_in_reset(info))
		return -ENETRESET;

	avail = smd_write_avail(info->ch);
	/* if no space, we'll have to setup a notification later to wake up the
	 * tty framework when space becomes avaliable
	 */
	if (!avail) {
		smd_enable_read_intr(info->ch);
		return 0;
	}
	if (len > avail)
		len = avail;

	return smd_write(info->ch, buf, len);
}
static int rmnet_xmit(struct sk_buff *skb, struct net_device *dev)
{
	struct rmnet_private *p = netdev_priv(dev);
	smd_channel_t *ch = p->ch;
	unsigned long flags;

	if (netif_queue_stopped(dev)) {
		pr_err("[%s] fatal: rmnet_xmit called when netif_queue is stopped",
			dev->name);
		return 0;
	}

	spin_lock_irqsave(&p->lock, flags);
	smd_enable_read_intr(ch);
	if (smd_write_avail(ch) < skb->len) {
		netif_stop_queue(dev);
		p->skb = skb;
		spin_unlock_irqrestore(&p->lock, flags);
		return 0;
	}
	smd_disable_read_intr(ch);
	spin_unlock_irqrestore(&p->lock, flags);

	_rmnet_xmit(skb, dev);

	return 0;
}
Exemple #3
0
static int rmnet_xmit(struct sk_buff *skb, struct net_device *dev)
{
	struct rmnet_private *p = netdev_priv(dev);
	smd_channel_t *ch = p->ch;
	unsigned long flags;
	int space;

	if (netif_queue_stopped(dev)) {
		pr_err("fatal: rmnet_xmit called when netif_queue is stopped");
		return 0;
	}

	spin_lock_irqsave(&p->lock, flags);
	smd_enable_read_intr(ch);
	if ((space=smd_write_avail(ch)) < skb->len) {
		pr_warn("warn: rmnet_xmit returned when no write resources on ch %s, available %d, needed %d\n",
				p->chname, space, skb->len);
		netif_stop_queue(dev);
		p->skb = skb;
		spin_unlock_irqrestore(&p->lock, flags);
		return 0;
	}
	smd_disable_read_intr(ch);
	spin_unlock_irqrestore(&p->lock, flags);

	_rmnet_xmit(skb, dev);

	return 0;
}
Exemple #4
0
static int smd_tty_write(struct tty_struct *tty, const unsigned char *buf, int len)
{
	struct smd_tty_info *info = tty->driver_data;
	int avail;

	if (is_in_reset(info))
		return -ENETRESET;

	avail = smd_write_avail(info->ch);
	if (!avail) {
		smd_enable_read_intr(info->ch);
		return 0;
	}
	if (len > avail)
		len = avail;

	return smd_write(info->ch, buf, len);
}
Exemple #5
0
/**
 @brief    This function is used by the DAL Core to to send a
           message over to the WLAN sub-system.

           Once a buffer has been passed into the Send Message
 API, CT takes full ownership of it and it is responsible for
 freeing the associated resources. (This prevents a memcpy in
 case of a deferred write)

 The messages transported through the CT on both RX and TX are
 flat memory buffers that can be accessed and manipulated
 through standard memory functions.

 @param wctsHandlehandle:  received upon open
        pMsg:  the message to be sent
        uLen: the length of the message

 @see
 @return   0 for success
*/
wpt_uint32
WCTS_SendMessage
(
   WCTS_HandleType      wctsHandle,
   void*                pMsg,
   wpt_uint32           uLen
)
{
   WCTS_ControlBlockType*    pWCTSCb = (WCTS_ControlBlockType*) wctsHandle;
   WCTS_BufferType*          pBufferQueue;
   int                       len;
   int                       written = 0;
   int                       available;

   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*--------------------------------------------------------------------
     Sanity check
     --------------------------------------------------------------------*/
   if ((NULL == pWCTSCb) || (WCTS_CB_MAGIC != pWCTSCb->wctsMagic) ||
       (NULL == pMsg) || (0 == uLen) || (0x7fffffff < uLen)) {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "WCTS_SendMessage: Invalid parameters received.");
      WPAL_ASSERT(0);
      if (NULL != pMsg) {
         wpalMemoryFree(pMsg);
      }
      return eWLAN_PAL_STATUS_E_INVAL;
   }

   /* the SMD API uses int instead of uint, so change types here */
   len = (int)uLen;

   if (WCTS_STATE_OPEN == pWCTSCb->wctsState) {
      available = smd_write_avail(pWCTSCb->wctsChannel);
      if (available >= len) {
         written = smd_write(pWCTSCb->wctsChannel, pMsg, len);
      }
   } else if (WCTS_STATE_DEFERRED == pWCTSCb->wctsState) {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
                 "WCTS_SendMessage: FIFO space not available, the packets will be queued");
   } else {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "WCTS_SendMessage: Channel in illegal state [%d].",
                 pWCTSCb->wctsState);
      /* force following logic to reclaim the buffer */
      written = -1;
   }

   if (-1 == written) {
      /*Something wrong*/
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "WCTS_SendMessage: Failed to send message over the bus.");
      wpalMemoryFree(pMsg);
      WPAL_ASSERT(0);
      return eWLAN_PAL_STATUS_E_FAILURE;
   } else if (written == len) {
      /* Message sent! No deferred state, free the buffer*/
      wpalMemoryFree(pMsg);
   } else {
      /* This much data cannot be written at this time,
         queue the rest of the data for later*/
      pBufferQueue = wpalMemoryAllocate(sizeof(WCTS_BufferType));
      if (NULL == pBufferQueue) {
         WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                    "WCTS_SendMessage: Cannot allocate memory for queuing the buffer");
         wpalMemoryFree(pMsg);
         WPAL_ASSERT(0);
         return eWLAN_PAL_STATUS_E_NOMEM;
      }

      pBufferQueue->bufferSize = len;
      pBufferQueue->pBuffer = pMsg;
      wpal_list_insert_back(&pWCTSCb->wctsPendingQueue, &pBufferQueue->node);

      /* if we are not already in the deferred state, then transition
         to that state.  when we do so, we enable the remote read
         interrupt so that we'll be notified when messages are read
         from the remote end */
      if (WCTS_STATE_DEFERRED != pWCTSCb->wctsState) {

         /* Mark the state as deferred.
            Later: We may need to protect wctsState by locks*/
         pWCTSCb->wctsState = WCTS_STATE_DEFERRED;

         smd_enable_read_intr(pWCTSCb->wctsChannel);
      }

      /*indicate to client that message was placed in deferred queue*/
      return eWLAN_PAL_STATUS_E_RESOURCES;
   }

   return eWLAN_PAL_STATUS_SUCCESS;

}/*WCTS_SendMessage*/
wpt_uint32
WCTS_SendMessage
(
   WCTS_HandleType      wctsHandle,
   void*                pMsg,
   wpt_uint32           uLen
)
{
   WCTS_ControlBlockType*    pWCTSCb = (WCTS_ControlBlockType*) wctsHandle;
   WCTS_BufferType*          pBufferQueue;
   int                       len;
   int                       written = 0;
   int                       available;

   

   if ((NULL == pWCTSCb) || (WCTS_CB_MAGIC != pWCTSCb->wctsMagic) ||
       (NULL == pMsg) || (0 == uLen) || (0x7fffffff < uLen)) {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "WCTS_SendMessage: Invalid parameters received.");
      WPAL_ASSERT(0);
      if (NULL != pMsg) {
         wpalMemoryFree(pMsg);
      }
      return eWLAN_PAL_STATUS_E_INVAL;
   }

   
   len = (int)uLen;

   if (WCTS_STATE_OPEN == pWCTSCb->wctsState) {
      available = smd_write_avail(pWCTSCb->wctsChannel);
      if (available >= len) {
         written = smd_write(pWCTSCb->wctsChannel, pMsg, len);
      }
   } else if (WCTS_STATE_DEFERRED == pWCTSCb->wctsState) {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
                 "WCTS_SendMessage: FIFO space not available, the packets will be queued");
   } else {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "WCTS_SendMessage: Channel in illegal state [%d].",
                 pWCTSCb->wctsState);
      
      written = -1;
   }

   if (-1 == written) {
      
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "WCTS_SendMessage: Failed to send message over the bus.");
      wpalMemoryFree(pMsg);
      return eWLAN_PAL_STATUS_E_FAILURE;
   } else if (written == len) {
      
      wpalMemoryFree(pMsg);
   } else {
      /* This much data cannot be written at this time,
         queue the rest of the data for later*/
      pBufferQueue = wpalMemoryAllocate(sizeof(WCTS_BufferType));
      if (NULL == pBufferQueue) {
         WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                    "WCTS_SendMessage: Cannot allocate memory for queuing the buffer");
         wpalMemoryFree(pMsg);
         WPAL_ASSERT(0);
         return eWLAN_PAL_STATUS_E_NOMEM;
      }

      pBufferQueue->bufferSize = len;
      pBufferQueue->pBuffer = pMsg;
      wpal_list_insert_back(&pWCTSCb->wctsPendingQueue, &pBufferQueue->node);

      if (WCTS_STATE_DEFERRED != pWCTSCb->wctsState) {

         pWCTSCb->wctsState = WCTS_STATE_DEFERRED;

         smd_enable_read_intr(pWCTSCb->wctsChannel);
      }

      
      return eWLAN_PAL_STATUS_E_RESOURCES;
   }

   return eWLAN_PAL_STATUS_SUCCESS;

}
Exemple #7
0
static int smd_tty_write(struct tty_struct *tty, const unsigned char *buf, int len)
{
	struct smd_tty_info *info = tty->driver_data;
	int avail, ret, runfix = 0;
#ifdef CONFIG_MACH_HTCLEO
	static int init = 0;
	// seems to start the modem
	const unsigned char* firstcall ="AT@BRIC=0\r";
	// set functionality to low power mode
	const unsigned char* secondcall="AT+CFUN=0\r";
	// deregister from the network
	const unsigned char* thirdcall ="AT+COPS=2\r";
	unsigned int call_len;
#endif

	/* if we're writing to a packet channel we will
	** never be able to write more data than there
	** is currently space for
	*/
	if (is_in_reset(info))
		return -ENETRESET;

#ifdef CONFIG_MACH_HTCLEO
	if(len>7 && !init && htcleo_is_nand_boot()) {
		pr_info("NAND boot, writing additional init commands to /dev/smd0");

		call_len = strlen(firstcall);
		avail = smd_write_avail(info->ch);
		if (call_len > avail)
			call_len = avail;
		ret = smd_write(info->ch, firstcall, call_len);

		call_len = strlen(secondcall);
		avail = smd_write_avail(info->ch);
		if (call_len > avail)
			call_len = avail;
		ret = smd_write(info->ch, secondcall, call_len);

		call_len = strlen(thirdcall);
		avail = smd_write_avail(info->ch);
		if (call_len > avail)
			call_len = avail;
		ret = smd_write(info->ch, thirdcall, call_len);

		init=1;
	}
#endif

	avail = smd_write_avail(info->ch);
	/* if no space, we'll have to setup a notification later to wake up the
	 * tty framework when space becomes avaliable
	 */
	if (!avail) {
		smd_enable_read_intr(info->ch);
		return 0;
	}
	if (len > avail)
		len = avail;

	return smd_write(info->ch, buf, len);
}