Skip to content

Commit 5efff64

Browse files
Vishakha Channapattanmartinkpetersen
authored andcommitted
scsi: pm80xx: Improve debugging for aborted commands
Improves the debugging capabilities of the driver by adding more context to debug messages: 1. Introduce a new function to show pending commands. 2. Include the tag number in NCQ EH path debug messages. 3. Add logging for ata_tag along with pm80xx tag to map I/Os aborted with ATA logs. Signed-off-by: Vishakha Channapattan <[email protected]> Signed-off-by: Salomon Dushimirimana <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Martin K. Petersen <[email protected]>
1 parent b64004d commit 5efff64

File tree

4 files changed

+77
-9
lines changed

4 files changed

+77
-9
lines changed

drivers/scsi/pm8001/pm8001_hwi.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3472,12 +3472,13 @@ int pm8001_mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
34723472
status, tag, scp);
34733473
switch (status) {
34743474
case IO_SUCCESS:
3475-
pm8001_dbg(pm8001_ha, EH, "IO_SUCCESS\n");
3475+
pm8001_dbg(pm8001_ha, FAIL, "ABORT IO_SUCCESS for tag %#x\n",
3476+
tag);
34763477
ts->resp = SAS_TASK_COMPLETE;
34773478
ts->stat = SAS_SAM_STAT_GOOD;
34783479
break;
34793480
case IO_NOT_VALID:
3480-
pm8001_dbg(pm8001_ha, EH, "IO_NOT_VALID\n");
3481+
pm8001_dbg(pm8001_ha, FAIL, "IO_NOT_VALID for tag %#x\n", tag);
34813482
ts->resp = TMF_RESP_FUNC_FAILED;
34823483
break;
34833484
}

drivers/scsi/pm8001/pm8001_sas.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,63 @@ int pm8001_tag_alloc(struct pm8001_hba_info *pm8001_ha, u32 *tag_out)
101101
return 0;
102102
}
103103

104+
static void pm80xx_get_tag_opcodes(struct sas_task *task, int *ata_op,
105+
int *ata_tag, bool *task_aborted)
106+
{
107+
unsigned long flags;
108+
struct ata_queued_cmd *qc = NULL;
109+
110+
*ata_op = 0;
111+
*ata_tag = -1;
112+
*task_aborted = false;
113+
114+
if (!task)
115+
return;
116+
117+
spin_lock_irqsave(&task->task_state_lock, flags);
118+
if (unlikely((task->task_state_flags & SAS_TASK_STATE_ABORTED)))
119+
*task_aborted = true;
120+
spin_unlock_irqrestore(&task->task_state_lock, flags);
121+
122+
if (task->task_proto == SAS_PROTOCOL_STP) {
123+
// sas_ata_qc_issue path uses SAS_PROTOCOL_STP.
124+
// This only works for scsi + libsas + libata users.
125+
qc = task->uldd_task;
126+
if (qc) {
127+
*ata_op = qc->tf.command;
128+
*ata_tag = qc->tag;
129+
}
130+
}
131+
}
132+
133+
void pm80xx_show_pending_commands(struct pm8001_hba_info *pm8001_ha,
134+
struct pm8001_device *target_pm8001_dev)
135+
{
136+
int i = 0, ata_op = 0, ata_tag = -1;
137+
struct pm8001_ccb_info *ccb = NULL;
138+
struct sas_task *task = NULL;
139+
struct pm8001_device *pm8001_dev = NULL;
140+
bool task_aborted;
141+
142+
for (i = 0; i < pm8001_ha->ccb_count; i++) {
143+
ccb = &pm8001_ha->ccb_info[i];
144+
if (ccb->ccb_tag == PM8001_INVALID_TAG)
145+
continue;
146+
pm8001_dev = ccb->device;
147+
if (target_pm8001_dev && pm8001_dev &&
148+
target_pm8001_dev != pm8001_dev)
149+
continue;
150+
task = ccb->task;
151+
pm80xx_get_tag_opcodes(task, &ata_op, &ata_tag, &task_aborted);
152+
pm8001_dbg(pm8001_ha, FAIL,
153+
"tag %#x, device %#x task %p task aborted %d ata opcode %#x ata tag %d\n",
154+
ccb->ccb_tag,
155+
(pm8001_dev ? pm8001_dev->device_id : 0),
156+
task, task_aborted,
157+
ata_op, ata_tag);
158+
}
159+
}
160+
104161
/**
105162
* pm8001_mem_alloc - allocate memory for pm8001.
106163
* @pdev: pci device.

drivers/scsi/pm8001/pm8001_sas.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,8 @@ static inline void pm8001_ccb_task_free_done(struct pm8001_hba_info *pm8001_ha,
787787
}
788788
void pm8001_setds_completion(struct domain_device *dev);
789789
void pm8001_tmf_aborted(struct sas_task *task);
790+
void pm80xx_show_pending_commands(struct pm8001_hba_info *pm8001_ha,
791+
struct pm8001_device *dev);
790792

791793
#endif
792794

drivers/scsi/pm8001/pm80xx_hwi.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2246,7 +2246,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha,
22462246
u32 param;
22472247
u32 status;
22482248
u32 tag;
2249-
int i, j;
2249+
int i, j, ata_tag = -1;
22502250
u8 sata_addr_low[4];
22512251
u32 temp_sata_addr_low, temp_sata_addr_hi;
22522252
u8 sata_addr_hi[4];
@@ -2256,6 +2256,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha,
22562256
u32 *sata_resp;
22572257
struct pm8001_device *pm8001_dev;
22582258
unsigned long flags;
2259+
struct ata_queued_cmd *qc;
22592260

22602261
psataPayload = (struct sata_completion_resp *)(piomb + 4);
22612262
status = le32_to_cpu(psataPayload->status);
@@ -2267,25 +2268,26 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha,
22672268
pm8001_dev = ccb->device;
22682269

22692270
if (t) {
2270-
if (t->dev && (t->dev->lldd_dev))
2271+
if (t->dev && (t->dev->lldd_dev)) {
22712272
pm8001_dev = t->dev->lldd_dev;
2273+
qc = t->uldd_task;
2274+
ata_tag = qc ? qc->tag : -1;
2275+
}
22722276
} else {
22732277
pm8001_dbg(pm8001_ha, FAIL, "task null, freeing CCB tag %d\n",
22742278
ccb->ccb_tag);
22752279
pm8001_ccb_free(pm8001_ha, ccb);
22762280
return;
22772281
}
22782282

2279-
22802283
if (pm8001_dev && unlikely(!t->lldd_task || !t->dev))
22812284
return;
22822285

22832286
ts = &t->task_status;
2284-
22852287
if (status != IO_SUCCESS) {
22862288
pm8001_dbg(pm8001_ha, FAIL,
2287-
"IO failed device_id %u status 0x%x tag %d\n",
2288-
pm8001_dev->device_id, status, tag);
2289+
"IO failed status %#x pm80xx tag %#x ata tag %d\n",
2290+
status, tag, ata_tag);
22892291
}
22902292

22912293
/* Print sas address of IO failed device */
@@ -2667,13 +2669,19 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha,
26672669

26682670
/* Check if this is NCQ error */
26692671
if (event == IO_XFER_ERROR_ABORTED_NCQ_MODE) {
2672+
/* tag value is invalid with this event */
2673+
pm8001_dbg(pm8001_ha, FAIL, "NCQ ERROR for device %#x tag %#x\n",
2674+
dev_id, tag);
2675+
26702676
/* find device using device id */
26712677
pm8001_dev = pm8001_find_dev(pm8001_ha, dev_id);
26722678
/* send read log extension by aborting the link - libata does what we want */
2673-
if (pm8001_dev)
2679+
if (pm8001_dev) {
2680+
pm80xx_show_pending_commands(pm8001_ha, pm8001_dev);
26742681
pm8001_handle_event(pm8001_ha,
26752682
pm8001_dev,
26762683
IO_XFER_ERROR_ABORTED_NCQ_MODE);
2684+
}
26772685
return;
26782686
}
26792687

0 commit comments

Comments
 (0)