Re: [PATCH 2/2] qla2xxx: FC pass through support - revised II

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 29 Oct 2008 05:48:08 -0700
Seokmann Ju <seokmann.ju@xxxxxxxxxx> wrote:

>  From 08df89c581e47b9745aa93029948011a7c4d31b0 Mon Sep 17 00:00:00 2001
> From: root <root@xxxxxxxxxxxxxxxxxxxxxxx>
> Date: Tue, 28 Oct 2008 19:29:30 -0700
> Subject: [PATCH] qla2xxx: FC pass through support
> 
> This patch will add FC passs through support.
> With this patch, the driver support,
> - ELS (Extended Link Services)
> - FC-CT (Generic Services)
> 
> Signed-off-by: Seokmann Ju <seokmann.ju@xxxxxxxxxx>
> ---
>   drivers/scsi/qla2xxx/qla_attr.c |  231 ++++++++++++++++++++++++++++++ 
> +++++++++
>   drivers/scsi/qla2xxx/qla_def.h  |    5 +
>   drivers/scsi/qla2xxx/qla_fw.h   |   35 ++++++
>   drivers/scsi/qla2xxx/qla_gbl.h  |    4 +
>   drivers/scsi/qla2xxx/qla_gs.c   |    2 +-
>   drivers/scsi/qla2xxx/qla_init.c |   11 ++
>   drivers/scsi/qla2xxx/qla_iocb.c |    9 +-
>   drivers/scsi/qla2xxx/qla_isr.c  |   68 ++++++++++++
>   8 files changed, 358 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/ 
> qla_attr.c
> index b223842..357ee3c 100644
> --- a/drivers/scsi/qla2xxx/qla_attr.c
> +++ b/drivers/scsi/qla2xxx/qla_attr.c
> @@ -1257,6 +1257,231 @@ qla24xx_vport_disable(struct fc_vport  
> *fc_vport, bool disable)
>   	return 0;
>   }
> 
> +static int
> +qla2x00_execute_fc_service(struct fc_service *service)
> +{
> +	struct fc_rport *rport = service->rport;
> +	fc_port_t *fcport = *(fc_port_t **) rport->dd_data;
> +	struct Scsi_Host *host = rport_to_shost(rport);
> +	scsi_qla_host_t *vha = shost_priv(host);
> +	struct qla_hw_data *ha = vha->hw;
> +	struct req_que *req = ha->req;
> +	struct els_entry_24xx *els_iocb;
> +	struct ct_entry_24xx *ct_iocb;
> +	request_t *iocb;
> +	srb_t *sp;
> +	unsigned long flags;
> +	uint32_t  handle;
> +	int  index, sg_cnt;
> +	uint8_t  *els_pkt = service->payload;
> +	uint16_t avail_dsds;
> +	uint32_t *cur_dsd;
> +
> +	if (rport->port_state != FC_PORTSTATE_ONLINE || !fcport)
> +		goto pt_error0;
> +
> +	if ((service->srv_request->request_type != FC_FRAME_TYPE_ELS) &&
> +	    (service->srv_request->request_type != FC_FRAME_TYPE_FC_CT))
> +		goto pt_error0;
> +
> +	/* ELS doesn't support multiple SG */
> +	if ((service->srv_request->request_type == FC_FRAME_TYPE_ELS) &&
> +	    (service->payload_sg_cnt > 1 || service->response_sg_cnt > 1)) {
> +		printk(KERN_WARNING "ERROR: multiple SG of payload/response "
> +		    "[%u/%u]  are not supported for ELS services\n",
> +		    service->payload_sg_cnt, service->response_sg_cnt);
> +		service->srv_reply.status = FC_SERVICE_UNSUPPORTED;
> +		goto pt_error0;
> +	}
> +
> +	sp = mempool_alloc(ha->srb_mempool, GFP_ATOMIC);
> +	if (!sp)
> +		goto pt_error0;
> +
> +	sp->vha = vha;
> +	sp->fcport = fcport;
> +	sp->cmd = (struct scsi_cmnd *)service;
> +	sp->flags = SRB_ELS_CT;
> +
> +	spin_lock_irqsave(&ha->hardware_lock, flags);
> +	iocb = qla2x00_req_pkt(vha);
> +	if (iocb == NULL) {
> +		qla_printk(KERN_WARNING, ha,
> +		    "Passthru request failed to get request packet\n");
> +		goto pt_error1;
> +	}
> +
> +	/* Check for room in outstanding command list. */
> +	handle = req->current_outstanding_cmd;
> +	for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) {
> +		handle++;
> +		if (handle == MAX_OUTSTANDING_COMMANDS)
> +			handle = 1;
> +		if (!req->outstanding_cmds[handle])
> +			break;
> +	}
> +
> +	req->current_outstanding_cmd = handle;
> +	req->outstanding_cmds[handle] = (srb_t *) sp;
> +
> +	iocb->handle = handle;
> +
> +	service->payload_sg_cnt = dma_map_sg(&rport->dev,
> +	    service->payload_dma, service->payload_sg_cnt, DMA_TO_DEVICE);
> +	service->response_sg_cnt = dma_map_sg(&rport->dev,
> +	    service->response_dma, service->response_sg_cnt, DMA_FROM_DEVICE);

Please check the return values, service->payload_sg_cnt and
service->response_sg_cnt. dma_map_sg could fail.


> +	if (service->srv_request->request_type == FC_FRAME_TYPE_ELS) {
> +		els_iocb = (struct els_entry_24xx *)iocb;
> +		els_iocb->entry_type = ELS_IOCB_TYPE;
> +		els_iocb->entry_count = 1;
> +		els_iocb->sys_define = 0;
> +		els_iocb->entry_status = 0;
> +		els_iocb->nport_handle = cpu_to_le16(fcport->loop_id);
> +		els_iocb->tx_dsd_count = __constant_cpu_to_le16(1);
> +		els_iocb->vp_index = vha->vp_idx;
> +		els_iocb->sof_type = EST_SOFI3;
> +		els_iocb->rx_dsd_count = __constant_cpu_to_le16(1);
> +		els_iocb->opcode = els_pkt[0];
> +		els_iocb->port_id[0] = fcport->d_id.b.al_pa;
> +		els_iocb->port_id[1] = fcport->d_id.b.area;
> +		els_iocb->port_id[2] = fcport->d_id.b.domain;
> +		els_iocb->control_flags = 0;
> +		els_iocb->rx_byte_count = cpu_to_le32(service->response_size);
> +		els_iocb->tx_byte_count = cpu_to_le32(service->payload_size);
> +		els_iocb->tx_address[0] = cpu_to_le32(LSD(sg_dma_address
> +		    (&service->payload_dma[0])));
> +		els_iocb->tx_address[1] = cpu_to_le32(MSD(sg_dma_address
> +		    (&service->payload_dma[0])));
> +
> +		els_iocb->tx_len = cpu_to_le32(sg_dma_len
> +		    (&service->payload_dma[0]));
> +
> +		els_iocb->rx_address[0] = cpu_to_le32(LSD(sg_dma_address
> +		    (&service->response_dma[0])));
> +		els_iocb->rx_address[1] = cpu_to_le32(MSD(sg_dma_address
> +		    (&service->response_dma[0])));
> +
> +		els_iocb->rx_len = cpu_to_le32(sg_dma_len
> +		    (&service->response_dma[0]));
> +	
> +		/* lld_pkt is only for ELS services in case of abort */
> +		service->lld_pkt = (void *) els_iocb;
> +	} else {
> +		ct_iocb = (struct ct_entry_24xx *)iocb;
> +		ct_iocb->entry_type = CT_IOCB_TYPE;
> +		ct_iocb->entry_count = 1;
> +		ct_iocb->entry_status = 0;
> +		ct_iocb->comp_status = __constant_cpu_to_le16(0);
> +		if (IS_FWI2_CAPABLE(ha))
> +			ct_iocb->nport_handle = cpu_to_le16(NPH_SNS);
> +		else
> +			ct_iocb->nport_handle =
> +			    cpu_to_le16(SIMPLE_NAME_SERVER);
> +		ct_iocb->cmd_dsd_count =
> +		    __constant_cpu_to_le16(service->payload_sg_cnt);
> +		ct_iocb->vp_index = vha->vp_idx;
> +		ct_iocb->timeout =
> +		    __constant_cpu_to_le16(service->timeout);
> +		ct_iocb->rsp_dsd_count =
> +		    __constant_cpu_to_le16(service->response_sg_cnt);
> +		ct_iocb->rsp_byte_count =
> +		    cpu_to_le32(service->response_size);
> +		ct_iocb->cmd_byte_count =
> +		    cpu_to_le32(service->payload_size);
> +		ct_iocb->dseg_0_address[0] = cpu_to_le32(LSD(sg_dma_address
> +		    (&service->payload_dma[0])));
> +		ct_iocb->dseg_0_address[1] = cpu_to_le32(MSD(sg_dma_address
> +		    (&service->payload_dma[0])));
> +
> +		ct_iocb->dseg_0_len = cpu_to_le32(sg_dma_len
> +		    (&service->payload_dma[0]));
> +
> +		sg_cnt = service->response_sg_cnt;
> +		avail_dsds = 1;
> +		cur_dsd = (uint32_t *)ct_iocb->dseg_1_address;
> +		index = 0;
> +		while (sg_cnt) {
> +			cont_a64_entry_t *cont_pkt;
> +
> +			/* Allocate additional continuation packets? */
> +			if (avail_dsds == 0) {
> +				/*
> +				 * Five DSDs are available in the Continuation
> +				 * Type 1 IOCB.
> +				 */
> +				cont_pkt = qla2x00_prep_cont_type1_iocb(vha);
> +				cur_dsd =
> +				    (uint32_t *) cont_pkt->dseg_0_address;
> +				avail_dsds = 5;
> +			}
> +
> +			*cur_dsd++ = cpu_to_le32(LSD(sg_dma_address
> +			    (&service->response_dma[index])));
> +			*cur_dsd++ = cpu_to_le32(MSD(sg_dma_address
> +			    (&service->response_dma[index])));
> +			*cur_dsd++ = cpu_to_le32(sg_dma_len
> +			    (&service->response_dma[index]));
> +			avail_dsds--;
> +			sg_cnt--;
> +			index++;

Can you use the standard API, for_each_sg(), to go through scatter
list? With sg chaining, you must use the API.


> +		}
> +	}
> +
> +	wmb();
> +	qla2x00_isp_cmd(vha);
> +
> +	spin_unlock_irqrestore(&ha->hardware_lock, flags);
> +	return 0;
> +pt_error1:
> +	spin_unlock_irqrestore(&ha->hardware_lock, flags);
> +pt_error0:
> +	qla_printk(KERN_WARNING, ha, "Passthru ELS failed\n");
> +
> +	return -EINVAL;
> +}
> +
> +static int
> +qla2x00_abort_fc_service(struct fc_service *service)
> +{
> +	unsigned long flags;
> +	struct fc_rport *rport = service->rport;
> +	struct Scsi_Host *host = rport_to_shost(rport);
> +	scsi_qla_host_t *vha = shost_priv(host);
> +	struct qla_hw_data *ha = vha->hw;
> +	struct abort_entry_24xx *abort_iocb;
> +	struct els_entry_24xx *els_iocb = service->lld_pkt;
> +
> +	printk("ELS/CT: DEBUG: %s is called...\n", __func__);
> +	if (service->srv_request->request_type != FC_FRAME_TYPE_ELS) {
> +		printk(KERN_ERR "abort frame is not supported\n");
> +		return -EINVAL;
> +	}
> +
> +	spin_lock_irqsave(&ha->hardware_lock, flags);
> +	abort_iocb = (struct abort_entry_24xx *)qla2x00_req_pkt(vha);
> +
> +	abort_iocb->entry_type = ABORT_IOCB_TYPE;
> +	abort_iocb->entry_count = 1;
> +	abort_iocb->handle_count = 0;
> +	abort_iocb->entry_status = 0;
> +	abort_iocb->options = 0;
> +	abort_iocb->handle_to_abort = els_iocb->handle;
> +	abort_iocb->port_id[0] = els_iocb->port_id[0];
> +	abort_iocb->port_id[1] = els_iocb->port_id[1];
> +	abort_iocb->port_id[2] = els_iocb->port_id[2];
> +	abort_iocb->vp_index = vha->vp_idx;
> +
> +	wmb();
> +	qla2x00_isp_cmd(vha);
> +
> +	spin_unlock_irqrestore(&ha->hardware_lock, flags);
> +
> +	service->service_state_flag = FC_SERVICE_STATE_ABORTED;
> +
> +	return 0;
> +}
> +
>   struct fc_function_template qla2xxx_transport_functions = {
> 
>   	.show_host_node_name = 1,
> @@ -1300,6 +1525,9 @@ struct fc_function_template  
> qla2xxx_transport_functions = {
>   	.vport_create = qla24xx_vport_create,
>   	.vport_disable = qla24xx_vport_disable,
>   	.vport_delete = qla24xx_vport_delete,
> +
> +	.execute_fc_service = qla2x00_execute_fc_service,
> +	.abort_fc_service = qla2x00_abort_fc_service,
>   };
> 
>   struct fc_function_template qla2xxx_transport_vport_functions = {
> @@ -1340,6 +1568,9 @@ struct fc_function_template  
> qla2xxx_transport_vport_functions = {
>   	.dev_loss_tmo_callbk = qla2x00_dev_loss_tmo_callbk,
>   	.terminate_rport_io = qla2x00_terminate_rport_io,
>   	.get_fc_host_stats = qla2x00_get_fc_host_stats,
> +
> +	.execute_fc_service = qla2x00_execute_fc_service,
> +	.abort_fc_service = qla2x00_abort_fc_service,
>   };
> 
>   void
> diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/ 
> qla_def.h
> index edead28..4cf8b1b 100644
> --- a/drivers/scsi/qla2xxx/qla_def.h
> +++ b/drivers/scsi/qla2xxx/qla_def.h
> @@ -93,6 +93,10 @@
>   #define LSD(x)	((uint32_t)((uint64_t)(x)))
>   #define MSD(x)	((uint32_t)((((uint64_t)(x)) >> 16) >> 16))
> 
> +/* ELS PT request buffer = 32 bytes */
> +#define EXT_ELS_PT_REQ_WWPN_VALID	0x1
> +#define EXT_ELS_PT_REQ_WWNN_VALID	0x2
> +#define EXT_ELS_PT_REQ_PID_VALID	0x4
> 
>   /*
>    * I/O register
> @@ -213,6 +217,7 @@ typedef struct srb {
>   #define SRB_FO_CANCEL		BIT_9	/* Command don't need to do failover */
>   #define SRB_IOCTL		BIT_10	/* IOCTL command. */
>   #define SRB_TAPE		BIT_11	/* FCP2 (Tape) command. */
> +#define SRB_ELS_CT		BIT_12	/* Link/Generic Service request. */
> 
>   /*
>    * ISP I/O Register Set structure definitions.
> diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/ 
> qla_fw.h
> index d1d1420..05b6910 100644
> --- a/drivers/scsi/qla2xxx/qla_fw.h
> +++ b/drivers/scsi/qla2xxx/qla_fw.h
> @@ -625,6 +625,41 @@ struct els_entry_24xx {
>   	uint32_t rx_len;		/* Data segment 1 length. */
>   };
> 
> +struct els_status_24xx {
> +	uint8_t entry_type;		/* Entry type. */
> +	uint8_t entry_count;		/* Entry count. */
> +	uint8_t sys_define;		/* System Defined. */
> +	uint8_t entry_status;		/* Entry Status. */
> +
> +	uint32_t handle;		/* System handle. */
> +
> +	uint16_t comp_status;
> +
> +	uint16_t nport_handle;		/* N_PORT handle. */
> +
> +	uint16_t tx_dsd_count;
> +
> +	uint8_t vp_index;
> +	uint8_t sof_type;
> +
> +	uint32_t rx_xchg_address;	/* Receive exchange address. */
> +	uint16_t rx_dsd_count;
> +
> +	uint8_t opcode;
> +	uint8_t reserved_2;
> +
> +	uint8_t port_id[3];
> +	uint8_t reserved_3;
> +
> +	uint16_t reserved_4;
> +
> +	uint16_t control_flags;		/* Control flags. */
> +
> +	uint32_t total_byte_count;
> +	uint32_t err_subcode1;
> +	uint32_t err_subcode2;
> +};
> +
>   /*
>    * ISP queue - Mailbox Command entry structure definition.
>    */
> diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/ 
> qla_gbl.h
> index c0cc686..7e71cdf 100644
> --- a/drivers/scsi/qla2xxx/qla_gbl.h
> +++ b/drivers/scsi/qla2xxx/qla_gbl.h
> @@ -124,6 +124,9 @@ extern int qla2x00_start_scsi(srb_t *sp);
>   extern int qla24xx_start_scsi(srb_t *sp);
>   int qla2x00_marker(scsi_qla_host_t *, uint16_t, uint16_t, uint8_t);
>   int __qla2x00_marker(scsi_qla_host_t *, uint16_t, uint16_t, uint8_t);
> +extern request_t * qla2x00_req_pkt(scsi_qla_host_t *);
> +extern void qla2x00_isp_cmd(scsi_qla_host_t *);
> +extern cont_a64_entry_t *qla2x00_prep_cont_type1_iocb(scsi_qla_host_t  
> *);
> 
>   /*
>    * Global Function Prototypes in qla_mbx.c source file.
> @@ -350,6 +353,7 @@ extern int qla2x00_fdmi_register(scsi_qla_host_t *);
>   extern int qla2x00_gfpn_id(scsi_qla_host_t *, sw_info_t *);
>   extern int qla2x00_gpsc(scsi_qla_host_t *, sw_info_t *);
>   extern void qla2x00_get_sym_node_name(scsi_qla_host_t *, uint8_t *);
> +extern int qla2x00_mgmt_svr_login(scsi_qla_host_t *);
> 
>   /*
>    * Global Function Prototypes in qla_attr.c source file.
> diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/ 
> qla_gs.c
> index db8de06..201ed93 100644
> --- a/drivers/scsi/qla2xxx/qla_gs.c
> +++ b/drivers/scsi/qla2xxx/qla_gs.c
> @@ -1096,7 +1096,7 @@ qla2x00_sns_rnn_id(scsi_qla_host_t *vha)
>    *
>    * Returns 0 on success.
>    */
> -static int
> +int
>   qla2x00_mgmt_svr_login(scsi_qla_host_t *vha)
>   {
>   	int ret;
> diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/ 
> qla_init.c
> index 7bee87f..2a92f6b 100644
> --- a/drivers/scsi/qla2xxx/qla_init.c
> +++ b/drivers/scsi/qla2xxx/qla_init.c
> @@ -2400,6 +2400,17 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)
>   			return (QLA_SUCCESS);
>   		}
> 
> +		/* allocate fc_port_t structure for name/directory server */
> +		fcptemp = qla2x00_alloc_fcport(vha, GFP_KERNEL);
> +		fcptemp->flags |= (FCF_FABRIC_DEVICE | FCF_LOGIN_NEEDED);
> +		fcptemp->loop_id = loop_id;
> +		fcptemp->d_id.b.domain = 0xff;
> +		fcptemp->d_id.b.area = 0xff;
> +		fcptemp->d_id.b.al_pa = 0xfc;
> +		list_add_tail(&fcptemp->list, &vha->vp_fcports);
> +		atomic_set(&fcptemp->state, FCS_ONLINE);
> +		qla2x00_reg_remote_port(vha, fcptemp);
> +
>   		if (test_and_clear_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags)) {
>   			if (qla2x00_rft_id(vha)) {
>   				/* EMPTY */
> diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/ 
> qla_iocb.c
> index 0c145c9..996bfe9 100644
> --- a/drivers/scsi/qla2xxx/qla_iocb.c
> +++ b/drivers/scsi/qla2xxx/qla_iocb.c
> @@ -11,9 +11,6 @@
> 
>   #include <scsi/scsi_tcq.h>
> 
> -static request_t *qla2x00_req_pkt(scsi_qla_host_t *);
> -static void qla2x00_isp_cmd(scsi_qla_host_t *);
> -
>   /**
>    * qla2x00_get_cmd_direction() - Determine control_flag data  
> direction.
>    * @cmd: SCSI command
> @@ -119,7 +116,7 @@ qla2x00_prep_cont_type0_iocb(scsi_qla_host_t *vha)
>    *
>    * Returns a pointer to the continuation type 1 IOCB packet.
>    */
> -static inline cont_a64_entry_t *
> +inline cont_a64_entry_t *
>   qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *vha)
>   {
>   	cont_a64_entry_t *cont_pkt;
> @@ -481,7 +478,7 @@ qla2x00_marker(scsi_qla_host_t *vha, uint16_t  
> loop_id, uint16_t lun,
>    *
>    * Returns NULL if function failed, else, a pointer to the request  
> packet.
>    */
> -static request_t *
> +request_t *
>   qla2x00_req_pkt(scsi_qla_host_t *vha)
>   {
>   	struct qla_hw_data *ha = vha->hw;
> @@ -552,7 +549,7 @@ qla2x00_req_pkt(scsi_qla_host_t *vha)
>    *
>    * Note: The caller must hold the hardware lock before calling this  
> routine.
>    */
> -static void
> +void
>   qla2x00_isp_cmd(scsi_qla_host_t *vha)
>   {
>   	struct qla_hw_data *ha = vha->hw;
> diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/ 
> qla_isr.c
> index 89d3271..3594bae 100644
> --- a/drivers/scsi/qla2xxx/qla_isr.c
> +++ b/drivers/scsi/qla2xxx/qla_isr.c
> @@ -1431,9 +1431,13 @@ void
>   qla24xx_process_response_queue(struct scsi_qla_host *vha)
>   {
>   	struct qla_hw_data *ha = vha->hw;
> +	struct req_que *req = ha->req;
>   	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
>   	struct sts_entry_24xx *pkt;
>   	struct rsp_que *rsp = ha->rsp;
> +	struct els_status_24xx *els_status;
> +	struct fc_service *service;
> +	srb_t *sp;
> 
>   	if (!vha->flags.online)
>   		return;
> @@ -1466,10 +1470,74 @@ qla24xx_process_response_queue(struct  
> scsi_qla_host *vha)
>   		case STATUS_CONT_TYPE:
>   			qla2x00_status_cont_entry(vha, (sts_cont_entry_t *)pkt);
>   			break;
> + 		case MS_IOCB_TYPE:
> +		case ELS_IOCB_TYPE:
> +			if (pkt->handle < MAX_OUTSTANDING_COMMANDS) {
> +				sp = req->outstanding_cmds[pkt->handle];
> +				service = (struct fc_service *) sp->cmd;
> +				req->outstanding_cmds[pkt->handle] = NULL;
> +			} else {
> +				service = NULL;
> +				break;
> +			}
> +
> +			service->service_state_flag = FC_SERVICE_STATE_DONE;
> +			service->srv_reply.status = FC_SERVICE_COMPLETE;
> +			service->srv_reply.error_code = pkt->comp_status;
> +
> +			if (pkt->comp_status) {
> +				printk(KERN_WARNING "scsi(%ld): ELS/CT: "
> +				    "comp_status = %x\n", vha->host_no,
> +				    pkt->comp_status);
> +				els_status = (struct els_status_24xx *)pkt;
> +				service->srv_reply.residual = 0;
> +				if (pkt->comp_status == CS_DATA_UNDERRUN)
> +					service->srv_reply.residual =
> +					    els_status->total_byte_count;
> +				else if (pkt->comp_status == CS_ABORTED) {
> +					service->service_state_flag =
> +					    FC_SERVICE_STATE_ABORTED;
> +					service->srv_reply.status =
> +					    FC_SERVICE_ABORT;
> +				} else
> +				service->srv_reply.status = FC_SERVICE_ERROR;
> +			}
> +
> +			dma_unmap_sg(&ha->pdev->dev, service->payload_dma,
> +			    service->payload_sg_cnt, DMA_TO_DEVICE);
> +			dma_unmap_sg(&ha->pdev->dev, service->response_dma,
> +			    service->response_sg_cnt, DMA_FROM_DEVICE);
> +
> +			mempool_free(sp, ha->srb_mempool);
> +			service->service_done(service);
> + 			break;
>   		case VP_RPT_ID_IOCB_TYPE:
>   			qla24xx_report_id_acquisition(vha,
>   			    (struct vp_rpt_id_entry_24xx *)pkt);
>   			break;
> +		case ABORT_IOCB_TYPE:
> +			if (pkt->comp_status) {
> +				if (pkt->handle < MAX_OUTSTANDING_COMMANDS) {
> +					sp = req->outstanding_cmds[pkt->handle];
> +					req->outstanding_cmds[pkt->handle] =
> +					    NULL;
> +					if (sp->flags & SRB_ELS_CT) {
> +						service = (struct fc_service *)
> +						    sp->cmd;
> +						qla_printk(KERN_ERR, ha,
> +						    "failed to abort"
> +						    " FC service %p\n",
> +						    service);
> +
> +					} else
> +						qla_printk(KERN_ERR, ha,
> +						    "failed to abort"
> +						    " SCSI CMD[0] = %2x\n",
> +						    sp->cmd->cmnd[0]);
> +				}
> +			}
> +			
> +			break;
>   		default:
>   			/* Type Not Supported. */
>   			DEBUG4(printk(KERN_WARNING
> -- 
> 1.6.0.2
> 
> 
> --
> 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-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux