@@ -147,6 +147,7 @@ struct cxlflash_cfg {
wait_queue_head_t tmf_waitq;
spinlock_t tmf_slock;
bool tmf_active;
+ bool ws_unmap; /* Write-same unmap supported */
wait_queue_head_t reset_waitq;
enum cxlflash_state state;
async_cookie_t async_reset_cookie;
@@ -1812,6 +1812,18 @@ static int init_global(struct cxlflash_cfg *cfg)
SISL_CTX_CAP_AFU_CMD | SISL_CTX_CAP_GSCSI_CMD),
&hwq->ctrl_map->ctx_cap);
}
+
+ /*
+ * Determine write-same unmap support for host by evaluating the unmap
+ * sector support bit of the context control register associated with
+ * the primary hardware queue. Note that while this status is reflected
+ * in a context register, the outcome can be assumed to be host-wide.
+ */
+ hwq = get_hwq(afu, PRIMARY_HWQ);
+ reg = readq_be(&hwq->host_map->ctx_ctrl);
+ if (reg & SISL_CTX_CTRL_UNMAP_SECTOR)
+ cfg->ws_unmap = true;
+
/* Initialize heartbeat */
afu->hb = readq_be(&afu->afu_map->global.regs.afu_hb);
out:
@@ -283,6 +283,7 @@ struct sisl_host_map {
__be64 rrq_end; /* write sequence: start followed by end */
__be64 cmd_room;
__be64 ctx_ctrl; /* least significant byte or b56:63 is LISN# */
+#define SISL_CTX_CTRL_UNMAP_SECTOR 0x8000000000000000ULL /* b0 */
__be64 mbox_w; /* restricted use */
__be64 sq_start; /* Submission Queue (R/W): write sequence and */
__be64 sq_end; /* inclusion semantics are the same as RRQ */
@@ -446,6 +446,7 @@ static int write_same16(struct scsi_device *sdev,
while (left > 0) {
scsi_cmd[0] = WRITE_SAME_16;
+ scsi_cmd[1] = cfg->ws_unmap ? 0x8 : 0;
put_unaligned_be64(offset, &scsi_cmd[2]);
put_unaligned_be32(ws_limit < left ? ws_limit : left,
&scsi_cmd[10]);