Subject: patch to add support for LSI SAS devices to mpt
To: None <tech-kern@NetBSD.org>
From: Garrett D'Amore <garrett@damore.org>
List: tech-kern
Date: 07/26/2007 16:23:08
This is a multi-part message in MIME format.
--------------030402000706020804040702
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

I've attached a patch, that I'd like to see committed into -current.  
This adds support for newer SAS and similar devices to mpt, and does it 
in a way that still allows for SCSI devices to get the most performance.

I've tested this on Sun x4200 hardware, which contains an LSI SAS1064 
.... and in fact with this kernel I'm able to use these SAS devices as 
the root filesystem.   Note that read performance is quite nice, but 
write performance suffers somewhat due to the drive's write cache not 
being enabled.   I've not figured out how to do that just yet, but maybe 
someone else can add that later. :-)

This patch also changes which should make the driver friendlier to 
devices with more than 2 PCI functions.

I'm not on tech-kern (or any other NetBSD mailing lists), and as I'm not 
a TNF member anymore, someone else will need to commit it.  I'd 
appreciate getting an e-mail for this.

Ultimately I need to get this pulled up to 3.0 and 3.1.  I have a 
version of the patch for 3.0 (there are some very minor changes) that I 
can post if someone from TNF responds telling me that they will commit 
it.  (The patch for 3.1 and 3.0 is the same.  Only -current needed changes.)

Note that others have also tested this patch, although I've made some 
changes to suppress warning messages about async events and to use the 
Link status event to report the SAS link speed.  You might see a dmesg 
chunk that looks like this:

mpt0 at pci2 dev 3 function 0: Symbios Logic SAS1064
mpt0: interrupting at ioapic2 pin 0 (irq 11)
mpt0: Phy 0: Link Rate 3.0 Gbps
mpt0: Phy 1: Link Rate 3.0 Gbps
scsibus0 at mpt0: 63 targets, 8 luns per target

This work is was developed under a contract from TELES AG, who have 
contributed the code back to the NetBSD community.  They have not 
retained any further copyright interest in the work, so the original 
copyrights are left unaltered.

    -- Garrett



--------------030402000706020804040702
Content-Type: text/x-patch;
 name="mpt-netbsd-current.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="mpt-netbsd-current.patch"

? sys/dev/ic/mpi.c
? sys/dev/ic/mpireg.h
? sys/dev/ic/mpivar.h
? sys/dev/pci/mpi_pci.c
Index: sys/dev/ic/mpt.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/mpt.c,v
retrieving revision 1.8
diff -d -p -u -r1.8 mpt.c
--- sys/dev/ic/mpt.c	4 Mar 2007 06:01:58 -0000	1.8
+++ sys/dev/ic/mpt.c	26 Jul 2007 23:15:51 -0000
@@ -28,6 +28,7 @@
  * Additional Copyright (c) 2002 by Matthew Jacob under same license.
  */
 
+
 /*
  * mpt.c:
  *
@@ -35,6 +36,8 @@
  *
  * Adapted from the FreeBSD "mpt" driver by Jason R. Thorpe for
  * Wasabi Systems, Inc.
+ *
+ * Additional contributions by Garrett D'Amore on behalf of TELES AG.
  */
 
 #include <sys/cdefs.h>
@@ -167,13 +170,10 @@ mpt_soft_reset(mpt_softc_t *mpt)
 void
 mpt_hard_reset(mpt_softc_t *mpt)
 {
-	/* This extra read comes for the Linux source
-	 * released by LSI. It's function is undocumented!
-	 */
 	if (mpt->verbose) {
 		mpt_prt(mpt, "hard reset");
 	}
-	mpt_read(mpt, MPT_OFFSET_FUBAR);
+	mpt_write(mpt, MPT_OFFSET_SEQUENCE, 0xff);
 
 	/* Enable diagnostic registers */
 	mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_1);
@@ -189,17 +189,6 @@ mpt_hard_reset(mpt_softc_t *mpt)
 
 	/* Disable Diagnostic Register */
 	mpt_write(mpt, MPT_OFFSET_SEQUENCE, 0xFF);
-
-	/* Restore the config register values */
-	/*   Hard resets are known to screw up the BAR for diagnostic
-	     memory accesses (Mem1). */
-	mpt_set_config_regs(mpt);
-	if (mpt->mpt2 != NULL) {
-		mpt_set_config_regs(mpt->mpt2);
-	}
-
-	/* Note that if there is no valid firmware to run, the doorbell will
-	   remain in the reset state (0x00000000) */
 }
 
 /*
@@ -487,11 +476,7 @@ mpt_send_ioc_init(mpt_softc_t *mpt, u_in
 	bzero(&init, sizeof init);
 	init.WhoInit = who;
 	init.Function = MPI_FUNCTION_IOC_INIT;
-	if (mpt->is_fc) {
-		init.MaxDevices = 255;
-	} else {
-		init.MaxDevices = 16;
-	}
+	init.MaxDevices = mpt->mpt_max_devices;
 	init.MaxBuses = 1;
 	init.ReplyFrameSize = MPT_REPLY_SIZE;
 	init.MsgContext = 0x12071941;
@@ -1022,6 +1007,40 @@ mpt_disable_ints(mpt_softc_t *mpt)
 
 /* (Re)Initialize the chip for use */
 int
+mpt_hw_init(mpt_softc_t *mpt)
+{
+	u_int32_t	db;
+	int		try;
+
+	/*
+	 * Start by making sure we're not at FAULT or RESET state
+	 */
+	for (try = 0; try < MPT_MAX_TRYS; try++) {
+
+		db = mpt_rd_db(mpt);
+
+		switch (MPT_STATE(db)) {
+		case MPT_DB_STATE_READY:
+			return (0);
+
+		default:
+			/* if peer has already reset us, don't do it again! */
+			if (MPT_WHO(db) == MPT_DB_INIT_PCIPEER)
+				return (0);
+			/*FALLTHRU*/
+		case MPT_DB_STATE_RESET:
+		case MPT_DB_STATE_FAULT:
+			if (mpt_reset(mpt) != MPT_OK) {
+				DELAY(10000);
+				continue;
+			}
+			break;
+		}
+	}
+	return (EIO);
+}
+
+int
 mpt_init(mpt_softc_t *mpt, u_int32_t who)
 {
         int try;
@@ -1044,33 +1063,13 @@ mpt_init(mpt_softc_t *mpt, u_int32_t who
 	/*
 	 * Start by making sure we're not at FAULT or RESET state
 	 */
-	switch (mpt_rd_db(mpt) & MPT_DB_STATE_MASK) {
-	case MPT_DB_STATE_RESET:
-	case MPT_DB_STATE_FAULT:
-		if (mpt_reset(mpt) != MPT_OK) {
-			return (EIO);
-		}
-	default:
-		break;
-	}
+	if (mpt_hw_init(mpt) != 0)
+		return (EIO);
 
 	for (try = 0; try < MPT_MAX_TRYS; try++) {
 		/*
 		 * No need to reset if the IOC is already in the READY state.
-		 *
-		 * Force reset if initialization failed previously.
-		 * Note that a hard_reset of the second channel of a '929
-		 * will stop operation of the first channel.  Hopefully, if the
-		 * first channel is ok, the second will not require a hard
-		 * reset.
 		 */
-		if ((mpt_rd_db(mpt) & MPT_DB_STATE_MASK) !=
-		    MPT_DB_STATE_READY) {
-			if (mpt_reset(mpt) != MPT_OK) {
-				DELAY(10000);
-				continue;
-			}
-		}
 
 		if (mpt_get_iocfacts(mpt, &facts) != MPT_OK) {
 			mpt_prt(mpt, "mpt_get_iocfacts failed");
@@ -1083,6 +1082,7 @@ mpt_init(mpt_softc_t *mpt, u_int32_t who
 			    "Request Frame Size %u\n", facts.GlobalCredits,
 			    facts.BlockSize, facts.RequestFrameSize);
 		}
+		mpt->mpt_max_devices = facts.MaxDevices;
 		mpt->mpt_global_credits = facts.GlobalCredits;
 		mpt->request_frame_size = facts.RequestFrameSize;
 
@@ -1098,21 +1098,29 @@ mpt_init(mpt_softc_t *mpt, u_int32_t who
 			    pfp.MaxDevices);
 		}
 
-		if (pfp.PortType != MPI_PORTFACTS_PORTTYPE_SCSI &&
-		    pfp.PortType != MPI_PORTFACTS_PORTTYPE_FC) {
-			mpt_prt(mpt, "Unsupported Port Type (%x)",
-			    pfp.PortType);
-			return (ENXIO);
-		}
 		if (!(pfp.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR)) {
 			mpt_prt(mpt, "initiator role unsupported");
 			return (ENXIO);
 		}
-		if (pfp.PortType == MPI_PORTFACTS_PORTTYPE_FC) {
+
+		switch (pfp.PortType) {
+		case MPI_PORTFACTS_PORTTYPE_FC:
 			mpt->is_fc = 1;
-		} else {
-			mpt->is_fc = 0;
+			break;
+		case MPI_PORTFACTS_PORTTYPE_SCSI:
+			mpt->is_scsi = 1;
+			/* some SPI controllers (VMWare, Sun) lie */
+			mpt->mpt_max_devices = 16;
+			break;
+		case MPI_PORTFACTS_PORTTYPE_SAS:
+			mpt->is_sas = 1;
+			break;
+		default:
+			mpt_prt(mpt, "Unsupported Port Type (%x)",
+			    pfp.PortType);
+			return (ENXIO);
 		}
+
 		mpt->mpt_ini_id = pfp.PortSCSIID;
 
 		if (mpt_send_ioc_init(mpt, who) != MPT_OK) {
@@ -1156,7 +1164,7 @@ mpt_init(mpt_softc_t *mpt, u_int32_t who
 		 * (SPI only for now)
 		 */
 
-		if (mpt->is_fc == 0) {
+		if (mpt->is_scsi) {
 			if (mpt_read_config_info_spi(mpt)) {
 				return (EIO);
 			}
Index: sys/dev/ic/mpt.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/mpt.h,v
retrieving revision 1.5
diff -d -p -u -r1.5 mpt.h
--- sys/dev/ic/mpt.h	11 Dec 2005 12:21:27 -0000	1.5
+++ sys/dev/ic/mpt.h	26 Jul 2007 23:15:51 -0000
@@ -164,6 +164,7 @@ void mpt_free_reply(mpt_softc_t *, u_int
 void mpt_enable_ints(mpt_softc_t *);
 void mpt_disable_ints(mpt_softc_t *);
 u_int32_t mpt_pop_reply_queue(mpt_softc_t *);
+int mpt_hw_init(mpt_softc_t *);
 int mpt_init(mpt_softc_t *, u_int32_t);
 int mpt_reset(mpt_softc_t *);
 int mpt_send_handshake_cmd(mpt_softc_t *, size_t, void *);
Index: sys/dev/ic/mpt_mpilib.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/mpt_mpilib.h,v
retrieving revision 1.2
diff -d -p -u -r1.2 mpt_mpilib.h
--- sys/dev/ic/mpt_mpilib.h	16 Apr 2003 23:24:01 -0000	1.2
+++ sys/dev/ic/mpt_mpilib.h	26 Jul 2007 23:15:52 -0000
@@ -3152,6 +3152,8 @@ typedef struct _MSG_PORT_FACTS_REPLY
 #define MPI_PORTFACTS_PORTTYPE_INACTIVE         (0x00)
 #define MPI_PORTFACTS_PORTTYPE_SCSI             (0x01)
 #define MPI_PORTFACTS_PORTTYPE_FC               (0x10)
+#define	MPI_PORTFACTS_PORTTYPE_ISCSI		(0x20)
+#define	MPI_PORTFACTS_PORTTYPE_SAS		(0x30)
 
 /* ProtocolFlags values */
 
@@ -3285,6 +3287,15 @@ typedef struct _MSG_EVENT_ACK_REPLY
 #define MPI_EVENT_INTEGRATED_RAID           (0x0000000B)
 #define MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE (0x0000000C)
 #define MPI_EVENT_ON_BUS_TIMER_EXPIRED      (0x0000000D)
+#define	MPI_EVENT_QUEUE_FULL                (0x0000000E)
+#define	MPI_EVENT_SAS_DEVICE_STATUS_CHANGE  (0x0000000F)
+#define	MPI_EVENT_SAS_SES                   (0x00000010)
+#define	MPI_EVENT_PERSISTENT_TABLE_FULL     (0x00000011)
+#define MPI_EVENT_SAS_PHY_LINK_STATUS       (0x00000012)
+#define MPI_EVENT_SAS_DISCOVERY_ERROR       (0x00000013)
+#define MPI_EVENT_IR_RESYNC_UPDATE          (0x00000014)
+#define MPI_EVENT_IR2                       (0x00000015)
+#define	MPI_EVENT_SAS_DISCOVERY		    (0x00000016)
 
 /* AckRequired field values */
 
@@ -3406,6 +3417,28 @@ typedef struct _EVENT_DATA_RAID
 #define MPI_EVENT_RAID_RC_SMART_DATA                    (0x0A)
 #define MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED        (0x0B)
 
+/* MPI SAS Phy Link Event data */
+
+typedef struct _EVENT_DATA_SAS_PHY_LINK_STATUS
+{
+    U8                      PhyNum;                     /* 00h */
+    U8                      LinkRates;                  /* 01h */
+    U16                     DevHandle;                  /* 02h */
+    U64                     SASAddress;                 /* 04h */
+} EVENT_DATA_SAS_PHY_LINK_STATUS,
+  MPI_POINTER PTR_EVENT_DATA_SAS_PHY_LINK_STATUS,
+  EventDataSASPhyLinkStatus_t, MPI_POINTER pEventDataSASPhyLinkStatus_t;
+
+#define MPI_EVENT_SAS_PLS_LR_CURRENT_MASK               (0xF0)
+#define MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT              (4)
+#define MPI_EVENT_SAS_PLS_LR_PREVIOUS_MASK              (0x0F)
+#define MPI_EVENT_SAS_PLS_LR_PREVIOUS_SHIFT             (0)
+#define MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN               (0x00)
+#define MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED          (0x01)
+#define MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEG      (0x02)
+#define MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE     (0x03)
+#define MPI_EVENT_SAS_PLS_LR_RATE_1_5                   (0x08)
+#define MPI_EVENT_SAS_PLS_LR_RATE_3_0                   (0x09)
 
 /*****************************************************************************
 *
Index: sys/dev/ic/mpt_netbsd.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/mpt_netbsd.c,v
retrieving revision 1.11
diff -d -p -u -r1.11 mpt_netbsd.c
--- sys/dev/ic/mpt_netbsd.c	4 Mar 2007 06:01:59 -0000	1.11
+++ sys/dev/ic/mpt_netbsd.c	26 Jul 2007 23:15:52 -0000
@@ -72,6 +72,8 @@
  *
  * Adapted from the FreeBSD "mpt" driver by Jason R. Thorpe for
  * Wasabi Systems, Inc.
+ *
+ * Additional contributions by Garrett D'Amore on behalf of TELES AG.
  */
 
 #include <sys/cdefs.h>
@@ -122,13 +124,8 @@ mpt_scsipi_attach(mpt_softc_t *mpt)
 	chan->chan_channel = 0;
 	chan->chan_flags = 0;
 	chan->chan_nluns = 8;
-	if (mpt->is_fc) {
-		chan->chan_ntargets = 256;
-		chan->chan_id = 256;
-	} else {
-		chan->chan_ntargets = 16;
-		chan->chan_id = mpt->mpt_ini_id;
-	}
+	chan->chan_ntargets = mpt->mpt_max_devices;
+	chan->chan_id = mpt->mpt_ini_id;
 
 	(void) config_found(&mpt->sc_dev, &mpt->sc_channel, scsiprint);
 }
@@ -702,7 +699,7 @@ mpt_run_xfer(mpt_softc_t *mpt, struct sc
 		mpt_req->Control = MPI_SCSIIO_CONTROL_NODATATRANSFER;
 
 	/* Set the queue behavior. */
-	if (__predict_true(mpt->is_fc ||
+	if (__predict_true((!mpt->is_scsi) ||
 			   (mpt->mpt_tag_enable &
 			    (1 << periph->periph_target)))) {
 		switch (XS_CTL_TAGTYPE(xs)) {
@@ -725,16 +722,16 @@ mpt_run_xfer(mpt_softc_t *mpt, struct sc
 			break;
 
 		default:
-			if (mpt->is_fc)
-				mpt_req->Control |= MPI_SCSIIO_CONTROL_SIMPLEQ;
-			else
+			if (mpt->is_scsi)
 				mpt_req->Control |= MPI_SCSIIO_CONTROL_UNTAGGED;
+			else
+				mpt_req->Control |= MPI_SCSIIO_CONTROL_SIMPLEQ;
 			break;
 		}
 	} else
 		mpt_req->Control |= MPI_SCSIIO_CONTROL_UNTAGGED;
 
-	if (__predict_false(mpt->is_fc == 0 &&
+	if (__predict_false(mpt->is_scsi &&
 			    (mpt->mpt_disc_enable &
 			     (1 << periph->periph_target)) == 0))
 		mpt_req->Control |= MPI_SCSIIO_CONTROL_NO_DISCONNECT;
@@ -937,7 +934,7 @@ mpt_set_xfer_mode(mpt_softc_t *mpt, stru
 {
 	fCONFIG_PAGE_SCSI_DEVICE_1 tmp;
 
-	if (mpt->is_fc) {
+	if (!mpt->is_scsi) {
 		/*
 		 * SCSI transport settings don't make any sense for
 		 * Fibre Channel; silently ignore the request.
@@ -1254,6 +1251,44 @@ mpt_event_notify_reply(mpt_softc_t *mpt,
 		 */
 		break;
 
+	case MPI_EVENT_SAS_PHY_LINK_STATUS:
+		switch((msg->Data[0] >> 12) & 0x0f) {
+		case 0x00:
+			mpt_prt(mpt, "Phy %d: Link Status Unknown",
+			    msg->Data[0] & 0xff);
+			break;
+		case 0x01:
+			mpt_prt(mpt, "Phy %d: Link Disabled",
+			    msg->Data[0] & 0xff);
+			break;
+		case 0x02:
+			mpt_prt(mpt, "Phy %d: Failed Speed Negotiation",
+			    msg->Data[0] & 0xff);
+			break;
+		case 0x03:
+			mpt_prt(mpt, "Phy %d: SATA OOB Complete",
+			    msg->Data[0] & 0xff);
+			break;
+		case 0x08:
+			mpt_prt(mpt, "Phy %d: Link Rate 1.5 Gbps",
+			    msg->Data[0] & 0xff);
+			break;
+		case 0x09:
+			mpt_prt(mpt, "Phy %d: Link Rate 3.0 Gbps",
+			    msg->Data[0] & 0xff);
+			break;
+                default:
+			mpt_prt(mpt, "Phy %d: SAS Phy Link Status Event: "
+			    "Unknown event (%0x)",
+			    msg->Data[0] & 0xff, (msg->Data[0] >> 8) & 0xff);
+		}
+		break;
+
+	case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
+	case MPI_EVENT_SAS_DISCOVERY:
+		/* ignore these events for now */
+		break;
+
 	default:
 		mpt_prt(mpt, "Unknown async event: 0x%x", msg->Event);
 		break;
Index: sys/dev/ic/mpt_netbsd.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/mpt_netbsd.h,v
retrieving revision 1.5
diff -d -p -u -r1.5 mpt_netbsd.h
--- sys/dev/ic/mpt_netbsd.h	25 Dec 2006 18:39:48 -0000	1.5
+++ sys/dev/ic/mpt_netbsd.h	26 Jul 2007 23:15:52 -0000
@@ -70,6 +70,8 @@
  *
  * Adapted from the FreeBSD "mpt" driver by Jason R. Thorpe for
  * Wasabi Systems, Inc.
+ *
+ * Additional contributions by Garrett D'Amore on behalf of TELES AG.
  */
 
 #ifndef _DEV_IC_MPT_NETBSD_H_
@@ -168,8 +170,10 @@ typedef struct mpt_softc {
 	int		verbose : 3,
 			mpt_locksetup : 1,
 			is_fc : 1,
+			is_scsi : 1,
+			is_sas : 1,
 			bus : 1,
-			: 26;
+			: 23;
 
 	/* IOC facts */
 	uint16_t	mpt_global_credits;
@@ -235,9 +239,6 @@ typedef struct mpt_softc {
 	uint32_t		timeouts;	/* timeout count */
 	uint32_t		success;	/* success after timeout */
 
-	/* Companion part in a 929 or 1030, or NULL. */
-	struct mpt_softc	*mpt2;
-
 	/* To restore configuration after hard reset. */
 	void			(*sc_set_config_regs)(struct mpt_softc *);
 } mpt_softc_t;
Index: sys/dev/pci/mpt_pci.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/mpt_pci.c,v
retrieving revision 1.10
diff -d -p -u -r1.10 mpt_pci.c
--- sys/dev/pci/mpt_pci.c	16 Nov 2006 01:33:09 -0000	1.10
+++ sys/dev/pci/mpt_pci.c	26 Jul 2007 23:15:52 -0000
@@ -36,6 +36,10 @@
  */
 
 /*
+ * Additional contributions by Garrett D'Amore on behalf of TELES AG.
+ */
+
+/*
  * mpt_pci.c:
  *
  * NetBSD PCI-specific routines for LSI Fusion adapters.
@@ -71,74 +75,47 @@ struct mpt_pci_softc {
 	pcireg_t sc_pci_pmcsr;
 };
 
-static void	mpt_pci_link_peer(mpt_softc_t *);
-static void	mpt_pci_read_config_regs(mpt_softc_t *);
-static void	mpt_pci_set_config_regs(mpt_softc_t *);
-
 #define	MPP_F_FC	0x01	/* Fibre Channel adapter */
 #define	MPP_F_DUAL	0x02	/* Dual port adapter */
 
 static const struct mpt_pci_product {
 	pci_vendor_id_t		mpp_vendor;
 	pci_product_id_t	mpp_product;
-	int			mpp_flags;
-	const char		*mpp_name;
 } mpt_pci_products[] = {
-	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_1030,
-	  MPP_F_DUAL,
-	  "LSI Logic 53c1030 Ultra320 SCSI" },
-
-	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_FC909,
-	  MPP_F_FC,
-	  "LSI Logic FC909 FC Adapter" },
-	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_FC909A,
-	  MPP_F_FC,
-	  "LSI Logic FC909A FC Adapter" },
-	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_FC929,
-	  MPP_F_FC | MPP_F_DUAL,
-	  "LSI Logic FC929 FC Adapter" },
-	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_FC929_1,
-	  MPP_F_FC | MPP_F_DUAL,
-	  "LSI Logic FC929 FC Adapter" },
-	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_FC919,
-	  MPP_F_FC,
-	  "LSI Logic FC919 FC Adapter" },
-	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_FC919_1,
-	  MPP_F_FC,
-	  "LSI Logic FC919 FC Adapter" },
-	{ PCI_VENDOR_SYMBIOS,   PCI_PRODUCT_SYMBIOS_FC929X,
-	  MPP_F_FC | MPP_F_DUAL,
-	  "LSI Logic FC929X FC Adapter" },
-	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_FC919X,
-	  MPP_F_FC,
-	  "LSI Logic FC919X FC Adapter" },
-
-	{ 0,			0,
-	  0,
-	  NULL },
+	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_1030 },
+	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_FC909 },
+	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_FC909A },
+	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_FC929 },
+	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_FC929_1 },
+	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_FC919 },
+	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_FC919_1},
+	{ PCI_VENDOR_SYMBIOS,   PCI_PRODUCT_SYMBIOS_FC929X },
+	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_FC919X },
+	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_FC929X },
+	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_FC939X },
+	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_FC949X },
+	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_SAS1064 },
+	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_SAS1064A },
+	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_SAS1064E },
+	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_SAS1066 },
+	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_SAS1066E },
+	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_SAS1068 },
+	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_SAS1078 },
+	{ PCI_VENDOR_SYMBIOS,	PCI_PRODUCT_SYMBIOS_SAS1068E },
+	{ 0,			0 }
 };
 
-static const struct mpt_pci_product *
-mpt_pci_lookup(const struct pci_attach_args *pa)
+static int
+mpt_pci_match(struct device *parent, struct cfdata *cf, void *aux)
 {
+	struct pci_attach_args *pa = aux;
 	const struct mpt_pci_product *mpp;
 
-	for (mpp = mpt_pci_products; mpp->mpp_name != NULL; mpp++) {
+	for (mpp = mpt_pci_products; mpp->mpp_vendor != 0; mpp++) {
 		if (PCI_VENDOR(pa->pa_id) == mpp->mpp_vendor &&
 		    PCI_PRODUCT(pa->pa_id) == mpp->mpp_product)
-			return (mpp);
+			return (1);
 	}
-	return (NULL);
-}
-
-static int
-mpt_pci_match(struct device *parent, struct cfdata *cf,
-    void *aux)
-{
-	struct pci_attach_args *pa = aux;
-
-	if (mpt_pci_lookup(pa) != NULL)
-		return (1);
 
 	return (0);
 }
@@ -149,32 +126,23 @@ mpt_pci_attach(struct device *parent, st
 	struct mpt_pci_softc *psc = (void *) self;
 	mpt_softc_t *mpt = &psc->sc_mpt;
 	struct pci_attach_args *pa = aux;
-	const struct mpt_pci_product *mpp;
 	pci_intr_handle_t ih;
 	const char *intrstr;
 	pcireg_t reg, memtype;
 	bus_space_tag_t memt;
 	bus_space_handle_t memh;
 	int memh_valid;
+	char devinfo[200];
 
-	mpp = mpt_pci_lookup(pa);
-	if (mpp == NULL) {
-		printf("\n");
-		panic("mpt_pci_attach");
-	}
+	pci_devinfo(pa->pa_id, 0, 0, devinfo, sizeof (devinfo));
 
-	if (mpp->mpp_flags & MPP_F_FC) {
-		mpt->is_fc = 1;
-		aprint_naive(": Fibre Channel controller\n");
-	} else
-		aprint_naive(": SCSI controller\n");
-	aprint_normal(": %s\n", mpp->mpp_name);
+	aprint_naive("\n");
+	aprint_normal(": %s\n", devinfo);
 
 	psc->sc_pc = pa->pa_pc;
 	psc->sc_tag = pa->pa_tag;
 
 	mpt->sc_dmat = pa->pa_dmat;
-	mpt->sc_set_config_regs = mpt_pci_set_config_regs;
 
 	/*
 	 * Map the device.
@@ -248,24 +216,6 @@ mpt_pci_attach(struct device *parent, st
 		return;
 	}
 
-	/*
-	 * Save the PCI config register values.
-	 *
-	 * Hard resets are known to screw up the BAR for diagnostic
-	 * memory accesses (Mem1).
-	 *
-	 * Using Mem1 is know to make the chip stop responding to
-	 * configuration cycles, so we need to save it now.
-	 */
-	mpt_pci_read_config_regs(mpt);
-
-	/*
-	 * If we're a dual-port adapter, try to find our peer.  We
-	 * need to fix his PCI config registers, too.
-	 */
-	if (mpp->mpp_flags & MPP_F_DUAL)
-		mpt_pci_link_peer(mpt);
-
 	/* Initialize the hardware. */
 	if (mpt_init(mpt, MPT_DB_INIT_HOST) != 0) {
 		/* Error message already printed. */
@@ -279,102 +229,3 @@ mpt_pci_attach(struct device *parent, st
 CFATTACH_DECL(mpt_pci, sizeof(struct mpt_pci_softc),
     mpt_pci_match, mpt_pci_attach, NULL, NULL);
 
-/*
- * Find and remember our peer PCI function on a dual-port device.
- */
-static void
-mpt_pci_link_peer(mpt_softc_t *mpt)
-{
-	extern struct cfdriver mpt_cd;
-
-	struct mpt_pci_softc *peer_psc, *psc = (void *) mpt;
-	struct device *dev;
-	int unit, b, d, f, peer_b, peer_d, peer_f;
-
-	pci_decompose_tag(psc->sc_pc, psc->sc_tag, &b, &d, &f);
-
-	for (unit = 0; unit < mpt_cd.cd_ndevs; unit++) {
-		if (unit == device_unit(&mpt->sc_dev))
-			continue;
-		dev = device_lookup(&mpt_cd, unit);
-		if (dev == NULL)
-			continue;
-		if (device_parent(&mpt->sc_dev) != device_parent(dev))
-			continue;
-		/*
-		 * If we have the same parent, we know the other one
-		 * is attached with mpt_pci.
-		 */
-		peer_psc = (void *) dev;
-		if (peer_psc->sc_pc != psc->sc_pc)
-			continue;
-		pci_decompose_tag(peer_psc->sc_pc, peer_psc->sc_tag,
-		    &peer_b, &peer_d, &peer_f);
-		if (peer_b == b && peer_d == d) {
-			if (mpt->verbose)
-				mpt_prt(mpt, "linking with peer: %s",
-				    peer_psc->sc_mpt.sc_dev.dv_xname);
-			mpt->mpt2 = (mpt_softc_t *) peer_psc;
-			peer_psc->sc_mpt.mpt2 = mpt;
-			return;
-		}
-	}
-}
-
-/*
- * Save the volatile PCI configuration registers.
- */
-static void
-mpt_pci_read_config_regs(mpt_softc_t *mpt)
-{
-	struct mpt_pci_softc *psc = (void *) mpt;
-
-	psc->sc_pci_csr = pci_conf_read(psc->sc_pc, psc->sc_tag,
-	    PCI_COMMAND_STATUS_REG);
-	psc->sc_pci_bhlc = pci_conf_read(psc->sc_pc, psc->sc_tag,
-	    PCI_BHLC_REG);
-	psc->sc_pci_io_bar = pci_conf_read(psc->sc_pc, psc->sc_tag,
-	    PCI_MAPREG_START);
-	psc->sc_pci_mem0_bar[0] = pci_conf_read(psc->sc_pc, psc->sc_tag,
-	    PCI_MAPREG_START+0x04);
-	psc->sc_pci_mem0_bar[1] = pci_conf_read(psc->sc_pc, psc->sc_tag,
-	    PCI_MAPREG_START+0x08);
-	psc->sc_pci_mem1_bar[0] = pci_conf_read(psc->sc_pc, psc->sc_tag,
-	    PCI_MAPREG_START+0x0c);
-	psc->sc_pci_mem1_bar[1] = pci_conf_read(psc->sc_pc, psc->sc_tag,
-	    PCI_MAPREG_START+0x10);
-	psc->sc_pci_rom_bar = pci_conf_read(psc->sc_pc, psc->sc_tag,
-	    PCI_MAPREG_ROM);
-	psc->sc_pci_int = pci_conf_read(psc->sc_pc, psc->sc_tag,
-	    PCI_INTERRUPT_REG);
-	psc->sc_pci_pmcsr = pci_conf_read(psc->sc_pc, psc->sc_tag, 0x44);
-}
-
-/*
- * Restore the volatile PCI configuration registers.
- */
-static void
-mpt_pci_set_config_regs(mpt_softc_t *mpt)
-{
-	struct mpt_pci_softc *psc = (void *) mpt;
-
-	pci_conf_write(psc->sc_pc, psc->sc_tag, PCI_COMMAND_STATUS_REG,
-	    psc->sc_pci_csr);
-	pci_conf_write(psc->sc_pc, psc->sc_tag, PCI_BHLC_REG,
-	    psc->sc_pci_bhlc);
-	pci_conf_write(psc->sc_pc, psc->sc_tag, PCI_MAPREG_START,
-	    psc->sc_pci_io_bar);
-	pci_conf_write(psc->sc_pc, psc->sc_tag, PCI_MAPREG_START+0x04,
-	    psc->sc_pci_mem0_bar[0]);
-	pci_conf_write(psc->sc_pc, psc->sc_tag, PCI_MAPREG_START+0x08,
-	    psc->sc_pci_mem0_bar[1]);
-	pci_conf_write(psc->sc_pc, psc->sc_tag, PCI_MAPREG_START+0x0c,
-	    psc->sc_pci_mem1_bar[0]);
-	pci_conf_write(psc->sc_pc, psc->sc_tag, PCI_MAPREG_START+0x10,
-	    psc->sc_pci_mem1_bar[1]);
-	pci_conf_write(psc->sc_pc, psc->sc_tag, PCI_MAPREG_ROM,
-	    psc->sc_pci_rom_bar);
-	pci_conf_write(psc->sc_pc, psc->sc_tag, PCI_INTERRUPT_REG,
-	    psc->sc_pci_int);
-	pci_conf_write(psc->sc_pc, psc->sc_tag, 0x44, psc->sc_pci_pmcsr);
-}

--------------030402000706020804040702--