1 /* mac_esp.c: ESP front-end for Macintosh Quadra systems. 2 * 3 * Adapted from jazz_esp.c and the old mac_esp.c. 4 * 5 * The pseudo DMA algorithm is based on the one used in NetBSD. 6 * See sys/arch/mac68k/obio/esp.c for some background information. 7 * 8 * Copyright (C) 2007-2008 Finn Thain 9 */ 10 11 #include <linux/kernel.h> 12 #include <linux/types.h> 13 #include <linux/module.h> 14 #include <linux/init.h> 15 #include <linux/interrupt.h> 16 #include <linux/platform_device.h> 17 #include <linux/dma-mapping.h> 18 #include <linux/scatterlist.h> 19 #include <linux/delay.h> 20 #include <linux/io.h> 21 #include <linux/nubus.h> 22 23 #include <asm/irq.h> 24 #include <asm/dma.h> 25 26 #include <asm/macints.h> 27 #include <asm/macintosh.h> 28 29 #include <scsi/scsi_host.h> 30 31 #include "esp_scsi.h" 32 33 #define DRV_MODULE_NAME "mac_esp" 34 #define PFX DRV_MODULE_NAME ": " 35 #define DRV_VERSION "1.000" 36 #define DRV_MODULE_RELDATE "Sept 15, 2007" 37 38 #define MAC_ESP_IO_BASE 0x50F00000 39 #define MAC_ESP_REGS_QUADRA (MAC_ESP_IO_BASE + 0x10000) 40 #define MAC_ESP_REGS_QUADRA2 (MAC_ESP_IO_BASE + 0xF000) 41 #define MAC_ESP_REGS_QUADRA3 (MAC_ESP_IO_BASE + 0x18000) 42 #define MAC_ESP_REGS_SPACING 0x402 43 #define MAC_ESP_PDMA_REG 0xF9800024 44 #define MAC_ESP_PDMA_REG_SPACING 0x4 45 #define MAC_ESP_PDMA_IO_OFFSET 0x100 46 47 #define esp_read8(REG) mac_esp_read8(esp, REG) 48 #define esp_write8(VAL, REG) mac_esp_write8(esp, VAL, REG) 49 50 struct mac_esp_priv { 51 struct esp *esp; 52 void __iomem *pdma_regs; 53 void __iomem *pdma_io; 54 int error; 55 }; 56 static struct platform_device *internal_pdev, *external_pdev; 57 static struct esp *esp_chips[2]; 58 59 #define MAC_ESP_GET_PRIV(esp) ((struct mac_esp_priv *) \ 60 platform_get_drvdata((struct platform_device *) \ 61 (esp->dev))) 62 63 static inline void mac_esp_write8(struct esp *esp, u8 val, unsigned long reg) 64 { 65 nubus_writeb(val, esp->regs + reg * 16); 66 } 67 68 static inline u8 mac_esp_read8(struct esp *esp, unsigned long reg) 69 { 70 return nubus_readb(esp->regs + reg * 16); 71 } 72 73 /* For pseudo DMA and PIO we need the virtual address 74 * so this address mapping is the identity mapping. 75 */ 76 77 static dma_addr_t mac_esp_map_single(struct esp *esp, void *buf, 78 size_t sz, int dir) 79 { 80 return (dma_addr_t)buf; 81 } 82 83 static int mac_esp_map_sg(struct esp *esp, struct scatterlist *sg, 84 int num_sg, int dir) 85 { 86 int i; 87 88 for (i = 0; i < num_sg; i++) 89 sg[i].dma_address = (u32)sg_virt(&sg[i]); 90 return num_sg; 91 } 92 93 static void mac_esp_unmap_single(struct esp *esp, dma_addr_t addr, 94 size_t sz, int dir) 95 { 96 /* Nothing to do. */ 97 } 98 99 static void mac_esp_unmap_sg(struct esp *esp, struct scatterlist *sg, 100 int num_sg, int dir) 101 { 102 /* Nothing to do. */ 103 } 104 105 static void mac_esp_reset_dma(struct esp *esp) 106 { 107 /* Nothing to do. */ 108 } 109 110 static void mac_esp_dma_drain(struct esp *esp) 111 { 112 /* Nothing to do. */ 113 } 114 115 static void mac_esp_dma_invalidate(struct esp *esp) 116 { 117 /* Nothing to do. */ 118 } 119 120 static int mac_esp_dma_error(struct esp *esp) 121 { 122 return MAC_ESP_GET_PRIV(esp)->error; 123 } 124 125 static inline int mac_esp_wait_for_empty_fifo(struct esp *esp) 126 { 127 struct mac_esp_priv *mep = MAC_ESP_GET_PRIV(esp); 128 int i = 500000; 129 130 do { 131 if (!(esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES)) 132 return 0; 133 134 if (esp_read8(ESP_STATUS) & ESP_STAT_INTR) 135 return 1; 136 137 udelay(2); 138 } while (--i); 139 140 printk(KERN_ERR PFX "FIFO is not empty (sreg %02x)\n", 141 esp_read8(ESP_STATUS)); 142 mep->error = 1; 143 return 1; 144 } 145 146 static inline int mac_esp_wait_for_dreq(struct esp *esp) 147 { 148 struct mac_esp_priv *mep = MAC_ESP_GET_PRIV(esp); 149 int i = 500000; 150 151 do { 152 if (mep->pdma_regs == NULL) { 153 if (mac_irq_pending(IRQ_MAC_SCSIDRQ)) 154 return 0; 155 } else { 156 if (nubus_readl(mep->pdma_regs) & 0x200) 157 return 0; 158 } 159 160 if (esp_read8(ESP_STATUS) & ESP_STAT_INTR) 161 return 1; 162 163 udelay(2); 164 } while (--i); 165 166 printk(KERN_ERR PFX "PDMA timeout (sreg %02x)\n", 167 esp_read8(ESP_STATUS)); 168 mep->error = 1; 169 return 1; 170 } 171 172 #define MAC_ESP_PDMA_LOOP(operands) \ 173 asm volatile ( \ 174 " tstw %1 \n" \ 175 " jbeq 20f \n" \ 176 "1: movew " operands " \n" \ 177 "2: movew " operands " \n" \ 178 "3: movew " operands " \n" \ 179 "4: movew " operands " \n" \ 180 "5: movew " operands " \n" \ 181 "6: movew " operands " \n" \ 182 "7: movew " operands " \n" \ 183 "8: movew " operands " \n" \ 184 "9: movew " operands " \n" \ 185 "10: movew " operands " \n" \ 186 "11: movew " operands " \n" \ 187 "12: movew " operands " \n" \ 188 "13: movew " operands " \n" \ 189 "14: movew " operands " \n" \ 190 "15: movew " operands " \n" \ 191 "16: movew " operands " \n" \ 192 " subqw #1,%1 \n" \ 193 " jbne 1b \n" \ 194 "20: tstw %2 \n" \ 195 " jbeq 30f \n" \ 196 "21: movew " operands " \n" \ 197 " subqw #1,%2 \n" \ 198 " jbne 21b \n" \ 199 "30: tstw %3 \n" \ 200 " jbeq 40f \n" \ 201 "31: moveb " operands " \n" \ 202 "32: nop \n" \ 203 "40: \n" \ 204 " \n" \ 205 " .section __ex_table,\"a\" \n" \ 206 " .align 4 \n" \ 207 " .long 1b,40b \n" \ 208 " .long 2b,40b \n" \ 209 " .long 3b,40b \n" \ 210 " .long 4b,40b \n" \ 211 " .long 5b,40b \n" \ 212 " .long 6b,40b \n" \ 213 " .long 7b,40b \n" \ 214 " .long 8b,40b \n" \ 215 " .long 9b,40b \n" \ 216 " .long 10b,40b \n" \ 217 " .long 11b,40b \n" \ 218 " .long 12b,40b \n" \ 219 " .long 13b,40b \n" \ 220 " .long 14b,40b \n" \ 221 " .long 15b,40b \n" \ 222 " .long 16b,40b \n" \ 223 " .long 21b,40b \n" \ 224 " .long 31b,40b \n" \ 225 " .long 32b,40b \n" \ 226 " .previous \n" \ 227 : "+a" (addr), "+r" (count32), "+r" (count2) \ 228 : "g" (count1), "a" (mep->pdma_io)) 229 230 static void mac_esp_send_pdma_cmd(struct esp *esp, u32 addr, u32 esp_count, 231 u32 dma_count, int write, u8 cmd) 232 { 233 struct mac_esp_priv *mep = MAC_ESP_GET_PRIV(esp); 234 unsigned long flags; 235 236 local_irq_save(flags); 237 238 mep->error = 0; 239 240 if (!write) 241 scsi_esp_cmd(esp, ESP_CMD_FLUSH); 242 243 esp_write8((esp_count >> 0) & 0xFF, ESP_TCLOW); 244 esp_write8((esp_count >> 8) & 0xFF, ESP_TCMED); 245 246 scsi_esp_cmd(esp, cmd); 247 248 do { 249 unsigned int count32 = esp_count >> 5; 250 unsigned int count2 = (esp_count & 0x1F) >> 1; 251 unsigned int count1 = esp_count & 1; 252 unsigned int start_addr = addr; 253 254 if (mac_esp_wait_for_dreq(esp)) 255 break; 256 257 if (write) { 258 MAC_ESP_PDMA_LOOP("%4@,%0@+"); 259 260 esp_count -= addr - start_addr; 261 } else { 262 unsigned int n; 263 264 MAC_ESP_PDMA_LOOP("%0@+,%4@"); 265 266 if (mac_esp_wait_for_empty_fifo(esp)) 267 break; 268 269 n = (esp_read8(ESP_TCMED) << 8) + esp_read8(ESP_TCLOW); 270 addr = start_addr + esp_count - n; 271 esp_count = n; 272 } 273 } while (esp_count); 274 275 local_irq_restore(flags); 276 } 277 278 /* 279 * Programmed IO routines follow. 280 */ 281 282 static inline int mac_esp_wait_for_fifo(struct esp *esp) 283 { 284 int i = 500000; 285 286 do { 287 if (esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES) 288 return 0; 289 290 udelay(2); 291 } while (--i); 292 293 printk(KERN_ERR PFX "FIFO is empty (sreg %02x)\n", 294 esp_read8(ESP_STATUS)); 295 return 1; 296 } 297 298 static inline int mac_esp_wait_for_intr(struct esp *esp) 299 { 300 int i = 500000; 301 302 do { 303 esp->sreg = esp_read8(ESP_STATUS); 304 if (esp->sreg & ESP_STAT_INTR) 305 return 0; 306 307 udelay(2); 308 } while (--i); 309 310 printk(KERN_ERR PFX "IRQ timeout (sreg %02x)\n", esp->sreg); 311 return 1; 312 } 313 314 #define MAC_ESP_PIO_LOOP(operands, reg1) \ 315 asm volatile ( \ 316 "1: moveb " operands " \n" \ 317 " subqw #1,%1 \n" \ 318 " jbne 1b \n" \ 319 : "+a" (addr), "+r" (reg1) \ 320 : "a" (fifo)) 321 322 #define MAC_ESP_PIO_FILL(operands, reg1) \ 323 asm volatile ( \ 324 " moveb " operands " \n" \ 325 " moveb " operands " \n" \ 326 " moveb " operands " \n" \ 327 " moveb " operands " \n" \ 328 " moveb " operands " \n" \ 329 " moveb " operands " \n" \ 330 " moveb " operands " \n" \ 331 " moveb " operands " \n" \ 332 " moveb " operands " \n" \ 333 " moveb " operands " \n" \ 334 " moveb " operands " \n" \ 335 " moveb " operands " \n" \ 336 " moveb " operands " \n" \ 337 " moveb " operands " \n" \ 338 " moveb " operands " \n" \ 339 " moveb " operands " \n" \ 340 " subqw #8,%1 \n" \ 341 " subqw #8,%1 \n" \ 342 : "+a" (addr), "+r" (reg1) \ 343 : "a" (fifo)) 344 345 #define MAC_ESP_FIFO_SIZE 16 346 347 static void mac_esp_send_pio_cmd(struct esp *esp, u32 addr, u32 esp_count, 348 u32 dma_count, int write, u8 cmd) 349 { 350 unsigned long flags; 351 struct mac_esp_priv *mep = MAC_ESP_GET_PRIV(esp); 352 u8 *fifo = esp->regs + ESP_FDATA * 16; 353 354 local_irq_save(flags); 355 356 cmd &= ~ESP_CMD_DMA; 357 mep->error = 0; 358 359 if (write) { 360 scsi_esp_cmd(esp, cmd); 361 362 if (!mac_esp_wait_for_intr(esp)) { 363 if (mac_esp_wait_for_fifo(esp)) 364 esp_count = 0; 365 } else { 366 esp_count = 0; 367 } 368 } else { 369 scsi_esp_cmd(esp, ESP_CMD_FLUSH); 370 371 if (esp_count >= MAC_ESP_FIFO_SIZE) 372 MAC_ESP_PIO_FILL("%0@+,%2@", esp_count); 373 else 374 MAC_ESP_PIO_LOOP("%0@+,%2@", esp_count); 375 376 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 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 402 if ((esp->sreg & ESP_STAT_PMASK) == ESP_STATP) 403 break; 404 405 if (esp_count) { 406 esp->ireg = esp_read8(ESP_INTRPT); 407 if (esp->ireg & ESP_INTR_DC) 408 break; 409 410 scsi_esp_cmd(esp, ESP_CMD_TI); 411 } 412 } else { 413 esp->ireg = esp_read8(ESP_INTRPT); 414 if (esp->ireg & ESP_INTR_DC) 415 break; 416 417 n = MAC_ESP_FIFO_SIZE - n; 418 if (n > esp_count) 419 n = esp_count; 420 421 if (n == MAC_ESP_FIFO_SIZE) { 422 MAC_ESP_PIO_FILL("%0@+,%2@", esp_count); 423 } else { 424 esp_count -= n; 425 MAC_ESP_PIO_LOOP("%0@+,%2@", n); 426 } 427 428 scsi_esp_cmd(esp, ESP_CMD_TI); 429 } 430 } 431 432 local_irq_restore(flags); 433 } 434 435 static int mac_esp_irq_pending(struct esp *esp) 436 { 437 if (esp_read8(ESP_STATUS) & ESP_STAT_INTR) 438 return 1; 439 return 0; 440 } 441 442 static u32 mac_esp_dma_length_limit(struct esp *esp, u32 dma_addr, u32 dma_len) 443 { 444 return dma_len > 0xFFFF ? 0xFFFF : dma_len; 445 } 446 447 static irqreturn_t mac_scsi_esp_intr(int irq, void *dev_id) 448 { 449 int got_intr; 450 451 /* 452 * This is an edge triggered IRQ, so we have to be careful to 453 * avoid missing a transition when it is shared by two ESP devices. 454 */ 455 456 do { 457 got_intr = 0; 458 if (esp_chips[0] && 459 (mac_esp_read8(esp_chips[0], ESP_STATUS) & ESP_STAT_INTR)) { 460 (void)scsi_esp_intr(irq, esp_chips[0]); 461 got_intr = 1; 462 } 463 if (esp_chips[1] && 464 (mac_esp_read8(esp_chips[1], ESP_STATUS) & ESP_STAT_INTR)) { 465 (void)scsi_esp_intr(irq, esp_chips[1]); 466 got_intr = 1; 467 } 468 } while (got_intr); 469 470 return IRQ_HANDLED; 471 } 472 473 static struct esp_driver_ops mac_esp_ops = { 474 .esp_write8 = mac_esp_write8, 475 .esp_read8 = mac_esp_read8, 476 .map_single = mac_esp_map_single, 477 .map_sg = mac_esp_map_sg, 478 .unmap_single = mac_esp_unmap_single, 479 .unmap_sg = mac_esp_unmap_sg, 480 .irq_pending = mac_esp_irq_pending, 481 .dma_length_limit = mac_esp_dma_length_limit, 482 .reset_dma = mac_esp_reset_dma, 483 .dma_drain = mac_esp_dma_drain, 484 .dma_invalidate = mac_esp_dma_invalidate, 485 .send_dma_cmd = mac_esp_send_pdma_cmd, 486 .dma_error = mac_esp_dma_error, 487 }; 488 489 static int __devinit esp_mac_probe(struct platform_device *dev) 490 { 491 struct scsi_host_template *tpnt = &scsi_esp_template; 492 struct Scsi_Host *host; 493 struct esp *esp; 494 int err; 495 int chips_present; 496 struct mac_esp_priv *mep; 497 498 if (!MACH_IS_MAC) 499 return -ENODEV; 500 501 switch (macintosh_config->scsi_type) { 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; 519 520 host = scsi_host_alloc(tpnt, sizeof(struct esp)); 521 522 err = -ENOMEM; 523 if (!host) 524 goto fail; 525 526 host->max_id = 8; 527 host->use_clustering = DISABLE_CLUSTERING; 528 esp = shost_priv(host); 529 530 esp->host = host; 531 esp->dev = dev; 532 533 esp->command_block = kzalloc(16, GFP_KERNEL); 534 if (!esp->command_block) 535 goto fail_unlink; 536 esp->command_block_dma = (dma_addr_t)esp->command_block; 537 538 esp->scsi_id = 7; 539 host->this_id = esp->scsi_id; 540 esp->scsi_id_mask = 1 << esp->scsi_id; 541 542 mep = kzalloc(sizeof(struct mac_esp_priv), GFP_KERNEL); 543 if (!mep) 544 goto fail_free_command_block; 545 mep->esp = esp; 546 platform_set_drvdata(dev, mep); 547 548 switch (macintosh_config->scsi_type) { 549 case MAC_SCSI_QUADRA: 550 esp->cfreq = 16500000; 551 esp->regs = (void __iomem *)MAC_ESP_REGS_QUADRA; 552 mep->pdma_io = esp->regs + MAC_ESP_PDMA_IO_OFFSET; 553 mep->pdma_regs = NULL; 554 break; 555 case MAC_SCSI_QUADRA2: 556 esp->cfreq = 25000000; 557 esp->regs = (void __iomem *)(MAC_ESP_REGS_QUADRA2 + 558 dev->id * MAC_ESP_REGS_SPACING); 559 mep->pdma_io = esp->regs + MAC_ESP_PDMA_IO_OFFSET; 560 mep->pdma_regs = (void __iomem *)(MAC_ESP_PDMA_REG + 561 dev->id * MAC_ESP_PDMA_REG_SPACING); 562 nubus_writel(0x1d1, mep->pdma_regs); 563 break; 564 case MAC_SCSI_QUADRA3: 565 /* These quadras have a real DMA controller (the PSC) but we 566 * don't know how to drive it so we must use PIO instead. 567 */ 568 esp->cfreq = 25000000; 569 esp->regs = (void __iomem *)MAC_ESP_REGS_QUADRA3; 570 mep->pdma_io = NULL; 571 mep->pdma_regs = NULL; 572 break; 573 } 574 575 esp->ops = &mac_esp_ops; 576 if (mep->pdma_io == NULL) { 577 printk(KERN_INFO PFX "using PIO for controller %d\n", dev->id); 578 esp_write8(0, ESP_TCLOW); 579 esp_write8(0, ESP_TCMED); 580 esp->flags = ESP_FLAG_DISABLE_SYNC; 581 mac_esp_ops.send_dma_cmd = mac_esp_send_pio_cmd; 582 } else { 583 printk(KERN_INFO PFX "using PDMA for controller %d\n", dev->id); 584 } 585 586 host->irq = IRQ_MAC_SCSI; 587 esp_chips[dev->id] = esp; 588 mb(); 589 if (esp_chips[!dev->id] == NULL) { 590 err = request_irq(host->irq, mac_scsi_esp_intr, 0, 591 "Mac ESP", NULL); 592 if (err < 0) { 593 esp_chips[dev->id] = NULL; 594 goto fail_free_priv; 595 } 596 } 597 598 err = scsi_esp_register(esp, &dev->dev); 599 if (err) 600 goto fail_free_irq; 601 602 return 0; 603 604 fail_free_irq: 605 if (esp_chips[!dev->id] == NULL) 606 free_irq(host->irq, esp); 607 fail_free_priv: 608 kfree(mep); 609 fail_free_command_block: 610 kfree(esp->command_block); 611 fail_unlink: 612 scsi_host_put(host); 613 fail: 614 return err; 615 } 616 617 static int __devexit esp_mac_remove(struct platform_device *dev) 618 { 619 struct mac_esp_priv *mep = platform_get_drvdata(dev); 620 struct esp *esp = mep->esp; 621 unsigned int irq = esp->host->irq; 622 623 scsi_esp_unregister(esp); 624 625 esp_chips[dev->id] = NULL; 626 if (!(esp_chips[0] || esp_chips[1])) 627 free_irq(irq, NULL); 628 629 kfree(mep); 630 631 kfree(esp->command_block); 632 633 scsi_host_put(esp->host); 634 635 return 0; 636 } 637 638 static struct platform_driver esp_mac_driver = { 639 .probe = esp_mac_probe, 640 .remove = __devexit_p(esp_mac_remove), 641 .driver = { 642 .name = DRV_MODULE_NAME, 643 }, 644 }; 645 646 static int __init mac_esp_init(void) 647 { 648 int err; 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 } 672 673 static void __exit mac_esp_exit(void) 674 { 675 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 } 686 687 MODULE_DESCRIPTION("Mac ESP SCSI driver"); 688 MODULE_AUTHOR("Finn Thain <fthain@telegraphics.com.au>"); 689 MODULE_LICENSE("GPL v2"); 690 MODULE_VERSION(DRV_VERSION); 691 692 module_init(mac_esp_init); 693 module_exit(mac_esp_exit); 694