falconide.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /*
  2. * Atari Falcon IDE Driver
  3. *
  4. * Created 12 Jul 1997 by Geert Uytterhoeven
  5. *
  6. * This file is subject to the terms and conditions of the GNU General Public
  7. * License. See the file COPYING in the main directory of this archive for
  8. * more details.
  9. */
  10. #include <linux/module.h>
  11. #include <linux/types.h>
  12. #include <linux/mm.h>
  13. #include <linux/interrupt.h>
  14. #include <linux/blkdev.h>
  15. #include <linux/ide.h>
  16. #include <linux/init.h>
  17. #include <asm/setup.h>
  18. #include <asm/atarihw.h>
  19. #include <asm/atariints.h>
  20. #include <asm/atari_stdma.h>
  21. #include <asm/ide.h>
  22. #define DRV_NAME "falconide"
  23. /*
  24. * Base of the IDE interface
  25. */
  26. #define ATA_HD_BASE 0xfff00000
  27. /*
  28. * Offsets from the above base
  29. */
  30. #define ATA_HD_CONTROL 0x39
  31. /*
  32. * falconide_intr_lock is used to obtain access to the IDE interrupt,
  33. * which is shared between several drivers.
  34. */
  35. static int falconide_intr_lock;
  36. static void falconide_release_lock(void)
  37. {
  38. if (falconide_intr_lock == 0) {
  39. printk(KERN_ERR "%s: bug\n", __func__);
  40. return;
  41. }
  42. falconide_intr_lock = 0;
  43. stdma_release();
  44. }
  45. static void falconide_get_lock(irq_handler_t handler, void *data)
  46. {
  47. if (falconide_intr_lock == 0) {
  48. if (in_interrupt() > 0)
  49. panic("Falcon IDE hasn't ST-DMA lock in interrupt");
  50. stdma_lock(handler, data);
  51. falconide_intr_lock = 1;
  52. }
  53. }
  54. static void falconide_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
  55. void *buf, unsigned int len)
  56. {
  57. unsigned long data_addr = drive->hwif->io_ports.data_addr;
  58. if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS)) {
  59. __ide_mm_insw(data_addr, buf, (len + 1) / 2);
  60. return;
  61. }
  62. raw_insw_swapw((u16 *)data_addr, buf, (len + 1) / 2);
  63. }
  64. static void falconide_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
  65. void *buf, unsigned int len)
  66. {
  67. unsigned long data_addr = drive->hwif->io_ports.data_addr;
  68. if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS)) {
  69. __ide_mm_outsw(data_addr, buf, (len + 1) / 2);
  70. return;
  71. }
  72. raw_outsw_swapw((u16 *)data_addr, buf, (len + 1) / 2);
  73. }
  74. /* Atari has a byte-swapped IDE interface */
  75. static const struct ide_tp_ops falconide_tp_ops = {
  76. .exec_command = ide_exec_command,
  77. .read_status = ide_read_status,
  78. .read_altstatus = ide_read_altstatus,
  79. .write_devctl = ide_write_devctl,
  80. .dev_select = ide_dev_select,
  81. .tf_load = ide_tf_load,
  82. .tf_read = ide_tf_read,
  83. .input_data = falconide_input_data,
  84. .output_data = falconide_output_data,
  85. };
  86. static const struct ide_port_info falconide_port_info = {
  87. .get_lock = falconide_get_lock,
  88. .release_lock = falconide_release_lock,
  89. .tp_ops = &falconide_tp_ops,
  90. .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_SERIALIZE |
  91. IDE_HFLAG_NO_DMA,
  92. .irq_flags = IRQF_SHARED,
  93. .chipset = ide_generic,
  94. };
  95. static void __init falconide_setup_ports(struct ide_hw *hw)
  96. {
  97. int i;
  98. memset(hw, 0, sizeof(*hw));
  99. hw->io_ports.data_addr = ATA_HD_BASE;
  100. for (i = 1; i < 8; i++)
  101. hw->io_ports_array[i] = ATA_HD_BASE + 1 + i * 4;
  102. hw->io_ports.ctl_addr = ATA_HD_BASE + ATA_HD_CONTROL;
  103. hw->irq = IRQ_MFP_IDE;
  104. }
  105. /*
  106. * Probe for a Falcon IDE interface
  107. */
  108. static int __init falconide_init(void)
  109. {
  110. struct ide_host *host;
  111. struct ide_hw hw, *hws[] = { &hw };
  112. int rc;
  113. if (!MACH_IS_ATARI || !ATARIHW_PRESENT(IDE))
  114. return -ENODEV;
  115. printk(KERN_INFO "ide: Falcon IDE controller\n");
  116. if (!request_mem_region(ATA_HD_BASE, 0x40, DRV_NAME)) {
  117. printk(KERN_ERR "%s: resources busy\n", DRV_NAME);
  118. return -EBUSY;
  119. }
  120. falconide_setup_ports(&hw);
  121. host = ide_host_alloc(&falconide_port_info, hws, 1);
  122. if (host == NULL) {
  123. rc = -ENOMEM;
  124. goto err;
  125. }
  126. falconide_get_lock(NULL, NULL);
  127. rc = ide_host_register(host, &falconide_port_info, hws);
  128. falconide_release_lock();
  129. if (rc)
  130. goto err_free;
  131. return 0;
  132. err_free:
  133. ide_host_free(host);
  134. err:
  135. release_mem_region(ATA_HD_BASE, 0x40);
  136. return rc;
  137. }
  138. module_init(falconide_init);
  139. MODULE_LICENSE("GPL");