]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/usb/gadget/function/fsl_updater.c
72c14ba03ace2b77dd12c0a9d1efd1c5c40e8969
[karo-tx-linux.git] / drivers / usb / gadget / function / fsl_updater.c
1 /*
2  * Freescale UUT driver
3  *
4  * Copyright 2008-2013 Freescale Semiconductor, Inc.
5  * Copyright 2008-2009 Embedded Alley Solutions, Inc All Rights Reserved.
6  */
7
8 /*
9  * The code contained herein is licensed under the GNU General Public
10  * License. You may obtain a copy of the GNU General Public License
11  * Version 2 or later at the following locations:
12  *
13  * http://www.opensource.org/licenses/gpl-license.html
14  * http://www.gnu.org/copyleft/gpl.html
15  */
16
17 static u64 get_be64(u8 *buf)
18 {
19         return ((u64)get_unaligned_be32(buf) << 32) |
20                 get_unaligned_be32(buf + 4);
21 }
22
23 static int utp_init(struct fsg_dev *fsg)
24 {
25         init_waitqueue_head(&utp_context.wq);
26         init_waitqueue_head(&utp_context.list_full_wq);
27
28         INIT_LIST_HEAD(&utp_context.read);
29         INIT_LIST_HEAD(&utp_context.write);
30         mutex_init(&utp_context.lock);
31
32         /* the max message is 64KB */
33         utp_context.buffer = vmalloc(0x10000);
34         if (!utp_context.buffer)
35                 return -EIO;
36         utp_context.utp_version = 0x1ull;
37         fsg->utp = &utp_context;
38         return misc_register(&utp_dev);
39 }
40
41 static void utp_exit(struct fsg_dev *fsg)
42 {
43         vfree(utp_context.buffer);
44         misc_deregister(&utp_dev);
45 }
46
47 static struct utp_user_data *utp_user_data_alloc(size_t size)
48 {
49         struct utp_user_data *uud;
50
51         uud = kzalloc(size + sizeof(*uud), GFP_KERNEL);
52         if (!uud)
53                 return uud;
54         uud->data.size = size + sizeof(uud->data);
55         INIT_LIST_HEAD(&uud->link);
56         return uud;
57 }
58
59 static void utp_user_data_free(struct utp_user_data *uud)
60 {
61         mutex_lock(&utp_context.lock);
62         list_del(&uud->link);
63         mutex_unlock(&utp_context.lock);
64         kfree(uud);
65 }
66
67 /* Get the number of element for list */
68 static u32 count_list(struct list_head *l)
69 {
70         u32 count = 0;
71         struct list_head *tmp;
72
73         mutex_lock(&utp_context.lock);
74         list_for_each(tmp, l) {
75                 count++;
76         }
77         mutex_unlock(&utp_context.lock);
78
79         return count;
80 }
81 /* The routine will not go on if utp_context.queue is empty */
82 #define WAIT_ACTIVITY(queue) \
83  wait_event_interruptible(utp_context.wq, !list_empty(&utp_context.queue))
84
85 /* Called by userspace program (uuc) */
86 static ssize_t utp_file_read(struct file *file,
87                              char __user *buf,
88                              size_t size,
89                              loff_t *off)
90 {
91         struct utp_user_data *uud;
92         size_t size_to_put;
93         int free = 0;
94
95         WAIT_ACTIVITY(read);
96
97         mutex_lock(&utp_context.lock);
98         uud = list_first_entry(&utp_context.read, struct utp_user_data, link);
99         mutex_unlock(&utp_context.lock);
100         size_to_put = uud->data.size;
101
102         if (size >= size_to_put)
103                 free = !0;
104         if (copy_to_user(buf, &uud->data, size_to_put))
105                 return -EACCES;
106         if (free)
107                 utp_user_data_free(uud);
108         else {
109                 pr_info("sizeof = %d, size = %d\n",
110                         sizeof(uud->data),
111                         uud->data.size);
112
113                 pr_err("Will not free utp_user_data, because buffer size = %d,"
114                         "need to put %d\n", size, size_to_put);
115         }
116
117         /*
118          * The user program has already finished data process,
119          * go on getting data from the host
120          */
121         wake_up(&utp_context.list_full_wq);
122
123         return size_to_put;
124 }
125
126 static ssize_t utp_file_write(struct file *file, const char __user *buf,
127                                 size_t size, loff_t *off)
128 {
129         struct utp_user_data *uud;
130
131         if (size < sizeof(uud->data))
132                 return -EINVAL;
133         uud = utp_user_data_alloc(size);
134         if (copy_from_user(&uud->data, buf, size))
135                 return -EACCES;
136         mutex_lock(&utp_context.lock);
137         list_add_tail(&uud->link, &utp_context.write);
138         /* Go on EXEC routine process */
139         wake_up(&utp_context.wq);
140         mutex_unlock(&utp_context.lock);
141         return size;
142 }
143
144 /*
145  * uuc should change to use soc bus infrastructure to soc information
146  * /sys/devices/soc0/soc_id
147  * this function can be removed.
148  */
149 static long
150 utp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
151 {
152         int cpu_id = 0;
153
154         switch (cmd) {
155         case UTP_GET_CPU_ID:
156                 return put_user(cpu_id, (int __user *)arg);
157         default:
158                 return -ENOIOCTLCMD;
159         }
160 }
161
162 /* Will be called when the host wants to get the sense data */
163 static int utp_get_sense(struct fsg_dev *fsg)
164 {
165         if (UTP_CTX(fsg)->processed == 0)
166                 return -1;
167
168         UTP_CTX(fsg)->processed = 0;
169         return 0;
170 }
171
172 static int utp_do_read(struct fsg_dev *fsg, void *data, size_t size)
173 {
174         struct fsg_buffhd       *bh;
175         int                     rc;
176         u32                     amount_left;
177         unsigned int            amount;
178
179         /* Get the starting Logical Block Address and check that it's
180          * not too big */
181
182         amount_left = size;
183         if (unlikely(amount_left == 0))
184                 return -EIO;            /* No default reply*/
185
186         pr_debug("%s: sending %d\n", __func__, size);
187         for (;;) {
188                 /* Figure out how much we need to read:
189                  * Try to read the remaining amount.
190                  * But don't read more than the buffer size.
191                  * And don't try to read past the end of the file.
192                  * Finally, if we're not at a page boundary, don't read past
193                  *      the next page.
194                  * If this means reading 0 then we were asked to read past
195                  *      the end of file. */
196                 amount = min((unsigned int) amount_left, FSG_BUFLEN);
197
198                 /* Wait for the next buffer to become available */
199                 bh = fsg->common->next_buffhd_to_fill;
200                 while (bh->state != BUF_STATE_EMPTY) {
201                         rc = sleep_thread(fsg->common);
202                         if (rc)
203                                 return rc;
204                 }
205
206                 /* If we were asked to read past the end of file,
207                  * end with an empty buffer. */
208                 if (amount == 0) {
209                         bh->inreq->length = 0;
210                         bh->state = BUF_STATE_FULL;
211                         break;
212                 }
213
214                 /* Perform the read */
215                 pr_info("Copied to %p, %d bytes started from %d\n",
216                                 bh->buf, amount, size - amount_left);
217                 /* from upt buffer to file_storeage buffer */
218                 memcpy(bh->buf, data + size - amount_left, amount);
219                 amount_left  -= amount;
220                 fsg->common->residue -= amount;
221
222                 bh->inreq->length = amount;
223                 bh->state = BUF_STATE_FULL;
224
225                 /* Send this buffer and go read some more */
226                 bh->inreq->zero = 0;
227
228                 /* USB Physical transfer: Data from device to host */
229                 start_transfer(fsg, fsg->bulk_in, bh->inreq,
230                                 &bh->inreq_busy, &bh->state);
231
232                 fsg->common->next_buffhd_to_fill = bh->next;
233
234                 if (amount_left <= 0)
235                         break;
236         }
237
238         return size - amount_left;
239 }
240
241 static int utp_do_write(struct fsg_dev *fsg, void *data, size_t size)
242 {
243         struct fsg_buffhd       *bh;
244         int                     get_some_more;
245         u32                     amount_left_to_req, amount_left_to_write;
246         unsigned int            amount;
247         int                     rc;
248         loff_t                  offset;
249
250         /* Carry out the file writes */
251         get_some_more = 1;
252         amount_left_to_req = amount_left_to_write = size;
253
254         if (unlikely(amount_left_to_write == 0))
255                 return -EIO;
256
257         offset = 0;
258         while (amount_left_to_write > 0) {
259
260                 /* Queue a request for more data from the host */
261                 bh = fsg->common->next_buffhd_to_fill;
262                 if (bh->state == BUF_STATE_EMPTY && get_some_more) {
263
264                         /* Figure out how much we want to get:
265                          * Try to get the remaining amount.
266                          * But don't get more than the buffer size.
267                          * And don't try to go past the end of the file.
268                          * If we're not at a page boundary,
269                          *      don't go past the next page.
270                          * If this means getting 0, then we were asked
271                          *      to write past the end of file.
272                          * Finally, round down to a block boundary. */
273                         amount = min(amount_left_to_req, FSG_BUFLEN);
274
275                         if (amount == 0) {
276                                 get_some_more = 0;
277                                 /* cry now */
278                                 continue;
279                         }
280
281                         /* Get the next buffer */
282                         amount_left_to_req -= amount;
283                         if (amount_left_to_req == 0)
284                                 get_some_more = 0;
285
286                         /* amount is always divisible by 512, hence by
287                          * the bulk-out maxpacket size */
288                         bh->outreq->length = bh->bulk_out_intended_length =
289                                         amount;
290                         bh->outreq->short_not_ok = 1;
291                         start_transfer(fsg, fsg->bulk_out, bh->outreq,
292                                         &bh->outreq_busy, &bh->state);
293                         fsg->common->next_buffhd_to_fill = bh->next;
294                         continue;
295                 }
296
297                 /* Write the received data to the backing file */
298                 bh = fsg->common->next_buffhd_to_drain;
299                 if (bh->state == BUF_STATE_EMPTY && !get_some_more)
300                         break;                  /* We stopped early */
301                 if (bh->state == BUF_STATE_FULL) {
302                         smp_rmb();
303                         fsg->common->next_buffhd_to_drain = bh->next;
304                         bh->state = BUF_STATE_EMPTY;
305
306                         /* Did something go wrong with the transfer? */
307                         if (bh->outreq->status != 0)
308                                 /* cry again, COMMUNICATION_FAILURE */
309                                 break;
310
311                         amount = bh->outreq->actual;
312
313                         /* Perform the write */
314                         memcpy(data + offset, bh->buf, amount);
315
316                         offset += amount;
317                         if (signal_pending(current))
318                                 return -EINTR;          /* Interrupted!*/
319                         amount_left_to_write -= amount;
320                         fsg->common->residue -= amount;
321
322                         /* Did the host decide to stop early? */
323                         if (bh->outreq->actual != bh->outreq->length) {
324                                 fsg->common->short_packet_received = 1;
325                                 break;
326                         }
327                         continue;
328                 }
329
330                 /* Wait for something to happen */
331                 rc = sleep_thread(fsg->common);
332                 if (rc)
333                         return rc;
334         }
335
336         return -EIO;
337 }
338
339 static inline void utp_set_sense(struct fsg_dev *fsg, u16 code, u64 reply)
340 {
341         UTP_CTX(fsg)->processed = true;
342         UTP_CTX(fsg)->sdinfo = reply & 0xFFFFFFFF;
343         UTP_CTX(fsg)->sdinfo_h = (reply >> 32) & 0xFFFFFFFF;
344         UTP_CTX(fsg)->sd = (UTP_SENSE_KEY << 16) | code;
345 }
346
347 static void utp_poll(struct fsg_dev *fsg)
348 {
349         struct utp_context *ctx = UTP_CTX(fsg);
350         struct utp_user_data *uud = NULL;
351
352         mutex_lock(&ctx->lock);
353         if (!list_empty(&ctx->write))
354                 uud = list_first_entry(&ctx->write, struct utp_user_data, link);
355         mutex_unlock(&ctx->lock);
356
357         if (uud) {
358                 if (uud->data.flags & UTP_FLAG_STATUS) {
359                         printk(KERN_WARNING "%s: exit with status %d\n",
360                                         __func__, uud->data.status);
361                         UTP_SS_EXIT(fsg, uud->data.status);
362                 } else {
363                         pr_debug("%s: pass\n", __func__);
364                         UTP_SS_PASS(fsg);
365                 }
366                 utp_user_data_free(uud);
367         } else {
368                 pr_debug("%s: still busy...\n", __func__);
369                 UTP_SS_BUSY(fsg, --ctx->counter);
370         }
371 }
372
373 static int utp_exec(struct fsg_dev *fsg,
374                     char *command,
375                     int cmdsize,
376                     unsigned long long payload)
377 {
378         struct utp_user_data *uud = NULL, *uud2r;
379         struct utp_context *ctx = UTP_CTX(fsg);
380
381         uud2r = utp_user_data_alloc(cmdsize + 1);
382         uud2r->data.flags = UTP_FLAG_COMMAND;
383         uud2r->data.payload = payload;
384         strncpy(uud2r->data.command, command, cmdsize);
385
386         mutex_lock(&ctx->lock);
387         list_add_tail(&uud2r->link, &ctx->read);
388         mutex_unlock(&ctx->lock);
389         /* wake up the read routine */
390         wake_up(&ctx->wq);
391
392         if (command[0] == '!')  /* there will be no response */
393                 return 0;
394
395         /*
396          * the user program (uuc) will return utp_message
397          * and add list to write list
398          */
399         WAIT_ACTIVITY(write);
400
401         mutex_lock(&ctx->lock);
402         if (!list_empty(&ctx->write)) {
403                 uud = list_first_entry(&ctx->write, struct utp_user_data, link);
404 #ifdef DEBUG
405                 pr_info("UUD:\n\tFlags = %02X\n", uud->data.flags);
406                 if (uud->data.flags & UTP_FLAG_DATA) {
407                         pr_info("\tbufsize = %d\n", uud->data.bufsize);
408                         print_hex_dump(KERN_DEBUG, "\t", DUMP_PREFIX_NONE,
409                                 16, 2, uud->data.data, uud->data.bufsize, true);
410                 }
411                 if (uud->data.flags & UTP_FLAG_REPORT_BUSY)
412                         pr_info("\tBUSY\n");
413 #endif
414         }
415         mutex_unlock(&ctx->lock);
416
417         if (uud->data.flags & UTP_FLAG_DATA) {
418                 memcpy(ctx->buffer, uud->data.data, uud->data.bufsize);
419                 UTP_SS_SIZE(fsg, uud->data.bufsize);
420         } else if (uud->data.flags & UTP_FLAG_REPORT_BUSY) {
421                 ctx->counter = 0xFFFF;
422                 UTP_SS_BUSY(fsg, ctx->counter);
423         } else if (uud->data.flags & UTP_FLAG_STATUS) {
424                 printk(KERN_WARNING "%s: exit with status %d\n", __func__,
425                                 uud->data.status);
426                 UTP_SS_EXIT(fsg, uud->data.status);
427         } else {
428                 pr_debug("%s: pass\n", __func__);
429                 UTP_SS_PASS(fsg);
430         }
431         utp_user_data_free(uud);
432         return 0;
433 }
434
435 static int utp_send_status(struct fsg_dev *fsg)
436 {
437         struct fsg_buffhd       *bh;
438         u8                      status = US_BULK_STAT_OK;
439         struct bulk_cs_wrap     *csw;
440         int                     rc;
441
442         /* Wait for the next buffer to become available */
443         bh = fsg->common->next_buffhd_to_fill;
444         while (bh->state != BUF_STATE_EMPTY) {
445                 rc = sleep_thread(fsg->common);
446                 if (rc)
447                         return rc;
448         }
449
450         if (fsg->common->phase_error) {
451                 DBG(fsg, "sending phase-error status\n");
452                 status = US_BULK_STAT_PHASE;
453
454         } else if ((UTP_CTX(fsg)->sd & 0xFFFF) != UTP_REPLY_PASS) {
455                 status = US_BULK_STAT_FAIL;
456         }
457
458         csw = bh->buf;
459
460         /* Store and send the Bulk-only CSW */
461         csw->Signature = __constant_cpu_to_le32(US_BULK_CS_SIGN);
462         csw->Tag = fsg->common->tag;
463         csw->Residue = cpu_to_le32(fsg->common->residue);
464         csw->Status = status;
465
466         bh->inreq->length = US_BULK_CS_WRAP_LEN;
467         bh->inreq->zero = 0;
468         start_transfer(fsg, fsg->bulk_in, bh->inreq,
469                         &bh->inreq_busy, &bh->state);
470         fsg->common->next_buffhd_to_fill = bh->next;
471         return 0;
472 }
473
474 static int utp_handle_message(struct fsg_dev *fsg,
475                               char *cdb_data,
476                               int default_reply)
477 {
478         struct utp_msg *m = (struct utp_msg *)cdb_data;
479         void *data = NULL;
480         int r;
481         struct utp_user_data *uud2r;
482         unsigned long long param;
483         unsigned long tag;
484
485         if (m->f0 != 0xF0)
486                 return default_reply;
487
488         tag = get_unaligned_be32((void *)&m->utp_msg_tag);
489         param = get_be64((void *)&m->param);
490         pr_debug("Type 0x%x, tag 0x%08lx, param %llx\n",
491                         m->utp_msg_type, tag, param);
492
493         switch ((enum utp_msg_type)m->utp_msg_type) {
494
495         case UTP_POLL:
496                 if (get_be64((void *)&m->param) == 1) {
497                         pr_debug("%s: version request\n", __func__);
498                         UTP_SS_EXIT(fsg, UTP_CTX(fsg)->utp_version);
499                         break;
500                 }
501                 utp_poll(fsg);
502                 break;
503         case UTP_EXEC:
504                 pr_debug("%s: EXEC\n", __func__);
505                 data = kzalloc(fsg->common->data_size, GFP_KERNEL);
506                 /* copy data from usb buffer to utp buffer */
507                 utp_do_write(fsg, data, fsg->common->data_size);
508                 utp_exec(fsg, data, fsg->common->data_size, param);
509                 kfree(data);
510                 break;
511         case UTP_GET: /* data from device to host */
512                 pr_debug("%s: GET, %d bytes\n", __func__,
513                                         fsg->common->data_size);
514                 r = utp_do_read(fsg, UTP_CTX(fsg)->buffer,
515                                         fsg->common->data_size);
516                 UTP_SS_PASS(fsg);
517                 break;
518         case UTP_PUT: /* data from host to device */
519                 pr_debug("%s: PUT, %d bytes\n", __func__,
520                                         fsg->common->data_size);
521                 uud2r = utp_user_data_alloc(fsg->common->data_size);
522                 uud2r->data.bufsize = fsg->common->data_size;
523                 uud2r->data.flags = UTP_FLAG_DATA;
524                 utp_do_write(fsg, uud2r->data.data, fsg->common->data_size);
525                 /* don't know what will be written */
526                 mutex_lock(&UTP_CTX(fsg)->lock);
527                 list_add_tail(&uud2r->link, &UTP_CTX(fsg)->read);
528                 mutex_unlock(&UTP_CTX(fsg)->lock);
529                 wake_up(&UTP_CTX(fsg)->wq);
530                 /*
531                  * Return PASS or FAIL according to uuc's status
532                  * Please open it if need to check uuc's status
533                  * and use another version uuc
534                  */
535 #if 0
536                 struct utp_user_data *uud = NULL;
537                 struct utp_context *ctx;
538                 WAIT_ACTIVITY(write);
539                 ctx = UTP_CTX(fsg);
540                 mutex_lock(&ctx->lock);
541
542                 if (!list_empty(&ctx->write))
543                         uud = list_first_entry(&ctx->write,
544                                         struct utp_user_data, link);
545
546                 mutex_unlock(&ctx->lock);
547                 if (uud) {
548                         if (uud->data.flags & UTP_FLAG_STATUS) {
549                                 printk(KERN_WARNING "%s: exit with status %d\n",
550                                          __func__, uud->data.status);
551                                 UTP_SS_EXIT(fsg, uud->data.status);
552                         } else {
553                                 pr_debug("%s: pass\n", __func__);
554                                 UTP_SS_PASS(fsg);
555                         }
556                         utp_user_data_free(uud);
557                 } else{
558                         UTP_SS_PASS(fsg);
559                 }
560 #endif
561                 UTP_SS_PASS(fsg);
562
563                 wait_event_interruptible(UTP_CTX(fsg)->list_full_wq,
564                         count_list(&UTP_CTX(fsg)->read) < 7);
565                 break;
566         }
567
568         utp_send_status(fsg);
569         return -1;
570 }