From owner-svn-src-head@FreeBSD.ORG Wed Feb 1 13:39:53 2012 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 511341065672; Wed, 1 Feb 2012 13:39:53 +0000 (UTC) (envelope-from raj@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 219498FC08; Wed, 1 Feb 2012 13:39:53 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q11Ddr8w089248; Wed, 1 Feb 2012 13:39:53 GMT (envelope-from raj@svn.freebsd.org) Received: (from raj@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q11DdrRY089245; Wed, 1 Feb 2012 13:39:53 GMT (envelope-from raj@svn.freebsd.org) Message-Id: <201202011339.q11DdrRY089245@svn.freebsd.org> From: Rafal Jaworowski Date: Wed, 1 Feb 2012 13:39:53 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r230865 - head/sys/dev/mvs X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 01 Feb 2012 13:39:53 -0000 Author: raj Date: Wed Feb 1 13:39:52 2012 New Revision: 230865 URL: http://svn.freebsd.org/changeset/base/230865 Log: Adjust mvs(4) to handle interrupt cause reg depending on the actual number of channels available - current code treats bits 4:7 in 'SATAHC interrupt mask' and 'SATAHC interrupt cause' as flags for SATA channels 2 and 3 - for embedded SATA controllers (SoC) these bits have been marked as reserved in datasheets so far, but for some new and upcoming chips they are used for purposes other than SATA Submitted by: Lukasz Plachno Reviewed by: mav Obtained from: Semihalf MFC after: 2 weeks Modified: head/sys/dev/mvs/mvs.h head/sys/dev/mvs/mvs_soc.c Modified: head/sys/dev/mvs/mvs.h ============================================================================== --- head/sys/dev/mvs/mvs.h Wed Feb 1 13:33:53 2012 (r230864) +++ head/sys/dev/mvs/mvs.h Wed Feb 1 13:39:52 2012 (r230865) @@ -61,6 +61,9 @@ #define CHIP_SOC_LED 0x2C /* SoC LED Configuration */ +/* Additional mask for SoC devices with less than 4 channels */ +#define CHIP_SOC_HC0_MASK(num) (0xff >> ((4 - (num)) * 2)) + /* Chip CCC registers */ #define CHIP_ICC 0x18008 #define CHIP_ICC_ALL_PORTS (1 << 4) /* all ports irq event */ Modified: head/sys/dev/mvs/mvs_soc.c ============================================================================== --- head/sys/dev/mvs/mvs_soc.c Wed Feb 1 13:33:53 2012 (r230864) +++ head/sys/dev/mvs/mvs_soc.c Wed Feb 1 13:39:52 2012 (r230865) @@ -216,7 +216,9 @@ mvs_ctlr_setup(device_t dev) if (ccc) ccim |= IC_HC0_COAL_DONE; /* Enable chip interrupts */ - ctlr->gmim = (ccc ? IC_HC0_COAL_DONE : IC_DONE_HC0) | IC_ERR_HC0; + ctlr->gmim = ((ccc ? IC_HC0_COAL_DONE : + (IC_DONE_HC0 & CHIP_SOC_HC0_MASK(ctlr->channels))) | + (IC_ERR_HC0 & CHIP_SOC_HC0_MASK(ctlr->channels))); ATA_OUTL(ctlr->r_mem, CHIP_SOC_MIM, ctlr->gmim | ctlr->pmim); return (0); } @@ -291,25 +293,26 @@ mvs_intr(void *data) struct mvs_controller *ctlr = data; struct mvs_intr_arg arg; void (*function)(void *); - int p; + int p, chan_num; u_int32_t ic, aic; ic = ATA_INL(ctlr->r_mem, CHIP_SOC_MIC); if ((ic & IC_HC0) == 0) return; + /* Acknowledge interrupts of this HC. */ aic = 0; - if (ic & (IC_DONE_IRQ << 0)) - aic |= HC_IC_DONE(0) | HC_IC_DEV(0); - if (ic & (IC_DONE_IRQ << 2)) - aic |= HC_IC_DONE(1) | HC_IC_DEV(1); - if (ic & (IC_DONE_IRQ << 4)) - aic |= HC_IC_DONE(2) | HC_IC_DEV(2); - if (ic & (IC_DONE_IRQ << 6)) - aic |= HC_IC_DONE(3) | HC_IC_DEV(3); + + /* Processing interrupts from each initialized channel */ + for (chan_num = 0; chan_num < ctlr->channels; chan_num++) { + if (ic & (IC_DONE_IRQ << (chan_num * 2))) + aic |= HC_IC_DONE(chan_num) | HC_IC_DEV(chan_num); + } + if (ic & IC_HC0_COAL_DONE) aic |= HC_IC_COAL; ATA_OUTL(ctlr->r_mem, HC_IC, ~aic); + /* Call per-port interrupt handler. */ for (p = 0; p < ctlr->channels; p++) { arg.cause = ic & (IC_ERR_IRQ|IC_DONE_IRQ);