Index: i82365.h =================================================================== RCS file: /home/imp/FreeBSD/CVS/src/sys/pccard/i82365.h,v retrieving revision 1.10 diff -u -r1.10 i82365.h --- i82365.h 2000/03/10 05:43:28 1.10 +++ i82365.h 2001/03/16 21:50:58 @@ -147,6 +147,16 @@ #define PCIC_IO1_EN 0x80 /* I/O Window 1 Enable */ /* + * The CL-PD67[12]x parts define MISC1 to deal with 3.3V cards. + */ +#define PCIC_MISC1_5V_DETECT 0x01 /* PD6710 only */ +#define PCIC_MISC1_VCC_33 0x02 /* Set Vcc is 3.3V, else 5.0V */ +#define PCIC_MISC1_PMINT 0x04 /* Pulse management intr */ +#define PCIC_MISC1_PCINT 0x08 /* Pulse card interrupt */ +#define PCIC_MISC1_SPEAKER 0x10 /* Enable speaker */ +#define PCIC_MISC1_INPACK 0x80 /* INPACK throttles data */ + +/* * For the I/O Control Register (PCIC_IOCTL) * The lower nybble is the flags for I/O window 0 * The upper nybble is the flags for I/O window 1 Index: pcic.c =================================================================== RCS file: /home/imp/FreeBSD/CVS/src/sys/pccard/pcic.c,v retrieving revision 1.103 diff -u -r1.103 pcic.c --- pcic.c 2001/01/09 23:39:32 1.103 +++ pcic.c 2001/03/16 21:50:58 @@ -55,7 +55,6 @@ static timeout_t pcic_reset; static void pcic_resume(struct slot *); static void pcic_disable __P((struct slot *)); -static void pcic_mapirq __P((struct slot *, int)); static timeout_t pcictimeout; static struct callout_handle pcictimeout_ch = CALLOUT_HANDLE_INITIALIZER(&pcictimeout_ch); @@ -299,7 +298,6 @@ cinfo.mapio = pcic_io; cinfo.ioctl = pcic_ioctl; cinfo.power = pcic_power; - cinfo.mapirq = pcic_mapirq; cinfo.reset = pcic_reset; cinfo.disable = pcic_disable; cinfo.resume = pcic_resume; @@ -487,6 +485,14 @@ return(validslots ? 0 : ENXIO); } +static void +do_mgt_irq(struct pcic_slot *sp, int irq) +{ + /* Management IRQ changes */ + setb(sp, PCIC_INT_GEN, PCIC_INTR_ENA); + sp->putb(sp, PCIC_STAT_INT, (irq << 4) | 0xF); +} + static int pcic_attach(device_t dev) { @@ -521,10 +527,15 @@ } rid = 0; r = 0; - if (irq >= 0) { + if (irq > 0) { r = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, irq, - ~0, 1, RF_ACTIVE); + irq, 1, RF_ACTIVE); } + if (r && ((1 << (rman_get_start(r))) & PCIC_INT_MASK_ALLOWED) == 0) { + device_printf(dev, "Hardware does not support irq %d.\n", irq); + bus_release_resource(dev, SYS_RES_IRQ, rid, r); + irq = 0; + } if (r) { error = bus_setup_intr(dev, r, INTR_TYPE_MISC, pcicintr, (void *) GET_UNIT(dev), &ih); @@ -538,19 +549,20 @@ irq = 0; } if (irq == 0) { - pcictimeout_ch = timeout(pcictimeout, (void *) GET_UNIT(dev), hz/2); + pcictimeout_ch = timeout(pcictimeout, (void *) GET_UNIT(dev), + hz/2); device_printf(dev, "Polling mode\n"); } sp = &pcic_slots[GET_UNIT(dev) * PCIC_CARD_SLOTS]; for (i = 0; i < PCIC_CARD_SLOTS; i++, sp++) { - /* Assign IRQ */ - sp->putb(sp, PCIC_STAT_INT, (irq << 4) | 0xF); + if (sp->slt == NULL) + continue; + + do_mgt_irq(sp, irq); /* Check for changes */ setb(sp, PCIC_POWER, PCIC_PCPWRE| PCIC_DISRST); - if (sp->slt == NULL) - continue; stat = sp->getb(sp, PCIC_STATUS); if (bootverbose) printf("stat is %x\n", stat); @@ -612,6 +624,7 @@ case PCIC_RF5C396: case PCIC_VLSI: case PCIC_IBM_KING: + case PCIC_I82365: switch(slt->pwr.vpp) { default: return(EINVAL); @@ -640,9 +653,9 @@ (sp->controller == PCIC_VG469) || (sp->controller == PCIC_VG465) || (sp->controller == PCIC_VG365)) - setb(sp, 0x2f, 0x03) ; + setb(sp, 0x2f, 0x03); else - setb(sp, 0x16, 0x02); + setb(sp, PCIC_MISC1, PCIC_MISC1_VCC_33); break; case 50: if (sp->controller == PCIC_IBM_KING) { @@ -654,9 +667,9 @@ (sp->controller == PCIC_VG469) || (sp->controller == PCIC_VG465) || (sp->controller == PCIC_VG365)) - clrb(sp, 0x2f, 0x03) ; + clrb(sp, 0x2f, 0x03); else - clrb(sp, 0x16, 0x02); + clrb(sp, PCIC_MISC1, PCIC_MISC1_VCC_33); break; } break; @@ -681,7 +694,8 @@ /* * tell the PCIC which irq we want to use. only the following are legal: - * 3, 4, 5, 7, 9, 10, 11, 12, 14, 15 + * 3, 4, 5, 7, 9, 10, 11, 12, 14, 15. We require the callers of this + * routine to do the check for legality. */ static void pcic_mapirq(struct slot *slt, int irq) @@ -690,7 +704,8 @@ if (irq == 0) clrb(sp, PCIC_INT_GEN, 0xF); else - sp->putb(sp, PCIC_INT_GEN, (sp->getb(sp, PCIC_INT_GEN) & 0xF0) | irq); + sp->putb(sp, PCIC_INT_GEN, + (sp->getb(sp, PCIC_INT_GEN) & 0xF0) | irq); } /* @@ -797,7 +812,7 @@ { struct pcic_slot *sp = slt->cdata; - sp->putb(sp, PCIC_STAT_INT, (slt->irq << 4) | 0xF); + do_mgt_irq(sp, slt->irq); if (sp->controller == PCIC_PD672X) { setb(sp, PCIC_MISC1, PCIC_SPKR_EN); setb(sp, PCIC_MISC2, PCIC_LPDM_EN); @@ -897,6 +912,12 @@ { struct pccard_devinfo *devi = device_get_ivars(child); int err; + + if (((1 << rman_get_start(irq)) & PCIC_INT_MASK_ALLOWED) == 0) { + device_printf(dev, "Hardware does not support irq %ld.\n", + rman_get_start(irq)); + return (EINVAL); + } err = bus_generic_setup_intr(dev, child, irq, flags, intr, arg, cookiep); Index: slot.h =================================================================== RCS file: /home/imp/FreeBSD/CVS/src/sys/pccard/slot.h,v retrieving revision 1.26 diff -u -r1.26 slot.h --- slot.h 2001/01/09 04:33:39 1.26 +++ slot.h 2001/03/16 21:50:58 @@ -66,8 +66,6 @@ /* Set power values */ int (*ioctl) __P((struct slot *, int, caddr_t)); /* ioctl to lower level */ - void (*mapirq) __P((struct slot *, int)); - /* Map interrupt number */ void (*resume) __P((struct slot *)); /* suspend/resume support */ int maxmem; /* Number of allowed memory windows */