Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1.  
  2.  
  3. #include "types.h"
  4. #include "link.h"
  5.  
  6. #include <stdio.h>
  7. #include <malloc.h>
  8. #include <memory.h>
  9.  
  10. #include "pci.h"
  11.  
  12. #include "syscall.h"
  13. #include "usb.h"
  14.  
  15. static Bool FindPciDevice();
  16.  
  17. int __stdcall srv_usb(ioctl_t *io);
  18.  
  19. Bool init_hc(hc_t *hc);
  20.  
  21. static slab_t   qh_slab;
  22. static slab_t   td_slab;
  23.  
  24. static link_t  hc_list;
  25. static link_t  newdev_list;
  26. static link_t  rq_list;
  27.  
  28. u32_t __stdcall drvEntry(int action)
  29. {
  30.     u32_t   retval;
  31.     hc_t   *hc;
  32.     udev_t *dev;
  33.  
  34.     int     i;
  35.  
  36.     if(action != 1)
  37.         return 0;
  38.  
  39.     if(!dbg_open("/rd/1/drivers/usb.log"))
  40.     {
  41.         printf("Can't open /rd/1/drivers/usb.log\nExit\n");
  42.         return 0;
  43.     }
  44.  
  45.     list_initialize(&hc_list);
  46.     list_initialize(&newdev_list);
  47.     list_initialize(&rq_list);
  48.  
  49.     if( !FindPciDevice() ) {
  50.         dbgprintf("no uhci devices found\n");
  51.         return 0;
  52.     };
  53.  
  54.      qh_slab.available = 256;
  55.      qh_slab.start     = KernelAlloc(4096);
  56.      qh_slab.nextavail = (addr_t)qh_slab.start;
  57.      qh_slab.dma       = GetPgAddr(qh_slab.start);
  58.  
  59.      qh_t    *p;
  60.      addr_t  dma;
  61.  
  62.      for (i = 0, p = (qh_t*)qh_slab.start, dma = qh_slab.dma;
  63.           i < 256; i++, p++, dma+= sizeof(qh_t))
  64.      {
  65.         p->qlink  = (addr_t)(p+1);
  66.         p->qelem  = 1;
  67.         p->dma    = dma;
  68.         p->r1     = 0;
  69.      };
  70.  
  71.      td_slab.available = 128;
  72.      td_slab.start     = KernelAlloc(4096);
  73.      td_slab.nextavail = (addr_t)td_slab.start;
  74.      td_slab.dma       = GetPgAddr(td_slab.start);
  75.  
  76.      td_t *td;
  77.      for (i = 0, td = (td_t*)td_slab.start, dma = td_slab.dma;
  78.           i < 128; i++, td++, dma+= sizeof(td_t))
  79.      {
  80.         td->link   = (addr_t)(td+1);
  81.         td->status = 0;
  82.         td->token  = 0;
  83.         td->buffer = 0;
  84.         td->dma    = dma;
  85.      };
  86.  
  87.  
  88.     hc = (hc_t*)hc_list.next;
  89.  
  90.     while( &hc->link != &hc_list)
  91.     {
  92.         init_hc(hc);
  93.         hc = (hc_t*)hc->link.next;
  94.     }
  95.  
  96.     dbgprintf("\n");
  97.  
  98.     dev = (udev_t*)newdev_list.next;
  99.     while( &dev->link != &newdev_list)
  100.     {
  101.         udev_t *tmp = dev;
  102.         dev = (udev_t*)dev->link.next;
  103.  
  104.         if(tmp->id != 0)
  105.             init_device(tmp);
  106.     }
  107.  
  108.     while(1)
  109.     {
  110.         udev_t    *dev;
  111.         request_t *rq;
  112.  
  113.         rq = (request_t*)rq_list.next;
  114.         while( &rq->link != &rq_list)
  115.         {
  116.             qh_t      *qh;
  117.             td_t      *td;
  118.  
  119.             td  = rq->td_head;
  120.             dev = rq->dev;
  121.             qh  = dev->host->qh1;
  122.  
  123.             qh->qelem = td->dma;
  124.  
  125.             __asm__ __volatile__ ("":::"memory");
  126.             rq = (request_t*)rq->link.next;
  127.         };
  128.  
  129.         delay(10/10);
  130.  
  131.         rq = (request_t*)rq_list.next;
  132.         while( &rq->link != &rq_list)
  133.         {
  134.             request_t *tmp;
  135.             td_t      *td;
  136.  
  137.             tmp = rq;
  138.             rq = (request_t*)rq->link.next;
  139.  
  140.             td  = tmp->td_head;
  141.  
  142.             if( td->status & TD_CTRL_ACTIVE)
  143.                 continue;
  144.  
  145.             tmp->handler(tmp->dev, tmp);
  146.         };
  147.     };
  148.  
  149.     retval = RegService("USB", srv_usb);
  150.     dbgprintf("reg service USB as: %x\n", retval);
  151.  
  152.     return retval;
  153. };
  154.  
  155.  
  156. #define API_VERSION     0x01000100
  157.  
  158. #define SRV_GETVERSION  0
  159.  
  160.  
  161. int __stdcall srv_usb(ioctl_t *io)
  162. {
  163.   u32_t *inp;
  164.   u32_t *outp;
  165.  
  166.   inp = io->input;
  167.   outp = io->output;
  168.  
  169.   switch(io->io_code)
  170.   {
  171.     case SRV_GETVERSION:
  172.       if(io->out_size==4)
  173.       {
  174.         *outp = API_VERSION;
  175.         return 0;
  176.       }
  177.       break;
  178.  
  179.  
  180.     default:
  181.       return ERR_PARAM;
  182.   };
  183.   return ERR_PARAM;
  184. }
  185.  
  186.  
  187. static qh_t* alloc_qh()
  188. {
  189.     if( qh_slab.available )
  190.     {
  191.         qh_t *qh;
  192.  
  193.         qh_slab.available--;
  194.         qh = (qh_t*)qh_slab.nextavail;
  195.         qh_slab.nextavail = qh->qlink;
  196.         return qh;
  197.      }
  198.      return NULL;
  199. };
  200.  
  201. static void  free_qh(qh_t *qh)
  202. {
  203.      qh->qlink = qh_slab.nextavail;
  204.      qh_slab.nextavail = (addr_t)qh;
  205.      qh_slab.available++;
  206. };
  207.  
  208. static td_t* alloc_td()
  209. {
  210.     if( td_slab.available )
  211.     {
  212.         td_t *td;
  213.  
  214.         td_slab.available--;
  215.         td = (td_t*)td_slab.nextavail;
  216.         td_slab.nextavail = td->link;
  217.         return td;
  218.      }
  219.      return NULL;
  220. };
  221.  
  222. static void  free_td(td_t *td)
  223. {
  224.      td->link = td_slab.nextavail;
  225.      td_slab.nextavail = (addr_t)td;
  226.      td_slab.available++;
  227. };
  228.  
  229. #include "pci.inc"
  230. #include "detect.inc"
  231. #include "hcd.inc"
  232. #include "hid.inc"
  233.