Hi Edward, [auto build test ERROR on next-20170619] [cannot apply to linux/master linus/master robh/for-next v4.12-rc6 v4.12-rc5 v4.12-rc4 v4.12-rc6] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Eddie-James/drivers-fsi-Add-SBEFIFO-and-OCC-drivers/20170623-160949 config: sh-allmodconfig (attached as .config) compiler: sh4-linux-gnu-gcc (Debian 6.3.0-18) 6.3.0 20170516 reproduce: wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=sh All error/warnings (new ones prefixed by >>): drivers//fsi/occ.c: In function 'occ_open': >> drivers//fsi/occ.c:136:32: error: dereferencing pointer to incomplete type 'struct file' struct miscdevice *mdev = file->private_data; ^~ >> drivers//fsi/occ.c:147:22: error: 'O_NONBLOCK' undeclared (first use in this function) if (file->f_flags & O_NONBLOCK) ^~~~~~~~~~ drivers//fsi/occ.c:147:22: note: each undeclared identifier is reported only once for each function it appears in drivers//fsi/occ.c: At top level: >> drivers//fsi/occ.c:324:21: error: variable 'occ_fops' has initializer but incomplete type static const struct file_operations occ_fops = { ^~~~~~~~~~~~~~~ >> drivers//fsi/occ.c:325:2: error: unknown field 'owner' specified in initializer .owner = THIS_MODULE, ^ In file included from include/linux/linkage.h:6:0, from include/linux/kernel.h:6, from include/linux/unaligned/packed_struct.h:4, from include/linux/unaligned/le_struct.h:4, from include/asm-generic/unaligned.h:17, from arch/sh/include/asm/unaligned.h:9, from drivers//fsi/occ.c:10: include/linux/export.h:35:21: warning: excess elements in struct initializer #define THIS_MODULE (&__this_module) ^ >> drivers//fsi/occ.c:325:11: note: in expansion of macro 'THIS_MODULE' .owner = THIS_MODULE, ^~~~~~~~~~~ include/linux/export.h:35:21: note: (near initialization for 'occ_fops') #define THIS_MODULE (&__this_module) ^ >> drivers//fsi/occ.c:325:11: note: in expansion of macro 'THIS_MODULE' .owner = THIS_MODULE, ^~~~~~~~~~~ >> drivers//fsi/occ.c:326:2: error: unknown field 'open' specified in initializer .open = occ_open, ^ >> drivers//fsi/occ.c:326:10: warning: excess elements in struct initializer .open = occ_open, ^~~~~~~~ drivers//fsi/occ.c:326:10: note: (near initialization for 'occ_fops') >> drivers//fsi/occ.c:327:2: error: unknown field 'read' specified in initializer .read = occ_read, ^ drivers//fsi/occ.c:327:10: warning: excess elements in struct initializer .read = occ_read, ^~~~~~~~ drivers//fsi/occ.c:327:10: note: (near initialization for 'occ_fops') >> drivers//fsi/occ.c:328:2: error: unknown field 'write' specified in initializer .write = occ_write, ^ drivers//fsi/occ.c:328:11: warning: excess elements in struct initializer .write = occ_write, ^~~~~~~~~ drivers//fsi/occ.c:328:11: note: (near initialization for 'occ_fops') >> drivers//fsi/occ.c:329:2: error: unknown field 'release' specified in initializer .release = occ_release, ^ drivers//fsi/occ.c:329:13: warning: excess elements in struct initializer .release = occ_release, ^~~~~~~~~~~ drivers//fsi/occ.c:329:13: note: (near initialization for 'occ_fops') >> drivers//fsi/occ.c:324:37: error: storage size of 'occ_fops' isn't known static const struct file_operations occ_fops = { ^~~~~~~~ vim +/O_NONBLOCK +147 drivers//fsi/occ.c 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 */ 9 > 10 #include <asm/unaligned.h> 11 #include <linux/device.h> 12 #include <linux/err.h> 13 #include <linux/fsi-sbefifo.h> 14 #include <linux/init.h> 15 #include <linux/kernel.h> 16 #include <linux/miscdevice.h> 17 #include <linux/module.h> 18 #include <linux/mutex.h> 19 #include <linux/of.h> 20 #include <linux/of_platform.h> 21 #include <linux/platform_device.h> 22 #include <linux/slab.h> 23 #include <linux/uaccess.h> 24 #include <linux/wait.h> 25 #include <linux/workqueue.h> 26 27 #define OCC_SRAM_BYTES 4096 28 #define OCC_CMD_DATA_BYTES 4090 29 #define OCC_RESP_DATA_BYTES 4089 30 31 struct occ { 32 struct device *sbefifo; 33 char name[32]; 34 int idx; 35 struct miscdevice mdev; 36 struct list_head xfrs; 37 spinlock_t list_lock; 38 struct mutex occ_lock; 39 struct work_struct work; 40 }; 41 42 #define to_occ(x) container_of((x), struct occ, mdev) 43 44 struct occ_command { 45 u8 seq_no; 46 u8 cmd_type; 47 u16 data_length; 48 u8 data[OCC_CMD_DATA_BYTES]; 49 u16 checksum; 50 } __packed; 51 52 struct occ_response { 53 u8 seq_no; 54 u8 cmd_type; 55 u8 return_status; 56 u16 data_length; 57 u8 data[OCC_RESP_DATA_BYTES]; 58 u16 checksum; 59 } __packed; 60 61 /* 62 * transfer flags are NOT mutually exclusive 63 * 64 * Initial flags are none; transfer is created and queued from write(). All 65 * flags are cleared when the transfer is completed by closing the file or 66 * reading all of the available response data. 67 * XFR_IN_PROGRESS is set when a transfer is started from occ_worker_putsram, 68 * and cleared if the transfer fails or occ_worker_getsram completes. 69 * XFR_COMPLETE is set when a transfer fails or finishes occ_worker_getsram. 70 * XFR_CANCELED is set when the transfer's client is released. 71 * XFR_WAITING is set from read() if the transfer isn't complete and 72 * O_NONBLOCK wasn't specified. Cleared in read() when transfer completes or 73 * fails. 74 */ 75 enum { 76 XFR_IN_PROGRESS, 77 XFR_COMPLETE, 78 XFR_CANCELED, 79 XFR_WAITING, 80 }; 81 82 struct occ_xfr { 83 struct list_head link; 84 int rc; 85 u8 buf[OCC_SRAM_BYTES]; 86 size_t cmd_data_length; 87 size_t resp_data_length; 88 unsigned long flags; 89 }; 90 91 /* 92 * client flags 93 * 94 * CLIENT_NONBLOCKING is set during open() if the file was opened with the 95 * O_NONBLOCK flag. 96 * CLIENT_XFR_PENDING is set during write() and cleared when all data has been 97 * read. 98 */ 99 enum { 100 CLIENT_NONBLOCKING, 101 CLIENT_XFR_PENDING, 102 }; 103 104 struct occ_client { 105 struct occ *occ; 106 struct occ_xfr xfr; 107 spinlock_t lock; 108 wait_queue_head_t wait; 109 size_t read_offset; 110 unsigned long flags; 111 }; 112 113 #define to_client(x) container_of((x), struct occ_client, xfr) 114 115 static struct workqueue_struct *occ_wq; 116 117 static DEFINE_IDA(occ_ida); 118 119 static void occ_enqueue_xfr(struct occ_xfr *xfr) 120 { 121 int empty; 122 struct occ_client *client = to_client(xfr); 123 struct occ *occ = client->occ; 124 125 spin_lock_irq(&occ->list_lock); 126 empty = list_empty(&occ->xfrs); 127 list_add_tail(&xfr->link, &occ->xfrs); 128 spin_unlock(&occ->list_lock); 129 130 if (empty) 131 queue_work(occ_wq, &occ->work); 132 } 133 134 static int occ_open(struct inode *inode, struct file *file) 135 { > 136 struct miscdevice *mdev = file->private_data; 137 struct occ *occ = to_occ(mdev); 138 struct occ_client *client = kzalloc(sizeof(*client), GFP_KERNEL); 139 140 if (!client) 141 return -ENOMEM; 142 143 client->occ = occ; 144 spin_lock_init(&client->lock); 145 init_waitqueue_head(&client->wait); 146 > 147 if (file->f_flags & O_NONBLOCK) 148 set_bit(CLIENT_NONBLOCKING, &client->flags); 149 150 file->private_data = client; 151 152 return 0; 153 } 154 155 static ssize_t occ_read(struct file *file, char __user *buf, size_t len, 156 loff_t *offset) 157 { 158 int rc; 159 size_t bytes; 160 struct occ_client *client = file->private_data; 161 struct occ_xfr *xfr = &client->xfr; 162 163 if (len > OCC_SRAM_BYTES) 164 return -EINVAL; 165 166 spin_lock_irq(&client->lock); 167 if (!test_bit(CLIENT_XFR_PENDING, &client->flags)) { 168 /* we just finished reading all data, return 0 */ 169 if (client->read_offset) { 170 rc = 0; 171 client->read_offset = 0; 172 } else 173 rc = -ENOMSG; 174 175 goto done; 176 } 177 178 if (!test_bit(XFR_COMPLETE, &xfr->flags)) { 179 if (test_bit(CLIENT_NONBLOCKING, &client->flags)) { 180 rc = -EAGAIN; 181 goto done; 182 } 183 184 set_bit(XFR_WAITING, &xfr->flags); 185 spin_unlock(&client->lock); 186 187 rc = wait_event_interruptible(client->wait, 188 test_bit(XFR_COMPLETE, &xfr->flags) || 189 test_bit(XFR_CANCELED, &xfr->flags)); 190 191 spin_lock_irq(&client->lock); 192 if (test_bit(XFR_CANCELED, &xfr->flags)) { 193 spin_unlock(&client->lock); 194 kfree(client); 195 return -EBADFD; 196 } 197 198 clear_bit(XFR_WAITING, &xfr->flags); 199 if (!test_bit(XFR_COMPLETE, &xfr->flags)) { 200 rc = -EINTR; 201 goto done; 202 } 203 } 204 205 if (xfr->rc) { 206 rc = xfr->rc; 207 goto done; 208 } 209 210 if (copy_to_user(buf, &xfr->buf[client->read_offset], bytes)) { 211 rc = -EFAULT; 212 goto done; 213 } 214 215 client->read_offset += bytes; 216 217 /* xfr done */ 218 if (client->read_offset == xfr->resp_data_length) 219 clear_bit(CLIENT_XFR_PENDING, &client->flags); 220 221 rc = bytes; 222 223 done: 224 spin_unlock(&client->lock); 225 return rc; 226 } 227 228 static ssize_t occ_write(struct file *file, const char __user *buf, 229 size_t len, loff_t *offset) 230 { 231 int rc; 232 unsigned int i; 233 u16 data_length, checksum = 0; 234 struct occ_client *client = file->private_data; 235 struct occ_xfr *xfr = &client->xfr; 236 237 if (len > (OCC_CMD_DATA_BYTES + 3) || len < 3) 238 return -EINVAL; 239 240 spin_lock_irq(&client->lock); 241 242 if (test_bit(CLIENT_XFR_PENDING, &client->flags)) { 243 rc = -EBUSY; 244 goto done; 245 } 246 247 memset(xfr, 0, sizeof(*xfr)); /* clear out the transfer */ 248 xfr->buf[0] = 1; /* occ sequence number */ 249 250 /* Assume user data follows the occ command format. 251 * byte 0: command type 252 * bytes 1-2: data length (msb first) 253 * bytes 3-n: data 254 */ 255 if (copy_from_user(&xfr->buf[1], buf, len)) { 256 rc = -EFAULT; 257 goto done; 258 } 259 260 data_length = (xfr->buf[2] << 8) + xfr->buf[3]; 261 if (data_length > OCC_CMD_DATA_BYTES) { 262 rc = -EINVAL; 263 goto done; 264 } 265 266 for (i = 0; i < data_length + 4; ++i) 267 checksum += xfr->buf[i]; 268 269 xfr->buf[data_length + 4] = checksum >> 8; 270 xfr->buf[data_length + 5] = checksum & 0xFF; 271 272 xfr->cmd_data_length = data_length + 6; 273 client->read_offset = 0; 274 set_bit(CLIENT_XFR_PENDING, &client->flags); 275 occ_enqueue_xfr(xfr); 276 277 rc = len; 278 279 done: 280 spin_unlock(&client->lock); 281 return rc; 282 } 283 284 static int occ_release(struct inode *inode, struct file *file) 285 { 286 struct occ_client *client = file->private_data; 287 struct occ_xfr *xfr = &client->xfr; 288 struct occ *occ = client->occ; 289 290 spin_lock_irq(&client->lock); 291 if (!test_bit(CLIENT_XFR_PENDING, &client->flags)) { 292 spin_unlock(&client->lock); 293 kfree(client); 294 return 0; 295 } 296 297 spin_lock_irq(&occ->list_lock); 298 set_bit(XFR_CANCELED, &xfr->flags); 299 if (!test_bit(XFR_IN_PROGRESS, &xfr->flags)) { 300 /* already deleted from list if complete */ 301 if (!test_bit(XFR_COMPLETE, &xfr->flags)) 302 list_del(&xfr->link); 303 304 spin_unlock(&occ->list_lock); 305 306 if (test_bit(XFR_WAITING, &xfr->flags)) { 307 /* blocking read; let reader clean up */ 308 wake_up_interruptible(&client->wait); 309 spin_unlock(&client->lock); 310 return 0; 311 } 312 313 spin_unlock(&client->lock); 314 kfree(client); 315 return 0; 316 } 317 318 /* operation is in progress; let worker clean up*/ 319 spin_unlock(&occ->list_lock); 320 spin_unlock(&client->lock); 321 return 0; 322 } 323 > 324 static const struct file_operations occ_fops = { > 325 .owner = THIS_MODULE, > 326 .open = occ_open, > 327 .read = occ_read, > 328 .write = occ_write, > 329 .release = occ_release, 330 }; 331 332 static int occ_write_sbefifo(struct sbefifo_client *client, const char *buf, --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
Attachment:
.config.gz
Description: application/gzip