SCSI: AACRAID: Fixes issues for PMC SRC on PowerPC
Subsystems (2)
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
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.
--- 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
@@ -1052,10 +1052,11 @@ struct aac_devstruct 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH 2/4 SCSI: AACRAID: Better handling of in-flight events on thread stop
In reply to Ben CollinsWhen an error occured that would shut down the driver, some in-flight events were getting caught up, deadlocking a CPU or two.
--- drivers/scsi/aacraid/linit.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/scsi/aacraid/linit.c +11 -1
@@ -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
PATCH 3/4 SCSI: AACRAID: Relax the tight timeout loop on fib commands
In reply to Ben CollinsThe 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.
--- drivers/scsi/aacraid/commsup.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/scsi/aacraid/commsup.c +6 -3
@@ -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
PATCH 4/4 SCSI: AACRAID: Fix endian issues in core and SRC portions of driver
In reply to Ben CollinsThis 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.
--- 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
@@ -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