/* atmioctl.c */ /* IOCTL interface to ATM device */ /* Copyright (c) 1996 Robert Geist and James Westall * Clemson University Dept. of Computer Science * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "atmdd.h" /**/ /* Character device open entry point */ extern struct pddtype ape25; int atm_open( struct inode *inode, struct file *fp) { struct pddtype *ape = &ape25; /* atm_getdma(&ape25); */ /* spin_lock_init(&ape->xmitlock); */ return(0); } /**/ /* Character device ioctl entry point */ int atm_ioctl( struct inode *inode, struct file *fp, unsigned int func_code, unsigned long arg) { unsigned int *word; unsigned int *wordxxx; unsigned int id; unsigned int val; int loc; int len; int rc; int i; int offset; struct pddtype *ape = &ape25; unsigned char nvbuf[128]; word = (unsigned int *)arg; rc = verify_area(VERIFY_WRITE, (char *)arg, 24); if (rc) return(rc); rc = 0; /* printk("Ioctl called with code %d \n", func_code); */ switch(func_code) { case AIO_WTCREG: get_user(id, word); get_user(val, word + 1); WT_CNTLREG(ape, id, val); /* printk("AIO_WTCTRL: id = %x - val = %x \n", id, val); */ break; case AIO_RDCREG: get_user(id, word); val = RD_CNTLREG(ape, id); put_user(val, word + 1); /* printk("AIO_RDCTRL: id = %x - val = %x \n", id, val); */ break; case AIO_WTSREG: get_user(id, word); get_user(val, word + 1); atm_wtsreg(ape, id, val); /* printk("AIO_WTSREG: id = %x - val = %x \n", id, val); */ break; case AIO_RDSREG: get_user(id, word); val = atm_rdsreg(ape, id); put_user(val, word + 1); /* printk("AIO_RDSREG: id = %x - val = %x \n", id, val); */ break; case AIO_MAPDMA: /* rc = atm_mapdma(ape, arg); */ break; case AIO_RDVSAP: get_user(id, word); val = atm_rdvsap(ape, id); put_user(val, word + 1); break; case AIO_WTVSAP: get_user(id, word); get_user(val, word + 1); atm_wtvsap(ape, id, val); break; case AIO_RDNVRAM: get_user(loc, word); get_user(len, word + 1); get_user(offset, word + 2); if (offset < 0) return(-1); if ((offset + len) > 128) return(-1); rc = verify_area(VERIFY_WRITE, (char *)loc, len); if (rc) return(rc); for (i = 0; i < len; i++) { nvbuf[i] = atm_rdnvram(ape, offset + i); } copy_from_user((char *)loc, nvbuf, len); break; case AIO_WTNVRAM: get_user(loc, word); get_user(len, word + 1); get_user(offset, word + 2); if (offset < 64) return(-1); if ((offset + len) > 128) return(-1); rc = verify_area(VERIFY_READ, (char *)loc, len); if (rc) return(rc); copy_from_user(nvbuf, (char *)loc, len); for (i = 0; i < len; i++) { atm_wtnvram(ape, offset + i, nvbuf[i]); } break; #ifndef FULL_STACK case AIO_SEND: /* printk("Calling atm_send5 \n"); */ get_user(id, word); rc = atm_send5(ape, id, "HELLO", 5); break; #endif case AIO_CREATELC: get_user(id, word); /* Get VCI */ val = atm_initlc5(ape, 0, id); put_user(val, word + 1); break; case AIO_FREELC: get_user(id, word); /* Get VCI */ val = atm_freelc5(ape, 0, id); put_user(val, word + 1); break; #ifndef FULL_STACK case AIO_SENDDATA: get_user(id, word); get_user(loc, word + 1); get_user(len, word + 2); rc = verify_area(VERIFY_WRITE, (char *)loc, len); if (rc) { printk("Bad code from verify \n"); return(rc); } rc = atm_send5u(ape, id, loc, len); if (rc == -1) printk("Bad code from send \n"); break; case AIO_RECVDATA: get_user(id, word); get_user(loc, word + 1); get_user(len, word + 2); rc = verify_area(VERIFY_WRITE, (char *)loc, len); if (rc) return(rc); /* printk("aio: RECVDATA queue = %d \n", id); */ rc = atm_recv5u(ape, id, loc, &len); return(len); break; #endif #ifdef CAPTURE_PMD case AIO_GETPMD: rc = verify_area(VERIFY_WRITE, (char *)word, sizeof(struct pmdtype)); /* printk("Verify area returned %d \n", rc); */ if (rc) return(rc); copy_to_user(word, ape->pmddata, sizeof(struct pmdtype)); return(sizeof(struct pmdtype)); break; #endif #ifdef CAPTURE_BUF case AIO_GETLOGB: rc = verify_area(VERIFY_WRITE, (char *)word, ape->logbuflen); if (rc) return(rc); copy_to_user(word, ape->logbuf, ape->logbuflen); return(ape->logbuflen); break; case AIO_GETXLOGB: rc = verify_area(VERIFY_WRITE, (char *)word, ape->xlogbuflen); if (rc) return(rc); copy_to_user(word, ape->xlogbuf, ape->xlogbuflen); return(ape->xlogbuflen); break; #endif #ifdef SYNTHETIC_DROPS case AIO_SETQMAX: get_user(ape->tqmax, word); printk("atmioctl::max_limit is %d\n", ape->tqmax); break; case AIO_SETDROPTHRESH: get_user(ape->dropthresh, word); printk("atmioctl::drop_thresh is %d\n", ape->dropthresh); break; #endif case AIO_DUMPRFL: atm_vbq(ape); atm_vtbq(ape); break; } return(rc); } /**/ /* Character device release */ int atm_release( struct inode *inode, struct file *fp) { struct pddtype *ape = &ape25; /* printk("APE25: Close called \n"); */ /* atm_unmapdma(ape); */ return(0); }