LMS 2012
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
d_usbdev.c
Go to the documentation of this file.
1 /*
2  * LEGO® MINDSTORMS EV3
3  *
4  * Copyright (C) 2010-2013 The LEGO Group
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  */
20 
21 /*
22  * This UsbDev file is based on and inheritated from
23  * the original file (zero.c) and work done by David Brownell
24  *
25  * >> zero.c -- Gadget Zero, for USB development <<
26  *
27  * >> Copyright (C) 2003-2008 David Brownell <<
28  * >> Copyright (C) 2008 by Nokia Corporation <<
29  *
30  */
31 
39 #ifndef PCASM
40 #include <asm/types.h>
41 #endif
42 
43 #include "../../lms2012/source/lms2012.h"
44 #include "../../lms2012/source/am1808.h"
45 
46 
47 #define MODULE_NAME "usbdev_module"
48 #define DEVICE1_NAME USBDEV_DEVICE
49 
50 
51 
52 static int ModuleInit(void);
53 static void ModuleExit(void);
54 
55 #define __USE_POSIX
56 
57 #include <linux/kernel.h>
58 #include <linux/fs.h>
59 
60 #include <linux/sched.h>
61 
62 
63 #ifndef PCASM
64 #include <linux/hrtimer.h>
65 
66 #include <linux/mm.h>
67 #include <linux/hrtimer.h>
68 
69 #include <linux/init.h>
70 #include <linux/uaccess.h>
71 #include <linux/debugfs.h>
72 
73 #include <linux/ioport.h>
74 #include <asm/gpio.h>
75 #include <asm/io.h>
76 #include <linux/module.h>
77 #include <linux/miscdevice.h>
78 #include <asm/uaccess.h>
79 #include <linux/hid.h>
80 #include <linux/utsname.h>
81 #include <linux/device.h>
82 
83 #include "computil.c" // The composite framework used as utility file
84 #include <../drivers/usb/gadget/gadget_chips.h>
85 #include <../drivers/usb/gadget/usbstring.c>
86 #include <../drivers/usb/gadget/config.c>
87 #include <../drivers/usb/gadget/epautoconf.c>
88 
89 
90 /*-------------------------------------------------------------------------*/
91 
92 /*
93  * Kbuild is not very cooperative with respect to linking separately
94  * compiled library objects into one module. So for now we won't use
95  * separate compilation ... ensuring init/exit sections work to shrink
96  * the runtime footprint, and giving us at least some parts of what
97  * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
98  */
99 
100 #include <../drivers/usb/gadget/g_zero.h>
101 #define MAX_EP_SIZE 1024
102 #define MAX_FULLSPEED_EP_SIZE 64
103 unsigned buflen = MAX_EP_SIZE ;
110 
111 #define SHM_LENGTH (sizeof(UsbSpeedDefault))
112 #define NPAGES ((SHM_LENGTH + PAGE_SIZE - 1) / PAGE_SIZE)
113 static void *kmalloc_ptr;
114 
115 #include "usb_function.c" // Specific USB functionality
116 
117 /*-------------------------------------------------------------------------*/
118 
119 MODULE_LICENSE("GPL");
120 MODULE_AUTHOR("The LEGO Group");
123 
124 module_init(ModuleInit);
125 module_exit(ModuleExit);
126 
127 #else
128 // Keep Eclipse happy
129 #endif
130 
131 // USB main stuff
132 
133 #define DRIVER_VERSION "31jan2011->"
134 
135 #ifndef PCASM
136 module_param(buflen, uint, 0);
137 #else
138 // Keep Eclipse happy
139 #endif
140 
141 static int loopdefault = 0;
142 #ifndef PCASM
143 module_param(loopdefault, bool, S_IRUGO|S_IWUSR);
144 #else
145 // Keep Eclipse happy
146 #endif
147 
148 #define DRIVER_VENDOR_NUM 0x0694 // LEGO Group
149 #define DRIVER_PRODUCT_NUM 0x0005 // No. 5 in a row
150 #define DEFAULT_AUTORESUME 0
151 
152 /* If the optional "autoresume" mode is enabled, it provides good
153  * functional coverage for the "USBCV" test harness from USB-IF.
154  * It's always set if OTG mode is enabled.
155  */
156 
158 module_param(autoresume, uint, S_IRUGO);
159 
160 #ifndef PCASM
161 MODULE_PARM_DESC(autoresume, "zero, or seconds before remote wakeup");
162 #else
163 // Keep Eclipse happy
164 #endif
165 
166 /*-------------------------------------------------------------------------*/
167 
168 static struct usb_device_descriptor device_desc = {
169  .bLength = sizeof device_desc,
170  .bDescriptorType = USB_DT_DEVICE,
171 
172  .bcdUSB = cpu_to_le16(0x0200),
173  .bDeviceClass = 0,
174  .bDeviceSubClass = 0,
175  .bDeviceProtocol = 0,
176  /*.bMaxPacketSize0 = f(hardware) */
177  .idVendor = cpu_to_le16(DRIVER_VENDOR_NUM),
178  .idProduct = cpu_to_le16(DRIVER_PRODUCT_NUM),
179 
180  .bNumConfigurations = 1,
181 };
182 
183 #ifdef CONFIG_USB_OTG
184 struct usb_otg_descriptor otg_descriptor = {
185  .bLength = sizeof otg_descriptor,
186  .bDescriptorType = USB_DT_OTG,
187 
188  /* REVISIT SRP-only hardware is possible, although
189  * it would not be called "OTG" ...
190  */
191  .bmAttributes = USB_OTG_SRP | USB_OTG_HNP,
192 };
193 
194 const struct usb_descriptor_header *otg_desc[] = {
195  (struct usb_descriptor_header *) &otg_descriptor,
196  NULL,
197 };
198 #endif
199 
200 /* string IDs are assigned dynamically */
201 
202 #define STRING_MANUFACTURER_IDX 0
203 #define STRING_PRODUCT_IDX 1
204 #define STRING_SERIAL_IDX 2
205 
206 static char manufacturer[] = "LEGO Group";
207 static char serial[] = "123456789ABC ";
208 static char longname[] = "EV3 brick ";
209 
210 static struct usb_string strings_dev[3] = {
211  [STRING_MANUFACTURER_IDX].s = manufacturer,
212  [STRING_PRODUCT_IDX].s = longname,
213  [STRING_SERIAL_IDX].s = serial
214 };
215 
216 
217 static struct usb_gadget_strings stringtab_dev = {
218  .language = 0x0409, /* en-us */
219  .strings = strings_dev,
220 };
221 
222 static struct usb_gadget_strings *dev_strings[] = {
223  &stringtab_dev,
224  NULL,
225 };
226 
227 /*-------------------------------------------------------------------------*/
228 
229 struct usb_request *alloc_ep_req(struct usb_ep *ep)
230 {
231  struct usb_request *req;
232 
233  req = usb_ep_alloc_request(ep, GFP_ATOMIC);
234  if (req) {
235  req->length = buflen;
236  req->buf = kmalloc(buflen, GFP_ATOMIC);
237  if (!req->buf) {
238  usb_ep_free_request(ep, req);
239  req = NULL;
240  }
241  }
242  return req;
243 }
244 
245 void free_ep_req(struct usb_ep *ep, struct usb_request *req)
246 {
247  kfree(req->buf);
248  usb_ep_free_request(ep, req);
249 }
250 
251 static void disable_ep(struct usb_composite_dev *cdev, struct usb_ep *ep)
252 {
253  int value;
254 
255  if (ep->driver_data) {
256  value = usb_ep_disable(ep);
257  if (value < 0)
258  DBG(cdev, "disable %s --> %d\n",
259  ep->name, value);
260  ep->driver_data = NULL;
261  }
262 }
263 
264 void disable_endpoints(struct usb_composite_dev *cdev,
265  struct usb_ep *in, struct usb_ep *out)
266 {
267  disable_ep(cdev, in);
268  disable_ep(cdev, out);
269 }
270 
271 /*-------------------------------------------------------------------------*/
272 
273 static struct timer_list autoresume_timer;
274 
275 static void zero_autoresume(unsigned long _c)
276 {
277  struct usb_composite_dev *cdev = (void *)_c;
278  struct usb_gadget *g = cdev->gadget;
279 
280  //#define DEBUG
281  #undef DEBUG
282  #ifdef DEBUG
283  printk("zero_autoresume\n\r");
284  #endif
285 
286  /* unconfigured devices can't issue wakeups */
287  if (!cdev->config)
288  return;
289 
290  /* Normally the host would be woken up for something
291  * more significant than just a timer firing; likely
292  * because of some direct user request.
293  */
294  if (g->speed != USB_SPEED_UNKNOWN) {
295  int status = usb_gadget_wakeup(g);
296  INFO(cdev, "%s --> %d\n", __func__, status);
297  }
298 }
299 
300 static void zero_suspend(struct usb_composite_dev *cdev)
301 {
302  //#define DEBUG
303  #undef DEBUG
304  #ifdef DEBUG
305  printk("zero_suspend\n\r");
306  #endif
307 
308  if (cdev->gadget->speed == USB_SPEED_UNKNOWN)
309  return;
310 
311  if (autoresume) {
312  mod_timer(&autoresume_timer, jiffies + (HZ * autoresume));
313  DBG(cdev, "suspend, wakeup in %d seconds\n", autoresume);
314  } else
315  DBG(cdev, "%s\n", __func__);
316 }
317 
318 static void zero_resume(struct usb_composite_dev *cdev)
319 {
320  DBG(cdev, "%s\n", __func__);
321 
322  //#define DEBUG
323  #undef DEBUG
324  #ifdef DEBUG
325  printk("zero_resume\n\r");
326  #endif
327 
328  del_timer(&autoresume_timer);
329 }
330 
331 /*-------------------------------------------------------------------------*/
332 
333 static int zero_bind(struct usb_composite_dev *cdev)
334 {
335  int gcnum;
336  struct usb_gadget *gadget = cdev->gadget;
337  int id;
338 
339  /* Allocate string descriptor numbers ... note that string
340  * contents can be overridden by the composite_dev glue.
341  */
342  id = usb_string_id(cdev);
343  if (id < 0)
344  return id;
345 
346  strings_dev[STRING_MANUFACTURER_IDX].id = id;
347  device_desc.iManufacturer = id;
348 
349  id = usb_string_id(cdev);
350  if (id < 0)
351  return id;
352 
353 
354  strings_dev[STRING_PRODUCT_IDX].id = id;
355  device_desc.iProduct = id;
356 
357  id = usb_string_id(cdev);
358  if (id < 0)
359  return id;
360 
361 
362  strings_dev[STRING_SERIAL_IDX].id = id;
363  device_desc.iSerialNumber = id;
364 
365  setup_timer(&autoresume_timer, zero_autoresume, (unsigned long) cdev);
366 
367  rudolf_add(cdev, autoresume != 0);
368 
369  gcnum = usb_gadget_controller_number(gadget);
370  if (gcnum >= 0)
371  device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum);
372  else {
373  /* gadget zero is so simple (for now, no altsettings) that
374  * it SHOULD NOT have problems with bulk-capable hardware.
375  * so just warn about unrcognized controllers -- don't panic.
376  *
377  * things like configuration and altsetting numbering
378  * can need hardware-specific attention though.
379  */
380  pr_warning("%s: controller '%s' not recognized\n",
381  longname, gadget->name);
382  device_desc.bcdDevice = cpu_to_le16(0x9999);
383  }
384  return 0;
385 }
386 
387 static int zero_unbind(struct usb_composite_dev *cdev)
388 {
389  //#define DEBUG
390  #undef DEBUG
391  #ifdef DEBUG
392  printk("zero_unbind\n\r");
393  #endif
394 
395  del_timer_sync(&autoresume_timer);
396  return 0;
397 }
398 
399 static struct usb_composite_driver zero_driver = {
400  .name = "zero",
401  .dev = &device_desc,
402  .strings = dev_strings,
403  .bind = zero_bind,
404  .unbind = zero_unbind,
405  .suspend = zero_suspend,
406  .resume = zero_resume,
407 };
408 
409 static int dUsbInit(void)
410 {
411  //#define DEBUG
412  #undef DEBUG
413  #ifdef DEBUG
414  printk("dUsbInit\n\r");
415  #endif
416 
417  UsbSpeed.Speed = FULL_SPEED; // default to FULL_SPEED if not connected to a HIGH-SPEED
418  (*pUsbSpeed).Speed = FULL_SPEED; // HOST. If not connected to HIGH-SPEED we assume we're
419  // wanting (or at least doing) Daisy Chain
420  return usb_composite_register(&zero_driver);
421 }
422 
423 static void dUsbExit(void)
424 {
425  usb_composite_unregister(&zero_driver);
426 }
427 
428 // DEVICE1 char device stuff ********************************************************************
429 
430 static ssize_t Device1Write(struct file *File,const char *Buffer,size_t Count,loff_t *Data)
431 {
432  // Write data for the HOST to poll - Stuff sent to the HOST
433 
434  int BytesWritten = 0;
435 
436  #undef DEBUG
437  //#define DEBUG
438  #ifdef DEBUG
439  printk("Device1Write - usb_char_in_length = %d\n", usb_char_in_length);
440  #endif
441 
442  if (usb_char_in_length == 0) // ready for more
443  { // else wait in USER layer
444  BytesWritten = Count;
445  copy_from_user(usb_char_buffer_in, Buffer, BytesWritten);
447 
448  //#define DEBUG
449  #undef DEBUG
450  #ifdef DEBUG
451  printk("WR = %d, %d -- ", usb_char_buffer_in[2], usb_char_buffer_in[3]);
452  #endif
453 
455  {
456  // Already we've a failed tx (HOST part starwing??
457 
459  #undef DEBUG
460  //#define DEBUG
461  #ifdef DEBUG
462  printk("DATA_PENDING SECOND time and reset!! in Device1Write\n\r");
463  #endif
464  }
465 
467  {
468  #undef DEBUG
469  //#define DEBUG
470  #ifdef DEBUG
471  printk("USB_DATA_READY in Device1Write\n\r");
472  #endif
473 
475  write_data_to_the_host(save_in_ep, save_in_req);
476  usb_req_arm(save_in_ep, save_in_req); // new request
477  }
478  else
479  {
481 
482  #undef DEBUG
483  //#define DEBUG
484  #ifdef DEBUG
485  printk("DATA_PENDING in Device1Write\n\r");
486  #endif
487  }
488  }
489 
490  //#define DEBUG
491  #undef DEBUG
492  #ifdef DEBUG
493  printk("usbdev %d written\n\r", BytesWritten);
494  #endif
495 
496  return (BytesWritten); // Zero means USB was not ready yet
497 }
498 
499 static ssize_t Device1Read(struct file *File,char *Buffer,size_t Count,loff_t *Offset)
500 {
501  // Read the bits'n'bytes from the HOST
502  int BytesRead = 0;
503 
504  if (usb_char_out_length > 0) // Something to look at
505  {
506  #undef DEBUG
507  //#define DEBUG
508  #ifdef DEBUG
509  printk("Some bytes to READ?\n\r");
510  #endif
511 
512  copy_to_user(Buffer, usb_char_buffer_out, Count);
513  BytesRead = usb_char_out_length;
515  }
516  return (BytesRead);
517 }
518 
519 static int Device1Mmap(struct file *filp, struct vm_area_struct *vma)
520 {
521  int ret;
522 
523  ret = remap_pfn_range(vma,vma->vm_start,virt_to_phys((void*)((unsigned long)pUsbSpeed)) >> PAGE_SHIFT,vma->vm_end-vma->vm_start,PAGE_SHARED);
524 
525  if (ret != 0)
526  {
527  ret = -EAGAIN;
528  }
529 
530  return (ret);
531 }
532 static const struct file_operations Device1Entries =
533 {
534  .owner = THIS_MODULE,
535  .read = Device1Read,
536  .write = Device1Write,
537  .mmap = Device1Mmap
538 };
539 
540 
541 static struct miscdevice Device1 =
542 {
543  MISC_DYNAMIC_MINOR,
544  DEVICE1_NAME,
545  &Device1Entries
546 };
547 
548 
549 static int Device1Init(void)
550 {
551  int Result = -1;
552  UWORD *pTemp;
553  int i;
554 
555  Result = misc_register(&Device1);
556  if (Result)
557  {
558  //#define DEBUG
559  #undef DEBUG
560  #ifdef DEBUG
561  printk(" %s device register failed\n",DEVICE1_NAME);
562  #endif
563  }
564  else
565  {
566  //#define DEBUG
567  #undef DEBUG
568  #ifdef DEBUG
569  printk(" %s device register OK\n",DEVICE1_NAME);
570  #endif
571 
572  // allocate kernel shared memory for DaisyChain Speed info
573 
574  if ((kmalloc_ptr = kmalloc((NPAGES + 2) * PAGE_SIZE, GFP_KERNEL)) != NULL)
575  {
576 
577  pTemp = (UWORD*)((((unsigned long)kmalloc_ptr) + PAGE_SIZE - 1) & PAGE_MASK);
578 
579  for (i = 0; i < NPAGES * PAGE_SIZE; i += PAGE_SIZE)
580  {
581  SetPageReserved(virt_to_page(((unsigned long)pTemp) + i));
582  }
583 
584  pUsbSpeed = (USB_SPEED*)pTemp;
585  }
586 
587  dUsbInit();
588  }
589 
590  return (Result);
591 }
592 
593 static void Device1Exit(void)
594 {
595  int i;
596  UWORD *pTemp = (UWORD*)pUsbSpeed;
597 
598  dUsbExit();
599 
600  pUsbSpeed = &UsbSpeedDefault;
601 
602  for (i = 0; i < NPAGES * PAGE_SIZE; i+= PAGE_SIZE)
603  {
604  ClearPageReserved(virt_to_page(((unsigned long)pTemp) + i));
605 
606  //#define DEBUG
607  #undef DEBUG
608  #ifdef DEBUG
609  printk(" %s memory page %d unmapped\n",DEVICE1_NAME,i);
610  #endif
611  }
612 
613  kfree(kmalloc_ptr);
614 
615  misc_deregister(&Device1);
616 
617  //#define DEBUG
618  #undef DEBUG
619  #ifdef DEBUG
620  printk(" %s device unregistered\n",DEVICE1_NAME);
621  #endif
622 }
623 
624 
625 // MODULE *********************************************************************
626 
627 char *HostStr; // Used for HostName - or NOT used at all
628 char *SerialStr; // Used for Serial number (I.e. BT number)
629 
630 module_param (HostStr, charp, 0);
631 module_param (SerialStr, charp, 0);
632 
633 static int ModuleInit(void)
634 {
635 
636  //#define DEBUG
637  #undef DEBUG
638  #ifdef DEBUG
639  printk("%s Module init started\r\n",MODULE_NAME);
640  #endif
641 
642  //#define DEBUG
643  #undef DEBUG
644  #ifdef DEBUG
645  printk("This is DEFAULT NAME: %s\n\r", longname);
646  #endif
647 
648  //#define DEBUG
649  #undef DEBUG
650  #ifdef DEBUG
651  printk("\n\rThis is the HostStr: %s\n\r", HostStr);
652  #endif
653 
654  strcpy(longname, HostStr);
655 
656  //#define DEBUG
657  #undef DEBUG
658  #ifdef DEBUG
659  printk("\n\rThis is the INSMODed NAME: %s\n\r", longname);
660  #endif
661 
662  //#define DEBUG
663  #undef DEBUG
664  #ifdef DEBUG
665  printk("\n\rThis is the DEFAULT SerialNumber: %s\n\r", serial);
666  #endif
667 
668  //#define DEBUG
669  #undef DEBUG
670  #ifdef DEBUG
671  printk("\n\rThis is the SerialStr: %s\n\r", SerialStr);
672  #endif
673 
674  strcpy(serial, SerialStr);
675 
676  //#define DEBUG
677  #undef DEBUG
678  #ifdef DEBUG
679  printk("\n\rThis is the INSMODed SerialNumber (BT mac): %s\n\r", serial);
680  #endif
681 
682  Device1Init();
683 
684  return (0);
685 }
686 
687 static void ModuleExit(void)
688 {
689  //#define DEBUG
690  #undef DEBUG
691  #ifdef DEBUG
692  printk("%s exit started\n",MODULE_NAME);
693  #endif
694 
695  Device1Exit();
696 
697 }
698 
int usb_string_id(struct usb_composite_dev *cdev)
Definition: computil.c:819
unsigned autoresume
Definition: d_usbdev.c:157
int usb_char_out_length
Definition: d_usbdev.c:109
MODULE_PARM_DESC(autoresume,"zero, or seconds before remote wakeup")
char * SerialStr
Definition: d_usbdev.c:628
char usb_full_buffer_out[MAX_FULLSPEED_EP_SIZE]
Definition: d_usbdev.c:108
#define DRIVER_VENDOR_NUM
Definition: d_usbdev.c:148
#define DEVICE1_NAME
Definition: d_usbdev.c:48
unsigned buflen
Definition: d_usbdev.c:103
struct usb_request * save_in_req
Definition: usb_function.c:56
#define STRING_MANUFACTURER_IDX
Definition: d_usbdev.c:202
MODULE_AUTHOR("The LEGO Group")
#define STRING_SERIAL_IDX
Definition: d_usbdev.c:204
struct usb_ep * save_in_ep
Definition: usb_function.c:55
MODULE_LICENSE("GPL")
#define NPAGES
Definition: d_usbdev.c:112
int rudolf_add(struct usb_composite_dev *cdev, bool autoresume)
Definition: usb_function.c:702
module_param(buflen, uint, 0)
int usb_composite_register(struct usb_composite_driver *driver)
Definition: computil.c:1343
USB_SPEED UsbSpeed
Definition: computil.c:44
#define MODULE_NAME
Definition: d_usbdev.c:47
MODULE_DESCRIPTION(MODULE_NAME)
void usb_composite_unregister(struct usb_composite_driver *driver)
Definition: computil.c:1364
#define MAX_EP_SIZE
Definition: d_usbdev.c:101
void disable_endpoints(struct usb_composite_dev *cdev, struct usb_ep *in, struct usb_ep *out)
Definition: d_usbdev.c:264
int BytesWritten
Definition: c_daisy.c:67
void free_ep_req(struct usb_ep *ep, struct usb_request *req)
Definition: d_usbdev.c:245
struct usb_request * alloc_ep_req(struct usb_ep *ep)
Definition: d_usbdev.c:229
#define DEFAULT_AUTORESUME
Definition: d_usbdev.c:150
#define STRING_PRODUCT_IDX
Definition: d_usbdev.c:203
MODULE_SUPPORTED_DEVICE(DEVICE1_NAME)
module_init(ModuleInit)
unsigned short UWORD
Basic Type used to symbolise 16 bit unsigned values.
Definition: lmstypes.h:30
char Buffer[1024]
Definition: c_wifi.c:102
int usb_char_in_length
Definition: d_usbdev.c:106
#define DRIVER_PRODUCT_NUM
Definition: d_usbdev.c:149
int input_state
Definition: usb_function.c:54
char usb_full_buffer_in[MAX_FULLSPEED_EP_SIZE]
Definition: d_usbdev.c:105
char * HostStr
Definition: d_usbdev.c:627
USB_SPEED * pUsbSpeed
Definition: c_daisy.c:102
char usb_char_buffer_out[MAX_EP_SIZE]
Definition: d_usbdev.c:107
char usb_char_buffer_in[MAX_EP_SIZE]
Definition: d_usbdev.c:104
#define MAX_FULLSPEED_EP_SIZE
Definition: d_usbdev.c:102
#define NULL
module_exit(ModuleExit)