diff options
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/hpsa.c | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index ec2503a720c6..08d96a9d9d0a 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c | |||
@@ -3107,7 +3107,8 @@ out: | |||
3107 | kfree(logdev_list); | 3107 | kfree(logdev_list); |
3108 | } | 3108 | } |
3109 | 3109 | ||
3110 | /* hpsa_scatter_gather takes a struct scsi_cmnd, (cmd), and does the pci | 3110 | /* |
3111 | * hpsa_scatter_gather takes a struct scsi_cmnd, (cmd), and does the pci | ||
3111 | * dma mapping and fills in the scatter gather entries of the | 3112 | * dma mapping and fills in the scatter gather entries of the |
3112 | * hpsa command, cp. | 3113 | * hpsa command, cp. |
3113 | */ | 3114 | */ |
@@ -3165,7 +3166,7 @@ static int hpsa_scatter_gather(struct ctlr_info *h, | |||
3165 | sglist_finished: | 3166 | sglist_finished: |
3166 | 3167 | ||
3167 | cp->Header.SGList = (u8) use_sg; /* no. SGs contig in this cmd */ | 3168 | cp->Header.SGList = (u8) use_sg; /* no. SGs contig in this cmd */ |
3168 | cp->Header.SGTotal = cpu_to_le16(use_sg); /* total sgs in this cmd list */ | 3169 | cp->Header.SGTotal = cpu_to_le16(use_sg); /* total sgs in cmd list */ |
3169 | return 0; | 3170 | return 0; |
3170 | } | 3171 | } |
3171 | 3172 | ||
@@ -6162,6 +6163,15 @@ static void hpsa_get_max_perf_mode_cmds(struct ctlr_info *h) | |||
6162 | } | 6163 | } |
6163 | } | 6164 | } |
6164 | 6165 | ||
6166 | /* If the controller reports that the total max sg entries is greater than 512, | ||
6167 | * then we know that chained SG blocks work. (Original smart arrays did not | ||
6168 | * support chained SG blocks and would return zero for max sg entries.) | ||
6169 | */ | ||
6170 | static int hpsa_supports_chained_sg_blocks(struct ctlr_info *h) | ||
6171 | { | ||
6172 | return h->maxsgentries > 512; | ||
6173 | } | ||
6174 | |||
6165 | /* Interrogate the hardware for some limits: | 6175 | /* Interrogate the hardware for some limits: |
6166 | * max commands, max SG elements without chaining, and with chaining, | 6176 | * max commands, max SG elements without chaining, and with chaining, |
6167 | * SG chain block size, etc. | 6177 | * SG chain block size, etc. |
@@ -6172,18 +6182,20 @@ static void hpsa_find_board_params(struct ctlr_info *h) | |||
6172 | h->nr_cmds = h->max_commands - 4; /* Allow room for some ioctls */ | 6182 | h->nr_cmds = h->max_commands - 4; /* Allow room for some ioctls */ |
6173 | h->maxsgentries = readl(&(h->cfgtable->MaxScatterGatherElements)); | 6183 | h->maxsgentries = readl(&(h->cfgtable->MaxScatterGatherElements)); |
6174 | h->fw_support = readl(&(h->cfgtable->misc_fw_support)); | 6184 | h->fw_support = readl(&(h->cfgtable->misc_fw_support)); |
6175 | /* | 6185 | if (hpsa_supports_chained_sg_blocks(h)) { |
6176 | * Limit in-command s/g elements to 32 save dma'able memory. | 6186 | /* Limit in-command s/g elements to 32 save dma'able memory. */ |
6177 | * Howvever spec says if 0, use 31 | ||
6178 | */ | ||
6179 | h->max_cmd_sg_entries = 31; | ||
6180 | if (h->maxsgentries > 512) { | ||
6181 | h->max_cmd_sg_entries = 32; | 6187 | h->max_cmd_sg_entries = 32; |
6182 | h->chainsize = h->maxsgentries - h->max_cmd_sg_entries; | 6188 | h->chainsize = h->maxsgentries - h->max_cmd_sg_entries; |
6183 | h->maxsgentries--; /* save one for chain pointer */ | 6189 | h->maxsgentries--; /* save one for chain pointer */ |
6184 | } else { | 6190 | } else { |
6185 | h->chainsize = 0; | 6191 | /* |
6192 | * Original smart arrays supported at most 31 s/g entries | ||
6193 | * embedded inline in the command (trying to use more | ||
6194 | * would lock up the controller) | ||
6195 | */ | ||
6196 | h->max_cmd_sg_entries = 31; | ||
6186 | h->maxsgentries = 31; /* default to traditional values */ | 6197 | h->maxsgentries = 31; /* default to traditional values */ |
6198 | h->chainsize = 0; | ||
6187 | } | 6199 | } |
6188 | 6200 | ||
6189 | /* Find out what task management functions are supported and cache */ | 6201 | /* Find out what task management functions are supported and cache */ |