功能是使用内存的4k单元,实现读,写,偏移,清除。
1 /*********************************************************************************
2 * Copyright: (C) 2014 zhouguangfeng
3 + plat_globalfifo.c
4 /*********************************************************************************
5 * Copyright: (C) 2014 zhouguangfeng
6 * All rights reserved.
7 *
8 * Filename: plat_globalfifo.c
9 * Description: This file is a commom platform driver
10 *
11 * Version: 1.0.0(08/19/2014)
12 * Author: zhouguangfeng
13 * ChangeLog: 1, Release initial version on "08/19/2014 02:31:17 PM"
14 *
15 ********************************************************************************/
16 #include
17 #include
18 #include
19 #include
20 #include
21 #include
22 #include
23 #include
24 #include //io operation function ,like ioremap,iowrite
25 #include
26 #include //for ioctl command
27 #include
28 #include
29 #include
30 #include
31
32
33 #define GLOBALFIFO_SIZE 0x1000 /* 4K */
34 #define NAME "globalfifo"
35 #define KELNEL_OLD 0 /* decsion ioctl() */
36
37 #ifndef GLOBALFIFO_MAJOR
38 #define GLOBALFIFO_MAJOR 0
39 #endif
40
41
42 //#define GLOBALFIFO_CLEAR 0x17
43 //#define MEM_CLEAR __IO (GLOBALFIFO_CLEAR, 0x20)
44 #define MEM_CLEAR 0x20
45
46
47 static int globalfifo_major = GLOBALFIFO_MAJOR;
48 static int globalfifo_minor = 0;
49
50
51 /* ============================ Platform Device part =============================== */
52
53 struct globalfifo_dev
54 {
55 struct cdev cdev;
56 unsigned int current_len;
57 unsigned char mem[GLOBALFIFO_SIZE];
58 struct class *class;
59
60
61 //struct semaphrore sem;
62 // wait_queue_t r_wait;
63 //wait_queue_t r_wait;
64 } globalfifo_dev;
65
66 static void plat_release(struct device * dev)
67 {
68 return;
69 }
70
71 static struct platform_device globalfifo_device = {
72 .name = "globalfifo",
73 .id = 1,
74 .dev = {
75 .release = plat_release,
76 },
77 };
78
79
80
81 /* ===================== globalfifo driver part ===========================*/
82
83 int globalfifo_open(struct inode *inode, struct file *filp)
84 {
85 struct globalfifo_dev *dev;
86
87 dev = container_of(inode->i_cdev, struct globalfifo_dev, cdev);
88 filp->private_data = dev;
89
90 return 0;
91 }
92
93 int globalfifo_release(struct inode *inode, struct file *filp)
94 {
95 return 0;
96 }
97
98
99 #if KELNEL_OLD
100 static ssize_t globalfifo_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
101 {
102 struct globalfifo_dev *dev = filp->private_data;
103 switch(cmd)
104 {
105 case MEM_CLEAR:
106 memset(dev->mem, 0, GLOBALFIFO_SIZE);
107 printk(KERN_INFO "globalfifo is set to zeron");
108 break;
109
110 default:
111 return -EINVAL;
112 }
113
114 return 0;
115 }
116 #endif
117
118 static ssize_t globalfifo_read(struct file *filp, char __user *buf, size_t size, loff_t *opps)
119 {
120 unsigned long p = *opps;
121 unsigned int count = size;
122 int ret = 0;
123
124 struct globalfifo_dev *dev = filp->private_data;
125
126 if(p >= GLOBALFIFO_SIZE)
127 {
128 return count ? -ENXIO : 0;
129 }
130 if(count > GLOBALFIFO_SIZE - p)
131 {
132 count = GLOBALFIFO_SIZE - p;
133 }
134
135 if(copy_to_user(buf, (void *)((dev->mem)+p), count))
136 {
137 ret = -EFAULT;
138 }
139 else
140 {
141 *opps += count;
142 ret = count;
143 printk(KERN_INFO"read %u bytes(s) from %lun", count, p);
144 }
145
146 return ret;
147 }
148
149 static ssize_t globalfifo_write(struct file *filp, const char __user *buf, size_t size, loff_t *opps)
150 {
151 unsigned long p = *opps;
152 unsigned int count = size;
153 int ret;
154
155 struct globalfifo_dev *dev = filp->private_data;
156
157 if(p >= GLOBALFIFO_SIZE)
158 {
159 return count ? -ENXIO : 0;
160 }
161
162 if(count > GLOBALFIFO_SIZE - p)
163 {
164 count = GLOBALFIFO_SIZE - p;
165 }
166
167 if(copy_from_user(((dev->mem)+p), buf, count))
168 {
169 ret = -EFAULT;
170 }
171 else
172 {
173 *opps =+ count;
174 ret = count;
175 printk(KERN_INFO "written %u bytes(s) from %lun", count, p);
176 }
177 return ret;
178 }
179
180
181 #if 1
182 static loff_t globalfifo_llseek(struct file *filp, loff_t offset, int orig)
183 {
184 loff_t ret = 0;
185
186 switch(orig)
187 {
188 case 0:
189 if(offset <0 )
190 {
191 ret = -EINVAL;
192 break;
193 }
194
195 if((unsigned int )offset > GLOBALFIFO_SIZE)
196 {
197 ret = -EINVAL;
198 break;
199 }
200 filp->f_pos = (unsigned int)offset;
201 ret = filp->f_pos;