acpi-ext.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /*
  2. * arch/ia64/kernel/acpi-ext.c
  3. *
  4. * Copyright (C) 2003 Hewlett-Packard
  5. * Copyright (C) Alex Williamson
  6. * Copyright (C) Bjorn Helgaas
  7. *
  8. * Vendor specific extensions to ACPI.
  9. */
  10. #include <linux/config.h>
  11. #include <linux/module.h>
  12. #include <linux/types.h>
  13. #include <linux/acpi.h>
  14. #include <linux/efi.h>
  15. #include <asm/acpi-ext.h>
  16. struct acpi_vendor_descriptor {
  17. u8 guid_id;
  18. efi_guid_t guid;
  19. };
  20. struct acpi_vendor_info {
  21. struct acpi_vendor_descriptor *descriptor;
  22. u8 *data;
  23. u32 length;
  24. };
  25. acpi_status
  26. acpi_vendor_resource_match(struct acpi_resource *resource, void *context)
  27. {
  28. struct acpi_vendor_info *info = (struct acpi_vendor_info *)context;
  29. struct acpi_resource_vendor *vendor;
  30. struct acpi_vendor_descriptor *descriptor;
  31. u32 length;
  32. if (resource->id != ACPI_RSTYPE_VENDOR)
  33. return AE_OK;
  34. vendor = (struct acpi_resource_vendor *)&resource->data;
  35. descriptor = (struct acpi_vendor_descriptor *)vendor->reserved;
  36. if (vendor->length <= sizeof(*info->descriptor) ||
  37. descriptor->guid_id != info->descriptor->guid_id ||
  38. efi_guidcmp(descriptor->guid, info->descriptor->guid))
  39. return AE_OK;
  40. length = vendor->length - sizeof(struct acpi_vendor_descriptor);
  41. info->data = acpi_os_allocate(length);
  42. if (!info->data)
  43. return AE_NO_MEMORY;
  44. memcpy(info->data,
  45. vendor->reserved + sizeof(struct acpi_vendor_descriptor),
  46. length);
  47. info->length = length;
  48. return AE_CTRL_TERMINATE;
  49. }
  50. acpi_status
  51. acpi_find_vendor_resource(acpi_handle obj, struct acpi_vendor_descriptor * id,
  52. u8 ** data, u32 * length)
  53. {
  54. struct acpi_vendor_info info;
  55. info.descriptor = id;
  56. info.data = NULL;
  57. acpi_walk_resources(obj, METHOD_NAME__CRS, acpi_vendor_resource_match,
  58. &info);
  59. if (!info.data)
  60. return AE_NOT_FOUND;
  61. *data = info.data;
  62. *length = info.length;
  63. return AE_OK;
  64. }
  65. struct acpi_vendor_descriptor hp_ccsr_descriptor = {
  66. .guid_id = 2,
  67. .guid =
  68. EFI_GUID(0x69e9adf9, 0x924f, 0xab5f, 0xf6, 0x4a, 0x24, 0xd2, 0x01,
  69. 0x37, 0x0e, 0xad)
  70. };
  71. acpi_status hp_acpi_csr_space(acpi_handle obj, u64 * csr_base, u64 * csr_length)
  72. {
  73. acpi_status status;
  74. u8 *data;
  75. u32 length;
  76. status =
  77. acpi_find_vendor_resource(obj, &hp_ccsr_descriptor, &data, &length);
  78. if (ACPI_FAILURE(status) || length != 16)
  79. return AE_NOT_FOUND;
  80. memcpy(csr_base, data, sizeof(*csr_base));
  81. memcpy(csr_length, data + 8, sizeof(*csr_length));
  82. acpi_os_free(data);
  83. return AE_OK;
  84. }
  85. EXPORT_SYMBOL(hp_acpi_csr_space);