]> oss.titaniummirror.com Git - cp210x.git/commitdiff
Several fixes.
authorR. Steve McKown <rsmckown@gmail.com>
Mon, 17 May 2010 20:39:52 +0000 (14:39 -0600)
committerR. Steve McKown <rsmckown@gmail.com>
Thu, 20 May 2010 01:21:17 +0000 (19:21 -0600)
* cp210x.h serves kernel module and userspace apps
* IOCTL_ -> CP210x_IOCTL_ to prevent collisions in userspace
* Fix defect in cp210x_usbstr_from_user
* cpmfg working with new changes

src/cp210x.c
src/cp210x.c.karmic
src/cp210x.h
src/examples/cpmfg.c

index b7de40f900f28a2c21e8cd526b7de2d1f805eae3..1ec4b8eaa403d9c581e0474dde5d695933744e62 100644 (file)
@@ -252,19 +252,21 @@ static size_t cp210x_usbstr_from_user(char *kbuf, unsigned long ubuf, size_t kle
 {
        struct cp210x_buffer t;
        char* str;
+       size_t slen;
 
        if (!kbuf || !ubuf || !klen)
                return 0;
        if (copy_from_user(&t, (struct cp210x_buffer __user *)ubuf, sizeof(t)))
                return 0;
-       if (!t.buf || !t.len)
+       if (!t.buf || !t.len || USBSTRLEN(t.len) > klen)
                return 0;
-       if (t.len < klen)
-               klen = t.len;
-       str = kbuf + klen - t.len;
-       if (copy_from_user(kbuf + klen - t.len, (u8 __user *)t.buf, klen))
+       slen = (klen - 2) / 2;
+       if (t.len < slen)
+               slen = t.len;
+       str = kbuf + klen - slen;
+       if (copy_from_user(str, (u8 __user *)t.buf, slen))
                return 0;
-       return make_usb_string(kbuf, klen, str, t.len);
+       return make_usb_string(kbuf, klen, str, slen);
 }
 
 /* cp210x_has_setmfg
@@ -695,7 +697,7 @@ static int cp210x_ioctl(struct usb_serial_port *port, struct file *file,
        }
        break;
 
-       case IOCTL_GPIOGET:
+       case CP210x_IOCTL_GPIOGET:
        if (cp210x_get_partnum(port) == CP210x_PART_CP2103) {
                u8 gpio = 0;
                if (!cp210x_gpioget(port, &gpio) && !copy_to_user(
@@ -705,27 +707,28 @@ static int cp210x_ioctl(struct usb_serial_port *port, struct file *file,
        return -EFAULT;
        break;
 
-       case IOCTL_GPIOSET:
+       case CP210x_IOCTL_GPIOSET:
        if (cp210x_get_partnum(port) == CP210x_PART_CP2103 &&
                        !cp210x_gpioset(port, arg))
                return 0;
        return -EFAULT;
        break;
 
-       case IOCTL_GPIOBIC:
-       case IOCTL_GPIOBIS:
+       case CP210x_IOCTL_GPIOBIC:
+       case CP210x_IOCTL_GPIOBIS:
        if (cp210x_get_partnum(port) == CP210x_PART_CP2103 &&
-                       !cp210x_gpiosetb(port, (cmd==IOCTL_GPIOBIC) ?  0 : arg,
-                       (cmd==IOCTL_GPIOBIC) ? arg : 0))
+                       !cp210x_gpiosetb(port,
+                               (cmd==CP210x_IOCTL_GPIOBIC) ?  0 : arg,
+                               (cmd==CP210x_IOCTL_GPIOBIC) ? arg : 0))
                return 0;
        return -EFAULT;
        break;
 
-       case IOCTL_DEVICERESET:
+       case CP210x_IOCTL_DEVICERESET:
        return cp210x_reset(port);
        break;
 
-       case IOCTL_PORTCONFGET:
+       case CP210x_IOCTL_PORTCONFGET:
        {
                struct cp210x_port_config config;
                if (!cp210x_portconfget(port, &config) && !copy_to_user(
@@ -736,7 +739,7 @@ static int cp210x_ioctl(struct usb_serial_port *port, struct file *file,
        return -EFAULT;
        break;
 
-       case IOCTL_PORTCONFSET:
+       case CP210x_IOCTL_PORTCONFSET:
        {
        struct cp210x_port_config config;
        if (!copy_from_user(&config, (struct cp210x_port_config __user *)arg,
@@ -747,7 +750,7 @@ static int cp210x_ioctl(struct usb_serial_port *port, struct file *file,
        }
        break;
 
-       case IOCTL_SETVID:
+       case CP210x_IOCTL_SETVID:
        {
                unsigned int vid;
                if (!copy_from_user(&vid, (unsigned int __user *)arg,
@@ -758,7 +761,7 @@ static int cp210x_ioctl(struct usb_serial_port *port, struct file *file,
        }
        break;
 
-       case IOCTL_SETPID:
+       case CP210x_IOCTL_SETPID:
        {
                unsigned int pid;
                if (!copy_from_user(&pid, (unsigned int __user *)arg,
@@ -769,7 +772,7 @@ static int cp210x_ioctl(struct usb_serial_port *port, struct file *file,
        }
        break;
 
-       case IOCTL_SETMFG:
+       case CP210x_IOCTL_SETMFG:
        if (cp210x_has_setmfg()) {
                char usbstr[USBSTRLEN(CP210x_MAX_MFG_STRLEN)];
                size_t len = cp210x_usbstr_from_user(usbstr, arg,
@@ -780,7 +783,7 @@ static int cp210x_ioctl(struct usb_serial_port *port, struct file *file,
        return -EFAULT;
        break;
 
-       case IOCTL_SETPRODUCT:
+       case CP210x_IOCTL_SETPRODUCT:
        {
                char usbstr[USBSTRLEN(CP210x_MAX_PRODUCT_STRLEN)];
                size_t len = cp210x_usbstr_from_user(usbstr, arg,
@@ -791,7 +794,7 @@ static int cp210x_ioctl(struct usb_serial_port *port, struct file *file,
        }
        break;
 
-       case IOCTL_SETSERIAL:
+       case CP210x_IOCTL_SETSERIAL:
        {
                char usbstr[USBSTRLEN(CP210x_MAX_SERIAL_STRLEN)];
                size_t len = cp210x_usbstr_from_user(usbstr, arg,
@@ -802,7 +805,7 @@ static int cp210x_ioctl(struct usb_serial_port *port, struct file *file,
        }
        break;
 
-       case IOCTL_SETDEVVER:
+       case CP210x_IOCTL_SETDEVVER:
        {
                unsigned int ver;
                if (!copy_from_user(&ver, (unsigned int __user *)arg,
index 6188b8a47d01f794794ac35cdd8c35f7f4546a48..707665782103b02ad8597c86c77c839a45b32e91 100644 (file)
@@ -273,19 +273,21 @@ static size_t cp210x_usbstr_from_user(char *kbuf, unsigned long ubuf, size_t kle
 {
        struct cp210x_buffer t;
        char* str;
+       size_t slen;
 
        if (!kbuf || !ubuf || !klen)
                return 0;
        if (copy_from_user(&t, (struct cp210x_buffer __user *)ubuf, sizeof(t)))
                return 0;
-       if (!t.buf || !t.len)
+       if (!t.buf || !t.len || USBSTRLEN(t.len) > klen)
                return 0;
-       if (t.len < klen)
-               klen = t.len;
-       str = kbuf + klen - t.len;
-       if (copy_from_user(kbuf + klen - t.len, (u8 __user *)t.buf, klen))
+       slen = (klen - 2) / 2;
+       if (t.len < slen)
+               slen = t.len;
+       str = kbuf + klen - slen;
+       if (copy_from_user(str, (u8 __user *)t.buf, slen))
                return 0;
-       return make_usb_string(kbuf, klen, str, t.len);
+       return make_usb_string(kbuf, klen, str, slen);
 }
 
 /* cp210x_has_setmfg
@@ -762,7 +764,7 @@ static int cp210x_ioctl(struct tty_struct *tty, struct file *file,
        }
        break;
 
-       case IOCTL_GPIOGET:
+       case CP210x_IOCTL_GPIOGET:
        if (cp210x_get_partnum(port) == CP210x_PART_CP2103) {
                u8 gpio = 0;
                if (!cp210x_gpioget(port, &gpio) && !copy_to_user(
@@ -772,27 +774,28 @@ static int cp210x_ioctl(struct tty_struct *tty, struct file *file,
        return -EFAULT;
        break;
 
-       case IOCTL_GPIOSET:
+       case CP210x_IOCTL_GPIOSET:
        if (cp210x_get_partnum(port) == CP210x_PART_CP2103 &&
                        !cp210x_gpioset(port, arg))
                return 0;
        return -EFAULT;
        break;
 
-       case IOCTL_GPIOBIC:
-       case IOCTL_GPIOBIS:
+       case CP210x_IOCTL_GPIOBIC:
+       case CP210x_IOCTL_GPIOBIS:
        if (cp210x_get_partnum(port) == CP210x_PART_CP2103 &&
-                       !cp210x_gpiosetb(port, (cmd==IOCTL_GPIOBIC) ?  0 : arg,
-                       (cmd==IOCTL_GPIOBIC) ? arg : 0))
+                       !cp210x_gpiosetb(port,
+                               (cmd==CP210x_IOCTL_GPIOBIC) ?  0 : arg,
+                               (cmd==CP210x_IOCTL_GPIOBIC) ? arg : 0))
                return 0;
        return -EFAULT;
        break;
 
-       case IOCTL_DEVICERESET:
+       case CP210x_IOCTL_DEVICERESET:
        return cp210x_reset(port);
        break;
 
-       case IOCTL_PORTCONFGET:
+       case CP210x_IOCTL_PORTCONFGET:
        {
                struct cp210x_port_config config;
                if (!cp210x_portconfget(port, &config) && !copy_to_user(
@@ -803,7 +806,7 @@ static int cp210x_ioctl(struct tty_struct *tty, struct file *file,
        return -EFAULT;
        break;
 
-       case IOCTL_PORTCONFSET:
+       case CP210x_IOCTL_PORTCONFSET:
        {
        struct cp210x_port_config config;
        if (!copy_from_user(&config, (struct cp210x_port_config __user *)arg,
@@ -814,7 +817,7 @@ static int cp210x_ioctl(struct tty_struct *tty, struct file *file,
        }
        break;
 
-       case IOCTL_SETVID:
+       case CP210x_IOCTL_SETVID:
        {
                unsigned int vid;
                if (!copy_from_user(&vid, (unsigned int __user *)arg,
@@ -825,7 +828,7 @@ static int cp210x_ioctl(struct tty_struct *tty, struct file *file,
        }
        break;
 
-       case IOCTL_SETPID:
+       case CP210x_IOCTL_SETPID:
        {
                unsigned int pid;
                if (!copy_from_user(&pid, (unsigned int __user *)arg,
@@ -836,7 +839,7 @@ static int cp210x_ioctl(struct tty_struct *tty, struct file *file,
        }
        break;
 
-       case IOCTL_SETMFG:
+       case CP210x_IOCTL_SETMFG:
        if (cp210x_has_setmfg()) {
                char usbstr[USBSTRLEN(CP210x_MAX_MFG_STRLEN)];
                size_t len = cp210x_usbstr_from_user(usbstr, arg,
@@ -847,7 +850,7 @@ static int cp210x_ioctl(struct tty_struct *tty, struct file *file,
        return -EFAULT;
        break;
 
-       case IOCTL_SETPRODUCT:
+       case CP210x_IOCTL_SETPRODUCT:
        {
                char usbstr[USBSTRLEN(CP210x_MAX_PRODUCT_STRLEN)];
                size_t len = cp210x_usbstr_from_user(usbstr, arg,
@@ -858,7 +861,7 @@ static int cp210x_ioctl(struct tty_struct *tty, struct file *file,
        }
        break;
 
-       case IOCTL_SETSERIAL:
+       case CP210x_IOCTL_SETSERIAL:
        {
                char usbstr[USBSTRLEN(CP210x_MAX_SERIAL_STRLEN)];
                size_t len = cp210x_usbstr_from_user(usbstr, arg,
@@ -869,7 +872,7 @@ static int cp210x_ioctl(struct tty_struct *tty, struct file *file,
        }
        break;
 
-       case IOCTL_SETDEVVER:
+       case CP210x_IOCTL_SETDEVVER:
        {
                unsigned int ver;
                if (!copy_from_user(&ver, (unsigned int __user *)arg,
index 2de79d3077d1c1de2fe76e92c7eb4557ebda9fc3..f3c96a801baa7a97e7221a227b549c1359fc4b3a 100644 (file)
 #if !defined(CP210X_H)
 #define CP210X_H
 
+#if defined(__KERNEL__)
+#include <linux/sockios.h>
+#else
+#include <asm/types.h>
+#include <sys/ioctl.h>
+#endif
+
 /* CP2103 GPIO ioctls */
-#define IOCTL_GPIOGET          0x8000  /* Get gpio bits */
-#define IOCTL_GPIOSET          0x8001  /* Set gpio bits */
-#define IOCTL_GPIOBIC          0x8002  /* Clear specific gpio bit(s) */
-#define IOCTL_GPIOBIS          0x8003  /* Set specific gpio bit(s) */
+#define CP210x_IOCTL_GPIOGET           (SIOCDEVPRIVATE + 0)    /* Get gpio bits */
+#define CP210x_IOCTL_GPIOSET           (SIOCDEVPRIVATE + 1)    /* Set gpio bits */
+#define CP210x_IOCTL_GPIOBIC           (SIOCDEVPRIVATE + 2)    /* Clear specific gpio bit(s) */
+#define CP210x_IOCTL_GPIOBIS           (SIOCDEVPRIVATE + 3)    /* Set specific gpio bit(s) */
 
 /* CP210x ioctls principally used during initial device configuration */
-#define IOCTL_DEVICERESET      0x8004  /* Reset the cp210x */
-#define IOCTL_PORTCONFGET      0x8005  /* Get port configuration */
-#define IOCTL_PORTCONFSET      0x8006  /* Set port configuration */
-#define IOCTL_SETVID           0x8007  /* Set vendor id */
-#define IOCTL_SETPID           0x8008  /* Set product id */
-#define IOCTL_SETMFG           0x8009  /* Set manufacturer string */
-#define IOCTL_SETPRODUCT       0x800a  /* Set product string */
-#define IOCTL_SETSERIAL                0x800b  /* Set serial number string */
-#define IOCTL_SETDEVVER                0x800c  /* Set device version id */
+#define CP210x_IOCTL_DEVICERESET       (SIOCDEVPRIVATE + 4)    /* Reset the cp210x */
+#define CP210x_IOCTL_PORTCONFGET       (SIOCDEVPRIVATE + 5)    /* Get port configuration */
+#define CP210x_IOCTL_PORTCONFSET       (SIOCDEVPRIVATE + 6)    /* Set port configuration */
+#define CP210x_IOCTL_SETVID            (SIOCDEVPRIVATE + 7)    /* Set vendor id */
+#define CP210x_IOCTL_SETPID            (SIOCDEVPRIVATE + 8)    /* Set product id */
+#define CP210x_IOCTL_SETMFG            (SIOCDEVPRIVATE + 9)    /* Set manufacturer string */
+#define CP210x_IOCTL_SETPRODUCT        (SIOCDEVPRIVATE + 10)   /* Set product string */
+#define CP210x_IOCTL_SETSERIAL         (SIOCDEVPRIVATE + 11)   /* Set serial number string */
+#define CP210x_IOCTL_SETDEVVER         (SIOCDEVPRIVATE + 12)   /* Set device version id */
 
 /* CP2103 GPIO bit positions */
 #define GPIO_0                 0x01
 #define GPIO_1                 0x02
 #define GPIO_2                 0x04
 #define GPIO_3                 0x08
-#define GPIO_MASK              (GPIO_0|GPIO_1|GPIO_2|GPIO_3)
+#define GPIO_MASK              (GPIO_3|GPIO_2|GPIO_1|GPIO_0)
 
 /* USB descriptor sizes */
 #define        CP210x_MAX_MFG_STRLEN           255
index a8a94d87d5a77f488822f915593aad643be5487f..f4c54014aaff214b11b5e1f9714e46c39ff08ab9 100644 (file)
@@ -5,68 +5,22 @@
  * device.
  */
 
+#include <fcntl.h>
 #include <netinet/in.h>
 #include <stdint.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <fcntl.h>
+#include <unistd.h>
+#include "../cp210x.h"
 
 #define VID    0x10c4
 #define PID    0xea60
 
-/* CP2103 ioctls */
-#define IOCTL_GPIOGET          0x8000  /* Get gpio bits */
-#define IOCTL_GPIOSET          0x8001  /* Set gpio bits */
-#define IOCTL_GPIOBIC          0x8002  /* Clear specific gpio bit(s) */
-#define IOCTL_GPIOBIS          0x8003  /* Set specific gpio bit(s) */
-
-/* CP210x ioctls principally used during initial device configuration */
-#define IOCTL_DEVICERESET      0x8004  /* Reset the cp210x */
-#define IOCTL_PORTCONFGET      0x8005  /* Get port configuration */
-#define IOCTL_PORTCONFSET      0x8006  /* Set port configuration */
-#define IOCTL_SETVID           0x8007  /* Set vendor id */
-#define IOCTL_SETPID           0x8008  /* Set product id */
-#define IOCTL_SETMFG           0x8009  /* Set manufacturer string */
-#define IOCTL_SETPRODUCT       0x800a  /* Set product string */
-#define IOCTL_SETSERIAL                0x800b  /* Set serial number string */
-#define IOCTL_SETDEVVER                0x800c  /* set device version id */
-/* FIXME: where is IOCTL_SETMFG? */
-
-/* CP2103 GPIO */
-#define GPIO_0         0x01
-#define GPIO_1         0x02
-#define GPIO_2         0x04
-#define GPIO_3         0x08
-#define GPIO_MASK      (GPIO_0|GPIO_1|GPIO_2|GPIO_3)
-
-/* Port config definitions */
-typedef struct {
-    uint16_t mode;             /* Push-pull = 1, Open-drain = 0 */
-    uint16_t lowPower;
-    uint16_t latch;            /* Logic high = 1, Logic low = 0 */
-} cp2101_port_state_t;
-
-typedef struct {
-    cp2101_port_state_t reset;
-    cp2101_port_state_t suspend;
-    uint8_t enhancedFxn;
-} cp2101_port_config_t;
-
-#define PORT_CONFIG_LEN        13      /* Because sizeof() will pad to full words */
-
-/* Used to pass variable sized buffers between user and kernel space (ioctls) */
-typedef struct {
-       char* buf;
-       size_t len;
-} cp210x_buffer_t;
-
-void exit(int);
-
 int cpConnect(char* device)
 {
-    int ret, ioval;
     int fd = open(device, O_RDWR);
     if (fd < 0) {
        fprintf(stderr, "cannot open %s\n", device);
@@ -85,7 +39,7 @@ void cpDisconnect(int fd)
 void cpSetStr(int fd, unsigned int ioctlno, char* string, size_t len)
 {
     int ret;
-    cp210x_buffer_t buf = { buf: string, len: len };
+    struct cp210x_buffer buf = { buf: (unsigned char *)string, len: len };
 
     ret = ioctl(fd, ioctlno, &buf);
     if (ret) {
@@ -98,10 +52,10 @@ void cpSetStr(int fd, unsigned int ioctlno, char* string, size_t len)
 void cpSetPortConf(int fd, int nopullups)
 {
     int ret;
-    cp2101_port_config_t config;
+    struct cp210x_port_config config;
 
     /* Read the current port configuration */
-    if ((ret = ioctl(fd, IOCTL_PORTCONFGET, &config))) {
+    if ((ret = ioctl(fd, CP210x_IOCTL_PORTCONFGET, &config))) {
        fprintf(stderr, "portconfget ioctl failed %d\n", ret);
        exit(1);
     }
@@ -122,7 +76,7 @@ void cpSetPortConf(int fd, int nopullups)
     if (nopullups)
        config.enhancedFxn &= ~0x10;
 
-    if ((ret = ioctl(fd, IOCTL_PORTCONFSET, &config))) {
+    if ((ret = ioctl(fd, CP210x_IOCTL_PORTCONFSET, &config))) {
        fprintf(stderr, "portconfset ioctl failed %d\n", ret);
        exit(1);
     }
@@ -133,7 +87,7 @@ void cpReset(int fd)
     int ret;
 
     /* Reset the part */
-    if ((ret = ioctl(fd, IOCTL_DEVICERESET, 0))) {
+    if ((ret = ioctl(fd, CP210x_IOCTL_DEVICERESET, 0))) {
        fprintf(stderr, "device reset ioctl %d\n", ret);
        exit(1);
     }
@@ -175,10 +129,10 @@ int main(int argc, char* argv[])
     strcpy(newsn, argv[nopullups + 4]);
     fd = cpConnect(argv[nopullups + 1]);
     /* SiLabs doesn't allow set of mfg string on cp210x.
-     * cpSetStr(fd, IOCTL_SETMFG, newmfg, strlen(newmfg));
+     * cpSetStr(fd, CP210x_IOCTL_SETMFG, newmfg, strlen(newmfg));
      */
-    cpSetStr(fd, IOCTL_SETPRODUCT, newprod, strlen(newprod));
-    cpSetStr(fd, IOCTL_SETSERIAL, newsn, strlen(newsn));
+    cpSetStr(fd, CP210x_IOCTL_SETPRODUCT, newprod, strlen(newprod));
+    cpSetStr(fd, CP210x_IOCTL_SETSERIAL, newsn, strlen(newsn));
     cpSetPortConf(fd, nopullups);
     cpReset(fd);
     cpDisconnect(fd);