Skip to content

Commit 2cbbf48

Browse files
John Garrymartinkpetersen
John Garry
authored andcommitted
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/[email protected] Tested-by: Damien Le Moal <[email protected]> Acked-by: Jack Wang <[email protected]> Signed-off-by: John Garry <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 6a91c3e commit 2cbbf48

File tree

5 files changed

+74
-147
lines changed

5 files changed

+74
-147
lines changed

drivers/scsi/pm8001/pm8001_hwi.c

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4477,22 +4477,25 @@ pm8001_chip_isr(struct pm8001_hba_info *pm8001_ha, u8 vec)
44774477
}
44784478

44794479
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)
44814481
{
44824482
struct task_abort_req task_abort;
44834483

44844484
memset(&task_abort, 0, sizeof(task_abort));
4485-
if (ABORT_SINGLE == (flag & ABORT_MASK)) {
4485+
if (type == SAS_INTERNAL_ABORT_SINGLE) {
44864486
task_abort.abort_all = 0;
44874487
task_abort.device_id = cpu_to_le32(dev_id);
44884488
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) {
44914490
task_abort.abort_all = cpu_to_le32(1);
44924491
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;
44944495
}
44954496

4497+
task_abort.tag = cpu_to_le32(cmd_tag);
4498+
44964499
return pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &task_abort,
44974500
sizeof(task_abort), 0);
44984501
}
@@ -4501,21 +4504,25 @@ static int send_task_abort(struct pm8001_hba_info *pm8001_ha, u32 opc,
45014504
* pm8001_chip_abort_task - SAS abort task when error or exception happened.
45024505
*/
45034506
int pm8001_chip_abort_task(struct pm8001_hba_info *pm8001_ha,
4504-
struct pm8001_device *pm8001_dev, u8 flag, u32 task_tag, u32 cmd_tag)
4507+
struct pm8001_ccb_info *ccb)
45054508
{
4506-
u32 opc, device_id;
4509+
struct sas_task *task = ccb->task;
4510+
struct sas_internal_abort_task *abort = &task->abort_task;
4511+
struct pm8001_device *pm8001_dev = ccb->device;
45074512
int rc = TMF_RESP_FUNC_FAILED;
4513+
u32 opc, device_id;
4514+
45084515
pm8001_dbg(pm8001_ha, EH, "cmd_tag = %x, abort task tag = 0x%x\n",
4509-
cmd_tag, task_tag);
4516+
ccb->ccb_tag, abort->tag);
45104517
if (pm8001_dev->dev_type == SAS_END_DEVICE)
45114518
opc = OPC_INB_SSP_ABORT;
45124519
else if (pm8001_dev->dev_type == SAS_SATA_DEV)
45134520
opc = OPC_INB_SATA_ABORT;
45144521
else
45154522
opc = OPC_INB_SMP_ABORT;/* SMP */
45164523
device_id = pm8001_dev->device_id;
4517-
rc = send_task_abort(pm8001_ha, opc, device_id, flag,
4518-
task_tag, cmd_tag);
4524+
rc = send_task_abort(pm8001_ha, opc, device_id, abort->type,
4525+
abort->tag, ccb->ccb_tag);
45194526
if (rc != TMF_RESP_FUNC_COMPLETE)
45204527
pm8001_dbg(pm8001_ha, EH, "rc= %d\n", rc);
45214528
return rc;

drivers/scsi/pm8001/pm8001_hwi.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -434,11 +434,6 @@ struct task_abort_req {
434434
u32 reserved[11];
435435
} __attribute__((packed, aligned(4)));
436436

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-
442437
/**
443438
* brief the data structure of SSP SATA SMP Abort Response
444439
* use to describe SSP SMP & SATA Abort Response ( 64 bytes)

drivers/scsi/pm8001/pm8001_sas.c

Lines changed: 55 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,18 @@ static int pm8001_task_prep_ata(struct pm8001_hba_info *pm8001_ha,
324324
return PM8001_CHIP_DISP->sata_req(pm8001_ha, ccb);
325325
}
326326

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+
327339
/**
328340
* pm8001_task_prep_ssp_tm - the dispatcher function, prepare task management data
329341
* @pm8001_ha: our hba card information
@@ -367,6 +379,35 @@ static int sas_find_local_port_id(struct domain_device *dev)
367379
#define DEV_IS_GONE(pm8001_dev) \
368380
((!pm8001_dev || (pm8001_dev->dev_type == SAS_PHY_UNUSED)))
369381

382+
383+
static int pm8001_deliver_command(struct pm8001_hba_info *pm8001_ha,
384+
struct pm8001_ccb_info *ccb)
385+
{
386+
struct sas_task *task = ccb->task;
387+
enum sas_protocol task_proto = task->task_proto;
388+
struct sas_tmf_task *tmf = task->tmf;
389+
int is_tmf = !!tmf;
390+
391+
switch (task_proto) {
392+
case SAS_PROTOCOL_SMP:
393+
return pm8001_task_prep_smp(pm8001_ha, ccb);
394+
case SAS_PROTOCOL_SSP:
395+
if (is_tmf)
396+
return pm8001_task_prep_ssp_tm(pm8001_ha, ccb, tmf);
397+
return pm8001_task_prep_ssp(pm8001_ha, ccb);
398+
case SAS_PROTOCOL_SATA:
399+
case SAS_PROTOCOL_STP:
400+
return pm8001_task_prep_ata(pm8001_ha, ccb);
401+
case SAS_PROTOCOL_INTERNAL_ABORT:
402+
return pm8001_task_prep_internal_abort(pm8001_ha, ccb);
403+
default:
404+
dev_err(pm8001_ha->dev, "unknown sas_task proto: 0x%x\n",
405+
task_proto);
406+
}
407+
408+
return -EINVAL;
409+
}
410+
370411
/**
371412
* pm8001_queue_command - register for upper layer used, all IO commands sent
372413
* to HBA are from this interface.
@@ -379,16 +420,15 @@ int pm8001_queue_command(struct sas_task *task, gfp_t gfp_flags)
379420
enum sas_protocol task_proto = task->task_proto;
380421
struct domain_device *dev = task->dev;
381422
struct pm8001_device *pm8001_dev = dev->lldd_dev;
423+
bool internal_abort = sas_is_internal_abort(task);
382424
struct pm8001_hba_info *pm8001_ha;
383425
struct pm8001_port *port = NULL;
384426
struct pm8001_ccb_info *ccb;
385-
struct sas_tmf_task *tmf = task->tmf;
386-
int is_tmf = !!task->tmf;
387427
unsigned long flags;
388428
u32 n_elem = 0;
389429
int rc = 0;
390430

391-
if (!dev->port) {
431+
if (!internal_abort && !dev->port) {
392432
ts->resp = SAS_TASK_UNDELIVERED;
393433
ts->stat = SAS_PHY_DOWN;
394434
if (dev->dev_type != SAS_SATA_DEV)
@@ -410,7 +450,8 @@ int pm8001_queue_command(struct sas_task *task, gfp_t gfp_flags)
410450
pm8001_dev = dev->lldd_dev;
411451
port = &pm8001_ha->port[sas_find_local_port_id(dev)];
412452

413-
if (DEV_IS_GONE(pm8001_dev) || !port->port_attached) {
453+
if (!internal_abort &&
454+
(DEV_IS_GONE(pm8001_dev) || !port->port_attached)) {
414455
ts->resp = SAS_TASK_UNDELIVERED;
415456
ts->stat = SAS_PHY_DOWN;
416457
if (sas_protocol_ata(task_proto)) {
@@ -448,27 +489,7 @@ int pm8001_queue_command(struct sas_task *task, gfp_t gfp_flags)
448489

449490
atomic_inc(&pm8001_dev->running_req);
450491

451-
switch (task_proto) {
452-
case SAS_PROTOCOL_SMP:
453-
rc = pm8001_task_prep_smp(pm8001_ha, ccb);
454-
break;
455-
case SAS_PROTOCOL_SSP:
456-
if (is_tmf)
457-
rc = pm8001_task_prep_ssp_tm(pm8001_ha, ccb, tmf);
458-
else
459-
rc = pm8001_task_prep_ssp(pm8001_ha, ccb);
460-
break;
461-
case SAS_PROTOCOL_SATA:
462-
case SAS_PROTOCOL_STP:
463-
rc = pm8001_task_prep_ata(pm8001_ha, ccb);
464-
break;
465-
default:
466-
dev_printk(KERN_ERR, pm8001_ha->dev,
467-
"unknown sas_task proto: 0x%x\n", task_proto);
468-
rc = -EINVAL;
469-
break;
470-
}
471-
492+
rc = pm8001_deliver_command(pm8001_ha, ccb);
472493
if (rc) {
473494
atomic_dec(&pm8001_dev->running_req);
474495
if (!sas_protocol_ata(task_proto) && n_elem)
@@ -668,87 +689,7 @@ void pm8001_task_done(struct sas_task *task)
668689
complete(&task->slow_task->completion);
669690
}
670691

671-
static void pm8001_tmf_timedout(struct timer_list *t)
672-
{
673-
struct sas_task_slow *slow = from_timer(slow, t, timer);
674-
struct sas_task *task = slow->task;
675-
unsigned long flags;
676-
677-
spin_lock_irqsave(&task->task_state_lock, flags);
678-
if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
679-
task->task_state_flags |= SAS_TASK_STATE_ABORTED;
680-
complete(&task->slow_task->completion);
681-
}
682-
spin_unlock_irqrestore(&task->task_state_lock, flags);
683-
}
684-
685692
#define PM8001_TASK_TIMEOUT 20
686-
static int
687-
pm8001_exec_internal_task_abort(struct pm8001_hba_info *pm8001_ha,
688-
struct pm8001_device *pm8001_dev, struct domain_device *dev, u32 flag,
689-
u32 task_tag)
690-
{
691-
int res, retry;
692-
struct pm8001_ccb_info *ccb;
693-
struct sas_task *task = NULL;
694-
695-
for (retry = 0; retry < 3; retry++) {
696-
task = sas_alloc_slow_task(GFP_KERNEL);
697-
if (!task)
698-
return -ENOMEM;
699-
700-
task->dev = dev;
701-
task->task_proto = dev->tproto;
702-
task->task_done = pm8001_task_done;
703-
task->slow_task->timer.function = pm8001_tmf_timedout;
704-
task->slow_task->timer.expires =
705-
jiffies + PM8001_TASK_TIMEOUT * HZ;
706-
add_timer(&task->slow_task->timer);
707-
708-
ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_dev, task);
709-
if (!ccb) {
710-
res = -SAS_QUEUE_FULL;
711-
break;
712-
}
713-
714-
res = PM8001_CHIP_DISP->task_abort(pm8001_ha, pm8001_dev, flag,
715-
task_tag, ccb->ccb_tag);
716-
if (res) {
717-
del_timer(&task->slow_task->timer);
718-
pm8001_dbg(pm8001_ha, FAIL,
719-
"Executing internal task failed\n");
720-
pm8001_ccb_free(pm8001_ha, ccb);
721-
break;
722-
}
723-
724-
wait_for_completion(&task->slow_task->completion);
725-
res = TMF_RESP_FUNC_FAILED;
726-
727-
/* Even TMF timed out, return direct. */
728-
if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {
729-
pm8001_dbg(pm8001_ha, FAIL, "TMF task timeout.\n");
730-
break;
731-
}
732-
733-
if (task->task_status.resp == SAS_TASK_COMPLETE &&
734-
task->task_status.stat == SAS_SAM_STAT_GOOD) {
735-
res = TMF_RESP_FUNC_COMPLETE;
736-
break;
737-
}
738-
739-
pm8001_dbg(pm8001_ha, EH,
740-
" Task to dev %016llx response: 0x%x status 0x%x\n",
741-
SAS_ADDR(dev->sas_addr),
742-
task->task_status.resp,
743-
task->task_status.stat);
744-
sas_free_task(task);
745-
task = NULL;
746-
}
747-
748-
BUG_ON(retry == 3 && task != NULL);
749-
sas_free_task(task);
750-
return res;
751-
}
752693

753694
/**
754695
* pm8001_dev_gone_notify - see the comments for "pm8001_dev_found_notify"
@@ -769,8 +710,7 @@ static void pm8001_dev_gone_notify(struct domain_device *dev)
769710
pm8001_dev->device_id, pm8001_dev->dev_type);
770711
if (atomic_read(&pm8001_dev->running_req)) {
771712
spin_unlock_irqrestore(&pm8001_ha->lock, flags);
772-
pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev,
773-
dev, 1, 0);
713+
sas_execute_internal_abort_dev(dev, 0, NULL);
774714
while (atomic_read(&pm8001_dev->running_req))
775715
msleep(20);
776716
spin_lock_irqsave(&pm8001_ha->lock, flags);
@@ -893,8 +833,7 @@ int pm8001_I_T_nexus_reset(struct domain_device *dev)
893833
goto out;
894834
}
895835
msleep(2000);
896-
rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev,
897-
dev, 1, 0);
836+
rc = sas_execute_internal_abort_dev(dev, 0, NULL);
898837
if (rc) {
899838
pm8001_dbg(pm8001_ha, EH, "task abort failed %x\n"
900839
"with rc %d\n", pm8001_dev->device_id, rc);
@@ -939,8 +878,7 @@ int pm8001_I_T_nexus_event_handler(struct domain_device *dev)
939878
goto out;
940879
}
941880
/* send internal ssp/sata/smp abort command to FW */
942-
rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev,
943-
dev, 1, 0);
881+
sas_execute_internal_abort_dev(dev, 0, NULL);
944882
msleep(100);
945883

946884
/* deregister the target device */
@@ -955,8 +893,7 @@ int pm8001_I_T_nexus_event_handler(struct domain_device *dev)
955893
wait_for_completion(&completion_setstate);
956894
} else {
957895
/* send internal ssp/sata/smp abort command to FW */
958-
rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev,
959-
dev, 1, 0);
896+
sas_execute_internal_abort_dev(dev, 0, NULL);
960897
msleep(100);
961898

962899
/* deregister the target device */
@@ -983,8 +920,7 @@ int pm8001_lu_reset(struct domain_device *dev, u8 *lun)
983920
DECLARE_COMPLETION_ONSTACK(completion_setstate);
984921
if (dev_is_sata(dev)) {
985922
struct sas_phy *phy = sas_get_local_phy(dev);
986-
rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev,
987-
dev, 1, 0);
923+
sas_execute_internal_abort_dev(dev, 0, NULL);
988924
rc = sas_phy_reset(phy, 1);
989925
sas_put_local_phy(phy);
990926
pm8001_dev->setds_completion = &completion_setstate;
@@ -1084,8 +1020,7 @@ int pm8001_abort_task(struct sas_task *task)
10841020
spin_unlock_irqrestore(&task->task_state_lock, flags);
10851021
if (task->task_proto & SAS_PROTOCOL_SSP) {
10861022
rc = sas_abort_task(task, tag);
1087-
pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev,
1088-
pm8001_dev->sas_device, 0, tag);
1023+
sas_execute_internal_abort_single(dev, tag, 0, NULL);
10891024
} else if (task->task_proto & SAS_PROTOCOL_SATA ||
10901025
task->task_proto & SAS_PROTOCOL_STP) {
10911026
if (pm8001_ha->chip_id == chip_8006) {
@@ -1158,8 +1093,7 @@ int pm8001_abort_task(struct sas_task *task)
11581093
* is removed from the ccb. on success the caller is
11591094
* going to free the task.
11601095
*/
1161-
ret = pm8001_exec_internal_task_abort(pm8001_ha,
1162-
pm8001_dev, pm8001_dev->sas_device, 1, tag);
1096+
ret = sas_execute_internal_abort_dev(dev, 0, NULL);
11631097
if (ret)
11641098
goto out;
11651099
ret = wait_for_completion_timeout(
@@ -1175,14 +1109,12 @@ int pm8001_abort_task(struct sas_task *task)
11751109
pm8001_dev, DS_OPERATIONAL);
11761110
wait_for_completion(&completion);
11771111
} else {
1178-
rc = pm8001_exec_internal_task_abort(pm8001_ha,
1179-
pm8001_dev, pm8001_dev->sas_device, 0, tag);
1112+
ret = sas_execute_internal_abort_single(dev, tag, 0, NULL);
11801113
}
11811114
rc = TMF_RESP_FUNC_COMPLETE;
11821115
} else if (task->task_proto & SAS_PROTOCOL_SMP) {
11831116
/* SMP */
1184-
rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev,
1185-
pm8001_dev->sas_device, 0, tag);
1117+
rc = sas_execute_internal_abort_single(dev, tag, 0, NULL);
11861118

11871119
}
11881120
out:

drivers/scsi/pm8001/pm8001_sas.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,7 @@ struct pm8001_dispatch {
196196
int (*phy_ctl_req)(struct pm8001_hba_info *pm8001_ha,
197197
u32 phy_id, u32 phy_op);
198198
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);
201200
int (*ssp_tm_req)(struct pm8001_hba_info *pm8001_ha,
202201
struct pm8001_ccb_info *ccb, struct sas_tmf_task *tmf);
203202
int (*get_nvmd_req)(struct pm8001_hba_info *pm8001_ha, void *payload);
@@ -683,8 +682,7 @@ int pm8001_chip_ssp_tm_req(struct pm8001_hba_info *pm8001_ha,
683682
struct pm8001_ccb_info *ccb,
684683
struct sas_tmf_task *tmf);
685684
int pm8001_chip_abort_task(struct pm8001_hba_info *pm8001_ha,
686-
struct pm8001_device *pm8001_dev,
687-
u8 flag, u32 task_tag, u32 cmd_tag);
685+
struct pm8001_ccb_info *ccb);
688686
int pm8001_chip_dereg_dev_req(struct pm8001_hba_info *pm8001_ha, u32 device_id);
689687
void pm8001_chip_make_sg(struct scatterlist *scatter, int nr, void *prd);
690688
void pm8001_work_fn(struct work_struct *work);

drivers/scsi/pm8001/pm80xx_hwi.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -672,11 +672,6 @@ struct task_abort_req {
672672
u32 reserved[27];
673673
} __attribute__((packed, aligned(4)));
674674

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-
680675
/**
681676
* brief the data structure of SSP SATA SMP Abort Response
682677
* use to describe SSP SMP & SATA Abort Response ( 64 bytes)

0 commit comments

Comments
 (0)