提交 095478a6 编写于 作者: J John Garry 提交者: 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: NDamien Le Moal <damien.lemoal@opensource.wdc.com>
Acked-by: NJack Wang <jinpu.wang@ionos.com>
Signed-off-by: NJohn Garry <john.garry@huawei.com>
Signed-off-by: NMartin K. Petersen <martin.petersen@oracle.com>
上级 2cbbf489
......@@ -133,11 +133,6 @@ struct hisi_sas_rst {
bool done;
};
struct hisi_sas_internal_abort {
unsigned int flag;
unsigned int tag;
};
#define HISI_SAS_RST_WORK_INIT(r, c) \
{ .hisi_hba = hisi_hba, \
.completion = &c, \
......@@ -325,8 +320,7 @@ struct hisi_sas_hw {
void (*prep_stp)(struct hisi_hba *hisi_hba,
struct hisi_sas_slot *slot);
void (*prep_abort)(struct hisi_hba *hisi_hba,
struct hisi_sas_slot *slot,
int device_id, int abort_flag, int tag_to_abort);
struct hisi_sas_slot *slot);
void (*phys_init)(struct hisi_hba *hisi_hba);
void (*phy_start)(struct hisi_hba *hisi_hba, int phy_no);
void (*phy_disable)(struct hisi_hba *hisi_hba, int phy_no);
......
......@@ -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,
struct hisi_sas_slot *slot,
int device_id, int abort_flag, int tag_to_abort)
struct hisi_sas_slot *slot)
{
struct sas_task *task = slot->task;
struct sas_internal_abort_task *abort = &task->abort_task;
struct domain_device *dev = task->dev;
struct hisi_sas_cmd_hdr *hdr = slot->cmd_hdr;
struct hisi_sas_port *port = slot->port;
struct timer_list *timer = &slot->internal_abort_timer;
struct hisi_sas_device *sas_dev = dev->lldd_dev;
/* setup the quirk timer */
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,
(port->id << CMD_HDR_PORT_OFF) |
(dev_is_sata(dev) <<
CMD_HDR_ABORT_DEVICE_TYPE_OFF) |
(abort_flag << CMD_HDR_ABORT_FLAG_OFF));
(abort->type << CMD_HDR_ABORT_FLAG_OFF));
/* 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 */
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);
}
......
......@@ -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,
struct hisi_sas_slot *slot,
int device_id, int abort_flag, int tag_to_abort)
struct hisi_sas_slot *slot)
{
struct sas_task *task = slot->task;
struct sas_internal_abort_task *abort = &task->abort_task;
struct domain_device *dev = task->dev;
struct hisi_sas_cmd_hdr *hdr = slot->cmd_hdr;
struct hisi_sas_port *port = slot->port;
struct hisi_sas_device *sas_dev = dev->lldd_dev;
bool sata = dev_is_sata(dev);
/* 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) |
(dev_is_sata(dev)
<< CMD_HDR_ABORT_DEVICE_TYPE_OFF) |
(abort_flag
<< CMD_HDR_ABORT_FLAG_OFF));
(sata << CMD_HDR_ABORT_DEVICE_TYPE_OFF) |
(abort->type << CMD_HDR_ABORT_FLAG_OFF));
/* dw1 */
hdr->dw1 = cpu_to_le32(device_id
hdr->dw1 = cpu_to_le32(sas_dev->device_id
<< CMD_HDR_DEV_ID_OFF);
/* 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);
}
......
......@@ -943,6 +943,7 @@ static int sas_execute_internal_abort(struct domain_device *device,
task->abort_task.tag = tag;
task->abort_task.type = type;
task->abort_task.qid = qid;
res = i->dft->lldd_execute_task(task, GFP_KERNEL);
if (res) {
......@@ -957,10 +958,16 @@ static int sas_execute_internal_abort(struct domain_device *device,
/* Even if the internal abort timed out, return direct. */
if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {
pr_err("Internal abort: timeout %016llx\n",
SAS_ADDR(device->sas_addr));
bool quit = true;
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;
break;
if (quit)
break;
}
if (task->task_status.resp == SAS_TASK_COMPLETE &&
......
......@@ -565,6 +565,7 @@ enum sas_internal_abort {
struct sas_internal_abort_task {
enum sas_internal_abort type;
unsigned int qid;
u16 tag;
};
......@@ -671,6 +672,7 @@ struct sas_domain_function_template {
/* Special TMF callbacks */
void (*lldd_tmf_exec_complete)(struct domain_device *dev);
void (*lldd_tmf_aborted)(struct sas_task *task);
bool (*lldd_abort_timeout)(struct sas_task *task, void *data);
/* Port and Adapter management */
int (*lldd_clear_nexus_port)(struct asd_sas_port *);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册