diff --git a/mips/arch.ccp b/mips/arch.ccp index eb95714..2a8d29b 100644 --- a/mips/arch.ccp +++ b/mips/arch.ccp @@ -220,11 +220,13 @@ bool kMemory_arch_map (kMemory *mem, kPage *page, unsigned address): mem->unmap (table->page[idx]) table->entrylo[idx] = make_entry_lo (page) table->page[idx] = page - //kdebug ("mapped ") - //kdebug_num (page->frame) - //kdebug (" at address ") - //kdebug_num (address) - //kdebug ('\n') + #if 0 + kdebug ("mapped ") + kdebug_num (page->frame) + kdebug (" at address ") + kdebug_num (address) + kdebug ('\n') + #endif page->mapping = address page->arch.next_mapped = mem->arch.shadow[address >> 21] if page->arch.next_mapped: diff --git a/mips/nand.hhp b/mips/nand.hhp index 84c4542..092d6b3 100644 --- a/mips/nand.hhp +++ b/mips/nand.hhp @@ -80,6 +80,9 @@ static unsigned rdata (): static void reset (): // Set up. gpio_as_nand () + gpio_as_gpio (2, 1 << 30) + gpio_as_input (2, 1 << 30) + gpio_enable_pull (2, 1 << 30) EMC_NFCSR = EMC_NFCSR_NFE1 | EMC_NFCSR_NFCE1 // Reset nand. @@ -149,11 +152,11 @@ static bool read (unsigned a, char *buffer): addr (col) addr (col >> 8) cmd (CMD_RNDOUTSTART) - //debug ("parity data:") + debug ("parity data:") for unsigned t = 0; t < 9; ++t: error[t] = rdata () - //debug (" %x", error[t] & 0xff) - //debug ("\n") + debug (" %x", error[t] & 0xff) + debug ("\n") cmd (CMD_RNDOUT) addr (column) addr (column >> 8) @@ -165,8 +168,10 @@ static bool read (unsigned a, char *buffer): for unsigned t = 0; t < 9; ++t: ((volatile char *)&EMC_NFPAR (0))[t] = error[t] EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_RS | EMC_NFECR_RS_DECODING | EMC_NFECR_PRDY + debug ("before\n") while !(EMC_NFINTS & EMC_NFINTS_DECF): DELAY () + debug ("after\n") unsigned ints = EMC_NFINTS if ints & EMC_NFINTS_UNCOR: debug ("uncorrectable error in nand at %x\n", a) diff --git a/source/nand.ccp b/source/nand.ccp index df9bb82..77ccd1f 100644 --- a/source/nand.ccp +++ b/source/nand.ccp @@ -20,7 +20,7 @@ #define ARCH #include "arch.hh" -#define debug Iris::debug +#define debug //Iris::debug #define DELAY Iris::schedule #include "nand.hh" @@ -74,7 +74,7 @@ Iris::Num start (): for unsigned p = 0; p < 1 << (block_bits - PAGE_BITS); ++p: Iris::Page page = Iris::my_memory.create_page () page.set_flags (Iris::Page::PAYING | Iris::Page::FRAME) - Iris::my_memory.map (page, (unsigned)cache + p << PAGE_BITS) + Iris::my_memory.map (page, (unsigned)cache + (p << PAGE_BITS)) Iris::free_cap (page) Iris::Page tmp = Iris::my_memory.create_page () tmp.set_flags (Iris::Page::PAYING) diff --git a/source/usb-mass-storage.ccp b/source/usb-mass-storage.ccp index cd1cd32..1c51279 100644 --- a/source/usb-mass-storage.ccp +++ b/source/usb-mass-storage.ccp @@ -146,10 +146,18 @@ class Udc: u8 size; u8 data[16]; enum Code { - INQUIRY = 0x12, TEST_UNIT_READY = 0x00, + REQUEST_SENSE = 0x03, + FORMAT_UNIT = 0x04, + INQUIRY = 0x12, + RESERVE6 = 0x16, + RELEASE6 = 0x17, + SEND_DIAGNOSTIC = 0x1d, READ_CAPACITY = 0x25, - REQUEST_SENSE = 0x03 + READ10 = 0x28, + WRITE10 = 0x2a, + RESERVE10 = 0x56, + RELEASE10 = 0x57 }; } __attribute__ ((packed)) static unsigned const max_packet_size0 = 64 @@ -223,6 +231,9 @@ class Udc: unsigned tag unsigned block_bits Iris::WBlock block + Iris::Page buffer_page + // A random address to map the buffer. + static unsigned const buffer = 0x15000 public: void init (Iris::WBlock b) void log (unsigned c) @@ -240,6 +251,10 @@ Udc::String <12> Udc::s_serial void Udc::init (Iris::WBlock b): block = b block_bits = block.get_align_bits () + // Set up the buffer page. + buffer_page = Iris::my_memory.create_page () + buffer_page.set_flags (Iris::Page::PAYING) + Iris::my_memory.map (buffer_page, buffer) // Initialize the globals. My method of compiling doesn't handle global constructors. device_descriptor = (Device){ sizeof (Device), Device::Type, 0x200, 0, 0, 0, max_packet_size0, 0xfffe, 0x0002, 0x100, 1, 2, 3, 1 } config_descriptor = (my_config){ @@ -259,6 +274,16 @@ void Udc::init (Iris::WBlock b): UDC_POWER = 0 UDC_TESTMODE = 0 configuration = 0 + // Set max packet sizes. + UDC_INDEX = 1 + UDC_OUTMAXP = max_packet_size_bulk + UDC_OUTCSR = UDC_OUTCSR_CDT | UDC_OUTCSR_FF + UDC_OUTCSR = UDC_OUTCSR_CDT | UDC_OUTCSR_FF + UDC_INDEX = 2 + UDC_INMAXP = max_packet_size_bulk + UDC_INCSRH = UDC_INCSRH_MODE + UDC_INCSR = UDC_INCSR_CDT | UDC_INCSR_FF + UDC_INCSR = UDC_INCSR_CDT | UDC_INCSR_FF // exit suspend mode by reading the interrupt register. unsigned i = UDC_INTRUSB // reset all pending endpoint interrupts. @@ -266,13 +291,10 @@ void Udc::init (Iris::WBlock b): i = UDC_INTROUT // enable interrupt on bus reset. UDC_INTRUSBE = UDC_INTR_RESET - // enable interrupt on control endpoint. - UDC_INTRINE = 1 << 0 - // Set max packet sizes. - UDC_INDEX = 1 - UDC_OUTMAXP = max_packet_size_bulk - UDC_INDEX = 2 - UDC_INMAXP = max_packet_size_bulk + // enable interrupts on endpoint 0 and in endpoint 2 + UDC_INTRINE = 1 << 0 | 1 << 2 + // and on out endpoint 1. + UDC_INTROUTE = 1 << 1 // Wait a while. Iris::sleep (HZ / 10) // Connect to the host. @@ -288,14 +310,17 @@ void Udc::send (unsigned ep, char const *data, unsigned length, unsigned maxleng unsigned i for i = 0; (length - i & ~3) > 0 && i < length; i += 4: UDC_FIFO (ep) = ((unsigned *)data)[i / 4] - kdebug_num (((unsigned *)data)[i / 4], 8) - kdebug (" ") + //kdebug_num (((unsigned *)data)[i / 4], 8) + //kdebug (" ") for ; i < length; ++i: UDC_FIFO8 (ep) = data[i] - kdebug_num (data[i], 2) - kdebug (" ") + //kdebug_num (data[i], 2) + //kdebug (" ") void Udc::send_padded (char const *data, unsigned length, unsigned maxlength): + UDC_INDEX = 2 + if UDC_INCSR & UDC_INCSR_INPKTRDY: + Iris::panic (0, "sending padded not possible because a packet is already waiting.\n") unsigned len = length < maxlength ? length : maxlength residue = maxlength - len len = (len + 3) & ~3 @@ -303,42 +328,41 @@ void Udc::send_padded (char const *data, unsigned length, unsigned maxlength): while len + 3 < maxlength: UDC_FIFO (2) = 0 len += 4 - kdebug_char ('-') + //kdebug_char ('-') while len < maxlength: UDC_FIFO8 (2) = 0 ++len - kdebug_char ('.') - UDC_INDEX = 2 + //kdebug_char ('.') UDC_INCSR |= UDC_INCSR_INPKTRDY while true: Iris::register_interrupt (IRQ_UDC) Iris::wait_for_interrupt (IRQ_UDC) - kdebug ("interrupt pad\n") + //kdebug ("interrupt pad\t") unsigned usb = UDC_INTRUSB unsigned in = UDC_INTRIN unsigned out = UDC_INTROUT if usb & 4 || in & 1: - kdebug ("general interrupt pad\n") + //kdebug ("general interrupt pad\t") if !handle_interrupt (usb & 4, in & 1): return if out & 2: Iris::panic (0, "out interrupt while waiting for in") if in & 4: break - kdebug ("done interrupt pad\n") + //kdebug ("done interrupt pad\n") unsigned Udc::get_descriptor (unsigned type, unsigned idx, unsigned len): switch type: case Configuration::Type: if idx != 0: return false - Iris::debug ("get config descriptor\n") + //Iris::debug ("get config descriptor\n") send (0, reinterpret_cast (&config_descriptor), sizeof (config_descriptor), len) return UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND case Device::Type: if idx != 0: return false - Iris::debug ("get device descriptor\n") + //Iris::debug ("get device descriptor\n") send (0, reinterpret_cast (&device_descriptor), sizeof (device_descriptor), len) return UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND case Device_Qualifier::Type: @@ -352,19 +376,19 @@ unsigned Udc::get_descriptor (unsigned type, unsigned idx, unsigned len): case String <6>::Type: switch idx: case 0: - Iris::debug ("get language descriptor\n") + //Iris::debug ("get language descriptor\n") send (0, reinterpret_cast (&s_langs), sizeof (s_langs), len) return UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND case 1: - Iris::debug ("get manufacturer descriptor\n") + //Iris::debug ("get manufacturer descriptor\n") send (0, reinterpret_cast (&s_manufacturer), sizeof (s_manufacturer), len) return UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND case 2: - Iris::debug ("get product descriptor\n") + //Iris::debug ("get product descriptor\n") send (0, reinterpret_cast (&s_product), sizeof (s_product), len) return UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND case 3: - Iris::debug ("get serial descriptor\n") + //Iris::debug ("get serial descriptor\n") send (0, reinterpret_cast (&s_serial), sizeof (s_serial), len) return UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND default: @@ -375,38 +399,42 @@ unsigned Udc::get_descriptor (unsigned type, unsigned idx, unsigned len): unsigned Udc::handle_setup (Setup *s): switch s->request_type: case STANDARD_TO_DEVICE: + UDC_INDEX = 0 + UDC_CSR0 = UDC_CSR0_DATAEND | UDC_CSR0_SVDOUTPKTRDY switch s->request: case SET_ADDRESS: UDC_FADDR = s->value - Iris::debug ("set address %x\n", s->value) + //Iris::debug ("set address %x\n", s->value) return 0 case SET_CONFIGURATION: if s->value >= 2: return ~0 configuration = s->value - Iris::debug ("set configuration %x\n", s->value) + //Iris::debug ("set configuration %x\n", s->value) return 0 case SET_INTERFACE: if s->value != 0: return ~0 - Iris::debug ("set interface %x\n", s->value) + //Iris::debug ("set interface %x\n", s->value) return 0 default: return ~0 case STANDARD_FROM_DEVICE: + UDC_INDEX = 0 + UDC_CSR0 = UDC_CSR0_DATAEND | UDC_CSR0_SVDOUTPKTRDY switch s->request: case GET_STATUS: - Iris::debug ("get status\n") + //Iris::debug ("get status\t") send (0, "\0\0", 2, s->length) return UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND case GET_DESCRIPTOR: return get_descriptor ((s->value >> 8) & 0xff, s->value & 0xff, s->length) case GET_CONFIGURATION: - Iris::debug ("get configuration\n") + //Iris::debug ("get configuration\t") send (0, &configuration, 1, s->length) return UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND case GET_INTERFACE: - Iris::debug ("get interface\n") + //Iris::debug ("get interface\t") send (0, "\0", 1, s->length) return UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND default: @@ -418,35 +446,42 @@ unsigned Udc::handle_setup (Setup *s): case ENDPOINT_HALT: switch s->index: case 0x82: - Iris::debug ("in ep halt reset\n") + //Iris::debug ("in ep halt reset\n") UDC_INDEX = 2 - UDC_INCSR &= ~(UDC_INCSR_SENDSTALL | UDC_INCSR_SENTSTALL) + UDC_INCSR &= ~UDC_INCSR_SENDSTALL stalling[2] = false - return 0 + break case 1: - Iris::debug ("out ep halt reset\n") + //Iris::debug ("out ep halt reset\n") UDC_INDEX = 1 - UDC_OUTCSR &= ~(UDC_OUTCSR_SENDSTALL | UDC_OUTCSR_SENTSTALL) + UDC_OUTCSR &= ~UDC_OUTCSR_SENDSTALL stalling[1] = false - return 0 + break default: return ~0 + UDC_INDEX = 0 + UDC_CSR0 = UDC_CSR0_DATAEND | UDC_CSR0_SVDOUTPKTRDY + return 0 default: return ~0 default: return ~0 case CLASS_FROM_INTERFACE: + UDC_INDEX = 0 + UDC_CSR0 = UDC_CSR0_DATAEND | UDC_CSR0_SVDOUTPKTRDY switch s->request: case GET_MAX_LUN: - Iris::debug ("get max lun\n") + //Iris::debug ("get max lun\t") send (0, "\0", 1, s->length) return UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND default: return ~0 case CLASS_TO_INTERFACE: + UDC_INDEX = 0 + UDC_CSR0 = UDC_CSR0_DATAEND | UDC_CSR0_SVDOUTPKTRDY switch s->request: case BULK_ONLY_RESET: - Iris::debug ("bulk reset\n") + //Iris::debug ("bulk reset\n") return 0 default: return ~0 @@ -462,45 +497,48 @@ void Udc::irq_usb (): UDC_INTROUTE = 1 << 1 UDC_INDEX = 1 // Do this twice to flush a double-buffered fifo completely. + UDC_OUTMAXP = max_packet_size_bulk UDC_OUTCSR |= UDC_OUTCSR_CDT | UDC_OUTCSR_FF UDC_OUTCSR |= UDC_OUTCSR_CDT | UDC_OUTCSR_FF UDC_INDEX = 2 + UDC_INMAXP = max_packet_size_bulk UDC_INCSR |= UDC_INCSR_CDT - Iris::debug ("usb reset\n") + //Iris::debug ("usb reset\n") void Udc::irq_in0 (): // Interrupt on endpoint 0. UDC_INDEX = 0 unsigned csr = UDC_CSR0 if csr & UDC_CSR0_SENTSTALL: - csr &= ~(UDC_CSR0_SENTSTALL | UDC_CSR0_SENDSTALL) + UDC_CSR0 = 0 + //Iris::debug ("stall done\t") if csr & UDC_CSR0_SETUPEND: - csr |= UDC_CSR0_SVDSETUPEND + UDC_CSR0 = UDC_CSR0_SVDSETUPEND + //Iris::debug ("setup aborted\t") if !(csr & UDC_CSR0_OUTPKTRDY): - kdebug ("packet sent 0\n") + //Iris::debug ("no packet 0: %x\n", csr) return union { unsigned d[2]; Setup s; } packet packet.d[0] = UDC_FIFO (0) packet.d[1] = UDC_FIFO (0) if !(packet.s.request_type & 0x80) && packet.s.length > 0: // More data will follow; unsupported. - Iris::debug ("packet on ep0 too long\n") - UDC_CSR0 = csr | UDC_CSR0_SENDSTALL + //Iris::debug ("packet on ep0 too long\n") + UDC_CSR0 = UDC_CSR0_SENDSTALL return - UDC_CSR0 = csr | UDC_CSR0_DATAEND | UDC_CSR0_SVDOUTPKTRDY - csr &= ~(UDC_CSR0_SETUPEND | UDC_CSR0_SENDSTALL | UDC_CSR0_SENTSTALL) - unsigned ret = handle_setup (&packet.s) UDC_INDEX = 1 UDC_OUTCSR |= UDC_OUTCSR_CDT UDC_INDEX = 2 UDC_INCSR |= UDC_INCSR_CDT + unsigned ret = handle_setup (&packet.s) UDC_INDEX = 0 if ret == ~0: 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) - UDC_CSR0 = csr | UDC_CSR0_SENDSTALL + UDC_CSR0 = UDC_CSR0_SENDSTALL return - UDC_CSR0 = csr | ret - kdebug ("done in0\n") + if ret: + UDC_CSR0 = ret + //kdebug ("done in0\n") void Udc::send_csw (): UDC_INDEX = 2 @@ -524,32 +562,38 @@ void Udc::send_csw (): unsigned out = UDC_INTROUT if out & 2: Iris::panic (0, "out interrupt while waiting for in after csw") - kdebug ("sent csw\n") + //kdebug ("sent csw\n") void Udc::stall (unsigned error): unsigned index = UDC_INDEX + if stalling[index]: + Iris::debug ("already stalling!\n") if index == 1: UDC_OUTCSR |= UDC_OUTCSR_SENDSTALL else: UDC_INCSR |= UDC_INCSR_SENDSTALL stalling[index] = true - kdebug ("stalling\n") while stalling[index]: + //kdebug ("stalling\t") Iris::register_interrupt (IRQ_UDC) Iris::wait_for_interrupt (IRQ_UDC) - kdebug ("stalling interrupt\n") + //kdebug ("stalling interrupt\n") unsigned usb = UDC_INTRUSB unsigned in = UDC_INTRIN + if in & 4: + //kdebug ("stall has been sent to in endpoint\n") + UDC_INDEX = 2 + UDC_INCSR &= ~UDC_INCSR_SENTSTALL + //Iris::debug ("csr: %x\n", UDC_INCSR) if usb & 4 || in & 1: - kdebug ("stuff\n") + //kdebug ("stuff\n") if !handle_interrupt (usb & 4, in & 1): return - if in & 4: - kdebug ("in interrupt ignored while waiting for stall reset\n") unsigned out = UDC_INTROUT if out & 2: - Iris::panic (0, "out interrupt while waiting for stall reset") - kdebug ("no stuff\n") + //kdebug ("stall has been sent to out endpoint\n") + UDC_INDEX = 1 + UDC_OUTCSR &= ~UDC_OUTCSR_SENTSTALL UDC_INDEX = index if index == 2: status = error @@ -564,12 +608,12 @@ void Udc::irq_out (): unsigned size = UDC_OUTCOUNT if !(csr & UDC_OUTCSR_OUTPKTRDY): // No packet, just a notification. - kdebug ("no packet\n") + //kdebug ("no packet\n") return if csr & UDC_OUTCSR_SENDSTALL: // When stalling, do nothing else. - kdebug ("not responding to out during stall\n") - UDC_OUTCSR &= ~UDC_OUTCSR_SENTSTALL + //kdebug ("not responding to out during stall\n") + UDC_OUTCSR = csr & ~UDC_OUTCSR_SENTSTALL return // expect a new cbw. if size != 31: @@ -578,51 +622,100 @@ void Udc::irq_out (): return union Cbw: unsigned u[8] + char b[32] CBW cbw Cbw cbw - for unsigned i = 0; i < 8; ++i: + for unsigned i = 0; i < 7; ++i: cbw.u[i] = UDC_FIFO (1) + for unsigned i = 28; i < 31; ++i: + cbw.b[i] = UDC_FIFO8 (1) + UDC_OUTCSR = csr & ~UDC_OUTCSR_OUTPKTRDY tag = cbw.cbw.tag if cbw.cbw.sig != 0x43425355 || cbw.cbw.lun != 0 || cbw.cbw.size == 0 || cbw.cbw.size > 16: Iris::debug ("sig %x lun %d size %d\n", cbw.cbw.sig, cbw.cbw.lun, cbw.cbw.size) stall (2) return - UDC_OUTCSR = csr & ~UDC_OUTCSR_OUTPKTRDY - kdebug ("bulk cbw\n") + //kdebug ("bulk cbw\t") UDC_INDEX = 2 bool to_host = cbw.cbw.flags & 0x80 switch cbw.cbw.data[0]: - case CBW::INQUIRY: - if !to_host: - stall (2) - break - Iris::debug ("sending inquiry response\n") - send_padded ("\x00\x00\x04\x02\x1f\x00\x00\x00shevek iris usb stick 0 ", 36, cbw.cbw.length) - send_csw () - break case CBW::TEST_UNIT_READY: if to_host || cbw.cbw.length != 0: stall (2) return - Iris::debug ("sending ready response\n") - send_csw () - break - case CBW::READ_CAPACITY: - if !to_host: - stall (2) - break - unsigned capacity[2] - capacity[0] = big_endian ((block.get_size ().value () >> block_bits) - 1) - capacity[1] = big_endian (1 << block_bits) - Iris::debug ("sending capacity: %x * %x\n", capacity[0], capacity[1]) - send_padded ((char *)capacity, 8, cbw.cbw.length) + //Iris::debug ("sending ready response\t") send_csw () break case CBW::REQUEST_SENSE: - Iris::debug ("sense requested\n") + //Iris::debug ("sense requested\t") send_padded ("\xf0\x00\x05\x00\x00\x00\x00\x00", 8, cbw.cbw.length) send_csw () break + case CBW::FORMAT_UNIT: + Iris::panic (0, "FORMAT_UNIT isn't implemented") + case CBW::INQUIRY: + if !to_host: + stall (2) + return + //Iris::debug ("sending inquiry response\t") + send_padded ("\x00\x00\x04\x02\x1f\x00\x00\x00shevek iris usb stick \x00\x00\x04\x02", 36, cbw.cbw.length) + send_csw () + break + case CBW::RESERVE6: + Iris::panic (0, "RESERVE6 isn't implemented") + case CBW::RELEASE6: + Iris::panic (0, "RELEASE6 isn't implemented") + case CBW::SEND_DIAGNOSTIC: + Iris::panic (0, "SEND_DIAGNOSTIC isn't implemented") + case CBW::READ_CAPACITY: + if !to_host: + stall (2) + return + unsigned capacity[2] + capacity[0] = big_endian ((block.get_size ().value () >> block_bits) - 1) + capacity[1] = big_endian (1 << block_bits) + //Iris::debug ("sending capacity: %x * %x\t", capacity[0], capacity[1]) + send_padded ((char *)capacity, 8, cbw.cbw.length) + send_csw () + break + case CBW::READ10: + unsigned lba = cbw.cbw.data[2] << 24 | cbw.cbw.data[3] << 16 | cbw.cbw.data[4] << 8 | cbw.cbw.data[5] + unsigned blocks = cbw.cbw.data[7] << 8 | cbw.cbw.data[8] + for unsigned i = 0; i < blocks; ++i: + //Iris::debug ("reading block %d:", lba + i) + // read block lba + i. + buffer_page.set_flags (Iris::Page::FRAME) + block.get_block (lba << block_bits, 1 << block_bits, 0, buffer_page) + for unsigned p = 0; p < 1 << block_bits; p += max_packet_size_bulk: + //Iris::debug (" %d", p) + UDC_INDEX = 2 + for unsigned t = 0; t < max_packet_size_bulk; t += 4: + UDC_FIFO (2) = ((unsigned *)buffer)[(p + t) >> 2] + UDC_INCSR |= UDC_INCSR_INPKTRDY + //Iris::debug ("\n") + while true: + Iris::register_interrupt (IRQ_UDC) + Iris::wait_for_interrupt (IRQ_UDC) + //kdebug ("interrupt read10\t") + unsigned usb = UDC_INTRUSB + unsigned in = UDC_INTRIN + unsigned out = UDC_INTROUT + if usb & 4 || in & 1: + //kdebug ("general interrupt read10\t") + if !handle_interrupt (usb & 4, in & 1): + return + if out & 2: + Iris::panic (0, "out interrupt while waiting for in") + if in & 4: + break + send_csw () + break + case CBW::WRITE10: + Iris::panic (0, "WRITE10 isn't implemented") + case CBW::RESERVE10: + Iris::panic (0, "RESERVE10 isn't implemented") + case CBW::RELEASE10: + Iris::panic (0, "RELEASE10 isn't implemented") default: Iris::debug ("cbw:") for unsigned i = 0; i < cbw.cbw.size; ++i: @@ -631,35 +724,40 @@ void Udc::irq_out (): Iris::debug ("\n") residue = cbw.cbw.length stall (1) - break + return // TODO. bool Udc::handle_interrupt (bool usb, bool in): if usb: - Iris::debug ("usb\t") + //Iris::debug ("usb\t") // reset. irq_usb () return false if in: - Iris::debug ("control\t") + //Iris::debug ("control\t") // control request irq_in0 () return true void Udc::interrupt (): + //Iris::debug ("interrupt\n") while true: unsigned usb = UDC_INTRUSB unsigned in = UDC_INTRIN - unsigned out = UDC_INTROUT - if !(usb & 4) && !(in & 5) && !(out & 2): - // No more interrupts to handle; this is normal, because we're looping until this happens. - Iris::debug ("irq done\n") - return + bool action = false if in & 4: - Iris::debug ("ignoring data request during idle\n") - handle_interrupt (usb & 4, in & 1) + Iris::panic (0, "data request during idle\n") + if usb & 4 || in & 1: + handle_interrupt (usb & 4, in & 1) + action = true + unsigned out = UDC_INTROUT if out & 2: irq_out () + action = true + if !action: + // No more interrupts to handle; this is normal, because we're looping until this happens. + //Iris::debug ("irq done\n") + return Iris::Num start (): map_udc ()