Module Name:    src
Committed By:   sborrill
Date:           Wed Mar 21 14:22:36 UTC 2012

Modified Files:
        src/sys/dev/ic: mfi.c mfireg.h mfivar.h
        src/sys/dev/pci: mfi_pci.c

Log Message:
Add support for skinny variants (e.g. IBM ServeRAID M1015). Based on OpenBSD
changes with some improvements. Tested on IBM x3550M3 with RAID0 and RAID1
volumes including bioctl(8) operation.


To generate a diff of this commit:
cvs rdiff -u -r1.37 -r1.38 src/sys/dev/ic/mfi.c
cvs rdiff -u -r1.4 -r1.5 src/sys/dev/ic/mfireg.h
cvs rdiff -u -r1.14 -r1.15 src/sys/dev/ic/mfivar.h
cvs rdiff -u -r1.12 -r1.13 src/sys/dev/pci/mfi_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/ic/mfi.c
diff -u src/sys/dev/ic/mfi.c:1.37 src/sys/dev/ic/mfi.c:1.38
--- src/sys/dev/ic/mfi.c:1.37	Wed Mar 21 13:19:11 2012
+++ src/sys/dev/ic/mfi.c	Wed Mar 21 14:22:36 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: mfi.c,v 1.37 2012/03/21 13:19:11 sborrill Exp $ */
+/* $NetBSD: mfi.c,v 1.38 2012/03/21 14:22:36 sborrill Exp $ */
 /* $OpenBSD: mfi.c,v 1.66 2006/11/28 23:59:45 dlg Exp $ */
 /*
  * Copyright (c) 2006 Marco Peereboom <ma...@peereboom.us>
@@ -17,7 +17,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mfi.c,v 1.37 2012/03/21 13:19:11 sborrill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mfi.c,v 1.38 2012/03/21 14:22:36 sborrill Exp $");
 
 #include "bio.h"
 
@@ -151,6 +151,20 @@ static const struct mfi_iop_ops mfi_iop_
 	mfi_gen2_post
 };
 
+u_int32_t	mfi_skinny_fw_state(struct mfi_softc *);
+void		mfi_skinny_intr_dis(struct mfi_softc *);
+void		mfi_skinny_intr_ena(struct mfi_softc *);
+int		mfi_skinny_intr(struct mfi_softc *);
+void		mfi_skinny_post(struct mfi_softc *, struct mfi_ccb *);
+
+static const struct mfi_iop_ops mfi_iop_skinny = {
+	mfi_skinny_fw_state,
+	mfi_skinny_intr_dis,
+	mfi_skinny_intr_ena,
+	mfi_skinny_intr,
+	mfi_skinny_post
+};
+
 #define mfi_fw_state(_s) 	((_s)->sc_iop->mio_fw_state(_s))
 #define mfi_intr_enable(_s) 	((_s)->sc_iop->mio_intr_ena(_s))
 #define mfi_intr_disable(_s) 	((_s)->sc_iop->mio_intr_dis(_s))
@@ -402,11 +416,17 @@ mfi_transition_firmware(struct mfi_softc
 			printf("%s: firmware fault\n", DEVNAME(sc));
 			return 1;
 		case MFI_STATE_WAIT_HANDSHAKE:
-			mfi_write(sc, MFI_IDB, MFI_INIT_CLEAR_HANDSHAKE);
+			if (sc->sc_flags & MFI_IOP_SKINNY)
+				mfi_write(sc, MFI_SKINNY_IDB, MFI_INIT_CLEAR_HANDSHAKE);
+			else
+				mfi_write(sc, MFI_IDB, MFI_INIT_CLEAR_HANDSHAKE);
 			max_wait = 2;
 			break;
 		case MFI_STATE_OPERATIONAL:
-			mfi_write(sc, MFI_IDB, MFI_INIT_READY);
+			if (sc->sc_flags & MFI_IOP_SKINNY)
+				mfi_write(sc, MFI_SKINNY_IDB, MFI_INIT_READY);
+			else
+				mfi_write(sc, MFI_IDB, MFI_INIT_READY);
 			max_wait = 10;
 			break;
 		case MFI_STATE_UNDEFINED:
@@ -730,6 +750,9 @@ mfi_attach(struct mfi_softc *sc, enum mf
 	case MFI_IOP_GEN2:
 		sc->sc_iop = &mfi_iop_gen2;
 		break;
+	case MFI_IOP_SKINNY:
+		sc->sc_iop = &mfi_iop_skinny;
+		break;
 	default:
 		 panic("%s: unknown iop %d", DEVNAME(sc), iop);
 	}
@@ -2233,3 +2256,44 @@ mfi_gen2_post(struct mfi_softc *sc, stru
 	mfi_write(sc, MFI_IQP, 0x1 | ccb->ccb_pframe |
 	    (ccb->ccb_extra_frames << 1));
 }
+
+u_int32_t
+mfi_skinny_fw_state(struct mfi_softc *sc)
+{
+	return (mfi_read(sc, MFI_OSP));
+}
+
+void
+mfi_skinny_intr_dis(struct mfi_softc *sc)
+{
+	mfi_write(sc, MFI_OMSK, 0);
+}
+
+void
+mfi_skinny_intr_ena(struct mfi_softc *sc)
+{
+	mfi_write(sc, MFI_OMSK, ~0x00000001);
+}
+
+int
+mfi_skinny_intr(struct mfi_softc *sc)
+{
+	u_int32_t status;
+
+	status = mfi_read(sc, MFI_OSTS);
+	if (!ISSET(status, MFI_OSTS_SKINNY_INTR_VALID))
+		return (0);
+
+	/* write status back to acknowledge interrupt */
+	mfi_write(sc, MFI_OSTS, status);
+
+	return (1);
+}
+
+void
+mfi_skinny_post(struct mfi_softc *sc, struct mfi_ccb *ccb)
+{
+	mfi_write(sc, MFI_IQPL, 0x1 | ccb->ccb_pframe |
+	    (ccb->ccb_extra_frames << 1));
+	mfi_write(sc, MFI_IQPH, 0x00000000);
+}

Index: src/sys/dev/ic/mfireg.h
diff -u src/sys/dev/ic/mfireg.h:1.4 src/sys/dev/ic/mfireg.h:1.5
--- src/sys/dev/ic/mfireg.h:1.4	Tue Feb  9 00:05:18 2010
+++ src/sys/dev/ic/mfireg.h	Wed Mar 21 14:22:36 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: mfireg.h,v 1.4 2010/02/09 00:05:18 msaitoh Exp $ */
+/* $NetBSD: mfireg.h,v 1.5 2012/03/21 14:22:36 sborrill Exp $ */
 /* $OpenBSD: mfireg.h,v 1.24 2006/06/19 19:05:45 marco Exp $ */
 /*
  * Copyright (c) 2006 Marco Peereboom <ma...@peereboom.us>
@@ -46,6 +46,14 @@
 #define MFI_ODC					0xa0 /* outbound doorbell clr */
 #define MFI_OSP 				0xb0 /* outbound scratch pad */
 
+/*
+ * skinny specific changes
+*/
+#define MFI_SKINNY_IDB				0x00 /* Inbound doorbell is at 0x00 for skinny */
+#define MFI_IQPL				0x000000c0
+#define MFI_IQPH				0x000000c4
+#define MFI_OSTS_SKINNY_INTR_VALID		0x00000001
+
 /* * firmware states */
 #define MFI_STATE_MASK				0xf0000000
 #define MFI_STATE_UNDEFINED			0x00000000

Index: src/sys/dev/ic/mfivar.h
diff -u src/sys/dev/ic/mfivar.h:1.14 src/sys/dev/ic/mfivar.h:1.15
--- src/sys/dev/ic/mfivar.h:1.14	Tue Feb  9 00:05:18 2010
+++ src/sys/dev/ic/mfivar.h	Wed Mar 21 14:22:36 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: mfivar.h,v 1.14 2010/02/09 00:05:18 msaitoh Exp $ */
+/* $NetBSD: mfivar.h,v 1.15 2012/03/21 14:22:36 sborrill Exp $ */
 /* $OpenBSD: mfivar.h,v 1.28 2006/08/31 18:18:46 marco Exp $ */
 /*
  * Copyright (c) 2006 Marco Peereboom <ma...@peereboom.us>
@@ -99,7 +99,8 @@ TAILQ_HEAD(mfi_ccb_list, mfi_ccb);
 enum mfi_iop {
 	MFI_IOP_XSCALE,
 	MFI_IOP_PPC,
-	MFI_IOP_GEN2
+	MFI_IOP_GEN2,
+	MFI_IOP_SKINNY
 };
 
 struct mfi_iop_ops {

Index: src/sys/dev/pci/mfi_pci.c
diff -u src/sys/dev/pci/mfi_pci.c:1.12 src/sys/dev/pci/mfi_pci.c:1.13
--- src/sys/dev/pci/mfi_pci.c:1.12	Tue Feb  9 00:05:18 2010
+++ src/sys/dev/pci/mfi_pci.c	Wed Mar 21 14:22:35 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: mfi_pci.c,v 1.12 2010/02/09 00:05:18 msaitoh Exp $ */
+/* $NetBSD: mfi_pci.c,v 1.13 2012/03/21 14:22:35 sborrill Exp $ */
 /* $OpenBSD: mfi_pci.c,v 1.11 2006/08/06 04:40:08 brad Exp $ */
 /*
  * Copyright (c) 2006 Marco Peereboom <ma...@peereboom.us>
@@ -17,7 +17,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mfi_pci.c,v 1.12 2010/02/09 00:05:18 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mfi_pci.c,v 1.13 2012/03/21 14:22:35 sborrill Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -88,6 +88,11 @@ static const struct mfi_pci_subtype mfi_
 	{ 0x0,			0,		"" }
 };
 
+static const struct mfi_pci_subtype mfi_skinny_subtypes[] = {
+	{ PCI_VENDOR_IBM,	0x03b1,		"IBM ServeRAID M1015 SAS/SATA" },
+	{ 0x0,			0,		"" }
+};
+
 static const
 struct mfi_pci_device {
 	pcireg_t			mpd_vendor;
@@ -111,6 +116,8 @@ struct mfi_pci_device {
 	  MFI_IOP_GEN2,		mfi_gen2_subtypes },
 	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_SAS2108_2,
 	  MFI_IOP_GEN2,		mfi_gen2_subtypes },
+	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_SAS2008_1,
+	  MFI_IOP_SKINNY,	mfi_skinny_subtypes },
 };
 
 const struct mfi_pci_device *
@@ -176,7 +183,9 @@ mfi_pci_attach(device_t parent, device_t
 		return;
 	}
 
-	if (mpd->mpd_iop == MFI_IOP_GEN2)
+	sc->sc_flags = mpd->mpd_iop;
+
+	if (mpd->mpd_iop == MFI_IOP_GEN2 || mpd->mpd_iop == MFI_IOP_SKINNY)
 		regbar = MFI_BAR_GEN2;
 	else
 		regbar = MFI_BAR;

Reply via email to