Root/userspace/glue/usbmassstorage.ccp

1#pypp 0
2// Iris: micro-kernel for a capability-based operating system.
3// source/usb-mass-storage.ccp: USB mass storage device driver.
4// Copyright 2009-2010 Bas Wijnen <wijnen@debian.org>
5//
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10//
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15//
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <http://www.gnu.org/licenses/>.
18
19#include "iris.hh"
20#include "devices.hh"
21#define ARCH
22#include "arch.hh"
23
24#if 0
25States and expected interrupts:
26
27IDLE: after reset or csw.
28    IN interrupt: csw received, do nothing.
29    OUT interrupt: cbw; handle
30        -> IDLE (no data; csw sent)
31        -> TX (send)
32        -> RX (receive packets)
33TX: transmitting data.
34    IN interrupt: host received data; send more.
35        -> TX (more to send)
36RX: receiving data.
37    OUT interrupt: host sent data; handle.
38        -> RX (more to receive)
39        -> IDLE (done receiving; send csw)
40#endif
41
42extern "C":
43    void *memset (char *s, int c, unsigned long n):
44        Iris::debug ("memset called: %x %x->%x\n", s, n, c)
45        for unsigned i = 0; i < n; ++i:
46            s[i] = c
47        return s
48
49class Udc:
50    typedef unsigned char u8
51    typedef unsigned short u16
52    typedef unsigned int u32
53    typedef u8 string
54    // The ugly stuff is because pypp doesn't support __attribute__.
55    /**/struct Setup {
56        u8 request_type;
57        u8 request;
58        u16 value;
59        u16 index;
60        u16 length;
61     } __attribute__ ((packed))
62    /**/struct Device {
63        static u8 const Type = 1;
64        u8 length;
65        u8 type;
66        u16 usb_version;
67        u8 dev_class;
68        u8 subclass;
69        u8 protocol;
70        u8 max_packet_size0;
71        u16 vendor;
72        u16 product;
73        u16 dev_version;
74        string s_manufacturer;
75        string s_product;
76        string s_serial;
77        u8 num_configurations;
78     } __attribute__ ((packed))
79    /**/struct Configuration {
80        static u8 const Type = 2;
81        u8 length;
82        u8 type;
83        u16 total_length;
84        u8 num_interfaces;
85        u8 configuration_value;
86        u8 configuration;
87        u8 attributes;
88        u8 max_power;
89     } __attribute__ ((packed))
90    /**/struct Interface {
91        static u8 const Type = 4;
92        u8 length;
93        u8 type;
94        u8 interface;
95        u8 alternate;
96        u8 num_endpoints;
97        u8 iface_class;
98        u8 subclass;
99        u8 protocol;
100        string name;
101     } __attribute__ ((packed))
102    /**/struct Endpoint {
103        static u8 const Type = 5;
104        u8 length;
105        u8 type;
106        u8 address;
107        u8 attributes;
108        u16 max_packet_size;
109        u8 interval;
110     } __attribute__ ((packed))
111    /**/struct Device_Qualifier {
112        static u8 const Type = 6;
113        u8 length;
114        u8 type;
115        u16 version;
116        u8 dev_class;
117        u8 subclass;
118        u8 protocol;
119        u8 max_packet_size0;
120        u8 num_configurations;
121        u8 reserved;
122     } __attribute__ ((packed))
123    /**/struct Langs {
124        static u8 const Type = 3;
125        u8 length;
126        u8 type;
127        u8 lang;
128     } __attribute__ ((packed))
129    template <unsigned size> struct String {
130        static u8 const Type = 3;
131        u8 length;
132        u8 type;
133        u16 data[size];
134     } __attribute__ ((packed))
135    /**/struct CBW {
136        u32 sig;
137        u32 tag;
138        u32 length;
139        u8 flags;
140        u8 lun;
141        u8 size;
142        u8 data[16];
143        enum Code {
144            TEST_UNIT_READY = 0x00,
145            REQUEST_SENSE = 0x03,
146            FORMAT_UNIT = 0x04,
147            INQUIRY = 0x12,
148            RESERVE6 = 0x16,
149            RELEASE6 = 0x17,
150            SEND_DIAGNOSTIC = 0x1d,
151            READ_CAPACITY = 0x25,
152            READ10 = 0x28,
153            WRITE10 = 0x2a,
154            RESERVE10 = 0x56,
155            RELEASE10 = 0x57
156         };
157     } __attribute__ ((packed))
158    static unsigned const max_packet_size0 = 64
159    static unsigned const max_packet_size_bulk = 64
160    enum Requests:
161        GET_STATUS = 0
162        CLEAR_FEATURE = 1
163        SET_FEATURE = 3
164        SET_ADDRESS = 5
165        GET_DESCRIPTOR = 6
166        SET_DESCRIPTOR = 7
167        GET_CONFIGURATION = 8
168        SET_CONFIGURATION = 9
169        GET_INTERFACE = 10
170        SET_INTERFACE = 11
171        SYNCH_FRAME = 12
172    enum Storage_requests:
173        BULK_ONLY_RESET = 0xff
174        GET_MAX_LUN = 0xfe
175    enum Request_types:
176        STANDARD_TO_DEVICE = 0
177        CLASS_TO_DEVICE = 0x20
178        VENDOR_TO_DEVICE = 0x40
179        STANDARD_TO_INTERFACE = 1
180        CLASS_TO_INTERFACE = 0x21
181        VENDOR_TO_INTERFACE = 0x41
182        STANDARD_TO_ENDPOINT = 2
183        CLASS_TO_ENDPOINT = 0x22
184        VENDOR_TO_ENDPOINT = 0x42
185        STANDARD_FROM_DEVICE = 0x80
186        CLASS_FROM_DEVICE = 0xa0
187        VENDOR_FROM_DEVICE = 0xc0
188        STANDARD_FROM_INTERFACE = 0x81
189        CLASS_FROM_INTERFACE = 0xa1
190        VENDOR_FROM_INTERFACE = 0xc1
191        STANDARD_FROM_ENDPOINT = 0x82
192        CLASS_FROM_ENDPOINT = 0xa2
193        VENDOR_FROM_ENDPOINT = 0xc2
194    enum Endpoint_types:
195        CONTROL = 0
196        ISOCHRONOUS = 1
197        BULK = 2
198        INTERRUPT = 3
199    enum Endpoint_features:
200        ENDPOINT_HALT = 0
201    /**/struct my_config {
202        Configuration config;
203        Interface interface;
204        Endpoint endpoint[2];
205     } __attribute__ ((packed))
206    static Device device_descriptor
207    //static Device_Qualifier device_qualifier_descriptor
208    static my_config config_descriptor; //, other_config_descriptor
209    static String <1> s_langs
210    static String <6> s_manufacturer
211    static String <16> s_product
212    static String <12> s_serial
213    char configuration
214    unsigned get_descriptor (unsigned type, unsigned idx, unsigned len)
215    unsigned handle_setup (Setup *s)
216    void reset ()
217    void irq_in0 ()
218    void handle_rx ()
219    void handle_tx ()
220    void handle_cbw ()
221    void send_csw ()
222    unsigned big_endian (unsigned src)
223    bool handle_interrupt (bool usb, bool in)
224    void stall (unsigned error)
225    bool stalling
226    enum State:
227        IDLE
228        TX
229        RX
230        SENT_CSW
231        STALL
232    State state
233    unsigned residue
234    unsigned status
235    unsigned tag
236    unsigned data_done, lba, blocks
237    unsigned block_bits
238    Iris::WBlock block
239    Iris::Page buffer_page
240    // A random address to map the buffer.
241    static unsigned const buffer = 0x15000
242    public:
243    void init (Iris::WBlock b)
244    void log (unsigned c)
245    void interrupt ()
246    void send (unsigned ep, char const *data, unsigned length, unsigned maxlength)
247    void send_padded (char const *data, unsigned length, unsigned maxlength)
248
249Udc::Device Udc::device_descriptor
250Udc::my_config Udc::config_descriptor
251Udc::String <1> Udc::s_langs
252Udc::String <6> Udc::s_manufacturer
253Udc::String <16> Udc::s_product
254Udc::String <12> Udc::s_serial
255
256void Udc::reset ():
257    // Reset.
258    UDC_TESTMODE = 0
259    configuration = 0
260    state = IDLE
261    status = 0
262    residue = 0
263    // enable interrupt on bus reset.
264    UDC_INTRUSBE = UDC_INTR_RESET
265    // enable interrupts on endpoint 0 and in endpoint 2
266    UDC_INTRINE = 1 << 0 | 1 << 2
267    // and on out endpoint 1.
268    UDC_INTROUTE = 1 << 1
269    // exit suspend mode by reading the interrupt register.
270    unsigned i = UDC_INTRUSB
271    // reset all pending endpoint interrupts.
272    i = UDC_INTRIN
273    i = UDC_INTROUT
274    UDC_INDEX = 1
275    UDC_OUTMAXP = max_packet_size_bulk
276    // Do this twice to flush a double-buffered fifo completely.
277    UDC_OUTCSR |= UDC_OUTCSR_CDT | UDC_OUTCSR_FF
278    UDC_OUTCSR |= UDC_OUTCSR_CDT | UDC_OUTCSR_FF
279    UDC_INDEX = 2
280    UDC_INMAXP = max_packet_size_bulk
281    UDC_INCSR = (UDC_INCSRH_MODE << 8) | UDC_INCSR_CDT | UDC_INCSR_FF
282    UDC_INCSR = (UDC_INCSRH_MODE << 8) | UDC_INCSR_CDT | UDC_INCSR_FF
283    //Iris::debug ("usb reset\n")
284
285void Udc::init (Iris::WBlock b):
286    block = b
287    block_bits = block.get_align_bits ()
288    // Set up the buffer page.
289    buffer_page = Iris::my_memory.create_page ()
290    buffer_page.set_flags (Iris::Page::PAYING)
291    Iris::my_memory.map (buffer_page, buffer)
292    // Initialize the globals. My method of compiling doesn't handle global constructors.
293    device_descriptor = (Device){ sizeof (Device), Device::Type, 0x200, 0, 0, 0, max_packet_size0, 0xfffe, 0x0002, 0x100, 1, 2, 3, 1 }
294    config_descriptor = (my_config){
295        (Configuration){ sizeof (Configuration), Configuration::Type, sizeof (my_config), 1, 1, 0, 0xc0, 30 },
296        (Interface){ sizeof (Interface), Interface::Type, 0, 0, 2, 0x8, 0x6, 0x50, 0 }, {
297            (Endpoint){ sizeof (Endpoint), Endpoint::Type, 1, BULK, max_packet_size_bulk, 0 },
298            (Endpoint){ sizeof (Endpoint), Endpoint::Type, 0x82, BULK, max_packet_size_bulk, 0 }
299        }
300     }
301    s_langs = (String <1>){ sizeof (String <1>), String <1>::Type, { 0x0409 } }
302    s_manufacturer = (String <6>){ sizeof (String <6>), String <6>::Type, { 's', 'h', 'e', 'v', 'e', 'k' } }
303    s_product = (String <16>){ sizeof (String <16>), String <16>::Type, { 'I', 'r', 'i', 's', ' ', 'o', 'n', ' ', 'N', 'a', 'n', 'o', 'N', 'o', 't', 'e' } }
304    s_serial = (String <12>){ sizeof (String <12>), String <12>::Type, { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B' } }
305
306    cpm_start_udc ()
307    // Disconnect from the bus and don't try to get high-speed.
308    UDC_POWER = 0
309    reset ()
310    // Wait a while.
311    Iris::sleep (HZ / 10)
312    // Connect to the host.
313    UDC_POWER = UDC_POWER_SOFTCONN
314
315void Udc::send (unsigned ep, char const *data, unsigned length, unsigned maxlength):
316    if maxlength < length:
317        length = maxlength
318    unsigned i
319    for i = 0; (length - i & ~3) > 0 && i < length; i += 4:
320        UDC_FIFO (ep) = ((unsigned *)data)[i / 4]
321        //kdebug_num (((unsigned *)data)[i / 4], 8)
322        //kdebug (" ")
323    for ; i < length; ++i:
324        UDC_FIFO8 (ep) = data[i]
325        //kdebug_num (data[i], 2)
326        //kdebug (" ")
327
328void Udc::send_padded (char const *data, unsigned length, unsigned maxlength):
329    UDC_INDEX = 2
330    unsigned len = length < maxlength ? length : maxlength
331    residue = maxlength - len
332    len = (len + 3) & ~3
333    send (2, data, len, maxlength)
334    //Iris::debug ("sending %x, valid %x\n", maxlength, len)
335    while len + 3 < maxlength:
336        UDC_FIFO (2) = 0
337        len += 4
338        //kdebug_char ('-')
339    while len < maxlength:
340        UDC_FIFO8 (2) = 0
341        ++len
342        //kdebug_char ('.')
343    UDC_INCSR |= UDC_INCSR_INPKTRDY
344    blocks = 0
345    state = TX
346
347unsigned Udc::get_descriptor (unsigned type, unsigned idx, unsigned len):
348    switch type:
349        case Configuration::Type:
350            if idx != 0:
351                return false
352            //Iris::debug ("get config descriptor\n")
353            send (0, reinterpret_cast <char const *> (&config_descriptor), sizeof (config_descriptor), len)
354            return UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND
355        case Device::Type:
356            if idx != 0:
357                return false
358            //Iris::debug ("get device descriptor\n")
359            send (0, reinterpret_cast <char const *> (&device_descriptor), sizeof (device_descriptor), len)
360            return UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND
361        case Device_Qualifier::Type:
362            //if idx != 0:
363            // return false
364            //send (0, reinterpret_cast <char const *> (&device_qualifier_descriptor), sizeof (device_qualifier_descriptor), len)
365            //return UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND
366            //break
367            return ~0
368        // The 6 is an arbitrary number, except that String <6> is instantiated already.
369        case String <6>::Type:
370            switch idx:
371                case 0:
372                    //Iris::debug ("get language descriptor\n")
373                    send (0, reinterpret_cast <char const *> (&s_langs), sizeof (s_langs), len)
374                    return UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND
375                case 1:
376                    //Iris::debug ("get manufacturer descriptor\n")
377                    send (0, reinterpret_cast <char const *> (&s_manufacturer), sizeof (s_manufacturer), len)
378                    return UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND
379                case 2:
380                    //Iris::debug ("get product descriptor\n")
381                    send (0, reinterpret_cast <char const *> (&s_product), sizeof (s_product), len)
382                    return UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND
383                case 3:
384                    //Iris::debug ("get serial descriptor\n")
385                    send (0, reinterpret_cast <char const *> (&s_serial), sizeof (s_serial), len)
386                    return UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND
387                default:
388                    return ~0
389        default:
390            return ~0
391
392unsigned Udc::handle_setup (Setup *s):
393    switch s->request_type:
394        case STANDARD_TO_DEVICE:
395            UDC_INDEX = 0
396            UDC_CSR0 = UDC_CSR0_DATAEND | UDC_CSR0_SVDOUTPKTRDY
397            switch s->request:
398                case SET_ADDRESS:
399                    UDC_FADDR = s->value
400                    Iris::debug ("set address %x\n", s->value)
401                    return 0
402                case SET_CONFIGURATION:
403                    if s->value >= 2:
404                        return ~0
405                    configuration = s->value
406                    Iris::debug ("set configuration %x\n", s->value)
407                    return 0
408                case SET_INTERFACE:
409                    if s->value != 0:
410                        return ~0
411                    Iris::debug ("set interface %x\n", s->value)
412                    return 0
413                default:
414                    return ~0
415        case STANDARD_FROM_DEVICE:
416            UDC_INDEX = 0
417            UDC_CSR0 = UDC_CSR0_DATAEND | UDC_CSR0_SVDOUTPKTRDY
418            switch s->request:
419                case GET_STATUS:
420                    Iris::debug ("get status\t")
421                    send (0, "\0\0", 2, s->length)
422                    return UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND
423                case GET_DESCRIPTOR:
424                    return get_descriptor ((s->value >> 8) & 0xff, s->value & 0xff, s->length)
425                case GET_CONFIGURATION:
426                    Iris::debug ("get configuration\t")
427                    send (0, &configuration, 1, s->length)
428                    return UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND
429                case GET_INTERFACE:
430                    Iris::debug ("get interface\t")
431                    send (0, "\0", 1, s->length)
432                    return UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND
433                default:
434                    return ~0
435        case STANDARD_TO_ENDPOINT:
436            switch s->request:
437                case CLEAR_FEATURE:
438                    switch s->value:
439                        case ENDPOINT_HALT:
440                            switch s->index:
441                                case 0x82:
442                                    //Iris::debug ("in ep halt reset\n")
443                                    UDC_INDEX = 2
444                                    UDC_INCSR = (UDC_INCSR & ~UDC_INCSR_SENDSTALL) | UDC_INCSR_CDT
445                                    stalling = false
446                                    send_csw ()
447                                    break
448                                case 1:
449                                    //Iris::panic (0, "halt reset on out endpoint")
450                                    UDC_INDEX = 1
451                                    UDC_OUTCSR |= UDC_OUTCSR_CDT
452                                    break
453                                default:
454                                    return ~0
455                            return UDC_CSR0_DATAEND | UDC_CSR0_SVDOUTPKTRDY
456                        default:
457                            return ~0
458                default:
459                    return ~0
460        case CLASS_FROM_INTERFACE:
461            UDC_INDEX = 0
462            UDC_CSR0 = UDC_CSR0_DATAEND | UDC_CSR0_SVDOUTPKTRDY
463            switch s->request:
464                case GET_MAX_LUN:
465                    //Iris::debug ("get max lun\t")
466                    send (0, "\0", 1, s->length)
467                    return UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND
468                default:
469                    return ~0
470        case CLASS_TO_INTERFACE:
471            UDC_INDEX = 0
472            UDC_CSR0 = UDC_CSR0_DATAEND | UDC_CSR0_SVDOUTPKTRDY
473            switch s->request:
474                case BULK_ONLY_RESET:
475                    Iris::debug ("bulk reset\n")
476                    state = IDLE
477                    return 0
478                default:
479                    return ~0
480        default:
481            Iris::debug ("request: %x %x %x %x %x\n", s->request_type, s->request, s->index, s->length, s->value)
482            return ~0
483
484void Udc::irq_in0 ():
485    // Interrupt on endpoint 0.
486    UDC_INDEX = 0
487    unsigned csr = UDC_CSR0
488    if csr & UDC_CSR0_SENTSTALL:
489        UDC_CSR0 = 0
490        //Iris::debug ("stall 0 done\t")
491    if csr & UDC_CSR0_SETUPEND:
492        UDC_CSR0 = UDC_CSR0_SVDSETUPEND
493        Iris::debug ("setup aborted\t")
494    if !(csr & UDC_CSR0_OUTPKTRDY):
495        //Iris::debug ("no packet 0: %x\n", csr)
496        return
497    UDC_INDEX = 0
498    union { unsigned d[2]; Setup s; } packet
499    packet.d[0] = UDC_FIFO (0)
500    packet.d[1] = UDC_FIFO (0)
501    if !(packet.s.request_type & 0x80) && packet.s.length > 0:
502        // More data will follow; unsupported.
503        Iris::debug ("packet on ep0 too long\n")
504        UDC_CSR0 = UDC_CSR0_SENDSTALL
505        return
506    unsigned ret = handle_setup (&packet.s)
507    UDC_INDEX = 0
508    if ret == ~0:
509        //Iris::debug ("failed setup: %x %x %x %x %x\n", packet.s.request_type, packet.s.request, packet.s.index, packet.s.length, packet.s.value)
510        UDC_CSR0 = UDC_CSR0_SENDSTALL
511        return
512    if ret:
513        UDC_CSR0 = ret
514    //kdebug ("done in0\n")
515
516void Udc::send_csw ():
517    UDC_INDEX = 2
518    UDC_FIFO (2) = 0x53425355
519    UDC_FIFO (2) = tag
520    UDC_FIFO (2) = residue
521    UDC_FIFO8 (2) = status
522    UDC_INCSR |= UDC_INCSR_INPKTRDY
523    state = SENT_CSW
524    status = 0
525    residue = 0
526    //kdebug ("sent csw\n")
527
528void Udc::stall (unsigned error):
529    if stalling:
530        Iris::debug ("already stalling!\n")
531    UDC_INCSR |= UDC_INCSR_SENDSTALL
532    stalling = true
533    state = STALL
534
535unsigned Udc::big_endian (unsigned src):
536    return src >> 24 | src >> 8 & 0xff00 | src << 8 & 0xff0000 | src << 24
537
538void Udc::handle_rx ():
539    buffer_page.set_flags (Iris::Page::FRAME)
540    UDC_INDEX = 1
541    if !(UDC_OUTCSR & UDC_OUTCSR_OUTPKTRDY):
542        Iris::panic (0, "no packet ready after out interrupt during rx")
543    if UDC_OUTCOUNT != max_packet_size_bulk:
544        Iris::panic (UDC_OUTCOUNT, "invalid packet size during rx")
545    for unsigned t = 0; t < max_packet_size_bulk; t += 4:
546        ((unsigned *)buffer)[(t + data_done) >> 2] = UDC_FIFO (1)
547    UDC_OUTCSR &= ~UDC_OUTCSR_OUTPKTRDY
548    data_done += max_packet_size_bulk
549    if data_done == 1 << block_bits:
550        //Iris::debug ("writing block %x\n", lba)
551        block.set_block (lba << block_bits, buffer_page, 1 << block_bits)
552        data_done = 0
553        --blocks
554        ++lba
555        if blocks == 0:
556            send_csw ()
557            return
558
559void Udc::handle_tx ():
560    if blocks == 0:
561        send_csw ()
562        return
563    if data_done == 0:
564        // read block lba.
565        buffer_page.set_flags (Iris::Page::FRAME)
566        block.get_block (lba << block_bits, 1 << block_bits, 0, buffer_page)
567    UDC_INDEX = 2
568    for unsigned t = 0; t < max_packet_size_bulk; t += 4:
569        UDC_FIFO (2) = ((unsigned *)buffer)[(data_done + t) >> 2]
570    data_done += max_packet_size_bulk
571    if data_done == 1 << block_bits:
572        data_done = 0
573        ++lba
574        --blocks
575    UDC_INCSR |= UDC_INCSR_INPKTRDY
576
577void Udc::handle_cbw ():
578    UDC_INDEX = 1
579    unsigned csr = UDC_OUTCSR
580    unsigned size = UDC_OUTCOUNT
581    if csr & UDC_OUTCSR_SENDSTALL:
582        // When stalling, do nothing else.
583        //kdebug ("not responding to out during stall\n")
584        UDC_OUTCSR = csr & ~UDC_OUTCSR_SENTSTALL
585        return
586    if !(csr & UDC_OUTCSR_OUTPKTRDY):
587        // No packet; this shouldn't happen.
588        Iris::panic (0, "no packet")
589        return
590    // expect a new cbw.
591    if size != 31:
592        Iris::debug ("count %d != 31\n", size)
593        stall (2)
594        return
595    union Cbw:
596        unsigned u[8]
597        char b[32]
598        CBW cbw
599    Cbw cbw
600    for unsigned i = 0; i < 7; ++i:
601        cbw.u[i] = UDC_FIFO (1)
602    for unsigned i = 28; i < 31; ++i:
603        cbw.b[i] = UDC_FIFO8 (1)
604    UDC_OUTCSR = csr & ~UDC_OUTCSR_OUTPKTRDY
605    tag = cbw.cbw.tag
606    if cbw.cbw.sig != 0x43425355 || cbw.cbw.lun != 0 || cbw.cbw.size == 0 || cbw.cbw.size > 16:
607        Iris::debug ("wrong cbw: sig %x lun %d size %d\n", cbw.cbw.sig, cbw.cbw.lun, cbw.cbw.size)
608        stall (2)
609        return
610    //kdebug ("bulk cbw\t")
611    #if 0
612    Iris::debug ("cbw:")
613    for unsigned i = 0; i < cbw.cbw.size; ++i:
614        kdebug_char (' ')
615        kdebug_num (cbw.cbw.data[i], 2)
616    Iris::debug ("\n")
617    #endif
618    UDC_INDEX = 2
619    bool to_host = cbw.cbw.flags & 0x80
620    switch cbw.cbw.data[0]:
621        case CBW::TEST_UNIT_READY:
622            if to_host || cbw.cbw.length != 0:
623                stall (2)
624                return
625            //Iris::debug ("sending ready response\t")
626            send_csw ()
627            break
628        case CBW::REQUEST_SENSE:
629            //Iris::debug ("sense requested\n")
630            send_padded ("\xf0\x00\x05\x00\x00\x00\x00\x00", 8, cbw.cbw.length)
631            break
632        case CBW::FORMAT_UNIT:
633            Iris::panic (0, "FORMAT_UNIT isn't implemented")
634        case CBW::INQUIRY:
635            if !to_host:
636                stall (2)
637                return
638            //Iris::debug ("sending inquiry response\t")
639            // TODO: find out why these bytes are messed up.
640            send_padded ("\x00\x00\x04\x02\x1f\x00\x00\x00shevek iris usb stick \x00\x00\x04\x02", 36, cbw.cbw.length)
641            break
642        case CBW::RESERVE6:
643            Iris::panic (0, "RESERVE6 isn't implemented")
644        case CBW::RELEASE6:
645            Iris::panic (0, "RELEASE6 isn't implemented")
646        case CBW::SEND_DIAGNOSTIC:
647            Iris::panic (0, "SEND_DIAGNOSTIC isn't implemented")
648        case CBW::READ_CAPACITY:
649            if !to_host:
650                stall (2)
651                return
652            unsigned capacity[2]
653            capacity[0] = big_endian ((block.get_size ().value () >> block_bits) - 1)
654            capacity[1] = big_endian (1 << block_bits)
655            //Iris::debug ("sending capacity: %x * %x\t", capacity[0], capacity[1])
656            send_padded ((char *)capacity, 8, cbw.cbw.length)
657            break
658        case CBW::READ10:
659            if !to_host:
660                stall (2)
661                return
662            lba = cbw.cbw.data[2] << 24 | cbw.cbw.data[3] << 16 | cbw.cbw.data[4] << 8 | cbw.cbw.data[5]
663            blocks = cbw.cbw.data[7] << 8 | cbw.cbw.data[8]
664            data_done = 0
665            state = TX
666            handle_tx ()
667            break
668        case CBW::WRITE10:
669            if to_host:
670                stall (2)
671                return
672            lba = cbw.cbw.data[2] << 24 | cbw.cbw.data[3] << 16 | cbw.cbw.data[4] << 8 | cbw.cbw.data[5]
673            blocks = cbw.cbw.data[7] << 8 | cbw.cbw.data[8]
674            if blocks == 0:
675                send_csw ()
676                break
677            state = RX
678            data_done = 0
679            buffer_page.set_flags (Iris::Page::FRAME)
680            break
681        case CBW::RESERVE10:
682            Iris::panic (0, "RESERVE10 isn't implemented")
683        case CBW::RELEASE10:
684            Iris::panic (0, "RELEASE10 isn't implemented")
685        default:
686            #if 0
687            Iris::debug ("unknown cbw:")
688            for unsigned i = 0; i < cbw.cbw.size; ++i:
689                kdebug_char (' ')
690                kdebug_num (cbw.cbw.data[i], 2)
691            Iris::debug ("\n")
692            #endif
693            residue = cbw.cbw.length
694            stall (1)
695            return
696
697void Udc::interrupt ():
698    //Iris::debug ("interrupt, state = %d\n", state)
699    while true:
700        bool action = false
701        unsigned usb = UDC_INTRUSB
702        unsigned in = UDC_INTRIN
703        unsigned out = UDC_INTROUT
704        if usb & 4:
705            //Iris::debug ("reset\n")
706            reset ()
707            action = true
708        if state == STALL && in & 4:
709            // This must be handled here, because the state can be changed by the control request.
710            //Iris::debug ("stalling\n")
711            in &= ~4
712        if in & 1:
713            //Iris::debug ("control request\n")
714            irq_in0 ()
715            action = true
716        if in & 4:
717            //Iris::debug ("in request\n")
718            // Notification of sent packet (or stall, but we don't do that on the in endpoint).
719            switch state:
720                case SENT_CSW:
721                    // csw received.
722                    state = IDLE
723                    break
724                case TX:
725                    handle_tx ()
726                    break
727                default:
728                    Iris::panic (state, "invalid state for data send")
729                    stall (2)
730                    break
731            action = true
732        if out & 2:
733            //Iris::debug ("out request\n")
734            switch state:
735                case IDLE:
736                    handle_cbw ()
737                    break
738                case RX:
739                    handle_rx ()
740                    break
741                default:
742                    stall (2)
743                    Iris::panic (0, "invalid state for data receive")
744                    break
745            action = true
746        if !action:
747            // No more interrupts to handle; this is normal, because we're looping until this happens.
748            //Iris::debug ("irq done\n")
749            return
750
751Iris::Num start ():
752    map_udc ()
753    map_gpio ()
754    map_cpm ()
755    Udc udc
756
757    Iris::WBlock nand = Iris::my_parent.get_capability <Iris::WBlock> ()
758    udc.init (nand)
759    while true:
760        Iris::register_interrupt (IRQ_UDC)
761        Iris::wait ()
762        udc.interrupt ()
763

Archive Download this file

Branches:
master



interactive