Skip to contentSkip to conversation

SCSI: AACRAID: Fixes issues for PMC SRC on PowerPC

PATCH New Ben Collins 1 participant 5 messages Jun 11, 2012

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

cover SCSI: AACRAID: Fixes issues for PMC SRC on PowerPC

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(-)
Signature · 1 line
1.7.9.5
#1 lore raw

PATCH 1/4 SCSI: AACRAID: Use resource_size_t for IO mem pointers and offsets

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.

Cc Adaptec OEM Raid Solutions <[email protected]
---
 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(-)
drivers/scsi/aacraid/aacraid.h +3 -2
index 3fcf627..6ab32db 100644
@@ -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 */
drivers/scsi/aacraid/linit.c +1 -1
index 0d279c44..fdfc4be 100644
@@ -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;
drivers/scsi/aacraid/nark.c +2 -2
index f397d21..6c53b1d 100644
@@ -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;
drivers/scsi/aacraid/rkt.c +1 -1
index be44de9..7d8013f 100644
@@ -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;
drivers/scsi/aacraid/rx.c +2 -2
index b029c7c..dada38a 100644
@@ -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;
 
drivers/scsi/aacraid/sa.c +2 -2
index beb5336..2244f31 100644
@@ -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;
 
drivers/scsi/aacraid/src.c +3 -4
index 7628206..27a3e77 100644
@@ -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;
 
Signature · 1 line
1.7.9.5
#2 lore raw

PATCH 2/4 SCSI: AACRAID: Better handling of in-flight events on thread stop

In reply to Ben Collins

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

Cc Adaptec OEM Raid Solutions <[email protected]
---
 drivers/scsi/aacraid/linit.c |   12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/scsi/aacraid/linit.c +11 -1
index fdfc4be..2be612b 100644
@@ -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;
 	}
 
Signature · 1 line
1.7.9.5
#3 lore raw

PATCH 3/4 SCSI: AACRAID: Relax the tight timeout loop on fib commands

In reply to Ben Collins

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.

Cc Adaptec OEM Raid Solutions <[email protected]
---
 drivers/scsi/aacraid/commsup.c |    9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/scsi/aacraid/commsup.c +6 -3
index 4b32ca4..906a501 100644
@@ -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
Signature · 1 line
1.7.9.5
#4 lore raw

PATCH 4/4 SCSI: AACRAID: Fix endian issues in core and SRC portions of driver

In reply to Ben Collins

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.

Cc Adaptec OEM Raid Solutions <[email protected]
---
 drivers/scsi/aacraid/comminit.c |    4 ++--
 drivers/scsi/aacraid/src.c      |   46 ++++++++++++++++++++++++---------------
 2 files changed, 31 insertions(+), 19 deletions(-)
drivers/scsi/aacraid/comminit.c +2 -2
index a35f54e..8e4b525 100644
@@ -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));
 
 
 	/*
drivers/scsi/aacraid/src.c +29 -17

66 lines not on this page · raw message

Signature · 1 line
1.7.9.5