Subversion Repositories Kolibri OS

Rev

Rev 2434 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
557 serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2465 Serge 3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
557 serge 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
8
;driver sceletone
9
 
10
format MS COFF
11
 
12
API_VERSION     equ 0  ;debug
13
 
14
include '../proc32.inc'
15
include '../imports.inc'
572 serge 16
include 'urb.inc'
557 serge 17
 
18
struc UHCI
19
{
567 serge 20
   .bus                dd ?
21
   .devfn              dd ?
22
   .io_base            dd ?
23
   .mm_base            dd ?
24
   .irq                dd ?
25
   .flags              dd ?
26
   .reset              dd ?
27
   .start              dd ?
28
   .stop               dd ?
29
 
30
   .port_c_suspend     dd ?
31
   .resuming_ports     dd ?
32
   .rh_state           dd ?
33
   .rh_numports        dd ?
34
   .is_stopped         dd ?
35
   .dead               dd ?
36
 
557 serge 37
   .sizeof:
38
}
39
 
40
virtual at 0
41
  UHCI UHCI
42
end virtual
43
 
44
struc IOCTL
45
{  .handle      dd ?
46
   .io_code     dd ?
47
   .input       dd ?
48
   .inp_size    dd ?
49
   .output      dd ?
50
   .out_size    dd ?
51
}
52
 
53
virtual at 0
54
  IOCTL IOCTL
55
end virtual
56
 
567 serge 57
struc TD   ;transfer descriptor
58
{
59
   .link        dd ?
60
   .status      dd ?
61
   .token       dd ?
62
   .buffer      dd ?
63
 
64
   .addr        dd ?
65
   .frame       dd ?
66
   .fd          dd ?
67
   .bk          dd ?
68
   .sizeof:
69
}
70
 
71
virtual at 0
72
  TD TD
73
end virtual
74
 
557 serge 75
public START
76
public service_proc
77
public version
78
 
79
DEBUG        equ 1
80
 
81
DRV_ENTRY    equ 1
82
DRV_EXIT     equ -1
83
STRIDE       equ 4      ;size of row in devices table
84
 
85
SRV_GETVERSION  equ 0
86
 
87
section '.flat' code readable align 16
88
 
89
proc START stdcall, state:dword
90
 
2434 Serge 91
        cmp     [state], 1
92
        jne     .exit
557 serge 93
.entry:
94
 
95
     if DEBUG
2434 Serge 96
        mov     esi, msgInit
97
        call    SysMsgBoardStr
557 serge 98
     end if
99
 
2434 Serge 100
        call    init
557 serge 101
 
2434 Serge 102
        stdcall RegService, my_service, service_proc
103
        ret
557 serge 104
.fail:
105
.exit:
2434 Serge 106
        xor     eax, eax
107
        ret
557 serge 108
endp
109
 
110
handle     equ  IOCTL.handle
111
io_code    equ  IOCTL.io_code
112
input      equ  IOCTL.input
113
inp_size   equ  IOCTL.inp_size
114
output     equ  IOCTL.output
115
out_size   equ  IOCTL.out_size
116
 
117
align 4
118
proc service_proc stdcall, ioctl:dword
119
 
2434 Serge 120
        mov     ebx, [ioctl]
121
        mov     eax, [ebx+io_code]
122
        cmp     eax, SRV_GETVERSION
123
        jne     @F
557 serge 124
 
2434 Serge 125
        mov     eax, [ebx+output]
126
        cmp     [ebx+out_size], 4
127
        jne     .fail
128
        mov     [eax], dword API_VERSION
129
        xor     eax, eax
130
        ret
557 serge 131
@@:
132
.fail:
2434 Serge 133
        or      eax, -1
134
        ret
557 serge 135
endp
136
 
137
restore   handle
138
restore   io_code
139
restore   input
140
restore   inp_size
141
restore   output
142
restore   out_size
143
 
144
align 4
145
proc detect
146
           locals
147
            last_bus   dd ?
148
            bus        dd ?
149
            devfn      dd ?
150
           endl
151
 
2434 Serge 152
        xor     eax, eax
153
        mov     [bus], eax
154
        inc     eax
155
        call    PciApi
156
        cmp     eax, -1
157
        je      .err
557 serge 158
 
2434 Serge 159
        mov     [last_bus], eax
557 serge 160
 
161
.next_bus:
2434 Serge 162
        and     [devfn], 0
557 serge 163
.next_dev:
2434 Serge 164
        stdcall PciRead32, [bus], [devfn], dword 0
165
        test    eax, eax
166
        jz      .next
167
        cmp     eax, -1
168
        je      .next
557 serge 169
 
2434 Serge 170
        mov     edi, devices
557 serge 171
@@:
2434 Serge 172
        mov     ebx, [edi]
173
        test    ebx, ebx
174
        jz      .next
557 serge 175
 
2434 Serge 176
        cmp     eax, ebx
177
        je      .found
557 serge 178
 
2434 Serge 179
        add     edi, STRIDE
180
        jmp     @B
557 serge 181
.next:
2434 Serge 182
        inc     [devfn]
183
        cmp     [devfn], 256
184
        jb      .next_dev
185
        mov     eax, [bus]
186
        inc     eax
187
        mov     [bus], eax
188
        cmp     eax, [last_bus]
189
        jna     .next_bus
190
        xor     eax, eax
191
        ret
557 serge 192
.found:
2434 Serge 193
        mov     eax, UHCI.sizeof
194
        call    Kmalloc
195
        test    eax, eax
196
        jz      .mem_fail
557 serge 197
 
2434 Serge 198
        mov     ebx, [bus]
199
        mov     [eax+UHCI.bus], ebx
557 serge 200
 
2434 Serge 201
        mov     ecx, [devfn]
202
        mov     [eax+UHCI.devfn], ecx
203
        ret
557 serge 204
.mem_fail:
205
     if DEBUG
2434 Serge 206
        mov     esi, msgMemFail
207
        call    SysMsgBoardStr
557 serge 208
     end if
209
.err:
2434 Serge 210
        xor     eax, eax
211
        ret
557 serge 212
endp
213
 
567 serge 214
PCI_BASE    equ 0x20
557 serge 215
USB_LEGKEY  equ 0xC0
216
 
217
align 4
218
proc init
219
           locals
220
            uhci       dd ?
221
           endl
222
 
2434 Serge 223
        call    detect
224
        test    eax, eax
225
        jz      .fail
557 serge 226
 
2434 Serge 227
        mov     [uhci], eax
557 serge 228
 
2434 Serge 229
        stdcall PciRead32, [eax+UHCI.bus], [eax+UHCI.devfn], PCI_BASE
230
        and     eax, 0xFFC0
231
        mov     esi, [uhci]
232
        mov     [esi+UHCI.io_base], eax
557 serge 233
 
2434 Serge 234
        stdcall uhci_reset, esi
557 serge 235
 
2434 Serge 236
        stdcall finish_reset, [uhci]
557 serge 237
 
238
.fail:
239
     if DEBUG
2434 Serge 240
        mov     esi, msgDevNotFound
241
        call    SysMsgBoardStr
557 serge 242
     end if
2434 Serge 243
        ret
557 serge 244
endp
245
 
567 serge 246
UHCI_USBINTR            equ  4             ; interrupt register
557 serge 247
 
567 serge 248
UHCI_USBLEGSUP_RWC      equ  0x8f00        ; the R/WC bits
249
UHCI_USBLEGSUP_RO       equ  0x5040        ; R/O and reserved bits
557 serge 250
 
567 serge 251
UHCI_USBCMD_RUN         equ  0x0001        ; RUN/STOP bit
252
UHCI_USBCMD_HCRESET     equ  0x0002        ; Host Controller reset
253
UHCI_USBCMD_EGSM        equ  0x0008        ; Global Suspend Mode
254
UHCI_USBCMD_CONFIGURE   equ  0x0040        ; Config Flag
255
UHCI_USBINTR_RESUME     equ  0x0002        ; Resume interrupt enable
557 serge 256
 
567 serge 257
PORTSC0                 equ  0x10
258
PORTSC1                 equ  0x12
557 serge 259
 
567 serge 260
 
261
UHCI_RH_RESET           equ  0
262
UHCI_RH_SUSPENDED       equ  1
263
UHCI_RH_AUTO_STOPPED    equ  2
264
UHCI_RH_RESUMING        equ  3
265
 
266
; In this state the HC changes from running to halted
267
; so it can legally appear either way.
268
UHCI_RH_SUSPENDING      equ  4
269
 
270
; In the following states it's an error if the HC is halted.
271
; These two must come last.
272
UHCI_RH_RUNNING         equ 5  ; The normal state
273
UHCI_RH_RUNNING_NODEVS  equ 6  ; Running with no devices
274
 
275
UHCI_IS_STOPPED         equ 9999
276
 
557 serge 277
align 4
278
proc uhci_reset stdcall, uhci:dword
2434 Serge 279
        mov     esi, [uhci]
280
        stdcall PciRead16, [esi+UHCI.bus], [esi+UHCI.devfn], USB_LEGKEY
281
        test    eax, not (UHCI_USBLEGSUP_RO or UHCI_USBLEGSUP_RWC)
282
        jnz     .reset
557 serge 283
 
2434 Serge 284
        mov     edx, [esi+UHCI.io_base]
285
        in      ax, dx
286
        test    ax, UHCI_USBCMD_RUN
287
        jnz     .reset
557 serge 288
 
2434 Serge 289
        test    ax, UHCI_USBCMD_CONFIGURE
290
        jz      .reset
557 serge 291
 
2434 Serge 292
        test    ax, UHCI_USBCMD_EGSM
293
        jz      .reset
567 serge 294
 
2434 Serge 295
        add     edx, UHCI_USBINTR
296
        in      ax, dx
297
        test    ax, not UHCI_USBINTR_RESUME
298
        jnz     .reset
299
        ret
557 serge 300
.reset:
2434 Serge 301
        stdcall PciWrite16, [esi+UHCI.bus], [esi+UHCI.devfn], USB_LEGKEY, UHCI_USBLEGSUP_RWC
557 serge 302
 
2434 Serge 303
        mov     edx, [esi+UHCI.io_base]
304
        mov     ax, UHCI_USBCMD_HCRESET
305
        out     dx, ax
557 serge 306
 
2434 Serge 307
        xor     eax, eax
308
        out     dx, ax
309
        add     edx, UHCI_USBINTR
310
        out     dx, ax
311
        ret
557 serge 312
endp
313
 
567 serge 314
proc finish_reset stdcall, uhci:dword
557 serge 315
 
2434 Serge 316
        mov     esi, [uhci]
317
        mov     edx, [esi+UHCI.io_base]
318
        add     edx, PORTSC0
319
        xor     eax, eax
320
        out     dx, ax
321
        add     edx, (PORTSC1-PORTSC0)
322
        out     dx, ax
557 serge 323
 
2434 Serge 324
        mov     [esi+UHCI.port_c_suspend], eax
325
        mov     [esi+UHCI.resuming_ports], eax
326
        mov     [esi+UHCI.rh_state], UHCI_RH_RESET
327
        mov     [esi+UHCI.rh_numports], 2
557 serge 328
 
2434 Serge 329
        mov     [esi+UHCI.is_stopped], UHCI_IS_STOPPED
567 serge 330
     ;      mov [ uhci_to_hcd(uhci)->state = HC_STATE_HALT;
331
     ;      uhci_to_hcd(uhci)->poll_rh = 0;
332
 
2434 Serge 333
        mov     [esi+UHCI.dead], eax ; Full reset resurrects the controller
567 serge 334
 
2434 Serge 335
        ret
567 serge 336
endp
337
 
338
proc insert_td stdcall, td:dword, frame:dword
339
 
2434 Serge 340
        mov     edi, [td]
341
        mov     eax, [frame]
342
        and     eax, -1024
343
        mov     [edi+TD.frame], eax
567 serge 344
 
2434 Serge 345
        mov     ebx, [framelist]
346
        mov     edx, [dma_framelist]
347
        shl     eax, 5
567 serge 348
 
2434 Serge 349
        mov     ecx, [eax+ebx]
350
        test    ecx, ecx
351
        jz      .empty
567 serge 352
 
2434 Serge 353
        mov     ecx, [ecx+TD.bk]              ;last TD
567 serge 354
 
2434 Serge 355
        mov     edx, [ecx+TD.fd]
356
        mov     [edi+TD.fd], edx
357
        mov     [edi+TD.bk], ecx
358
        mov     [ecx+TD.fd], edi
359
        mov     [edx+TD.bk], edi
567 serge 360
 
2434 Serge 361
        mov     eax, [ecx+TD.link]
362
        mov     [edi+TD.link], eax
363
        mov     ebx, [edi+TD.addr]
364
        mov     [ecx+TD.link], ebx
365
        ret
567 serge 366
.empty:
2434 Serge 367
        mov     ecx, [eax+edx]
368
        mov     [edi+TD.link], ecx
369
        mov     [ebx+eax], edi
370
        mov     ecx, [edi+TD.addr]
371
        mov     [eax+edx], ecx
372
        ret
567 serge 373
endp
374
 
572 serge 375
 
376
align 4
377
proc usb_get_descriptor stdcall, dev:dword, type:dword, index:dword,\
378
                                 buf:dword, size:dword
379
 
380
           locals
381
             count        dd ?
382
           endl
383
 
2434 Serge 384
        mov     esi, [buf]
385
        mov     ecx, [size]
386
        xor     eax, eax
387
        cld
388
        rep stosb
572 serge 389
 
2434 Serge 390
        mov     [count], 3
572 serge 391
@@:
2434 Serge 392
        mov     eax, [type]
393
        shl     eax, 8
394
        add     eax, [index]
395
        stdcall usb_control_msg, [dev], pipe, USB_REQ_GET_DESCRIPTOR, \
396
                USB_DIR_IN, eax,0,[buf], [size],\
397
                USB_CTRL_GET_TIMEOUT
398
        test    eax, eax
399
        jz      .next
400
        cmp     eax, -1
401
        je      .next
572 serge 402
           jmp. ok
403
.next:
2434 Serge 404
        dec     [count]
405
        jnz     @B
406
        mov     eax, -1
572 serge 407
.ok:
2434 Serge 408
        ret
572 serge 409
endp
410
 
567 serge 411
DEVICE_ID    equ  0x24D2     ;  pci device id
412
VENDOR_ID    equ  0x8086     ;  device vendor id
413
QEMU_USB     equ  0x7020
414
 
557 serge 415
;all initialized data place here
416
 
417
align 4
418
devices         dd (DEVICE_ID shl 16)+VENDOR_ID
567 serge 419
                dd (QEMU_USB  shl 16)+VENDOR_ID
420
                dd 0      ;terminator
557 serge 421
 
422
version         dd (5 shl 16) or (API_VERSION and 0xFFFF)
423
 
424
my_service      db 'UHCI',0  ;max 16 chars include zero
425
 
426
msgInit         db 'detect hardware...',13,10,0
427
msgPCI          db 'PCI accsess not supported',13,10,0
428
msgDevNotFound  db 'device not found',13,10,0
429
msgMemFail      db 'Kmalloc failed', 10,10,0
430
;msgFail         db 'device not found',13,10,0
431
 
432
section '.data' data readable writable align 16
433
 
434
;all uninitialized data place here
435