PERFORCE change 197444 for review
Matt Jacob
mjacob at FreeBSD.org
Tue Aug 9 22:33:09 UTC 2011
http://p4web.freebsd.org/@@197444?ac=10
Change 197444 by mjacob at mjacob-sandbox on 2011/08/09 22:32:23
Do some cleanup so that this SIM can unload too.
Handle the case that seems to occur with Phase 10 FW where
Gen1 enclosure disks (not the SES) don't attach. Key off
of SAS_DISCOVERY_EVENT end and then get SAS extended device
config with the NxtHandle option to see who to add. It turns
out there a bunch of devices without PHYs filled out, but
the ones that are then can actually get attached.
Affected files ...
.. //depot/projects/mjacob-dev/sys/dev/mpt2sas/mpt2cam.c#5 edit
.. //depot/projects/mjacob-dev/sys/dev/mpt2sas/mpt2pci.c#5 edit
.. //depot/projects/mjacob-dev/sys/dev/mpt2sas/mpt2sas.c#7 edit
.. //depot/projects/mjacob-dev/sys/dev/mpt2sas/mpt2sas.h#8 edit
.. //depot/projects/mjacob-dev/sys/modules/mpt2sas/Makefile#1 add
Differences ...
==== //depot/projects/mjacob-dev/sys/dev/mpt2sas/mpt2cam.c#5 (text+ko) ====
@@ -191,15 +191,21 @@
}
-void
+/*
+ * Should be called locked
+ */
+int
mpt2sas_cam_detach(mpt2sas_t *mpt)
{
- if (mpt->sim != NULL) {
- xpt_free_path(mpt->path);
- xpt_bus_deregister(cam_sim_path(mpt->sim));
- cam_sim_free(mpt->sim, TRUE);
- mpt->sim = NULL;
- }
+ if (mpt->sim == NULL)
+ return (ENODEV);
+ if (mpt->sim->refcount > 2)
+ return (EBUSY);
+ xpt_free_path(mpt->path);
+ xpt_bus_deregister(cam_sim_path(mpt->sim));
+ cam_sim_free(mpt->sim, TRUE);
+ mpt->sim = NULL;
+ return (0);
}
/* This routine is used after a system crash to dump core onto the swap device.
==== //depot/projects/mjacob-dev/sys/dev/mpt2sas/mpt2pci.c#5 (text+ko) ====
@@ -203,6 +203,7 @@
if (bootverbose) {
mpt->prt_mask |= MP2PRT_INFO;
}
+ mpt->prt_mask = 0x3f;
}
}
@@ -213,13 +214,14 @@
struct sysctl_ctx_list *ctx;
struct sysctl_oid *tree;
mpt2sas_t *mpt;
- int iqd;
+ int iqd, result;
mpt = (mpt2sas_t *)device_get_softc(dev);
if (mpt == NULL) {
device_printf(dev, "cannot allocate softc\n");
return (ENOMEM);
}
+ result = 0;
memset(mpt, 0, sizeof(mpt2sas_t));
mpt->dev = dev;
mpt2sas_set_options(mpt);
@@ -259,6 +261,7 @@
mpt->pci_mem_reg = bus_alloc_resource(dev, SYS_RES_MEMORY, &mpt->pci_mem_rid, 0, ~0, 0, RF_ACTIVE);
if (mpt->pci_mem_reg == NULL) {
mpt2sas_prt(mpt, MP2PRT_ERR, "Unable to memory map registers.\n");
+ result = ENXIO;
goto bad;
} else {
mpt->pci_mem_st = rman_get_bustag(mpt->pci_mem_reg);
@@ -290,6 +293,7 @@
}
mpt->pci_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &iqd, RF_ACTIVE | RF_SHAREABLE);
if (mpt->pci_irq == NULL) {
+ result = ENXIO;
mpt2sas_prt(mpt, MP2PRT_ERR, "could not allocate interrupt\n");
goto bad;
}
@@ -301,6 +305,7 @@
/* Register the interrupt handler */
if (bus_setup_intr(dev, mpt->pci_irq, MPT2_IFLAGS, NULL, mpt2sas_pci_intr, mpt, &mpt->ih)) {
+ result = ENXIO;
mpt2sas_prt(mpt, MP2PRT_ERR, "could not setup interrupt\n");
goto bad;
}
@@ -312,7 +317,8 @@
/* Initialize the hardware */
if (mpt->disabled == 0) {
- if (mpt2sas_attach(mpt) != 0) {
+ result = mpt2sas_attach(mpt);
+ if (result != 0) {
goto bad;
}
} else {
@@ -333,7 +339,7 @@
/*
* but return zero to preserve unit numbering
*/
- return (0);
+ return (result);
}
static void
@@ -390,10 +396,11 @@
{
mpt2sas_t *mpt = (mpt2sas_t*)device_get_softc(dev);
- if (mpt) {
+ if (mpt && mpt->disabled == 0) {
+ int r = mpt2sas_detach(mpt);
+ if (r)
+ return (r);
mpt2sas_disable_ints(mpt);
- mpt2sas_detach(mpt);
- mpt2sas_reset(mpt);
mpt2sas_mem_free(mpt);
mpt2sas_free_bus_resources(mpt);
}
==== //depot/projects/mjacob-dev/sys/dev/mpt2sas/mpt2sas.c#7 (text+ko) ====
@@ -210,8 +210,6 @@
mpt->cfg_ExtPageLength = le16toh(m->ExtPageLength);
mpt->cfg_ExtPageType = m->ExtPageType;
}
- } else {
- mpt2sas_prt(mpt, MP2PRT_ERR, "%s: MPI2_CONFIG_REPLY IOC STATUS %#x\n", __func__, req->IOCStatus);
}
} else {
mpt2sas_prt(mpt, MP2PRT_ERR, "%s: MPI2_FUNCTION_CONFIG with no reply frame\n", __func__);
@@ -339,6 +337,86 @@
}
static void
+mpt2sas_discovery_change(mpt2sas_t *mpt)
+{
+ int off, error;
+ MPI2_CONFIG_REQUEST *rqs;
+ MPI2_CONFIG_PAGE_HEADER hdr;
+ MPI2_CONFIG_PAGE_SAS_DEV_0 *sio;
+ U16 handle, cfglen;
+ struct topochg *tp;
+ request_t *req;
+
+ if (mpt2sas_get_cfgbuf(mpt, &off)) {
+ mpt2sas_prt(mpt, MP2PRT_WARN, "%s: cannot allocate config buffer\n", __func__);
+ return;
+ }
+ error = mpt2sas_read_config_header(mpt, MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE, 0);
+ if (error) {
+ mpt2sas_free_cfgbuf(mpt, off);
+ return;
+ }
+ cfglen = mpt->cfg_ExtPageLength;
+ hdr = mpt->cfg_hdr;
+ handle = 0xffff;
+ for (;;) {
+ MPT2SAS_GET_REQUEST(mpt, req);
+ if (req == NULL) {
+ mpt2sas_free_cfgbuf(mpt, off);
+ return;
+ }
+ req->flags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
+ rqs = MPT2_REQ2RQS(mpt, req);
+ memset(rqs, 0, sizeof (MPI2_CONFIG_REQUEST));
+ rqs->Function = MPI2_FUNCTION_CONFIG;
+ rqs->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
+ rqs->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
+ rqs->ExtPageLength = htole16(cfglen);
+ rqs->PageAddress = htole32(MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE | handle);
+ rqs->Header = hdr;
+ mpt2sas_single_sge(&rqs->PageBufferSGE.MpiSimple, mpt->config.paddr + off, cfglen << 2, MPI2_SGE_FLAGS_IOC_TO_HOST|SINGLE_SGE);
+ memset(&mpt->config.vaddr[off], 0, MPT2_CONFIG_DATA_SIZE(mpt));
+ mpt2sas_send_cmd(mpt, req);
+ error = mpt2sas_wait_req(mpt, req, REQ_STATE_DONE, REQ_STATE_DONE, 1000);
+ if (error) {
+ if (error != EIO || mpt->iocsts != MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) {
+ MPT2SAS_SYNC_ERR_NORET(mpt, error);
+ }
+ break;
+ }
+ bus_dmamap_sync(mpt->config.dmat, mpt->config.dmap, BUS_DMASYNC_POSTREAD);
+ sio = (MPI2_CONFIG_PAGE_SAS_DEV_0 *) &mpt->config.vaddr[off];
+ mpt2host_sas_dev_page0_convert(dsc);
+ mpt2sas_prt(mpt, MP2PRT_CONFIG, "%s: DevHandle %x SAS Address 0x%016jx Name 0x%016jx DeviceInfo 0x%08x PhyNum 0x%02x\n", __func__,
+ sio->DevHandle, (uintmax_t) le64toh(sio->SASAddress), (uintmax_t) le64toh(sio->DeviceName), le32toh(sio->DeviceInfo),
+ sio->PhyNum);
+ handle = sio->DevHandle;
+ if (mpt2_hdl2dev(mpt, handle)) {
+ continue;
+ }
+ TAILQ_FOREACH(tp, &mpt->topo_wait_list, links) {
+ if (tp->create && tp->hdl == handle) {
+ break;
+ }
+ }
+ if (tp) {
+ continue;
+ }
+ tp = TAILQ_FIRST(&mpt->topo_free_list);
+ if (tp == NULL) {
+ mpt2sas_free_cfgbuf(mpt, off);
+ return;
+ }
+ TAILQ_REMOVE(&mpt->topo_free_list, tp, links);
+ tp->hdl = handle;
+ tp->create = 1;
+ TAILQ_INSERT_TAIL(&mpt->topo_wait_list, tp, links);
+ }
+ mpt2sas_free_cfgbuf(mpt, off);
+ mpt->fabchanged = 0;
+}
+
+static void
mpt2sas_topology_change(mpt2sas_t *mpt, MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST *tpl)
{
static const char *lrstat[16] = {
@@ -552,8 +630,16 @@
mpt2sas_prt(mpt, MP2PRT_INFO, "MPI2_EVENT_IS_OPERATION_STATUS\n");
break;
case MPI2_EVENT_SAS_DISCOVERY:
- mpt2sas_prt(mpt, MP2PRT_CONFIG, "MPI2_EVENT_SAS_DISCOVERY\n");
+ {
+ MPI2_EVENT_DATA_SAS_DISCOVERY *p = (MPI2_EVENT_DATA_SAS_DISCOVERY *)evp->EventData;
+ mpt2host_sas_discovery_event_convert(p);
+ mpt2sas_prt(mpt, MP2PRT_CONFIG2, "MPI2_EVENT_SAS_DISCOVERY: Flags=%x ReasonCode=%x PhysicalPort=%x DiscoveryStatus=%x\n",
+ p->Flags, p->ReasonCode, p->PhysicalPort, p->DiscoveryStatus);
+ if (p->Flags == MPI2_EVENT_SAS_DISC_DEVICE_CHANGE && p->ReasonCode == MPI2_EVENT_SAS_DISC_RC_COMPLETED) {
+ mpt->fabchanged = 1;
+ }
break;
+ }
case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE:
mpt2sas_prt(mpt, MP2PRT_CONFIG, "MPI2_EVENT_SAS_BROADCAST_PRIMITIVE\n");
break;
@@ -1052,6 +1138,11 @@
MPT2_2_HOST32(sio, Reserved2);
MPT2_2_HOST32(sio, Reserved3);
}
+
+void mpt2host_sas_discovery_event_convert(MPI2_EVENT_DATA_SAS_DISCOVERY *sp)
+{
+ MPT2_2_HOST32(sp, DiscoveryStatus);
+}
#endif
/******************************* Discovery and SAS/IOC Config Routines **************************/
@@ -2009,6 +2100,7 @@
return (EIO);
}
+ mpt2sas_prt(mpt, MP2PRT_CONFIG, "IO Unit Page 1 Flags = 0x%x\n", mpt->iounit_pg1_flags);
base = mpt->iounit_pg1_flags;
if (mpt->ioc_facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING) {
base &= ~MPI2_IOUNITPAGE1_DISABLE_TASK_SET_FULL_HANDLING;
@@ -2222,6 +2314,9 @@
break;
}
}
+ if (mpt->fabchanged) {
+ mpt2sas_discovery_change(mpt);
+ }
if (mpt->ehook_active == 0 && mpt->path && mpt->devchanged) {
sas_dev_t *dp;
int r;
@@ -2294,17 +2389,20 @@
MPT2_LOCK(mpt);
mpt->ehook.ich_func = mpt2sas_intr_enable;
mpt->ehook.ich_arg = mpt;
+ mpt->ehook_active = 1;
if (config_intrhook_establish(&mpt->ehook) != 0) {
+ mpt->ehook_active = 0;
return (-EIO);
}
- mpt->ehook_active = 1;
callout_init(&mpt->watchdog, 1);
MPT2_UNLOCK(mpt);
error = mpt2sas_init(mpt);
if (error) {
MPT2_LOCK(mpt);
- config_intrhook_disestablish(&mpt->ehook);
- mpt->ehook_active = 0;
+ if (mpt->ehook_active) {
+ mpt->ehook_active = 0;
+ config_intrhook_disestablish(&mpt->ehook);
+ }
MPT2_UNLOCK(mpt);
return (error);
}
@@ -2316,8 +2414,10 @@
error = mpt2sas_cam_attach(mpt);
if (error) {
MPT2_LOCK(mpt);
- config_intrhook_disestablish(&mpt->ehook);
- mpt->ehook_active = 0;
+ if (mpt->ehook_active) {
+ mpt->ehook_active = 0;
+ config_intrhook_disestablish(&mpt->ehook);
+ }
MPT2_UNLOCK(mpt);
return (error);
}
@@ -2331,14 +2431,20 @@
int
mpt2sas_detach(mpt2sas_t *mpt)
{
+ int res;
+
MPT2_LOCK(mpt);
+ res = mpt2sas_cam_detach(mpt);
+ if (res) {
+ MPT2_UNLOCK(mpt);
+ return (res);
+ }
if (mpt->ehook_active) {
config_intrhook_disestablish(&mpt->ehook);
mpt->ehook_active = 0;
}
- if (callout_active(&mpt->watchdog)) {
+ if (callout_active(&mpt->watchdog))
callout_drain(&mpt->watchdog);
- }
TAILQ_REMOVE(&mpt2sas_tailq, mpt, links);
MPT2_UNLOCK(mpt);
return (0);
==== //depot/projects/mjacob-dev/sys/dev/mpt2sas/mpt2sas.h#8 (text+ko) ====
@@ -307,11 +307,13 @@
void mpt2host_portfacts_convert(MPI2_PORT_FACTS_REPLY *);
void mpt2host_phydata_convert(MPI2_SAS_IO_UNIT0_PHY_DATA *);
void mpt2host_sas_dev_page0_convert(MPI2_CONFIG_PAGE_SAS_DEV_0 *);
+void mpt2host_sas_discovery_event_convert(MPI2_EVENT_DATA_SAS_DISCOVERY *);
#else
#define mpt2host_iocfacts_convert(x) do { ; } while (0)
#define mpt2host_portfacts_convert(x) do { ; } while (0)
#define mpt2host_phydata_convert(x) do { ; } while (0)
#define mpt2host_sas_dev_page0_convert(x) do { ; } while (0)
+#define mpt2host_sas_discovery_event_convert(x) do { ; } while (0)
#endif
@@ -529,6 +531,7 @@
*/
unsigned int
portenabled : 1,
+ fabchanged : 1,
devchanged : 1,
outofbeer : 1,
acks_needed : 1,
@@ -696,7 +699,7 @@
/**************************** CAM Routines ***************************/
int mpt2sas_cam_attach(mpt2sas_t *);
-void mpt2sas_cam_detach(mpt2sas_t *);
+int mpt2sas_cam_detach(mpt2sas_t *);
void mpt2sas_cam_done(mpt2sas_t *, request_t *, MPI2_SCSI_IO_REPLY *);
int mpt2sas_run_scsicmd(mpt2sas_t *, U16, U8 *, int, bus_addr_t, bus_size_t, boolean_t);
int mpt2sas_scsi_abort(mpt2sas_t *, request_t *);
More information about the p4-projects
mailing list