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
;
19 ret
= ufshcd_map_desc_id_to_length(hba
, desc_id
, desc_len
);
20 if (ret
|| !*desc_len
)
23 *desc_len
= min_t(int, *desc_len
, desc_size
);
28 static int ufs_bsg_verify_query_size(struct ufs_hba
*hba
,
29 unsigned int request_len
,
30 unsigned int reply_len
)
32 int min_req_len
= sizeof(struct ufs_bsg_request
);
33 int min_rsp_len
= sizeof(struct ufs_bsg_reply
);
35 if (min_req_len
> request_len
|| min_rsp_len
> reply_len
) {
36 dev_err(hba
->dev
, "not enough space assigned\n");
43 static int ufs_bsg_alloc_desc_buffer(struct ufs_hba
*hba
, struct bsg_job
*job
,
44 uint8_t **desc_buff
, int *desc_len
,
45 enum query_opcode desc_op
)
47 struct ufs_bsg_request
*bsg_request
= job
->request
;
48 struct utp_upiu_query
*qr
;
51 if (desc_op
!= UPIU_QUERY_OPCODE_WRITE_DESC
&&
52 desc_op
!= UPIU_QUERY_OPCODE_READ_DESC
)
55 qr
= &bsg_request
->upiu_req
.qr
;
56 if (ufs_bsg_get_query_desc_size(hba
, desc_len
, qr
)) {
57 dev_err(hba
->dev
, "Illegal desc size\n");
61 if (*desc_len
> job
->request_payload
.payload_len
) {
62 dev_err(hba
->dev
, "Illegal desc size\n");
66 descp
= kzalloc(*desc_len
, GFP_KERNEL
);
70 if (desc_op
== UPIU_QUERY_OPCODE_WRITE_DESC
)
71 sg_copy_to_buffer(job
->request_payload
.sg_list
,
72 job
->request_payload
.sg_cnt
, descp
,
81 static int ufs_bsg_request(struct bsg_job
*job
)
83 struct ufs_bsg_request
*bsg_request
= job
->request
;
84 struct ufs_bsg_reply
*bsg_reply
= job
->reply
;
85 struct ufs_hba
*hba
= shost_priv(dev_to_shost(job
->dev
->parent
));
86 unsigned int req_len
= job
->request_len
;
87 unsigned int reply_len
= job
->reply_len
;
88 struct uic_command uc
= {};
90 uint8_t *desc_buff
= NULL
;
92 enum query_opcode desc_op
= UPIU_QUERY_OPCODE_NOP
;
95 ret
= ufs_bsg_verify_query_size(hba
, req_len
, reply_len
);
99 bsg_reply
->reply_payload_rcv_len
= 0;
101 msgcode
= bsg_request
->msgcode
;
103 case UPIU_TRANSACTION_QUERY_REQ
:
104 desc_op
= bsg_request
->upiu_req
.qr
.opcode
;
105 ret
= ufs_bsg_alloc_desc_buffer(hba
, job
, &desc_buff
,
111 case UPIU_TRANSACTION_NOP_OUT
:
112 case UPIU_TRANSACTION_TASK_REQ
:
113 ret
= ufshcd_exec_raw_upiu_cmd(hba
, &bsg_request
->upiu_req
,
114 &bsg_reply
->upiu_rsp
, msgcode
,
115 desc_buff
, &desc_len
, desc_op
);
118 "exe raw upiu: error code %d\n", ret
);
121 case UPIU_TRANSACTION_UIC_CMD
:
122 memcpy(&uc
, &bsg_request
->upiu_req
.uc
, UIC_CMD_SIZE
);
123 ret
= ufshcd_send_uic_cmd(hba
, &uc
);
126 "send uic cmd: error code %d\n", ret
);
128 memcpy(&bsg_reply
->upiu_rsp
.uc
, &uc
, UIC_CMD_SIZE
);
133 dev_err(hba
->dev
, "unsupported msgcode 0x%x\n", msgcode
);
141 if (desc_op
== UPIU_QUERY_OPCODE_READ_DESC
&& desc_len
)
142 bsg_reply
->reply_payload_rcv_len
=
143 sg_copy_from_buffer(job
->request_payload
.sg_list
,
144 job
->request_payload
.sg_cnt
,
145 desc_buff
, desc_len
);
150 bsg_reply
->result
= ret
;
151 job
->reply_len
= sizeof(struct ufs_bsg_reply
);
152 bsg_job_done(job
, ret
, bsg_reply
->reply_payload_rcv_len
);
158 * ufs_bsg_remove - detach and remove the added ufs-bsg node
160 * Should be called when unloading the driver.
162 void ufs_bsg_remove(struct ufs_hba
*hba
)
164 struct device
*bsg_dev
= &hba
->bsg_dev
;
169 bsg_remove_queue(hba
->bsg_queue
);
175 static inline void ufs_bsg_node_release(struct device
*dev
)
177 put_device(dev
->parent
);
181 * ufs_bsg_probe - Add ufs bsg device node
182 * @hba: per adapter object
184 * Called during initial loading of the driver, and before scsi_scan_host.
186 int ufs_bsg_probe(struct ufs_hba
*hba
)
188 struct device
*bsg_dev
= &hba
->bsg_dev
;
189 struct Scsi_Host
*shost
= hba
->host
;
190 struct device
*parent
= &shost
->shost_gendev
;
191 struct request_queue
*q
;
194 device_initialize(bsg_dev
);
196 bsg_dev
->parent
= get_device(parent
);
197 bsg_dev
->release
= ufs_bsg_node_release
;
199 dev_set_name(bsg_dev
, "ufs-bsg");
201 ret
= device_add(bsg_dev
);
205 q
= bsg_setup_queue(bsg_dev
, dev_name(bsg_dev
), ufs_bsg_request
, NULL
, 0);
216 dev_err(bsg_dev
, "fail to initialize a bsg dev %d\n", shost
->host_no
);