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

scsi: libsas: Add sas_abort_task()

Add a generic implementation of abort task TMF handler, and use in LLDDs.

With that, some LLDDs custom TMF functions can now be deleted.

Link: https://lore.kernel.org/r/1645112566-115804-18-git-send-email-john.garry@huawei.com
Tested-by: Yihang Li <liyihang6@hisilicon.com>
Tested-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: John Garry <john.garry@huawei.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

John Garry and committed by
Martin K. Petersen
4fea759e 72f8810e

+20 -259
+1 -26
drivers/scsi/hisi_sas/hisi_sas_main.c
··· 10 10 #define DEV_IS_GONE(dev) \ 11 11 ((!dev) || (dev->dev_type == SAS_PHY_UNUSED)) 12 12 13 - static int hisi_sas_debug_issue_ssp_tmf(struct domain_device *device, 14 - u8 *lun, struct sas_tmf_task *tmf); 15 13 static int 16 14 hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba, 17 15 struct domain_device *device, ··· 1414 1416 return rc; 1415 1417 } 1416 1418 1417 - static int hisi_sas_debug_issue_ssp_tmf(struct domain_device *device, 1418 - u8 *lun, struct sas_tmf_task *tmf) 1419 - { 1420 - struct sas_ssp_task ssp_task; 1421 - 1422 - if (!(device->tproto & SAS_PROTOCOL_SSP)) 1423 - return TMF_RESP_FUNC_ESUPP; 1424 - 1425 - memcpy(ssp_task.LUN, lun, 8); 1426 - 1427 - return hisi_sas_exec_internal_tmf_task(device, &ssp_task, 1428 - sizeof(ssp_task), tmf); 1429 - } 1430 - 1431 1419 static void hisi_sas_refresh_port_id(struct hisi_hba *hisi_hba) 1432 1420 { 1433 1421 u32 state = hisi_hba->hw->get_phys_state(hisi_hba); ··· 1659 1675 1660 1676 static int hisi_sas_abort_task(struct sas_task *task) 1661 1677 { 1662 - struct scsi_lun lun; 1663 - struct sas_tmf_task tmf_task; 1664 1678 struct domain_device *device = task->dev; 1665 1679 struct hisi_sas_device *sas_dev = device->lldd_dev; 1666 1680 struct hisi_hba *hisi_hba; ··· 1693 1711 spin_unlock_irqrestore(&task->task_state_lock, flags); 1694 1712 1695 1713 if (task->lldd_task && task->task_proto & SAS_PROTOCOL_SSP) { 1696 - struct scsi_cmnd *cmnd = task->uldd_task; 1697 1714 struct hisi_sas_slot *slot = task->lldd_task; 1698 1715 u16 tag = slot->idx; 1699 1716 int rc2; 1700 1717 1701 - int_to_scsilun(cmnd->device->lun, &lun); 1702 - tmf_task.tmf = TMF_ABORT_TASK; 1703 - tmf_task.tag_of_task_to_be_managed = tag; 1704 - 1705 - rc = hisi_sas_debug_issue_ssp_tmf(task->dev, lun.scsi_lun, 1706 - &tmf_task); 1707 - 1718 + rc = sas_abort_task(task, tag); 1708 1719 rc2 = hisi_sas_internal_task_abort(hisi_hba, device, 1709 1720 HISI_SAS_INT_ABT_CMD, tag, 1710 1721 false);
+16
drivers/scsi/libsas/sas_scsi_host.c
··· 1089 1089 } 1090 1090 EXPORT_SYMBOL_GPL(sas_query_task); 1091 1091 1092 + int sas_abort_task(struct sas_task *task, u16 tag) 1093 + { 1094 + struct sas_tmf_task tmf_task = { 1095 + .tmf = TMF_ABORT_TASK, 1096 + .tag_of_task_to_be_managed = tag, 1097 + }; 1098 + struct scsi_cmnd *cmnd = task->uldd_task; 1099 + struct domain_device *dev = task->dev; 1100 + struct scsi_lun lun; 1101 + 1102 + int_to_scsilun(cmnd->device->lun, &lun); 1103 + 1104 + return sas_execute_ssp_tmf(dev, lun.scsi_lun, &tmf_task); 1105 + } 1106 + EXPORT_SYMBOL_GPL(sas_abort_task); 1107 + 1092 1108 /* 1093 1109 * Tell an upper layer that it needs to initiate an abort for a given task. 1094 1110 * This should only ever be called by an LLDD.
+1 -117
drivers/scsi/mvsas/mv_sas.c
··· 1254 1254 mvs_dev_gone_notify(dev); 1255 1255 } 1256 1256 1257 - static void mvs_task_done(struct sas_task *task) 1258 - { 1259 - if (!del_timer(&task->slow_task->timer)) 1260 - return; 1261 - complete(&task->slow_task->completion); 1262 - } 1263 - 1264 - static void mvs_tmf_timedout(struct timer_list *t) 1265 - { 1266 - struct sas_task_slow *slow = from_timer(slow, t, timer); 1267 - struct sas_task *task = slow->task; 1268 - 1269 - task->task_state_flags |= SAS_TASK_STATE_ABORTED; 1270 - complete(&task->slow_task->completion); 1271 - } 1272 - 1273 - #define MVS_TASK_TIMEOUT 20 1274 - static int mvs_exec_internal_tmf_task(struct domain_device *dev, 1275 - void *parameter, u32 para_len, struct sas_tmf_task *tmf) 1276 - { 1277 - int res, retry; 1278 - struct sas_task *task = NULL; 1279 - 1280 - for (retry = 0; retry < 3; retry++) { 1281 - task = sas_alloc_slow_task(GFP_KERNEL); 1282 - if (!task) 1283 - return -ENOMEM; 1284 - 1285 - task->dev = dev; 1286 - task->task_proto = dev->tproto; 1287 - 1288 - memcpy(&task->ssp_task, parameter, para_len); 1289 - task->task_done = mvs_task_done; 1290 - 1291 - task->slow_task->timer.function = mvs_tmf_timedout; 1292 - task->slow_task->timer.expires = jiffies + MVS_TASK_TIMEOUT*HZ; 1293 - add_timer(&task->slow_task->timer); 1294 - 1295 - task->tmf = tmf; 1296 - 1297 - res = mvs_queue_command(task, GFP_KERNEL); 1298 - 1299 - if (res) { 1300 - del_timer(&task->slow_task->timer); 1301 - mv_printk("executing internal task failed:%d\n", res); 1302 - goto ex_err; 1303 - } 1304 - 1305 - wait_for_completion(&task->slow_task->completion); 1306 - res = TMF_RESP_FUNC_FAILED; 1307 - /* Even TMF timed out, return direct. */ 1308 - if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) { 1309 - if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { 1310 - mv_printk("TMF task[%x] timeout.\n", tmf->tmf); 1311 - goto ex_err; 1312 - } 1313 - } 1314 - 1315 - if (task->task_status.resp == SAS_TASK_COMPLETE && 1316 - task->task_status.stat == SAS_SAM_STAT_GOOD) { 1317 - res = TMF_RESP_FUNC_COMPLETE; 1318 - break; 1319 - } 1320 - 1321 - if (task->task_status.resp == SAS_TASK_COMPLETE && 1322 - task->task_status.stat == SAS_DATA_UNDERRUN) { 1323 - /* no error, but return the number of bytes of 1324 - * underrun */ 1325 - res = task->task_status.residual; 1326 - break; 1327 - } 1328 - 1329 - if (task->task_status.resp == SAS_TASK_COMPLETE && 1330 - task->task_status.stat == SAS_DATA_OVERRUN) { 1331 - mv_dprintk("blocked task error.\n"); 1332 - res = -EMSGSIZE; 1333 - break; 1334 - } else { 1335 - mv_dprintk(" task to dev %016llx response: 0x%x " 1336 - "status 0x%x\n", 1337 - SAS_ADDR(dev->sas_addr), 1338 - task->task_status.resp, 1339 - task->task_status.stat); 1340 - sas_free_task(task); 1341 - task = NULL; 1342 - 1343 - } 1344 - } 1345 - ex_err: 1346 - BUG_ON(retry == 3 && task != NULL); 1347 - sas_free_task(task); 1348 - return res; 1349 - } 1350 - 1351 - static int mvs_debug_issue_ssp_tmf(struct domain_device *dev, 1352 - u8 *lun, struct sas_tmf_task *tmf) 1353 - { 1354 - struct sas_ssp_task ssp_task; 1355 - if (!(dev->tproto & SAS_PROTOCOL_SSP)) 1356 - return TMF_RESP_FUNC_ESUPP; 1357 - 1358 - memcpy(ssp_task.LUN, lun, 8); 1359 - 1360 - return mvs_exec_internal_tmf_task(dev, &ssp_task, 1361 - sizeof(ssp_task), tmf); 1362 - } 1363 - 1364 - 1365 1257 /* Standard mandates link reset for ATA (type 0) 1366 1258 and hard reset for SSP (type 1) , only for RECOVERY */ 1367 1259 static int mvs_debug_I_T_nexus_reset(struct domain_device *dev) ··· 1344 1452 /* mandatory SAM-3, still need free task/slot info */ 1345 1453 int mvs_abort_task(struct sas_task *task) 1346 1454 { 1347 - struct scsi_lun lun; 1348 - struct sas_tmf_task tmf_task; 1349 1455 struct domain_device *dev = task->dev; 1350 1456 struct mvs_device *mvi_dev = (struct mvs_device *)dev->lldd_dev; 1351 1457 struct mvs_info *mvi; ··· 1367 1477 spin_unlock_irqrestore(&task->task_state_lock, flags); 1368 1478 mvi_dev->dev_status = MVS_DEV_EH; 1369 1479 if (task->lldd_task && task->task_proto & SAS_PROTOCOL_SSP) { 1370 - struct scsi_cmnd * cmnd = (struct scsi_cmnd *)task->uldd_task; 1371 - 1372 - int_to_scsilun(cmnd->device->lun, &lun); 1373 1480 rc = mvs_find_tag(mvi, task, &tag); 1374 1481 if (rc == 0) { 1375 1482 mv_printk("No such tag in %s\n", __func__); ··· 1374 1487 return rc; 1375 1488 } 1376 1489 1377 - tmf_task.tmf = TMF_ABORT_TASK; 1378 - tmf_task.tag_of_task_to_be_managed = cpu_to_le16(tag); 1379 - 1380 - rc = mvs_debug_issue_ssp_tmf(dev, lun.scsi_lun, &tmf_task); 1490 + rc = sas_abort_task(task, tag); 1381 1491 1382 1492 /* if successful, clear the task and callback forwards.*/ 1383 1493 if (rc == TMF_RESP_FUNC_COMPLETE) {
+1 -116
drivers/scsi/pm8001/pm8001_sas.c
··· 706 706 } 707 707 708 708 #define PM8001_TASK_TIMEOUT 20 709 - /** 710 - * pm8001_exec_internal_tmf_task - execute some task management commands. 711 - * @dev: the wanted device. 712 - * @tmf: which task management wanted to be take. 713 - * @para_len: para_len. 714 - * @parameter: ssp task parameter. 715 - * 716 - * when errors or exception happened, we may want to do something, for example 717 - * abort the issued task which result in this exception, it is done by calling 718 - * this function, note it is also with the task execute interface. 719 - */ 720 - static int pm8001_exec_internal_tmf_task(struct domain_device *dev, 721 - void *parameter, u32 para_len, struct sas_tmf_task *tmf) 722 - { 723 - int res, retry; 724 - struct sas_task *task = NULL; 725 - struct pm8001_hba_info *pm8001_ha = pm8001_find_ha_by_dev(dev); 726 - struct pm8001_device *pm8001_dev = dev->lldd_dev; 727 - DECLARE_COMPLETION_ONSTACK(completion_setstate); 728 - 729 - for (retry = 0; retry < 3; retry++) { 730 - task = sas_alloc_slow_task(GFP_KERNEL); 731 - if (!task) 732 - return -ENOMEM; 733 - 734 - task->dev = dev; 735 - task->task_proto = dev->tproto; 736 - memcpy(&task->ssp_task, parameter, para_len); 737 - task->task_done = pm8001_task_done; 738 - task->slow_task->timer.function = pm8001_tmf_timedout; 739 - task->slow_task->timer.expires = jiffies + PM8001_TASK_TIMEOUT*HZ; 740 - add_timer(&task->slow_task->timer); 741 - 742 - task->tmf = tmf; 743 - 744 - res = pm8001_queue_command(task, GFP_KERNEL); 745 - 746 - if (res) { 747 - del_timer(&task->slow_task->timer); 748 - pm8001_dbg(pm8001_ha, FAIL, "Executing internal task failed\n"); 749 - goto ex_err; 750 - } 751 - wait_for_completion(&task->slow_task->completion); 752 - if (pm8001_ha->chip_id != chip_8001) { 753 - pm8001_dev->setds_completion = &completion_setstate; 754 - PM8001_CHIP_DISP->set_dev_state_req(pm8001_ha, 755 - pm8001_dev, DS_OPERATIONAL); 756 - wait_for_completion(&completion_setstate); 757 - } 758 - res = -TMF_RESP_FUNC_FAILED; 759 - /* Even TMF timed out, return direct. */ 760 - if (task->task_state_flags & SAS_TASK_STATE_ABORTED) { 761 - struct pm8001_ccb_info *ccb = task->lldd_task; 762 - 763 - pm8001_dbg(pm8001_ha, FAIL, "TMF task[%x]timeout.\n", 764 - tmf->tmf); 765 - 766 - if (ccb) 767 - ccb->task = NULL; 768 - goto ex_err; 769 - } 770 - 771 - if (task->task_status.resp == SAS_TASK_COMPLETE && 772 - task->task_status.stat == SAS_SAM_STAT_GOOD) { 773 - res = TMF_RESP_FUNC_COMPLETE; 774 - break; 775 - } 776 - 777 - if (task->task_status.resp == SAS_TASK_COMPLETE && 778 - task->task_status.stat == SAS_DATA_UNDERRUN) { 779 - /* no error, but return the number of bytes of 780 - * underrun */ 781 - res = task->task_status.residual; 782 - break; 783 - } 784 - 785 - if (task->task_status.resp == SAS_TASK_COMPLETE && 786 - task->task_status.stat == SAS_DATA_OVERRUN) { 787 - pm8001_dbg(pm8001_ha, FAIL, "Blocked task error.\n"); 788 - res = -EMSGSIZE; 789 - break; 790 - } else { 791 - pm8001_dbg(pm8001_ha, EH, 792 - " Task to dev %016llx response:0x%x status 0x%x\n", 793 - SAS_ADDR(dev->sas_addr), 794 - task->task_status.resp, 795 - task->task_status.stat); 796 - sas_free_task(task); 797 - task = NULL; 798 - } 799 - } 800 - ex_err: 801 - BUG_ON(retry == 3 && task != NULL); 802 - sas_free_task(task); 803 - return res; 804 - } 805 - 806 709 static int 807 710 pm8001_exec_internal_task_abort(struct pm8001_hba_info *pm8001_ha, 808 711 struct pm8001_device *pm8001_dev, struct domain_device *dev, u32 flag, ··· 811 908 void pm8001_dev_gone(struct domain_device *dev) 812 909 { 813 910 pm8001_dev_gone_notify(dev); 814 - } 815 - 816 - static int pm8001_issue_ssp_tmf(struct domain_device *dev, 817 - u8 *lun, struct sas_tmf_task *tmf) 818 - { 819 - struct sas_ssp_task ssp_task; 820 - if (!(dev->tproto & SAS_PROTOCOL_SSP)) 821 - return TMF_RESP_FUNC_ESUPP; 822 - 823 - memcpy((u8 *)&ssp_task.LUN, lun, 8); 824 - return pm8001_exec_internal_tmf_task(dev, &ssp_task, sizeof(ssp_task), 825 - tmf); 826 911 } 827 912 828 913 /* retry commands by ha, by task and/or by device */ ··· 1072 1181 u32 tag; 1073 1182 struct domain_device *dev ; 1074 1183 struct pm8001_hba_info *pm8001_ha; 1075 - struct scsi_lun lun; 1076 1184 struct pm8001_device *pm8001_dev; 1077 - struct sas_tmf_task tmf_task; 1078 1185 int rc = TMF_RESP_FUNC_FAILED, ret; 1079 1186 u32 phy_id, port_id; 1080 1187 struct sas_task_slow slow_task; ··· 1108 1219 } 1109 1220 spin_unlock_irqrestore(&task->task_state_lock, flags); 1110 1221 if (task->task_proto & SAS_PROTOCOL_SSP) { 1111 - struct scsi_cmnd *cmnd = task->uldd_task; 1112 - int_to_scsilun(cmnd->device->lun, &lun); 1113 - tmf_task.tmf = TMF_ABORT_TASK; 1114 - tmf_task.tag_of_task_to_be_managed = tag; 1115 - rc = pm8001_issue_ssp_tmf(dev, lun.scsi_lun, &tmf_task); 1222 + rc = sas_abort_task(task, tag); 1116 1223 pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev, 1117 1224 pm8001_dev->sas_device, 0, tag); 1118 1225 } else if (task->task_proto & SAS_PROTOCOL_SATA ||
+1
include/scsi/libsas.h
··· 726 726 int sas_clear_task_set(struct domain_device *dev, u8 *lun); 727 727 int sas_lu_reset(struct domain_device *dev, u8 *lun); 728 728 int sas_query_task(struct sas_task *task, u16 tag); 729 + int sas_abort_task(struct sas_task *task, u16 tag); 729 730 730 731 int sas_notify_port_event(struct asd_sas_phy *phy, enum port_event event, 731 732 gfp_t gfp_flags);