summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorhvozda <hvozda@cvs.openbsd.org>1996-04-29 13:07:06 +0000
committerhvozda <hvozda@cvs.openbsd.org>1996-04-29 13:07:06 +0000
commit66dbdef25563581a0d393d8d919df22c43de70c7 (patch)
tree4cfdb17adf8be1fdf71a7e416fdc352fc014c3f3 /sbin
parentfc0fd904cb2c0308afe4ec749ac0a2e82b1cf240 (diff)
Pull in John Kohl's most recent (15Apr96) APM and PCMCIA work
(original PCMCIA framework by Stefan Grefen).
Diffstat (limited to 'sbin')
-rw-r--r--sbin/Makefile6
-rw-r--r--sbin/config_slot/Makefile15
-rw-r--r--sbin/config_slot/config_slot.c233
-rw-r--r--sbin/config_slot/read_conf.c288
-rw-r--r--sbin/pcmcia_cntrl/Makefile9
-rw-r--r--sbin/pcmcia_cntrl/pcmcia_cntrl.177
-rw-r--r--sbin/pcmcia_cntrl/pcmcia_cntrl.c165
7 files changed, 791 insertions, 2 deletions
diff --git a/sbin/Makefile b/sbin/Makefile
index 3c87a070c83..1b8b46a7875 100644
--- a/sbin/Makefile
+++ b/sbin/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.5 1996/04/22 20:21:52 hannken Exp $
+# $OpenBSD: Makefile,v 1.6 1996/04/29 13:07:00 hvozda Exp $
# $NetBSD: Makefile,v 1.28 1996/04/05 01:44:24 cgd Exp $
# @(#)Makefile 8.5 (Berkeley) 3/31/94
@@ -27,9 +27,11 @@ SUBDIR+= mount_umap
SUBDIR+= mount_union
.if make(clean) || make(cleandir)
-SUBDIR+= bim edlabel fdisk
+SUBDIR+= bim config_slot edlabel fdisk pcmcia_cntrl
.elif ${MACHINE} == "i386"
+SUBDIR+= config_slot
SUBDIR+= fdisk
+SUBDIR+= pcmcia_cntrl
.elif ${MACHINE} == "pc532"
SUBDIR+= bim
.elif ${MACHINE} == "sun3"
diff --git a/sbin/config_slot/Makefile b/sbin/config_slot/Makefile
new file mode 100644
index 00000000000..74e14e35e1f
--- /dev/null
+++ b/sbin/config_slot/Makefile
@@ -0,0 +1,15 @@
+# $Id: Makefile,v 1.1 1996/04/29 13:07:01 hvozda Exp $
+
+SRCS = config_slot.c pcmcia_conf.c
+VPATH = ${.CURDIR}/../../sys/dev/pcmcia
+#dumpreg.c
+
+CFLAGS+= -g -O2 -Wmissing-prototypes -I${.CURDIR}/../../sys
+PROG=config_slot
+NOMAN=
+
+pcmcia_conf.o: pcmcia_conf.c
+ $(CC) $(CFLAGS) -D_KERNEL -c $<
+
+.include <bsd.prog.mk>
+# DO NOT DELETE THIS LINE -- make depend depends on it.
diff --git a/sbin/config_slot/config_slot.c b/sbin/config_slot/config_slot.c
new file mode 100644
index 00000000000..a24c387eff9
--- /dev/null
+++ b/sbin/config_slot/config_slot.c
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 1993, 1994 Stefan Grefen. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following dipclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Stefan Grefen.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <sys/device.h>
+
+#include <dev/pcmcia/pcmciareg.h>
+#include <dev/pcmcia/pcmciavar.h>
+#include <dev/pcmcia/pcmcia_ioctl.h>
+
+void parse_device(u_char *, int, int);
+void parse_ver1(u_char *, int, int);
+void parse_config(u_char *, int, int);
+void read_extended_speed(u_char *, int *);
+const char *tuple_name(int), *dtype_name(int), *dsize_name(int),
+ *dspeed_name(int);
+void parse_tuples(u_char *buf, int print_tuples);
+int dumpcf(struct pcmcia_conf *pc_cf);
+void usage(void);
+int readiowin(char **argv,struct iowin *io);
+void dcp(char **argv,char *target);
+void parse_cmdline(int argc,char **argv,struct pcmcia_conf *pc_cf);
+
+int iowins=0;
+
+dumpcf(struct pcmcia_conf *pc_cf) {
+ int i;
+ static char *ios[]= {
+ "auto","8bit","16bit","illegal"
+ };
+ printf("Driver name '%s'\n",pc_cf->driver_name);
+ printf("CFG offset %x\n",pc_cf->cfg_off );
+ printf("IRQ type %s\n",pc_cf->irq_level?"Level":pc_cf->irq_pulse?"Pulse":"None");
+ printf("CFG Entry %x %s\n",pc_cf->cfgtype,pc_cf->cfgtype&DOSRESET?"dosreset":"");
+ printf("IRQ num %x\n",pc_cf->irq_num&0xf);
+ printf("Cardtype %s\n",pc_cf->iocard?"IO":"MEM");
+ for (i=0;i<pc_cf->iowin;i++) {
+ printf("iowin %x-%x %s\n",pc_cf->io[i].start,
+ pc_cf->io[i].start+pc_cf->io[i].len-1,
+ ios[(pc_cf->io[i].flags&(PCMCIA_MAP_8|PCMCIA_MAP_16))>>8]);
+ }
+ for (i=0;i<pc_cf->memwin;i++) {
+ printf("memwin (%x)%x-%x %x\n",
+ pc_cf->mem[i].caddr,
+ pc_cf->mem[i].start,
+ pc_cf->mem[i].start+pc_cf->mem[i].len-1,
+ pc_cf->mem[i].flags);
+ }
+}
+
+void
+usage(void) {
+ fprintf(stderr,"usage: config_slot <slotid> [driver name][iocard]\\\n");
+ fprintf(stderr," [irq num][lirq][iowin start len width]\n");
+ fprintf(stderr," [** not yet memwin start offs len width]\n");
+}
+
+
+main(int argc,char **argv) {
+ char namebuf[64];
+ struct pcmcia_status stbuf;
+ struct pcmcia_info inbuf;
+ struct pcmcia_conf pc_cf;
+ char manu[MAX_CIS_NAMELEN];
+ char model[MAX_CIS_NAMELEN];
+ char addinf1[MAX_CIS_NAMELEN];
+ char addinf2[MAX_CIS_NAMELEN];
+ int sockid;
+ int fd,cfg;
+
+ if(argc<2 || !isdigit(argv[1][0])) {
+ usage();
+ exit(1);
+ }
+
+ sockid=atoi(argv[1]);
+
+ bzero(pc_cf,sizeof(pc_cf));
+
+ argc-=2;argv+=2;
+ sprintf(namebuf,"/dev/pcmcia/slot%d",sockid);
+
+ if((fd=open(namebuf,O_RDWR))<0) {
+ printf("errno %d\n",errno);
+ perror("open");
+ exit(1);
+ }
+ if(ioctl(fd,PCMCIAIO_GET_STATUS,&stbuf)<0) {
+ printf("errno %d\n",errno);
+ perror("ioctl PCMCIAIO_GET_STATUS");
+ exit(1);
+ }
+ if(!(stbuf.status&PCMCIA_CARD_PRESENT)) {
+ printf("No card in slot %d\n",stbuf.slot);
+ exit(1);
+ }
+ if(!(stbuf.status&PCMCIA_POWER)) {
+ int pw=PCMCIA_POWER_5V;
+ printf("Card in slot %d no power\n",stbuf.slot);
+ if(ioctl(fd,PCMCIAIO_SET_POWER,&pw)<0) {
+ printf("errno %d\n",errno);
+ perror("ioctl PCMCIAIO_SET_POWER");
+ exit(1);
+ }
+ /*exit(1);/**/
+ }
+ if(ioctl(fd,PCMCIAIO_GET_STATUS,&stbuf)<0) {
+ printf("errno %d\n",errno);
+ perror("ioctl PCMCIAIO_GET_STATUS");
+ exit(1);
+ }
+ printf("Status slot %d %x\n",stbuf.slot,stbuf.status);
+ if(!(stbuf.status&PCMCIA_READY)) {
+ printf("Card in slot %d not ready\n",stbuf.slot);
+ /*exit(1);/**/
+ }
+ if(ioctl(fd,PCMCIAIO_GET_INFO,&inbuf)<0) {
+ printf("errno %d\n",errno);
+ perror("ioctl PCMCIAIO_GET_INFO");
+ exit(1);
+ }
+ /*dbuf(inbuf.cis_data,512);/**/
+ bzero(&pc_cf,sizeof(pc_cf));
+ /*parse_cmdline(argc,argv,&pc_cf);/**/
+ printf("* %x\n",pc_cf.cfgtype);
+ cfg=pc_cf.cfgtype&CFGENTRYMASK;
+ if(pcmcia_get_cf(0, inbuf.cis_data,512,CFGENTRYMASK,&pc_cf)) {
+ fprintf(stderr,"read_conf failed\n");
+ exit(1);
+ }
+ if(pc_cf.cfgtype&CFGENTRYID) {
+ if(pcmcia_get_cf(0, inbuf.cis_data,512,cfg,&pc_cf)) {
+ fprintf(stderr,"read_conf failed\n");
+ exit(1);
+ }
+ }
+ parse_cmdline(argc,argv,&pc_cf);
+ if(iowins && pc_cf.iowin!=iowins) {
+ pc_cf.iowin=iowins;
+ }
+ dumpcf(&pc_cf);
+ if (pcmcia_get_cisver1(0, (u_char *)&inbuf.cis_data, 512,
+ manu, model, addinf1, addinf2) == 0) {
+ printf(" <%s, %s", manu, model);
+ if (addinf1[0])
+ printf(", %s", addinf1);
+ if (addinf2[0])
+ printf(", %s", addinf2);
+ printf(">\n");
+ }
+ printf("PCMCIAIO_CONFIGURE==%x\n",PCMCIAIO_CONFIGURE);
+ if(ioctl(fd,PCMCIAIO_CONFIGURE,&pc_cf)<0) {
+ printf("errno %d\n",errno);
+ perror("ioctl PCMCIAIO_CONFIGURE");
+ exit(1);
+ }
+
+ exit(0);
+
+}
+#define OPT_ARG(opt,arg,func) if(argc>1 && !strcmp(argv[0],opt)) { \
+ arg=func(argv[1]); argv+=2;argc-=2 ;continue;}
+#define OPT(opt,arg) if(!strcmp(argv[0],opt)) { \
+ arg=1; argv++;argc-- ;continue;}
+#define OPTOV_ARG(opt,op,func,arg) if(!strcmp(argv[0],opt)) { \
+ arg op func(argv[1]); argv+=2;argc-=2 ;continue;}
+#define OPTOV(opt,op,val,arg) if(!strcmp(argv[0],opt)) { \
+ arg op val; argv++;argc-- ;continue;}
+#define OPT_ARGN(opt,n,arg,func) if(argc>n && !strcmp(argv[0],opt)) { \
+ func(&argv[1],&(arg)); argv+=n+1;argc-=n+1 ;continue;}
+readiowin(char **argv,struct iowin *io) {
+ io->start=strtol(argv[0],NULL,0);
+ io->len=strtol(argv[1],NULL,0);
+ if(!strcmp(argv[2],"auto")) {
+ io->flags=0;
+ } else if(!strcmp(argv[2],"8bit")) {
+ io->flags=PCMCIA_MAP_8;
+ } else if(!strcmp(argv[2],"16bit")) {
+ io->flags=PCMCIA_MAP_16;
+ }
+}
+
+void
+dcp(char **argv,char *target) {
+ strcpy(target,argv[0]);
+}
+
+void
+parse_cmdline(int argc,char **argv,struct pcmcia_conf *pc_cf) {
+ int memwin=0;
+ while(argc>0) {
+ OPT_ARG("irq", pc_cf->irq_num,atoi);
+ OPT_ARGN("iowin",3,pc_cf->io[iowins++],readiowin);
+ /*OPT_ARGN("-memwin",4,pc_cf->mem,readmem,win);/**/
+ OPT("pirq", pc_cf->irq_pulse);
+ OPT("lirq", pc_cf->irq_level);
+ OPT("iocard", pc_cf->iocard);
+ OPTOV("dosreset", |= ,DOSRESET,pc_cf->cfgtype);
+ OPTOV_ARG("configid",|= CFGENTRYID |,atoi,pc_cf->cfgtype);
+ OPT_ARGN("driver",1, pc_cf->driver_name[0][0],dcp);
+ printf("illegal option '%s'\n",argv[0]);
+ argc--;argv++;
+ }
+}
diff --git a/sbin/config_slot/read_conf.c b/sbin/config_slot/read_conf.c
new file mode 100644
index 00000000000..9e4a60cb569
--- /dev/null
+++ b/sbin/config_slot/read_conf.c
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 1993, 1994 Stefan Grefen. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following dipclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Stefan Grefen.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/* With 'help' of Barry Jaspan's code */
+
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <sys/device.h>
+
+#include <dev/pcmcia/pcmcia.h>
+#include <dev/pcmcia/pcmciabus.h>
+#include <dev/pcmcia/pcmcia_ioctl.h>
+
+read_conf(u_char *buf, int blen,int cfidx,struct pcmcia_conf *pc_cf)
+{
+ u_char code, len,*tbuf,*endp=buf+blen;
+ int done;
+
+ done = 0;
+ while (!done && buf<endp) {
+ code=*buf++;
+ if (code == CIS_NULL) {
+ continue;
+ }
+
+ len=*buf++;
+
+ tbuf=buf;
+ buf+=len;
+ switch (code) {
+ case CIS_END:
+ done = 1;
+ break;
+ case CIS_CFG_INFO:
+ read_cfg_info(tbuf, len, pc_cf);
+ break;
+ case CIS_CFG_ENT:
+ parse_cfent(tbuf, len,cfidx, pc_cf);
+ break;
+ default:
+ break;
+ }
+ }
+ return 0;
+}
+
+read_cfg_info(u_char *tbuf, int len, struct pcmcia_conf *pc_cf)
+{
+ int i, rasz, rmsz;
+
+ i = 0;
+ rasz = (tbuf[i] & TPCC_RASZ) >> TPCC_RASZ_SHIFT;
+ rmsz = (tbuf[i] & TPCC_RMSZ) >> TPCC_RMSZ_SHIFT;
+
+ i+=2;
+ pc_cf->cfg_off = 0;
+ switch (rasz) {
+ case 3:
+ pc_cf->cfg_off |= (tbuf[i+3] << 24);
+ case 2:
+ pc_cf->cfg_off |= (tbuf[i+2] << 16);
+ case 1:
+ pc_cf->cfg_off |= (tbuf[i+1] << 8);
+ case 0:
+ pc_cf->cfg_off |= tbuf[i];
+ }
+ i+=rasz;
+ pc_cf->cfg_regmask = 0;
+ switch (rmsz) {
+ default:
+ case 3:
+ pc_cf->cfg_regmask |= (tbuf[i+3] << 24);
+ case 2:
+ pc_cf->cfg_regmask |= (tbuf[i+2] << 16);
+ case 1:
+ pc_cf->cfg_regmask |= (tbuf[i+1] << 8);
+ case 0:
+ pc_cf->cfg_regmask |= tbuf[i];
+ }
+
+}
+
+parse_cfent(u_char *tbuf, int len,int slotid, struct pcmcia_conf *pc_cf)
+{
+ int i, idx,defp,iop,io_16,ios,ftrs,intface,k;
+ int host_addr_p, addr_size, len_size;
+
+ i = 0;
+ intface = (tbuf[i] & TPCE_INDX_INT);
+ idx = (tbuf[i] & TPCE_INDX_ENTRY);
+ defp = (tbuf[i] & TPCE_INDX_DEF);
+ printf("%x %x\n",idx,slotid);
+ if((idx==slotid) ||(defp && slotid==-1)) {
+ int j;
+ printf("** %x %x\n",idx,slotid);
+ if (intface) {
+ i++;
+ pc_cf->iocard=(tbuf[i] & TPCE_IF_TYPE)==1;
+ }
+
+ i++;
+ ftrs = tbuf[i++];
+ for (j = 0; j < (ftrs & TPCE_FS_PWR); j++) {
+ int pwr_desc = tbuf[i++];
+ /* for each struct, skip all parameter defns */
+ for (k = 0; k < 8; pwr_desc >>= 1, k++) {
+ if (pwr_desc & 0x01) {
+ /* skip bytes until non-ext found */
+ while (tbuf[i++] & 0x80)
+ ;
+ }
+ }
+ }
+
+ if (ftrs & TPCE_FS_TD) {
+ i++;
+ }
+
+ if (ftrs & TPCE_FS_IO) {
+ int io_addrs[16],io_lens[16];
+ int io_16,io_block_len, io_block_size;
+ iop = 1;
+ io_16 = tbuf[i] & TPCE_FS_IO_BUS16;
+ i++;
+ ios--; /*TMPFIX*/;
+ io_block_len = (tbuf[i] & TPCE_FS_IO_LEN) >>
+ TPCE_FS_IO_LEN_SHIFT;
+ io_block_size = (tbuf[i] & TPCE_FS_IO_SIZE) >>
+ TPCE_FS_IO_SIZE_SHIFT;
+ ios = (tbuf[i] & TPCE_FS_IO_NUM) + 1;
+ i++;
+ for (j = 0; j < ios; j++) {
+ io_addrs[j] = io_lens[j] = 0;
+ switch (io_block_size) {
+ case 3:
+ io_addrs[j] |= tbuf[i+3] << 24;
+ io_addrs[j] |= tbuf[i+2] << 16;
+ case 2:
+ io_addrs[j] |= tbuf[i+1] << 8;
+ case 1:
+ io_addrs[j] |= tbuf[i];
+ break;
+ }
+ pc_cf->io[j].start=io_addrs[j];
+ i += io_block_size + (io_block_size == 3 ? 1
+ : 0);
+ switch (io_block_len) {
+ case 3:
+ io_lens[j] |= tbuf[i+3] << 24;
+ io_lens[j] |= tbuf[i+2] << 16;
+ case 2:
+ io_lens[j] |= tbuf[i+1] << 8;
+ case 1:
+ io_lens[j] |= tbuf[i];
+ break;
+ }
+ /* io_lens[j]++; /*TMPFIX*/;
+ pc_cf->io[j].len=io_lens[j];
+ pc_cf->io[j].flags=io_16?PCMCIA_MAP_16:PCMCIA_MAP_8;
+ i += io_block_len + (io_block_len == 3 ? 1
+ : 0);
+
+ }
+ pc_cf->iowin=ios;
+ }
+
+ if (ftrs & TPCE_FS_IRQ) {
+ int irq_mask,irqp,irq;
+ pc_cf->irq_level=!!(tbuf[i] & TPCE_FS_IRQ_LEVEL);
+ pc_cf->irq_pulse=!!(tbuf[i] & TPCE_FS_IRQ_PULSE);
+ pc_cf->irq_share=!!(tbuf[i] & TPCE_FS_IRQ_SHARE);
+ if (tbuf[i] & TPCE_FS_IRQ_MASK) {
+ irq_mask = (tbuf[i+2] << 8) + tbuf[i+1];
+ i += 2;
+ } else {
+ pc_cf->irq_num = tbuf[i] & TPCE_FS_IRQ_IRQN;
+ }
+
+ i++;
+ }
+
+ if (ftrs & TPCE_FS_MEM) {
+ int memp,mems,mem_lens[16],mem_caddrs[16],mem_haddrs[16];
+ memp = 1;
+ switch ((ftrs & TPCE_FS_MEM) >> TPCE_FS_MEM_SHIFT) {
+ case 1:
+ mems = 1;
+ mem_lens[0] = (tbuf[i+1] << 8) + tbuf[i];
+ mem_lens[0] <<= 8;
+ printf("\tmem: len %d\n", mem_lens[0]);
+
+ break;
+ case 2:
+ mems = 1;
+ mem_lens[0] = (tbuf[i+1] << 8) + tbuf[i];
+ mem_caddrs[0] = mem_haddrs[0] =
+ (tbuf[i+3] << 8) + tbuf[i+2];
+
+ mem_lens[0] <<= 8;
+ mem_caddrs[0] <<= 8;
+
+ break;
+ case 3:
+ host_addr_p = tbuf[i] & TPCE_FS_MEM_HOST;
+ addr_size = (tbuf[i] & TPCE_FS_MEM_ADDR) >>
+ TPCE_FS_MEM_ADDR_SHIFT;
+ len_size = (tbuf[i] & TPCE_FS_MEM_LEN) >>
+ TPCE_FS_MEM_LEN_SHIFT;
+ mems = (tbuf[i] & TPCE_FS_MEM_WINS) + 1;
+ i++;
+ for (j = 0; j < mems; j++) {
+ mem_lens[j] = 0;
+ mem_caddrs[j] = 0;
+ mem_haddrs[j] = 0;
+ switch (len_size) {
+ case 3:
+ mem_lens[j] |= (tbuf[i+2] << 16);
+ case 2:
+ mem_lens[j] |= (tbuf[i+1] << 8);
+ case 1:
+ mem_lens[j] |= tbuf[i];
+ }
+ i += len_size;
+ switch (addr_size) {
+ case 3:
+ mem_caddrs[j] |= (tbuf[i+2] << 16);
+ case 2:
+ mem_caddrs[j] |= (tbuf[i+1] << 8);
+ case 1:
+ mem_caddrs[j] |= tbuf[i];
+ }
+ i += addr_size;
+ if (host_addr_p) {
+ switch (addr_size) {
+ case 3:
+ mem_haddrs[j] |=
+ (tbuf[i+2] << 16);
+ case 2:
+ mem_haddrs[j] |=
+ (tbuf[i+1] << 8);
+ case 1:
+ mem_haddrs[j] |=
+ tbuf[i];
+ }
+ i += addr_size;
+ }
+
+ mem_lens[j] <<= 8;
+ mem_caddrs[j] <<= 8;
+ mem_haddrs[j] <<= 8;
+
+ }
+ }
+ }
+ }
+}
+
+
+
+
diff --git a/sbin/pcmcia_cntrl/Makefile b/sbin/pcmcia_cntrl/Makefile
new file mode 100644
index 00000000000..a231297e9ae
--- /dev/null
+++ b/sbin/pcmcia_cntrl/Makefile
@@ -0,0 +1,9 @@
+# $Id: Makefile,v 1.1 1996/04/29 13:07:04 hvozda Exp $
+
+SRCS = pcmcia_cntrl.c
+
+CFLAGS += -g
+PROG=pcmcia_cntrl
+
+.include <bsd.prog.mk>
+# DO NOT DELETE THIS LINE -- make depend depends on it.
diff --git a/sbin/pcmcia_cntrl/pcmcia_cntrl.1 b/sbin/pcmcia_cntrl/pcmcia_cntrl.1
new file mode 100644
index 00000000000..0ad4cadae2d
--- /dev/null
+++ b/sbin/pcmcia_cntrl/pcmcia_cntrl.1
@@ -0,0 +1,77 @@
+.\" Copyright (c) 1994 Stefan Grefen
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the Institute of Electrical and Electronics Engineers, Inc.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)pwd.1 6.5 (Berkeley) 6/27/91
+.\" $Id: pcmcia_cntrl.1,v 1.1 1996/04/29 13:07:04 hvozda Exp $
+.\"
+.Dd May 31, 1994
+.Dt PWD 1
+.Os BSD 4
+.Sh NAME
+.Nm pcmcia_cntrl
+.Nd Change the status of a pcmcia slot
+.Sh SYNOPSIS
+.Nm pcmcia_cntrl
+.Ar slotid
+.Op on | off | unmap | probe
+.Sh DESCRIPTION
+.Nm Pcmcia_cntrl
+controls the operation of a PCMCIA card. It operates on the card in slot
+.Ar slotid .
+\.
+.Pp
+The options are as follows:
+.Bl -tag -width flag
+.It Fl on
+Turns power on
+.It Fl off
+Turns power off
+.It Fl unmap
+Unmaps and unconfigures a active card (not all drivers may support this).
+.It Fl probe
+Probes and attaches the card found in the slot. Works only for devices that
+have kernel support for mapping.
+Use config_slot for other devices.
+.El
+.Pp
+If an error occurs,
+.Nm pcmcia_cntrl
+exits with a value >0.
+.Sh SEE ALSO
+.Xr config_slot 1 ,
+.Xr pcmcia 4
+.Sh BUGS
+To numerous to mention.
+
+
diff --git a/sbin/pcmcia_cntrl/pcmcia_cntrl.c b/sbin/pcmcia_cntrl/pcmcia_cntrl.c
new file mode 100644
index 00000000000..e01e754177b
--- /dev/null
+++ b/sbin/pcmcia_cntrl/pcmcia_cntrl.c
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 1993, 1994 Stefan Grefen. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following dipclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Stefan Grefen.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <sys/device.h>
+
+#include <dev/pcmcia/pcmciavar.h>
+#include <dev/pcmcia/pcmciareg.h>
+#include <dev/pcmcia/pcmcia_ioctl.h>
+
+#define HAS_POWER(a) (!!(a&(PCMCIA_POWER)))
+
+void
+usage(void) {
+ fprintf(stderr,"usage: pcmcia_cntrl [-f fd] <slotid> on|off|unmap|unconf|probe\n");
+}
+
+main(int argc,char **argv) {
+ int fd = -1;
+ char namebuf[64];
+ int sockid;
+ struct pcmcia_status stbuf;
+ struct pcmcia_info inbuf;
+ int onoff=-1;
+ int unmap=-1;
+ int unconf=-1;
+ int probe=-1;
+ int force=-1;
+
+ if (argv[1] && strcmp(argv[1], "-f") == 0 &&
+ argv[2]) {
+ fd = atoi(argv[2]);
+ argv += 2;
+ argc -= 2;
+ }
+
+ if(argc!=3 || !isdigit(argv[1][0])) {
+ usage();
+ exit(1);
+ }
+ sockid=atoi(argv[1]);
+
+
+ if(!strcmp(argv[2],"on")) {
+ onoff=1;
+ } else if(!strcmp(argv[2],"off")) {
+ onoff=0;
+ } else if(!strcmp(argv[2],"unconf")) {
+ unmap=1;
+ unconf=1;
+ } else if(!strcmp(argv[2],"unconfforce")) {
+ unmap=1;
+ unconf=1;
+ force=1;
+ } else if(!strcmp(argv[2],"unmap")) {
+ unmap=1;
+ } else if(!strcmp(argv[2],"probe")) {
+ probe=1;
+ } else {
+ usage();
+ exit(1);
+ }
+
+ sprintf(namebuf,"/dev/pcmcia/slot%d",sockid);
+
+ if (fd == -1 && (fd=open(namebuf,O_RDWR))<0) {
+ perror("open");
+ exit(1);
+ }
+ if(ioctl(fd,PCMCIAIO_GET_STATUS,&stbuf)<0) {
+ perror("ioctl PCMCIAIO_GET_STATUS");
+ exit(1);
+ }
+ if(!(stbuf.status&PCMCIA_CARD_PRESENT) && force < 0) {
+ fprintf(stderr,"No card in slot %d\n",stbuf.slot);
+ exit(1);
+ }
+ if(onoff>=0) {
+ if(stbuf.status&PCMCIA_CARD_IS_MAPPED) {
+ fprintf(stderr,"Card in slot %d is mapped, can't turn it %s\n",stbuf.slot,onoff?"on":"off");
+ exit(1);
+ }
+ if((HAS_POWER(stbuf.status&PCMCIA_POWER))^(!!onoff)) {
+ int pw=onoff?PCMCIASIO_POWER_5V:PCMCIASIO_POWER_OFF;
+ printf("Card in slot %d power %s\n",stbuf.slot,onoff?"on":"off" );
+ if(ioctl(fd,PCMCIAIO_SET_POWER,&pw)<0) {
+ printf("errno %d\n",errno);
+ perror("ioctl PCMCIAIO_SET_POWER");
+ exit(1);
+ }
+ /*exit(1);/**/
+ }
+ }
+ if (unconf >= 0) {
+ int o;
+ if(!(stbuf.status&PCMCIA_CARD_IS_MAPPED)) {
+ fprintf(stderr,"Card in slot %d is not mapped\n",stbuf.slot);
+ exit(1);
+ }
+ if(ioctl(fd,PCMCIAIO_UNCONFIGURE,0)<0) {
+ perror("ioctl PCMCIAIO_UNCONFIGURE");
+ exit(1);
+ }
+ }
+ if (unmap >= 0) {
+ if (!unconf && (stbuf.status&PCMCIA_CARD_INUSE)) {
+ fprintf(stderr, "Card in slot %d is configured--unconfigure before unmapping.\n", stbuf.slot);
+ exit(1);
+ }
+ if(!(stbuf.status&PCMCIA_CARD_IS_MAPPED)) {
+ fprintf(stderr,"Card in slot %d is not mapped\n",stbuf.slot);
+ exit(1);
+ }
+ if(ioctl(fd,PCMCIAIO_UNMAP,0)<0) {
+ perror("ioctl PCMCIAIO_UNMAP");
+ exit(1);
+ }
+ }
+ if(probe>=0) {
+ struct pcmcia_conf pc_cf;
+ if(stbuf.status&PCMCIA_CARD_IS_MAPPED) {
+ fprintf(stderr,"Card in slot %d is mapped, can't probe it\n",
+ stbuf.slot);
+ exit(1);
+ }
+ bzero(pc_cf,sizeof(pc_cf));
+ if(ioctl(fd,PCMCIAIO_CONFIGURE,&pc_cf)<0) {
+ perror("ioctl PCMCIAIO_CONFIGURE");
+ exit(1);
+ }
+ }
+ exit(0);
+}
+