aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mac_esp.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/scsi/mac_esp.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/scsi/mac_esp.c')
-rw-r--r--drivers/scsi/mac_esp.c153
1 files changed, 55 insertions, 98 deletions
diff --git a/drivers/scsi/mac_esp.c b/drivers/scsi/mac_esp.c
index c24e86f07804..3893337e3dd3 100644
--- a/drivers/scsi/mac_esp.c
+++ b/drivers/scsi/mac_esp.c
@@ -19,10 +19,10 @@
19#include <linux/delay.h> 19#include <linux/delay.h>
20#include <linux/io.h> 20#include <linux/io.h>
21#include <linux/nubus.h> 21#include <linux/nubus.h>
22#include <linux/slab.h>
22 23
23#include <asm/irq.h> 24#include <asm/irq.h>
24#include <asm/dma.h> 25#include <asm/dma.h>
25
26#include <asm/macints.h> 26#include <asm/macints.h>
27#include <asm/macintosh.h> 27#include <asm/macintosh.h>
28 28
@@ -53,7 +53,6 @@ struct mac_esp_priv {
53 void __iomem *pdma_io; 53 void __iomem *pdma_io;
54 int error; 54 int error;
55}; 55};
56static struct platform_device *internal_pdev, *external_pdev;
57static struct esp *esp_chips[2]; 56static struct esp *esp_chips[2];
58 57
59#define MAC_ESP_GET_PRIV(esp) ((struct mac_esp_priv *) \ 58#define MAC_ESP_GET_PRIV(esp) ((struct mac_esp_priv *) \
@@ -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 403
382 if (mac_esp_wait_for_intr(esp)) { 404 while (esp_count) {
383 mep->error = 1; 405 unsigned int n;
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
393 n = esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES;
394
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)
@@ -492,29 +495,12 @@ static int __devinit esp_mac_probe(struct platform_device *dev)
492 struct Scsi_Host *host; 495 struct Scsi_Host *host;
493 struct esp *esp; 496 struct esp *esp;
494 int err; 497 int err;
495 int chips_present;
496 struct mac_esp_priv *mep; 498 struct mac_esp_priv *mep;
497 499
498 if (!MACH_IS_MAC) 500 if (!MACH_IS_MAC)
499 return -ENODEV; 501 return -ENODEV;
500 502
501 switch (macintosh_config->scsi_type) { 503 if (dev->id > 1)
502 case MAC_SCSI_QUADRA:
503 case MAC_SCSI_QUADRA3:
504 chips_present = 1;
505 break;
506 case MAC_SCSI_QUADRA2:
507 if ((macintosh_config->ident == MAC_MODEL_Q900) ||
508 (macintosh_config->ident == MAC_MODEL_Q950))
509 chips_present = 2;
510 else
511 chips_present = 1;
512 break;
513 default:
514 chips_present = 0;
515 }
516
517 if (dev->id + 1 > chips_present)
518 return -ENODEV; 504 return -ENODEV;
519 505
520 host = scsi_host_alloc(tpnt, sizeof(struct esp)); 506 host = scsi_host_alloc(tpnt, sizeof(struct esp));
@@ -639,55 +625,26 @@ static struct platform_driver esp_mac_driver = {
639 .probe = esp_mac_probe, 625 .probe = esp_mac_probe,
640 .remove = __devexit_p(esp_mac_remove), 626 .remove = __devexit_p(esp_mac_remove),
641 .driver = { 627 .driver = {
642 .name = DRV_MODULE_NAME, 628 .name = DRV_MODULE_NAME,
629 .owner = THIS_MODULE,
643 }, 630 },
644}; 631};
645 632
646static int __init mac_esp_init(void) 633static int __init mac_esp_init(void)
647{ 634{
648 int err; 635 return platform_driver_register(&esp_mac_driver);
649
650 err = platform_driver_register(&esp_mac_driver);
651 if (err)
652 return err;
653
654 internal_pdev = platform_device_alloc(DRV_MODULE_NAME, 0);
655 if (internal_pdev && platform_device_add(internal_pdev)) {
656 platform_device_put(internal_pdev);
657 internal_pdev = NULL;
658 }
659 external_pdev = platform_device_alloc(DRV_MODULE_NAME, 1);
660 if (external_pdev && platform_device_add(external_pdev)) {
661 platform_device_put(external_pdev);
662 external_pdev = NULL;
663 }
664
665 if (internal_pdev || external_pdev) {
666 return 0;
667 } else {
668 platform_driver_unregister(&esp_mac_driver);
669 return -ENOMEM;
670 }
671} 636}
672 637
673static void __exit mac_esp_exit(void) 638static void __exit mac_esp_exit(void)
674{ 639{
675 platform_driver_unregister(&esp_mac_driver); 640 platform_driver_unregister(&esp_mac_driver);
676
677 if (internal_pdev) {
678 platform_device_unregister(internal_pdev);
679 internal_pdev = NULL;
680 }
681 if (external_pdev) {
682 platform_device_unregister(external_pdev);
683 external_pdev = NULL;
684 }
685} 641}
686 642
687MODULE_DESCRIPTION("Mac ESP SCSI driver"); 643MODULE_DESCRIPTION("Mac ESP SCSI driver");
688MODULE_AUTHOR("Finn Thain <fthain@telegraphics.com.au>"); 644MODULE_AUTHOR("Finn Thain <fthain@telegraphics.com.au>");
689MODULE_LICENSE("GPL v2"); 645MODULE_LICENSE("GPL v2");
690MODULE_VERSION(DRV_VERSION); 646MODULE_VERSION(DRV_VERSION);
647MODULE_ALIAS("platform:" DRV_MODULE_NAME);
691 648
692module_init(mac_esp_init); 649module_init(mac_esp_init);
693module_exit(mac_esp_exit); 650module_exit(mac_esp_exit);