aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/scsi.c')
-rw-r--r--drivers/scsi/scsi.c55
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
197scsi_pool_free_command(struct scsi_host_cmd_pool *pool, 197scsi_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 */
215static struct scsi_cmnd *
216scsi_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) {