aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi.c
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2006-11-16 05:24:10 -0500
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-11-25 14:08:56 -0500
commitb58d91547fb17c65ad621f3f98b1f2c228c812a5 (patch)
tree4fafd4db96cb7931577f87b02a79cc6f52986333 /drivers/scsi/scsi.c
parent84ad58e4efcf80c154f693d4cc8f5c913511b760 (diff)
[SCSI] export scsi-ml functions needed by tgt_scsi_lib and its LLDs
This patch contains the needed changes to the scsi-ml for the target mode support. Note, per the last review we moved almost all the fields we added to the scsi_cmnd to our internal data structure which we are going to try and kill off when we can replace it with support from other parts of the kernel. The one field we left on was the offset variable. This is needed to handle the case where the target gets request that is so large that it cannot execute it in one dma operation. So max_secotors or a segment limit may limit the size of the transfer. In this case our tgt core code will break up the command into managable transfers and send them to the LLD one at a time. The offset is then used to tell the LLD where in the command we are at. Is there another field on the scsi_cmd for that? Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/scsi.c')
-rw-r--r--drivers/scsi/scsi.c43
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
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 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}
255EXPORT_SYMBOL(scsi_put_command); 264EXPORT_SYMBOL(scsi_put_command);
256 265