summaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorJens Axboe <axboe@fb.com>2017-04-28 12:45:08 -0400
committerJens Axboe <axboe@fb.com>2017-05-02 09:52:08 -0400
commit3f5e6a35774cd6bb4fd6b32edb4efd2a3f90e4dd (patch)
treecbeaac6a62d43fbee2ee12badb3e00a7d8cf7fdc /drivers/block
parentbaed548a98397f57a71d61917177f7d42ab17881 (diff)
mtip32xx: convert internal command issue to block IO path
The driver special cases certain things for command issue, depending on whether it's an internal command or not. Make the internal commands use the regular infrastructure for issuing IO. Since this is an 8-group souped up AHCI variant, we have to deal with NCQ vs non-queueable commands. Do this from the queue_rq handler, by backing off unless the drive is idle. Reviewed-by: Christoph Hellwig <hch@lst.de> Tested-by: Ming Lei <ming.lei@redhat.com> Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/mtip32xx/mtip32xx.c103
1 files changed, 73 insertions, 30 deletions
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c
index aee94f260725..9749b099a914 100644
--- a/drivers/block/mtip32xx/mtip32xx.c
+++ b/drivers/block/mtip32xx/mtip32xx.c
@@ -195,7 +195,7 @@ static struct mtip_cmd *mtip_get_int_command(struct driver_data *dd)
195 if (mtip_check_surprise_removal(dd->pdev)) 195 if (mtip_check_surprise_removal(dd->pdev))
196 return NULL; 196 return NULL;
197 197
198 rq = blk_mq_alloc_request(dd->queue, 0, BLK_MQ_REQ_RESERVED); 198 rq = blk_mq_alloc_request(dd->queue, REQ_OP_DRV_IN, BLK_MQ_REQ_RESERVED);
199 if (IS_ERR(rq)) 199 if (IS_ERR(rq))
200 return NULL; 200 return NULL;
201 201
@@ -1088,6 +1088,13 @@ err_fault:
1088 return -EFAULT; 1088 return -EFAULT;
1089} 1089}
1090 1090
1091struct mtip_int_cmd {
1092 int fis_len;
1093 dma_addr_t buffer;
1094 int buf_len;
1095 u32 opts;
1096};
1097
1091/* 1098/*
1092 * Execute an internal command and wait for the completion. 1099 * Execute an internal command and wait for the completion.
1093 * 1100 *
@@ -1114,10 +1121,16 @@ static int mtip_exec_internal_command(struct mtip_port *port,
1114 u32 opts, 1121 u32 opts,
1115 unsigned long timeout) 1122 unsigned long timeout)
1116{ 1123{
1117 struct mtip_cmd_sg *command_sg;
1118 DECLARE_COMPLETION_ONSTACK(wait); 1124 DECLARE_COMPLETION_ONSTACK(wait);
1119 struct mtip_cmd *int_cmd; 1125 struct mtip_cmd *int_cmd;
1120 struct driver_data *dd = port->dd; 1126 struct driver_data *dd = port->dd;
1127 struct request *rq;
1128 struct mtip_int_cmd icmd = {
1129 .fis_len = fis_len,
1130 .buffer = buffer,
1131 .buf_len = buf_len,
1132 .opts = opts
1133 };
1121 int rv = 0; 1134 int rv = 0;
1122 unsigned long start; 1135 unsigned long start;
1123 1136
@@ -1132,6 +1145,8 @@ static int mtip_exec_internal_command(struct mtip_port *port,
1132 dbg_printk(MTIP_DRV_NAME "Unable to allocate tag for PIO cmd\n"); 1145 dbg_printk(MTIP_DRV_NAME "Unable to allocate tag for PIO cmd\n");
1133 return -EFAULT; 1146 return -EFAULT;
1134 } 1147 }
1148 rq = blk_mq_rq_from_pdu(int_cmd);
1149 rq->end_io_data = &icmd;
1135 1150
1136 set_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags); 1151 set_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags);
1137 1152
@@ -1158,35 +1173,16 @@ static int mtip_exec_internal_command(struct mtip_port *port,
1158 /* Copy the command to the command table */ 1173 /* Copy the command to the command table */
1159 memcpy(int_cmd->command, fis, fis_len*4); 1174 memcpy(int_cmd->command, fis, fis_len*4);
1160 1175
1161 /* Populate the SG list */
1162 int_cmd->command_header->opts =
1163 __force_bit2int cpu_to_le32(opts | fis_len);
1164 if (buf_len) {
1165 command_sg = int_cmd->command + AHCI_CMD_TBL_HDR_SZ;
1166
1167 command_sg->info =
1168 __force_bit2int cpu_to_le32((buf_len-1) & 0x3FFFFF);
1169 command_sg->dba =
1170 __force_bit2int cpu_to_le32(buffer & 0xFFFFFFFF);
1171 command_sg->dba_upper =
1172 __force_bit2int cpu_to_le32((buffer >> 16) >> 16);
1173
1174 int_cmd->command_header->opts |=
1175 __force_bit2int cpu_to_le32((1 << 16));
1176 }
1177
1178 /* Populate the command header */
1179 int_cmd->command_header->byte_count = 0;
1180
1181 start = jiffies; 1176 start = jiffies;
1177 rq->timeout = timeout;
1182 1178
1183 /* Issue the command to the hardware */ 1179 /* insert request and run queue */
1184 mtip_issue_non_ncq_command(port, MTIP_TAG_INTERNAL); 1180 blk_execute_rq_nowait(rq->q, NULL, rq, true, NULL);
1181
1182 wait_for_completion(&wait);
1183 rv = int_cmd->status;
1185 1184
1186 /* Wait for the command to complete or timeout. */ 1185 if (rv < 0) {
1187 rv = wait_for_completion_interruptible_timeout(&wait,
1188 msecs_to_jiffies(timeout));
1189 if (rv <= 0) {
1190 if (rv == -ERESTARTSYS) { /* interrupted */ 1186 if (rv == -ERESTARTSYS) { /* interrupted */
1191 dev_err(&dd->pdev->dev, 1187 dev_err(&dd->pdev->dev,
1192 "Internal command [%02X] was interrupted after %u ms\n", 1188 "Internal command [%02X] was interrupted after %u ms\n",
@@ -1217,7 +1213,6 @@ static int mtip_exec_internal_command(struct mtip_port *port,
1217 goto exec_ic_exit; 1213 goto exec_ic_exit;
1218 } 1214 }
1219 1215
1220 rv = 0;
1221 if (readl(port->cmd_issue[MTIP_TAG_INTERNAL]) 1216 if (readl(port->cmd_issue[MTIP_TAG_INTERNAL])
1222 & (1 << MTIP_TAG_INTERNAL)) { 1217 & (1 << MTIP_TAG_INTERNAL)) {
1223 rv = -ENXIO; 1218 rv = -ENXIO;
@@ -3762,6 +3757,44 @@ static bool mtip_check_unal_depth(struct blk_mq_hw_ctx *hctx,
3762 return false; 3757 return false;
3763} 3758}
3764 3759
3760static int mtip_issue_reserved_cmd(struct blk_mq_hw_ctx *hctx,
3761 struct request *rq)
3762{
3763 struct driver_data *dd = hctx->queue->queuedata;
3764 struct mtip_int_cmd *icmd = rq->end_io_data;
3765 struct mtip_cmd *cmd = blk_mq_rq_to_pdu(rq);
3766 struct mtip_cmd_sg *command_sg;
3767
3768 if (mtip_commands_active(dd->port))
3769 return BLK_MQ_RQ_QUEUE_BUSY;
3770
3771 rq->end_io_data = NULL;
3772
3773 /* Populate the SG list */
3774 cmd->command_header->opts =
3775 __force_bit2int cpu_to_le32(icmd->opts | icmd->fis_len);
3776 if (icmd->buf_len) {
3777 command_sg = cmd->command + AHCI_CMD_TBL_HDR_SZ;
3778
3779 command_sg->info =
3780 __force_bit2int cpu_to_le32((icmd->buf_len-1) & 0x3FFFFF);
3781 command_sg->dba =
3782 __force_bit2int cpu_to_le32(icmd->buffer & 0xFFFFFFFF);
3783 command_sg->dba_upper =
3784 __force_bit2int cpu_to_le32((icmd->buffer >> 16) >> 16);
3785
3786 cmd->command_header->opts |=
3787 __force_bit2int cpu_to_le32((1 << 16));
3788 }
3789
3790 /* Populate the command header */
3791 cmd->command_header->byte_count = 0;
3792
3793 blk_mq_start_request(rq);
3794 mtip_issue_non_ncq_command(dd->port, rq->tag);
3795 return BLK_MQ_RQ_QUEUE_OK;
3796}
3797
3765static int mtip_queue_rq(struct blk_mq_hw_ctx *hctx, 3798static int mtip_queue_rq(struct blk_mq_hw_ctx *hctx,
3766 const struct blk_mq_queue_data *bd) 3799 const struct blk_mq_queue_data *bd)
3767{ 3800{
@@ -3770,6 +3803,9 @@ static int mtip_queue_rq(struct blk_mq_hw_ctx *hctx,
3770 3803
3771 mtip_init_cmd_header(rq); 3804 mtip_init_cmd_header(rq);
3772 3805
3806 if (blk_rq_is_passthrough(rq))
3807 return mtip_issue_reserved_cmd(hctx, rq);
3808
3773 if (unlikely(mtip_check_unal_depth(hctx, rq))) 3809 if (unlikely(mtip_check_unal_depth(hctx, rq)))
3774 return BLK_MQ_RQ_QUEUE_BUSY; 3810 return BLK_MQ_RQ_QUEUE_BUSY;
3775 3811
@@ -3825,8 +3861,14 @@ static enum blk_eh_timer_return mtip_cmd_timeout(struct request *req,
3825{ 3861{
3826 struct driver_data *dd = req->q->queuedata; 3862 struct driver_data *dd = req->q->queuedata;
3827 3863
3828 if (reserved) 3864 if (reserved) {
3865 struct mtip_cmd *cmd = blk_mq_rq_to_pdu(req);
3866
3867 cmd->status = -ETIME;
3868 if (cmd->comp_func)
3869 cmd->comp_func(dd->port, MTIP_TAG_INTERNAL, cmd, -ETIME);
3829 goto exit_handler; 3870 goto exit_handler;
3871 }
3830 3872
3831 if (test_bit(req->tag, dd->port->cmds_to_issue)) 3873 if (test_bit(req->tag, dd->port->cmds_to_issue))
3832 goto exit_handler; 3874 goto exit_handler;
@@ -4063,6 +4105,7 @@ static void mtip_no_dev_cleanup(struct request *rq, void *data, bool reserv)
4063 } else if (test_bit(MTIP_PF_IC_ACTIVE_BIT, &dd->port->flags)) { 4105 } else if (test_bit(MTIP_PF_IC_ACTIVE_BIT, &dd->port->flags)) {
4064 4106
4065 cmd = mtip_cmd_from_tag(dd, MTIP_TAG_INTERNAL); 4107 cmd = mtip_cmd_from_tag(dd, MTIP_TAG_INTERNAL);
4108 cmd->status = -ENODEV;
4066 if (cmd->comp_func) 4109 if (cmd->comp_func)
4067 cmd->comp_func(dd->port, MTIP_TAG_INTERNAL, 4110 cmd->comp_func(dd->port, MTIP_TAG_INTERNAL,
4068 cmd, -ENODEV); 4111 cmd, -ENODEV);