Statistics
| Branch: | Revision:

root / hw / esp.c @ d60efc6b

History | View | Annotate | Download (19.2 kB)

1
/*
2
 * QEMU ESP/NCR53C9x emulation
3
 *
4
 * Copyright (c) 2005-2006 Fabrice Bellard
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24

    
25
#include "sysbus.h"
26
#include "scsi-disk.h"
27
#include "scsi.h"
28

    
29
/* debug ESP card */
30
//#define DEBUG_ESP
31

    
32
/*
33
 * On Sparc32, this is the ESP (NCR53C90) part of chip STP2000 (Master I/O),
34
 * also produced as NCR89C100. See
35
 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C100.txt
36
 * and
37
 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR53C9X.txt
38
 */
39

    
40
#ifdef DEBUG_ESP
41
#define DPRINTF(fmt, ...)                                       \
42
    do { printf("ESP: " fmt , ## __VA_ARGS__); } while (0)
43
#else
44
#define DPRINTF(fmt, ...) do {} while (0)
45
#endif
46

    
47
#define ESP_ERROR(fmt, ...)                                             \
48
    do { printf("ESP ERROR: %s: " fmt, __func__ , ## __VA_ARGS__); } while (0)
49

    
50
#define ESP_REGS 16
51
#define TI_BUFSZ 16
52

    
53
typedef struct ESPState ESPState;
54

    
55
struct ESPState {
56
    SysBusDevice busdev;
57
    uint32_t it_shift;
58
    qemu_irq irq;
59
    uint8_t rregs[ESP_REGS];
60
    uint8_t wregs[ESP_REGS];
61
    int32_t ti_size;
62
    uint32_t ti_rptr, ti_wptr;
63
    uint8_t ti_buf[TI_BUFSZ];
64
    uint32_t sense;
65
    uint32_t dma;
66
    SCSIDevice *scsi_dev[ESP_MAX_DEVS];
67
    SCSIDevice *current_dev;
68
    uint8_t cmdbuf[TI_BUFSZ];
69
    uint32_t cmdlen;
70
    uint32_t do_cmd;
71

    
72
    /* The amount of data left in the current DMA transfer.  */
73
    uint32_t dma_left;
74
    /* The size of the current DMA transfer.  Zero if no transfer is in
75
       progress.  */
76
    uint32_t dma_counter;
77
    uint8_t *async_buf;
78
    uint32_t async_len;
79

    
80
    espdma_memory_read_write dma_memory_read;
81
    espdma_memory_read_write dma_memory_write;
82
    void *dma_opaque;
83
};
84

    
85
#define ESP_TCLO   0x0
86
#define ESP_TCMID  0x1
87
#define ESP_FIFO   0x2
88
#define ESP_CMD    0x3
89
#define ESP_RSTAT  0x4
90
#define ESP_WBUSID 0x4
91
#define ESP_RINTR  0x5
92
#define ESP_WSEL   0x5
93
#define ESP_RSEQ   0x6
94
#define ESP_WSYNTP 0x6
95
#define ESP_RFLAGS 0x7
96
#define ESP_WSYNO  0x7
97
#define ESP_CFG1   0x8
98
#define ESP_RRES1  0x9
99
#define ESP_WCCF   0x9
100
#define ESP_RRES2  0xa
101
#define ESP_WTEST  0xa
102
#define ESP_CFG2   0xb
103
#define ESP_CFG3   0xc
104
#define ESP_RES3   0xd
105
#define ESP_TCHI   0xe
106
#define ESP_RES4   0xf
107

    
108
#define CMD_DMA 0x80
109
#define CMD_CMD 0x7f
110

    
111
#define CMD_NOP      0x00
112
#define CMD_FLUSH    0x01
113
#define CMD_RESET    0x02
114
#define CMD_BUSRESET 0x03
115
#define CMD_TI       0x10
116
#define CMD_ICCS     0x11
117
#define CMD_MSGACC   0x12
118
#define CMD_PAD      0x18
119
#define CMD_SATN     0x1a
120
#define CMD_SEL      0x41
121
#define CMD_SELATN   0x42
122
#define CMD_SELATNS  0x43
123
#define CMD_ENSEL    0x44
124

    
125
#define STAT_DO 0x00
126
#define STAT_DI 0x01
127
#define STAT_CD 0x02
128
#define STAT_ST 0x03
129
#define STAT_MO 0x06
130
#define STAT_MI 0x07
131
#define STAT_PIO_MASK 0x06
132

    
133
#define STAT_TC 0x10
134
#define STAT_PE 0x20
135
#define STAT_GE 0x40
136
#define STAT_INT 0x80
137

    
138
#define BUSID_DID 0x07
139

    
140
#define INTR_FC 0x08
141
#define INTR_BS 0x10
142
#define INTR_DC 0x20
143
#define INTR_RST 0x80
144

    
145
#define SEQ_0 0x0
146
#define SEQ_CD 0x4
147

    
148
#define CFG1_RESREPT 0x40
149

    
150
#define TCHI_FAS100A 0x4
151

    
152
static void esp_raise_irq(ESPState *s)
153
{
154
    if (!(s->rregs[ESP_RSTAT] & STAT_INT)) {
155
        s->rregs[ESP_RSTAT] |= STAT_INT;
156
        qemu_irq_raise(s->irq);
157
    }
158
}
159

    
160
static void esp_lower_irq(ESPState *s)
161
{
162
    if (s->rregs[ESP_RSTAT] & STAT_INT) {
163
        s->rregs[ESP_RSTAT] &= ~STAT_INT;
164
        qemu_irq_lower(s->irq);
165
    }
166
}
167

    
168
static uint32_t get_cmd(ESPState *s, uint8_t *buf)
169
{
170
    uint32_t dmalen;
171
    int target;
172

    
173
    target = s->wregs[ESP_WBUSID] & BUSID_DID;
174
    if (s->dma) {
175
        dmalen = s->rregs[ESP_TCLO] | (s->rregs[ESP_TCMID] << 8);
176
        s->dma_memory_read(s->dma_opaque, buf, dmalen);
177
    } else {
178
        dmalen = s->ti_size;
179
        memcpy(buf, s->ti_buf, dmalen);
180
        buf[0] = 0;
181
    }
182
    DPRINTF("get_cmd: len %d target %d\n", dmalen, target);
183

    
184
    s->ti_size = 0;
185
    s->ti_rptr = 0;
186
    s->ti_wptr = 0;
187

    
188
    if (s->current_dev) {
189
        /* Started a new command before the old one finished.  Cancel it.  */
190
        s->current_dev->cancel_io(s->current_dev, 0);
191
        s->async_len = 0;
192
    }
193

    
194
    if (target >= ESP_MAX_DEVS || !s->scsi_dev[target]) {
195
        // No such drive
196
        s->rregs[ESP_RSTAT] = 0;
197
        s->rregs[ESP_RINTR] = INTR_DC;
198
        s->rregs[ESP_RSEQ] = SEQ_0;
199
        esp_raise_irq(s);
200
        return 0;
201
    }
202
    s->current_dev = s->scsi_dev[target];
203
    return dmalen;
204
}
205

    
206
static void do_cmd(ESPState *s, uint8_t *buf)
207
{
208
    int32_t datalen;
209
    int lun;
210

    
211
    DPRINTF("do_cmd: busid 0x%x\n", buf[0]);
212
    lun = buf[0] & 7;
213
    datalen = s->current_dev->send_command(s->current_dev, 0, &buf[1], lun);
214
    s->ti_size = datalen;
215
    if (datalen != 0) {
216
        s->rregs[ESP_RSTAT] = STAT_TC;
217
        s->dma_left = 0;
218
        s->dma_counter = 0;
219
        if (datalen > 0) {
220
            s->rregs[ESP_RSTAT] |= STAT_DI;
221
            s->current_dev->read_data(s->current_dev, 0);
222
        } else {
223
            s->rregs[ESP_RSTAT] |= STAT_DO;
224
            s->current_dev->write_data(s->current_dev, 0);
225
        }
226
    }
227
    s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
228
    s->rregs[ESP_RSEQ] = SEQ_CD;
229
    esp_raise_irq(s);
230
}
231

    
232
static void handle_satn(ESPState *s)
233
{
234
    uint8_t buf[32];
235
    int len;
236

    
237
    len = get_cmd(s, buf);
238
    if (len)
239
        do_cmd(s, buf);
240
}
241

    
242
static void handle_satn_stop(ESPState *s)
243
{
244
    s->cmdlen = get_cmd(s, s->cmdbuf);
245
    if (s->cmdlen) {
246
        DPRINTF("Set ATN & Stop: cmdlen %d\n", s->cmdlen);
247
        s->do_cmd = 1;
248
        s->rregs[ESP_RSTAT] = STAT_TC | STAT_CD;
249
        s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
250
        s->rregs[ESP_RSEQ] = SEQ_CD;
251
        esp_raise_irq(s);
252
    }
253
}
254

    
255
static void write_response(ESPState *s)
256
{
257
    DPRINTF("Transfer status (sense=%d)\n", s->sense);
258
    s->ti_buf[0] = s->sense;
259
    s->ti_buf[1] = 0;
260
    if (s->dma) {
261
        s->dma_memory_write(s->dma_opaque, s->ti_buf, 2);
262
        s->rregs[ESP_RSTAT] = STAT_TC | STAT_ST;
263
        s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
264
        s->rregs[ESP_RSEQ] = SEQ_CD;
265
    } else {
266
        s->ti_size = 2;
267
        s->ti_rptr = 0;
268
        s->ti_wptr = 0;
269
        s->rregs[ESP_RFLAGS] = 2;
270
    }
271
    esp_raise_irq(s);
272
}
273

    
274
static void esp_dma_done(ESPState *s)
275
{
276
    s->rregs[ESP_RSTAT] |= STAT_TC;
277
    s->rregs[ESP_RINTR] = INTR_BS;
278
    s->rregs[ESP_RSEQ] = 0;
279
    s->rregs[ESP_RFLAGS] = 0;
280
    s->rregs[ESP_TCLO] = 0;
281
    s->rregs[ESP_TCMID] = 0;
282
    esp_raise_irq(s);
283
}
284

    
285
static void esp_do_dma(ESPState *s)
286
{
287
    uint32_t len;
288
    int to_device;
289

    
290
    to_device = (s->ti_size < 0);
291
    len = s->dma_left;
292
    if (s->do_cmd) {
293
        DPRINTF("command len %d + %d\n", s->cmdlen, len);
294
        s->dma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len);
295
        s->ti_size = 0;
296
        s->cmdlen = 0;
297
        s->do_cmd = 0;
298
        do_cmd(s, s->cmdbuf);
299
        return;
300
    }
301
    if (s->async_len == 0) {
302
        /* Defer until data is available.  */
303
        return;
304
    }
305
    if (len > s->async_len) {
306
        len = s->async_len;
307
    }
308
    if (to_device) {
309
        s->dma_memory_read(s->dma_opaque, s->async_buf, len);
310
    } else {
311
        s->dma_memory_write(s->dma_opaque, s->async_buf, len);
312
    }
313
    s->dma_left -= len;
314
    s->async_buf += len;
315
    s->async_len -= len;
316
    if (to_device)
317
        s->ti_size += len;
318
    else
319
        s->ti_size -= len;
320
    if (s->async_len == 0) {
321
        if (to_device) {
322
            // ti_size is negative
323
            s->current_dev->write_data(s->current_dev, 0);
324
        } else {
325
            s->current_dev->read_data(s->current_dev, 0);
326
            /* If there is still data to be read from the device then
327
               complete the DMA operation immediately.  Otherwise defer
328
               until the scsi layer has completed.  */
329
            if (s->dma_left == 0 && s->ti_size > 0) {
330
                esp_dma_done(s);
331
            }
332
        }
333
    } else {
334
        /* Partially filled a scsi buffer. Complete immediately.  */
335
        esp_dma_done(s);
336
    }
337
}
338

    
339
static void esp_command_complete(void *opaque, int reason, uint32_t tag,
340
                                 uint32_t arg)
341
{
342
    ESPState *s = (ESPState *)opaque;
343

    
344
    if (reason == SCSI_REASON_DONE) {
345
        DPRINTF("SCSI Command complete\n");
346
        if (s->ti_size != 0)
347
            DPRINTF("SCSI command completed unexpectedly\n");
348
        s->ti_size = 0;
349
        s->dma_left = 0;
350
        s->async_len = 0;
351
        if (arg)
352
            DPRINTF("Command failed\n");
353
        s->sense = arg;
354
        s->rregs[ESP_RSTAT] = STAT_ST;
355
        esp_dma_done(s);
356
        s->current_dev = NULL;
357
    } else {
358
        DPRINTF("transfer %d/%d\n", s->dma_left, s->ti_size);
359
        s->async_len = arg;
360
        s->async_buf = s->current_dev->get_buf(s->current_dev, 0);
361
        if (s->dma_left) {
362
            esp_do_dma(s);
363
        } else if (s->dma_counter != 0 && s->ti_size <= 0) {
364
            /* If this was the last part of a DMA transfer then the
365
               completion interrupt is deferred to here.  */
366
            esp_dma_done(s);
367
        }
368
    }
369
}
370

    
371
static void handle_ti(ESPState *s)
372
{
373
    uint32_t dmalen, minlen;
374

    
375
    dmalen = s->rregs[ESP_TCLO] | (s->rregs[ESP_TCMID] << 8);
376
    if (dmalen==0) {
377
      dmalen=0x10000;
378
    }
379
    s->dma_counter = dmalen;
380

    
381
    if (s->do_cmd)
382
        minlen = (dmalen < 32) ? dmalen : 32;
383
    else if (s->ti_size < 0)
384
        minlen = (dmalen < -s->ti_size) ? dmalen : -s->ti_size;
385
    else
386
        minlen = (dmalen < s->ti_size) ? dmalen : s->ti_size;
387
    DPRINTF("Transfer Information len %d\n", minlen);
388
    if (s->dma) {
389
        s->dma_left = minlen;
390
        s->rregs[ESP_RSTAT] &= ~STAT_TC;
391
        esp_do_dma(s);
392
    } else if (s->do_cmd) {
393
        DPRINTF("command len %d\n", s->cmdlen);
394
        s->ti_size = 0;
395
        s->cmdlen = 0;
396
        s->do_cmd = 0;
397
        do_cmd(s, s->cmdbuf);
398
        return;
399
    }
400
}
401

    
402
static void esp_reset(void *opaque)
403
{
404
    ESPState *s = opaque;
405

    
406
    memset(s->rregs, 0, ESP_REGS);
407
    memset(s->wregs, 0, ESP_REGS);
408
    s->rregs[ESP_TCHI] = TCHI_FAS100A; // Indicate fas100a
409
    s->ti_size = 0;
410
    s->ti_rptr = 0;
411
    s->ti_wptr = 0;
412
    s->dma = 0;
413
    s->do_cmd = 0;
414

    
415
    s->rregs[ESP_CFG1] = 7;
416
}
417

    
418
static void parent_esp_reset(void *opaque, int irq, int level)
419
{
420
    if (level)
421
        esp_reset(opaque);
422
}
423

    
424
static uint32_t esp_mem_readb(void *opaque, target_phys_addr_t addr)
425
{
426
    ESPState *s = opaque;
427
    uint32_t saddr, old_val;
428

    
429
    saddr = addr >> s->it_shift;
430
    DPRINTF("read reg[%d]: 0x%2.2x\n", saddr, s->rregs[saddr]);
431
    switch (saddr) {
432
    case ESP_FIFO:
433
        if (s->ti_size > 0) {
434
            s->ti_size--;
435
            if ((s->rregs[ESP_RSTAT] & STAT_PIO_MASK) == 0) {
436
                /* Data out.  */
437
                ESP_ERROR("PIO data read not implemented\n");
438
                s->rregs[ESP_FIFO] = 0;
439
            } else {
440
                s->rregs[ESP_FIFO] = s->ti_buf[s->ti_rptr++];
441
            }
442
            esp_raise_irq(s);
443
        }
444
        if (s->ti_size == 0) {
445
            s->ti_rptr = 0;
446
            s->ti_wptr = 0;
447
        }
448
        break;
449
    case ESP_RINTR:
450
        /* Clear sequence step, interrupt register and all status bits
451
           except TC */
452
        old_val = s->rregs[ESP_RINTR];
453
        s->rregs[ESP_RINTR] = 0;
454
        s->rregs[ESP_RSTAT] &= ~STAT_TC;
455
        s->rregs[ESP_RSEQ] = SEQ_CD;
456
        esp_lower_irq(s);
457

    
458
        return old_val;
459
    default:
460
        break;
461
    }
462
    return s->rregs[saddr];
463
}
464

    
465
static void esp_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
466
{
467
    ESPState *s = opaque;
468
    uint32_t saddr;
469

    
470
    saddr = addr >> s->it_shift;
471
    DPRINTF("write reg[%d]: 0x%2.2x -> 0x%2.2x\n", saddr, s->wregs[saddr],
472
            val);
473
    switch (saddr) {
474
    case ESP_TCLO:
475
    case ESP_TCMID:
476
        s->rregs[ESP_RSTAT] &= ~STAT_TC;
477
        break;
478
    case ESP_FIFO:
479
        if (s->do_cmd) {
480
            s->cmdbuf[s->cmdlen++] = val & 0xff;
481
        } else if (s->ti_size == TI_BUFSZ - 1) {
482
            ESP_ERROR("fifo overrun\n");
483
        } else {
484
            s->ti_size++;
485
            s->ti_buf[s->ti_wptr++] = val & 0xff;
486
        }
487
        break;
488
    case ESP_CMD:
489
        s->rregs[saddr] = val;
490
        if (val & CMD_DMA) {
491
            s->dma = 1;
492
            /* Reload DMA counter.  */
493
            s->rregs[ESP_TCLO] = s->wregs[ESP_TCLO];
494
            s->rregs[ESP_TCMID] = s->wregs[ESP_TCMID];
495
        } else {
496
            s->dma = 0;
497
        }
498
        switch(val & CMD_CMD) {
499
        case CMD_NOP:
500
            DPRINTF("NOP (%2.2x)\n", val);
501
            break;
502
        case CMD_FLUSH:
503
            DPRINTF("Flush FIFO (%2.2x)\n", val);
504
            //s->ti_size = 0;
505
            s->rregs[ESP_RINTR] = INTR_FC;
506
            s->rregs[ESP_RSEQ] = 0;
507
            s->rregs[ESP_RFLAGS] = 0;
508
            break;
509
        case CMD_RESET:
510
            DPRINTF("Chip reset (%2.2x)\n", val);
511
            esp_reset(s);
512
            break;
513
        case CMD_BUSRESET:
514
            DPRINTF("Bus reset (%2.2x)\n", val);
515
            s->rregs[ESP_RINTR] = INTR_RST;
516
            if (!(s->wregs[ESP_CFG1] & CFG1_RESREPT)) {
517
                esp_raise_irq(s);
518
            }
519
            break;
520
        case CMD_TI:
521
            handle_ti(s);
522
            break;
523
        case CMD_ICCS:
524
            DPRINTF("Initiator Command Complete Sequence (%2.2x)\n", val);
525
            write_response(s);
526
            s->rregs[ESP_RINTR] = INTR_FC;
527
            s->rregs[ESP_RSTAT] |= STAT_MI;
528
            break;
529
        case CMD_MSGACC:
530
            DPRINTF("Message Accepted (%2.2x)\n", val);
531
            write_response(s);
532
            s->rregs[ESP_RINTR] = INTR_DC;
533
            s->rregs[ESP_RSEQ] = 0;
534
            break;
535
        case CMD_PAD:
536
            DPRINTF("Transfer padding (%2.2x)\n", val);
537
            s->rregs[ESP_RSTAT] = STAT_TC;
538
            s->rregs[ESP_RINTR] = INTR_FC;
539
            s->rregs[ESP_RSEQ] = 0;
540
            break;
541
        case CMD_SATN:
542
            DPRINTF("Set ATN (%2.2x)\n", val);
543
            break;
544
        case CMD_SEL:
545
            DPRINTF("Select without ATN (%2.2x)\n", val);
546
            handle_satn(s);
547
            break;
548
        case CMD_SELATN:
549
            DPRINTF("Select with ATN (%2.2x)\n", val);
550
            handle_satn(s);
551
            break;
552
        case CMD_SELATNS:
553
            DPRINTF("Select with ATN & stop (%2.2x)\n", val);
554
            handle_satn_stop(s);
555
            break;
556
        case CMD_ENSEL:
557
            DPRINTF("Enable selection (%2.2x)\n", val);
558
            s->rregs[ESP_RINTR] = 0;
559
            break;
560
        default:
561
            ESP_ERROR("Unhandled ESP command (%2.2x)\n", val);
562
            break;
563
        }
564
        break;
565
    case ESP_WBUSID ... ESP_WSYNO:
566
        break;
567
    case ESP_CFG1:
568
        s->rregs[saddr] = val;
569
        break;
570
    case ESP_WCCF ... ESP_WTEST:
571
        break;
572
    case ESP_CFG2 ... ESP_RES4:
573
        s->rregs[saddr] = val;
574
        break;
575
    default:
576
        ESP_ERROR("invalid write of 0x%02x at [0x%x]\n", val, saddr);
577
        return;
578
    }
579
    s->wregs[saddr] = val;
580
}
581

    
582
static CPUReadMemoryFunc * const esp_mem_read[3] = {
583
    esp_mem_readb,
584
    NULL,
585
    NULL,
586
};
587

    
588
static CPUWriteMemoryFunc * const esp_mem_write[3] = {
589
    esp_mem_writeb,
590
    NULL,
591
    esp_mem_writeb,
592
};
593

    
594
static void esp_save(QEMUFile *f, void *opaque)
595
{
596
    ESPState *s = opaque;
597

    
598
    qemu_put_buffer(f, s->rregs, ESP_REGS);
599
    qemu_put_buffer(f, s->wregs, ESP_REGS);
600
    qemu_put_sbe32s(f, &s->ti_size);
601
    qemu_put_be32s(f, &s->ti_rptr);
602
    qemu_put_be32s(f, &s->ti_wptr);
603
    qemu_put_buffer(f, s->ti_buf, TI_BUFSZ);
604
    qemu_put_be32s(f, &s->sense);
605
    qemu_put_be32s(f, &s->dma);
606
    qemu_put_buffer(f, s->cmdbuf, TI_BUFSZ);
607
    qemu_put_be32s(f, &s->cmdlen);
608
    qemu_put_be32s(f, &s->do_cmd);
609
    qemu_put_be32s(f, &s->dma_left);
610
    // There should be no transfers in progress, so dma_counter is not saved
611
}
612

    
613
static int esp_load(QEMUFile *f, void *opaque, int version_id)
614
{
615
    ESPState *s = opaque;
616

    
617
    if (version_id != 3)
618
        return -EINVAL; // Cannot emulate 2
619

    
620
    qemu_get_buffer(f, s->rregs, ESP_REGS);
621
    qemu_get_buffer(f, s->wregs, ESP_REGS);
622
    qemu_get_sbe32s(f, &s->ti_size);
623
    qemu_get_be32s(f, &s->ti_rptr);
624
    qemu_get_be32s(f, &s->ti_wptr);
625
    qemu_get_buffer(f, s->ti_buf, TI_BUFSZ);
626
    qemu_get_be32s(f, &s->sense);
627
    qemu_get_be32s(f, &s->dma);
628
    qemu_get_buffer(f, s->cmdbuf, TI_BUFSZ);
629
    qemu_get_be32s(f, &s->cmdlen);
630
    qemu_get_be32s(f, &s->do_cmd);
631
    qemu_get_be32s(f, &s->dma_left);
632

    
633
    return 0;
634
}
635

    
636
static void esp_scsi_attach(DeviceState *host, BlockDriverState *bd, int id)
637
{
638
    ESPState *s = FROM_SYSBUS(ESPState, sysbus_from_qdev(host));
639

    
640
    if (id < 0) {
641
        for (id = 0; id < ESP_MAX_DEVS; id++) {
642
            if (id == (s->rregs[ESP_CFG1] & 0x7))
643
                continue;
644
            if (s->scsi_dev[id] == NULL)
645
                break;
646
        }
647
    }
648
    if (id >= ESP_MAX_DEVS) {
649
        DPRINTF("Bad Device ID %d\n", id);
650
        return;
651
    }
652
    if (s->scsi_dev[id]) {
653
        DPRINTF("Destroying device %d\n", id);
654
        s->scsi_dev[id]->destroy(s->scsi_dev[id]);
655
    }
656
    DPRINTF("Attaching block device %d\n", id);
657
    /* Command queueing is not implemented.  */
658
    s->scsi_dev[id] = scsi_generic_init(bd, 0, esp_command_complete, s);
659
    if (s->scsi_dev[id] == NULL)
660
        s->scsi_dev[id] = scsi_disk_init(bd, 0, esp_command_complete, s);
661
}
662

    
663
void esp_init(target_phys_addr_t espaddr, int it_shift,
664
              espdma_memory_read_write dma_memory_read,
665
              espdma_memory_read_write dma_memory_write,
666
              void *dma_opaque, qemu_irq irq, qemu_irq *reset)
667
{
668
    DeviceState *dev;
669
    SysBusDevice *s;
670
    ESPState *esp;
671

    
672
    dev = qdev_create(NULL, "esp");
673
    esp = DO_UPCAST(ESPState, busdev.qdev, dev);
674
    esp->dma_memory_read = dma_memory_read;
675
    esp->dma_memory_write = dma_memory_write;
676
    esp->dma_opaque = dma_opaque;
677
    esp->it_shift = it_shift;
678
    qdev_init(dev);
679
    s = sysbus_from_qdev(dev);
680
    sysbus_connect_irq(s, 0, irq);
681
    sysbus_mmio_map(s, 0, espaddr);
682
    *reset = qdev_get_gpio_in(dev, 0);
683
}
684

    
685
static void esp_init1(SysBusDevice *dev)
686
{
687
    ESPState *s = FROM_SYSBUS(ESPState, dev);
688
    int esp_io_memory;
689

    
690
    sysbus_init_irq(dev, &s->irq);
691
    assert(s->it_shift != -1);
692

    
693
    esp_io_memory = cpu_register_io_memory(esp_mem_read, esp_mem_write, s);
694
    sysbus_init_mmio(dev, ESP_REGS << s->it_shift, esp_io_memory);
695

    
696
    esp_reset(s);
697

    
698
    register_savevm("esp", -1, 3, esp_save, esp_load, s);
699
    qemu_register_reset(esp_reset, s);
700

    
701
    qdev_init_gpio_in(&dev->qdev, parent_esp_reset, 1);
702

    
703
    scsi_bus_new(&dev->qdev, esp_scsi_attach);
704
}
705

    
706
static void esp_register_devices(void)
707
{
708
    sysbus_register_dev("esp", sizeof(ESPState), esp_init1);
709
}
710

    
711
device_init(esp_register_devices)