Statistics
| Branch: | Revision:

root / hw / ide / core.c @ b3a21988

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