dma_sbus.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. /* $OpenBSD: dma_sbus.c,v 1.16 2008/06/26 05:42:18 ray Exp $ */
  2. /* $NetBSD: dma_sbus.c,v 1.5 2000/07/09 20:57:42 pk Exp $ */
  3. /*-
  4. * Copyright (c) 1998 The NetBSD Foundation, Inc.
  5. * All rights reserved.
  6. *
  7. * This code is derived from software contributed to The NetBSD Foundation
  8. * by Paul Kranenburg.
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions
  12. * are met:
  13. * 1. Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions and the following disclaimer.
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in the
  17. * documentation and/or other materials provided with the distribution.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
  20. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  21. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  22. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
  23. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  24. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  25. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  26. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  27. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  28. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  29. * POSSIBILITY OF SUCH DAMAGE.
  30. */
  31. /*
  32. * Copyright (c) 1994 Peter Galbavy. All rights reserved.
  33. *
  34. * Redistribution and use in source and binary forms, with or without
  35. * modification, are permitted provided that the following conditions
  36. * are met:
  37. * 1. Redistributions of source code must retain the above copyright
  38. * notice, this list of conditions and the following disclaimer.
  39. * 2. Redistributions in binary form must reproduce the above copyright
  40. * notice, this list of conditions and the following disclaimer in the
  41. * documentation and/or other materials provided with the distribution.
  42. *
  43. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  44. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  45. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  46. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  47. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  48. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  49. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  50. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  51. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  52. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  53. */
  54. #include <sys/types.h>
  55. #include <sys/param.h>
  56. #include <sys/systm.h>
  57. #include <sys/kernel.h>
  58. #include <sys/errno.h>
  59. #include <sys/device.h>
  60. #include <sys/malloc.h>
  61. #include <machine/bus.h>
  62. #include <machine/intr.h>
  63. #include <machine/autoconf.h>
  64. #include <dev/sbus/sbusvar.h>
  65. #include <dev/ic/lsi64854reg.h>
  66. #include <dev/ic/lsi64854var.h>
  67. #include <scsi/scsi_all.h>
  68. #include <scsi/scsiconf.h>
  69. #include <dev/ic/ncr53c9xreg.h>
  70. #include <dev/ic/ncr53c9xvar.h>
  71. struct dma_softc {
  72. struct lsi64854_softc sc_lsi64854; /* base device */
  73. };
  74. int dmamatch_sbus(struct device *, void *, void *);
  75. void dmaattach_sbus(struct device *, struct device *, void *);
  76. int dmaprint_sbus(void *, const char *);
  77. void *dmabus_intr_establish(
  78. bus_space_tag_t,
  79. bus_space_tag_t,
  80. int, /*bus interrupt priority*/
  81. int, /*`device class' level*/
  82. int, /*flags*/
  83. int (*)(void *), /*handler*/
  84. void *, /*handler arg*/
  85. const char *); /*what*/
  86. static bus_space_tag_t dma_alloc_bustag(struct dma_softc *sc);
  87. struct cfattach dma_sbus_ca = {
  88. sizeof(struct dma_softc), dmamatch_sbus, dmaattach_sbus
  89. };
  90. struct cfattach ledma_ca = {
  91. sizeof(struct dma_softc), dmamatch_sbus, dmaattach_sbus
  92. };
  93. struct cfdriver ledma_cd = {
  94. NULL, "ledma", DV_DULL
  95. };
  96. struct cfdriver dma_cd = {
  97. NULL, "dma", DV_DULL
  98. };
  99. int
  100. dmaprint_sbus(void *aux, const char *busname)
  101. {
  102. struct sbus_attach_args *sa = aux;
  103. bus_space_tag_t t = sa->sa_bustag;
  104. struct dma_softc *sc = t->cookie;
  105. sa->sa_bustag = sc->sc_lsi64854.sc_bustag; /* XXX */
  106. sbus_print(aux, busname); /* XXX */
  107. sa->sa_bustag = t; /* XXX */
  108. return (UNCONF);
  109. }
  110. int
  111. dmamatch_sbus(struct device *parent, void *vcf, void *aux)
  112. {
  113. struct cfdata *cf = vcf;
  114. struct sbus_attach_args *sa = aux;
  115. return (strcmp(cf->cf_driver->cd_name, sa->sa_name) == 0 ||
  116. strcmp("espdma", sa->sa_name) == 0);
  117. }
  118. void
  119. dmaattach_sbus(parent, self, aux)
  120. struct device *parent, *self;
  121. void *aux;
  122. {
  123. struct sbus_attach_args *sa = aux;
  124. struct dma_softc *dsc = (void *)self;
  125. struct lsi64854_softc *sc = &dsc->sc_lsi64854;
  126. bus_space_handle_t bh;
  127. bus_space_tag_t sbt;
  128. int sbusburst, burst;
  129. int node;
  130. node = sa->sa_node;
  131. sc->sc_bustag = sa->sa_bustag;
  132. sc->sc_dmatag = sa->sa_dmatag;
  133. /* Map registers */
  134. if (sa->sa_npromvaddrs != 0) {
  135. if (sbus_bus_map(sa->sa_bustag, 0,
  136. sa->sa_promvaddrs[0],
  137. sa->sa_size, /* ???? */
  138. BUS_SPACE_MAP_PROMADDRESS,
  139. 0, &bh) != 0) {
  140. printf("%s: cannot map registers\n", self->dv_xname);
  141. return;
  142. }
  143. } else if (sbus_bus_map(sa->sa_bustag, sa->sa_slot,
  144. sa->sa_offset,
  145. sa->sa_size,
  146. 0, 0, &bh) != 0) {
  147. printf("%s: cannot map registers\n", self->dv_xname);
  148. return;
  149. }
  150. sc->sc_regs = bh;
  151. /*
  152. * Get transfer burst size from PROM and plug it into the
  153. * controller registers. This is needed on the Sun4m; do
  154. * others need it too?
  155. */
  156. sbusburst = ((struct sbus_softc *)parent)->sc_burst;
  157. if (sbusburst == 0)
  158. sbusburst = SBUS_BURST_32 - 1; /* 1->16 */
  159. burst = getpropint(node,"burst-sizes", -1);
  160. if (burst == -1)
  161. /* take SBus burst sizes */
  162. burst = sbusburst;
  163. /* Clamp at parent's burst sizes */
  164. burst &= sbusburst;
  165. sc->sc_burst = (burst & SBUS_BURST_32) ? 32 :
  166. (burst & SBUS_BURST_16) ? 16 : 0;
  167. if (sc->sc_dev.dv_cfdata->cf_attach == &ledma_ca) {
  168. char *cabletype;
  169. u_int32_t csr;
  170. /*
  171. * Check to see which cable type is currently active and
  172. * set the appropriate bit in the ledma csr so that it
  173. * gets used. If we didn't netboot, the PROM won't have
  174. * the "cable-selection" property; default to TP and then
  175. * the user can change it via a "media" option to ifconfig.
  176. */
  177. cabletype = getpropstring(node, "cable-selection");
  178. csr = L64854_GCSR(sc);
  179. if (strcmp(cabletype, "tpe") == 0) {
  180. csr |= E_TP_AUI;
  181. } else if (strcmp(cabletype, "aui") == 0) {
  182. csr &= ~E_TP_AUI;
  183. } else {
  184. /* assume TP if nothing there */
  185. csr |= E_TP_AUI;
  186. }
  187. L64854_SCSR(sc, csr);
  188. delay(20000); /* manual says we need a 20ms delay */
  189. sc->sc_channel = L64854_CHANNEL_ENET;
  190. } else {
  191. sc->sc_channel = L64854_CHANNEL_SCSI;
  192. }
  193. sbt = dma_alloc_bustag(dsc);
  194. if (lsi64854_attach(sc) != 0)
  195. return;
  196. /* Attach children */
  197. for (node = firstchild(sa->sa_node); node; node = nextsibling(node)) {
  198. struct sbus_attach_args sa;
  199. sbus_setup_attach_args((struct sbus_softc *)parent,
  200. sbt, sc->sc_dmatag, node, &sa);
  201. (void) config_found(&sc->sc_dev, (void *)&sa, dmaprint_sbus);
  202. sbus_destroy_attach_args(&sa);
  203. }
  204. }
  205. void *
  206. dmabus_intr_establish(
  207. bus_space_tag_t t,
  208. bus_space_tag_t t0,
  209. int pri,
  210. int level,
  211. int flags,
  212. int (*handler)(void *),
  213. void *arg,
  214. const char *what)
  215. {
  216. struct lsi64854_softc *sc = t->cookie;
  217. /* XXX - for now only le; do esp later */
  218. if (sc->sc_channel == L64854_CHANNEL_ENET) {
  219. sc->sc_intrchain = handler;
  220. sc->sc_intrchainarg = arg;
  221. handler = lsi64854_enet_intr;
  222. arg = sc;
  223. }
  224. for (t = t->parent; t; t = t->parent) {
  225. if (t->sparc_intr_establish != NULL)
  226. return ((*t->sparc_intr_establish)
  227. (t, t0, pri, level, flags, handler, arg, what));
  228. }
  229. panic("dmabus_intr_establish: no handler found");
  230. return (NULL);
  231. }
  232. bus_space_tag_t
  233. dma_alloc_bustag(struct dma_softc *sc)
  234. {
  235. struct sparc_bus_space_tag *sbt;
  236. sbt = malloc(sizeof(*sbt), M_DEVBUF, M_NOWAIT | M_ZERO);
  237. if (sbt == NULL)
  238. return (NULL);
  239. sbt->cookie = sc;
  240. sbt->parent = sc->sc_lsi64854.sc_bustag;
  241. sbt->asi = sbt->parent->asi;
  242. sbt->sasi = sbt->parent->sasi;
  243. sbt->sparc_intr_establish = dmabus_intr_establish;
  244. return (sbt);
  245. }