aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/scsi.c67
1 files changed, 25 insertions, 42 deletions
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index c4dd0bfc663a..586c241c941e 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -161,47 +161,20 @@ static struct scsi_host_cmd_pool scsi_cmd_dma_pool = {
161static DEFINE_MUTEX(host_cmd_pool_mutex); 161static DEFINE_MUTEX(host_cmd_pool_mutex);
162 162
163/** 163/**
164 * scsi_pool_alloc_command - internal function to get a fully allocated command 164 * scsi_host_free_command - internal function to release a command
165 * @pool: slab pool to allocate the command from 165 * @shost: host to free the command for
166 * @gfp_mask: mask for the allocation
167 *
168 * Returns a fully allocated command (with the allied sense buffer) or
169 * NULL on failure
170 */
171static struct scsi_cmnd *
172scsi_pool_alloc_command(struct scsi_host_cmd_pool *pool, gfp_t gfp_mask)
173{
174 struct scsi_cmnd *cmd;
175
176 cmd = kmem_cache_zalloc(pool->cmd_slab, gfp_mask | pool->gfp_mask);
177 if (!cmd)
178 return NULL;
179
180 cmd->sense_buffer = kmem_cache_alloc(pool->sense_slab,
181 gfp_mask | pool->gfp_mask);
182 if (!cmd->sense_buffer) {
183 kmem_cache_free(pool->cmd_slab, cmd);
184 return NULL;
185 }
186
187 return cmd;
188}
189
190/**
191 * scsi_pool_free_command - internal function to release a command
192 * @pool: slab pool to allocate the command from
193 * @cmd: command to release 166 * @cmd: command to release
194 * 167 *
195 * the command must previously have been allocated by 168 * the command must previously have been allocated by
196 * scsi_pool_alloc_command. 169 * scsi_host_alloc_command.
197 */ 170 */
198static void 171static void
199scsi_pool_free_command(struct scsi_host_cmd_pool *pool, 172scsi_host_free_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
200 struct scsi_cmnd *cmd)
201{ 173{
174 struct scsi_host_cmd_pool *pool = shost->cmd_pool;
175
202 if (cmd->prot_sdb) 176 if (cmd->prot_sdb)
203 kmem_cache_free(scsi_sdb_cache, cmd->prot_sdb); 177 kmem_cache_free(scsi_sdb_cache, cmd->prot_sdb);
204
205 kmem_cache_free(pool->sense_slab, cmd->sense_buffer); 178 kmem_cache_free(pool->sense_slab, cmd->sense_buffer);
206 kmem_cache_free(pool->cmd_slab, cmd); 179 kmem_cache_free(pool->cmd_slab, cmd);
207} 180}
@@ -217,22 +190,32 @@ scsi_pool_free_command(struct scsi_host_cmd_pool *pool,
217static struct scsi_cmnd * 190static struct scsi_cmnd *
218scsi_host_alloc_command(struct Scsi_Host *shost, gfp_t gfp_mask) 191scsi_host_alloc_command(struct Scsi_Host *shost, gfp_t gfp_mask)
219{ 192{
193 struct scsi_host_cmd_pool *pool = shost->cmd_pool;
220 struct scsi_cmnd *cmd; 194 struct scsi_cmnd *cmd;
221 195
222 cmd = scsi_pool_alloc_command(shost->cmd_pool, gfp_mask); 196 cmd = kmem_cache_zalloc(pool->cmd_slab, gfp_mask | pool->gfp_mask);
223 if (!cmd) 197 if (!cmd)
224 return NULL; 198 goto fail;
199
200 cmd->sense_buffer = kmem_cache_alloc(pool->sense_slab,
201 gfp_mask | pool->gfp_mask);
202 if (!cmd->sense_buffer)
203 goto fail_free_cmd;
225 204
226 if (scsi_host_get_prot(shost) >= SHOST_DIX_TYPE0_PROTECTION) { 205 if (scsi_host_get_prot(shost) >= SHOST_DIX_TYPE0_PROTECTION) {
227 cmd->prot_sdb = kmem_cache_zalloc(scsi_sdb_cache, gfp_mask); 206 cmd->prot_sdb = kmem_cache_zalloc(scsi_sdb_cache, gfp_mask);
228 207 if (!cmd->prot_sdb)
229 if (!cmd->prot_sdb) { 208 goto fail_free_sense;
230 scsi_pool_free_command(shost->cmd_pool, cmd);
231 return NULL;
232 }
233 } 209 }
234 210
235 return cmd; 211 return cmd;
212
213fail_free_sense:
214 kmem_cache_free(pool->sense_slab, cmd->sense_buffer);
215fail_free_cmd:
216 kmem_cache_free(pool->cmd_slab, cmd);
217fail:
218 return NULL;
236} 219}
237 220
238/** 221/**
@@ -320,7 +303,7 @@ void __scsi_put_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
320 } 303 }
321 304
322 if (likely(cmd != NULL)) 305 if (likely(cmd != NULL))
323 scsi_pool_free_command(shost->cmd_pool, cmd); 306 scsi_host_free_command(shost, cmd);
324} 307}
325EXPORT_SYMBOL(__scsi_put_command); 308EXPORT_SYMBOL(__scsi_put_command);
326 309
@@ -456,7 +439,7 @@ void scsi_destroy_command_freelist(struct Scsi_Host *shost)
456 439
457 cmd = list_entry(shost->free_list.next, struct scsi_cmnd, list); 440 cmd = list_entry(shost->free_list.next, struct scsi_cmnd, list);
458 list_del_init(&cmd->list); 441 list_del_init(&cmd->list);
459 scsi_pool_free_command(shost->cmd_pool, cmd); 442 scsi_host_free_command(shost, cmd);
460 } 443 }
461 shost->cmd_pool = NULL; 444 shost->cmd_pool = NULL;
462 scsi_put_host_cmd_pool(shost->unchecked_isa_dma ? GFP_DMA : GFP_KERNEL); 445 scsi_put_host_cmd_pool(shost->unchecked_isa_dma ? GFP_DMA : GFP_KERNEL);