1 // SPDX-License-Identifier: GPL-2.0
3 * bsg endpoint that supports UPIUs
5 * Copyright (C) 2018 Western Digital Corporation
9 static int ufs_bsg_get_query_desc_size(struct ufs_hba
*hba
, int *desc_len
,
10 struct utp_upiu_query
*qr
)
12 int desc_size
= be16_to_cpu(qr
->length
);
13 int desc_id
= qr
->idn
;
18 ufshcd_map_desc_id_to_length(hba
, desc_id
, desc_len
);
22 *desc_len
= min_t(int, *desc_len
, desc_size
);
27 static int ufs_bsg_verify_query_size(struct ufs_hba
*hba
,
28 unsigned int request_len
,
29 unsigned int reply_len
)
31 int min_req_len
= sizeof(struct ufs_bsg_request
);
32 int min_rsp_len
= sizeof(struct ufs_bsg_reply
);
34 if (min_req_len
> request_len
|| min_rsp_len
> reply_len
) {
35 dev_err(hba
->dev
, "not enough space assigned\n");
42 static int ufs_bsg_alloc_desc_buffer(struct ufs_hba
*hba
, struct bsg_job
*job
,
43 uint8_t **desc_buff
, int *desc_len
,
44 enum query_opcode desc_op
)
46 struct ufs_bsg_request
*bsg_request
= job
->request
;
47 struct utp_upiu_query
*qr
;
50 if (desc_op
!= UPIU_QUERY_OPCODE_WRITE_DESC
&&
51 desc_op
!= UPIU_QUERY_OPCODE_READ_DESC
)
54 qr
= &bsg_request
->upiu_req
.qr
;
55 if (ufs_bsg_get_query_desc_size(hba
, desc_len
, qr
)) {
56 dev_err(hba
->dev
, "Illegal desc size\n");
60 if (*desc_len
> job
->request_payload
.payload_len
) {
61 dev_err(hba
->dev
, "Illegal desc size\n");
65 descp
= kzalloc(*desc_len
, GFP_KERNEL
);
69 if (desc_op
== UPIU_QUERY_OPCODE_WRITE_DESC
)
70 sg_copy_to_buffer(job
->request_payload
.sg_list
,
71 job
->request_payload
.sg_cnt
, descp
,
80 static int ufs_bsg_request(struct bsg_job
*job
)
82 struct ufs_bsg_request
*bsg_request
= job
->request
;
83 struct ufs_bsg_reply
*bsg_reply
= job
->reply
;
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 struct uic_command uc
= {};
89 uint8_t *desc_buff
= NULL
;
91 enum query_opcode desc_op
= UPIU_QUERY_OPCODE_NOP
;
94 ret
= ufs_bsg_verify_query_size(hba
, req_len
, reply_len
);
98 bsg_reply
->reply_payload_rcv_len
= 0;
100 pm_runtime_get_sync(hba
->dev
);
102 msgcode
= bsg_request
->msgcode
;
104 case UPIU_TRANSACTION_QUERY_REQ
:
105 desc_op
= bsg_request
->upiu_req
.qr
.opcode
;
106 ret
= ufs_bsg_alloc_desc_buffer(hba
, job
, &desc_buff
,
109 pm_runtime_put_sync(hba
->dev
);
114 case UPIU_TRANSACTION_NOP_OUT
:
115 case UPIU_TRANSACTION_TASK_REQ
:
116 ret
= ufshcd_exec_raw_upiu_cmd(hba
, &bsg_request
->upiu_req
,
117 &bsg_reply
->upiu_rsp
, msgcode
,
118 desc_buff
, &desc_len
, desc_op
);
121 "exe raw upiu: error code %d\n", ret
);
124 case UPIU_TRANSACTION_UIC_CMD
:
125 memcpy(&uc
, &bsg_request
->upiu_req
.uc
, UIC_CMD_SIZE
);
126 ret
= ufshcd_send_uic_cmd(hba
, &uc
);
129 "send uic cmd: error code %d\n", ret
);
131 memcpy(&bsg_reply
->upiu_rsp
.uc
, &uc
, UIC_CMD_SIZE
);
136 dev_err(hba
->dev
, "unsupported msgcode 0x%x\n", msgcode
);
141 pm_runtime_put_sync(hba
->dev
);
146 if (desc_op
== UPIU_QUERY_OPCODE_READ_DESC
&& desc_len
)
147 bsg_reply
->reply_payload_rcv_len
=
148 sg_copy_from_buffer(job
->request_payload
.sg_list
,
149 job
->request_payload
.sg_cnt
,
150 desc_buff
, desc_len
);
155 bsg_reply
->result
= ret
;
156 job
->reply_len
= sizeof(struct ufs_bsg_reply
);
157 /* complete the job here only if no error */
159 bsg_job_done(job
, ret
, bsg_reply
->reply_payload_rcv_len
);
165 * ufs_bsg_remove - detach and remove the added ufs-bsg node
166 * @hba: per adapter object
168 * Should be called when unloading the driver.
170 void ufs_bsg_remove(struct ufs_hba
*hba
)
172 struct device
*bsg_dev
= &hba
->bsg_dev
;
177 bsg_remove_queue(hba
->bsg_queue
);
183 static inline void ufs_bsg_node_release(struct device
*dev
)
185 put_device(dev
->parent
);
189 * ufs_bsg_probe - Add ufs bsg device node
190 * @hba: per adapter object
192 * Called during initial loading of the driver, and before scsi_scan_host.
194 int ufs_bsg_probe(struct ufs_hba
*hba
)
196 struct device
*bsg_dev
= &hba
->bsg_dev
;
197 struct Scsi_Host
*shost
= hba
->host
;
198 struct device
*parent
= &shost
->shost_gendev
;
199 struct request_queue
*q
;
202 device_initialize(bsg_dev
);
204 bsg_dev
->parent
= get_device(parent
);
205 bsg_dev
->release
= ufs_bsg_node_release
;
207 dev_set_name(bsg_dev
, "ufs-bsg%u", shost
->host_no
);
209 ret
= device_add(bsg_dev
);
213 q
= bsg_setup_queue(bsg_dev
, dev_name(bsg_dev
), ufs_bsg_request
, NULL
, 0);
224 dev_err(bsg_dev
, "fail to initialize a bsg dev %d\n", shost
->host_no
);