Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 23 Jul 2016 17:41:47 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r303229 - stable/10/sys/dev/acpica
Message-ID:  <201607231741.u6NHflan045567@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Sat Jul 23 17:41:47 2016
New Revision: 303229
URL: https://svnweb.freebsd.org/changeset/base/303229

Log:
  MFC 298370,298372,298377,298379,298380,298484:
  Abstract out _OSC handling and invoke it for PCI bridges.
  
  r298370:
  Add a wrapper for evaluating _OSC methods.
  
  This wrapper does not translate errors in the first word to ACPI
  error status returns.  Use this wrapper in the acpi_cpu(4) driver in
  place of the existing _OSC code.  While here, fix a bug where the wrong
  count of words was passed when invoking _OSC.
  
  r298372:
  Invoke _OSC on Host-PCI bridges.
  
  Tell the firmware that we support PCI-express config space access
  and MSI.
  
  r298377:
  Remove query flag from acpi_EvaluateOSC().  This function does not support
  return buffer (yet).
  
  r298379:
  There is no need to use array any more.  No functional change.
  
  r298380:
  Prefer sizeof(*pointer) over sizeof(type).  No funtional change.
  
  r298484:
  Optionally return the output capabilities list from _OSC.
  
  Both of the callers were expecting the input cap_set to be modified.
  This fixes them to request cap_set to be updated with the returned buffer.

Modified:
  stable/10/sys/dev/acpica/acpi.c
  stable/10/sys/dev/acpica/acpi_cpu.c
  stable/10/sys/dev/acpica/acpi_pcib_acpi.c
  stable/10/sys/dev/acpica/acpivar.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/acpica/acpi.c
==============================================================================
--- stable/10/sys/dev/acpica/acpi.c	Sat Jul 23 17:37:59 2016	(r303228)
+++ stable/10/sys/dev/acpica/acpi.c	Sat Jul 23 17:41:47 2016	(r303229)
@@ -2451,6 +2451,46 @@ acpi_AppendBufferResource(ACPI_BUFFER *b
     return (AE_OK);
 }
 
+ACPI_STATUS
+acpi_EvaluateOSC(ACPI_HANDLE handle, uint8_t *uuid, int revision, int count,
+    uint32_t *caps_in, uint32_t *caps_out, bool query)
+{
+	ACPI_OBJECT arg[4], *ret;
+	ACPI_OBJECT_LIST arglist;
+	ACPI_BUFFER buf;
+	ACPI_STATUS status;
+
+	arglist.Pointer = arg;
+	arglist.Count = 4;
+	arg[0].Type = ACPI_TYPE_BUFFER;
+	arg[0].Buffer.Length = ACPI_UUID_LENGTH;
+	arg[0].Buffer.Pointer = uuid;
+	arg[1].Type = ACPI_TYPE_INTEGER;
+	arg[1].Integer.Value = revision;
+	arg[2].Type = ACPI_TYPE_INTEGER;
+	arg[2].Integer.Value = count;
+	arg[3].Type = ACPI_TYPE_BUFFER;
+	arg[3].Buffer.Length = count * sizeof(*caps_in);
+	arg[3].Buffer.Pointer = (uint8_t *)caps_in;
+	caps_in[0] = query ? 1 : 0;
+	buf.Pointer = NULL;
+	buf.Length = ACPI_ALLOCATE_BUFFER;
+	status = AcpiEvaluateObjectTyped(handle, "_OSC", &arglist, &buf,
+	    ACPI_TYPE_BUFFER);
+	if (ACPI_FAILURE(status))
+		return (status);
+	if (caps_out != NULL) {
+		ret = buf.Pointer;
+		if (ret->Buffer.Length != count * sizeof(*caps_out)) {
+			AcpiOsFree(buf.Pointer);
+			return (AE_BUFFER_OVERFLOW);
+		}
+		bcopy(ret->Buffer.Pointer, caps_out, ret->Buffer.Length);
+	}
+	AcpiOsFree(buf.Pointer);
+	return (status);
+}
+
 /*
  * Set interrupt model.
  */

Modified: stable/10/sys/dev/acpica/acpi_cpu.c
==============================================================================
--- stable/10/sys/dev/acpica/acpi_cpu.c	Sat Jul 23 17:37:59 2016	(r303228)
+++ stable/10/sys/dev/acpica/acpi_cpu.c	Sat Jul 23 17:41:47 2016	(r303229)
@@ -275,7 +275,7 @@ static int
 acpi_cpu_attach(device_t dev)
 {
     ACPI_BUFFER		   buf;
-    ACPI_OBJECT		   arg[4], *obj;
+    ACPI_OBJECT		   arg, *obj;
     ACPI_OBJECT_LIST	   arglist;
     struct pcpu		   *pcpu_data;
     struct acpi_cpu_softc *sc;
@@ -359,31 +359,19 @@ acpi_cpu_attach(device_t dev)
      * Intel Processor Vendor-Specific ACPI Interface Specification.
      */
     if (sc->cpu_features) {
-	arglist.Pointer = arg;
-	arglist.Count = 4;
-	arg[0].Type = ACPI_TYPE_BUFFER;
-	arg[0].Buffer.Length = sizeof(cpu_oscuuid);
-	arg[0].Buffer.Pointer = cpu_oscuuid;	/* UUID */
-	arg[1].Type = ACPI_TYPE_INTEGER;
-	arg[1].Integer.Value = 1;		/* revision */
-	arg[2].Type = ACPI_TYPE_INTEGER;
-	arg[2].Integer.Value = 1;		/* count */
-	arg[3].Type = ACPI_TYPE_BUFFER;
-	arg[3].Buffer.Length = sizeof(cap_set);	/* Capabilities buffer */
-	arg[3].Buffer.Pointer = (uint8_t *)cap_set;
-	cap_set[0] = 0;				/* status */
 	cap_set[1] = sc->cpu_features;
-	status = AcpiEvaluateObject(sc->cpu_handle, "_OSC", &arglist, NULL);
+	status = acpi_EvaluateOSC(sc->cpu_handle, cpu_oscuuid, 1, 2, cap_set,
+	    cap_set, false);
 	if (ACPI_SUCCESS(status)) {
 	    if (cap_set[0] != 0)
 		device_printf(dev, "_OSC returned status %#x\n", cap_set[0]);
 	}
 	else {
-	    arglist.Pointer = arg;
+	    arglist.Pointer = &arg;
 	    arglist.Count = 1;
-	    arg[0].Type = ACPI_TYPE_BUFFER;
-	    arg[0].Buffer.Length = sizeof(cap_set);
-	    arg[0].Buffer.Pointer = (uint8_t *)cap_set;
+	    arg.Type = ACPI_TYPE_BUFFER;
+	    arg.Buffer.Length = sizeof(cap_set);
+	    arg.Buffer.Pointer = (uint8_t *)cap_set;
 	    cap_set[0] = 1; /* revision */
 	    cap_set[1] = 1; /* number of capabilities integers */
 	    cap_set[2] = sc->cpu_features;

Modified: stable/10/sys/dev/acpica/acpi_pcib_acpi.c
==============================================================================
--- stable/10/sys/dev/acpica/acpi_pcib_acpi.c	Sat Jul 23 17:37:59 2016	(r303228)
+++ stable/10/sys/dev/acpica/acpi_pcib_acpi.c	Sat Jul 23 17:41:47 2016	(r303229)
@@ -295,6 +295,39 @@ first_decoded_bus(struct acpi_hpcib_soft
 }
 #endif
 
+static void
+acpi_pcib_osc(struct acpi_hpcib_softc *sc)
+{
+	ACPI_STATUS status;
+	uint32_t cap_set[3];
+
+	static uint8_t pci_host_bridge_uuid[ACPI_UUID_LENGTH] = {
+		0x5b, 0x4d, 0xdb, 0x33, 0xf7, 0x1f, 0x1c, 0x40,
+		0x96, 0x57, 0x74, 0x41, 0xc0, 0x3d, 0xd7, 0x66
+	};
+
+	/* Support Field: Extended PCI Config Space, MSI */
+	cap_set[1] = 0x11;
+
+	/* Control Field */
+	cap_set[2] = 0;
+
+	status = acpi_EvaluateOSC(sc->ap_handle, pci_host_bridge_uuid, 1,
+	    nitems(cap_set), cap_set, cap_set, false);
+	if (ACPI_FAILURE(status)) {
+		if (status == AE_NOT_FOUND)
+			return;
+		device_printf(sc->ap_dev, "_OSC failed: %s\n",
+		    AcpiFormatException(status));
+		return;
+	}
+
+	if (cap_set[0] != 0) {
+		device_printf(sc->ap_dev, "_OSC returned error %#x\n",
+		    cap_set[0]);
+	}
+}
+
 static int
 acpi_pcib_acpi_attach(device_t dev)
 {
@@ -321,6 +354,8 @@ acpi_pcib_acpi_attach(device_t dev)
     if (!acpi_DeviceIsPresent(dev))
 	return (ENXIO);
 
+    acpi_pcib_osc(sc);
+
     /*
      * Get our segment number by evaluating _SEG.
      * It's OK for this to not exist.

Modified: stable/10/sys/dev/acpica/acpivar.h
==============================================================================
--- stable/10/sys/dev/acpica/acpivar.h	Sat Jul 23 17:37:59 2016	(r303228)
+++ stable/10/sys/dev/acpica/acpivar.h	Sat Jul 23 17:41:47 2016	(r303229)
@@ -335,6 +335,9 @@ ACPI_STATUS	acpi_FindIndexedResource(ACP
 		    ACPI_RESOURCE **resp);
 ACPI_STATUS	acpi_AppendBufferResource(ACPI_BUFFER *buf,
 		    ACPI_RESOURCE *res);
+ACPI_STATUS	acpi_EvaluateOSC(ACPI_HANDLE handle, uint8_t *uuid,
+		    int revision, int count, uint32_t *caps_in,
+		    uint32_t *caps_out, bool query);
 ACPI_STATUS	acpi_OverrideInterruptLevel(UINT32 InterruptNumber);
 ACPI_STATUS	acpi_SetIntrModel(int model);
 int		acpi_ReqSleepState(struct acpi_softc *sc, int state);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201607231741.u6NHflan045567>