Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3ffd6c5a authored by Raghava Aditya Renukunta's avatar Raghava Aditya Renukunta Committed by Martin K. Petersen
Browse files

scsi: aacraid: Added support for response path



This patch enables the driver to actually process the I/O, or srb replies
from adapter. In addition to any HBA1000 or SmartIOC2000 adapter events.

Signed-off-by: default avatarRaghava Aditya Renukunta <raghavaaditya.renukunta@microsemi.com>
Signed-off-by: default avatarDave Carroll <David.Carroll@microsemi.com>
Reviewed-by: default avatarJohannes Thumshirn <jthumshirn@suse.de>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 4ec57fb4
Loading
Loading
Loading
Loading
+19 −15
Original line number Diff line number Diff line
@@ -329,7 +329,7 @@ static inline int aac_valid_context(struct scsi_cmnd *scsicmd,
	}
	scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL;
	device = scsicmd->device;
	if (unlikely(!device || !scsi_device_online(device))) {
	if (unlikely(!device)) {
		dprintk((KERN_WARNING "aac_valid_context: scsi device corrupt\n"));
		aac_fib_complete(fibptr);
		return 0;
@@ -475,16 +475,26 @@ int aac_get_containers(struct aac_dev *dev)

	if (maximum_num_containers < MAXIMUM_NUM_CONTAINERS)
		maximum_num_containers = MAXIMUM_NUM_CONTAINERS;
	fsa_dev_ptr = kzalloc(sizeof(*fsa_dev_ptr) * maximum_num_containers,
			GFP_KERNEL);
	if (!fsa_dev_ptr)
	if (dev->fsa_dev == NULL ||
		dev->maximum_num_containers != maximum_num_containers) {

		fsa_dev_ptr = dev->fsa_dev;

		dev->fsa_dev = kcalloc(maximum_num_containers,
					sizeof(*fsa_dev_ptr), GFP_KERNEL);

		kfree(fsa_dev_ptr);
		fsa_dev_ptr = NULL;


		if (!dev->fsa_dev)
			return -ENOMEM;

	dev->fsa_dev = fsa_dev_ptr;
		dev->maximum_num_containers = maximum_num_containers;

	for (index = 0; index < dev->maximum_num_containers; ) {
		fsa_dev_ptr[index].devname[0] = '\0';
	}
	for (index = 0; index < dev->maximum_num_containers; index++) {
		dev->fsa_dev[index].devname[0] = '\0';
		dev->fsa_dev[index].valid = 0;

		status = aac_probe_container(dev, index);

@@ -492,12 +502,6 @@ int aac_get_containers(struct aac_dev *dev)
			printk(KERN_WARNING "aac_get_containers: SendFIB failed.\n");
			break;
		}

		/*
		 *	If there are no more containers, then stop asking.
		 */
		if (++index >= status)
			break;
	}
	return status;
}
+29 −23
Original line number Diff line number Diff line
@@ -407,7 +407,7 @@ struct aac_fibhdr {
		__le32 SenderFibAddressHigh;/* upper 32bit of phys. FIB address */
		__le32 TimeStamp;	/* otherwise timestamp for FW internal use */
	} u;
	u32 Handle;		/* FIB handle used for MSGU commnunication */
	__le32 Handle;		/* FIB handle used for MSGU commnunication */
	u32 Previous;		/* FW internal use */
	u32 Next;		/* FW internal use */
};
@@ -882,7 +882,9 @@ struct src_mu_registers {
	__le32	reserved2[25];  /*  38h | Reserved */
	__le32	ODR_R;		/*  9ch | Outbound Doorbell Read */
	__le32	ODR_C;		/*  a0h | Outbound Doorbell Clear */
	__le32	reserved3[6];	/*	a4h | Reserved */
	__le32	reserved3[3];	/*  a4h | Reserved */
	__le32	SCR0;		/*  b0h | Scratchpad 0 */
	__le32	reserved4[2];	/*  b4h | Reserved */
	__le32	OMR;		/*  bch | Outbound Message Register */
	__le32	IQ_L;		/*  c0h | Inbound Queue (Low address) */
	__le32	IQ_H;		/*  c4h | Inbound Queue (High address) */
@@ -982,6 +984,7 @@ struct fsa_dev_info {
	char		devname[8];
	struct sense_data sense_data;
	u32		block_size;
	u8		identifier[16];
};

struct fib {
@@ -1012,6 +1015,7 @@ struct fib {
	u32			vector_no;
	struct hw_fib		*hw_fib_va;		/* Actual shared object */
	dma_addr_t		hw_fib_pa;		/* physical address of hw_fib*/
	u32			hbacmd_size;	/* cmd size for native */
};

#define AAC_DEVTYPE_RAID_MEMBER	1
@@ -1215,9 +1219,11 @@ struct aac_dev
	/*
	 *	negotiated FIB settings
	 */
	unsigned		max_fib_size;
	unsigned		sg_tablesize;
	unsigned		max_num_aif;
	unsigned int		max_fib_size;
	unsigned int		sg_tablesize;
	unsigned int		max_num_aif;

	unsigned int		max_cmd_size;	/* max_fib_size or MAX_NATIVE */

	/*
	 *	Map for 128 fib objects (64k)
@@ -1259,17 +1265,16 @@ struct aac_dev
	 */
	union aac_init		*init;
	dma_addr_t		init_pa;	/* Holds physical address of the init struct */

	u32			*host_rrq;	/* response queue
						 * if AAC_COMM_MESSAGE_TYPE1 */

	/* response queue (if AAC_COMM_MESSAGE_TYPE1) */
	__le32			*host_rrq;
	dma_addr_t		host_rrq_pa;	/* phys. address */
	/* index into rrq buffer */
	u32			host_rrq_idx[AAC_MAX_MSIX];
	atomic_t		rrq_outstanding[AAC_MAX_MSIX];
	u32			fibs_pushed_no;
	struct pci_dev		*pdev;		/* Our PCI interface */
	void *			printfbuf;	/* pointer to buffer used for printf's from the adapter */
	/* pointer to buffer used for printf's from the adapter */
	void			*printfbuf;
	void			*comm_addr;	/* Base address of Comm area */
	dma_addr_t		comm_phys;	/* Physical Address of Comm area */
	size_t			comm_size;
@@ -1342,6 +1347,8 @@ struct aac_dev
	u32			max_msix;	/* max. MSI-X vectors */
	u32			vector_cap;	/* MSI-X vector capab.*/
	int			msi_enabled;	/* MSI/MSI-X enabled */
	atomic_t		msix_counter;
	struct msix_entry	msixentry[AAC_MAX_MSIX];
	struct aac_msix_ctx	aac_msix[AAC_MAX_MSIX]; /* context */
	struct aac_hba_map_info	hba_map[AAC_MAX_BUSES][AAC_MAX_TARGETS];
	u8			adapter_shutdown;
@@ -2281,7 +2288,6 @@ int aac_rx_select_comm(struct aac_dev *dev, int comm);
int aac_rx_deliver_producer(struct fib * fib);
char * get_container_type(unsigned type);
extern int numacb;
extern int acbsize;
extern char aac_driver_version[];
extern int startup_timeout;
extern int aif_timeout;
+11 −6
Original line number Diff line number Diff line
@@ -60,12 +60,17 @@

static int fib_map_alloc(struct aac_dev *dev)
{
	if (dev->max_fib_size > AAC_MAX_NATIVE_SIZE)
		dev->max_cmd_size = AAC_MAX_NATIVE_SIZE;
	else
		dev->max_cmd_size = dev->max_fib_size;

	dprintk((KERN_INFO
	  "allocate hardware fibs pci_alloc_consistent(%p, %d * (%d + %d), %p)\n",
	  dev->pdev, dev->max_fib_size, dev->scsi_host_ptr->can_queue,
	  dev->pdev, dev->max_cmd_size, dev->scsi_host_ptr->can_queue,
	  AAC_NUM_MGT_FIB, &dev->hw_fib_pa));
	dev->hw_fib_va = pci_alloc_consistent(dev->pdev,
		(dev->max_fib_size + sizeof(struct aac_fib_xporthdr))
		(dev->max_cmd_size + sizeof(struct aac_fib_xporthdr))
		* (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB) + (ALIGN32 - 1),
		&dev->hw_fib_pa);
	if (dev->hw_fib_va == NULL)
@@ -83,9 +88,9 @@ static int fib_map_alloc(struct aac_dev *dev)

void aac_fib_map_free(struct aac_dev *dev)
{
	if (dev->hw_fib_va && dev->max_fib_size) {
	if (dev->hw_fib_va && dev->max_cmd_size) {
		pci_free_consistent(dev->pdev,
		(dev->max_fib_size *
		(dev->max_cmd_size *
		(dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB)),
		dev->hw_fib_va, dev->hw_fib_pa);
	}
@@ -176,9 +181,9 @@ int aac_fib_setup(struct aac_dev * dev)
		hw_fib->header.SenderSize = cpu_to_le16(dev->max_fib_size);
		fibptr->hw_fib_pa = hw_fib_pa;
		hw_fib = (struct hw_fib *)((unsigned char *)hw_fib +
			dev->max_fib_size + sizeof(struct aac_fib_xporthdr));
			dev->max_cmd_size + sizeof(struct aac_fib_xporthdr));
		hw_fib_pa = hw_fib_pa +
			dev->max_fib_size + sizeof(struct aac_fib_xporthdr);
			dev->max_cmd_size + sizeof(struct aac_fib_xporthdr);
	}

	/*
+11 −9
Original line number Diff line number Diff line
@@ -122,7 +122,6 @@ unsigned int aac_response_normal(struct aac_queue * q)
			 *	NOTE:  we cannot touch the fib after this
			 *	    call, because it may have been deallocated.
			 */
			fib->flags &= FIB_CONTEXT_FLAG_FASTRESP;
			fib->callback(fib->callback_data, fib);
		} else {
			unsigned long flagv;
@@ -251,8 +250,9 @@ static void aac_aif_callback(void *context, struct fib * fibptr)
	BUG_ON(fibptr == NULL);
	dev = fibptr->dev;

	if (fibptr->hw_fib_va->header.XferState &
	    cpu_to_le32(NoMoreAifDataAvailable)) {
	if ((fibptr->hw_fib_va->header.XferState &
	    cpu_to_le32(NoMoreAifDataAvailable)) ||
		dev->sa_firmware) {
		aac_fib_complete(fibptr);
		aac_fib_free(fibptr);
		return;
@@ -282,8 +282,8 @@ static void aac_aif_callback(void *context, struct fib * fibptr)
 *	know there is a response on our normal priority queue. We will pull off
 *	all QE there are and wake up all the waiters before exiting.
 */
unsigned int aac_intr_normal(struct aac_dev *dev, u32 index,
			int isAif, int isFastResponse, struct hw_fib *aif_fib)
unsigned int aac_intr_normal(struct aac_dev *dev, u32 index, int isAif,
	int isFastResponse, struct hw_fib *aif_fib)
{
	unsigned long mflags;
	dprintk((KERN_INFO "aac_intr_normal(%p,%x)\n", dev, index));
@@ -305,12 +305,14 @@ unsigned int aac_intr_normal(struct aac_dev *dev, u32 index,
			kfree (fib);
			return 1;
		}
		if (aif_fib != NULL) {
		if (dev->sa_firmware) {
			fib->hbacmd_size = index;	/* store event type */
		} else if (aif_fib != NULL) {
			memcpy(hw_fib, aif_fib, sizeof(struct hw_fib));
		} else {
			memcpy(hw_fib,
				(struct hw_fib *)(((uintptr_t)(dev->regs.sa)) +
				index), sizeof(struct hw_fib));
			memcpy(hw_fib, (struct hw_fib *)
				(((uintptr_t)(dev->regs.sa)) + index),
				sizeof(struct hw_fib));
		}
		INIT_LIST_HEAD(&fib->fiblink);
		fib->type = FSAFS_NTC_FIB_CONTEXT;
+29 −9
Original line number Diff line number Diff line
@@ -135,8 +135,16 @@ static irqreturn_t aac_src_intr_message(int irq, void *dev_id)

	if (mode & AAC_INT_MODE_AIF) {
		/* handle AIF */
		if (dev->sa_firmware) {
			u32 events = src_readl(dev, MUnit.SCR0);

			aac_intr_normal(dev, events, 1, 0, NULL);
			writel(events, &dev->IndexRegs->Mailbox[0]);
			src_writel(dev, MUnit.IDR, 1 << 23);
		} else {
			if (dev->aif_thread && dev->fsa_dev)
				aac_intr_normal(dev, 0, 2, 0, NULL);
		}
		if (dev->msi_enabled)
			aac_src_access_devreg(dev, AAC_CLEAR_AIF_BIT);
		mode = 0;
@@ -148,17 +156,19 @@ static irqreturn_t aac_src_intr_message(int irq, void *dev_id)
		for (;;) {
			isFastResponse = 0;
			/* remove toggle bit (31) */
			handle = (dev->host_rrq[index] & 0x7fffffff);
			/* check fast response bit (30) */
			handle = le32_to_cpu((dev->host_rrq[index])
				& 0x7fffffff);
			/* check fast response bits (30, 1) */
			if (handle & 0x40000000)
				isFastResponse = 1;
			handle &= 0x0000ffff;
			if (handle == 0)
				break;
			handle >>= 2;
			if (dev->msi_enabled && dev->max_msix > 1)
				atomic_dec(&dev->rrq_outstanding[vector_no]);
			aac_intr_normal(dev, handle, 0, isFastResponse, NULL);
			dev->host_rrq[index++] = 0;
			aac_intr_normal(dev, handle-1, 0, isFastResponse, NULL);
			if (index == (vector_no + 1) * dev->vector_cap)
				index = vector_no * dev->vector_cap;
			dev->host_rrq_idx[vector_no] = index;
@@ -392,6 +402,7 @@ static void aac_src_start_adapter(struct aac_dev *dev)
		dev->host_rrq_idx[i] = i * dev->vector_cap;
		atomic_set(&dev->rrq_outstanding[i], 0);
	}
	atomic_set(&dev->msix_counter, 0);
	dev->fibs_pushed_no = 0;

	init = dev->init;
@@ -565,9 +576,18 @@ static int aac_srcv_ioremap(struct aac_dev *dev, u32 size)
		dev->base = dev->regs.src.bar0 = NULL;
		return 0;
	}

	dev->regs.src.bar1 =
	ioremap(pci_resource_start(dev->pdev, 2), AAC_MIN_SRCV_BAR1_SIZE);
	dev->base = NULL;
	if (dev->regs.src.bar1 == NULL)
		return -1;
	dev->base = dev->regs.src.bar0 = ioremap(dev->base_start, size);
	if (dev->base == NULL)
	if (dev->base == NULL) {
		iounmap(dev->regs.src.bar1);
		dev->regs.src.bar1 = NULL;
		return -1;
	}
	dev->IndexRegs = &((struct src_registers __iomem *)
		dev->base)->u.denali.IndexRegs;
	return 0;
@@ -918,9 +938,9 @@ int aac_srcv_init(struct aac_dev *dev)
	if (aac_acquire_irq(dev))
		goto error_iounmap;

	dev->dbg_base = dev->base_start;
	dev->dbg_base_mapped = dev->base;
	dev->dbg_size = dev->base_size;
	dev->dbg_base = pci_resource_start(dev->pdev, 2);
	dev->dbg_base_mapped = dev->regs.src.bar1;
	dev->dbg_size = AAC_MIN_SRCV_BAR1_SIZE;
	dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message;

	aac_adapter_enable_int(dev);