diff options
Diffstat (limited to 'drivers/scsi/scsi.c')
-rw-r--r-- | drivers/scsi/scsi.c | 43 |
1 files changed, 26 insertions, 17 deletions
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 780d6dc92b42..fafc00deaade 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c | |||
@@ -156,8 +156,7 @@ static struct scsi_host_cmd_pool scsi_cmd_dma_pool = { | |||
156 | 156 | ||
157 | static DEFINE_MUTEX(host_cmd_pool_mutex); | 157 | static DEFINE_MUTEX(host_cmd_pool_mutex); |
158 | 158 | ||
159 | static struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost, | 159 | struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost, gfp_t gfp_mask) |
160 | gfp_t gfp_mask) | ||
161 | { | 160 | { |
162 | struct scsi_cmnd *cmd; | 161 | struct scsi_cmnd *cmd; |
163 | 162 | ||
@@ -178,6 +177,7 @@ static struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost, | |||
178 | 177 | ||
179 | return cmd; | 178 | return cmd; |
180 | } | 179 | } |
180 | EXPORT_SYMBOL_GPL(__scsi_get_command); | ||
181 | 181 | ||
182 | /* | 182 | /* |
183 | * Function: scsi_get_command() | 183 | * Function: scsi_get_command() |
@@ -214,9 +214,29 @@ struct scsi_cmnd *scsi_get_command(struct scsi_device *dev, gfp_t gfp_mask) | |||
214 | put_device(&dev->sdev_gendev); | 214 | put_device(&dev->sdev_gendev); |
215 | 215 | ||
216 | return cmd; | 216 | return cmd; |
217 | } | 217 | } |
218 | EXPORT_SYMBOL(scsi_get_command); | 218 | EXPORT_SYMBOL(scsi_get_command); |
219 | 219 | ||
220 | void __scsi_put_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd, | ||
221 | struct device *dev) | ||
222 | { | ||
223 | unsigned long flags; | ||
224 | |||
225 | /* changing locks here, don't need to restore the irq state */ | ||
226 | spin_lock_irqsave(&shost->free_list_lock, flags); | ||
227 | if (unlikely(list_empty(&shost->free_list))) { | ||
228 | list_add(&cmd->list, &shost->free_list); | ||
229 | cmd = NULL; | ||
230 | } | ||
231 | spin_unlock_irqrestore(&shost->free_list_lock, flags); | ||
232 | |||
233 | if (likely(cmd != NULL)) | ||
234 | kmem_cache_free(shost->cmd_pool->slab, cmd); | ||
235 | |||
236 | put_device(dev); | ||
237 | } | ||
238 | EXPORT_SYMBOL(__scsi_put_command); | ||
239 | |||
220 | /* | 240 | /* |
221 | * Function: scsi_put_command() | 241 | * Function: scsi_put_command() |
222 | * | 242 | * |
@@ -231,26 +251,15 @@ EXPORT_SYMBOL(scsi_get_command); | |||
231 | void scsi_put_command(struct scsi_cmnd *cmd) | 251 | void scsi_put_command(struct scsi_cmnd *cmd) |
232 | { | 252 | { |
233 | struct scsi_device *sdev = cmd->device; | 253 | struct scsi_device *sdev = cmd->device; |
234 | struct Scsi_Host *shost = sdev->host; | ||
235 | unsigned long flags; | 254 | unsigned long flags; |
236 | 255 | ||
237 | /* serious error if the command hasn't come from a device list */ | 256 | /* serious error if the command hasn't come from a device list */ |
238 | spin_lock_irqsave(&cmd->device->list_lock, flags); | 257 | spin_lock_irqsave(&cmd->device->list_lock, flags); |
239 | BUG_ON(list_empty(&cmd->list)); | 258 | BUG_ON(list_empty(&cmd->list)); |
240 | list_del_init(&cmd->list); | 259 | list_del_init(&cmd->list); |
241 | spin_unlock(&cmd->device->list_lock); | 260 | spin_unlock_irqrestore(&cmd->device->list_lock, flags); |
242 | /* changing locks here, don't need to restore the irq state */ | ||
243 | spin_lock(&shost->free_list_lock); | ||
244 | if (unlikely(list_empty(&shost->free_list))) { | ||
245 | list_add(&cmd->list, &shost->free_list); | ||
246 | cmd = NULL; | ||
247 | } | ||
248 | spin_unlock_irqrestore(&shost->free_list_lock, flags); | ||
249 | 261 | ||
250 | if (likely(cmd != NULL)) | 262 | __scsi_put_command(cmd->device->host, cmd, &sdev->sdev_gendev); |
251 | kmem_cache_free(shost->cmd_pool->slab, cmd); | ||
252 | |||
253 | put_device(&sdev->sdev_gendev); | ||
254 | } | 263 | } |
255 | EXPORT_SYMBOL(scsi_put_command); | 264 | EXPORT_SYMBOL(scsi_put_command); |
256 | 265 | ||