aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorFinn Thain <fthain@telegraphics.com.au>2009-12-04 20:30:42 -0500
committerJames Bottomley <James.Bottomley@suse.de>2010-01-18 11:48:10 -0500
commit02507a80b35edd720480540d917e9f92cc371009 (patch)
tree0da90f4cc680093926073f34fb9ddcb84f4a1aea /drivers/scsi
parentf2818663c82b7297ff4aa38cbddb870dc02f7104 (diff)
[SCSI] mac_esp: fix PIO mode, take 2
The mac_esp PIO algorithm no longer works in 2.6.31 and crashes my Centris 660av. So here's a better one. Also, force async with esp_set_offset() rather than esp_slave_configure(). One of the SCSI drives I tested still doesn't like the PIO mode and fails with "esp: esp0: Reconnect IRQ2 timeout" (the same drive works fine in PDMA mode). This failure happens when esp_reconnect_with_tag() tries to read in two tag bytes but the chip only provides one (0x20). I don't know what causes this. I decided not to waste any more time trying to fix it because the best solution is to rip out the PIO mode altogether and use the DMA engine. Signed-off-by: Finn Thain <fthain@telegraphics.com.au> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/esp_scsi.c14
-rw-r--r--drivers/scsi/mac_esp.c95
2 files changed, 53 insertions, 56 deletions
diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c
index a680e18b5f3b..e2bc779f86c1 100644
--- a/drivers/scsi/esp_scsi.c
+++ b/drivers/scsi/esp_scsi.c
@@ -1449,9 +1449,6 @@ static void esp_msgin_sdtr(struct esp *esp, struct esp_target_data *tp)
1449 if (offset > 15) 1449 if (offset > 15)
1450 goto do_reject; 1450 goto do_reject;
1451 1451
1452 if (esp->flags & ESP_FLAG_DISABLE_SYNC)
1453 offset = 0;
1454
1455 if (offset) { 1452 if (offset) {
1456 int one_clock; 1453 int one_clock;
1457 1454
@@ -2405,12 +2402,6 @@ static int esp_slave_configure(struct scsi_device *dev)
2405 struct esp_target_data *tp = &esp->target[dev->id]; 2402 struct esp_target_data *tp = &esp->target[dev->id];
2406 int goal_tags, queue_depth; 2403 int goal_tags, queue_depth;
2407 2404
2408 if (esp->flags & ESP_FLAG_DISABLE_SYNC) {
2409 /* Bypass async domain validation */
2410 dev->ppr = 0;
2411 dev->sdtr = 0;
2412 }
2413
2414 goal_tags = 0; 2405 goal_tags = 0;
2415 2406
2416 if (dev->tagged_supported) { 2407 if (dev->tagged_supported) {
@@ -2660,7 +2651,10 @@ static void esp_set_offset(struct scsi_target *target, int offset)
2660 struct esp *esp = shost_priv(host); 2651 struct esp *esp = shost_priv(host);
2661 struct esp_target_data *tp = &esp->target[target->id]; 2652 struct esp_target_data *tp = &esp->target[target->id];
2662 2653
2663 tp->nego_goal_offset = offset; 2654 if (esp->flags & ESP_FLAG_DISABLE_SYNC)
2655 tp->nego_goal_offset = 0;
2656 else
2657 tp->nego_goal_offset = offset;
2664 tp->flags |= ESP_TGT_CHECK_NEGO; 2658 tp->flags |= ESP_TGT_CHECK_NEGO;
2665} 2659}
2666 2660
diff --git a/drivers/scsi/mac_esp.c b/drivers/scsi/mac_esp.c
index c24e86f07804..dd808ae942a1 100644
--- a/drivers/scsi/mac_esp.c
+++ b/drivers/scsi/mac_esp.c
@@ -22,7 +22,6 @@
22 22
23#include <asm/irq.h> 23#include <asm/irq.h>
24#include <asm/dma.h> 24#include <asm/dma.h>
25
26#include <asm/macints.h> 25#include <asm/macints.h>
27#include <asm/macintosh.h> 26#include <asm/macintosh.h>
28 27
@@ -279,24 +278,27 @@ static void mac_esp_send_pdma_cmd(struct esp *esp, u32 addr, u32 esp_count,
279 * Programmed IO routines follow. 278 * Programmed IO routines follow.
280 */ 279 */
281 280
282static inline int mac_esp_wait_for_fifo(struct esp *esp) 281static inline unsigned int mac_esp_wait_for_fifo(struct esp *esp)
283{ 282{
284 int i = 500000; 283 int i = 500000;
285 284
286 do { 285 do {
287 if (esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES) 286 unsigned int fbytes = esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES;
288 return 0; 287
288 if (fbytes)
289 return fbytes;
289 290
290 udelay(2); 291 udelay(2);
291 } while (--i); 292 } while (--i);
292 293
293 printk(KERN_ERR PFX "FIFO is empty (sreg %02x)\n", 294 printk(KERN_ERR PFX "FIFO is empty (sreg %02x)\n",
294 esp_read8(ESP_STATUS)); 295 esp_read8(ESP_STATUS));
295 return 1; 296 return 0;
296} 297}
297 298
298static inline int mac_esp_wait_for_intr(struct esp *esp) 299static inline int mac_esp_wait_for_intr(struct esp *esp)
299{ 300{
301 struct mac_esp_priv *mep = MAC_ESP_GET_PRIV(esp);
300 int i = 500000; 302 int i = 500000;
301 303
302 do { 304 do {
@@ -308,6 +310,7 @@ static inline int mac_esp_wait_for_intr(struct esp *esp)
308 } while (--i); 310 } while (--i);
309 311
310 printk(KERN_ERR PFX "IRQ timeout (sreg %02x)\n", esp->sreg); 312 printk(KERN_ERR PFX "IRQ timeout (sreg %02x)\n", esp->sreg);
313 mep->error = 1;
311 return 1; 314 return 1;
312} 315}
313 316
@@ -347,11 +350,10 @@ static inline int mac_esp_wait_for_intr(struct esp *esp)
347static void mac_esp_send_pio_cmd(struct esp *esp, u32 addr, u32 esp_count, 350static void mac_esp_send_pio_cmd(struct esp *esp, u32 addr, u32 esp_count,
348 u32 dma_count, int write, u8 cmd) 351 u32 dma_count, int write, u8 cmd)
349{ 352{
350 unsigned long flags;
351 struct mac_esp_priv *mep = MAC_ESP_GET_PRIV(esp); 353 struct mac_esp_priv *mep = MAC_ESP_GET_PRIV(esp);
352 u8 *fifo = esp->regs + ESP_FDATA * 16; 354 u8 *fifo = esp->regs + ESP_FDATA * 16;
353 355
354 local_irq_save(flags); 356 disable_irq(esp->host->irq);
355 357
356 cmd &= ~ESP_CMD_DMA; 358 cmd &= ~ESP_CMD_DMA;
357 mep->error = 0; 359 mep->error = 0;
@@ -359,11 +361,35 @@ static void mac_esp_send_pio_cmd(struct esp *esp, u32 addr, u32 esp_count,
359 if (write) { 361 if (write) {
360 scsi_esp_cmd(esp, cmd); 362 scsi_esp_cmd(esp, cmd);
361 363
362 if (!mac_esp_wait_for_intr(esp)) { 364 while (1) {
363 if (mac_esp_wait_for_fifo(esp)) 365 unsigned int n;
364 esp_count = 0; 366
365 } else { 367 n = mac_esp_wait_for_fifo(esp);
366 esp_count = 0; 368 if (!n)
369 break;
370
371 if (n > esp_count)
372 n = esp_count;
373 esp_count -= n;
374
375 MAC_ESP_PIO_LOOP("%2@,%0@+", n);
376
377 if (!esp_count)
378 break;
379
380 if (mac_esp_wait_for_intr(esp))
381 break;
382
383 if (((esp->sreg & ESP_STAT_PMASK) != ESP_DIP) &&
384 ((esp->sreg & ESP_STAT_PMASK) != ESP_MIP))
385 break;
386
387 esp->ireg = esp_read8(ESP_INTRPT);
388 if ((esp->ireg & (ESP_INTR_DC | ESP_INTR_BSERV)) !=
389 ESP_INTR_BSERV)
390 break;
391
392 scsi_esp_cmd(esp, ESP_CMD_TI);
367 } 393 }
368 } else { 394 } else {
369 scsi_esp_cmd(esp, ESP_CMD_FLUSH); 395 scsi_esp_cmd(esp, ESP_CMD_FLUSH);
@@ -374,47 +400,24 @@ static void mac_esp_send_pio_cmd(struct esp *esp, u32 addr, u32 esp_count,
374 MAC_ESP_PIO_LOOP("%0@+,%2@", esp_count); 400 MAC_ESP_PIO_LOOP("%0@+,%2@", esp_count);
375 401
376 scsi_esp_cmd(esp, cmd); 402 scsi_esp_cmd(esp, cmd);
377 }
378
379 while (esp_count) {
380 unsigned int n;
381
382 if (mac_esp_wait_for_intr(esp)) {
383 mep->error = 1;
384 break;
385 }
386
387 if (esp->sreg & ESP_STAT_SPAM) {
388 printk(KERN_ERR PFX "gross error\n");
389 mep->error = 1;
390 break;
391 }
392 403
393 n = esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES; 404 while (esp_count) {
394 405 unsigned int n;
395 if (write) {
396 if (n > esp_count)
397 n = esp_count;
398 esp_count -= n;
399
400 MAC_ESP_PIO_LOOP("%2@,%0@+", n);
401 406
402 if ((esp->sreg & ESP_STAT_PMASK) == ESP_STATP) 407 if (mac_esp_wait_for_intr(esp))
403 break; 408 break;
404 409
405 if (esp_count) { 410 if (((esp->sreg & ESP_STAT_PMASK) != ESP_DOP) &&
406 esp->ireg = esp_read8(ESP_INTRPT); 411 ((esp->sreg & ESP_STAT_PMASK) != ESP_MOP))
407 if (esp->ireg & ESP_INTR_DC) 412 break;
408 break;
409 413
410 scsi_esp_cmd(esp, ESP_CMD_TI);
411 }
412 } else {
413 esp->ireg = esp_read8(ESP_INTRPT); 414 esp->ireg = esp_read8(ESP_INTRPT);
414 if (esp->ireg & ESP_INTR_DC) 415 if ((esp->ireg & (ESP_INTR_DC | ESP_INTR_BSERV)) !=
416 ESP_INTR_BSERV)
415 break; 417 break;
416 418
417 n = MAC_ESP_FIFO_SIZE - n; 419 n = MAC_ESP_FIFO_SIZE -
420 (esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES);
418 if (n > esp_count) 421 if (n > esp_count)
419 n = esp_count; 422 n = esp_count;
420 423
@@ -429,7 +432,7 @@ static void mac_esp_send_pio_cmd(struct esp *esp, u32 addr, u32 esp_count,
429 } 432 }
430 } 433 }
431 434
432 local_irq_restore(flags); 435 enable_irq(esp->host->irq);
433} 436}
434 437
435static int mac_esp_irq_pending(struct esp *esp) 438static int mac_esp_irq_pending(struct esp *esp)