Subversion Repositories Kolibri OS

Rev

Rev 1600 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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