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--