diff options
Diffstat (limited to 'drivers/scsi/scsi.c')
-rw-r--r-- | drivers/scsi/scsi.c | 55 |
1 files changed, 48 insertions, 7 deletions
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 36c92f961e15..ee6be596503d 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c | |||
@@ -197,11 +197,43 @@ static void | |||
197 | scsi_pool_free_command(struct scsi_host_cmd_pool *pool, | 197 | scsi_pool_free_command(struct scsi_host_cmd_pool *pool, |
198 | struct scsi_cmnd *cmd) | 198 | struct scsi_cmnd *cmd) |
199 | { | 199 | { |
200 | if (cmd->prot_sdb) | ||
201 | kmem_cache_free(scsi_sdb_cache, cmd->prot_sdb); | ||
202 | |||
200 | kmem_cache_free(pool->sense_slab, cmd->sense_buffer); | 203 | kmem_cache_free(pool->sense_slab, cmd->sense_buffer); |
201 | kmem_cache_free(pool->cmd_slab, cmd); | 204 | kmem_cache_free(pool->cmd_slab, cmd); |
202 | } | 205 | } |
203 | 206 | ||
204 | /** | 207 | /** |
208 | * scsi_host_alloc_command - internal function to allocate command | ||
209 | * @shost: SCSI host whose pool to allocate from | ||
210 | * @gfp_mask: mask for the allocation | ||
211 | * | ||
212 | * Returns a fully allocated command with sense buffer and protection | ||
213 | * data buffer (where applicable) or NULL on failure | ||
214 | */ | ||
215 | static struct scsi_cmnd * | ||
216 | scsi_host_alloc_command(struct Scsi_Host *shost, gfp_t gfp_mask) | ||
217 | { | ||
218 | struct scsi_cmnd *cmd; | ||
219 | |||
220 | cmd = scsi_pool_alloc_command(shost->cmd_pool, gfp_mask); | ||
221 | if (!cmd) | ||
222 | return NULL; | ||
223 | |||
224 | if (scsi_host_get_prot(shost) >= SHOST_DIX_TYPE0_PROTECTION) { | ||
225 | cmd->prot_sdb = kmem_cache_zalloc(scsi_sdb_cache, gfp_mask); | ||
226 | |||
227 | if (!cmd->prot_sdb) { | ||
228 | scsi_pool_free_command(shost->cmd_pool, cmd); | ||
229 | return NULL; | ||
230 | } | ||
231 | } | ||
232 | |||
233 | return cmd; | ||
234 | } | ||
235 | |||
236 | /** | ||
205 | * __scsi_get_command - Allocate a struct scsi_cmnd | 237 | * __scsi_get_command - Allocate a struct scsi_cmnd |
206 | * @shost: host to transmit command | 238 | * @shost: host to transmit command |
207 | * @gfp_mask: allocation mask | 239 | * @gfp_mask: allocation mask |
@@ -214,7 +246,7 @@ struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost, gfp_t gfp_mask) | |||
214 | struct scsi_cmnd *cmd; | 246 | struct scsi_cmnd *cmd; |
215 | unsigned char *buf; | 247 | unsigned char *buf; |
216 | 248 | ||
217 | cmd = scsi_pool_alloc_command(shost->cmd_pool, gfp_mask); | 249 | cmd = scsi_host_alloc_command(shost, gfp_mask); |
218 | 250 | ||
219 | if (unlikely(!cmd)) { | 251 | if (unlikely(!cmd)) { |
220 | unsigned long flags; | 252 | unsigned long flags; |
@@ -457,7 +489,7 @@ int scsi_setup_command_freelist(struct Scsi_Host *shost) | |||
457 | /* | 489 | /* |
458 | * Get one backup command for this host. | 490 | * Get one backup command for this host. |
459 | */ | 491 | */ |
460 | cmd = scsi_pool_alloc_command(shost->cmd_pool, gfp_mask); | 492 | cmd = scsi_host_alloc_command(shost, gfp_mask); |
461 | if (!cmd) { | 493 | if (!cmd) { |
462 | scsi_put_host_cmd_pool(gfp_mask); | 494 | scsi_put_host_cmd_pool(gfp_mask); |
463 | shost->cmd_pool = NULL; | 495 | shost->cmd_pool = NULL; |
@@ -902,11 +934,20 @@ void scsi_adjust_queue_depth(struct scsi_device *sdev, int tagged, int tags) | |||
902 | 934 | ||
903 | spin_lock_irqsave(sdev->request_queue->queue_lock, flags); | 935 | spin_lock_irqsave(sdev->request_queue->queue_lock, flags); |
904 | 936 | ||
905 | /* Check to see if the queue is managed by the block layer. | 937 | /* |
906 | * If it is, and we fail to adjust the depth, exit. */ | 938 | * Check to see if the queue is managed by the block layer. |
907 | if (blk_queue_tagged(sdev->request_queue) && | 939 | * If it is, and we fail to adjust the depth, exit. |
908 | blk_queue_resize_tags(sdev->request_queue, tags) != 0) | 940 | * |
909 | goto out; | 941 | * Do not resize the tag map if it is a host wide share bqt, |
942 | * because the size should be the hosts's can_queue. If there | ||
943 | * is more IO than the LLD's can_queue (so there are not enuogh | ||
944 | * tags) request_fn's host queue ready check will handle it. | ||
945 | */ | ||
946 | if (!sdev->host->bqt) { | ||
947 | if (blk_queue_tagged(sdev->request_queue) && | ||
948 | blk_queue_resize_tags(sdev->request_queue, tags) != 0) | ||
949 | goto out; | ||
950 | } | ||
910 | 951 | ||
911 | sdev->queue_depth = tags; | 952 | sdev->queue_depth = tags; |
912 | switch (tagged) { | 953 | switch (tagged) { |