ide-io-std.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. #include <linux/kernel.h>
  2. #include <linux/export.h>
  3. #include <linux/ide.h>
  4. #if defined(CONFIG_ARM) || defined(CONFIG_M68K) || defined(CONFIG_MIPS) || \
  5. defined(CONFIG_PARISC) || defined(CONFIG_PPC) || defined(CONFIG_SPARC)
  6. #include <asm/ide.h>
  7. #else
  8. #include <asm-generic/ide_iops.h>
  9. #endif
  10. /*
  11. * Conventional PIO operations for ATA devices
  12. */
  13. static u8 ide_inb(unsigned long port)
  14. {
  15. return (u8) inb(port);
  16. }
  17. static void ide_outb(u8 val, unsigned long port)
  18. {
  19. outb(val, port);
  20. }
  21. /*
  22. * MMIO operations, typically used for SATA controllers
  23. */
  24. static u8 ide_mm_inb(unsigned long port)
  25. {
  26. return (u8) readb((void __iomem *) port);
  27. }
  28. static void ide_mm_outb(u8 value, unsigned long port)
  29. {
  30. writeb(value, (void __iomem *) port);
  31. }
  32. void ide_exec_command(ide_hwif_t *hwif, u8 cmd)
  33. {
  34. if (hwif->host_flags & IDE_HFLAG_MMIO)
  35. writeb(cmd, (void __iomem *)hwif->io_ports.command_addr);
  36. else
  37. outb(cmd, hwif->io_ports.command_addr);
  38. }
  39. EXPORT_SYMBOL_GPL(ide_exec_command);
  40. u8 ide_read_status(ide_hwif_t *hwif)
  41. {
  42. if (hwif->host_flags & IDE_HFLAG_MMIO)
  43. return readb((void __iomem *)hwif->io_ports.status_addr);
  44. else
  45. return inb(hwif->io_ports.status_addr);
  46. }
  47. EXPORT_SYMBOL_GPL(ide_read_status);
  48. u8 ide_read_altstatus(ide_hwif_t *hwif)
  49. {
  50. if (hwif->host_flags & IDE_HFLAG_MMIO)
  51. return readb((void __iomem *)hwif->io_ports.ctl_addr);
  52. else
  53. return inb(hwif->io_ports.ctl_addr);
  54. }
  55. EXPORT_SYMBOL_GPL(ide_read_altstatus);
  56. void ide_write_devctl(ide_hwif_t *hwif, u8 ctl)
  57. {
  58. if (hwif->host_flags & IDE_HFLAG_MMIO)
  59. writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr);
  60. else
  61. outb(ctl, hwif->io_ports.ctl_addr);
  62. }
  63. EXPORT_SYMBOL_GPL(ide_write_devctl);
  64. void ide_dev_select(ide_drive_t *drive)
  65. {
  66. ide_hwif_t *hwif = drive->hwif;
  67. u8 select = drive->select | ATA_DEVICE_OBS;
  68. if (hwif->host_flags & IDE_HFLAG_MMIO)
  69. writeb(select, (void __iomem *)hwif->io_ports.device_addr);
  70. else
  71. outb(select, hwif->io_ports.device_addr);
  72. }
  73. EXPORT_SYMBOL_GPL(ide_dev_select);
  74. void ide_tf_load(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid)
  75. {
  76. ide_hwif_t *hwif = drive->hwif;
  77. struct ide_io_ports *io_ports = &hwif->io_ports;
  78. void (*tf_outb)(u8 addr, unsigned long port);
  79. u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
  80. if (mmio)
  81. tf_outb = ide_mm_outb;
  82. else
  83. tf_outb = ide_outb;
  84. if (valid & IDE_VALID_FEATURE)
  85. tf_outb(tf->feature, io_ports->feature_addr);
  86. if (valid & IDE_VALID_NSECT)
  87. tf_outb(tf->nsect, io_ports->nsect_addr);
  88. if (valid & IDE_VALID_LBAL)
  89. tf_outb(tf->lbal, io_ports->lbal_addr);
  90. if (valid & IDE_VALID_LBAM)
  91. tf_outb(tf->lbam, io_ports->lbam_addr);
  92. if (valid & IDE_VALID_LBAH)
  93. tf_outb(tf->lbah, io_ports->lbah_addr);
  94. if (valid & IDE_VALID_DEVICE)
  95. tf_outb(tf->device, io_ports->device_addr);
  96. }
  97. EXPORT_SYMBOL_GPL(ide_tf_load);
  98. void ide_tf_read(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid)
  99. {
  100. ide_hwif_t *hwif = drive->hwif;
  101. struct ide_io_ports *io_ports = &hwif->io_ports;
  102. u8 (*tf_inb)(unsigned long port);
  103. u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
  104. if (mmio)
  105. tf_inb = ide_mm_inb;
  106. else
  107. tf_inb = ide_inb;
  108. if (valid & IDE_VALID_ERROR)
  109. tf->error = tf_inb(io_ports->feature_addr);
  110. if (valid & IDE_VALID_NSECT)
  111. tf->nsect = tf_inb(io_ports->nsect_addr);
  112. if (valid & IDE_VALID_LBAL)
  113. tf->lbal = tf_inb(io_ports->lbal_addr);
  114. if (valid & IDE_VALID_LBAM)
  115. tf->lbam = tf_inb(io_ports->lbam_addr);
  116. if (valid & IDE_VALID_LBAH)
  117. tf->lbah = tf_inb(io_ports->lbah_addr);
  118. if (valid & IDE_VALID_DEVICE)
  119. tf->device = tf_inb(io_ports->device_addr);
  120. }
  121. EXPORT_SYMBOL_GPL(ide_tf_read);
  122. /*
  123. * Some localbus EIDE interfaces require a special access sequence
  124. * when using 32-bit I/O instructions to transfer data. We call this
  125. * the "vlb_sync" sequence, which consists of three successive reads
  126. * of the sector count register location, with interrupts disabled
  127. * to ensure that the reads all happen together.
  128. */
  129. static void ata_vlb_sync(unsigned long port)
  130. {
  131. (void)inb(port);
  132. (void)inb(port);
  133. (void)inb(port);
  134. }
  135. /*
  136. * This is used for most PIO data transfers *from* the IDE interface
  137. *
  138. * These routines will round up any request for an odd number of bytes,
  139. * so if an odd len is specified, be sure that there's at least one
  140. * extra byte allocated for the buffer.
  141. */
  142. void ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf,
  143. unsigned int len)
  144. {
  145. ide_hwif_t *hwif = drive->hwif;
  146. struct ide_io_ports *io_ports = &hwif->io_ports;
  147. unsigned long data_addr = io_ports->data_addr;
  148. unsigned int words = (len + 1) >> 1;
  149. u8 io_32bit = drive->io_32bit;
  150. u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
  151. if (io_32bit) {
  152. unsigned long uninitialized_var(flags);
  153. if ((io_32bit & 2) && !mmio) {
  154. local_irq_save(flags);
  155. ata_vlb_sync(io_ports->nsect_addr);
  156. }
  157. words >>= 1;
  158. if (mmio)
  159. __ide_mm_insl((void __iomem *)data_addr, buf, words);
  160. else
  161. insl(data_addr, buf, words);
  162. if ((io_32bit & 2) && !mmio)
  163. local_irq_restore(flags);
  164. if (((len + 1) & 3) < 2)
  165. return;
  166. buf += len & ~3;
  167. words = 1;
  168. }
  169. if (mmio)
  170. __ide_mm_insw((void __iomem *)data_addr, buf, words);
  171. else
  172. insw(data_addr, buf, words);
  173. }
  174. EXPORT_SYMBOL_GPL(ide_input_data);
  175. /*
  176. * This is used for most PIO data transfers *to* the IDE interface
  177. */
  178. void ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf,
  179. unsigned int len)
  180. {
  181. ide_hwif_t *hwif = drive->hwif;
  182. struct ide_io_ports *io_ports = &hwif->io_ports;
  183. unsigned long data_addr = io_ports->data_addr;
  184. unsigned int words = (len + 1) >> 1;
  185. u8 io_32bit = drive->io_32bit;
  186. u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
  187. if (io_32bit) {
  188. unsigned long uninitialized_var(flags);
  189. if ((io_32bit & 2) && !mmio) {
  190. local_irq_save(flags);
  191. ata_vlb_sync(io_ports->nsect_addr);
  192. }
  193. words >>= 1;
  194. if (mmio)
  195. __ide_mm_outsl((void __iomem *)data_addr, buf, words);
  196. else
  197. outsl(data_addr, buf, words);
  198. if ((io_32bit & 2) && !mmio)
  199. local_irq_restore(flags);
  200. if (((len + 1) & 3) < 2)
  201. return;
  202. buf += len & ~3;
  203. words = 1;
  204. }
  205. if (mmio)
  206. __ide_mm_outsw((void __iomem *)data_addr, buf, words);
  207. else
  208. outsw(data_addr, buf, words);
  209. }
  210. EXPORT_SYMBOL_GPL(ide_output_data);
  211. const struct ide_tp_ops default_tp_ops = {
  212. .exec_command = ide_exec_command,
  213. .read_status = ide_read_status,
  214. .read_altstatus = ide_read_altstatus,
  215. .write_devctl = ide_write_devctl,
  216. .dev_select = ide_dev_select,
  217. .tf_load = ide_tf_load,
  218. .tf_read = ide_tf_read,
  219. .input_data = ide_input_data,
  220. .output_data = ide_output_data,
  221. };