diff options
Diffstat (limited to 'drivers/acpi/resources/rsio.c')
-rw-r--r-- | drivers/acpi/resources/rsio.c | 333 |
1 files changed, 135 insertions, 198 deletions
diff --git a/drivers/acpi/resources/rsio.c b/drivers/acpi/resources/rsio.c index 0dab8cdfa800..ef24ba110c6e 100644 --- a/drivers/acpi/resources/rsio.c +++ b/drivers/acpi/resources/rsio.c | |||
@@ -49,269 +49,206 @@ ACPI_MODULE_NAME("rsio") | |||
49 | 49 | ||
50 | /******************************************************************************* | 50 | /******************************************************************************* |
51 | * | 51 | * |
52 | * FUNCTION: acpi_rs_get_io | 52 | * acpi_rs_convert_io |
53 | * | ||
54 | * PARAMETERS: Aml - Pointer to the AML resource descriptor | ||
55 | * aml_resource_length - Length of the resource from the AML header | ||
56 | * Resource - Where the internal resource is returned | ||
57 | * | ||
58 | * RETURN: Status | ||
59 | * | ||
60 | * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding | ||
61 | * internal resource descriptor, simplifying bitflags and handling | ||
62 | * alignment and endian issues if necessary. | ||
63 | * | 53 | * |
64 | ******************************************************************************/ | 54 | ******************************************************************************/ |
65 | acpi_status | 55 | struct acpi_rsconvert_info acpi_rs_convert_io[5] = { |
66 | acpi_rs_get_io(union aml_resource *aml, | 56 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_IO, |
67 | u16 aml_resource_length, struct acpi_resource *resource) | 57 | ACPI_RS_SIZE(struct acpi_resource_io), |
68 | { | 58 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_io)}, |
69 | ACPI_FUNCTION_TRACE("rs_get_io"); | ||
70 | 59 | ||
71 | /* Get the Decode flag */ | 60 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_IO, |
61 | sizeof(struct aml_resource_io), | ||
62 | 0}, | ||
72 | 63 | ||
73 | resource->data.io.io_decode = aml->io.information & 0x01; | 64 | /* Decode flag */ |
74 | 65 | ||
66 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.io.io_decode), | ||
67 | AML_OFFSET(io.flags), | ||
68 | 0}, | ||
75 | /* | 69 | /* |
76 | * Get the following contiguous fields from the AML descriptor: | 70 | * These fields are contiguous in both the source and destination: |
77 | * Minimum Base Address | ||
78 | * Maximum Base Address | ||
79 | * Address Alignment | 71 | * Address Alignment |
80 | * Length | 72 | * Length |
73 | * Minimum Base Address | ||
74 | * Maximum Base Address | ||
81 | */ | 75 | */ |
82 | ACPI_MOVE_16_TO_32(&resource->data.io.minimum, &aml->io.minimum); | 76 | {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.io.alignment), |
83 | ACPI_MOVE_16_TO_32(&resource->data.io.maximum, &aml->io.maximum); | 77 | AML_OFFSET(io.alignment), |
84 | resource->data.io.alignment = aml->io.alignment; | 78 | 2}, |
85 | resource->data.io.address_length = aml->io.address_length; | ||
86 | |||
87 | /* Complete the resource header */ | ||
88 | 79 | ||
89 | resource->type = ACPI_RESOURCE_TYPE_IO; | 80 | {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.io.minimum), |
90 | resource->length = ACPI_SIZEOF_RESOURCE(struct acpi_resource_io); | 81 | AML_OFFSET(io.minimum), |
91 | return_ACPI_STATUS(AE_OK); | 82 | 2} |
92 | } | 83 | }; |
93 | 84 | ||
94 | /******************************************************************************* | 85 | /******************************************************************************* |
95 | * | 86 | * |
96 | * FUNCTION: acpi_rs_set_io | 87 | * acpi_rs_convert_fixed_io |
97 | * | ||
98 | * PARAMETERS: Resource - Pointer to the resource descriptor | ||
99 | * Aml - Where the AML descriptor is returned | ||
100 | * | ||
101 | * RETURN: Status | ||
102 | * | ||
103 | * DESCRIPTION: Convert an internal resource descriptor to the corresponding | ||
104 | * external AML resource descriptor. | ||
105 | * | 88 | * |
106 | ******************************************************************************/ | 89 | ******************************************************************************/ |
107 | 90 | ||
108 | acpi_status | 91 | struct acpi_rsconvert_info acpi_rs_convert_fixed_io[4] = { |
109 | acpi_rs_set_io(struct acpi_resource *resource, union aml_resource *aml) | 92 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_FIXED_IO, |
110 | { | 93 | ACPI_RS_SIZE(struct acpi_resource_fixed_io), |
111 | ACPI_FUNCTION_TRACE("rs_set_io"); | 94 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_fixed_io)}, |
112 | |||
113 | /* I/O Information Byte */ | ||
114 | |||
115 | aml->io.information = (u8) (resource->data.io.io_decode & 0x01); | ||
116 | 95 | ||
96 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_FIXED_IO, | ||
97 | sizeof(struct aml_resource_fixed_io), | ||
98 | 0}, | ||
117 | /* | 99 | /* |
118 | * Set the following contiguous fields in the AML descriptor: | 100 | * These fields are contiguous in both the source and destination: |
119 | * Minimum Base Address | 101 | * Base Address |
120 | * Maximum Base Address | ||
121 | * Address Alignment | ||
122 | * Length | 102 | * Length |
123 | */ | 103 | */ |
124 | ACPI_MOVE_32_TO_16(&aml->io.minimum, &resource->data.io.minimum); | 104 | {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.fixed_io.address_length), |
125 | ACPI_MOVE_32_TO_16(&aml->io.maximum, &resource->data.io.maximum); | 105 | AML_OFFSET(fixed_io.address_length), |
126 | aml->io.alignment = (u8) resource->data.io.alignment; | 106 | 1}, |
127 | aml->io.address_length = (u8) resource->data.io.address_length; | ||
128 | |||
129 | /* Complete the AML descriptor header */ | ||
130 | 107 | ||
131 | acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_IO, | 108 | {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.fixed_io.address), |
132 | sizeof(struct aml_resource_io), aml); | 109 | AML_OFFSET(fixed_io.address), |
133 | return_ACPI_STATUS(AE_OK); | 110 | 1} |
134 | } | 111 | }; |
135 | 112 | ||
136 | /******************************************************************************* | 113 | /******************************************************************************* |
137 | * | 114 | * |
138 | * FUNCTION: acpi_rs_get_fixed_io | 115 | * acpi_rs_convert_generic_reg |
139 | * | ||
140 | * PARAMETERS: Aml - Pointer to the AML resource descriptor | ||
141 | * aml_resource_length - Length of the resource from the AML header | ||
142 | * Resource - Where the internal resource is returned | ||
143 | * | ||
144 | * RETURN: Status | ||
145 | * | ||
146 | * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding | ||
147 | * internal resource descriptor, simplifying bitflags and handling | ||
148 | * alignment and endian issues if necessary. | ||
149 | * | 116 | * |
150 | ******************************************************************************/ | 117 | ******************************************************************************/ |
151 | 118 | ||
152 | acpi_status | 119 | struct acpi_rsconvert_info acpi_rs_convert_generic_reg[4] = { |
153 | acpi_rs_get_fixed_io(union aml_resource *aml, | 120 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_GENERIC_REGISTER, |
154 | u16 aml_resource_length, struct acpi_resource *resource) | 121 | ACPI_RS_SIZE(struct acpi_resource_generic_register), |
155 | { | 122 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_generic_reg)}, |
156 | ACPI_FUNCTION_TRACE("rs_get_fixed_io"); | ||
157 | 123 | ||
124 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_GENERIC_REGISTER, | ||
125 | sizeof(struct aml_resource_generic_register), | ||
126 | 0}, | ||
158 | /* | 127 | /* |
159 | * Get the following contiguous fields from the AML descriptor: | 128 | * These fields are contiguous in both the source and destination: |
160 | * Base Address | 129 | * Address Space ID |
161 | * Length | 130 | * Register Bit Width |
131 | * Register Bit Offset | ||
132 | * Access Size | ||
162 | */ | 133 | */ |
163 | ACPI_MOVE_16_TO_32(&resource->data.fixed_io.address, | 134 | {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.generic_reg.space_id), |
164 | &aml->fixed_io.address); | 135 | AML_OFFSET(generic_reg.address_space_id), |
165 | resource->data.fixed_io.address_length = aml->fixed_io.address_length; | 136 | 4}, |
166 | 137 | ||
167 | /* Complete the resource header */ | 138 | /* Get the Register Address */ |
168 | 139 | ||
169 | resource->type = ACPI_RESOURCE_TYPE_FIXED_IO; | 140 | {ACPI_RSC_MOVE64, ACPI_RS_OFFSET(data.generic_reg.address), |
170 | resource->length = ACPI_SIZEOF_RESOURCE(struct acpi_resource_fixed_io); | 141 | AML_OFFSET(generic_reg.address), |
171 | return_ACPI_STATUS(AE_OK); | 142 | 1} |
172 | } | 143 | }; |
173 | 144 | ||
174 | /******************************************************************************* | 145 | /******************************************************************************* |
175 | * | 146 | * |
176 | * FUNCTION: acpi_rs_set_fixed_io | 147 | * acpi_rs_convert_end_dpf |
177 | * | ||
178 | * PARAMETERS: Resource - Pointer to the resource descriptor | ||
179 | * Aml - Where the AML descriptor is returned | ||
180 | * | 148 | * |
181 | * RETURN: Status | 149 | ******************************************************************************/ |
150 | |||
151 | struct acpi_rsconvert_info acpi_rs_convert_end_dpf[2] = { | ||
152 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_END_DEPENDENT, | ||
153 | ACPI_RS_SIZE_MIN, | ||
154 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_end_dpf)}, | ||
155 | |||
156 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_END_DEPENDENT, | ||
157 | sizeof(struct aml_resource_end_dependent), | ||
158 | 0} | ||
159 | }; | ||
160 | |||
161 | /******************************************************************************* | ||
182 | * | 162 | * |
183 | * DESCRIPTION: Convert an internal resource descriptor to the corresponding | 163 | * acpi_rs_convert_end_tag |
184 | * external AML resource descriptor. | ||
185 | * | 164 | * |
186 | ******************************************************************************/ | 165 | ******************************************************************************/ |
187 | 166 | ||
188 | acpi_status | 167 | struct acpi_rsconvert_info acpi_rs_convert_end_tag[2] = { |
189 | acpi_rs_set_fixed_io(struct acpi_resource *resource, union aml_resource *aml) | 168 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_END_TAG, |
190 | { | 169 | ACPI_RS_SIZE_MIN, |
191 | ACPI_FUNCTION_TRACE("rs_set_fixed_io"); | 170 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_end_tag)}, |
192 | 171 | ||
193 | /* | 172 | /* |
194 | * Set the following contiguous fields in the AML descriptor: | 173 | * Note: The checksum field is set to zero, meaning that the resource |
195 | * Base Address | 174 | * data is treated as if the checksum operation succeeded. |
196 | * Length | 175 | * (ACPI Spec 1.0b Section 6.4.2.8) |
197 | */ | 176 | */ |
198 | ACPI_MOVE_32_TO_16(&aml->fixed_io.address, | 177 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_END_TAG, |
199 | &resource->data.fixed_io.address); | 178 | sizeof(struct aml_resource_end_tag), |
200 | aml->fixed_io.address_length = | 179 | 0} |
201 | (u8) resource->data.fixed_io.address_length; | 180 | }; |
202 | |||
203 | /* Complete the AML descriptor header */ | ||
204 | |||
205 | acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_FIXED_IO, | ||
206 | sizeof(struct aml_resource_fixed_io), aml); | ||
207 | return_ACPI_STATUS(AE_OK); | ||
208 | } | ||
209 | 181 | ||
210 | /******************************************************************************* | 182 | /******************************************************************************* |
211 | * | 183 | * |
212 | * FUNCTION: acpi_rs_get_dma | 184 | * acpi_rs_get_start_dpf |
213 | * | ||
214 | * PARAMETERS: Aml - Pointer to the AML resource descriptor | ||
215 | * aml_resource_length - Length of the resource from the AML header | ||
216 | * Resource - Where the internal resource is returned | ||
217 | * | ||
218 | * RETURN: Status | ||
219 | * | ||
220 | * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding | ||
221 | * internal resource descriptor, simplifying bitflags and handling | ||
222 | * alignment and endian issues if necessary. | ||
223 | * | 185 | * |
224 | ******************************************************************************/ | 186 | ******************************************************************************/ |
225 | 187 | ||
226 | acpi_status | 188 | struct acpi_rsconvert_info acpi_rs_get_start_dpf[5] = { |
227 | acpi_rs_get_dma(union aml_resource *aml, | 189 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_START_DEPENDENT, |
228 | u16 aml_resource_length, struct acpi_resource *resource) | 190 | ACPI_RS_SIZE(struct acpi_resource_start_dependent), |
229 | { | 191 | ACPI_RSC_TABLE_SIZE(acpi_rs_get_start_dpf)}, |
230 | u32 channel_count = 0; | ||
231 | u32 i; | ||
232 | u8 temp8; | ||
233 | 192 | ||
234 | ACPI_FUNCTION_TRACE("rs_get_dma"); | 193 | /* Defaults for Compatibility and Performance priorities */ |
235 | 194 | ||
236 | /* Decode the DMA channel bits */ | 195 | {ACPI_RSC_SET8, ACPI_RS_OFFSET(data.start_dpf.compatibility_priority), |
196 | ACPI_ACCEPTABLE_CONFIGURATION, | ||
197 | 2}, | ||
237 | 198 | ||
238 | for (i = 0; i < 8; i++) { | 199 | /* All done if there is no flag byte present in the descriptor */ |
239 | if ((aml->dma.dma_channel_mask >> i) & 0x01) { | ||
240 | resource->data.dma.channels[channel_count] = i; | ||
241 | channel_count++; | ||
242 | } | ||
243 | } | ||
244 | 200 | ||
245 | resource->length = 0; | 201 | {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_AML_LENGTH, 0, 1}, |
246 | resource->data.dma.channel_count = channel_count; | ||
247 | 202 | ||
248 | /* | 203 | /* Flag byte is present, get the flags */ |
249 | * Calculate the structure size based upon the number of channels | ||
250 | * Note: Zero DMA channels is valid | ||
251 | */ | ||
252 | if (channel_count > 0) { | ||
253 | resource->length = (u32) (channel_count - 1) * 4; | ||
254 | } | ||
255 | |||
256 | /* Get the flags: transfer preference, bus mastering, channel speed */ | ||
257 | 204 | ||
258 | temp8 = aml->dma.flags; | 205 | {ACPI_RSC_2BITFLAG, |
259 | resource->data.dma.transfer = temp8 & 0x03; | 206 | ACPI_RS_OFFSET(data.start_dpf.compatibility_priority), |
260 | resource->data.dma.bus_master = (temp8 >> 2) & 0x01; | 207 | AML_OFFSET(start_dpf.flags), |
261 | resource->data.dma.type = (temp8 >> 5) & 0x03; | 208 | 0}, |
262 | 209 | ||
263 | if (resource->data.dma.transfer == 0x03) { | 210 | {ACPI_RSC_2BITFLAG, |
264 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 211 | ACPI_RS_OFFSET(data.start_dpf.performance_robustness), |
265 | "Invalid DMA.Transfer preference (3)\n")); | 212 | AML_OFFSET(start_dpf.flags), |
266 | return_ACPI_STATUS(AE_BAD_DATA); | 213 | 2} |
267 | } | 214 | }; |
268 | |||
269 | /* Complete the resource header */ | ||
270 | |||
271 | resource->type = ACPI_RESOURCE_TYPE_DMA; | ||
272 | resource->length += ACPI_SIZEOF_RESOURCE(struct acpi_resource_dma); | ||
273 | return_ACPI_STATUS(AE_OK); | ||
274 | } | ||
275 | 215 | ||
276 | /******************************************************************************* | 216 | /******************************************************************************* |
277 | * | 217 | * |
278 | * FUNCTION: acpi_rs_set_dma | 218 | * acpi_rs_set_start_dpf |
279 | * | ||
280 | * PARAMETERS: Resource - Pointer to the resource descriptor | ||
281 | * Aml - Where the AML descriptor is returned | ||
282 | * | ||
283 | * RETURN: Status | ||
284 | * | ||
285 | * DESCRIPTION: Convert an internal resource descriptor to the corresponding | ||
286 | * external AML resource descriptor. | ||
287 | * | 219 | * |
288 | ******************************************************************************/ | 220 | ******************************************************************************/ |
289 | 221 | ||
290 | acpi_status | 222 | struct acpi_rsconvert_info acpi_rs_set_start_dpf[6] = { |
291 | acpi_rs_set_dma(struct acpi_resource *resource, union aml_resource *aml) | 223 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_START_DEPENDENT, |
292 | { | 224 | sizeof(struct aml_resource_start_dependent), |
293 | u8 i; | 225 | ACPI_RSC_TABLE_SIZE(acpi_rs_set_start_dpf)}, |
294 | |||
295 | ACPI_FUNCTION_TRACE("rs_set_dma"); | ||
296 | 226 | ||
297 | /* Convert channel list to 8-bit DMA channel bitmask */ | 227 | /* Set the default flag values */ |
298 | 228 | ||
299 | aml->dma.dma_channel_mask = 0; | 229 | {ACPI_RSC_2BITFLAG, |
300 | for (i = 0; i < resource->data.dma.channel_count; i++) { | 230 | ACPI_RS_OFFSET(data.start_dpf.compatibility_priority), |
301 | aml->dma.dma_channel_mask |= | 231 | AML_OFFSET(start_dpf.flags), |
302 | (1 << resource->data.dma.channels[i]); | 232 | 0}, |
303 | } | ||
304 | 233 | ||
305 | /* Set the DMA Flag bits */ | 234 | {ACPI_RSC_2BITFLAG, |
235 | ACPI_RS_OFFSET(data.start_dpf.performance_robustness), | ||
236 | AML_OFFSET(start_dpf.flags), | ||
237 | 2}, | ||
238 | /* | ||
239 | * All done if flags byte is necessary -- if either priority value | ||
240 | * is not ACPI_ACCEPTABLE_CONFIGURATION | ||
241 | */ | ||
242 | {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE, | ||
243 | ACPI_RS_OFFSET(data.start_dpf.compatibility_priority), | ||
244 | ACPI_ACCEPTABLE_CONFIGURATION}, | ||
306 | 245 | ||
307 | aml->dma.flags = (u8) | 246 | {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE, |
308 | (((resource->data.dma.type & 0x03) << 5) | | 247 | ACPI_RS_OFFSET(data.start_dpf.performance_robustness), |
309 | ((resource->data.dma.bus_master & 0x01) << 2) | | 248 | ACPI_ACCEPTABLE_CONFIGURATION}, |
310 | (resource->data.dma.transfer & 0x03)); | ||
311 | 249 | ||
312 | /* Complete the AML descriptor header */ | 250 | /* Flag byte is not necessary */ |
313 | 251 | ||
314 | acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_DMA, | 252 | {ACPI_RSC_LENGTH, 0, 0, |
315 | sizeof(struct aml_resource_dma), aml); | 253 | sizeof(struct aml_resource_start_dependent_noprio)} |
316 | return_ACPI_STATUS(AE_OK); | 254 | }; |
317 | } | ||