diff --git a/drivers/scsi/cxlflash/common.h b/drivers/scsi/cxlflash/common.h index a91151c4a4fc..e95e5a516b5e 100644 --- a/drivers/scsi/cxlflash/common.h +++ b/drivers/scsi/cxlflash/common.h @@ -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; diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index d3ad52ec5314..0cce442c260a 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c @@ -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: diff --git a/drivers/scsi/cxlflash/sislite.h b/drivers/scsi/cxlflash/sislite.h index d671fae19697..09daa86670fc 100644 --- a/drivers/scsi/cxlflash/sislite.h +++ b/drivers/scsi/cxlflash/sislite.h @@ -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 */ diff --git a/drivers/scsi/cxlflash/vlun.c b/drivers/scsi/cxlflash/vlun.c index 0800bcba5a00..bdfb93061460 100644 --- a/drivers/scsi/cxlflash/vlun.c +++ b/drivers/scsi/cxlflash/vlun.c @@ -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]);