summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi.c
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2006-11-16 19:24:10 +0900
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-11-25 13:08:56 -0600
commitb58d91547fb17c65ad621f3f98b1f2c228c812a5 (patch)
tree4fafd4db96cb7931577f87b02a79cc6f52986333 /drivers/scsi/scsi.c
parent84ad58e4efcf80c154f693d4cc8f5c913511b760 (diff)
downloadlinux-b58d91547fb17c65ad621f3f98b1f2c228c812a5.tar.gz
linux-b58d91547fb17c65ad621f3f98b1f2c228c812a5.tar.bz2
linux-b58d91547fb17c65ad621f3f98b1f2c228c812a5.zip
[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 = {
static DEFINE_MUTEX(host_cmd_pool_mutex);
-static struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost,
- gfp_t gfp_mask)
+struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost, gfp_t gfp_mask)
{
struct scsi_cmnd *cmd;
@@ -178,6 +177,7 @@ static struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost,
return cmd;
}
+EXPORT_SYMBOL_GPL(__scsi_get_command);
/*
* Function: scsi_get_command()
@@ -214,9 +214,29 @@ struct scsi_cmnd *scsi_get_command(struct scsi_device *dev, gfp_t gfp_mask)
put_device(&dev->sdev_gendev);
return cmd;
-}
+}
EXPORT_SYMBOL(scsi_get_command);
+void __scsi_put_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd,
+ struct device *dev)
+{
+ unsigned long flags;
+
+ /* changing locks here, don't need to restore the irq state */
+ spin_lock_irqsave(&shost->free_list_lock, flags);
+ if (unlikely(list_empty(&shost->free_list))) {
+ list_add(&cmd->list, &shost->free_list);
+ cmd = NULL;
+ }
+ spin_unlock_irqrestore(&shost->free_list_lock, flags);
+
+ if (likely(cmd != NULL))
+ kmem_cache_free(shost->cmd_pool->slab, cmd);
+
+ put_device(dev);
+}
+EXPORT_SYMBOL(__scsi_put_command);
+
/*
* Function: scsi_put_command()
*
@@ -231,26 +251,15 @@ EXPORT_SYMBOL(scsi_get_command);
void scsi_put_command(struct scsi_cmnd *cmd)
{
struct scsi_device *sdev = cmd->device;
- struct Scsi_Host *shost = sdev->host;
unsigned long flags;
-
+
/* serious error if the command hasn't come from a device list */
spin_lock_irqsave(&cmd->device->list_lock, flags);
BUG_ON(list_empty(&cmd->list));
list_del_init(&cmd->list);
- spin_unlock(&cmd->device->list_lock);
- /* changing locks here, don't need to restore the irq state */
- spin_lock(&shost->free_list_lock);
- if (unlikely(list_empty(&shost->free_list))) {
- list_add(&cmd->list, &shost->free_list);
- cmd = NULL;
- }
- spin_unlock_irqrestore(&shost->free_list_lock, flags);
+ spin_unlock_irqrestore(&cmd->device->list_lock, flags);
- if (likely(cmd != NULL))
- kmem_cache_free(shost->cmd_pool->slab, cmd);
-
- put_device(&sdev->sdev_gendev);
+ __scsi_put_command(cmd->device->host, cmd, &sdev->sdev_gendev);
}
EXPORT_SYMBOL(scsi_put_command);