Statistics
| Branch: | Revision:

root / hw / esp.c @ c9c3c80a

History | View | Annotate | Download (20 kB)

1 6f7e9aec bellard
/*
2 67e999be bellard
 * QEMU ESP/NCR53C9x emulation
3 5fafdf24 ths
 *
4 4e9aec74 pbrook
 * Copyright (c) 2005-2006 Fabrice Bellard
5 5fafdf24 ths
 *
6 6f7e9aec bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 6f7e9aec bellard
 * of this software and associated documentation files (the "Software"), to deal
8 6f7e9aec bellard
 * in the Software without restriction, including without limitation the rights
9 6f7e9aec bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 6f7e9aec bellard
 * copies of the Software, and to permit persons to whom the Software is
11 6f7e9aec bellard
 * furnished to do so, subject to the following conditions:
12 6f7e9aec bellard
 *
13 6f7e9aec bellard
 * The above copyright notice and this permission notice shall be included in
14 6f7e9aec bellard
 * all copies or substantial portions of the Software.
15 6f7e9aec bellard
 *
16 6f7e9aec bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 6f7e9aec bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 6f7e9aec bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 6f7e9aec bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 6f7e9aec bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 6f7e9aec bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 6f7e9aec bellard
 * THE SOFTWARE.
23 6f7e9aec bellard
 */
24 5d20fa6b blueswir1
25 cfb9de9c Paul Brook
#include "sysbus.h"
26 43b443b6 Gerd Hoffmann
#include "scsi.h"
27 1cd3af54 Gerd Hoffmann
#include "esp.h"
28 bf4b9889 Blue Swirl
#include "trace.h"
29 6f7e9aec bellard
30 67e999be bellard
/*
31 5ad6bb97 blueswir1
 * On Sparc32, this is the ESP (NCR53C90) part of chip STP2000 (Master I/O),
32 5ad6bb97 blueswir1
 * also produced as NCR89C100. See
33 67e999be bellard
 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C100.txt
34 67e999be bellard
 * and
35 67e999be bellard
 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR53C9X.txt
36 67e999be bellard
 */
37 67e999be bellard
38 001faf32 Blue Swirl
#define ESP_ERROR(fmt, ...)                                             \
39 001faf32 Blue Swirl
    do { printf("ESP ERROR: %s: " fmt, __func__ , ## __VA_ARGS__); } while (0)
40 8dea1dd4 blueswir1
41 5aca8c3b blueswir1
#define ESP_REGS 16
42 8dea1dd4 blueswir1
#define TI_BUFSZ 16
43 67e999be bellard
44 4e9aec74 pbrook
typedef struct ESPState ESPState;
45 6f7e9aec bellard
46 4e9aec74 pbrook
struct ESPState {
47 cfb9de9c Paul Brook
    SysBusDevice busdev;
48 67bb5314 Avi Kivity
    MemoryRegion iomem;
49 5aca8c3b blueswir1
    uint8_t rregs[ESP_REGS];
50 5aca8c3b blueswir1
    uint8_t wregs[ESP_REGS];
51 9a975d63 Blue Swirl
    qemu_irq irq;
52 9a975d63 Blue Swirl
    uint32_t it_shift;
53 67e999be bellard
    int32_t ti_size;
54 4f6200f0 bellard
    uint32_t ti_rptr, ti_wptr;
55 3944966d Paolo Bonzini
    uint32_t status;
56 22548760 blueswir1
    uint32_t dma;
57 9a975d63 Blue Swirl
    uint8_t ti_buf[TI_BUFSZ];
58 ca9c39fa Gerd Hoffmann
    SCSIBus bus;
59 2e5d83bb pbrook
    SCSIDevice *current_dev;
60 5c6c0e51 Hannes Reinecke
    SCSIRequest *current_req;
61 9f149aa9 pbrook
    uint8_t cmdbuf[TI_BUFSZ];
62 22548760 blueswir1
    uint32_t cmdlen;
63 22548760 blueswir1
    uint32_t do_cmd;
64 4d611c9a pbrook
65 6787f5fa pbrook
    /* The amount of data left in the current DMA transfer.  */
66 4d611c9a pbrook
    uint32_t dma_left;
67 6787f5fa pbrook
    /* The size of the current DMA transfer.  Zero if no transfer is in
68 6787f5fa pbrook
       progress.  */
69 6787f5fa pbrook
    uint32_t dma_counter;
70 9a975d63 Blue Swirl
    int dma_enabled;
71 9a975d63 Blue Swirl
72 4d611c9a pbrook
    uint32_t async_len;
73 9a975d63 Blue Swirl
    uint8_t *async_buf;
74 8b17de88 blueswir1
75 ff9868ec Blue Swirl
    ESPDMAMemoryReadWriteFunc dma_memory_read;
76 ff9868ec Blue Swirl
    ESPDMAMemoryReadWriteFunc dma_memory_write;
77 67e999be bellard
    void *dma_opaque;
78 73d74342 Blue Swirl
    void (*dma_cb)(ESPState *s);
79 4e9aec74 pbrook
};
80 6f7e9aec bellard
81 5ad6bb97 blueswir1
#define ESP_TCLO   0x0
82 5ad6bb97 blueswir1
#define ESP_TCMID  0x1
83 5ad6bb97 blueswir1
#define ESP_FIFO   0x2
84 5ad6bb97 blueswir1
#define ESP_CMD    0x3
85 5ad6bb97 blueswir1
#define ESP_RSTAT  0x4
86 5ad6bb97 blueswir1
#define ESP_WBUSID 0x4
87 5ad6bb97 blueswir1
#define ESP_RINTR  0x5
88 5ad6bb97 blueswir1
#define ESP_WSEL   0x5
89 5ad6bb97 blueswir1
#define ESP_RSEQ   0x6
90 5ad6bb97 blueswir1
#define ESP_WSYNTP 0x6
91 5ad6bb97 blueswir1
#define ESP_RFLAGS 0x7
92 5ad6bb97 blueswir1
#define ESP_WSYNO  0x7
93 5ad6bb97 blueswir1
#define ESP_CFG1   0x8
94 5ad6bb97 blueswir1
#define ESP_RRES1  0x9
95 5ad6bb97 blueswir1
#define ESP_WCCF   0x9
96 5ad6bb97 blueswir1
#define ESP_RRES2  0xa
97 5ad6bb97 blueswir1
#define ESP_WTEST  0xa
98 5ad6bb97 blueswir1
#define ESP_CFG2   0xb
99 5ad6bb97 blueswir1
#define ESP_CFG3   0xc
100 5ad6bb97 blueswir1
#define ESP_RES3   0xd
101 5ad6bb97 blueswir1
#define ESP_TCHI   0xe
102 5ad6bb97 blueswir1
#define ESP_RES4   0xf
103 5ad6bb97 blueswir1
104 5ad6bb97 blueswir1
#define CMD_DMA 0x80
105 5ad6bb97 blueswir1
#define CMD_CMD 0x7f
106 5ad6bb97 blueswir1
107 5ad6bb97 blueswir1
#define CMD_NOP      0x00
108 5ad6bb97 blueswir1
#define CMD_FLUSH    0x01
109 5ad6bb97 blueswir1
#define CMD_RESET    0x02
110 5ad6bb97 blueswir1
#define CMD_BUSRESET 0x03
111 5ad6bb97 blueswir1
#define CMD_TI       0x10
112 5ad6bb97 blueswir1
#define CMD_ICCS     0x11
113 5ad6bb97 blueswir1
#define CMD_MSGACC   0x12
114 0fd0eb21 Blue Swirl
#define CMD_PAD      0x18
115 5ad6bb97 blueswir1
#define CMD_SATN     0x1a
116 5e1e0a3b Blue Swirl
#define CMD_SEL      0x41
117 5ad6bb97 blueswir1
#define CMD_SELATN   0x42
118 5ad6bb97 blueswir1
#define CMD_SELATNS  0x43
119 5ad6bb97 blueswir1
#define CMD_ENSEL    0x44
120 5ad6bb97 blueswir1
121 2f275b8f bellard
#define STAT_DO 0x00
122 2f275b8f bellard
#define STAT_DI 0x01
123 2f275b8f bellard
#define STAT_CD 0x02
124 2f275b8f bellard
#define STAT_ST 0x03
125 8dea1dd4 blueswir1
#define STAT_MO 0x06
126 8dea1dd4 blueswir1
#define STAT_MI 0x07
127 5ad6bb97 blueswir1
#define STAT_PIO_MASK 0x06
128 2f275b8f bellard
129 2f275b8f bellard
#define STAT_TC 0x10
130 4d611c9a pbrook
#define STAT_PE 0x20
131 4d611c9a pbrook
#define STAT_GE 0x40
132 c73f96fd blueswir1
#define STAT_INT 0x80
133 2f275b8f bellard
134 8dea1dd4 blueswir1
#define BUSID_DID 0x07
135 8dea1dd4 blueswir1
136 2f275b8f bellard
#define INTR_FC 0x08
137 2f275b8f bellard
#define INTR_BS 0x10
138 2f275b8f bellard
#define INTR_DC 0x20
139 9e61bde5 bellard
#define INTR_RST 0x80
140 2f275b8f bellard
141 2f275b8f bellard
#define SEQ_0 0x0
142 2f275b8f bellard
#define SEQ_CD 0x4
143 2f275b8f bellard
144 5ad6bb97 blueswir1
#define CFG1_RESREPT 0x40
145 5ad6bb97 blueswir1
146 5ad6bb97 blueswir1
#define TCHI_FAS100A 0x4
147 5ad6bb97 blueswir1
148 c73f96fd blueswir1
static void esp_raise_irq(ESPState *s)
149 c73f96fd blueswir1
{
150 c73f96fd blueswir1
    if (!(s->rregs[ESP_RSTAT] & STAT_INT)) {
151 c73f96fd blueswir1
        s->rregs[ESP_RSTAT] |= STAT_INT;
152 c73f96fd blueswir1
        qemu_irq_raise(s->irq);
153 bf4b9889 Blue Swirl
        trace_esp_raise_irq();
154 c73f96fd blueswir1
    }
155 c73f96fd blueswir1
}
156 c73f96fd blueswir1
157 c73f96fd blueswir1
static void esp_lower_irq(ESPState *s)
158 c73f96fd blueswir1
{
159 c73f96fd blueswir1
    if (s->rregs[ESP_RSTAT] & STAT_INT) {
160 c73f96fd blueswir1
        s->rregs[ESP_RSTAT] &= ~STAT_INT;
161 c73f96fd blueswir1
        qemu_irq_lower(s->irq);
162 bf4b9889 Blue Swirl
        trace_esp_lower_irq();
163 c73f96fd blueswir1
    }
164 c73f96fd blueswir1
}
165 c73f96fd blueswir1
166 73d74342 Blue Swirl
static void esp_dma_enable(void *opaque, int irq, int level)
167 73d74342 Blue Swirl
{
168 73d74342 Blue Swirl
    DeviceState *d = opaque;
169 73d74342 Blue Swirl
    ESPState *s = container_of(d, ESPState, busdev.qdev);
170 73d74342 Blue Swirl
171 73d74342 Blue Swirl
    if (level) {
172 73d74342 Blue Swirl
        s->dma_enabled = 1;
173 bf4b9889 Blue Swirl
        trace_esp_dma_enable();
174 73d74342 Blue Swirl
        if (s->dma_cb) {
175 73d74342 Blue Swirl
            s->dma_cb(s);
176 73d74342 Blue Swirl
            s->dma_cb = NULL;
177 73d74342 Blue Swirl
        }
178 73d74342 Blue Swirl
    } else {
179 bf4b9889 Blue Swirl
        trace_esp_dma_disable();
180 73d74342 Blue Swirl
        s->dma_enabled = 0;
181 73d74342 Blue Swirl
    }
182 73d74342 Blue Swirl
}
183 73d74342 Blue Swirl
184 94d3f98a Paolo Bonzini
static void esp_request_cancelled(SCSIRequest *req)
185 94d3f98a Paolo Bonzini
{
186 94d3f98a Paolo Bonzini
    ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent);
187 94d3f98a Paolo Bonzini
188 94d3f98a Paolo Bonzini
    if (req == s->current_req) {
189 94d3f98a Paolo Bonzini
        scsi_req_unref(s->current_req);
190 94d3f98a Paolo Bonzini
        s->current_req = NULL;
191 94d3f98a Paolo Bonzini
        s->current_dev = NULL;
192 94d3f98a Paolo Bonzini
    }
193 94d3f98a Paolo Bonzini
}
194 94d3f98a Paolo Bonzini
195 22548760 blueswir1
static uint32_t get_cmd(ESPState *s, uint8_t *buf)
196 2f275b8f bellard
{
197 a917d384 pbrook
    uint32_t dmalen;
198 2f275b8f bellard
    int target;
199 2f275b8f bellard
200 8dea1dd4 blueswir1
    target = s->wregs[ESP_WBUSID] & BUSID_DID;
201 4f6200f0 bellard
    if (s->dma) {
202 fc4d65da blueswir1
        dmalen = s->rregs[ESP_TCLO] | (s->rregs[ESP_TCMID] << 8);
203 8b17de88 blueswir1
        s->dma_memory_read(s->dma_opaque, buf, dmalen);
204 4f6200f0 bellard
    } else {
205 fc4d65da blueswir1
        dmalen = s->ti_size;
206 fc4d65da blueswir1
        memcpy(buf, s->ti_buf, dmalen);
207 75ef8496 Hervรฉ Poussineau
        buf[0] = buf[2] >> 5;
208 4f6200f0 bellard
    }
209 bf4b9889 Blue Swirl
    trace_esp_get_cmd(dmalen, target);
210 2e5d83bb pbrook
211 2f275b8f bellard
    s->ti_size = 0;
212 4f6200f0 bellard
    s->ti_rptr = 0;
213 4f6200f0 bellard
    s->ti_wptr = 0;
214 2f275b8f bellard
215 429bef69 Hervรฉ Poussineau
    if (s->current_req) {
216 a917d384 pbrook
        /* Started a new command before the old one finished.  Cancel it.  */
217 94d3f98a Paolo Bonzini
        scsi_req_cancel(s->current_req);
218 a917d384 pbrook
        s->async_len = 0;
219 a917d384 pbrook
    }
220 a917d384 pbrook
221 0d3545e7 Paolo Bonzini
    s->current_dev = scsi_device_find(&s->bus, 0, target, 0);
222 f48a7a6e Paolo Bonzini
    if (!s->current_dev) {
223 2e5d83bb pbrook
        // No such drive
224 c73f96fd blueswir1
        s->rregs[ESP_RSTAT] = 0;
225 5ad6bb97 blueswir1
        s->rregs[ESP_RINTR] = INTR_DC;
226 5ad6bb97 blueswir1
        s->rregs[ESP_RSEQ] = SEQ_0;
227 c73f96fd blueswir1
        esp_raise_irq(s);
228 f930d07e blueswir1
        return 0;
229 2f275b8f bellard
    }
230 9f149aa9 pbrook
    return dmalen;
231 9f149aa9 pbrook
}
232 9f149aa9 pbrook
233 f2818f22 Artyom Tarasenko
static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid)
234 9f149aa9 pbrook
{
235 9f149aa9 pbrook
    int32_t datalen;
236 9f149aa9 pbrook
    int lun;
237 f48a7a6e Paolo Bonzini
    SCSIDevice *current_lun;
238 9f149aa9 pbrook
239 bf4b9889 Blue Swirl
    trace_esp_do_busid_cmd(busid);
240 f2818f22 Artyom Tarasenko
    lun = busid & 7;
241 0d3545e7 Paolo Bonzini
    current_lun = scsi_device_find(&s->bus, 0, s->current_dev->id, lun);
242 f48a7a6e Paolo Bonzini
    s->current_req = scsi_req_new(current_lun, 0, lun, buf, NULL);
243 c39ce112 Paolo Bonzini
    datalen = scsi_req_enqueue(s->current_req);
244 67e999be bellard
    s->ti_size = datalen;
245 67e999be bellard
    if (datalen != 0) {
246 c73f96fd blueswir1
        s->rregs[ESP_RSTAT] = STAT_TC;
247 a917d384 pbrook
        s->dma_left = 0;
248 6787f5fa pbrook
        s->dma_counter = 0;
249 2e5d83bb pbrook
        if (datalen > 0) {
250 5ad6bb97 blueswir1
            s->rregs[ESP_RSTAT] |= STAT_DI;
251 2e5d83bb pbrook
        } else {
252 5ad6bb97 blueswir1
            s->rregs[ESP_RSTAT] |= STAT_DO;
253 b9788fc4 bellard
        }
254 ad3376cc Paolo Bonzini
        scsi_req_continue(s->current_req);
255 2f275b8f bellard
    }
256 5ad6bb97 blueswir1
    s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
257 5ad6bb97 blueswir1
    s->rregs[ESP_RSEQ] = SEQ_CD;
258 c73f96fd blueswir1
    esp_raise_irq(s);
259 2f275b8f bellard
}
260 2f275b8f bellard
261 f2818f22 Artyom Tarasenko
static void do_cmd(ESPState *s, uint8_t *buf)
262 f2818f22 Artyom Tarasenko
{
263 f2818f22 Artyom Tarasenko
    uint8_t busid = buf[0];
264 f2818f22 Artyom Tarasenko
265 f2818f22 Artyom Tarasenko
    do_busid_cmd(s, &buf[1], busid);
266 f2818f22 Artyom Tarasenko
}
267 f2818f22 Artyom Tarasenko
268 9f149aa9 pbrook
static void handle_satn(ESPState *s)
269 9f149aa9 pbrook
{
270 9f149aa9 pbrook
    uint8_t buf[32];
271 9f149aa9 pbrook
    int len;
272 9f149aa9 pbrook
273 73d74342 Blue Swirl
    if (!s->dma_enabled) {
274 73d74342 Blue Swirl
        s->dma_cb = handle_satn;
275 73d74342 Blue Swirl
        return;
276 73d74342 Blue Swirl
    }
277 9f149aa9 pbrook
    len = get_cmd(s, buf);
278 9f149aa9 pbrook
    if (len)
279 9f149aa9 pbrook
        do_cmd(s, buf);
280 9f149aa9 pbrook
}
281 9f149aa9 pbrook
282 f2818f22 Artyom Tarasenko
static void handle_s_without_atn(ESPState *s)
283 f2818f22 Artyom Tarasenko
{
284 f2818f22 Artyom Tarasenko
    uint8_t buf[32];
285 f2818f22 Artyom Tarasenko
    int len;
286 f2818f22 Artyom Tarasenko
287 73d74342 Blue Swirl
    if (!s->dma_enabled) {
288 73d74342 Blue Swirl
        s->dma_cb = handle_s_without_atn;
289 73d74342 Blue Swirl
        return;
290 73d74342 Blue Swirl
    }
291 f2818f22 Artyom Tarasenko
    len = get_cmd(s, buf);
292 f2818f22 Artyom Tarasenko
    if (len) {
293 f2818f22 Artyom Tarasenko
        do_busid_cmd(s, buf, 0);
294 f2818f22 Artyom Tarasenko
    }
295 f2818f22 Artyom Tarasenko
}
296 f2818f22 Artyom Tarasenko
297 9f149aa9 pbrook
static void handle_satn_stop(ESPState *s)
298 9f149aa9 pbrook
{
299 73d74342 Blue Swirl
    if (!s->dma_enabled) {
300 73d74342 Blue Swirl
        s->dma_cb = handle_satn_stop;
301 73d74342 Blue Swirl
        return;
302 73d74342 Blue Swirl
    }
303 9f149aa9 pbrook
    s->cmdlen = get_cmd(s, s->cmdbuf);
304 9f149aa9 pbrook
    if (s->cmdlen) {
305 bf4b9889 Blue Swirl
        trace_esp_handle_satn_stop(s->cmdlen);
306 9f149aa9 pbrook
        s->do_cmd = 1;
307 c73f96fd blueswir1
        s->rregs[ESP_RSTAT] = STAT_TC | STAT_CD;
308 5ad6bb97 blueswir1
        s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
309 5ad6bb97 blueswir1
        s->rregs[ESP_RSEQ] = SEQ_CD;
310 c73f96fd blueswir1
        esp_raise_irq(s);
311 9f149aa9 pbrook
    }
312 9f149aa9 pbrook
}
313 9f149aa9 pbrook
314 0fc5c15a pbrook
static void write_response(ESPState *s)
315 2f275b8f bellard
{
316 bf4b9889 Blue Swirl
    trace_esp_write_response(s->status);
317 3944966d Paolo Bonzini
    s->ti_buf[0] = s->status;
318 0fc5c15a pbrook
    s->ti_buf[1] = 0;
319 4f6200f0 bellard
    if (s->dma) {
320 8b17de88 blueswir1
        s->dma_memory_write(s->dma_opaque, s->ti_buf, 2);
321 c73f96fd blueswir1
        s->rregs[ESP_RSTAT] = STAT_TC | STAT_ST;
322 5ad6bb97 blueswir1
        s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
323 5ad6bb97 blueswir1
        s->rregs[ESP_RSEQ] = SEQ_CD;
324 4f6200f0 bellard
    } else {
325 f930d07e blueswir1
        s->ti_size = 2;
326 f930d07e blueswir1
        s->ti_rptr = 0;
327 f930d07e blueswir1
        s->ti_wptr = 0;
328 5ad6bb97 blueswir1
        s->rregs[ESP_RFLAGS] = 2;
329 4f6200f0 bellard
    }
330 c73f96fd blueswir1
    esp_raise_irq(s);
331 2f275b8f bellard
}
332 4f6200f0 bellard
333 a917d384 pbrook
static void esp_dma_done(ESPState *s)
334 a917d384 pbrook
{
335 c73f96fd blueswir1
    s->rregs[ESP_RSTAT] |= STAT_TC;
336 5ad6bb97 blueswir1
    s->rregs[ESP_RINTR] = INTR_BS;
337 5ad6bb97 blueswir1
    s->rregs[ESP_RSEQ] = 0;
338 5ad6bb97 blueswir1
    s->rregs[ESP_RFLAGS] = 0;
339 5ad6bb97 blueswir1
    s->rregs[ESP_TCLO] = 0;
340 5ad6bb97 blueswir1
    s->rregs[ESP_TCMID] = 0;
341 c73f96fd blueswir1
    esp_raise_irq(s);
342 a917d384 pbrook
}
343 a917d384 pbrook
344 4d611c9a pbrook
static void esp_do_dma(ESPState *s)
345 4d611c9a pbrook
{
346 67e999be bellard
    uint32_t len;
347 4d611c9a pbrook
    int to_device;
348 a917d384 pbrook
349 67e999be bellard
    to_device = (s->ti_size < 0);
350 a917d384 pbrook
    len = s->dma_left;
351 4d611c9a pbrook
    if (s->do_cmd) {
352 bf4b9889 Blue Swirl
        trace_esp_do_dma(s->cmdlen, len);
353 8b17de88 blueswir1
        s->dma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len);
354 4d611c9a pbrook
        s->ti_size = 0;
355 4d611c9a pbrook
        s->cmdlen = 0;
356 4d611c9a pbrook
        s->do_cmd = 0;
357 4d611c9a pbrook
        do_cmd(s, s->cmdbuf);
358 4d611c9a pbrook
        return;
359 a917d384 pbrook
    }
360 a917d384 pbrook
    if (s->async_len == 0) {
361 a917d384 pbrook
        /* Defer until data is available.  */
362 a917d384 pbrook
        return;
363 a917d384 pbrook
    }
364 a917d384 pbrook
    if (len > s->async_len) {
365 a917d384 pbrook
        len = s->async_len;
366 a917d384 pbrook
    }
367 a917d384 pbrook
    if (to_device) {
368 8b17de88 blueswir1
        s->dma_memory_read(s->dma_opaque, s->async_buf, len);
369 4d611c9a pbrook
    } else {
370 8b17de88 blueswir1
        s->dma_memory_write(s->dma_opaque, s->async_buf, len);
371 a917d384 pbrook
    }
372 a917d384 pbrook
    s->dma_left -= len;
373 a917d384 pbrook
    s->async_buf += len;
374 a917d384 pbrook
    s->async_len -= len;
375 6787f5fa pbrook
    if (to_device)
376 6787f5fa pbrook
        s->ti_size += len;
377 6787f5fa pbrook
    else
378 6787f5fa pbrook
        s->ti_size -= len;
379 a917d384 pbrook
    if (s->async_len == 0) {
380 ad3376cc Paolo Bonzini
        scsi_req_continue(s->current_req);
381 ad3376cc Paolo Bonzini
        /* If there is still data to be read from the device then
382 ad3376cc Paolo Bonzini
           complete the DMA operation immediately.  Otherwise defer
383 ad3376cc Paolo Bonzini
           until the scsi layer has completed.  */
384 ad3376cc Paolo Bonzini
        if (to_device || s->dma_left != 0 || s->ti_size == 0) {
385 ad3376cc Paolo Bonzini
            return;
386 4d611c9a pbrook
        }
387 a917d384 pbrook
    }
388 ad3376cc Paolo Bonzini
389 ad3376cc Paolo Bonzini
    /* Partially filled a scsi buffer. Complete immediately.  */
390 ad3376cc Paolo Bonzini
    esp_dma_done(s);
391 4d611c9a pbrook
}
392 4d611c9a pbrook
393 aba1f023 Paolo Bonzini
static void esp_command_complete(SCSIRequest *req, uint32_t status)
394 2e5d83bb pbrook
{
395 5c6c0e51 Hannes Reinecke
    ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent);
396 2e5d83bb pbrook
397 bf4b9889 Blue Swirl
    trace_esp_command_complete();
398 c6df7102 Paolo Bonzini
    if (s->ti_size != 0) {
399 bf4b9889 Blue Swirl
        trace_esp_command_complete_unexpected();
400 c6df7102 Paolo Bonzini
    }
401 c6df7102 Paolo Bonzini
    s->ti_size = 0;
402 c6df7102 Paolo Bonzini
    s->dma_left = 0;
403 c6df7102 Paolo Bonzini
    s->async_len = 0;
404 aba1f023 Paolo Bonzini
    if (status) {
405 bf4b9889 Blue Swirl
        trace_esp_command_complete_fail();
406 c6df7102 Paolo Bonzini
    }
407 aba1f023 Paolo Bonzini
    s->status = status;
408 c6df7102 Paolo Bonzini
    s->rregs[ESP_RSTAT] = STAT_ST;
409 c6df7102 Paolo Bonzini
    esp_dma_done(s);
410 c6df7102 Paolo Bonzini
    if (s->current_req) {
411 c6df7102 Paolo Bonzini
        scsi_req_unref(s->current_req);
412 c6df7102 Paolo Bonzini
        s->current_req = NULL;
413 c6df7102 Paolo Bonzini
        s->current_dev = NULL;
414 c6df7102 Paolo Bonzini
    }
415 c6df7102 Paolo Bonzini
}
416 c6df7102 Paolo Bonzini
417 aba1f023 Paolo Bonzini
static void esp_transfer_data(SCSIRequest *req, uint32_t len)
418 c6df7102 Paolo Bonzini
{
419 c6df7102 Paolo Bonzini
    ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent);
420 c6df7102 Paolo Bonzini
421 bf4b9889 Blue Swirl
    trace_esp_transfer_data(s->dma_left, s->ti_size);
422 aba1f023 Paolo Bonzini
    s->async_len = len;
423 c6df7102 Paolo Bonzini
    s->async_buf = scsi_req_get_buf(req);
424 c6df7102 Paolo Bonzini
    if (s->dma_left) {
425 c6df7102 Paolo Bonzini
        esp_do_dma(s);
426 c6df7102 Paolo Bonzini
    } else if (s->dma_counter != 0 && s->ti_size <= 0) {
427 c6df7102 Paolo Bonzini
        /* If this was the last part of a DMA transfer then the
428 c6df7102 Paolo Bonzini
           completion interrupt is deferred to here.  */
429 a917d384 pbrook
        esp_dma_done(s);
430 4d611c9a pbrook
    }
431 2e5d83bb pbrook
}
432 2e5d83bb pbrook
433 2f275b8f bellard
static void handle_ti(ESPState *s)
434 2f275b8f bellard
{
435 4d611c9a pbrook
    uint32_t dmalen, minlen;
436 2f275b8f bellard
437 5ad6bb97 blueswir1
    dmalen = s->rregs[ESP_TCLO] | (s->rregs[ESP_TCMID] << 8);
438 db59203d pbrook
    if (dmalen==0) {
439 db59203d pbrook
      dmalen=0x10000;
440 db59203d pbrook
    }
441 6787f5fa pbrook
    s->dma_counter = dmalen;
442 db59203d pbrook
443 9f149aa9 pbrook
    if (s->do_cmd)
444 9f149aa9 pbrook
        minlen = (dmalen < 32) ? dmalen : 32;
445 67e999be bellard
    else if (s->ti_size < 0)
446 67e999be bellard
        minlen = (dmalen < -s->ti_size) ? dmalen : -s->ti_size;
447 9f149aa9 pbrook
    else
448 9f149aa9 pbrook
        minlen = (dmalen < s->ti_size) ? dmalen : s->ti_size;
449 bf4b9889 Blue Swirl
    trace_esp_handle_ti(minlen);
450 4f6200f0 bellard
    if (s->dma) {
451 4d611c9a pbrook
        s->dma_left = minlen;
452 5ad6bb97 blueswir1
        s->rregs[ESP_RSTAT] &= ~STAT_TC;
453 4d611c9a pbrook
        esp_do_dma(s);
454 9f149aa9 pbrook
    } else if (s->do_cmd) {
455 bf4b9889 Blue Swirl
        trace_esp_handle_ti_cmd(s->cmdlen);
456 9f149aa9 pbrook
        s->ti_size = 0;
457 9f149aa9 pbrook
        s->cmdlen = 0;
458 9f149aa9 pbrook
        s->do_cmd = 0;
459 9f149aa9 pbrook
        do_cmd(s, s->cmdbuf);
460 9f149aa9 pbrook
        return;
461 9f149aa9 pbrook
    }
462 2f275b8f bellard
}
463 2f275b8f bellard
464 85948643 Blue Swirl
static void esp_hard_reset(DeviceState *d)
465 6f7e9aec bellard
{
466 63235df8 Blue Swirl
    ESPState *s = container_of(d, ESPState, busdev.qdev);
467 67e999be bellard
468 5aca8c3b blueswir1
    memset(s->rregs, 0, ESP_REGS);
469 5aca8c3b blueswir1
    memset(s->wregs, 0, ESP_REGS);
470 5ad6bb97 blueswir1
    s->rregs[ESP_TCHI] = TCHI_FAS100A; // Indicate fas100a
471 4e9aec74 pbrook
    s->ti_size = 0;
472 4e9aec74 pbrook
    s->ti_rptr = 0;
473 4e9aec74 pbrook
    s->ti_wptr = 0;
474 4e9aec74 pbrook
    s->dma = 0;
475 9f149aa9 pbrook
    s->do_cmd = 0;
476 73d74342 Blue Swirl
    s->dma_cb = NULL;
477 8dea1dd4 blueswir1
478 8dea1dd4 blueswir1
    s->rregs[ESP_CFG1] = 7;
479 6f7e9aec bellard
}
480 6f7e9aec bellard
481 85948643 Blue Swirl
static void esp_soft_reset(DeviceState *d)
482 85948643 Blue Swirl
{
483 85948643 Blue Swirl
    ESPState *s = container_of(d, ESPState, busdev.qdev);
484 85948643 Blue Swirl
485 85948643 Blue Swirl
    qemu_irq_lower(s->irq);
486 85948643 Blue Swirl
    esp_hard_reset(d);
487 85948643 Blue Swirl
}
488 85948643 Blue Swirl
489 2d069bab blueswir1
static void parent_esp_reset(void *opaque, int irq, int level)
490 2d069bab blueswir1
{
491 85948643 Blue Swirl
    if (level) {
492 85948643 Blue Swirl
        esp_soft_reset(opaque);
493 85948643 Blue Swirl
    }
494 2d069bab blueswir1
}
495 2d069bab blueswir1
496 73d74342 Blue Swirl
static void esp_gpio_demux(void *opaque, int irq, int level)
497 73d74342 Blue Swirl
{
498 73d74342 Blue Swirl
    switch (irq) {
499 73d74342 Blue Swirl
    case 0:
500 73d74342 Blue Swirl
        parent_esp_reset(opaque, irq, level);
501 73d74342 Blue Swirl
        break;
502 73d74342 Blue Swirl
    case 1:
503 73d74342 Blue Swirl
        esp_dma_enable(opaque, irq, level);
504 73d74342 Blue Swirl
        break;
505 73d74342 Blue Swirl
    }
506 73d74342 Blue Swirl
}
507 73d74342 Blue Swirl
508 67bb5314 Avi Kivity
static uint64_t esp_mem_read(void *opaque, target_phys_addr_t addr,
509 67bb5314 Avi Kivity
                             unsigned size)
510 6f7e9aec bellard
{
511 6f7e9aec bellard
    ESPState *s = opaque;
512 2814df28 Blue Swirl
    uint32_t saddr, old_val;
513 6f7e9aec bellard
514 e64d7d59 blueswir1
    saddr = addr >> s->it_shift;
515 bf4b9889 Blue Swirl
    trace_esp_mem_readb(saddr, s->rregs[saddr]);
516 6f7e9aec bellard
    switch (saddr) {
517 5ad6bb97 blueswir1
    case ESP_FIFO:
518 f930d07e blueswir1
        if (s->ti_size > 0) {
519 f930d07e blueswir1
            s->ti_size--;
520 5ad6bb97 blueswir1
            if ((s->rregs[ESP_RSTAT] & STAT_PIO_MASK) == 0) {
521 8dea1dd4 blueswir1
                /* Data out.  */
522 8dea1dd4 blueswir1
                ESP_ERROR("PIO data read not implemented\n");
523 5ad6bb97 blueswir1
                s->rregs[ESP_FIFO] = 0;
524 2e5d83bb pbrook
            } else {
525 5ad6bb97 blueswir1
                s->rregs[ESP_FIFO] = s->ti_buf[s->ti_rptr++];
526 2e5d83bb pbrook
            }
527 c73f96fd blueswir1
            esp_raise_irq(s);
528 f930d07e blueswir1
        }
529 f930d07e blueswir1
        if (s->ti_size == 0) {
530 4f6200f0 bellard
            s->ti_rptr = 0;
531 4f6200f0 bellard
            s->ti_wptr = 0;
532 4f6200f0 bellard
        }
533 f930d07e blueswir1
        break;
534 5ad6bb97 blueswir1
    case ESP_RINTR:
535 2814df28 Blue Swirl
        /* Clear sequence step, interrupt register and all status bits
536 2814df28 Blue Swirl
           except TC */
537 2814df28 Blue Swirl
        old_val = s->rregs[ESP_RINTR];
538 2814df28 Blue Swirl
        s->rregs[ESP_RINTR] = 0;
539 2814df28 Blue Swirl
        s->rregs[ESP_RSTAT] &= ~STAT_TC;
540 2814df28 Blue Swirl
        s->rregs[ESP_RSEQ] = SEQ_CD;
541 c73f96fd blueswir1
        esp_lower_irq(s);
542 2814df28 Blue Swirl
543 2814df28 Blue Swirl
        return old_val;
544 6f7e9aec bellard
    default:
545 f930d07e blueswir1
        break;
546 6f7e9aec bellard
    }
547 2f275b8f bellard
    return s->rregs[saddr];
548 6f7e9aec bellard
}
549 6f7e9aec bellard
550 67bb5314 Avi Kivity
static void esp_mem_write(void *opaque, target_phys_addr_t addr,
551 67bb5314 Avi Kivity
                          uint64_t val, unsigned size)
552 6f7e9aec bellard
{
553 6f7e9aec bellard
    ESPState *s = opaque;
554 6f7e9aec bellard
    uint32_t saddr;
555 6f7e9aec bellard
556 e64d7d59 blueswir1
    saddr = addr >> s->it_shift;
557 bf4b9889 Blue Swirl
    trace_esp_mem_writeb(saddr, s->wregs[saddr], val);
558 6f7e9aec bellard
    switch (saddr) {
559 5ad6bb97 blueswir1
    case ESP_TCLO:
560 5ad6bb97 blueswir1
    case ESP_TCMID:
561 5ad6bb97 blueswir1
        s->rregs[ESP_RSTAT] &= ~STAT_TC;
562 4f6200f0 bellard
        break;
563 5ad6bb97 blueswir1
    case ESP_FIFO:
564 9f149aa9 pbrook
        if (s->do_cmd) {
565 9f149aa9 pbrook
            s->cmdbuf[s->cmdlen++] = val & 0xff;
566 8dea1dd4 blueswir1
        } else if (s->ti_size == TI_BUFSZ - 1) {
567 8dea1dd4 blueswir1
            ESP_ERROR("fifo overrun\n");
568 2e5d83bb pbrook
        } else {
569 2e5d83bb pbrook
            s->ti_size++;
570 2e5d83bb pbrook
            s->ti_buf[s->ti_wptr++] = val & 0xff;
571 2e5d83bb pbrook
        }
572 f930d07e blueswir1
        break;
573 5ad6bb97 blueswir1
    case ESP_CMD:
574 4f6200f0 bellard
        s->rregs[saddr] = val;
575 5ad6bb97 blueswir1
        if (val & CMD_DMA) {
576 f930d07e blueswir1
            s->dma = 1;
577 6787f5fa pbrook
            /* Reload DMA counter.  */
578 5ad6bb97 blueswir1
            s->rregs[ESP_TCLO] = s->wregs[ESP_TCLO];
579 5ad6bb97 blueswir1
            s->rregs[ESP_TCMID] = s->wregs[ESP_TCMID];
580 f930d07e blueswir1
        } else {
581 f930d07e blueswir1
            s->dma = 0;
582 f930d07e blueswir1
        }
583 5ad6bb97 blueswir1
        switch(val & CMD_CMD) {
584 5ad6bb97 blueswir1
        case CMD_NOP:
585 bf4b9889 Blue Swirl
            trace_esp_mem_writeb_cmd_nop(val);
586 f930d07e blueswir1
            break;
587 5ad6bb97 blueswir1
        case CMD_FLUSH:
588 bf4b9889 Blue Swirl
            trace_esp_mem_writeb_cmd_flush(val);
589 9e61bde5 bellard
            //s->ti_size = 0;
590 5ad6bb97 blueswir1
            s->rregs[ESP_RINTR] = INTR_FC;
591 5ad6bb97 blueswir1
            s->rregs[ESP_RSEQ] = 0;
592 a214c598 blueswir1
            s->rregs[ESP_RFLAGS] = 0;
593 f930d07e blueswir1
            break;
594 5ad6bb97 blueswir1
        case CMD_RESET:
595 bf4b9889 Blue Swirl
            trace_esp_mem_writeb_cmd_reset(val);
596 85948643 Blue Swirl
            esp_soft_reset(&s->busdev.qdev);
597 f930d07e blueswir1
            break;
598 5ad6bb97 blueswir1
        case CMD_BUSRESET:
599 bf4b9889 Blue Swirl
            trace_esp_mem_writeb_cmd_bus_reset(val);
600 5ad6bb97 blueswir1
            s->rregs[ESP_RINTR] = INTR_RST;
601 5ad6bb97 blueswir1
            if (!(s->wregs[ESP_CFG1] & CFG1_RESREPT)) {
602 c73f96fd blueswir1
                esp_raise_irq(s);
603 9e61bde5 bellard
            }
604 f930d07e blueswir1
            break;
605 5ad6bb97 blueswir1
        case CMD_TI:
606 f930d07e blueswir1
            handle_ti(s);
607 f930d07e blueswir1
            break;
608 5ad6bb97 blueswir1
        case CMD_ICCS:
609 bf4b9889 Blue Swirl
            trace_esp_mem_writeb_cmd_iccs(val);
610 f930d07e blueswir1
            write_response(s);
611 4bf5801d blueswir1
            s->rregs[ESP_RINTR] = INTR_FC;
612 4bf5801d blueswir1
            s->rregs[ESP_RSTAT] |= STAT_MI;
613 f930d07e blueswir1
            break;
614 5ad6bb97 blueswir1
        case CMD_MSGACC:
615 bf4b9889 Blue Swirl
            trace_esp_mem_writeb_cmd_msgacc(val);
616 5ad6bb97 blueswir1
            s->rregs[ESP_RINTR] = INTR_DC;
617 5ad6bb97 blueswir1
            s->rregs[ESP_RSEQ] = 0;
618 4e2a68c1 Artyom Tarasenko
            s->rregs[ESP_RFLAGS] = 0;
619 4e2a68c1 Artyom Tarasenko
            esp_raise_irq(s);
620 f930d07e blueswir1
            break;
621 0fd0eb21 Blue Swirl
        case CMD_PAD:
622 bf4b9889 Blue Swirl
            trace_esp_mem_writeb_cmd_pad(val);
623 0fd0eb21 Blue Swirl
            s->rregs[ESP_RSTAT] = STAT_TC;
624 0fd0eb21 Blue Swirl
            s->rregs[ESP_RINTR] = INTR_FC;
625 0fd0eb21 Blue Swirl
            s->rregs[ESP_RSEQ] = 0;
626 0fd0eb21 Blue Swirl
            break;
627 5ad6bb97 blueswir1
        case CMD_SATN:
628 bf4b9889 Blue Swirl
            trace_esp_mem_writeb_cmd_satn(val);
629 f930d07e blueswir1
            break;
630 5e1e0a3b Blue Swirl
        case CMD_SEL:
631 bf4b9889 Blue Swirl
            trace_esp_mem_writeb_cmd_sel(val);
632 f2818f22 Artyom Tarasenko
            handle_s_without_atn(s);
633 5e1e0a3b Blue Swirl
            break;
634 5ad6bb97 blueswir1
        case CMD_SELATN:
635 bf4b9889 Blue Swirl
            trace_esp_mem_writeb_cmd_selatn(val);
636 f930d07e blueswir1
            handle_satn(s);
637 f930d07e blueswir1
            break;
638 5ad6bb97 blueswir1
        case CMD_SELATNS:
639 bf4b9889 Blue Swirl
            trace_esp_mem_writeb_cmd_selatns(val);
640 f930d07e blueswir1
            handle_satn_stop(s);
641 f930d07e blueswir1
            break;
642 5ad6bb97 blueswir1
        case CMD_ENSEL:
643 bf4b9889 Blue Swirl
            trace_esp_mem_writeb_cmd_ensel(val);
644 e3926838 blueswir1
            s->rregs[ESP_RINTR] = 0;
645 74ec6048 blueswir1
            break;
646 f930d07e blueswir1
        default:
647 67bb5314 Avi Kivity
            ESP_ERROR("Unhandled ESP command (%2.2x)\n", (unsigned)val);
648 f930d07e blueswir1
            break;
649 f930d07e blueswir1
        }
650 f930d07e blueswir1
        break;
651 5ad6bb97 blueswir1
    case ESP_WBUSID ... ESP_WSYNO:
652 f930d07e blueswir1
        break;
653 5ad6bb97 blueswir1
    case ESP_CFG1:
654 4f6200f0 bellard
        s->rregs[saddr] = val;
655 4f6200f0 bellard
        break;
656 5ad6bb97 blueswir1
    case ESP_WCCF ... ESP_WTEST:
657 4f6200f0 bellard
        break;
658 b44c08fa blueswir1
    case ESP_CFG2 ... ESP_RES4:
659 4f6200f0 bellard
        s->rregs[saddr] = val;
660 4f6200f0 bellard
        break;
661 6f7e9aec bellard
    default:
662 67bb5314 Avi Kivity
        ESP_ERROR("invalid write of 0x%02x at [0x%x]\n", (unsigned)val, saddr);
663 8dea1dd4 blueswir1
        return;
664 6f7e9aec bellard
    }
665 2f275b8f bellard
    s->wregs[saddr] = val;
666 6f7e9aec bellard
}
667 6f7e9aec bellard
668 67bb5314 Avi Kivity
static bool esp_mem_accepts(void *opaque, target_phys_addr_t addr,
669 67bb5314 Avi Kivity
                            unsigned size, bool is_write)
670 67bb5314 Avi Kivity
{
671 67bb5314 Avi Kivity
    return (size == 1) || (is_write && size == 4);
672 67bb5314 Avi Kivity
}
673 6f7e9aec bellard
674 67bb5314 Avi Kivity
static const MemoryRegionOps esp_mem_ops = {
675 67bb5314 Avi Kivity
    .read = esp_mem_read,
676 67bb5314 Avi Kivity
    .write = esp_mem_write,
677 67bb5314 Avi Kivity
    .endianness = DEVICE_NATIVE_ENDIAN,
678 67bb5314 Avi Kivity
    .valid.accepts = esp_mem_accepts,
679 6f7e9aec bellard
};
680 6f7e9aec bellard
681 cc9952f3 Blue Swirl
static const VMStateDescription vmstate_esp = {
682 cc9952f3 Blue Swirl
    .name ="esp",
683 cc9952f3 Blue Swirl
    .version_id = 3,
684 cc9952f3 Blue Swirl
    .minimum_version_id = 3,
685 cc9952f3 Blue Swirl
    .minimum_version_id_old = 3,
686 cc9952f3 Blue Swirl
    .fields      = (VMStateField []) {
687 cc9952f3 Blue Swirl
        VMSTATE_BUFFER(rregs, ESPState),
688 cc9952f3 Blue Swirl
        VMSTATE_BUFFER(wregs, ESPState),
689 cc9952f3 Blue Swirl
        VMSTATE_INT32(ti_size, ESPState),
690 cc9952f3 Blue Swirl
        VMSTATE_UINT32(ti_rptr, ESPState),
691 cc9952f3 Blue Swirl
        VMSTATE_UINT32(ti_wptr, ESPState),
692 cc9952f3 Blue Swirl
        VMSTATE_BUFFER(ti_buf, ESPState),
693 3944966d Paolo Bonzini
        VMSTATE_UINT32(status, ESPState),
694 cc9952f3 Blue Swirl
        VMSTATE_UINT32(dma, ESPState),
695 cc9952f3 Blue Swirl
        VMSTATE_BUFFER(cmdbuf, ESPState),
696 cc9952f3 Blue Swirl
        VMSTATE_UINT32(cmdlen, ESPState),
697 cc9952f3 Blue Swirl
        VMSTATE_UINT32(do_cmd, ESPState),
698 cc9952f3 Blue Swirl
        VMSTATE_UINT32(dma_left, ESPState),
699 cc9952f3 Blue Swirl
        VMSTATE_END_OF_LIST()
700 cc9952f3 Blue Swirl
    }
701 cc9952f3 Blue Swirl
};
702 6f7e9aec bellard
703 c227f099 Anthony Liguori
void esp_init(target_phys_addr_t espaddr, int it_shift,
704 ff9868ec Blue Swirl
              ESPDMAMemoryReadWriteFunc dma_memory_read,
705 ff9868ec Blue Swirl
              ESPDMAMemoryReadWriteFunc dma_memory_write,
706 73d74342 Blue Swirl
              void *dma_opaque, qemu_irq irq, qemu_irq *reset,
707 73d74342 Blue Swirl
              qemu_irq *dma_enable)
708 6f7e9aec bellard
{
709 cfb9de9c Paul Brook
    DeviceState *dev;
710 cfb9de9c Paul Brook
    SysBusDevice *s;
711 ee6847d1 Gerd Hoffmann
    ESPState *esp;
712 cfb9de9c Paul Brook
713 cfb9de9c Paul Brook
    dev = qdev_create(NULL, "esp");
714 ee6847d1 Gerd Hoffmann
    esp = DO_UPCAST(ESPState, busdev.qdev, dev);
715 ee6847d1 Gerd Hoffmann
    esp->dma_memory_read = dma_memory_read;
716 ee6847d1 Gerd Hoffmann
    esp->dma_memory_write = dma_memory_write;
717 ee6847d1 Gerd Hoffmann
    esp->dma_opaque = dma_opaque;
718 ee6847d1 Gerd Hoffmann
    esp->it_shift = it_shift;
719 73d74342 Blue Swirl
    /* XXX for now until rc4030 has been changed to use DMA enable signal */
720 73d74342 Blue Swirl
    esp->dma_enabled = 1;
721 e23a1b33 Markus Armbruster
    qdev_init_nofail(dev);
722 cfb9de9c Paul Brook
    s = sysbus_from_qdev(dev);
723 cfb9de9c Paul Brook
    sysbus_connect_irq(s, 0, irq);
724 cfb9de9c Paul Brook
    sysbus_mmio_map(s, 0, espaddr);
725 74ff8d90 Blue Swirl
    *reset = qdev_get_gpio_in(dev, 0);
726 73d74342 Blue Swirl
    *dma_enable = qdev_get_gpio_in(dev, 1);
727 cfb9de9c Paul Brook
}
728 6f7e9aec bellard
729 afd4030c Paolo Bonzini
static const struct SCSIBusInfo esp_scsi_info = {
730 afd4030c Paolo Bonzini
    .tcq = false,
731 7e0380b9 Paolo Bonzini
    .max_target = ESP_MAX_DEVS,
732 7e0380b9 Paolo Bonzini
    .max_lun = 7,
733 afd4030c Paolo Bonzini
734 c6df7102 Paolo Bonzini
    .transfer_data = esp_transfer_data,
735 94d3f98a Paolo Bonzini
    .complete = esp_command_complete,
736 94d3f98a Paolo Bonzini
    .cancel = esp_request_cancelled
737 cfdc1bb0 Paolo Bonzini
};
738 cfdc1bb0 Paolo Bonzini
739 81a322d4 Gerd Hoffmann
static int esp_init1(SysBusDevice *dev)
740 cfb9de9c Paul Brook
{
741 cfb9de9c Paul Brook
    ESPState *s = FROM_SYSBUS(ESPState, dev);
742 6f7e9aec bellard
743 cfb9de9c Paul Brook
    sysbus_init_irq(dev, &s->irq);
744 cfb9de9c Paul Brook
    assert(s->it_shift != -1);
745 6f7e9aec bellard
746 67bb5314 Avi Kivity
    memory_region_init_io(&s->iomem, &esp_mem_ops, s,
747 67bb5314 Avi Kivity
                          "esp", ESP_REGS << s->it_shift);
748 750ecd44 Avi Kivity
    sysbus_init_mmio(dev, &s->iomem);
749 6f7e9aec bellard
750 73d74342 Blue Swirl
    qdev_init_gpio_in(&dev->qdev, esp_gpio_demux, 2);
751 2d069bab blueswir1
752 afd4030c Paolo Bonzini
    scsi_bus_new(&s->bus, &dev->qdev, &esp_scsi_info);
753 fa66b909 Markus Armbruster
    return scsi_bus_legacy_handle_cmdline(&s->bus);
754 67e999be bellard
}
755 cfb9de9c Paul Brook
756 63235df8 Blue Swirl
static SysBusDeviceInfo esp_info = {
757 63235df8 Blue Swirl
    .init = esp_init1,
758 63235df8 Blue Swirl
    .qdev.name  = "esp",
759 63235df8 Blue Swirl
    .qdev.size  = sizeof(ESPState),
760 63235df8 Blue Swirl
    .qdev.vmsd  = &vmstate_esp,
761 85948643 Blue Swirl
    .qdev.reset = esp_hard_reset,
762 63235df8 Blue Swirl
    .qdev.props = (Property[]) {
763 63235df8 Blue Swirl
        {.name = NULL}
764 63235df8 Blue Swirl
    }
765 63235df8 Blue Swirl
};
766 63235df8 Blue Swirl
767 cfb9de9c Paul Brook
static void esp_register_devices(void)
768 cfb9de9c Paul Brook
{
769 63235df8 Blue Swirl
    sysbus_register_withprop(&esp_info);
770 cfb9de9c Paul Brook
}
771 cfb9de9c Paul Brook
772 cfb9de9c Paul Brook
device_init(esp_register_devices)