Statistics
| Branch: | Revision:

root / hw / ide / core.c @ 2507c12a

History | View | Annotate | Download (89.8 kB)

1 5391d806 bellard
/*
2 38cdea7c balrog
 * QEMU IDE disk and CD/DVD-ROM Emulator
3 5fafdf24 ths
 *
4 5391d806 bellard
 * Copyright (c) 2003 Fabrice Bellard
5 201a51fc balrog
 * Copyright (c) 2006 Openedhand Ltd.
6 5fafdf24 ths
 *
7 5391d806 bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 5391d806 bellard
 * of this software and associated documentation files (the "Software"), to deal
9 5391d806 bellard
 * in the Software without restriction, including without limitation the rights
10 5391d806 bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 5391d806 bellard
 * copies of the Software, and to permit persons to whom the Software is
12 5391d806 bellard
 * furnished to do so, subject to the following conditions:
13 5391d806 bellard
 *
14 5391d806 bellard
 * The above copyright notice and this permission notice shall be included in
15 5391d806 bellard
 * all copies or substantial portions of the Software.
16 5391d806 bellard
 *
17 5391d806 bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 5391d806 bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 5391d806 bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 5391d806 bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 5391d806 bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 5391d806 bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 5391d806 bellard
 * THE SOFTWARE.
24 5391d806 bellard
 */
25 59f2a787 Gerd Hoffmann
#include <hw/hw.h>
26 59f2a787 Gerd Hoffmann
#include <hw/pc.h>
27 59f2a787 Gerd Hoffmann
#include <hw/pci.h>
28 43b443b6 Gerd Hoffmann
#include <hw/scsi.h>
29 c4d74df7 Markus Armbruster
#include "qemu-error.h"
30 87ecb68b pbrook
#include "qemu-timer.h"
31 87ecb68b pbrook
#include "sysemu.h"
32 1fb8648d aliguori
#include "dma.h"
33 2446333c Blue Swirl
#include "blockdev.h"
34 59f2a787 Gerd Hoffmann
35 59f2a787 Gerd Hoffmann
#include <hw/ide/internal.h>
36 e8b54394 Brian Wheeler
37 6450a334 Blue Swirl
#define IDE_PAGE_SIZE 4096
38 6450a334 Blue Swirl
39 117e1e82 Blue Swirl
static const int smart_attributes[][5] = {
40 e8b54394 Brian Wheeler
    /* id,  flags, val, wrst, thrsh */
41 e8b54394 Brian Wheeler
    { 0x01, 0x03, 0x64, 0x64, 0x06}, /* raw read */
42 e8b54394 Brian Wheeler
    { 0x03, 0x03, 0x64, 0x64, 0x46}, /* spin up */
43 e8b54394 Brian Wheeler
    { 0x04, 0x02, 0x64, 0x64, 0x14}, /* start stop count */
44 e8b54394 Brian Wheeler
    { 0x05, 0x03, 0x64, 0x64, 0x36}, /* remapped sectors */
45 e8b54394 Brian Wheeler
    { 0x00, 0x00, 0x00, 0x00, 0x00}
46 e8b54394 Brian Wheeler
};
47 e8b54394 Brian Wheeler
48 8114e9e8 ths
/* XXX: DVDs that could fit on a CD will be reported as a CD */
49 8114e9e8 ths
static inline int media_present(IDEState *s)
50 8114e9e8 ths
{
51 8114e9e8 ths
    return (s->nb_sectors > 0);
52 8114e9e8 ths
}
53 8114e9e8 ths
54 8114e9e8 ths
static inline int media_is_dvd(IDEState *s)
55 8114e9e8 ths
{
56 8114e9e8 ths
    return (media_present(s) && s->nb_sectors > CD_MAX_SECTORS);
57 8114e9e8 ths
}
58 8114e9e8 ths
59 8114e9e8 ths
static inline int media_is_cd(IDEState *s)
60 8114e9e8 ths
{
61 8114e9e8 ths
    return (media_present(s) && s->nb_sectors <= CD_MAX_SECTORS);
62 8114e9e8 ths
}
63 8114e9e8 ths
64 8ccad811 bellard
static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb);
65 ce4b6522 Kevin Wolf
static void ide_dma_restart(IDEState *s, int is_read);
66 5f12ab4b ths
static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret);
67 ce4b6522 Kevin Wolf
static int ide_handle_rw_error(IDEState *s, int error, int op);
68 e2bcadad Kevin Wolf
static void ide_flush_cache(IDEState *s);
69 98087450 bellard
70 5391d806 bellard
static void padstr(char *str, const char *src, int len)
71 5391d806 bellard
{
72 5391d806 bellard
    int i, v;
73 5391d806 bellard
    for(i = 0; i < len; i++) {
74 5391d806 bellard
        if (*src)
75 5391d806 bellard
            v = *src++;
76 5391d806 bellard
        else
77 5391d806 bellard
            v = ' ';
78 69b34976 ths
        str[i^1] = v;
79 5391d806 bellard
    }
80 5391d806 bellard
}
81 5391d806 bellard
82 bd0d90b2 bellard
static void padstr8(uint8_t *buf, int buf_size, const char *src)
83 bd0d90b2 bellard
{
84 bd0d90b2 bellard
    int i;
85 bd0d90b2 bellard
    for(i = 0; i < buf_size; i++) {
86 bd0d90b2 bellard
        if (*src)
87 bd0d90b2 bellard
            buf[i] = *src++;
88 bd0d90b2 bellard
        else
89 bd0d90b2 bellard
            buf[i] = ' ';
90 bd0d90b2 bellard
    }
91 bd0d90b2 bellard
}
92 bd0d90b2 bellard
93 67b915a5 bellard
static void put_le16(uint16_t *p, unsigned int v)
94 67b915a5 bellard
{
95 0c4ad8dc bellard
    *p = cpu_to_le16(v);
96 67b915a5 bellard
}
97 67b915a5 bellard
98 5391d806 bellard
static void ide_identify(IDEState *s)
99 5391d806 bellard
{
100 5391d806 bellard
    uint16_t *p;
101 5391d806 bellard
    unsigned int oldsize;
102 57dac7ef Markus Armbruster
    IDEDevice *dev;
103 5391d806 bellard
104 94458802 bellard
    if (s->identify_set) {
105 94458802 bellard
        memcpy(s->io_buffer, s->identify_data, sizeof(s->identify_data));
106 94458802 bellard
        return;
107 94458802 bellard
    }
108 94458802 bellard
109 5391d806 bellard
    memset(s->io_buffer, 0, 512);
110 5391d806 bellard
    p = (uint16_t *)s->io_buffer;
111 67b915a5 bellard
    put_le16(p + 0, 0x0040);
112 5fafdf24 ths
    put_le16(p + 1, s->cylinders);
113 67b915a5 bellard
    put_le16(p + 3, s->heads);
114 67b915a5 bellard
    put_le16(p + 4, 512 * s->sectors); /* XXX: retired, remove ? */
115 67b915a5 bellard
    put_le16(p + 5, 512); /* XXX: retired, remove ? */
116 5fafdf24 ths
    put_le16(p + 6, s->sectors);
117 fa879c64 aliguori
    padstr((char *)(p + 10), s->drive_serial_str, 20); /* serial number */
118 67b915a5 bellard
    put_le16(p + 20, 3); /* XXX: retired, remove ? */
119 67b915a5 bellard
    put_le16(p + 21, 512); /* cache size in sectors */
120 67b915a5 bellard
    put_le16(p + 22, 4); /* ecc bytes */
121 47c06340 Gerd Hoffmann
    padstr((char *)(p + 23), s->version, 8); /* firmware version */
122 60fe76f3 ths
    padstr((char *)(p + 27), "QEMU HARDDISK", 40); /* model */
123 3b46e624 ths
#if MAX_MULT_SECTORS > 1
124 67b915a5 bellard
    put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
125 5391d806 bellard
#endif
126 67b915a5 bellard
    put_le16(p + 48, 1); /* dword I/O */
127 94458802 bellard
    put_le16(p + 49, (1 << 11) | (1 << 9) | (1 << 8)); /* DMA and LBA supported */
128 67b915a5 bellard
    put_le16(p + 51, 0x200); /* PIO transfer cycle */
129 67b915a5 bellard
    put_le16(p + 52, 0x200); /* DMA transfer cycle */
130 94458802 bellard
    put_le16(p + 53, 1 | (1 << 1) | (1 << 2)); /* words 54-58,64-70,88 are valid */
131 67b915a5 bellard
    put_le16(p + 54, s->cylinders);
132 67b915a5 bellard
    put_le16(p + 55, s->heads);
133 67b915a5 bellard
    put_le16(p + 56, s->sectors);
134 5391d806 bellard
    oldsize = s->cylinders * s->heads * s->sectors;
135 67b915a5 bellard
    put_le16(p + 57, oldsize);
136 67b915a5 bellard
    put_le16(p + 58, oldsize >> 16);
137 5391d806 bellard
    if (s->mult_sectors)
138 67b915a5 bellard
        put_le16(p + 59, 0x100 | s->mult_sectors);
139 67b915a5 bellard
    put_le16(p + 60, s->nb_sectors);
140 67b915a5 bellard
    put_le16(p + 61, s->nb_sectors >> 16);
141 d1b5c20d ths
    put_le16(p + 62, 0x07); /* single word dma0-2 supported */
142 94458802 bellard
    put_le16(p + 63, 0x07); /* mdma0-2 supported */
143 79d1d331 Jonathan A. Kollasch
    put_le16(p + 64, 0x03); /* pio3-4 supported */
144 94458802 bellard
    put_le16(p + 65, 120);
145 94458802 bellard
    put_le16(p + 66, 120);
146 94458802 bellard
    put_le16(p + 67, 120);
147 94458802 bellard
    put_le16(p + 68, 120);
148 94458802 bellard
    put_le16(p + 80, 0xf0); /* ata3 -> ata6 supported */
149 94458802 bellard
    put_le16(p + 81, 0x16); /* conforms to ata5 */
150 a58b8d54 Christoph Hellwig
    /* 14=NOP supported, 5=WCACHE supported, 0=SMART supported */
151 a58b8d54 Christoph Hellwig
    put_le16(p + 82, (1 << 14) | (1 << 5) | 1);
152 c2ff060f bellard
    /* 13=flush_cache_ext,12=flush_cache,10=lba48 */
153 c2ff060f bellard
    put_le16(p + 83, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10));
154 e8b54394 Brian Wheeler
    /* 14=set to 1, 1=SMART self test, 0=SMART error logging */
155 e8b54394 Brian Wheeler
    put_le16(p + 84, (1 << 14) | 0);
156 e900a7b7 Christoph Hellwig
    /* 14 = NOP supported, 5=WCACHE enabled, 0=SMART feature set enabled */
157 e900a7b7 Christoph Hellwig
    if (bdrv_enable_write_cache(s->bs))
158 e900a7b7 Christoph Hellwig
         put_le16(p + 85, (1 << 14) | (1 << 5) | 1);
159 e900a7b7 Christoph Hellwig
    else
160 e900a7b7 Christoph Hellwig
         put_le16(p + 85, (1 << 14) | 1);
161 c2ff060f bellard
    /* 13=flush_cache_ext,12=flush_cache,10=lba48 */
162 c2ff060f bellard
    put_le16(p + 86, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10));
163 e8b54394 Brian Wheeler
    /* 14=set to 1, 1=smart self test, 0=smart error logging */
164 e8b54394 Brian Wheeler
    put_le16(p + 87, (1 << 14) | 0);
165 94458802 bellard
    put_le16(p + 88, 0x3f | (1 << 13)); /* udma5 set and supported */
166 94458802 bellard
    put_le16(p + 93, 1 | (1 << 14) | 0x2000);
167 c2ff060f bellard
    put_le16(p + 100, s->nb_sectors);
168 c2ff060f bellard
    put_le16(p + 101, s->nb_sectors >> 16);
169 c2ff060f bellard
    put_le16(p + 102, s->nb_sectors >> 32);
170 c2ff060f bellard
    put_le16(p + 103, s->nb_sectors >> 48);
171 57dac7ef Markus Armbruster
    dev = s->unit ? s->bus->slave : s->bus->master;
172 57dac7ef Markus Armbruster
    if (dev && dev->conf.physical_block_size)
173 57dac7ef Markus Armbruster
        put_le16(p + 106, 0x6000 | get_physical_block_exp(&dev->conf));
174 94458802 bellard
175 94458802 bellard
    memcpy(s->identify_data, p, sizeof(s->identify_data));
176 94458802 bellard
    s->identify_set = 1;
177 5391d806 bellard
}
178 5391d806 bellard
179 5391d806 bellard
static void ide_atapi_identify(IDEState *s)
180 5391d806 bellard
{
181 5391d806 bellard
    uint16_t *p;
182 5391d806 bellard
183 94458802 bellard
    if (s->identify_set) {
184 94458802 bellard
        memcpy(s->io_buffer, s->identify_data, sizeof(s->identify_data));
185 94458802 bellard
        return;
186 94458802 bellard
    }
187 94458802 bellard
188 5391d806 bellard
    memset(s->io_buffer, 0, 512);
189 5391d806 bellard
    p = (uint16_t *)s->io_buffer;
190 5391d806 bellard
    /* Removable CDROM, 50us response, 12 byte packets */
191 67b915a5 bellard
    put_le16(p + 0, (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0));
192 fa879c64 aliguori
    padstr((char *)(p + 10), s->drive_serial_str, 20); /* serial number */
193 67b915a5 bellard
    put_le16(p + 20, 3); /* buffer type */
194 67b915a5 bellard
    put_le16(p + 21, 512); /* cache size in sectors */
195 67b915a5 bellard
    put_le16(p + 22, 4); /* ecc bytes */
196 47c06340 Gerd Hoffmann
    padstr((char *)(p + 23), s->version, 8); /* firmware version */
197 38cdea7c balrog
    padstr((char *)(p + 27), "QEMU DVD-ROM", 40); /* model */
198 67b915a5 bellard
    put_le16(p + 48, 1); /* dword I/O (XXX: should not be set on CDROM) */
199 8ccad811 bellard
#ifdef USE_DMA_CDROM
200 8ccad811 bellard
    put_le16(p + 49, 1 << 9 | 1 << 8); /* DMA and LBA supported */
201 8ccad811 bellard
    put_le16(p + 53, 7); /* words 64-70, 54-58, 88 valid */
202 d1b5c20d ths
    put_le16(p + 62, 7);  /* single word dma0-2 supported */
203 8ccad811 bellard
    put_le16(p + 63, 7);  /* mdma0-2 supported */
204 8ccad811 bellard
#else
205 67b915a5 bellard
    put_le16(p + 49, 1 << 9); /* LBA supported, no DMA */
206 67b915a5 bellard
    put_le16(p + 53, 3); /* words 64-70, 54-58 valid */
207 67b915a5 bellard
    put_le16(p + 63, 0x103); /* DMA modes XXX: may be incorrect */
208 8ccad811 bellard
#endif
209 79d1d331 Jonathan A. Kollasch
    put_le16(p + 64, 3); /* pio3-4 supported */
210 67b915a5 bellard
    put_le16(p + 65, 0xb4); /* minimum DMA multiword tx cycle time */
211 67b915a5 bellard
    put_le16(p + 66, 0xb4); /* recommended DMA multiword tx cycle time */
212 67b915a5 bellard
    put_le16(p + 67, 0x12c); /* minimum PIO cycle time without flow control */
213 67b915a5 bellard
    put_le16(p + 68, 0xb4); /* minimum PIO cycle time with IORDY flow control */
214 94458802 bellard
215 67b915a5 bellard
    put_le16(p + 71, 30); /* in ns */
216 67b915a5 bellard
    put_le16(p + 72, 30); /* in ns */
217 5391d806 bellard
218 67b915a5 bellard
    put_le16(p + 80, 0x1e); /* support up to ATA/ATAPI-4 */
219 8ccad811 bellard
#ifdef USE_DMA_CDROM
220 8ccad811 bellard
    put_le16(p + 88, 0x3f | (1 << 13)); /* udma5 set and supported */
221 8ccad811 bellard
#endif
222 94458802 bellard
    memcpy(s->identify_data, p, sizeof(s->identify_data));
223 94458802 bellard
    s->identify_set = 1;
224 5391d806 bellard
}
225 5391d806 bellard
226 201a51fc balrog
static void ide_cfata_identify(IDEState *s)
227 201a51fc balrog
{
228 201a51fc balrog
    uint16_t *p;
229 201a51fc balrog
    uint32_t cur_sec;
230 201a51fc balrog
231 201a51fc balrog
    p = (uint16_t *) s->identify_data;
232 201a51fc balrog
    if (s->identify_set)
233 201a51fc balrog
        goto fill_buffer;
234 201a51fc balrog
235 201a51fc balrog
    memset(p, 0, sizeof(s->identify_data));
236 201a51fc balrog
237 201a51fc balrog
    cur_sec = s->cylinders * s->heads * s->sectors;
238 201a51fc balrog
239 201a51fc balrog
    put_le16(p + 0, 0x848a);                        /* CF Storage Card signature */
240 201a51fc balrog
    put_le16(p + 1, s->cylinders);                /* Default cylinders */
241 201a51fc balrog
    put_le16(p + 3, s->heads);                        /* Default heads */
242 201a51fc balrog
    put_le16(p + 6, s->sectors);                /* Default sectors per track */
243 201a51fc balrog
    put_le16(p + 7, s->nb_sectors >> 16);        /* Sectors per card */
244 201a51fc balrog
    put_le16(p + 8, s->nb_sectors);                /* Sectors per card */
245 fa879c64 aliguori
    padstr((char *)(p + 10), s->drive_serial_str, 20); /* serial number */
246 201a51fc balrog
    put_le16(p + 22, 0x0004);                        /* ECC bytes */
247 47c06340 Gerd Hoffmann
    padstr((char *) (p + 23), s->version, 8);        /* Firmware Revision */
248 60fe76f3 ths
    padstr((char *) (p + 27), "QEMU MICRODRIVE", 40);/* Model number */
249 201a51fc balrog
#if MAX_MULT_SECTORS > 1
250 201a51fc balrog
    put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
251 201a51fc balrog
#else
252 201a51fc balrog
    put_le16(p + 47, 0x0000);
253 201a51fc balrog
#endif
254 201a51fc balrog
    put_le16(p + 49, 0x0f00);                        /* Capabilities */
255 201a51fc balrog
    put_le16(p + 51, 0x0002);                        /* PIO cycle timing mode */
256 201a51fc balrog
    put_le16(p + 52, 0x0001);                        /* DMA cycle timing mode */
257 201a51fc balrog
    put_le16(p + 53, 0x0003);                        /* Translation params valid */
258 201a51fc balrog
    put_le16(p + 54, s->cylinders);                /* Current cylinders */
259 201a51fc balrog
    put_le16(p + 55, s->heads);                        /* Current heads */
260 201a51fc balrog
    put_le16(p + 56, s->sectors);                /* Current sectors */
261 201a51fc balrog
    put_le16(p + 57, cur_sec);                        /* Current capacity */
262 201a51fc balrog
    put_le16(p + 58, cur_sec >> 16);                /* Current capacity */
263 201a51fc balrog
    if (s->mult_sectors)                        /* Multiple sector setting */
264 201a51fc balrog
        put_le16(p + 59, 0x100 | s->mult_sectors);
265 201a51fc balrog
    put_le16(p + 60, s->nb_sectors);                /* Total LBA sectors */
266 201a51fc balrog
    put_le16(p + 61, s->nb_sectors >> 16);        /* Total LBA sectors */
267 201a51fc balrog
    put_le16(p + 63, 0x0203);                        /* Multiword DMA capability */
268 201a51fc balrog
    put_le16(p + 64, 0x0001);                        /* Flow Control PIO support */
269 201a51fc balrog
    put_le16(p + 65, 0x0096);                        /* Min. Multiword DMA cycle */
270 201a51fc balrog
    put_le16(p + 66, 0x0096);                        /* Rec. Multiword DMA cycle */
271 201a51fc balrog
    put_le16(p + 68, 0x00b4);                        /* Min. PIO cycle time */
272 201a51fc balrog
    put_le16(p + 82, 0x400c);                        /* Command Set supported */
273 201a51fc balrog
    put_le16(p + 83, 0x7068);                        /* Command Set supported */
274 201a51fc balrog
    put_le16(p + 84, 0x4000);                        /* Features supported */
275 201a51fc balrog
    put_le16(p + 85, 0x000c);                        /* Command Set enabled */
276 201a51fc balrog
    put_le16(p + 86, 0x7044);                        /* Command Set enabled */
277 201a51fc balrog
    put_le16(p + 87, 0x4000);                        /* Features enabled */
278 201a51fc balrog
    put_le16(p + 91, 0x4060);                        /* Current APM level */
279 201a51fc balrog
    put_le16(p + 129, 0x0002);                        /* Current features option */
280 201a51fc balrog
    put_le16(p + 130, 0x0005);                        /* Reassigned sectors */
281 201a51fc balrog
    put_le16(p + 131, 0x0001);                        /* Initial power mode */
282 201a51fc balrog
    put_le16(p + 132, 0x0000);                        /* User signature */
283 201a51fc balrog
    put_le16(p + 160, 0x8100);                        /* Power requirement */
284 201a51fc balrog
    put_le16(p + 161, 0x8001);                        /* CF command set */
285 201a51fc balrog
286 201a51fc balrog
    s->identify_set = 1;
287 201a51fc balrog
288 201a51fc balrog
fill_buffer:
289 201a51fc balrog
    memcpy(s->io_buffer, p, sizeof(s->identify_data));
290 201a51fc balrog
}
291 201a51fc balrog
292 5391d806 bellard
static void ide_set_signature(IDEState *s)
293 5391d806 bellard
{
294 5391d806 bellard
    s->select &= 0xf0; /* clear head */
295 5391d806 bellard
    /* put signature */
296 5391d806 bellard
    s->nsector = 1;
297 5391d806 bellard
    s->sector = 1;
298 cd8722bb Markus Armbruster
    if (s->drive_kind == IDE_CD) {
299 5391d806 bellard
        s->lcyl = 0x14;
300 5391d806 bellard
        s->hcyl = 0xeb;
301 5391d806 bellard
    } else if (s->bs) {
302 5391d806 bellard
        s->lcyl = 0;
303 5391d806 bellard
        s->hcyl = 0;
304 5391d806 bellard
    } else {
305 5391d806 bellard
        s->lcyl = 0xff;
306 5391d806 bellard
        s->hcyl = 0xff;
307 5391d806 bellard
    }
308 5391d806 bellard
}
309 5391d806 bellard
310 5391d806 bellard
static inline void ide_abort_command(IDEState *s)
311 5391d806 bellard
{
312 5391d806 bellard
    s->status = READY_STAT | ERR_STAT;
313 5391d806 bellard
    s->error = ABRT_ERR;
314 5391d806 bellard
}
315 5391d806 bellard
316 5604e090 balrog
static inline void ide_dma_submit_check(IDEState *s,
317 5604e090 balrog
          BlockDriverCompletionFunc *dma_cb, BMDMAState *bm)
318 5604e090 balrog
{
319 5604e090 balrog
    if (bm->aiocb)
320 5604e090 balrog
        return;
321 5604e090 balrog
    dma_cb(bm, -1);
322 5604e090 balrog
}
323 5604e090 balrog
324 5391d806 bellard
/* prepare data transfer and tell what to do after */
325 5fafdf24 ths
static void ide_transfer_start(IDEState *s, uint8_t *buf, int size,
326 5391d806 bellard
                               EndTransferFunc *end_transfer_func)
327 5391d806 bellard
{
328 5391d806 bellard
    s->end_transfer_func = end_transfer_func;
329 5391d806 bellard
    s->data_ptr = buf;
330 5391d806 bellard
    s->data_end = buf + size;
331 7603d156 ths
    if (!(s->status & ERR_STAT))
332 7603d156 ths
        s->status |= DRQ_STAT;
333 5391d806 bellard
}
334 5391d806 bellard
335 5391d806 bellard
static void ide_transfer_stop(IDEState *s)
336 5391d806 bellard
{
337 5391d806 bellard
    s->end_transfer_func = ide_transfer_stop;
338 5391d806 bellard
    s->data_ptr = s->io_buffer;
339 5391d806 bellard
    s->data_end = s->io_buffer;
340 5391d806 bellard
    s->status &= ~DRQ_STAT;
341 5391d806 bellard
}
342 5391d806 bellard
343 356721ae Gerd Hoffmann
int64_t ide_get_sector(IDEState *s)
344 5391d806 bellard
{
345 5391d806 bellard
    int64_t sector_num;
346 5391d806 bellard
    if (s->select & 0x40) {
347 5391d806 bellard
        /* lba */
348 c2ff060f bellard
        if (!s->lba48) {
349 c2ff060f bellard
            sector_num = ((s->select & 0x0f) << 24) | (s->hcyl << 16) |
350 c2ff060f bellard
                (s->lcyl << 8) | s->sector;
351 c2ff060f bellard
        } else {
352 c2ff060f bellard
            sector_num = ((int64_t)s->hob_hcyl << 40) |
353 c2ff060f bellard
                ((int64_t) s->hob_lcyl << 32) |
354 c2ff060f bellard
                ((int64_t) s->hob_sector << 24) |
355 c2ff060f bellard
                ((int64_t) s->hcyl << 16) |
356 c2ff060f bellard
                ((int64_t) s->lcyl << 8) | s->sector;
357 c2ff060f bellard
        }
358 5391d806 bellard
    } else {
359 5391d806 bellard
        sector_num = ((s->hcyl << 8) | s->lcyl) * s->heads * s->sectors +
360 c2ff060f bellard
            (s->select & 0x0f) * s->sectors + (s->sector - 1);
361 5391d806 bellard
    }
362 5391d806 bellard
    return sector_num;
363 5391d806 bellard
}
364 5391d806 bellard
365 356721ae Gerd Hoffmann
void ide_set_sector(IDEState *s, int64_t sector_num)
366 5391d806 bellard
{
367 5391d806 bellard
    unsigned int cyl, r;
368 5391d806 bellard
    if (s->select & 0x40) {
369 c2ff060f bellard
        if (!s->lba48) {
370 c2ff060f bellard
            s->select = (s->select & 0xf0) | (sector_num >> 24);
371 c2ff060f bellard
            s->hcyl = (sector_num >> 16);
372 c2ff060f bellard
            s->lcyl = (sector_num >> 8);
373 c2ff060f bellard
            s->sector = (sector_num);
374 c2ff060f bellard
        } else {
375 c2ff060f bellard
            s->sector = sector_num;
376 c2ff060f bellard
            s->lcyl = sector_num >> 8;
377 c2ff060f bellard
            s->hcyl = sector_num >> 16;
378 c2ff060f bellard
            s->hob_sector = sector_num >> 24;
379 c2ff060f bellard
            s->hob_lcyl = sector_num >> 32;
380 c2ff060f bellard
            s->hob_hcyl = sector_num >> 40;
381 c2ff060f bellard
        }
382 5391d806 bellard
    } else {
383 5391d806 bellard
        cyl = sector_num / (s->heads * s->sectors);
384 5391d806 bellard
        r = sector_num % (s->heads * s->sectors);
385 5391d806 bellard
        s->hcyl = cyl >> 8;
386 5391d806 bellard
        s->lcyl = cyl;
387 1b8eb456 bellard
        s->select = (s->select & 0xf0) | ((r / s->sectors) & 0x0f);
388 5391d806 bellard
        s->sector = (r % s->sectors) + 1;
389 5391d806 bellard
    }
390 5391d806 bellard
}
391 5391d806 bellard
392 e162cfb0 balrog
static void ide_rw_error(IDEState *s) {
393 e162cfb0 balrog
    ide_abort_command(s);
394 9cdd03a7 Gerd Hoffmann
    ide_set_irq(s->bus);
395 e162cfb0 balrog
}
396 e162cfb0 balrog
397 5391d806 bellard
static void ide_sector_read(IDEState *s)
398 5391d806 bellard
{
399 5391d806 bellard
    int64_t sector_num;
400 5391d806 bellard
    int ret, n;
401 5391d806 bellard
402 5391d806 bellard
    s->status = READY_STAT | SEEK_STAT;
403 a136e5a8 bellard
    s->error = 0; /* not needed by IDE spec, but needed by Windows */
404 5391d806 bellard
    sector_num = ide_get_sector(s);
405 5391d806 bellard
    n = s->nsector;
406 5391d806 bellard
    if (n == 0) {
407 5391d806 bellard
        /* no more sector to read from disk */
408 5391d806 bellard
        ide_transfer_stop(s);
409 5391d806 bellard
    } else {
410 5391d806 bellard
#if defined(DEBUG_IDE)
411 18c5f8ea balrog
        printf("read sector=%" PRId64 "\n", sector_num);
412 5391d806 bellard
#endif
413 5391d806 bellard
        if (n > s->req_nb_sectors)
414 5391d806 bellard
            n = s->req_nb_sectors;
415 5391d806 bellard
        ret = bdrv_read(s->bs, sector_num, s->io_buffer, n);
416 e162cfb0 balrog
        if (ret != 0) {
417 ce4b6522 Kevin Wolf
            if (ide_handle_rw_error(s, -ret,
418 ce4b6522 Kevin Wolf
                BM_STATUS_PIO_RETRY | BM_STATUS_RETRY_READ))
419 ce4b6522 Kevin Wolf
            {
420 ce4b6522 Kevin Wolf
                return;
421 ce4b6522 Kevin Wolf
            }
422 e162cfb0 balrog
        }
423 5391d806 bellard
        ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_read);
424 9cdd03a7 Gerd Hoffmann
        ide_set_irq(s->bus);
425 5391d806 bellard
        ide_set_sector(s, sector_num + n);
426 5391d806 bellard
        s->nsector -= n;
427 5391d806 bellard
    }
428 5391d806 bellard
}
429 5391d806 bellard
430 7aea4412 aliguori
431 7aea4412 aliguori
/* return 0 if buffer completed */
432 7aea4412 aliguori
static int dma_buf_prepare(BMDMAState *bm, int is_write)
433 7aea4412 aliguori
{
434 bcbdc4d3 Gerd Hoffmann
    IDEState *s = bmdma_active_if(bm);
435 7aea4412 aliguori
    struct {
436 7aea4412 aliguori
        uint32_t addr;
437 7aea4412 aliguori
        uint32_t size;
438 7aea4412 aliguori
    } prd;
439 7aea4412 aliguori
    int l, len;
440 7aea4412 aliguori
441 6450a334 Blue Swirl
    qemu_sglist_init(&s->sg, s->nsector / (IDE_PAGE_SIZE / 512) + 1);
442 7aea4412 aliguori
    s->io_buffer_size = 0;
443 7aea4412 aliguori
    for(;;) {
444 7aea4412 aliguori
        if (bm->cur_prd_len == 0) {
445 7aea4412 aliguori
            /* end of table (with a fail safe of one page) */
446 7aea4412 aliguori
            if (bm->cur_prd_last ||
447 6450a334 Blue Swirl
                (bm->cur_addr - bm->addr) >= IDE_PAGE_SIZE)
448 7aea4412 aliguori
                return s->io_buffer_size != 0;
449 7aea4412 aliguori
            cpu_physical_memory_read(bm->cur_addr, (uint8_t *)&prd, 8);
450 7aea4412 aliguori
            bm->cur_addr += 8;
451 7aea4412 aliguori
            prd.addr = le32_to_cpu(prd.addr);
452 7aea4412 aliguori
            prd.size = le32_to_cpu(prd.size);
453 7aea4412 aliguori
            len = prd.size & 0xfffe;
454 7aea4412 aliguori
            if (len == 0)
455 7aea4412 aliguori
                len = 0x10000;
456 7aea4412 aliguori
            bm->cur_prd_len = len;
457 7aea4412 aliguori
            bm->cur_prd_addr = prd.addr;
458 7aea4412 aliguori
            bm->cur_prd_last = (prd.size & 0x80000000);
459 7aea4412 aliguori
        }
460 7aea4412 aliguori
        l = bm->cur_prd_len;
461 7aea4412 aliguori
        if (l > 0) {
462 1fb8648d aliguori
            qemu_sglist_add(&s->sg, bm->cur_prd_addr, l);
463 1fb8648d aliguori
            bm->cur_prd_addr += l;
464 1fb8648d aliguori
            bm->cur_prd_len -= l;
465 1fb8648d aliguori
            s->io_buffer_size += l;
466 7aea4412 aliguori
        }
467 7aea4412 aliguori
    }
468 7aea4412 aliguori
    return 1;
469 7aea4412 aliguori
}
470 7aea4412 aliguori
471 7aea4412 aliguori
static void dma_buf_commit(IDEState *s, int is_write)
472 7aea4412 aliguori
{
473 1fb8648d aliguori
    qemu_sglist_destroy(&s->sg);
474 7aea4412 aliguori
}
475 7aea4412 aliguori
476 8337606d Kevin Wolf
static void ide_dma_set_inactive(BMDMAState *bm)
477 8337606d Kevin Wolf
{
478 8337606d Kevin Wolf
    bm->status &= ~BM_STATUS_DMAING;
479 8337606d Kevin Wolf
    bm->dma_cb = NULL;
480 8337606d Kevin Wolf
    bm->unit = -1;
481 8337606d Kevin Wolf
    bm->aiocb = NULL;
482 8337606d Kevin Wolf
}
483 8337606d Kevin Wolf
484 356721ae Gerd Hoffmann
void ide_dma_error(IDEState *s)
485 e162cfb0 balrog
{
486 e162cfb0 balrog
    ide_transfer_stop(s);
487 e162cfb0 balrog
    s->error = ABRT_ERR;
488 e162cfb0 balrog
    s->status = READY_STAT | ERR_STAT;
489 e3982b3c Kevin Wolf
    ide_dma_set_inactive(s->bus->bmdma);
490 e3982b3c Kevin Wolf
    s->bus->bmdma->status |= BM_STATUS_INT;
491 9cdd03a7 Gerd Hoffmann
    ide_set_irq(s->bus);
492 e162cfb0 balrog
}
493 e162cfb0 balrog
494 ce4b6522 Kevin Wolf
static int ide_handle_rw_error(IDEState *s, int error, int op)
495 428c5705 aliguori
{
496 ce4b6522 Kevin Wolf
    int is_read = (op & BM_STATUS_RETRY_READ);
497 abd7f68d Markus Armbruster
    BlockErrorAction action = bdrv_get_on_error(s->bs, is_read);
498 428c5705 aliguori
499 7ad7e3c3 Luiz Capitulino
    if (action == BLOCK_ERR_IGNORE) {
500 7ad7e3c3 Luiz Capitulino
        bdrv_mon_event(s->bs, BDRV_ACTION_IGNORE, is_read);
501 428c5705 aliguori
        return 0;
502 7ad7e3c3 Luiz Capitulino
    }
503 428c5705 aliguori
504 428c5705 aliguori
    if ((error == ENOSPC && action == BLOCK_ERR_STOP_ENOSPC)
505 428c5705 aliguori
            || action == BLOCK_ERR_STOP_ANY) {
506 bcbdc4d3 Gerd Hoffmann
        s->bus->bmdma->unit = s->unit;
507 bcbdc4d3 Gerd Hoffmann
        s->bus->bmdma->status |= op;
508 7ad7e3c3 Luiz Capitulino
        bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read);
509 554a310b Luiz Capitulino
        vm_stop(0);
510 428c5705 aliguori
    } else {
511 ce4b6522 Kevin Wolf
        if (op & BM_STATUS_DMA_RETRY) {
512 7aea4412 aliguori
            dma_buf_commit(s, 0);
513 428c5705 aliguori
            ide_dma_error(s);
514 7aea4412 aliguori
        } else {
515 428c5705 aliguori
            ide_rw_error(s);
516 7aea4412 aliguori
        }
517 7ad7e3c3 Luiz Capitulino
        bdrv_mon_event(s->bs, BDRV_ACTION_REPORT, is_read);
518 428c5705 aliguori
    }
519 428c5705 aliguori
520 428c5705 aliguori
    return 1;
521 428c5705 aliguori
}
522 428c5705 aliguori
523 8ccad811 bellard
/* return 0 if buffer completed */
524 8ccad811 bellard
static int dma_buf_rw(BMDMAState *bm, int is_write)
525 98087450 bellard
{
526 bcbdc4d3 Gerd Hoffmann
    IDEState *s = bmdma_active_if(bm);
527 8ccad811 bellard
    struct {
528 8ccad811 bellard
        uint32_t addr;
529 8ccad811 bellard
        uint32_t size;
530 8ccad811 bellard
    } prd;
531 8ccad811 bellard
    int l, len;
532 98087450 bellard
533 8ccad811 bellard
    for(;;) {
534 8ccad811 bellard
        l = s->io_buffer_size - s->io_buffer_index;
535 5fafdf24 ths
        if (l <= 0)
536 8ccad811 bellard
            break;
537 8ccad811 bellard
        if (bm->cur_prd_len == 0) {
538 8ccad811 bellard
            /* end of table (with a fail safe of one page) */
539 8ccad811 bellard
            if (bm->cur_prd_last ||
540 6450a334 Blue Swirl
                (bm->cur_addr - bm->addr) >= IDE_PAGE_SIZE)
541 8ccad811 bellard
                return 0;
542 8ccad811 bellard
            cpu_physical_memory_read(bm->cur_addr, (uint8_t *)&prd, 8);
543 8ccad811 bellard
            bm->cur_addr += 8;
544 8ccad811 bellard
            prd.addr = le32_to_cpu(prd.addr);
545 8ccad811 bellard
            prd.size = le32_to_cpu(prd.size);
546 8ccad811 bellard
            len = prd.size & 0xfffe;
547 8ccad811 bellard
            if (len == 0)
548 8ccad811 bellard
                len = 0x10000;
549 8ccad811 bellard
            bm->cur_prd_len = len;
550 8ccad811 bellard
            bm->cur_prd_addr = prd.addr;
551 8ccad811 bellard
            bm->cur_prd_last = (prd.size & 0x80000000);
552 8ccad811 bellard
        }
553 8ccad811 bellard
        if (l > bm->cur_prd_len)
554 8ccad811 bellard
            l = bm->cur_prd_len;
555 8ccad811 bellard
        if (l > 0) {
556 8ccad811 bellard
            if (is_write) {
557 5fafdf24 ths
                cpu_physical_memory_write(bm->cur_prd_addr,
558 8ccad811 bellard
                                          s->io_buffer + s->io_buffer_index, l);
559 8ccad811 bellard
            } else {
560 5fafdf24 ths
                cpu_physical_memory_read(bm->cur_prd_addr,
561 8ccad811 bellard
                                          s->io_buffer + s->io_buffer_index, l);
562 8ccad811 bellard
            }
563 8ccad811 bellard
            bm->cur_prd_addr += l;
564 8ccad811 bellard
            bm->cur_prd_len -= l;
565 8ccad811 bellard
            s->io_buffer_index += l;
566 98087450 bellard
        }
567 98087450 bellard
    }
568 8ccad811 bellard
    return 1;
569 8ccad811 bellard
}
570 8ccad811 bellard
571 8ccad811 bellard
static void ide_read_dma_cb(void *opaque, int ret)
572 8ccad811 bellard
{
573 8ccad811 bellard
    BMDMAState *bm = opaque;
574 bcbdc4d3 Gerd Hoffmann
    IDEState *s = bmdma_active_if(bm);
575 8ccad811 bellard
    int n;
576 8ccad811 bellard
    int64_t sector_num;
577 8ccad811 bellard
578 e162cfb0 balrog
    if (ret < 0) {
579 ce4b6522 Kevin Wolf
        if (ide_handle_rw_error(s, -ret,
580 ce4b6522 Kevin Wolf
            BM_STATUS_DMA_RETRY | BM_STATUS_RETRY_READ))
581 ce4b6522 Kevin Wolf
        {
582 ce4b6522 Kevin Wolf
            return;
583 ce4b6522 Kevin Wolf
        }
584 e162cfb0 balrog
    }
585 e162cfb0 balrog
586 8ccad811 bellard
    n = s->io_buffer_size >> 9;
587 8ccad811 bellard
    sector_num = ide_get_sector(s);
588 8ccad811 bellard
    if (n > 0) {
589 7aea4412 aliguori
        dma_buf_commit(s, 1);
590 8ccad811 bellard
        sector_num += n;
591 8ccad811 bellard
        ide_set_sector(s, sector_num);
592 8ccad811 bellard
        s->nsector -= n;
593 8ccad811 bellard
    }
594 8ccad811 bellard
595 8ccad811 bellard
    /* end of transfer ? */
596 8ccad811 bellard
    if (s->nsector == 0) {
597 98087450 bellard
        s->status = READY_STAT | SEEK_STAT;
598 9cdd03a7 Gerd Hoffmann
        ide_set_irq(s->bus);
599 8ccad811 bellard
    eot:
600 8ccad811 bellard
        bm->status |= BM_STATUS_INT;
601 8337606d Kevin Wolf
        ide_dma_set_inactive(bm);
602 8ccad811 bellard
        return;
603 98087450 bellard
    }
604 8ccad811 bellard
605 8ccad811 bellard
    /* launch next transfer */
606 8ccad811 bellard
    n = s->nsector;
607 8ccad811 bellard
    s->io_buffer_index = 0;
608 8ccad811 bellard
    s->io_buffer_size = n * 512;
609 7aea4412 aliguori
    if (dma_buf_prepare(bm, 1) == 0)
610 7aea4412 aliguori
        goto eot;
611 8ccad811 bellard
#ifdef DEBUG_AIO
612 5df23f53 blueswir1
    printf("aio_read: sector_num=%" PRId64 " n=%d\n", sector_num, n);
613 8ccad811 bellard
#endif
614 1fb8648d aliguori
    bm->aiocb = dma_bdrv_read(s->bs, &s->sg, sector_num, ide_read_dma_cb, bm);
615 5604e090 balrog
    ide_dma_submit_check(s, ide_read_dma_cb, bm);
616 98087450 bellard
}
617 98087450 bellard
618 98087450 bellard
static void ide_sector_read_dma(IDEState *s)
619 98087450 bellard
{
620 8ccad811 bellard
    s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
621 98087450 bellard
    s->io_buffer_index = 0;
622 98087450 bellard
    s->io_buffer_size = 0;
623 e3007e66 aurel32
    s->is_read = 1;
624 98087450 bellard
    ide_dma_start(s, ide_read_dma_cb);
625 98087450 bellard
}
626 98087450 bellard
627 a09db21f bellard
static void ide_sector_write_timer_cb(void *opaque)
628 a09db21f bellard
{
629 a09db21f bellard
    IDEState *s = opaque;
630 9cdd03a7 Gerd Hoffmann
    ide_set_irq(s->bus);
631 a09db21f bellard
}
632 a09db21f bellard
633 5391d806 bellard
static void ide_sector_write(IDEState *s)
634 5391d806 bellard
{
635 5391d806 bellard
    int64_t sector_num;
636 31c2a146 ths
    int ret, n, n1;
637 5391d806 bellard
638 5391d806 bellard
    s->status = READY_STAT | SEEK_STAT;
639 5391d806 bellard
    sector_num = ide_get_sector(s);
640 5391d806 bellard
#if defined(DEBUG_IDE)
641 18c5f8ea balrog
    printf("write sector=%" PRId64 "\n", sector_num);
642 5391d806 bellard
#endif
643 5391d806 bellard
    n = s->nsector;
644 5391d806 bellard
    if (n > s->req_nb_sectors)
645 5391d806 bellard
        n = s->req_nb_sectors;
646 31c2a146 ths
    ret = bdrv_write(s->bs, sector_num, s->io_buffer, n);
647 428c5705 aliguori
648 e162cfb0 balrog
    if (ret != 0) {
649 ce4b6522 Kevin Wolf
        if (ide_handle_rw_error(s, -ret, BM_STATUS_PIO_RETRY))
650 428c5705 aliguori
            return;
651 e162cfb0 balrog
    }
652 e162cfb0 balrog
653 5391d806 bellard
    s->nsector -= n;
654 5391d806 bellard
    if (s->nsector == 0) {
655 292eef5a ths
        /* no more sectors to write */
656 5391d806 bellard
        ide_transfer_stop(s);
657 5391d806 bellard
    } else {
658 5391d806 bellard
        n1 = s->nsector;
659 5391d806 bellard
        if (n1 > s->req_nb_sectors)
660 5391d806 bellard
            n1 = s->req_nb_sectors;
661 5391d806 bellard
        ide_transfer_start(s, s->io_buffer, 512 * n1, ide_sector_write);
662 5391d806 bellard
    }
663 5391d806 bellard
    ide_set_sector(s, sector_num + n);
664 3b46e624 ths
665 31c2a146 ths
    if (win2k_install_hack && ((++s->irq_count % 16) == 0)) {
666 31c2a146 ths
        /* It seems there is a bug in the Windows 2000 installer HDD
667 31c2a146 ths
           IDE driver which fills the disk with empty logs when the
668 31c2a146 ths
           IDE write IRQ comes too early. This hack tries to correct
669 31c2a146 ths
           that at the expense of slower write performances. Use this
670 31c2a146 ths
           option _only_ to install Windows 2000. You must disable it
671 31c2a146 ths
           for normal use. */
672 f7736b91 Blue Swirl
        qemu_mod_timer(s->sector_write_timer,
673 6ee093c9 Juan Quintela
                       qemu_get_clock(vm_clock) + (get_ticks_per_sec() / 1000));
674 f7736b91 Blue Swirl
    } else {
675 9cdd03a7 Gerd Hoffmann
        ide_set_irq(s->bus);
676 31c2a146 ths
    }
677 5391d806 bellard
}
678 5391d806 bellard
679 213189ab Markus Armbruster
static void ide_dma_restart_bh(void *opaque)
680 428c5705 aliguori
{
681 428c5705 aliguori
    BMDMAState *bm = opaque;
682 ce4b6522 Kevin Wolf
    int is_read;
683 213189ab Markus Armbruster
684 213189ab Markus Armbruster
    qemu_bh_delete(bm->bh);
685 213189ab Markus Armbruster
    bm->bh = NULL;
686 213189ab Markus Armbruster
687 ce4b6522 Kevin Wolf
    is_read = !!(bm->status & BM_STATUS_RETRY_READ);
688 ce4b6522 Kevin Wolf
689 428c5705 aliguori
    if (bm->status & BM_STATUS_DMA_RETRY) {
690 ce4b6522 Kevin Wolf
        bm->status &= ~(BM_STATUS_DMA_RETRY | BM_STATUS_RETRY_READ);
691 ce4b6522 Kevin Wolf
        ide_dma_restart(bmdma_active_if(bm), is_read);
692 428c5705 aliguori
    } else if (bm->status & BM_STATUS_PIO_RETRY) {
693 ce4b6522 Kevin Wolf
        bm->status &= ~(BM_STATUS_PIO_RETRY | BM_STATUS_RETRY_READ);
694 ce4b6522 Kevin Wolf
        if (is_read) {
695 ce4b6522 Kevin Wolf
            ide_sector_read(bmdma_active_if(bm));
696 ce4b6522 Kevin Wolf
        } else {
697 ce4b6522 Kevin Wolf
            ide_sector_write(bmdma_active_if(bm));
698 ce4b6522 Kevin Wolf
        }
699 e2bcadad Kevin Wolf
    } else if (bm->status & BM_STATUS_RETRY_FLUSH) {
700 e2bcadad Kevin Wolf
        ide_flush_cache(bmdma_active_if(bm));
701 428c5705 aliguori
    }
702 428c5705 aliguori
}
703 428c5705 aliguori
704 356721ae Gerd Hoffmann
void ide_dma_restart_cb(void *opaque, int running, int reason)
705 213189ab Markus Armbruster
{
706 213189ab Markus Armbruster
    BMDMAState *bm = opaque;
707 213189ab Markus Armbruster
708 213189ab Markus Armbruster
    if (!running)
709 213189ab Markus Armbruster
        return;
710 213189ab Markus Armbruster
711 213189ab Markus Armbruster
    if (!bm->bh) {
712 213189ab Markus Armbruster
        bm->bh = qemu_bh_new(ide_dma_restart_bh, bm);
713 213189ab Markus Armbruster
        qemu_bh_schedule(bm->bh);
714 213189ab Markus Armbruster
    }
715 213189ab Markus Armbruster
}
716 213189ab Markus Armbruster
717 8ccad811 bellard
static void ide_write_dma_cb(void *opaque, int ret)
718 98087450 bellard
{
719 8ccad811 bellard
    BMDMAState *bm = opaque;
720 bcbdc4d3 Gerd Hoffmann
    IDEState *s = bmdma_active_if(bm);
721 8ccad811 bellard
    int n;
722 98087450 bellard
    int64_t sector_num;
723 98087450 bellard
724 e162cfb0 balrog
    if (ret < 0) {
725 ce4b6522 Kevin Wolf
        if (ide_handle_rw_error(s, -ret,  BM_STATUS_DMA_RETRY))
726 428c5705 aliguori
            return;
727 e162cfb0 balrog
    }
728 e162cfb0 balrog
729 8ccad811 bellard
    n = s->io_buffer_size >> 9;
730 8ccad811 bellard
    sector_num = ide_get_sector(s);
731 8ccad811 bellard
    if (n > 0) {
732 7aea4412 aliguori
        dma_buf_commit(s, 0);
733 8ccad811 bellard
        sector_num += n;
734 8ccad811 bellard
        ide_set_sector(s, sector_num);
735 8ccad811 bellard
        s->nsector -= n;
736 98087450 bellard
    }
737 98087450 bellard
738 8ccad811 bellard
    /* end of transfer ? */
739 8ccad811 bellard
    if (s->nsector == 0) {
740 8ccad811 bellard
        s->status = READY_STAT | SEEK_STAT;
741 9cdd03a7 Gerd Hoffmann
        ide_set_irq(s->bus);
742 8ccad811 bellard
    eot:
743 8ccad811 bellard
        bm->status |= BM_STATUS_INT;
744 8337606d Kevin Wolf
        ide_dma_set_inactive(bm);
745 8ccad811 bellard
        return;
746 8ccad811 bellard
    }
747 8ccad811 bellard
748 98087450 bellard
    n = s->nsector;
749 98087450 bellard
    s->io_buffer_size = n * 512;
750 7aea4412 aliguori
    /* launch next transfer */
751 7aea4412 aliguori
    if (dma_buf_prepare(bm, 0) == 0)
752 8ccad811 bellard
        goto eot;
753 8ccad811 bellard
#ifdef DEBUG_AIO
754 5df23f53 blueswir1
    printf("aio_write: sector_num=%" PRId64 " n=%d\n", sector_num, n);
755 8ccad811 bellard
#endif
756 1fb8648d aliguori
    bm->aiocb = dma_bdrv_write(s->bs, &s->sg, sector_num, ide_write_dma_cb, bm);
757 5604e090 balrog
    ide_dma_submit_check(s, ide_write_dma_cb, bm);
758 8ccad811 bellard
}
759 8ccad811 bellard
760 8ccad811 bellard
static void ide_sector_write_dma(IDEState *s)
761 8ccad811 bellard
{
762 8ccad811 bellard
    s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
763 8ccad811 bellard
    s->io_buffer_index = 0;
764 8ccad811 bellard
    s->io_buffer_size = 0;
765 e3007e66 aurel32
    s->is_read = 0;
766 98087450 bellard
    ide_dma_start(s, ide_write_dma_cb);
767 98087450 bellard
}
768 98087450 bellard
769 356721ae Gerd Hoffmann
void ide_atapi_cmd_ok(IDEState *s)
770 5391d806 bellard
{
771 5391d806 bellard
    s->error = 0;
772 41a2b959 aliguori
    s->status = READY_STAT | SEEK_STAT;
773 5391d806 bellard
    s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
774 9cdd03a7 Gerd Hoffmann
    ide_set_irq(s->bus);
775 5391d806 bellard
}
776 5391d806 bellard
777 356721ae Gerd Hoffmann
void ide_atapi_cmd_error(IDEState *s, int sense_key, int asc)
778 5391d806 bellard
{
779 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
780 5391d806 bellard
    printf("atapi_cmd_error: sense=0x%x asc=0x%x\n", sense_key, asc);
781 5391d806 bellard
#endif
782 5391d806 bellard
    s->error = sense_key << 4;
783 5391d806 bellard
    s->status = READY_STAT | ERR_STAT;
784 5391d806 bellard
    s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
785 5391d806 bellard
    s->sense_key = sense_key;
786 5391d806 bellard
    s->asc = asc;
787 9cdd03a7 Gerd Hoffmann
    ide_set_irq(s->bus);
788 5391d806 bellard
}
789 5391d806 bellard
790 9118e7f0 aliguori
static void ide_atapi_cmd_check_status(IDEState *s)
791 9118e7f0 aliguori
{
792 9118e7f0 aliguori
#ifdef DEBUG_IDE_ATAPI
793 9118e7f0 aliguori
    printf("atapi_cmd_check_status\n");
794 9118e7f0 aliguori
#endif
795 9118e7f0 aliguori
    s->error = MC_ERR | (SENSE_UNIT_ATTENTION << 4);
796 9118e7f0 aliguori
    s->status = ERR_STAT;
797 9118e7f0 aliguori
    s->nsector = 0;
798 9cdd03a7 Gerd Hoffmann
    ide_set_irq(s->bus);
799 9118e7f0 aliguori
}
800 9118e7f0 aliguori
801 b0484ae4 Christoph Hellwig
static void ide_flush_cb(void *opaque, int ret)
802 b0484ae4 Christoph Hellwig
{
803 b0484ae4 Christoph Hellwig
    IDEState *s = opaque;
804 b0484ae4 Christoph Hellwig
805 e2bcadad Kevin Wolf
    if (ret < 0) {
806 e2bcadad Kevin Wolf
        /* XXX: What sector number to set here? */
807 e2bcadad Kevin Wolf
        if (ide_handle_rw_error(s, -ret, BM_STATUS_RETRY_FLUSH)) {
808 e2bcadad Kevin Wolf
            return;
809 e2bcadad Kevin Wolf
        }
810 e2bcadad Kevin Wolf
    }
811 b0484ae4 Christoph Hellwig
812 b0484ae4 Christoph Hellwig
    s->status = READY_STAT | SEEK_STAT;
813 b0484ae4 Christoph Hellwig
    ide_set_irq(s->bus);
814 b0484ae4 Christoph Hellwig
}
815 b0484ae4 Christoph Hellwig
816 6bcb1a79 Kevin Wolf
static void ide_flush_cache(IDEState *s)
817 6bcb1a79 Kevin Wolf
{
818 b2df7531 Kevin Wolf
    BlockDriverAIOCB *acb;
819 b2df7531 Kevin Wolf
820 b2df7531 Kevin Wolf
    if (s->bs == NULL) {
821 6bcb1a79 Kevin Wolf
        ide_flush_cb(s, 0);
822 b2df7531 Kevin Wolf
        return;
823 b2df7531 Kevin Wolf
    }
824 b2df7531 Kevin Wolf
825 b2df7531 Kevin Wolf
    acb = bdrv_aio_flush(s->bs, ide_flush_cb, s);
826 b2df7531 Kevin Wolf
    if (acb == NULL) {
827 b2df7531 Kevin Wolf
        ide_flush_cb(s, -EIO);
828 6bcb1a79 Kevin Wolf
    }
829 6bcb1a79 Kevin Wolf
}
830 6bcb1a79 Kevin Wolf
831 5391d806 bellard
static inline void cpu_to_ube16(uint8_t *buf, int val)
832 5391d806 bellard
{
833 5391d806 bellard
    buf[0] = val >> 8;
834 9e622b15 blueswir1
    buf[1] = val & 0xff;
835 5391d806 bellard
}
836 5391d806 bellard
837 5391d806 bellard
static inline void cpu_to_ube32(uint8_t *buf, unsigned int val)
838 5391d806 bellard
{
839 5391d806 bellard
    buf[0] = val >> 24;
840 5391d806 bellard
    buf[1] = val >> 16;
841 5391d806 bellard
    buf[2] = val >> 8;
842 9e622b15 blueswir1
    buf[3] = val & 0xff;
843 5391d806 bellard
}
844 5391d806 bellard
845 5391d806 bellard
static inline int ube16_to_cpu(const uint8_t *buf)
846 5391d806 bellard
{
847 5391d806 bellard
    return (buf[0] << 8) | buf[1];
848 5391d806 bellard
}
849 5391d806 bellard
850 5391d806 bellard
static inline int ube32_to_cpu(const uint8_t *buf)
851 5391d806 bellard
{
852 5391d806 bellard
    return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
853 5391d806 bellard
}
854 5391d806 bellard
855 98087450 bellard
static void lba_to_msf(uint8_t *buf, int lba)
856 98087450 bellard
{
857 98087450 bellard
    lba += 150;
858 98087450 bellard
    buf[0] = (lba / 75) / 60;
859 98087450 bellard
    buf[1] = (lba / 75) % 60;
860 98087450 bellard
    buf[2] = lba % 75;
861 98087450 bellard
}
862 98087450 bellard
863 8ccad811 bellard
static void cd_data_to_raw(uint8_t *buf, int lba)
864 8ccad811 bellard
{
865 8ccad811 bellard
    /* sync bytes */
866 8ccad811 bellard
    buf[0] = 0x00;
867 8ccad811 bellard
    memset(buf + 1, 0xff, 10);
868 8ccad811 bellard
    buf[11] = 0x00;
869 8ccad811 bellard
    buf += 12;
870 8ccad811 bellard
    /* MSF */
871 8ccad811 bellard
    lba_to_msf(buf, lba);
872 8ccad811 bellard
    buf[3] = 0x01; /* mode 1 data */
873 8ccad811 bellard
    buf += 4;
874 8ccad811 bellard
    /* data */
875 8ccad811 bellard
    buf += 2048;
876 8ccad811 bellard
    /* XXX: ECC not computed */
877 8ccad811 bellard
    memset(buf, 0, 288);
878 8ccad811 bellard
}
879 8ccad811 bellard
880 5fafdf24 ths
static int cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf,
881 98087450 bellard
                           int sector_size)
882 98087450 bellard
{
883 66c6ef76 bellard
    int ret;
884 66c6ef76 bellard
885 98087450 bellard
    switch(sector_size) {
886 98087450 bellard
    case 2048:
887 66c6ef76 bellard
        ret = bdrv_read(bs, (int64_t)lba << 2, buf, 4);
888 98087450 bellard
        break;
889 98087450 bellard
    case 2352:
890 66c6ef76 bellard
        ret = bdrv_read(bs, (int64_t)lba << 2, buf + 16, 4);
891 66c6ef76 bellard
        if (ret < 0)
892 66c6ef76 bellard
            return ret;
893 8ccad811 bellard
        cd_data_to_raw(buf, lba);
894 98087450 bellard
        break;
895 98087450 bellard
    default:
896 66c6ef76 bellard
        ret = -EIO;
897 98087450 bellard
        break;
898 98087450 bellard
    }
899 66c6ef76 bellard
    return ret;
900 66c6ef76 bellard
}
901 66c6ef76 bellard
902 356721ae Gerd Hoffmann
void ide_atapi_io_error(IDEState *s, int ret)
903 66c6ef76 bellard
{
904 66c6ef76 bellard
    /* XXX: handle more errors */
905 66c6ef76 bellard
    if (ret == -ENOMEDIUM) {
906 5fafdf24 ths
        ide_atapi_cmd_error(s, SENSE_NOT_READY,
907 66c6ef76 bellard
                            ASC_MEDIUM_NOT_PRESENT);
908 66c6ef76 bellard
    } else {
909 5fafdf24 ths
        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
910 66c6ef76 bellard
                            ASC_LOGICAL_BLOCK_OOR);
911 66c6ef76 bellard
    }
912 98087450 bellard
}
913 98087450 bellard
914 5391d806 bellard
/* The whole ATAPI transfer logic is handled in this function */
915 5391d806 bellard
static void ide_atapi_cmd_reply_end(IDEState *s)
916 5391d806 bellard
{
917 66c6ef76 bellard
    int byte_count_limit, size, ret;
918 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
919 5fafdf24 ths
    printf("reply: tx_size=%d elem_tx_size=%d index=%d\n",
920 5391d806 bellard
           s->packet_transfer_size,
921 5391d806 bellard
           s->elementary_transfer_size,
922 5391d806 bellard
           s->io_buffer_index);
923 5391d806 bellard
#endif
924 5391d806 bellard
    if (s->packet_transfer_size <= 0) {
925 5391d806 bellard
        /* end of transfer */
926 5391d806 bellard
        ide_transfer_stop(s);
927 41a2b959 aliguori
        s->status = READY_STAT | SEEK_STAT;
928 5391d806 bellard
        s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
929 9cdd03a7 Gerd Hoffmann
        ide_set_irq(s->bus);
930 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
931 5391d806 bellard
        printf("status=0x%x\n", s->status);
932 5391d806 bellard
#endif
933 5391d806 bellard
    } else {
934 5391d806 bellard
        /* see if a new sector must be read */
935 98087450 bellard
        if (s->lba != -1 && s->io_buffer_index >= s->cd_sector_size) {
936 66c6ef76 bellard
            ret = cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size);
937 66c6ef76 bellard
            if (ret < 0) {
938 66c6ef76 bellard
                ide_transfer_stop(s);
939 66c6ef76 bellard
                ide_atapi_io_error(s, ret);
940 66c6ef76 bellard
                return;
941 66c6ef76 bellard
            }
942 5391d806 bellard
            s->lba++;
943 5391d806 bellard
            s->io_buffer_index = 0;
944 5391d806 bellard
        }
945 5391d806 bellard
        if (s->elementary_transfer_size > 0) {
946 5391d806 bellard
            /* there are some data left to transmit in this elementary
947 5391d806 bellard
               transfer */
948 98087450 bellard
            size = s->cd_sector_size - s->io_buffer_index;
949 5391d806 bellard
            if (size > s->elementary_transfer_size)
950 5391d806 bellard
                size = s->elementary_transfer_size;
951 5fafdf24 ths
            ide_transfer_start(s, s->io_buffer + s->io_buffer_index,
952 5391d806 bellard
                               size, ide_atapi_cmd_reply_end);
953 5391d806 bellard
            s->packet_transfer_size -= size;
954 5391d806 bellard
            s->elementary_transfer_size -= size;
955 5391d806 bellard
            s->io_buffer_index += size;
956 5391d806 bellard
        } else {
957 5391d806 bellard
            /* a new transfer is needed */
958 5391d806 bellard
            s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO;
959 5391d806 bellard
            byte_count_limit = s->lcyl | (s->hcyl << 8);
960 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
961 5391d806 bellard
            printf("byte_count_limit=%d\n", byte_count_limit);
962 5391d806 bellard
#endif
963 5391d806 bellard
            if (byte_count_limit == 0xffff)
964 5391d806 bellard
                byte_count_limit--;
965 5391d806 bellard
            size = s->packet_transfer_size;
966 5391d806 bellard
            if (size > byte_count_limit) {
967 5391d806 bellard
                /* byte count limit must be even if this case */
968 5391d806 bellard
                if (byte_count_limit & 1)
969 5391d806 bellard
                    byte_count_limit--;
970 5391d806 bellard
                size = byte_count_limit;
971 5391d806 bellard
            }
972 a136e5a8 bellard
            s->lcyl = size;
973 a136e5a8 bellard
            s->hcyl = size >> 8;
974 5391d806 bellard
            s->elementary_transfer_size = size;
975 5391d806 bellard
            /* we cannot transmit more than one sector at a time */
976 5391d806 bellard
            if (s->lba != -1) {
977 98087450 bellard
                if (size > (s->cd_sector_size - s->io_buffer_index))
978 98087450 bellard
                    size = (s->cd_sector_size - s->io_buffer_index);
979 5391d806 bellard
            }
980 5fafdf24 ths
            ide_transfer_start(s, s->io_buffer + s->io_buffer_index,
981 5391d806 bellard
                               size, ide_atapi_cmd_reply_end);
982 5391d806 bellard
            s->packet_transfer_size -= size;
983 5391d806 bellard
            s->elementary_transfer_size -= size;
984 5391d806 bellard
            s->io_buffer_index += size;
985 9cdd03a7 Gerd Hoffmann
            ide_set_irq(s->bus);
986 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
987 5391d806 bellard
            printf("status=0x%x\n", s->status);
988 5391d806 bellard
#endif
989 5391d806 bellard
        }
990 5391d806 bellard
    }
991 5391d806 bellard
}
992 5391d806 bellard
993 5391d806 bellard
/* send a reply of 'size' bytes in s->io_buffer to an ATAPI command */
994 5391d806 bellard
static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size)
995 5391d806 bellard
{
996 5391d806 bellard
    if (size > max_size)
997 5391d806 bellard
        size = max_size;
998 5391d806 bellard
    s->lba = -1; /* no sector read */
999 5391d806 bellard
    s->packet_transfer_size = size;
1000 5f12ab4b ths
    s->io_buffer_size = size;    /* dma: send the reply data as one chunk */
1001 5391d806 bellard
    s->elementary_transfer_size = 0;
1002 5391d806 bellard
    s->io_buffer_index = 0;
1003 5391d806 bellard
1004 5f12ab4b ths
    if (s->atapi_dma) {
1005 41a2b959 aliguori
            s->status = READY_STAT | SEEK_STAT | DRQ_STAT;
1006 5f12ab4b ths
        ide_dma_start(s, ide_atapi_cmd_read_dma_cb);
1007 5f12ab4b ths
    } else {
1008 41a2b959 aliguori
            s->status = READY_STAT | SEEK_STAT;
1009 5f12ab4b ths
            ide_atapi_cmd_reply_end(s);
1010 5f12ab4b ths
    }
1011 5391d806 bellard
}
1012 5391d806 bellard
1013 5391d806 bellard
/* start a CD-CDROM read command */
1014 98087450 bellard
static void ide_atapi_cmd_read_pio(IDEState *s, int lba, int nb_sectors,
1015 98087450 bellard
                                   int sector_size)
1016 5391d806 bellard
{
1017 5391d806 bellard
    s->lba = lba;
1018 98087450 bellard
    s->packet_transfer_size = nb_sectors * sector_size;
1019 5391d806 bellard
    s->elementary_transfer_size = 0;
1020 98087450 bellard
    s->io_buffer_index = sector_size;
1021 98087450 bellard
    s->cd_sector_size = sector_size;
1022 5391d806 bellard
1023 41a2b959 aliguori
    s->status = READY_STAT | SEEK_STAT;
1024 5391d806 bellard
    ide_atapi_cmd_reply_end(s);
1025 5391d806 bellard
}
1026 5391d806 bellard
1027 98087450 bellard
/* ATAPI DMA support */
1028 8ccad811 bellard
1029 8ccad811 bellard
/* XXX: handle read errors */
1030 8ccad811 bellard
static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret)
1031 98087450 bellard
{
1032 8ccad811 bellard
    BMDMAState *bm = opaque;
1033 bcbdc4d3 Gerd Hoffmann
    IDEState *s = bmdma_active_if(bm);
1034 8ccad811 bellard
    int data_offset, n;
1035 8ccad811 bellard
1036 66c6ef76 bellard
    if (ret < 0) {
1037 66c6ef76 bellard
        ide_atapi_io_error(s, ret);
1038 66c6ef76 bellard
        goto eot;
1039 66c6ef76 bellard
    }
1040 66c6ef76 bellard
1041 8ccad811 bellard
    if (s->io_buffer_size > 0) {
1042 5f12ab4b ths
        /*
1043 5f12ab4b ths
         * For a cdrom read sector command (s->lba != -1),
1044 5f12ab4b ths
         * adjust the lba for the next s->io_buffer_size chunk
1045 5f12ab4b ths
         * and dma the current chunk.
1046 5f12ab4b ths
         * For a command != read (s->lba == -1), just transfer
1047 5f12ab4b ths
         * the reply data.
1048 5f12ab4b ths
         */
1049 5f12ab4b ths
        if (s->lba != -1) {
1050 5f12ab4b ths
            if (s->cd_sector_size == 2352) {
1051 5f12ab4b ths
                n = 1;
1052 5f12ab4b ths
                cd_data_to_raw(s->io_buffer, s->lba);
1053 5f12ab4b ths
            } else {
1054 5f12ab4b ths
                n = s->io_buffer_size >> 11;
1055 5f12ab4b ths
            }
1056 5f12ab4b ths
            s->lba += n;
1057 5f12ab4b ths
        }
1058 8ccad811 bellard
        s->packet_transfer_size -= s->io_buffer_size;
1059 8ccad811 bellard
        if (dma_buf_rw(bm, 1) == 0)
1060 8ccad811 bellard
            goto eot;
1061 98087450 bellard
    }
1062 8ccad811 bellard
1063 98087450 bellard
    if (s->packet_transfer_size <= 0) {
1064 41a2b959 aliguori
        s->status = READY_STAT | SEEK_STAT;
1065 98087450 bellard
        s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
1066 9cdd03a7 Gerd Hoffmann
        ide_set_irq(s->bus);
1067 8ccad811 bellard
    eot:
1068 8ccad811 bellard
        bm->status |= BM_STATUS_INT;
1069 8337606d Kevin Wolf
        ide_dma_set_inactive(bm);
1070 8ccad811 bellard
        return;
1071 8ccad811 bellard
    }
1072 3b46e624 ths
1073 8ccad811 bellard
    s->io_buffer_index = 0;
1074 8ccad811 bellard
    if (s->cd_sector_size == 2352) {
1075 8ccad811 bellard
        n = 1;
1076 8ccad811 bellard
        s->io_buffer_size = s->cd_sector_size;
1077 8ccad811 bellard
        data_offset = 16;
1078 8ccad811 bellard
    } else {
1079 8ccad811 bellard
        n = s->packet_transfer_size >> 11;
1080 1d8cde5b aurel32
        if (n > (IDE_DMA_BUF_SECTORS / 4))
1081 1d8cde5b aurel32
            n = (IDE_DMA_BUF_SECTORS / 4);
1082 8ccad811 bellard
        s->io_buffer_size = n * 2048;
1083 8ccad811 bellard
        data_offset = 0;
1084 98087450 bellard
    }
1085 8ccad811 bellard
#ifdef DEBUG_AIO
1086 8ccad811 bellard
    printf("aio_read_cd: lba=%u n=%d\n", s->lba, n);
1087 8ccad811 bellard
#endif
1088 3f4cb3d3 blueswir1
    bm->iov.iov_base = (void *)(s->io_buffer + data_offset);
1089 c87c0672 aliguori
    bm->iov.iov_len = n * 4 * 512;
1090 c87c0672 aliguori
    qemu_iovec_init_external(&bm->qiov, &bm->iov, 1);
1091 c87c0672 aliguori
    bm->aiocb = bdrv_aio_readv(s->bs, (int64_t)s->lba << 2, &bm->qiov,
1092 c87c0672 aliguori
                               n * 4, ide_atapi_cmd_read_dma_cb, bm);
1093 66c6ef76 bellard
    if (!bm->aiocb) {
1094 66c6ef76 bellard
        /* Note: media not present is the most likely case */
1095 5fafdf24 ths
        ide_atapi_cmd_error(s, SENSE_NOT_READY,
1096 66c6ef76 bellard
                            ASC_MEDIUM_NOT_PRESENT);
1097 66c6ef76 bellard
        goto eot;
1098 66c6ef76 bellard
    }
1099 98087450 bellard
}
1100 98087450 bellard
1101 98087450 bellard
/* start a CD-CDROM read command with DMA */
1102 98087450 bellard
/* XXX: test if DMA is available */
1103 98087450 bellard
static void ide_atapi_cmd_read_dma(IDEState *s, int lba, int nb_sectors,
1104 98087450 bellard
                                   int sector_size)
1105 98087450 bellard
{
1106 98087450 bellard
    s->lba = lba;
1107 98087450 bellard
    s->packet_transfer_size = nb_sectors * sector_size;
1108 8ccad811 bellard
    s->io_buffer_index = 0;
1109 8ccad811 bellard
    s->io_buffer_size = 0;
1110 98087450 bellard
    s->cd_sector_size = sector_size;
1111 98087450 bellard
1112 8ccad811 bellard
    /* XXX: check if BUSY_STAT should be set */
1113 41a2b959 aliguori
    s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
1114 98087450 bellard
    ide_dma_start(s, ide_atapi_cmd_read_dma_cb);
1115 98087450 bellard
}
1116 98087450 bellard
1117 5fafdf24 ths
static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors,
1118 98087450 bellard
                               int sector_size)
1119 98087450 bellard
{
1120 98087450 bellard
#ifdef DEBUG_IDE_ATAPI
1121 5f12ab4b ths
    printf("read %s: LBA=%d nb_sectors=%d\n", s->atapi_dma ? "dma" : "pio",
1122 5f12ab4b ths
        lba, nb_sectors);
1123 98087450 bellard
#endif
1124 98087450 bellard
    if (s->atapi_dma) {
1125 98087450 bellard
        ide_atapi_cmd_read_dma(s, lba, nb_sectors, sector_size);
1126 98087450 bellard
    } else {
1127 98087450 bellard
        ide_atapi_cmd_read_pio(s, lba, nb_sectors, sector_size);
1128 98087450 bellard
    }
1129 98087450 bellard
}
1130 98087450 bellard
1131 38cdea7c balrog
static inline uint8_t ide_atapi_set_profile(uint8_t *buf, uint8_t *index,
1132 38cdea7c balrog
                                            uint16_t profile)
1133 38cdea7c balrog
{
1134 38cdea7c balrog
    uint8_t *buf_profile = buf + 12; /* start of profiles */
1135 38cdea7c balrog
1136 38cdea7c balrog
    buf_profile += ((*index) * 4); /* start of indexed profile */
1137 38cdea7c balrog
    cpu_to_ube16 (buf_profile, profile);
1138 38cdea7c balrog
    buf_profile[2] = ((buf_profile[0] == buf[6]) && (buf_profile[1] == buf[7]));
1139 38cdea7c balrog
1140 38cdea7c balrog
    /* each profile adds 4 bytes to the response */
1141 38cdea7c balrog
    (*index)++;
1142 38cdea7c balrog
    buf[11] += 4; /* Additional Length */
1143 38cdea7c balrog
1144 38cdea7c balrog
    return 4;
1145 38cdea7c balrog
}
1146 38cdea7c balrog
1147 8114e9e8 ths
static int ide_dvd_read_structure(IDEState *s, int format,
1148 8114e9e8 ths
                                  const uint8_t *packet, uint8_t *buf)
1149 8114e9e8 ths
{
1150 8114e9e8 ths
    switch (format) {
1151 8114e9e8 ths
        case 0x0: /* Physical format information */
1152 8114e9e8 ths
            {
1153 8114e9e8 ths
                int layer = packet[6];
1154 8114e9e8 ths
                uint64_t total_sectors;
1155 8114e9e8 ths
1156 8114e9e8 ths
                if (layer != 0)
1157 8114e9e8 ths
                    return -ASC_INV_FIELD_IN_CMD_PACKET;
1158 8114e9e8 ths
1159 8114e9e8 ths
                bdrv_get_geometry(s->bs, &total_sectors);
1160 8114e9e8 ths
                total_sectors >>= 2;
1161 8114e9e8 ths
                if (total_sectors == 0)
1162 8114e9e8 ths
                    return -ASC_MEDIUM_NOT_PRESENT;
1163 8114e9e8 ths
1164 8114e9e8 ths
                buf[4] = 1;   /* DVD-ROM, part version 1 */
1165 8114e9e8 ths
                buf[5] = 0xf; /* 120mm disc, minimum rate unspecified */
1166 8114e9e8 ths
                buf[6] = 1;   /* one layer, read-only (per MMC-2 spec) */
1167 8114e9e8 ths
                buf[7] = 0;   /* default densities */
1168 8114e9e8 ths
1169 8114e9e8 ths
                /* FIXME: 0x30000 per spec? */
1170 8114e9e8 ths
                cpu_to_ube32(buf + 8, 0); /* start sector */
1171 8114e9e8 ths
                cpu_to_ube32(buf + 12, total_sectors - 1); /* end sector */
1172 8114e9e8 ths
                cpu_to_ube32(buf + 16, total_sectors - 1); /* l0 end sector */
1173 8114e9e8 ths
1174 8114e9e8 ths
                /* Size of buffer, not including 2 byte size field */
1175 8114e9e8 ths
                cpu_to_be16wu((uint16_t *)buf, 2048 + 2);
1176 8114e9e8 ths
1177 8114e9e8 ths
                /* 2k data + 4 byte header */
1178 8114e9e8 ths
                return (2048 + 4);
1179 8114e9e8 ths
            }
1180 8114e9e8 ths
1181 8114e9e8 ths
        case 0x01: /* DVD copyright information */
1182 8114e9e8 ths
            buf[4] = 0; /* no copyright data */
1183 8114e9e8 ths
            buf[5] = 0; /* no region restrictions */
1184 8114e9e8 ths
1185 8114e9e8 ths
            /* Size of buffer, not including 2 byte size field */
1186 8114e9e8 ths
            cpu_to_be16wu((uint16_t *)buf, 4 + 2);
1187 8114e9e8 ths
1188 8114e9e8 ths
            /* 4 byte header + 4 byte data */
1189 8114e9e8 ths
            return (4 + 4);
1190 8114e9e8 ths
1191 8114e9e8 ths
        case 0x03: /* BCA information - invalid field for no BCA info */
1192 8114e9e8 ths
            return -ASC_INV_FIELD_IN_CMD_PACKET;
1193 8114e9e8 ths
1194 8114e9e8 ths
        case 0x04: /* DVD disc manufacturing information */
1195 8114e9e8 ths
            /* Size of buffer, not including 2 byte size field */
1196 8114e9e8 ths
            cpu_to_be16wu((uint16_t *)buf, 2048 + 2);
1197 8114e9e8 ths
1198 8114e9e8 ths
            /* 2k data + 4 byte header */
1199 8114e9e8 ths
            return (2048 + 4);
1200 8114e9e8 ths
1201 8114e9e8 ths
        case 0xff:
1202 8114e9e8 ths
            /*
1203 8114e9e8 ths
             * This lists all the command capabilities above.  Add new ones
1204 8114e9e8 ths
             * in order and update the length and buffer return values.
1205 8114e9e8 ths
             */
1206 8114e9e8 ths
1207 8114e9e8 ths
            buf[4] = 0x00; /* Physical format */
1208 8114e9e8 ths
            buf[5] = 0x40; /* Not writable, is readable */
1209 8114e9e8 ths
            cpu_to_be16wu((uint16_t *)(buf + 6), 2048 + 4);
1210 8114e9e8 ths
1211 8114e9e8 ths
            buf[8] = 0x01; /* Copyright info */
1212 8114e9e8 ths
            buf[9] = 0x40; /* Not writable, is readable */
1213 8114e9e8 ths
            cpu_to_be16wu((uint16_t *)(buf + 10), 4 + 4);
1214 8114e9e8 ths
1215 8114e9e8 ths
            buf[12] = 0x03; /* BCA info */
1216 8114e9e8 ths
            buf[13] = 0x40; /* Not writable, is readable */
1217 8114e9e8 ths
            cpu_to_be16wu((uint16_t *)(buf + 14), 188 + 4);
1218 8114e9e8 ths
1219 8114e9e8 ths
            buf[16] = 0x04; /* Manufacturing info */
1220 8114e9e8 ths
            buf[17] = 0x40; /* Not writable, is readable */
1221 8114e9e8 ths
            cpu_to_be16wu((uint16_t *)(buf + 18), 2048 + 4);
1222 8114e9e8 ths
1223 8114e9e8 ths
            /* Size of buffer, not including 2 byte size field */
1224 8114e9e8 ths
            cpu_to_be16wu((uint16_t *)buf, 16 + 2);
1225 8114e9e8 ths
1226 8114e9e8 ths
            /* data written + 4 byte header */
1227 8114e9e8 ths
            return (16 + 4);
1228 8114e9e8 ths
1229 8114e9e8 ths
        default: /* TODO: formats beyond DVD-ROM requires */
1230 8114e9e8 ths
            return -ASC_INV_FIELD_IN_CMD_PACKET;
1231 8114e9e8 ths
    }
1232 8114e9e8 ths
}
1233 8114e9e8 ths
1234 5391d806 bellard
static void ide_atapi_cmd(IDEState *s)
1235 5391d806 bellard
{
1236 5391d806 bellard
    const uint8_t *packet;
1237 5391d806 bellard
    uint8_t *buf;
1238 5391d806 bellard
    int max_len;
1239 5391d806 bellard
1240 5391d806 bellard
    packet = s->io_buffer;
1241 5391d806 bellard
    buf = s->io_buffer;
1242 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
1243 5391d806 bellard
    {
1244 5391d806 bellard
        int i;
1245 5391d806 bellard
        printf("ATAPI limit=0x%x packet:", s->lcyl | (s->hcyl << 8));
1246 5391d806 bellard
        for(i = 0; i < ATAPI_PACKET_SIZE; i++) {
1247 5391d806 bellard
            printf(" %02x", packet[i]);
1248 5391d806 bellard
        }
1249 5391d806 bellard
        printf("\n");
1250 5391d806 bellard
    }
1251 5391d806 bellard
#endif
1252 9118e7f0 aliguori
    /* If there's a UNIT_ATTENTION condition pending, only
1253 9118e7f0 aliguori
       REQUEST_SENSE and INQUIRY commands are allowed to complete. */
1254 9118e7f0 aliguori
    if (s->sense_key == SENSE_UNIT_ATTENTION &&
1255 9118e7f0 aliguori
        s->io_buffer[0] != GPCMD_REQUEST_SENSE &&
1256 9118e7f0 aliguori
        s->io_buffer[0] != GPCMD_INQUIRY) {
1257 9118e7f0 aliguori
        ide_atapi_cmd_check_status(s);
1258 9118e7f0 aliguori
        return;
1259 9118e7f0 aliguori
    }
1260 5391d806 bellard
    switch(s->io_buffer[0]) {
1261 5391d806 bellard
    case GPCMD_TEST_UNIT_READY:
1262 93c8cfd9 Gleb Natapov
        if (bdrv_is_inserted(s->bs) && !s->cdrom_changed) {
1263 5391d806 bellard
            ide_atapi_cmd_ok(s);
1264 5391d806 bellard
        } else {
1265 93c8cfd9 Gleb Natapov
            s->cdrom_changed = 0;
1266 5fafdf24 ths
            ide_atapi_cmd_error(s, SENSE_NOT_READY,
1267 5391d806 bellard
                                ASC_MEDIUM_NOT_PRESENT);
1268 5391d806 bellard
        }
1269 5391d806 bellard
        break;
1270 d14049ea ths
    case GPCMD_MODE_SENSE_6:
1271 5391d806 bellard
    case GPCMD_MODE_SENSE_10:
1272 5391d806 bellard
        {
1273 5391d806 bellard
            int action, code;
1274 d14049ea ths
            if (packet[0] == GPCMD_MODE_SENSE_10)
1275 d14049ea ths
                max_len = ube16_to_cpu(packet + 7);
1276 d14049ea ths
            else
1277 d14049ea ths
                max_len = packet[4];
1278 5391d806 bellard
            action = packet[2] >> 6;
1279 5391d806 bellard
            code = packet[2] & 0x3f;
1280 5391d806 bellard
            switch(action) {
1281 5391d806 bellard
            case 0: /* current values */
1282 5391d806 bellard
                switch(code) {
1283 a70089ce Thadeu Lima de Souza Cascardo
                case GPMODE_R_W_ERROR_PAGE: /* error recovery */
1284 5391d806 bellard
                    cpu_to_ube16(&buf[0], 16 + 6);
1285 5391d806 bellard
                    buf[2] = 0x70;
1286 5391d806 bellard
                    buf[3] = 0;
1287 5391d806 bellard
                    buf[4] = 0;
1288 5391d806 bellard
                    buf[5] = 0;
1289 5391d806 bellard
                    buf[6] = 0;
1290 5391d806 bellard
                    buf[7] = 0;
1291 5391d806 bellard
1292 5391d806 bellard
                    buf[8] = 0x01;
1293 5391d806 bellard
                    buf[9] = 0x06;
1294 5391d806 bellard
                    buf[10] = 0x00;
1295 5391d806 bellard
                    buf[11] = 0x05;
1296 5391d806 bellard
                    buf[12] = 0x00;
1297 5391d806 bellard
                    buf[13] = 0x00;
1298 5391d806 bellard
                    buf[14] = 0x00;
1299 5391d806 bellard
                    buf[15] = 0x00;
1300 5391d806 bellard
                    ide_atapi_cmd_reply(s, 16, max_len);
1301 5391d806 bellard
                    break;
1302 fe0d6123 Thadeu Lima de Souza Cascardo
                case GPMODE_AUDIO_CTL_PAGE:
1303 fe0d6123 Thadeu Lima de Souza Cascardo
                    cpu_to_ube16(&buf[0], 24 + 6);
1304 fe0d6123 Thadeu Lima de Souza Cascardo
                    buf[2] = 0x70;
1305 fe0d6123 Thadeu Lima de Souza Cascardo
                    buf[3] = 0;
1306 fe0d6123 Thadeu Lima de Souza Cascardo
                    buf[4] = 0;
1307 fe0d6123 Thadeu Lima de Souza Cascardo
                    buf[5] = 0;
1308 fe0d6123 Thadeu Lima de Souza Cascardo
                    buf[6] = 0;
1309 fe0d6123 Thadeu Lima de Souza Cascardo
                    buf[7] = 0;
1310 fe0d6123 Thadeu Lima de Souza Cascardo
1311 fe0d6123 Thadeu Lima de Souza Cascardo
                    /* Fill with CDROM audio volume */
1312 fe0d6123 Thadeu Lima de Souza Cascardo
                    buf[17] = 0;
1313 fe0d6123 Thadeu Lima de Souza Cascardo
                    buf[19] = 0;
1314 fe0d6123 Thadeu Lima de Souza Cascardo
                    buf[21] = 0;
1315 fe0d6123 Thadeu Lima de Souza Cascardo
                    buf[23] = 0;
1316 fe0d6123 Thadeu Lima de Souza Cascardo
1317 fe0d6123 Thadeu Lima de Souza Cascardo
                    ide_atapi_cmd_reply(s, 24, max_len);
1318 fe0d6123 Thadeu Lima de Souza Cascardo
                    break;
1319 a70089ce Thadeu Lima de Souza Cascardo
                case GPMODE_CAPABILITIES_PAGE:
1320 5391d806 bellard
                    cpu_to_ube16(&buf[0], 28 + 6);
1321 5391d806 bellard
                    buf[2] = 0x70;
1322 5391d806 bellard
                    buf[3] = 0;
1323 5391d806 bellard
                    buf[4] = 0;
1324 5391d806 bellard
                    buf[5] = 0;
1325 5391d806 bellard
                    buf[6] = 0;
1326 5391d806 bellard
                    buf[7] = 0;
1327 5391d806 bellard
1328 5391d806 bellard
                    buf[8] = 0x2a;
1329 5391d806 bellard
                    buf[9] = 0x12;
1330 0d4a05a1 ths
                    buf[10] = 0x00;
1331 5391d806 bellard
                    buf[11] = 0x00;
1332 3b46e624 ths
1333 d5b4eb40 aliguori
                    /* Claim PLAY_AUDIO capability (0x01) since some Linux
1334 d5b4eb40 aliguori
                       code checks for this to automount media. */
1335 d5b4eb40 aliguori
                    buf[12] = 0x71;
1336 5391d806 bellard
                    buf[13] = 3 << 5;
1337 5391d806 bellard
                    buf[14] = (1 << 0) | (1 << 3) | (1 << 5);
1338 caed8802 bellard
                    if (bdrv_is_locked(s->bs))
1339 5391d806 bellard
                        buf[6] |= 1 << 1;
1340 5391d806 bellard
                    buf[15] = 0x00;
1341 5391d806 bellard
                    cpu_to_ube16(&buf[16], 706);
1342 5391d806 bellard
                    buf[18] = 0;
1343 5391d806 bellard
                    buf[19] = 2;
1344 5391d806 bellard
                    cpu_to_ube16(&buf[20], 512);
1345 5391d806 bellard
                    cpu_to_ube16(&buf[22], 706);
1346 5391d806 bellard
                    buf[24] = 0;
1347 5391d806 bellard
                    buf[25] = 0;
1348 5391d806 bellard
                    buf[26] = 0;
1349 5391d806 bellard
                    buf[27] = 0;
1350 5391d806 bellard
                    ide_atapi_cmd_reply(s, 28, max_len);
1351 5391d806 bellard
                    break;
1352 5391d806 bellard
                default:
1353 5391d806 bellard
                    goto error_cmd;
1354 5391d806 bellard
                }
1355 5391d806 bellard
                break;
1356 5391d806 bellard
            case 1: /* changeable values */
1357 5391d806 bellard
                goto error_cmd;
1358 5391d806 bellard
            case 2: /* default values */
1359 5391d806 bellard
                goto error_cmd;
1360 5391d806 bellard
            default:
1361 5391d806 bellard
            case 3: /* saved values */
1362 5fafdf24 ths
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1363 5391d806 bellard
                                    ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
1364 5391d806 bellard
                break;
1365 5391d806 bellard
            }
1366 5391d806 bellard
        }
1367 5391d806 bellard
        break;
1368 5391d806 bellard
    case GPCMD_REQUEST_SENSE:
1369 5391d806 bellard
        max_len = packet[4];
1370 5391d806 bellard
        memset(buf, 0, 18);
1371 5391d806 bellard
        buf[0] = 0x70 | (1 << 7);
1372 5391d806 bellard
        buf[2] = s->sense_key;
1373 5391d806 bellard
        buf[7] = 10;
1374 5391d806 bellard
        buf[12] = s->asc;
1375 9118e7f0 aliguori
        if (s->sense_key == SENSE_UNIT_ATTENTION)
1376 9118e7f0 aliguori
            s->sense_key = SENSE_NONE;
1377 5391d806 bellard
        ide_atapi_cmd_reply(s, 18, max_len);
1378 5391d806 bellard
        break;
1379 5391d806 bellard
    case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
1380 caed8802 bellard
        if (bdrv_is_inserted(s->bs)) {
1381 caed8802 bellard
            bdrv_set_locked(s->bs, packet[4] & 1);
1382 5391d806 bellard
            ide_atapi_cmd_ok(s);
1383 5391d806 bellard
        } else {
1384 5fafdf24 ths
            ide_atapi_cmd_error(s, SENSE_NOT_READY,
1385 5391d806 bellard
                                ASC_MEDIUM_NOT_PRESENT);
1386 5391d806 bellard
        }
1387 5391d806 bellard
        break;
1388 5391d806 bellard
    case GPCMD_READ_10:
1389 5391d806 bellard
    case GPCMD_READ_12:
1390 5391d806 bellard
        {
1391 5391d806 bellard
            int nb_sectors, lba;
1392 5391d806 bellard
1393 5391d806 bellard
            if (packet[0] == GPCMD_READ_10)
1394 5391d806 bellard
                nb_sectors = ube16_to_cpu(packet + 7);
1395 5391d806 bellard
            else
1396 5391d806 bellard
                nb_sectors = ube32_to_cpu(packet + 6);
1397 5391d806 bellard
            lba = ube32_to_cpu(packet + 2);
1398 5391d806 bellard
            if (nb_sectors == 0) {
1399 5391d806 bellard
                ide_atapi_cmd_ok(s);
1400 5391d806 bellard
                break;
1401 5391d806 bellard
            }
1402 98087450 bellard
            ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
1403 98087450 bellard
        }
1404 98087450 bellard
        break;
1405 98087450 bellard
    case GPCMD_READ_CD:
1406 98087450 bellard
        {
1407 98087450 bellard
            int nb_sectors, lba, transfer_request;
1408 98087450 bellard
1409 98087450 bellard
            nb_sectors = (packet[6] << 16) | (packet[7] << 8) | packet[8];
1410 98087450 bellard
            lba = ube32_to_cpu(packet + 2);
1411 98087450 bellard
            if (nb_sectors == 0) {
1412 98087450 bellard
                ide_atapi_cmd_ok(s);
1413 98087450 bellard
                break;
1414 98087450 bellard
            }
1415 98087450 bellard
            transfer_request = packet[9];
1416 98087450 bellard
            switch(transfer_request & 0xf8) {
1417 98087450 bellard
            case 0x00:
1418 98087450 bellard
                /* nothing */
1419 98087450 bellard
                ide_atapi_cmd_ok(s);
1420 98087450 bellard
                break;
1421 98087450 bellard
            case 0x10:
1422 98087450 bellard
                /* normal read */
1423 98087450 bellard
                ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
1424 98087450 bellard
                break;
1425 98087450 bellard
            case 0xf8:
1426 98087450 bellard
                /* read all data */
1427 98087450 bellard
                ide_atapi_cmd_read(s, lba, nb_sectors, 2352);
1428 98087450 bellard
                break;
1429 98087450 bellard
            default:
1430 5fafdf24 ths
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1431 98087450 bellard
                                    ASC_INV_FIELD_IN_CMD_PACKET);
1432 98087450 bellard
                break;
1433 98087450 bellard
            }
1434 5391d806 bellard
        }
1435 5391d806 bellard
        break;
1436 5391d806 bellard
    case GPCMD_SEEK:
1437 5391d806 bellard
        {
1438 96b8f136 ths
            unsigned int lba;
1439 96b8f136 ths
            uint64_t total_sectors;
1440 66c6ef76 bellard
1441 66c6ef76 bellard
            bdrv_get_geometry(s->bs, &total_sectors);
1442 66c6ef76 bellard
            total_sectors >>= 2;
1443 96b8f136 ths
            if (total_sectors == 0) {
1444 5fafdf24 ths
                ide_atapi_cmd_error(s, SENSE_NOT_READY,
1445 5391d806 bellard
                                    ASC_MEDIUM_NOT_PRESENT);
1446 5391d806 bellard
                break;
1447 5391d806 bellard
            }
1448 5391d806 bellard
            lba = ube32_to_cpu(packet + 2);
1449 66c6ef76 bellard
            if (lba >= total_sectors) {
1450 5fafdf24 ths
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1451 5391d806 bellard
                                    ASC_LOGICAL_BLOCK_OOR);
1452 5391d806 bellard
                break;
1453 5391d806 bellard
            }
1454 5391d806 bellard
            ide_atapi_cmd_ok(s);
1455 5391d806 bellard
        }
1456 5391d806 bellard
        break;
1457 5391d806 bellard
    case GPCMD_START_STOP_UNIT:
1458 5391d806 bellard
        {
1459 aea2a33c Mark McLoughlin
            int start, eject, err = 0;
1460 5391d806 bellard
            start = packet[4] & 1;
1461 5391d806 bellard
            eject = (packet[4] >> 1) & 1;
1462 3b46e624 ths
1463 aea2a33c Mark McLoughlin
            if (eject) {
1464 aea2a33c Mark McLoughlin
                err = bdrv_eject(s->bs, !start);
1465 aea2a33c Mark McLoughlin
            }
1466 aea2a33c Mark McLoughlin
1467 aea2a33c Mark McLoughlin
            switch (err) {
1468 aea2a33c Mark McLoughlin
            case 0:
1469 aea2a33c Mark McLoughlin
                ide_atapi_cmd_ok(s);
1470 aea2a33c Mark McLoughlin
                break;
1471 aea2a33c Mark McLoughlin
            case -EBUSY:
1472 aea2a33c Mark McLoughlin
                ide_atapi_cmd_error(s, SENSE_NOT_READY,
1473 aea2a33c Mark McLoughlin
                                    ASC_MEDIA_REMOVAL_PREVENTED);
1474 aea2a33c Mark McLoughlin
                break;
1475 aea2a33c Mark McLoughlin
            default:
1476 aea2a33c Mark McLoughlin
                ide_atapi_cmd_error(s, SENSE_NOT_READY,
1477 aea2a33c Mark McLoughlin
                                    ASC_MEDIUM_NOT_PRESENT);
1478 aea2a33c Mark McLoughlin
                break;
1479 caed8802 bellard
            }
1480 5391d806 bellard
        }
1481 5391d806 bellard
        break;
1482 5391d806 bellard
    case GPCMD_MECHANISM_STATUS:
1483 5391d806 bellard
        {
1484 5391d806 bellard
            max_len = ube16_to_cpu(packet + 8);
1485 5391d806 bellard
            cpu_to_ube16(buf, 0);
1486 5391d806 bellard
            /* no current LBA */
1487 5391d806 bellard
            buf[2] = 0;
1488 5391d806 bellard
            buf[3] = 0;
1489 5391d806 bellard
            buf[4] = 0;
1490 5391d806 bellard
            buf[5] = 1;
1491 5391d806 bellard
            cpu_to_ube16(buf + 6, 0);
1492 5391d806 bellard
            ide_atapi_cmd_reply(s, 8, max_len);
1493 5391d806 bellard
        }
1494 5391d806 bellard
        break;
1495 5391d806 bellard
    case GPCMD_READ_TOC_PMA_ATIP:
1496 5391d806 bellard
        {
1497 5391d806 bellard
            int format, msf, start_track, len;
1498 96b8f136 ths
            uint64_t total_sectors;
1499 5391d806 bellard
1500 66c6ef76 bellard
            bdrv_get_geometry(s->bs, &total_sectors);
1501 66c6ef76 bellard
            total_sectors >>= 2;
1502 96b8f136 ths
            if (total_sectors == 0) {
1503 5fafdf24 ths
                ide_atapi_cmd_error(s, SENSE_NOT_READY,
1504 5391d806 bellard
                                    ASC_MEDIUM_NOT_PRESENT);
1505 5391d806 bellard
                break;
1506 5391d806 bellard
            }
1507 5391d806 bellard
            max_len = ube16_to_cpu(packet + 7);
1508 5391d806 bellard
            format = packet[9] >> 6;
1509 5391d806 bellard
            msf = (packet[1] >> 1) & 1;
1510 5391d806 bellard
            start_track = packet[6];
1511 5391d806 bellard
            switch(format) {
1512 5391d806 bellard
            case 0:
1513 66c6ef76 bellard
                len = cdrom_read_toc(total_sectors, buf, msf, start_track);
1514 5391d806 bellard
                if (len < 0)
1515 5391d806 bellard
                    goto error_cmd;
1516 5391d806 bellard
                ide_atapi_cmd_reply(s, len, max_len);
1517 5391d806 bellard
                break;
1518 5391d806 bellard
            case 1:
1519 5391d806 bellard
                /* multi session : only a single session defined */
1520 5391d806 bellard
                memset(buf, 0, 12);
1521 5391d806 bellard
                buf[1] = 0x0a;
1522 5391d806 bellard
                buf[2] = 0x01;
1523 5391d806 bellard
                buf[3] = 0x01;
1524 5391d806 bellard
                ide_atapi_cmd_reply(s, 12, max_len);
1525 5391d806 bellard
                break;
1526 98087450 bellard
            case 2:
1527 66c6ef76 bellard
                len = cdrom_read_toc_raw(total_sectors, buf, msf, start_track);
1528 98087450 bellard
                if (len < 0)
1529 98087450 bellard
                    goto error_cmd;
1530 98087450 bellard
                ide_atapi_cmd_reply(s, len, max_len);
1531 98087450 bellard
                break;
1532 5391d806 bellard
            default:
1533 7f777bf3 bellard
            error_cmd:
1534 5fafdf24 ths
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1535 7f777bf3 bellard
                                    ASC_INV_FIELD_IN_CMD_PACKET);
1536 7f777bf3 bellard
                break;
1537 5391d806 bellard
            }
1538 5391d806 bellard
        }
1539 5391d806 bellard
        break;
1540 5391d806 bellard
    case GPCMD_READ_CDVD_CAPACITY:
1541 66c6ef76 bellard
        {
1542 96b8f136 ths
            uint64_t total_sectors;
1543 66c6ef76 bellard
1544 66c6ef76 bellard
            bdrv_get_geometry(s->bs, &total_sectors);
1545 66c6ef76 bellard
            total_sectors >>= 2;
1546 96b8f136 ths
            if (total_sectors == 0) {
1547 5fafdf24 ths
                ide_atapi_cmd_error(s, SENSE_NOT_READY,
1548 66c6ef76 bellard
                                    ASC_MEDIUM_NOT_PRESENT);
1549 66c6ef76 bellard
                break;
1550 66c6ef76 bellard
            }
1551 66c6ef76 bellard
            /* NOTE: it is really the number of sectors minus 1 */
1552 66c6ef76 bellard
            cpu_to_ube32(buf, total_sectors - 1);
1553 66c6ef76 bellard
            cpu_to_ube32(buf + 4, 2048);
1554 66c6ef76 bellard
            ide_atapi_cmd_reply(s, 8, 8);
1555 5391d806 bellard
        }
1556 5391d806 bellard
        break;
1557 d14049ea ths
    case GPCMD_READ_DVD_STRUCTURE:
1558 d14049ea ths
        {
1559 d14049ea ths
            int media = packet[1];
1560 8114e9e8 ths
            int format = packet[7];
1561 8114e9e8 ths
            int ret;
1562 d14049ea ths
1563 8114e9e8 ths
            max_len = ube16_to_cpu(packet + 8);
1564 d14049ea ths
1565 8114e9e8 ths
            if (format < 0xff) {
1566 8114e9e8 ths
                if (media_is_cd(s)) {
1567 8114e9e8 ths
                    ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1568 8114e9e8 ths
                                        ASC_INCOMPATIBLE_FORMAT);
1569 8114e9e8 ths
                    break;
1570 8114e9e8 ths
                } else if (!media_present(s)) {
1571 8114e9e8 ths
                    ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1572 8114e9e8 ths
                                        ASC_INV_FIELD_IN_CMD_PACKET);
1573 8114e9e8 ths
                    break;
1574 8114e9e8 ths
                }
1575 8114e9e8 ths
            }
1576 d14049ea ths
1577 8114e9e8 ths
            memset(buf, 0, max_len > IDE_DMA_BUF_SECTORS * 512 + 4 ?
1578 8114e9e8 ths
                   IDE_DMA_BUF_SECTORS * 512 + 4 : max_len);
1579 d14049ea ths
1580 8114e9e8 ths
            switch (format) {
1581 8114e9e8 ths
                case 0x00 ... 0x7f:
1582 8114e9e8 ths
                case 0xff:
1583 8114e9e8 ths
                    if (media == 0) {
1584 8114e9e8 ths
                        ret = ide_dvd_read_structure(s, format, packet, buf);
1585 d14049ea ths
1586 8114e9e8 ths
                        if (ret < 0)
1587 8114e9e8 ths
                            ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, -ret);
1588 8114e9e8 ths
                        else
1589 8114e9e8 ths
                            ide_atapi_cmd_reply(s, ret, max_len);
1590 d14049ea ths
1591 8114e9e8 ths
                        break;
1592 8114e9e8 ths
                    }
1593 8114e9e8 ths
                    /* TODO: BD support, fall through for now */
1594 8114e9e8 ths
1595 8114e9e8 ths
                /* Generic disk structures */
1596 8114e9e8 ths
                case 0x80: /* TODO: AACS volume identifier */
1597 8114e9e8 ths
                case 0x81: /* TODO: AACS media serial number */
1598 8114e9e8 ths
                case 0x82: /* TODO: AACS media identifier */
1599 8114e9e8 ths
                case 0x83: /* TODO: AACS media key block */
1600 8114e9e8 ths
                case 0x90: /* TODO: List of recognized format layers */
1601 8114e9e8 ths
                case 0xc0: /* TODO: Write protection status */
1602 d14049ea ths
                default:
1603 d14049ea ths
                    ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1604 d14049ea ths
                                        ASC_INV_FIELD_IN_CMD_PACKET);
1605 d14049ea ths
                    break;
1606 d14049ea ths
            }
1607 d14049ea ths
        }
1608 d14049ea ths
        break;
1609 d14049ea ths
    case GPCMD_SET_SPEED:
1610 d14049ea ths
        ide_atapi_cmd_ok(s);
1611 d14049ea ths
        break;
1612 bd0d90b2 bellard
    case GPCMD_INQUIRY:
1613 bd0d90b2 bellard
        max_len = packet[4];
1614 bd0d90b2 bellard
        buf[0] = 0x05; /* CD-ROM */
1615 bd0d90b2 bellard
        buf[1] = 0x80; /* removable */
1616 bd0d90b2 bellard
        buf[2] = 0x00; /* ISO */
1617 bd0d90b2 bellard
        buf[3] = 0x21; /* ATAPI-2 (XXX: put ATAPI-4 ?) */
1618 aa1f17c1 ths
        buf[4] = 31; /* additional length */
1619 bd0d90b2 bellard
        buf[5] = 0; /* reserved */
1620 bd0d90b2 bellard
        buf[6] = 0; /* reserved */
1621 bd0d90b2 bellard
        buf[7] = 0; /* reserved */
1622 bd0d90b2 bellard
        padstr8(buf + 8, 8, "QEMU");
1623 38cdea7c balrog
        padstr8(buf + 16, 16, "QEMU DVD-ROM");
1624 47c06340 Gerd Hoffmann
        padstr8(buf + 32, 4, s->version);
1625 bd0d90b2 bellard
        ide_atapi_cmd_reply(s, 36, max_len);
1626 bd0d90b2 bellard
        break;
1627 d14049ea ths
    case GPCMD_GET_CONFIGURATION:
1628 d14049ea ths
        {
1629 38cdea7c balrog
            uint32_t len;
1630 091d055b balrog
            uint8_t index = 0;
1631 d14049ea ths
1632 d14049ea ths
            /* only feature 0 is supported */
1633 d14049ea ths
            if (packet[2] != 0 || packet[3] != 0) {
1634 d14049ea ths
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1635 d14049ea ths
                                    ASC_INV_FIELD_IN_CMD_PACKET);
1636 d14049ea ths
                break;
1637 d14049ea ths
            }
1638 38cdea7c balrog
1639 38cdea7c balrog
            /* XXX: could result in alignment problems in some architectures */
1640 38cdea7c balrog
            max_len = ube16_to_cpu(packet + 7);
1641 091d055b balrog
1642 38cdea7c balrog
            /*
1643 091d055b balrog
             * XXX: avoid overflow for io_buffer if max_len is bigger than
1644 091d055b balrog
             *      the size of that buffer (dimensioned to max number of
1645 091d055b balrog
             *      sectors to transfer at once)
1646 38cdea7c balrog
             *
1647 091d055b balrog
             *      Only a problem if the feature/profiles grow.
1648 38cdea7c balrog
             */
1649 38cdea7c balrog
            if (max_len > 512) /* XXX: assume 1 sector */
1650 38cdea7c balrog
                max_len = 512;
1651 38cdea7c balrog
1652 38cdea7c balrog
            memset(buf, 0, max_len);
1653 38cdea7c balrog
            /* 
1654 38cdea7c balrog
             * the number of sectors from the media tells us which profile
1655 38cdea7c balrog
             * to use as current.  0 means there is no media
1656 38cdea7c balrog
             */
1657 8114e9e8 ths
            if (media_is_dvd(s))
1658 8114e9e8 ths
                cpu_to_ube16(buf + 6, MMC_PROFILE_DVD_ROM);
1659 8114e9e8 ths
            else if (media_is_cd(s))
1660 8114e9e8 ths
                cpu_to_ube16(buf + 6, MMC_PROFILE_CD_ROM);
1661 38cdea7c balrog
1662 091d055b balrog
            buf[10] = 0x02 | 0x01; /* persistent and current */
1663 091d055b balrog
            len = 12; /* headers: 8 + 4 */
1664 091d055b balrog
            len += ide_atapi_set_profile(buf, &index, MMC_PROFILE_DVD_ROM);
1665 091d055b balrog
            len += ide_atapi_set_profile(buf, &index, MMC_PROFILE_CD_ROM);
1666 38cdea7c balrog
            cpu_to_ube32(buf, len - 4); /* data length */
1667 38cdea7c balrog
1668 38cdea7c balrog
            ide_atapi_cmd_reply(s, len, max_len);
1669 d14049ea ths
            break;
1670 d14049ea ths
        }
1671 253cb7b9 Aurelien Jarno
    case GPCMD_GET_EVENT_STATUS_NOTIFICATION:
1672 253cb7b9 Aurelien Jarno
        max_len = ube16_to_cpu(packet + 7);
1673 253cb7b9 Aurelien Jarno
1674 253cb7b9 Aurelien Jarno
        if (packet[1] & 0x01) { /* polling */
1675 253cb7b9 Aurelien Jarno
            /* We don't support any event class (yet). */
1676 253cb7b9 Aurelien Jarno
            cpu_to_ube16(buf, 0x00); /* No event descriptor returned */
1677 253cb7b9 Aurelien Jarno
            buf[2] = 0x80;           /* No Event Available (NEA) */
1678 253cb7b9 Aurelien Jarno
            buf[3] = 0x00;           /* Empty supported event classes */
1679 253cb7b9 Aurelien Jarno
            ide_atapi_cmd_reply(s, 4, max_len);
1680 253cb7b9 Aurelien Jarno
        } else { /* asynchronous mode */
1681 253cb7b9 Aurelien Jarno
            /* Only polling is supported, asynchronous mode is not. */
1682 253cb7b9 Aurelien Jarno
            ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1683 253cb7b9 Aurelien Jarno
                                ASC_INV_FIELD_IN_CMD_PACKET);
1684 253cb7b9 Aurelien Jarno
        }
1685 253cb7b9 Aurelien Jarno
        break;
1686 5391d806 bellard
    default:
1687 5fafdf24 ths
        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1688 7f777bf3 bellard
                            ASC_ILLEGAL_OPCODE);
1689 5391d806 bellard
        break;
1690 5391d806 bellard
    }
1691 5391d806 bellard
}
1692 5391d806 bellard
1693 201a51fc balrog
static void ide_cfata_metadata_inquiry(IDEState *s)
1694 201a51fc balrog
{
1695 201a51fc balrog
    uint16_t *p;
1696 201a51fc balrog
    uint32_t spd;
1697 201a51fc balrog
1698 201a51fc balrog
    p = (uint16_t *) s->io_buffer;
1699 201a51fc balrog
    memset(p, 0, 0x200);
1700 201a51fc balrog
    spd = ((s->mdata_size - 1) >> 9) + 1;
1701 201a51fc balrog
1702 201a51fc balrog
    put_le16(p + 0, 0x0001);                        /* Data format revision */
1703 201a51fc balrog
    put_le16(p + 1, 0x0000);                        /* Media property: silicon */
1704 201a51fc balrog
    put_le16(p + 2, s->media_changed);                /* Media status */
1705 201a51fc balrog
    put_le16(p + 3, s->mdata_size & 0xffff);        /* Capacity in bytes (low) */
1706 201a51fc balrog
    put_le16(p + 4, s->mdata_size >> 16);        /* Capacity in bytes (high) */
1707 201a51fc balrog
    put_le16(p + 5, spd & 0xffff);                /* Sectors per device (low) */
1708 201a51fc balrog
    put_le16(p + 6, spd >> 16);                        /* Sectors per device (high) */
1709 201a51fc balrog
}
1710 201a51fc balrog
1711 201a51fc balrog
static void ide_cfata_metadata_read(IDEState *s)
1712 201a51fc balrog
{
1713 201a51fc balrog
    uint16_t *p;
1714 201a51fc balrog
1715 201a51fc balrog
    if (((s->hcyl << 16) | s->lcyl) << 9 > s->mdata_size + 2) {
1716 201a51fc balrog
        s->status = ERR_STAT;
1717 201a51fc balrog
        s->error = ABRT_ERR;
1718 201a51fc balrog
        return;
1719 201a51fc balrog
    }
1720 201a51fc balrog
1721 201a51fc balrog
    p = (uint16_t *) s->io_buffer;
1722 201a51fc balrog
    memset(p, 0, 0x200);
1723 201a51fc balrog
1724 201a51fc balrog
    put_le16(p + 0, s->media_changed);                /* Media status */
1725 201a51fc balrog
    memcpy(p + 1, s->mdata_storage + (((s->hcyl << 16) | s->lcyl) << 9),
1726 201a51fc balrog
                    MIN(MIN(s->mdata_size - (((s->hcyl << 16) | s->lcyl) << 9),
1727 201a51fc balrog
                                    s->nsector << 9), 0x200 - 2));
1728 201a51fc balrog
}
1729 201a51fc balrog
1730 201a51fc balrog
static void ide_cfata_metadata_write(IDEState *s)
1731 201a51fc balrog
{
1732 201a51fc balrog
    if (((s->hcyl << 16) | s->lcyl) << 9 > s->mdata_size + 2) {
1733 201a51fc balrog
        s->status = ERR_STAT;
1734 201a51fc balrog
        s->error = ABRT_ERR;
1735 201a51fc balrog
        return;
1736 201a51fc balrog
    }
1737 201a51fc balrog
1738 201a51fc balrog
    s->media_changed = 0;
1739 201a51fc balrog
1740 201a51fc balrog
    memcpy(s->mdata_storage + (((s->hcyl << 16) | s->lcyl) << 9),
1741 201a51fc balrog
                    s->io_buffer + 2,
1742 201a51fc balrog
                    MIN(MIN(s->mdata_size - (((s->hcyl << 16) | s->lcyl) << 9),
1743 201a51fc balrog
                                    s->nsector << 9), 0x200 - 2));
1744 201a51fc balrog
}
1745 201a51fc balrog
1746 bd491d6a ths
/* called when the inserted state of the media has changed */
1747 bd491d6a ths
static void cdrom_change_cb(void *opaque)
1748 bd491d6a ths
{
1749 bd491d6a ths
    IDEState *s = opaque;
1750 96b8f136 ths
    uint64_t nb_sectors;
1751 bd491d6a ths
1752 bd491d6a ths
    bdrv_get_geometry(s->bs, &nb_sectors);
1753 bd491d6a ths
    s->nb_sectors = nb_sectors;
1754 9118e7f0 aliguori
1755 9118e7f0 aliguori
    s->sense_key = SENSE_UNIT_ATTENTION;
1756 9118e7f0 aliguori
    s->asc = ASC_MEDIUM_MAY_HAVE_CHANGED;
1757 93c8cfd9 Gleb Natapov
    s->cdrom_changed = 1;
1758 9cdd03a7 Gerd Hoffmann
    ide_set_irq(s->bus);
1759 bd491d6a ths
}
1760 bd491d6a ths
1761 c2ff060f bellard
static void ide_cmd_lba48_transform(IDEState *s, int lba48)
1762 c2ff060f bellard
{
1763 c2ff060f bellard
    s->lba48 = lba48;
1764 c2ff060f bellard
1765 c2ff060f bellard
    /* handle the 'magic' 0 nsector count conversion here. to avoid
1766 c2ff060f bellard
     * fiddling with the rest of the read logic, we just store the
1767 c2ff060f bellard
     * full sector count in ->nsector and ignore ->hob_nsector from now
1768 c2ff060f bellard
     */
1769 c2ff060f bellard
    if (!s->lba48) {
1770 c2ff060f bellard
        if (!s->nsector)
1771 c2ff060f bellard
            s->nsector = 256;
1772 c2ff060f bellard
    } else {
1773 c2ff060f bellard
        if (!s->nsector && !s->hob_nsector)
1774 c2ff060f bellard
            s->nsector = 65536;
1775 c2ff060f bellard
        else {
1776 c2ff060f bellard
            int lo = s->nsector;
1777 c2ff060f bellard
            int hi = s->hob_nsector;
1778 c2ff060f bellard
1779 c2ff060f bellard
            s->nsector = (hi << 8) | lo;
1780 c2ff060f bellard
        }
1781 c2ff060f bellard
    }
1782 c2ff060f bellard
}
1783 c2ff060f bellard
1784 bcbdc4d3 Gerd Hoffmann
static void ide_clear_hob(IDEBus *bus)
1785 c2ff060f bellard
{
1786 c2ff060f bellard
    /* any write clears HOB high bit of device control register */
1787 bcbdc4d3 Gerd Hoffmann
    bus->ifs[0].select &= ~(1 << 7);
1788 bcbdc4d3 Gerd Hoffmann
    bus->ifs[1].select &= ~(1 << 7);
1789 c2ff060f bellard
}
1790 c2ff060f bellard
1791 356721ae Gerd Hoffmann
void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
1792 caed8802 bellard
{
1793 bcbdc4d3 Gerd Hoffmann
    IDEBus *bus = opaque;
1794 c45c3d00 bellard
    IDEState *s;
1795 bcbdc4d3 Gerd Hoffmann
    int n;
1796 c2ff060f bellard
    int lba48 = 0;
1797 5391d806 bellard
1798 5391d806 bellard
#ifdef DEBUG_IDE
1799 5391d806 bellard
    printf("IDE: write addr=0x%x val=0x%02x\n", addr, val);
1800 5391d806 bellard
#endif
1801 c2ff060f bellard
1802 5391d806 bellard
    addr &= 7;
1803 fcdd25ab aliguori
1804 fcdd25ab aliguori
    /* ignore writes to command block while busy with previous command */
1805 bcbdc4d3 Gerd Hoffmann
    if (addr != 7 && (idebus_active_if(bus)->status & (BUSY_STAT|DRQ_STAT)))
1806 fcdd25ab aliguori
        return;
1807 fcdd25ab aliguori
1808 5391d806 bellard
    switch(addr) {
1809 5391d806 bellard
    case 0:
1810 5391d806 bellard
        break;
1811 5391d806 bellard
    case 1:
1812 bcbdc4d3 Gerd Hoffmann
        ide_clear_hob(bus);
1813 c45c3d00 bellard
        /* NOTE: data is written to the two drives */
1814 bcbdc4d3 Gerd Hoffmann
        bus->ifs[0].hob_feature = bus->ifs[0].feature;
1815 bcbdc4d3 Gerd Hoffmann
        bus->ifs[1].hob_feature = bus->ifs[1].feature;
1816 bcbdc4d3 Gerd Hoffmann
        bus->ifs[0].feature = val;
1817 bcbdc4d3 Gerd Hoffmann
        bus->ifs[1].feature = val;
1818 5391d806 bellard
        break;
1819 5391d806 bellard
    case 2:
1820 bcbdc4d3 Gerd Hoffmann
        ide_clear_hob(bus);
1821 bcbdc4d3 Gerd Hoffmann
        bus->ifs[0].hob_nsector = bus->ifs[0].nsector;
1822 bcbdc4d3 Gerd Hoffmann
        bus->ifs[1].hob_nsector = bus->ifs[1].nsector;
1823 bcbdc4d3 Gerd Hoffmann
        bus->ifs[0].nsector = val;
1824 bcbdc4d3 Gerd Hoffmann
        bus->ifs[1].nsector = val;
1825 5391d806 bellard
        break;
1826 5391d806 bellard
    case 3:
1827 bcbdc4d3 Gerd Hoffmann
        ide_clear_hob(bus);
1828 bcbdc4d3 Gerd Hoffmann
        bus->ifs[0].hob_sector = bus->ifs[0].sector;
1829 bcbdc4d3 Gerd Hoffmann
        bus->ifs[1].hob_sector = bus->ifs[1].sector;
1830 bcbdc4d3 Gerd Hoffmann
        bus->ifs[0].sector = val;
1831 bcbdc4d3 Gerd Hoffmann
        bus->ifs[1].sector = val;
1832 5391d806 bellard
        break;
1833 5391d806 bellard
    case 4:
1834 bcbdc4d3 Gerd Hoffmann
        ide_clear_hob(bus);
1835 bcbdc4d3 Gerd Hoffmann
        bus->ifs[0].hob_lcyl = bus->ifs[0].lcyl;
1836 bcbdc4d3 Gerd Hoffmann
        bus->ifs[1].hob_lcyl = bus->ifs[1].lcyl;
1837 bcbdc4d3 Gerd Hoffmann
        bus->ifs[0].lcyl = val;
1838 bcbdc4d3 Gerd Hoffmann
        bus->ifs[1].lcyl = val;
1839 5391d806 bellard
        break;
1840 5391d806 bellard
    case 5:
1841 bcbdc4d3 Gerd Hoffmann
        ide_clear_hob(bus);
1842 bcbdc4d3 Gerd Hoffmann
        bus->ifs[0].hob_hcyl = bus->ifs[0].hcyl;
1843 bcbdc4d3 Gerd Hoffmann
        bus->ifs[1].hob_hcyl = bus->ifs[1].hcyl;
1844 bcbdc4d3 Gerd Hoffmann
        bus->ifs[0].hcyl = val;
1845 bcbdc4d3 Gerd Hoffmann
        bus->ifs[1].hcyl = val;
1846 5391d806 bellard
        break;
1847 5391d806 bellard
    case 6:
1848 c2ff060f bellard
        /* FIXME: HOB readback uses bit 7 */
1849 bcbdc4d3 Gerd Hoffmann
        bus->ifs[0].select = (val & ~0x10) | 0xa0;
1850 bcbdc4d3 Gerd Hoffmann
        bus->ifs[1].select = (val | 0x10) | 0xa0;
1851 5391d806 bellard
        /* select drive */
1852 bcbdc4d3 Gerd Hoffmann
        bus->unit = (val >> 4) & 1;
1853 5391d806 bellard
        break;
1854 5391d806 bellard
    default:
1855 5391d806 bellard
    case 7:
1856 5391d806 bellard
        /* command */
1857 5391d806 bellard
#if defined(DEBUG_IDE)
1858 5391d806 bellard
        printf("ide: CMD=%02x\n", val);
1859 5391d806 bellard
#endif
1860 bcbdc4d3 Gerd Hoffmann
        s = idebus_active_if(bus);
1861 66201e2d bellard
        /* ignore commands to non existant slave */
1862 bcbdc4d3 Gerd Hoffmann
        if (s != bus->ifs && !s->bs)
1863 66201e2d bellard
            break;
1864 c2ff060f bellard
1865 fcdd25ab aliguori
        /* Only DEVICE RESET is allowed while BSY or/and DRQ are set */
1866 fcdd25ab aliguori
        if ((s->status & (BUSY_STAT|DRQ_STAT)) && val != WIN_DEVICE_RESET)
1867 fcdd25ab aliguori
            break;
1868 fcdd25ab aliguori
1869 5391d806 bellard
        switch(val) {
1870 5391d806 bellard
        case WIN_IDENTIFY:
1871 cd8722bb Markus Armbruster
            if (s->bs && s->drive_kind != IDE_CD) {
1872 cd8722bb Markus Armbruster
                if (s->drive_kind != IDE_CFATA)
1873 201a51fc balrog
                    ide_identify(s);
1874 201a51fc balrog
                else
1875 201a51fc balrog
                    ide_cfata_identify(s);
1876 2a282056 bellard
                s->status = READY_STAT | SEEK_STAT;
1877 5391d806 bellard
                ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
1878 5391d806 bellard
            } else {
1879 cd8722bb Markus Armbruster
                if (s->drive_kind == IDE_CD) {
1880 5391d806 bellard
                    ide_set_signature(s);
1881 5391d806 bellard
                }
1882 5391d806 bellard
                ide_abort_command(s);
1883 5391d806 bellard
            }
1884 9cdd03a7 Gerd Hoffmann
            ide_set_irq(s->bus);
1885 5391d806 bellard
            break;
1886 5391d806 bellard
        case WIN_SPECIFY:
1887 5391d806 bellard
        case WIN_RECAL:
1888 a136e5a8 bellard
            s->error = 0;
1889 769bec72 bellard
            s->status = READY_STAT | SEEK_STAT;
1890 9cdd03a7 Gerd Hoffmann
            ide_set_irq(s->bus);
1891 5391d806 bellard
            break;
1892 5391d806 bellard
        case WIN_SETMULT:
1893 cd8722bb Markus Armbruster
            if (s->drive_kind == IDE_CFATA && s->nsector == 0) {
1894 201a51fc balrog
                /* Disable Read and Write Multiple */
1895 201a51fc balrog
                s->mult_sectors = 0;
1896 41a2b959 aliguori
                s->status = READY_STAT | SEEK_STAT;
1897 201a51fc balrog
            } else if ((s->nsector & 0xff) != 0 &&
1898 39dfc926 ths
                ((s->nsector & 0xff) > MAX_MULT_SECTORS ||
1899 39dfc926 ths
                 (s->nsector & (s->nsector - 1)) != 0)) {
1900 5391d806 bellard
                ide_abort_command(s);
1901 5391d806 bellard
            } else {
1902 292eef5a ths
                s->mult_sectors = s->nsector & 0xff;
1903 41a2b959 aliguori
                s->status = READY_STAT | SEEK_STAT;
1904 5391d806 bellard
            }
1905 9cdd03a7 Gerd Hoffmann
            ide_set_irq(s->bus);
1906 5391d806 bellard
            break;
1907 c2ff060f bellard
        case WIN_VERIFY_EXT:
1908 c2ff060f bellard
            lba48 = 1;
1909 4ce900b4 bellard
        case WIN_VERIFY:
1910 4ce900b4 bellard
        case WIN_VERIFY_ONCE:
1911 4ce900b4 bellard
            /* do sector number check ? */
1912 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1913 41a2b959 aliguori
            s->status = READY_STAT | SEEK_STAT;
1914 9cdd03a7 Gerd Hoffmann
            ide_set_irq(s->bus);
1915 4ce900b4 bellard
            break;
1916 c2ff060f bellard
        case WIN_READ_EXT:
1917 c2ff060f bellard
            lba48 = 1;
1918 5391d806 bellard
        case WIN_READ:
1919 5391d806 bellard
        case WIN_READ_ONCE:
1920 5fafdf24 ths
            if (!s->bs)
1921 6b136f9e bellard
                goto abort_cmd;
1922 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1923 5391d806 bellard
            s->req_nb_sectors = 1;
1924 5391d806 bellard
            ide_sector_read(s);
1925 5391d806 bellard
            break;
1926 c2ff060f bellard
        case WIN_WRITE_EXT:
1927 c2ff060f bellard
            lba48 = 1;
1928 5391d806 bellard
        case WIN_WRITE:
1929 5391d806 bellard
        case WIN_WRITE_ONCE:
1930 201a51fc balrog
        case CFA_WRITE_SECT_WO_ERASE:
1931 201a51fc balrog
        case WIN_WRITE_VERIFY:
1932 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1933 a136e5a8 bellard
            s->error = 0;
1934 f66723fa bellard
            s->status = SEEK_STAT | READY_STAT;
1935 5391d806 bellard
            s->req_nb_sectors = 1;
1936 5391d806 bellard
            ide_transfer_start(s, s->io_buffer, 512, ide_sector_write);
1937 201a51fc balrog
            s->media_changed = 1;
1938 5391d806 bellard
            break;
1939 c2ff060f bellard
        case WIN_MULTREAD_EXT:
1940 c2ff060f bellard
            lba48 = 1;
1941 5391d806 bellard
        case WIN_MULTREAD:
1942 5391d806 bellard
            if (!s->mult_sectors)
1943 5391d806 bellard
                goto abort_cmd;
1944 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1945 5391d806 bellard
            s->req_nb_sectors = s->mult_sectors;
1946 5391d806 bellard
            ide_sector_read(s);
1947 5391d806 bellard
            break;
1948 c2ff060f bellard
        case WIN_MULTWRITE_EXT:
1949 c2ff060f bellard
            lba48 = 1;
1950 5391d806 bellard
        case WIN_MULTWRITE:
1951 201a51fc balrog
        case CFA_WRITE_MULTI_WO_ERASE:
1952 5391d806 bellard
            if (!s->mult_sectors)
1953 5391d806 bellard
                goto abort_cmd;
1954 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1955 a136e5a8 bellard
            s->error = 0;
1956 f66723fa bellard
            s->status = SEEK_STAT | READY_STAT;
1957 5391d806 bellard
            s->req_nb_sectors = s->mult_sectors;
1958 5391d806 bellard
            n = s->nsector;
1959 5391d806 bellard
            if (n > s->req_nb_sectors)
1960 5391d806 bellard
                n = s->req_nb_sectors;
1961 5391d806 bellard
            ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
1962 201a51fc balrog
            s->media_changed = 1;
1963 5391d806 bellard
            break;
1964 c2ff060f bellard
        case WIN_READDMA_EXT:
1965 c2ff060f bellard
            lba48 = 1;
1966 98087450 bellard
        case WIN_READDMA:
1967 98087450 bellard
        case WIN_READDMA_ONCE:
1968 5fafdf24 ths
            if (!s->bs)
1969 98087450 bellard
                goto abort_cmd;
1970 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1971 98087450 bellard
            ide_sector_read_dma(s);
1972 98087450 bellard
            break;
1973 c2ff060f bellard
        case WIN_WRITEDMA_EXT:
1974 c2ff060f bellard
            lba48 = 1;
1975 98087450 bellard
        case WIN_WRITEDMA:
1976 98087450 bellard
        case WIN_WRITEDMA_ONCE:
1977 5fafdf24 ths
            if (!s->bs)
1978 98087450 bellard
                goto abort_cmd;
1979 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1980 98087450 bellard
            ide_sector_write_dma(s);
1981 201a51fc balrog
            s->media_changed = 1;
1982 98087450 bellard
            break;
1983 c2ff060f bellard
        case WIN_READ_NATIVE_MAX_EXT:
1984 c2ff060f bellard
            lba48 = 1;
1985 5391d806 bellard
        case WIN_READ_NATIVE_MAX:
1986 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1987 5391d806 bellard
            ide_set_sector(s, s->nb_sectors - 1);
1988 41a2b959 aliguori
            s->status = READY_STAT | SEEK_STAT;
1989 9cdd03a7 Gerd Hoffmann
            ide_set_irq(s->bus);
1990 5391d806 bellard
            break;
1991 a136e5a8 bellard
        case WIN_CHECKPOWERMODE1:
1992 201a51fc balrog
        case WIN_CHECKPOWERMODE2:
1993 a136e5a8 bellard
            s->nsector = 0xff; /* device active or idle */
1994 41a2b959 aliguori
            s->status = READY_STAT | SEEK_STAT;
1995 9cdd03a7 Gerd Hoffmann
            ide_set_irq(s->bus);
1996 a136e5a8 bellard
            break;
1997 34e538ae bellard
        case WIN_SETFEATURES:
1998 34e538ae bellard
            if (!s->bs)
1999 34e538ae bellard
                goto abort_cmd;
2000 34e538ae bellard
            /* XXX: valid for CDROM ? */
2001 34e538ae bellard
            switch(s->feature) {
2002 e1f63470 ths
            case 0xcc: /* reverting to power-on defaults enable */
2003 e1f63470 ths
            case 0x66: /* reverting to power-on defaults disable */
2004 34e538ae bellard
            case 0x02: /* write cache enable */
2005 34e538ae bellard
            case 0x82: /* write cache disable */
2006 34e538ae bellard
            case 0xaa: /* read look-ahead enable */
2007 34e538ae bellard
            case 0x55: /* read look-ahead disable */
2008 201a51fc balrog
            case 0x05: /* set advanced power management mode */
2009 201a51fc balrog
            case 0x85: /* disable advanced power management mode */
2010 201a51fc balrog
            case 0x69: /* NOP */
2011 201a51fc balrog
            case 0x67: /* NOP */
2012 201a51fc balrog
            case 0x96: /* NOP */
2013 201a51fc balrog
            case 0x9a: /* NOP */
2014 c3e88d8c ths
            case 0x42: /* enable Automatic Acoustic Mode */
2015 c3e88d8c ths
            case 0xc2: /* disable Automatic Acoustic Mode */
2016 e0fe67aa bellard
                s->status = READY_STAT | SEEK_STAT;
2017 9cdd03a7 Gerd Hoffmann
                ide_set_irq(s->bus);
2018 34e538ae bellard
                break;
2019 94458802 bellard
            case 0x03: { /* set transfer mode */
2020 94458802 bellard
                uint8_t val = s->nsector & 0x07;
2021 96c35ceb Juan Quintela
                uint16_t *identify_data = (uint16_t *)s->identify_data;
2022 94458802 bellard
2023 94458802 bellard
                switch (s->nsector >> 3) {
2024 94458802 bellard
                    case 0x00: /* pio default */
2025 94458802 bellard
                    case 0x01: /* pio mode */
2026 96c35ceb Juan Quintela
                        put_le16(identify_data + 62,0x07);
2027 96c35ceb Juan Quintela
                        put_le16(identify_data + 63,0x07);
2028 96c35ceb Juan Quintela
                        put_le16(identify_data + 88,0x3f);
2029 d1b5c20d ths
                        break;
2030 d1b5c20d ths
                    case 0x02: /* sigle word dma mode*/
2031 96c35ceb Juan Quintela
                        put_le16(identify_data + 62,0x07 | (1 << (val + 8)));
2032 96c35ceb Juan Quintela
                        put_le16(identify_data + 63,0x07);
2033 96c35ceb Juan Quintela
                        put_le16(identify_data + 88,0x3f);
2034 94458802 bellard
                        break;
2035 94458802 bellard
                    case 0x04: /* mdma mode */
2036 96c35ceb Juan Quintela
                        put_le16(identify_data + 62,0x07);
2037 96c35ceb Juan Quintela
                        put_le16(identify_data + 63,0x07 | (1 << (val + 8)));
2038 96c35ceb Juan Quintela
                        put_le16(identify_data + 88,0x3f);
2039 94458802 bellard
                        break;
2040 94458802 bellard
                    case 0x08: /* udma mode */
2041 96c35ceb Juan Quintela
                        put_le16(identify_data + 62,0x07);
2042 96c35ceb Juan Quintela
                        put_le16(identify_data + 63,0x07);
2043 96c35ceb Juan Quintela
                        put_le16(identify_data + 88,0x3f | (1 << (val + 8)));
2044 94458802 bellard
                        break;
2045 94458802 bellard
                    default:
2046 94458802 bellard
                        goto abort_cmd;
2047 94458802 bellard
                }
2048 94458802 bellard
                s->status = READY_STAT | SEEK_STAT;
2049 9cdd03a7 Gerd Hoffmann
                ide_set_irq(s->bus);
2050 94458802 bellard
                break;
2051 94458802 bellard
            }
2052 34e538ae bellard
            default:
2053 34e538ae bellard
                goto abort_cmd;
2054 34e538ae bellard
            }
2055 34e538ae bellard
            break;
2056 c2ff060f bellard
        case WIN_FLUSH_CACHE:
2057 c2ff060f bellard
        case WIN_FLUSH_CACHE_EXT:
2058 6bcb1a79 Kevin Wolf
            ide_flush_cache(s);
2059 7a6cba61 pbrook
            break;
2060 c3e88d8c ths
        case WIN_STANDBY:
2061 c3e88d8c ths
        case WIN_STANDBY2:
2062 c3e88d8c ths
        case WIN_STANDBYNOW1:
2063 201a51fc balrog
        case WIN_STANDBYNOW2:
2064 c451ee71 bellard
        case WIN_IDLEIMMEDIATE:
2065 201a51fc balrog
        case CFA_IDLEIMMEDIATE:
2066 201a51fc balrog
        case WIN_SETIDLE1:
2067 201a51fc balrog
        case WIN_SETIDLE2:
2068 c3e88d8c ths
        case WIN_SLEEPNOW1:
2069 c3e88d8c ths
        case WIN_SLEEPNOW2:
2070 c3e88d8c ths
            s->status = READY_STAT;
2071 9cdd03a7 Gerd Hoffmann
            ide_set_irq(s->bus);
2072 a7dfe172 bellard
            break;
2073 4fbfcd6d aurel32
        case WIN_SEEK:
2074 cd8722bb Markus Armbruster
            if(s->drive_kind == IDE_CD)
2075 4fbfcd6d aurel32
                goto abort_cmd;
2076 4fbfcd6d aurel32
            /* XXX: Check that seek is within bounds */
2077 4fbfcd6d aurel32
            s->status = READY_STAT | SEEK_STAT;
2078 9cdd03a7 Gerd Hoffmann
            ide_set_irq(s->bus);
2079 4fbfcd6d aurel32
            break;
2080 5391d806 bellard
            /* ATAPI commands */
2081 5391d806 bellard
        case WIN_PIDENTIFY:
2082 cd8722bb Markus Armbruster
            if (s->drive_kind == IDE_CD) {
2083 5391d806 bellard
                ide_atapi_identify(s);
2084 1298fe63 bellard
                s->status = READY_STAT | SEEK_STAT;
2085 5391d806 bellard
                ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
2086 5391d806 bellard
            } else {
2087 5391d806 bellard
                ide_abort_command(s);
2088 5391d806 bellard
            }
2089 9cdd03a7 Gerd Hoffmann
            ide_set_irq(s->bus);
2090 5391d806 bellard
            break;
2091 c451ee71 bellard
        case WIN_DIAGNOSE:
2092 c451ee71 bellard
            ide_set_signature(s);
2093 cd8722bb Markus Armbruster
            if (s->drive_kind == IDE_CD)
2094 33256a25 aliguori
                s->status = 0; /* ATAPI spec (v6) section 9.10 defines packet
2095 33256a25 aliguori
                                * devices to return a clear status register
2096 33256a25 aliguori
                                * with READY_STAT *not* set. */
2097 33256a25 aliguori
            else
2098 33256a25 aliguori
                s->status = READY_STAT | SEEK_STAT;
2099 33256a25 aliguori
            s->error = 0x01; /* Device 0 passed, Device 1 passed or not
2100 33256a25 aliguori
                              * present. 
2101 33256a25 aliguori
                              */
2102 9cdd03a7 Gerd Hoffmann
            ide_set_irq(s->bus);
2103 c451ee71 bellard
            break;
2104 5391d806 bellard
        case WIN_SRST:
2105 cd8722bb Markus Armbruster
            if (s->drive_kind != IDE_CD)
2106 5391d806 bellard
                goto abort_cmd;
2107 5391d806 bellard
            ide_set_signature(s);
2108 6b136f9e bellard
            s->status = 0x00; /* NOTE: READY is _not_ set */
2109 5391d806 bellard
            s->error = 0x01;
2110 5391d806 bellard
            break;
2111 5391d806 bellard
        case WIN_PACKETCMD:
2112 cd8722bb Markus Armbruster
            if (s->drive_kind != IDE_CD)
2113 5391d806 bellard
                goto abort_cmd;
2114 98087450 bellard
            /* overlapping commands not supported */
2115 98087450 bellard
            if (s->feature & 0x02)
2116 5391d806 bellard
                goto abort_cmd;
2117 41a2b959 aliguori
            s->status = READY_STAT | SEEK_STAT;
2118 98087450 bellard
            s->atapi_dma = s->feature & 1;
2119 5391d806 bellard
            s->nsector = 1;
2120 5fafdf24 ths
            ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE,
2121 5391d806 bellard
                               ide_atapi_cmd);
2122 5391d806 bellard
            break;
2123 201a51fc balrog
        /* CF-ATA commands */
2124 201a51fc balrog
        case CFA_REQ_EXT_ERROR_CODE:
2125 cd8722bb Markus Armbruster
            if (s->drive_kind != IDE_CFATA)
2126 201a51fc balrog
                goto abort_cmd;
2127 201a51fc balrog
            s->error = 0x09;    /* miscellaneous error */
2128 41a2b959 aliguori
            s->status = READY_STAT | SEEK_STAT;
2129 9cdd03a7 Gerd Hoffmann
            ide_set_irq(s->bus);
2130 201a51fc balrog
            break;
2131 201a51fc balrog
        case CFA_ERASE_SECTORS:
2132 201a51fc balrog
        case CFA_WEAR_LEVEL:
2133 cd8722bb Markus Armbruster
            if (s->drive_kind != IDE_CFATA)
2134 201a51fc balrog
                goto abort_cmd;
2135 201a51fc balrog
            if (val == CFA_WEAR_LEVEL)
2136 201a51fc balrog
                s->nsector = 0;
2137 201a51fc balrog
            if (val == CFA_ERASE_SECTORS)
2138 201a51fc balrog
                s->media_changed = 1;
2139 201a51fc balrog
            s->error = 0x00;
2140 41a2b959 aliguori
            s->status = READY_STAT | SEEK_STAT;
2141 9cdd03a7 Gerd Hoffmann
            ide_set_irq(s->bus);
2142 201a51fc balrog
            break;
2143 201a51fc balrog
        case CFA_TRANSLATE_SECTOR:
2144 cd8722bb Markus Armbruster
            if (s->drive_kind != IDE_CFATA)
2145 201a51fc balrog
                goto abort_cmd;
2146 201a51fc balrog
            s->error = 0x00;
2147 41a2b959 aliguori
            s->status = READY_STAT | SEEK_STAT;
2148 201a51fc balrog
            memset(s->io_buffer, 0, 0x200);
2149 201a51fc balrog
            s->io_buffer[0x00] = s->hcyl;                        /* Cyl MSB */
2150 201a51fc balrog
            s->io_buffer[0x01] = s->lcyl;                        /* Cyl LSB */
2151 201a51fc balrog
            s->io_buffer[0x02] = s->select;                        /* Head */
2152 201a51fc balrog
            s->io_buffer[0x03] = s->sector;                        /* Sector */
2153 201a51fc balrog
            s->io_buffer[0x04] = ide_get_sector(s) >> 16;        /* LBA MSB */
2154 201a51fc balrog
            s->io_buffer[0x05] = ide_get_sector(s) >> 8;        /* LBA */
2155 201a51fc balrog
            s->io_buffer[0x06] = ide_get_sector(s) >> 0;        /* LBA LSB */
2156 201a51fc balrog
            s->io_buffer[0x13] = 0x00;                                /* Erase flag */
2157 201a51fc balrog
            s->io_buffer[0x18] = 0x00;                                /* Hot count */
2158 201a51fc balrog
            s->io_buffer[0x19] = 0x00;                                /* Hot count */
2159 201a51fc balrog
            s->io_buffer[0x1a] = 0x01;                                /* Hot count */
2160 201a51fc balrog
            ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
2161 9cdd03a7 Gerd Hoffmann
            ide_set_irq(s->bus);
2162 201a51fc balrog
            break;
2163 201a51fc balrog
        case CFA_ACCESS_METADATA_STORAGE:
2164 cd8722bb Markus Armbruster
            if (s->drive_kind != IDE_CFATA)
2165 201a51fc balrog
                goto abort_cmd;
2166 201a51fc balrog
            switch (s->feature) {
2167 201a51fc balrog
            case 0x02:        /* Inquiry Metadata Storage */
2168 201a51fc balrog
                ide_cfata_metadata_inquiry(s);
2169 201a51fc balrog
                break;
2170 201a51fc balrog
            case 0x03:        /* Read Metadata Storage */
2171 201a51fc balrog
                ide_cfata_metadata_read(s);
2172 201a51fc balrog
                break;
2173 201a51fc balrog
            case 0x04:        /* Write Metadata Storage */
2174 201a51fc balrog
                ide_cfata_metadata_write(s);
2175 201a51fc balrog
                break;
2176 201a51fc balrog
            default:
2177 201a51fc balrog
                goto abort_cmd;
2178 201a51fc balrog
            }
2179 201a51fc balrog
            ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
2180 201a51fc balrog
            s->status = 0x00; /* NOTE: READY is _not_ set */
2181 9cdd03a7 Gerd Hoffmann
            ide_set_irq(s->bus);
2182 201a51fc balrog
            break;
2183 201a51fc balrog
        case IBM_SENSE_CONDITION:
2184 cd8722bb Markus Armbruster
            if (s->drive_kind != IDE_CFATA)
2185 201a51fc balrog
                goto abort_cmd;
2186 201a51fc balrog
            switch (s->feature) {
2187 201a51fc balrog
            case 0x01:  /* sense temperature in device */
2188 201a51fc balrog
                s->nsector = 0x50;      /* +20 C */
2189 201a51fc balrog
                break;
2190 201a51fc balrog
            default:
2191 201a51fc balrog
                goto abort_cmd;
2192 201a51fc balrog
            }
2193 41a2b959 aliguori
            s->status = READY_STAT | SEEK_STAT;
2194 9cdd03a7 Gerd Hoffmann
            ide_set_irq(s->bus);
2195 201a51fc balrog
            break;
2196 e8b54394 Brian Wheeler
2197 e8b54394 Brian Wheeler
        case WIN_SMART:
2198 cd8722bb Markus Armbruster
            if (s->drive_kind == IDE_CD)
2199 e8b54394 Brian Wheeler
                goto abort_cmd;
2200 e8b54394 Brian Wheeler
            if (s->hcyl != 0xc2 || s->lcyl != 0x4f)
2201 e8b54394 Brian Wheeler
                goto abort_cmd;
2202 e8b54394 Brian Wheeler
            if (!s->smart_enabled && s->feature != SMART_ENABLE)
2203 e8b54394 Brian Wheeler
                goto abort_cmd;
2204 e8b54394 Brian Wheeler
            switch (s->feature) {
2205 e8b54394 Brian Wheeler
            case SMART_DISABLE:
2206 e8b54394 Brian Wheeler
                s->smart_enabled = 0;
2207 e8b54394 Brian Wheeler
                s->status = READY_STAT | SEEK_STAT;
2208 9cdd03a7 Gerd Hoffmann
                ide_set_irq(s->bus);
2209 e8b54394 Brian Wheeler
                break;
2210 e8b54394 Brian Wheeler
            case SMART_ENABLE:
2211 e8b54394 Brian Wheeler
                s->smart_enabled = 1;
2212 e8b54394 Brian Wheeler
                s->status = READY_STAT | SEEK_STAT;
2213 9cdd03a7 Gerd Hoffmann
                ide_set_irq(s->bus);
2214 e8b54394 Brian Wheeler
                break;
2215 e8b54394 Brian Wheeler
            case SMART_ATTR_AUTOSAVE:
2216 e8b54394 Brian Wheeler
                switch (s->sector) {
2217 e8b54394 Brian Wheeler
                case 0x00:
2218 e8b54394 Brian Wheeler
                    s->smart_autosave = 0;
2219 e8b54394 Brian Wheeler
                    break;
2220 e8b54394 Brian Wheeler
                case 0xf1:
2221 e8b54394 Brian Wheeler
                    s->smart_autosave = 1;
2222 e8b54394 Brian Wheeler
                    break;
2223 e8b54394 Brian Wheeler
                default:
2224 e8b54394 Brian Wheeler
                    goto abort_cmd;
2225 e8b54394 Brian Wheeler
                }
2226 e8b54394 Brian Wheeler
                s->status = READY_STAT | SEEK_STAT;
2227 9cdd03a7 Gerd Hoffmann
                ide_set_irq(s->bus);
2228 e8b54394 Brian Wheeler
                break;
2229 e8b54394 Brian Wheeler
            case SMART_STATUS:
2230 e8b54394 Brian Wheeler
                if (!s->smart_errors) {
2231 e8b54394 Brian Wheeler
                    s->hcyl = 0xc2;
2232 e8b54394 Brian Wheeler
                    s->lcyl = 0x4f;
2233 e8b54394 Brian Wheeler
                } else {
2234 e8b54394 Brian Wheeler
                    s->hcyl = 0x2c;
2235 e8b54394 Brian Wheeler
                    s->lcyl = 0xf4;
2236 e8b54394 Brian Wheeler
                }
2237 e8b54394 Brian Wheeler
                s->status = READY_STAT | SEEK_STAT;
2238 9cdd03a7 Gerd Hoffmann
                ide_set_irq(s->bus);
2239 e8b54394 Brian Wheeler
                break;
2240 e8b54394 Brian Wheeler
            case SMART_READ_THRESH:
2241 e8b54394 Brian Wheeler
                memset(s->io_buffer, 0, 0x200);
2242 e8b54394 Brian Wheeler
                s->io_buffer[0] = 0x01; /* smart struct version */
2243 e8b54394 Brian Wheeler
                for (n=0; n<30; n++) {
2244 e8b54394 Brian Wheeler
                    if (smart_attributes[n][0] == 0)
2245 e8b54394 Brian Wheeler
                        break;
2246 e8b54394 Brian Wheeler
                    s->io_buffer[2+0+(n*12)] = smart_attributes[n][0];
2247 e8b54394 Brian Wheeler
                    s->io_buffer[2+1+(n*12)] = smart_attributes[n][4];
2248 e8b54394 Brian Wheeler
                }
2249 e8b54394 Brian Wheeler
                for (n=0; n<511; n++) /* checksum */
2250 e8b54394 Brian Wheeler
                    s->io_buffer[511] += s->io_buffer[n];
2251 e8b54394 Brian Wheeler
                s->io_buffer[511] = 0x100 - s->io_buffer[511];
2252 e8b54394 Brian Wheeler
                s->status = READY_STAT | SEEK_STAT;
2253 e8b54394 Brian Wheeler
                ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
2254 9cdd03a7 Gerd Hoffmann
                ide_set_irq(s->bus);
2255 e8b54394 Brian Wheeler
                break;
2256 e8b54394 Brian Wheeler
            case SMART_READ_DATA:
2257 e8b54394 Brian Wheeler
                memset(s->io_buffer, 0, 0x200);
2258 e8b54394 Brian Wheeler
                s->io_buffer[0] = 0x01; /* smart struct version */
2259 e8b54394 Brian Wheeler
                for (n=0; n<30; n++) {
2260 e8b54394 Brian Wheeler
                    if (smart_attributes[n][0] == 0)
2261 e8b54394 Brian Wheeler
                        break;
2262 e8b54394 Brian Wheeler
                    s->io_buffer[2+0+(n*12)] = smart_attributes[n][0];
2263 e8b54394 Brian Wheeler
                    s->io_buffer[2+1+(n*12)] = smart_attributes[n][1];
2264 e8b54394 Brian Wheeler
                    s->io_buffer[2+3+(n*12)] = smart_attributes[n][2];
2265 e8b54394 Brian Wheeler
                    s->io_buffer[2+4+(n*12)] = smart_attributes[n][3];
2266 e8b54394 Brian Wheeler
                }
2267 e8b54394 Brian Wheeler
                s->io_buffer[362] = 0x02 | (s->smart_autosave?0x80:0x00);
2268 e8b54394 Brian Wheeler
                if (s->smart_selftest_count == 0) {
2269 e8b54394 Brian Wheeler
                    s->io_buffer[363] = 0;
2270 e8b54394 Brian Wheeler
                } else {
2271 e8b54394 Brian Wheeler
                    s->io_buffer[363] = 
2272 e8b54394 Brian Wheeler
                        s->smart_selftest_data[3 + 
2273 e8b54394 Brian Wheeler
                                               (s->smart_selftest_count - 1) * 
2274 e8b54394 Brian Wheeler
                                               24];
2275 e8b54394 Brian Wheeler
                }
2276 e8b54394 Brian Wheeler
                s->io_buffer[364] = 0x20; 
2277 e8b54394 Brian Wheeler
                s->io_buffer[365] = 0x01; 
2278 e8b54394 Brian Wheeler
                /* offline data collection capacity: execute + self-test*/
2279 e8b54394 Brian Wheeler
                s->io_buffer[367] = (1<<4 | 1<<3 | 1); 
2280 e8b54394 Brian Wheeler
                s->io_buffer[368] = 0x03; /* smart capability (1) */
2281 e8b54394 Brian Wheeler
                s->io_buffer[369] = 0x00; /* smart capability (2) */
2282 e8b54394 Brian Wheeler
                s->io_buffer[370] = 0x01; /* error logging supported */
2283 e8b54394 Brian Wheeler
                s->io_buffer[372] = 0x02; /* minutes for poll short test */
2284 e8b54394 Brian Wheeler
                s->io_buffer[373] = 0x36; /* minutes for poll ext test */
2285 e8b54394 Brian Wheeler
                s->io_buffer[374] = 0x01; /* minutes for poll conveyance */
2286 e8b54394 Brian Wheeler
2287 e8b54394 Brian Wheeler
                for (n=0; n<511; n++) 
2288 e8b54394 Brian Wheeler
                    s->io_buffer[511] += s->io_buffer[n];
2289 e8b54394 Brian Wheeler
                s->io_buffer[511] = 0x100 - s->io_buffer[511];
2290 e8b54394 Brian Wheeler
                s->status = READY_STAT | SEEK_STAT;
2291 e8b54394 Brian Wheeler
                ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
2292 9cdd03a7 Gerd Hoffmann
                ide_set_irq(s->bus);
2293 e8b54394 Brian Wheeler
                break;
2294 e8b54394 Brian Wheeler
            case SMART_READ_LOG:
2295 e8b54394 Brian Wheeler
                switch (s->sector) {
2296 e8b54394 Brian Wheeler
                case 0x01: /* summary smart error log */
2297 e8b54394 Brian Wheeler
                    memset(s->io_buffer, 0, 0x200);
2298 e8b54394 Brian Wheeler
                    s->io_buffer[0] = 0x01;
2299 e8b54394 Brian Wheeler
                    s->io_buffer[1] = 0x00; /* no error entries */
2300 e8b54394 Brian Wheeler
                    s->io_buffer[452] = s->smart_errors & 0xff;
2301 e8b54394 Brian Wheeler
                    s->io_buffer[453] = (s->smart_errors & 0xff00) >> 8;
2302 e8b54394 Brian Wheeler
2303 e8b54394 Brian Wheeler
                    for (n=0; n<511; n++)
2304 e8b54394 Brian Wheeler
                        s->io_buffer[511] += s->io_buffer[n];
2305 e8b54394 Brian Wheeler
                    s->io_buffer[511] = 0x100 - s->io_buffer[511];
2306 e8b54394 Brian Wheeler
                    break;
2307 e8b54394 Brian Wheeler
                case 0x06: /* smart self test log */
2308 e8b54394 Brian Wheeler
                    memset(s->io_buffer, 0, 0x200);
2309 e8b54394 Brian Wheeler
                    s->io_buffer[0] = 0x01; 
2310 e8b54394 Brian Wheeler
                    if (s->smart_selftest_count == 0) {
2311 e8b54394 Brian Wheeler
                        s->io_buffer[508] = 0;
2312 e8b54394 Brian Wheeler
                    } else {
2313 e8b54394 Brian Wheeler
                        s->io_buffer[508] = s->smart_selftest_count;
2314 e8b54394 Brian Wheeler
                        for (n=2; n<506; n++) 
2315 e8b54394 Brian Wheeler
                            s->io_buffer[n] = s->smart_selftest_data[n];
2316 e8b54394 Brian Wheeler
                    }                    
2317 e8b54394 Brian Wheeler
                    for (n=0; n<511; n++)
2318 e8b54394 Brian Wheeler
                        s->io_buffer[511] += s->io_buffer[n];
2319 e8b54394 Brian Wheeler
                    s->io_buffer[511] = 0x100 - s->io_buffer[511];
2320 e8b54394 Brian Wheeler
                    break;
2321 e8b54394 Brian Wheeler
                default:
2322 e8b54394 Brian Wheeler
                    goto abort_cmd;
2323 e8b54394 Brian Wheeler
                }
2324 e8b54394 Brian Wheeler
                s->status = READY_STAT | SEEK_STAT;
2325 e8b54394 Brian Wheeler
                ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
2326 9cdd03a7 Gerd Hoffmann
                ide_set_irq(s->bus);
2327 e8b54394 Brian Wheeler
                break;
2328 e8b54394 Brian Wheeler
            case SMART_EXECUTE_OFFLINE:
2329 e8b54394 Brian Wheeler
                switch (s->sector) {
2330 e8b54394 Brian Wheeler
                case 0: /* off-line routine */
2331 e8b54394 Brian Wheeler
                case 1: /* short self test */
2332 e8b54394 Brian Wheeler
                case 2: /* extended self test */
2333 e8b54394 Brian Wheeler
                    s->smart_selftest_count++;
2334 e8b54394 Brian Wheeler
                    if(s->smart_selftest_count > 21)
2335 e8b54394 Brian Wheeler
                        s->smart_selftest_count = 0;
2336 e8b54394 Brian Wheeler
                    n = 2 + (s->smart_selftest_count - 1) * 24;
2337 e8b54394 Brian Wheeler
                    s->smart_selftest_data[n] = s->sector;
2338 e8b54394 Brian Wheeler
                    s->smart_selftest_data[n+1] = 0x00; /* OK and finished */
2339 e8b54394 Brian Wheeler
                    s->smart_selftest_data[n+2] = 0x34; /* hour count lsb */
2340 e8b54394 Brian Wheeler
                    s->smart_selftest_data[n+3] = 0x12; /* hour count msb */
2341 e8b54394 Brian Wheeler
                    s->status = READY_STAT | SEEK_STAT;
2342 9cdd03a7 Gerd Hoffmann
                    ide_set_irq(s->bus);
2343 e8b54394 Brian Wheeler
                    break;
2344 e8b54394 Brian Wheeler
                default:
2345 e8b54394 Brian Wheeler
                    goto abort_cmd;
2346 e8b54394 Brian Wheeler
                }
2347 e8b54394 Brian Wheeler
                break;
2348 e8b54394 Brian Wheeler
            default:
2349 e8b54394 Brian Wheeler
                goto abort_cmd;
2350 e8b54394 Brian Wheeler
            }
2351 e8b54394 Brian Wheeler
            break;
2352 5391d806 bellard
        default:
2353 5391d806 bellard
        abort_cmd:
2354 5391d806 bellard
            ide_abort_command(s);
2355 9cdd03a7 Gerd Hoffmann
            ide_set_irq(s->bus);
2356 5391d806 bellard
            break;
2357 5391d806 bellard
        }
2358 5391d806 bellard
    }
2359 5391d806 bellard
}
2360 5391d806 bellard
2361 356721ae Gerd Hoffmann
uint32_t ide_ioport_read(void *opaque, uint32_t addr1)
2362 5391d806 bellard
{
2363 bcbdc4d3 Gerd Hoffmann
    IDEBus *bus = opaque;
2364 bcbdc4d3 Gerd Hoffmann
    IDEState *s = idebus_active_if(bus);
2365 5391d806 bellard
    uint32_t addr;
2366 c2ff060f bellard
    int ret, hob;
2367 5391d806 bellard
2368 5391d806 bellard
    addr = addr1 & 7;
2369 c2ff060f bellard
    /* FIXME: HOB readback uses bit 7, but it's always set right now */
2370 c2ff060f bellard
    //hob = s->select & (1 << 7);
2371 c2ff060f bellard
    hob = 0;
2372 5391d806 bellard
    switch(addr) {
2373 5391d806 bellard
    case 0:
2374 5391d806 bellard
        ret = 0xff;
2375 5391d806 bellard
        break;
2376 5391d806 bellard
    case 1:
2377 bcbdc4d3 Gerd Hoffmann
        if ((!bus->ifs[0].bs && !bus->ifs[1].bs) ||
2378 bcbdc4d3 Gerd Hoffmann
            (s != bus->ifs && !s->bs))
2379 c45c3d00 bellard
            ret = 0;
2380 c2ff060f bellard
        else if (!hob)
2381 c45c3d00 bellard
            ret = s->error;
2382 c2ff060f bellard
        else
2383 c2ff060f bellard
            ret = s->hob_feature;
2384 5391d806 bellard
        break;
2385 5391d806 bellard
    case 2:
2386 bcbdc4d3 Gerd Hoffmann
        if (!bus->ifs[0].bs && !bus->ifs[1].bs)
2387 c45c3d00 bellard
            ret = 0;
2388 c2ff060f bellard
        else if (!hob)
2389 c45c3d00 bellard
            ret = s->nsector & 0xff;
2390 c2ff060f bellard
        else
2391 c2ff060f bellard
            ret = s->hob_nsector;
2392 5391d806 bellard
        break;
2393 5391d806 bellard
    case 3:
2394 bcbdc4d3 Gerd Hoffmann
        if (!bus->ifs[0].bs && !bus->ifs[1].bs)
2395 c45c3d00 bellard
            ret = 0;
2396 c2ff060f bellard
        else if (!hob)
2397 c45c3d00 bellard
            ret = s->sector;
2398 c2ff060f bellard
        else
2399 c2ff060f bellard
            ret = s->hob_sector;
2400 5391d806 bellard
        break;
2401 5391d806 bellard
    case 4:
2402 bcbdc4d3 Gerd Hoffmann
        if (!bus->ifs[0].bs && !bus->ifs[1].bs)
2403 c45c3d00 bellard
            ret = 0;
2404 c2ff060f bellard
        else if (!hob)
2405 c45c3d00 bellard
            ret = s->lcyl;
2406 c2ff060f bellard
        else
2407 c2ff060f bellard
            ret = s->hob_lcyl;
2408 5391d806 bellard
        break;
2409 5391d806 bellard
    case 5:
2410 bcbdc4d3 Gerd Hoffmann
        if (!bus->ifs[0].bs && !bus->ifs[1].bs)
2411 c45c3d00 bellard
            ret = 0;
2412 c2ff060f bellard
        else if (!hob)
2413 c45c3d00 bellard
            ret = s->hcyl;
2414 c2ff060f bellard
        else
2415 c2ff060f bellard
            ret = s->hob_hcyl;
2416 5391d806 bellard
        break;
2417 5391d806 bellard
    case 6:
2418 bcbdc4d3 Gerd Hoffmann
        if (!bus->ifs[0].bs && !bus->ifs[1].bs)
2419 c45c3d00 bellard
            ret = 0;
2420 c45c3d00 bellard
        else
2421 7ae98627 bellard
            ret = s->select;
2422 5391d806 bellard
        break;
2423 5391d806 bellard
    default:
2424 5391d806 bellard
    case 7:
2425 bcbdc4d3 Gerd Hoffmann
        if ((!bus->ifs[0].bs && !bus->ifs[1].bs) ||
2426 bcbdc4d3 Gerd Hoffmann
            (s != bus->ifs && !s->bs))
2427 c45c3d00 bellard
            ret = 0;
2428 c45c3d00 bellard
        else
2429 c45c3d00 bellard
            ret = s->status;
2430 9cdd03a7 Gerd Hoffmann
        qemu_irq_lower(bus->irq);
2431 5391d806 bellard
        break;
2432 5391d806 bellard
    }
2433 5391d806 bellard
#ifdef DEBUG_IDE
2434 5391d806 bellard
    printf("ide: read addr=0x%x val=%02x\n", addr1, ret);
2435 5391d806 bellard
#endif
2436 5391d806 bellard
    return ret;
2437 5391d806 bellard
}
2438 5391d806 bellard
2439 356721ae Gerd Hoffmann
uint32_t ide_status_read(void *opaque, uint32_t addr)
2440 5391d806 bellard
{
2441 bcbdc4d3 Gerd Hoffmann
    IDEBus *bus = opaque;
2442 bcbdc4d3 Gerd Hoffmann
    IDEState *s = idebus_active_if(bus);
2443 5391d806 bellard
    int ret;
2444 7ae98627 bellard
2445 bcbdc4d3 Gerd Hoffmann
    if ((!bus->ifs[0].bs && !bus->ifs[1].bs) ||
2446 bcbdc4d3 Gerd Hoffmann
        (s != bus->ifs && !s->bs))
2447 7ae98627 bellard
        ret = 0;
2448 7ae98627 bellard
    else
2449 7ae98627 bellard
        ret = s->status;
2450 5391d806 bellard
#ifdef DEBUG_IDE
2451 5391d806 bellard
    printf("ide: read status addr=0x%x val=%02x\n", addr, ret);
2452 5391d806 bellard
#endif
2453 5391d806 bellard
    return ret;
2454 5391d806 bellard
}
2455 5391d806 bellard
2456 356721ae Gerd Hoffmann
void ide_cmd_write(void *opaque, uint32_t addr, uint32_t val)
2457 5391d806 bellard
{
2458 bcbdc4d3 Gerd Hoffmann
    IDEBus *bus = opaque;
2459 5391d806 bellard
    IDEState *s;
2460 5391d806 bellard
    int i;
2461 5391d806 bellard
2462 5391d806 bellard
#ifdef DEBUG_IDE
2463 5391d806 bellard
    printf("ide: write control addr=0x%x val=%02x\n", addr, val);
2464 5391d806 bellard
#endif
2465 5391d806 bellard
    /* common for both drives */
2466 9cdd03a7 Gerd Hoffmann
    if (!(bus->cmd & IDE_CMD_RESET) &&
2467 5391d806 bellard
        (val & IDE_CMD_RESET)) {
2468 5391d806 bellard
        /* reset low to high */
2469 5391d806 bellard
        for(i = 0;i < 2; i++) {
2470 bcbdc4d3 Gerd Hoffmann
            s = &bus->ifs[i];
2471 5391d806 bellard
            s->status = BUSY_STAT | SEEK_STAT;
2472 5391d806 bellard
            s->error = 0x01;
2473 5391d806 bellard
        }
2474 9cdd03a7 Gerd Hoffmann
    } else if ((bus->cmd & IDE_CMD_RESET) &&
2475 5391d806 bellard
               !(val & IDE_CMD_RESET)) {
2476 5391d806 bellard
        /* high to low */
2477 5391d806 bellard
        for(i = 0;i < 2; i++) {
2478 bcbdc4d3 Gerd Hoffmann
            s = &bus->ifs[i];
2479 cd8722bb Markus Armbruster
            if (s->drive_kind == IDE_CD)
2480 6b136f9e bellard
                s->status = 0x00; /* NOTE: READY is _not_ set */
2481 6b136f9e bellard
            else
2482 56bf1d37 bellard
                s->status = READY_STAT | SEEK_STAT;
2483 5391d806 bellard
            ide_set_signature(s);
2484 5391d806 bellard
        }
2485 5391d806 bellard
    }
2486 5391d806 bellard
2487 9cdd03a7 Gerd Hoffmann
    bus->cmd = val;
2488 5391d806 bellard
}
2489 5391d806 bellard
2490 356721ae Gerd Hoffmann
void ide_data_writew(void *opaque, uint32_t addr, uint32_t val)
2491 5391d806 bellard
{
2492 bcbdc4d3 Gerd Hoffmann
    IDEBus *bus = opaque;
2493 bcbdc4d3 Gerd Hoffmann
    IDEState *s = idebus_active_if(bus);
2494 5391d806 bellard
    uint8_t *p;
2495 5391d806 bellard
2496 fcdd25ab aliguori
    /* PIO data access allowed only when DRQ bit is set */
2497 fcdd25ab aliguori
    if (!(s->status & DRQ_STAT))
2498 fcdd25ab aliguori
        return;
2499 fcdd25ab aliguori
2500 5391d806 bellard
    p = s->data_ptr;
2501 0c4ad8dc bellard
    *(uint16_t *)p = le16_to_cpu(val);
2502 5391d806 bellard
    p += 2;
2503 5391d806 bellard
    s->data_ptr = p;
2504 5391d806 bellard
    if (p >= s->data_end)
2505 5391d806 bellard
        s->end_transfer_func(s);
2506 5391d806 bellard
}
2507 5391d806 bellard
2508 356721ae Gerd Hoffmann
uint32_t ide_data_readw(void *opaque, uint32_t addr)
2509 5391d806 bellard
{
2510 bcbdc4d3 Gerd Hoffmann
    IDEBus *bus = opaque;
2511 bcbdc4d3 Gerd Hoffmann
    IDEState *s = idebus_active_if(bus);
2512 5391d806 bellard
    uint8_t *p;
2513 5391d806 bellard
    int ret;
2514 fcdd25ab aliguori
2515 fcdd25ab aliguori
    /* PIO data access allowed only when DRQ bit is set */
2516 fcdd25ab aliguori
    if (!(s->status & DRQ_STAT))
2517 fcdd25ab aliguori
        return 0;
2518 fcdd25ab aliguori
2519 5391d806 bellard
    p = s->data_ptr;
2520 0c4ad8dc bellard
    ret = cpu_to_le16(*(uint16_t *)p);
2521 5391d806 bellard
    p += 2;
2522 5391d806 bellard
    s->data_ptr = p;
2523 5391d806 bellard
    if (p >= s->data_end)
2524 5391d806 bellard
        s->end_transfer_func(s);
2525 5391d806 bellard
    return ret;
2526 5391d806 bellard
}
2527 5391d806 bellard
2528 356721ae Gerd Hoffmann
void ide_data_writel(void *opaque, uint32_t addr, uint32_t val)
2529 5391d806 bellard
{
2530 bcbdc4d3 Gerd Hoffmann
    IDEBus *bus = opaque;
2531 bcbdc4d3 Gerd Hoffmann
    IDEState *s = idebus_active_if(bus);
2532 5391d806 bellard
    uint8_t *p;
2533 5391d806 bellard
2534 fcdd25ab aliguori
    /* PIO data access allowed only when DRQ bit is set */
2535 fcdd25ab aliguori
    if (!(s->status & DRQ_STAT))
2536 fcdd25ab aliguori
        return;
2537 fcdd25ab aliguori
2538 5391d806 bellard
    p = s->data_ptr;
2539 0c4ad8dc bellard
    *(uint32_t *)p = le32_to_cpu(val);
2540 5391d806 bellard
    p += 4;
2541 5391d806 bellard
    s->data_ptr = p;
2542 5391d806 bellard
    if (p >= s->data_end)
2543 5391d806 bellard
        s->end_transfer_func(s);
2544 5391d806 bellard
}
2545 5391d806 bellard
2546 356721ae Gerd Hoffmann
uint32_t ide_data_readl(void *opaque, uint32_t addr)
2547 5391d806 bellard
{
2548 bcbdc4d3 Gerd Hoffmann
    IDEBus *bus = opaque;
2549 bcbdc4d3 Gerd Hoffmann
    IDEState *s = idebus_active_if(bus);
2550 5391d806 bellard
    uint8_t *p;
2551 5391d806 bellard
    int ret;
2552 3b46e624 ths
2553 fcdd25ab aliguori
    /* PIO data access allowed only when DRQ bit is set */
2554 fcdd25ab aliguori
    if (!(s->status & DRQ_STAT))
2555 fcdd25ab aliguori
        return 0;
2556 fcdd25ab aliguori
2557 5391d806 bellard
    p = s->data_ptr;
2558 0c4ad8dc bellard
    ret = cpu_to_le32(*(uint32_t *)p);
2559 5391d806 bellard
    p += 4;
2560 5391d806 bellard
    s->data_ptr = p;
2561 5391d806 bellard
    if (p >= s->data_end)
2562 5391d806 bellard
        s->end_transfer_func(s);
2563 5391d806 bellard
    return ret;
2564 5391d806 bellard
}
2565 5391d806 bellard
2566 a7dfe172 bellard
static void ide_dummy_transfer_stop(IDEState *s)
2567 a7dfe172 bellard
{
2568 a7dfe172 bellard
    s->data_ptr = s->io_buffer;
2569 a7dfe172 bellard
    s->data_end = s->io_buffer;
2570 a7dfe172 bellard
    s->io_buffer[0] = 0xff;
2571 a7dfe172 bellard
    s->io_buffer[1] = 0xff;
2572 a7dfe172 bellard
    s->io_buffer[2] = 0xff;
2573 a7dfe172 bellard
    s->io_buffer[3] = 0xff;
2574 a7dfe172 bellard
}
2575 a7dfe172 bellard
2576 4a643563 Blue Swirl
static void ide_reset(IDEState *s)
2577 5391d806 bellard
{
2578 4a643563 Blue Swirl
#ifdef DEBUG_IDE
2579 4a643563 Blue Swirl
    printf("ide: reset\n");
2580 4a643563 Blue Swirl
#endif
2581 cd8722bb Markus Armbruster
    if (s->drive_kind == IDE_CFATA)
2582 201a51fc balrog
        s->mult_sectors = 0;
2583 201a51fc balrog
    else
2584 201a51fc balrog
        s->mult_sectors = MAX_MULT_SECTORS;
2585 4a643563 Blue Swirl
    /* ide regs */
2586 4a643563 Blue Swirl
    s->feature = 0;
2587 4a643563 Blue Swirl
    s->error = 0;
2588 4a643563 Blue Swirl
    s->nsector = 0;
2589 4a643563 Blue Swirl
    s->sector = 0;
2590 4a643563 Blue Swirl
    s->lcyl = 0;
2591 4a643563 Blue Swirl
    s->hcyl = 0;
2592 4a643563 Blue Swirl
2593 4a643563 Blue Swirl
    /* lba48 */
2594 4a643563 Blue Swirl
    s->hob_feature = 0;
2595 4a643563 Blue Swirl
    s->hob_sector = 0;
2596 4a643563 Blue Swirl
    s->hob_nsector = 0;
2597 4a643563 Blue Swirl
    s->hob_lcyl = 0;
2598 4a643563 Blue Swirl
    s->hob_hcyl = 0;
2599 4a643563 Blue Swirl
2600 5391d806 bellard
    s->select = 0xa0;
2601 41a2b959 aliguori
    s->status = READY_STAT | SEEK_STAT;
2602 4a643563 Blue Swirl
2603 4a643563 Blue Swirl
    s->lba48 = 0;
2604 4a643563 Blue Swirl
2605 4a643563 Blue Swirl
    /* ATAPI specific */
2606 4a643563 Blue Swirl
    s->sense_key = 0;
2607 4a643563 Blue Swirl
    s->asc = 0;
2608 4a643563 Blue Swirl
    s->cdrom_changed = 0;
2609 4a643563 Blue Swirl
    s->packet_transfer_size = 0;
2610 4a643563 Blue Swirl
    s->elementary_transfer_size = 0;
2611 4a643563 Blue Swirl
    s->io_buffer_index = 0;
2612 4a643563 Blue Swirl
    s->cd_sector_size = 0;
2613 4a643563 Blue Swirl
    s->atapi_dma = 0;
2614 4a643563 Blue Swirl
    /* ATA DMA state */
2615 4a643563 Blue Swirl
    s->io_buffer_size = 0;
2616 4a643563 Blue Swirl
    s->req_nb_sectors = 0;
2617 4a643563 Blue Swirl
2618 5391d806 bellard
    ide_set_signature(s);
2619 a7dfe172 bellard
    /* init the transfer handler so that 0xffff is returned on data
2620 a7dfe172 bellard
       accesses */
2621 a7dfe172 bellard
    s->end_transfer_func = ide_dummy_transfer_stop;
2622 a7dfe172 bellard
    ide_dummy_transfer_stop(s);
2623 201a51fc balrog
    s->media_changed = 0;
2624 5391d806 bellard
}
2625 5391d806 bellard
2626 4a643563 Blue Swirl
void ide_bus_reset(IDEBus *bus)
2627 4a643563 Blue Swirl
{
2628 4a643563 Blue Swirl
    bus->unit = 0;
2629 4a643563 Blue Swirl
    bus->cmd = 0;
2630 4a643563 Blue Swirl
    ide_reset(&bus->ifs[0]);
2631 4a643563 Blue Swirl
    ide_reset(&bus->ifs[1]);
2632 4a643563 Blue Swirl
    ide_clear_hob(bus);
2633 4a643563 Blue Swirl
}
2634 4a643563 Blue Swirl
2635 c4d74df7 Markus Armbruster
int ide_init_drive(IDEState *s, BlockDriverState *bs,
2636 c4d74df7 Markus Armbruster
                   const char *version, const char *serial)
2637 88804180 Gerd Hoffmann
{
2638 88804180 Gerd Hoffmann
    int cylinders, heads, secs;
2639 88804180 Gerd Hoffmann
    uint64_t nb_sectors;
2640 88804180 Gerd Hoffmann
2641 f8b6cc00 Markus Armbruster
    s->bs = bs;
2642 f8b6cc00 Markus Armbruster
    bdrv_get_geometry(bs, &nb_sectors);
2643 f8b6cc00 Markus Armbruster
    bdrv_guess_geometry(bs, &cylinders, &heads, &secs);
2644 dce9e928 Markus Armbruster
    if (cylinders < 1 || cylinders > 16383) {
2645 dce9e928 Markus Armbruster
        error_report("cyls must be between 1 and 16383");
2646 dce9e928 Markus Armbruster
        return -1;
2647 dce9e928 Markus Armbruster
    }
2648 dce9e928 Markus Armbruster
    if (heads < 1 || heads > 16) {
2649 dce9e928 Markus Armbruster
        error_report("heads must be between 1 and 16");
2650 dce9e928 Markus Armbruster
        return -1;
2651 dce9e928 Markus Armbruster
    }
2652 dce9e928 Markus Armbruster
    if (secs < 1 || secs > 63) {
2653 dce9e928 Markus Armbruster
        error_report("secs must be between 1 and 63");
2654 dce9e928 Markus Armbruster
        return -1;
2655 dce9e928 Markus Armbruster
    }
2656 870111c8 Markus Armbruster
    s->cylinders = cylinders;
2657 870111c8 Markus Armbruster
    s->heads = heads;
2658 870111c8 Markus Armbruster
    s->sectors = secs;
2659 870111c8 Markus Armbruster
    s->nb_sectors = nb_sectors;
2660 870111c8 Markus Armbruster
    /* The SMART values should be preserved across power cycles
2661 870111c8 Markus Armbruster
       but they aren't.  */
2662 870111c8 Markus Armbruster
    s->smart_enabled = 1;
2663 870111c8 Markus Armbruster
    s->smart_autosave = 1;
2664 870111c8 Markus Armbruster
    s->smart_errors = 0;
2665 870111c8 Markus Armbruster
    s->smart_selftest_count = 0;
2666 f8b6cc00 Markus Armbruster
    if (bdrv_get_type_hint(bs) == BDRV_TYPE_CDROM) {
2667 cd8722bb Markus Armbruster
        s->drive_kind = IDE_CD;
2668 f8b6cc00 Markus Armbruster
        bdrv_set_change_cb(bs, cdrom_change_cb, s);
2669 1b2adf28 Christoph Hellwig
        bs->buffer_alignment = 2048;
2670 7aa9c811 Markus Armbruster
    } else {
2671 98f28ad7 Markus Armbruster
        if (!bdrv_is_inserted(s->bs)) {
2672 98f28ad7 Markus Armbruster
            error_report("Device needs media, but drive is empty");
2673 98f28ad7 Markus Armbruster
            return -1;
2674 98f28ad7 Markus Armbruster
        }
2675 7aa9c811 Markus Armbruster
        if (bdrv_is_read_only(bs)) {
2676 7aa9c811 Markus Armbruster
            error_report("Can't use a read-only drive");
2677 7aa9c811 Markus Armbruster
            return -1;
2678 7aa9c811 Markus Armbruster
        }
2679 88804180 Gerd Hoffmann
    }
2680 f8b6cc00 Markus Armbruster
    if (serial) {
2681 6ced55a5 Markus Armbruster
        strncpy(s->drive_serial_str, serial, sizeof(s->drive_serial_str));
2682 6ced55a5 Markus Armbruster
    } else {
2683 88804180 Gerd Hoffmann
        snprintf(s->drive_serial_str, sizeof(s->drive_serial_str),
2684 88804180 Gerd Hoffmann
                 "QM%05d", s->drive_serial);
2685 870111c8 Markus Armbruster
    }
2686 47c06340 Gerd Hoffmann
    if (version) {
2687 47c06340 Gerd Hoffmann
        pstrcpy(s->version, sizeof(s->version), version);
2688 47c06340 Gerd Hoffmann
    } else {
2689 47c06340 Gerd Hoffmann
        pstrcpy(s->version, sizeof(s->version), QEMU_VERSION);
2690 47c06340 Gerd Hoffmann
    }
2691 88804180 Gerd Hoffmann
    ide_reset(s);
2692 cd8722bb Markus Armbruster
    bdrv_set_removable(bs, s->drive_kind == IDE_CD);
2693 c4d74df7 Markus Armbruster
    return 0;
2694 88804180 Gerd Hoffmann
}
2695 88804180 Gerd Hoffmann
2696 57234ee4 Markus Armbruster
static void ide_init1(IDEBus *bus, int unit)
2697 d459da0e Markus Armbruster
{
2698 d459da0e Markus Armbruster
    static int drive_serial = 1;
2699 d459da0e Markus Armbruster
    IDEState *s = &bus->ifs[unit];
2700 d459da0e Markus Armbruster
2701 d459da0e Markus Armbruster
    s->bus = bus;
2702 d459da0e Markus Armbruster
    s->unit = unit;
2703 d459da0e Markus Armbruster
    s->drive_serial = drive_serial++;
2704 1b2adf28 Christoph Hellwig
    /* we need at least 2k alignment for accessing CDROMs using O_DIRECT */
2705 1b2adf28 Christoph Hellwig
    s->io_buffer = qemu_memalign(2048, IDE_DMA_BUF_SECTORS*512 + 4);
2706 50641c5c Juan Quintela
    s->io_buffer_total_len = IDE_DMA_BUF_SECTORS*512 + 4;
2707 d459da0e Markus Armbruster
    s->smart_selftest_data = qemu_blockalign(s->bs, 512);
2708 d459da0e Markus Armbruster
    s->sector_write_timer = qemu_new_timer(vm_clock,
2709 d459da0e Markus Armbruster
                                           ide_sector_write_timer_cb, s);
2710 57234ee4 Markus Armbruster
}
2711 57234ee4 Markus Armbruster
2712 57234ee4 Markus Armbruster
void ide_init2(IDEBus *bus, qemu_irq irq)
2713 57234ee4 Markus Armbruster
{
2714 57234ee4 Markus Armbruster
    int i;
2715 57234ee4 Markus Armbruster
2716 57234ee4 Markus Armbruster
    for(i = 0; i < 2; i++) {
2717 57234ee4 Markus Armbruster
        ide_init1(bus, i);
2718 57234ee4 Markus Armbruster
        ide_reset(&bus->ifs[i]);
2719 870111c8 Markus Armbruster
    }
2720 57234ee4 Markus Armbruster
    bus->irq = irq;
2721 d459da0e Markus Armbruster
}
2722 d459da0e Markus Armbruster
2723 57234ee4 Markus Armbruster
/* TODO convert users to qdev and remove */
2724 57234ee4 Markus Armbruster
void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0,
2725 57234ee4 Markus Armbruster
                                    DriveInfo *hd1, qemu_irq irq)
2726 5391d806 bellard
{
2727 88804180 Gerd Hoffmann
    int i;
2728 57234ee4 Markus Armbruster
    DriveInfo *dinfo;
2729 5391d806 bellard
2730 caed8802 bellard
    for(i = 0; i < 2; i++) {
2731 57234ee4 Markus Armbruster
        dinfo = i == 0 ? hd0 : hd1;
2732 57234ee4 Markus Armbruster
        ide_init1(bus, i);
2733 57234ee4 Markus Armbruster
        if (dinfo) {
2734 c4d74df7 Markus Armbruster
            if (ide_init_drive(&bus->ifs[i], dinfo->bdrv, NULL,
2735 c4d74df7 Markus Armbruster
                               *dinfo->serial ? dinfo->serial : NULL) < 0) {
2736 c4d74df7 Markus Armbruster
                error_report("Can't set up IDE drive %s", dinfo->id);
2737 c4d74df7 Markus Armbruster
                exit(1);
2738 c4d74df7 Markus Armbruster
            }
2739 57234ee4 Markus Armbruster
        } else {
2740 57234ee4 Markus Armbruster
            ide_reset(&bus->ifs[i]);
2741 57234ee4 Markus Armbruster
        }
2742 5391d806 bellard
    }
2743 9cdd03a7 Gerd Hoffmann
    bus->irq = irq;
2744 69b91039 bellard
}
2745 69b91039 bellard
2746 356721ae Gerd Hoffmann
void ide_init_ioport(IDEBus *bus, int iobase, int iobase2)
2747 69b91039 bellard
{
2748 bcbdc4d3 Gerd Hoffmann
    register_ioport_write(iobase, 8, 1, ide_ioport_write, bus);
2749 bcbdc4d3 Gerd Hoffmann
    register_ioport_read(iobase, 8, 1, ide_ioport_read, bus);
2750 caed8802 bellard
    if (iobase2) {
2751 bcbdc4d3 Gerd Hoffmann
        register_ioport_read(iobase2, 1, 1, ide_status_read, bus);
2752 bcbdc4d3 Gerd Hoffmann
        register_ioport_write(iobase2, 1, 1, ide_cmd_write, bus);
2753 5391d806 bellard
    }
2754 3b46e624 ths
2755 caed8802 bellard
    /* data ports */
2756 bcbdc4d3 Gerd Hoffmann
    register_ioport_write(iobase, 2, 2, ide_data_writew, bus);
2757 bcbdc4d3 Gerd Hoffmann
    register_ioport_read(iobase, 2, 2, ide_data_readw, bus);
2758 bcbdc4d3 Gerd Hoffmann
    register_ioport_write(iobase, 4, 4, ide_data_writel, bus);
2759 bcbdc4d3 Gerd Hoffmann
    register_ioport_read(iobase, 4, 4, ide_data_readl, bus);
2760 5391d806 bellard
}
2761 69b91039 bellard
2762 37159f13 Juan Quintela
static bool is_identify_set(void *opaque, int version_id)
2763 aa941b94 balrog
{
2764 37159f13 Juan Quintela
    IDEState *s = opaque;
2765 37159f13 Juan Quintela
2766 37159f13 Juan Quintela
    return s->identify_set != 0;
2767 37159f13 Juan Quintela
}
2768 37159f13 Juan Quintela
2769 50641c5c Juan Quintela
static EndTransferFunc* transfer_end_table[] = {
2770 50641c5c Juan Quintela
        ide_sector_read,
2771 50641c5c Juan Quintela
        ide_sector_write,
2772 50641c5c Juan Quintela
        ide_transfer_stop,
2773 50641c5c Juan Quintela
        ide_atapi_cmd_reply_end,
2774 50641c5c Juan Quintela
        ide_atapi_cmd,
2775 50641c5c Juan Quintela
        ide_dummy_transfer_stop,
2776 50641c5c Juan Quintela
};
2777 50641c5c Juan Quintela
2778 50641c5c Juan Quintela
static int transfer_end_table_idx(EndTransferFunc *fn)
2779 50641c5c Juan Quintela
{
2780 50641c5c Juan Quintela
    int i;
2781 50641c5c Juan Quintela
2782 50641c5c Juan Quintela
    for (i = 0; i < ARRAY_SIZE(transfer_end_table); i++)
2783 50641c5c Juan Quintela
        if (transfer_end_table[i] == fn)
2784 50641c5c Juan Quintela
            return i;
2785 50641c5c Juan Quintela
2786 50641c5c Juan Quintela
    return -1;
2787 50641c5c Juan Quintela
}
2788 50641c5c Juan Quintela
2789 37159f13 Juan Quintela
static int ide_drive_post_load(void *opaque, int version_id)
2790 aa941b94 balrog
{
2791 37159f13 Juan Quintela
    IDEState *s = opaque;
2792 37159f13 Juan Quintela
2793 37159f13 Juan Quintela
    if (version_id < 3) {
2794 93c8cfd9 Gleb Natapov
        if (s->sense_key == SENSE_UNIT_ATTENTION &&
2795 37159f13 Juan Quintela
            s->asc == ASC_MEDIUM_MAY_HAVE_CHANGED) {
2796 93c8cfd9 Gleb Natapov
            s->cdrom_changed = 1;
2797 37159f13 Juan Quintela
        }
2798 93c8cfd9 Gleb Natapov
    }
2799 37159f13 Juan Quintela
    return 0;
2800 aa941b94 balrog
}
2801 aa941b94 balrog
2802 50641c5c Juan Quintela
static int ide_drive_pio_post_load(void *opaque, int version_id)
2803 50641c5c Juan Quintela
{
2804 50641c5c Juan Quintela
    IDEState *s = opaque;
2805 50641c5c Juan Quintela
2806 7bccf573 Blue Swirl
    if (s->end_transfer_fn_idx > ARRAY_SIZE(transfer_end_table)) {
2807 50641c5c Juan Quintela
        return -EINVAL;
2808 50641c5c Juan Quintela
    }
2809 50641c5c Juan Quintela
    s->end_transfer_func = transfer_end_table[s->end_transfer_fn_idx];
2810 50641c5c Juan Quintela
    s->data_ptr = s->io_buffer + s->cur_io_buffer_offset;
2811 50641c5c Juan Quintela
    s->data_end = s->data_ptr + s->cur_io_buffer_len;
2812 50641c5c Juan Quintela
2813 50641c5c Juan Quintela
    return 0;
2814 50641c5c Juan Quintela
}
2815 50641c5c Juan Quintela
2816 50641c5c Juan Quintela
static void ide_drive_pio_pre_save(void *opaque)
2817 50641c5c Juan Quintela
{
2818 50641c5c Juan Quintela
    IDEState *s = opaque;
2819 50641c5c Juan Quintela
    int idx;
2820 50641c5c Juan Quintela
2821 50641c5c Juan Quintela
    s->cur_io_buffer_offset = s->data_ptr - s->io_buffer;
2822 50641c5c Juan Quintela
    s->cur_io_buffer_len = s->data_end - s->data_ptr;
2823 50641c5c Juan Quintela
2824 50641c5c Juan Quintela
    idx = transfer_end_table_idx(s->end_transfer_func);
2825 50641c5c Juan Quintela
    if (idx == -1) {
2826 50641c5c Juan Quintela
        fprintf(stderr, "%s: invalid end_transfer_func for DRQ_STAT\n",
2827 50641c5c Juan Quintela
                        __func__);
2828 50641c5c Juan Quintela
        s->end_transfer_fn_idx = 2;
2829 50641c5c Juan Quintela
    } else {
2830 50641c5c Juan Quintela
        s->end_transfer_fn_idx = idx;
2831 50641c5c Juan Quintela
    }
2832 50641c5c Juan Quintela
}
2833 50641c5c Juan Quintela
2834 50641c5c Juan Quintela
static bool ide_drive_pio_state_needed(void *opaque)
2835 50641c5c Juan Quintela
{
2836 50641c5c Juan Quintela
    IDEState *s = opaque;
2837 50641c5c Juan Quintela
2838 50641c5c Juan Quintela
    return (s->status & DRQ_STAT) != 0;
2839 50641c5c Juan Quintela
}
2840 50641c5c Juan Quintela
2841 50641c5c Juan Quintela
const VMStateDescription vmstate_ide_drive_pio_state = {
2842 50641c5c Juan Quintela
    .name = "ide_drive/pio_state",
2843 50641c5c Juan Quintela
    .version_id = 1,
2844 50641c5c Juan Quintela
    .minimum_version_id = 1,
2845 50641c5c Juan Quintela
    .minimum_version_id_old = 1,
2846 50641c5c Juan Quintela
    .pre_save = ide_drive_pio_pre_save,
2847 50641c5c Juan Quintela
    .post_load = ide_drive_pio_post_load,
2848 50641c5c Juan Quintela
    .fields      = (VMStateField []) {
2849 50641c5c Juan Quintela
        VMSTATE_INT32(req_nb_sectors, IDEState),
2850 50641c5c Juan Quintela
        VMSTATE_VARRAY_INT32(io_buffer, IDEState, io_buffer_total_len, 1,
2851 50641c5c Juan Quintela
                             vmstate_info_uint8, uint8_t),
2852 50641c5c Juan Quintela
        VMSTATE_INT32(cur_io_buffer_offset, IDEState),
2853 50641c5c Juan Quintela
        VMSTATE_INT32(cur_io_buffer_len, IDEState),
2854 50641c5c Juan Quintela
        VMSTATE_UINT8(end_transfer_fn_idx, IDEState),
2855 50641c5c Juan Quintela
        VMSTATE_INT32(elementary_transfer_size, IDEState),
2856 50641c5c Juan Quintela
        VMSTATE_INT32(packet_transfer_size, IDEState),
2857 50641c5c Juan Quintela
        VMSTATE_END_OF_LIST()
2858 50641c5c Juan Quintela
    }
2859 50641c5c Juan Quintela
};
2860 50641c5c Juan Quintela
2861 37159f13 Juan Quintela
const VMStateDescription vmstate_ide_drive = {
2862 37159f13 Juan Quintela
    .name = "ide_drive",
2863 3abb6260 Juan Quintela
    .version_id = 3,
2864 37159f13 Juan Quintela
    .minimum_version_id = 0,
2865 37159f13 Juan Quintela
    .minimum_version_id_old = 0,
2866 37159f13 Juan Quintela
    .post_load = ide_drive_post_load,
2867 37159f13 Juan Quintela
    .fields      = (VMStateField []) {
2868 37159f13 Juan Quintela
        VMSTATE_INT32(mult_sectors, IDEState),
2869 37159f13 Juan Quintela
        VMSTATE_INT32(identify_set, IDEState),
2870 37159f13 Juan Quintela
        VMSTATE_BUFFER_TEST(identify_data, IDEState, is_identify_set),
2871 37159f13 Juan Quintela
        VMSTATE_UINT8(feature, IDEState),
2872 37159f13 Juan Quintela
        VMSTATE_UINT8(error, IDEState),
2873 37159f13 Juan Quintela
        VMSTATE_UINT32(nsector, IDEState),
2874 37159f13 Juan Quintela
        VMSTATE_UINT8(sector, IDEState),
2875 37159f13 Juan Quintela
        VMSTATE_UINT8(lcyl, IDEState),
2876 37159f13 Juan Quintela
        VMSTATE_UINT8(hcyl, IDEState),
2877 37159f13 Juan Quintela
        VMSTATE_UINT8(hob_feature, IDEState),
2878 37159f13 Juan Quintela
        VMSTATE_UINT8(hob_sector, IDEState),
2879 37159f13 Juan Quintela
        VMSTATE_UINT8(hob_nsector, IDEState),
2880 37159f13 Juan Quintela
        VMSTATE_UINT8(hob_lcyl, IDEState),
2881 37159f13 Juan Quintela
        VMSTATE_UINT8(hob_hcyl, IDEState),
2882 37159f13 Juan Quintela
        VMSTATE_UINT8(select, IDEState),
2883 37159f13 Juan Quintela
        VMSTATE_UINT8(status, IDEState),
2884 37159f13 Juan Quintela
        VMSTATE_UINT8(lba48, IDEState),
2885 37159f13 Juan Quintela
        VMSTATE_UINT8(sense_key, IDEState),
2886 37159f13 Juan Quintela
        VMSTATE_UINT8(asc, IDEState),
2887 37159f13 Juan Quintela
        VMSTATE_UINT8_V(cdrom_changed, IDEState, 3),
2888 37159f13 Juan Quintela
        VMSTATE_END_OF_LIST()
2889 50641c5c Juan Quintela
    },
2890 50641c5c Juan Quintela
    .subsections = (VMStateSubsection []) {
2891 50641c5c Juan Quintela
        {
2892 50641c5c Juan Quintela
            .vmsd = &vmstate_ide_drive_pio_state,
2893 50641c5c Juan Quintela
            .needed = ide_drive_pio_state_needed,
2894 50641c5c Juan Quintela
        }, {
2895 50641c5c Juan Quintela
            /* empty */
2896 50641c5c Juan Quintela
        }
2897 37159f13 Juan Quintela
    }
2898 37159f13 Juan Quintela
};
2899 37159f13 Juan Quintela
2900 6521dc62 Juan Quintela
const VMStateDescription vmstate_ide_bus = {
2901 6521dc62 Juan Quintela
    .name = "ide_bus",
2902 6521dc62 Juan Quintela
    .version_id = 1,
2903 6521dc62 Juan Quintela
    .minimum_version_id = 1,
2904 6521dc62 Juan Quintela
    .minimum_version_id_old = 1,
2905 6521dc62 Juan Quintela
    .fields      = (VMStateField []) {
2906 6521dc62 Juan Quintela
        VMSTATE_UINT8(cmd, IDEBus),
2907 6521dc62 Juan Quintela
        VMSTATE_UINT8(unit, IDEBus),
2908 6521dc62 Juan Quintela
        VMSTATE_END_OF_LIST()
2909 6521dc62 Juan Quintela
    }
2910 6521dc62 Juan Quintela
};
2911 6521dc62 Juan Quintela
2912 69b91039 bellard
/***********************************************************/
2913 69b91039 bellard
/* PCI IDE definitions */
2914 69b91039 bellard
2915 8ccad811 bellard
static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb)
2916 98087450 bellard
{
2917 bcbdc4d3 Gerd Hoffmann
    BMDMAState *bm = s->bus->bmdma;
2918 98087450 bellard
    if(!bm)
2919 98087450 bellard
        return;
2920 bcbdc4d3 Gerd Hoffmann
    bm->unit = s->unit;
2921 98087450 bellard
    bm->dma_cb = dma_cb;
2922 8ccad811 bellard
    bm->cur_prd_last = 0;
2923 8ccad811 bellard
    bm->cur_prd_addr = 0;
2924 8ccad811 bellard
    bm->cur_prd_len = 0;
2925 428c5705 aliguori
    bm->sector_num = ide_get_sector(s);
2926 428c5705 aliguori
    bm->nsector = s->nsector;
2927 98087450 bellard
    if (bm->status & BM_STATUS_DMAING) {
2928 8ccad811 bellard
        bm->dma_cb(bm, 0);
2929 98087450 bellard
    }
2930 98087450 bellard
}
2931 98087450 bellard
2932 ce4b6522 Kevin Wolf
static void ide_dma_restart(IDEState *s, int is_read)
2933 428c5705 aliguori
{
2934 bcbdc4d3 Gerd Hoffmann
    BMDMAState *bm = s->bus->bmdma;
2935 428c5705 aliguori
    ide_set_sector(s, bm->sector_num);
2936 428c5705 aliguori
    s->io_buffer_index = 0;
2937 428c5705 aliguori
    s->io_buffer_size = 0;
2938 428c5705 aliguori
    s->nsector = bm->nsector;
2939 428c5705 aliguori
    bm->cur_addr = bm->addr;
2940 ce4b6522 Kevin Wolf
2941 ce4b6522 Kevin Wolf
    if (is_read) {
2942 ce4b6522 Kevin Wolf
        bm->dma_cb = ide_read_dma_cb;
2943 ce4b6522 Kevin Wolf
    } else {
2944 ce4b6522 Kevin Wolf
        bm->dma_cb = ide_write_dma_cb;
2945 ce4b6522 Kevin Wolf
    }
2946 ce4b6522 Kevin Wolf
2947 428c5705 aliguori
    ide_dma_start(s, bm->dma_cb);
2948 428c5705 aliguori
}
2949 428c5705 aliguori
2950 356721ae Gerd Hoffmann
void ide_dma_cancel(BMDMAState *bm)
2951 72c7b06c aliguori
{
2952 72c7b06c aliguori
    if (bm->status & BM_STATUS_DMAING) {
2953 72c7b06c aliguori
        if (bm->aiocb) {
2954 72c7b06c aliguori
#ifdef DEBUG_AIO
2955 72c7b06c aliguori
            printf("aio_cancel\n");
2956 72c7b06c aliguori
#endif
2957 72c7b06c aliguori
            bdrv_aio_cancel(bm->aiocb);
2958 72c7b06c aliguori
        }
2959 8337606d Kevin Wolf
2960 38d8dfa1 Kevin Wolf
        /* cancel DMA request */
2961 8337606d Kevin Wolf
        ide_dma_set_inactive(bm);
2962 72c7b06c aliguori
    }
2963 72c7b06c aliguori
}
2964 72c7b06c aliguori
2965 4a643563 Blue Swirl
void ide_dma_reset(BMDMAState *bm)
2966 4a643563 Blue Swirl
{
2967 4a643563 Blue Swirl
#ifdef DEBUG_IDE
2968 4a643563 Blue Swirl
    printf("ide: dma_reset\n");
2969 4a643563 Blue Swirl
#endif
2970 4a643563 Blue Swirl
    ide_dma_cancel(bm);
2971 4a643563 Blue Swirl
    bm->cmd = 0;
2972 4a643563 Blue Swirl
    bm->status = 0;
2973 4a643563 Blue Swirl
    bm->addr = 0;
2974 4a643563 Blue Swirl
    bm->cur_addr = 0;
2975 4a643563 Blue Swirl
    bm->cur_prd_last = 0;
2976 4a643563 Blue Swirl
    bm->cur_prd_addr = 0;
2977 4a643563 Blue Swirl
    bm->cur_prd_len = 0;
2978 4a643563 Blue Swirl
    bm->sector_num = 0;
2979 4a643563 Blue Swirl
    bm->nsector = 0;
2980 4a643563 Blue Swirl
}