Subversion Repositories Kolibri OS

Rev

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