Commit 0585b754 authored by Jens Axboe's avatar Jens Axboe

sx8: convert to blk-mq

Convert from the old request_fn style driver to blk-mq.
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 8535fd6f
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/blkdev.h> #include <linux/blk-mq.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/compiler.h> #include <linux/compiler.h>
...@@ -244,6 +244,7 @@ struct carm_port { ...@@ -244,6 +244,7 @@ struct carm_port {
unsigned int port_no; unsigned int port_no;
struct gendisk *disk; struct gendisk *disk;
struct carm_host *host; struct carm_host *host;
struct blk_mq_tag_set tag_set;
/* attached device characteristics */ /* attached device characteristics */
u64 capacity; u64 capacity;
...@@ -279,6 +280,7 @@ struct carm_host { ...@@ -279,6 +280,7 @@ struct carm_host {
unsigned int state; unsigned int state;
u32 fw_ver; u32 fw_ver;
struct blk_mq_tag_set tag_set;
struct request_queue *oob_q; struct request_queue *oob_q;
unsigned int n_oob; unsigned int n_oob;
...@@ -750,7 +752,7 @@ static inline void carm_end_request_queued(struct carm_host *host, ...@@ -750,7 +752,7 @@ static inline void carm_end_request_queued(struct carm_host *host,
struct request *req = crq->rq; struct request *req = crq->rq;
int rc; int rc;
__blk_end_request_all(req, error); blk_mq_end_request(req, error);
rc = carm_put_request(host, crq); rc = carm_put_request(host, crq);
assert(rc == 0); assert(rc == 0);
...@@ -760,7 +762,7 @@ static inline void carm_push_q (struct carm_host *host, struct request_queue *q) ...@@ -760,7 +762,7 @@ static inline void carm_push_q (struct carm_host *host, struct request_queue *q)
{ {
unsigned int idx = host->wait_q_prod % CARM_MAX_WAIT_Q; unsigned int idx = host->wait_q_prod % CARM_MAX_WAIT_Q;
blk_stop_queue(q); blk_mq_stop_hw_queues(q);
VPRINTK("STOPPED QUEUE %p\n", q); VPRINTK("STOPPED QUEUE %p\n", q);
host->wait_q[idx] = q; host->wait_q[idx] = q;
...@@ -785,7 +787,7 @@ static inline void carm_round_robin(struct carm_host *host) ...@@ -785,7 +787,7 @@ static inline void carm_round_robin(struct carm_host *host)
{ {
struct request_queue *q = carm_pop_q(host); struct request_queue *q = carm_pop_q(host);
if (q) { if (q) {
blk_start_queue(q); blk_mq_start_hw_queues(q);
VPRINTK("STARTED QUEUE %p\n", q); VPRINTK("STARTED QUEUE %p\n", q);
} }
} }
...@@ -802,62 +804,62 @@ static inline void carm_end_rq(struct carm_host *host, struct carm_request *crq, ...@@ -802,62 +804,62 @@ static inline void carm_end_rq(struct carm_host *host, struct carm_request *crq,
} }
} }
static void carm_oob_rq_fn(struct request_queue *q) static blk_status_t carm_oob_queue_rq(struct blk_mq_hw_ctx *hctx,
const struct blk_mq_queue_data *bd)
{ {
struct request_queue *q = hctx->queue;
struct carm_host *host = q->queuedata; struct carm_host *host = q->queuedata;
struct carm_request *crq; struct carm_request *crq;
struct request *rq;
int rc; int rc;
while (1) { blk_mq_start_request(bd->rq);
DPRINTK("get req\n");
rq = blk_fetch_request(q);
if (!rq)
break;
crq = rq->special; spin_lock_irq(&host->lock);
assert(crq != NULL);
assert(crq->rq == rq);
crq->n_elem = 0; crq = bd->rq->special;
assert(crq != NULL);
assert(crq->rq == bd->rq);
DPRINTK("send req\n"); crq->n_elem = 0;
rc = carm_send_msg(host, crq);
if (rc) { DPRINTK("send req\n");
blk_requeue_request(q, rq); rc = carm_send_msg(host, crq);
carm_push_q(host, q); if (rc) {
return; /* call us again later, eventually */ carm_push_q(host, q);
} spin_unlock_irq(&host->lock);
return BLK_STS_DEV_RESOURCE;
} }
spin_unlock_irq(&host->lock);
return BLK_STS_OK;
} }
static void carm_rq_fn(struct request_queue *q) static blk_status_t carm_queue_rq(struct blk_mq_hw_ctx *hctx,
const struct blk_mq_queue_data *bd)
{ {
struct request_queue *q = hctx->queue;
struct carm_port *port = q->queuedata; struct carm_port *port = q->queuedata;
struct carm_host *host = port->host; struct carm_host *host = port->host;
struct carm_msg_rw *msg; struct carm_msg_rw *msg;
struct carm_request *crq; struct carm_request *crq;
struct request *rq; struct request *rq = bd->rq;
struct scatterlist *sg; struct scatterlist *sg;
int writing = 0, pci_dir, i, n_elem, rc; int writing = 0, pci_dir, i, n_elem, rc;
u32 tmp; u32 tmp;
unsigned int msg_size; unsigned int msg_size;
queue_one_request: blk_mq_start_request(rq);
VPRINTK("get req\n");
rq = blk_peek_request(q); spin_lock_irq(&host->lock);
if (!rq)
return;
crq = carm_get_request(host); crq = carm_get_request(host);
if (!crq) { if (!crq) {
carm_push_q(host, q); carm_push_q(host, q);
return; /* call us again later, eventually */ spin_unlock_irq(&host->lock);
return BLK_STS_DEV_RESOURCE;
} }
crq->rq = rq; crq->rq = rq;
blk_start_request(rq);
if (rq_data_dir(rq) == WRITE) { if (rq_data_dir(rq) == WRITE) {
writing = 1; writing = 1;
pci_dir = PCI_DMA_TODEVICE; pci_dir = PCI_DMA_TODEVICE;
...@@ -869,15 +871,19 @@ static void carm_rq_fn(struct request_queue *q) ...@@ -869,15 +871,19 @@ static void carm_rq_fn(struct request_queue *q)
sg = &crq->sg[0]; sg = &crq->sg[0];
n_elem = blk_rq_map_sg(q, rq, sg); n_elem = blk_rq_map_sg(q, rq, sg);
if (n_elem <= 0) { if (n_elem <= 0) {
/* request with no s/g entries? */
carm_end_rq(host, crq, BLK_STS_IOERR); carm_end_rq(host, crq, BLK_STS_IOERR);
return; /* request with no s/g entries? */ spin_unlock_irq(&host->lock);
return BLK_STS_IOERR;
} }
/* map scatterlist to PCI bus addresses */ /* map scatterlist to PCI bus addresses */
n_elem = pci_map_sg(host->pdev, sg, n_elem, pci_dir); n_elem = pci_map_sg(host->pdev, sg, n_elem, pci_dir);
if (n_elem <= 0) { if (n_elem <= 0) {
/* request with no s/g entries? */
carm_end_rq(host, crq, BLK_STS_IOERR); carm_end_rq(host, crq, BLK_STS_IOERR);
return; /* request with no s/g entries? */ spin_unlock_irq(&host->lock);
return BLK_STS_IOERR;
} }
crq->n_elem = n_elem; crq->n_elem = n_elem;
crq->port = port; crq->port = port;
...@@ -927,12 +933,13 @@ static void carm_rq_fn(struct request_queue *q) ...@@ -927,12 +933,13 @@ static void carm_rq_fn(struct request_queue *q)
rc = carm_send_msg(host, crq); rc = carm_send_msg(host, crq);
if (rc) { if (rc) {
carm_put_request(host, crq); carm_put_request(host, crq);
blk_requeue_request(q, rq);
carm_push_q(host, q); carm_push_q(host, q);
return; /* call us again later, eventually */ spin_unlock_irq(&host->lock);
return BLK_STS_DEV_RESOURCE;
} }
goto queue_one_request; spin_unlock_irq(&host->lock);
return BLK_STS_OK;
} }
static void carm_handle_array_info(struct carm_host *host, static void carm_handle_array_info(struct carm_host *host,
...@@ -1485,6 +1492,14 @@ static int carm_init_host(struct carm_host *host) ...@@ -1485,6 +1492,14 @@ static int carm_init_host(struct carm_host *host)
return 0; return 0;
} }
static const struct blk_mq_ops carm_oob_mq_ops = {
.queue_rq = carm_oob_queue_rq,
};
static const struct blk_mq_ops carm_mq_ops = {
.queue_rq = carm_queue_rq,
};
static int carm_init_disks(struct carm_host *host) static int carm_init_disks(struct carm_host *host)
{ {
unsigned int i; unsigned int i;
...@@ -1513,9 +1528,10 @@ static int carm_init_disks(struct carm_host *host) ...@@ -1513,9 +1528,10 @@ static int carm_init_disks(struct carm_host *host)
disk->fops = &carm_bd_ops; disk->fops = &carm_bd_ops;
disk->private_data = port; disk->private_data = port;
q = blk_init_queue(carm_rq_fn, &host->lock); q = blk_mq_init_sq_queue(&port->tag_set, &carm_mq_ops,
if (!q) { max_queue, BLK_MQ_F_SHOULD_MERGE);
rc = -ENOMEM; if (IS_ERR(q)) {
rc = PTR_ERR(q);
break; break;
} }
disk->queue = q; disk->queue = q;
...@@ -1533,14 +1549,18 @@ static void carm_free_disks(struct carm_host *host) ...@@ -1533,14 +1549,18 @@ static void carm_free_disks(struct carm_host *host)
unsigned int i; unsigned int i;
for (i = 0; i < CARM_MAX_PORTS; i++) { for (i = 0; i < CARM_MAX_PORTS; i++) {
struct gendisk *disk = host->port[i].disk; struct carm_port *port = &host->port[i];
struct gendisk *disk = port->disk;
if (disk) { if (disk) {
struct request_queue *q = disk->queue; struct request_queue *q = disk->queue;
if (disk->flags & GENHD_FL_UP) if (disk->flags & GENHD_FL_UP)
del_gendisk(disk); del_gendisk(disk);
if (q) if (q) {
blk_mq_free_tag_set(&port->tag_set);
blk_cleanup_queue(q); blk_cleanup_queue(q);
}
put_disk(disk); put_disk(disk);
} }
} }
...@@ -1636,11 +1656,12 @@ static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1636,11 +1656,12 @@ static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_iounmap; goto err_out_iounmap;
} }
q = blk_init_queue(carm_oob_rq_fn, &host->lock); q = blk_mq_init_sq_queue(&host->tag_set, &carm_oob_mq_ops, 1,
if (!q) { BLK_MQ_F_NO_SCHED);
if (IS_ERR(q)) {
printk(KERN_ERR DRV_NAME "(%s): OOB queue alloc failure\n", printk(KERN_ERR DRV_NAME "(%s): OOB queue alloc failure\n",
pci_name(pdev)); pci_name(pdev));
rc = -ENOMEM; rc = PTR_ERR(q);
goto err_out_pci_free; goto err_out_pci_free;
} }
host->oob_q = q; host->oob_q = q;
...@@ -1705,6 +1726,7 @@ static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1705,6 +1726,7 @@ static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
else if (host->major == 161) else if (host->major == 161)
clear_bit(1, &carm_major_alloc); clear_bit(1, &carm_major_alloc);
blk_cleanup_queue(host->oob_q); blk_cleanup_queue(host->oob_q);
blk_mq_free_tag_set(&host->tag_set);
err_out_pci_free: err_out_pci_free:
pci_free_consistent(pdev, CARM_SHM_SIZE, host->shm, host->shm_dma); pci_free_consistent(pdev, CARM_SHM_SIZE, host->shm, host->shm_dma);
err_out_iounmap: err_out_iounmap:
...@@ -1736,6 +1758,7 @@ static void carm_remove_one (struct pci_dev *pdev) ...@@ -1736,6 +1758,7 @@ static void carm_remove_one (struct pci_dev *pdev)
else if (host->major == 161) else if (host->major == 161)
clear_bit(1, &carm_major_alloc); clear_bit(1, &carm_major_alloc);
blk_cleanup_queue(host->oob_q); blk_cleanup_queue(host->oob_q);
blk_mq_free_tag_set(&host->tag_set);
pci_free_consistent(pdev, CARM_SHM_SIZE, host->shm, host->shm_dma); pci_free_consistent(pdev, CARM_SHM_SIZE, host->shm, host->shm_dma);
iounmap(host->mmio); iounmap(host->mmio);
kfree(host); kfree(host);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment