Author: mav Date: Thu Sep 16 12:39:50 2010 New Revision: 212732 URL: http://svn.freebsd.org/changeset/base/212732
Log: Fix panic, when due to some kind of congestion on FIS-based switching port multiplier some command triggers false positive timeout, but then completes normally. MFC after: 2 weeks Modified: head/sys/dev/ahci/ahci.c head/sys/dev/mvs/mvs.c head/sys/dev/siis/siis.c Modified: head/sys/dev/ahci/ahci.c ============================================================================== --- head/sys/dev/ahci/ahci.c Thu Sep 16 12:13:06 2010 (r212731) +++ head/sys/dev/ahci/ahci.c Thu Sep 16 12:39:50 2010 (r212732) @@ -1854,6 +1854,7 @@ ahci_end_transaction(struct ahci_slot *s device_t dev = slot->dev; struct ahci_channel *ch = device_get_softc(dev); union ccb *ccb = slot->ccb; + int lastto; bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map, BUS_DMASYNC_POSTWRITE); @@ -1955,11 +1956,6 @@ ahci_end_transaction(struct ahci_slot *s ch->oslots &= ~(1 << slot->slot); ch->rslots &= ~(1 << slot->slot); ch->aslots &= ~(1 << slot->slot); - if (et != AHCI_ERR_TIMEOUT) { - if (ch->toslots == (1 << slot->slot)) - xpt_release_simq(ch->sim, TRUE); - ch->toslots &= ~(1 << slot->slot); - } slot->state = AHCI_SLOT_EMPTY; slot->ccb = NULL; /* Update channel stats. */ @@ -1970,6 +1966,13 @@ ahci_end_transaction(struct ahci_slot *s ch->numtslots--; ch->numtslotspd[ccb->ccb_h.target_id]--; } + /* Cancel timeout state if request completed normally. */ + if (et != AHCI_ERR_TIMEOUT) { + lastto = (ch->toslots == (1 << slot->slot)); + ch->toslots &= ~(1 << slot->slot); + if (lastto) + xpt_release_simq(ch->sim, TRUE); + } /* If it was first request of reset sequence and there is no error, * proceed to second request. */ if ((ccb->ccb_h.func_code == XPT_ATA_IO) && Modified: head/sys/dev/mvs/mvs.c ============================================================================== --- head/sys/dev/mvs/mvs.c Thu Sep 16 12:13:06 2010 (r212731) +++ head/sys/dev/mvs/mvs.c Thu Sep 16 12:39:50 2010 (r212732) @@ -1552,6 +1552,7 @@ mvs_end_transaction(struct mvs_slot *slo device_t dev = slot->dev; struct mvs_channel *ch = device_get_softc(dev); union ccb *ccb = slot->ccb; + int lastto; //device_printf(dev, "cmd done status %d\n", et); bus_dmamap_sync(ch->dma.workrq_tag, ch->dma.workrq_map, @@ -1634,11 +1635,6 @@ mvs_end_transaction(struct mvs_slot *slo ch->oslots &= ~(1 << slot->slot); ch->rslots &= ~(1 << slot->slot); ch->aslots &= ~(1 << slot->slot); - if (et != MVS_ERR_TIMEOUT) { - if (ch->toslots == (1 << slot->slot)) - xpt_release_simq(ch->sim, TRUE); - ch->toslots &= ~(1 << slot->slot); - } slot->state = MVS_SLOT_EMPTY; slot->ccb = NULL; /* Update channel stats. */ @@ -1658,6 +1654,13 @@ mvs_end_transaction(struct mvs_slot *slo ch->numpslots--; ch->basic_dma = 0; } + /* Cancel timeout state if request completed normally. */ + if (et != MVS_ERR_TIMEOUT) { + lastto = (ch->toslots == (1 << slot->slot)); + ch->toslots &= ~(1 << slot->slot); + if (lastto) + xpt_release_simq(ch->sim, TRUE); + } /* If it was our READ LOG command - process it. */ if (ch->readlog) { mvs_process_read_log(dev, ccb); Modified: head/sys/dev/siis/siis.c ============================================================================== --- head/sys/dev/siis/siis.c Thu Sep 16 12:13:06 2010 (r212731) +++ head/sys/dev/siis/siis.c Thu Sep 16 12:39:50 2010 (r212732) @@ -1179,6 +1179,7 @@ siis_end_transaction(struct siis_slot *s device_t dev = slot->dev; struct siis_channel *ch = device_get_softc(dev); union ccb *ccb = slot->ccb; + int lastto; mtx_assert(&ch->mtx, MA_OWNED); bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map, @@ -1262,11 +1263,6 @@ siis_end_transaction(struct siis_slot *s ch->oslots &= ~(1 << slot->slot); ch->rslots &= ~(1 << slot->slot); ch->aslots &= ~(1 << slot->slot); - if (et != SIIS_ERR_TIMEOUT) { - if (ch->toslots == (1 << slot->slot)) - xpt_release_simq(ch->sim, TRUE); - ch->toslots &= ~(1 << slot->slot); - } slot->state = SIIS_SLOT_EMPTY; slot->ccb = NULL; /* Update channel stats. */ @@ -1275,6 +1271,13 @@ siis_end_transaction(struct siis_slot *s (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) { ch->numtslots[ccb->ccb_h.target_id]--; } + /* Cancel timeout state if request completed normally. */ + if (et != SIIS_ERR_TIMEOUT) { + lastto = (ch->toslots == (1 << slot->slot)); + ch->toslots &= ~(1 << slot->slot); + if (lastto) + xpt_release_simq(ch->sim, TRUE); + } /* If it was our READ LOG command - process it. */ if (ch->readlog) { siis_process_read_log(dev, ccb); _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"