Statistics
| Branch: | Revision:

root / hw / ide / core.c @ c9159fe9

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