aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mac_esp.c
diff options
context:
space:
mode:
authorFinn Thain <fthain@telegraphics.com.au>2008-11-17 15:37:07 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-12-29 12:24:19 -0500
commit09e13e91670b69736b5da0a869a076a55a326394 (patch)
tree1f71954fec3fa3bf4f9bb50c413761798e3da060 /drivers/scsi/mac_esp.c
parent749af3d54a6d5619088ecadb1010c6ab7766f519 (diff)
[SCSI] m68k: mac_esp asm fix
Fix asm constraints and arguments so as not to transfer an odd byte when there may be more words to transfer. The bug would probably also cause exceptions sometimes by transferring one too many bytes. Signed-off-by: Finn Thain <fthain@telegraphics.com.au> Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/mac_esp.c')
-rw-r--r--drivers/scsi/mac_esp.c19
1 files changed, 10 insertions, 9 deletions
diff --git a/drivers/scsi/mac_esp.c b/drivers/scsi/mac_esp.c
index 887682a24e36..a99f9ce6be55 100644
--- a/drivers/scsi/mac_esp.c
+++ b/drivers/scsi/mac_esp.c
@@ -170,7 +170,7 @@ static inline int mac_esp_wait_for_dreq(struct esp *esp)
170 170
171#define MAC_ESP_PDMA_LOOP(operands) \ 171#define MAC_ESP_PDMA_LOOP(operands) \
172 asm volatile ( \ 172 asm volatile ( \
173 " tstw %2 \n" \ 173 " tstw %1 \n" \
174 " jbeq 20f \n" \ 174 " jbeq 20f \n" \
175 "1: movew " operands " \n" \ 175 "1: movew " operands " \n" \
176 "2: movew " operands " \n" \ 176 "2: movew " operands " \n" \
@@ -188,14 +188,14 @@ static inline int mac_esp_wait_for_dreq(struct esp *esp)
188 "14: movew " operands " \n" \ 188 "14: movew " operands " \n" \
189 "15: movew " operands " \n" \ 189 "15: movew " operands " \n" \
190 "16: movew " operands " \n" \ 190 "16: movew " operands " \n" \
191 " subqw #1,%2 \n" \ 191 " subqw #1,%1 \n" \
192 " jbne 1b \n" \ 192 " jbne 1b \n" \
193 "20: tstw %3 \n" \ 193 "20: tstw %2 \n" \
194 " jbeq 30f \n" \ 194 " jbeq 30f \n" \
195 "21: movew " operands " \n" \ 195 "21: movew " operands " \n" \
196 " subqw #1,%3 \n" \ 196 " subqw #1,%2 \n" \
197 " jbne 21b \n" \ 197 " jbne 21b \n" \
198 "30: tstw %4 \n" \ 198 "30: tstw %3 \n" \
199 " jbeq 40f \n" \ 199 " jbeq 40f \n" \
200 "31: moveb " operands " \n" \ 200 "31: moveb " operands " \n" \
201 "32: nop \n" \ 201 "32: nop \n" \
@@ -223,8 +223,8 @@ static inline int mac_esp_wait_for_dreq(struct esp *esp)
223 " .long 31b,40b \n" \ 223 " .long 31b,40b \n" \
224 " .long 32b,40b \n" \ 224 " .long 32b,40b \n" \
225 " .previous \n" \ 225 " .previous \n" \
226 : "+a" (addr) \ 226 : "+a" (addr), "+r" (count32), "+r" (count2) \
227 : "a" (mep->pdma_io), "r" (count32), "r" (count2), "g" (esp_count)) 227 : "g" (count1), "a" (mep->pdma_io))
228 228
229static void mac_esp_send_pdma_cmd(struct esp *esp, u32 addr, u32 esp_count, 229static void mac_esp_send_pdma_cmd(struct esp *esp, u32 addr, u32 esp_count,
230 u32 dma_count, int write, u8 cmd) 230 u32 dma_count, int write, u8 cmd)
@@ -247,19 +247,20 @@ static void mac_esp_send_pdma_cmd(struct esp *esp, u32 addr, u32 esp_count,
247 do { 247 do {
248 unsigned int count32 = esp_count >> 5; 248 unsigned int count32 = esp_count >> 5;
249 unsigned int count2 = (esp_count & 0x1F) >> 1; 249 unsigned int count2 = (esp_count & 0x1F) >> 1;
250 unsigned int count1 = esp_count & 1;
250 unsigned int start_addr = addr; 251 unsigned int start_addr = addr;
251 252
252 if (mac_esp_wait_for_dreq(esp)) 253 if (mac_esp_wait_for_dreq(esp))
253 break; 254 break;
254 255
255 if (write) { 256 if (write) {
256 MAC_ESP_PDMA_LOOP("%1@,%0@+"); 257 MAC_ESP_PDMA_LOOP("%4@,%0@+");
257 258
258 esp_count -= addr - start_addr; 259 esp_count -= addr - start_addr;
259 } else { 260 } else {
260 unsigned int n; 261 unsigned int n;
261 262
262 MAC_ESP_PDMA_LOOP("%0@+,%1@"); 263 MAC_ESP_PDMA_LOOP("%0@+,%4@");
263 264
264 if (mac_esp_wait_for_empty_fifo(esp)) 265 if (mac_esp_wait_for_empty_fifo(esp))
265 break; 266 break;