1/*
2 * Copyright (c) 1998-2001 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 _IOKIT_IOFIREWIREAVCUNIT_H
24#define _IOKIT_IOFIREWIREAVCUNIT_H
25
26#include <IOKit/IOService.h>
27#include <IOKit/firewire/IOFWRegs.h>
28#include <IOKit/firewire/IOFWAddressSpace.h>
29#include <IOKit/firewire/IOFWCommand.h>
30#include <IOKit/avc/IOFireWireAVCConsts.h>
31
32extern const OSSymbol *gIOAVCUnitType;
33
34class IOFireWireNub;
35class IOFireWireAVCCommand;
36class IOFireWirePCRSpace;
37class IOFireWireAVCUnit;
38class IOFireWireAVCSubUnit;
39class IOFireWireAVCAsynchronousCommand;
40class IOFireWireAVCNub;
41
42// The callback prototype for AVC Asynchronous Commands
43typedef void (*IOFireWireAVCAsynchronousCommandCallback)(void *pRefCon, IOFireWireAVCAsynchronousCommand *pCommandObject);
44
45const UInt16 kIOFWAVCAsyncCmdFreed = 0xdead;
46
47/*!
48@class IOFireWireAVCAsynchronousCommand
49*/
50class IOFireWireAVCAsynchronousCommand : public IOCommand
51{
52    OSDeclareDefaultStructors(IOFireWireAVCAsynchronousCommand)
53	void free(void);
54
55	friend class IOFireWireAVCUnit;
56
57protected:
58	/*! @struct ExpansionData
59    @discussion This structure will be used to expand the capablilties of the class in the future.
60    */
61    struct ExpansionData { };
62
63	/*! @var reserved
64		Reserved for future use.  (Internal use only)  */
65    ExpansionData *reserved;
66
67public:
68	IOReturn init(const UInt8 * command, UInt32 len, IOFireWireAVCAsynchronousCommandCallback completionCallback, void *pClientRefCon);
69	IOReturn submit(IOFireWireAVCNub *pAVCNub);
70	IOReturn cancel(void);
71	IOReturn reinit(const UInt8 * command, UInt32 cmdLen);
72
73	// This function returns true if this command is currently waiting for a response
74	bool isPending(void);
75
76	IOFWAVCAsyncCommandState cmdState;
77	void	*pRefCon;
78	UInt8	*pCommandBuf;
79	UInt32	cmdLen;
80	UInt8	*pInterimResponseBuf;
81	UInt32	interimResponseLen;
82	UInt8	*pFinalResponseBuf;
83	UInt32	finalResponseLen;
84
85protected:
86	IOFireWireAVCAsynchronousCommandCallback fCallback;
87	IOFireWireAVCUnit *fAVCUnit;
88	IOMemoryDescriptor *fMem;
89	IOFWCommand *fWriteCmd;
90	IOFWDelayCommand *fDelayCmd;
91    UInt16 fWriteNodeID;
92	UInt32 fWriteGen;
93
94private:
95	OSMetaClassDeclareReservedUnused(IOFireWireAVCAsynchronousCommand, 0);
96    OSMetaClassDeclareReservedUnused(IOFireWireAVCAsynchronousCommand, 1);
97    OSMetaClassDeclareReservedUnused(IOFireWireAVCAsynchronousCommand, 2);
98    OSMetaClassDeclareReservedUnused(IOFireWireAVCAsynchronousCommand, 3);
99};
100
101/*!
102    @class IOFireWireAVCNub
103    @abstract nub for AVC devices
104*/
105class IOFireWireAVCNub : public IOService
106{
107    OSDeclareDefaultStructors(IOFireWireAVCNub)
108
109protected:
110    IOFireWireNub * fDevice;
111
112public:
113    // execute AVC command
114/*!
115    @function AVCCommand
116    @abstract Sends an AVC command to the device and stores the response.
117    @param command Pointer to command to send.
118    @param cmdLen Length of the command.
119    @param response Pointer to place to store the response.
120    @param responseLen Pointer to response length - initialize to the size of the buffer pointed to by response,
121    updated to the number of bytes returned by the device.
122*/
123    virtual IOReturn AVCCommand(const UInt8 * command, UInt32 cmdLen, UInt8 * response, UInt32 *responseLen) = 0;
124
125/*!
126    @function AVCCommandInGeneration
127    @abstract Sends an AVC command to the device and stores the response. The command must complete in the specified
128    FireWire bus generation otherwise kIOFireWireBusReset is returned.
129    @param generation The bus generation that the command must execute in.
130    @param command Pointer to command to send.
131    @param cmdLen Length of the command.
132    @param response Pointer to place to store the response.
133    @param responseLen Pointer to response length - initialize to the size of the buffer pointed to by response,
134    updated to the number of bytes returned by the device.
135*/
136    virtual IOReturn AVCCommandInGeneration(UInt32 generation,
137                const UInt8 * command, UInt32 cmdLen, UInt8 * response, UInt32 *responseLen) = 0;
138
139/*!
140    @function getDevice
141    @abstract Returns the FireWire device nub that is this object's provider .
142*/
143    IOFireWireNub* getDevice() const
144        {return fDevice;};
145
146/*!
147    @function updateAVCCommandTimeout
148    @abstract By default, AVCCommands timeout 10 seconds after receiving an Interim response.
149    This function resets the timeout of the current command to 10 seconds from the current time.
150    Call this repeatedly for AVC commands that take a very long time to execute to prevent premature
151    timeout.
152*/
153    virtual IOReturn updateAVCCommandTimeout() = 0;
154
155private:
156    OSMetaClassDeclareReservedUsed(IOFireWireAVCNub, 0);
157    OSMetaClassDeclareReservedUnused(IOFireWireAVCNub, 1);
158    OSMetaClassDeclareReservedUnused(IOFireWireAVCNub, 2);
159    OSMetaClassDeclareReservedUnused(IOFireWireAVCNub, 3);
160};
161
162/*!
163    @class IOFireWireAVCUnit
164    @abstract nub for AVC devices
165*/
166class IOFireWireAVCUnit : public IOFireWireAVCNub
167{
168    OSDeclareDefaultStructors(IOFireWireAVCUnit)
169
170	friend class IOFireWireAVCAsynchronousCommand;
171
172protected:
173    IOFWPseudoAddressSpace *fFCPResponseSpace;
174    IOLock *avcLock;
175    IOFireWireAVCCommand *fCommand;
176
177    UInt8 fSubUnitCount[kAVCNumSubUnitTypes];
178
179	bool fStarted;
180    IOLock *cmdLock;
181
182/*! @struct ExpansionData
183    @discussion This structure is used to expand the capablilties of the class in a binary compatible way
184    */
185    struct ExpansionData
186	{
187		OSArray * fAVCAsyncCommands;
188		IOFireWireController *fControl;
189		bool enableRobustAVCCommandResponseMatching;
190	};
191
192/*! @var fIOFireWireAVCUnitExpansion
193      */
194    ExpansionData *fIOFireWireAVCUnitExpansion;
195
196    static UInt32 AVCResponse(void *refcon, UInt16 nodeID, IOFWSpeed &speed,
197                    FWAddress addr, UInt32 len, const void *buf, IOFWRequestRefCon requestRefcon);
198
199    static void rescanSubUnits(void *arg);
200
201    virtual void free(void);
202
203    virtual void updateSubUnits(bool firstTime);
204
205	static void AVCAsynchRequestWriteDone(void *refcon, IOReturn status, IOFireWireNub *device, IOFWCommand *fwCmd);
206	static void AVCAsynchDelayDone(void *refcon, IOReturn status, IOFireWireBus *bus, IOFWBusCommand *fwCmd);
207
208public:
209    // IOService overrides
210    virtual bool start(IOService *provider);
211    virtual IOReturn message(UInt32 type, IOService *provider, void *argument);
212	virtual IOReturn setProperties (OSObject * properties );
213
214/*! @function handleOpen
215    @abstract Overrideable method to control the open / close behaviour of an IOService.
216    @discussion See IOService for discussion.
217    @param forClient Designates the client of the provider requesting the open.
218    @param options Options for the open, may be interpreted by the implementor of handleOpen.
219    @result Return true if the open was successful, false otherwise.
220*/
221
222    virtual bool handleOpen(  IOService *	  forClient,
223                              IOOptionBits	  options,
224                              void *		  arg );
225/*!
226    @function handleClose
227    @abstract Overrideable method to control the open / close behaviour of an IOService.
228    @discussion See IOService for discussion.
229    @param forClient Designates the client of the provider requesting the close.
230    @param options Options for the close, may be interpreted by the implementor of handleOpen.
231*/
232
233    virtual void handleClose(   IOService *		forClient,
234                                IOOptionBits	options );
235
236
237/*!
238    @function matchPropertyTable
239    @abstract Matching language support
240	Match on the following properties of the unit:
241	Vendor_ID
242	GUID
243	Unit_Type
244	and available sub-units, match if the device has at least the requested number of a sub-unit type:
245	AVCSubUnit_0 -> AVCSubUnit_1f
246*/
247    virtual bool matchPropertyTable(OSDictionary * table);
248
249    // execute AVC command
250/*!
251    @function AVCCommand
252    @abstract Sends an AVC command to the device and stores the response.
253    @param command Pointer to command to send.
254    @param cmdLen Length of the command.
255    @param response Pointer to place to store the response.
256    @param responseLen Pointer to response length - initialize to the size of the buffer pointed to by response,
257    updated to the number of bytes returned by the device.
258*/
259    virtual IOReturn AVCCommand(const UInt8 * command, UInt32 cmdLen, UInt8 * response, UInt32 *responseLen);
260
261/*!
262    @function AVCCommandInGeneration
263    @abstract Sends an AVC command to the device and stores the response. The command must complete in the specified
264    FireWire bus generation otherwise kIOFireWireBusReset is returned.
265    @param generation The bus generation that the command must execute in.
266    @param command Pointer to command to send.
267    @param cmdLen Length of the command.
268    @param response Pointer to place to store the response.
269    @param responseLen Pointer to response length - initialize to the size of the buffer pointed to by response,
270    updated to the number of bytes returned by the device.
271*/
272    virtual IOReturn AVCCommandInGeneration(UInt32 generation,
273                const UInt8 * command, UInt32 cmdLen, UInt8 * response, UInt32 *responseLen);
274
275/*!
276    @function updateAVCCommandTimeout
277    @abstract By default, AVCCommands timeout 10 seconds after receiving an Interim response.
278    This function resets the timeout of the current command to 10 seconds from the current time.
279    Call this repeatedly for AVC commands that take a very long time to execute to prevent premature
280    timeout.
281*/
282    virtual IOReturn updateAVCCommandTimeout();
283
284protected:
285	UInt32 indexOfAVCAsynchronousCommandObject(IOFireWireAVCAsynchronousCommand *pCommandObject);
286	void removeAVCAsynchronousCommandObjectAtIndex(UInt32 index);
287
288	void lockAVCAsynchronousCommandLock();
289
290	void unlockAVCAsynchronousCommandLock();
291
292	bool available();
293
294private:
295
296    OSMetaClassDeclareReservedUnused(IOFireWireAVCUnit, 0);
297    OSMetaClassDeclareReservedUnused(IOFireWireAVCUnit, 1);
298    OSMetaClassDeclareReservedUnused(IOFireWireAVCUnit, 2);
299    OSMetaClassDeclareReservedUnused(IOFireWireAVCUnit, 3);
300
301};
302
303/*!
304    @class IOFireWireAVCSubUnit
305    @abstract nub for sub unit of AVC devices. Just for matching, calls the AVC unit for all functions.
306*/
307class IOFireWireAVCSubUnit : public IOFireWireAVCNub
308{
309    OSDeclareDefaultStructors(IOFireWireAVCSubUnit)
310
311	friend class IOFireWireAVCAsynchronousCommand;
312
313protected:
314    IOFireWireAVCUnit *fAVCUnit;
315
316/*! @struct ExpansionData
317    @discussion This structure will be used to expand the capablilties of the class in the future.
318    */
319    struct ExpansionData { };
320
321/*! @var reserved
322    Reserved for future use.  (Internal use only)  */
323    ExpansionData *reserved;
324
325public:
326    virtual bool init(OSDictionary *propTable, IOFireWireAVCUnit *provider);
327
328    // IOService overrides
329    virtual IOReturn message(UInt32 type, IOService *provider, void *argument);
330
331/*! @function handleOpen
332    @abstract Overrideable method to control the open / close behaviour of an IOService.
333    @discussion See IOService for discussion.
334    @param forClient Designates the client of the provider requesting the open.
335    @param options Options for the open, may be interpreted by the implementor of handleOpen.
336    @result Return true if the open was successful, false otherwise.
337*/
338
339    virtual bool handleOpen(  IOService *	  forClient,
340                              IOOptionBits	  options,
341                              void *		  arg );
342/*!
343    @function handleClose
344    @abstract Overrideable method to control the open / close behaviour of an IOService.
345    @discussion See IOService for discussion.
346    @param forClient Designates the client of the provider requesting the close.
347    @param options Options for the close, may be interpreted by the implementor of handleOpen.
348*/
349
350    virtual void handleClose(   IOService *		forClient,
351                                IOOptionBits	options );
352
353
354/*!
355    @function matchPropertyTable
356    @abstract Matching language support
357	Match on the following properties of the sub unit:
358	Vendor_ID
359	GUID
360	SubUnit_Type
361*/
362    virtual bool matchPropertyTable(OSDictionary * table);
363
364    // execute AVC command
365/*!
366    @function AVCCommand
367    @abstract Sends an AVC command to the device and stores the response.
368    @param command Pointer to command to send.
369    @param cmdLen Length of the command.
370    @param response Pointer to place to store the response.
371    @param responseLen Pointer to response length - initialize to the size of the buffer pointed to by response,
372    updated to the number of bytes returned by the device.
373*/
374    virtual IOReturn AVCCommand(const UInt8 * command, UInt32 cmdLen, UInt8 * response, UInt32 *responseLen);
375
376/*!
377    @function AVCCommandInGeneration
378    @abstract Sends an AVC command to the device and stores the response. The command must complete in the specified
379    FireWire bus generation otherwise kIOFireWireBusReset is returned.
380    @param generation The bus generation that the command must execute in.
381    @param command Pointer to command to send.
382    @param cmdLen Length of the command.
383    @param response Pointer to place to store the response.
384    @param responseLen Pointer to response length - initialize to the size of the buffer pointed to by response,
385    updated to the number of bytes returned by the device.
386*/
387    virtual IOReturn AVCCommandInGeneration(UInt32 generation,
388                const UInt8 * command, UInt32 cmdLen, UInt8 * response, UInt32 *responseLen);
389
390/*!
391    @function updateAVCCommandTimeout
392    @abstract By default, AVCCommands timeout 10 seconds after receiving an Interim response.
393    This function resets the timeout of the current command to 10 seconds from the current time.
394    Call this repeatedly for AVC commands that take a very long time to execute to prevent premature
395    timeout.
396*/
397    virtual IOReturn updateAVCCommandTimeout();
398
399private:
400    OSMetaClassDeclareReservedUnused(IOFireWireAVCSubUnit, 0);
401    OSMetaClassDeclareReservedUnused(IOFireWireAVCSubUnit, 1);
402    OSMetaClassDeclareReservedUnused(IOFireWireAVCSubUnit, 2);
403    OSMetaClassDeclareReservedUnused(IOFireWireAVCSubUnit, 3);
404
405};
406
407#endif // _IOKIT_IOFIREWIREAVCUNIT_H
408
409