This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / drivers / pci / hotplug / acpiphp_ibm.c
index aced661..fe7866c 100644 (file)
@@ -64,8 +64,6 @@ do {                                                  \
 #define IBM_HARDWARE_ID1 "IBM37D0"
 #define IBM_HARDWARE_ID2 "IBM37D4"
 
-#define hpslot_to_sun(A) (((struct slot *)((A)->private))->acpi_slot->sun)
-
 /* union apci_descriptor - allows access to the
  * various device descriptors that are embedded in the
  * aPCI table
@@ -86,7 +84,6 @@ union apci_descriptor {
                u8  attn;
                u8  status[2];
                u8  sun;
-               u8  res[3];
        } slot;
        struct {
                u8 type;
@@ -131,43 +128,6 @@ static struct acpiphp_attention_info ibm_attention_info =
        .owner = THIS_MODULE,
 };
 
-/**
- * ibm_slot_from_id - workaround for bad ibm hardware
- * @id: the slot number that linux refers to the slot by
- *
- * Description: this method returns the aCPI slot descriptor
- * corresponding to the Linux slot number.  This descriptor
- * has info about the aPCI slot id and attention status.
- * This descriptor must be freed using kfree when done.
- **/
-static union apci_descriptor *ibm_slot_from_id(int id)
-{
-       int ind = 0, size;
-       union apci_descriptor *ret = NULL, *des;
-       char *table;
-
-       size = ibm_get_table_from_acpi(&table);
-       des = (union apci_descriptor *)table;
-       if (memcmp(des->header.sig, "aPCI", 4) != 0)
-               goto ibm_slot_done;
-
-       des = (union apci_descriptor *)&table[ind += des->header.len];
-       while (ind < size && (des->generic.type != 0x82 ||
-                       des->slot.slot_num != id)) {
-               des = (union apci_descriptor *)&table[ind += des->generic.len];
-       }
-
-       if (ind < size && des->slot.slot_num == id)
-               ret = des;
-
-ibm_slot_done:
-       if (ret) {
-               ret = kmalloc(sizeof(union apci_descriptor), GFP_KERNEL);
-               memcpy(ret, des, sizeof(union apci_descriptor));
-       }
-       kfree(table);
-       return ret;
-}
 
 /**
  * ibm_set_attention_status - callback method to set the attention LED
@@ -179,34 +139,32 @@ ibm_slot_done:
  **/
 static int ibm_set_attention_status(struct hotplug_slot *slot, u8 status)
 {
+       int retval = 0;
        union acpi_object args[2]; 
        struct acpi_object_list params = { .pointer = args, .count = 2 };
        acpi_status stat; 
-       unsigned long rc;
-       union apci_descriptor *ibm_slot;
+       unsigned long rc = 0;
+       struct acpiphp_slot *acpi_slot;
 
-       ibm_slot = ibm_slot_from_id(hpslot_to_sun(slot));
+       acpi_slot = ((struct slot *)(slot->private))->acpi_slot;
 
-       dbg("%s: set slot %d (%d) attention status to %d\n", __FUNCTION__,
-                       ibm_slot->slot.slot_num, ibm_slot->slot.slot_id,
-                       (status ? 1 : 0));
+       dbg("%s: set slot %d attention status to %d\n", __FUNCTION__,
+                       acpi_slot->sun, (status ? 1 : 0));
 
        args[0].type = ACPI_TYPE_INTEGER;
-       args[0].integer.value = ibm_slot->slot.slot_id;
+       args[0].integer.value = acpi_slot->sun;
        args[1].type = ACPI_TYPE_INTEGER;
        args[1].integer.value = (status) ? 1 : 0;
 
-       kfree(ibm_slot);
-
        stat = acpi_evaluate_integer(ibm_acpi_handle, "APLS", &params, &rc);
        if (ACPI_FAILURE(stat)) {
+               retval = -ENODEV;
                err("APLS evaluation failed:  0x%08x\n", stat);
-               return -ENODEV;
        } else if (!rc) {
+               retval = -ERANGE;
                err("APLS method failed:  0x%08lx\n", rc);
-               return -ERANGE;
        }
-       return 0;
+       return retval;
 }
 
 /**
@@ -223,21 +181,38 @@ static int ibm_set_attention_status(struct hotplug_slot *slot, u8 status)
  **/
 static int ibm_get_attention_status(struct hotplug_slot *slot, u8 *status)
 {
-       union apci_descriptor *ibm_slot;
+       int retval = -EINVAL, ind = 0, size;
+       char *table = NULL;
+       struct acpiphp_slot *acpi_slot;
+       union apci_descriptor *des;
 
-       ibm_slot = ibm_slot_from_id(hpslot_to_sun(slot));
+       acpi_slot = ((struct slot *)(slot->private))->acpi_slot;
 
-       if (ibm_slot->slot.attn & 0xa0 || ibm_slot->slot.status[1] & 0x08)
-               *status = 1;
-       else
-               *status = 0;
+       size = ibm_get_table_from_acpi(&table);
+       if (size <= 0 || !table)
+               goto get_attn_done;
+       // read the header
+       des = (union apci_descriptor *)&table[ind];
+       if (memcmp(des->header.sig, "aPCI", 4) != 0)
+               goto get_attn_done;
+       des = (union apci_descriptor *)&table[ind += des->header.len];
+       while (ind < size && (des->generic.type != 0x82 ||
+                       des->slot.slot_id != acpi_slot->sun))
+               des = (union apci_descriptor *)&table[ind += des->generic.len];
+       if (ind < size && des->slot.slot_id == acpi_slot->sun) {
+               retval = 0;
+               if (des->slot.attn & 0xa0 || des->slot.status[1] & 0x08)
+                       *status = 1;
+               else
+                       *status = 0;
+       }
 
-       dbg("%s: get slot %d (%d) attention status is %d\n", __FUNCTION__,
-                       ibm_slot->slot.slot_num, ibm_slot->slot.slot_id,
-                       *status);
+       dbg("%s: get slot %d attention status is %d retval=%x\n",
+                       __FUNCTION__, acpi_slot->sun, *status, retval);
 
-       kfree(ibm_slot);
-       return 0;
+get_attn_done:
+       kfree(table);
+       return retval;
 }
 
 /**