From owner-p4-projects@FreeBSD.ORG Tue Aug 9 22:33:08 2011 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id B2DE6106567D; Tue, 9 Aug 2011 22:33:08 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 5C60B1065675 for ; Tue, 9 Aug 2011 22:33:08 +0000 (UTC) (envelope-from mjacob@freebsd.org) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:4f8:fff6::2d]) by mx1.freebsd.org (Postfix) with ESMTP id 49B208FC0C for ; Tue, 9 Aug 2011 22:33:08 +0000 (UTC) Received: from skunkworks.freebsd.org (localhost [127.0.0.1]) by skunkworks.freebsd.org (8.14.4/8.14.4) with ESMTP id p79MX8Za050594 for ; Tue, 9 Aug 2011 22:33:08 GMT (envelope-from mjacob@freebsd.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.4/8.14.4/Submit) id p79MX8qx050591 for perforce@freebsd.org; Tue, 9 Aug 2011 22:33:08 GMT (envelope-from mjacob@freebsd.org) Date: Tue, 9 Aug 2011 22:33:08 GMT Message-Id: <201108092233.p79MX8qx050591@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to mjacob@freebsd.org using -f From: Matt Jacob To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 197444 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 09 Aug 2011 22:33:09 -0000 http://p4web.freebsd.org/@@197444?ac=10 Change 197444 by mjacob@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 *);