summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/qemu/qemu/smc91c111_fix.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-devtools/qemu/qemu/smc91c111_fix.patch')
-rw-r--r--meta/recipes-devtools/qemu/qemu/smc91c111_fix.patch74
1 files changed, 74 insertions, 0 deletions
diff --git a/meta/recipes-devtools/qemu/qemu/smc91c111_fix.patch b/meta/recipes-devtools/qemu/qemu/smc91c111_fix.patch
new file mode 100644
index 0000000000..e37e777347
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/smc91c111_fix.patch
@@ -0,0 +1,74 @@
1The smc91c111.c driver appears to have several issues. The can_receive()
2function can return that the driver is ready when rx_fifo has not been
3freed yet. There is also no sanity check of rx_fifo() in _receive() which
4can lead to corruption of the rx_fifo array.
5
6release_packet() can also call qemu_flush_queued_packets() before rx_fifo
7has been cleaned up, resulting in cases where packets are submitted
8for which there is not yet any space.
9
10This patch therefore:
11
12* fixes the logic in can_receive()
13* adds logic to receive() as a sanity check
14* moves the flush() calls to the correct places where data is ready
15 to be received
16
17Upstream-Status: Pending [discussion in progress on mailing list]
18RP 2015/9/7
19
20Index: qemu-2.4.0/hw/net/smc91c111.c
21===================================================================
22--- qemu-2.4.0.orig/hw/net/smc91c111.c
23+++ qemu-2.4.0/hw/net/smc91c111.c
24@@ -185,7 +185,6 @@ static void smc91c111_release_packet(smc
25 s->allocated &= ~(1 << packet);
26 if (s->tx_alloc == 0x80)
27 smc91c111_tx_alloc(s);
28- qemu_flush_queued_packets(qemu_get_queue(s->nic));
29 }
30
31 /* Flush the TX FIFO. */
32@@ -237,9 +236,11 @@ static void smc91c111_do_tx(smc91c111_st
33 }
34 }
35 #endif
36- if (s->ctr & CTR_AUTO_RELEASE)
37+ if (s->ctr & CTR_AUTO_RELEASE) {
38 /* Race? */
39 smc91c111_release_packet(s, packetnum);
40+ qemu_flush_queued_packets(qemu_get_queue(s->nic));
41+ }
42 else if (s->tx_fifo_done_len < NUM_PACKETS)
43 s->tx_fifo_done[s->tx_fifo_done_len++] = packetnum;
44 qemu_send_packet(qemu_get_queue(s->nic), p, len);
45@@ -379,9 +380,11 @@ static void smc91c111_writeb(void *opaqu
46 smc91c111_release_packet(s, s->rx_fifo[0]);
47 }
48 smc91c111_pop_rx_fifo(s);
49+ qemu_flush_queued_packets(qemu_get_queue(s->nic));
50 break;
51 case 5: /* Release. */
52 smc91c111_release_packet(s, s->packet_num);
53+ qemu_flush_queued_packets(qemu_get_queue(s->nic));
54 break;
55 case 6: /* Add to TX FIFO. */
56 smc91c111_queue_tx(s, s->packet_num);
57@@ -642,7 +642,7 @@ static int smc91c111_can_receive(NetClie
58
59 if ((s->rcr & RCR_RXEN) == 0 || (s->rcr & RCR_SOFT_RST))
60 return 1;
61- if (s->allocated == (1 << NUM_PACKETS) - 1)
62+ if ((s->allocated == (1 << NUM_PACKETS) - 1) || (s->rx_fifo_len == NUM_PACKETS))
63 return 0;
64 return 1;
65 }
66@@ -671,6 +671,8 @@ static ssize_t smc91c111_receive(NetClie
67 /* TODO: Flag overrun and receive errors. */
68 if (packetsize > 2048)
69 return -1;
70+ if (s->rx_fifo_len == NUM_PACKETS)
71+ return -1;
72 packetnum = smc91c111_allocate_packet(s);
73 if (packetnum == 0x80)
74 return -1;