linux-scsi.vger.kernel.org archive mirror
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).