1 2 /* Copyright (c) 2000 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * The contents of this file constitute Original Code as defined in and 7 * are subject to the Apple Public Source License Version 1.1 (the 8 * "License"). You may not use this file except in compliance with the 9 * License. Please obtain a copy of the License at 10 * http://www.apple.com/publicsource and read it before using this file. 11 * 12 * This Original Code and all software distributed under the License are 13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 * License for the specific language governing rights and limitations 18 * under the License. 19 * 20 * @APPLE_LICENSE_HEADER_END@ 21 */ 22 23#ifndef _APPLEUSBIRDA_ 24#define _APPLEUSBIRDA_ 25 26#include <IOKit/usb/IOUSBDevice.h> 27#include <IOKit/serial/IOSerialDriverSync.h> 28 29#include "AppleIrDA.h" 30 31#define defaultName "IrDA Device" 32#define productNameLength 32 // Arbitrary length 33#define propertyTag "Product Name" 34 35 36 /* IrDA USB stuff */ 37 38#define USBIrDAClassDescriptor 0x21 39 40enum // usb-irda bridge baud codes, in both rcv and xmit headers 41{ 42 kLinkSpeedIgnored = 0, 43 kLinkSpeed2400 = 1, 44 kLinkSpeed9600 = 2, 45 kLinkSpeed19200 = 3, 46 kLinkSpeed38400 = 4, 47 kLinkSpeed57600 = 5, 48 kLinkSpeed115200 = 6, 49 kLinkSpeed576000 = 7, 50 kLinkSpeed1152000 = 8, 51 kLinkSpeed4000000 = 9, 52 53 kLinkSpeedMask = 0x0f // low four bits in the inbound/outbound headers 54}; 55 56 /* PPCSerialPort.h */ 57 58#define SPECIAL_SHIFT (5) 59#define SPECIAL_MASK ((1<<SPECIAL_SHIFT) - 1) 60#define STATE_ALL ( PD_RS232_S_MASK | PD_S_MASK ) 61#define FLOW_RX_AUTO ( PD_RS232_A_RFR | PD_RS232_A_DTR | PD_RS232_A_RXO ) 62#define FLOW_TX_AUTO ( PD_RS232_A_CTS | PD_RS232_A_DSR | PD_RS232_A_TXO | PD_RS232_A_DCD ) 63#define CAN_BE_AUTO ( FLOW_RX_AUTO | FLOW_TX_AUTO ) 64#define CAN_NOTIFY ( PD_RS232_N_MASK ) 65#define EXTERNAL_MASK ( PD_S_MASK | (PD_RS232_S_MASK & ~PD_RS232_S_LOOP) ) 66#define INTERNAL_DELAY ( PD_RS232_S_LOOP ) 67#define DEFAULT_AUTO ( PD_RS232_A_DTR | PD_RS232_A_RFR | PD_RS232_A_CTS | PD_RS232_A_DSR ) 68#define DEFAULT_NOTIFY 0x00 69#define DEFAULT_STATE ( PD_S_TX_ENABLE | PD_S_RX_ENABLE | PD_RS232_A_TXO | PD_RS232_A_RXO ) 70 71#define IDLE_XO 0 72#define NEEDS_XOFF 1 73#define SENT_XOFF -1 74#define NEEDS_XON 2 75#define SENT_XON -2 76 77#define INTERRUPT_BUFF_SIZE 1 78#define USBLapPayLoad 2048 79 80typedef struct 81{ 82 UInt32 ints; 83 UInt32 txInts; 84 UInt32 rxInts; 85 UInt32 mdmInts; 86 UInt32 txChars; 87 UInt32 rxChars; 88} Stats_t; 89 90typedef struct BufferMarks 91{ 92 unsigned long BufferSize; 93 unsigned long HighWater; 94 unsigned long LowWater; 95 bool OverRun; 96} BufferMarks; 97 98typedef struct 99{ 100 UInt32 State; 101 UInt32 WatchStateMask; 102 IOLock *serialRequestLock; 103 104 // queue control structures: 105 106 CirQueue RX; 107 CirQueue TX; 108 109 BufferMarks RXStats; 110 BufferMarks TXStats; 111 112 // UART configuration info: 113 114 UInt32 CharLength; 115 UInt32 StopBits; 116 UInt32 TX_Parity; 117 UInt32 RX_Parity; 118 UInt32 BaudRate; 119 UInt8 FCRimage; 120 UInt8 IERmask; 121 bool MinLatency; 122 123 // flow control state & configuration: 124 125 UInt8 XONchar; 126 UInt8 XOFFchar; 127 UInt32 SWspecial[ 0x100 >> SPECIAL_SHIFT ]; 128 UInt32 FlowControl; // notify-on-delta & auto_control 129 130 int RXOstate; /* Indicates our receive state. */ 131 int TXOstate; /* Indicates our transmit state, if we have received any Flow Control. */ 132 133 IOThread FrameTOEntry; 134 135 mach_timespec DataLatInterval; 136 mach_timespec CharLatInterval; 137 138 bool AreTransmitting; 139 140 /* extensions to handle the Driver */ 141 142 bool isDriver; 143 void *DriverPowerRegister; 144 UInt32 DriverPowerMask; 145 146 147} PortInfo_t; 148 149class IrDAComm; 150class AppleUSBIrDADriver; 151 152 /* AppleUSBIrDA.h - This file contains definitions for IrDA */ 153class AppleUSBIrDA : public AppleIrDASerial // glue for IrDA to call the USB IrDA Driver 154{ 155 OSDeclareDefaultStructors( AppleUSBIrDA ) ; /* Constructor & Destructor stuff */ 156public: 157 bool attach(AppleUSBIrDADriver *provider); // IOSerialStream attach requires a IOSerialDriverSync 158 159 void Add_RXBytes( UInt8 *Buffer, size_t Size ); 160 SInt16 SetBofCount( SInt16 bof_count ); 161 UInt16 SetSpeed( UInt32 brate ); 162 bool SetUpTransmit( void ); 163 164 IOReturn StartTransmit( UInt32 control_length, UInt8 *control_buffer, UInt32 data_length, UInt8 *data_buffer ); 165 USBIrDAQoS* GetIrDAQoS( void ); 166 IrDAComm* GetIrDAComm( void ); 167 void GetIrDAStatus( IrDAStatus *status ); 168 IOReturn SetIrDAUserClientState( bool IrDAOn ); 169}; 170 171class AppleUSBIrDADriver : public IOSerialDriverSync 172{ 173 OSDeclareDefaultStructors( AppleUSBIrDADriver ) ; /* Constructor & Destructor stuff */ 174 175private: 176 UInt32 fCount; // usb write length 177 UInt8 fSessions; // Active sessions (count of opens on /dev/tty entries) 178 bool fUserClientStarted; // user/client has started (stopped) us 179 bool fUSBStarted; // usb family has started (stopped) us 180 bool fTerminate; // Are we being terminated (ie the device was unplugged) 181 UInt8 fProductName[productNameLength]; // Actually the product String from the Device 182 PortInfo_t *fPort; // The Port 183 bool fReadActive; // usb read is active 184 bool fWriteActive; // usb write is active 185 UInt8 fPowerState; // off,on ordinal for power management 186 187 188 // Some of these globals would normally be by port but as we only have one port it doesn't really matter 189 190 IrDAComm *fIrDA; // IrDA (IrCOMM) object 191 AppleUSBIrDA *fNub; // glue back to IOSerialStream side 192 AppleIrDA *fUserClientNub; // nub to publish newUserClient for us 193 USBIrDAQoS fQoS; // Quality of Service 194 bool fIrDAOn; // IrDA state (on or off) 195 bool fSuspendFail; // Suspend not supported or failed 196 197 UInt8 fBaudCode; // encoded baud code for change speed byte 198 UInt8 fBofsCode; // extra bof count (encoded but unshifted) 199 UInt8 fMediabusy; // media busy flag (0 or 1) 200 UInt8 fLastChangeByte; // saved BOF / baud code byte (send only if changed) 201 UInt32 fCurrentBaud; // current speed in bps 202 203 IOBufferMemoryDescriptor *fpinterruptPipeMDP; 204 IOBufferMemoryDescriptor *fpPipeInMDP; 205 IOBufferMemoryDescriptor *fpPipeOutMDP; 206 207 UInt8 *fpinterruptPipeBuffer; 208 UInt8 *fPipeInBuffer; 209 UInt8 *fPipeOutBuffer; 210 211 UInt8 fpInterfaceNumber; 212 213 IOUSBCompletion finterruptCompletionInfo; 214 IOUSBCompletion fReadCompletionInfo; 215 IOUSBCompletion fWriteCompletionInfo; 216 IOUSBCompletion fRequestCompletionInfo; 217 218 thread_call_t fPowerThreadCall; 219 IOCommandGate *fGate; 220 bool fWaitForGatedCmd; 221 222 static void interruptReadComplete( void *obj, void *param, IOReturn ior, UInt32 remaining ); 223 static void dataReadComplete( void *obj, void *param, IOReturn ior, UInt32 remaining ); 224 static void dataWriteComplete( void *obj, void *param, IOReturn ior, UInt32 remaining ); 225 static void workAroundComplete( void *obj, void *param, IOReturn ior, UInt32 remaining ); 226 227 bool initForPM(IOService *provider); 228 static void handleSetPowerState(thread_call_param_t param0, thread_call_param_t param1 ); 229 static IOReturn setPowerStateGated(OSObject *owner, void *arg0, void *arg1, void *arg2, void *arg3); 230 IOReturn setPowerStateGatedPrivate(uintptr_t powerStateOrdinal); 231 232public: 233 234 IOUSBDevice *fpDevice; 235 IOUSBInterface *fpInterface; 236 IOUSBPipe *fpInPipe; 237 IOUSBPipe *fpOutPipe; 238 IOUSBPipe *fpInterruptPipe; 239 240 /* IOKit methods: */ 241 242 virtual bool init( OSDictionary *dict ); 243 virtual IOService* probe( IOService *provider, SInt32 *score ); 244 virtual bool start( IOService *provider ); 245 virtual void free( void ); 246 virtual void stop( IOService *provider ); 247 virtual IOReturn message( UInt32 type, IOService *provider, void *argument = 0 ); 248 249 /**** IOSerialDriverSync Abstract Method Implementation ****/ 250 251 virtual IOReturn acquirePort( bool sleep, void *refCon ); 252 virtual IOReturn releasePort( void *refCon ); 253 virtual IOReturn setState( UInt32 state, UInt32 mask, void *refCon ); 254 virtual UInt32 getState( void *refCon ); 255 virtual IOReturn watchState( UInt32 *state, UInt32 mask, void *refCon ); 256 virtual UInt32 nextEvent( void *refCon ); 257 virtual IOReturn executeEvent( UInt32 event, UInt32 data, void *refCon ); 258 virtual IOReturn requestEvent( UInt32 event, UInt32 *data, void *refCon ); 259 virtual IOReturn enqueueEvent( UInt32 event, UInt32 data, bool sleep, void *refCon ); 260 virtual IOReturn dequeueEvent( UInt32 *event, UInt32 *data, bool sleep, void *refCon ); 261 virtual IOReturn enqueueData( UInt8 *buffer, UInt32 size, UInt32 * count, bool sleep, void *refCon ); 262 virtual IOReturn dequeueData( UInt8 *buffer, UInt32 size, UInt32 *count, UInt32 min, void *refCon ); 263 264 // Power management routines 265 virtual unsigned long initialPowerStateForDomainState ( IOPMPowerFlags ); 266 virtual IOReturn setPowerState(unsigned long powerStateOrdinal, IOService * whatDevice); 267 268 /**** AppleUSBIrDA Methods ****/ 269 /**** IrDA Specific (Public) ****/ 270 271 void Add_RXBytes( UInt8 *Buffer, size_t Size ); 272 SInt16 SetBofCount( SInt16 bof_count ); 273 UInt16 SetSpeed( UInt32 brate ); 274 bool SetUpTransmit( void ); 275 IOReturn StartTransmit( UInt32 control_length, UInt8 *control_buffer, UInt32 data_length, UInt8 *data_buffer ); 276 277 IrDAComm* GetIrDAComm( void ); 278 void GetIrDAStatus( IrDAStatus *status ); 279 IOReturn SetIrDAUserClientState( bool IrDAOn ); 280 USBIrDAQoS* GetIrDAQoS( void ); 281 282private: 283 284 /**** Queue primatives ****/ 285 286 QueueStatus AddBytetoQueue( CirQueue *Queue, char Value ); 287 QueueStatus GetBytetoQueue( CirQueue *Queue, UInt8 *Value ); 288 QueueStatus InitQueue( CirQueue *Queue, UInt8 *Buffer, size_t Size ); 289 QueueStatus CloseQueue( CirQueue *Queue ); 290 size_t AddtoQueue( CirQueue *Queue, UInt8 *Buffer, size_t Size ); 291 size_t RemovefromQueue( CirQueue *Queue, UInt8 *Buffer, size_t MaxSize ); 292 size_t FreeSpaceinQueue( CirQueue *Queue ); 293 size_t UsedSpaceinQueue( CirQueue *Queue ); 294 size_t GetQueueSize( CirQueue *Queue ); 295 //QueueStatus GetQueueStatus( CirQueue *Queue ); 296 void CheckQueues( PortInfo_t *port ); 297 298 /**** State manipulations ****/ 299 300 IOReturn privateWatchState( PortInfo_t *port, UInt32 *state, UInt32 mask ); 301 UInt32 readPortState( PortInfo_t *port ); 302 void changeState( PortInfo_t *port, UInt32 state, UInt32 mask ); 303 IOReturn CheckIrDAState(); // combines fSessions, fStartStopUserClient, fStartStopUSB to new state 304 305 /**** USB Specific ****/ 306 307 bool configureDevice( UInt8 numConfigs ); 308 void Workaround(); // reset confused silicon 309 310 bool allocateResources( void ); // allocate pipes 311 void releaseResources( void ); // free pipes 312 bool startPipes(); // start the usb reads going 313 void stopPipes(); 314 bool createSerialStream(); // create bsd stream 315 void destroySerialStream(); // delete bsd stream 316 bool createSuffix( unsigned char *sufKey, int sufMaxLen ); 317 bool startIrDA(); // start irda up 318 void stopIrDA(); // shut down irda 319 bool createNub(); // create nub (and port) 320 void destroyNub(); 321 void SetStructureDefaults( PortInfo_t *port, bool Init ); 322 bool allocateRingBuffer( CirQueue *Queue, size_t BufferSize ); 323 void freeRingBuffer( CirQueue *Queue ); 324 325}; /* end class AppleUSBIrDADriver */ 326 327#endif 328