X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fchar%2Fip2main.c;h=ac97e617a10783f5a6b3b8f01474b56d59fc56fa;hb=9bf4aaab3e101692164d49b7ca357651eb691cb6;hp=043cff46fb74ae6cd7e72a98c399c067e0cf9f84;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/char/ip2main.c b/drivers/char/ip2main.c index 043cff46f..ac97e617a 100644 --- a/drivers/char/ip2main.c +++ b/drivers/char/ip2main.c @@ -99,6 +99,7 @@ #include #include #include +#include #include #include @@ -202,16 +203,16 @@ static void ip2_wait_until_sent(PTTY,int); static void set_params (i2ChanStrPtr, struct termios *); static int set_modem_info(i2ChanStrPtr, unsigned int, unsigned int *); -static int get_serial_info(i2ChanStrPtr, struct serial_struct *); -static int set_serial_info(i2ChanStrPtr, struct serial_struct *); +static int get_serial_info(i2ChanStrPtr, struct serial_struct __user *); +static int set_serial_info(i2ChanStrPtr, struct serial_struct __user *); -static ssize_t ip2_ipl_read(struct file *, char *, size_t, loff_t *); -static ssize_t ip2_ipl_write(struct file *, const char *, size_t, loff_t *); +static ssize_t ip2_ipl_read(struct file *, char __user *, size_t, loff_t *); +static ssize_t ip2_ipl_write(struct file *, const char __user *, size_t, loff_t *); static int ip2_ipl_ioctl(struct inode *, struct file *, UINT, ULONG); static int ip2_ipl_open(struct inode *, struct file *); -static int DumpTraceBuffer(char *, int); -static int DumpFifoBuffer( char *, int); +static int DumpTraceBuffer(char __user *, int); +static int DumpFifoBuffer( char __user *, int); static void ip2_init_board(int); static unsigned short find_eisa_board(int); @@ -301,6 +302,9 @@ static int iindx; static char rirqs[IP2_MAX_BOARDS]; static int Valid_Irqs[] = { 3, 4, 5, 7, 10, 11, 12, 15, 0}; +/* for sysfs class support */ +static struct class_simple *ip2_class; + // Some functions to keep track of what irq's we have static int __init @@ -411,7 +415,9 @@ cleanup_module(void) iiResetDelay( i2BoardPtrTable[i] ); /* free io addresses and Tibet */ release_region( ip2config.addr[i], 8 ); + class_simple_device_remove(MKDEV(IP2_IPL_MAJOR, 4 * i)); devfs_remove("ip2/ipl%d", i); + class_simple_device_remove(MKDEV(IP2_IPL_MAJOR, 4 * i + 1)); devfs_remove("ip2/stat%d", i); } /* Disable and remove interrupt handler. */ @@ -420,6 +426,7 @@ cleanup_module(void) clear_requested_irq( ip2config.irq[i]); } } + class_simple_destroy(ip2_class); devfs_remove("ip2"); if ( ( err = tty_unregister_driver ( ip2_tty_driver ) ) ) { printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", err); @@ -494,7 +501,7 @@ int ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) { int i, j, box; - int err; + int err = 0; int status = 0; static int loaded; i2eBordStrPtr pB = NULL; @@ -683,7 +690,14 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) /* Register the IPL driver. */ if ( ( err = register_chrdev ( IP2_IPL_MAJOR, pcIpl, &ip2_ipl ) ) ) { printk(KERN_ERR "IP2: failed to register IPL device (%d)\n", err ); - } else + } else { + /* create the sysfs class */ + ip2_class = class_simple_create(THIS_MODULE, "ip2"); + if (IS_ERR(ip2_class)) { + err = PTR_ERR(ip2_class); + goto out_chrdev; + } + } /* Register the read_procmem thing */ if (!create_proc_info_entry("ip2mem",0,&proc_root,ip2_read_procmem)) { printk(KERN_ERR "IP2: failed to register read_procmem\n"); @@ -700,13 +714,27 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) } if ( NULL != ( pB = i2BoardPtrTable[i] ) ) { - devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i), + class_simple_device_add(ip2_class, MKDEV(IP2_IPL_MAJOR, + 4 * i), NULL, "ipl%d", i); + err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i), S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR, "ip2/ipl%d", i); + if (err) { + class_simple_device_remove(MKDEV(IP2_IPL_MAJOR, + 4 * i)); + goto out_class; + } - devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i + 1), + class_simple_device_add(ip2_class, MKDEV(IP2_IPL_MAJOR, + 4 * i + 1), NULL, "stat%d", i); + err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i + 1), S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR, "ip2/stat%d", i); + if (err) { + class_simple_device_remove(MKDEV(IP2_IPL_MAJOR, + 4 * i + 1)); + goto out_class; + } for ( box = 0; box < ABS_MAX_BOXES; ++box ) { @@ -759,8 +787,14 @@ retry: } } ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_RETURN, 0 ); - - return 0; + goto out; + +out_class: + class_simple_destroy(ip2_class); +out_chrdev: + unregister_chrdev(IP2_IPL_MAJOR, "ip2"); +out: + return err; } EXPORT_SYMBOL(ip2_loadmain); @@ -1087,7 +1121,7 @@ set_irq( int boardnum, int boardIrq ) /******************************************************************************/ static inline void -service_all_boards() +service_all_boards(void) { int i; i2eBordStrPtr pB; @@ -2048,9 +2082,10 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg ) wait_queue_t wait; i2ChanStrPtr pCh = DevTable[tty->index]; struct async_icount cprev, cnow; /* kernel counter temps */ - struct serial_icounter_struct *p_cuser; /* user space */ + struct serial_icounter_struct __user *p_cuser; int rc = 0; unsigned long flags; + void __user *argp = (void __user *)arg; if ( pCh == NULL ) { return -ENODEV; @@ -2067,7 +2102,7 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg ) ip2trace (CHANN, ITRC_IOCTL, 2, 1, rc ); - rc = get_serial_info(pCh, (struct serial_struct *) arg); + rc = get_serial_info(pCh, argp); if (rc) return rc; break; @@ -2076,7 +2111,7 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg ) ip2trace (CHANN, ITRC_IOCTL, 3, 1, rc ); - rc = set_serial_info(pCh, (struct serial_struct *) arg); + rc = set_serial_info(pCh, argp); if (rc) return rc; break; @@ -2140,7 +2175,7 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg ) ip2trace (CHANN, ITRC_IOCTL, 6, 1, rc ); - rc = put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long *) arg); + rc = put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *)argp); if (rc) return rc; break; @@ -2149,7 +2184,7 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg ) ip2trace (CHANN, ITRC_IOCTL, 7, 1, rc ); - rc = get_user(arg,(unsigned long *) arg); + rc = get_user(arg,(unsigned long __user *) argp); if (rc) return rc; tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) @@ -2228,7 +2263,7 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg ) save_flags(flags);cli(); cnow = pCh->icount; restore_flags(flags); - p_cuser = (struct serial_icounter_struct *) arg; + p_cuser = argp; rc = put_user(cnow.cts, &p_cuser->cts); rc = put_user(cnow.dsr, &p_cuser->dsr); rc = put_user(cnow.rng, &p_cuser->rng); @@ -2277,14 +2312,9 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg ) /* standard Linux serial structure. */ /******************************************************************************/ static int -get_serial_info ( i2ChanStrPtr pCh, struct serial_struct *retinfo ) +get_serial_info ( i2ChanStrPtr pCh, struct serial_struct __user *retinfo ) { struct serial_struct tmp; - int rc; - - if ( !retinfo ) { - return -EFAULT; - } memset ( &tmp, 0, sizeof(tmp) ); tmp.type = pCh->pMyBord->channelBtypes.bid_value[(pCh->port_index & (IP2_PORTS_PER_BOARD-1))/16]; @@ -2301,8 +2331,7 @@ get_serial_info ( i2ChanStrPtr pCh, struct serial_struct *retinfo ) tmp.close_delay = pCh->ClosingDelay; tmp.closing_wait = pCh->ClosingWaitTime; tmp.custom_divisor = pCh->BaudDivisor; - rc = copy_to_user(retinfo,&tmp,sizeof(*retinfo)); - return rc; + return copy_to_user(retinfo,&tmp,sizeof(*retinfo)); } /******************************************************************************/ @@ -2317,18 +2346,13 @@ get_serial_info ( i2ChanStrPtr pCh, struct serial_struct *retinfo ) /* change the IRQ, address or type of the port the ioctl fails. */ /******************************************************************************/ static int -set_serial_info( i2ChanStrPtr pCh, struct serial_struct *new_info ) +set_serial_info( i2ChanStrPtr pCh, struct serial_struct __user *new_info ) { struct serial_struct ns; int old_flags, old_baud_divisor; - if ( !new_info ) { + if (copy_from_user(&ns, new_info, sizeof (ns))) return -EFAULT; - } - - if (copy_from_user(&ns, new_info, sizeof (ns))) { - return -EFAULT; - } /* * We don't allow setserial to change IRQ, board address, type or baud @@ -2693,7 +2717,7 @@ service_it: static ssize_t -ip2_ipl_read(struct file *pFile, char *pData, size_t count, loff_t *off ) +ip2_ipl_read(struct file *pFile, char __user *pData, size_t count, loff_t *off ) { unsigned int minor = iminor(pFile->f_dentry->d_inode); int rc = 0; @@ -2726,7 +2750,7 @@ ip2_ipl_read(struct file *pFile, char *pData, size_t count, loff_t *off ) } static int -DumpFifoBuffer ( char *pData, int count ) +DumpFifoBuffer ( char __user *pData, int count ) { #ifdef DEBUG_FIFO int rc; @@ -2740,13 +2764,13 @@ DumpFifoBuffer ( char *pData, int count ) } static int -DumpTraceBuffer ( char *pData, int count ) +DumpTraceBuffer ( char __user *pData, int count ) { #ifdef IP2DEBUG_TRACE int rc; int dumpcount; int chunk; - int *pIndex = (int*)pData; + int *pIndex = (int __user *)pData; if ( count < (sizeof(int) * 6) ) { return -EIO; @@ -2802,7 +2826,7 @@ DumpTraceBuffer ( char *pData, int count ) /* */ /******************************************************************************/ static ssize_t -ip2_ipl_write(struct file *pFile, const char *pData, size_t count, loff_t *off) +ip2_ipl_write(struct file *pFile, const char __user *pData, size_t count, loff_t *off) { #ifdef IP2DEBUG_IPL printk (KERN_DEBUG "IP2IPL: write %p, %d bytes\n", pData, count ); @@ -2827,7 +2851,8 @@ ip2_ipl_ioctl ( struct inode *pInode, struct file *pFile, UINT cmd, ULONG arg ) { unsigned int iplminor = iminor(pInode); int rc = 0; - ULONG *pIndex = (ULONG*)arg; + void __user *argp = (void __user *)arg; + ULONG __user *pIndex = argp; i2eBordStrPtr pB = i2BoardPtrTable[iplminor / 4]; i2ChanStrPtr pCh; @@ -2852,9 +2877,9 @@ ip2_ipl_ioctl ( struct inode *pInode, struct file *pFile, UINT cmd, ULONG arg ) case 65: /* Board - ip2stat */ if ( pB ) { - rc = copy_to_user((char*)arg, (char*)pB, sizeof(i2eBordStr) ); + rc = copy_to_user(argp, pB, sizeof(i2eBordStr)); rc = put_user(INB(pB->i2eStatus), - (ULONG*)(arg + (ULONG)(&pB->i2eStatus) - (ULONG)pB ) ); + (ULONG __user *)(arg + (ULONG)(&pB->i2eStatus) - (ULONG)pB ) ); } else { rc = -ENODEV; } @@ -2865,7 +2890,7 @@ ip2_ipl_ioctl ( struct inode *pInode, struct file *pFile, UINT cmd, ULONG arg ) pCh = DevTable[cmd]; if ( pCh ) { - rc = copy_to_user((char*)arg, (char*)pCh, sizeof(i2ChanStr) ); + rc = copy_to_user(argp, pCh, sizeof(i2ChanStr)); } else { rc = -ENODEV; }