IB/ipath: Fix calculation for number of kernel PIO buffers

If the module parameter "kpiobufs" is set too high, the calculation to
reset it to a sane value was incorrect.

Signed-off-by: Ralph Campbell <ralph.campbell@qlogic.com>
Signed-off-by: Bryan O'Sullivan <bryan.osullivan@qlogic.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
This commit is contained in:
Bryan O'Sullivan 2007-03-15 14:45:02 -07:00 committed by Roland Dreier
parent c8c6f5d496
commit 0ed3c594e3
1 changed files with 16 additions and 21 deletions

View File

@ -668,6 +668,7 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit)
{ {
int ret = 0, i; int ret = 0, i;
u32 val32, kpiobufs; u32 val32, kpiobufs;
u32 piobufs, uports;
u64 val; u64 val;
struct ipath_portdata *pd = NULL; /* keep gcc4 happy */ struct ipath_portdata *pd = NULL; /* keep gcc4 happy */
gfp_t gfp_flags = GFP_USER | __GFP_COMP; gfp_t gfp_flags = GFP_USER | __GFP_COMP;
@ -702,16 +703,17 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit)
* the in memory DMA'ed copies of the registers. This has to * the in memory DMA'ed copies of the registers. This has to
* be done early, before we calculate lastport, etc. * be done early, before we calculate lastport, etc.
*/ */
val = dd->ipath_piobcnt2k + dd->ipath_piobcnt4k; piobufs = dd->ipath_piobcnt2k + dd->ipath_piobcnt4k;
/* /*
* calc number of pioavail registers, and save it; we have 2 * calc number of pioavail registers, and save it; we have 2
* bits per buffer. * bits per buffer.
*/ */
dd->ipath_pioavregs = ALIGN(val, sizeof(u64) * BITS_PER_BYTE / 2) dd->ipath_pioavregs = ALIGN(piobufs, sizeof(u64) * BITS_PER_BYTE / 2)
/ (sizeof(u64) * BITS_PER_BYTE / 2); / (sizeof(u64) * BITS_PER_BYTE / 2);
uports = dd->ipath_cfgports ? dd->ipath_cfgports - 1 : 0;
if (ipath_kpiobufs == 0) { if (ipath_kpiobufs == 0) {
/* not set by user (this is default) */ /* not set by user (this is default) */
if ((dd->ipath_piobcnt2k + dd->ipath_piobcnt4k) > 128) if (piobufs >= (uports * IPATH_MIN_USER_PORT_BUFCNT) + 32)
kpiobufs = 32; kpiobufs = 32;
else else
kpiobufs = 16; kpiobufs = 16;
@ -719,31 +721,25 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit)
else else
kpiobufs = ipath_kpiobufs; kpiobufs = ipath_kpiobufs;
if (kpiobufs > if (kpiobufs + (uports * IPATH_MIN_USER_PORT_BUFCNT) > piobufs) {
(dd->ipath_piobcnt2k + dd->ipath_piobcnt4k - i = (int) piobufs -
(dd->ipath_cfgports * IPATH_MIN_USER_PORT_BUFCNT))) { (int) (uports * IPATH_MIN_USER_PORT_BUFCNT);
i = dd->ipath_piobcnt2k + dd->ipath_piobcnt4k -
(dd->ipath_cfgports * IPATH_MIN_USER_PORT_BUFCNT);
if (i < 0) if (i < 0)
i = 0; i = 0;
dev_info(&dd->pcidev->dev, "Allocating %d PIO bufs for " dev_info(&dd->pcidev->dev, "Allocating %d PIO bufs of "
"kernel leaves too few for %d user ports " "%d for kernel leaves too few for %d user ports "
"(%d each); using %u\n", kpiobufs, "(%d each); using %u\n", kpiobufs,
dd->ipath_cfgports - 1, piobufs, uports, IPATH_MIN_USER_PORT_BUFCNT, i);
IPATH_MIN_USER_PORT_BUFCNT, i);
/* /*
* shouldn't change ipath_kpiobufs, because could be * shouldn't change ipath_kpiobufs, because could be
* different for different devices... * different for different devices...
*/ */
kpiobufs = i; kpiobufs = i;
} }
dd->ipath_lastport_piobuf = dd->ipath_lastport_piobuf = piobufs - kpiobufs;
dd->ipath_piobcnt2k + dd->ipath_piobcnt4k - kpiobufs; dd->ipath_pbufsport =
dd->ipath_pbufsport = dd->ipath_cfgports > 1 uports ? dd->ipath_lastport_piobuf / uports : 0;
? dd->ipath_lastport_piobuf / (dd->ipath_cfgports - 1) val32 = dd->ipath_lastport_piobuf - (dd->ipath_pbufsport * uports);
: 0;
val32 = dd->ipath_lastport_piobuf -
(dd->ipath_pbufsport * (dd->ipath_cfgports - 1));
if (val32 > 0) { if (val32 > 0) {
ipath_dbg("allocating %u pbufs/port leaves %u unused, " ipath_dbg("allocating %u pbufs/port leaves %u unused, "
"add to kernel\n", dd->ipath_pbufsport, val32); "add to kernel\n", dd->ipath_pbufsport, val32);
@ -754,8 +750,7 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit)
dd->ipath_lastpioindex = dd->ipath_lastport_piobuf; dd->ipath_lastpioindex = dd->ipath_lastport_piobuf;
ipath_cdbg(VERBOSE, "%d PIO bufs for kernel out of %d total %u " ipath_cdbg(VERBOSE, "%d PIO bufs for kernel out of %d total %u "
"each for %u user ports\n", kpiobufs, "each for %u user ports\n", kpiobufs,
dd->ipath_piobcnt2k + dd->ipath_piobcnt4k, piobufs, dd->ipath_pbufsport, uports);
dd->ipath_pbufsport, dd->ipath_cfgports - 1);
dd->ipath_f_early_init(dd); dd->ipath_f_early_init(dd);