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

VxWorks

开发平台:

C/C++

  1. /* usbKlsiEnd.c - USB Ethernet driver for the KLSI USB-Ethernet adapter */
  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,01aug31,wef  fixed man page generation comments
  10. 01d,03may01,wef  moved ATTACH_CALLBACK typedef to this file from .h 
  11. 01c,30apr01,wef  changed USB_DEV to USB_KLSI_DEV
  12. 01b,11aug00,bri  Dynamic memory allocation for input and output buffers 
  13.  and removal of wrappers for klsiEndStart and klsiEndStop.
  14. 01a,03may00,bri  Created
  15. */
  16. /*
  17. DESCRIPTION
  18.  
  19. This module is the END (Enhanced Network Driver) driver for USB-ethernet 
  20. adapters built around the Kawasaki-LSI KL5KUSB101 chip for the VxWorks 
  21. operating system. This device falls under subclass Ethernet Networking 
  22. Control Model (Clause 3.8.2) of USB Class Definition for Communication 
  23. Devices (Ver1.1). 
  24. This driver is designed to be moderately generic for all KLSI devices. 
  25. To achieve this, the driver load routine requires an input string consisting 
  26. of some target-specific values. These are described below.
  27. As this adapter deviates from the standard specification in some respects, 
  28. it calls for addition of certain extensions which are required to fulfill 
  29. the requirements of the hot-plugging USB environment. 
  30. EXTERNAL INTERFACE
  31. There are only two external interfaces usbKlsiEndInit() and klsiEndLoad() 
  32. in this driver.  usbKlsiEndInit() is called before the muxLoad() calls 
  33. sysEndLoad(), to register with USBD. sysEndLoad() function calls klsiEndLoad().  
  34. klsiEndLoad() function expects a <initString> parameter as input which 
  35. describes some target specific parameters.  
  36. This parameter is passed in a colon-delimited string of the format:
  37. <initString>
  38. "unit : vendorId : productId : noOfInBfrs : noOfIrps"
  39. The klsiEndLoad() function uses strtok() to parse the string. 
  40. TARGET-SPECIFIC PARAMETERS
  41. is
  42.  i <unit>
  43. A convenient holdover from the former model. This parameter is used only 
  44. in the string as name of the driver
  45.  i <vendorId>
  46. This is a vendorId for the target device supplied by the manufacturer.
  47.  i <productId>
  48. This is a productId for the target device supplied by the manufacturer.  
  49.  i <noOfInBfrs>
  50. Tells the driver no of input buffers to be allocated for usage.
  51.  i <noOfIrps>
  52. Tells the driver no of output IRPs to be allocated for usage.
  53. ie
  54.  
  55. DEVICE FUNCTIONALITY
  56.  
  57. The KLSI USB to ethernet adapter chip contains an USB serial interface,
  58. ethernet MAC and embedded microcontroller (called the QT Engine).
  59. The chip must have firmware loaded into it before it can operate.
  60. The KLSI Chip supports 4 End Points. The first is the default end point, 
  61. which is of control type. The Second and the Third are BULK IN and BULK OUT 
  62. end points respectively for transferring the data into the Host and from the 
  63. Host. The Fourth End Point is an Interrupt end point that is currently not used.
  64. This device supports one configuration, which contains One Interface. This 
  65. interface contains the 3 end points i.e. the Bulk IN/OUT and interrupt
  66. end points. Issuing a SET_CONFIGURATION command will cause the MAC to be 
  67. reset.
  68.  
  69. Apart from the traditional commands, the device supports as many as 12 
  70. vendor specific commands. These commands are described in the device manual. 
  71. This device even allows the user to change the contents of the EEPROM. 
  72. Packets are passed between the chip and host via bulk transfers.
  73. There is an interrupt endpoint mentioned in the software spec, however
  74. it is currently unused. This device is 10Mbps half-duplex only, hence
  75. there is no media selection logic. The MAC supports a 128 entry multicast 
  76. filter, though the exact size of the filter can depend on the firmware. 
  77. Curiously, while the software specification describes various ethernet 
  78. statistics counters, this adapter and firmware combination claims not 
  79. to support any statistics counters at all.
  80. The device supports the following (vendor specific )commands :
  81. is 
  82. i USB_REQ_KLSI_ETHDESC_GET Retrieves the Ethernet functional descriptor from 
  83. the device.
  84. i USB_REQ_KLSI_SET_MCAST_FILTER Sets the ethernet device multicast filters as 
  85. specified in the sequential list if 48 bit addresses ethernet multicast
  86. addresses.
  87. i USB_REQ_KLSI_SET_PACKET_FILTER This Sets the Ethernet packet filter settings.
  88. i USB_REQ_KLSI_GET_STATS Retrieves the device statistics of the feature
  89. requested.
  90. i USB_REQ_KLSI_GET_AUX_INPUTS Reads four auxiliary input pins from the 
  91. USB-Ethernet controller chip.
  92. i USB_REQ_KLSI_SET_AUX_OUTPUTS Sets four auxiliary input pins from the 
  93. USB-Ethernet controller chip.
  94. i USB_REQ_KLSI_SET_TEMP_MAC Obtains the MAC address currently used by the 
  95. ethernet adapter.
  96. i USB_REQ_KLSI_GET_TEMP_MAC Sets the MAC address to be used by the ethernet 
  97. adapter.
  98. i USB_REQ_KLSI_SET_URB_SIZE Sets the USB Request Block size to be used by the 
  99. ethernet adapter.
  100. i USB_REQ_KLSI_SET_SOFS_TO_WAIT Sets the no. of Start of Frames to wait while 
  101. filling a URB before sending a ZLP.
  102. i USB_REQ_KLSI_SET_EVEN_PACKETS Specific to Win95. Not Applicable.
  103. i USB_REQ_KLSI_SCAN Request to modify the I2C EEPROM on the device at a 
  104. specified address.
  105. ie
  106. DRIVER FUNCTIONALITY
  107.  
  108. The function usbKlsiEndInit() is called at the time of usb system 
  109. initialization. It registers as a client with the USBD. This function also
  110. registers for the dynamic attachment and removal of the USB devices.
  111. Ideally the registering should be done for a specific Class ID and a Subclass
  112. ID. Since the device doesn't support these parameters in the Device descriptor, 
  113. ALL kinds of devices are registered for. A list of the ethernet devices on USB 
  114. is maintained in a linked list "klsiDevList". This list is created and 
  115. maintained using the linked list library provided as a part of the USBD. 
  116. API calls are provided to find if the device exists in the list, by taking 
  117. either the device "node ID" or the vendorID and productID as the parameters. 
  118. klsiAttachCallback(), which is the Callback function registered for the 
  119. dynamic attachment/removal, will be called if any device is found on the 
  120. USB or removed from the USB. This function checks if this is duplicate 
  121. information, by checking if this device already exists in the List. If not, 
  122. the device descriptor is parsed to obtain the Vendor ID and Product ID. If the
  123. Vendor ID and Product ID match with KLSI IDs, then the device is added to the 
  124. list of ethernet devices found on the USB.
  125. klsiDevInit() does most of the device structure initialization. This routine 
  126. checks if the device corresponding to the VendorID and ProductID match to any 
  127. of the devices in the "List". If matched, a pointer structure on the list will 
  128. be assigned to one of the device structure parameters. Next, InPut and OutPut 
  129. end point details are found by parsing through the configuration descriptor and 
  130. interface descriptor. Once these end point descriptors are found, respective 
  131. input and output Pipes are created and assigned to the corresponding structure. 
  132. At this moment device is triggered to reset.
  133. This driver is a Polled mode driver. It keeps listening on the input pipe by 
  134. calling "klsiListenToInput" all the time, from the first time it is called 
  135. by klsiEndStart(). Pre allocated buffer IRP is submitted. Unless the IRP is 
  136. cancelled (by klsiEndStop()), it will be submitted again and again.
  137. If cancelled, it will again start listening only if klsiEndStart() is called.
  138. If there is data (IRP successful), then it will be passed on to upper layer by
  139. calling klsiEndRecv().
  140. Rest of the functionality of the driver is straight forward and most of
  141. the places is achieved by sending a vendor specific command from the list
  142. described above, to the device.
  143. INCLUDE FILES:
  144. end.h endLib.h lstLib.h etherMultiLib.h usbPlatform.h usb.h usbListLib.h 
  145. usbdLib.h usbLib.h usbKlsiEnd.h
  146. SEE ALSO:
  147. muxLib, endLib,  usbLib, usbdLib, ossLib 
  148. .I "Writing and Enhanced Network Driver" and
  149. .I "USB Developer's Kit User's Guide"
  150. */
  151. /* includes */
  152. #include "vxWorks.h"
  153. #include "stdlib.h"
  154. #include "stdio.h"
  155. #include "string.h"
  156. #include "cacheLib.h"
  157. #include "intLib.h"
  158. #include "end.h" /* Common END structures. */
  159. #include "endLib.h"
  160. #include "lstLib.h" /* Needed to maintain protocol list */
  161. #include "wdLib.h"
  162. #include "iv.h"
  163. #include "semLib.h"
  164. #include "etherLib.h"
  165. #include "logLib.h"
  166. #include "netLib.h"
  167. #include "stdio.h"
  168. #include "sysLib.h"
  169. #include "errno.h"
  170. #include "errnoLib.h"
  171. #include "memLib.h"
  172. #include "iosLib.h"
  173. #undef ETHER_MAP_IP_MULTICAST
  174. #include "etherMultiLib.h" /* multicast stuff. */
  175. #include "net/mbuf.h"
  176. #include "net/unixLib.h"
  177. #include "net/protosw.h"
  178. #include "net/systm.h"
  179. #include "net/if_subr.h"
  180. #include "net/route.h"
  181. #include "sys/socket.h"
  182. #include "sys/ioctl.h"
  183. #include "sys/times.h"
  184. #include "usb/usbPlatform.h"
  185. #include "usb/ossLib.h"  /* operations system services */
  186. #include "usb/usb.h" /* general USB definitions */
  187. #include "usb/usbListLib.h" /* linked list functions */
  188. #include "usb/usbdLib.h" /* USBD interface */
  189. #include "usb/usbLib.h"  /* USB utility functions */
  190. #include "drv/usb/usbKlsiEnd.h"
  191. /* defines */
  192. /* for debugging */
  193. #define KLSI_DBG
  194. #ifdef KLSI_DBG
  195. #define KLSI_DBG_OFF 0x0000
  196. #define KLSI_DBG_RX 0x0001
  197. #define KLSI_DBG_TX 0x0002
  198. #define KLSI_DBG_MCAST 0x0004
  199. #define KLSI_DBG_ATTACH 0x0008
  200. #define KLSI_DBG_INIT 0x0010
  201. #define KLSI_DBG_START 0x0020
  202. #define KLSI_DBG_STOP 0x0040
  203. #define KLSI_DBG_RESET 0x0080
  204. #define KLSI_DBG_MAC 0x0100
  205. #define KLSI_DBG_POLL_RX 0x0200
  206. #define KLSI_DBG_POLL_TX 0x0400
  207. #define KLSI_DBG_LOAD 0x0800
  208. #define KLSI_DBG_IOCTL 0x1000
  209. #define KLSI_DBG_DNLD 0x2000
  210. int klsiDebug = (0x0000);
  211. #define KLSI_LOG(FLG, X0, X1, X2, X3, X4, X5, X6)    
  212. if (klsiDebug & FLG)                         
  213.             logMsg(X0, X1, X2, X3, X4, X5, X6);
  214. #define KLSI_PRINT(FLG,X)                            
  215. if (klsiDebug & FLG) printf X;
  216. #else /*KLSI_DBG*/
  217. #define KLSI_LOG(FLG, X0, X1, X2, X3, X4, X5, X6)
  218. #define KLSI_PRINT(DBG_SW,X)
  219. #endif /*KLSI_DBG*/
  220. #if (CPU == PPC604)
  221.  #undef CACHE_PIPE_FLUSH()
  222.  #define CACHE_PIPE_FLUSH() vxEieio()
  223. #endif
  224. #define KLSI_FIRMWARE_BUF 4096
  225. #define KLSI_CLIENT_NAME "usb"
  226. #define KLSI_BUFSIZ   (ETHERMTU + ENET_HDR_REAL_SIZ + 6) 
  227. #define EH_SIZE (14)
  228. #define END_SPEED_10M 10000000 /* 10Mbs */
  229. #define KLSI_SPEED    END_SPEED_10M
  230. #define KLSI_NAME "usb"
  231. #define KLSI_NAME_LEN sizeof(KLSI_NAME)+1
  232. /* A shortcut for getting the hardware address from the MIB II stuff. */
  233. #define END_HADDR(pEnd)
  234. ((pEnd)->mib2Tbl.ifPhysAddress.phyAddress)
  235. #define END_HADDR_LEN(pEnd) 
  236. ((pEnd)->mib2Tbl.ifPhysAddress.addrLength)
  237. #define KLSI_MIN_FBUF (1514) /* min first buffer size */
  238. /* typedefs */
  239. /*
  240.  * This will only work if there is only a single unit, for multiple
  241.  * unit device drivers these should be integrated into the KLSI_DEVICE
  242.  * structure.
  243.  */
  244. M_CL_CONFIG klsiMclBlkConfig =  /* network mbuf configuration table */
  245.     {
  246.     /* 
  247.     no. mBlks no. clBlks memArea memSize
  248.     ----------- ---------- ------- -------
  249.     */
  250.     0,  0,  NULL,  0
  251.     };
  252. CL_DESC klsiClDescTbl [] =  /* network cluster pool configuration table */
  253.     {
  254.     /* 
  255.     clusterSize num memArea memSize
  256.     ----------- ---- ------- -------
  257.     */
  258.     {ETHERMTU + EH_SIZE + 2, 0, NULL, 0}
  259.     }; 
  260. int klsiClDescTblNumEnt = (NELEMENTS(klsiClDescTbl));
  261. typedef struct attach_request
  262.     {
  263.     LINK reqLink;                       /* linked list of requests */
  264.     USB_KLSI_ATTACH_CALLBACK callback;  /* client callback routine */
  265.     pVOID callbackArg;                  /* client callback argument*/
  266.     } ATTACH_REQUEST, *pATTACH_REQUEST;
  267. /* globals */
  268. USBD_CLIENT_HANDLE klsiHandle;  /* our USBD client handle */
  269. /* Locals */
  270. /* Firmware Download details */
  271. /*
  272.  * NOTE: B6/C3 is data header signature   
  273.  *       0xAA/0xBB is data length = total 
  274.  *       bytes - 7, 0xCC is type, 0xDD is 
  275.  *       interrupt to use.                
  276.  */
  277. /*
  278.  *     klsiNewCode
  279.  */
  280. static UINT8 klsiNewCode[] = 
  281. {
  282.     0xB6, 0xC3, 0xAA, 0xBB, 0xCC, 0xDD,
  283.     0x9f, 0xcf, 0xbc, 0x08, 0xe7, 0x57, 0x00, 0x00,
  284.     0x9a, 0x08, 0x97, 0xc1, 0xe7, 0x67, 0xff, 0x1f,
  285.     0x28, 0xc0, 0xe7, 0x87, 0x00, 0x04, 0x24, 0xc0,
  286.     0xe7, 0x67, 0xff, 0xf9, 0x22, 0xc0, 0x97, 0xcf,
  287.     0xe7, 0x09, 0xa2, 0xc0, 0x94, 0x08, 0xd7, 0x09,
  288.     0x00, 0xc0, 0xe7, 0x59, 0xba, 0x08, 0x94, 0x08,
  289.     0x03, 0xc1, 0xe7, 0x67, 0xff, 0xf7, 0x24, 0xc0,
  290.     0xe7, 0x05, 0x00, 0xc0, 0xa7, 0xcf, 0x92, 0x08,
  291.     0xe7, 0x57, 0x00, 0x00, 0x8e, 0x08, 0xa7, 0xa1,
  292.     0x8e, 0x08, 0x97, 0xcf, 0xe7, 0x57, 0x00, 0x00,
  293.     0xf2, 0x09, 0x0a, 0xc0, 0xe7, 0x57, 0x00, 0x00,
  294.     0xa4, 0xc0, 0xa7, 0xc0, 0x56, 0x08, 0x9f, 0xaf,
  295.     0x70, 0x09, 0xe7, 0x07, 0x00, 0x00, 0xf2, 0x09,
  296.     0xe7, 0x57, 0xff, 0xff, 0x90, 0x08, 0x9f, 0xa0,
  297.     0x40, 0x00, 0xe7, 0x59, 0x90, 0x08, 0x94, 0x08,
  298.     0x9f, 0xa0, 0x40, 0x00, 0xc8, 0x09, 0xa2, 0x08,
  299.     0x08, 0x62, 0x9f, 0xa1, 0x14, 0x0a, 0xe7, 0x57,
  300.     0x00, 0x00, 0x52, 0x08, 0xa7, 0xc0, 0x56, 0x08,
  301.     0x9f, 0xaf, 0x04, 0x00, 0xe7, 0x57, 0x00, 0x00,
  302.     0x8e, 0x08, 0xa7, 0xc1, 0x56, 0x08, 0xc0, 0x09,
  303.     0xa8, 0x08, 0x00, 0x60, 0x05, 0xc4, 0xc0, 0x59,
  304.     0x94, 0x08, 0x02, 0xc0, 0x9f, 0xaf, 0xee, 0x00,
  305.     0xe7, 0x59, 0xae, 0x08, 0x94, 0x08, 0x02, 0xc1,
  306.     0x9f, 0xaf, 0xf6, 0x00, 0x9f, 0xaf, 0x9e, 0x03,
  307.     0xef, 0x57, 0x00, 0x00, 0xf0, 0x09, 0x9f, 0xa1,
  308.     0xde, 0x01, 0xe7, 0x57, 0x00, 0x00, 0x78, 0x08,
  309.     0x9f, 0xa0, 0xe4, 0x03, 0x9f, 0xaf, 0x2c, 0x04,
  310.     0xa7, 0xcf, 0x56, 0x08, 0x48, 0x02, 0xe7, 0x09,
  311.     0x94, 0x08, 0xa8, 0x08, 0xc8, 0x37, 0x04, 0x00,
  312.     0x9f, 0xaf, 0x68, 0x04, 0x97, 0xcf, 0xe7, 0x57,
  313.     0x00, 0x00, 0xa6, 0x08, 0x97, 0xc0, 0xd7, 0x09,
  314.     0x00, 0xc0, 0xc1, 0xdf, 0xc8, 0x09, 0x9c, 0x08,
  315.     0x08, 0x62, 0x1d, 0xc0, 0x27, 0x04, 0x9c, 0x08,
  316.     0x10, 0x94, 0xf0, 0x07, 0xee, 0x09, 0x02, 0x00,
  317.     0xc1, 0x07, 0x01, 0x00, 0x70, 0x00, 0x04, 0x00,
  318.     0xf0, 0x07, 0x44, 0x01, 0x06, 0x00, 0x50, 0xaf,
  319.     0xe7, 0x09, 0x94, 0x08, 0xae, 0x08, 0xe7, 0x17,
  320.     0x14, 0x00, 0xae, 0x08, 0xe7, 0x67, 0xff, 0x07,
  321.     0xae, 0x08, 0xe7, 0x07, 0xff, 0xff, 0xa8, 0x08,
  322.     0xe7, 0x07, 0x00, 0x00, 0xa6, 0x08, 0xe7, 0x05,
  323.     0x00, 0xc0, 0x97, 0xcf, 0xd7, 0x09, 0x00, 0xc0,
  324.     0xc1, 0xdf, 0x48, 0x02, 0xd0, 0x09, 0x9c, 0x08,
  325.     0x27, 0x02, 0x9c, 0x08, 0xe7, 0x09, 0x20, 0xc0,
  326.     0xee, 0x09, 0xe7, 0xd0, 0xee, 0x09, 0xe7, 0x05,
  327.     0x00, 0xc0, 0x97, 0xcf, 0x48, 0x02, 0xc8, 0x37,
  328.     0x04, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x60,
  329.     0x21, 0xc0, 0xc0, 0x37, 0x3e, 0x00, 0x23, 0xc9,
  330.     0xc0, 0x57, 0xb4, 0x05, 0x1b, 0xc8, 0xc0, 0x17,
  331.     0x3f, 0x00, 0xc0, 0x67, 0xc0, 0xff, 0x30, 0x00,
  332.     0x08, 0x00, 0xf0, 0x07, 0x00, 0x00, 0x04, 0x00,
  333.     0x00, 0x02, 0xc0, 0x17, 0x4c, 0x00, 0x30, 0x00,
  334.     0x06, 0x00, 0xf0, 0x07, 0xbe, 0x01, 0x0a, 0x00,
  335.     0x48, 0x02, 0xc1, 0x07, 0x02, 0x00, 0xd7, 0x09,
  336.     0x00, 0xc0, 0xc1, 0xdf, 0x51, 0xaf, 0xe7, 0x05,
  337.     0x00, 0xc0, 0x97, 0xcf, 0x9f, 0xaf, 0x68, 0x04,
  338.     0x9f, 0xaf, 0xe4, 0x03, 0x97, 0xcf, 0x9f, 0xaf,
  339.     0xe4, 0x03, 0xc9, 0x37, 0x04, 0x00, 0xc1, 0xdf,
  340.     0xc8, 0x09, 0x70, 0x08, 0x50, 0x02, 0x67, 0x02,
  341.     0x70, 0x08, 0xd1, 0x07, 0x00, 0x00, 0xc0, 0xdf,
  342.     0x9f, 0xaf, 0xde, 0x01, 0x97, 0xcf, 0xe7, 0x57,
  343.     0x00, 0x00, 0xaa, 0x08, 0x97, 0xc1, 0xe7, 0x57,
  344.     0x01, 0x00, 0x7a, 0x08, 0x97, 0xc0, 0xc8, 0x09,
  345.     0x6e, 0x08, 0x08, 0x62, 0x97, 0xc0, 0x00, 0x02,
  346.     0xc0, 0x17, 0x0e, 0x00, 0x27, 0x00, 0x34, 0x01,
  347.     0x27, 0x0c, 0x0c, 0x00, 0x36, 0x01, 0xef, 0x57,
  348.     0x00, 0x00, 0xf0, 0x09, 0x9f, 0xc0, 0xbe, 0x02,
  349.     0xe7, 0x57, 0x00, 0x00, 0xb0, 0x08, 0x97, 0xc1,
  350.     0xe7, 0x07, 0x09, 0x00, 0x12, 0xc0, 0xe7, 0x77,
  351.     0x00, 0x08, 0x20, 0xc0, 0x9f, 0xc1, 0xb6, 0x02,
  352.     0xe7, 0x57, 0x09, 0x00, 0x12, 0xc0, 0x77, 0xc9,
  353.     0xd7, 0x09, 0x00, 0xc0, 0xc1, 0xdf, 0xe7, 0x77,
  354.     0x00, 0x08, 0x20, 0xc0, 0x2f, 0xc1, 0xe7, 0x07,
  355.     0x00, 0x00, 0x42, 0xc0, 0xe7, 0x07, 0x05, 0x00,
  356.     0x90, 0xc0, 0xc8, 0x07, 0x0a, 0x00, 0xe7, 0x77,
  357.     0x04, 0x00, 0x20, 0xc0, 0x09, 0xc1, 0x08, 0xda,
  358.     0x7a, 0xc1, 0xe7, 0x07, 0x00, 0x01, 0x42, 0xc0,
  359.     0xe7, 0x07, 0x04, 0x00, 0x90, 0xc0, 0x1a, 0xcf,
  360.     0xe7, 0x07, 0x01, 0x00, 0x7a, 0x08, 0x00, 0xd8,
  361.     0x27, 0x50, 0x34, 0x01, 0x17, 0xc1, 0xe7, 0x77,
  362.     0x02, 0x00, 0x20, 0xc0, 0x79, 0xc1, 0x27, 0x50,
  363.     0x34, 0x01, 0x10, 0xc1, 0xe7, 0x77, 0x02, 0x00,
  364.     0x20, 0xc0, 0x79, 0xc0, 0x9f, 0xaf, 0xd8, 0x02,
  365.     0xe7, 0x05, 0x00, 0xc0, 0x00, 0x60, 0x9f, 0xc0,
  366.     0xde, 0x01, 0x97, 0xcf, 0xe7, 0x07, 0x01, 0x00,
  367.     0xb8, 0x08, 0x06, 0xcf, 0xe7, 0x07, 0x30, 0x0e,
  368.     0x02, 0x00, 0xe7, 0x07, 0x50, 0xc3, 0x12, 0xc0,
  369.     0xe7, 0x05, 0x00, 0xc0, 0x97, 0xcf, 0xe7, 0x07,
  370.     0x01, 0x00, 0xb8, 0x08, 0x97, 0xcf, 0xe7, 0x07,
  371.     0x50, 0xc3, 0x12, 0xc0, 0xe7, 0x07, 0x30, 0x0e,
  372.     0x02, 0x00, 0xe7, 0x07, 0x01, 0x00, 0x7a, 0x08,
  373.     0xe7, 0x07, 0x05, 0x00, 0x90, 0xc0, 0x97, 0xcf,
  374.     0xe7, 0x07, 0x00, 0x01, 0x42, 0xc0, 0xe7, 0x07,
  375.     0x04, 0x00, 0x90, 0xc0, 0xe7, 0x07, 0x00, 0x00,
  376.     0x7a, 0x08, 0xe7, 0x57, 0x0f, 0x00, 0xb2, 0x08,
  377.     0x13, 0xc1, 0x9f, 0xaf, 0x2e, 0x08, 0xca, 0x09,
  378.     0xac, 0x08, 0xf2, 0x17, 0x01, 0x00, 0x5c, 0x00,
  379.     0xf2, 0x27, 0x00, 0x00, 0x5e, 0x00, 0xe7, 0x07,
  380.     0x00, 0x00, 0xb2, 0x08, 0xe7, 0x07, 0x01, 0x00,
  381.     0xb4, 0x08, 0xc0, 0x07, 0xff, 0xff, 0x97, 0xcf,
  382.     0x9f, 0xaf, 0x4c, 0x03, 0xc0, 0x69, 0xb4, 0x08,
  383.     0x57, 0x00, 0x9f, 0xde, 0x33, 0x00, 0xc1, 0x05,
  384.     0x27, 0xd8, 0xb2, 0x08, 0x27, 0xd2, 0xb4, 0x08,
  385.     0xe7, 0x87, 0x01, 0x00, 0xb4, 0x08, 0xe7, 0x67,
  386.     0xff, 0x03, 0xb4, 0x08, 0x00, 0x60, 0x97, 0xc0,
  387.     0xe7, 0x07, 0x01, 0x00, 0xb0, 0x08, 0x27, 0x00,
  388.     0x12, 0xc0, 0x97, 0xcf, 0xc0, 0x09, 0xb6, 0x08,
  389.     0x00, 0xd2, 0x02, 0xc3, 0xc0, 0x97, 0x05, 0x80,
  390.     0x27, 0x00, 0xb6, 0x08, 0xc0, 0x99, 0x82, 0x08,
  391.     0xc0, 0x99, 0xa2, 0xc0, 0x97, 0xcf, 0xe7, 0x07,
  392.     0x00, 0x00, 0xb0, 0x08, 0xc0, 0xdf, 0x97, 0xcf,
  393.     0xc8, 0x09, 0x72, 0x08, 0x08, 0x62, 0x02, 0xc0,
  394.     0x10, 0x64, 0x07, 0xc1, 0xe7, 0x07, 0x00, 0x00,
  395.     0x64, 0x08, 0xe7, 0x07, 0xc8, 0x05, 0x24, 0x00,
  396.     0x97, 0xcf, 0x27, 0x04, 0x72, 0x08, 0xc8, 0x17,
  397.     0x0e, 0x00, 0x27, 0x02, 0x64, 0x08, 0xe7, 0x07,
  398.     0xd6, 0x05, 0x24, 0x00, 0x97, 0xcf, 0xd7, 0x09,
  399.     0x00, 0xc0, 0xc1, 0xdf, 0xe7, 0x57, 0x00, 0x00,
  400.     0x62, 0x08, 0x13, 0xc1, 0x9f, 0xaf, 0x70, 0x03,
  401.     0xe7, 0x57, 0x00, 0x00, 0x64, 0x08, 0x13, 0xc0,
  402.     0xe7, 0x09, 0x64, 0x08, 0x30, 0x01, 0xe7, 0x07,
  403.     0xf2, 0x05, 0x32, 0x01, 0xe7, 0x07, 0x10, 0x00,
  404.     0x96, 0xc0, 0xe7, 0x09, 0x64, 0x08, 0x62, 0x08,
  405.     0x04, 0xcf, 0xe7, 0x57, 0x00, 0x00, 0x64, 0x08,
  406.     0x02, 0xc1, 0x9f, 0xaf, 0x70, 0x03, 0xe7, 0x05,
  407.     0x00, 0xc0, 0x97, 0xcf, 0xd7, 0x09, 0x00, 0xc0,
  408.     0xc1, 0xdf, 0xc8, 0x09, 0x72, 0x08, 0x27, 0x02,
  409.     0x78, 0x08, 0x08, 0x62, 0x03, 0xc1, 0xe7, 0x05,
  410.     0x00, 0xc0, 0x97, 0xcf, 0x27, 0x04, 0x72, 0x08,
  411.     0xe7, 0x05, 0x00, 0xc0, 0xf0, 0x07, 0x40, 0x00,
  412.     0x08, 0x00, 0xf0, 0x07, 0x00, 0x00, 0x04, 0x00,
  413.     0x00, 0x02, 0xc0, 0x17, 0x0c, 0x00, 0x30, 0x00,
  414.     0x06, 0x00, 0xf0, 0x07, 0x64, 0x01, 0x0a, 0x00,
  415.     0xc8, 0x17, 0x04, 0x00, 0xc1, 0x07, 0x02, 0x00,
  416.     0x51, 0xaf, 0x97, 0xcf, 0xe7, 0x57, 0x00, 0x00,
  417.     0x6a, 0x08, 0x97, 0xc0, 0xc1, 0xdf, 0xc8, 0x09,
  418.     0x6a, 0x08, 0x27, 0x04, 0x6a, 0x08, 0x27, 0x52,
  419.     0x6c, 0x08, 0x03, 0xc1, 0xe7, 0x07, 0x6a, 0x08,
  420.     0x6c, 0x08, 0xc0, 0xdf, 0x17, 0x02, 0xc8, 0x17,
  421.     0x0e, 0x00, 0x9f, 0xaf, 0x16, 0x05, 0xc8, 0x05,
  422.     0x00, 0x60, 0x03, 0xc0, 0x9f, 0xaf, 0x80, 0x04,
  423.     0x97, 0xcf, 0x9f, 0xaf, 0x68, 0x04, 0x97, 0xcf,
  424.     0xd7, 0x09, 0x00, 0xc0, 0xc1, 0xdf, 0x08, 0x62,
  425.     0x1c, 0xc0, 0xd0, 0x09, 0x72, 0x08, 0x27, 0x02,
  426.     0x72, 0x08, 0xe7, 0x05, 0x00, 0xc0, 0x97, 0xcf,
  427.     0x97, 0x02, 0xca, 0x09, 0xac, 0x08, 0xf2, 0x17,
  428.     0x01, 0x00, 0x04, 0x00, 0xf2, 0x27, 0x00, 0x00,
  429.     0x06, 0x00, 0xca, 0x17, 0x2c, 0x00, 0xf8, 0x77,
  430.     0x01, 0x00, 0x0e, 0x00, 0x06, 0xc0, 0xca, 0xd9,
  431.     0xf8, 0x57, 0xff, 0x00, 0x0e, 0x00, 0x01, 0xc1,
  432.     0xca, 0xd9, 0x22, 0x1c, 0x0c, 0x00, 0xe2, 0x27,
  433.     0x00, 0x00, 0xe2, 0x17, 0x01, 0x00, 0xe2, 0x27,
  434.     0x00, 0x00, 0xca, 0x05, 0x00, 0x0c, 0x0c, 0x00,
  435.     0xc0, 0x17, 0x41, 0x00, 0xc0, 0x67, 0xc0, 0xff,
  436.     0x30, 0x00, 0x08, 0x00, 0x00, 0x02, 0xc0, 0x17,
  437.     0x0c, 0x00, 0x30, 0x00, 0x06, 0x00, 0xf0, 0x07,
  438.     0xdc, 0x00, 0x0a, 0x00, 0xf0, 0x07, 0x00, 0x00,
  439.     0x04, 0x00, 0x00, 0x0c, 0x08, 0x00, 0x40, 0xd1,
  440.     0x01, 0x00, 0xc0, 0x19, 0xa6, 0x08, 0xc0, 0x59,
  441.     0x98, 0x08, 0x04, 0xc9, 0x49, 0xaf, 0x9f, 0xaf,
  442.     0xee, 0x00, 0x4a, 0xaf, 0x67, 0x10, 0xa6, 0x08,
  443.     0xc8, 0x17, 0x04, 0x00, 0xc1, 0x07, 0x01, 0x00,
  444.     0xd7, 0x09, 0x00, 0xc0, 0xc1, 0xdf, 0x50, 0xaf,
  445.     0xe7, 0x05, 0x00, 0xc0, 0x97, 0xcf, 0xc0, 0x07,
  446.     0x01, 0x00, 0xc1, 0x09, 0x7c, 0x08, 0xc1, 0x77,
  447.     0x01, 0x00, 0x97, 0xc1, 0xd8, 0x77, 0x01, 0x00,
  448.     0x12, 0xc0, 0xc9, 0x07, 0x4c, 0x08, 0x9f, 0xaf,
  449.     0x64, 0x05, 0x04, 0xc1, 0xc1, 0x77, 0x08, 0x00,
  450.     0x13, 0xc0, 0x97, 0xcf, 0xc1, 0x77, 0x02, 0x00,
  451.     0x97, 0xc1, 0xc1, 0x77, 0x10, 0x00, 0x0c, 0xc0,
  452.     0x9f, 0xaf, 0x86, 0x05, 0x97, 0xcf, 0xc1, 0x77,
  453.     0x04, 0x00, 0x06, 0xc0, 0xc9, 0x07, 0x7e, 0x08,
  454.     0x9f, 0xaf, 0x64, 0x05, 0x97, 0xc0, 0x00, 0xcf,
  455.     0x00, 0x90, 0x97, 0xcf, 0x50, 0x54, 0x97, 0xc1,
  456.     0x70, 0x5c, 0x02, 0x00, 0x02, 0x00, 0x97, 0xc1,
  457.     0x70, 0x5c, 0x04, 0x00, 0x04, 0x00, 0x97, 0xcf,
  458.     0xc0, 0x00, 0x60, 0x00, 0x30, 0x00, 0x18, 0x00,
  459.     0x0c, 0x00, 0x06, 0x00, 0x00, 0x00, 0xcb, 0x09,
  460.     0x88, 0x08, 0xcc, 0x09, 0x8a, 0x08, 0x0b, 0x53,
  461.     0x11, 0xc0, 0xc9, 0x02, 0xca, 0x07, 0x78, 0x05,
  462.     0x9f, 0xaf, 0x64, 0x05, 0x97, 0xc0, 0x0a, 0xc8,
  463.     0x82, 0x08, 0x0a, 0xcf, 0x82, 0x08, 0x9f, 0xaf,
  464.     0x64, 0x05, 0x97, 0xc0, 0x05, 0xc2, 0x89, 0x30,
  465.     0x82, 0x60, 0x78, 0xc1, 0x00, 0x90, 0x97, 0xcf,
  466.     0x89, 0x10, 0x09, 0x53, 0x79, 0xc2, 0x89, 0x30,
  467.     0x82, 0x08, 0x7a, 0xcf, 0xc0, 0xdf, 0x97, 0xcf,
  468.     0xe7, 0x09, 0x96, 0xc0, 0x66, 0x08, 0xe7, 0x09,
  469.     0x98, 0xc0, 0x68, 0x08, 0x0f, 0xcf, 0xe7, 0x09,
  470.     0x96, 0xc0, 0x66, 0x08, 0xe7, 0x09, 0x98, 0xc0,
  471.     0x68, 0x08, 0xe7, 0x09, 0x64, 0x08, 0x30, 0x01,
  472.     0xe7, 0x07, 0xf2, 0x05, 0x32, 0x01, 0xe7, 0x07,
  473.     0x10, 0x00, 0x96, 0xc0, 0xd7, 0x09, 0x00, 0xc0,
  474.     0x17, 0x02, 0xc8, 0x09, 0x62, 0x08, 0xc8, 0x37,
  475.     0x0e, 0x00, 0xe7, 0x57, 0x04, 0x00, 0x68, 0x08,
  476.     0x3d, 0xc0, 0xe7, 0x87, 0x00, 0x08, 0x24, 0xc0,
  477.     0xe7, 0x09, 0x94, 0x08, 0xba, 0x08, 0xe7, 0x17,
  478.     0x64, 0x00, 0xba, 0x08, 0xe7, 0x67, 0xff, 0x07,
  479.     0xba, 0x08, 0xe7, 0x77, 0x2a, 0x00, 0x66, 0x08,
  480.     0x30, 0xc0, 0x97, 0x02, 0xca, 0x09, 0xac, 0x08,
  481.     0xe7, 0x77, 0x20, 0x00, 0x66, 0x08, 0x0e, 0xc0,
  482.     0xf2, 0x17, 0x01, 0x00, 0x10, 0x00, 0xf2, 0x27,
  483.     0x00, 0x00, 0x12, 0x00, 0xe7, 0x77, 0x0a, 0x00,
  484.     0x66, 0x08, 0xca, 0x05, 0x1e, 0xc0, 0x97, 0x02,
  485.     0xca, 0x09, 0xac, 0x08, 0xf2, 0x17, 0x01, 0x00,
  486.     0x0c, 0x00, 0xf2, 0x27, 0x00, 0x00, 0x0e, 0x00,
  487.     0xe7, 0x77, 0x02, 0x00, 0x66, 0x08, 0x07, 0xc0,
  488.     0xf2, 0x17, 0x01, 0x00, 0x44, 0x00, 0xf2, 0x27,
  489.     0x00, 0x00, 0x46, 0x00, 0x06, 0xcf, 0xf2, 0x17,
  490.     0x01, 0x00, 0x60, 0x00, 0xf2, 0x27, 0x00, 0x00,
  491.     0x62, 0x00, 0xca, 0x05, 0x9f, 0xaf, 0x68, 0x04,
  492.     0x0f, 0xcf, 0x57, 0x02, 0x09, 0x02, 0xf1, 0x09,
  493.     0x68, 0x08, 0x0c, 0x00, 0xf1, 0xda, 0x0c, 0x00,
  494.     0xc8, 0x09, 0x6c, 0x08, 0x50, 0x02, 0x67, 0x02,
  495.     0x6c, 0x08, 0xd1, 0x07, 0x00, 0x00, 0xc9, 0x05,
  496.     0xe7, 0x09, 0x64, 0x08, 0x62, 0x08, 0xe7, 0x57,
  497.     0x00, 0x00, 0x62, 0x08, 0x02, 0xc0, 0x9f, 0xaf,
  498.     0x70, 0x03, 0xc8, 0x05, 0xe7, 0x05, 0x00, 0xc0,
  499.     0xc0, 0xdf, 0x97, 0xcf, 0xd7, 0x09, 0x00, 0xc0,
  500.     0x17, 0x00, 0x17, 0x02, 0x97, 0x02, 0xc0, 0x09,
  501.     0x92, 0xc0, 0xe7, 0x87, 0x00, 0x08, 0x24, 0xc0,
  502.     0xe7, 0x09, 0x94, 0x08, 0xba, 0x08, 0xe7, 0x17,
  503.     0x64, 0x00, 0xba, 0x08, 0xe7, 0x67, 0xff, 0x07,
  504.     0xba, 0x08, 0xe7, 0x07, 0x04, 0x00, 0x90, 0xc0,
  505.     0xca, 0x09, 0xac, 0x08, 0xe7, 0x07, 0x00, 0x00,
  506.     0x7a, 0x08, 0xe7, 0x07, 0x66, 0x03, 0x02, 0x00,
  507.     0xc0, 0x77, 0x02, 0x00, 0x10, 0xc0, 0xef, 0x57,
  508.     0x00, 0x00, 0xf0, 0x09, 0x04, 0xc0, 0x9f, 0xaf,
  509.     0xd8, 0x02, 0x9f, 0xcf, 0x12, 0x08, 0xf2, 0x17,
  510.     0x01, 0x00, 0x50, 0x00, 0xf2, 0x27, 0x00, 0x00,
  511.     0x52, 0x00, 0x9f, 0xcf, 0x12, 0x08, 0xef, 0x57,
  512.     0x00, 0x00, 0xf0, 0x09, 0x08, 0xc0, 0xe7, 0x57,
  513.     0x00, 0x00, 0xb8, 0x08, 0xe7, 0x07, 0x00, 0x00,
  514.     0xb8, 0x08, 0x0a, 0xc0, 0x03, 0xcf, 0xc0, 0x77,
  515.     0x10, 0x00, 0x06, 0xc0, 0xf2, 0x17, 0x01, 0x00,
  516.     0x58, 0x00, 0xf2, 0x27, 0x00, 0x00, 0x5a, 0x00,
  517.     0xc0, 0x77, 0x80, 0x00, 0x06, 0xc0, 0xf2, 0x17,
  518.     0x01, 0x00, 0x70, 0x00, 0xf2, 0x27, 0x00, 0x00,
  519.     0x72, 0x00, 0xc0, 0x77, 0x08, 0x00, 0x1d, 0xc1,
  520.     0xf2, 0x17, 0x01, 0x00, 0x08, 0x00, 0xf2, 0x27,
  521.     0x00, 0x00, 0x0a, 0x00, 0xc0, 0x77, 0x00, 0x02,
  522.     0x06, 0xc0, 0xf2, 0x17, 0x01, 0x00, 0x64, 0x00,
  523.     0xf2, 0x27, 0x00, 0x00, 0x66, 0x00, 0xc0, 0x77,
  524.     0x40, 0x00, 0x06, 0xc0, 0xf2, 0x17, 0x01, 0x00,
  525.     0x5c, 0x00, 0xf2, 0x27, 0x00, 0x00, 0x5e, 0x00,
  526.     0xc0, 0x77, 0x01, 0x00, 0x01, 0xc0, 0x37, 0xcf,
  527.     0x36, 0xcf, 0xf2, 0x17, 0x01, 0x00, 0x00, 0x00,
  528.     0xf2, 0x27, 0x00, 0x00, 0x02, 0x00, 0xef, 0x57,
  529.     0x00, 0x00, 0xf0, 0x09, 0x18, 0xc0, 0xe7, 0x57,
  530.     0x01, 0x00, 0xb2, 0x08, 0x0e, 0xc2, 0x07, 0xc8,
  531.     0xf2, 0x17, 0x01, 0x00, 0x50, 0x00, 0xf2, 0x27,
  532.     0x00, 0x00, 0x52, 0x00, 0x06, 0xcf, 0xf2, 0x17,
  533.     0x01, 0x00, 0x54, 0x00, 0xf2, 0x27, 0x00, 0x00,
  534.     0x56, 0x00, 0xe7, 0x07, 0x00, 0x00, 0xb2, 0x08,
  535.     0xe7, 0x07, 0x01, 0x00, 0xb4, 0x08, 0xc8, 0x09,
  536.     0x34, 0x01, 0xca, 0x17, 0x14, 0x00, 0xd8, 0x77,
  537.     0x01, 0x00, 0x05, 0xc0, 0xca, 0xd9, 0xd8, 0x57,
  538.     0xff, 0x00, 0x01, 0xc0, 0xca, 0xd9, 0xe2, 0x19,
  539.     0x94, 0xc0, 0xe2, 0x27, 0x00, 0x00, 0xe2, 0x17,
  540.     0x01, 0x00, 0xe2, 0x27, 0x00, 0x00, 0x9f, 0xaf,
  541.     0x2e, 0x08, 0x9f, 0xaf, 0xde, 0x01, 0xe7, 0x57,
  542.     0x00, 0x00, 0xaa, 0x08, 0x9f, 0xa1, 0xf0, 0x0b,
  543.     0xca, 0x05, 0xc8, 0x05, 0xc0, 0x05, 0xe7, 0x05,
  544.     0x00, 0xc0, 0xc0, 0xdf, 0x97, 0xcf, 0xc8, 0x09,
  545.     0x6e, 0x08, 0x08, 0x62, 0x97, 0xc0, 0x27, 0x04,
  546.     0x6e, 0x08, 0x27, 0x52, 0x70, 0x08, 0x03, 0xc1,
  547.     0xe7, 0x07, 0x6e, 0x08, 0x70, 0x08, 0x9f, 0xaf,
  548.     0x68, 0x04, 0x97, 0xcf, 0xff, 0xff, 0xff, 0xff,
  549.     0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  550.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  551.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  552.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  553.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  554.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  555.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  556.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  557.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  558.     0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  559.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  560.     0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
  561.     0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x33, 0xcc,
  562.     0x00, 0x00, 0x00, 0x00, 0xe7, 0x57, 0x00, 0x80,
  563.     0xb2, 0x00, 0x06, 0xc2, 0xe7, 0x07, 0x52, 0x0e,
  564.     0x12, 0x00, 0xe7, 0x07, 0x98, 0x0e, 0xb2, 0x00,
  565.     0xe7, 0x07, 0xa4, 0x09, 0xf2, 0x02, 0xc8, 0x09,
  566.     0xb4, 0x00, 0xf8, 0x07, 0x02, 0x00, 0x0d, 0x00,
  567.     0xd7, 0x09, 0x0e, 0xc0, 0xe7, 0x07, 0x00, 0x00,
  568.     0x0e, 0xc0, 0xc8, 0x09, 0xdc, 0x00, 0xf0, 0x07,
  569.     0xff, 0xff, 0x09, 0x00, 0xf0, 0x07, 0xfb, 0x13,
  570.     0x0b, 0x00, 0xe7, 0x09, 0xc0, 0x00, 0x58, 0x08,
  571.     0xe7, 0x09, 0xbe, 0x00, 0x54, 0x08, 0xe7, 0x09,
  572.     0x10, 0x00, 0x92, 0x08, 0xc8, 0x07, 0xb4, 0x09,
  573.     0x9f, 0xaf, 0x8c, 0x09, 0x9f, 0xaf, 0xe2, 0x0b,
  574.     0xc0, 0x07, 0x80, 0x01, 0x44, 0xaf, 0x27, 0x00,
  575.     0x88, 0x08, 0x27, 0x00, 0x8a, 0x08, 0x27, 0x00,
  576.     0x8c, 0x08, 0xc0, 0x07, 0x74, 0x00, 0x44, 0xaf,
  577.     0x27, 0x00, 0xac, 0x08, 0x08, 0x00, 0x00, 0x90,
  578.     0xc1, 0x07, 0x1d, 0x00, 0x20, 0x00, 0x20, 0x00,
  579.     0x01, 0xda, 0x7c, 0xc1, 0x9f, 0xaf, 0x8a, 0x0b,
  580.     0xc0, 0x07, 0x4c, 0x00, 0x48, 0xaf, 0x27, 0x00,
  581.     0x56, 0x08, 0x9f, 0xaf, 0x72, 0x0c, 0xe7, 0x07,
  582.     0x00, 0x80, 0x96, 0x08, 0xef, 0x57, 0x00, 0x00,
  583.     0xf0, 0x09, 0x03, 0xc0, 0xe7, 0x07, 0x01, 0x00,
  584.     0x1c, 0xc0, 0xe7, 0x05, 0x0e, 0xc0, 0x97, 0xcf,
  585.     0x49, 0xaf, 0xe7, 0x87, 0x43, 0x00, 0x0e, 0xc0,
  586.     0xe7, 0x07, 0xff, 0xff, 0x94, 0x08, 0x9f, 0xaf,
  587.     0x8a, 0x0c, 0xc0, 0x07, 0x01, 0x00, 0x60, 0xaf,
  588.     0x4a, 0xaf, 0x97, 0xcf, 0x00, 0x08, 0x09, 0x08,
  589.     0x11, 0x08, 0x00, 0xda, 0x7c, 0xc1, 0x97, 0xcf,
  590.     0x67, 0x04, 0xcc, 0x02, 0xc0, 0xdf, 0x51, 0x94,
  591.     0xb1, 0xaf, 0x06, 0x00, 0xc1, 0xdf, 0xc9, 0x09,
  592.     0xcc, 0x02, 0x49, 0x62, 0x75, 0xc1, 0xc0, 0xdf,
  593.     0xa7, 0xcf, 0xd6, 0x02, 0x0e, 0x00, 0x24, 0x00,
  594.     0xd6, 0x05, 0x22, 0x00, 0xc4, 0x06, 0xd0, 0x00,
  595.     0xf0, 0x0b, 0xaa, 0x00, 0x0e, 0x0a, 0xbe, 0x00,
  596.     0x2c, 0x0c, 0x10, 0x00, 0x20, 0x00, 0x04, 0x00,
  597.     0xc4, 0x05, 0x02, 0x00, 0x66, 0x03, 0x06, 0x00,
  598.     0x00, 0x00, 0x24, 0xc0, 0x04, 0x04, 0x28, 0xc0,
  599.     0xfe, 0xfb, 0x1e, 0xc0, 0x00, 0x04, 0x22, 0xc0,
  600.     0xff, 0xf0, 0xc0, 0x00, 0x60, 0x0b, 0x00, 0x00,
  601.     0x00, 0x00, 0xff, 0xff, 0x34, 0x0a, 0x3e, 0x0a,
  602.     0x9e, 0x0a, 0xa8, 0x0a, 0xce, 0x0a, 0xd2, 0x0a,
  603.     0xd6, 0x0a, 0x00, 0x0b, 0x10, 0x0b, 0x1e, 0x0b,
  604.     0x20, 0x0b, 0x28, 0x0b, 0x28, 0x0b, 0x27, 0x02,
  605.     0xa2, 0x08, 0x97, 0xcf, 0xe7, 0x07, 0x00, 0x00,
  606.     0xa2, 0x08, 0x0a, 0x0e, 0x01, 0x00, 0xca, 0x57,
  607.     0x0e, 0x00, 0x9f, 0xc3, 0x2a, 0x0b, 0xca, 0x37,
  608.     0x00, 0x00, 0x9f, 0xc2, 0x2a, 0x0b, 0x0a, 0xd2,
  609.     0xb2, 0xcf, 0xf4, 0x09, 0xc8, 0x09, 0xde, 0x00,
  610.     0x07, 0x06, 0x9f, 0xcf, 0x3c, 0x0b, 0xf0, 0x57,
  611.     0x80, 0x01, 0x06, 0x00, 0x9f, 0xc8, 0x2a, 0x0b,
  612.     0x27, 0x0c, 0x02, 0x00, 0x86, 0x08, 0xc0, 0x09,
  613.     0x88, 0x08, 0x27, 0x00, 0x8a, 0x08, 0xe7, 0x07,
  614.     0x00, 0x00, 0x84, 0x08, 0x27, 0x00, 0x5c, 0x08,
  615.     0x00, 0x1c, 0x06, 0x00, 0x27, 0x00, 0x8c, 0x08,
  616.     0x41, 0x90, 0x67, 0x50, 0x86, 0x08, 0x0d, 0xc0,
  617.     0x67, 0x00, 0x5a, 0x08, 0x27, 0x0c, 0x06, 0x00,
  618.     0x5e, 0x08, 0xe7, 0x07, 0x8a, 0x0a, 0x60, 0x08,
  619.     0xc8, 0x07, 0x5a, 0x08, 0x41, 0x90, 0x51, 0xaf,
  620.     0x97, 0xcf, 0x9f, 0xaf, 0xac, 0x0e, 0xe7, 0x09,
  621.     0x8c, 0x08, 0x8a, 0x08, 0xe7, 0x09, 0x86, 0x08,
  622.     0x84, 0x08, 0x59, 0xaf, 0x97, 0xcf, 0x27, 0x0c,
  623.     0x02, 0x00, 0x7c, 0x08, 0x59, 0xaf, 0x97, 0xcf,
  624.     0x09, 0x0c, 0x02, 0x00, 0x09, 0xda, 0x49, 0xd2,
  625.     0xc9, 0x19, 0xac, 0x08, 0xc8, 0x07, 0x5a, 0x08,
  626.     0xe0, 0x07, 0x00, 0x00, 0x60, 0x02, 0xe0, 0x07,
  627.     0x04, 0x00, 0xd0, 0x07, 0x9a, 0x0a, 0x48, 0xdb,
  628.     0x41, 0x90, 0x50, 0xaf, 0x97, 0xcf, 0x59, 0xaf,
  629.     0x97, 0xcf, 0x59, 0xaf, 0x97, 0xcf, 0xf0, 0x57,
  630.     0x06, 0x00, 0x06, 0x00, 0x26, 0xc1, 0xe7, 0x07,
  631.     0x7e, 0x08, 0x5c, 0x08, 0x41, 0x90, 0x67, 0x00,
  632.     0x5a, 0x08, 0x27, 0x0c, 0x06, 0x00, 0x5e, 0x08,
  633.     0xe7, 0x07, 0x5c, 0x0b, 0x60, 0x08, 0xc8, 0x07,
  634.     0x5a, 0x08, 0x41, 0x90, 0x51, 0xaf, 0x97, 0xcf,
  635.     0x07, 0x0c, 0x06, 0x00, 0xc7, 0x57, 0x06, 0x00,
  636.     0x10, 0xc1, 0xc8, 0x07, 0x7e, 0x08, 0x16, 0xcf,
  637.     0x00, 0x0c, 0x02, 0x00, 0x00, 0xda, 0x40, 0xd1,
  638.     0x27, 0x00, 0x98, 0x08, 0x1f, 0xcf, 0x1e, 0xcf,
  639.     0x27, 0x0c, 0x02, 0x00, 0xa4, 0x08, 0x1a, 0xcf,
  640.     0x00, 0xcf, 0x27, 0x02, 0x20, 0x01, 0xe7, 0x07,
  641.     0x08, 0x00, 0x22, 0x01, 0xe7, 0x07, 0x13, 0x00,
  642.     0xb0, 0xc0, 0x97, 0xcf, 0x41, 0x90, 0x67, 0x00,
  643.     0x5a, 0x08, 0xe7, 0x01, 0x5e, 0x08, 0x27, 0x02,
  644.     0x5c, 0x08, 0xe7, 0x07, 0x5c, 0x0b, 0x60, 0x08,
  645.     0xc8, 0x07, 0x5a, 0x08, 0xc1, 0x07, 0x00, 0x80,
  646.     0x50, 0xaf, 0x97, 0xcf, 0x59, 0xaf, 0x97, 0xcf,
  647.     0x00, 0x60, 0x05, 0xc0, 0xe7, 0x07, 0x00, 0x00,
  648.     0x9a, 0x08, 0xa7, 0xcf, 0x58, 0x08, 0x9f, 0xaf,
  649.     0xe2, 0x0b, 0xe7, 0x07, 0x01, 0x00, 0x9a, 0x08,
  650.     0x49, 0xaf, 0xd7, 0x09, 0x00, 0xc0, 0x07, 0xaf,
  651.     0xe7, 0x05, 0x00, 0xc0, 0x4a, 0xaf, 0xa7, 0xcf,
  652.     0x58, 0x08, 0xc0, 0x07, 0x40, 0x00, 0x44, 0xaf,
  653.     0x27, 0x00, 0xa0, 0x08, 0x08, 0x00, 0xc0, 0x07,
  654.     0x20, 0x00, 0x20, 0x94, 0x00, 0xda, 0x7d, 0xc1,
  655.     0xc0, 0x07, 0xfe, 0x7f, 0x44, 0xaf, 0x40, 0x00,
  656.     0x41, 0x90, 0xc0, 0x37, 0x08, 0x00, 0xdf, 0xde,
  657.     0x50, 0x06, 0xc0, 0x57, 0x10, 0x00, 0x02, 0xc2,
  658.     0xc0, 0x07, 0x10, 0x00, 0x27, 0x00, 0x76, 0x08,
  659.     0x41, 0x90, 0x9f, 0xde, 0x40, 0x06, 0x44, 0xaf,
  660.     0x27, 0x00, 0x74, 0x08, 0xc0, 0x09, 0x76, 0x08,
  661.     0x41, 0x90, 0x00, 0xd2, 0x00, 0xd8, 0x9f, 0xde,
  662.     0x08, 0x00, 0x44, 0xaf, 0x27, 0x00, 0x9e, 0x08,
  663.     0x97, 0xcf, 0xe7, 0x87, 0x00, 0x84, 0x28, 0xc0,
  664.     0xe7, 0x67, 0xff, 0xf3, 0x24, 0xc0, 0x97, 0xcf,
  665.     0xe7, 0x87, 0x01, 0x00, 0xaa, 0x08, 0xe7, 0x57,
  666.     0x00, 0x00, 0x7a, 0x08, 0x97, 0xc1, 0x9f, 0xaf,
  667.     0xe2, 0x0b, 0xe7, 0x87, 0x00, 0x06, 0x22, 0xc0,
  668.     0xe7, 0x07, 0x00, 0x00, 0x90, 0xc0, 0xe7, 0x67,
  669.     0xfe, 0xff, 0x3e, 0xc0, 0xe7, 0x07, 0x2e, 0x00,
  670.     0x0a, 0xc0, 0xe7, 0x87, 0x01, 0x00, 0x3e, 0xc0,
  671.     0xe7, 0x07, 0xff, 0xff, 0x94, 0x08, 0x9f, 0xaf,
  672.     0xf0, 0x0c, 0x97, 0xcf, 0x17, 0x00, 0xa7, 0xaf,
  673.     0x54, 0x08, 0xc0, 0x05, 0x27, 0x00, 0x52, 0x08,
  674.     0xe7, 0x87, 0x01, 0x00, 0xaa, 0x08, 0x9f, 0xaf,
  675.     0xe2, 0x0b, 0xe7, 0x07, 0x0c, 0x00, 0x40, 0xc0,
  676.     0x9f, 0xaf, 0xf0, 0x0c, 0xe7, 0x07, 0x00, 0x00,
  677.     0x78, 0x08, 0x00, 0x90, 0xe7, 0x09, 0x88, 0x08,
  678.     0x8a, 0x08, 0x27, 0x00, 0x84, 0x08, 0x27, 0x00,
  679.     0x7c, 0x08, 0x9f, 0xaf, 0x8a, 0x0c, 0xe7, 0x07,
  680.     0x00, 0x00, 0xb2, 0x02, 0xe7, 0x07, 0x00, 0x00,
  681.     0xb4, 0x02, 0xc0, 0x07, 0x06, 0x00, 0xc8, 0x09,
  682.     0xde, 0x00, 0xc8, 0x17, 0x03, 0x00, 0xc9, 0x07,
  683.     0x7e, 0x08, 0x29, 0x0a, 0x00, 0xda, 0x7d, 0xc1,
  684.     0x97, 0xcf, 0xd7, 0x09, 0x00, 0xc0, 0xc1, 0xdf,
  685.     0x00, 0x90, 0x27, 0x00, 0x6a, 0x08, 0xe7, 0x07,
  686.     0x6a, 0x08, 0x6c, 0x08, 0x27, 0x00, 0x6e, 0x08,
  687.     0xe7, 0x07, 0x6e, 0x08, 0x70, 0x08, 0x27, 0x00,
  688.     0x78, 0x08, 0x27, 0x00, 0x62, 0x08, 0x27, 0x00,
  689.     0x64, 0x08, 0xc8, 0x09, 0x74, 0x08, 0xc1, 0x09,
  690.     0x76, 0x08, 0xc9, 0x07, 0x72, 0x08, 0x11, 0x02,
  691.     0x09, 0x02, 0xc8, 0x17, 0x40, 0x06, 0x01, 0xda,
  692.     0x7a, 0xc1, 0x51, 0x94, 0xc8, 0x09, 0x9e, 0x08,
  693.     0xc9, 0x07, 0x9c, 0x08, 0xc1, 0x09, 0x76, 0x08,
  694.     0x01, 0xd2, 0x01, 0xd8, 0x11, 0x02, 0x09, 0x02,
  695.     0xc8, 0x17, 0x08, 0x00, 0x01, 0xda, 0x7a, 0xc1,
  696.     0x51, 0x94, 0xe7, 0x05, 0x00, 0xc0, 0x97, 0xcf,
  697.     0xe7, 0x57, 0x00, 0x00, 0x52, 0x08, 0x97, 0xc0,
  698.     0x9f, 0xaf, 0x04, 0x00, 0xe7, 0x09, 0x94, 0x08,
  699.     0x90, 0x08, 0xe7, 0x57, 0xff, 0xff, 0x90, 0x08,
  700.     0x04, 0xc1, 0xe7, 0x07, 0xf0, 0x0c, 0x8e, 0x08,
  701.     0x97, 0xcf, 0xe7, 0x17, 0x32, 0x00, 0x90, 0x08,
  702.     0xe7, 0x67, 0xff, 0x07, 0x90, 0x08, 0xe7, 0x07,
  703.     0x26, 0x0d, 0x8e, 0x08, 0x97, 0xcf, 0xd7, 0x09,
  704.     0x00, 0xc0, 0xc1, 0xdf, 0xe7, 0x57, 0x00, 0x00,
  705.     0x96, 0x08, 0x23, 0xc0, 0xe7, 0x07, 0x00, 0x80,
  706.     0x80, 0xc0, 0xe7, 0x07, 0x04, 0x00, 0x90, 0xc0,
  707.     0xe7, 0x07, 0x00, 0x00, 0x80, 0xc0, 0xe7, 0x07,
  708.     0x00, 0x80, 0x80, 0xc0, 0xc0, 0x07, 0x00, 0x00,
  709.     0xc0, 0x07, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00,
  710.     0xe7, 0x07, 0x00, 0x00, 0x80, 0xc0, 0xe7, 0x07,
  711.     0x00, 0x80, 0x80, 0xc0, 0xe7, 0x07, 0x00, 0x80,
  712.     0x40, 0xc0, 0xc0, 0x07, 0x00, 0x00, 0xe7, 0x07,
  713.     0x00, 0x00, 0x40, 0xc0, 0xe7, 0x07, 0x00, 0x00,
  714.     0x80, 0xc0, 0xef, 0x57, 0x00, 0x00, 0xf1, 0x09,
  715.     0x9f, 0xa0, 0xc0, 0x0d, 0xe7, 0x07, 0x04, 0x00,
  716.     0x90, 0xc0, 0xe7, 0x07, 0x00, 0x02, 0x40, 0xc0,
  717.     0xe7, 0x07, 0x0c, 0x02, 0x40, 0xc0, 0xe7, 0x07,
  718.     0x00, 0x00, 0x96, 0x08, 0xe7, 0x07, 0x00, 0x00,
  719.     0x8e, 0x08, 0xe7, 0x07, 0x00, 0x00, 0xaa, 0x08,
  720.     0xd7, 0x09, 0x00, 0xc0, 0xc1, 0xdf, 0x9f, 0xaf,
  721.     0x9e, 0x03, 0xe7, 0x05, 0x00, 0xc0, 0x9f, 0xaf,
  722.     0xde, 0x01, 0xe7, 0x05, 0x00, 0xc0, 0x97, 0xcf,
  723.     0x9f, 0xaf, 0xde, 0x0d, 0xef, 0x77, 0x00, 0x00,
  724.     0xf1, 0x09, 0x97, 0xc1, 0x9f, 0xaf, 0xde, 0x0d,
  725.     0xef, 0x77, 0x00, 0x00, 0xf1, 0x09, 0x97, 0xc1,
  726.     0xef, 0x07, 0x01, 0x00, 0xf1, 0x09, 0xe7, 0x87,
  727.     0x00, 0x08, 0x1e, 0xc0, 0xe7, 0x87, 0x00, 0x08,
  728.     0x22, 0xc0, 0xe7, 0x67, 0xff, 0xf7, 0x22, 0xc0,
  729.     0xe7, 0x77, 0x00, 0x08, 0x20, 0xc0, 0x11, 0xc0,
  730.     0xe7, 0x67, 0xff, 0xf7, 0x1e, 0xc0, 0xe7, 0x87,
  731.     0x00, 0x08, 0x22, 0xc0, 0xe7, 0x67, 0xff, 0xf7,
  732.     0x22, 0xc0, 0xe7, 0x77, 0x00, 0x08, 0x20, 0xc0,
  733.     0x04, 0xc1, 0xe7, 0x87, 0x00, 0x08, 0x22, 0xc0,
  734.     0x97, 0xcf, 0xe7, 0x07, 0x01, 0x01, 0xf0, 0x09,
  735.     0xef, 0x57, 0x18, 0x00, 0xfe, 0xff, 0x97, 0xc2,
  736.     0xef, 0x07, 0x00, 0x00, 0xf0, 0x09, 0x97, 0xcf,
  737.     0xd7, 0x09, 0x00, 0xc0, 0x17, 0x00, 0x17, 0x02,
  738.     0x97, 0x02, 0xe7, 0x57, 0x00, 0x00, 0x7a, 0x08,
  739.     0x06, 0xc0, 0xc0, 0x09, 0x92, 0xc0, 0xc0, 0x77,
  740.     0x09, 0x02, 0x9f, 0xc1, 0xea, 0x06, 0x9f, 0xcf,
  741.     0x20, 0x08, 0xd7, 0x09, 0x0e, 0xc0, 0xe7, 0x07,
  742.     0x00, 0x00, 0x0e, 0xc0, 0x9f, 0xaf, 0x66, 0x0e,
  743.     0xe7, 0x05, 0x0e, 0xc0, 0x97, 0xcf, 0xd7, 0x09,
  744.     0x00, 0xc0, 0x17, 0x02, 0xc8, 0x09, 0xb0, 0xc0,
  745.     0xe7, 0x67, 0xfe, 0x7f, 0xb0, 0xc0, 0xc8, 0x77,
  746.     0x00, 0x20, 0x9f, 0xc1, 0x64, 0xeb, 0xe7, 0x57,
  747.     0x00, 0x00, 0xc8, 0x02, 0x9f, 0xc1, 0x80, 0xeb,
  748.     0xc8, 0x99, 0xca, 0x02, 0xc8, 0x67, 0x04, 0x00,
  749.     0x9f, 0xc1, 0x96, 0xeb, 0x9f, 0xcf, 0x4c, 0xeb,
  750.     0xe7, 0x07, 0x00, 0x00, 0xa6, 0xc0, 0xe7, 0x09,
  751.     0xb0, 0xc0, 0xc8, 0x02, 0xe7, 0x07, 0x03, 0x00,
  752.     0xb0, 0xc0, 0x97, 0xcf, 0xc0, 0x09, 0x86, 0x08,
  753.     0xc0, 0x37, 0x01, 0x00, 0x97, 0xc9, 0xc9, 0x09,
  754.     0x88, 0x08, 0x02, 0x00, 0x41, 0x90, 0x48, 0x02,
  755.     0xc9, 0x17, 0x06, 0x00, 0x9f, 0xaf, 0x64, 0x05,
  756.     0x9f, 0xa2, 0xd6, 0x0e, 0x02, 0xda, 0x77, 0xc1,
  757.     0x41, 0x60, 0x71, 0xc1, 0x97, 0xcf, 0x17, 0x02,
  758.     0x57, 0x02, 0x43, 0x04, 0x21, 0x04, 0xe0, 0x00,
  759.     0x43, 0x04, 0x21, 0x04, 0xe0, 0x00, 0x43, 0x04,
  760.     0x21, 0x04, 0xe0, 0x00, 0xc1, 0x07, 0x01, 0x00,
  761.     0xc9, 0x05, 0xc8, 0x05, 0x97, 0xcf,
  762.     0,    0
  763. };
  764. /*
  765.  *     klsiNewCodeFix
  766.  */
  767. static UINT8 klsiNewCodeFix[] = 
  768. {
  769.     0xB6, 0xC3, 0xAA, 0xBB, 0xCC, 0xDD,
  770.     0x02, 0x00, 0x08, 0x00, 0x24, 0x00, 0x2e, 0x00,
  771.     0x2c, 0x00, 0x3e, 0x00, 0x44, 0x00, 0x48, 0x00,
  772.     0x50, 0x00, 0x5c, 0x00, 0x60, 0x00, 0x66, 0x00,
  773.     0x6c, 0x00, 0x70, 0x00, 0x76, 0x00, 0x74, 0x00,
  774.     0x7a, 0x00, 0x7e, 0x00, 0x84, 0x00, 0x8a, 0x00,
  775.     0x8e, 0x00, 0x92, 0x00, 0x98, 0x00, 0x9c, 0x00,
  776.     0xa0, 0x00, 0xa8, 0x00, 0xae, 0x00, 0xb4, 0x00,
  777.     0xb2, 0x00, 0xba, 0x00, 0xbe, 0x00, 0xc4, 0x00,
  778.     0xc8, 0x00, 0xce, 0x00, 0xd2, 0x00, 0xd6, 0x00,
  779.     0xda, 0x00, 0xe2, 0x00, 0xe0, 0x00, 0xea, 0x00,
  780.     0xf2, 0x00, 0xfe, 0x00, 0x06, 0x01, 0x0c, 0x01,
  781.     0x1a, 0x01, 0x24, 0x01, 0x22, 0x01, 0x2a, 0x01,
  782.     0x30, 0x01, 0x36, 0x01, 0x3c, 0x01, 0x4e, 0x01,
  783.     0x52, 0x01, 0x58, 0x01, 0x5c, 0x01, 0x9c, 0x01,
  784.     0xb6, 0x01, 0xba, 0x01, 0xc0, 0x01, 0xca, 0x01,
  785.     0xd0, 0x01, 0xda, 0x01, 0xe2, 0x01, 0xea, 0x01,
  786.     0xf0, 0x01, 0x0a, 0x02, 0x0e, 0x02, 0x14, 0x02,
  787.     0x26, 0x02, 0x6c, 0x02, 0x8e, 0x02, 0x98, 0x02,
  788.     0xa0, 0x02, 0xa6, 0x02, 0xba, 0x02, 0xc6, 0x02,
  789.     0xce, 0x02, 0xe8, 0x02, 0xee, 0x02, 0xf4, 0x02,
  790.     0xf8, 0x02, 0x0a, 0x03, 0x10, 0x03, 0x1a, 0x03,
  791.     0x1e, 0x03, 0x2a, 0x03, 0x2e, 0x03, 0x34, 0x03,
  792.     0x3a, 0x03, 0x44, 0x03, 0x4e, 0x03, 0x5a, 0x03,
  793.     0x5e, 0x03, 0x6a, 0x03, 0x72, 0x03, 0x80, 0x03,
  794.     0x84, 0x03, 0x8c, 0x03, 0x94, 0x03, 0x98, 0x03,
  795.     0xa8, 0x03, 0xae, 0x03, 0xb4, 0x03, 0xba, 0x03,
  796.     0xce, 0x03, 0xcc, 0x03, 0xd6, 0x03, 0xdc, 0x03,
  797.     0xec, 0x03, 0xf0, 0x03, 0xfe, 0x03, 0x1c, 0x04,
  798.     0x30, 0x04, 0x38, 0x04, 0x3c, 0x04, 0x40, 0x04,
  799.     0x48, 0x04, 0x46, 0x04, 0x54, 0x04, 0x5e, 0x04,
  800.     0x64, 0x04, 0x74, 0x04, 0x78, 0x04, 0x84, 0x04,
  801.     0xd8, 0x04, 0xec, 0x04, 0xf0, 0x04, 0xf8, 0x04,
  802.     0xfe, 0x04, 0x1c, 0x05, 0x2c, 0x05, 0x30, 0x05,
  803.     0x4a, 0x05, 0x56, 0x05, 0x5a, 0x05, 0x88, 0x05,
  804.     0x8c, 0x05, 0x96, 0x05, 0x9a, 0x05, 0xa8, 0x05,
  805.     0xcc, 0x05, 0xd2, 0x05, 0xda, 0x05, 0xe0, 0x05,
  806.     0xe4, 0x05, 0xfc, 0x05, 0x06, 0x06, 0x14, 0x06,
  807.     0x12, 0x06, 0x1a, 0x06, 0x20, 0x06, 0x26, 0x06,
  808.     0x2e, 0x06, 0x34, 0x06, 0x48, 0x06, 0x52, 0x06,
  809.     0x64, 0x06, 0x86, 0x06, 0x90, 0x06, 0x9a, 0x06,
  810.     0xa0, 0x06, 0xac, 0x06, 0xaa, 0x06, 0xb2, 0x06,
  811.     0xb8, 0x06, 0xdc, 0x06, 0xda, 0x06, 0xe2, 0x06,
  812.     0xe8, 0x06, 0xf2, 0x06, 0xf8, 0x06, 0xfc, 0x06,
  813.     0x0a, 0x07, 0x10, 0x07, 0x14, 0x07, 0x24, 0x07,
  814.     0x2a, 0x07, 0x32, 0x07, 0x38, 0x07, 0xb2, 0x07,
  815.     0xba, 0x07, 0xde, 0x07, 0xe4, 0x07, 0x10, 0x08,
  816.     0x14, 0x08, 0x1a, 0x08, 0x1e, 0x08, 0x30, 0x08,
  817.     0x38, 0x08, 0x3c, 0x08, 0x44, 0x08, 0x42, 0x08,
  818.     0x48, 0x08, 0xc6, 0x08, 0xcc, 0x08, 0xd2, 0x08,
  819.     0xfe, 0x08, 0x04, 0x09, 0x0a, 0x09, 0x0e, 0x09,
  820.     0x12, 0x09, 0x16, 0x09, 0x20, 0x09, 0x24, 0x09,
  821.     0x28, 0x09, 0x32, 0x09, 0x46, 0x09, 0x4a, 0x09,
  822.     0x50, 0x09, 0x54, 0x09, 0x5a, 0x09, 0x60, 0x09,
  823.     0x7c, 0x09, 0x80, 0x09, 0xb8, 0x09, 0xbc, 0x09,
  824.     0xc0, 0x09, 0xc4, 0x09, 0xc8, 0x09, 0xcc, 0x09,
  825.     0xd0, 0x09, 0xd4, 0x09, 0xec, 0x09, 0xf4, 0x09,
  826.     0xf6, 0x09, 0xf8, 0x09, 0xfa, 0x09, 0xfc, 0x09,
  827.     0xfe, 0x09, 0x00, 0x0a, 0x02, 0x0a, 0x04, 0x0a,
  828.     0x06, 0x0a, 0x08, 0x0a, 0x0a, 0x0a, 0x0c, 0x0a,
  829.     0x10, 0x0a, 0x18, 0x0a, 0x24, 0x0a, 0x2c, 0x0a,
  830.     0x32, 0x0a, 0x3c, 0x0a, 0x46, 0x0a, 0x4c, 0x0a,
  831.     0x50, 0x0a, 0x54, 0x0a, 0x5a, 0x0a, 0x5e, 0x0a,
  832.     0x66, 0x0a, 0x6c, 0x0a, 0x72, 0x0a, 0x78, 0x0a,
  833.     0x7e, 0x0a, 0x7c, 0x0a, 0x82, 0x0a, 0x8c, 0x0a,
  834.     0x92, 0x0a, 0x90, 0x0a, 0x98, 0x0a, 0x96, 0x0a,
  835.     0xa2, 0x0a, 0xb2, 0x0a, 0xb6, 0x0a, 0xc4, 0x0a,
  836.     0xe2, 0x0a, 0xe0, 0x0a, 0xe8, 0x0a, 0xee, 0x0a,
  837.     0xf4, 0x0a, 0xf2, 0x0a, 0xf8, 0x0a, 0x0c, 0x0b,
  838.     0x1a, 0x0b, 0x24, 0x0b, 0x40, 0x0b, 0x44, 0x0b,
  839.     0x48, 0x0b, 0x4e, 0x0b, 0x4c, 0x0b, 0x52, 0x0b,
  840.     0x68, 0x0b, 0x6c, 0x0b, 0x70, 0x0b, 0x76, 0x0b,
  841.     0x88, 0x0b, 0x92, 0x0b, 0xbe, 0x0b, 0xca, 0x0b,
  842.     0xce, 0x0b, 0xde, 0x0b, 0xf4, 0x0b, 0xfa, 0x0b,
  843.     0x00, 0x0c, 0x24, 0x0c, 0x28, 0x0c, 0x30, 0x0c,
  844.     0x36, 0x0c, 0x3c, 0x0c, 0x40, 0x0c, 0x4a, 0x0c,
  845.     0x50, 0x0c, 0x58, 0x0c, 0x56, 0x0c, 0x5c, 0x0c,
  846.     0x60, 0x0c, 0x64, 0x0c, 0x80, 0x0c, 0x94, 0x0c,
  847.     0x9a, 0x0c, 0x98, 0x0c, 0x9e, 0x0c, 0xa4, 0x0c,
  848.     0xa2, 0x0c, 0xa8, 0x0c, 0xac, 0x0c, 0xb0, 0x0c,
  849.     0xb4, 0x0c, 0xb8, 0x0c, 0xbc, 0x0c, 0xce, 0x0c,
  850.     0xd2, 0x0c, 0xd6, 0x0c, 0xf4, 0x0c, 0xfa, 0x0c,
  851.     0x00, 0x0d, 0xfe, 0x0c, 0x06, 0x0d, 0x0e, 0x0d,
  852.     0x0c, 0x0d, 0x16, 0x0d, 0x1c, 0x0d, 0x22, 0x0d,
  853.     0x20, 0x0d, 0x30, 0x0d, 0x7e, 0x0d, 0x82, 0x0d,
  854.     0x9a, 0x0d, 0xa0, 0x0d, 0xa6, 0x0d, 0xb0, 0x0d,
  855.     0xb8, 0x0d, 0xc2, 0x0d, 0xc8, 0x0d, 0xce, 0x0d,
  856.     0xd4, 0x0d, 0xdc, 0x0d, 0x1e, 0x0e, 0x2c, 0x0e,
  857.     0x3e, 0x0e, 0x4c, 0x0e, 0x50, 0x0e, 0x5e, 0x0e,
  858.     0xae, 0x0e, 0xb8, 0x0e, 0xc6, 0x0e, 0xca, 0x0e,
  859.     0,    0
  860. };
  861. const int  lenKlsiNewCode = sizeof (klsiNewCode);
  862. const int  lenKlsiNewCodeFix = sizeof (klsiNewCodeFix);
  863. LOCAL UINT16  initCount = 0; /* Count of init nesting */
  864. LOCAL MUTEX_HANDLE  klsiMutex; /* to protect internal structs */
  865. LOCAL LIST_HEAD klsiDevList; /* linked list of Device Structs */
  866. LOCAL LIST_HEAD     reqList;        /* Attach callback request list */
  867. LOCAL MUTEX_HANDLE  klsiTxMutex; /* to protect internal structs */
  868. LOCAL MUTEX_HANDLE  klsiRxMutex; /* to protect internal structs */
  869. /* forward declarartions */
  870. /* END Specific Externally imported interfaces. */
  871. IMPORT int  endMultiLstCnt  (END_OBJ* pEnd);
  872. /* Externally visible interfaces. */
  873. END_OBJ *  KlsiEndLoad  (char * initString);
  874. STATUS  usbKlsiEndInit  (void);
  875. /*  LOCAL functions */
  876. LOCAL STATUS klsiEndStart (KLSI_DEVICE * pDrvCtrl);
  877. LOCAL STATUS klsiEndStop (KLSI_DEVICE * pDrvCtrl);
  878. LOCAL int klsiEndIoctl    (KLSI_DEVICE * pDrvCtrl, 
  879.  int cmd, caddr_t data);
  880. LOCAL STATUS klsiEndUnload (KLSI_DEVICE * pDrvCtrl);
  881. LOCAL STATUS klsiEndSend (KLSI_DEVICE * pDrvCtrl, M_BLK_ID pBuf);
  882.   
  883. LOCAL STATUS klsiEndMCastAdd (KLSI_DEVICE * pDrvCtrl, char * pAddress);
  884. LOCAL STATUS klsiEndMCastDel (KLSI_DEVICE * pDrvCtrl, char * pAddress);
  885. LOCAL STATUS klsiEndMCastGet (KLSI_DEVICE * pDrvCtrl, 
  886.  MULTI_TABLE * pTable);
  887. LOCAL STATUS klsiEndPollSend (KLSI_DEVICE * pDrvCtrl, M_BLK_ID pBuf);
  888. LOCAL STATUS klsiEndPollRcv  (KLSI_DEVICE * pDrvCtrl, M_BLK_ID pBuf);
  889. LOCAL STATUS klsiEndParse (KLSI_DEVICE * pDrvCtrl,
  890.       char * initString,
  891. UINT16 * pVendorId,
  892.      UINT16 * pProductId
  893. );
  894. LOCAL STATUS klsiEndMemInit (KLSI_DEVICE * pDrvCtrl);
  895. LOCAL STATUS klsiEndConfig (KLSI_DEVICE * pDrvCtrl);
  896. LOCAL STATUS  klsiDevInit  (KLSI_DEVICE* pDevCtrl, 
  897.     UINT16 vendorId, 
  898.     UINT16 productId
  899. );
  900. LOCAL void  klsiTxCallback (pVOID p);
  901. LOCAL void  klsiRxCallback (pVOID p);
  902. LOCAL STATUS  klsiShutdown  (int errCode);
  903. LOCAL STATUS  klsiReset  (KLSI_DEVICE* pDevCtrl);
  904. LOCAL STATUS  klsiInit (KLSI_DEVICE * pDevCtrl);
  905. LOCAL STATUS  klsiSend (KLSI_DEVICE* pDevCtrl,UINT8* pBfr,
  906.  UINT32 size);
  907. LOCAL STATUS  klsiListenForInput    (KLSI_DEVICE * pDevCtrl);
  908. LOCAL USB_KLSI_DEV * klsiFindDevice (USBD_NODE_ID nodeId);
  909. LOCAL USB_KLSI_DEV * klsiEndFindDevice  (UINT16 vendorId, UINT16 productId);
  910. LOCAL void  klsiDestroyDevice  (KLSI_DEVICE * pDevCtrl);
  911. LOCAL STATUS  klsiMCastFilterSet  (KLSI_DEVICE* pDevCtrl,
  912.                      UINT8* pAddress,
  913.                  UINT32 noOfFilters);
  914. LOCAL STATUS  klsiPacketFilterSet  (KLSI_DEVICE* pDevCtrl,
  915.          UINT8 bitmap);
  916. LOCAL STATUS  klsiMacAddressSet (KLSI_DEVICE* pDevCtrl,
  917.                       UINT8 * pAddress);
  918. LOCAL void  klsiAttachCallback   (USBD_NODE_ID nodeId, 
  919.              UINT16 attachAction, 
  920.               UINT16 configuration,
  921.               UINT16 interface,
  922.               UINT16 deviceClass, 
  923.               UINT16 deviceSubClass, 
  924.               UINT16 deviceProtocol);
  925. LOCAL STATUS  klsiEndRecv (KLSI_DEVICE *pDrvCtrl, UINT8* pData, UINT32 len);
  926. LOCAL VOID  notifyAttach  (USBD_NODE_ID nodeId,
  927.       UINT16 attachCode);
  928. /*
  929.  * Our driver function table.  This is static across all driver instances.
  930.  */
  931. LOCAL NET_FUNCS klsiEndFuncTable =
  932.     {
  933.     (FUNCPTR) klsiEndStart, /* Function to start the device. */
  934.     (FUNCPTR) klsiEndStop, /* Function to stop the device. */
  935.     (FUNCPTR) klsiEndUnload, /* Unloading function for the driver. */
  936.     (FUNCPTR) klsiEndIoctl, /* Ioctl function for the driver. */
  937.     (FUNCPTR) klsiEndSend, /* Send function for the driver. */
  938.     (FUNCPTR) klsiEndMCastAdd, /* Multicast add function for the */
  939. /* driver. */
  940.     (FUNCPTR) klsiEndMCastDel, /* Multicast delete function for */
  941. /* the driver. */
  942.     (FUNCPTR) klsiEndMCastGet, /* Multicast retrieve function for */
  943. /* the driver. */
  944.     (FUNCPTR) klsiEndPollSend, /* Polling send function */
  945.     (FUNCPTR) klsiEndPollRcv, /* Polling receive function */
  946.     endEtherAddressForm, /* put address info into a NET_BUFFER */
  947.     endEtherPacketDataGet, /* get pointer to data in NET_BUFFER */
  948.     endEtherPacketAddrGet   /* Get packet addresses. */
  949.     };
  950. /***************************************************************************
  951. *
  952. * klsiAttachCallback - Gets called for attachment/detachment of devices
  953. *
  954. * The USBD will invoke this callback when a USB ethernet device is 
  955. * attached to or removed from the system.  
  956. * <nodeId> is the USBD_NODE_ID of the node being attached or removed.
  957. * <attachAction> is USBD_DYNA_ATTACH or USBD_DYNA_REMOVE.
  958. * Communication device functionality resides at the interface level, with
  959. * the exception of being the definition of the Communication device class
  960. * code.so <configuration> and <interface> will indicate the configuration
  961. * / interface that reports itself as a network device.
  962. * <deviceClass> and <deviceSubClass> will match the class/subclass for 
  963. * which registration is done.  
  964. * <deviceProtocol> doesn't have any meaning for the ethernet devices.
  965. * This field is ignored.
  966. *
  967. * NOTE: The USBD will invoke this function once for each configuration/
  968. * interface, which reports itself as a network device.
  969. * So, it is possible that a single device insertion/removal may trigger 
  970. * multiple callbacks. All callbacks are ignored except the first  
  971. * for a given device.
  972. *
  973. * RETURNS: N/A
  974. */
  975. LOCAL void  klsiAttachCallback
  976.     (
  977.     USBD_NODE_ID nodeId, 
  978.     UINT16 attachAction, 
  979.     UINT16 configuration,
  980.     UINT16 interface,
  981.     UINT16 deviceClass, 
  982.     UINT16 deviceSubClass, 
  983.     UINT16 deviceProtocol
  984.     )
  985.     {
  986.      
  987.     pUsbListDev pNewDev;
  988.     UINT8 bfr[30];
  989.     UINT16 actLen;
  990.     UINT16 vendorId;
  991.     UINT16 productId;
  992.     int noOfSupportedDevices = (sizeof (klsiAdapterList) /
  993.  (2 * sizeof (UINT16)));
  994.     int index = 0;
  995.     OSS_MUTEX_TAKE (klsiMutex, OSS_BLOCK);
  996.     switch (attachAction)
  997. {
  998. case USBD_DYNA_ATTACH :
  999.     /* a new device is found */
  1000.     KLSI_LOG (KLSI_DBG_ATTACH, 
  1001.                       "New Device found : %0x Class %0x Subclass %0x Protocol "
  1002.                       "%0x Configuration %0x Interface  %0x nodeId n", 
  1003.         deviceClass, deviceSubClass, deviceProtocol, 
  1004.       configuration, interface, (UINT)nodeId);
  1005.     /* First Ensure that this device is not already on the list */
  1006.  
  1007.     if (klsiFindDevice (nodeId) != NULL)
  1008. {
  1009. KLSI_LOG (KLSI_DBG_ATTACH, "Device already exists. n",
  1010.           0, 0, 0, 0, 0, 0);
  1011.         break;
  1012. }
  1013.     /* Now, Ensure that it is a KLSI device */
  1014.             if (usbdDescriptorGet (klsiHandle, 
  1015.    nodeId, 
  1016.    USB_RT_STANDARD | USB_RT_DEVICE, 
  1017.    USB_DESCR_DEVICE, 
  1018.    0, 
  1019.    0, 
  1020.    30, 
  1021.    bfr, 
  1022.    &actLen) 
  1023. != OK)
  1024.         {
  1025. break;
  1026.              }
  1027. #if 0
  1028.     for(index=0;index<actLen;index++)
  1029. printf(" 0x%x",bfr[index]);
  1030.     printf("n");
  1031. #endif
  1032.             vendorId = (*(bfr+9) << 8)&0xff00;
  1033.             vendorId |= *(bfr+8);
  1034.             productId = (*(bfr+11) << 8)&0xff00;
  1035.             productId |= *(bfr+10);
  1036.             for (index = 0; index < noOfSupportedDevices; index++)
  1037. if (vendorId == klsiAdapterList[index][0])
  1038.     if (productId == klsiAdapterList[index][1])
  1039. break;
  1040.   
  1041.     if (index == noOfSupportedDevices )
  1042. {
  1043. /* device not supported */
  1044. KLSI_LOG (KLSI_DBG_ATTACH, 
  1045.                           " Unsupported device found vId %0x; pId %0x! n", 
  1046.   vendorId, productId, 0, 0, 0, 0);
  1047. break;
  1048. }
  1049.        KLSI_LOG (KLSI_DBG_ATTACH, 
  1050.                       " Found a KLSI Adapter!  %0x  %0xn", 
  1051.                       vendorId, productId, 0, 0, 0, 0);
  1052.     /* 
  1053.      * Now create a strcture for the newly found device and add 
  1054.      * it to the linked list 
  1055.      */
  1056.             /* Try to allocate space for a new device struct */
  1057.     if ((pNewDev = OSS_CALLOC (sizeof (*pNewDev))) == NULL)
  1058.        {
  1059. break;     
  1060. }
  1061.     /* Fill in the device structure */
  1062.     pNewDev->nodeId = nodeId;
  1063.     pNewDev->configuration = configuration;
  1064.     pNewDev->interface = interface;
  1065.     pNewDev->vendorId = vendorId;
  1066.     pNewDev->productId = productId;
  1067.     /* Add this device to the linked list */
  1068.     usbListLink (&klsiDevList, pNewDev, &pNewDev->devLink, 
  1069.  LINK_TAIL);
  1070.  /* Notify registered callers that a klsi device has been added */
  1071.     notifyAttach (pNewDev->nodeId, USB_KLSI_ATTACH);  /*##*/
  1072.     break;
  1073. case USBD_DYNA_REMOVE:
  1074.     KLSI_LOG (KLSI_DBG_ATTACH, "Device Removed  %x n", (int) nodeId,
  1075.     0, 0, 0, 0, 0);
  1076.   /* First Ensure that this device is on the list */
  1077.     if ((pNewDev = klsiFindDevice (nodeId)) == NULL)
  1078.         break;
  1079.      /* Check the connected flag  */
  1080.             if (pNewDev->connected == FALSE)
  1081.                 break;    
  1082.      
  1083.      pNewDev->connected = FALSE;
  1084.     /* Notify registered callers that the klsi device has been
  1085.      * removed 
  1086.      *
  1087.      * NOTE: We temporarily increment the device's lock count
  1088.      * to prevent usbKlsiDevUnlock() from destroying the
  1089.      * structure while we're still using it.
  1090.      */
  1091.             pNewDev->lockCount++; 
  1092.             notifyAttach (pNewDev->nodeId, USB_KLSI_REMOVE); 
  1093.             pNewDev->lockCount--; 
  1094.     if (pNewDev->lockCount == 0)
  1095. klsiDestroyDevice((KLSI_DEVICE *)pNewDev->pDevStructure);
  1096.     break;
  1097. }
  1098.     OSS_MUTEX_RELEASE (klsiMutex);
  1099.     }
  1100. /***************************************************************************
  1101. *
  1102. * usbKlsiEndInit - Initializes the klsi Library
  1103. *
  1104. * Initizes the klsi Library. The Library maintains an initialization
  1105. * count so that the calls to this function can be nested.
  1106. *
  1107. * This function initializes the system resources required for the library
  1108. * initializes the linked list for the ethernet devices found.
  1109. * This function registers the library as a client for the USBD calls and 
  1110. * registers for dynamic attachment notification of USB communication device
  1111. * class and Ethernet sub class of devices.
  1112. *
  1113. * This function is to be called after the USBD initialization and before 
  1114. * the endStart gets called. Otherwise the Library can't perform.
  1115. *
  1116. * RETURNS : OK or ERROR
  1117. *
  1118. * ERRNO :
  1119. *
  1120. * S_klsiLib_OUT_OF_RESOURCES
  1121. * S_klsiLib_USBD_FAULT
  1122. */
  1123. STATUS usbKlsiEndInit (void)
  1124.     {
  1125.  
  1126.     /* see if already initialized. if not, initialize the library */
  1127.     initCount++;
  1128.     if(initCount != 1) /* already registered */
  1129. return OK;
  1130.     /* 
  1131.      * Initialize USBD
  1132.      * The assumption is made that the USB host stack has already been
  1133.      * initialized elsewhere.  
  1134.      */
  1135.     /* usbdInitialize(); */
  1136.     memset (&klsiDevList, 0, sizeof (klsiDevList));
  1137.     
  1138.     klsiMutex = NULL;
  1139.     klsiTxMutex = NULL;
  1140.     klsiRxMutex = NULL;
  1141.     klsiHandle = NULL;
  1142.     /* create the mutex */
  1143.     if (OSS_MUTEX_CREATE (&klsiMutex) != OK)
  1144. return klsiShutdown (S_usbKlsiLib_OUT_OF_RESOURCES);
  1145.     
  1146.     if (OSS_MUTEX_CREATE (&klsiTxMutex) != OK)
  1147. return klsiShutdown (S_usbKlsiLib_OUT_OF_RESOURCES);
  1148.     
  1149.     if (OSS_MUTEX_CREATE (&klsiRxMutex) != OK)
  1150. return klsiShutdown (S_usbKlsiLib_OUT_OF_RESOURCES);
  1151.     /* 
  1152.      * Register the Library as a Client and register for 
  1153.      * dynamic attachment callback.
  1154.      */
  1155.     /* 
  1156.      if((usbdClientRegister (KLSI_CLIENT_NAME, &klsiHandle) != OK) ||
  1157. usbdDynamicAttachRegister (klsiHandle, 
  1158.    USB_CLASS_COMMDEVICE, 
  1159.    USB_SUBCLASS_ENET, 
  1160.    USBD_NOTIFY_ALL, 
  1161.    klsiAttachCallback) 
  1162. != OK))
  1163. {
  1164.      return klsiShutdown (S_klsiLib_USBD_FAULT);
  1165. }
  1166.     */
  1167.     /*
  1168.      * The above registration doesn't work for KLSI chip based adapters.
  1169.      * This is because the chip doesn't show up as a communications class
  1170.      * device. It shows up as  a proprietary device. Decifering that a 
  1171.      * given device is a KLSI device is done from its product ID and
  1172.      * vendor ID. This is done in the dynamic attachment call back function.
  1173.      */
  1174.      if((usbdClientRegister (KLSI_CLIENT_NAME, &klsiHandle) != OK) ||
  1175. (usbdDynamicAttachRegister (klsiHandle, 
  1176.     USBD_NOTIFY_ALL, 
  1177.     USBD_NOTIFY_ALL, 
  1178.     USBD_NOTIFY_ALL, 
  1179.     (USBD_ATTACH_CALLBACK) klsiAttachCallback)
  1180.  != OK))
  1181. {
  1182. logMsg(" Registration Failed..n", 0, 0, 0, 0, 0, 0);
  1183.      return klsiShutdown (S_usbKlsiLib_USBD_FAULT);
  1184. }
  1185.     
  1186.     return OK;
  1187.     }
  1188. /***************************************************************************
  1189. *
  1190. * findEndpoint - Searches for a BULK endpoint of the indicated direction.
  1191. *
  1192. * RETURNS: pointer to matching endpoint descriptor or NULL if not found
  1193. */
  1194. LOCAL pUSB_ENDPOINT_DESCR findEndpoint
  1195.     (
  1196.     pUINT8 pBfr, /* buffer to search for */
  1197.     UINT16 bfrLen, /* buffer length */
  1198.     UINT16 direction /* end point direction */
  1199.     )
  1200.     {
  1201.     pUSB_ENDPOINT_DESCR pEp;
  1202.     while ((pEp = (pUSB_ENDPOINT_DESCR) 
  1203.           usbDescrParseSkip (&pBfr, &bfrLen, USB_DESCR_ENDPOINT)) 
  1204.    != NULL)
  1205. {
  1206. if ((pEp->attributes & USB_ATTR_EPTYPE_MASK) == USB_ATTR_BULK &&
  1207.     (pEp->endpointAddress & USB_ENDPOINT_DIR_MASK) == direction)
  1208.     break;
  1209. }
  1210.     return pEp;
  1211.     }
  1212. /***************************************************************************
  1213. *
  1214. * klsiDevInit - Initializes the klsi Device structure.
  1215. *
  1216. * This function initializes the USB ethernet device. It is called by 
  1217. * klsiEndLoad() as part of the end driver initialization. klsiEndLoad()
  1218. * expects this routine to perform all the device and USB specific 
  1219. * initialization and fill in the corresponding member fields in the 
  1220. * KLSI_DEVICE structure.
  1221. *
  1222. * This function first checks to see if the device corresponding to
  1223. * <vendorId> and <productId> exits in the linkedlist klsiDevList.
  1224. * It allocates memory for the input and output buffers. The device 
  1225. * descriptors are retrieved andused to findout the IN and OUT
  1226. * bulk end points. Once the end points are found, the corresponding
  1227. * pipes are constructed. The Pipe handles are stored in the device 
  1228. * structure <pDevCtrl>. The device's Ethernet Address (MAC address) 
  1229. * is retrieved and the corresponding field in the device structure
  1230. * is updated. This is followed by setting up of the parameters 
  1231. * like Multicast address filter list, Packet Filter bitmap etc.
  1232. *
  1233. * RETURNS : OK or ERROR
  1234. *
  1235. */
  1236. STATUS klsiDevInit
  1237.     (
  1238.     KLSI_DEVICE* pDevCtrl, /* the device structure to be updated */
  1239.     UINT16 vendorId, /* manufacturer id of the device */
  1240.     UINT16 productId     /* product id of the device */
  1241.     )
  1242.     {
  1243.     USB_KLSI_DEV* pNewDev;
  1244.     pUSB_CONFIG_DESCR pCfgDescr;
  1245.     pUSB_INTERFACE_DESCR pIfDescr;
  1246.     pUSB_ENDPOINT_DESCR pOutEp;
  1247.     pUSB_ENDPOINT_DESCR pInEp;
  1248.     
  1249.     KLSI_ENET_IRP * pIrpBfrs;
  1250.     UINT8 bfr[30];   
  1251.     pUINT8 pBfr;
  1252.     UINT8** pInBfr;
  1253.     UINT16 actLen;
  1254.     
  1255.     int index = 0;
  1256.     if(pDevCtrl == NULL)
  1257. {
  1258. KLSI_LOG (KLSI_DBG_INIT,"Null Device n", 0, 0, 0, 0, 0, 0);
  1259. return ERROR;
  1260. }
  1261.     /* Find if the device is in the found devices list */
  1262.      
  1263.     if ((pNewDev = klsiEndFindDevice (vendorId,productId)) == NULL)
  1264. {
  1265. printf("Could not find KLSI device.n");
  1266. return ERROR;
  1267. }
  1268.     /* Link the End Structure and the device that is found */
  1269.     pDevCtrl->pDev = pNewDev;
  1270.     /* Allocate memory for the input and output buffers..*/
  1271.     if ((pIrpBfrs = (KLSI_ENET_IRP *) memalign (sizeof(ULONG), 
  1272. pDevCtrl->noOfIrps * 
  1273. sizeof (KLSI_ENET_IRP))) 
  1274.  == NULL)
  1275. {
  1276. KLSI_LOG (KLSI_DBG_INIT,"Could not allocate memory for IRPs.n",
  1277.      0, 0, 0, 0, 0, 0);
  1278. return ERROR;
  1279. }
  1280.     if ((pInBfr = (pUINT8*) memalign (sizeof(ULONG),
  1281.          pDevCtrl->noOfInBfrs * sizeof (char *))) 
  1282.      ==NULL)
  1283. {
  1284. KLSI_LOG (KLSI_DBG_INIT,"Could Not align Memory for pInBfrs ...n",
  1285.          0, 0, 0, 0, 0, 0);
  1286.         return ERROR;
  1287.         }
  1288.     for (index=0;index<pDevCtrl->noOfInBfrs;index++)
  1289. {
  1290. if ((pInBfr[index] = (pUINT8)memalign(sizeof(ULONG),
  1291.    KLSI_IN_BFR_SIZE+8)) == NULL)
  1292.    {
  1293.    KLSI_LOG (KLSI_DBG_INIT,"Could Not align Memory for InBfrs  %d...n",
  1294.     index, 0, 0, 0, 0, 0);
  1295.    return ERROR;
  1296.    }
  1297. }
  1298.     pDevCtrl->pEnetIrp = pIrpBfrs;
  1299.     pDevCtrl->pInBfrArray = pInBfr;
  1300.     for (index = 0; index < pDevCtrl->noOfIrps; index++)
  1301.         {
  1302.         pIrpBfrs->outIrpInUse = FALSE;
  1303.         pIrpBfrs ++;
  1304.         }
  1305.     pDevCtrl->rxIndex = 0;    
  1306.     pDevCtrl->txIrpIndex = 0;
  1307.     pDevCtrl->outBfrLen = KLSI_OUT_BFR_SIZE;
  1308.     pDevCtrl->inBfrLen = KLSI_IN_BFR_SIZE;
  1309.    
  1310.     /* Do the device specific initialization */
  1311.     
  1312.     klsiInit (pDevCtrl);
  1313.     /* 
  1314.      * Decifer the descriptors provided by the device 
  1315.      * and try to find out which end point is what.
  1316.      * Here it is assumed that there aren't any alternate 
  1317.      * settings for interfaces.
  1318.      */
  1319.     /* To start with, get the configuration descriptor */
  1320.     if (usbdDescriptorGet (klsiHandle, 
  1321.    pNewDev->nodeId, 
  1322.    USB_RT_STANDARD | USB_RT_DEVICE, 
  1323.    USB_DESCR_CONFIGURATION, 
  1324.    0, 
  1325.    0, 
  1326.    sizeof (bfr), 
  1327.    bfr, 
  1328.    &actLen) 
  1329.    != OK)
  1330. {
  1331. KLSI_LOG (KLSI_DBG_INIT, "Could not GET Descriptor.n",
  1332.      0, 0, 0, 0, 0, 0);
  1333. return ERROR;
  1334. }
  1335.     if ((pCfgDescr = (pUSB_CONFIG_DESCR) 
  1336. usbDescrParse (bfr, actLen, USB_DESCR_CONFIGURATION)) == NULL)
  1337. {
  1338. KLSI_LOG (KLSI_DBG_INIT, "Could not find Config. Descriptor.n",
  1339.      0, 0, 0, 0, 0, 0);
  1340. return ERROR;
  1341. }
  1342.     pBfr = bfr;
  1343.     /*
  1344.      * Since we registered for NOTIFY_ALL for attachment of devices,
  1345.      * the configuration no. and interface number as reported by the 
  1346.      * call back function doesn't have any meaning. The KLSI document 
  1347.      * says that it has only one interface with number 0. So the first 
  1348.      * (and only) interface found is the interface desited. 
  1349.      *  
  1350.      * If there are more interfaces and one of them meet our requirement
  1351.      * (as reported by callback function), then we need to parse
  1352.      * until the desired interface is found..
  1353.      */
  1354.     /* 
  1355.      * pBfr and bfr are needed in case there are multiple interfaces,
  1356.      * to allow multiple parses.
  1357.      */
  1358.         
  1359.     if ((pIfDescr = (pUSB_INTERFACE_DESCR) 
  1360. usbDescrParseSkip (&pBfr, &actLen, USB_DESCR_INTERFACE)) == NULL)
  1361. {
  1362. KLSI_LOG (KLSI_DBG_INIT, "Could not find Interface Descriptor.n",
  1363.      0, 0, 0, 0, 0, 0);
  1364.      return ERROR;
  1365. }
  1366.     
  1367.      /* Find out the output and input end points ... */
  1368.     if ((pOutEp = findEndpoint (pBfr, actLen, USB_ENDPOINT_OUT)) == NULL)
  1369. {
  1370. KLSI_LOG (KLSI_DBG_INIT, "No Output End Point. n",
  1371.      0, 0, 0, 0, 0, 0);
  1372. return ERROR;
  1373. }
  1374.     if ((pInEp = findEndpoint (pBfr, actLen, USB_ENDPOINT_IN)) == NULL)
  1375. {
  1376. KLSI_LOG (KLSI_DBG_INIT, "No Input End Point. n",
  1377.      0, 0, 0, 0, 0, 0);
  1378. return ERROR;
  1379. }
  1380.     pDevCtrl->maxPower = pCfgDescr->maxPower; 
  1381.     /*
  1382.      * Now, set the configuration.
  1383.      * Note that any ConfigurationSet request will reset the device.
  1384.      * Thus, an explicit device reset is not required 
  1385.      */
  1386.     if (usbdConfigurationSet (klsiHandle, 
  1387.       pNewDev->nodeId, 
  1388.       pCfgDescr->configurationValue, 
  1389.       pCfgDescr->maxPower * USB_POWER_MA_PER_UNIT) 
  1390.    != OK)
  1391. return ERROR;
  1392.  
  1393.     /* Now, Create the Pipes... */
  1394.     if (usbdPipeCreate (klsiHandle, 
  1395. pNewDev->nodeId, 
  1396. pOutEp->endpointAddress, 
  1397. pCfgDescr->configurationValue, 
  1398. pNewDev->interface, 
  1399. USB_XFRTYPE_BULK, 
  1400. USB_DIR_OUT, 
  1401. FROM_LITTLEW (pOutEp->maxPacketSize), 
  1402. 0, 
  1403. 0, 
  1404. &pDevCtrl->outPipeHandle) 
  1405. != OK)
  1406. {
  1407. KLSI_LOG (KLSI_DBG_INIT, "Output Pipe could not be created. n",
  1408.      0, 0, 0, 0, 0, 0);
  1409. return ERROR;
  1410. }
  1411.     
  1412.     if (usbdPipeCreate (klsiHandle, 
  1413. pNewDev->nodeId, 
  1414. pInEp->endpointAddress, 
  1415. pCfgDescr->configurationValue, 
  1416. pNewDev->interface, 
  1417. USB_XFRTYPE_BULK, 
  1418. USB_DIR_IN, 
  1419. FROM_LITTLEW (pInEp->maxPacketSize), 
  1420. 0, 
  1421. 0, 
  1422. &pDevCtrl->inPipeHandle) 
  1423.     != OK)       
  1424. {
  1425. KLSI_LOG (KLSI_DBG_INIT, "Input Pipe could not be created n",
  1426.            0, 0, 0, 0, 0, 0);
  1427. return ERROR;
  1428. }
  1429.     pDevCtrl->inIrpInUse = FALSE;
  1430.     /* 
  1431.      * Read the (Ethernet) Function Descriptor and get the details.
  1432.      * Though this is described as a "descriptor", it is a vendor specific 
  1433.      * command for KLSI and is a control Pipe 0 transaction.
  1434.      */
  1435.    
  1436.     if (usbdDescriptorGet (klsiHandle, 
  1437.    pNewDev->nodeId, 
  1438.    USB_RT_STANDARD | USB_RT_DEVICE, 
  1439.    USB_DESCR_STRING, 
  1440.    1, 
  1441.    0x409, 
  1442.    sizeof (bfr), 
  1443.    bfr, 
  1444.    &actLen) 
  1445. != OK)
  1446. {
  1447. KLSI_LOG (KLSI_DBG_INIT, "Could not GET String Descriptor.n",
  1448.      0, 0, 0, 0, 0, 0);
  1449. return ERROR;
  1450. }
  1451.     /* UNICODE to ASCII conversion and then finally to MAC Address */
  1452.     if (usbdVendorSpecific (klsiHandle, 
  1453.       pNewDev->nodeId, 
  1454.       USB_RT_VENDOR |USB_RT_DEV_TO_HOST, 
  1455.       USB_REQ_KLSI_ETHDESC_GET, 
  1456.       0, 
  1457.       0, 
  1458.       sizeof(bfr), 
  1459.       bfr, 
  1460.       &actLen) 
  1461.     != OK)
  1462. {
  1463. KLSI_LOG (KLSI_DBG_INIT, "Error retrieving Ethernet descriptor. n",
  1464.                   0, 0, 0, 0, 0, 0);
  1465. return ERROR;
  1466. }
  1467. #if 0
  1468.     printf("Eth Desc = "); 
  1469.     for(index=0;index<actLen;index++)
  1470. printf("%x ",bfr[index]);
  1471.     printf("n");
  1472. #endif
  1473.     for (index = 0; index< 6; index++)
  1474. {
  1475. pDevCtrl->macAdrs[index] = bfr[3+index];
  1476. }
  1477. #if 0    
  1478.     printf("MAC Addrs = "); 
  1479.     for(index=0;index<6;index++)
  1480. printf("%x ",pDevCtrl->macAdrs[index]);
  1481.     printf("n");
  1482. #endif
  1483.  
  1484.     /* Set URB Size */
  1485.     if (usbdVendorSpecific (klsiHandle, 
  1486.     pNewDev->nodeId, 
  1487.     USB_RT_VENDOR |USB_RT_HOST_TO_DEV, 
  1488.     USB_REQ_KLSI_SET_URB_SIZE, 
  1489.     64, 
  1490.     0, 
  1491.     0, 
  1492.     NULL, 
  1493.     NULL) 
  1494. != OK)
  1495. {
  1496. KLSI_LOG (KLSI_DBG_INIT, "Error Setting URB Size. n",
  1497.   0, 0, 0, 0, 0, 0);
  1498. return ERROR;
  1499. }
  1500.      
  1501.     if (usbdVendorSpecific (klsiHandle, 
  1502.     pNewDev->nodeId, 
  1503.     USB_RT_VENDOR |USB_RT_HOST_TO_DEV, 
  1504.     USB_REQ_KLSI_SET_SOFS_TO_WAIT, 
  1505.     0x1, 
  1506.     0, 
  1507.     0, 
  1508.     NULL, 
  1509.     NULL) 
  1510.   != OK)
  1511. {
  1512. KLSI_LOG (KLSI_DBG_INIT, "Error setting SOFs n",
  1513.   0, 0, 0, 0, 0, 0);
  1514. return ERROR;
  1515. }
  1516.     
  1517.     /* Set No Multicasting */
  1518.     if (usbdVendorSpecific (klsiHandle, 
  1519.     pNewDev->nodeId, 
  1520.     USB_RT_VENDOR |USB_RT_HOST_TO_DEV, 
  1521.     USB_REQ_KLSI_SET_MCAST_FILTER, 
  1522.     0, 
  1523.     0, 
  1524.     0, 
  1525.     NULL, 
  1526.     NULL) 
  1527.   != OK)
  1528. {
  1529. KLSI_LOG (KLSI_DBG_INIT, "Error setting Multicast Addresses n",
  1530.   0, 0, 0, 0, 0, 0);
  1531. return ERROR;
  1532. }
  1533.     /* Set Only directed Packets to be received */
  1534.     
  1535.     if (usbdVendorSpecific (klsiHandle, 
  1536.     pNewDev->nodeId, 
  1537.     USB_RT_VENDOR |USB_RT_HOST_TO_DEV, 
  1538.     USB_REQ_KLSI_SET_PACKET_FILTER, 
  1539.     0x0004, 
  1540.     0, 
  1541.     0, 
  1542.     NULL, 
  1543.     NULL) 
  1544.  != OK)
  1545. {
  1546. KLSI_LOG (KLSI_DBG_INIT, "Error setting packet bitmap. n",
  1547.      0, 0, 0, 0, 0, 0);
  1548. return ERROR;
  1549. }
  1550.     return OK;
  1551.     }
  1552. /***************************************************************************
  1553. *
  1554. * klsiEndStart - Starts communications over Ethernet via USB (device)
  1555. *
  1556. * Since there is no interrupt available, the device is to be prevented from 
  1557. * communicating in some other way. Here, since the reception is based 
  1558. * on polling and the klsiListenForInput() is called for such polling,
  1559. * the listening can be delayed to any packet coming in  by calling
  1560. * klsiListenForInput(). This way, the traditional "interrupt enabling"   
  1561. * is mimicked. This is for packet reception.
  1562. *
  1563. * For packet transmission, communicateOk flag is used. Data is transmitted 
  1564. * only if this flag is true. This flag will be set to TRUE and will be
  1565. * reset to FALSE in klsiEndStop().
  1566. *
  1567. * RETURNS : OK or ERROR
  1568. */
  1569. STATUS klsiEndStart
  1570.     (
  1571.     KLSI_DEVICE* pDevCtrl         /* Device to be started */
  1572.     )
  1573.     {
  1574.     KLSI_LOG (KLSI_DBG_START, "Entered klsiEndStart.n",
  1575.  0, 0, 0, 0, 0, 0);
  1576.     
  1577.     /*
  1578.      * start listening on the BULK input pipe for any  
  1579.      *  ethernet packet coming in. This is how   
  1580.      * "connecting the interrupt" of the END Model is simulated.
  1581.      */
  1582.     pDevCtrl->communicateOk = TRUE;
  1583.     if (klsiListenForInput (pDevCtrl) != OK)
  1584. {
  1585.         pDevCtrl->communicateOk = FALSE;
  1586.         KLSI_LOG (KLSI_DBG_START, 
  1587.                   "klsiEndStart:..Unable to listen for input...n",
  1588.                   0, 0, 0, 0, 0, 0);
  1589. return ERROR;
  1590. }
  1591.     /* 
  1592.      * The above will effectively preempt any possibility of packet reception.
  1593.      * For preempting such possibility for transmission, the communicateOk 
  1594.      * flag is used. Ideally a semaphore should be used here, but
  1595.      * the use of a flag will suffice.
  1596.      */
  1597.     return OK;
  1598.     }
  1599. /***************************************************************************
  1600. *
  1601. * klsiEndStop - Disables communication over Ethernet via USB (device)
  1602. * The pipes will be aborted. If there are any pending transfers on these
  1603. * Pipes, USBD will see to it that they are also cancelled. The IRPs for
  1604. * these transfers will return a S_usbHcdLib_IRP_CANCELED error code.
  1605. * It waits for the IRPs to be informed of their Cancelled Status and then
  1606. * the function returns.
  1607. * RETURNS: OK or ERROR
  1608. */
  1609. STATUS klsiEndStop
  1610.     (
  1611.     KLSI_DEVICE* pDevCtrl     /* Device to be Stopped */
  1612.     )
  1613.     {
  1614.     KLSI_LOG (KLSI_DBG_STOP, "klsiEndStop:..entered.n",
  1615.       0, 0, 0, 0, 0, 0);
  1616.     /* 
  1617.      * Abort the transfers the input and output Pipes.
  1618.      * once such requests are issued, usbd will take care of aborting the 
  1619.      * outstanding transfers, if any, associated with the Pipes.
  1620.      */
  1621.     pDevCtrl->communicateOk = FALSE;
  1622.     klsiDestroyDevice(pDevCtrl);
  1623.     taskDelay(sysClkRateGet()*5);
  1624.     return OK;
  1625.     }
  1626. /***************************************************************************
  1627. * klsiListenForInput - Listens for data on the ethernet (Bulk In Pipe) 
  1628. *
  1629. * Input IRP will be initialized to listen on the BULK input pipe and will
  1630. * be submitted to the usbd.
  1631. *
  1632. * RETURNS : OK or ERROR
  1633. *
  1634. */
  1635.      
  1636. LOCAL STATUS klsiListenForInput
  1637.     (
  1638.     KLSI_DEVICE* pDevCtrl /* device to receive from */
  1639.     )
  1640.     {
  1641.     pUSB_IRP pIrp = &pDevCtrl->inIrp;
  1642.     if (pDevCtrl == NULL)
  1643. return ERROR;
  1644.     /* Initialize IRP */
  1645.     memset (pIrp, 0, sizeof (*pIrp));
  1646.     pIrp->userPtr = pDevCtrl;
  1647.     pIrp->irpLen = sizeof (*pIrp);
  1648.     pIrp->userCallback = klsiRxCallback;
  1649.     pIrp->timeout = USB_TIMEOUT_DEFAULT;
  1650.     pIrp->transferLen = pDevCtrl->inBfrLen; 
  1651.     pIrp->flags = USB_FLAG_SHORT_OK;
  1652.     pIrp->bfrCount = 1;
  1653.     pIrp->bfrList[0].pid = USB_PID_IN;
  1654.     pIrp->bfrList[0].bfrLen = pDevCtrl->inBfrLen; 
  1655.     pIrp->bfrList[0].pBfr = (pUINT8)pDevCtrl->pInBfrArray[pDevCtrl->rxIndex] - 2;  
  1656.     /* Submit IRP */
  1657.     if (usbdTransfer (klsiHandle, pDevCtrl->inPipeHandle, (pUSB_IRP)pIrp) != OK)
  1658. return ERROR;
  1659.     pDevCtrl->inIrpInUse = TRUE;
  1660.     return OK;
  1661.     }
  1662. /***************************************************************************
  1663. *
  1664. * klsiSend - Initiates data transmission to the device
  1665. *
  1666. * This function initiates transmission on the ethernet.
  1667. *
  1668. * RETURNS: OK or ERROR
  1669. */
  1670. STATUS klsiSend
  1671.     (
  1672.     KLSI_DEVICE* pDevCtrl, /* device to send to */
  1673.     UINT8* pBfr, /* data to send */
  1674.     UINT32 size /* data size */
  1675.     )
  1676.     {
  1677.     pUSB_IRP pIrp;       /* = &pDevCtrl->outIrp; */
  1678.     KLSI_ENET_IRP * pIrpBfr;
  1679.     KLSI_LOG (KLSI_DBG_TX, "klsiSend:..entered. %d bytesn", 
  1680.       size, 0, 0, 0, 0, 0); 
  1681.     if ((pDevCtrl == NULL) || (pBfr == NULL))
  1682. {
  1683. return ERROR;
  1684. }
  1685.     if (size == 0)
  1686. return ERROR;
  1687.     pIrpBfr = (KLSI_ENET_IRP *)(pDevCtrl->pEnetIrp + pDevCtrl->txIrpIndex);
  1688.     pIrp =(pUSB_IRP) &pIrpBfr->outIrp;
  1689.     pIrpBfr->outIrpInUse = TRUE;
  1690.     pDevCtrl->txIrpIndex++;
  1691.     pDevCtrl->txIrpIndex %= pDevCtrl->noOfIrps;
  1692.     /* Initialize IRP */
  1693.     memset (pIrp, 0, sizeof (*pIrp));
  1694.     pIrp->userPtr = pDevCtrl;
  1695.     pIrp->irpLen = sizeof (*pIrp);
  1696.     pIrp->userCallback = klsiTxCallback;
  1697.     pIrp->timeout = USB_TIMEOUT_NONE;
  1698.     pIrp->transferLen = size;
  1699.     pIrp->bfrCount = 1;
  1700.     pIrp->bfrList[0].pid = USB_PID_OUT;
  1701.     pIrp->bfrList[0].pBfr = pBfr;
  1702.     pIrp->bfrList[0].bfrLen = size;
  1703.     /* Submit IRP */
  1704.     KLSI_LOG (KLSI_DBG_TX, "klsiSend:..Sumitting IRP for Trans. %d bytesn", 
  1705.  size, 0, 0, 0, 0, 0); 
  1706.     if (usbdTransfer (klsiHandle, 
  1707. pDevCtrl->outPipeHandle, 
  1708. (pUSB_IRP)pIrp) 
  1709. != OK)
  1710. return ERROR;
  1711.     KLSI_LOG (KLSI_DBG_TX, "klsiSend:..done !!!!!!n", 
  1712.  0, 0, 0, 0, 0, 0); 
  1713. /*    OSS_MUTEX_RELEASE (klsiMutex); */
  1714.  
  1715.     return OK;
  1716.     }
  1717. /***************************************************************************
  1718. *
  1719. * klsiTxCallback - Invoked upon Transmit IRP completion/cancellation
  1720. *
  1721. * RETURNS : N/A
  1722. *
  1723. */
  1724. LOCAL void klsiTxCallback
  1725.     (
  1726.     pVOID p /* completed IRP */
  1727.     )
  1728.     {
  1729.     pUSB_IRP pIrp = (pUSB_IRP) p;
  1730.     KLSI_ENET_IRP * pIrpBfr;
  1731.     int index = 0;
  1732.     KLSI_DEVICE* pDevCtrl = pIrp->userPtr;
  1733.     /* Output IRP completed */
  1734.     for (index = 0; index < pDevCtrl->noOfIrps; index++)
  1735. {
  1736. pIrpBfr = pDevCtrl->pEnetIrp + index;
  1737. if (pIrp ==(pUSB_IRP) &pIrpBfr->outIrp)
  1738.     {
  1739.     break;
  1740.     }
  1741. }
  1742.    
  1743.     if (index == pDevCtrl->noOfIrps)
  1744. {
  1745. return;
  1746. }
  1747.  
  1748.     KLSI_LOG (KLSI_DBG_TX, "Tx Callback for  %d IRP.n",
  1749.     index, 0, 0, 0, 0, 0);
  1750.     pIrpBfr = pDevCtrl->pEnetIrp + index;
  1751.     pIrpBfr->outIrpInUse = FALSE;
  1752.      
  1753.     free (pIrp->bfrList[0].pBfr);
  1754.     if (pIrp->result != OK)
  1755. {
  1756.         KLSI_LOG (KLSI_DBG_TX, "Tx error %x.n",
  1757.     pIrp->result, 0, 0, 0, 0, 0);
  1758. if (pIrp->result == S_usbHcdLib_STALLED)
  1759.     {
  1760.        if (usbdFeatureClear (klsiHandle, 
  1761.   pDevCtrl->pDev->nodeId,
  1762.   USB_RT_STANDARD | USB_RT_ENDPOINT, 
  1763.   0, 
  1764.   1) == ERROR)
  1765. {
  1766.         KLSI_LOG (KLSI_DBG_TX, "Could not clear STALL.n",
  1767.              pIrp->result, 0, 0, 0, 0, 0);
  1768. }
  1769.     }
  1770.   
  1771.         pDevCtrl->outErrors++; /* Should also Update MIB */
  1772. }
  1773.     else
  1774. {
  1775.             KLSI_LOG (KLSI_DBG_TX, "Tx finished.n",
  1776.       0, 0, 0, 0, 0, 0);
  1777. }
  1778.     }
  1779. /***************************************************************************
  1780. *
  1781. * klsiRxCallback - Invoked when a Packet is received.
  1782. *
  1783. *
  1784. * RETURNS : N/A
  1785. *
  1786. */
  1787. LOCAL void klsiRxCallback
  1788.     (
  1789.     pVOID p /* completed IRP */
  1790.     )
  1791.     {
  1792.     pUSB_IRP pIrp = (pUSB_IRP) p;
  1793.     KLSI_DEVICE* pDevCtrl = pIrp->userPtr;
  1794.     BOOL irpStalled = FALSE;
  1795.     OSS_MUTEX_TAKE (klsiMutex, OSS_BLOCK);
  1796.     /* Input IRP completed */
  1797.     pDevCtrl->inIrpInUse = FALSE;
  1798.     /*
  1799.      * If the IRP was successful then pass the data back to the client.
  1800.      * Note that the netJobAdd() is not necessary here as the function 
  1801.      * is not getting executed in isr context.
  1802.      * If irp STALL occurs and could not be cleared then we do not submit 
  1803.      * next Irp for listening input.
  1804.      */
  1805.     if (pIrp->result != OK)
  1806. {
  1807.         pDevCtrl->inErrors++; /* Should also update MIB */
  1808.   
  1809. if(pIrp->result == S_usbHcdLib_STALLED)
  1810.     {
  1811.     if(usbdFeatureClear (klsiHandle,
  1812.  pDevCtrl->pDev->nodeId,
  1813.  USB_RT_STANDARD | USB_RT_ENDPOINT, 
  1814.  0, 
  1815.  0) !=OK)
  1816.   {
  1817.         KLSI_LOG (KLSI_DBG_TX, "Irp STALLED ..Could not clearn",
  1818.                   0, 0, 0, 0, 0, 0);
  1819. irpStalled = TRUE;
  1820. }
  1821.     }
  1822. }
  1823.     else
  1824. {
  1825. if( pIrp->bfrList[0].actLen >= 2)
  1826.     {
  1827.        klsiEndRecv (pDevCtrl,(pUINT8)(pIrp->bfrList[0].pBfr+2), 
  1828. pIrp->bfrList[0].actLen-2);  
  1829.     pDevCtrl->rxIndex++;
  1830.     pDevCtrl->rxIndex %= pDevCtrl->noOfInBfrs;    
  1831.     }
  1832. }       
  1833.     /*
  1834.      * Unless the IRP was cancelled,stalled - implying the channel is being
  1835.      * torn down, re-initiate the "in" IRP to listen for more data.
  1836.      */
  1837.     if ((pIrp->result != S_usbHcdLib_IRP_CANCELED) && (irpStalled !=TRUE))
  1838. klsiListenForInput (pDevCtrl);
  1839.     else
  1840.         KLSI_LOG (KLSI_DBG_TX, "Rxcallback....pIrp->result %dn",
  1841.              pIrp->result, 0, 0, 0, 0, 0);
  1842.     OSS_MUTEX_RELEASE (klsiMutex);  
  1843.     }
  1844. /***************************************************************************
  1845. *
  1846. * klsiMCastFilterSet - Sets a Multicast Address Filter for the device
  1847. *
  1848. * Even if the host wishes to change a single multicast filter in the device,
  1849. * it must reprogram the entire list of filters using this function. 
  1850. * <pAddress> shall contain a pointer to this list of multicast addresses
  1851. * and <noOfFilters> shall hold the number of multicast address filters
  1852. * being programmed to the device.
  1853. *
  1854. * RETURNS : OK or ERROR
  1855. */
  1856. STATUS klsiMCastFilterSet
  1857.     (
  1858.     KLSI_DEVICE* pDevCtrl, /* device to add the mcast filters */
  1859.     UINT8* pAddress, /* Mcast address filters list */
  1860.     UINT32 noOfFilters /* no. of filters to add */
  1861.     )
  1862.     {
  1863.     
  1864.     KLSI_LOG (KLSI_DBG_MCAST, "klsiMCasrFilterSet:..entered.n",
  1865.  0, 0, 0, 0, 0, 0);
  1866.     if (pDevCtrl == NULL)
  1867. return ERROR;
  1868.     /* Check if  this many number of Filters are supported by the device */
  1869.     if ((noOfFilters < 0) || 
  1870. (noOfFilters > (pDevCtrl->mCastFilters.noMCastFilters)))
  1871. return ERROR;
  1872.     if (((noOfFilters == 0) && (pAddress != NULL)) ||
  1873. ((noOfFilters > 0) && (pAddress == NULL)))
  1874. return ERROR;
  1875.     
  1876.     /* Set the Filters */
  1877.     if (usbdVendorSpecific (klsiHandle, 
  1878.     pDevCtrl->pDev->nodeId,
  1879.     USB_RT_VENDOR | USB_RT_HOST_TO_DEV, 
  1880.     USB_REQ_KLSI_SET_MCAST_FILTER, 
  1881.     noOfFilters, 
  1882.     0, 
  1883.     noOfFilters * 6, 
  1884.     pAddress, 
  1885.     NULL) != OK)
  1886. {
  1887. return ERROR;
  1888. }
  1889.     return OK;
  1890.     }
  1891. /***************************************************************************
  1892. *
  1893. * klsiPacketFilterSet - Sets a Ethernet Packet Filter for the device
  1894. *
  1895. * This function configures the Ethernet device for reception of various 
  1896. * kinds of ethernet packets. <bitmap> is an inclusive OR of the BITs
  1897. * listed below. Additional Filtering, if needed must be performed in the 
  1898. * host software.
  1899. * .IP "PACKET_TYPE_MULTICAST"
  1900. * This bit will enable all multicast packets enumerated in the
  1901. * devices multicast address list to be forwarded to the host.
  1902. * .IP "PACKET_TYPE_BROADCAST"
  1903. * This bit enables all broadcast packets to be forwarded to host.
  1904. * .IP "PACKET_TYPE_DIRECTED"
  1905. * This bit enables all normal packets to be forwarded to host.
  1906. * .IP "PACKET_TYPE_ALL_MULTICAST"
  1907. * This bit enables all multi cast packets to be forwarded to host.
  1908. * .IP "PACKET_TYPE_PROMISCOUS"
  1909. * This bit enables all packets to be forwarded to host.
  1910. * The Rest of the bits in <bitmap> shall be reset to Zero.
  1911. * RETURNS: OK or ERROR
  1912. */
  1913. STATUS klsiPacketFilterSet
  1914.     (
  1915.     KLSI_DEVICE* pDevCtrl, /* device to set he packet filter */
  1916.     UINT8 bitmap /* packet filter bitmap */
  1917.     )
  1918.     {
  1919.     UINT16 pktFilterBitmap = 0x0000;    
  1920.     KLSI_LOG (KLSI_DBG_MCAST, "klsiPacketFilterSet:..entered.n",
  1921.  0, 0, 0, 0, 0, 0);
  1922.     if (pDevCtrl == NULL)
  1923. return ERROR;
  1924.     bitmap |= PACKET_TYPE_DIRECTED; /* this is always maintained  */
  1925.     pktFilterBitmap |= bitmap;
  1926.     /* Set the Filters */
  1927.     if (usbdVendorSpecific (klsiHandle, 
  1928.     pDevCtrl->pDev->nodeId,
  1929.     USB_RT_VENDOR | USB_RT_HOST_TO_DEV, 
  1930.     USB_REQ_KLSI_SET_PACKET_FILTER, 
  1931.     pktFilterBitmap, 
  1932.     0, 
  1933.     0, 
  1934.     NULL, 
  1935.     NULL) != OK)
  1936. {
  1937. return ERROR;
  1938. }
  1939.     return OK;
  1940.        
  1941.     }   
  1942. /***************************************************************************
  1943. *
  1944. * klsiStatsGet - Gets the statistics from the device
  1945. * RETURNS : OK or ERROR 
  1946. *
  1947. */
  1948. STATUS klsiStatsGet
  1949.     (
  1950.     KLSI_DEVICE* pDevCtrl, /* device to retrieve the Statistic */
  1951.     UINT8 feature, /* statistic to get */
  1952.     UINT8* pStat /* place to store the stats */
  1953.     )
  1954.     {
  1955.     KLSI_LOG (KLSI_DBG_MCAST, "Entered klsiStatsGet.n",
  1956.  0, 0, 0, 0, 0, 0);
  1957.     if (pDevCtrl == NULL)
  1958. return ERROR;
  1959.     /* see if this particular statistic is supported by the device */
  1960.     if ((pDevCtrl->stats.bitmap & (0x1 << feature)) == 0)
  1961. return ERROR;
  1962.     if (usbdVendorSpecific (klsiHandle, 
  1963.     pDevCtrl->pDev->nodeId,
  1964.                     USB_RT_VENDOR | USB_RT_DEV_TO_HOST, 
  1965.                     USB_REQ_KLSI_GET_STATS, 
  1966.     feature, 
  1967.                             0, 
  1968.     4, 
  1969.     pStat, 
  1970.     0) != OK)
  1971. {
  1972. return ERROR;
  1973. }
  1974.     /* the driver structure is not updated now */
  1975.     return OK;
  1976.     
  1977.     }   
  1978. /***************************************************************************
  1979. *
  1980. * klsiReset - Resets the USB-ethernet adapter
  1981. *
  1982. * This function resets the Ethernet Adapter. 
  1983. *
  1984. * RETURNS : OK or ERROR
  1985. */
  1986. STATUS klsiReset
  1987.     (
  1988.     KLSI_DEVICE* pDevCtrl /* device to reset */
  1989.     )
  1990.     {
  1991.     KLSI_LOG (KLSI_DBG_RESET, "Entered klsiReset.n",
  1992.  0, 0, 0, 0, 0, 0);
  1993.     if (pDevCtrl == NULL)
  1994. return ERROR;
  1995.     /* SET_CONFIGURATION command shall cause the device to reset */
  1996.     if (usbdConfigurationSet (klsiHandle, 
  1997. pDevCtrl->pDev->nodeId,
  1998. 0, 
  1999. pDevCtrl->maxPower * USB_POWER_MA_PER_UNIT) 
  2000. != OK)
  2001. {
  2002.         KLSI_LOG (KLSI_DBG_RESET, " Could not reset the device. n",
  2003.   0, 0, 0, 0, 0, 0);
  2004. return ERROR;
  2005. }
  2006.     return OK;
  2007.     
  2008.     }  
  2009.   
  2010. /***************************************************************************
  2011. *
  2012. * klsiFindDevice - Searches for a USB ethernet device for indicated <nodeId>
  2013. *
  2014. * RETURNS: pointer to matching device structure, or NULL if device not found
  2015. */
  2016. USB_KLSI_DEV* klsiFindDevice
  2017.     (
  2018.     USBD_NODE_ID nodeId /* Node Id to find */
  2019.     )
  2020.     {
  2021.     USB_KLSI_DEV * pDev = usbListFirst (&klsiDevList);
  2022.     while (pDev != NULL)
  2023. {
  2024. if (pDev->nodeId == nodeId)
  2025.     break;
  2026. pDev = usbListNext (&pDev->devLink);
  2027. }
  2028.     return pDev;
  2029.     }
  2030. /***************************************************************************
  2031. *
  2032. * klsiEndFindDevice - Searches USB ethernet device 
  2033. *
  2034. * RETURNS: pointer to matching device structure, or NULL if not found
  2035. */
  2036. USB_KLSI_DEV* klsiEndFindDevice
  2037.     (
  2038.     UINT16 vendorId, /* Vendor Id to search for */
  2039.     UINT16 productId /* Product Id to search for */
  2040.     )
  2041.     {
  2042.     USB_KLSI_DEV * pDev = usbListFirst (&klsiDevList);
  2043.     while (pDev != NULL)
  2044. {
  2045. if ((pDev->vendorId == vendorId) && (pDev->productId == productId))
  2046.     break;
  2047. pDev = usbListNext (&pDev->devLink);
  2048. }
  2049.     return pDev;
  2050.     }
  2051.   
  2052.      
  2053. /***************************************************************************
  2054. *
  2055. * klsiMacAddressSet - Sets a Ethernet Address for the device
  2056. *
  2057. * This function will do the address setting for the given device.
  2058. *
  2059. * RETURNS : OK or ERROR 
  2060. */
  2061. STATUS klsiMacAddressSet
  2062.     (
  2063.     KLSI_DEVICE* pDevCtrl,  /* Device to set the address for */
  2064.     UINT8 * pAddress     /* The MAC Address to be Set */
  2065.     )
  2066.    
  2067.     {
  2068.     KLSI_LOG (KLSI_DBG_MAC, "Entered klsiMacAddressSet...n",
  2069.  0, 0, 0, 0, 0, 0);
  2070.     if ((pDevCtrl == NULL) || (pAddress == NULL))
  2071. return ERROR;
  2072.     /* Set the MAC Address */
  2073.     if (usbdVendorSpecific (klsiHandle, 
  2074.     pDevCtrl->pDev->nodeId,
  2075.                     USB_RT_VENDOR | USB_RT_HOST_TO_DEV, 
  2076.                     USB_REQ_KLSI_SET_TEMP_MAC, 
  2077.     0, 
  2078.     0, 
  2079.     6, 
  2080.     pAddress,
  2081.                     NULL) != OK)
  2082. {
  2083. return ERROR;
  2084. }
  2085.     return OK;
  2086.     
  2087.     }   
  2088.     
  2089. /***************************************************************************
  2090. *
  2091. * klsiShutdown - Shuts down USB EnetLib
  2092. *
  2093. * <errCode> should be OK or S_klsiLib_xxxx.  This value will be
  2094. * passed to ossStatus() and the return value from ossStatus() is the
  2095. * return value of this function.
  2096. *
  2097. * RETURNS: OK or ERROR
  2098. */
  2099. LOCAL STATUS klsiShutdown
  2100.     (
  2101.     int errCode
  2102.     )
  2103.     {
  2104.    
  2105.     KLSI_DEVICE * pDev;
  2106.     /* Dispose of any open connections. */
  2107.     while ((pDev = usbListFirst (&klsiDevList)) != NULL)
  2108. klsiDestroyDevice (pDev);
  2109.     /*
  2110.      * Release our connection to the USBD.  The USBD automatically 
  2111.      * releases any outstanding dynamic attach requests when a client
  2112.      * unregisters.
  2113.      */
  2114.     if (klsiHandle != NULL)
  2115. {
  2116. usbdClientUnregister (klsiHandle);
  2117. klsiHandle = NULL;
  2118. }
  2119.     /* Release resources. */
  2120.     if (klsiMutex != NULL)
  2121. {
  2122. OSS_MUTEX_DESTROY (klsiMutex);
  2123. klsiMutex = NULL;
  2124. }
  2125.     
  2126.     if (klsiTxMutex != NULL)
  2127. {
  2128. OSS_MUTEX_DESTROY (klsiTxMutex);
  2129. klsiTxMutex = NULL;
  2130. }
  2131.     
  2132.     if (klsiRxMutex != NULL)
  2133. {
  2134. OSS_MUTEX_DESTROY (klsiRxMutex);
  2135. klsiRxMutex = NULL;
  2136. }
  2137.    
  2138.     usbdShutdown();
  2139.     return ossStatus (errCode);
  2140.     }
  2141.      
  2142. /***************************************************************************
  2143. *
  2144. * klsiDestroyDevice - disposes of a KLSI_DEVICE structure
  2145. *
  2146. * Unlinks the indicated KLSI_DEVICE structure and de-allocates
  2147. * resources associated with the channel.
  2148. *
  2149. * RETURNS: N/A
  2150. */
  2151. void klsiDestroyDevice
  2152.     (
  2153.     KLSI_DEVICE* pDevCtrl
  2154.     )
  2155.     {
  2156.     USB_KLSI_DEV *pDev;
  2157.     if (pDevCtrl != NULL)
  2158. {
  2159. pDev = pDevCtrl->pDev;
  2160. /* Unlink the structure. */
  2161. usbListUnlink (&pDev->devLink);
  2162.   
  2163. /* Release pipes and wait for IRPs to be cancelled if necessary. */
  2164. if (pDevCtrl->outPipeHandle != NULL)
  2165.     usbdPipeDestroy (klsiHandle, pDevCtrl->outPipeHandle);
  2166. if (pDevCtrl->inPipeHandle != NULL)
  2167.     usbdPipeDestroy (klsiHandle, pDevCtrl->inPipeHandle);
  2168. /* taskDelay(sysClkRateGet()*2);*/
  2169. while (pDevCtrl->pEnetIrp->outIrpInUse || pDevCtrl->inIrpInUse)
  2170.    OSS_THREAD_SLEEP (1);
  2171.   /*  Release Input buffers*/
  2172. if ( pDevCtrl->pInBfrArray !=NULL)
  2173.     {
  2174.             OSS_FREE(pDevCtrl->pInBfrArray);
  2175.     taskDelay(sysClkRateGet()*1);
  2176.     }
  2177. /*  Release EnetIrp buffers*/
  2178. if ( pDevCtrl->pEnetIrp != NULL)
  2179.     {
  2180.            OSS_FREE(pDevCtrl->pEnetIrp);
  2181.    taskDelay(sysClkRateGet()*1);
  2182.             }
  2183. /* Release structure. */
  2184. if (pDev !=NULL)
  2185.     OSS_FREE (pDev);
  2186. }
  2187.     }
  2188. /**************************************************************************
  2189. *
  2190. * klsiEndLoad - Initialize the driver and device
  2191. *
  2192. * This routine initializes the driver and the device to the operational state.
  2193. * All of the device specific parameters are passed in the initString.
  2194. * This function first extracts the vendorId and productId of the device 
  2195. * from the initialization string using the klsiEndParse() function. It then 
  2196. * passes these parameters and its control structure to the klsiDevInit()
  2197. * function. klsiDevInit() does most of the device specific initialization
  2198. * and brings the device to the operational state. Please refer to klsiLib.c
  2199. * for more details about usbenetDevInit(). This driver will be attached to MUX
  2200. * and then the memory initialization of the device is carried out using
  2201. * klsiEndMemInit(). 
  2202. *
  2203. * This function doesn't do any thing device specific. Instead, it delegates
  2204. * such initialization to klsiDevInit(). This routine handles the other part
  2205. * of the driver initialization as required by MUX.
  2206. *
  2207. * muxDevLoad() calls this function twice. First time this function is called, 
  2208. * initialization string will be NULL . We are required to fill in the device 
  2209. * name ("usb") in the string and return. When next time this function is called,
  2210. * the initialization string will be proper.
  2211. *
  2212. * <initString> will be of the format :
  2213. * "unit : vendorId : productId : noOfInBfrs : noOfIrps"
  2214. *
  2215. * PARAMETERS
  2216. *
  2217. * .IP <initString>
  2218. * The device initialization string.
  2219. *
  2220. * RETURNS: An END object pointer, or NULL on error.
  2221. */
  2222. END_OBJ * klsiEndLoad
  2223.     (
  2224.     char * initString                             /* initialization string */
  2225.     )
  2226.     {
  2227.     KLSI_DEVICE * pDrvCtrl;                      /* driver structure */
  2228.     UINT16 vendorId;                                /* vendor information */
  2229.     UINT16 productId;                               /* product information */
  2230.     KLSI_LOG (KLSI_DBG_LOAD, "Loading usb end...n", 1, 2, 3, 4, 5, 6);
  2231.     if (initString == NULL)
  2232. return (NULL);
  2233.     
  2234.     if (initString[0] == EOS)
  2235. {
  2236.         /* Fill in the device name and return peacefully */
  2237. bcopy ((char *)KLSI_NAME, (void *)initString, KLSI_NAME_LEN);
  2238. return (0);
  2239. }
  2240.     /* allocate the device structure */
  2241.     pDrvCtrl = (KLSI_DEVICE *)calloc (sizeof (KLSI_DEVICE), 1);
  2242.     if (pDrvCtrl == NULL)
  2243. {
  2244. KLSI_LOG (KLSI_DBG_LOAD, "No Memory!!...n", 1, 2, 3, 4, 5, 6);
  2245. goto errorExit;
  2246. }
  2247.     /* parse the init string, filling in the device structure */
  2248.     if (klsiEndParse (pDrvCtrl, initString, &vendorId, &productId) == ERROR)
  2249. {
  2250. KLSI_LOG (KLSI_DBG_LOAD, "Parse Failed.n", 1, 2, 3, 4, 5, 6);
  2251. goto errorExit;
  2252. }
  2253.     /* Ask the klsiLib to do the necessary initialization. */
  2254.     if (klsiDevInit(pDrvCtrl,vendorId,productId) == ERROR)
  2255. {
  2256. KLSI_LOG (KLSI_DBG_LOAD, "EnetDevInitFailed.n", 
  2257.     1, 2, 3, 4, 5, 6);
  2258. goto errorExit;
  2259. }
  2260.     /* initialize the END and MIB2 parts of the structure */
  2261.     if (END_OBJ_INIT (&pDrvCtrl->endObj, 
  2262.       (DEV_OBJ *)pDrvCtrl, 
  2263.       "usb",
  2264.                       pDrvCtrl->unit, 
  2265.       &klsiEndFuncTable,
  2266.                       KLSI_NAME) == ERROR
  2267.      || END_MIB_INIT (&pDrvCtrl->endObj, 
  2268.       M2_ifType_ethernet_csmacd,
  2269.                       &pDrvCtrl->macAdrs[0], 
  2270.       6, 
  2271.       KLSI_BUFSIZ,
  2272.                       KLSI_SPEED)
  2273.     == ERROR)
  2274. {
  2275. KLSI_LOG (KLSI_DBG_LOAD, "END MACROS FAILED...n", 
  2276. 1, 2, 3, 4, 5, 6);
  2277. goto errorExit;
  2278. }
  2279.     /* Perform memory allocation/distribution */
  2280.     if (klsiEndMemInit (pDrvCtrl) == ERROR)
  2281. {
  2282. KLSI_LOG (KLSI_DBG_LOAD, "endMemInit() Failed...n", 
  2283.     1, 2, 3, 4, 5, 6);
  2284. klsiDestroyDevice(pDrvCtrl);
  2285. goto errorExit;
  2286. }
  2287.  
  2288.     /* set the flags to indicate readiness */
  2289.     END_OBJ_READY (&pDrvCtrl->endObj,
  2290.     IFF_UP | IFF_RUNNING | IFF_NOTRAILERS | IFF_BROADCAST
  2291.     | IFF_MULTICAST);
  2292.     KLSI_LOG (KLSI_DBG_LOAD, "Done loading usb end..n", 
  2293. 1, 2, 3, 4, 5, 6);
  2294.     pDrvCtrl->pDev->connected = TRUE;
  2295.     return (&pDrvCtrl->endObj);
  2296. errorExit:
  2297.     if (pDrvCtrl != NULL)
  2298. {
  2299. free ((char *)pDrvCtrl);
  2300. }
  2301.     return NULL;
  2302.     }
  2303. /***************************************************************************
  2304. *
  2305. * klsiEndParse - parse the init string
  2306. *
  2307. * Parse the input string.  Fill in values in the driver control structure.
  2308. *
  2309. * The muxLib.o module automatically prepends the unit number to the user's
  2310. * initialization string from the BSP (configNet.h).
  2311. * This function parses the input string and fills in the places pointed
  2312. * to by <pVendorId> and <pProductId>. Unit Number, no of Irps and no of Input 
  2313. * buffers of the string will be stored in the device structure pointed to by 
  2314. * <pDrvCtrl>.
  2315. *
  2316. * .IP <pDrvCtrl>
  2317. * Pointer to the device structure.
  2318. * .IP <initString>
  2319. * Initialization string for the device. It will be of the following format :
  2320. * "unit:vendorId:productId:noOfInbfrs:noOfIrps"
  2321. * Device unit number, a small integer.
  2322. * .IP <pVendorId>
  2323. * Pointer to the place holder of the device vendor id.
  2324. * .IP <pProductId>
  2325. *  Pointer to the place holder of the device product id.
  2326. * .IP <noOfInbfrs>
  2327. * Holds the number of input buffers.
  2328. * .IP <noOfIrps>
  2329. *  Holds the number of output IRP's.
  2330. *
  2331. * RETURNS: OK or ERROR
  2332. */
  2333. STATUS klsiEndParse
  2334.     (
  2335.     KLSI_DEVICE * pDrvCtrl, /* device pointer */
  2336.     char * initString, /* information string */
  2337.     UINT16 * pVendorId,
  2338.     UINT16 * pProductId
  2339.     )
  2340.     {
  2341.     char * tok;
  2342.     char * pHolder = NULL;
  2343.     
  2344.     /* Parse the initString */
  2345.     /* Unit number. (from muxLib.o) */
  2346.     tok = strtok_r (initString, ":", &pHolder);
  2347.     if (tok == NULL)
  2348. return ERROR;
  2349.     pDrvCtrl->unit = atoi (tok);
  2350.     KLSI_LOG (KLSI_DBG_LOAD, "Parse: Unit : %d..n", 
  2351. pDrvCtrl->unit, 2, 3, 4, 5, 6); 
  2352.     /* Vendor Id. */
  2353.     tok = strtok_r (NULL, ":", &pHolder);
  2354.     if (tok == NULL)
  2355. return ERROR;
  2356.     *pVendorId = atoi (tok);
  2357.     KLSI_LOG (KLSI_DBG_LOAD, "Parse: VendorId : 0x%x..n", 
  2358. *pVendorId, 2, 3, 4, 5, 6); 
  2359.     /* Product Id. */
  2360.     tok = strtok_r (NULL, ":", &pHolder);
  2361.     if (tok == NULL)
  2362. return ERROR;
  2363.     *pProductId = atoi (tok);
  2364.   
  2365.     KLSI_LOG (KLSI_DBG_LOAD, "Parse: ProductId : 0x%x..n", 
  2366. *pProductId, 2, 3, 4, 5, 6); 
  2367.     /* no of in buffers */
  2368.     tok = strtok_r (NULL, ":", &pHolder);
  2369.     if (tok == NULL)
  2370. return ERROR;
  2371.     pDrvCtrl->noOfInBfrs  = atoi (tok);
  2372.   
  2373.     KLSI_LOG (KLSI_DBG_LOAD, "Parse: NoInBfrs : %x..n", 
  2374. pDrvCtrl->noOfInBfrs, 2, 3, 4, 5, 6); 
  2375.     /* no of out IRPs */
  2376.     tok = strtok_r (NULL, ":", &pHolder);
  2377.     if (tok == NULL)
  2378. return ERROR;
  2379.     pDrvCtrl->noOfIrps = atoi (tok);
  2380.   
  2381.     KLSI_LOG (KLSI_DBG_LOAD, "Parse: NoOutIrps : %x..n", 
  2382.  pDrvCtrl->noOfIrps, 2, 3, 4, 5, 6);
  2383.     KLSI_LOG (KLSI_DBG_LOAD, "Parse: Processed all argumentsn", 
  2384. 1, 2, 3, 4, 5, 6);
  2385.     return OK;
  2386.     }
  2387. /***************************************************************************
  2388. *
  2389. * klsiEndSend - the driver send routine
  2390. *
  2391. * This routine takes a M_BLK_ID sends off the data in the M_BLK_ID. The data 
  2392. * contained in the MBlks is copied to a character buffer and the buffer is 
  2393. * handed over  to klsiSend(). The buffer must already have the addressing 
  2394. * information properly installed in it.  This is done by a higher layer.   
  2395. * The device requires that the first two bytes of the data sent to it (for 
  2396. * transmission over ethernet) contain the length of the data. This is added
  2397. * here. 
  2398. *
  2399. * During the course of testing the driver, it is found that the device is 
  2400. * corrupting some bytes of the packet if exact length of the data as handed 
  2401. * over by MUX is sent. This is resulting in packet not being received
  2402. * by the addressed destination, packet checksum errors etc. The remedy is to
  2403. * pad up few bytes to the data packet. This solved the problem.
  2404. *
  2405. * RETURNS: OK or ERROR.
  2406. */
  2407. LOCAL STATUS klsiEndSend
  2408.     (
  2409.     KLSI_DEVICE * pDrvCtrl, /* device ptr */
  2410.     M_BLK_ID     pMblk /* data to send */
  2411.     )
  2412.     {
  2413.     UINT8 *      pBuf;  /* buffer to hold the data */
  2414.     UINT32 noOfBytes;      /* noOfBytes to be transmitted */
  2415. #if 0
  2416.     int i=0;
  2417. #endif
  2418.     KLSI_LOG (KLSI_DBG_TX, "klsiEndSend: Entered.n", 0, 0, 0, 0, 0, 0);  
  2419.  
  2420.     if ((pDrvCtrl == NULL) || (pMblk == NULL))
  2421. return ERROR;
  2422. /*   pBuf = (UINT8 *) malloc(KLSI_OUT_BFR_SIZE);*/
  2423.      pBuf = (UINT8 *) memalign(sizeof(ULONG),KLSI_OUT_BFR_SIZE);
  2424.   
  2425.     
  2426.     if (pBuf == NULL)
  2427. {
  2428. printf(" klsiEndSend : Could not allocate memory n");
  2429. return ERROR;
  2430. }
  2431.     /* copy the MBlk chain to a buffer */
  2432.     noOfBytes = netMblkToBufCopy(pMblk,(char *)pBuf+2,NULL); 
  2433.     KLSI_LOG (KLSI_DBG_LOAD, "klsiEndSend: %d bytes to be sent.n", 
  2434. noOfBytes, 0, 0, 0, 0, 0);
  2435.     if (noOfBytes == 0) 
  2436. return ERROR;
  2437.     /* 
  2438.      * Padding : how much to pad is decided by trial and error.
  2439.      * Note that there is no need to add any extra bytes in the buffer.
  2440.      * since these bytes are not used, they can be any junk 
  2441.      * which is already in the buffer.
  2442.      * We are just interested in the count.
  2443.      */
  2444.     
  2445.     if (noOfBytes < 60)
  2446. noOfBytes = 60;
  2447.     /* (Required by the device) Fill in the Length in the first Two Bytes */
  2448. /*    *(UINT16 *)pBuf = noOfBytes; */
  2449.     pBuf[0] = (UINT8) (noOfBytes&0x00ff); 
  2450.     pBuf[1] = (UINT8) ((noOfBytes >> 8)&0x00ff);
  2451. #if 0
  2452.     for(i=0;i<noOfBytes+2;i++)
  2453. printf("%x ",pBuf[i]);
  2454.     printf("n"); 
  2455. #endif
  2456.     /* Transmit the data */
  2457.     if (klsiSend (pDrvCtrl, pBuf, noOfBytes+2) == ERROR)
  2458. return ERROR;
  2459.  
  2460.     KLSI_LOG (KLSI_DBG_TX, "klsiEndSend: Pkt submitted for tx.n", 
  2461. 0, 0, 0, 0, 0, 0);
  2462.  
  2463.     /* Bump the statistic counter. */
  2464.     END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_UCAST, +1);
  2465.     /*
  2466.      * Cleanup.  The driver frees the packet now.
  2467.      */
  2468.     netMblkClChainFree (pMblk);
  2469.     return (OK);
  2470.     }
  2471. /***************************************************************************
  2472. *
  2473. * klsiEndRecv - process the next incoming packet
  2474. *
  2475. * klsiEndRecv is called by the klsiRxCallBack() upon successful execution
  2476. * of an input IRP. This means some proper data is received. This function  
  2477. * will be called with the pointer to be buffer and the length of data.
  2478. * What is done here is to construct an MBlk structure with the data received 
  2479. * and pass it onto the upper layer.
  2480. *
  2481. * RETURNS: N/A.
  2482. */
  2483. STATUS klsiEndRecv
  2484.     (
  2485.     KLSI_DEVICE *pDrvCtrl, /* device structure */
  2486.     UINT8*  pData,              /* pointer to data buffer */
  2487.     UINT32  len                 /* length of data */
  2488.     )
  2489.     {
  2490.     
  2491.     UCHAR *     pNewCluster;    /* Clsuter to store the data */
  2492.     CL_BLK_ID pClBlk;         /* Control block to "control" the cluster */
  2493.     M_BLK_ID  pMblk;          /* and an MBlk to complete a MBlk contract */   
  2494. #if 0
  2495.     int i=0;
  2496. #endif
  2497.     /* Add one to our unicast data. */
  2498.     END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, +1);
  2499.     pNewCluster = (UCHAR *)pData; 
  2500. #if 0
  2501.      for (i=0;i<len;i++)
  2502. printf("%x ",pNewCluster[i]);
  2503.      printf("n");
  2504. #endif
  2505.     /* Grab a cluster block to marry to the cluster received. */
  2506.     if ((pClBlk = netClBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT)) == NULL)
  2507.         {
  2508.         netClFree (pDrvCtrl->endObj.pNetPool, pNewCluster);
  2509. KLSI_LOG (KLSI_DBG_RX, "Out of Cluster Blocks!n", 
  2510.     1, 2, 3, 4, 5, 6);
  2511. END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);
  2512. goto cleanRXD;
  2513.         }
  2514.     
  2515.     /*
  2516.      * Let's get an M_BLK_ID and marry it to the one in the ring.
  2517.      */
  2518.     if ((pMblk = mBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT, MT_DATA)) 
  2519. == NULL)
  2520.         {
  2521.         netClBlkFree (pDrvCtrl->endObj.pNetPool, pClBlk); 
  2522.         netClFree (pDrvCtrl->endObj.pNetPool, pNewCluster);
  2523. KLSI_LOG (KLSI_DBG_RX, "Out of M Blocks!n", 
  2524.     1, 2, 3, 4, 5, 6);
  2525. END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);
  2526. goto cleanRXD;
  2527.         }
  2528.     END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, +1);
  2529.     
  2530.     /* Join the cluster to the MBlock */
  2531.     netClBlkJoin (pClBlk, (char *)pNewCluster, len, NULL, 0, 0, 0);
  2532.     netMblkClJoin (pMblk, pClBlk);
  2533.     pMblk->mBlkHdr.mLen = len;
  2534.     pMblk->mBlkHdr.mFlags |= M_PKTHDR;
  2535.     pMblk->mBlkPktHdr.len = len;
  2536.     END_RCV_RTN_CALL(&pDrvCtrl->endObj, pMblk);    
  2537. cleanRXD:
  2538.     return OK;
  2539.     }
  2540. /***************************************************************************
  2541. *
  2542. * klsiEndMemInit - initialize memory for the device.
  2543. *
  2544. * The END's Network memory pool is setup. This code is highly generic and 
  2545. * very simple. The technique described in netBufLib is followed.
  2546. * It is not even needed to make the memory cache DMA coherent. This is because
  2547. * unlike other END drivers, which act right on the top of the hardware,  
  2548. * we are layers above the hardware. 
  2549. *
  2550. * RETURNS: OK or ERROR.
  2551. */
  2552. STATUS klsiEndMemInit
  2553.     (
  2554.     KLSI_DEVICE * pDrvCtrl /* device to be initialized */
  2555.     )
  2556.     {
  2557.   
  2558.     /*
  2559.      * This is how END netPool is setup using netBufLib(1).
  2560.      * This code is very generic.
  2561.      */
  2562.     
  2563.     if ((pDrvCtrl->endObj.pNetPool = malloc (sizeof (NET_POOL))) == NULL)
  2564.         return (ERROR);
  2565.     klsiMclBlkConfig.mBlkNum = KLSI_M_BULK_NUM;
  2566.     klsiClDescTbl[0].clNum = KLSI_CL_NUMBER;
  2567.     klsiMclBlkConfig.clBlkNum = klsiClDescTbl[0].clNum;
  2568.     /* Calculate the total memory for all the M-Blks and CL-Blks. */
  2569.     klsiMclBlkConfig.memSize = (klsiMclBlkConfig.mBlkNum *
  2570.     (MSIZE + sizeof (long))) +
  2571.       (klsiMclBlkConfig.clBlkNum * 
  2572.     (CL_BLK_SZ + sizeof(long)));
  2573.     if ((klsiMclBlkConfig.memArea = (char *) memalign (sizeof(long),
  2574.                          klsiMclBlkConfig.memSize)) == NULL)
  2575.         return (ERROR);
  2576.     
  2577.     /* Calculate the memory size of all the clusters. */
  2578.     klsiClDescTbl[0].memSize = (klsiClDescTbl[0].clNum *
  2579.     (KLSI_BUFSIZ + 8)) + sizeof(int);
  2580.     /* Allocate the memory for the clusters from cache safe memory. */
  2581.     klsiClDescTbl[0].memArea =
  2582.         (char *) cacheDmaMalloc (klsiClDescTbl[0].memSize);
  2583.     if (klsiClDescTbl[0].memArea == NULL)
  2584.         {
  2585.         KLSI_LOG (KLSI_DBG_LOAD,"klsiEndMemInit:system memory "
  2586.     "unavailablen", 1, 2, 3, 4, 5, 6);
  2587.         return (ERROR);
  2588.         }
  2589.     
  2590.     /* Initialize the memory pool. */
  2591.     if (netPoolInit(pDrvCtrl->endObj.pNetPool, 
  2592.     &klsiMclBlkConfig,
  2593.                     &klsiClDescTbl[0], 
  2594.     klsiClDescTblNumEnt,
  2595.     NULL) == ERROR)
  2596.         {
  2597.         KLSI_LOG (KLSI_DBG_LOAD, "Could not init bufferingn",
  2598. 1, 2, 3, 4, 5, 6);
  2599.         return (ERROR);
  2600.         }
  2601.     if ((pDrvCtrl->pClPoolId = netClPoolIdGet (pDrvCtrl->endObj.pNetPool,
  2602.        ETHERMTU, 
  2603.        FALSE)) 
  2604.     == NULL)
  2605. {
  2606.         KLSI_LOG (KLSI_DBG_LOAD, "netClPoolIdGet() not successful n",
  2607.        1, 2, 3, 4, 5, 6);
  2608. return (ERROR);
  2609.         }
  2610.     KLSI_LOG (KLSI_DBG_LOAD, "Memory setup completen", 
  2611. 1, 2, 3, 4, 5, 6);
  2612.     return OK;
  2613.     }
  2614. /***************************************************************************
  2615. *
  2616. * klsiEndConfig - reconfigure the interface under us.
  2617. *
  2618. * Reconfigure the interface setting promiscuous/ broadcast etc modes, and 
  2619. * changing the multicast interface list.
  2620. *
  2621. * RETURNS: N/A.
  2622. */
  2623. LOCAL STATUS klsiEndConfig
  2624.     (
  2625.     KLSI_DEVICE *pDrvCtrl /* device to be re-configured */
  2626.     )
  2627.     {
  2628.     UINT8 bitmap = 0x00;    
  2629.     MULTI_TABLE* pList = NULL;
  2630.     /* Set the modes asked for. */
  2631.     if (END_FLAGS_GET(&pDrvCtrl->endObj) & IFF_PROMISC)
  2632. {
  2633. KLSI_LOG (KLSI_DBG_IOCTL, "Setting Promiscuous mode on!n",
  2634. 1, 2, 3, 4, 5, 6);
  2635. bitmap |= PACKET_TYPE_PROMISCOUS;
  2636. }
  2637.     if (END_FLAGS_GET(&pDrvCtrl->endObj) & IFF_MULTICAST)
  2638. {
  2639. KLSI_LOG (KLSI_DBG_IOCTL, "Setting Multicast mode On!n",
  2640. 1, 2, 3, 4, 5, 6);
  2641. bitmap |= PACKET_TYPE_MULTICAST;
  2642. }
  2643.     if (END_FLAGS_GET(&pDrvCtrl->endObj) & IFF_ALLMULTI)
  2644. {
  2645. KLSI_LOG (KLSI_DBG_IOCTL, "Setting ALLMULTI mode On!n",
  2646. 1, 2, 3, 4, 5, 6);
  2647. bitmap |= PACKET_TYPE_ALL_MULTICAST;
  2648. }
  2649.     if (END_FLAGS_GET(&pDrvCtrl->endObj) & IFF_BROADCAST)
  2650. {
  2651. KLSI_LOG (KLSI_DBG_IOCTL, "Setting Broadcast mode On!n",
  2652. 1, 2, 3, 4, 5, 6);
  2653. bitmap |= PACKET_TYPE_BROADCAST;
  2654. }
  2655.     /* Setup the packet filter */
  2656.     if (klsiPacketFilterSet (pDrvCtrl, bitmap) == ERROR)
  2657.         return ERROR;
  2658.          
  2659.     
  2660.     /* Set up address filter for multicasting. */
  2661.     if (END_MULTI_LST_CNT(&pDrvCtrl->endObj) > 0)
  2662. {
  2663. /* get the list of address to send to the device */
  2664.  
  2665.   if (etherMultiGet (&pDrvCtrl->endObj.multiList, pList)
  2666.    == ERROR)
  2667.     return ERROR;   
  2668.         /* Set the Filter!!! */
  2669.         if (klsiMCastFilterSet(pDrvCtrl,(pUINT8)pList->pTable,
  2670.     (pList->len) / 6) == ERROR)
  2671.     return ERROR;
  2672. }
  2673.     return OK;
  2674.     }
  2675. /***************************************************************************
  2676. *
  2677. * klsiEndMCastAdd - add a multicast address for the device
  2678. *
  2679. * This routine adds a multicast address to whatever the chip is already 
  2680. * listening for. The USB Ethernet device specifically requires that even 
  2681. * if a small modification (addition or removal) of the filter list is desired,
  2682. * the entire list has to be downloaded to the device. The generic etherMultiLib
  2683. * functions are used and then klsiMCastFilterSet() is called to achieve the
  2684. * functionality.
  2685. *
  2686. * RETURNS: OK or ERROR.
  2687. */
  2688. LOCAL STATUS klsiEndMCastAdd
  2689.     (
  2690.     KLSI_DEVICE *pDrvCtrl, /* device pointer */
  2691.     char* pAddress /* new address to add */
  2692.     )
  2693.     {
  2694.     
  2695.     int error;
  2696.     MULTI_TABLE* pList = NULL;
  2697.     if ((pDrvCtrl == NULL) || (pAddress == NULL))
  2698. return ERROR;
  2699.     /* First, add this address to the local list */
  2700.     
  2701.     if ((error = etherMultiAdd (&pDrvCtrl->endObj.multiList,
  2702. pAddress)) == ERROR)
  2703. return ERROR;
  2704.      
  2705.     /* Then get the list of address to send to the device */
  2706.  
  2707.     if ((error = etherMultiGet (&pDrvCtrl->endObj.multiList, pList))
  2708. == ERROR)
  2709. return ERROR;   
  2710.     /* Set the Filter!!! */
  2711.     if ((error = klsiMCastFilterSet (pDrvCtrl, 
  2712.      (pUINT8)pList->pTable, 
  2713.      (pList->len) / 6))
  2714. == ERROR)
  2715. return ERROR;   
  2716.     return (OK);
  2717.     }
  2718. /***************************************************************************
  2719. *
  2720. * klsiEndMCastDel - delete a multicast address for the device
  2721. *
  2722. * This routine removes a multicast address from whatever the driver
  2723. * listening for. The USB Ethernet device specifically requires that even 
  2724. * if a small modification (addition or removal) of the filter list is desired,
  2725. * the entire list has to be downloaded to the device. The generic etherMultiLib
  2726. * functions are used and then klsiMCastFilterSet() is called to achieve the
  2727. * functionality.
  2728. *
  2729. * RETURNS: OK or ERROR.
  2730. */
  2731. LOCAL STATUS klsiEndMCastDel
  2732.     (
  2733.     KLSI_DEVICE *pDrvCtrl, /* device pointer */
  2734.     char* pAddress /* new address to add */
  2735.     )
  2736.     {
  2737.     int error;
  2738.     MULTI_TABLE* pList = NULL;
  2739.     if ((pDrvCtrl == NULL) || (pAddress == NULL))
  2740. return ERROR;
  2741.     /* First, add this address to the local list */
  2742.     
  2743.     if ((error = etherMultiDel (&pDrvCtrl->endObj.multiList,
  2744. pAddress)) == ERROR)
  2745. return ERROR;
  2746.      
  2747.     /* Then get the list of address to send to the device */
  2748.  
  2749.     if ((error = etherMultiGet (&pDrvCtrl->endObj.multiList, pList))
  2750. == ERROR)
  2751. return ERROR;   
  2752.     if ((error = klsiMCastFilterSet (pDrvCtrl,
  2753.      (pUINT8)pList->pTable, 
  2754.      (pList->len) / 6))
  2755. == ERROR)
  2756. return ERROR;
  2757.     return (OK);
  2758.     }
  2759. /***************************************************************************
  2760. *
  2761. * klsiEndMCastGet - get the multicast address list for the device
  2762. *
  2763. * This routine gets the multicast list of whatever the driver
  2764. * is already listening for.
  2765. *
  2766. * RETURNS: OK or ERROR.
  2767. */
  2768. LOCAL STATUS klsiEndMCastGet
  2769.     (
  2770.     KLSI_DEVICE *pDrvCtrl, /* device pointer */
  2771.     MULTI_TABLE* pTable /* address table to be filled in */
  2772.     )
  2773.     {
  2774.     return (etherMultiGet (&pDrvCtrl->endObj.multiList, pTable));
  2775.     }
  2776. /***************************************************************************
  2777. *
  2778. * klsiEndIoctl - the driver I/O control routine
  2779. *
  2780. * Process an ioctl request.
  2781. *
  2782. * RETURNS: A command specific response, usually OK or ERROR.
  2783. */
  2784. int klsiEndIoctl
  2785.     (
  2786.     KLSI_DEVICE * pDrvCtrl, /* device receiving command */
  2787.     int cmd, /* ioctl command code */
  2788.     caddr_t data /* command argument */
  2789.     )
  2790.     {
  2791.     int error = 0;
  2792.     long value;
  2793.     switch (cmd)
  2794.         {
  2795.         case EIOCSADDR : /* Set Device Address */
  2796.     if (data == NULL)
  2797. return (EINVAL);
  2798.             bcopy ((char *)data, 
  2799.    (char *)END_HADDR (&pDrvCtrl->endObj),
  2800.    END_HADDR_LEN (&pDrvCtrl->endObj));
  2801.     if(klsiMacAddressSet (pDrvCtrl, (UINT8 *)data) == ERROR)
  2802. return ERROR;
  2803.             break;
  2804.         case EIOCGADDR : /* Get Device Address */
  2805.     if (data == NULL)
  2806. return (EINVAL);
  2807.             bcopy ((char *)END_HADDR (&pDrvCtrl->endObj), 
  2808.       (char *)data,
  2809.       END_HADDR_LEN (&pDrvCtrl->endObj));
  2810.             break;
  2811.         case EIOCSFLAGS : /* Set Device Flags */
  2812.   
  2813.     value = (long)data;
  2814.     if (value < 0)
  2815.         {
  2816. value = -(--value);
  2817. END_FLAGS_CLR (&pDrvCtrl->endObj, value);
  2818. }
  2819.     else
  2820. {
  2821. END_FLAGS_SET (&pDrvCtrl->endObj, value);
  2822. }
  2823.     klsiEndConfig (pDrvCtrl);
  2824.             break;
  2825.         case EIOCGFLAGS: /* Get Device Flags */
  2826.     *(int *)data = END_FLAGS_GET(&pDrvCtrl->endObj);
  2827.             break;
  2828. case EIOCPOLLSTART : /* Begin polled operation */
  2829.     return EINVAL; /* Not supported */
  2830. case EIOCPOLLSTOP : /* End polled operation */
  2831.     return EINVAL; /* Not supported */
  2832.         case EIOCGMIB2 : /* return MIB information */
  2833.             if (data == NULL)
  2834.                 return (EINVAL);
  2835.             bcopy ((char *)&pDrvCtrl->endObj.mib2Tbl, 
  2836.    (char *)data,
  2837.    sizeof(pDrvCtrl->endObj.mib2Tbl));
  2838.             break;
  2839.         case EIOCGFBUF : /* return minimum First Buffer for chaining */
  2840.             if (data == NULL)
  2841.                 return (EINVAL);
  2842.             * (int *)data = KLSI_MIN_FBUF;
  2843.             break;
  2844. case EIOCMULTIADD :  /* Add a Multicast Address */
  2845.     if (data == NULL)
  2846. return (EINVAL);
  2847.     if (klsiEndMCastAdd (pDrvCtrl, (char *)data) == ERROR)
  2848. return ERROR;
  2849.     break;
  2850. case EIOCMULTIDEL :  /* Delete a Multicast Address */
  2851.     if (data == NULL)
  2852. return (EINVAL);
  2853.     if (klsiEndMCastDel (pDrvCtrl, (char *)data) == ERROR)
  2854. return ERROR;
  2855.     break;
  2856. case EIOCMULTIGET :  /* Get the Multicast List */
  2857.     if (data == NULL)
  2858. return (EINVAL);
  2859.     if (klsiEndMCastGet (pDrvCtrl, (MULTI_TABLE *)data) == ERROR)
  2860. return ERROR;
  2861.     break;
  2862.        default:
  2863.             error = EINVAL;
  2864.         }
  2865.     return (error);
  2866.     }
  2867. /***************************************************************************
  2868. *
  2869. * klsiEndUnload - unload a driver from the system
  2870. *
  2871. * This function first brings down the device, and then frees any
  2872. * stuff that was allocated by the driver in the load function.
  2873. *
  2874. * RETURNS: OK or ERROR.
  2875. */
  2876. LOCAL STATUS klsiEndUnload
  2877.     (
  2878.     KLSI_DEVICE* pDrvCtrl /* device to be unloaded */
  2879.     )
  2880.     {
  2881.     END_OBJECT_UNLOAD (&pDrvCtrl->endObj);
  2882.    
  2883.     if ((pDrvCtrl->pDev->lockCount == 0) && (!pDrvCtrl->pDev->connected))
  2884. {
  2885.   klsiDestroyDevice (pDrvCtrl);
  2886.      taskDelay(sysClkRateGet() *1);
  2887.      netPoolDelete (pDrvCtrl->endObj.pNetPool);
  2888.      taskDelay(sysClkRateGet() *1);
  2889.     
  2890.      if (cfree((char *)pDrvCtrl)!=OK)
  2891.    {
  2892.     printf(" Error in memory clearing of device Structuren");
  2893.     return (ERROR);
  2894.     }
  2895. }
  2896.     return (OK);
  2897.     }
  2898. /***************************************************************************
  2899. *
  2900. * klsiEndPollRcv - routine to receive a packet in polled mode.
  2901. *
  2902. * This routine is NOT supported
  2903. *
  2904. * RETURNS: ERROR Always
  2905. */
  2906. LOCAL STATUS klsiEndPollRcv
  2907.     (
  2908.     KLSI_DEVICE * pDrvCtrl, /* device to be polled */
  2909.     M_BLK_ID      pMblk /* ptr to buffer */
  2910.     )
  2911.     {
  2912.     
  2913.     KLSI_LOG (KLSI_DBG_POLL_RX, "Poll Recv: NOT SUPPORTED", 
  2914. 1, 2, 3, 4, 5, 6);
  2915.     return ERROR;
  2916.     }
  2917. /***************************************************************************
  2918. *
  2919. * klsiEndPollSend - routine to send a packet in polled mode.
  2920. *
  2921. * This routine is NOT SUPPORTED
  2922. *
  2923. * RETURNS: ERROR always
  2924. */
  2925. LOCAL STATUS klsiEndPollSend
  2926.     (
  2927.     KLSI_DEVICE*  pDrvCtrl, /* device to be polled */
  2928.     M_BLK_ID    pMblk /* packet to send */
  2929.     )
  2930.     {
  2931.     
  2932.     KLSI_LOG (KLSI_DBG_POLL_TX, "Poll Send : NOT SUPPORTED", 
  2933. 1, 2, 3, 4, 5, 6);
  2934.     return ERROR;
  2935.     }
  2936. /***************************************************************************
  2937. *
  2938. * klsiDownloadFirmware - Downloads firmware to the KLSI Chip
  2939. *
  2940. * This routine downloads firmaware to the KLSI chip.  It will not function
  2941. * until this occurs.
  2942. *
  2943. *
  2944. * RETURNS : OK or ERROR
  2945. */
  2946. LOCAL STATUS klsiDownloadFirmware
  2947.     (
  2948.     KLSI_DEVICE * pDevCtrl, /* device to download */
  2949.     UINT8 * pData, /* Firmware */
  2950.     UINT16 len, /* size of firmware */
  2951.     UINT8 interrupt, /* Interrupt to use */
  2952.     UINT8 type
  2953.     )
  2954.     {
  2955.     UINT16 actLen = 0;
  2956.     if (len > KLSI_FIRMWARE_BUF)
  2957. {
  2958. KLSI_LOG (KLSI_DBG_DNLD," Firmware too BIG : %d bytes n", 
  2959.     len, 0, 0, 0, 0, 0);
  2960. return ERROR;
  2961. }    
  2962.     pData[2] = (len & 0xFF) - 7;
  2963.     pData[3] = len >> 8;
  2964.     pData[4] = type;
  2965.     pData[5] = interrupt;
  2966.     if (usbdVendorSpecific (klsiHandle, 
  2967.     pDevCtrl->pDev->nodeId,
  2968.     USB_RT_VENDOR | USB_RT_DEVICE | USB_RT_HOST_TO_DEV, 
  2969.     USB_REQ_KLSI_SCAN, 
  2970.     0, 
  2971.     0, 
  2972.     len, 
  2973.     pData,
  2974.     &actLen) != OK)
  2975. {
  2976. return ERROR;
  2977. }
  2978.     
  2979.     return OK;
  2980.     }        
  2981. /***************************************************************************
  2982. *
  2983. * klsiTriggerFirmware - Triggers firmware of KLSI Chip
  2984. *
  2985. * RETURNS : OK or ERROR
  2986. */
  2987. LOCAL STATUS klsiTriggerFirmware
  2988.     (
  2989.     KLSI_DEVICE * pDevCtrl, /* device to trigger */
  2990.     UINT8 interrupt /* interrupt to use */
  2991.     )
  2992.     {
  2993.     UINT16 actLen = 0;
  2994.     UINT8 triggerBuf[8];
  2995.     triggerBuf[0] = 0xB6;
  2996.     triggerBuf[1] = 0xC3;
  2997.     triggerBuf[2] = 1;
  2998.     triggerBuf[3] = 0;
  2999.     triggerBuf[4] = 6;
  3000.     triggerBuf[5] = 100;
  3001.     triggerBuf[6] = 0;
  3002.     triggerBuf[7] = 0;
  3003.     if (usbdVendorSpecific (klsiHandle, 
  3004.     pDevCtrl->pDev->nodeId,
  3005.     USB_RT_VENDOR | USB_RT_DEVICE | USB_RT_HOST_TO_DEV, 
  3006.     USB_REQ_KLSI_SCAN, 
  3007.     0, 
  3008.     0, 
  3009.     8, 
  3010.     triggerBuf,
  3011.     &actLen) 
  3012. != OK)
  3013. {
  3014. return ERROR;
  3015. }
  3016.     
  3017.     return OK;
  3018.     }        
  3019. /***************************************************************************
  3020. *
  3021. * klsiInit - Initialization for the KLSI Chip
  3022. *
  3023. * This device requires that a piece of "Firmware" be downloaded to the Chip 
  3024. * before it starts functioning as an Ethernet adapter. This function does 
  3025. * the device specific initialization, it basically downloads the firmware 
  3026. * on to the chip. Also sets which Interrupt of the device is to be used and 
  3027. * then reset the device.
  3028. *
  3029. * RETURNS : OK or ERROR
  3030. */
  3031. STATUS klsiInit
  3032.     (
  3033.     KLSI_DEVICE * pDevCtrl
  3034.     )
  3035.     {
  3036.     if (klsiDownloadFirmware (pDevCtrl, 
  3037.       klsiNewCode, 
  3038.       lenKlsiNewCode, 
  3039.       KLSI_INTERRUPT_TO_USE, 
  3040.       2) 
  3041.     == ERROR)
  3042. {
  3043. KLSI_LOG (KLSI_DBG_DNLD, " Couldnot download : NewCode n",
  3044.     0, 0, 0, 0, 0, 0);
  3045. return ERROR;
  3046. }
  3047.     if (klsiDownloadFirmware (pDevCtrl, 
  3048.       klsiNewCodeFix, 
  3049.       lenKlsiNewCodeFix, 
  3050.       KLSI_INTERRUPT_TO_USE, 
  3051.       3) 
  3052.     == ERROR)
  3053. {
  3054. KLSI_LOG (KLSI_DBG_DNLD, " Couldnot download : NewCode Fixn", 
  3055.     0, 0, 0, 0, 0, 0);
  3056. return ERROR;
  3057. }
  3058.     if (klsiTriggerFirmware (pDevCtrl, KLSI_INTERRUPT_TO_USE) == ERROR )
  3059. {
  3060. KLSI_LOG (KLSI_DBG_DNLD, " Couldnot Trigger n", 
  3061.     0, 0, 0, 0, 0, 0);
  3062. return ERROR;
  3063. }
  3064.     if (klsiReset (pDevCtrl) == ERROR)
  3065. {
  3066. KLSI_LOG (KLSI_DBG_DNLD, " Couldnot Reset the device n",
  3067.     0, 0, 0, 0, 0, 0);
  3068. return ERROR;
  3069. }
  3070.     return OK;
  3071.     }    
  3072.      
  3073. /***************************************************************************
  3074. *
  3075. * notifyAttach - Notifies registered callers of attachment/removal
  3076. *
  3077. * RETURNS: N/A
  3078. */
  3079. LOCAL VOID notifyAttach
  3080.     (
  3081.     USBD_NODE_ID nodeId,
  3082.     UINT16 attachCode
  3083.     )
  3084.     {
  3085.     pATTACH_REQUEST pRequest = usbListFirst (&reqList);
  3086.     
  3087.     while (pRequest != NULL)
  3088.     {
  3089.     (*pRequest->callback) (pRequest->callbackArg, 
  3090.                    nodeId, 
  3091.    attachCode);
  3092.     pRequest = usbListNext (&pRequest->reqLink);
  3093.     }
  3094.     }
  3095. /***************************************************************************
  3096. *
  3097. * usbKlsiDynamicAttachRegister - Register KLSI device attach callback.
  3098. *
  3099. * <callback> is a caller-supplied function of the form:
  3100. *
  3101. * .CS
  3102. * typedef (*USB_KLSI_ATTACH_CALLBACK) 
  3103. *     (
  3104. *     pVOID arg,
  3105. *     USBD_NODE_ID nodeId,
  3106. *     UINT16 attachCode
  3107. *     );
  3108. * .CE
  3109. *
  3110. * usbKlsiEnd will invoke <callback> each time a KLSI device
  3111. * is attached to or removed from the system.  <arg> is a caller-defined
  3112. * parameter which will be passed to the <callback> each time it is
  3113. * invoked.  The <callback> will also be passed the nodeID of the device 
  3114. * being created/destroyed and an attach code of USB_KLSI_ATTACH or 
  3115. * USB_KLSI_REMOVE.
  3116. *
  3117. * NOTE: The user callback routine should not invoke any driver function that
  3118. * submits IRPs.  Further processing must be done from a different task context.
  3119. * As the driver routines wait for IRP completion, they cannot be invoked from
  3120. * USBD client task's context created for this driver.
  3121. *
  3122. *
  3123. * RETURNS: OK, or ERROR if unable to register callback
  3124. *
  3125. * ERRNO:
  3126. *   S_usbKlsiLib_BAD_PARAM
  3127. *   S_usbKlsiLib_OUT_OF_MEMORY
  3128. */
  3129. STATUS usbKlsiDynamicAttachRegister
  3130.     (
  3131.     USB_KLSI_ATTACH_CALLBACK callback, /* new callback to be registered */
  3132.     pVOID arg                           /* user-defined arg to callback  */
  3133.     )
  3134.     {
  3135.     pATTACH_REQUEST   pRequest;
  3136.     USB_KLSI_DEV  *       pKlsiDev;
  3137.     int status = OK;
  3138.     /* Validate parameters */
  3139.     if (callback == NULL)
  3140.         return (ossStatus (S_usbKlsiLib_BAD_PARAM));
  3141.     OSS_MUTEX_TAKE (klsiMutex, OSS_BLOCK);
  3142.     /* Create a new request structure to track this callback request. */
  3143.     if ((pRequest = OSS_CALLOC (sizeof (*pRequest))) == NULL)
  3144.         {
  3145.         status = ossStatus (S_usbKlsiLib_OUT_OF_MEMORY);
  3146.         }
  3147.     else
  3148.         {
  3149.         pRequest->callback    = callback;
  3150.         pRequest->callbackArg = arg;
  3151.         usbListLink (&reqList, pRequest, &pRequest->reqLink, LINK_TAIL) ;
  3152.     
  3153.        /* 
  3154.         * Perform an initial notification of all currrently attached
  3155.         * KLSI devices.
  3156.         */
  3157.         pKlsiDev = usbListFirst (&klsiDevList);
  3158.         while (pKlsiDev != NULL)
  3159.     {
  3160.             if (pKlsiDev->connected)
  3161.                 (*callback) (arg, pKlsiDev->nodeId, USB_KLSI_ATTACH);
  3162.     pKlsiDev = usbListNext (&pKlsiDev->devLink);
  3163.     }
  3164.         }
  3165.     OSS_MUTEX_RELEASE (klsiMutex);
  3166.     return (ossStatus (status));
  3167.     }
  3168. /***************************************************************************
  3169. *
  3170. * usbKlsiDynamicAttachUnregister - Unregisters KLSI attach callback.
  3171. *
  3172. * This function cancels a previous request to be dynamically notified for
  3173. * KLSI device attachment and removal.  The <callback> and <arg> paramters 
  3174. * must exactly match those passed in a previous call to 
  3175. * usbKlsiDynamicAttachRegister().
  3176. *
  3177. * RETURNS: OK, or ERROR if unable to unregister callback
  3178. *
  3179. * ERRNO:
  3180. *   S_usbKlsiLib_NOT_REGISTERED
  3181. */
  3182. STATUS usbKlsiDynamicAttachUnregister
  3183.     (
  3184.     USB_KLSI_ATTACH_CALLBACK callback, /* callback to be unregistered  */
  3185.     pVOID arg                          /* user-defined arg to callback */
  3186.     )
  3187.     {
  3188.     pATTACH_REQUEST pRequest;
  3189.     int status = S_usbKlsiLib_NOT_REGISTERED;
  3190.     OSS_MUTEX_TAKE (klsiMutex, OSS_BLOCK);
  3191.     pRequest = usbListFirst (&reqList);
  3192.     while (pRequest != NULL)
  3193.         {
  3194.         if ((callback == pRequest->callback) && (arg == pRequest->callbackArg))
  3195.     {
  3196.     /* We found a matching notification request. */
  3197.     usbListUnlink (&pRequest->reqLink);
  3198.             /* Dispose of structure */
  3199.             OSS_FREE (pRequest);
  3200.     status = OK;
  3201.     break;
  3202.     }
  3203.         pRequest = usbListNext (&pRequest->reqLink);
  3204. }
  3205.     OSS_MUTEX_RELEASE (klsiMutex);
  3206.     return (ossStatus (status));
  3207.     }
  3208. /***************************************************************************
  3209. *
  3210. * usbKlsiDevLock - Marks USB_KLSI_DEV structure as in use.
  3211. *
  3212. * A caller uses usbKlsiDevLock() to notify usbKlsiEnd that
  3213. * it is using the indicated USB_KLSI_DEV structure.  usbKlsiEnd maintains
  3214. * a count of callers using a particular USB_KLSI_DEV structure so that it 
  3215. * knows when it is safe to dispose of a structure when the underlying
  3216. * USB_KLSI_DEV is removed from the system.  So long as the "lock count"
  3217. * is greater than zero, usbKlsiEnd will not dispose of an USB_KLSI_DEV
  3218. * structure.
  3219. *
  3220. * RETURNS: OK, or ERROR if unable to mark USB_KLSI_DEV structure in use.
  3221. */
  3222. STATUS usbKlsiDevLock
  3223.     (
  3224.     USBD_NODE_ID nodeId   /* NodeId of the USB_KLSI_DEV to be marked as in use */
  3225.     )
  3226.     {
  3227.     USB_KLSI_DEV* pKlsiDev = klsiFindDevice (nodeId);
  3228.     if ( pKlsiDev == NULL)
  3229.         return (ERROR);
  3230.     pKlsiDev->lockCount++;
  3231.     return (OK);
  3232.     }
  3233. /***************************************************************************
  3234. *
  3235. * usbKlsiDevUnlock - Marks USB_KLSI_DEV structure as unused.
  3236. *
  3237. * This function releases a lock placed on an USB_KLSI_DEV structure.  When a
  3238. * caller no longer needs an USB_KLSI_DEV structure for which it has previously
  3239. * called usbKlsiDevLock(), then it should call this function to
  3240. * release the lock.
  3241. *
  3242. * RETURNS: OK, or ERROR if unable to mark USB_KLSI_DEV structure unused
  3243. *
  3244. * ERRNO:
  3245. *   S_usbKlsiLib_NOT_LOCKED
  3246. */
  3247. STATUS usbKlsiDevUnlock
  3248.     (
  3249.     USBD_NODE_ID nodeId    /* NodeId of the BLK_DEV to be marked as unused */
  3250.     )
  3251.     {
  3252.     int status = OK;
  3253.     USB_KLSI_DEV *      pKlsiDev = klsiFindDevice (nodeId);
  3254.  
  3255.     if ( pKlsiDev == NULL)
  3256.         return (ERROR);
  3257.     OSS_MUTEX_TAKE (klsiMutex, OSS_BLOCK);
  3258.     if (pKlsiDev->lockCount == 0)
  3259.         {
  3260.         status = S_usbKlsiLib_NOT_LOCKED;
  3261.         }
  3262.     else
  3263.      {
  3264.        /* 
  3265. * If this is the last lock and the underlying KLSI device is
  3266.         * no longer connected, then dispose of the device.
  3267.         */
  3268.      if ((--pKlsiDev->lockCount == 0) && (!pKlsiDev->connected))
  3269. klsiDestroyDevice ((KLSI_DEVICE *)pKlsiDev->pDevStructure);
  3270.      }
  3271.     OSS_MUTEX_RELEASE (klsiMutex);
  3272.     return (ossStatus (status));
  3273.     }