Page MenuHomeFreeBSD

D61117.1793787325.diff
No OneTemporary

Authored By
Unknown
Size
3 KB
Referenced Files
None
Subscribers
None

D61117.1793787325.diff

diff --git a/sys/dev/ufshci/ufshci.h b/sys/dev/ufshci/ufshci.h
--- a/sys/dev/ufshci/ufshci.h
+++ b/sys/dev/ufshci/ufshci.h
@@ -653,6 +653,8 @@
struct ufshci_completion {
union ufshci_reponse_upiu response_upiu;
size_t size;
+ /* Overall command status of the completed request. */
+ uint8_t ocs;
};
typedef void (*ufshci_cb_fn_t)(void *, const struct ufshci_completion *, bool);
diff --git a/sys/dev/ufshci/ufshci.c b/sys/dev/ufshci/ufshci.c
--- a/sys/dev/ufshci/ufshci.c
+++ b/sys/dev/ufshci/ufshci.c
@@ -59,6 +59,7 @@
* or failed.
*/
memcpy(&status->cpl.response_upiu, &cpl->response_upiu, cpl->size);
+ status->cpl.ocs = cpl->ocs;
status->error = error;
atomic_store_rel_int(&status->done, 1);
}
diff --git a/sys/dev/ufshci/ufshci_ioctl.h b/sys/dev/ufshci/ufshci_ioctl.h
--- a/sys/dev/ufshci/ufshci_ioctl.h
+++ b/sys/dev/ufshci/ufshci_ioctl.h
@@ -39,7 +39,7 @@
uint32_t flags; /* [in] UFSHCI_PT_FLAG_* */
uint32_t timeout_ms; /* [in] reserved, must be 0 */
uint32_t xfer_len; /* [out] bytes the request carried */
- uint8_t ocs; /* [out] reserved, always 0 for now */
+ uint8_t ocs; /* [out] overall command status */
uint8_t reserved[7];
};
diff --git a/sys/dev/ufshci/ufshci_ioctl.c b/sys/dev/ufshci/ufshci_ioctl.c
--- a/sys/dev/ufshci/ufshci_ioctl.c
+++ b/sys/dev/ufshci/ufshci_ioctl.c
@@ -176,8 +176,7 @@
memcpy(&pt->resp_upiu, &status.cpl.response_upiu,
min(sizeof(pt->resp_upiu), sizeof(status.cpl.response_upiu)));
pt->xfer_len = pt->len;
- /* The completion does not carry the overall command status yet. */
- pt->ocs = 0;
+ pt->ocs = status.cpl.ocs;
/*
* A refused command still answered, so let the caller read the
diff --git a/sys/dev/ufshci/ufshci_req_queue.c b/sys/dev/ufshci/ufshci_req_queue.c
--- a/sys/dev/ufshci/ufshci_req_queue.c
+++ b/sys/dev/ufshci/ufshci_req_queue.c
@@ -240,6 +240,11 @@
tr->slot_state = UFSHCI_SLOT_STATE_COMPLETING;
mtx_unlock(&hwq->qlock);
+ /*
+ * TODO: The request that timed out and caused the reset is
+ * requeued here as well, without using a retry, so a command
+ * the device never answers repeats timeout and reset forever.
+ */
ufshci_req_queue_manual_complete_tracker(tr,
UFSHCI_DESC_ABORTED,
UFSHCI_RESPONSE_CODE_GENERAL_FAILURE);
@@ -323,6 +328,8 @@
ocs = hwq->utrd[tr->slot_num].overall_command_status;
}
+ cpl.ocs = ocs;
+
error = ufshci_req_queue_response_is_error(req_queue, ocs,
&cpl.response_upiu);
@@ -562,8 +569,9 @@
*/
ufshci_printf(tr->hwq->ctrlr,
"abort task request failed, aborting task manually\n");
+ /* Not ABORTED: the SIM requeues those without a retry. */
ufshci_req_queue_manual_complete_tracker(tr,
- UFSHCI_DESC_ABORTED, UFSHCI_RESPONSE_CODE_GENERAL_FAILURE);
+ UFSHCI_DESC_INVALID, UFSHCI_RESPONSE_CODE_GENERAL_FAILURE);
output_param1 = be32toh(
status->response_upiu.task_mgmt_response_upiu.output_param1);
diff --git a/sys/dev/ufshci/ufshci_sim.c b/sys/dev/ufshci/ufshci_sim.c
--- a/sys/dev/ufshci/ufshci_sim.c
+++ b/sys/dev/ufshci/ufshci_sim.c
@@ -46,7 +46,15 @@
min(sense_data_len, sense_data_max_size));
ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
- if (error) {
+ if (cpl->ocs == UFSHCI_DESC_ABORTED) {
+ /*
+ * A reset took the request back, so requeue it without a
+ * retry. A failed controller rejects the resubmit, so
+ * this cannot loop.
+ */
+ ccb->ccb_h.status = CAM_REQUEUE_REQ;
+ xpt_done(ccb);
+ } else if (error) {
printf("ufshci: SCSI command completion error, Status(0x%x)"
" Key(0x%x), ASC(0x%x), ASCQ(0x%x)\n",
cpl->response_upiu.cmd_response_upiu.header

File Metadata

Mime Type
text/plain
Expires
Wed, Nov 4, 10:15 AM (1 h, 52 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41360920
Default Alt Text
D61117.1793787325.diff (3 KB)

Event Timeline