wdbVisionPktDrv.c
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:12k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* wdbVisionPktDrv.c - packet driver for lightweight UDP/IP */
  2. /* Copyright 1988-2002 Wind River Systems Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01d,29nov01,g_h  Cleaning for T2.2
  7. 01c,07feb01,g_h  renaming module name and cleaning
  8. 01b,03may97,est  adapted for EST Background mode emulator
  9. 01a,23aug95,ms   written.
  10. */
  11. /*
  12. DESCRIPTION
  13. This module is a Wind River Vision driver for interfacing with the 
  14. WDB agent's lightweight UDP/IP interpreter. It was derived from the
  15. wdbTemplatePktDrv.c template.
  16. PACKET READY CALLBACK
  17. ---------------------
  18. When the driver detects that a packet has arrived (either in its receiver
  19. ISR or in its poll input routine), it invokes a callback to pass the
  20. data to the debug agent. The driver's wdbVisionPktDevInit() routine 
  21. passes the callback as parameter and places it in the device data structure. 
  22. MODES
  23. -----
  24. Wind River Vision Driver support Poll Mode/Pseudo-Interrupt Mode only. This is done
  25. by spawning a separate polling task to monitor the receive channel.
  26. USAGE
  27. -----
  28. The driver is typically only called only from usrWdb.c. The only directly
  29. callable routine in this module is wdbVisionPktDevInit().
  30. DATA BUFFERING
  31. --------------
  32. The drivers only need to handle one input packet at a time because
  33. the WDB protocol only supports one outstanding host-request at a time.
  34. For output, the agent will pass the driver a chain of mbufs, which
  35. the driver must send as a packet. When it is done with the mbufs,
  36. it calls wdbMbufChainFree() to free them.
  37. */
  38. #include "vxWorks.h"
  39. #include "string.h"
  40. #include "errno.h"
  41. #include "sioLib.h"
  42. #include "intLib.h"
  43. #include "stdio.h"
  44. #include "ioLib.h"
  45. #include "iosLib.h"
  46. #include "memLib.h"
  47. #include "errnoLib.h"
  48. #include "taskLib.h"        
  49. #include "netinet/in_systm.h"
  50. #include "netinet/in.h"
  51. #include "netinet/ip.h"
  52. #include "netinet/udp.h"
  53. #include "intLib.h"
  54. #include "cacheLib.h"
  55. #include "wdb/wdbMbufLib.h"
  56. #include "drv/wdb/vision/wdbVisionPktDrv.h"
  57. #include "drv/wdb/vision/wdbVisionDrvIF.h"
  58. #include "drv/wdb/vision/wdbVisionDrv.h"
  59.                                
  60.                                 
  61. /* pseudo-macros */
  62. #define DRIVER_RESET_INPUT(pDev) {pDev->inputBusy=FALSE; pDev->bytesRead=0;}
  63. #define DRIVER_RESET_OUTPUT(pDev){pDev->outputBusy=FALSE; pDev->bytesWritten=0;}
  64. /* forward declarations */
  65. LOCAL int  wdbVisionPoll    (void *pDev);
  66. LOCAL int  wdbVisionPktTx   (void *pDev, struct mbuf *pMbuf);
  67. LOCAL int  wdbVisionModeSet (void *pDev, uint_t newMode);
  68. LOCAL void wdbVisionFree    (void *pDev);
  69. /* externals */
  70. int wdbVisionPollTask (void*, int);
  71. /***************************************************************************
  72. *
  73. * wdbVisionPktDevInit - initialize the Vision packet driver.
  74. *
  75. * This routine initialize the vision packet driver.
  76. *
  77. * RETURNS: OK or ERROR
  78. */
  79. int wdbVisionPktDevInit
  80.     (
  81.     WDB_VISION_PKT_DEV *pPktDev,      /* Vision device structure */
  82.     void                (*stackRcv)() /* receive packet callback */
  83.     )
  84.     {
  85.     /* initialize the wdbDrvIf field with driver info */
  86.     pPktDev->wdbDrvIf.mode      = WDB_COMM_MODE_POLL | WDB_COMM_MODE_INT;
  87.     pPktDev->wdbDrvIf.mtu       = WDB_VISION_PKT_MTU;
  88.     pPktDev->wdbDrvIf.stackRcv  = stackRcv;      
  89.     pPktDev->wdbDrvIf.devId     = (WDB_VISION_PKT_DEV*)pPktDev;
  90.     pPktDev->wdbDrvIf.pollRtn   = wdbVisionPoll;
  91.     pPktDev->wdbDrvIf.pktTxRtn  = wdbVisionPktTx;
  92.     pPktDev->wdbDrvIf.modeSetRtn= wdbVisionModeSet;
  93.     /* Reset driver input/output status indicators */
  94.     DRIVER_RESET_INPUT  (pPktDev);
  95.     DRIVER_RESET_OUTPUT (pPktDev);
  96.     /* Install Wind River Vision I/O Driver */
  97.     if (visionDriverInit () == ERROR)
  98.         return (ERROR);                 
  99.     /*
  100.      * The Vision Driver can support a Task-Level Only or combination of 
  101.      * Task-Level/System-Level. 
  102.      */
  103. #ifdef VISION_SPECIAL_TASKMODE_ONLY          
  104.     if ((visionDriverCreate ("/vision/0", 
  105.                              VISION_PINTR_MODE,    
  106.                              VISION_BLOCKED_MODE, 
  107.                              VISION_BUFFERED_MODE, 
  108.                              VISION_DEFAULT_POLL_DELAY,
  109.                              VISION_DEFAULT_POLL_PRI)) == ERROR)
  110.         return (ERROR);
  111. #else
  112.                                           /* ||     OR      || */
  113.     if ((visionDriverCreate ("/vision/0", /* vv   BLOCKED   vv */
  114.                              VISION_POLL_MODE,        
  115.                              VISION_NONBLOCKED_MODE, 
  116.                              VISION_NONBUFFERED_MODE, 
  117.                              VISION_DEFAULT_POLL_DELAY,
  118.                              VISION_DEFAULT_POLL_PRI)) == ERROR)
  119.         return (ERROR);
  120. #endif
  121.     pPktDev->fileFd = open ("/vision/0", O_RDWR, 0644);
  122.     if (pPktDev->fileFd == ERROR)
  123.         { 
  124.         return (ERROR);
  125.         }
  126.     /* Allocate storage for Tx and Rx Buffers */
  127.     pPktDev->pTxBuffer = cacheDmaMalloc (WDB_VISION_PKT_MTU);
  128.     if (pPktDev->pTxBuffer == NULL)
  129.         {
  130.         return (ERROR);
  131.         }
  132.     pPktDev->pRxBuffer = cacheDmaMalloc (WDB_VISION_PKT_MTU + UDP_IP_HDR_SIZE);
  133.     if (pPktDev->pRxBuffer == NULL)
  134.         {
  135.         free (pPktDev->pTxBuffer);
  136.         return (ERROR);
  137.         }
  138.     /* 
  139.      *  Create a receive polling task to simulate Rx interrupts. 
  140.      */
  141.     if (taskIdCurrent)                /* insure we're multitasking */
  142.         {
  143.         pPktDev->pollTaskId = taskSpawn ("tVisionWdb", 
  144.                                          VISION_DEFAULT_POLL_PRI,0,5000,
  145.                                          (int(*)())wdbVisionPollTask,
  146.                                          (int)pPktDev, 
  147.                                          VISION_DEFAULT_POLL_DELAY,
  148.                                          0,0,0,0,0,0,0,0);
  149.         if (pPktDev->pollTaskId == ERROR)
  150.             {
  151.             free (pPktDev->pTxBuffer);
  152.             free (pPktDev->pRxBuffer);
  153.      
  154.             return (ERROR);
  155.             }
  156.         }
  157.     else  /* need to be multitasking */
  158.         {
  159.         free (pPktDev->pTxBuffer);
  160.         free (pPktDev->pRxBuffer);
  161.         return (ERROR);
  162.         }
  163.     /* Standard operating mode is Pseudo-interrupt mode */
  164.     pPktDev->mode = VISION_PINTR_MODE;
  165.     return (OK);
  166.     }
  167. /***************************************************************************
  168. *
  169. * wdbVisionPktTx - transmit a packet.
  170. *
  171. * This routine transmit a packet.
  172. * RETURNS: OK or ERROR
  173. *
  174. * NOTE: The packet is really a chain of mbufs. We may have to just 
  175. *       queue up this packet if we are already transmitting.
  176. */
  177. LOCAL int wdbVisionPktTx
  178.     (
  179.     void        *pDev,
  180.     struct mbuf *pMbuf
  181.     )
  182.     {
  183.     WDB_VISION_PKT_DEV *pPktDev    = pDev;
  184.     struct mbuf        *pFirstMbuf = pMbuf;
  185.     int                 lockKey;
  186.     int                 len        = 0;
  187.     
  188.     if (pPktDev->outputBusy == TRUE)
  189.         return ERROR;    
  190.     /* 
  191.      *  The first mbuf contains the udp/ip packet header. 
  192.      *  This is not needed in our case so discard it. Buffer up
  193.      *  the remaining mbufs and send to the Wind River visionPROBRE/ICE box.
  194.      */
  195.     pMbuf = pMbuf->m_next;    
  196.     while (pMbuf != NULL)
  197.         {
  198.         if ((len + pMbuf->m_len) > WDB_VISION_PKT_MTU)
  199.             {
  200.             return (ERROR);
  201.             }
  202.         bcopy (mtod(pMbuf, char*), (char*)(&pPktDev->pTxBuffer[len]), pMbuf->m_len);
  203.         len  += pMbuf->m_len;
  204.         pMbuf = pMbuf->m_next;
  205.         }
  206.     /* 
  207.      * Transmit packet to emulator. 
  208.      * If an error occurred during the write(), just return with 
  209.      * existing errno.
  210.      */
  211.     lockKey = intLock (); 
  212.     pPktDev->outputBusy = TRUE;         
  213.     pPktDev->bytesWritten = write (pPktDev->fileFd, pPktDev->pTxBuffer, len);
  214.     
  215.     intUnlock (lockKey);                
  216.     if (pPktDev->bytesWritten != len)
  217.         {
  218.         DRIVER_RESET_OUTPUT (pPktDev);   
  219.         return (ERROR);
  220.         }
  221.     wdbMbufChainFree (pFirstMbuf);
  222.     
  223.     DRIVER_RESET_OUTPUT (pPktDev);      
  224.     return (OK);
  225.     }
  226. /***************************************************************************
  227. *
  228. * wdbVisionFree - free the input buffer
  229. *
  230. * This routine is the callback used to let us know the agent is done with the
  231. * input buffer we loaded it.
  232. *
  233. * RETURNS: N/A
  234. */
  235. LOCAL void wdbVisionFree
  236.     (
  237.     void *pDev
  238.     )
  239.     {
  240.     WDB_VISION_PKT_DEV *pPktDev = pDev;
  241.     DRIVER_RESET_INPUT (pPktDev);
  242.     }
  243. /***************************************************************************
  244. *
  245. * wdbVisionModeSet - switch driver modes   
  246. *
  247. * This routine switch the driver modes.
  248. *
  249. * RETURNS: OK for a supported mode, else ERROR
  250. */
  251. LOCAL int wdbVisionModeSet
  252.     (
  253.     void   *pDev,
  254.     uint_t  newMode
  255.     )
  256.     {
  257.     WDB_VISION_PKT_DEV  *pPktDev = pDev;
  258.     DRIVER_RESET_INPUT (pPktDev);
  259.     DRIVER_RESET_OUTPUT (pPktDev);
  260.     /*
  261.      *  Interrupt Mode is achieved via a polling task
  262.      */
  263.     if (newMode == WDB_COMM_MODE_INT)
  264.         {
  265.         pPktDev->mode = WDB_COMM_MODE_INT;
  266.         }
  267.     else if (newMode == WDB_COMM_MODE_POLL)
  268.         {
  269.         pPktDev->mode = WDB_COMM_MODE_POLL;
  270.         }
  271.     else
  272.         return (ERROR);
  273.  
  274.     return (OK);
  275.     }
  276. /***************************************************************************
  277. *
  278. * wdbVisionPoll - poll for a packet
  279. *
  280. * This routine polls for a Rx packet. If a packet has arrived it invokes
  281. * the agents callback.
  282. *
  283. * RETURNS: OK if a packet has arrived, else ERROR.
  284. */ 
  285. LOCAL int wdbVisionPoll
  286.     (
  287.     void *pDev
  288.     )
  289.     {
  290.     WDB_VISION_PKT_DEV *pPktDev = pDev;
  291.     struct mbuf        *pMbuf;
  292.     struct udphdr *pUdpHdr;
  293.     struct ip     *pIpHdr;
  294.     /* If the agent is processing a previous message, skip this poll */
  295.     if (pPktDev->inputBusy)
  296.         return (ERROR);
  297.     
  298.     /* Read a packet from the emulator  */
  299.     pPktDev->bytesRead = read (pPktDev->fileFd,
  300.                               (char*)(&pPktDev->pRxBuffer[UDP_IP_HDR_SIZE]),
  301.                               WDB_VISION_PKT_MTU);
  302.     /* 
  303.      *  If an error occurred while reading the packet, just
  304.      *  exit with existing errno value. 
  305.      */
  306.     if (pPktDev->bytesRead == 0)
  307.         return (ERROR);
  308.     /*
  309.      * Else pass received packet to agent. Attach a dummy UDP/IP header. 
  310.      * (Note: most UDP/IP fields are ignorred by the agent)
  311.      */
  312.     pPktDev->bytesRead += UDP_IP_HDR_SIZE;
  313.      
  314.     pIpHdr  = (struct ip*)pPktDev->pRxBuffer;
  315.     pUdpHdr = (struct udphdr*)((int)pIpHdr + IP_HDR_SIZE);
  316. #ifdef FIX_IP_VH
  317.     pIpHdr->ip_v  =  0x4; 
  318.     pIpHdr->ip_hl =  0x5; 
  319. #else
  320.     pIpHdr->ip_v_hl =  0x45; 
  321. #endif /* FIX_IP_VH */
  322.     pIpHdr->ip_src.s_addr = VISION_DUMMY_IP_ADRS;
  323.     pIpHdr->ip_dst.s_addr = VISION_DUMMY_IP_ADRS;
  324.     pIpHdr->ip_sum = 0;
  325.     pIpHdr->ip_p = IPPROTO_UDP;
  326.     pUdpHdr->uh_sport = htons(VISION_DUMMY_PORT);
  327.     pUdpHdr->uh_dport = htons(WDBPORT);
  328.     pUdpHdr->uh_ulen  = pPktDev->bytesRead;
  329.     pUdpHdr->uh_sum   = 0;
  330.     /*
  331.      *  Allocate a mbuf, initialize it, and pass it to the agent.
  332.      */
  333.     
  334.     pMbuf = wdbMbufAlloc ();
  335.     if (pMbuf == NULL)
  336.         {
  337.         DRIVER_RESET_INPUT(pPktDev);     
  338.         return (ERROR);
  339.         }
  340.     pPktDev->inputBusy = TRUE;
  341.     wdbMbufClusterInit (pMbuf, pPktDev->pRxBuffer, pPktDev->bytesRead, 
  342.                         (int(*)())wdbVisionFree, (int)pPktDev);
  343.     /* invoke callback */ 
  344.     (*pPktDev->wdbDrvIf.stackRcv)(pMbuf);  
  345.     return (OK);
  346.     }
  347. /***************************************************************************
  348. * wdbVisionPollTask -  continually poll emulator buffer descriptors and
  349. *                      buffer queues.
  350. *
  351. * This routine continually poll emulator buffer descriptors and buffer 
  352. * queues. This simulates Rx and Tx interrupts.
  353. *
  354. * RETURNS: N/A
  355. */ 
  356. int wdbVisionPollTask
  357.     (
  358.     void *pDev,
  359.     int   pollTaskDelay
  360.     )
  361.     {
  362.     volatile int key;
  363.     for (;;)
  364.         {
  365.         taskDelay (pollTaskDelay);
  366.         key = intLock ();  
  367.         wdbVisionPoll (pDev);
  368.         intUnlock (key);       
  369.         }
  370.     }