Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

ahci: Use MSI if device support it.

  • Loading branch information...
commit 9783883ae1a6a13fe8f96b5938cb141382fdbf2a 1 parent 9dc47ee
authored December 27, 2011
4  sys/dev/disk/ahci/ahci.h
@@ -453,6 +453,7 @@ struct ahci_softc {
453 453
 	bus_space_tag_t		sc_iot;		/* split from sc_regs */
454 454
 	bus_space_handle_t	sc_ioh;		/* split from sc_regs */
455 455
 
  456
+	int			sc_irq_type;
456 457
 	int			sc_rid_irq;	/* saved bus RIDs */
457 458
 	int			sc_rid_regs;
458 459
 	u_int32_t		sc_cap;		/* capabilities */
@@ -486,6 +487,9 @@ struct ahci_softc {
486 487
 };
487 488
 #define DEVNAME(_s)		((_s)->sc_dev.dv_xname)
488 489
 
  490
+#define AHCI_IRQ_TYPE_LEGACY	0
  491
+#define AHCI_IRQ_TYPE_MSI	1
  492
+
489 493
 struct ahci_device {
490 494
 	pci_vendor_id_t		ad_vendor;
491 495
 	pci_product_id_t	ad_product;
39  sys/dev/disk/ahci/ahci_attach.c
@@ -74,6 +74,9 @@ static const struct ahci_device ahci_devices[] = {
74 74
 	    ahci_pci_attach, ahci_pci_detach, "AHCI-PCI-SATA" }
75 75
 };
76 76
 
  77
+static int	ahci_msi_enable = 1;
  78
+TUNABLE_INT("hw.ahci.msi.enable", &ahci_msi_enable);
  79
+
77 80
 /*
78 81
  * Match during probe and attach.  The device does not yet have a softc.
79 82
  */
@@ -165,10 +168,11 @@ ahci_pci_attach(device_t dev)
165 168
 	struct ahci_port *ap;
166 169
 	const char *gen;
167 170
 	u_int32_t cap, pi, reg;
  171
+	u_int irq_flags;
168 172
 	bus_addr_t addr;
169  
-	int i;
170  
-	int error;
  173
+	int i, error, msi_enable;
171 174
 	const char *revision;
  175
+	char env[64];
172 176
 
173 177
 	if (pci_read_config(dev, PCIR_COMMAND, 2) & 0x0400) {
174 178
 		device_printf(dev, "BIOS disabled PCI interrupt, "
@@ -177,14 +181,37 @@ ahci_pci_attach(device_t dev)
177 181
 			pci_read_config(dev, PCIR_COMMAND, 2) & ~0x0400, 2);
178 182
 	}
179 183
 
  184
+	sc->sc_dev = dev;
180 185
 
181 186
 	/*
182 187
 	 * Map the AHCI controller's IRQ and BAR(5) (hardware registers)
183 188
 	 */
184  
-	sc->sc_dev = dev;
  189
+	msi_enable = ahci_msi_enable;
  190
+	ksnprintf(env, sizeof(env), "hw.%s.msi.enable",
  191
+	    device_get_nameunit(dev));
  192
+	kgetenv_int(env, &msi_enable);
  193
+
185 194
 	sc->sc_rid_irq = AHCI_IRQ_RID;
  195
+	sc->sc_irq_type = AHCI_IRQ_TYPE_LEGACY;
  196
+	irq_flags = RF_SHAREABLE | RF_ACTIVE;
  197
+
  198
+	if (msi_enable) {
  199
+		int cpu = -1;
  200
+
  201
+		ksnprintf(env, sizeof(env), "hw.%s.msi.cpu",
  202
+		    device_get_nameunit(dev));
  203
+		kgetenv_int(env, &cpu);
  204
+		if (cpu >= ncpus)
  205
+			cpu = ncpus - 1;
  206
+
  207
+		if (pci_alloc_msi(dev, &sc->sc_rid_irq, 1, cpu) == 0) {
  208
+			irq_flags &= ~RF_SHAREABLE;
  209
+			sc->sc_irq_type = AHCI_IRQ_TYPE_MSI;
  210
+		}
  211
+	}
  212
+
186 213
 	sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->sc_rid_irq,
187  
-					    RF_SHAREABLE | RF_ACTIVE);
  214
+	    irq_flags);
188 215
 	if (sc->sc_irq == NULL) {
189 216
 		device_printf(dev, "unable to map interrupt\n");
190 217
 		ahci_pci_detach(dev);
@@ -529,6 +556,10 @@ ahci_pci_detach(device_t dev)
529 556
 				     sc->sc_rid_irq, sc->sc_irq);
530 557
 		sc->sc_irq = NULL;
531 558
 	}
  559
+
  560
+	if (sc->sc_irq_type == AHCI_IRQ_TYPE_MSI)
  561
+		pci_release_msi(dev);
  562
+
532 563
 	if (sc->sc_regs) {
533 564
 		bus_release_resource(dev, SYS_RES_MEMORY,
534 565
 				     sc->sc_rid_regs, sc->sc_regs);

0 notes on commit 9783883

Please sign in to comment.
Something went wrong with that request. Please try again.