Subversion Repositories Kolibri OS

Rev

Rev 1613 | 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
    td = alloc_td();
240
1029 serge 241
 
1605 serge 242
    td->status =  (1<<24) | (1<<23) ;
243
    td->token  = TOKEN( 0x7FF, DATA0, 0, 0, 0xE1);
244
    td->buffer = 0;
245
    td->bk     = NULL;
246
*/
247
1029 serge 248
 
1605 serge 249
    {
250
        int qnum;
251
1029 serge 252
 
1605 serge 253
254
 
255
            qnum = 9;
256
257
 
258
    }
259
260
 
261
262
 
1029 serge 263
    out8(hc->iobase + USBSOF, USBSOF_DEFAULT);
264
265
 
266
    out32(hc->iobase + USBFLBASEADD, hc->frame_dma);
267
268
 
269
    out16(hc->iobase + USBFRNUM, 0);
270
271
 
272
1605 serge 273
 
274
275
 
276
277
 
278
279
 
1029 serge 280
                               USBCMD_MAXP);
281
282
 
283
        out16(hc->iobase + USBPORTSC1 + (port * 2), 0x200);
284
    delay(100/10);
285
286
 
287
    {
288
        time_t timeout;
289
290
 
291
        dbgprintf("port%d status %x\n", port, status);
292
293
 
294
295
 
296
        while(timeout--)
297
        {
298
            delay(10/10);
299
            status = in16(hc->iobase + USBPORTSC1 + (port * 2));
300
            if(status & 1)
301
            {
302
                udev_t *dev = kmalloc(sizeof(udev_t),0);
1600 serge 303
1029 serge 304
 
305
306
 
307
308
 
309
                status = in16(hc->iobase + USBPORTSC1 + (port * 2));
310
                dbgprintf("port%d status %x\n", port, status);
311
312
 
1600 serge 313
314
 
1029 serge 315
                dev->port     = port;
316
                dev->ep0_size = 8;
317
                dev->status   = status;
318
319
 
320
                if(status & 4)
321
                    dbgprintf(" enabled");
322
                else
323
                    dbgprintf(" disabled");
324
                if(status & 0x100){
325
                    dev->speed = 0x4000000;
326
                    dbgprintf(" low speed\n");
327
                } else {
328
                    dev->speed = 0;
329
                    dbgprintf(" full speed\n");
330
                };
331
332
 
333
                    list_add_tail(&dev->list, &newdev_list);
1600 serge 334
                    hc->port_map |= 1<
1029 serge 335
                }
336
                else {
337
                    free(dev);
338
                    out16(hc->iobase + USBPORTSC1 + (port * 2), 0);
339
                }
340
                break;
341
            };
342
        };
343
    };
344
    return true;
1600 serge 345
1616 serge 346
 
347
348
 
349
350
 
351
};
1029 serge 352
353
 
354
      req_descr[4]  = {0x0680,0x0100,0x0000,8};
355
356
 
357
IN(69) OUT(E1) SETUP(2D)
358
SETUP(0) IN(1)
359
SETUP(0) OUT(1) OUT(0) OUT(1)...IN(1)
360
SETUP(0) IN(1) IN(0) IN(1)...OUT(0)
361
*/
362
363
 
364
 
1600 serge 365
{
1029 serge 366
    static  udev_id   = 0;
367
    static  udev_addr = 0;
368
    static  u16_t __attribute__((aligned(16)))
369
            req_addr[4] = {0x0500,0x0001,0x0000,0x0000};
370
371
 
372
            req_descr[4]  = {0x0680,0x0100,0x0000,8};
373
374
 
375
376
 
377
    td_t  *td0, *td1, *td2;
378
    u32_t   dev_status;
379
    count_t timeout;
380
    int address;
381
382
 
383
384
 
385
386
 
387
        return false;
1600 serge 388
1029 serge 389
 
390
    dev->id   = (++udev_id << 8) | address;
391
392
 
393
394
 
395
    data[1] = 0;
396
397
 
398
        return false;
1600 serge 399
1029 serge 400
 
401
    dev->ep0_size = descr->bMaxPacketSize0;
402
403
 
1600 serge 404
}
1029 serge 405
406
 
407
                          void *data, size_t req_size)
408
{
409
    td_t  *td, *td_prev;
410
    addr_t data_dma;
411
    hc_t     *hc = dev->host;
1616 serge 412
    size_t  packet_size = enp->size;
1600 serge 413
    size_t  size = req_size;
414
    addr_t  td_dma;
1616 serge 415
1029 serge 416
 
1600 serge 417
1029 serge 418
 
1600 serge 419
1029 serge 420
 
421
    rq->size = req_size;
422
    rq->dev  = dev;
1600 serge 423
1029 serge 424
 
425
        data_dma = DMA(data);
426
427
 
428
429
 
1600 serge 430
    {
1029 serge 431
        if ( size < packet_size)
1600 serge 432
        {
433
            packet_size = size;
434
        };
435
436
 
1616 serge 437
        td->dma = td_dma;
438
439
 
1600 serge 440
1029 serge 441
 
442
            rq->td_head = td;
443
444
 
445
            td_prev->link   = td->dma | 4;
446
        td->status = TD_CTRL_ACTIVE | dev->speed;
1605 serge 447
        td->token  = TOKEN(packet_size,enp->toggle,enp->address,
1600 serge 448
                           dev->addr,dir);
1029 serge 449
        td->buffer = data_dma;
450
        td->bk     = td_prev;
451
452
 
453
454
 
1600 serge 455
        size-= packet_size;
456
        enp->toggle ^= DATA1;
1029 serge 457
    };
1605 serge 458
459
 
460
    rq->td_tail = td;
1029 serge 461
1613 serge 462
 
463
464
 
465
        printf("%s: epic fail\n", __FUNCTION__);
466
467
 
468
    rq->event.data[0] = (addr_t)rq;
469
470
 
1029 serge 471
}
472
473
 
1600 serge 474
                  void *data, size_t req_size)
1029 serge 475
{
476
    size_t  packet_size = dev->ep0_size;
477
    size_t  size = req_size;
478
    u32_t   toggle = DATA1;
479
480
 
481
    qh_t   *qh;
482
    addr_t  data_dma = 0;
483
    hc_t   *hc = dev->host;
1616 serge 484
485
 
486
487
 
1600 serge 488
1029 serge 489
 
1613 serge 490
 
491
492
 
493
494
 
495
    rq->size = req_size;
496
    rq->dev  = dev;
497
498
 
1616 serge 499
    td0->dma = td_dma;
500
1029 serge 501
 
1616 serge 502
503
 
1029 serge 504
    td0->token  = TOKEN( 8, DATA0, 0, dev->addr, 0x2D);
505
    td0->buffer = DMA(req);
506
    td0->bk     = NULL;
507
508
 
509
        data_dma = DMA(data);
510
511
 
512
513
 
1600 serge 514
    {
1029 serge 515
        if ( size < packet_size)
1600 serge 516
        {
517
            packet_size = size;
518
        };
519
520
 
1616 serge 521
        td->dma = td_dma;
522
523
 
524
525
 
1029 serge 526
        td->status = TD_CTRL_ACTIVE | dev->speed;
1605 serge 527
        td->token  = TOKEN(packet_size, toggle, 0,dev->addr, pid);
1029 serge 528
        td->buffer = data_dma;
529
        td->bk     = td_prev;
530
531
 
532
533
 
534
        size-= packet_size;
535
        toggle ^= DATA1;
536
    }
537
538
 
1616 serge 539
    td->dma = td_dma;
540
541
 
542
543
 
1029 serge 544
545
 
546
547
 
548
    td->status = TD_CTRL_ACTIVE | TD_CTRL_IOC | dev->speed ;
1605 serge 549
    td->token  = (0x7FF<<21)|DATA1|(dev->addr<<8)|pid;
1029 serge 550
    td->buffer = 0;
551
    td->bk     = td_prev;
552
553
 
1613 serge 554
    rq->td_tail = td;
555
556
 
557
558
 
559
        printf("%s: epic fail\n", __FUNCTION__);
560
561
 
562
    rq->event.data[0] = (addr_t)rq;
563
564
 
565
566
 
567
568
 
1605 serge 569
1029 serge 570
 
571
572
 
1605 serge 573
574
 
1613 serge 575
1029 serge 576
 
1613 serge 577
578
 
579
    dbgprintf("td  status 0x%0x\n", td->status);
580
581
 
1029 serge 582
        (td_prev->status & TD_ANY_ERROR) ||
583
        (td->status & TD_ANY_ERROR))
584
    {
585
        u32_t dev_status = in16(dev->host->iobase + USBSTS);
586
587
 
588
                   in16(dev->host->iobase + USBFRNUM),
589
                   in16(dev->host->iobase + USBCMD),
590
                    dev_status);
591
        dbgprintf("td0 status %x\n",td0->status);
592
        dbgprintf("td_prev status %x\n",td_prev->status);
593
        dbgprintf("td status %x\n",td->status);
594
        dbgprintf("qh %x \n", qh->qelem);
595
596
 
1600 serge 597
    } else retval = true;
598
1029 serge 599
 
1613 serge 600
601
 
602
603
 
1029 serge 604
    {
605
        td_prev = td->bk;
606
        dma_pool_free(hc->td_pool, td, td->dma);
1616 serge 607
        td = td_prev;
1029 serge 608
    }while( td != NULL);
609
610
 
1613 serge 611
    delete event;
612
*/
613
    kfree(rq);
614
615
 
1029 serge 616
};
617
618
 
619
 
1600 serge 620
{
1029 serge 621
    static  u16_t __attribute__((aligned(16)))
622
            req_descr[4]  = {0x0680,0x0100,0x0000,18};
623
624
 
625
            req_conf[4]  = {0x0680,0x0200,0x0000,9};
626
627
 
628
629
 
630
631
 
632
633
 
634
    conf_descr_t      *conf;
635
636
 
637
               dev->id, dev->host->pciId, dev->port);
638
639
 
640
    {
1613 serge 641
        dbgprintf("%s epic fail\n",__FUNCTION__);
642
        return;
1029 serge 643
    };
1613 serge 644
1029 serge 645
 
646
647
 
648
              "bLength             %d\n"
649
              "bDescriptorType     %d\n"
650
              "bcdUSB              %x\n"
651
              "bDeviceClass        %x\n"
652
              "bDeviceSubClass     %x\n"
653
              "bDeviceProtocol     %x\n"
654
              "bMaxPacketSize0     %d\n"
655
              "idVendor            %x\n"
656
              "idProduct           %x\n"
657
              "bcdDevice           %x\n"
658
              "iManufacturer       %x\n"
659
              "iProduct            %x\n"
660
              "iSerialNumber       %x\n"
661
              "bNumConfigurations  %d\n\n",
662
              descr.bLength, descr.bDescriptorType,
663
              descr.bcdUSB,  descr.bDeviceClass,
664
              descr.bDeviceSubClass, descr.bDeviceProtocol,
665
              descr.bMaxPacketSize0, descr.idVendor,
666
              descr.idProduct, descr.bcdDevice,
667
              descr.iManufacturer, descr.iProduct,
668
              descr.iSerialNumber, descr.bNumConfigurations);
669
670
 
671
    if( !ctrl_request(dev, req_conf, DIN, &data, 8))
672
        return;
673
674
 
675
676
 
677
678
 
679
    conf = malloc(conf_size);
680
681
 
682
        return;
683
684
 
685
    dptr+= conf->bLength;
686
687
 
688
              "bLength             %d\n"
689
              "bDescriptorType     %d\n"
690
              "wTotalLength        %d\n"
691
              "bNumInterfaces      %d\n"
692
              "bConfigurationValue %x\n"
693
              "iConfiguration      %d\n"
694
              "bmAttributes        %x\n"
695
              "bMaxPower           %dmA\n\n",
696
              conf->bLength,
697
              conf->bDescriptorType,
698
              conf->wTotalLength,
699
              conf->bNumInterfaces,
700
              conf->bConfigurationValue,
701
              conf->iConfiguration,
702
              conf->bmAttributes,
703
              conf->bMaxPower*2);
704
705
 
706
707
 
708
        {
709
            case USB_CLASS_AUDIO:
710
                dbgprintf( "audio device\n");
711
                break;
712
            case USB_CLASS_HID:
713
                dev->conf = conf;
714
                list_del(&dev->list);
1600 serge 715
                return init_hid(dev);
1029 serge 716
717
 
718
                dbgprintf("printer\n");
719
                break;
720
            case USB_CLASS_MASS_STORAGE:
721
                dbgprintf("mass storage device\n");
722
                break;
723
            case USB_CLASS_HUB:
724
                dbgprintf("hub device\n");
725
                break;
726
            default:
727
                dbgprintf("unknown device\n");
728
        };
729
};
730
>