0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/bsg-lib.h>
0009 #include <scsi/scsi.h>
0010 #include <scsi/scsi_host.h>
0011 #include "ufs_bsg.h"
0012 #include <ufs/ufshcd.h>
0013 #include "ufshcd-priv.h"
0014
0015 static int ufs_bsg_get_query_desc_size(struct ufs_hba *hba, int *desc_len,
0016 struct utp_upiu_query *qr)
0017 {
0018 int desc_size = be16_to_cpu(qr->length);
0019 int desc_id = qr->idn;
0020
0021 if (desc_size <= 0)
0022 return -EINVAL;
0023
0024 ufshcd_map_desc_id_to_length(hba, desc_id, desc_len);
0025 if (!*desc_len)
0026 return -EINVAL;
0027
0028 *desc_len = min_t(int, *desc_len, desc_size);
0029
0030 return 0;
0031 }
0032
0033 static int ufs_bsg_verify_query_size(struct ufs_hba *hba,
0034 unsigned int request_len,
0035 unsigned int reply_len)
0036 {
0037 int min_req_len = sizeof(struct ufs_bsg_request);
0038 int min_rsp_len = sizeof(struct ufs_bsg_reply);
0039
0040 if (min_req_len > request_len || min_rsp_len > reply_len) {
0041 dev_err(hba->dev, "not enough space assigned\n");
0042 return -EINVAL;
0043 }
0044
0045 return 0;
0046 }
0047
0048 static int ufs_bsg_alloc_desc_buffer(struct ufs_hba *hba, struct bsg_job *job,
0049 uint8_t **desc_buff, int *desc_len,
0050 enum query_opcode desc_op)
0051 {
0052 struct ufs_bsg_request *bsg_request = job->request;
0053 struct utp_upiu_query *qr;
0054 u8 *descp;
0055
0056 if (desc_op != UPIU_QUERY_OPCODE_WRITE_DESC &&
0057 desc_op != UPIU_QUERY_OPCODE_READ_DESC)
0058 goto out;
0059
0060 qr = &bsg_request->upiu_req.qr;
0061 if (ufs_bsg_get_query_desc_size(hba, desc_len, qr)) {
0062 dev_err(hba->dev, "Illegal desc size\n");
0063 return -EINVAL;
0064 }
0065
0066 if (*desc_len > job->request_payload.payload_len) {
0067 dev_err(hba->dev, "Illegal desc size\n");
0068 return -EINVAL;
0069 }
0070
0071 descp = kzalloc(*desc_len, GFP_KERNEL);
0072 if (!descp)
0073 return -ENOMEM;
0074
0075 if (desc_op == UPIU_QUERY_OPCODE_WRITE_DESC)
0076 sg_copy_to_buffer(job->request_payload.sg_list,
0077 job->request_payload.sg_cnt, descp,
0078 *desc_len);
0079
0080 *desc_buff = descp;
0081
0082 out:
0083 return 0;
0084 }
0085
0086 static int ufs_bsg_request(struct bsg_job *job)
0087 {
0088 struct ufs_bsg_request *bsg_request = job->request;
0089 struct ufs_bsg_reply *bsg_reply = job->reply;
0090 struct ufs_hba *hba = shost_priv(dev_to_shost(job->dev->parent));
0091 unsigned int req_len = job->request_len;
0092 unsigned int reply_len = job->reply_len;
0093 struct uic_command uc = {};
0094 int msgcode;
0095 uint8_t *desc_buff = NULL;
0096 int desc_len = 0;
0097 enum query_opcode desc_op = UPIU_QUERY_OPCODE_NOP;
0098 int ret;
0099
0100 ret = ufs_bsg_verify_query_size(hba, req_len, reply_len);
0101 if (ret)
0102 goto out;
0103
0104 bsg_reply->reply_payload_rcv_len = 0;
0105
0106 ufshcd_rpm_get_sync(hba);
0107
0108 msgcode = bsg_request->msgcode;
0109 switch (msgcode) {
0110 case UPIU_TRANSACTION_QUERY_REQ:
0111 desc_op = bsg_request->upiu_req.qr.opcode;
0112 ret = ufs_bsg_alloc_desc_buffer(hba, job, &desc_buff,
0113 &desc_len, desc_op);
0114 if (ret) {
0115 ufshcd_rpm_put_sync(hba);
0116 goto out;
0117 }
0118
0119 fallthrough;
0120 case UPIU_TRANSACTION_NOP_OUT:
0121 case UPIU_TRANSACTION_TASK_REQ:
0122 ret = ufshcd_exec_raw_upiu_cmd(hba, &bsg_request->upiu_req,
0123 &bsg_reply->upiu_rsp, msgcode,
0124 desc_buff, &desc_len, desc_op);
0125 if (ret)
0126 dev_err(hba->dev,
0127 "exe raw upiu: error code %d\n", ret);
0128
0129 break;
0130 case UPIU_TRANSACTION_UIC_CMD:
0131 memcpy(&uc, &bsg_request->upiu_req.uc, UIC_CMD_SIZE);
0132 ret = ufshcd_send_uic_cmd(hba, &uc);
0133 if (ret)
0134 dev_err(hba->dev,
0135 "send uic cmd: error code %d\n", ret);
0136
0137 memcpy(&bsg_reply->upiu_rsp.uc, &uc, UIC_CMD_SIZE);
0138
0139 break;
0140 default:
0141 ret = -ENOTSUPP;
0142 dev_err(hba->dev, "unsupported msgcode 0x%x\n", msgcode);
0143
0144 break;
0145 }
0146
0147 ufshcd_rpm_put_sync(hba);
0148
0149 if (!desc_buff)
0150 goto out;
0151
0152 if (desc_op == UPIU_QUERY_OPCODE_READ_DESC && desc_len)
0153 bsg_reply->reply_payload_rcv_len =
0154 sg_copy_from_buffer(job->request_payload.sg_list,
0155 job->request_payload.sg_cnt,
0156 desc_buff, desc_len);
0157
0158 kfree(desc_buff);
0159
0160 out:
0161 bsg_reply->result = ret;
0162 job->reply_len = sizeof(struct ufs_bsg_reply);
0163
0164 if (ret == 0)
0165 bsg_job_done(job, ret, bsg_reply->reply_payload_rcv_len);
0166
0167 return ret;
0168 }
0169
0170
0171
0172
0173
0174
0175
0176 void ufs_bsg_remove(struct ufs_hba *hba)
0177 {
0178 struct device *bsg_dev = &hba->bsg_dev;
0179
0180 if (!hba->bsg_queue)
0181 return;
0182
0183 bsg_remove_queue(hba->bsg_queue);
0184
0185 device_del(bsg_dev);
0186 put_device(bsg_dev);
0187 }
0188
0189 static inline void ufs_bsg_node_release(struct device *dev)
0190 {
0191 put_device(dev->parent);
0192 }
0193
0194
0195
0196
0197
0198
0199
0200 int ufs_bsg_probe(struct ufs_hba *hba)
0201 {
0202 struct device *bsg_dev = &hba->bsg_dev;
0203 struct Scsi_Host *shost = hba->host;
0204 struct device *parent = &shost->shost_gendev;
0205 struct request_queue *q;
0206 int ret;
0207
0208 device_initialize(bsg_dev);
0209
0210 bsg_dev->parent = get_device(parent);
0211 bsg_dev->release = ufs_bsg_node_release;
0212
0213 dev_set_name(bsg_dev, "ufs-bsg%u", shost->host_no);
0214
0215 ret = device_add(bsg_dev);
0216 if (ret)
0217 goto out;
0218
0219 q = bsg_setup_queue(bsg_dev, dev_name(bsg_dev), ufs_bsg_request, NULL, 0);
0220 if (IS_ERR(q)) {
0221 ret = PTR_ERR(q);
0222 goto out;
0223 }
0224
0225 hba->bsg_queue = q;
0226
0227 return 0;
0228
0229 out:
0230 dev_err(bsg_dev, "fail to initialize a bsg dev %d\n", shost->host_no);
0231 put_device(bsg_dev);
0232 return ret;
0233 }