Statistics
| Branch: | Revision:

root / hw / ide / core.c @ 76b523db

History | View | Annotate | Download (68.8 kB)

1 5391d806 bellard
/*
2 38cdea7c balrog
 * QEMU IDE disk and CD/DVD-ROM Emulator
3 5fafdf24 ths
 *
4 5391d806 bellard
 * Copyright (c) 2003 Fabrice Bellard
5 201a51fc balrog
 * Copyright (c) 2006 Openedhand Ltd.
6 5fafdf24 ths
 *
7 5391d806 bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 5391d806 bellard
 * of this software and associated documentation files (the "Software"), to deal
9 5391d806 bellard
 * in the Software without restriction, including without limitation the rights
10 5391d806 bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 5391d806 bellard
 * copies of the Software, and to permit persons to whom the Software is
12 5391d806 bellard
 * furnished to do so, subject to the following conditions:
13 5391d806 bellard
 *
14 5391d806 bellard
 * The above copyright notice and this permission notice shall be included in
15 5391d806 bellard
 * all copies or substantial portions of the Software.
16 5391d806 bellard
 *
17 5391d806 bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 5391d806 bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 5391d806 bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 5391d806 bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 5391d806 bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 5391d806 bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 5391d806 bellard
 * THE SOFTWARE.
24 5391d806 bellard
 */
25 59f2a787 Gerd Hoffmann
#include <hw/hw.h>
26 59f2a787 Gerd Hoffmann
#include <hw/pc.h>
27 59f2a787 Gerd Hoffmann
#include <hw/pci.h>
28 4a91d3b3 Richard Henderson
#include <hw/isa.h>
29 c4d74df7 Markus Armbruster
#include "qemu-error.h"
30 87ecb68b pbrook
#include "qemu-timer.h"
31 87ecb68b pbrook
#include "sysemu.h"
32 1fb8648d aliguori
#include "dma.h"
33 9db1c0f7 Markus Armbruster
#include "hw/block-common.h"
34 2446333c Blue Swirl
#include "blockdev.h"
35 59f2a787 Gerd Hoffmann
36 59f2a787 Gerd Hoffmann
#include <hw/ide/internal.h>
37 e8b54394 Brian Wheeler
38 b93af93d Brian Wheeler
/* These values were based on a Seagate ST3500418AS but have been modified
39 b93af93d Brian Wheeler
   to make more sense in QEMU */
40 b93af93d Brian Wheeler
static const int smart_attributes[][12] = {
41 b93af93d Brian Wheeler
    /* id,  flags, hflags, val, wrst, raw (6 bytes), threshold */
42 b93af93d Brian Wheeler
    /* raw read error rate*/
43 b93af93d Brian Wheeler
    { 0x01, 0x03, 0x00, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06},
44 b93af93d Brian Wheeler
    /* spin up */
45 b93af93d Brian Wheeler
    { 0x03, 0x03, 0x00, 0x64, 0x64, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
46 b93af93d Brian Wheeler
    /* start stop count */
47 b93af93d Brian Wheeler
    { 0x04, 0x02, 0x00, 0x64, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14},
48 b93af93d Brian Wheeler
    /* remapped sectors */
49 b93af93d Brian Wheeler
    { 0x05, 0x03, 0x00, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24},
50 b93af93d Brian Wheeler
    /* power on hours */
51 b93af93d Brian Wheeler
    { 0x09, 0x03, 0x00, 0x64, 0x64, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
52 b93af93d Brian Wheeler
    /* power cycle count */
53 b93af93d Brian Wheeler
    { 0x0c, 0x03, 0x00, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
54 b93af93d Brian Wheeler
    /* airflow-temperature-celsius */
55 b93af93d Brian Wheeler
    { 190,  0x03, 0x00, 0x45, 0x45, 0x1f, 0x00, 0x1f, 0x1f, 0x00, 0x00, 0x32},
56 b93af93d Brian Wheeler
    /* end of list */
57 b93af93d Brian Wheeler
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
58 e8b54394 Brian Wheeler
};
59 e8b54394 Brian Wheeler
60 ce4b6522 Kevin Wolf
static int ide_handle_rw_error(IDEState *s, int error, int op);
61 40c4ed3f Kevin Wolf
static void ide_dummy_transfer_stop(IDEState *s);
62 98087450 bellard
63 5391d806 bellard
static void padstr(char *str, const char *src, int len)
64 5391d806 bellard
{
65 5391d806 bellard
    int i, v;
66 5391d806 bellard
    for(i = 0; i < len; i++) {
67 5391d806 bellard
        if (*src)
68 5391d806 bellard
            v = *src++;
69 5391d806 bellard
        else
70 5391d806 bellard
            v = ' ';
71 69b34976 ths
        str[i^1] = v;
72 5391d806 bellard
    }
73 5391d806 bellard
}
74 5391d806 bellard
75 67b915a5 bellard
static void put_le16(uint16_t *p, unsigned int v)
76 67b915a5 bellard
{
77 0c4ad8dc bellard
    *p = cpu_to_le16(v);
78 67b915a5 bellard
}
79 67b915a5 bellard
80 5391d806 bellard
static void ide_identify(IDEState *s)
81 5391d806 bellard
{
82 5391d806 bellard
    uint16_t *p;
83 5391d806 bellard
    unsigned int oldsize;
84 d353fb72 Christoph Hellwig
    IDEDevice *dev = s->unit ? s->bus->slave : s->bus->master;
85 5391d806 bellard
86 94458802 bellard
    if (s->identify_set) {
87 94458802 bellard
        memcpy(s->io_buffer, s->identify_data, sizeof(s->identify_data));
88 94458802 bellard
        return;
89 94458802 bellard
    }
90 94458802 bellard
91 5391d806 bellard
    memset(s->io_buffer, 0, 512);
92 5391d806 bellard
    p = (uint16_t *)s->io_buffer;
93 67b915a5 bellard
    put_le16(p + 0, 0x0040);
94 5fafdf24 ths
    put_le16(p + 1, s->cylinders);
95 67b915a5 bellard
    put_le16(p + 3, s->heads);
96 67b915a5 bellard
    put_le16(p + 4, 512 * s->sectors); /* XXX: retired, remove ? */
97 67b915a5 bellard
    put_le16(p + 5, 512); /* XXX: retired, remove ? */
98 5fafdf24 ths
    put_le16(p + 6, s->sectors);
99 fa879c64 aliguori
    padstr((char *)(p + 10), s->drive_serial_str, 20); /* serial number */
100 67b915a5 bellard
    put_le16(p + 20, 3); /* XXX: retired, remove ? */
101 67b915a5 bellard
    put_le16(p + 21, 512); /* cache size in sectors */
102 67b915a5 bellard
    put_le16(p + 22, 4); /* ecc bytes */
103 47c06340 Gerd Hoffmann
    padstr((char *)(p + 23), s->version, 8); /* firmware version */
104 27e0c9a1 Floris Bos
    padstr((char *)(p + 27), s->drive_model_str, 40); /* model */
105 3b46e624 ths
#if MAX_MULT_SECTORS > 1
106 67b915a5 bellard
    put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
107 5391d806 bellard
#endif
108 67b915a5 bellard
    put_le16(p + 48, 1); /* dword I/O */
109 94458802 bellard
    put_le16(p + 49, (1 << 11) | (1 << 9) | (1 << 8)); /* DMA and LBA supported */
110 67b915a5 bellard
    put_le16(p + 51, 0x200); /* PIO transfer cycle */
111 67b915a5 bellard
    put_le16(p + 52, 0x200); /* DMA transfer cycle */
112 94458802 bellard
    put_le16(p + 53, 1 | (1 << 1) | (1 << 2)); /* words 54-58,64-70,88 are valid */
113 67b915a5 bellard
    put_le16(p + 54, s->cylinders);
114 67b915a5 bellard
    put_le16(p + 55, s->heads);
115 67b915a5 bellard
    put_le16(p + 56, s->sectors);
116 5391d806 bellard
    oldsize = s->cylinders * s->heads * s->sectors;
117 67b915a5 bellard
    put_le16(p + 57, oldsize);
118 67b915a5 bellard
    put_le16(p + 58, oldsize >> 16);
119 5391d806 bellard
    if (s->mult_sectors)
120 67b915a5 bellard
        put_le16(p + 59, 0x100 | s->mult_sectors);
121 67b915a5 bellard
    put_le16(p + 60, s->nb_sectors);
122 67b915a5 bellard
    put_le16(p + 61, s->nb_sectors >> 16);
123 d1b5c20d ths
    put_le16(p + 62, 0x07); /* single word dma0-2 supported */
124 94458802 bellard
    put_le16(p + 63, 0x07); /* mdma0-2 supported */
125 79d1d331 Jonathan A. Kollasch
    put_le16(p + 64, 0x03); /* pio3-4 supported */
126 94458802 bellard
    put_le16(p + 65, 120);
127 94458802 bellard
    put_le16(p + 66, 120);
128 94458802 bellard
    put_le16(p + 67, 120);
129 94458802 bellard
    put_le16(p + 68, 120);
130 d353fb72 Christoph Hellwig
    if (dev && dev->conf.discard_granularity) {
131 d353fb72 Christoph Hellwig
        put_le16(p + 69, (1 << 14)); /* determinate TRIM behavior */
132 d353fb72 Christoph Hellwig
    }
133 ccf0fd8b Roland Elek
134 ccf0fd8b Roland Elek
    if (s->ncq_queues) {
135 ccf0fd8b Roland Elek
        put_le16(p + 75, s->ncq_queues - 1);
136 ccf0fd8b Roland Elek
        /* NCQ supported */
137 ccf0fd8b Roland Elek
        put_le16(p + 76, (1 << 8));
138 ccf0fd8b Roland Elek
    }
139 ccf0fd8b Roland Elek
140 94458802 bellard
    put_le16(p + 80, 0xf0); /* ata3 -> ata6 supported */
141 94458802 bellard
    put_le16(p + 81, 0x16); /* conforms to ata5 */
142 a58b8d54 Christoph Hellwig
    /* 14=NOP supported, 5=WCACHE supported, 0=SMART supported */
143 a58b8d54 Christoph Hellwig
    put_le16(p + 82, (1 << 14) | (1 << 5) | 1);
144 c2ff060f bellard
    /* 13=flush_cache_ext,12=flush_cache,10=lba48 */
145 c2ff060f bellard
    put_le16(p + 83, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10));
146 95ebda85 Floris Bos
    /* 14=set to 1, 8=has WWN, 1=SMART self test, 0=SMART error logging */
147 95ebda85 Floris Bos
    if (s->wwn) {
148 95ebda85 Floris Bos
        put_le16(p + 84, (1 << 14) | (1 << 8) | 0);
149 95ebda85 Floris Bos
    } else {
150 95ebda85 Floris Bos
        put_le16(p + 84, (1 << 14) | 0);
151 95ebda85 Floris Bos
    }
152 e900a7b7 Christoph Hellwig
    /* 14 = NOP supported, 5=WCACHE enabled, 0=SMART feature set enabled */
153 e900a7b7 Christoph Hellwig
    if (bdrv_enable_write_cache(s->bs))
154 e900a7b7 Christoph Hellwig
         put_le16(p + 85, (1 << 14) | (1 << 5) | 1);
155 e900a7b7 Christoph Hellwig
    else
156 e900a7b7 Christoph Hellwig
         put_le16(p + 85, (1 << 14) | 1);
157 c2ff060f bellard
    /* 13=flush_cache_ext,12=flush_cache,10=lba48 */
158 2844bdd9 Kevin Wolf
    put_le16(p + 86, (1 << 13) | (1 <<12) | (1 << 10));
159 95ebda85 Floris Bos
    /* 14=set to 1, 8=has WWN, 1=SMART self test, 0=SMART error logging */
160 95ebda85 Floris Bos
    if (s->wwn) {
161 95ebda85 Floris Bos
        put_le16(p + 87, (1 << 14) | (1 << 8) | 0);
162 95ebda85 Floris Bos
    } else {
163 95ebda85 Floris Bos
        put_le16(p + 87, (1 << 14) | 0);
164 95ebda85 Floris Bos
    }
165 94458802 bellard
    put_le16(p + 88, 0x3f | (1 << 13)); /* udma5 set and supported */
166 94458802 bellard
    put_le16(p + 93, 1 | (1 << 14) | 0x2000);
167 c2ff060f bellard
    put_le16(p + 100, s->nb_sectors);
168 c2ff060f bellard
    put_le16(p + 101, s->nb_sectors >> 16);
169 c2ff060f bellard
    put_le16(p + 102, s->nb_sectors >> 32);
170 c2ff060f bellard
    put_le16(p + 103, s->nb_sectors >> 48);
171 d353fb72 Christoph Hellwig
172 57dac7ef Markus Armbruster
    if (dev && dev->conf.physical_block_size)
173 57dac7ef Markus Armbruster
        put_le16(p + 106, 0x6000 | get_physical_block_exp(&dev->conf));
174 95ebda85 Floris Bos
    if (s->wwn) {
175 95ebda85 Floris Bos
        /* LE 16-bit words 111-108 contain 64-bit World Wide Name */
176 95ebda85 Floris Bos
        put_le16(p + 108, s->wwn >> 48);
177 95ebda85 Floris Bos
        put_le16(p + 109, s->wwn >> 32);
178 95ebda85 Floris Bos
        put_le16(p + 110, s->wwn >> 16);
179 95ebda85 Floris Bos
        put_le16(p + 111, s->wwn);
180 95ebda85 Floris Bos
    }
181 d353fb72 Christoph Hellwig
    if (dev && dev->conf.discard_granularity) {
182 d353fb72 Christoph Hellwig
        put_le16(p + 169, 1); /* TRIM support */
183 d353fb72 Christoph Hellwig
    }
184 94458802 bellard
185 94458802 bellard
    memcpy(s->identify_data, p, sizeof(s->identify_data));
186 94458802 bellard
    s->identify_set = 1;
187 5391d806 bellard
}
188 5391d806 bellard
189 5391d806 bellard
static void ide_atapi_identify(IDEState *s)
190 5391d806 bellard
{
191 5391d806 bellard
    uint16_t *p;
192 5391d806 bellard
193 94458802 bellard
    if (s->identify_set) {
194 94458802 bellard
        memcpy(s->io_buffer, s->identify_data, sizeof(s->identify_data));
195 94458802 bellard
        return;
196 94458802 bellard
    }
197 94458802 bellard
198 5391d806 bellard
    memset(s->io_buffer, 0, 512);
199 5391d806 bellard
    p = (uint16_t *)s->io_buffer;
200 5391d806 bellard
    /* Removable CDROM, 50us response, 12 byte packets */
201 67b915a5 bellard
    put_le16(p + 0, (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0));
202 fa879c64 aliguori
    padstr((char *)(p + 10), s->drive_serial_str, 20); /* serial number */
203 67b915a5 bellard
    put_le16(p + 20, 3); /* buffer type */
204 67b915a5 bellard
    put_le16(p + 21, 512); /* cache size in sectors */
205 67b915a5 bellard
    put_le16(p + 22, 4); /* ecc bytes */
206 47c06340 Gerd Hoffmann
    padstr((char *)(p + 23), s->version, 8); /* firmware version */
207 27e0c9a1 Floris Bos
    padstr((char *)(p + 27), s->drive_model_str, 40); /* model */
208 67b915a5 bellard
    put_le16(p + 48, 1); /* dword I/O (XXX: should not be set on CDROM) */
209 8ccad811 bellard
#ifdef USE_DMA_CDROM
210 8ccad811 bellard
    put_le16(p + 49, 1 << 9 | 1 << 8); /* DMA and LBA supported */
211 8ccad811 bellard
    put_le16(p + 53, 7); /* words 64-70, 54-58, 88 valid */
212 d1b5c20d ths
    put_le16(p + 62, 7);  /* single word dma0-2 supported */
213 8ccad811 bellard
    put_le16(p + 63, 7);  /* mdma0-2 supported */
214 8ccad811 bellard
#else
215 67b915a5 bellard
    put_le16(p + 49, 1 << 9); /* LBA supported, no DMA */
216 67b915a5 bellard
    put_le16(p + 53, 3); /* words 64-70, 54-58 valid */
217 67b915a5 bellard
    put_le16(p + 63, 0x103); /* DMA modes XXX: may be incorrect */
218 8ccad811 bellard
#endif
219 79d1d331 Jonathan A. Kollasch
    put_le16(p + 64, 3); /* pio3-4 supported */
220 67b915a5 bellard
    put_le16(p + 65, 0xb4); /* minimum DMA multiword tx cycle time */
221 67b915a5 bellard
    put_le16(p + 66, 0xb4); /* recommended DMA multiword tx cycle time */
222 67b915a5 bellard
    put_le16(p + 67, 0x12c); /* minimum PIO cycle time without flow control */
223 67b915a5 bellard
    put_le16(p + 68, 0xb4); /* minimum PIO cycle time with IORDY flow control */
224 94458802 bellard
225 67b915a5 bellard
    put_le16(p + 71, 30); /* in ns */
226 67b915a5 bellard
    put_le16(p + 72, 30); /* in ns */
227 5391d806 bellard
228 1bdaa28d Alexander Graf
    if (s->ncq_queues) {
229 1bdaa28d Alexander Graf
        put_le16(p + 75, s->ncq_queues - 1);
230 1bdaa28d Alexander Graf
        /* NCQ supported */
231 1bdaa28d Alexander Graf
        put_le16(p + 76, (1 << 8));
232 1bdaa28d Alexander Graf
    }
233 1bdaa28d Alexander Graf
234 67b915a5 bellard
    put_le16(p + 80, 0x1e); /* support up to ATA/ATAPI-4 */
235 8ccad811 bellard
#ifdef USE_DMA_CDROM
236 8ccad811 bellard
    put_le16(p + 88, 0x3f | (1 << 13)); /* udma5 set and supported */
237 8ccad811 bellard
#endif
238 94458802 bellard
    memcpy(s->identify_data, p, sizeof(s->identify_data));
239 94458802 bellard
    s->identify_set = 1;
240 5391d806 bellard
}
241 5391d806 bellard
242 201a51fc balrog
static void ide_cfata_identify(IDEState *s)
243 201a51fc balrog
{
244 201a51fc balrog
    uint16_t *p;
245 201a51fc balrog
    uint32_t cur_sec;
246 201a51fc balrog
247 201a51fc balrog
    p = (uint16_t *) s->identify_data;
248 201a51fc balrog
    if (s->identify_set)
249 201a51fc balrog
        goto fill_buffer;
250 201a51fc balrog
251 201a51fc balrog
    memset(p, 0, sizeof(s->identify_data));
252 201a51fc balrog
253 201a51fc balrog
    cur_sec = s->cylinders * s->heads * s->sectors;
254 201a51fc balrog
255 201a51fc balrog
    put_le16(p + 0, 0x848a);                        /* CF Storage Card signature */
256 201a51fc balrog
    put_le16(p + 1, s->cylinders);                /* Default cylinders */
257 201a51fc balrog
    put_le16(p + 3, s->heads);                        /* Default heads */
258 201a51fc balrog
    put_le16(p + 6, s->sectors);                /* Default sectors per track */
259 201a51fc balrog
    put_le16(p + 7, s->nb_sectors >> 16);        /* Sectors per card */
260 201a51fc balrog
    put_le16(p + 8, s->nb_sectors);                /* Sectors per card */
261 fa879c64 aliguori
    padstr((char *)(p + 10), s->drive_serial_str, 20); /* serial number */
262 201a51fc balrog
    put_le16(p + 22, 0x0004);                        /* ECC bytes */
263 47c06340 Gerd Hoffmann
    padstr((char *) (p + 23), s->version, 8);        /* Firmware Revision */
264 27e0c9a1 Floris Bos
    padstr((char *) (p + 27), s->drive_model_str, 40);/* Model number */
265 201a51fc balrog
#if MAX_MULT_SECTORS > 1
266 201a51fc balrog
    put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
267 201a51fc balrog
#else
268 201a51fc balrog
    put_le16(p + 47, 0x0000);
269 201a51fc balrog
#endif
270 201a51fc balrog
    put_le16(p + 49, 0x0f00);                        /* Capabilities */
271 201a51fc balrog
    put_le16(p + 51, 0x0002);                        /* PIO cycle timing mode */
272 201a51fc balrog
    put_le16(p + 52, 0x0001);                        /* DMA cycle timing mode */
273 201a51fc balrog
    put_le16(p + 53, 0x0003);                        /* Translation params valid */
274 201a51fc balrog
    put_le16(p + 54, s->cylinders);                /* Current cylinders */
275 201a51fc balrog
    put_le16(p + 55, s->heads);                        /* Current heads */
276 201a51fc balrog
    put_le16(p + 56, s->sectors);                /* Current sectors */
277 201a51fc balrog
    put_le16(p + 57, cur_sec);                        /* Current capacity */
278 201a51fc balrog
    put_le16(p + 58, cur_sec >> 16);                /* Current capacity */
279 201a51fc balrog
    if (s->mult_sectors)                        /* Multiple sector setting */
280 201a51fc balrog
        put_le16(p + 59, 0x100 | s->mult_sectors);
281 201a51fc balrog
    put_le16(p + 60, s->nb_sectors);                /* Total LBA sectors */
282 201a51fc balrog
    put_le16(p + 61, s->nb_sectors >> 16);        /* Total LBA sectors */
283 201a51fc balrog
    put_le16(p + 63, 0x0203);                        /* Multiword DMA capability */
284 201a51fc balrog
    put_le16(p + 64, 0x0001);                        /* Flow Control PIO support */
285 201a51fc balrog
    put_le16(p + 65, 0x0096);                        /* Min. Multiword DMA cycle */
286 201a51fc balrog
    put_le16(p + 66, 0x0096);                        /* Rec. Multiword DMA cycle */
287 201a51fc balrog
    put_le16(p + 68, 0x00b4);                        /* Min. PIO cycle time */
288 201a51fc balrog
    put_le16(p + 82, 0x400c);                        /* Command Set supported */
289 201a51fc balrog
    put_le16(p + 83, 0x7068);                        /* Command Set supported */
290 201a51fc balrog
    put_le16(p + 84, 0x4000);                        /* Features supported */
291 201a51fc balrog
    put_le16(p + 85, 0x000c);                        /* Command Set enabled */
292 201a51fc balrog
    put_le16(p + 86, 0x7044);                        /* Command Set enabled */
293 201a51fc balrog
    put_le16(p + 87, 0x4000);                        /* Features enabled */
294 201a51fc balrog
    put_le16(p + 91, 0x4060);                        /* Current APM level */
295 201a51fc balrog
    put_le16(p + 129, 0x0002);                        /* Current features option */
296 201a51fc balrog
    put_le16(p + 130, 0x0005);                        /* Reassigned sectors */
297 201a51fc balrog
    put_le16(p + 131, 0x0001);                        /* Initial power mode */
298 201a51fc balrog
    put_le16(p + 132, 0x0000);                        /* User signature */
299 201a51fc balrog
    put_le16(p + 160, 0x8100);                        /* Power requirement */
300 201a51fc balrog
    put_le16(p + 161, 0x8001);                        /* CF command set */
301 201a51fc balrog
302 201a51fc balrog
    s->identify_set = 1;
303 201a51fc balrog
304 201a51fc balrog
fill_buffer:
305 201a51fc balrog
    memcpy(s->io_buffer, p, sizeof(s->identify_data));
306 201a51fc balrog
}
307 201a51fc balrog
308 5391d806 bellard
static void ide_set_signature(IDEState *s)
309 5391d806 bellard
{
310 5391d806 bellard
    s->select &= 0xf0; /* clear head */
311 5391d806 bellard
    /* put signature */
312 5391d806 bellard
    s->nsector = 1;
313 5391d806 bellard
    s->sector = 1;
314 cd8722bb Markus Armbruster
    if (s->drive_kind == IDE_CD) {
315 5391d806 bellard
        s->lcyl = 0x14;
316 5391d806 bellard
        s->hcyl = 0xeb;
317 5391d806 bellard
    } else if (s->bs) {
318 5391d806 bellard
        s->lcyl = 0;
319 5391d806 bellard
        s->hcyl = 0;
320 5391d806 bellard
    } else {
321 5391d806 bellard
        s->lcyl = 0xff;
322 5391d806 bellard
        s->hcyl = 0xff;
323 5391d806 bellard
    }
324 5391d806 bellard
}
325 5391d806 bellard
326 d353fb72 Christoph Hellwig
typedef struct TrimAIOCB {
327 d353fb72 Christoph Hellwig
    BlockDriverAIOCB common;
328 d353fb72 Christoph Hellwig
    QEMUBH *bh;
329 d353fb72 Christoph Hellwig
    int ret;
330 d353fb72 Christoph Hellwig
} TrimAIOCB;
331 d353fb72 Christoph Hellwig
332 d353fb72 Christoph Hellwig
static void trim_aio_cancel(BlockDriverAIOCB *acb)
333 d353fb72 Christoph Hellwig
{
334 d353fb72 Christoph Hellwig
    TrimAIOCB *iocb = container_of(acb, TrimAIOCB, common);
335 d353fb72 Christoph Hellwig
336 d353fb72 Christoph Hellwig
    qemu_bh_delete(iocb->bh);
337 d353fb72 Christoph Hellwig
    iocb->bh = NULL;
338 d353fb72 Christoph Hellwig
    qemu_aio_release(iocb);
339 d353fb72 Christoph Hellwig
}
340 d353fb72 Christoph Hellwig
341 d353fb72 Christoph Hellwig
static AIOPool trim_aio_pool = {
342 d353fb72 Christoph Hellwig
    .aiocb_size         = sizeof(TrimAIOCB),
343 d353fb72 Christoph Hellwig
    .cancel             = trim_aio_cancel,
344 d353fb72 Christoph Hellwig
};
345 d353fb72 Christoph Hellwig
346 d353fb72 Christoph Hellwig
static void ide_trim_bh_cb(void *opaque)
347 d353fb72 Christoph Hellwig
{
348 d353fb72 Christoph Hellwig
    TrimAIOCB *iocb = opaque;
349 d353fb72 Christoph Hellwig
350 d353fb72 Christoph Hellwig
    iocb->common.cb(iocb->common.opaque, iocb->ret);
351 d353fb72 Christoph Hellwig
352 d353fb72 Christoph Hellwig
    qemu_bh_delete(iocb->bh);
353 d353fb72 Christoph Hellwig
    iocb->bh = NULL;
354 d353fb72 Christoph Hellwig
355 d353fb72 Christoph Hellwig
    qemu_aio_release(iocb);
356 d353fb72 Christoph Hellwig
}
357 d353fb72 Christoph Hellwig
358 d353fb72 Christoph Hellwig
BlockDriverAIOCB *ide_issue_trim(BlockDriverState *bs,
359 d353fb72 Christoph Hellwig
        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
360 d353fb72 Christoph Hellwig
        BlockDriverCompletionFunc *cb, void *opaque)
361 d353fb72 Christoph Hellwig
{
362 d353fb72 Christoph Hellwig
    TrimAIOCB *iocb;
363 d353fb72 Christoph Hellwig
    int i, j, ret;
364 d353fb72 Christoph Hellwig
365 d353fb72 Christoph Hellwig
    iocb = qemu_aio_get(&trim_aio_pool, bs, cb, opaque);
366 d353fb72 Christoph Hellwig
    iocb->bh = qemu_bh_new(ide_trim_bh_cb, iocb);
367 d353fb72 Christoph Hellwig
    iocb->ret = 0;
368 d353fb72 Christoph Hellwig
369 d353fb72 Christoph Hellwig
    for (j = 0; j < qiov->niov; j++) {
370 d353fb72 Christoph Hellwig
        uint64_t *buffer = qiov->iov[j].iov_base;
371 d353fb72 Christoph Hellwig
372 d353fb72 Christoph Hellwig
        for (i = 0; i < qiov->iov[j].iov_len / 8; i++) {
373 d353fb72 Christoph Hellwig
            /* 6-byte LBA + 2-byte range per entry */
374 d353fb72 Christoph Hellwig
            uint64_t entry = le64_to_cpu(buffer[i]);
375 d353fb72 Christoph Hellwig
            uint64_t sector = entry & 0x0000ffffffffffffULL;
376 d353fb72 Christoph Hellwig
            uint16_t count = entry >> 48;
377 d353fb72 Christoph Hellwig
378 d353fb72 Christoph Hellwig
            if (count == 0) {
379 d353fb72 Christoph Hellwig
                break;
380 d353fb72 Christoph Hellwig
            }
381 d353fb72 Christoph Hellwig
382 d353fb72 Christoph Hellwig
            ret = bdrv_discard(bs, sector, count);
383 d353fb72 Christoph Hellwig
            if (!iocb->ret) {
384 d353fb72 Christoph Hellwig
                iocb->ret = ret;
385 d353fb72 Christoph Hellwig
            }
386 d353fb72 Christoph Hellwig
        }
387 d353fb72 Christoph Hellwig
    }
388 d353fb72 Christoph Hellwig
389 d353fb72 Christoph Hellwig
    qemu_bh_schedule(iocb->bh);
390 d353fb72 Christoph Hellwig
391 d353fb72 Christoph Hellwig
    return &iocb->common;
392 d353fb72 Christoph Hellwig
}
393 d353fb72 Christoph Hellwig
394 5391d806 bellard
static inline void ide_abort_command(IDEState *s)
395 5391d806 bellard
{
396 5391d806 bellard
    s->status = READY_STAT | ERR_STAT;
397 5391d806 bellard
    s->error = ABRT_ERR;
398 5391d806 bellard
}
399 5391d806 bellard
400 5391d806 bellard
/* prepare data transfer and tell what to do after */
401 33231e0e Kevin Wolf
void ide_transfer_start(IDEState *s, uint8_t *buf, int size,
402 33231e0e Kevin Wolf
                        EndTransferFunc *end_transfer_func)
403 5391d806 bellard
{
404 5391d806 bellard
    s->end_transfer_func = end_transfer_func;
405 5391d806 bellard
    s->data_ptr = buf;
406 5391d806 bellard
    s->data_end = buf + size;
407 40a6238a Alexander Graf
    if (!(s->status & ERR_STAT)) {
408 7603d156 ths
        s->status |= DRQ_STAT;
409 40a6238a Alexander Graf
    }
410 40a6238a Alexander Graf
    s->bus->dma->ops->start_transfer(s->bus->dma);
411 5391d806 bellard
}
412 5391d806 bellard
413 33231e0e Kevin Wolf
void ide_transfer_stop(IDEState *s)
414 5391d806 bellard
{
415 5391d806 bellard
    s->end_transfer_func = ide_transfer_stop;
416 5391d806 bellard
    s->data_ptr = s->io_buffer;
417 5391d806 bellard
    s->data_end = s->io_buffer;
418 5391d806 bellard
    s->status &= ~DRQ_STAT;
419 5391d806 bellard
}
420 5391d806 bellard
421 356721ae Gerd Hoffmann
int64_t ide_get_sector(IDEState *s)
422 5391d806 bellard
{
423 5391d806 bellard
    int64_t sector_num;
424 5391d806 bellard
    if (s->select & 0x40) {
425 5391d806 bellard
        /* lba */
426 c2ff060f bellard
        if (!s->lba48) {
427 c2ff060f bellard
            sector_num = ((s->select & 0x0f) << 24) | (s->hcyl << 16) |
428 c2ff060f bellard
                (s->lcyl << 8) | s->sector;
429 c2ff060f bellard
        } else {
430 c2ff060f bellard
            sector_num = ((int64_t)s->hob_hcyl << 40) |
431 c2ff060f bellard
                ((int64_t) s->hob_lcyl << 32) |
432 c2ff060f bellard
                ((int64_t) s->hob_sector << 24) |
433 c2ff060f bellard
                ((int64_t) s->hcyl << 16) |
434 c2ff060f bellard
                ((int64_t) s->lcyl << 8) | s->sector;
435 c2ff060f bellard
        }
436 5391d806 bellard
    } else {
437 5391d806 bellard
        sector_num = ((s->hcyl << 8) | s->lcyl) * s->heads * s->sectors +
438 c2ff060f bellard
            (s->select & 0x0f) * s->sectors + (s->sector - 1);
439 5391d806 bellard
    }
440 5391d806 bellard
    return sector_num;
441 5391d806 bellard
}
442 5391d806 bellard
443 356721ae Gerd Hoffmann
void ide_set_sector(IDEState *s, int64_t sector_num)
444 5391d806 bellard
{
445 5391d806 bellard
    unsigned int cyl, r;
446 5391d806 bellard
    if (s->select & 0x40) {
447 c2ff060f bellard
        if (!s->lba48) {
448 c2ff060f bellard
            s->select = (s->select & 0xf0) | (sector_num >> 24);
449 c2ff060f bellard
            s->hcyl = (sector_num >> 16);
450 c2ff060f bellard
            s->lcyl = (sector_num >> 8);
451 c2ff060f bellard
            s->sector = (sector_num);
452 c2ff060f bellard
        } else {
453 c2ff060f bellard
            s->sector = sector_num;
454 c2ff060f bellard
            s->lcyl = sector_num >> 8;
455 c2ff060f bellard
            s->hcyl = sector_num >> 16;
456 c2ff060f bellard
            s->hob_sector = sector_num >> 24;
457 c2ff060f bellard
            s->hob_lcyl = sector_num >> 32;
458 c2ff060f bellard
            s->hob_hcyl = sector_num >> 40;
459 c2ff060f bellard
        }
460 5391d806 bellard
    } else {
461 5391d806 bellard
        cyl = sector_num / (s->heads * s->sectors);
462 5391d806 bellard
        r = sector_num % (s->heads * s->sectors);
463 5391d806 bellard
        s->hcyl = cyl >> 8;
464 5391d806 bellard
        s->lcyl = cyl;
465 1b8eb456 bellard
        s->select = (s->select & 0xf0) | ((r / s->sectors) & 0x0f);
466 5391d806 bellard
        s->sector = (r % s->sectors) + 1;
467 5391d806 bellard
    }
468 5391d806 bellard
}
469 5391d806 bellard
470 e162cfb0 balrog
static void ide_rw_error(IDEState *s) {
471 e162cfb0 balrog
    ide_abort_command(s);
472 9cdd03a7 Gerd Hoffmann
    ide_set_irq(s->bus);
473 e162cfb0 balrog
}
474 e162cfb0 balrog
475 bef0fd59 Stefan Hajnoczi
static void ide_sector_read_cb(void *opaque, int ret)
476 bef0fd59 Stefan Hajnoczi
{
477 bef0fd59 Stefan Hajnoczi
    IDEState *s = opaque;
478 bef0fd59 Stefan Hajnoczi
    int n;
479 bef0fd59 Stefan Hajnoczi
480 bef0fd59 Stefan Hajnoczi
    s->pio_aiocb = NULL;
481 bef0fd59 Stefan Hajnoczi
    s->status &= ~BUSY_STAT;
482 bef0fd59 Stefan Hajnoczi
483 bef0fd59 Stefan Hajnoczi
    bdrv_acct_done(s->bs, &s->acct);
484 bef0fd59 Stefan Hajnoczi
    if (ret != 0) {
485 bef0fd59 Stefan Hajnoczi
        if (ide_handle_rw_error(s, -ret, BM_STATUS_PIO_RETRY |
486 bef0fd59 Stefan Hajnoczi
                                BM_STATUS_RETRY_READ)) {
487 bef0fd59 Stefan Hajnoczi
            return;
488 bef0fd59 Stefan Hajnoczi
        }
489 bef0fd59 Stefan Hajnoczi
    }
490 bef0fd59 Stefan Hajnoczi
491 bef0fd59 Stefan Hajnoczi
    n = s->nsector;
492 bef0fd59 Stefan Hajnoczi
    if (n > s->req_nb_sectors) {
493 bef0fd59 Stefan Hajnoczi
        n = s->req_nb_sectors;
494 bef0fd59 Stefan Hajnoczi
    }
495 bef0fd59 Stefan Hajnoczi
496 bef0fd59 Stefan Hajnoczi
    /* Allow the guest to read the io_buffer */
497 bef0fd59 Stefan Hajnoczi
    ide_transfer_start(s, s->io_buffer, n * BDRV_SECTOR_SIZE, ide_sector_read);
498 bef0fd59 Stefan Hajnoczi
499 bef0fd59 Stefan Hajnoczi
    ide_set_irq(s->bus);
500 bef0fd59 Stefan Hajnoczi
501 bef0fd59 Stefan Hajnoczi
    ide_set_sector(s, ide_get_sector(s) + n);
502 bef0fd59 Stefan Hajnoczi
    s->nsector -= n;
503 bef0fd59 Stefan Hajnoczi
}
504 bef0fd59 Stefan Hajnoczi
505 40a6238a Alexander Graf
void ide_sector_read(IDEState *s)
506 5391d806 bellard
{
507 5391d806 bellard
    int64_t sector_num;
508 bef0fd59 Stefan Hajnoczi
    int n;
509 5391d806 bellard
510 5391d806 bellard
    s->status = READY_STAT | SEEK_STAT;
511 a136e5a8 bellard
    s->error = 0; /* not needed by IDE spec, but needed by Windows */
512 5391d806 bellard
    sector_num = ide_get_sector(s);
513 5391d806 bellard
    n = s->nsector;
514 bef0fd59 Stefan Hajnoczi
515 5391d806 bellard
    if (n == 0) {
516 5391d806 bellard
        ide_transfer_stop(s);
517 bef0fd59 Stefan Hajnoczi
        return;
518 bef0fd59 Stefan Hajnoczi
    }
519 bef0fd59 Stefan Hajnoczi
520 bef0fd59 Stefan Hajnoczi
    s->status |= BUSY_STAT;
521 bef0fd59 Stefan Hajnoczi
522 bef0fd59 Stefan Hajnoczi
    if (n > s->req_nb_sectors) {
523 bef0fd59 Stefan Hajnoczi
        n = s->req_nb_sectors;
524 bef0fd59 Stefan Hajnoczi
    }
525 bef0fd59 Stefan Hajnoczi
526 5391d806 bellard
#if defined(DEBUG_IDE)
527 bef0fd59 Stefan Hajnoczi
    printf("sector=%" PRId64 "\n", sector_num);
528 5391d806 bellard
#endif
529 a597e79c Christoph Hellwig
530 bef0fd59 Stefan Hajnoczi
    s->iov.iov_base = s->io_buffer;
531 bef0fd59 Stefan Hajnoczi
    s->iov.iov_len  = n * BDRV_SECTOR_SIZE;
532 bef0fd59 Stefan Hajnoczi
    qemu_iovec_init_external(&s->qiov, &s->iov, 1);
533 bef0fd59 Stefan Hajnoczi
534 bef0fd59 Stefan Hajnoczi
    bdrv_acct_start(s->bs, &s->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
535 bef0fd59 Stefan Hajnoczi
    s->pio_aiocb = bdrv_aio_readv(s->bs, sector_num, &s->qiov, n,
536 bef0fd59 Stefan Hajnoczi
                                  ide_sector_read_cb, s);
537 5391d806 bellard
}
538 5391d806 bellard
539 b61744b3 Paolo Bonzini
static void dma_buf_commit(IDEState *s)
540 7aea4412 aliguori
{
541 1fb8648d aliguori
    qemu_sglist_destroy(&s->sg);
542 7aea4412 aliguori
}
543 7aea4412 aliguori
544 33231e0e Kevin Wolf
void ide_set_inactive(IDEState *s)
545 8337606d Kevin Wolf
{
546 40a6238a Alexander Graf
    s->bus->dma->aiocb = NULL;
547 40a6238a Alexander Graf
    s->bus->dma->ops->set_inactive(s->bus->dma);
548 8337606d Kevin Wolf
}
549 8337606d Kevin Wolf
550 356721ae Gerd Hoffmann
void ide_dma_error(IDEState *s)
551 e162cfb0 balrog
{
552 e162cfb0 balrog
    ide_transfer_stop(s);
553 e162cfb0 balrog
    s->error = ABRT_ERR;
554 e162cfb0 balrog
    s->status = READY_STAT | ERR_STAT;
555 40a6238a Alexander Graf
    ide_set_inactive(s);
556 9cdd03a7 Gerd Hoffmann
    ide_set_irq(s->bus);
557 e162cfb0 balrog
}
558 e162cfb0 balrog
559 ce4b6522 Kevin Wolf
static int ide_handle_rw_error(IDEState *s, int error, int op)
560 428c5705 aliguori
{
561 ce4b6522 Kevin Wolf
    int is_read = (op & BM_STATUS_RETRY_READ);
562 abd7f68d Markus Armbruster
    BlockErrorAction action = bdrv_get_on_error(s->bs, is_read);
563 428c5705 aliguori
564 7ad7e3c3 Luiz Capitulino
    if (action == BLOCK_ERR_IGNORE) {
565 329c0a48 Luiz Capitulino
        bdrv_emit_qmp_error_event(s->bs, BDRV_ACTION_IGNORE, is_read);
566 428c5705 aliguori
        return 0;
567 7ad7e3c3 Luiz Capitulino
    }
568 428c5705 aliguori
569 428c5705 aliguori
    if ((error == ENOSPC && action == BLOCK_ERR_STOP_ENOSPC)
570 428c5705 aliguori
            || action == BLOCK_ERR_STOP_ANY) {
571 40a6238a Alexander Graf
        s->bus->dma->ops->set_unit(s->bus->dma, s->unit);
572 def93791 Kevin Wolf
        s->bus->error_status = op;
573 329c0a48 Luiz Capitulino
        bdrv_emit_qmp_error_event(s->bs, BDRV_ACTION_STOP, is_read);
574 0461d5a6 Luiz Capitulino
        vm_stop(RUN_STATE_IO_ERROR);
575 50fb1900 Luiz Capitulino
        bdrv_iostatus_set_err(s->bs, error);
576 428c5705 aliguori
    } else {
577 ce4b6522 Kevin Wolf
        if (op & BM_STATUS_DMA_RETRY) {
578 b61744b3 Paolo Bonzini
            dma_buf_commit(s);
579 428c5705 aliguori
            ide_dma_error(s);
580 7aea4412 aliguori
        } else {
581 428c5705 aliguori
            ide_rw_error(s);
582 7aea4412 aliguori
        }
583 329c0a48 Luiz Capitulino
        bdrv_emit_qmp_error_event(s->bs, BDRV_ACTION_REPORT, is_read);
584 428c5705 aliguori
    }
585 428c5705 aliguori
586 428c5705 aliguori
    return 1;
587 428c5705 aliguori
}
588 428c5705 aliguori
589 cd369c46 Christoph Hellwig
void ide_dma_cb(void *opaque, int ret)
590 98087450 bellard
{
591 40a6238a Alexander Graf
    IDEState *s = opaque;
592 8ccad811 bellard
    int n;
593 8ccad811 bellard
    int64_t sector_num;
594 8ccad811 bellard
595 e162cfb0 balrog
    if (ret < 0) {
596 cd369c46 Christoph Hellwig
        int op = BM_STATUS_DMA_RETRY;
597 cd369c46 Christoph Hellwig
598 4e1e0051 Christoph Hellwig
        if (s->dma_cmd == IDE_DMA_READ)
599 cd369c46 Christoph Hellwig
            op |= BM_STATUS_RETRY_READ;
600 d353fb72 Christoph Hellwig
        else if (s->dma_cmd == IDE_DMA_TRIM)
601 d353fb72 Christoph Hellwig
            op |= BM_STATUS_RETRY_TRIM;
602 d353fb72 Christoph Hellwig
603 cd369c46 Christoph Hellwig
        if (ide_handle_rw_error(s, -ret, op)) {
604 ce4b6522 Kevin Wolf
            return;
605 ce4b6522 Kevin Wolf
        }
606 e162cfb0 balrog
    }
607 e162cfb0 balrog
608 8ccad811 bellard
    n = s->io_buffer_size >> 9;
609 8ccad811 bellard
    sector_num = ide_get_sector(s);
610 8ccad811 bellard
    if (n > 0) {
611 b61744b3 Paolo Bonzini
        dma_buf_commit(s);
612 8ccad811 bellard
        sector_num += n;
613 8ccad811 bellard
        ide_set_sector(s, sector_num);
614 8ccad811 bellard
        s->nsector -= n;
615 8ccad811 bellard
    }
616 8ccad811 bellard
617 8ccad811 bellard
    /* end of transfer ? */
618 8ccad811 bellard
    if (s->nsector == 0) {
619 98087450 bellard
        s->status = READY_STAT | SEEK_STAT;
620 9cdd03a7 Gerd Hoffmann
        ide_set_irq(s->bus);
621 cd369c46 Christoph Hellwig
        goto eot;
622 98087450 bellard
    }
623 8ccad811 bellard
624 8ccad811 bellard
    /* launch next transfer */
625 8ccad811 bellard
    n = s->nsector;
626 596bb44d Christoph Hellwig
    s->io_buffer_index = 0;
627 8ccad811 bellard
    s->io_buffer_size = n * 512;
628 4e1e0051 Christoph Hellwig
    if (s->bus->dma->ops->prepare_buf(s->bus->dma, ide_cmd_is_read(s)) == 0) {
629 69c38b8f Kevin Wolf
        /* The PRDs were too short. Reset the Active bit, but don't raise an
630 69c38b8f Kevin Wolf
         * interrupt. */
631 7aea4412 aliguori
        goto eot;
632 69c38b8f Kevin Wolf
    }
633 cd369c46 Christoph Hellwig
634 8ccad811 bellard
#ifdef DEBUG_AIO
635 4e1e0051 Christoph Hellwig
    printf("ide_dma_cb: sector_num=%" PRId64 " n=%d, cmd_cmd=%d\n",
636 4e1e0051 Christoph Hellwig
           sector_num, n, s->dma_cmd);
637 8ccad811 bellard
#endif
638 cd369c46 Christoph Hellwig
639 4e1e0051 Christoph Hellwig
    switch (s->dma_cmd) {
640 4e1e0051 Christoph Hellwig
    case IDE_DMA_READ:
641 cd369c46 Christoph Hellwig
        s->bus->dma->aiocb = dma_bdrv_read(s->bs, &s->sg, sector_num,
642 cd369c46 Christoph Hellwig
                                           ide_dma_cb, s);
643 4e1e0051 Christoph Hellwig
        break;
644 4e1e0051 Christoph Hellwig
    case IDE_DMA_WRITE:
645 cd369c46 Christoph Hellwig
        s->bus->dma->aiocb = dma_bdrv_write(s->bs, &s->sg, sector_num,
646 cd369c46 Christoph Hellwig
                                            ide_dma_cb, s);
647 4e1e0051 Christoph Hellwig
        break;
648 d353fb72 Christoph Hellwig
    case IDE_DMA_TRIM:
649 d353fb72 Christoph Hellwig
        s->bus->dma->aiocb = dma_bdrv_io(s->bs, &s->sg, sector_num,
650 43cf8ae6 David Gibson
                                         ide_issue_trim, ide_dma_cb, s,
651 43cf8ae6 David Gibson
                                         DMA_DIRECTION_TO_DEVICE);
652 d353fb72 Christoph Hellwig
        break;
653 cd369c46 Christoph Hellwig
    }
654 cd369c46 Christoph Hellwig
    return;
655 cd369c46 Christoph Hellwig
656 cd369c46 Christoph Hellwig
eot:
657 a597e79c Christoph Hellwig
    if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) {
658 a597e79c Christoph Hellwig
        bdrv_acct_done(s->bs, &s->acct);
659 a597e79c Christoph Hellwig
    }
660 a597e79c Christoph Hellwig
    ide_set_inactive(s);
661 98087450 bellard
}
662 98087450 bellard
663 4e1e0051 Christoph Hellwig
static void ide_sector_start_dma(IDEState *s, enum ide_dma_cmd dma_cmd)
664 98087450 bellard
{
665 8ccad811 bellard
    s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
666 98087450 bellard
    s->io_buffer_index = 0;
667 98087450 bellard
    s->io_buffer_size = 0;
668 4e1e0051 Christoph Hellwig
    s->dma_cmd = dma_cmd;
669 a597e79c Christoph Hellwig
670 a597e79c Christoph Hellwig
    switch (dma_cmd) {
671 a597e79c Christoph Hellwig
    case IDE_DMA_READ:
672 a597e79c Christoph Hellwig
        bdrv_acct_start(s->bs, &s->acct, s->nsector * BDRV_SECTOR_SIZE,
673 a597e79c Christoph Hellwig
                        BDRV_ACCT_READ);
674 a597e79c Christoph Hellwig
        break;
675 a597e79c Christoph Hellwig
    case IDE_DMA_WRITE:
676 a597e79c Christoph Hellwig
        bdrv_acct_start(s->bs, &s->acct, s->nsector * BDRV_SECTOR_SIZE,
677 a597e79c Christoph Hellwig
                        BDRV_ACCT_WRITE);
678 a597e79c Christoph Hellwig
        break;
679 a597e79c Christoph Hellwig
    default:
680 a597e79c Christoph Hellwig
        break;
681 a597e79c Christoph Hellwig
    }
682 a597e79c Christoph Hellwig
683 cd369c46 Christoph Hellwig
    s->bus->dma->ops->start_dma(s->bus->dma, s, ide_dma_cb);
684 98087450 bellard
}
685 98087450 bellard
686 a09db21f bellard
static void ide_sector_write_timer_cb(void *opaque)
687 a09db21f bellard
{
688 a09db21f bellard
    IDEState *s = opaque;
689 9cdd03a7 Gerd Hoffmann
    ide_set_irq(s->bus);
690 a09db21f bellard
}
691 a09db21f bellard
692 e82dabd8 Stefan Hajnoczi
static void ide_sector_write_cb(void *opaque, int ret)
693 5391d806 bellard
{
694 e82dabd8 Stefan Hajnoczi
    IDEState *s = opaque;
695 e82dabd8 Stefan Hajnoczi
    int n;
696 a597e79c Christoph Hellwig
697 a597e79c Christoph Hellwig
    bdrv_acct_done(s->bs, &s->acct);
698 428c5705 aliguori
699 e82dabd8 Stefan Hajnoczi
    s->pio_aiocb = NULL;
700 e82dabd8 Stefan Hajnoczi
    s->status &= ~BUSY_STAT;
701 e82dabd8 Stefan Hajnoczi
702 e162cfb0 balrog
    if (ret != 0) {
703 e82dabd8 Stefan Hajnoczi
        if (ide_handle_rw_error(s, -ret, BM_STATUS_PIO_RETRY)) {
704 428c5705 aliguori
            return;
705 e82dabd8 Stefan Hajnoczi
        }
706 e162cfb0 balrog
    }
707 e162cfb0 balrog
708 e82dabd8 Stefan Hajnoczi
    n = s->nsector;
709 e82dabd8 Stefan Hajnoczi
    if (n > s->req_nb_sectors) {
710 e82dabd8 Stefan Hajnoczi
        n = s->req_nb_sectors;
711 e82dabd8 Stefan Hajnoczi
    }
712 5391d806 bellard
    s->nsector -= n;
713 5391d806 bellard
    if (s->nsector == 0) {
714 292eef5a ths
        /* no more sectors to write */
715 5391d806 bellard
        ide_transfer_stop(s);
716 5391d806 bellard
    } else {
717 e82dabd8 Stefan Hajnoczi
        int n1 = s->nsector;
718 e82dabd8 Stefan Hajnoczi
        if (n1 > s->req_nb_sectors) {
719 5391d806 bellard
            n1 = s->req_nb_sectors;
720 e82dabd8 Stefan Hajnoczi
        }
721 e82dabd8 Stefan Hajnoczi
        ide_transfer_start(s, s->io_buffer, n1 * BDRV_SECTOR_SIZE,
722 e82dabd8 Stefan Hajnoczi
                           ide_sector_write);
723 5391d806 bellard
    }
724 e82dabd8 Stefan Hajnoczi
    ide_set_sector(s, ide_get_sector(s) + n);
725 3b46e624 ths
726 31c2a146 ths
    if (win2k_install_hack && ((++s->irq_count % 16) == 0)) {
727 31c2a146 ths
        /* It seems there is a bug in the Windows 2000 installer HDD
728 31c2a146 ths
           IDE driver which fills the disk with empty logs when the
729 31c2a146 ths
           IDE write IRQ comes too early. This hack tries to correct
730 31c2a146 ths
           that at the expense of slower write performances. Use this
731 31c2a146 ths
           option _only_ to install Windows 2000. You must disable it
732 31c2a146 ths
           for normal use. */
733 f7736b91 Blue Swirl
        qemu_mod_timer(s->sector_write_timer,
734 74475455 Paolo Bonzini
                       qemu_get_clock_ns(vm_clock) + (get_ticks_per_sec() / 1000));
735 f7736b91 Blue Swirl
    } else {
736 9cdd03a7 Gerd Hoffmann
        ide_set_irq(s->bus);
737 31c2a146 ths
    }
738 5391d806 bellard
}
739 5391d806 bellard
740 e82dabd8 Stefan Hajnoczi
void ide_sector_write(IDEState *s)
741 e82dabd8 Stefan Hajnoczi
{
742 e82dabd8 Stefan Hajnoczi
    int64_t sector_num;
743 e82dabd8 Stefan Hajnoczi
    int n;
744 e82dabd8 Stefan Hajnoczi
745 e82dabd8 Stefan Hajnoczi
    s->status = READY_STAT | SEEK_STAT | BUSY_STAT;
746 e82dabd8 Stefan Hajnoczi
    sector_num = ide_get_sector(s);
747 e82dabd8 Stefan Hajnoczi
#if defined(DEBUG_IDE)
748 e82dabd8 Stefan Hajnoczi
    printf("sector=%" PRId64 "\n", sector_num);
749 e82dabd8 Stefan Hajnoczi
#endif
750 e82dabd8 Stefan Hajnoczi
    n = s->nsector;
751 e82dabd8 Stefan Hajnoczi
    if (n > s->req_nb_sectors) {
752 e82dabd8 Stefan Hajnoczi
        n = s->req_nb_sectors;
753 e82dabd8 Stefan Hajnoczi
    }
754 e82dabd8 Stefan Hajnoczi
755 e82dabd8 Stefan Hajnoczi
    s->iov.iov_base = s->io_buffer;
756 e82dabd8 Stefan Hajnoczi
    s->iov.iov_len  = n * BDRV_SECTOR_SIZE;
757 e82dabd8 Stefan Hajnoczi
    qemu_iovec_init_external(&s->qiov, &s->iov, 1);
758 e82dabd8 Stefan Hajnoczi
759 e82dabd8 Stefan Hajnoczi
    bdrv_acct_start(s->bs, &s->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
760 e82dabd8 Stefan Hajnoczi
    s->pio_aiocb = bdrv_aio_writev(s->bs, sector_num, &s->qiov, n,
761 e82dabd8 Stefan Hajnoczi
                                   ide_sector_write_cb, s);
762 e82dabd8 Stefan Hajnoczi
}
763 e82dabd8 Stefan Hajnoczi
764 b0484ae4 Christoph Hellwig
static void ide_flush_cb(void *opaque, int ret)
765 b0484ae4 Christoph Hellwig
{
766 b0484ae4 Christoph Hellwig
    IDEState *s = opaque;
767 b0484ae4 Christoph Hellwig
768 e2bcadad Kevin Wolf
    if (ret < 0) {
769 e2bcadad Kevin Wolf
        /* XXX: What sector number to set here? */
770 e2bcadad Kevin Wolf
        if (ide_handle_rw_error(s, -ret, BM_STATUS_RETRY_FLUSH)) {
771 e2bcadad Kevin Wolf
            return;
772 e2bcadad Kevin Wolf
        }
773 e2bcadad Kevin Wolf
    }
774 b0484ae4 Christoph Hellwig
775 a597e79c Christoph Hellwig
    bdrv_acct_done(s->bs, &s->acct);
776 b0484ae4 Christoph Hellwig
    s->status = READY_STAT | SEEK_STAT;
777 b0484ae4 Christoph Hellwig
    ide_set_irq(s->bus);
778 b0484ae4 Christoph Hellwig
}
779 b0484ae4 Christoph Hellwig
780 40a6238a Alexander Graf
void ide_flush_cache(IDEState *s)
781 6bcb1a79 Kevin Wolf
{
782 b2df7531 Kevin Wolf
    if (s->bs == NULL) {
783 6bcb1a79 Kevin Wolf
        ide_flush_cb(s, 0);
784 b2df7531 Kevin Wolf
        return;
785 b2df7531 Kevin Wolf
    }
786 b2df7531 Kevin Wolf
787 a597e79c Christoph Hellwig
    bdrv_acct_start(s->bs, &s->acct, 0, BDRV_ACCT_FLUSH);
788 ad54ae80 Paolo Bonzini
    bdrv_aio_flush(s->bs, ide_flush_cb, s);
789 6bcb1a79 Kevin Wolf
}
790 6bcb1a79 Kevin Wolf
791 201a51fc balrog
static void ide_cfata_metadata_inquiry(IDEState *s)
792 201a51fc balrog
{
793 201a51fc balrog
    uint16_t *p;
794 201a51fc balrog
    uint32_t spd;
795 201a51fc balrog
796 201a51fc balrog
    p = (uint16_t *) s->io_buffer;
797 201a51fc balrog
    memset(p, 0, 0x200);
798 201a51fc balrog
    spd = ((s->mdata_size - 1) >> 9) + 1;
799 201a51fc balrog
800 201a51fc balrog
    put_le16(p + 0, 0x0001);                        /* Data format revision */
801 201a51fc balrog
    put_le16(p + 1, 0x0000);                        /* Media property: silicon */
802 201a51fc balrog
    put_le16(p + 2, s->media_changed);                /* Media status */
803 201a51fc balrog
    put_le16(p + 3, s->mdata_size & 0xffff);        /* Capacity in bytes (low) */
804 201a51fc balrog
    put_le16(p + 4, s->mdata_size >> 16);        /* Capacity in bytes (high) */
805 201a51fc balrog
    put_le16(p + 5, spd & 0xffff);                /* Sectors per device (low) */
806 201a51fc balrog
    put_le16(p + 6, spd >> 16);                        /* Sectors per device (high) */
807 201a51fc balrog
}
808 201a51fc balrog
809 201a51fc balrog
static void ide_cfata_metadata_read(IDEState *s)
810 201a51fc balrog
{
811 201a51fc balrog
    uint16_t *p;
812 201a51fc balrog
813 201a51fc balrog
    if (((s->hcyl << 16) | s->lcyl) << 9 > s->mdata_size + 2) {
814 201a51fc balrog
        s->status = ERR_STAT;
815 201a51fc balrog
        s->error = ABRT_ERR;
816 201a51fc balrog
        return;
817 201a51fc balrog
    }
818 201a51fc balrog
819 201a51fc balrog
    p = (uint16_t *) s->io_buffer;
820 201a51fc balrog
    memset(p, 0, 0x200);
821 201a51fc balrog
822 201a51fc balrog
    put_le16(p + 0, s->media_changed);                /* Media status */
823 201a51fc balrog
    memcpy(p + 1, s->mdata_storage + (((s->hcyl << 16) | s->lcyl) << 9),
824 201a51fc balrog
                    MIN(MIN(s->mdata_size - (((s->hcyl << 16) | s->lcyl) << 9),
825 201a51fc balrog
                                    s->nsector << 9), 0x200 - 2));
826 201a51fc balrog
}
827 201a51fc balrog
828 201a51fc balrog
static void ide_cfata_metadata_write(IDEState *s)
829 201a51fc balrog
{
830 201a51fc balrog
    if (((s->hcyl << 16) | s->lcyl) << 9 > s->mdata_size + 2) {
831 201a51fc balrog
        s->status = ERR_STAT;
832 201a51fc balrog
        s->error = ABRT_ERR;
833 201a51fc balrog
        return;
834 201a51fc balrog
    }
835 201a51fc balrog
836 201a51fc balrog
    s->media_changed = 0;
837 201a51fc balrog
838 201a51fc balrog
    memcpy(s->mdata_storage + (((s->hcyl << 16) | s->lcyl) << 9),
839 201a51fc balrog
                    s->io_buffer + 2,
840 201a51fc balrog
                    MIN(MIN(s->mdata_size - (((s->hcyl << 16) | s->lcyl) << 9),
841 201a51fc balrog
                                    s->nsector << 9), 0x200 - 2));
842 201a51fc balrog
}
843 201a51fc balrog
844 bd491d6a ths
/* called when the inserted state of the media has changed */
845 7d4b4ba5 Markus Armbruster
static void ide_cd_change_cb(void *opaque, bool load)
846 bd491d6a ths
{
847 bd491d6a ths
    IDEState *s = opaque;
848 96b8f136 ths
    uint64_t nb_sectors;
849 bd491d6a ths
850 25ad22bc Markus Armbruster
    s->tray_open = !load;
851 bd491d6a ths
    bdrv_get_geometry(s->bs, &nb_sectors);
852 bd491d6a ths
    s->nb_sectors = nb_sectors;
853 9118e7f0 aliguori
854 4b9b7092 Amit Shah
    /*
855 4b9b7092 Amit Shah
     * First indicate to the guest that a CD has been removed.  That's
856 4b9b7092 Amit Shah
     * done on the next command the guest sends us.
857 4b9b7092 Amit Shah
     *
858 67cc61e4 Paolo Bonzini
     * Then we set UNIT_ATTENTION, by which the guest will
859 4b9b7092 Amit Shah
     * detect a new CD in the drive.  See ide_atapi_cmd() for details.
860 4b9b7092 Amit Shah
     */
861 93c8cfd9 Gleb Natapov
    s->cdrom_changed = 1;
862 996faf1a Amit Shah
    s->events.new_media = true;
863 2df0a3a3 Paolo Bonzini
    s->events.eject_request = false;
864 2df0a3a3 Paolo Bonzini
    ide_set_irq(s->bus);
865 2df0a3a3 Paolo Bonzini
}
866 2df0a3a3 Paolo Bonzini
867 2df0a3a3 Paolo Bonzini
static void ide_cd_eject_request_cb(void *opaque, bool force)
868 2df0a3a3 Paolo Bonzini
{
869 2df0a3a3 Paolo Bonzini
    IDEState *s = opaque;
870 2df0a3a3 Paolo Bonzini
871 2df0a3a3 Paolo Bonzini
    s->events.eject_request = true;
872 2df0a3a3 Paolo Bonzini
    if (force) {
873 2df0a3a3 Paolo Bonzini
        s->tray_locked = false;
874 2df0a3a3 Paolo Bonzini
    }
875 9cdd03a7 Gerd Hoffmann
    ide_set_irq(s->bus);
876 bd491d6a ths
}
877 bd491d6a ths
878 c2ff060f bellard
static void ide_cmd_lba48_transform(IDEState *s, int lba48)
879 c2ff060f bellard
{
880 c2ff060f bellard
    s->lba48 = lba48;
881 c2ff060f bellard
882 c2ff060f bellard
    /* handle the 'magic' 0 nsector count conversion here. to avoid
883 c2ff060f bellard
     * fiddling with the rest of the read logic, we just store the
884 c2ff060f bellard
     * full sector count in ->nsector and ignore ->hob_nsector from now
885 c2ff060f bellard
     */
886 c2ff060f bellard
    if (!s->lba48) {
887 c2ff060f bellard
        if (!s->nsector)
888 c2ff060f bellard
            s->nsector = 256;
889 c2ff060f bellard
    } else {
890 c2ff060f bellard
        if (!s->nsector && !s->hob_nsector)
891 c2ff060f bellard
            s->nsector = 65536;
892 c2ff060f bellard
        else {
893 c2ff060f bellard
            int lo = s->nsector;
894 c2ff060f bellard
            int hi = s->hob_nsector;
895 c2ff060f bellard
896 c2ff060f bellard
            s->nsector = (hi << 8) | lo;
897 c2ff060f bellard
        }
898 c2ff060f bellard
    }
899 c2ff060f bellard
}
900 c2ff060f bellard
901 bcbdc4d3 Gerd Hoffmann
static void ide_clear_hob(IDEBus *bus)
902 c2ff060f bellard
{
903 c2ff060f bellard
    /* any write clears HOB high bit of device control register */
904 bcbdc4d3 Gerd Hoffmann
    bus->ifs[0].select &= ~(1 << 7);
905 bcbdc4d3 Gerd Hoffmann
    bus->ifs[1].select &= ~(1 << 7);
906 c2ff060f bellard
}
907 c2ff060f bellard
908 356721ae Gerd Hoffmann
void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
909 caed8802 bellard
{
910 bcbdc4d3 Gerd Hoffmann
    IDEBus *bus = opaque;
911 5391d806 bellard
912 5391d806 bellard
#ifdef DEBUG_IDE
913 5391d806 bellard
    printf("IDE: write addr=0x%x val=0x%02x\n", addr, val);
914 5391d806 bellard
#endif
915 c2ff060f bellard
916 5391d806 bellard
    addr &= 7;
917 fcdd25ab aliguori
918 fcdd25ab aliguori
    /* ignore writes to command block while busy with previous command */
919 bcbdc4d3 Gerd Hoffmann
    if (addr != 7 && (idebus_active_if(bus)->status & (BUSY_STAT|DRQ_STAT)))
920 fcdd25ab aliguori
        return;
921 fcdd25ab aliguori
922 5391d806 bellard
    switch(addr) {
923 5391d806 bellard
    case 0:
924 5391d806 bellard
        break;
925 5391d806 bellard
    case 1:
926 bcbdc4d3 Gerd Hoffmann
        ide_clear_hob(bus);
927 c45c3d00 bellard
        /* NOTE: data is written to the two drives */
928 bcbdc4d3 Gerd Hoffmann
        bus->ifs[0].hob_feature = bus->ifs[0].feature;
929 bcbdc4d3 Gerd Hoffmann
        bus->ifs[1].hob_feature = bus->ifs[1].feature;
930 bcbdc4d3 Gerd Hoffmann
        bus->ifs[0].feature = val;
931 bcbdc4d3 Gerd Hoffmann
        bus->ifs[1].feature = val;
932 5391d806 bellard
        break;
933 5391d806 bellard
    case 2:
934 bcbdc4d3 Gerd Hoffmann
        ide_clear_hob(bus);
935 bcbdc4d3 Gerd Hoffmann
        bus->ifs[0].hob_nsector = bus->ifs[0].nsector;
936 bcbdc4d3 Gerd Hoffmann
        bus->ifs[1].hob_nsector = bus->ifs[1].nsector;
937 bcbdc4d3 Gerd Hoffmann
        bus->ifs[0].nsector = val;
938 bcbdc4d3 Gerd Hoffmann
        bus->ifs[1].nsector = val;
939 5391d806 bellard
        break;
940 5391d806 bellard
    case 3:
941 bcbdc4d3 Gerd Hoffmann
        ide_clear_hob(bus);
942 bcbdc4d3 Gerd Hoffmann
        bus->ifs[0].hob_sector = bus->ifs[0].sector;
943 bcbdc4d3 Gerd Hoffmann
        bus->ifs[1].hob_sector = bus->ifs[1].sector;
944 bcbdc4d3 Gerd Hoffmann
        bus->ifs[0].sector = val;
945 bcbdc4d3 Gerd Hoffmann
        bus->ifs[1].sector = val;
946 5391d806 bellard
        break;
947 5391d806 bellard
    case 4:
948 bcbdc4d3 Gerd Hoffmann
        ide_clear_hob(bus);
949 bcbdc4d3 Gerd Hoffmann
        bus->ifs[0].hob_lcyl = bus->ifs[0].lcyl;
950 bcbdc4d3 Gerd Hoffmann
        bus->ifs[1].hob_lcyl = bus->ifs[1].lcyl;
951 bcbdc4d3 Gerd Hoffmann
        bus->ifs[0].lcyl = val;
952 bcbdc4d3 Gerd Hoffmann
        bus->ifs[1].lcyl = val;
953 5391d806 bellard
        break;
954 5391d806 bellard
    case 5:
955 bcbdc4d3 Gerd Hoffmann
        ide_clear_hob(bus);
956 bcbdc4d3 Gerd Hoffmann
        bus->ifs[0].hob_hcyl = bus->ifs[0].hcyl;
957 bcbdc4d3 Gerd Hoffmann
        bus->ifs[1].hob_hcyl = bus->ifs[1].hcyl;
958 bcbdc4d3 Gerd Hoffmann
        bus->ifs[0].hcyl = val;
959 bcbdc4d3 Gerd Hoffmann
        bus->ifs[1].hcyl = val;
960 5391d806 bellard
        break;
961 5391d806 bellard
    case 6:
962 c2ff060f bellard
        /* FIXME: HOB readback uses bit 7 */
963 bcbdc4d3 Gerd Hoffmann
        bus->ifs[0].select = (val & ~0x10) | 0xa0;
964 bcbdc4d3 Gerd Hoffmann
        bus->ifs[1].select = (val | 0x10) | 0xa0;
965 5391d806 bellard
        /* select drive */
966 bcbdc4d3 Gerd Hoffmann
        bus->unit = (val >> 4) & 1;
967 5391d806 bellard
        break;
968 5391d806 bellard
    default:
969 5391d806 bellard
    case 7:
970 5391d806 bellard
        /* command */
971 7cff87ff Alexander Graf
        ide_exec_cmd(bus, val);
972 7cff87ff Alexander Graf
        break;
973 7cff87ff Alexander Graf
    }
974 7cff87ff Alexander Graf
}
975 7cff87ff Alexander Graf
976 844505b1 Markus Armbruster
#define HD_OK (1u << IDE_HD)
977 844505b1 Markus Armbruster
#define CD_OK (1u << IDE_CD)
978 844505b1 Markus Armbruster
#define CFA_OK (1u << IDE_CFATA)
979 844505b1 Markus Armbruster
#define HD_CFA_OK (HD_OK | CFA_OK)
980 844505b1 Markus Armbruster
#define ALL_OK (HD_OK | CD_OK | CFA_OK)
981 844505b1 Markus Armbruster
982 844505b1 Markus Armbruster
/* See ACS-2 T13/2015-D Table B.2 Command codes */
983 844505b1 Markus Armbruster
static const uint8_t ide_cmd_table[0x100] = {
984 844505b1 Markus Armbruster
    /* NOP not implemented, mandatory for CD */
985 844505b1 Markus Armbruster
    [CFA_REQ_EXT_ERROR_CODE]            = CFA_OK,
986 844505b1 Markus Armbruster
    [WIN_DSM]                           = ALL_OK,
987 844505b1 Markus Armbruster
    [WIN_DEVICE_RESET]                  = CD_OK,
988 3cfc2269 Markus Armbruster
    [WIN_RECAL]                         = HD_CFA_OK,
989 844505b1 Markus Armbruster
    [WIN_READ]                          = ALL_OK,
990 844505b1 Markus Armbruster
    [WIN_READ_ONCE]                     = ALL_OK,
991 3cfc2269 Markus Armbruster
    [WIN_READ_EXT]                      = HD_CFA_OK,
992 3cfc2269 Markus Armbruster
    [WIN_READDMA_EXT]                   = HD_CFA_OK,
993 3cfc2269 Markus Armbruster
    [WIN_READ_NATIVE_MAX_EXT]           = HD_CFA_OK,
994 3cfc2269 Markus Armbruster
    [WIN_MULTREAD_EXT]                  = HD_CFA_OK,
995 3cfc2269 Markus Armbruster
    [WIN_WRITE]                         = HD_CFA_OK,
996 3cfc2269 Markus Armbruster
    [WIN_WRITE_ONCE]                    = HD_CFA_OK,
997 3cfc2269 Markus Armbruster
    [WIN_WRITE_EXT]                     = HD_CFA_OK,
998 3cfc2269 Markus Armbruster
    [WIN_WRITEDMA_EXT]                  = HD_CFA_OK,
999 3cfc2269 Markus Armbruster
    [CFA_WRITE_SECT_WO_ERASE]           = CFA_OK,
1000 3cfc2269 Markus Armbruster
    [WIN_MULTWRITE_EXT]                 = HD_CFA_OK,
1001 3cfc2269 Markus Armbruster
    [WIN_WRITE_VERIFY]                  = HD_CFA_OK,
1002 3cfc2269 Markus Armbruster
    [WIN_VERIFY]                        = HD_CFA_OK,
1003 3cfc2269 Markus Armbruster
    [WIN_VERIFY_ONCE]                   = HD_CFA_OK,
1004 3cfc2269 Markus Armbruster
    [WIN_VERIFY_EXT]                    = HD_CFA_OK,
1005 844505b1 Markus Armbruster
    [WIN_SEEK]                          = HD_CFA_OK,
1006 844505b1 Markus Armbruster
    [CFA_TRANSLATE_SECTOR]              = CFA_OK,
1007 844505b1 Markus Armbruster
    [WIN_DIAGNOSE]                      = ALL_OK,
1008 3cfc2269 Markus Armbruster
    [WIN_SPECIFY]                       = HD_CFA_OK,
1009 844505b1 Markus Armbruster
    [WIN_STANDBYNOW2]                   = ALL_OK,
1010 844505b1 Markus Armbruster
    [WIN_IDLEIMMEDIATE2]                = ALL_OK,
1011 844505b1 Markus Armbruster
    [WIN_STANDBY2]                      = ALL_OK,
1012 844505b1 Markus Armbruster
    [WIN_SETIDLE2]                      = ALL_OK,
1013 844505b1 Markus Armbruster
    [WIN_CHECKPOWERMODE2]               = ALL_OK,
1014 844505b1 Markus Armbruster
    [WIN_SLEEPNOW2]                     = ALL_OK,
1015 844505b1 Markus Armbruster
    [WIN_PACKETCMD]                     = CD_OK,
1016 844505b1 Markus Armbruster
    [WIN_PIDENTIFY]                     = CD_OK,
1017 844505b1 Markus Armbruster
    [WIN_SMART]                         = HD_CFA_OK,
1018 844505b1 Markus Armbruster
    [CFA_ACCESS_METADATA_STORAGE]       = CFA_OK,
1019 844505b1 Markus Armbruster
    [CFA_ERASE_SECTORS]                 = CFA_OK,
1020 3cfc2269 Markus Armbruster
    [WIN_MULTREAD]                      = HD_CFA_OK,
1021 3cfc2269 Markus Armbruster
    [WIN_MULTWRITE]                     = HD_CFA_OK,
1022 3cfc2269 Markus Armbruster
    [WIN_SETMULT]                       = HD_CFA_OK,
1023 3cfc2269 Markus Armbruster
    [WIN_READDMA]                       = HD_CFA_OK,
1024 3cfc2269 Markus Armbruster
    [WIN_READDMA_ONCE]                  = HD_CFA_OK,
1025 3cfc2269 Markus Armbruster
    [WIN_WRITEDMA]                      = HD_CFA_OK,
1026 3cfc2269 Markus Armbruster
    [WIN_WRITEDMA_ONCE]                 = HD_CFA_OK,
1027 3cfc2269 Markus Armbruster
    [CFA_WRITE_MULTI_WO_ERASE]          = CFA_OK,
1028 844505b1 Markus Armbruster
    [WIN_STANDBYNOW1]                   = ALL_OK,
1029 844505b1 Markus Armbruster
    [WIN_IDLEIMMEDIATE]                 = ALL_OK,
1030 844505b1 Markus Armbruster
    [WIN_STANDBY]                       = ALL_OK,
1031 844505b1 Markus Armbruster
    [WIN_SETIDLE1]                      = ALL_OK,
1032 844505b1 Markus Armbruster
    [WIN_CHECKPOWERMODE1]               = ALL_OK,
1033 844505b1 Markus Armbruster
    [WIN_SLEEPNOW1]                     = ALL_OK,
1034 844505b1 Markus Armbruster
    [WIN_FLUSH_CACHE]                   = ALL_OK,
1035 3cfc2269 Markus Armbruster
    [WIN_FLUSH_CACHE_EXT]               = HD_CFA_OK,
1036 844505b1 Markus Armbruster
    [WIN_IDENTIFY]                      = ALL_OK,
1037 844505b1 Markus Armbruster
    [WIN_SETFEATURES]                   = ALL_OK,
1038 844505b1 Markus Armbruster
    [IBM_SENSE_CONDITION]               = CFA_OK,
1039 d5b406d9 Alexander Graf
    [CFA_WEAR_LEVEL]                    = HD_CFA_OK,
1040 844505b1 Markus Armbruster
    [WIN_READ_NATIVE_MAX]               = ALL_OK,
1041 844505b1 Markus Armbruster
};
1042 844505b1 Markus Armbruster
1043 844505b1 Markus Armbruster
static bool ide_cmd_permitted(IDEState *s, uint32_t cmd)
1044 844505b1 Markus Armbruster
{
1045 844505b1 Markus Armbruster
    return cmd < ARRAY_SIZE(ide_cmd_table)
1046 844505b1 Markus Armbruster
        && (ide_cmd_table[cmd] & (1u << s->drive_kind));
1047 844505b1 Markus Armbruster
}
1048 7cff87ff Alexander Graf
1049 7cff87ff Alexander Graf
void ide_exec_cmd(IDEBus *bus, uint32_t val)
1050 7cff87ff Alexander Graf
{
1051 7cdd481c Paolo Bonzini
    uint16_t *identify_data;
1052 7cff87ff Alexander Graf
    IDEState *s;
1053 7cff87ff Alexander Graf
    int n;
1054 7cff87ff Alexander Graf
    int lba48 = 0;
1055 7cff87ff Alexander Graf
1056 5391d806 bellard
#if defined(DEBUG_IDE)
1057 6ef2ba5e Alexander Graf
    printf("ide: CMD=%02x\n", val);
1058 5391d806 bellard
#endif
1059 6ef2ba5e Alexander Graf
    s = idebus_active_if(bus);
1060 66a0a2cb Dong Xu Wang
    /* ignore commands to non existent slave */
1061 6ef2ba5e Alexander Graf
    if (s != bus->ifs && !s->bs)
1062 6ef2ba5e Alexander Graf
        return;
1063 c2ff060f bellard
1064 6ef2ba5e Alexander Graf
    /* Only DEVICE RESET is allowed while BSY or/and DRQ are set */
1065 6ef2ba5e Alexander Graf
    if ((s->status & (BUSY_STAT|DRQ_STAT)) && val != WIN_DEVICE_RESET)
1066 6ef2ba5e Alexander Graf
        return;
1067 fcdd25ab aliguori
1068 844505b1 Markus Armbruster
    if (!ide_cmd_permitted(s, val)) {
1069 844505b1 Markus Armbruster
        goto abort_cmd;
1070 844505b1 Markus Armbruster
    }
1071 844505b1 Markus Armbruster
1072 6ef2ba5e Alexander Graf
    switch(val) {
1073 d353fb72 Christoph Hellwig
    case WIN_DSM:
1074 d353fb72 Christoph Hellwig
        switch (s->feature) {
1075 d353fb72 Christoph Hellwig
        case DSM_TRIM:
1076 d353fb72 Christoph Hellwig
            if (!s->bs) {
1077 d353fb72 Christoph Hellwig
                goto abort_cmd;
1078 d353fb72 Christoph Hellwig
            }
1079 d353fb72 Christoph Hellwig
            ide_sector_start_dma(s, IDE_DMA_TRIM);
1080 d353fb72 Christoph Hellwig
            break;
1081 d353fb72 Christoph Hellwig
        default:
1082 d353fb72 Christoph Hellwig
            goto abort_cmd;
1083 d353fb72 Christoph Hellwig
        }
1084 d353fb72 Christoph Hellwig
        break;
1085 6ef2ba5e Alexander Graf
    case WIN_IDENTIFY:
1086 6ef2ba5e Alexander Graf
        if (s->bs && s->drive_kind != IDE_CD) {
1087 6ef2ba5e Alexander Graf
            if (s->drive_kind != IDE_CFATA)
1088 6ef2ba5e Alexander Graf
                ide_identify(s);
1089 6ef2ba5e Alexander Graf
            else
1090 6ef2ba5e Alexander Graf
                ide_cfata_identify(s);
1091 769bec72 bellard
            s->status = READY_STAT | SEEK_STAT;
1092 6ef2ba5e Alexander Graf
            ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
1093 6ef2ba5e Alexander Graf
        } else {
1094 6ef2ba5e Alexander Graf
            if (s->drive_kind == IDE_CD) {
1095 6ef2ba5e Alexander Graf
                ide_set_signature(s);
1096 5391d806 bellard
            }
1097 6ef2ba5e Alexander Graf
            ide_abort_command(s);
1098 6ef2ba5e Alexander Graf
        }
1099 6ef2ba5e Alexander Graf
        ide_set_irq(s->bus);
1100 6ef2ba5e Alexander Graf
        break;
1101 6ef2ba5e Alexander Graf
    case WIN_SPECIFY:
1102 6ef2ba5e Alexander Graf
    case WIN_RECAL:
1103 6ef2ba5e Alexander Graf
        s->error = 0;
1104 6ef2ba5e Alexander Graf
        s->status = READY_STAT | SEEK_STAT;
1105 6ef2ba5e Alexander Graf
        ide_set_irq(s->bus);
1106 6ef2ba5e Alexander Graf
        break;
1107 6ef2ba5e Alexander Graf
    case WIN_SETMULT:
1108 6ef2ba5e Alexander Graf
        if (s->drive_kind == IDE_CFATA && s->nsector == 0) {
1109 6ef2ba5e Alexander Graf
            /* Disable Read and Write Multiple */
1110 6ef2ba5e Alexander Graf
            s->mult_sectors = 0;
1111 41a2b959 aliguori
            s->status = READY_STAT | SEEK_STAT;
1112 6ef2ba5e Alexander Graf
        } else if ((s->nsector & 0xff) != 0 &&
1113 6ef2ba5e Alexander Graf
            ((s->nsector & 0xff) > MAX_MULT_SECTORS ||
1114 6ef2ba5e Alexander Graf
             (s->nsector & (s->nsector - 1)) != 0)) {
1115 6ef2ba5e Alexander Graf
            ide_abort_command(s);
1116 6ef2ba5e Alexander Graf
        } else {
1117 6ef2ba5e Alexander Graf
            s->mult_sectors = s->nsector & 0xff;
1118 6ef2ba5e Alexander Graf
            s->status = READY_STAT | SEEK_STAT;
1119 6ef2ba5e Alexander Graf
        }
1120 6ef2ba5e Alexander Graf
        ide_set_irq(s->bus);
1121 6ef2ba5e Alexander Graf
        break;
1122 6ef2ba5e Alexander Graf
    case WIN_VERIFY_EXT:
1123 6ef2ba5e Alexander Graf
        lba48 = 1;
1124 6ef2ba5e Alexander Graf
    case WIN_VERIFY:
1125 6ef2ba5e Alexander Graf
    case WIN_VERIFY_ONCE:
1126 6ef2ba5e Alexander Graf
        /* do sector number check ? */
1127 6ef2ba5e Alexander Graf
        ide_cmd_lba48_transform(s, lba48);
1128 6ef2ba5e Alexander Graf
        s->status = READY_STAT | SEEK_STAT;
1129 6ef2ba5e Alexander Graf
        ide_set_irq(s->bus);
1130 6ef2ba5e Alexander Graf
        break;
1131 814839c0 Markus Armbruster
    case WIN_READ_EXT:
1132 6ef2ba5e Alexander Graf
        lba48 = 1;
1133 6ef2ba5e Alexander Graf
    case WIN_READ:
1134 6ef2ba5e Alexander Graf
    case WIN_READ_ONCE:
1135 3f76a7c3 Markus Armbruster
        if (s->drive_kind == IDE_CD) {
1136 3f76a7c3 Markus Armbruster
            ide_set_signature(s); /* odd, but ATA4 8.27.5.2 requires it */
1137 6ef2ba5e Alexander Graf
            goto abort_cmd;
1138 3f76a7c3 Markus Armbruster
        }
1139 d53cdb30 Paolo Bonzini
        if (!s->bs) {
1140 d53cdb30 Paolo Bonzini
            goto abort_cmd;
1141 d53cdb30 Paolo Bonzini
        }
1142 6ef2ba5e Alexander Graf
        ide_cmd_lba48_transform(s, lba48);
1143 6ef2ba5e Alexander Graf
        s->req_nb_sectors = 1;
1144 6ef2ba5e Alexander Graf
        ide_sector_read(s);
1145 6ef2ba5e Alexander Graf
        break;
1146 814839c0 Markus Armbruster
    case WIN_WRITE_EXT:
1147 6ef2ba5e Alexander Graf
        lba48 = 1;
1148 6ef2ba5e Alexander Graf
    case WIN_WRITE:
1149 6ef2ba5e Alexander Graf
    case WIN_WRITE_ONCE:
1150 6ef2ba5e Alexander Graf
    case CFA_WRITE_SECT_WO_ERASE:
1151 6ef2ba5e Alexander Graf
    case WIN_WRITE_VERIFY:
1152 d53cdb30 Paolo Bonzini
        if (!s->bs) {
1153 d53cdb30 Paolo Bonzini
            goto abort_cmd;
1154 d53cdb30 Paolo Bonzini
        }
1155 6ef2ba5e Alexander Graf
        ide_cmd_lba48_transform(s, lba48);
1156 6ef2ba5e Alexander Graf
        s->error = 0;
1157 6ef2ba5e Alexander Graf
        s->status = SEEK_STAT | READY_STAT;
1158 6ef2ba5e Alexander Graf
        s->req_nb_sectors = 1;
1159 6ef2ba5e Alexander Graf
        ide_transfer_start(s, s->io_buffer, 512, ide_sector_write);
1160 6ef2ba5e Alexander Graf
        s->media_changed = 1;
1161 6ef2ba5e Alexander Graf
        break;
1162 814839c0 Markus Armbruster
    case WIN_MULTREAD_EXT:
1163 6ef2ba5e Alexander Graf
        lba48 = 1;
1164 6ef2ba5e Alexander Graf
    case WIN_MULTREAD:
1165 d53cdb30 Paolo Bonzini
        if (!s->bs) {
1166 d53cdb30 Paolo Bonzini
            goto abort_cmd;
1167 d53cdb30 Paolo Bonzini
        }
1168 d53cdb30 Paolo Bonzini
        if (!s->mult_sectors) {
1169 6ef2ba5e Alexander Graf
            goto abort_cmd;
1170 d53cdb30 Paolo Bonzini
        }
1171 6ef2ba5e Alexander Graf
        ide_cmd_lba48_transform(s, lba48);
1172 6ef2ba5e Alexander Graf
        s->req_nb_sectors = s->mult_sectors;
1173 6ef2ba5e Alexander Graf
        ide_sector_read(s);
1174 6ef2ba5e Alexander Graf
        break;
1175 6ef2ba5e Alexander Graf
    case WIN_MULTWRITE_EXT:
1176 6ef2ba5e Alexander Graf
        lba48 = 1;
1177 6ef2ba5e Alexander Graf
    case WIN_MULTWRITE:
1178 6ef2ba5e Alexander Graf
    case CFA_WRITE_MULTI_WO_ERASE:
1179 d53cdb30 Paolo Bonzini
        if (!s->bs) {
1180 d53cdb30 Paolo Bonzini
            goto abort_cmd;
1181 d53cdb30 Paolo Bonzini
        }
1182 d53cdb30 Paolo Bonzini
        if (!s->mult_sectors) {
1183 6ef2ba5e Alexander Graf
            goto abort_cmd;
1184 d53cdb30 Paolo Bonzini
        }
1185 6ef2ba5e Alexander Graf
        ide_cmd_lba48_transform(s, lba48);
1186 6ef2ba5e Alexander Graf
        s->error = 0;
1187 6ef2ba5e Alexander Graf
        s->status = SEEK_STAT | READY_STAT;
1188 6ef2ba5e Alexander Graf
        s->req_nb_sectors = s->mult_sectors;
1189 6ef2ba5e Alexander Graf
        n = s->nsector;
1190 6ef2ba5e Alexander Graf
        if (n > s->req_nb_sectors)
1191 6ef2ba5e Alexander Graf
            n = s->req_nb_sectors;
1192 6ef2ba5e Alexander Graf
        ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
1193 6ef2ba5e Alexander Graf
        s->media_changed = 1;
1194 6ef2ba5e Alexander Graf
        break;
1195 814839c0 Markus Armbruster
    case WIN_READDMA_EXT:
1196 6ef2ba5e Alexander Graf
        lba48 = 1;
1197 6ef2ba5e Alexander Graf
    case WIN_READDMA:
1198 6ef2ba5e Alexander Graf
    case WIN_READDMA_ONCE:
1199 d53cdb30 Paolo Bonzini
        if (!s->bs) {
1200 6ef2ba5e Alexander Graf
            goto abort_cmd;
1201 d53cdb30 Paolo Bonzini
        }
1202 6ef2ba5e Alexander Graf
        ide_cmd_lba48_transform(s, lba48);
1203 4e1e0051 Christoph Hellwig
        ide_sector_start_dma(s, IDE_DMA_READ);
1204 6ef2ba5e Alexander Graf
        break;
1205 814839c0 Markus Armbruster
    case WIN_WRITEDMA_EXT:
1206 6ef2ba5e Alexander Graf
        lba48 = 1;
1207 6ef2ba5e Alexander Graf
    case WIN_WRITEDMA:
1208 6ef2ba5e Alexander Graf
    case WIN_WRITEDMA_ONCE:
1209 d53cdb30 Paolo Bonzini
        if (!s->bs) {
1210 6ef2ba5e Alexander Graf
            goto abort_cmd;
1211 d53cdb30 Paolo Bonzini
        }
1212 6ef2ba5e Alexander Graf
        ide_cmd_lba48_transform(s, lba48);
1213 4e1e0051 Christoph Hellwig
        ide_sector_start_dma(s, IDE_DMA_WRITE);
1214 6ef2ba5e Alexander Graf
        s->media_changed = 1;
1215 6ef2ba5e Alexander Graf
        break;
1216 6ef2ba5e Alexander Graf
    case WIN_READ_NATIVE_MAX_EXT:
1217 6ef2ba5e Alexander Graf
        lba48 = 1;
1218 6ef2ba5e Alexander Graf
    case WIN_READ_NATIVE_MAX:
1219 6ef2ba5e Alexander Graf
        ide_cmd_lba48_transform(s, lba48);
1220 6ef2ba5e Alexander Graf
        ide_set_sector(s, s->nb_sectors - 1);
1221 6ef2ba5e Alexander Graf
        s->status = READY_STAT | SEEK_STAT;
1222 6ef2ba5e Alexander Graf
        ide_set_irq(s->bus);
1223 6ef2ba5e Alexander Graf
        break;
1224 6ef2ba5e Alexander Graf
    case WIN_CHECKPOWERMODE1:
1225 6ef2ba5e Alexander Graf
    case WIN_CHECKPOWERMODE2:
1226 b93af93d Brian Wheeler
        s->error = 0;
1227 6ef2ba5e Alexander Graf
        s->nsector = 0xff; /* device active or idle */
1228 6ef2ba5e Alexander Graf
        s->status = READY_STAT | SEEK_STAT;
1229 6ef2ba5e Alexander Graf
        ide_set_irq(s->bus);
1230 6ef2ba5e Alexander Graf
        break;
1231 6ef2ba5e Alexander Graf
    case WIN_SETFEATURES:
1232 6ef2ba5e Alexander Graf
        if (!s->bs)
1233 6ef2ba5e Alexander Graf
            goto abort_cmd;
1234 6ef2ba5e Alexander Graf
        /* XXX: valid for CDROM ? */
1235 6ef2ba5e Alexander Graf
        switch(s->feature) {
1236 6ef2ba5e Alexander Graf
        case 0x02: /* write cache enable */
1237 7cdd481c Paolo Bonzini
            bdrv_set_enable_write_cache(s->bs, true);
1238 7cdd481c Paolo Bonzini
            identify_data = (uint16_t *)s->identify_data;
1239 7cdd481c Paolo Bonzini
            put_le16(identify_data + 85, (1 << 14) | (1 << 5) | 1);
1240 7cdd481c Paolo Bonzini
            s->status = READY_STAT | SEEK_STAT;
1241 7cdd481c Paolo Bonzini
            ide_set_irq(s->bus);
1242 7cdd481c Paolo Bonzini
            break;
1243 6ef2ba5e Alexander Graf
        case 0x82: /* write cache disable */
1244 7cdd481c Paolo Bonzini
            bdrv_set_enable_write_cache(s->bs, false);
1245 7cdd481c Paolo Bonzini
            identify_data = (uint16_t *)s->identify_data;
1246 7cdd481c Paolo Bonzini
            put_le16(identify_data + 85, (1 << 14) | 1);
1247 7cdd481c Paolo Bonzini
            ide_flush_cache(s);
1248 7cdd481c Paolo Bonzini
            break;
1249 7cdd481c Paolo Bonzini
        case 0xcc: /* reverting to power-on defaults enable */
1250 7cdd481c Paolo Bonzini
        case 0x66: /* reverting to power-on defaults disable */
1251 6ef2ba5e Alexander Graf
        case 0xaa: /* read look-ahead enable */
1252 6ef2ba5e Alexander Graf
        case 0x55: /* read look-ahead disable */
1253 6ef2ba5e Alexander Graf
        case 0x05: /* set advanced power management mode */
1254 6ef2ba5e Alexander Graf
        case 0x85: /* disable advanced power management mode */
1255 6ef2ba5e Alexander Graf
        case 0x69: /* NOP */
1256 6ef2ba5e Alexander Graf
        case 0x67: /* NOP */
1257 6ef2ba5e Alexander Graf
        case 0x96: /* NOP */
1258 6ef2ba5e Alexander Graf
        case 0x9a: /* NOP */
1259 6ef2ba5e Alexander Graf
        case 0x42: /* enable Automatic Acoustic Mode */
1260 6ef2ba5e Alexander Graf
        case 0xc2: /* disable Automatic Acoustic Mode */
1261 41a2b959 aliguori
            s->status = READY_STAT | SEEK_STAT;
1262 9cdd03a7 Gerd Hoffmann
            ide_set_irq(s->bus);
1263 a136e5a8 bellard
            break;
1264 6ef2ba5e Alexander Graf
        case 0x03: { /* set transfer mode */
1265 94458802 bellard
                uint8_t val = s->nsector & 0x07;
1266 7cdd481c Paolo Bonzini
                identify_data = (uint16_t *)s->identify_data;
1267 94458802 bellard
1268 94458802 bellard
                switch (s->nsector >> 3) {
1269 6ef2ba5e Alexander Graf
                case 0x00: /* pio default */
1270 6ef2ba5e Alexander Graf
                case 0x01: /* pio mode */
1271 96c35ceb Juan Quintela
                        put_le16(identify_data + 62,0x07);
1272 96c35ceb Juan Quintela
                        put_le16(identify_data + 63,0x07);
1273 96c35ceb Juan Quintela
                        put_le16(identify_data + 88,0x3f);
1274 d1b5c20d ths
                        break;
1275 6ef2ba5e Alexander Graf
                case 0x02: /* sigle word dma mode*/
1276 96c35ceb Juan Quintela
                        put_le16(identify_data + 62,0x07 | (1 << (val + 8)));
1277 96c35ceb Juan Quintela
                        put_le16(identify_data + 63,0x07);
1278 96c35ceb Juan Quintela
                        put_le16(identify_data + 88,0x3f);
1279 94458802 bellard
                        break;
1280 6ef2ba5e Alexander Graf
                case 0x04: /* mdma mode */
1281 96c35ceb Juan Quintela
                        put_le16(identify_data + 62,0x07);
1282 96c35ceb Juan Quintela
                        put_le16(identify_data + 63,0x07 | (1 << (val + 8)));
1283 96c35ceb Juan Quintela
                        put_le16(identify_data + 88,0x3f);
1284 94458802 bellard
                        break;
1285 6ef2ba5e Alexander Graf
                case 0x08: /* udma mode */
1286 96c35ceb Juan Quintela
                        put_le16(identify_data + 62,0x07);
1287 96c35ceb Juan Quintela
                        put_le16(identify_data + 63,0x07);
1288 96c35ceb Juan Quintela
                        put_le16(identify_data + 88,0x3f | (1 << (val + 8)));
1289 94458802 bellard
                        break;
1290 6ef2ba5e Alexander Graf
                default:
1291 94458802 bellard
                        goto abort_cmd;
1292 94458802 bellard
                }
1293 4fbfcd6d aurel32
            s->status = READY_STAT | SEEK_STAT;
1294 9cdd03a7 Gerd Hoffmann
            ide_set_irq(s->bus);
1295 4fbfcd6d aurel32
            break;
1296 6ef2ba5e Alexander Graf
        }
1297 6ef2ba5e Alexander Graf
        default:
1298 6ef2ba5e Alexander Graf
            goto abort_cmd;
1299 6ef2ba5e Alexander Graf
        }
1300 6ef2ba5e Alexander Graf
        break;
1301 6ef2ba5e Alexander Graf
    case WIN_FLUSH_CACHE:
1302 6ef2ba5e Alexander Graf
    case WIN_FLUSH_CACHE_EXT:
1303 6ef2ba5e Alexander Graf
        ide_flush_cache(s);
1304 6ef2ba5e Alexander Graf
        break;
1305 6ef2ba5e Alexander Graf
    case WIN_STANDBY:
1306 6ef2ba5e Alexander Graf
    case WIN_STANDBY2:
1307 6ef2ba5e Alexander Graf
    case WIN_STANDBYNOW1:
1308 6ef2ba5e Alexander Graf
    case WIN_STANDBYNOW2:
1309 6ef2ba5e Alexander Graf
    case WIN_IDLEIMMEDIATE:
1310 1d4316d3 Markus Armbruster
    case WIN_IDLEIMMEDIATE2:
1311 6ef2ba5e Alexander Graf
    case WIN_SETIDLE1:
1312 6ef2ba5e Alexander Graf
    case WIN_SETIDLE2:
1313 6ef2ba5e Alexander Graf
    case WIN_SLEEPNOW1:
1314 6ef2ba5e Alexander Graf
    case WIN_SLEEPNOW2:
1315 6ef2ba5e Alexander Graf
        s->status = READY_STAT;
1316 6ef2ba5e Alexander Graf
        ide_set_irq(s->bus);
1317 6ef2ba5e Alexander Graf
        break;
1318 6ef2ba5e Alexander Graf
    case WIN_SEEK:
1319 6ef2ba5e Alexander Graf
        /* XXX: Check that seek is within bounds */
1320 6ef2ba5e Alexander Graf
        s->status = READY_STAT | SEEK_STAT;
1321 6ef2ba5e Alexander Graf
        ide_set_irq(s->bus);
1322 6ef2ba5e Alexander Graf
        break;
1323 6ef2ba5e Alexander Graf
        /* ATAPI commands */
1324 6ef2ba5e Alexander Graf
    case WIN_PIDENTIFY:
1325 844505b1 Markus Armbruster
        ide_atapi_identify(s);
1326 844505b1 Markus Armbruster
        s->status = READY_STAT | SEEK_STAT;
1327 844505b1 Markus Armbruster
        ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
1328 6ef2ba5e Alexander Graf
        ide_set_irq(s->bus);
1329 6ef2ba5e Alexander Graf
        break;
1330 6ef2ba5e Alexander Graf
    case WIN_DIAGNOSE:
1331 6ef2ba5e Alexander Graf
        ide_set_signature(s);
1332 6ef2ba5e Alexander Graf
        if (s->drive_kind == IDE_CD)
1333 6ef2ba5e Alexander Graf
            s->status = 0; /* ATAPI spec (v6) section 9.10 defines packet
1334 6ef2ba5e Alexander Graf
                            * devices to return a clear status register
1335 6ef2ba5e Alexander Graf
                            * with READY_STAT *not* set. */
1336 6ef2ba5e Alexander Graf
        else
1337 41a2b959 aliguori
            s->status = READY_STAT | SEEK_STAT;
1338 6ef2ba5e Alexander Graf
        s->error = 0x01; /* Device 0 passed, Device 1 passed or not
1339 6ef2ba5e Alexander Graf
                          * present.
1340 6ef2ba5e Alexander Graf
                          */
1341 6ef2ba5e Alexander Graf
        ide_set_irq(s->bus);
1342 6ef2ba5e Alexander Graf
        break;
1343 1d4316d3 Markus Armbruster
    case WIN_DEVICE_RESET:
1344 6ef2ba5e Alexander Graf
        ide_set_signature(s);
1345 6ef2ba5e Alexander Graf
        s->status = 0x00; /* NOTE: READY is _not_ set */
1346 6ef2ba5e Alexander Graf
        s->error = 0x01;
1347 6ef2ba5e Alexander Graf
        break;
1348 6ef2ba5e Alexander Graf
    case WIN_PACKETCMD:
1349 6ef2ba5e Alexander Graf
        /* overlapping commands not supported */
1350 6ef2ba5e Alexander Graf
        if (s->feature & 0x02)
1351 6ef2ba5e Alexander Graf
            goto abort_cmd;
1352 6ef2ba5e Alexander Graf
        s->status = READY_STAT | SEEK_STAT;
1353 6ef2ba5e Alexander Graf
        s->atapi_dma = s->feature & 1;
1354 6ef2ba5e Alexander Graf
        s->nsector = 1;
1355 6ef2ba5e Alexander Graf
        ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE,
1356 6ef2ba5e Alexander Graf
                           ide_atapi_cmd);
1357 6ef2ba5e Alexander Graf
        break;
1358 6ef2ba5e Alexander Graf
    /* CF-ATA commands */
1359 6ef2ba5e Alexander Graf
    case CFA_REQ_EXT_ERROR_CODE:
1360 6ef2ba5e Alexander Graf
        s->error = 0x09;    /* miscellaneous error */
1361 6ef2ba5e Alexander Graf
        s->status = READY_STAT | SEEK_STAT;
1362 6ef2ba5e Alexander Graf
        ide_set_irq(s->bus);
1363 6ef2ba5e Alexander Graf
        break;
1364 6ef2ba5e Alexander Graf
    case CFA_ERASE_SECTORS:
1365 6ef2ba5e Alexander Graf
    case CFA_WEAR_LEVEL:
1366 d5b406d9 Alexander Graf
#if 0
1367 d5b406d9 Alexander Graf
    /* This one has the same ID as CFA_WEAR_LEVEL and is required for
1368 d5b406d9 Alexander Graf
       Windows 8 to work with AHCI */
1369 d5b406d9 Alexander Graf
    case WIN_SECURITY_FREEZE_LOCK:
1370 d5b406d9 Alexander Graf
#endif
1371 6ef2ba5e Alexander Graf
        if (val == CFA_WEAR_LEVEL)
1372 6ef2ba5e Alexander Graf
            s->nsector = 0;
1373 6ef2ba5e Alexander Graf
        if (val == CFA_ERASE_SECTORS)
1374 6ef2ba5e Alexander Graf
            s->media_changed = 1;
1375 6ef2ba5e Alexander Graf
        s->error = 0x00;
1376 6ef2ba5e Alexander Graf
        s->status = READY_STAT | SEEK_STAT;
1377 6ef2ba5e Alexander Graf
        ide_set_irq(s->bus);
1378 6ef2ba5e Alexander Graf
        break;
1379 6ef2ba5e Alexander Graf
    case CFA_TRANSLATE_SECTOR:
1380 6ef2ba5e Alexander Graf
        s->error = 0x00;
1381 6ef2ba5e Alexander Graf
        s->status = READY_STAT | SEEK_STAT;
1382 6ef2ba5e Alexander Graf
        memset(s->io_buffer, 0, 0x200);
1383 6ef2ba5e Alexander Graf
        s->io_buffer[0x00] = s->hcyl;                        /* Cyl MSB */
1384 6ef2ba5e Alexander Graf
        s->io_buffer[0x01] = s->lcyl;                        /* Cyl LSB */
1385 6ef2ba5e Alexander Graf
        s->io_buffer[0x02] = s->select;                        /* Head */
1386 6ef2ba5e Alexander Graf
        s->io_buffer[0x03] = s->sector;                        /* Sector */
1387 6ef2ba5e Alexander Graf
        s->io_buffer[0x04] = ide_get_sector(s) >> 16;        /* LBA MSB */
1388 6ef2ba5e Alexander Graf
        s->io_buffer[0x05] = ide_get_sector(s) >> 8;        /* LBA */
1389 6ef2ba5e Alexander Graf
        s->io_buffer[0x06] = ide_get_sector(s) >> 0;        /* LBA LSB */
1390 6ef2ba5e Alexander Graf
        s->io_buffer[0x13] = 0x00;                                /* Erase flag */
1391 6ef2ba5e Alexander Graf
        s->io_buffer[0x18] = 0x00;                                /* Hot count */
1392 6ef2ba5e Alexander Graf
        s->io_buffer[0x19] = 0x00;                                /* Hot count */
1393 6ef2ba5e Alexander Graf
        s->io_buffer[0x1a] = 0x01;                                /* Hot count */
1394 6ef2ba5e Alexander Graf
        ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
1395 6ef2ba5e Alexander Graf
        ide_set_irq(s->bus);
1396 6ef2ba5e Alexander Graf
        break;
1397 6ef2ba5e Alexander Graf
    case CFA_ACCESS_METADATA_STORAGE:
1398 6ef2ba5e Alexander Graf
        switch (s->feature) {
1399 6ef2ba5e Alexander Graf
        case 0x02:        /* Inquiry Metadata Storage */
1400 6ef2ba5e Alexander Graf
            ide_cfata_metadata_inquiry(s);
1401 201a51fc balrog
            break;
1402 6ef2ba5e Alexander Graf
        case 0x03:        /* Read Metadata Storage */
1403 6ef2ba5e Alexander Graf
            ide_cfata_metadata_read(s);
1404 201a51fc balrog
            break;
1405 6ef2ba5e Alexander Graf
        case 0x04:        /* Write Metadata Storage */
1406 6ef2ba5e Alexander Graf
            ide_cfata_metadata_write(s);
1407 201a51fc balrog
            break;
1408 6ef2ba5e Alexander Graf
        default:
1409 6ef2ba5e Alexander Graf
            goto abort_cmd;
1410 6ef2ba5e Alexander Graf
        }
1411 6ef2ba5e Alexander Graf
        ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
1412 6ef2ba5e Alexander Graf
        s->status = 0x00; /* NOTE: READY is _not_ set */
1413 6ef2ba5e Alexander Graf
        ide_set_irq(s->bus);
1414 6ef2ba5e Alexander Graf
        break;
1415 6ef2ba5e Alexander Graf
    case IBM_SENSE_CONDITION:
1416 6ef2ba5e Alexander Graf
        switch (s->feature) {
1417 6ef2ba5e Alexander Graf
        case 0x01:  /* sense temperature in device */
1418 6ef2ba5e Alexander Graf
            s->nsector = 0x50;      /* +20 C */
1419 201a51fc balrog
            break;
1420 6ef2ba5e Alexander Graf
        default:
1421 6ef2ba5e Alexander Graf
            goto abort_cmd;
1422 6ef2ba5e Alexander Graf
        }
1423 6ef2ba5e Alexander Graf
        s->status = READY_STAT | SEEK_STAT;
1424 6ef2ba5e Alexander Graf
        ide_set_irq(s->bus);
1425 6ef2ba5e Alexander Graf
        break;
1426 e8b54394 Brian Wheeler
1427 814839c0 Markus Armbruster
    case WIN_SMART:
1428 6ef2ba5e Alexander Graf
        if (s->hcyl != 0xc2 || s->lcyl != 0x4f)
1429 e8b54394 Brian Wheeler
                goto abort_cmd;
1430 6ef2ba5e Alexander Graf
        if (!s->smart_enabled && s->feature != SMART_ENABLE)
1431 e8b54394 Brian Wheeler
                goto abort_cmd;
1432 6ef2ba5e Alexander Graf
        switch (s->feature) {
1433 6ef2ba5e Alexander Graf
        case SMART_DISABLE:
1434 e8b54394 Brian Wheeler
                s->smart_enabled = 0;
1435 e8b54394 Brian Wheeler
                s->status = READY_STAT | SEEK_STAT;
1436 9cdd03a7 Gerd Hoffmann
                ide_set_irq(s->bus);
1437 e8b54394 Brian Wheeler
                break;
1438 6ef2ba5e Alexander Graf
        case SMART_ENABLE:
1439 e8b54394 Brian Wheeler
                s->smart_enabled = 1;
1440 e8b54394 Brian Wheeler
                s->status = READY_STAT | SEEK_STAT;
1441 9cdd03a7 Gerd Hoffmann
                ide_set_irq(s->bus);
1442 e8b54394 Brian Wheeler
                break;
1443 6ef2ba5e Alexander Graf
        case SMART_ATTR_AUTOSAVE:
1444 e8b54394 Brian Wheeler
                switch (s->sector) {
1445 e8b54394 Brian Wheeler
                case 0x00:
1446 6ef2ba5e Alexander Graf
                s->smart_autosave = 0;
1447 6ef2ba5e Alexander Graf
                break;
1448 e8b54394 Brian Wheeler
                case 0xf1:
1449 6ef2ba5e Alexander Graf
                s->smart_autosave = 1;
1450 6ef2ba5e Alexander Graf
                break;
1451 e8b54394 Brian Wheeler
                default:
1452 6ef2ba5e Alexander Graf
                goto abort_cmd;
1453 e8b54394 Brian Wheeler
                }
1454 e8b54394 Brian Wheeler
                s->status = READY_STAT | SEEK_STAT;
1455 9cdd03a7 Gerd Hoffmann
                ide_set_irq(s->bus);
1456 e8b54394 Brian Wheeler
                break;
1457 6ef2ba5e Alexander Graf
        case SMART_STATUS:
1458 e8b54394 Brian Wheeler
                if (!s->smart_errors) {
1459 6ef2ba5e Alexander Graf
                s->hcyl = 0xc2;
1460 6ef2ba5e Alexander Graf
                s->lcyl = 0x4f;
1461 e8b54394 Brian Wheeler
                } else {
1462 6ef2ba5e Alexander Graf
                s->hcyl = 0x2c;
1463 6ef2ba5e Alexander Graf
                s->lcyl = 0xf4;
1464 e8b54394 Brian Wheeler
                }
1465 e8b54394 Brian Wheeler
                s->status = READY_STAT | SEEK_STAT;
1466 9cdd03a7 Gerd Hoffmann
                ide_set_irq(s->bus);
1467 e8b54394 Brian Wheeler
                break;
1468 6ef2ba5e Alexander Graf
        case SMART_READ_THRESH:
1469 e8b54394 Brian Wheeler
                memset(s->io_buffer, 0, 0x200);
1470 e8b54394 Brian Wheeler
                s->io_buffer[0] = 0x01; /* smart struct version */
1471 e8b54394 Brian Wheeler
                for (n=0; n<30; n++) {
1472 6ef2ba5e Alexander Graf
                if (smart_attributes[n][0] == 0)
1473 e8b54394 Brian Wheeler
                        break;
1474 6ef2ba5e Alexander Graf
                s->io_buffer[2+0+(n*12)] = smart_attributes[n][0];
1475 b93af93d Brian Wheeler
                s->io_buffer[2+1+(n*12)] = smart_attributes[n][11];
1476 e8b54394 Brian Wheeler
                }
1477 e8b54394 Brian Wheeler
                for (n=0; n<511; n++) /* checksum */
1478 6ef2ba5e Alexander Graf
                s->io_buffer[511] += s->io_buffer[n];
1479 e8b54394 Brian Wheeler
                s->io_buffer[511] = 0x100 - s->io_buffer[511];
1480 e8b54394 Brian Wheeler
                s->status = READY_STAT | SEEK_STAT;
1481 e8b54394 Brian Wheeler
                ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
1482 9cdd03a7 Gerd Hoffmann
                ide_set_irq(s->bus);
1483 e8b54394 Brian Wheeler
                break;
1484 6ef2ba5e Alexander Graf
        case SMART_READ_DATA:
1485 e8b54394 Brian Wheeler
                memset(s->io_buffer, 0, 0x200);
1486 e8b54394 Brian Wheeler
                s->io_buffer[0] = 0x01; /* smart struct version */
1487 e8b54394 Brian Wheeler
                for (n=0; n<30; n++) {
1488 b93af93d Brian Wheeler
                    if (smart_attributes[n][0] == 0) {
1489 e8b54394 Brian Wheeler
                        break;
1490 b93af93d Brian Wheeler
                    }
1491 b93af93d Brian Wheeler
                    int i;
1492 b93af93d Brian Wheeler
                    for(i = 0; i < 11; i++) {
1493 b93af93d Brian Wheeler
                        s->io_buffer[2+i+(n*12)] = smart_attributes[n][i];
1494 b93af93d Brian Wheeler
                    }
1495 e8b54394 Brian Wheeler
                }
1496 e8b54394 Brian Wheeler
                s->io_buffer[362] = 0x02 | (s->smart_autosave?0x80:0x00);
1497 e8b54394 Brian Wheeler
                if (s->smart_selftest_count == 0) {
1498 6ef2ba5e Alexander Graf
                s->io_buffer[363] = 0;
1499 e8b54394 Brian Wheeler
                } else {
1500 6ef2ba5e Alexander Graf
                s->io_buffer[363] =
1501 e8b54394 Brian Wheeler
                        s->smart_selftest_data[3 + 
1502 6ef2ba5e Alexander Graf
                                           (s->smart_selftest_count - 1) *
1503 6ef2ba5e Alexander Graf
                                           24];
1504 e8b54394 Brian Wheeler
                }
1505 e8b54394 Brian Wheeler
                s->io_buffer[364] = 0x20; 
1506 e8b54394 Brian Wheeler
                s->io_buffer[365] = 0x01; 
1507 e8b54394 Brian Wheeler
                /* offline data collection capacity: execute + self-test*/
1508 e8b54394 Brian Wheeler
                s->io_buffer[367] = (1<<4 | 1<<3 | 1); 
1509 e8b54394 Brian Wheeler
                s->io_buffer[368] = 0x03; /* smart capability (1) */
1510 e8b54394 Brian Wheeler
                s->io_buffer[369] = 0x00; /* smart capability (2) */
1511 e8b54394 Brian Wheeler
                s->io_buffer[370] = 0x01; /* error logging supported */
1512 e8b54394 Brian Wheeler
                s->io_buffer[372] = 0x02; /* minutes for poll short test */
1513 e8b54394 Brian Wheeler
                s->io_buffer[373] = 0x36; /* minutes for poll ext test */
1514 e8b54394 Brian Wheeler
                s->io_buffer[374] = 0x01; /* minutes for poll conveyance */
1515 e8b54394 Brian Wheeler
1516 e8b54394 Brian Wheeler
                for (n=0; n<511; n++) 
1517 6ef2ba5e Alexander Graf
                s->io_buffer[511] += s->io_buffer[n];
1518 e8b54394 Brian Wheeler
                s->io_buffer[511] = 0x100 - s->io_buffer[511];
1519 e8b54394 Brian Wheeler
                s->status = READY_STAT | SEEK_STAT;
1520 e8b54394 Brian Wheeler
                ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
1521 9cdd03a7 Gerd Hoffmann
                ide_set_irq(s->bus);
1522 e8b54394 Brian Wheeler
                break;
1523 6ef2ba5e Alexander Graf
        case SMART_READ_LOG:
1524 e8b54394 Brian Wheeler
                switch (s->sector) {
1525 e8b54394 Brian Wheeler
                case 0x01: /* summary smart error log */
1526 6ef2ba5e Alexander Graf
                memset(s->io_buffer, 0, 0x200);
1527 6ef2ba5e Alexander Graf
                s->io_buffer[0] = 0x01;
1528 6ef2ba5e Alexander Graf
                s->io_buffer[1] = 0x00; /* no error entries */
1529 6ef2ba5e Alexander Graf
                s->io_buffer[452] = s->smart_errors & 0xff;
1530 6ef2ba5e Alexander Graf
                s->io_buffer[453] = (s->smart_errors & 0xff00) >> 8;
1531 e8b54394 Brian Wheeler
1532 6ef2ba5e Alexander Graf
                for (n=0; n<511; n++)
1533 e8b54394 Brian Wheeler
                        s->io_buffer[511] += s->io_buffer[n];
1534 6ef2ba5e Alexander Graf
                s->io_buffer[511] = 0x100 - s->io_buffer[511];
1535 6ef2ba5e Alexander Graf
                break;
1536 e8b54394 Brian Wheeler
                case 0x06: /* smart self test log */
1537 6ef2ba5e Alexander Graf
                memset(s->io_buffer, 0, 0x200);
1538 6ef2ba5e Alexander Graf
                s->io_buffer[0] = 0x01;
1539 6ef2ba5e Alexander Graf
                if (s->smart_selftest_count == 0) {
1540 e8b54394 Brian Wheeler
                        s->io_buffer[508] = 0;
1541 6ef2ba5e Alexander Graf
                } else {
1542 e8b54394 Brian Wheeler
                        s->io_buffer[508] = s->smart_selftest_count;
1543 e8b54394 Brian Wheeler
                        for (n=2; n<506; n++) 
1544 6ef2ba5e Alexander Graf
                        s->io_buffer[n] = s->smart_selftest_data[n];
1545 6ef2ba5e Alexander Graf
                }
1546 6ef2ba5e Alexander Graf
                for (n=0; n<511; n++)
1547 e8b54394 Brian Wheeler
                        s->io_buffer[511] += s->io_buffer[n];
1548 6ef2ba5e Alexander Graf
                s->io_buffer[511] = 0x100 - s->io_buffer[511];
1549 6ef2ba5e Alexander Graf
                break;
1550 e8b54394 Brian Wheeler
                default:
1551 6ef2ba5e Alexander Graf
                goto abort_cmd;
1552 e8b54394 Brian Wheeler
                }
1553 e8b54394 Brian Wheeler
                s->status = READY_STAT | SEEK_STAT;
1554 e8b54394 Brian Wheeler
                ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
1555 9cdd03a7 Gerd Hoffmann
                ide_set_irq(s->bus);
1556 e8b54394 Brian Wheeler
                break;
1557 6ef2ba5e Alexander Graf
        case SMART_EXECUTE_OFFLINE:
1558 e8b54394 Brian Wheeler
                switch (s->sector) {
1559 e8b54394 Brian Wheeler
                case 0: /* off-line routine */
1560 e8b54394 Brian Wheeler
                case 1: /* short self test */
1561 e8b54394 Brian Wheeler
                case 2: /* extended self test */
1562 6ef2ba5e Alexander Graf
                s->smart_selftest_count++;
1563 6ef2ba5e Alexander Graf
                if(s->smart_selftest_count > 21)
1564 e8b54394 Brian Wheeler
                        s->smart_selftest_count = 0;
1565 6ef2ba5e Alexander Graf
                n = 2 + (s->smart_selftest_count - 1) * 24;
1566 6ef2ba5e Alexander Graf
                s->smart_selftest_data[n] = s->sector;
1567 6ef2ba5e Alexander Graf
                s->smart_selftest_data[n+1] = 0x00; /* OK and finished */
1568 6ef2ba5e Alexander Graf
                s->smart_selftest_data[n+2] = 0x34; /* hour count lsb */
1569 6ef2ba5e Alexander Graf
                s->smart_selftest_data[n+3] = 0x12; /* hour count msb */
1570 6ef2ba5e Alexander Graf
                s->status = READY_STAT | SEEK_STAT;
1571 6ef2ba5e Alexander Graf
                ide_set_irq(s->bus);
1572 6ef2ba5e Alexander Graf
                break;
1573 e8b54394 Brian Wheeler
                default:
1574 6ef2ba5e Alexander Graf
                goto abort_cmd;
1575 e8b54394 Brian Wheeler
                }
1576 e8b54394 Brian Wheeler
                break;
1577 6ef2ba5e Alexander Graf
        default:
1578 e8b54394 Brian Wheeler
                goto abort_cmd;
1579 6ef2ba5e Alexander Graf
        }
1580 6ef2ba5e Alexander Graf
        break;
1581 6ef2ba5e Alexander Graf
    default:
1582 844505b1 Markus Armbruster
        /* should not be reachable */
1583 6ef2ba5e Alexander Graf
    abort_cmd:
1584 6ef2ba5e Alexander Graf
        ide_abort_command(s);
1585 6ef2ba5e Alexander Graf
        ide_set_irq(s->bus);
1586 6ef2ba5e Alexander Graf
        break;
1587 6ef2ba5e Alexander Graf
    }
1588 5391d806 bellard
}
1589 5391d806 bellard
1590 356721ae Gerd Hoffmann
uint32_t ide_ioport_read(void *opaque, uint32_t addr1)
1591 5391d806 bellard
{
1592 bcbdc4d3 Gerd Hoffmann
    IDEBus *bus = opaque;
1593 bcbdc4d3 Gerd Hoffmann
    IDEState *s = idebus_active_if(bus);
1594 5391d806 bellard
    uint32_t addr;
1595 c2ff060f bellard
    int ret, hob;
1596 5391d806 bellard
1597 5391d806 bellard
    addr = addr1 & 7;
1598 c2ff060f bellard
    /* FIXME: HOB readback uses bit 7, but it's always set right now */
1599 c2ff060f bellard
    //hob = s->select & (1 << 7);
1600 c2ff060f bellard
    hob = 0;
1601 5391d806 bellard
    switch(addr) {
1602 5391d806 bellard
    case 0:
1603 5391d806 bellard
        ret = 0xff;
1604 5391d806 bellard
        break;
1605 5391d806 bellard
    case 1:
1606 bcbdc4d3 Gerd Hoffmann
        if ((!bus->ifs[0].bs && !bus->ifs[1].bs) ||
1607 bcbdc4d3 Gerd Hoffmann
            (s != bus->ifs && !s->bs))
1608 c45c3d00 bellard
            ret = 0;
1609 c2ff060f bellard
        else if (!hob)
1610 c45c3d00 bellard
            ret = s->error;
1611 c2ff060f bellard
        else
1612 c2ff060f bellard
            ret = s->hob_feature;
1613 5391d806 bellard
        break;
1614 5391d806 bellard
    case 2:
1615 bcbdc4d3 Gerd Hoffmann
        if (!bus->ifs[0].bs && !bus->ifs[1].bs)
1616 c45c3d00 bellard
            ret = 0;
1617 c2ff060f bellard
        else if (!hob)
1618 c45c3d00 bellard
            ret = s->nsector & 0xff;
1619 c2ff060f bellard
        else
1620 c2ff060f bellard
            ret = s->hob_nsector;
1621 5391d806 bellard
        break;
1622 5391d806 bellard
    case 3:
1623 bcbdc4d3 Gerd Hoffmann
        if (!bus->ifs[0].bs && !bus->ifs[1].bs)
1624 c45c3d00 bellard
            ret = 0;
1625 c2ff060f bellard
        else if (!hob)
1626 c45c3d00 bellard
            ret = s->sector;
1627 c2ff060f bellard
        else
1628 c2ff060f bellard
            ret = s->hob_sector;
1629 5391d806 bellard
        break;
1630 5391d806 bellard
    case 4:
1631 bcbdc4d3 Gerd Hoffmann
        if (!bus->ifs[0].bs && !bus->ifs[1].bs)
1632 c45c3d00 bellard
            ret = 0;
1633 c2ff060f bellard
        else if (!hob)
1634 c45c3d00 bellard
            ret = s->lcyl;
1635 c2ff060f bellard
        else
1636 c2ff060f bellard
            ret = s->hob_lcyl;
1637 5391d806 bellard
        break;
1638 5391d806 bellard
    case 5:
1639 bcbdc4d3 Gerd Hoffmann
        if (!bus->ifs[0].bs && !bus->ifs[1].bs)
1640 c45c3d00 bellard
            ret = 0;
1641 c2ff060f bellard
        else if (!hob)
1642 c45c3d00 bellard
            ret = s->hcyl;
1643 c2ff060f bellard
        else
1644 c2ff060f bellard
            ret = s->hob_hcyl;
1645 5391d806 bellard
        break;
1646 5391d806 bellard
    case 6:
1647 bcbdc4d3 Gerd Hoffmann
        if (!bus->ifs[0].bs && !bus->ifs[1].bs)
1648 c45c3d00 bellard
            ret = 0;
1649 c45c3d00 bellard
        else
1650 7ae98627 bellard
            ret = s->select;
1651 5391d806 bellard
        break;
1652 5391d806 bellard
    default:
1653 5391d806 bellard
    case 7:
1654 bcbdc4d3 Gerd Hoffmann
        if ((!bus->ifs[0].bs && !bus->ifs[1].bs) ||
1655 bcbdc4d3 Gerd Hoffmann
            (s != bus->ifs && !s->bs))
1656 c45c3d00 bellard
            ret = 0;
1657 c45c3d00 bellard
        else
1658 c45c3d00 bellard
            ret = s->status;
1659 9cdd03a7 Gerd Hoffmann
        qemu_irq_lower(bus->irq);
1660 5391d806 bellard
        break;
1661 5391d806 bellard
    }
1662 5391d806 bellard
#ifdef DEBUG_IDE
1663 5391d806 bellard
    printf("ide: read addr=0x%x val=%02x\n", addr1, ret);
1664 5391d806 bellard
#endif
1665 5391d806 bellard
    return ret;
1666 5391d806 bellard
}
1667 5391d806 bellard
1668 356721ae Gerd Hoffmann
uint32_t ide_status_read(void *opaque, uint32_t addr)
1669 5391d806 bellard
{
1670 bcbdc4d3 Gerd Hoffmann
    IDEBus *bus = opaque;
1671 bcbdc4d3 Gerd Hoffmann
    IDEState *s = idebus_active_if(bus);
1672 5391d806 bellard
    int ret;
1673 7ae98627 bellard
1674 bcbdc4d3 Gerd Hoffmann
    if ((!bus->ifs[0].bs && !bus->ifs[1].bs) ||
1675 bcbdc4d3 Gerd Hoffmann
        (s != bus->ifs && !s->bs))
1676 7ae98627 bellard
        ret = 0;
1677 7ae98627 bellard
    else
1678 7ae98627 bellard
        ret = s->status;
1679 5391d806 bellard
#ifdef DEBUG_IDE
1680 5391d806 bellard
    printf("ide: read status addr=0x%x val=%02x\n", addr, ret);
1681 5391d806 bellard
#endif
1682 5391d806 bellard
    return ret;
1683 5391d806 bellard
}
1684 5391d806 bellard
1685 356721ae Gerd Hoffmann
void ide_cmd_write(void *opaque, uint32_t addr, uint32_t val)
1686 5391d806 bellard
{
1687 bcbdc4d3 Gerd Hoffmann
    IDEBus *bus = opaque;
1688 5391d806 bellard
    IDEState *s;
1689 5391d806 bellard
    int i;
1690 5391d806 bellard
1691 5391d806 bellard
#ifdef DEBUG_IDE
1692 5391d806 bellard
    printf("ide: write control addr=0x%x val=%02x\n", addr, val);
1693 5391d806 bellard
#endif
1694 5391d806 bellard
    /* common for both drives */
1695 9cdd03a7 Gerd Hoffmann
    if (!(bus->cmd & IDE_CMD_RESET) &&
1696 5391d806 bellard
        (val & IDE_CMD_RESET)) {
1697 5391d806 bellard
        /* reset low to high */
1698 5391d806 bellard
        for(i = 0;i < 2; i++) {
1699 bcbdc4d3 Gerd Hoffmann
            s = &bus->ifs[i];
1700 5391d806 bellard
            s->status = BUSY_STAT | SEEK_STAT;
1701 5391d806 bellard
            s->error = 0x01;
1702 5391d806 bellard
        }
1703 9cdd03a7 Gerd Hoffmann
    } else if ((bus->cmd & IDE_CMD_RESET) &&
1704 5391d806 bellard
               !(val & IDE_CMD_RESET)) {
1705 5391d806 bellard
        /* high to low */
1706 5391d806 bellard
        for(i = 0;i < 2; i++) {
1707 bcbdc4d3 Gerd Hoffmann
            s = &bus->ifs[i];
1708 cd8722bb Markus Armbruster
            if (s->drive_kind == IDE_CD)
1709 6b136f9e bellard
                s->status = 0x00; /* NOTE: READY is _not_ set */
1710 6b136f9e bellard
            else
1711 56bf1d37 bellard
                s->status = READY_STAT | SEEK_STAT;
1712 5391d806 bellard
            ide_set_signature(s);
1713 5391d806 bellard
        }
1714 5391d806 bellard
    }
1715 5391d806 bellard
1716 9cdd03a7 Gerd Hoffmann
    bus->cmd = val;
1717 5391d806 bellard
}
1718 5391d806 bellard
1719 40c4ed3f Kevin Wolf
/*
1720 40c4ed3f Kevin Wolf
 * Returns true if the running PIO transfer is a PIO out (i.e. data is
1721 40c4ed3f Kevin Wolf
 * transferred from the device to the guest), false if it's a PIO in
1722 40c4ed3f Kevin Wolf
 */
1723 40c4ed3f Kevin Wolf
static bool ide_is_pio_out(IDEState *s)
1724 40c4ed3f Kevin Wolf
{
1725 40c4ed3f Kevin Wolf
    if (s->end_transfer_func == ide_sector_write ||
1726 40c4ed3f Kevin Wolf
        s->end_transfer_func == ide_atapi_cmd) {
1727 40c4ed3f Kevin Wolf
        return false;
1728 40c4ed3f Kevin Wolf
    } else if (s->end_transfer_func == ide_sector_read ||
1729 40c4ed3f Kevin Wolf
               s->end_transfer_func == ide_transfer_stop ||
1730 40c4ed3f Kevin Wolf
               s->end_transfer_func == ide_atapi_cmd_reply_end ||
1731 40c4ed3f Kevin Wolf
               s->end_transfer_func == ide_dummy_transfer_stop) {
1732 40c4ed3f Kevin Wolf
        return true;
1733 40c4ed3f Kevin Wolf
    }
1734 40c4ed3f Kevin Wolf
1735 40c4ed3f Kevin Wolf
    abort();
1736 40c4ed3f Kevin Wolf
}
1737 40c4ed3f Kevin Wolf
1738 356721ae Gerd Hoffmann
void ide_data_writew(void *opaque, uint32_t addr, uint32_t val)
1739 5391d806 bellard
{
1740 bcbdc4d3 Gerd Hoffmann
    IDEBus *bus = opaque;
1741 bcbdc4d3 Gerd Hoffmann
    IDEState *s = idebus_active_if(bus);
1742 5391d806 bellard
    uint8_t *p;
1743 5391d806 bellard
1744 40c4ed3f Kevin Wolf
    /* PIO data access allowed only when DRQ bit is set. The result of a write
1745 40c4ed3f Kevin Wolf
     * during PIO out is indeterminate, just ignore it. */
1746 40c4ed3f Kevin Wolf
    if (!(s->status & DRQ_STAT) || ide_is_pio_out(s)) {
1747 fcdd25ab aliguori
        return;
1748 40c4ed3f Kevin Wolf
    }
1749 fcdd25ab aliguori
1750 5391d806 bellard
    p = s->data_ptr;
1751 0c4ad8dc bellard
    *(uint16_t *)p = le16_to_cpu(val);
1752 5391d806 bellard
    p += 2;
1753 5391d806 bellard
    s->data_ptr = p;
1754 5391d806 bellard
    if (p >= s->data_end)
1755 5391d806 bellard
        s->end_transfer_func(s);
1756 5391d806 bellard
}
1757 5391d806 bellard
1758 356721ae Gerd Hoffmann
uint32_t ide_data_readw(void *opaque, uint32_t addr)
1759 5391d806 bellard
{
1760 bcbdc4d3 Gerd Hoffmann
    IDEBus *bus = opaque;
1761 bcbdc4d3 Gerd Hoffmann
    IDEState *s = idebus_active_if(bus);
1762 5391d806 bellard
    uint8_t *p;
1763 5391d806 bellard
    int ret;
1764 fcdd25ab aliguori
1765 40c4ed3f Kevin Wolf
    /* PIO data access allowed only when DRQ bit is set. The result of a read
1766 40c4ed3f Kevin Wolf
     * during PIO in is indeterminate, return 0 and don't move forward. */
1767 40c4ed3f Kevin Wolf
    if (!(s->status & DRQ_STAT) || !ide_is_pio_out(s)) {
1768 fcdd25ab aliguori
        return 0;
1769 40c4ed3f Kevin Wolf
    }
1770 fcdd25ab aliguori
1771 5391d806 bellard
    p = s->data_ptr;
1772 0c4ad8dc bellard
    ret = cpu_to_le16(*(uint16_t *)p);
1773 5391d806 bellard
    p += 2;
1774 5391d806 bellard
    s->data_ptr = p;
1775 5391d806 bellard
    if (p >= s->data_end)
1776 5391d806 bellard
        s->end_transfer_func(s);
1777 5391d806 bellard
    return ret;
1778 5391d806 bellard
}
1779 5391d806 bellard
1780 356721ae Gerd Hoffmann
void ide_data_writel(void *opaque, uint32_t addr, uint32_t val)
1781 5391d806 bellard
{
1782 bcbdc4d3 Gerd Hoffmann
    IDEBus *bus = opaque;
1783 bcbdc4d3 Gerd Hoffmann
    IDEState *s = idebus_active_if(bus);
1784 5391d806 bellard
    uint8_t *p;
1785 5391d806 bellard
1786 40c4ed3f Kevin Wolf
    /* PIO data access allowed only when DRQ bit is set. The result of a write
1787 40c4ed3f Kevin Wolf
     * during PIO out is indeterminate, just ignore it. */
1788 40c4ed3f Kevin Wolf
    if (!(s->status & DRQ_STAT) || ide_is_pio_out(s)) {
1789 fcdd25ab aliguori
        return;
1790 40c4ed3f Kevin Wolf
    }
1791 fcdd25ab aliguori
1792 5391d806 bellard
    p = s->data_ptr;
1793 0c4ad8dc bellard
    *(uint32_t *)p = le32_to_cpu(val);
1794 5391d806 bellard
    p += 4;
1795 5391d806 bellard
    s->data_ptr = p;
1796 5391d806 bellard
    if (p >= s->data_end)
1797 5391d806 bellard
        s->end_transfer_func(s);
1798 5391d806 bellard
}
1799 5391d806 bellard
1800 356721ae Gerd Hoffmann
uint32_t ide_data_readl(void *opaque, uint32_t addr)
1801 5391d806 bellard
{
1802 bcbdc4d3 Gerd Hoffmann
    IDEBus *bus = opaque;
1803 bcbdc4d3 Gerd Hoffmann
    IDEState *s = idebus_active_if(bus);
1804 5391d806 bellard
    uint8_t *p;
1805 5391d806 bellard
    int ret;
1806 3b46e624 ths
1807 40c4ed3f Kevin Wolf
    /* PIO data access allowed only when DRQ bit is set. The result of a read
1808 40c4ed3f Kevin Wolf
     * during PIO in is indeterminate, return 0 and don't move forward. */
1809 40c4ed3f Kevin Wolf
    if (!(s->status & DRQ_STAT) || !ide_is_pio_out(s)) {
1810 fcdd25ab aliguori
        return 0;
1811 40c4ed3f Kevin Wolf
    }
1812 fcdd25ab aliguori
1813 5391d806 bellard
    p = s->data_ptr;
1814 0c4ad8dc bellard
    ret = cpu_to_le32(*(uint32_t *)p);
1815 5391d806 bellard
    p += 4;
1816 5391d806 bellard
    s->data_ptr = p;
1817 5391d806 bellard
    if (p >= s->data_end)
1818 5391d806 bellard
        s->end_transfer_func(s);
1819 5391d806 bellard
    return ret;
1820 5391d806 bellard
}
1821 5391d806 bellard
1822 a7dfe172 bellard
static void ide_dummy_transfer_stop(IDEState *s)
1823 a7dfe172 bellard
{
1824 a7dfe172 bellard
    s->data_ptr = s->io_buffer;
1825 a7dfe172 bellard
    s->data_end = s->io_buffer;
1826 a7dfe172 bellard
    s->io_buffer[0] = 0xff;
1827 a7dfe172 bellard
    s->io_buffer[1] = 0xff;
1828 a7dfe172 bellard
    s->io_buffer[2] = 0xff;
1829 a7dfe172 bellard
    s->io_buffer[3] = 0xff;
1830 a7dfe172 bellard
}
1831 a7dfe172 bellard
1832 4a643563 Blue Swirl
static void ide_reset(IDEState *s)
1833 5391d806 bellard
{
1834 4a643563 Blue Swirl
#ifdef DEBUG_IDE
1835 4a643563 Blue Swirl
    printf("ide: reset\n");
1836 4a643563 Blue Swirl
#endif
1837 bef0fd59 Stefan Hajnoczi
1838 bef0fd59 Stefan Hajnoczi
    if (s->pio_aiocb) {
1839 bef0fd59 Stefan Hajnoczi
        bdrv_aio_cancel(s->pio_aiocb);
1840 bef0fd59 Stefan Hajnoczi
        s->pio_aiocb = NULL;
1841 bef0fd59 Stefan Hajnoczi
    }
1842 bef0fd59 Stefan Hajnoczi
1843 cd8722bb Markus Armbruster
    if (s->drive_kind == IDE_CFATA)
1844 201a51fc balrog
        s->mult_sectors = 0;
1845 201a51fc balrog
    else
1846 201a51fc balrog
        s->mult_sectors = MAX_MULT_SECTORS;
1847 4a643563 Blue Swirl
    /* ide regs */
1848 4a643563 Blue Swirl
    s->feature = 0;
1849 4a643563 Blue Swirl
    s->error = 0;
1850 4a643563 Blue Swirl
    s->nsector = 0;
1851 4a643563 Blue Swirl
    s->sector = 0;
1852 4a643563 Blue Swirl
    s->lcyl = 0;
1853 4a643563 Blue Swirl
    s->hcyl = 0;
1854 4a643563 Blue Swirl
1855 4a643563 Blue Swirl
    /* lba48 */
1856 4a643563 Blue Swirl
    s->hob_feature = 0;
1857 4a643563 Blue Swirl
    s->hob_sector = 0;
1858 4a643563 Blue Swirl
    s->hob_nsector = 0;
1859 4a643563 Blue Swirl
    s->hob_lcyl = 0;
1860 4a643563 Blue Swirl
    s->hob_hcyl = 0;
1861 4a643563 Blue Swirl
1862 5391d806 bellard
    s->select = 0xa0;
1863 41a2b959 aliguori
    s->status = READY_STAT | SEEK_STAT;
1864 4a643563 Blue Swirl
1865 4a643563 Blue Swirl
    s->lba48 = 0;
1866 4a643563 Blue Swirl
1867 4a643563 Blue Swirl
    /* ATAPI specific */
1868 4a643563 Blue Swirl
    s->sense_key = 0;
1869 4a643563 Blue Swirl
    s->asc = 0;
1870 4a643563 Blue Swirl
    s->cdrom_changed = 0;
1871 4a643563 Blue Swirl
    s->packet_transfer_size = 0;
1872 4a643563 Blue Swirl
    s->elementary_transfer_size = 0;
1873 4a643563 Blue Swirl
    s->io_buffer_index = 0;
1874 4a643563 Blue Swirl
    s->cd_sector_size = 0;
1875 4a643563 Blue Swirl
    s->atapi_dma = 0;
1876 4a643563 Blue Swirl
    /* ATA DMA state */
1877 4a643563 Blue Swirl
    s->io_buffer_size = 0;
1878 4a643563 Blue Swirl
    s->req_nb_sectors = 0;
1879 4a643563 Blue Swirl
1880 5391d806 bellard
    ide_set_signature(s);
1881 a7dfe172 bellard
    /* init the transfer handler so that 0xffff is returned on data
1882 a7dfe172 bellard
       accesses */
1883 a7dfe172 bellard
    s->end_transfer_func = ide_dummy_transfer_stop;
1884 a7dfe172 bellard
    ide_dummy_transfer_stop(s);
1885 201a51fc balrog
    s->media_changed = 0;
1886 5391d806 bellard
}
1887 5391d806 bellard
1888 4a643563 Blue Swirl
void ide_bus_reset(IDEBus *bus)
1889 4a643563 Blue Swirl
{
1890 4a643563 Blue Swirl
    bus->unit = 0;
1891 4a643563 Blue Swirl
    bus->cmd = 0;
1892 4a643563 Blue Swirl
    ide_reset(&bus->ifs[0]);
1893 4a643563 Blue Swirl
    ide_reset(&bus->ifs[1]);
1894 4a643563 Blue Swirl
    ide_clear_hob(bus);
1895 40a6238a Alexander Graf
1896 40a6238a Alexander Graf
    /* pending async DMA */
1897 40a6238a Alexander Graf
    if (bus->dma->aiocb) {
1898 40a6238a Alexander Graf
#ifdef DEBUG_AIO
1899 40a6238a Alexander Graf
        printf("aio_cancel\n");
1900 40a6238a Alexander Graf
#endif
1901 40a6238a Alexander Graf
        bdrv_aio_cancel(bus->dma->aiocb);
1902 40a6238a Alexander Graf
        bus->dma->aiocb = NULL;
1903 40a6238a Alexander Graf
    }
1904 40a6238a Alexander Graf
1905 40a6238a Alexander Graf
    /* reset dma provider too */
1906 40a6238a Alexander Graf
    bus->dma->ops->reset(bus->dma);
1907 4a643563 Blue Swirl
}
1908 4a643563 Blue Swirl
1909 e4def80b Markus Armbruster
static bool ide_cd_is_tray_open(void *opaque)
1910 e4def80b Markus Armbruster
{
1911 e4def80b Markus Armbruster
    return ((IDEState *)opaque)->tray_open;
1912 e4def80b Markus Armbruster
}
1913 e4def80b Markus Armbruster
1914 f107639a Markus Armbruster
static bool ide_cd_is_medium_locked(void *opaque)
1915 f107639a Markus Armbruster
{
1916 f107639a Markus Armbruster
    return ((IDEState *)opaque)->tray_locked;
1917 f107639a Markus Armbruster
}
1918 f107639a Markus Armbruster
1919 0e49de52 Markus Armbruster
static const BlockDevOps ide_cd_block_ops = {
1920 145feb17 Markus Armbruster
    .change_media_cb = ide_cd_change_cb,
1921 2df0a3a3 Paolo Bonzini
    .eject_request_cb = ide_cd_eject_request_cb,
1922 e4def80b Markus Armbruster
    .is_tray_open = ide_cd_is_tray_open,
1923 f107639a Markus Armbruster
    .is_medium_locked = ide_cd_is_medium_locked,
1924 0e49de52 Markus Armbruster
};
1925 0e49de52 Markus Armbruster
1926 1f56e32a Markus Armbruster
int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
1927 95ebda85 Floris Bos
                   const char *version, const char *serial, const char *model,
1928 ba801960 Markus Armbruster
                   uint64_t wwn,
1929 ba801960 Markus Armbruster
                   uint32_t cylinders, uint32_t heads, uint32_t secs,
1930 ba801960 Markus Armbruster
                   int chs_trans)
1931 88804180 Gerd Hoffmann
{
1932 88804180 Gerd Hoffmann
    uint64_t nb_sectors;
1933 88804180 Gerd Hoffmann
1934 f8b6cc00 Markus Armbruster
    s->bs = bs;
1935 1f56e32a Markus Armbruster
    s->drive_kind = kind;
1936 1f56e32a Markus Armbruster
1937 f8b6cc00 Markus Armbruster
    bdrv_get_geometry(bs, &nb_sectors);
1938 870111c8 Markus Armbruster
    s->cylinders = cylinders;
1939 870111c8 Markus Armbruster
    s->heads = heads;
1940 870111c8 Markus Armbruster
    s->sectors = secs;
1941 ba801960 Markus Armbruster
    s->chs_trans = chs_trans;
1942 870111c8 Markus Armbruster
    s->nb_sectors = nb_sectors;
1943 95ebda85 Floris Bos
    s->wwn = wwn;
1944 870111c8 Markus Armbruster
    /* The SMART values should be preserved across power cycles
1945 870111c8 Markus Armbruster
       but they aren't.  */
1946 870111c8 Markus Armbruster
    s->smart_enabled = 1;
1947 870111c8 Markus Armbruster
    s->smart_autosave = 1;
1948 870111c8 Markus Armbruster
    s->smart_errors = 0;
1949 870111c8 Markus Armbruster
    s->smart_selftest_count = 0;
1950 1f56e32a Markus Armbruster
    if (kind == IDE_CD) {
1951 0e49de52 Markus Armbruster
        bdrv_set_dev_ops(bs, &ide_cd_block_ops, s);
1952 7b6f9300 Markus Armbruster
        bdrv_set_buffer_alignment(bs, 2048);
1953 7aa9c811 Markus Armbruster
    } else {
1954 98f28ad7 Markus Armbruster
        if (!bdrv_is_inserted(s->bs)) {
1955 98f28ad7 Markus Armbruster
            error_report("Device needs media, but drive is empty");
1956 98f28ad7 Markus Armbruster
            return -1;
1957 98f28ad7 Markus Armbruster
        }
1958 7aa9c811 Markus Armbruster
        if (bdrv_is_read_only(bs)) {
1959 7aa9c811 Markus Armbruster
            error_report("Can't use a read-only drive");
1960 7aa9c811 Markus Armbruster
            return -1;
1961 7aa9c811 Markus Armbruster
        }
1962 88804180 Gerd Hoffmann
    }
1963 f8b6cc00 Markus Armbruster
    if (serial) {
1964 aa2c91bd Floris Bos
        pstrcpy(s->drive_serial_str, sizeof(s->drive_serial_str), serial);
1965 6ced55a5 Markus Armbruster
    } else {
1966 88804180 Gerd Hoffmann
        snprintf(s->drive_serial_str, sizeof(s->drive_serial_str),
1967 88804180 Gerd Hoffmann
                 "QM%05d", s->drive_serial);
1968 870111c8 Markus Armbruster
    }
1969 27e0c9a1 Floris Bos
    if (model) {
1970 27e0c9a1 Floris Bos
        pstrcpy(s->drive_model_str, sizeof(s->drive_model_str), model);
1971 27e0c9a1 Floris Bos
    } else {
1972 27e0c9a1 Floris Bos
        switch (kind) {
1973 27e0c9a1 Floris Bos
        case IDE_CD:
1974 27e0c9a1 Floris Bos
            strcpy(s->drive_model_str, "QEMU DVD-ROM");
1975 27e0c9a1 Floris Bos
            break;
1976 27e0c9a1 Floris Bos
        case IDE_CFATA:
1977 27e0c9a1 Floris Bos
            strcpy(s->drive_model_str, "QEMU MICRODRIVE");
1978 27e0c9a1 Floris Bos
            break;
1979 27e0c9a1 Floris Bos
        default:
1980 27e0c9a1 Floris Bos
            strcpy(s->drive_model_str, "QEMU HARDDISK");
1981 27e0c9a1 Floris Bos
            break;
1982 27e0c9a1 Floris Bos
        }
1983 27e0c9a1 Floris Bos
    }
1984 27e0c9a1 Floris Bos
1985 47c06340 Gerd Hoffmann
    if (version) {
1986 47c06340 Gerd Hoffmann
        pstrcpy(s->version, sizeof(s->version), version);
1987 47c06340 Gerd Hoffmann
    } else {
1988 93bfef4c Crรญstian Viana
        pstrcpy(s->version, sizeof(s->version), qemu_get_version());
1989 47c06340 Gerd Hoffmann
    }
1990 40a6238a Alexander Graf
1991 88804180 Gerd Hoffmann
    ide_reset(s);
1992 50fb1900 Luiz Capitulino
    bdrv_iostatus_enable(bs);
1993 c4d74df7 Markus Armbruster
    return 0;
1994 88804180 Gerd Hoffmann
}
1995 88804180 Gerd Hoffmann
1996 57234ee4 Markus Armbruster
static void ide_init1(IDEBus *bus, int unit)
1997 d459da0e Markus Armbruster
{
1998 d459da0e Markus Armbruster
    static int drive_serial = 1;
1999 d459da0e Markus Armbruster
    IDEState *s = &bus->ifs[unit];
2000 d459da0e Markus Armbruster
2001 d459da0e Markus Armbruster
    s->bus = bus;
2002 d459da0e Markus Armbruster
    s->unit = unit;
2003 d459da0e Markus Armbruster
    s->drive_serial = drive_serial++;
2004 1b2adf28 Christoph Hellwig
    /* we need at least 2k alignment for accessing CDROMs using O_DIRECT */
2005 50641c5c Juan Quintela
    s->io_buffer_total_len = IDE_DMA_BUF_SECTORS*512 + 4;
2006 c925400b Kevin Wolf
    s->io_buffer = qemu_memalign(2048, s->io_buffer_total_len);
2007 c925400b Kevin Wolf
    memset(s->io_buffer, 0, s->io_buffer_total_len);
2008 c925400b Kevin Wolf
2009 d459da0e Markus Armbruster
    s->smart_selftest_data = qemu_blockalign(s->bs, 512);
2010 c925400b Kevin Wolf
    memset(s->smart_selftest_data, 0, 512);
2011 c925400b Kevin Wolf
2012 74475455 Paolo Bonzini
    s->sector_write_timer = qemu_new_timer_ns(vm_clock,
2013 d459da0e Markus Armbruster
                                           ide_sector_write_timer_cb, s);
2014 57234ee4 Markus Armbruster
}
2015 57234ee4 Markus Armbruster
2016 40a6238a Alexander Graf
static void ide_nop_start(IDEDMA *dma, IDEState *s,
2017 40a6238a Alexander Graf
                          BlockDriverCompletionFunc *cb)
2018 40a6238a Alexander Graf
{
2019 40a6238a Alexander Graf
}
2020 40a6238a Alexander Graf
2021 40a6238a Alexander Graf
static int ide_nop(IDEDMA *dma)
2022 40a6238a Alexander Graf
{
2023 40a6238a Alexander Graf
    return 0;
2024 40a6238a Alexander Graf
}
2025 40a6238a Alexander Graf
2026 40a6238a Alexander Graf
static int ide_nop_int(IDEDMA *dma, int x)
2027 40a6238a Alexander Graf
{
2028 40a6238a Alexander Graf
    return 0;
2029 40a6238a Alexander Graf
}
2030 40a6238a Alexander Graf
2031 1dfb4dd9 Luiz Capitulino
static void ide_nop_restart(void *opaque, int x, RunState y)
2032 40a6238a Alexander Graf
{
2033 40a6238a Alexander Graf
}
2034 40a6238a Alexander Graf
2035 40a6238a Alexander Graf
static const IDEDMAOps ide_dma_nop_ops = {
2036 40a6238a Alexander Graf
    .start_dma      = ide_nop_start,
2037 40a6238a Alexander Graf
    .start_transfer = ide_nop,
2038 40a6238a Alexander Graf
    .prepare_buf    = ide_nop_int,
2039 40a6238a Alexander Graf
    .rw_buf         = ide_nop_int,
2040 40a6238a Alexander Graf
    .set_unit       = ide_nop_int,
2041 40a6238a Alexander Graf
    .add_status     = ide_nop_int,
2042 40a6238a Alexander Graf
    .set_inactive   = ide_nop,
2043 40a6238a Alexander Graf
    .restart_cb     = ide_nop_restart,
2044 40a6238a Alexander Graf
    .reset          = ide_nop,
2045 40a6238a Alexander Graf
};
2046 40a6238a Alexander Graf
2047 40a6238a Alexander Graf
static IDEDMA ide_dma_nop = {
2048 40a6238a Alexander Graf
    .ops = &ide_dma_nop_ops,
2049 40a6238a Alexander Graf
    .aiocb = NULL,
2050 40a6238a Alexander Graf
};
2051 40a6238a Alexander Graf
2052 57234ee4 Markus Armbruster
void ide_init2(IDEBus *bus, qemu_irq irq)
2053 57234ee4 Markus Armbruster
{
2054 57234ee4 Markus Armbruster
    int i;
2055 57234ee4 Markus Armbruster
2056 57234ee4 Markus Armbruster
    for(i = 0; i < 2; i++) {
2057 57234ee4 Markus Armbruster
        ide_init1(bus, i);
2058 57234ee4 Markus Armbruster
        ide_reset(&bus->ifs[i]);
2059 870111c8 Markus Armbruster
    }
2060 57234ee4 Markus Armbruster
    bus->irq = irq;
2061 40a6238a Alexander Graf
    bus->dma = &ide_dma_nop;
2062 d459da0e Markus Armbruster
}
2063 d459da0e Markus Armbruster
2064 57234ee4 Markus Armbruster
/* TODO convert users to qdev and remove */
2065 57234ee4 Markus Armbruster
void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0,
2066 57234ee4 Markus Armbruster
                                    DriveInfo *hd1, qemu_irq irq)
2067 5391d806 bellard
{
2068 ba801960 Markus Armbruster
    int i, trans;
2069 57234ee4 Markus Armbruster
    DriveInfo *dinfo;
2070 ba801960 Markus Armbruster
    uint32_t cyls, heads, secs;
2071 5391d806 bellard
2072 caed8802 bellard
    for(i = 0; i < 2; i++) {
2073 57234ee4 Markus Armbruster
        dinfo = i == 0 ? hd0 : hd1;
2074 57234ee4 Markus Armbruster
        ide_init1(bus, i);
2075 57234ee4 Markus Armbruster
        if (dinfo) {
2076 ba801960 Markus Armbruster
            cyls  = dinfo->cyls;
2077 ba801960 Markus Armbruster
            heads = dinfo->heads;
2078 ba801960 Markus Armbruster
            secs  = dinfo->secs;
2079 ba801960 Markus Armbruster
            trans = dinfo->trans;
2080 ba801960 Markus Armbruster
            if (!cyls && !heads && !secs) {
2081 ba801960 Markus Armbruster
                hd_geometry_guess(dinfo->bdrv, &cyls, &heads, &secs, &trans);
2082 2adc99b2 Markus Armbruster
            } else if (trans == BIOS_ATA_TRANSLATION_AUTO) {
2083 2adc99b2 Markus Armbruster
                trans = hd_bios_chs_auto_trans(cyls, heads, secs);
2084 ba801960 Markus Armbruster
            }
2085 b7eb0c9f Markus Armbruster
            if (cyls < 1 || cyls > 65535) {
2086 b7eb0c9f Markus Armbruster
                error_report("cyls must be between 1 and 65535");
2087 b7eb0c9f Markus Armbruster
                exit(1);
2088 b7eb0c9f Markus Armbruster
            }
2089 b7eb0c9f Markus Armbruster
            if (heads < 1 || heads > 16) {
2090 b7eb0c9f Markus Armbruster
                error_report("heads must be between 1 and 16");
2091 b7eb0c9f Markus Armbruster
                exit(1);
2092 b7eb0c9f Markus Armbruster
            }
2093 b7eb0c9f Markus Armbruster
            if (secs < 1 || secs > 255) {
2094 b7eb0c9f Markus Armbruster
                error_report("secs must be between 1 and 255");
2095 b7eb0c9f Markus Armbruster
                exit(1);
2096 b7eb0c9f Markus Armbruster
            }
2097 1f56e32a Markus Armbruster
            if (ide_init_drive(&bus->ifs[i], dinfo->bdrv,
2098 577d0a38 Markus Armbruster
                               dinfo->media_cd ? IDE_CD : IDE_HD,
2099 577d0a38 Markus Armbruster
                               NULL, dinfo->serial, NULL, 0,
2100 577d0a38 Markus Armbruster
                               cyls, heads, secs, trans) < 0) {
2101 c4d74df7 Markus Armbruster
                error_report("Can't set up IDE drive %s", dinfo->id);
2102 c4d74df7 Markus Armbruster
                exit(1);
2103 c4d74df7 Markus Armbruster
            }
2104 fa879d62 Markus Armbruster
            bdrv_attach_dev_nofail(dinfo->bdrv, &bus->ifs[i]);
2105 57234ee4 Markus Armbruster
        } else {
2106 57234ee4 Markus Armbruster
            ide_reset(&bus->ifs[i]);
2107 57234ee4 Markus Armbruster
        }
2108 5391d806 bellard
    }
2109 9cdd03a7 Gerd Hoffmann
    bus->irq = irq;
2110 40a6238a Alexander Graf
    bus->dma = &ide_dma_nop;
2111 69b91039 bellard
}
2112 69b91039 bellard
2113 4a91d3b3 Richard Henderson
static const MemoryRegionPortio ide_portio_list[] = {
2114 4a91d3b3 Richard Henderson
    { 0, 8, 1, .read = ide_ioport_read, .write = ide_ioport_write },
2115 4a91d3b3 Richard Henderson
    { 0, 2, 2, .read = ide_data_readw, .write = ide_data_writew },
2116 4a91d3b3 Richard Henderson
    { 0, 4, 4, .read = ide_data_readl, .write = ide_data_writel },
2117 4a91d3b3 Richard Henderson
    PORTIO_END_OF_LIST(),
2118 4a91d3b3 Richard Henderson
};
2119 4a91d3b3 Richard Henderson
2120 4a91d3b3 Richard Henderson
static const MemoryRegionPortio ide_portio2_list[] = {
2121 4a91d3b3 Richard Henderson
    { 0, 1, 1, .read = ide_status_read, .write = ide_cmd_write },
2122 4a91d3b3 Richard Henderson
    PORTIO_END_OF_LIST(),
2123 4a91d3b3 Richard Henderson
};
2124 4a91d3b3 Richard Henderson
2125 4a91d3b3 Richard Henderson
void ide_init_ioport(IDEBus *bus, ISADevice *dev, int iobase, int iobase2)
2126 69b91039 bellard
{
2127 4a91d3b3 Richard Henderson
    /* ??? Assume only ISA and PCI configurations, and that the PCI-ISA
2128 4a91d3b3 Richard Henderson
       bridge has been setup properly to always register with ISA.  */
2129 4a91d3b3 Richard Henderson
    isa_register_portio_list(dev, iobase, ide_portio_list, bus, "ide");
2130 4a91d3b3 Richard Henderson
2131 caed8802 bellard
    if (iobase2) {
2132 4a91d3b3 Richard Henderson
        isa_register_portio_list(dev, iobase2, ide_portio2_list, bus, "ide");
2133 5391d806 bellard
    }
2134 5391d806 bellard
}
2135 69b91039 bellard
2136 37159f13 Juan Quintela
static bool is_identify_set(void *opaque, int version_id)
2137 aa941b94 balrog
{
2138 37159f13 Juan Quintela
    IDEState *s = opaque;
2139 37159f13 Juan Quintela
2140 37159f13 Juan Quintela
    return s->identify_set != 0;
2141 37159f13 Juan Quintela
}
2142 37159f13 Juan Quintela
2143 50641c5c Juan Quintela
static EndTransferFunc* transfer_end_table[] = {
2144 50641c5c Juan Quintela
        ide_sector_read,
2145 50641c5c Juan Quintela
        ide_sector_write,
2146 50641c5c Juan Quintela
        ide_transfer_stop,
2147 50641c5c Juan Quintela
        ide_atapi_cmd_reply_end,
2148 50641c5c Juan Quintela
        ide_atapi_cmd,
2149 50641c5c Juan Quintela
        ide_dummy_transfer_stop,
2150 50641c5c Juan Quintela
};
2151 50641c5c Juan Quintela
2152 50641c5c Juan Quintela
static int transfer_end_table_idx(EndTransferFunc *fn)
2153 50641c5c Juan Quintela
{
2154 50641c5c Juan Quintela
    int i;
2155 50641c5c Juan Quintela
2156 50641c5c Juan Quintela
    for (i = 0; i < ARRAY_SIZE(transfer_end_table); i++)
2157 50641c5c Juan Quintela
        if (transfer_end_table[i] == fn)
2158 50641c5c Juan Quintela
            return i;
2159 50641c5c Juan Quintela
2160 50641c5c Juan Quintela
    return -1;
2161 50641c5c Juan Quintela
}
2162 50641c5c Juan Quintela
2163 37159f13 Juan Quintela
static int ide_drive_post_load(void *opaque, int version_id)
2164 aa941b94 balrog
{
2165 37159f13 Juan Quintela
    IDEState *s = opaque;
2166 37159f13 Juan Quintela
2167 37159f13 Juan Quintela
    if (version_id < 3) {
2168 67cc61e4 Paolo Bonzini
        if (s->sense_key == UNIT_ATTENTION &&
2169 37159f13 Juan Quintela
            s->asc == ASC_MEDIUM_MAY_HAVE_CHANGED) {
2170 93c8cfd9 Gleb Natapov
            s->cdrom_changed = 1;
2171 37159f13 Juan Quintela
        }
2172 93c8cfd9 Gleb Natapov
    }
2173 7cdd481c Paolo Bonzini
    if (s->identify_set) {
2174 7cdd481c Paolo Bonzini
        bdrv_set_enable_write_cache(s->bs, !!(s->identify_data[85] & (1 << 5)));
2175 7cdd481c Paolo Bonzini
    }
2176 37159f13 Juan Quintela
    return 0;
2177 aa941b94 balrog
}
2178 aa941b94 balrog
2179 50641c5c Juan Quintela
static int ide_drive_pio_post_load(void *opaque, int version_id)
2180 50641c5c Juan Quintela
{
2181 50641c5c Juan Quintela
    IDEState *s = opaque;
2182 50641c5c Juan Quintela
2183 fb60105d Kevin Wolf
    if (s->end_transfer_fn_idx >= ARRAY_SIZE(transfer_end_table)) {
2184 50641c5c Juan Quintela
        return -EINVAL;
2185 50641c5c Juan Quintela
    }
2186 50641c5c Juan Quintela
    s->end_transfer_func = transfer_end_table[s->end_transfer_fn_idx];
2187 50641c5c Juan Quintela
    s->data_ptr = s->io_buffer + s->cur_io_buffer_offset;
2188 50641c5c Juan Quintela
    s->data_end = s->data_ptr + s->cur_io_buffer_len;
2189 50641c5c Juan Quintela
2190 50641c5c Juan Quintela
    return 0;
2191 50641c5c Juan Quintela
}
2192 50641c5c Juan Quintela
2193 50641c5c Juan Quintela
static void ide_drive_pio_pre_save(void *opaque)
2194 50641c5c Juan Quintela
{
2195 50641c5c Juan Quintela
    IDEState *s = opaque;
2196 50641c5c Juan Quintela
    int idx;
2197 50641c5c Juan Quintela
2198 50641c5c Juan Quintela
    s->cur_io_buffer_offset = s->data_ptr - s->io_buffer;
2199 50641c5c Juan Quintela
    s->cur_io_buffer_len = s->data_end - s->data_ptr;
2200 50641c5c Juan Quintela
2201 50641c5c Juan Quintela
    idx = transfer_end_table_idx(s->end_transfer_func);
2202 50641c5c Juan Quintela
    if (idx == -1) {
2203 50641c5c Juan Quintela
        fprintf(stderr, "%s: invalid end_transfer_func for DRQ_STAT\n",
2204 50641c5c Juan Quintela
                        __func__);
2205 50641c5c Juan Quintela
        s->end_transfer_fn_idx = 2;
2206 50641c5c Juan Quintela
    } else {
2207 50641c5c Juan Quintela
        s->end_transfer_fn_idx = idx;
2208 50641c5c Juan Quintela
    }
2209 50641c5c Juan Quintela
}
2210 50641c5c Juan Quintela
2211 50641c5c Juan Quintela
static bool ide_drive_pio_state_needed(void *opaque)
2212 50641c5c Juan Quintela
{
2213 50641c5c Juan Quintela
    IDEState *s = opaque;
2214 50641c5c Juan Quintela
2215 fdc650d7 Kevin Wolf
    return ((s->status & DRQ_STAT) != 0)
2216 fdc650d7 Kevin Wolf
        || (s->bus->error_status & BM_STATUS_PIO_RETRY);
2217 50641c5c Juan Quintela
}
2218 50641c5c Juan Quintela
2219 db118fe7 Markus Armbruster
static bool ide_tray_state_needed(void *opaque)
2220 db118fe7 Markus Armbruster
{
2221 db118fe7 Markus Armbruster
    IDEState *s = opaque;
2222 db118fe7 Markus Armbruster
2223 db118fe7 Markus Armbruster
    return s->tray_open || s->tray_locked;
2224 db118fe7 Markus Armbruster
}
2225 db118fe7 Markus Armbruster
2226 996faf1a Amit Shah
static bool ide_atapi_gesn_needed(void *opaque)
2227 996faf1a Amit Shah
{
2228 996faf1a Amit Shah
    IDEState *s = opaque;
2229 996faf1a Amit Shah
2230 996faf1a Amit Shah
    return s->events.new_media || s->events.eject_request;
2231 996faf1a Amit Shah
}
2232 996faf1a Amit Shah
2233 def93791 Kevin Wolf
static bool ide_error_needed(void *opaque)
2234 def93791 Kevin Wolf
{
2235 def93791 Kevin Wolf
    IDEBus *bus = opaque;
2236 def93791 Kevin Wolf
2237 def93791 Kevin Wolf
    return (bus->error_status != 0);
2238 def93791 Kevin Wolf
}
2239 def93791 Kevin Wolf
2240 996faf1a Amit Shah
/* Fields for GET_EVENT_STATUS_NOTIFICATION ATAPI command */
2241 656fbeff Markus Armbruster
static const VMStateDescription vmstate_ide_atapi_gesn_state = {
2242 996faf1a Amit Shah
    .name ="ide_drive/atapi/gesn_state",
2243 996faf1a Amit Shah
    .version_id = 1,
2244 996faf1a Amit Shah
    .minimum_version_id = 1,
2245 996faf1a Amit Shah
    .minimum_version_id_old = 1,
2246 996faf1a Amit Shah
    .fields = (VMStateField []) {
2247 996faf1a Amit Shah
        VMSTATE_BOOL(events.new_media, IDEState),
2248 996faf1a Amit Shah
        VMSTATE_BOOL(events.eject_request, IDEState),
2249 0754f9ec Kevin Wolf
        VMSTATE_END_OF_LIST()
2250 996faf1a Amit Shah
    }
2251 996faf1a Amit Shah
};
2252 996faf1a Amit Shah
2253 db118fe7 Markus Armbruster
static const VMStateDescription vmstate_ide_tray_state = {
2254 db118fe7 Markus Armbruster
    .name = "ide_drive/tray_state",
2255 db118fe7 Markus Armbruster
    .version_id = 1,
2256 db118fe7 Markus Armbruster
    .minimum_version_id = 1,
2257 db118fe7 Markus Armbruster
    .minimum_version_id_old = 1,
2258 db118fe7 Markus Armbruster
    .fields = (VMStateField[]) {
2259 db118fe7 Markus Armbruster
        VMSTATE_BOOL(tray_open, IDEState),
2260 db118fe7 Markus Armbruster
        VMSTATE_BOOL(tray_locked, IDEState),
2261 db118fe7 Markus Armbruster
        VMSTATE_END_OF_LIST()
2262 db118fe7 Markus Armbruster
    }
2263 db118fe7 Markus Armbruster
};
2264 db118fe7 Markus Armbruster
2265 656fbeff Markus Armbruster
static const VMStateDescription vmstate_ide_drive_pio_state = {
2266 50641c5c Juan Quintela
    .name = "ide_drive/pio_state",
2267 50641c5c Juan Quintela
    .version_id = 1,
2268 50641c5c Juan Quintela
    .minimum_version_id = 1,
2269 50641c5c Juan Quintela
    .minimum_version_id_old = 1,
2270 50641c5c Juan Quintela
    .pre_save = ide_drive_pio_pre_save,
2271 50641c5c Juan Quintela
    .post_load = ide_drive_pio_post_load,
2272 50641c5c Juan Quintela
    .fields      = (VMStateField []) {
2273 50641c5c Juan Quintela
        VMSTATE_INT32(req_nb_sectors, IDEState),
2274 50641c5c Juan Quintela
        VMSTATE_VARRAY_INT32(io_buffer, IDEState, io_buffer_total_len, 1,
2275 50641c5c Juan Quintela
                             vmstate_info_uint8, uint8_t),
2276 50641c5c Juan Quintela
        VMSTATE_INT32(cur_io_buffer_offset, IDEState),
2277 50641c5c Juan Quintela
        VMSTATE_INT32(cur_io_buffer_len, IDEState),
2278 50641c5c Juan Quintela
        VMSTATE_UINT8(end_transfer_fn_idx, IDEState),
2279 50641c5c Juan Quintela
        VMSTATE_INT32(elementary_transfer_size, IDEState),
2280 50641c5c Juan Quintela
        VMSTATE_INT32(packet_transfer_size, IDEState),
2281 50641c5c Juan Quintela
        VMSTATE_END_OF_LIST()
2282 50641c5c Juan Quintela
    }
2283 50641c5c Juan Quintela
};
2284 50641c5c Juan Quintela
2285 37159f13 Juan Quintela
const VMStateDescription vmstate_ide_drive = {
2286 37159f13 Juan Quintela
    .name = "ide_drive",
2287 3abb6260 Juan Quintela
    .version_id = 3,
2288 37159f13 Juan Quintela
    .minimum_version_id = 0,
2289 37159f13 Juan Quintela
    .minimum_version_id_old = 0,
2290 37159f13 Juan Quintela
    .post_load = ide_drive_post_load,
2291 37159f13 Juan Quintela
    .fields      = (VMStateField []) {
2292 37159f13 Juan Quintela
        VMSTATE_INT32(mult_sectors, IDEState),
2293 37159f13 Juan Quintela
        VMSTATE_INT32(identify_set, IDEState),
2294 37159f13 Juan Quintela
        VMSTATE_BUFFER_TEST(identify_data, IDEState, is_identify_set),
2295 37159f13 Juan Quintela
        VMSTATE_UINT8(feature, IDEState),
2296 37159f13 Juan Quintela
        VMSTATE_UINT8(error, IDEState),
2297 37159f13 Juan Quintela
        VMSTATE_UINT32(nsector, IDEState),
2298 37159f13 Juan Quintela
        VMSTATE_UINT8(sector, IDEState),
2299 37159f13 Juan Quintela
        VMSTATE_UINT8(lcyl, IDEState),
2300 37159f13 Juan Quintela
        VMSTATE_UINT8(hcyl, IDEState),
2301 37159f13 Juan Quintela
        VMSTATE_UINT8(hob_feature, IDEState),
2302 37159f13 Juan Quintela
        VMSTATE_UINT8(hob_sector, IDEState),
2303 37159f13 Juan Quintela
        VMSTATE_UINT8(hob_nsector, IDEState),
2304 37159f13 Juan Quintela
        VMSTATE_UINT8(hob_lcyl, IDEState),
2305 37159f13 Juan Quintela
        VMSTATE_UINT8(hob_hcyl, IDEState),
2306 37159f13 Juan Quintela
        VMSTATE_UINT8(select, IDEState),
2307 37159f13 Juan Quintela
        VMSTATE_UINT8(status, IDEState),
2308 37159f13 Juan Quintela
        VMSTATE_UINT8(lba48, IDEState),
2309 37159f13 Juan Quintela
        VMSTATE_UINT8(sense_key, IDEState),
2310 37159f13 Juan Quintela
        VMSTATE_UINT8(asc, IDEState),
2311 37159f13 Juan Quintela
        VMSTATE_UINT8_V(cdrom_changed, IDEState, 3),
2312 37159f13 Juan Quintela
        VMSTATE_END_OF_LIST()
2313 50641c5c Juan Quintela
    },
2314 50641c5c Juan Quintela
    .subsections = (VMStateSubsection []) {
2315 50641c5c Juan Quintela
        {
2316 50641c5c Juan Quintela
            .vmsd = &vmstate_ide_drive_pio_state,
2317 50641c5c Juan Quintela
            .needed = ide_drive_pio_state_needed,
2318 50641c5c Juan Quintela
        }, {
2319 db118fe7 Markus Armbruster
            .vmsd = &vmstate_ide_tray_state,
2320 db118fe7 Markus Armbruster
            .needed = ide_tray_state_needed,
2321 db118fe7 Markus Armbruster
        }, {
2322 996faf1a Amit Shah
            .vmsd = &vmstate_ide_atapi_gesn_state,
2323 996faf1a Amit Shah
            .needed = ide_atapi_gesn_needed,
2324 996faf1a Amit Shah
        }, {
2325 50641c5c Juan Quintela
            /* empty */
2326 50641c5c Juan Quintela
        }
2327 37159f13 Juan Quintela
    }
2328 37159f13 Juan Quintela
};
2329 37159f13 Juan Quintela
2330 656fbeff Markus Armbruster
static const VMStateDescription vmstate_ide_error_status = {
2331 def93791 Kevin Wolf
    .name ="ide_bus/error",
2332 def93791 Kevin Wolf
    .version_id = 1,
2333 def93791 Kevin Wolf
    .minimum_version_id = 1,
2334 def93791 Kevin Wolf
    .minimum_version_id_old = 1,
2335 def93791 Kevin Wolf
    .fields = (VMStateField []) {
2336 def93791 Kevin Wolf
        VMSTATE_INT32(error_status, IDEBus),
2337 def93791 Kevin Wolf
        VMSTATE_END_OF_LIST()
2338 def93791 Kevin Wolf
    }
2339 def93791 Kevin Wolf
};
2340 def93791 Kevin Wolf
2341 6521dc62 Juan Quintela
const VMStateDescription vmstate_ide_bus = {
2342 6521dc62 Juan Quintela
    .name = "ide_bus",
2343 6521dc62 Juan Quintela
    .version_id = 1,
2344 6521dc62 Juan Quintela
    .minimum_version_id = 1,
2345 6521dc62 Juan Quintela
    .minimum_version_id_old = 1,
2346 6521dc62 Juan Quintela
    .fields      = (VMStateField []) {
2347 6521dc62 Juan Quintela
        VMSTATE_UINT8(cmd, IDEBus),
2348 6521dc62 Juan Quintela
        VMSTATE_UINT8(unit, IDEBus),
2349 6521dc62 Juan Quintela
        VMSTATE_END_OF_LIST()
2350 def93791 Kevin Wolf
    },
2351 def93791 Kevin Wolf
    .subsections = (VMStateSubsection []) {
2352 def93791 Kevin Wolf
        {
2353 def93791 Kevin Wolf
            .vmsd = &vmstate_ide_error_status,
2354 def93791 Kevin Wolf
            .needed = ide_error_needed,
2355 def93791 Kevin Wolf
        }, {
2356 def93791 Kevin Wolf
            /* empty */
2357 def93791 Kevin Wolf
        }
2358 6521dc62 Juan Quintela
    }
2359 6521dc62 Juan Quintela
};
2360 75717903 Isaku Yamahata
2361 75717903 Isaku Yamahata
void ide_drive_get(DriveInfo **hd, int max_bus)
2362 75717903 Isaku Yamahata
{
2363 75717903 Isaku Yamahata
    int i;
2364 75717903 Isaku Yamahata
2365 75717903 Isaku Yamahata
    if (drive_get_max_bus(IF_IDE) >= max_bus) {
2366 75717903 Isaku Yamahata
        fprintf(stderr, "qemu: too many IDE bus: %d\n", max_bus);
2367 75717903 Isaku Yamahata
        exit(1);
2368 75717903 Isaku Yamahata
    }
2369 75717903 Isaku Yamahata
2370 75717903 Isaku Yamahata
    for(i = 0; i < max_bus * MAX_IDE_DEVS; i++) {
2371 75717903 Isaku Yamahata
        hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
2372 75717903 Isaku Yamahata
    }
2373 75717903 Isaku Yamahata
}