diff options
Diffstat (limited to 'drivers/scsi/scsi.c')
| -rw-r--r-- | drivers/scsi/scsi.c | 45 |
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 | ||
| 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 | |||
| 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 | } |
| 255 | EXPORT_SYMBOL(scsi_put_command); | 264 | EXPORT_SYMBOL(scsi_put_command); |
| 256 | 265 | ||
| @@ -871,9 +880,9 @@ EXPORT_SYMBOL(scsi_device_get); | |||
| 871 | */ | 880 | */ |
| 872 | void scsi_device_put(struct scsi_device *sdev) | 881 | void 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) |
