Statistics
| Branch: | Revision:

root / hw / ide / core.c @ 95b5edcd

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 40a6238a Alexander Graf
    s->bus->dma->ops->add_status(s->bus->dma, BM_STATUS_INT);
434 9cdd03a7 Gerd Hoffmann
    ide_set_irq(s->bus);
435 e162cfb0 balrog
}
436 e162cfb0 balrog
437 ce4b6522 Kevin Wolf
static int ide_handle_rw_error(IDEState *s, int error, int op)
438 428c5705 aliguori
{
439 ce4b6522 Kevin Wolf
    int is_read = (op & BM_STATUS_RETRY_READ);
440 abd7f68d Markus Armbruster
    BlockErrorAction action = bdrv_get_on_error(s->bs, is_read);
441 428c5705 aliguori
442 7ad7e3c3 Luiz Capitulino
    if (action == BLOCK_ERR_IGNORE) {
443 7ad7e3c3 Luiz Capitulino
        bdrv_mon_event(s->bs, BDRV_ACTION_IGNORE, is_read);
444 428c5705 aliguori
        return 0;
445 7ad7e3c3 Luiz Capitulino
    }
446 428c5705 aliguori
447 428c5705 aliguori
    if ((error == ENOSPC && action == BLOCK_ERR_STOP_ENOSPC)
448 428c5705 aliguori
            || action == BLOCK_ERR_STOP_ANY) {
449 40a6238a Alexander Graf
        s->bus->dma->ops->set_unit(s->bus->dma, s->unit);
450 40a6238a Alexander Graf
        s->bus->dma->ops->add_status(s->bus->dma, op);
451 7ad7e3c3 Luiz Capitulino
        bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read);
452 e07bbac5 Jan Kiszka
        vm_stop(VMSTOP_DISKFULL);
453 428c5705 aliguori
    } else {
454 ce4b6522 Kevin Wolf
        if (op & BM_STATUS_DMA_RETRY) {
455 7aea4412 aliguori
            dma_buf_commit(s, 0);
456 428c5705 aliguori
            ide_dma_error(s);
457 7aea4412 aliguori
        } else {
458 428c5705 aliguori
            ide_rw_error(s);
459 7aea4412 aliguori
        }
460 7ad7e3c3 Luiz Capitulino
        bdrv_mon_event(s->bs, BDRV_ACTION_REPORT, is_read);
461 428c5705 aliguori
    }
462 428c5705 aliguori
463 428c5705 aliguori
    return 1;
464 428c5705 aliguori
}
465 428c5705 aliguori
466 cd369c46 Christoph Hellwig
void ide_dma_cb(void *opaque, int ret)
467 98087450 bellard
{
468 40a6238a Alexander Graf
    IDEState *s = opaque;
469 8ccad811 bellard
    int n;
470 8ccad811 bellard
    int64_t sector_num;
471 8ccad811 bellard
472 c641483f Christoph Hellwig
handle_rw_error:
473 e162cfb0 balrog
    if (ret < 0) {
474 cd369c46 Christoph Hellwig
        int op = BM_STATUS_DMA_RETRY;
475 cd369c46 Christoph Hellwig
476 cd369c46 Christoph Hellwig
        if (s->is_read)
477 cd369c46 Christoph Hellwig
            op |= BM_STATUS_RETRY_READ;
478 cd369c46 Christoph Hellwig
        if (ide_handle_rw_error(s, -ret, op)) {
479 ce4b6522 Kevin Wolf
            return;
480 ce4b6522 Kevin Wolf
        }
481 e162cfb0 balrog
    }
482 e162cfb0 balrog
483 8ccad811 bellard
    n = s->io_buffer_size >> 9;
484 8ccad811 bellard
    sector_num = ide_get_sector(s);
485 8ccad811 bellard
    if (n > 0) {
486 cd369c46 Christoph Hellwig
        dma_buf_commit(s, s->is_read);
487 8ccad811 bellard
        sector_num += n;
488 8ccad811 bellard
        ide_set_sector(s, sector_num);
489 8ccad811 bellard
        s->nsector -= n;
490 8ccad811 bellard
    }
491 8ccad811 bellard
492 8ccad811 bellard
    /* end of transfer ? */
493 8ccad811 bellard
    if (s->nsector == 0) {
494 98087450 bellard
        s->status = READY_STAT | SEEK_STAT;
495 9cdd03a7 Gerd Hoffmann
        ide_set_irq(s->bus);
496 cd369c46 Christoph Hellwig
        goto eot;
497 98087450 bellard
    }
498 8ccad811 bellard
499 8ccad811 bellard
    /* launch next transfer */
500 8ccad811 bellard
    n = s->nsector;
501 596bb44d Christoph Hellwig
    s->io_buffer_index = 0;
502 8ccad811 bellard
    s->io_buffer_size = n * 512;
503 cd369c46 Christoph Hellwig
    if (s->bus->dma->ops->prepare_buf(s->bus->dma, s->is_read) == 0)
504 7aea4412 aliguori
        goto eot;
505 cd369c46 Christoph Hellwig
506 8ccad811 bellard
#ifdef DEBUG_AIO
507 cd369c46 Christoph Hellwig
    printf("ide_dma_cb: sector_num=%" PRId64 " n=%d, is_read=%d\n",
508 cd369c46 Christoph Hellwig
           sector_num, n, s->is_read);
509 8ccad811 bellard
#endif
510 cd369c46 Christoph Hellwig
511 cd369c46 Christoph Hellwig
    if (s->is_read) {
512 cd369c46 Christoph Hellwig
        s->bus->dma->aiocb = dma_bdrv_read(s->bs, &s->sg, sector_num,
513 cd369c46 Christoph Hellwig
                                           ide_dma_cb, s);
514 cd369c46 Christoph Hellwig
    } else {
515 cd369c46 Christoph Hellwig
        s->bus->dma->aiocb = dma_bdrv_write(s->bs, &s->sg, sector_num,
516 cd369c46 Christoph Hellwig
                                            ide_dma_cb, s);
517 cd369c46 Christoph Hellwig
    }
518 c641483f Christoph Hellwig
519 c641483f Christoph Hellwig
    if (!s->bus->dma->aiocb) {
520 c641483f Christoph Hellwig
        ret = -1;
521 c641483f Christoph Hellwig
        goto handle_rw_error;
522 c641483f Christoph Hellwig
    }
523 cd369c46 Christoph Hellwig
    return;
524 cd369c46 Christoph Hellwig
525 cd369c46 Christoph Hellwig
eot:
526 cd369c46 Christoph Hellwig
   s->bus->dma->ops->add_status(s->bus->dma, BM_STATUS_INT);
527 cd369c46 Christoph Hellwig
   ide_set_inactive(s);
528 98087450 bellard
}
529 98087450 bellard
530 cd369c46 Christoph Hellwig
static void ide_sector_start_dma(IDEState *s, int is_read)
531 98087450 bellard
{
532 8ccad811 bellard
    s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
533 98087450 bellard
    s->io_buffer_index = 0;
534 98087450 bellard
    s->io_buffer_size = 0;
535 cd369c46 Christoph Hellwig
    s->is_read = is_read;
536 cd369c46 Christoph Hellwig
    s->bus->dma->ops->start_dma(s->bus->dma, s, ide_dma_cb);
537 98087450 bellard
}
538 98087450 bellard
539 a09db21f bellard
static void ide_sector_write_timer_cb(void *opaque)
540 a09db21f bellard
{
541 a09db21f bellard
    IDEState *s = opaque;
542 9cdd03a7 Gerd Hoffmann
    ide_set_irq(s->bus);
543 a09db21f bellard
}
544 a09db21f bellard
545 40a6238a Alexander Graf
void ide_sector_write(IDEState *s)
546 5391d806 bellard
{
547 5391d806 bellard
    int64_t sector_num;
548 31c2a146 ths
    int ret, n, n1;
549 5391d806 bellard
550 5391d806 bellard
    s->status = READY_STAT | SEEK_STAT;
551 5391d806 bellard
    sector_num = ide_get_sector(s);
552 5391d806 bellard
#if defined(DEBUG_IDE)
553 18c5f8ea balrog
    printf("write sector=%" PRId64 "\n", sector_num);
554 5391d806 bellard
#endif
555 5391d806 bellard
    n = s->nsector;
556 5391d806 bellard
    if (n > s->req_nb_sectors)
557 5391d806 bellard
        n = s->req_nb_sectors;
558 31c2a146 ths
    ret = bdrv_write(s->bs, sector_num, s->io_buffer, n);
559 428c5705 aliguori
560 e162cfb0 balrog
    if (ret != 0) {
561 ce4b6522 Kevin Wolf
        if (ide_handle_rw_error(s, -ret, BM_STATUS_PIO_RETRY))
562 428c5705 aliguori
            return;
563 e162cfb0 balrog
    }
564 e162cfb0 balrog
565 5391d806 bellard
    s->nsector -= n;
566 5391d806 bellard
    if (s->nsector == 0) {
567 292eef5a ths
        /* no more sectors to write */
568 5391d806 bellard
        ide_transfer_stop(s);
569 5391d806 bellard
    } else {
570 5391d806 bellard
        n1 = s->nsector;
571 5391d806 bellard
        if (n1 > s->req_nb_sectors)
572 5391d806 bellard
            n1 = s->req_nb_sectors;
573 5391d806 bellard
        ide_transfer_start(s, s->io_buffer, 512 * n1, ide_sector_write);
574 5391d806 bellard
    }
575 5391d806 bellard
    ide_set_sector(s, sector_num + n);
576 3b46e624 ths
577 31c2a146 ths
    if (win2k_install_hack && ((++s->irq_count % 16) == 0)) {
578 31c2a146 ths
        /* It seems there is a bug in the Windows 2000 installer HDD
579 31c2a146 ths
           IDE driver which fills the disk with empty logs when the
580 31c2a146 ths
           IDE write IRQ comes too early. This hack tries to correct
581 31c2a146 ths
           that at the expense of slower write performances. Use this
582 31c2a146 ths
           option _only_ to install Windows 2000. You must disable it
583 31c2a146 ths
           for normal use. */
584 f7736b91 Blue Swirl
        qemu_mod_timer(s->sector_write_timer,
585 74475455 Paolo Bonzini
                       qemu_get_clock_ns(vm_clock) + (get_ticks_per_sec() / 1000));
586 f7736b91 Blue Swirl
    } else {
587 9cdd03a7 Gerd Hoffmann
        ide_set_irq(s->bus);
588 31c2a146 ths
    }
589 5391d806 bellard
}
590 5391d806 bellard
591 b0484ae4 Christoph Hellwig
static void ide_flush_cb(void *opaque, int ret)
592 b0484ae4 Christoph Hellwig
{
593 b0484ae4 Christoph Hellwig
    IDEState *s = opaque;
594 b0484ae4 Christoph Hellwig
595 e2bcadad Kevin Wolf
    if (ret < 0) {
596 e2bcadad Kevin Wolf
        /* XXX: What sector number to set here? */
597 e2bcadad Kevin Wolf
        if (ide_handle_rw_error(s, -ret, BM_STATUS_RETRY_FLUSH)) {
598 e2bcadad Kevin Wolf
            return;
599 e2bcadad Kevin Wolf
        }
600 e2bcadad Kevin Wolf
    }
601 b0484ae4 Christoph Hellwig
602 b0484ae4 Christoph Hellwig
    s->status = READY_STAT | SEEK_STAT;
603 b0484ae4 Christoph Hellwig
    ide_set_irq(s->bus);
604 b0484ae4 Christoph Hellwig
}
605 b0484ae4 Christoph Hellwig
606 40a6238a Alexander Graf
void ide_flush_cache(IDEState *s)
607 6bcb1a79 Kevin Wolf
{
608 b2df7531 Kevin Wolf
    BlockDriverAIOCB *acb;
609 b2df7531 Kevin Wolf
610 b2df7531 Kevin Wolf
    if (s->bs == NULL) {
611 6bcb1a79 Kevin Wolf
        ide_flush_cb(s, 0);
612 b2df7531 Kevin Wolf
        return;
613 b2df7531 Kevin Wolf
    }
614 b2df7531 Kevin Wolf
615 b2df7531 Kevin Wolf
    acb = bdrv_aio_flush(s->bs, ide_flush_cb, s);
616 b2df7531 Kevin Wolf
    if (acb == NULL) {
617 b2df7531 Kevin Wolf
        ide_flush_cb(s, -EIO);
618 6bcb1a79 Kevin Wolf
    }
619 6bcb1a79 Kevin Wolf
}
620 6bcb1a79 Kevin Wolf
621 201a51fc balrog
static void ide_cfata_metadata_inquiry(IDEState *s)
622 201a51fc balrog
{
623 201a51fc balrog
    uint16_t *p;
624 201a51fc balrog
    uint32_t spd;
625 201a51fc balrog
626 201a51fc balrog
    p = (uint16_t *) s->io_buffer;
627 201a51fc balrog
    memset(p, 0, 0x200);
628 201a51fc balrog
    spd = ((s->mdata_size - 1) >> 9) + 1;
629 201a51fc balrog
630 201a51fc balrog
    put_le16(p + 0, 0x0001);                        /* Data format revision */
631 201a51fc balrog
    put_le16(p + 1, 0x0000);                        /* Media property: silicon */
632 201a51fc balrog
    put_le16(p + 2, s->media_changed);                /* Media status */
633 201a51fc balrog
    put_le16(p + 3, s->mdata_size & 0xffff);        /* Capacity in bytes (low) */
634 201a51fc balrog
    put_le16(p + 4, s->mdata_size >> 16);        /* Capacity in bytes (high) */
635 201a51fc balrog
    put_le16(p + 5, spd & 0xffff);                /* Sectors per device (low) */
636 201a51fc balrog
    put_le16(p + 6, spd >> 16);                        /* Sectors per device (high) */
637 201a51fc balrog
}
638 201a51fc balrog
639 201a51fc balrog
static void ide_cfata_metadata_read(IDEState *s)
640 201a51fc balrog
{
641 201a51fc balrog
    uint16_t *p;
642 201a51fc balrog
643 201a51fc balrog
    if (((s->hcyl << 16) | s->lcyl) << 9 > s->mdata_size + 2) {
644 201a51fc balrog
        s->status = ERR_STAT;
645 201a51fc balrog
        s->error = ABRT_ERR;
646 201a51fc balrog
        return;
647 201a51fc balrog
    }
648 201a51fc balrog
649 201a51fc balrog
    p = (uint16_t *) s->io_buffer;
650 201a51fc balrog
    memset(p, 0, 0x200);
651 201a51fc balrog
652 201a51fc balrog
    put_le16(p + 0, s->media_changed);                /* Media status */
653 201a51fc balrog
    memcpy(p + 1, s->mdata_storage + (((s->hcyl << 16) | s->lcyl) << 9),
654 201a51fc balrog
                    MIN(MIN(s->mdata_size - (((s->hcyl << 16) | s->lcyl) << 9),
655 201a51fc balrog
                                    s->nsector << 9), 0x200 - 2));
656 201a51fc balrog
}
657 201a51fc balrog
658 201a51fc balrog
static void ide_cfata_metadata_write(IDEState *s)
659 201a51fc balrog
{
660 201a51fc balrog
    if (((s->hcyl << 16) | s->lcyl) << 9 > s->mdata_size + 2) {
661 201a51fc balrog
        s->status = ERR_STAT;
662 201a51fc balrog
        s->error = ABRT_ERR;
663 201a51fc balrog
        return;
664 201a51fc balrog
    }
665 201a51fc balrog
666 201a51fc balrog
    s->media_changed = 0;
667 201a51fc balrog
668 201a51fc balrog
    memcpy(s->mdata_storage + (((s->hcyl << 16) | s->lcyl) << 9),
669 201a51fc balrog
                    s->io_buffer + 2,
670 201a51fc balrog
                    MIN(MIN(s->mdata_size - (((s->hcyl << 16) | s->lcyl) << 9),
671 201a51fc balrog
                                    s->nsector << 9), 0x200 - 2));
672 201a51fc balrog
}
673 201a51fc balrog
674 bd491d6a ths
/* called when the inserted state of the media has changed */
675 db97ee6a Christoph Hellwig
static void cdrom_change_cb(void *opaque, int reason)
676 bd491d6a ths
{
677 bd491d6a ths
    IDEState *s = opaque;
678 96b8f136 ths
    uint64_t nb_sectors;
679 bd491d6a ths
680 db97ee6a Christoph Hellwig
    if (!(reason & CHANGE_MEDIA)) {
681 db97ee6a Christoph Hellwig
        return;
682 db97ee6a Christoph Hellwig
    }
683 db97ee6a Christoph Hellwig
684 bd491d6a ths
    bdrv_get_geometry(s->bs, &nb_sectors);
685 bd491d6a ths
    s->nb_sectors = nb_sectors;
686 9118e7f0 aliguori
687 4b9b7092 Amit Shah
    /*
688 4b9b7092 Amit Shah
     * First indicate to the guest that a CD has been removed.  That's
689 4b9b7092 Amit Shah
     * done on the next command the guest sends us.
690 4b9b7092 Amit Shah
     *
691 4b9b7092 Amit Shah
     * Then we set SENSE_UNIT_ATTENTION, by which the guest will
692 4b9b7092 Amit Shah
     * detect a new CD in the drive.  See ide_atapi_cmd() for details.
693 4b9b7092 Amit Shah
     */
694 93c8cfd9 Gleb Natapov
    s->cdrom_changed = 1;
695 996faf1a Amit Shah
    s->events.new_media = true;
696 9cdd03a7 Gerd Hoffmann
    ide_set_irq(s->bus);
697 bd491d6a ths
}
698 bd491d6a ths
699 c2ff060f bellard
static void ide_cmd_lba48_transform(IDEState *s, int lba48)
700 c2ff060f bellard
{
701 c2ff060f bellard
    s->lba48 = lba48;
702 c2ff060f bellard
703 c2ff060f bellard
    /* handle the 'magic' 0 nsector count conversion here. to avoid
704 c2ff060f bellard
     * fiddling with the rest of the read logic, we just store the
705 c2ff060f bellard
     * full sector count in ->nsector and ignore ->hob_nsector from now
706 c2ff060f bellard
     */
707 c2ff060f bellard
    if (!s->lba48) {
708 c2ff060f bellard
        if (!s->nsector)
709 c2ff060f bellard
            s->nsector = 256;
710 c2ff060f bellard
    } else {
711 c2ff060f bellard
        if (!s->nsector && !s->hob_nsector)
712 c2ff060f bellard
            s->nsector = 65536;
713 c2ff060f bellard
        else {
714 c2ff060f bellard
            int lo = s->nsector;
715 c2ff060f bellard
            int hi = s->hob_nsector;
716 c2ff060f bellard
717 c2ff060f bellard
            s->nsector = (hi << 8) | lo;
718 c2ff060f bellard
        }
719 c2ff060f bellard
    }
720 c2ff060f bellard
}
721 c2ff060f bellard
722 bcbdc4d3 Gerd Hoffmann
static void ide_clear_hob(IDEBus *bus)
723 c2ff060f bellard
{
724 c2ff060f bellard
    /* any write clears HOB high bit of device control register */
725 bcbdc4d3 Gerd Hoffmann
    bus->ifs[0].select &= ~(1 << 7);
726 bcbdc4d3 Gerd Hoffmann
    bus->ifs[1].select &= ~(1 << 7);
727 c2ff060f bellard
}
728 c2ff060f bellard
729 356721ae Gerd Hoffmann
void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
730 caed8802 bellard
{
731 bcbdc4d3 Gerd Hoffmann
    IDEBus *bus = opaque;
732 5391d806 bellard
733 5391d806 bellard
#ifdef DEBUG_IDE
734 5391d806 bellard
    printf("IDE: write addr=0x%x val=0x%02x\n", addr, val);
735 5391d806 bellard
#endif
736 c2ff060f bellard
737 5391d806 bellard
    addr &= 7;
738 fcdd25ab aliguori
739 fcdd25ab aliguori
    /* ignore writes to command block while busy with previous command */
740 bcbdc4d3 Gerd Hoffmann
    if (addr != 7 && (idebus_active_if(bus)->status & (BUSY_STAT|DRQ_STAT)))
741 fcdd25ab aliguori
        return;
742 fcdd25ab aliguori
743 5391d806 bellard
    switch(addr) {
744 5391d806 bellard
    case 0:
745 5391d806 bellard
        break;
746 5391d806 bellard
    case 1:
747 bcbdc4d3 Gerd Hoffmann
        ide_clear_hob(bus);
748 c45c3d00 bellard
        /* NOTE: data is written to the two drives */
749 bcbdc4d3 Gerd Hoffmann
        bus->ifs[0].hob_feature = bus->ifs[0].feature;
750 bcbdc4d3 Gerd Hoffmann
        bus->ifs[1].hob_feature = bus->ifs[1].feature;
751 bcbdc4d3 Gerd Hoffmann
        bus->ifs[0].feature = val;
752 bcbdc4d3 Gerd Hoffmann
        bus->ifs[1].feature = val;
753 5391d806 bellard
        break;
754 5391d806 bellard
    case 2:
755 bcbdc4d3 Gerd Hoffmann
        ide_clear_hob(bus);
756 bcbdc4d3 Gerd Hoffmann
        bus->ifs[0].hob_nsector = bus->ifs[0].nsector;
757 bcbdc4d3 Gerd Hoffmann
        bus->ifs[1].hob_nsector = bus->ifs[1].nsector;
758 bcbdc4d3 Gerd Hoffmann
        bus->ifs[0].nsector = val;
759 bcbdc4d3 Gerd Hoffmann
        bus->ifs[1].nsector = val;
760 5391d806 bellard
        break;
761 5391d806 bellard
    case 3:
762 bcbdc4d3 Gerd Hoffmann
        ide_clear_hob(bus);
763 bcbdc4d3 Gerd Hoffmann
        bus->ifs[0].hob_sector = bus->ifs[0].sector;
764 bcbdc4d3 Gerd Hoffmann
        bus->ifs[1].hob_sector = bus->ifs[1].sector;
765 bcbdc4d3 Gerd Hoffmann
        bus->ifs[0].sector = val;
766 bcbdc4d3 Gerd Hoffmann
        bus->ifs[1].sector = val;
767 5391d806 bellard
        break;
768 5391d806 bellard
    case 4:
769 bcbdc4d3 Gerd Hoffmann
        ide_clear_hob(bus);
770 bcbdc4d3 Gerd Hoffmann
        bus->ifs[0].hob_lcyl = bus->ifs[0].lcyl;
771 bcbdc4d3 Gerd Hoffmann
        bus->ifs[1].hob_lcyl = bus->ifs[1].lcyl;
772 bcbdc4d3 Gerd Hoffmann
        bus->ifs[0].lcyl = val;
773 bcbdc4d3 Gerd Hoffmann
        bus->ifs[1].lcyl = val;
774 5391d806 bellard
        break;
775 5391d806 bellard
    case 5:
776 bcbdc4d3 Gerd Hoffmann
        ide_clear_hob(bus);
777 bcbdc4d3 Gerd Hoffmann
        bus->ifs[0].hob_hcyl = bus->ifs[0].hcyl;
778 bcbdc4d3 Gerd Hoffmann
        bus->ifs[1].hob_hcyl = bus->ifs[1].hcyl;
779 bcbdc4d3 Gerd Hoffmann
        bus->ifs[0].hcyl = val;
780 bcbdc4d3 Gerd Hoffmann
        bus->ifs[1].hcyl = val;
781 5391d806 bellard
        break;
782 5391d806 bellard
    case 6:
783 c2ff060f bellard
        /* FIXME: HOB readback uses bit 7 */
784 bcbdc4d3 Gerd Hoffmann
        bus->ifs[0].select = (val & ~0x10) | 0xa0;
785 bcbdc4d3 Gerd Hoffmann
        bus->ifs[1].select = (val | 0x10) | 0xa0;
786 5391d806 bellard
        /* select drive */
787 bcbdc4d3 Gerd Hoffmann
        bus->unit = (val >> 4) & 1;
788 5391d806 bellard
        break;
789 5391d806 bellard
    default:
790 5391d806 bellard
    case 7:
791 5391d806 bellard
        /* command */
792 7cff87ff Alexander Graf
        ide_exec_cmd(bus, val);
793 7cff87ff Alexander Graf
        break;
794 7cff87ff Alexander Graf
    }
795 7cff87ff Alexander Graf
}
796 7cff87ff Alexander Graf
797 7cff87ff Alexander Graf
798 7cff87ff Alexander Graf
void ide_exec_cmd(IDEBus *bus, uint32_t val)
799 7cff87ff Alexander Graf
{
800 7cff87ff Alexander Graf
    IDEState *s;
801 7cff87ff Alexander Graf
    int n;
802 7cff87ff Alexander Graf
    int lba48 = 0;
803 7cff87ff Alexander Graf
804 5391d806 bellard
#if defined(DEBUG_IDE)
805 6ef2ba5e Alexander Graf
    printf("ide: CMD=%02x\n", val);
806 5391d806 bellard
#endif
807 6ef2ba5e Alexander Graf
    s = idebus_active_if(bus);
808 6ef2ba5e Alexander Graf
    /* ignore commands to non existant slave */
809 6ef2ba5e Alexander Graf
    if (s != bus->ifs && !s->bs)
810 6ef2ba5e Alexander Graf
        return;
811 c2ff060f bellard
812 6ef2ba5e Alexander Graf
    /* Only DEVICE RESET is allowed while BSY or/and DRQ are set */
813 6ef2ba5e Alexander Graf
    if ((s->status & (BUSY_STAT|DRQ_STAT)) && val != WIN_DEVICE_RESET)
814 6ef2ba5e Alexander Graf
        return;
815 fcdd25ab aliguori
816 6ef2ba5e Alexander Graf
    switch(val) {
817 6ef2ba5e Alexander Graf
    case WIN_IDENTIFY:
818 6ef2ba5e Alexander Graf
        if (s->bs && s->drive_kind != IDE_CD) {
819 6ef2ba5e Alexander Graf
            if (s->drive_kind != IDE_CFATA)
820 6ef2ba5e Alexander Graf
                ide_identify(s);
821 6ef2ba5e Alexander Graf
            else
822 6ef2ba5e Alexander Graf
                ide_cfata_identify(s);
823 769bec72 bellard
            s->status = READY_STAT | SEEK_STAT;
824 6ef2ba5e Alexander Graf
            ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
825 6ef2ba5e Alexander Graf
        } else {
826 6ef2ba5e Alexander Graf
            if (s->drive_kind == IDE_CD) {
827 6ef2ba5e Alexander Graf
                ide_set_signature(s);
828 5391d806 bellard
            }
829 6ef2ba5e Alexander Graf
            ide_abort_command(s);
830 6ef2ba5e Alexander Graf
        }
831 6ef2ba5e Alexander Graf
        ide_set_irq(s->bus);
832 6ef2ba5e Alexander Graf
        break;
833 6ef2ba5e Alexander Graf
    case WIN_SPECIFY:
834 6ef2ba5e Alexander Graf
    case WIN_RECAL:
835 6ef2ba5e Alexander Graf
        s->error = 0;
836 6ef2ba5e Alexander Graf
        s->status = READY_STAT | SEEK_STAT;
837 6ef2ba5e Alexander Graf
        ide_set_irq(s->bus);
838 6ef2ba5e Alexander Graf
        break;
839 6ef2ba5e Alexander Graf
    case WIN_SETMULT:
840 6ef2ba5e Alexander Graf
        if (s->drive_kind == IDE_CFATA && s->nsector == 0) {
841 6ef2ba5e Alexander Graf
            /* Disable Read and Write Multiple */
842 6ef2ba5e Alexander Graf
            s->mult_sectors = 0;
843 41a2b959 aliguori
            s->status = READY_STAT | SEEK_STAT;
844 6ef2ba5e Alexander Graf
        } else if ((s->nsector & 0xff) != 0 &&
845 6ef2ba5e Alexander Graf
            ((s->nsector & 0xff) > MAX_MULT_SECTORS ||
846 6ef2ba5e Alexander Graf
             (s->nsector & (s->nsector - 1)) != 0)) {
847 6ef2ba5e Alexander Graf
            ide_abort_command(s);
848 6ef2ba5e Alexander Graf
        } else {
849 6ef2ba5e Alexander Graf
            s->mult_sectors = s->nsector & 0xff;
850 6ef2ba5e Alexander Graf
            s->status = READY_STAT | SEEK_STAT;
851 6ef2ba5e Alexander Graf
        }
852 6ef2ba5e Alexander Graf
        ide_set_irq(s->bus);
853 6ef2ba5e Alexander Graf
        break;
854 6ef2ba5e Alexander Graf
    case WIN_VERIFY_EXT:
855 6ef2ba5e Alexander Graf
        lba48 = 1;
856 6ef2ba5e Alexander Graf
    case WIN_VERIFY:
857 6ef2ba5e Alexander Graf
    case WIN_VERIFY_ONCE:
858 6ef2ba5e Alexander Graf
        /* do sector number check ? */
859 6ef2ba5e Alexander Graf
        ide_cmd_lba48_transform(s, lba48);
860 6ef2ba5e Alexander Graf
        s->status = READY_STAT | SEEK_STAT;
861 6ef2ba5e Alexander Graf
        ide_set_irq(s->bus);
862 6ef2ba5e Alexander Graf
        break;
863 c2ff060f bellard
        case WIN_READ_EXT:
864 6ef2ba5e Alexander Graf
        lba48 = 1;
865 6ef2ba5e Alexander Graf
    case WIN_READ:
866 6ef2ba5e Alexander Graf
    case WIN_READ_ONCE:
867 6ef2ba5e Alexander Graf
        if (!s->bs)
868 6ef2ba5e Alexander Graf
            goto abort_cmd;
869 6ef2ba5e Alexander Graf
        ide_cmd_lba48_transform(s, lba48);
870 6ef2ba5e Alexander Graf
        s->req_nb_sectors = 1;
871 6ef2ba5e Alexander Graf
        ide_sector_read(s);
872 6ef2ba5e Alexander Graf
        break;
873 c2ff060f bellard
        case WIN_WRITE_EXT:
874 6ef2ba5e Alexander Graf
        lba48 = 1;
875 6ef2ba5e Alexander Graf
    case WIN_WRITE:
876 6ef2ba5e Alexander Graf
    case WIN_WRITE_ONCE:
877 6ef2ba5e Alexander Graf
    case CFA_WRITE_SECT_WO_ERASE:
878 6ef2ba5e Alexander Graf
    case WIN_WRITE_VERIFY:
879 6ef2ba5e Alexander Graf
        ide_cmd_lba48_transform(s, lba48);
880 6ef2ba5e Alexander Graf
        s->error = 0;
881 6ef2ba5e Alexander Graf
        s->status = SEEK_STAT | READY_STAT;
882 6ef2ba5e Alexander Graf
        s->req_nb_sectors = 1;
883 6ef2ba5e Alexander Graf
        ide_transfer_start(s, s->io_buffer, 512, ide_sector_write);
884 6ef2ba5e Alexander Graf
        s->media_changed = 1;
885 6ef2ba5e Alexander Graf
        break;
886 c2ff060f bellard
        case WIN_MULTREAD_EXT:
887 6ef2ba5e Alexander Graf
        lba48 = 1;
888 6ef2ba5e Alexander Graf
    case WIN_MULTREAD:
889 6ef2ba5e Alexander Graf
        if (!s->mult_sectors)
890 6ef2ba5e Alexander Graf
            goto abort_cmd;
891 6ef2ba5e Alexander Graf
        ide_cmd_lba48_transform(s, lba48);
892 6ef2ba5e Alexander Graf
        s->req_nb_sectors = s->mult_sectors;
893 6ef2ba5e Alexander Graf
        ide_sector_read(s);
894 6ef2ba5e Alexander Graf
        break;
895 6ef2ba5e Alexander Graf
    case WIN_MULTWRITE_EXT:
896 6ef2ba5e Alexander Graf
        lba48 = 1;
897 6ef2ba5e Alexander Graf
    case WIN_MULTWRITE:
898 6ef2ba5e Alexander Graf
    case CFA_WRITE_MULTI_WO_ERASE:
899 6ef2ba5e Alexander Graf
        if (!s->mult_sectors)
900 6ef2ba5e Alexander Graf
            goto abort_cmd;
901 6ef2ba5e Alexander Graf
        ide_cmd_lba48_transform(s, lba48);
902 6ef2ba5e Alexander Graf
        s->error = 0;
903 6ef2ba5e Alexander Graf
        s->status = SEEK_STAT | READY_STAT;
904 6ef2ba5e Alexander Graf
        s->req_nb_sectors = s->mult_sectors;
905 6ef2ba5e Alexander Graf
        n = s->nsector;
906 6ef2ba5e Alexander Graf
        if (n > s->req_nb_sectors)
907 6ef2ba5e Alexander Graf
            n = s->req_nb_sectors;
908 6ef2ba5e Alexander Graf
        ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
909 6ef2ba5e Alexander Graf
        s->media_changed = 1;
910 6ef2ba5e Alexander Graf
        break;
911 c2ff060f bellard
        case WIN_READDMA_EXT:
912 6ef2ba5e Alexander Graf
        lba48 = 1;
913 6ef2ba5e Alexander Graf
    case WIN_READDMA:
914 6ef2ba5e Alexander Graf
    case WIN_READDMA_ONCE:
915 6ef2ba5e Alexander Graf
        if (!s->bs)
916 6ef2ba5e Alexander Graf
            goto abort_cmd;
917 6ef2ba5e Alexander Graf
        ide_cmd_lba48_transform(s, lba48);
918 cd369c46 Christoph Hellwig
        ide_sector_start_dma(s, 1);
919 6ef2ba5e Alexander Graf
        break;
920 c2ff060f bellard
        case WIN_WRITEDMA_EXT:
921 6ef2ba5e Alexander Graf
        lba48 = 1;
922 6ef2ba5e Alexander Graf
    case WIN_WRITEDMA:
923 6ef2ba5e Alexander Graf
    case WIN_WRITEDMA_ONCE:
924 6ef2ba5e Alexander Graf
        if (!s->bs)
925 6ef2ba5e Alexander Graf
            goto abort_cmd;
926 6ef2ba5e Alexander Graf
        ide_cmd_lba48_transform(s, lba48);
927 cd369c46 Christoph Hellwig
        ide_sector_start_dma(s, 0);
928 6ef2ba5e Alexander Graf
        s->media_changed = 1;
929 6ef2ba5e Alexander Graf
        break;
930 6ef2ba5e Alexander Graf
    case WIN_READ_NATIVE_MAX_EXT:
931 6ef2ba5e Alexander Graf
        lba48 = 1;
932 6ef2ba5e Alexander Graf
    case WIN_READ_NATIVE_MAX:
933 6ef2ba5e Alexander Graf
        ide_cmd_lba48_transform(s, lba48);
934 6ef2ba5e Alexander Graf
        ide_set_sector(s, s->nb_sectors - 1);
935 6ef2ba5e Alexander Graf
        s->status = READY_STAT | SEEK_STAT;
936 6ef2ba5e Alexander Graf
        ide_set_irq(s->bus);
937 6ef2ba5e Alexander Graf
        break;
938 6ef2ba5e Alexander Graf
    case WIN_CHECKPOWERMODE1:
939 6ef2ba5e Alexander Graf
    case WIN_CHECKPOWERMODE2:
940 b93af93d Brian Wheeler
        s->error = 0;
941 6ef2ba5e Alexander Graf
        s->nsector = 0xff; /* device active or idle */
942 6ef2ba5e Alexander Graf
        s->status = READY_STAT | SEEK_STAT;
943 6ef2ba5e Alexander Graf
        ide_set_irq(s->bus);
944 6ef2ba5e Alexander Graf
        break;
945 6ef2ba5e Alexander Graf
    case WIN_SETFEATURES:
946 6ef2ba5e Alexander Graf
        if (!s->bs)
947 6ef2ba5e Alexander Graf
            goto abort_cmd;
948 6ef2ba5e Alexander Graf
        /* XXX: valid for CDROM ? */
949 6ef2ba5e Alexander Graf
        switch(s->feature) {
950 6ef2ba5e Alexander Graf
        case 0xcc: /* reverting to power-on defaults enable */
951 6ef2ba5e Alexander Graf
        case 0x66: /* reverting to power-on defaults disable */
952 6ef2ba5e Alexander Graf
        case 0x02: /* write cache enable */
953 6ef2ba5e Alexander Graf
        case 0x82: /* write cache disable */
954 6ef2ba5e Alexander Graf
        case 0xaa: /* read look-ahead enable */
955 6ef2ba5e Alexander Graf
        case 0x55: /* read look-ahead disable */
956 6ef2ba5e Alexander Graf
        case 0x05: /* set advanced power management mode */
957 6ef2ba5e Alexander Graf
        case 0x85: /* disable advanced power management mode */
958 6ef2ba5e Alexander Graf
        case 0x69: /* NOP */
959 6ef2ba5e Alexander Graf
        case 0x67: /* NOP */
960 6ef2ba5e Alexander Graf
        case 0x96: /* NOP */
961 6ef2ba5e Alexander Graf
        case 0x9a: /* NOP */
962 6ef2ba5e Alexander Graf
        case 0x42: /* enable Automatic Acoustic Mode */
963 6ef2ba5e Alexander Graf
        case 0xc2: /* disable Automatic Acoustic Mode */
964 41a2b959 aliguori
            s->status = READY_STAT | SEEK_STAT;
965 9cdd03a7 Gerd Hoffmann
            ide_set_irq(s->bus);
966 a136e5a8 bellard
            break;
967 6ef2ba5e Alexander Graf
        case 0x03: { /* set transfer mode */
968 94458802 bellard
                uint8_t val = s->nsector & 0x07;
969 6ef2ba5e Alexander Graf
            uint16_t *identify_data = (uint16_t *)s->identify_data;
970 94458802 bellard
971 94458802 bellard
                switch (s->nsector >> 3) {
972 6ef2ba5e Alexander Graf
                case 0x00: /* pio default */
973 6ef2ba5e Alexander Graf
                case 0x01: /* pio mode */
974 96c35ceb Juan Quintela
                        put_le16(identify_data + 62,0x07);
975 96c35ceb Juan Quintela
                        put_le16(identify_data + 63,0x07);
976 96c35ceb Juan Quintela
                        put_le16(identify_data + 88,0x3f);
977 d1b5c20d ths
                        break;
978 6ef2ba5e Alexander Graf
                case 0x02: /* sigle word dma mode*/
979 96c35ceb Juan Quintela
                        put_le16(identify_data + 62,0x07 | (1 << (val + 8)));
980 96c35ceb Juan Quintela
                        put_le16(identify_data + 63,0x07);
981 96c35ceb Juan Quintela
                        put_le16(identify_data + 88,0x3f);
982 94458802 bellard
                        break;
983 6ef2ba5e Alexander Graf
                case 0x04: /* mdma mode */
984 96c35ceb Juan Quintela
                        put_le16(identify_data + 62,0x07);
985 96c35ceb Juan Quintela
                        put_le16(identify_data + 63,0x07 | (1 << (val + 8)));
986 96c35ceb Juan Quintela
                        put_le16(identify_data + 88,0x3f);
987 94458802 bellard
                        break;
988 6ef2ba5e Alexander Graf
                case 0x08: /* udma mode */
989 96c35ceb Juan Quintela
                        put_le16(identify_data + 62,0x07);
990 96c35ceb Juan Quintela
                        put_le16(identify_data + 63,0x07);
991 96c35ceb Juan Quintela
                        put_le16(identify_data + 88,0x3f | (1 << (val + 8)));
992 94458802 bellard
                        break;
993 6ef2ba5e Alexander Graf
                default:
994 94458802 bellard
                        goto abort_cmd;
995 94458802 bellard
                }
996 4fbfcd6d aurel32
            s->status = READY_STAT | SEEK_STAT;
997 9cdd03a7 Gerd Hoffmann
            ide_set_irq(s->bus);
998 4fbfcd6d aurel32
            break;
999 6ef2ba5e Alexander Graf
        }
1000 6ef2ba5e Alexander Graf
        default:
1001 6ef2ba5e Alexander Graf
            goto abort_cmd;
1002 6ef2ba5e Alexander Graf
        }
1003 6ef2ba5e Alexander Graf
        break;
1004 6ef2ba5e Alexander Graf
    case WIN_FLUSH_CACHE:
1005 6ef2ba5e Alexander Graf
    case WIN_FLUSH_CACHE_EXT:
1006 6ef2ba5e Alexander Graf
        ide_flush_cache(s);
1007 6ef2ba5e Alexander Graf
        break;
1008 6ef2ba5e Alexander Graf
    case WIN_STANDBY:
1009 6ef2ba5e Alexander Graf
    case WIN_STANDBY2:
1010 6ef2ba5e Alexander Graf
    case WIN_STANDBYNOW1:
1011 6ef2ba5e Alexander Graf
    case WIN_STANDBYNOW2:
1012 6ef2ba5e Alexander Graf
    case WIN_IDLEIMMEDIATE:
1013 6ef2ba5e Alexander Graf
    case CFA_IDLEIMMEDIATE:
1014 6ef2ba5e Alexander Graf
    case WIN_SETIDLE1:
1015 6ef2ba5e Alexander Graf
    case WIN_SETIDLE2:
1016 6ef2ba5e Alexander Graf
    case WIN_SLEEPNOW1:
1017 6ef2ba5e Alexander Graf
    case WIN_SLEEPNOW2:
1018 6ef2ba5e Alexander Graf
        s->status = READY_STAT;
1019 6ef2ba5e Alexander Graf
        ide_set_irq(s->bus);
1020 6ef2ba5e Alexander Graf
        break;
1021 6ef2ba5e Alexander Graf
    case WIN_SEEK:
1022 6ef2ba5e Alexander Graf
        if(s->drive_kind == IDE_CD)
1023 6ef2ba5e Alexander Graf
            goto abort_cmd;
1024 6ef2ba5e Alexander Graf
        /* XXX: Check that seek is within bounds */
1025 6ef2ba5e Alexander Graf
        s->status = READY_STAT | SEEK_STAT;
1026 6ef2ba5e Alexander Graf
        ide_set_irq(s->bus);
1027 6ef2ba5e Alexander Graf
        break;
1028 6ef2ba5e Alexander Graf
        /* ATAPI commands */
1029 6ef2ba5e Alexander Graf
    case WIN_PIDENTIFY:
1030 6ef2ba5e Alexander Graf
        if (s->drive_kind == IDE_CD) {
1031 6ef2ba5e Alexander Graf
            ide_atapi_identify(s);
1032 41a2b959 aliguori
            s->status = READY_STAT | SEEK_STAT;
1033 6ef2ba5e Alexander Graf
            ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
1034 6ef2ba5e Alexander Graf
        } else {
1035 6ef2ba5e Alexander Graf
            ide_abort_command(s);
1036 6ef2ba5e Alexander Graf
        }
1037 6ef2ba5e Alexander Graf
        ide_set_irq(s->bus);
1038 6ef2ba5e Alexander Graf
        break;
1039 6ef2ba5e Alexander Graf
    case WIN_DIAGNOSE:
1040 6ef2ba5e Alexander Graf
        ide_set_signature(s);
1041 6ef2ba5e Alexander Graf
        if (s->drive_kind == IDE_CD)
1042 6ef2ba5e Alexander Graf
            s->status = 0; /* ATAPI spec (v6) section 9.10 defines packet
1043 6ef2ba5e Alexander Graf
                            * devices to return a clear status register
1044 6ef2ba5e Alexander Graf
                            * with READY_STAT *not* set. */
1045 6ef2ba5e Alexander Graf
        else
1046 41a2b959 aliguori
            s->status = READY_STAT | SEEK_STAT;
1047 6ef2ba5e Alexander Graf
        s->error = 0x01; /* Device 0 passed, Device 1 passed or not
1048 6ef2ba5e Alexander Graf
                          * present.
1049 6ef2ba5e Alexander Graf
                          */
1050 6ef2ba5e Alexander Graf
        ide_set_irq(s->bus);
1051 6ef2ba5e Alexander Graf
        break;
1052 6ef2ba5e Alexander Graf
    case WIN_SRST:
1053 6ef2ba5e Alexander Graf
        if (s->drive_kind != IDE_CD)
1054 6ef2ba5e Alexander Graf
            goto abort_cmd;
1055 6ef2ba5e Alexander Graf
        ide_set_signature(s);
1056 6ef2ba5e Alexander Graf
        s->status = 0x00; /* NOTE: READY is _not_ set */
1057 6ef2ba5e Alexander Graf
        s->error = 0x01;
1058 6ef2ba5e Alexander Graf
        break;
1059 6ef2ba5e Alexander Graf
    case WIN_PACKETCMD:
1060 6ef2ba5e Alexander Graf
        if (s->drive_kind != IDE_CD)
1061 6ef2ba5e Alexander Graf
            goto abort_cmd;
1062 6ef2ba5e Alexander Graf
        /* overlapping commands not supported */
1063 6ef2ba5e Alexander Graf
        if (s->feature & 0x02)
1064 6ef2ba5e Alexander Graf
            goto abort_cmd;
1065 6ef2ba5e Alexander Graf
        s->status = READY_STAT | SEEK_STAT;
1066 6ef2ba5e Alexander Graf
        s->atapi_dma = s->feature & 1;
1067 6ef2ba5e Alexander Graf
        s->nsector = 1;
1068 6ef2ba5e Alexander Graf
        ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE,
1069 6ef2ba5e Alexander Graf
                           ide_atapi_cmd);
1070 6ef2ba5e Alexander Graf
        break;
1071 6ef2ba5e Alexander Graf
    /* CF-ATA commands */
1072 6ef2ba5e Alexander Graf
    case CFA_REQ_EXT_ERROR_CODE:
1073 6ef2ba5e Alexander Graf
        if (s->drive_kind != IDE_CFATA)
1074 6ef2ba5e Alexander Graf
            goto abort_cmd;
1075 6ef2ba5e Alexander Graf
        s->error = 0x09;    /* miscellaneous error */
1076 6ef2ba5e Alexander Graf
        s->status = READY_STAT | SEEK_STAT;
1077 6ef2ba5e Alexander Graf
        ide_set_irq(s->bus);
1078 6ef2ba5e Alexander Graf
        break;
1079 6ef2ba5e Alexander Graf
    case CFA_ERASE_SECTORS:
1080 6ef2ba5e Alexander Graf
    case CFA_WEAR_LEVEL:
1081 6ef2ba5e Alexander Graf
        if (s->drive_kind != IDE_CFATA)
1082 6ef2ba5e Alexander Graf
            goto abort_cmd;
1083 6ef2ba5e Alexander Graf
        if (val == CFA_WEAR_LEVEL)
1084 6ef2ba5e Alexander Graf
            s->nsector = 0;
1085 6ef2ba5e Alexander Graf
        if (val == CFA_ERASE_SECTORS)
1086 6ef2ba5e Alexander Graf
            s->media_changed = 1;
1087 6ef2ba5e Alexander Graf
        s->error = 0x00;
1088 6ef2ba5e Alexander Graf
        s->status = READY_STAT | SEEK_STAT;
1089 6ef2ba5e Alexander Graf
        ide_set_irq(s->bus);
1090 6ef2ba5e Alexander Graf
        break;
1091 6ef2ba5e Alexander Graf
    case CFA_TRANSLATE_SECTOR:
1092 6ef2ba5e Alexander Graf
        if (s->drive_kind != IDE_CFATA)
1093 6ef2ba5e Alexander Graf
            goto abort_cmd;
1094 6ef2ba5e Alexander Graf
        s->error = 0x00;
1095 6ef2ba5e Alexander Graf
        s->status = READY_STAT | SEEK_STAT;
1096 6ef2ba5e Alexander Graf
        memset(s->io_buffer, 0, 0x200);
1097 6ef2ba5e Alexander Graf
        s->io_buffer[0x00] = s->hcyl;                        /* Cyl MSB */
1098 6ef2ba5e Alexander Graf
        s->io_buffer[0x01] = s->lcyl;                        /* Cyl LSB */
1099 6ef2ba5e Alexander Graf
        s->io_buffer[0x02] = s->select;                        /* Head */
1100 6ef2ba5e Alexander Graf
        s->io_buffer[0x03] = s->sector;                        /* Sector */
1101 6ef2ba5e Alexander Graf
        s->io_buffer[0x04] = ide_get_sector(s) >> 16;        /* LBA MSB */
1102 6ef2ba5e Alexander Graf
        s->io_buffer[0x05] = ide_get_sector(s) >> 8;        /* LBA */
1103 6ef2ba5e Alexander Graf
        s->io_buffer[0x06] = ide_get_sector(s) >> 0;        /* LBA LSB */
1104 6ef2ba5e Alexander Graf
        s->io_buffer[0x13] = 0x00;                                /* Erase flag */
1105 6ef2ba5e Alexander Graf
        s->io_buffer[0x18] = 0x00;                                /* Hot count */
1106 6ef2ba5e Alexander Graf
        s->io_buffer[0x19] = 0x00;                                /* Hot count */
1107 6ef2ba5e Alexander Graf
        s->io_buffer[0x1a] = 0x01;                                /* Hot count */
1108 6ef2ba5e Alexander Graf
        ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
1109 6ef2ba5e Alexander Graf
        ide_set_irq(s->bus);
1110 6ef2ba5e Alexander Graf
        break;
1111 6ef2ba5e Alexander Graf
    case CFA_ACCESS_METADATA_STORAGE:
1112 6ef2ba5e Alexander Graf
        if (s->drive_kind != IDE_CFATA)
1113 6ef2ba5e Alexander Graf
            goto abort_cmd;
1114 6ef2ba5e Alexander Graf
        switch (s->feature) {
1115 6ef2ba5e Alexander Graf
        case 0x02:        /* Inquiry Metadata Storage */
1116 6ef2ba5e Alexander Graf
            ide_cfata_metadata_inquiry(s);
1117 201a51fc balrog
            break;
1118 6ef2ba5e Alexander Graf
        case 0x03:        /* Read Metadata Storage */
1119 6ef2ba5e Alexander Graf
            ide_cfata_metadata_read(s);
1120 201a51fc balrog
            break;
1121 6ef2ba5e Alexander Graf
        case 0x04:        /* Write Metadata Storage */
1122 6ef2ba5e Alexander Graf
            ide_cfata_metadata_write(s);
1123 201a51fc balrog
            break;
1124 6ef2ba5e Alexander Graf
        default:
1125 6ef2ba5e Alexander Graf
            goto abort_cmd;
1126 6ef2ba5e Alexander Graf
        }
1127 6ef2ba5e Alexander Graf
        ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
1128 6ef2ba5e Alexander Graf
        s->status = 0x00; /* NOTE: READY is _not_ set */
1129 6ef2ba5e Alexander Graf
        ide_set_irq(s->bus);
1130 6ef2ba5e Alexander Graf
        break;
1131 6ef2ba5e Alexander Graf
    case IBM_SENSE_CONDITION:
1132 6ef2ba5e Alexander Graf
        if (s->drive_kind != IDE_CFATA)
1133 6ef2ba5e Alexander Graf
            goto abort_cmd;
1134 6ef2ba5e Alexander Graf
        switch (s->feature) {
1135 6ef2ba5e Alexander Graf
        case 0x01:  /* sense temperature in device */
1136 6ef2ba5e Alexander Graf
            s->nsector = 0x50;      /* +20 C */
1137 201a51fc balrog
            break;
1138 6ef2ba5e Alexander Graf
        default:
1139 6ef2ba5e Alexander Graf
            goto abort_cmd;
1140 6ef2ba5e Alexander Graf
        }
1141 6ef2ba5e Alexander Graf
        s->status = READY_STAT | SEEK_STAT;
1142 6ef2ba5e Alexander Graf
        ide_set_irq(s->bus);
1143 6ef2ba5e Alexander Graf
        break;
1144 e8b54394 Brian Wheeler
1145 e8b54394 Brian Wheeler
        case WIN_SMART:
1146 6ef2ba5e Alexander Graf
        if (s->drive_kind == IDE_CD)
1147 e8b54394 Brian Wheeler
                goto abort_cmd;
1148 6ef2ba5e Alexander Graf
        if (s->hcyl != 0xc2 || s->lcyl != 0x4f)
1149 e8b54394 Brian Wheeler
                goto abort_cmd;
1150 6ef2ba5e Alexander Graf
        if (!s->smart_enabled && s->feature != SMART_ENABLE)
1151 e8b54394 Brian Wheeler
                goto abort_cmd;
1152 6ef2ba5e Alexander Graf
        switch (s->feature) {
1153 6ef2ba5e Alexander Graf
        case SMART_DISABLE:
1154 e8b54394 Brian Wheeler
                s->smart_enabled = 0;
1155 e8b54394 Brian Wheeler
                s->status = READY_STAT | SEEK_STAT;
1156 9cdd03a7 Gerd Hoffmann
                ide_set_irq(s->bus);
1157 e8b54394 Brian Wheeler
                break;
1158 6ef2ba5e Alexander Graf
        case SMART_ENABLE:
1159 e8b54394 Brian Wheeler
                s->smart_enabled = 1;
1160 e8b54394 Brian Wheeler
                s->status = READY_STAT | SEEK_STAT;
1161 9cdd03a7 Gerd Hoffmann
                ide_set_irq(s->bus);
1162 e8b54394 Brian Wheeler
                break;
1163 6ef2ba5e Alexander Graf
        case SMART_ATTR_AUTOSAVE:
1164 e8b54394 Brian Wheeler
                switch (s->sector) {
1165 e8b54394 Brian Wheeler
                case 0x00:
1166 6ef2ba5e Alexander Graf
                s->smart_autosave = 0;
1167 6ef2ba5e Alexander Graf
                break;
1168 e8b54394 Brian Wheeler
                case 0xf1:
1169 6ef2ba5e Alexander Graf
                s->smart_autosave = 1;
1170 6ef2ba5e Alexander Graf
                break;
1171 e8b54394 Brian Wheeler
                default:
1172 6ef2ba5e Alexander Graf
                goto abort_cmd;
1173 e8b54394 Brian Wheeler
                }
1174 e8b54394 Brian Wheeler
                s->status = READY_STAT | SEEK_STAT;
1175 9cdd03a7 Gerd Hoffmann
                ide_set_irq(s->bus);
1176 e8b54394 Brian Wheeler
                break;
1177 6ef2ba5e Alexander Graf
        case SMART_STATUS:
1178 e8b54394 Brian Wheeler
                if (!s->smart_errors) {
1179 6ef2ba5e Alexander Graf
                s->hcyl = 0xc2;
1180 6ef2ba5e Alexander Graf
                s->lcyl = 0x4f;
1181 e8b54394 Brian Wheeler
                } else {
1182 6ef2ba5e Alexander Graf
                s->hcyl = 0x2c;
1183 6ef2ba5e Alexander Graf
                s->lcyl = 0xf4;
1184 e8b54394 Brian Wheeler
                }
1185 e8b54394 Brian Wheeler
                s->status = READY_STAT | SEEK_STAT;
1186 9cdd03a7 Gerd Hoffmann
                ide_set_irq(s->bus);
1187 e8b54394 Brian Wheeler
                break;
1188 6ef2ba5e Alexander Graf
        case SMART_READ_THRESH:
1189 e8b54394 Brian Wheeler
                memset(s->io_buffer, 0, 0x200);
1190 e8b54394 Brian Wheeler
                s->io_buffer[0] = 0x01; /* smart struct version */
1191 e8b54394 Brian Wheeler
                for (n=0; n<30; n++) {
1192 6ef2ba5e Alexander Graf
                if (smart_attributes[n][0] == 0)
1193 e8b54394 Brian Wheeler
                        break;
1194 6ef2ba5e Alexander Graf
                s->io_buffer[2+0+(n*12)] = smart_attributes[n][0];
1195 b93af93d Brian Wheeler
                s->io_buffer[2+1+(n*12)] = smart_attributes[n][11];
1196 e8b54394 Brian Wheeler
                }
1197 e8b54394 Brian Wheeler
                for (n=0; n<511; n++) /* checksum */
1198 6ef2ba5e Alexander Graf
                s->io_buffer[511] += s->io_buffer[n];
1199 e8b54394 Brian Wheeler
                s->io_buffer[511] = 0x100 - s->io_buffer[511];
1200 e8b54394 Brian Wheeler
                s->status = READY_STAT | SEEK_STAT;
1201 e8b54394 Brian Wheeler
                ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
1202 9cdd03a7 Gerd Hoffmann
                ide_set_irq(s->bus);
1203 e8b54394 Brian Wheeler
                break;
1204 6ef2ba5e Alexander Graf
        case SMART_READ_DATA:
1205 e8b54394 Brian Wheeler
                memset(s->io_buffer, 0, 0x200);
1206 e8b54394 Brian Wheeler
                s->io_buffer[0] = 0x01; /* smart struct version */
1207 e8b54394 Brian Wheeler
                for (n=0; n<30; n++) {
1208 b93af93d Brian Wheeler
                    if (smart_attributes[n][0] == 0) {
1209 e8b54394 Brian Wheeler
                        break;
1210 b93af93d Brian Wheeler
                    }
1211 b93af93d Brian Wheeler
                    int i;
1212 b93af93d Brian Wheeler
                    for(i = 0; i < 11; i++) {
1213 b93af93d Brian Wheeler
                        s->io_buffer[2+i+(n*12)] = smart_attributes[n][i];
1214 b93af93d Brian Wheeler
                    }
1215 e8b54394 Brian Wheeler
                }
1216 e8b54394 Brian Wheeler
                s->io_buffer[362] = 0x02 | (s->smart_autosave?0x80:0x00);
1217 e8b54394 Brian Wheeler
                if (s->smart_selftest_count == 0) {
1218 6ef2ba5e Alexander Graf
                s->io_buffer[363] = 0;
1219 e8b54394 Brian Wheeler
                } else {
1220 6ef2ba5e Alexander Graf
                s->io_buffer[363] =
1221 e8b54394 Brian Wheeler
                        s->smart_selftest_data[3 + 
1222 6ef2ba5e Alexander Graf
                                           (s->smart_selftest_count - 1) *
1223 6ef2ba5e Alexander Graf
                                           24];
1224 e8b54394 Brian Wheeler
                }
1225 e8b54394 Brian Wheeler
                s->io_buffer[364] = 0x20; 
1226 e8b54394 Brian Wheeler
                s->io_buffer[365] = 0x01; 
1227 e8b54394 Brian Wheeler
                /* offline data collection capacity: execute + self-test*/
1228 e8b54394 Brian Wheeler
                s->io_buffer[367] = (1<<4 | 1<<3 | 1); 
1229 e8b54394 Brian Wheeler
                s->io_buffer[368] = 0x03; /* smart capability (1) */
1230 e8b54394 Brian Wheeler
                s->io_buffer[369] = 0x00; /* smart capability (2) */
1231 e8b54394 Brian Wheeler
                s->io_buffer[370] = 0x01; /* error logging supported */
1232 e8b54394 Brian Wheeler
                s->io_buffer[372] = 0x02; /* minutes for poll short test */
1233 e8b54394 Brian Wheeler
                s->io_buffer[373] = 0x36; /* minutes for poll ext test */
1234 e8b54394 Brian Wheeler
                s->io_buffer[374] = 0x01; /* minutes for poll conveyance */
1235 e8b54394 Brian Wheeler
1236 e8b54394 Brian Wheeler
                for (n=0; n<511; n++) 
1237 6ef2ba5e Alexander Graf
                s->io_buffer[511] += s->io_buffer[n];
1238 e8b54394 Brian Wheeler
                s->io_buffer[511] = 0x100 - s->io_buffer[511];
1239 e8b54394 Brian Wheeler
                s->status = READY_STAT | SEEK_STAT;
1240 e8b54394 Brian Wheeler
                ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
1241 9cdd03a7 Gerd Hoffmann
                ide_set_irq(s->bus);
1242 e8b54394 Brian Wheeler
                break;
1243 6ef2ba5e Alexander Graf
        case SMART_READ_LOG:
1244 e8b54394 Brian Wheeler
                switch (s->sector) {
1245 e8b54394 Brian Wheeler
                case 0x01: /* summary smart error log */
1246 6ef2ba5e Alexander Graf
                memset(s->io_buffer, 0, 0x200);
1247 6ef2ba5e Alexander Graf
                s->io_buffer[0] = 0x01;
1248 6ef2ba5e Alexander Graf
                s->io_buffer[1] = 0x00; /* no error entries */
1249 6ef2ba5e Alexander Graf
                s->io_buffer[452] = s->smart_errors & 0xff;
1250 6ef2ba5e Alexander Graf
                s->io_buffer[453] = (s->smart_errors & 0xff00) >> 8;
1251 e8b54394 Brian Wheeler
1252 6ef2ba5e Alexander Graf
                for (n=0; n<511; n++)
1253 e8b54394 Brian Wheeler
                        s->io_buffer[511] += s->io_buffer[n];
1254 6ef2ba5e Alexander Graf
                s->io_buffer[511] = 0x100 - s->io_buffer[511];
1255 6ef2ba5e Alexander Graf
                break;
1256 e8b54394 Brian Wheeler
                case 0x06: /* smart self test log */
1257 6ef2ba5e Alexander Graf
                memset(s->io_buffer, 0, 0x200);
1258 6ef2ba5e Alexander Graf
                s->io_buffer[0] = 0x01;
1259 6ef2ba5e Alexander Graf
                if (s->smart_selftest_count == 0) {
1260 e8b54394 Brian Wheeler
                        s->io_buffer[508] = 0;
1261 6ef2ba5e Alexander Graf
                } else {
1262 e8b54394 Brian Wheeler
                        s->io_buffer[508] = s->smart_selftest_count;
1263 e8b54394 Brian Wheeler
                        for (n=2; n<506; n++) 
1264 6ef2ba5e Alexander Graf
                        s->io_buffer[n] = s->smart_selftest_data[n];
1265 6ef2ba5e Alexander Graf
                }
1266 6ef2ba5e Alexander Graf
                for (n=0; n<511; n++)
1267 e8b54394 Brian Wheeler
                        s->io_buffer[511] += s->io_buffer[n];
1268 6ef2ba5e Alexander Graf
                s->io_buffer[511] = 0x100 - s->io_buffer[511];
1269 6ef2ba5e Alexander Graf
                break;
1270 e8b54394 Brian Wheeler
                default:
1271 6ef2ba5e Alexander Graf
                goto abort_cmd;
1272 e8b54394 Brian Wheeler
                }
1273 e8b54394 Brian Wheeler
                s->status = READY_STAT | SEEK_STAT;
1274 e8b54394 Brian Wheeler
                ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
1275 9cdd03a7 Gerd Hoffmann
                ide_set_irq(s->bus);
1276 e8b54394 Brian Wheeler
                break;
1277 6ef2ba5e Alexander Graf
        case SMART_EXECUTE_OFFLINE:
1278 e8b54394 Brian Wheeler
                switch (s->sector) {
1279 e8b54394 Brian Wheeler
                case 0: /* off-line routine */
1280 e8b54394 Brian Wheeler
                case 1: /* short self test */
1281 e8b54394 Brian Wheeler
                case 2: /* extended self test */
1282 6ef2ba5e Alexander Graf
                s->smart_selftest_count++;
1283 6ef2ba5e Alexander Graf
                if(s->smart_selftest_count > 21)
1284 e8b54394 Brian Wheeler
                        s->smart_selftest_count = 0;
1285 6ef2ba5e Alexander Graf
                n = 2 + (s->smart_selftest_count - 1) * 24;
1286 6ef2ba5e Alexander Graf
                s->smart_selftest_data[n] = s->sector;
1287 6ef2ba5e Alexander Graf
                s->smart_selftest_data[n+1] = 0x00; /* OK and finished */
1288 6ef2ba5e Alexander Graf
                s->smart_selftest_data[n+2] = 0x34; /* hour count lsb */
1289 6ef2ba5e Alexander Graf
                s->smart_selftest_data[n+3] = 0x12; /* hour count msb */
1290 6ef2ba5e Alexander Graf
                s->status = READY_STAT | SEEK_STAT;
1291 6ef2ba5e Alexander Graf
                ide_set_irq(s->bus);
1292 6ef2ba5e Alexander Graf
                break;
1293 e8b54394 Brian Wheeler
                default:
1294 6ef2ba5e Alexander Graf
                goto abort_cmd;
1295 e8b54394 Brian Wheeler
                }
1296 e8b54394 Brian Wheeler
                break;
1297 6ef2ba5e Alexander Graf
        default:
1298 e8b54394 Brian Wheeler
                goto abort_cmd;
1299 6ef2ba5e Alexander Graf
        }
1300 6ef2ba5e Alexander Graf
        break;
1301 6ef2ba5e Alexander Graf
    default:
1302 6ef2ba5e Alexander Graf
    abort_cmd:
1303 6ef2ba5e Alexander Graf
        ide_abort_command(s);
1304 6ef2ba5e Alexander Graf
        ide_set_irq(s->bus);
1305 6ef2ba5e Alexander Graf
        break;
1306 6ef2ba5e Alexander Graf
    }
1307 5391d806 bellard
}
1308 5391d806 bellard
1309 356721ae Gerd Hoffmann
uint32_t ide_ioport_read(void *opaque, uint32_t addr1)
1310 5391d806 bellard
{
1311 bcbdc4d3 Gerd Hoffmann
    IDEBus *bus = opaque;
1312 bcbdc4d3 Gerd Hoffmann
    IDEState *s = idebus_active_if(bus);
1313 5391d806 bellard
    uint32_t addr;
1314 c2ff060f bellard
    int ret, hob;
1315 5391d806 bellard
1316 5391d806 bellard
    addr = addr1 & 7;
1317 c2ff060f bellard
    /* FIXME: HOB readback uses bit 7, but it's always set right now */
1318 c2ff060f bellard
    //hob = s->select & (1 << 7);
1319 c2ff060f bellard
    hob = 0;
1320 5391d806 bellard
    switch(addr) {
1321 5391d806 bellard
    case 0:
1322 5391d806 bellard
        ret = 0xff;
1323 5391d806 bellard
        break;
1324 5391d806 bellard
    case 1:
1325 bcbdc4d3 Gerd Hoffmann
        if ((!bus->ifs[0].bs && !bus->ifs[1].bs) ||
1326 bcbdc4d3 Gerd Hoffmann
            (s != bus->ifs && !s->bs))
1327 c45c3d00 bellard
            ret = 0;
1328 c2ff060f bellard
        else if (!hob)
1329 c45c3d00 bellard
            ret = s->error;
1330 c2ff060f bellard
        else
1331 c2ff060f bellard
            ret = s->hob_feature;
1332 5391d806 bellard
        break;
1333 5391d806 bellard
    case 2:
1334 bcbdc4d3 Gerd Hoffmann
        if (!bus->ifs[0].bs && !bus->ifs[1].bs)
1335 c45c3d00 bellard
            ret = 0;
1336 c2ff060f bellard
        else if (!hob)
1337 c45c3d00 bellard
            ret = s->nsector & 0xff;
1338 c2ff060f bellard
        else
1339 c2ff060f bellard
            ret = s->hob_nsector;
1340 5391d806 bellard
        break;
1341 5391d806 bellard
    case 3:
1342 bcbdc4d3 Gerd Hoffmann
        if (!bus->ifs[0].bs && !bus->ifs[1].bs)
1343 c45c3d00 bellard
            ret = 0;
1344 c2ff060f bellard
        else if (!hob)
1345 c45c3d00 bellard
            ret = s->sector;
1346 c2ff060f bellard
        else
1347 c2ff060f bellard
            ret = s->hob_sector;
1348 5391d806 bellard
        break;
1349 5391d806 bellard
    case 4:
1350 bcbdc4d3 Gerd Hoffmann
        if (!bus->ifs[0].bs && !bus->ifs[1].bs)
1351 c45c3d00 bellard
            ret = 0;
1352 c2ff060f bellard
        else if (!hob)
1353 c45c3d00 bellard
            ret = s->lcyl;
1354 c2ff060f bellard
        else
1355 c2ff060f bellard
            ret = s->hob_lcyl;
1356 5391d806 bellard
        break;
1357 5391d806 bellard
    case 5:
1358 bcbdc4d3 Gerd Hoffmann
        if (!bus->ifs[0].bs && !bus->ifs[1].bs)
1359 c45c3d00 bellard
            ret = 0;
1360 c2ff060f bellard
        else if (!hob)
1361 c45c3d00 bellard
            ret = s->hcyl;
1362 c2ff060f bellard
        else
1363 c2ff060f bellard
            ret = s->hob_hcyl;
1364 5391d806 bellard
        break;
1365 5391d806 bellard
    case 6:
1366 bcbdc4d3 Gerd Hoffmann
        if (!bus->ifs[0].bs && !bus->ifs[1].bs)
1367 c45c3d00 bellard
            ret = 0;
1368 c45c3d00 bellard
        else
1369 7ae98627 bellard
            ret = s->select;
1370 5391d806 bellard
        break;
1371 5391d806 bellard
    default:
1372 5391d806 bellard
    case 7:
1373 bcbdc4d3 Gerd Hoffmann
        if ((!bus->ifs[0].bs && !bus->ifs[1].bs) ||
1374 bcbdc4d3 Gerd Hoffmann
            (s != bus->ifs && !s->bs))
1375 c45c3d00 bellard
            ret = 0;
1376 c45c3d00 bellard
        else
1377 c45c3d00 bellard
            ret = s->status;
1378 9cdd03a7 Gerd Hoffmann
        qemu_irq_lower(bus->irq);
1379 5391d806 bellard
        break;
1380 5391d806 bellard
    }
1381 5391d806 bellard
#ifdef DEBUG_IDE
1382 5391d806 bellard
    printf("ide: read addr=0x%x val=%02x\n", addr1, ret);
1383 5391d806 bellard
#endif
1384 5391d806 bellard
    return ret;
1385 5391d806 bellard
}
1386 5391d806 bellard
1387 356721ae Gerd Hoffmann
uint32_t ide_status_read(void *opaque, uint32_t addr)
1388 5391d806 bellard
{
1389 bcbdc4d3 Gerd Hoffmann
    IDEBus *bus = opaque;
1390 bcbdc4d3 Gerd Hoffmann
    IDEState *s = idebus_active_if(bus);
1391 5391d806 bellard
    int ret;
1392 7ae98627 bellard
1393 bcbdc4d3 Gerd Hoffmann
    if ((!bus->ifs[0].bs && !bus->ifs[1].bs) ||
1394 bcbdc4d3 Gerd Hoffmann
        (s != bus->ifs && !s->bs))
1395 7ae98627 bellard
        ret = 0;
1396 7ae98627 bellard
    else
1397 7ae98627 bellard
        ret = s->status;
1398 5391d806 bellard
#ifdef DEBUG_IDE
1399 5391d806 bellard
    printf("ide: read status addr=0x%x val=%02x\n", addr, ret);
1400 5391d806 bellard
#endif
1401 5391d806 bellard
    return ret;
1402 5391d806 bellard
}
1403 5391d806 bellard
1404 356721ae Gerd Hoffmann
void ide_cmd_write(void *opaque, uint32_t addr, uint32_t val)
1405 5391d806 bellard
{
1406 bcbdc4d3 Gerd Hoffmann
    IDEBus *bus = opaque;
1407 5391d806 bellard
    IDEState *s;
1408 5391d806 bellard
    int i;
1409 5391d806 bellard
1410 5391d806 bellard
#ifdef DEBUG_IDE
1411 5391d806 bellard
    printf("ide: write control addr=0x%x val=%02x\n", addr, val);
1412 5391d806 bellard
#endif
1413 5391d806 bellard
    /* common for both drives */
1414 9cdd03a7 Gerd Hoffmann
    if (!(bus->cmd & IDE_CMD_RESET) &&
1415 5391d806 bellard
        (val & IDE_CMD_RESET)) {
1416 5391d806 bellard
        /* reset low to high */
1417 5391d806 bellard
        for(i = 0;i < 2; i++) {
1418 bcbdc4d3 Gerd Hoffmann
            s = &bus->ifs[i];
1419 5391d806 bellard
            s->status = BUSY_STAT | SEEK_STAT;
1420 5391d806 bellard
            s->error = 0x01;
1421 5391d806 bellard
        }
1422 9cdd03a7 Gerd Hoffmann
    } else if ((bus->cmd & IDE_CMD_RESET) &&
1423 5391d806 bellard
               !(val & IDE_CMD_RESET)) {
1424 5391d806 bellard
        /* high to low */
1425 5391d806 bellard
        for(i = 0;i < 2; i++) {
1426 bcbdc4d3 Gerd Hoffmann
            s = &bus->ifs[i];
1427 cd8722bb Markus Armbruster
            if (s->drive_kind == IDE_CD)
1428 6b136f9e bellard
                s->status = 0x00; /* NOTE: READY is _not_ set */
1429 6b136f9e bellard
            else
1430 56bf1d37 bellard
                s->status = READY_STAT | SEEK_STAT;
1431 5391d806 bellard
            ide_set_signature(s);
1432 5391d806 bellard
        }
1433 5391d806 bellard
    }
1434 5391d806 bellard
1435 9cdd03a7 Gerd Hoffmann
    bus->cmd = val;
1436 5391d806 bellard
}
1437 5391d806 bellard
1438 356721ae Gerd Hoffmann
void ide_data_writew(void *opaque, uint32_t addr, uint32_t val)
1439 5391d806 bellard
{
1440 bcbdc4d3 Gerd Hoffmann
    IDEBus *bus = opaque;
1441 bcbdc4d3 Gerd Hoffmann
    IDEState *s = idebus_active_if(bus);
1442 5391d806 bellard
    uint8_t *p;
1443 5391d806 bellard
1444 fcdd25ab aliguori
    /* PIO data access allowed only when DRQ bit is set */
1445 fcdd25ab aliguori
    if (!(s->status & DRQ_STAT))
1446 fcdd25ab aliguori
        return;
1447 fcdd25ab aliguori
1448 5391d806 bellard
    p = s->data_ptr;
1449 0c4ad8dc bellard
    *(uint16_t *)p = le16_to_cpu(val);
1450 5391d806 bellard
    p += 2;
1451 5391d806 bellard
    s->data_ptr = p;
1452 5391d806 bellard
    if (p >= s->data_end)
1453 5391d806 bellard
        s->end_transfer_func(s);
1454 5391d806 bellard
}
1455 5391d806 bellard
1456 356721ae Gerd Hoffmann
uint32_t ide_data_readw(void *opaque, uint32_t addr)
1457 5391d806 bellard
{
1458 bcbdc4d3 Gerd Hoffmann
    IDEBus *bus = opaque;
1459 bcbdc4d3 Gerd Hoffmann
    IDEState *s = idebus_active_if(bus);
1460 5391d806 bellard
    uint8_t *p;
1461 5391d806 bellard
    int ret;
1462 fcdd25ab aliguori
1463 fcdd25ab aliguori
    /* PIO data access allowed only when DRQ bit is set */
1464 fcdd25ab aliguori
    if (!(s->status & DRQ_STAT))
1465 fcdd25ab aliguori
        return 0;
1466 fcdd25ab aliguori
1467 5391d806 bellard
    p = s->data_ptr;
1468 0c4ad8dc bellard
    ret = cpu_to_le16(*(uint16_t *)p);
1469 5391d806 bellard
    p += 2;
1470 5391d806 bellard
    s->data_ptr = p;
1471 5391d806 bellard
    if (p >= s->data_end)
1472 5391d806 bellard
        s->end_transfer_func(s);
1473 5391d806 bellard
    return ret;
1474 5391d806 bellard
}
1475 5391d806 bellard
1476 356721ae Gerd Hoffmann
void ide_data_writel(void *opaque, uint32_t addr, uint32_t val)
1477 5391d806 bellard
{
1478 bcbdc4d3 Gerd Hoffmann
    IDEBus *bus = opaque;
1479 bcbdc4d3 Gerd Hoffmann
    IDEState *s = idebus_active_if(bus);
1480 5391d806 bellard
    uint8_t *p;
1481 5391d806 bellard
1482 fcdd25ab aliguori
    /* PIO data access allowed only when DRQ bit is set */
1483 fcdd25ab aliguori
    if (!(s->status & DRQ_STAT))
1484 fcdd25ab aliguori
        return;
1485 fcdd25ab aliguori
1486 5391d806 bellard
    p = s->data_ptr;
1487 0c4ad8dc bellard
    *(uint32_t *)p = le32_to_cpu(val);
1488 5391d806 bellard
    p += 4;
1489 5391d806 bellard
    s->data_ptr = p;
1490 5391d806 bellard
    if (p >= s->data_end)
1491 5391d806 bellard
        s->end_transfer_func(s);
1492 5391d806 bellard
}
1493 5391d806 bellard
1494 356721ae Gerd Hoffmann
uint32_t ide_data_readl(void *opaque, uint32_t addr)
1495 5391d806 bellard
{
1496 bcbdc4d3 Gerd Hoffmann
    IDEBus *bus = opaque;
1497 bcbdc4d3 Gerd Hoffmann
    IDEState *s = idebus_active_if(bus);
1498 5391d806 bellard
    uint8_t *p;
1499 5391d806 bellard
    int ret;
1500 3b46e624 ths
1501 fcdd25ab aliguori
    /* PIO data access allowed only when DRQ bit is set */
1502 fcdd25ab aliguori
    if (!(s->status & DRQ_STAT))
1503 fcdd25ab aliguori
        return 0;
1504 fcdd25ab aliguori
1505 5391d806 bellard
    p = s->data_ptr;
1506 0c4ad8dc bellard
    ret = cpu_to_le32(*(uint32_t *)p);
1507 5391d806 bellard
    p += 4;
1508 5391d806 bellard
    s->data_ptr = p;
1509 5391d806 bellard
    if (p >= s->data_end)
1510 5391d806 bellard
        s->end_transfer_func(s);
1511 5391d806 bellard
    return ret;
1512 5391d806 bellard
}
1513 5391d806 bellard
1514 a7dfe172 bellard
static void ide_dummy_transfer_stop(IDEState *s)
1515 a7dfe172 bellard
{
1516 a7dfe172 bellard
    s->data_ptr = s->io_buffer;
1517 a7dfe172 bellard
    s->data_end = s->io_buffer;
1518 a7dfe172 bellard
    s->io_buffer[0] = 0xff;
1519 a7dfe172 bellard
    s->io_buffer[1] = 0xff;
1520 a7dfe172 bellard
    s->io_buffer[2] = 0xff;
1521 a7dfe172 bellard
    s->io_buffer[3] = 0xff;
1522 a7dfe172 bellard
}
1523 a7dfe172 bellard
1524 4a643563 Blue Swirl
static void ide_reset(IDEState *s)
1525 5391d806 bellard
{
1526 4a643563 Blue Swirl
#ifdef DEBUG_IDE
1527 4a643563 Blue Swirl
    printf("ide: reset\n");
1528 4a643563 Blue Swirl
#endif
1529 cd8722bb Markus Armbruster
    if (s->drive_kind == IDE_CFATA)
1530 201a51fc balrog
        s->mult_sectors = 0;
1531 201a51fc balrog
    else
1532 201a51fc balrog
        s->mult_sectors = MAX_MULT_SECTORS;
1533 4a643563 Blue Swirl
    /* ide regs */
1534 4a643563 Blue Swirl
    s->feature = 0;
1535 4a643563 Blue Swirl
    s->error = 0;
1536 4a643563 Blue Swirl
    s->nsector = 0;
1537 4a643563 Blue Swirl
    s->sector = 0;
1538 4a643563 Blue Swirl
    s->lcyl = 0;
1539 4a643563 Blue Swirl
    s->hcyl = 0;
1540 4a643563 Blue Swirl
1541 4a643563 Blue Swirl
    /* lba48 */
1542 4a643563 Blue Swirl
    s->hob_feature = 0;
1543 4a643563 Blue Swirl
    s->hob_sector = 0;
1544 4a643563 Blue Swirl
    s->hob_nsector = 0;
1545 4a643563 Blue Swirl
    s->hob_lcyl = 0;
1546 4a643563 Blue Swirl
    s->hob_hcyl = 0;
1547 4a643563 Blue Swirl
1548 5391d806 bellard
    s->select = 0xa0;
1549 41a2b959 aliguori
    s->status = READY_STAT | SEEK_STAT;
1550 4a643563 Blue Swirl
1551 4a643563 Blue Swirl
    s->lba48 = 0;
1552 4a643563 Blue Swirl
1553 4a643563 Blue Swirl
    /* ATAPI specific */
1554 4a643563 Blue Swirl
    s->sense_key = 0;
1555 4a643563 Blue Swirl
    s->asc = 0;
1556 4a643563 Blue Swirl
    s->cdrom_changed = 0;
1557 4a643563 Blue Swirl
    s->packet_transfer_size = 0;
1558 4a643563 Blue Swirl
    s->elementary_transfer_size = 0;
1559 4a643563 Blue Swirl
    s->io_buffer_index = 0;
1560 4a643563 Blue Swirl
    s->cd_sector_size = 0;
1561 4a643563 Blue Swirl
    s->atapi_dma = 0;
1562 4a643563 Blue Swirl
    /* ATA DMA state */
1563 4a643563 Blue Swirl
    s->io_buffer_size = 0;
1564 4a643563 Blue Swirl
    s->req_nb_sectors = 0;
1565 4a643563 Blue Swirl
1566 5391d806 bellard
    ide_set_signature(s);
1567 a7dfe172 bellard
    /* init the transfer handler so that 0xffff is returned on data
1568 a7dfe172 bellard
       accesses */
1569 a7dfe172 bellard
    s->end_transfer_func = ide_dummy_transfer_stop;
1570 a7dfe172 bellard
    ide_dummy_transfer_stop(s);
1571 201a51fc balrog
    s->media_changed = 0;
1572 5391d806 bellard
}
1573 5391d806 bellard
1574 4a643563 Blue Swirl
void ide_bus_reset(IDEBus *bus)
1575 4a643563 Blue Swirl
{
1576 4a643563 Blue Swirl
    bus->unit = 0;
1577 4a643563 Blue Swirl
    bus->cmd = 0;
1578 4a643563 Blue Swirl
    ide_reset(&bus->ifs[0]);
1579 4a643563 Blue Swirl
    ide_reset(&bus->ifs[1]);
1580 4a643563 Blue Swirl
    ide_clear_hob(bus);
1581 40a6238a Alexander Graf
1582 40a6238a Alexander Graf
    /* pending async DMA */
1583 40a6238a Alexander Graf
    if (bus->dma->aiocb) {
1584 40a6238a Alexander Graf
#ifdef DEBUG_AIO
1585 40a6238a Alexander Graf
        printf("aio_cancel\n");
1586 40a6238a Alexander Graf
#endif
1587 40a6238a Alexander Graf
        bdrv_aio_cancel(bus->dma->aiocb);
1588 40a6238a Alexander Graf
        bus->dma->aiocb = NULL;
1589 40a6238a Alexander Graf
    }
1590 40a6238a Alexander Graf
1591 40a6238a Alexander Graf
    /* reset dma provider too */
1592 40a6238a Alexander Graf
    bus->dma->ops->reset(bus->dma);
1593 4a643563 Blue Swirl
}
1594 4a643563 Blue Swirl
1595 1f56e32a Markus Armbruster
int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
1596 c4d74df7 Markus Armbruster
                   const char *version, const char *serial)
1597 88804180 Gerd Hoffmann
{
1598 88804180 Gerd Hoffmann
    int cylinders, heads, secs;
1599 88804180 Gerd Hoffmann
    uint64_t nb_sectors;
1600 88804180 Gerd Hoffmann
1601 f8b6cc00 Markus Armbruster
    s->bs = bs;
1602 1f56e32a Markus Armbruster
    s->drive_kind = kind;
1603 1f56e32a Markus Armbruster
1604 f8b6cc00 Markus Armbruster
    bdrv_get_geometry(bs, &nb_sectors);
1605 f8b6cc00 Markus Armbruster
    bdrv_guess_geometry(bs, &cylinders, &heads, &secs);
1606 dce9e928 Markus Armbruster
    if (cylinders < 1 || cylinders > 16383) {
1607 dce9e928 Markus Armbruster
        error_report("cyls must be between 1 and 16383");
1608 dce9e928 Markus Armbruster
        return -1;
1609 dce9e928 Markus Armbruster
    }
1610 dce9e928 Markus Armbruster
    if (heads < 1 || heads > 16) {
1611 dce9e928 Markus Armbruster
        error_report("heads must be between 1 and 16");
1612 dce9e928 Markus Armbruster
        return -1;
1613 dce9e928 Markus Armbruster
    }
1614 dce9e928 Markus Armbruster
    if (secs < 1 || secs > 63) {
1615 dce9e928 Markus Armbruster
        error_report("secs must be between 1 and 63");
1616 dce9e928 Markus Armbruster
        return -1;
1617 dce9e928 Markus Armbruster
    }
1618 870111c8 Markus Armbruster
    s->cylinders = cylinders;
1619 870111c8 Markus Armbruster
    s->heads = heads;
1620 870111c8 Markus Armbruster
    s->sectors = secs;
1621 870111c8 Markus Armbruster
    s->nb_sectors = nb_sectors;
1622 870111c8 Markus Armbruster
    /* The SMART values should be preserved across power cycles
1623 870111c8 Markus Armbruster
       but they aren't.  */
1624 870111c8 Markus Armbruster
    s->smart_enabled = 1;
1625 870111c8 Markus Armbruster
    s->smart_autosave = 1;
1626 870111c8 Markus Armbruster
    s->smart_errors = 0;
1627 870111c8 Markus Armbruster
    s->smart_selftest_count = 0;
1628 1f56e32a Markus Armbruster
    if (kind == IDE_CD) {
1629 f8b6cc00 Markus Armbruster
        bdrv_set_change_cb(bs, cdrom_change_cb, s);
1630 1b2adf28 Christoph Hellwig
        bs->buffer_alignment = 2048;
1631 7aa9c811 Markus Armbruster
    } else {
1632 98f28ad7 Markus Armbruster
        if (!bdrv_is_inserted(s->bs)) {
1633 98f28ad7 Markus Armbruster
            error_report("Device needs media, but drive is empty");
1634 98f28ad7 Markus Armbruster
            return -1;
1635 98f28ad7 Markus Armbruster
        }
1636 7aa9c811 Markus Armbruster
        if (bdrv_is_read_only(bs)) {
1637 7aa9c811 Markus Armbruster
            error_report("Can't use a read-only drive");
1638 7aa9c811 Markus Armbruster
            return -1;
1639 7aa9c811 Markus Armbruster
        }
1640 88804180 Gerd Hoffmann
    }
1641 f8b6cc00 Markus Armbruster
    if (serial) {
1642 6ced55a5 Markus Armbruster
        strncpy(s->drive_serial_str, serial, sizeof(s->drive_serial_str));
1643 6ced55a5 Markus Armbruster
    } else {
1644 88804180 Gerd Hoffmann
        snprintf(s->drive_serial_str, sizeof(s->drive_serial_str),
1645 88804180 Gerd Hoffmann
                 "QM%05d", s->drive_serial);
1646 870111c8 Markus Armbruster
    }
1647 47c06340 Gerd Hoffmann
    if (version) {
1648 47c06340 Gerd Hoffmann
        pstrcpy(s->version, sizeof(s->version), version);
1649 47c06340 Gerd Hoffmann
    } else {
1650 47c06340 Gerd Hoffmann
        pstrcpy(s->version, sizeof(s->version), QEMU_VERSION);
1651 47c06340 Gerd Hoffmann
    }
1652 40a6238a Alexander Graf
1653 88804180 Gerd Hoffmann
    ide_reset(s);
1654 cd8722bb Markus Armbruster
    bdrv_set_removable(bs, s->drive_kind == IDE_CD);
1655 c4d74df7 Markus Armbruster
    return 0;
1656 88804180 Gerd Hoffmann
}
1657 88804180 Gerd Hoffmann
1658 57234ee4 Markus Armbruster
static void ide_init1(IDEBus *bus, int unit)
1659 d459da0e Markus Armbruster
{
1660 d459da0e Markus Armbruster
    static int drive_serial = 1;
1661 d459da0e Markus Armbruster
    IDEState *s = &bus->ifs[unit];
1662 d459da0e Markus Armbruster
1663 d459da0e Markus Armbruster
    s->bus = bus;
1664 d459da0e Markus Armbruster
    s->unit = unit;
1665 d459da0e Markus Armbruster
    s->drive_serial = drive_serial++;
1666 1b2adf28 Christoph Hellwig
    /* we need at least 2k alignment for accessing CDROMs using O_DIRECT */
1667 1b2adf28 Christoph Hellwig
    s->io_buffer = qemu_memalign(2048, IDE_DMA_BUF_SECTORS*512 + 4);
1668 50641c5c Juan Quintela
    s->io_buffer_total_len = IDE_DMA_BUF_SECTORS*512 + 4;
1669 d459da0e Markus Armbruster
    s->smart_selftest_data = qemu_blockalign(s->bs, 512);
1670 74475455 Paolo Bonzini
    s->sector_write_timer = qemu_new_timer_ns(vm_clock,
1671 d459da0e Markus Armbruster
                                           ide_sector_write_timer_cb, s);
1672 57234ee4 Markus Armbruster
}
1673 57234ee4 Markus Armbruster
1674 40a6238a Alexander Graf
static void ide_nop_start(IDEDMA *dma, IDEState *s,
1675 40a6238a Alexander Graf
                          BlockDriverCompletionFunc *cb)
1676 40a6238a Alexander Graf
{
1677 40a6238a Alexander Graf
}
1678 40a6238a Alexander Graf
1679 40a6238a Alexander Graf
static int ide_nop(IDEDMA *dma)
1680 40a6238a Alexander Graf
{
1681 40a6238a Alexander Graf
    return 0;
1682 40a6238a Alexander Graf
}
1683 40a6238a Alexander Graf
1684 40a6238a Alexander Graf
static int ide_nop_int(IDEDMA *dma, int x)
1685 40a6238a Alexander Graf
{
1686 40a6238a Alexander Graf
    return 0;
1687 40a6238a Alexander Graf
}
1688 40a6238a Alexander Graf
1689 40a6238a Alexander Graf
static void ide_nop_restart(void *opaque, int x, int y)
1690 40a6238a Alexander Graf
{
1691 40a6238a Alexander Graf
}
1692 40a6238a Alexander Graf
1693 40a6238a Alexander Graf
static const IDEDMAOps ide_dma_nop_ops = {
1694 40a6238a Alexander Graf
    .start_dma      = ide_nop_start,
1695 40a6238a Alexander Graf
    .start_transfer = ide_nop,
1696 40a6238a Alexander Graf
    .prepare_buf    = ide_nop_int,
1697 40a6238a Alexander Graf
    .rw_buf         = ide_nop_int,
1698 40a6238a Alexander Graf
    .set_unit       = ide_nop_int,
1699 40a6238a Alexander Graf
    .add_status     = ide_nop_int,
1700 40a6238a Alexander Graf
    .set_inactive   = ide_nop,
1701 40a6238a Alexander Graf
    .restart_cb     = ide_nop_restart,
1702 40a6238a Alexander Graf
    .reset          = ide_nop,
1703 40a6238a Alexander Graf
};
1704 40a6238a Alexander Graf
1705 40a6238a Alexander Graf
static IDEDMA ide_dma_nop = {
1706 40a6238a Alexander Graf
    .ops = &ide_dma_nop_ops,
1707 40a6238a Alexander Graf
    .aiocb = NULL,
1708 40a6238a Alexander Graf
};
1709 40a6238a Alexander Graf
1710 57234ee4 Markus Armbruster
void ide_init2(IDEBus *bus, qemu_irq irq)
1711 57234ee4 Markus Armbruster
{
1712 57234ee4 Markus Armbruster
    int i;
1713 57234ee4 Markus Armbruster
1714 57234ee4 Markus Armbruster
    for(i = 0; i < 2; i++) {
1715 57234ee4 Markus Armbruster
        ide_init1(bus, i);
1716 57234ee4 Markus Armbruster
        ide_reset(&bus->ifs[i]);
1717 870111c8 Markus Armbruster
    }
1718 57234ee4 Markus Armbruster
    bus->irq = irq;
1719 40a6238a Alexander Graf
    bus->dma = &ide_dma_nop;
1720 d459da0e Markus Armbruster
}
1721 d459da0e Markus Armbruster
1722 57234ee4 Markus Armbruster
/* TODO convert users to qdev and remove */
1723 57234ee4 Markus Armbruster
void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0,
1724 57234ee4 Markus Armbruster
                                    DriveInfo *hd1, qemu_irq irq)
1725 5391d806 bellard
{
1726 88804180 Gerd Hoffmann
    int i;
1727 57234ee4 Markus Armbruster
    DriveInfo *dinfo;
1728 5391d806 bellard
1729 caed8802 bellard
    for(i = 0; i < 2; i++) {
1730 57234ee4 Markus Armbruster
        dinfo = i == 0 ? hd0 : hd1;
1731 57234ee4 Markus Armbruster
        ide_init1(bus, i);
1732 57234ee4 Markus Armbruster
        if (dinfo) {
1733 1f56e32a Markus Armbruster
            if (ide_init_drive(&bus->ifs[i], dinfo->bdrv,
1734 95b5edcd Markus Armbruster
                               dinfo->media_cd ? IDE_CD : IDE_HD, NULL,
1735 c4d74df7 Markus Armbruster
                               *dinfo->serial ? dinfo->serial : NULL) < 0) {
1736 c4d74df7 Markus Armbruster
                error_report("Can't set up IDE drive %s", dinfo->id);
1737 c4d74df7 Markus Armbruster
                exit(1);
1738 c4d74df7 Markus Armbruster
            }
1739 57234ee4 Markus Armbruster
        } else {
1740 57234ee4 Markus Armbruster
            ide_reset(&bus->ifs[i]);
1741 57234ee4 Markus Armbruster
        }
1742 5391d806 bellard
    }
1743 9cdd03a7 Gerd Hoffmann
    bus->irq = irq;
1744 40a6238a Alexander Graf
    bus->dma = &ide_dma_nop;
1745 69b91039 bellard
}
1746 69b91039 bellard
1747 356721ae Gerd Hoffmann
void ide_init_ioport(IDEBus *bus, int iobase, int iobase2)
1748 69b91039 bellard
{
1749 bcbdc4d3 Gerd Hoffmann
    register_ioport_write(iobase, 8, 1, ide_ioport_write, bus);
1750 bcbdc4d3 Gerd Hoffmann
    register_ioport_read(iobase, 8, 1, ide_ioport_read, bus);
1751 caed8802 bellard
    if (iobase2) {
1752 bcbdc4d3 Gerd Hoffmann
        register_ioport_read(iobase2, 1, 1, ide_status_read, bus);
1753 bcbdc4d3 Gerd Hoffmann
        register_ioport_write(iobase2, 1, 1, ide_cmd_write, bus);
1754 5391d806 bellard
    }
1755 3b46e624 ths
1756 caed8802 bellard
    /* data ports */
1757 bcbdc4d3 Gerd Hoffmann
    register_ioport_write(iobase, 2, 2, ide_data_writew, bus);
1758 bcbdc4d3 Gerd Hoffmann
    register_ioport_read(iobase, 2, 2, ide_data_readw, bus);
1759 bcbdc4d3 Gerd Hoffmann
    register_ioport_write(iobase, 4, 4, ide_data_writel, bus);
1760 bcbdc4d3 Gerd Hoffmann
    register_ioport_read(iobase, 4, 4, ide_data_readl, bus);
1761 5391d806 bellard
}
1762 69b91039 bellard
1763 37159f13 Juan Quintela
static bool is_identify_set(void *opaque, int version_id)
1764 aa941b94 balrog
{
1765 37159f13 Juan Quintela
    IDEState *s = opaque;
1766 37159f13 Juan Quintela
1767 37159f13 Juan Quintela
    return s->identify_set != 0;
1768 37159f13 Juan Quintela
}
1769 37159f13 Juan Quintela
1770 50641c5c Juan Quintela
static EndTransferFunc* transfer_end_table[] = {
1771 50641c5c Juan Quintela
        ide_sector_read,
1772 50641c5c Juan Quintela
        ide_sector_write,
1773 50641c5c Juan Quintela
        ide_transfer_stop,
1774 50641c5c Juan Quintela
        ide_atapi_cmd_reply_end,
1775 50641c5c Juan Quintela
        ide_atapi_cmd,
1776 50641c5c Juan Quintela
        ide_dummy_transfer_stop,
1777 50641c5c Juan Quintela
};
1778 50641c5c Juan Quintela
1779 50641c5c Juan Quintela
static int transfer_end_table_idx(EndTransferFunc *fn)
1780 50641c5c Juan Quintela
{
1781 50641c5c Juan Quintela
    int i;
1782 50641c5c Juan Quintela
1783 50641c5c Juan Quintela
    for (i = 0; i < ARRAY_SIZE(transfer_end_table); i++)
1784 50641c5c Juan Quintela
        if (transfer_end_table[i] == fn)
1785 50641c5c Juan Quintela
            return i;
1786 50641c5c Juan Quintela
1787 50641c5c Juan Quintela
    return -1;
1788 50641c5c Juan Quintela
}
1789 50641c5c Juan Quintela
1790 37159f13 Juan Quintela
static int ide_drive_post_load(void *opaque, int version_id)
1791 aa941b94 balrog
{
1792 37159f13 Juan Quintela
    IDEState *s = opaque;
1793 37159f13 Juan Quintela
1794 37159f13 Juan Quintela
    if (version_id < 3) {
1795 93c8cfd9 Gleb Natapov
        if (s->sense_key == SENSE_UNIT_ATTENTION &&
1796 37159f13 Juan Quintela
            s->asc == ASC_MEDIUM_MAY_HAVE_CHANGED) {
1797 93c8cfd9 Gleb Natapov
            s->cdrom_changed = 1;
1798 37159f13 Juan Quintela
        }
1799 93c8cfd9 Gleb Natapov
    }
1800 37159f13 Juan Quintela
    return 0;
1801 aa941b94 balrog
}
1802 aa941b94 balrog
1803 50641c5c Juan Quintela
static int ide_drive_pio_post_load(void *opaque, int version_id)
1804 50641c5c Juan Quintela
{
1805 50641c5c Juan Quintela
    IDEState *s = opaque;
1806 50641c5c Juan Quintela
1807 7bccf573 Blue Swirl
    if (s->end_transfer_fn_idx > ARRAY_SIZE(transfer_end_table)) {
1808 50641c5c Juan Quintela
        return -EINVAL;
1809 50641c5c Juan Quintela
    }
1810 50641c5c Juan Quintela
    s->end_transfer_func = transfer_end_table[s->end_transfer_fn_idx];
1811 50641c5c Juan Quintela
    s->data_ptr = s->io_buffer + s->cur_io_buffer_offset;
1812 50641c5c Juan Quintela
    s->data_end = s->data_ptr + s->cur_io_buffer_len;
1813 50641c5c Juan Quintela
1814 50641c5c Juan Quintela
    return 0;
1815 50641c5c Juan Quintela
}
1816 50641c5c Juan Quintela
1817 50641c5c Juan Quintela
static void ide_drive_pio_pre_save(void *opaque)
1818 50641c5c Juan Quintela
{
1819 50641c5c Juan Quintela
    IDEState *s = opaque;
1820 50641c5c Juan Quintela
    int idx;
1821 50641c5c Juan Quintela
1822 50641c5c Juan Quintela
    s->cur_io_buffer_offset = s->data_ptr - s->io_buffer;
1823 50641c5c Juan Quintela
    s->cur_io_buffer_len = s->data_end - s->data_ptr;
1824 50641c5c Juan Quintela
1825 50641c5c Juan Quintela
    idx = transfer_end_table_idx(s->end_transfer_func);
1826 50641c5c Juan Quintela
    if (idx == -1) {
1827 50641c5c Juan Quintela
        fprintf(stderr, "%s: invalid end_transfer_func for DRQ_STAT\n",
1828 50641c5c Juan Quintela
                        __func__);
1829 50641c5c Juan Quintela
        s->end_transfer_fn_idx = 2;
1830 50641c5c Juan Quintela
    } else {
1831 50641c5c Juan Quintela
        s->end_transfer_fn_idx = idx;
1832 50641c5c Juan Quintela
    }
1833 50641c5c Juan Quintela
}
1834 50641c5c Juan Quintela
1835 50641c5c Juan Quintela
static bool ide_drive_pio_state_needed(void *opaque)
1836 50641c5c Juan Quintela
{
1837 50641c5c Juan Quintela
    IDEState *s = opaque;
1838 50641c5c Juan Quintela
1839 50641c5c Juan Quintela
    return (s->status & DRQ_STAT) != 0;
1840 50641c5c Juan Quintela
}
1841 50641c5c Juan Quintela
1842 996faf1a Amit Shah
static bool ide_atapi_gesn_needed(void *opaque)
1843 996faf1a Amit Shah
{
1844 996faf1a Amit Shah
    IDEState *s = opaque;
1845 996faf1a Amit Shah
1846 996faf1a Amit Shah
    return s->events.new_media || s->events.eject_request;
1847 996faf1a Amit Shah
}
1848 996faf1a Amit Shah
1849 996faf1a Amit Shah
/* Fields for GET_EVENT_STATUS_NOTIFICATION ATAPI command */
1850 996faf1a Amit Shah
const VMStateDescription vmstate_ide_atapi_gesn_state = {
1851 996faf1a Amit Shah
    .name ="ide_drive/atapi/gesn_state",
1852 996faf1a Amit Shah
    .version_id = 1,
1853 996faf1a Amit Shah
    .minimum_version_id = 1,
1854 996faf1a Amit Shah
    .minimum_version_id_old = 1,
1855 996faf1a Amit Shah
    .fields = (VMStateField []) {
1856 996faf1a Amit Shah
        VMSTATE_BOOL(events.new_media, IDEState),
1857 996faf1a Amit Shah
        VMSTATE_BOOL(events.eject_request, IDEState),
1858 996faf1a Amit Shah
    }
1859 996faf1a Amit Shah
};
1860 996faf1a Amit Shah
1861 50641c5c Juan Quintela
const VMStateDescription vmstate_ide_drive_pio_state = {
1862 50641c5c Juan Quintela
    .name = "ide_drive/pio_state",
1863 50641c5c Juan Quintela
    .version_id = 1,
1864 50641c5c Juan Quintela
    .minimum_version_id = 1,
1865 50641c5c Juan Quintela
    .minimum_version_id_old = 1,
1866 50641c5c Juan Quintela
    .pre_save = ide_drive_pio_pre_save,
1867 50641c5c Juan Quintela
    .post_load = ide_drive_pio_post_load,
1868 50641c5c Juan Quintela
    .fields      = (VMStateField []) {
1869 50641c5c Juan Quintela
        VMSTATE_INT32(req_nb_sectors, IDEState),
1870 50641c5c Juan Quintela
        VMSTATE_VARRAY_INT32(io_buffer, IDEState, io_buffer_total_len, 1,
1871 50641c5c Juan Quintela
                             vmstate_info_uint8, uint8_t),
1872 50641c5c Juan Quintela
        VMSTATE_INT32(cur_io_buffer_offset, IDEState),
1873 50641c5c Juan Quintela
        VMSTATE_INT32(cur_io_buffer_len, IDEState),
1874 50641c5c Juan Quintela
        VMSTATE_UINT8(end_transfer_fn_idx, IDEState),
1875 50641c5c Juan Quintela
        VMSTATE_INT32(elementary_transfer_size, IDEState),
1876 50641c5c Juan Quintela
        VMSTATE_INT32(packet_transfer_size, IDEState),
1877 50641c5c Juan Quintela
        VMSTATE_END_OF_LIST()
1878 50641c5c Juan Quintela
    }
1879 50641c5c Juan Quintela
};
1880 50641c5c Juan Quintela
1881 37159f13 Juan Quintela
const VMStateDescription vmstate_ide_drive = {
1882 37159f13 Juan Quintela
    .name = "ide_drive",
1883 3abb6260 Juan Quintela
    .version_id = 3,
1884 37159f13 Juan Quintela
    .minimum_version_id = 0,
1885 37159f13 Juan Quintela
    .minimum_version_id_old = 0,
1886 37159f13 Juan Quintela
    .post_load = ide_drive_post_load,
1887 37159f13 Juan Quintela
    .fields      = (VMStateField []) {
1888 37159f13 Juan Quintela
        VMSTATE_INT32(mult_sectors, IDEState),
1889 37159f13 Juan Quintela
        VMSTATE_INT32(identify_set, IDEState),
1890 37159f13 Juan Quintela
        VMSTATE_BUFFER_TEST(identify_data, IDEState, is_identify_set),
1891 37159f13 Juan Quintela
        VMSTATE_UINT8(feature, IDEState),
1892 37159f13 Juan Quintela
        VMSTATE_UINT8(error, IDEState),
1893 37159f13 Juan Quintela
        VMSTATE_UINT32(nsector, IDEState),
1894 37159f13 Juan Quintela
        VMSTATE_UINT8(sector, IDEState),
1895 37159f13 Juan Quintela
        VMSTATE_UINT8(lcyl, IDEState),
1896 37159f13 Juan Quintela
        VMSTATE_UINT8(hcyl, IDEState),
1897 37159f13 Juan Quintela
        VMSTATE_UINT8(hob_feature, IDEState),
1898 37159f13 Juan Quintela
        VMSTATE_UINT8(hob_sector, IDEState),
1899 37159f13 Juan Quintela
        VMSTATE_UINT8(hob_nsector, IDEState),
1900 37159f13 Juan Quintela
        VMSTATE_UINT8(hob_lcyl, IDEState),
1901 37159f13 Juan Quintela
        VMSTATE_UINT8(hob_hcyl, IDEState),
1902 37159f13 Juan Quintela
        VMSTATE_UINT8(select, IDEState),
1903 37159f13 Juan Quintela
        VMSTATE_UINT8(status, IDEState),
1904 37159f13 Juan Quintela
        VMSTATE_UINT8(lba48, IDEState),
1905 37159f13 Juan Quintela
        VMSTATE_UINT8(sense_key, IDEState),
1906 37159f13 Juan Quintela
        VMSTATE_UINT8(asc, IDEState),
1907 37159f13 Juan Quintela
        VMSTATE_UINT8_V(cdrom_changed, IDEState, 3),
1908 37159f13 Juan Quintela
        VMSTATE_END_OF_LIST()
1909 50641c5c Juan Quintela
    },
1910 50641c5c Juan Quintela
    .subsections = (VMStateSubsection []) {
1911 50641c5c Juan Quintela
        {
1912 50641c5c Juan Quintela
            .vmsd = &vmstate_ide_drive_pio_state,
1913 50641c5c Juan Quintela
            .needed = ide_drive_pio_state_needed,
1914 50641c5c Juan Quintela
        }, {
1915 996faf1a Amit Shah
            .vmsd = &vmstate_ide_atapi_gesn_state,
1916 996faf1a Amit Shah
            .needed = ide_atapi_gesn_needed,
1917 996faf1a Amit Shah
        }, {
1918 50641c5c Juan Quintela
            /* empty */
1919 50641c5c Juan Quintela
        }
1920 37159f13 Juan Quintela
    }
1921 37159f13 Juan Quintela
};
1922 37159f13 Juan Quintela
1923 6521dc62 Juan Quintela
const VMStateDescription vmstate_ide_bus = {
1924 6521dc62 Juan Quintela
    .name = "ide_bus",
1925 6521dc62 Juan Quintela
    .version_id = 1,
1926 6521dc62 Juan Quintela
    .minimum_version_id = 1,
1927 6521dc62 Juan Quintela
    .minimum_version_id_old = 1,
1928 6521dc62 Juan Quintela
    .fields      = (VMStateField []) {
1929 6521dc62 Juan Quintela
        VMSTATE_UINT8(cmd, IDEBus),
1930 6521dc62 Juan Quintela
        VMSTATE_UINT8(unit, IDEBus),
1931 6521dc62 Juan Quintela
        VMSTATE_END_OF_LIST()
1932 6521dc62 Juan Quintela
    }
1933 6521dc62 Juan Quintela
};
1934 75717903 Isaku Yamahata
1935 75717903 Isaku Yamahata
void ide_drive_get(DriveInfo **hd, int max_bus)
1936 75717903 Isaku Yamahata
{
1937 75717903 Isaku Yamahata
    int i;
1938 75717903 Isaku Yamahata
1939 75717903 Isaku Yamahata
    if (drive_get_max_bus(IF_IDE) >= max_bus) {
1940 75717903 Isaku Yamahata
        fprintf(stderr, "qemu: too many IDE bus: %d\n", max_bus);
1941 75717903 Isaku Yamahata
        exit(1);
1942 75717903 Isaku Yamahata
    }
1943 75717903 Isaku Yamahata
1944 75717903 Isaku Yamahata
    for(i = 0; i < max_bus * MAX_IDE_DEVS; i++) {
1945 75717903 Isaku Yamahata
        hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
1946 75717903 Isaku Yamahata
    }
1947 75717903 Isaku Yamahata
}