History

scsi: ufs-bsg: Add support for raw upiu in ufs_bsg_request()

Do that for the currently supported UPIUs: query, nop out, and task management. We do not support UPIU of type scsi command yet, while we are using the job's request and reply pointers to hold the payload. We will look into it in later patches. We might need to elaborate the raw upiu api for that. We also still not supporting uic commands: For first phase, we plan to use the existing api, and send only uic commands that are already supported. Anyway, all that will come in the next patch.

Avri Altman committed 8 years ago

Commit 95e34bf1 parent 5e0a86e1 file · +110 −4Browse files

Unified · Split

drivers/scsi/ufs/ufs_bsg.c+110−4
@@ -6,19 +6,125 @@ · 5 unmodified lines
6 */6 */
7#include "ufs_bsg.h"7#include "ufs_bsg.h"
8 8
9static int ufs_bsg_get_query_desc_size(struct ufs_hba *hba, int *desc_len,
10 struct utp_upiu_query *qr)
11{
12 int desc_size = be16_to_cpu(qr->length);
13 int desc_id = qr->idn;
14 int ret;
15
16 if (desc_size <= 0)
17 return -EINVAL;
18
19 ret = ufshcd_map_desc_id_to_length(hba, desc_id, desc_len);
20 if (ret || !*desc_len)
21 return -EINVAL;
22
23 *desc_len = min_t(int, *desc_len, desc_size);
24
25 return 0;
26}
27
28static int ufs_bsg_verify_query_size(struct ufs_hba *hba,
29 unsigned int request_len,
30 unsigned int reply_len,
31 int desc_len, enum query_opcode desc_op)
32{
33 int min_req_len = sizeof(struct ufs_bsg_request);
34 int min_rsp_len = sizeof(struct ufs_bsg_reply);
35
36 if (desc_op == UPIU_QUERY_OPCODE_WRITE_DESC)
37 min_req_len += desc_len;
38
39 if (min_req_len > request_len || min_rsp_len > reply_len) {
40 dev_err(hba->dev, "not enough space assigned\n");
41 return -EINVAL;
42 }
43
44 return 0;
45}
46
47static int ufs_bsg_verify_query_params(struct ufs_hba *hba,
48 struct ufs_bsg_request *bsg_request,
49 unsigned int request_len,
50 unsigned int reply_len,
51 uint8_t *desc_buff, int *desc_len,
52 enum query_opcode desc_op)
53{
54 struct utp_upiu_query *qr;
55
56 if (desc_op == UPIU_QUERY_OPCODE_READ_DESC) {
57 dev_err(hba->dev, "unsupported opcode %d\n", desc_op);
58 return -ENOTSUPP;
59 }
60
61 if (desc_op != UPIU_QUERY_OPCODE_WRITE_DESC)
62 goto out;
63
64 qr = &bsg_request->upiu_req.qr;
65 if (ufs_bsg_get_query_desc_size(hba, desc_len, qr)) {
66 dev_err(hba->dev, "Illegal desc size\n");
67 return -EINVAL;
68 }
69
70 if (ufs_bsg_verify_query_size(hba, request_len, reply_len, *desc_len,
71 desc_op))
72 return -EINVAL;
73
74 desc_buff = (uint8_t *)(bsg_request + 1);
75
76out:
77 return 0;
78}
9 79
10static int ufs_bsg_request(struct bsg_job *job)80static int ufs_bsg_request(struct bsg_job *job)
11{81{
12 struct ufs_bsg_request *bsg_request = job->request;82 struct ufs_bsg_request *bsg_request = job->request;
13 struct ufs_bsg_reply *bsg_reply = job->reply;83 struct ufs_bsg_reply *bsg_reply = job->reply;
14 int ret = -ENOTSUPP;84 struct ufs_hba *hba = shost_priv(dev_to_shost(job->dev->parent));
85 unsigned int req_len = job->request_len;
86 unsigned int reply_len = job->reply_len;
87 int msgcode;
88 uint8_t *desc_buff = NULL;
89 int desc_len = 0;
90 enum query_opcode desc_op = UPIU_QUERY_OPCODE_NOP;
91 int ret;
92
93 ret = ufs_bsg_verify_query_size(hba, req_len, reply_len, 0, desc_op);
94 if (ret)
95 goto out;
15 96
16 bsg_reply->reply_payload_rcv_len = 0;97 bsg_reply->reply_payload_rcv_len = 0;
17 98
18 /* Do Nothing for now */99 msgcode = bsg_request->msgcode;
19 dev_err(job->dev, "unsupported message_code 0x%x\n",100 switch (msgcode) {
20 bsg_request->msgcode);101 case UPIU_TRANSACTION_QUERY_REQ:
102 desc_op = bsg_request->upiu_req.qr.opcode;
103 ret = ufs_bsg_verify_query_params(hba, bsg_request, req_len,
104 reply_len, desc_buff,
105 &desc_len, desc_op);
106 if (ret)
107 goto out;
108
109 /* fall through */
110 case UPIU_TRANSACTION_NOP_OUT:
111 case UPIU_TRANSACTION_TASK_REQ:
112 ret = ufshcd_exec_raw_upiu_cmd(hba, &bsg_request->upiu_req,
113 &bsg_reply->upiu_rsp, msgcode,
114 desc_buff, &desc_len, desc_op);
115 if (ret)
116 dev_err(hba->dev,
117 "exe raw upiu: error code %d\n", ret);
118
119 break;
120 default:
121 ret = -ENOTSUPP;
122 dev_err(hba->dev, "unsupported msgcode 0x%x\n", msgcode);
123
124 break;
125 }
21 126
127out:
22 bsg_reply->result = ret;128 bsg_reply->result = ret;
23 job->reply_len = sizeof(struct ufs_bsg_reply) +129 job->reply_len = sizeof(struct ufs_bsg_reply) +
24 bsg_reply->reply_payload_rcv_len;130 bsg_reply->reply_payload_rcv_len;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t