1/* 2 * 3 * @APPLE_LICENSE_HEADER_START@ 4 * 5 * Copyright (c) 1998-2004 Apple Computer, Inc. All Rights Reserved. 6 * 7 * This file contains Original Code and/or Modifications of Original Code 8 * as defined in and that are subject to the Apple Public Source License 9 * Version 2.0 (the 'License'). You may not use this file except in 10 * compliance with the License. Please obtain a copy of the License at 11 * http://www.opensource.apple.com/apsl/ and read it before using this 12 * file. 13 * 14 * The Original Code and all software distributed under the License are 15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 19 * Please see the License for the specific language governing rights and 20 * limitations under the License. 21 * 22 * @APPLE_LICENSE_HEADER_END@ 23 */ 24 25#ifndef __APPLEUSBCDCDMM__ 26#define __APPLEUSBCDCDMM__ 27 28#include "AppleUSBCDCCommon.h" 29#include "AppleUSBCDC.h" 30 31 // Common Defintions 32 33#define LDEBUG 0 // for debugging 34#define USE_ELG 0 // to Event LoG (via kprintf and Firewire) - LDEBUG must also be set 35#define USE_IOL 0 // to IOLog - LDEBUG must also be set 36#define LOG_DATA 0 // logs data to the appropriate log - LDEBUG must also be set 37#define DUMPALL 0 // Dumps all the data to the log - LOG_DATA must also be set 38 39#define Sleep_Time 20 40 41#define Log IOLog 42#if USE_ELG 43 #undef Log 44 #define Log kprintf 45#endif 46 47#if LDEBUG 48 #if USE_ELG 49 #define XTRACE(ID,A,B,STRING) {Log("%8p %8x %8x " DEBUG_NAME ": " STRING "\n",(void *)(ID),(unsigned int)(A),(unsigned int)(B));} 50 #define XTRACEP(ID,A,B,STRING) {Log("%8p %8p %8p " DEBUG_NAME ": " STRING "\n",(void *)(ID),(void *)(A),(void *)(B));} 51 #else /* not USE_ELG */ 52 #if USE_IOL 53 #define XTRACE(ID,A,B,STRING) {Log("%8p %8x %8x " DEBUG_NAME ": " STRING "\n",(void *)(ID),(unsigned int)(A),(unsigned int)(B)); IOSleep(Sleep_Time);} 54 #define XTRACEP(ID,A,B,STRING) {Log("%8p %8p %8p " DEBUG_NAME ": " STRING "\n",(void *)(ID),(void *)(A),(void *)(B)); IOSleep(Sleep_Time);} 55 #else 56 #define XTRACE(id, x, y, msg) 57 #define XTRACEP(id, x, y, msg) 58 #endif /* USE_IOL */ 59 #endif /* USE_ELG */ 60 #if LOG_DATA 61 #define LogData(D, C, b) USBLogData((UInt8)D, (SInt32)C, (char *)b) 62 #define meLogData(D, C, b) me->USBLogData((UInt8)D, (SInt32)C, (char *)b) 63 #else /* not LOG_DATA */ 64 #define LogData(D, C, b) 65 #define meLogData(D, C, b) 66 #endif /* LOG_DATA */ 67#else /* not LDEBUG */ 68 #define XTRACE(id, x, y, msg) 69 #define XTRACEP(id, x, y, msg) 70 #define LogData(D, C, b) 71 #define meLogData(D, C, b) 72 #undef USE_ELG 73 #undef USE_IOL 74 #undef LOG_DATA 75#endif /* LDEBUG */ 76 77#define ALERT(A,B,STRING) Log("%8x %8x " DEBUG_NAME ": " STRING "\n", (unsigned int)(A), (unsigned int)(B)) 78 79enum 80{ 81 kDataIn = 0, 82 kDataOut, 83 kDataOther 84}; 85 86#define baseName "dmmcontrol" 87#define defaultName "USB Modem" 88#define productNameLength 32 // Arbitrary length 89#define propertyTag "Product Name" 90#define hiddenTag "HiddenPort" 91 92#define kDefaultBaudRate 9600 93#define kMaxBaudRate 230400 94#define kMaxCirBufferSize 4096 95 96 // USB CDC DMM Defintions 97 98#define kUSBbRxCarrier 0x01 // Carrier Detect 99#define kUSBDCD kUSBbRxCarrier 100#define kUSBbTxCarrier 0x02 // Data Set Ready 101#define kUSBDSR kUSBbTxCarrier 102#define kUSBbBreak 0x04 103#define kUSBbRingSignal 0x08 104#define kUSBbFraming 0x10 105#define kUSBbParity 0x20 106#define kUSBbOverRun 0x40 107 108#define kDTROff 0 109#define kRTSOff 0 110#define kDTROn 1 111#define kRTSOn 2 112 113typedef struct 114{ 115 UInt32 dwDTERate; 116 UInt8 bCharFormat; 117 UInt8 bParityType; 118 UInt8 bDataBits; 119} LineCoding; 120 121#define dwDTERateOffset 0 122 123#define wValueOffset 2 124#define wIndexOffset 4 125#define wLengthOffset 6 126 127 // SccQueuePrimatives.h 128 129typedef struct CirQueue 130{ 131 UInt8 *Start; 132 UInt8 *End; 133 UInt8 *NextChar; 134 UInt8 *LastChar; 135 size_t Size; 136 size_t InQueue; 137} CirQueue; 138 139typedef enum QueueStatus 140{ 141 queueNoError = 0, 142 queueFull, 143 queueEmpty, 144 queueMaxStatus 145} QueueStatus; 146 147 // Miscellaneous 148 149#define BIGGEST_EVENT 3 150 151#define SPECIAL_SHIFT (5) 152#define SPECIAL_MASK ((1<<SPECIAL_SHIFT) - 1) 153#define STATE_ALL (PD_RS232_S_MASK | PD_S_MASK) 154#define FLOW_RX_AUTO (PD_RS232_A_RFR | PD_RS232_A_DTR | PD_RS232_A_RXO) 155#define FLOW_TX_AUTO (PD_RS232_A_CTS | PD_RS232_A_DSR | PD_RS232_A_TXO | PD_RS232_A_DCD) 156#define CAN_BE_AUTO (FLOW_RX_AUTO | FLOW_TX_AUTO) 157#define CAN_NOTIFY (PD_RS232_N_MASK) 158#define EXTERNAL_MASK (PD_S_MASK | (PD_RS232_S_MASK & ~PD_RS232_S_LOOP)) 159#define INTERNAL_DELAY (PD_RS232_S_LOOP) 160#define DEFAULT_AUTO (PD_RS232_A_RFR | PD_RS232_A_CTS | PD_RS232_A_DSR) 161#define DEFAULT_NOTIFY 0x00 162#define DEFAULT_STATE (PD_S_TX_ENABLE | PD_S_RX_ENABLE | PD_RS232_A_TXO | PD_RS232_A_RXO) 163 164#define IDLE_XO 0 165#define NEEDS_XOFF 1 166#define SENT_XOFF -1 167#define NEEDS_XON 2 168#define SENT_XON -2 169 170#define INT_BUFF_SIZE 16 171 172typedef struct 173{ 174 UInt32 ints; 175 UInt32 txInts; 176 UInt32 rxInts; 177 UInt32 mdmInts; 178 UInt32 txChars; 179 UInt32 rxChars; 180} Stats_t; 181 182typedef struct BufferMarks 183{ 184 unsigned long BufferSize; 185 unsigned long HighWater; 186 unsigned long LowWater; 187 bool OverRun; 188} BufferMarks; 189 190typedef struct 191{ 192 193 // State and serialization variables 194 195 UInt32 State; 196 UInt32 WatchStateMask; 197 198 // queue control structures: 199 200 CirQueue RX; 201 CirQueue TX; 202 203 BufferMarks RXStats; 204 BufferMarks TXStats; 205 206 // UART configuration info: 207 208 UInt32 CharLength; 209 UInt32 StopBits; 210 UInt32 TX_Parity; 211 UInt32 RX_Parity; 212 UInt32 BaudRate; 213 UInt8 FCRimage; 214 UInt8 IERmask; 215 bool MinLatency; 216 217 // flow control state & configuration: 218 219 UInt8 XONchar; 220 UInt8 XOFFchar; 221 UInt32 SWspecial[ 0x100 >> SPECIAL_SHIFT ]; 222 UInt32 FlowControl; // notify-on-delta & auto_control 223 224 SInt16 RXOstate; // Indicates our receive state. 225 SInt16 TXOstate; // Indicates our transmit state, if we have received any Flow Control. 226 227 IOThread FrameTOEntry; 228 229 mach_timespec DataLatInterval; 230 mach_timespec CharLatInterval; 231 232 // extensions for USB Driver 233 234// UInt8 InterfaceNumber; 235 236 UInt32 OutPacketSize; 237 UInt32 InPacketSize; 238 239 UInt32 LastCharLength; 240 UInt32 LastStopBits; 241 UInt32 LastTX_Parity; 242 UInt32 LastBaudRate; 243 244} PortInfo_t; 245 246 /* AppleUSBCDCDMM.h - This file contains the class definition for the */ 247 /* USB Communication Device Class (CDC) DMM Interface driver. */ 248 249class AppleUSBCDCDMM : public IOSerialDriverSync 250{ 251 OSDeclareDefaultStructors(AppleUSBCDCDMM); // Constructor & Destructor stuff 252 253private: 254 UInt16 fSessions; // Number of active sessions 255 bool fTerminate; // Are we being terminated (ie the device was unplugged) 256 bool fStopping; // Are we being "stopped" 257 UInt8 fProductName[productNameLength]; // Product String from the Device 258 259 bool fReadDead; // Is the interrupt pipe read dead 260 IOUSBPipe *fIntPipe; // The interrupt pipe 261 IOBufferMemoryDescriptor *fIntPipeMDP; // Interrupt pipe memory descriptor 262 UInt8 *fIntPipeBuffer; // Interrupt pipe buffer 263 UInt16 fIntBufferSize; // Size of the interrupt buffer 264 IOUSBCompletion fIntCompletionInfo; // Interrupt completion routine 265 IOUSBCompletion fMERCompletionInfo; // MER completion routine 266 IOUSBCompletion fRspCompletionInfo; // Response completion routine 267 UInt8 fInterfaceNumber; // My interface number 268 269 UInt8 *fInBuffer; 270 UInt8 *fOutBuffer; 271 272 static void intReadComplete(void *obj, void *param, IOReturn rc, UInt32 remaining); 273 static void merWriteComplete(void *obj, void *param, IOReturn rc, UInt32 remaining); 274 static void rspComplete(void *obj, void *param, IOReturn rc, UInt32 remaining); 275 276public: 277 278 IOUSBInterface *fInterface; 279 IOWorkLoop *fWorkLoop; 280 IOCommandGate *fCommandGate; 281 PortInfo_t fPort; // Port structure 282 283 UInt16 fMax_Command; // maximum command size 284 285// UInt8 fConfigAttributes; // Configuration descriptor attributes 286 287 // IOKit methods: 288 289 virtual IOService *probe(IOService *provider, SInt32 *score); 290 virtual bool start(IOService *provider); 291 virtual void stop(IOService *provider); 292 virtual IOReturn message(UInt32 type, IOService *provider, void *argument = 0); 293 294 // IOSerialDriverSync Abstract Method Implementation 295 296 virtual IOReturn acquirePort(bool sleep, void *refCon); 297 virtual IOReturn releasePort(void *refCon); 298 virtual UInt32 getState(void *refCon); 299 virtual IOReturn setState(UInt32 state, UInt32 mask, void *refCon); 300 virtual IOReturn watchState(UInt32 *state, UInt32 mask, void *refCon); 301 virtual UInt32 nextEvent(void *refCon); 302 virtual IOReturn executeEvent(UInt32 event, UInt32 data, void *refCon); 303 virtual IOReturn requestEvent(UInt32 event, UInt32 *data, void *refCon); 304 virtual IOReturn enqueueEvent(UInt32 event, UInt32 data, bool sleep, void *refCon); 305 virtual IOReturn dequeueEvent(UInt32 *event, UInt32 *data, bool sleep, void *refCon); 306 virtual IOReturn enqueueData(UInt8 *buffer, UInt32 size, UInt32 * count, bool sleep, void *refCon); 307 virtual IOReturn dequeueData(UInt8 *buffer, UInt32 size, UInt32 *count, UInt32 min, void *refCon); 308 309 // Static stubs for IOCommandGate::runAction 310 311 static IOReturn stopAction(OSObject *owner, void *, void *, void *, void *); 312 static IOReturn acquirePortAction(OSObject *owner, void *arg0, void *, void *, void *); 313 static IOReturn releasePortAction(OSObject *owner, void *, void *, void *, void *); 314 static IOReturn getStateAction(OSObject *owner, void *, void *, void *, void *); 315 static IOReturn setStateAction(OSObject *owner, void *arg0, void *arg1, void *, void *); 316 static IOReturn watchStateAction(OSObject *owner, void *arg0, void *arg1, void *, void *); 317 static IOReturn executeEventAction(OSObject *owner, void *arg0, void *arg1, void *, void *); 318 static IOReturn enqueueDataAction(OSObject *owner, void *arg0, void *arg1, void *arg2, void *arg3); 319 static IOReturn dequeueDataAction(OSObject *owner, void *arg0, void *arg1, void *arg2, void *arg3); 320 321 // Gated methods called by the Static stubs 322 323 virtual void stopGated(void); 324 virtual IOReturn acquirePortGated(bool sleep); 325 virtual IOReturn releasePortGated(void); 326 virtual UInt32 getStateGated(void); 327 virtual IOReturn setStateGated(UInt32 *pState, UInt32 *pMask); 328 virtual IOReturn watchStateGated(UInt32 *state, UInt32 *pMask); 329 virtual IOReturn executeEventGated(UInt32 *event, UInt32 *data); 330 virtual IOReturn enqueueDataGated(UInt8 *buffer, UInt32 *pSize, UInt32 *count, bool *pSleep); 331 virtual IOReturn dequeueDataGated(UInt8 *buffer, UInt32 *pSize, UInt32 *count, UInt32 *pMin); 332 333 // DMM Driver Methods 334 335 void USBLogData(UInt8 Dir, SInt32 Count, char *buf); 336 bool configureDMM(void); 337 bool getFunctionalDescriptors(void); 338 bool createSuffix(unsigned char *sufKey); 339 bool createSerialStream(void); 340 bool setUpTransmit(void); 341 void startTransmission(void); 342 IOReturn sendMERRequest(UInt8 request, UInt16 val, UInt16 len, UInt8 *buff, IOUSBCompletion *Comp); 343 void setLineCoding(void); 344 void setControlLineState(bool RTS, bool DTR); 345 void sendBreak(bool sBreak); 346 IOReturn checkPipe(IOUSBPipe *thePipe, bool devReq); 347 void initStructure(void); 348 void setStructureDefaults(void); 349 bool allocateResources(void); 350 void releaseResources(void); 351 void freeRingBuffer(CirQueue *Queue); 352 bool allocateRingBuffer(CirQueue *Queue, size_t BufferSize); 353 354private: 355 356 // QueuePrimatives 357 358 QueueStatus AddBytetoQueue(CirQueue *Queue, char Value); 359 QueueStatus GetBytetoQueue(CirQueue *Queue, UInt8 *Value); 360 QueueStatus InitQueue(CirQueue *Queue, UInt8 *Buffer, size_t Size); 361 QueueStatus CloseQueue(CirQueue *Queue); 362 size_t AddtoQueue(CirQueue *Queue, UInt8 *Buffer, size_t Size); 363 size_t RemovefromQueue(CirQueue *Queue, UInt8 *Buffer, size_t MaxSize); 364 size_t FreeSpaceinQueue(CirQueue *Queue); 365 size_t UsedSpaceinQueue(CirQueue *Queue); 366 size_t GetQueueSize(CirQueue *Queue); 367 QueueStatus GetQueueStatus(CirQueue *Queue); 368 UInt16 isCRinQueue(CirQueue *Queue); 369 void CheckQueues(void); 370 371}; /* end class AppleUSBCDCDMM */ 372#endif