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

VxWorks

开发平台:

C/C++

  1. /* usbNC1080End.c - NC1080 Turbo connect Network Interface driver */
  2. /* Copyright 2000-2001 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01g,15oct01,wef  fix SPR 70953 - fixes man page generation and 70716 - fixes
  7.  coding convention and some warnings
  8. 01f,08aug01,dat  Removing warnings
  9. 01e,08aug01,dat  Removing compiler warnings
  10. 01d,31jul01,wef  fixed comments for man page genereation
  11. 01c,03may01,wef  changed pUsbListDev to USB_NC1080_DEV, moved attach_request 
  12.  definition to .c file from .h file.
  13. 01b,09apr01,bri  modified for Dynamic Memory allocation, hot plugging 
  14.  and multiple devices.
  15. 01a,28nov00,bri  Created. Adapted from templateEnd.c.
  16. */
  17. /*
  18. DESCRIPTION
  19. NC1080 Turbo connect device is a USB Host to Host communications device.
  20. This device consists of two SIEs to interface two hosts simultaneously, 
  21. bidirectional FIFOs and an EEPROM interface. EEPROM interface provides the 
  22. necessary initialization details for the device. For each host, this device 
  23. offers a Pair of BULK IN and BULK OUT end points having 256 byte fifo each, per 
  24. direction. Additionally, it offers a Pair of mailbox end points and a status end 
  25. point for each host. mail box end points are intended for additional data 
  26. communication. Status endpoint (interrupt) informs the host of any data in its 
  27. Fifo. It has the remote wakeup signalling capability, if any data becomes 
  28. available for a host.
  29. As such the device is a simple data transfer device. It communicates with any 
  30. other device that understands the protocol used by the driver. The protocol is 
  31. introduced  by the driver. The same protocol is being followed by all drivers in 
  32. all OSs. The device will be viewed as a Network device and data will be 
  33. packetized in Ethernet frames. In addition, the ethernet frames are packetized 
  34. in another protocol and sent on the Bulk out pipe. This protocol is described 
  35. underneath.
  36. This driver uses only the Bulk End points for the communcation. The remaining 
  37. end points are ignored. 
  38. The driver is an VxWorks END driver for the device which also incorporates the 
  39. NC1080 protocol. Then this driver uses the Bulk In and Bulk out end points for 
  40. communication over USB. 
  41. USB relies on the HC interrupt for all its activities. This means that there is 
  42. no Polled mode for a USB device. So the NC1080 End driver doesn't support 
  43. polled mode functions.
  44. The NC1080 device is a back-to-back communication device. So the usbNC1080 end 
  45. driver doesn't support broadcast/multicast functionality.
  46. Since the device by itself is not a Network device, it doesn't have any MAC 
  47. address. It is expected that the User passes the MAC address via the 
  48. initialization string to endLoad(). The initilization string format is described 
  49. in sysNC1080End.c.
  50. INITIALIZATION
  51. The driver is expected to be initialized via usbNC1080DrvInit() before the endLoad 
  52. is called. It is required that the device be recognized as attached by the 
  53. HCD/USBD and attach callback be exceuted, before the endLoad() for the usbNC1080 
  54. driver is called as a part of the system wide network initialization. 
  55. PROTOCOL
  56. NC1080 protocol:  ethernet framing, and only use bulk endpoints (01/81);
  57. not mailboxes 02/82 or status interrupt 83).  Expects Ethernet bridging.
  58. Odd USB length == always short read. the data needs to be packetized before 
  59. sending to the Netchip1080 device for transmission. Also the received data
  60. has to be de-packetized before we send it up. The packetizing protocol is
  61.   -------------------------------------
  62.   |header|    data (payload)   |footer|
  63.   -------------------------------------
  64. - netchip_header
  65. - payload, in Ethernet framing (14 byte header etc)
  66. - (optional padding byte, if needed so that length is odd)
  67. - netchip_footer
  68. */
  69. /* includes */
  70. #include "vxWorks.h"
  71. #include "stdlib.h"
  72. #include "cacheLib.h"
  73. #include "intLib.h"
  74. #include "end.h" /* Common END structures. */
  75. #include "endLib.h"
  76. #include "lstLib.h" /* Needed to maintain protocol list. */
  77. #include "wdLib.h"
  78. #include "iv.h"
  79. #include "semLib.h"
  80. #include "etherLib.h"
  81. #include "logLib.h"
  82. #include "netLib.h"
  83. #include "stdio.h"
  84. #include "sysLib.h"
  85. #include "errno.h"
  86. #include "errnoLib.h"
  87. #include "memLib.h"
  88. #include "iosLib.h"
  89. #undef ETHER_MAP_IP_MULTICAST
  90. #include "etherMultiLib.h" /* multicast stuff. */
  91. #include "net/mbuf.h"
  92. #include "net/unixLib.h"
  93. #include "net/protosw.h"
  94. #include "net/systm.h"
  95. #include "net/if_subr.h"
  96. #include "net/route.h"
  97. #include "sys/socket.h"
  98. #include "sys/ioctl.h"
  99. #include "sys/times.h"
  100. #include "usb/usbPlatform.h"
  101. #include "usb/ossLib.h"  /* operations system srvcs */
  102. #include "usb/usb.h" /* general USB definitions */
  103. #include "usb/usbListLib.h" /* linked list functions */
  104. #include "usb/usbdLib.h" /* USBD interface */
  105. #include "usb/usbLib.h"  /* USB utility functions */
  106. #include "drv/usb/usbNC1080End.h" /* device header file*/
  107. #define NETCHIP_PAD_BYTE ((UINT8)0xAC)
  108. #define NETCHIP_MIN_HEADER 6
  109. /*
  110.  * This will only work if there is only a single unit, for multiple
  111.  * unit device drivers these should be integrated into the END_DEVICE
  112.  * structure.
  113.  */
  114. M_CL_CONFIG usbNC1080MclBlkConfig =  /* network mbuf configuration table */
  115.     {
  116.     /*
  117.     no. mBlks no. clBlks memArea memSize
  118.     ----------- ---------- ------- -------
  119.     */
  120.     0,  0,  NULL,  0
  121.     };
  122. CL_DESC usbNC1080ClDescTbl [] =  /* network cluster pool configuration table */
  123.     {
  124.     /*
  125.     clusterSize num memArea memSize
  126.     ----------- ---- ------- -------
  127.     */
  128.     {NETCHIP_MTU + EH_SIZE + 2, 0, NULL, 0}
  129.     };
  130. int usbNC1080ClDescTblNumEnt = (NELEMENTS(usbNC1080ClDescTbl));
  131. NET_POOL usbNC1080CmpNetPool;
  132. #define NETCHIP_MIN_FBUF (NETCHIP_BUFSIZ) /* min first buffer size */
  133. /* DEBUG MACROS */
  134. #define DEBUG
  135. #ifdef DEBUG
  136. #   define LOGMSG(x,a,b,c,d,e,f) 
  137. if (endDebug) 
  138.     { 
  139.     logMsg (x,a,b,c,d,e,f); 
  140.     }
  141. #else
  142. #   define LOGMSG(x,a,b,c,d,e,f)
  143. #endif /* ENDDEBUG */
  144. #define DRV_DBG
  145. #ifdef DRV_DBG
  146. #define DRV_DBG_OFF 0x0000
  147. #define DRV_DBG_RX 0x0001
  148. #define DRV_DBG_TX 0x0002
  149. #define DRV_DBG_ATTACH 0x0004
  150. #define DRV_DBG_INIT 0x0008
  151. #define DRV_DBG_REGISTER 0x1000
  152. #define DRV_DBG_LOAD 0x0020
  153. #define DRV_DBG_IOCTL 0x0040
  154. #define DRV_DBG_RESET 0x1000
  155. #define DRV_DBG_START 0x0100
  156. #define DRV_DBG_PARSE 0x20000
  157. #define DRV_DBG_UNLOAD 0x40000
  158. int usbNC1080Debug = 0;  /* no debug msgs, by default */
  159. #define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6)                        
  160. if (usbNC1080Debug & FLG)                                        
  161.             logMsg(X0, X1, X2, X3, X4, X5, X6);
  162. void DRV_DESC_PRINT(int flg, char * str, UINT8 * ptr, UINT16 len)
  163.     {
  164.     if (usbNC1080Debug & flg)
  165.         {
  166. int i = 0;
  167. printf("%s : %d bytesn",str,len);
  168. for(i = 0; i < len; i++)
  169.     {
  170.     printf("%x ", *ptr++);
  171.     if ((i+1)%16 == 0)
  172. printf("n");
  173.     }
  174. printf("n");
  175.         }
  176.     }
  177. #else /*DRV_DBG*/
  178. #define DRV_LOG(DBG_SW, X0, X1, X2, X3, X4, X5, X6)
  179. #define DRV_DESC_PRINT(DBG_SW,X,Y,Z)
  180. #endif /*DRV_DBG*/
  181. #define PKT_DBG
  182. #ifdef PKT_DBG
  183. #define PKT_DBG_TX ((UINT8)0x01)
  184. #define PKT_DBG_RX ((UINT8)0x02)
  185. UINT8 pktDebug = 0; /*(PKT_DBG_TX | PKT_DBG_RX); */
  186. void PKT_PRINT(int flg, UINT8 *pkt, UINT16 len)
  187.     {
  188.     NC_HEADER * pHeader = (NC_HEADER *)pkt;
  189.     NC_FOOTER * pFooter;
  190.     int i =0;
  191.     if (!(flg & pktDebug))
  192. return;
  193.     if( flg == PKT_DBG_TX)
  194. printf(" Tx Packet : n");
  195.     else
  196. printf(" Rx Packet : n");
  197.  
  198.     printf("Header : hdr_len : %d  pkt_len : %d pkt_id : %x n",
  199. pHeader->hdr_len, pHeader->packet_len, pHeader->packet_id);
  200.     
  201.     printf(" Data :n");
  202.     for (i=0; i< pHeader->packet_len;i++)
  203. {
  204. printf("%x ",*(pkt+pHeader->hdr_len+i));
  205. if (((i+1) % 16) == 0)
  206.     printf("n");
  207. }
  208.         printf("n");
  209.     if (((pHeader->packet_len + sizeof (*pFooter)) & 0x01) == 0)
  210. {
  211. printf("Pad Byte : %x n",*(pkt+pHeader->hdr_len+pHeader->packet_len));
  212. pFooter = (NC_FOOTER *)(pkt+pHeader->hdr_len+pHeader->packet_len + 1);
  213. }
  214.     else
  215. {
  216. pFooter = (NC_FOOTER *)(pkt+pHeader->hdr_len+pHeader->packet_len);
  217. }
  218.     
  219.     printf("Footer : pkt_id : %x n",pFooter->packet_id);
  220.     }
  221. #else
  222. #define PKT_PRINT( X, Y, Z)
  223. #endif
  224.     
  225. /* LOCALS */
  226. LOCAL USBD_CLIENT_HANDLE usbNC1080Handle; /* our USBD client handle */
  227. LOCAL UINT16 initCount = 0;          /* Count of init nesting */
  228. LOCAL MUTEX_HANDLE usbNC1080Mutex;
  229. LOCAL MUTEX_HANDLE usbNC1080TxMutex;
  230. LOCAL MUTEX_HANDLE usbNC1080RxMutex;
  231. LOCAL SEM_HANDLE   usbNC1080IrpSem;       /* Semaphore for IRP Synchronisation */
  232. LOCAL LIST_HEAD usbNC1080DevList;      /* linked list of Device Structs */
  233. LOCAL LIST_HEAD     reqList;            /* Attach callback request list */
  234. LOCAL const struct product
  235.     {
  236.     char *name;
  237.     UINT16 idVendor;
  238.     UINT16 idProduct;
  239. } products [] = {
  240. { "NC1080 TurboCONNECT", 0x0525, 0x1080 }, /* NC1080 */
  241. { 0, 0, 0 },             /* END */
  242. };
  243. typedef struct attach_request
  244.     {
  245.     LINK reqLink;                          /* linked list of requests */
  246.     USB_NETCHIP_ATTACH_CALLBACK callback;  /* client callback routine */
  247.     pVOID callbackArg;                     /* client callback argument*/
  248.     } ATTACH_REQUEST, *pATTACH_REQUEST;    /* added for multiple devices */
  249. /* externally visible interfaces. */
  250. END_OBJ *  usbNC1080Load (char* initString);     /* the endLoad ( ) */
  251. STATUS          usbNC1080DrvInit ( );             /* Initialization */
  252. STATUS usbNC1080DynamicAttachRegister (USB_NETCHIP_ATTACH_CALLBACK callback,
  253. pVOID arg);
  254. STATUS usbNC1080DynamicAttachRegister (USB_NETCHIP_ATTACH_CALLBACK callback,
  255. pVOID arg);
  256. STATUS usbNC1080DevLock (USBD_NODE_ID nodeId);
  257. STATUS usbNC1080DevUnlock (USBD_NODE_ID nodeId);
  258. /* END Specific interfaces. */
  259. IMPORT int     endMultiLstCnt (END_OBJ* pEnd);
  260. /* forward static functions */
  261. LOCAL STATUS usbNC1080Start (NC1080_END_DEV * pDrvCtrl);
  262. LOCAL STATUS usbNC1080Stop     (NC1080_END_DEV * pDrvCtrl);
  263. LOCAL int     usbNC1080Ioctl    (NC1080_END_DEV * pDrvCtrl, int cmd, caddr_t data);
  264. LOCAL STATUS usbNC1080Unload (NC1080_END_DEV * pDrvCtrl);
  265. LOCAL STATUS usbNC1080Send     (NC1080_END_DEV * pDrvCtrl, M_BLK_ID pBuf);
  266. LOCAL STATUS usbNC1080MCastAdd (NC1080_END_DEV * pDrvCtrl, char * pAddress);
  267. LOCAL STATUS usbNC1080MCastDel (NC1080_END_DEV * pDrvCtrl, char * pAddress);
  268. LOCAL STATUS usbNC1080MCastGet (NC1080_END_DEV * pDrvCtrl, MULTI_TABLE * pTable);
  269. LOCAL STATUS usbNC1080PollSend (NC1080_END_DEV * pDrvCtrl, M_BLK_ID pBuf);
  270. LOCAL STATUS usbNC1080PollRcv  (NC1080_END_DEV * pDrvCtrl, M_BLK_ID pBuf);
  271. LOCAL STATUS usbNC1080Recv (NC1080_END_DEV * pDrvCtrl, UINT8 * pData, UINT16 len);
  272. LOCAL STATUS  usbNC1080Shutdown (int errCode);
  273. LOCAL STATUS  usbNC1080Reset  (NC1080_END_DEV * pDrvCtrl);
  274. LOCAL STATUS  usbNC1080DevInit  (NC1080_END_DEV * pDrvCtrl,
  275.                                  UINT16 vendorId,
  276.                                  UINT16 productId);
  277. LOCAL void  usbNC1080TxCallback(pVOID p);
  278. LOCAL void  usbNC1080RxCallback(pVOID p);
  279. LOCAL STATUS  usbNC1080ListenForInput   (NC1080_END_DEV * pDrvCtrl);
  280. LOCAL USB_NC1080_DEV * usbNC1080FindUsbNode     (USBD_NODE_ID nodeId);
  281. LOCAL USB_NC1080_DEV * usbNC1080FindUsbDevice  (UINT16 vendorId, UINT16 productId);
  282. LOCAL VOID  usbNC1080DestroyDevice      (NC1080_END_DEV * pDrvCtrl);
  283. LOCAL STATUS  usbNC1080AttachCallback
  284.   (USBD_NODE_ID nodeId,
  285.     UINT16 attachAction,
  286.      UINT16 configuration,
  287.      UINT16 interface,
  288.      UINT16 deviceClass,
  289.      UINT16 deviceSubClass,
  290.      UINT16 deviceProtocol
  291. );
  292. LOCAL STATUS usbNC1080ReadRegister(NC1080_END_DEV * pDrv, UINT8 reg, UINT16 * retVal);
  293. LOCAL STATUS usbNC1080WriteRegister(NC1080_END_DEV * pDrv, UINT8 reg, UINT16 retVal);
  294. LOCAL VOID notifyAttach ( USB_NC1080_DEV* pDev, UINT16 attachCode);
  295. /*
  296.  * Declare our function table.  This is static across all driver
  297.  * instances.
  298.  */
  299. LOCAL NET_FUNCS usbNC1080FuncTable =
  300.     {
  301.     (FUNCPTR) usbNC1080Start, /* Function to start the device. */
  302.     (FUNCPTR) usbNC1080Stop, /* Function to stop the device. */
  303.     (FUNCPTR) usbNC1080Unload, /* Unloading function for the driver. */
  304.     (FUNCPTR) usbNC1080Ioctl, /* Ioctl function for the driver. */
  305.     (FUNCPTR) usbNC1080Send, /* Send function for the driver. */
  306.     (FUNCPTR) usbNC1080MCastAdd, /* Multicast add function for the */
  307. /* driver. */
  308.     (FUNCPTR) usbNC1080MCastDel, /* Multicast delete function for */
  309. /* the driver. */
  310.     (FUNCPTR) usbNC1080MCastGet, /* Multicast retrieve function for */
  311. /* the driver. */
  312.     (FUNCPTR) usbNC1080PollSend, /* Polling send function */
  313.     (FUNCPTR) usbNC1080PollRcv, /* Polling receive function */
  314.     endEtherAddressForm, /* put address info into a NET_BUFFER */
  315.     endEtherPacketDataGet,  /* get pointer to data in NET_BUFFER */
  316.     endEtherPacketAddrGet  /* Get packet addresses. */
  317.     };
  318. /*
  319.  * functions to do a short (UINT16) access to read / write the registers
  320.  * from the net1080 chip.
  321.  */
  322. LOCAL STATUS usbNC1080ReadRegister
  323.     (
  324.     NC1080_END_DEV * pDrv, 
  325.     UINT8 reg, 
  326.     UINT16 * retVal
  327.     )
  328.     {
  329.     UINT16 actLen;
  330.     UINT16 data;
  331.     if (usbdVendorSpecific (usbNC1080Handle, pDrv->pDev->nodeId,
  332. USB_RT_VENDOR | USB_RT_DEV_TO_HOST, /* bmRequest */ 
  333. NETCHIP_REQ_REGISTER_READ,  /* bRequest */
  334. 0,  /* wValue */
  335. TO_LITTLEW(reg), /* wIndex */
  336. TO_LITTLEW(2), /* wLength must be 2 */
  337. (UINT8 *)retVal, &actLen) != OK)
  338. {
  339. DRV_LOG (DRV_DBG_REGISTER, "Read Register Failed reading from "
  340. "%d regsiter..n", reg, 0, 0, 0, 0, 0);
  341. return ERROR;
  342. }
  343.   
  344.     data = FROM_LITTLEW(*retVal);
  345.     *retVal = data;
  346.     return OK;
  347.     }
  348. LOCAL STATUS usbNC1080WriteRegister 
  349.     (
  350.     NC1080_END_DEV * pDrv, 
  351.     UINT8 reg, 
  352.     UINT16 data
  353.     )
  354.     {
  355.     if (usbdVendorSpecific (usbNC1080Handle, pDrv->pDev->nodeId,
  356. USB_RT_VENDOR | USB_RT_HOST_TO_DEV, /* bmRequest */
  357. NETCHIP_REQ_REGISTER_READ,  /* bRequest */
  358. TO_LITTLEW(data),  /* wValue */
  359. TO_LITTLEW(reg), /* wIndex */
  360. 0, /* wLength */
  361. 0, NULL) != OK)
  362. {
  363. DRV_LOG (DRV_DBG_REGISTER, "Write Register Failed while writing "
  364. "%d to %d register..n", data, reg, 0, 0, 0, 0);
  365. return ERROR;
  366. }
  367.      return OK;
  368. }
  369. /* Register display routines */
  370. /**************************************************************************
  371. *
  372. * usbNC1080ShowStatus - Displays the NC1080 status register
  373. * Displays, in human readable way, the status register of the NC1080 
  374. * Turboconnect device
  375. *
  376. * RETURNS: N/A 
  377. */
  378. LOCAL void usbNC1080ShowStatus 
  379.     (
  380.     UINT16 status
  381.     )
  382.     {
  383.     DRV_LOG (DRV_DBG_REGISTER, "Status Register : %x n"
  384.                                "Reading from Port : %c n",
  385.                                 status,
  386.                                 (status & 0x8000)?'A':'B',
  387.                                  0, 0, 0, 0);
  388.     DRV_LOG (DRV_DBG_REGISTER, "Peer port : n"
  389.                                "   %sconnected : %s: "
  390.                                "MBOX data %savailable : "
  391.                                "data %savailable n",
  392.                                 (UINT)((status & 0x4000)?"":"dis"),
  393.                                 (UINT)((status & 0x2000)?"suspended":"live"),
  394.                                 (UINT)((status & 0x1000)?"":"Not"),
  395.                                 (UINT)((status & 0x0300)?"":"Not"),
  396.                                 0, 0);
  397.     DRV_LOG (DRV_DBG_REGISTER, "This port : n"
  398.                                "t%sconnected : %s: "
  399.                                "MBOX data %savailable : "
  400.                                "data %savailable n",
  401.                                 (UINT)((status & 0x0040)?"":"dis"),
  402.                                 (UINT)((status & 0x0020)?"suspended":"live"),
  403.                                 (UINT)((status & 0x0010)?"":"Not"),
  404.                                 (UINT)((status & 0x0003)?"":"Not"),
  405.                                 0, 0);
  406.     }
  407. /**************************************************************************
  408. *
  409. * usbNC1080ShowUsbctl -  Displays NC1080 USBCTL register
  410. *
  411. * Displays, in human readable way, the USBCTL register of the NC1080 
  412. * Turboconnect device
  413. *
  414. * RETURNS: N/A
  415. */
  416. LOCAL void usbNC1080ShowUsbctl
  417.     (
  418.     UINT16 usbctl
  419.     )
  420.     {
  421.     DRV_LOG (DRV_DBG_REGISTER, "USBCTL Register : %x n", usbctl,
  422.     2, 3, 4, 5, 6);
  423.     }
  424. /**************************************************************************
  425. *
  426. * usbNC1080ShowTtl - Display NC1080 TTL register
  427. *
  428. * Displays, in human readable way, the TTL register of the NC1080 
  429. * Turboconnect device
  430. *
  431. * RETURNS: N/A
  432. */
  433. LOCAL void usbNC1080ShowTtl
  434.     (
  435.     UINT16 ttl
  436.     )
  437.     {
  438.     DRV_LOG (DRV_DBG_REGISTER, "TTL Register : %x n"
  439.                                "tTTL for this Port : %d ms "
  440.                                "other port : %d msn",
  441.                                 ttl, (ttl&0x00ff), ((ttl>>8)&0x00ff),
  442.                                  0, 0, 0);
  443.     }
  444. /**************************************************************************
  445. *
  446. * usbNC1080Reset - Resets the NC1080 Turboconnect device
  447. *
  448. *
  449. * RETURNS: OK or ERROR
  450. */
  451. LOCAL STATUS usbNC1080Reset 
  452.     (
  453.     NC1080_END_DEV* pDrvCtrl
  454.     )
  455.     {
  456.     UINT16 reg_status, reg_usbctl, reg_ttl, temp_ttl;
  457.     /* Read the status register */
  458.     if (usbNC1080ReadRegister(pDrvCtrl, NETCHIP_STATUS, &reg_status) != OK)
  459.         {
  460.         DRV_LOG (DRV_DBG_RESET, "Failed to read status register",
  461.                 0, 0, 0, 0, 0, 0);
  462.         return ERROR;
  463.         }
  464.     usbNC1080ShowStatus (reg_status);
  465.     if (usbNC1080ReadRegister(pDrvCtrl, NETCHIP_USBCTL, &reg_usbctl) != OK)
  466.         {
  467.         DRV_LOG (DRV_DBG_RESET, "Failed to read usbctl register",
  468.                 0, 0, 0, 0, 0, 0);
  469.         return ERROR;
  470.         }
  471.     usbNC1080ShowUsbctl (reg_usbctl);
  472.     /* Flush Fifo of both ports */
  473.     if (usbNC1080WriteRegister(pDrvCtrl, NETCHIP_USBCTL,
  474.                 USBCTL_FLUSH_THIS | USBCTL_FLUSH_OTHER) == ERROR)
  475.         {
  476.         return ERROR;
  477.         }
  478.     /* Some TTL funda */
  479.     if (usbNC1080ReadRegister(pDrvCtrl, NETCHIP_TTL, &reg_ttl) != OK)
  480.         {
  481.         DRV_LOG (DRV_DBG_RESET, "Failed to read ttl register",
  482.                 0, 0, 0, 0, 0, 0);
  483.         return ERROR;
  484.         }
  485.     usbNC1080ShowTtl(reg_ttl);
  486.     /* set some timeout for our read fifo. it shall time out and flush data */
  487.     temp_ttl = (reg_ttl) & 0xff00; /* on the other side */
  488.     reg_ttl = (NETCHIP_TTLVAL & 0x00ff);        /* our ttl */
  489.     reg_ttl |= temp_ttl; /* TTL register value */
  490.     if (usbNC1080WriteRegister(pDrvCtrl, NETCHIP_TTL,
  491.                 reg_ttl) == ERROR)
  492.         {
  493.         DRV_LOG (DRV_DBG_RESET, "Failed to set ttl register",
  494.                 0, 0, 0, 0, 0, 0);
  495.         return ERROR;
  496.         }
  497.     return OK;
  498.     }
  499. /**************************************************************************
  500. *
  501. * usbNC1080DrvInit - Initializes the usbNC1080 Library
  502. *
  503. * Initializes the usbNC1080 driver. The driver maintains an initialization
  504. * count so that the calls to this function might be nested.
  505. *
  506. * This function initializes the system resources required for the driver
  507. * initializes the linked list for the usbNC1080 devices found.
  508. * This function reegisters the library as a client for the usbd calls and 
  509. * registers for dynamic attachment notification of usb devices. Since the
  510. * usbNC1080 device is a "vendor specific" device, this function registers
  511. * for attachment / removal notification for all devices.
  512. *
  513. * This function is to be called AFTER the usbd initialization and before 
  514. * the endLoad gets called. Otherwise the driver can't perform.
  515. *
  516. * RETURNS : OK if successful, ERROR if failure
  517. *
  518. * ERRNO :
  519. *
  520. * S_usbNC1080Drv_OUT_OF_RESOURCES
  521. * S_usbNC1080Drv_USBD_FAULT
  522. */
  523. STATUS usbNC1080DrvInit(void)
  524.     {
  525.     
  526.     /* see if already initialized. if not, initialize the library */
  527.     initCount++;
  528.     if(initCount != 1) /* if its the first time */
  529. return OK;
  530.     /* Initialize usbd */
  531.     usbdInitialize();
  532.     memset (&usbNC1080DevList, 0, sizeof (usbNC1080DevList));
  533.  
  534.     usbNC1080Mutex = NULL;
  535.     usbNC1080TxMutex = NULL;
  536.     usbNC1080RxMutex = NULL;
  537.     usbNC1080IrpSem = NULL;
  538.     usbNC1080Handle = NULL;
  539.     /* create the mutex */
  540.     if (OSS_MUTEX_CREATE (&usbNC1080Mutex) != OK)
  541. return usbNC1080Shutdown (S_usbNC1080Lib_OUT_OF_RESOURCES);
  542.     if (OSS_MUTEX_CREATE (&usbNC1080TxMutex) != OK)
  543. return usbNC1080Shutdown (S_usbNC1080Lib_OUT_OF_RESOURCES);
  544.     if (OSS_MUTEX_CREATE (&usbNC1080RxMutex) != OK)
  545. return usbNC1080Shutdown (S_usbNC1080Lib_OUT_OF_RESOURCES);
  546.     if (OSS_SEM_CREATE (1, 0 , &usbNC1080IrpSem) != OK)
  547.         return usbNC1080Shutdown (S_usbNC1080Lib_OUT_OF_RESOURCES);
  548.     /*
  549.      * Register the Library as a Client and register for
  550.      * dynamic attachment callback.
  551.      */
  552.      if((usbdClientRegister (CLIENT_NAME, &usbNC1080Handle) != OK) ||
  553. (usbdDynamicAttachRegister (usbNC1080Handle, 
  554.     USBD_NOTIFY_ALL, 
  555.     USBD_NOTIFY_ALL, 
  556.     USBD_NOTIFY_ALL, 
  557. (USBD_ATTACH_CALLBACK) usbNC1080AttachCallback)
  558.  != OK))
  559. {
  560.      return usbNC1080Shutdown (S_usbNC1080Lib_USBD_FAULT);
  561. }
  562.     return OK;
  563.     }
  564. /**************************************************************************
  565. *
  566. * usbNC1080AttachCallback - Gets called for attachment/detachment of devices
  567. *
  568. * The USBD will invoke this callback when a USB device is attached to or 
  569. * removed from the system (usb bus).  
  570. * <nodeId> is the USBD_NODE_ID of the node being attached or removed.
  571. * <attachAction> is USBD_DYNA_ATTACH or USBD_DYNA_REMOVE.
  572. * The registeration has been for notification of any usb device attachment /
  573. * removal. This means that the USBD will invoke this function once for each
  574. * configuration / interface for any device attached. <configuration> and
  575. * <interface> will indicate the configuration / interface information of
  576. * the device. How-ever, usbNC1080 device has only one configuration which has
  577. * only one interface.
  578. * <deviceClass> and <deviceSubClass> will match the class/subclass for
  579. * which we registered.  In this case, since usbNC1080 is a vendor specific
  580. * device, these fields donot matter for this device.
  581. * <deviceProtocol> doesn't have meaning for the vendor devices so we 
  582. * ignore this field.
  583. *
  584. * NOTE: The USBD will invoke this function once for each configuration/
  585. * interface.  So, it is possible that a single device insertion/removal may 
  586. * trigger multiple callbacks.  This function ignores all callbacks except the
  587. * first for a given device.
  588. *
  589. * RETURNS: N/A
  590. *
  591. * NOMANUAL
  592. */
  593. STATUS  usbNC1080AttachCallback
  594.     (
  595.     USBD_NODE_ID nodeId, 
  596.     UINT16 attachAction, 
  597.     UINT16 configuration,
  598.     UINT16 interface,
  599.     UINT16 deviceClass, 
  600.     UINT16 deviceSubClass, 
  601.     UINT16 deviceProtocol
  602.     )
  603.     {
  604.     USB_NC1080_DEV * pNewDev;
  605.     UINT8 bfr[USB_MAX_DESCR_LEN];
  606.     UINT16 actLen;
  607.     UINT16 vendorId;
  608.     UINT16 productId;
  609.     int index = 0;
  610.     OSS_MUTEX_TAKE (usbNC1080Mutex, OSS_BLOCK);
  611.     switch (attachAction)
  612. {
  613. case USBD_DYNA_ATTACH :
  614.     /* a new device is found */
  615.     DRV_LOG (DRV_DBG_ATTACH, "New Usb device on Bus..n",
  616.          0, 0, 0, 0, 0, 0);
  617.     /* First Ensure that this device is not already on the list */
  618.     if (usbNC1080FindUsbNode (nodeId) != NULL)
  619.         break;
  620.     /* Now, we have to ensure that its a NETCHIP device */
  621.             if (usbdDescriptorGet (usbNC1080Handle, 
  622.    nodeId, 
  623.    USB_RT_STANDARD | USB_RT_DEVICE, 
  624.    USB_DESCR_DEVICE, 
  625.    0, 
  626.    0, 
  627.    sizeof (bfr), 
  628.    bfr, 
  629.    &actLen) 
  630. != OK)
  631.         {
  632. DRV_LOG (DRV_DBG_ATTACH, "DescriporGet Failed for device "
  633. "descriptor.n", 0, 0, 0, 0, 0, 0);
  634. break;
  635.              }
  636.     DRV_DESC_PRINT (DRV_DBG_ATTACH, "Device Descriptor", bfr, actLen);
  637.             vendorId = ((pUSB_DEVICE_DESCR)bfr)->vendor;
  638.     productId = ((pUSB_DEVICE_DESCR)bfr)->product;
  639.     DRV_LOG (DRV_DBG_ATTACH, "VendorID : 0x%x t ProductID : 0x%x.n",
  640.      vendorId, productId, 0, 0, 0, 0);
  641.     /* Check if the device is a NC1080 Turboconnect */
  642.     for (index = 0; products [index].idVendor != 0; index++) 
  643. {
  644. if (products [index].idVendor != vendorId)
  645. continue;
  646. if (products [index].idProduct != productId)
  647. continue;
  648. break;
  649. }
  650.     if (products [index].idVendor == 0) /* device not a usbNC1080 device */
  651. {
  652. DRV_LOG (DRV_DBG_ATTACH, " unsupported device ... n",
  653. 0, 0, 0, 0, 0, 0);
  654. break;
  655. }
  656.        DRV_LOG (DRV_DBG_ATTACH, "that was a NC1080 device!!!  n",
  657.     0, 0, 0, 0, 0, 0);
  658.     /* 
  659.      * Now create a structure for the newly found device and add 
  660.      * it to the linked list
  661.      */
  662.          /* Try to allocate space for a new device struct */
  663.     if ((pNewDev = OSS_CALLOC (sizeof (*pNewDev))) == NULL)
  664.        {
  665. DRV_LOG (DRV_DBG_ATTACH, "Could not allocate memory "
  666. "for new device n", 0, 0, 0, 0, 0, 0);
  667. break;     
  668. }
  669.     /* Fill in the device structure */
  670.     pNewDev->nodeId = nodeId;
  671.     pNewDev->configuration = configuration;
  672.     pNewDev->interface = interface;
  673.     pNewDev->vendorId = vendorId;
  674.     pNewDev->productId = productId;
  675.     /* Add this device to the linked list */
  676.     usbListLink (&usbNC1080DevList, pNewDev, &pNewDev->devLink, 
  677. LINK_TAIL);
  678.     /* Notify registered callers that a NETCHIP device has been added */
  679.         notifyAttach(pNewDev, USB_NETCHIP_ATTACH);
  680.     break;
  681. case USBD_DYNA_REMOVE:
  682.     /* First Ensure that this device is on the list */
  683.     if ((pNewDev = usbNC1080FindUsbNode (nodeId)) == NULL)
  684.         break;
  685. if (pNewDev->connected == FALSE)
  686. {
  687. printf (" Device not found %x n",(int)pNewDev->nodeId);
  688.                 break;
  689. }
  690.     DRV_LOG (DRV_DBG_ATTACH, "NC1080 device Removed from Bus..n",
  691.          0, 0, 0, 0, 0, 0);
  692.     pNewDev->connected = FALSE;
  693.     /*
  694.      * we need not check for the vendor/product ids as if the device is
  695.      * on the list, then it is a usbNC1080 device only.
  696.      */
  697.          pNewDev->lockCount++; 
  698.             notifyAttach (pNewDev, USB_NETCHIP_REMOVE); 
  699.             pNewDev->lockCount--; 
  700.     if (pNewDev->lockCount == 0)
  701. usbNC1080DestroyDevice((NC1080_END_DEV *)pNewDev->pDevStructure);
  702.     break;
  703. }
  704.     OSS_MUTEX_RELEASE (usbNC1080Mutex);
  705.     return OK;
  706.     }
  707. /**************************************************************************
  708. *
  709. * findEndpoint - Searches for a BULK endpoint of the indicated direction.
  710. *
  711. * RETURNS: pointer to matching endpoint descriptor or NULL if not found
  712. * NOMANUAL
  713. */
  714. LOCAL pUSB_ENDPOINT_DESCR findEndpoint
  715.     (
  716.     pUINT8 pBfr, /* buffer to search for */
  717.     UINT16 bfrLen, /* buffer length */
  718.     UINT16 direction /* end point direction */
  719.     )
  720.     {
  721.     pUSB_ENDPOINT_DESCR pEp;
  722.     while ((pEp = (pUSB_ENDPOINT_DESCR) 
  723.     usbDescrParseSkip (&pBfr, &bfrLen, USB_DESCR_ENDPOINT)) 
  724. != NULL)
  725. {
  726. if ((pEp->attributes & USB_ATTR_EPTYPE_MASK) == USB_ATTR_BULK &&
  727.     (pEp->endpointAddress & USB_ENDPOINT_DIR_MASK) == direction)
  728.     break;
  729. }
  730.     return pEp;
  731.     }
  732. /**************************************************************************
  733. *
  734. * usbNC1080FindUsbNode - Searches for a usbNC1080 device of indicated <nodeId>
  735. * in the usbNC1080 device linked list
  736. *
  737. * RETURNS: pointer to matching dev struct or NULL if not found
  738. * NOMANUAL
  739. */
  740. USB_NC1080_DEV* usbNC1080FindUsbNode
  741.     (
  742.     USBD_NODE_ID nodeId /* Node Id to find */
  743.     )
  744.     {
  745.     USB_NC1080_DEV * pDev = usbListFirst (&usbNC1080DevList);
  746.     while (pDev != NULL)
  747. {
  748. if (pDev->nodeId == nodeId)
  749.     break;
  750. pDev = usbListNext (&pDev->devLink);
  751. }
  752.     return pDev;
  753.     }
  754. /**************************************************************************
  755. *
  756. * usbNC1080FindUsbDevice - Searches for a usbNC1080 device of a given <productId>
  757. * and <vendorId> in the usbNC1080 device linked list.
  758. *
  759. * RETURNS: pointer to matching dev struct or NULL if not found
  760. * NOMANUAL
  761. */
  762. USB_NC1080_DEV* usbNC1080FindUsbDevice
  763.     (
  764.     UINT16 vendorId, /* Vendor Id to search for */
  765.     UINT16 productId /* Product Id to search for */
  766.     )
  767.     {
  768.     USB_NC1080_DEV * pDev = usbListFirst (&usbNC1080DevList);
  769.     while (pDev != NULL)
  770. {
  771. if ((pDev->vendorId == vendorId) && (pDev->productId == productId))
  772.     break;
  773. pDev = usbListNext (&pDev->devLink);
  774. }
  775.     return pDev;
  776.     }
  777. /**************************************************************************
  778. *
  779. * usbNC1080DevInit - Initializes the usbNC1080 Device structure.
  780. *
  781. * This function initializes the usb ethernet device. It is called by 
  782. * usbNC1080Load() as part of the end driver initialzation. usbNC1080Load()
  783. * expects this routine to perform all the device and usb specific
  784. * initialization and fill in the corresponding member fields in the 
  785. * NC1080_END_DEV structure.
  786. *
  787. * This function first checks to see if the device corresponding to
  788. * <vendorId> and <productId> exits in the linkedlist usbNC1080DevList.
  789. * It allocates memory for the input and output buffers. The device
  790. * descriptors will be retrieved and are used to findout the IN and OUT
  791. * bulk end points. Once the end points are found, the corresponding
  792. * pipes are constructed. The Pipe handles are stored in the device 
  793. * structure <pDrvCtrl>. 
  794. *
  795. * RETURNS : OK if every thing succeds and ERROR if any thing fails.
  796. *
  797. */
  798. STATUS usbNC1080DevInit
  799.     (
  800.     NC1080_END_DEV * pDrvCtrl, /* the device structure to be updated */
  801.     UINT16    vendorId, /* manufacturer id of the device */
  802.     UINT16    productId     /* product id of the device */
  803.     )
  804.     {
  805.     USB_NC1080_DEV * pNewDev;
  806.     pUSB_CONFIG_DESCR pCfgDescr;
  807.     pUSB_INTERFACE_DESCR pIfDescr;
  808.     pUSB_ENDPOINT_DESCR pOutEp;
  809.     pUSB_ENDPOINT_DESCR pInEp;
  810.     UINT8 bfr [USB_MAX_DESCR_LEN];
  811.     pUINT8 pBfr;
  812.     UINT8** ppIrpBfrs;
  813.     UINT8** ppInBfr;
  814.     UINT16 actLen;
  815.     
  816.     int index = 0;
  817.     if(pDrvCtrl == NULL)
  818. {
  819. DRV_LOG (DRV_DBG_INIT,"Null Device n", 0, 0, 0, 0, 0, 0);
  820. return ERROR;
  821. }
  822.     /* Find if the device is in the found devices list */
  823.     if ((pNewDev = usbNC1080FindUsbDevice (vendorId,productId)) == NULL)
  824. {
  825. DRV_LOG (DRV_DBG_INIT,"Could not find device in the attached "
  826. "usbNC1080 devices..n", 0, 0, 0, 0, 0, 0);
  827. return ERROR;
  828. }
  829.     /* Link the End Structure and the device that is found */
  830.     pDrvCtrl->pDev = pNewDev;
  831.     /* Allocate memory for the output buffers..*/
  832.     if ((ppIrpBfrs = (UINT8**) memalign (sizeof(ULONG), 
  833. pDrvCtrl->noOfIrps * sizeof (char *))) 
  834. == NULL)
  835. {
  836. DRV_LOG (DRV_DBG_INIT,"Could not allocate memory for IRPs.n",
  837.      0, 0, 0, 0, 0, 0);
  838. return ERROR;
  839. }
  840.     for (index=0;index<pDrvCtrl->noOfIrps;index++)
  841. {
  842. if ((ppIrpBfrs[index] = (pUINT8)memalign(sizeof(ULONG),
  843.    NETCHIP_OUT_BFR_SIZE+8)) == NULL)
  844.     {
  845.     DRV_LOG (DRV_DBG_INIT,"Could not allocate memory for buffer"
  846. " for input Irp %xn", 
  847. index, 0, 0, 0, 0, 0);    
  848.     return ERROR;
  849.     }
  850. }
  851.     /* Allocate memory for input buffers */
  852.     if ((ppInBfr = (UINT8**)memalign(sizeof(ULONG),
  853. pDrvCtrl->noOfInBfrs * sizeof (char *)))==NULL)
  854. {
  855. DRV_LOG (DRV_DBG_INIT,"Could Not align Memory for"
  856.     " InBfrs pointer array...n",
  857.      0, 0, 0, 0, 0, 0);
  858.         return ERROR;
  859.         }
  860.    for (index=0;index<pDrvCtrl->noOfInBfrs;index++)
  861. {
  862. if ((ppInBfr[index] = (pUINT8)memalign(sizeof(ULONG),
  863.    NETCHIP_IN_BFR_SIZE+8)) == NULL)
  864.     {
  865.     DRV_LOG (DRV_DBG_INIT,"Could not allocate memory for"
  866. " buffer for input Irp %xn", 
  867. index, 0, 0, 0, 0, 0);    
  868.     return ERROR;
  869.     }
  870. }
  871.     
  872.     pDrvCtrl->pOutBfrArray= ppIrpBfrs;
  873.     pDrvCtrl->pInBfrArray = ppInBfr;
  874.     pDrvCtrl->txBufIndex=0;
  875.     pDrvCtrl->rxBufIndex=0;
  876.     pDrvCtrl->inBfrLen = NETCHIP_IN_BFR_SIZE;
  877.     /*
  878.      * Now we decifer the descriptors provided by the device ..
  879.      * we try finding out what end point is what..
  880.      */
  881.     /* To start with, get the configuration descriptor ..*/
  882.     if (usbdDescriptorGet (usbNC1080Handle, 
  883.    pNewDev->nodeId, 
  884.    USB_RT_STANDARD | USB_RT_DEVICE, 
  885.    USB_DESCR_CONFIGURATION, 
  886.    0, 
  887.    0, 
  888.    sizeof (bfr), 
  889.    bfr, 
  890.    &actLen) 
  891. != OK)
  892. {
  893. DRV_LOG (DRV_DBG_INIT, "DescriptorGet failed for CFG...n",
  894.      0, 0, 0, 0, 0, 0);
  895. return ERROR;
  896. }
  897.     if ((pCfgDescr = (pUSB_CONFIG_DESCR)
  898. usbDescrParse (bfr, actLen, USB_DESCR_CONFIGURATION)) == NULL)
  899. {
  900. DRV_LOG (DRV_DBG_INIT, "Could not find Config. Desc...n",
  901.      0, 0, 0, 0, 0, 0);
  902. return ERROR;
  903. }
  904.     /* DRV_DESC_PRINT (DRV_DBG_INIT, "Configuration Descriptor",
  905.                    (UINT8 *)pCfgDescr, actLen); */
  906.     pBfr = bfr;
  907.     /*
  908.      * Since we registered for NOTIFY_ALL for attachment of devices,
  909.      * the configuration no and interface number as reported by the
  910.      * call back function doesn't have any meanning.
  911.      * we refer to the DRV document and it says, it has only one
  912.      * interface with number 0. So the first (only) interface we find
  913.      * is the interface we want.
  914.      * If there are more interfaces and one of them meet our requirement
  915.      * (as reported by callback funtction), then we need to parse
  916.      * until we find our one..
  917.      */
  918.     if ((pIfDescr = (pUSB_INTERFACE_DESCR)
  919. usbDescrParseSkip (&pBfr, &actLen, USB_DESCR_INTERFACE)) == NULL)
  920. {
  921. DRV_LOG (DRV_DBG_INIT, "Could not find Interface Desc.n",
  922.      0, 0, 0, 0, 0, 0);
  923.      return ERROR;
  924. }
  925.     /*
  926.      * DRV_DESC_PRINT (DRV_DBG_INIT, "Interface Descriptor", 
  927.      * (UINT8 *)pIfDescr, actLen); 
  928.      */
  929.     /* Find out the output and input end points ..*/
  930.     if ((pOutEp = findEndpoint (pBfr, actLen, USB_ENDPOINT_OUT)) == NULL)
  931. {
  932. DRV_LOG (DRV_DBG_INIT, "No Output End Point n",
  933.      0, 0, 0, 0, 0, 0);
  934. return ERROR;
  935. }
  936.     DRV_DESC_PRINT (DRV_DBG_INIT, "Out EP", (UINT8 *)pOutEp, 5);
  937.     if ((pInEp = findEndpoint (pBfr, actLen, USB_ENDPOINT_IN)) == NULL)
  938. {
  939. DRV_LOG (DRV_DBG_INIT, "No Input End Point n",
  940.      0, 0, 0, 0, 0, 0);
  941. return ERROR;
  942. }
  943.     DRV_DESC_PRINT (DRV_DBG_INIT, "In EP", (UINT8 *)pInEp, 5);
  944.     pNewDev->maxPower = pCfgDescr->maxPower;
  945.     /* Now, set the configuration. */
  946.     if (usbdConfigurationSet (usbNC1080Handle, 
  947.       pNewDev->nodeId, 
  948.       pCfgDescr->configurationValue, 
  949.       pCfgDescr->maxPower * USB_POWER_MA_PER_UNIT) 
  950.    != OK)
  951. return ERROR;
  952.     /*  reset the device */
  953.     usbNC1080Reset(pDrvCtrl);
  954.     /* Now, Create the Pipes.. */
  955.     if (usbdPipeCreate (usbNC1080Handle, 
  956. pNewDev->nodeId, 
  957. pOutEp->endpointAddress, 
  958. pCfgDescr->configurationValue, 
  959. pNewDev->interface, 
  960. USB_XFRTYPE_BULK, 
  961. USB_DIR_OUT, 
  962. FROM_LITTLEW (pOutEp->maxPacketSize), 
  963. 0, 
  964. 0, 
  965. &pDrvCtrl->outPipeHandle) 
  966. != OK)
  967. {
  968. DRV_LOG (DRV_DBG_INIT, "Pipe O/P coud not be created n",
  969.      0, 0, 0, 0, 0, 0);
  970. return ERROR;
  971. }
  972.     if (usbdPipeCreate (usbNC1080Handle, 
  973. pNewDev->nodeId, 
  974. pInEp->endpointAddress, 
  975. pCfgDescr->configurationValue, 
  976. pNewDev->interface, 
  977. USB_XFRTYPE_BULK, 
  978. USB_DIR_IN, 
  979. FROM_LITTLEW (pInEp->maxPacketSize), 
  980. 0, 
  981. 0, 
  982. &pDrvCtrl->inPipeHandle) 
  983. != OK)
  984. {
  985. DRV_LOG (DRV_DBG_INIT, "Pipe I/P coud not be created n",
  986.            0, 0, 0, 0, 0, 0);
  987. return ERROR;
  988. }
  989.     /* Reset counters and indices */
  990.     pDrvCtrl->inIrpInUse = FALSE;
  991.     pDrvCtrl->outIrpInUse = FALSE;
  992.     pDrvCtrl->txBufIndex = 0;
  993.     pDrvCtrl->rxBufIndex = 0;
  994.     pDrvCtrl->txPkts = 0;
  995.     /* Now device is ready for communication : return back to the caller */
  996.     return OK;
  997.     }
  998. /**************************************************************************
  999. *
  1000. * usbNC1080Shutdown - shuts down usbNC1080Lib
  1001. *
  1002. * <errCode> should be OK or S_usbNC1080Lib_xxxx.  This value will be
  1003. * passed to ossStatus() and the return value from ossStatus() is the
  1004. * return value of this function.
  1005. *
  1006. * RETURNS: OK, or ERROR per value of <errCode> passed by caller
  1007. */
  1008. LOCAL STATUS usbNC1080Shutdown
  1009.     (
  1010.     int errCode
  1011.     )
  1012.     {
  1013.     NC1080_END_DEV * pDev;
  1014.     /* Dispose of any open connections. */
  1015.     while ((pDev = usbListFirst (&usbNC1080DevList)) != NULL)
  1016. usbNC1080DestroyDevice (pDev);
  1017.     /*
  1018.      * Release our connection to the USBD.  The USBD automatically
  1019.      * releases any outstanding dynamic attach requests when a client
  1020.      * unregisters.
  1021.      */
  1022.     if (usbNC1080Handle != NULL)
  1023. {
  1024. usbdClientUnregister (usbNC1080Handle);
  1025. usbNC1080Handle = NULL;
  1026. }
  1027.     /* Release resources. */
  1028.     if (usbNC1080Mutex != NULL)
  1029. {
  1030. OSS_MUTEX_DESTROY (usbNC1080Mutex);
  1031. usbNC1080Mutex = NULL;
  1032. }
  1033.     if (usbNC1080TxMutex != NULL)
  1034. {
  1035. OSS_MUTEX_DESTROY (usbNC1080TxMutex);
  1036. usbNC1080TxMutex = NULL;
  1037. }
  1038.     if (usbNC1080RxMutex != NULL)
  1039. {
  1040. OSS_MUTEX_DESTROY (usbNC1080RxMutex);
  1041. usbNC1080RxMutex = NULL;
  1042. }
  1043.     if (usbNC1080IrpSem != NULL)
  1044.         {
  1045.         OSS_SEM_DESTROY (usbNC1080IrpSem);
  1046.         usbNC1080IrpSem = NULL;
  1047.         }
  1048.     usbdShutdown();
  1049.     return ossStatus (errCode);
  1050.     }
  1051. /**************************************************************************
  1052. *
  1053. * usbNC1080DestroyDevice - disposes of a NC1080_END_DEV structure
  1054. *
  1055. * Unlinks the indicated NC1080_END_DEV structure and de-allocates
  1056. * resources associated with the channel.
  1057. *
  1058. * RETURNS: N/A
  1059. */
  1060. VOID usbNC1080DestroyDevice
  1061.     (
  1062.     NC1080_END_DEV * pDrvCtrl
  1063.     )
  1064.     {
  1065.     USB_NC1080_DEV * pDev;
  1066.     if (pDrvCtrl != NULL)
  1067. {
  1068. pDev = pDrvCtrl->pDev;
  1069. /* Unlink the structure. */
  1070. usbListUnlink (&pDev->devLink);
  1071.   
  1072. /* Release pipes and wait for IRPs to be cancelled if necessary. */
  1073. if (pDrvCtrl->outPipeHandle != NULL)
  1074.     usbdPipeDestroy (usbNC1080Handle, pDrvCtrl->outPipeHandle);
  1075. if (pDrvCtrl->inPipeHandle != NULL)
  1076.     usbdPipeDestroy (usbNC1080Handle, pDrvCtrl->inPipeHandle);
  1077. while (pDrvCtrl->outIrpInUse || pDrvCtrl->inIrpInUse) 
  1078.     OSS_THREAD_SLEEP (1);
  1079.   /*  Release Input buffers*/
  1080. if ( pDrvCtrl->pInBfrArray !=NULL)
  1081.     {
  1082.             OSS_FREE(pDrvCtrl->pInBfrArray);
  1083.     taskDelay(sysClkRateGet()*1);
  1084.     DRV_LOG (DRV_DBG_ATTACH, "Destroy device InBfrArray destroyed...n",
  1085.          0, 0, 0, 0, 0, 0);
  1086.     }
  1087. /*  Release outputIrp buffers*/
  1088. if ( pDrvCtrl->pOutBfrArray != NULL)
  1089.     {
  1090.             OSS_FREE(pDrvCtrl->pOutBfrArray);
  1091.     taskDelay(sysClkRateGet()*1);
  1092.    
  1093.     DRV_LOG (DRV_DBG_ATTACH, "Destroy device pOutBfrArray destroyed...n",
  1094.          0, 0, 0, 0, 0, 0);
  1095.             }
  1096. /* Release structure. */
  1097.         if (pDev!=NULL)
  1098.             {
  1099.     OSS_FREE (pDev);
  1100.     DRV_LOG (DRV_DBG_ATTACH, "destroy device pDev destroyed...n",
  1101.          0, 0, 0, 0, 0, 0);
  1102.          }
  1103. }
  1104.     }
  1105. /**************************************************************************
  1106. *
  1107. * usbNC1080EndMemInit - initialize memory for the device.
  1108. *
  1109. * We setup the END's Network memory pool. This code is highly generic and
  1110. * very simple. We just follow the technique described in netBufLib.
  1111. * We don't even need to make the memory cache DMA coherent. This is because
  1112. * unlike other END drivers, which act on the top of the hardware, we are
  1113. * layers above the hardware.
  1114. *
  1115. * RETURNS: OK or ERROR.
  1116. * NOMANUAL
  1117. */
  1118. STATUS usbNC1080EndMemInit
  1119.     (
  1120.     NC1080_END_DEV * pDrvCtrl /* device to be initialized */
  1121.     )
  1122.     {
  1123.     /*
  1124.      * This is how we would set up and END netPool using netBufLib(1).
  1125.      * This code is pretty generic.
  1126.      */
  1127.     if ((pDrvCtrl->endObj.pNetPool = malloc (sizeof (NET_POOL))) == NULL)
  1128.         return (ERROR);
  1129.     usbNC1080MclBlkConfig.mBlkNum = 512;
  1130.     usbNC1080ClDescTbl[0].clNum = 256;
  1131.     usbNC1080MclBlkConfig.clBlkNum = usbNC1080ClDescTbl[0].clNum;
  1132.     /* Calculate the total memory for all the M-Blks and CL-Blks. */
  1133.     usbNC1080MclBlkConfig.memSize = (usbNC1080MclBlkConfig.mBlkNum *
  1134.     (MSIZE + sizeof (long))) +
  1135.       (usbNC1080MclBlkConfig.clBlkNum *
  1136.     (CL_BLK_SZ + sizeof(long)));
  1137.     if ((usbNC1080MclBlkConfig.memArea = (char *) memalign (sizeof(long),
  1138.          usbNC1080MclBlkConfig.memSize)) == NULL)
  1139.         return (ERROR);
  1140.     /* Calculate the memory size of all the clusters. */
  1141.     usbNC1080ClDescTbl[0].memSize = (usbNC1080ClDescTbl[0].clNum *
  1142.     (NETCHIP_BUFSIZ + 8)) + sizeof(int);
  1143.     /* Allocate the memory for the clusters from cache safe memory. */
  1144.     usbNC1080ClDescTbl[0].memArea =
  1145.         (char *) cacheDmaMalloc (usbNC1080ClDescTbl[0].memSize);
  1146.     if (usbNC1080ClDescTbl[0].memArea == NULL)
  1147.         {
  1148.         DRV_LOG (DRV_DBG_LOAD,"usbNC1080EndMemInit:system memory "
  1149.     "unavailablen", 1, 2, 3, 4, 5, 6);
  1150.         return (ERROR);
  1151.         }
  1152.     /* Initialize the memory pool. */
  1153.     if (netPoolInit(pDrvCtrl->endObj.pNetPool, &usbNC1080MclBlkConfig,
  1154.                     &usbNC1080ClDescTbl[0], usbNC1080ClDescTblNumEnt,
  1155.     NULL) == ERROR)
  1156.         {
  1157.         DRV_LOG (DRV_DBG_LOAD, "Could not init bufferingn",
  1158. 1, 2, 3, 4, 5, 6);
  1159.         return (ERROR);
  1160.         }
  1161.     if ((pDrvCtrl->pClPoolId = netClPoolIdGet (pDrvCtrl->endObj.pNetPool,
  1162. NETCHIP_MTU, FALSE))         
  1163.         == NULL)
  1164. {
  1165.         DRV_LOG (DRV_DBG_LOAD, "netClPoolIdGet() not successfull n",
  1166.        1, 2, 3, 4, 5, 6);
  1167. return (ERROR);
  1168.         }
  1169.     DRV_LOG (DRV_DBG_LOAD, "Memory setup completen",
  1170. 1, 2, 3, 4, 5, 6);
  1171.     return OK;
  1172.     }
  1173. /**************************************************************************
  1174. *
  1175. * usbNC1080EndParse - parse the init string
  1176. *
  1177. * Parse the input string.  Fill in values in the driver control structure.
  1178. *
  1179. * The muxLib.o module automatically prepends the unit number to the user's
  1180. * initialization string from the BSP (configNet.h).
  1181. *
  1182. * This function parses the input string and fills in the places pointed
  1183. * to by <pVendorId> and <pProductId>. Unit Number of the string will be
  1184. * be stored in the device structure pointed to by <pDrvCtrl>.
  1185. * The MAC Address of the card will be passed onto us by this initString.
  1186. *
  1187. * .IP <pDrvCtrl>
  1188. * Pointer to the device structure.
  1189. * .IP <initString>
  1190. * Initialization string for the device. It will be of the following format :
  1191. * "unit:vendorId:productId:no of input irp buffers: no of output IRP buffers:
  1192. * <6 byte mac address, delimited by :>"
  1193. * Device unit number, a small integer.
  1194. * .IP <pVendorId>
  1195. * Pointer to the place holder of the device vendor id.
  1196. * .IP <pProductId>
  1197. * Pointer to the place holder of the device product id.
  1198. * .IP <noOfIrps>
  1199. * No of Input Irp buffers 
  1200. * .IP <noOfOutIrps>
  1201. * No of output Irp buffers
  1202. * .IP <macAddress>
  1203. * 6 byte Hardware address of the device.
  1204. *
  1205. * RETURNS: OK or ERROR for invalid arguments.
  1206. * NOMANUAL
  1207. */
  1208. STATUS usbNC1080EndParse
  1209.     (
  1210.     NC1080_END_DEV * pDrvCtrl, /* device pointer */
  1211.     char * initString, /* information string */
  1212.     UINT16 * pVendorId,
  1213.     UINT16 * pProductId
  1214.     )
  1215.     {
  1216.     char * tok;
  1217.     char * pHolder = NULL;
  1218.     int i;
  1219.     /* Parse the initString */
  1220.     /* Unit number. (from muxLib.o) */
  1221.     tok = strtok_r (initString, ":", &pHolder);
  1222.     if (tok == NULL)
  1223. return ERROR;
  1224.     pDrvCtrl->unit = atoi (tok);
  1225.     DRV_LOG (DRV_DBG_PARSE, "Parse: Unit : %d..n",
  1226. pDrvCtrl->unit, 2, 3, 4, 5, 6);
  1227.     /* Vendor Id. */
  1228.     tok = strtok_r (NULL, ":", &pHolder);
  1229.     if (tok == NULL)
  1230. return ERROR;
  1231.     *pVendorId = atoi (tok);
  1232.     DRV_LOG (DRV_DBG_PARSE, "Parse: VendorId : 0x%x..n",
  1233. *pVendorId, 2, 3, 4, 5, 6);
  1234.     /* Product Id. */
  1235.     tok = strtok_r (NULL, ":", &pHolder);
  1236.     if (tok == NULL)
  1237. return ERROR;
  1238.     *pProductId = atoi (tok);
  1239.     DRV_LOG (DRV_DBG_PARSE, "Parse: ProductId : 0x%x..n",
  1240. *pProductId, 2, 3, 4, 5, 6);
  1241. /* no of in buffers */
  1242.     tok = strtok_r (NULL, ":", &pHolder);
  1243.     if (tok == NULL)
  1244. return ERROR;
  1245.     pDrvCtrl->noOfInBfrs  = atoi (tok);
  1246.   
  1247.     DRV_LOG (DRV_DBG_PARSE, "Parse: noOfInBfrs : 0x%x..n",
  1248. pDrvCtrl->noOfInBfrs, 2, 3, 4, 5, 6);
  1249.     /* no of out IRPs */
  1250.     tok = strtok_r (NULL, ":", &pHolder);
  1251.     if (tok == NULL)
  1252. return ERROR;
  1253.     pDrvCtrl->noOfIrps = atoi (tok);
  1254.   
  1255.     DRV_LOG (DRV_DBG_PARSE, "Parse: noOfIrps : 0x%x..n",
  1256. pDrvCtrl->noOfIrps, 2, 3, 4, 5, 6);
  1257.     /* Hardware address */
  1258.     for (i=0; i<6; i++)
  1259.         {
  1260.         tok = strtok_r (NULL, ":", &pHolder);
  1261.         if (tok == NULL)
  1262.     return ERROR;
  1263.         pDrvCtrl->enetAddr[i] = atoi (tok);
  1264.         }
  1265.      DRV_LOG (DRV_DBG_PARSE, "Parse: Mac Address : "
  1266.                                 "%x: %x: %x : %x: %x: %x..n",
  1267. pDrvCtrl->enetAddr[0],
  1268.                                 pDrvCtrl->enetAddr[1],
  1269.                                 pDrvCtrl->enetAddr[2],
  1270.                                 pDrvCtrl->enetAddr[3],
  1271.                                 pDrvCtrl->enetAddr[4],
  1272.                                 pDrvCtrl->enetAddr[5]);
  1273.     DRV_LOG (DRV_DBG_PARSE, "Parse: Processed all arugmentsn",
  1274. 1, 2, 3, 4, 5, 6);
  1275.     return OK;
  1276.     }
  1277. /* End Interface routines as required by VxWorks */
  1278. /**************************************************************************
  1279. *
  1280. * usbNC1080Load - initialize the driver and device
  1281. *
  1282. * This routine initializes the driver and the device to the operational state.
  1283. * All of the device specific parameters are passed in the initString.
  1284. *
  1285. * This function first extracts the vendorId, productId and mac address of
  1286. * the device from the initialization string using the usbNC1080EndParse()
  1287. * function. It then passes these parameters and its control strcuture to
  1288. * the usbNC1080DevInit() function.
  1289. *
  1290. * usbNC1080DevInit() does most of the device specific initialization
  1291. * and brings the device to the operational state. This driver will be attached
  1292. * to MUX.
  1293. *
  1294. * This function doesn't do any thing device specific. Instead, it delegates
  1295. * such initialization to usbNC1080DevInit(). This routine handles the other part
  1296. * of the driver initialization as required by MUX.
  1297. *
  1298. * muxDevLoad calls this function twice. First time this function is called,
  1299. * initialization string will be NULL . We are required to fill in the device
  1300. * name ("usbNC1080") in the string and return. The next time this function is 
  1301. * called the intilization string will be proper.
  1302. *
  1303. * <initString> will be in the following format :
  1304. * "unit:vendorId:productId:<6bytes of mac address, delimited by :>"
  1305. *
  1306. * PARAMETERS
  1307. *
  1308. *.IP <initString>
  1309. *The device initialization string.
  1310. *
  1311. * RETURNS: An END object pointer or NULL on error.
  1312. */
  1313. END_OBJ * usbNC1080Load
  1314.     (
  1315.     char * initString                            /* initialization string */
  1316.     )
  1317.     {
  1318.     NC1080_END_DEV * pDrvCtrl;                        /* driver structure */
  1319.     UINT16 vendorId;                               /* vendor information */
  1320.     UINT16 productId;                              /* product information */
  1321.     DRV_LOG (DRV_DBG_LOAD, "Loading usbNC1080 ...n", 1, 2, 3, 4, 5, 6);
  1322.     if (initString == NULL)
  1323. return (NULL);
  1324.     if (initString[0] == EOS)
  1325. {
  1326.         /* Fill in the device name and return */
  1327. bcopy ((char *)NETCHIP_NAME, (void *)initString, NETCHIP_NAME_LEN);
  1328. return (0);
  1329. }
  1330.     /* allocate the device structure */
  1331.     pDrvCtrl = (NC1080_END_DEV *)calloc (sizeof (NC1080_END_DEV), 1);
  1332.     if (pDrvCtrl == NULL)
  1333. {
  1334. DRV_LOG (DRV_DBG_LOAD, "No Memory!!...n", 1, 2, 3, 4, 5, 6);
  1335. goto errorExit;
  1336. }
  1337.     /* parse the init string, filling in the device structure */
  1338.     if (usbNC1080EndParse (pDrvCtrl, initString, &vendorId, &productId) == ERROR)
  1339. {
  1340. DRV_LOG (DRV_DBG_LOAD, "Parse Failed.n", 1, 2, 3, 4, 5, 6);
  1341. goto errorExit;
  1342. }
  1343.     /* Ask the usbNC1080Lib to do the necessary initilization. */
  1344.     if (usbNC1080DevInit(pDrvCtrl,vendorId,productId) == ERROR)
  1345. {
  1346. DRV_LOG (DRV_DBG_LOAD, "EnetDevInitFailed.n",
  1347.     1, 2, 3, 4, 5, 6);
  1348. goto errorExit;
  1349. }
  1350.     /* initialize the END and MIB2 parts of the structure */
  1351.     if (END_OBJ_INIT (&pDrvCtrl->endObj, 
  1352.       (DEV_OBJ *)pDrvCtrl, 
  1353.       "usbNC1080", 
  1354.       pDrvCtrl->unit, 
  1355.       &usbNC1080FuncTable, 
  1356.       "usbNC1080") 
  1357.     == ERROR
  1358.      || END_MIB_INIT (&pDrvCtrl->endObj, 
  1359.       M2_ifType_ethernet_csmacd, 
  1360.       &pDrvCtrl->enetAddr[0], 
  1361.       6, 
  1362.       NETCHIP_BUFSIZ, 
  1363.       NETCHIP_SPEED) 
  1364.      == ERROR)
  1365. {
  1366. DRV_LOG (DRV_DBG_LOAD, "END MACROS FAILED...n",
  1367. 1, 2, 3, 4, 5, 6);
  1368. goto errorExit;
  1369. }
  1370.     /* Perform memory allocation/distribution */
  1371.     if (usbNC1080EndMemInit (pDrvCtrl) == ERROR)
  1372. {
  1373. DRV_LOG (DRV_DBG_LOAD, "endMemInit() Failed...n",
  1374.     1, 2, 3, 4, 5, 6);
  1375. goto errorExit;
  1376. }
  1377.     /* set the flags to indicate readiness */
  1378.     END_OBJ_READY (&pDrvCtrl->endObj,
  1379.     IFF_UP | IFF_RUNNING | IFF_NOTRAILERS );
  1380.     DRV_LOG (DRV_DBG_LOAD, "Done loading Netchip ...n",
  1381. 1, 2, 3, 4, 5, 6);
  1382. pDrvCtrl->pDev->connected = TRUE;
  1383.     return (&pDrvCtrl->endObj);
  1384. errorExit:
  1385.     if (pDrvCtrl != NULL)
  1386. {
  1387. free ((char *)pDrvCtrl);
  1388. }
  1389.     return NULL;
  1390.     }
  1391. /**************************************************************************
  1392. *
  1393. * usbNC1080Unload - unload a driver from the system
  1394. *
  1395. * This function first brings down the device, and then frees any
  1396. * stuff that was allocated by the driver in the load function.
  1397. *
  1398. * RETURNS: OK or ERROR.
  1399. */
  1400. LOCAL STATUS usbNC1080Unload
  1401.     (
  1402.     NC1080_END_DEV * pDrvCtrl /* device to be unloaded */
  1403.     )
  1404.     {
  1405.     DRV_LOG (DRV_DBG_UNLOAD, "In netchipUnload... n",
  1406.          0, 0, 0, 0, 0, 0);
  1407.     END_OBJECT_UNLOAD (&pDrvCtrl->endObj);
  1408.     usbNC1080DestroyDevice (pDrvCtrl);
  1409.     DRV_LOG(DRV_DBG_UNLOAD,"netchipdestroy device ..donen" 
  1410. , 0, 0, 0, 0, 0, 0);
  1411.     netPoolDelete (pDrvCtrl->endObj.pNetPool);
  1412. DRV_LOG(DRV_DBG_UNLOAD,"netpoolDelete ..donen" 
  1413. , 0, 0, 0, 0, 0, 0);
  1414.     free(pDrvCtrl);
  1415. DRV_LOG(DRV_DBG_UNLOAD,"pDrvCtrl free...donen" 
  1416. , 0, 0, 0, 0, 0, 0);
  1417.     return (OK);
  1418.     }
  1419. /**************************************************************************
  1420. *
  1421. * usbNC1080Start - start the device
  1422. *
  1423. * This function just starts communication with the device.
  1424. *
  1425. * RETURNS: OK or ERROR
  1426. *
  1427. */
  1428. STATUS usbNC1080Start
  1429.     (
  1430.     NC1080_END_DEV  * pDrvCtrl /* device ID */
  1431.     )
  1432.     {
  1433.     UINT16 status;
  1434.     int temp;
  1435.     /* Check if the other side is connected, FIXME */
  1436.     if (usbNC1080ReadRegister(pDrvCtrl, NETCHIP_STATUS, &status) != OK)
  1437.         {
  1438.         DRV_LOG (DRV_DBG_START, "usbNC1080Start: Failed to read status",
  1439.                 0, 0, 0, 0, 0, 0);
  1440.         return ERROR;
  1441.         }
  1442.     if (!(status & 0x4000))
  1443.         {
  1444.         DRV_LOG (DRV_DBG_START, "usbNC1080Start: Peer not connected",
  1445.                 0, 0, 0, 0, 0, 0);
  1446.         temp = usbNC1080Debug;
  1447.         usbNC1080Debug |= DRV_DBG_REGISTER;
  1448.         usbNC1080ShowStatus(status);
  1449.         usbNC1080Debug = temp;
  1450.         return ERROR;
  1451.         }
  1452.     /*
  1453.      * Listem for any ethernet packet coming in.
  1454.      * This is just simulating "connecting the interrupt" in End Model.
  1455.      */
  1456.      if (usbNC1080ListenForInput (pDrvCtrl) != OK)
  1457. {
  1458.         DRV_LOG (DRV_DBG_START, "usbNC1080Start: Failedn",0, 0, 0, 0, 0, 0);
  1459. return ERROR;
  1460. }
  1461.     return OK;
  1462.     }
  1463. /**************************************************************************
  1464. *
  1465. * usbNC1080Stop - stop the device
  1466. *
  1467. * This function stops communication with the device.
  1468. *
  1469. * RETURNS: OK or ERROR
  1470. *
  1471. */
  1472. STATUS usbNC1080Stop
  1473.     (
  1474.     NC1080_END_DEV * pDrvCtrl /* device ID */
  1475.     )
  1476.     {
  1477.     /* Abort any pending transfers */
  1478.     DRV_LOG(DRV_DBG_UNLOAD,"In usbNC1080Stop..n",
  1479. 0, 0, 0, 0, 0, 0);
  1480.     pDrvCtrl->pDev->connected = FALSE;
  1481.     usbNC1080DestroyDevice(pDrvCtrl);
  1482.     taskDelay(sysClkRateGet()*5);
  1483.     return OK;
  1484.     }
  1485. /************************************************************************
  1486. * usbNC1080ListenForInput - Listens for data on the Bulk In Pipe
  1487. *
  1488. * Input IRP will be initialized to listen on the BULK input pipe and will
  1489. * be submitted to the usbd.
  1490. *
  1491. * RETURNS : OK or ERROR
  1492. *
  1493. * NOMANUAL
  1494. */
  1495. LOCAL STATUS usbNC1080ListenForInput
  1496.     (
  1497.     NC1080_END_DEV * pDrvCtrl /* device to receive from */
  1498.     )
  1499.     {
  1500.     pUSB_IRP pIrp = &pDrvCtrl->inIrp;
  1501.     if (pDrvCtrl == NULL)
  1502. return ERROR;
  1503.     /* Initialize IRP */
  1504.     memset (pIrp, 0, sizeof (*pIrp));
  1505.     pIrp->userPtr = pDrvCtrl;
  1506.     pIrp->irpLen = sizeof (*pIrp);
  1507.     pIrp->userCallback = usbNC1080RxCallback;
  1508.     pIrp->timeout = USB_TIMEOUT_DEFAULT;
  1509.     pIrp->transferLen = NETCHIP_IN_BFR_SIZE; /* for the max pkt size */
  1510.     pIrp->flags = USB_FLAG_SHORT_OK;
  1511.     pIrp->bfrCount = 1;
  1512.     pIrp->bfrList[0].pid = USB_PID_IN;
  1513.     pIrp->bfrList[0].bfrLen = NETCHIP_IN_BFR_SIZE;
  1514.     pIrp->bfrList[0].pBfr = (pUINT8)pDrvCtrl->pInBfrArray[pDrvCtrl->rxBufIndex];
  1515. /* for dynamic memory allocation */
  1516.     /* Submit IRP */
  1517.     if (usbdTransfer (usbNC1080Handle, pDrvCtrl->inPipeHandle, pIrp) != OK)
  1518. return ERROR;
  1519.     pDrvCtrl->inIrpInUse = TRUE;
  1520.     return OK;
  1521.     }
  1522. /**************************************************************************
  1523. *
  1524. * usbNC1080RxCallback - Invoked when a Packet is received.
  1525. *
  1526. * NOMANUAL
  1527. */
  1528. LOCAL VOID usbNC1080RxCallback
  1529.     (
  1530.     pVOID p /* completed IRP */
  1531.     )
  1532.     {
  1533.     pUSB_IRP pIrp = (pUSB_IRP) p;
  1534.     NC1080_END_DEV * pDrvCtrl = pIrp->userPtr;
  1535.     /* Input IRP completed */
  1536.     pDrvCtrl->inIrpInUse = FALSE;
  1537.     /*
  1538.      * If the IRP was successful then pass the data back to the client.
  1539.      */
  1540.     if (pIrp->result != OK)
  1541. {
  1542.         pDrvCtrl->inErrors++; /* FIXME : Should also update MIB */
  1543. if(pIrp->result == S_usbHcdLib_STALLED)
  1544.     {
  1545.             DRV_LOG (DRV_DBG_RX, "BULK_IN End point stalled",
  1546.                 0, 0, 0, 0, 0, 0);
  1547.     usbdFeatureClear (usbNC1080Handle,
  1548.       pDrvCtrl->pDev->nodeId, 
  1549.       USB_RT_STANDARD | USB_RT_ENDPOINT, 
  1550.       0, 
  1551.       0);
  1552.     }
  1553. }
  1554.     else
  1555. {
  1556. if( pIrp->bfrList[0].actLen >= 2)
  1557.     {
  1558.     PKT_PRINT(0x2,pIrp->bfrList[0].pBfr,pIrp->bfrList[0].actLen);
  1559.        usbNC1080Recv (pDrvCtrl,pIrp->bfrList[0].pBfr, pIrp->bfrList[0].actLen);
  1560.     pDrvCtrl->rxBufIndex++;
  1561.     pDrvCtrl->rxBufIndex %= NETCHIP_NUM_IN_BFRS;
  1562.     }
  1563. }
  1564.     /*
  1565.      * Unless the IRP was cancelled - implying the channel is being
  1566.      * torn down, re-initiate the "in" IRP to listen for more data from
  1567.      * the device.
  1568.      */
  1569.     if (pIrp->result != S_usbHcdLib_IRP_CANCELED)
  1570. usbNC1080ListenForInput (pDrvCtrl);
  1571.     }
  1572. /**************************************************************************
  1573. *
  1574. * usbNC1080Recv - process the incoming packet
  1575. *
  1576. * usbNC1080Recv is called by the usbNC1080RxCallBack() upon successful execution
  1577. * of an input IRP. This means we got some proper data. This function will be
  1578. * called with the pointer to be buffer and the length of data.
  1579. * What we do here is to construct an MBlk strcuture with the data received
  1580. * and pass it onto the upper layer.
  1581. *
  1582. * RETURNS: N/A.
  1583. * NOMANUAL
  1584. */
  1585. LOCAL STATUS usbNC1080Recv
  1586.     (
  1587.     NC1080_END_DEV * pDrvCtrl, /* device structure */
  1588.     UINT8 *  pBuf,              /* pointer to data buffer */
  1589.     UINT16  len                 /* length of data */
  1590.     )
  1591.     {
  1592.     char *      pNewCluster;    /* Clsuter to store the data */
  1593.     CL_BLK_ID pClBlk;         /* Control block to "control" the cluster */
  1594.     M_BLK_ID  pMblk;          /* and an MBlk to complete a MBlk contruct */
  1595.     NC_HEADER * pHeader;        /* usbNC1080 Protocol */
  1596.     /* Add one to our unicast data. */
  1597.     END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, +1);
  1598.     /* NC1080 Protocol verifications */
  1599.     pHeader = (NC_HEADER *) pBuf;
  1600.     if (pHeader->hdr_len < NETCHIP_MIN_HEADER)
  1601.         {
  1602.         DRV_LOG (DRV_DBG_RX, "Rx : Header Length mismatch! Actual : %d n",
  1603.     pHeader->hdr_len, 2, 3, 4, 5, 6);
  1604.         return ERROR;
  1605.         }
  1606.     if (pHeader->hdr_len != sizeof (NC_HEADER))
  1607.         {
  1608.         DRV_LOG (DRV_DBG_RX, "Rx : Out of Band Header : %d bytesn",
  1609.     pHeader->hdr_len, 2, 3, 4, 5, 6);
  1610.         }
  1611.      /* All protocol checks complete */
  1612.     pNewCluster = netClusterGet (pDrvCtrl->endObj.pNetPool, pDrvCtrl->pClPoolId);
  1613.     if (pNewCluster == NULL)
  1614.         {
  1615. DRV_LOG (DRV_DBG_RX, "Recv: Cannot loan!n", 1, 2, 3, 4, 5, 6);
  1616. END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);
  1617. goto cleanRXD;
  1618.         }
  1619.     memcpy( pNewCluster, pBuf + pHeader->hdr_len, pHeader->packet_len);
  1620. /* pNewCluster = pBuf + pHeader->hdr_len; */
  1621.     /* Grab a cluster block to marry to the cluster we received. */
  1622.     if ((pClBlk = netClBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT)) == NULL)
  1623.         {
  1624.         netClFree (pDrvCtrl->endObj.pNetPool, (UCHAR *)pNewCluster);
  1625. DRV_LOG (DRV_DBG_RX, "Out of Cluster Blocks!n",
  1626.     1, 2, 3, 4, 5, 6);
  1627. END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);
  1628. goto cleanRXD;
  1629.         }
  1630.     /*
  1631.      * Let's get an M_BLK_ID and marry it to the one in the ring.
  1632.      */
  1633.     if ((pMblk = mBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT, MT_DATA))
  1634. == NULL)
  1635.         {
  1636.         netClBlkFree (pDrvCtrl->endObj.pNetPool, pClBlk);
  1637. netClFree (pDrvCtrl->endObj.pNetPool, (UCHAR *)pNewCluster);
  1638. DRV_LOG (DRV_DBG_RX, "Out of M Blocks!n",
  1639.     1, 2, 3, 4, 5, 6);
  1640. END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);
  1641. goto cleanRXD;
  1642.         }
  1643.     END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, +1);
  1644.     /* Join the cluster to the MBlock */
  1645.     netClBlkJoin (pClBlk, pNewCluster, pHeader->packet_len, NULL, 0, 0, 0);
  1646.     netMblkClJoin (pMblk, pClBlk);
  1647.     pMblk->mBlkHdr.mLen = pHeader->packet_len;
  1648.     pMblk->mBlkHdr.mFlags |= M_PKTHDR;
  1649.     pMblk->mBlkPktHdr.len = pHeader->packet_len;
  1650.     /* Call the upper layer's receive routine. */
  1651.     END_RCV_RTN_CALL(&pDrvCtrl->endObj, pMblk);
  1652.     cleanRXD:
  1653.     return OK;
  1654.     }
  1655. /**************************************************************************
  1656. *
  1657. * usbNC1080Send - the driver send routine
  1658. *
  1659. * This routine takes a M_BLK_ID sends off the data in the M_BLK_ID. We copy
  1660. * the data contained in the MBlks to a character buffer, forms an IRP and
  1661. * transmits the data.
  1662. * We put the usbNC1080 turboconnect protocol information in the buffer here.
  1663. * The data copied from MBlks, must already have the addressing information
  1664. * properly installed in it.  This is done by a higher layer.
  1665. *
  1666. *
  1667. * RETURNS: OK or ERROR.
  1668. */
  1669. LOCAL STATUS usbNC1080Send
  1670.     (
  1671.     NC1080_END_DEV * pDrvCtrl, /* device ptr */
  1672.     M_BLK_ID      pMblk /* data to send */
  1673.     )
  1674.     {
  1675.     UINT8 *     pBuf;  /* buffer to hold the data */
  1676.     UINT32 noOfBytes; /* noOfBytes to be transmitted */
  1677.     NC_HEADER * pHeader;        /* protcol header */
  1678.     NC_FOOTER * pFooter;        /* protocol footer */
  1679.     int         len;            /* length of packet */
  1680.     pUSB_IRP pIrp = &pDrvCtrl->outIrp;
  1681.     if ((pDrvCtrl == NULL) || (pMblk == NULL))
  1682. return ERROR;
  1683.     OSS_MUTEX_TAKE (usbNC1080TxMutex, OSS_BLOCK);
  1684.     DRV_LOG (DRV_DBG_TX, "usbNC1080Send: Entered.n", 0, 0, 0, 0, 0, 0);
  1685. pBuf =  pDrvCtrl->pOutBfrArray[pDrvCtrl->txBufIndex];
  1686.     pDrvCtrl->txBufIndex++;
  1687.     pDrvCtrl->txBufIndex %= NETCHIP_NUM_OUT_BFRS;
  1688.     /* copy the MBlk chain to a buffer */
  1689.     noOfBytes = netMblkToBufCopy (pMblk, (char *)pBuf + sizeof(NC_HEADER),NULL);
  1690.     if (noOfBytes == 0)
  1691. return ERROR;
  1692.     DRV_LOG (DRV_DBG_TX, "usbNC1080Send: %d bytes to be sent.n",
  1693. noOfBytes, 0, 0, 0, 0, 0);
  1694.     /* Set the netchip protocol header/footer */
  1695.     pHeader = (NC_HEADER *)pBuf;
  1696.     pHeader->hdr_len = sizeof (NC_HEADER);
  1697.     pHeader->packet_len = noOfBytes;
  1698.     pHeader->packet_id = ++(pDrvCtrl->txPkts);
  1699.     /* Maintain odd length. Pad a byte if necessary */
  1700.     len = noOfBytes + sizeof (NC_HEADER)+ sizeof (NC_FOOTER);
  1701.     if (!(len & 0x01))
  1702.         {
  1703.         *(pBuf + noOfBytes + sizeof (NC_HEADER)) = NETCHIP_PAD_BYTE;
  1704.         pFooter = (NC_FOOTER *)(pBuf + noOfBytes + sizeof (NC_HEADER) + 1);
  1705.         len ++;
  1706.         }
  1707.     else
  1708.         {
  1709.         pFooter = (NC_FOOTER *)(pBuf + noOfBytes + sizeof (NC_HEADER));
  1710.         }
  1711.     pFooter->packet_id = pDrvCtrl->txPkts;
  1712.     PKT_PRINT(PKT_DBG_TX,pBuf,len);
  1713.     /* Transmit data */
  1714.     pDrvCtrl->outIrpInUse = TRUE;
  1715.     /* Initialize IRP */
  1716.     memset (pIrp, 0, sizeof (*pIrp));
  1717.     pIrp->userPtr = pDrvCtrl;
  1718.     pIrp->irpLen = sizeof (*pIrp);
  1719.     pIrp->userCallback = usbNC1080TxCallback;
  1720.     pIrp->timeout = 2000;
  1721.     pIrp->transferLen = len;
  1722.     pIrp->bfrCount = 1;
  1723.     pIrp->bfrList [0].pid = USB_PID_OUT;
  1724.     pIrp->bfrList [0].pBfr = pBuf;
  1725.     pIrp->bfrList [0].bfrLen = len;
  1726.     /* Submit IRP */
  1727.     if (usbdTransfer (usbNC1080Handle, pDrvCtrl->outPipeHandle, pIrp) != OK)
  1728. return ERROR;
  1729.     DRV_LOG (DRV_DBG_TX, "usbNC1080Send: Pkt submitted for tx.n",
  1730. 0, 0, 0, 0, 0, 0);
  1731.     /* Wait for IRP to complete or cancel by timeout */
  1732.     if (OSS_SEM_TAKE (usbNC1080IrpSem, 2000 + 1000) == ERROR )
  1733.         {
  1734.         DRV_LOG (DRV_DBG_TX, "usbNC1080Send: Fatal error. "
  1735.                 "pId : %x  len : %x n",
  1736. pHeader->packet_id, len, 0, 0, 0, 0);
  1737.         OSS_SEM_GIVE (usbNC1080IrpSem);
  1738.         }
  1739.     else
  1740.         {
  1741.         DRV_LOG (DRV_DBG_TX, "usbNC1080Send: Tx Successful!!. "
  1742.                 "pId : %x  len : %d n",
  1743. pHeader->packet_id, len, 0, 0, 0, 0);
  1744.         }
  1745.     OSS_MUTEX_RELEASE (usbNC1080TxMutex);
  1746.     /* Bump the statistic counter. */
  1747.     END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_UCAST, +1);
  1748.     /* Cleanup.  The driver frees the packet now. */
  1749.     netMblkClChainFree (pMblk);
  1750.     return (OK);
  1751.     }
  1752. /**************************************************************************
  1753. *
  1754. * usbNC1080TxCallback - Invoked upon Transmit IRP completion/cancellation
  1755. *
  1756. * NOMANUAL
  1757. */
  1758. LOCAL VOID usbNC1080TxCallback
  1759.     (
  1760.     pVOID p /* completed IRP */
  1761.     )
  1762.     {
  1763.     pUSB_IRP pIrp = (pUSB_IRP) p;
  1764.     NC1080_END_DEV * pDrvCtrl = pIrp->userPtr;
  1765.     /* Output IRP completed */
  1766.     pDrvCtrl->outIrpInUse = FALSE;
  1767.     DRV_LOG (DRV_DBG_TX, "Tx Callback n", 0, 0, 0, 0, 0, 0);
  1768.     if (pIrp->result != OK)
  1769. {
  1770.         DRV_LOG (DRV_DBG_TX, "Tx error %x.n",pIrp->result, 0, 0, 0, 0, 0);
  1771. if (pIrp->result == S_usbHcdLib_STALLED)
  1772.     {
  1773.        if (usbdFeatureClear (usbNC1080Handle, 
  1774.   pDrvCtrl->pDev->nodeId, 
  1775.   USB_RT_STANDARD | USB_RT_ENDPOINT, 
  1776.   0, 
  1777.   1) 
  1778.       == ERROR)
  1779. {
  1780.         DRV_LOG (DRV_DBG_TX, "Could not clear STALL.n",
  1781.      pIrp->result, 0, 0, 0, 0, 0);
  1782. }
  1783.     }
  1784.         pDrvCtrl->outErrors++; /* Should also Update MIB */
  1785. }
  1786.     /* Release the sync semaphore */
  1787.     OSS_SEM_GIVE (usbNC1080IrpSem);
  1788.     }
  1789. /**************************************************************************
  1790. *
  1791. * usbNC1080MCastAdd - add a multicast address for the device
  1792. *
  1793. * This function is not supported.
  1794. * RETURNS: ERROR 
  1795. */
  1796. LOCAL STATUS usbNC1080MCastAdd
  1797.     (
  1798.     NC1080_END_DEV * pDrvCtrl, /* device pointer */
  1799.     char* pAddress /* new address to add */
  1800.     )
  1801.     {
  1802.     return (ERROR);
  1803.     }
  1804. /**************************************************************************
  1805. *
  1806. * usbNC1080MCastDel - delete a multicast address for the device
  1807. *
  1808. * This function is not supported.
  1809. * RETURNS: ERROR.
  1810. */
  1811. LOCAL STATUS usbNC1080MCastDel
  1812.     (
  1813.     NC1080_END_DEV * pDrvCtrl, /* device pointer */
  1814.     char* pAddress /* new address to add */
  1815.     )
  1816.     {
  1817.     return (ERROR);
  1818.     }
  1819. /**************************************************************************
  1820. *
  1821. * usbNC1080MCastGet - get the multicast address list for the device
  1822. *
  1823. * This routine is not supported.
  1824. * RETURNS: ERROR.
  1825. */
  1826. LOCAL STATUS usbNC1080MCastGet
  1827.     (
  1828.     NC1080_END_DEV * pDrvCtrl, /* device pointer */
  1829.     MULTI_TABLE * pTable /* address table to be filled in */
  1830.     )
  1831.     {
  1832.     return (ERROR);
  1833.     }
  1834. /**************************************************************************
  1835. *
  1836. * usbNC1080Ioctl - the driver I/O control routine
  1837. *
  1838. * Process an ioctl request.
  1839. *
  1840. * RETURNS: A command specific response, usually OK or ERROR.
  1841. */
  1842. LOCAL int usbNC1080Ioctl
  1843.     (
  1844.     NC1080_END_DEV * pDrvCtrl, /* device receiving command */
  1845.     int cmd, /* ioctl command code */
  1846.     caddr_t data /* command argument */
  1847.     )
  1848.     {
  1849.     int error = 0;
  1850.     long value;
  1851.     switch (cmd)
  1852.         {
  1853.         case EIOCSADDR : /* Set Device Address */
  1854.     return ERROR;
  1855.         case EIOCGADDR : /* Get Device Address */
  1856.     if (data == NULL)
  1857. return (EINVAL);
  1858.             bcopy ((char *)NETCHIP_HADDR (&pDrvCtrl->endObj), 
  1859.    (char *)data, 
  1860.    NETCHIP_HADDR_LEN (&pDrvCtrl->endObj));
  1861.             break;
  1862.         case EIOCSFLAGS : /* Set Device Flags */
  1863.     
  1864.     value = (long)data;
  1865.     if (value < 0)
  1866.         {
  1867. value = -(--value);
  1868. END_FLAGS_CLR (&pDrvCtrl->endObj, value);
  1869. }
  1870.     else
  1871. {
  1872. END_FLAGS_SET (&pDrvCtrl->endObj, value);
  1873. }
  1874.             break;
  1875.         case EIOCGFLAGS: /* Get Device Flags */
  1876.     *(int *)data = END_FLAGS_GET(&pDrvCtrl->endObj);
  1877.     
  1878.             break;
  1879. case EIOCPOLLSTART : /* Begin polled operation */
  1880.     return EINVAL; /* Not supported */
  1881. case EIOCPOLLSTOP : /* End polled operation */
  1882.     return EINVAL; /* Not supported */
  1883.         case EIOCGMIB2 : /* return MIB information */
  1884.             if (data == NULL)
  1885.                 return (EINVAL);
  1886.             bcopy ((char *)&pDrvCtrl->endObj.mib2Tbl, 
  1887.    (char *)data,
  1888.                    sizeof(pDrvCtrl->endObj.mib2Tbl));
  1889.             break;
  1890.         case EIOCGFBUF : /* return minimum First Buffer for chaining */
  1891.             if (data == NULL)
  1892.                 return (EINVAL);
  1893.             *(int *)data = NETCHIP_MIN_FBUF;
  1894.             break;
  1895. case EIOCMULTIADD :  /* Add a Multicast Address */
  1896.     return EINVAL; /* Not supported */
  1897. case EIOCMULTIDEL :  /* Delete a Multicast Address */
  1898.     return EINVAL; /* Not supported */
  1899.     break;
  1900. case EIOCMULTIGET :  /* Get the Multicast List */
  1901.     return EINVAL; /* Not supported */
  1902.     break;
  1903.        default:
  1904.             error = EINVAL;
  1905.         }
  1906.     return (error);
  1907.     }
  1908. /**************************************************************************
  1909. *
  1910. * usbNC1080PollRcv - routine to receive a packet in polled mode.
  1911. *
  1912. * This routine is NOT supported
  1913. *
  1914. * RETURNS: ERROR Always
  1915. */
  1916. LOCAL STATUS usbNC1080PollRcv
  1917.     (
  1918.     NC1080_END_DEV * pDrvCtrl, /* device to be polled */
  1919.     M_BLK_ID      pMblk /* ptr to buffer */
  1920.     )
  1921.     {
  1922.     return (ERROR);
  1923.     }
  1924. /**************************************************************************
  1925. *
  1926. * usbNC1080PollSend - routine to send a packet in polled mode.
  1927. *
  1928. * This routine is NOT SUPPORTED
  1929. *
  1930. * RETURNS: ERROR always
  1931. */
  1932. LOCAL STATUS usbNC1080PollSend
  1933.     (
  1934.     NC1080_END_DEV *  pDrvCtrl, /* device to be polled */
  1935.     M_BLK_ID     pMblk /* packet to send */
  1936.     )
  1937.     {
  1938.     return (ERROR);
  1939.     }
  1940. /***************************************************************************
  1941. *
  1942. * notifyAttach - Notifies registered callers of attachment/removal
  1943. *
  1944. * RETURNS: N/A
  1945. */
  1946. LOCAL VOID notifyAttach
  1947.     (
  1948.     USB_NC1080_DEV* pDev,
  1949.     UINT16 attachCode
  1950.     )
  1951.     {
  1952.     pATTACH_REQUEST pRequest = usbListFirst (&reqList);
  1953.     DRV_LOG (DRV_DBG_ATTACH, "We are in notify attachn",
  1954.      0, 0, 0, 0, 0, 0);
  1955.     while (pRequest != NULL)
  1956.     {
  1957.     (*pRequest->callback) (pRequest->callbackArg, 
  1958.                    pDev, attachCode);
  1959.     pRequest = usbListNext (&pRequest->reqLink);
  1960.     DRV_LOG (DRV_DBG_ATTACH, "Attach call back executedn",
  1961.      0, 0, 0, 0, 0, 0);
  1962.     }
  1963.     }
  1964. /***************************************************************************
  1965. *
  1966. * usbNC1080DynamicAttachRegister - Register NETCHIP device attach callback.
  1967. *
  1968. * <callback> is a caller-supplied function of the form:
  1969. *
  1970. * .CS
  1971. * typedef (*USB_NETCHIP_ATTACH_CALLBACK) 
  1972. *     (
  1973. *     pVOID arg,
  1974. *     USB_NC1080_DEV * pDev,
  1975. *     UINT16 attachCode
  1976. *     );
  1977. * .CE
  1978. *
  1979. * usbNC1080End will invoke <callback> each time a NETCHIP device
  1980. * is attached to or removed from the system.  <arg> is a caller-defined
  1981. * parameter which will be passed to the <callback> each time it is
  1982. * invoked.  The <callback> will also be passed the nodeID of the device 
  1983. * being created/destroyed and an attach code of USB_NETCHIP_ATTACH or 
  1984. * USB_NETCHIP_REMOVE.
  1985. *
  1986. * NOTE: The user callback routine should not invoke any driver function that
  1987. * submits IRPs.  Further processing must be done from a different task context.
  1988. * As the driver routines wait for IRP completion, they cannot be invoked from
  1989. * USBD client task's context created for this driver.
  1990. *
  1991. *
  1992. * RETURNS: OK, or ERROR if unable to register callback
  1993. *
  1994. * ERRNO:
  1995. *   S_usbNC1080Lib_BAD_PARAM
  1996. *   S_usbNC1080Lib_OUT_OF_MEMORY
  1997. */
  1998. STATUS usbNC1080DynamicAttachRegister
  1999.     (
  2000.     USB_NETCHIP_ATTACH_CALLBACK callback, /* new callback to be registered */
  2001.     pVOID arg /* user-defined arg to callback */
  2002.     )
  2003.     {
  2004.     pATTACH_REQUEST   pRequest;
  2005.     USB_NC1080_DEV  *       pNC1080Dev;
  2006.     int status = OK;
  2007.     /* Validate parameters */
  2008.     if (callback == NULL)
  2009.         return (ossStatus (S_usbNC1080Lib_BAD_PARAM));
  2010.     OSS_MUTEX_TAKE (usbNC1080Mutex, OSS_BLOCK);
  2011.     /* Create a new request structure to track this callback request. */
  2012.     if ((pRequest = OSS_CALLOC (sizeof (*pRequest))) == NULL)
  2013.         {
  2014.         status = ossStatus (S_usbNC1080Lib_OUT_OF_MEMORY);
  2015.         }
  2016.     else
  2017.         {
  2018.         pRequest->callback    = callback;
  2019.         pRequest->callbackArg = arg;
  2020.         usbListLink (&reqList, pRequest, &pRequest->reqLink, LINK_TAIL);
  2021.     
  2022.        /* 
  2023.         * Perform an initial notification of all currrently attached
  2024.         * NETCHIP devices.
  2025.         */
  2026.         pNC1080Dev = usbListFirst (&usbNC1080DevList);
  2027.         while (pNC1080Dev != NULL)
  2028.     {
  2029.             if (pNC1080Dev->connected)
  2030.                 (*callback) (arg, pNC1080Dev, USB_NETCHIP_ATTACH);
  2031.     pNC1080Dev = usbListNext (&pNC1080Dev->devLink);
  2032.     }
  2033.         }
  2034.     OSS_MUTEX_RELEASE (usbNC1080Mutex);
  2035.     return (ossStatus (status));
  2036.     }
  2037. /***************************************************************************
  2038. *
  2039. * usbNC1080DynamicAttachUnregister - Unregisters NETCHIP attach callback.
  2040. *
  2041. * This function cancels a previous request to be dynamically notified for
  2042. * NETCHIP device attachment and removal.  The <callback> and <arg> paramters 
  2043. * must exactly match those passed in a previous call to 
  2044. * usbNC1080DynamicAttachRegister().
  2045. *
  2046. * RETURNS: OK, or ERROR if unable to unregister callback
  2047. *
  2048. * ERRNO:
  2049. *   S_usbNC1080Lib_NOT_REGISTERED
  2050. */
  2051. STATUS usbNC1080DynamicAttachUnregister
  2052.     (
  2053.     USB_NETCHIP_ATTACH_CALLBACK callback, /* callback to be unregistered */
  2054.     pVOID arg   /* user-defined arg to callback */
  2055.     )
  2056.     {
  2057.     pATTACH_REQUEST pRequest;
  2058.     int status = S_usbNC1080Lib_NOT_REGISTERED;
  2059.     OSS_MUTEX_TAKE (usbNC1080Mutex, OSS_BLOCK);
  2060.     pRequest = usbListFirst (&reqList);
  2061.     while (pRequest != NULL)
  2062.         {
  2063.         if ((callback == pRequest->callback) && (arg == pRequest->callbackArg))
  2064.     {
  2065.     /* We found a matching notification request. */
  2066.     usbListUnlink (&pRequest->reqLink);
  2067.         /* Dispose of structure */
  2068.         OSS_FREE (pRequest);
  2069.     status = OK;
  2070.     break;
  2071.     }
  2072.         pRequest = usbListNext (&pRequest->reqLink);
  2073. }
  2074.     OSS_MUTEX_RELEASE (usbNC1080Mutex);
  2075.     return (ossStatus (status));
  2076.     }
  2077. /***************************************************************************
  2078. *
  2079. * usbNC1080DevLock - Marks USB_NC1080_DEV structure as in use.
  2080. *
  2081. * A caller uses usbNC1080DevLock() to notify usbNC1080End that
  2082. * it is using the indicated USB_NC1080_DEV structure.  usbNC1080End maintains
  2083. * a count of callers using a particular USB_NC1080_DEV structure so that it 
  2084. * knows when it is safe to dispose of a structure when the underlying
  2085. * USB_NC1080_DEV is removed from the system.  So long as the "lock count"
  2086. * is greater than zero, usbNC1080End will not dispose of an USB_NC1080_DEV
  2087. * structure.
  2088. *
  2089. * RETURNS: OK, or ERROR if unable to mark USB_NC1080_DEV structure in use.
  2090. */
  2091. STATUS usbNC1080DevLock
  2092.     (
  2093.     USBD_NODE_ID nodeId    /* NodeId of the USB_NC1080_DEV to be marked as in use */
  2094.     )
  2095.     {
  2096.     USB_NC1080_DEV* pNC1080Dev = usbNC1080FindUsbNode (nodeId);
  2097.     if ( pNC1080Dev == NULL)
  2098.         return (ERROR);
  2099.     pNC1080Dev->lockCount++;
  2100.     return (OK);
  2101.     }
  2102.  
  2103. /***************************************************************************
  2104. *
  2105. * usbNC1080DevUnlock - Marks USB_NC1080_DEV structure as unused.
  2106. *
  2107. * This function releases a lock placed on an USB_NC1080_DEV structure.  When a
  2108. * caller no longer needs an USB_NC1080_DEV structure for which it has previously
  2109. * called usbNC1080DevLock(), then it should call this function to
  2110. * release the lock.
  2111. *
  2112. * RETURNS: OK, or ERROR if unable to mark USB_NC1080_DEV structure unused
  2113. *
  2114. * ERRNO:
  2115. *   S_usbNC1080Lib_NOT_LOCKED
  2116. */
  2117. STATUS usbNC1080DevUnlock
  2118.     (
  2119.     USBD_NODE_ID nodeId    /* NodeId of the BLK_DEV to be marked as unused */
  2120.     )
  2121.     {
  2122.     int status = OK;
  2123.     USB_NC1080_DEV *      pNC1080Dev =  usbNC1080FindUsbNode (nodeId);
  2124.  
  2125.     if ( pNC1080Dev == NULL)
  2126.         return (ERROR);
  2127.     OSS_MUTEX_TAKE (usbNC1080Mutex, OSS_BLOCK);
  2128.     if (pNC1080Dev->lockCount == 0)
  2129.         {
  2130.         status = S_usbNC1080Lib_NOT_LOCKED;
  2131.         }
  2132.     else
  2133.      {
  2134.      /* 
  2135.       * If this is the last lock and the underlying NETCHIP device is
  2136.       * no longer connected, then dispose of the device.
  2137.       */
  2138.       if ((--pNC1080Dev->lockCount == 0) && (!pNC1080Dev->connected))
  2139.    usbNC1080DestroyDevice ((NC1080_END_DEV *)pNC1080Dev->pDevStructure);
  2140.      }
  2141.     OSS_MUTEX_RELEASE (usbNC1080Mutex);
  2142.     return (ossStatus (status));
  2143.     }