All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/4] SCSI: AACRAID: Use resource_size_t for IO mem pointers and offsets
  2012-06-11 22:20 [PATCH 0/4] SCSI: AACRAID: Fixes issues for PMC SRC on PowerPC Ben Collins
@ 2012-06-11 18:05 ` Ben Collins
  2012-06-11 18:16 ` [PATCH 2/4] SCSI: AACRAID: Better handling of in-flight events on thread stop Ben Collins
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Ben Collins @ 2012-06-11 18:05 UTC (permalink / raw)
  To: linux-scsi; +Cc: Adaptec OEM Raid Solutions

This also stops using the "legacy crap" in Scsi_Host (shost->base is an
unsigned long).

This affected 32-bit systems that have 64-bit resource sizes, causing the
IO address to be truncated.

Signed-off-by: Ben Collins <bcollins@ubuntu.com>
Cc: Adaptec OEM Raid Solutions <aacraid@adaptec.com
Cc: linux-scsi@vger.kernel.org
---
 drivers/scsi/aacraid/aacraid.h |    5 +++--
 drivers/scsi/aacraid/linit.c   |    2 +-
 drivers/scsi/aacraid/nark.c    |    4 ++--
 drivers/scsi/aacraid/rkt.c     |    2 +-
 drivers/scsi/aacraid/rx.c      |    4 ++--
 drivers/scsi/aacraid/sa.c      |    4 ++--
 drivers/scsi/aacraid/src.c     |    7 +++----
 7 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 3fcf627..6ab32db 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -1052,10 +1052,11 @@ struct aac_dev
 	struct adapter_ops	a_ops;
 	unsigned long		fsrev;		/* Main driver's revision number */
 
-	unsigned long		dbg_base;	/* address of UART
+	resource_size_t		base_start;	/* main IO base */
+	resource_size_t		dbg_base;	/* address of UART
 						 * debug buffer */
 
-	unsigned		base_size, dbg_size;	/* Size of
+	resource_size_t		base_size, dbg_size;	/* Size of
 							 *  mapped in region */
 
 	struct aac_init		*init;		/* Holds initialization info to communicate with adapter */
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 0d279c44..fdfc4be 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -1145,11 +1145,11 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
 		goto out_disable_pdev;
 
 	shost->irq = pdev->irq;
-	shost->base = pci_resource_start(pdev, 0);
 	shost->unique_id = unique_id;
 	shost->max_cmd_len = 16;
 
 	aac = (struct aac_dev *)shost->hostdata;
+	aac->base_start = pci_resource_start(pdev, 0);
 	aac->scsi_host_ptr = shost;
 	aac->pdev = pdev;
 	aac->name = aac_driver_template.name;
diff --git a/drivers/scsi/aacraid/nark.c b/drivers/scsi/aacraid/nark.c
index f397d21..6c53b1d 100644
--- a/drivers/scsi/aacraid/nark.c
+++ b/drivers/scsi/aacraid/nark.c
@@ -49,14 +49,14 @@ static int aac_nark_ioremap(struct aac_dev * dev, u32 size)
 		dev->base = NULL;
 		return 0;
 	}
-	dev->scsi_host_ptr->base = pci_resource_start(dev->pdev, 2);
+	dev->base_start = pci_resource_start(dev->pdev, 2);
 	dev->regs.rx = ioremap((u64)pci_resource_start(dev->pdev, 0) |
 	  ((u64)pci_resource_start(dev->pdev, 1) << 32),
 	  sizeof(struct rx_registers) - sizeof(struct rx_inbound));
 	dev->base = NULL;
 	if (dev->regs.rx == NULL)
 		return -1;
-	dev->base = ioremap(dev->scsi_host_ptr->base, size);
+	dev->base = ioremap(dev->base_start, size);
 	if (dev->base == NULL) {
 		iounmap(dev->regs.rx);
 		dev->regs.rx = NULL;
diff --git a/drivers/scsi/aacraid/rkt.c b/drivers/scsi/aacraid/rkt.c
index be44de9..7d8013f 100644
--- a/drivers/scsi/aacraid/rkt.c
+++ b/drivers/scsi/aacraid/rkt.c
@@ -79,7 +79,7 @@ static int aac_rkt_ioremap(struct aac_dev * dev, u32 size)
 		iounmap(dev->regs.rkt);
 		return 0;
 	}
-	dev->base = dev->regs.rkt = ioremap(dev->scsi_host_ptr->base, size);
+	dev->base = dev->regs.rkt = ioremap(dev->base_start, size);
 	if (dev->base == NULL)
 		return -1;
 	dev->IndexRegs = &dev->regs.rkt->IndexRegs;
diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c
index b029c7c..dada38a 100644
--- a/drivers/scsi/aacraid/rx.c
+++ b/drivers/scsi/aacraid/rx.c
@@ -471,7 +471,7 @@ static int aac_rx_ioremap(struct aac_dev * dev, u32 size)
 		iounmap(dev->regs.rx);
 		return 0;
 	}
-	dev->base = dev->regs.rx = ioremap(dev->scsi_host_ptr->base, size);
+	dev->base = dev->regs.rx = ioremap(dev->base_start, size);
 	if (dev->base == NULL)
 		return -1;
 	dev->IndexRegs = &dev->regs.rx->IndexRegs;
@@ -653,7 +653,7 @@ int _aac_rx_init(struct aac_dev *dev)
 			name, instance);
 		goto error_iounmap;
 	}
-	dev->dbg_base = dev->scsi_host_ptr->base;
+	dev->dbg_base = dev->base_start;
 	dev->dbg_base_mapped = dev->base;
 	dev->dbg_size = dev->base_size;
 
diff --git a/drivers/scsi/aacraid/sa.c b/drivers/scsi/aacraid/sa.c
index beb5336..2244f31 100644
--- a/drivers/scsi/aacraid/sa.c
+++ b/drivers/scsi/aacraid/sa.c
@@ -305,7 +305,7 @@ static int aac_sa_ioremap(struct aac_dev * dev, u32 size)
 		iounmap(dev->regs.sa);
 		return 0;
 	}
-	dev->base = dev->regs.sa = ioremap(dev->scsi_host_ptr->base, size);
+	dev->base = dev->regs.sa = ioremap(dev->base_start, size);
 	return (dev->base == NULL) ? -1 : 0;
 }
 
@@ -393,7 +393,7 @@ int aac_sa_init(struct aac_dev *dev)
 			name, instance);
 		goto error_iounmap;
 	}
-	dev->dbg_base = dev->scsi_host_ptr->base;
+	dev->dbg_base = dev->base_start;
 	dev->dbg_base_mapped = dev->base;
 	dev->dbg_size = dev->base_size;
 
diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c
index 7628206..27a3e77 100644
--- a/drivers/scsi/aacraid/src.c
+++ b/drivers/scsi/aacraid/src.c
@@ -435,8 +435,7 @@ static int aac_src_ioremap(struct aac_dev *dev, u32 size)
 	dev->base = NULL;
 	if (dev->regs.src.bar1 == NULL)
 		return -1;
-	dev->base = dev->regs.src.bar0 = ioremap(dev->scsi_host_ptr->base,
-				size);
+	dev->base = dev->regs.src.bar0 = ioremap(dev->base_start, size);
 	if (dev->base == NULL) {
 		iounmap(dev->regs.src.bar1);
 		dev->regs.src.bar1 = NULL;
@@ -459,7 +458,7 @@ static int aac_srcv_ioremap(struct aac_dev *dev, u32 size)
 		dev->base = dev->regs.src.bar0 = NULL;
 		return 0;
 	}
-	dev->base = dev->regs.src.bar0 = ioremap(dev->scsi_host_ptr->base, size);
+	dev->base = dev->regs.src.bar0 = ioremap(dev->base_start, size);
 	if (dev->base == NULL)
 		return -1;
 	dev->IndexRegs = &((struct src_registers __iomem *)
@@ -764,7 +763,7 @@ int aac_srcv_init(struct aac_dev *dev)
 			name, instance);
 		goto error_iounmap;
 	}
-	dev->dbg_base = dev->scsi_host_ptr->base;
+	dev->dbg_base = dev->base_start;
 	dev->dbg_base_mapped = dev->base;
 	dev->dbg_size = dev->base_size;
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/4] SCSI: AACRAID: Better handling of in-flight events on thread stop
  2012-06-11 22:20 [PATCH 0/4] SCSI: AACRAID: Fixes issues for PMC SRC on PowerPC Ben Collins
  2012-06-11 18:05 ` [PATCH 1/4] SCSI: AACRAID: Use resource_size_t for IO mem pointers and offsets Ben Collins
@ 2012-06-11 18:16 ` Ben Collins
  2012-06-11 18:44 ` [PATCH 3/4] SCSI: AACRAID: Relax the tight timeout loop on fib commands Ben Collins
  2012-06-11 20:14 ` [PATCH 4/4] SCSI: AACRAID: Fix endian issues in core and SRC portions of driver Ben Collins
  3 siblings, 0 replies; 5+ messages in thread
From: Ben Collins @ 2012-06-11 18:16 UTC (permalink / raw)
  To: linux-scsi; +Cc: Adaptec OEM Raid Solutions

When an error occured that would shut down the driver, some in-flight
events were getting caught up, deadlocking a CPU or two.

Signed-off-by: Ben Collins <bcollins@ubuntu.com>
Cc: Adaptec OEM Raid Solutions <aacraid@adaptec.com
Cc: linux-scsi@vger.kernel.org
---
 drivers/scsi/aacraid/linit.c |   12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index fdfc4be..2be612b 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -1089,8 +1089,17 @@ static struct scsi_host_template aac_driver_template = {
 
 static void __aac_shutdown(struct aac_dev * aac)
 {
-	if (aac->aif_thread)
+	if (aac->aif_thread) {
+		int i;
+		/* Clear out events first */
+		for (i = 0; i < (aac->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); i++) {
+			struct fib *fib = &aac->fibs[i];
+			if (!(fib->hw_fib_va->header.XferState & cpu_to_le32(NoResponseExpected | Async)) &&
+			    (fib->hw_fib_va->header.XferState & cpu_to_le32(ResponseExpected)))
+				up(&fib->event_wait);
+		}
 		kthread_stop(aac->thread);
+	}
 	aac_send_shutdown(aac);
 	aac_adapter_disable_int(aac);
 	free_irq(aac->pdev->irq, aac);
@@ -1191,6 +1200,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
 	if (IS_ERR(aac->thread)) {
 		printk(KERN_ERR "aacraid: Unable to create command thread.\n");
 		error = PTR_ERR(aac->thread);
+		aac->thread = NULL;
 		goto out_deinit;
 	}
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 3/4] SCSI: AACRAID: Relax the tight timeout loop on fib commands
  2012-06-11 22:20 [PATCH 0/4] SCSI: AACRAID: Fixes issues for PMC SRC on PowerPC Ben Collins
  2012-06-11 18:05 ` [PATCH 1/4] SCSI: AACRAID: Use resource_size_t for IO mem pointers and offsets Ben Collins
  2012-06-11 18:16 ` [PATCH 2/4] SCSI: AACRAID: Better handling of in-flight events on thread stop Ben Collins
@ 2012-06-11 18:44 ` Ben Collins
  2012-06-11 20:14 ` [PATCH 4/4] SCSI: AACRAID: Fix endian issues in core and SRC portions of driver Ben Collins
  3 siblings, 0 replies; 5+ messages in thread
From: Ben Collins @ 2012-06-11 18:44 UTC (permalink / raw)
  To: linux-scsi; +Cc: Adaptec OEM Raid Solutions

The loop that waited for syncronous fib commands was causing a CPU stall
when a timeout actually occured.

1) Switch to using a more accurate timeout mechanism.
2) Do not pace the loop with udelay(). Use cpu_relax() to allow for
   scheduling to occur.

Signed-off-by: Ben Collins <bcollins@ubuntu.com>
Cc: Adaptec OEM Raid Solutions <aacraid@adaptec.com
Cc: linux-scsi@vger.kernel.org
---
 drivers/scsi/aacraid/commsup.c |    9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 4b32ca4..906a501 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -564,10 +564,10 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
 			 * functioning because an interrupt routing or other
 			 * hardware failure has occurred.
 			 */
-			unsigned long count = 36000000L; /* 3 minutes */
+			unsigned long timeout = jiffies + (180 * HZ); /* 3 minutes */
 			while (down_trylock(&fibptr->event_wait)) {
 				int blink;
-				if (--count == 0) {
+				if (time_is_before_eq_jiffies(timeout)) {
 					struct aac_queue * q = &dev->queues->queue[AdapNormCmdQueue];
 					spin_lock_irqsave(q->lock, qflags);
 					q->numpending--;
@@ -588,7 +588,10 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
 					}
 					return -EFAULT;
 				}
-				udelay(5);
+				/* We used to udelay() here but that absorbed
+				 * a CPU when a timeout occured. Not very
+				 * useful. */
+				cpu_relax();
 			}
 		} else if (down_interruptible(&fibptr->event_wait)) {
 			/* Do nothing ... satisfy
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 4/4] SCSI: AACRAID: Fix endian issues in core and SRC portions of driver
  2012-06-11 22:20 [PATCH 0/4] SCSI: AACRAID: Fixes issues for PMC SRC on PowerPC Ben Collins
                   ` (2 preceding siblings ...)
  2012-06-11 18:44 ` [PATCH 3/4] SCSI: AACRAID: Relax the tight timeout loop on fib commands Ben Collins
@ 2012-06-11 20:14 ` Ben Collins
  3 siblings, 0 replies; 5+ messages in thread
From: Ben Collins @ 2012-06-11 20:14 UTC (permalink / raw)
  To: linux-scsi; +Cc: Adaptec OEM Raid Solutions

This may not fix all endian issues in this driver, but it does get the
driver working on PowerPC for a PMC SRC card. So it should at least fix
all the problems in the core and in the SRC support.

Signed-off-by: Ben Collins <bcollins@ubuntu.com>
Cc: Adaptec OEM Raid Solutions <aacraid@adaptec.com
Cc: linux-scsi@vger.kernel.org
---
 drivers/scsi/aacraid/comminit.c |    4 ++--
 drivers/scsi/aacraid/src.c      |   46 ++++++++++++++++++++++++---------------
 2 files changed, 31 insertions(+), 19 deletions(-)

diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index a35f54e..8e4b525 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -132,8 +132,8 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
 	init->MaxFibSize = cpu_to_le32(dev->max_fib_size);
 
 	init->MaxNumAif = cpu_to_le32(dev->max_num_aif);
-	init->HostRRQ_AddrHigh = (u32)((u64)dev->host_rrq_pa >> 32);
-	init->HostRRQ_AddrLow = (u32)(dev->host_rrq_pa & 0xffffffff);
+	init->HostRRQ_AddrHigh = cpu_to_le32((u32)((u64)dev->host_rrq_pa >> 32));
+	init->HostRRQ_AddrLow = cpu_to_le32((u32)(dev->host_rrq_pa & 0xffffffff));
 
 
 	/*
diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c
index 27a3e77..0fb1f55 100644
--- a/drivers/scsi/aacraid/src.c
+++ b/drivers/scsi/aacraid/src.c
@@ -74,7 +74,7 @@ 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);
+			handle = le32_to_cpu(dev->host_rrq[index]) & 0x7fffffff;
 			/* check fast response bit (30) */
 			if (handle & 0x40000000)
 				isFastResponse = 1;
@@ -389,30 +389,42 @@ static int aac_src_deliver_message(struct fib *fib)
 	struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue];
 	unsigned long qflags;
 	u32 fibsize;
-	u64 address;
+	dma_addr_t address;
 	struct aac_fib_xporthdr *pFibX;
+	u16 hdr_size = le16_to_cpu(fib->hw_fib_va->header.Size);
 
 	spin_lock_irqsave(q->lock, qflags);
 	q->numpending++;
 	spin_unlock_irqrestore(q->lock, qflags);
 
 	/* Calculate the amount to the fibsize bits */
-	fibsize = (sizeof(struct aac_fib_xporthdr) +
-		fib->hw_fib_va->header.Size + 127) / 128 - 1;
+	fibsize = (sizeof(struct aac_fib_xporthdr) + hdr_size + 127) / 128 - 1;
 	if (fibsize > (ALIGN32 - 1))
-		fibsize = ALIGN32 - 1;
-
-    /* Fill XPORT header */
-	pFibX = (struct aac_fib_xporthdr *)
-		((unsigned char *)fib->hw_fib_va -
-		sizeof(struct aac_fib_xporthdr));
-	pFibX->Handle = fib->hw_fib_va->header.SenderData + 1;
-	pFibX->HostAddress = fib->hw_fib_pa;
-	pFibX->Size = fib->hw_fib_va->header.Size;
-	address = fib->hw_fib_pa - (u64)sizeof(struct aac_fib_xporthdr);
-
-	src_writel(dev, MUnit.IQ_H, (u32)(address >> 32));
-	src_writel(dev, MUnit.IQ_L, (u32)(address & 0xffffffff) + fibsize);
+		return -EMSGSIZE;
+
+	/* Fill XPORT header */
+	pFibX = (void *)fib->hw_fib_va - sizeof(struct aac_fib_xporthdr);
+	/*
+	 * This was stored by aac_fib_send() and it is the index into
+	 * dev->fibs. Not sure why we add 1 to it, but I suspect that it's
+	 * because it can't be zero when we pass it to the hardware. Note that
+	 * it was stored in native endian, hence the lack of swapping. -- BenC
+	 */
+	pFibX->Handle = cpu_to_le32(fib->hw_fib_va->header.SenderData + 1);
+	pFibX->HostAddress = cpu_to_le64(fib->hw_fib_pa);
+	pFibX->Size = cpu_to_le32(hdr_size);
+
+	/*
+	 * The xport header has been 32-byte aligned for us so that fibsize
+	 * can be masked out of this address by hardware. -- BenC
+	 */
+	address = fib->hw_fib_pa - sizeof(struct aac_fib_xporthdr);
+	if (address & (ALIGN32 - 1))
+		return -EINVAL;
+	address |= fibsize;
+	src_writel(dev, MUnit.IQ_H, (address >> 32) & 0xffffffff);
+	src_writel(dev, MUnit.IQ_L, address & 0xffffffff);
+
 	return 0;
 }
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 0/4] SCSI: AACRAID: Fixes issues for PMC SRC on PowerPC
@ 2012-06-11 22:20 Ben Collins
  2012-06-11 18:05 ` [PATCH 1/4] SCSI: AACRAID: Use resource_size_t for IO mem pointers and offsets Ben Collins
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Ben Collins @ 2012-06-11 22:20 UTC (permalink / raw)
  To: linux-scsi; +Cc: Adaptec OEM Raid Solutions

While working on getting a PCM SRC card operating on a 32-bit PowerPC
system, I ran into some big-endian and resource size problems (64-bit
resources on 32-bit are not the same as unsigned long).

These patches fix these problems and also a couple bugs that I
encountered in the error paths.

The following changes are available in the git repository at:

  git://github.com/benmcollins/linux.git aacraid

Ben Collins (4):
  SCSI: AACRAID: Use resource_size_t for IO mem pointers and offsets
  SCSI: AACRAID: Better handling of in-flight events on thread stop
  SCSI: AACRAID: Relax the tight timeout loop on fib commands
  SCSI: AACRAID: Fix endian issues in core and SRC portions of driver

 drivers/scsi/aacraid/aacraid.h  |    5 ++--
 drivers/scsi/aacraid/comminit.c |    4 +--
 drivers/scsi/aacraid/commsup.c  |    9 ++++---
 drivers/scsi/aacraid/linit.c    |   14 +++++++++--
 drivers/scsi/aacraid/nark.c     |    4 +--
 drivers/scsi/aacraid/rkt.c      |    2 +-
 drivers/scsi/aacraid/rx.c       |    4 +--
 drivers/scsi/aacraid/sa.c       |    4 +--
 drivers/scsi/aacraid/src.c      |   53 +++++++++++++++++++++++----------------
 9 files changed, 62 insertions(+), 37 deletions(-)

-- 
1.7.9.5


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2012-06-11 22:40 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-06-11 22:20 [PATCH 0/4] SCSI: AACRAID: Fixes issues for PMC SRC on PowerPC Ben Collins
2012-06-11 18:05 ` [PATCH 1/4] SCSI: AACRAID: Use resource_size_t for IO mem pointers and offsets Ben Collins
2012-06-11 18:16 ` [PATCH 2/4] SCSI: AACRAID: Better handling of in-flight events on thread stop Ben Collins
2012-06-11 18:44 ` [PATCH 3/4] SCSI: AACRAID: Relax the tight timeout loop on fib commands Ben Collins
2012-06-11 20:14 ` [PATCH 4/4] SCSI: AACRAID: Fix endian issues in core and SRC portions of driver Ben Collins

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.