diff options
| author | Dan Williams <dan.j.williams@intel.com> | 2009-09-08 15:01:14 -0400 |
|---|---|---|
| committer | Dan Williams <dan.j.williams@intel.com> | 2009-09-08 20:30:24 -0400 |
| commit | bb3207863014c7310593146f11fbc6573eab43c8 (patch) | |
| tree | d54da64e459d28969cdd9250cadaaa581cbae43d | |
| parent | 4fb9b9e8d55880523db550043dfb204696dd0422 (diff) | |
ioat: ignore reserved bits for chancnt and xfercap
Don't trust that the reserved bits are always zero, also sanity check
the returned value.
Signed-off-by: Maciej Sosnowski <maciej.sosnowski@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
| -rw-r--r-- | drivers/dma/ioat/dma.c | 7 | ||||
| -rw-r--r-- | drivers/dma/ioat/dma_v2.c | 7 |
2 files changed, 14 insertions, 0 deletions
diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c index 08417ad4edca..5173ba97ba31 100644 --- a/drivers/dma/ioat/dma.c +++ b/drivers/dma/ioat/dma.c | |||
| @@ -132,7 +132,14 @@ static int ioat1_enumerate_channels(struct ioatdma_device *device) | |||
| 132 | 132 | ||
| 133 | INIT_LIST_HEAD(&dma->channels); | 133 | INIT_LIST_HEAD(&dma->channels); |
| 134 | dma->chancnt = readb(device->reg_base + IOAT_CHANCNT_OFFSET); | 134 | dma->chancnt = readb(device->reg_base + IOAT_CHANCNT_OFFSET); |
| 135 | dma->chancnt &= 0x1f; /* bits [4:0] valid */ | ||
| 136 | if (dma->chancnt > ARRAY_SIZE(device->idx)) { | ||
| 137 | dev_warn(dev, "(%d) exceeds max supported channels (%zu)\n", | ||
| 138 | dma->chancnt, ARRAY_SIZE(device->idx)); | ||
| 139 | dma->chancnt = ARRAY_SIZE(device->idx); | ||
| 140 | } | ||
| 135 | xfercap_scale = readb(device->reg_base + IOAT_XFERCAP_OFFSET); | 141 | xfercap_scale = readb(device->reg_base + IOAT_XFERCAP_OFFSET); |
| 142 | xfercap_scale &= 0x1f; /* bits [4:0] valid */ | ||
| 136 | xfercap = (xfercap_scale == 0 ? -1 : (1UL << xfercap_scale)); | 143 | xfercap = (xfercap_scale == 0 ? -1 : (1UL << xfercap_scale)); |
| 137 | dev_dbg(dev, "%s: xfercap = %d\n", __func__, xfercap); | 144 | dev_dbg(dev, "%s: xfercap = %d\n", __func__, xfercap); |
| 138 | 145 | ||
diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c index ca1134249341..137cf879265f 100644 --- a/drivers/dma/ioat/dma_v2.c +++ b/drivers/dma/ioat/dma_v2.c | |||
| @@ -359,7 +359,14 @@ static int ioat2_enumerate_channels(struct ioatdma_device *device) | |||
| 359 | 359 | ||
| 360 | INIT_LIST_HEAD(&dma->channels); | 360 | INIT_LIST_HEAD(&dma->channels); |
| 361 | dma->chancnt = readb(device->reg_base + IOAT_CHANCNT_OFFSET); | 361 | dma->chancnt = readb(device->reg_base + IOAT_CHANCNT_OFFSET); |
| 362 | dma->chancnt &= 0x1f; /* bits [4:0] valid */ | ||
| 363 | if (dma->chancnt > ARRAY_SIZE(device->idx)) { | ||
| 364 | dev_warn(dev, "(%d) exceeds max supported channels (%zu)\n", | ||
| 365 | dma->chancnt, ARRAY_SIZE(device->idx)); | ||
| 366 | dma->chancnt = ARRAY_SIZE(device->idx); | ||
| 367 | } | ||
| 362 | xfercap_log = readb(device->reg_base + IOAT_XFERCAP_OFFSET); | 368 | xfercap_log = readb(device->reg_base + IOAT_XFERCAP_OFFSET); |
| 369 | xfercap_log &= 0x1f; /* bits [4:0] valid */ | ||
| 363 | if (xfercap_log == 0) | 370 | if (xfercap_log == 0) |
| 364 | return 0; | 371 | return 0; |
| 365 | dev_dbg(dev, "%s: xfercap = %d\n", __func__, 1 << xfercap_log); | 372 | dev_dbg(dev, "%s: xfercap = %d\n", __func__, 1 << xfercap_log); |
