[PATCH 5/5] arcmsr: Add the spinlock for queue buffer access

2012-10-03 Thread NickCheng
From: Nick Cheng 

Add the spinlock for queue buffer access
Signed-off-by: Nick Cheng 
---
diff -uprN -X linux-vanilla/Documentation/dontdiff
linux-vanilla//drivers/scsi/arcmsr/arcmsr.h
linux-development//drivers/scsi/arcmsr/arcmsr.h
--- linux-vanilla//drivers/scsi/arcmsr/arcmsr.h 2012-10-03
19:31:31.742620819 +0800
+++ linux-development//drivers/scsi/arcmsr/arcmsr.h 2012-10-03
19:31:04.098621088 +0800
@@ -617,6 +617,8 @@ struct AdapterControlBlock
spinlock_t  eh_lock;
spinlock_t
ccblist_lock;
spinlock_t  postq_lock;
+   spinlock_t  rqbuffer_lock;
+   spinlock_t  wqbuffer_lock;
union {
struct MessageUnit_A __iomem *pmuA;
struct MessageUnit_B*pmuB;
diff -uprN -X linux-vanilla/Documentation/dontdiff
linux-vanilla//drivers/scsi/arcmsr/arcmsr_hba.c
linux-development//drivers/scsi/arcmsr/arcmsr_hba.c
--- linux-vanilla//drivers/scsi/arcmsr/arcmsr_hba.c 2012-10-03
19:31:31.754620820 +0800
+++ linux-development//drivers/scsi/arcmsr/arcmsr_hba.c 2012-10-03
19:31:04.118621087 +0800
@@ -987,6 +987,8 @@ static int arcmsr_probe(struct pci_dev *
spin_lock_init(>eh_lock);
spin_lock_init(>ccblist_lock);
spin_lock_init(>postq_lock);
+   spin_lock_init(>rqbuffer_lock);
+   spin_lock_init(>wqbuffer_lock);
acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED |
ACB_F_MESSAGE_RQBUFFER_CLEARED |
ACB_F_MESSAGE_WQBUFFER_READED);
@@ -1927,10 +1929,12 @@ static struct QBUFFER __iomem *arcmsr_ge
 
 static void arcmsr_iop2drv_data_wrote_handle(struct AdapterControlBlock
*acb)
 {
+   uint8_t __iomem *iop_data;
struct QBUFFER __iomem *prbuffer;
struct QBUFFER *pQbuffer;
-   uint8_t __iomem *iop_data;
int32_t my_empty_len, iop_len, rqbuf_firstindex, rqbuf_lastindex;
+   unsigned long flags;
+   spin_lock_irqsave(>rqbuffer_lock, flags);
rqbuf_lastindex = acb->rqbuf_lastindex;
rqbuf_firstindex = acb->rqbuf_firstindex;
prbuffer = arcmsr_get_iop_rqbuffer(acb);
@@ -1952,10 +1956,13 @@ static void arcmsr_iop2drv_data_wrote_ha
} else {
acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW;
}
+   spin_unlock_irqrestore(>rqbuffer_lock, flags);
 }
 
 static void arcmsr_iop2drv_data_read_handle(struct AdapterControlBlock
*acb)
 {
+   unsigned long flags;
+   spin_lock_irqsave(>wqbuffer_lock, flags);
acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_READED;
if (acb->wqbuf_firstindex != acb->wqbuf_lastindex) {
uint8_t *pQbuffer;
@@ -1984,6 +1991,7 @@ static void arcmsr_iop2drv_data_read_han
if (acb->wqbuf_firstindex == acb->wqbuf_lastindex) {
acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_CLEARED;
}
+   spin_unlock_irqrestore(>wqbuffer_lock, flags);
 }
 
 static void arcmsr_hbaA_doorbell_isr(struct AdapterControlBlock *acb)
@@ -2403,6 +2411,7 @@ static int arcmsr_iop_message_xfer(struc
unsigned char *ver_addr;
uint8_t *pQbuffer, *ptmpQbuffer;
int32_t allxfer_len = 0;
+   unsigned long flags;
 
ver_addr = kmalloc(1032, GFP_ATOMIC);
if (!ver_addr) {
@@ -2411,6 +2420,7 @@ static int arcmsr_iop_message_xfer(struc
}

ptmpQbuffer = ver_addr;
+   spin_lock_irqsave(>rqbuffer_lock, flags);
while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex)
&& (allxfer_len < 1031)) {
pQbuffer = >rqbuffer[acb->rqbuf_firstindex];
@@ -2439,6 +2449,7 @@ static int arcmsr_iop_message_xfer(struc
}
arcmsr_iop_message_read(acb);
}
+   spin_unlock_irqrestore(>rqbuffer_lock, flags);
memcpy(pcmdmessagefld->messagedatabuffer, ver_addr,
allxfer_len);
pcmdmessagefld->cmdmessage.Length = allxfer_len;
if(acb->fw_flag == FW_DEADLOCK) {
@@ -2452,8 +2463,9 @@ static int arcmsr_iop_message_xfer(struc
 
case ARCMSR_MESSAGE_WRITE_WQBUFFER: {
unsigned char *ver_addr;
-   int32_t my_empty_len, user_len, wqbuf_firstindex,
wqbuf_lastindex;
uint8_t *pQbuffer, *ptmpuserbuffer;
+   int32_t my_empty_len, user_len, wqbuf_firstindex,
wqbuf_lastindex;
+   unsigned long flags;
 
ver_addr = kmalloc(1032, GFP_ATOMIC);
if (!ver_addr) {
@@ -2470,6 +2482,7 @@ static int arcmsr_iop_message_xfer(struc
ptmpuserbuffer = ver_addr;
user_len = pcmdmessagefld->cmdmessage.Length;
memcpy(ptmpuserbuffer, pcmdmessagefld->messagedatabuffer,
user_len);
+   

[PATCH 5/5] arcmsr: Add the spinlock for queue buffer access

2012-10-03 Thread NickCheng
From: Nick Cheng nick.ch...@areca.com.tw

Add the spinlock for queue buffer access
Signed-off-by: Nick Cheng nick.ch...@areca.com.tw
---
diff -uprN -X linux-vanilla/Documentation/dontdiff
linux-vanilla//drivers/scsi/arcmsr/arcmsr.h
linux-development//drivers/scsi/arcmsr/arcmsr.h
--- linux-vanilla//drivers/scsi/arcmsr/arcmsr.h 2012-10-03
19:31:31.742620819 +0800
+++ linux-development//drivers/scsi/arcmsr/arcmsr.h 2012-10-03
19:31:04.098621088 +0800
@@ -617,6 +617,8 @@ struct AdapterControlBlock
spinlock_t  eh_lock;
spinlock_t
ccblist_lock;
spinlock_t  postq_lock;
+   spinlock_t  rqbuffer_lock;
+   spinlock_t  wqbuffer_lock;
union {
struct MessageUnit_A __iomem *pmuA;
struct MessageUnit_B*pmuB;
diff -uprN -X linux-vanilla/Documentation/dontdiff
linux-vanilla//drivers/scsi/arcmsr/arcmsr_hba.c
linux-development//drivers/scsi/arcmsr/arcmsr_hba.c
--- linux-vanilla//drivers/scsi/arcmsr/arcmsr_hba.c 2012-10-03
19:31:31.754620820 +0800
+++ linux-development//drivers/scsi/arcmsr/arcmsr_hba.c 2012-10-03
19:31:04.118621087 +0800
@@ -987,6 +987,8 @@ static int arcmsr_probe(struct pci_dev *
spin_lock_init(acb-eh_lock);
spin_lock_init(acb-ccblist_lock);
spin_lock_init(acb-postq_lock);
+   spin_lock_init(acb-rqbuffer_lock);
+   spin_lock_init(acb-wqbuffer_lock);
acb-acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED |
ACB_F_MESSAGE_RQBUFFER_CLEARED |
ACB_F_MESSAGE_WQBUFFER_READED);
@@ -1927,10 +1929,12 @@ static struct QBUFFER __iomem *arcmsr_ge
 
 static void arcmsr_iop2drv_data_wrote_handle(struct AdapterControlBlock
*acb)
 {
+   uint8_t __iomem *iop_data;
struct QBUFFER __iomem *prbuffer;
struct QBUFFER *pQbuffer;
-   uint8_t __iomem *iop_data;
int32_t my_empty_len, iop_len, rqbuf_firstindex, rqbuf_lastindex;
+   unsigned long flags;
+   spin_lock_irqsave(acb-rqbuffer_lock, flags);
rqbuf_lastindex = acb-rqbuf_lastindex;
rqbuf_firstindex = acb-rqbuf_firstindex;
prbuffer = arcmsr_get_iop_rqbuffer(acb);
@@ -1952,10 +1956,13 @@ static void arcmsr_iop2drv_data_wrote_ha
} else {
acb-acb_flags |= ACB_F_IOPDATA_OVERFLOW;
}
+   spin_unlock_irqrestore(acb-rqbuffer_lock, flags);
 }
 
 static void arcmsr_iop2drv_data_read_handle(struct AdapterControlBlock
*acb)
 {
+   unsigned long flags;
+   spin_lock_irqsave(acb-wqbuffer_lock, flags);
acb-acb_flags |= ACB_F_MESSAGE_WQBUFFER_READED;
if (acb-wqbuf_firstindex != acb-wqbuf_lastindex) {
uint8_t *pQbuffer;
@@ -1984,6 +1991,7 @@ static void arcmsr_iop2drv_data_read_han
if (acb-wqbuf_firstindex == acb-wqbuf_lastindex) {
acb-acb_flags |= ACB_F_MESSAGE_WQBUFFER_CLEARED;
}
+   spin_unlock_irqrestore(acb-wqbuffer_lock, flags);
 }
 
 static void arcmsr_hbaA_doorbell_isr(struct AdapterControlBlock *acb)
@@ -2403,6 +2411,7 @@ static int arcmsr_iop_message_xfer(struc
unsigned char *ver_addr;
uint8_t *pQbuffer, *ptmpQbuffer;
int32_t allxfer_len = 0;
+   unsigned long flags;
 
ver_addr = kmalloc(1032, GFP_ATOMIC);
if (!ver_addr) {
@@ -2411,6 +2420,7 @@ static int arcmsr_iop_message_xfer(struc
}

ptmpQbuffer = ver_addr;
+   spin_lock_irqsave(acb-rqbuffer_lock, flags);
while ((acb-rqbuf_firstindex != acb-rqbuf_lastindex)
 (allxfer_len  1031)) {
pQbuffer = acb-rqbuffer[acb-rqbuf_firstindex];
@@ -2439,6 +2449,7 @@ static int arcmsr_iop_message_xfer(struc
}
arcmsr_iop_message_read(acb);
}
+   spin_unlock_irqrestore(acb-rqbuffer_lock, flags);
memcpy(pcmdmessagefld-messagedatabuffer, ver_addr,
allxfer_len);
pcmdmessagefld-cmdmessage.Length = allxfer_len;
if(acb-fw_flag == FW_DEADLOCK) {
@@ -2452,8 +2463,9 @@ static int arcmsr_iop_message_xfer(struc
 
case ARCMSR_MESSAGE_WRITE_WQBUFFER: {
unsigned char *ver_addr;
-   int32_t my_empty_len, user_len, wqbuf_firstindex,
wqbuf_lastindex;
uint8_t *pQbuffer, *ptmpuserbuffer;
+   int32_t my_empty_len, user_len, wqbuf_firstindex,
wqbuf_lastindex;
+   unsigned long flags;
 
ver_addr = kmalloc(1032, GFP_ATOMIC);
if (!ver_addr) {
@@ -2470,6 +2482,7 @@ static int arcmsr_iop_message_xfer(struc
ptmpuserbuffer = ver_addr;
user_len = pcmdmessagefld-cmdmessage.Length;
memcpy(ptmpuserbuffer,