All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tomas Henzl <thenzl@redhat.com>
To: ching <ching2048@areca.com.tw>,
	jbottomley@parallels.com, dan.carpenter@oracle.com,
	agordeev@redhat.com, linux-scsi@vger.kernel.org,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH v1.1 2/16 update 3] arcmsr:  Adding code to support MSI-X interrupt
Date: Wed, 07 May 2014 16:31:11 +0200	[thread overview]
Message-ID: <536A43AF.6060908@redhat.com> (raw)
In-Reply-To: <1399463548.23184.6.camel@localhost>

On 05/07/2014 01:52 PM, ching wrote:
> From: Ching<ching2048@areca.com.tw>
>
> Adding code to support MSI-X interrupt.
>
> This update has made change by Tomas' and Alexander's suggestion.
>
> Signed-off-by: Ching<ching2048@areca.com.tw>
> ---
>
> diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
> --- a/drivers/scsi/arcmsr/arcmsr.h	2014-04-28 16:02:46.000000000 +0800
> +++ b/drivers/scsi/arcmsr/arcmsr.h	2014-05-06 15:24:36.000000000 +0800
> @@ -64,6 +64,7 @@ struct device_attribute;
>  #define ARCMSR_MAX_HBB_POSTQUEUE						264
>  #define ARCMSR_MAX_XFER_LEN							0x26000 /* 152K */
>  #define ARCMSR_CDB_SG_PAGE_LENGTH						256 
> +#define ARCMST_NUM_MSIX_VECTORS		4
>  #ifndef PCI_DEVICE_ID_ARECA_1880
>  #define PCI_DEVICE_ID_ARECA_1880 0x1880
>   #endif
> @@ -508,6 +509,7 @@ struct AdapterControlBlock
>  	struct pci_dev *		pdev;
>  	struct Scsi_Host *		host;
>  	unsigned long			vir2phy_offset;
> +	struct msix_entry	entries[ARCMST_NUM_MSIX_VECTORS];
>  	/* Offset is used in making arc cdb physical to virtual calculations */
>  	uint32_t			outbound_int_enable;
>  	uint32_t			cdb_phyaddr_hi32;
> @@ -544,6 +546,8 @@ struct AdapterControlBlock
>  	/* iop init */
>  	#define ACB_F_ABORT				0x0200
>  	#define ACB_F_FIRMWARE_TRAP           		0x0400
> +	#define ACB_F_MSI_ENABLED		0x1000
> +	#define ACB_F_MSIX_ENABLED		0x2000
>  	struct CommandControlBlock *			pccb_pool[ARCMSR_MAX_FREECCB_NUM];
>  	/* used for memory free */
>  	struct list_head		ccb_free_list;
> @@ -594,6 +598,7 @@ struct AdapterControlBlock
>  				#define	FW_DEADLOCK	0x0010
>  	atomic_t 			rq_map_token;
>  	atomic_t			ante_token_value;
> +	int		msix_vector_count;
>  };/* HW_DEVICE_EXTENSION */
>  /*
>  *******************************************************************************
> diff -uprN a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
> --- a/drivers/scsi/arcmsr/arcmsr_hba.c	2014-04-28 15:58:34.000000000 +0800
> +++ b/drivers/scsi/arcmsr/arcmsr_hba.c	2014-05-07 18:42:40.000000000 +0800
> @@ -603,6 +603,60 @@ static void arcmsr_message_isr_bh_fn(str
>  	}
>  }
>  
> +static int
> +arcmsr_request_irq(struct pci_dev *pdev, struct AdapterControlBlock *acb)
> +{
> +	int	i, j, r;
> +	struct msix_entry entries[ARCMST_NUM_MSIX_VECTORS];
> +
> +	if (!pci_find_capability(pdev, PCI_CAP_ID_MSIX))
> +		goto msi_int;
> +	for (i = 0; i < ARCMST_NUM_MSIX_VECTORS; i++)
> +		entries[i].entry = i;
> +	r = pci_enable_msix_range(pdev, entries, 1, ARCMST_NUM_MSIX_VECTORS);
> +	if (r < 0)
> +		goto msi_int;
> +	acb->msix_vector_count = r;
> +	for (i = 0; i < r; i++) {
> +		if (request_irq(entries[i].vector,
> +			arcmsr_do_interrupt, 0, "arcmsr", acb)) {
> +			pr_warn("arcmsr%d: request_irq =%d failed!\n",
> +				acb->host->host_no, pdev->irq);
> +			for (j = 0 ; j < i ; j++)
> +				free_irq(entries[j].vector, acb);
> +			pci_disable_msix(pdev);
> +			goto msi_int;
> +		}
> +		acb->entries[i] = entries[i];
> +	}
> +	acb->acb_flags |= ACB_F_MSIX_ENABLED;
> +	pr_info("arcmsr%d: msi-x enabled\n", acb->host->host_no);
> +	return ARC_SUCCESS;
> +msi_int:
> +	if (!pci_find_capability(pdev, PCI_CAP_ID_MSI))
> +		goto legacy_int;
> +	if (pci_enable_msi_range(pdev, 1, 1) < 0)
> +		goto legacy_int;
> +	if (request_irq(pdev->irq, arcmsr_do_interrupt,
> +		IRQF_SHARED, "arcmsr", acb)) {
> +		pr_warn("arcmsr%d: request_irq =%d failed!\n",
> +			acb->host->host_no, pdev->irq);
> +		pci_disable_msi(pdev);
> +		goto legacy_int;
> +	}
> +	acb->acb_flags |= ACB_F_MSI_ENABLED;
> +	pr_info("arcmsr%d: msi enabled\n", acb->host->host_no);
> +	return ARC_SUCCESS;
> +legacy_int:
> +	if (request_irq(pdev->irq, arcmsr_do_interrupt,
> +		IRQF_SHARED, "arcmsr", acb)) {
> +		pr_warn("arcmsr%d: request_irq = %d failed!\n",
> +			acb->host->host_no, pdev->irq);
> +		return ARC_FAILURE;
> +	}
> +	return ARC_SUCCESS;
> +}
> +
>  static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>  {
>  	struct Scsi_Host *host;
> @@ -667,16 +721,13 @@ static int arcmsr_probe(struct pci_dev *
>  	if(error){
>  		goto free_hbb_mu;
>  	}
> -	arcmsr_iop_init(acb);
>  	error = scsi_add_host(host, &pdev->dev);
>  	if(error){
>  		goto RAID_controller_stop;
Hi Ching,
you have moved the arcmsr_iop_init so you probably
should accordingly rewrite the error path handling at the end of this function
I don't know if it is a problem when you call arcmsr_stop_adapter_bgrb
without a starting it before
Also when you allocate the irq you could free the irq in out_free_sysfs:  
When you change all this you could consider moving the scsi_scan_host
more towards the end of that function so it's called after everything else 
is initiated, that can be made in another patch later.
-tomas
>
>
>
>
>
>  	}
> -	error = request_irq(pdev->irq, arcmsr_do_interrupt, IRQF_SHARED, "arcmsr", acb);
> -	if(error){
> +	if (arcmsr_request_irq(pdev, acb) == ARC_FAILURE)
>  		goto scsi_host_remove;
> -	}
> -	host->irq = pdev->irq;
> +	arcmsr_iop_init(acb);
>      	scsi_scan_host(host);
>  	INIT_WORK(&acb->arcmsr_do_message_isr_bh, arcmsr_message_isr_bh_fn);
>  	atomic_set(&acb->rq_map_token, 16);
> @@ -710,6 +761,21 @@ pci_disable_dev:
>  	return -ENODEV;
>  }
>  
> +static void arcmsr_free_irq(struct pci_dev *pdev, struct AdapterControlBlock *acb)
> +{
> +	int i;
> +
> +	if (acb->acb_flags & ACB_F_MSI_ENABLED) {
> +		free_irq(pdev->irq, acb);
> +		pci_disable_msi(pdev);
> +	} else if (acb->acb_flags & ACB_F_MSIX_ENABLED) {
> +		for (i = 0; i < acb->msix_vector_count; i++)
> +			free_irq(acb->entries[i].vector, acb);
> +		pci_disable_msix(pdev);
> +	} else
> +		free_irq(pdev->irq, acb);
> +}
> +
>  static uint8_t arcmsr_abort_hba_allcmd(struct AdapterControlBlock *acb)
>  {
>  	struct MessageUnit_A __iomem *reg = acb->pmuA;
> @@ -992,6 +1058,7 @@ static void arcmsr_done4abort_postqueue(
>  	}
>  	}
>  }
> +
>  static void arcmsr_remove(struct pci_dev *pdev)
>  {
>  	struct Scsi_Host *host = pci_get_drvdata(pdev);
> @@ -1029,7 +1096,7 @@ static void arcmsr_remove(struct pci_dev
>  			}
>  		}
>  	}
> -	free_irq(pdev->irq, acb);
> +	arcmsr_free_irq(pdev, acb);
>  	arcmsr_free_ccb_pool(acb);
>  	arcmsr_free_hbb_mu(acb);
>  	arcmsr_unmap_pciregion(acb);
> @@ -1045,6 +1112,7 @@ static void arcmsr_shutdown(struct pci_d
>  		(struct AdapterControlBlock *)host->hostdata;
>  	del_timer_sync(&acb->eternal_timer);
>  	arcmsr_disable_outbound_ints(acb);
> +	arcmsr_free_irq(pdev, acb);
>  	flush_work(&acb->arcmsr_do_message_isr_bh);
>  	arcmsr_stop_adapter_bgrb(acb);
>  	arcmsr_flush_adapter_cache(acb);
> @@ -2516,8 +2584,6 @@ static int arcmsr_iop_confirm(struct Ada
>  	case ACB_ADAPTER_TYPE_A: {
>  		if (cdb_phyaddr_hi32 != 0) {
>  			struct MessageUnit_A __iomem *reg = acb->pmuA;
> -			uint32_t intmask_org;
> -			intmask_org = arcmsr_disable_outbound_ints(acb);
>  			writel(ARCMSR_SIGNATURE_SET_CONFIG, \
>  						&reg->message_rwbuffer[0]);
>  			writel(cdb_phyaddr_hi32, &reg->message_rwbuffer[1]);
> @@ -2529,7 +2595,6 @@ static int arcmsr_iop_confirm(struct Ada
>  				acb->host->host_no);
>  				return 1;
>  			}
> -			arcmsr_enable_outbound_ints(acb, intmask_org);
>  		}
>  		}
>  		break;
> @@ -2539,8 +2604,6 @@ static int arcmsr_iop_confirm(struct Ada
>  		uint32_t __iomem *rwbuffer;
>  
>  		struct MessageUnit_B *reg = acb->pmuB;
> -		uint32_t intmask_org;
> -		intmask_org = arcmsr_disable_outbound_ints(acb);
>  		reg->postq_index = 0;
>  		reg->doneq_index = 0;
>  		writel(ARCMSR_MESSAGE_SET_POST_WINDOW, reg->drv2iop_doorbell);
> @@ -2569,7 +2632,6 @@ static int arcmsr_iop_confirm(struct Ada
>  			return 1;
>  		}
>  		arcmsr_hbb_enable_driver_mode(acb);
> -		arcmsr_enable_outbound_ints(acb, intmask_org);
>  		}
>  		break;
>  	case ACB_ADAPTER_TYPE_C: {
>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

  reply	other threads:[~2014-05-07 14:31 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-05-07 11:52 [PATCH v1.1 2/16 update 3] arcmsr: Adding code to support MSI-X interrupt ching
2014-05-07 14:31 ` Tomas Henzl [this message]
2014-05-08 11:37   ` ching
2014-05-09 11:15     ` Tomas Henzl
2014-05-12 11:55       ` ching
2014-05-12 13:01         ` Tomas Henzl
2014-05-13 12:17           ` ching

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=536A43AF.6060908@redhat.com \
    --to=thenzl@redhat.com \
    --cc=agordeev@redhat.com \
    --cc=ching2048@areca.com.tw \
    --cc=dan.carpenter@oracle.com \
    --cc=jbottomley@parallels.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-scsi@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.