Statistics
| Branch: | Revision:

root / hw / ide.c @ a2d4e44b

History | View | Annotate | Download (79.9 kB)

1 5391d806 bellard
/*
2 5391d806 bellard
 * QEMU IDE disk and CD-ROM Emulator
3 5391d806 bellard
 * 
4 5391d806 bellard
 * Copyright (c) 2003 Fabrice Bellard
5 5391d806 bellard
 * 
6 5391d806 bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 5391d806 bellard
 * of this software and associated documentation files (the "Software"), to deal
8 5391d806 bellard
 * in the Software without restriction, including without limitation the rights
9 5391d806 bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 5391d806 bellard
 * copies of the Software, and to permit persons to whom the Software is
11 5391d806 bellard
 * furnished to do so, subject to the following conditions:
12 5391d806 bellard
 *
13 5391d806 bellard
 * The above copyright notice and this permission notice shall be included in
14 5391d806 bellard
 * all copies or substantial portions of the Software.
15 5391d806 bellard
 *
16 5391d806 bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 5391d806 bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 5391d806 bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 5391d806 bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 5391d806 bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 5391d806 bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 5391d806 bellard
 * THE SOFTWARE.
23 5391d806 bellard
 */
24 5391d806 bellard
#include "vl.h"
25 5391d806 bellard
26 5391d806 bellard
/* debug IDE devices */
27 5391d806 bellard
//#define DEBUG_IDE
28 5391d806 bellard
//#define DEBUG_IDE_ATAPI
29 8ccad811 bellard
//#define DEBUG_AIO
30 8ccad811 bellard
#define USE_DMA_CDROM
31 5391d806 bellard
32 5391d806 bellard
/* Bits of HD_STATUS */
33 5391d806 bellard
#define ERR_STAT                0x01
34 5391d806 bellard
#define INDEX_STAT                0x02
35 5391d806 bellard
#define ECC_STAT                0x04        /* Corrected error */
36 5391d806 bellard
#define DRQ_STAT                0x08
37 5391d806 bellard
#define SEEK_STAT                0x10
38 5391d806 bellard
#define SRV_STAT                0x10
39 5391d806 bellard
#define WRERR_STAT                0x20
40 5391d806 bellard
#define READY_STAT                0x40
41 5391d806 bellard
#define BUSY_STAT                0x80
42 5391d806 bellard
43 5391d806 bellard
/* Bits for HD_ERROR */
44 5391d806 bellard
#define MARK_ERR                0x01        /* Bad address mark */
45 5391d806 bellard
#define TRK0_ERR                0x02        /* couldn't find track 0 */
46 5391d806 bellard
#define ABRT_ERR                0x04        /* Command aborted */
47 5391d806 bellard
#define MCR_ERR                        0x08        /* media change request */
48 5391d806 bellard
#define ID_ERR                        0x10        /* ID field not found */
49 5391d806 bellard
#define MC_ERR                        0x20        /* media changed */
50 5391d806 bellard
#define ECC_ERR                        0x40        /* Uncorrectable ECC error */
51 5391d806 bellard
#define BBD_ERR                        0x80        /* pre-EIDE meaning:  block marked bad */
52 5391d806 bellard
#define ICRC_ERR                0x80        /* new meaning:  CRC error during transfer */
53 5391d806 bellard
54 5391d806 bellard
/* Bits of HD_NSECTOR */
55 5391d806 bellard
#define CD                        0x01
56 5391d806 bellard
#define IO                        0x02
57 5391d806 bellard
#define REL                        0x04
58 5391d806 bellard
#define TAG_MASK                0xf8
59 5391d806 bellard
60 5391d806 bellard
#define IDE_CMD_RESET           0x04
61 5391d806 bellard
#define IDE_CMD_DISABLE_IRQ     0x02
62 5391d806 bellard
63 5391d806 bellard
/* ATA/ATAPI Commands pre T13 Spec */
64 5391d806 bellard
#define WIN_NOP                                0x00
65 5391d806 bellard
/*
66 5391d806 bellard
 *        0x01->0x02 Reserved
67 5391d806 bellard
 */
68 5391d806 bellard
#define CFA_REQ_EXT_ERROR_CODE                0x03 /* CFA Request Extended Error Code */
69 5391d806 bellard
/*
70 5391d806 bellard
 *        0x04->0x07 Reserved
71 5391d806 bellard
 */
72 5391d806 bellard
#define WIN_SRST                        0x08 /* ATAPI soft reset command */
73 5391d806 bellard
#define WIN_DEVICE_RESET                0x08
74 5391d806 bellard
/*
75 5391d806 bellard
 *        0x09->0x0F Reserved
76 5391d806 bellard
 */
77 5391d806 bellard
#define WIN_RECAL                        0x10
78 5391d806 bellard
#define WIN_RESTORE                        WIN_RECAL
79 5391d806 bellard
/*
80 5391d806 bellard
 *        0x10->0x1F Reserved
81 5391d806 bellard
 */
82 5391d806 bellard
#define WIN_READ                        0x20 /* 28-Bit */
83 5391d806 bellard
#define WIN_READ_ONCE                        0x21 /* 28-Bit without retries */
84 5391d806 bellard
#define WIN_READ_LONG                        0x22 /* 28-Bit */
85 5391d806 bellard
#define WIN_READ_LONG_ONCE                0x23 /* 28-Bit without retries */
86 5391d806 bellard
#define WIN_READ_EXT                        0x24 /* 48-Bit */
87 5391d806 bellard
#define WIN_READDMA_EXT                        0x25 /* 48-Bit */
88 5391d806 bellard
#define WIN_READDMA_QUEUED_EXT                0x26 /* 48-Bit */
89 5391d806 bellard
#define WIN_READ_NATIVE_MAX_EXT                0x27 /* 48-Bit */
90 5391d806 bellard
/*
91 5391d806 bellard
 *        0x28
92 5391d806 bellard
 */
93 5391d806 bellard
#define WIN_MULTREAD_EXT                0x29 /* 48-Bit */
94 5391d806 bellard
/*
95 5391d806 bellard
 *        0x2A->0x2F Reserved
96 5391d806 bellard
 */
97 5391d806 bellard
#define WIN_WRITE                        0x30 /* 28-Bit */
98 5391d806 bellard
#define WIN_WRITE_ONCE                        0x31 /* 28-Bit without retries */
99 5391d806 bellard
#define WIN_WRITE_LONG                        0x32 /* 28-Bit */
100 5391d806 bellard
#define WIN_WRITE_LONG_ONCE                0x33 /* 28-Bit without retries */
101 5391d806 bellard
#define WIN_WRITE_EXT                        0x34 /* 48-Bit */
102 5391d806 bellard
#define WIN_WRITEDMA_EXT                0x35 /* 48-Bit */
103 5391d806 bellard
#define WIN_WRITEDMA_QUEUED_EXT                0x36 /* 48-Bit */
104 5391d806 bellard
#define WIN_SET_MAX_EXT                        0x37 /* 48-Bit */
105 5391d806 bellard
#define CFA_WRITE_SECT_WO_ERASE                0x38 /* CFA Write Sectors without erase */
106 5391d806 bellard
#define WIN_MULTWRITE_EXT                0x39 /* 48-Bit */
107 5391d806 bellard
/*
108 5391d806 bellard
 *        0x3A->0x3B Reserved
109 5391d806 bellard
 */
110 5391d806 bellard
#define WIN_WRITE_VERIFY                0x3C /* 28-Bit */
111 5391d806 bellard
/*
112 5391d806 bellard
 *        0x3D->0x3F Reserved
113 5391d806 bellard
 */
114 5391d806 bellard
#define WIN_VERIFY                        0x40 /* 28-Bit - Read Verify Sectors */
115 5391d806 bellard
#define WIN_VERIFY_ONCE                        0x41 /* 28-Bit - without retries */
116 5391d806 bellard
#define WIN_VERIFY_EXT                        0x42 /* 48-Bit */
117 5391d806 bellard
/*
118 5391d806 bellard
 *        0x43->0x4F Reserved
119 5391d806 bellard
 */
120 5391d806 bellard
#define WIN_FORMAT                        0x50
121 5391d806 bellard
/*
122 5391d806 bellard
 *        0x51->0x5F Reserved
123 5391d806 bellard
 */
124 5391d806 bellard
#define WIN_INIT                        0x60
125 5391d806 bellard
/*
126 5391d806 bellard
 *        0x61->0x5F Reserved
127 5391d806 bellard
 */
128 5391d806 bellard
#define WIN_SEEK                        0x70 /* 0x70-0x7F Reserved */
129 5391d806 bellard
#define CFA_TRANSLATE_SECTOR                0x87 /* CFA Translate Sector */
130 5391d806 bellard
#define WIN_DIAGNOSE                        0x90
131 5391d806 bellard
#define WIN_SPECIFY                        0x91 /* set drive geometry translation */
132 5391d806 bellard
#define WIN_DOWNLOAD_MICROCODE                0x92
133 5391d806 bellard
#define WIN_STANDBYNOW2                        0x94
134 5391d806 bellard
#define WIN_STANDBY2                        0x96
135 5391d806 bellard
#define WIN_SETIDLE2                        0x97
136 5391d806 bellard
#define WIN_CHECKPOWERMODE2                0x98
137 5391d806 bellard
#define WIN_SLEEPNOW2                        0x99
138 5391d806 bellard
/*
139 5391d806 bellard
 *        0x9A VENDOR
140 5391d806 bellard
 */
141 5391d806 bellard
#define WIN_PACKETCMD                        0xA0 /* Send a packet command. */
142 5391d806 bellard
#define WIN_PIDENTIFY                        0xA1 /* identify ATAPI device        */
143 5391d806 bellard
#define WIN_QUEUED_SERVICE                0xA2
144 5391d806 bellard
#define WIN_SMART                        0xB0 /* self-monitoring and reporting */
145 5391d806 bellard
#define CFA_ERASE_SECTORS               0xC0
146 5391d806 bellard
#define WIN_MULTREAD                        0xC4 /* read sectors using multiple mode*/
147 5391d806 bellard
#define WIN_MULTWRITE                        0xC5 /* write sectors using multiple mode */
148 5391d806 bellard
#define WIN_SETMULT                        0xC6 /* enable/disable multiple mode */
149 5391d806 bellard
#define WIN_READDMA_QUEUED                0xC7 /* read sectors using Queued DMA transfers */
150 5391d806 bellard
#define WIN_READDMA                        0xC8 /* read sectors using DMA transfers */
151 5391d806 bellard
#define WIN_READDMA_ONCE                0xC9 /* 28-Bit - without retries */
152 5391d806 bellard
#define WIN_WRITEDMA                        0xCA /* write sectors using DMA transfers */
153 5391d806 bellard
#define WIN_WRITEDMA_ONCE                0xCB /* 28-Bit - without retries */
154 5391d806 bellard
#define WIN_WRITEDMA_QUEUED                0xCC /* write sectors using Queued DMA transfers */
155 5391d806 bellard
#define CFA_WRITE_MULTI_WO_ERASE        0xCD /* CFA Write multiple without erase */
156 5391d806 bellard
#define WIN_GETMEDIASTATUS                0xDA        
157 5391d806 bellard
#define WIN_ACKMEDIACHANGE                0xDB /* ATA-1, ATA-2 vendor */
158 5391d806 bellard
#define WIN_POSTBOOT                        0xDC
159 5391d806 bellard
#define WIN_PREBOOT                        0xDD
160 5391d806 bellard
#define WIN_DOORLOCK                        0xDE /* lock door on removable drives */
161 5391d806 bellard
#define WIN_DOORUNLOCK                        0xDF /* unlock door on removable drives */
162 5391d806 bellard
#define WIN_STANDBYNOW1                        0xE0
163 5391d806 bellard
#define WIN_IDLEIMMEDIATE                0xE1 /* force drive to become "ready" */
164 5391d806 bellard
#define WIN_STANDBY                     0xE2 /* Set device in Standby Mode */
165 5391d806 bellard
#define WIN_SETIDLE1                        0xE3
166 5391d806 bellard
#define WIN_READ_BUFFER                        0xE4 /* force read only 1 sector */
167 5391d806 bellard
#define WIN_CHECKPOWERMODE1                0xE5
168 5391d806 bellard
#define WIN_SLEEPNOW1                        0xE6
169 5391d806 bellard
#define WIN_FLUSH_CACHE                        0xE7
170 5391d806 bellard
#define WIN_WRITE_BUFFER                0xE8 /* force write only 1 sector */
171 5391d806 bellard
#define WIN_WRITE_SAME                        0xE9 /* read ata-2 to use */
172 5391d806 bellard
        /* SET_FEATURES 0x22 or 0xDD */
173 5391d806 bellard
#define WIN_FLUSH_CACHE_EXT                0xEA /* 48-Bit */
174 5391d806 bellard
#define WIN_IDENTIFY                        0xEC /* ask drive to identify itself        */
175 5391d806 bellard
#define WIN_MEDIAEJECT                        0xED
176 5391d806 bellard
#define WIN_IDENTIFY_DMA                0xEE /* same as WIN_IDENTIFY, but DMA */
177 5391d806 bellard
#define WIN_SETFEATURES                        0xEF /* set special drive features */
178 5391d806 bellard
#define EXABYTE_ENABLE_NEST                0xF0
179 5391d806 bellard
#define WIN_SECURITY_SET_PASS                0xF1
180 5391d806 bellard
#define WIN_SECURITY_UNLOCK                0xF2
181 5391d806 bellard
#define WIN_SECURITY_ERASE_PREPARE        0xF3
182 5391d806 bellard
#define WIN_SECURITY_ERASE_UNIT                0xF4
183 5391d806 bellard
#define WIN_SECURITY_FREEZE_LOCK        0xF5
184 5391d806 bellard
#define WIN_SECURITY_DISABLE                0xF6
185 5391d806 bellard
#define WIN_READ_NATIVE_MAX                0xF8 /* return the native maximum address */
186 5391d806 bellard
#define WIN_SET_MAX                        0xF9
187 5391d806 bellard
#define DISABLE_SEAGATE                        0xFB
188 5391d806 bellard
189 5391d806 bellard
/* set to 1 set disable mult support */
190 f66723fa bellard
#define MAX_MULT_SECTORS 16
191 5391d806 bellard
192 5391d806 bellard
/* ATAPI defines */
193 5391d806 bellard
194 5391d806 bellard
#define ATAPI_PACKET_SIZE 12
195 5391d806 bellard
196 5391d806 bellard
/* The generic packet command opcodes for CD/DVD Logical Units,
197 5391d806 bellard
 * From Table 57 of the SFF8090 Ver. 3 (Mt. Fuji) draft standard. */
198 5391d806 bellard
#define GPCMD_BLANK                            0xa1
199 5391d806 bellard
#define GPCMD_CLOSE_TRACK                    0x5b
200 5391d806 bellard
#define GPCMD_FLUSH_CACHE                    0x35
201 5391d806 bellard
#define GPCMD_FORMAT_UNIT                    0x04
202 5391d806 bellard
#define GPCMD_GET_CONFIGURATION                    0x46
203 5391d806 bellard
#define GPCMD_GET_EVENT_STATUS_NOTIFICATION 0x4a
204 5391d806 bellard
#define GPCMD_GET_PERFORMANCE                    0xac
205 5391d806 bellard
#define GPCMD_INQUIRY                            0x12
206 5391d806 bellard
#define GPCMD_LOAD_UNLOAD                    0xa6
207 5391d806 bellard
#define GPCMD_MECHANISM_STATUS                    0xbd
208 5391d806 bellard
#define GPCMD_MODE_SELECT_10                    0x55
209 5391d806 bellard
#define GPCMD_MODE_SENSE_10                    0x5a
210 5391d806 bellard
#define GPCMD_PAUSE_RESUME                    0x4b
211 5391d806 bellard
#define GPCMD_PLAY_AUDIO_10                    0x45
212 5391d806 bellard
#define GPCMD_PLAY_AUDIO_MSF                    0x47
213 5391d806 bellard
#define GPCMD_PLAY_AUDIO_TI                    0x48
214 5391d806 bellard
#define GPCMD_PLAY_CD                            0xbc
215 5391d806 bellard
#define GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL  0x1e
216 5391d806 bellard
#define GPCMD_READ_10                            0x28
217 5391d806 bellard
#define GPCMD_READ_12                            0xa8
218 5391d806 bellard
#define GPCMD_READ_CDVD_CAPACITY            0x25
219 5391d806 bellard
#define GPCMD_READ_CD                            0xbe
220 5391d806 bellard
#define GPCMD_READ_CD_MSF                    0xb9
221 5391d806 bellard
#define GPCMD_READ_DISC_INFO                    0x51
222 5391d806 bellard
#define GPCMD_READ_DVD_STRUCTURE            0xad
223 5391d806 bellard
#define GPCMD_READ_FORMAT_CAPACITIES            0x23
224 5391d806 bellard
#define GPCMD_READ_HEADER                    0x44
225 5391d806 bellard
#define GPCMD_READ_TRACK_RZONE_INFO            0x52
226 5391d806 bellard
#define GPCMD_READ_SUBCHANNEL                    0x42
227 5391d806 bellard
#define GPCMD_READ_TOC_PMA_ATIP                    0x43
228 5391d806 bellard
#define GPCMD_REPAIR_RZONE_TRACK            0x58
229 5391d806 bellard
#define GPCMD_REPORT_KEY                    0xa4
230 5391d806 bellard
#define GPCMD_REQUEST_SENSE                    0x03
231 5391d806 bellard
#define GPCMD_RESERVE_RZONE_TRACK            0x53
232 5391d806 bellard
#define GPCMD_SCAN                            0xba
233 5391d806 bellard
#define GPCMD_SEEK                            0x2b
234 5391d806 bellard
#define GPCMD_SEND_DVD_STRUCTURE            0xad
235 5391d806 bellard
#define GPCMD_SEND_EVENT                    0xa2
236 5391d806 bellard
#define GPCMD_SEND_KEY                            0xa3
237 5391d806 bellard
#define GPCMD_SEND_OPC                            0x54
238 5391d806 bellard
#define GPCMD_SET_READ_AHEAD                    0xa7
239 5391d806 bellard
#define GPCMD_SET_STREAMING                    0xb6
240 5391d806 bellard
#define GPCMD_START_STOP_UNIT                    0x1b
241 5391d806 bellard
#define GPCMD_STOP_PLAY_SCAN                    0x4e
242 5391d806 bellard
#define GPCMD_TEST_UNIT_READY                    0x00
243 5391d806 bellard
#define GPCMD_VERIFY_10                            0x2f
244 5391d806 bellard
#define GPCMD_WRITE_10                            0x2a
245 5391d806 bellard
#define GPCMD_WRITE_AND_VERIFY_10            0x2e
246 5391d806 bellard
/* This is listed as optional in ATAPI 2.6, but is (curiously) 
247 5391d806 bellard
 * missing from Mt. Fuji, Table 57.  It _is_ mentioned in Mt. Fuji
248 5391d806 bellard
 * Table 377 as an MMC command for SCSi devices though...  Most ATAPI
249 5391d806 bellard
 * drives support it. */
250 5391d806 bellard
#define GPCMD_SET_SPEED                            0xbb
251 5391d806 bellard
/* This seems to be a SCSI specific CD-ROM opcode 
252 5391d806 bellard
 * to play data at track/index */
253 5391d806 bellard
#define GPCMD_PLAYAUDIO_TI                    0x48
254 5391d806 bellard
/*
255 5391d806 bellard
 * From MS Media Status Notification Support Specification. For
256 5391d806 bellard
 * older drives only.
257 5391d806 bellard
 */
258 5391d806 bellard
#define GPCMD_GET_MEDIA_STATUS                    0xda
259 5391d806 bellard
260 5391d806 bellard
/* Mode page codes for mode sense/set */
261 5391d806 bellard
#define GPMODE_R_W_ERROR_PAGE                0x01
262 5391d806 bellard
#define GPMODE_WRITE_PARMS_PAGE                0x05
263 5391d806 bellard
#define GPMODE_AUDIO_CTL_PAGE                0x0e
264 5391d806 bellard
#define GPMODE_POWER_PAGE                0x1a
265 5391d806 bellard
#define GPMODE_FAULT_FAIL_PAGE                0x1c
266 5391d806 bellard
#define GPMODE_TO_PROTECT_PAGE                0x1d
267 5391d806 bellard
#define GPMODE_CAPABILITIES_PAGE        0x2a
268 5391d806 bellard
#define GPMODE_ALL_PAGES                0x3f
269 5391d806 bellard
/* Not in Mt. Fuji, but in ATAPI 2.6 -- depricated now in favor
270 5391d806 bellard
 * of MODE_SENSE_POWER_PAGE */
271 5391d806 bellard
#define GPMODE_CDROM_PAGE                0x0d
272 5391d806 bellard
273 5391d806 bellard
#define ATAPI_INT_REASON_CD             0x01 /* 0 = data transfer */
274 5391d806 bellard
#define ATAPI_INT_REASON_IO             0x02 /* 1 = transfer to the host */
275 5391d806 bellard
#define ATAPI_INT_REASON_REL            0x04
276 5391d806 bellard
#define ATAPI_INT_REASON_TAG            0xf8
277 5391d806 bellard
278 5391d806 bellard
/* same constants as bochs */
279 7f777bf3 bellard
#define ASC_ILLEGAL_OPCODE                   0x20
280 5391d806 bellard
#define ASC_LOGICAL_BLOCK_OOR                0x21
281 5391d806 bellard
#define ASC_INV_FIELD_IN_CMD_PACKET          0x24
282 5391d806 bellard
#define ASC_MEDIUM_NOT_PRESENT               0x3a
283 5391d806 bellard
#define ASC_SAVING_PARAMETERS_NOT_SUPPORTED  0x39
284 5391d806 bellard
285 5391d806 bellard
#define SENSE_NONE            0
286 5391d806 bellard
#define SENSE_NOT_READY       2
287 5391d806 bellard
#define SENSE_ILLEGAL_REQUEST 5
288 5391d806 bellard
#define SENSE_UNIT_ATTENTION  6
289 5391d806 bellard
290 5391d806 bellard
struct IDEState;
291 5391d806 bellard
292 5391d806 bellard
typedef void EndTransferFunc(struct IDEState *);
293 5391d806 bellard
294 caed8802 bellard
/* NOTE: IDEState represents in fact one drive */
295 5391d806 bellard
typedef struct IDEState {
296 5391d806 bellard
    /* ide config */
297 5391d806 bellard
    int is_cdrom;
298 5391d806 bellard
    int cylinders, heads, sectors;
299 5391d806 bellard
    int64_t nb_sectors;
300 5391d806 bellard
    int mult_sectors;
301 94458802 bellard
    int identify_set;
302 94458802 bellard
    uint16_t identify_data[256];
303 5457c8ce bellard
    SetIRQFunc *set_irq;
304 5457c8ce bellard
    void *irq_opaque;
305 5391d806 bellard
    int irq;
306 34e538ae bellard
    PCIDevice *pci_dev;
307 98087450 bellard
    struct BMDMAState *bmdma;
308 aedf5382 bellard
    int drive_serial;
309 5391d806 bellard
    /* ide regs */
310 5391d806 bellard
    uint8_t feature;
311 5391d806 bellard
    uint8_t error;
312 c2ff060f bellard
    uint32_t nsector;
313 5391d806 bellard
    uint8_t sector;
314 5391d806 bellard
    uint8_t lcyl;
315 5391d806 bellard
    uint8_t hcyl;
316 c2ff060f bellard
    /* other part of tf for lba48 support */
317 c2ff060f bellard
    uint8_t hob_feature;
318 c2ff060f bellard
    uint8_t hob_nsector;
319 c2ff060f bellard
    uint8_t hob_sector;
320 c2ff060f bellard
    uint8_t hob_lcyl;
321 c2ff060f bellard
    uint8_t hob_hcyl;
322 c2ff060f bellard
323 5391d806 bellard
    uint8_t select;
324 5391d806 bellard
    uint8_t status;
325 c2ff060f bellard
326 5391d806 bellard
    /* 0x3f6 command, only meaningful for drive 0 */
327 5391d806 bellard
    uint8_t cmd;
328 c2ff060f bellard
    /* set for lba48 access */
329 c2ff060f bellard
    uint8_t lba48;
330 5391d806 bellard
    /* depends on bit 4 in select, only meaningful for drive 0 */
331 5391d806 bellard
    struct IDEState *cur_drive; 
332 5391d806 bellard
    BlockDriverState *bs;
333 5391d806 bellard
    /* ATAPI specific */
334 5391d806 bellard
    uint8_t sense_key;
335 5391d806 bellard
    uint8_t asc;
336 5391d806 bellard
    int packet_transfer_size;
337 5391d806 bellard
    int elementary_transfer_size;
338 5391d806 bellard
    int io_buffer_index;
339 5391d806 bellard
    int lba;
340 98087450 bellard
    int cd_sector_size;
341 98087450 bellard
    int atapi_dma; /* true if dma is requested for the packet cmd */
342 98087450 bellard
    /* ATA DMA state */
343 98087450 bellard
    int io_buffer_size;
344 98087450 bellard
    /* PIO transfer handling */
345 5391d806 bellard
    int req_nb_sectors; /* number of sectors per interrupt */
346 5391d806 bellard
    EndTransferFunc *end_transfer_func;
347 5391d806 bellard
    uint8_t *data_ptr;
348 5391d806 bellard
    uint8_t *data_end;
349 5391d806 bellard
    uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4];
350 a09db21f bellard
    QEMUTimer *sector_write_timer; /* only used for win2k instal hack */
351 e774a278 bellard
    uint32_t irq_count; /* counts IRQs when using win2k install hack */
352 5391d806 bellard
} IDEState;
353 5391d806 bellard
354 98087450 bellard
#define BM_STATUS_DMAING 0x01
355 98087450 bellard
#define BM_STATUS_ERROR  0x02
356 98087450 bellard
#define BM_STATUS_INT    0x04
357 98087450 bellard
358 98087450 bellard
#define BM_CMD_START     0x01
359 98087450 bellard
#define BM_CMD_READ      0x08
360 98087450 bellard
361 5457c8ce bellard
#define IDE_TYPE_PIIX3   0
362 5457c8ce bellard
#define IDE_TYPE_CMD646  1
363 5457c8ce bellard
364 5457c8ce bellard
/* CMD646 specific */
365 5457c8ce bellard
#define MRDMODE                0x71
366 5457c8ce bellard
#define   MRDMODE_INTR_CH0        0x04
367 5457c8ce bellard
#define   MRDMODE_INTR_CH1        0x08
368 5457c8ce bellard
#define   MRDMODE_BLK_CH0        0x10
369 5457c8ce bellard
#define   MRDMODE_BLK_CH1        0x20
370 5457c8ce bellard
#define UDIDETCR0        0x73
371 5457c8ce bellard
#define UDIDETCR1        0x7B
372 5457c8ce bellard
373 98087450 bellard
typedef struct BMDMAState {
374 98087450 bellard
    uint8_t cmd;
375 98087450 bellard
    uint8_t status;
376 98087450 bellard
    uint32_t addr;
377 8ccad811 bellard
    
378 5457c8ce bellard
    struct PCIIDEState *pci_dev;
379 98087450 bellard
    /* current transfer state */
380 8ccad811 bellard
    uint32_t cur_addr;
381 8ccad811 bellard
    uint32_t cur_prd_last;
382 8ccad811 bellard
    uint32_t cur_prd_addr;
383 8ccad811 bellard
    uint32_t cur_prd_len;
384 98087450 bellard
    IDEState *ide_if;
385 8ccad811 bellard
    BlockDriverCompletionFunc *dma_cb;
386 8ccad811 bellard
    BlockDriverAIOCB *aiocb;
387 98087450 bellard
} BMDMAState;
388 98087450 bellard
389 98087450 bellard
typedef struct PCIIDEState {
390 98087450 bellard
    PCIDevice dev;
391 98087450 bellard
    IDEState ide_if[4];
392 98087450 bellard
    BMDMAState bmdma[2];
393 5457c8ce bellard
    int type; /* see IDE_TYPE_xxx */
394 98087450 bellard
} PCIIDEState;
395 98087450 bellard
396 8ccad811 bellard
static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb);
397 98087450 bellard
398 5391d806 bellard
static void padstr(char *str, const char *src, int len)
399 5391d806 bellard
{
400 5391d806 bellard
    int i, v;
401 5391d806 bellard
    for(i = 0; i < len; i++) {
402 5391d806 bellard
        if (*src)
403 5391d806 bellard
            v = *src++;
404 5391d806 bellard
        else
405 5391d806 bellard
            v = ' ';
406 5391d806 bellard
        *(char *)((long)str ^ 1) = v;
407 5391d806 bellard
        str++;
408 5391d806 bellard
    }
409 5391d806 bellard
}
410 5391d806 bellard
411 bd0d90b2 bellard
static void padstr8(uint8_t *buf, int buf_size, const char *src)
412 bd0d90b2 bellard
{
413 bd0d90b2 bellard
    int i;
414 bd0d90b2 bellard
    for(i = 0; i < buf_size; i++) {
415 bd0d90b2 bellard
        if (*src)
416 bd0d90b2 bellard
            buf[i] = *src++;
417 bd0d90b2 bellard
        else
418 bd0d90b2 bellard
            buf[i] = ' ';
419 bd0d90b2 bellard
    }
420 bd0d90b2 bellard
}
421 bd0d90b2 bellard
422 67b915a5 bellard
static void put_le16(uint16_t *p, unsigned int v)
423 67b915a5 bellard
{
424 0c4ad8dc bellard
    *p = cpu_to_le16(v);
425 67b915a5 bellard
}
426 67b915a5 bellard
427 5391d806 bellard
static void ide_identify(IDEState *s)
428 5391d806 bellard
{
429 5391d806 bellard
    uint16_t *p;
430 5391d806 bellard
    unsigned int oldsize;
431 aedf5382 bellard
    char buf[20];
432 5391d806 bellard
433 94458802 bellard
    if (s->identify_set) {
434 94458802 bellard
        memcpy(s->io_buffer, s->identify_data, sizeof(s->identify_data));
435 94458802 bellard
        return;
436 94458802 bellard
    }
437 94458802 bellard
438 5391d806 bellard
    memset(s->io_buffer, 0, 512);
439 5391d806 bellard
    p = (uint16_t *)s->io_buffer;
440 67b915a5 bellard
    put_le16(p + 0, 0x0040);
441 67b915a5 bellard
    put_le16(p + 1, s->cylinders); 
442 67b915a5 bellard
    put_le16(p + 3, s->heads);
443 67b915a5 bellard
    put_le16(p + 4, 512 * s->sectors); /* XXX: retired, remove ? */
444 67b915a5 bellard
    put_le16(p + 5, 512); /* XXX: retired, remove ? */
445 67b915a5 bellard
    put_le16(p + 6, s->sectors); 
446 aedf5382 bellard
    snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial);
447 aedf5382 bellard
    padstr((uint8_t *)(p + 10), buf, 20); /* serial number */
448 67b915a5 bellard
    put_le16(p + 20, 3); /* XXX: retired, remove ? */
449 67b915a5 bellard
    put_le16(p + 21, 512); /* cache size in sectors */
450 67b915a5 bellard
    put_le16(p + 22, 4); /* ecc bytes */
451 5391d806 bellard
    padstr((uint8_t *)(p + 23), QEMU_VERSION, 8); /* firmware version */
452 5391d806 bellard
    padstr((uint8_t *)(p + 27), "QEMU HARDDISK", 40); /* model */
453 5391d806 bellard
#if MAX_MULT_SECTORS > 1    
454 67b915a5 bellard
    put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
455 5391d806 bellard
#endif
456 67b915a5 bellard
    put_le16(p + 48, 1); /* dword I/O */
457 94458802 bellard
    put_le16(p + 49, (1 << 11) | (1 << 9) | (1 << 8)); /* DMA and LBA supported */
458 67b915a5 bellard
    put_le16(p + 51, 0x200); /* PIO transfer cycle */
459 67b915a5 bellard
    put_le16(p + 52, 0x200); /* DMA transfer cycle */
460 94458802 bellard
    put_le16(p + 53, 1 | (1 << 1) | (1 << 2)); /* words 54-58,64-70,88 are valid */
461 67b915a5 bellard
    put_le16(p + 54, s->cylinders);
462 67b915a5 bellard
    put_le16(p + 55, s->heads);
463 67b915a5 bellard
    put_le16(p + 56, s->sectors);
464 5391d806 bellard
    oldsize = s->cylinders * s->heads * s->sectors;
465 67b915a5 bellard
    put_le16(p + 57, oldsize);
466 67b915a5 bellard
    put_le16(p + 58, oldsize >> 16);
467 5391d806 bellard
    if (s->mult_sectors)
468 67b915a5 bellard
        put_le16(p + 59, 0x100 | s->mult_sectors);
469 67b915a5 bellard
    put_le16(p + 60, s->nb_sectors);
470 67b915a5 bellard
    put_le16(p + 61, s->nb_sectors >> 16);
471 94458802 bellard
    put_le16(p + 63, 0x07); /* mdma0-2 supported */
472 94458802 bellard
    put_le16(p + 65, 120);
473 94458802 bellard
    put_le16(p + 66, 120);
474 94458802 bellard
    put_le16(p + 67, 120);
475 94458802 bellard
    put_le16(p + 68, 120);
476 94458802 bellard
    put_le16(p + 80, 0xf0); /* ata3 -> ata6 supported */
477 94458802 bellard
    put_le16(p + 81, 0x16); /* conforms to ata5 */
478 67b915a5 bellard
    put_le16(p + 82, (1 << 14));
479 c2ff060f bellard
    /* 13=flush_cache_ext,12=flush_cache,10=lba48 */
480 c2ff060f bellard
    put_le16(p + 83, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10));
481 67b915a5 bellard
    put_le16(p + 84, (1 << 14));
482 67b915a5 bellard
    put_le16(p + 85, (1 << 14));
483 c2ff060f bellard
    /* 13=flush_cache_ext,12=flush_cache,10=lba48 */
484 c2ff060f bellard
    put_le16(p + 86, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10));
485 67b915a5 bellard
    put_le16(p + 87, (1 << 14));
486 94458802 bellard
    put_le16(p + 88, 0x3f | (1 << 13)); /* udma5 set and supported */
487 94458802 bellard
    put_le16(p + 93, 1 | (1 << 14) | 0x2000);
488 c2ff060f bellard
    put_le16(p + 100, s->nb_sectors);
489 c2ff060f bellard
    put_le16(p + 101, s->nb_sectors >> 16);
490 c2ff060f bellard
    put_le16(p + 102, s->nb_sectors >> 32);
491 c2ff060f bellard
    put_le16(p + 103, s->nb_sectors >> 48);
492 94458802 bellard
493 94458802 bellard
    memcpy(s->identify_data, p, sizeof(s->identify_data));
494 94458802 bellard
    s->identify_set = 1;
495 5391d806 bellard
}
496 5391d806 bellard
497 5391d806 bellard
static void ide_atapi_identify(IDEState *s)
498 5391d806 bellard
{
499 5391d806 bellard
    uint16_t *p;
500 aedf5382 bellard
    char buf[20];
501 5391d806 bellard
502 94458802 bellard
    if (s->identify_set) {
503 94458802 bellard
        memcpy(s->io_buffer, s->identify_data, sizeof(s->identify_data));
504 94458802 bellard
        return;
505 94458802 bellard
    }
506 94458802 bellard
507 5391d806 bellard
    memset(s->io_buffer, 0, 512);
508 5391d806 bellard
    p = (uint16_t *)s->io_buffer;
509 5391d806 bellard
    /* Removable CDROM, 50us response, 12 byte packets */
510 67b915a5 bellard
    put_le16(p + 0, (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0));
511 aedf5382 bellard
    snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial);
512 aedf5382 bellard
    padstr((uint8_t *)(p + 10), buf, 20); /* serial number */
513 67b915a5 bellard
    put_le16(p + 20, 3); /* buffer type */
514 67b915a5 bellard
    put_le16(p + 21, 512); /* cache size in sectors */
515 67b915a5 bellard
    put_le16(p + 22, 4); /* ecc bytes */
516 5391d806 bellard
    padstr((uint8_t *)(p + 23), QEMU_VERSION, 8); /* firmware version */
517 5391d806 bellard
    padstr((uint8_t *)(p + 27), "QEMU CD-ROM", 40); /* model */
518 67b915a5 bellard
    put_le16(p + 48, 1); /* dword I/O (XXX: should not be set on CDROM) */
519 8ccad811 bellard
#ifdef USE_DMA_CDROM
520 8ccad811 bellard
    put_le16(p + 49, 1 << 9 | 1 << 8); /* DMA and LBA supported */
521 8ccad811 bellard
    put_le16(p + 53, 7); /* words 64-70, 54-58, 88 valid */
522 8ccad811 bellard
    put_le16(p + 63, 7);  /* mdma0-2 supported */
523 8ccad811 bellard
    put_le16(p + 64, 0x3f); /* PIO modes supported */
524 8ccad811 bellard
#else
525 67b915a5 bellard
    put_le16(p + 49, 1 << 9); /* LBA supported, no DMA */
526 67b915a5 bellard
    put_le16(p + 53, 3); /* words 64-70, 54-58 valid */
527 67b915a5 bellard
    put_le16(p + 63, 0x103); /* DMA modes XXX: may be incorrect */
528 67b915a5 bellard
    put_le16(p + 64, 1); /* PIO modes */
529 8ccad811 bellard
#endif
530 67b915a5 bellard
    put_le16(p + 65, 0xb4); /* minimum DMA multiword tx cycle time */
531 67b915a5 bellard
    put_le16(p + 66, 0xb4); /* recommended DMA multiword tx cycle time */
532 67b915a5 bellard
    put_le16(p + 67, 0x12c); /* minimum PIO cycle time without flow control */
533 67b915a5 bellard
    put_le16(p + 68, 0xb4); /* minimum PIO cycle time with IORDY flow control */
534 94458802 bellard
535 67b915a5 bellard
    put_le16(p + 71, 30); /* in ns */
536 67b915a5 bellard
    put_le16(p + 72, 30); /* in ns */
537 5391d806 bellard
538 67b915a5 bellard
    put_le16(p + 80, 0x1e); /* support up to ATA/ATAPI-4 */
539 8ccad811 bellard
#ifdef USE_DMA_CDROM
540 8ccad811 bellard
    put_le16(p + 88, 0x3f | (1 << 13)); /* udma5 set and supported */
541 8ccad811 bellard
#endif
542 94458802 bellard
    memcpy(s->identify_data, p, sizeof(s->identify_data));
543 94458802 bellard
    s->identify_set = 1;
544 5391d806 bellard
}
545 5391d806 bellard
546 5391d806 bellard
static void ide_set_signature(IDEState *s)
547 5391d806 bellard
{
548 5391d806 bellard
    s->select &= 0xf0; /* clear head */
549 5391d806 bellard
    /* put signature */
550 5391d806 bellard
    s->nsector = 1;
551 5391d806 bellard
    s->sector = 1;
552 5391d806 bellard
    if (s->is_cdrom) {
553 5391d806 bellard
        s->lcyl = 0x14;
554 5391d806 bellard
        s->hcyl = 0xeb;
555 5391d806 bellard
    } else if (s->bs) {
556 5391d806 bellard
        s->lcyl = 0;
557 5391d806 bellard
        s->hcyl = 0;
558 5391d806 bellard
    } else {
559 5391d806 bellard
        s->lcyl = 0xff;
560 5391d806 bellard
        s->hcyl = 0xff;
561 5391d806 bellard
    }
562 5391d806 bellard
}
563 5391d806 bellard
564 5391d806 bellard
static inline void ide_abort_command(IDEState *s)
565 5391d806 bellard
{
566 5391d806 bellard
    s->status = READY_STAT | ERR_STAT;
567 5391d806 bellard
    s->error = ABRT_ERR;
568 5391d806 bellard
}
569 5391d806 bellard
570 5391d806 bellard
static inline void ide_set_irq(IDEState *s)
571 5391d806 bellard
{
572 98ff7d30 bellard
    BMDMAState *bm = s->bmdma;
573 5391d806 bellard
    if (!(s->cmd & IDE_CMD_DISABLE_IRQ)) {
574 5457c8ce bellard
        if (bm) {
575 98ff7d30 bellard
            bm->status |= BM_STATUS_INT;
576 5457c8ce bellard
        }
577 5457c8ce bellard
        s->set_irq(s->irq_opaque, s->irq, 1);
578 5391d806 bellard
    }
579 5391d806 bellard
}
580 5391d806 bellard
581 5391d806 bellard
/* prepare data transfer and tell what to do after */
582 5391d806 bellard
static void ide_transfer_start(IDEState *s, uint8_t *buf, int size, 
583 5391d806 bellard
                               EndTransferFunc *end_transfer_func)
584 5391d806 bellard
{
585 5391d806 bellard
    s->end_transfer_func = end_transfer_func;
586 5391d806 bellard
    s->data_ptr = buf;
587 5391d806 bellard
    s->data_end = buf + size;
588 5391d806 bellard
    s->status |= DRQ_STAT;
589 5391d806 bellard
}
590 5391d806 bellard
591 5391d806 bellard
static void ide_transfer_stop(IDEState *s)
592 5391d806 bellard
{
593 5391d806 bellard
    s->end_transfer_func = ide_transfer_stop;
594 5391d806 bellard
    s->data_ptr = s->io_buffer;
595 5391d806 bellard
    s->data_end = s->io_buffer;
596 5391d806 bellard
    s->status &= ~DRQ_STAT;
597 5391d806 bellard
}
598 5391d806 bellard
599 5391d806 bellard
static int64_t ide_get_sector(IDEState *s)
600 5391d806 bellard
{
601 5391d806 bellard
    int64_t sector_num;
602 5391d806 bellard
    if (s->select & 0x40) {
603 5391d806 bellard
        /* lba */
604 c2ff060f bellard
        if (!s->lba48) {
605 c2ff060f bellard
            sector_num = ((s->select & 0x0f) << 24) | (s->hcyl << 16) |
606 c2ff060f bellard
                (s->lcyl << 8) | s->sector;
607 c2ff060f bellard
        } else {
608 c2ff060f bellard
            sector_num = ((int64_t)s->hob_hcyl << 40) |
609 c2ff060f bellard
                ((int64_t) s->hob_lcyl << 32) |
610 c2ff060f bellard
                ((int64_t) s->hob_sector << 24) |
611 c2ff060f bellard
                ((int64_t) s->hcyl << 16) |
612 c2ff060f bellard
                ((int64_t) s->lcyl << 8) | s->sector;
613 c2ff060f bellard
        }
614 5391d806 bellard
    } else {
615 5391d806 bellard
        sector_num = ((s->hcyl << 8) | s->lcyl) * s->heads * s->sectors +
616 c2ff060f bellard
            (s->select & 0x0f) * s->sectors + (s->sector - 1);
617 5391d806 bellard
    }
618 5391d806 bellard
    return sector_num;
619 5391d806 bellard
}
620 5391d806 bellard
621 5391d806 bellard
static void ide_set_sector(IDEState *s, int64_t sector_num)
622 5391d806 bellard
{
623 5391d806 bellard
    unsigned int cyl, r;
624 5391d806 bellard
    if (s->select & 0x40) {
625 c2ff060f bellard
        if (!s->lba48) {
626 c2ff060f bellard
            s->select = (s->select & 0xf0) | (sector_num >> 24);
627 c2ff060f bellard
            s->hcyl = (sector_num >> 16);
628 c2ff060f bellard
            s->lcyl = (sector_num >> 8);
629 c2ff060f bellard
            s->sector = (sector_num);
630 c2ff060f bellard
        } else {
631 c2ff060f bellard
            s->sector = sector_num;
632 c2ff060f bellard
            s->lcyl = sector_num >> 8;
633 c2ff060f bellard
            s->hcyl = sector_num >> 16;
634 c2ff060f bellard
            s->hob_sector = sector_num >> 24;
635 c2ff060f bellard
            s->hob_lcyl = sector_num >> 32;
636 c2ff060f bellard
            s->hob_hcyl = sector_num >> 40;
637 c2ff060f bellard
        }
638 5391d806 bellard
    } else {
639 5391d806 bellard
        cyl = sector_num / (s->heads * s->sectors);
640 5391d806 bellard
        r = sector_num % (s->heads * s->sectors);
641 5391d806 bellard
        s->hcyl = cyl >> 8;
642 5391d806 bellard
        s->lcyl = cyl;
643 1b8eb456 bellard
        s->select = (s->select & 0xf0) | ((r / s->sectors) & 0x0f);
644 5391d806 bellard
        s->sector = (r % s->sectors) + 1;
645 5391d806 bellard
    }
646 5391d806 bellard
}
647 5391d806 bellard
648 5391d806 bellard
static void ide_sector_read(IDEState *s)
649 5391d806 bellard
{
650 5391d806 bellard
    int64_t sector_num;
651 5391d806 bellard
    int ret, n;
652 5391d806 bellard
653 5391d806 bellard
    s->status = READY_STAT | SEEK_STAT;
654 a136e5a8 bellard
    s->error = 0; /* not needed by IDE spec, but needed by Windows */
655 5391d806 bellard
    sector_num = ide_get_sector(s);
656 5391d806 bellard
    n = s->nsector;
657 5391d806 bellard
    if (n == 0) {
658 5391d806 bellard
        /* no more sector to read from disk */
659 5391d806 bellard
        ide_transfer_stop(s);
660 5391d806 bellard
    } else {
661 5391d806 bellard
#if defined(DEBUG_IDE)
662 5391d806 bellard
        printf("read sector=%Ld\n", sector_num);
663 5391d806 bellard
#endif
664 5391d806 bellard
        if (n > s->req_nb_sectors)
665 5391d806 bellard
            n = s->req_nb_sectors;
666 5391d806 bellard
        ret = bdrv_read(s->bs, sector_num, s->io_buffer, n);
667 5391d806 bellard
        ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_read);
668 5391d806 bellard
        ide_set_irq(s);
669 5391d806 bellard
        ide_set_sector(s, sector_num + n);
670 5391d806 bellard
        s->nsector -= n;
671 5391d806 bellard
    }
672 5391d806 bellard
}
673 5391d806 bellard
674 8ccad811 bellard
/* return 0 if buffer completed */
675 8ccad811 bellard
static int dma_buf_rw(BMDMAState *bm, int is_write)
676 98087450 bellard
{
677 8ccad811 bellard
    IDEState *s = bm->ide_if;
678 8ccad811 bellard
    struct {
679 8ccad811 bellard
        uint32_t addr;
680 8ccad811 bellard
        uint32_t size;
681 8ccad811 bellard
    } prd;
682 8ccad811 bellard
    int l, len;
683 98087450 bellard
684 8ccad811 bellard
    for(;;) {
685 8ccad811 bellard
        l = s->io_buffer_size - s->io_buffer_index;
686 8ccad811 bellard
        if (l <= 0) 
687 8ccad811 bellard
            break;
688 8ccad811 bellard
        if (bm->cur_prd_len == 0) {
689 8ccad811 bellard
            /* end of table (with a fail safe of one page) */
690 8ccad811 bellard
            if (bm->cur_prd_last ||
691 8ccad811 bellard
                (bm->cur_addr - bm->addr) >= 4096)
692 8ccad811 bellard
                return 0;
693 8ccad811 bellard
            cpu_physical_memory_read(bm->cur_addr, (uint8_t *)&prd, 8);
694 8ccad811 bellard
            bm->cur_addr += 8;
695 8ccad811 bellard
            prd.addr = le32_to_cpu(prd.addr);
696 8ccad811 bellard
            prd.size = le32_to_cpu(prd.size);
697 8ccad811 bellard
            len = prd.size & 0xfffe;
698 8ccad811 bellard
            if (len == 0)
699 8ccad811 bellard
                len = 0x10000;
700 8ccad811 bellard
            bm->cur_prd_len = len;
701 8ccad811 bellard
            bm->cur_prd_addr = prd.addr;
702 8ccad811 bellard
            bm->cur_prd_last = (prd.size & 0x80000000);
703 8ccad811 bellard
        }
704 8ccad811 bellard
        if (l > bm->cur_prd_len)
705 8ccad811 bellard
            l = bm->cur_prd_len;
706 8ccad811 bellard
        if (l > 0) {
707 8ccad811 bellard
            if (is_write) {
708 8ccad811 bellard
                cpu_physical_memory_write(bm->cur_prd_addr, 
709 8ccad811 bellard
                                          s->io_buffer + s->io_buffer_index, l);
710 8ccad811 bellard
            } else {
711 8ccad811 bellard
                cpu_physical_memory_read(bm->cur_prd_addr, 
712 8ccad811 bellard
                                          s->io_buffer + s->io_buffer_index, l);
713 8ccad811 bellard
            }
714 8ccad811 bellard
            bm->cur_prd_addr += l;
715 8ccad811 bellard
            bm->cur_prd_len -= l;
716 8ccad811 bellard
            s->io_buffer_index += l;
717 98087450 bellard
        }
718 98087450 bellard
    }
719 8ccad811 bellard
    return 1;
720 8ccad811 bellard
}
721 8ccad811 bellard
722 8ccad811 bellard
/* XXX: handle errors */
723 8ccad811 bellard
static void ide_read_dma_cb(void *opaque, int ret)
724 8ccad811 bellard
{
725 8ccad811 bellard
    BMDMAState *bm = opaque;
726 8ccad811 bellard
    IDEState *s = bm->ide_if;
727 8ccad811 bellard
    int n;
728 8ccad811 bellard
    int64_t sector_num;
729 8ccad811 bellard
730 8ccad811 bellard
    n = s->io_buffer_size >> 9;
731 8ccad811 bellard
    sector_num = ide_get_sector(s);
732 8ccad811 bellard
    if (n > 0) {
733 8ccad811 bellard
        sector_num += n;
734 8ccad811 bellard
        ide_set_sector(s, sector_num);
735 8ccad811 bellard
        s->nsector -= n;
736 8ccad811 bellard
        if (dma_buf_rw(bm, 1) == 0)
737 8ccad811 bellard
            goto eot;
738 8ccad811 bellard
    }
739 8ccad811 bellard
740 8ccad811 bellard
    /* end of transfer ? */
741 8ccad811 bellard
    if (s->nsector == 0) {
742 98087450 bellard
        s->status = READY_STAT | SEEK_STAT;
743 98087450 bellard
        ide_set_irq(s);
744 8ccad811 bellard
    eot:
745 8ccad811 bellard
        bm->status &= ~BM_STATUS_DMAING;
746 8ccad811 bellard
        bm->status |= BM_STATUS_INT;
747 8ccad811 bellard
        bm->dma_cb = NULL;
748 8ccad811 bellard
        bm->ide_if = NULL;
749 8ccad811 bellard
        bm->aiocb = NULL;
750 8ccad811 bellard
        return;
751 98087450 bellard
    }
752 8ccad811 bellard
753 8ccad811 bellard
    /* launch next transfer */
754 8ccad811 bellard
    n = s->nsector;
755 8ccad811 bellard
    if (n > MAX_MULT_SECTORS)
756 8ccad811 bellard
        n = MAX_MULT_SECTORS;
757 8ccad811 bellard
    s->io_buffer_index = 0;
758 8ccad811 bellard
    s->io_buffer_size = n * 512;
759 8ccad811 bellard
#ifdef DEBUG_AIO
760 8ccad811 bellard
    printf("aio_read: sector_num=%lld n=%d\n", sector_num, n);
761 8ccad811 bellard
#endif
762 8ccad811 bellard
    bm->aiocb = bdrv_aio_read(s->bs, sector_num, s->io_buffer, n, 
763 8ccad811 bellard
                              ide_read_dma_cb, bm);
764 98087450 bellard
}
765 98087450 bellard
766 98087450 bellard
static void ide_sector_read_dma(IDEState *s)
767 98087450 bellard
{
768 8ccad811 bellard
    s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
769 98087450 bellard
    s->io_buffer_index = 0;
770 98087450 bellard
    s->io_buffer_size = 0;
771 98087450 bellard
    ide_dma_start(s, ide_read_dma_cb);
772 98087450 bellard
}
773 98087450 bellard
774 a09db21f bellard
static void ide_sector_write_timer_cb(void *opaque)
775 a09db21f bellard
{
776 a09db21f bellard
    IDEState *s = opaque;
777 a09db21f bellard
    ide_set_irq(s);
778 a09db21f bellard
}
779 a09db21f bellard
780 5391d806 bellard
static void ide_sector_write(IDEState *s)
781 5391d806 bellard
{
782 5391d806 bellard
    int64_t sector_num;
783 5391d806 bellard
    int ret, n, n1;
784 5391d806 bellard
785 5391d806 bellard
    s->status = READY_STAT | SEEK_STAT;
786 5391d806 bellard
    sector_num = ide_get_sector(s);
787 5391d806 bellard
#if defined(DEBUG_IDE)
788 5391d806 bellard
    printf("write sector=%Ld\n", sector_num);
789 5391d806 bellard
#endif
790 5391d806 bellard
    n = s->nsector;
791 5391d806 bellard
    if (n > s->req_nb_sectors)
792 5391d806 bellard
        n = s->req_nb_sectors;
793 5391d806 bellard
    ret = bdrv_write(s->bs, sector_num, s->io_buffer, n);
794 5391d806 bellard
    s->nsector -= n;
795 5391d806 bellard
    if (s->nsector == 0) {
796 5391d806 bellard
        /* no more sector to write */
797 5391d806 bellard
        ide_transfer_stop(s);
798 5391d806 bellard
    } else {
799 5391d806 bellard
        n1 = s->nsector;
800 5391d806 bellard
        if (n1 > s->req_nb_sectors)
801 5391d806 bellard
            n1 = s->req_nb_sectors;
802 5391d806 bellard
        ide_transfer_start(s, s->io_buffer, 512 * n1, ide_sector_write);
803 5391d806 bellard
    }
804 5391d806 bellard
    ide_set_sector(s, sector_num + n);
805 a09db21f bellard
    
806 a09db21f bellard
#ifdef TARGET_I386
807 e774a278 bellard
    if (win2k_install_hack && ((++s->irq_count % 16) == 0)) {
808 a09db21f bellard
        /* It seems there is a bug in the Windows 2000 installer HDD
809 a09db21f bellard
           IDE driver which fills the disk with empty logs when the
810 a09db21f bellard
           IDE write IRQ comes too early. This hack tries to correct
811 a09db21f bellard
           that at the expense of slower write performances. Use this
812 a09db21f bellard
           option _only_ to install Windows 2000. You must disable it
813 a09db21f bellard
           for normal use. */
814 a09db21f bellard
        qemu_mod_timer(s->sector_write_timer, 
815 a09db21f bellard
                       qemu_get_clock(vm_clock) + (ticks_per_sec / 1000));
816 a09db21f bellard
    } else 
817 a09db21f bellard
#endif
818 a09db21f bellard
    {
819 a09db21f bellard
        ide_set_irq(s);
820 a09db21f bellard
    }
821 5391d806 bellard
}
822 5391d806 bellard
823 8ccad811 bellard
/* XXX: handle errors */
824 8ccad811 bellard
static void ide_write_dma_cb(void *opaque, int ret)
825 98087450 bellard
{
826 8ccad811 bellard
    BMDMAState *bm = opaque;
827 8ccad811 bellard
    IDEState *s = bm->ide_if;
828 8ccad811 bellard
    int n;
829 98087450 bellard
    int64_t sector_num;
830 98087450 bellard
831 8ccad811 bellard
    n = s->io_buffer_size >> 9;
832 8ccad811 bellard
    sector_num = ide_get_sector(s);
833 8ccad811 bellard
    if (n > 0) {
834 8ccad811 bellard
        sector_num += n;
835 8ccad811 bellard
        ide_set_sector(s, sector_num);
836 8ccad811 bellard
        s->nsector -= n;
837 98087450 bellard
    }
838 98087450 bellard
839 8ccad811 bellard
    /* end of transfer ? */
840 8ccad811 bellard
    if (s->nsector == 0) {
841 8ccad811 bellard
        s->status = READY_STAT | SEEK_STAT;
842 8ccad811 bellard
        ide_set_irq(s);
843 8ccad811 bellard
    eot:
844 8ccad811 bellard
        bm->status &= ~BM_STATUS_DMAING;
845 8ccad811 bellard
        bm->status |= BM_STATUS_INT;
846 8ccad811 bellard
        bm->dma_cb = NULL;
847 8ccad811 bellard
        bm->ide_if = NULL;
848 8ccad811 bellard
        bm->aiocb = NULL;
849 8ccad811 bellard
        return;
850 8ccad811 bellard
    }
851 8ccad811 bellard
852 8ccad811 bellard
    /* launch next transfer */
853 98087450 bellard
    n = s->nsector;
854 98087450 bellard
    if (n > MAX_MULT_SECTORS)
855 98087450 bellard
        n = MAX_MULT_SECTORS;
856 98087450 bellard
    s->io_buffer_index = 0;
857 98087450 bellard
    s->io_buffer_size = n * 512;
858 8ccad811 bellard
859 8ccad811 bellard
    if (dma_buf_rw(bm, 0) == 0)
860 8ccad811 bellard
        goto eot;
861 8ccad811 bellard
#ifdef DEBUG_AIO
862 8ccad811 bellard
    printf("aio_write: sector_num=%lld n=%d\n", sector_num, n);
863 8ccad811 bellard
#endif
864 8ccad811 bellard
    bm->aiocb = bdrv_aio_write(s->bs, sector_num, s->io_buffer, n, 
865 8ccad811 bellard
                               ide_write_dma_cb, bm);
866 8ccad811 bellard
}
867 8ccad811 bellard
868 8ccad811 bellard
static void ide_sector_write_dma(IDEState *s)
869 8ccad811 bellard
{
870 8ccad811 bellard
    s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
871 8ccad811 bellard
    s->io_buffer_index = 0;
872 8ccad811 bellard
    s->io_buffer_size = 0;
873 98087450 bellard
    ide_dma_start(s, ide_write_dma_cb);
874 98087450 bellard
}
875 98087450 bellard
876 5391d806 bellard
static void ide_atapi_cmd_ok(IDEState *s)
877 5391d806 bellard
{
878 5391d806 bellard
    s->error = 0;
879 5391d806 bellard
    s->status = READY_STAT;
880 5391d806 bellard
    s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
881 5391d806 bellard
    ide_set_irq(s);
882 5391d806 bellard
}
883 5391d806 bellard
884 5391d806 bellard
static void ide_atapi_cmd_error(IDEState *s, int sense_key, int asc)
885 5391d806 bellard
{
886 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
887 5391d806 bellard
    printf("atapi_cmd_error: sense=0x%x asc=0x%x\n", sense_key, asc);
888 5391d806 bellard
#endif
889 5391d806 bellard
    s->error = sense_key << 4;
890 5391d806 bellard
    s->status = READY_STAT | ERR_STAT;
891 5391d806 bellard
    s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
892 5391d806 bellard
    s->sense_key = sense_key;
893 5391d806 bellard
    s->asc = asc;
894 5391d806 bellard
    ide_set_irq(s);
895 5391d806 bellard
}
896 5391d806 bellard
897 5391d806 bellard
static inline void cpu_to_ube16(uint8_t *buf, int val)
898 5391d806 bellard
{
899 5391d806 bellard
    buf[0] = val >> 8;
900 5391d806 bellard
    buf[1] = val;
901 5391d806 bellard
}
902 5391d806 bellard
903 5391d806 bellard
static inline void cpu_to_ube32(uint8_t *buf, unsigned int val)
904 5391d806 bellard
{
905 5391d806 bellard
    buf[0] = val >> 24;
906 5391d806 bellard
    buf[1] = val >> 16;
907 5391d806 bellard
    buf[2] = val >> 8;
908 5391d806 bellard
    buf[3] = val;
909 5391d806 bellard
}
910 5391d806 bellard
911 5391d806 bellard
static inline int ube16_to_cpu(const uint8_t *buf)
912 5391d806 bellard
{
913 5391d806 bellard
    return (buf[0] << 8) | buf[1];
914 5391d806 bellard
}
915 5391d806 bellard
916 5391d806 bellard
static inline int ube32_to_cpu(const uint8_t *buf)
917 5391d806 bellard
{
918 5391d806 bellard
    return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
919 5391d806 bellard
}
920 5391d806 bellard
921 98087450 bellard
static void lba_to_msf(uint8_t *buf, int lba)
922 98087450 bellard
{
923 98087450 bellard
    lba += 150;
924 98087450 bellard
    buf[0] = (lba / 75) / 60;
925 98087450 bellard
    buf[1] = (lba / 75) % 60;
926 98087450 bellard
    buf[2] = lba % 75;
927 98087450 bellard
}
928 98087450 bellard
929 8ccad811 bellard
static void cd_data_to_raw(uint8_t *buf, int lba)
930 8ccad811 bellard
{
931 8ccad811 bellard
    /* sync bytes */
932 8ccad811 bellard
    buf[0] = 0x00;
933 8ccad811 bellard
    memset(buf + 1, 0xff, 10);
934 8ccad811 bellard
    buf[11] = 0x00;
935 8ccad811 bellard
    buf += 12;
936 8ccad811 bellard
    /* MSF */
937 8ccad811 bellard
    lba_to_msf(buf, lba);
938 8ccad811 bellard
    buf[3] = 0x01; /* mode 1 data */
939 8ccad811 bellard
    buf += 4;
940 8ccad811 bellard
    /* data */
941 8ccad811 bellard
    buf += 2048;
942 8ccad811 bellard
    /* XXX: ECC not computed */
943 8ccad811 bellard
    memset(buf, 0, 288);
944 8ccad811 bellard
}
945 8ccad811 bellard
946 66c6ef76 bellard
static int cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf, 
947 98087450 bellard
                           int sector_size)
948 98087450 bellard
{
949 66c6ef76 bellard
    int ret;
950 66c6ef76 bellard
951 98087450 bellard
    switch(sector_size) {
952 98087450 bellard
    case 2048:
953 66c6ef76 bellard
        ret = bdrv_read(bs, (int64_t)lba << 2, buf, 4);
954 98087450 bellard
        break;
955 98087450 bellard
    case 2352:
956 66c6ef76 bellard
        ret = bdrv_read(bs, (int64_t)lba << 2, buf + 16, 4);
957 66c6ef76 bellard
        if (ret < 0)
958 66c6ef76 bellard
            return ret;
959 8ccad811 bellard
        cd_data_to_raw(buf, lba);
960 98087450 bellard
        break;
961 98087450 bellard
    default:
962 66c6ef76 bellard
        ret = -EIO;
963 98087450 bellard
        break;
964 98087450 bellard
    }
965 66c6ef76 bellard
    return ret;
966 66c6ef76 bellard
}
967 66c6ef76 bellard
968 66c6ef76 bellard
static void ide_atapi_io_error(IDEState *s, int ret)
969 66c6ef76 bellard
{
970 66c6ef76 bellard
    /* XXX: handle more errors */
971 66c6ef76 bellard
    if (ret == -ENOMEDIUM) {
972 66c6ef76 bellard
        ide_atapi_cmd_error(s, SENSE_NOT_READY, 
973 66c6ef76 bellard
                            ASC_MEDIUM_NOT_PRESENT);
974 66c6ef76 bellard
    } else {
975 66c6ef76 bellard
        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
976 66c6ef76 bellard
                            ASC_LOGICAL_BLOCK_OOR);
977 66c6ef76 bellard
    }
978 98087450 bellard
}
979 98087450 bellard
980 5391d806 bellard
/* The whole ATAPI transfer logic is handled in this function */
981 5391d806 bellard
static void ide_atapi_cmd_reply_end(IDEState *s)
982 5391d806 bellard
{
983 66c6ef76 bellard
    int byte_count_limit, size, ret;
984 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
985 5391d806 bellard
    printf("reply: tx_size=%d elem_tx_size=%d index=%d\n", 
986 5391d806 bellard
           s->packet_transfer_size,
987 5391d806 bellard
           s->elementary_transfer_size,
988 5391d806 bellard
           s->io_buffer_index);
989 5391d806 bellard
#endif
990 5391d806 bellard
    if (s->packet_transfer_size <= 0) {
991 5391d806 bellard
        /* end of transfer */
992 5391d806 bellard
        ide_transfer_stop(s);
993 5391d806 bellard
        s->status = READY_STAT;
994 5391d806 bellard
        s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
995 5391d806 bellard
        ide_set_irq(s);
996 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
997 5391d806 bellard
        printf("status=0x%x\n", s->status);
998 5391d806 bellard
#endif
999 5391d806 bellard
    } else {
1000 5391d806 bellard
        /* see if a new sector must be read */
1001 98087450 bellard
        if (s->lba != -1 && s->io_buffer_index >= s->cd_sector_size) {
1002 66c6ef76 bellard
            ret = cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size);
1003 66c6ef76 bellard
            if (ret < 0) {
1004 66c6ef76 bellard
                ide_transfer_stop(s);
1005 66c6ef76 bellard
                ide_atapi_io_error(s, ret);
1006 66c6ef76 bellard
                return;
1007 66c6ef76 bellard
            }
1008 5391d806 bellard
            s->lba++;
1009 5391d806 bellard
            s->io_buffer_index = 0;
1010 5391d806 bellard
        }
1011 5391d806 bellard
        if (s->elementary_transfer_size > 0) {
1012 5391d806 bellard
            /* there are some data left to transmit in this elementary
1013 5391d806 bellard
               transfer */
1014 98087450 bellard
            size = s->cd_sector_size - s->io_buffer_index;
1015 5391d806 bellard
            if (size > s->elementary_transfer_size)
1016 5391d806 bellard
                size = s->elementary_transfer_size;
1017 5391d806 bellard
            ide_transfer_start(s, s->io_buffer + s->io_buffer_index, 
1018 5391d806 bellard
                               size, ide_atapi_cmd_reply_end);
1019 5391d806 bellard
            s->packet_transfer_size -= size;
1020 5391d806 bellard
            s->elementary_transfer_size -= size;
1021 5391d806 bellard
            s->io_buffer_index += size;
1022 5391d806 bellard
        } else {
1023 5391d806 bellard
            /* a new transfer is needed */
1024 5391d806 bellard
            s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO;
1025 5391d806 bellard
            byte_count_limit = s->lcyl | (s->hcyl << 8);
1026 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
1027 5391d806 bellard
            printf("byte_count_limit=%d\n", byte_count_limit);
1028 5391d806 bellard
#endif
1029 5391d806 bellard
            if (byte_count_limit == 0xffff)
1030 5391d806 bellard
                byte_count_limit--;
1031 5391d806 bellard
            size = s->packet_transfer_size;
1032 5391d806 bellard
            if (size > byte_count_limit) {
1033 5391d806 bellard
                /* byte count limit must be even if this case */
1034 5391d806 bellard
                if (byte_count_limit & 1)
1035 5391d806 bellard
                    byte_count_limit--;
1036 5391d806 bellard
                size = byte_count_limit;
1037 5391d806 bellard
            }
1038 a136e5a8 bellard
            s->lcyl = size;
1039 a136e5a8 bellard
            s->hcyl = size >> 8;
1040 5391d806 bellard
            s->elementary_transfer_size = size;
1041 5391d806 bellard
            /* we cannot transmit more than one sector at a time */
1042 5391d806 bellard
            if (s->lba != -1) {
1043 98087450 bellard
                if (size > (s->cd_sector_size - s->io_buffer_index))
1044 98087450 bellard
                    size = (s->cd_sector_size - s->io_buffer_index);
1045 5391d806 bellard
            }
1046 5391d806 bellard
            ide_transfer_start(s, s->io_buffer + s->io_buffer_index, 
1047 5391d806 bellard
                               size, ide_atapi_cmd_reply_end);
1048 5391d806 bellard
            s->packet_transfer_size -= size;
1049 5391d806 bellard
            s->elementary_transfer_size -= size;
1050 5391d806 bellard
            s->io_buffer_index += size;
1051 5391d806 bellard
            ide_set_irq(s);
1052 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
1053 5391d806 bellard
            printf("status=0x%x\n", s->status);
1054 5391d806 bellard
#endif
1055 5391d806 bellard
        }
1056 5391d806 bellard
    }
1057 5391d806 bellard
}
1058 5391d806 bellard
1059 5391d806 bellard
/* send a reply of 'size' bytes in s->io_buffer to an ATAPI command */
1060 5391d806 bellard
static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size)
1061 5391d806 bellard
{
1062 5391d806 bellard
    if (size > max_size)
1063 5391d806 bellard
        size = max_size;
1064 5391d806 bellard
    s->lba = -1; /* no sector read */
1065 5391d806 bellard
    s->packet_transfer_size = size;
1066 5391d806 bellard
    s->elementary_transfer_size = 0;
1067 5391d806 bellard
    s->io_buffer_index = 0;
1068 5391d806 bellard
1069 5391d806 bellard
    s->status = READY_STAT;
1070 5391d806 bellard
    ide_atapi_cmd_reply_end(s);
1071 5391d806 bellard
}
1072 5391d806 bellard
1073 5391d806 bellard
/* start a CD-CDROM read command */
1074 98087450 bellard
static void ide_atapi_cmd_read_pio(IDEState *s, int lba, int nb_sectors,
1075 98087450 bellard
                                   int sector_size)
1076 5391d806 bellard
{
1077 5391d806 bellard
    s->lba = lba;
1078 98087450 bellard
    s->packet_transfer_size = nb_sectors * sector_size;
1079 5391d806 bellard
    s->elementary_transfer_size = 0;
1080 98087450 bellard
    s->io_buffer_index = sector_size;
1081 98087450 bellard
    s->cd_sector_size = sector_size;
1082 5391d806 bellard
1083 5391d806 bellard
    s->status = READY_STAT;
1084 5391d806 bellard
    ide_atapi_cmd_reply_end(s);
1085 5391d806 bellard
}
1086 5391d806 bellard
1087 98087450 bellard
/* ATAPI DMA support */
1088 8ccad811 bellard
1089 8ccad811 bellard
/* XXX: handle read errors */
1090 8ccad811 bellard
static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret)
1091 98087450 bellard
{
1092 8ccad811 bellard
    BMDMAState *bm = opaque;
1093 8ccad811 bellard
    IDEState *s = bm->ide_if;
1094 8ccad811 bellard
    int data_offset, n;
1095 8ccad811 bellard
1096 66c6ef76 bellard
    if (ret < 0) {
1097 66c6ef76 bellard
        ide_atapi_io_error(s, ret);
1098 66c6ef76 bellard
        goto eot;
1099 66c6ef76 bellard
    }
1100 66c6ef76 bellard
1101 8ccad811 bellard
    if (s->io_buffer_size > 0) {
1102 8ccad811 bellard
        if (s->cd_sector_size == 2352) {
1103 8ccad811 bellard
            n = 1;
1104 8ccad811 bellard
            cd_data_to_raw(s->io_buffer, s->lba);
1105 8ccad811 bellard
        } else {
1106 8ccad811 bellard
            n = s->io_buffer_size >> 11;
1107 98087450 bellard
        }
1108 8ccad811 bellard
        s->packet_transfer_size -= s->io_buffer_size;
1109 8ccad811 bellard
        s->lba += n;
1110 8ccad811 bellard
        if (dma_buf_rw(bm, 1) == 0)
1111 8ccad811 bellard
            goto eot;
1112 98087450 bellard
    }
1113 8ccad811 bellard
1114 98087450 bellard
    if (s->packet_transfer_size <= 0) {
1115 98087450 bellard
        s->status = READY_STAT;
1116 98087450 bellard
        s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
1117 98087450 bellard
        ide_set_irq(s);
1118 8ccad811 bellard
    eot:
1119 8ccad811 bellard
        bm->status &= ~BM_STATUS_DMAING;
1120 8ccad811 bellard
        bm->status |= BM_STATUS_INT;
1121 8ccad811 bellard
        bm->dma_cb = NULL;
1122 8ccad811 bellard
        bm->ide_if = NULL;
1123 8ccad811 bellard
        bm->aiocb = NULL;
1124 8ccad811 bellard
        return;
1125 8ccad811 bellard
    }
1126 8ccad811 bellard
    
1127 8ccad811 bellard
    s->io_buffer_index = 0;
1128 8ccad811 bellard
    if (s->cd_sector_size == 2352) {
1129 8ccad811 bellard
        n = 1;
1130 8ccad811 bellard
        s->io_buffer_size = s->cd_sector_size;
1131 8ccad811 bellard
        data_offset = 16;
1132 8ccad811 bellard
    } else {
1133 8ccad811 bellard
        n = s->packet_transfer_size >> 11;
1134 8ccad811 bellard
        if (n > (MAX_MULT_SECTORS / 4))
1135 8ccad811 bellard
            n = (MAX_MULT_SECTORS / 4);
1136 8ccad811 bellard
        s->io_buffer_size = n * 2048;
1137 8ccad811 bellard
        data_offset = 0;
1138 98087450 bellard
    }
1139 8ccad811 bellard
#ifdef DEBUG_AIO
1140 8ccad811 bellard
    printf("aio_read_cd: lba=%u n=%d\n", s->lba, n);
1141 8ccad811 bellard
#endif
1142 8ccad811 bellard
    bm->aiocb = bdrv_aio_read(s->bs, (int64_t)s->lba << 2, 
1143 8ccad811 bellard
                              s->io_buffer + data_offset, n * 4, 
1144 8ccad811 bellard
                              ide_atapi_cmd_read_dma_cb, bm);
1145 66c6ef76 bellard
    if (!bm->aiocb) {
1146 66c6ef76 bellard
        /* Note: media not present is the most likely case */
1147 66c6ef76 bellard
        ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1148 66c6ef76 bellard
                            ASC_MEDIUM_NOT_PRESENT);
1149 66c6ef76 bellard
        goto eot;
1150 66c6ef76 bellard
    }
1151 98087450 bellard
}
1152 98087450 bellard
1153 98087450 bellard
/* start a CD-CDROM read command with DMA */
1154 98087450 bellard
/* XXX: test if DMA is available */
1155 98087450 bellard
static void ide_atapi_cmd_read_dma(IDEState *s, int lba, int nb_sectors,
1156 98087450 bellard
                                   int sector_size)
1157 98087450 bellard
{
1158 98087450 bellard
    s->lba = lba;
1159 98087450 bellard
    s->packet_transfer_size = nb_sectors * sector_size;
1160 8ccad811 bellard
    s->io_buffer_index = 0;
1161 8ccad811 bellard
    s->io_buffer_size = 0;
1162 98087450 bellard
    s->cd_sector_size = sector_size;
1163 98087450 bellard
1164 8ccad811 bellard
    /* XXX: check if BUSY_STAT should be set */
1165 8ccad811 bellard
    s->status = READY_STAT | DRQ_STAT | BUSY_STAT;
1166 98087450 bellard
    ide_dma_start(s, ide_atapi_cmd_read_dma_cb);
1167 98087450 bellard
}
1168 98087450 bellard
1169 98087450 bellard
static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors, 
1170 98087450 bellard
                               int sector_size)
1171 98087450 bellard
{
1172 98087450 bellard
#ifdef DEBUG_IDE_ATAPI
1173 98087450 bellard
    printf("read: LBA=%d nb_sectors=%d\n", lba, nb_sectors);
1174 98087450 bellard
#endif
1175 98087450 bellard
    if (s->atapi_dma) {
1176 98087450 bellard
        ide_atapi_cmd_read_dma(s, lba, nb_sectors, sector_size);
1177 98087450 bellard
    } else {
1178 98087450 bellard
        ide_atapi_cmd_read_pio(s, lba, nb_sectors, sector_size);
1179 98087450 bellard
    }
1180 98087450 bellard
}
1181 98087450 bellard
1182 5391d806 bellard
static void ide_atapi_cmd(IDEState *s)
1183 5391d806 bellard
{
1184 5391d806 bellard
    const uint8_t *packet;
1185 5391d806 bellard
    uint8_t *buf;
1186 5391d806 bellard
    int max_len;
1187 5391d806 bellard
1188 5391d806 bellard
    packet = s->io_buffer;
1189 5391d806 bellard
    buf = s->io_buffer;
1190 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
1191 5391d806 bellard
    {
1192 5391d806 bellard
        int i;
1193 5391d806 bellard
        printf("ATAPI limit=0x%x packet:", s->lcyl | (s->hcyl << 8));
1194 5391d806 bellard
        for(i = 0; i < ATAPI_PACKET_SIZE; i++) {
1195 5391d806 bellard
            printf(" %02x", packet[i]);
1196 5391d806 bellard
        }
1197 5391d806 bellard
        printf("\n");
1198 5391d806 bellard
    }
1199 5391d806 bellard
#endif
1200 5391d806 bellard
    switch(s->io_buffer[0]) {
1201 5391d806 bellard
    case GPCMD_TEST_UNIT_READY:
1202 caed8802 bellard
        if (bdrv_is_inserted(s->bs)) {
1203 5391d806 bellard
            ide_atapi_cmd_ok(s);
1204 5391d806 bellard
        } else {
1205 5391d806 bellard
            ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1206 5391d806 bellard
                                ASC_MEDIUM_NOT_PRESENT);
1207 5391d806 bellard
        }
1208 5391d806 bellard
        break;
1209 5391d806 bellard
    case GPCMD_MODE_SENSE_10:
1210 5391d806 bellard
        {
1211 5391d806 bellard
            int action, code;
1212 5391d806 bellard
            max_len = ube16_to_cpu(packet + 7);
1213 5391d806 bellard
            action = packet[2] >> 6;
1214 5391d806 bellard
            code = packet[2] & 0x3f;
1215 5391d806 bellard
            switch(action) {
1216 5391d806 bellard
            case 0: /* current values */
1217 5391d806 bellard
                switch(code) {
1218 5391d806 bellard
                case 0x01: /* error recovery */
1219 5391d806 bellard
                    cpu_to_ube16(&buf[0], 16 + 6);
1220 5391d806 bellard
                    buf[2] = 0x70;
1221 5391d806 bellard
                    buf[3] = 0;
1222 5391d806 bellard
                    buf[4] = 0;
1223 5391d806 bellard
                    buf[5] = 0;
1224 5391d806 bellard
                    buf[6] = 0;
1225 5391d806 bellard
                    buf[7] = 0;
1226 5391d806 bellard
1227 5391d806 bellard
                    buf[8] = 0x01;
1228 5391d806 bellard
                    buf[9] = 0x06;
1229 5391d806 bellard
                    buf[10] = 0x00;
1230 5391d806 bellard
                    buf[11] = 0x05;
1231 5391d806 bellard
                    buf[12] = 0x00;
1232 5391d806 bellard
                    buf[13] = 0x00;
1233 5391d806 bellard
                    buf[14] = 0x00;
1234 5391d806 bellard
                    buf[15] = 0x00;
1235 5391d806 bellard
                    ide_atapi_cmd_reply(s, 16, max_len);
1236 5391d806 bellard
                    break;
1237 5391d806 bellard
                case 0x2a:
1238 5391d806 bellard
                    cpu_to_ube16(&buf[0], 28 + 6);
1239 5391d806 bellard
                    buf[2] = 0x70;
1240 5391d806 bellard
                    buf[3] = 0;
1241 5391d806 bellard
                    buf[4] = 0;
1242 5391d806 bellard
                    buf[5] = 0;
1243 5391d806 bellard
                    buf[6] = 0;
1244 5391d806 bellard
                    buf[7] = 0;
1245 5391d806 bellard
1246 5391d806 bellard
                    buf[8] = 0x2a;
1247 5391d806 bellard
                    buf[9] = 0x12;
1248 5391d806 bellard
                    buf[10] = 0x00;
1249 5391d806 bellard
                    buf[11] = 0x00;
1250 5391d806 bellard
                    
1251 5391d806 bellard
                    buf[12] = 0x70;
1252 5391d806 bellard
                    buf[13] = 3 << 5;
1253 5391d806 bellard
                    buf[14] = (1 << 0) | (1 << 3) | (1 << 5);
1254 caed8802 bellard
                    if (bdrv_is_locked(s->bs))
1255 5391d806 bellard
                        buf[6] |= 1 << 1;
1256 5391d806 bellard
                    buf[15] = 0x00;
1257 5391d806 bellard
                    cpu_to_ube16(&buf[16], 706);
1258 5391d806 bellard
                    buf[18] = 0;
1259 5391d806 bellard
                    buf[19] = 2;
1260 5391d806 bellard
                    cpu_to_ube16(&buf[20], 512);
1261 5391d806 bellard
                    cpu_to_ube16(&buf[22], 706);
1262 5391d806 bellard
                    buf[24] = 0;
1263 5391d806 bellard
                    buf[25] = 0;
1264 5391d806 bellard
                    buf[26] = 0;
1265 5391d806 bellard
                    buf[27] = 0;
1266 5391d806 bellard
                    ide_atapi_cmd_reply(s, 28, max_len);
1267 5391d806 bellard
                    break;
1268 5391d806 bellard
                default:
1269 5391d806 bellard
                    goto error_cmd;
1270 5391d806 bellard
                }
1271 5391d806 bellard
                break;
1272 5391d806 bellard
            case 1: /* changeable values */
1273 5391d806 bellard
                goto error_cmd;
1274 5391d806 bellard
            case 2: /* default values */
1275 5391d806 bellard
                goto error_cmd;
1276 5391d806 bellard
            default:
1277 5391d806 bellard
            case 3: /* saved values */
1278 5391d806 bellard
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1279 5391d806 bellard
                                    ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
1280 5391d806 bellard
                break;
1281 5391d806 bellard
            }
1282 5391d806 bellard
        }
1283 5391d806 bellard
        break;
1284 5391d806 bellard
    case GPCMD_REQUEST_SENSE:
1285 5391d806 bellard
        max_len = packet[4];
1286 5391d806 bellard
        memset(buf, 0, 18);
1287 5391d806 bellard
        buf[0] = 0x70 | (1 << 7);
1288 5391d806 bellard
        buf[2] = s->sense_key;
1289 5391d806 bellard
        buf[7] = 10;
1290 5391d806 bellard
        buf[12] = s->asc;
1291 5391d806 bellard
        ide_atapi_cmd_reply(s, 18, max_len);
1292 5391d806 bellard
        break;
1293 5391d806 bellard
    case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
1294 caed8802 bellard
        if (bdrv_is_inserted(s->bs)) {
1295 caed8802 bellard
            bdrv_set_locked(s->bs, packet[4] & 1);
1296 5391d806 bellard
            ide_atapi_cmd_ok(s);
1297 5391d806 bellard
        } else {
1298 5391d806 bellard
            ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1299 5391d806 bellard
                                ASC_MEDIUM_NOT_PRESENT);
1300 5391d806 bellard
        }
1301 5391d806 bellard
        break;
1302 5391d806 bellard
    case GPCMD_READ_10:
1303 5391d806 bellard
    case GPCMD_READ_12:
1304 5391d806 bellard
        {
1305 5391d806 bellard
            int nb_sectors, lba;
1306 5391d806 bellard
1307 5391d806 bellard
            if (packet[0] == GPCMD_READ_10)
1308 5391d806 bellard
                nb_sectors = ube16_to_cpu(packet + 7);
1309 5391d806 bellard
            else
1310 5391d806 bellard
                nb_sectors = ube32_to_cpu(packet + 6);
1311 5391d806 bellard
            lba = ube32_to_cpu(packet + 2);
1312 5391d806 bellard
            if (nb_sectors == 0) {
1313 5391d806 bellard
                ide_atapi_cmd_ok(s);
1314 5391d806 bellard
                break;
1315 5391d806 bellard
            }
1316 98087450 bellard
            ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
1317 98087450 bellard
        }
1318 98087450 bellard
        break;
1319 98087450 bellard
    case GPCMD_READ_CD:
1320 98087450 bellard
        {
1321 98087450 bellard
            int nb_sectors, lba, transfer_request;
1322 98087450 bellard
1323 98087450 bellard
            nb_sectors = (packet[6] << 16) | (packet[7] << 8) | packet[8];
1324 98087450 bellard
            lba = ube32_to_cpu(packet + 2);
1325 98087450 bellard
            if (nb_sectors == 0) {
1326 98087450 bellard
                ide_atapi_cmd_ok(s);
1327 98087450 bellard
                break;
1328 98087450 bellard
            }
1329 98087450 bellard
            transfer_request = packet[9];
1330 98087450 bellard
            switch(transfer_request & 0xf8) {
1331 98087450 bellard
            case 0x00:
1332 98087450 bellard
                /* nothing */
1333 98087450 bellard
                ide_atapi_cmd_ok(s);
1334 98087450 bellard
                break;
1335 98087450 bellard
            case 0x10:
1336 98087450 bellard
                /* normal read */
1337 98087450 bellard
                ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
1338 98087450 bellard
                break;
1339 98087450 bellard
            case 0xf8:
1340 98087450 bellard
                /* read all data */
1341 98087450 bellard
                ide_atapi_cmd_read(s, lba, nb_sectors, 2352);
1342 98087450 bellard
                break;
1343 98087450 bellard
            default:
1344 98087450 bellard
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1345 98087450 bellard
                                    ASC_INV_FIELD_IN_CMD_PACKET);
1346 98087450 bellard
                break;
1347 98087450 bellard
            }
1348 5391d806 bellard
        }
1349 5391d806 bellard
        break;
1350 5391d806 bellard
    case GPCMD_SEEK:
1351 5391d806 bellard
        {
1352 5391d806 bellard
            int lba;
1353 66c6ef76 bellard
            int64_t total_sectors;
1354 66c6ef76 bellard
1355 66c6ef76 bellard
            bdrv_get_geometry(s->bs, &total_sectors);
1356 66c6ef76 bellard
            total_sectors >>= 2;
1357 66c6ef76 bellard
            if (total_sectors <= 0) {
1358 5391d806 bellard
                ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1359 5391d806 bellard
                                    ASC_MEDIUM_NOT_PRESENT);
1360 5391d806 bellard
                break;
1361 5391d806 bellard
            }
1362 5391d806 bellard
            lba = ube32_to_cpu(packet + 2);
1363 66c6ef76 bellard
            if (lba >= total_sectors) {
1364 5391d806 bellard
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1365 5391d806 bellard
                                    ASC_LOGICAL_BLOCK_OOR);
1366 5391d806 bellard
                break;
1367 5391d806 bellard
            }
1368 5391d806 bellard
            ide_atapi_cmd_ok(s);
1369 5391d806 bellard
        }
1370 5391d806 bellard
        break;
1371 5391d806 bellard
    case GPCMD_START_STOP_UNIT:
1372 5391d806 bellard
        {
1373 5391d806 bellard
            int start, eject;
1374 5391d806 bellard
            start = packet[4] & 1;
1375 5391d806 bellard
            eject = (packet[4] >> 1) & 1;
1376 5391d806 bellard
            
1377 caed8802 bellard
            if (eject && !start) {
1378 caed8802 bellard
                /* eject the disk */
1379 66c6ef76 bellard
                bdrv_eject(s->bs, 1);
1380 66c6ef76 bellard
            } else if (eject && start) {
1381 66c6ef76 bellard
                /* close the tray */
1382 66c6ef76 bellard
                bdrv_eject(s->bs, 0);
1383 caed8802 bellard
            }
1384 5391d806 bellard
            ide_atapi_cmd_ok(s);
1385 5391d806 bellard
        }
1386 5391d806 bellard
        break;
1387 5391d806 bellard
    case GPCMD_MECHANISM_STATUS:
1388 5391d806 bellard
        {
1389 5391d806 bellard
            max_len = ube16_to_cpu(packet + 8);
1390 5391d806 bellard
            cpu_to_ube16(buf, 0);
1391 5391d806 bellard
            /* no current LBA */
1392 5391d806 bellard
            buf[2] = 0;
1393 5391d806 bellard
            buf[3] = 0;
1394 5391d806 bellard
            buf[4] = 0;
1395 5391d806 bellard
            buf[5] = 1;
1396 5391d806 bellard
            cpu_to_ube16(buf + 6, 0);
1397 5391d806 bellard
            ide_atapi_cmd_reply(s, 8, max_len);
1398 5391d806 bellard
        }
1399 5391d806 bellard
        break;
1400 5391d806 bellard
    case GPCMD_READ_TOC_PMA_ATIP:
1401 5391d806 bellard
        {
1402 5391d806 bellard
            int format, msf, start_track, len;
1403 66c6ef76 bellard
            int64_t total_sectors;
1404 5391d806 bellard
1405 66c6ef76 bellard
            bdrv_get_geometry(s->bs, &total_sectors);
1406 66c6ef76 bellard
            total_sectors >>= 2;
1407 66c6ef76 bellard
            if (total_sectors <= 0) {
1408 5391d806 bellard
                ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1409 5391d806 bellard
                                    ASC_MEDIUM_NOT_PRESENT);
1410 5391d806 bellard
                break;
1411 5391d806 bellard
            }
1412 5391d806 bellard
            max_len = ube16_to_cpu(packet + 7);
1413 5391d806 bellard
            format = packet[9] >> 6;
1414 5391d806 bellard
            msf = (packet[1] >> 1) & 1;
1415 5391d806 bellard
            start_track = packet[6];
1416 5391d806 bellard
            switch(format) {
1417 5391d806 bellard
            case 0:
1418 66c6ef76 bellard
                len = cdrom_read_toc(total_sectors, buf, msf, start_track);
1419 5391d806 bellard
                if (len < 0)
1420 5391d806 bellard
                    goto error_cmd;
1421 5391d806 bellard
                ide_atapi_cmd_reply(s, len, max_len);
1422 5391d806 bellard
                break;
1423 5391d806 bellard
            case 1:
1424 5391d806 bellard
                /* multi session : only a single session defined */
1425 5391d806 bellard
                memset(buf, 0, 12);
1426 5391d806 bellard
                buf[1] = 0x0a;
1427 5391d806 bellard
                buf[2] = 0x01;
1428 5391d806 bellard
                buf[3] = 0x01;
1429 5391d806 bellard
                ide_atapi_cmd_reply(s, 12, max_len);
1430 5391d806 bellard
                break;
1431 98087450 bellard
            case 2:
1432 66c6ef76 bellard
                len = cdrom_read_toc_raw(total_sectors, buf, msf, start_track);
1433 98087450 bellard
                if (len < 0)
1434 98087450 bellard
                    goto error_cmd;
1435 98087450 bellard
                ide_atapi_cmd_reply(s, len, max_len);
1436 98087450 bellard
                break;
1437 5391d806 bellard
            default:
1438 7f777bf3 bellard
            error_cmd:
1439 7f777bf3 bellard
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1440 7f777bf3 bellard
                                    ASC_INV_FIELD_IN_CMD_PACKET);
1441 7f777bf3 bellard
                break;
1442 5391d806 bellard
            }
1443 5391d806 bellard
        }
1444 5391d806 bellard
        break;
1445 5391d806 bellard
    case GPCMD_READ_CDVD_CAPACITY:
1446 66c6ef76 bellard
        {
1447 66c6ef76 bellard
            int64_t total_sectors;
1448 66c6ef76 bellard
1449 66c6ef76 bellard
            bdrv_get_geometry(s->bs, &total_sectors);
1450 66c6ef76 bellard
            total_sectors >>= 2;
1451 66c6ef76 bellard
            if (total_sectors <= 0) {
1452 66c6ef76 bellard
                ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1453 66c6ef76 bellard
                                    ASC_MEDIUM_NOT_PRESENT);
1454 66c6ef76 bellard
                break;
1455 66c6ef76 bellard
            }
1456 66c6ef76 bellard
            /* NOTE: it is really the number of sectors minus 1 */
1457 66c6ef76 bellard
            cpu_to_ube32(buf, total_sectors - 1);
1458 66c6ef76 bellard
            cpu_to_ube32(buf + 4, 2048);
1459 66c6ef76 bellard
            ide_atapi_cmd_reply(s, 8, 8);
1460 5391d806 bellard
        }
1461 5391d806 bellard
        break;
1462 bd0d90b2 bellard
    case GPCMD_INQUIRY:
1463 bd0d90b2 bellard
        max_len = packet[4];
1464 bd0d90b2 bellard
        buf[0] = 0x05; /* CD-ROM */
1465 bd0d90b2 bellard
        buf[1] = 0x80; /* removable */
1466 bd0d90b2 bellard
        buf[2] = 0x00; /* ISO */
1467 bd0d90b2 bellard
        buf[3] = 0x21; /* ATAPI-2 (XXX: put ATAPI-4 ?) */
1468 bd0d90b2 bellard
        buf[4] = 31; /* additionnal length */
1469 bd0d90b2 bellard
        buf[5] = 0; /* reserved */
1470 bd0d90b2 bellard
        buf[6] = 0; /* reserved */
1471 bd0d90b2 bellard
        buf[7] = 0; /* reserved */
1472 bd0d90b2 bellard
        padstr8(buf + 8, 8, "QEMU");
1473 bd0d90b2 bellard
        padstr8(buf + 16, 16, "QEMU CD-ROM");
1474 bd0d90b2 bellard
        padstr8(buf + 32, 4, QEMU_VERSION);
1475 bd0d90b2 bellard
        ide_atapi_cmd_reply(s, 36, max_len);
1476 bd0d90b2 bellard
        break;
1477 5391d806 bellard
    default:
1478 5391d806 bellard
        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1479 7f777bf3 bellard
                            ASC_ILLEGAL_OPCODE);
1480 5391d806 bellard
        break;
1481 5391d806 bellard
    }
1482 5391d806 bellard
}
1483 5391d806 bellard
1484 c2ff060f bellard
static void ide_cmd_lba48_transform(IDEState *s, int lba48)
1485 c2ff060f bellard
{
1486 c2ff060f bellard
    s->lba48 = lba48;
1487 c2ff060f bellard
1488 c2ff060f bellard
    /* handle the 'magic' 0 nsector count conversion here. to avoid
1489 c2ff060f bellard
     * fiddling with the rest of the read logic, we just store the
1490 c2ff060f bellard
     * full sector count in ->nsector and ignore ->hob_nsector from now
1491 c2ff060f bellard
     */
1492 c2ff060f bellard
    if (!s->lba48) {
1493 c2ff060f bellard
        if (!s->nsector)
1494 c2ff060f bellard
            s->nsector = 256;
1495 c2ff060f bellard
    } else {
1496 c2ff060f bellard
        if (!s->nsector && !s->hob_nsector)
1497 c2ff060f bellard
            s->nsector = 65536;
1498 c2ff060f bellard
        else {
1499 c2ff060f bellard
            int lo = s->nsector;
1500 c2ff060f bellard
            int hi = s->hob_nsector;
1501 c2ff060f bellard
1502 c2ff060f bellard
            s->nsector = (hi << 8) | lo;
1503 c2ff060f bellard
        }
1504 c2ff060f bellard
    }
1505 c2ff060f bellard
}
1506 c2ff060f bellard
1507 c2ff060f bellard
static void ide_clear_hob(IDEState *ide_if)
1508 c2ff060f bellard
{
1509 c2ff060f bellard
    /* any write clears HOB high bit of device control register */
1510 c2ff060f bellard
    ide_if[0].select &= ~(1 << 7);
1511 c2ff060f bellard
    ide_if[1].select &= ~(1 << 7);
1512 c2ff060f bellard
}
1513 c2ff060f bellard
1514 caed8802 bellard
static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
1515 caed8802 bellard
{
1516 caed8802 bellard
    IDEState *ide_if = opaque;
1517 c45c3d00 bellard
    IDEState *s;
1518 5391d806 bellard
    int unit, n;
1519 c2ff060f bellard
    int lba48 = 0;
1520 5391d806 bellard
1521 5391d806 bellard
#ifdef DEBUG_IDE
1522 5391d806 bellard
    printf("IDE: write addr=0x%x val=0x%02x\n", addr, val);
1523 5391d806 bellard
#endif
1524 c2ff060f bellard
1525 5391d806 bellard
    addr &= 7;
1526 5391d806 bellard
    switch(addr) {
1527 5391d806 bellard
    case 0:
1528 5391d806 bellard
        break;
1529 5391d806 bellard
    case 1:
1530 c2ff060f bellard
        ide_clear_hob(ide_if);
1531 c45c3d00 bellard
        /* NOTE: data is written to the two drives */
1532 c2ff060f bellard
        ide_if[0].hob_feature = ide_if[0].feature;
1533 c2ff060f bellard
        ide_if[1].hob_feature = ide_if[1].feature;
1534 c45c3d00 bellard
        ide_if[0].feature = val;
1535 c45c3d00 bellard
        ide_if[1].feature = val;
1536 5391d806 bellard
        break;
1537 5391d806 bellard
    case 2:
1538 c2ff060f bellard
        ide_clear_hob(ide_if);
1539 c2ff060f bellard
        ide_if[0].hob_nsector = ide_if[0].nsector;
1540 c2ff060f bellard
        ide_if[1].hob_nsector = ide_if[1].nsector;
1541 c45c3d00 bellard
        ide_if[0].nsector = val;
1542 c45c3d00 bellard
        ide_if[1].nsector = val;
1543 5391d806 bellard
        break;
1544 5391d806 bellard
    case 3:
1545 c2ff060f bellard
        ide_clear_hob(ide_if);
1546 c2ff060f bellard
        ide_if[0].hob_sector = ide_if[0].sector;
1547 c2ff060f bellard
        ide_if[1].hob_sector = ide_if[1].sector;
1548 c45c3d00 bellard
        ide_if[0].sector = val;
1549 c45c3d00 bellard
        ide_if[1].sector = val;
1550 5391d806 bellard
        break;
1551 5391d806 bellard
    case 4:
1552 c2ff060f bellard
        ide_clear_hob(ide_if);
1553 c2ff060f bellard
        ide_if[0].hob_lcyl = ide_if[0].lcyl;
1554 c2ff060f bellard
        ide_if[1].hob_lcyl = ide_if[1].lcyl;
1555 c45c3d00 bellard
        ide_if[0].lcyl = val;
1556 c45c3d00 bellard
        ide_if[1].lcyl = val;
1557 5391d806 bellard
        break;
1558 5391d806 bellard
    case 5:
1559 c2ff060f bellard
        ide_clear_hob(ide_if);
1560 c2ff060f bellard
        ide_if[0].hob_hcyl = ide_if[0].hcyl;
1561 c2ff060f bellard
        ide_if[1].hob_hcyl = ide_if[1].hcyl;
1562 c45c3d00 bellard
        ide_if[0].hcyl = val;
1563 c45c3d00 bellard
        ide_if[1].hcyl = val;
1564 5391d806 bellard
        break;
1565 5391d806 bellard
    case 6:
1566 c2ff060f bellard
        /* FIXME: HOB readback uses bit 7 */
1567 7ae98627 bellard
        ide_if[0].select = (val & ~0x10) | 0xa0;
1568 7ae98627 bellard
        ide_if[1].select = (val | 0x10) | 0xa0;
1569 5391d806 bellard
        /* select drive */
1570 5391d806 bellard
        unit = (val >> 4) & 1;
1571 5391d806 bellard
        s = ide_if + unit;
1572 5391d806 bellard
        ide_if->cur_drive = s;
1573 5391d806 bellard
        break;
1574 5391d806 bellard
    default:
1575 5391d806 bellard
    case 7:
1576 5391d806 bellard
        /* command */
1577 5391d806 bellard
#if defined(DEBUG_IDE)
1578 5391d806 bellard
        printf("ide: CMD=%02x\n", val);
1579 5391d806 bellard
#endif
1580 c45c3d00 bellard
        s = ide_if->cur_drive;
1581 66201e2d bellard
        /* ignore commands to non existant slave */
1582 66201e2d bellard
        if (s != ide_if && !s->bs) 
1583 66201e2d bellard
            break;
1584 c2ff060f bellard
1585 5391d806 bellard
        switch(val) {
1586 5391d806 bellard
        case WIN_IDENTIFY:
1587 5391d806 bellard
            if (s->bs && !s->is_cdrom) {
1588 5391d806 bellard
                ide_identify(s);
1589 2a282056 bellard
                s->status = READY_STAT | SEEK_STAT;
1590 5391d806 bellard
                ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
1591 5391d806 bellard
            } else {
1592 5391d806 bellard
                if (s->is_cdrom) {
1593 5391d806 bellard
                    ide_set_signature(s);
1594 5391d806 bellard
                }
1595 5391d806 bellard
                ide_abort_command(s);
1596 5391d806 bellard
            }
1597 5391d806 bellard
            ide_set_irq(s);
1598 5391d806 bellard
            break;
1599 5391d806 bellard
        case WIN_SPECIFY:
1600 5391d806 bellard
        case WIN_RECAL:
1601 a136e5a8 bellard
            s->error = 0;
1602 769bec72 bellard
            s->status = READY_STAT | SEEK_STAT;
1603 5391d806 bellard
            ide_set_irq(s);
1604 5391d806 bellard
            break;
1605 5391d806 bellard
        case WIN_SETMULT:
1606 5391d806 bellard
            if (s->nsector > MAX_MULT_SECTORS || 
1607 5391d806 bellard
                s->nsector == 0 ||
1608 5391d806 bellard
                (s->nsector & (s->nsector - 1)) != 0) {
1609 5391d806 bellard
                ide_abort_command(s);
1610 5391d806 bellard
            } else {
1611 5391d806 bellard
                s->mult_sectors = s->nsector;
1612 5391d806 bellard
                s->status = READY_STAT;
1613 5391d806 bellard
            }
1614 5391d806 bellard
            ide_set_irq(s);
1615 5391d806 bellard
            break;
1616 c2ff060f bellard
        case WIN_VERIFY_EXT:
1617 c2ff060f bellard
            lba48 = 1;
1618 4ce900b4 bellard
        case WIN_VERIFY:
1619 4ce900b4 bellard
        case WIN_VERIFY_ONCE:
1620 4ce900b4 bellard
            /* do sector number check ? */
1621 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1622 4ce900b4 bellard
            s->status = READY_STAT;
1623 4ce900b4 bellard
            ide_set_irq(s);
1624 4ce900b4 bellard
            break;
1625 c2ff060f bellard
        case WIN_READ_EXT:
1626 c2ff060f bellard
            lba48 = 1;
1627 5391d806 bellard
        case WIN_READ:
1628 5391d806 bellard
        case WIN_READ_ONCE:
1629 6b136f9e bellard
            if (!s->bs) 
1630 6b136f9e bellard
                goto abort_cmd;
1631 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1632 5391d806 bellard
            s->req_nb_sectors = 1;
1633 5391d806 bellard
            ide_sector_read(s);
1634 5391d806 bellard
            break;
1635 c2ff060f bellard
        case WIN_WRITE_EXT:
1636 c2ff060f bellard
            lba48 = 1;
1637 5391d806 bellard
        case WIN_WRITE:
1638 5391d806 bellard
        case WIN_WRITE_ONCE:
1639 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1640 a136e5a8 bellard
            s->error = 0;
1641 f66723fa bellard
            s->status = SEEK_STAT | READY_STAT;
1642 5391d806 bellard
            s->req_nb_sectors = 1;
1643 5391d806 bellard
            ide_transfer_start(s, s->io_buffer, 512, ide_sector_write);
1644 5391d806 bellard
            break;
1645 c2ff060f bellard
        case WIN_MULTREAD_EXT:
1646 c2ff060f bellard
            lba48 = 1;
1647 5391d806 bellard
        case WIN_MULTREAD:
1648 5391d806 bellard
            if (!s->mult_sectors)
1649 5391d806 bellard
                goto abort_cmd;
1650 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1651 5391d806 bellard
            s->req_nb_sectors = s->mult_sectors;
1652 5391d806 bellard
            ide_sector_read(s);
1653 5391d806 bellard
            break;
1654 c2ff060f bellard
        case WIN_MULTWRITE_EXT:
1655 c2ff060f bellard
            lba48 = 1;
1656 5391d806 bellard
        case WIN_MULTWRITE:
1657 5391d806 bellard
            if (!s->mult_sectors)
1658 5391d806 bellard
                goto abort_cmd;
1659 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1660 a136e5a8 bellard
            s->error = 0;
1661 f66723fa bellard
            s->status = SEEK_STAT | READY_STAT;
1662 5391d806 bellard
            s->req_nb_sectors = s->mult_sectors;
1663 5391d806 bellard
            n = s->nsector;
1664 5391d806 bellard
            if (n > s->req_nb_sectors)
1665 5391d806 bellard
                n = s->req_nb_sectors;
1666 5391d806 bellard
            ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
1667 5391d806 bellard
            break;
1668 c2ff060f bellard
        case WIN_READDMA_EXT:
1669 c2ff060f bellard
            lba48 = 1;
1670 98087450 bellard
        case WIN_READDMA:
1671 98087450 bellard
        case WIN_READDMA_ONCE:
1672 98087450 bellard
            if (!s->bs) 
1673 98087450 bellard
                goto abort_cmd;
1674 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1675 98087450 bellard
            ide_sector_read_dma(s);
1676 98087450 bellard
            break;
1677 c2ff060f bellard
        case WIN_WRITEDMA_EXT:
1678 c2ff060f bellard
            lba48 = 1;
1679 98087450 bellard
        case WIN_WRITEDMA:
1680 98087450 bellard
        case WIN_WRITEDMA_ONCE:
1681 98087450 bellard
            if (!s->bs) 
1682 98087450 bellard
                goto abort_cmd;
1683 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1684 98087450 bellard
            ide_sector_write_dma(s);
1685 98087450 bellard
            break;
1686 c2ff060f bellard
        case WIN_READ_NATIVE_MAX_EXT:
1687 c2ff060f bellard
            lba48 = 1;
1688 5391d806 bellard
        case WIN_READ_NATIVE_MAX:
1689 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1690 5391d806 bellard
            ide_set_sector(s, s->nb_sectors - 1);
1691 5391d806 bellard
            s->status = READY_STAT;
1692 5391d806 bellard
            ide_set_irq(s);
1693 5391d806 bellard
            break;
1694 a136e5a8 bellard
        case WIN_CHECKPOWERMODE1:
1695 a136e5a8 bellard
            s->nsector = 0xff; /* device active or idle */
1696 a136e5a8 bellard
            s->status = READY_STAT;
1697 a136e5a8 bellard
            ide_set_irq(s);
1698 a136e5a8 bellard
            break;
1699 34e538ae bellard
        case WIN_SETFEATURES:
1700 34e538ae bellard
            if (!s->bs)
1701 34e538ae bellard
                goto abort_cmd;
1702 34e538ae bellard
            /* XXX: valid for CDROM ? */
1703 34e538ae bellard
            switch(s->feature) {
1704 34e538ae bellard
            case 0x02: /* write cache enable */
1705 34e538ae bellard
            case 0x82: /* write cache disable */
1706 34e538ae bellard
            case 0xaa: /* read look-ahead enable */
1707 34e538ae bellard
            case 0x55: /* read look-ahead disable */
1708 e0fe67aa bellard
                s->status = READY_STAT | SEEK_STAT;
1709 34e538ae bellard
                ide_set_irq(s);
1710 34e538ae bellard
                break;
1711 94458802 bellard
            case 0x03: { /* set transfer mode */
1712 94458802 bellard
                uint8_t val = s->nsector & 0x07;
1713 94458802 bellard
1714 94458802 bellard
                switch (s->nsector >> 3) {
1715 94458802 bellard
                    case 0x00: /* pio default */
1716 94458802 bellard
                    case 0x01: /* pio mode */
1717 94458802 bellard
                        put_le16(s->identify_data + 63,0x07);
1718 94458802 bellard
                        put_le16(s->identify_data + 88,0x3f);
1719 94458802 bellard
                        break;
1720 94458802 bellard
                    case 0x04: /* mdma mode */
1721 94458802 bellard
                        put_le16(s->identify_data + 63,0x07 | (1 << (val + 8)));
1722 94458802 bellard
                        put_le16(s->identify_data + 88,0x3f);
1723 94458802 bellard
                        break;
1724 94458802 bellard
                    case 0x08: /* udma mode */
1725 94458802 bellard
                        put_le16(s->identify_data + 63,0x07);
1726 94458802 bellard
                        put_le16(s->identify_data + 88,0x3f | (1 << (val + 8)));
1727 94458802 bellard
                        break;
1728 94458802 bellard
                    default:
1729 94458802 bellard
                        goto abort_cmd;
1730 94458802 bellard
                }
1731 94458802 bellard
                s->status = READY_STAT | SEEK_STAT;
1732 94458802 bellard
                ide_set_irq(s);
1733 94458802 bellard
                break;
1734 94458802 bellard
            }
1735 34e538ae bellard
            default:
1736 34e538ae bellard
                goto abort_cmd;
1737 34e538ae bellard
            }
1738 34e538ae bellard
            break;
1739 c2ff060f bellard
        case WIN_FLUSH_CACHE:
1740 c2ff060f bellard
        case WIN_FLUSH_CACHE_EXT:
1741 7a6cba61 pbrook
            if (s->bs)
1742 7a6cba61 pbrook
                bdrv_flush(s->bs);
1743 7a6cba61 pbrook
            s->status = READY_STAT;
1744 7a6cba61 pbrook
            ide_set_irq(s);
1745 7a6cba61 pbrook
            break;
1746 a7dfe172 bellard
        case WIN_STANDBYNOW1:
1747 c451ee71 bellard
        case WIN_IDLEIMMEDIATE:
1748 a7dfe172 bellard
            s->status = READY_STAT;
1749 a7dfe172 bellard
            ide_set_irq(s);
1750 a7dfe172 bellard
            break;
1751 5391d806 bellard
            /* ATAPI commands */
1752 5391d806 bellard
        case WIN_PIDENTIFY:
1753 5391d806 bellard
            if (s->is_cdrom) {
1754 5391d806 bellard
                ide_atapi_identify(s);
1755 1298fe63 bellard
                s->status = READY_STAT | SEEK_STAT;
1756 5391d806 bellard
                ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
1757 5391d806 bellard
            } else {
1758 5391d806 bellard
                ide_abort_command(s);
1759 5391d806 bellard
            }
1760 5391d806 bellard
            ide_set_irq(s);
1761 5391d806 bellard
            break;
1762 c451ee71 bellard
        case WIN_DIAGNOSE:
1763 c451ee71 bellard
            ide_set_signature(s);
1764 c451ee71 bellard
            s->status = 0x00; /* NOTE: READY is _not_ set */
1765 c451ee71 bellard
            s->error = 0x01;
1766 c451ee71 bellard
            break;
1767 5391d806 bellard
        case WIN_SRST:
1768 5391d806 bellard
            if (!s->is_cdrom)
1769 5391d806 bellard
                goto abort_cmd;
1770 5391d806 bellard
            ide_set_signature(s);
1771 6b136f9e bellard
            s->status = 0x00; /* NOTE: READY is _not_ set */
1772 5391d806 bellard
            s->error = 0x01;
1773 5391d806 bellard
            break;
1774 5391d806 bellard
        case WIN_PACKETCMD:
1775 5391d806 bellard
            if (!s->is_cdrom)
1776 5391d806 bellard
                goto abort_cmd;
1777 98087450 bellard
            /* overlapping commands not supported */
1778 98087450 bellard
            if (s->feature & 0x02)
1779 5391d806 bellard
                goto abort_cmd;
1780 98087450 bellard
            s->atapi_dma = s->feature & 1;
1781 5391d806 bellard
            s->nsector = 1;
1782 5391d806 bellard
            ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE, 
1783 5391d806 bellard
                               ide_atapi_cmd);
1784 5391d806 bellard
            break;
1785 5391d806 bellard
        default:
1786 5391d806 bellard
        abort_cmd:
1787 5391d806 bellard
            ide_abort_command(s);
1788 5391d806 bellard
            ide_set_irq(s);
1789 5391d806 bellard
            break;
1790 5391d806 bellard
        }
1791 5391d806 bellard
    }
1792 5391d806 bellard
}
1793 5391d806 bellard
1794 caed8802 bellard
static uint32_t ide_ioport_read(void *opaque, uint32_t addr1)
1795 5391d806 bellard
{
1796 7ae98627 bellard
    IDEState *ide_if = opaque;
1797 7ae98627 bellard
    IDEState *s = ide_if->cur_drive;
1798 5391d806 bellard
    uint32_t addr;
1799 c2ff060f bellard
    int ret, hob;
1800 5391d806 bellard
1801 5391d806 bellard
    addr = addr1 & 7;
1802 c2ff060f bellard
    /* FIXME: HOB readback uses bit 7, but it's always set right now */
1803 c2ff060f bellard
    //hob = s->select & (1 << 7);
1804 c2ff060f bellard
    hob = 0;
1805 5391d806 bellard
    switch(addr) {
1806 5391d806 bellard
    case 0:
1807 5391d806 bellard
        ret = 0xff;
1808 5391d806 bellard
        break;
1809 5391d806 bellard
    case 1:
1810 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
1811 c45c3d00 bellard
            ret = 0;
1812 c2ff060f bellard
        else if (!hob)
1813 c45c3d00 bellard
            ret = s->error;
1814 c2ff060f bellard
        else
1815 c2ff060f bellard
            ret = s->hob_feature;
1816 5391d806 bellard
        break;
1817 5391d806 bellard
    case 2:
1818 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
1819 c45c3d00 bellard
            ret = 0;
1820 c2ff060f bellard
        else if (!hob)
1821 c45c3d00 bellard
            ret = s->nsector & 0xff;
1822 c2ff060f bellard
        else
1823 c2ff060f bellard
            ret = s->hob_nsector;
1824 5391d806 bellard
        break;
1825 5391d806 bellard
    case 3:
1826 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
1827 c45c3d00 bellard
            ret = 0;
1828 c2ff060f bellard
        else if (!hob)
1829 c45c3d00 bellard
            ret = s->sector;
1830 c2ff060f bellard
        else
1831 c2ff060f bellard
            ret = s->hob_sector;
1832 5391d806 bellard
        break;
1833 5391d806 bellard
    case 4:
1834 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
1835 c45c3d00 bellard
            ret = 0;
1836 c2ff060f bellard
        else if (!hob)
1837 c45c3d00 bellard
            ret = s->lcyl;
1838 c2ff060f bellard
        else
1839 c2ff060f bellard
            ret = s->hob_lcyl;
1840 5391d806 bellard
        break;
1841 5391d806 bellard
    case 5:
1842 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
1843 c45c3d00 bellard
            ret = 0;
1844 c2ff060f bellard
        else if (!hob)
1845 c45c3d00 bellard
            ret = s->hcyl;
1846 c2ff060f bellard
        else
1847 c2ff060f bellard
            ret = s->hob_hcyl;
1848 5391d806 bellard
        break;
1849 5391d806 bellard
    case 6:
1850 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
1851 c45c3d00 bellard
            ret = 0;
1852 c45c3d00 bellard
        else
1853 7ae98627 bellard
            ret = s->select;
1854 5391d806 bellard
        break;
1855 5391d806 bellard
    default:
1856 5391d806 bellard
    case 7:
1857 66201e2d bellard
        if ((!ide_if[0].bs && !ide_if[1].bs) ||
1858 66201e2d bellard
            (s != ide_if && !s->bs))
1859 c45c3d00 bellard
            ret = 0;
1860 c45c3d00 bellard
        else
1861 c45c3d00 bellard
            ret = s->status;
1862 5457c8ce bellard
        s->set_irq(s->irq_opaque, s->irq, 0);
1863 5391d806 bellard
        break;
1864 5391d806 bellard
    }
1865 5391d806 bellard
#ifdef DEBUG_IDE
1866 5391d806 bellard
    printf("ide: read addr=0x%x val=%02x\n", addr1, ret);
1867 5391d806 bellard
#endif
1868 5391d806 bellard
    return ret;
1869 5391d806 bellard
}
1870 5391d806 bellard
1871 caed8802 bellard
static uint32_t ide_status_read(void *opaque, uint32_t addr)
1872 5391d806 bellard
{
1873 7ae98627 bellard
    IDEState *ide_if = opaque;
1874 7ae98627 bellard
    IDEState *s = ide_if->cur_drive;
1875 5391d806 bellard
    int ret;
1876 7ae98627 bellard
1877 66201e2d bellard
    if ((!ide_if[0].bs && !ide_if[1].bs) ||
1878 66201e2d bellard
        (s != ide_if && !s->bs))
1879 7ae98627 bellard
        ret = 0;
1880 7ae98627 bellard
    else
1881 7ae98627 bellard
        ret = s->status;
1882 5391d806 bellard
#ifdef DEBUG_IDE
1883 5391d806 bellard
    printf("ide: read status addr=0x%x val=%02x\n", addr, ret);
1884 5391d806 bellard
#endif
1885 5391d806 bellard
    return ret;
1886 5391d806 bellard
}
1887 5391d806 bellard
1888 caed8802 bellard
static void ide_cmd_write(void *opaque, uint32_t addr, uint32_t val)
1889 5391d806 bellard
{
1890 caed8802 bellard
    IDEState *ide_if = opaque;
1891 5391d806 bellard
    IDEState *s;
1892 5391d806 bellard
    int i;
1893 5391d806 bellard
1894 5391d806 bellard
#ifdef DEBUG_IDE
1895 5391d806 bellard
    printf("ide: write control addr=0x%x val=%02x\n", addr, val);
1896 5391d806 bellard
#endif
1897 5391d806 bellard
    /* common for both drives */
1898 5391d806 bellard
    if (!(ide_if[0].cmd & IDE_CMD_RESET) &&
1899 5391d806 bellard
        (val & IDE_CMD_RESET)) {
1900 5391d806 bellard
        /* reset low to high */
1901 5391d806 bellard
        for(i = 0;i < 2; i++) {
1902 5391d806 bellard
            s = &ide_if[i];
1903 5391d806 bellard
            s->status = BUSY_STAT | SEEK_STAT;
1904 5391d806 bellard
            s->error = 0x01;
1905 5391d806 bellard
        }
1906 5391d806 bellard
    } else if ((ide_if[0].cmd & IDE_CMD_RESET) &&
1907 5391d806 bellard
               !(val & IDE_CMD_RESET)) {
1908 5391d806 bellard
        /* high to low */
1909 5391d806 bellard
        for(i = 0;i < 2; i++) {
1910 5391d806 bellard
            s = &ide_if[i];
1911 6b136f9e bellard
            if (s->is_cdrom)
1912 6b136f9e bellard
                s->status = 0x00; /* NOTE: READY is _not_ set */
1913 6b136f9e bellard
            else
1914 56bf1d37 bellard
                s->status = READY_STAT | SEEK_STAT;
1915 5391d806 bellard
            ide_set_signature(s);
1916 5391d806 bellard
        }
1917 5391d806 bellard
    }
1918 5391d806 bellard
1919 5391d806 bellard
    ide_if[0].cmd = val;
1920 5391d806 bellard
    ide_if[1].cmd = val;
1921 5391d806 bellard
}
1922 5391d806 bellard
1923 caed8802 bellard
static void ide_data_writew(void *opaque, uint32_t addr, uint32_t val)
1924 5391d806 bellard
{
1925 caed8802 bellard
    IDEState *s = ((IDEState *)opaque)->cur_drive;
1926 5391d806 bellard
    uint8_t *p;
1927 5391d806 bellard
1928 5391d806 bellard
    p = s->data_ptr;
1929 0c4ad8dc bellard
    *(uint16_t *)p = le16_to_cpu(val);
1930 5391d806 bellard
    p += 2;
1931 5391d806 bellard
    s->data_ptr = p;
1932 5391d806 bellard
    if (p >= s->data_end)
1933 5391d806 bellard
        s->end_transfer_func(s);
1934 5391d806 bellard
}
1935 5391d806 bellard
1936 caed8802 bellard
static uint32_t ide_data_readw(void *opaque, uint32_t addr)
1937 5391d806 bellard
{
1938 caed8802 bellard
    IDEState *s = ((IDEState *)opaque)->cur_drive;
1939 5391d806 bellard
    uint8_t *p;
1940 5391d806 bellard
    int ret;
1941 5391d806 bellard
    p = s->data_ptr;
1942 0c4ad8dc bellard
    ret = cpu_to_le16(*(uint16_t *)p);
1943 5391d806 bellard
    p += 2;
1944 5391d806 bellard
    s->data_ptr = p;
1945 5391d806 bellard
    if (p >= s->data_end)
1946 5391d806 bellard
        s->end_transfer_func(s);
1947 5391d806 bellard
    return ret;
1948 5391d806 bellard
}
1949 5391d806 bellard
1950 caed8802 bellard
static void ide_data_writel(void *opaque, uint32_t addr, uint32_t val)
1951 5391d806 bellard
{
1952 caed8802 bellard
    IDEState *s = ((IDEState *)opaque)->cur_drive;
1953 5391d806 bellard
    uint8_t *p;
1954 5391d806 bellard
1955 5391d806 bellard
    p = s->data_ptr;
1956 0c4ad8dc bellard
    *(uint32_t *)p = le32_to_cpu(val);
1957 5391d806 bellard
    p += 4;
1958 5391d806 bellard
    s->data_ptr = p;
1959 5391d806 bellard
    if (p >= s->data_end)
1960 5391d806 bellard
        s->end_transfer_func(s);
1961 5391d806 bellard
}
1962 5391d806 bellard
1963 caed8802 bellard
static uint32_t ide_data_readl(void *opaque, uint32_t addr)
1964 5391d806 bellard
{
1965 caed8802 bellard
    IDEState *s = ((IDEState *)opaque)->cur_drive;
1966 5391d806 bellard
    uint8_t *p;
1967 5391d806 bellard
    int ret;
1968 5391d806 bellard
    
1969 5391d806 bellard
    p = s->data_ptr;
1970 0c4ad8dc bellard
    ret = cpu_to_le32(*(uint32_t *)p);
1971 5391d806 bellard
    p += 4;
1972 5391d806 bellard
    s->data_ptr = p;
1973 5391d806 bellard
    if (p >= s->data_end)
1974 5391d806 bellard
        s->end_transfer_func(s);
1975 5391d806 bellard
    return ret;
1976 5391d806 bellard
}
1977 5391d806 bellard
1978 a7dfe172 bellard
static void ide_dummy_transfer_stop(IDEState *s)
1979 a7dfe172 bellard
{
1980 a7dfe172 bellard
    s->data_ptr = s->io_buffer;
1981 a7dfe172 bellard
    s->data_end = s->io_buffer;
1982 a7dfe172 bellard
    s->io_buffer[0] = 0xff;
1983 a7dfe172 bellard
    s->io_buffer[1] = 0xff;
1984 a7dfe172 bellard
    s->io_buffer[2] = 0xff;
1985 a7dfe172 bellard
    s->io_buffer[3] = 0xff;
1986 a7dfe172 bellard
}
1987 a7dfe172 bellard
1988 5391d806 bellard
static void ide_reset(IDEState *s)
1989 5391d806 bellard
{
1990 5391d806 bellard
    s->mult_sectors = MAX_MULT_SECTORS;
1991 5391d806 bellard
    s->cur_drive = s;
1992 5391d806 bellard
    s->select = 0xa0;
1993 5391d806 bellard
    s->status = READY_STAT;
1994 5391d806 bellard
    ide_set_signature(s);
1995 a7dfe172 bellard
    /* init the transfer handler so that 0xffff is returned on data
1996 a7dfe172 bellard
       accesses */
1997 a7dfe172 bellard
    s->end_transfer_func = ide_dummy_transfer_stop;
1998 a7dfe172 bellard
    ide_dummy_transfer_stop(s);
1999 5391d806 bellard
}
2000 5391d806 bellard
2001 5391d806 bellard
struct partition {
2002 5391d806 bellard
        uint8_t boot_ind;                /* 0x80 - active */
2003 5391d806 bellard
        uint8_t head;                /* starting head */
2004 5391d806 bellard
        uint8_t sector;                /* starting sector */
2005 5391d806 bellard
        uint8_t cyl;                /* starting cylinder */
2006 5391d806 bellard
        uint8_t sys_ind;                /* What partition type */
2007 5391d806 bellard
        uint8_t end_head;                /* end head */
2008 5391d806 bellard
        uint8_t end_sector;        /* end sector */
2009 5391d806 bellard
        uint8_t end_cyl;                /* end cylinder */
2010 5391d806 bellard
        uint32_t start_sect;        /* starting sector counting from 0 */
2011 5391d806 bellard
        uint32_t nr_sects;                /* nr of sectors in partition */
2012 5391d806 bellard
} __attribute__((packed));
2013 5391d806 bellard
2014 bf1b938f bellard
/* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */
2015 bf1b938f bellard
static int guess_disk_lchs(IDEState *s, 
2016 bf1b938f bellard
                           int *pcylinders, int *pheads, int *psectors)
2017 5391d806 bellard
{
2018 5391d806 bellard
    uint8_t buf[512];
2019 46d4767d bellard
    int ret, i, heads, sectors, cylinders;
2020 5391d806 bellard
    struct partition *p;
2021 5391d806 bellard
    uint32_t nr_sects;
2022 5391d806 bellard
2023 5391d806 bellard
    ret = bdrv_read(s->bs, 0, buf, 1);
2024 5391d806 bellard
    if (ret < 0)
2025 bf1b938f bellard
        return -1;
2026 5391d806 bellard
    /* test msdos magic */
2027 5391d806 bellard
    if (buf[510] != 0x55 || buf[511] != 0xaa)
2028 bf1b938f bellard
        return -1;
2029 5391d806 bellard
    for(i = 0; i < 4; i++) {
2030 5391d806 bellard
        p = ((struct partition *)(buf + 0x1be)) + i;
2031 0c4ad8dc bellard
        nr_sects = le32_to_cpu(p->nr_sects);
2032 5391d806 bellard
        if (nr_sects && p->end_head) {
2033 5391d806 bellard
            /* We make the assumption that the partition terminates on
2034 5391d806 bellard
               a cylinder boundary */
2035 46d4767d bellard
            heads = p->end_head + 1;
2036 46d4767d bellard
            sectors = p->end_sector & 63;
2037 46d4767d bellard
            if (sectors == 0)
2038 46d4767d bellard
                continue;
2039 46d4767d bellard
            cylinders = s->nb_sectors / (heads * sectors);
2040 46d4767d bellard
            if (cylinders < 1 || cylinders > 16383)
2041 46d4767d bellard
                continue;
2042 bf1b938f bellard
            *pheads = heads;
2043 bf1b938f bellard
            *psectors = sectors;
2044 bf1b938f bellard
            *pcylinders = cylinders;
2045 5391d806 bellard
#if 0
2046 bf1b938f bellard
            printf("guessed geometry: LCHS=%d %d %d\n", 
2047 bf1b938f bellard
                   cylinders, heads, sectors);
2048 5391d806 bellard
#endif
2049 bf1b938f bellard
            return 0;
2050 5391d806 bellard
        }
2051 5391d806 bellard
    }
2052 bf1b938f bellard
    return -1;
2053 5391d806 bellard
}
2054 5391d806 bellard
2055 5457c8ce bellard
static void ide_init2(IDEState *ide_state,
2056 5457c8ce bellard
                      BlockDriverState *hd0, BlockDriverState *hd1,
2057 5457c8ce bellard
                      SetIRQFunc *set_irq, void *irq_opaque, int irq)
2058 5391d806 bellard
{
2059 69b91039 bellard
    IDEState *s;
2060 aedf5382 bellard
    static int drive_serial = 1;
2061 bf1b938f bellard
    int i, cylinders, heads, secs, translation;
2062 5391d806 bellard
    int64_t nb_sectors;
2063 5391d806 bellard
2064 caed8802 bellard
    for(i = 0; i < 2; i++) {
2065 caed8802 bellard
        s = ide_state + i;
2066 caed8802 bellard
        if (i == 0)
2067 caed8802 bellard
            s->bs = hd0;
2068 caed8802 bellard
        else
2069 caed8802 bellard
            s->bs = hd1;
2070 5391d806 bellard
        if (s->bs) {
2071 5391d806 bellard
            bdrv_get_geometry(s->bs, &nb_sectors);
2072 5391d806 bellard
            s->nb_sectors = nb_sectors;
2073 caed8802 bellard
            /* if a geometry hint is available, use it */
2074 caed8802 bellard
            bdrv_get_geometry_hint(s->bs, &cylinders, &heads, &secs);
2075 caed8802 bellard
            if (cylinders != 0) {
2076 5391d806 bellard
                s->cylinders = cylinders;
2077 caed8802 bellard
                s->heads = heads;
2078 caed8802 bellard
                s->sectors = secs;
2079 caed8802 bellard
            } else {
2080 bf1b938f bellard
                if (guess_disk_lchs(s, &cylinders, &heads, &secs) == 0) {
2081 bf1b938f bellard
                    if (heads > 16) {
2082 bf1b938f bellard
                        /* if heads > 16, it means that a BIOS LBA
2083 bf1b938f bellard
                           translation was active, so the default
2084 bf1b938f bellard
                           hardware geometry is OK */
2085 bf1b938f bellard
                        goto default_geometry;
2086 bf1b938f bellard
                    } else {
2087 bf1b938f bellard
                        s->cylinders = cylinders;
2088 bf1b938f bellard
                        s->heads = heads;
2089 bf1b938f bellard
                        s->sectors = secs;
2090 bf1b938f bellard
                        /* disable any translation to be in sync with
2091 bf1b938f bellard
                           the logical geometry */
2092 bf1b938f bellard
                        translation = bdrv_get_translation_hint(s->bs);
2093 bf1b938f bellard
                        if (translation == BIOS_ATA_TRANSLATION_AUTO) {
2094 bf1b938f bellard
                            bdrv_set_translation_hint(s->bs,
2095 bf1b938f bellard
                                                      BIOS_ATA_TRANSLATION_NONE);
2096 bf1b938f bellard
                        }
2097 bf1b938f bellard
                    }
2098 bf1b938f bellard
                } else {
2099 bf1b938f bellard
                default_geometry:
2100 46d4767d bellard
                    /* if no geometry, use a standard physical disk geometry */
2101 caed8802 bellard
                    cylinders = nb_sectors / (16 * 63);
2102 caed8802 bellard
                    if (cylinders > 16383)
2103 caed8802 bellard
                        cylinders = 16383;
2104 caed8802 bellard
                    else if (cylinders < 2)
2105 caed8802 bellard
                        cylinders = 2;
2106 caed8802 bellard
                    s->cylinders = cylinders;
2107 caed8802 bellard
                    s->heads = 16;
2108 caed8802 bellard
                    s->sectors = 63;
2109 caed8802 bellard
                }
2110 769bec72 bellard
                bdrv_set_geometry_hint(s->bs, s->cylinders, s->heads, s->sectors);
2111 caed8802 bellard
            }
2112 caed8802 bellard
            if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) {
2113 caed8802 bellard
                s->is_cdrom = 1;
2114 5391d806 bellard
            }
2115 5391d806 bellard
        }
2116 aedf5382 bellard
        s->drive_serial = drive_serial++;
2117 5457c8ce bellard
        s->set_irq = set_irq;
2118 5457c8ce bellard
        s->irq_opaque = irq_opaque;
2119 caed8802 bellard
        s->irq = irq;
2120 a09db21f bellard
        s->sector_write_timer = qemu_new_timer(vm_clock, 
2121 a09db21f bellard
                                               ide_sector_write_timer_cb, s);
2122 5391d806 bellard
        ide_reset(s);
2123 5391d806 bellard
    }
2124 69b91039 bellard
}
2125 69b91039 bellard
2126 34e538ae bellard
static void ide_init_ioport(IDEState *ide_state, int iobase, int iobase2)
2127 69b91039 bellard
{
2128 caed8802 bellard
    register_ioport_write(iobase, 8, 1, ide_ioport_write, ide_state);
2129 caed8802 bellard
    register_ioport_read(iobase, 8, 1, ide_ioport_read, ide_state);
2130 caed8802 bellard
    if (iobase2) {
2131 caed8802 bellard
        register_ioport_read(iobase2, 1, 1, ide_status_read, ide_state);
2132 caed8802 bellard
        register_ioport_write(iobase2, 1, 1, ide_cmd_write, ide_state);
2133 5391d806 bellard
    }
2134 caed8802 bellard
    
2135 caed8802 bellard
    /* data ports */
2136 caed8802 bellard
    register_ioport_write(iobase, 2, 2, ide_data_writew, ide_state);
2137 caed8802 bellard
    register_ioport_read(iobase, 2, 2, ide_data_readw, ide_state);
2138 caed8802 bellard
    register_ioport_write(iobase, 4, 4, ide_data_writel, ide_state);
2139 caed8802 bellard
    register_ioport_read(iobase, 4, 4, ide_data_readl, ide_state);
2140 5391d806 bellard
}
2141 69b91039 bellard
2142 69b91039 bellard
/***********************************************************/
2143 34e538ae bellard
/* ISA IDE definitions */
2144 34e538ae bellard
2145 34e538ae bellard
void isa_ide_init(int iobase, int iobase2, int irq,
2146 34e538ae bellard
                  BlockDriverState *hd0, BlockDriverState *hd1)
2147 34e538ae bellard
{
2148 34e538ae bellard
    IDEState *ide_state;
2149 34e538ae bellard
2150 34e538ae bellard
    ide_state = qemu_mallocz(sizeof(IDEState) * 2);
2151 34e538ae bellard
    if (!ide_state)
2152 34e538ae bellard
        return;
2153 34e538ae bellard
    
2154 3de388f6 bellard
    ide_init2(ide_state, hd0, hd1, pic_set_irq_new, isa_pic, irq);
2155 34e538ae bellard
    ide_init_ioport(ide_state, iobase, iobase2);
2156 34e538ae bellard
}
2157 34e538ae bellard
2158 34e538ae bellard
/***********************************************************/
2159 69b91039 bellard
/* PCI IDE definitions */
2160 69b91039 bellard
2161 5457c8ce bellard
static void cmd646_update_irq(PCIIDEState *d);
2162 5457c8ce bellard
2163 69b91039 bellard
static void ide_map(PCIDevice *pci_dev, int region_num, 
2164 69b91039 bellard
                    uint32_t addr, uint32_t size, int type)
2165 69b91039 bellard
{
2166 69b91039 bellard
    PCIIDEState *d = (PCIIDEState *)pci_dev;
2167 69b91039 bellard
    IDEState *ide_state;
2168 69b91039 bellard
2169 69b91039 bellard
    if (region_num <= 3) {
2170 69b91039 bellard
        ide_state = &d->ide_if[(region_num >> 1) * 2];
2171 69b91039 bellard
        if (region_num & 1) {
2172 69b91039 bellard
            register_ioport_read(addr + 2, 1, 1, ide_status_read, ide_state);
2173 69b91039 bellard
            register_ioport_write(addr + 2, 1, 1, ide_cmd_write, ide_state);
2174 69b91039 bellard
        } else {
2175 69b91039 bellard
            register_ioport_write(addr, 8, 1, ide_ioport_write, ide_state);
2176 69b91039 bellard
            register_ioport_read(addr, 8, 1, ide_ioport_read, ide_state);
2177 69b91039 bellard
2178 69b91039 bellard
            /* data ports */
2179 69b91039 bellard
            register_ioport_write(addr, 2, 2, ide_data_writew, ide_state);
2180 69b91039 bellard
            register_ioport_read(addr, 2, 2, ide_data_readw, ide_state);
2181 69b91039 bellard
            register_ioport_write(addr, 4, 4, ide_data_writel, ide_state);
2182 69b91039 bellard
            register_ioport_read(addr, 4, 4, ide_data_readl, ide_state);
2183 69b91039 bellard
        }
2184 69b91039 bellard
    }
2185 69b91039 bellard
}
2186 69b91039 bellard
2187 8ccad811 bellard
static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb)
2188 98087450 bellard
{
2189 98087450 bellard
    BMDMAState *bm = s->bmdma;
2190 98087450 bellard
    if(!bm)
2191 98087450 bellard
        return;
2192 98087450 bellard
    bm->ide_if = s;
2193 98087450 bellard
    bm->dma_cb = dma_cb;
2194 8ccad811 bellard
    bm->cur_addr = bm->addr;
2195 8ccad811 bellard
    bm->cur_prd_last = 0;
2196 8ccad811 bellard
    bm->cur_prd_addr = 0;
2197 8ccad811 bellard
    bm->cur_prd_len = 0;
2198 98087450 bellard
    if (bm->status & BM_STATUS_DMAING) {
2199 8ccad811 bellard
        bm->dma_cb(bm, 0);
2200 98087450 bellard
    }
2201 98087450 bellard
}
2202 98087450 bellard
2203 98087450 bellard
static void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)
2204 98087450 bellard
{
2205 98087450 bellard
    BMDMAState *bm = opaque;
2206 98087450 bellard
#ifdef DEBUG_IDE
2207 98087450 bellard
    printf("%s: 0x%08x\n", __func__, val);
2208 98087450 bellard
#endif
2209 98087450 bellard
    if (!(val & BM_CMD_START)) {
2210 98087450 bellard
        /* XXX: do it better */
2211 8ccad811 bellard
        if (bm->status & BM_STATUS_DMAING) {
2212 8ccad811 bellard
            bm->status &= ~BM_STATUS_DMAING;
2213 8ccad811 bellard
            /* cancel DMA request */
2214 8ccad811 bellard
            bm->ide_if = NULL;
2215 8ccad811 bellard
            bm->dma_cb = NULL;
2216 8ccad811 bellard
            if (bm->aiocb) {
2217 8ccad811 bellard
#ifdef DEBUG_AIO
2218 8ccad811 bellard
                printf("aio_cancel\n");
2219 8ccad811 bellard
#endif
2220 8ccad811 bellard
                bdrv_aio_cancel(bm->aiocb);
2221 8ccad811 bellard
                bm->aiocb = NULL;
2222 8ccad811 bellard
            }
2223 8ccad811 bellard
        }
2224 98087450 bellard
        bm->cmd = val & 0x09;
2225 98087450 bellard
    } else {
2226 8ccad811 bellard
        if (!(bm->status & BM_STATUS_DMAING)) {
2227 8ccad811 bellard
            bm->status |= BM_STATUS_DMAING;
2228 8ccad811 bellard
            /* start dma transfer if possible */
2229 8ccad811 bellard
            if (bm->dma_cb)
2230 8ccad811 bellard
                bm->dma_cb(bm, 0);
2231 8ccad811 bellard
        }
2232 98087450 bellard
        bm->cmd = val & 0x09;
2233 98087450 bellard
    }
2234 98087450 bellard
}
2235 98087450 bellard
2236 5457c8ce bellard
static uint32_t bmdma_readb(void *opaque, uint32_t addr)
2237 98087450 bellard
{
2238 98087450 bellard
    BMDMAState *bm = opaque;
2239 5457c8ce bellard
    PCIIDEState *pci_dev;
2240 98087450 bellard
    uint32_t val;
2241 5457c8ce bellard
    
2242 5457c8ce bellard
    switch(addr & 3) {
2243 5457c8ce bellard
    case 0: 
2244 5457c8ce bellard
        val = bm->cmd;
2245 5457c8ce bellard
        break;
2246 5457c8ce bellard
    case 1:
2247 5457c8ce bellard
        pci_dev = bm->pci_dev;
2248 5457c8ce bellard
        if (pci_dev->type == IDE_TYPE_CMD646) {
2249 5457c8ce bellard
            val = pci_dev->dev.config[MRDMODE];
2250 5457c8ce bellard
        } else {
2251 5457c8ce bellard
            val = 0xff;
2252 5457c8ce bellard
        }
2253 5457c8ce bellard
        break;
2254 5457c8ce bellard
    case 2:
2255 5457c8ce bellard
        val = bm->status;
2256 5457c8ce bellard
        break;
2257 5457c8ce bellard
    case 3:
2258 5457c8ce bellard
        pci_dev = bm->pci_dev;
2259 5457c8ce bellard
        if (pci_dev->type == IDE_TYPE_CMD646) {
2260 5457c8ce bellard
            if (bm == &pci_dev->bmdma[0])
2261 5457c8ce bellard
                val = pci_dev->dev.config[UDIDETCR0];
2262 5457c8ce bellard
            else
2263 5457c8ce bellard
                val = pci_dev->dev.config[UDIDETCR1];
2264 5457c8ce bellard
        } else {
2265 5457c8ce bellard
            val = 0xff;
2266 5457c8ce bellard
        }
2267 5457c8ce bellard
        break;
2268 5457c8ce bellard
    default:
2269 5457c8ce bellard
        val = 0xff;
2270 5457c8ce bellard
        break;
2271 5457c8ce bellard
    }
2272 98087450 bellard
#ifdef DEBUG_IDE
2273 5457c8ce bellard
    printf("bmdma: readb 0x%02x : 0x%02x\n", addr, val);
2274 98087450 bellard
#endif
2275 98087450 bellard
    return val;
2276 98087450 bellard
}
2277 98087450 bellard
2278 5457c8ce bellard
static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val)
2279 98087450 bellard
{
2280 98087450 bellard
    BMDMAState *bm = opaque;
2281 5457c8ce bellard
    PCIIDEState *pci_dev;
2282 98087450 bellard
#ifdef DEBUG_IDE
2283 5457c8ce bellard
    printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val);
2284 98087450 bellard
#endif
2285 5457c8ce bellard
    switch(addr & 3) {
2286 5457c8ce bellard
    case 1:
2287 5457c8ce bellard
        pci_dev = bm->pci_dev;
2288 5457c8ce bellard
        if (pci_dev->type == IDE_TYPE_CMD646) {
2289 5457c8ce bellard
            pci_dev->dev.config[MRDMODE] = 
2290 5457c8ce bellard
                (pci_dev->dev.config[MRDMODE] & ~0x30) | (val & 0x30);
2291 5457c8ce bellard
            cmd646_update_irq(pci_dev);
2292 5457c8ce bellard
        }
2293 5457c8ce bellard
        break;
2294 5457c8ce bellard
    case 2:
2295 5457c8ce bellard
        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
2296 5457c8ce bellard
        break;
2297 5457c8ce bellard
    case 3:
2298 5457c8ce bellard
        pci_dev = bm->pci_dev;
2299 5457c8ce bellard
        if (pci_dev->type == IDE_TYPE_CMD646) {
2300 5457c8ce bellard
            if (bm == &pci_dev->bmdma[0])
2301 5457c8ce bellard
                pci_dev->dev.config[UDIDETCR0] = val;
2302 5457c8ce bellard
            else
2303 5457c8ce bellard
                pci_dev->dev.config[UDIDETCR1] = val;
2304 5457c8ce bellard
        }
2305 5457c8ce bellard
        break;
2306 5457c8ce bellard
    }
2307 98087450 bellard
}
2308 98087450 bellard
2309 98087450 bellard
static uint32_t bmdma_addr_readl(void *opaque, uint32_t addr)
2310 98087450 bellard
{
2311 98087450 bellard
    BMDMAState *bm = opaque;
2312 98087450 bellard
    uint32_t val;
2313 98087450 bellard
    val = bm->addr;
2314 98087450 bellard
#ifdef DEBUG_IDE
2315 98087450 bellard
    printf("%s: 0x%08x\n", __func__, val);
2316 98087450 bellard
#endif
2317 98087450 bellard
    return val;
2318 98087450 bellard
}
2319 98087450 bellard
2320 98087450 bellard
static void bmdma_addr_writel(void *opaque, uint32_t addr, uint32_t val)
2321 98087450 bellard
{
2322 98087450 bellard
    BMDMAState *bm = opaque;
2323 98087450 bellard
#ifdef DEBUG_IDE
2324 98087450 bellard
    printf("%s: 0x%08x\n", __func__, val);
2325 98087450 bellard
#endif
2326 98087450 bellard
    bm->addr = val & ~3;
2327 98087450 bellard
}
2328 98087450 bellard
2329 98087450 bellard
static void bmdma_map(PCIDevice *pci_dev, int region_num, 
2330 98087450 bellard
                    uint32_t addr, uint32_t size, int type)
2331 98087450 bellard
{
2332 98087450 bellard
    PCIIDEState *d = (PCIIDEState *)pci_dev;
2333 98087450 bellard
    int i;
2334 98087450 bellard
2335 98087450 bellard
    for(i = 0;i < 2; i++) {
2336 98087450 bellard
        BMDMAState *bm = &d->bmdma[i];
2337 98087450 bellard
        d->ide_if[2 * i].bmdma = bm;
2338 98087450 bellard
        d->ide_if[2 * i + 1].bmdma = bm;
2339 5457c8ce bellard
        bm->pci_dev = (PCIIDEState *)pci_dev;
2340 5457c8ce bellard
2341 98087450 bellard
        register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);
2342 98087450 bellard
2343 5457c8ce bellard
        register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm);
2344 5457c8ce bellard
        register_ioport_read(addr, 4, 1, bmdma_readb, bm);
2345 98087450 bellard
2346 98087450 bellard
        register_ioport_write(addr + 4, 4, 4, bmdma_addr_writel, bm);
2347 98087450 bellard
        register_ioport_read(addr + 4, 4, 4, bmdma_addr_readl, bm);
2348 98087450 bellard
        addr += 8;
2349 98087450 bellard
    }
2350 98087450 bellard
}
2351 98087450 bellard
2352 5457c8ce bellard
/* XXX: call it also when the MRDMODE is changed from the PCI config
2353 5457c8ce bellard
   registers */
2354 5457c8ce bellard
static void cmd646_update_irq(PCIIDEState *d)
2355 5457c8ce bellard
{
2356 5457c8ce bellard
    int pci_level;
2357 5457c8ce bellard
    pci_level = ((d->dev.config[MRDMODE] & MRDMODE_INTR_CH0) &&
2358 5457c8ce bellard
                 !(d->dev.config[MRDMODE] & MRDMODE_BLK_CH0)) ||
2359 5457c8ce bellard
        ((d->dev.config[MRDMODE] & MRDMODE_INTR_CH1) &&
2360 5457c8ce bellard
         !(d->dev.config[MRDMODE] & MRDMODE_BLK_CH1));
2361 5457c8ce bellard
    pci_set_irq((PCIDevice *)d, 0, pci_level);
2362 5457c8ce bellard
}
2363 5457c8ce bellard
2364 5457c8ce bellard
/* the PCI irq level is the logical OR of the two channels */
2365 5457c8ce bellard
static void cmd646_set_irq(void *opaque, int channel, int level)
2366 5457c8ce bellard
{
2367 5457c8ce bellard
    PCIIDEState *d = opaque;
2368 5457c8ce bellard
    int irq_mask;
2369 5457c8ce bellard
2370 5457c8ce bellard
    irq_mask = MRDMODE_INTR_CH0 << channel;
2371 5457c8ce bellard
    if (level)
2372 5457c8ce bellard
        d->dev.config[MRDMODE] |= irq_mask;
2373 5457c8ce bellard
    else
2374 5457c8ce bellard
        d->dev.config[MRDMODE] &= ~irq_mask;
2375 5457c8ce bellard
    cmd646_update_irq(d);
2376 5457c8ce bellard
}
2377 5457c8ce bellard
2378 5457c8ce bellard
/* CMD646 PCI IDE controller */
2379 5457c8ce bellard
void pci_cmd646_ide_init(PCIBus *bus, BlockDriverState **hd_table,
2380 5457c8ce bellard
                         int secondary_ide_enabled)
2381 69b91039 bellard
{
2382 69b91039 bellard
    PCIIDEState *d;
2383 69b91039 bellard
    uint8_t *pci_conf;
2384 34e538ae bellard
    int i;
2385 34e538ae bellard
2386 5457c8ce bellard
    d = (PCIIDEState *)pci_register_device(bus, "CMD646 IDE", 
2387 5457c8ce bellard
                                           sizeof(PCIIDEState),
2388 46e50e9d bellard
                                           -1, 
2389 73c11f63 bellard
                                           NULL, NULL);
2390 5457c8ce bellard
    d->type = IDE_TYPE_CMD646;
2391 69b91039 bellard
    pci_conf = d->dev.config;
2392 5457c8ce bellard
    pci_conf[0x00] = 0x95; // CMD646
2393 5457c8ce bellard
    pci_conf[0x01] = 0x10;
2394 5457c8ce bellard
    pci_conf[0x02] = 0x46;
2395 5457c8ce bellard
    pci_conf[0x03] = 0x06;
2396 5457c8ce bellard
2397 5457c8ce bellard
    pci_conf[0x08] = 0x07; // IDE controller revision
2398 5457c8ce bellard
    pci_conf[0x09] = 0x8f; 
2399 5457c8ce bellard
2400 69b91039 bellard
    pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
2401 69b91039 bellard
    pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
2402 5457c8ce bellard
    pci_conf[0x0e] = 0x00; // header_type
2403 5457c8ce bellard
    
2404 5457c8ce bellard
    if (secondary_ide_enabled) {
2405 5457c8ce bellard
        /* XXX: if not enabled, really disable the seconday IDE controller */
2406 5457c8ce bellard
        pci_conf[0x51] = 0x80; /* enable IDE1 */
2407 5457c8ce bellard
    }
2408 69b91039 bellard
2409 69b91039 bellard
    pci_register_io_region((PCIDevice *)d, 0, 0x8, 
2410 69b91039 bellard
                           PCI_ADDRESS_SPACE_IO, ide_map);
2411 69b91039 bellard
    pci_register_io_region((PCIDevice *)d, 1, 0x4, 
2412 69b91039 bellard
                           PCI_ADDRESS_SPACE_IO, ide_map);
2413 69b91039 bellard
    pci_register_io_region((PCIDevice *)d, 2, 0x8, 
2414 69b91039 bellard
                           PCI_ADDRESS_SPACE_IO, ide_map);
2415 69b91039 bellard
    pci_register_io_region((PCIDevice *)d, 3, 0x4, 
2416 69b91039 bellard
                           PCI_ADDRESS_SPACE_IO, ide_map);
2417 98087450 bellard
    pci_register_io_region((PCIDevice *)d, 4, 0x10, 
2418 98087450 bellard
                           PCI_ADDRESS_SPACE_IO, bmdma_map);
2419 69b91039 bellard
2420 34e538ae bellard
    pci_conf[0x3d] = 0x01; // interrupt on pin 1
2421 5457c8ce bellard
    
2422 34e538ae bellard
    for(i = 0; i < 4; i++)
2423 34e538ae bellard
        d->ide_if[i].pci_dev = (PCIDevice *)d;
2424 5457c8ce bellard
    ide_init2(&d->ide_if[0], hd_table[0], hd_table[1],
2425 5457c8ce bellard
              cmd646_set_irq, d, 0);
2426 5457c8ce bellard
    ide_init2(&d->ide_if[2], hd_table[2], hd_table[3],
2427 5457c8ce bellard
              cmd646_set_irq, d, 1);
2428 34e538ae bellard
}
2429 34e538ae bellard
2430 c3d78997 bellard
static void pci_ide_save(QEMUFile* f, void *opaque)
2431 c3d78997 bellard
{
2432 c3d78997 bellard
    PCIIDEState *d = opaque;
2433 c3d78997 bellard
    int i;
2434 c3d78997 bellard
2435 c3d78997 bellard
    pci_device_save(&d->dev, f);
2436 c3d78997 bellard
2437 c3d78997 bellard
    for(i = 0; i < 2; i++) {
2438 c3d78997 bellard
        BMDMAState *bm = &d->bmdma[i];
2439 c3d78997 bellard
        qemu_put_8s(f, &bm->cmd);
2440 c3d78997 bellard
        qemu_put_8s(f, &bm->status);
2441 c3d78997 bellard
        qemu_put_be32s(f, &bm->addr);
2442 c3d78997 bellard
        /* XXX: if a transfer is pending, we do not save it yet */
2443 c3d78997 bellard
    }
2444 c3d78997 bellard
2445 c3d78997 bellard
    /* per IDE interface data */
2446 c3d78997 bellard
    for(i = 0; i < 2; i++) {
2447 c3d78997 bellard
        IDEState *s = &d->ide_if[i * 2];
2448 c3d78997 bellard
        uint8_t drive1_selected;
2449 c3d78997 bellard
        qemu_put_8s(f, &s->cmd);
2450 c3d78997 bellard
        drive1_selected = (s->cur_drive != s);
2451 c3d78997 bellard
        qemu_put_8s(f, &drive1_selected);
2452 c3d78997 bellard
    }
2453 c3d78997 bellard
2454 c3d78997 bellard
    /* per IDE drive data */
2455 c3d78997 bellard
    for(i = 0; i < 4; i++) {
2456 c3d78997 bellard
        IDEState *s = &d->ide_if[i];
2457 c3d78997 bellard
        qemu_put_be32s(f, &s->mult_sectors);
2458 c3d78997 bellard
        qemu_put_be32s(f, &s->identify_set);
2459 c3d78997 bellard
        if (s->identify_set) {
2460 c3d78997 bellard
            qemu_put_buffer(f, (const uint8_t *)s->identify_data, 512);
2461 c3d78997 bellard
        }
2462 c3d78997 bellard
        qemu_put_8s(f, &s->feature);
2463 c3d78997 bellard
        qemu_put_8s(f, &s->error);
2464 c3d78997 bellard
        qemu_put_be32s(f, &s->nsector);
2465 c3d78997 bellard
        qemu_put_8s(f, &s->sector);
2466 c3d78997 bellard
        qemu_put_8s(f, &s->lcyl);
2467 c3d78997 bellard
        qemu_put_8s(f, &s->hcyl);
2468 c3d78997 bellard
        qemu_put_8s(f, &s->hob_feature);
2469 c3d78997 bellard
        qemu_put_8s(f, &s->hob_nsector);
2470 c3d78997 bellard
        qemu_put_8s(f, &s->hob_sector);
2471 c3d78997 bellard
        qemu_put_8s(f, &s->hob_lcyl);
2472 c3d78997 bellard
        qemu_put_8s(f, &s->hob_hcyl);
2473 c3d78997 bellard
        qemu_put_8s(f, &s->select);
2474 c3d78997 bellard
        qemu_put_8s(f, &s->status);
2475 c3d78997 bellard
        qemu_put_8s(f, &s->lba48);
2476 c3d78997 bellard
2477 c3d78997 bellard
        qemu_put_8s(f, &s->sense_key);
2478 c3d78997 bellard
        qemu_put_8s(f, &s->asc);
2479 c3d78997 bellard
        /* XXX: if a transfer is pending, we do not save it yet */
2480 c3d78997 bellard
    }
2481 c3d78997 bellard
}
2482 c3d78997 bellard
2483 c3d78997 bellard
static int pci_ide_load(QEMUFile* f, void *opaque, int version_id)
2484 c3d78997 bellard
{
2485 c3d78997 bellard
    PCIIDEState *d = opaque;
2486 c3d78997 bellard
    int ret, i;
2487 c3d78997 bellard
2488 c3d78997 bellard
    if (version_id != 1)
2489 c3d78997 bellard
        return -EINVAL;
2490 c3d78997 bellard
    ret = pci_device_load(&d->dev, f);
2491 c3d78997 bellard
    if (ret < 0)
2492 c3d78997 bellard
        return ret;
2493 c3d78997 bellard
2494 c3d78997 bellard
    for(i = 0; i < 2; i++) {
2495 c3d78997 bellard
        BMDMAState *bm = &d->bmdma[i];
2496 c3d78997 bellard
        qemu_get_8s(f, &bm->cmd);
2497 c3d78997 bellard
        qemu_get_8s(f, &bm->status);
2498 c3d78997 bellard
        qemu_get_be32s(f, &bm->addr);
2499 c3d78997 bellard
        /* XXX: if a transfer is pending, we do not save it yet */
2500 c3d78997 bellard
    }
2501 c3d78997 bellard
2502 c3d78997 bellard
    /* per IDE interface data */
2503 c3d78997 bellard
    for(i = 0; i < 2; i++) {
2504 c3d78997 bellard
        IDEState *s = &d->ide_if[i * 2];
2505 c3d78997 bellard
        uint8_t drive1_selected;
2506 c3d78997 bellard
        qemu_get_8s(f, &s->cmd);
2507 c3d78997 bellard
        qemu_get_8s(f, &drive1_selected);
2508 c3d78997 bellard
        s->cur_drive = &d->ide_if[i * 2 + (drive1_selected != 0)];
2509 c3d78997 bellard
    }
2510 c3d78997 bellard
2511 c3d78997 bellard
    /* per IDE drive data */
2512 c3d78997 bellard
    for(i = 0; i < 4; i++) {
2513 c3d78997 bellard
        IDEState *s = &d->ide_if[i];
2514 c3d78997 bellard
        qemu_get_be32s(f, &s->mult_sectors);
2515 c3d78997 bellard
        qemu_get_be32s(f, &s->identify_set);
2516 c3d78997 bellard
        if (s->identify_set) {
2517 c3d78997 bellard
            qemu_get_buffer(f, (uint8_t *)s->identify_data, 512);
2518 c3d78997 bellard
        }
2519 c3d78997 bellard
        qemu_get_8s(f, &s->feature);
2520 c3d78997 bellard
        qemu_get_8s(f, &s->error);
2521 c3d78997 bellard
        qemu_get_be32s(f, &s->nsector);
2522 c3d78997 bellard
        qemu_get_8s(f, &s->sector);
2523 c3d78997 bellard
        qemu_get_8s(f, &s->lcyl);
2524 c3d78997 bellard
        qemu_get_8s(f, &s->hcyl);
2525 c3d78997 bellard
        qemu_get_8s(f, &s->hob_feature);
2526 c3d78997 bellard
        qemu_get_8s(f, &s->hob_nsector);
2527 c3d78997 bellard
        qemu_get_8s(f, &s->hob_sector);
2528 c3d78997 bellard
        qemu_get_8s(f, &s->hob_lcyl);
2529 c3d78997 bellard
        qemu_get_8s(f, &s->hob_hcyl);
2530 c3d78997 bellard
        qemu_get_8s(f, &s->select);
2531 c3d78997 bellard
        qemu_get_8s(f, &s->status);
2532 c3d78997 bellard
        qemu_get_8s(f, &s->lba48);
2533 c3d78997 bellard
2534 c3d78997 bellard
        qemu_get_8s(f, &s->sense_key);
2535 c3d78997 bellard
        qemu_get_8s(f, &s->asc);
2536 c3d78997 bellard
        /* XXX: if a transfer is pending, we do not save it yet */
2537 c3d78997 bellard
    }
2538 c3d78997 bellard
    return 0;
2539 c3d78997 bellard
}
2540 c3d78997 bellard
2541 34e538ae bellard
/* hd_table must contain 4 block drivers */
2542 34e538ae bellard
/* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
2543 502a5395 pbrook
void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn)
2544 34e538ae bellard
{
2545 34e538ae bellard
    PCIIDEState *d;
2546 34e538ae bellard
    uint8_t *pci_conf;
2547 34e538ae bellard
    
2548 34e538ae bellard
    /* register a function 1 of PIIX3 */
2549 46e50e9d bellard
    d = (PCIIDEState *)pci_register_device(bus, "PIIX3 IDE", 
2550 46e50e9d bellard
                                           sizeof(PCIIDEState),
2551 502a5395 pbrook
                                           devfn,
2552 34e538ae bellard
                                           NULL, NULL);
2553 5457c8ce bellard
    d->type = IDE_TYPE_PIIX3;
2554 5457c8ce bellard
2555 34e538ae bellard
    pci_conf = d->dev.config;
2556 34e538ae bellard
    pci_conf[0x00] = 0x86; // Intel
2557 34e538ae bellard
    pci_conf[0x01] = 0x80;
2558 34e538ae bellard
    pci_conf[0x02] = 0x10;
2559 34e538ae bellard
    pci_conf[0x03] = 0x70;
2560 92510b8c bellard
    pci_conf[0x09] = 0x80; // legacy ATA mode
2561 34e538ae bellard
    pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
2562 34e538ae bellard
    pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
2563 34e538ae bellard
    pci_conf[0x0e] = 0x00; // header_type
2564 34e538ae bellard
2565 98087450 bellard
    pci_register_io_region((PCIDevice *)d, 4, 0x10, 
2566 98087450 bellard
                           PCI_ADDRESS_SPACE_IO, bmdma_map);
2567 34e538ae bellard
2568 5457c8ce bellard
    ide_init2(&d->ide_if[0], hd_table[0], hd_table[1],
2569 3de388f6 bellard
              pic_set_irq_new, isa_pic, 14);
2570 5457c8ce bellard
    ide_init2(&d->ide_if[2], hd_table[2], hd_table[3],
2571 3de388f6 bellard
              pic_set_irq_new, isa_pic, 15);
2572 34e538ae bellard
    ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
2573 34e538ae bellard
    ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
2574 c3d78997 bellard
2575 c3d78997 bellard
    register_savevm("ide", 0, 1, pci_ide_save, pci_ide_load, d);
2576 69b91039 bellard
}
2577 1ade1de2 bellard
2578 1ade1de2 bellard
/***********************************************************/
2579 1ade1de2 bellard
/* MacIO based PowerPC IDE */
2580 1ade1de2 bellard
2581 1ade1de2 bellard
/* PowerMac IDE memory IO */
2582 1ade1de2 bellard
static void pmac_ide_writeb (void *opaque,
2583 1ade1de2 bellard
                             target_phys_addr_t addr, uint32_t val)
2584 1ade1de2 bellard
{
2585 1ade1de2 bellard
    addr = (addr & 0xFFF) >> 4; 
2586 1ade1de2 bellard
    switch (addr) {
2587 1ade1de2 bellard
    case 1 ... 7:
2588 1ade1de2 bellard
        ide_ioport_write(opaque, addr, val);
2589 1ade1de2 bellard
        break;
2590 1ade1de2 bellard
    case 8:
2591 1ade1de2 bellard
    case 22:
2592 1ade1de2 bellard
        ide_cmd_write(opaque, 0, val);
2593 1ade1de2 bellard
        break;
2594 1ade1de2 bellard
    default:
2595 1ade1de2 bellard
        break;
2596 1ade1de2 bellard
    }
2597 1ade1de2 bellard
}
2598 1ade1de2 bellard
2599 1ade1de2 bellard
static uint32_t pmac_ide_readb (void *opaque,target_phys_addr_t addr)
2600 1ade1de2 bellard
{
2601 1ade1de2 bellard
    uint8_t retval;
2602 1ade1de2 bellard
2603 1ade1de2 bellard
    addr = (addr & 0xFFF) >> 4;
2604 1ade1de2 bellard
    switch (addr) {
2605 1ade1de2 bellard
    case 1 ... 7:
2606 1ade1de2 bellard
        retval = ide_ioport_read(opaque, addr);
2607 1ade1de2 bellard
        break;
2608 1ade1de2 bellard
    case 8:
2609 1ade1de2 bellard
    case 22:
2610 1ade1de2 bellard
        retval = ide_status_read(opaque, 0);
2611 1ade1de2 bellard
        break;
2612 1ade1de2 bellard
    default:
2613 1ade1de2 bellard
        retval = 0xFF;
2614 1ade1de2 bellard
        break;
2615 1ade1de2 bellard
    }
2616 1ade1de2 bellard
    return retval;
2617 1ade1de2 bellard
}
2618 1ade1de2 bellard
2619 1ade1de2 bellard
static void pmac_ide_writew (void *opaque,
2620 1ade1de2 bellard
                             target_phys_addr_t addr, uint32_t val)
2621 1ade1de2 bellard
{
2622 1ade1de2 bellard
    addr = (addr & 0xFFF) >> 4; 
2623 1ade1de2 bellard
#ifdef TARGET_WORDS_BIGENDIAN
2624 1ade1de2 bellard
    val = bswap16(val);
2625 1ade1de2 bellard
#endif
2626 1ade1de2 bellard
    if (addr == 0) {
2627 1ade1de2 bellard
        ide_data_writew(opaque, 0, val);
2628 1ade1de2 bellard
    }
2629 1ade1de2 bellard
}
2630 1ade1de2 bellard
2631 1ade1de2 bellard
static uint32_t pmac_ide_readw (void *opaque,target_phys_addr_t addr)
2632 1ade1de2 bellard
{
2633 1ade1de2 bellard
    uint16_t retval;
2634 1ade1de2 bellard
2635 1ade1de2 bellard
    addr = (addr & 0xFFF) >> 4; 
2636 1ade1de2 bellard
    if (addr == 0) {
2637 1ade1de2 bellard
        retval = ide_data_readw(opaque, 0);
2638 1ade1de2 bellard
    } else {
2639 1ade1de2 bellard
        retval = 0xFFFF;
2640 1ade1de2 bellard
    }
2641 1ade1de2 bellard
#ifdef TARGET_WORDS_BIGENDIAN
2642 1ade1de2 bellard
    retval = bswap16(retval);
2643 1ade1de2 bellard
#endif
2644 1ade1de2 bellard
    return retval;
2645 1ade1de2 bellard
}
2646 1ade1de2 bellard
2647 1ade1de2 bellard
static void pmac_ide_writel (void *opaque,
2648 1ade1de2 bellard
                             target_phys_addr_t addr, uint32_t val)
2649 1ade1de2 bellard
{
2650 1ade1de2 bellard
    addr = (addr & 0xFFF) >> 4; 
2651 1ade1de2 bellard
#ifdef TARGET_WORDS_BIGENDIAN
2652 1ade1de2 bellard
    val = bswap32(val);
2653 1ade1de2 bellard
#endif
2654 1ade1de2 bellard
    if (addr == 0) {
2655 1ade1de2 bellard
        ide_data_writel(opaque, 0, val);
2656 1ade1de2 bellard
    }
2657 1ade1de2 bellard
}
2658 1ade1de2 bellard
2659 1ade1de2 bellard
static uint32_t pmac_ide_readl (void *opaque,target_phys_addr_t addr)
2660 1ade1de2 bellard
{
2661 1ade1de2 bellard
    uint32_t retval;
2662 1ade1de2 bellard
2663 1ade1de2 bellard
    addr = (addr & 0xFFF) >> 4; 
2664 1ade1de2 bellard
    if (addr == 0) {
2665 1ade1de2 bellard
        retval = ide_data_readl(opaque, 0);
2666 1ade1de2 bellard
    } else {
2667 1ade1de2 bellard
        retval = 0xFFFFFFFF;
2668 1ade1de2 bellard
    }
2669 1ade1de2 bellard
#ifdef TARGET_WORDS_BIGENDIAN
2670 1ade1de2 bellard
    retval = bswap32(retval);
2671 1ade1de2 bellard
#endif
2672 1ade1de2 bellard
    return retval;
2673 1ade1de2 bellard
}
2674 1ade1de2 bellard
2675 1ade1de2 bellard
static CPUWriteMemoryFunc *pmac_ide_write[] = {
2676 1ade1de2 bellard
    pmac_ide_writeb,
2677 1ade1de2 bellard
    pmac_ide_writew,
2678 1ade1de2 bellard
    pmac_ide_writel,
2679 1ade1de2 bellard
};
2680 1ade1de2 bellard
2681 1ade1de2 bellard
static CPUReadMemoryFunc *pmac_ide_read[] = {
2682 1ade1de2 bellard
    pmac_ide_readb,
2683 1ade1de2 bellard
    pmac_ide_readw,
2684 1ade1de2 bellard
    pmac_ide_readl,
2685 1ade1de2 bellard
};
2686 1ade1de2 bellard
2687 1ade1de2 bellard
/* hd_table must contain 4 block drivers */
2688 1ade1de2 bellard
/* PowerMac uses memory mapped registers, not I/O. Return the memory
2689 1ade1de2 bellard
   I/O index to access the ide. */
2690 1ade1de2 bellard
int pmac_ide_init (BlockDriverState **hd_table,
2691 5457c8ce bellard
                   SetIRQFunc *set_irq, void *irq_opaque, int irq)
2692 1ade1de2 bellard
{
2693 1ade1de2 bellard
    IDEState *ide_if;
2694 1ade1de2 bellard
    int pmac_ide_memory;
2695 1ade1de2 bellard
2696 1ade1de2 bellard
    ide_if = qemu_mallocz(sizeof(IDEState) * 2);
2697 5457c8ce bellard
    ide_init2(&ide_if[0], hd_table[0], hd_table[1],
2698 5457c8ce bellard
              set_irq, irq_opaque, irq);
2699 1ade1de2 bellard
    
2700 1ade1de2 bellard
    pmac_ide_memory = cpu_register_io_memory(0, pmac_ide_read,
2701 1ade1de2 bellard
                                             pmac_ide_write, &ide_if[0]);
2702 1ade1de2 bellard
    return pmac_ide_memory;
2703 1ade1de2 bellard
}