1/*
2 * Copyright (c) 1998-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/*!
24  @header IOFireWireSBP2Login
25  Contains the class definition for IOFireWireSBP2Login.
26*/
27
28#ifndef _IOKIT_IOFIREWIRESBP2LOGIN_H
29#define _IOKIT_IOFIREWIRESBP2LOGIN_H
30
31#include <IOKit/IOCommandGate.h>
32
33#include <IOKit/firewire/IOFireWireUnit.h>
34
35#include <IOKit/sbp2/IOFireWireSBP2ORB.h>
36#include <IOKit/sbp2/IOFireWireSBP2Target.h>
37
38// login option flags
39enum
40{
41	kFWSBP2DontSynchronizeMgmtAgent = (1 << 0),
42    kFWSBP2ExclusiveLogin 			= (1 << 5)
43};
44
45// notification events
46enum
47{
48    kFWSBP2NormalCommandStatus	= 6,
49    kFWSBP2NormalCommandTimeout	= 7,
50    kFWSBP2UnsolicitedStatus	= 8,
51    kFWSBP2NormalCommandReset	= 9
52};
53
54#define kIOMessageFWSBP2ReconnectComplete	iokit_fw_err(0x3E8)
55#define kIOMessageFWSBP2ReconnectFailed		iokit_fw_err(0x3E9)
56
57/*!
58    @typedef FWSBP2LoginResponse
59    @param length Length of login response.
60    @param loginID Unique id representing this login.
61    @param commandBlockAgentAddressHi High 32 bits of command block agent address.
62    @param commandBlockAgentAddressLo Low 32 bits of command block agent address.
63    @param reserved Reserved.
64    @param reconnectHold Reconnect timeout encoded as 2^reconnectHold seconds.
65*/
66
67typedef struct
68{
69    UInt16		length;
70    UInt16		loginID;
71    UInt32		commandBlockAgentAddressHi;
72    UInt32		commandBlockAgentAddressLo;
73    UInt16		reserved;
74    UInt16		reconnectHold;
75} FWSBP2LoginResponse, *FWSBP2LoginResponsePtr;
76
77/*!
78    @typedef FWSBP2StatusBlock
79    @param details Src, Resp, D, Len fields of status block format
80    @param sbpStatus SBP2 specific status
81    @param orbOffsetHi High 32 bits of address of orb status is for.
82    @param orbOffsetLo Low 32 bits of address of orb status is for.
83    @param status[6] Up to 48 bytes of additional data. Length is determined by len field.
84*/
85
86typedef struct
87{
88    UInt8		details;
89    UInt8		sbpStatus;
90    UInt16		orbOffsetHi;
91    UInt32		orbOffsetLo;
92    UInt32		status[6];
93} FWSBP2StatusBlock;
94
95class IOFireWireSBP2LUN;
96class IOFireWireSBP2Login;
97
98// struct sent to login complete handler
99
100/*!
101    @typedef FWSBP2LoginCompleteParams
102    @param login Pointer to IOFireWireSBP2Login object.
103    @param generation FireWire generation value.
104    @param status Status of login attempt.
105    @param loginResponse Pointer to login response struct.
106    @param statusBlock Pointer to status block buffer.
107    @param statusBlockLength Length of entire status block.
108*/
109
110typedef struct
111{
112    IOFireWireSBP2Login * 	login;			// login object this param is sent from
113    UInt32					generation;		// generation this login was attempted in
114
115    IOReturn				status;			// status of login attempt
116
117    FWSBP2LoginResponsePtr	loginResponse;		// pointer to loginResponse buffer
118    FWSBP2StatusBlock *		statusBlock;		// pointer to statusBlock buffer
119    UInt32					statusBlockLength;	// size of statusBlock buffer
120
121} FWSBP2LoginCompleteParams, *FWSBP2LoginCompleteParamsPtr;
122
123// struct sent to logout complete handler
124
125/*!
126    @typedef FWSBP2LogoutCompleteParams
127    @param login Pointer to IOFireWireSBP2Login object.
128    @param generation FireWire generation value.
129    @param status Status of login attempt.
130    @param statusBlock Pointer to status block buffer.
131    @param statusBlockLength Length of entire status block.
132*/
133
134typedef struct
135{
136    IOFireWireSBP2Login * 	login;			// login object this param is sent from
137    UInt32					generation;		// generation this login was attempted in
138
139    IOReturn				status;			// status of login attempt
140
141    FWSBP2StatusBlock *		statusBlock;		// pointer to statusBlock buffer
142    UInt32					statusBlockLength;	// size of statusBlock buffer
143
144} FWSBP2LogoutCompleteParams, *FWSBP2LogoutCompleteParamsPtr;
145
146// struct sent with reconnect notification
147
148/*!
149    @typedef FWSBP2LogoutCompleteParams
150    @param login Pointer to IOFireWireSBP2Login object.
151    @param generation FireWire generation value.
152    @param status Status of login attempt.
153    @param reconnectStatusBlock Pointer to status block buffer.
154    @param reconnectStatusBlockLength Length of entire status block.
155*/
156
157typedef struct
158{
159    IOFireWireSBP2Login * 	login;			// login object this param is sent from
160    UInt32					generation;		// generation this login was attempted in
161
162    IOReturn			status;			// status of reconnect attempt
163
164    void *			reconnectStatusBlock;		// pointer to statusBlock buffer
165    UInt32			reconnectStatusBlockLength;	// size of statusBlock buffer
166} FWSBP2ReconnectParams, *FWSBP2ReconnectParamsPtr;
167
168// Callback when login and logout commands complete asynchronously
169
170/*!
171    @typedef FWSBP2LoginCallback
172    @param refCon Reference constant supplied when the notification was registered.
173    @param params Structure containing additional information about the status of the login.
174*/
175
176typedef void (*FWSBP2LoginCallback)(void * refCon, FWSBP2LoginCompleteParamsPtr params);
177
178/*!
179    @typedef FWSBP2LogoutCallback
180    @param refCon Reference constant supplied when the notification was registered.
181    @param params Structure containing additional information about the status of the logout.
182*/
183
184typedef void (*FWSBP2LogoutCallback)(void * refCon, FWSBP2LogoutCompleteParamsPtr params);
185
186/*!
187    @typedef FWSBP2StatusCallback
188    @param refCon Reference constant supplied when the notification was registered.
189    @param status Indicates success or failure of operation.
190*/
191
192typedef void (*FWSBP2StatusCallback)(void * refCon, IOReturn status);
193
194/*!
195    @typedef FWSBP2FetchAgentWriteCallback
196    @param refCon Reference constant supplied when the notification was registered.
197    @param status Indicates success or failure of operation.
198    @param orb Indicates current last orb in chain.
199*/
200
201typedef void (*FWSBP2FetchAgentWriteCallback)(void * refCon, IOReturn status, IOFireWireSBP2ORB * orb);
202
203/*!
204    @typedef FWSBP2NotifyParams
205    @param notificationEvent Type of event we are being notified of.
206    @param message buffer containing message.
207    @param length length of message field.
208    @param generation FireWire generation value.
209*/
210
211typedef struct
212{
213    void *				commandObject;
214    UInt32 				notificationEvent;
215    const void * 		message;
216    UInt32				length;
217    UInt32				generation;
218} FWSBP2NotifyParams, *FWSBP2NotifyParamsPtr;
219
220
221/*!
222    @typedef FWSBP2NotifyCallback
223    @param refCon Reference constant supplied when the notification was registered.
224    @param params FWSBP2NotifyParams containing notification information.
225*/
226
227typedef void (*FWSBP2NotifyCallback)(void * refCon, FWSBP2NotifyParamsPtr params);
228
229/*!
230    @class IOFireWireSBP2Login
231    @abstract Supplies the login maintenance and Normal Command ORB execution portions of the API.
232    @discussion Supplies APIs for login maintenance and command execution.  Drivers can use this
233    object to create IOFireWireSBP2ORB objects and execute them.  Solicited and unsolicited status
234    callback routines can be registered and the SBP2 services will notify the driver when the
235    appropriate status arrives.
236    This class also handles login maintenance.  Supplies APIs for logging in and logging out and
237    attempts to reconnect to the LUN after bus resets.  The base FireWire services deliver bus
238    reset notification via the IOKit message routine.  The SBP2 services build on this behavior
239    and deliver reconnectFailed and reconnectComplete through the message routine as well.
240*/
241
242class IOFireWireSBP2Login : public OSObject
243{
244    OSDeclareDefaultStructors( IOFireWireSBP2Login )
245
246	friend class IOFireWireSBP2ORB;
247	friend class IOFireWireSBP2LUN;
248	friend class IOFireWireSBP2UserClient;
249
250protected:
251
252    // command selectors
253    enum
254    {
255        kLoginCommandIdle		= 0,
256        kLoginCommandDoLogin 	= 1,
257        kLoginCommandDoLogout	= 2,
258        kLoginAddORB			= 3,
259        kLoginRemoveORB			= 4,
260		kLoginFetchAgentReset	= 5
261     };
262
263    // internal login states
264    enum
265    {
266        kLoginStateIdle			= 0,
267        kLoginStateLoggingIn	= 1,
268        kLoginStateConnected	= 2,
269        kLoginStateReconnect	= 3,
270        kLoginStateLoggingOut	= 4,
271		kLoginStateTerminated	= 5
272    };
273
274    // rom keys
275    enum
276    {
277        kUnitCharacteristicsKey 	= 0x3A,
278        kManagementAgentOffsetKey	= 0x54
279    };
280
281    // sbp2 defs
282    enum
283    {
284        kFWSBP2RequestComplete 	= 0,
285        kFWSBP2TransportFailure	= 1,
286        kFWSBP2IllegalRequest	= 2,
287        kFWSBP2VendorDependent	= 3
288    };
289
290    enum
291    {
292        kFWSBP2NoSense					= 0,
293        kFWSBP2RequestTypeNotSupported	= 1,
294        kFWSBP2SpeedNotSupported		= 2,
295        kFWSBP2PageSizeNotSupported		= 3,
296        kFWSBP2AccessDenied				= 4,
297        kFWSBP2LogicalUnitNotSupported	= 5,
298        kFWSBP2MaxPayloadTooSmall		= 6,
299        kFWSBP2FunctionRejected			= 9,
300        kFWSBP2LoginIDNotRecognized		= 10,
301        kFWSBP2DummyORBCompleted		= 11,
302        kFWSBP2RequestAborted			= 12,
303        kFWSBP2UnspecifiedError			= 0xFF
304    };
305
306    typedef struct
307    {
308        UInt32		password[2];
309        UInt32		loginResponseAddressHi;
310        UInt32		loginResponseAddressLo;
311        UInt16		options;
312        UInt16		lun;
313        UInt16		passwordLength;
314        UInt16		loginResponseLength;
315        UInt32		statusFIFOAddressHi;
316        UInt32		statusFIFOAddressLo;
317    } FWSBP2LoginORB;
318
319    typedef struct
320    {
321        UInt32		reserved1[4];
322        UInt16		options;
323        UInt16		loginID;
324        UInt32		reserved2;
325        UInt32		statusFIFOAddressHi;
326        UInt32		statusFIFOAddressLo;
327    } FWSBP2ReconnectORB;
328
329    typedef struct
330    {
331        UInt32		reserved1[4];
332        UInt16		options;
333        UInt16		loginID;
334        UInt32		reserved2;
335        UInt32		statusFIFOAddressHi;
336        UInt32		statusFIFOAddressLo;
337    } FWSBP2LogoutORB;
338
339protected:
340
341    ///////////////////////////////////////////////////////////////////
342    // private interface methods
343
344	// IOFireWireSBP2LUN methods
345	virtual void clearAllTasksInSet( void );
346    virtual bool initWithLUN( IOFireWireSBP2LUN * lun );
347    virtual void suspendedNotify( void );
348    virtual void resumeNotify( void );
349
350	// IOFireWireSBP2ORB methods
351	virtual IOFireWireUnit * getFireWireUnit( void );
352    virtual IOFireWireSBP2LUN * getFireWireLUN( void );
353    virtual bool isFetchAgentWriteInProgress( void );
354    virtual bool isConnected( void );
355    virtual IOReturn removeORB( IOFireWireSBP2ORB * orb );
356    virtual IOReturn appendORBImmediate( IOFireWireSBP2ORB * orb );
357    virtual IOReturn appendORB( IOFireWireSBP2ORB * orb );
358    virtual void sendTimeoutNotification( IOFireWireSBP2ORB * orb );
359
360protected:
361
362    // reserved for future use
363    struct ExpansionData { };
364    ExpansionData *reserved;
365
366    IOFireWireSBP2LUN * 	fLUN;
367    IOFireWireUnit *		fUnit;
368	IOFireWireController *	fControl;
369	IOCommandGate * 		fGate;
370
371    FWSBP2LoginCallback		fLoginCompletionCallback;
372    void *	  				fLoginCompletionRefCon;
373
374    FWSBP2LogoutCallback	fLogoutCompletionCallback;
375    void *					fLogoutCompletionRefCon;
376
377    FWSBP2NotifyCallback	fStatusNotifyCallback;
378    void *					fStatusNotifyRefCon;
379
380    FWSBP2NotifyCallback	fUnsolicitedStatusNotifyCallback;
381    void *					fUnsolicitedStatusNotifyRefCon;
382
383    UInt32					fLoginFlags;
384    UInt32					fReconnectTime;
385
386    UInt32					fLoginState;
387    UInt32					fManagementOffset;
388    UInt32					fManagementTimeout;
389    UInt32					fMaxORBSize;
390    UInt32					fMaxCommandBlockSize;
391    UInt16					fLoginNodeID;
392    UInt32					fLoginGeneration;
393    UInt32					fLoginID;
394    UInt32					fReconnectHold;
395    UInt32					fMaxPayloadSize;
396    void *					fRefCon;
397
398    // resources
399
400    FWSBP2LoginORB			fLoginORB;
401    IOFWAddressSpace *		fLoginORBAddressSpace;
402    FWAddress				fLoginORBAddress;
403
404    FWSBP2LoginResponse		fLoginResponse;
405    IOFWAddressSpace *		fLoginResponseAddressSpace;
406    FWAddress				fLoginResponseAddress;
407
408    FWSBP2ReconnectORB		fReconnectORB;
409    IOFWAddressSpace *		fReconnectORBAddressSpace;
410    FWAddress				fReconnectORBAddress;
411
412    FWSBP2StatusBlock		fStatusBlock;
413    IOFWAddressSpace *		fStatusBlockAddressSpace;
414    FWAddress				fStatusBlockAddress;
415
416    FWSBP2StatusBlock		fReconnectStatusBlock;
417    IOFWAddressSpace *		fReconnectStatusBlockAddressSpace;
418    FWAddress				fReconnectStatusBlockAddress;
419
420    FWSBP2LogoutORB			fLogoutORB;
421    IOFWAddressSpace *		fLogoutORBAddressSpace;
422    FWAddress				fLogoutORBAddress;
423    bool					fLogoutPending;
424
425    IOFWWriteCommand *		fLoginWriteCommand;
426    IOMemoryDescriptor *	fLoginWriteCommandMemory;
427    bool					fLoginWriteInProgress;
428
429    IOFWWriteCommand *		fReconnectWriteCommand;
430    IOMemoryDescriptor *	fReconnectWriteCommandMemory;
431    bool					fReconnectWriteInProgress;
432    bool					fReconnectWriteInterrupted;
433
434    IOFWWriteCommand *		fLogoutWriteCommand;
435    IOMemoryDescriptor *	fLogoutWriteCommandMemory;
436    bool					fLogoutWriteInProgress;
437
438    IOFWCommand *			fLoginTimeoutCommand;
439    bool					fLoginTimeoutTimerSet;
440
441    IOFWDelayCommand *		fReconnectTimeoutCommand;
442    bool					fReconnectTimeoutTimerSet;
443
444    IOFWCommand *			fLogoutTimeoutCommand;
445    bool					fLogoutTimeoutTimerSet;
446
447    FWAddress 				fFetchAgentAddress;
448    IOMemoryDescriptor *	fFetchAgentWriteCommandMemory;
449    FWAddress 				fLastORBAddress;
450    IOFireWireSBP2ORB *		fLastORB;
451    IOFWWriteCommand *		fFetchAgentWriteCommand;
452    bool					fFetchAgentWriteCommandInUse;
453	FWSBP2FetchAgentWriteCallback 	fFetchAgentWriteCompletion;
454	void * 							fFetchAgentWriteRefCon;
455	IOFireWireSBP2ORB *		fORBToWrite;
456
457    OSSet *					fORBSet;
458    OSIterator *			fORBSetIterator;
459
460    void *					fPasswordBuf;
461    UInt32					fPasswordLen;
462    IOFWAddressSpace *		fPasswordAddressSpace;
463    FWAddress				fPasswordAddress;
464	IOMemoryDescriptor *	fPasswordDescriptor;
465
466	bool fSuspended;
467
468	UInt32					fLoginRetryDelay;
469	UInt32					fLoginRetryCount;
470	UInt32					fLoginRetryMax;
471	IOFWDelayCommand *		fLoginRetryTimeoutCommand;
472    bool					fLoginRetryTimeoutTimerSet;
473	IOFireWireSBP2Target * 	fTarget;
474
475	bool					fUnsolicitedStatusEnableRequested;
476
477	IOFWDelayCommand *		fReconnectRetryTimeoutCommand;
478    bool					fReconnectRetryTimeoutTimerSet;
479
480	int						fCriticalSectionCount;
481
482	// init / destroy
483    virtual IOReturn getUnitInformation( void );
484    virtual IOReturn allocateResources( void );
485    virtual void free( void );
486
487	// orb add / remove
488	virtual IOReturn addORB( IOFireWireSBP2ORB * orb );
489	static IOReturn staticExecuteAddORB( OSObject *self, void * orb, void *, void *, void * );
490	virtual IOReturn executeAddORB( IOFireWireSBP2ORB * orb );
491
492	static IOReturn staticExecuteRemoveORB( OSObject *self, void * orb, void *, void *, void * );
493	virtual IOReturn executeRemoveORB( IOFireWireSBP2ORB * orb );
494
495    //
496    // login
497    //
498
499    static IOReturn staticExecuteLogin( OSObject *self, void *, void *, void *, void * );
500    virtual IOReturn executeLogin( void );
501    virtual void abortLogin( void );
502
503    // login write complete handler
504    static void loginWriteCompleteStatic( void *refcon, IOReturn status, IOFireWireNub *device, IOFWCommand *fwCmd );
505    virtual void loginWriteComplete( IOReturn status, IOFireWireNub *device, IOFWCommand *fwCmd );
506
507    // login timeout handler
508    static void loginTimeoutStatic( void *refcon, IOReturn status, IOFireWireBus *bus, IOFWBusCommand *fwCmd );
509    virtual void loginTimeout( IOReturn status, IOFireWireBus *bus, IOFWBusCommand *fwCmd );
510
511    // status block write handler
512    static UInt32 statusBlockWriteStatic(void *refcon, UInt16 nodeID, IOFWSpeed &speed, FWAddress addr, UInt32 len,
513                                         const void *buf, IOFWRequestRefCon lockRead);
514   	virtual UInt32 statusBlockWrite( UInt16 nodeID, IOFWSpeed &speed, FWAddress addr, UInt32 len, const void *buf, IOFWRequestRefCon lockRead);
515	virtual void completeLogin( IOReturn state, const void *buf = NULL, UInt32 len = 0, void * buf2 = NULL );
516
517    //
518    // reconnect
519    //
520
521    virtual void doReconnect( void );
522    virtual void restartReconnect( void );
523    virtual void startReconnectTimer( void );
524
525    // reconnect write complete handler
526    static void reconnectWriteCompleteStatic( void *refcon, IOReturn status, IOFireWireNub *device, IOFWCommand *fwCmd );
527    virtual void reconnectWriteComplete( IOReturn status, IOFireWireNub *device, IOFWCommand *fwCmd );
528
529    // reconnect timeout handler
530    static void reconnectTimeoutStatic( void *refcon, IOReturn status, IOFireWireBus *bus, IOFWBusCommand *fwCmd );
531    virtual void reconnectTimeout( IOReturn status, IOFireWireBus *bus, IOFWBusCommand *fwCmd );
532
533    // reconnect status block
534    static UInt32 reconnectStatusBlockWriteStatic(void *refcon, UInt16 nodeID, IOFWSpeed &speed, FWAddress addr,
535                                                  UInt32 len, const void *buf, IOFWRequestRefCon lockRead);
536   	virtual UInt32 reconnectStatusBlockWrite( UInt16 nodeID, IOFWSpeed &speed, FWAddress addr, UInt32 len,
537                                              const void *buf, IOFWRequestRefCon lockRead);
538
539    virtual void sendReconnectNotification( UInt32 event );
540    virtual void sendReconnectNotificationWithStatusBlock( UInt32 event );
541
542    //
543    // logout
544    //
545
546	static IOReturn staticExecuteLogout( OSObject *self, void *, void *, void *, void * );
547    virtual IOReturn executeLogout( void );
548
549    // logout write complete handler
550    static void logoutWriteCompleteStatic( void *refcon, IOReturn status, IOFireWireNub *device, IOFWCommand *fwCmd );
551    virtual void logoutWriteComplete( IOReturn status, IOFireWireNub *device, IOFWCommand *fwCmd );
552
553    // logout timeout handler
554    static void logoutTimeoutStatic( void *refcon, IOReturn status, IOFireWireBus *bus, IOFWBusCommand *fwCmd );
555    virtual void logoutTimeout( IOReturn status, IOFireWireBus *bus, IOFWBusCommand *fwCmd );
556
557	virtual void completeLogout( IOReturn state, const void *buf = NULL, UInt32 len = 0);
558
559	// fetch agent write complete handler
560    static void fetchAgentWriteCompleteStatic( void *refcon, IOReturn status, IOFireWireNub *device, IOFWCommand *fwCmd );
561    virtual void fetchAgentWriteComplete( IOReturn status, IOFireWireNub *device, IOFWCommand *fwCmd );
562
563    //
564    // fetch agent
565    //
566
567	bool 							fFetchAgentResetInProgress;
568	UInt32 							fFetchAgentResetBuffer;
569	FWAddress 						fFetchAgentResetAddress;
570	IOFWWriteQuadCommand *			fFetchAgentResetCommand;
571	void * 							fFetchAgentResetRefCon;
572	FWSBP2StatusCallback 			fFetchAgentResetCompletion;
573
574	static IOReturn staticExecuteFetchAgentReset( OSObject *self, void *, void *, void *, void * );
575	virtual IOReturn executeFetchAgentReset( void );
576	static void fetchAgentResetCompleteStatic( void *refcon, IOReturn status, IOFireWireNub *device, IOFWCommand *fwCmd );
577	virtual void fetchAgentResetComplete( IOReturn status, IOFireWireNub *device, IOFWCommand *fwCmd );
578
579	//
580	// doorbell
581	//
582
583	bool 							fDoorbellInProgress;
584	bool							fDoorbellRingAgain;
585	UInt32 							fDoorbellBuffer;
586	FWAddress 						fDoorbellAddress;
587	IOFWWriteQuadCommand *			fDoorbellCommand;
588
589	static IOReturn staticExecuteDoorbell( OSObject *self, void *, void *, void *, void * );
590	virtual IOReturn executeDoorbell( void );
591	static void doorbellCompleteStatic( void *refcon, IOReturn status, IOFireWireNub *device, IOFWCommand *fwCmd );
592	virtual void doorbellComplete( IOReturn status, IOFireWireNub *device, IOFWCommand *fwCmd );
593
594	//
595	// enable unsolicited satus
596	//
597
598	bool 							fUnsolicitedStatusEnableInProgress;
599	UInt32 							fUnsolicitedStatusEnableBuffer;
600	FWAddress 						fUnsolicitedStatusEnableAddress;
601	IOFWWriteQuadCommand *			fUnsolicitedStatusEnableCommand;
602
603	static IOReturn staticExecuteUnsolicitedStatusEnable( OSObject *self, void *, void *, void *, void * );
604	virtual IOReturn executeUnsolicitedStatusEnable( void );
605	static void unsolicitedStatusEnableCompleteStatic( void *refcon, IOReturn status, IOFireWireNub *device, IOFWCommand *fwCmd );
606	virtual void unsolicitedStatusEnableComplete( IOReturn status, IOFireWireNub *device, IOFWCommand *fwCmd );
607
608	//
609	// busy timeout stuff
610	//
611
612	bool 							fSetBusyTimeoutInProgress;
613	UInt32 							fSetBusyTimeoutBuffer;
614	FWAddress 						fSetBusyTimeoutAddress;
615	IOFWWriteQuadCommand *			fSetBusyTimeoutCommand;
616
617	bool							fInCriticalSection;
618
619	UInt16					fLocalNodeID;
620	bool					fFastStartSupported;
621	UInt32					fFastStartOffset;
622	UInt32					fFastStartMaxPayload;
623
624	UInt32					fUserLoginGeneration;
625	bool					fUserLoginGenerationSet;
626
627	IOFWDelayCommand *		fFetchAgentRetryTimerCommand;
628    bool					fFetchAgentRetryTimerSet;
629
630	virtual IOReturn executeSetBusyTimeout( void );
631	static void setBusyTimeoutCompleteStatic( void *refcon, IOReturn status, IOFireWireNub *device, IOFWCommand *fwCmd );
632	virtual void setBusyTimeoutComplete( IOReturn status, IOFireWireNub *device, IOFWCommand *fwCmd );
633
634private:
635	// IOFireWireSBP2ORB friend class wrappers
636	OSMetaClassDeclareReservedUnused(IOFireWireSBP2Login, 0);
637
638protected:
639	virtual bool initORBWithLogin( IOFireWireSBP2ORB * orb, IOFireWireSBP2Login * login );
640	virtual void setNextORBAddress( IOFireWireSBP2ORB * orb, FWAddress address );
641    virtual void fetchAgentWriteComplete( IOFireWireSBP2ORB * orb, IOReturn status );
642    virtual bool isORBTimerSet( IOFireWireSBP2ORB * orb );
643    virtual void cancelORBTimer( IOFireWireSBP2ORB * orb );
644
645	// IOFireWireSBP2LUN friend class wrappers
646	virtual void removeLogin( void );
647	virtual IOFireWireSBP2Target * getTarget( void );
648
649	UInt32		fARDMAMax;
650	bool		fPhysicalAccessEnabled;
651
652	bool					fLoginStatusReceived;
653	FWSBP2StatusBlock		fLoginStatusBlock;
654	UInt32					fLoginStatusBlockLen;
655
656private:
657
658    OSMetaClassDeclareReservedUnused(IOFireWireSBP2Login, 1);
659    OSMetaClassDeclareReservedUnused(IOFireWireSBP2Login, 2);
660    OSMetaClassDeclareReservedUnused(IOFireWireSBP2Login, 3);
661    OSMetaClassDeclareReservedUnused(IOFireWireSBP2Login, 4);
662	OSMetaClassDeclareReservedUnused(IOFireWireSBP2Login, 5);
663
664public:
665
666	//////////////////////////////
667
668    /*!
669		@function createORB
670		@abstract Creates a new IOFireWireSBP2ORB for this login.
671		@discussion	Create a new IOFireWireSBP2ORB for this login.  It can be configured
672        with it's accessors and executed with submitORB below.
673        @result Returns a pointer to the new ORB object.
674	*/
675
676	virtual IOFireWireSBP2ORB * createORB( void );
677
678    /*!
679		@function submitORB
680		@abstract Submits the given orb
681		@discussion	Starts execution of the given ORB.  If the ORB is an immediate ORB it's
682        addresss is written to the fetch agent.  If it is a non immediate orb its address
683        is appended to the last orb of the currently processing chain.  The doorbell is not
684        rung automatically it must be run manually with the ringDoorbell command described below.
685        @param orb The orb to be executed.
686        @result Returns kIOReturnSuccess if the ORB has been started successfully.
687	*/
688
689    virtual IOReturn submitORB( IOFireWireSBP2ORB * orb );
690
691    // set callbacks
692
693    /*!
694		@function setStatusNotifyProc
695		@abstract Sets the callback to be called on normal command status.
696		@discussion The supplied callback is called when normal command status is recieved, when
697        a normal command times out, or when a normal command is aborted.
698        "notificationEvent" in the callback's params will indicate what happened.
699        It will be set to one of the following values: kFWSBP2NormalCommandReset, kFWSBP2NormalCommandStatus,
700        or kFWSBP2NormalCommandTimeout.  If the event type is kFWSBP2NormalCommandTimeout and "len" is
701        non-zero then "message" contains the data written to the status block.
702        @param refCon refCon passed to callback.
703        @param callback address of callback method of type FWSBP2NotifyCallback.
704	*/
705
706    virtual void setStatusNotifyProc( void * refCon, FWSBP2NotifyCallback callback );
707
708    /*!
709		@function getStatusNotifyProc
710		@abstract Returns the callback to be called on normal command status.
711		@discussion Returns the refCon and callback address of the status notify callback.
712        @param refCon output parameter returning the refCon to be passed to the callback.
713        @param callback output parameter returning the address of the callback.
714	*/
715
716    virtual void getStatusNotifyProc( void ** refCon, FWSBP2NotifyCallback * callback );
717
718    /*!
719		@function setUnsolicitedStatusNotifyProc
720		@abstract Sets the callback to be called on normal command status.
721		@discussion The supplied callback is called when unsolicited status is recieved.
722        "notificationEvent" in the callback's params will indicate what happened.  In this
723        case it will be set to kFWSBP2UnsolicitedStatus. If "len" is
724        non-zero then "message" contains the data written to the status block. Note: any buffers
725        returned by callbacks are only valid for the duration of the login and should not have
726        their contents modified.
727        @param refCon refCon passed to callback.
728        @param callback address of callback method of type FWSBP2NotifyCallback.
729	*/
730
731    virtual void setUnsolicitedStatusNotifyProc( void * refCon, FWSBP2NotifyCallback callback );
732
733    /*!
734		@function getUnsolicitedStatusNotifyProc
735		@abstract Returns the callback to be called on unsolicited status.
736		@discussion Returns the refCon and callback address of the unsolicited status notify callback.
737        @param refCon output parameter returning the refCon to be passed to the callback.
738        @param callback output parameter returning the address of the callback.
739	*/
740
741    virtual void getUnsolicitedStatusNotifyProc( void ** refCon, FWSBP2NotifyCallback * callback );
742
743    // command handling
744
745    /*!
746		@function setLoginCompletion
747		@abstract Sets the callback to be called when a login attempt is complete.
748		@discussion The supplied callback is called when a login attempt has completed. "status" in the
749        callback's params should be checked to determine the success or failure of the login attempt.
750        If "statusBlock" is non-null then login status was written and it has been supplied here.  If
751        the login attempt was successful then the login response will be supplied in the "loginResponse"
752        buffer.  Note: all buffers supplied to callbacks are only valid for the duration of the callback.
753        Also, you are not to modify the contents of any supplied buffer.
754        @param refCon refCon passed to callback.
755        @param callback address of callback method of type FWSBP2LoginCallback.
756	*/
757
758	virtual void setLoginCompletion( void * refCon, FWSBP2LoginCallback completion );
759
760    /*!
761		@function submitLogin
762		@abstract Attempts to login to the LUN.
763        @discussion This call begins the login process.  The login object should be configured prior
764        to this call. If kIOReturnSuccess is returned from this call then the loginCompletion routine
765        will be called when the login completes (successfully or unsuccesfully).
766        @result Returns kIOReturnSuccess login has successlly begun.
767	*/
768
769    virtual IOReturn submitLogin( void );
770
771    /*!
772		@function submitLogout
773		@abstract Attempts to logout of the LUN.
774        @discussion This call begins the logout process.  If kIOReturnSuccess is returned from this call then
775        the logoutCompletion routine will be called when the logout completes (successfully or unsuccesfully).
776        @result Returns kIOReturnSuccess if logout has successfully begun.
777	*/
778
779    virtual IOReturn submitLogout( void );
780
781    /*!
782		@function setLogoutCompletion
783		@abstract Sets the callback to be called when a logout attempt is complete.
784		@discussion The supplied callback is called when a logout attempt has completed. "status" in the
785        callback's params should be checked to determine the success or failure of the logout attempt.
786        If "statusBlock" is non-null then logout status was written and it has been supplied here.
787        Note: all buffers supplied to callbacks are only valid for the duration of the callback.
788        Also, you are not to modify the contents of any supplied buffer.
789        @param refCon refCon passed to callback.
790        @param callback address of callback method of type FWSBP2LogoutCallback.
791	*/
792
793    virtual void setLogoutCompletion( void * refCon, FWSBP2LogoutCallback completion );
794
795    /*!
796		@function setFetchAgentWriteCompletion
797		@abstract Sets the callback to be called when the fetch agent write completes.
798		@discussion When an immediate orb is executed with submitORB, it's address is written to a
799        specific address on the device.  This address is called the fetch agent.  The device the
800        reads that orb from the Mac's memory and executes it.  With this call you can register to
801        be called back when this write to the fetch agent completes.  The SBP2 services guarantee
802        that the fetch agent write will be complete before status is reported for an ORB, so for
803        most drivers this notification is not required.
804        @param refCon refCon passed to callback.
805        @param callback address of callback method of type FWSBP2FetchAgentWriteCallback.
806	*/
807
808	virtual void setFetchAgentWriteCompletion( void * refCon, FWSBP2FetchAgentWriteCallback completion );
809
810    /*!
811		@function setFetchAgentResetCompletion
812		@abstract Sets the callback to be called when a fetch agent reset completes.
813		@discussion The fetch agent state machine on the device can be reset by a write to a specific
814        register.  The SBP2 services offer a utility method to reset the fetch agent.  You can register
815        a callback routine here to be notified when this rest write completes.
816        @param refCon refCon passed to callback.
817        @param callback address of callback method of type FWSBP2FetchAgentWriteCallback.
818	*/
819
820    virtual void setFetchAgentResetCompletion( void * refCon, FWSBP2StatusCallback completion );
821
822    /*!
823		@function submitFetchAgentReset
824		@abstract Resets the LUN's fetch agent.
825		@discussion The fetch agent state machine on the device can be reset by a write to a specific
826        register.  This reset can be intiated by a call to this method.  Notification of the completion
827        of this write can be had by registering a callback with the setFetchAgentResetCompletion method.
828        @result Returns kIOReturnSuccess if the reset started successfully.
829	*/
830
831	virtual IOReturn submitFetchAgentReset( void );
832
833    /*!
834		@function ringDoorbell
835		@abstract Rings the doorbell on the LUN.
836		@discussion Non-immediate appends to the ORB chain may require the fetch agent state machine
837        to be notified of the new ORB's presence.  This is accomplished by writing to the so called
838        doorbell register.  This method begins one of those writes.
839        @result Returns kIOReturnSuccess if the ring started successfully.
840	*/
841
842 	virtual IOReturn ringDoorbell( void );
843
844    /*!
845		@function enableUnsolicitedStatus
846		@abstract Enables unsolicited status.
847		@discussion After unsolicited is sent the device will not send any additional unsolicited status
848        until a specific register is written.  This serves as a sort of flow-control for unsolicited status.
849        After unsolicited status is recieved and processed drivers will want to reenable the delivery
850        of unsolicted status by a call to this method.
851        @result Returns kIOReturnSuccess if the status enable write started successfully.
852	*/
853
854	virtual IOReturn enableUnsolicitedStatus( void );
855
856    // accessors
857
858    /*!
859		@function getMaxCommandBlockSize
860		@abstract Returns the maximum command block size.
861		@discussion The device publishes an upper limit on the size of command block that it can
862        accept.  That value can be accessed via this method.
863        @result Returns a UInt32 containing the maximum command block size.
864	*/
865
866    virtual UInt32 getMaxCommandBlockSize( void );
867
868    /*!
869		@function getLoginID
870		@abstract Returns the current login ID.
871		@discussion When we successfully login to a device.  The device gives us a unique login id.
872        This is used internally for reconnecting to the device after bus resets and for certain other
873        management ORBs.  Most drivers are probably not interested in this value.
874        @result Returns a UInt32 containing the current login ID.
875	*/
876
877    virtual UInt32 getLoginID( void );
878
879    /*!
880		@function setLoginFlags
881		@abstract Sets login configuration flags.
882		@discussion Configures the login behavior according to the provided flags.  Currently two
883        flags are defined for this API.  kFWSBP2ExclusiveLogin sets the exclusive login bit in the
884        login ORB. kFWSBP2DontSynchronizeMgmtAgent allows simultaneous logins or reconnects to LUNs
885        with a common management agent (ie LUNs in the same unit directory).
886        @param loginFlags the login configuration flags.
887	*/
888
889    virtual void setLoginFlags( UInt32 loginFlags );
890
891    /*!
892		@function getLoginFlags
893		@abstract Returns the currently set login flags.
894		@discussion Returns the current state of the login flags.  Currently there is only one
895        flag defined for this API.  kFWSBP2ExclusiveLogin indicates that the exclusive login bit
896        should be set in the login ORB.
897        @result Returns a UInt32 containing the currently set login flags.
898	*/
899
900    virtual UInt32 getLoginFlags( void );
901
902    /*!
903		@function setReconnectTime
904		@abstract Sets the desired reconnect duration.
905		@discussion The target and initiator arbitrate the duration of the reconnect timeout.  Here
906        the initiator specifies its desired timeout time in 2^reconnectTime seconds.  After a
907        successful login the device returns the actual timeout value it wishes to use.  This value
908        may be less than the reconnect timeout that the intiator specified if this is all that the
909        device can support.
910        @param reconnectTime The desired reconnect timeout encoded as 2^reconnectTime seconds.
911	*/
912
913    virtual void setReconnectTime( UInt32 reconnectTime );
914
915    /*!
916		@function getReconnectTime
917		@abstract Returns the currently set reconnect time.
918		@discussion Returns the currently desired initiator reconnect time encoded as 2^time seconds.
919        @result Returns a UInt32 containing the currently set reconnect time.
920	*/
921
922    virtual UInt32 getReconnectTime( void );
923
924    /*!
925		@function setMaxPayloadSize
926		@abstract Sets the maximum data transfer length for a normal command ORB.
927		@discussion Sets the maximum data transfer length for a normal command ORB.  This value is
928        the maximum for all ORBs sent to this LUN.  This can be trimmed further on an ORB by ORB basis,
929        by a similar call in the IOFireWireSBP2ORB itself.
930        @param reconnectTime The desired maximum payload size in bytes.
931	*/
932
933    virtual void setMaxPayloadSize( UInt32 maxPayloadSize );
934
935    /*!
936		@function getMaxPayloadSize
937		@abstract Returns the currently set maximum payload size.
938		@discussion Returns the currently global maximum payload size in bytes.
939        @result Returns a UInt32 containing the currently set maximum payload size.
940	*/
941
942    virtual UInt32 getMaxPayloadSize( void );
943
944    /*!
945		@function setPassword
946		@abstract Sets the login password.
947		@discussion Sets the login password using a buffer and a length.  An alternate version exists
948        that accepts an IOMemoryDescriptor.  If the password length is 8 or less the password is copied
949        directly into the login orb.  If the length is greater than 8 the buffer is referenced by address
950        in the login ORB.  In this case the buffer is not copied and should remain allocated for the
951        duration of the login attempt.
952        @param buf a pointer to the password buffer.
953        @param len the length in bytes of the password buffer.
954        @result Returns kIOReturnSuccess on success.
955	*/
956
957    virtual IOReturn setPassword( void * buf, UInt32 len );
958
959    /*!
960		@function setPassword
961		@abstract Sets the login password.
962		@discussion Sets the login password using an IOMemoryDescriptor.  An alternate version exists
963        that accepts a buffer and a length.  If the password length is 8 or less the password is copied
964        directly into the login orb.  If the length is greater than 8 the buffer is referenced by address
965        in the login ORB.
966        @param memory an IOMemoryDescriptor referencing the password.
967        @result Returns kIOReturnSuccess on success.
968	*/
969
970    virtual IOReturn setPassword( IOMemoryDescriptor * memory );
971
972
973    /*!
974		@function setRefCon
975		@abstract Sets the login refCon.
976		@discussion Sets a user defined value on the login that can be retrieved later with the
977        method getRefCon.
978        @param refCon a user defined value.
979    */
980
981    virtual void setRefCon( void * refCon );
982
983    /*!
984		@function getRefCon
985		@abstract Returns the refCon set with setRefCon.
986		@discussion Returns the user defined value previously stored in the login with setRefCon.
987        @result Returns the previously stored user defined value.
988	*/
989
990    virtual void * getRefCon( void );
991
992    /*!
993		@function setBusyTimeoutRegisterValue
994		@abstract Sets the value to be written to the BUSY_TIMEOUT register.
995		@discussion 1394-1995 defines a register known as the BUSY_TIMEOUT register. This register
996        controls the busy retry behavior of your device.  The initial value for this register is
997        0x00000000.  Which means busied transactions will not be retried.  Since most devices want
998        their transactions retired on busy acks, the SBP2 service automatically updates the
999        BUSY_TIMEOUT register with the value specified here whenever necessary.  Most drivers should
1000        set this value to 0x0000000f.
1001        @param timeout desired value of the BUSY_TIMEOUT register.
1002    */
1003
1004	virtual void setBusyTimeoutRegisterValue( UInt32 timeout );
1005
1006protected:
1007
1008    virtual void startORBTimer( IOFireWireSBP2ORB * orb );
1009    virtual void prepareORBForExecution( IOFireWireSBP2ORB * orb );
1010
1011    static IOReturn staticExecuteORB( OSObject *self, void * orb, void *, void *, void * );
1012    virtual IOReturn executeORB( IOFireWireSBP2ORB * orb );
1013
1014public:
1015
1016    /*!
1017        @function release
1018        @abstract Primary implementation of the release mechanism.
1019        @discussion See OSObject.h for more information.  When retainCount == when then call free().
1020    */
1021
1022    virtual void release() const;
1023
1024	/*!
1025        @function setLoginRetryCountAndDelayTime
1026        @abstract Sets login retry behavior.
1027        @discussion Sets login retry behavior.
1028        @param retryCount number of times to retry logins
1029		@param uSecs delay time in microseconds between login retries
1030    */
1031
1032	virtual void setLoginRetryCountAndDelayTime( UInt32 retryCount, UInt32 uSecs );
1033
1034protected:
1035	virtual IOReturn initialExecuteLogin( void );
1036	virtual void startLoginRetryTimer( void );
1037	virtual void stopLoginRetryTimer( void );
1038	static void loginRetryTimeoutStatic( void *refcon, IOReturn status,
1039										 IOFireWireBus *bus, IOFWBusCommand *fwCmd );
1040	virtual void loginRetryTimeout( IOReturn status, IOFireWireBus *bus, IOFWBusCommand *fwCmd);
1041
1042	virtual void startReconnectRetryTimer( void );
1043	virtual void stopReconnectRetryTimer( void );
1044	static void reconnectRetryTimeoutStatic( void *refcon, IOReturn status, IOFireWireBus *bus, IOFWBusCommand *fwCmd );
1045	virtual void reconnectRetryTimeout( IOReturn status, IOFireWireBus *bus, IOFWBusCommand *fwCmd );
1046
1047	virtual bool isORBAppended( IOFireWireSBP2ORB * orb );
1048	virtual void setORBIsAppended( IOFireWireSBP2ORB * orb, bool state );
1049
1050public:
1051	virtual void setAddressLoForLoginORBAndResponse( UInt32 addressLoORB, UInt32 addresLoResponse );
1052
1053	virtual void setLoginGeneration( UInt32 generation );
1054	virtual void clearLoginGeneration( void );
1055
1056protected:
1057	void startFetchAgentRetryTimer( UInt32 duration );
1058	void stopFetchAgentRetryTimer( void );
1059	static void fetchAgentRetryTimerStatic( void *refcon, IOReturn status, IOFireWireBus *bus, IOFWBusCommand *fwCmd );
1060	void fetchAgentRetryTimer( IOReturn status, IOFireWireBus *bus, IOFWBusCommand *fwCmd );
1061
1062	void terminateNotify( void );
1063	void processLoginWrite( void );
1064
1065public:
1066
1067	bool	isPhysicalAccessEnabled( void );
1068	UInt32	getARDMMax( void );
1069
1070private:
1071
1072    OSMetaClassDeclareReservedUnused(IOFireWireSBP2Login, 6);
1073    OSMetaClassDeclareReservedUnused(IOFireWireSBP2Login, 7);
1074    OSMetaClassDeclareReservedUnused(IOFireWireSBP2Login, 8);
1075
1076 };
1077
1078#endif
1079