Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 42462
b: refs/heads/master
c: b58d915
h: refs/heads/master
v: v3
  • Loading branch information
FUJITA Tomonori authored and James Bottomley committed Nov 25, 2006
1 parent 23731d2 commit 66f618c
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 27 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 84ad58e4efcf80c154f693d4cc8f5c913511b760
refs/heads/master: b58d91547fb17c65ad621f3f98b1f2c228c812a5
4 changes: 4 additions & 0 deletions trunk/drivers/scsi/hosts.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,10 @@ static void scsi_host_dev_release(struct device *dev)
kthread_stop(shost->ehandler);
if (shost->work_q)
destroy_workqueue(shost->work_q);
if (shost->uspace_req_q) {
kfree(shost->uspace_req_q->queuedata);
scsi_free_queue(shost->uspace_req_q);
}

scsi_destroy_command_freelist(shost);
if (shost->bqt)
Expand Down
43 changes: 26 additions & 17 deletions trunk/drivers/scsi/scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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()
Expand Down Expand Up @@ -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()
*
Expand All @@ -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);

Expand Down
33 changes: 24 additions & 9 deletions trunk/drivers/scsi/scsi_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,7 @@ static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int uptodate,
return NULL;
}

static struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
{
struct scsi_host_sg_pool *sgp;
struct scatterlist *sgl;
Expand Down Expand Up @@ -745,7 +745,9 @@ static struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_m
return sgl;
}

static void scsi_free_sgtable(struct scatterlist *sgl, int index)
EXPORT_SYMBOL(scsi_alloc_sgtable);

void scsi_free_sgtable(struct scatterlist *sgl, int index)
{
struct scsi_host_sg_pool *sgp;

Expand All @@ -755,6 +757,8 @@ static void scsi_free_sgtable(struct scatterlist *sgl, int index)
mempool_free(sgl, sgp->pool);
}

EXPORT_SYMBOL(scsi_free_sgtable);

/*
* Function: scsi_release_buffers()
*
Expand Down Expand Up @@ -1567,29 +1571,40 @@ u64 scsi_calculate_bounce_limit(struct Scsi_Host *shost)
}
EXPORT_SYMBOL(scsi_calculate_bounce_limit);

struct request_queue *scsi_alloc_queue(struct scsi_device *sdev)
struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost,
request_fn_proc *request_fn)
{
struct Scsi_Host *shost = sdev->host;
struct request_queue *q;

q = blk_init_queue(scsi_request_fn, NULL);
q = blk_init_queue(request_fn, NULL);
if (!q)
return NULL;

blk_queue_prep_rq(q, scsi_prep_fn);

blk_queue_max_hw_segments(q, shost->sg_tablesize);
blk_queue_max_phys_segments(q, SCSI_MAX_PHYS_SEGMENTS);
blk_queue_max_sectors(q, shost->max_sectors);
blk_queue_bounce_limit(q, scsi_calculate_bounce_limit(shost));
blk_queue_segment_boundary(q, shost->dma_boundary);
blk_queue_issue_flush_fn(q, scsi_issue_flush_fn);
blk_queue_softirq_done(q, scsi_softirq_done);

if (!shost->use_clustering)
clear_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags);
return q;
}
EXPORT_SYMBOL(__scsi_alloc_queue);

struct request_queue *scsi_alloc_queue(struct scsi_device *sdev)
{
struct request_queue *q;

q = __scsi_alloc_queue(sdev->host, scsi_request_fn);
if (!q)
return NULL;

blk_queue_prep_rq(q, scsi_prep_fn);
blk_queue_issue_flush_fn(q, scsi_issue_flush_fn);
blk_queue_softirq_done(q, scsi_softirq_done);
return q;
}

void scsi_free_queue(struct request_queue *q)
{
Expand Down
10 changes: 10 additions & 0 deletions trunk/include/scsi/scsi_cmnd.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

struct request;
struct scatterlist;
struct Scsi_Host;
struct scsi_device;


Expand Down Expand Up @@ -72,6 +73,9 @@ struct scsi_cmnd {
unsigned short use_sg; /* Number of pieces of scatter-gather */
unsigned short sglist_len; /* size of malloc'd scatter-gather list */

/* offset in cmd we are at (for multi-transfer tgt cmds) */
unsigned offset;

unsigned underflow; /* Return error if less than
this amount is transferred */

Expand Down Expand Up @@ -119,7 +123,10 @@ struct scsi_cmnd {
};

extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, gfp_t);
extern struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *, gfp_t);
extern void scsi_put_command(struct scsi_cmnd *);
extern void __scsi_put_command(struct Scsi_Host *, struct scsi_cmnd *,
struct device *);
extern void scsi_io_completion(struct scsi_cmnd *, unsigned int);
extern void scsi_finish_command(struct scsi_cmnd *cmd);
extern void scsi_req_abort_cmd(struct scsi_cmnd *cmd);
Expand All @@ -128,4 +135,7 @@ extern void *scsi_kmap_atomic_sg(struct scatterlist *sg, int sg_count,
size_t *offset, size_t *len);
extern void scsi_kunmap_atomic_sg(void *virt);

extern struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *, gfp_t);
extern void scsi_free_sgtable(struct scatterlist *, int);

#endif /* _SCSI_SCSI_CMND_H */
43 changes: 43 additions & 0 deletions trunk/include/scsi/scsi_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <linux/workqueue.h>
#include <linux/mutex.h>

struct request_queue;
struct block_device;
struct completion;
struct module;
Expand Down Expand Up @@ -123,6 +124,39 @@ struct scsi_host_template {
int (* queuecommand)(struct scsi_cmnd *,
void (*done)(struct scsi_cmnd *));

/*
* The transfer functions are used to queue a scsi command to
* the LLD. When the driver is finished processing the command
* the done callback is invoked.
*
* return values: see queuecommand
*
* If the LLD accepts the cmd, it should set the result to an
* appropriate value when completed before calling the done function.
*
* STATUS: REQUIRED FOR TARGET DRIVERS
*/
/* TODO: rename */
int (* transfer_response)(struct scsi_cmnd *,
void (*done)(struct scsi_cmnd *));
/*
* This is called to inform the LLD to transfer cmd->request_bufflen
* bytes of the cmd at cmd->offset in the cmd. The cmd->use_sg
* speciefies the number of scatterlist entried in the command
* and cmd->request_buffer contains the scatterlist.
*
* If the command cannot be processed in one transfer_data call
* becuase a scatterlist within the LLD's limits cannot be
* created then transfer_data will be called multiple times.
* It is initially called from process context, and later
* calls are from the interrup context.
*/
int (* transfer_data)(struct scsi_cmnd *,
void (*done)(struct scsi_cmnd *));

/* Used as callback for the completion of task management request. */
int (* tsk_mgmt_response)(u64 mid, int result);

/*
* This is an error handling strategy routine. You don't need to
* define one of these if you don't want to - there is a default
Expand Down Expand Up @@ -589,6 +623,12 @@ struct Scsi_Host {
*/
unsigned int max_host_blocked;

/*
* q used for scsi_tgt msgs, async events or any other requests that
* need to be processed in userspace
*/
struct request_queue *uspace_req_q;

/* legacy crap */
unsigned long base;
unsigned long io_port;
Expand Down Expand Up @@ -687,6 +727,9 @@ extern void scsi_unblock_requests(struct Scsi_Host *);
extern void scsi_block_requests(struct Scsi_Host *);

struct class_container;

extern struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost,
void (*) (struct request_queue *));
/*
* These two functions are used to allocate and free a pseudo device
* which will connect to the host adapter itself rather than any
Expand Down

0 comments on commit 66f618c

Please sign in to comment.