]> Git Repo - qemu.git/blob - hw/pxa2xx_pcmcia.c
usb: kill handle_packet callback
[qemu.git] / hw / pxa2xx_pcmcia.c
1 /*
2  * Intel XScale PXA255/270 PC Card and CompactFlash Interface.
3  *
4  * Copyright (c) 2006 Openedhand Ltd.
5  * Written by Andrzej Zaborowski <[email protected]>
6  *
7  * This code is licensed under the GPLv2.
8  *
9  * Contributions after 2012-01-13 are licensed under the terms of the
10  * GNU GPL, version 2 or (at your option) any later version.
11  */
12
13 #include "hw.h"
14 #include "pcmcia.h"
15 #include "pxa.h"
16
17
18 struct PXA2xxPCMCIAState {
19     PCMCIASocket slot;
20     PCMCIACardState *card;
21     MemoryRegion common_iomem;
22     MemoryRegion attr_iomem;
23     MemoryRegion iomem;
24
25     qemu_irq irq;
26     qemu_irq cd_irq;
27 };
28
29 static uint64_t pxa2xx_pcmcia_common_read(void *opaque,
30                 target_phys_addr_t offset, unsigned size)
31 {
32     PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
33
34     if (s->slot.attached) {
35         return s->card->common_read(s->card->state, offset);
36     }
37
38     return 0;
39 }
40
41 static void pxa2xx_pcmcia_common_write(void *opaque, target_phys_addr_t offset,
42                                        uint64_t value, unsigned size)
43 {
44     PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
45
46     if (s->slot.attached) {
47         s->card->common_write(s->card->state, offset, value);
48     }
49 }
50
51 static uint64_t pxa2xx_pcmcia_attr_read(void *opaque,
52                 target_phys_addr_t offset, unsigned size)
53 {
54     PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
55
56     if (s->slot.attached) {
57         return s->card->attr_read(s->card->state, offset);
58     }
59
60     return 0;
61 }
62
63 static void pxa2xx_pcmcia_attr_write(void *opaque, target_phys_addr_t offset,
64                                      uint64_t value, unsigned size)
65 {
66     PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
67
68     if (s->slot.attached) {
69         s->card->attr_write(s->card->state, offset, value);
70     }
71 }
72
73 static uint64_t pxa2xx_pcmcia_io_read(void *opaque,
74                 target_phys_addr_t offset, unsigned size)
75 {
76     PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
77
78     if (s->slot.attached) {
79         return s->card->io_read(s->card->state, offset);
80     }
81
82     return 0;
83 }
84
85 static void pxa2xx_pcmcia_io_write(void *opaque, target_phys_addr_t offset,
86                                    uint64_t value, unsigned size)
87 {
88     PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
89
90     if (s->slot.attached) {
91         s->card->io_write(s->card->state, offset, value);
92     }
93 }
94
95 static const MemoryRegionOps pxa2xx_pcmcia_common_ops = {
96     .read = pxa2xx_pcmcia_common_read,
97     .write = pxa2xx_pcmcia_common_write,
98     .endianness = DEVICE_NATIVE_ENDIAN
99 };
100
101 static const MemoryRegionOps pxa2xx_pcmcia_attr_ops = {
102     .read = pxa2xx_pcmcia_attr_read,
103     .write = pxa2xx_pcmcia_attr_write,
104     .endianness = DEVICE_NATIVE_ENDIAN
105 };
106
107 static const MemoryRegionOps pxa2xx_pcmcia_io_ops = {
108     .read = pxa2xx_pcmcia_io_read,
109     .write = pxa2xx_pcmcia_io_write,
110     .endianness = DEVICE_NATIVE_ENDIAN
111 };
112
113 static void pxa2xx_pcmcia_set_irq(void *opaque, int line, int level)
114 {
115     PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
116     if (!s->irq)
117         return;
118
119     qemu_set_irq(s->irq, level);
120 }
121
122 PXA2xxPCMCIAState *pxa2xx_pcmcia_init(MemoryRegion *sysmem,
123                                       target_phys_addr_t base)
124 {
125     PXA2xxPCMCIAState *s;
126
127     s = (PXA2xxPCMCIAState *)
128             g_malloc0(sizeof(PXA2xxPCMCIAState));
129
130     /* Socket I/O Memory Space */
131     memory_region_init_io(&s->iomem, &pxa2xx_pcmcia_io_ops, s,
132                           "pxa2xx-pcmcia-io", 0x04000000);
133     memory_region_add_subregion(sysmem, base | 0x00000000,
134                                 &s->iomem);
135
136     /* Then next 64 MB is reserved */
137
138     /* Socket Attribute Memory Space */
139     memory_region_init_io(&s->attr_iomem, &pxa2xx_pcmcia_attr_ops, s,
140                           "pxa2xx-pcmcia-attribute", 0x04000000);
141     memory_region_add_subregion(sysmem, base | 0x08000000,
142                                 &s->attr_iomem);
143
144     /* Socket Common Memory Space */
145     memory_region_init_io(&s->common_iomem, &pxa2xx_pcmcia_common_ops, s,
146                           "pxa2xx-pcmcia-common", 0x04000000);
147     memory_region_add_subregion(sysmem, base | 0x0c000000,
148                                 &s->common_iomem);
149
150     if (base == 0x30000000)
151         s->slot.slot_string = "PXA PC Card Socket 1";
152     else
153         s->slot.slot_string = "PXA PC Card Socket 0";
154     s->slot.irq = qemu_allocate_irqs(pxa2xx_pcmcia_set_irq, s, 1)[0];
155     pcmcia_socket_register(&s->slot);
156
157     return s;
158 }
159
160 /* Insert a new card into a slot */
161 int pxa2xx_pcmcia_attach(void *opaque, PCMCIACardState *card)
162 {
163     PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
164     if (s->slot.attached)
165         return -EEXIST;
166
167     if (s->cd_irq) {
168         qemu_irq_raise(s->cd_irq);
169     }
170
171     s->card = card;
172
173     s->slot.attached = 1;
174     s->card->slot = &s->slot;
175     s->card->attach(s->card->state);
176
177     return 0;
178 }
179
180 /* Eject card from the slot */
181 int pxa2xx_pcmcia_dettach(void *opaque)
182 {
183     PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
184     if (!s->slot.attached)
185         return -ENOENT;
186
187     s->card->detach(s->card->state);
188     s->card->slot = NULL;
189     s->card = NULL;
190
191     s->slot.attached = 0;
192
193     if (s->irq)
194         qemu_irq_lower(s->irq);
195     if (s->cd_irq)
196         qemu_irq_lower(s->cd_irq);
197
198     return 0;
199 }
200
201 /* Who to notify on card events */
202 void pxa2xx_pcmcia_set_irq_cb(void *opaque, qemu_irq irq, qemu_irq cd_irq)
203 {
204     PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
205     s->irq = irq;
206     s->cd_irq = cd_irq;
207 }
This page took 0.033494 seconds and 4 git commands to generate.