Commit cba3d38b authored by Stephen M. Cameron's avatar Stephen M. Cameron Committed by James Bottomley

[SCSI] hpsa: 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: default avatarStephen M. Cameron <scameron@beardog.cce.hp.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent 10f66018
...@@ -3505,13 +3505,25 @@ static int __devinit hpsa_find_cfgtables(struct ctlr_info *h) ...@@ -3505,13 +3505,25 @@ static int __devinit hpsa_find_cfgtables(struct ctlr_info *h)
return 0; return 0;
} }
static void __devinit hpsa_get_max_perf_mode_cmds(struct ctlr_info *h)
{
h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands));
if (h->max_commands < 16) {
dev_warn(&h->pdev->dev, "Controller reports "
"max supported commands of %d, an obvious lie. "
"Using 16. Ensure that firmware is up to date.\n",
h->max_commands);
h->max_commands = 16;
}
}
/* Interrogate the hardware for some limits: /* Interrogate the hardware for some limits:
* max commands, max SG elements without chaining, and with chaining, * max commands, max SG elements without chaining, and with chaining,
* SG chain block size, etc. * SG chain block size, etc.
*/ */
static void __devinit hpsa_find_board_params(struct ctlr_info *h) static void __devinit hpsa_find_board_params(struct ctlr_info *h)
{ {
h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands)); hpsa_get_max_perf_mode_cmds(h);
h->nr_cmds = h->max_commands - 4; /* Allow room for some ioctls */ h->nr_cmds = h->max_commands - 4; /* Allow room for some ioctls */
h->maxsgentries = readl(&(h->cfgtable->MaxScatterGatherElements)); h->maxsgentries = readl(&(h->cfgtable->MaxScatterGatherElements));
/* /*
...@@ -4056,7 +4068,7 @@ static __devinit void hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h) ...@@ -4056,7 +4068,7 @@ static __devinit void hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h)
if (!(trans_support & PERFORMANT_MODE)) if (!(trans_support & PERFORMANT_MODE))
return; return;
h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands)); hpsa_get_max_perf_mode_cmds(h);
h->max_sg_entries = 32; h->max_sg_entries = 32;
/* Performant mode ring buffer and supporting data structures */ /* Performant mode ring buffer and supporting data structures */
h->reply_pool_size = h->max_commands * sizeof(u64); h->reply_pool_size = h->max_commands * sizeof(u64);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment