Re: [PATCH] 3/3: Handle REQ_TASK_ABORT in aic94xx

From: Luben Tuikov
Date: Tue Oct 31 2006 - 02:53:29 EST


--- "Darrick J. Wong" <djwong@xxxxxxxxxx> wrote:
> This patch straightens out the code that distinguishes the various escb
> opcodes in escb_tasklet_complete so that they can be handled correctly.
> It also provides all the necessary code to create a workqueue item that
> tells libsas to abort a sas_task.
>
> Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx>
>
> --
>
> diff --git a/drivers/scsi/aic94xx/aic94xx_scb.c b/drivers/scsi/aic94xx/aic94xx_scb.c
> index 7ee49b5..1911c5d 100644
> --- a/drivers/scsi/aic94xx/aic94xx_scb.c
> +++ b/drivers/scsi/aic94xx/aic94xx_scb.c
> @@ -25,6 +25,7 @@
> */
>
> #include <linux/pci.h>
> +#include <scsi/scsi_host.h>
>
> #include "aic94xx.h"
> #include "aic94xx_reg.h"
> @@ -342,6 +343,18 @@ void asd_invalidate_edb(struct asd_ascb
> }
> }
>
> +/* start up the ABORT TASK tmf... */
> +static void task_kill_later(struct asd_ascb *ascb)
> +{
> + struct asd_ha_struct *asd_ha = ascb->ha;
> + struct sas_ha_struct *sas_ha = &asd_ha->sas_ha;
> + struct Scsi_Host *shost = sas_ha->core.shost;
> + struct sas_task *task = ascb->uldd_task;
> +
> + INIT_WORK(&task->abort_work, (void (*)(void *))sas_task_abort, task);
> + queue_work(shost->work_q, &task->abort_work);
> +}
> +
> static void escb_tasklet_complete(struct asd_ascb *ascb,
> struct done_list_struct *dl)
> {
> @@ -368,6 +381,58 @@ static void escb_tasklet_complete(struct
> ascb->scb->header.opcode);
> }
>
> + /* Catch these before we mask off the sb_opcode bits */
> + switch (sb_opcode) {
> + case REQ_TASK_ABORT: {
> + struct asd_ascb *a, *b;
> + u16 tc_abort;
> +
> + tc_abort = *((u16*)(&dl->status_block[1]));
> + tc_abort = le16_to_cpu(tc_abort);
> +
> + ASD_DPRINTK("%s: REQ_TASK_ABORT, reason=0x%X\n",
> + __FUNCTION__, dl->status_block[3]);
> +
> + /* Find the pending task and abort it. */
> + list_for_each_entry_safe(a, b, &asd_ha->seq.pend_q, list)
> + if (a->tc_index == tc_abort) {
> + task_kill_later(a);
> + break;
> + }
> + goto out;
> + }
> + case REQ_DEVICE_RESET: {
> + struct asd_ascb *a, *b;
> + u16 conn_handle;
> +
> + conn_handle = *((u16*)(&dl->status_block[1]));
> + conn_handle = le16_to_cpu(conn_handle);
> +
> + ASD_DPRINTK("%s: REQ_DEVICE_RESET, reason=0x%X\n", __FUNCTION__,
> + dl->status_block[3]);
> +
> + /* Kill all pending tasks and reset the device */
> + list_for_each_entry_safe(a, b, &asd_ha->seq.pend_q, list) {
> + struct sas_task *task = a->uldd_task;
> + struct domain_device *dev = task->dev;
> + u16 x;
> +
> + x = *((u16*)(&dev->lldd_dev));
> + if (x == conn_handle)
> + task_kill_later(a);
> + }
> +
> + /* FIXME: Reset device port (huh?) */
> + goto out;

"huh?" -- LOL, that's a very funny comment.

Good luck!
Luben

> + }
> + case SIGNAL_NCQ_ERROR:
> + ASD_DPRINTK("%s: SIGNAL_NCQ_ERROR\n", __FUNCTION__);
> + goto out;
> + case CLEAR_NCQ_ERROR:
> + ASD_DPRINTK("%s: CLEAR_NCQ_ERROR\n", __FUNCTION__);
> + goto out;
> + }
> +
> sb_opcode &= ~DL_PHY_MASK;
>
> switch (sb_opcode) {
> @@ -397,22 +462,6 @@ static void escb_tasklet_complete(struct
> sas_phy_disconnected(sas_phy);
> sas_ha->notify_port_event(sas_phy, PORTE_TIMER_EVENT);
> break;
> - case REQ_TASK_ABORT:
> - ASD_DPRINTK("%s: phy%d: REQ_TASK_ABORT\n", __FUNCTION__,
> - phy_id);
> - break;
> - case REQ_DEVICE_RESET:
> - ASD_DPRINTK("%s: phy%d: REQ_DEVICE_RESET\n", __FUNCTION__,
> - phy_id);
> - break;
> - case SIGNAL_NCQ_ERROR:
> - ASD_DPRINTK("%s: phy%d: SIGNAL_NCQ_ERROR\n", __FUNCTION__,
> - phy_id);
> - break;
> - case CLEAR_NCQ_ERROR:
> - ASD_DPRINTK("%s: phy%d: CLEAR_NCQ_ERROR\n", __FUNCTION__,
> - phy_id);
> - break;
> default:
> ASD_DPRINTK("%s: phy%d: unknown event:0x%x\n", __FUNCTION__,
> phy_id, sb_opcode);
> @@ -432,7 +481,7 @@ static void escb_tasklet_complete(struct
>
> break;
> }
> -
> +out:
> asd_invalidate_edb(ascb, edb);
> }
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/