1.1 --- a/pkg/devices/lib/msc/src/common.cc Thu Feb 15 23:15:30 2024 +0100
1.2 +++ b/pkg/devices/lib/msc/src/common.cc Thu Feb 15 23:18:09 2024 +0100
1.3 @@ -914,9 +914,11 @@
1.4
1.5 // Determine whether a timeout occurred.
1.6
1.7 - bool have_response = !(_regs[Msc_interrupt_flag] & Int_response_timeout);
1.8 + bool have_response = !((_regs[Msc_interrupt_flag] & Int_response_timeout) ||
1.9 + (_regs[Msc_status] & Status_response_crc_error) ||
1.10 + (_regs[Msc_status] & Status_timeout_response));
1.11
1.12 - // Acknowledge the interrupts and return the status.
1.13 + // Acknowledge the response interrupts and return the status.
1.14
1.15 ack_irq(flags);
1.16 return have_response;
1.17 @@ -1190,24 +1192,51 @@
1.18 uint32_t
1.19 Msc_channel::recv_data(l4re_dma_space_dma_addr_t paddr, uint32_t count)
1.20 {
1.21 - return transfer(_msc_start + Msc_recv_data_fifo, paddr, true, count);
1.22 + uint32_t flags = Int_data_transfer_done;
1.23 +
1.24 + unmask_irq(flags);
1.25 +
1.26 + uint32_t to_transfer = transfer(_msc_start + Msc_recv_data_fifo, paddr, true, count);
1.27 +
1.28 + wait_for_irq(flags);
1.29 + ack_irq(flags);
1.30 +
1.31 + if (!to_transfer ||
1.32 + (_regs[Msc_status] & Status_read_crc_error) ||
1.33 + (_regs[Msc_status] & Status_timeout_read))
1.34 + return 0;
1.35 +
1.36 + return to_transfer;
1.37 }
1.38
1.39 uint32_t
1.40 Msc_channel::send_data(l4re_dma_space_dma_addr_t paddr, uint32_t count)
1.41 {
1.42 - return transfer(paddr, _msc_start + Msc_trans_data_fifo, false, count);
1.43 + uint32_t flags = Int_data_transfer_done;
1.44 +
1.45 + unmask_irq(flags);
1.46 +
1.47 + uint32_t to_transfer = transfer(paddr, _msc_start + Msc_trans_data_fifo, false, count);
1.48 +
1.49 + wait_for_irq(flags);
1.50 + ack_irq(flags);
1.51 +
1.52 + if (!to_transfer ||
1.53 + (_regs[Msc_status] & Status_write_crc_error_data) ||
1.54 + (_regs[Msc_status] & Status_write_crc_error_no_status))
1.55 + return 0;
1.56 +
1.57 + return to_transfer;
1.58 }
1.59
1.60 uint32_t
1.61 -Msc_channel::read_block(uint8_t card, l4re_dma_space_dma_addr_t paddr)
1.62 +Msc_channel::read_blocks(uint8_t card, l4re_dma_space_dma_addr_t paddr,
1.63 + uint32_t block_address, uint32_t block_count)
1.64 {
1.65 uint32_t block_size = 1 << _csd[card].read_blocklen;
1.66 uint16_t buffer[Response_size_R1];
1.67 struct R1 *r = (struct R1 *) buffer;
1.68
1.69 - //printf("read_block: card %d -> %d\n", card, _rca[card]);
1.70 -
1.71 // Select the requested card.
1.72
1.73 if (_current_rca != _rca[card])
1.74 @@ -1245,15 +1274,18 @@
1.75 if (r->status & R1_status_error_mask)
1.76 return 0;
1.77
1.78 + // NOTE: Consider issuing a predefined block count command to any multiple
1.79 + // NOTE: block operation, at least for cards that support it.
1.80 +
1.81 // Apply block count and size properties to the issued command.
1.82
1.83 - _regs[Msc_block_count] = 1;
1.84 + _regs[Msc_block_count] = block_count;
1.85 _regs[Msc_block_length] = block_size;
1.86
1.87 - // NOTE: Support an actual address.
1.88 // NOTE: Where CCS = 0, byte addressing is used. Otherwise, block addressing is used.
1.89
1.90 - if (!send_command(Command_read_single_block, 0))
1.91 + if (!send_command(block_count == 1 ? Command_read_single_block
1.92 + : Command_read_multiple_block, block_address))
1.93 return 0;
1.94
1.95 read_response(buffer, Response_size_R1);
1.96 @@ -1261,7 +1293,14 @@
1.97 if (r->status & R1_status_error_mask)
1.98 return 0;
1.99
1.100 - return recv_data(paddr, block_size);
1.101 + // NOTE: Use Msc_block_success_count instead.
1.102 +
1.103 + uint32_t transferred = recv_data(paddr, block_size * block_count);
1.104 +
1.105 + if (block_count > 1)
1.106 + send_command(Command_stop_transmission, 0);
1.107 +
1.108 + return transferred;
1.109 }
1.110
1.111 // Wait indefinitely for an interrupt request, returning true if one was delivered.