devices/ccat/update-2.6.32-ethercat.c
author Patrick Bruenn <p.bruenn@beckhoff.com>
Wed, 23 Apr 2014 13:15:10 +0200
branchstable-1.5
changeset 2552 6e419c23b1b3
permissions -rw-r--r--
added ccat support for kernel 2.6.32
2552
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
     1
/**
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
     2
    Network Driver for Beckhoff CCAT communication controller
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
     3
    Copyright (C) 2014  Beckhoff Automation GmbH
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
     4
    Author: Patrick Bruenn <p.bruenn@beckhoff.com>
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
     5
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
     6
    This program is free software; you can redistribute it and/or modify
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
     7
    it under the terms of the GNU General Public License as published by
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
     8
    the Free Software Foundation; either version 2 of the License, or
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
     9
    (at your option) any later version.
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    10
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    11
    This program is distributed in the hope that it will be useful,
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    14
    GNU General Public License for more details.
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    15
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    16
    You should have received a copy of the GNU General Public License along
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    17
    with this program; if not, write to the Free Software Foundation, Inc.,
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    18
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    19
*/
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    20
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    21
#include <linux/fs.h>
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    22
#include <linux/kernel.h>
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    23
#include <linux/module.h>
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    24
#include <linux/sched.h>
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    25
#include <linux/uaccess.h>
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    26
#include "compat.h"
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    27
#include "module.h"
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    28
#include "print.h"
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    29
#include "update.h"
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    30
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    31
#define CCAT_DATA_IN_4 0x038
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    32
#define CCAT_DATA_IN_N 0x7F0
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    33
#define CCAT_DATA_OUT_4 0x030
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    34
#define CCAT_DATA_BLOCK_SIZE (size_t)((CCAT_DATA_IN_N - CCAT_DATA_IN_4)/8)
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    35
#define CCAT_WRITE_BLOCK_SIZE 128
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    36
#define CCAT_FLASH_SIZE (size_t)0xE0000
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    37
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    38
/**     FUNCTION_NAME            CMD,  CLOCKS          */
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    39
#define CCAT_BULK_ERASE          0xE3, 8
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    40
#define CCAT_GET_PROM_ID         0xD5, 40
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    41
#define CCAT_READ_FLASH          0xC0, 32
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    42
#define CCAT_READ_STATUS         0xA0, 16
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    43
#define CCAT_WRITE_ENABLE        0x60, 8
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    44
#define CCAT_WRITE_FLASH         0x40, 32
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    45
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    46
/* from http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith32Bits */
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    47
#define SWAP_BITS(B) \
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    48
	((((B) * 0x0802LU & 0x22110LU) | ((B) * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16)
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    49
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    50
/**
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    51
 * struct update_buffer - keep track of a CCAT FPGA update
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    52
 * @update: pointer to a valid ccat_update object
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    53
 * @data: buffer used for write operations
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    54
 * @size: number of bytes written to the data buffer, if 0 on ccat_update_release() no data will be written to FPGA
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    55
 */
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    56
struct update_buffer {
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    57
	struct ccat_update *update;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    58
	char data[CCAT_FLASH_SIZE];
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    59
	size_t size;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    60
};
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    61
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    62
static void ccat_wait_status_cleared(void __iomem * const ioaddr);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    63
static int ccat_read_flash(void __iomem * const ioaddr, char __user * buf,
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    64
			   uint32_t len, loff_t * off);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    65
static void ccat_write_flash(const struct update_buffer *const buf);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    66
static void ccat_update_cmd(void __iomem * const ioaddr, uint8_t cmd,
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    67
			    uint16_t clocks);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    68
static void ccat_update_destroy(struct kref *ref);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    69
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    70
/**
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    71
 * wait_until_busy_reset() - wait until the busy flag was reset
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    72
 * @ioaddr: address of the CCAT Update function in PCI config space
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    73
 */
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    74
static inline void wait_until_busy_reset(void __iomem * const ioaddr)
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    75
{
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    76
	wmb();
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    77
	while (ioread8(ioaddr + 1)) {
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    78
		schedule();
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    79
	}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    80
}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    81
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    82
static int ccat_update_open(struct inode *const i, struct file *const f)
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    83
{
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    84
	struct ccat_update *update =
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    85
	    container_of(i->i_cdev, struct ccat_update, cdev);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    86
	struct update_buffer *buf;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    87
	kref_get(&update->refcount);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    88
	if (atomic_read(&update->refcount.refcount) > 2) {
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    89
		kref_put(&update->refcount, ccat_update_destroy);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    90
		return -EBUSY;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    91
	}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    92
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    93
	buf = kzalloc(sizeof(*buf), GFP_KERNEL);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    94
	if (!buf) {
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    95
		kref_put(&update->refcount, ccat_update_destroy);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    96
		return -ENOMEM;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    97
	}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    98
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
    99
	buf->update = update;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   100
	f->private_data = buf;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   101
	return 0;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   102
}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   103
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   104
static int ccat_update_release(struct inode *const i, struct file *const f)
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   105
{
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   106
	const struct update_buffer *const buf = f->private_data;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   107
	struct ccat_update *const update = buf->update;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   108
	if (buf->size > 0) {
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   109
		ccat_update_cmd(update->ioaddr, CCAT_WRITE_ENABLE);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   110
		ccat_update_cmd(update->ioaddr, CCAT_BULK_ERASE);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   111
		ccat_wait_status_cleared(update->ioaddr);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   112
		ccat_write_flash(buf);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   113
	}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   114
	kfree(f->private_data);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   115
	kref_put(&update->refcount, ccat_update_destroy);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   116
	return 0;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   117
}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   118
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   119
/**
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   120
 * ccat_update_read() - Read CCAT configuration data from flash
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   121
 * @f: file handle previously initialized with ccat_update_open()
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   122
 * @buf: buffer in user space provided for our data
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   123
 * @len: length of the user space buffer
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   124
 * @off: current offset of our file operation
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   125
 *
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   126
 * Copies data from the CCAT FPGA's configuration flash to user space.
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   127
 * Note that the size of the FPGA's firmware is not known exactly so it
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   128
 * is very possible that the overall buffer ends with a lot of 0xff.
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   129
 *
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   130
 * Return: the number of bytes written, or 0 if EOF reached
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   131
 */
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   132
static ssize_t ccat_update_read(struct file *const f, char __user * buf,
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   133
				size_t len, loff_t * off)
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   134
{
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   135
	struct update_buffer *update = f->private_data;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   136
	if (!buf || !off) {
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   137
		return -EINVAL;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   138
	}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   139
	if (*off >= CCAT_FLASH_SIZE) {
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   140
		return 0;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   141
	}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   142
	if (*off + len >= CCAT_FLASH_SIZE) {
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   143
		len = CCAT_FLASH_SIZE - *off;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   144
	}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   145
	return ccat_read_flash(update->update->ioaddr, buf, len, off);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   146
}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   147
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   148
/**
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   149
 * ccat_update_write() - Write data to the CCAT FPGA's configuration flash
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   150
 * @f: file handle previously initialized with ccat_update_open()
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   151
 * @buf: buffer in user space providing the new configuration data (from *.rbf)
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   152
 * @len: length of the user space buffer
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   153
 * @off: current offset in the configuration data
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   154
 *
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   155
 * Copies data from user space (possibly a *.rbf) to the CCAT FPGA's
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   156
 * configuration flash to user space.
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   157
 *
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   158
 * Return: the number of bytes written, or 0 if flash end is reached
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   159
 */
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   160
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   161
static ssize_t ccat_update_write(struct file *const f, const char __user * buf,
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   162
				 size_t len, loff_t * off)
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   163
{
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   164
	struct update_buffer *const update = f->private_data;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   165
	if (*off + len > sizeof(update->data))
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   166
		return 0;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   167
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   168
	copy_from_user(update->data + *off, buf, len);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   169
	*off += len;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   170
	update->size = *off;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   171
	return len;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   172
}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   173
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   174
static struct file_operations update_ops = {
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   175
	.owner = THIS_MODULE,
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   176
	.open = ccat_update_open,
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   177
	.release = ccat_update_release,
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   178
	.read = ccat_update_read,
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   179
	.write = ccat_update_write,
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   180
};
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   181
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   182
/**
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   183
 * __ccat_update_cmd() - Helper to issue a FPGA flash command
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   184
 * @ioaddr: address of the CCAT Update function in PCI config space
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   185
 * @cmd: the command identifier
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   186
 * @clocks: the number of clocks associated with the specified command
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   187
 *
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   188
 * no write memory barrier is called and the busy flag is not evaluated
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   189
 */
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   190
static inline void __ccat_update_cmd(void __iomem * const ioaddr, uint8_t cmd,
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   191
				     uint16_t clocks)
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   192
{
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   193
	iowrite8((0xff00 & clocks) >> 8, ioaddr);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   194
	iowrite8(0x00ff & clocks, ioaddr + 0x8);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   195
	iowrite8(cmd, ioaddr + 0x10);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   196
}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   197
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   198
/**
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   199
 * ccat_update_cmd() - Helper to issue a FPGA flash command
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   200
 * @ioaddr: address of the CCAT Update function in PCI config space
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   201
 * @cmd: the command identifier
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   202
 * @clocks: the number of clocks associated with the specified command
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   203
 *
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   204
 * Triggers a full flash command cycle with write memory barrier and
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   205
 * command activate. This call blocks until the busy flag is reset.
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   206
 */
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   207
static inline void ccat_update_cmd(void __iomem * const ioaddr, uint8_t cmd,
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   208
				   uint16_t clocks)
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   209
{
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   210
	__ccat_update_cmd(ioaddr, cmd, clocks);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   211
	wmb();
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   212
	iowrite8(0xff, ioaddr + 0x7f8);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   213
	wait_until_busy_reset(ioaddr);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   214
}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   215
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   216
/**
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   217
 * ccat_update_cmd_addr() - Helper to issue a FPGA flash command with address parameter
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   218
 * @ioaddr: address of the CCAT Update function in PCI config space
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   219
 * @cmd: the command identifier
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   220
 * @clocks: the number of clocks associated with the specified command
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   221
 * @addr: 24 bit address associated with the specified command
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   222
 *
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   223
 * Triggers a full flash command cycle with write memory barrier and
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   224
 * command activate. This call blocks until the busy flag is reset.
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   225
 */
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   226
static inline void ccat_update_cmd_addr(void __iomem * const ioaddr,
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   227
					uint8_t cmd, uint16_t clocks,
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   228
					uint32_t addr)
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   229
{
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   230
	const uint8_t addr_0 = SWAP_BITS(addr & 0xff);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   231
	const uint8_t addr_1 = SWAP_BITS((addr & 0xff00) >> 8);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   232
	const uint8_t addr_2 = SWAP_BITS((addr & 0xff0000) >> 16);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   233
	__ccat_update_cmd(ioaddr, cmd, clocks);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   234
	iowrite8(addr_2, ioaddr + 0x18);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   235
	iowrite8(addr_1, ioaddr + 0x20);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   236
	iowrite8(addr_0, ioaddr + 0x28);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   237
	wmb();
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   238
	iowrite8(0xff, ioaddr + 0x7f8);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   239
	wait_until_busy_reset(ioaddr);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   240
}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   241
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   242
/**
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   243
 * ccat_get_prom_id() - Read CCAT PROM ID
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   244
 * @ioaddr: address of the CCAT Update function in PCI config space
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   245
 *
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   246
 * Return: the CCAT FPGA's PROM identifier
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   247
 */
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   248
uint8_t ccat_get_prom_id(void __iomem * const ioaddr)
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   249
{
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   250
	ccat_update_cmd(ioaddr, CCAT_GET_PROM_ID);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   251
	return ioread8(ioaddr + 0x38);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   252
}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   253
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   254
/**
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   255
 * ccat_get_status() - Read CCAT Update status
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   256
 * @ioaddr: address of the CCAT Update function in PCI config space
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   257
 *
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   258
 * Return: the current status of the CCAT Update function
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   259
 */
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   260
static uint8_t ccat_get_status(void __iomem * const ioaddr)
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   261
{
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   262
	ccat_update_cmd(ioaddr, CCAT_READ_STATUS);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   263
	return ioread8(ioaddr + 0x20);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   264
}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   265
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   266
/**
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   267
 * ccat_wait_status_cleared() - wait until CCAT status is cleared
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   268
 * @ioaddr: address of the CCAT Update function in PCI config space
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   269
 *
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   270
 * Blocks until bit 7 of the CCAT Update status is reset
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   271
 */
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   272
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   273
static void ccat_wait_status_cleared(void __iomem * const ioaddr)
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   274
{
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   275
	uint8_t status;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   276
	do {
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   277
		status = ccat_get_status(ioaddr);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   278
	} while (status & (1 << 7));
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   279
}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   280
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   281
/**
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   282
 * ccat_read_flash_block() - Read a block of CCAT configuration data from flash
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   283
 * @ioaddr: address of the CCAT Update function in PCI config space
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   284
 * @addr: 24 bit address of the block to read
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   285
 * @len: number of bytes to read from this block, len <= CCAT_DATA_BLOCK_SIZE
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   286
 * @buf: output buffer in user space
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   287
 *
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   288
 * Copies one block of configuration data from the CCAT FPGA's flash to
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   289
 * the user space buffer.
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   290
 * Note that the size of the FPGA's firmware is not known exactly so it
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   291
 * is very possible that the overall buffer ends with a lot of 0xff.
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   292
 *
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   293
 * Return: the number of bytes copied
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   294
 */
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   295
static int ccat_read_flash_block(void __iomem * const ioaddr,
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   296
				 const uint32_t addr, const uint16_t len,
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   297
				 char __user * const buf)
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   298
{
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   299
	uint16_t i;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   300
	const uint16_t clocks = 8 * len;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   301
	ccat_update_cmd_addr(ioaddr, CCAT_READ_FLASH + clocks, addr);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   302
	for (i = 0; i < len; i++) {
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   303
		put_user(ioread8(ioaddr + CCAT_DATA_IN_4 + 8 * i), buf + i);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   304
	}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   305
	return len;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   306
}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   307
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   308
/**
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   309
 * ccat_read_flash() - Read a chunk of CCAT configuration data from flash
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   310
 * @ioaddr: address of the CCAT Update function in PCI config space
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   311
 * @buf: output buffer in user space
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   312
 * @len: number of bytes to read
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   313
 * @off: offset in the configuration data
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   314
 *
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   315
 * Copies multiple blocks of configuration data from the CCAT FPGA's
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   316
 * flash to the user space buffer.
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   317
 *
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   318
 * Return: the number of bytes copied
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   319
 */
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   320
static int ccat_read_flash(void __iomem * const ioaddr, char __user * buf,
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   321
			   uint32_t len, loff_t * off)
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   322
{
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   323
	const loff_t start = *off;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   324
	while (len > CCAT_DATA_BLOCK_SIZE) {
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   325
		*off +=
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   326
		    ccat_read_flash_block(ioaddr, *off, CCAT_DATA_BLOCK_SIZE,
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   327
					  buf);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   328
		buf += CCAT_DATA_BLOCK_SIZE;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   329
		len -= CCAT_DATA_BLOCK_SIZE;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   330
	}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   331
	*off += ccat_read_flash_block(ioaddr, *off, len, buf);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   332
	return *off - start;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   333
}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   334
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   335
/**
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   336
 * ccat_write_flash_block() - Write a block of CCAT configuration data to flash
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   337
 * @ioaddr: address of the CCAT Update function in PCI config space
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   338
 * @addr: 24 bit start address in the CCAT FPGA's flash
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   339
 * @len: number of bytes to write in this block, len <= CCAT_WRITE_BLOCK_SIZE
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   340
 * @buf: input buffer
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   341
 *
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   342
 * Copies one block of configuration data to the CCAT FPGA's flash
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   343
 *
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   344
 * Return: the number of bytes copied
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   345
 */
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   346
static int ccat_write_flash_block(void __iomem * const ioaddr,
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   347
				  const uint32_t addr, const uint16_t len,
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   348
				  const char *const buf)
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   349
{
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   350
	const uint16_t clocks = 8 * len;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   351
	uint16_t i;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   352
	ccat_update_cmd(ioaddr, CCAT_WRITE_ENABLE);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   353
	for (i = 0; i < len; i++) {
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   354
		iowrite8(buf[i], ioaddr + CCAT_DATA_OUT_4 + 8 * i);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   355
	}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   356
	ccat_update_cmd_addr(ioaddr, CCAT_WRITE_FLASH + clocks, addr);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   357
	ccat_wait_status_cleared(ioaddr);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   358
	return len;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   359
}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   360
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   361
/**
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   362
 * ccat_write_flash() - Write a new CCAT configuration to FPGA's flash
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   363
 * @update: a CCAT Update buffer containing the new FPGA configuration
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   364
 */
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   365
static void ccat_write_flash(const struct update_buffer *const update)
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   366
{
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   367
	const char *buf = update->data;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   368
	uint32_t off = 0;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   369
	size_t len = update->size;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   370
	while (len > CCAT_WRITE_BLOCK_SIZE) {
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   371
		ccat_write_flash_block(update->update->ioaddr, off,
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   372
				       (uint16_t) CCAT_WRITE_BLOCK_SIZE, buf);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   373
		off += CCAT_WRITE_BLOCK_SIZE;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   374
		buf += CCAT_WRITE_BLOCK_SIZE;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   375
		len -= CCAT_WRITE_BLOCK_SIZE;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   376
	}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   377
	ccat_write_flash_block(update->update->ioaddr, off, (uint16_t) len,
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   378
			       buf);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   379
}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   380
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   381
/**
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   382
 * ccat_update_init() - Initialize the CCAT Update function
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   383
 */
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   384
struct ccat_update *ccat_update_init(const struct ccat_device *const ccatdev,
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   385
				     void __iomem * const addr)
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   386
{
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   387
	struct ccat_update *const update = kzalloc(sizeof(*update), GFP_KERNEL);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   388
	if (!update) {
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   389
		return NULL;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   390
	}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   391
	kref_init(&update->refcount);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   392
	update->ioaddr = ccatdev->bar[0].ioaddr + ioread32(addr + 0x8);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   393
	memcpy_fromio(&update->info, addr, sizeof(update->info));
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   394
	print_update_info(&update->info, update->ioaddr);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   395
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   396
	if (0x00 != update->info.nRevision) {
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   397
		pr_warn("CCAT Update rev. %d not supported\n",
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   398
			update->info.nRevision);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   399
		goto cleanup;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   400
	}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   401
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   402
	if (alloc_chrdev_region(&update->dev, 0, 1, DRV_NAME)) {
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   403
		pr_warn("alloc_chrdev_region() failed\n");
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   404
		goto cleanup;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   405
	}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   406
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   407
	update->class = class_create(THIS_MODULE, "ccat_update");
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   408
	if (NULL == update->class) {
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   409
		pr_warn("Create device class failed\n");
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   410
		goto cleanup;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   411
	}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   412
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   413
	if (NULL ==
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   414
	    device_create(update->class, NULL, update->dev, NULL,
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   415
			  "ccat_update")) {
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   416
		pr_warn("device_create() failed\n");
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   417
		goto cleanup;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   418
	}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   419
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   420
	cdev_init(&update->cdev, &update_ops);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   421
	update->cdev.owner = THIS_MODULE;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   422
	update->cdev.ops = &update_ops;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   423
	if (cdev_add(&update->cdev, update->dev, 1)) {
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   424
		pr_warn("add update device failed\n");
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   425
		goto cleanup;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   426
	}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   427
	return update;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   428
cleanup:
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   429
	kref_put(&update->refcount, ccat_update_destroy);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   430
	return NULL;
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   431
}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   432
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   433
/**
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   434
 * ccat_update_destroy() - Cleanup the CCAT Update function
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   435
 * @ref: pointer to a struct kref embedded into a struct ccat_update, which we intend to destroy
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   436
 *
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   437
 * Retrieves the parent struct ccat_update and destroys it.
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   438
 */
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   439
static void ccat_update_destroy(struct kref *ref)
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   440
{
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   441
	struct ccat_update *update =
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   442
	    container_of(ref, struct ccat_update, refcount);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   443
	cdev_del(&update->cdev);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   444
	device_destroy(update->class, update->dev);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   445
	class_destroy(update->class);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   446
	unregister_chrdev_region(update->dev, 1);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   447
	kfree(update);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   448
	pr_debug("%s(): done\n", __FUNCTION__);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   449
}
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   450
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   451
/**
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   452
 * ccat_update_remove() - Prepare the CCAT Update function for removal
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   453
 */
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   454
void ccat_update_remove(struct ccat_update *update)
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   455
{
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   456
	kref_put(&update->refcount, ccat_update_destroy);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   457
	pr_debug("%s(): done\n", __FUNCTION__);
6e419c23b1b3 added ccat support for kernel 2.6.32
Patrick Bruenn <p.bruenn@beckhoff.com>
parents:
diff changeset
   458
}