]> git.proxmox.com Git - qemu.git/blame - hw/esp.c
esp: enable for all PCI machines
[qemu.git] / hw / esp.c
CommitLineData
6f7e9aec 1/*
67e999be 2 * QEMU ESP/NCR53C9x emulation
5fafdf24 3 *
4e9aec74 4 * Copyright (c) 2005-2006 Fabrice Bellard
fabaaf1d 5 * Copyright (c) 2012 Herve Poussineau
5fafdf24 6 *
6f7e9aec
FB
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 */
5d20fa6b 25
cfb9de9c 26#include "sysbus.h"
fabaaf1d 27#include "pci.h"
43b443b6 28#include "scsi.h"
1cd3af54 29#include "esp.h"
bf4b9889 30#include "trace.h"
3af4e9aa 31#include "qemu-log.h"
6f7e9aec 32
67e999be 33/*
5ad6bb97
BS
34 * On Sparc32, this is the ESP (NCR53C90) part of chip STP2000 (Master I/O),
35 * also produced as NCR89C100. See
67e999be
FB
36 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C100.txt
37 * and
38 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR53C9X.txt
39 */
40
5aca8c3b 41#define ESP_REGS 16
8dea1dd4 42#define TI_BUFSZ 16
67e999be 43
4e9aec74 44typedef struct ESPState ESPState;
6f7e9aec 45
4e9aec74 46struct ESPState {
5aca8c3b
BS
47 uint8_t rregs[ESP_REGS];
48 uint8_t wregs[ESP_REGS];
9a975d63 49 qemu_irq irq;
d32e4b3d 50 uint8_t chip_id;
67e999be 51 int32_t ti_size;
4f6200f0 52 uint32_t ti_rptr, ti_wptr;
3944966d 53 uint32_t status;
22548760 54 uint32_t dma;
9a975d63 55 uint8_t ti_buf[TI_BUFSZ];
ca9c39fa 56 SCSIBus bus;
2e5d83bb 57 SCSIDevice *current_dev;
5c6c0e51 58 SCSIRequest *current_req;
9f149aa9 59 uint8_t cmdbuf[TI_BUFSZ];
22548760
BS
60 uint32_t cmdlen;
61 uint32_t do_cmd;
4d611c9a 62
6787f5fa 63 /* The amount of data left in the current DMA transfer. */
4d611c9a 64 uint32_t dma_left;
6787f5fa
PB
65 /* The size of the current DMA transfer. Zero if no transfer is in
66 progress. */
67 uint32_t dma_counter;
9a975d63
BS
68 int dma_enabled;
69
4d611c9a 70 uint32_t async_len;
9a975d63 71 uint8_t *async_buf;
8b17de88 72
ff9868ec
BS
73 ESPDMAMemoryReadWriteFunc dma_memory_read;
74 ESPDMAMemoryReadWriteFunc dma_memory_write;
67e999be 75 void *dma_opaque;
73d74342 76 void (*dma_cb)(ESPState *s);
4e9aec74 77};
6f7e9aec 78
5ad6bb97
BS
79#define ESP_TCLO 0x0
80#define ESP_TCMID 0x1
81#define ESP_FIFO 0x2
82#define ESP_CMD 0x3
83#define ESP_RSTAT 0x4
84#define ESP_WBUSID 0x4
85#define ESP_RINTR 0x5
86#define ESP_WSEL 0x5
87#define ESP_RSEQ 0x6
88#define ESP_WSYNTP 0x6
89#define ESP_RFLAGS 0x7
90#define ESP_WSYNO 0x7
91#define ESP_CFG1 0x8
92#define ESP_RRES1 0x9
93#define ESP_WCCF 0x9
94#define ESP_RRES2 0xa
95#define ESP_WTEST 0xa
96#define ESP_CFG2 0xb
97#define ESP_CFG3 0xc
98#define ESP_RES3 0xd
99#define ESP_TCHI 0xe
100#define ESP_RES4 0xf
101
102#define CMD_DMA 0x80
103#define CMD_CMD 0x7f
104
105#define CMD_NOP 0x00
106#define CMD_FLUSH 0x01
107#define CMD_RESET 0x02
108#define CMD_BUSRESET 0x03
109#define CMD_TI 0x10
110#define CMD_ICCS 0x11
111#define CMD_MSGACC 0x12
0fd0eb21 112#define CMD_PAD 0x18
5ad6bb97 113#define CMD_SATN 0x1a
6915bff1 114#define CMD_RSTATN 0x1b
5e1e0a3b 115#define CMD_SEL 0x41
5ad6bb97
BS
116#define CMD_SELATN 0x42
117#define CMD_SELATNS 0x43
118#define CMD_ENSEL 0x44
6fe84c18 119#define CMD_DISSEL 0x45
5ad6bb97 120
2f275b8f
FB
121#define STAT_DO 0x00
122#define STAT_DI 0x01
123#define STAT_CD 0x02
124#define STAT_ST 0x03
8dea1dd4
BS
125#define STAT_MO 0x06
126#define STAT_MI 0x07
5ad6bb97 127#define STAT_PIO_MASK 0x06
2f275b8f
FB
128
129#define STAT_TC 0x10
4d611c9a
PB
130#define STAT_PE 0x20
131#define STAT_GE 0x40
c73f96fd 132#define STAT_INT 0x80
2f275b8f 133
8dea1dd4
BS
134#define BUSID_DID 0x07
135
2f275b8f
FB
136#define INTR_FC 0x08
137#define INTR_BS 0x10
138#define INTR_DC 0x20
9e61bde5 139#define INTR_RST 0x80
2f275b8f
FB
140
141#define SEQ_0 0x0
142#define SEQ_CD 0x4
143
5ad6bb97
BS
144#define CFG1_RESREPT 0x40
145
5ad6bb97 146#define TCHI_FAS100A 0x4
fabaaf1d 147#define TCHI_AM53C974 0x12
5ad6bb97 148
c73f96fd
BS
149static void esp_raise_irq(ESPState *s)
150{
151 if (!(s->rregs[ESP_RSTAT] & STAT_INT)) {
152 s->rregs[ESP_RSTAT] |= STAT_INT;
153 qemu_irq_raise(s->irq);
bf4b9889 154 trace_esp_raise_irq();
c73f96fd
BS
155 }
156}
157
158static void esp_lower_irq(ESPState *s)
159{
160 if (s->rregs[ESP_RSTAT] & STAT_INT) {
161 s->rregs[ESP_RSTAT] &= ~STAT_INT;
162 qemu_irq_lower(s->irq);
bf4b9889 163 trace_esp_lower_irq();
c73f96fd
BS
164 }
165}
166
a391fdbc 167static void esp_dma_enable(ESPState *s, int irq, int level)
73d74342 168{
73d74342
BS
169 if (level) {
170 s->dma_enabled = 1;
bf4b9889 171 trace_esp_dma_enable();
73d74342
BS
172 if (s->dma_cb) {
173 s->dma_cb(s);
174 s->dma_cb = NULL;
175 }
176 } else {
bf4b9889 177 trace_esp_dma_disable();
73d74342
BS
178 s->dma_enabled = 0;
179 }
180}
181
94d3f98a
PB
182static void esp_request_cancelled(SCSIRequest *req)
183{
e6810db8 184 ESPState *s = req->hba_private;
94d3f98a
PB
185
186 if (req == s->current_req) {
187 scsi_req_unref(s->current_req);
188 s->current_req = NULL;
189 s->current_dev = NULL;
190 }
191}
192
22548760 193static uint32_t get_cmd(ESPState *s, uint8_t *buf)
2f275b8f 194{
a917d384 195 uint32_t dmalen;
2f275b8f
FB
196 int target;
197
8dea1dd4 198 target = s->wregs[ESP_WBUSID] & BUSID_DID;
4f6200f0 199 if (s->dma) {
fc4d65da 200 dmalen = s->rregs[ESP_TCLO] | (s->rregs[ESP_TCMID] << 8);
8b17de88 201 s->dma_memory_read(s->dma_opaque, buf, dmalen);
4f6200f0 202 } else {
fc4d65da
BS
203 dmalen = s->ti_size;
204 memcpy(buf, s->ti_buf, dmalen);
75ef8496 205 buf[0] = buf[2] >> 5;
4f6200f0 206 }
bf4b9889 207 trace_esp_get_cmd(dmalen, target);
2e5d83bb 208
2f275b8f 209 s->ti_size = 0;
4f6200f0
FB
210 s->ti_rptr = 0;
211 s->ti_wptr = 0;
2f275b8f 212
429bef69 213 if (s->current_req) {
a917d384 214 /* Started a new command before the old one finished. Cancel it. */
94d3f98a 215 scsi_req_cancel(s->current_req);
a917d384
PB
216 s->async_len = 0;
217 }
218
0d3545e7 219 s->current_dev = scsi_device_find(&s->bus, 0, target, 0);
f48a7a6e 220 if (!s->current_dev) {
2e5d83bb 221 // No such drive
c73f96fd 222 s->rregs[ESP_RSTAT] = 0;
5ad6bb97
BS
223 s->rregs[ESP_RINTR] = INTR_DC;
224 s->rregs[ESP_RSEQ] = SEQ_0;
c73f96fd 225 esp_raise_irq(s);
f930d07e 226 return 0;
2f275b8f 227 }
9f149aa9
PB
228 return dmalen;
229}
230
f2818f22 231static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid)
9f149aa9
PB
232{
233 int32_t datalen;
234 int lun;
f48a7a6e 235 SCSIDevice *current_lun;
9f149aa9 236
bf4b9889 237 trace_esp_do_busid_cmd(busid);
f2818f22 238 lun = busid & 7;
0d3545e7 239 current_lun = scsi_device_find(&s->bus, 0, s->current_dev->id, lun);
e6810db8 240 s->current_req = scsi_req_new(current_lun, 0, lun, buf, s);
c39ce112 241 datalen = scsi_req_enqueue(s->current_req);
67e999be
FB
242 s->ti_size = datalen;
243 if (datalen != 0) {
c73f96fd 244 s->rregs[ESP_RSTAT] = STAT_TC;
a917d384 245 s->dma_left = 0;
6787f5fa 246 s->dma_counter = 0;
2e5d83bb 247 if (datalen > 0) {
5ad6bb97 248 s->rregs[ESP_RSTAT] |= STAT_DI;
2e5d83bb 249 } else {
5ad6bb97 250 s->rregs[ESP_RSTAT] |= STAT_DO;
b9788fc4 251 }
ad3376cc 252 scsi_req_continue(s->current_req);
2f275b8f 253 }
5ad6bb97
BS
254 s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
255 s->rregs[ESP_RSEQ] = SEQ_CD;
c73f96fd 256 esp_raise_irq(s);
2f275b8f
FB
257}
258
f2818f22
AT
259static void do_cmd(ESPState *s, uint8_t *buf)
260{
261 uint8_t busid = buf[0];
262
263 do_busid_cmd(s, &buf[1], busid);
264}
265
9f149aa9
PB
266static void handle_satn(ESPState *s)
267{
268 uint8_t buf[32];
269 int len;
270
1b26eaa1 271 if (s->dma && !s->dma_enabled) {
73d74342
BS
272 s->dma_cb = handle_satn;
273 return;
274 }
9f149aa9
PB
275 len = get_cmd(s, buf);
276 if (len)
277 do_cmd(s, buf);
278}
279
f2818f22
AT
280static void handle_s_without_atn(ESPState *s)
281{
282 uint8_t buf[32];
283 int len;
284
1b26eaa1 285 if (s->dma && !s->dma_enabled) {
73d74342
BS
286 s->dma_cb = handle_s_without_atn;
287 return;
288 }
f2818f22
AT
289 len = get_cmd(s, buf);
290 if (len) {
291 do_busid_cmd(s, buf, 0);
292 }
293}
294
9f149aa9
PB
295static void handle_satn_stop(ESPState *s)
296{
1b26eaa1 297 if (s->dma && !s->dma_enabled) {
73d74342
BS
298 s->dma_cb = handle_satn_stop;
299 return;
300 }
9f149aa9
PB
301 s->cmdlen = get_cmd(s, s->cmdbuf);
302 if (s->cmdlen) {
bf4b9889 303 trace_esp_handle_satn_stop(s->cmdlen);
9f149aa9 304 s->do_cmd = 1;
c73f96fd 305 s->rregs[ESP_RSTAT] = STAT_TC | STAT_CD;
5ad6bb97
BS
306 s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
307 s->rregs[ESP_RSEQ] = SEQ_CD;
c73f96fd 308 esp_raise_irq(s);
9f149aa9
PB
309 }
310}
311
0fc5c15a 312static void write_response(ESPState *s)
2f275b8f 313{
bf4b9889 314 trace_esp_write_response(s->status);
3944966d 315 s->ti_buf[0] = s->status;
0fc5c15a 316 s->ti_buf[1] = 0;
4f6200f0 317 if (s->dma) {
8b17de88 318 s->dma_memory_write(s->dma_opaque, s->ti_buf, 2);
c73f96fd 319 s->rregs[ESP_RSTAT] = STAT_TC | STAT_ST;
5ad6bb97
BS
320 s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
321 s->rregs[ESP_RSEQ] = SEQ_CD;
4f6200f0 322 } else {
f930d07e
BS
323 s->ti_size = 2;
324 s->ti_rptr = 0;
325 s->ti_wptr = 0;
5ad6bb97 326 s->rregs[ESP_RFLAGS] = 2;
4f6200f0 327 }
c73f96fd 328 esp_raise_irq(s);
2f275b8f 329}
4f6200f0 330
a917d384
PB
331static void esp_dma_done(ESPState *s)
332{
c73f96fd 333 s->rregs[ESP_RSTAT] |= STAT_TC;
5ad6bb97
BS
334 s->rregs[ESP_RINTR] = INTR_BS;
335 s->rregs[ESP_RSEQ] = 0;
336 s->rregs[ESP_RFLAGS] = 0;
337 s->rregs[ESP_TCLO] = 0;
338 s->rregs[ESP_TCMID] = 0;
c73f96fd 339 esp_raise_irq(s);
a917d384
PB
340}
341
4d611c9a
PB
342static void esp_do_dma(ESPState *s)
343{
67e999be 344 uint32_t len;
4d611c9a 345 int to_device;
a917d384 346
67e999be 347 to_device = (s->ti_size < 0);
a917d384 348 len = s->dma_left;
4d611c9a 349 if (s->do_cmd) {
bf4b9889 350 trace_esp_do_dma(s->cmdlen, len);
8b17de88 351 s->dma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len);
4d611c9a
PB
352 s->ti_size = 0;
353 s->cmdlen = 0;
354 s->do_cmd = 0;
355 do_cmd(s, s->cmdbuf);
356 return;
a917d384
PB
357 }
358 if (s->async_len == 0) {
359 /* Defer until data is available. */
360 return;
361 }
362 if (len > s->async_len) {
363 len = s->async_len;
364 }
365 if (to_device) {
8b17de88 366 s->dma_memory_read(s->dma_opaque, s->async_buf, len);
4d611c9a 367 } else {
8b17de88 368 s->dma_memory_write(s->dma_opaque, s->async_buf, len);
a917d384 369 }
a917d384
PB
370 s->dma_left -= len;
371 s->async_buf += len;
372 s->async_len -= len;
6787f5fa
PB
373 if (to_device)
374 s->ti_size += len;
375 else
376 s->ti_size -= len;
a917d384 377 if (s->async_len == 0) {
ad3376cc
PB
378 scsi_req_continue(s->current_req);
379 /* If there is still data to be read from the device then
380 complete the DMA operation immediately. Otherwise defer
381 until the scsi layer has completed. */
382 if (to_device || s->dma_left != 0 || s->ti_size == 0) {
383 return;
4d611c9a 384 }
a917d384 385 }
ad3376cc
PB
386
387 /* Partially filled a scsi buffer. Complete immediately. */
388 esp_dma_done(s);
4d611c9a
PB
389}
390
01e95455
PB
391static void esp_command_complete(SCSIRequest *req, uint32_t status,
392 size_t resid)
2e5d83bb 393{
e6810db8 394 ESPState *s = req->hba_private;
2e5d83bb 395
bf4b9889 396 trace_esp_command_complete();
c6df7102 397 if (s->ti_size != 0) {
bf4b9889 398 trace_esp_command_complete_unexpected();
c6df7102
PB
399 }
400 s->ti_size = 0;
401 s->dma_left = 0;
402 s->async_len = 0;
aba1f023 403 if (status) {
bf4b9889 404 trace_esp_command_complete_fail();
c6df7102 405 }
aba1f023 406 s->status = status;
c6df7102
PB
407 s->rregs[ESP_RSTAT] = STAT_ST;
408 esp_dma_done(s);
409 if (s->current_req) {
410 scsi_req_unref(s->current_req);
411 s->current_req = NULL;
412 s->current_dev = NULL;
413 }
414}
415
aba1f023 416static void esp_transfer_data(SCSIRequest *req, uint32_t len)
c6df7102 417{
e6810db8 418 ESPState *s = req->hba_private;
c6df7102 419
bf4b9889 420 trace_esp_transfer_data(s->dma_left, s->ti_size);
aba1f023 421 s->async_len = len;
c6df7102
PB
422 s->async_buf = scsi_req_get_buf(req);
423 if (s->dma_left) {
424 esp_do_dma(s);
425 } else if (s->dma_counter != 0 && s->ti_size <= 0) {
426 /* If this was the last part of a DMA transfer then the
427 completion interrupt is deferred to here. */
a917d384 428 esp_dma_done(s);
4d611c9a 429 }
2e5d83bb
PB
430}
431
2f275b8f
FB
432static void handle_ti(ESPState *s)
433{
4d611c9a 434 uint32_t dmalen, minlen;
2f275b8f 435
7246e160
HP
436 if (s->dma && !s->dma_enabled) {
437 s->dma_cb = handle_ti;
438 return;
439 }
440
5ad6bb97 441 dmalen = s->rregs[ESP_TCLO] | (s->rregs[ESP_TCMID] << 8);
db59203d
PB
442 if (dmalen==0) {
443 dmalen=0x10000;
444 }
6787f5fa 445 s->dma_counter = dmalen;
db59203d 446
9f149aa9
PB
447 if (s->do_cmd)
448 minlen = (dmalen < 32) ? dmalen : 32;
67e999be
FB
449 else if (s->ti_size < 0)
450 minlen = (dmalen < -s->ti_size) ? dmalen : -s->ti_size;
9f149aa9
PB
451 else
452 minlen = (dmalen < s->ti_size) ? dmalen : s->ti_size;
bf4b9889 453 trace_esp_handle_ti(minlen);
4f6200f0 454 if (s->dma) {
4d611c9a 455 s->dma_left = minlen;
5ad6bb97 456 s->rregs[ESP_RSTAT] &= ~STAT_TC;
4d611c9a 457 esp_do_dma(s);
9f149aa9 458 } else if (s->do_cmd) {
bf4b9889 459 trace_esp_handle_ti_cmd(s->cmdlen);
9f149aa9
PB
460 s->ti_size = 0;
461 s->cmdlen = 0;
462 s->do_cmd = 0;
463 do_cmd(s, s->cmdbuf);
464 return;
465 }
2f275b8f
FB
466}
467
a391fdbc 468static void esp_hard_reset(ESPState *s)
6f7e9aec 469{
5aca8c3b
BS
470 memset(s->rregs, 0, ESP_REGS);
471 memset(s->wregs, 0, ESP_REGS);
d32e4b3d 472 s->rregs[ESP_TCHI] = s->chip_id;
4e9aec74
PB
473 s->ti_size = 0;
474 s->ti_rptr = 0;
475 s->ti_wptr = 0;
4e9aec74 476 s->dma = 0;
9f149aa9 477 s->do_cmd = 0;
73d74342 478 s->dma_cb = NULL;
8dea1dd4
BS
479
480 s->rregs[ESP_CFG1] = 7;
6f7e9aec
FB
481}
482
a391fdbc 483static void esp_soft_reset(ESPState *s)
85948643 484{
85948643 485 qemu_irq_lower(s->irq);
a391fdbc 486 esp_hard_reset(s);
85948643
BS
487}
488
a391fdbc 489static void parent_esp_reset(ESPState *s, int irq, int level)
2d069bab 490{
85948643 491 if (level) {
a391fdbc 492 esp_soft_reset(s);
85948643 493 }
2d069bab
BS
494}
495
a391fdbc 496static uint64_t esp_reg_read(ESPState *s, uint32_t saddr)
73d74342 497{
a391fdbc 498 uint32_t old_val;
73d74342 499
bf4b9889 500 trace_esp_mem_readb(saddr, s->rregs[saddr]);
6f7e9aec 501 switch (saddr) {
5ad6bb97 502 case ESP_FIFO:
f930d07e
BS
503 if (s->ti_size > 0) {
504 s->ti_size--;
5ad6bb97 505 if ((s->rregs[ESP_RSTAT] & STAT_PIO_MASK) == 0) {
8dea1dd4 506 /* Data out. */
3af4e9aa
HP
507 qemu_log_mask(LOG_UNIMP,
508 "esp: PIO data read not implemented\n");
5ad6bb97 509 s->rregs[ESP_FIFO] = 0;
2e5d83bb 510 } else {
5ad6bb97 511 s->rregs[ESP_FIFO] = s->ti_buf[s->ti_rptr++];
2e5d83bb 512 }
c73f96fd 513 esp_raise_irq(s);
f930d07e
BS
514 }
515 if (s->ti_size == 0) {
4f6200f0
FB
516 s->ti_rptr = 0;
517 s->ti_wptr = 0;
518 }
f930d07e 519 break;
5ad6bb97 520 case ESP_RINTR:
2814df28
BS
521 /* Clear sequence step, interrupt register and all status bits
522 except TC */
523 old_val = s->rregs[ESP_RINTR];
524 s->rregs[ESP_RINTR] = 0;
525 s->rregs[ESP_RSTAT] &= ~STAT_TC;
526 s->rregs[ESP_RSEQ] = SEQ_CD;
c73f96fd 527 esp_lower_irq(s);
2814df28
BS
528
529 return old_val;
6f7e9aec 530 default:
f930d07e 531 break;
6f7e9aec 532 }
2f275b8f 533 return s->rregs[saddr];
6f7e9aec
FB
534}
535
a391fdbc 536static void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val)
6f7e9aec 537{
bf4b9889 538 trace_esp_mem_writeb(saddr, s->wregs[saddr], val);
6f7e9aec 539 switch (saddr) {
5ad6bb97
BS
540 case ESP_TCLO:
541 case ESP_TCMID:
542 s->rregs[ESP_RSTAT] &= ~STAT_TC;
4f6200f0 543 break;
5ad6bb97 544 case ESP_FIFO:
9f149aa9
PB
545 if (s->do_cmd) {
546 s->cmdbuf[s->cmdlen++] = val & 0xff;
8dea1dd4 547 } else if (s->ti_size == TI_BUFSZ - 1) {
3af4e9aa 548 trace_esp_error_fifo_overrun();
2e5d83bb
PB
549 } else {
550 s->ti_size++;
551 s->ti_buf[s->ti_wptr++] = val & 0xff;
552 }
f930d07e 553 break;
5ad6bb97 554 case ESP_CMD:
4f6200f0 555 s->rregs[saddr] = val;
5ad6bb97 556 if (val & CMD_DMA) {
f930d07e 557 s->dma = 1;
6787f5fa 558 /* Reload DMA counter. */
5ad6bb97
BS
559 s->rregs[ESP_TCLO] = s->wregs[ESP_TCLO];
560 s->rregs[ESP_TCMID] = s->wregs[ESP_TCMID];
f930d07e
BS
561 } else {
562 s->dma = 0;
563 }
5ad6bb97
BS
564 switch(val & CMD_CMD) {
565 case CMD_NOP:
bf4b9889 566 trace_esp_mem_writeb_cmd_nop(val);
f930d07e 567 break;
5ad6bb97 568 case CMD_FLUSH:
bf4b9889 569 trace_esp_mem_writeb_cmd_flush(val);
9e61bde5 570 //s->ti_size = 0;
5ad6bb97
BS
571 s->rregs[ESP_RINTR] = INTR_FC;
572 s->rregs[ESP_RSEQ] = 0;
a214c598 573 s->rregs[ESP_RFLAGS] = 0;
f930d07e 574 break;
5ad6bb97 575 case CMD_RESET:
bf4b9889 576 trace_esp_mem_writeb_cmd_reset(val);
a391fdbc 577 esp_soft_reset(s);
f930d07e 578 break;
5ad6bb97 579 case CMD_BUSRESET:
bf4b9889 580 trace_esp_mem_writeb_cmd_bus_reset(val);
5ad6bb97
BS
581 s->rregs[ESP_RINTR] = INTR_RST;
582 if (!(s->wregs[ESP_CFG1] & CFG1_RESREPT)) {
c73f96fd 583 esp_raise_irq(s);
9e61bde5 584 }
f930d07e 585 break;
5ad6bb97 586 case CMD_TI:
f930d07e
BS
587 handle_ti(s);
588 break;
5ad6bb97 589 case CMD_ICCS:
bf4b9889 590 trace_esp_mem_writeb_cmd_iccs(val);
f930d07e 591 write_response(s);
4bf5801d
BS
592 s->rregs[ESP_RINTR] = INTR_FC;
593 s->rregs[ESP_RSTAT] |= STAT_MI;
f930d07e 594 break;
5ad6bb97 595 case CMD_MSGACC:
bf4b9889 596 trace_esp_mem_writeb_cmd_msgacc(val);
5ad6bb97
BS
597 s->rregs[ESP_RINTR] = INTR_DC;
598 s->rregs[ESP_RSEQ] = 0;
4e2a68c1
AT
599 s->rregs[ESP_RFLAGS] = 0;
600 esp_raise_irq(s);
f930d07e 601 break;
0fd0eb21 602 case CMD_PAD:
bf4b9889 603 trace_esp_mem_writeb_cmd_pad(val);
0fd0eb21
BS
604 s->rregs[ESP_RSTAT] = STAT_TC;
605 s->rregs[ESP_RINTR] = INTR_FC;
606 s->rregs[ESP_RSEQ] = 0;
607 break;
5ad6bb97 608 case CMD_SATN:
bf4b9889 609 trace_esp_mem_writeb_cmd_satn(val);
f930d07e 610 break;
6915bff1
HP
611 case CMD_RSTATN:
612 trace_esp_mem_writeb_cmd_rstatn(val);
613 break;
5e1e0a3b 614 case CMD_SEL:
bf4b9889 615 trace_esp_mem_writeb_cmd_sel(val);
f2818f22 616 handle_s_without_atn(s);
5e1e0a3b 617 break;
5ad6bb97 618 case CMD_SELATN:
bf4b9889 619 trace_esp_mem_writeb_cmd_selatn(val);
f930d07e
BS
620 handle_satn(s);
621 break;
5ad6bb97 622 case CMD_SELATNS:
bf4b9889 623 trace_esp_mem_writeb_cmd_selatns(val);
f930d07e
BS
624 handle_satn_stop(s);
625 break;
5ad6bb97 626 case CMD_ENSEL:
bf4b9889 627 trace_esp_mem_writeb_cmd_ensel(val);
e3926838 628 s->rregs[ESP_RINTR] = 0;
74ec6048 629 break;
6fe84c18
HP
630 case CMD_DISSEL:
631 trace_esp_mem_writeb_cmd_dissel(val);
632 s->rregs[ESP_RINTR] = 0;
633 esp_raise_irq(s);
634 break;
f930d07e 635 default:
3af4e9aa 636 trace_esp_error_unhandled_command(val);
f930d07e
BS
637 break;
638 }
639 break;
5ad6bb97 640 case ESP_WBUSID ... ESP_WSYNO:
f930d07e 641 break;
5ad6bb97 642 case ESP_CFG1:
4f6200f0
FB
643 s->rregs[saddr] = val;
644 break;
5ad6bb97 645 case ESP_WCCF ... ESP_WTEST:
4f6200f0 646 break;
b44c08fa 647 case ESP_CFG2 ... ESP_RES4:
4f6200f0
FB
648 s->rregs[saddr] = val;
649 break;
6f7e9aec 650 default:
3af4e9aa 651 trace_esp_error_invalid_write(val, saddr);
8dea1dd4 652 return;
6f7e9aec 653 }
2f275b8f 654 s->wregs[saddr] = val;
6f7e9aec
FB
655}
656
67bb5314
AK
657static bool esp_mem_accepts(void *opaque, target_phys_addr_t addr,
658 unsigned size, bool is_write)
659{
660 return (size == 1) || (is_write && size == 4);
661}
6f7e9aec 662
cc9952f3
BS
663static const VMStateDescription vmstate_esp = {
664 .name ="esp",
665 .version_id = 3,
666 .minimum_version_id = 3,
667 .minimum_version_id_old = 3,
668 .fields = (VMStateField []) {
669 VMSTATE_BUFFER(rregs, ESPState),
670 VMSTATE_BUFFER(wregs, ESPState),
671 VMSTATE_INT32(ti_size, ESPState),
672 VMSTATE_UINT32(ti_rptr, ESPState),
673 VMSTATE_UINT32(ti_wptr, ESPState),
674 VMSTATE_BUFFER(ti_buf, ESPState),
3944966d 675 VMSTATE_UINT32(status, ESPState),
cc9952f3
BS
676 VMSTATE_UINT32(dma, ESPState),
677 VMSTATE_BUFFER(cmdbuf, ESPState),
678 VMSTATE_UINT32(cmdlen, ESPState),
679 VMSTATE_UINT32(do_cmd, ESPState),
680 VMSTATE_UINT32(dma_left, ESPState),
681 VMSTATE_END_OF_LIST()
682 }
683};
6f7e9aec 684
a391fdbc
HP
685typedef struct {
686 SysBusDevice busdev;
687 MemoryRegion iomem;
688 uint32_t it_shift;
689 ESPState esp;
690} SysBusESPState;
691
692static void sysbus_esp_mem_write(void *opaque, target_phys_addr_t addr,
693 uint64_t val, unsigned int size)
694{
695 SysBusESPState *sysbus = opaque;
696 uint32_t saddr;
697
698 saddr = addr >> sysbus->it_shift;
699 esp_reg_write(&sysbus->esp, saddr, val);
700}
701
702static uint64_t sysbus_esp_mem_read(void *opaque, target_phys_addr_t addr,
703 unsigned int size)
704{
705 SysBusESPState *sysbus = opaque;
706 uint32_t saddr;
707
708 saddr = addr >> sysbus->it_shift;
709 return esp_reg_read(&sysbus->esp, saddr);
710}
711
712static const MemoryRegionOps sysbus_esp_mem_ops = {
713 .read = sysbus_esp_mem_read,
714 .write = sysbus_esp_mem_write,
715 .endianness = DEVICE_NATIVE_ENDIAN,
716 .valid.accepts = esp_mem_accepts,
717};
718
c227f099 719void esp_init(target_phys_addr_t espaddr, int it_shift,
ff9868ec
BS
720 ESPDMAMemoryReadWriteFunc dma_memory_read,
721 ESPDMAMemoryReadWriteFunc dma_memory_write,
73d74342
BS
722 void *dma_opaque, qemu_irq irq, qemu_irq *reset,
723 qemu_irq *dma_enable)
6f7e9aec 724{
cfb9de9c
PB
725 DeviceState *dev;
726 SysBusDevice *s;
a391fdbc 727 SysBusESPState *sysbus;
ee6847d1 728 ESPState *esp;
cfb9de9c
PB
729
730 dev = qdev_create(NULL, "esp");
a391fdbc
HP
731 sysbus = DO_UPCAST(SysBusESPState, busdev.qdev, dev);
732 esp = &sysbus->esp;
ee6847d1
GH
733 esp->dma_memory_read = dma_memory_read;
734 esp->dma_memory_write = dma_memory_write;
735 esp->dma_opaque = dma_opaque;
a391fdbc 736 sysbus->it_shift = it_shift;
73d74342
BS
737 /* XXX for now until rc4030 has been changed to use DMA enable signal */
738 esp->dma_enabled = 1;
e23a1b33 739 qdev_init_nofail(dev);
cfb9de9c
PB
740 s = sysbus_from_qdev(dev);
741 sysbus_connect_irq(s, 0, irq);
742 sysbus_mmio_map(s, 0, espaddr);
74ff8d90 743 *reset = qdev_get_gpio_in(dev, 0);
73d74342 744 *dma_enable = qdev_get_gpio_in(dev, 1);
cfb9de9c 745}
6f7e9aec 746
afd4030c
PB
747static const struct SCSIBusInfo esp_scsi_info = {
748 .tcq = false,
7e0380b9
PB
749 .max_target = ESP_MAX_DEVS,
750 .max_lun = 7,
afd4030c 751
c6df7102 752 .transfer_data = esp_transfer_data,
94d3f98a
PB
753 .complete = esp_command_complete,
754 .cancel = esp_request_cancelled
cfdc1bb0
PB
755};
756
a391fdbc 757static void sysbus_esp_gpio_demux(void *opaque, int irq, int level)
cfb9de9c 758{
a391fdbc
HP
759 DeviceState *d = opaque;
760 SysBusESPState *sysbus = container_of(d, SysBusESPState, busdev.qdev);
761 ESPState *s = &sysbus->esp;
762
763 switch (irq) {
764 case 0:
765 parent_esp_reset(s, irq, level);
766 break;
767 case 1:
768 esp_dma_enable(opaque, irq, level);
769 break;
770 }
771}
772
773static int sysbus_esp_init(SysBusDevice *dev)
774{
775 SysBusESPState *sysbus = FROM_SYSBUS(SysBusESPState, dev);
776 ESPState *s = &sysbus->esp;
6f7e9aec 777
cfb9de9c 778 sysbus_init_irq(dev, &s->irq);
a391fdbc 779 assert(sysbus->it_shift != -1);
6f7e9aec 780
d32e4b3d 781 s->chip_id = TCHI_FAS100A;
a391fdbc
HP
782 memory_region_init_io(&sysbus->iomem, &sysbus_esp_mem_ops, sysbus,
783 "esp", ESP_REGS << sysbus->it_shift);
784 sysbus_init_mmio(dev, &sysbus->iomem);
6f7e9aec 785
a391fdbc 786 qdev_init_gpio_in(&dev->qdev, sysbus_esp_gpio_demux, 2);
2d069bab 787
afd4030c 788 scsi_bus_new(&s->bus, &dev->qdev, &esp_scsi_info);
fa66b909 789 return scsi_bus_legacy_handle_cmdline(&s->bus);
67e999be 790}
cfb9de9c 791
a391fdbc
HP
792static void sysbus_esp_hard_reset(DeviceState *dev)
793{
794 SysBusESPState *sysbus = DO_UPCAST(SysBusESPState, busdev.qdev, dev);
795 esp_hard_reset(&sysbus->esp);
796}
797
798static const VMStateDescription vmstate_sysbus_esp_scsi = {
799 .name = "sysbusespscsi",
800 .version_id = 0,
801 .minimum_version_id = 0,
802 .minimum_version_id_old = 0,
803 .fields = (VMStateField[]) {
804 VMSTATE_STRUCT(esp, SysBusESPState, 0, vmstate_esp, ESPState),
805 VMSTATE_END_OF_LIST()
806 }
999e12bb
AL
807};
808
a391fdbc 809static void sysbus_esp_class_init(ObjectClass *klass, void *data)
999e12bb 810{
39bffca2 811 DeviceClass *dc = DEVICE_CLASS(klass);
999e12bb
AL
812 SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
813
a391fdbc
HP
814 k->init = sysbus_esp_init;
815 dc->reset = sysbus_esp_hard_reset;
816 dc->vmsd = &vmstate_sysbus_esp_scsi;
999e12bb
AL
817}
818
a391fdbc 819static TypeInfo sysbus_esp_info = {
39bffca2
AL
820 .name = "esp",
821 .parent = TYPE_SYS_BUS_DEVICE,
a391fdbc
HP
822 .instance_size = sizeof(SysBusESPState),
823 .class_init = sysbus_esp_class_init,
63235df8
BS
824};
825
fabaaf1d
HP
826#define DMA_CMD 0x0
827#define DMA_STC 0x1
828#define DMA_SPA 0x2
829#define DMA_WBC 0x3
830#define DMA_WAC 0x4
831#define DMA_STAT 0x5
832#define DMA_SMDLA 0x6
833#define DMA_WMAC 0x7
834
835#define DMA_CMD_MASK 0x03
836#define DMA_CMD_DIAG 0x04
837#define DMA_CMD_MDL 0x10
838#define DMA_CMD_INTE_P 0x20
839#define DMA_CMD_INTE_D 0x40
840#define DMA_CMD_DIR 0x80
841
842#define DMA_STAT_PWDN 0x01
843#define DMA_STAT_ERROR 0x02
844#define DMA_STAT_ABORT 0x04
845#define DMA_STAT_DONE 0x08
846#define DMA_STAT_SCSIINT 0x10
847#define DMA_STAT_BCMBLT 0x20
848
849#define SBAC_STATUS 0x1000
850
851typedef struct PCIESPState {
852 PCIDevice dev;
853 MemoryRegion io;
854 uint32_t dma_regs[8];
855 uint32_t sbac;
856 ESPState esp;
857} PCIESPState;
858
859static void esp_pci_handle_idle(PCIESPState *pci, uint32_t val)
860{
861 trace_esp_pci_dma_idle(val);
862 esp_dma_enable(&pci->esp, 0, 0);
863}
864
865static void esp_pci_handle_blast(PCIESPState *pci, uint32_t val)
866{
867 trace_esp_pci_dma_blast(val);
868 qemu_log_mask(LOG_UNIMP, "am53c974: cmd BLAST not implemented\n");
869}
870
871static void esp_pci_handle_abort(PCIESPState *pci, uint32_t val)
872{
873 trace_esp_pci_dma_abort(val);
874 if (pci->esp.current_req) {
875 scsi_req_cancel(pci->esp.current_req);
876 }
877}
878
879static void esp_pci_handle_start(PCIESPState *pci, uint32_t val)
880{
881 trace_esp_pci_dma_start(val);
882
883 pci->dma_regs[DMA_WBC] = pci->dma_regs[DMA_STC];
884 pci->dma_regs[DMA_WAC] = pci->dma_regs[DMA_SPA];
885 pci->dma_regs[DMA_WMAC] = pci->dma_regs[DMA_SMDLA];
886
887 pci->dma_regs[DMA_STAT] &= ~(DMA_STAT_BCMBLT | DMA_STAT_SCSIINT
888 | DMA_STAT_DONE | DMA_STAT_ABORT
889 | DMA_STAT_ERROR | DMA_STAT_PWDN);
890
891 esp_dma_enable(&pci->esp, 0, 1);
892}
893
894static void esp_pci_dma_write(PCIESPState *pci, uint32_t saddr, uint32_t val)
895{
896 trace_esp_pci_dma_write(saddr, pci->dma_regs[saddr], val);
897 switch (saddr) {
898 case DMA_CMD:
899 pci->dma_regs[saddr] = val;
900 switch (val & DMA_CMD_MASK) {
901 case 0x0: /* IDLE */
902 esp_pci_handle_idle(pci, val);
903 break;
904 case 0x1: /* BLAST */
905 esp_pci_handle_blast(pci, val);
906 break;
907 case 0x2: /* ABORT */
908 esp_pci_handle_abort(pci, val);
909 break;
910 case 0x3: /* START */
911 esp_pci_handle_start(pci, val);
912 break;
913 default: /* can't happen */
914 abort();
915 }
916 break;
917 case DMA_STC:
918 case DMA_SPA:
919 case DMA_SMDLA:
920 pci->dma_regs[saddr] = val;
921 break;
922 case DMA_STAT:
923 if (!(pci->sbac & SBAC_STATUS)) {
924 /* clear some bits on write */
925 uint32_t mask = DMA_STAT_ERROR | DMA_STAT_ABORT | DMA_STAT_DONE;
926 pci->dma_regs[DMA_STAT] &= ~(val & mask);
927 }
928 break;
929 default:
930 trace_esp_pci_error_invalid_write_dma(val, saddr);
931 return;
932 }
933}
934
935static uint32_t esp_pci_dma_read(PCIESPState *pci, uint32_t saddr)
936{
937 uint32_t val;
938
939 val = pci->dma_regs[saddr];
940 if (saddr == DMA_STAT) {
941 if (pci->esp.rregs[ESP_RSTAT] & STAT_INT) {
942 val |= DMA_STAT_SCSIINT;
943 }
944 if (pci->sbac & SBAC_STATUS) {
945 pci->dma_regs[DMA_STAT] &= ~(DMA_STAT_ERROR | DMA_STAT_ABORT |
946 DMA_STAT_DONE);
947 }
948 }
949
950 trace_esp_pci_dma_read(saddr, val);
951 return val;
952}
953
954static void esp_pci_io_write(void *opaque, target_phys_addr_t addr,
955 uint64_t val, unsigned int size)
956{
957 PCIESPState *pci = opaque;
958
959 if (size < 4 || addr & 3) {
960 /* need to upgrade request: we only support 4-bytes accesses */
961 uint32_t current = 0, mask;
962 int shift;
963
964 if (addr < 0x40) {
965 current = pci->esp.wregs[addr >> 2];
966 } else if (addr < 0x60) {
967 current = pci->dma_regs[(addr - 0x40) >> 2];
968 } else if (addr < 0x74) {
969 current = pci->sbac;
970 }
971
972 shift = (4 - size) * 8;
973 mask = (~(uint32_t)0 << shift) >> shift;
974
975 shift = ((4 - (addr & 3)) & 3) * 8;
976 val <<= shift;
977 val |= current & ~(mask << shift);
978 addr &= ~3;
979 size = 4;
980 }
981
982 if (addr < 0x40) {
983 /* SCSI core reg */
984 esp_reg_write(&pci->esp, addr >> 2, val);
985 } else if (addr < 0x60) {
986 /* PCI DMA CCB */
987 esp_pci_dma_write(pci, (addr - 0x40) >> 2, val);
988 } else if (addr == 0x70) {
989 /* DMA SCSI Bus and control */
990 trace_esp_pci_sbac_write(pci->sbac, val);
991 pci->sbac = val;
992 } else {
993 trace_esp_pci_error_invalid_write((int)addr);
994 }
995}
996
997static uint64_t esp_pci_io_read(void *opaque, target_phys_addr_t addr,
998 unsigned int size)
999{
1000 PCIESPState *pci = opaque;
1001 uint32_t ret;
1002
1003 if (addr < 0x40) {
1004 /* SCSI core reg */
1005 ret = esp_reg_read(&pci->esp, addr >> 2);
1006 } else if (addr < 0x60) {
1007 /* PCI DMA CCB */
1008 ret = esp_pci_dma_read(pci, (addr - 0x40) >> 2);
1009 } else if (addr == 0x70) {
1010 /* DMA SCSI Bus and control */
1011 trace_esp_pci_sbac_read(pci->sbac);
1012 ret = pci->sbac;
1013 } else {
1014 /* Invalid region */
1015 trace_esp_pci_error_invalid_read((int)addr);
1016 ret = 0;
1017 }
1018
1019 /* give only requested data */
1020 ret >>= (addr & 3) * 8;
1021 ret &= ~(~(uint64_t)0 << (8 * size));
1022
1023 return ret;
1024}
1025
1026static void esp_pci_dma_memory_rw(PCIESPState *pci, uint8_t *buf, int len,
1027 DMADirection dir)
1028{
1029 dma_addr_t addr;
1030 DMADirection expected_dir;
1031
1032 if (pci->dma_regs[DMA_CMD] & DMA_CMD_DIR) {
1033 expected_dir = DMA_DIRECTION_FROM_DEVICE;
1034 } else {
1035 expected_dir = DMA_DIRECTION_TO_DEVICE;
1036 }
1037
1038 if (dir != expected_dir) {
1039 trace_esp_pci_error_invalid_dma_direction();
1040 return;
1041 }
1042
1043 if (pci->dma_regs[DMA_STAT] & DMA_CMD_MDL) {
1044 qemu_log_mask(LOG_UNIMP, "am53c974: MDL transfer not implemented\n");
1045 }
1046
1047 addr = pci->dma_regs[DMA_SPA];
1048 if (pci->dma_regs[DMA_WBC] < len) {
1049 len = pci->dma_regs[DMA_WBC];
1050 }
1051
1052 pci_dma_rw(&pci->dev, addr, buf, len, dir);
1053
1054 /* update status registers */
1055 pci->dma_regs[DMA_WBC] -= len;
1056 pci->dma_regs[DMA_WAC] += len;
1057}
1058
1059static void esp_pci_dma_memory_read(void *opaque, uint8_t *buf, int len)
1060{
1061 PCIESPState *pci = opaque;
1062 esp_pci_dma_memory_rw(pci, buf, len, DMA_DIRECTION_TO_DEVICE);
1063}
1064
1065static void esp_pci_dma_memory_write(void *opaque, uint8_t *buf, int len)
1066{
1067 PCIESPState *pci = opaque;
1068 esp_pci_dma_memory_rw(pci, buf, len, DMA_DIRECTION_FROM_DEVICE);
1069}
1070
1071static const MemoryRegionOps esp_pci_io_ops = {
1072 .read = esp_pci_io_read,
1073 .write = esp_pci_io_write,
1074 .endianness = DEVICE_LITTLE_ENDIAN,
1075 .impl = {
1076 .min_access_size = 1,
1077 .max_access_size = 4,
1078 },
1079};
1080
1081static void esp_pci_hard_reset(DeviceState *dev)
1082{
1083 PCIESPState *pci = DO_UPCAST(PCIESPState, dev.qdev, dev);
1084 esp_hard_reset(&pci->esp);
1085 pci->dma_regs[DMA_CMD] &= ~(DMA_CMD_DIR | DMA_CMD_INTE_D | DMA_CMD_INTE_P
1086 | DMA_CMD_MDL | DMA_CMD_DIAG | DMA_CMD_MASK);
1087 pci->dma_regs[DMA_WBC] &= ~0xffff;
1088 pci->dma_regs[DMA_WAC] = 0xffffffff;
1089 pci->dma_regs[DMA_STAT] &= ~(DMA_STAT_BCMBLT | DMA_STAT_SCSIINT
1090 | DMA_STAT_DONE | DMA_STAT_ABORT
1091 | DMA_STAT_ERROR);
1092 pci->dma_regs[DMA_WMAC] = 0xfffffffd;
1093}
1094
1095static const VMStateDescription vmstate_esp_pci_scsi = {
1096 .name = "pciespscsi",
1097 .version_id = 0,
1098 .minimum_version_id = 0,
1099 .minimum_version_id_old = 0,
1100 .fields = (VMStateField[]) {
1101 VMSTATE_PCI_DEVICE(dev, PCIESPState),
1102 VMSTATE_BUFFER_UNSAFE(dma_regs, PCIESPState, 0, 8 * sizeof(uint32_t)),
1103 VMSTATE_STRUCT(esp, PCIESPState, 0, vmstate_esp, ESPState),
1104 VMSTATE_END_OF_LIST()
1105 }
1106};
1107
1108static void esp_pci_command_complete(SCSIRequest *req, uint32_t status,
1109 size_t resid)
1110{
1111 ESPState *s = req->hba_private;
1112 PCIESPState *pci = container_of(s, PCIESPState, esp);
1113
1114 esp_command_complete(req, status, resid);
1115 pci->dma_regs[DMA_WBC] = 0;
1116 pci->dma_regs[DMA_STAT] |= DMA_STAT_DONE;
1117}
1118
1119static const struct SCSIBusInfo esp_pci_scsi_info = {
1120 .tcq = false,
1121 .max_target = ESP_MAX_DEVS,
1122 .max_lun = 7,
1123
1124 .transfer_data = esp_transfer_data,
1125 .complete = esp_pci_command_complete,
1126 .cancel = esp_request_cancelled,
1127};
1128
1129static int esp_pci_scsi_init(PCIDevice *dev)
1130{
1131 PCIESPState *pci = DO_UPCAST(PCIESPState, dev, dev);
1132 ESPState *s = &pci->esp;
1133 uint8_t *pci_conf;
1134
1135 pci_conf = pci->dev.config;
1136
1137 /* Interrupt pin A */
1138 pci_conf[PCI_INTERRUPT_PIN] = 0x01;
1139
1140 s->dma_memory_read = esp_pci_dma_memory_read;
1141 s->dma_memory_write = esp_pci_dma_memory_write;
1142 s->dma_opaque = pci;
1143 s->chip_id = TCHI_AM53C974;
1144 memory_region_init_io(&pci->io, &esp_pci_io_ops, pci, "esp-io", 0x80);
1145
1146 pci_register_bar(&pci->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &pci->io);
1147 s->irq = pci->dev.irq[0];
1148
1149 scsi_bus_new(&s->bus, &dev->qdev, &esp_pci_scsi_info);
1150 if (!dev->qdev.hotplugged) {
1151 return scsi_bus_legacy_handle_cmdline(&s->bus);
1152 }
1153 return 0;
1154}
1155
5e59b024 1156static void esp_pci_scsi_uninit(PCIDevice *d)
fabaaf1d
HP
1157{
1158 PCIESPState *pci = DO_UPCAST(PCIESPState, dev, d);
1159
1160 memory_region_destroy(&pci->io);
fabaaf1d
HP
1161}
1162
1163static void esp_pci_class_init(ObjectClass *klass, void *data)
1164{
1165 DeviceClass *dc = DEVICE_CLASS(klass);
1166 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
1167
1168 k->init = esp_pci_scsi_init;
1169 k->exit = esp_pci_scsi_uninit;
1170 k->vendor_id = PCI_VENDOR_ID_AMD;
1171 k->device_id = PCI_DEVICE_ID_AMD_SCSI;
1172 k->revision = 0x10;
1173 k->class_id = PCI_CLASS_STORAGE_SCSI;
1174 dc->desc = "AMD Am53c974 PCscsi-PCI SCSI adapter";
1175 dc->reset = esp_pci_hard_reset;
1176 dc->vmsd = &vmstate_esp_pci_scsi;
1177}
1178
1179static TypeInfo esp_pci_info = {
1180 .name = "am53c974",
1181 .parent = TYPE_PCI_DEVICE,
1182 .instance_size = sizeof(PCIESPState),
1183 .class_init = esp_pci_class_init,
1184};
1185
83f7d43a 1186static void esp_register_types(void)
cfb9de9c 1187{
a391fdbc 1188 type_register_static(&sysbus_esp_info);
fabaaf1d 1189 type_register_static(&esp_pci_info);
cfb9de9c
PB
1190}
1191
83f7d43a 1192type_init(esp_register_types)