Statistics
| Branch: | Revision:

root / hw / esp.c @ ad3376cc

History | View | Annotate | Download (20.1 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 6f7e9aec bellard
29 6f7e9aec bellard
/* debug ESP card */
30 2f275b8f bellard
//#define DEBUG_ESP
31 6f7e9aec bellard
32 67e999be bellard
/*
33 5ad6bb97 blueswir1
 * On Sparc32, this is the ESP (NCR53C90) part of chip STP2000 (Master I/O),
34 5ad6bb97 blueswir1
 * also produced as NCR89C100. See
35 67e999be bellard
 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C100.txt
36 67e999be bellard
 * and
37 67e999be bellard
 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR53C9X.txt
38 67e999be bellard
 */
39 67e999be bellard
40 6f7e9aec bellard
#ifdef DEBUG_ESP
41 001faf32 Blue Swirl
#define DPRINTF(fmt, ...)                                       \
42 001faf32 Blue Swirl
    do { printf("ESP: " fmt , ## __VA_ARGS__); } while (0)
43 6f7e9aec bellard
#else
44 001faf32 Blue Swirl
#define DPRINTF(fmt, ...) do {} while (0)
45 6f7e9aec bellard
#endif
46 6f7e9aec bellard
47 001faf32 Blue Swirl
#define ESP_ERROR(fmt, ...)                                             \
48 001faf32 Blue Swirl
    do { printf("ESP ERROR: %s: " fmt, __func__ , ## __VA_ARGS__); } while (0)
49 8dea1dd4 blueswir1
50 5aca8c3b blueswir1
#define ESP_REGS 16
51 8dea1dd4 blueswir1
#define TI_BUFSZ 16
52 67e999be bellard
53 4e9aec74 pbrook
typedef struct ESPState ESPState;
54 6f7e9aec bellard
55 4e9aec74 pbrook
struct ESPState {
56 cfb9de9c Paul Brook
    SysBusDevice busdev;
57 5d20fa6b blueswir1
    uint32_t it_shift;
58 70c0de96 blueswir1
    qemu_irq irq;
59 5aca8c3b blueswir1
    uint8_t rregs[ESP_REGS];
60 5aca8c3b blueswir1
    uint8_t wregs[ESP_REGS];
61 67e999be bellard
    int32_t ti_size;
62 4f6200f0 bellard
    uint32_t ti_rptr, ti_wptr;
63 4f6200f0 bellard
    uint8_t ti_buf[TI_BUFSZ];
64 22548760 blueswir1
    uint32_t sense;
65 22548760 blueswir1
    uint32_t dma;
66 ca9c39fa Gerd Hoffmann
    SCSIBus bus;
67 2e5d83bb pbrook
    SCSIDevice *current_dev;
68 5c6c0e51 Hannes Reinecke
    SCSIRequest *current_req;
69 9f149aa9 pbrook
    uint8_t cmdbuf[TI_BUFSZ];
70 22548760 blueswir1
    uint32_t cmdlen;
71 22548760 blueswir1
    uint32_t do_cmd;
72 4d611c9a pbrook
73 6787f5fa pbrook
    /* The amount of data left in the current DMA transfer.  */
74 4d611c9a pbrook
    uint32_t dma_left;
75 6787f5fa pbrook
    /* The size of the current DMA transfer.  Zero if no transfer is in
76 6787f5fa pbrook
       progress.  */
77 6787f5fa pbrook
    uint32_t dma_counter;
78 a917d384 pbrook
    uint8_t *async_buf;
79 4d611c9a pbrook
    uint32_t async_len;
80 8b17de88 blueswir1
81 ff9868ec Blue Swirl
    ESPDMAMemoryReadWriteFunc dma_memory_read;
82 ff9868ec Blue Swirl
    ESPDMAMemoryReadWriteFunc dma_memory_write;
83 67e999be bellard
    void *dma_opaque;
84 73d74342 Blue Swirl
    int dma_enabled;
85 73d74342 Blue Swirl
    void (*dma_cb)(ESPState *s);
86 4e9aec74 pbrook
};
87 6f7e9aec bellard
88 5ad6bb97 blueswir1
#define ESP_TCLO   0x0
89 5ad6bb97 blueswir1
#define ESP_TCMID  0x1
90 5ad6bb97 blueswir1
#define ESP_FIFO   0x2
91 5ad6bb97 blueswir1
#define ESP_CMD    0x3
92 5ad6bb97 blueswir1
#define ESP_RSTAT  0x4
93 5ad6bb97 blueswir1
#define ESP_WBUSID 0x4
94 5ad6bb97 blueswir1
#define ESP_RINTR  0x5
95 5ad6bb97 blueswir1
#define ESP_WSEL   0x5
96 5ad6bb97 blueswir1
#define ESP_RSEQ   0x6
97 5ad6bb97 blueswir1
#define ESP_WSYNTP 0x6
98 5ad6bb97 blueswir1
#define ESP_RFLAGS 0x7
99 5ad6bb97 blueswir1
#define ESP_WSYNO  0x7
100 5ad6bb97 blueswir1
#define ESP_CFG1   0x8
101 5ad6bb97 blueswir1
#define ESP_RRES1  0x9
102 5ad6bb97 blueswir1
#define ESP_WCCF   0x9
103 5ad6bb97 blueswir1
#define ESP_RRES2  0xa
104 5ad6bb97 blueswir1
#define ESP_WTEST  0xa
105 5ad6bb97 blueswir1
#define ESP_CFG2   0xb
106 5ad6bb97 blueswir1
#define ESP_CFG3   0xc
107 5ad6bb97 blueswir1
#define ESP_RES3   0xd
108 5ad6bb97 blueswir1
#define ESP_TCHI   0xe
109 5ad6bb97 blueswir1
#define ESP_RES4   0xf
110 5ad6bb97 blueswir1
111 5ad6bb97 blueswir1
#define CMD_DMA 0x80
112 5ad6bb97 blueswir1
#define CMD_CMD 0x7f
113 5ad6bb97 blueswir1
114 5ad6bb97 blueswir1
#define CMD_NOP      0x00
115 5ad6bb97 blueswir1
#define CMD_FLUSH    0x01
116 5ad6bb97 blueswir1
#define CMD_RESET    0x02
117 5ad6bb97 blueswir1
#define CMD_BUSRESET 0x03
118 5ad6bb97 blueswir1
#define CMD_TI       0x10
119 5ad6bb97 blueswir1
#define CMD_ICCS     0x11
120 5ad6bb97 blueswir1
#define CMD_MSGACC   0x12
121 0fd0eb21 Blue Swirl
#define CMD_PAD      0x18
122 5ad6bb97 blueswir1
#define CMD_SATN     0x1a
123 5e1e0a3b Blue Swirl
#define CMD_SEL      0x41
124 5ad6bb97 blueswir1
#define CMD_SELATN   0x42
125 5ad6bb97 blueswir1
#define CMD_SELATNS  0x43
126 5ad6bb97 blueswir1
#define CMD_ENSEL    0x44
127 5ad6bb97 blueswir1
128 2f275b8f bellard
#define STAT_DO 0x00
129 2f275b8f bellard
#define STAT_DI 0x01
130 2f275b8f bellard
#define STAT_CD 0x02
131 2f275b8f bellard
#define STAT_ST 0x03
132 8dea1dd4 blueswir1
#define STAT_MO 0x06
133 8dea1dd4 blueswir1
#define STAT_MI 0x07
134 5ad6bb97 blueswir1
#define STAT_PIO_MASK 0x06
135 2f275b8f bellard
136 2f275b8f bellard
#define STAT_TC 0x10
137 4d611c9a pbrook
#define STAT_PE 0x20
138 4d611c9a pbrook
#define STAT_GE 0x40
139 c73f96fd blueswir1
#define STAT_INT 0x80
140 2f275b8f bellard
141 8dea1dd4 blueswir1
#define BUSID_DID 0x07
142 8dea1dd4 blueswir1
143 2f275b8f bellard
#define INTR_FC 0x08
144 2f275b8f bellard
#define INTR_BS 0x10
145 2f275b8f bellard
#define INTR_DC 0x20
146 9e61bde5 bellard
#define INTR_RST 0x80
147 2f275b8f bellard
148 2f275b8f bellard
#define SEQ_0 0x0
149 2f275b8f bellard
#define SEQ_CD 0x4
150 2f275b8f bellard
151 5ad6bb97 blueswir1
#define CFG1_RESREPT 0x40
152 5ad6bb97 blueswir1
153 5ad6bb97 blueswir1
#define TCHI_FAS100A 0x4
154 5ad6bb97 blueswir1
155 c73f96fd blueswir1
static void esp_raise_irq(ESPState *s)
156 c73f96fd blueswir1
{
157 c73f96fd blueswir1
    if (!(s->rregs[ESP_RSTAT] & STAT_INT)) {
158 c73f96fd blueswir1
        s->rregs[ESP_RSTAT] |= STAT_INT;
159 c73f96fd blueswir1
        qemu_irq_raise(s->irq);
160 dca47edd Blue Swirl
        DPRINTF("Raise IRQ\n");
161 c73f96fd blueswir1
    }
162 c73f96fd blueswir1
}
163 c73f96fd blueswir1
164 c73f96fd blueswir1
static void esp_lower_irq(ESPState *s)
165 c73f96fd blueswir1
{
166 c73f96fd blueswir1
    if (s->rregs[ESP_RSTAT] & STAT_INT) {
167 c73f96fd blueswir1
        s->rregs[ESP_RSTAT] &= ~STAT_INT;
168 c73f96fd blueswir1
        qemu_irq_lower(s->irq);
169 dca47edd Blue Swirl
        DPRINTF("Lower IRQ\n");
170 c73f96fd blueswir1
    }
171 c73f96fd blueswir1
}
172 c73f96fd blueswir1
173 73d74342 Blue Swirl
static void esp_dma_enable(void *opaque, int irq, int level)
174 73d74342 Blue Swirl
{
175 73d74342 Blue Swirl
    DeviceState *d = opaque;
176 73d74342 Blue Swirl
    ESPState *s = container_of(d, ESPState, busdev.qdev);
177 73d74342 Blue Swirl
178 73d74342 Blue Swirl
    if (level) {
179 73d74342 Blue Swirl
        s->dma_enabled = 1;
180 73d74342 Blue Swirl
        DPRINTF("Raise enable\n");
181 73d74342 Blue Swirl
        if (s->dma_cb) {
182 73d74342 Blue Swirl
            s->dma_cb(s);
183 73d74342 Blue Swirl
            s->dma_cb = NULL;
184 73d74342 Blue Swirl
        }
185 73d74342 Blue Swirl
    } else {
186 73d74342 Blue Swirl
        DPRINTF("Lower enable\n");
187 73d74342 Blue Swirl
        s->dma_enabled = 0;
188 73d74342 Blue Swirl
    }
189 73d74342 Blue Swirl
}
190 73d74342 Blue Swirl
191 94d3f98a Paolo Bonzini
static void esp_request_cancelled(SCSIRequest *req)
192 94d3f98a Paolo Bonzini
{
193 94d3f98a Paolo Bonzini
    ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent);
194 94d3f98a Paolo Bonzini
195 94d3f98a Paolo Bonzini
    if (req == s->current_req) {
196 94d3f98a Paolo Bonzini
        scsi_req_unref(s->current_req);
197 94d3f98a Paolo Bonzini
        s->current_req = NULL;
198 94d3f98a Paolo Bonzini
        s->current_dev = NULL;
199 94d3f98a Paolo Bonzini
    }
200 94d3f98a Paolo Bonzini
}
201 94d3f98a Paolo Bonzini
202 22548760 blueswir1
static uint32_t get_cmd(ESPState *s, uint8_t *buf)
203 2f275b8f bellard
{
204 a917d384 pbrook
    uint32_t dmalen;
205 2f275b8f bellard
    int target;
206 2f275b8f bellard
207 8dea1dd4 blueswir1
    target = s->wregs[ESP_WBUSID] & BUSID_DID;
208 4f6200f0 bellard
    if (s->dma) {
209 fc4d65da blueswir1
        dmalen = s->rregs[ESP_TCLO] | (s->rregs[ESP_TCMID] << 8);
210 8b17de88 blueswir1
        s->dma_memory_read(s->dma_opaque, buf, dmalen);
211 4f6200f0 bellard
    } else {
212 fc4d65da blueswir1
        dmalen = s->ti_size;
213 fc4d65da blueswir1
        memcpy(buf, s->ti_buf, dmalen);
214 f930d07e blueswir1
        buf[0] = 0;
215 4f6200f0 bellard
    }
216 fc4d65da blueswir1
    DPRINTF("get_cmd: len %d target %d\n", dmalen, target);
217 2e5d83bb pbrook
218 2f275b8f bellard
    s->ti_size = 0;
219 4f6200f0 bellard
    s->ti_rptr = 0;
220 4f6200f0 bellard
    s->ti_wptr = 0;
221 2f275b8f bellard
222 a917d384 pbrook
    if (s->current_dev) {
223 a917d384 pbrook
        /* Started a new command before the old one finished.  Cancel it.  */
224 94d3f98a Paolo Bonzini
        scsi_req_cancel(s->current_req);
225 a917d384 pbrook
        s->async_len = 0;
226 a917d384 pbrook
    }
227 a917d384 pbrook
228 ca9c39fa Gerd Hoffmann
    if (target >= ESP_MAX_DEVS || !s->bus.devs[target]) {
229 2e5d83bb pbrook
        // No such drive
230 c73f96fd blueswir1
        s->rregs[ESP_RSTAT] = 0;
231 5ad6bb97 blueswir1
        s->rregs[ESP_RINTR] = INTR_DC;
232 5ad6bb97 blueswir1
        s->rregs[ESP_RSEQ] = SEQ_0;
233 c73f96fd blueswir1
        esp_raise_irq(s);
234 f930d07e blueswir1
        return 0;
235 2f275b8f bellard
    }
236 ca9c39fa Gerd Hoffmann
    s->current_dev = s->bus.devs[target];
237 9f149aa9 pbrook
    return dmalen;
238 9f149aa9 pbrook
}
239 9f149aa9 pbrook
240 f2818f22 Artyom Tarasenko
static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid)
241 9f149aa9 pbrook
{
242 9f149aa9 pbrook
    int32_t datalen;
243 9f149aa9 pbrook
    int lun;
244 9f149aa9 pbrook
245 f2818f22 Artyom Tarasenko
    DPRINTF("do_busid_cmd: busid 0x%x\n", busid);
246 f2818f22 Artyom Tarasenko
    lun = busid & 7;
247 43a2b339 Paolo Bonzini
    s->current_req = scsi_req_new(s->current_dev, 0, lun);
248 fc4f0754 Paolo Bonzini
    datalen = scsi_req_enqueue(s->current_req, buf);
249 67e999be bellard
    s->ti_size = datalen;
250 67e999be bellard
    if (datalen != 0) {
251 c73f96fd blueswir1
        s->rregs[ESP_RSTAT] = STAT_TC;
252 a917d384 pbrook
        s->dma_left = 0;
253 6787f5fa pbrook
        s->dma_counter = 0;
254 2e5d83bb pbrook
        if (datalen > 0) {
255 5ad6bb97 blueswir1
            s->rregs[ESP_RSTAT] |= STAT_DI;
256 2e5d83bb pbrook
        } else {
257 5ad6bb97 blueswir1
            s->rregs[ESP_RSTAT] |= STAT_DO;
258 b9788fc4 bellard
        }
259 ad3376cc Paolo Bonzini
        scsi_req_continue(s->current_req);
260 2f275b8f bellard
    }
261 5ad6bb97 blueswir1
    s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
262 5ad6bb97 blueswir1
    s->rregs[ESP_RSEQ] = SEQ_CD;
263 c73f96fd blueswir1
    esp_raise_irq(s);
264 2f275b8f bellard
}
265 2f275b8f bellard
266 f2818f22 Artyom Tarasenko
static void do_cmd(ESPState *s, uint8_t *buf)
267 f2818f22 Artyom Tarasenko
{
268 f2818f22 Artyom Tarasenko
    uint8_t busid = buf[0];
269 f2818f22 Artyom Tarasenko
270 f2818f22 Artyom Tarasenko
    do_busid_cmd(s, &buf[1], busid);
271 f2818f22 Artyom Tarasenko
}
272 f2818f22 Artyom Tarasenko
273 9f149aa9 pbrook
static void handle_satn(ESPState *s)
274 9f149aa9 pbrook
{
275 9f149aa9 pbrook
    uint8_t buf[32];
276 9f149aa9 pbrook
    int len;
277 9f149aa9 pbrook
278 73d74342 Blue Swirl
    if (!s->dma_enabled) {
279 73d74342 Blue Swirl
        s->dma_cb = handle_satn;
280 73d74342 Blue Swirl
        return;
281 73d74342 Blue Swirl
    }
282 9f149aa9 pbrook
    len = get_cmd(s, buf);
283 9f149aa9 pbrook
    if (len)
284 9f149aa9 pbrook
        do_cmd(s, buf);
285 9f149aa9 pbrook
}
286 9f149aa9 pbrook
287 f2818f22 Artyom Tarasenko
static void handle_s_without_atn(ESPState *s)
288 f2818f22 Artyom Tarasenko
{
289 f2818f22 Artyom Tarasenko
    uint8_t buf[32];
290 f2818f22 Artyom Tarasenko
    int len;
291 f2818f22 Artyom Tarasenko
292 73d74342 Blue Swirl
    if (!s->dma_enabled) {
293 73d74342 Blue Swirl
        s->dma_cb = handle_s_without_atn;
294 73d74342 Blue Swirl
        return;
295 73d74342 Blue Swirl
    }
296 f2818f22 Artyom Tarasenko
    len = get_cmd(s, buf);
297 f2818f22 Artyom Tarasenko
    if (len) {
298 f2818f22 Artyom Tarasenko
        do_busid_cmd(s, buf, 0);
299 f2818f22 Artyom Tarasenko
    }
300 f2818f22 Artyom Tarasenko
}
301 f2818f22 Artyom Tarasenko
302 9f149aa9 pbrook
static void handle_satn_stop(ESPState *s)
303 9f149aa9 pbrook
{
304 73d74342 Blue Swirl
    if (!s->dma_enabled) {
305 73d74342 Blue Swirl
        s->dma_cb = handle_satn_stop;
306 73d74342 Blue Swirl
        return;
307 73d74342 Blue Swirl
    }
308 9f149aa9 pbrook
    s->cmdlen = get_cmd(s, s->cmdbuf);
309 9f149aa9 pbrook
    if (s->cmdlen) {
310 9f149aa9 pbrook
        DPRINTF("Set ATN & Stop: cmdlen %d\n", s->cmdlen);
311 9f149aa9 pbrook
        s->do_cmd = 1;
312 c73f96fd blueswir1
        s->rregs[ESP_RSTAT] = STAT_TC | STAT_CD;
313 5ad6bb97 blueswir1
        s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
314 5ad6bb97 blueswir1
        s->rregs[ESP_RSEQ] = SEQ_CD;
315 c73f96fd blueswir1
        esp_raise_irq(s);
316 9f149aa9 pbrook
    }
317 9f149aa9 pbrook
}
318 9f149aa9 pbrook
319 0fc5c15a pbrook
static void write_response(ESPState *s)
320 2f275b8f bellard
{
321 0fc5c15a pbrook
    DPRINTF("Transfer status (sense=%d)\n", s->sense);
322 0fc5c15a pbrook
    s->ti_buf[0] = s->sense;
323 0fc5c15a pbrook
    s->ti_buf[1] = 0;
324 4f6200f0 bellard
    if (s->dma) {
325 8b17de88 blueswir1
        s->dma_memory_write(s->dma_opaque, s->ti_buf, 2);
326 c73f96fd blueswir1
        s->rregs[ESP_RSTAT] = STAT_TC | STAT_ST;
327 5ad6bb97 blueswir1
        s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
328 5ad6bb97 blueswir1
        s->rregs[ESP_RSEQ] = SEQ_CD;
329 4f6200f0 bellard
    } else {
330 f930d07e blueswir1
        s->ti_size = 2;
331 f930d07e blueswir1
        s->ti_rptr = 0;
332 f930d07e blueswir1
        s->ti_wptr = 0;
333 5ad6bb97 blueswir1
        s->rregs[ESP_RFLAGS] = 2;
334 4f6200f0 bellard
    }
335 c73f96fd blueswir1
    esp_raise_irq(s);
336 2f275b8f bellard
}
337 4f6200f0 bellard
338 a917d384 pbrook
static void esp_dma_done(ESPState *s)
339 a917d384 pbrook
{
340 c73f96fd blueswir1
    s->rregs[ESP_RSTAT] |= STAT_TC;
341 5ad6bb97 blueswir1
    s->rregs[ESP_RINTR] = INTR_BS;
342 5ad6bb97 blueswir1
    s->rregs[ESP_RSEQ] = 0;
343 5ad6bb97 blueswir1
    s->rregs[ESP_RFLAGS] = 0;
344 5ad6bb97 blueswir1
    s->rregs[ESP_TCLO] = 0;
345 5ad6bb97 blueswir1
    s->rregs[ESP_TCMID] = 0;
346 c73f96fd blueswir1
    esp_raise_irq(s);
347 a917d384 pbrook
}
348 a917d384 pbrook
349 4d611c9a pbrook
static void esp_do_dma(ESPState *s)
350 4d611c9a pbrook
{
351 67e999be bellard
    uint32_t len;
352 4d611c9a pbrook
    int to_device;
353 a917d384 pbrook
354 67e999be bellard
    to_device = (s->ti_size < 0);
355 a917d384 pbrook
    len = s->dma_left;
356 4d611c9a pbrook
    if (s->do_cmd) {
357 4d611c9a pbrook
        DPRINTF("command len %d + %d\n", s->cmdlen, len);
358 8b17de88 blueswir1
        s->dma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len);
359 4d611c9a pbrook
        s->ti_size = 0;
360 4d611c9a pbrook
        s->cmdlen = 0;
361 4d611c9a pbrook
        s->do_cmd = 0;
362 4d611c9a pbrook
        do_cmd(s, s->cmdbuf);
363 4d611c9a pbrook
        return;
364 a917d384 pbrook
    }
365 a917d384 pbrook
    if (s->async_len == 0) {
366 a917d384 pbrook
        /* Defer until data is available.  */
367 a917d384 pbrook
        return;
368 a917d384 pbrook
    }
369 a917d384 pbrook
    if (len > s->async_len) {
370 a917d384 pbrook
        len = s->async_len;
371 a917d384 pbrook
    }
372 a917d384 pbrook
    if (to_device) {
373 8b17de88 blueswir1
        s->dma_memory_read(s->dma_opaque, s->async_buf, len);
374 4d611c9a pbrook
    } else {
375 8b17de88 blueswir1
        s->dma_memory_write(s->dma_opaque, s->async_buf, len);
376 a917d384 pbrook
    }
377 a917d384 pbrook
    s->dma_left -= len;
378 a917d384 pbrook
    s->async_buf += len;
379 a917d384 pbrook
    s->async_len -= len;
380 6787f5fa pbrook
    if (to_device)
381 6787f5fa pbrook
        s->ti_size += len;
382 6787f5fa pbrook
    else
383 6787f5fa pbrook
        s->ti_size -= len;
384 a917d384 pbrook
    if (s->async_len == 0) {
385 ad3376cc Paolo Bonzini
        scsi_req_continue(s->current_req);
386 ad3376cc Paolo Bonzini
        /* If there is still data to be read from the device then
387 ad3376cc Paolo Bonzini
           complete the DMA operation immediately.  Otherwise defer
388 ad3376cc Paolo Bonzini
           until the scsi layer has completed.  */
389 ad3376cc Paolo Bonzini
        if (to_device || s->dma_left != 0 || s->ti_size == 0) {
390 ad3376cc Paolo Bonzini
            return;
391 4d611c9a pbrook
        }
392 a917d384 pbrook
    }
393 ad3376cc Paolo Bonzini
394 ad3376cc Paolo Bonzini
    /* Partially filled a scsi buffer. Complete immediately.  */
395 ad3376cc Paolo Bonzini
    esp_dma_done(s);
396 4d611c9a pbrook
}
397 4d611c9a pbrook
398 5c6c0e51 Hannes Reinecke
static void esp_command_complete(SCSIRequest *req, int reason, uint32_t arg)
399 2e5d83bb pbrook
{
400 5c6c0e51 Hannes Reinecke
    ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent);
401 2e5d83bb pbrook
402 4d611c9a pbrook
    if (reason == SCSI_REASON_DONE) {
403 4d611c9a pbrook
        DPRINTF("SCSI Command complete\n");
404 4d611c9a pbrook
        if (s->ti_size != 0)
405 4d611c9a pbrook
            DPRINTF("SCSI command completed unexpectedly\n");
406 4d611c9a pbrook
        s->ti_size = 0;
407 a917d384 pbrook
        s->dma_left = 0;
408 a917d384 pbrook
        s->async_len = 0;
409 a917d384 pbrook
        if (arg)
410 4d611c9a pbrook
            DPRINTF("Command failed\n");
411 a917d384 pbrook
        s->sense = arg;
412 5ad6bb97 blueswir1
        s->rregs[ESP_RSTAT] = STAT_ST;
413 a917d384 pbrook
        esp_dma_done(s);
414 5c6c0e51 Hannes Reinecke
        if (s->current_req) {
415 5c6c0e51 Hannes Reinecke
            scsi_req_unref(s->current_req);
416 5c6c0e51 Hannes Reinecke
            s->current_req = NULL;
417 5c6c0e51 Hannes Reinecke
            s->current_dev = NULL;
418 5c6c0e51 Hannes Reinecke
        }
419 4d611c9a pbrook
    } else {
420 4d611c9a pbrook
        DPRINTF("transfer %d/%d\n", s->dma_left, s->ti_size);
421 a917d384 pbrook
        s->async_len = arg;
422 5c6c0e51 Hannes Reinecke
        s->async_buf = s->current_dev->info->get_buf(req);
423 6787f5fa pbrook
        if (s->dma_left) {
424 a917d384 pbrook
            esp_do_dma(s);
425 6787f5fa pbrook
        } else if (s->dma_counter != 0 && s->ti_size <= 0) {
426 6787f5fa pbrook
            /* If this was the last part of a DMA transfer then the
427 6787f5fa pbrook
               completion interrupt is deferred to here.  */
428 6787f5fa pbrook
            esp_dma_done(s);
429 6787f5fa pbrook
        }
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 db59203d pbrook
    DPRINTF("Transfer Information len %d\n", 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 9f149aa9 pbrook
        DPRINTF("command len %d\n", 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 c227f099 Anthony Liguori
static uint32_t esp_mem_readb(void *opaque, target_phys_addr_t addr)
509 6f7e9aec bellard
{
510 6f7e9aec bellard
    ESPState *s = opaque;
511 2814df28 Blue Swirl
    uint32_t saddr, old_val;
512 6f7e9aec bellard
513 e64d7d59 blueswir1
    saddr = addr >> s->it_shift;
514 9e61bde5 bellard
    DPRINTF("read reg[%d]: 0x%2.2x\n", saddr, s->rregs[saddr]);
515 6f7e9aec bellard
    switch (saddr) {
516 5ad6bb97 blueswir1
    case ESP_FIFO:
517 f930d07e blueswir1
        if (s->ti_size > 0) {
518 f930d07e blueswir1
            s->ti_size--;
519 5ad6bb97 blueswir1
            if ((s->rregs[ESP_RSTAT] & STAT_PIO_MASK) == 0) {
520 8dea1dd4 blueswir1
                /* Data out.  */
521 8dea1dd4 blueswir1
                ESP_ERROR("PIO data read not implemented\n");
522 5ad6bb97 blueswir1
                s->rregs[ESP_FIFO] = 0;
523 2e5d83bb pbrook
            } else {
524 5ad6bb97 blueswir1
                s->rregs[ESP_FIFO] = s->ti_buf[s->ti_rptr++];
525 2e5d83bb pbrook
            }
526 c73f96fd blueswir1
            esp_raise_irq(s);
527 f930d07e blueswir1
        }
528 f930d07e blueswir1
        if (s->ti_size == 0) {
529 4f6200f0 bellard
            s->ti_rptr = 0;
530 4f6200f0 bellard
            s->ti_wptr = 0;
531 4f6200f0 bellard
        }
532 f930d07e blueswir1
        break;
533 5ad6bb97 blueswir1
    case ESP_RINTR:
534 2814df28 Blue Swirl
        /* Clear sequence step, interrupt register and all status bits
535 2814df28 Blue Swirl
           except TC */
536 2814df28 Blue Swirl
        old_val = s->rregs[ESP_RINTR];
537 2814df28 Blue Swirl
        s->rregs[ESP_RINTR] = 0;
538 2814df28 Blue Swirl
        s->rregs[ESP_RSTAT] &= ~STAT_TC;
539 2814df28 Blue Swirl
        s->rregs[ESP_RSEQ] = SEQ_CD;
540 c73f96fd blueswir1
        esp_lower_irq(s);
541 2814df28 Blue Swirl
542 2814df28 Blue Swirl
        return old_val;
543 6f7e9aec bellard
    default:
544 f930d07e blueswir1
        break;
545 6f7e9aec bellard
    }
546 2f275b8f bellard
    return s->rregs[saddr];
547 6f7e9aec bellard
}
548 6f7e9aec bellard
549 c227f099 Anthony Liguori
static void esp_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
550 6f7e9aec bellard
{
551 6f7e9aec bellard
    ESPState *s = opaque;
552 6f7e9aec bellard
    uint32_t saddr;
553 6f7e9aec bellard
554 e64d7d59 blueswir1
    saddr = addr >> s->it_shift;
555 5ad6bb97 blueswir1
    DPRINTF("write reg[%d]: 0x%2.2x -> 0x%2.2x\n", saddr, s->wregs[saddr],
556 5ad6bb97 blueswir1
            val);
557 6f7e9aec bellard
    switch (saddr) {
558 5ad6bb97 blueswir1
    case ESP_TCLO:
559 5ad6bb97 blueswir1
    case ESP_TCMID:
560 5ad6bb97 blueswir1
        s->rregs[ESP_RSTAT] &= ~STAT_TC;
561 4f6200f0 bellard
        break;
562 5ad6bb97 blueswir1
    case ESP_FIFO:
563 9f149aa9 pbrook
        if (s->do_cmd) {
564 9f149aa9 pbrook
            s->cmdbuf[s->cmdlen++] = val & 0xff;
565 8dea1dd4 blueswir1
        } else if (s->ti_size == TI_BUFSZ - 1) {
566 8dea1dd4 blueswir1
            ESP_ERROR("fifo overrun\n");
567 2e5d83bb pbrook
        } else {
568 2e5d83bb pbrook
            s->ti_size++;
569 2e5d83bb pbrook
            s->ti_buf[s->ti_wptr++] = val & 0xff;
570 2e5d83bb pbrook
        }
571 f930d07e blueswir1
        break;
572 5ad6bb97 blueswir1
    case ESP_CMD:
573 4f6200f0 bellard
        s->rregs[saddr] = val;
574 5ad6bb97 blueswir1
        if (val & CMD_DMA) {
575 f930d07e blueswir1
            s->dma = 1;
576 6787f5fa pbrook
            /* Reload DMA counter.  */
577 5ad6bb97 blueswir1
            s->rregs[ESP_TCLO] = s->wregs[ESP_TCLO];
578 5ad6bb97 blueswir1
            s->rregs[ESP_TCMID] = s->wregs[ESP_TCMID];
579 f930d07e blueswir1
        } else {
580 f930d07e blueswir1
            s->dma = 0;
581 f930d07e blueswir1
        }
582 5ad6bb97 blueswir1
        switch(val & CMD_CMD) {
583 5ad6bb97 blueswir1
        case CMD_NOP:
584 f930d07e blueswir1
            DPRINTF("NOP (%2.2x)\n", val);
585 f930d07e blueswir1
            break;
586 5ad6bb97 blueswir1
        case CMD_FLUSH:
587 f930d07e blueswir1
            DPRINTF("Flush FIFO (%2.2x)\n", val);
588 9e61bde5 bellard
            //s->ti_size = 0;
589 5ad6bb97 blueswir1
            s->rregs[ESP_RINTR] = INTR_FC;
590 5ad6bb97 blueswir1
            s->rregs[ESP_RSEQ] = 0;
591 a214c598 blueswir1
            s->rregs[ESP_RFLAGS] = 0;
592 f930d07e blueswir1
            break;
593 5ad6bb97 blueswir1
        case CMD_RESET:
594 f930d07e blueswir1
            DPRINTF("Chip reset (%2.2x)\n", val);
595 85948643 Blue Swirl
            esp_soft_reset(&s->busdev.qdev);
596 f930d07e blueswir1
            break;
597 5ad6bb97 blueswir1
        case CMD_BUSRESET:
598 f930d07e blueswir1
            DPRINTF("Bus reset (%2.2x)\n", val);
599 5ad6bb97 blueswir1
            s->rregs[ESP_RINTR] = INTR_RST;
600 5ad6bb97 blueswir1
            if (!(s->wregs[ESP_CFG1] & CFG1_RESREPT)) {
601 c73f96fd blueswir1
                esp_raise_irq(s);
602 9e61bde5 bellard
            }
603 f930d07e blueswir1
            break;
604 5ad6bb97 blueswir1
        case CMD_TI:
605 f930d07e blueswir1
            handle_ti(s);
606 f930d07e blueswir1
            break;
607 5ad6bb97 blueswir1
        case CMD_ICCS:
608 f930d07e blueswir1
            DPRINTF("Initiator Command Complete Sequence (%2.2x)\n", val);
609 f930d07e blueswir1
            write_response(s);
610 4bf5801d blueswir1
            s->rregs[ESP_RINTR] = INTR_FC;
611 4bf5801d blueswir1
            s->rregs[ESP_RSTAT] |= STAT_MI;
612 f930d07e blueswir1
            break;
613 5ad6bb97 blueswir1
        case CMD_MSGACC:
614 f930d07e blueswir1
            DPRINTF("Message Accepted (%2.2x)\n", val);
615 5ad6bb97 blueswir1
            s->rregs[ESP_RINTR] = INTR_DC;
616 5ad6bb97 blueswir1
            s->rregs[ESP_RSEQ] = 0;
617 4e2a68c1 Artyom Tarasenko
            s->rregs[ESP_RFLAGS] = 0;
618 4e2a68c1 Artyom Tarasenko
            esp_raise_irq(s);
619 f930d07e blueswir1
            break;
620 0fd0eb21 Blue Swirl
        case CMD_PAD:
621 0fd0eb21 Blue Swirl
            DPRINTF("Transfer padding (%2.2x)\n", val);
622 0fd0eb21 Blue Swirl
            s->rregs[ESP_RSTAT] = STAT_TC;
623 0fd0eb21 Blue Swirl
            s->rregs[ESP_RINTR] = INTR_FC;
624 0fd0eb21 Blue Swirl
            s->rregs[ESP_RSEQ] = 0;
625 0fd0eb21 Blue Swirl
            break;
626 5ad6bb97 blueswir1
        case CMD_SATN:
627 f930d07e blueswir1
            DPRINTF("Set ATN (%2.2x)\n", val);
628 f930d07e blueswir1
            break;
629 5e1e0a3b Blue Swirl
        case CMD_SEL:
630 5e1e0a3b Blue Swirl
            DPRINTF("Select without ATN (%2.2x)\n", val);
631 f2818f22 Artyom Tarasenko
            handle_s_without_atn(s);
632 5e1e0a3b Blue Swirl
            break;
633 5ad6bb97 blueswir1
        case CMD_SELATN:
634 5e1e0a3b Blue Swirl
            DPRINTF("Select with ATN (%2.2x)\n", val);
635 f930d07e blueswir1
            handle_satn(s);
636 f930d07e blueswir1
            break;
637 5ad6bb97 blueswir1
        case CMD_SELATNS:
638 5e1e0a3b Blue Swirl
            DPRINTF("Select with ATN & stop (%2.2x)\n", val);
639 f930d07e blueswir1
            handle_satn_stop(s);
640 f930d07e blueswir1
            break;
641 5ad6bb97 blueswir1
        case CMD_ENSEL:
642 74ec6048 blueswir1
            DPRINTF("Enable selection (%2.2x)\n", val);
643 e3926838 blueswir1
            s->rregs[ESP_RINTR] = 0;
644 74ec6048 blueswir1
            break;
645 f930d07e blueswir1
        default:
646 8dea1dd4 blueswir1
            ESP_ERROR("Unhandled ESP command (%2.2x)\n", val);
647 f930d07e blueswir1
            break;
648 f930d07e blueswir1
        }
649 f930d07e blueswir1
        break;
650 5ad6bb97 blueswir1
    case ESP_WBUSID ... ESP_WSYNO:
651 f930d07e blueswir1
        break;
652 5ad6bb97 blueswir1
    case ESP_CFG1:
653 4f6200f0 bellard
        s->rregs[saddr] = val;
654 4f6200f0 bellard
        break;
655 5ad6bb97 blueswir1
    case ESP_WCCF ... ESP_WTEST:
656 4f6200f0 bellard
        break;
657 b44c08fa blueswir1
    case ESP_CFG2 ... ESP_RES4:
658 4f6200f0 bellard
        s->rregs[saddr] = val;
659 4f6200f0 bellard
        break;
660 6f7e9aec bellard
    default:
661 8dea1dd4 blueswir1
        ESP_ERROR("invalid write of 0x%02x at [0x%x]\n", val, saddr);
662 8dea1dd4 blueswir1
        return;
663 6f7e9aec bellard
    }
664 2f275b8f bellard
    s->wregs[saddr] = val;
665 6f7e9aec bellard
}
666 6f7e9aec bellard
667 d60efc6b Blue Swirl
static CPUReadMemoryFunc * const esp_mem_read[3] = {
668 6f7e9aec bellard
    esp_mem_readb,
669 7c560456 blueswir1
    NULL,
670 7c560456 blueswir1
    NULL,
671 6f7e9aec bellard
};
672 6f7e9aec bellard
673 d60efc6b Blue Swirl
static CPUWriteMemoryFunc * const esp_mem_write[3] = {
674 6f7e9aec bellard
    esp_mem_writeb,
675 7c560456 blueswir1
    NULL,
676 daa41b00 blueswir1
    esp_mem_writeb,
677 6f7e9aec bellard
};
678 6f7e9aec bellard
679 cc9952f3 Blue Swirl
static const VMStateDescription vmstate_esp = {
680 cc9952f3 Blue Swirl
    .name ="esp",
681 cc9952f3 Blue Swirl
    .version_id = 3,
682 cc9952f3 Blue Swirl
    .minimum_version_id = 3,
683 cc9952f3 Blue Swirl
    .minimum_version_id_old = 3,
684 cc9952f3 Blue Swirl
    .fields      = (VMStateField []) {
685 cc9952f3 Blue Swirl
        VMSTATE_BUFFER(rregs, ESPState),
686 cc9952f3 Blue Swirl
        VMSTATE_BUFFER(wregs, ESPState),
687 cc9952f3 Blue Swirl
        VMSTATE_INT32(ti_size, ESPState),
688 cc9952f3 Blue Swirl
        VMSTATE_UINT32(ti_rptr, ESPState),
689 cc9952f3 Blue Swirl
        VMSTATE_UINT32(ti_wptr, ESPState),
690 cc9952f3 Blue Swirl
        VMSTATE_BUFFER(ti_buf, ESPState),
691 cc9952f3 Blue Swirl
        VMSTATE_UINT32(sense, ESPState),
692 cc9952f3 Blue Swirl
        VMSTATE_UINT32(dma, ESPState),
693 cc9952f3 Blue Swirl
        VMSTATE_BUFFER(cmdbuf, ESPState),
694 cc9952f3 Blue Swirl
        VMSTATE_UINT32(cmdlen, ESPState),
695 cc9952f3 Blue Swirl
        VMSTATE_UINT32(do_cmd, ESPState),
696 cc9952f3 Blue Swirl
        VMSTATE_UINT32(dma_left, ESPState),
697 cc9952f3 Blue Swirl
        VMSTATE_END_OF_LIST()
698 cc9952f3 Blue Swirl
    }
699 cc9952f3 Blue Swirl
};
700 6f7e9aec bellard
701 c227f099 Anthony Liguori
void esp_init(target_phys_addr_t espaddr, int it_shift,
702 ff9868ec Blue Swirl
              ESPDMAMemoryReadWriteFunc dma_memory_read,
703 ff9868ec Blue Swirl
              ESPDMAMemoryReadWriteFunc dma_memory_write,
704 73d74342 Blue Swirl
              void *dma_opaque, qemu_irq irq, qemu_irq *reset,
705 73d74342 Blue Swirl
              qemu_irq *dma_enable)
706 6f7e9aec bellard
{
707 cfb9de9c Paul Brook
    DeviceState *dev;
708 cfb9de9c Paul Brook
    SysBusDevice *s;
709 ee6847d1 Gerd Hoffmann
    ESPState *esp;
710 cfb9de9c Paul Brook
711 cfb9de9c Paul Brook
    dev = qdev_create(NULL, "esp");
712 ee6847d1 Gerd Hoffmann
    esp = DO_UPCAST(ESPState, busdev.qdev, dev);
713 ee6847d1 Gerd Hoffmann
    esp->dma_memory_read = dma_memory_read;
714 ee6847d1 Gerd Hoffmann
    esp->dma_memory_write = dma_memory_write;
715 ee6847d1 Gerd Hoffmann
    esp->dma_opaque = dma_opaque;
716 ee6847d1 Gerd Hoffmann
    esp->it_shift = it_shift;
717 73d74342 Blue Swirl
    /* XXX for now until rc4030 has been changed to use DMA enable signal */
718 73d74342 Blue Swirl
    esp->dma_enabled = 1;
719 e23a1b33 Markus Armbruster
    qdev_init_nofail(dev);
720 cfb9de9c Paul Brook
    s = sysbus_from_qdev(dev);
721 cfb9de9c Paul Brook
    sysbus_connect_irq(s, 0, irq);
722 cfb9de9c Paul Brook
    sysbus_mmio_map(s, 0, espaddr);
723 74ff8d90 Blue Swirl
    *reset = qdev_get_gpio_in(dev, 0);
724 73d74342 Blue Swirl
    *dma_enable = qdev_get_gpio_in(dev, 1);
725 cfb9de9c Paul Brook
}
726 6f7e9aec bellard
727 cfdc1bb0 Paolo Bonzini
static const struct SCSIBusOps esp_scsi_ops = {
728 94d3f98a Paolo Bonzini
    .complete = esp_command_complete,
729 94d3f98a Paolo Bonzini
    .cancel = esp_request_cancelled
730 cfdc1bb0 Paolo Bonzini
};
731 cfdc1bb0 Paolo Bonzini
732 81a322d4 Gerd Hoffmann
static int esp_init1(SysBusDevice *dev)
733 cfb9de9c Paul Brook
{
734 cfb9de9c Paul Brook
    ESPState *s = FROM_SYSBUS(ESPState, dev);
735 cfb9de9c Paul Brook
    int esp_io_memory;
736 6f7e9aec bellard
737 cfb9de9c Paul Brook
    sysbus_init_irq(dev, &s->irq);
738 cfb9de9c Paul Brook
    assert(s->it_shift != -1);
739 6f7e9aec bellard
740 2507c12a Alexander Graf
    esp_io_memory = cpu_register_io_memory(esp_mem_read, esp_mem_write, s,
741 2507c12a Alexander Graf
                                           DEVICE_NATIVE_ENDIAN);
742 cfb9de9c Paul Brook
    sysbus_init_mmio(dev, ESP_REGS << s->it_shift, esp_io_memory);
743 6f7e9aec bellard
744 73d74342 Blue Swirl
    qdev_init_gpio_in(&dev->qdev, esp_gpio_demux, 2);
745 2d069bab blueswir1
746 cfdc1bb0 Paolo Bonzini
    scsi_bus_new(&s->bus, &dev->qdev, 0, ESP_MAX_DEVS, &esp_scsi_ops);
747 fa66b909 Markus Armbruster
    return scsi_bus_legacy_handle_cmdline(&s->bus);
748 67e999be bellard
}
749 cfb9de9c Paul Brook
750 63235df8 Blue Swirl
static SysBusDeviceInfo esp_info = {
751 63235df8 Blue Swirl
    .init = esp_init1,
752 63235df8 Blue Swirl
    .qdev.name  = "esp",
753 63235df8 Blue Swirl
    .qdev.size  = sizeof(ESPState),
754 63235df8 Blue Swirl
    .qdev.vmsd  = &vmstate_esp,
755 85948643 Blue Swirl
    .qdev.reset = esp_hard_reset,
756 63235df8 Blue Swirl
    .qdev.props = (Property[]) {
757 63235df8 Blue Swirl
        {.name = NULL}
758 63235df8 Blue Swirl
    }
759 63235df8 Blue Swirl
};
760 63235df8 Blue Swirl
761 cfb9de9c Paul Brook
static void esp_register_devices(void)
762 cfb9de9c Paul Brook
{
763 63235df8 Blue Swirl
    sysbus_register_withprop(&esp_info);
764 cfb9de9c Paul Brook
}
765 cfb9de9c Paul Brook
766 cfb9de9c Paul Brook
device_init(esp_register_devices)