VoodooSDHCI

VoodooSDHCI Commit Details

Date:2010-07-17 19:06:48 (13 years 9 months ago)
Author:nil
Commit:2
Parents: 1
Message:VoodooSDHCI : Initial Commit KNOWN PROBLEM: (CMD8) error (grep for it)
Changes:
A/trunk/VoodooSDHC.h
A/trunk/VoodooSDHC.xcodeproj
A/trunk/SD_Misc.h
A/trunk/License.h
A/trunk/SD_DataTypes.h
A/trunk/SD_Commands.h
A/trunk/English.lproj/InfoPlist.strings
A/trunk/English.lproj
A/trunk/VoodooSDHC.xcodeproj/james.mode1v3
A/trunk/sdhci.h
A/trunk/me.jpg
A/trunk/SDHCI_Register_Map.h
A/trunk/Info.plist
A/trunk/VoodooSDHC.cpp
A/trunk/VoodooSDHC.xcodeproj/james.pbxuser
A/trunk/VoodooSDHC.xcodeproj/project.pbxproj

File differences

trunk/sdhci.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
#ifndef SDHCI_H
#include "License.h"
/*Controller registers*/
#define SDHCI_DMA_ADDRESS0x00
#define SDHCI_BLOCK_SIZE0x04
#define SDHCI_MAKE_BLKSZ(dma, blksz) (((dma & 0x7) << 12) | (blksz & 0xFFF))
#define SDHCI_BLOCK_COUNT0x06
#define SDHCI_ARGUMENT0x08
#define SDHCI_TRANSFER_MODE0x0C
#define SDHCI_TRNS_DMA0x01
#define SDHCI_TRNS_BLK_CNT_EN0x02
#define SDHCI_TRNS_ACMD120x04
#define SDHCI_TRNS_READ0x10
#define SDHCI_TRNS_MULTI0x20
#define SDHCI_COMMAND0x0E
#define SDHCI_CMD_RESP_MASK0x03
#define SDHCI_CMD_CRC0x08
#define SDHCI_CMD_INDEX0x10
#define SDHCI_CMD_DATA0x20
#define SDHCI_CMD_RESP_NONE0x00
#define SDHCI_CMD_RESP_LONG0x01
#define SDHCI_CMD_RESP_SHORT0x02
#define SDHCI_CMD_RESP_SHORT_BUSY 0x03
#define SDHCI_MAKE_CMD(c, f) (((c & 0xff) << 8) | (f & 0xff))
#define SDHCI_RESPONSE0x10
#define SDHCI_BUFFER0x20
#define SDHCI_PRESENT_STATE0x24
#define SDHCI_CMD_INHIBIT0x00000001
#define SDHCI_DATA_INHIBIT0x00000002
#define SDHCI_DOING_WRITE0x00000100
#define SDHCI_DOING_READ0x00000200
#define SDHCI_SPACE_AVAILABLE0x00000400
#define SDHCI_DATA_AVAILABLE0x00000800
#define SDHCI_CARD_PRESENT0x00010000
#define SDHCI_WRITE_PROTECT0x00080000
#define SDHCI_HOST_CONTROL 0x28
#define SDHCI_CTRL_LED0x01
#define SDHCI_CTRL_4BITBUS0x02
#define SDHCI_CTRL_HISPD0x04
#define SDHCI_CTRL_DMA_MASK0x18
#define SDHCI_CTRL_SDMA0x00
#define SDHCI_CTRL_ADMA10x08
#define SDHCI_CTRL_ADMA320x10
#define SDHCI_CTRL_ADMA640x18
#define SDHCI_POWER_CONTROL0x29
#define SDHCI_POWER_ON0x01
#define SDHCI_POWER_1800x0A
#define SDHCI_POWER_3000x0C
#define SDHCI_POWER_3300x0E
#define SDHCI_BLOCK_GAP_CONTROL0x2A
#define SDHCI_WAKE_UP_CONTROL0x2B
#define SDHCI_CLOCK_CONTROL0x2C
#define SDHCI_DIVIDER_SHIFT8
#define SDHCI_CLOCK_CARD_EN0x0004
#define SDHCI_CLOCK_INT_STABLE0x0002
#define SDHCI_CLOCK_INT_EN0x0001
#define SDHCI_TIMEOUT_CONTROL0x2E
#define SDHCI_SOFTWARE_RESET0x2F
#define SDHCI_RESET_ALL0x01
#define SDHCI_RESET_CMD0x02
#define SDHCI_RESET_DATA0x04
#define SDHCI_INT_STATUS0x30
#define SDHCI_INT_ENABLE0x34
#define SDHCI_SIGNAL_ENABLE0x38
#define SDHCI_INT_RESPONSE0x00000001
#define SDHCI_INT_DATA_END0x00000002
#define SDHCI_INT_DMA_END0x00000008
#define SDHCI_INT_SPACE_AVAIL0x00000010
#define SDHCI_INT_DATA_AVAIL0x00000020
#define SDHCI_INT_CARD_INSERT0x00000040
#define SDHCI_INT_CARD_REMOVE0x00000080
#define SDHCI_INT_CARD_INT0x00000100
#define SDHCI_INT_ERROR0x00008000
#define SDHCI_INT_TIMEOUT0x00010000
#define SDHCI_INT_CRC0x00020000
#define SDHCI_INT_END_BIT0x00040000
#define SDHCI_INT_INDEX0x00080000
#define SDHCI_INT_DATA_TIMEOUT0x00100000
#define SDHCI_INT_DATA_CRC0x00200000
#define SDHCI_INT_DATA_END_BIT0x00400000
#define SDHCI_INT_BUS_POWER0x00800000
#define SDHCI_INT_ACMD12ERR0x01000000
#define SDHCI_INT_ADMA_ERROR0x02000000
#define SDHCI_INT_NORMAL_MASK0x00007FFF
#define SDHCI_INT_ERROR_MASK0xFFFF8000
#define SDHCI_INT_CMD_MASK(SDHCI_INT_RESPONSE | SDHCI_INT_TIMEOUT | \
SDHCI_INT_CRC | SDHCI_INT_END_BIT | SDHCI_INT_INDEX)
#define SDHCI_INT_DATA_MASK(SDHCI_INT_DATA_END | SDHCI_INT_DMA_END | \
SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | \
SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \
SDHCI_INT_DATA_END_BIT)
#define SDHCI_ACMD12_ERR0x3C
/* 3E-3F reserved */
#define SDHCI_CAPABILITIES0x40
#define SDHCI_TIMEOUT_CLK_MASK0x0000003F
#define SDHCI_TIMEOUT_CLK_SHIFT 0
#define SDHCI_TIMEOUT_CLK_UNIT0x00000080
#define SDHCI_CLOCK_BASE_MASK0x00003F00
#define SDHCI_CLOCK_BASE_SHIFT8
#define SDHCI_MAX_BLOCK_MASK0x00030000
#define SDHCI_MAX_BLOCK_SHIFT 16
#define SDHCI_CAN_DO_ADMA20x00080000
#define SDHCI_CAN_DO_ADMA10x00100000
#define SDHCI_CAN_DO_HISPD0x00200000
#define SDHCI_CAN_DO_DMA0x00400000
#define SDHCI_CAN_VDD_3300x01000000
#define SDHCI_CAN_VDD_3000x02000000
#define SDHCI_CAN_VDD_1800x04000000
#define SDHCI_CAN_64BIT0x10000000
/* 44-47 reserved for more caps */
#define SDHCI_MAX_CURRENT0x48
/* 4C-4F reserved for more max current */
#define SDHCI_SET_ACMD12_ERROR0x50
#define SDHCI_SET_INT_ERROR0x52
#define SDHCI_ADMA_ERROR0x54
/* 55-57 reserved */
#define SDHCI_ADMA_ADDRESS0x58
/* 60-FB reserved */
#define SDHCI_SLOT_INT_STATUS0xFC
#define SDHCI_HOST_VERSION0xFE
#define SDHCI_VENDOR_VER_MASK0xFF00
#define SDHCI_VENDOR_VER_SHIFT8
#define SDHCI_SPEC_VER_MASK0x00FF
#define SDHCI_SPEC_VER_SHIFT0
#define SDHCI_SPEC_1000
#define SDHCI_SPEC_2001
#ifdef LINUX_STRUCTURE
struct sdhci_ops;
struct sdhci_host {
/* Data set by hardware interface driver */
const char*hw_name;/* Hardware bus name */
unsigned intquirks;/* Deviations from spec. */
/* Controller doesn't honor resets unless we touch the clock register */
#define SDHCI_QUIRK_CLOCK_BEFORE_RESET(1<<0)
/* Controller has bad caps bits, but really supports DMA */
#define SDHCI_QUIRK_FORCE_DMA(1<<1)
/* Controller doesn't like to be reset when there is no card inserted. */
#define SDHCI_QUIRK_NO_CARD_NO_RESET(1<<2)
/* Controller doesn't like clearing the power reg before a change */
#define SDHCI_QUIRK_SINGLE_POWER_WRITE(1<<3)
/* Controller has flaky internal state so reset it on each ios change */
#define SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS(1<<4)
/* Controller has an unusable DMA engine */
#define SDHCI_QUIRK_BROKEN_DMA(1<<5)
/* Controller has an unusable ADMA engine */
#define SDHCI_QUIRK_BROKEN_ADMA(1<<6)
/* Controller can only DMA from 32-bit aligned addresses */
#define SDHCI_QUIRK_32BIT_DMA_ADDR(1<<7)
/* Controller can only DMA chunk sizes that are a multiple of 32 bits */
#define SDHCI_QUIRK_32BIT_DMA_SIZE(1<<8)
/* Controller can only ADMA chunks that are a multiple of 32 bits */
#define SDHCI_QUIRK_32BIT_ADMA_SIZE(1<<9)
/* Controller needs to be reset after each request to stay stable */
#define SDHCI_QUIRK_RESET_AFTER_REQUEST(1<<10)
/* Controller needs voltage and power writes to happen separately */
#define SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER(1<<11)
/* Controller provides an incorrect timeout value for transfers */
#define SDHCI_QUIRK_BROKEN_TIMEOUT_VAL(1<<12)
/* Controller has an issue with buffer bits for small transfers */
#define SDHCI_QUIRK_BROKEN_SMALL_PIO(1<<13)
intirq;/* Device IRQ */
void __iomem *ioaddr;/* Mapped address */
const struct sdhci_ops*ops;/* Low level hw interface */
/* Internal data */
struct mmc_host*mmc;/* MMC structure */
u64dma_mask;/* custom DMA mask */
#ifdef CONFIG_LEDS_CLASS
struct led_classdevled;/* LED control */
#endif
spinlock_tlock;/* Mutex */
intflags;/* Host attributes */
#define SDHCI_USE_DMA(1<<0)/* Host is DMA capable */
#define SDHCI_USE_ADMA(1<<1)/* Host is ADMA capable */
#define SDHCI_REQ_USE_DMA(1<<2)/* Use DMA for this req. */
#define SDHCI_DEVICE_DEAD(1<<3)/* Device unresponsive */
unsigned intversion;/* SDHCI spec. version */
unsigned intmax_clk;/* Max possible freq (MHz) */
unsigned inttimeout_clk;/* Timeout freq (KHz) */
unsigned intclock;/* Current clock (MHz) */
unsigned shortpower;/* Current voltage */
struct mmc_request*mrq;/* Current request */
struct mmc_command*cmd;/* Current command */
struct mmc_data*data;/* Current data request */
unsigned intdata_early:1;/* Data finished before cmd */
struct sg_mapping_itersg_miter;/* SG state for PIO */
unsigned intblocks;/* remaining PIO blocks */
intsg_count;/* Mapped sg entries */
u8*adma_desc;/* ADMA descriptor table */
u8*align_buffer;/* Bounce buffer */
dma_addr_tadma_addr;/* Mapped ADMA descr. table */
dma_addr_talign_addr;/* Mapped bounce buffer */
struct tasklet_structcard_tasklet;/* Tasklet structures */
struct tasklet_structfinish_tasklet;
struct timer_listtimer;/* Timer for timeouts */
unsigned longprivate[0] ____cacheline_aligned;
};
struct sdhci_ops {
int(*enable_dma)(struct sdhci_host *host);
};
extern struct sdhci_host *sdhci_alloc_host(struct device *dev,
size_t priv_size);
extern void sdhci_free_host(struct sdhci_host *host);
static inline void *sdhci_priv(struct sdhci_host *host)
{
return (void *)host->private;
}
extern int sdhci_add_host(struct sdhci_host *host);
extern void sdhci_remove_host(struct sdhci_host *host, int dead);
#ifdef CONFIG_PM
extern int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state);
extern int sdhci_resume_host(struct sdhci_host *host);
#endif
#endif /* LINUX_STRUCTURE */
#endif /* SDHCI_H */
trunk/SDHCI_Register_Map.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include "License.h"
#include "SD_Misc.h"
struct __attribute__ ((__packed__)) SDHCIRegMap_t {
volatile UInt32 SDMASysAddr;//0x00
volatile UInt16 BlockSize;//0x04
volatile UInt16 BlockCount;//0x06
volatile UInt32 Argument;//0x08
volatile UInt16 TransferMode;//0x0C
volatile UInt16 Command;//0x0E
volatile UInt32 Response[4];//0x10
volatile UInt32 BufferDataPort;//0x20
volatile UInt32 PresentState;//0x24
volatile UInt8 HostControl;//0x28
volatile UInt8 PowerControl;//0x29
volatile UInt8 BlockGapControl;//0x2A
volatile UInt8 WakeupControl;//0x2B
volatile UInt16 ClockControl;//0x2C
volatile UInt8 TimeoutControl;//0x2E
volatile UInt8 SoftwareReset;//0x2F
volatile UInt16 NormalIntStatus;//0x30
volatile UInt16 ErrorIntStatus;//0x32
volatile UInt16 NormalIntStatusEn;//0x34
volatile UInt16 ErrorIntStatusEn;//0x36
volatile UInt16 NormalIntSignalEn;//0x38
volatile UInt16 ErrorIntSignalEn;//0x3A
volatile UInt16 CMD12ErrorStatus;//0x3C
volatile UInt16 Reserved0;//0x3E
volatile UInt32 Capabilities[2];//0x40
volatile UInt32 MaxCurrentCap[2];//0x48
volatile UInt16 ForceEventCMD12ErrStatus;//0x50
volatile UInt16 ForceEventErrorIntStatus;//0x52
volatile UInt8 AMDAErrorStatus;//0x54
volatile UInt8 Reserved1;//0x55
volatile UInt16 Reserved2;//0x56
volatile UInt32 ADMASystemAddr[2];//0x58
volatile UInt16 ReservedArray[78];//0x60
volatile UInt16 SlotIntStatus;//0xFC
volatile UInt16 HostControllerVer;//0xFE
};
//PresentState
#define CMDLineLevelBIT24
#define DAT3LevelBIT23
#define DAT2LevelBIT22
#define DAT1LevelBIT21
#define DAT0LevelBIT20
#define WPSwitchLevelBIT19
#define CardDetectLevelBIT18
#define CardStateStable BIT17
#define CardInsertedBIT16
#define BuffReadEnBIT11
#define BuffWriteEnBIT10
#define ReadXferActiveBIT9
#define WriteXferActiveBIT8
#define DATLineActiveBIT2
#define ComInhibitDATBIT1
#define ComInhibitCMDBIT0
//HostControl
#define CDSigSelectionBIT7
#define CDTestLevelBIT6
#define DMASelSDMA0
#define DMASel32ADMA2BIT3
#define DMASel64ADMA2BIT4|BIT3
#define HighSpeedEnBIT2
#define DataXferWidthBIT1
#define LedControlBIT0
//PowerControl
#define HC3v30xE
#define HC3v00xD
#define HC1v80xA
#define SDPowerBIT0
//ClockControl
#define DIV256BIT16
#define DIV128BIT15
#defineDIV64BIT14
#define DIV32BIT13
#define DIV16BIT12
#define DIV8BIT11
#define DIV4BIT10
#defineDIV2BIT9
#define SDClockEnBIT2
#define SDClockStableBIT1
#define InternalClockEn BIT0
//Capabilities
#define CR64SysBusBIT28
#defineCR1v8SupportBIT26
#define CR3v0SupportBIT25
#define CR3v3SupportBIT24
#define SusRsmSupportBIT23
#define SDMASupportBIT22
#define HighSpSupportBIT21
#define ADMA2SupportBIT19
#define BlockLen5120
#define BlockLen1024BIT16
#define BlockLen2048BIT17
#define BaseClockMaskBIT13|BIT12|BIT11|BIT10|BIT9|BIT8
#define TOutClockUnitBIT7
#define TOutClockMaskBIT5|BIT4|BIT3|BIT2|BIT1|BIT0
//MaxCurrentCap
#define MaxCur1v8MaskBIT23|BIT22|BIT21|BIT20|BIT19|BIT18|BIT17|BIT16
#define MaxCur3v0MaskBIT15|BIT14|BIT13|BIT12|BIT11|BIT10|BIT9|BIT8
#define MaxCur3v3MaskBIT7|BIT6|BIT5|BIT4|BIT3|BIT2|BIT1|BIT0
//HostControllerVer
#define VendorVerMaskBIT15|BIT14|BIT13|BIT12|BIT11|BIT10|BIT9|BIT8
#define SpecVerMaskBIT7|BIT6|BIT5|BIT4|BIT3|BIT2|BIT1|BIT0
//SoftwareReset
#define CMD_RESETBIT1
#define DAT_RESETBIT2
#define FULL_RESETBIT0
//NormalIntStatus
#define ErrorInterruptBIT15
#define CardInterruptBIT8
#define CardRemovalBIT7
#define CardInsertionBIT6
#define BuffReadReadyBIT5
#define BuffWriteReadyBIT4
#defineDMAInterruptBIT3
#define BlockGapEventBIT2
#defineXferCompleteBIT1
#defineCmdCompleteBIT0
//ErrorIntStatus
#define ADMAErrorBIT9
#define AutoCMD12ErrorBIT8
#define CurLimitErrorBIT7
#define DatEndBitErrorBIT6
#define DatCRCErrorBIT5
#define DatTimeoutErrorBIT4
#define CmdIndexErrorBIT3
#define CmdEndBitErrorBIT2
#define CmdCRCErrorBIT1
#define CmdTimeoutErrorBIT0
trunk/VoodooSDHC.xcodeproj/james.pbxuser
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// !$*UTF8*$!
{
089C1669FE841209C02AAC07 /* Project object */ = {
activeBuildConfigurationName = Debug;
activeTarget = 32D94FC30562CBF700B6AF17 /* VoodooSDHC */;
codeSenseManager = 1A0E1DC611F218B700391780 /* Code sense */;
perUserDictionary = {
PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = {
PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
PBXFileTableDataSourceColumnWidthsKey = (
20,
341,
20,
48,
43,
43,
20,
);
PBXFileTableDataSourceColumnsKey = (
PBXFileDataSource_FiletypeID,
PBXFileDataSource_Filename_ColumnID,
PBXFileDataSource_Built_ColumnID,
PBXFileDataSource_ObjectSize_ColumnID,
PBXFileDataSource_Errors_ColumnID,
PBXFileDataSource_Warnings_ColumnID,
PBXFileDataSource_Target_ColumnID,
);
};
PBXPerProjectTemplateStateSaveDate = 301079019;
PBXWorkspaceStateSaveDate = 301079019;
};
sourceControlManager = 1A0E1DC511F218B700391780 /* Source Control */;
userBuildSettings = {
};
};
1A0E1DC511F218B700391780 /* Source Control */ = {
isa = PBXSourceControlManager;
fallbackIsa = XCSourceControlManager;
isSCMEnabled = 0;
scmConfiguration = {
repositoryNamesForRoots = {
"" = "";
};
};
};
1A0E1DC611F218B700391780 /* Code sense */ = {
isa = PBXCodeSenseManager;
indexTemplatePath = "";
};
32D94FC30562CBF700B6AF17 /* VoodooSDHC */ = {
activeExec = 0;
};
}
trunk/VoodooSDHC.xcodeproj/project.pbxproj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
052A08C50BF57D0A00D3692D /* SD_DataTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 052A08C40BF57D0A00D3692D /* SD_DataTypes.h */; };
05D69FA60BF0CE7D00AA4006 /* SDHCI_Register_Map.h in Headers */ = {isa = PBXBuildFile; fileRef = 05D69FA50BF0CE7D00AA4006 /* SDHCI_Register_Map.h */; };
05D69FBB0BF0D16100AA4006 /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 32D94FCF0562CBF700B6AF17 /* Info.plist */; };
05D6A0630BF128B500AA4006 /* SD_Commands.h in Headers */ = {isa = PBXBuildFile; fileRef = 05D6A0620BF128B500AA4006 /* SD_Commands.h */; };
05D6A0670BF1293100AA4006 /* SD_Misc.h in Headers */ = {isa = PBXBuildFile; fileRef = 05D6A0660BF1293100AA4006 /* SD_Misc.h */; };
1A147D05107EB37E006FFB43 /* License.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C98484A0F9A5D7800A2842D /* License.h */; };
32D94FC60562CBF700B6AF17 /* VoodooSDHC.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A224C3EFF42367911CA2CB7 /* VoodooSDHC.h */; };
32D94FC80562CBF700B6AF17 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; };
32D94FCA0562CBF700B6AF17 /* VoodooSDHC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A224C3FFF42367911CA2CB7 /* VoodooSDHC.cpp */; settings = {ATTRIBUTES = (); }; };
CFF5D56D0ECEC6F4009BB171 /* sdhci.h in Headers */ = {isa = PBXBuildFile; fileRef = CFF5D56C0ECEC6F4009BB171 /* sdhci.h */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
052A08C40BF57D0A00D3692D /* SD_DataTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SD_DataTypes.h; sourceTree = "<group>"; };
05D69FA50BF0CE7D00AA4006 /* SDHCI_Register_Map.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SDHCI_Register_Map.h; sourceTree = "<group>"; };
05D6A0620BF128B500AA4006 /* SD_Commands.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SD_Commands.h; sourceTree = "<group>"; };
05D6A0660BF1293100AA4006 /* SD_Misc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SD_Misc.h; sourceTree = "<group>"; };
089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
1A224C3EFF42367911CA2CB7 /* VoodooSDHC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VoodooSDHC.h; sourceTree = "<group>"; };
1A224C3FFF42367911CA2CB7 /* VoodooSDHC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VoodooSDHC.cpp; sourceTree = "<group>"; };
32D94FCF0562CBF700B6AF17 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
32D94FD00562CBF700B6AF17 /* VoodooSDHC.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = VoodooSDHC.kext; sourceTree = BUILT_PRODUCTS_DIR; };
6C98484A0F9A5D7800A2842D /* License.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = License.h; sourceTree = "<group>"; };
8DA8362C06AD9B9200E5AC22 /* Kernel.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Kernel.framework; path = /System/Library/Frameworks/Kernel.framework; sourceTree = "<absolute>"; };
CFF5D56C0ECEC6F4009BB171 /* sdhci.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sdhci.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
32D94FCB0562CBF700B6AF17 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
089C166AFE841209C02AAC07 /* IOSDHCIBlockDevice */ = {
isa = PBXGroup;
children = (
247142CAFF3F8F9811CA285C /* Source */,
8DA8362C06AD9B9200E5AC22 /* Kernel.framework */,
089C167CFE841241C02AAC07 /* Resources */,
19C28FB6FE9D52B211CA2CBB /* Products */,
);
name = IOSDHCIBlockDevice;
sourceTree = "<group>";
};
089C167CFE841241C02AAC07 /* Resources */ = {
isa = PBXGroup;
children = (
32D94FCF0562CBF700B6AF17 /* Info.plist */,
089C167DFE841241C02AAC07 /* InfoPlist.strings */,
);
name = Resources;
sourceTree = "<group>";
};
19C28FB6FE9D52B211CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
32D94FD00562CBF700B6AF17 /* VoodooSDHC.kext */,
);
name = Products;
sourceTree = "<group>";
};
247142CAFF3F8F9811CA285C /* Source */ = {
isa = PBXGroup;
children = (
6C98484A0F9A5D7800A2842D /* License.h */,
05D69FA50BF0CE7D00AA4006 /* SDHCI_Register_Map.h */,
CFF5D56C0ECEC6F4009BB171 /* sdhci.h */,
052A08C40BF57D0A00D3692D /* SD_DataTypes.h */,
05D6A0660BF1293100AA4006 /* SD_Misc.h */,
05D6A0620BF128B500AA4006 /* SD_Commands.h */,
1A224C3EFF42367911CA2CB7 /* VoodooSDHC.h */,
1A224C3FFF42367911CA2CB7 /* VoodooSDHC.cpp */,
);
name = Source;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
32D94FC50562CBF700B6AF17 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
32D94FC60562CBF700B6AF17 /* VoodooSDHC.h in Headers */,
05D69FA60BF0CE7D00AA4006 /* SDHCI_Register_Map.h in Headers */,
05D6A0630BF128B500AA4006 /* SD_Commands.h in Headers */,
05D6A0670BF1293100AA4006 /* SD_Misc.h in Headers */,
052A08C50BF57D0A00D3692D /* SD_DataTypes.h in Headers */,
CFF5D56D0ECEC6F4009BB171 /* sdhci.h in Headers */,
1A147D05107EB37E006FFB43 /* License.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
32D94FC30562CBF700B6AF17 /* VoodooSDHC */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1DEB91D908733DB10010E9CD /* Build configuration list for PBXNativeTarget "VoodooSDHC" */;
buildPhases = (
32D94FC50562CBF700B6AF17 /* Headers */,
32D94FC70562CBF700B6AF17 /* Resources */,
32D94FC90562CBF700B6AF17 /* Sources */,
32D94FCB0562CBF700B6AF17 /* Frameworks */,
32D94FCC0562CBF700B6AF17 /* Rez */,
);
buildRules = (
);
dependencies = (
);
name = VoodooSDHC;
productInstallPath = "$(SYSTEM_LIBRARY_DIR)/Extensions";
productName = IOSDHCIBlockDevice;
productReference = 32D94FD00562CBF700B6AF17 /* VoodooSDHC.kext */;
productType = "com.apple.product-type.kernel-extension.iokit";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
089C1669FE841209C02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 1DEB91DD08733DB10010E9CD /* Build configuration list for PBXProject "VoodooSDHC" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
English,
Japanese,
French,
German,
);
mainGroup = 089C166AFE841209C02AAC07 /* IOSDHCIBlockDevice */;
projectDirPath = "";
projectRoot = "";
targets = (
32D94FC30562CBF700B6AF17 /* VoodooSDHC */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
32D94FC70562CBF700B6AF17 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
32D94FC80562CBF700B6AF17 /* InfoPlist.strings in Resources */,
05D69FBB0BF0D16100AA4006 /* Info.plist in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXRezBuildPhase section */
32D94FCC0562CBF700B6AF17 /* Rez */ = {
isa = PBXRezBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXRezBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
32D94FC90562CBF700B6AF17 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
32D94FCA0562CBF700B6AF17 /* VoodooSDHC.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
089C167DFE841241C02AAC07 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
089C167EFE841241C02AAC07 /* English */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
1DEB91DA08733DB10010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1.1d1;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
GCC_MODEL_TUNING = G5;
GCC_OPTIMIZATION_LEVEL = 0;
INFOPLIST_FILE = Info.plist;
INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Extensions";
MODULE_NAME = com.Voodoo.driver.VoodooSDHC;
MODULE_VERSION = 1.1d1;
ONLY_ACTIVE_ARCH = NO;
PRODUCT_NAME = VoodooSDHC;
WRAPPER_EXTENSION = kext;
ZERO_LINK = YES;
};
name = Debug;
};
1DEB91DB08733DB10010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(NATIVE_ARCH)";
CURRENT_PROJECT_VERSION = 1.1d1;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_MODEL_TUNING = G5;
INFOPLIST_FILE = Info.plist;
INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Extensions";
MODULE_NAME = com.Voodoo.driver.VoodooSDHC;
MODULE_VERSION = 1.1d1;
PRODUCT_NAME = VoodooSDHC;
WRAPPER_EXTENSION = kext;
};
name = Release;
};
1DEB91DE08733DB10010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
GCC_ENABLE_KERNEL_DEVELOPMENT = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = NO;
GCC_WARN_PEDANTIC = NO;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
SDKROOT = macosx10.6;
VALID_ARCHS = "i386 x86_64";
};
name = Debug;
};
1DEB91DF08733DB10010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
SDKROOT = macosx10.6;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1DEB91D908733DB10010E9CD /* Build configuration list for PBXNativeTarget "VoodooSDHC" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB91DA08733DB10010E9CD /* Debug */,
1DEB91DB08733DB10010E9CD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
1DEB91DD08733DB10010E9CD /* Build configuration list for PBXProject "VoodooSDHC" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB91DE08733DB10010E9CD /* Debug */,
1DEB91DF08733DB10010E9CD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 089C1669FE841209C02AAC07 /* Project object */;
}
trunk/VoodooSDHC.xcodeproj/james.mode1v3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>ActivePerspectiveName</key>
<string>Project</string>
<key>AllowedModules</key>
<array>
<dict>
<key>BundleLoadPath</key>
<string></string>
<key>MaxInstances</key>
<string>n</string>
<key>Module</key>
<string>PBXSmartGroupTreeModule</string>
<key>Name</key>
<string>Groups and Files Outline View</string>
</dict>
<dict>
<key>BundleLoadPath</key>
<string></string>
<key>MaxInstances</key>
<string>n</string>
<key>Module</key>
<string>PBXNavigatorGroup</string>
<key>Name</key>
<string>Editor</string>
</dict>
<dict>
<key>BundleLoadPath</key>
<string></string>
<key>MaxInstances</key>
<string>n</string>
<key>Module</key>
<string>XCTaskListModule</string>
<key>Name</key>
<string>Task List</string>
</dict>
<dict>
<key>BundleLoadPath</key>
<string></string>
<key>MaxInstances</key>
<string>n</string>
<key>Module</key>
<string>XCDetailModule</string>
<key>Name</key>
<string>File and Smart Group Detail Viewer</string>
</dict>
<dict>
<key>BundleLoadPath</key>
<string></string>
<key>MaxInstances</key>
<string>1</string>
<key>Module</key>
<string>PBXBuildResultsModule</string>
<key>Name</key>
<string>Detailed Build Results Viewer</string>
</dict>
<dict>
<key>BundleLoadPath</key>
<string></string>
<key>MaxInstances</key>
<string>1</string>
<key>Module</key>
<string>PBXProjectFindModule</string>
<key>Name</key>
<string>Project Batch Find Tool</string>
</dict>
<dict>
<key>BundleLoadPath</key>
<string></string>
<key>MaxInstances</key>
<string>n</string>
<key>Module</key>
<string>XCProjectFormatConflictsModule</string>
<key>Name</key>
<string>Project Format Conflicts List</string>
</dict>
<dict>
<key>BundleLoadPath</key>
<string></string>
<key>MaxInstances</key>
<string>n</string>
<key>Module</key>
<string>PBXBookmarksModule</string>
<key>Name</key>
<string>Bookmarks Tool</string>
</dict>
<dict>
<key>BundleLoadPath</key>
<string></string>
<key>MaxInstances</key>
<string>n</string>
<key>Module</key>
<string>PBXClassBrowserModule</string>
<key>Name</key>
<string>Class Browser</string>
</dict>
<dict>
<key>BundleLoadPath</key>
<string></string>
<key>MaxInstances</key>
<string>n</string>
<key>Module</key>
<string>PBXCVSModule</string>
<key>Name</key>
<string>Source Code Control Tool</string>
</dict>
<dict>
<key>BundleLoadPath</key>
<string></string>
<key>MaxInstances</key>
<string>n</string>
<key>Module</key>
<string>PBXDebugBreakpointsModule</string>
<key>Name</key>
<string>Debug Breakpoints Tool</string>
</dict>
<dict>
<key>BundleLoadPath</key>
<string></string>
<key>MaxInstances</key>
<string>n</string>
<key>Module</key>
<string>XCDockableInspector</string>
<key>Name</key>
<string>Inspector</string>
</dict>
<dict>
<key>BundleLoadPath</key>
<string></string>
<key>MaxInstances</key>
<string>n</string>
<key>Module</key>
<string>PBXOpenQuicklyModule</string>
<key>Name</key>
<string>Open Quickly Tool</string>
</dict>
<dict>
<key>BundleLoadPath</key>
<string></string>
<key>MaxInstances</key>
<string>1</string>
<key>Module</key>
<string>PBXDebugSessionModule</string>
<key>Name</key>
<string>Debugger</string>
</dict>
<dict>
<key>BundleLoadPath</key>
<string></string>
<key>MaxInstances</key>
<string>1</string>
<key>Module</key>
<string>PBXDebugCLIModule</string>
<key>Name</key>
<string>Debug Console</string>
</dict>
<dict>
<key>BundleLoadPath</key>
<string></string>
<key>MaxInstances</key>
<string>n</string>
<key>Module</key>
<string>XCSnapshotModule</string>
<key>Name</key>
<string>Snapshots Tool</string>
</dict>
</array>
<key>BundlePath</key>
<string>/Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources</string>
<key>Description</key>
<string>DefaultDescriptionKey</string>
<key>DockingSystemVisible</key>
<false/>
<key>Extension</key>
<string>mode1v3</string>
<key>FavBarConfig</key>
<dict>
<key>PBXProjectModuleGUID</key>
<string>1A0E1DC411F218B700391780</string>
<key>XCBarModuleItemNames</key>
<dict/>
<key>XCBarModuleItems</key>
<array/>
</dict>
<key>FirstTimeWindowDisplayed</key>
<false/>
<key>Identifier</key>
<string>com.apple.perspectives.project.mode1v3</string>
<key>MajorVersion</key>
<integer>33</integer>
<key>MinorVersion</key>
<integer>0</integer>
<key>Name</key>
<string>Default</string>
<key>Notifications</key>
<array/>
<key>OpenEditors</key>
<array/>
<key>PerspectiveWidths</key>
<array>
<integer>-1</integer>
<integer>-1</integer>
</array>
<key>Perspectives</key>
<array>
<dict>
<key>ChosenToolbarItems</key>
<array>
<string>active-combo-popup</string>
<string>action</string>
<string>NSToolbarFlexibleSpaceItem</string>
<string>debugger-enable-breakpoints</string>
<string>build-and-go</string>
<string>com.apple.ide.PBXToolbarStopButton</string>
<string>get-info</string>
<string>NSToolbarFlexibleSpaceItem</string>
<string>com.apple.pbx.toolbar.searchfield</string>
</array>
<key>ControllerClassBaseName</key>
<string></string>
<key>IconName</key>
<string>WindowOfProjectWithEditor</string>
<key>Identifier</key>
<string>perspective.project</string>
<key>IsVertical</key>
<false/>
<key>Layout</key>
<array>
<dict>
<key>ContentConfiguration</key>
<dict>
<key>PBXBottomSmartGroupGIDs</key>
<array>
<string>1C37FBAC04509CD000000102</string>
<string>1C37FAAC04509CD000000102</string>
<string>1C37FABC05509CD000000102</string>
<string>1C37FABC05539CD112110102</string>
<string>E2644B35053B69B200211256</string>
<string>1C37FABC04509CD000100104</string>
<string>1CC0EA4004350EF90044410B</string>
<string>1CC0EA4004350EF90041110B</string>
</array>
<key>PBXProjectModuleGUID</key>
<string>1CE0B1FE06471DED0097A5F4</string>
<key>PBXProjectModuleLabel</key>
<string>Files</string>
<key>PBXProjectStructureProvided</key>
<string>yes</string>
<key>PBXSmartGroupTreeModuleColumnData</key>
<dict>
<key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
<array>
<real>186</real>
</array>
<key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
<array>
<string>MainColumn</string>
</array>
</dict>
<key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
<dict>
<key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
<array>
<string>089C166AFE841209C02AAC07</string>
<string>1C37FABC05509CD000000102</string>
</array>
<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
<array>
<array>
<integer>0</integer>
</array>
</array>
<key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
<string>{{0, 0}, {186, 445}}</string>
</dict>
<key>PBXTopSmartGroupGIDs</key>
<array/>
<key>XCIncludePerspectivesSwitch</key>
<true/>
<key>XCSharingToken</key>
<string>com.apple.Xcode.GFSharingToken</string>
</dict>
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{0, 0}, {203, 463}}</string>
<key>GroupTreeTableConfiguration</key>
<array>
<string>MainColumn</string>
<real>186</real>
</array>
<key>RubberWindowFrame</key>
<string>246 220 788 504 0 0 1280 778 </string>
</dict>
<key>Module</key>
<string>PBXSmartGroupTreeModule</string>
<key>Proportion</key>
<string>203pt</string>
</dict>
<dict>
<key>Dock</key>
<array>
<dict>
<key>ContentConfiguration</key>
<dict>
<key>PBXProjectModuleGUID</key>
<string>1CE0B20306471E060097A5F4</string>
<key>PBXProjectModuleLabel</key>
<string>MyNewFile14.java</string>
<key>PBXSplitModuleInNavigatorKey</key>
<dict>
<key>Split0</key>
<dict>
<key>PBXProjectModuleGUID</key>
<string>1CE0B20406471E060097A5F4</string>
<key>PBXProjectModuleLabel</key>
<string>MyNewFile14.java</string>
</dict>
<key>SplitCount</key>
<string>1</string>
</dict>
<key>StatusBarVisibility</key>
<true/>
</dict>
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{0, 0}, {580, 0}}</string>
<key>RubberWindowFrame</key>
<string>246 220 788 504 0 0 1280 778 </string>
</dict>
<key>Module</key>
<string>PBXNavigatorGroup</string>
<key>Proportion</key>
<string>0pt</string>
</dict>
<dict>
<key>BecomeActive</key>
<true/>
<key>ContentConfiguration</key>
<dict>
<key>PBXProjectModuleGUID</key>
<string>1CE0B20506471E060097A5F4</string>
<key>PBXProjectModuleLabel</key>
<string>Detail</string>
</dict>
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{0, 5}, {580, 458}}</string>
<key>RubberWindowFrame</key>
<string>246 220 788 504 0 0 1280 778 </string>
</dict>
<key>Module</key>
<string>XCDetailModule</string>
<key>Proportion</key>
<string>458pt</string>
</dict>
</array>
<key>Proportion</key>
<string>580pt</string>
</dict>
</array>
<key>Name</key>
<string>Project</string>
<key>ServiceClasses</key>
<array>
<string>XCModuleDock</string>
<string>PBXSmartGroupTreeModule</string>
<string>XCModuleDock</string>
<string>PBXNavigatorGroup</string>
<string>XCDetailModule</string>
</array>
<key>TableOfContents</key>
<array>
<string>1A0F559C11F219F0005C4680</string>
<string>1CE0B1FE06471DED0097A5F4</string>
<string>1A0F559D11F219F0005C4680</string>
<string>1CE0B20306471E060097A5F4</string>
<string>1CE0B20506471E060097A5F4</string>
</array>
<key>ToolbarConfigUserDefaultsMinorVersion</key>
<string>2</string>
<key>ToolbarConfiguration</key>
<string>xcode.toolbar.config.defaultV3</string>
</dict>
<dict>
<key>ControllerClassBaseName</key>
<string></string>
<key>IconName</key>
<string>WindowOfProject</string>
<key>Identifier</key>
<string>perspective.morph</string>
<key>IsVertical</key>
<integer>0</integer>
<key>Layout</key>
<array>
<dict>
<key>BecomeActive</key>
<integer>1</integer>
<key>ContentConfiguration</key>
<dict>
<key>PBXBottomSmartGroupGIDs</key>
<array>
<string>1C37FBAC04509CD000000102</string>
<string>1C37FAAC04509CD000000102</string>
<string>1C08E77C0454961000C914BD</string>
<string>1C37FABC05509CD000000102</string>
<string>1C37FABC05539CD112110102</string>
<string>E2644B35053B69B200211256</string>
<string>1C37FABC04509CD000100104</string>
<string>1CC0EA4004350EF90044410B</string>
<string>1CC0EA4004350EF90041110B</string>
</array>
<key>PBXProjectModuleGUID</key>
<string>11E0B1FE06471DED0097A5F4</string>
<key>PBXProjectModuleLabel</key>
<string>Files</string>
<key>PBXProjectStructureProvided</key>
<string>yes</string>
<key>PBXSmartGroupTreeModuleColumnData</key>
<dict>
<key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
<array>
<real>186</real>
</array>
<key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
<array>
<string>MainColumn</string>
</array>
</dict>
<key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
<dict>
<key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
<array>
<string>29B97314FDCFA39411CA2CEA</string>
<string>1C37FABC05509CD000000102</string>
</array>
<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
<array>
<array>
<integer>0</integer>
</array>
</array>
<key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
<string>{{0, 0}, {186, 337}}</string>
</dict>
<key>PBXTopSmartGroupGIDs</key>
<array/>
<key>XCIncludePerspectivesSwitch</key>
<integer>1</integer>
<key>XCSharingToken</key>
<string>com.apple.Xcode.GFSharingToken</string>
</dict>
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{0, 0}, {203, 355}}</string>
<key>GroupTreeTableConfiguration</key>
<array>
<string>MainColumn</string>
<real>186</real>
</array>
<key>RubberWindowFrame</key>
<string>373 269 690 397 0 0 1440 878 </string>
</dict>
<key>Module</key>
<string>PBXSmartGroupTreeModule</string>
<key>Proportion</key>
<string>100%</string>
</dict>
</array>
<key>Name</key>
<string>Morph</string>
<key>PreferredWidth</key>
<integer>300</integer>
<key>ServiceClasses</key>
<array>
<string>XCModuleDock</string>
<string>PBXSmartGroupTreeModule</string>
</array>
<key>TableOfContents</key>
<array>
<string>11E0B1FE06471DED0097A5F4</string>
</array>
<key>ToolbarConfiguration</key>
<string>xcode.toolbar.config.default.shortV3</string>
</dict>
</array>
<key>PerspectivesBarVisible</key>
<false/>
<key>ShelfIsVisible</key>
<false/>
<key>SourceDescription</key>
<string>file at '/Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources/XCPerspectivesSpecificationMode1.xcperspec'</string>
<key>StatusbarIsVisible</key>
<true/>
<key>TimeStamp</key>
<real>0.0</real>
<key>ToolbarConfigUserDefaultsMinorVersion</key>
<string>2</string>
<key>ToolbarDisplayMode</key>
<integer>1</integer>
<key>ToolbarIsVisible</key>
<true/>
<key>ToolbarSizeMode</key>
<integer>1</integer>
<key>Type</key>
<string>Perspectives</string>
<key>UpdateMessage</key>
<string>The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'?</string>
<key>WindowJustification</key>
<integer>5</integer>
<key>WindowOrderList</key>
<array>
<string>1A0E1DC011F218B700391780</string>
<string>/Users/james/Desktop/voodoosdhci/trunk/VoodooSDHC.xcodeproj</string>
</array>
<key>WindowString</key>
<string>246 220 788 504 0 0 1280 778 </string>
<key>WindowToolsV3</key>
<array>
<dict>
<key>FirstTimeWindowDisplayed</key>
<false/>
<key>Identifier</key>
<string>windowTool.build</string>
<key>IsVertical</key>
<true/>
<key>Layout</key>
<array>
<dict>
<key>Dock</key>
<array>
<dict>
<key>ContentConfiguration</key>
<dict>
<key>PBXProjectModuleGUID</key>
<string>1CD0528F0623707200166675</string>
<key>PBXProjectModuleLabel</key>
<string></string>
<key>StatusBarVisibility</key>
<true/>
</dict>
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{0, 0}, {500, 218}}</string>
<key>RubberWindowFrame</key>
<string>267 201 500 500 0 0 1280 778 </string>
</dict>
<key>Module</key>
<string>PBXNavigatorGroup</string>
<key>Proportion</key>
<string>218pt</string>
</dict>
<dict>
<key>ContentConfiguration</key>
<dict>
<key>PBXProjectModuleGUID</key>
<string>XCMainBuildResultsModuleGUID</string>
<key>PBXProjectModuleLabel</key>
<string>Build Results</string>
<key>XCBuildResultsTrigger_Collapse</key>
<integer>1021</integer>
<key>XCBuildResultsTrigger_Open</key>
<integer>1011</integer>
</dict>
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{0, 223}, {500, 236}}</string>
<key>RubberWindowFrame</key>
<string>267 201 500 500 0 0 1280 778 </string>
</dict>
<key>Module</key>
<string>PBXBuildResultsModule</string>
<key>Proportion</key>
<string>236pt</string>
</dict>
</array>
<key>Proportion</key>
<string>459pt</string>
</dict>
</array>
<key>Name</key>
<string>Build Results</string>
<key>ServiceClasses</key>
<array>
<string>PBXBuildResultsModule</string>
</array>
<key>StatusbarIsVisible</key>
<true/>
<key>TableOfContents</key>
<array>
<string>1A0E1DC011F218B700391780</string>
<string>1A0F559E11F219F0005C4680</string>
<string>1CD0528F0623707200166675</string>
<string>XCMainBuildResultsModuleGUID</string>
</array>
<key>ToolbarConfiguration</key>
<string>xcode.toolbar.config.buildV3</string>
<key>WindowContentMinSize</key>
<string>486 300</string>
<key>WindowString</key>
<string>267 201 500 500 0 0 1280 778 </string>
<key>WindowToolGUID</key>
<string>1A0E1DC011F218B700391780</string>
<key>WindowToolIsVisible</key>
<false/>
</dict>
<dict>
<key>Identifier</key>
<string>windowTool.debugger</string>
<key>Layout</key>
<array>
<dict>
<key>Dock</key>
<array>
<dict>
<key>ContentConfiguration</key>
<dict>
<key>Debugger</key>
<dict>
<key>HorizontalSplitView</key>
<dict>
<key>_collapsingFrameDimension</key>
<real>0.0</real>
<key>_indexOfCollapsedView</key>
<integer>0</integer>
<key>_percentageOfCollapsedView</key>
<real>0.0</real>
<key>isCollapsed</key>
<string>yes</string>
<key>sizes</key>
<array>
<string>{{0, 0}, {317, 164}}</string>
<string>{{317, 0}, {377, 164}}</string>
</array>
</dict>
<key>VerticalSplitView</key>
<dict>
<key>_collapsingFrameDimension</key>
<real>0.0</real>
<key>_indexOfCollapsedView</key>
<integer>0</integer>
<key>_percentageOfCollapsedView</key>
<real>0.0</real>
<key>isCollapsed</key>
<string>yes</string>
<key>sizes</key>
<array>
<string>{{0, 0}, {694, 164}}</string>
<string>{{0, 164}, {694, 216}}</string>
</array>
</dict>
</dict>
<key>LauncherConfigVersion</key>
<string>8</string>
<key>PBXProjectModuleGUID</key>
<string>1C162984064C10D400B95A72</string>
<key>PBXProjectModuleLabel</key>
<string>Debug - GLUTExamples (Underwater)</string>
</dict>
<key>GeometryConfiguration</key>
<dict>
<key>DebugConsoleDrawerSize</key>
<string>{100, 120}</string>
<key>DebugConsoleVisible</key>
<string>None</string>
<key>DebugConsoleWindowFrame</key>
<string>{{200, 200}, {500, 300}}</string>
<key>DebugSTDIOWindowFrame</key>
<string>{{200, 200}, {500, 300}}</string>
<key>Frame</key>
<string>{{0, 0}, {694, 380}}</string>
<key>RubberWindowFrame</key>
<string>321 238 694 422 0 0 1440 878 </string>
</dict>
<key>Module</key>
<string>PBXDebugSessionModule</string>
<key>Proportion</key>
<string>100%</string>
</dict>
</array>
<key>Proportion</key>
<string>100%</string>
</dict>
</array>
<key>Name</key>
<string>Debugger</string>
<key>ServiceClasses</key>
<array>
<string>PBXDebugSessionModule</string>
</array>
<key>StatusbarIsVisible</key>
<integer>1</integer>
<key>TableOfContents</key>
<array>
<string>1CD10A99069EF8BA00B06720</string>
<string>1C0AD2AB069F1E9B00FABCE6</string>
<string>1C162984064C10D400B95A72</string>
<string>1C0AD2AC069F1E9B00FABCE6</string>
</array>
<key>ToolbarConfiguration</key>
<string>xcode.toolbar.config.debugV3</string>
<key>WindowString</key>
<string>321 238 694 422 0 0 1440 878 </string>
<key>WindowToolGUID</key>
<string>1CD10A99069EF8BA00B06720</string>
<key>WindowToolIsVisible</key>
<integer>0</integer>
</dict>
<dict>
<key>Identifier</key>
<string>windowTool.find</string>
<key>Layout</key>
<array>
<dict>
<key>Dock</key>
<array>
<dict>
<key>Dock</key>
<array>
<dict>
<key>ContentConfiguration</key>
<dict>
<key>PBXProjectModuleGUID</key>
<string>1CDD528C0622207200134675</string>
<key>PBXProjectModuleLabel</key>
<string>&lt;No Editor&gt;</string>
<key>PBXSplitModuleInNavigatorKey</key>
<dict>
<key>Split0</key>
<dict>
<key>PBXProjectModuleGUID</key>
<string>1CD0528D0623707200166675</string>
</dict>
<key>SplitCount</key>
<string>1</string>
</dict>
<key>StatusBarVisibility</key>
<integer>1</integer>
</dict>
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{0, 0}, {781, 167}}</string>
<key>RubberWindowFrame</key>
<string>62 385 781 470 0 0 1440 878 </string>
</dict>
<key>Module</key>
<string>PBXNavigatorGroup</string>
<key>Proportion</key>
<string>781pt</string>
</dict>
</array>
<key>Proportion</key>
<string>50%</string>
</dict>
<dict>
<key>BecomeActive</key>
<integer>1</integer>
<key>ContentConfiguration</key>
<dict>
<key>PBXProjectModuleGUID</key>
<string>1CD0528E0623707200166675</string>
<key>PBXProjectModuleLabel</key>
<string>Project Find</string>
</dict>
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{8, 0}, {773, 254}}</string>
<key>RubberWindowFrame</key>
<string>62 385 781 470 0 0 1440 878 </string>
</dict>
<key>Module</key>
<string>PBXProjectFindModule</string>
<key>Proportion</key>
<string>50%</string>
</dict>
</array>
<key>Proportion</key>
<string>428pt</string>
</dict>
</array>
<key>Name</key>
<string>Project Find</string>
<key>ServiceClasses</key>
<array>
<string>PBXProjectFindModule</string>
</array>
<key>StatusbarIsVisible</key>
<integer>1</integer>
<key>TableOfContents</key>
<array>
<string>1C530D57069F1CE1000CFCEE</string>
<string>1C530D58069F1CE1000CFCEE</string>
<string>1C530D59069F1CE1000CFCEE</string>
<string>1CDD528C0622207200134675</string>
<string>1C530D5A069F1CE1000CFCEE</string>
<string>1CE0B1FE06471DED0097A5F4</string>
<string>1CD0528E0623707200166675</string>
</array>
<key>WindowString</key>
<string>62 385 781 470 0 0 1440 878 </string>
<key>WindowToolGUID</key>
<string>1C530D57069F1CE1000CFCEE</string>
<key>WindowToolIsVisible</key>
<integer>0</integer>
</dict>
<dict>
<key>Identifier</key>
<string>MENUSEPARATOR</string>
</dict>
<dict>
<key>Identifier</key>
<string>windowTool.debuggerConsole</string>
<key>Layout</key>
<array>
<dict>
<key>Dock</key>
<array>
<dict>
<key>BecomeActive</key>
<integer>1</integer>
<key>ContentConfiguration</key>
<dict>
<key>PBXProjectModuleGUID</key>
<string>1C78EAAC065D492600B07095</string>
<key>PBXProjectModuleLabel</key>
<string>Debugger Console</string>
</dict>
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{0, 0}, {650, 250}}</string>
<key>RubberWindowFrame</key>
<string>516 632 650 250 0 0 1680 1027 </string>
</dict>
<key>Module</key>
<string>PBXDebugCLIModule</string>
<key>Proportion</key>
<string>209pt</string>
</dict>
</array>
<key>Proportion</key>
<string>209pt</string>
</dict>
</array>
<key>Name</key>
<string>Debugger Console</string>
<key>ServiceClasses</key>
<array>
<string>PBXDebugCLIModule</string>
</array>
<key>StatusbarIsVisible</key>
<integer>1</integer>
<key>TableOfContents</key>
<array>
<string>1C78EAAD065D492600B07095</string>
<string>1C78EAAE065D492600B07095</string>
<string>1C78EAAC065D492600B07095</string>
</array>
<key>ToolbarConfiguration</key>
<string>xcode.toolbar.config.consoleV3</string>
<key>WindowString</key>
<string>650 41 650 250 0 0 1280 1002 </string>
<key>WindowToolGUID</key>
<string>1C78EAAD065D492600B07095</string>
<key>WindowToolIsVisible</key>
<integer>0</integer>
</dict>
<dict>
<key>Identifier</key>
<string>windowTool.snapshots</string>
<key>Layout</key>
<array>
<dict>
<key>Dock</key>
<array>
<dict>
<key>Module</key>
<string>XCSnapshotModule</string>
<key>Proportion</key>
<string>100%</string>
</dict>
</array>
<key>Proportion</key>
<string>100%</string>
</dict>
</array>
<key>Name</key>
<string>Snapshots</string>
<key>ServiceClasses</key>
<array>
<string>XCSnapshotModule</string>
</array>
<key>StatusbarIsVisible</key>
<string>Yes</string>
<key>ToolbarConfiguration</key>
<string>xcode.toolbar.config.snapshots</string>
<key>WindowString</key>
<string>315 824 300 550 0 0 1440 878 </string>
<key>WindowToolIsVisible</key>
<string>Yes</string>
</dict>
<dict>
<key>Identifier</key>
<string>windowTool.scm</string>
<key>Layout</key>
<array>
<dict>
<key>Dock</key>
<array>
<dict>
<key>ContentConfiguration</key>
<dict>
<key>PBXProjectModuleGUID</key>
<string>1C78EAB2065D492600B07095</string>
<key>PBXProjectModuleLabel</key>
<string>&lt;No Editor&gt;</string>
<key>PBXSplitModuleInNavigatorKey</key>
<dict>
<key>Split0</key>
<dict>
<key>PBXProjectModuleGUID</key>
<string>1C78EAB3065D492600B07095</string>
</dict>
<key>SplitCount</key>
<string>1</string>
</dict>
<key>StatusBarVisibility</key>
<integer>1</integer>
</dict>
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{0, 0}, {452, 0}}</string>
<key>RubberWindowFrame</key>
<string>743 379 452 308 0 0 1280 1002 </string>
</dict>
<key>Module</key>
<string>PBXNavigatorGroup</string>
<key>Proportion</key>
<string>0pt</string>
</dict>
<dict>
<key>BecomeActive</key>
<integer>1</integer>
<key>ContentConfiguration</key>
<dict>
<key>PBXProjectModuleGUID</key>
<string>1CD052920623707200166675</string>
<key>PBXProjectModuleLabel</key>
<string>SCM</string>
</dict>
<key>GeometryConfiguration</key>
<dict>
<key>ConsoleFrame</key>
<string>{{0, 259}, {452, 0}}</string>
<key>Frame</key>
<string>{{0, 7}, {452, 259}}</string>
<key>RubberWindowFrame</key>
<string>743 379 452 308 0 0 1280 1002 </string>
<key>TableConfiguration</key>
<array>
<string>Status</string>
<real>30</real>
<string>FileName</string>
<real>199</real>
<string>Path</string>
<real>197.0950012207031</real>
</array>
<key>TableFrame</key>
<string>{{0, 0}, {452, 250}}</string>
</dict>
<key>Module</key>
<string>PBXCVSModule</string>
<key>Proportion</key>
<string>262pt</string>
</dict>
</array>
<key>Proportion</key>
<string>266pt</string>
</dict>
</array>
<key>Name</key>
<string>SCM</string>
<key>ServiceClasses</key>
<array>
<string>PBXCVSModule</string>
</array>
<key>StatusbarIsVisible</key>
<integer>1</integer>
<key>TableOfContents</key>
<array>
<string>1C78EAB4065D492600B07095</string>
<string>1C78EAB5065D492600B07095</string>
<string>1C78EAB2065D492600B07095</string>
<string>1CD052920623707200166675</string>
</array>
<key>ToolbarConfiguration</key>
<string>xcode.toolbar.config.scm</string>
<key>WindowString</key>
<string>743 379 452 308 0 0 1280 1002 </string>
</dict>
<dict>
<key>Identifier</key>
<string>windowTool.breakpoints</string>
<key>IsVertical</key>
<integer>0</integer>
<key>Layout</key>
<array>
<dict>
<key>Dock</key>
<array>
<dict>
<key>BecomeActive</key>
<integer>1</integer>
<key>ContentConfiguration</key>
<dict>
<key>PBXBottomSmartGroupGIDs</key>
<array>
<string>1C77FABC04509CD000000102</string>
</array>
<key>PBXProjectModuleGUID</key>
<string>1CE0B1FE06471DED0097A5F4</string>
<key>PBXProjectModuleLabel</key>
<string>Files</string>
<key>PBXProjectStructureProvided</key>
<string>no</string>
<key>PBXSmartGroupTreeModuleColumnData</key>
<dict>
<key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
<array>
<real>168</real>
</array>
<key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
<array>
<string>MainColumn</string>
</array>
</dict>
<key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
<dict>
<key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
<array>
<string>1C77FABC04509CD000000102</string>
</array>
<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
<array>
<array>
<integer>0</integer>
</array>
</array>
<key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
<string>{{0, 0}, {168, 350}}</string>
</dict>
<key>PBXTopSmartGroupGIDs</key>
<array/>
<key>XCIncludePerspectivesSwitch</key>
<integer>0</integer>
</dict>
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{0, 0}, {185, 368}}</string>
<key>GroupTreeTableConfiguration</key>
<array>
<string>MainColumn</string>
<real>168</real>
</array>
<key>RubberWindowFrame</key>
<string>315 424 744 409 0 0 1440 878 </string>
</dict>
<key>Module</key>
<string>PBXSmartGroupTreeModule</string>
<key>Proportion</key>
<string>185pt</string>
</dict>
<dict>
<key>ContentConfiguration</key>
<dict>
<key>PBXProjectModuleGUID</key>
<string>1CA1AED706398EBD00589147</string>
<key>PBXProjectModuleLabel</key>
<string>Detail</string>
</dict>
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{190, 0}, {554, 368}}</string>
<key>RubberWindowFrame</key>
<string>315 424 744 409 0 0 1440 878 </string>
</dict>
<key>Module</key>
<string>XCDetailModule</string>
<key>Proportion</key>
<string>554pt</string>
</dict>
</array>
<key>Proportion</key>
<string>368pt</string>
</dict>
</array>
<key>MajorVersion</key>
<integer>3</integer>
<key>MinorVersion</key>
<integer>0</integer>
<key>Name</key>
<string>Breakpoints</string>
<key>ServiceClasses</key>
<array>
<string>PBXSmartGroupTreeModule</string>
<string>XCDetailModule</string>
</array>
<key>StatusbarIsVisible</key>
<integer>1</integer>
<key>TableOfContents</key>
<array>
<string>1CDDB66807F98D9800BB5817</string>
<string>1CDDB66907F98D9800BB5817</string>
<string>1CE0B1FE06471DED0097A5F4</string>
<string>1CA1AED706398EBD00589147</string>
</array>
<key>ToolbarConfiguration</key>
<string>xcode.toolbar.config.breakpointsV3</string>
<key>WindowString</key>
<string>315 424 744 409 0 0 1440 878 </string>
<key>WindowToolGUID</key>
<string>1CDDB66807F98D9800BB5817</string>
<key>WindowToolIsVisible</key>
<integer>1</integer>
</dict>
<dict>
<key>Identifier</key>
<string>windowTool.debugAnimator</string>
<key>Layout</key>
<array>
<dict>
<key>Dock</key>
<array>
<dict>
<key>Module</key>
<string>PBXNavigatorGroup</string>
<key>Proportion</key>
<string>100%</string>
</dict>
</array>
<key>Proportion</key>
<string>100%</string>
</dict>
</array>
<key>Name</key>
<string>Debug Visualizer</string>
<key>ServiceClasses</key>
<array>
<string>PBXNavigatorGroup</string>
</array>
<key>StatusbarIsVisible</key>
<integer>1</integer>
<key>ToolbarConfiguration</key>
<string>xcode.toolbar.config.debugAnimatorV3</string>
<key>WindowString</key>
<string>100 100 700 500 0 0 1280 1002 </string>
</dict>
<dict>
<key>Identifier</key>
<string>windowTool.bookmarks</string>
<key>Layout</key>
<array>
<dict>
<key>Dock</key>
<array>
<dict>
<key>Module</key>
<string>PBXBookmarksModule</string>
<key>Proportion</key>
<string>100%</string>
</dict>
</array>
<key>Proportion</key>
<string>100%</string>
</dict>
</array>
<key>Name</key>
<string>Bookmarks</string>
<key>ServiceClasses</key>
<array>
<string>PBXBookmarksModule</string>
</array>
<key>StatusbarIsVisible</key>
<integer>0</integer>
<key>WindowString</key>
<string>538 42 401 187 0 0 1280 1002 </string>
</dict>
<dict>
<key>Identifier</key>
<string>windowTool.projectFormatConflicts</string>
<key>Layout</key>
<array>
<dict>
<key>Dock</key>
<array>
<dict>
<key>Module</key>
<string>XCProjectFormatConflictsModule</string>
<key>Proportion</key>
<string>100%</string>
</dict>
</array>
<key>Proportion</key>
<string>100%</string>
</dict>
</array>
<key>Name</key>
<string>Project Format Conflicts</string>
<key>ServiceClasses</key>
<array>
<string>XCProjectFormatConflictsModule</string>
</array>
<key>StatusbarIsVisible</key>
<integer>0</integer>
<key>WindowContentMinSize</key>
<string>450 300</string>
<key>WindowString</key>
<string>50 850 472 307 0 0 1440 877</string>
</dict>
<dict>
<key>Identifier</key>
<string>windowTool.classBrowser</string>
<key>Layout</key>
<array>
<dict>
<key>Dock</key>
<array>
<dict>
<key>BecomeActive</key>
<integer>1</integer>
<key>ContentConfiguration</key>
<dict>
<key>OptionsSetName</key>
<string>Hierarchy, all classes</string>
<key>PBXProjectModuleGUID</key>
<string>1CA6456E063B45B4001379D8</string>
<key>PBXProjectModuleLabel</key>
<string>Class Browser - NSObject</string>
</dict>
<key>GeometryConfiguration</key>
<dict>
<key>ClassesFrame</key>
<string>{{0, 0}, {374, 96}}</string>
<key>ClassesTreeTableConfiguration</key>
<array>
<string>PBXClassNameColumnIdentifier</string>
<real>208</real>
<string>PBXClassBookColumnIdentifier</string>
<real>22</real>
</array>
<key>Frame</key>
<string>{{0, 0}, {630, 331}}</string>
<key>MembersFrame</key>
<string>{{0, 105}, {374, 395}}</string>
<key>MembersTreeTableConfiguration</key>
<array>
<string>PBXMemberTypeIconColumnIdentifier</string>
<real>22</real>
<string>PBXMemberNameColumnIdentifier</string>
<real>216</real>
<string>PBXMemberTypeColumnIdentifier</string>
<real>97</real>
<string>PBXMemberBookColumnIdentifier</string>
<real>22</real>
</array>
<key>PBXModuleWindowStatusBarHidden2</key>
<integer>1</integer>
<key>RubberWindowFrame</key>
<string>385 179 630 352 0 0 1440 878 </string>
</dict>
<key>Module</key>
<string>PBXClassBrowserModule</string>
<key>Proportion</key>
<string>332pt</string>
</dict>
</array>
<key>Proportion</key>
<string>332pt</string>
</dict>
</array>
<key>Name</key>
<string>Class Browser</string>
<key>ServiceClasses</key>
<array>
<string>PBXClassBrowserModule</string>
</array>
<key>StatusbarIsVisible</key>
<integer>0</integer>
<key>TableOfContents</key>
<array>
<string>1C0AD2AF069F1E9B00FABCE6</string>
<string>1C0AD2B0069F1E9B00FABCE6</string>
<string>1CA6456E063B45B4001379D8</string>
</array>
<key>ToolbarConfiguration</key>
<string>xcode.toolbar.config.classbrowser</string>
<key>WindowString</key>
<string>385 179 630 352 0 0 1440 878 </string>
<key>WindowToolGUID</key>
<string>1C0AD2AF069F1E9B00FABCE6</string>
<key>WindowToolIsVisible</key>
<integer>0</integer>
</dict>
<dict>
<key>Identifier</key>
<string>windowTool.refactoring</string>
<key>IncludeInToolsMenu</key>
<integer>0</integer>
<key>Layout</key>
<array>
<dict>
<key>Dock</key>
<array>
<dict>
<key>BecomeActive</key>
<integer>1</integer>
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{0, 0}, {500, 335}</string>
<key>RubberWindowFrame</key>
<string>{0, 0}, {500, 335}</string>
</dict>
<key>Module</key>
<string>XCRefactoringModule</string>
<key>Proportion</key>
<string>100%</string>
</dict>
</array>
<key>Proportion</key>
<string>100%</string>
</dict>
</array>
<key>Name</key>
<string>Refactoring</string>
<key>ServiceClasses</key>
<array>
<string>XCRefactoringModule</string>
</array>
<key>WindowString</key>
<string>200 200 500 356 0 0 1920 1200 </string>
</dict>
</array>
</dict>
</plist>
trunk/Info.plist
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>VoodooSDHC</string>
<key>CFBundleIconFile</key>
<string>me.jpg</string>
<key>CFBundleIdentifier</key>
<string>VoodooSDHC</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>VoodooSDHC</string>
<key>CFBundlePackageType</key>
<string>KEXT</string>
<key>CFBundleSignature</key>
<string>Voodoo</string>
<key>CFBundleVersion</key>
<string>1.1d1</string>
<key>IOKitPersonalities</key>
<dict>
<key>SD Card Host Controller</key>
<dict>
<key>IOClass</key>
<string>VoodooSDHC</string>
<key>IOPCIMatch</key>
<string>0x08221180</string>
<key>IOProviderClass</key>
<string>IOPCIDevice</string>
</dict>
</dict>
<key>OSBundleLibraries</key>
<dict>
<key>com.apple.iokit.IOPCIFamily</key>
<string>2.6</string>
<key>com.apple.iokit.IOStorageFamily</key>
<string>1.6</string>
<key>com.apple.kpi.iokit</key>
<string>8.0.0</string>
<key>com.apple.kpi.libkern</key>
<string>8.0.0</string>
<key>com.apple.kpi.mach</key>
<string>8.0.0</string>
</dict>
</dict>
</plist>
trunk/SD_Misc.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include "License.h"
#define BIT0 1<<0
#define BIT1 1<<1
#define BIT2 1<<2
#define BIT3 1<<3
#define BIT4 1<<4
#define BIT5 1<<5
#define BIT6 1<<6
#define BIT7 1<<7
#define BIT8 1<<8
#define BIT9 1<<9
#define BIT10 1<<10
#define BIT11 1<<11
#define BIT12 1<<12
#define BIT13 1<<13
#define BIT14 1<<14
#define BIT15 1<<15
#define BIT16 1<<16
#define BIT17 1<<17
#define BIT18 1<<18
#define BIT19 1<<19
#define BIT20 1<<20
#define BIT21 1<<21
#define BIT22 1<<22
#define BIT23 1<<23
#define BIT24 1<<24
#define BIT25 1<<25
#define BIT26 1<<26
#define BIT27 1<<27
#define BIT28 1<<28
#define BIT29 1<<29
#define BIT30 1<<30
#define BIT31 1<<31
trunk/License.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/*
* License.h
* IOSDHCIBlockDevice
*
* Created by james francis toy iv on 4/18/09.
* Copyright 2009 VoodooLabs. All rights reserved.
*
* previously worked on by : Forest Godfrey, type11, Reggie McMurtrey
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*
* Full text of agreement at http://www.gnu.org/licenses/gpl-2.0.txt
****************************************************************************
* Original Linux Code Copyrights
*
* Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved.
* Copyright (C) 2002 Hewlett-Packard Company
*
* Many thanks to Alessandro Rubini and Jonathan Corbet!
* Based strongly on code by:
* Author: Yong-iL Joh <tolkien@mizi.com>
* Author: Andrew Christian 15 May 2002
****************************************************************************
*/
trunk/VoodooSDHC.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
#include "License.h"
/*****************************************************************************/
/* Build Configuration Defines */
/* Debug - mostly turns on more logging */
//#define __DEBUG__1
/*
* Builds the driver to prohibit writes to the card. Useful while building
* confidence in changes without corrupting data.
*/
//#define READONLY_DRIVER1
/*
* Builds the driver with High Speed Card support.
*/
//#define HIGHSPEED_CARD_MODE1
/*
* Builds the driver with 4-bit Bus support.
*/
#define WIDE_BUS_MODE1
/*
* Use multiblock reads/writes. Define to either 0 or 1
*/
#define USE_MULTIBLOCK1
/*
* Use SDMA reads/writes. Define to either 0 or 1
*/
#define USE_SDMA 1
/*
* The Linux driver for this device claimed that the card needs to be reset
* after every command. That doesn't seem to be necessary so we turn on
* NO_RESET_WAR.
*/
#define NO_RESET_WAR1
#define SDMA_BUFFER_SIZE 32768
#define SDMA_BUFFER_SIZE_IN_REG 0x3000 /* see def. of Block Size Register */
#define SDMA_RETRY_COUNT 5
/*****************************************************************************/
//#include <libkern/OSByteOrder.h>
#include "VoodooSDHC.h"
#include "SDHCI_Register_Map.h"
#include "SD_Commands.h"
#include "sdhci.h"
#define MAX(a, b)((a) > (b) ? (a) : (b))
#define MIN(a, b)((a) < (b) ? (a) : (b))
#definesuper IOBlockStorageDevice
OSDefineMetaClassAndStructors ( VoodooSDHC, IOBlockStorageDevice );
/*****************************************************************************/
/* Helper Functions */
/*
* read_block_pio: Read a single 512 byte block of data with no error
* checking from a PIO address to memory.
*volatile UInt32 *reg_addr: Address of card's PIO register
*UInt8 *buf: Buffer in which to place data - m
*/
static inline void read_block_pio(volatile UInt32 *reg_addr, UInt32 *buf) {
UInt32 *bufp = buf;
for (int i = 0; i < 512 / sizeof(UInt32); i++) {
*bufp++ = *reg_addr;
}
}
/*****************************************************************************/
/* Main Driver Code */
/*
* init: Initialize driver. Returns true on success, false on failure
*OSDictionary *properties: Driver properties passed in
*/
bool VoodooSDHC::init ( OSDictionary * properties )
{
IOLog("VoodooSDHCI ::: an SDHCI driver for Ricoh, TI, and JMicron SD Host Controllers ::: rev 20091008\n");
IOLog("VoodooSDHCI: initializing SD host controller\n");
/* Run by our superclass */
if ( super::init ( properties ) == false )
{
return false;
}
#ifdef USE_SDMA
if ((workLoop = IOWorkLoop::workLoop()) == NULL)
return false;
#endif
return true;
}
void VoodooSDHC::free()
{
#ifdef USE_SDMA
if (workLoop != NULL) {
workLoop->release();
workLoop = NULL;
}
#endif
super::free();
}
/*
* start: Starts driver. Called upon insertion of card. Returns true
* on success, false on failure.
*IOService *provider: Provider structure
*/
bool VoodooSDHC::start ( IOService * provider )
{
#ifdef __DEBUG__
IOLog("VoodooSDHCI: running start()\n");
IOLog("VoodooSDHCI: we have found %d SD Host Controllers\n",provider->getDeviceMemoryCount());
#endif
super::start ( provider );
lock.init();
#ifdef USE_SDMA
sdmaCond = IOLockAlloc();
mediaStateLock = IOLockAlloc();
#endif
#ifdef __DEBUG__
IOLog("VoodooSDHCI: starting card power management\n");
#endif
// initialize superclass variables from IOService.h
PMinit();
static const IOPMPowerState powerStates[] = {
{kIOPMPowerStateVersion1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{kIOPMPowerStateVersion1, kIOPMDeviceUsable, IOPMPowerOn, IOPMPowerOn, 0, 0, 0, 0, 0, 0, 0, 0}
};
registerPowerDriver(this, const_cast<IOPMPowerState*>(powerStates),
sizeof(powerStates) / sizeof(powerStates[0]));
// join the tree from IOService.h
provider->joinPMtree(this);
#ifdef USE_SDMA
sdmaBuffDesc = IOBufferMemoryDescriptor::withCapacity(SDMA_BUFFER_SIZE * 2, kIODirectionInOut, true);
physSdmaBuff = sdmaBuffDesc->getPhysicalAddress();
virtSdmaBuff = (char*)sdmaBuffDesc->getBytesNoCopy() + SDMA_BUFFER_SIZE - physSdmaBuff % SDMA_BUFFER_SIZE;
physSdmaBuff += SDMA_BUFFER_SIZE - physSdmaBuff % SDMA_BUFFER_SIZE;
#endif
cardPresence = kCardNotPresent;
if (! setup(provider)) {
return false;
}
#ifdef USE_SDMA
IOWorkLoop *workLoop;
if ((workLoop = getWorkLoop()) == NULL) {
IOLog("VoodooSDHCI: unable to get a workloop; getWorkLoop() == NULL\n");
return false;
}
if ((interruptSrc = IOFilterInterruptEventSource::filterInterruptEventSource(
this, interruptHandler, interruptFilter, provider
)) == NULL) {
IOLog("VoodooSDHCI: failed to create an interrupt source\n");
return false;
}
if (workLoop->addEventSource(interruptSrc) != kIOReturnSuccess) {
IOLog("VoodooSDHCI: failed to add FIES to work loop\n");
return false;
}
if ((timerSrc = IOTimerEventSource::timerEventSource(this, timerHandler)) == NULL) {
IOLog("VoodooSDHCI: failed to create a timer event source\n");
return false;
}
if (workLoop->addEventSource(timerSrc) != kIOReturnSuccess) {
IOLog("VoodooSDHCI: failed ot add TES to work loop\n");
return false;
}
#endif
this->attach(this);
registerService();
#ifdef USE_SDMA
interruptSrc->enable();
timerSrc->enable();
timerSrc->setTimeoutMS(50); // intial timeout is small, to detect card insertion ASAP
#endif
// The controller is now initialized and ready for operation
return true;
}
/*
* setup: Initializes I/O, called upon start and resume, returns true on success.
*IOService *provider: Provider structure
*/
bool VoodooSDHC::setup(IOService * provider)
{
IODeviceMemory *pMem;
UInt8 slot = 0;
for (slot=0; slot<provider->getDeviceMemoryCount(); slot++) {
pMem = provider->getDeviceMemoryWithIndex(0);
this->PCIRegMap = provider->mapDeviceMemoryWithIndex(0);
if (!this->PCIRegMap) {
IOLog("VoodooSDHCI: PCI Register Mapping for Device %d Failed!\n", (int)slot);
return false;
}
this->PCIRegP[slot] =
(SDHCIRegMap_t *)PCIRegMap->getVirtualAddress();
#ifdef __DEBUG__
IOLog("VoodooSDHCI: controller slot == %d\n", slot);
IOLog("VoodooSDHCI: unit memory (pMem) == %d\n", pMem->getLength());
#endif
this->PCIRegP[slot]->PowerControl = 0;
Reset(slot, FULL_RESET);
IODelay(10000);
if (cardPresence == kCardIsPresent && isCardPresent(slot)) {
SDCIDReg_t oldCID = SDCIDReg[slot];
cardInit(slot);
if (memcmp(&oldCID, SDCIDReg + slot, sizeof(oldCID)) != 0) {
IOLog("VoodooSDHCI: oops! we found a different card :: remount?\n");
cardPresence = kCardRemount;
}
}
}
return true;
}
/*
* stop: Called on completion of service, such as ejection of card's
* filesystem.
*IOService *provider: Our provider structure
*/
void VoodooSDHC::stop(IOService *provider)
{
#ifdef __DEBUG__
IOLog("VoodooSDHCI: card is in stop() function\n");
#endif
#ifdef USE_SDMA
if (timerSrc != NULL) {
timerSrc->disable();
timerSrc->cancelTimeout();
getWorkLoop()->removeEventSource(timerSrc);
timerSrc->release();
timerSrc = NULL;
}
if (interruptSrc != NULL) {
interruptSrc->disable();
getWorkLoop()->removeEventSource(interruptSrc);
interruptSrc->release();
interruptSrc = NULL;
}
sdmaBuffDesc->release();
#endif
PMstop();
#ifdef USE_SDMA
IOLockFree(sdmaCond);
IOLockFree(mediaStateLock);
#endif
lock.free();
// Call our superclass
super::stop ( provider );
}
/*
* dumpRegs: Dump selected Host registers. Only used for driver
* debugging.
*UInt8 slot: Which card slot to dump
*/
void VoodooSDHC::dumpRegs(UInt8 slot) {
IOLog("VoodooSDHCI: Register Dump ******************************************************\n");
IOLog("VoodooSDHCI: SDMASysAddr: 0x%08X PresentState: 0x%08X\n",
this->PCIRegP[slot]->SDMASysAddr, this->PCIRegP[slot]->PresentState);
IOLog("VoodooSDHCI: BlockSize: 0x%04X BlockCount: 0x%04X\n",
this->PCIRegP[slot]->BlockSize, this->PCIRegP[slot]->BlockCount);
IOLog("VoodooSDHCI: TransferMode: 0x%04X Command: 0x%04X\n",
this->PCIRegP[slot]->TransferMode, this->PCIRegP[slot]->Command);
IOLog("VoodooSDHCI: HostControl: 0x%02X PowerControl: 0x%02X\n",
this->PCIRegP[slot]->HostControl, this->PCIRegP[slot]->PowerControl);
IOLog("VoodooSDHCI: BlockGapControl: 0x%02X WakeupControl: 0x%02X\n",
this->PCIRegP[slot]->BlockGapControl, this->PCIRegP[slot]->WakeupControl);
IOLog("VoodooSDHCI: ClockControl: 0x%04X TimeoutControl: 0x%02X\n",
this->PCIRegP[slot]->ClockControl, this->PCIRegP[slot]->TimeoutControl);
IOLog("VoodooSDHCI: SoftwareReset: 0x%02X NormalIntStatus: 0x%04X\n",
this->PCIRegP[slot]->SoftwareReset, this->PCIRegP[slot]->NormalIntStatus);
IOLog("VoodooSDHCI: ErrorIntStatus: 0x%04X NormalIntStatusEn: 0x%04X\n",
this->PCIRegP[slot]->ErrorIntStatus, this->PCIRegP[slot]->NormalIntStatusEn);
IOLog("VoodooSDHCI: ErrorIntStatusEn: 0x%04X NormalIntSignalEn: 0x%04X\n",
this->PCIRegP[slot]->ErrorIntStatusEn, this->PCIRegP[slot]->NormalIntSignalEn);
IOLog("VoodooSDHCI: ErrorIntSignalEn: 0x%04X CMD12ErrorStatus: 0x%04X\n",
this->PCIRegP[slot]->ErrorIntSignalEn, this->PCIRegP[slot]->CMD12ErrorStatus);
IOLog("VoodooSDHCI: Capabilities[1]: 0x%08X Capabilities[0]: 0x%08X\n",
this->PCIRegP[slot]->Capabilities[1], this->PCIRegP[slot]->Capabilities[0]);
IOLog("VoodooSDHCI: MaxCurrentCap[1]: 0x%08X MaxCurrentCap[0]: 0x%08X\n",
this->PCIRegP[slot]->MaxCurrentCap[1], this->PCIRegP[slot]->MaxCurrentCap[0]);
IOLog("VoodooSDHCI: ForceEventCMD12ErrStatus: 0x%04X ForceEventErrorIntStatus: 0x%04X\n",
this->PCIRegP[slot]->ForceEventCMD12ErrStatus, this->PCIRegP[slot]->ForceEventErrorIntStatus);
IOLog("VoodooSDHCI: AMDAErrorStatus: 0x%02X Argument 0x%08X\n",
this->PCIRegP[slot]->AMDAErrorStatus, PCIRegP[slot]->Argument);
IOLog("VoodooSDHCI: ADMASystemAddr[1]: 0x%08X ADMASystemAddr[0]: 0x%08lX\n",
this->PCIRegP[slot]->ADMASystemAddr[1], this->PCIRegP[slot]->ADMASystemAddr[0]);
IOLog("VoodooSDHCI: SlotIntStatus: 0x%04X HostControllerVer: 0x%04X\n",
this->PCIRegP[slot]->SlotIntStatus, this->PCIRegP[slot]->HostControllerVer);
IOLog("VoodooSDHCI: Response[1]: 0x%08X Response[0]: 0x%08X\n",
this->PCIRegP[slot]->Response[1], this->PCIRegP[slot]->Response[0]);
IOLog("VoodooSDHCI: Response[3]: 0x%08X Response[2]: 0x%08X\n",
this->PCIRegP[slot]->Response[3], this->PCIRegP[slot]->Response[2]);
IOLog("VoodooSDHCI: End of Register Dump************************************************\n");
}
/*
* cardInit: Initialize a card. Called upon insertion. When complete,
* card should be running at full speed and card data
* populated.
*UInt8 slot: Which slot the card is in.
*/
bool VoodooSDHC::cardInit(UInt8 slot)
{
isHighCapacity = false;
calcClock(slot, 400000);
powerSD(slot);
SDCommand(slot, SD_GO_IDLE_STATE, SDCR0, 0);
IODelay(30000);
SDCommand(slot, SD_SEND_IF_COND, SDCR8, 0x000001AA);
for (int i = 0; i < 100; i++) {
IODelay(10000);
if (!(PCIRegP[slot]->PresentState & ComInhibitCMD)) {
break;
}
}
if(this->PCIRegP[slot]->PresentState & ComInhibitCMD) {
IOLog("VoodooSDHCI: no response from CMD_8 -- ComInhibitCMD\n");
Reset(slot, CMD_RESET);
Reset(slot, DAT_RESET);
SDCommand(slot, SD_GO_IDLE_STATE, SDCR0, 0);
do {
SDCommand(slot, SD_APP_CMD, SDCR55, 0);
SDCommand(slot, SD_APP_OP_COND, SDACR41, 0x00FF8000);
IODelay(1000);
} while (!(this->PCIRegP[slot]->Response[0] & BIT31));
} else {
// check and init SDHC (wait for 2 secs; spec requires 1 sec)
IOLog("VoodooSDHCI: initializing spec 2.0 SD card\n");
for (int i = 0; i < 80; i++) {
#ifdef __DEBUG__
IOLog("VoodooSDHCI: sending CMD_55\n");
#endif //me
SDCommand(slot, SD_APP_CMD, SDCR55, 0);
#ifdef __DEBUG__
IOLog("VoodooSDHCI: sending APP_CMD_41\n");
#endif //me
SDCommand(slot, SD_APP_OP_COND, SDACR41, 0x40FF8000);
IODelay(25000);
if (this->PCIRegP[slot]->Response[0] & BIT31) {
goto OP_COND_COMPLETE;
}
}
#ifdef __DEBUG__
IOLog("VoodooSDHCI: no response to APP_CMD_41: 0x%08x\n", PCIRegP[slot]->Response[0]);
#endif
return false;
OP_COND_COMPLETE:
#ifdef __DEBUG__
IOLog("VoodooSDHCI: got response to APP_CMD_41: 0x%08x\n", PCIRegP[slot]->Response[0]);
#endif
if (this->PCIRegP[slot]->Response[0] & BIT30) {
IOLog("VoodooSDHCI: we have HC card\n");
isHighCapacity = true;
} else {
IOLog("VoodooSDHCI: standard SD (without HC)\n");
}
}
SDCommand(slot, SD_ALL_SEND_CID, SDCR2, 0);
IODelay(1000);
parseCID(slot);
SDCommand(slot, SD_SET_RELATIVE_ADDR, SDCR3, 0);
IODelay(1000);
calcClock(slot, 25000000);
this->RCA = this->PCIRegP[slot]->Response[0] >> 16;
#ifdef __DEBUG__
IOLog("VoodooSDHCI: RCA == 0x%08X\n", this->RCA);
#endif//me
SDCommand(slot, SD_SEND_CSD, SDCR9, this->RCA << 16);
IODelay(2000000);
parseCSD(slot);
#ifdef __DEBUG__
IOLog("VoodooSDHCI: PCIRegP response order (3,2,1,0) :: 0x%08X 0x%08X 0x%08X 0x%08X\n",
this->PCIRegP[slot]->Response[3],
this->PCIRegP[slot]->Response[2],
this->PCIRegP[slot]->Response[1],
this->PCIRegP[slot]->Response[0]);
#endif//me
SDCommand(slot, SD_SELECT_CARD, SDCR7, this->RCA << 16);
IODelay(10000);
#ifdef WIDE_BUS_MODE
/* XXX - Need to check whether the card is capable before enabiling this */
#ifdef __DEBUG__
IOLog("VoodooSDHCI: WIDE_BUS_MODE :: setting 4 bit mode\n");
#endif //me
SDCommand(0, SD_APP_CMD, SDCR55, this->RCA << 16);
SDCommand(slot, SD_APP_SET_BUS_WIDTH, SDCR6, 2);
IODelay(30000);
#ifdef__DEBUG__
IOLog("VoodooSDHCI: PCIRegP response order (3,2,1,0) :: 0x%08X 0x%08X 0x%08X 0x%08X\n",
this->PCIRegP[slot]->Response[3],
this->PCIRegP[slot]->Response[2],
this->PCIRegP[slot]->Response[1],
this->PCIRegP[slot]->Response[0]);
#endif//me
if (!(this->PCIRegP[slot]->Response[0] & 0x480000)) { /* check ERROR and ILLEGAL COMMAND */
this->PCIRegP[slot]->HostControl |= SDHCI_CTRL_4BITBUS;
#ifdef __DEBUG__
IOLog("VoodooSDHCI: properly switched to 4 bit mode\n");
#endif//me
} else {
#ifdef __DEBUG__
IOLog("VoodooSDHCI: unable to switch to 4 bit mode -- calling Reset(slot, {CMD,DAT}_RESET)\n");
#endif//me
Reset(slot, CMD_RESET);
Reset(slot, DAT_RESET);
}
IODelay(30000);
#endif /* WIDE_BUS_MODE */
#ifdef HIGHSPEED_CARD_MODE
/* XXX - Need to check whether the card is capable before enabiling this */
#ifdef __DEBUG__
IOLog("VoodooSDHCI: HIGHSPEED_CARD_MODE \n");
#endif //me
SDCommand(slot, SD_SWITCH, SDCR6, 0x01fffff1);
IODelay(10000);
calcClock(slot, 50000000);
this->PCIRegP[slot]->HostControl |= SDHCI_CTRL_HISPD;
#endif /* HIGHSPEED_CARD_MODE */
this->PCIRegP[slot]->BlockSize = 512;
this->PCIRegP[slot]->BlockCount = 1;
#ifdef __DEBUG__
IOLog("VoodooSDHCI: Card Init: Host Control = 0x%x\n", this->PCIRegP[slot]->HostControl);
#endif
this->PCIRegP[slot]->HostControl |= 0x1;
#ifdef __DEBUG__
IOLog("VoodooSDHCI: Card Init: Host Control = 0x%x\n", this->PCIRegP[slot]->HostControl);
#endif
return true;
}
/*
* isCardPresent: Return true if card is present, false otherwise
*UInt8 slot: Which slot the card is in
*/
bool VoodooSDHC::isCardPresent(UInt8 slot) {
return PCIRegP[slot]->PresentState & CardInserted;
}
/*
* isCardWP: Return true if card is write protected, false otherwise
*UInt8 slot: Which slot the card is in.
*/
bool VoodooSDHC::isCardWP(UInt8 slot) {
#ifndef READONLY_DRIVER
return !(this->PCIRegP[slot]->PresentState & WPSwitchLevel);
#else
return true;
#endif
}
IOReturn VoodooSDHC::setPowerState ( unsigned long state, IOService * provider )
// Note that it is safe to ignore the whatDevice parameter.
{
switch (state) {
case 0: // sleep
#ifdef __DEBUG__
IOLog("VoodooSDHCI: sleep requested by thread: 0x%08x\n", (int)IOThreadSelf());
#endif //me
lock.lock();
break;
case 1: // wakeup
#ifdef __DEBUG__
IOLog("VoodooSDHCI: wakeup requested by thread: 0x%08x\n", (int)IOThreadSelf());
#endif //me
setup(getProvider());
lock.unlock();
break;
}
return kIOPMAckImplied;
}
/*
* LEDControl: Turns on/off LED on card slot. Not present on Dell Mini 9.
*UInt8 slot: Which slot the card is in.
*bool state: True for on, false for off
*/
void VoodooSDHC::LEDControl(UInt8 slot, bool state) {
if (state) {
this->PCIRegP[slot]->HostControl |= LedControl;
} else {
this->PCIRegP[slot]->HostControl &= ~LedControl;
}
}
/*
* Reset: Reset SDHCI host controller. Reset levels are defined by SDHCI
* standard.
*UInt8 slot: Which host controller to reset
*UInt8 type: Reset type (Command, Data, or Full)
*/
void VoodooSDHC::Reset(UInt8 slot, UInt8 type)
{
switch(type) {
case CMD_RESET:
this->PCIRegP[slot]->SoftwareReset = CMD_RESET;
break;
case DAT_RESET:
this->PCIRegP[slot]->SoftwareReset = DAT_RESET;
break;
default:
this->PCIRegP[slot]->SoftwareReset = FULL_RESET;
break;
}
while(this->PCIRegP[slot]->SoftwareReset);
}
/*
* SDCommand: Send a single command to the SDHCI Host controller. Return true on
* success, false on failure. Will spin wait indefinitely if device is
* busy.
*UInt8 slot: Which slot the card to send to is in
*UInt8 command: SDHC command as defined in SDHC Physical Interface
*UInt16 response: Response type to expect for command passed in
*UInt32 arg: Command argument as defined in SDHC Physical Interface
*/
bool VoodooSDHC::SDCommand(UInt8 slot, UInt8 command, UInt16 response,
UInt32 arg) {
if (command != 0) {
while(this->PCIRegP[slot]->PresentState & ComInhibitCMD);
}
//if(command 1= COMMANDS?)
//{
//Wait for DAT to free up
//while(this->PCIRegP[slot]->PresentState & ComInhibitDAT);
//}
switch(response) { //See SD Host Controller Spec Version 2.00 Page 30
case R0:
response = 0;
break;
case R1:
response = BIT4|BIT3|BIT1;
break;
case R1b:
response = BIT4|BIT3|BIT1|BIT0;
break;
case R2:
response = BIT3|BIT0;
break;
case R3:
response = BIT1;
break;
case R4:
response = BIT1;
break;
case R5:
response = BIT4|BIT3|BIT1;
break;
case R5b:
response = BIT4|BIT3|BIT1|BIT0;
break;
case R6:
response = BIT4|BIT3|BIT1;
break;
case R7:
response = BIT4|BIT3|BIT1;
break;
}
this->PCIRegP[slot]->Argument = arg;
if (command == 17 || command == 24)
response |= BIT5;
if (command == SD_READ_MULTIPLE_BLOCK) {
response |= BIT5;
this->PCIRegP[0]->TransferMode =
SDHCI_TRNS_READ | SDHCI_TRNS_MULTI |
SDHCI_TRNS_BLK_CNT_EN | SDHCI_TRNS_ACMD12
#ifdef USE_SDMA
| SDHCI_TRNS_DMA
#endif
;
}
if (command == SD_WRITE_MULTIPLE_BLOCK) {
response |= BIT5;
this->PCIRegP[0]->TransferMode = SDHCI_TRNS_MULTI |
SDHCI_TRNS_BLK_CNT_EN | SDHCI_TRNS_ACMD12
#ifdef USE_SDMA
| SDHCI_TRNS_DMA
#endif
;
}
this->PCIRegP[slot]->Command = (command << 8) | response;
//IOLog("Command: %d", (command << 8) | response);
return true;
}
/*
* calcClock: Calculate card clock rate. See SDHCI Host Controller spec
* for details on calculation. Must be called after cardInit.
*UInt8 slot: Host controller/slot number
*UInt32 clockspeed: Maximum desired clock speed
*/
bool VoodooSDHC::calcClock(UInt8 slot, UInt32 clockspeed) {
UInt32 baseClock;
UInt32 div;
this->PCIRegP[slot]->ClockControl = 0;
this->PCIRegP[slot]->ClockControl = 0;
this->PCIRegP[slot]->ClockControl |= BIT0;
while(!this->PCIRegP[slot]->ClockControl & BIT1);
baseClock = ((this->PCIRegP[slot]->Capabilities[0] & 0x3F00) >> 8);
baseClock *= 1000000;
#ifdef __DEBUG__
IOLog("VoodooSDHCI: BaseClock :: %dMHz\n", baseClock/1000000);
#endif //me
for(div=1;(baseClock / div) > clockspeed;div <<= 1);
#ifdef __DEBUG__
IOLog("VoodooSDHCI: SD Clock :: %dKHz\n", (baseClock/div)/1000);
#endif //me
div = (div<<7) & 0xFF000;
this->PCIRegP[slot]->ClockControl |= div;
this->PCIRegP[slot]->ClockControl |= BIT2;
return true;
}
/*
* powerSD: Turn on power to SD Card. Must pay attention to voltage
* level supported. This is determined from the Host capability
* register.
*UInt8 slot: Slot the card is in.
*/
bool VoodooSDHC::powerSD(UInt8 slot) {
this->PCIRegP[slot]->PowerControl = 0;
#ifdef __DEBUG__
IOLog("VoodooSDHCI: in power_sd(slot) function :: 0x%x\n", this->PCIRegP[slot]->Capabilities[0]);
#endif
if(this->PCIRegP[slot]->Capabilities[0] & CR3v3Support) {
this->PCIRegP[slot]->PowerControl |= HC3v3;
} else if(this->PCIRegP[slot]->Capabilities[0] & CR3v0Support) {
this->PCIRegP[slot]->PowerControl |= HC3v0;
} else if(this->PCIRegP[slot]->Capabilities[0] & CR1v8Support) {
this->PCIRegP[slot]->PowerControl |= HC1v8;
}
this->PCIRegP[slot]->PowerControl |= SDPower;
return true;
}
/*
* parseCID: Parse Card Idenitification information
*UInt8 slot: slot the card is in
*/
void VoodooSDHC::parseCID(UInt8 slot) {
this->SDCIDReg[slot].MID = (UInt8)(this->PCIRegP[slot]->Response[3] & 0xFF000000) >> 24;
this->SDCIDReg[slot].OID = (UInt16)(this->PCIRegP[slot]->Response[3] & 0xFFFF00) >> 8;
this->SDCIDReg[slot].PNM[0] = (UInt8)(this->PCIRegP[slot]->Response[3] & 0xFF);
this->SDCIDReg[slot].PNM[1] = (UInt8)((this->PCIRegP[slot]->Response[2] & 0xFF000000) >> 24);
this->SDCIDReg[slot].PNM[2] = (UInt8)((this->PCIRegP[slot]->Response[2] & 0xFF0000) >> 16);
this->SDCIDReg[slot].PNM[3] = (UInt8)((this->PCIRegP[slot]->Response[2] & 0xFF00) >> 8);
this->SDCIDReg[slot].PNM[4] = (UInt8)(this->PCIRegP[slot]->Response[2] & 0xFF);
this->SDCIDReg[slot].PNM[5] = 0;
this->SDCIDReg[slot].PRV[0] = (UInt8)(this->PCIRegP[slot]->Response[1] & 0xF0000000) >> 28;
this->SDCIDReg[slot].PRV[1] = (UInt8)(this->PCIRegP[slot]->Response[1] & 0xF000000) >> 24;
this->SDCIDReg[slot].PSN = (this->PCIRegP[slot]->Response[1] & 0xFFFFFF) << 8;
this->SDCIDReg[slot].PSN |= (this->PCIRegP[slot]->Response[0] & 0xFF000000) >> 24;
this->SDCIDReg[slot].MDT[0] = (UInt8)(this->PCIRegP[slot]->Response[0] & 0xFF000) >> 12;
this->SDCIDReg[slot].MDT[1] = (UInt8)(this->PCIRegP[slot]->Response[1] & 0xF00) >> 8;
}
/*
* parseCSD: Parse CSD information
*UInt8 slot: slot the card is in
*/
void VoodooSDHC::parseCSD(UInt8 slot) {
switch ((UInt8)((this->PCIRegP[slot]->Response[3] & 0xC00000) >> 22)) {
case 0: // version 1
{
UInt8 blLen = (UInt8)((PCIRegP[slot]->Response[2] & 0xF00) >> 8);
UInt16 cSize = (UInt16)((PCIRegP[slot]->Response[2] & 0x3) << 10);
cSize |= (UInt16)((PCIRegP[slot]->Response[1] & 0xFFC00000) >> 22);
UInt8 cSizeMult = (UInt8)((PCIRegP[slot]->Response[1] & 0x000380) >> 7);
int large_to_small = (1 << (blLen)) / 512;
maxBlock = (cSize+1) * large_to_small *
(1 << (cSizeMult+2)) - 1;
}
break;
case 1: // version 2
{
int units = (UInt16)(PCIRegP[slot]->Response[1] >> 24);
units |= (PCIRegP[slot]->Response[1] & 0x00ff0000) >> 8;
units |= (PCIRegP[slot]->Response[2] & 0x3f) << 16;
maxBlock = (units + 1) * 1024;
}
break;
default:
// donno how to bail out...
;
}
}
/*
* reportRemovability: Apple API function. An SD Card is a removeable
* device. Returns an I/O success.
*bool *isRemovable: Passed back. Always return true.
*/
IOReturn VoodooSDHC::reportRemovability(bool *isRemovable) {
*isRemovable = true;
#ifdef __DEBUG__
IOLog("VoodooSDHCI: reportRemovability\n");
#endif
return kIOReturnSuccess;
}
/*
* reportWriteProtection: Apple API function. Returns whether the card is
*write protected. Returns an I/O success.
*bool *isWriteProtected: Passed back. Always return true.
*/
IOReturn VoodooSDHC::reportWriteProtection(bool *isWriteProtected) {
// XXX - how is this supposed to work for multi-slot???
*isWriteProtected = isCardWP( 0 );
//*isWriteProtected = true;
#ifdef __DEBUG__
IOLog("VoodooSDHCI: reportWriteProtection\n");
#endif
return kIOReturnSuccess;
}
/*
* setWriteCacheState: Apple API function. This driver does not support
*write cacheing. Returns an I/O success.
*bool enabled: Enable/disable cache
*/
IOReturn VoodooSDHC::setWriteCacheState(bool enabled) {
#ifdef __DEBUG__
IOLog("VoodooSDHCI: setWriteCacheState\n");
#endif
return kIOReturnSuccess;
}
/*
* reportPollRequirements: Apple API function. Report back requirements for
* polling. This driver must be polled, but the poll
* is cheap.
*bool *pollRequired: This is a return value from this function
*bool *pollIsExpensive: This is a return value from this function
*/
IOReturn VoodooSDHC::reportPollRequirements(bool *pollRequired, bool *pollIsExpensive)
{
*pollRequired = false;
*pollIsExpensive = false;
return kIOReturnSuccess;
}
IOReturn VoodooSDHC::reportMediaState(bool *mediaPresent, bool *changedState)
{
IOLockLock(mediaStateLock);
bool presence = isCardPresent(0);
if (cardPresence == kCardRemount) {
*changedState = true;
cardPresence = kCardNotPresent;
} else if ((cardPresence == kCardIsPresent) == presence) {
*changedState = false;
} else {
*changedState = true;
if (presence) {
Reset(0, FULL_RESET);
cardInit(0);
::OSSynchronizeIO();
cardPresence = kCardIsPresent;
} else {
cardPresence = kCardNotPresent;
}
}
*mediaPresent = cardPresence == kCardIsPresent;
IOLockUnlock(mediaStateLock);
return kIOReturnSuccess;
}
#ifndef __LP64__
IOReturn VoodooSDHC::reportMaxWriteTransfer(UInt64 blockSize,
UInt64 *max) {
//Max blocks we can read at once (see Block Count Register)
*max = 64 * blockSize;
#ifdef __DEBUG__
IOLog("VoodooSDHCI: reportMaxWriteTransfer\n");
#endif /* end DEBUG */
return kIOReturnSuccess;
}
IOReturn VoodooSDHC::reportMaxReadTransfer (UInt64 blockSize,
UInt64 *max) {
//Max blocks we can read at once (see Block Count Register)
*max = 65536 * blockSize;
#ifdef __DEBUG__
IOLog("VoodooSDHCI: reportMaxReadTransfer\n");
#endif /* end DEBUG */
return kIOReturnSuccess;
}
#endif /* !__LP64__ */
IOReturn VoodooSDHC::reportMaxValidBlock(UInt64 *maxBlock) {
*maxBlock = this->maxBlock;
#ifdef __DEBUG__
IOLog("VoodooSDHCI: reportMaxValidBlock\n");
#endif
return kIOReturnSuccess;
}
IOReturn VoodooSDHC::reportLockability(bool *isLockable) {
*isLockable = false;
#ifdef __DEBUG__
IOLog("VoodooSDHCI: reportLockability\n");
#endif
return kIOReturnSuccess;
}
IOReturn VoodooSDHC::reportEjectability(bool *isEjectable) {
*isEjectable = false;
#ifdef __DEBUG__
IOLog("VoodooSDHCI: reportEjectability\n");
#endif
return kIOReturnSuccess;
}
IOReturn VoodooSDHC::reportBlockSize(UInt64 *blockSize) {
// Read/write block size is always 512 bytes. Card's block size
// is reported but only used in computations of size, not access.
*blockSize = 512;
#ifdef __DEBUG__
IOLog("VoodooSDHCI: reportBlockSize: %d\n", *blockSize);
#endif
return kIOReturnSuccess;
}
IOReturn VoodooSDHC::getWriteCacheState(bool *enabled) {
*enabled = false;
#ifdef __DEBUG__
IOLog("VoodooSDHCI: getWriteCacheState\n");
#endif
return kIOReturnSuccess;
}
char * VoodooSDHC::getVendorString(void) {
#ifdef __DEBUG__
IOLog("VoodooSDHCI: getVendorString\n");
#endif
return("Generic");
}
char * VoodooSDHC::getRevisionString(void) {
#ifdef __DEBUG__
IOLog("VoodooSDHCI: getRevisionString\n");
#endif
return("2");
}
char * VoodooSDHC::getProductString(void) {
#ifdef __DEBUG__
IOLog("VoodooSDHCI: getProductString\n");
#endif
return("SDHCI Controller");
}
char * VoodooSDHC::getAdditionalDeviceInfoString(void) {
#ifdef __DEBUG__
IOLog("VoodooSDHCI: getAdditionalDeviceInfoString\n");
#endif
return("VoodooSDHCI:getAdditionalDeviceInfoString");
}
IOReturn VoodooSDHC::doSynchronizeCache(void) {
#ifdef __DEBUG__
IOLog("VoodooSDHCI: doSynchronizeCache\n");
#endif
return kIOReturnSuccess;
}
IOReturn VoodooSDHC::doLockUnlockMedia(bool doLock) {
#ifdef __DEBUG__
IOLog("VoodooSDHCI: doLockUnlockMedia\n");
#endif
return kIOReturnUnsupported;
}
UInt32 VoodooSDHC::doGetFormatCapacities(UInt64 *capacities, UInt32 capacitiesMaxCount) const {
#ifdef __DEBUG__
IOLog("VoodooSDHCI: doGetFormatCapacities\n");
#endif
return kIOReturnSuccess;
}
IOReturn VoodooSDHC::doFormatMedia(UInt64 byteCapacity) {
#ifdef __DEBUG__
IOLog("VoodooSDHCI: doFormatMedia\n");
#endif
return kIOReturnUnsupported;
}
IOReturn VoodooSDHC::doEjectMedia(void) {
#ifdef __DEBUG__
IOLog("VoodooSDHCI: doEjectMedia\n");
#endif
return kIOReturnUnsupported;
}
bool VoodooSDHC::waitIntStatus(UInt32 maskBits)
{
// roughly 5 seconds before timeout
for (int cnt = 0; cnt < 500000; cnt++) {
while (1) {
UInt32 nis = PCIRegP[0]->NormalIntStatus;
if (nis & ErrorInterrupt) {
return false;
}
if (nis & maskBits) {
PCIRegP[0]->NormalIntStatus = nis | maskBits;
return true;
}
}
::IODelay(10);
}
return false;
}
/*
* readBlockMulti_pio: Read a set of blocks using multi-block reads and PIO
* not DMA mode. The host controller must be locked when
*this function is called.
*IOMemoryDescriptor *buffer: Buffer operation class. Defines
*read/write, address of operation, etc.
*UInt32 block: Block offset to read/write
*UInt32 nblks: Block count to read/write
*UInt32 offset: Offset from beginning of transfer - where in
*final buffer we should begin placing data
*/
IOReturn VoodooSDHC::readBlockMulti_pio(IOMemoryDescriptor *buffer,
UInt32 block, UInt32 nblks,
UInt32 offset) {
UInt8 buff[512];// Temporary storage for one block
UInt32 *pBuff;
IOReturn ret = kIOReturnError;
#ifdef __DEBUG__
IOLog("VoodooSDHCI: readBlockMulti_pio: block = %d, nblks = %d\n", block, nblks);
#endif /* __DEBUG__ */
pBuff = (UInt32*)buff;
#ifndef NO_RESET_WAR
// Reset card before every operation. The Linux driver
// does this for this host controller. Not sure why.
Reset(0, CMD_RESET);
Reset(0, DAT_RESET);
#endif
/* Enable all interrupts */
this->PCIRegP[0]->NormalIntStatusEn = -1;
this->PCIRegP[0]->ErrorIntStatusEn = -1;
/* Clear pending interrupts */
this->PCIRegP[0]->NormalIntStatus =
(BuffReadReady | XferComplete | CmdComplete);
/* Set maximum timeout value */
this->PCIRegP[0]->TimeoutControl = 0xe;
*(volatile UInt32 *)&(this->PCIRegP[0]->NormalIntStatus) =
*(volatile UInt32 *)&(this->PCIRegP[0]->NormalIntStatus);
this->PCIRegP[0]->BlockSize = 512;
this->PCIRegP[0]->BlockCount = nblks;
this->PCIRegP[0]->TransferMode = SDHCI_TRNS_READ | SDHCI_TRNS_MULTI |
SDHCI_TRNS_BLK_CNT_EN | SDHCI_TRNS_ACMD12;
// Issue read command to host controller
SDCommand(0, SD_READ_MULTIPLE_BLOCK, SDCR18, isHighCapacity ? block : block * 512);
// wait for CmdComplete
if (! waitIntStatus(CmdComplete)) {
IOLog("VoodooSDHCI: I/O error after command 18: It Status: 0x%x\n", PCIRegP[0]->NormalIntStatus);
goto out;
}
for (int i = 0; i < nblks; i++) {
// wait for BufferReadReady
if (! waitIntStatus(BuffReadReady)) {
IOLog("VoodooSDHCI: I/O timeout while waiting for data, Status: 0x%0x\n", PCIRegP[0]->NormalIntStatus);
goto out;
}
/* Read block from card */
read_block_pio(&this->PCIRegP[0]->BufferDataPort, pBuff);
/* Copy buffer to final location */
buffer->writeBytes((i + offset) * 512, buff, 1 * 512);
}
// wait for transfer complete
if (! waitIntStatus(XferComplete)) {
IOLog("VoodooSDHCI: I/O timeout during completion... status == 0x%x\n", PCIRegP[0]->NormalIntStatus);
}
ret = kIOReturnSuccess;
out:
return ret;
}
/*
* sdma_access: Read / write a set of blocks using multi-block reads in SDMA mode.
* The host controller must be locked when this function is called.
*IOMemoryDescriptor *buffer: Buffer operation class. Defines
*read/write, address of operation, etc.
*UInt32 block: Block offset to read/write
*UInt32 nblks: Block count to read/write
* bool read: true if read, false if write
*/
IOReturn VoodooSDHC::sdma_access(IOMemoryDescriptor *buffer,
UInt32 block, UInt32 nblks, bool read) {
IOReturn ret = kIOReturnError;
UInt32 nis, offset = 0;
AbsoluteTime deadline;
#ifdef __DEBUG__
IOLog("VoodooSDHCI readBlockMulti_sdma: block = %d, nblks = %d\n", block, nblks);
#endif /* __DEBUG__ */
#ifndef NO_RESET_WAR
// Reset card before every operation. The Linux driver
// does this for this host controller. Not sure why.
Reset(0, CMD_RESET);
Reset(0, DAT_RESET);
#endif
/* write: fill in data */
if (! read) {
buffer->readBytes(offset * 512, virtSdmaBuff, min(SDMA_BUFFER_SIZE, nblks * 512));
offset += min(SDMA_BUFFER_SIZE / 512, nblks);
}
/* Set maximum timeout value */
this->PCIRegP[0]->TimeoutControl = 0xe; // 2^27clks / 50MHz = 2.7 seconds
/* Enable all interrupts */
this->PCIRegP[0]->NormalIntSignalEn = 0x01ff;
this->PCIRegP[0]->NormalIntStatusEn = -1;
this->PCIRegP[0]->ErrorIntSignalEn = 0x01ff;
this->PCIRegP[0]->ErrorIntStatusEn = -1;
/* Clear pending interrupts */
this->PCIRegP[0]->NormalIntStatus =
(BuffReadReady | XferComplete | CmdComplete);
this->PCIRegP[0]->ErrorIntStatus = 0xf3ff;
::OSSynchronizeIO();
PCIRegP[0]->SDMASysAddr = physSdmaBuff;
::OSSynchronizeIO();
this->PCIRegP[0]->BlockSize = 512 | SDMA_BUFFER_SIZE_IN_REG;
this->PCIRegP[0]->BlockCount = nblks;
::OSSynchronizeIO();
// Issue read command to host controller
SDCommand(0,
read ? SD_READ_MULTIPLE_BLOCK : SD_WRITE_MULTIPLE_BLOCK,
SDCR18,
isHighCapacity ? block : block * 512);
::OSSynchronizeIO();
// wait for CmdComplete
if (! waitIntStatus(CmdComplete)) {
IOLog("VoodooSDHCI: I/O error after command %d (SDMA): Status: 0x%x, Error: 0x%x\n",
read ? SD_READ_MULTIPLE_BLOCK : SD_WRITE_MULTIPLE_BLOCK, PCIRegP[0]->NormalIntStatus, PCIRegP[0]->ErrorIntStatus);
Reset(0, FULL_RESET);
if (! cardInit(0)) {
IOLog("VoodooSDHCI: reset failed, disabling access\n");
cardPresence = kCardRemount;
}
ret = kIOReturnTimeout;
goto out;
}
// check response
if (PCIRegP[0]->Response[0] & (read ? 0xcff80000 : 0xeff80000)) {
IOLog("VoodooSDHCI: Unexpected response from command %d (SDMA): Response: 0x%x\n",
read ? SD_READ_MULTIPLE_BLOCK : SD_WRITE_MULTIPLE_BLOCK, PCIRegP[0]->Response[0]);
goto out;
}
clock_interval_to_deadline(5000, kMillisecondScale, (uint64_t*)&deadline);
IOLockLock(sdmaCond);
while ((PCIRegP[0]->NormalIntStatus & ErrorInterrupt) == 0) {
if (IOLockSleepDeadline(sdmaCond, sdmaCond, deadline, THREAD_UNINT) == THREAD_TIMED_OUT) {
IOLockUnlock(sdmaCond);
// timeout
IOLog("VoodooSDHCI: I/O timeout during SDMA transfer: Status: 0x%x, Error: 0x%x, Block: %d, Offset: %d, Blocks: %d\n",
PCIRegP[0]->NormalIntStatus, PCIRegP[0]->ErrorIntStatus, (int)block, (int)offset, (int)nblks);
ret = kIOReturnTimeout;
goto out;
}
nis = PCIRegP[0]->NormalIntStatus;
if (nis & XferComplete) {
IOLockUnlock(sdmaCond);
if (read) {
buffer->writeBytes(offset * 512, virtSdmaBuff, nblks * 512);
}
PCIRegP[0]->NormalIntStatus = XferComplete | DMAInterrupt;
ret = kIOReturnSuccess;
goto out;
} else if (nis & DMAInterrupt) {
IOLockUnlock(sdmaCond);
if (read) {
buffer->writeBytes(offset * 512, virtSdmaBuff, SDMA_BUFFER_SIZE);
offset += SDMA_BUFFER_SIZE / 512;
nblks -= SDMA_BUFFER_SIZE / 512;
} else {
buffer->readBytes(offset * 512, virtSdmaBuff, min(SDMA_BUFFER_SIZE, (nblks - offset) * 512));
offset += min(SDMA_BUFFER_SIZE / 512, nblks - offset);
}
IOLockLock(sdmaCond);
PCIRegP[0]->NormalIntStatus = DMAInterrupt;
::OSSynchronizeIO();
PCIRegP[0]->SDMASysAddr = physSdmaBuff;
}
}
IOLockUnlock(sdmaCond);
// error
IOLog("VoodooSDHCI: I/O error during SDMA transfer: Status: 0x%x, Error: 0x%x, Block: %d, Offset: %d, Blocks: %d\n",
PCIRegP[0]->NormalIntStatus, PCIRegP[0]->ErrorIntStatus, (int)block, (int)offset, (int)nblks);
goto out;
ret = kIOReturnSuccess;
out:
PCIRegP[0]->NormalIntSignalEn = 0;
PCIRegP[0]->ErrorIntSignalEn = 0;
return ret;
}
/*
* readBlockSingle_pio: Read a single block from the card using PIO not DMA
* mode. The host controller must be locked when this
* function is called.
*UInt8 *buff: Temporary buffer for data
*UInt32 block: Block offset to read/write
*/
IOReturn VoodooSDHC::readBlockSingle_pio(UInt8 *buff, UInt32 block) {
UInt32 *pBuff;
int cnt, pass;
IOReturn ret;
#ifndef NO_RESET_WAR
// Reset card before every operation. The Linux driver does this for
// this host controller. Not sure why
Reset(0, CMD_RESET);
Reset(0, DAT_RESET);
#endif /* NO_RESET_WAR */
pBuff = (UInt32*)buff;
/* Set transfer mode to single block */
this->PCIRegP[0]->TransferMode = BIT4;
/* Enable interrupt flags */
this->PCIRegP[0]->NormalIntStatusEn = -1;
this->PCIRegP[0]->ErrorIntStatusEn = -1;
/* Clear pending interrupts */
this->PCIRegP[0]->NormalIntStatus =
(BuffReadReady | XferComplete | CmdComplete);
/* Set maximum timeout value */
this->PCIRegP[0]->TimeoutControl = 0xe;
#ifdef __DEBUG__
IOLog("VoodooSDHCI Int Status 0x%x Timeout = 0x%x\n",
*(volatile UInt32 *)&(this->PCIRegP[0]->NormalIntStatus),
this->PCIRegP[0]->TimeoutControl);
//IOLog("VoodooSDHCI: state1 = 0x%x response = 0x%x\n",
//this->PCIRegP[0]->PresentState, this->PCIRegP[0]->Response[0]);
#endif /* __DEBUG__ */
*(volatile UInt32 *)&(this->PCIRegP[0]->NormalIntStatus) =
*(volatile UInt32 *)&(this->PCIRegP[0]->NormalIntStatus);
SDCommand(0, SD_READ_SINGLE_BLOCK, SDCR17, isHighCapacity ? block : block * 512);
cnt = pass = 0;
//IOLog("VoodooSDHCI: state2 = 0x%x response = 0x%x\n",
//this->PCIRegP[0]->PresentState, this->PCIRegP[0]->Response[0]);
while((this->PCIRegP[0]->NormalIntStatus & BuffReadReady) !=
BuffReadReady) {
if (this->PCIRegP[0]->NormalIntStatus & 0x8000) {
IOLog("VoodooSDHCI: S Returning error: 0x%x\n", *(volatile UInt32 *) & (this->PCIRegP[0]->NormalIntStatus));
ret = kIOReturnError;
goto out;
}
cnt++;
if (cnt > 100000) {
cnt = 0;
pass++;
IOLog("VoodooSDHCI: Stuck in while loop 1: pass = %d"
" status = 0x%x state = 0x%x\n", pass,
*(volatile UInt32 *)&(this->PCIRegP[0]->
NormalIntStatus),
this->PCIRegP[0]->PresentState);
if (pass > 10) {
ret = kIOReturnError;
goto out;
}
}
::IODelay(10);
}
/* Read block from card */
read_block_pio(&this->PCIRegP[0]->BufferDataPort, pBuff);
ret = kIOReturnSuccess;
out:
this->PCIRegP[0]->NormalIntStatus =
(BuffReadReady|XferComplete|CmdComplete);
return ret;
}
/*
* writeBlockMulti_pio: Write multiple blocks to the card using PIO not DMA
* mode. The host controller must be locked when this
* function is called.
*IOMemoryDescriptor *buffer: Buffer operation class. Defines
*read/write, address of operation, etc.
*UInt32 block: Block offset to read/write
*UInt32 nblks: Number of blocks to read/write
*UInt32 offset: Offset from beginning of transfer - where in
*final buffer we should begin placing data
*/
IOReturn VoodooSDHC::writeBlockMulti_pio(IOMemoryDescriptor *buffer,
UInt32 block, UInt32 nblks, UInt32 offset) {
UInt8 buff[512];// Temporary storage for data block
int cnt, pass;
UInt32 *pBuff;
IOReturn ret;
#ifndef NO_RESET_WAR
// Reset card before every operation. The Linux driver does this
// for this host controller. Not sure why.
Reset(0, CMD_RESET);
Reset(0, DAT_RESET);
#endif
this->PCIRegP[0]->NormalIntStatusEn = -1;
this->PCIRegP[0]->ErrorIntStatusEn = -1;
this->PCIRegP[0]->NormalIntStatus =
BuffWriteReady | XferComplete | CmdComplete;
this->PCIRegP[0]->TimeoutControl = 0xe;
this->PCIRegP[0]->BlockSize = 512;
this->PCIRegP[0]->BlockCount = nblks;
SDCommand(0, SD_APP_CMD, SDCR55, this->RCA << 16);
SDCommand(0, SD_APP_SET_WR_BLK_ERASE_COUNT, SDCR23, nblks);
SDCommand(0, SD_WRITE_MULTIPLE_BLOCK, SDCR24, isHighCapacity ? block : block * 512);
for (int i = 0; i < nblks; i++) {
buffer->readBytes((offset + i) * 512, buff, 1 * 512);
pBuff = (UInt32*)buff;
cnt = pass = 0;
while(!(this->PCIRegP[0]->PresentState &
SDHCI_SPACE_AVAILABLE)) {
cnt++;
if (this->PCIRegP[0]->NormalIntStatus & 0x8000) {
IOLog("VoodooSDHCI 2 Returning error: 0x%x\n",
*(volatile UInt32 *)
&(this->PCIRegP[0]->NormalIntStatus));
ret = kIOReturnError;
goto out;
}
if (cnt > 100000) {
cnt = 0;
pass++;
IOLog("VoodooSDHCI: Stuck in while loop 2: pass = %d"
" status = 0x%x\n", pass,
this->PCIRegP[0]->NormalIntStatus);
if (pass > 10) {
ret = kIOReturnError;
goto out;
}
}
::IODelay(10);
}
this->PCIRegP[0]->NormalIntStatus =
this->PCIRegP[0]->NormalIntStatus;
for (int j = 0; j < 128; j++) {
this->PCIRegP[0]->BufferDataPort = *pBuff;
pBuff++;
}
}
cnt = pass = 0;
while ((this->PCIRegP[0]->NormalIntStatus & XferComplete) !=
XferComplete) {
cnt++;
if (this->PCIRegP[0]->NormalIntStatus & 0x8000) {
IOLog("VoodooSDHCI 3 Returning error: 0x%x\n",
*(volatile UInt32 *)
&(this->PCIRegP[0]->NormalIntStatus));
ret = kIOReturnError;
goto out;
}
if (cnt > 100000) {
cnt = 0;
pass++;
IOLog("VoodooSDHCI: Stuck in while loop 3: pass = %d"
" status = 0x%x\n", pass,
this->PCIRegP[0]->NormalIntStatus);
if (pass > 10) {
ret = kIOReturnError;
goto out;
}
}
}
this->PCIRegP[0]->NormalIntStatus =
BuffWriteReady | XferComplete | CmdComplete;
ret = kIOReturnSuccess;
out:
return ret;
}
/*
* writeBlockSingle_pio: Read a single block from the card using PIO not DMA
* mode. The host controller must be locked when this
* function is called.
*IOMemoryDescriptor *buffer: Buffer operation class. Defines
*read/write, address of operation, etc.
*UInt32 block: Block offset to read/write
*UInt32 offset: Offset from beginning of transfer - where in
*final buffer we should begin placing data
*/
IOReturn VoodooSDHC::writeBlockSingle_pio(IOMemoryDescriptor *buffer,
UInt32 block, UInt32 offset) {
UInt8 buff[512];// Temporary storage for data block
int cnt, pass;
UInt32 *pBuff;
IOReturn ret;
pBuff = (UInt32*)buff;
buffer->readBytes(offset * 512, buff, 1 * 512);
#ifndef NO_RESET_WAR
// Reset card before every operation. The Linux driver does this
// for this host controller. Not sure why.
Reset(0, CMD_RESET);
Reset(0, DAT_RESET);
#endif
this->PCIRegP[0]->TransferMode = 0;
this->PCIRegP[0]->NormalIntStatusEn = -1;
this->PCIRegP[0]->ErrorIntStatusEn = -1;
this->PCIRegP[0]->NormalIntStatus =
BuffWriteReady | XferComplete | CmdComplete;
this->PCIRegP[0]->TimeoutControl = 0xe;
SDCommand(0, SD_WRITE_BLOCK, SDCR24, isHighCapacity ? block : block * 512);
cnt = pass = 0;
while ((this->PCIRegP[0]->NormalIntStatus & BuffWriteReady) !=
BuffWriteReady) {
cnt++;
if (this->PCIRegP[0]->NormalIntStatus & 0x8000) {
IOLog("VoodooSDHCI: 2 Returning error: 0x%x\n",
*(volatile UInt32 *)
&(this->PCIRegP[0]->NormalIntStatus));
ret = kIOReturnError;
goto out;
}
if (cnt > 100000) {
cnt = 0;
pass++;
IOLog("VoodooSDHCI: Stuck in while loop 2: pass = %d"
" status = 0x%x\n", pass,
this->PCIRegP[0]->NormalIntStatus);
if (pass > 10) {
ret = kIOReturnError;
goto out;
}
}
}
for (int j = 0; j < 128; j++) {
this->PCIRegP[0]->BufferDataPort = *pBuff;
pBuff++;
}
cnt = pass = 0;
while ((this->PCIRegP[0]->NormalIntStatus & XferComplete) !=
XferComplete) {
cnt++;
if (this->PCIRegP[0]->NormalIntStatus & 0x8000) {
IOLog("VoodooSDHCI 3 Returning error: 0x%x\n",
*(volatile UInt32 *)
&(this->PCIRegP[0]->NormalIntStatus));
ret = kIOReturnError;
goto out;
}
if (cnt > 100000) {
cnt = 0;
pass++;
IOLog("VoodooSDHCI: stuck in while loop #3: pass = %d"
" status = 0x%x\n", pass,
this->PCIRegP[0]->NormalIntStatus);
if (pass > 10) {
ret = kIOReturnError;
goto out;
}
}
}
this->PCIRegP[0]->NormalIntStatus =
BuffWriteReady | XferComplete | CmdComplete;
ret = kIOReturnSuccess;
out:
return ret;
}
/*
* doAsyncReadWrite: Guts of the driver. Perform reads and writes. This
* function must be reentrant. Further, the completion
* action may result in another call to this function.
* This function may block.
* Returns success or failure.
*IOMemoryDescriptor *buffer: Buffer operation class. Defines
*read/write, address of operation, etc.
*UInt32 block: Block offset to read/write
*
*IOStorageCompletion completion: Action to perform upon
*completion of operation
*/
#ifdef __LP64__
IOReturn VoodooSDHC::doAsyncReadWrite(IOMemoryDescriptor *buffer,
UInt64 block, UInt64 nblks,
IOStorageAttributes *attributes,
IOStorageCompletion *completion) {
UInt8 buff[512];// Temporary storage for data block
int ret = 0;
int locked;
UInt64 blk, n;
// All access to the card must be done while this lock is held
lock.lock();
locked = 1;
if (cardPresence != kCardIsPresent || ! isCardPresent(0)) {
ret = kIOReturnNoMedia;
goto out;
}
#ifdef __DEBUG__
IOLog("VoodooSDHCI: in doAsyncReadWrite function :: block == %d, nblks == %d, ", block, nblks);
#endif
if (buffer->getDirection() == kIODirectionIn) {
/* Read from Card */
#ifdef __DEBUG__
IOLog("READING FROM CARD!\n");
#endif
blk = block;
n = nblks;
while (n) {
if (USE_SDMA) {
int i;
for (i = 0; i < SDMA_RETRY_COUNT; i++)
if ((ret = sdma_access(buffer, block, nblks, true)) != kIOReturnTimeout)
break;
if (i != 0)
IOLog("VoodooSDHCI: retry succeeded\n");
n = 0;
} else if ((nblks > 1) && USE_MULTIBLOCK) {
int b = MIN(2048 /* should fit in sdma buff */, n);
ret = readBlockMulti_pio(buffer, blk, b,
blk - block);
n -= b;
blk += b;
} else {
ret = readBlockSingle_pio(buff, blk);
buffer->writeBytes((blk - block) * 512,
buff, 1 * 512);
n--;
blk++;
}
if (ret != kIOReturnSuccess) goto out;
#ifdef __DEBUG__
IOLog("VoodooSDHCI: ret = 0x%x block = %d\n", ret, blk);;
#endif /* __DEBUG__ */
}
} else {
/* Write to Card */
#ifdef __DEBUG__
IOLog("WRITING TO CARD!\n");
#endif
#ifdef READONLY_DRIVER
// When compiled in this mode, the driver fails all write
// operations. Useful for testing to gain confidence in
// code without trashing data. Define must be set at top
// of file.
ret = kIOReturnError;
goto out;
#endif
blk = block;
n = nblks;
while (n) {
if (USE_SDMA) {
int i;
for (i = 0; i < SDMA_RETRY_COUNT; i++)
if ((ret = sdma_access(buffer, block, nblks, false)) != kIOReturnTimeout)
break;
if (i != 0)
IOLog("VoodooSDHCI: retry succeeded\n");
n = 0;
}
else if ((nblks > 1) && USE_MULTIBLOCK) {
int b = MIN(2048, n);
ret = writeBlockMulti_pio(buffer, blk, b,
blk - block);
n -= b;
blk += b;
} else {
ret = writeBlockSingle_pio(buffer, blk,
blk - block);
n--;
blk++;
}
if (ret != kIOReturnSuccess) goto out;
}
}
locked = 0;
lock.unlock();
if(completion->action) {
(completion->action)(completion->target, completion->parameter, kIOReturnSuccess, nblks * 512);
} else {
IOLog("VoodooSDHCI ERROR!\n");
ret = kIOReturnError;
goto out;
}
ret = kIOReturnSuccess;
out:
switch (ret) {
case kIOReturnSuccess:
break;
case kIOReturnNoMedia:
/* require remount */
cardPresence = kCardRemount;
IOLog("VoodooSDHCI: media not present, require remount\n");
break;
}
if (locked)
lock.unlock();
//in_read_write = 0;
return ret;
}
#else /* !__LP64__ */
IOReturn VoodooSDHC::doAsyncReadWrite(IOMemoryDescriptor *buffer,
UInt32 block, UInt32 nblks, IOStorageCompletion completion) {
UInt8 buff[512];// Temporary storage for data block
int ret = 0;
int locked;
UInt32 blk, n;
// All access to the card must be done while this lock is held
lock.lock();
locked = 1;
if (cardPresence != kCardIsPresent || ! isCardPresent(0)) {
ret = kIOReturnNoMedia;
goto out;
}
#ifdef __DEBUG__
IOLog("VoodooSDHCI: in doAsyncReadWrite function :: block == %d, nblks == %d, ", block, nblks);
#endif
if (buffer->getDirection() == kIODirectionIn) {
/* Read from Card */
#ifdef __DEBUG__
IOLog("READING FROM CARD!\n");
#endif
blk = block;
n = nblks;
while (n) {
if (USE_SDMA) {
int i;
for (i = 0; i < SDMA_RETRY_COUNT; i++)
if ((ret = sdma_access(buffer, block, nblks, true)) != kIOReturnTimeout)
break;
if (i != 0)
IOLog("VoodooSDHCI: retry succeeded\n");
n = 0;
} else if ((nblks > 1) && USE_MULTIBLOCK) {
int b = MIN(2048 /* should fit in sdma buff */, n);
ret = readBlockMulti_pio(buffer, blk, b,
blk - block);
n -= b;
blk += b;
} else {
ret = readBlockSingle_pio(buff, blk);
buffer->writeBytes((blk - block) * 512,
buff, 1 * 512);
n--;
blk++;
}
if (ret != kIOReturnSuccess) goto out;
#ifdef __DEBUG__
IOLog("VoodooSDHCI: ret = 0x%x block = %d\n", ret, blk);;
#endif /* __DEBUG__ */
}
} else {
/* Write to Card */
#ifdef __DEBUG__
IOLog("WRITING TO CARD!\n");
#endif
#ifdef READONLY_DRIVER
// When compiled in this mode, the driver fails all write
// operations. Useful for testing to gain confidence in
// code without trashing data. Define must be set at top
// of file.
ret = kIOReturnError;
goto out;
#endif
blk = block;
n = nblks;
while (n) {
if (USE_SDMA) {
int i;
for (i = 0; i < SDMA_RETRY_COUNT; i++)
if ((ret = sdma_access(buffer, block, nblks, false)) != kIOReturnTimeout)
break;
if (i != 0)
IOLog("VoodooSDHCI: retry succeeded\n");
n = 0;
}
else if ((nblks > 1) && USE_MULTIBLOCK) {
int b = MIN(2048, n);
ret = writeBlockMulti_pio(buffer, blk, b,
blk - block);
n -= b;
blk += b;
} else {
ret = writeBlockSingle_pio(buffer, blk,
blk - block);
n--;
blk++;
}
if (ret != kIOReturnSuccess) goto out;
}
}
locked = 0;
lock.unlock();
if(completion.action) {
(*completion.action)(completion.target, completion.parameter, kIOReturnSuccess, nblks * 512);
} else {
IOLog("VoodooSDHCI ERROR!\n");
ret = kIOReturnError;
goto out;
}
ret = kIOReturnSuccess;
out:
switch (ret) {
case kIOReturnSuccess:
break;
case kIOReturnNoMedia:
/* require remount */
cardPresence = kCardRemount;
IOLog("VoodooSDHCI: media not present, require remount\n");
break;
}
if (locked)
lock.unlock();
//in_read_write = 0;
return ret;
}
#endif /* !__LP64__ */
void VoodooSDHC::handleInterrupt()
{
IOLockLock(sdmaCond);
IOLockWakeup(sdmaCond, sdmaCond, true);
IOLockUnlock(sdmaCond);
}
void VoodooSDHC::handleTimer()
{
bool mediaPresent, changedState;
reportMediaState(&mediaPresent, &changedState);
if (changedState)
messageClients(
kIOMessageMediaStateHasChanged,
(void*)(mediaPresent ? kIOMediaStateOnline: kIOMediaStateOffline),
0);
timerSrc->setTimeoutMS(1000);
}
void VoodooSDHC::interruptHandler(OSObject *owner, IOInterruptEventSource *, int)
{
VoodooSDHC *self = static_cast<VoodooSDHC*>(owner);
self->handleInterrupt();
}
bool VoodooSDHC::interruptFilter(OSObject *owner, IOFilterInterruptEventSource *)
{
if (OSDynamicCast(VoodooSDHC, owner)) {
return true;
}
return false;
}
void VoodooSDHC::timerHandler(OSObject *owner, IOTimerEventSource *)
{
VoodooSDHC *self = static_cast<VoodooSDHC*>(owner);
self->handleTimer();
}
trunk/SD_DataTypes.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include "License.h"
struct SDCIDReg_t
{
UInt8MID;
UInt16OID;
charPNM[6];
UInt8PRV[2];
UInt32PSN;
UInt8MDT[2];
};
struct SDCSDReg1_t
{
UInt8CSD_STRUCTURE;
UInt8TAAC;
UInt8NSAC;
UInt8TRAN_SPEED;
UInt16CCC;
UInt8READ_BL_LEN;
UInt8READ_BL_PARTIAL;
UInt8READ_BLK_MISALIGN;
UInt8DSR_IMP;
UInt16C_SIZE;
UInt8VDD_R_CURR_MIN;
UInt8VDD_R_CURR_MAX;
UInt8VDD_W_CURR_MIN;
UInt8VDD_W_CURR_MAX;
UInt8C_SIZE_MULT;
UInt8ERASE_BLK_EN;
UInt8SECTOR_SIZE;
UInt8WP_GRP_SIZE;
UInt8WP_GRP_ENABLE;
UInt8R2W_FACTOR;
UInt8WRITE_BL_LEN;
UInt8WRITE_BL_PARTIAL;
UInt8FILE_FORMAT_GRP;
UInt8COPY;
UInt8PERM_WRITE_PROTECT;
UInt8TMP_WRITE_PROTECT;
UInt8FILE_FORMAT;
UInt8CRC;
};
struct SDCSDReg2_t
{
UInt8CSD_STRUCTURE;
UInt8TAAC;
UInt8NSAC;
UInt8TRAN_SPEED;
UInt16CCC;
UInt8READ_BL_LEN;
UInt8READ_BL_PARTIAL;
UInt8READ_BLK_MISALIGN;
UInt8DSR_IMP;
UInt32C_SIZE;
UInt8ERASE_BLK_EN;
UInt8SECTOR_SIZE;
UInt8WP_GRP_SIZE;
UInt8WP_GRP_ENABLE;
UInt8R2W_FACTOR;
UInt8WRITE_BL_LEN;
UInt8WRITE_BL_PARTIAL;
UInt8FILE_FORMAT_GRP;
UInt8COPY;
UInt8PERM_WRITE_PROTECT;
UInt8TMP_WRITE_PROTECT;
UInt8FILE_FORMAT;
UInt8CRC;
};
trunk/SD_Commands.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
#ifndef SD_H
#define SD_H
#include "License.h"
#include "SD_Misc.h"
/* SD commands type argument response */
/* class 0 */
/* This is basically the same command as for MMC with some quirks. */
#define SD_SEND_RELATIVE_ADDR 3 /* bcr R6 */
#define SD_SEND_IF_COND 8 /* bcr [11:0] See below R7 */
/* class 10 */
#define SD_SWITCH 6 /* adtc [31:0] See below R1 */
/* Application commands */
#define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */
#define SD_APP_SEND_NUM_WR_BLKS 22 /* adtc R1 */
#define SD_APP_SET_WR_BLK_ERASE_COUNT 23/* R1 */
#define SD_APP_OP_COND 41 /* bcr [31:0] OCR R3 */
#define SD_APP_SEND_SCR 51 /* adtc R1 */
/* Standard MMC commands (4.1) type argument response */
/* class 1 */
#define SD_GO_IDLE_STATE 0 /* bc */
#define SD_SEND_OP_COND 1 /* bcr [31:0] OCR R3 */
#define SD_ALL_SEND_CID 2 /* bcr R2 */
#define SD_SET_RELATIVE_ADDR 3 /* ac [31:16] RCA R1 */
#define SD_SET_DSR 4 /* bc [31:16] RCA */
#define SD_SWITCH 6 /* ac [31:0] See below R1b */
#define SD_SELECT_CARD 7 /* ac [31:16] RCA R1 */
#define SD_SEND_EXT_CSD 8 /* adtc R1 */
#define SD_SEND_CSD 9 /* ac [31:16] RCA R2 */
#define SD_SEND_CID 10 /* ac [31:16] RCA R2 */
#define SD_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */
#define SD_STOP_TRANSMISSION 12 /* ac R1b */
#define SD_SEND_STATUS 13 /* ac [31:16] RCA R1 */
#define SD_GO_INACTIVE_STATE 15 /* ac [31:16] RCA */
#define SD_SPI_READ_OCR 58 /* spi spi_R3 */
#define SD_SPI_CRC_ON_OFF 59 /* spi [0:0] flag spi_R1 */
/* class 2 */
#define SD_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */
#define SD_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */
#define SD_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */
/* class 3 */
#define SD_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */
/* class 4 */
#define SD_SET_BLOCK_COUNT 23 /* adtc [31:0] data addr R1 */
#define SD_WRITE_BLOCK 24 /* adtc [31:0] data addr R1 */
#define SD_WRITE_MULTIPLE_BLOCK 25 /* adtc R1 */
#define SD_PROGRAM_CID 26 /* adtc R1 */
#define SD_PROGRAM_CSD 27 /* adtc R1 */
/* class 6 */
#define SD_SET_WRITE_PROT 28 /* ac [31:0] data addr R1b */
#define SD_CLR_WRITE_PROT 29 /* ac [31:0] data addr R1b */
#define SD_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */
/* class 5 */
#define SD_ERASE_GROUP_START 35 /* ac [31:0] data addr R1 */
#define SD_ERASE_GROUP_END 36 /* ac [31:0] data addr R1 */
#define SD_ERASE 38 /* ac R1b */
/* class 9 */
#define SD_FAST_IO 39 /* ac <Complex> R4 */
#define SD_GO_IRQ_STATE 40 /* bcr R5 */
/* class 7 */
#define SD_LOCK_UNLOCK 42 /* adtc R1b */
/* class 8 */
#define SD_APP_CMD 55 /* ac [31:16] RCA R1 */
#define SD_GEN_CMD 56 /* adtc [0] RD/WR R1 */
/*
* MMC_SWITCH argument format:
*
*[31:26] Always 0
*[25:24] Access Mode
*[23:16] Location of target Byte in EXT_CSD
*[15:08] Value Byte
*[07:03] Always 0
*[02:00] Command Set
*/
/*
MMC status in R1, for native mode (SPI bits are different)
Type
e : error bit
s : status bit
r : detected and set for the actual command response
x : detected and set during command execution. the host must poll
the card by sending status command in order to read these bits.
Clear condition
a : according to the card state
b : always related to the previous command. Reception of
a valid command will clear it (with a delay of one command)
c : clear by read
*/
#define R1_OUT_OF_RANGE(1 << 31)/* er, c */
#define R1_ADDRESS_ERROR(1 << 30)/* erx, c */
#define R1_BLOCK_LEN_ERROR(1 << 29)/* er, c */
#define R1_ERASE_SEQ_ERROR (1 << 28)/* er, c */
#define R1_ERASE_PARAM(1 << 27)/* ex, c */
#define R1_WP_VIOLATION(1 << 26)/* erx, c */
#define R1_CARD_IS_LOCKED(1 << 25)/* sx, a */
#define R1_LOCK_UNLOCK_FAILED(1 << 24)/* erx, c */
#define R1_COM_CRC_ERROR(1 << 23)/* er, b */
#define R1_ILLEGAL_COMMAND(1 << 22)/* er, b */
#define R1_CARD_ECC_FAILED(1 << 21)/* ex, c */
#define R1_CC_ERROR(1 << 20)/* erx, c */
#define R1_ERROR(1 << 19)/* erx, c */
#define R1_UNDERRUN(1 << 18)/* ex, c */
#define R1_OVERRUN(1 << 17)/* ex, c */
#define R1_CID_CSD_OVERWRITE(1 << 16)/* erx, c, CID/CSD overwrite */
#define R1_WP_ERASE_SKIP(1 << 15)/* sx, c */
#define R1_CARD_ECC_DISABLED(1 << 14)/* sx, a */
#define R1_ERASE_RESET(1 << 13)/* sr, c */
#define R1_STATUS(x) (x & 0xFFFFE000)
#define R1_CURRENT_STATE(x)((x & 0x00001E00) >> 9)/* sx, b (4 bits) */
#define R1_READY_FOR_DATA(1 << 8)/* sx, a */
#define R1_APP_CMD(1 << 5)/* sr, c */
/*
* MMC/SD in SPI mode reports R1 status always, and R2 for SEND_STATUS
* R1 is the low order byte; R2 is the next highest byte, when present.
*/
#define R1_SPI_IDLE(1 << 0)
#define R1_SPI_ERASE_RESET(1 << 1)
#define R1_SPI_ILLEGAL_COMMAND(1 << 2)
#define R1_SPI_COM_CRC(1 << 3)
#define R1_SPI_ERASE_SEQ(1 << 4)
#define R1_SPI_ADDRESS(1 << 5)
#define R1_SPI_PARAMETER(1 << 6)
/* R1 bit 7 is always zero */
#define R2_SPI_CARD_LOCKED(1 << 8)
#define R2_SPI_WP_ERASE_SKIP(1 << 9)/* or lock/unlock fail */
#define R2_SPI_LOCK_UNLOCK_FAILR2_SPI_WP_ERASE_SKIP
#define R2_SPI_ERROR(1 << 10)
#define R2_SPI_CC_ERROR(1 << 11)
#define R2_SPI_CARD_ECC_ERROR(1 << 12)
#define R2_SPI_WP_VIOLATION(1 << 13)
#define R2_SPI_ERASE_PARAM(1 << 14)
#define R2_SPI_OUT_OF_RANGE(1 << 15)/* or CSD overwrite */
#define R2_SPI_CSD_OVERWRITER2_SPI_OUT_OF_RANGE
/* These are unpacked versions of the actual responses */
struct _mmc_csd {
UInt8 csd_structure;
UInt8 spec_vers;
UInt8 taac;
UInt8 nsac;
UInt8 tran_speed;
UInt16 ccc;
UInt8 read_bl_len;
UInt8 read_bl_partial;
UInt8 write_blk_misalign;
UInt8 read_blk_misalign;
UInt8 dsr_imp;
UInt16 c_size;
UInt8 vdd_r_curr_min;
UInt8 vdd_r_curr_max;
UInt8 vdd_w_curr_min;
UInt8 vdd_w_curr_max;
UInt8 c_size_mult;
union {
struct { /* MMC system specification version 3.1 */
UInt8 erase_grp_size;
UInt8 erase_grp_mult;
} v31;
struct { /* MMC system specification version 2.2 */
UInt8 sector_size;
UInt8 erase_grp_size;
} v22;
} erase;
UInt8 wp_grp_size;
UInt8 wp_grp_enable;
UInt8 default_ecc;
UInt8 r2w_factor;
UInt8 write_bl_len;
UInt8 write_bl_partial;
UInt8 file_format_grp;
UInt8 copy;
UInt8 perm_write_protect;
UInt8 tmp_write_protect;
UInt8 file_format;
UInt8 ecc;
};
/*
* OCR bits are mostly in host.h
*/
#define MMC_CARD_BUSY0x80000000/* Card Power up status bit */
/*
* Card Command Classes (CCC)
*/
#define CCC_BASIC(1<<0)/* (0) Basic protocol functions */
/* (CMD0,1,2,3,4,7,9,10,12,13,15) */
/* (and for SPI, CMD58,59) */
#define CCC_STREAM_READ(1<<1)/* (1) Stream read commands */
/* (CMD11) */
#define CCC_BLOCK_READ(1<<2)/* (2) Block read commands */
/* (CMD16,17,18) */
#define CCC_STREAM_WRITE(1<<3)/* (3) Stream write commands */
/* (CMD20) */
#define CCC_BLOCK_WRITE(1<<4)/* (4) Block write commands */
/* (CMD16,24,25,26,27) */
#define CCC_ERASE(1<<5)/* (5) Ability to erase blocks */
/* (CMD32,33,34,35,36,37,38,39) */
#define CCC_WRITE_PROT(1<<6)/* (6) Able to write protect blocks */
/* (CMD28,29,30) */
#define CCC_LOCK_CARD(1<<7)/* (7) Able to lock down card */
/* (CMD16,CMD42) */
#define CCC_APP_SPEC(1<<8)/* (8) Application specific */
/* (CMD55,56,57,ACMD*) */
#define CCC_IO_MODE(1<<9)/* (9) I/O mode */
/* (CMD5,39,40,52,53) */
#define CCC_SWITCH(1<<10)/* (10) High speed switch */
/* (CMD6,34,35,36,37,50) */
/* (11) Reserved */
/* (CMD?) */
/*
* CSD field definitions
*/
#define CSD_STRUCT_VER_1_0 0 /* Valid for system specification 1.0 - 1.2 */
#define CSD_STRUCT_VER_1_1 1 /* Valid for system specification 1.4 - 2.2 */
#define CSD_STRUCT_VER_1_2 2 /* Valid for system specification 3.1 - 3.2 - 3.31 - 4.0 - 4.1 */
#define CSD_STRUCT_EXT_CSD 3 /* Version is coded in CSD_STRUCTURE in EXT_CSD */
#define CSD_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.2 */
#define CSD_SPEC_VER_1 1 /* Implements system specification 1.4 */
#define CSD_SPEC_VER_2 2 /* Implements system specification 2.0 - 2.2 */
#define CSD_SPEC_VER_3 3 /* Implements system specification 3.1 - 3.2 - 3.31 */
#define CSD_SPEC_VER_4 4 /* Implements system specification 4.0 - 4.1 */
/*
* EXT_CSD fields
*/
#define EXT_CSD_BUS_WIDTH183/* R/W */
#define EXT_CSD_HS_TIMING185/* R/W */
#define EXT_CSD_CARD_TYPE196/* RO */
#define EXT_CSD_REV192/* RO */
#define EXT_CSD_SEC_CNT212/* RO, 4 bytes */
/*
* EXT_CSD field definitions
*/
#define EXT_CSD_CMD_SET_NORMAL(1<<0)
#define EXT_CSD_CMD_SET_SECURE(1<<1)
#define EXT_CSD_CMD_SET_CPSECURE(1<<2)
#define EXT_CSD_CARD_TYPE_26(1<<0)/* Card can run at 26MHz */
#define EXT_CSD_CARD_TYPE_52(1<<1)/* Card can run at 52MHz */
#define EXT_CSD_BUS_WIDTH_10/* Card is in 1 bit mode */
#define EXT_CSD_BUS_WIDTH_41/* Card is in 4 bit mode */
#define EXT_CSD_BUS_WIDTH_82/* Card is in 8 bit mode */
/*
* MMC_SWITCH access modes
*/
#define MMC_SWITCH_MODE_CMD_SET0x00/* Change the command set */
#define MMC_SWITCH_MODE_SET_BITS0x01/* Set bits which are 1 in value */
#define MMC_SWITCH_MODE_CLEAR_BITS0x02/* Clear bits which are 1 in value */
#define MMC_SWITCH_MODE_WRITE_BYTE0x03/* Set target to value */
/*
* SD_SWITCH argument format:
*
* [31] Check (0) or switch (1)
* [30:24] Reserved (0)
* [23:20] Function group 6
* [19:16] Function group 5
* [15:12] Function group 4
* [11:8] Function group 3
* [7:4] Function group 2
* [3:0] Function group 1
*/
/*
* SD_SEND_IF_COND argument format:
*
*[31:12] Reserved (0)
*[11:8] Host Voltage Supply Flags
*[7:0] Check Pattern (0xAA)
*/
/*
* SCR field definitions
*/
#define SCR_SPEC_VER_00/* Implements system specification 1.0 - 1.01 */
#define SCR_SPEC_VER_11/* Implements system specification 1.10 */
#define SCR_SPEC_VER_22/* Implements system specification 2.00 */
/*
* SD bus widths
*/
#define SD_BUS_WIDTH_10
#define SD_BUS_WIDTH_42
/*
* SD_SWITCH mode
*/
#define SD_SWITCH_CHECK0
#define SD_SWITCH_SET1
/*
* SD_SWITCH function groups
*/
#define SD_SWITCH_GRP_ACCESS0
/*
* SD_SWITCH access modes
*/
#define SD_SWITCH_ACCESS_DEF0
#define SD_SWITCH_ACCESS_HS1
/**********************************/
/* From original SDHCI OSX driver */
/**********************************/
#define R00
#define R11
#define R1b2
#define R23
#define R34
#define R45
#define R56
#define R5b 7
#define R68
#define R79
#define SDCR0R0
#define SDCR1R0
#define SDCR2R2
#define SDCR3R6
#define SDCR4R0
#define SDCR5R0
#define SDCR6R1
#define SDCR7R1b
#define SDCR8R7
#define SDCR9R2
#define SDCR10R2
#define SDCR11R0
#define SDCR12R1b
#define SDCR13R1
#define SDCR14R0
#define SDCR15R0
#define SDCR16R1
#define SDCR17R1
#define SDCR18R1
#define SDCR19R0
#define SDCR20R0
#define SDCR21R0
#define SDCR22R0
#define SDCR23R0
#define SDCR24R1
#define SDCR25R1
#define SDCR26R0
#define SDCR27R1
#define SDCR28R1b
#define SDCR29R1b
#define SDCR30R1
#define SDCR31R0
#define SDCR32R1
#define SDCR33R1
#define SDCR34R0
#define SDCR35R0
#define SDCR36R0
#define SDCR37R0
#define SDCR38R1b
#define SDCR39R0
#define SDCR40R0
#define SDCR41R0
#define SDCR42R1
#define SDCR43R0
#define SDCR44R0
#define SDCR45R0
#define SDCR46R0
#define SDCR47R0
#define SDCR48R0
#define SDCR49R0
#define SDCR50R0
#define SDCR51R0
#define SDCR52R0
#define SDCR53R0
#define SDCR54R0
#define SDCR55R1
#define SDCR56R1
#define SDCR57R0
#define SDCR58R0
#define SDCR59R0
#define SDCR60R0
#define SDCR61R0
#define SDCR62R0
#define SDCR63R0
#define SDACR0R0
#define SDACR1R0
#define SDACR2R0
#define SDACR3R0
#define SDACR4R0
#define SDACR5R0
#define SDACR6R1
#define SDACR7R0
#define SDACR8R0
#define SDACR9R0
#define SDACR10R0
#define SDACR11R0
#define SDACR12R0
#define SDACR13R1
#define SDACR14R0
#define SDACR15R0
#define SDACR16R0
#define SDACR17R0
#define SDACR18R0
#define SDACR19R0
#define SDACR20R0
#define SDACR21R1
#define SDACR22R1
#define SDACR23R0
#define SDACR24R0
#define SDACR25R0
#define SDACR26R0
#define SDACR27R0
#define SDACR28R0
#define SDACR29R0
#define SDACR30R0
#define SDACR31R0
#define SDACR32R0
#define SDACR33R0
#define SDACR34R0
#define SDACR35R0
#define SDACR36R0
#define SDACR37R0
#define SDACR38R0
#define SDACR39R0
#define SDACR40R0
#define SDACR41R3
#define SDACR42R1
#define SDACR43R0
#define SDACR44R0
#define SDACR45R0
#define SDACR46R0
#define SDACR47R0
#define SDACR48R0
#define SDACR49R0
#define SDACR50R0
#define SDACR51R1
#define SDACR52R0
#define SDACR53R0
#define SDACR54R0
#define SDACR55R0
#define SDACR56R0
#define SDACR57R0
#define SDACR58R0
#define SDACR59R0
#define SDACR60R0
#define SDACR61R0
#define SDACR62R0
#define SDACR63R0
#endif /* SD_H */
trunk/VoodooSDHC.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#ifndef _VoodooSDHC_H_
#define _VoodooSDHC_H_
#include "License.h"
#define SLOT1 0
#define SLOT2 1
#define SLOT3 2
#define SLOT4 3
#define SLOT5 4
#define SLOT6 5
/* General IOKit includes */
#include <IOKit/IOLib.h>
#include <IOKit/IOMessage.h>
#include <IOKit/IOService.h>
#include <IOKit/IOFilterInterruptEventSource.h>
#include <IOKit/IOTimerEventSource.h>
#include <IOKit/storage/IOBlockStorageDriver.h>
#include <IOKit/storage/IOBlockStorageDevice.h>
#include <IOKit/IOBufferMemoryDescriptor.h>
#include <libkern/locks.h>
#include "SD_DataTypes.h"
class VoodooSDHC : public IOBlockStorageDevice
{
OSDeclareDefaultStructors ( VoodooSDHC )
protected:
public:
// Overrides from IOService
virtual boolinit ( OSDictionary * propertyTable );
virtual voidfree();
virtual bool start ( IOService * provider );
virtual void stop ( IOService * provider );
private:
// This lock protects block I/O access to the card reader
class Lock {
IOLock*mutex_;
boollocked_;
intwaiting_;
public:
void init() {
mutex_ = IOLockAlloc();
locked_ = false;
waiting_ = 0;
}
void free() {
IOLockFree(mutex_);
}
void lock() {
IOLockLock(mutex_);
if (locked_) {
waiting_++;
do {
IOLockSleep(mutex_, mutex_, THREAD_UNINT);
} while (locked_);
waiting_--;
}
locked_ = true;
IOLockUnlock(mutex_);
}
void unlock() {
IOLockLock(mutex_);
locked_ = false;
if (waiting_)
IOLockWakeup(mutex_, mutex_, true);
IOLockUnlock(mutex_);
}
} lock;
#ifdef USE_SDMA
IOLock*sdmaCond; // this lock handles I/O interrupt
IOLock*mediaStateLock; // this lock serializes reportMediaState
IOBufferMemoryDescriptor *sdmaBuffDesc;
UInt32physSdmaBuff;
void*virtSdmaBuff;
IOWorkLoop*workLoop;
IOFilterInterruptEventSource *interruptSrc;
IOTimerEventSource*timerSrc;
virtual IOWorkLoop *getWorkLoop() const { return workLoop; }
#endif
IOMemoryMap*PCIRegMap;
structSDHCIRegMap_t *PCIRegP[6];
structSDCIDReg_t SDCIDReg[6];
UInt32RCA;
UInt32maxBlock;
enum {
kCardNotPresent,
kCardIsPresent,
kCardRemount
} cardPresence;
boolisHighCapacity;
boolsetup(IOService *provider);
voiddumpRegs(UInt8 slot);
boolisCardPresent(UInt8 slot);
boolisCardWP(UInt8 slot);
boolcardInit( UInt8 slot );
voidLEDControl(UInt8 slot, bool state);
voidReset( UInt8 slot, UInt8 type );
boolSDCommand( UInt8 slot, UInt8 command, UInt16 response, UInt32 arg);
boolcalcClock(UInt8 slot, UInt32 clockspeed);
boolpowerSD(UInt8 slot);
voidparseCID(UInt8 slot);
voidparseCSD(UInt8 slot);
//IOReturnrequestIdle(void); /* 10.6.0 */
//IOReturndoDiscard(UInt64 block, UInt64 nblks); /* 10.6.0 */
IOReturnreportRemovability(bool *isRemovable);
IOReturnreportWriteProtection(bool *isWriteProtected);
IOReturnsetWriteCacheState(bool enabled);
IOReturnreportPollRequirements(bool *pollRequired, bool *pollIsExpensive);
IOReturnreportMediaState(bool *mediaPresent, bool *changedState);
IOReturnreportMaxValidBlock(UInt64 *maxBlock);
IOReturnreportLockability(bool *isLockable);
IOReturnreportEjectability(bool *isEjectable);
IOReturnreportBlockSize(UInt64 *blockSize);
IOReturngetWriteCacheState(bool *enabled);
IOReturnsetPowerState( unsigned long whichState, IOService * whatDevice );
char *getVendorString(void);
char *getRevisionString(void);
char *getProductString(void);
char *getAdditionalDeviceInfoString(void);
IOReturndoSynchronizeCache(void);
IOReturndoLockUnlockMedia(bool doLock);
UInt32doGetFormatCapacities(UInt64 *capacities, UInt32 capacitiesMaxCount) const;
IOReturndoFormatMedia(UInt64 byteCapacity);
IOReturndoEjectMedia(void);
#ifdef __LP64__
virtual IOReturndoAsyncReadWrite(IOMemoryDescriptor *buffer,
UInt64 block, UInt64 nblks,
IOStorageAttributes *attributes,
IOStorageCompletion *completion);
#endif
#ifndef __LP64__
IOReturndoAsyncReadWrite(IOMemoryDescriptor *buffer,
UInt32 block, UInt32 nblks,
IOStorageCompletion completion); //completion was start
IOReturnreportMaxWriteTransfer(UInt64 blockSize, UInt64 *max);
IOReturnreportMaxReadTransfer (UInt64 blockSize, UInt64 *max);
#endif
IOReturnsdma_access(IOMemoryDescriptor *buffer, UInt32 block, UInt32 nblks, bool read);
IOReturnreadBlockMulti_pio(IOMemoryDescriptor *buffer, UInt32 block, UInt32 nblks,
UInt32 offset);
IOReturnreadBlockSingle_pio(UInt8 *buff, UInt32 block);
IOReturnwriteBlockMulti_pio(IOMemoryDescriptor *buffer, UInt32 block, UInt32 nblks,
UInt32 offset);
IOReturnwriteBlockSingle_pio(IOMemoryDescriptor *buffer, UInt32 block,
UInt32 offset);
boolwaitIntStatus(UInt32 maskBits);
voidhandleInterrupt();
voidhandleTimer();
static void interruptHandler(OSObject *owner, IOInterruptEventSource *source, int count);
static bool interruptFilter(OSObject *owner, IOFilterInterruptEventSource *source);
static void timerHandler(OSObject *owner, IOTimerEventSource *sender);
};
#endif /* _VoodooSDHC_H_ */

Archive Download the corresponding diff file

Revision: 2