aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorStephen M. Cameron <scameron@beardog.cce.hp.com>2010-07-19 14:46:28 -0400
committerJens Axboe <jaxboe@fusionio.com>2010-08-07 12:52:30 -0400
commitadfbc1ff342ece2e482254bcc5381fadfffbbb89 (patch)
treeaefa1482a22f0378a1397546595e7980fb4acf75 /drivers/block
parenta6528d017234b483283274fbdd360f3541befe19 (diff)
cciss: sanitize max commands
cciss: sanitize max commands Some controllers might try to tell us they support 0 commands in performant mode. This is a lie told by buggy firmware. We have to be wary of this lest we try to allocate a negative number of command blocks, which will be treated as unsigned, and get an out of memory condition. Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com> Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/cciss.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index b3060eced553..6d4c4f227d55 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -4112,13 +4112,25 @@ static int __devinit cciss_find_cfgtables(ctlr_info_t *h)
4112 return 0; 4112 return 0;
4113} 4113}
4114 4114
4115static void __devinit cciss_get_max_perf_mode_cmds(struct ctlr_info *h)
4116{
4117 h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands));
4118 if (h->max_commands < 16) {
4119 dev_warn(&h->pdev->dev, "Controller reports "
4120 "max supported commands of %d, an obvious lie. "
4121 "Using 16. Ensure that firmware is up to date.\n",
4122 h->max_commands);
4123 h->max_commands = 16;
4124 }
4125}
4126
4115/* Interrogate the hardware for some limits: 4127/* Interrogate the hardware for some limits:
4116 * max commands, max SG elements without chaining, and with chaining, 4128 * max commands, max SG elements without chaining, and with chaining,
4117 * SG chain block size, etc. 4129 * SG chain block size, etc.
4118 */ 4130 */
4119static void __devinit cciss_find_board_params(ctlr_info_t *h) 4131static void __devinit cciss_find_board_params(ctlr_info_t *h)
4120{ 4132{
4121 h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands)); 4133 cciss_get_max_perf_mode_cmds(h);
4122 h->nr_cmds = h->max_commands - 4; /* Allow room for some ioctls */ 4134 h->nr_cmds = h->max_commands - 4; /* Allow room for some ioctls */
4123 h->maxsgentries = readl(&(h->cfgtable->MaxSGElements)); 4135 h->maxsgentries = readl(&(h->cfgtable->MaxSGElements));
4124 /* 4136 /*