Subversion Repositories Kolibri OS

Rev

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