lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-Id: <1315329841-3086-1-git-send-email-alexandre.bounine@idt.com>
Date:	Tue,  6 Sep 2011 13:24:01 -0400
From:	Alexandre Bounine <alexandre.bounine@....com>
To:	akpm@...ux-foundation.org, linux-kernel@...r.kernel.org,
	linuxppc-dev@...ts.ozlabs.org
Cc:	Alexandre Bounine <alexandre.bounine@....com>,
	Chul Kim <chul.kim@....com>,
	Kumar Gala <galak@...nel.crashing.org>,
	Matt Porter <mporter@...nel.crashing.org>,
	Li Yang <leoli@...escale.com>
Subject: [PATCH -mm] RapidIO: Tsi721 driver - fixes for the initial release

- address comments made by Andrew Morton,
  see http://marc.info/?l=linux-kernel&m=131361256714116&w=2
- add spinlock for IB_MSG handler
- rename private BDMA channel structure to avoid conflict with DMA engine
- fix endianess bug in outbound message interrupt handler

Signed-off-by: Alexandre Bounine <alexandre.bounine@....com>
Cc: Chul Kim <chul.kim@....com>
Cc: Kumar Gala <galak@...nel.crashing.org>
Cc: Matt Porter <mporter@...nel.crashing.org>
Cc: Li Yang <leoli@...escale.com>
---
 drivers/rapidio/devices/Kconfig  |    2 +-
 drivers/rapidio/devices/tsi721.c |  273 ++++++++++++++++++++-----------------
 drivers/rapidio/devices/tsi721.h |   20 ++-
 3 files changed, 161 insertions(+), 134 deletions(-)

diff --git a/drivers/rapidio/devices/Kconfig b/drivers/rapidio/devices/Kconfig
index df0b0c5..12a9d7f 100644
--- a/drivers/rapidio/devices/Kconfig
+++ b/drivers/rapidio/devices/Kconfig
@@ -4,7 +4,7 @@
 
 config RAPIDIO_TSI721
 	bool "IDT Tsi721 PCI Express SRIO Controller support"
-	depends on RAPIDIO && PCI && PCIEPORTBUS
+	depends on RAPIDIO && PCIEPORTBUS
 	default "n"
 	---help---
 	  Include support for IDT Tsi721 PCI Express Serial RapidIO controller.
diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c
index dafedc8..5225930 100644
--- a/drivers/rapidio/devices/tsi721.c
+++ b/drivers/rapidio/devices/tsi721.c
@@ -136,21 +136,20 @@ static int tsi721_maint_dma(struct tsi721_device *priv, u32 sys_size,
 	/* Start DMA operation */
 	iowrite32(rd_count + 2,
 		priv->regs + TSI721_DMAC_DWRCNT(TSI721_DMACH_MAINT));
-	(void)ioread32(priv->regs + TSI721_DMAC_DWRCNT(TSI721_DMACH_MAINT));
+	ioread32(priv->regs + TSI721_DMAC_DWRCNT(TSI721_DMACH_MAINT));
 	i = 0;
 
 	/* Wait until DMA transfer is finished */
 	while ((ch_stat = ioread32(priv->regs +
 		TSI721_DMAC_STS(TSI721_DMACH_MAINT))) & TSI721_DMAC_STS_RUN) {
-		udelay(10);
-		i++;
-		if (i >= 5000000) {
+		udelay(1);
+		if (++i >= 5000000) {
 			dev_dbg(&priv->pdev->dev,
 				"%s : DMA[%d] read timeout ch_status=%x\n",
 				__func__, TSI721_DMACH_MAINT, ch_stat);
 			if (!do_wr)
 				*data = 0xffffffff;
-			err = -EFAULT;
+			err = -EIO;
 			goto err_out;
 		}
 	}
@@ -173,7 +172,7 @@ static int tsi721_maint_dma(struct tsi721_device *priv, u32 sys_size,
 		udelay(1);
 		if (!do_wr)
 			*data = 0xffffffff;
-		err = -EFAULT;
+		err = -EIO;
 		goto err_out;
 	}
 
@@ -288,18 +287,15 @@ static void tsi721_pw_dpc(struct work_struct *work)
 {
 	struct tsi721_device *priv = container_of(work, struct tsi721_device,
 						    pw_work);
-	unsigned long flags;
 	u32 msg_buffer[RIO_PW_MSG_SIZE/sizeof(u32)]; /* Use full size PW message
 							buffer for RIO layer */
 
 	/*
 	 * Process port-write messages
 	 */
-	spin_lock_irqsave(&priv->pw_fifo_lock, flags);
-	while (kfifo_out(&priv->pw_fifo, (unsigned char *)msg_buffer,
-			 TSI721_RIO_PW_MSG_SIZE)) {
+	while (kfifo_out_spinlocked(&priv->pw_fifo, (unsigned char *)msg_buffer,
+			 TSI721_RIO_PW_MSG_SIZE, &priv->pw_fifo_lock)) {
 		/* Process one message */
-		spin_unlock_irqrestore(&priv->pw_fifo_lock, flags);
 #ifdef DEBUG_PW
 		{
 		u32 i;
@@ -315,9 +311,7 @@ static void tsi721_pw_dpc(struct work_struct *work)
 #endif
 		/* Pass the port-write message to RIO core for processing */
 		rio_inb_pwrite_handler((union rio_pw_msg *)msg_buffer);
-		spin_lock_irqsave(&priv->pw_fifo_lock, flags);
 	}
-	spin_unlock_irqrestore(&priv->pw_fifo_lock, flags);
 }
 
 /**
@@ -457,87 +451,6 @@ static void tsi721_db_dpc(struct work_struct *work)
 }
 
 /**
- * tsi721_srio_msix - Tsi721 MSI-X SRIO MAC interrupt handler
- * @irq: Linux interrupt number
- * @ptr: Pointer to interrupt-specific data (mport structure)
- *
- * Handles Tsi721 interrupts from SRIO MAC.
- */
-static irqreturn_t tsi721_srio_msix(int irq, void *ptr)
-{
-	struct tsi721_device *priv = ((struct rio_mport *)ptr)->priv;
-	u32 srio_int;
-
-	/* Service SRIO MAC interrupts */
-	srio_int = ioread32(priv->regs + TSI721_RIO_EM_INT_STAT);
-	if (srio_int & TSI721_RIO_EM_INT_STAT_PW_RX)
-		tsi721_pw_handler((struct rio_mport *)ptr);
-
-	return IRQ_HANDLED;
-}
-
-/**
- * tsi721_sr2pc_ch_msix - Tsi721 MSI-X SR2PC Channel interrupt handler
- * @irq: Linux interrupt number
- * @ptr: Pointer to interrupt-specific data (mport structure)
- *
- * Handles Tsi721 interrupts from SR2PC Channel.
- * NOTE: At this moment services only one SR2PC channel associated with inbound
- * doorbells.
- */
-static irqreturn_t tsi721_sr2pc_ch_msix(int irq, void *ptr)
-{
-	struct tsi721_device *priv = ((struct rio_mport *)ptr)->priv;
-	u32 sr_ch_int;
-
-	/* Service Inbound DB interrupt from SR2PC channel */
-	sr_ch_int = ioread32(priv->regs + TSI721_SR_CHINT(IDB_QUEUE));
-	if (sr_ch_int & TSI721_SR_CHINT_IDBQRCV)
-		tsi721_dbell_handler((struct rio_mport *)ptr);
-
-	/* Clear interrupts */
-	iowrite32(sr_ch_int, priv->regs + TSI721_SR_CHINT(IDB_QUEUE));
-	/* Read back to ensure that interrupt was cleared */
-	sr_ch_int = ioread32(priv->regs + TSI721_SR_CHINT(IDB_QUEUE));
-
-	return IRQ_HANDLED;
-}
-
-/**
- * tsi721_omsg_msix - MSI-X interrupt handler for outbound messaging
- * @irq: Linux interrupt number
- * @ptr: Pointer to interrupt-specific data (mport structure)
- *
- * Handles outbound messaging interrupts signaled using MSI-X.
- */
-static irqreturn_t tsi721_omsg_msix(int irq, void *ptr)
-{
-	struct tsi721_device *priv = ((struct rio_mport *)ptr)->priv;
-	int mbox;
-
-	mbox = (irq - priv->msix[TSI721_VECT_OMB0_DONE].vector) % RIO_MAX_MBOX;
-	tsi721_omsg_handler(priv, mbox);
-	return IRQ_HANDLED;
-}
-
-/**
- * tsi721_imsg_msix - MSI-X interrupt handler for inbound messaging
- * @irq: Linux interrupt number
- * @ptr: Pointer to interrupt-specific data (mport structure)
- *
- * Handles inbound messaging interrupts signaled using MSI-X.
- */
-static irqreturn_t tsi721_imsg_msix(int irq, void *ptr)
-{
-	struct tsi721_device *priv = ((struct rio_mport *)ptr)->priv;
-	int mbox;
-
-	mbox = (irq - priv->msix[TSI721_VECT_IMB0_RCV].vector) % RIO_MAX_MBOX;
-	tsi721_imsg_handler(priv, mbox + 4);
-	return IRQ_HANDLED;
-}
-
-/**
  * tsi721_irqhandler - Tsi721 interrupt handler
  * @irq: Linux interrupt number
  * @ptr: Pointer to interrupt-specific data (mport structure)
@@ -575,7 +488,7 @@ static irqreturn_t tsi721_irqhandler(int irq, void *ptr)
 			/* Clear interrupts */
 			iowrite32(intval,
 				priv->regs + TSI721_SR_CHINT(IDB_QUEUE));
-			(void)ioread32(priv->regs + TSI721_SR_CHINT(IDB_QUEUE));
+			ioread32(priv->regs + TSI721_SR_CHINT(IDB_QUEUE));
 		}
 	}
 
@@ -653,7 +566,89 @@ static void tsi721_interrupts_init(struct tsi721_device *priv)
 			TSI721_DEV_INT_SMSG_CH;
 
 	iowrite32(intr, priv->regs + TSI721_DEV_INTE);
-	(void)ioread32(priv->regs + TSI721_DEV_INTE);
+	ioread32(priv->regs + TSI721_DEV_INTE);
+}
+
+#ifdef CONFIG_PCI_MSI
+/**
+ * tsi721_omsg_msix - MSI-X interrupt handler for outbound messaging
+ * @irq: Linux interrupt number
+ * @ptr: Pointer to interrupt-specific data (mport structure)
+ *
+ * Handles outbound messaging interrupts signaled using MSI-X.
+ */
+static irqreturn_t tsi721_omsg_msix(int irq, void *ptr)
+{
+	struct tsi721_device *priv = ((struct rio_mport *)ptr)->priv;
+	int mbox;
+
+	mbox = (irq - priv->msix[TSI721_VECT_OMB0_DONE].vector) % RIO_MAX_MBOX;
+	tsi721_omsg_handler(priv, mbox);
+	return IRQ_HANDLED;
+}
+
+/**
+ * tsi721_imsg_msix - MSI-X interrupt handler for inbound messaging
+ * @irq: Linux interrupt number
+ * @ptr: Pointer to interrupt-specific data (mport structure)
+ *
+ * Handles inbound messaging interrupts signaled using MSI-X.
+ */
+static irqreturn_t tsi721_imsg_msix(int irq, void *ptr)
+{
+	struct tsi721_device *priv = ((struct rio_mport *)ptr)->priv;
+	int mbox;
+
+	mbox = (irq - priv->msix[TSI721_VECT_IMB0_RCV].vector) % RIO_MAX_MBOX;
+	tsi721_imsg_handler(priv, mbox + 4);
+	return IRQ_HANDLED;
+}
+
+/**
+ * tsi721_srio_msix - Tsi721 MSI-X SRIO MAC interrupt handler
+ * @irq: Linux interrupt number
+ * @ptr: Pointer to interrupt-specific data (mport structure)
+ *
+ * Handles Tsi721 interrupts from SRIO MAC.
+ */
+static irqreturn_t tsi721_srio_msix(int irq, void *ptr)
+{
+	struct tsi721_device *priv = ((struct rio_mport *)ptr)->priv;
+	u32 srio_int;
+
+	/* Service SRIO MAC interrupts */
+	srio_int = ioread32(priv->regs + TSI721_RIO_EM_INT_STAT);
+	if (srio_int & TSI721_RIO_EM_INT_STAT_PW_RX)
+		tsi721_pw_handler((struct rio_mport *)ptr);
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * tsi721_sr2pc_ch_msix - Tsi721 MSI-X SR2PC Channel interrupt handler
+ * @irq: Linux interrupt number
+ * @ptr: Pointer to interrupt-specific data (mport structure)
+ *
+ * Handles Tsi721 interrupts from SR2PC Channel.
+ * NOTE: At this moment services only one SR2PC channel associated with inbound
+ * doorbells.
+ */
+static irqreturn_t tsi721_sr2pc_ch_msix(int irq, void *ptr)
+{
+	struct tsi721_device *priv = ((struct rio_mport *)ptr)->priv;
+	u32 sr_ch_int;
+
+	/* Service Inbound DB interrupt from SR2PC channel */
+	sr_ch_int = ioread32(priv->regs + TSI721_SR_CHINT(IDB_QUEUE));
+	if (sr_ch_int & TSI721_SR_CHINT_IDBQRCV)
+		tsi721_dbell_handler((struct rio_mport *)ptr);
+
+	/* Clear interrupts */
+	iowrite32(sr_ch_int, priv->regs + TSI721_SR_CHINT(IDB_QUEUE));
+	/* Read back to ensure that interrupt was cleared */
+	sr_ch_int = ioread32(priv->regs + TSI721_SR_CHINT(IDB_QUEUE));
+
+	return IRQ_HANDLED;
 }
 
 /**
@@ -678,26 +673,11 @@ static int tsi721_request_msix(struct rio_mport *mport)
 	err = request_irq(priv->msix[TSI721_VECT_PWRX].vector,
 			tsi721_srio_msix, 0,
 			priv->msix[TSI721_VECT_PWRX].irq_name, (void *)mport);
-out:
-	return err;
-}
-
-static int tsi721_request_irq(struct rio_mport *mport)
-{
-	struct tsi721_device *priv = mport->priv;
-	int err;
-
-	if (priv->flags & TSI721_USING_MSIX)
-		err = tsi721_request_msix(mport);
-	else
-		err = request_irq(priv->pdev->irq, tsi721_irqhandler,
-			  (priv->flags & TSI721_USING_MSI) ? 0 : IRQF_SHARED,
-			  DRV_NAME, (void *)mport);
-
 	if (err)
-		dev_err(&priv->pdev->dev,
-			"Unable to allocate interrupt, Error: %d\n", err);
-
+		free_irq(
+			priv->msix[TSI721_VECT_IDB].vector,
+			(void *)mport);
+out:
 	return err;
 }
 
@@ -781,6 +761,28 @@ static int tsi721_enable_msix(struct tsi721_device *priv)
 
 	return 0;
 }
+#endif /* CONFIG_PCI_MSI */
+
+static int tsi721_request_irq(struct rio_mport *mport)
+{
+	struct tsi721_device *priv = mport->priv;
+	int err;
+
+#ifdef CONFIG_PCI_MSI
+	if (priv->flags & TSI721_USING_MSIX)
+		err = tsi721_request_msix(mport);
+	else
+#endif
+		err = request_irq(priv->pdev->irq, tsi721_irqhandler,
+			  (priv->flags & TSI721_USING_MSI) ? 0 : IRQF_SHARED,
+			  DRV_NAME, (void *)mport);
+
+	if (err)
+		dev_err(&priv->pdev->dev,
+			"Unable to allocate interrupt, Error: %d\n", err);
+
+	return err;
+}
 
 /**
  * tsi721_init_pc2sr_mapping - initializes outbound (PCIe->SRIO)
@@ -966,11 +968,11 @@ static int tsi721_bdma_ch_init(struct tsi721_device *priv, int chnum)
 	iowrite32(TSI721_DMAC_INT_ALL,
 		priv->regs + TSI721_DMAC_INT(chnum));
 
-	(void)ioread32(priv->regs + TSI721_DMAC_INT(chnum));
+	ioread32(priv->regs + TSI721_DMAC_INT(chnum));
 
 	/* Toggle DMA channel initialization */
 	iowrite32(TSI721_DMAC_CTL_INIT,	priv->regs + TSI721_DMAC_CTL(chnum));
-	(void)ioread32(priv->regs + TSI721_DMAC_CTL(chnum));
+	ioread32(priv->regs + TSI721_DMAC_CTL(chnum));
 	udelay(10);
 
 	return 0;
@@ -1205,7 +1207,7 @@ tsi721_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox,
 	/* Set new write count value */
 	iowrite32(priv->omsg_ring[mbox].wr_count,
 		priv->regs + TSI721_OBDMAC_DWRCNT(mbox));
-	(void)ioread32(priv->regs + TSI721_OBDMAC_DWRCNT(mbox));
+	ioread32(priv->regs + TSI721_OBDMAC_DWRCNT(mbox));
 
 	return 0;
 }
@@ -1246,7 +1248,7 @@ static void tsi721_omsg_handler(struct tsi721_device *priv, int ch)
 		while (sts_ptr[j]) {
 			for (i = 0; i < 8 && sts_ptr[j]; i++, j++) {
 				prev_ptr = last_ptr;
-				last_ptr = sts_ptr[j];
+				last_ptr = le64_to_cpu(sts_ptr[j]);
 				sts_ptr[j] = 0;
 			}
 
@@ -1308,7 +1310,7 @@ no_sts_update:
 				priv->regs + TSI721_OBDMAC_INT(ch));
 		iowrite32(TSI721_OBDMAC_CTL_INIT,
 				priv->regs + TSI721_OBDMAC_CTL(ch));
-		(void)ioread32(priv->regs + TSI721_OBDMAC_CTL(ch));
+		ioread32(priv->regs + TSI721_OBDMAC_CTL(ch));
 
 		/* Inform upper level to clear all pending tx slots */
 		if (priv->mport->outb_msg[ch].mcback)
@@ -1318,7 +1320,7 @@ no_sts_update:
 		/* Synch tx_slot tracking */
 		iowrite32(priv->omsg_ring[ch].tx_slot,
 			priv->regs + TSI721_OBDMAC_DRDCNT(ch));
-		(void)ioread32(priv->regs + TSI721_OBDMAC_DRDCNT(ch));
+		ioread32(priv->regs + TSI721_OBDMAC_DRDCNT(ch));
 		priv->omsg_ring[ch].wr_count = priv->omsg_ring[ch].tx_slot;
 		priv->omsg_ring[ch].sts_rdptr = 0;
 	}
@@ -1394,8 +1396,6 @@ static int tsi721_open_outb_mbox(struct rio_mport *mport, void *dev_id,
 		goto out_buf;
 	}
 
-	memset(priv->omsg_ring[mbox].omd_base, 0,
-		(entries + 1) * sizeof(struct tsi721_omsg_desc));
 	priv->omsg_ring[mbox].tx_slot = 0;
 
 	/* Outbound message descriptor status FIFO allocation */
@@ -1437,6 +1437,7 @@ static int tsi721_open_outb_mbox(struct rio_mport *mport, void *dev_id,
 
 	/* Enable interrupts */
 
+#ifdef CONFIG_PCI_MSI
 	if (priv->flags & TSI721_USING_MSIX) {
 		/* Request interrupt service if we are in MSI-X mode */
 		rc = request_irq(
@@ -1467,12 +1468,14 @@ static int tsi721_open_outb_mbox(struct rio_mport *mport, void *dev_id,
 			goto out_stat;
 		}
 	}
+#endif /* CONFIG_PCI_MSI */
 
 	tsi721_omsg_interrupt_enable(priv, mbox, TSI721_OBDMAC_INT_ALL);
 
 	/* Initialize Outbound Message descriptors ring */
 	bd_ptr = priv->omsg_ring[mbox].omd_base;
 	bd_ptr[entries].type_id = cpu_to_le32(DTYPE5 << 29);
+	bd_ptr[entries].msg_info = 0;
 	bd_ptr[entries].next_lo =
 		cpu_to_le32((u64)priv->omsg_ring[mbox].omd_phys &
 		TSI721_OBDMAC_DPTRL_MASK);
@@ -1483,13 +1486,14 @@ static int tsi721_open_outb_mbox(struct rio_mport *mport, void *dev_id,
 
 	/* Initialize Outbound Message engine */
 	iowrite32(TSI721_OBDMAC_CTL_INIT, priv->regs + TSI721_OBDMAC_CTL(mbox));
-	(void)ioread32(priv->regs + TSI721_OBDMAC_DWRCNT(mbox));
+	ioread32(priv->regs + TSI721_OBDMAC_DWRCNT(mbox));
 	udelay(10);
 
 	priv->omsg_init[mbox] = 1;
 
 	return 0;
 
+#ifdef CONFIG_PCI_MSI
 out_stat:
 	dma_free_coherent(&priv->pdev->dev,
 		priv->omsg_ring[mbox].sts_size * sizeof(struct tsi721_dma_sts),
@@ -1497,6 +1501,7 @@ out_stat:
 		priv->omsg_ring[mbox].sts_phys);
 
 	priv->omsg_ring[mbox].sts_base = NULL;
+#endif /* CONFIG_PCI_MSI */
 
 out_desc:
 	dma_free_coherent(&priv->pdev->dev,
@@ -1540,12 +1545,14 @@ static void tsi721_close_outb_mbox(struct rio_mport *mport, int mbox)
 
 	tsi721_omsg_interrupt_disable(priv, mbox, TSI721_OBDMAC_INT_ALL);
 
+#ifdef CONFIG_PCI_MSI
 	if (priv->flags & TSI721_USING_MSIX) {
 		free_irq(priv->msix[TSI721_VECT_OMB0_DONE + mbox].vector,
 			 (void *)mport);
 		free_irq(priv->msix[TSI721_VECT_OMB0_INT + mbox].vector,
 			 (void *)mport);
 	}
+#endif /* CONFIG_PCI_MSI */
 
 	/* Free OMSG Descriptor Status FIFO */
 	dma_free_coherent(&priv->pdev->dev,
@@ -1589,6 +1596,8 @@ static void tsi721_imsg_handler(struct tsi721_device *priv, int ch)
 	u32 mbox = ch - 4;
 	u32 imsg_int;
 
+	spin_lock(&priv->imsg_ring[mbox].lock);
+
 	imsg_int = ioread32(priv->regs + TSI721_IBDMAC_INT(ch));
 
 	if (imsg_int & TSI721_IBDMAC_INT_SRTO)
@@ -1620,6 +1629,8 @@ static void tsi721_imsg_handler(struct tsi721_device *priv, int ch)
 		ch_inte |= TSI721_INT_IMSG_CHAN(ch);
 		iowrite32(ch_inte, priv->regs + TSI721_DEV_CHAN_INTE);
 	}
+
+	spin_unlock(&priv->imsg_ring[mbox].lock);
 }
 
 /**
@@ -1653,6 +1664,7 @@ static int tsi721_open_inb_mbox(struct rio_mport *mport, void *dev_id,
 	priv->imsg_ring[mbox].fq_wrptr = 0;
 	for (i = 0; i < priv->imsg_ring[mbox].size; i++)
 		priv->imsg_ring[mbox].imq_base[i] = NULL;
+	spin_lock_init(&priv->imsg_ring[mbox].lock);
 
 	/* Allocate buffers for incoming messages */
 	priv->imsg_ring[mbox].buf_base =
@@ -1740,6 +1752,7 @@ static int tsi721_open_inb_mbox(struct rio_mport *mport, void *dev_id,
 
 	/* Enable interrupts */
 
+#ifdef CONFIG_PCI_MSI
 	if (priv->flags & TSI721_USING_MSIX) {
 		/* Request interrupt service if we are in MSI-X mode */
 		rc = request_irq(priv->msix[TSI721_VECT_IMB0_RCV + mbox].vector,
@@ -1763,15 +1776,19 @@ static int tsi721_open_inb_mbox(struct rio_mport *mport, void *dev_id,
 			dev_dbg(&priv->pdev->dev,
 				"Unable to allocate MSI-X interrupt for "
 				"IBOX%d-INT\n", mbox);
+			free_irq(
+				priv->msix[TSI721_VECT_IMB0_RCV + mbox].vector,
+				(void *)mport);
 			goto out_desc;
 		}
 	}
+#endif /* CONFIG_PCI_MSI */
 
 	tsi721_imsg_interrupt_enable(priv, ch, TSI721_IBDMAC_INT_ALL);
 
 	/* Initialize Inbound Message Engine */
 	iowrite32(TSI721_IBDMAC_CTL_INIT, priv->regs + TSI721_IBDMAC_CTL(ch));
-	(void)ioread32(priv->regs + TSI721_IBDMAC_CTL(ch));
+	ioread32(priv->regs + TSI721_IBDMAC_CTL(ch));
 	udelay(10);
 	priv->imsg_ring[mbox].fq_wrptr = entries - 1;
 	iowrite32(entries - 1, priv->regs + TSI721_IBDMAC_FQWP(ch));
@@ -1779,6 +1796,7 @@ static int tsi721_open_inb_mbox(struct rio_mport *mport, void *dev_id,
 	priv->imsg_init[mbox] = 1;
 	return 0;
 
+#ifdef CONFIG_PCI_MSI
 out_desc:
 	dma_free_coherent(&priv->pdev->dev,
 		priv->imsg_ring[mbox].size * sizeof(struct tsi721_imsg_desc),
@@ -1786,6 +1804,7 @@ out_desc:
 		priv->imsg_ring[mbox].imd_phys);
 
 	priv->imsg_ring[mbox].imd_base = NULL;
+#endif /* CONFIG_PCI_MSI */
 
 out_dma:
 	dma_free_coherent(&priv->pdev->dev,
@@ -1827,12 +1846,14 @@ static void tsi721_close_inb_mbox(struct rio_mport *mport, int mbox)
 	/* Disable Interrupts */
 	tsi721_imsg_interrupt_disable(priv, ch, TSI721_OBDMAC_INT_MASK);
 
+#ifdef CONFIG_PCI_MSI
 	if (priv->flags & TSI721_USING_MSIX) {
 		free_irq(priv->msix[TSI721_VECT_IMB0_RCV + mbox].vector,
 				(void *)mport);
 		free_irq(priv->msix[TSI721_VECT_IMB0_INT + mbox].vector,
 				(void *)mport);
 	}
+#endif /* CONFIG_PCI_MSI */
 
 	/* Clear Inbound Buffer Queue */
 	for (rx_slot = 0; rx_slot < priv->imsg_ring[mbox].size; rx_slot++)
@@ -2101,6 +2122,7 @@ static int __devinit tsi721_setup_mport(struct tsi721_device *priv)
 
 	/* Hook up interrupt handler */
 
+#ifdef CONFIG_PCI_MSI
 	if (!tsi721_enable_msix(priv))
 		priv->flags |= TSI721_USING_MSIX;
 	else if (!pci_enable_msi(pdev))
@@ -2108,6 +2130,7 @@ static int __devinit tsi721_setup_mport(struct tsi721_device *priv)
 	else
 		dev_info(&pdev->dev,
 			 "MSI/MSI-X is not available. Using legacy INTx.\n");
+#endif /* CONFIG_PCI_MSI */
 
 	err = tsi721_request_irq(mport);
 
diff --git a/drivers/rapidio/devices/tsi721.h b/drivers/rapidio/devices/tsi721.h
index 3bea6bc..58be4de 100644
--- a/drivers/rapidio/devices/tsi721.h
+++ b/drivers/rapidio/devices/tsi721.h
@@ -505,7 +505,7 @@ struct tsi721_dma_desc {
 		__le32 data[4];		   /* if DTYPE == 2 */
 		u32    reserved[4];	   /* if DTYPE == 3 */
 	};
-} __attribute__((aligned(32)));
+} __aligned(32);
 
 /*
  * Inbound Messaging Descriptor
@@ -533,7 +533,7 @@ struct tsi721_imsg_desc {
 	__le32 bufptr_hi;
 	u32    reserved[12];
 
-} __attribute__((aligned(64)));
+} __aligned(64);
 
 /*
  * Outbound Messaging Descriptor
@@ -567,11 +567,11 @@ struct tsi721_omsg_desc {
 		__le32 next_hi;		/* if DTYPE == 5 */
 	};
 
-} __attribute__((aligned(16)));
+} __aligned(16);
 
 struct tsi721_dma_sts {
 	__le64	desc_sts[8];
-} __attribute__((aligned(64)));
+} __aligned(64);
 
 struct tsi721_desc_sts_fifo {
 	union {
@@ -581,7 +581,7 @@ struct tsi721_desc_sts_fifo {
 			__le32	hi;
 		} da32;
 	} stat[8];
-} __attribute__((aligned(64)));
+} __aligned(64);
 
 /* Descriptor types for BDMA and Messaging blocks */
 enum dma_dtype {
@@ -624,7 +624,7 @@ enum tsi721_smsg_int_flag {
 
 /* Structures */
 
-struct dma_chan {
+struct tsi721_bdma_chan {
 	int		bd_num;		/* number of buffer descriptors */
 	void		*bd_base;	/* start of DMA descriptors */
 	dma_addr_t	bd_phys;
@@ -651,6 +651,7 @@ struct tsi721_imsg_ring {
 	void		*dev_id;
 	u32		fq_wrptr;
 	u32		desc_rdptr;
+	spinlock_t	lock;
 };
 
 struct tsi721_omsg_ring {
@@ -679,6 +680,7 @@ enum tsi721_flags {
 	TSI721_IMSGID_SET	= (1 << 2),
 };
 
+#ifdef CONFIG_PCI_MSI
 /*
  * MSI-X Table Entries (0 ... 69)
  */
@@ -726,14 +728,16 @@ struct msix_irq {
 	u16	vector;
 	char	irq_name[IRQ_DEVICE_NAME_MAX];
 };
+#endif /* CONFIG_PCI_MSI */
 
 struct tsi721_device {
 	struct pci_dev	*pdev;
 	struct rio_mport *mport;
 	u32		flags;
 	void __iomem	*regs;
+#ifdef CONFIG_PCI_MSI
 	struct msix_irq	msix[TSI721_VECT_MAX];
-
+#endif
 	/* Doorbells */
 	void __iomem	*odb_base;
 	void		*idb_base;
@@ -748,7 +752,7 @@ struct tsi721_device {
 	u32		pw_discard_count;
 
 	/* BDMA Engine */
-	struct dma_chan bdma[TSI721_DMA_CHNUM];
+	struct tsi721_bdma_chan bdma[TSI721_DMA_CHNUM];
 
 	/* Inbound Messaging */
 	int		imsg_init[TSI721_IMSG_CHNUM];
-- 
1.7.6

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

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ