Statistics
| Branch: | Revision:

root / hw / ide / core.c @ 69c38b8f

History | View | Annotate | Download (55.9 kB)

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