Jordan wrote this diff to play with modular hotplug bay devices such as
cd players.  We need some tests on this to see if the acpi device to pci
device mapping works right.  Try removing and reinserting the cd bay
device.

Be warned that this may panic your box.

Please send me and jordan the results.

Index: acpi.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpi.c,v
retrieving revision 1.137
diff -u -p -u -p -b -r1.137 acpi.c
--- acpi.c      30 Apr 2009 20:42:14 -0000      1.137
+++ acpi.c      31 May 2009 18:18:53 -0000
@@ -339,6 +339,103 @@ acpi_foundprt(struct aml_node *node, voi
        return 0;
 }
 
+int acpi_foundide(struct aml_node *node, void *arg);
+int acpiide_notify(struct aml_node *, int, void *);
+
+int ide_installed=1;
+
+#include <dev/pci/pciidereg.h>
+#include <dev/pci/pciidevar.h>
+void  wdcattach(struct channel_softc *);
+int   wdcdetach(struct channel_softc *, int);
+
+struct idechnl
+{
+       struct acpi_softc *sc;
+       int64_t addr;
+       int64_t chnl;
+};
+
+int
+acpiide_notify(struct aml_node *node, int ntype, void *arg)
+{
+       struct idechnl *ide = arg;
+       struct acpi_softc *sc = ide->sc;
+       struct pciide_softc *wsc;
+       struct device *dev;
+       int b,d,f;
+       int64_t sta;
+
+       if (aml_evalinteger(sc, node, "_STA", 0, NULL, &sta) != 0)
+               return 0;
+
+       printf("IDE notify! %s %d status:%llx\n", aml_nodename(node), ntype, 
sta);
+
+       /* Walk device list looking for IDE device match */
+       TAILQ_FOREACH(dev, &alldevs, dv_list) {
+               if (strncmp(dev->dv_xname, "pciide", 6))
+                       continue;
+
+               wsc = (struct pciide_softc *)dev;
+               pci_decompose_tag(NULL, wsc->sc_tag, &b, &d, &f);
+               if (b != ACPI_PCI_BUS(ide->addr) ||
+                   d != ACPI_PCI_DEV(ide->addr) ||
+                   f != ACPI_PCI_FN(ide->addr))
+                       continue;
+               printf("Found pciide: %s %x.%x.%x channel:%llx \"%s\"\n",
+                       dev->dv_xname, b,d,f, ide->chnl,
+                       wsc->pciide_channels[ide->chnl].name);
+#if 1
+               if (sta == 0 && ide_installed) {
+                       ide_installed = 0;
+                       
wdcdetach(&wsc->pciide_channels[ide->chnl].wdc_channel,0);
+               }
+               else if (sta && !ide_installed) {
+                       ide_installed = 1;
+                       wdcattach(&wsc->pciide_channels[ide->chnl].wdc_channel);
+               }
+#endif
+       }
+       return 0;
+}
+
+int
+acpi_foundide(struct aml_node *node, void *arg)
+{
+       struct acpi_softc *sc = arg;
+       struct aml_node *pp;
+       struct idechnl *ide;
+       int lvl;
+
+       ide = malloc(sizeof(struct idechnl), M_DEVBUF, M_NOWAIT | M_ZERO);
+       ide->sc = sc;
+
+       /* GTM/GTF can be at 2/3 levels:  pciX.ideX.channelX[.driveX] */
+       lvl = 0;
+       for (pp=node->parent; pp; pp=pp->parent) {
+               lvl++;
+               if (aml_searchname(pp, "_HID"))
+                       break;
+       }
+
+       /* Get PCI address and channel */
+       if (lvl == 3) {
+               aml_evalinteger(sc, node->parent, "_ADR", 0, NULL, 
+                       &ide->chnl);
+               aml_xgetpci(node->parent, &ide->addr);
+       }
+       else if (lvl == 4) {
+               aml_evalinteger(sc, node->parent->parent, "_ADR", 0, NULL, 
+                       &ide->chnl);
+               aml_xgetpci(node->parent->parent, &ide->addr);
+       }
+       printf("%s %llx channel:%llx\n", 
+               aml_nodename(node), ide->addr, ide->chnl);
+
+       aml_register_notify(node->parent, "acpiide", acpiide_notify, ide, 0);
+       return 0;
+}
+
 int
 acpi_match(struct device *parent, void *match, void *aux)
 {
@@ -584,6 +681,10 @@ acpi_attach(struct device *parent, struc
 
        /* attach battery, power supply and button devices */
        aml_find_node(&aml_root, "_HID", acpi_foundhid, sc);
+
+       /* Attach IDE bay */
+       aml_find_node(&aml_root, "_GTF", acpi_foundide, sc);
+       aml_find_node(&aml_root, "_GTM", acpi_foundide, sc);
 
        /* attach docks */
        aml_find_node(&aml_root, "_DCK", acpi_founddock, sc);

Reply via email to