ata_iobus.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. /*-
  2. * SPDX-License-Identifier: BSD-3-Clause
  3. *
  4. * Copyright 2002 by Peter Grehan. All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * 3. The name of the author may not be used to endorse or promote products
  15. * derived from this software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  22. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  23. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  24. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  25. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27. * SUCH DAMAGE.
  28. */
  29. #include <sys/cdefs.h>
  30. __FBSDID("$FreeBSD$");
  31. /*
  32. * PSIM local bus ATA controller
  33. */
  34. #include <sys/param.h>
  35. #include <sys/systm.h>
  36. #include <sys/kernel.h>
  37. #include <sys/module.h>
  38. #include <sys/bus.h>
  39. #include <sys/malloc.h>
  40. #include <sys/sema.h>
  41. #include <sys/taskqueue.h>
  42. #include <machine/stdarg.h>
  43. #include <vm/uma.h>
  44. #include <machine/resource.h>
  45. #include <machine/bus.h>
  46. #include <sys/rman.h>
  47. #include <sys/ata.h>
  48. #include <dev/ata/ata-all.h>
  49. #include <ata_if.h>
  50. #include <dev/ofw/openfirm.h>
  51. #include <powerpc/psim/iobusvar.h>
  52. /*
  53. * Define the iobus ata bus attachment. This creates a pseudo-bus that
  54. * the ATA device can be attached to
  55. */
  56. static int ata_iobus_attach(device_t dev);
  57. static int ata_iobus_probe(device_t dev);
  58. static int ata_iobus_print_child(device_t dev, device_t child);
  59. struct resource *ata_iobus_alloc_resource(device_t, device_t, int, int *,
  60. rman_res_t, rman_res_t, rman_res_t,
  61. u_int);
  62. static int ata_iobus_release_resource(device_t, device_t, int, int,
  63. struct resource *);
  64. static device_method_t ata_iobus_methods[] = {
  65. /* Device interface */
  66. DEVMETHOD(device_probe, ata_iobus_probe),
  67. DEVMETHOD(device_attach, ata_iobus_attach),
  68. DEVMETHOD(device_shutdown, bus_generic_shutdown),
  69. DEVMETHOD(device_suspend, bus_generic_suspend),
  70. DEVMETHOD(device_resume, bus_generic_resume),
  71. /* Bus methods */
  72. DEVMETHOD(bus_print_child, ata_iobus_print_child),
  73. DEVMETHOD(bus_alloc_resource, ata_iobus_alloc_resource),
  74. DEVMETHOD(bus_release_resource, ata_iobus_release_resource),
  75. DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
  76. DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
  77. DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
  78. DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
  79. DEVMETHOD_END
  80. };
  81. static driver_t ata_iobus_driver = {
  82. "ataiobus",
  83. ata_iobus_methods,
  84. 0,
  85. };
  86. static devclass_t ata_iobus_devclass;
  87. DRIVER_MODULE(ataiobus, iobus, ata_iobus_driver, ata_iobus_devclass, NULL,
  88. NULL);
  89. MODULE_DEPEND(ata, ata, 1, 1, 1);
  90. static int
  91. ata_iobus_probe(device_t dev)
  92. {
  93. char *type = iobus_get_name(dev);
  94. if (strncmp(type, "ata", 3) != 0)
  95. return (ENXIO);
  96. device_set_desc(dev, "PSIM ATA Controller");
  97. return (0);
  98. }
  99. static int
  100. ata_iobus_attach(device_t dev)
  101. {
  102. /*
  103. * Add a single child per controller. Should be able
  104. * to add two
  105. */
  106. device_add_child(dev, "ata", -1);
  107. return (bus_generic_attach(dev));
  108. }
  109. static int
  110. ata_iobus_print_child(device_t dev, device_t child)
  111. {
  112. int retval = 0;
  113. retval += bus_print_child_header(dev, child);
  114. /* irq ? */
  115. retval += bus_print_child_footer(dev, child);
  116. return (retval);
  117. }
  118. struct resource *
  119. ata_iobus_alloc_resource(device_t dev, device_t child, int type, int *rid,
  120. rman_res_t start, rman_res_t end, rman_res_t count,
  121. u_int flags)
  122. {
  123. struct resource *res = NULL;
  124. int myrid;
  125. u_int *ofw_regs;
  126. ofw_regs = iobus_get_regs(dev);
  127. /*
  128. * The reg array for the PSIM ata device has 6 start/size entries:
  129. * 0 - unused
  130. * 1/2/3 - unused
  131. * 4/5/6 - primary command
  132. * 7/8/9 - secondary command
  133. * 10/11/12 - primary control
  134. * 13/14/15 - secondary control
  135. * 16/17/18 - primary/secondary dma registers, unimplemented
  136. *
  137. * The resource values are calculated from these registers
  138. */
  139. if (type == SYS_RES_IOPORT) {
  140. switch (*rid) {
  141. case ATA_IOADDR_RID:
  142. myrid = 0;
  143. start = ofw_regs[4];
  144. end = start + ATA_IOSIZE - 1;
  145. count = ATA_IOSIZE;
  146. res = BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
  147. SYS_RES_MEMORY, &myrid,
  148. start, end, count, flags);
  149. break;
  150. case ATA_CTLADDR_RID:
  151. myrid = 0;
  152. start = ofw_regs[10];
  153. end = start + ATA_CTLIOSIZE - 1;
  154. count = ATA_CTLIOSIZE;
  155. res = BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
  156. SYS_RES_MEMORY, &myrid,
  157. start, end, count, flags);
  158. break;
  159. case ATA_BMADDR_RID:
  160. /* DMA not properly supported by psim */
  161. break;
  162. }
  163. return (res);
  164. } else if (type == SYS_RES_IRQ && *rid == ATA_IRQ_RID) {
  165. /*
  166. * Pass this on to the parent
  167. */
  168. return (BUS_ALLOC_RESOURCE(device_get_parent(dev), dev,
  169. SYS_RES_IRQ, rid, 0, ~0, 1, flags));
  170. } else {
  171. return (NULL);
  172. }
  173. }
  174. static int
  175. ata_iobus_release_resource(device_t dev, device_t child, int type, int rid,
  176. struct resource *r)
  177. {
  178. /* no hotplug... */
  179. return (0);
  180. }
  181. /*
  182. * Define the actual ATA device. This is a sub-bus to the ata-iobus layer
  183. * to allow the higher layer bus to massage the resource allocation.
  184. */
  185. static int ata_iobus_sub_probe(device_t dev);
  186. static int ata_iobus_sub_setmode(device_t dev, int target, int mode);
  187. static device_method_t ata_iobus_sub_methods[] = {
  188. /* Device interface */
  189. DEVMETHOD(device_probe, ata_iobus_sub_probe),
  190. DEVMETHOD(device_attach, ata_attach),
  191. DEVMETHOD(device_detach, ata_detach),
  192. DEVMETHOD(device_resume, ata_resume),
  193. /* ATA interface */
  194. DEVMETHOD(ata_setmode, ata_iobus_sub_setmode),
  195. DEVMETHOD_END
  196. };
  197. static driver_t ata_iobus_sub_driver = {
  198. "ata",
  199. ata_iobus_sub_methods,
  200. sizeof(struct ata_channel),
  201. };
  202. DRIVER_MODULE(ata, ataiobus, ata_iobus_sub_driver, ata_devclass, NULL, NULL);
  203. static int
  204. ata_iobus_sub_probe(device_t dev)
  205. {
  206. struct ata_channel *ch = device_get_softc(dev);
  207. /* Only a single unit per controller thus far */
  208. ch->unit = 0;
  209. ch->flags = (ATA_USE_16BIT|ATA_NO_SLAVE);
  210. ata_generic_hw(dev);
  211. return ata_probe(dev);
  212. }
  213. static int
  214. ata_iobus_sub_setmode(device_t parent, int target, int mode)
  215. {
  216. /* Only ever PIO mode here... */
  217. return (ATA_PIO);
  218. }