Commit 095478a6 authored by John Garry's avatar John Garry Committed by Martin K. Petersen

scsi: hisi_sas: Use libsas internal abort support

Use the common libsas internal abort functionality.

In addition, this driver has special handling for internal abort timeouts -
specifically whether to reset the controller in that instance, so extend
the API for that.

Timeout is now increased to 20 * Hz from 6 * Hz.

We also retry for failure now, but this should not make a difference.

Link: https://lore.kernel.org/r/1647001432-239276-5-git-send-email-john.garry@huawei.comTested-by: default avatarDamien Le Moal <damien.lemoal@opensource.wdc.com>
Acked-by: default avatarJack Wang <jinpu.wang@ionos.com>
Signed-off-by: default avatarJohn Garry <john.garry@huawei.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 2cbbf489
...@@ -133,11 +133,6 @@ struct hisi_sas_rst { ...@@ -133,11 +133,6 @@ struct hisi_sas_rst {
bool done; bool done;
}; };
struct hisi_sas_internal_abort {
unsigned int flag;
unsigned int tag;
};
#define HISI_SAS_RST_WORK_INIT(r, c) \ #define HISI_SAS_RST_WORK_INIT(r, c) \
{ .hisi_hba = hisi_hba, \ { .hisi_hba = hisi_hba, \
.completion = &c, \ .completion = &c, \
...@@ -325,8 +320,7 @@ struct hisi_sas_hw { ...@@ -325,8 +320,7 @@ struct hisi_sas_hw {
void (*prep_stp)(struct hisi_hba *hisi_hba, void (*prep_stp)(struct hisi_hba *hisi_hba,
struct hisi_sas_slot *slot); struct hisi_sas_slot *slot);
void (*prep_abort)(struct hisi_hba *hisi_hba, void (*prep_abort)(struct hisi_hba *hisi_hba,
struct hisi_sas_slot *slot, struct hisi_sas_slot *slot);
int device_id, int abort_flag, int tag_to_abort);
void (*phys_init)(struct hisi_hba *hisi_hba); void (*phys_init)(struct hisi_hba *hisi_hba);
void (*phy_start)(struct hisi_hba *hisi_hba, int phy_no); void (*phy_start)(struct hisi_hba *hisi_hba, int phy_no);
void (*phy_disable)(struct hisi_hba *hisi_hba, int phy_no); void (*phy_disable)(struct hisi_hba *hisi_hba, int phy_no);
......
This diff is collapsed.
...@@ -2603,14 +2603,15 @@ static void hisi_sas_internal_abort_quirk_timeout(struct timer_list *t) ...@@ -2603,14 +2603,15 @@ static void hisi_sas_internal_abort_quirk_timeout(struct timer_list *t)
} }
static void prep_abort_v2_hw(struct hisi_hba *hisi_hba, static void prep_abort_v2_hw(struct hisi_hba *hisi_hba,
struct hisi_sas_slot *slot, struct hisi_sas_slot *slot)
int device_id, int abort_flag, int tag_to_abort)
{ {
struct sas_task *task = slot->task; struct sas_task *task = slot->task;
struct sas_internal_abort_task *abort = &task->abort_task;
struct domain_device *dev = task->dev; struct domain_device *dev = task->dev;
struct hisi_sas_cmd_hdr *hdr = slot->cmd_hdr; struct hisi_sas_cmd_hdr *hdr = slot->cmd_hdr;
struct hisi_sas_port *port = slot->port; struct hisi_sas_port *port = slot->port;
struct timer_list *timer = &slot->internal_abort_timer; struct timer_list *timer = &slot->internal_abort_timer;
struct hisi_sas_device *sas_dev = dev->lldd_dev;
/* setup the quirk timer */ /* setup the quirk timer */
timer_setup(timer, hisi_sas_internal_abort_quirk_timeout, 0); timer_setup(timer, hisi_sas_internal_abort_quirk_timeout, 0);
...@@ -2622,13 +2623,13 @@ static void prep_abort_v2_hw(struct hisi_hba *hisi_hba, ...@@ -2622,13 +2623,13 @@ static void prep_abort_v2_hw(struct hisi_hba *hisi_hba,
(port->id << CMD_HDR_PORT_OFF) | (port->id << CMD_HDR_PORT_OFF) |
(dev_is_sata(dev) << (dev_is_sata(dev) <<
CMD_HDR_ABORT_DEVICE_TYPE_OFF) | CMD_HDR_ABORT_DEVICE_TYPE_OFF) |
(abort_flag << CMD_HDR_ABORT_FLAG_OFF)); (abort->type << CMD_HDR_ABORT_FLAG_OFF));
/* dw1 */ /* dw1 */
hdr->dw1 = cpu_to_le32(device_id << CMD_HDR_DEV_ID_OFF); hdr->dw1 = cpu_to_le32(sas_dev->device_id << CMD_HDR_DEV_ID_OFF);
/* dw7 */ /* dw7 */
hdr->dw7 = cpu_to_le32(tag_to_abort << CMD_HDR_ABORT_IPTT_OFF); hdr->dw7 = cpu_to_le32(abort->tag << CMD_HDR_ABORT_IPTT_OFF);
hdr->transfer_tags = cpu_to_le32(slot->idx); hdr->transfer_tags = cpu_to_le32(slot->idx);
} }
......
...@@ -1452,28 +1452,28 @@ static void prep_ata_v3_hw(struct hisi_hba *hisi_hba, ...@@ -1452,28 +1452,28 @@ static void prep_ata_v3_hw(struct hisi_hba *hisi_hba,
} }
static void prep_abort_v3_hw(struct hisi_hba *hisi_hba, static void prep_abort_v3_hw(struct hisi_hba *hisi_hba,
struct hisi_sas_slot *slot, struct hisi_sas_slot *slot)
int device_id, int abort_flag, int tag_to_abort)
{ {
struct sas_task *task = slot->task; struct sas_task *task = slot->task;
struct sas_internal_abort_task *abort = &task->abort_task;
struct domain_device *dev = task->dev; struct domain_device *dev = task->dev;
struct hisi_sas_cmd_hdr *hdr = slot->cmd_hdr; struct hisi_sas_cmd_hdr *hdr = slot->cmd_hdr;
struct hisi_sas_port *port = slot->port; struct hisi_sas_port *port = slot->port;
struct hisi_sas_device *sas_dev = dev->lldd_dev;
bool sata = dev_is_sata(dev);
/* dw0 */ /* dw0 */
hdr->dw0 = cpu_to_le32((5U << CMD_HDR_CMD_OFF) | /*abort*/ hdr->dw0 = cpu_to_le32((5U << CMD_HDR_CMD_OFF) | /* abort */
(port->id << CMD_HDR_PORT_OFF) | (port->id << CMD_HDR_PORT_OFF) |
(dev_is_sata(dev) (sata << CMD_HDR_ABORT_DEVICE_TYPE_OFF) |
<< CMD_HDR_ABORT_DEVICE_TYPE_OFF) | (abort->type << CMD_HDR_ABORT_FLAG_OFF));
(abort_flag
<< CMD_HDR_ABORT_FLAG_OFF));
/* dw1 */ /* dw1 */
hdr->dw1 = cpu_to_le32(device_id hdr->dw1 = cpu_to_le32(sas_dev->device_id
<< CMD_HDR_DEV_ID_OFF); << CMD_HDR_DEV_ID_OFF);
/* dw7 */ /* dw7 */
hdr->dw7 = cpu_to_le32(tag_to_abort << CMD_HDR_ABORT_IPTT_OFF); hdr->dw7 = cpu_to_le32(abort->tag << CMD_HDR_ABORT_IPTT_OFF);
hdr->transfer_tags = cpu_to_le32(slot->idx); hdr->transfer_tags = cpu_to_le32(slot->idx);
} }
......
...@@ -943,6 +943,7 @@ static int sas_execute_internal_abort(struct domain_device *device, ...@@ -943,6 +943,7 @@ static int sas_execute_internal_abort(struct domain_device *device,
task->abort_task.tag = tag; task->abort_task.tag = tag;
task->abort_task.type = type; task->abort_task.type = type;
task->abort_task.qid = qid;
res = i->dft->lldd_execute_task(task, GFP_KERNEL); res = i->dft->lldd_execute_task(task, GFP_KERNEL);
if (res) { if (res) {
...@@ -957,10 +958,16 @@ static int sas_execute_internal_abort(struct domain_device *device, ...@@ -957,10 +958,16 @@ static int sas_execute_internal_abort(struct domain_device *device,
/* Even if the internal abort timed out, return direct. */ /* Even if the internal abort timed out, return direct. */
if (task->task_state_flags & SAS_TASK_STATE_ABORTED) { if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {
pr_err("Internal abort: timeout %016llx\n", bool quit = true;
SAS_ADDR(device->sas_addr));
if (i->dft->lldd_abort_timeout)
quit = i->dft->lldd_abort_timeout(task, data);
else
pr_err("Internal abort: timeout %016llx\n",
SAS_ADDR(device->sas_addr));
res = -EIO; res = -EIO;
break; if (quit)
break;
} }
if (task->task_status.resp == SAS_TASK_COMPLETE && if (task->task_status.resp == SAS_TASK_COMPLETE &&
......
...@@ -565,6 +565,7 @@ enum sas_internal_abort { ...@@ -565,6 +565,7 @@ enum sas_internal_abort {
struct sas_internal_abort_task { struct sas_internal_abort_task {
enum sas_internal_abort type; enum sas_internal_abort type;
unsigned int qid;
u16 tag; u16 tag;
}; };
...@@ -671,6 +672,7 @@ struct sas_domain_function_template { ...@@ -671,6 +672,7 @@ struct sas_domain_function_template {
/* Special TMF callbacks */ /* Special TMF callbacks */
void (*lldd_tmf_exec_complete)(struct domain_device *dev); void (*lldd_tmf_exec_complete)(struct domain_device *dev);
void (*lldd_tmf_aborted)(struct sas_task *task); void (*lldd_tmf_aborted)(struct sas_task *task);
bool (*lldd_abort_timeout)(struct sas_task *task, void *data);
/* Port and Adapter management */ /* Port and Adapter management */
int (*lldd_clear_nexus_port)(struct asd_sas_port *); int (*lldd_clear_nexus_port)(struct asd_sas_port *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment