PERFORCE change 59420 for review

Scott Long scottl at FreeBSD.org
Wed Aug 11 11:03:47 PDT 2004


http://perforce.freebsd.org/chv.cgi?CH=59420

Change 59420 by scottl at scottl-wv1u on 2004/08/11 18:03:25

	Add initial code to the AHD driver to demonstrate how MSI will work.

Affected files ...

.. //depot/projects/newint/sys/dev/aic7xxx/ahd_pci.c#3 edit
.. //depot/projects/newint/sys/dev/aic7xxx/aic79xx_osm.c#3 edit
.. //depot/projects/newint/sys/dev/aic7xxx/aic79xx_osm.h#3 edit

Differences ...

==== //depot/projects/newint/sys/dev/aic7xxx/ahd_pci.c#3 (text+ko) ====

@@ -246,14 +246,42 @@
 int
 ahd_pci_map_int(struct ahd_softc *ahd)
 {
-	int zero;
+	int zero, count, rid;
 
 	zero = 0;
-	ahd->platform_data->irq =
-	    bus_alloc_resource_any(ahd->dev_softc, SYS_RES_IRQ, &zero,
-				   RF_ACTIVE | RF_SHAREABLE);
-	if (ahd->platform_data->irq == NULL)
-		return (ENOMEM);
-	ahd->platform_data->irq_res_type = SYS_RES_IRQ;
-	return (ahd_map_int(ahd));
+	count = 2;	/* Want 2 MSI messages */
+
+	/* See if we can use MSI for interrupts */
+	if (bus_reserve_resource(ahd->dev_softc, SYS_RES_MESSAGE, &zero,
+				 &count, 0) != 0)
+		count = 0;
+
+	/*
+	 * If both message vectors are available then use them.
+	 * XXX Should we still try to use MSI even if only one message is
+	 * available?  That would require patching the sequencer.
+	 */
+	if (zero == 0 && count == 2) {
+		rid = 0;
+		ahd->platform_data->msi0 =
+		    bus_alloc_resource(ahd->dev_softc, SYS_RES_MESSAGE, &rid,
+				       0, 0, 1, RF_ACTIVE);
+		rid = 1;
+		ahd->platform_data->msi1 =
+		    bus_alloc_resource(ahd->dev_softc, SYS_RES_MESSAGE, &rid,
+				       1, 1, 1, RF_ACTIVE);
+		if ((ahd->platform_data->msi0 == NULL) ||
+		    (ahd->platform_data->msi1 == NULL))
+			return (ENOMEM);
+		ahd->platform_data->irq_res_type = SYS_RES_MESSAGE;
+		return (ahd_map_msi(ahd));
+	} else {
+		ahd->platform_data->irq =
+		    bus_alloc_resource_any(ahd->dev_softc, SYS_RES_IRQ, &zero,
+					   RF_ACTIVE | RF_SHAREABLE);
+		if (ahd->platform_data->irq == NULL)
+			return (ENOMEM);
+		ahd->platform_data->irq_res_type = SYS_RES_IRQ;
+		return (ahd_map_int(ahd));
+	}
 }

==== //depot/projects/newint/sys/dev/aic7xxx/aic79xx_osm.c#3 (text+ko) ====

@@ -103,6 +103,31 @@
 	return (error);
 }
 
+int
+ahd_map_msi(struct ahd_softc *ahd)
+{
+	int error;
+
+	/* Hook up the command complete MSI message */
+	error = bus_setup_intr(ahd->dev_softc, ahd->platform_data->msi0,
+			       INTR_TYPE_CAM, ahd_platform_intr, ahd,
+			       &ahd->platform_data->ih_cmd);
+	if (error != 0) {
+		device_printf(ahd->dev_softc, "bus_setup_intr() falied for "
+			      "msi0: %d\n", error);
+		return (error);
+	}
+
+	/* Hook up the SEQINT MSI message */
+	error = bus_setup_intr(ahd->dev_softc, ahd->platform_data->msi1,
+			       INTR_TYPE_CAM, ahd_platform_intr, ahd,
+			       &ahd->platform_data->ih_seqint);
+	if (error != 0)
+		device_printf(ahd->dev_softc, "bus_setup_intr() falied for "
+			      "msi1: %d\n", error);
+	return (error);
+}
+
 /*
  * Attach all the sub-devices we can find
  */

==== //depot/projects/newint/sys/dev/aic7xxx/aic79xx_osm.h#3 (text+ko) ====

@@ -137,7 +137,11 @@
 	int			 irq_res_type;
 	struct resource		*regs[2];
 	struct resource		*irq;
+	struct resource		*msi0;
+	struct resource		*msi1;
 	void			*ih;
+	void			*ih_cmd;
+	void			*ih_seqint;
 	eventhandler_tag	 eh;
 	struct proc		*recovery_thread;
 };
@@ -302,6 +306,7 @@
 int	  ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg);
 void	  ahd_platform_free(struct ahd_softc *ahd);
 int	  ahd_map_int(struct ahd_softc *ahd);
+int	  ahd_map_msi(struct ahd_softc *ahd);
 int	  ahd_attach(struct ahd_softc *);
 int	  ahd_softc_comp(struct ahd_softc *lahd, struct ahd_softc *rahd);
 int	  ahd_detach(device_t);


More information about the p4-projects mailing list