esp_sbus.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  1. /* $OpenBSD: esp_sbus.c,v 1.24 2014/01/18 22:33:59 dlg Exp $ */
  2. /* $NetBSD: esp_sbus.c,v 1.14 2001/04/25 17:53:37 bouyer Exp $ */
  3. /*-
  4. * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
  5. * All rights reserved.
  6. *
  7. * This code is derived from software contributed to The NetBSD Foundation
  8. * by Charles M. Hannum; Jason R. Thorpe of the Numerical Aerospace
  9. * Simulation Facility, NASA Ames Research Center; Paul Kranenburg.
  10. *
  11. * Redistribution and use in source and binary forms, with or without
  12. * modification, are permitted provided that the following conditions
  13. * are met:
  14. * 1. Redistributions of source code must retain the above copyright
  15. * notice, this list of conditions and the following disclaimer.
  16. * 2. Redistributions in binary form must reproduce the above copyright
  17. * notice, this list of conditions and the following disclaimer in the
  18. * documentation and/or other materials provided with the distribution.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
  21. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  22. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  23. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
  24. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  25. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  26. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  27. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  28. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  29. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  30. * POSSIBILITY OF SUCH DAMAGE.
  31. */
  32. #include <sys/types.h>
  33. #include <sys/param.h>
  34. #include <sys/systm.h>
  35. #include <sys/device.h>
  36. #include <sys/buf.h>
  37. #include <sys/malloc.h>
  38. #include <scsi/scsi_all.h>
  39. #include <scsi/scsiconf.h>
  40. #include <scsi/scsi_message.h>
  41. #include <machine/bus.h>
  42. #include <machine/intr.h>
  43. #include <machine/autoconf.h>
  44. #include <dev/ic/lsi64854reg.h>
  45. #include <dev/ic/lsi64854var.h>
  46. #include <dev/ic/ncr53c9xreg.h>
  47. #include <dev/ic/ncr53c9xvar.h>
  48. #include <dev/sbus/sbusvar.h>
  49. /* #define ESP_SBUS_DEBUG */
  50. static int esp_unit_offset;
  51. struct esp_softc {
  52. struct ncr53c9x_softc sc_ncr53c9x; /* glue to MI code */
  53. bus_space_tag_t sc_bustag;
  54. bus_dma_tag_t sc_dmatag;
  55. bus_space_handle_t sc_reg; /* the registers */
  56. struct lsi64854_softc *sc_dma; /* pointer to my dma */
  57. int sc_pri; /* SBUS priority */
  58. };
  59. void espattach_sbus(struct device *, struct device *, void *);
  60. void espattach_dma(struct device *, struct device *, void *);
  61. int espmatch_sbus(struct device *, void *, void *);
  62. /* Linkup to the rest of the kernel */
  63. struct cfattach esp_sbus_ca = {
  64. sizeof(struct esp_softc), espmatch_sbus, espattach_sbus
  65. };
  66. struct cfattach esp_dma_ca = {
  67. sizeof(struct esp_softc), espmatch_sbus, espattach_dma
  68. };
  69. /*
  70. * Functions and the switch for the MI code.
  71. */
  72. static u_char esp_read_reg(struct ncr53c9x_softc *, int);
  73. static void esp_write_reg(struct ncr53c9x_softc *, int, u_char);
  74. static u_char esp_rdreg1(struct ncr53c9x_softc *, int);
  75. static void esp_wrreg1(struct ncr53c9x_softc *, int, u_char);
  76. static int esp_dma_isintr(struct ncr53c9x_softc *);
  77. static void esp_dma_reset(struct ncr53c9x_softc *);
  78. static int esp_dma_intr(struct ncr53c9x_softc *);
  79. static int esp_dma_setup(struct ncr53c9x_softc *, caddr_t *,
  80. size_t *, int, size_t *);
  81. static void esp_dma_go(struct ncr53c9x_softc *);
  82. static void esp_dma_stop(struct ncr53c9x_softc *);
  83. static int esp_dma_isactive(struct ncr53c9x_softc *);
  84. static struct ncr53c9x_glue esp_sbus_glue = {
  85. esp_read_reg,
  86. esp_write_reg,
  87. esp_dma_isintr,
  88. esp_dma_reset,
  89. esp_dma_intr,
  90. esp_dma_setup,
  91. esp_dma_go,
  92. esp_dma_stop,
  93. esp_dma_isactive,
  94. NULL, /* gl_clear_latched_intr */
  95. };
  96. static struct ncr53c9x_glue esp_sbus_glue1 = {
  97. esp_rdreg1,
  98. esp_wrreg1,
  99. esp_dma_isintr,
  100. esp_dma_reset,
  101. esp_dma_intr,
  102. esp_dma_setup,
  103. esp_dma_go,
  104. esp_dma_stop,
  105. esp_dma_isactive,
  106. NULL, /* gl_clear_latched_intr */
  107. };
  108. static void espattach(struct esp_softc *, struct ncr53c9x_glue *);
  109. int
  110. espmatch_sbus(struct device *parent, void *vcf, void *aux)
  111. {
  112. struct cfdata *cf = vcf;
  113. int rv;
  114. struct sbus_attach_args *sa = aux;
  115. if (strcmp("SUNW,fas", sa->sa_name) == 0)
  116. return 1;
  117. rv = (strcmp(cf->cf_driver->cd_name, sa->sa_name) == 0 ||
  118. strcmp("ptscII", sa->sa_name) == 0);
  119. return (rv);
  120. }
  121. void
  122. espattach_sbus(struct device *parent, struct device *self, void *aux)
  123. {
  124. struct esp_softc *esc = (void *)self;
  125. struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
  126. struct sbus_attach_args *sa = aux;
  127. struct lsi64854_softc *lsc;
  128. int burst, sbusburst;
  129. esc->sc_bustag = sa->sa_bustag;
  130. esc->sc_dmatag = sa->sa_dmatag;
  131. sc->sc_id = getpropint(sa->sa_node, "initiator-id", 7);
  132. sc->sc_freq = getpropint(sa->sa_node, "clock-frequency", -1);
  133. if (sc->sc_freq < 0)
  134. sc->sc_freq = sa->sa_frequency;
  135. #ifdef ESP_SBUS_DEBUG
  136. printf("%s: espattach_sbus: sc_id %d, freq %d\n",
  137. self->dv_xname, sc->sc_id, sc->sc_freq);
  138. #endif
  139. if (strcmp("SUNW,fas", sa->sa_name) == 0) {
  140. /*
  141. * offset searches for other esp/dma devices.
  142. */
  143. esp_unit_offset++;
  144. /*
  145. * fas has 2 register spaces: dma(lsi64854) and SCSI core (ncr53c9x)
  146. */
  147. if (sa->sa_nreg != 2) {
  148. printf("%s: %d register spaces\n", self->dv_xname, sa->sa_nreg);
  149. return;
  150. }
  151. /*
  152. * allocate space for dma, in SUNW,fas there are no separate
  153. * dma device
  154. */
  155. lsc = malloc(sizeof (struct lsi64854_softc), M_DEVBUF, M_NOWAIT);
  156. if (lsc == NULL) {
  157. printf("%s: out of memory (lsi64854_softc)\n",
  158. self->dv_xname);
  159. return;
  160. }
  161. esc->sc_dma = lsc;
  162. lsc->sc_bustag = sa->sa_bustag;
  163. lsc->sc_dmatag = sa->sa_dmatag;
  164. bcopy(sc->sc_dev.dv_xname, lsc->sc_dev.dv_xname,
  165. sizeof (lsc->sc_dev.dv_xname));
  166. /* Map dma registers */
  167. if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
  168. sa->sa_reg[0].sbr_offset, sa->sa_reg[0].sbr_size,
  169. 0, 0, &lsc->sc_regs) != 0) {
  170. printf("%s: cannot map dma registers\n", self->dv_xname);
  171. return;
  172. }
  173. /*
  174. * XXX is this common(from bpp.c), the same in dma_sbus...etc.
  175. *
  176. * Get transfer burst size from PROM and plug it into the
  177. * controller registers. This is needed on the Sun4m; do
  178. * others need it too?
  179. */
  180. sbusburst = ((struct sbus_softc *)parent)->sc_burst;
  181. if (sbusburst == 0)
  182. sbusburst = SBUS_BURST_32 - 1; /* 1->16 */
  183. burst = getpropint(sa->sa_node, "burst-sizes", -1);
  184. #ifdef ESP_SBUS_DEBUG
  185. printf("espattach_sbus: burst 0x%x, sbus 0x%x\n",
  186. burst, sbusburst);
  187. #endif
  188. if (burst == -1)
  189. /* take SBus burst sizes */
  190. burst = sbusburst;
  191. /* Clamp at parent's burst sizes */
  192. burst &= sbusburst;
  193. lsc->sc_burst = (burst & SBUS_BURST_32) ? 32 :
  194. (burst & SBUS_BURST_16) ? 16 : 0;
  195. lsc->sc_channel = L64854_CHANNEL_SCSI;
  196. lsc->sc_client = sc;
  197. lsi64854_attach(lsc);
  198. /*
  199. * map SCSI core registers
  200. */
  201. if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[1].sbr_slot,
  202. sa->sa_reg[1].sbr_offset, sa->sa_reg[1].sbr_size,
  203. 0, 0, &esc->sc_reg) != 0) {
  204. printf("%s: cannot map scsi core registers\n",
  205. self->dv_xname);
  206. return;
  207. }
  208. if (sa->sa_nintr == 0) {
  209. printf("%s: no interrupt property\n", self->dv_xname);
  210. return;
  211. }
  212. esc->sc_pri = sa->sa_pri;
  213. printf("%s", self->dv_xname);
  214. espattach(esc, &esp_sbus_glue);
  215. return;
  216. }
  217. /*
  218. * Find the DMA by poking around the dma device structures
  219. *
  220. * What happens here is that if the dma driver has not been
  221. * configured, then this returns a NULL pointer. Then when the
  222. * dma actually gets configured, it does the opposing test, and
  223. * if the sc->sc_esp field in its softc is NULL, then tries to
  224. * find the matching esp driver.
  225. */
  226. esc->sc_dma = (struct lsi64854_softc *)
  227. getdevunit("dma", sc->sc_dev.dv_unit - esp_unit_offset);
  228. /*
  229. * and a back pointer to us, for DMA
  230. */
  231. if (esc->sc_dma)
  232. esc->sc_dma->sc_client = sc;
  233. else {
  234. printf("\n");
  235. panic("espattach: no dma found");
  236. }
  237. /*
  238. * The `ESC' DMA chip must be reset before we can access
  239. * the esp registers.
  240. */
  241. if (esc->sc_dma->sc_rev == DMAREV_ESC)
  242. DMA_RESET(esc->sc_dma);
  243. /*
  244. * Map my registers in, if they aren't already in virtual
  245. * address space.
  246. */
  247. if (sa->sa_npromvaddrs) {
  248. if (bus_space_map(sa->sa_bustag, sa->sa_promvaddrs[0],
  249. sa->sa_size, BUS_SPACE_MAP_PROMADDRESS,
  250. &esc->sc_reg) != 0) {
  251. printf("%s @ sbus: cannot map registers\n",
  252. self->dv_xname);
  253. return;
  254. }
  255. } else {
  256. if (sbus_bus_map(sa->sa_bustag, sa->sa_slot,
  257. sa->sa_offset, sa->sa_size, 0, 0, &esc->sc_reg) != 0) {
  258. printf("%s @ sbus: cannot map registers\n",
  259. self->dv_xname);
  260. return;
  261. }
  262. }
  263. if (sa->sa_nintr == 0) {
  264. /*
  265. * No interrupt properties: we quit; this might
  266. * happen on e.g. a Sparc X terminal.
  267. */
  268. printf("\n%s: no interrupt property\n", self->dv_xname);
  269. return;
  270. }
  271. esc->sc_pri = sa->sa_pri;
  272. if (strcmp("ptscII", sa->sa_name) == 0) {
  273. espattach(esc, &esp_sbus_glue1);
  274. } else {
  275. espattach(esc, &esp_sbus_glue);
  276. }
  277. }
  278. void
  279. espattach_dma(struct device *parent, struct device *self, void *aux)
  280. {
  281. struct esp_softc *esc = (void *)self;
  282. struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
  283. struct sbus_attach_args *sa = aux;
  284. if (strcmp("ptscII", sa->sa_name) == 0) {
  285. return;
  286. }
  287. esc->sc_bustag = sa->sa_bustag;
  288. esc->sc_dmatag = sa->sa_dmatag;
  289. sc->sc_id = getpropint(sa->sa_node, "initiator-id", 7);
  290. sc->sc_freq = getpropint(sa->sa_node, "clock-frequency", -1);
  291. esc->sc_dma = (struct lsi64854_softc *)parent;
  292. esc->sc_dma->sc_client = sc;
  293. /*
  294. * Map my registers in, if they aren't already in virtual
  295. * address space.
  296. */
  297. if (sa->sa_npromvaddrs) {
  298. if (bus_space_map(sa->sa_bustag, sa->sa_promvaddrs[0],
  299. sa->sa_size /* ??? */, BUS_SPACE_MAP_PROMADDRESS,
  300. &esc->sc_reg) != 0) {
  301. printf("%s @ dma: cannot map registers\n",
  302. self->dv_xname);
  303. return;
  304. }
  305. } else {
  306. if (sbus_bus_map(sa->sa_bustag, sa->sa_slot, sa->sa_offset,
  307. sa->sa_size, 0, 0, &esc->sc_reg) != 0) {
  308. printf("%s @ dma: cannot map registers\n",
  309. self->dv_xname);
  310. return;
  311. }
  312. }
  313. if (sa->sa_nintr == 0) {
  314. /*
  315. * No interrupt properties: we quit; this might
  316. * happen on e.g. a Sparc X terminal.
  317. */
  318. printf("\n%s: no interrupt property\n", self->dv_xname);
  319. return;
  320. }
  321. esc->sc_pri = sa->sa_pri;
  322. espattach(esc, &esp_sbus_glue);
  323. }
  324. /*
  325. * Attach this instance, and then all the sub-devices
  326. */
  327. void
  328. espattach(struct esp_softc *esc, struct ncr53c9x_glue *gluep)
  329. {
  330. struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
  331. void *icookie;
  332. unsigned int uid = 0;
  333. /*
  334. * Set up glue for MI code early; we use some of it here.
  335. */
  336. sc->sc_glue = gluep;
  337. /* gimme MHz */
  338. sc->sc_freq /= 1000000;
  339. /*
  340. * XXX More of this should be in ncr53c9x_attach(), but
  341. * XXX should we really poke around the chip that much in
  342. * XXX the MI code? Think about this more...
  343. */
  344. /*
  345. * It is necessary to try to load the 2nd config register here,
  346. * to find out what rev the esp chip is, else the ncr53c9x_reset
  347. * will not set up the defaults correctly.
  348. */
  349. sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB;
  350. sc->sc_cfg2 = NCRCFG2_SCSI2 | NCRCFG2_RPE;
  351. sc->sc_cfg3 = NCRCFG3_CDB;
  352. NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
  353. if ((NCR_READ_REG(sc, NCR_CFG2) & ~NCRCFG2_RSVD) !=
  354. (NCRCFG2_SCSI2 | NCRCFG2_RPE)) {
  355. sc->sc_rev = NCR_VARIANT_ESP100;
  356. } else {
  357. sc->sc_cfg2 = NCRCFG2_SCSI2;
  358. NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
  359. sc->sc_cfg3 = 0;
  360. NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
  361. sc->sc_cfg3 = (NCRCFG3_CDB | NCRCFG3_FCLK);
  362. NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
  363. if (NCR_READ_REG(sc, NCR_CFG3) !=
  364. (NCRCFG3_CDB | NCRCFG3_FCLK)) {
  365. sc->sc_rev = NCR_VARIANT_ESP100A;
  366. } else {
  367. /* NCRCFG2_FE enables > 64K transfers */
  368. sc->sc_cfg2 |= NCRCFG2_FE;
  369. sc->sc_cfg3 = 0;
  370. NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
  371. sc->sc_rev = NCR_VARIANT_ESP200;
  372. /* XXX spec says it's valid after power up or chip reset */
  373. uid = NCR_READ_REG(sc, NCR_UID);
  374. if (((uid & 0xf8) >> 3) == 0x0a) /* XXX */
  375. sc->sc_rev = NCR_VARIANT_FAS366;
  376. }
  377. }
  378. #ifdef ESP_SBUS_DEBUG
  379. printf("espattach: revision %d, uid 0x%x\n", sc->sc_rev, uid);
  380. #endif
  381. /*
  382. * XXX minsync and maxxfer _should_ be set up in MI code,
  383. * XXX but it appears to have some dependency on what sort
  384. * XXX of DMA we're hooked up to, etc.
  385. */
  386. /*
  387. * This is the value used to start sync negotiations
  388. * Note that the NCR register "SYNCTP" is programmed
  389. * in "clocks per byte", and has a minimum value of 4.
  390. * The SCSI period used in negotiation is one-fourth
  391. * of the time (in nanoseconds) needed to transfer one byte.
  392. * Since the chip's clock is given in MHz, we have the following
  393. * formula: 4 * period = (1000 / freq) * 4
  394. */
  395. sc->sc_minsync = 1000 / sc->sc_freq;
  396. /*
  397. * Alas, we must now modify the value a bit, because it's
  398. * only valid when can switch on FASTCLK and FASTSCSI bits
  399. * in config register 3...
  400. */
  401. switch (sc->sc_rev) {
  402. case NCR_VARIANT_ESP100:
  403. sc->sc_maxxfer = 64 * 1024;
  404. sc->sc_minsync = 0; /* No synch on old chip? */
  405. break;
  406. case NCR_VARIANT_ESP100A:
  407. sc->sc_maxxfer = 64 * 1024;
  408. /* Min clocks/byte is 5 */
  409. sc->sc_minsync = ncr53c9x_cpb2stp(sc, 5);
  410. break;
  411. case NCR_VARIANT_ESP200:
  412. case NCR_VARIANT_FAS366:
  413. sc->sc_maxxfer = 16 * 1024 * 1024;
  414. /* XXX - do actually set FAST* bits */
  415. break;
  416. }
  417. /* Establish interrupt channel */
  418. icookie = bus_intr_establish(esc->sc_bustag, esc->sc_pri, IPL_BIO, 0,
  419. ncr53c9x_intr, sc, sc->sc_dev.dv_xname);
  420. /* Turn on target selection using the `dma' method */
  421. if (sc->sc_rev != NCR_VARIANT_FAS366)
  422. sc->sc_features |= NCR_F_DMASELECT;
  423. /* Do the common parts of attachment. */
  424. ncr53c9x_attach(sc);
  425. }
  426. /*
  427. * Glue functions.
  428. */
  429. #ifdef ESP_SBUS_DEBUG
  430. int esp_sbus_debug = 0;
  431. static struct {
  432. char *r_name;
  433. int r_flag;
  434. } esp__read_regnames [] = {
  435. { "TCL", 0}, /* 0/00 */
  436. { "TCM", 0}, /* 1/04 */
  437. { "FIFO", 0}, /* 2/08 */
  438. { "CMD", 0}, /* 3/0c */
  439. { "STAT", 0}, /* 4/10 */
  440. { "INTR", 0}, /* 5/14 */
  441. { "STEP", 0}, /* 6/18 */
  442. { "FFLAGS", 1}, /* 7/1c */
  443. { "CFG1", 1}, /* 8/20 */
  444. { "STAT2", 0}, /* 9/24 */
  445. { "CFG4", 1}, /* a/28 */
  446. { "CFG2", 1}, /* b/2c */
  447. { "CFG3", 1}, /* c/30 */
  448. { "-none", 1}, /* d/34 */
  449. { "TCH", 1}, /* e/38 */
  450. { "TCX", 1}, /* f/3c */
  451. };
  452. static struct {
  453. char *r_name;
  454. int r_flag;
  455. } esp__write_regnames[] = {
  456. { "TCL", 1}, /* 0/00 */
  457. { "TCM", 1}, /* 1/04 */
  458. { "FIFO", 0}, /* 2/08 */
  459. { "CMD", 0}, /* 3/0c */
  460. { "SELID", 1}, /* 4/10 */
  461. { "TIMEOUT", 1}, /* 5/14 */
  462. { "SYNCTP", 1}, /* 6/18 */
  463. { "SYNCOFF", 1}, /* 7/1c */
  464. { "CFG1", 1}, /* 8/20 */
  465. { "CCF", 1}, /* 9/24 */
  466. { "TEST", 1}, /* a/28 */
  467. { "CFG2", 1}, /* b/2c */
  468. { "CFG3", 1}, /* c/30 */
  469. { "-none", 1}, /* d/34 */
  470. { "TCH", 1}, /* e/38 */
  471. { "TCX", 1}, /* f/3c */
  472. };
  473. #endif
  474. u_char
  475. esp_read_reg(struct ncr53c9x_softc *sc, int reg)
  476. {
  477. struct esp_softc *esc = (struct esp_softc *)sc;
  478. u_char v;
  479. v = bus_space_read_1(esc->sc_bustag, esc->sc_reg, reg * 4);
  480. #ifdef ESP_SBUS_DEBUG
  481. if (esp_sbus_debug && (reg < 0x10) && esp__read_regnames[reg].r_flag)
  482. printf("RD:%x <%s> %x\n", reg * 4,
  483. ((unsigned)reg < 0x10) ? esp__read_regnames[reg].r_name : "<***>", v);
  484. #endif
  485. return v;
  486. }
  487. void
  488. esp_write_reg(struct ncr53c9x_softc *sc, int reg, u_char v)
  489. {
  490. struct esp_softc *esc = (struct esp_softc *)sc;
  491. #ifdef ESP_SBUS_DEBUG
  492. if (esp_sbus_debug && (reg < 0x10) && esp__write_regnames[reg].r_flag)
  493. printf("WR:%x <%s> %x\n", reg * 4,
  494. ((unsigned)reg < 0x10) ? esp__write_regnames[reg].r_name : "<***>", v);
  495. #endif
  496. bus_space_write_1(esc->sc_bustag, esc->sc_reg, reg * 4, v);
  497. }
  498. u_char
  499. esp_rdreg1(struct ncr53c9x_softc *sc, int reg)
  500. {
  501. struct esp_softc *esc = (struct esp_softc *)sc;
  502. return (bus_space_read_1(esc->sc_bustag, esc->sc_reg, reg));
  503. }
  504. void
  505. esp_wrreg1(struct ncr53c9x_softc *sc, int reg, u_char v)
  506. {
  507. struct esp_softc *esc = (struct esp_softc *)sc;
  508. bus_space_write_1(esc->sc_bustag, esc->sc_reg, reg, v);
  509. }
  510. int
  511. esp_dma_isintr(struct ncr53c9x_softc *sc)
  512. {
  513. struct esp_softc *esc = (struct esp_softc *)sc;
  514. return (DMA_ISINTR(esc->sc_dma));
  515. }
  516. void
  517. esp_dma_reset(struct ncr53c9x_softc *sc)
  518. {
  519. struct esp_softc *esc = (struct esp_softc *)sc;
  520. DMA_RESET(esc->sc_dma);
  521. }
  522. int
  523. esp_dma_intr(struct ncr53c9x_softc *sc)
  524. {
  525. struct esp_softc *esc = (struct esp_softc *)sc;
  526. return (DMA_INTR(esc->sc_dma));
  527. }
  528. int
  529. esp_dma_setup(struct ncr53c9x_softc *sc, caddr_t *addr, size_t *len,
  530. int datain, size_t *dmasize)
  531. {
  532. struct esp_softc *esc = (struct esp_softc *)sc;
  533. return (DMA_SETUP(esc->sc_dma, addr, len, datain, dmasize));
  534. }
  535. void
  536. esp_dma_go(struct ncr53c9x_softc *sc)
  537. {
  538. struct esp_softc *esc = (struct esp_softc *)sc;
  539. DMA_GO(esc->sc_dma);
  540. }
  541. void
  542. esp_dma_stop(struct ncr53c9x_softc *sc)
  543. {
  544. struct esp_softc *esc = (struct esp_softc *)sc;
  545. u_int32_t csr;
  546. csr = L64854_GCSR(esc->sc_dma);
  547. csr &= ~D_EN_DMA;
  548. L64854_SCSR(esc->sc_dma, csr);
  549. }
  550. int
  551. esp_dma_isactive(struct ncr53c9x_softc *sc)
  552. {
  553. struct esp_softc *esc = (struct esp_softc *)sc;
  554. return (DMA_ISACTIVE(esc->sc_dma));
  555. }
  556. #if defined(DDB) && defined(notyet)
  557. #include <machine/db_machdep.h>
  558. #include <ddb/db_output.h>
  559. void db_esp(db_expr_t, int, db_expr_t, char *);
  560. void
  561. db_esp(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  562. {
  563. struct ncr53c9x_softc *sc;
  564. struct ncr53c9x_ecb *ecb;
  565. struct ncr53c9x_linfo *li;
  566. int u, t, i;
  567. for (u=0; u<10; u++) {
  568. sc = (struct ncr53c9x_softc *)
  569. getdevunit("esp", u);
  570. if (!sc) continue;
  571. db_printf("esp%d: nexus %p phase %x prev %x dp %p dleft %lx ify %x\n",
  572. u, sc->sc_nexus, sc->sc_phase, sc->sc_prevphase,
  573. sc->sc_dp, sc->sc_dleft, sc->sc_msgify);
  574. db_printf("\tmsgout %x msgpriq %x msgin %x:%x:%x:%x:%x\n",
  575. sc->sc_msgout, sc->sc_msgpriq, sc->sc_imess[0],
  576. sc->sc_imess[1], sc->sc_imess[2], sc->sc_imess[3],
  577. sc->sc_imess[0]);
  578. db_printf("ready: ");
  579. TAILQ_FOREACH(ecb, &sc->ready_list, chain) {
  580. db_printf("ecb %p ", ecb);
  581. if (ecb == TAILQ_NEXT(ecb, chain)) {
  582. db_printf("\nWARNING: tailq loop on ecb %p", ecb);
  583. break;
  584. }
  585. }
  586. db_printf("\n");
  587. for (t=0; t<NCR_NTARG; t++) {
  588. LIST_FOREACH(li, &sc->sc_tinfo[t].luns, link) {
  589. db_printf("t%d lun %d untagged %p busy %d used %x\n",
  590. t, (int)li->lun, li->untagged, li->busy,
  591. li->used);
  592. for (i=0; i<256; i++)
  593. if ((ecb = li->queued[i])) {
  594. db_printf("ecb %p tag %x\n", ecb, i);
  595. }
  596. }
  597. }
  598. }
  599. }
  600. #endif