1/*
2 * Copyright (c) 2007 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25//-----------------------------------------------------------------------------
26//	Includes
27//-----------------------------------------------------------------------------
28
29#include <IOKit/IOTypes.h>
30#include "SCSIParallelWorkLoop.h"
31
32
33//-----------------------------------------------------------------------------
34//	Macros
35//-----------------------------------------------------------------------------
36
37#define DEBUG 												0
38#define DEBUG_ASSERT_COMPONENT_NAME_STRING					"SPI WorkLoop"
39
40#if DEBUG
41#define SCSI_PARALLEL_WORKLOOP_DEBUGGING_LEVEL				0
42#endif
43
44
45#include "IOSCSIParallelFamilyDebugging.h"
46
47
48#if ( SCSI_PARALLEL_WORKLOOP_DEBUGGING_LEVEL >= 1 )
49#define PANIC_NOW(x)		panic x
50#else
51#define PANIC_NOW(x)
52#endif
53
54#if ( SCSI_PARALLEL_WORKLOOP_DEBUGGING_LEVEL >= 2 )
55#define ERROR_LOG(x)		IOLog x
56#else
57#define ERROR_LOG(x)
58#endif
59
60#if ( SCSI_PARALLEL_WORKLOOP_DEBUGGING_LEVEL >= 3 )
61#define STATUS_LOG(x)		IOLog x
62#else
63#define STATUS_LOG(x)
64#endif
65
66
67#define super IOWorkLoop
68OSDefineMetaClassAndStructors ( SCSIParallelWorkLoop, IOWorkLoop );
69
70
71#if 0
72#pragma mark -
73#pragma mark IOKit Member Routines
74#pragma mark -
75#endif
76
77
78//-----------------------------------------------------------------------------
79//	Create													   [STATIC][PUBLIC]
80//-----------------------------------------------------------------------------
81
82SCSIParallelWorkLoop *
83SCSIParallelWorkLoop::Create ( const char *	lockGroupName )
84{
85
86	SCSIParallelWorkLoop *		workLoop = NULL;
87
88	workLoop = OSTypeAlloc ( SCSIParallelWorkLoop );
89	require_nonzero ( workLoop, ErrorExit );
90
91	require ( workLoop->InitWithLockGroupName ( lockGroupName ), ReleaseWorkLoop );
92
93	return workLoop;
94
95
96ReleaseWorkLoop:
97
98
99	require_nonzero ( workLoop, ErrorExit );
100	workLoop->release ( );
101	workLoop = NULL;
102
103
104ErrorExit:
105
106
107	return workLoop;
108
109}
110
111
112//-----------------------------------------------------------------------------
113//	InitWithLockGroupName											[PROTECTED]
114//-----------------------------------------------------------------------------
115
116bool
117SCSIParallelWorkLoop::InitWithLockGroupName ( const char * lockGroupName )
118{
119
120	bool	result = false;
121
122	fLockGroup = lck_grp_alloc_init ( lockGroupName, LCK_GRP_ATTR_NULL );
123	require_nonzero ( fLockGroup, ErrorExit );
124
125	// Allocate the gateLock before calling the super class. This allows
126	// us to profile contention on our workloop lock.
127	gateLock = IORecursiveLockAllocWithLockGroup ( fLockGroup );
128
129	result = super::init ( );
130
131
132ErrorExit:
133
134
135	return result;
136
137}
138
139
140//-----------------------------------------------------------------------------
141//	free															[PROTECTED]
142//-----------------------------------------------------------------------------
143
144void
145SCSIParallelWorkLoop::free ( void )
146{
147
148	// NOTE: IOWorkLoop::free() gets called multiple times!
149	if ( fLockGroup != NULL )
150	{
151
152		lck_grp_free ( fLockGroup );
153		fLockGroup = NULL;
154
155	}
156
157	super::free ( );
158
159}
160