Statistics
| Branch: | Revision:

root / hw / ide / core.c @ 7ad7e3c3

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