ide-io-std.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. #include <linux/kernel.h>
  2. #include <linux/ide.h>
  3. /*
  4. * Conventional PIO operations for ATA devices
  5. */
  6. static u8 ide_inb(unsigned long port)
  7. {
  8. return (u8) inb(port);
  9. }
  10. static void ide_outb(u8 val, unsigned long port)
  11. {
  12. outb(val, port);
  13. }
  14. /*
  15. * MMIO operations, typically used for SATA controllers
  16. */
  17. static u8 ide_mm_inb(unsigned long port)
  18. {
  19. return (u8) readb((void __iomem *) port);
  20. }
  21. static void ide_mm_outb(u8 value, unsigned long port)
  22. {
  23. writeb(value, (void __iomem *) port);
  24. }
  25. void ide_exec_command(ide_hwif_t *hwif, u8 cmd)
  26. {
  27. if (hwif->host_flags & IDE_HFLAG_MMIO)
  28. writeb(cmd, (void __iomem *)hwif->io_ports.command_addr);
  29. else
  30. outb(cmd, hwif->io_ports.command_addr);
  31. }
  32. EXPORT_SYMBOL_GPL(ide_exec_command);
  33. u8 ide_read_status(ide_hwif_t *hwif)
  34. {
  35. if (hwif->host_flags & IDE_HFLAG_MMIO)
  36. return readb((void __iomem *)hwif->io_ports.status_addr);
  37. else
  38. return inb(hwif->io_ports.status_addr);
  39. }
  40. EXPORT_SYMBOL_GPL(ide_read_status);
  41. u8 ide_read_altstatus(ide_hwif_t *hwif)
  42. {
  43. if (hwif->host_flags & IDE_HFLAG_MMIO)
  44. return readb((void __iomem *)hwif->io_ports.ctl_addr);
  45. else
  46. return inb(hwif->io_ports.ctl_addr);
  47. }
  48. EXPORT_SYMBOL_GPL(ide_read_altstatus);
  49. void ide_set_irq(ide_hwif_t *hwif, int on)
  50. {
  51. u8 ctl = ATA_DEVCTL_OBS;
  52. if (on == 4) { /* hack for SRST */
  53. ctl |= 4;
  54. on &= ~4;
  55. }
  56. ctl |= on ? 0 : 2;
  57. if (hwif->host_flags & IDE_HFLAG_MMIO)
  58. writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr);
  59. else
  60. outb(ctl, hwif->io_ports.ctl_addr);
  61. }
  62. EXPORT_SYMBOL_GPL(ide_set_irq);
  63. void ide_tf_load(ide_drive_t *drive, ide_task_t *task)
  64. {
  65. ide_hwif_t *hwif = drive->hwif;
  66. struct ide_io_ports *io_ports = &hwif->io_ports;
  67. struct ide_taskfile *tf = &task->tf;
  68. void (*tf_outb)(u8 addr, unsigned long port);
  69. u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
  70. u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
  71. if (mmio)
  72. tf_outb = ide_mm_outb;
  73. else
  74. tf_outb = ide_outb;
  75. if (task->tf_flags & IDE_TFLAG_FLAGGED)
  76. HIHI = 0xFF;
  77. if (task->tf_flags & IDE_TFLAG_OUT_DATA) {
  78. u16 data = (tf->hob_data << 8) | tf->data;
  79. if (mmio)
  80. writew(data, (void __iomem *)io_ports->data_addr);
  81. else
  82. outw(data, io_ports->data_addr);
  83. }
  84. if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
  85. tf_outb(tf->hob_feature, io_ports->feature_addr);
  86. if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
  87. tf_outb(tf->hob_nsect, io_ports->nsect_addr);
  88. if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
  89. tf_outb(tf->hob_lbal, io_ports->lbal_addr);
  90. if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
  91. tf_outb(tf->hob_lbam, io_ports->lbam_addr);
  92. if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
  93. tf_outb(tf->hob_lbah, io_ports->lbah_addr);
  94. if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
  95. tf_outb(tf->feature, io_ports->feature_addr);
  96. if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
  97. tf_outb(tf->nsect, io_ports->nsect_addr);
  98. if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
  99. tf_outb(tf->lbal, io_ports->lbal_addr);
  100. if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
  101. tf_outb(tf->lbam, io_ports->lbam_addr);
  102. if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
  103. tf_outb(tf->lbah, io_ports->lbah_addr);
  104. if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
  105. tf_outb((tf->device & HIHI) | drive->select,
  106. io_ports->device_addr);
  107. }
  108. EXPORT_SYMBOL_GPL(ide_tf_load);
  109. void ide_tf_read(ide_drive_t *drive, ide_task_t *task)
  110. {
  111. ide_hwif_t *hwif = drive->hwif;
  112. struct ide_io_ports *io_ports = &hwif->io_ports;
  113. struct ide_taskfile *tf = &task->tf;
  114. void (*tf_outb)(u8 addr, unsigned long port);
  115. u8 (*tf_inb)(unsigned long port);
  116. u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
  117. if (mmio) {
  118. tf_outb = ide_mm_outb;
  119. tf_inb = ide_mm_inb;
  120. } else {
  121. tf_outb = ide_outb;
  122. tf_inb = ide_inb;
  123. }
  124. if (task->tf_flags & IDE_TFLAG_IN_DATA) {
  125. u16 data;
  126. if (mmio)
  127. data = readw((void __iomem *)io_ports->data_addr);
  128. else
  129. data = inw(io_ports->data_addr);
  130. tf->data = data & 0xff;
  131. tf->hob_data = (data >> 8) & 0xff;
  132. }
  133. /* be sure we're looking at the low order bits */
  134. tf_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
  135. if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
  136. tf->feature = tf_inb(io_ports->feature_addr);
  137. if (task->tf_flags & IDE_TFLAG_IN_NSECT)
  138. tf->nsect = tf_inb(io_ports->nsect_addr);
  139. if (task->tf_flags & IDE_TFLAG_IN_LBAL)
  140. tf->lbal = tf_inb(io_ports->lbal_addr);
  141. if (task->tf_flags & IDE_TFLAG_IN_LBAM)
  142. tf->lbam = tf_inb(io_ports->lbam_addr);
  143. if (task->tf_flags & IDE_TFLAG_IN_LBAH)
  144. tf->lbah = tf_inb(io_ports->lbah_addr);
  145. if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
  146. tf->device = tf_inb(io_ports->device_addr);
  147. if (task->tf_flags & IDE_TFLAG_LBA48) {
  148. tf_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
  149. if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
  150. tf->hob_feature = tf_inb(io_ports->feature_addr);
  151. if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
  152. tf->hob_nsect = tf_inb(io_ports->nsect_addr);
  153. if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
  154. tf->hob_lbal = tf_inb(io_ports->lbal_addr);
  155. if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
  156. tf->hob_lbam = tf_inb(io_ports->lbam_addr);
  157. if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
  158. tf->hob_lbah = tf_inb(io_ports->lbah_addr);
  159. }
  160. }
  161. EXPORT_SYMBOL_GPL(ide_tf_read);
  162. /*
  163. * Some localbus EIDE interfaces require a special access sequence
  164. * when using 32-bit I/O instructions to transfer data. We call this
  165. * the "vlb_sync" sequence, which consists of three successive reads
  166. * of the sector count register location, with interrupts disabled
  167. * to ensure that the reads all happen together.
  168. */
  169. static void ata_vlb_sync(unsigned long port)
  170. {
  171. (void)inb(port);
  172. (void)inb(port);
  173. (void)inb(port);
  174. }
  175. /*
  176. * This is used for most PIO data transfers *from* the IDE interface
  177. *
  178. * These routines will round up any request for an odd number of bytes,
  179. * so if an odd len is specified, be sure that there's at least one
  180. * extra byte allocated for the buffer.
  181. */
  182. void ide_input_data(ide_drive_t *drive, struct request *rq, void *buf,
  183. unsigned int len)
  184. {
  185. ide_hwif_t *hwif = drive->hwif;
  186. struct ide_io_ports *io_ports = &hwif->io_ports;
  187. unsigned long data_addr = io_ports->data_addr;
  188. u8 io_32bit = drive->io_32bit;
  189. u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
  190. len++;
  191. if (io_32bit) {
  192. unsigned long uninitialized_var(flags);
  193. if ((io_32bit & 2) && !mmio) {
  194. local_irq_save(flags);
  195. ata_vlb_sync(io_ports->nsect_addr);
  196. }
  197. if (mmio)
  198. __ide_mm_insl((void __iomem *)data_addr, buf, len / 4);
  199. else
  200. insl(data_addr, buf, len / 4);
  201. if ((io_32bit & 2) && !mmio)
  202. local_irq_restore(flags);
  203. if ((len & 3) >= 2) {
  204. if (mmio)
  205. __ide_mm_insw((void __iomem *)data_addr,
  206. (u8 *)buf + (len & ~3), 1);
  207. else
  208. insw(data_addr, (u8 *)buf + (len & ~3), 1);
  209. }
  210. } else {
  211. if (mmio)
  212. __ide_mm_insw((void __iomem *)data_addr, buf, len / 2);
  213. else
  214. insw(data_addr, buf, len / 2);
  215. }
  216. }
  217. EXPORT_SYMBOL_GPL(ide_input_data);
  218. /*
  219. * This is used for most PIO data transfers *to* the IDE interface
  220. */
  221. void ide_output_data(ide_drive_t *drive, struct request *rq, void *buf,
  222. unsigned int len)
  223. {
  224. ide_hwif_t *hwif = drive->hwif;
  225. struct ide_io_ports *io_ports = &hwif->io_ports;
  226. unsigned long data_addr = io_ports->data_addr;
  227. u8 io_32bit = drive->io_32bit;
  228. u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
  229. len++;
  230. if (io_32bit) {
  231. unsigned long uninitialized_var(flags);
  232. if ((io_32bit & 2) && !mmio) {
  233. local_irq_save(flags);
  234. ata_vlb_sync(io_ports->nsect_addr);
  235. }
  236. if (mmio)
  237. __ide_mm_outsl((void __iomem *)data_addr, buf, len / 4);
  238. else
  239. outsl(data_addr, buf, len / 4);
  240. if ((io_32bit & 2) && !mmio)
  241. local_irq_restore(flags);
  242. if ((len & 3) >= 2) {
  243. if (mmio)
  244. __ide_mm_outsw((void __iomem *)data_addr,
  245. (u8 *)buf + (len & ~3), 1);
  246. else
  247. outsw(data_addr, (u8 *)buf + (len & ~3), 1);
  248. }
  249. } else {
  250. if (mmio)
  251. __ide_mm_outsw((void __iomem *)data_addr, buf, len / 2);
  252. else
  253. outsw(data_addr, buf, len / 2);
  254. }
  255. }
  256. EXPORT_SYMBOL_GPL(ide_output_data);
  257. const struct ide_tp_ops default_tp_ops = {
  258. .exec_command = ide_exec_command,
  259. .read_status = ide_read_status,
  260. .read_altstatus = ide_read_altstatus,
  261. .set_irq = ide_set_irq,
  262. .tf_load = ide_tf_load,
  263. .tf_read = ide_tf_read,
  264. .input_data = ide_input_data,
  265. .output_data = ide_output_data,
  266. };