aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChing Huang <ching2048@areca.com.tw>2014-08-19 03:17:45 -0400
committerChristoph Hellwig <hch@lst.de>2014-09-16 12:40:01 -0400
commitbb263c4ecbb186fe394c6c9acc32d8c59b6a7bdd (patch)
treedd1841d010aae6c78fd2f13b5f5e3b7b32b23754
parent6e38adfc58406e7ea6f6701c49abaf046ce076a8 (diff)
arcmsr: fix ioctl data read/write error for adapter type C
Rewrite ioctl entry and its relate function. This patch fix ioctl data read/write error and change data I/O access from byte to Dword. Signed-off-by: Ching Huang <ching2048@areca.com.tw> Reviewed-by: Tomas Henzl <thenzl@redhat.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
-rw-r--r--drivers/scsi/arcmsr/arcmsr.h8
-rw-r--r--drivers/scsi/arcmsr/arcmsr_attr.c101
-rw-r--r--drivers/scsi/arcmsr/arcmsr_hba.c572
3 files changed, 442 insertions, 239 deletions
diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
index 83c0a7dbfef3..799393ede1cc 100644
--- a/drivers/scsi/arcmsr/arcmsr.h
+++ b/drivers/scsi/arcmsr/arcmsr.h
@@ -518,6 +518,8 @@ struct AdapterControlBlock
518 uint32_t reg_mu_acc_handle0; 518 uint32_t reg_mu_acc_handle0;
519 spinlock_t eh_lock; 519 spinlock_t eh_lock;
520 spinlock_t ccblist_lock; 520 spinlock_t ccblist_lock;
521 spinlock_t rqbuffer_lock;
522 spinlock_t wqbuffer_lock;
521 union { 523 union {
522 struct MessageUnit_A __iomem *pmuA; 524 struct MessageUnit_A __iomem *pmuA;
523 struct MessageUnit_B *pmuB; 525 struct MessageUnit_B *pmuB;
@@ -693,8 +695,10 @@ struct SENSE_DATA
693#define ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE 0x01 695#define ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE 0x01
694#define ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE 0x1F 696#define ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE 0x1F
695 697
696extern void arcmsr_post_ioctldata2iop(struct AdapterControlBlock *); 698extern void arcmsr_write_ioctldata2iop(struct AdapterControlBlock *);
697extern void arcmsr_iop_message_read(struct AdapterControlBlock *); 699extern uint32_t arcmsr_Read_iop_rqbuffer_data(struct AdapterControlBlock *,
700 struct QBUFFER __iomem *);
701extern void arcmsr_clear_iop2drv_rqueue_buffer(struct AdapterControlBlock *);
698extern struct QBUFFER __iomem *arcmsr_get_iop_rqbuffer(struct AdapterControlBlock *); 702extern struct QBUFFER __iomem *arcmsr_get_iop_rqbuffer(struct AdapterControlBlock *);
699extern struct device_attribute *arcmsr_host_attrs[]; 703extern struct device_attribute *arcmsr_host_attrs[];
700extern int arcmsr_alloc_sysfs_attr(struct AdapterControlBlock *); 704extern int arcmsr_alloc_sysfs_attr(struct AdapterControlBlock *);
diff --git a/drivers/scsi/arcmsr/arcmsr_attr.c b/drivers/scsi/arcmsr/arcmsr_attr.c
index acdae33de521..16422adcc531 100644
--- a/drivers/scsi/arcmsr/arcmsr_attr.c
+++ b/drivers/scsi/arcmsr/arcmsr_attr.c
@@ -70,40 +70,75 @@ static ssize_t arcmsr_sysfs_iop_message_read(struct file *filp,
70 struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; 70 struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata;
71 uint8_t *pQbuffer,*ptmpQbuffer; 71 uint8_t *pQbuffer,*ptmpQbuffer;
72 int32_t allxfer_len = 0; 72 int32_t allxfer_len = 0;
73 unsigned long flags;
73 74
74 if (!capable(CAP_SYS_ADMIN)) 75 if (!capable(CAP_SYS_ADMIN))
75 return -EACCES; 76 return -EACCES;
76 77
77 /* do message unit read. */ 78 /* do message unit read. */
78 ptmpQbuffer = (uint8_t *)buf; 79 ptmpQbuffer = (uint8_t *)buf;
79 while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex) 80 spin_lock_irqsave(&acb->rqbuffer_lock, flags);
80 && (allxfer_len < 1031)) { 81 if (acb->rqbuf_firstindex != acb->rqbuf_lastindex) {
81 pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex]; 82 pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex];
82 memcpy(ptmpQbuffer, pQbuffer, 1); 83 if (acb->rqbuf_firstindex > acb->rqbuf_lastindex) {
83 acb->rqbuf_firstindex++; 84 if ((ARCMSR_MAX_QBUFFER - acb->rqbuf_firstindex) >= 1032) {
84 acb->rqbuf_firstindex %= ARCMSR_MAX_QBUFFER; 85 memcpy(ptmpQbuffer, pQbuffer, 1032);
85 ptmpQbuffer++; 86 acb->rqbuf_firstindex += 1032;
86 allxfer_len++; 87 acb->rqbuf_firstindex %= ARCMSR_MAX_QBUFFER;
88 allxfer_len = 1032;
89 } else {
90 if (((ARCMSR_MAX_QBUFFER - acb->rqbuf_firstindex)
91 + acb->rqbuf_lastindex) > 1032) {
92 memcpy(ptmpQbuffer, pQbuffer,
93 ARCMSR_MAX_QBUFFER
94 - acb->rqbuf_firstindex);
95 ptmpQbuffer += ARCMSR_MAX_QBUFFER
96 - acb->rqbuf_firstindex;
97 memcpy(ptmpQbuffer, acb->rqbuffer, 1032
98 - (ARCMSR_MAX_QBUFFER -
99 acb->rqbuf_firstindex));
100 acb->rqbuf_firstindex = 1032 -
101 (ARCMSR_MAX_QBUFFER -
102 acb->rqbuf_firstindex);
103 allxfer_len = 1032;
104 } else {
105 memcpy(ptmpQbuffer, pQbuffer,
106 ARCMSR_MAX_QBUFFER -
107 acb->rqbuf_firstindex);
108 ptmpQbuffer += ARCMSR_MAX_QBUFFER -
109 acb->rqbuf_firstindex;
110 memcpy(ptmpQbuffer, acb->rqbuffer,
111 acb->rqbuf_lastindex);
112 allxfer_len = ARCMSR_MAX_QBUFFER -
113 acb->rqbuf_firstindex +
114 acb->rqbuf_lastindex;
115 acb->rqbuf_firstindex =
116 acb->rqbuf_lastindex;
117 }
118 }
119 } else {
120 if ((acb->rqbuf_lastindex - acb->rqbuf_firstindex) > 1032) {
121 memcpy(ptmpQbuffer, pQbuffer, 1032);
122 acb->rqbuf_firstindex += 1032;
123 allxfer_len = 1032;
124 } else {
125 memcpy(ptmpQbuffer, pQbuffer, acb->rqbuf_lastindex
126 - acb->rqbuf_firstindex);
127 allxfer_len = acb->rqbuf_lastindex -
128 acb->rqbuf_firstindex;
129 acb->rqbuf_firstindex = acb->rqbuf_lastindex;
130 }
131 }
87 } 132 }
88 if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { 133 if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
89 struct QBUFFER __iomem *prbuffer; 134 struct QBUFFER __iomem *prbuffer;
90 uint8_t __iomem *iop_data;
91 int32_t iop_len;
92
93 acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; 135 acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
94 prbuffer = arcmsr_get_iop_rqbuffer(acb); 136 prbuffer = arcmsr_get_iop_rqbuffer(acb);
95 iop_data = prbuffer->data; 137 if (arcmsr_Read_iop_rqbuffer_data(acb, prbuffer) == 0)
96 iop_len = readl(&prbuffer->data_len); 138 acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW;
97 while (iop_len > 0) {
98 acb->rqbuffer[acb->rqbuf_lastindex] = readb(iop_data);
99 acb->rqbuf_lastindex++;
100 acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
101 iop_data++;
102 iop_len--;
103 }
104 arcmsr_iop_message_read(acb);
105 } 139 }
106 return (allxfer_len); 140 spin_unlock_irqrestore(&acb->rqbuffer_lock, flags);
141 return allxfer_len;
107} 142}
108 143
109static ssize_t arcmsr_sysfs_iop_message_write(struct file *filp, 144static ssize_t arcmsr_sysfs_iop_message_write(struct file *filp,
@@ -117,6 +152,7 @@ static ssize_t arcmsr_sysfs_iop_message_write(struct file *filp,
117 struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; 152 struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata;
118 int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex; 153 int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex;
119 uint8_t *pQbuffer, *ptmpuserbuffer; 154 uint8_t *pQbuffer, *ptmpuserbuffer;
155 unsigned long flags;
120 156
121 if (!capable(CAP_SYS_ADMIN)) 157 if (!capable(CAP_SYS_ADMIN))
122 return -EACCES; 158 return -EACCES;
@@ -125,18 +161,19 @@ static ssize_t arcmsr_sysfs_iop_message_write(struct file *filp,
125 /* do message unit write. */ 161 /* do message unit write. */
126 ptmpuserbuffer = (uint8_t *)buf; 162 ptmpuserbuffer = (uint8_t *)buf;
127 user_len = (int32_t)count; 163 user_len = (int32_t)count;
164 spin_lock_irqsave(&acb->wqbuffer_lock, flags);
128 wqbuf_lastindex = acb->wqbuf_lastindex; 165 wqbuf_lastindex = acb->wqbuf_lastindex;
129 wqbuf_firstindex = acb->wqbuf_firstindex; 166 wqbuf_firstindex = acb->wqbuf_firstindex;
130 if (wqbuf_lastindex != wqbuf_firstindex) { 167 if (wqbuf_lastindex != wqbuf_firstindex) {
131 arcmsr_post_ioctldata2iop(acb); 168 arcmsr_write_ioctldata2iop(acb);
169 spin_unlock_irqrestore(&acb->wqbuffer_lock, flags);
132 return 0; /*need retry*/ 170 return 0; /*need retry*/
133 } else { 171 } else {
134 my_empty_len = (wqbuf_firstindex-wqbuf_lastindex - 1) 172 my_empty_len = (wqbuf_firstindex-wqbuf_lastindex - 1)
135 &(ARCMSR_MAX_QBUFFER - 1); 173 &(ARCMSR_MAX_QBUFFER - 1);
136 if (my_empty_len >= user_len) { 174 if (my_empty_len >= user_len) {
137 while (user_len > 0) { 175 while (user_len > 0) {
138 pQbuffer = 176 pQbuffer = &acb->wqbuffer[acb->wqbuf_lastindex];
139 &acb->wqbuffer[acb->wqbuf_lastindex];
140 memcpy(pQbuffer, ptmpuserbuffer, 1); 177 memcpy(pQbuffer, ptmpuserbuffer, 1);
141 acb->wqbuf_lastindex++; 178 acb->wqbuf_lastindex++;
142 acb->wqbuf_lastindex %= ARCMSR_MAX_QBUFFER; 179 acb->wqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
@@ -146,10 +183,12 @@ static ssize_t arcmsr_sysfs_iop_message_write(struct file *filp,
146 if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_CLEARED) { 183 if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_CLEARED) {
147 acb->acb_flags &= 184 acb->acb_flags &=
148 ~ACB_F_MESSAGE_WQBUFFER_CLEARED; 185 ~ACB_F_MESSAGE_WQBUFFER_CLEARED;
149 arcmsr_post_ioctldata2iop(acb); 186 arcmsr_write_ioctldata2iop(acb);
150 } 187 }
188 spin_unlock_irqrestore(&acb->wqbuffer_lock, flags);
151 return count; 189 return count;
152 } else { 190 } else {
191 spin_unlock_irqrestore(&acb->wqbuffer_lock, flags);
153 return 0; /*need retry*/ 192 return 0; /*need retry*/
154 } 193 }
155 } 194 }
@@ -165,22 +204,24 @@ static ssize_t arcmsr_sysfs_iop_message_clear(struct file *filp,
165 struct Scsi_Host *host = class_to_shost(dev); 204 struct Scsi_Host *host = class_to_shost(dev);
166 struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; 205 struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata;
167 uint8_t *pQbuffer; 206 uint8_t *pQbuffer;
207 unsigned long flags;
168 208
169 if (!capable(CAP_SYS_ADMIN)) 209 if (!capable(CAP_SYS_ADMIN))
170 return -EACCES; 210 return -EACCES;
171 211
172 if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { 212 arcmsr_clear_iop2drv_rqueue_buffer(acb);
173 acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
174 arcmsr_iop_message_read(acb);
175 }
176 acb->acb_flags |= 213 acb->acb_flags |=
177 (ACB_F_MESSAGE_WQBUFFER_CLEARED 214 (ACB_F_MESSAGE_WQBUFFER_CLEARED
178 | ACB_F_MESSAGE_RQBUFFER_CLEARED 215 | ACB_F_MESSAGE_RQBUFFER_CLEARED
179 | ACB_F_MESSAGE_WQBUFFER_READED); 216 | ACB_F_MESSAGE_WQBUFFER_READED);
217 spin_lock_irqsave(&acb->rqbuffer_lock, flags);
180 acb->rqbuf_firstindex = 0; 218 acb->rqbuf_firstindex = 0;
181 acb->rqbuf_lastindex = 0; 219 acb->rqbuf_lastindex = 0;
220 spin_unlock_irqrestore(&acb->rqbuffer_lock, flags);
221 spin_lock_irqsave(&acb->wqbuffer_lock, flags);
182 acb->wqbuf_firstindex = 0; 222 acb->wqbuf_firstindex = 0;
183 acb->wqbuf_lastindex = 0; 223 acb->wqbuf_lastindex = 0;
224 spin_unlock_irqrestore(&acb->wqbuffer_lock, flags);
184 pQbuffer = acb->rqbuffer; 225 pQbuffer = acb->rqbuffer;
185 memset(pQbuffer, 0, sizeof (struct QBUFFER)); 226 memset(pQbuffer, 0, sizeof (struct QBUFFER));
186 pQbuffer = acb->wqbuffer; 227 pQbuffer = acb->wqbuffer;
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index fc0dfbc70feb..1576805efc7d 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -653,6 +653,8 @@ static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
653 } 653 }
654 spin_lock_init(&acb->eh_lock); 654 spin_lock_init(&acb->eh_lock);
655 spin_lock_init(&acb->ccblist_lock); 655 spin_lock_init(&acb->ccblist_lock);
656 spin_lock_init(&acb->rqbuffer_lock);
657 spin_lock_init(&acb->wqbuffer_lock);
656 acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED | 658 acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED |
657 ACB_F_MESSAGE_RQBUFFER_CLEARED | 659 ACB_F_MESSAGE_RQBUFFER_CLEARED |
658 ACB_F_MESSAGE_WQBUFFER_READED); 660 ACB_F_MESSAGE_WQBUFFER_READED);
@@ -1449,68 +1451,175 @@ static struct QBUFFER __iomem *arcmsr_get_iop_wqbuffer(struct AdapterControlBloc
1449 return pqbuffer; 1451 return pqbuffer;
1450} 1452}
1451 1453
1452static void arcmsr_iop2drv_data_wrote_handle(struct AdapterControlBlock *acb) 1454static uint32_t
1455arcmsr_Read_iop_rqbuffer_in_DWORD(struct AdapterControlBlock *acb,
1456 struct QBUFFER __iomem *prbuffer)
1453{ 1457{
1454 struct QBUFFER __iomem *prbuffer; 1458 uint8_t *pQbuffer;
1455 struct QBUFFER *pQbuffer; 1459 uint8_t *buf1 = NULL;
1456 uint8_t __iomem *iop_data; 1460 uint32_t __iomem *iop_data;
1457 int32_t my_empty_len, iop_len, rqbuf_firstindex, rqbuf_lastindex; 1461 uint32_t iop_len, data_len, *buf2 = NULL;
1458 rqbuf_lastindex = acb->rqbuf_lastindex; 1462
1459 rqbuf_firstindex = acb->rqbuf_firstindex; 1463 iop_data = (uint32_t __iomem *)prbuffer->data;
1460 prbuffer = arcmsr_get_iop_rqbuffer(acb); 1464 iop_len = readl(&prbuffer->data_len);
1461 iop_data = (uint8_t __iomem *)prbuffer->data; 1465 if (iop_len > 0) {
1462 iop_len = prbuffer->data_len; 1466 buf1 = kmalloc(128, GFP_ATOMIC);
1463 my_empty_len = (rqbuf_firstindex - rqbuf_lastindex - 1) & (ARCMSR_MAX_QBUFFER - 1); 1467 buf2 = (uint32_t *)buf1;
1464 1468 if (buf1 == NULL)
1465 if (my_empty_len >= iop_len) 1469 return 0;
1466 { 1470 data_len = iop_len;
1467 while (iop_len > 0) { 1471 while (data_len >= 4) {
1468 pQbuffer = (struct QBUFFER *)&acb->rqbuffer[rqbuf_lastindex]; 1472 *buf2++ = readl(iop_data);
1469 memcpy(pQbuffer, iop_data, 1);
1470 rqbuf_lastindex++;
1471 rqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
1472 iop_data++; 1473 iop_data++;
1473 iop_len--; 1474 data_len -= 4;
1474 } 1475 }
1475 acb->rqbuf_lastindex = rqbuf_lastindex; 1476 if (data_len)
1476 arcmsr_iop_message_read(acb); 1477 *buf2 = readl(iop_data);
1478 buf2 = (uint32_t *)buf1;
1479 }
1480 while (iop_len > 0) {
1481 pQbuffer = &acb->rqbuffer[acb->rqbuf_lastindex];
1482 *pQbuffer = *buf1;
1483 acb->rqbuf_lastindex++;
1484 /* if last, index number set it to 0 */
1485 acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
1486 buf1++;
1487 iop_len--;
1488 }
1489 if (buf2)
1490 kfree(buf2);
1491 /* let IOP know data has been read */
1492 arcmsr_iop_message_read(acb);
1493 return 1;
1494}
1495
1496uint32_t
1497arcmsr_Read_iop_rqbuffer_data(struct AdapterControlBlock *acb,
1498 struct QBUFFER __iomem *prbuffer) {
1499
1500 uint8_t *pQbuffer;
1501 uint8_t __iomem *iop_data;
1502 uint32_t iop_len;
1503
1504 if (acb->adapter_type & ACB_ADAPTER_TYPE_C)
1505 return arcmsr_Read_iop_rqbuffer_in_DWORD(acb, prbuffer);
1506 iop_data = (uint8_t __iomem *)prbuffer->data;
1507 iop_len = readl(&prbuffer->data_len);
1508 while (iop_len > 0) {
1509 pQbuffer = &acb->rqbuffer[acb->rqbuf_lastindex];
1510 *pQbuffer = readb(iop_data);
1511 acb->rqbuf_lastindex++;
1512 acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
1513 iop_data++;
1514 iop_len--;
1477 } 1515 }
1516 arcmsr_iop_message_read(acb);
1517 return 1;
1518}
1478 1519
1479 else { 1520static void arcmsr_iop2drv_data_wrote_handle(struct AdapterControlBlock *acb)
1521{
1522 unsigned long flags;
1523 struct QBUFFER __iomem *prbuffer;
1524 int32_t buf_empty_len;
1525
1526 spin_lock_irqsave(&acb->rqbuffer_lock, flags);
1527 prbuffer = arcmsr_get_iop_rqbuffer(acb);
1528 buf_empty_len = (acb->rqbuf_lastindex - acb->rqbuf_firstindex - 1) &
1529 (ARCMSR_MAX_QBUFFER - 1);
1530 if (buf_empty_len >= readl(&prbuffer->data_len)) {
1531 if (arcmsr_Read_iop_rqbuffer_data(acb, prbuffer) == 0)
1532 acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW;
1533 } else
1480 acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW; 1534 acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW;
1535 spin_unlock_irqrestore(&acb->rqbuffer_lock, flags);
1536}
1537
1538static void arcmsr_write_ioctldata2iop_in_DWORD(struct AdapterControlBlock *acb)
1539{
1540 uint8_t *pQbuffer;
1541 struct QBUFFER __iomem *pwbuffer;
1542 uint8_t *buf1 = NULL;
1543 uint32_t __iomem *iop_data;
1544 uint32_t allxfer_len = 0, data_len, *buf2 = NULL, data;
1545
1546 if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_READED) {
1547 buf1 = kmalloc(128, GFP_ATOMIC);
1548 buf2 = (uint32_t *)buf1;
1549 if (buf1 == NULL)
1550 return;
1551
1552 acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READED);
1553 pwbuffer = arcmsr_get_iop_wqbuffer(acb);
1554 iop_data = (uint32_t __iomem *)pwbuffer->data;
1555 while ((acb->wqbuf_firstindex != acb->wqbuf_lastindex)
1556 && (allxfer_len < 124)) {
1557 pQbuffer = &acb->wqbuffer[acb->wqbuf_firstindex];
1558 *buf1 = *pQbuffer;
1559 acb->wqbuf_firstindex++;
1560 acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER;
1561 buf1++;
1562 allxfer_len++;
1563 }
1564 data_len = allxfer_len;
1565 buf1 = (uint8_t *)buf2;
1566 while (data_len >= 4) {
1567 data = *buf2++;
1568 writel(data, iop_data);
1569 iop_data++;
1570 data_len -= 4;
1571 }
1572 if (data_len) {
1573 data = *buf2;
1574 writel(data, iop_data);
1575 }
1576 writel(allxfer_len, &pwbuffer->data_len);
1577 kfree(buf1);
1578 arcmsr_iop_message_wrote(acb);
1481 } 1579 }
1482} 1580}
1483 1581
1484static void arcmsr_iop2drv_data_read_handle(struct AdapterControlBlock *acb) 1582void
1583arcmsr_write_ioctldata2iop(struct AdapterControlBlock *acb)
1485{ 1584{
1486 acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_READED; 1585 uint8_t *pQbuffer;
1487 if (acb->wqbuf_firstindex != acb->wqbuf_lastindex) { 1586 struct QBUFFER __iomem *pwbuffer;
1488 uint8_t *pQbuffer; 1587 uint8_t __iomem *iop_data;
1489 struct QBUFFER __iomem *pwbuffer; 1588 int32_t allxfer_len = 0;
1490 uint8_t __iomem *iop_data;
1491 int32_t allxfer_len = 0;
1492 1589
1590 if (acb->adapter_type & ACB_ADAPTER_TYPE_C) {
1591 arcmsr_write_ioctldata2iop_in_DWORD(acb);
1592 return;
1593 }
1594 if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_READED) {
1493 acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READED); 1595 acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READED);
1494 pwbuffer = arcmsr_get_iop_wqbuffer(acb); 1596 pwbuffer = arcmsr_get_iop_wqbuffer(acb);
1495 iop_data = (uint8_t __iomem *)pwbuffer->data; 1597 iop_data = (uint8_t __iomem *)pwbuffer->data;
1496 1598 while ((acb->wqbuf_firstindex != acb->wqbuf_lastindex)
1497 while ((acb->wqbuf_firstindex != acb->wqbuf_lastindex) && \ 1599 && (allxfer_len < 124)) {
1498 (allxfer_len < 124)) {
1499 pQbuffer = &acb->wqbuffer[acb->wqbuf_firstindex]; 1600 pQbuffer = &acb->wqbuffer[acb->wqbuf_firstindex];
1500 memcpy(iop_data, pQbuffer, 1); 1601 writeb(*pQbuffer, iop_data);
1501 acb->wqbuf_firstindex++; 1602 acb->wqbuf_firstindex++;
1502 acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER; 1603 acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER;
1503 iop_data++; 1604 iop_data++;
1504 allxfer_len++; 1605 allxfer_len++;
1505 } 1606 }
1506 pwbuffer->data_len = allxfer_len; 1607 writel(allxfer_len, &pwbuffer->data_len);
1507
1508 arcmsr_iop_message_wrote(acb); 1608 arcmsr_iop_message_wrote(acb);
1509 } 1609 }
1610}
1611
1612static void arcmsr_iop2drv_data_read_handle(struct AdapterControlBlock *acb)
1613{
1614 unsigned long flags;
1510 1615
1511 if (acb->wqbuf_firstindex == acb->wqbuf_lastindex) { 1616 spin_lock_irqsave(&acb->wqbuffer_lock, flags);
1617 acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_READED;
1618 if (acb->wqbuf_firstindex != acb->wqbuf_lastindex)
1619 arcmsr_write_ioctldata2iop(acb);
1620 if (acb->wqbuf_firstindex == acb->wqbuf_lastindex)
1512 acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_CLEARED; 1621 acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_CLEARED;
1513 } 1622 spin_unlock_irqrestore(&acb->wqbuffer_lock, flags);
1514} 1623}
1515 1624
1516static void arcmsr_hbaA_doorbell_isr(struct AdapterControlBlock *acb) 1625static void arcmsr_hbaA_doorbell_isr(struct AdapterControlBlock *acb)
@@ -1768,296 +1877,345 @@ static void arcmsr_iop_parking(struct AdapterControlBlock *acb)
1768 } 1877 }
1769} 1878}
1770 1879
1771void arcmsr_post_ioctldata2iop(struct AdapterControlBlock *acb) 1880
1881void arcmsr_clear_iop2drv_rqueue_buffer(struct AdapterControlBlock *acb)
1772{ 1882{
1773 int32_t wqbuf_firstindex, wqbuf_lastindex; 1883 uint32_t i;
1774 uint8_t *pQbuffer; 1884
1775 struct QBUFFER __iomem *pwbuffer; 1885 if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
1776 uint8_t __iomem *iop_data; 1886 for (i = 0; i < 15; i++) {
1777 int32_t allxfer_len = 0; 1887 if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
1778 pwbuffer = arcmsr_get_iop_wqbuffer(acb); 1888 acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
1779 iop_data = (uint8_t __iomem *)pwbuffer->data; 1889 acb->rqbuf_firstindex = 0;
1780 if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_READED) { 1890 acb->rqbuf_lastindex = 0;
1781 acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READED); 1891 arcmsr_iop_message_read(acb);
1782 wqbuf_firstindex = acb->wqbuf_firstindex; 1892 mdelay(30);
1783 wqbuf_lastindex = acb->wqbuf_lastindex; 1893 } else if (acb->rqbuf_firstindex !=
1784 while ((wqbuf_firstindex != wqbuf_lastindex) && (allxfer_len < 124)) { 1894 acb->rqbuf_lastindex) {
1785 pQbuffer = &acb->wqbuffer[wqbuf_firstindex]; 1895 acb->rqbuf_firstindex = 0;
1786 memcpy(iop_data, pQbuffer, 1); 1896 acb->rqbuf_lastindex = 0;
1787 wqbuf_firstindex++; 1897 mdelay(30);
1788 wqbuf_firstindex %= ARCMSR_MAX_QBUFFER; 1898 } else
1789 iop_data++; 1899 break;
1790 allxfer_len++;
1791 } 1900 }
1792 acb->wqbuf_firstindex = wqbuf_firstindex;
1793 pwbuffer->data_len = allxfer_len;
1794 arcmsr_iop_message_wrote(acb);
1795 } 1901 }
1796} 1902}
1797 1903
1798static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, 1904static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb,
1799 struct scsi_cmnd *cmd) 1905 struct scsi_cmnd *cmd)
1800{ 1906{
1801 struct CMD_MESSAGE_FIELD *pcmdmessagefld;
1802 int retvalue = 0, transfer_len = 0;
1803 char *buffer; 1907 char *buffer;
1908 unsigned short use_sg;
1909 int retvalue = 0, transfer_len = 0;
1910 unsigned long flags;
1911 struct CMD_MESSAGE_FIELD *pcmdmessagefld;
1912 uint32_t controlcode = (uint32_t)cmd->cmnd[5] << 24 |
1913 (uint32_t)cmd->cmnd[6] << 16 |
1914 (uint32_t)cmd->cmnd[7] << 8 |
1915 (uint32_t)cmd->cmnd[8];
1804 struct scatterlist *sg; 1916 struct scatterlist *sg;
1805 uint32_t controlcode = (uint32_t ) cmd->cmnd[5] << 24 | 1917
1806 (uint32_t ) cmd->cmnd[6] << 16 | 1918 use_sg = scsi_sg_count(cmd);
1807 (uint32_t ) cmd->cmnd[7] << 8 |
1808 (uint32_t ) cmd->cmnd[8];
1809 /* 4 bytes: Areca io control code */
1810 sg = scsi_sglist(cmd); 1919 sg = scsi_sglist(cmd);
1811 buffer = kmap_atomic(sg_page(sg)) + sg->offset; 1920 buffer = kmap_atomic(sg_page(sg)) + sg->offset;
1812 if (scsi_sg_count(cmd) > 1) { 1921 if (use_sg > 1) {
1813 retvalue = ARCMSR_MESSAGE_FAIL; 1922 retvalue = ARCMSR_MESSAGE_FAIL;
1814 goto message_out; 1923 goto message_out;
1815 } 1924 }
1816 transfer_len += sg->length; 1925 transfer_len += sg->length;
1817
1818 if (transfer_len > sizeof(struct CMD_MESSAGE_FIELD)) { 1926 if (transfer_len > sizeof(struct CMD_MESSAGE_FIELD)) {
1819 retvalue = ARCMSR_MESSAGE_FAIL; 1927 retvalue = ARCMSR_MESSAGE_FAIL;
1928 pr_info("%s: ARCMSR_MESSAGE_FAIL!\n", __func__);
1820 goto message_out; 1929 goto message_out;
1821 } 1930 }
1822 pcmdmessagefld = (struct CMD_MESSAGE_FIELD *) buffer; 1931 pcmdmessagefld = (struct CMD_MESSAGE_FIELD *)buffer;
1823 switch(controlcode) { 1932 switch (controlcode) {
1824
1825 case ARCMSR_MESSAGE_READ_RQBUFFER: { 1933 case ARCMSR_MESSAGE_READ_RQBUFFER: {
1826 unsigned char *ver_addr; 1934 unsigned char *ver_addr;
1827 uint8_t *pQbuffer, *ptmpQbuffer; 1935 uint8_t *pQbuffer, *ptmpQbuffer;
1828 int32_t allxfer_len = 0; 1936 uint32_t allxfer_len = 0;
1829
1830 ver_addr = kmalloc(1032, GFP_ATOMIC); 1937 ver_addr = kmalloc(1032, GFP_ATOMIC);
1831 if (!ver_addr) { 1938 if (!ver_addr) {
1832 retvalue = ARCMSR_MESSAGE_FAIL; 1939 retvalue = ARCMSR_MESSAGE_FAIL;
1940 pr_info("%s: memory not enough!\n", __func__);
1833 goto message_out; 1941 goto message_out;
1834 } 1942 }
1835
1836 ptmpQbuffer = ver_addr; 1943 ptmpQbuffer = ver_addr;
1837 while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex) 1944 spin_lock_irqsave(&acb->rqbuffer_lock, flags);
1838 && (allxfer_len < 1031)) { 1945 if (acb->rqbuf_firstindex != acb->rqbuf_lastindex) {
1839 pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex]; 1946 pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex];
1840 memcpy(ptmpQbuffer, pQbuffer, 1); 1947 if (acb->rqbuf_firstindex > acb->rqbuf_lastindex) {
1841 acb->rqbuf_firstindex++; 1948 if ((ARCMSR_MAX_QBUFFER -
1842 acb->rqbuf_firstindex %= ARCMSR_MAX_QBUFFER; 1949 acb->rqbuf_firstindex) >= 1032) {
1843 ptmpQbuffer++; 1950 memcpy(ptmpQbuffer, pQbuffer, 1032);
1844 allxfer_len++; 1951 acb->rqbuf_firstindex += 1032;
1952 acb->rqbuf_firstindex %= ARCMSR_MAX_QBUFFER;
1953 allxfer_len = 1032;
1954 } else {
1955 if (((ARCMSR_MAX_QBUFFER -
1956 acb->rqbuf_firstindex) +
1957 acb->rqbuf_lastindex) > 1032) {
1958 memcpy(ptmpQbuffer,
1959 pQbuffer, ARCMSR_MAX_QBUFFER
1960 - acb->rqbuf_firstindex);
1961 ptmpQbuffer +=
1962 ARCMSR_MAX_QBUFFER -
1963 acb->rqbuf_firstindex;
1964 memcpy(ptmpQbuffer,
1965 acb->rqbuffer, 1032 -
1966 (ARCMSR_MAX_QBUFFER
1967 - acb->rqbuf_firstindex));
1968 acb->rqbuf_firstindex =
1969 1032 - (ARCMSR_MAX_QBUFFER
1970 - acb->rqbuf_firstindex);
1971 allxfer_len = 1032;
1972 } else {
1973 memcpy(ptmpQbuffer,
1974 pQbuffer, ARCMSR_MAX_QBUFFER
1975 - acb->rqbuf_firstindex);
1976 ptmpQbuffer +=
1977 ARCMSR_MAX_QBUFFER -
1978 acb->rqbuf_firstindex;
1979 memcpy(ptmpQbuffer,
1980 acb->rqbuffer,
1981 acb->rqbuf_lastindex);
1982 allxfer_len = ARCMSR_MAX_QBUFFER
1983 - acb->rqbuf_firstindex +
1984 acb->rqbuf_lastindex;
1985 acb->rqbuf_firstindex =
1986 acb->rqbuf_lastindex;
1987 }
1988 }
1989 } else {
1990 if ((acb->rqbuf_lastindex -
1991 acb->rqbuf_firstindex) > 1032) {
1992 memcpy(ptmpQbuffer, pQbuffer, 1032);
1993 acb->rqbuf_firstindex += 1032;
1994 allxfer_len = 1032;
1995 } else {
1996 memcpy(ptmpQbuffer, pQbuffer,
1997 acb->rqbuf_lastindex -
1998 acb->rqbuf_firstindex);
1999 allxfer_len = acb->rqbuf_lastindex
2000 - acb->rqbuf_firstindex;
2001 acb->rqbuf_firstindex =
2002 acb->rqbuf_lastindex;
2003 }
2004 }
1845 } 2005 }
2006 memcpy(pcmdmessagefld->messagedatabuffer, ver_addr,
2007 allxfer_len);
1846 if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { 2008 if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
1847
1848 struct QBUFFER __iomem *prbuffer; 2009 struct QBUFFER __iomem *prbuffer;
1849 uint8_t __iomem *iop_data;
1850 int32_t iop_len;
1851
1852 acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; 2010 acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
1853 prbuffer = arcmsr_get_iop_rqbuffer(acb); 2011 prbuffer = arcmsr_get_iop_rqbuffer(acb);
1854 iop_data = prbuffer->data; 2012 if (arcmsr_Read_iop_rqbuffer_data(acb, prbuffer) == 0)
1855 iop_len = readl(&prbuffer->data_len); 2013 acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW;
1856 while (iop_len > 0) {
1857 acb->rqbuffer[acb->rqbuf_lastindex] = readb(iop_data);
1858 acb->rqbuf_lastindex++;
1859 acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
1860 iop_data++;
1861 iop_len--;
1862 }
1863 arcmsr_iop_message_read(acb);
1864 }
1865 memcpy(pcmdmessagefld->messagedatabuffer, ver_addr, allxfer_len);
1866 pcmdmessagefld->cmdmessage.Length = allxfer_len;
1867 if(acb->fw_flag == FW_DEADLOCK) {
1868 pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
1869 }else{
1870 pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
1871 } 2014 }
2015 spin_unlock_irqrestore(&acb->rqbuffer_lock, flags);
1872 kfree(ver_addr); 2016 kfree(ver_addr);
1873 } 2017 pcmdmessagefld->cmdmessage.Length = allxfer_len;
2018 if (acb->fw_flag == FW_DEADLOCK)
2019 pcmdmessagefld->cmdmessage.ReturnCode =
2020 ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
2021 else
2022 pcmdmessagefld->cmdmessage.ReturnCode =
2023 ARCMSR_MESSAGE_RETURNCODE_OK;
1874 break; 2024 break;
1875 2025 }
1876 case ARCMSR_MESSAGE_WRITE_WQBUFFER: { 2026 case ARCMSR_MESSAGE_WRITE_WQBUFFER: {
1877 unsigned char *ver_addr; 2027 unsigned char *ver_addr;
1878 int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex; 2028 int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex;
1879 uint8_t *pQbuffer, *ptmpuserbuffer; 2029 uint8_t *pQbuffer, *ptmpuserbuffer;
1880
1881 ver_addr = kmalloc(1032, GFP_ATOMIC); 2030 ver_addr = kmalloc(1032, GFP_ATOMIC);
1882 if (!ver_addr) { 2031 if (!ver_addr) {
1883 retvalue = ARCMSR_MESSAGE_FAIL; 2032 retvalue = ARCMSR_MESSAGE_FAIL;
1884 goto message_out; 2033 goto message_out;
1885 } 2034 }
1886 if(acb->fw_flag == FW_DEADLOCK) {
1887 pcmdmessagefld->cmdmessage.ReturnCode =
1888 ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
1889 }else{
1890 pcmdmessagefld->cmdmessage.ReturnCode =
1891 ARCMSR_MESSAGE_RETURNCODE_OK;
1892 }
1893 ptmpuserbuffer = ver_addr; 2035 ptmpuserbuffer = ver_addr;
1894 user_len = pcmdmessagefld->cmdmessage.Length; 2036 user_len = pcmdmessagefld->cmdmessage.Length;
1895 memcpy(ptmpuserbuffer, pcmdmessagefld->messagedatabuffer, user_len); 2037 memcpy(ptmpuserbuffer,
2038 pcmdmessagefld->messagedatabuffer, user_len);
2039 spin_lock_irqsave(&acb->wqbuffer_lock, flags);
1896 wqbuf_lastindex = acb->wqbuf_lastindex; 2040 wqbuf_lastindex = acb->wqbuf_lastindex;
1897 wqbuf_firstindex = acb->wqbuf_firstindex; 2041 wqbuf_firstindex = acb->wqbuf_firstindex;
1898 if (wqbuf_lastindex != wqbuf_firstindex) { 2042 if (wqbuf_lastindex != wqbuf_firstindex) {
1899 struct SENSE_DATA *sensebuffer = 2043 struct SENSE_DATA *sensebuffer =
1900 (struct SENSE_DATA *)cmd->sense_buffer; 2044 (struct SENSE_DATA *)cmd->sense_buffer;
1901 arcmsr_post_ioctldata2iop(acb); 2045 arcmsr_write_ioctldata2iop(acb);
1902 /* has error report sensedata */ 2046 /* has error report sensedata */
1903 sensebuffer->ErrorCode = 0x70; 2047 sensebuffer->ErrorCode = SCSI_SENSE_CURRENT_ERRORS;
1904 sensebuffer->SenseKey = ILLEGAL_REQUEST; 2048 sensebuffer->SenseKey = ILLEGAL_REQUEST;
1905 sensebuffer->AdditionalSenseLength = 0x0A; 2049 sensebuffer->AdditionalSenseLength = 0x0A;
1906 sensebuffer->AdditionalSenseCode = 0x20; 2050 sensebuffer->AdditionalSenseCode = 0x20;
1907 sensebuffer->Valid = 1; 2051 sensebuffer->Valid = 1;
1908 retvalue = ARCMSR_MESSAGE_FAIL; 2052 retvalue = ARCMSR_MESSAGE_FAIL;
1909 } else { 2053 } else {
1910 my_empty_len = (wqbuf_firstindex-wqbuf_lastindex - 1) 2054 my_empty_len = (wqbuf_firstindex - wqbuf_lastindex - 1)
1911 &(ARCMSR_MAX_QBUFFER - 1); 2055 & (ARCMSR_MAX_QBUFFER - 1);
1912 if (my_empty_len >= user_len) { 2056 if (my_empty_len >= user_len) {
1913 while (user_len > 0) { 2057 while (user_len > 0) {
1914 pQbuffer = 2058 pQbuffer = &acb->wqbuffer[acb->wqbuf_lastindex];
1915 &acb->wqbuffer[acb->wqbuf_lastindex]; 2059 if ((acb->wqbuf_lastindex + user_len)
1916 memcpy(pQbuffer, ptmpuserbuffer, 1); 2060 > ARCMSR_MAX_QBUFFER) {
1917 acb->wqbuf_lastindex++; 2061 memcpy(pQbuffer, ptmpuserbuffer,
1918 acb->wqbuf_lastindex %= ARCMSR_MAX_QBUFFER; 2062 ARCMSR_MAX_QBUFFER -
1919 ptmpuserbuffer++; 2063 acb->wqbuf_lastindex);
1920 user_len--; 2064 ptmpuserbuffer +=
2065 (ARCMSR_MAX_QBUFFER
2066 - acb->wqbuf_lastindex);
2067 user_len -= (ARCMSR_MAX_QBUFFER
2068 - acb->wqbuf_lastindex);
2069 acb->wqbuf_lastindex = 0;
2070 } else {
2071 memcpy(pQbuffer, ptmpuserbuffer,
2072 user_len);
2073 acb->wqbuf_lastindex += user_len;
2074 acb->wqbuf_lastindex %=
2075 ARCMSR_MAX_QBUFFER;
2076 user_len = 0;
2077 }
1921 } 2078 }
1922 if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_CLEARED) { 2079 if (acb->acb_flags &
2080 ACB_F_MESSAGE_WQBUFFER_CLEARED) {
1923 acb->acb_flags &= 2081 acb->acb_flags &=
1924 ~ACB_F_MESSAGE_WQBUFFER_CLEARED; 2082 ~ACB_F_MESSAGE_WQBUFFER_CLEARED;
1925 arcmsr_post_ioctldata2iop(acb); 2083 arcmsr_write_ioctldata2iop(acb);
1926 } 2084 }
1927 } else { 2085 } else {
1928 /* has error report sensedata */
1929 struct SENSE_DATA *sensebuffer = 2086 struct SENSE_DATA *sensebuffer =
1930 (struct SENSE_DATA *)cmd->sense_buffer; 2087 (struct SENSE_DATA *)cmd->sense_buffer;
1931 sensebuffer->ErrorCode = 0x70; 2088 /* has error report sensedata */
2089 sensebuffer->ErrorCode =
2090 SCSI_SENSE_CURRENT_ERRORS;
1932 sensebuffer->SenseKey = ILLEGAL_REQUEST; 2091 sensebuffer->SenseKey = ILLEGAL_REQUEST;
1933 sensebuffer->AdditionalSenseLength = 0x0A; 2092 sensebuffer->AdditionalSenseLength = 0x0A;
1934 sensebuffer->AdditionalSenseCode = 0x20; 2093 sensebuffer->AdditionalSenseCode = 0x20;
1935 sensebuffer->Valid = 1; 2094 sensebuffer->Valid = 1;
1936 retvalue = ARCMSR_MESSAGE_FAIL; 2095 retvalue = ARCMSR_MESSAGE_FAIL;
1937 } 2096 }
1938 }
1939 kfree(ver_addr);
1940 } 2097 }
2098 spin_unlock_irqrestore(&acb->wqbuffer_lock, flags);
2099 kfree(ver_addr);
2100 if (acb->fw_flag == FW_DEADLOCK)
2101 pcmdmessagefld->cmdmessage.ReturnCode =
2102 ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
2103 else
2104 pcmdmessagefld->cmdmessage.ReturnCode =
2105 ARCMSR_MESSAGE_RETURNCODE_OK;
1941 break; 2106 break;
1942 2107 }
1943 case ARCMSR_MESSAGE_CLEAR_RQBUFFER: { 2108 case ARCMSR_MESSAGE_CLEAR_RQBUFFER: {
1944 uint8_t *pQbuffer = acb->rqbuffer; 2109 uint8_t *pQbuffer = acb->rqbuffer;
1945 if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { 2110
1946 acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; 2111 arcmsr_clear_iop2drv_rqueue_buffer(acb);
1947 arcmsr_iop_message_read(acb); 2112 spin_lock_irqsave(&acb->rqbuffer_lock, flags);
1948 }
1949 acb->acb_flags |= ACB_F_MESSAGE_RQBUFFER_CLEARED; 2113 acb->acb_flags |= ACB_F_MESSAGE_RQBUFFER_CLEARED;
1950 acb->rqbuf_firstindex = 0; 2114 acb->rqbuf_firstindex = 0;
1951 acb->rqbuf_lastindex = 0; 2115 acb->rqbuf_lastindex = 0;
1952 memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); 2116 memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER);
1953 if(acb->fw_flag == FW_DEADLOCK) { 2117 spin_unlock_irqrestore(&acb->rqbuffer_lock, flags);
2118 if (acb->fw_flag == FW_DEADLOCK)
1954 pcmdmessagefld->cmdmessage.ReturnCode = 2119 pcmdmessagefld->cmdmessage.ReturnCode =
1955 ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; 2120 ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
1956 }else{ 2121 else
1957 pcmdmessagefld->cmdmessage.ReturnCode = 2122 pcmdmessagefld->cmdmessage.ReturnCode =
1958 ARCMSR_MESSAGE_RETURNCODE_OK; 2123 ARCMSR_MESSAGE_RETURNCODE_OK;
1959 }
1960 }
1961 break; 2124 break;
1962 2125 }
1963 case ARCMSR_MESSAGE_CLEAR_WQBUFFER: { 2126 case ARCMSR_MESSAGE_CLEAR_WQBUFFER: {
1964 uint8_t *pQbuffer = acb->wqbuffer; 2127 uint8_t *pQbuffer = acb->wqbuffer;
1965 if(acb->fw_flag == FW_DEADLOCK) { 2128 spin_lock_irqsave(&acb->wqbuffer_lock, flags);
1966 pcmdmessagefld->cmdmessage.ReturnCode = 2129 acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED |
1967 ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; 2130 ACB_F_MESSAGE_WQBUFFER_READED);
1968 }else{
1969 pcmdmessagefld->cmdmessage.ReturnCode =
1970 ARCMSR_MESSAGE_RETURNCODE_OK;
1971 }
1972
1973 if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
1974 acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
1975 arcmsr_iop_message_read(acb);
1976 }
1977 acb->acb_flags |=
1978 (ACB_F_MESSAGE_WQBUFFER_CLEARED |
1979 ACB_F_MESSAGE_WQBUFFER_READED);
1980 acb->wqbuf_firstindex = 0; 2131 acb->wqbuf_firstindex = 0;
1981 acb->wqbuf_lastindex = 0; 2132 acb->wqbuf_lastindex = 0;
1982 memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); 2133 memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER);
1983 } 2134 spin_unlock_irqrestore(&acb->wqbuffer_lock, flags);
2135 if (acb->fw_flag == FW_DEADLOCK)
2136 pcmdmessagefld->cmdmessage.ReturnCode =
2137 ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
2138 else
2139 pcmdmessagefld->cmdmessage.ReturnCode =
2140 ARCMSR_MESSAGE_RETURNCODE_OK;
1984 break; 2141 break;
1985 2142 }
1986 case ARCMSR_MESSAGE_CLEAR_ALLQBUFFER: { 2143 case ARCMSR_MESSAGE_CLEAR_ALLQBUFFER: {
1987 uint8_t *pQbuffer; 2144 uint8_t *pQbuffer;
1988 2145 arcmsr_clear_iop2drv_rqueue_buffer(acb);
1989 if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { 2146 spin_lock_irqsave(&acb->rqbuffer_lock, flags);
1990 acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; 2147 acb->acb_flags |= ACB_F_MESSAGE_RQBUFFER_CLEARED;
1991 arcmsr_iop_message_read(acb);
1992 }
1993 acb->acb_flags |=
1994 (ACB_F_MESSAGE_WQBUFFER_CLEARED
1995 | ACB_F_MESSAGE_RQBUFFER_CLEARED
1996 | ACB_F_MESSAGE_WQBUFFER_READED);
1997 acb->rqbuf_firstindex = 0; 2148 acb->rqbuf_firstindex = 0;
1998 acb->rqbuf_lastindex = 0; 2149 acb->rqbuf_lastindex = 0;
1999 acb->wqbuf_firstindex = 0;
2000 acb->wqbuf_lastindex = 0;
2001 pQbuffer = acb->rqbuffer; 2150 pQbuffer = acb->rqbuffer;
2002 memset(pQbuffer, 0, sizeof(struct QBUFFER)); 2151 memset(pQbuffer, 0, sizeof(struct QBUFFER));
2152 spin_unlock_irqrestore(&acb->rqbuffer_lock, flags);
2153 spin_lock_irqsave(&acb->wqbuffer_lock, flags);
2154 acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED |
2155 ACB_F_MESSAGE_WQBUFFER_READED);
2156 acb->wqbuf_firstindex = 0;
2157 acb->wqbuf_lastindex = 0;
2003 pQbuffer = acb->wqbuffer; 2158 pQbuffer = acb->wqbuffer;
2004 memset(pQbuffer, 0, sizeof(struct QBUFFER)); 2159 memset(pQbuffer, 0, sizeof(struct QBUFFER));
2005 if(acb->fw_flag == FW_DEADLOCK) { 2160 spin_unlock_irqrestore(&acb->wqbuffer_lock, flags);
2161 if (acb->fw_flag == FW_DEADLOCK)
2006 pcmdmessagefld->cmdmessage.ReturnCode = 2162 pcmdmessagefld->cmdmessage.ReturnCode =
2007 ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; 2163 ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
2008 }else{ 2164 else
2009 pcmdmessagefld->cmdmessage.ReturnCode = 2165 pcmdmessagefld->cmdmessage.ReturnCode =
2010 ARCMSR_MESSAGE_RETURNCODE_OK; 2166 ARCMSR_MESSAGE_RETURNCODE_OK;
2011 }
2012 }
2013 break; 2167 break;
2014 2168 }
2015 case ARCMSR_MESSAGE_RETURN_CODE_3F: { 2169 case ARCMSR_MESSAGE_RETURN_CODE_3F: {
2016 if(acb->fw_flag == FW_DEADLOCK) { 2170 if (acb->fw_flag == FW_DEADLOCK)
2017 pcmdmessagefld->cmdmessage.ReturnCode = 2171 pcmdmessagefld->cmdmessage.ReturnCode =
2018 ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; 2172 ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
2019 }else{ 2173 else
2020 pcmdmessagefld->cmdmessage.ReturnCode = 2174 pcmdmessagefld->cmdmessage.ReturnCode =
2021 ARCMSR_MESSAGE_RETURNCODE_3F; 2175 ARCMSR_MESSAGE_RETURNCODE_3F;
2022 }
2023 break; 2176 break;
2024 } 2177 }
2025 case ARCMSR_MESSAGE_SAY_HELLO: { 2178 case ARCMSR_MESSAGE_SAY_HELLO: {
2026 int8_t *hello_string = "Hello! I am ARCMSR"; 2179 int8_t *hello_string = "Hello! I am ARCMSR";
2027 if(acb->fw_flag == FW_DEADLOCK) { 2180 if (acb->fw_flag == FW_DEADLOCK)
2028 pcmdmessagefld->cmdmessage.ReturnCode = 2181 pcmdmessagefld->cmdmessage.ReturnCode =
2029 ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; 2182 ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
2030 }else{ 2183 else
2031 pcmdmessagefld->cmdmessage.ReturnCode = 2184 pcmdmessagefld->cmdmessage.ReturnCode =
2032 ARCMSR_MESSAGE_RETURNCODE_OK; 2185 ARCMSR_MESSAGE_RETURNCODE_OK;
2033 } 2186 memcpy(pcmdmessagefld->messagedatabuffer,
2034 memcpy(pcmdmessagefld->messagedatabuffer, hello_string 2187 hello_string, (int16_t)strlen(hello_string));
2035 , (int16_t)strlen(hello_string));
2036 }
2037 break; 2188 break;
2038 2189 }
2039 case ARCMSR_MESSAGE_SAY_GOODBYE: 2190 case ARCMSR_MESSAGE_SAY_GOODBYE: {
2040 if(acb->fw_flag == FW_DEADLOCK) { 2191 if (acb->fw_flag == FW_DEADLOCK)
2041 pcmdmessagefld->cmdmessage.ReturnCode = 2192 pcmdmessagefld->cmdmessage.ReturnCode =
2042 ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; 2193 ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
2043 } 2194 else
2195 pcmdmessagefld->cmdmessage.ReturnCode =
2196 ARCMSR_MESSAGE_RETURNCODE_OK;
2044 arcmsr_iop_parking(acb); 2197 arcmsr_iop_parking(acb);
2045 break; 2198 break;
2046 2199 }
2047 case ARCMSR_MESSAGE_FLUSH_ADAPTER_CACHE: 2200 case ARCMSR_MESSAGE_FLUSH_ADAPTER_CACHE: {
2048 if(acb->fw_flag == FW_DEADLOCK) { 2201 if (acb->fw_flag == FW_DEADLOCK)
2049 pcmdmessagefld->cmdmessage.ReturnCode = 2202 pcmdmessagefld->cmdmessage.ReturnCode =
2050 ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; 2203 ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
2051 } 2204 else
2205 pcmdmessagefld->cmdmessage.ReturnCode =
2206 ARCMSR_MESSAGE_RETURNCODE_OK;
2052 arcmsr_flush_adapter_cache(acb); 2207 arcmsr_flush_adapter_cache(acb);
2053 break; 2208 break;
2054 2209 }
2055 default: 2210 default:
2056 retvalue = ARCMSR_MESSAGE_FAIL; 2211 retvalue = ARCMSR_MESSAGE_FAIL;
2212 pr_info("%s: unknown controlcode!\n", __func__);
2213 }
2214message_out:
2215 if (use_sg) {
2216 struct scatterlist *sg = scsi_sglist(cmd);
2217 kunmap_atomic(buffer - sg->offset);
2057 } 2218 }
2058 message_out:
2059 sg = scsi_sglist(cmd);
2060 kunmap_atomic(buffer - sg->offset);
2061 return retvalue; 2219 return retvalue;
2062} 2220}
2063 2221