This is the second submission which has changes suggested by Alan.

>From 4671b1de8a93a60f116328b2ee433bffdbf8075e Mon Sep 17 00:00:00 2001
From: Ken Mills <[email protected]>
Date: Wed, 20 Oct 2010 16:16:15 -0700
Subject: [PATCH] New ioctl to adjust SPI message length

This allows an application to change the default SPI message length from 2048 
bytes
to 2060 bytes. 2060 bytes is the message size used for modem firmware download.

Signed-off-by: Ken Mills <[email protected]>
---
 drivers/serial/ifx6x60.c          |   66 +++++++++++++++++++++++++-----------
 drivers/serial/ifx6x60.h          |    5 ++-
 include/linux/spi/ifx6x60_ioctl.h |   13 +++++++
 3 files changed, 62 insertions(+), 22 deletions(-)

diff --git a/drivers/serial/ifx6x60.c b/drivers/serial/ifx6x60.c
index d5bef6e..5353368 100644
--- a/drivers/serial/ifx6x60.c
+++ b/drivers/serial/ifx6x60.c
@@ -492,12 +492,14 @@ static int ifx_spi_decode_spi_header(unsigned char 
*buffer, int *length,
  *
  *     FIXME: endianness?
  */
-static void ifx_spi_setup_spi_header(unsigned char *txbuffer, int tx_count,
-                                       unsigned char more)
+static void ifx_spi_setup_spi_header(struct ifx_spi_device *ifx_dev,
+               int tx_count)
 {
-       *(u16 *)(txbuffer) = tx_count;
-       *(u16 *)(txbuffer+2) = IFX_SPI_PAYLOAD_SIZE;
-       txbuffer[1] |= (more << IFX_SPI_MORE_BIT) & IFX_SPI_MORE_MASK;
+       *(u16 *)(ifx_dev->tx_buffer) = tx_count;
+       *(u16 *)(ifx_dev->tx_buffer+2) = ifx_dev->ifx_transfer_size -
+               IFX_SPI_HEADER_OVERHEAD;
+       ifx_dev->tx_buffer[1] |= (ifx_dev->spi_more << IFX_SPI_MORE_BIT) &
+               IFX_SPI_MORE_MASK;
 }
 
 /**
@@ -541,7 +543,7 @@ static int ifx_spi_prepare_tx_buffer(struct ifx_spi_device 
*ifx_dev)
 
        dev_dbg(&ifx_dev->spi_dev->dev, "prepare_tx_buffer called");
        tx_buffer = ifx_dev->tx_buffer;
-       memset(tx_buffer, 0, IFX_SPI_TRANSFER_SIZE);
+       memset(tx_buffer, 0, IFX_SPI_MAX_BUFFER_SIZE);
 
        /* make room for required SPI header */
        tx_buffer += IFX_SPI_HEADER_OVERHEAD;
@@ -557,7 +559,9 @@ static int ifx_spi_prepare_tx_buffer(struct ifx_spi_device 
*ifx_dev)
                queue_length = kfifo_len(&port_data->tx_fifo);
                if (queue_length != 0) {
                        /* data to mux -- see if there's room for it */
-                       temp_count = min(queue_length, IFX_SPI_PAYLOAD_SIZE);
+                       temp_count = min(queue_length,
+                               ifx_dev->ifx_transfer_size -
+                               IFX_SPI_HEADER_OVERHEAD);
                        temp_count = kfifo_out_locked(&port_data->tx_fifo,
                                        tx_buffer, temp_count,
                                        &port_data->fifo_lock);
@@ -591,12 +595,10 @@ static int ifx_spi_prepare_tx_buffer(struct 
ifx_spi_device *ifx_dev)
        }
        /* have data and info for header -- set up SPI header in buffer */
        /* spi header needs payload size, not entire buffer size */
-       ifx_spi_setup_spi_header(ifx_dev->tx_buffer,
-                                       tx_count-IFX_SPI_HEADER_OVERHEAD,
-                                       ifx_dev->spi_more);
+       ifx_spi_setup_spi_header(ifx_dev, tx_count-IFX_SPI_HEADER_OVERHEAD);
        /* swap actual data in the buffer */
        swap_buf((u16 *)(ifx_dev->tx_buffer), tx_count,
-               &ifx_dev->tx_buffer[IFX_SPI_TRANSFER_SIZE]);
+               &ifx_dev->tx_buffer[ifx_dev->ifx_transfer_size]);
        return tx_count;
 }
 
@@ -641,7 +643,7 @@ static int ifx_spi_write(struct tty_struct *tty, const 
unsigned char *buf,
  *     @tty: our tty device
  *
  *     Report how much data we can accept before we drop bytes. As we use
- *     a simple FIFO this is nice and easy.
+ *     a simple FIFO this is nice and easy.
  */
 static int ifx_spi_write_room(struct tty_struct *tty)
 {
@@ -694,8 +696,28 @@ static int ifx_spi_ioctl(struct tty_struct *tty, struct 
file *file,
                nreset = ifx_dev->mdm_reset_unsol;
                ifx_dev->mdm_reset_unsol = 0;
                dev_dbg(&ifx_dev->spi_dev->dev, "reset = %d", nreset);
-               if (copy_to_user((int __user *)arg, &nreset, sizeof(int)))
-                       return -EFAULT;
+               return put_user(nreset, (int __user *)arg);
+               break;
+
+       case IFX_GET_SPI_TRANSFER_SIZE:
+               if (!capable(CAP_SYS_RAWIO))
+                       return -EPERM;
+               return put_user(ifx_dev->ifx_transfer_size, (int __user *)arg);
+
+       case IFX_SET_SPI_TRANSFER_SIZE:
+               if (!capable(CAP_SYS_RAWIO))
+                       return -EPERM;
+
+               switch (arg) {
+               case IFX_SPI_TRANSFER_SIZE:
+               case IFX_FW_DWNLD_TRANSFER_SIZE:
+                       ifx_dev->ifx_transfer_size = arg;
+                       break;
+               default:
+                       dev_dbg(&ifx_dev->spi_dev->dev,
+                               "Invalid Transfer Size %d\n", (int)arg);
+                       break;
+               }
                break;
 
        default:
@@ -933,7 +955,7 @@ static void ifx_spi_complete(void *ctx)
                                        ifx_dev->spi_msg.actual_length);
                swap_buf((u16 *)(ifx_dev->rx_buffer+IFX_SPI_HEADER_OVERHEAD),
                         actual_length,
-                        &ifx_dev->rx_buffer[IFX_SPI_TRANSFER_SIZE]);
+                        &ifx_dev->rx_buffer[ifx_dev->ifx_transfer_size]);
                dev_dbg(&ifx_dev->spi_dev->dev, "send data to flip buffer");
                ifx_spi_insert_flip_string(
                        &port_data->serial,
@@ -1043,7 +1065,7 @@ static void ifx_spi_io(unsigned long data)
 
                /* set up our spi transfer */
                /* note len is BYTES, not transfers */
-               ifx_dev->spi_xfer.len = IFX_SPI_TRANSFER_SIZE;
+               ifx_dev->spi_xfer.len = ifx_dev->ifx_transfer_size;
                ifx_dev->spi_xfer.cs_change = 0;
                ifx_dev->spi_xfer.speed_hz = 12500000;
                /* ifx_dev->spi_xfer.speed_hz = 390625; */
@@ -1398,15 +1420,20 @@ static int ifx_spi_spi_probe(struct spi_device *spi)
        ifx_dev->spi_more = 0;
        ifx_dev->spi_slave_cts = 0;
 
-       /*initialize transfer and dma buffers */
-       ifx_dev->tx_buffer = kzalloc(IFX_SPI_TRANSFER_SIZE,
+       /* set up default IFX data transfer size - 2048 bytes */
+       ifx_dev->ifx_transfer_size = IFX_SPI_TRANSFER_SIZE;
+
+       /*initialize transfer and dma buffers
+        *      FIXME: kzalloc's will be replaced in a later bug fix patch.
+        */
+       ifx_dev->tx_buffer = kzalloc(IFX_SPI_MAX_BUFFER_SIZE,
                GFP_KERNEL | GFP_DMA);
        if (!ifx_dev->tx_buffer) {
                dev_err(&spi->dev, "DMA-TX buffer allocation failed");
                ret = -ENOMEM;
                goto error_ret;
        }
-       ifx_dev->rx_buffer = kzalloc(IFX_SPI_TRANSFER_SIZE,
+       ifx_dev->rx_buffer = kzalloc(IFX_SPI_MAX_BUFFER_SIZE,
                                           GFP_KERNEL | GFP_DMA);
        if (!ifx_dev->rx_buffer) {
                dev_err(&spi->dev, "DMA-RX buffer allocation failed");
@@ -1815,7 +1842,6 @@ static int __init ifx_spi_init(void)
        pr_info("%s: %s called", DRVNAME, __func__);
 
 
-
        tty_drv = alloc_tty_driver(1);
        if (!tty_drv) {
                pr_err("%s: alloc_tty_driver failed", DRVNAME);
diff --git a/drivers/serial/ifx6x60.h b/drivers/serial/ifx6x60.h
index 01c8883..28f892f 100644
--- a/drivers/serial/ifx6x60.h
+++ b/drivers/serial/ifx6x60.h
@@ -31,10 +31,10 @@
 #define MODEMNAME_6160                 "spi_6160_modem"
 #define MODEMNAME_6260                 "spi_6260_modem"
 
-/* #define IFX_THROTTLE_CODE */
-
 #define IFX_SPI_MAX_MINORS             1
 #define IFX_SPI_TRANSFER_SIZE          2048
+#define IFX_FW_DWNLD_TRANSFER_SIZE     2060
+#define IFX_SPI_MAX_BUFFER_SIZE                2060
 #define IFX_SPI_FIFO_SIZE              4096
 
 #define IFX_SPI_HEADER_OVERHEAD                4
@@ -88,6 +88,7 @@ struct ifx_spi_device {
        unsigned char *tx_buffer;
        unsigned char spi_more;
        unsigned char spi_slave_cts;
+       int ifx_transfer_size;
 
        struct timer_list spi_timer;
 
diff --git a/include/linux/spi/ifx6x60_ioctl.h 
b/include/linux/spi/ifx6x60_ioctl.h
index 3d773ab..e1a6057 100644
--- a/include/linux/spi/ifx6x60_ioctl.h
+++ b/include/linux/spi/ifx6x60_ioctl.h
@@ -36,4 +36,17 @@
  */
 #define IFX_GET_SILENT_RESET   _IOR(IFX_SPI_MAGIC, 1, int)
 
+/*
+ * IFX_GET_SPI_TRANSFER_SIZE - gets the current spi message transfer size
+ */
+#define IFX_GET_SPI_TRANSFER_SIZE      _IOR(IFX_SPI_MAGIC, 2, int)
+
+/*
+ * IFX_SET_SPI_TRANSFER_SIZE - set the spi message transfer size to either
+ *                             2048 bytes for normal data transfers, or
+ *                             2060 bytes for the firmware download.
+ */
+#define IFX_SET_SPI_TRANSFER_SIZE      _IOW(IFX_SPI_MAGIC, 3, int)
+
+
 #endif /* _IFX6X60_IOCTL_H */
-- 
1.7.0.4
From 4671b1de8a93a60f116328b2ee433bffdbf8075e Mon Sep 17 00:00:00 2001
From: Ken Mills <[email protected]>
Date: Wed, 20 Oct 2010 16:16:15 -0700
Subject: [PATCH] New ioctl to adjust SPI message length

This allows an application to change the default SPI message length from 2048 bytes
to 2060 bytes. 2060 bytes is the message size used for modem firmware download.

Signed-off-by: Ken Mills <[email protected]>
---
 drivers/serial/ifx6x60.c          |   66 +++++++++++++++++++++++++-----------
 drivers/serial/ifx6x60.h          |    5 ++-
 include/linux/spi/ifx6x60_ioctl.h |   13 +++++++
 3 files changed, 62 insertions(+), 22 deletions(-)

diff --git a/drivers/serial/ifx6x60.c b/drivers/serial/ifx6x60.c
index d5bef6e..5353368 100644
--- a/drivers/serial/ifx6x60.c
+++ b/drivers/serial/ifx6x60.c
@@ -492,12 +492,14 @@ static int ifx_spi_decode_spi_header(unsigned char *buffer, int *length,
  *
  *	FIXME: endianness?
  */
-static void ifx_spi_setup_spi_header(unsigned char *txbuffer, int tx_count,
-					unsigned char more)
+static void ifx_spi_setup_spi_header(struct ifx_spi_device *ifx_dev,
+		int tx_count)
 {
-	*(u16 *)(txbuffer) = tx_count;
-	*(u16 *)(txbuffer+2) = IFX_SPI_PAYLOAD_SIZE;
-	txbuffer[1] |= (more << IFX_SPI_MORE_BIT) & IFX_SPI_MORE_MASK;
+	*(u16 *)(ifx_dev->tx_buffer) = tx_count;
+	*(u16 *)(ifx_dev->tx_buffer+2) = ifx_dev->ifx_transfer_size -
+		IFX_SPI_HEADER_OVERHEAD;
+	ifx_dev->tx_buffer[1] |= (ifx_dev->spi_more << IFX_SPI_MORE_BIT) &
+		IFX_SPI_MORE_MASK;
 }
 
 /**
@@ -541,7 +543,7 @@ static int ifx_spi_prepare_tx_buffer(struct ifx_spi_device *ifx_dev)
 
 	dev_dbg(&ifx_dev->spi_dev->dev, "prepare_tx_buffer called");
 	tx_buffer = ifx_dev->tx_buffer;
-	memset(tx_buffer, 0, IFX_SPI_TRANSFER_SIZE);
+	memset(tx_buffer, 0, IFX_SPI_MAX_BUFFER_SIZE);
 
 	/* make room for required SPI header */
 	tx_buffer += IFX_SPI_HEADER_OVERHEAD;
@@ -557,7 +559,9 @@ static int ifx_spi_prepare_tx_buffer(struct ifx_spi_device *ifx_dev)
 		queue_length = kfifo_len(&port_data->tx_fifo);
 		if (queue_length != 0) {
 			/* data to mux -- see if there's room for it */
-			temp_count = min(queue_length, IFX_SPI_PAYLOAD_SIZE);
+			temp_count = min(queue_length,
+				ifx_dev->ifx_transfer_size -
+				IFX_SPI_HEADER_OVERHEAD);
 			temp_count = kfifo_out_locked(&port_data->tx_fifo,
 					tx_buffer, temp_count,
 					&port_data->fifo_lock);
@@ -591,12 +595,10 @@ static int ifx_spi_prepare_tx_buffer(struct ifx_spi_device *ifx_dev)
 	}
 	/* have data and info for header -- set up SPI header in buffer */
 	/* spi header needs payload size, not entire buffer size */
-	ifx_spi_setup_spi_header(ifx_dev->tx_buffer,
-					tx_count-IFX_SPI_HEADER_OVERHEAD,
-					ifx_dev->spi_more);
+	ifx_spi_setup_spi_header(ifx_dev, tx_count-IFX_SPI_HEADER_OVERHEAD);
 	/* swap actual data in the buffer */
 	swap_buf((u16 *)(ifx_dev->tx_buffer), tx_count,
-		&ifx_dev->tx_buffer[IFX_SPI_TRANSFER_SIZE]);
+		&ifx_dev->tx_buffer[ifx_dev->ifx_transfer_size]);
 	return tx_count;
 }
 
@@ -641,7 +643,7 @@ static int ifx_spi_write(struct tty_struct *tty, const unsigned char *buf,
  *	@tty: our tty device
  *
  *	Report how much data we can accept before we drop bytes. As we use
- * 	a simple FIFO this is nice and easy.
+ *	a simple FIFO this is nice and easy.
  */
 static int ifx_spi_write_room(struct tty_struct *tty)
 {
@@ -694,8 +696,28 @@ static int ifx_spi_ioctl(struct tty_struct *tty, struct file *file,
 		nreset = ifx_dev->mdm_reset_unsol;
 		ifx_dev->mdm_reset_unsol = 0;
 		dev_dbg(&ifx_dev->spi_dev->dev, "reset = %d", nreset);
-		if (copy_to_user((int __user *)arg, &nreset, sizeof(int)))
-			return -EFAULT;
+		return put_user(nreset, (int __user *)arg);
+		break;
+
+	case IFX_GET_SPI_TRANSFER_SIZE:
+		if (!capable(CAP_SYS_RAWIO))
+			return -EPERM;
+		return put_user(ifx_dev->ifx_transfer_size, (int __user *)arg);
+
+	case IFX_SET_SPI_TRANSFER_SIZE:
+		if (!capable(CAP_SYS_RAWIO))
+			return -EPERM;
+
+		switch (arg) {
+		case IFX_SPI_TRANSFER_SIZE:
+		case IFX_FW_DWNLD_TRANSFER_SIZE:
+			ifx_dev->ifx_transfer_size = arg;
+			break;
+		default:
+			dev_dbg(&ifx_dev->spi_dev->dev,
+				"Invalid Transfer Size %d\n", (int)arg);
+			break;
+		}
 		break;
 
 	default:
@@ -933,7 +955,7 @@ static void ifx_spi_complete(void *ctx)
 					ifx_dev->spi_msg.actual_length);
 		swap_buf((u16 *)(ifx_dev->rx_buffer+IFX_SPI_HEADER_OVERHEAD),
 			 actual_length,
-			 &ifx_dev->rx_buffer[IFX_SPI_TRANSFER_SIZE]);
+			 &ifx_dev->rx_buffer[ifx_dev->ifx_transfer_size]);
 		dev_dbg(&ifx_dev->spi_dev->dev, "send data to flip buffer");
 		ifx_spi_insert_flip_string(
 			&port_data->serial,
@@ -1043,7 +1065,7 @@ static void ifx_spi_io(unsigned long data)
 
 		/* set up our spi transfer */
 		/* note len is BYTES, not transfers */
-		ifx_dev->spi_xfer.len = IFX_SPI_TRANSFER_SIZE;
+		ifx_dev->spi_xfer.len = ifx_dev->ifx_transfer_size;
 		ifx_dev->spi_xfer.cs_change = 0;
 		ifx_dev->spi_xfer.speed_hz = 12500000;
 		/* ifx_dev->spi_xfer.speed_hz = 390625; */
@@ -1398,15 +1420,20 @@ static int ifx_spi_spi_probe(struct spi_device *spi)
 	ifx_dev->spi_more = 0;
 	ifx_dev->spi_slave_cts = 0;
 
-	/*initialize transfer and dma buffers */
-	ifx_dev->tx_buffer = kzalloc(IFX_SPI_TRANSFER_SIZE,
+	/* set up default IFX data transfer size - 2048 bytes */
+	ifx_dev->ifx_transfer_size = IFX_SPI_TRANSFER_SIZE;
+
+	/*initialize transfer and dma buffers
+	 *	FIXME: kzalloc's will be replaced in a later bug fix patch.
+	 */
+	ifx_dev->tx_buffer = kzalloc(IFX_SPI_MAX_BUFFER_SIZE,
 		GFP_KERNEL | GFP_DMA);
 	if (!ifx_dev->tx_buffer) {
 		dev_err(&spi->dev, "DMA-TX buffer allocation failed");
 		ret = -ENOMEM;
 		goto error_ret;
 	}
-	ifx_dev->rx_buffer = kzalloc(IFX_SPI_TRANSFER_SIZE,
+	ifx_dev->rx_buffer = kzalloc(IFX_SPI_MAX_BUFFER_SIZE,
 					   GFP_KERNEL | GFP_DMA);
 	if (!ifx_dev->rx_buffer) {
 		dev_err(&spi->dev, "DMA-RX buffer allocation failed");
@@ -1815,7 +1842,6 @@ static int __init ifx_spi_init(void)
 	pr_info("%s: %s called", DRVNAME, __func__);
 
 
-
 	tty_drv = alloc_tty_driver(1);
 	if (!tty_drv) {
 		pr_err("%s: alloc_tty_driver failed", DRVNAME);
diff --git a/drivers/serial/ifx6x60.h b/drivers/serial/ifx6x60.h
index 01c8883..28f892f 100644
--- a/drivers/serial/ifx6x60.h
+++ b/drivers/serial/ifx6x60.h
@@ -31,10 +31,10 @@
 #define MODEMNAME_6160			"spi_6160_modem"
 #define MODEMNAME_6260			"spi_6260_modem"
 
-/* #define IFX_THROTTLE_CODE */
-
 #define IFX_SPI_MAX_MINORS		1
 #define IFX_SPI_TRANSFER_SIZE		2048
+#define IFX_FW_DWNLD_TRANSFER_SIZE	2060
+#define IFX_SPI_MAX_BUFFER_SIZE		2060
 #define IFX_SPI_FIFO_SIZE		4096
 
 #define IFX_SPI_HEADER_OVERHEAD		4
@@ -88,6 +88,7 @@ struct ifx_spi_device {
 	unsigned char *tx_buffer;
 	unsigned char spi_more;
 	unsigned char spi_slave_cts;
+	int ifx_transfer_size;
 
 	struct timer_list spi_timer;
 
diff --git a/include/linux/spi/ifx6x60_ioctl.h b/include/linux/spi/ifx6x60_ioctl.h
index 3d773ab..e1a6057 100644
--- a/include/linux/spi/ifx6x60_ioctl.h
+++ b/include/linux/spi/ifx6x60_ioctl.h
@@ -36,4 +36,17 @@
  */
 #define IFX_GET_SILENT_RESET	_IOR(IFX_SPI_MAGIC, 1, int)
 
+/*
+ * IFX_GET_SPI_TRANSFER_SIZE - gets the current spi message transfer size
+ */
+#define IFX_GET_SPI_TRANSFER_SIZE	_IOR(IFX_SPI_MAGIC, 2, int)
+
+/*
+ * IFX_SET_SPI_TRANSFER_SIZE - set the spi message transfer size to either
+ *				2048 bytes for normal data transfers, or
+ *				2060 bytes for the firmware download.
+ */
+#define IFX_SET_SPI_TRANSFER_SIZE	_IOW(IFX_SPI_MAGIC, 3, int)
+
+
 #endif /* _IFX6X60_IOCTL_H */
-- 
1.7.0.4

_______________________________________________
Meego-kernel mailing list
[email protected]
http://lists.meego.com/listinfo/meego-kernel

Reply via email to