Module Name:    src
Committed By:   jdolecek
Date:           Sat Sep 17 20:12:53 UTC 2016

Modified Files:
        src/sys/dev/pci: nvme_pci.c

Log Message:
#ifdef out MSI related code on platforms not supporting MSI, so that it's
possible to load the driver as module on those platforms (the weak symbols
are not found by module load, claiming they don't exist); this makes it possible
to load the driver on e.g. sparc64, which is supposed to be working
under OpenBSD

unfortunately QEMU sparc64 emulator starts causing data access errors
on first device register read in nvme_attach(), so can't confirm the driver
is actually working on sparc64; same happens in QEMU when booting OpenBSD
image, so it seems to be emulator bug


To generate a diff of this commit:
cvs rdiff -u -r1.10 -r1.11 src/sys/dev/pci/nvme_pci.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/pci/nvme_pci.c
diff -u src/sys/dev/pci/nvme_pci.c:1.10 src/sys/dev/pci/nvme_pci.c:1.11
--- src/sys/dev/pci/nvme_pci.c:1.10	Sat Sep 17 12:58:51 2016
+++ src/sys/dev/pci/nvme_pci.c	Sat Sep 17 20:12:53 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvme_pci.c,v 1.10 2016/09/17 12:58:51 jdolecek Exp $	*/
+/*	$NetBSD: nvme_pci.c,v 1.11 2016/09/17 20:12:53 jdolecek Exp $	*/
 /*	$OpenBSD: nvme_pci.c,v 1.3 2016/04/14 11:18:32 dlg Exp $ */
 
 /*
@@ -43,7 +43,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nvme_pci.c,v 1.10 2016/09/17 12:58:51 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvme_pci.c,v 1.11 2016/09/17 20:12:53 jdolecek Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -69,6 +69,13 @@ int nvme_pci_mq = 1;		/* INTx: ioq=1, MS
 
 #define NVME_PCI_BAR		0x10
 
+#ifndef __HAVE_PCI_MSI_MSIX
+#define pci_intr_release(pc, intrs, nintrs) \
+	kmem_free(intrs, sizeof(*intrs) * nintrs)
+#define pci_intr_establish_xname(pc, ih, level, intrhand, intrarg, xname) \
+	pci_intr_establish(pc, ih, level, intrhand, intrarg)
+#endif 
+
 struct nvme_pci_softc {
 	struct nvme_softc	psc_nvme;
 
@@ -112,8 +119,10 @@ nvme_pci_attach(device_t parent, device_
 	struct pci_attach_args *pa = aux;
 	pcireg_t memtype, reg;
 	bus_addr_t memaddr;
-	int flags, msixoff;
-	int error;
+	int flags, error;
+#ifdef __HAVE_PCI_MSI_MSIX
+	int msixoff;
+#endif
 
 	sc->sc_dev = self;
 	psc->psc_pc = pa->pa_pc;
@@ -143,6 +152,8 @@ nvme_pci_attach(device_t parent, device_
 		aprint_error_dev(self, "can't get map info\n");
 		return;
 	}
+
+#ifdef __HAVE_PCI_MSI_MSIX
 	if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_MSIX, &msixoff,
 	    NULL)) {
 		pcireg_t msixtbl;
@@ -157,6 +168,8 @@ nvme_pci_attach(device_t parent, device_
 			sc->sc_ios = table_offset;
 		}
 	}
+#endif /* __HAVE_PCI_MSI_MSIX */
+
 	error = bus_space_map(sc->sc_iot, memaddr, sc->sc_ios, flags,
 	    &sc->sc_ioh);
 	if (error != 0) {
@@ -179,9 +192,16 @@ nvme_pci_attach(device_t parent, device_
 		goto intr_release;
 	}
 
+	sc->sc_softih = kmem_zalloc(sizeof(*sc->sc_softih) * psc->psc_nintrs,
+	    KM_SLEEP);
+	if (sc->sc_softih == NULL) {
+		aprint_error_dev(self, "unable to allocate softih memory\n");
+		goto intr_free;
+	}
+
 	if (nvme_attach(sc) != 0) {
 		/* error printed by nvme_attach() */
-		goto intr_free;
+		goto softintr_free;
 	}
 
 	if (!pmf_device_register(self, NULL, NULL))
@@ -190,6 +210,8 @@ nvme_pci_attach(device_t parent, device_
 	SET(sc->sc_flags, NVME_F_ATTACHED);
 	return;
 
+softintr_free:
+	kmem_free(sc->sc_softih, sizeof(*sc->sc_softih) * psc->psc_nintrs);
 intr_free:
 	kmem_free(sc->sc_ih, sizeof(*sc->sc_ih) * psc->psc_nintrs);
 	sc->sc_nq = 0;
@@ -231,26 +253,29 @@ nvme_pci_intr_establish(struct nvme_soft
 	const char *intrstr = NULL;
 	int (*ih_func)(void *);
 	void *ih_arg;
-	kcpuset_t *affinity;
-	cpuid_t affinity_to;
+#ifdef __HAVE_PCI_MSI_MSIX
 	int error;
+#endif
 
-	if (!sc->sc_use_mq && qid > 0)
-		return 0;
-
+	KASSERT(sc->sc_use_mq || qid == NVME_ADMIN_Q);
 	KASSERT(sc->sc_ih[qid] == NULL);
 
 	if (nvme_pci_mpsafe) {
 		pci_intr_setattr(psc->psc_pc, &psc->psc_intrs[qid],
 		    PCI_INTR_MPSAFE, true);
 	}
+
+#ifdef __HAVE_PCI_MSI_MSIX
 	if (!sc->sc_use_mq) {
+#endif
 		snprintf(intr_xname, sizeof(intr_xname), "%s",
 		    device_xname(sc->sc_dev));
 		ih_arg = sc;
 		ih_func = nvme_intr;
-	} else {
-		if (qid == 0) {
+#ifdef __HAVE_PCI_MSI_MSIX
+	}
+	else {
+		if (qid == NVME_ADMIN_Q) {
 			snprintf(intr_xname, sizeof(intr_xname), "%s adminq",
 			    device_xname(sc->sc_dev));
 		} else {
@@ -264,6 +289,7 @@ nvme_pci_intr_establish(struct nvme_soft
 		else
 			ih_func = nvme_mq_msi_intr;
 	}
+#endif /* __HAVE_PCI_MSI_MSIX */
 	sc->sc_ih[qid] = pci_intr_establish_xname(psc->psc_pc,
 	    psc->psc_intrs[qid], IPL_BIO, ih_func, ih_arg, intr_xname);
 	if (sc->sc_ih[qid] == NULL) {
@@ -275,13 +301,18 @@ nvme_pci_intr_establish(struct nvme_soft
 	    sizeof(intrbuf));
 	if (!sc->sc_use_mq) {
 		aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", intrstr);
-	} else if (qid == NVME_ADMIN_Q) {
+	}
+#ifdef __HAVE_PCI_MSI_MSIX
+	else if (qid == NVME_ADMIN_Q) {
 		aprint_normal_dev(sc->sc_dev,
 		    "for admin queue interrupting at %s\n", intrstr);
 	} else if (!nvme_pci_mpsafe) {
 		aprint_normal_dev(sc->sc_dev,
 		    "for io queue %d interrupting at %s\n", qid, intrstr);
 	} else {
+		kcpuset_t *affinity;
+		cpuid_t affinity_to;
+
 		kcpuset_create(&affinity, true);
 		affinity_to = (qid - 1) % ncpu;
 		kcpuset_set(affinity, affinity_to);
@@ -293,6 +324,7 @@ nvme_pci_intr_establish(struct nvme_soft
 			aprint_normal(" affinity to cpu%lu", affinity_to);
 		aprint_normal("\n");
 	}
+#endif
 	return 0;
 }
 
@@ -316,11 +348,16 @@ static int
 nvme_pci_setup_intr(struct pci_attach_args *pa, struct nvme_pci_softc *psc)
 {
 	struct nvme_softc *sc = &psc->psc_nvme;
-	pci_intr_handle_t *ihps;
+#ifdef __HAVE_PCI_MSI_MSIX
+	int error;
 	int counts[PCI_INTR_TYPE_SIZE], alloced_counts[PCI_INTR_TYPE_SIZE];
+	pci_intr_handle_t *ihps;
 	int max_type, intr_type;
-	int error;
+#else
+	pci_intr_handle_t ih;
+#endif /* __HAVE_PCI_MSI_MSIX */
 
+#ifdef __HAVE_PCI_MSI_MSIX
 	if (nvme_pci_force_intx) {
 		max_type = PCI_INTR_TYPE_INTX;
 		goto force_intx;
@@ -420,6 +457,20 @@ retry:
 	}
 	sc->sc_use_mq = alloced_counts[intr_type] > 1;
 	sc->sc_nq = sc->sc_use_mq ? alloced_counts[intr_type] - 1 : 1;
+
+#else /* !__HAVE_PCI_MSI_MSIX */
+        if (pci_intr_map(pa, &ih)) {
+                aprint_error_dev(sc->sc_dev, "couldn't map interrupt\n");
+                return EBUSY;
+        }
+
+	psc->psc_intrs = kmem_zalloc(sizeof(ih), KM_SLEEP);
+	psc->psc_intrs[0] = ih;
+	psc->psc_nintrs = 1;
+	sc->sc_use_mq = 0;
+	sc->sc_nq = 1;
+#endif /* __HAVE_PCI_MSI_MSIX */
+
 	return 0;
 }
 

Reply via email to