Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

scsi: pm80xx: Completing pending I/O after fatal error

When controller runs into fatal error, I/Os get stuck with no response,
handler event is defined to complete the pending I/Os (SAS task and
internal task) and also perform the cleanup for the drives.

Link: https://lore.kernel.org/r/20210415103352.3580-7-Viswas.G@microchip.com
Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com>
Signed-off-by: Ruksar Devadi <Ruksar.devadi@microchip.com>
Signed-off-by: Viswas G <Viswas.G@microchip.com>
Signed-off-by: Ashokkumar N <Ashokkumar.N@microchip.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Ruksar Devadi and committed by
Martin K. Petersen
4f5deeb4 b0c306e6

+65 -7
+60 -6
drivers/scsi/pm8001/pm8001_hwi.c
··· 1499 1499 * was cancelled. This nullification happens when the device 1500 1500 * goes away. 1501 1501 */ 1502 - pm8001_dev = pw->data; /* Most stash device structure */ 1503 - if ((pm8001_dev == NULL) 1504 - || ((pw->handler != IO_XFER_ERROR_BREAK) 1505 - && (pm8001_dev->dev_type == SAS_PHY_UNUSED))) { 1506 - kfree(pw); 1507 - return; 1502 + if (pw->handler != IO_FATAL_ERROR) { 1503 + pm8001_dev = pw->data; /* Most stash device structure */ 1504 + if ((pm8001_dev == NULL) 1505 + || ((pw->handler != IO_XFER_ERROR_BREAK) 1506 + && (pm8001_dev->dev_type == SAS_PHY_UNUSED))) { 1507 + kfree(pw); 1508 + return; 1509 + } 1508 1510 } 1509 1511 1510 1512 switch (pw->handler) { ··· 1670 1668 dev = pm8001_dev->sas_device; 1671 1669 pm8001_I_T_nexus_reset(dev); 1672 1670 break; 1671 + case IO_FATAL_ERROR: 1672 + { 1673 + struct pm8001_hba_info *pm8001_ha = pw->pm8001_ha; 1674 + struct pm8001_ccb_info *ccb; 1675 + struct task_status_struct *ts; 1676 + struct sas_task *task; 1677 + int i; 1678 + u32 tag, device_id; 1679 + 1680 + for (i = 0; ccb = NULL, i < PM8001_MAX_CCB; i++) { 1681 + ccb = &pm8001_ha->ccb_info[i]; 1682 + task = ccb->task; 1683 + ts = &task->task_status; 1684 + tag = ccb->ccb_tag; 1685 + /* check if tag is NULL */ 1686 + if (!tag) { 1687 + pm8001_dbg(pm8001_ha, FAIL, 1688 + "tag Null\n"); 1689 + continue; 1690 + } 1691 + if (task != NULL) { 1692 + dev = task->dev; 1693 + if (!dev) { 1694 + pm8001_dbg(pm8001_ha, FAIL, 1695 + "dev is NULL\n"); 1696 + continue; 1697 + } 1698 + /*complete sas task and update to top layer */ 1699 + pm8001_ccb_task_free(pm8001_ha, task, ccb, tag); 1700 + ts->resp = SAS_TASK_COMPLETE; 1701 + task->task_done(task); 1702 + } else if (tag != 0xFFFFFFFF) { 1703 + /* complete the internal commands/non-sas task */ 1704 + pm8001_dev = ccb->device; 1705 + if (pm8001_dev->dcompletion) { 1706 + complete(pm8001_dev->dcompletion); 1707 + pm8001_dev->dcompletion = NULL; 1708 + } 1709 + complete(pm8001_ha->nvmd_completion); 1710 + pm8001_tag_free(pm8001_ha, tag); 1711 + } 1712 + } 1713 + /* Deregister all the device ids */ 1714 + for (i = 0; i < PM8001_MAX_DEVICES; i++) { 1715 + pm8001_dev = &pm8001_ha->devices[i]; 1716 + device_id = pm8001_dev->device_id; 1717 + if (device_id) { 1718 + PM8001_CHIP_DISP->dereg_dev_req(pm8001_ha, device_id); 1719 + pm8001_free_dev(pm8001_dev); 1720 + } 1721 + } 1722 + } break; 1673 1723 } 1674 1724 kfree(pw); 1675 1725 }
+1
drivers/scsi/pm8001/pm8001_hwi.h
··· 805 805 #define IO_ABORT_IN_PROGRESS 0x40 806 806 #define IO_ABORT_DELAYED 0x41 807 807 #define IO_INVALID_LENGTH 0x42 808 + #define IO_FATAL_ERROR 0x51 808 809 809 810 /* WARNING: This error code must always be the last number. 810 811 * If you add error code, modify this code also
+1 -1
drivers/scsi/pm8001/pm8001_sas.c
··· 590 590 return NULL; 591 591 } 592 592 593 - static void pm8001_free_dev(struct pm8001_device *pm8001_dev) 593 + void pm8001_free_dev(struct pm8001_device *pm8001_dev) 594 594 { 595 595 u32 id = pm8001_dev->id; 596 596 memset(pm8001_dev, 0, sizeof(*pm8001_dev));
+1
drivers/scsi/pm8001/pm8001_sas.h
··· 726 726 struct device_attribute *attr, char *buf); 727 727 ssize_t pm8001_get_gsm_dump(struct device *cdev, u32, char *buf); 728 728 int pm80xx_fatal_errors(struct pm8001_hba_info *pm8001_ha); 729 + void pm8001_free_dev(struct pm8001_device *pm8001_dev); 729 730 /* ctl shared API */ 730 731 extern struct device_attribute *pm8001_host_attrs[]; 731 732
+1
drivers/scsi/pm8001/pm80xx_hwi.c
··· 4126 4126 pm8001_dbg(pm8001_ha, FAIL, 4127 4127 "Firmware Fatal error! Regval:0x%x\n", 4128 4128 regval); 4129 + pm8001_handle_event(pm8001_ha, NULL, IO_FATAL_ERROR); 4129 4130 print_scratchpad_registers(pm8001_ha); 4130 4131 return ret; 4131 4132 }
+1
drivers/scsi/pm8001/pm80xx_hwi.h
··· 1272 1272 #define IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE 0x47 1273 1273 #define IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED 0x48 1274 1274 #define IO_DS_INVALID 0x49 1275 + #define IO_FATAL_ERROR 0x51 1275 1276 /* WARNING: the value is not contiguous from here */ 1276 1277 #define IO_XFER_ERR_LAST_PIO_DATAIN_CRC_ERR 0x52 1277 1278 #define IO_XFER_DMA_ACTIVATE_TIMEOUT 0x53