/*
 * Aic94xx SAS/SATA Tasks
 *
 * Copyright (C) 2005 Adaptec, Inc.  All rights reserved.
 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
 *
 * This file is licensed under GPLv2.
 *
 * This file is part of the aic94xx driver.
 *
 * The aic94xx driver is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; version 2 of the
 * License.
 *
 * The aic94xx driver is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with the aic94xx driver; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#include <linux/spinlock.h>
#include "aic94xx.h"
#include "aic94xx_sas.h"
#include "aic94xx_hwi.h"

static void asd_unbuild_ata_ascb(struct asd_ascb *a);
static void asd_unbuild_smp_ascb(struct asd_ascb *a);
static void asd_unbuild_ssp_ascb(struct asd_ascb *a);

static inline void asd_can_dequeue(struct asd_ha_struct *asd_ha, int num)
{
	unsigned long flags;

	spin_lock_irqsave(&asd_ha->seq.pend_q_lock, flags);
	asd_ha->seq.can_queue += num;
	spin_unlock_irqrestore(&asd_ha->seq.pend_q_lock, flags);
}

/* PCI_DMA_... to our direction translation.
 */
static const u8 data_dir_flags[] = {
	[PCI_DMA_BIDIRECTIONAL] = DATA_DIR_BYRECIPIENT,	/* UNSPECIFIED */
	[PCI_DMA_TODEVICE]      = DATA_DIR_OUT, /* OUTBOUND */
	[PCI_DMA_FROMDEVICE]    = DATA_DIR_IN, /* INBOUND */
	[PCI_DMA_NONE]          = DATA_DIR_NONE, /* NO TRANSFER */
};

static inline int asd_map_scatterlist(struct sas_task *task,
				      struct sg_el *sg_arr,
				      gfp_t gfp_flags)
{
	struct asd_ascb *ascb = task->lldd_task;
	struct asd_ha_struct *asd_ha = ascb->ha;
	struct scatterlist *sc;
	int num_sg, res;

	if (task->data_dir == PCI_DMA_NONE)
		return 0;

	if (task->num_scatter == 0) {
		void *p = task->scatter;
		dma_addr_t dma = pci_map_single(asd_ha->pcidev, p,
						task->total_xfer_len,
						task->data_dir);
		sg_arr[0].bus_addr = cpu_to_le64((u64)dma);
		sg_arr[0].size = cpu_to_le32(task->total_xfer_len);
		sg_arr[0].flags |= ASD_SG_EL_LIST_EOL;
		return 0;
	}

	num_sg = pci_map_sg(asd_ha->pcidev, task->scatter, task->num_scatter,
			    task->data_dir);
	if (num_sg == 0)
		return -ENOMEM;

	if (num_sg > 3) {
		int i;

		ascb->sg_arr = asd_alloc_coherent(asd_ha,
						  num_sg*sizeof(struct sg_el),
						  gfp_flags);
		if (!ascb->sg_arr) {
			res = -ENOMEM;
			goto err_unmap;
		}
		for (sc = task->scatter, i = 0; i < num_sg; i++, sc++) {
			struct sg_el *sg =
				&((struct sg_el *)ascb->sg_arr->vaddr)[i];
			sg->bus_addr = cpu_to_le64((u64)sg_dma_address(sc));
			sg->size = cpu_to_le32((u32)sg_dma_len(sc));
			if (i == num_sg-1)
				sg->flags |= ASD_SG_EL_LIST_EOL;
		}

		for (sc = task->scatter, i = 0; i < 2; i++, sc++) {
			sg_arr[i].bus_addr =
				cpu_to_le64((u64)sg_dma_address(sc));
			sg_arr[i].size = cpu_to_le32((u32)sg_dma_len(sc));
		}
		sg_arr[1].next_sg_offs = 2 * sizeof(*sg_arr);
		sg_arr[1].flags |= ASD_SG_EL_LIST_EOS;

		memset(&sg_arr[2], 0, sizeof(*sg_arr));
		sg_arr[2].bus_addr=cpu_to_le64((u64)ascb->sg_arr->dma_handle);
	} else {
		int i;
		for (sc = task->scatter, i = 0; i < num_sg; i++, sc++) {
			sg_arr[i].bus_addr =
				cpu_to_le64((u64)sg_dma_address(sc));
			sg_arr[i].size = cpu_to_le32((u32)sg_dma_len(sc));
		}
		sg_arr[i-1].flags |= ASD_SG_EL_LIST_EOL;
	}

	return 0;
err_unmap:
	pci_unmap_sg(asd_ha->pcidev, task->scatter, task->num_scatter,
		     task->data_dir);
	return res;
}

static inline void asd_unmap_scatterlist(struct asd_ascb *ascb)
{
	struct asd_ha_struct *asd_ha = ascb->ha;
	struct sas_task *task = ascb->uldd_task;

	if (task->data_dir == PCI_DMA_NONE)
		return;

	if (task->num_scatter == 0) {
		dma_addr_t dma = (dma_addr_t)
		       le64_to_cpu(ascb->scb->ssp_task.sg_element[0].bus_addr);
		pci_unmap_single(ascb->ha->pcidev, dma, task->total_xfer_len,
				 task->data_dir);
		return;
	}

	asd_free_coherent(asd_ha, ascb->sg_arr);
	pci_unmap_sg(asd_ha->pcidev, task->scatter, task->num_scatter,
		     task->data_dir);
}

/* ---------- Task complete tasklet ---------- */

static void asd_get_response_tasklet(struct asd_ascb *ascb,
				     struct done_list_struct *dl)
{
	struct asd_ha_struct *asd_ha = ascb->ha;
	struct sas_task *task = ascb->uldd_task;
	struct task_status_struct *ts = &task->task_status;
	unsigned long flags;
	struct tc_resp_sb_struct {
		__le16 index_escb;
		u8     len_lsb;
		u8     flags;
	} __attribute__ ((packed)) *resp_sb = (void *) dl->status_block;

/* 	int  size   = ((resp_sb->flags & 7) << 8) | resp_sb->len_lsb; */
	int  edb_id = ((resp_sb->flags & 0x70) >> 4)-1;
	struct asd_ascb *escb;
	struct asd_dma_tok *edb;
	void *r;

	spin_lock_irqsave(&asd_ha->seq.tc_index_lock, flags);
	escb = asd_tc_index_find(&asd_ha->seq,
				 (int)le16_to_cpu(resp_sb->index_escb));
	spin_unlock_irqrestore(&asd_ha->seq.tc_index_lock, flags);

	if (!escb) {
		ASD_DPRINTK("Uh-oh! No escb for this dl?!\n");
		return;
	}

	ts->buf_valid_size = 0;
	edb = asd_ha->seq.edb_arr[edb_id + escb->edb_index];
	r = edb->vaddr;
	if (task->task_proto == SAS_PROTO_SSP) {
		struct ssp_response_iu *iu =
			r + 16 + sizeof(struct ssp_frame_hdr);

		ts->residual = le32_to_cpu(*(__le32 *)r);
		ts->resp = SAS_TASK_COMPLETE;
		if (iu->datapres == 0)
			ts->stat = iu->status;
		else if (iu->datapres == 1)
			ts->stat = iu->resp_data[3];
		else if (iu->datapres == 2) {
			ts->stat = SAM_CHECK_COND;
			ts->buf_valid_size = min((u32) SAS_STATUS_BUF_SIZE,
					 be32_to_cpu(iu->sense_data_len));
			memcpy(ts->buf, iu->sense_data, ts->buf_valid_size);
			if (iu->status != SAM_CHECK_COND) {
				ASD_DPRINTK("device %llx sent sense data, but "
					    "stat(0x%x) is not CHECK_CONDITION"
					    "\n",
					    SAS_ADDR(task->dev->sas_addr),
					    ts->stat);
			}
		}
	}  else {
		struct ata_task_resp *resp = (void *) &ts->buf[0];

		ts->residual = le32_to_cpu(*(__le32 *)r);

		if (SAS_STATUS_BUF_SIZE >= sizeof(*resp)) {
			resp->frame_len = le16_to_cpu(*(__le16 *)(r+6));
			memcpy(&resp->ending_fis[0], r+16, 24);
			ts->buf_valid_size = sizeof(*resp);
		}
	}

	asd_invalidate_edb(escb, edb_id);
}

static void asd_task_tasklet_complete(struct asd_ascb *ascb,
				      struct done_list_struct *dl)
{
	struct sas_task *task = ascb->uldd_task;
	struct task_status_struct *ts = &task->task_status;
	unsigned long flags;
	u8 opcode = dl->opcode;

	asd_can_dequeue(ascb->ha, 1);

Again:
	switch (opcode) {
	case TC_NO_ERROR:
		ts->resp = SAS_TASK_COMPLETE;
		ts->stat = SAM_GOOD;
		break;
	case TC_UNDERRUN:
		ts->resp = SAS_TASK_COMPLETE;
		ts->stat = SAS_DATA_UNDERRUN;
		ts->residual = le32_to_cpu(*(__le32 *)dl->status_block);
		break;
	case TC_OVERRUN:
		ts->resp = SAS_TASK_COMPLETE;
		ts->stat = SAS_DATA_OVERRUN;
		ts->residual = 0;
		break;
	case TC_SSP_RESP:
	case TC_ATA_RESP:
		ts->resp = SAS_TASK_COMPLETE;
		ts->stat = SAS_PROTO_RESPONSE;
		asd_get_response_tasklet(ascb, dl);
		break;
	case TF_OPEN_REJECT:
		ts->resp = SAS_TASK_UNDELIVERED;
		ts->stat = SAS_OPEN_REJECT;
		if (dl->status_block[1] & 2)
			ts->open_rej_reason = 1 + dl->status_block[2];
		else if (dl->status_block[1] & 1)
			ts->open_rej_reason = (dl->status_block[2] >> 4)+10;
		else
			ts->open_rej_reason = SAS_OREJ_UNKNOWN;
		break;
	case TF_OPEN_TO:
		ts->resp = SAS_TASK_UNDELIVERED;
		ts->stat = SAS_OPEN_TO;
		break;
	case TF_PHY_DOWN:
	case TU_PHY_DOWN:
		ts->resp = SAS_TASK_UNDELIVERED;
		ts->stat = SAS_PHY_DOWN;
		break;
	case TI_PHY_DOWN:
		ts->resp = SAS_TASK_COMPLETE;
		ts->stat = SAS_PHY_DOWN;
		break;
	case TI_BREAK:
	case TI_PROTO_ERR:
	case TI_NAK:
	case TI_ACK_NAK_TO:
	case TF_SMP_XMIT_RCV_ERR:
	case TC_ATA_R_ERR_RECV:
		ts->resp = SAS_TASK_COMPLETE;
		ts->stat = SAS_INTERRUPTED;
		break;
	case TF_BREAK:
	case TU_BREAK:
	case TU_ACK_NAK_TO:
	case TF_SMPRSP_TO:
		ts->resp = SAS_TASK_UNDELIVERED;
		ts->stat = SAS_DEV_NO_RESPONSE;
		break;
	case TF_NAK_RECV:
		ts->resp = SAS_TASK_COMPLETE;
		ts->stat = SAS_NAK_R_ERR;
		break;
	case TA_I_T_NEXUS_LOSS:
		opcode = dl->status_block[0];
		goto Again;
		break;
	case TF_INV_CONN_HANDLE:
		ts->resp = SAS_TASK_UNDELIVERED;
		ts->stat = SAS_DEVICE_UNKNOWN;
		break;
	case TF_REQUESTED_N_PENDING:
		ts->resp = SAS_TASK_UNDELIVERED;
		ts->stat = SAS_PENDING;
		break;
	case TC_TASK_CLEARED:
	case TA_ON_REQ:
		ts->resp = SAS_TASK_COMPLETE;
		ts->stat = SAS_ABORTED_TASK;
		break;

	case TF_NO_SMP_CONN:
	case TF_TMF_NO_CTX:
	case TF_TMF_NO_TAG:
	case TF_TMF_TAG_FREE:
	case TF_TMF_TASK_DONE:
	case TF_TMF_NO_CONN_HANDLE:
	case TF_IRTT_TO:
	case TF_IU_SHORT:
	case TF_DATA_OFFS_ERR:
		ts->resp = SAS_TASK_UNDELIVERED;
		ts->stat = SAS_DEV_NO_RESPONSE;
		break;

	case TC_LINK_ADM_RESP:
	case TC_CONTROL_PHY:
	case TC_RESUME:
	case TC_PARTIAL_SG_LIST:
	default:
		ASD_DPRINTK("%s: dl opcode: 0x%x?\n", __FUNCTION__, opcode);
		break;
	}

	switch (task->task_proto) {
	case SATA_PROTO:
	case SAS_PROTO_STP:
		asd_unbuild_ata_ascb(ascb);
		break;
	case SAS_PROTO_SMP:
		asd_unbuild_smp_ascb(ascb);
		break;
	case SAS_PROTO_SSP:
		asd_unbuild_ssp_ascb(ascb);
	default:
		break;
	}

	spin_lock_irqsave(&task->task_state_lock, flags);
	task->task_state_flags &= ~SAS_TASK_STATE_PENDING;
	task->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
	task->task_state_flags |= SAS_TASK_STATE_DONE;
	if (unlikely((task->task_state_flags & SAS_TASK_STATE_ABORTED))) {
		spin_unlock_irqrestore(&task->task_state_lock, flags);
		ASD_DPRINTK("task 0x%p done with opcode 0x%x resp 0x%x "
			    "stat 0x%x but aborted by upper layer!\n",
			    task, opcode, ts->resp, ts->stat);
		complete(&ascb->completion);
	} else {
		spin_unlock_irqrestore(&task->task_state_lock, flags);
		task->lldd_task = NULL;
		asd_ascb_free(ascb);
		mb();
		task->task_done(task);
	}
}

/* ---------- ATA ---------- */

static int asd_build_ata_ascb(struct asd_ascb *ascb, struct sas_task *task,
			      gfp_t gfp_flags)
{
	struct domain_device *dev = task->dev;
	struct scb *scb;
	u8     flags;
	int    res = 0;

	scb = ascb->scb;

	if (unlikely(task->ata_task.device_control_reg_update))
		scb->header.opcode = CONTROL_ATA_DEV;
	else if (dev->sata_dev.command_set == ATA_COMMAND_SET)
		scb->header.opcode = INITIATE_ATA_TASK;
	else
		scb->header.opcode = INITIATE_ATAPI_TASK;

	scb->ata_task.proto_conn_rate = (1 << 5); /* STP */
	if (dev->port->oob_mode == SAS_OOB_MODE)
		scb->ata_task.proto_conn_rate |= dev->linkrate;

	scb->ata_task.total_xfer_len = cpu_to_le32(task->total_xfer_len);
	scb->ata_task.fis = task->ata_task.fis;
	scb->ata_task.fis.fis_type = 0x27;
	if (likely(!task->ata_task.device_control_reg_update))
		scb->ata_task.fis.flags |= 0x80; /* C=1: update ATA cmd reg */
	scb->ata_task.fis.flags &= 0xF0; /* PM_PORT field shall be 0 */
	if (dev->sata_dev.command_set == ATAPI_COMMAND_SET)
		memcpy(scb->ata_task.atapi_packet, task->ata_task.atapi_packet,
		       16);
	scb->ata_task.sister_scb = cpu_to_le16(0xFFFF);
	scb->ata_task.conn_handle = cpu_to_le16(
		(u16)(unsigned long)dev->lldd_dev);

	if (likely(!task->ata_task.device_control_reg_update)) {
		flags = 0;
		if (task->ata_task.dma_xfer)
			flags |= DATA_XFER_MODE_DMA;
		if (task->ata_task.use_ncq &&
		    dev->sata_dev.command_set != ATAPI_COMMAND_SET)
			flags |= ATA_Q_TYPE_NCQ;
		flags |= data_dir_flags[task->data_dir];
		scb->ata_task.ata_flags = flags;

		scb->ata_task.retry_count = task->ata_task.retry_count;

		flags = 0;
		if (task->ata_task.set_affil_pol)
			flags |= SET_AFFIL_POLICY;
		if (task->ata_task.stp_affil_pol)
			flags |= STP_AFFIL_POLICY;
		scb->ata_task.flags = flags;
	}
	ascb->tasklet_complete = asd_task_tasklet_complete;

	if (likely(!task->ata_task.device_control_reg_update))
		res = asd_map_scatterlist(task, scb->ata_task.sg_element,
					  gfp_flags);

	return res;
}

static void asd_unbuild_ata_ascb(struct asd_ascb *a)
{
	asd_unmap_scatterlist(a);
}

/* ---------- SMP ---------- */

static int asd_build_smp_ascb(struct asd_ascb *ascb, struct sas_task *task,
			      gfp_t gfp_flags)
{
	struct asd_ha_struct *asd_ha = ascb->ha;
	struct domain_device *dev = task->dev;
	struct scb *scb;

	pci_map_sg(asd_ha->pcidev, &task->smp_task.smp_req, 1,
		   PCI_DMA_FROMDEVICE);
	pci_map_sg(asd_ha->pcidev, &task->smp_task.smp_resp, 1,
		   PCI_DMA_FROMDEVICE);

	scb = ascb->scb;

	scb->header.opcode = INITIATE_SMP_TASK;

	scb->smp_task.proto_conn_rate = dev->linkrate;

	scb->smp_task.smp_req.bus_addr =
		cpu_to_le64((u64)sg_dma_address(&task->smp_task.smp_req));
	scb->smp_task.smp_req.size =
		cpu_to_le32((u32)sg_dma_len(&task->smp_task.smp_req)-4);

	scb->smp_task.smp_resp.bus_addr =
		cpu_to_le64((u64)sg_dma_address(&task->smp_task.smp_resp));
	scb->smp_task.smp_resp.size =
		cpu_to_le32((u32)sg_dma_len(&task->smp_task.smp_resp)-4);

	scb->smp_task.sister_scb = cpu_to_le16(0xFFFF);
	scb->smp_task.conn_handle = cpu_to_le16((u16)
						(unsigned long)dev->lldd_dev);

	ascb->tasklet_complete = asd_task_tasklet_complete;

	return 0;
}

static void asd_unbuild_smp_ascb(struct asd_ascb *a)
{
	struct sas_task *task = a->uldd_task;

	BUG_ON(!task);
	pci_unmap_sg(a->ha->pcidev, &task->smp_task.smp_req, 1,
		     PCI_DMA_FROMDEVICE);
	pci_unmap_sg(a->ha->pcidev, &task->smp_task.smp_resp, 1,
		     PCI_DMA_FROMDEVICE);
}

/* ---------- SSP ---------- */

static int asd_build_ssp_ascb(struct asd_ascb *ascb, struct sas_task *task,
			      gfp_t gfp_flags)
{
	struct domain_device *dev = task->dev;
	struct scb *scb;
	int    res = 0;

	scb = ascb->scb;

	scb->header.opcode = INITIATE_SSP_TASK;

	scb->ssp_task.proto_conn_rate  = (1 << 4); /* SSP */
	scb->ssp_task.proto_conn_rate |= dev->linkrate;
	scb->ssp_task.total_xfer_len = cpu_to_le32(task->total_xfer_len);
	scb->ssp_task.ssp_frame.frame_type = SSP_DATA;
	memcpy(scb->ssp_task.ssp_frame.hashed_dest_addr, dev->hashed_sas_addr,
	       HASHED_SAS_ADDR_SIZE);
	memcpy(scb->ssp_task.ssp_frame.hashed_src_addr,
	       dev->port->ha->hashed_sas_addr, HASHED_SAS_ADDR_SIZE);
	scb->ssp_task.ssp_frame.tptt = cpu_to_be16(0xFFFF);

	memcpy(scb->ssp_task.ssp_cmd.lun, task->ssp_task.LUN, 8);
	if (task->ssp_task.enable_first_burst)
		scb->ssp_task.ssp_cmd.efb_prio_attr |= EFB_MASK;
	scb->ssp_task.ssp_cmd.efb_prio_attr |= (task->ssp_task.task_prio << 3);
	scb->ssp_task.ssp_cmd.efb_prio_attr |= (task->ssp_task.task_attr & 7);
	memcpy(scb->ssp_task.ssp_cmd.cdb, task->ssp_task.cdb, 16);

	scb->ssp_task.sister_scb = cpu_to_le16(0xFFFF);
	scb->ssp_task.conn_handle = cpu_to_le16(
		(u16)(unsigned long)dev->lldd_dev);
	scb->ssp_task.data_dir = data_dir_flags[task->data_dir];
	scb->ssp_task.retry_count = scb->ssp_task.retry_count;

	ascb->tasklet_complete = asd_task_tasklet_complete;

	res = asd_map_scatterlist(task, scb->ssp_task.sg_element, gfp_flags);

	return res;
}

static void asd_unbuild_ssp_ascb(struct asd_ascb *a)
{
	asd_unmap_scatterlist(a);
}

/* ---------- Execute Task ---------- */

static inline int asd_can_queue(struct asd_ha_struct *asd_ha, int num)
{
	int res = 0;
	unsigned long flags;

	spin_lock_irqsave(&asd_ha->seq.pend_q_lock, flags);
	if ((asd_ha->seq.can_queue - num) < 0)
		res = -SAS_QUEUE_FULL;
	else
		asd_ha->seq.can_queue -= num;
	spin_unlock_irqrestore(&asd_ha->seq.pend_q_lock, flags);

	return res;
}

int asd_execute_task(struct sas_task *task, const int num,
		     gfp_t gfp_flags)
{
	int res = 0;
	LIST_HEAD(alist);
	struct sas_task *t = task;
	struct asd_ascb *ascb = NULL, *a;
	struct asd_ha_struct *asd_ha = task->dev->port->ha->lldd_ha;
	unsigned long flags;

	res = asd_can_queue(asd_ha, num);
	if (res)
		return res;

	res = num;
	ascb = asd_ascb_alloc_list(asd_ha, &res, gfp_flags);
	if (res) {
		res = -ENOMEM;
		goto out_err;
	}

	__list_add(&alist, ascb->list.prev, &ascb->list);
	list_for_each_entry(a, &alist, list) {
		a->uldd_task = t;
		t->lldd_task = a;
		t = list_entry(t->list.next, struct sas_task, list);
	}
	list_for_each_entry(a, &alist, list) {
		t = a->uldd_task;
		a->uldd_timer = 1;
		if (t->task_proto & SAS_PROTO_STP)
			t->task_proto = SAS_PROTO_STP;
		switch (t->task_proto) {
		case SATA_PROTO:
		case SAS_PROTO_STP:
			res = asd_build_ata_ascb(a, t, gfp_flags);
			break;
		case SAS_PROTO_SMP:
			res = asd_build_smp_ascb(a, t, gfp_flags);
			break;
		case SAS_PROTO_SSP:
			res = asd_build_ssp_ascb(a, t, gfp_flags);
			break;
		default:
			asd_printk("unknown sas_task proto: 0x%x\n",
				   t->task_proto);
			res = -ENOMEM;
			break;
		}
		if (res)
			goto out_err_unmap;

		spin_lock_irqsave(&t->task_state_lock, flags);
		t->task_state_flags |= SAS_TASK_AT_INITIATOR;
		spin_unlock_irqrestore(&t->task_state_lock, flags);
	}
	list_del_init(&alist);

	res = asd_post_ascb_list(asd_ha, ascb, num);
	if (unlikely(res)) {
		a = NULL;
		__list_add(&alist, ascb->list.prev, &ascb->list);
		goto out_err_unmap;
	}

	return 0;
out_err_unmap:
	{
		struct asd_ascb *b = a;
		list_for_each_entry(a, &alist, list) {
			if (a == b)
				break;
			t = a->uldd_task;
			spin_lock_irqsave(&t->task_state_lock, flags);
			t->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
			spin_unlock_irqrestore(&t->task_state_lock, flags);
			switch (t->task_proto) {
			case SATA_PROTO:
			case SAS_PROTO_STP:
				asd_unbuild_ata_ascb(a);
				break;
			case SAS_PROTO_SMP:
				asd_unbuild_smp_ascb(a);
				break;
			case SAS_PROTO_SSP:
				asd_unbuild_ssp_ascb(a);
			default:
				break;
			}
			t->lldd_task = NULL;
		}
	}
	list_del_init(&alist);
out_err:
	if (ascb)
		asd_ascb_free_list(ascb);
	asd_can_dequeue(asd_ha, num);
	return res;
}
