aic_pcmcia.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /* $OpenBSD: aic_pcmcia.c,v 1.17 2015/03/14 03:38:49 jsg Exp $ */
  2. /* $NetBSD: aic_pcmcia.c,v 1.6 1998/07/19 17:28:15 christos Exp $ */
  3. /*
  4. * Copyright (c) 1997 Marc Horowitz. 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. All advertising materials mentioning features or use of this software
  15. * must display the following acknowledgement:
  16. * This product includes software developed by Marc Horowitz.
  17. * 4. The name of the author may not be used to endorse or promote products
  18. * derived from this software without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  21. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  22. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  23. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  24. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  25. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  29. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. */
  31. #include <sys/param.h>
  32. #include <sys/systm.h>
  33. #include <sys/selinfo.h>
  34. #include <sys/device.h>
  35. #include <machine/cpu.h>
  36. #include <machine/bus.h>
  37. #include <machine/intr.h>
  38. #include <scsi/scsi_all.h>
  39. #include <scsi/scsiconf.h>
  40. #include <dev/ic/aic6360var.h>
  41. #include <dev/pcmcia/pcmciavar.h>
  42. #include <dev/pcmcia/pcmciadevs.h>
  43. int aic_pcmcia_match(struct device *, void *, void *);
  44. void aic_pcmcia_attach(struct device *, struct device *, void *);
  45. int aic_pcmcia_detach(struct device *, int);
  46. struct aic_pcmcia_softc {
  47. struct aic_softc sc_aic; /* real "aic" softc */
  48. /* PCMCIA-specific goo. */
  49. struct pcmcia_io_handle sc_pcioh; /* PCMCIA i/o space info */
  50. int sc_io_window; /* our i/o window */
  51. struct pcmcia_function *sc_pf; /* our PCMCIA function */
  52. void *sc_ih; /* interrupt handler */
  53. };
  54. struct cfattach aic_pcmcia_ca = {
  55. sizeof(struct aic_pcmcia_softc), aic_pcmcia_match, aic_pcmcia_attach,
  56. aic_pcmcia_detach
  57. };
  58. struct aic_pcmcia_product {
  59. u_int16_t app_vendor; /* PCMCIA vendor ID */
  60. u_int16_t app_product; /* PCMCIA product ID */
  61. int app_expfunc; /* expected function number */
  62. } aic_pcmcia_prod[] = {
  63. { PCMCIA_VENDOR_ADAPTEC, PCMCIA_PRODUCT_ADAPTEC_APA1460_1,
  64. 0 },
  65. { PCMCIA_VENDOR_ADAPTEC, PCMCIA_PRODUCT_ADAPTEC_APA1460_2,
  66. 0 },
  67. { PCMCIA_VENDOR_NEWMEDIA, PCMCIA_PRODUCT_NEWMEDIA_BUSTOASTER,
  68. 0 }
  69. };
  70. int
  71. aic_pcmcia_match(parent, match, aux)
  72. struct device *parent;
  73. void *match, *aux;
  74. {
  75. struct pcmcia_attach_args *pa = aux;
  76. int i;
  77. for (i = 0; i < nitems(aic_pcmcia_prod); i++)
  78. if (pa->manufacturer == aic_pcmcia_prod[i].app_vendor &&
  79. pa->product == aic_pcmcia_prod[i].app_product &&
  80. pa->pf->number == aic_pcmcia_prod[i].app_expfunc)
  81. return (1);
  82. return (0);
  83. }
  84. void
  85. aic_pcmcia_attach(parent, self, aux)
  86. struct device *parent, *self;
  87. void *aux;
  88. {
  89. struct aic_pcmcia_softc *psc = (void *)self;
  90. struct aic_softc *sc = &psc->sc_aic;
  91. struct pcmcia_attach_args *pa = aux;
  92. struct pcmcia_config_entry *cfe;
  93. struct pcmcia_function *pf = pa->pf;
  94. const char *intrstr;
  95. psc->sc_pf = pf;
  96. for (cfe = SIMPLEQ_FIRST(&pf->cfe_head); cfe != NULL;
  97. cfe = SIMPLEQ_NEXT(cfe, cfe_list)) {
  98. if (cfe->num_memspace != 0 ||
  99. cfe->num_iospace != 1)
  100. continue;
  101. /* The bustoaster has a default config as first
  102. * entry, we don't want to use that. */
  103. if (pa->manufacturer == PCMCIA_VENDOR_NEWMEDIA &&
  104. pa->product == PCMCIA_PRODUCT_NEWMEDIA_BUSTOASTER &&
  105. cfe->iospace[0].start == 0)
  106. continue;
  107. if (pcmcia_io_alloc(pa->pf, cfe->iospace[0].start,
  108. cfe->iospace[0].length, AIC_NPORTS, &psc->sc_pcioh) == 0)
  109. break;
  110. }
  111. if (cfe == 0) {
  112. printf(": can't alloc i/o space\n");
  113. return;
  114. }
  115. sc->sc_iot = psc->sc_pcioh.iot;
  116. sc->sc_ioh = psc->sc_pcioh.ioh;
  117. /* Enable the card. */
  118. pcmcia_function_init(pf, cfe);
  119. if (pcmcia_function_enable(pf)) {
  120. printf(": function enable failed\n");
  121. return;
  122. }
  123. /* Map in the io space */
  124. if (pcmcia_io_map(pa->pf, PCMCIA_WIDTH_AUTO, 0, psc->sc_pcioh.size,
  125. &psc->sc_pcioh, &psc->sc_io_window)) {
  126. printf(": can't map i/o space\n");
  127. return;
  128. }
  129. printf(" port 0x%lx/%lu", psc->sc_pcioh.addr,
  130. (u_long)psc->sc_pcioh.size);
  131. if (!aic_find(sc->sc_iot, sc->sc_ioh)) {
  132. printf(": unable to detect chip!\n");
  133. return;
  134. }
  135. /* Establish the interrupt handler. */
  136. psc->sc_ih = pcmcia_intr_establish(pa->pf, IPL_BIO,
  137. aicintr, sc, sc->sc_dev.dv_xname);
  138. intrstr = pcmcia_intr_string(psc->sc_pf, psc->sc_ih);
  139. printf("%s%s\n", *intrstr ? ", " : "", intrstr);
  140. if (psc->sc_ih == NULL)
  141. return;
  142. aicattach(sc);
  143. }
  144. int
  145. aic_pcmcia_detach(self, flags)
  146. struct device *self;
  147. int flags;
  148. {
  149. struct aic_pcmcia_softc *sc= (void *)self;
  150. int error;
  151. error = aic_detach(self, flags);
  152. if (error)
  153. return (error);
  154. /* Unmap our i/o window and i/o space. */
  155. pcmcia_io_unmap(sc->sc_pf, sc->sc_io_window);
  156. pcmcia_io_free(sc->sc_pf, &sc->sc_pcioh);
  157. return (0);
  158. }