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.c45
1 files changed, 27 insertions, 18 deletions
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index c59f31533ab4..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
157static DEFINE_MUTEX(host_cmd_pool_mutex); 157static DEFINE_MUTEX(host_cmd_pool_mutex);
158 158
159static struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost, 159struct 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}
180EXPORT_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}
218EXPORT_SYMBOL(scsi_get_command); 218EXPORT_SYMBOL(scsi_get_command);
219 219
220void __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}
238EXPORT_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);
231void scsi_put_command(struct scsi_cmnd *cmd) 251void 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
250 if (likely(cmd != NULL))
251 kmem_cache_free(shost->cmd_pool->slab, cmd);
252 261
253 put_device(&sdev->sdev_gendev); 262 __scsi_put_command(cmd->device->host, cmd, &sdev->sdev_gendev);
254} 263}
255EXPORT_SYMBOL(scsi_put_command); 264EXPORT_SYMBOL(scsi_put_command);
256 265
@@ -871,9 +880,9 @@ EXPORT_SYMBOL(scsi_device_get);
871 */ 880 */
872void scsi_device_put(struct scsi_device *sdev) 881void scsi_device_put(struct scsi_device *sdev)
873{ 882{
883#ifdef CONFIG_MODULE_UNLOAD
874 struct module *module = sdev->host->hostt->module; 884 struct module *module = sdev->host->hostt->module;
875 885
876#ifdef CONFIG_MODULE_UNLOAD
877 /* The module refcount will be zero if scsi_device_get() 886 /* The module refcount will be zero if scsi_device_get()
878 * was called from a module removal routine */ 887 * was called from a module removal routine */
879 if (module && module_refcount(module) != 0) 888 if (module && module_refcount(module) != 0)