2 * Copyright (c) 1995 Andrew McRae. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 * $FreeBSD: src/usr.sbin/pccard/pccardd/cardd.c,v 1.46.2.16 2001/12/10 14:38:19 iwasaki Exp $
27 * $DragonFly: src/usr.sbin/pccard/pccardd/Attic/cardd.c,v 1.3 2004/06/19 20:38:22 joerg Exp $
39 #include <machine/resource.h>
40 #include <sys/ioctl.h>
43 static struct card_config *assign_driver(struct slot *, struct card *);
44 static int assign_io(struct slot *);
45 static int setup_slot(struct slot *);
46 static void card_inserted(struct slot *);
47 static void card_removed(struct slot *);
48 static void pr_cmd(struct cmd *);
49 static void read_ether(struct slot *);
50 static void read_ether_attr2(struct slot *sp);
55 * Dump configuration file data.
58 dump_config_file(void)
61 struct card_config *confp;
63 for (cp = cards; cp; cp = cp->next) {
64 printf("Card manuf %s, vers %s\n", cp->manuf, cp->version);
65 printf("Configuration entries:\n");
66 for (confp = cp->config; confp; confp = confp->next) {
67 printf("\tIndex code = ");
68 switch (confp->index_type) {
76 printf("0x%x", confp->index);
79 printf(", driver name = %s\n", confp->driver->name);
82 printf("Insert commands are:\n");
86 printf("Remove commands are:\n");
94 pr_cmd(struct cmd *cp)
97 printf("\t%s\n", cp->line);
103 * readslots - read all the PCMCIA slots, and build
104 * a list of the slots.
114 for (i = 0; i < MAXSLOT; i++) {
115 sprintf(name, CARD_DEVICE, i);
116 fd = open(name, O_RDWR);
119 sp = xmalloc(sizeof(*sp));
121 sp->name = newstr(name);
124 /* Check to see if the controller memory has been set up. */
126 unsigned long mem = 0;
128 if (ioctl(fd, PIOCRWMEM, &mem))
129 logerr("ioctl (PIOCRWMEM)");
131 logmsg("mem=0x%x\n", mem);
134 mem = alloc_memory(4 * 1024);
136 die("can't allocate memory for "
137 "controller access");
138 if (ioctl(fd, PIOCRWMEM, &mem))
139 logerr("ioctl (PIOCRWMEM)");
150 * slot_change - Card status has changed.
151 * read new state and process.
154 slot_change(struct slot *sp)
156 struct slotstate state;
158 if (ioctl(sp->fd, PIOCGSTATE, &state)) {
159 logerr("ioctl (PIOCGSTATE)");
162 switch (state.state) {
166 /* Debounce potentially incorrectly reported removals */
167 if (state.laststate == filled || state.laststate == suspend)
171 /* KLUDGE: if we were suspended, remove card */
172 if (state.laststate == suspend)
180 sp->state = state.state;
185 * card_removed - card has been removed from slot.
186 * Execute the remove commands, and clear the slot's state.
187 * Execute the device commands, then the driver commands
188 * and then the card commands. This is the reverse
189 * order to the insertion commands
192 card_removed(struct slot *sp)
195 struct allocblk *sio;
198 if (sp->config && sp->config->driver && sp->card)
199 logmsg("%s%d: %s removed.", sp->config->driver->kernel,
200 sp->config->driver->unit, sp->card->logstr);
204 if (sp->config->inuse && sp->config->driver->inuse)
206 sp->config->inuse = 0;
207 sp->config->driver->inuse = 0;
209 if ((cp = sp->card) != 0 && in_use)
210 execute(cp->remove, sp);
214 if (sp->flags & IO_ASSIGNED)
215 for (sio = &sp->io; sio; sio = sio->next)
216 if (sio->addr && sio->size)
217 bit_nset(io_avail, sio->addr, sio->addr + sio->size - 1);
219 if (sp->flags & IRQ_ASSIGNED)
220 if (sp->irq >= 1 && sp->irq <= 15)
221 pool_irq[sp->irq] = 1;
224 /* CIS string comparison */
226 #define REGCOMP_FLAGS (REG_EXTENDED | REG_NOSUB)
227 #define REGEXEC_FLAGS (0)
230 cis_strcmp(char *db, char *cis)
242 if (n > 2 && db[0] == '/' && db[n-1] == '/') {
243 /* matching by regex */
246 /* otherwise, matching by strncmp() */
247 if (n != strlen(cis)) {
251 return strncmp(db, cis, n);
254 strncpy(p + 1, db, n-2);
257 if ((err = regcomp(&rx, p, REGCOMP_FLAGS))) {
258 regerror(err, &rx, buf, sizeof buf);
259 logmsg("Warning: REGEX error for\"%s\" -- %s\n", p, buf);
264 res = regexec(&rx, cis, 0, NULL, REGEXEC_FLAGS);
271 * card_inserted - Card has been inserted;
273 * - match the card type.
274 * - Match the driver and allocate a driver instance.
275 * - Allocate I/O ports, memory and IRQ.
277 * - assign the driver (if failed, then terminate).
278 * - Run the card commands.
279 * - Run the driver commands
280 * - Run the device commands
283 card_inserted(struct slot *sp)
288 usleep(pccard_init_sleep);
289 sp->cis = readcis(sp->fd);
291 logmsg("Error reading CIS on %s\n", sp->name);
297 for (cp = cards; cp; cp = cp->next) {
298 switch (cp->deftype) {
300 if (cis_strcmp(cp->manuf, sp->cis->manuf) == 0 &&
301 cis_strcmp(cp->version, sp->cis->vers) == 0) {
302 if (cp->add_info1 != NULL &&
303 cis_strcmp(cp->add_info1, sp->cis->add_info1) != 0) {
306 if (cp->add_info2 != NULL &&
307 cis_strcmp(cp->add_info2, sp->cis->add_info2) != 0) {
311 logmsg("Card \"%s\"(\"%s\") "
313 "matched \"%s\" (\"%s\") "
315 sp->cis->manuf, sp->cis->vers,
316 sp->cis->add_info1, sp->cis->add_info2,
317 cp->manuf, cp->version,
318 cp->add_info1, cp->add_info2);
323 if (cp->func_id == sp->cis->func_id1) {
324 logmsg("Card \"%s\"(\"%s\") "
326 "has function ID %d\n",
327 sp->cis->manuf, sp->cis->vers,
328 sp->cis->add_info1, sp->cis->add_info2,
334 logmsg("Unknown deftype %d\n", cp->deftype);
335 die("cardd.c:card_inserted()");
344 logmsg("No card in database for \"%s\"(\"%s\")",
345 sp->cis->manuf, sp->cis->vers);
348 if (sp->cis->lan_nid && sp->cis->lan_nid[0] == sizeof(sp->eaddr)) {
349 bcopy(sp->cis->lan_nid + 1, sp->eaddr, sizeof(sp->eaddr));
350 sp->flags |= EADDR_CONFIGED;
352 bzero(sp->eaddr, sizeof(sp->eaddr));
360 read_ether_attr2(sp);
367 if ((sp->config = assign_driver(sp, cp)) == NULL)
369 if ((err = assign_io(sp))) {
374 reason = "specified CIS was not found";
377 reason = "memory block allocation failed";
380 reason = "I/O block allocation failed";
383 reason = "requires more than one memory window";
389 logmsg("Resource allocation failure for \"%s\"(\"%s\") "
390 "[%s] [%s]; Reason %s\n",
391 sp->cis->manuf, sp->cis->vers,
392 sp->cis->add_info1, sp->cis->add_info2, reason);
398 * Once assigned, set up the I/O & mem contexts, set up the
399 * windows, and then attach the driver.
402 execute(cp->insert, sp);
410 * read_ether - read ethernet address from card. Offset is
411 * the offset into the attribute memory of the card.
414 read_ether(struct slot *sp)
416 unsigned char net_addr[12];
417 int flags = MDF_ATTR; /* attribute memory */
419 ioctl(sp->fd, PIOCRWFLAG, &flags);
420 lseek(sp->fd, (off_t)sp->card->ether->value, SEEK_SET);
421 if (read(sp->fd, net_addr, sizeof(net_addr)) != sizeof(net_addr)) {
422 logerr("read err on net addr");
425 sp->eaddr[0] = net_addr[0];
426 sp->eaddr[1] = net_addr[2];
427 sp->eaddr[2] = net_addr[4];
428 sp->eaddr[3] = net_addr[6];
429 sp->eaddr[4] = net_addr[8];
430 sp->eaddr[5] = net_addr[10];
431 logmsg("Ether=%02x:%02x:%02x:%02x:%02x:%02x\n",
432 sp->eaddr[0], sp->eaddr[1], sp->eaddr[2],
433 sp->eaddr[3], sp->eaddr[4], sp->eaddr[5]);
434 sp->flags |= EADDR_CONFIGED;
438 * Megahertz X-Jack Ethernet uses unique way to get/set MAC
439 * address of the card.
442 read_ether_attr2(struct slot *sp)
447 hexaddr = sp->cis->add_info2;
448 for (i = 0; i < 6; i++)
452 if (strlen(hexaddr) != 12)
454 for (i = 0; i < 12; i++)
455 if (!isxdigit(hexaddr[i]))
457 for (i = 0; i < 6; i++) {
460 s[0] = hexaddr[i * 2];
461 s[1] = hexaddr[i * 2 + 1];
463 if (!sscanf(s, "%x", &d)) {
465 for (j = 0; j < 6; j++)
469 sp->eaddr[i] = (u_char)d;
471 sp->flags |= EADDR_CONFIGED;
476 * assign_driver - Assign driver to card.
477 * First, see if an existing driver is already setup.
479 static struct card_config *
480 assign_driver(struct slot *sp, struct card *cp)
483 struct card_config *conf;
484 struct pccard_resource res;
488 for (conf = cp->config; conf; conf = conf->next)
489 if (conf->inuse == 0 && conf->driver->card == cp &&
490 conf->driver->config == conf &&
491 conf->driver->inuse == 0) {
492 if (debug_level > 0) {
493 logmsg("Found existing driver (%s) for %s\n",
494 conf->driver->name, cp->manuf);
496 conf->driver->inuse = 1;
501 * New driver must be allocated. Find the first configuration
504 for (conf = cp->config; conf; conf = conf->next)
505 if (conf->inuse == 0 && conf->driver->inuse/*card*/ == 0)
508 logmsg("No free configuration for card %s", cp->manuf);
512 * Now we have a free driver and a matching configuration.
513 * Before assigning and allocating everything, check to
514 * see if a device class can be allocated to this.
518 /* If none available, then we can't use this card. */
520 logmsg("Driver already being used for %s", cp->manuf);
525 * Allocate a free IRQ if none has been specified. When we're
526 * sharing interrupts (cardbus bridge case), then we'll use what
527 * the kernel tells us to use, reguardless of what the user
528 * configured. Asking the kernel for IRQ 0 is our way of asking
529 * if we should use a shared interrupt.
531 res.type = SYS_RES_IRQ;
533 if (conf->irq == 0) {
537 irqmin = irqmax = conf->irq;
538 conf->irq = 0; /* Make sure we get it. */
542 if (ioctl(sp->fd, PIOCSRESOURCE, &res) < 0)
543 err(1, "ioctl (PIOCSRESOURCE)");
544 if (res.resource_addr != ~0ul) {
545 conf->irq = res.resource_addr;
546 pool_irq[conf->irq] = 0;
548 for (i = irqmin; i <= irqmax; i++) {
550 * Skip irqs not in the pool.
552 if (pool_irq[i] == 0)
555 * -I forces us to use the interrupt, so use it.
563 * Ask the kernel if we have an free irq.
567 if (ioctl(sp->fd, PIOCSRESOURCE, &res) < 0)
568 err(1, "ioctl (PIOCSRESOURCE)");
569 if (res.resource_addr == ~0ul)
572 * res.resource_addr might be the kernel's
573 * better idea than i, so we have to check to
574 * see if that's in use too. If not, mark it
575 * in use and break out of the loop. I'm not
576 * sure this can happen when IRQ 0 above fails,
577 * but the test is cheap enough.
579 if (pool_irq[res.resource_addr] == 0)
581 conf->irq = res.resource_addr;
582 pool_irq[conf->irq] = 0;
586 if (conf->irq == 0) {
587 logmsg("Failed to allocate IRQ for %s\n", cp->manuf);
598 * Auto select config index
600 static struct cis_config *
601 assign_card_index(struct slot *sp, struct cis * cis)
603 struct cis_config *cp;
604 struct cis_ioblk *cio;
605 struct pccard_resource res;
608 res.type = SYS_RES_IOPORT;
609 for (cp = cis->conf; cp; cp = cp->next) {
610 if (!cp->iospace || !cp->io)
612 for (cio = cp->io; cio; cio = cio->next) {
613 res.size = cio->size;
615 res.max = res.min + cio->size - 1;
616 if (ioctl(sp->fd, PIOCSRESOURCE, &res) < 0)
617 err(1, "ioctl (PIOCSRESOURCE)");
618 if (res.resource_addr != cio->addr)
620 for (i = cio->addr; i < cio->addr + cio->size - 1; i++)
621 if (!bit_test(io_avail, i))
624 return cp; /* found */
628 return cis->def_config;
632 * assign_io - Allocate resources to slot matching the
633 * configuration index selected.
636 assign_io(struct slot *sp)
639 struct cis_config *cisconf, *defconf;
642 defconf = cis->def_config;
643 switch (sp->config->index_type) {
644 case DEFAULT_INDEX: /* default */
646 sp->config->index = cisconf->id;
648 case AUTO_INDEX: /* auto */
649 cisconf = assign_card_index(sp, cis);
650 sp->config->index = cisconf->id;
652 default: /* normal, use index value */
653 for (cisconf = cis->conf; cisconf; cisconf = cisconf->next)
654 if (cisconf->id == sp->config->index)
659 logmsg("Config id %d not present in this card",
663 sp->card_config = cisconf;
666 * Found a matching configuration. Now look at the I/O, memory and IRQ
667 * to create the desired parameters. Look at memory first.
670 /* Skip ed cards in PIO mode */
671 if ((strncmp(sp->config->driver->name, "ed", 2) == 0) &&
672 (sp->config->flags & 0x10))
675 if (cisconf->memspace || (defconf && defconf->memspace)) {
676 struct cis_memblk *mp;
680 * Currently we do not handle the presence of multiple windows.
681 * Then again neither does the interface to the kernel!
682 * See setup_slot() and readcis.c:cis_conf()
684 if (cisconf->memwins > 1) {
685 logmsg("Card requires %d memory windows.",
690 if (!cisconf->memspace)
692 sp->mem.size = mp->length;
693 sp->mem.cardaddr = mp->address;
695 /* For now, we allocate our own memory from the pool. */
696 sp->mem.addr = sp->config->driver->mem;
698 * Host memory address is required. Allocate one
701 if (sp->mem.size && sp->mem.addr == 0) {
702 sp->mem.addr = alloc_memory(mp->length);
703 if (sp->mem.addr == 0)
705 sp->config->driver->mem = sp->mem.addr;
707 /* Driver specific set up */
708 if (strncmp(sp->config->driver->name, "ed", 2) == 0) {
709 sp->mem.cardaddr = 0x4000;
710 sp->mem.flags = MDF_ACTIVE | MDF_16BITS;
712 sp->mem.flags = MDF_ACTIVE | MDF_16BITS;
715 if (sp->mem.flags & MDF_ACTIVE)
716 sp->flags |= MEM_ASSIGNED;
717 if (debug_level > 0) {
718 logmsg("Using mem addr 0x%x, size %d, card addr 0x%x, flags 0x%x\n",
719 sp->mem.addr, sp->mem.size, sp->mem.cardaddr,
725 /* Now look at I/O. */
726 bzero(&sp->io, sizeof(sp->io));
727 if (cisconf->iospace || (defconf && defconf->iospace)
728 || sp->card->iosize) {
729 struct cis_config *cp;
730 struct cis_ioblk *cio;
731 struct allocblk *sio;
736 if (!cisconf->iospace)
738 iosize = sp->card->iosize;
743 iosize = cp->io->size;
745 iosize = 1 << cp->io_addr;
749 * If # of I/O lines decoded == 10, then card does its
752 * If an I/O block exists, then use it.
753 * If no address (but a length) is available, allocate
759 if (iosize == 0 && cio)
760 xmax = cisconf->io_blks;
761 for (x = 0; x < xmax; x++) {
766 sio->addr = cio->addr;
767 sio->size = cio->size;
770 * No I/O block, assume the address lines
771 * decode gives the size.
773 sio->size = 1 << cp->io_addr;
775 if (sio->addr == 0) {
776 struct pccard_resource res;
779 res.type = SYS_RES_IOPORT;
780 res.size = sio->size;
782 for (i = 0; i < IOPORTS; i++) {
783 j = bit_fns(io_avail, IOPORTS, i,
784 sio->size, sio->size);
785 if ((j & (sio->size - 1)) != 0)
788 res.max = j + sio->size - 1;
789 if (ioctl(sp->fd, PIOCSRESOURCE, &res) < 0)
790 err(1, "ioctl (PIOCSRESOURCE)");
791 if (res.resource_addr == j)
800 bit_nclear(io_avail, sio->addr,
801 sio->addr + sio->size - 1);
802 sp->flags |= IO_ASSIGNED;
804 /* Set up the size to take into account the decode lines. */
805 sio->cardaddr = cp->io_addr;
806 switch (cp->io_bus) {
810 sio->flags = IODF_WS;
813 sio->flags = IODF_WS | IODF_CS16;
816 sio->flags = IODF_WS | IODF_CS16 | IODF_16BIT;
819 if (debug_level > 0) {
820 logmsg("Using I/O addr 0x%x, size %d\n",
821 sio->addr, sio->size);
823 if (cio && cio->next) {
824 sio->next = xmalloc(sizeof(*sio));
830 sp->irq = sp->config->irq;
831 sp->flags |= IRQ_ASSIGNED;
836 * setup_slot - Allocate the I/O and memory contexts
837 * return true if completed OK.
840 setup_slot(struct slot *sp)
845 struct driver *drvp = sp->config->driver;
846 struct allocblk *sio;
853 memset(&io, 0, sizeof io);
854 memset(&drv, 0, sizeof drv);
855 offs = sp->cis->reg_addr;
857 ioctl(sp->fd, PIOCRWFLAG, &rw_flags);
858 #if RESET_MAY_BE_HARMFUL
859 lseek(sp->fd, offs, SEEK_SET);
861 write(sp->fd, &c, sizeof(c));
862 usleep(sp->card->reset_time * 1000);
863 lseek(sp->fd, offs, SEEK_SET);
865 write(sp->fd, &c, sizeof(c));
866 usleep(sp->card->reset_time * 1000);
868 lseek(sp->fd, offs, SEEK_SET);
869 c = sp->config->index;
871 write(sp->fd, &c, sizeof(c));
872 if (debug_level > 0) {
873 logmsg("Setting config reg at offs 0x%lx to 0x%x, "
874 "Reset time = %d ms\n", (unsigned long)offs, c,
875 sp->card->reset_time);
877 usleep(pccard_init_sleep);
878 usleep(sp->card->reset_time * 1000);
880 /* If other config registers exist, set them up. */
881 if (sp->cis->ccrs & 2) {
884 if (sp->cis->def_config && sp->cis->def_config->misc_valid &&
885 (sp->cis->def_config->misc & 0x8))
887 if (sp->card_config->io_bus == 1)
889 lseek(sp->fd, offs + 2, SEEK_SET);
890 write(sp->fd, &c, sizeof(c));
892 if (sp->flags & MEM_ASSIGNED) {
894 mem.flags = sp->mem.flags;
895 mem.start = (caddr_t) sp->mem.addr;
896 mem.card = sp->mem.cardaddr;
897 mem.size = sp->mem.size;
898 if (ioctl(sp->fd, PIOCSMEM, &mem)) {
899 logerr("ioctl (PIOCSMEM)");
903 if (sp->flags & IO_ASSIGNED) {
904 for (iowin = 0, sio = &(sp->io); iowin <= 1; iowin++) {
907 io.flags = sio->flags;
908 io.start = sio->addr;
912 io.start = sp->io.addr & ~((1 << sp->io.cardaddr) - 1);
913 io.size = 1 << sp->io.cardaddr;
914 if (io.start < 0x100) {
919 if (debug_level > 0) {
920 logmsg("Assigning I/O window %d, start 0x%x, "
921 "size 0x%x flags 0x%x\n", io.window, io.start,
924 io.flags |= IODF_ACTIVE;
925 if (ioctl(sp->fd, PIOCSIO, &io)) {
926 logerr("ioctl (PIOCSIO)");
929 if (ioctl(sp->fd, PIOCGIO, &io))
931 logerr("ioctl (PIOCGIO)");
934 if (io.start != sio->addr){
935 logmsg("I/O base address changed from 0x%x to 0x%x\n",
936 sio->addr, io.start);
937 sio->addr = io.start;
945 strcpy(drv.name, drvp->kernel);
946 drv.unit = drvp->unit;
947 drv.irqmask = 1 << sp->irq;
948 drv.flags = sp->config->flags;
949 if (sp->flags & MEM_ASSIGNED) {
950 drv.mem = sp->mem.addr;
951 drv.memsize = sp->mem.size;
956 if (sp->flags & IO_ASSIGNED)
957 drv.iobase = sp->io.addr;
960 #ifdef DEV_DESC_HAS_SIZE
961 drv.iosize = sp->io.size;
963 if (debug_level > 0) {
964 logmsg("Assign %s%d, io 0x%x-0x%x, mem 0x%lx, %d bytes, "
965 "irq %d, flags %x\n", drv.name, drv.unit, drv.iobase,
966 drv.iobase + sp->io.size - 1, drv.mem, drv.memsize,
970 * If the driver fails to be connected to the device,
971 * then it may mean that the driver did not recognise it.
973 memcpy(drv.misc, sp->eaddr, 6);
974 if (ioctl(sp->fd, PIOCSDRV, &drv)) {
975 logmsg("driver allocation failed for %s(%s): %s",
976 sp->card->manuf, sp->card->version, strerror(errno));
979 drv.name[sizeof(drv.name) - 1] = '\0';
980 if (strncmp(drv.name, drvp->kernel, sizeof(drv.name))) {
981 drvp->kernel = newstr(drv.name);
984 if (*p >= '0' && *p <= '9') {
985 drvp->unit = atoi(p);
990 logmsg("%s%d: %s inserted.", sp->config->driver->kernel,
991 sp->config->driver->unit, sp->card->logstr);