1 /*=========================================================================== 2 FILE: 3 QMIDevice.h 4 5 DESCRIPTION: 6 Functions related to the QMI interface device 7 8 FUNCTIONS: 9 Generic functions 10 IsDeviceValid 11 PrintHex 12 GobiSetDownReason 13 GobiClearDownReason 14 GobiTestDownReason 15 16 Driver level asynchronous read functions 17 ResubmitIntURB 18 ReadCallback 19 IntCallback 20 StartRead 21 KillRead 22 23 Internal read/write functions 24 ReadAsync 25 UpSem 26 ReadSync 27 WriteSyncCallback 28 WriteSync 29 30 Internal memory management functions 31 GetClientID 32 ReleaseClientID 33 FindClientMem 34 AddToReadMemList 35 PopFromReadMemList 36 AddToNotifyList 37 NotifyAndPopNotifyList 38 AddToURBList 39 PopFromURBList 40 41 Internal userspace wrapper functions 42 UserspaceunlockedIOCTL 43 44 Userspace wrappers 45 UserspaceOpen 46 UserspaceIOCTL 47 UserspaceClose 48 UserspaceRead 49 UserspaceWrite 50 UserspacePoll 51 52 Initializer and destructor 53 RegisterQMIDevice 54 DeregisterQMIDevice 55 56 Driver level client management 57 QMIReady 58 QMIWDSCallback 59 SetupQMIWDSCallback 60 QMIDMSGetMEID 61 62 Copyright (c) 2011, Code Aurora Forum. All rights reserved. 63 64 Redistribution and use in source and binary forms, with or without 65 modification, are permitted provided that the following conditions are met: 66 * Redistributions of source code must retain the above copyright 67 notice, this list of conditions and the following disclaimer. 68 * Redistributions in binary form must reproduce the above copyright 69 notice, this list of conditions and the following disclaimer in the 70 documentation and/or other materials provided with the distribution. 71 * Neither the name of Code Aurora Forum nor 72 the names of its contributors may be used to endorse or promote 73 products derived from this software without specific prior written 74 permission. 75 76 77 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 78 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 79 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 80 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 81 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 82 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 83 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 84 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 85 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 86 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 87 POSSIBILITY OF SUCH DAMAGE. 88 ===========================================================================*/ 89 90 //--------------------------------------------------------------------------- 91 // Pragmas 92 //--------------------------------------------------------------------------- 93 #pragma once 94 95 //--------------------------------------------------------------------------- 96 // Include Files 97 //--------------------------------------------------------------------------- 98 #include "Structs.h" 99 #include "QMI.h" 100 101 /*=========================================================================*/ 102 // Generic functions 103 /*=========================================================================*/ 104 105 #ifdef __QUECTEL_INTER__ 106 107 // Basic test to see if device memory is valid 108 static bool IsDeviceValid( sGobiUSBNet * pDev ); 109 110 /*=========================================================================*/ 111 // Driver level asynchronous read functions 112 /*=========================================================================*/ 113 114 // Resubmit interrupt URB, re-using same values 115 static int ResubmitIntURB( struct urb * pIntURB ); 116 117 // Read callback 118 // Put the data in storage and notify anyone waiting for data 119 #if (LINUX_VERSION_CODE > KERNEL_VERSION( 2,6,18 )) 120 static void ReadCallback( struct urb * pReadURB ); 121 #else 122 static void ReadCallback(struct urb *pReadURB, struct pt_regs *regs); 123 #endif 124 125 // Inturrupt callback 126 // Data is available, start a read URB 127 #if (LINUX_VERSION_CODE > KERNEL_VERSION( 2,6,18 )) 128 static void IntCallback( struct urb * pIntURB ); 129 #else 130 static void IntCallback(struct urb *pIntURB, struct pt_regs *regs); 131 #endif 132 133 /*=========================================================================*/ 134 // Internal read/write functions 135 /*=========================================================================*/ 136 137 // Start asynchronous read 138 // Reading client's data store, not device 139 static int ReadAsync( 140 sGobiUSBNet * pDev, 141 u16 clientID, 142 u16 transactionID, 143 void (*pCallback)(sGobiUSBNet *, u16, void *), 144 void * pData ); 145 146 // Notification function for synchronous read 147 static void UpSem( 148 sGobiUSBNet * pDev, 149 u16 clientID, 150 void * pData ); 151 152 // Start synchronous read 153 // Reading client's data store, not device 154 static int ReadSync( 155 sGobiUSBNet * pDev, 156 void ** ppOutBuffer, 157 u16 clientID, 158 u16 transactionID ); 159 160 // Write callback 161 #if (LINUX_VERSION_CODE > KERNEL_VERSION( 2,6,18 )) 162 static void WriteSyncCallback( struct urb * pWriteURB ); 163 #else 164 static void WriteSyncCallback(struct urb *pWriteURB, struct pt_regs *regs); 165 #endif 166 167 // Start synchronous write 168 static int WriteSync( 169 sGobiUSBNet * pDev, 170 char * pInWriteBuffer, 171 int size, 172 u16 clientID ); 173 174 /*=========================================================================*/ 175 // Internal memory management functions 176 /*=========================================================================*/ 177 178 // Create client and allocate memory 179 static int GetClientID( 180 sGobiUSBNet * pDev, 181 u8 serviceType ); 182 183 // Release client and free memory 184 static void ReleaseClientID( 185 sGobiUSBNet * pDev, 186 u16 clientID ); 187 188 // Find this client's memory 189 static sClientMemList * FindClientMem( 190 sGobiUSBNet * pDev, 191 u16 clientID ); 192 193 // Add Data to this client's ReadMem list 194 static bool AddToReadMemList( 195 sGobiUSBNet * pDev, 196 u16 clientID, 197 u16 transactionID, 198 void * pData, 199 u16 dataSize ); 200 201 // Remove data from this client's ReadMem list if it matches 202 // the specified transaction ID. 203 static bool PopFromReadMemList( 204 sGobiUSBNet * pDev, 205 u16 clientID, 206 u16 transactionID, 207 void ** ppData, 208 u16 * pDataSize ); 209 210 // Add Notify entry to this client's notify List 211 static bool AddToNotifyList( 212 sGobiUSBNet * pDev, 213 u16 clientID, 214 u16 transactionID, 215 void (* pNotifyFunct)(sGobiUSBNet *, u16, void *), 216 void * pData ); 217 218 // Remove first Notify entry from this client's notify list 219 // and Run function 220 static bool NotifyAndPopNotifyList( 221 sGobiUSBNet * pDev, 222 u16 clientID, 223 u16 transactionID ); 224 225 // Add URB to this client's URB list 226 static bool AddToURBList( 227 sGobiUSBNet * pDev, 228 u16 clientID, 229 struct urb * pURB ); 230 231 // Remove URB from this client's URB list 232 static struct urb * PopFromURBList( 233 sGobiUSBNet * pDev, 234 u16 clientID ); 235 236 /*=========================================================================*/ 237 // Internal userspace wrappers 238 /*=========================================================================*/ 239 240 // Userspace unlocked ioctl 241 static long UserspaceunlockedIOCTL( 242 struct file * pFilp, 243 unsigned int cmd, 244 unsigned long arg ); 245 246 /*=========================================================================*/ 247 // Userspace wrappers 248 /*=========================================================================*/ 249 250 // Userspace open 251 static int UserspaceOpen( 252 struct inode * pInode, 253 struct file * pFilp ); 254 255 #if (LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,36 )) 256 // Userspace ioctl 257 static int UserspaceIOCTL( 258 struct inode * pUnusedInode, 259 struct file * pFilp, 260 unsigned int cmd, 261 unsigned long arg ); 262 #endif 263 264 // Userspace close 265 #define quectel_no_for_each_process 266 #ifdef quectel_no_for_each_process 267 static int UserspaceClose( 268 struct inode * pInode, 269 struct file * pFilp ); 270 #else 271 #if (LINUX_VERSION_CODE > KERNEL_VERSION( 2,6,14 )) 272 static int UserspaceClose( 273 struct file * pFilp, 274 fl_owner_t unusedFileTable ); 275 #else 276 static int UserspaceClose( struct file * pFilp ); 277 #endif 278 #endif 279 280 // Userspace read (synchronous) 281 static ssize_t UserspaceRead( 282 struct file * pFilp, 283 char __user * pBuf, 284 size_t size, 285 loff_t * pUnusedFpos ); 286 287 // Userspace write (synchronous) 288 static ssize_t UserspaceWrite( 289 struct file * pFilp, 290 const char __user * pBuf, 291 size_t size, 292 loff_t * pUnusedFpos ); 293 294 static unsigned int UserspacePoll( 295 struct file * pFilp, 296 struct poll_table_struct * pPollTable ); 297 298 /*=========================================================================*/ 299 // Driver level client management 300 /*=========================================================================*/ 301 302 // Check if QMI is ready for use 303 static bool QMIReady( 304 sGobiUSBNet * pDev, 305 u16 timeout ); 306 307 // QMI WDS callback function 308 static void QMIWDSCallback( 309 sGobiUSBNet * pDev, 310 u16 clientID, 311 void * pData ); 312 313 // Fire off reqests and start async read for QMI WDS callback 314 static int SetupQMIWDSCallback( sGobiUSBNet * pDev ); 315 316 // Register client, send req and parse MEID response, release client 317 static int QMIDMSGetMEID( sGobiUSBNet * pDev ); 318 319 // Register client, send req and parse Data format response, release client 320 static int QMIWDASetDataFormat( sGobiUSBNet * pDev, int qmap_mode, int *rx_urb_size ); 321 #endif 322 323 // Print Hex data, for debug purposes 324 void QuecPrintHex( 325 void * pBuffer, 326 u16 bufSize ); 327 328 // Sets mDownReason and turns carrier off 329 void QuecGobiSetDownReason( 330 sGobiUSBNet * pDev, 331 u8 reason ); 332 333 // Clear mDownReason and may turn carrier on 334 void QuecGobiClearDownReason( 335 sGobiUSBNet * pDev, 336 u8 reason ); 337 338 // Tests mDownReason and returns whether reason is set 339 bool QuecGobiTestDownReason( 340 sGobiUSBNet * pDev, 341 u8 reason ); 342 343 // Start continuous read "thread" 344 int QuecStartRead( sGobiUSBNet * pDev ); 345 346 // Kill continuous read "thread" 347 void QuecKillRead( sGobiUSBNet * pDev ); 348 349 /*=========================================================================*/ 350 // Initializer and destructor 351 /*=========================================================================*/ 352 353 // QMI Device initialization function 354 int QuecRegisterQMIDevice( sGobiUSBNet * pDev ); 355 356 // QMI Device cleanup function 357 void QuecDeregisterQMIDevice( sGobiUSBNet * pDev ); 358 359 int QuecQMIWDASetDataFormat( sGobiUSBNet * pDev, int qmap_mode, int *rx_urb_size ); 360 361 #define PrintHex QuecPrintHex 362 #define GobiSetDownReason QuecGobiSetDownReason 363 #define GobiClearDownReason QuecGobiClearDownReason 364 #define GobiTestDownReason QuecGobiTestDownReason 365 #define StartRead QuecStartRead 366 #define KillRead QuecKillRead 367 #define RegisterQMIDevice QuecRegisterQMIDevice 368 #define DeregisterQMIDevice QuecDeregisterQMIDevice 369