Statistics
| Branch: | Revision:

root / hw / ide / core.c @ 5d87e4b7

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