2 * QEMU UFS Logical Unit
4 * Copyright (c) 2023 Samsung Electronics Co., Ltd. All rights reserved.
6 * Written by Jeuk Kim <jeuk20.kim@samsung.com>
8 * This code is licensed under the GNU GPL v2 or later.
11 #include "qemu/osdep.h"
12 #include "qemu/units.h"
13 #include "qapi/error.h"
14 #include "qemu/memalign.h"
15 #include "hw/scsi/scsi.h"
16 #include "scsi/constants.h"
17 #include "sysemu/block-backend.h"
18 #include "qemu/cutils.h"
22 #define SCSI_COMMAND_FAIL (-1)
24 static void ufs_build_upiu_sense_data(UfsRequest
*req
, uint8_t *sense
,
27 req
->rsp_upiu
.sr
.sense_data_len
= cpu_to_be16(sense_len
);
28 assert(sense_len
<= SCSI_SENSE_LEN
);
29 memcpy(req
->rsp_upiu
.sr
.sense_data
, sense
, sense_len
);
32 static void ufs_build_scsi_response_upiu(UfsRequest
*req
, uint8_t *sense
,
34 uint32_t transfered_len
,
37 uint32_t expected_len
= be32_to_cpu(req
->req_upiu
.sc
.exp_data_transfer_len
);
38 uint8_t flags
= 0, response
= UFS_COMMAND_RESULT_SUCCESS
;
39 uint16_t data_segment_length
;
41 if (expected_len
> transfered_len
) {
42 req
->rsp_upiu
.sr
.residual_transfer_count
=
43 cpu_to_be32(expected_len
- transfered_len
);
44 flags
|= UFS_UPIU_FLAG_UNDERFLOW
;
45 } else if (expected_len
< transfered_len
) {
46 req
->rsp_upiu
.sr
.residual_transfer_count
=
47 cpu_to_be32(transfered_len
- expected_len
);
48 flags
|= UFS_UPIU_FLAG_OVERFLOW
;
52 ufs_build_upiu_sense_data(req
, sense
, sense_len
);
53 response
= UFS_COMMAND_RESULT_FAIL
;
57 cpu_to_be16(sense_len
+ sizeof(req
->rsp_upiu
.sr
.sense_data_len
));
58 ufs_build_upiu_header(req
, UFS_UPIU_TRANSACTION_RESPONSE
, flags
, response
,
59 status
, data_segment_length
);
62 static void ufs_scsi_command_complete(SCSIRequest
*scsi_req
, size_t resid
)
64 UfsRequest
*req
= scsi_req
->hba_private
;
65 int16_t status
= scsi_req
->status
;
67 uint32_t transfered_len
= scsi_req
->cmd
.xfer
- resid
;
69 ufs_build_scsi_response_upiu(req
, scsi_req
->sense
, scsi_req
->sense_len
,
70 transfered_len
, status
);
72 ufs_complete_req(req
, UFS_REQUEST_SUCCESS
);
74 scsi_req
->hba_private
= NULL
;
75 scsi_req_unref(scsi_req
);
78 static QEMUSGList
*ufs_get_sg_list(SCSIRequest
*scsi_req
)
80 UfsRequest
*req
= scsi_req
->hba_private
;
84 static const struct SCSIBusInfo ufs_scsi_info
= {
87 .max_lun
= UFS_MAX_LUS
,
90 .get_sg_list
= ufs_get_sg_list
,
91 .complete
= ufs_scsi_command_complete
,
94 static int ufs_emulate_report_luns(UfsRequest
*req
, uint8_t *outbuf
,
100 /* TODO: Support for cases where SELECT REPORT is 1 and 2 */
101 if (req
->req_upiu
.sc
.cdb
[2] != 0) {
102 return SCSI_COMMAND_FAIL
;
107 for (uint8_t lun
= 0; lun
< UFS_MAX_LUS
; ++lun
) {
109 if (len
+ 8 > outbuf_len
) {
113 memset(outbuf
+ len
, 0, 8);
115 outbuf
[len
+ 1] = lun
;
120 /* store the LUN list length */
121 stl_be_p(outbuf
, len
- 8);
126 static int ufs_scsi_emulate_vpd_page(UfsRequest
*req
, uint8_t *outbuf
,
129 uint8_t page_code
= req
->req_upiu
.sc
.cdb
[2];
130 int start
, buflen
= 0;
132 outbuf
[buflen
++] = TYPE_WLUN
;
133 outbuf
[buflen
++] = page_code
;
134 outbuf
[buflen
++] = 0x00;
135 outbuf
[buflen
++] = 0x00;
139 case 0x00: /* Supported page codes, mandatory */
141 outbuf
[buflen
++] = 0x00; /* list of supported pages (this page) */
142 outbuf
[buflen
++] = 0x87; /* mode page policy */
145 case 0x87: /* Mode Page Policy, mandatory */
147 outbuf
[buflen
++] = 0x3f; /* apply to all mode pages and subpages */
148 outbuf
[buflen
++] = 0xff;
149 outbuf
[buflen
++] = 0; /* shared */
150 outbuf
[buflen
++] = 0;
154 return SCSI_COMMAND_FAIL
;
157 assert(buflen
- start
<= 255);
158 outbuf
[start
- 1] = buflen
- start
;
162 static int ufs_emulate_wlun_inquiry(UfsRequest
*req
, uint8_t *outbuf
,
165 if (outbuf_len
< SCSI_INQUIRY_LEN
) {
169 if (req
->req_upiu
.sc
.cdb
[1] & 0x1) {
170 /* Vital product data */
171 return ufs_scsi_emulate_vpd_page(req
, outbuf
, outbuf_len
);
174 /* Standard INQUIRY data */
175 if (req
->req_upiu
.sc
.cdb
[2] != 0) {
176 return SCSI_COMMAND_FAIL
;
179 outbuf
[0] = TYPE_WLUN
;
181 outbuf
[2] = 0x6; /* SPC-4 */
187 strpadcpy((char *)&outbuf
[8], 8, "QEMU", ' ');
188 strpadcpy((char *)&outbuf
[16], 16, "QEMU UFS", ' ');
189 memset(&outbuf
[32], 0, 4);
191 return SCSI_INQUIRY_LEN
;
194 static UfsReqResult
ufs_emulate_scsi_cmd(UfsLu
*lu
, UfsRequest
*req
)
196 uint8_t lun
= lu
->lun
;
197 uint8_t outbuf
[4096];
198 uint8_t sense_buf
[UFS_SENSE_SIZE
];
202 switch (req
->req_upiu
.sc
.cdb
[0]) {
204 len
= ufs_emulate_report_luns(req
, outbuf
, sizeof(outbuf
));
205 if (len
== SCSI_COMMAND_FAIL
) {
206 scsi_build_sense(sense_buf
, SENSE_CODE(INVALID_FIELD
));
207 scsi_status
= CHECK_CONDITION
;
213 len
= ufs_emulate_wlun_inquiry(req
, outbuf
, sizeof(outbuf
));
214 if (len
== SCSI_COMMAND_FAIL
) {
215 scsi_build_sense(sense_buf
, SENSE_CODE(INVALID_FIELD
));
216 scsi_status
= CHECK_CONDITION
;
222 /* Just return no sense data */
223 len
= scsi_build_sense_buf(outbuf
, sizeof(outbuf
), SENSE_CODE(NO_SENSE
),
228 /* TODO: Revisit it when Power Management is implemented */
229 if (lun
== UFS_UPIU_UFS_DEVICE_WLUN
) {
235 scsi_build_sense(sense_buf
, SENSE_CODE(INVALID_OPCODE
));
236 scsi_status
= CHECK_CONDITION
;
239 len
= MIN(len
, (int)req
->data_len
);
240 if (scsi_status
== GOOD
&& len
> 0 &&
241 dma_buf_read(outbuf
, len
, NULL
, req
->sg
, MEMTXATTRS_UNSPECIFIED
) !=
243 return UFS_REQUEST_FAIL
;
246 ufs_build_scsi_response_upiu(req
, sense_buf
, sizeof(sense_buf
), len
,
248 return UFS_REQUEST_SUCCESS
;
251 static UfsReqResult
ufs_process_scsi_cmd(UfsLu
*lu
, UfsRequest
*req
)
253 uint8_t task_tag
= req
->req_upiu
.header
.task_tag
;
256 * Each ufs-lu has its own independent virtual SCSI bus. Therefore, we can't
257 * use scsi_target_emulate_report_luns() which gets all lu information over
258 * the SCSI bus. Therefore, we use ufs_emulate_scsi_cmd() like the
261 if (req
->req_upiu
.sc
.cdb
[0] == REPORT_LUNS
) {
262 return ufs_emulate_scsi_cmd(lu
, req
);
265 SCSIRequest
*scsi_req
=
266 scsi_req_new(lu
->scsi_dev
, task_tag
, lu
->lun
, req
->req_upiu
.sc
.cdb
,
269 uint32_t len
= scsi_req_enqueue(scsi_req
);
271 scsi_req_continue(scsi_req
);
274 return UFS_REQUEST_NO_COMPLETE
;
277 static Property ufs_lu_props
[] = {
278 DEFINE_PROP_DRIVE("drive", UfsLu
, conf
.blk
),
279 DEFINE_PROP_UINT8("lun", UfsLu
, lun
, 0),
280 DEFINE_PROP_END_OF_LIST(),
283 static bool ufs_add_lu(UfsHc
*u
, UfsLu
*lu
, Error
**errp
)
285 BlockBackend
*blk
= lu
->conf
.blk
;
286 int64_t brdv_len
= blk_getlength(blk
);
287 uint64_t raw_dev_cap
=
288 be64_to_cpu(u
->geometry_desc
.total_raw_device_capacity
);
290 if (u
->device_desc
.number_lu
>= UFS_MAX_LUS
) {
291 error_setg(errp
, "ufs host controller has too many logical units.");
295 if (u
->lus
[lu
->lun
] != NULL
) {
296 error_setg(errp
, "ufs logical unit %d already exists.", lu
->lun
);
300 u
->lus
[lu
->lun
] = lu
;
301 u
->device_desc
.number_lu
++;
302 raw_dev_cap
+= (brdv_len
>> UFS_GEOMETRY_CAPACITY_SHIFT
);
303 u
->geometry_desc
.total_raw_device_capacity
= cpu_to_be64(raw_dev_cap
);
307 void ufs_init_wlu(UfsLu
*wlu
, uint8_t wlun
)
310 wlu
->scsi_op
= &ufs_emulate_scsi_cmd
;
313 static void ufs_init_lu(UfsLu
*lu
)
315 BlockBackend
*blk
= lu
->conf
.blk
;
316 int64_t brdv_len
= blk_getlength(blk
);
318 memset(&lu
->unit_desc
, 0, sizeof(lu
->unit_desc
));
319 lu
->unit_desc
.length
= sizeof(UnitDescriptor
);
320 lu
->unit_desc
.descriptor_idn
= UFS_QUERY_DESC_IDN_UNIT
;
321 lu
->unit_desc
.lu_enable
= 0x01;
322 lu
->unit_desc
.logical_block_size
= UFS_BLOCK_SIZE_SHIFT
;
323 lu
->unit_desc
.unit_index
= lu
->lun
;
324 lu
->unit_desc
.logical_block_count
=
325 cpu_to_be64(brdv_len
/ (1 << lu
->unit_desc
.logical_block_size
));
327 lu
->scsi_op
= &ufs_process_scsi_cmd
;
330 static bool ufs_lu_check_constraints(UfsLu
*lu
, Error
**errp
)
333 error_setg(errp
, "drive property not set");
337 if (lu
->lun
>= UFS_MAX_LUS
) {
338 error_setg(errp
, "lun must be between 0 and %d", UFS_MAX_LUS
- 1);
345 static void ufs_init_scsi_device(UfsLu
*lu
, BlockBackend
*blk
, Error
**errp
)
347 DeviceState
*scsi_dev
;
349 scsi_bus_init(&lu
->bus
, sizeof(lu
->bus
), DEVICE(lu
), &ufs_scsi_info
);
352 blk_detach_dev(blk
, DEVICE(lu
));
356 * The ufs-lu is the device that is wrapping the scsi-hd. It owns a virtual
357 * SCSI bus that serves the scsi-hd.
359 scsi_dev
= qdev_new("scsi-hd");
360 object_property_add_child(OBJECT(&lu
->bus
), "ufs-scsi", OBJECT(scsi_dev
));
362 qdev_prop_set_uint32(scsi_dev
, "physical_block_size", UFS_BLOCK_SIZE
);
363 qdev_prop_set_uint32(scsi_dev
, "logical_block_size", UFS_BLOCK_SIZE
);
364 qdev_prop_set_uint32(scsi_dev
, "scsi-id", 0);
365 qdev_prop_set_uint32(scsi_dev
, "lun", lu
->lun
);
366 if (!qdev_prop_set_drive_err(scsi_dev
, "drive", blk
, errp
)) {
367 object_unparent(OBJECT(scsi_dev
));
371 if (!qdev_realize_and_unref(scsi_dev
, &lu
->bus
.qbus
, errp
)) {
372 object_unparent(OBJECT(scsi_dev
));
377 lu
->scsi_dev
= SCSI_DEVICE(scsi_dev
);
380 static void ufs_lu_realize(DeviceState
*dev
, Error
**errp
)
382 UfsLu
*lu
= DO_UPCAST(UfsLu
, qdev
, dev
);
383 BusState
*s
= qdev_get_parent_bus(dev
);
384 UfsHc
*u
= UFS(s
->parent
);
385 BlockBackend
*blk
= lu
->conf
.blk
;
387 if (!ufs_lu_check_constraints(lu
, errp
)) {
392 error_setg(errp
, "drive property not set");
396 if (!blkconf_blocksizes(&lu
->conf
, errp
)) {
400 if (!blkconf_apply_backend_options(&lu
->conf
, !blk_supports_write_perm(blk
),
406 if (!ufs_add_lu(u
, lu
, errp
)) {
410 ufs_init_scsi_device(lu
, blk
, errp
);
413 static void ufs_lu_unrealize(DeviceState
*dev
)
415 UfsLu
*lu
= DO_UPCAST(UfsLu
, qdev
, dev
);
418 object_unref(OBJECT(lu
->scsi_dev
));
423 static void ufs_lu_class_init(ObjectClass
*oc
, void *data
)
425 DeviceClass
*dc
= DEVICE_CLASS(oc
);
427 dc
->realize
= ufs_lu_realize
;
428 dc
->unrealize
= ufs_lu_unrealize
;
429 dc
->bus_type
= TYPE_UFS_BUS
;
430 device_class_set_props(dc
, ufs_lu_props
);
431 dc
->desc
= "Virtual UFS logical unit";
434 static const TypeInfo ufs_lu_info
= {
436 .parent
= TYPE_DEVICE
,
437 .class_init
= ufs_lu_class_init
,
438 .instance_size
= sizeof(UfsLu
),
441 static void ufs_lu_register_types(void)
443 type_register_static(&ufs_lu_info
);
446 type_init(ufs_lu_register_types
)