Subversion Repositories Kolibri OS

Rev

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

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