printf("status for slot %d %b\n", link->slot, cp, PCIC_STATUSBITS); *iarg = 0; #define DO_STATUS(cp, val, map)	((cp & val) == val ? map : 0) *iarg |= DO_STATUS(cp, PCIC_CD, PCMCIA_CARD_PRESENT); *iarg |= DO_STATUS(cp, PCIC_BVD, PCMCIA_BATTERY); *iarg |= DO_STATUS(cp, PCIC_MWP, PCMCIA_WRITE_PROT); *iarg |= DO_STATUS(cp, PCIC_READY, PCMCIA_READY); *iarg |= DO_STATUS(cp, PCIC_POW, PCMCIA_POWER); *iarg |= DO_STATUS(cp, PCIC_VPPV, PCMCIA_POWER_PP); return 0;
printf("off\n"); } return 0; } case PCMCIA_OP_GETREGS: { struct pcic_regs *pi = arg; int             i;
pcic_service(link, opcode, arg, flags)	struct pcmcia_link *link;	int             opcode;	void           *arg;	int		flags;{	struct pcic_softc *sc = link->adapter->adapter_softc;	struct slot    *slot;	if (link->slot >= sc->sc_adapter.nslots)		return ENXIO;	slot = &sc->slot[link->slot];	slot->link = link;		/* save it for later :) */	switch (opcode) {	case PCMCIA_OP_STATUS:{			u_char          cp;			int            *iarg = arg;			if (PDEBUG(PCDSERV))				printf("pcic_service(status)\n");			cp = pcic_rd(slot, PCIC_STATUS);			if (PDEBUG(PCDSERV))				printf("status for slot %d %b\n",				       link->slot, cp, PCIC_STATUSBITS);			*iarg = 0;#define DO_STATUS(cp, val, map)	((cp & val) == val ? map : 0)			*iarg |= DO_STATUS(cp, PCIC_CD, PCMCIA_CARD_PRESENT);			*iarg |= DO_STATUS(cp, PCIC_BVD, PCMCIA_BATTERY);			*iarg |= DO_STATUS(cp, PCIC_MWP, PCMCIA_WRITE_PROT);			*iarg |= DO_STATUS(cp, PCIC_READY, PCMCIA_READY);			*iarg |= DO_STATUS(cp, PCIC_POW, PCMCIA_POWER);			*iarg |= DO_STATUS(cp, PCIC_VPPV, PCMCIA_POWER_PP);			return 0;		}	case PCMCIA_OP_WAIT:{			int             iarg = (int) arg;			int             i = iarg * 4;			if (PDEBUG(PCDSERV))				printf("pcic_service(wait)\n");			i = pcic_wait(slot, i);			if (PDEBUG(PCDSERV))				printf("op99 %b %d\n", 				       pcic_rd(slot, PCIC_STATUS),				       PCIC_STATUSBITS, i);			if (i <= 0)				return EIO;			else				return 0;		}	case PCMCIA_OP_RESET:{			int             force = ((int) arg) < 0;			int             iarg = abs((int) arg);			int             i = iarg * 4;			if (PDEBUG(PCDSERV))				printf("pcic_service(reset)\n");			if (flags)				slot->irq |= PCIC_IOCARD;			else				slot->irq &= ~PCIC_IOCARD; /* XXX? */			pcic_wr(slot, PCIC_POWER, slot->pow &= ~PCIC_DISRST);			slot->irq &= ~PCIC_CARDRESET;			pcic_wr(slot, PCIC_INT_GEN, slot->irq);			if (iarg == 0)				return 0;			delay(iarg);			pcic_wr(slot, PCIC_POWER, slot->pow |= PCIC_DISRST);			slot->irq |= PCIC_CARDRESET;			pcic_wr(slot, PCIC_INT_GEN, slot->irq);			delay(iarg);			i = pcic_wait(slot, i);			if (PDEBUG(PCDSERV))				printf("opreset %d %b %d\n", force, 				       pcic_rd(slot, PCIC_STATUS),				       PCIC_STATUSBITS, i);			if (i <= 0)				return EIO;			else				return 0;		}	case PCMCIA_OP_POWER:{			int             iarg = (int) arg;			if (PDEBUG(PCDSERV))				printf("pcic_service(power): ");			if (flags & PCMCIA_POWER_ON) {				int nv = (PCIC_DISRST|PCIC_OUTENA);				pcic_wr(slot, PCIC_INT_GEN,					slot->irq = PCIC_IOCARD);				if(flags & PCMCIA_POWER_3V)					nv |= PCIC_VCC3V;				if(flags & PCMCIA_POWER_5V)					nv |= PCIC_VCC5V;				if(flags & PCMCIA_POWER_AUTO)					nv |= PCIC_APSENA|					      PCIC_VCC5V|PCIC_VCC3V;				slot->pow &= ~(PCIC_APSENA|PCIC_VCC5V|					       PCIC_VCC3V|PCIC_VPP12V|					       PCIC_VPP5V);				slot->pow |= nv;				pcic_wr(slot, PCIC_POWER, slot->pow);#if 0				delay(iarg);				slot->pow |= PCIC_OUTENA;				pcic_wr(slot, PCIC_POWER, slot->pow);#endif				delay(iarg);				if (PDEBUG(PCDSERV))					printf("on\n");			} else {				slot->pow &= ~(PCIC_APSENA|PCIC_VCC5V|					       PCIC_VCC3V);				slot->pow &= ~(PCIC_DISRST|PCIC_OUTENA);				pcic_wr(slot,PCIC_POWER, slot->pow);				if (PDEBUG(PCDSERV))					printf("off\n");			}			return 0;		}	case PCMCIA_OP_GETREGS:{			struct pcic_regs *pi = arg;			int             i;			if (PDEBUG(PCDSERV))				printf("pcic_service(getregs)\n");			pi->chip_vers = sc->chip_inf;			for (i = 0; i < pi->cnt; i++)				pi->reg[i].val =				    pcic_rd(slot, pi->reg[i].addr);			return 0;		}	default:		if (PDEBUG(PCDSERV))			printf("pcic_service(%x)\n", opcode);		return EINVAL;	}}