The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ic/i82365.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $OpenBSD: i82365.c,v 1.40 2021/03/07 06:21:38 jsg Exp $ */
    2 /*      $NetBSD: i82365.c,v 1.10 1998/06/09 07:36:55 thorpej Exp $      */
    3 
    4 /*
    5  * Copyright (c) 1997 Marc Horowitz.  All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. All advertising materials mentioning features or use of this software
   16  *    must display the following acknowledgement:
   17  *      This product includes software developed by Marc Horowitz.
   18  * 4. The name of the author may not be used to endorse or promote products
   19  *    derived from this software without specific prior written permission.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   31  */
   32 
   33 #include <sys/param.h>
   34 #include <sys/systm.h>
   35 #include <sys/device.h>
   36 #include <sys/extent.h>
   37 #include <sys/kernel.h>
   38 #include <sys/malloc.h>
   39 #include <sys/kthread.h>
   40 
   41 #include <machine/bus.h>
   42 #include <machine/intr.h>
   43 
   44 #include <dev/pcmcia/pcmciareg.h>
   45 #include <dev/pcmcia/pcmciavar.h>
   46 
   47 #include <dev/ic/i82365reg.h>
   48 #include <dev/ic/i82365var.h>
   49 
   50 #ifdef PCICDEBUG
   51 #define DPRINTF(arg)    printf arg;
   52 #else
   53 #define DPRINTF(arg)
   54 #endif
   55 
   56 #define PCIC_VENDOR_UNKNOWN             0
   57 #define PCIC_VENDOR_I82365SLR0          1
   58 #define PCIC_VENDOR_I82365SLR1          2
   59 #define PCIC_VENDOR_I82365SLR2          3
   60 #define PCIC_VENDOR_CIRRUS_PD6710       4
   61 #define PCIC_VENDOR_CIRRUS_PD672X       5
   62 #define PCIC_VENDOR_VADEM_VG468         6
   63 #define PCIC_VENDOR_VADEM_VG469         7
   64 
   65 static char *pcic_vendor_to_string[] = {
   66         "Unknown",
   67         "Intel 82365SL rev 0",
   68         "Intel 82365SL rev 1",
   69         "Intel 82365SL rev 2",
   70         "Cirrus PD6710",
   71         "Cirrus PD672X",
   72         "Vadem VG468",
   73         "Vadem VG469",
   74 };
   75 
   76 /*
   77  * Individual drivers will allocate their own memory and io regions. Memory
   78  * regions must be a multiple of 4k, aligned on a 4k boundary.
   79  */
   80 
   81 #define PCIC_MEM_ALIGN  PCIC_MEM_PAGESIZE
   82 
   83 void    pcic_attach_socket(struct pcic_handle *);
   84 void    pcic_init_socket(struct pcic_handle *);
   85 
   86 int     pcic_submatch(struct device *, void *, void *);
   87 int     pcic_print(void *arg, const char *pnp);
   88 int     pcic_intr_socket(struct pcic_handle *);
   89 
   90 void    pcic_attach_card(struct pcic_handle *);
   91 void    pcic_detach_card(struct pcic_handle *, int);
   92 void    pcic_deactivate_card(struct pcic_handle *);
   93 
   94 void    pcic_chip_do_mem_map(struct pcic_handle *, int);
   95 void    pcic_chip_do_io_map(struct pcic_handle *, int);
   96 
   97 void    pcic_create_event_thread(void *);
   98 void    pcic_event_thread(void *);
   99 void    pcic_event_process(struct pcic_handle *, struct pcic_event *);
  100 void    pcic_queue_event(struct pcic_handle *, int);
  101 
  102 void    pcic_wait_ready(struct pcic_handle *);
  103 
  104 u_int8_t st_pcic_read(struct pcic_handle *, int);
  105 void    st_pcic_write(struct pcic_handle *, int, int);
  106 
  107 struct cfdriver pcic_cd = {
  108         NULL, "pcic", DV_DULL
  109 };
  110 
  111 int
  112 pcic_ident_ok(int ident)
  113 {
  114         /* this is very empirical and heuristic */
  115 
  116         if (ident == 0 || ident == 0xff || (ident & PCIC_IDENT_ZERO))
  117                 return (0);
  118 
  119         if ((ident & PCIC_IDENT_IFTYPE_MASK) != PCIC_IDENT_IFTYPE_MEM_AND_IO) {
  120 #ifdef DEBUG
  121                 printf("pcic: does not support memory and I/O cards, "
  122                     "ignored (ident=%0x)\n", ident);
  123 #endif
  124                 return (0);
  125         }
  126         return (1);
  127 }
  128 
  129 int
  130 pcic_vendor(struct pcic_handle *h)
  131 {
  132         int vendor, reg;
  133 
  134         /*
  135          * the chip_id of the cirrus toggles between 11 and 00 after a write.
  136          * weird.
  137          */
  138 
  139         pcic_write(h, PCIC_CIRRUS_CHIP_INFO, 0);
  140         reg = pcic_read(h, -1);
  141 
  142         if ((reg & PCIC_CIRRUS_CHIP_INFO_CHIP_ID) ==
  143             PCIC_CIRRUS_CHIP_INFO_CHIP_ID) {
  144                 reg = pcic_read(h, -1);
  145                 if ((reg & PCIC_CIRRUS_CHIP_INFO_CHIP_ID) == 0) {
  146                         if (reg & PCIC_CIRRUS_CHIP_INFO_SLOTS)
  147                                 return (PCIC_VENDOR_CIRRUS_PD672X);
  148                         else
  149                                 return (PCIC_VENDOR_CIRRUS_PD6710);
  150                 }
  151         }
  152 
  153         reg = pcic_read(h, PCIC_IDENT);
  154 
  155         switch (reg) {
  156         case PCIC_IDENT_REV_I82365SLR0:
  157                 vendor = PCIC_VENDOR_I82365SLR0;
  158                 break;
  159         case PCIC_IDENT_REV_I82365SLR1:
  160                 vendor = PCIC_VENDOR_I82365SLR1;
  161                 break;
  162         case PCIC_IDENT_REV_I82365SLR2:
  163                 vendor = PCIC_VENDOR_I82365SLR2;
  164                 break;
  165         default:
  166                 vendor = PCIC_VENDOR_UNKNOWN;
  167                 break;
  168         }
  169 
  170         pcic_write(h, 0x0e, -1);
  171         pcic_write(h, 0x37, -1);
  172 
  173         reg = pcic_read(h, PCIC_VG468_MISC);
  174         reg |= PCIC_VG468_MISC_VADEMREV;
  175         pcic_write(h, PCIC_VG468_MISC, reg);
  176 
  177         reg = pcic_read(h, PCIC_IDENT);
  178 
  179         if (reg & PCIC_IDENT_VADEM_MASK) {
  180                 if ((reg & 7) >= 4)
  181                         vendor = PCIC_VENDOR_VADEM_VG469;
  182                 else
  183                         vendor = PCIC_VENDOR_VADEM_VG468;
  184 
  185                 reg = pcic_read(h, PCIC_VG468_MISC);
  186                 reg &= ~PCIC_VG468_MISC_VADEMREV;
  187                 pcic_write(h, PCIC_VG468_MISC, reg);
  188         }
  189 
  190         return (vendor);
  191 }
  192 
  193 void
  194 pcic_attach(struct pcic_softc *sc)
  195 {
  196         int vendor, count, i, reg;
  197 
  198         /* now check for each controller/socket */
  199 
  200         /*
  201          * this could be done with a loop, but it would violate the
  202          * abstraction
  203          */
  204 
  205         count = 0;
  206 
  207         DPRINTF(("pcic ident regs:"));
  208 
  209         sc->handle[0].ph_parent = (struct device *)sc;
  210         sc->handle[0].sock = C0SA;
  211         /* initialise pcic_read and pcic_write functions */
  212         sc->handle[0].ph_read = st_pcic_read;
  213         sc->handle[0].ph_write = st_pcic_write;
  214         sc->handle[0].ph_bus_t = sc->iot;
  215         sc->handle[0].ph_bus_h = sc->ioh;
  216         if (pcic_ident_ok(reg = pcic_read(&sc->handle[0], PCIC_IDENT))) {
  217                 sc->handle[0].flags = PCIC_FLAG_SOCKETP;
  218                 count++;
  219         } else {
  220                 sc->handle[0].flags = 0;
  221         }
  222         sc->handle[0].laststate = PCIC_LASTSTATE_EMPTY;
  223 
  224         DPRINTF((" 0x%02x", reg));
  225 
  226         sc->handle[1].ph_parent = (struct device *)sc;
  227         sc->handle[1].sock = C0SB;
  228         /* initialise pcic_read and pcic_write functions */
  229         sc->handle[1].ph_read = st_pcic_read;
  230         sc->handle[1].ph_write = st_pcic_write;
  231         sc->handle[1].ph_bus_t = sc->iot;
  232         sc->handle[1].ph_bus_h = sc->ioh;
  233         if (pcic_ident_ok(reg = pcic_read(&sc->handle[1], PCIC_IDENT))) {
  234                 sc->handle[1].flags = PCIC_FLAG_SOCKETP;
  235                 count++;
  236         } else {
  237                 sc->handle[1].flags = 0;
  238         }
  239         sc->handle[1].laststate = PCIC_LASTSTATE_EMPTY;
  240 
  241         DPRINTF((" 0x%02x", reg));
  242 
  243         /*
  244          * The CL-PD6729 has only one controller and always returns 0
  245          * if you try to read from the second one. Maybe pcic_ident_ok
  246          * shouldn't accept 0?
  247          */
  248         sc->handle[2].ph_parent = (struct device *)sc;
  249         sc->handle[2].sock = C1SA;
  250         /* initialise pcic_read and pcic_write functions */
  251         sc->handle[2].ph_read = st_pcic_read;
  252         sc->handle[2].ph_write = st_pcic_write;
  253         sc->handle[2].ph_bus_t = sc->iot;
  254         sc->handle[2].ph_bus_h = sc->ioh;
  255         if (pcic_vendor(&sc->handle[0]) != PCIC_VENDOR_CIRRUS_PD672X ||
  256             pcic_read(&sc->handle[2], PCIC_IDENT) != 0) {
  257                 if (pcic_ident_ok(reg = pcic_read(&sc->handle[2],
  258                     PCIC_IDENT))) {
  259                         sc->handle[2].flags = PCIC_FLAG_SOCKETP;
  260                         count++;
  261                 } else {
  262                         sc->handle[2].flags = 0;
  263                 }
  264                 sc->handle[2].laststate = PCIC_LASTSTATE_EMPTY;
  265 
  266                 DPRINTF((" 0x%02x", reg));
  267 
  268                 sc->handle[3].ph_parent = (struct device *)sc;
  269                 sc->handle[3].sock = C1SB;
  270                 /* initialise pcic_read and pcic_write functions */
  271                 sc->handle[3].ph_read = st_pcic_read;
  272                 sc->handle[3].ph_write = st_pcic_write;
  273                 sc->handle[3].ph_bus_t = sc->iot;
  274                 sc->handle[3].ph_bus_h = sc->ioh;
  275                 if (pcic_ident_ok(reg = pcic_read(&sc->handle[3],
  276                     PCIC_IDENT))) {
  277                         sc->handle[3].flags = PCIC_FLAG_SOCKETP;
  278                         count++;
  279                 } else {
  280                         sc->handle[3].flags = 0;
  281                 }
  282                 sc->handle[3].laststate = PCIC_LASTSTATE_EMPTY;
  283 
  284                 DPRINTF((" 0x%02x\n", reg));
  285         } else {
  286                 sc->handle[2].flags = 0;
  287                 sc->handle[3].flags = 0;
  288         }
  289 
  290         if (count == 0)
  291                 return;
  292 
  293         /* establish the interrupt */
  294 
  295         /* XXX block interrupts? */
  296 
  297         for (i = 0; i < PCIC_NSLOTS; i++) {
  298                 /*
  299                  * this should work, but w/o it, setting tty flags hangs at
  300                  * boot time.
  301                  */
  302                 if (sc->handle[i].flags & PCIC_FLAG_SOCKETP) {
  303                         SIMPLEQ_INIT(&sc->handle[i].events);
  304                         pcic_write(&sc->handle[i], PCIC_CSC_INTR, 0);
  305                         pcic_read(&sc->handle[i], PCIC_CSC);
  306                 }
  307         }
  308 
  309         for (i = 0; i < PCIC_NSLOTS; i += 2) {
  310                 if ((sc->handle[i+0].flags & PCIC_FLAG_SOCKETP) ||
  311                     (sc->handle[i+1].flags & PCIC_FLAG_SOCKETP)) {
  312                         vendor = pcic_vendor(&sc->handle[i]);
  313 
  314                         printf("%s controller %d: <%s> has socket",
  315                             sc->dev.dv_xname, i/2,
  316                             pcic_vendor_to_string[vendor]);
  317 
  318                         if ((sc->handle[i+0].flags & PCIC_FLAG_SOCKETP) &&
  319                             (sc->handle[i+1].flags & PCIC_FLAG_SOCKETP))
  320                                 printf("s A and B\n");
  321                         else if (sc->handle[i+0].flags & PCIC_FLAG_SOCKETP)
  322                                 printf(" A only\n");
  323                         else
  324                                 printf(" B only\n");
  325 
  326                         if (sc->handle[i+0].flags & PCIC_FLAG_SOCKETP)
  327                                 sc->handle[i+0].vendor = vendor;
  328                         if (sc->handle[i+1].flags & PCIC_FLAG_SOCKETP)
  329                                 sc->handle[i+1].vendor = vendor;
  330                 }
  331         }
  332 }
  333 
  334 void
  335 pcic_attach_sockets(struct pcic_softc *sc)
  336 {
  337         int i;
  338 
  339         for (i = 0; i < PCIC_NSLOTS; i++)
  340                 if (sc->handle[i].flags & PCIC_FLAG_SOCKETP)
  341                         pcic_attach_socket(&sc->handle[i]);
  342 }
  343 
  344 void
  345 pcic_attach_socket(struct pcic_handle *h)
  346 {
  347         struct pcmciabus_attach_args paa;
  348         struct pcic_softc *sc = (struct pcic_softc *)(h->ph_parent);
  349 
  350         /* initialize the rest of the handle */
  351 
  352         h->shutdown = 0;
  353         h->memalloc = 0;
  354         h->ioalloc = 0;
  355         h->ih_irq = 0;
  356 
  357         /* now, config one pcmcia device per socket */
  358 
  359         paa.paa_busname = "pcmcia";
  360         paa.pct = (pcmcia_chipset_tag_t) sc->pct;
  361         paa.pch = (pcmcia_chipset_handle_t) h;
  362         paa.iobase = sc->iobase;
  363         paa.iosize = sc->iosize;
  364 
  365         h->pcmcia = config_found_sm(&sc->dev, &paa, pcic_print,
  366             pcic_submatch);
  367 
  368         /* if there's actually a pcmcia device attached, initialize the slot */
  369 
  370         if (h->pcmcia)
  371                 pcic_init_socket(h);
  372         else
  373                 h->flags &= ~PCIC_FLAG_SOCKETP;
  374 }
  375 
  376 void
  377 pcic_create_event_thread(void *arg)
  378 {
  379         struct pcic_handle *h = arg;
  380         char name[MAXCOMLEN+1];
  381         const char *cs;
  382 
  383         switch (h->sock) {
  384         case C0SA:
  385                 cs = "0,0";
  386                 break;
  387         case C0SB:
  388                 cs = "0,1";
  389                 break;
  390         case C1SA:
  391                 cs = "1,0";
  392                 break;
  393         case C1SB:
  394                 cs = "1,1";
  395                 break;
  396         default:
  397                 panic("pcic_create_event_thread: unknown pcic socket");
  398         }
  399 
  400         snprintf(name, sizeof name, "%s,%s", h->ph_parent->dv_xname, cs);
  401         if (kthread_create(pcic_event_thread, h, &h->event_thread, name)) {
  402                 printf("%s: unable to create event thread for sock 0x%02x\n",
  403                     h->ph_parent->dv_xname, h->sock);
  404                 panic("pcic_create_event_thread");
  405         }
  406 }
  407 
  408 void
  409 pcic_event_thread(void *arg)
  410 {
  411         struct pcic_handle *h = arg;
  412         struct pcic_event *pe;
  413         int s;
  414         struct pcic_softc *sc = (struct pcic_softc *)(h->ph_parent);
  415 
  416         while (h->shutdown == 0) {
  417                 s = splhigh();
  418                 if ((pe = SIMPLEQ_FIRST(&h->events)) == NULL) {
  419                         splx(s);
  420                         tsleep_nsec(&h->events, PWAIT, "pcicev", INFSLP);
  421                         continue;
  422                 } else {
  423                         splx(s);
  424                         /* sleep .25s to be enqueued chatterling interrupts */
  425                         tsleep_nsec(pcic_event_thread, PWAIT, "pcicss",
  426                             MSEC_TO_NSEC(250));
  427                 }
  428                 pcic_event_process(h, pe);
  429         }
  430 
  431         h->event_thread = NULL;
  432 
  433         /* In case parent is waiting for us to exit. */
  434         wakeup(sc);
  435 
  436         kthread_exit(0);
  437 }
  438 
  439 void
  440 pcic_event_process(struct pcic_handle *h, struct pcic_event *pe)
  441 {
  442         int s;
  443 
  444         s = splhigh();
  445         SIMPLEQ_REMOVE_HEAD(&h->events, pe_q);
  446         splx(s);
  447 
  448         switch (pe->pe_type) {
  449         case PCIC_EVENT_INSERTION:
  450                 s = splhigh();
  451                 while (1) {
  452                         struct pcic_event *pe1, *pe2;
  453 
  454                         if ((pe1 = SIMPLEQ_FIRST(&h->events)) == NULL)
  455                                 break;
  456                         if (pe1->pe_type != PCIC_EVENT_REMOVAL)
  457                                 break;
  458                         if ((pe2 = SIMPLEQ_NEXT(pe1, pe_q)) == NULL)
  459                                 break;
  460                         if (pe2->pe_type == PCIC_EVENT_INSERTION) {
  461                                 SIMPLEQ_REMOVE_HEAD(&h->events, pe_q);
  462                                 free(pe1, M_TEMP, sizeof *pe1);
  463                                 SIMPLEQ_REMOVE_HEAD(&h->events, pe_q);
  464                                 free(pe2, M_TEMP, sizeof *pe2);
  465                         }
  466                 }
  467                 splx(s);
  468                                 
  469                 DPRINTF(("%s: insertion event\n", h->ph_parent->dv_xname));
  470                 pcic_attach_card(h);
  471                 break;
  472 
  473         case PCIC_EVENT_REMOVAL:
  474                 s = splhigh();
  475                 while (1) {
  476                         struct pcic_event *pe1, *pe2;
  477 
  478                         if ((pe1 = SIMPLEQ_FIRST(&h->events)) == NULL)
  479                                 break;
  480                         if (pe1->pe_type != PCIC_EVENT_INSERTION)
  481                                 break;
  482                         if ((pe2 = SIMPLEQ_NEXT(pe1, pe_q)) == NULL)
  483                                 break;
  484                         if (pe2->pe_type == PCIC_EVENT_REMOVAL) {
  485                                 SIMPLEQ_REMOVE_HEAD(&h->events, pe_q);
  486                                 free(pe1, M_TEMP, sizeof *pe1);
  487                                 SIMPLEQ_REMOVE_HEAD(&h->events, pe_q);
  488                                 free(pe2, M_TEMP, sizeof *pe1);
  489                         }
  490                 }
  491                 splx(s);
  492 
  493                 DPRINTF(("%s: removal event\n", h->ph_parent->dv_xname));
  494                 pcic_detach_card(h, DETACH_FORCE);
  495                 break;
  496 
  497         default:
  498                 panic("pcic_event_thread: unknown event %d", pe->pe_type);
  499         }
  500         free(pe, M_TEMP, sizeof *pe);
  501 }
  502 
  503 void
  504 pcic_init_socket(struct pcic_handle *h)
  505 {
  506         int reg;
  507         struct pcic_softc *sc = (struct pcic_softc *)(h->ph_parent);
  508 
  509         /*
  510          * queue creation of a kernel thread to handle insert/removal events.
  511          */
  512 #ifdef DIAGNOSTIC
  513         if (h->event_thread != NULL)
  514                 panic("pcic_attach_socket: event thread");
  515 #endif
  516         kthread_create_deferred(pcic_create_event_thread, h);
  517 
  518         /* set up the card to interrupt on card detect */
  519 
  520         pcic_write(h, PCIC_CSC_INTR, (sc->irq << PCIC_CSC_INTR_IRQ_SHIFT) |
  521             PCIC_CSC_INTR_CD_ENABLE);
  522         pcic_write(h, PCIC_INTR, 0);
  523         pcic_read(h, PCIC_CSC);
  524 
  525         /* unsleep the cirrus controller */
  526 
  527         if ((h->vendor == PCIC_VENDOR_CIRRUS_PD6710) ||
  528             (h->vendor == PCIC_VENDOR_CIRRUS_PD672X)) {
  529                 reg = pcic_read(h, PCIC_CIRRUS_MISC_CTL_2);
  530                 if (reg & PCIC_CIRRUS_MISC_CTL_2_SUSPEND) {
  531                         DPRINTF(("%s: socket %02x was suspended\n",
  532                             h->ph_parent->dv_xname, h->sock));
  533                         reg &= ~PCIC_CIRRUS_MISC_CTL_2_SUSPEND;
  534                         pcic_write(h, PCIC_CIRRUS_MISC_CTL_2, reg);
  535                 }
  536         }
  537         /* if there's a card there, then attach it. */
  538 
  539         reg = pcic_read(h, PCIC_IF_STATUS);
  540 
  541         if ((reg & PCIC_IF_STATUS_CARDDETECT_MASK) ==
  542             PCIC_IF_STATUS_CARDDETECT_PRESENT) {
  543                 pcic_attach_card(h);
  544                 h->laststate = PCIC_LASTSTATE_PRESENT;
  545         } else
  546                 h->laststate = PCIC_LASTSTATE_EMPTY;
  547 }
  548 
  549 int
  550 pcic_submatch(struct device *parent, void *match, void *aux)
  551 {
  552         struct cfdata *cf = match;
  553         struct pcmciabus_attach_args *paa = aux;
  554         struct pcic_handle *h = (struct pcic_handle *) paa->pch;
  555 
  556         switch (h->sock) {
  557         case C0SA:
  558                 if (cf->cf_loc[0 /* PCICCF_CONTROLLER */] !=
  559                     -1 /* PCICCF_CONTROLLER_DEFAULT */ &&
  560                     cf->cf_loc[0 /* PCICCF_CONTROLLER */] != 0)
  561                         return 0;
  562                 if (cf->cf_loc[1 /* PCICCF_SOCKET */] !=
  563                     -1 /* PCICCF_SOCKET_DEFAULT */ &&
  564                     cf->cf_loc[1 /* PCICCF_SOCKET */] != 0)
  565                         return 0;
  566 
  567                 break;
  568         case C0SB:
  569                 if (cf->cf_loc[0 /* PCICCF_CONTROLLER */] !=
  570                     -1 /* PCICCF_CONTROLLER_DEFAULT */ &&
  571                     cf->cf_loc[0 /* PCICCF_CONTROLLER */] != 0)
  572                         return 0;
  573                 if (cf->cf_loc[1 /* PCICCF_SOCKET */] !=
  574                     -1 /* PCICCF_SOCKET_DEFAULT */ &&
  575                     cf->cf_loc[1 /* PCICCF_SOCKET */] != 1)
  576                         return 0;
  577 
  578                 break;
  579         case C1SA:
  580                 if (cf->cf_loc[0 /* PCICCF_CONTROLLER */] !=
  581                     -1 /* PCICCF_CONTROLLER_DEFAULT */ &&
  582                     cf->cf_loc[0 /* PCICCF_CONTROLLER */] != 1)
  583                         return 0;
  584                 if (cf->cf_loc[1 /* PCICCF_SOCKET */] !=
  585                     -1 /* PCICCF_SOCKET_DEFAULT */ &&
  586                     cf->cf_loc[1 /* PCICCF_SOCKET */] != 0)
  587                         return 0;
  588 
  589                 break;
  590         case C1SB:
  591                 if (cf->cf_loc[0 /* PCICCF_CONTROLLER */] !=
  592                     -1 /* PCICCF_CONTROLLER_DEFAULT */ &&
  593                     cf->cf_loc[0 /* PCICCF_CONTROLLER */] != 1)
  594                         return 0;
  595                 if (cf->cf_loc[1 /* PCICCF_SOCKET */] !=
  596                     -1 /* PCICCF_SOCKET_DEFAULT */ &&
  597                     cf->cf_loc[1 /* PCICCF_SOCKET */] != 1)
  598                         return 0;
  599 
  600                 break;
  601         default:
  602                 panic("unknown pcic socket");
  603         }
  604 
  605         return ((*cf->cf_attach->ca_match)(parent, cf, aux));
  606 }
  607 
  608 int
  609 pcic_print(void *arg, const char *pnp)
  610 {
  611         struct pcmciabus_attach_args *paa = arg;
  612         struct pcic_handle *h = (struct pcic_handle *) paa->pch;
  613 
  614         /* Only "pcmcia"s can attach to "pcic"s... easy. */
  615         if (pnp)
  616                 printf("pcmcia at %s", pnp);
  617 
  618         switch (h->sock) {
  619         case C0SA:
  620                 printf(" controller 0 socket 0");
  621                 break;
  622         case C0SB:
  623                 printf(" controller 0 socket 1");
  624                 break;
  625         case C1SA:
  626                 printf(" controller 1 socket 0");
  627                 break;
  628         case C1SB:
  629                 printf(" controller 1 socket 1");
  630                 break;
  631         default:
  632                 panic("unknown pcic socket");
  633         }
  634 
  635         return (UNCONF);
  636 }
  637 
  638 int
  639 pcic_intr(void *arg)
  640 {
  641         struct pcic_softc *sc = arg;
  642         int i, ret = 0;
  643 
  644         DPRINTF(("%s: intr\n", sc->dev.dv_xname));
  645 
  646         for (i = 0; i < PCIC_NSLOTS; i++)
  647                 if (sc->handle[i].flags & PCIC_FLAG_SOCKETP)
  648                         ret += pcic_intr_socket(&sc->handle[i]);
  649 
  650         return (ret ? 1 : 0);
  651 }
  652 
  653 void
  654 pcic_poll_intr(void *arg)
  655 {
  656         struct pcic_softc *sc = arg;
  657         int i, s;
  658 
  659         /*
  660          * Since we're polling, we aren't in interrupt context, so block any
  661          * actual interrupts coming from the pcic.
  662          */
  663         s = spltty();
  664 
  665         for (i = 0; i < PCIC_NSLOTS; i++)
  666                 if (sc->handle[i].flags & PCIC_FLAG_SOCKETP)
  667                         pcic_intr_socket(&sc->handle[i]);
  668 
  669         timeout_add_msec(&sc->poll_timeout, 500);
  670 
  671         splx(s);
  672 }
  673 
  674 int
  675 pcic_intr_socket(struct pcic_handle *h)
  676 {
  677         int cscreg;
  678 
  679         cscreg = pcic_read(h, PCIC_CSC);
  680 
  681         cscreg &= (PCIC_CSC_GPI |
  682                    PCIC_CSC_CD |
  683                    PCIC_CSC_READY |
  684                    PCIC_CSC_BATTWARN |
  685                    PCIC_CSC_BATTDEAD);
  686 
  687         if (cscreg & PCIC_CSC_GPI) {
  688                 DPRINTF(("%s: %02x GPI\n", h->ph_parent->dv_xname, h->sock));
  689         }
  690         if (cscreg & PCIC_CSC_CD) {
  691                 int statreg;
  692 
  693                 statreg = pcic_read(h, PCIC_IF_STATUS);
  694 
  695                 DPRINTF(("%s: %02x CD %x\n", h->ph_parent->dv_xname, h->sock,
  696                     statreg));
  697 
  698                 if ((statreg & PCIC_IF_STATUS_CARDDETECT_MASK) ==
  699                     PCIC_IF_STATUS_CARDDETECT_PRESENT) {
  700                         if (h->laststate != PCIC_LASTSTATE_PRESENT) {
  701                                 DPRINTF(("%s: enqueuing INSERTION event\n",
  702                                     h->ph_parent->dv_xname));
  703                                 pcic_queue_event(h, PCIC_EVENT_INSERTION);
  704                         }
  705                         h->laststate = PCIC_LASTSTATE_PRESENT;
  706                 } else {
  707                         if (h->laststate == PCIC_LASTSTATE_PRESENT) {
  708                                 /* Deactivate the card now. */
  709                                 DPRINTF(("%s: deactivating card\n",
  710                                     h->ph_parent->dv_xname));
  711                                 pcic_deactivate_card(h);
  712 
  713                                 DPRINTF(("%s: enqueuing REMOVAL event\n",
  714                                     h->ph_parent->dv_xname));
  715                                 pcic_queue_event(h, PCIC_EVENT_REMOVAL);
  716                         }
  717                         h->laststate =
  718                             ((statreg & PCIC_IF_STATUS_CARDDETECT_MASK) == 0)
  719                             ? PCIC_LASTSTATE_EMPTY : PCIC_LASTSTATE_HALF;
  720                 }
  721         }
  722         if (cscreg & PCIC_CSC_READY) {
  723                 DPRINTF(("%s: %02x READY\n", h->ph_parent->dv_xname, h->sock));
  724                 /* shouldn't happen */
  725         }
  726         if (cscreg & PCIC_CSC_BATTWARN) {
  727                 DPRINTF(("%s: %02x BATTWARN\n", h->ph_parent->dv_xname,
  728                     h->sock));
  729         }
  730         if (cscreg & PCIC_CSC_BATTDEAD) {
  731                 DPRINTF(("%s: %02x BATTDEAD\n", h->ph_parent->dv_xname,
  732                     h->sock));
  733         }
  734         return (cscreg ? 1 : 0);
  735 }
  736 
  737 void
  738 pcic_queue_event(struct pcic_handle *h, int event)
  739 {
  740         struct pcic_event *pe;
  741         int s;
  742 
  743         pe = malloc(sizeof(*pe), M_TEMP, M_NOWAIT);
  744         if (pe == NULL)
  745                 panic("pcic_queue_event: can't allocate event");
  746 
  747         pe->pe_type = event;
  748         s = splhigh();
  749         SIMPLEQ_INSERT_TAIL(&h->events, pe, pe_q);
  750         splx(s);
  751         wakeup(&h->events);
  752 }
  753 
  754 void
  755 pcic_attach_card(struct pcic_handle *h)
  756 {
  757         if (h->flags & PCIC_FLAG_CARDP)
  758                 panic("pcic_attach_card: already attached");
  759 
  760         /* call the MI attach function */
  761         pcmcia_card_attach(h->pcmcia);
  762 
  763         h->flags |= PCIC_FLAG_CARDP;
  764 }
  765 
  766 void
  767 pcic_detach_card(struct pcic_handle *h, int flags)
  768 {
  769 
  770         if (h->flags & PCIC_FLAG_CARDP) {
  771                 h->flags &= ~PCIC_FLAG_CARDP;
  772 
  773                 /* call the MI detach function */
  774                 pcmcia_card_detach(h->pcmcia, flags);
  775         } else {
  776                 DPRINTF(("pcic_detach_card: already detached"));
  777         }
  778 }
  779 
  780 void
  781 pcic_deactivate_card(struct pcic_handle *h)
  782 {
  783         struct device *dev = (struct device *)h->pcmcia;
  784 
  785         /*
  786          * At suspend, apm deactivates any connected cards. If we've woken up
  787          * to find a previously-connected device missing, and we're detaching
  788          * it, we don't want to deactivate it again.
  789          */
  790         if (dev->dv_flags & DVF_ACTIVE)
  791                 pcmcia_card_deactivate(h->pcmcia);
  792 
  793         /* power down the socket */
  794         pcic_write(h, PCIC_PWRCTL, 0);
  795 
  796         /* reset the socket */
  797         pcic_write(h, PCIC_INTR, 0);
  798 }
  799 
  800 /*
  801  * The pcic_power() function must execute BEFORE the pcmcia_power() hooks.
  802  * During suspend, a card may have been ejected. If so, we must detach it
  803  * completely before pcmcia_power() tries to activate it. Attempting to
  804  * activate a card that isn't there is bad news.
  805  */
  806 void
  807 pcic_power(int why, void *arg)
  808 {
  809         struct pcic_handle *h = (struct pcic_handle *)arg;
  810         struct pcic_softc *sc = (struct pcic_softc *)h->ph_parent;
  811         struct pcic_event *pe;
  812 
  813         if (why != DVACT_RESUME) {
  814                 if (sc->poll_established)
  815                         timeout_del(&sc->poll_timeout);
  816         } else {
  817                 pcic_intr_socket(h);
  818 
  819                 while ((pe = SIMPLEQ_FIRST(&h->events)))
  820                         pcic_event_process(h, pe);
  821 
  822                 if (sc->poll_established)
  823                         timeout_add_msec(&sc->poll_timeout, 500);
  824         }
  825 }
  826 
  827 int 
  828 pcic_chip_mem_alloc(pcmcia_chipset_handle_t pch, bus_size_t size,
  829     struct pcmcia_mem_handle *pcmhp)
  830 {
  831         struct pcic_handle *h = (struct pcic_handle *) pch;
  832         bus_space_handle_t memh;
  833         bus_addr_t addr;
  834         bus_size_t sizepg;
  835         int i, mask, mhandle;
  836         struct pcic_softc *sc = (struct pcic_softc *)(h->ph_parent);
  837 
  838         /* out of sc->memh, allocate as many pages as necessary */
  839 
  840         /* convert size to PCIC pages */
  841         sizepg = (size + (PCIC_MEM_ALIGN - 1)) / PCIC_MEM_ALIGN;
  842         if (sizepg > PCIC_MAX_MEM_PAGES)
  843                 return (1);
  844 
  845         mask = (1 << sizepg) - 1;
  846 
  847         addr = 0;               /* XXX gcc -Wuninitialized */
  848         mhandle = 0;            /* XXX gcc -Wuninitialized */
  849 
  850         for (i = 0; i <= PCIC_MAX_MEM_PAGES - sizepg; i++) {
  851                 if ((sc->subregionmask & (mask << i)) == (mask << i)) {
  852                         if (bus_space_subregion(sc->memt, sc->memh,
  853                             i * PCIC_MEM_PAGESIZE,
  854                             sizepg * PCIC_MEM_PAGESIZE, &memh))
  855                                 return (1);
  856                         mhandle = mask << i;
  857                         addr = sc->membase + (i * PCIC_MEM_PAGESIZE);
  858                         sc->subregionmask &= ~(mhandle);
  859                         pcmhp->memt = sc->memt;
  860                         pcmhp->memh = memh;
  861                         pcmhp->addr = addr;
  862                         pcmhp->size = size;
  863                         pcmhp->mhandle = mhandle;
  864                         pcmhp->realsize = sizepg * PCIC_MEM_PAGESIZE;
  865         
  866                         DPRINTF(("pcic_chip_mem_alloc bus addr 0x%lx+0x%lx\n",
  867                             (u_long) addr, (u_long) size));
  868 
  869                         return (0);
  870                 }
  871         }
  872 
  873         return (1);
  874 }
  875 
  876 void 
  877 pcic_chip_mem_free(pcmcia_chipset_handle_t pch, struct pcmcia_mem_handle *pcmhp)
  878 {
  879         struct pcic_handle *h = (struct pcic_handle *) pch;
  880         struct pcic_softc *sc = (struct pcic_softc *)(h->ph_parent);
  881 
  882         sc->subregionmask |= pcmhp->mhandle;
  883 }
  884 
  885 static struct mem_map_index_st {
  886         int     sysmem_start_lsb;
  887         int     sysmem_start_msb;
  888         int     sysmem_stop_lsb;
  889         int     sysmem_stop_msb;
  890         int     cardmem_lsb;
  891         int     cardmem_msb;
  892         int     memenable;
  893 } mem_map_index[] = {
  894         {
  895                 PCIC_SYSMEM_ADDR0_START_LSB,
  896                 PCIC_SYSMEM_ADDR0_START_MSB,
  897                 PCIC_SYSMEM_ADDR0_STOP_LSB,
  898                 PCIC_SYSMEM_ADDR0_STOP_MSB,
  899                 PCIC_CARDMEM_ADDR0_LSB,
  900                 PCIC_CARDMEM_ADDR0_MSB,
  901                 PCIC_ADDRWIN_ENABLE_MEM0,
  902         },
  903         {
  904                 PCIC_SYSMEM_ADDR1_START_LSB,
  905                 PCIC_SYSMEM_ADDR1_START_MSB,
  906                 PCIC_SYSMEM_ADDR1_STOP_LSB,
  907                 PCIC_SYSMEM_ADDR1_STOP_MSB,
  908                 PCIC_CARDMEM_ADDR1_LSB,
  909                 PCIC_CARDMEM_ADDR1_MSB,
  910                 PCIC_ADDRWIN_ENABLE_MEM1,
  911         },
  912         {
  913                 PCIC_SYSMEM_ADDR2_START_LSB,
  914                 PCIC_SYSMEM_ADDR2_START_MSB,
  915                 PCIC_SYSMEM_ADDR2_STOP_LSB,
  916                 PCIC_SYSMEM_ADDR2_STOP_MSB,
  917                 PCIC_CARDMEM_ADDR2_LSB,
  918                 PCIC_CARDMEM_ADDR2_MSB,
  919                 PCIC_ADDRWIN_ENABLE_MEM2,
  920         },
  921         {
  922                 PCIC_SYSMEM_ADDR3_START_LSB,
  923                 PCIC_SYSMEM_ADDR3_START_MSB,
  924                 PCIC_SYSMEM_ADDR3_STOP_LSB,
  925                 PCIC_SYSMEM_ADDR3_STOP_MSB,
  926                 PCIC_CARDMEM_ADDR3_LSB,
  927                 PCIC_CARDMEM_ADDR3_MSB,
  928                 PCIC_ADDRWIN_ENABLE_MEM3,
  929         },
  930         {
  931                 PCIC_SYSMEM_ADDR4_START_LSB,
  932                 PCIC_SYSMEM_ADDR4_START_MSB,
  933                 PCIC_SYSMEM_ADDR4_STOP_LSB,
  934                 PCIC_SYSMEM_ADDR4_STOP_MSB,
  935                 PCIC_CARDMEM_ADDR4_LSB,
  936                 PCIC_CARDMEM_ADDR4_MSB,
  937                 PCIC_ADDRWIN_ENABLE_MEM4,
  938         },
  939 };
  940 
  941 void 
  942 pcic_chip_do_mem_map(struct pcic_handle *h, int win)
  943 {
  944         int reg;
  945         int kind = h->mem[win].kind & ~PCMCIA_WIDTH_MEM_MASK;
  946         int mem8 =
  947             (h->mem[win].kind & PCMCIA_WIDTH_MEM_MASK) == PCMCIA_WIDTH_MEM8
  948             || (kind == PCMCIA_MEM_ATTR);
  949 
  950         pcic_write(h, mem_map_index[win].sysmem_start_lsb,
  951             (h->mem[win].addr >> PCIC_SYSMEM_ADDRX_SHIFT) & 0xff);
  952         pcic_write(h, mem_map_index[win].sysmem_start_msb,
  953             ((h->mem[win].addr >> (PCIC_SYSMEM_ADDRX_SHIFT + 8)) &
  954             PCIC_SYSMEM_ADDRX_START_MSB_ADDR_MASK) |
  955             (mem8 ? 0 : PCIC_SYSMEM_ADDRX_START_MSB_DATASIZE_16BIT));
  956 
  957         pcic_write(h, mem_map_index[win].sysmem_stop_lsb,
  958             ((h->mem[win].addr + h->mem[win].size) >>
  959             PCIC_SYSMEM_ADDRX_SHIFT) & 0xff);
  960         pcic_write(h, mem_map_index[win].sysmem_stop_msb,
  961             (((h->mem[win].addr + h->mem[win].size) >>
  962             (PCIC_SYSMEM_ADDRX_SHIFT + 8)) &
  963             PCIC_SYSMEM_ADDRX_STOP_MSB_ADDR_MASK) |
  964             PCIC_SYSMEM_ADDRX_STOP_MSB_WAIT2);
  965 
  966         pcic_write(h, mem_map_index[win].cardmem_lsb,
  967             (h->mem[win].offset >> PCIC_CARDMEM_ADDRX_SHIFT) & 0xff);
  968         pcic_write(h, mem_map_index[win].cardmem_msb,
  969             ((h->mem[win].offset >> (PCIC_CARDMEM_ADDRX_SHIFT + 8)) &
  970             PCIC_CARDMEM_ADDRX_MSB_ADDR_MASK) |
  971             ((kind == PCMCIA_MEM_ATTR) ?
  972             PCIC_CARDMEM_ADDRX_MSB_REGACTIVE_ATTR : 0));
  973 
  974         reg = pcic_read(h, PCIC_ADDRWIN_ENABLE);
  975         reg |= (mem_map_index[win].memenable | PCIC_ADDRWIN_ENABLE_MEMCS16);
  976         pcic_write(h, PCIC_ADDRWIN_ENABLE, reg);
  977 
  978 #ifdef PCICDEBUG
  979         {
  980                 int r1, r2, r3, r4, r5, r6;
  981 
  982                 r1 = pcic_read(h, mem_map_index[win].sysmem_start_msb);
  983                 r2 = pcic_read(h, mem_map_index[win].sysmem_start_lsb);
  984                 r3 = pcic_read(h, mem_map_index[win].sysmem_stop_msb);
  985                 r4 = pcic_read(h, mem_map_index[win].sysmem_stop_lsb);
  986                 r5 = pcic_read(h, mem_map_index[win].cardmem_msb);
  987                 r6 = pcic_read(h, mem_map_index[win].cardmem_lsb);
  988 
  989                 DPRINTF(("pcic_chip_do_mem_map window %d: %02x%02x %02x%02x "
  990                     "%02x%02x\n", win, r1, r2, r3, r4, r5, r6));
  991         }
  992 #endif
  993 }
  994 
  995 int 
  996 pcic_chip_mem_map(pcmcia_chipset_handle_t pch, int kind, bus_addr_t card_addr,
  997     bus_size_t size, struct pcmcia_mem_handle *pcmhp, bus_size_t *offsetp,
  998     int *windowp)
  999 {
 1000         struct pcic_handle *h = (struct pcic_handle *) pch;
 1001         bus_addr_t busaddr;
 1002         long card_offset;
 1003         int i, win;
 1004         struct pcic_softc *sc = (struct pcic_softc *)(h->ph_parent);
 1005 
 1006         win = -1;
 1007         for (i = 0; i < (sizeof(mem_map_index) / sizeof(mem_map_index[0]));
 1008             i++) {
 1009                 if ((h->memalloc & (1 << i)) == 0) {
 1010                         win = i;
 1011                         h->memalloc |= (1 << i);
 1012                         break;
 1013                 }
 1014         }
 1015 
 1016         if (win == -1)
 1017                 return (1);
 1018 
 1019         *windowp = win;
 1020 
 1021         /* XXX this is pretty gross */
 1022 
 1023         if (sc->memt != pcmhp->memt)
 1024                 panic("pcic_chip_mem_map memt is bogus");
 1025 
 1026         busaddr = pcmhp->addr;
 1027 
 1028         /*
 1029          * Compute the address offset to the pcmcia address space for the
 1030          * pcic.  This is intentionally signed.  The masks and shifts below
 1031          * will cause TRT to happen in the pcic registers.  Deal with making
 1032          * sure the address is aligned, and return the alignment offset.
 1033          */
 1034 
 1035         *offsetp = card_addr % PCIC_MEM_ALIGN;
 1036         card_addr -= *offsetp;
 1037 
 1038         DPRINTF(("pcic_chip_mem_map window %d bus %lx+%lx+%lx at card addr "
 1039             "%lx\n", win, (u_long) busaddr, (u_long) * offsetp, (u_long) size,
 1040             (u_long) card_addr));
 1041 
 1042         /*
 1043          * include the offset in the size, and decrement size by one, since
 1044          * the hw wants start/stop
 1045          */
 1046         size += *offsetp - 1;
 1047 
 1048         card_offset = (((long) card_addr) - ((long) busaddr));
 1049 
 1050         h->mem[win].addr = busaddr;
 1051         h->mem[win].size = size;
 1052         h->mem[win].offset = card_offset;
 1053         h->mem[win].kind = kind;
 1054 
 1055         pcic_chip_do_mem_map(h, win);
 1056 
 1057         return (0);
 1058 }
 1059 
 1060 void 
 1061 pcic_chip_mem_unmap(pcmcia_chipset_handle_t pch, int window)
 1062 {
 1063         struct pcic_handle *h = (struct pcic_handle *) pch;
 1064         int reg;
 1065 
 1066         if (window >= (sizeof(mem_map_index) / sizeof(mem_map_index[0])))
 1067                 panic("pcic_chip_mem_unmap: window out of range");
 1068 
 1069         reg = pcic_read(h, PCIC_ADDRWIN_ENABLE);
 1070         reg &= ~mem_map_index[window].memenable;
 1071         pcic_write(h, PCIC_ADDRWIN_ENABLE, reg);
 1072 
 1073         h->memalloc &= ~(1 << window);
 1074 }
 1075 
 1076 int 
 1077 pcic_chip_io_alloc(pcmcia_chipset_handle_t pch, bus_addr_t start,
 1078     bus_size_t size, bus_size_t align, struct pcmcia_io_handle *pcihp)
 1079 {
 1080         struct pcic_handle *h = (struct pcic_handle *) pch;
 1081         bus_space_tag_t iot;
 1082         bus_space_handle_t ioh;
 1083         bus_addr_t ioaddr, beg, fin;
 1084         int flags = 0;
 1085         struct pcic_softc *sc = (struct pcic_softc *)(h->ph_parent);
 1086         struct pcic_ranges *range;
 1087 
 1088         /*
 1089          * Allocate some arbitrary I/O space.
 1090          */
 1091 
 1092         iot = sc->iot;
 1093 
 1094         if (start) {
 1095                 ioaddr = start;
 1096                 if (bus_space_map(iot, start, size, 0, &ioh))
 1097                         return (1);
 1098                 DPRINTF(("pcic_chip_io_alloc map port %lx+%lx\n",
 1099                     (u_long)ioaddr, (u_long)size));
 1100         } else if (sc->ranges) {
 1101                 flags |= PCMCIA_IO_ALLOCATED;
 1102 
 1103                 /*
 1104                  * In this case, we know the "size" and "align" that
 1105                  * we want.  So we need to start walking down
 1106                  * sc->ranges, searching for a similar space that
 1107                  * is (1) large enough for the size and alignment
 1108                  * (2) then we need to try to allocate
 1109                  * (3) if it fails to allocate, we try next range.
 1110                  *
 1111                  * We must also check that the start/size of each
 1112                  * allocation we are about to do is within the bounds
 1113                  * of "sc->iobase" and "sc->iosize".
 1114                  * (Some pcmcia controllers handle a 12 bits of addressing,
 1115                  * but we want to use the same range structure)
 1116                  */
 1117                 for (range = sc->ranges; range->start; range++) {
 1118                         /* Potentially trim the range because of bounds. */
 1119                         beg = max(range->start, sc->iobase);
 1120                         fin = min(range->start + range->len,
 1121                             sc->iobase + sc->iosize);
 1122 
 1123                         /* Short-circuit easy cases. */
 1124                         if (fin < beg || fin - beg < size)
 1125                                 continue;
 1126 
 1127                         /*
 1128                          * This call magically fulfills our alignment
 1129                          * requirements.
 1130                          */
 1131                         DPRINTF(("pcic_chip_io_alloc beg-fin %lx-%lx\n",
 1132                             (u_long)beg, (u_long)fin));
 1133                         if (bus_space_alloc(iot, beg, fin, size, align, 0, 0,
 1134                             &ioaddr, &ioh) == 0)
 1135                                 break;
 1136                 }
 1137                 if (range->start == 0)
 1138                         return (1);
 1139                 DPRINTF(("pcic_chip_io_alloc alloc port %lx+%lx\n",
 1140                     (u_long)ioaddr, (u_long)size));
 1141 
 1142         } else {
 1143                 flags |= PCMCIA_IO_ALLOCATED;
 1144                 if (bus_space_alloc(iot, sc->iobase,
 1145                     sc->iobase + sc->iosize, size, align, 0, 0,
 1146                     &ioaddr, &ioh))
 1147                         return (1);
 1148                 DPRINTF(("pcic_chip_io_alloc alloc port %lx+%lx\n",
 1149                     (u_long)ioaddr, (u_long)size));
 1150         }
 1151 
 1152         pcihp->iot = iot;
 1153         pcihp->ioh = ioh;
 1154         pcihp->addr = ioaddr;
 1155         pcihp->size = size;
 1156         pcihp->flags = flags;
 1157 
 1158         return (0);
 1159 }
 1160 
 1161 void 
 1162 pcic_chip_io_free(pcmcia_chipset_handle_t pch, struct pcmcia_io_handle *pcihp)
 1163 {
 1164         bus_space_tag_t iot = pcihp->iot;
 1165         bus_space_handle_t ioh = pcihp->ioh;
 1166         bus_size_t size = pcihp->size;
 1167 
 1168         if (pcihp->flags & PCMCIA_IO_ALLOCATED)
 1169                 bus_space_free(iot, ioh, size);
 1170         else
 1171                 bus_space_unmap(iot, ioh, size);
 1172 }
 1173 
 1174 
 1175 static struct io_map_index_st {
 1176         int     start_lsb;
 1177         int     start_msb;
 1178         int     stop_lsb;
 1179         int     stop_msb;
 1180         int     ioenable;
 1181         int     ioctlmask;
 1182         int     ioctlbits[3];           /* indexed by PCMCIA_WIDTH_* */
 1183 }               io_map_index[] = {
 1184         {
 1185                 PCIC_IOADDR0_START_LSB,
 1186                 PCIC_IOADDR0_START_MSB,
 1187                 PCIC_IOADDR0_STOP_LSB,
 1188                 PCIC_IOADDR0_STOP_MSB,
 1189                 PCIC_ADDRWIN_ENABLE_IO0,
 1190                 PCIC_IOCTL_IO0_WAITSTATE | PCIC_IOCTL_IO0_ZEROWAIT |
 1191                 PCIC_IOCTL_IO0_IOCS16SRC_MASK | PCIC_IOCTL_IO0_DATASIZE_MASK,
 1192                 {
 1193                         PCIC_IOCTL_IO0_IOCS16SRC_CARD,
 1194                         PCIC_IOCTL_IO0_IOCS16SRC_DATASIZE |
 1195                             PCIC_IOCTL_IO0_DATASIZE_8BIT,
 1196                         PCIC_IOCTL_IO0_IOCS16SRC_DATASIZE |
 1197                             PCIC_IOCTL_IO0_DATASIZE_16BIT,
 1198                 },
 1199         },
 1200         {
 1201                 PCIC_IOADDR1_START_LSB,
 1202                 PCIC_IOADDR1_START_MSB,
 1203                 PCIC_IOADDR1_STOP_LSB,
 1204                 PCIC_IOADDR1_STOP_MSB,
 1205                 PCIC_ADDRWIN_ENABLE_IO1,
 1206                 PCIC_IOCTL_IO1_WAITSTATE | PCIC_IOCTL_IO1_ZEROWAIT |
 1207                 PCIC_IOCTL_IO1_IOCS16SRC_MASK | PCIC_IOCTL_IO1_DATASIZE_MASK,
 1208                 {
 1209                         PCIC_IOCTL_IO1_IOCS16SRC_CARD,
 1210                         PCIC_IOCTL_IO1_IOCS16SRC_DATASIZE |
 1211                             PCIC_IOCTL_IO1_DATASIZE_8BIT,
 1212                         PCIC_IOCTL_IO1_IOCS16SRC_DATASIZE |
 1213                             PCIC_IOCTL_IO1_DATASIZE_16BIT,
 1214                 },
 1215         },
 1216 };
 1217 
 1218 void 
 1219 pcic_chip_do_io_map(struct pcic_handle *h, int win)
 1220 {
 1221         int reg;
 1222 
 1223         DPRINTF(("pcic_chip_do_io_map win %d addr %lx size %lx width %d\n",
 1224             win, (long) h->io[win].addr, (long) h->io[win].size,
 1225             h->io[win].width * 8));
 1226 
 1227         pcic_write(h, io_map_index[win].start_lsb, h->io[win].addr & 0xff);
 1228         pcic_write(h, io_map_index[win].start_msb,
 1229             (h->io[win].addr >> 8) & 0xff);
 1230 
 1231         pcic_write(h, io_map_index[win].stop_lsb,
 1232             (h->io[win].addr + h->io[win].size - 1) & 0xff);
 1233         pcic_write(h, io_map_index[win].stop_msb,
 1234             ((h->io[win].addr + h->io[win].size - 1) >> 8) & 0xff);
 1235 
 1236         reg = pcic_read(h, PCIC_IOCTL);
 1237         reg &= ~io_map_index[win].ioctlmask;
 1238         reg |= io_map_index[win].ioctlbits[h->io[win].width];
 1239         pcic_write(h, PCIC_IOCTL, reg);
 1240 
 1241         reg = pcic_read(h, PCIC_ADDRWIN_ENABLE);
 1242         reg |= io_map_index[win].ioenable;
 1243         pcic_write(h, PCIC_ADDRWIN_ENABLE, reg);
 1244 }
 1245 
 1246 int 
 1247 pcic_chip_io_map(pcmcia_chipset_handle_t pch, int width, bus_addr_t offset,
 1248     bus_size_t size, struct pcmcia_io_handle *pcihp, int *windowp)
 1249 {
 1250         struct pcic_handle *h = (struct pcic_handle *) pch;
 1251         bus_addr_t ioaddr = pcihp->addr + offset;
 1252         int i, win;
 1253 #ifdef PCICDEBUG
 1254         static char *width_names[] = { "auto", "io8", "io16" };
 1255 #endif
 1256         struct pcic_softc *sc = (struct pcic_softc *)(h->ph_parent);
 1257 
 1258         /* XXX Sanity check offset/size. */
 1259 
 1260         win = -1;
 1261         for (i = 0; i < (sizeof(io_map_index) / sizeof(io_map_index[0])); i++) {
 1262                 if ((h->ioalloc & (1 << i)) == 0) {
 1263                         win = i;
 1264                         h->ioalloc |= (1 << i);
 1265                         break;
 1266                 }
 1267         }
 1268 
 1269         if (win == -1)
 1270                 return (1);
 1271 
 1272         *windowp = win;
 1273 
 1274         /* XXX this is pretty gross */
 1275 
 1276         if (sc->iot != pcihp->iot)
 1277                 panic("pcic_chip_io_map iot is bogus");
 1278 
 1279         DPRINTF(("pcic_chip_io_map window %d %s port %lx+%lx\n",
 1280                  win, width_names[width], (u_long) ioaddr, (u_long) size));
 1281 
 1282         h->io[win].addr = ioaddr;
 1283         h->io[win].size = size;
 1284         h->io[win].width = width;
 1285 
 1286         pcic_chip_do_io_map(h, win);
 1287 
 1288         return (0);
 1289 }
 1290 
 1291 void 
 1292 pcic_chip_io_unmap(pcmcia_chipset_handle_t pch, int window)
 1293 {
 1294         struct pcic_handle *h = (struct pcic_handle *) pch;
 1295         int reg;
 1296 
 1297         if (window >= (sizeof(io_map_index) / sizeof(io_map_index[0])))
 1298                 panic("pcic_chip_io_unmap: window out of range");
 1299 
 1300         reg = pcic_read(h, PCIC_ADDRWIN_ENABLE);
 1301         reg &= ~io_map_index[window].ioenable;
 1302         pcic_write(h, PCIC_ADDRWIN_ENABLE, reg);
 1303 
 1304         h->ioalloc &= ~(1 << window);
 1305 }
 1306 
 1307 void
 1308 pcic_wait_ready(struct pcic_handle *h)
 1309 {
 1310         int i;
 1311 
 1312         for (i = 0; i < 10000; i++) {
 1313                 if (pcic_read(h, PCIC_IF_STATUS) & PCIC_IF_STATUS_READY)
 1314                         return;
 1315                 delay(500);
 1316 #ifdef PCICDEBUG
 1317                         if ((i>5000) && (i%100 == 99))
 1318                                 printf(".");
 1319 #endif
 1320         }
 1321 
 1322 #ifdef DIAGNOSTIC
 1323         printf("pcic_wait_ready: ready never happened, status = %02x\n",
 1324             pcic_read(h, PCIC_IF_STATUS));
 1325 #endif
 1326 }
 1327 
 1328 void
 1329 pcic_chip_socket_enable(pcmcia_chipset_handle_t pch)
 1330 {
 1331         struct pcic_handle *h = (struct pcic_handle *) pch;
 1332         int cardtype, reg, win;
 1333 
 1334         /* this bit is mostly stolen from pcic_attach_card */
 1335 
 1336         /* power down the socket to reset it, clear the card reset pin */
 1337 
 1338         pcic_write(h, PCIC_PWRCTL, 0);
 1339 
 1340         /* 
 1341          * wait 300ms until power fails (Tpf).  Then, wait 100ms since
 1342          * we are changing Vcc (Toff).
 1343          */
 1344         delay((300 + 100) * 1000);
 1345 
 1346         if (h->vendor == PCIC_VENDOR_VADEM_VG469) {
 1347                 reg = pcic_read(h, PCIC_VG469_VSELECT);
 1348                 reg &= ~PCIC_VG469_VSELECT_VCC;
 1349                 pcic_write(h, PCIC_VG469_VSELECT, reg);
 1350         }
 1351 
 1352         /* power up the socket */
 1353 
 1354         pcic_write(h, PCIC_PWRCTL, PCIC_PWRCTL_DISABLE_RESETDRV |
 1355             PCIC_PWRCTL_PWR_ENABLE);
 1356 
 1357         /*
 1358          * wait 100ms until power raise (Tpr) and 20ms to become
 1359          * stable (Tsu(Vcc)).
 1360          *
 1361          * some machines require some more time to be settled
 1362          * (another 200ms is added here).
 1363          */
 1364         delay((100 + 20 + 200) * 1000);
 1365 
 1366         pcic_write(h, PCIC_PWRCTL, PCIC_PWRCTL_DISABLE_RESETDRV |
 1367             PCIC_PWRCTL_OE | PCIC_PWRCTL_PWR_ENABLE);
 1368         pcic_write(h, PCIC_INTR, 0);
 1369 
 1370         /*
 1371          * hold RESET at least 10us.
 1372          */
 1373         delay(10);
 1374 
 1375         /* clear the reset flag */
 1376 
 1377         pcic_write(h, PCIC_INTR, PCIC_INTR_RESET);
 1378 
 1379         /* wait 20ms as per pc card standard (r2.01) section 4.3.6 */
 1380 
 1381         delay(20000);
 1382 
 1383         /* wait for the chip to finish initializing */
 1384 
 1385 #ifdef DIAGNOSTIC
 1386         reg = pcic_read(h, PCIC_IF_STATUS);
 1387         if (!(reg & PCIC_IF_STATUS_POWERACTIVE)) {
 1388                 printf("pcic_chip_socket_enable: status %x\n", reg);
 1389         }
 1390 #endif
 1391 
 1392         pcic_wait_ready(h);
 1393 
 1394         /* zero out the address windows */
 1395 
 1396         pcic_write(h, PCIC_ADDRWIN_ENABLE, 0);
 1397 
 1398         /* set the card type */
 1399 
 1400         cardtype = pcmcia_card_gettype(h->pcmcia);
 1401 
 1402         reg = pcic_read(h, PCIC_INTR);
 1403         reg &= ~PCIC_INTR_CARDTYPE_MASK;
 1404         reg |= ((cardtype == PCMCIA_IFTYPE_IO) ?
 1405                 PCIC_INTR_CARDTYPE_IO :
 1406                 PCIC_INTR_CARDTYPE_MEM);
 1407         reg |= h->ih_irq;
 1408         pcic_write(h, PCIC_INTR, reg);
 1409 
 1410         DPRINTF(("%s: pcic_chip_socket_enable %02x cardtype %s %02x\n",
 1411             h->ph_parent->dv_xname, h->sock,
 1412             ((cardtype == PCMCIA_IFTYPE_IO) ? "io" : "mem"), reg));
 1413 
 1414         /* reinstall all the memory and io mappings */
 1415 
 1416         for (win = 0; win < PCIC_MEM_WINS; win++)
 1417                 if (h->memalloc & (1 << win))
 1418                         pcic_chip_do_mem_map(h, win);
 1419 
 1420         for (win = 0; win < PCIC_IO_WINS; win++)
 1421                 if (h->ioalloc & (1 << win))
 1422                         pcic_chip_do_io_map(h, win);
 1423 }
 1424 
 1425 void
 1426 pcic_chip_socket_disable(pcmcia_chipset_handle_t pch)
 1427 {
 1428         struct pcic_handle *h = (struct pcic_handle *) pch;
 1429 
 1430         DPRINTF(("pcic_chip_socket_disable\n"));
 1431 
 1432         /* power down the socket */
 1433 
 1434         pcic_write(h, PCIC_PWRCTL, 0);
 1435 
 1436         /*
 1437          * wait 300ms until power fails (Tpf).
 1438          */
 1439         delay(300 * 1000);
 1440 }
 1441 
 1442 u_int8_t
 1443 st_pcic_read(struct pcic_handle *h, int idx)
 1444 {
 1445         if (idx != -1)
 1446                 bus_space_write_1(h->ph_bus_t, h->ph_bus_h, PCIC_REG_INDEX,
 1447                     h->sock + idx);
 1448         return bus_space_read_1(h->ph_bus_t, h->ph_bus_h, PCIC_REG_DATA);
 1449 }
 1450 
 1451 void
 1452 st_pcic_write(struct pcic_handle *h, int idx, int data)
 1453 {
 1454         if (idx != -1)
 1455                 bus_space_write_1(h->ph_bus_t, h->ph_bus_h, PCIC_REG_INDEX,
 1456                     h->sock + idx);
 1457         if (data != -1)
 1458                 bus_space_write_1(h->ph_bus_t, h->ph_bus_h, PCIC_REG_DATA,
 1459                     data);
 1460 }

Cache object: d86747d4922d6f52cb95a9eeeea0667a


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.