* [PATCH 5/5] arcmsr: Modify ARC-1214 IO Behavior
@ 2012-11-15 7:33 NickCheng
0 siblings, 0 replies; 3+ messages in thread
From: NickCheng @ 2012-11-15 7:33 UTC (permalink / raw)
To: linux-scsi; +Cc: linux-kernel, jejb
[-- Attachment #1: Type: text/plain, Size: 166 bytes --]
From: Nick Cheng <nick.cheng@areca.com.tw>
Modify ARC-1214 IO behavior to make up for HW seldom malfunction.
Signed-off-by: Nick Cheng <nick.cheng@areca.com.tw>
---
[-- Attachment #2: patch5 --]
[-- Type: application/octet-stream, Size: 16628 bytes --]
diff -uprN a//drivers/scsi/arcmsr/arcmsr.h b//drivers/scsi/arcmsr/arcmsr.h
--- a//drivers/scsi/arcmsr/arcmsr.h 2012-11-15 12:12:19.035557259 +0800
+++ b//drivers/scsi/arcmsr/arcmsr.h 2012-11-15 15:04:34.291456858 +0800
@@ -63,6 +63,7 @@ struct device_attribute;
#define ARCMSR_DEFAULT_SG_ENTRIES 38
#define ARCMSR_MAX_HBB_POSTQUEUE 264
#define ARCMSR_MAX_ARC1214_POSTQUEUE 256
+#define ARCMSR_MAX_ARC1214_DONEQUEUE 257
#define ARCMSR_MAX_XFER_LEN 0x26000
#define ARCMSR_CDB_SG_PAGE_LENGTH 256
#define ARCMST_NUM_MSIX_VECTORS 4
@@ -175,8 +176,8 @@ struct SG64ENTRY
*/
struct QBUFFER
{
- uint32_t data_len;
- uint8_t data[124];
+ uint32_t __iomem data_len;
+ uint8_t __iomem data[124];
};
/*
*******************************************************************************
@@ -565,7 +566,7 @@ struct OutBound_SRB {
struct MessageUnit_D {
struct InBound_SRB post_qbuffer[ARCMSR_MAX_ARC1214_POSTQUEUE];
- struct OutBound_SRB done_qbuffer[ARCMSR_MAX_ARC1214_POSTQUEUE];
+ struct OutBound_SRB done_qbuffer[ARCMSR_MAX_ARC1214_DONEQUEUE];
u16 postq_index;
u16 doneq_index;
u32 __iomem *chip_id; //0x00004
@@ -618,6 +619,7 @@ struct AdapterControlBlock
spinlock_t eh_lock;
spinlock_t ccblist_lock;
spinlock_t postq_lock;
+ spinlock_t doneq_lock;
spinlock_t rqbuffer_lock;
spinlock_t wqbuffer_lock;
union {
@@ -671,15 +673,15 @@ struct AdapterControlBlock
unsigned int uncache_size;
uint8_t rqbuffer[ARCMSR_MAX_QBUFFER];
/* data collection buffer for read from 80331 */
- int32_t rqbuf_firstindex;
+ uint32_t rqbuf_firstindex;
/* first of read buffer */
- int32_t rqbuf_lastindex;
+ uint32_t rqbuf_lastindex;
/* last of read buffer */
uint8_t wqbuffer[ARCMSR_MAX_QBUFFER];
/* data collection buffer for write to 80331 */
- int32_t wqbuf_firstindex;
+ uint32_t wqbuf_firstindex;
/* first of write buffer */
- int32_t wqbuf_lastindex;
+ uint32_t wqbuf_lastindex;
/* last of write buffer */
uint8_t devstate[ARCMSR_MAX_TARGETID][ARCMSR_MAX_TARGETLUN];
/* id0 ..... id15, lun0...lun7 */
diff -uprN a//drivers/scsi/arcmsr/arcmsr_hba.c b//drivers/scsi/arcmsr/arcmsr_hba.c
--- a//drivers/scsi/arcmsr/arcmsr_hba.c 2012-11-15 12:12:40.851557048 +0800
+++ b//drivers/scsi/arcmsr/arcmsr_hba.c 2012-11-15 15:04:34.319456858 +0800
@@ -1106,6 +1106,7 @@ 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->doneq_lock);
spin_lock_init(&acb->rqbuffer_lock);
spin_lock_init(&acb->wqbuffer_lock);
acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED |
@@ -1247,6 +1248,7 @@ arcmsr_hbaB_abort_allcmd(struct AdapterC
}
return true;
}
+
static uint8_t
arcmsr_hbaC_abort_allcmd(struct AdapterControlBlock *pACB)
{
@@ -1261,6 +1263,7 @@ arcmsr_hbaC_abort_allcmd(struct AdapterC
}
return true;
}
+
static uint8_t
arcmsr_hbaD_abort_allcmd(struct AdapterControlBlock *pACB)
{
@@ -1274,6 +1277,7 @@ arcmsr_hbaD_abort_allcmd(struct AdapterC
}
return true;
}
+
static uint8_t
arcmsr_abort_allcmd(struct AdapterControlBlock *acb)
{
@@ -1554,29 +1558,29 @@ arcmsr_done4abort_postqueue(struct Adapt
uint32_t doneq_index, index_stripped, addressLow, residual;
bool error;
struct CommandControlBlock *pCCB;
- outbound_write_pointer = ioread32(pmu->outboundlist_copy_pointer);
+ outbound_write_pointer = pmu->done_qbuffer[0].addressLow + 1;
doneq_index = pmu->doneq_index;
residual = atomic_read(&acb->ccboutstandingcount);
for (i = 0; i < residual; i++) {
- while ((doneq_index & 0xFF) != (outbound_write_pointer & 0xFF)) {
+ while ((doneq_index & 0xFFF) != (outbound_write_pointer & 0xFFF)) {
if (doneq_index & 0x4000) {
- index_stripped = doneq_index & 0xFF;
+ index_stripped = doneq_index & 0xFFF;
index_stripped += 1;
index_stripped %=
- ARCMSR_MAX_ARC1214_POSTQUEUE;
+ ARCMSR_MAX_ARC1214_DONEQUEUE;
pmu->doneq_index = index_stripped ?
- (index_stripped | 0x4000) : index_stripped;
+ (index_stripped | 0x4000) : (index_stripped + 1);
} else {
index_stripped = doneq_index;
index_stripped += 1;
index_stripped %=
- ARCMSR_MAX_ARC1214_POSTQUEUE;
+ ARCMSR_MAX_ARC1214_DONEQUEUE;
pmu->doneq_index =
- index_stripped ? index_stripped : (index_stripped | 0x4000);
+ index_stripped ? index_stripped : ((index_stripped | 0x4000) + 1);
}
doneq_index = pmu->doneq_index;
addressLow =
- pmu->done_qbuffer[doneq_index & 0xFF].addressLow;
+ pmu->done_qbuffer[doneq_index & 0xFFF].addressLow;
ccb_cdb_phy = (addressLow & 0xFFFFFFF0);
pARCMSR_CDB = (struct ARCMSR_CDB *)
(acb->vir2phy_offset + ccb_cdb_phy);
@@ -1591,7 +1595,7 @@ arcmsr_done4abort_postqueue(struct Adapt
}
mdelay(10);
outbound_write_pointer =
- ioread32(pmu->outboundlist_copy_pointer);
+ pmu->done_qbuffer[0].addressLow + 1;
doneq_index = pmu->doneq_index;
}
pmu->postq_index = 0;
@@ -2148,10 +2152,9 @@ struct QBUFFER __iomem
void
arcmsr_iop2drv_data_wrote_handle(struct AdapterControlBlock *acb)
{
- uint8_t __iomem *iop_data;
+ uint8_t __iomem *iop_data, *pQbuffer, *vaddr, *temp;
struct QBUFFER __iomem *prbuffer;
- struct QBUFFER *pQbuffer;
- int32_t my_empty_len, iop_len, rqbuf_firstindex, rqbuf_lastindex;
+ int32_t my_empty_len, data_len, rqbuf_firstindex, rqbuf_lastindex;
unsigned long flags;
spin_lock_irqsave(&acb->rqbuffer_lock, flags);
@@ -2159,22 +2162,33 @@ arcmsr_iop2drv_data_wrote_handle(struct
rqbuf_firstindex = acb->rqbuf_firstindex;
prbuffer = arcmsr_get_iop_rqbuffer(acb);
iop_data = (uint8_t __iomem *)prbuffer->data;
- iop_len = prbuffer->data_len;
+ data_len = prbuffer->data_len;
my_empty_len = (rqbuf_firstindex - rqbuf_lastindex - 1) &
(ARCMSR_MAX_QBUFFER - 1);
- if (my_empty_len >= iop_len) {
- while (iop_len > 0) {
- pQbuffer = (struct QBUFFER *)
- &acb->rqbuffer[rqbuf_lastindex];
- memcpy(pQbuffer, iop_data, 1);
- rqbuf_lastindex++;
- rqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
- iop_data++;
- iop_len--;
+ if (my_empty_len >= data_len) {
+ if (data_len > 0) {
+ temp = vaddr = kmalloc(data_len, GFP_ATOMIC);
+ memcpy(vaddr, iop_data, data_len);
+ smp_mb();
+ pQbuffer = &acb->rqbuffer[rqbuf_lastindex];
+ if ((rqbuf_lastindex + data_len)
+ > ARCMSR_MAX_QBUFFER) {
+ memcpy(pQbuffer, temp, ARCMSR_MAX_QBUFFER
+ - rqbuf_lastindex);
+ temp += (ARCMSR_MAX_QBUFFER - rqbuf_lastindex);
+ rqbuf_lastindex = (rqbuf_lastindex + data_len)
+ % ARCMSR_MAX_QBUFFER;
+ memcpy(&acb->rqbuffer[0], temp, rqbuf_lastindex);
+ } else {
+ memcpy(pQbuffer, temp, data_len);
+ rqbuf_lastindex = (rqbuf_lastindex + data_len)
+ % ARCMSR_MAX_QBUFFER;
+ }
+ kfree(vaddr);
}
- acb->rqbuf_lastindex = rqbuf_lastindex;
- arcmsr_iop_message_read(acb);
+ acb->rqbuf_lastindex = rqbuf_lastindex;
+ arcmsr_iop_message_read(acb);/*notice IOP the message is read*/
} else {
acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW;
}
@@ -2238,6 +2252,7 @@ arcmsr_hbaA_doorbell_isr(struct AdapterC
(ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK
| ARCMSR_OUTBOUND_IOP331_DATA_READ_OK));
}
+
static void
arcmsr_hbaC_doorbell_isr(struct AdapterControlBlock *pACB)
{
@@ -2392,28 +2407,30 @@ arcmsr_hbaD_postqueue_isr(struct Adapter
struct MessageUnit_D __iomem *pmu;
struct ARCMSR_CDB *arcmsr_cdb;
struct CommandControlBlock *ccb;
+ unsigned long flags;
+ spin_lock_irqsave(&acb->doneq_lock, flags);
pmu = (struct MessageUnit_D *)acb->pmuD;
- outbound_write_pointer = ioread32(pmu->outboundlist_copy_pointer);
+ outbound_write_pointer = pmu->done_qbuffer[0].addressLow + 1;
doneq_index = pmu->doneq_index;
- if ((doneq_index & 0xFF) != (outbound_write_pointer & 0xFF)) {
+ if ((doneq_index & 0xFFF) != (outbound_write_pointer & 0xFFF)) {
do {
if (doneq_index & 0x4000) {
- index_stripped = doneq_index & 0xFF;
+ index_stripped = doneq_index & 0xFFF;
index_stripped += 1;
- index_stripped %= ARCMSR_MAX_ARC1214_POSTQUEUE;
+ index_stripped %= ARCMSR_MAX_ARC1214_DONEQUEUE;
pmu->doneq_index = index_stripped
- ? (index_stripped | 0x4000) : index_stripped;
+ ? (index_stripped | 0x4000) : (index_stripped + 1);
} else {
index_stripped = doneq_index;
index_stripped += 1;
- index_stripped %= ARCMSR_MAX_ARC1214_POSTQUEUE;
+ index_stripped %= ARCMSR_MAX_ARC1214_DONEQUEUE;
pmu->doneq_index = index_stripped
- ? index_stripped : (index_stripped | 0x4000);
+ ? index_stripped : ((index_stripped | 0x4000) + 1);
}
doneq_index = pmu->doneq_index;
addressLow =
- pmu->done_qbuffer[doneq_index & 0xFF].addressLow;
+ pmu->done_qbuffer[doneq_index & 0xFFF].addressLow;
ccb_cdb_phy = (addressLow & 0xFFFFFFF0);
arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset
+ ccb_cdb_phy);
@@ -2424,12 +2441,13 @@ arcmsr_hbaD_postqueue_isr(struct Adapter
arcmsr_drain_donequeue(acb, ccb, error);
iowrite32(doneq_index,
pmu->outboundlist_read_pointer);
- } while ((doneq_index & 0xFF) !=
- (outbound_write_pointer & 0xFF));
+ } while ((doneq_index & 0xFFF) !=
+ (outbound_write_pointer & 0xFFF));
}
iowrite32(ARCMSR_ARC1214_OUTBOUND_LIST_INTERRUPT_CLEAR,
pmu->outboundlist_interrupt_cause);
ioread32(pmu->outboundlist_interrupt_cause);
+ spin_unlock_irqrestore(&acb->doneq_lock, flags);
}
static void
@@ -2440,6 +2458,7 @@ arcmsr_hbaA_message_isr(struct AdapterCo
iowrite32(ARCMSR_MU_OUTBOUND_MESSAGE0_INT, ®->outbound_intstatus);
schedule_work(&acb->arcmsr_do_message_isr_bh);
}
+
static void
arcmsr_hbaB_message_isr(struct AdapterControlBlock *acb)
{
@@ -2694,33 +2713,96 @@ arcmsr_iop_message_xfer(struct AdapterCo
}
ptmpQbuffer = ver_addr;
spin_lock_irqsave(&acb->rqbuffer_lock, flags);
- while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex)
- && (allxfer_len < 1031)) {
+ if (acb->rqbuf_firstindex != acb->rqbuf_lastindex) {
pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex];
- memcpy(ptmpQbuffer, pQbuffer, 1);
- acb->rqbuf_firstindex++;
- acb->rqbuf_firstindex %= ARCMSR_MAX_QBUFFER;
- ptmpQbuffer++;
- allxfer_len++;
+ if (acb->rqbuf_firstindex > acb->rqbuf_lastindex) {
+ if ((ARCMSR_MAX_QBUFFER -
+ acb->rqbuf_firstindex) >= 1032) {
+ memcpy(ptmpQbuffer, pQbuffer, 1032);
+ acb->rqbuf_firstindex += 1032;
+ allxfer_len = 1032;
+ } else {
+ if (((ARCMSR_MAX_QBUFFER -
+ acb->rqbuf_firstindex)
+ + acb->rqbuf_lastindex) > 1032) {
+ memcpy(ptmpQbuffer, pQbuffer,
+ ARCMSR_MAX_QBUFFER
+ - acb->rqbuf_firstindex);
+ ptmpQbuffer += ARCMSR_MAX_QBUFFER
+ - acb->rqbuf_firstindex;
+ memcpy(ptmpQbuffer, acb->rqbuffer,
+ 1032 - (ARCMSR_MAX_QBUFFER
+ - acb->rqbuf_firstindex));
+ acb->rqbuf_firstindex = 1032 -
+ (ARCMSR_MAX_QBUFFER
+ - acb->rqbuf_firstindex);
+ allxfer_len = 1032;
+ } else {
+ memcpy(ptmpQbuffer, pQbuffer,
+ ARCMSR_MAX_QBUFFER
+ - acb->rqbuf_firstindex);
+ ptmpQbuffer += ARCMSR_MAX_QBUFFER
+ - acb->rqbuf_firstindex;
+ memcpy(ptmpQbuffer, acb->rqbuffer,
+ acb->rqbuf_lastindex);
+ allxfer_len = ARCMSR_MAX_QBUFFER
+ - acb->rqbuf_firstindex
+ + acb->rqbuf_lastindex;
+ acb->rqbuf_firstindex =
+ acb->rqbuf_lastindex;
+ }
+ }
+ } else {
+ if ((acb->rqbuf_lastindex
+ - acb->rqbuf_firstindex) > 1032) {
+ memcpy(ptmpQbuffer,
+ pQbuffer, 1032);
+ acb->rqbuf_firstindex += 1032;
+ allxfer_len = 1032;
+ } else {
+ memcpy(ptmpQbuffer,
+ pQbuffer,
+ acb->rqbuf_lastindex
+ - acb->rqbuf_firstindex);
+ allxfer_len = acb->rqbuf_lastindex
+ - acb->rqbuf_firstindex;
+ acb->rqbuf_firstindex
+ = acb->rqbuf_lastindex;
+ }
+ }
}
if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
-
struct QBUFFER __iomem *prbuffer;
- uint8_t __iomem *iop_data;
- int32_t iop_len;
-
- acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
+ uint8_t __iomem *iop_data, *vaddr, *temp;
+ uint32_t data_len, rqbuf_lastindex;
+ acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
+ rqbuf_lastindex = acb->rqbuf_lastindex;
prbuffer = arcmsr_get_iop_rqbuffer(acb);
- iop_data = prbuffer->data;
- iop_len = ioread32(&prbuffer->data_len);
- while (iop_len > 0) {
- acb->rqbuffer[acb->rqbuf_lastindex] =
- ioread8(iop_data);
- acb->rqbuf_lastindex++;
- acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
- iop_data++;
- iop_len--;
+ iop_data = (uint8_t __iomem *)prbuffer->data;
+ data_len = ioread32(&prbuffer->data_len);
+ if (data_len > 0) {
+ temp = vaddr = kmalloc(data_len, GFP_ATOMIC);
+ memcpy(vaddr, iop_data, data_len);
+ smp_mb();
+ pQbuffer = &acb->rqbuffer[acb->rqbuf_lastindex];
+ if ((rqbuf_lastindex + data_len) >
+ ARCMSR_MAX_QBUFFER) {
+ memcpy(pQbuffer, temp,
+ ARCMSR_MAX_QBUFFER - rqbuf_lastindex);
+ temp += (ARCMSR_MAX_QBUFFER
+ - rqbuf_lastindex);
+ rqbuf_lastindex = (rqbuf_lastindex
+ + data_len) % ARCMSR_MAX_QBUFFER;
+ memcpy(&acb->rqbuffer[0],
+ temp, rqbuf_lastindex);
+ } else {
+ memcpy(pQbuffer, temp, data_len);
+ rqbuf_lastindex = (rqbuf_lastindex +
+ data_len) % ARCMSR_MAX_QBUFFER;
+ }
+ kfree(vaddr);
}
+ acb->rqbuf_lastindex = rqbuf_lastindex;
arcmsr_iop_message_read(acb);
}
spin_unlock_irqrestore(&acb->rqbuffer_lock, flags);
@@ -3641,19 +3723,21 @@ arcmsr_hbaD_polling_ccbdone(struct Adapt
{
bool error;
uint32_t poll_ccb_done = 0, poll_count = 0, flag_ccb, ccb_cdb_phy;
- int rtn, index, outbound_write_pointer;
+ int rtn, doneq_index, index_stripped, outbound_write_pointer;
+ unsigned long flags;
struct ARCMSR_CDB *arcmsr_cdb;
struct CommandControlBlock *pCCB;
- struct MessageUnit_D __iomem *reg =
+ struct MessageUnit_D __iomem *pmu =
(struct MessageUnit_D *)acb->pmuD;
+ spin_lock_irqsave(&acb->doneq_lock, flags);
polling_hbaD_ccb_retry:
poll_count++;
while (1) {
outbound_write_pointer =
- ioread32(reg->outboundlist_copy_pointer);
- index = reg->doneq_index;
- if ((outbound_write_pointer & 0xFF) == index) {
+ pmu->done_qbuffer[0].addressLow + 1;
+ doneq_index = pmu->doneq_index;
+ if ((outbound_write_pointer & 0xFFF) == (doneq_index & 0xFFF)) {
if (poll_ccb_done) {
rtn = SUCCESS;
break;
@@ -3666,17 +3750,27 @@ arcmsr_hbaD_polling_ccbdone(struct Adapt
goto polling_hbaD_ccb_retry;
}
}
- flag_ccb = reg->done_qbuffer[index].addressLow;
+ if (doneq_index & 0x4000) {
+ index_stripped = doneq_index & 0xFFF;
+ index_stripped += 1;
+ index_stripped %= ARCMSR_MAX_ARC1214_DONEQUEUE;
+ pmu->doneq_index = index_stripped ? (index_stripped | 0x4000)
+ : (index_stripped + 1);
+ } else {
+ index_stripped = doneq_index;
+ index_stripped += 1;
+ index_stripped %= ARCMSR_MAX_ARC1214_DONEQUEUE;
+ pmu->doneq_index = index_stripped ? index_stripped :
+ ((index_stripped | 0x4000) + 1);
+ }
+ doneq_index = pmu->doneq_index;
+ flag_ccb = pmu->done_qbuffer[doneq_index & 0xFFF].addressLow;
ccb_cdb_phy = (flag_ccb & 0xFFFFFFF0);
arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset +
ccb_cdb_phy);
pCCB = container_of(arcmsr_cdb,
struct CommandControlBlock, arcmsr_cdb);
poll_ccb_done = (pCCB == poll_ccb) ? 1 : 0;
- index++;
- index %= ARCMSR_MAX_ARC1214_POSTQUEUE;
- reg->doneq_index = index;
- /* check if command done with no error*/
if ((pCCB->acb != acb) ||
(pCCB->startdone != ARCMSR_CCB_START)) {
if (pCCB->startdone == ARCMSR_CCB_ABORTED) {
@@ -3703,6 +3797,7 @@ arcmsr_hbaD_polling_ccbdone(struct Adapt
? true : false;
arcmsr_report_ccb_state(acb, pCCB, error);
}
+ spin_unlock_irqrestore(&acb->doneq_lock, flags);
return rtn;
}
@@ -3838,7 +3933,7 @@ arcmsr_iop_confirm(struct AdapterControl
struct MessageUnit_D *reg =
(struct MessageUnit_D *)acb->pmuD;
reg->postq_index = 0;
- reg->doneq_index = 0x40FF;
+ reg->doneq_index = 0;
rwbuffer = reg->msgcode_rwbuffer;
iowrite32(ARCMSR_SIGNATURE_SET_CONFIG, rwbuffer++);
iowrite32(cdb_phyaddr_hi32, rwbuffer++);
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH 5/5] arcmsr: Modify ARC-1214 IO Behavior
2012-11-16 11:56 NickCheng
@ 2012-11-30 9:18 ` James Bottomley
0 siblings, 0 replies; 3+ messages in thread
From: James Bottomley @ 2012-11-30 9:18 UTC (permalink / raw)
To: NickCheng; +Cc: linux-scsi, linux-kernel, jejb
On Fri, 2012-11-16 at 19:56 +0800, NickCheng wrote:
> From: Nick Cheng <nick.cheng@areca.com.tw>
>
> Modify ARC-1214 IO behavior to make up for HW seldom malfunction.
> Signed-off-by: Nick Cheng <nick.cheng@areca.com.tw>
This still isn't right. I said you could ignore most of the warnings
(like lines over 80 characters), but you have a lot of this:
> - printk(KERN_NOTICE "arcmsr%d: memory mapping region fail \n", =
> acb->host->host_no);
> + pr_notice("arcmsr%d: memory mapping"
> + "region fail\n", acb->host->host_no);
I'm agnostic on whether you split a print, in spite of the warning but I
do tend to prefer longer lines, since they avoid the mistake you made
quite a few times, which is not leaving a space between the separate
words in the split string. This will produce a message like
arcmsr1: memory mappingregion fail
Plus this indentation
> - if (readl(&acb->pmuC->outbound_doorbell) & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) {
> - writel(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR, &acb->pmuC->outbound_doorbell_clear);/*clear interrupt*/=0A=
> + if (readl(&acb->pmuC->outbound_doorbell) &
> + ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) {
> + writel(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR,
> + &acb->pmuC->outbound_doorbell_clear);
Is being changed from correctly indented to incorrectly indented (writel
needs another tab).
James
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 5/5] arcmsr: Modify ARC-1214 IO Behavior
@ 2012-11-16 11:56 NickCheng
2012-11-30 9:18 ` James Bottomley
0 siblings, 1 reply; 3+ messages in thread
From: NickCheng @ 2012-11-16 11:56 UTC (permalink / raw)
To: linux-scsi; +Cc: linux-kernel, jejb
[-- Attachment #1: Type: text/plain, Size: 166 bytes --]
From: Nick Cheng <nick.cheng@areca.com.tw>
Modify ARC-1214 IO behavior to make up for HW seldom malfunction.
Signed-off-by: Nick Cheng <nick.cheng@areca.com.tw>
---
[-- Attachment #2: patch5 --]
[-- Type: application/octet-stream, Size: 15110 bytes --]
diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
--- a/drivers/scsi/arcmsr/arcmsr.h 2012-11-16 18:07:40.052372519 +0800
+++ b/drivers/scsi/arcmsr/arcmsr.h 2012-11-16 18:52:25.840453468 +0800
@@ -63,6 +63,7 @@ struct device_attribute;
#define ARCMSR_DEFAULT_SG_ENTRIES 38
#define ARCMSR_MAX_HBB_POSTQUEUE 264
#define ARCMSR_MAX_ARC1214_POSTQUEUE 256
+#define ARCMSR_MAX_ARC1214_DONEQUEUE 257
#define ARCMSR_MAX_XFER_LEN 0x26000
#define ARCMSR_CDB_SG_PAGE_LENGTH 256
#define ARCMST_NUM_MSIX_VECTORS 4
@@ -564,7 +565,7 @@ struct OutBound_SRB {
struct MessageUnit_D {
struct InBound_SRB post_qbuffer[ARCMSR_MAX_ARC1214_POSTQUEUE];
- struct OutBound_SRB done_qbuffer[ARCMSR_MAX_ARC1214_POSTQUEUE];
+ struct OutBound_SRB done_qbuffer[ARCMSR_MAX_ARC1214_DONEQUEUE];
u16 postq_index;
u16 doneq_index;
u32 __iomem *chip_id; /*0x00004*/
@@ -617,6 +618,7 @@ struct AdapterControlBlock
spinlock_t eh_lock;
spinlock_t ccblist_lock;
spinlock_t postq_lock;
+ spinlock_t doneq_lock;
spinlock_t rqbuffer_lock;
spinlock_t wqbuffer_lock;
union {
@@ -670,15 +672,15 @@ struct AdapterControlBlock
unsigned int uncache_size;
uint8_t rqbuffer[ARCMSR_MAX_QBUFFER];
/* data collection buffer for read from 80331 */
- int32_t rqbuf_firstindex;
+ uint32_t rqbuf_firstindex;
/* first of read buffer */
- int32_t rqbuf_lastindex;
+ uint32_t rqbuf_lastindex;
/* last of read buffer */
uint8_t wqbuffer[ARCMSR_MAX_QBUFFER];
/* data collection buffer for write to 80331 */
- int32_t wqbuf_firstindex;
+ uint32_t wqbuf_firstindex;
/* first of write buffer */
- int32_t wqbuf_lastindex;
+ uint32_t wqbuf_lastindex;
/* last of write buffer */
uint8_t devstate[ARCMSR_MAX_TARGETID][ARCMSR_MAX_TARGETLUN];
/* id0 ..... id15, lun0...lun7 */
diff -uprN a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
--- a/drivers/scsi/arcmsr/arcmsr_hba.c 2012-11-16 18:07:40.072372510 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c 2012-11-16 18:52:25.840453468 +0800
@@ -1097,6 +1097,7 @@ 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->doneq_lock);
spin_lock_init(&acb->rqbuffer_lock);
spin_lock_init(&acb->wqbuffer_lock);
acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED |
@@ -1541,33 +1542,29 @@ arcmsr_done4abort_postqueue(struct Adapt
uint32_t doneq_index, index_stripped, addressLow, residual;
bool error;
struct CommandControlBlock *pCCB;
- outbound_write_pointer =
- ioread32(pmu->outboundlist_copy_pointer);
+ outbound_write_pointer = pmu->done_qbuffer[0].addressLow + 1;
doneq_index = pmu->doneq_index;
residual = atomic_read(&acb->ccboutstandingcount);
for (i = 0; i < residual; i++) {
- while ((doneq_index & 0xFF) !=
- (outbound_write_pointer & 0xFF)) {
+ while ((doneq_index & 0xFFF) != (outbound_write_pointer & 0xFFF)) {
if (doneq_index & 0x4000) {
- index_stripped = doneq_index & 0xFF;
+ index_stripped = doneq_index & 0xFFF;
index_stripped += 1;
index_stripped %=
- ARCMSR_MAX_ARC1214_POSTQUEUE;
+ ARCMSR_MAX_ARC1214_DONEQUEUE;
pmu->doneq_index = index_stripped ?
- (index_stripped | 0x4000) :
- index_stripped;
+ (index_stripped | 0x4000) : (index_stripped + 1);
} else {
index_stripped = doneq_index;
index_stripped += 1;
index_stripped %=
- ARCMSR_MAX_ARC1214_POSTQUEUE;
+ ARCMSR_MAX_ARC1214_DONEQUEUE;
pmu->doneq_index =
- index_stripped ? index_stripped :
- (index_stripped | 0x4000);
+ index_stripped ? index_stripped : ((index_stripped | 0x4000) + 1);
}
doneq_index = pmu->doneq_index;
addressLow =
- pmu->done_qbuffer[doneq_index & 0xFF].addressLow;
+ pmu->done_qbuffer[doneq_index & 0xFFF].addressLow;
ccb_cdb_phy = (addressLow & 0xFFFFFFF0);
pARCMSR_CDB = (struct ARCMSR_CDB *)
(acb->vir2phy_offset + ccb_cdb_phy);
@@ -1582,7 +1579,7 @@ arcmsr_done4abort_postqueue(struct Adapt
}
mdelay(10);
outbound_write_pointer =
- ioread32(pmu->outboundlist_copy_pointer);
+ pmu->done_qbuffer[0].addressLow + 1;
doneq_index = pmu->doneq_index;
}
pmu->postq_index = 0;
@@ -2135,10 +2132,9 @@ struct QBUFFER __iomem
void
arcmsr_iop2drv_data_wrote_handle(struct AdapterControlBlock *acb)
{
- uint8_t __iomem *iop_data;
+ uint8_t __iomem *iop_data, *pQbuffer, *vaddr, *temp;
struct QBUFFER __iomem *prbuffer;
- struct QBUFFER *pQbuffer;
- int32_t my_empty_len, iop_len, rqbuf_firstindex, rqbuf_lastindex;
+ int32_t my_empty_len, data_len, rqbuf_firstindex, rqbuf_lastindex;
unsigned long flags;
spin_lock_irqsave(&acb->rqbuffer_lock, flags);
@@ -2146,19 +2142,30 @@ arcmsr_iop2drv_data_wrote_handle(struct
rqbuf_firstindex = acb->rqbuf_firstindex;
prbuffer = arcmsr_get_iop_rqbuffer(acb);
iop_data = (uint8_t __iomem *)prbuffer->data;
- iop_len = prbuffer->data_len;
+ data_len = prbuffer->data_len;
my_empty_len = (rqbuf_firstindex - rqbuf_lastindex - 1) &
(ARCMSR_MAX_QBUFFER - 1);
- if (my_empty_len >= iop_len) {
- while (iop_len > 0) {
- pQbuffer = (struct QBUFFER *)
- &acb->rqbuffer[rqbuf_lastindex];
- memcpy(pQbuffer, iop_data, 1);
- rqbuf_lastindex++;
- rqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
- iop_data++;
- iop_len--;
+ if (my_empty_len >= data_len) {
+ if (data_len > 0) {
+ temp = vaddr = kmalloc(data_len, GFP_ATOMIC);
+ memcpy(vaddr, iop_data, data_len);
+ smp_mb();
+ pQbuffer = &acb->rqbuffer[rqbuf_lastindex];
+ if ((rqbuf_lastindex + data_len)
+ > ARCMSR_MAX_QBUFFER) {
+ memcpy(pQbuffer, temp, ARCMSR_MAX_QBUFFER
+ - rqbuf_lastindex);
+ temp += (ARCMSR_MAX_QBUFFER - rqbuf_lastindex);
+ rqbuf_lastindex = (rqbuf_lastindex + data_len)
+ % ARCMSR_MAX_QBUFFER;
+ memcpy(&acb->rqbuffer[0], temp, rqbuf_lastindex);
+ } else {
+ memcpy(pQbuffer, temp, data_len);
+ rqbuf_lastindex = (rqbuf_lastindex + data_len)
+ % ARCMSR_MAX_QBUFFER;
+ }
+ kfree(vaddr);
}
acb->rqbuf_lastindex = rqbuf_lastindex;
arcmsr_iop_message_read(acb);
@@ -2379,28 +2386,30 @@ arcmsr_hbaD_postqueue_isr(struct Adapter
struct MessageUnit_D __iomem *pmu;
struct ARCMSR_CDB *arcmsr_cdb;
struct CommandControlBlock *ccb;
+ unsigned long flags;
+ spin_lock_irqsave(&acb->doneq_lock, flags);
pmu = (struct MessageUnit_D *)acb->pmuD;
- outbound_write_pointer = ioread32(pmu->outboundlist_copy_pointer);
+ outbound_write_pointer = pmu->done_qbuffer[0].addressLow + 1;
doneq_index = pmu->doneq_index;
- if ((doneq_index & 0xFF) != (outbound_write_pointer & 0xFF)) {
+ if ((doneq_index & 0xFFF) != (outbound_write_pointer & 0xFFF)) {
do {
if (doneq_index & 0x4000) {
- index_stripped = doneq_index & 0xFF;
+ index_stripped = doneq_index & 0xFFF;
index_stripped += 1;
- index_stripped %= ARCMSR_MAX_ARC1214_POSTQUEUE;
+ index_stripped %= ARCMSR_MAX_ARC1214_DONEQUEUE;
pmu->doneq_index = index_stripped
- ? (index_stripped | 0x4000) : index_stripped;
+ ? (index_stripped | 0x4000) : (index_stripped + 1);
} else {
index_stripped = doneq_index;
index_stripped += 1;
- index_stripped %= ARCMSR_MAX_ARC1214_POSTQUEUE;
+ index_stripped %= ARCMSR_MAX_ARC1214_DONEQUEUE;
pmu->doneq_index = index_stripped
- ? index_stripped : (index_stripped | 0x4000);
+ ? index_stripped : ((index_stripped | 0x4000) + 1);
}
doneq_index = pmu->doneq_index;
addressLow =
- pmu->done_qbuffer[doneq_index & 0xFF].addressLow;
+ pmu->done_qbuffer[doneq_index & 0xFFF].addressLow;
ccb_cdb_phy = (addressLow & 0xFFFFFFF0);
arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset
+ ccb_cdb_phy);
@@ -2411,12 +2420,13 @@ arcmsr_hbaD_postqueue_isr(struct Adapter
arcmsr_drain_donequeue(acb, ccb, error);
iowrite32(doneq_index,
pmu->outboundlist_read_pointer);
- } while ((doneq_index & 0xFF) !=
- (outbound_write_pointer & 0xFF));
+ } while ((doneq_index & 0xFFF) !=
+ (outbound_write_pointer & 0xFFF));
}
iowrite32(ARCMSR_ARC1214_OUTBOUND_LIST_INTERRUPT_CLEAR,
pmu->outboundlist_interrupt_cause);
ioread32(pmu->outboundlist_interrupt_cause);
+ spin_unlock_irqrestore(&acb->doneq_lock, flags);
}
static void
@@ -2675,33 +2685,96 @@ arcmsr_iop_message_xfer(struct AdapterCo
}
ptmpQbuffer = ver_addr;
spin_lock_irqsave(&acb->rqbuffer_lock, flags);
- while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex)
- && (allxfer_len < 1031)) {
+ if (acb->rqbuf_firstindex != acb->rqbuf_lastindex) {
pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex];
- memcpy(ptmpQbuffer, pQbuffer, 1);
- acb->rqbuf_firstindex++;
- acb->rqbuf_firstindex %= ARCMSR_MAX_QBUFFER;
- ptmpQbuffer++;
- allxfer_len++;
+ if (acb->rqbuf_firstindex > acb->rqbuf_lastindex) {
+ if ((ARCMSR_MAX_QBUFFER -
+ acb->rqbuf_firstindex) >= 1032) {
+ memcpy(ptmpQbuffer, pQbuffer, 1032);
+ acb->rqbuf_firstindex += 1032;
+ allxfer_len = 1032;
+ } else {
+ if (((ARCMSR_MAX_QBUFFER -
+ acb->rqbuf_firstindex)
+ + acb->rqbuf_lastindex) > 1032) {
+ memcpy(ptmpQbuffer, pQbuffer,
+ ARCMSR_MAX_QBUFFER
+ - acb->rqbuf_firstindex);
+ ptmpQbuffer += ARCMSR_MAX_QBUFFER
+ - acb->rqbuf_firstindex;
+ memcpy(ptmpQbuffer, acb->rqbuffer,
+ 1032 - (ARCMSR_MAX_QBUFFER
+ - acb->rqbuf_firstindex));
+ acb->rqbuf_firstindex = 1032 -
+ (ARCMSR_MAX_QBUFFER
+ - acb->rqbuf_firstindex);
+ allxfer_len = 1032;
+ } else {
+ memcpy(ptmpQbuffer, pQbuffer,
+ ARCMSR_MAX_QBUFFER
+ - acb->rqbuf_firstindex);
+ ptmpQbuffer += ARCMSR_MAX_QBUFFER
+ - acb->rqbuf_firstindex;
+ memcpy(ptmpQbuffer, acb->rqbuffer,
+ acb->rqbuf_lastindex);
+ allxfer_len = ARCMSR_MAX_QBUFFER
+ - acb->rqbuf_firstindex
+ + acb->rqbuf_lastindex;
+ acb->rqbuf_firstindex =
+ acb->rqbuf_lastindex;
+ }
+ }
+ } else {
+ if ((acb->rqbuf_lastindex
+ - acb->rqbuf_firstindex) > 1032) {
+ memcpy(ptmpQbuffer,
+ pQbuffer, 1032);
+ acb->rqbuf_firstindex += 1032;
+ allxfer_len = 1032;
+ } else {
+ memcpy(ptmpQbuffer,
+ pQbuffer,
+ acb->rqbuf_lastindex
+ - acb->rqbuf_firstindex);
+ allxfer_len = acb->rqbuf_lastindex
+ - acb->rqbuf_firstindex;
+ acb->rqbuf_firstindex
+ = acb->rqbuf_lastindex;
+ }
+ }
}
if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
-
struct QBUFFER __iomem *prbuffer;
- uint8_t __iomem *iop_data;
- int32_t iop_len;
-
+ uint8_t __iomem *iop_data, *vaddr, *temp;
+ uint32_t data_len, rqbuf_lastindex;
acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
+ rqbuf_lastindex = acb->rqbuf_lastindex;
prbuffer = arcmsr_get_iop_rqbuffer(acb);
- iop_data = prbuffer->data;
- iop_len = ioread32(&prbuffer->data_len);
- while (iop_len > 0) {
- acb->rqbuffer[acb->rqbuf_lastindex] =
- ioread8(iop_data);
- acb->rqbuf_lastindex++;
- acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
- iop_data++;
- iop_len--;
+ iop_data = (uint8_t __iomem *)prbuffer->data;
+ data_len = ioread32(&prbuffer->data_len);
+ if (data_len > 0) {
+ temp = vaddr = kmalloc(data_len, GFP_ATOMIC);
+ memcpy(vaddr, iop_data, data_len);
+ smp_mb();
+ pQbuffer = &acb->rqbuffer[acb->rqbuf_lastindex];
+ if ((rqbuf_lastindex + data_len) >
+ ARCMSR_MAX_QBUFFER) {
+ memcpy(pQbuffer, temp,
+ ARCMSR_MAX_QBUFFER - rqbuf_lastindex);
+ temp += (ARCMSR_MAX_QBUFFER
+ - rqbuf_lastindex);
+ rqbuf_lastindex = (rqbuf_lastindex
+ + data_len) % ARCMSR_MAX_QBUFFER;
+ memcpy(&acb->rqbuffer[0],
+ temp, rqbuf_lastindex);
+ } else {
+ memcpy(pQbuffer, temp, data_len);
+ rqbuf_lastindex = (rqbuf_lastindex +
+ data_len) % ARCMSR_MAX_QBUFFER;
+ }
+ kfree(vaddr);
}
+ acb->rqbuf_lastindex = rqbuf_lastindex;
arcmsr_iop_message_read(acb);
}
spin_unlock_irqrestore(&acb->rqbuffer_lock, flags);
@@ -3623,19 +3696,21 @@ arcmsr_hbaD_polling_ccbdone(struct Adapt
{
bool error;
uint32_t poll_ccb_done = 0, poll_count = 0, flag_ccb, ccb_cdb_phy;
- int rtn, index, outbound_write_pointer;
+ int rtn, doneq_index, index_stripped, outbound_write_pointer;
+ unsigned long flags;
struct ARCMSR_CDB *arcmsr_cdb;
struct CommandControlBlock *pCCB;
- struct MessageUnit_D __iomem *reg =
+ struct MessageUnit_D __iomem *pmu =
(struct MessageUnit_D *)acb->pmuD;
+ spin_lock_irqsave(&acb->doneq_lock, flags);
polling_hbaD_ccb_retry:
poll_count++;
while (1) {
outbound_write_pointer =
- ioread32(reg->outboundlist_copy_pointer);
- index = reg->doneq_index;
- if ((outbound_write_pointer & 0xFF) == index) {
+ pmu->done_qbuffer[0].addressLow + 1;
+ doneq_index = pmu->doneq_index;
+ if ((outbound_write_pointer & 0xFFF) == (doneq_index & 0xFFF)) {
if (poll_ccb_done) {
rtn = SUCCESS;
break;
@@ -3648,17 +3723,27 @@ arcmsr_hbaD_polling_ccbdone(struct Adapt
goto polling_hbaD_ccb_retry;
}
}
- flag_ccb = reg->done_qbuffer[index].addressLow;
+ if (doneq_index & 0x4000) {
+ index_stripped = doneq_index & 0xFFF;
+ index_stripped += 1;
+ index_stripped %= ARCMSR_MAX_ARC1214_DONEQUEUE;
+ pmu->doneq_index = index_stripped ? (index_stripped | 0x4000)
+ : (index_stripped + 1);
+ } else {
+ index_stripped = doneq_index;
+ index_stripped += 1;
+ index_stripped %= ARCMSR_MAX_ARC1214_DONEQUEUE;
+ pmu->doneq_index = index_stripped ? index_stripped :
+ ((index_stripped | 0x4000) + 1);
+ }
+ doneq_index = pmu->doneq_index;
+ flag_ccb = pmu->done_qbuffer[doneq_index & 0xFFF].addressLow;
ccb_cdb_phy = (flag_ccb & 0xFFFFFFF0);
arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset +
ccb_cdb_phy);
pCCB = container_of(arcmsr_cdb,
struct CommandControlBlock, arcmsr_cdb);
poll_ccb_done = (pCCB == poll_ccb) ? 1 : 0;
- index++;
- index %= ARCMSR_MAX_ARC1214_POSTQUEUE;
- reg->doneq_index = index;
- /* check if command done with no error*/
if ((pCCB->acb != acb) ||
(pCCB->startdone != ARCMSR_CCB_START)) {
if (pCCB->startdone == ARCMSR_CCB_ABORTED) {
@@ -3685,6 +3770,7 @@ arcmsr_hbaD_polling_ccbdone(struct Adapt
? true : false;
arcmsr_report_ccb_state(acb, pCCB, error);
}
+ spin_unlock_irqrestore(&acb->doneq_lock, flags);
return rtn;
}
@@ -3817,7 +3903,7 @@ arcmsr_iop_confirm(struct AdapterControl
struct MessageUnit_D *reg =
(struct MessageUnit_D *)acb->pmuD;
reg->postq_index = 0;
- reg->doneq_index = 0x40FF;
+ reg->doneq_index = 0;
rwbuffer = reg->msgcode_rwbuffer;
iowrite32(ARCMSR_SIGNATURE_SET_CONFIG, rwbuffer++);
iowrite32(cdb_phyaddr_hi32, rwbuffer++);
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2012-11-30 9:18 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-11-15 7:33 [PATCH 5/5] arcmsr: Modify ARC-1214 IO Behavior NickCheng
2012-11-16 11:56 NickCheng
2012-11-30 9:18 ` James Bottomley
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®