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

scsi: pm8001: Use libsas internal abort support

New special handling is added for SAS_PROTOCOL_INTERNAL_ABORT proto so that
we may use the common queue command API.

Link: https://lore.kernel.org/r/1647001432-239276-4-git-send-email-john.garry@huawei.com
Tested-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Acked-by: Jack Wang <jinpu.wang@ionos.com>
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
2cbbf489 6a91c3e3

+74 -147
+17 -10
drivers/scsi/pm8001/pm8001_hwi.c
··· 4477 4477 } 4478 4478 4479 4479 static int send_task_abort(struct pm8001_hba_info *pm8001_ha, u32 opc, 4480 - u32 dev_id, u8 flag, u32 task_tag, u32 cmd_tag) 4480 + u32 dev_id, enum sas_internal_abort type, u32 task_tag, u32 cmd_tag) 4481 4481 { 4482 4482 struct task_abort_req task_abort; 4483 4483 4484 4484 memset(&task_abort, 0, sizeof(task_abort)); 4485 - if (ABORT_SINGLE == (flag & ABORT_MASK)) { 4485 + if (type == SAS_INTERNAL_ABORT_SINGLE) { 4486 4486 task_abort.abort_all = 0; 4487 4487 task_abort.device_id = cpu_to_le32(dev_id); 4488 4488 task_abort.tag_to_abort = cpu_to_le32(task_tag); 4489 - task_abort.tag = cpu_to_le32(cmd_tag); 4490 - } else if (ABORT_ALL == (flag & ABORT_MASK)) { 4489 + } else if (type == SAS_INTERNAL_ABORT_DEV) { 4491 4490 task_abort.abort_all = cpu_to_le32(1); 4492 4491 task_abort.device_id = cpu_to_le32(dev_id); 4493 - task_abort.tag = cpu_to_le32(cmd_tag); 4492 + } else { 4493 + pm8001_dbg(pm8001_ha, EH, "unknown type (%d)\n", type); 4494 + return -EIO; 4494 4495 } 4496 + 4497 + task_abort.tag = cpu_to_le32(cmd_tag); 4495 4498 4496 4499 return pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &task_abort, 4497 4500 sizeof(task_abort), 0); ··· 4504 4501 * pm8001_chip_abort_task - SAS abort task when error or exception happened. 4505 4502 */ 4506 4503 int pm8001_chip_abort_task(struct pm8001_hba_info *pm8001_ha, 4507 - struct pm8001_device *pm8001_dev, u8 flag, u32 task_tag, u32 cmd_tag) 4504 + struct pm8001_ccb_info *ccb) 4508 4505 { 4509 - u32 opc, device_id; 4506 + struct sas_task *task = ccb->task; 4507 + struct sas_internal_abort_task *abort = &task->abort_task; 4508 + struct pm8001_device *pm8001_dev = ccb->device; 4510 4509 int rc = TMF_RESP_FUNC_FAILED; 4510 + u32 opc, device_id; 4511 + 4511 4512 pm8001_dbg(pm8001_ha, EH, "cmd_tag = %x, abort task tag = 0x%x\n", 4512 - cmd_tag, task_tag); 4513 + ccb->ccb_tag, abort->tag); 4513 4514 if (pm8001_dev->dev_type == SAS_END_DEVICE) 4514 4515 opc = OPC_INB_SSP_ABORT; 4515 4516 else if (pm8001_dev->dev_type == SAS_SATA_DEV) ··· 4521 4514 else 4522 4515 opc = OPC_INB_SMP_ABORT;/* SMP */ 4523 4516 device_id = pm8001_dev->device_id; 4524 - rc = send_task_abort(pm8001_ha, opc, device_id, flag, 4525 - task_tag, cmd_tag); 4517 + rc = send_task_abort(pm8001_ha, opc, device_id, abort->type, 4518 + abort->tag, ccb->ccb_tag); 4526 4519 if (rc != TMF_RESP_FUNC_COMPLETE) 4527 4520 pm8001_dbg(pm8001_ha, EH, "rc= %d\n", rc); 4528 4521 return rc;
-5
drivers/scsi/pm8001/pm8001_hwi.h
··· 434 434 u32 reserved[11]; 435 435 } __attribute__((packed, aligned(4))); 436 436 437 - /* These flags used for SSP SMP & SATA Abort */ 438 - #define ABORT_MASK 0x3 439 - #define ABORT_SINGLE 0x0 440 - #define ABORT_ALL 0x1 441 - 442 437 /** 443 438 * brief the data structure of SSP SATA SMP Abort Response 444 439 * use to describe SSP SMP & SATA Abort Response ( 64 bytes)
+55 -123
drivers/scsi/pm8001/pm8001_sas.c
··· 325 325 } 326 326 327 327 /** 328 + * pm8001_task_prep_internal_abort - the dispatcher function, prepare data 329 + * for internal abort task 330 + * @pm8001_ha: our hba card information 331 + * @ccb: the ccb which attached to sata task 332 + */ 333 + static int pm8001_task_prep_internal_abort(struct pm8001_hba_info *pm8001_ha, 334 + struct pm8001_ccb_info *ccb) 335 + { 336 + return PM8001_CHIP_DISP->task_abort(pm8001_ha, ccb); 337 + } 338 + 339 + /** 328 340 * pm8001_task_prep_ssp_tm - the dispatcher function, prepare task management data 329 341 * @pm8001_ha: our hba card information 330 342 * @ccb: the ccb which attached to TM ··· 379 367 #define DEV_IS_GONE(pm8001_dev) \ 380 368 ((!pm8001_dev || (pm8001_dev->dev_type == SAS_PHY_UNUSED))) 381 369 370 + 371 + static int pm8001_deliver_command(struct pm8001_hba_info *pm8001_ha, 372 + struct pm8001_ccb_info *ccb) 373 + { 374 + struct sas_task *task = ccb->task; 375 + enum sas_protocol task_proto = task->task_proto; 376 + struct sas_tmf_task *tmf = task->tmf; 377 + int is_tmf = !!tmf; 378 + 379 + switch (task_proto) { 380 + case SAS_PROTOCOL_SMP: 381 + return pm8001_task_prep_smp(pm8001_ha, ccb); 382 + case SAS_PROTOCOL_SSP: 383 + if (is_tmf) 384 + return pm8001_task_prep_ssp_tm(pm8001_ha, ccb, tmf); 385 + return pm8001_task_prep_ssp(pm8001_ha, ccb); 386 + case SAS_PROTOCOL_SATA: 387 + case SAS_PROTOCOL_STP: 388 + return pm8001_task_prep_ata(pm8001_ha, ccb); 389 + case SAS_PROTOCOL_INTERNAL_ABORT: 390 + return pm8001_task_prep_internal_abort(pm8001_ha, ccb); 391 + default: 392 + dev_err(pm8001_ha->dev, "unknown sas_task proto: 0x%x\n", 393 + task_proto); 394 + } 395 + 396 + return -EINVAL; 397 + } 398 + 382 399 /** 383 400 * pm8001_queue_command - register for upper layer used, all IO commands sent 384 401 * to HBA are from this interface. ··· 420 379 enum sas_protocol task_proto = task->task_proto; 421 380 struct domain_device *dev = task->dev; 422 381 struct pm8001_device *pm8001_dev = dev->lldd_dev; 382 + bool internal_abort = sas_is_internal_abort(task); 423 383 struct pm8001_hba_info *pm8001_ha; 424 384 struct pm8001_port *port = NULL; 425 385 struct pm8001_ccb_info *ccb; 426 - struct sas_tmf_task *tmf = task->tmf; 427 - int is_tmf = !!task->tmf; 428 386 unsigned long flags; 429 387 u32 n_elem = 0; 430 388 int rc = 0; 431 389 432 - if (!dev->port) { 390 + if (!internal_abort && !dev->port) { 433 391 ts->resp = SAS_TASK_UNDELIVERED; 434 392 ts->stat = SAS_PHY_DOWN; 435 393 if (dev->dev_type != SAS_SATA_DEV) ··· 450 410 pm8001_dev = dev->lldd_dev; 451 411 port = &pm8001_ha->port[sas_find_local_port_id(dev)]; 452 412 453 - if (DEV_IS_GONE(pm8001_dev) || !port->port_attached) { 413 + if (!internal_abort && 414 + (DEV_IS_GONE(pm8001_dev) || !port->port_attached)) { 454 415 ts->resp = SAS_TASK_UNDELIVERED; 455 416 ts->stat = SAS_PHY_DOWN; 456 417 if (sas_protocol_ata(task_proto)) { ··· 489 448 490 449 atomic_inc(&pm8001_dev->running_req); 491 450 492 - switch (task_proto) { 493 - case SAS_PROTOCOL_SMP: 494 - rc = pm8001_task_prep_smp(pm8001_ha, ccb); 495 - break; 496 - case SAS_PROTOCOL_SSP: 497 - if (is_tmf) 498 - rc = pm8001_task_prep_ssp_tm(pm8001_ha, ccb, tmf); 499 - else 500 - rc = pm8001_task_prep_ssp(pm8001_ha, ccb); 501 - break; 502 - case SAS_PROTOCOL_SATA: 503 - case SAS_PROTOCOL_STP: 504 - rc = pm8001_task_prep_ata(pm8001_ha, ccb); 505 - break; 506 - default: 507 - dev_printk(KERN_ERR, pm8001_ha->dev, 508 - "unknown sas_task proto: 0x%x\n", task_proto); 509 - rc = -EINVAL; 510 - break; 511 - } 512 - 451 + rc = pm8001_deliver_command(pm8001_ha, ccb); 513 452 if (rc) { 514 453 atomic_dec(&pm8001_dev->running_req); 515 454 if (!sas_protocol_ata(task_proto) && n_elem) ··· 689 668 complete(&task->slow_task->completion); 690 669 } 691 670 692 - static void pm8001_tmf_timedout(struct timer_list *t) 693 - { 694 - struct sas_task_slow *slow = from_timer(slow, t, timer); 695 - struct sas_task *task = slow->task; 696 - unsigned long flags; 697 - 698 - spin_lock_irqsave(&task->task_state_lock, flags); 699 - if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { 700 - task->task_state_flags |= SAS_TASK_STATE_ABORTED; 701 - complete(&task->slow_task->completion); 702 - } 703 - spin_unlock_irqrestore(&task->task_state_lock, flags); 704 - } 705 - 706 671 #define PM8001_TASK_TIMEOUT 20 707 - static int 708 - pm8001_exec_internal_task_abort(struct pm8001_hba_info *pm8001_ha, 709 - struct pm8001_device *pm8001_dev, struct domain_device *dev, u32 flag, 710 - u32 task_tag) 711 - { 712 - int res, retry; 713 - struct pm8001_ccb_info *ccb; 714 - struct sas_task *task = NULL; 715 - 716 - for (retry = 0; retry < 3; retry++) { 717 - task = sas_alloc_slow_task(GFP_KERNEL); 718 - if (!task) 719 - return -ENOMEM; 720 - 721 - task->dev = dev; 722 - task->task_proto = dev->tproto; 723 - task->task_done = pm8001_task_done; 724 - task->slow_task->timer.function = pm8001_tmf_timedout; 725 - task->slow_task->timer.expires = 726 - jiffies + PM8001_TASK_TIMEOUT * HZ; 727 - add_timer(&task->slow_task->timer); 728 - 729 - ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_dev, task); 730 - if (!ccb) { 731 - res = -SAS_QUEUE_FULL; 732 - break; 733 - } 734 - 735 - res = PM8001_CHIP_DISP->task_abort(pm8001_ha, pm8001_dev, flag, 736 - task_tag, ccb->ccb_tag); 737 - if (res) { 738 - del_timer(&task->slow_task->timer); 739 - pm8001_dbg(pm8001_ha, FAIL, 740 - "Executing internal task failed\n"); 741 - pm8001_ccb_free(pm8001_ha, ccb); 742 - break; 743 - } 744 - 745 - wait_for_completion(&task->slow_task->completion); 746 - res = TMF_RESP_FUNC_FAILED; 747 - 748 - /* Even TMF timed out, return direct. */ 749 - if (task->task_state_flags & SAS_TASK_STATE_ABORTED) { 750 - pm8001_dbg(pm8001_ha, FAIL, "TMF task timeout.\n"); 751 - break; 752 - } 753 - 754 - if (task->task_status.resp == SAS_TASK_COMPLETE && 755 - task->task_status.stat == SAS_SAM_STAT_GOOD) { 756 - res = TMF_RESP_FUNC_COMPLETE; 757 - break; 758 - } 759 - 760 - pm8001_dbg(pm8001_ha, EH, 761 - " Task to dev %016llx response: 0x%x status 0x%x\n", 762 - SAS_ADDR(dev->sas_addr), 763 - task->task_status.resp, 764 - task->task_status.stat); 765 - sas_free_task(task); 766 - task = NULL; 767 - } 768 - 769 - BUG_ON(retry == 3 && task != NULL); 770 - sas_free_task(task); 771 - return res; 772 - } 773 672 774 673 /** 775 674 * pm8001_dev_gone_notify - see the comments for "pm8001_dev_found_notify" ··· 710 769 pm8001_dev->device_id, pm8001_dev->dev_type); 711 770 if (atomic_read(&pm8001_dev->running_req)) { 712 771 spin_unlock_irqrestore(&pm8001_ha->lock, flags); 713 - pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev, 714 - dev, 1, 0); 772 + sas_execute_internal_abort_dev(dev, 0, NULL); 715 773 while (atomic_read(&pm8001_dev->running_req)) 716 774 msleep(20); 717 775 spin_lock_irqsave(&pm8001_ha->lock, flags); ··· 833 893 goto out; 834 894 } 835 895 msleep(2000); 836 - rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev, 837 - dev, 1, 0); 896 + rc = sas_execute_internal_abort_dev(dev, 0, NULL); 838 897 if (rc) { 839 898 pm8001_dbg(pm8001_ha, EH, "task abort failed %x\n" 840 899 "with rc %d\n", pm8001_dev->device_id, rc); ··· 878 939 goto out; 879 940 } 880 941 /* send internal ssp/sata/smp abort command to FW */ 881 - rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev, 882 - dev, 1, 0); 942 + sas_execute_internal_abort_dev(dev, 0, NULL); 883 943 msleep(100); 884 944 885 945 /* deregister the target device */ ··· 893 955 wait_for_completion(&completion_setstate); 894 956 } else { 895 957 /* send internal ssp/sata/smp abort command to FW */ 896 - rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev, 897 - dev, 1, 0); 958 + sas_execute_internal_abort_dev(dev, 0, NULL); 898 959 msleep(100); 899 960 900 961 /* deregister the target device */ ··· 920 983 DECLARE_COMPLETION_ONSTACK(completion_setstate); 921 984 if (dev_is_sata(dev)) { 922 985 struct sas_phy *phy = sas_get_local_phy(dev); 923 - rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev, 924 - dev, 1, 0); 986 + sas_execute_internal_abort_dev(dev, 0, NULL); 925 987 rc = sas_phy_reset(phy, 1); 926 988 sas_put_local_phy(phy); 927 989 pm8001_dev->setds_completion = &completion_setstate; ··· 1020 1084 spin_unlock_irqrestore(&task->task_state_lock, flags); 1021 1085 if (task->task_proto & SAS_PROTOCOL_SSP) { 1022 1086 rc = sas_abort_task(task, tag); 1023 - pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev, 1024 - pm8001_dev->sas_device, 0, tag); 1087 + sas_execute_internal_abort_single(dev, tag, 0, NULL); 1025 1088 } else if (task->task_proto & SAS_PROTOCOL_SATA || 1026 1089 task->task_proto & SAS_PROTOCOL_STP) { 1027 1090 if (pm8001_ha->chip_id == chip_8006) { ··· 1093 1158 * is removed from the ccb. on success the caller is 1094 1159 * going to free the task. 1095 1160 */ 1096 - ret = pm8001_exec_internal_task_abort(pm8001_ha, 1097 - pm8001_dev, pm8001_dev->sas_device, 1, tag); 1161 + ret = sas_execute_internal_abort_dev(dev, 0, NULL); 1098 1162 if (ret) 1099 1163 goto out; 1100 1164 ret = wait_for_completion_timeout( ··· 1109 1175 pm8001_dev, DS_OPERATIONAL); 1110 1176 wait_for_completion(&completion); 1111 1177 } else { 1112 - rc = pm8001_exec_internal_task_abort(pm8001_ha, 1113 - pm8001_dev, pm8001_dev->sas_device, 0, tag); 1178 + ret = sas_execute_internal_abort_single(dev, tag, 0, NULL); 1114 1179 } 1115 1180 rc = TMF_RESP_FUNC_COMPLETE; 1116 1181 } else if (task->task_proto & SAS_PROTOCOL_SMP) { 1117 1182 /* SMP */ 1118 - rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev, 1119 - pm8001_dev->sas_device, 0, tag); 1183 + rc = sas_execute_internal_abort_single(dev, tag, 0, NULL); 1120 1184 1121 1185 } 1122 1186 out:
+2 -4
drivers/scsi/pm8001/pm8001_sas.h
··· 196 196 int (*phy_ctl_req)(struct pm8001_hba_info *pm8001_ha, 197 197 u32 phy_id, u32 phy_op); 198 198 int (*task_abort)(struct pm8001_hba_info *pm8001_ha, 199 - struct pm8001_device *pm8001_dev, u8 flag, u32 task_tag, 200 - u32 cmd_tag); 199 + struct pm8001_ccb_info *ccb); 201 200 int (*ssp_tm_req)(struct pm8001_hba_info *pm8001_ha, 202 201 struct pm8001_ccb_info *ccb, struct sas_tmf_task *tmf); 203 202 int (*get_nvmd_req)(struct pm8001_hba_info *pm8001_ha, void *payload); ··· 682 683 struct pm8001_ccb_info *ccb, 683 684 struct sas_tmf_task *tmf); 684 685 int pm8001_chip_abort_task(struct pm8001_hba_info *pm8001_ha, 685 - struct pm8001_device *pm8001_dev, 686 - u8 flag, u32 task_tag, u32 cmd_tag); 686 + struct pm8001_ccb_info *ccb); 687 687 int pm8001_chip_dereg_dev_req(struct pm8001_hba_info *pm8001_ha, u32 device_id); 688 688 void pm8001_chip_make_sg(struct scatterlist *scatter, int nr, void *prd); 689 689 void pm8001_work_fn(struct work_struct *work);
-5
drivers/scsi/pm8001/pm80xx_hwi.h
··· 672 672 u32 reserved[27]; 673 673 } __attribute__((packed, aligned(4))); 674 674 675 - /* These flags used for SSP SMP & SATA Abort */ 676 - #define ABORT_MASK 0x3 677 - #define ABORT_SINGLE 0x0 678 - #define ABORT_ALL 0x1 679 - 680 675 /** 681 676 * brief the data structure of SSP SATA SMP Abort Response 682 677 * use to describe SSP SMP & SATA Abort Response ( 64 bytes)