Subversion Repositories Kolibri OS

Rev

Rev 1616 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1029 serge 1
 
2
#define UHCI_USBLEGSUP_DEFAULT  0x2000  /* only PIRQ enable set */
1605 serge 3
#define UHCI_USBLEGSUP_RWC      0x8f00  /* the R/WC bits */
4
#define UHCI_USBLEGSUP_RO       0x5040  /* R/O and reserved bits */
5
6
 
7
 
1029 serge 8
#define UHCI_USBINTR                 4  /* interrupt register */
9
#define UHCI_USBCMD_RUN         0x0001  /* RUN/STOP bit */
10
#define UHCI_USBCMD_HCRESET     0x0002  /* Host Controller reset */
11
#define UHCI_USBCMD_EGSM        0x0008  /* Global Suspend Mode */
12
#define UHCI_USBCMD_CONFIGURE   0x0040  /* Config Flag */
13
#define UHCI_USBINTR_RESUME     0x0002  /* Resume interrupt enable */
14
15
 
16
 
17
#define  USBCMD_RS              0x0001  /* Run/Stop */
18
#define  USBCMD_HCRESET         0x0002  /* Host reset */
19
#define  USBCMD_GRESET          0x0004  /* Global reset */
20
#define  USBCMD_EGSM            0x0008  /* Global Suspend Mode */
21
#define  USBCMD_FGR             0x0010  /* Force Global Resume */
22
#define  USBCMD_SWDBG           0x0020  /* SW Debug mode */
23
#define  USBCMD_CF              0x0040  /* Config Flag (sw only) */
24
#define  USBCMD_MAXP            0x0080  /* Max Packet (0 = 32, 1 = 64) */
25
26
 
27
#define   USBSTS_USBINT         0x0001  /* Interrupt due to IOC */
28
#define   USBSTS_ERROR          0x0002  /* Interrupt due to error */
29
#define   USBSTS_RD             0x0004  /* Resume Detect */
30
#define   USBSTS_HSE            0x0008  /* Host System Error: PCI problems */
31
#define   USBSTS_HCPE           0x0010  /* Host Controller Process Error:
32
                                         * the schedule is buggy */
33
#define   USBSTS_HCH            0x0020  /* HC Halted */
34
35
 
36
 
37
#define  USBFLBASEADD                8
38
#define  USBSOF                     12
39
#define  USBSOF_DEFAULT             64  /* Frame length is exactly 1 ms */
40
41
 
42
#define  USBPORTSC2                 18
43
44
 
45
46
 
47
 
48
 * Make sure the controller is completely inactive, unable to
49
 * generate interrupts or do DMA.
50
 */
51
void uhci_reset_hc(hc_t *hc)
52
{
53
	/* Turn off PIRQ enable and SMI enable.  (This also turns off the
54
	 * BIOS's USB Legacy Support.)  Turn off all the R/WC bits too.
55
	 */
56
    pciWriteWord(hc->PciTag, UHCI_USBLEGSUP, UHCI_USBLEGSUP_RWC);
57
58
 
59
	 * new notification of any already connected
60
	 * ports due to the virtual disconnect that it
61
	 * implies.
62
	 */
63
    out16(hc->iobase + UHCI_USBCMD, UHCI_USBCMD_HCRESET);
64
    __asm__ __volatile__ ("":::"memory");
65
66
 
67
68
 
69
        dbgprintf("HCRESET not completed yet!\n");
70
71
 
72
	 * make sure the controller is stopped.
73
	 */
74
    out16(hc->iobase + UHCI_USBINTR, 0);
75
    out16(hc->iobase + UHCI_USBCMD, 0);
76
};
77
78
 
79
{
80
    u16_t legsup;
81
	unsigned int cmd, intr;
82
83
 
84
	 * When restarting a suspended controller, we expect all the
85
	 * settings to be the same as we left them:
86
	 *
87
	 *	PIRQ and SMI disabled, no R/W bits set in USBLEGSUP;
88
	 *	Controller is stopped and configured with EGSM set;
89
	 *	No interrupts enabled except possibly Resume Detect.
90
	 *
91
	 * If any of these conditions are violated we do a complete reset.
92
	 */
93
    legsup = pciReadWord(hc->PciTag, UHCI_USBLEGSUP);
94
	if (legsup & ~(UHCI_USBLEGSUP_RO | UHCI_USBLEGSUP_RWC)) {
95
        dbgprintf("%s: legsup = 0x%04x\n",__FUNCTION__, legsup);
96
		goto reset_needed;
97
	}
98
99
 
100
    if ( (cmd & UHCI_USBCMD_RUN) ||
101
        !(cmd & UHCI_USBCMD_CONFIGURE) ||
102
        !(cmd & UHCI_USBCMD_EGSM))
103
    {
104
        dbgprintf("%s: cmd = 0x%04x\n", __FUNCTION__, cmd);
105
		goto reset_needed;
106
	}
107
108
 
109
    if (intr & (~UHCI_USBINTR_RESUME))
110
    {
111
        dbgprintf("%s: intr = 0x%04x\n", __FUNCTION__, intr);
112
		goto reset_needed;
113
	}
114
	return 0;
115
116
 
117
    dbgprintf("Performing full reset\n");
118
    uhci_reset_hc(hc);
119
	return 1;
120
}
121
122
 
1605 serge 123
{
124
    hc_t   *hc;
125
1029 serge 126
 
1613 serge 127
1605 serge 128
 
129
130
 
131
    {
132
        hc_t       *htmp;
1613 serge 133
        request_t  *rq;
134
        u16_t  status;
1605 serge 135
136
 
1613 serge 137
138
 
1605 serge 139
140
 
1613 serge 141
        if (!(status & ~USBSTS_HCH))            /* shared interrupt, not mine */
1605 serge 142
            continue;
143
        out16(htmp->iobase + USBSTS, status);     /* Clear it */
1613 serge 144
145
 
146
147
 
148
        {
149
            request_t *rtmp;
150
            td_t      *td;
151
152
 
153
            rq = (request_t*)rq->list.next;
154
155
 
156
157
 
158
                continue;
159
160
 
161
162
 
163
        };
164
    }
1605 serge 165
};
166
167
 
168
 
169
 
1600 serge 170
{
1029 serge 171
    int    port;
1600 serge 172
    u32_t  ifl;
173
    u16_t  dev_status;
174
    td_t   *td;
1605 serge 175
    int i;
1029 serge 176
177
 
178
179
 
180
    {
181
        if(hc->ioBase[i]){
182
           hc->iobase = hc->ioBase[i];
183
       //    dbgprintf("Io base_%d 0x%x\n", i,hc->ioBase[i]);
184
           break;
185
        };
186
    };
187
188
 
189
	 * they may have more but gives no way to determine how many there
190
	 * are.  However according to the UHCI spec, Bit 7 of the port
191
	 * status and control register is always set to 1.  So we try to
192
	 * use this to our advantage.  Another common failure mode when
193
	 * a nonexistent register is addressed is to return all ones, so
194
	 * we test for that also.
195
	 */
196
    for (port = 0; port < 2; port++)
197
    {
198
        u32_t status;
199
200
 
201
        dbgprintf("port%d status %x\n", port, status);
202
        if (!(status & 0x0080) || status == 0xffff)
203
			break;
204
	}
205
    dbgprintf("detected %d ports\n\n", port);
206
207
 
208
209
 
210
	 * isn't already safely quiescent.
211
	 */
212
    uhci_check_and_reset_hc(hc);
213
214
 
215
    hc->frame_dma    = GetPgAddr(hc->frame_base);
216
    hc->frame_number = 0;
217
218
 
1616 serge 219
                                  sizeof(td_t), 16, 0);
220
    if (!hc->td_pool)
221
    {
222
        dbgprintf("unable to create td dma_pool\n");
223
        goto err_create_td_pool;
224
    }
225
1605 serge 226
 
227
    {
228
    qh_t *qh = alloc_qh();
1029 serge 229
230
 
231
    qh->qelem = 1;
232
233
 
1605 serge 234
    }
235
    for (i = SKEL_ISO + 1; i < SKEL_ASYNC; ++i)
236
        hc->qh[i]->qlink = hc->qh[SKEL_ASYNC]->dma | 2;
237
1029 serge 238
 
1605 serge 239
    {
240
        int qnum;
241
1029 serge 242
 
1605 serge 243
244
 
245
            qnum = 9;
246
247
 
248
    }
249
250
 
251
252
 
1029 serge 253
    out8(hc->iobase + USBSOF, USBSOF_DEFAULT);
254
255
 
256
    out32(hc->iobase + USBFLBASEADD, hc->frame_dma);
257
258
 
259
    out16(hc->iobase + USBFRNUM, 0);
260
261
 
262
1605 serge 263
 
264
265
 
266
267
 
268
269
 
1029 serge 270
                               USBCMD_MAXP);
271
272
 
273
        out16(hc->iobase + USBPORTSC1 + (port * 2), 0x200);
274
275
 
276
    {
277
        time_t timeout;
278
279
 
1875 serge 280
281
 
1029 serge 282
        dbgprintf("port%d status %x\n", port, status);
283
284
 
285
286
 
287
        while(timeout--)
288
        {
289
            delay(10/10);
290
            status = in16(hc->iobase + USBPORTSC1 + (port * 2));
291
            if(status & 1)
292
            {
293
                udev_t *dev = kmalloc(sizeof(udev_t),0);
1600 serge 294
1029 serge 295
 
296
297
 
298
299
 
300
                status = in16(hc->iobase + USBPORTSC1 + (port * 2));
301
                dbgprintf("port%d status %x\n", port, status);
302
303
 
1600 serge 304
305
 
1029 serge 306
                dev->port     = port;
307
                dev->ep0_size = 8;
308
                dev->status   = status;
309
310
 
311
                if(status & 4)
312
                    dbgprintf(" enabled");
313
                else
314
                    dbgprintf(" disabled");
315
                if(status & 0x100){
316
                    dev->speed = 0x4000000;
317
                    dbgprintf(" low speed\n");
318
                } else {
319
                    dev->speed = 0;
320
                    dbgprintf(" full speed\n");
321
                };
322
323
 
324
                    list_add_tail(&dev->list, &newdev_list);
1600 serge 325
                    hc->port_map |= 1<
1029 serge 326
                }
327
                else {
328
                    free(dev);
329
                    out16(hc->iobase + USBPORTSC1 + (port * 2), 0);
330
                }
331
                break;
332
            };
333
        };
334
    };
335
    return true;
1600 serge 336
1616 serge 337
 
338
339
 
340
341
 
342
};
1029 serge 343
344
 
345
      req_descr[4]  = {0x0680,0x0100,0x0000,8};
346
347
 
348
IN(69) OUT(E1) SETUP(2D)
349
SETUP(0) IN(1)
350
SETUP(0) OUT(1) OUT(0) OUT(1)...IN(1)
351
SETUP(0) IN(1) IN(0) IN(1)...OUT(0)
352
*/
353
354
 
355
 
1600 serge 356
{
1029 serge 357
    static  udev_id   = 0;
358
    static  udev_addr = 0;
359
    static  u16_t __attribute__((aligned(16)))
360
            req_addr[4] = {0x0500,0x0001,0x0000,0x0000};
361
362
 
363
            req_descr[4]  = {0x0680,0x0100,0x0000,8};
364
365
 
366
367
 
368
    td_t  *td0, *td1, *td2;
369
    u32_t   dev_status;
370
    count_t timeout;
371
    int address;
372
373
 
374
375
 
376
377
 
378
        return false;
1600 serge 379
1029 serge 380
 
381
    dev->id   = (++udev_id << 8) | address;
382
383
 
384
385
 
386
    data[1] = 0;
387
388
 
389
        return false;
1600 serge 390
1029 serge 391
 
392
    dev->ep0_size = descr->bMaxPacketSize0;
393
394
 
1600 serge 395
}
1029 serge 396
397
 
1875 serge 398
399
 
400
401
 
402
                           size_t data_size)
403
{
1029 serge 404
    size_t  packet_size = dev->ep0_size;
1875 serge 405
    int     dsize = data_size;
406
    size_t  buf_size;
407
408
 
409
    addr_t  td_dma;
1616 serge 410
    addr_t  data_dma;
1875 serge 411
1029 serge 412
 
1875 serge 413
1029 serge 414
 
1875 serge 415
    int td_count = 0;
416
417
 
418
    {
419
        td_count++;
420
        dsize-= packet_size;
421
    };
422
423
 
424
               td_count*sizeof(td_t);
425
426
 
427
    memset(rq, 0, buf_size);
428
429
 
430
    td_dma = data_dma + ALIGN16(data_size);
431
432
 
1600 serge 433
1029 serge 434
 
1875 serge 435
    td = MakePtr(td_t*, rq->data, ALIGN16(data_size));
436
    rq->td_head = td;
437
    rq->size = data_size;
438
    rq->dev  = dev;
1600 serge 439
1029 serge 440
 
441
442
 
1875 serge 443
444
 
445
    {
1029 serge 446
        if ( dsize < packet_size)
1875 serge 447
        {
1600 serge 448
            packet_size = dsize;
1875 serge 449
        };
1600 serge 450
451
 
1616 serge 452
453
 
1600 serge 454
1029 serge 455
 
456
            td_prev->link   = td->dma | 4;
457
        td->status = TD_CTRL_ACTIVE | dev->speed;
1605 serge 458
        td->token  = TOKEN(packet_size,enp->toggle,enp->address,
1600 serge 459
                           dev->addr,dir);
1029 serge 460
        td->buffer = data_dma;
461
        td->bk     = td_prev;
462
463
 
464
465
 
1875 serge 466
        td_dma+= sizeof(td_t);
467
        data_dma+= packet_size;
1600 serge 468
1875 serge 469
 
470
        enp->toggle ^= DATA1;
1029 serge 471
    };
1605 serge 472
473
 
1875 serge 474
    rq->td_tail = td_prev;
475
1613 serge 476
 
477
478
 
479
        printf("%s: epic fail\n", __FUNCTION__);
480
481
 
482
    rq->event.data[0] = (addr_t)rq;
483
484
 
1029 serge 485
}
486
487
 
1600 serge 488
                  void *data, size_t req_size)
1029 serge 489
{
490
    size_t  packet_size = dev->ep0_size;
491
    size_t  size = req_size;
492
    u32_t   toggle = DATA1;
493
494
 
495
    qh_t   *qh;
496
    addr_t  data_dma = 0;
497
    hc_t   *hc = dev->host;
1616 serge 498
499
 
500
501
 
1600 serge 502
1029 serge 503
 
1613 serge 504
 
505
506
 
507
508
 
509
    rq->size = req_size;
510
    rq->dev  = dev;
511
512
 
1616 serge 513
    td0->dma = td_dma;
514
1029 serge 515
 
1875 serge 516
1616 serge 517
 
1029 serge 518
    td0->token  = TOKEN( 8, DATA0, 0, dev->addr, 0x2D);
519
    td0->buffer = DMA(req);
520
    td0->bk     = NULL;
521
522
 
523
        data_dma = DMA(data);
524
525
 
526
527
 
1600 serge 528
    {
1029 serge 529
        if ( size < packet_size)
1600 serge 530
        {
531
            packet_size = size;
532
        };
533
534
 
1616 serge 535
        td->dma = td_dma;
536
537
 
1875 serge 538
1616 serge 539
 
1029 serge 540
        td->status = TD_CTRL_ACTIVE | dev->speed;
1605 serge 541
        td->token  = TOKEN(packet_size, toggle, 0,dev->addr, pid);
1029 serge 542
        td->buffer = data_dma;
543
        td->bk     = td_prev;
544
545
 
546
547
 
548
        size-= packet_size;
549
        toggle ^= DATA1;
550
    }
551
552
 
1616 serge 553
    td->dma = td_dma;
554
555
 
1875 serge 556
1616 serge 557
 
1029 serge 558
559
 
560
561
 
562
    td->status = TD_CTRL_ACTIVE | TD_CTRL_IOC | dev->speed ;
1605 serge 563
    td->token  = (0x7FF<<21)|DATA1|(dev->addr<<8)|pid;
1029 serge 564
    td->buffer = 0;
565
    td->bk     = td_prev;
566
567
 
1613 serge 568
    rq->td_tail = td;
569
570
 
571
572
 
573
        printf("%s: epic fail\n", __FUNCTION__);
574
575
 
576
    rq->event.data[0] = (addr_t)rq;
577
578
 
579
580
 
1875 serge 581
1613 serge 582
 
1605 serge 583
1029 serge 584
 
585
586
 
1605 serge 587
588
 
1613 serge 589
1029 serge 590
 
1613 serge 591
592
 
593
    dbgprintf("td  status 0x%0x\n", td->status);
594
595
 
1029 serge 596
        (td_prev->status & TD_ANY_ERROR) ||
597
        (td->status & TD_ANY_ERROR))
598
    {
599
        u32_t dev_status = in16(dev->host->iobase + USBSTS);
600
601
 
602
                   in16(dev->host->iobase + USBFRNUM),
603
                   in16(dev->host->iobase + USBCMD),
604
                    dev_status);
605
        dbgprintf("td0 status %x\n",td0->status);
606
        dbgprintf("td_prev status %x\n",td_prev->status);
607
        dbgprintf("td status %x\n",td->status);
608
        dbgprintf("qh %x \n", qh->qelem);
609
610
 
1600 serge 611
    } else retval = true;
612
1029 serge 613
 
1613 serge 614
615
 
616
617
 
1029 serge 618
    {
619
        td_prev = td->bk;
620
        dma_pool_free(hc->td_pool, td, td->dma);
1616 serge 621
        td = td_prev;
1029 serge 622
    }while( td != NULL);
623
624
 
1613 serge 625
    delete event;
626
*/
627
    kfree(rq);
628
629
 
1029 serge 630
};
631
632
 
633
 
1600 serge 634
{
1029 serge 635
    static  u16_t __attribute__((aligned(16)))
636
            req_descr[4]  = {0x0680,0x0100,0x0000,18};
637
638
 
639
            req_conf[4]  = {0x0680,0x0200,0x0000,9};
640
641
 
642
643
 
644
645
 
646
647
 
648
    conf_descr_t      *conf;
649
650
 
651
               dev->id, dev->host->pciId, dev->port);
652
653
 
654
    {
1613 serge 655
        dbgprintf("%s epic fail\n",__FUNCTION__);
656
        return;
1029 serge 657
    };
1613 serge 658
1029 serge 659
 
660
661
 
662
              "bLength             %d\n"
663
              "bDescriptorType     %d\n"
664
              "bcdUSB              %x\n"
665
              "bDeviceClass        %x\n"
666
              "bDeviceSubClass     %x\n"
667
              "bDeviceProtocol     %x\n"
668
              "bMaxPacketSize0     %d\n"
669
              "idVendor            %x\n"
670
              "idProduct           %x\n"
671
              "bcdDevice           %x\n"
672
              "iManufacturer       %x\n"
673
              "iProduct            %x\n"
674
              "iSerialNumber       %x\n"
675
              "bNumConfigurations  %d\n\n",
676
              descr.bLength, descr.bDescriptorType,
677
              descr.bcdUSB,  descr.bDeviceClass,
678
              descr.bDeviceSubClass, descr.bDeviceProtocol,
679
              descr.bMaxPacketSize0, descr.idVendor,
680
              descr.idProduct, descr.bcdDevice,
681
              descr.iManufacturer, descr.iProduct,
682
              descr.iSerialNumber, descr.bNumConfigurations);
683
684
 
685
    if( !ctrl_request(dev, req_conf, DIN, &data, 8))
686
        return;
687
688
 
689
690
 
691
692
 
693
    conf = malloc(conf_size);
694
695
 
696
        return;
697
698
 
699
    dptr+= conf->bLength;
700
701
 
702
              "bLength             %d\n"
703
              "bDescriptorType     %d\n"
704
              "wTotalLength        %d\n"
705
              "bNumInterfaces      %d\n"
706
              "bConfigurationValue %x\n"
707
              "iConfiguration      %d\n"
708
              "bmAttributes        %x\n"
709
              "bMaxPower           %dmA\n\n",
710
              conf->bLength,
711
              conf->bDescriptorType,
712
              conf->wTotalLength,
713
              conf->bNumInterfaces,
714
              conf->bConfigurationValue,
715
              conf->iConfiguration,
716
              conf->bmAttributes,
717
              conf->bMaxPower*2);
718
719
 
720
721
 
722
        {
723
            case USB_CLASS_AUDIO:
724
                dbgprintf( "audio device\n");
725
                break;
726
            case USB_CLASS_HID:
727
                dev->conf = conf;
728
                list_del(&dev->list);
1600 serge 729
                return init_hid(dev);
1029 serge 730
731
 
732
                dbgprintf("printer\n");
733
                break;
734
            case USB_CLASS_MASS_STORAGE:
735
                dbgprintf("mass storage device\n");
736
                break;
737
            case USB_CLASS_HUB:
738
                dbgprintf("hub device\n");
739
                break;
740
            default:
741
                dbgprintf("unknown device\n");
742
        };
743
};
744
>