mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-25 02:09:42 +00:00
skd: Introduce skd_process_request()
The only functional change in this patch is that the skd_fitmsg_context in which requests are accumulated is changed from a local variable into a member of struct skd_device. This patch will make the blk-mq conversion easier. Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com> Cc: Christoph Hellwig <hch@lst.de> Cc: Hannes Reinecke <hare@suse.de> Cc: Johannes Thumshirn <jthumshirn@suse.de> Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
6fbb2de5c9
commit
91f85da4eb
1 changed files with 119 additions and 118 deletions
|
@ -232,6 +232,7 @@ struct skd_device {
|
|||
spinlock_t lock;
|
||||
struct gendisk *disk;
|
||||
struct request_queue *queue;
|
||||
struct skd_fitmsg_context *skmsg;
|
||||
struct device *class_dev;
|
||||
int gendisk_on;
|
||||
int sync_done;
|
||||
|
@ -492,23 +493,128 @@ static bool skd_fail_all(struct request_queue *q)
|
|||
}
|
||||
}
|
||||
|
||||
static void skd_request_fn(struct request_queue *q)
|
||||
static void skd_process_request(struct request *req)
|
||||
{
|
||||
struct request_queue *const q = req->q;
|
||||
struct skd_device *skdev = q->queuedata;
|
||||
struct skd_fitmsg_context *skmsg = NULL;
|
||||
struct fit_msg_hdr *fmh = NULL;
|
||||
struct skd_request_context *skreq;
|
||||
struct request *req = NULL;
|
||||
struct skd_fitmsg_context *skmsg;
|
||||
struct fit_msg_hdr *fmh;
|
||||
const u32 tag = blk_mq_unique_tag(req);
|
||||
struct skd_request_context *const skreq = &skdev->skreq_table[tag];
|
||||
struct skd_scsi_request *scsi_req;
|
||||
unsigned long io_flags;
|
||||
u32 lba;
|
||||
u32 count;
|
||||
int data_dir;
|
||||
__be64 be_dmaa;
|
||||
u64 cmdctxt;
|
||||
u32 timo_slot;
|
||||
int flush, fua;
|
||||
u32 tag;
|
||||
|
||||
WARN_ONCE(tag >= skd_max_queue_depth, "%#x > %#x (nr_requests = %lu)\n",
|
||||
tag, skd_max_queue_depth, q->nr_requests);
|
||||
|
||||
SKD_ASSERT(skreq->state == SKD_REQ_STATE_IDLE);
|
||||
|
||||
flush = fua = 0;
|
||||
|
||||
lba = (u32)blk_rq_pos(req);
|
||||
count = blk_rq_sectors(req);
|
||||
data_dir = rq_data_dir(req);
|
||||
io_flags = req->cmd_flags;
|
||||
|
||||
if (req_op(req) == REQ_OP_FLUSH)
|
||||
flush++;
|
||||
|
||||
if (io_flags & REQ_FUA)
|
||||
fua++;
|
||||
|
||||
dev_dbg(&skdev->pdev->dev,
|
||||
"new req=%p lba=%u(0x%x) count=%u(0x%x) dir=%d\n", req, lba,
|
||||
lba, count, count, data_dir);
|
||||
|
||||
skreq->id = tag + SKD_ID_RW_REQUEST;
|
||||
skreq->flush_cmd = 0;
|
||||
skreq->n_sg = 0;
|
||||
skreq->sg_byte_count = 0;
|
||||
|
||||
skreq->req = req;
|
||||
skreq->fitmsg_id = 0;
|
||||
|
||||
skreq->data_dir = data_dir == READ ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
|
||||
|
||||
if (req->bio && !skd_preop_sg_list(skdev, skreq)) {
|
||||
dev_dbg(&skdev->pdev->dev, "error Out\n");
|
||||
skd_end_request(skdev, skreq->req, BLK_STS_RESOURCE);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Either a FIT msg is in progress or we have to start one. */
|
||||
skmsg = skdev->skmsg;
|
||||
if (!skmsg) {
|
||||
skmsg = &skdev->skmsg_table[tag];
|
||||
skdev->skmsg = skmsg;
|
||||
|
||||
/* Initialize the FIT msg header */
|
||||
fmh = &skmsg->msg_buf->fmh;
|
||||
memset(fmh, 0, sizeof(*fmh));
|
||||
fmh->protocol_id = FIT_PROTOCOL_ID_SOFIT;
|
||||
skmsg->length = sizeof(*fmh);
|
||||
} else {
|
||||
fmh = &skmsg->msg_buf->fmh;
|
||||
}
|
||||
|
||||
skreq->fitmsg_id = skmsg->id;
|
||||
|
||||
scsi_req = &skmsg->msg_buf->scsi[fmh->num_protocol_cmds_coalesced];
|
||||
memset(scsi_req, 0, sizeof(*scsi_req));
|
||||
|
||||
be_dmaa = cpu_to_be64(skreq->sksg_dma_address);
|
||||
|
||||
scsi_req->hdr.tag = skreq->id;
|
||||
scsi_req->hdr.sg_list_dma_address = be_dmaa;
|
||||
|
||||
if (flush == SKD_FLUSH_ZERO_SIZE_FIRST) {
|
||||
skd_prep_zerosize_flush_cdb(scsi_req, skreq);
|
||||
SKD_ASSERT(skreq->flush_cmd == 1);
|
||||
} else {
|
||||
skd_prep_rw_cdb(scsi_req, data_dir, lba, count);
|
||||
}
|
||||
|
||||
if (fua)
|
||||
scsi_req->cdb[1] |= SKD_FUA_NV;
|
||||
|
||||
scsi_req->hdr.sg_list_len_bytes = cpu_to_be32(skreq->sg_byte_count);
|
||||
|
||||
/* Complete resource allocations. */
|
||||
skreq->state = SKD_REQ_STATE_BUSY;
|
||||
|
||||
skmsg->length += sizeof(struct skd_scsi_request);
|
||||
fmh->num_protocol_cmds_coalesced++;
|
||||
|
||||
/*
|
||||
* Update the active request counts.
|
||||
* Capture the timeout timestamp.
|
||||
*/
|
||||
skreq->timeout_stamp = atomic_read(&skdev->timeout_stamp);
|
||||
timo_slot = skreq->timeout_stamp & SKD_TIMEOUT_SLOT_MASK;
|
||||
atomic_inc(&skdev->timeout_slot[timo_slot]);
|
||||
atomic_inc(&skdev->in_flight);
|
||||
dev_dbg(&skdev->pdev->dev, "req=0x%x busy=%d\n", skreq->id,
|
||||
atomic_read(&skdev->in_flight));
|
||||
|
||||
/*
|
||||
* If the FIT msg buffer is full send it.
|
||||
*/
|
||||
if (fmh->num_protocol_cmds_coalesced >= skd_max_req_per_msg) {
|
||||
skd_send_fitmsg(skdev, skmsg);
|
||||
skdev->skmsg = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void skd_request_fn(struct request_queue *q)
|
||||
{
|
||||
struct skd_device *skdev = q->queuedata;
|
||||
struct request *req;
|
||||
|
||||
if (skdev->state != SKD_DRVR_STATE_ONLINE) {
|
||||
if (skd_fail_all(q))
|
||||
|
@ -533,30 +639,12 @@ static void skd_request_fn(struct request_queue *q)
|
|||
* - There are no more FIT msg buffers
|
||||
*/
|
||||
for (;; ) {
|
||||
|
||||
flush = fua = 0;
|
||||
|
||||
req = blk_peek_request(q);
|
||||
|
||||
/* Are there any native requests to start? */
|
||||
if (req == NULL)
|
||||
break;
|
||||
|
||||
lba = (u32)blk_rq_pos(req);
|
||||
count = blk_rq_sectors(req);
|
||||
data_dir = rq_data_dir(req);
|
||||
io_flags = req->cmd_flags;
|
||||
|
||||
if (req_op(req) == REQ_OP_FLUSH)
|
||||
flush++;
|
||||
|
||||
if (io_flags & REQ_FUA)
|
||||
fua++;
|
||||
|
||||
dev_dbg(&skdev->pdev->dev,
|
||||
"new req=%p lba=%u(0x%x) count=%u(0x%x) dir=%d\n",
|
||||
req, lba, lba, count, count, data_dir);
|
||||
|
||||
/* At this point we know there is a request */
|
||||
|
||||
/* Are too many requets already in progress? */
|
||||
|
@ -576,103 +664,16 @@ static void skd_request_fn(struct request_queue *q)
|
|||
* available but is still at the head of the free list.
|
||||
*/
|
||||
WARN_ON_ONCE(blk_queue_start_tag(q, req));
|
||||
|
||||
tag = blk_mq_unique_tag(req);
|
||||
WARN_ONCE(tag >= skd_max_queue_depth,
|
||||
"%#x > %#x (nr_requests = %lu)\n", tag,
|
||||
skd_max_queue_depth, q->nr_requests);
|
||||
|
||||
skreq = &skdev->skreq_table[tag];
|
||||
SKD_ASSERT(skreq->state == SKD_REQ_STATE_IDLE);
|
||||
SKD_ASSERT((skreq->id & SKD_ID_INCR) == 0);
|
||||
|
||||
skreq->id = tag + SKD_ID_RW_REQUEST;
|
||||
skreq->flush_cmd = 0;
|
||||
skreq->n_sg = 0;
|
||||
skreq->sg_byte_count = 0;
|
||||
|
||||
skreq->req = req;
|
||||
skreq->fitmsg_id = 0;
|
||||
|
||||
skreq->data_dir = data_dir == READ ? DMA_FROM_DEVICE :
|
||||
DMA_TO_DEVICE;
|
||||
|
||||
if (req->bio && !skd_preop_sg_list(skdev, skreq)) {
|
||||
dev_dbg(&skdev->pdev->dev, "error Out\n");
|
||||
skd_end_request(skdev, skreq->req, BLK_STS_RESOURCE);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Either a FIT msg is in progress or we have to start one. */
|
||||
if (skmsg == NULL) {
|
||||
skmsg = &skdev->skmsg_table[tag];
|
||||
|
||||
/* Initialize the FIT msg header */
|
||||
fmh = &skmsg->msg_buf->fmh;
|
||||
memset(fmh, 0, sizeof(*fmh));
|
||||
fmh->protocol_id = FIT_PROTOCOL_ID_SOFIT;
|
||||
skmsg->length = sizeof(*fmh);
|
||||
}
|
||||
|
||||
skreq->fitmsg_id = skmsg->id;
|
||||
|
||||
scsi_req =
|
||||
&skmsg->msg_buf->scsi[fmh->num_protocol_cmds_coalesced];
|
||||
memset(scsi_req, 0, sizeof(*scsi_req));
|
||||
|
||||
be_dmaa = cpu_to_be64(skreq->sksg_dma_address);
|
||||
cmdctxt = skreq->id + SKD_ID_INCR;
|
||||
|
||||
scsi_req->hdr.tag = cmdctxt;
|
||||
scsi_req->hdr.sg_list_dma_address = be_dmaa;
|
||||
|
||||
if (flush == SKD_FLUSH_ZERO_SIZE_FIRST) {
|
||||
skd_prep_zerosize_flush_cdb(scsi_req, skreq);
|
||||
SKD_ASSERT(skreq->flush_cmd == 1);
|
||||
} else {
|
||||
skd_prep_rw_cdb(scsi_req, data_dir, lba, count);
|
||||
}
|
||||
|
||||
if (fua)
|
||||
scsi_req->cdb[1] |= SKD_FUA_NV;
|
||||
|
||||
scsi_req->hdr.sg_list_len_bytes =
|
||||
cpu_to_be32(skreq->sg_byte_count);
|
||||
|
||||
/* Complete resource allocations. */
|
||||
skreq->state = SKD_REQ_STATE_BUSY;
|
||||
skreq->id += SKD_ID_INCR;
|
||||
|
||||
skmsg->length += sizeof(struct skd_scsi_request);
|
||||
fmh->num_protocol_cmds_coalesced++;
|
||||
|
||||
/*
|
||||
* Update the active request counts.
|
||||
* Capture the timeout timestamp.
|
||||
*/
|
||||
skreq->timeout_stamp = atomic_read(&skdev->timeout_stamp);
|
||||
timo_slot = skreq->timeout_stamp & SKD_TIMEOUT_SLOT_MASK;
|
||||
atomic_inc(&skdev->timeout_slot[timo_slot]);
|
||||
atomic_inc(&skdev->in_flight);
|
||||
dev_dbg(&skdev->pdev->dev, "req=0x%x busy=%d\n", skreq->id,
|
||||
atomic_read(&skdev->in_flight));
|
||||
|
||||
/*
|
||||
* If the FIT msg buffer is full send it.
|
||||
*/
|
||||
if (fmh->num_protocol_cmds_coalesced >= skd_max_req_per_msg) {
|
||||
skd_send_fitmsg(skdev, skmsg);
|
||||
skmsg = NULL;
|
||||
fmh = NULL;
|
||||
}
|
||||
skd_process_request(req);
|
||||
}
|
||||
|
||||
/* If the FIT msg buffer is not empty send what we got. */
|
||||
if (skmsg) {
|
||||
if (skdev->skmsg) {
|
||||
struct fit_msg_hdr *fmh = &skdev->skmsg->msg_buf->fmh;
|
||||
|
||||
WARN_ON_ONCE(!fmh->num_protocol_cmds_coalesced);
|
||||
skd_send_fitmsg(skdev, skmsg);
|
||||
skmsg = NULL;
|
||||
fmh = NULL;
|
||||
skd_send_fitmsg(skdev, skdev->skmsg);
|
||||
skdev->skmsg = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue