Loading drivers/block/xsysace.c +55 −25 Original line number Original line Diff line number Diff line Loading @@ -88,7 +88,7 @@ #include <linux/kernel.h> #include <linux/kernel.h> #include <linux/delay.h> #include <linux/delay.h> #include <linux/slab.h> #include <linux/slab.h> #include <linux/blkdev.h> #include <linux/blk-mq.h> #include <linux/mutex.h> #include <linux/mutex.h> #include <linux/ata.h> #include <linux/ata.h> #include <linux/hdreg.h> #include <linux/hdreg.h> Loading Loading @@ -209,6 +209,8 @@ struct ace_device { struct device *dev; struct device *dev; struct request_queue *queue; struct request_queue *queue; struct gendisk *gd; struct gendisk *gd; struct blk_mq_tag_set tag_set; struct list_head rq_list; /* Inserted CF card parameters */ /* Inserted CF card parameters */ u16 cf_id[ATA_ID_WORDS]; u16 cf_id[ATA_ID_WORDS]; Loading Loading @@ -462,18 +464,26 @@ static inline void ace_fsm_yieldirq(struct ace_device *ace) ace->fsm_continue_flag = 0; ace->fsm_continue_flag = 0; } } static bool ace_has_next_request(struct request_queue *q) { struct ace_device *ace = q->queuedata; return !list_empty(&ace->rq_list); } /* Get the next read/write request; ending requests that we don't handle */ /* Get the next read/write request; ending requests that we don't handle */ static struct request *ace_get_next_request(struct request_queue *q) static struct request *ace_get_next_request(struct request_queue *q) { { struct request *req; struct ace_device *ace = q->queuedata; struct request *rq; while ((req = blk_peek_request(q)) != NULL) { rq = list_first_entry_or_null(&ace->rq_list, struct request, queuelist); if (!blk_rq_is_passthrough(req)) if (rq) { break; list_del_init(&rq->queuelist); blk_start_request(req); blk_mq_start_request(rq); __blk_end_request_all(req, BLK_STS_IOERR); } } return req; return NULL; } } static void ace_fsm_dostate(struct ace_device *ace) static void ace_fsm_dostate(struct ace_device *ace) Loading @@ -499,11 +509,11 @@ static void ace_fsm_dostate(struct ace_device *ace) /* Drop all in-flight and pending requests */ /* Drop all in-flight and pending requests */ if (ace->req) { if (ace->req) { __blk_end_request_all(ace->req, BLK_STS_IOERR); blk_mq_end_request(ace->req, BLK_STS_IOERR); ace->req = NULL; ace->req = NULL; } } while ((req = blk_fetch_request(ace->queue)) != NULL) while ((req = ace_get_next_request(ace->queue)) != NULL) __blk_end_request_all(req, BLK_STS_IOERR); blk_mq_end_request(req, BLK_STS_IOERR); /* Drop back to IDLE state and notify waiters */ /* Drop back to IDLE state and notify waiters */ ace->fsm_state = ACE_FSM_STATE_IDLE; ace->fsm_state = ACE_FSM_STATE_IDLE; Loading @@ -517,7 +527,7 @@ static void ace_fsm_dostate(struct ace_device *ace) switch (ace->fsm_state) { switch (ace->fsm_state) { case ACE_FSM_STATE_IDLE: case ACE_FSM_STATE_IDLE: /* See if there is anything to do */ /* See if there is anything to do */ if (ace->id_req_count || ace_get_next_request(ace->queue)) { if (ace->id_req_count || ace_has_next_request(ace->queue)) { ace->fsm_iter_num++; ace->fsm_iter_num++; ace->fsm_state = ACE_FSM_STATE_REQ_LOCK; ace->fsm_state = ACE_FSM_STATE_REQ_LOCK; mod_timer(&ace->stall_timer, jiffies + HZ); mod_timer(&ace->stall_timer, jiffies + HZ); Loading Loading @@ -651,7 +661,6 @@ static void ace_fsm_dostate(struct ace_device *ace) ace->fsm_state = ACE_FSM_STATE_IDLE; ace->fsm_state = ACE_FSM_STATE_IDLE; break; break; } } blk_start_request(req); /* Okay, it's a data request, set it up for transfer */ /* Okay, it's a data request, set it up for transfer */ dev_dbg(ace->dev, dev_dbg(ace->dev, Loading Loading @@ -728,7 +737,8 @@ static void ace_fsm_dostate(struct ace_device *ace) } } /* bio finished; is there another one? */ /* bio finished; is there another one? */ if (__blk_end_request_cur(ace->req, BLK_STS_OK)) { if (blk_update_request(ace->req, BLK_STS_OK, blk_rq_cur_bytes(ace->req))) { /* dev_dbg(ace->dev, "next block; h=%u c=%u\n", /* dev_dbg(ace->dev, "next block; h=%u c=%u\n", * blk_rq_sectors(ace->req), * blk_rq_sectors(ace->req), * blk_rq_cur_sectors(ace->req)); * blk_rq_cur_sectors(ace->req)); Loading Loading @@ -854,17 +864,23 @@ static irqreturn_t ace_interrupt(int irq, void *dev_id) /* --------------------------------------------------------------------- /* --------------------------------------------------------------------- * Block ops * Block ops */ */ static void ace_request(struct request_queue * q) static blk_status_t ace_queue_rq(struct blk_mq_hw_ctx *hctx, const struct blk_mq_queue_data *bd) { { struct request *req; struct ace_device *ace = hctx->queue->queuedata; struct ace_device *ace; struct request *req = bd->rq; req = ace_get_next_request(q); if (blk_rq_is_passthrough(req)) { blk_mq_start_request(req); return BLK_STS_IOERR; } spin_lock_irq(&ace->lock); list_add_tail(&req->queuelist, &ace->rq_list); spin_unlock_irq(&ace->lock); if (req) { ace = req->rq_disk->private_data; tasklet_schedule(&ace->fsm_tasklet); tasklet_schedule(&ace->fsm_tasklet); } return BLK_STS_OK; } } static unsigned int ace_check_events(struct gendisk *gd, unsigned int clearing) static unsigned int ace_check_events(struct gendisk *gd, unsigned int clearing) Loading Loading @@ -957,6 +973,10 @@ static const struct block_device_operations ace_fops = { .getgeo = ace_getgeo, .getgeo = ace_getgeo, }; }; static const struct blk_mq_ops ace_mq_ops = { .queue_rq = ace_queue_rq, }; /* -------------------------------------------------------------------- /* -------------------------------------------------------------------- * SystemACE device setup/teardown code * SystemACE device setup/teardown code */ */ Loading @@ -972,6 +992,7 @@ static int ace_setup(struct ace_device *ace) spin_lock_init(&ace->lock); spin_lock_init(&ace->lock); init_completion(&ace->id_completion); init_completion(&ace->id_completion); INIT_LIST_HEAD(&ace->rq_list); /* /* * Map the device * Map the device Loading @@ -989,9 +1010,15 @@ static int ace_setup(struct ace_device *ace) /* /* * Initialize the request queue * Initialize the request queue */ */ ace->queue = blk_init_queue(ace_request, &ace->lock); ace->queue = blk_mq_init_sq_queue(&ace->tag_set, &ace_mq_ops, 2, if (ace->queue == NULL) BLK_MQ_F_SHOULD_MERGE); if (IS_ERR(ace->queue)) { rc = PTR_ERR(ace->queue); ace->queue = NULL; goto err_blk_initq; goto err_blk_initq; } ace->queue->queuedata = ace; blk_queue_logical_block_size(ace->queue, 512); blk_queue_logical_block_size(ace->queue, 512); blk_queue_bounce_limit(ace->queue, BLK_BOUNCE_HIGH); blk_queue_bounce_limit(ace->queue, BLK_BOUNCE_HIGH); Loading Loading @@ -1066,6 +1093,7 @@ static int ace_setup(struct ace_device *ace) put_disk(ace->gd); put_disk(ace->gd); err_alloc_disk: err_alloc_disk: blk_cleanup_queue(ace->queue); blk_cleanup_queue(ace->queue); blk_mq_free_tag_set(&ace->tag_set); err_blk_initq: err_blk_initq: iounmap(ace->baseaddr); iounmap(ace->baseaddr); err_ioremap: err_ioremap: Loading @@ -1081,8 +1109,10 @@ static void ace_teardown(struct ace_device *ace) put_disk(ace->gd); put_disk(ace->gd); } } if (ace->queue) if (ace->queue) { blk_cleanup_queue(ace->queue); blk_cleanup_queue(ace->queue); blk_mq_free_tag_set(&ace->tag_set); } tasklet_kill(&ace->fsm_tasklet); tasklet_kill(&ace->fsm_tasklet); Loading Loading
drivers/block/xsysace.c +55 −25 Original line number Original line Diff line number Diff line Loading @@ -88,7 +88,7 @@ #include <linux/kernel.h> #include <linux/kernel.h> #include <linux/delay.h> #include <linux/delay.h> #include <linux/slab.h> #include <linux/slab.h> #include <linux/blkdev.h> #include <linux/blk-mq.h> #include <linux/mutex.h> #include <linux/mutex.h> #include <linux/ata.h> #include <linux/ata.h> #include <linux/hdreg.h> #include <linux/hdreg.h> Loading Loading @@ -209,6 +209,8 @@ struct ace_device { struct device *dev; struct device *dev; struct request_queue *queue; struct request_queue *queue; struct gendisk *gd; struct gendisk *gd; struct blk_mq_tag_set tag_set; struct list_head rq_list; /* Inserted CF card parameters */ /* Inserted CF card parameters */ u16 cf_id[ATA_ID_WORDS]; u16 cf_id[ATA_ID_WORDS]; Loading Loading @@ -462,18 +464,26 @@ static inline void ace_fsm_yieldirq(struct ace_device *ace) ace->fsm_continue_flag = 0; ace->fsm_continue_flag = 0; } } static bool ace_has_next_request(struct request_queue *q) { struct ace_device *ace = q->queuedata; return !list_empty(&ace->rq_list); } /* Get the next read/write request; ending requests that we don't handle */ /* Get the next read/write request; ending requests that we don't handle */ static struct request *ace_get_next_request(struct request_queue *q) static struct request *ace_get_next_request(struct request_queue *q) { { struct request *req; struct ace_device *ace = q->queuedata; struct request *rq; while ((req = blk_peek_request(q)) != NULL) { rq = list_first_entry_or_null(&ace->rq_list, struct request, queuelist); if (!blk_rq_is_passthrough(req)) if (rq) { break; list_del_init(&rq->queuelist); blk_start_request(req); blk_mq_start_request(rq); __blk_end_request_all(req, BLK_STS_IOERR); } } return req; return NULL; } } static void ace_fsm_dostate(struct ace_device *ace) static void ace_fsm_dostate(struct ace_device *ace) Loading @@ -499,11 +509,11 @@ static void ace_fsm_dostate(struct ace_device *ace) /* Drop all in-flight and pending requests */ /* Drop all in-flight and pending requests */ if (ace->req) { if (ace->req) { __blk_end_request_all(ace->req, BLK_STS_IOERR); blk_mq_end_request(ace->req, BLK_STS_IOERR); ace->req = NULL; ace->req = NULL; } } while ((req = blk_fetch_request(ace->queue)) != NULL) while ((req = ace_get_next_request(ace->queue)) != NULL) __blk_end_request_all(req, BLK_STS_IOERR); blk_mq_end_request(req, BLK_STS_IOERR); /* Drop back to IDLE state and notify waiters */ /* Drop back to IDLE state and notify waiters */ ace->fsm_state = ACE_FSM_STATE_IDLE; ace->fsm_state = ACE_FSM_STATE_IDLE; Loading @@ -517,7 +527,7 @@ static void ace_fsm_dostate(struct ace_device *ace) switch (ace->fsm_state) { switch (ace->fsm_state) { case ACE_FSM_STATE_IDLE: case ACE_FSM_STATE_IDLE: /* See if there is anything to do */ /* See if there is anything to do */ if (ace->id_req_count || ace_get_next_request(ace->queue)) { if (ace->id_req_count || ace_has_next_request(ace->queue)) { ace->fsm_iter_num++; ace->fsm_iter_num++; ace->fsm_state = ACE_FSM_STATE_REQ_LOCK; ace->fsm_state = ACE_FSM_STATE_REQ_LOCK; mod_timer(&ace->stall_timer, jiffies + HZ); mod_timer(&ace->stall_timer, jiffies + HZ); Loading Loading @@ -651,7 +661,6 @@ static void ace_fsm_dostate(struct ace_device *ace) ace->fsm_state = ACE_FSM_STATE_IDLE; ace->fsm_state = ACE_FSM_STATE_IDLE; break; break; } } blk_start_request(req); /* Okay, it's a data request, set it up for transfer */ /* Okay, it's a data request, set it up for transfer */ dev_dbg(ace->dev, dev_dbg(ace->dev, Loading Loading @@ -728,7 +737,8 @@ static void ace_fsm_dostate(struct ace_device *ace) } } /* bio finished; is there another one? */ /* bio finished; is there another one? */ if (__blk_end_request_cur(ace->req, BLK_STS_OK)) { if (blk_update_request(ace->req, BLK_STS_OK, blk_rq_cur_bytes(ace->req))) { /* dev_dbg(ace->dev, "next block; h=%u c=%u\n", /* dev_dbg(ace->dev, "next block; h=%u c=%u\n", * blk_rq_sectors(ace->req), * blk_rq_sectors(ace->req), * blk_rq_cur_sectors(ace->req)); * blk_rq_cur_sectors(ace->req)); Loading Loading @@ -854,17 +864,23 @@ static irqreturn_t ace_interrupt(int irq, void *dev_id) /* --------------------------------------------------------------------- /* --------------------------------------------------------------------- * Block ops * Block ops */ */ static void ace_request(struct request_queue * q) static blk_status_t ace_queue_rq(struct blk_mq_hw_ctx *hctx, const struct blk_mq_queue_data *bd) { { struct request *req; struct ace_device *ace = hctx->queue->queuedata; struct ace_device *ace; struct request *req = bd->rq; req = ace_get_next_request(q); if (blk_rq_is_passthrough(req)) { blk_mq_start_request(req); return BLK_STS_IOERR; } spin_lock_irq(&ace->lock); list_add_tail(&req->queuelist, &ace->rq_list); spin_unlock_irq(&ace->lock); if (req) { ace = req->rq_disk->private_data; tasklet_schedule(&ace->fsm_tasklet); tasklet_schedule(&ace->fsm_tasklet); } return BLK_STS_OK; } } static unsigned int ace_check_events(struct gendisk *gd, unsigned int clearing) static unsigned int ace_check_events(struct gendisk *gd, unsigned int clearing) Loading Loading @@ -957,6 +973,10 @@ static const struct block_device_operations ace_fops = { .getgeo = ace_getgeo, .getgeo = ace_getgeo, }; }; static const struct blk_mq_ops ace_mq_ops = { .queue_rq = ace_queue_rq, }; /* -------------------------------------------------------------------- /* -------------------------------------------------------------------- * SystemACE device setup/teardown code * SystemACE device setup/teardown code */ */ Loading @@ -972,6 +992,7 @@ static int ace_setup(struct ace_device *ace) spin_lock_init(&ace->lock); spin_lock_init(&ace->lock); init_completion(&ace->id_completion); init_completion(&ace->id_completion); INIT_LIST_HEAD(&ace->rq_list); /* /* * Map the device * Map the device Loading @@ -989,9 +1010,15 @@ static int ace_setup(struct ace_device *ace) /* /* * Initialize the request queue * Initialize the request queue */ */ ace->queue = blk_init_queue(ace_request, &ace->lock); ace->queue = blk_mq_init_sq_queue(&ace->tag_set, &ace_mq_ops, 2, if (ace->queue == NULL) BLK_MQ_F_SHOULD_MERGE); if (IS_ERR(ace->queue)) { rc = PTR_ERR(ace->queue); ace->queue = NULL; goto err_blk_initq; goto err_blk_initq; } ace->queue->queuedata = ace; blk_queue_logical_block_size(ace->queue, 512); blk_queue_logical_block_size(ace->queue, 512); blk_queue_bounce_limit(ace->queue, BLK_BOUNCE_HIGH); blk_queue_bounce_limit(ace->queue, BLK_BOUNCE_HIGH); Loading Loading @@ -1066,6 +1093,7 @@ static int ace_setup(struct ace_device *ace) put_disk(ace->gd); put_disk(ace->gd); err_alloc_disk: err_alloc_disk: blk_cleanup_queue(ace->queue); blk_cleanup_queue(ace->queue); blk_mq_free_tag_set(&ace->tag_set); err_blk_initq: err_blk_initq: iounmap(ace->baseaddr); iounmap(ace->baseaddr); err_ioremap: err_ioremap: Loading @@ -1081,8 +1109,10 @@ static void ace_teardown(struct ace_device *ace) put_disk(ace->gd); put_disk(ace->gd); } } if (ace->queue) if (ace->queue) { blk_cleanup_queue(ace->queue); blk_cleanup_queue(ace->queue); blk_mq_free_tag_set(&ace->tag_set); } tasklet_kill(&ace->fsm_tasklet); tasklet_kill(&ace->fsm_tasklet); Loading