Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.13-rc2 528 lines 16 kB view raw
1 2/****************************************************************************** 3 * 4 * Module Name: exregion - ACPI default op_region (address space) handlers 5 * 6 *****************************************************************************/ 7 8/* 9 * Copyright (C) 2000 - 2005, R. Byron Moore 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions, and the following disclaimer, 17 * without modification. 18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19 * substantially similar to the "NO WARRANTY" disclaimer below 20 * ("Disclaimer") and any redistribution must be conditioned upon 21 * including a substantially similar Disclaimer requirement for further 22 * binary redistribution. 23 * 3. Neither the names of the above-listed copyright holders nor the names 24 * of any contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * Alternatively, this software may be distributed under the terms of the 28 * GNU General Public License ("GPL") version 2 as published by the Free 29 * Software Foundation. 30 * 31 * NO WARRANTY 32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42 * POSSIBILITY OF SUCH DAMAGES. 43 */ 44 45 46#include <acpi/acpi.h> 47#include <acpi/acinterp.h> 48 49 50#define _COMPONENT ACPI_EXECUTER 51 ACPI_MODULE_NAME ("exregion") 52 53 54/******************************************************************************* 55 * 56 * FUNCTION: acpi_ex_system_memory_space_handler 57 * 58 * PARAMETERS: Function - Read or Write operation 59 * Address - Where in the space to read or write 60 * bit_width - Field width in bits (8, 16, or 32) 61 * Value - Pointer to in or out value 62 * handler_context - Pointer to Handler's context 63 * region_context - Pointer to context specific to the 64 * accessed region 65 * 66 * RETURN: Status 67 * 68 * DESCRIPTION: Handler for the System Memory address space (Op Region) 69 * 70 ******************************************************************************/ 71 72acpi_status 73acpi_ex_system_memory_space_handler ( 74 u32 function, 75 acpi_physical_address address, 76 u32 bit_width, 77 acpi_integer *value, 78 void *handler_context, 79 void *region_context) 80{ 81 acpi_status status = AE_OK; 82 void *logical_addr_ptr = NULL; 83 struct acpi_mem_space_context *mem_info = region_context; 84 u32 length; 85 acpi_size window_size; 86#ifndef ACPI_MISALIGNED_TRANSFERS 87 u32 remainder; 88#endif 89 90 ACPI_FUNCTION_TRACE ("ex_system_memory_space_handler"); 91 92 93 /* Validate and translate the bit width */ 94 95 switch (bit_width) { 96 case 8: 97 length = 1; 98 break; 99 100 case 16: 101 length = 2; 102 break; 103 104 case 32: 105 length = 4; 106 break; 107 108 case 64: 109 length = 8; 110 break; 111 112 default: 113 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid system_memory width %d\n", 114 bit_width)); 115 return_ACPI_STATUS (AE_AML_OPERAND_VALUE); 116 } 117 118 119#ifndef ACPI_MISALIGNED_TRANSFERS 120 /* 121 * Hardware does not support non-aligned data transfers, we must verify 122 * the request. 123 */ 124 (void) acpi_ut_short_divide ((acpi_integer) address, length, NULL, &remainder); 125 if (remainder != 0) { 126 return_ACPI_STATUS (AE_AML_ALIGNMENT); 127 } 128#endif 129 130 /* 131 * Does the request fit into the cached memory mapping? 132 * Is 1) Address below the current mapping? OR 133 * 2) Address beyond the current mapping? 134 */ 135 if ((address < mem_info->mapped_physical_address) || 136 (((acpi_integer) address + length) > 137 ((acpi_integer) mem_info->mapped_physical_address + mem_info->mapped_length))) { 138 /* 139 * The request cannot be resolved by the current memory mapping; 140 * Delete the existing mapping and create a new one. 141 */ 142 if (mem_info->mapped_length) { 143 /* Valid mapping, delete it */ 144 145 acpi_os_unmap_memory (mem_info->mapped_logical_address, 146 mem_info->mapped_length); 147 } 148 149 /* 150 * Don't attempt to map memory beyond the end of the region, and 151 * constrain the maximum mapping size to something reasonable. 152 */ 153 window_size = (acpi_size) ((mem_info->address + mem_info->length) - address); 154 if (window_size > ACPI_SYSMEM_REGION_WINDOW_SIZE) { 155 window_size = ACPI_SYSMEM_REGION_WINDOW_SIZE; 156 } 157 158 /* Create a new mapping starting at the address given */ 159 160 status = acpi_os_map_memory (address, window_size, 161 (void **) &mem_info->mapped_logical_address); 162 if (ACPI_FAILURE (status)) { 163 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %8.8X%8.8X, size %X\n", 164 ACPI_FORMAT_UINT64 (address), (u32) window_size)); 165 mem_info->mapped_length = 0; 166 return_ACPI_STATUS (status); 167 } 168 169 /* Save the physical address and mapping size */ 170 171 mem_info->mapped_physical_address = address; 172 mem_info->mapped_length = window_size; 173 } 174 175 /* 176 * Generate a logical pointer corresponding to the address we want to 177 * access 178 */ 179 logical_addr_ptr = mem_info->mapped_logical_address + 180 ((acpi_integer) address - (acpi_integer) mem_info->mapped_physical_address); 181 182 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 183 "system_memory %d (%d width) Address=%8.8X%8.8X\n", function, bit_width, 184 ACPI_FORMAT_UINT64 (address))); 185 186 /* 187 * Perform the memory read or write 188 * 189 * Note: For machines that do not support non-aligned transfers, the target 190 * address was checked for alignment above. We do not attempt to break the 191 * transfer up into smaller (byte-size) chunks because the AML specifically 192 * asked for a transfer width that the hardware may require. 193 */ 194 switch (function) { 195 case ACPI_READ: 196 197 *value = 0; 198 switch (bit_width) { 199 case 8: 200 *value = (acpi_integer) *((u8 *) logical_addr_ptr); 201 break; 202 203 case 16: 204 *value = (acpi_integer) *((u16 *) logical_addr_ptr); 205 break; 206 207 case 32: 208 *value = (acpi_integer) *((u32 *) logical_addr_ptr); 209 break; 210 211#if ACPI_MACHINE_WIDTH != 16 212 case 64: 213 *value = (acpi_integer) *((u64 *) logical_addr_ptr); 214 break; 215#endif 216 default: 217 /* bit_width was already validated */ 218 break; 219 } 220 break; 221 222 case ACPI_WRITE: 223 224 switch (bit_width) { 225 case 8: 226 *(u8 *) logical_addr_ptr = (u8) *value; 227 break; 228 229 case 16: 230 *(u16 *) logical_addr_ptr = (u16) *value; 231 break; 232 233 case 32: 234 *(u32 *) logical_addr_ptr = (u32) *value; 235 break; 236 237#if ACPI_MACHINE_WIDTH != 16 238 case 64: 239 *(u64 *) logical_addr_ptr = (u64) *value; 240 break; 241#endif 242 243 default: 244 /* bit_width was already validated */ 245 break; 246 } 247 break; 248 249 default: 250 status = AE_BAD_PARAMETER; 251 break; 252 } 253 254 return_ACPI_STATUS (status); 255} 256 257 258/******************************************************************************* 259 * 260 * FUNCTION: acpi_ex_system_io_space_handler 261 * 262 * PARAMETERS: Function - Read or Write operation 263 * Address - Where in the space to read or write 264 * bit_width - Field width in bits (8, 16, or 32) 265 * Value - Pointer to in or out value 266 * handler_context - Pointer to Handler's context 267 * region_context - Pointer to context specific to the 268 * accessed region 269 * 270 * RETURN: Status 271 * 272 * DESCRIPTION: Handler for the System IO address space (Op Region) 273 * 274 ******************************************************************************/ 275 276acpi_status 277acpi_ex_system_io_space_handler ( 278 u32 function, 279 acpi_physical_address address, 280 u32 bit_width, 281 acpi_integer *value, 282 void *handler_context, 283 void *region_context) 284{ 285 acpi_status status = AE_OK; 286 u32 value32; 287 288 289 ACPI_FUNCTION_TRACE ("ex_system_io_space_handler"); 290 291 292 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 293 "system_iO %d (%d width) Address=%8.8X%8.8X\n", function, bit_width, 294 ACPI_FORMAT_UINT64 (address))); 295 296 /* Decode the function parameter */ 297 298 switch (function) { 299 case ACPI_READ: 300 301 status = acpi_os_read_port ((acpi_io_address) address, &value32, bit_width); 302 *value = value32; 303 break; 304 305 case ACPI_WRITE: 306 307 status = acpi_os_write_port ((acpi_io_address) address, (u32) *value, bit_width); 308 break; 309 310 default: 311 status = AE_BAD_PARAMETER; 312 break; 313 } 314 315 return_ACPI_STATUS (status); 316} 317 318 319/******************************************************************************* 320 * 321 * FUNCTION: acpi_ex_pci_config_space_handler 322 * 323 * PARAMETERS: Function - Read or Write operation 324 * Address - Where in the space to read or write 325 * bit_width - Field width in bits (8, 16, or 32) 326 * Value - Pointer to in or out value 327 * handler_context - Pointer to Handler's context 328 * region_context - Pointer to context specific to the 329 * accessed region 330 * 331 * RETURN: Status 332 * 333 * DESCRIPTION: Handler for the PCI Config address space (Op Region) 334 * 335 ******************************************************************************/ 336 337acpi_status 338acpi_ex_pci_config_space_handler ( 339 u32 function, 340 acpi_physical_address address, 341 u32 bit_width, 342 acpi_integer *value, 343 void *handler_context, 344 void *region_context) 345{ 346 acpi_status status = AE_OK; 347 struct acpi_pci_id *pci_id; 348 u16 pci_register; 349 350 351 ACPI_FUNCTION_TRACE ("ex_pci_config_space_handler"); 352 353 354 /* 355 * The arguments to acpi_os(Read|Write)pci_configuration are: 356 * 357 * pci_segment is the PCI bus segment range 0-31 358 * pci_bus is the PCI bus number range 0-255 359 * pci_device is the PCI device number range 0-31 360 * pci_function is the PCI device function number 361 * pci_register is the Config space register range 0-255 bytes 362 * 363 * Value - input value for write, output address for read 364 * 365 */ 366 pci_id = (struct acpi_pci_id *) region_context; 367 pci_register = (u16) (u32) address; 368 369 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 370 "pci_config %d (%d) Seg(%04x) Bus(%04x) Dev(%04x) Func(%04x) Reg(%04x)\n", 371 function, bit_width, pci_id->segment, pci_id->bus, pci_id->device, 372 pci_id->function, pci_register)); 373 374 switch (function) { 375 case ACPI_READ: 376 377 *value = 0; 378 status = acpi_os_read_pci_configuration (pci_id, pci_register, value, bit_width); 379 break; 380 381 case ACPI_WRITE: 382 383 status = acpi_os_write_pci_configuration (pci_id, pci_register, *value, bit_width); 384 break; 385 386 default: 387 388 status = AE_BAD_PARAMETER; 389 break; 390 } 391 392 return_ACPI_STATUS (status); 393} 394 395 396/******************************************************************************* 397 * 398 * FUNCTION: acpi_ex_cmos_space_handler 399 * 400 * PARAMETERS: Function - Read or Write operation 401 * Address - Where in the space to read or write 402 * bit_width - Field width in bits (8, 16, or 32) 403 * Value - Pointer to in or out value 404 * handler_context - Pointer to Handler's context 405 * region_context - Pointer to context specific to the 406 * accessed region 407 * 408 * RETURN: Status 409 * 410 * DESCRIPTION: Handler for the CMOS address space (Op Region) 411 * 412 ******************************************************************************/ 413 414acpi_status 415acpi_ex_cmos_space_handler ( 416 u32 function, 417 acpi_physical_address address, 418 u32 bit_width, 419 acpi_integer *value, 420 void *handler_context, 421 void *region_context) 422{ 423 acpi_status status = AE_OK; 424 425 426 ACPI_FUNCTION_TRACE ("ex_cmos_space_handler"); 427 428 429 return_ACPI_STATUS (status); 430} 431 432 433/******************************************************************************* 434 * 435 * FUNCTION: acpi_ex_pci_bar_space_handler 436 * 437 * PARAMETERS: Function - Read or Write operation 438 * Address - Where in the space to read or write 439 * bit_width - Field width in bits (8, 16, or 32) 440 * Value - Pointer to in or out value 441 * handler_context - Pointer to Handler's context 442 * region_context - Pointer to context specific to the 443 * accessed region 444 * 445 * RETURN: Status 446 * 447 * DESCRIPTION: Handler for the PCI bar_target address space (Op Region) 448 * 449 ******************************************************************************/ 450 451acpi_status 452acpi_ex_pci_bar_space_handler ( 453 u32 function, 454 acpi_physical_address address, 455 u32 bit_width, 456 acpi_integer *value, 457 void *handler_context, 458 void *region_context) 459{ 460 acpi_status status = AE_OK; 461 462 463 ACPI_FUNCTION_TRACE ("ex_pci_bar_space_handler"); 464 465 466 return_ACPI_STATUS (status); 467} 468 469 470/******************************************************************************* 471 * 472 * FUNCTION: acpi_ex_data_table_space_handler 473 * 474 * PARAMETERS: Function - Read or Write operation 475 * Address - Where in the space to read or write 476 * bit_width - Field width in bits (8, 16, or 32) 477 * Value - Pointer to in or out value 478 * handler_context - Pointer to Handler's context 479 * region_context - Pointer to context specific to the 480 * accessed region 481 * 482 * RETURN: Status 483 * 484 * DESCRIPTION: Handler for the Data Table address space (Op Region) 485 * 486 ******************************************************************************/ 487 488acpi_status 489acpi_ex_data_table_space_handler ( 490 u32 function, 491 acpi_physical_address address, 492 u32 bit_width, 493 acpi_integer *value, 494 void *handler_context, 495 void *region_context) 496{ 497 acpi_status status = AE_OK; 498 u32 byte_width = ACPI_DIV_8 (bit_width); 499 u32 i; 500 char *logical_addr_ptr; 501 502 503 ACPI_FUNCTION_TRACE ("ex_data_table_space_handler"); 504 505 506 logical_addr_ptr = ACPI_PHYSADDR_TO_PTR (address); 507 508 509 /* Perform the memory read or write */ 510 511 switch (function) { 512 case ACPI_READ: 513 514 for (i = 0; i < byte_width; i++) { 515 ((char *) value) [i] = logical_addr_ptr[i]; 516 } 517 break; 518 519 case ACPI_WRITE: 520 default: 521 522 return_ACPI_STATUS (AE_SUPPORT); 523 } 524 525 return_ACPI_STATUS (status); 526} 527 528